UNPKG

@spartacus/core

Version:

Spartacus - the core framework

137 lines 21.4 kB
import { Injectable } from '@angular/core'; import { combineLatest, of } from 'rxjs'; import { map, shareReplay, switchMap } from 'rxjs/operators'; import { DefaultRoutePageMetaResolver } from './default-route-page-meta.resolver'; import * as i0 from "@angular/core"; import * as i1 from "../../../routing/services/activated-routes.service"; /** * Resolves the page meta based on the Angular Activated Routes */ export class RoutingPageMetaResolver { constructor(activatedRoutesService, injector) { this.activatedRoutesService = activatedRoutesService; this.injector = injector; /** * Array of activated routes, excluding the special Angular `root` route. */ this.routes$ = this.activatedRoutesService.routes$.pipe( // drop the first route - the special `root` route: map((routes) => (routes = routes.slice(1, routes.length)))); /** * Array of activated routes together with precalculated extras: * * - route's page meta resolver * - route's absolute string URL * * In case when there is no page meta resolver configured for a specific route, * it inherits its parent's resolver. * * When there is no page meta resolver configured for the highest parent in the hierarchy, * it uses the `DefaultRoutePageMetaResolver`. */ this.routesWithExtras$ = this.routes$.pipe(map((routes) => routes.reduce((results, route) => { var _a; const parent = results.length ? results[results.length - 1] : { route: null, resolver: this.injector.get(DefaultRoutePageMetaResolver), url: '', }; const resolver = (_a = this.getResolver(route)) !== null && _a !== void 0 ? _a : parent.resolver; // fallback to parent's resolver const urlPart = this.getUrlPart(route); const url = parent.url + (urlPart ? `/${urlPart}` : ''); // don't add slash for a route with path '', to avoid double slash ...//... return results.concat({ route, resolver, url }); }, [])), shareReplay({ bufferSize: 1, refCount: true })); } /** * Array of breadcrumbs defined for all the activated routes (from the root route to the leaf route). * It emits on every completed routing navigation. */ resolveBreadcrumbs(options) { return this.routesWithExtras$.pipe(map((routesWithExtras) => (options === null || options === void 0 ? void 0 : options.includeCurrentRoute) ? routesWithExtras : this.trimCurrentRoute(routesWithExtras)), switchMap((routesWithExtras) => routesWithExtras.length ? combineLatest(routesWithExtras.map((routeWithExtras) => this.resolveRouteBreadcrumb(routeWithExtras))) : of([])), map((breadcrumbArrays) => breadcrumbArrays.flat())); } /** * Returns the instance of the RoutePageMetaResolver configured for the given activated route. * Returns null in case there the resolver can't be injected or is undefined. * * @param route route to resolve */ getResolver(route) { const pageMetaConfig = this.getPageMetaConfig(route); if (typeof pageMetaConfig !== 'string' && (pageMetaConfig === null || pageMetaConfig === void 0 ? void 0 : pageMetaConfig.resolver)) { return this.injector.get(pageMetaConfig.resolver, null); } return null; } /** * Resolvers breadcrumb for a specific route */ resolveRouteBreadcrumb({ route, resolver, url, }) { const breadcrumbResolver = resolver; if (typeof breadcrumbResolver.resolveBreadcrumbs === 'function') { return breadcrumbResolver.resolveBreadcrumbs({ route, url, pageMetaConfig: this.getPageMetaConfig(route), }); } return of([]); } /** * By default in breadcrumbs list we don't want to show a link to the current page, so this function * trims the last breadcrumb (the breadcrumb of the current route). * * This function also handles special case when the current route has a configured empty path ('' route). * The '' routes are often a _technical_ routes to organize other routes, assign common guards for its children, etc. * It shouldn't happen that '' route has a defined breadcrumb config. * * In that case, we trim not only the last route ('' route), but also its parent route with non-empty path * (which likely defines the breadcrumb config). */ trimCurrentRoute(routesWithExtras) { // If the last route is '', we trim: // - the '' route // - all parent '' routes (until we meet route with non-empty path) var _a, _b; let i = routesWithExtras.length - 1; while (((_b = (_a = routesWithExtras[i]) === null || _a === void 0 ? void 0 : _a.route) === null || _b === void 0 ? void 0 : _b.url.length) === 0 && i >= 0) { i--; } // Finally we trim the last route (the one with non-empty path) return routesWithExtras.slice(0, i); } /** * Returns the URL path for the given activated route in a string format. * (ActivatedRouteSnapshot#url contains an array of `UrlSegment`s, not a string) */ getUrlPart(route) { return route.url.map((urlSegment) => urlSegment.path).join('/'); } /** * Returns the breadcrumb config placed in the route's `data` configuration. */ getPageMetaConfig(route) { var _a, _b; // Note: we use `route.routeConfig.data` (not `route.data`) to save us from // an edge case bug. In Angular, by design the `data` of ActivatedRoute is inherited // from the parent route, if only the child has an empty path ''. // But in any case we don't want the page meta configs to be inherited, so we // read data from the original `routeConfig` which is static. // // Note: we may inherit the parent's page meta resolver in case we don't define it, // but we don't want to inherit parent's page meta config! return (_b = (_a = route === null || route === void 0 ? void 0 : route.routeConfig) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.cxPageMeta; } } RoutingPageMetaResolver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: RoutingPageMetaResolver, deps: [{ token: i1.ActivatedRoutesService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); RoutingPageMetaResolver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: RoutingPageMetaResolver, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: RoutingPageMetaResolver, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: i1.ActivatedRoutesService }, { type: i0.Injector }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGluZy1wYWdlLW1ldGEucmVzb2x2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9jbXMvcGFnZS9yb3V0aW5nL3JvdXRpbmctcGFnZS1tZXRhLnJlc29sdmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQVksTUFBTSxlQUFlLENBQUM7QUFFckQsT0FBTyxFQUFFLGFBQWEsRUFBYyxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDckQsT0FBTyxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHN0QsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sb0NBQW9DLENBQUM7OztBQXFCbEY7O0dBRUc7QUFFSCxNQUFNLE9BQU8sdUJBQXVCO0lBQ2xDLFlBQ1ksc0JBQThDLEVBQzlDLFFBQWtCO1FBRGxCLDJCQUFzQixHQUF0QixzQkFBc0IsQ0FBd0I7UUFDOUMsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUc5Qjs7V0FFRztRQUNnQixZQUFPLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxJQUFJO1FBQ25FLG1EQUFtRDtRQUNuRCxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQzNELENBQUM7UUFFRjs7Ozs7Ozs7Ozs7V0FXRztRQUNnQixzQkFBaUIsR0FDbEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQ2YsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FDYixNQUFNLENBQUMsTUFBTSxDQUFvQixDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRTs7WUFDbEQsTUFBTSxNQUFNLEdBQUcsT0FB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Y3RhYmxlLCBJbmplY3RvciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGVTbmFwc2hvdCB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBjb21iaW5lTGF0ZXN0LCBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwLCBzaGFyZVJlcGxheSwgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGVzU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3JvdXRpbmcvc2VydmljZXMvYWN0aXZhdGVkLXJvdXRlcy5zZXJ2aWNlJztcbmltcG9ydCB7IEJyZWFkY3J1bWJNZXRhIH0gZnJvbSAnLi4vLi4vbW9kZWwvcGFnZS5tb2RlbCc7XG5pbXBvcnQgeyBEZWZhdWx0Um91dGVQYWdlTWV0YVJlc29sdmVyIH0gZnJvbSAnLi9kZWZhdWx0LXJvdXRlLXBhZ2UtbWV0YS5yZXNvbHZlcic7XG5pbXBvcnQge1xuICBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90V2l0aFBhZ2VNZXRhLFxuICBSb3V0ZUJyZWFkY3J1bWJSZXNvbHZlcixcbiAgUm91dGVQYWdlTWV0YUNvbmZpZyxcbn0gZnJvbSAnLi9yb3V0ZS1wYWdlLW1ldGEubW9kZWwnO1xuXG4vLyBQUklWQVRFXG5leHBvcnQgaW50ZXJmYWNlIFJvdXRlV2l0aEV4dHJhcyB7XG4gIHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90V2l0aFBhZ2VNZXRhO1xuICByZXNvbHZlcjogYW55O1xuICB1cmw6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSb3V0aW5nUmVzb2x2ZUJyZWFkY3J1bWJzT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBJbmNsdWRlcyB0aGUgY3VycmVudCByb3V0ZSBpbiB0aGUgYnJlYWRjcnVtYnMuXG4gICAqL1xuICBpbmNsdWRlQ3VycmVudFJvdXRlPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgcGFnZSBtZXRhIGJhc2VkIG9uIHRoZSBBbmd1bGFyIEFjdGl2YXRlZCBSb3V0ZXNcbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBSb3V0aW5nUGFnZU1ldGFSZXNvbHZlciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBhY3RpdmF0ZWRSb3V0ZXNTZXJ2aWNlOiBBY3RpdmF0ZWRSb3V0ZXNTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBpbmplY3RvcjogSW5qZWN0b3JcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBBcnJheSBvZiBhY3RpdmF0ZWQgcm91dGVzLCBleGNsdWRpbmcgdGhlIHNwZWNpYWwgQW5ndWxhciBgcm9vdGAgcm91dGUuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcm91dGVzJCA9IHRoaXMuYWN0aXZhdGVkUm91dGVzU2VydmljZS5yb3V0ZXMkLnBpcGUoXG4gICAgLy8gZHJvcCB0aGUgZmlyc3Qgcm91dGUgLSB0aGUgc3BlY2lhbCBgcm9vdGAgcm91dGU6XG4gICAgbWFwKChyb3V0ZXMpID0+IChyb3V0ZXMgPSByb3V0ZXMuc2xpY2UoMSwgcm91dGVzLmxlbmd0aCkpKVxuICApO1xuXG4gIC8qKlxuICAgKiBBcnJheSBvZiBhY3RpdmF0ZWQgcm91dGVzIHRvZ2V0aGVyIHdpdGggcHJlY2FsY3VsYXRlZCBleHRyYXM6XG4gICAqXG4gICAqIC0gcm91dGUncyBwYWdlIG1ldGEgcmVzb2x2ZXJcbiAgICogLSByb3V0ZSdzIGFic29sdXRlIHN0cmluZyBVUkxcbiAgICpcbiAgICogSW4gY2FzZSB3aGVuIHRoZXJlIGlzIG5vIHBhZ2UgbWV0YSByZXNvbHZlciBjb25maWd1cmVkIGZvciBhIHNwZWNpZmljIHJvdXRlLFxuICAgKiBpdCBpbmhlcml0cyBpdHMgcGFyZW50J3MgcmVzb2x2ZXIuXG4gICAqXG4gICAqIFdoZW4gdGhlcmUgaXMgbm8gcGFnZSBtZXRhIHJlc29sdmVyIGNvbmZpZ3VyZWQgZm9yIHRoZSBoaWdoZXN0IHBhcmVudCBpbiB0aGUgaGllcmFyY2h5LFxuICAgKiBpdCB1c2VzIHRoZSBgRGVmYXVsdFJvdXRlUGFnZU1ldGFSZXNvbHZlcmAuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcm91dGVzV2l0aEV4dHJhcyQ6IE9ic2VydmFibGU8Um91dGVXaXRoRXh0cmFzW10+ID1cbiAgICB0aGlzLnJvdXRlcyQucGlwZShcbiAgICAgIG1hcCgocm91dGVzKSA9PlxuICAgICAgICByb3V0ZXMucmVkdWNlPFJvdXRlV2l0aEV4dHJhc1tdPigocmVzdWx0cywgcm91dGUpID0+IHtcbiAgICAgICAgICBjb25zdCBwYXJlbnQgPSByZXN1bHRzLmxlbmd0aFxuICAgICAgICAgICAgPyByZXN1bHRzW3Jlc3VsdHMubGVuZ3RoIC0gMV1cbiAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgIHJvdXRlOiBudWxsLFxuICAgICAgICAgICAgICAgIHJlc29sdmVyOiB0aGlzLmluamVjdG9yLmdldChEZWZhdWx0Um91dGVQYWdlTWV0YVJlc29sdmVyKSxcbiAgICAgICAgICAgICAgICB1cmw6ICcnLFxuICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgY29uc3QgcmVzb2x2ZXIgPSB0aGlzLmdldFJlc29sdmVyKHJvdXRlKSA/PyBwYXJlbnQucmVzb2x2ZXI7IC8vIGZhbGxiYWNrIHRvIHBhcmVudCdzIHJlc29sdmVyXG5cbiAgICAgICAgICBjb25zdCB1cmxQYXJ0ID0gdGhpcy5nZXRVcmxQYXJ0KHJvdXRlKTtcbiAgICAgICAgICBjb25zdCB1cmwgPSBwYXJlbnQudXJsICsgKHVybFBhcnQgPyBgLyR7dXJsUGFydH1gIDogJycpOyAvLyBkb24ndCBhZGQgc2xhc2ggZm9yIGEgcm91dGUgd2l0aCBwYXRoICcnLCB0byBhdm9pZCBkb3VibGUgc2xhc2ggLi4uLy8uLi5cblxuICAgICAgICAgIHJldHVybiByZXN1bHRzLmNvbmNhdCh7IHJvdXRlLCByZXNvbHZlciwgdXJsIH0pO1xuICAgICAgICB9LCBbXSlcbiAgICAgICksXG4gICAgICBzaGFyZVJlcGxheSh7IGJ1ZmZlclNpemU6IDEsIHJlZkNvdW50OiB0cnVlIH0pXG4gICAgKTtcblxuICAvKipcbiAgICogQXJyYXkgb2YgYnJlYWRjcnVtYnMgZGVmaW5lZCBmb3IgYWxsIHRoZSBhY3RpdmF0ZWQgcm91dGVzIChmcm9tIHRoZSByb290IHJvdXRlIHRvIHRoZSBsZWFmIHJvdXRlKS5cbiAgICogSXQgZW1pdHMgb24gZXZlcnkgY29tcGxldGVkIHJvdXRpbmcgbmF2aWdhdGlvbi5cbiAgICovXG4gIHJlc29sdmVCcmVhZGNydW1icyhcbiAgICBvcHRpb25zPzogUm91dGluZ1Jlc29sdmVCcmVhZGNydW1ic09wdGlvbnNcbiAgKTogT2JzZXJ2YWJsZTxCcmVhZGNydW1iTWV0YVtdPiB7XG4gICAgcmV0dXJuIHRoaXMucm91dGVzV2l0aEV4dHJhcyQucGlwZShcbiAgICAgIG1hcCgocm91dGVzV2l0aEV4dHJhcykgPT5cbiAgICAgICAgb3B0aW9ucz8uaW5jbHVkZUN1cnJlbnRSb3V0ZVxuICAgICAgICAgID8gcm91dGVzV2l0aEV4dHJhc1xuICAgICAgICAgIDogdGhpcy50cmltQ3VycmVudFJvdXRlKHJvdXRlc1dpdGhFeHRyYXMpXG4gICAgICApLFxuICAgICAgc3dpdGNoTWFwKChyb3V0ZXNXaXRoRXh0cmFzKSA9PlxuICAgICAgICByb3V0ZXNXaXRoRXh0cmFzLmxlbmd0aFxuICAgICAgICAgID8gY29tYmluZUxhdGVzdChcbiAgICAgICAgICAgICAgcm91dGVzV2l0aEV4dHJhcy5tYXAoKHJvdXRlV2l0aEV4dHJhcykgPT5cbiAgICAgICAgICAgICAgICB0aGlzLnJlc29sdmVSb3V0ZUJyZWFkY3J1bWIocm91dGVXaXRoRXh0cmFzKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiBvZihbXSlcbiAgICAgICksXG4gICAgICBtYXAoKGJyZWFkY3J1bWJBcnJheXMpID0+IGJyZWFkY3J1bWJBcnJheXMuZmxhdCgpKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgaW5zdGFuY2Ugb2YgdGhlIFJvdXRlUGFnZU1ldGFSZXNvbHZlciBjb25maWd1cmVkIGZvciB0aGUgZ2l2ZW4gYWN0aXZhdGVkIHJvdXRlLlxuICAgKiBSZXR1cm5zIG51bGwgaW4gY2FzZSB0aGVyZSB0aGUgcmVzb2x2ZXIgY2FuJ3QgYmUgaW5qZWN0ZWQgb3IgaXMgdW5kZWZpbmVkLlxuICAgKlxuICAgKiBAcGFyYW0gcm91dGUgcm91dGUgdG8gcmVzb2x2ZVxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFJlc29sdmVyKHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90V2l0aFBhZ2VNZXRhKTogYW55IHtcbiAgICBjb25zdCBwYWdlTWV0YUNvbmZpZyA9IHRoaXMuZ2V0UGFnZU1ldGFDb25maWcocm91dGUpO1xuXG4gICAgaWYgKHR5cGVvZiBwYWdlTWV0YUNvbmZpZyAhPT0gJ3N0cmluZycgJiYgcGFnZU1ldGFDb25maWc/LnJlc29sdmVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5pbmplY3Rvci5nZXQocGFnZU1ldGFDb25maWcucmVzb2x2ZXIsIG51bGwpO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcnMgYnJlYWRjcnVtYiBmb3IgYSBzcGVjaWZpYyByb3V0ZVxuICAgKi9cbiAgcHJvdGVjdGVkIHJlc29sdmVSb3V0ZUJyZWFkY3J1bWIoe1xuICAgIHJvdXRlLFxuICAgIHJlc29sdmVyLFxuICAgIHVybCxcbiAgfTogUm91dGVXaXRoRXh0cmFzKTogT2JzZXJ2YWJsZTxCcmVhZGNydW1iTWV0YVtdPiB7XG4gICAgY29uc3QgYnJlYWRjcnVtYlJlc29sdmVyID0gcmVzb2x2ZXIgYXMgUm91dGVCcmVhZGNydW1iUmVzb2x2ZXI7XG5cbiAgICBpZiAodHlwZW9mIGJyZWFkY3J1bWJSZXNvbHZlci5yZXNvbHZlQnJlYWRjcnVtYnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiBicmVhZGNydW1iUmVzb2x2ZXIucmVzb2x2ZUJyZWFkY3J1bWJzKHtcbiAgICAgICAgcm91dGUsXG4gICAgICAgIHVybCxcbiAgICAgICAgcGFnZU1ldGFDb25maWc6IHRoaXMuZ2V0UGFnZU1ldGFDb25maWcocm91dGUpLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBvZihbXSk7XG4gIH1cblxuICAvKipcbiAgICogQnkgZGVmYXVsdCBpbiBicmVhZGNydW1icyBsaXN0IHdlIGRvbid0IHdhbnQgdG8gc2hvdyBhIGxpbmsgdG8gdGhlIGN1cnJlbnQgcGFnZSwgc28gdGhpcyBmdW5jdGlvblxuICAgKiB0cmltcyB0aGUgbGFzdCBicmVhZGNydW1iICh0aGUgYnJlYWRjcnVtYiBvZiB0aGUgY3VycmVudCByb3V0ZSkuXG4gICAqXG4gICAqIFRoaXMgZnVuY3Rpb24gYWxzbyBoYW5kbGVzIHNwZWNpYWwgY2FzZSB3aGVuIHRoZSBjdXJyZW50IHJvdXRlIGhhcyBhIGNvbmZpZ3VyZWQgZW1wdHkgcGF0aCAoJycgcm91dGUpLlxuICAgKiBUaGUgJycgcm91dGVzIGFyZSBvZnRlbiBhIF90ZWNobmljYWxfIHJvdXRlcyB0byBvcmdhbml6ZSBvdGhlciByb3V0ZXMsIGFzc2lnbiBjb21tb24gZ3VhcmRzIGZvciBpdHMgY2hpbGRyZW4sIGV0Yy5cbiAgICogSXQgc2hvdWxkbid0IGhhcHBlbiB0aGF0ICcnIHJvdXRlIGhhcyBhIGRlZmluZWQgYnJlYWRjcnVtYiBjb25maWcuXG4gICAqXG4gICAqIEluIHRoYXQgY2FzZSwgd2UgdHJpbSBub3Qgb25seSB0aGUgbGFzdCByb3V0ZSAoJycgcm91dGUpLCBidXQgYWxzbyBpdHMgcGFyZW50IHJvdXRlIHdpdGggbm9uLWVtcHR5IHBhdGhcbiAgICogKHdoaWNoIGxpa2VseSBkZWZpbmVzIHRoZSBicmVhZGNydW1iIGNvbmZpZykuXG4gICAqL1xuICBwcml2YXRlIHRyaW1DdXJyZW50Um91dGUoXG4gICAgcm91dGVzV2l0aEV4dHJhczogUm91dGVXaXRoRXh0cmFzW11cbiAgKTogUm91dGVXaXRoRXh0cmFzW10ge1xuICAgIC8vIElmIHRoZSBsYXN0IHJvdXRlIGlzICcnLCB3ZSB0cmltOlxuICAgIC8vIC0gdGhlICcnIHJvdXRlXG4gICAgLy8gLSBhbGwgcGFyZW50ICcnIHJvdXRlcyAodW50aWwgd2UgbWVldCByb3V0ZSB3aXRoIG5vbi1lbXB0eSBwYXRoKVxuXG4gICAgbGV0IGkgPSByb3V0ZXNXaXRoRXh0cmFzLmxlbmd0aCAtIDE7XG4gICAgd2hpbGUgKHJvdXRlc1dpdGhFeHRyYXNbaV0/LnJvdXRlPy51cmwubGVuZ3RoID09PSAwICYmIGkgPj0gMCkge1xuICAgICAgaS0tO1xuICAgIH1cblxuICAgIC8vIEZpbmFsbHkgd2UgdHJpbSB0aGUgbGFzdCByb3V0ZSAodGhlIG9uZSB3aXRoIG5vbi1lbXB0eSBwYXRoKVxuICAgIHJldHVybiByb3V0ZXNXaXRoRXh0cmFzLnNsaWNlKDAsIGkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIFVSTCBwYXRoIGZvciB0aGUgZ2l2ZW4gYWN0aXZhdGVkIHJvdXRlIGluIGEgc3RyaW5nIGZvcm1hdC5cbiAgICogKEFjdGl2YXRlZFJvdXRlU25hcHNob3QjdXJsIGNvbnRhaW5zIGFuIGFycmF5IG9mIGBVcmxTZWdtZW50YHMsIG5vdCBhIHN0cmluZylcbiAgICovXG4gIHByaXZhdGUgZ2V0VXJsUGFydChyb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHJvdXRlLnVybC5tYXAoKHVybFNlZ21lbnQpID0+IHVybFNlZ21lbnQucGF0aCkuam9pbignLycpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGJyZWFkY3J1bWIgY29uZmlnIHBsYWNlZCBpbiB0aGUgcm91dGUncyBgZGF0YWAgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWdlTWV0YUNvbmZpZyhcbiAgICByb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdFdpdGhQYWdlTWV0YVxuICApOiBSb3V0ZVBhZ2VNZXRhQ29uZmlnIHtcbiAgICAvLyBOb3RlOiB3ZSB1c2UgYHJvdXRlLnJvdXRlQ29uZmlnLmRhdGFgIChub3QgYHJvdXRlLmRhdGFgKSB0byBzYXZlIHVzIGZyb21cbiAgICAvLyBhbiBlZGdlIGNhc2UgYnVnLiBJbiBBbmd1bGFyLCBieSBkZXNpZ24gdGhlIGBkYXRhYCBvZiBBY3RpdmF0ZWRSb3V0ZSBpcyBpbmhlcml0ZWRcbiAgICAvLyBmcm9tIHRoZSBwYXJlbnQgcm91dGUsIGlmIG9ubHkgdGhlIGNoaWxkIGhhcyBhbiBlbXB0eSBwYXRoICcnLlxuICAgIC8vIEJ1dCBpbiBhbnkgY2FzZSB3ZSBkb24ndCB3YW50IHRoZSBwYWdlIG1ldGEgY29uZmlncyB0byBiZSBpbmhlcml0ZWQsIHNvIHdlXG4gICAgLy8gcmVhZCBkYXRhIGZyb20gdGhlIG9yaWdpbmFsIGByb3V0ZUNvbmZpZ2Agd2hpY2ggaXMgc3RhdGljLlxuICAgIC8vXG4gICAgLy8gTm90ZTogd2UgbWF5IGluaGVyaXQgdGhlIHBhcmVudCdzIHBhZ2UgbWV0YSByZXNvbHZlciBpbiBjYXNlIHdlIGRvbid0IGRlZmluZSBpdCxcbiAgICAvLyBidXQgd2UgZG9uJ3Qgd2FudCB0byBpbmhlcml0IHBhcmVudCdzIHBhZ2UgbWV0YSBjb25maWchXG4gICAgcmV0dXJuIHJvdXRlPy5yb3V0ZUNvbmZpZz8uZGF0YT8uY3hQYWdlTWV0YTtcbiAgfVxufVxuIl19