import { __assign } from "/_nuxt/node_modules/tslib/tslib.es6.js?v=e4f18c29"; import { invariant, newInvariantError } from "/_nuxt/node_modules/@apollo/client/utilities/globals/index.js?v=e4f18c29"; import { ApolloLink, execute } from "/_nuxt/node_modules/@apollo/client/link/core/index.js?v=e4f18c29"; import { version } from "/_nuxt/node_modules/@apollo/client/version.js?v=e4f18c29"; import { HttpLink } from "/_nuxt/node_modules/@apollo/client/link/http/index.js?v=e4f18c29"; import { QueryManager } from "/_nuxt/node_modules/@apollo/client/core/QueryManager.js?v=e4f18c29"; import { LocalState } from "/_nuxt/node_modules/@apollo/client/core/LocalState.js?v=e4f18c29"; var hasSuggestedDevtools = false; // Though mergeOptions now resides in @apollo/client/utilities, it was // previously declared and exported from this module, and then reexported from // @apollo/client/core. Since we need to preserve that API anyway, the easiest // solution is to reexport mergeOptions where it was previously declared (here). import { mergeOptions } from "/_nuxt/node_modules/@apollo/client/utilities/index.js?v=e4f18c29"; import { getApolloClientMemoryInternals } from "/_nuxt/node_modules/@apollo/client/utilities/caching/getMemoryInternals.js?v=e4f18c29"; export { mergeOptions }; /** * This is the primary Apollo Client class. It is used to send GraphQL documents (i.e. queries * and mutations) to a GraphQL spec-compliant server over an `ApolloLink` instance, * receive results from the server and cache the results in a store. It also delivers updates * to GraphQL queries through `Observable` instances. */ var ApolloClient = /** @class */ (function () { /** * Constructs an instance of `ApolloClient`. * * @example * ```js * import { ApolloClient, InMemoryCache } from '@apollo/client'; * * const cache = new InMemoryCache(); * * const client = new ApolloClient({ * // Provide required constructor fields * cache: cache, * uri: 'http://localhost:4000/', * * // Provide some optional constructor fields * name: 'react-web-client', * version: '1.3', * queryDeduplication: false, * defaultOptions: { * watchQuery: { * fetchPolicy: 'cache-and-network', * }, * }, * }); * ``` */ function ApolloClient(options) { var _this = this; var _a; this.resetStoreCallbacks = []; this.clearStoreCallbacks = []; if (!options.cache) { throw newInvariantError(16); } var uri = options.uri, credentials = options.credentials, headers = options.headers, cache = options.cache, documentTransform = options.documentTransform, _b = options.ssrMode, ssrMode = _b === void 0 ? false : _b, _c = options.ssrForceFetchDelay, ssrForceFetchDelay = _c === void 0 ? 0 : _c, // Expose the client instance as window.__APOLLO_CLIENT__ and call // onBroadcast in queryManager.broadcastQueries to enable browser // devtools, but disable them by default in production. connectToDevTools = options.connectToDevTools, _d = options.queryDeduplication, queryDeduplication = _d === void 0 ? true : _d, defaultOptions = options.defaultOptions, defaultContext = options.defaultContext, _e = options.assumeImmutableResults, assumeImmutableResults = _e === void 0 ? cache.assumeImmutableResults : _e, resolvers = options.resolvers, typeDefs = options.typeDefs, fragmentMatcher = options.fragmentMatcher, clientAwarenessName = options.name, clientAwarenessVersion = options.version, devtools = options.devtools, dataMasking = options.dataMasking; var link = options.link; if (!link) { link = uri ? new HttpLink({ uri: uri, credentials: credentials, headers: headers }) : ApolloLink.empty(); } this.link = link; this.cache = cache; this.disableNetworkFetches = ssrMode || ssrForceFetchDelay > 0; this.queryDeduplication = queryDeduplication; this.defaultOptions = defaultOptions || Object.create(null); this.typeDefs = typeDefs; this.devtoolsConfig = __assign(__assign({}, devtools), { enabled: (_a = devtools === null || devtools === void 0 ? void 0 : devtools.enabled) !== null && _a !== void 0 ? _a : connectToDevTools }); if (this.devtoolsConfig.enabled === undefined) { this.devtoolsConfig.enabled = globalThis.__DEV__ !== false; } if (ssrForceFetchDelay) { setTimeout(function () { return (_this.disableNetworkFetches = false); }, ssrForceFetchDelay); } this.watchQuery = this.watchQuery.bind(this); this.query = this.query.bind(this); this.mutate = this.mutate.bind(this); this.watchFragment = this.watchFragment.bind(this); this.resetStore = this.resetStore.bind(this); this.reFetchObservableQueries = this.reFetchObservableQueries.bind(this); this.version = version; this.localState = new LocalState({ cache: cache, client: this, resolvers: resolvers, fragmentMatcher: fragmentMatcher, }); this.queryManager = new QueryManager({ cache: this.cache, link: this.link, defaultOptions: this.defaultOptions, defaultContext: defaultContext, documentTransform: documentTransform, queryDeduplication: queryDeduplication, ssrMode: ssrMode, dataMasking: !!dataMasking, clientAwareness: { name: clientAwarenessName, version: clientAwarenessVersion, }, localState: this.localState, assumeImmutableResults: assumeImmutableResults, onBroadcast: this.devtoolsConfig.enabled ? function () { if (_this.devToolsHookCb) { _this.devToolsHookCb({ action: {}, state: { queries: _this.queryManager.getQueryStore(), mutations: _this.queryManager.mutationStore || {}, }, dataWithOptimisticResults: _this.cache.extract(true), }); } } : void 0, }); if (this.devtoolsConfig.enabled) this.connectToDevTools(); } ApolloClient.prototype.connectToDevTools = function () { if (typeof window === "undefined") { return; } var windowWithDevTools = window; var devtoolsSymbol = Symbol.for("apollo.devtools"); (windowWithDevTools[devtoolsSymbol] = windowWithDevTools[devtoolsSymbol] || []).push(this); windowWithDevTools.__APOLLO_CLIENT__ = this; /** * Suggest installing the devtools for developers who don't have them */ if (!hasSuggestedDevtools && globalThis.__DEV__ !== false) { hasSuggestedDevtools = true; if (window.document && window.top === window.self && /^(https?|file):$/.test(window.location.protocol)) { setTimeout(function () { if (!window.__APOLLO_DEVTOOLS_GLOBAL_HOOK__) { var nav = window.navigator; var ua = nav && nav.userAgent; var url = void 0; if (typeof ua === "string") { if (ua.indexOf("Chrome/") > -1) { url = "https://chrome.google.com/webstore/detail/" + "apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm"; } else if (ua.indexOf("Firefox/") > -1) { url = "https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/"; } } if (url) { globalThis.__DEV__ !== false && invariant.log("Download the Apollo DevTools for a better development " + "experience: %s", url); } } }, 10000); } } }; Object.defineProperty(ApolloClient.prototype, "documentTransform", { /** * The `DocumentTransform` used to modify GraphQL documents before a request * is made. If a custom `DocumentTransform` is not provided, this will be the * default document transform. */ get: function () { return this.queryManager.documentTransform; }, enumerable: false, configurable: true }); /** * Call this method to terminate any active client processes, making it safe * to dispose of this `ApolloClient` instance. */ ApolloClient.prototype.stop = function () { this.queryManager.stop(); }; /** * This watches the cache store of the query according to the options specified and * returns an `ObservableQuery`. We can subscribe to this `ObservableQuery` and * receive updated results through an observer when the cache store changes. * * Note that this method is not an implementation of GraphQL subscriptions. Rather, * it uses Apollo's store in order to reactively deliver updates to your query results. * * For example, suppose you call watchQuery on a GraphQL query that fetches a person's * first and last name and this person has a particular object identifier, provided by * dataIdFromObject. Later, a different query fetches that same person's * first and last name and the first name has now changed. Then, any observers associated * with the results of the first query will be updated with a new result object. * * Note that if the cache does not change, the subscriber will *not* be notified. * * See [here](https://medium.com/apollo-stack/the-concepts-of-graphql-bc68bd819be3#.3mb0cbcmc) for * a description of store reactivity. */ ApolloClient.prototype.watchQuery = function (options) { if (this.defaultOptions.watchQuery) { options = mergeOptions(this.defaultOptions.watchQuery, options); } // XXX Overwriting options is probably not the best way to do this long term... if (this.disableNetworkFetches && (options.fetchPolicy === "network-only" || options.fetchPolicy === "cache-and-network")) { options = __assign(__assign({}, options), { fetchPolicy: "cache-first" }); } return this.queryManager.watchQuery(options); }; /** * This resolves a single query according to the options specified and * returns a `Promise` which is either resolved with the resulting data * or rejected with an error. * * @param options - An object of type `QueryOptions` that allows us to * describe how this query should be treated e.g. whether it should hit the * server at all or just resolve from the cache, etc. */ ApolloClient.prototype.query = function (options) { if (this.defaultOptions.query) { options = mergeOptions(this.defaultOptions.query, options); } invariant(options.fetchPolicy !== "cache-and-network", 17); if (this.disableNetworkFetches && options.fetchPolicy === "network-only") { options = __assign(__assign({}, options), { fetchPolicy: "cache-first" }); } return this.queryManager.query(options); }; /** * This resolves a single mutation according to the options specified and returns a * Promise which is either resolved with the resulting data or rejected with an * error. In some cases both `data` and `errors` might be undefined, for example * when `errorPolicy` is set to `'ignore'`. * * It takes options as an object with the following keys and values: */ ApolloClient.prototype.mutate = function (options) { if (this.defaultOptions.mutate) { options = mergeOptions(this.defaultOptions.mutate, options); } return this.queryManager.mutate(options); }; /** * This subscribes to a graphql subscription according to the options specified and returns an * `Observable` which either emits received data or an error. */ ApolloClient.prototype.subscribe = function (options) { var _this = this; var id = this.queryManager.generateQueryId(); return this.queryManager .startGraphQLSubscription(options) .map(function (result) { return (__assign(__assign({}, result), { data: _this.queryManager.maskOperation({ document: options.query, data: result.data, fetchPolicy: options.fetchPolicy, id: id, }) })); }); }; /** * Tries to read some data from the store in the shape of the provided * GraphQL query without making a network request. This method will start at * the root query. To start at a specific id returned by `dataIdFromObject` * use `readFragment`. * * @param optimistic - Set to `true` to allow `readQuery` to return * optimistic results. Is `false` by default. */ ApolloClient.prototype.readQuery = function (options, optimistic) { if (optimistic === void 0) { optimistic = false; } return this.cache.readQuery(options, optimistic); }; /** * Watches the cache store of the fragment according to the options specified * and returns an `Observable`. We can subscribe to this * `Observable` and receive updated results through an * observer when the cache store changes. * * You must pass in a GraphQL document with a single fragment or a document * with multiple fragments that represent what you are reading. If you pass * in a document with multiple fragments then you must also specify a * `fragmentName`. * * @since 3.10.0 * @param options - An object of type `WatchFragmentOptions` that allows * the cache to identify the fragment and optionally specify whether to react * to optimistic updates. */ ApolloClient.prototype.watchFragment = function (options) { var _a; return this.cache.watchFragment(__assign(__assign({}, options), (_a = {}, _a[Symbol.for("apollo.dataMasking")] = this.queryManager.dataMasking, _a))); }; /** * Tries to read some data from the store in the shape of the provided * GraphQL fragment without making a network request. This method will read a * GraphQL fragment from any arbitrary id that is currently cached, unlike * `readQuery` which will only read from the root query. * * You must pass in a GraphQL document with a single fragment or a document * with multiple fragments that represent what you are reading. If you pass * in a document with multiple fragments then you must also specify a * `fragmentName`. * * @param optimistic - Set to `true` to allow `readFragment` to return * optimistic results. Is `false` by default. */ ApolloClient.prototype.readFragment = function (options, optimistic) { if (optimistic === void 0) { optimistic = false; } return this.cache.readFragment(options, optimistic); }; /** * Writes some data in the shape of the provided GraphQL query directly to * the store. This method will start at the root query. To start at a * specific id returned by `dataIdFromObject` then use `writeFragment`. */ ApolloClient.prototype.writeQuery = function (options) { var ref = this.cache.writeQuery(options); if (options.broadcast !== false) { this.queryManager.broadcastQueries(); } return ref; }; /** * Writes some data in the shape of the provided GraphQL fragment directly to * the store. This method will write to a GraphQL fragment from any arbitrary * id that is currently cached, unlike `writeQuery` which will only write * from the root query. * * You must pass in a GraphQL document with a single fragment or a document * with multiple fragments that represent what you are writing. If you pass * in a document with multiple fragments then you must also specify a * `fragmentName`. */ ApolloClient.prototype.writeFragment = function (options) { var ref = this.cache.writeFragment(options); if (options.broadcast !== false) { this.queryManager.broadcastQueries(); } return ref; }; ApolloClient.prototype.__actionHookForDevTools = function (cb) { this.devToolsHookCb = cb; }; ApolloClient.prototype.__requestRaw = function (payload) { return execute(this.link, payload); }; /** * Resets your entire store by clearing out your cache and then re-executing * all of your active queries. This makes it so that you may guarantee that * there is no data left in your store from a time before you called this * method. * * `resetStore()` is useful when your user just logged out. You’ve removed the * user session, and you now want to make sure that any references to data you * might have fetched while the user session was active is gone. * * It is important to remember that `resetStore()` *will* refetch any active * queries. This means that any components that might be mounted will execute * their queries again using your network interface. If you do not want to * re-execute any queries then you should make sure to stop watching any * active queries. */ ApolloClient.prototype.resetStore = function () { var _this = this; return Promise.resolve() .then(function () { return _this.queryManager.clearStore({ discardWatches: false, }); }) .then(function () { return Promise.all(_this.resetStoreCallbacks.map(function (fn) { return fn(); })); }) .then(function () { return _this.reFetchObservableQueries(); }); }; /** * Remove all data from the store. Unlike `resetStore`, `clearStore` will * not refetch any active queries. */ ApolloClient.prototype.clearStore = function () { var _this = this; return Promise.resolve() .then(function () { return _this.queryManager.clearStore({ discardWatches: true, }); }) .then(function () { return Promise.all(_this.clearStoreCallbacks.map(function (fn) { return fn(); })); }); }; /** * Allows callbacks to be registered that are executed when the store is * reset. `onResetStore` returns an unsubscribe function that can be used * to remove registered callbacks. */ ApolloClient.prototype.onResetStore = function (cb) { var _this = this; this.resetStoreCallbacks.push(cb); return function () { _this.resetStoreCallbacks = _this.resetStoreCallbacks.filter(function (c) { return c !== cb; }); }; }; /** * Allows callbacks to be registered that are executed when the store is * cleared. `onClearStore` returns an unsubscribe function that can be used * to remove registered callbacks. */ ApolloClient.prototype.onClearStore = function (cb) { var _this = this; this.clearStoreCallbacks.push(cb); return function () { _this.clearStoreCallbacks = _this.clearStoreCallbacks.filter(function (c) { return c !== cb; }); }; }; /** * Refetches all of your active queries. * * `reFetchObservableQueries()` is useful if you want to bring the client back to proper state in case of a network outage * * It is important to remember that `reFetchObservableQueries()` *will* refetch any active * queries. This means that any components that might be mounted will execute * their queries again using your network interface. If you do not want to * re-execute any queries then you should make sure to stop watching any * active queries. * Takes optional parameter `includeStandby` which will include queries in standby-mode when refetching. */ ApolloClient.prototype.reFetchObservableQueries = function (includeStandby) { return this.queryManager.reFetchObservableQueries(includeStandby); }; /** * Refetches specified active queries. Similar to "reFetchObservableQueries()" but with a specific list of queries. * * `refetchQueries()` is useful for use cases to imperatively refresh a selection of queries. * * It is important to remember that `refetchQueries()` *will* refetch specified active * queries. This means that any components that might be mounted will execute * their queries again using your network interface. If you do not want to * re-execute any queries then you should make sure to stop watching any * active queries. */ ApolloClient.prototype.refetchQueries = function (options) { var map = this.queryManager.refetchQueries(options); var queries = []; var results = []; map.forEach(function (result, obsQuery) { queries.push(obsQuery); results.push(result); }); var result = Promise.all(results); // In case you need the raw results immediately, without awaiting // Promise.all(results): result.queries = queries; result.results = results; // If you decide to ignore the result Promise because you're using // result.queries and result.results instead, you shouldn't have to worry // about preventing uncaught rejections for the Promise.all result. result.catch(function (error) { globalThis.__DEV__ !== false && invariant.debug(18, error); }); return result; }; /** * Get all currently active `ObservableQuery` objects, in a `Map` keyed by * query ID strings. * * An "active" query is one that has observers and a `fetchPolicy` other than * "standby" or "cache-only". * * You can include all `ObservableQuery` objects (including the inactive ones) * by passing "all" instead of "active", or you can include just a subset of * active queries by passing an array of query names or DocumentNode objects. */ ApolloClient.prototype.getObservableQueries = function (include) { if (include === void 0) { include = "active"; } return this.queryManager.getObservableQueries(include); }; /** * Exposes the cache's complete state, in a serializable format for later restoration. */ ApolloClient.prototype.extract = function (optimistic) { return this.cache.extract(optimistic); }; /** * Replaces existing state in the cache (if any) with the values expressed by * `serializedState`. * * Called when hydrating a cache (server side rendering, or offline storage), * and also (potentially) during hot reloads. */ ApolloClient.prototype.restore = function (serializedState) { return this.cache.restore(serializedState); }; /** * Add additional local resolvers. */ ApolloClient.prototype.addResolvers = function (resolvers) { this.localState.addResolvers(resolvers); }; /** * Set (override existing) local resolvers. */ ApolloClient.prototype.setResolvers = function (resolvers) { this.localState.setResolvers(resolvers); }; /** * Get all registered local resolvers. */ ApolloClient.prototype.getResolvers = function () { return this.localState.getResolvers(); }; /** * Set a custom local state fragment matcher. */ ApolloClient.prototype.setLocalStateFragmentMatcher = function (fragmentMatcher) { this.localState.setFragmentMatcher(fragmentMatcher); }; /** * Define a new ApolloLink (or link chain) that Apollo Client will use. */ ApolloClient.prototype.setLink = function (newLink) { this.link = this.queryManager.link = newLink; }; Object.defineProperty(ApolloClient.prototype, "defaultContext", { get: function () { return this.queryManager.defaultContext; }, enumerable: false, configurable: true }); return ApolloClient; }()); export { ApolloClient }; if (globalThis.__DEV__ !== false) { ApolloClient.prototype.getMemoryInternals = getApolloClientMemoryInternals; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXBvbGxvQ2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvcmUvQXBvbGxvQ2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFLN0UsT0FBTyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUk1RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXhDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUVqRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUF1QmpELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQXdCN0MsSUFBSSxvQkFBb0IsR0FBRyxLQUFLLENBQUM7QUFnR2pDLHNFQUFzRTtBQUN0RSw4RUFBOEU7QUFDOUUsOEVBQThFO0FBQzlFLGdGQUFnRjtBQUNoRixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDckQsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFNNUYsT0FBTyxFQUFFLFlBQVksRUFBRSxDQUFDO0FBRXhCOzs7OztHQUtHO0FBQ0g7SUFnQkU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0F5Qkc7SUFDSCxzQkFBWSxPQUF5QztRQUFyRCxpQkFnSEM7O1FBOUlPLHdCQUFtQixHQUE4QixFQUFFLENBQUM7UUFDcEQsd0JBQW1CLEdBQThCLEVBQUUsQ0FBQztRQThCMUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNuQixNQUFNLGlCQUFpQixDQUNyQixtRUFBbUU7Z0JBQ2pFLDJCQUEyQjtnQkFDM0Isa0VBQWtFLENBQ3JFLENBQUM7UUFDSixDQUFDO1FBR0MsSUFBQSxHQUFHLEdBc0JELE9BQU8s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SUFDL0MsQ0FBQztJQUVELHNCQUFXLHdDQUFjO2FBQXpCO1lBQ0UsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQztRQUMxQyxDQUFDOzs7T0FBQTtJQW1GSCxtQkFBQztBQUFELENBQUMsQUF4dkJELElBd3ZCQzs7QUFFRCxJQUFJLE9BQU8sRUFBRSxDQUFDO0lBQ1osWUFBWSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsR0FBRyw4QkFBOEIsQ0FBQztBQUM3RSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW52YXJpYW50LCBuZXdJbnZhcmlhbnRFcnJvciB9IGZyb20gXCIuLi91dGlsaXRpZXMvZ2xvYmFscy9pbmRleC5qc1wiO1xuXG5pbXBvcnQgdHlwZSB7IERvY3VtZW50Tm9kZSwgRm9ybWF0dGVkRXhlY3V0aW9uUmVzdWx0IH0gZnJvbSBcImdyYXBocWxcIjtcblxuaW1wb3J0IHR5cGUgeyBGZXRjaFJlc3VsdCwgR3JhcGhRTFJlcXVlc3QgfSBmcm9tIFwiLi4vbGluay9jb3JlL2luZGV4LmpzXCI7XG5pbXBvcnQgeyBBcG9sbG9MaW5rLCBleGVjdXRlIH0gZnJvbSBcIi4uL2xpbmsvY29yZS9pbmRleC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBBcG9sbG9DYWNoZSwgRGF0YVByb3h5LCBSZWZlcmVuY2UgfSBmcm9tIFwiLi4vY2FjaGUvaW5kZXguanNcIjtcbmltcG9ydCB0eXBlIHsgRG9jdW1lbnRUcmFuc2Zvcm0gfSBmcm9tIFwiLi4vdXRpbGl0aWVzL2luZGV4LmpzXCI7XG5pbXBvcnQgdHlwZSB7IE9ic2VydmFibGUgfSBmcm9tIFwiLi4vdXRpbGl0aWVzL2luZGV4LmpzXCI7XG5pbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSBcIi4uL3ZlcnNpb24uanNcIjtcbmltcG9ydCB0eXBlIHsgVXJpRnVuY3Rpb24gfSBmcm9tIFwiLi4vbGluay9odHRwL2luZGV4LmpzXCI7XG5pbXBvcnQgeyBIdHRwTGluayB9IGZyb20gXCIuLi9saW5rL2h0dHAvaW5kZXguanNcIjtcblxuaW1wb3J0IHsgUXVlcnlNYW5hZ2VyIH0gZnJvbSBcIi4vUXVlcnlNYW5hZ2VyLmpzXCI7XG5pbXBvcnQgdHlwZSB7IE9ic2VydmFibGVRdWVyeSB9IGZyb20gXCIuL09ic2VydmFibGVRdWVyeS5qc1wiO1xuXG5pbXBvcnQgdHlwZSB7XG4gIEFwb2xsb1F1ZXJ5UmVzdWx0LFxuICBEZWZhdWx0Q29udGV4dCxcbiAgT3BlcmF0aW9uVmFyaWFibGVzLFxuICBSZXNvbHZlcnMsXG4gIFJlZmV0Y2hRdWVyaWVzT3B0aW9ucyxcbiAgUmVmZXRjaFF1ZXJpZXNSZXN1bHQsXG4gIEludGVybmFsUmVmZXRjaFF1ZXJpZXNSZXN1bHQsXG4gIFJlZmV0Y2hRdWVyaWVzSW5jbHVkZSxcbn0gZnJvbSBcIi4vdHlwZXMuanNcIjtcblxuaW1wb3J0IHR5cGUge1xuICBRdWVyeU9wdGlvbnMsXG4gIFdhdGNoUXVlcnlPcHRpb25zLFxuICBNdXRhdGlvbk9wdGlvbnMsXG4gIFN1YnNjcmlwdGlvbk9wdGlvbnMsXG4gIFdhdGNoUXVlcnlGZXRjaFBvbGljeSxcbn0gZnJvbSBcIi4vd2F0Y2hRdWVyeU9wdGlvbnMuanNcIjtcblxuaW1wb3J0IHR5cGUgeyBGcmFnbWVudE1hdGNoZXIgfSBmcm9tIFwiLi9Mb2NhbFN0YXRlLmpzXCI7XG5pbXBvcnQgeyBMb2NhbFN0YXRlIH0gZnJvbSBcIi4vTG9jYWxTdGF0ZS5qc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIERlZmF1bHRPcHRpb25zIHtcbiAgd2F0Y2hRdWVyeT86IFBhcnRpYWw8V2F0Y2hRdWVyeU9wdGlvbnM8YW55LCBhbnk+PjtcbiAgcXVlcnk/OiBQYXJ0aWFsPFF1ZXJ5T3B0aW9uczxhbnksIGFueT4+O1xuICBtdXRhdGU/OiBQYXJ0aWFsPE11dGF0aW9uT3B0aW9uczxhbnksIGFueSwgYW55Pj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGV2dG9vbHNPcHRpb25zIHtcbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgdGhlIFtBcG9sbG8gQ2xpZW50IERldnRvb2xzXShodHRwczovL3d3dy5hcG9sbG9ncmFwaHFsLmNvbS9kb2NzL3JlYWN0L2RldmVsb3BtZW50LXRlc3RpbmcvZGV2ZWxvcGVyLXRvb2xpbmcvI2Fwb2xsby1jbGllbnQtZGV2dG9vbHMpIGJyb3dzZXIgZXh0ZW5zaW9uIGNhbiBjb25uZWN0IHRvIHRoaXMgYEFwb2xsb0NsaWVudGAgaW5zdGFuY2UuXG4gICAqXG4gICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGBmYWxzZWAgaW4gcHJvZHVjdGlvbiBhbmQgYHRydWVgIGluIGRldmVsb3BtZW50IGlmIHRoZXJlIGlzIGEgYHdpbmRvd2Agb2JqZWN0LlxuICAgKi9cbiAgZW5hYmxlZD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIG5hbWUgZm9yIHRoaXMgYEFwb2xsb0NsaWVudGAgaW5zdGFuY2UgaW4gdGhlIGRldnRvb2xzLiBUaGlzIGlzXG4gICAqIHVzZWZ1bCB3aGVuIHlvdSBpbnN0YW50aWF0ZSBtdWx0aXBsZSBjbGllbnRzIGFuZCB3YW50IHRvIGJlIGFibGUgdG9cbiAgICogaWRlbnRpZnkgdGhlbSBieSBuYW1lLlxuICAgKi9cbiAgbmFtZT86IHN0cmluZztcbn1cblxubGV0IGhhc1N1Z2dlc3RlZERldnRvb2xzID0gZmFsc2U7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXBvbGxvQ2xpZW50T3B0aW9uczxUQ2FjaGVTaGFwZT4ge1xuICAvKipcbiAgICogVGhlIFVSSSBvZiB0aGUgR3JhcGhRTCBlbmRwb2ludCB0aGF0IEFwb2xsbyBDbGllbnQgd2lsbCBjb21tdW5pY2F0ZSB3aXRoLlxuICAgKlxuICAgKiBPbmUgb2YgYHVyaWAgb3IgYGxpbmtgIGlzICoqcmVxdWlyZWQqKi4gSWYgeW91IHByb3ZpZGUgYm90aCwgYGxpbmtgIHRha2VzIHByZWNlZGVuY2UuXG4gICAqL1xuICB1cmk/OiBzdHJpbmcgfCBVcmlGdW5jdGlvbjtcbiAgY3JlZGVudGlhbHM/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBbiBvYmplY3QgcmVwcmVzZW50aW5nIGhlYWRlcnMgdG8gaW5jbHVkZSBpbiBldmVyeSBIVFRQIHJlcXVlc3QsIHN1Y2ggYXMgYHtBdXRob3JpemF0aW9uOiAnQmVhcmVyIDEyMzQnfWBcbiAgICpcbiAgICogVGhpcyB2YWx1ZSB3aWxsIGJlIGlnbm9yZWQgd2hlbiB1c2luZyB0aGUgYGxpbmtgIG9wdGlvbi5cbiAgICovXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICAvKipcbiAgICogWW91IGNhbiBwcm92aWRlIGFuIGBBcG9sbG9MaW5rYCBpbnN0YW5jZSB0byBzZXJ2ZSBhcyBBcG9sbG8gQ2xpZW50J3MgbmV0d29yayBsYXllci4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQWR2YW5jZWQgSFRUUCBuZXR3b3JraW5nXShodHRwczovL3d3dy5hcG9sbG9ncmFwaHFsLmNvbS9kb2NzL3JlYWN0L25ldHdvcmtpbmcvYWR2YW5jZWQtaHR0cC1uZXR3b3JraW5nLykuXG4gICAqXG4gICAqIE9uZSBvZiBgdXJpYCBvciBgbGlua2AgaXMgKipyZXF1aXJlZCoqLiBJZiB5b3UgcHJvdmlkZSBib3RoLCBgbGlua2AgdGFrZXMgcHJlY2VkZW5jZS5cbiAgICovXG4gIGxpbms/OiBBcG9sbG9MaW5rO1xuICAvKipcbiAgICogVGhlIGNhY2hlIHRoYXQgQXBvbGxvIENsaWVudCBzaG91bGQgdXNlIHRvIHN0b3JlIHF1ZXJ5IHJlc3VsdHMgbG9jYWxseS4gVGhlIHJlY29tbWVuZGVkIGNhY2hlIGlzIGBJbk1lbW9yeUNhY2hlYCwgd2hpY2ggaXMgcHJvdmlkZWQgYnkgdGhlIGBAYXBvbGxvL2NsaWVudGAgcGFja2FnZS5cbiAgICpcbiAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQ29uZmlndXJpbmcgdGhlIGNhY2hlXShodHRwczovL3d3dy5hcG9sbG9ncmFwaHFsLmNvbS9kb2NzL3JlYWN0L2NhY2hpbmcvY2FjaGUtY29uZmlndXJhdGlvbi8pLlxuICAgKi9cbiAgY2FjaGU6IEFwb2xsb0NhY2hlPFRDYWNoZVNoYXBlPjtcbiAgLyoqXG4gICAqIFRoZSB0aW1lIGludGVydmFsIChpbiBtaWxsaXNlY29uZHMpIGJlZm9yZSBBcG9sbG8gQ2xpZW50IGZvcmNlLWZldGNoZXMgcXVlcmllcyBhZnRlciBhIHNlcnZlci1zaWRlIHJlbmRlci5cbiAgICpcbiAgICogQGRlZmF1bHRWYWx1ZSBgMGAgKG5vIGRlbGF5KVxuICAgKi9cbiAgc3NyRm9yY2VGZXRjaERlbGF5PzogbnVtYmVyO1xuICAvKipcbiAgICogV2hlbiB1c2luZyBBcG9sbG8gQ2xpZW50IGZvciBbc2VydmVyLXNpZGUgcmVuZGVyaW5nXShodHRwczovL3d3dy5hcG9sbG9ncmFwaHFsLmNvbS9kb2NzL3JlYWN0L3BlcmZvcm1hbmNlL3NlcnZlci1zaWRlLXJlbmRlcmluZy8pLCBzZXQgdGhpcyB0byBgdHJ1ZWAgc28gdGhhdCB0aGUgW2BnZXREYXRhRnJvbVRyZWVgIGZ1bmN0aW9uXSguLi9yZWFjdC9zc3IvI2dldGRhdGFmcm9tdHJlZSkgY2FuIHdvcmsgZWZmZWN0aXZlbHkuXG4gICAqXG4gICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgKi9cbiAgc3NyTW9kZT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBJZiBgdHJ1ZWAsIHRoZSBbQXBvbGxvIENsaWVudCBEZXZ0b29sc10oaHR0cHM6Ly93d3cuYXBvbGxvZ3JhcGhxbC5jb20vZG9jcy9yZWFjdC9kZXZlbG9wbWVudC10ZXN0aW5nL2RldmVsb3Blci10b29saW5nLyNhcG9sbG8tY2xpZW50LWRldnRvb2xzKSBicm93c2VyIGV4dGVuc2lvbiBjYW4gY29ubmVjdCB0byBBcG9sbG8gQ2xpZW50LlxuICAgKlxuICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgZmFsc2VgIGluIHByb2R1Y3Rpb24gYW5kIGB0cnVlYCBpbiBkZXZlbG9wbWVudCAoaWYgdGhlcmUgaXMgYSBgd2luZG93YCBvYmplY3QpLlxuICAgKiBAZGVwcmVjYXRlZCBQbGVhc2UgdXNlIHRoZSBgZGV2dG9vbHMuZW5hYmxlZGAgb3B0aW9uLlxuICAgKi9cbiAgY29ubmVjdFRvRGV2VG9vbHM/OiBib29sZWFuO1xuICAvKipcbiAgICogSWYgYGZhbHNlYCwgQXBvbGxvIENsaWVudCBzZW5kcyBldmVyeSBjcmVhdGVkIHF1ZXJ5IHRvIHRoZSBzZXJ2ZXIsIGV2ZW4gaWYgYSBfY29tcGxldGVseV8gaWRlbnRpY2FsIHF1ZXJ5IChpZGVudGljYWwgaW4gdGVybXMgb2YgcXVlcnkgc3RyaW5nLCB2YXJpYWJsZSB2YWx1ZXMsIGFuZCBvcGVyYXRpb25OYW1lKSBpcyBhbHJlYWR5IGluIGZsaWdodC5cbiAgICpcbiAgICogQGRlZmF1bHRWYWx1ZSBgdHJ1ZWBcbiAgICovXG4gIHF1ZXJ5RGVkdXBsaWNhdGlvbj86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBQcm92aWRlIHRoaXMgb2JqZWN0IHRvIHNldCBhcHBsaWNhdGlvbi13aWRlIGRlZmF1bHQgdmFsdWVzIGZvciBvcHRpb25zIHlvdSBjYW4gcHJvdmlkZSB0byB0aGUgYHdhdGNoUXVlcnlgLCBgcXVlcnlgLCBhbmQgYG11dGF0ZWAgZnVuY3Rpb25zLiBTZWUgYmVsb3cgZm9yIGFuIGV4YW1wbGUgb2JqZWN0LlxuICAgKlxuICAgKiBTZWUgdGhpcyBbZXhhbXBsZSBvYmplY3RdKGh0dHBzOi8vd3d3LmFwb2xsb2dyYXBocWwuY29tL2RvY3MvcmVhY3QvYXBpL2NvcmUvQXBvbGxvQ2xpZW50I2V4YW1wbGUtZGVmYXVsdG9wdGlvbnMtb2JqZWN0KS5cbiAgICovXG4gIGRlZmF1bHRPcHRpb25zPzogRGVmYXVsdE9wdGlvbnM7XG4gIGRlZmF1bHRDb250ZXh0PzogUGFydGlhbDxEZWZhdWx0Q29udGV4dD47XG4gIC8qKlxuICAgKiBJZiBgdHJ1ZWAsIEFwb2xsbyBDbGllbnQgd2lsbCBhc3N1bWUgcmVzdWx0cyByZWFkIGZyb20gdGhlIGNhY2hlIGFyZSBuZXZlciBtdXRhdGVkIGJ5IGFwcGxpY2F0aW9uIGNvZGUsIHdoaWNoIGVuYWJsZXMgc3Vic3RhbnRpYWwgcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9ucy5cbiAgICpcbiAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAqL1xuICBhc3N1bWVJbW11dGFibGVSZXN1bHRzPzogYm9vbGVhbjtcbiAgcmVzb2x2ZXJzPzogUmVzb2x2ZXJzIHwgUmVzb2x2ZXJzW107XG4gIHR5cGVEZWZzPzogc3RyaW5nIHwgc3RyaW5nW10gfCBEb2N1bWVudE5vZGUgfCBEb2N1bWVudE5vZGVbXTtcbiAgZnJhZ21lbnRNYXRjaGVyPzogRnJhZ21lbnRNYXRjaGVyO1xuICAvKipcbiAgICogQSBjdXN0b20gbmFtZSAoZS5nLiwgYGlPU2ApIHRoYXQgaWRlbnRpZmllcyB0aGlzIHBhcnRpY3VsYXIgY2xpZW50IGFtb25nIHlvdXIgc2V0IG9mIGNsaWVudHMuIEFwb2xsbyBTZXJ2ZXIgYW5kIEFwb2xsbyBTdHVkaW8gdXNlIHRoaXMgcHJvcGVydHkgYXMgcGFydCBvZiB0aGUgW2NsaWVudCBhd2FyZW5lc3NdKGh0dHBzOi8vd3d3LmFwb2xsb2dyYXBocWwuY29tL2RvY3MvYXBvbGxvLXNlcnZlci9tb25pdG9yaW5nL21ldHJpY3MjaWRlbnRpZnlpbmctZGlzdGluY3QtY2xpZW50cykgZmVhdHVyZS5cbiAgICovXG4gIG5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBIGN1c3RvbSB2ZXJzaW9uIHRoYXQgaWRlbnRpZmllcyB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoaXMgcGFydGljdWxhciBjbGllbnQgKGUuZy4sIGAxLjJgKS4gQXBvbGxvIFNlcnZlciBhbmQgQXBvbGxvIFN0dWRpbyB1c2UgdGhpcyBwcm9wZXJ0eSBhcyBwYXJ0IG9mIHRoZSBbY2xpZW50IGF3YXJlbmVzc10oaHR0cHM6Ly93d3cuYXBvbGxvZ3JhcGhxbC5jb20vZG9jcy9hcG9sbG8tc2VydmVyL21vbml0b3JpbmcvbWV0cmljcyNpZGVudGlmeWluZy1kaXN0aW5jdC1jbGllbnRzKSBmZWF0dXJlLlxuICAgKlxuICAgKiBUaGlzIGlzICoqbm90KiogdGhlIHZlcnNpb24gb2YgQXBvbGxvIENsaWVudCB0aGF0IHlvdSBhcmUgdXNpbmcsIGJ1dCByYXRoZXIgYW55IHZlcnNpb24gc3RyaW5nIHRoYXQgaGVscHMgeW91IGRpZmZlcmVudGlhdGUgYmV0d2VlbiB2ZXJzaW9ucyBvZiB5b3VyIGNsaWVudC5cbiAgICovXG4gIHZlcnNpb24/OiBzdHJpbmc7XG4gIGRvY3VtZW50VHJhbnNmb3JtPzogRG9jdW1lbnRUcmFuc2Zvcm07XG5cbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gdXNlZCBieSB0aGUgW0Fwb2xsbyBDbGllbnQgRGV2dG9vbHMgZXh0ZW5zaW9uXShodHRwczovL3d3dy5hcG9sbG9ncmFwaHFsLmNvbS9kb2NzL3JlYWN0L2RldmVsb3BtZW50LXRlc3RpbmcvZGV2ZWxvcGVyLXRvb2xpbmcvI2Fwb2xsby1jbGllbnQtZGV2dG9vbHMpIGZvciB0aGlzIGNsaWVudC5cbiAgICpcbiAgICogQHNpbmNlIDMuMTEuMFxuICAgKi9cbiAgZGV2dG9vbHM/OiBEZXZ0b29sc09wdGlvbnM7XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgaWYgZGF0YSBtYXNraW5nIGlzIGVuYWJsZWQgZm9yIHRoZSBjbGllbnQuXG4gICAqXG4gICAqIEBkZWZhdWx0VmFsdWUgZmFsc2VcbiAgICovXG4gIGRhdGFNYXNraW5nPzogYm9vbGVhbjtcbn1cblxuLy8gVGhvdWdoIG1lcmdlT3B0aW9ucyBub3cgcmVzaWRlcyBpbiBAYXBvbGxvL2NsaWVudC91dGlsaXRpZXMsIGl0IHdhc1xuLy8gcHJldmlvdXNseSBkZWNsYXJlZCBhbmQgZXhwb3J0ZWQgZnJvbSB0aGlzIG1vZHVsZSwgYW5kIHRoZW4gcmVleHBvcnRlZCBmcm9tXG4vLyBAYXBvbGxvL2NsaWVudC9jb3JlLiBTaW5jZSB3ZSBuZWVkIHRvIHByZXNlcnZlIHRoYXQgQVBJIGFueXdheSwgdGhlIGVhc2llc3Rcbi8vIHNvbHV0aW9uIGlzIHRvIHJlZXhwb3J0IG1lcmdlT3B0aW9ucyB3aGVyZSBpdCB3YXMgcHJldmlvdXNseSBkZWNsYXJlZCAoaGVyZSkuXG5pbXBvcnQgeyBtZXJnZU9wdGlvbnMgfSBmcm9tIFwiLi4vdXRpbGl0aWVzL2luZGV4LmpzXCI7XG5pbXBvcnQgeyBnZXRBcG9sbG9DbGllbnRNZW1vcnlJbnRlcm5hbHMgfSBmcm9tIFwiLi4vdXRpbGl0aWVzL2NhY2hpbmcvZ2V0TWVtb3J5SW50ZXJuYWxzLmpzXCI7XG5pbXBvcnQgdHlwZSB7XG4gIFdhdGNoRnJhZ21lbnRPcHRpb25zLFxuICBXYXRjaEZyYWdtZW50UmVzdWx0LFxufSBmcm9tIFwiLi4vY2FjaGUvY29yZS9jYWNoZS5qc1wiO1xuaW1wb3J0IHR5cGUgeyBNYXliZU1hc2tlZCwgVW5tYXNrZWQgfSBmcm9tIFwiLi4vbWFza2luZy9pbmRleC5qc1wiO1xuZXhwb3J0IHsgbWVyZ2VPcHRpb25zIH07XG5cbi8qKlxuICogVGhpcyBpcyB0aGUgcHJpbWFyeSBBcG9sbG8gQ2xpZW50IGNsYXNzLiBJdCBpcyB1c2VkIHRvIHNlbmQgR3JhcGhRTCBkb2N1bWVudHMgKGkuZS4gcXVlcmllc1xuICogYW5kIG11dGF0aW9ucykgdG8gYSBHcmFwaFFMIHNwZWMtY29tcGxpYW50IHNlcnZlciBvdmVyIGFuIGBBcG9sbG9MaW5rYCBpbnN0YW5jZSxcbiAqIHJlY2VpdmUgcmVzdWx0cyBmcm9tIHRoZSBzZXJ2ZXIgYW5kIGNhY2hlIHRoZSByZXN1bHRzIGluIGEgc3RvcmUuIEl0IGFsc28gZGVsaXZlcnMgdXBkYXRlc1xuICogdG8gR3JhcGhRTCBxdWVyaWVzIHRocm91Z2ggYE9ic2VydmFibGVgIGluc3RhbmNlcy5cbiAqL1xuZXhwb3J0IGNsYXNzIEFwb2xsb0NsaWVudDxUQ2FjaGVTaGFwZT4gaW1wbGVtZW50cyBEYXRhUHJveHkge1xuICBwdWJsaWMgbGluazogQXBvbGxvTGluaztcbiAgcHVibGljIGNhY2hlOiBBcG9sbG9DYWNoZTxUQ2FjaGVTaGFwZT47XG4gIHB1YmxpYyBkaXNhYmxlTmV0d29ya0ZldGNoZXM6IGJvb2xlYW47XG4gIHB1YmxpYyB2ZXJzaW9uOiBzdHJpbmc7XG4gIHB1YmxpYyBxdWVyeURlZHVwbGljYXRpb246IGJvb2xlYW47XG4gIHB1YmxpYyBkZWZhdWx0T3B0aW9uczogRGVmYXVsdE9wdGlvbnM7XG4gIHB1YmxpYyByZWFkb25seSB0eXBlRGVmczogQXBvbGxvQ2xpZW50T3B0aW9uczxUQ2FjaGVTaGFwZT5bXCJ0eXBlRGVmc1wiXTtcbiAgcHVibGljIHJlYWRvbmx5IGRldnRvb2xzQ29uZmlnOiBEZXZ0b29sc09wdGlvbnM7XG5cbiAgcHJpdmF0ZSBxdWVyeU1hbmFnZXI6IFF1ZXJ5TWFuYWdlcjxUQ2FjaGVTaGFwZT47XG4gIHByaXZhdGUgZGV2VG9vbHNIb29rQ2I/OiBGdW5jdGlvbjtcbiAgcHJpdmF0ZSByZXNldFN0b3JlQ2FsbGJhY2tzOiBBcnJheTwoKSA9PiBQcm9taXNlPGFueT4+ID0gW107XG4gIHByaXZhdGUgY2xlYXJTdG9yZUNhbGxiYWNrczogQXJyYXk8KCkgPT4gUHJvbWlzZTxhbnk+PiA9IFtdO1xuICBwcml2YXRlIGxvY2FsU3RhdGU6IExvY2FsU3RhdGU8VENhY2hlU2hhcGU+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGFuIGluc3RhbmNlIG9mIGBBcG9sbG9DbGllbnRgLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGBqc1xuICAgKiBpbXBvcnQgeyBBcG9sbG9DbGllbnQsIEluTWVtb3J5Q2FjaGUgfSBmcm9tICdAYXBvbGxvL2NsaWVudCc7XG4gICAqXG4gICAqIGNvbnN0IGNhY2hlID0gbmV3IEluTWVtb3J5Q2FjaGUoKTtcbiAgICpcbiAgICogY29uc3QgY2xpZW50ID0gbmV3IEFwb2xsb0NsaWVudCh7XG4gICAqICAgLy8gUHJvdmlkZSByZXF1aXJlZCBjb25zdHJ1Y3RvciBmaWVsZHNcbiAgICogICBjYWNoZTogY2FjaGUsXG4gICAqICAgdXJpOiAnaHR0cDovL2xvY2FsaG9zdDo0MDAwLycsXG4gICAqXG4gICAqICAgLy8gUHJvdmlkZSBzb21lIG9wdGlvbmFsIGNvbnN0cnVjdG9yIGZpZWxkc1xuICAgKiAgIG5hbWU6ICdyZWFjdC13ZWItY2xpZW50JyxcbiAgICogICB2ZXJzaW9uOiAnMS4zJyxcbiAgICogICBxdWVyeURlZHVwbGljYXRpb246IGZhbHNlLFxuICAgKiAgIGRlZmF1bHRPcHRpb25zOiB7XG4gICAqICAgICB3YXRjaFF1ZXJ5OiB7XG4gICAqICAgICAgIGZldGNoUG9saWN5OiAnY2FjaGUtYW5kLW5ldHdvcmsnLFxuICAgKiAgICAgfSxcbiAgICogICB9LFxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBBcG9sbG9DbGllbnRPcHRpb25zPFRDYWNoZVNoYXBlPikge1xuICAgIGlmICghb3B0aW9ucy5jYWNoZSkge1xuICAgICAgdGhyb3cgbmV3SW52YXJpYW50RXJyb3IoXG4gICAgICAgIFwiVG8gaW5pdGlhbGl6ZSBBcG9sbG8gQ2xpZW50LCB5b3UgbXVzdCBzcGVjaWZ5IGEgJ2NhY2hlJyBwcm9wZXJ0eSBcIiArXG4gICAgICAgICAgXCJpbiB0aGUgb3B0aW9ucyBvYmplY3QuIFxcblwiICtcbiAgICAgICAgICBcIkZvciBtb3JlIGluZm9ybWF0aW9uLCBwbGVhc2UgdmlzaXQ6IGh0dHBzOi8vZ28uYXBvbGxvLmRldi9jL2RvY3NcIlxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCB7XG4gICAgICB1cmksXG4gICAgICBjcmVkZW50aWFscyxcbiAgICAgIGhlYWRlcnMsXG4gICAgICBjYWNoZSxcbiAgICAgIGRvY3VtZW50VHJhbnNmb3JtLFxuICAgICAgc3NyTW9kZSA9IGZhbHNlLFxuICAgICAgc3NyRm9yY2VGZXRjaERlbGF5ID0gMCxcbiAgICAgIC8vIEV4cG9zZSB0aGUgY2xpZW50IGluc3RhbmNlIGFzIHdpbmRvdy5fX0FQT0xMT19DTElFTlRfXyBhbmQgY2FsbFxuICAgICAgLy8gb25Ccm9hZGNhc3QgaW4gcXVlcnlNYW5hZ2VyLmJyb2FkY2FzdFF1ZXJpZXMgdG8gZW5hYmxlIGJyb3dzZXJcbiAgICAgIC8vIGRldnRvb2xzLCBidXQgZGlzYWJsZSB0aGVtIGJ5IGRlZmF1bHQgaW4gcHJvZHVjdGlvbi5cbiAgICAgIGNvbm5lY3RUb0RldlRvb2xzLFxuICAgICAgcXVlcnlEZWR1cGxpY2F0aW9uID0gdHJ1ZSxcbiAgICAgIGRlZmF1bHRPcHRpb25zLFxuICAgICAgZGVmYXVsdENvbnRleHQsXG4gICAgICBhc3N1bWVJbW11dGFibGVSZXN1bHRzID0gY2FjaGUuYXNzdW1lSW1tdXRhYmxlUmVzdWx0cyxcbiAgICAgIHJlc29sdmVycyxcbiAgICAgIHR5cGVEZWZzLFxuICAgICAgZnJhZ21lbnRNYXRjaGVyLFxuICAgICAgbmFtZTogY2xpZW50QXdhcmVuZXNzTmFtZSxcbiAgICAgIHZlcnNpb246IGNsaWVudEF3YXJlbmVzc1ZlcnNpb24sXG4gICAgICBkZXZ0b29scyxcbiAgICAgIGRhdGFNYXNraW5nLFxuICAgIH0gPSBvcHRpb25zO1xuXG4gICAgbGV0IHsgbGluayB9ID0gb3B0aW9ucztcblxuICAgIGlmICghbGluaykge1xuICAgICAgbGluayA9XG4gICAgICAgIHVyaSA/IG5ldyBIdHRwTGluayh7IHVyaSwgY3JlZGVudGlhbHMsIGhlYWRlcnMgfSkgOiBBcG9sbG9MaW5rLmVtcHR5KCk7XG4gICAgfVxuXG4gICAgdGhpcy5saW5rID0gbGluaztcbiAgICB0aGlzLmNhY2hlID0gY2FjaGU7XG4gICAgdGhpcy5kaXNhYmxlTmV0d29ya0ZldGNoZXMgPSBzc3JNb2RlIHx8IHNzckZvcmNlRmV0Y2hEZWxheSA+IDA7XG4gICAgdGhpcy5xdWVyeURlZHVwbGljYXRpb24gPSBxdWVyeURlZHVwbGljYXRpb247XG4gICAgdGhpcy5kZWZhdWx0T3B0aW9ucyA9IGRlZmF1bHRPcHRpb25zIHx8IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGhpcy50eXBlRGVmcyA9IHR5cGVEZWZzO1xuICAgIHRoaXMuZGV2dG9vbHNDb25maWcgPSB7XG4gICAgICAuLi5kZXZ0b29scyxcbiAgICAgIGVuYWJsZWQ6IGRldnRvb2xzPy5lbmFibGVkID8/IGNvbm5lY3RUb0RldlRvb2xzLFxuICAgIH07XG5cbiAgICBpZiAodGhpcy5kZXZ0b29sc0NvbmZpZy5lbmFibGVkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuZGV2dG9vbHNDb25maWcuZW5hYmxlZCA9IF9fREVWX187XG4gICAgfVxuXG4gICAgaWYgKHNzckZvcmNlRmV0Y2hEZWxheSkge1xuICAgICAgc2V0VGltZW91dChcbiAgICAgICAgKCkgPT4gKHRoaXMuZGlzYWJsZU5ldHdvcmtGZXRjaGVzID0gZmFsc2UpLFxuICAgICAgICBzc3JGb3JjZUZldGNoRGVsYXlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy53YXRjaFF1ZXJ5ID0gdGhpcy53YXRjaFF1ZXJ5LmJpbmQodGhpcyk7XG4gICAgdGhpcy5xdWVyeSA9IHRoaXMucXVlcnkuYmluZCh0aGlzKTtcbiAgICB0aGlzLm11dGF0ZSA9IHRoaXMubXV0YXRlLmJpbmQodGhpcyk7XG4gICAgdGhpcy53YXRjaEZyYWdtZW50ID0gdGhpcy53YXRjaEZyYWdtZW50LmJpbmQodGhpcyk7XG4gICAgdGhpcy5yZXNldFN0b3JlID0gdGhpcy5yZXNldFN0b3JlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5yZUZldGNoT2JzZXJ2YWJsZVF1ZXJpZXMgPSB0aGlzLnJlRmV0Y2hPYnNlcnZhYmxlUXVlcmllcy5iaW5kKHRoaXMpO1xuXG4gICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjtcblxuICAgIHRoaXMubG9jYWxTdGF0ZSA9IG5ldyBMb2NhbFN0YXRlKHtcbiAgICAgIGNhY2hlLFxuICAgICAgY2xpZW50OiB0aGlzLFxuICAgICAgcmVzb2x2ZXJzLFxuICAgICAgZnJhZ21lbnRNYXRjaGVyLFxuICAgIH0pO1xuXG4gICAgdGhpcy5xdWVyeU1hbmFnZXIgPSBuZXcgUXVlcnlNYW5hZ2VyKHtcbiAgICAgIGNhY2hlOiB0aGlzLmNhY2hlLFxuICAgICAgbGluazogdGhpcy5saW5rLFxuICAgICAgZGVmYXVsdE9wdGlvbnM6IHRoaXMuZGVmYXVsdE9wdGlvbnMsXG4gICAgICBkZWZhdWx0Q29udGV4dCxcbiAgICAgIGRvY3VtZW50VHJhbnNmb3JtLFxuICAgICAgcXVlcnlEZWR1cGxpY2F0aW9uLFxuICAgICAgc3NyTW9kZSxcbiAgICAgIGRhdGFNYXNraW5nOiAhIWRhdGFNYXNraW5nLFxuICAgICAgY2xpZW50QXdhcmVuZXNzOiB7XG4gICAgICAgIG5hbWU6IGNsaWVudEF3YXJlbmVzc05hbWUhLFxuICAgICAgICB2ZXJzaW9uOiBjbGllbnRBd2FyZW5lc3NWZXJzaW9uISxcbiAgICAgIH0sXG4gICAgICBsb2NhbFN0YXRlOiB0aGlzLmxvY2FsU3RhdGUsXG4gICAgICBhc3N1bWVJbW11dGFibGVSZXN1bHRzLFxuICAgICAgb25Ccm9hZGNhc3Q6XG4gICAgICAgIHRoaXMuZGV2dG9vbHNDb25maWcuZW5hYmxlZCA/XG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuZGV2VG9vbHNIb29rQ2IpIHtcbiAgICAgICAgICAgICAgdGhpcy5kZXZUb29sc0hvb2tDYih7XG4gICAgICAgICAgICAgICAgYWN0aW9uOiB7fSxcbiAgICAgICAgICAgICAgICBzdGF0ZToge1xuICAgICAgICAgICAgICAgICAgcXVlcmllczogdGhpcy5xdWVyeU1hbmFnZXIuZ2V0UXVlcnlTdG9yZSgpLFxuICAgICAgICAgICAgICAgICAgbXV0YXRpb25zOiB0aGlzLnF1ZXJ5TWFuYWdlci5tdXRhdGlvblN0b3JlIHx8IHt9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZGF0YVdpdGhPcHRpbWlzdGljUmVzdWx0czogdGhpcy5jYWNoZS5leHRyYWN0KHRydWUpLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIDogdm9pZCAwLFxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuZGV2dG9vbHNDb25maWcuZW5hYmxlZCkgdGhpcy5jb25uZWN0VG9EZXZUb29scygpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25uZWN0VG9EZXZUb29scygpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHR5cGUgRGV2VG9vbHNDb25uZWN0b3IgPSB7XG4gICAgICBwdXNoKGNsaWVudDogQXBvbGxvQ2xpZW50PGFueT4pOiB2b2lkO1xuICAgIH07XG4gICAgY29uc3Qgd2luZG93V2l0aERldlRvb2xzID0gd2luZG93IGFzIFdpbmRvdyAmIHtcbiAgICAgIFtkZXZ0b29sc1N5bWJvbF0/OiBEZXZUb29sc0Nvbm5lY3RvcjtcbiAgICAgIF9fQVBPTExPX0NMSUVOVF9fPzogQXBvbGxvQ2xpZW50PGFueT47XG4gICAgfTtcbiAgICBjb25zdCBkZXZ0b29sc1N5bWJvbCA9IFN5bWJvbC5mb3IoXCJhcG9sbG8uZGV2dG9vbHNcIik7XG4gICAgKHdpbmRvd1dpdGhEZXZUb29sc1tkZXZ0b29sc1N5bWJvbF0gPVxuICAgICAgd2luZG93V2l0aERldlRvb2xzW2RldnRvb2xzU3ltYm9sXSB8fCAoW10gYXMgRGV2VG9vbHNDb25uZWN0b3IpKS5wdXNoKFxuICAgICAgdGhpc1xuICAgICk7XG4gICAgd2luZG93V2l0aERldlRvb2xzLl9fQVBPTExPX0NMSUVOVF9fID0gdGhpcztcblxuICAgIC8qKlxuICAgICAqIFN1Z2dlc3QgaW5zdGFsbGluZyB0aGUgZGV2dG9vbHMgZm9yIGRldmVsb3BlcnMgd2hvIGRvbid0IGhhdmUgdGhlbVxuICAgICAqL1xuICAgIGlmICghaGFzU3VnZ2VzdGVkRGV2dG9vbHMgJiYgX19ERVZfXykge1xuICAgICAgaGFzU3VnZ2VzdGVkRGV2dG9vbHMgPSB0cnVlO1xuICAgICAgaWYgKFxuICAgICAgICB3aW5kb3cuZG9jdW1lbnQgJiZcbiAgICAgICAgd2luZG93LnRvcCA9PT0gd2luZG93LnNlbGYgJiZcbiAgICAgICAgL14oaHR0cHM/fGZpbGUpOiQvLnRlc3Qod2luZG93LmxvY2F0aW9uLnByb3RvY29sKVxuICAgICAgKSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIGlmICghKHdpbmRvdyBhcyBhbnkpLl9fQVBPTExPX0RFVlRPT0xTX0dMT0JBTF9IT09LX18pIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdiA9IHdpbmRvdy5uYXZpZ2F0b3I7XG4gICAgICAgICAgICBjb25zdCB1YSA9IG5hdiAmJiBuYXYudXNlckFnZW50O1xuICAgICAgICAgICAgbGV0IHVybDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB1YSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICBpZiAodWEuaW5kZXhPZihcIkNocm9tZS9cIikgPiAtMSkge1xuICAgICAgICAgICAgICAgIHVybCA9XG4gICAgICAgICAgICAgICAgICBcImh0dHBzOi8vY2hyb21lLmdvb2dsZS5jb20vd2Vic3RvcmUvZGV0YWlsL1wiICtcbiAgICAgICAgICAgICAgICAgIFwiYXBvbGxvLWNsaWVudC1kZXZlbG9wZXItdC9qZGtrbmtrYmViYmFwaWxnb2VjY2NpZ2xrZmJtYm5mbVwiO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHVhLmluZGV4T2YoXCJGaXJlZm94L1wiKSA+IC0xKSB7XG4gICAgICAgICAgICAgICAgdXJsID1cbiAgICAgICAgICAgICAgICAgIFwiaHR0cHM6Ly9hZGRvbnMubW96aWxsYS5vcmcvZW4tVVMvZmlyZWZveC9hZGRvbi9hcG9sbG8tZGV2ZWxvcGVyLXRvb2xzL1wiO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodXJsKSB7XG4gICAgICAgICAgICAgIGludmFyaWFudC5sb2coXG4gICAgICAgICAgICAgICAgXCJEb3dubG9hZCB0aGUgQXBvbGxvIERldlRvb2xzIGZvciBhIGJldHRlciBkZXZlbG9wbWVudCBcIiArXG4gICAgICAgICAgICAgICAgICBcImV4cGVyaWVuY2U6ICVzXCIsXG4gICAgICAgICAgICAgICAgdXJsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCAxMDAwMCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBgRG9jdW1lbnRUcmFuc2Zvcm1gIHVzZWQgdG8gbW9kaWZ5IEdyYXBoUUwgZG9jdW1lbnRzIGJlZm9yZSBhIHJlcXVlc3RcbiAgICogaXMgbWFkZS4gSWYgYSBjdXN0b20gYERvY3VtZW50VHJhbnNmb3JtYCBpcyBub3QgcHJvdmlkZWQsIHRoaXMgd2lsbCBiZSB0aGVcbiAgICogZGVmYXVsdCBkb2N1bWVudCB0cmFuc2Zvcm0uXG4gICAqL1xuICBnZXQgZG9jdW1lbnRUcmFuc2Zvcm0oKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlNYW5hZ2VyLmRvY3VtZW50VHJhbnNmb3JtO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGwgdGhpcyBtZXRob2QgdG8gdGVybWluYXRlIGFueSBhY3RpdmUgY2xpZW50IHByb2Nlc3NlcywgbWFraW5nIGl0IHNhZmVcbiAgICogdG8gZGlzcG9zZSBvZiB0aGlzIGBBcG9sbG9DbGllbnRgIGluc3RhbmNlLlxuICAgKi9cbiAgcHVibGljIHN0b3AoKSB7XG4gICAgdGhpcy5xdWVyeU1hbmFnZXIuc3RvcCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgd2F0Y2hlcyB0aGUgY2FjaGUgc3RvcmUgb2YgdGhlIHF1ZXJ5IGFjY29yZGluZyB0byB0aGUgb3B0aW9ucyBzcGVjaWZpZWQgYW5kXG4gICAqIHJldHVybnMgYW4gYE9ic2VydmFibGVRdWVyeWAuIFdlIGNhbiBzdWJzY3JpYmUgdG8gdGhpcyBgT2JzZXJ2YWJsZVF1ZXJ5YCBhbmRcbiAgICogcmVjZWl2ZSB1cGRhdGVkIHJlc3VsdHMgdGhyb3VnaCBhbiBvYnNlcnZlciB3aGVuIHRoZSBjYWNoZSBzdG9yZSBjaGFuZ2VzLlxuICAgKlxuICAgKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgaXMgbm90IGFuIGltcGxlbWVudGF0aW9uIG9mIEdyYXBoUUwgc3Vic2NyaXB0aW9ucy4gUmF0aGVyLFxuICAgKiBpdCB1c2VzIEFwb2xsbydzIHN0b3JlIGluIG9yZGVyIHRvIHJlYWN0aXZlbHkgZGVsaXZlciB1cGRhdGVzIHRvIHlvdXIgcXVlcnkgcmVzdWx0cy5cbiAgICpcbiAgICogRm9yIGV4YW1wbGUsIHN1cHBvc2UgeW91IGNhbGwgd2F0Y2hRdWVyeSBvbiBhIEdyYXBoUUwgcXVlcnkgdGhhdCBmZXRjaGVzIGEgcGVyc29uJ3NcbiAgICogZmlyc3QgYW5kIGxhc3QgbmFtZSBhbmQgdGhpcyBwZXJzb24gaGFzIGEgcGFydGljdWxhciBvYmplY3QgaWRlbnRpZmllciwgcHJvdmlkZWQgYnlcbiAgICogZGF0YUlkRnJvbU9iamVjdC4gTGF0ZXIsIGEgZGlmZmVyZW50IHF1ZXJ5IGZldGNoZXMgdGhhdCBzYW1lIHBlcnNvbidzXG4gICAqIGZpcnN0IGFuZCBsYXN0IG5hbWUgYW5kIHRoZSBmaXJzdCBuYW1lIGhhcyBub3cgY2hhbmdlZC4gVGhlbiwgYW55IG9ic2VydmVycyBhc3NvY2lhdGVkXG4gICAqIHdpdGggdGhlIHJlc3VsdHMgb2YgdGhlIGZpcnN0IHF1ZXJ5IHdpbGwgYmUgdXBkYXRlZCB3aXRoIGEgbmV3IHJlc3VsdCBvYmplY3QuXG4gICAqXG4gICAqIE5vdGUgdGhhdCBpZiB0aGUgY2FjaGUgZG9lcyBub3QgY2hhbmdlLCB0aGUgc3Vic2NyaWJlciB3aWxsICpub3QqIGJlIG5vdGlmaWVkLlxuICAgKlxuICAgKiBTZWUgW2hlcmVdKGh0dHBzOi8vbWVkaXVtLmNvbS9hcG9sbG8tc3RhY2svdGhlLWNvbmNlcHRzLW9mLWdyYXBocWwtYmM2OGJkODE5YmUzIy4zbWIwY2JjbWMpIGZvclxuICAgKiBhIGRlc2NyaXB0aW9uIG9mIHN0b3JlIHJlYWN0aXZpdHkuXG4gICAqL1xuICBwdWJsaWMgd2F0Y2hRdWVyeTxcbiAgICBUID0gYW55LFxuICAgIFRWYXJpYWJsZXMgZXh0ZW5kcyBPcGVyYXRpb25WYXJpYWJsZXMgPSBPcGVyYXRpb25WYXJpYWJsZXMsXG4gID4ob3B0aW9uczogV2F0Y2hRdWVyeU9wdGlvbnM8VFZhcmlhYmxlcywgVD4pOiBPYnNlcnZhYmxlUXVlcnk8VCwgVFZhcmlhYmxlcz4ge1xuICAgIGlmICh0aGlzLmRlZmF1bHRPcHRpb25zLndhdGNoUXVlcnkpIHtcbiAgICAgIG9wdGlvbnMgPSBtZXJnZU9wdGlvbnModGhpcy5kZWZhdWx0T3B0aW9ucy53YXRjaFF1ZXJ5LCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICAvLyBYWFggT3ZlcndyaXRpbmcgb3B0aW9ucyBpcyBwcm9iYWJseSBub3QgdGhlIGJlc3Qgd2F5IHRvIGRvIHRoaXMgbG9uZyB0ZXJtLi4uXG4gICAgaWYgKFxuICAgICAgdGhpcy5kaXNhYmxlTmV0d29ya0ZldGNoZXMgJiZcbiAgICAgIChvcHRpb25zLmZldGNoUG9saWN5ID09PSBcIm5ldHdvcmstb25seVwiIHx8XG4gICAgICAgIG9wdGlvbnMuZmV0Y2hQb2xpY3kgPT09IFwiY2FjaGUtYW5kLW5ldHdvcmtcIilcbiAgICApIHtcbiAgICAgIG9wdGlvbnMgPSB7IC4uLm9wdGlvbnMsIGZldGNoUG9saWN5OiBcImNhY2hlLWZpcnN0XCIgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5xdWVyeU1hbmFnZXIud2F0Y2hRdWVyeTxULCBUVmFyaWFibGVzPihvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIHJlc29sdmVzIGEgc2luZ2xlIHF1ZXJ5IGFjY29yZGluZyB0byB0aGUgb3B0aW9ucyBzcGVjaWZpZWQgYW5kXG4gICAqIHJldHVybnMgYSBgUHJvbWlzZWAgd2hpY2ggaXMgZWl0aGVyIHJlc29sdmVkIHdpdGggdGhlIHJlc3VsdGluZyBkYXRhXG4gICAqIG9yIHJlamVjdGVkIHdpdGggYW4gZXJyb3IuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb2JqZWN0IG9mIHR5cGUgYFF1ZXJ5T3B0aW9uc2AgdGhhdCBhbGxvd3MgdXMgdG9cbiAgICogZGVzY3JpYmUgaG93IHRoaXMgcXVlcnkgc2hvdWxkIGJlIHRyZWF0ZWQgZS5nLiB3aGV0aGVyIGl0IHNob3VsZCBoaXQgdGhlXG4gICAqIHNlcnZlciBhdCBhbGwgb3IganVzdCByZXNvbHZlIGZyb20gdGhlIGNhY2hlLCBldGMuXG4gICAqL1xuICBwdWJsaWMgcXVlcnk8XG4gICAgVCA9IGFueSxcbiAgICBUVmFyaWFibGVzIGV4dGVuZHMgT3BlcmF0aW9uVmFyaWFibGVzID0gT3BlcmF0aW9uVmFyaWFibGVzLFxuICA+KFxuICAgIG9wdGlvbnM6IFF1ZXJ5T3B0aW9uczxUVmFyaWFibGVzLCBUPlxuICApOiBQcm9taXNlPEFwb2xsb1F1ZXJ5UmVzdWx0PE1heWJlTWFza2VkPFQ+Pj4ge1xuICAgIGlmICh0aGlzLmRlZmF1bHRPcHRpb25zLnF1ZXJ5KSB7XG4gICAgICBvcHRpb25zID0gbWVyZ2VPcHRpb25zKHRoaXMuZGVmYXVsdE9wdGlvbnMucXVlcnksIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGludmFyaWFudChcbiAgICAgIChvcHRpb25zLmZldGNoUG9saWN5IGFzIFdhdGNoUXVlcnlGZXRjaFBvbGljeSkgIT09IFwiY2FjaGUtYW5kLW5ldHdvcmtcIixcbiAgICAgIFwiVGhlIGNhY2hlLWFuZC1uZXR3b3JrIGZldGNoUG9saWN5IGRvZXMgbm90IHdvcmsgd2l0aCBjbGllbnQucXVlcnksIGJlY2F1c2UgXCIgK1xuICAgICAgICBcImNsaWVudC5xdWVyeSBjYW4gb25seSByZXR1cm4gYSBzaW5nbGUgcmVzdWx0LiBQbGVhc2UgdXNlIGNsaWVudC53YXRjaFF1ZXJ5IFwiICtcbiAgICAgICAgXCJ0byByZWNlaXZlIG11bHRpcGxlIHJlc3VsdHMgZnJvbSB0aGUgY2FjaGUgYW5kIHRoZSBuZXR3b3JrLCBvciBjb25zaWRlciBcIiArXG4gICAgICAgIFwidXNpbmcgYSBkaWZmZXJlbnQgZmV0Y2hQb2xpY3ksIHN1Y2ggYXMgY2FjaGUtZmlyc3Qgb3IgbmV0d29yay1vbmx5LlwiXG4gICAgKTtcblxuICAgIGlmICh0aGlzLmRpc2FibGVOZXR3b3JrRmV0Y2hlcyAmJiBvcHRpb25zLmZldGNoUG9saWN5ID09PSBcIm5ldHdvcmstb25seVwiKSB7XG4gICAgICBvcHRpb25zID0geyAuLi5vcHRpb25zLCBmZXRjaFBvbGljeTogXCJjYWNoZS1maXJzdFwiIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucXVlcnlNYW5hZ2VyLnF1ZXJ5PFQsIFRWYXJpYWJsZXM+KG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgcmVzb2x2ZXMgYSBzaW5nbGUgbXV0YXRpb24gYWNjb3JkaW5nIHRvIHRoZSBvcHRpb25zIHNwZWNpZmllZCBhbmQgcmV0dXJucyBhXG4gICAqIFByb21pc2Ugd2hpY2ggaXMgZWl0aGVyIHJlc29sdmVkIHdpdGggdGhlIHJlc3VsdGluZyBkYXRhIG9yIHJlamVjdGVkIHdpdGggYW5cbiAgICogZXJyb3IuIEluIHNvbWUgY2FzZXMgYm90aCBgZGF0YWAgYW5kIGBlcnJvcnNgIG1pZ2h0IGJlIHVuZGVmaW5lZCwgZm9yIGV4YW1wbGVcbiAgICogd2hlbiBgZXJyb3JQb2xpY3lgIGlzIHNldCB0byBgJ2lnbm9yZSdgLlxuICAgKlxuICAgKiBJdCB0YWtlcyBvcHRpb25zIGFzIGFuIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcga2V5cyBhbmQgdmFsdWVzOlxuICAgKi9cbiAgcHVibGljIG11dGF0ZTxcbiAgICBURGF0YSA9IGFueSxcbiAgICBUVmFyaWFibGVzIGV4dGVuZHMgT3BlcmF0aW9uVmFyaWFibGVzID0gT3BlcmF0aW9uVmFyaWFibGVzLFxuICAgIFRDb250ZXh0IGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PiA9IERlZmF1bHRDb250ZXh0LFxuICAgIFRDYWNoZSBleHRlbmRzIEFwb2xsb0NhY2hlPGFueT4gPSBBcG9sbG9DYWNoZTxhbnk+LFxuICA+KFxuICAgIG9wdGlvbnM6IE11dGF0aW9uT3B0aW9uczxURGF0YSwgVFZhcmlhYmxlcywgVENvbnRleHQ+XG4gICk6IFByb21pc2U8RmV0Y2hSZXN1bHQ8TWF5YmVNYXNrZWQ8VERhdGE+Pj4ge1xuICAgIGlmICh0aGlzLmRlZmF1bHRPcHRpb25zLm11dGF0ZSkge1xuICAgICAgb3B0aW9ucyA9IG1lcmdlT3B0aW9ucyh0aGlzLmRlZmF1bHRPcHRpb25zLm11dGF0ZSwgb3B0aW9ucyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnF1ZXJ5TWFuYWdlci5tdXRhdGU8VERhdGEsIFRWYXJpYWJsZXMsIFRDb250ZXh0LCBUQ2FjaGU+KFxuICAgICAgb3B0aW9uc1xuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBzdWJzY3JpYmVzIHRvIGEgZ3JhcGhxbCBzdWJzY3JpcHRpb24gYWNjb3JkaW5nIHRvIHRoZSBvcHRpb25zIHNwZWNpZmllZCBhbmQgcmV0dXJucyBhblxuICAgKiBgT2JzZXJ2YWJsZWAgd2hpY2ggZWl0aGVyIGVtaXRzIHJlY2VpdmVkIGRhdGEgb3IgYW4gZXJyb3IuXG4gICAqL1xuICBwdWJsaWMgc3Vic2NyaWJlPFxuICAgIFQgPSBhbnksXG4gICAgVFZhcmlhYmxlcyBleHRlbmRzIE9wZXJhdGlvblZhcmlhYmxlcyA9IE9wZXJhdGlvblZhcmlhYmxlcyxcbiAgPihcbiAgICBvcHRpb25zOiBTdWJzY3JpcHRpb25PcHRpb25zPFRWYXJpYWJsZXMsIFQ+XG4gICk6IE9ic2VydmFibGU8RmV0Y2hSZXN1bHQ8TWF5YmVNYXNrZWQ8VD4+PiB7XG4gICAgY29uc3QgaWQgPSB0aGlzLnF1ZXJ5TWFuYWdlci5nZW5lcmF0ZVF1ZXJ5SWQoKTtcblxuICAgIHJldHVybiB0aGlzLnF1ZXJ5TWFuYWdlclxuICAgICAgLnN0YXJ0R3JhcGhRTFN1YnNjcmlwdGlvbjxUPihvcHRpb25zKVxuICAgICAgLm1hcCgocmVzdWx0KSA9PiAoe1xuICAgICAgICAuLi5yZXN1bHQsXG4gICAgICAgIGRhdGE6IHRoaXMucXVlcnlNYW5hZ2VyLm1hc2tPcGVyYXRpb24oe1xuICAgICAgICAgIGRvY3VtZW50OiBvcHRpb25zLnF1ZXJ5LFxuICAgICAgICAgIGRhdGE6IHJlc3VsdC5kYXRhLFxuICAgICAgICAgIGZldGNoUG9saWN5OiBvcHRpb25zLmZldGNoUG9saWN5LFxuICAgICAgICAgIGlkLFxuICAgICAgICB9KSxcbiAgICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmllcyB0byByZWFkIHNvbWUgZGF0YSBmcm9tIHRoZSBzdG9yZSBpbiB0aGUgc2hhcGUgb2YgdGhlIHByb3ZpZGVkXG4gICAqIEdyYXBoUUwgcXVlcnkgd2l0aG91dCBtYWtpbmcgYSBuZXR3b3JrIHJlcXVlc3QuIFRoaXMgbWV0aG9kIHdpbGwgc3RhcnQgYXRcbiAgICogdGhlIHJvb3QgcXVlcnkuIFRvIHN0YXJ0IGF0IGEgc3BlY2lmaWMgaWQgcmV0dXJuZWQgYnkgYGRhdGFJZEZyb21PYmplY3RgXG4gICAqIHVzZSBgcmVhZEZyYWdtZW50YC5cbiAgICpcbiAgICogQHBhcmFtIG9wdGltaXN0aWMgLSBTZXQgdG8gYHRydWVgIHRvIGFsbG93IGByZWFkUXVlcnlgIHRvIHJldHVyblxuICAgKiBvcHRpbWlzdGljIHJlc3VsdHMuIElzIGBmYWxzZWAgYnkgZGVmYXVsdC5cbiAgICovXG4gIHB1YmxpYyByZWFkUXVlcnk8VCA9IGFueSwgVFZhcmlhYmxlcyA9IE9wZXJhdGlvblZhcmlhYmxlcz4oXG4gICAgb3B0aW9uczogRGF0YVByb3h5LlF1ZXJ5PFRWYXJpYWJsZXMsIFQ+LFxuICAgIG9wdGltaXN0aWM6IGJvb2xlYW4gPSBmYWxzZVxuICApOiBVbm1hc2tlZDxUPiB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmNhY2hlLnJlYWRRdWVyeTxULCBUVmFyaWFibGVzPihvcHRpb25zLCBvcHRpbWlzdGljKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXYXRjaGVzIHRoZSBjYWNoZSBzdG9yZSBvZiB0aGUgZnJhZ21lbnQgYWNjb3JkaW5nIHRvIHRoZSBvcHRpb25zIHNwZWNpZmllZFxuICAgKiBhbmQgcmV0dXJucyBhbiBgT2JzZXJ2YWJsZWAuIFdlIGNhbiBzdWJzY3JpYmUgdG8gdGhpc1xuICAgKiBgT2JzZXJ2YWJsZWAgYW5kIHJlY2VpdmUgdXBkYXRlZCByZXN1bHRzIHRocm91Z2ggYW5cbiAgICogb2JzZXJ2ZXIgd2hlbiB0aGUgY2FjaGUgc3RvcmUgY2hhbmdlcy5cbiAgICpcbiAgICogWW91IG11c3QgcGFzcyBpbiBhIEdyYXBoUUwgZG9jdW1lbnQgd2l0aCBhIHNpbmdsZSBmcmFnbWVudCBvciBhIGRvY3VtZW50XG4gICAqIHdpdGggbXVsdGlwbGUgZnJhZ21lbnRzIHRoYXQgcmVwcmVzZW50IHdoYXQgeW91IGFyZSByZWFkaW5nLiBJZiB5b3UgcGFzc1xuICAgKiBpbiBhIGRvY3VtZW50IHdpdGggbXVsdGlwbGUgZnJhZ21lbnRzIHRoZW4geW91IG11c3QgYWxzbyBzcGVjaWZ5IGFcbiAgICogYGZyYWdtZW50TmFtZWAuXG4gICAqXG4gICAqIEBzaW5jZSAzLjEwLjBcbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvYmplY3Qgb2YgdHlwZSBgV2F0Y2hGcmFnbWVudE9wdGlvbnNgIHRoYXQgYWxsb3dzXG4gICAqIHRoZSBjYWNoZSB0byBpZGVudGlmeSB0aGUgZnJhZ21lbnQgYW5kIG9wdGlvbmFsbHkgc3BlY2lmeSB3aGV0aGVyIHRvIHJlYWN0XG4gICAqIHRvIG9wdGltaXN0aWMgdXBkYXRlcy5cbiAgICovXG5cbiAgcHVibGljIHdhdGNoRnJhZ21lbnQ8XG4gICAgVEZyYWdtZW50RGF0YSA9IHVua25vd24sXG4gICAgVFZhcmlhYmxlcyA9IE9wZXJhdGlvblZhcmlhYmxlcyxcbiAgPihcbiAgICBvcHRpb25zOiBXYXRjaEZyYWdtZW50T3B0aW9uczxURnJhZ21lbnREYXRhLCBUVmFyaWFibGVzPlxuICApOiBPYnNlcnZhYmxlPFdhdGNoRnJhZ21lbnRSZXN1bHQ8VEZyYWdtZW50RGF0YT4+IHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS53YXRjaEZyYWdtZW50KHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBbU3ltYm9sLmZvcihcImFwb2xsby5kYXRhTWFza2luZ1wiKV06IHRoaXMucXVlcnlNYW5hZ2VyLmRhdGFNYXNraW5nLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyaWVzIHRvIHJlYWQgc29tZSBkYXRhIGZyb20gdGhlIHN0b3JlIGluIHRoZSBzaGFwZSBvZiB0aGUgcHJvdmlkZWRcbiAgICogR3JhcGhRTCBmcmFnbWVudCB3aXRob3V0IG1ha2luZyBhIG5ldHdvcmsgcmVxdWVzdC4gVGhpcyBtZXRob2Qgd2lsbCByZWFkIGFcbiAgICogR3JhcGhRTCBmcmFnbWVudCBmcm9tIGFueSBhcmJpdHJhcnkgaWQgdGhhdCBpcyBjdXJyZW50bHkgY2FjaGVkLCB1bmxpa2VcbiAgICogYHJlYWRRdWVyeWAgd2hpY2ggd2lsbCBvbmx5IHJlYWQgZnJvbSB0aGUgcm9vdCBxdWVyeS5cbiAgICpcbiAgICogWW91IG11c3QgcGFzcyBpbiBhIEdyYXBoUUwgZG9jdW1lbnQgd2l0aCBhIHNpbmdsZSBmcmFnbWVudCBvciBhIGRvY3VtZW50XG4gICAqIHdpdGggbXVsdGlwbGUgZnJhZ21lbnRzIHRoYXQgcmVwcmVzZW50IHdoYXQgeW91IGFyZSByZWFkaW5nLiBJZiB5b3UgcGFzc1xuICAgKiBpbiBhIGRvY3VtZW50IHdpdGggbXVsdGlwbGUgZnJhZ21lbnRzIHRoZW4geW91IG11c3QgYWxzbyBzcGVjaWZ5IGFcbiAgICogYGZyYWdtZW50TmFtZWAuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpbWlzdGljIC0gU2V0IHRvIGB0cnVlYCB0byBhbGxvdyBgcmVhZEZyYWdtZW50YCB0byByZXR1cm5cbiAgICogb3B0aW1pc3RpYyByZXN1bHRzLiBJcyBgZmFsc2VgIGJ5IGRlZmF1bHQuXG4gICAqL1xuICBwdWJsaWMgcmVhZEZyYWdtZW50PFQgPSBhbnksIFRWYXJpYWJsZXMgPSBPcGVyYXRpb25WYXJpYWJsZXM+KFxuICAgIG9wdGlvbnM6IERhdGFQcm94eS5GcmFnbWVudDxUVmFyaWFibGVzLCBUPixcbiAgICBvcHRpbWlzdGljOiBib29sZWFuID0gZmFsc2VcbiAgKTogVW5tYXNrZWQ8VD4gfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS5yZWFkRnJhZ21lbnQ8VCwgVFZhcmlhYmxlcz4ob3B0aW9ucywgb3B0aW1pc3RpYyk7XG4gIH1cblxuICAvKipcbiAgICogV3JpdGVzIHNvbWUgZGF0YSBpbiB0aGUgc2hhcGUgb2YgdGhlIHByb3ZpZGVkIEdyYXBoUUwgcXVlcnkgZGlyZWN0bHkgdG9cbiAgICogdGhlIHN0b3JlLiBUaGlzIG1ldGhvZCB3aWxsIHN0YXJ0IGF0IHRoZSByb290IHF1ZXJ5LiBUbyBzdGFydCBhdCBhXG4gICAqIHNwZWNpZmljIGlkIHJldHVybmVkIGJ5IGBkYXRhSWRGcm9tT2JqZWN0YCB0aGVuIHVzZSBgd3JpdGVGcmFnbWVudGAuXG4gICAqL1xuICBwdWJsaWMgd3JpdGVRdWVyeTxURGF0YSA9IGFueSwgVFZhcmlhYmxlcyA9IE9wZXJhdGlvblZhcmlhYmxlcz4oXG4gICAgb3B0aW9uczogRGF0YVByb3h5LldyaXRlUXVlcnlPcHRpb25zPFREYXRhLCBUVmFyaWFibGVzPlxuICApOiBSZWZlcmVuY2UgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHJlZiA9IHRoaXMuY2FjaGUud3JpdGVRdWVyeTxURGF0YSwgVFZhcmlhYmxlcz4ob3B0aW9ucyk7XG5cbiAgICBpZiAob3B0aW9ucy5icm9hZGNhc3QgIT09IGZhbHNlKSB7XG4gICAgICB0aGlzLnF1ZXJ5TWFuYWdlci5icm9hZGNhc3RRdWVyaWVzKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZXMgc29tZSBkYXRhIGluIHRoZSBzaGFwZSBvZiB0aGUgcHJvdmlkZWQgR3JhcGhRTCBmcmFnbWVudCBkaXJlY3RseSB0b1xuICAgKiB0aGUgc3RvcmUuIFRoaXMgbWV0aG9kIHdpbGwgd3JpdGUgdG8gYSBHcmFwaFFMIGZyYWdtZW50IGZyb20gYW55IGFyYml0cmFyeVxuICAgKiBpZCB0aGF0IGlzIGN1cnJlbnRseSBjYWNoZWQsIHVubGlrZSBgd3JpdGVRdWVyeWAgd2hpY2ggd2lsbCBvbmx5IHdyaXRlXG4gICAqIGZyb20gdGhlIHJvb3QgcXVlcnkuXG4gICAqXG4gICAqIFlvdSBtdXN0IHBhc3MgaW4gYSBHcmFwaFFMIGRvY3VtZW50IHdpdGggYSBzaW5nbGUgZnJhZ21lbnQgb3IgYSBkb2N1bWVudFxuICAgKiB3aXRoIG11bHRpcGxlIGZyYWdtZW50cyB0aGF0IHJlcHJlc2VudCB3aGF0IHlvdSBhcmUgd3JpdGluZy4gSWYgeW91IHBhc3NcbiAgICogaW4gYSBkb2N1bWVudCB3aXRoIG11bHRpcGxlIGZyYWdtZW50cyB0aGVuIHlvdSBtdXN0IGFsc28gc3BlY2lmeSBhXG4gICAqIGBmcmFnbWVudE5hbWVgLlxuICAgKi9cbiAgcHVibGljIHdyaXRlRnJhZ21lbnQ8VERhdGEgPSBhbnksIFRWYXJpYWJsZXMgPSBPcGVyYXRpb25WYXJpYWJsZXM+KFxuICAgIG9wdGlvbnM6IERhdGFQcm94eS5Xcml0ZUZyYWdtZW50T3B0aW9uczxURGF0YSwgVFZhcmlhYmxlcz5cbiAgKTogUmVmZXJlbmNlIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCByZWYgPSB0aGlzLmNhY2hlLndyaXRlRnJhZ21lbnQ8VERhdGEsIFRWYXJpYWJsZXM+KG9wdGlvbnMpO1xuXG4gICAgaWYgKG9wdGlvbnMuYnJvYWRjYXN0ICE9PSBmYWxzZSkge1xuICAgICAgdGhpcy5xdWVyeU1hbmFnZXIuYnJvYWRjYXN0UXVlcmllcygpO1xuICAgIH1cblxuICAgIHJldHVybiByZWY7XG4gIH1cblxuICBwdWJsaWMgX19hY3Rpb25Ib29rRm9yRGV2VG9vbHMoY2I6ICgpID0+IGFueSkge1xuICAgIHRoaXMuZGV2VG9vbHNIb29rQ2IgPSBjYjtcbiAgfVxuXG4gIHB1YmxpYyBfX3JlcXVlc3RSYXcoXG4gICAgcGF5bG9hZDogR3JhcGhRTFJlcXVlc3RcbiAgKTogT2JzZXJ2YWJsZTxGb3JtYXR0ZWRFeGVjdXRpb25SZXN1bHQ+IHtcbiAgICByZXR1cm4gZXhlY3V0ZSh0aGlzLmxpbmssIHBheWxvYWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0cyB5b3VyIGVudGlyZSBzdG9yZSBieSBjbGVhcmluZyBvdXQgeW91ciBjYWNoZSBhbmQgdGhlbiByZS1leGVjdXRpbmdcbiAgICogYWxsIG9mIHlvdXIgYWN0aXZlIHF1ZXJpZXMuIFRoaXMgbWFrZXMgaXQgc28gdGhhdCB5b3UgbWF5IGd1YXJhbnRlZSB0aGF0XG4gICAqIHRoZXJlIGlzIG5vIGRhdGEgbGVmdCBpbiB5b3VyIHN0b3JlIGZyb20gYSB0aW1lIGJlZm9yZSB5b3UgY2FsbGVkIHRoaXNcbiAgICogbWV0aG9kLlxuICAgKlxuICAgKiBgcmVzZXRTdG9yZSgpYCBpcyB1c2VmdWwgd2hlbiB5b3VyIHVzZXIganVzdCBsb2dnZWQgb3V0LiBZb3XigJl2ZSByZW1vdmVkIHRoZVxuICAgKiB1c2VyIHNlc3Npb24sIGFuZCB5b3Ugbm93IHdhbnQgdG8gbWFrZSBzdXJlIHRoYXQgYW55IHJlZmVyZW5jZXMgdG8gZGF0YSB5b3VcbiAgICogbWlnaHQgaGF2ZSBmZXRjaGVkIHdoaWxlIHRoZSB1c2VyIHNlc3Npb24gd2FzIGFjdGl2ZSBpcyBnb25lLlxuICAgKlxuICAgKiBJdCBpcyBpbXBvcnRhbnQgdG8gcmVtZW1iZXIgdGhhdCBgcmVzZXRTdG9yZSgpYCAqd2lsbCogcmVmZXRjaCBhbnkgYWN0aXZlXG4gICAqIHF1ZXJpZXMuIFRoaXMgbWVhbnMgdGhhdCBhbnkgY29tcG9uZW50cyB0aGF0IG1pZ2h0IGJlIG1vdW50ZWQgd2lsbCBleGVjdXRlXG4gICAqIHRoZWlyIHF1ZXJpZXMgYWdhaW4gdXNpbmcgeW91ciBuZXR3b3JrIGludGVyZmFjZS4gSWYgeW91IGRvIG5vdCB3YW50IHRvXG4gICAqIHJlLWV4ZWN1dGUgYW55IHF1ZXJpZXMgdGhlbiB5b3Ugc2hvdWxkIG1ha2Ugc3VyZSB0byBzdG9wIHdhdGNoaW5nIGFueVxuICAgKiBhY3RpdmUgcXVlcmllcy5cbiAgICovXG4gIHB1YmxpYyByZXNldFN0b3JlKCk6IFByb21pc2U8QXBvbGxvUXVlcnlSZXN1bHQ8YW55PltdIHwgbnVsbD4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oKCkgPT5cbiAgICAgICAgdGhpcy5xdWVyeU1hbmFnZXIuY2xlYXJTdG9yZSh7XG4gICAgICAgICAgZGlzY2FyZFdhdGNoZXM6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLnRoZW4oKCkgPT4gUHJvbWlzZS5hbGwodGhpcy5yZXNldFN0b3JlQ2FsbGJhY2tzLm1hcCgoZm4pID0+IGZuKCkpKSlcbiAgICAgIC50aGVuKCgpID0+IHRoaXMucmVGZXRjaE9ic2VydmFibGVRdWVyaWVzKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhbGwgZGF0YSBmcm9tIHRoZSBzdG9yZS4gVW5saWtlIGByZXNldFN0b3JlYCwgYGNsZWFyU3RvcmVgIHdpbGxcbiAgICogbm90IHJlZmV0Y2ggYW55IGFjdGl2ZSBxdWVyaWVzLlxuICAgKi9cbiAgcHVibGljIGNsZWFyU3RvcmUoKTogUHJvbWlzZTxhbnlbXT4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oKCkgPT5cbiAgICAgICAgdGhpcy5xdWVyeU1hbmFnZXIuY2xlYXJTdG9yZSh7XG4gICAgICAgICAgZGlzY2FyZFdhdGNoZXM6IHRydWUsXG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAudGhlbigoKSA9PiBQcm9taXNlLmFsbCh0aGlzLmNsZWFyU3RvcmVDYWxsYmFja3MubWFwKChmbikgPT4gZm4oKSkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbGxvd3MgY2FsbGJhY2tzIHRvIGJlIHJlZ2lzdGVyZWQgdGhhdCBhcmUgZXhlY3V0ZWQgd2hlbiB0aGUgc3RvcmUgaXNcbiAgICogcmVzZXQuIGBvblJlc2V0U3RvcmVgIHJldHVybnMgYW4gdW5zdWJzY3JpYmUgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZFxuICAgKiB0byByZW1vdmUgcmVnaXN0ZXJlZCBjYWxsYmFja3MuXG4gICAqL1xuICBwdWJsaWMgb25SZXNldFN0b3JlKGNiOiAoKSA9PiBQcm9taXNlPGFueT4pOiAoKSA9PiB2b2lkIHtcbiAgICB0aGlzLnJlc2V0U3RvcmVDYWxsYmFja3MucHVzaChjYik7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHRoaXMucmVzZXRTdG9yZUNhbGxiYWNrcyA9IHRoaXMucmVzZXRTdG9yZUNhbGxiYWNrcy5maWx0ZXIoXG4gICAgICAgIChjKSA9PiBjICE9PSBjYlxuICAgICAgKTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFsbG93cyBjYWxsYmFja3MgdG8gYmUgcmVnaXN0ZXJlZCB0aGF0IGFyZSBleGVjdXRlZCB3aGVuIHRoZSBzdG9yZSBpc1xuICAgKiBjbGVhcmVkLiBgb25DbGVhclN0b3JlYCByZXR1cm5zIGFuIHVuc3Vic2NyaWJlIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWRcbiAgICogdG8gcmVtb3ZlIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICAgKi9cbiAgcHVibGljIG9uQ2xlYXJTdG9yZShjYjogKCkgPT4gUHJvbWlzZTxhbnk+KTogKCkgPT4gdm9pZCB7XG4gICAgdGhpcy5jbGVhclN0b3JlQ2FsbGJhY2tzLnB1c2goY2IpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICB0aGlzLmNsZWFyU3RvcmVDYWxsYmFja3MgPSB0aGlzLmNsZWFyU3RvcmVDYWxsYmFja3MuZmlsdGVyKFxuICAgICAgICAoYykgPT4gYyAhPT0gY2JcbiAgICAgICk7XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWZldGNoZXMgYWxsIG9mIHlvdXIgYWN0aXZlIHF1ZXJpZXMuXG4gICAqXG4gICAqIGByZUZldGNoT2JzZXJ2YWJsZVF1ZXJpZXMoKWAgaXMgdXNlZnVsIGlmIHlvdSB3YW50IHRvIGJyaW5nIHRoZSBjbGllbnQgYmFjayB0byBwcm9wZXIgc3RhdGUgaW4gY2FzZSBvZiBhIG5ldHdvcmsgb3V0YWdlXG4gICAqXG4gICAqIEl0IGlzIGltcG9ydGFudCB0byByZW1lbWJlciB0aGF0IGByZUZldGNoT2JzZXJ2YWJsZVF1ZXJpZXMoKWAgKndpbGwqIHJlZmV0Y2ggYW55IGFjdGl2ZVxuICAgKiBxdWVyaWVzLiBUaGlzIG1lYW5zIHRoYXQgYW55IGNvbXBvbmVudHMgdGhhdCBtaWdodCBiZSBtb3VudGVkIHdpbGwgZXhlY3V0ZVxuICAgKiB0aGVpciBxdWVyaWVzIGFnYWluIHVzaW5nIHlvdXIgbmV0d29yayBpbnRlcmZhY2UuIElmIHlvdSBkbyBub3Qgd2FudCB0b1xuICAgKiByZS1leGVjdXRlIGFueSBxdWVyaWVzIHRoZW4geW91IHNob3VsZCBtYWtlIHN1cmUgdG8gc3RvcCB3YXRjaGluZyBhbnlcbiAgICogYWN0aXZlIHF1ZXJpZXMuXG4gICAqIFRha2VzIG9wdGlvbmFsIHBhcmFtZXRlciBgaW5jbHVkZVN0YW5kYnlgIHdoaWNoIHdpbGwgaW5jbHVkZSBxdWVyaWVzIGluIHN0YW5kYnktbW9kZSB3aGVuIHJlZmV0Y2hpbmcuXG4gICAqL1xuICBwdWJsaWMgcmVGZXRjaE9ic2VydmFibGVRdWVyaWVzKFxuICAgIGluY2x1ZGVTdGFuZGJ5PzogYm9vbGVhblxuICApOiBQcm9taXNlPEFwb2xsb1F1ZXJ5UmVzdWx0PGFueT5bXT4ge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5TWFuYWdlci5yZUZldGNoT2JzZXJ2YWJsZVF1ZXJpZXMoaW5jbHVkZVN0YW5kYnkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZmV0Y2hlcyBzcGVjaWZpZWQgYWN0aXZlIHF1ZXJpZXMuIFNpbWlsYXIgdG8gXCJyZUZldGNoT2JzZXJ2YWJsZVF1ZXJpZXMoKVwiIGJ1dCB3aXRoIGEgc3BlY2lmaWMgbGlzdCBvZiBxdWVyaWVzLlxuICAgKlxuICAgKiBgcmVmZXRjaFF1ZXJpZXMoKWAgaXMgdXNlZnVsIGZvciB1c2UgY2FzZXMgdG8gaW1wZXJhdGl2ZWx5IHJlZnJlc2ggYSBzZWxlY3Rpb24gb2YgcXVlcmllcy5cbiAgICpcbiAgICogSXQgaXMgaW1wb3J0YW50IHRvIHJlbWVtYmVyIHRoYXQgYHJlZmV0Y2hRdWVyaWVzKClgICp3aWxsKiByZWZldGNoIHNwZWNpZmllZCBhY3RpdmVcbiAgICogcXVlcmllcy4gVGhpcyBtZWFucyB0aGF0IGFueSBjb21wb25lbnRzIHRoYXQgbWlnaHQgYmUgbW91bnRlZCB3aWxsIGV4ZWN1dGVcbiAgICogdGhlaXIgcXVlcmllcyBhZ2FpbiB1c2luZyB5b3VyIG5ldHdvcmsgaW50ZXJmYWNlLiBJZiB5b3UgZG8gbm90IHdhbnQgdG9cbiAgICogcmUtZXhlY3V0ZSBhbnkgcXVlcmllcyB0aGVuIHlvdSBzaG91bGQgbWFrZSBzdXJlIHRvIHN0b3Agd2F0Y2hpbmcgYW55XG4gICAqIGFjdGl2ZSBxdWVyaWVzLlxuICAgKi9cbiAgcHVibGljIHJlZmV0Y2hRdWVyaWVzPFxuICAgIFRDYWNoZSBleHRlbmRzIEFwb2xsb0NhY2hlPGFueT4gPSBBcG9sbG9DYWNoZTxUQ2FjaGVTaGFwZT4sXG4gICAgVFJlc3VsdCA9IFByb21pc2U8QXBvbGxvUXVlcnlSZXN1bHQ8YW55Pj4sXG4gID4oXG4gICAgb3B0aW9uczogUmVmZXRjaFF1ZXJpZXNPcHRpb25zPFRDYWNoZSwgVFJlc3VsdD5cbiAgKTogUmVmZXRjaFF1ZXJpZXNSZXN1bHQ8VFJlc3VsdD4ge1xuICAgIGNvbnN0IG1hcCA9IHRoaXMucXVlcnlNYW5hZ2VyLnJlZmV0Y2hRdWVyaWVzKFxuICAgICAgb3B0aW9ucyBhcyBSZWZldGNoUXVlcmllc09wdGlvbnM8QXBvbGxvQ2FjaGU8VENhY2hlU2hhcGU+LCBUUmVzdWx0PlxuICAgICk7XG4gICAgY29uc3QgcXVlcmllczogT2JzZXJ2YWJsZVF1ZXJ5PGFueT5bXSA9IFtdO1xuICAgIGNvbnN0IHJlc3VsdHM6IEludGVybmFsUmVmZXRjaFF1ZXJpZXNSZXN1bHQ8VFJlc3VsdD5bXSA9IFtdO1xuXG4gICAgbWFwLmZvckVhY2goKHJlc3VsdCwgb2JzUXVlcnkpID0+IHtcbiAgICAgIHF1ZXJpZXMucHVzaChvYnNRdWVyeSk7XG4gICAgICByZXN1bHRzLnB1c2gocmVzdWx0KTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IFByb21pc2UuYWxsPFRSZXN1bHQ+KFxuICAgICAgcmVzdWx0cyBhcyBUUmVzdWx0W11cbiAgICApIGFzIFJlZmV0Y2hRdWVyaWVzUmVzdWx0PFRSZXN1bHQ+O1xuXG4gICAgLy8gSW4gY2FzZSB5b3UgbmVlZCB0aGUgcmF3IHJlc3VsdHMgaW1tZWRpYXRlbHksIHdpdGhvdXQgYXdhaXRpbmdcbiAgICAvLyBQcm9taXNlLmFsbChyZXN1bHRzKTpcbiAgICByZXN1bHQucXVlcmllcyA9IHF1ZXJpZXM7XG4gICAgcmVzdWx0LnJlc3VsdHMgPSByZXN1bHRzO1xuXG4gICAgLy8gSWYgeW91IGRlY2lkZSB0byBpZ25vcmUgdGhlIHJlc3VsdCBQcm9taXNlIGJlY2F1c2UgeW91J3JlIHVzaW5nXG4gICAgLy8gcmVzdWx0LnF1ZXJpZXMgYW5kIHJlc3VsdC5yZXN1bHRzIGluc3RlYWQsIHlvdSBzaG91bGRuJ3QgaGF2ZSB0byB3b3JyeVxuICAgIC8vIGFib3V0IHByZXZlbnRpbmcgdW5jYXVnaHQgcmVqZWN0aW9ucyBmb3IgdGhlIFByb21pc2UuYWxsIHJlc3VsdC5cbiAgICByZXN1bHQuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICBpbnZhcmlhbnQuZGVidWcoXG4gICAgICAgIGBJbiBjbGllbnQucmVmZXRjaFF1ZXJpZXMsIFByb21pc2UuYWxsIHByb21pc2UgcmVqZWN0ZWQgd2l0aCBlcnJvciAlb2AsXG4gICAgICAgIGVycm9yXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIGN1cnJlbnRseSBhY3RpdmUgYE9ic2VydmFibGVRdWVyeWAgb2JqZWN0cywgaW4gYSBgTWFwYCBrZXllZCBieVxuICAgKiBxdWVyeSBJRCBzdHJpbmdzLlxuICAgKlxuICAgKiBBbiBcImFjdGl2ZVwiIHF1ZXJ5IGlzIG9uZSB0aGF0IGhhcyBvYnNlcnZlcnMgYW5kIGEgYGZldGNoUG9saWN5YCBvdGhlciB0aGFuXG4gICAqIFwic3RhbmRieVwiIG9yIFwiY2FjaGUtb25seVwiLlxuICAgKlxuICAgKiBZb3UgY2FuIGluY2x1ZGUgYWxsIGBPYnNlcnZhYmxlUXVlcnlgIG9iamVjdHMgKGluY2x1ZGluZyB0aGUgaW5hY3RpdmUgb25lcylcbiAgICogYnkgcGFzc2luZyBcImFsbFwiIGluc3RlYWQgb2YgXCJhY3RpdmVcIiwgb3IgeW91IGNhbiBpbmNsdWRlIGp1c3QgYSBzdWJzZXQgb2ZcbiAgICogYWN0aXZlIHF1ZXJpZXMgYnkgcGFzc2luZyBhbiBhcnJheSBvZiBxdWVyeSBuYW1lcyBvciBEb2N1bWVudE5vZGUgb2JqZWN0cy5cbiAgICovXG4gIHB1YmxpYyBnZXRPYnNlcnZhYmxlUXVlcmllcyhcbiAgICBpbmNsdWRlOiBSZWZldGNoUXVlcmllc0luY2x1ZGUgPSBcImFjdGl2ZVwiXG4gICk6IE1hcDxzdHJpbmcsIE9ic2VydmFibGVRdWVyeTxhbnk+PiB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlNYW5hZ2VyLmdldE9ic2VydmFibGVRdWVyaWVzKGluY2x1ZGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cG9zZXMgdGhlIGNhY2hlJ3MgY29tcGxldGUgc3RhdGUsIGluIGEgc2VyaWFsaXphYmxlIGZvcm1hdCBmb3IgbGF0ZXIgcmVzdG9yYXRpb24uXG4gICAqL1xuICBwdWJsaWMgZXh0cmFjdChvcHRpbWlzdGljPzogYm9vbGVhbik6IFRDYWNoZVNoYXBlIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS5leHRyYWN0KG9wdGltaXN0aWMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2VzIGV4aXN0aW5nIHN0YXRlIGluIHRoZSBjYWNoZSAoaWYgYW55KSB3aXRoIHRoZSB2YWx1ZXMgZXhwcmVzc2VkIGJ5XG4gICAqIGBzZXJpYWxpemVkU3RhdGVgLlxuICAgKlxuICAgKiBDYWxsZWQgd2hlbiBoeWRyYXRpbmcgYSBjYWNoZSAoc2VydmVyIHNpZGUgcmVuZGVyaW5nLCBvciBvZmZsaW5lIHN0b3JhZ2UpLFxuICAgKiBhbmQgYWxzbyAocG90ZW50aWFsbHkpIGR1cmluZyBob3QgcmVsb2Fkcy5cbiAgICovXG4gIHB1YmxpYyByZXN0b3JlKHNlcmlhbGl6ZWRTdGF0ZTogVENhY2hlU2hhcGUpOiBBcG9sbG9DYWNoZTxUQ2FjaGVTaGFwZT4ge1xuICAgIHJldHVybiB0aGlzLmNhY2hlLnJlc3RvcmUoc2VyaWFsaXplZFN0YXRlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYWRkaXRpb25hbCBsb2NhbCByZXNvbHZlcnMuXG4gICAqL1xuICBwdWJsaWMgYWRkUmVzb2x2ZXJzKHJlc29sdmVyczogUmVzb2x2ZXJzIHwgUmVzb2x2ZXJzW10pIHtcbiAgICB0aGlzLmxvY2FsU3RhdGUuYWRkUmVzb2x2ZXJzKHJlc29sdmVycyk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IChvdmVycmlkZSBleGlzdGluZykgbG9jYWwgcmVzb2x2ZXJzLlxuICAgKi9cbiAgcHVibGljIHNldFJlc29sdmVycyhyZXNvbHZlcnM6IFJlc29sdmVycyB8IFJlc29sdmVyc1tdKSB7XG4gICAgdGhpcy5sb2NhbFN0YXRlLnNldFJlc29sdmVycyhyZXNvbHZlcnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgcmVnaXN0ZXJlZCBsb2NhbCByZXNvbHZlcnMuXG4gICAqL1xuICBwdWJsaWMgZ2V0UmVzb2x2ZXJzKCkge1xuICAgIHJldHVybiB0aGlzLmxvY2FsU3RhdGUuZ2V0UmVzb2x2ZXJzKCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGEgY3VzdG9tIGxvY2FsIHN0YXRlIGZyYWdtZW50IG1hdGNoZXIuXG4gICAqL1xuICBwdWJsaWMgc2V0TG9jYWxTdGF0ZUZyYWdtZW50TWF0Y2hlcihmcmFnbWVudE1hdGNoZXI6IEZyYWdtZW50TWF0Y2hlcikge1xuICAgIHRoaXMubG9jYWxTdGF0ZS5zZXRGcmFnbWVudE1hdGNoZXIoZnJhZ21lbnRNYXRjaGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWZpbmUgYSBuZXcgQXBvbGxvTGluayAob3IgbGluayBjaGFpbikgdGhhdCBBcG9sbG8gQ2xpZW50IHdpbGwgdXNlLlxuICAgKi9cbiAgcHVibGljIHNldExpbmsobmV3TGluazogQXBvbGxvTGluaykge1xuICAgIHRoaXMubGluayA9IHRoaXMucXVlcnlNYW5hZ2VyLmxpbmsgPSBuZXdMaW5rO1xuICB9XG5cbiAgcHVibGljIGdldCBkZWZhdWx0Q29udGV4dCgpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeU1hbmFnZXIuZGVmYXVsdENvbnRleHQ7XG4gIH1cblxuICAvKipcbiAgICogQGV4cGVyaW1lbnRhbFxuICAgKiBUaGlzIGlzIG5vdCBhIHN0YWJsZSBBUEkgLSBpdCBpcyB1c2VkIGluIGRldmVsb3BtZW50IGJ1aWxkcyB0byBleHBvc2VcbiAgICogaW5mb3JtYXRpb24gdG8gdGhlIERldlRvb2xzLlxuICAgKiBVc2UgYXQgeW91ciBvd24gcmlzayFcbiAgICogRm9yIG1vcmUgZGV0YWlscywgc2VlIFtNZW1vcnkgTWFuYWdlbWVudF0oaHR0cHM6Ly93d3cuYXBvbGxvZ3JhcGhxbC5jb20vZG9jcy9yZWFjdC9jYWNoaW5nL21lbW9yeS1tYW5hZ2VtZW50LyNtZWFzdXJpbmctY2FjaGUtdXNhZ2UpXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHRzXG4gICAqIGNvbnNvbGUubG9nKGNsaWVudC5nZXRNZW1vcnlJbnRlcm5hbHMoKSlcbiAgICogYGBgXG4gICAqIExvZ3Mgb3V0cHV0IGluIHRoZSBmb2xsb3dpbmcgSlNPTiBmb3JtYXQ6XG4gICAqIEBleGFtcGxlXG4gICAqIGBgYGpzb25cbiAgICp7XG4gICAqICBsaW1pdHM6ICAgICB7XG4gICAqICAgIHBhcnNlcjogMTAwMCxcbiAgICogICAgY2Fub25pY2FsU3RyaW5naWZ5OiAxMDAwLFxuICAgKiAgICBwcmludDogMjAwMCxcbiAgICogICAgJ2RvY3VtZW50VHJhbnNmb3JtLmNhY2hlJzogMjAwMCxcbiAgICogICAgJ3F1ZXJ5TWFuYWdlci5nZXREb2N1bWVudEluZm8nOiAyMDAwLFxuICAgKiAgICAnUGVyc2lzdGVkUXVlcnlMaW5rLnBlcnNpc3RlZFF1ZXJ5SGFzaGVzJzogMjAwMCxcbiAgICogICAgJ2ZyYWdtZW50UmVnaXN0cnkudHJhbnNmb3JtJzogMjAwMCxcbiAgICogICAgJ2ZyYWdtZW50UmVnaXN0cnkubG9va3VwJzogMTAwMCxcbiAgICogICAgJ2ZyYWdtZW50UmVnaXN0cnkuZmluZEZyYWdtZW50U3ByZWFkcyc6IDQwMDAsXG4gICAqICAgICdjYWNoZS5mcmFnbWVudFF1ZXJ5RG9jdW1lbnRzJzogMTAwMCxcbiAgICogICAgJ3JlbW92ZVR5cGVuYW1lRnJvbVZhcmlhYmxlcy5nZXRWYXJpYWJsZURlZmluaXRpb25zJzogMjAwMCxcbiAgICogICAgJ2luTWVtb3J5Q2FjaGUubWF5YmVCcm9hZGNhc3RXYXRjaCc6IDUwMDAsXG4gICAqICAgICdpbk1lbW9yeUNhY2hlLmV4ZWN1dGVTZWxlY3Rpb25TZXQnOiAxMDAwMCxcbiAgICogICAgJ2luTWVtb3J5Q2FjaGUuZXhlY3V0ZVN1YlNlbGVjdGVkQXJyYXknOiA1MDAwXG4gICAqICB9LFxuICAgKiAgc2l6ZXM6IHtcbiAgICogICAgcGFyc2VyOiAyNixcbiAgICogICAgY2Fub25pY2FsU3RyaW5naWZ5OiA0LFxuICAgKiAgICBwcmludDogMTQsXG4gICAqICAgIGFkZFR5cGVuYW1lRG9jdW1lbnRUcmFuc2Zvcm06IFtcbiAgICogICAgICB7XG4gICAqICAgICAgICBjYWNoZTogMTQsXG4gICAqICAgICAgfSxcbiAgICogICAgXSxcbiAgICogICAgcXVlcnlNYW5hZ2VyOiB7XG4gICAqICAgICAgZ2V0RG9jdW1lbnRJbmZvOiAxNCxcbiAgICogICAgICBkb2N1bWVudFRyYW5zZm9ybXM6IFtcbiAgICogICAgICAgIHtcbiAgICogICAgICAgICAgY2FjaGU6IDE0LFxuICAgKiAgICAgICAgfSxcbiAgICogICAgICAgIHtcbiAgICogICAgICAgICAgY2FjaGU6IDE0LFxuICAgKiAgICAgICAgfSxcbiAgICogICAgICBdLFxuICAgKiAgICB9LFxuICAgKiAgICBmcmFnbWVudFJlZ2lzdHJ5OiB7XG4gICAqICAgICAgZmluZEZyYWdtZW50U3ByZWFkczogMzQsXG4gICAqICAgICAgbG9va3VwOiAyMCxcbiAgICogICAgICB0cmFuc2Zvcm06IDE0LFxuICAgKiAgICB9LFxuICAgKiAgICBjYWNoZToge1xuICAgKiAgICAgIGZyYWdtZW50UXVlcnlEb2N1bWVudHM6IDIyLFxuICAgKiAgICB9LFxuICAgKiAgICBpbk1lbW9yeUNhY2hlOiB7XG4gICAqICAgICAgZXhlY3V0ZVNlbGVjdGlvblNldDogNDM0NSxcbiAgICogICAgICBleGVjdXRlU3ViU2VsZWN0ZWRBcnJheTogMTIwNixcbiAgICogICAgICBtYXliZUJyb2FkY2FzdFdhdGNoOiAzMixcbiAgICogICAgfSxcbiAgICogICAgbGlua3M6IFtcbiAgICogICAgICB7XG4gICAqICAgICAgICBQZXJzaXN0ZWRRdWVyeUxpbms6IHtcbiAgICogICAgICAgICAgcGVyc2lzdGVkUXVlcnlIYXNoZXM6IDE0LFxuICAgKiAgICAgICAgfSxcbiAgICogICAgICB9LFxuICAgKiAgICAgIHtcbiAgICogICAgICAgIHJlbW92ZVR5cGVuYW1lRnJvbVZhcmlhYmxlczoge1xuICAgKiAgICAgICAgICBnZXRWYXJpYWJsZURlZmluaXRpb25zOiAxNCxcbiAgICogICAgICAgIH0sXG4gICAqICAgICAgfSxcbiAgICogICAgXSxcbiAgICogIH0sXG4gICAqIH1cbiAgICpgYGBcbiAgICovXG4gIHB1YmxpYyBnZXRNZW1vcnlJbnRlcm5hbHM/OiB0eXBlb2YgZ2V0QXBvbGxvQ2xpZW50TWVtb3J5SW50ZXJuYWxzO1xufVxuXG5pZiAoX19ERVZfXykge1xuICBBcG9sbG9DbGllbnQucHJvdG90eXBlLmdldE1lbW9yeUludGVybmFscyA9IGdldEFwb2xsb0NsaWVudE1lbW9yeUludGVybmFscztcbn1cbiJdLCJ4X2dvb2dsZV9pZ25vcmVMaXN0IjpbMF19