@cisstech/nge
Version:
NG Essentials is a collection of libraries for Angular developers.
203 lines • 24.3 kB
JavaScript
import { Injectable } from '@angular/core';
import { NavigationEnd } from '@angular/router';
import { BehaviorSubject } from 'rxjs';
import { filter } from 'rxjs/operators';
import { extractNgeDocSettings } from './nge-doc';
import * as i0 from "@angular/core";
import * as i1 from "@angular/router";
import * as i2 from "@angular/common";
export class NgeDocService {
/** documentation state */
get stateChanges() {
return this.state.pipe(filter((state) => !!state.currLink));
}
constructor(router, injector, location, activatedRoute) {
this.router = router;
this.injector = injector;
this.location = location;
this.activatedRoute = activatedRoute;
this.state = new BehaviorSubject({
meta: {
root: '',
name: '',
},
links: [],
prevLink: undefined,
nextLink: undefined,
currLink: undefined,
});
this.pages = new Map();
this.links = [];
this.subscriptions = [];
}
ngOnDestroy() {
this.reset();
}
/**
* Loads navigation from the router configuration.
*/
async setup() {
this.reset();
const { data } = this.activatedRoute.snapshot;
const settings = extractNgeDocSettings(data);
for (const setting of settings) {
const links = [];
let meta;
if (typeof setting.meta === 'function') {
meta = await setting.meta(this.injector);
}
else {
meta = setting.meta;
}
if (!meta) {
throw new Error('[nge-doc]: Missing setting.meta');
}
for (const item of setting.pages) {
const pages = [];
let object;
if (typeof item === 'function') {
object = await item(this.injector);
}
else {
object = item;
}
if (Array.isArray(object)) {
pages.push(...object);
}
else {
pages.push(object);
}
pages.forEach((page) => {
links.push(page);
this.resolvePageLinks(meta, page);
});
this.pages.set(meta.root, {
meta,
links: links,
});
}
}
this.subscriptions.push(this.router.events.pipe(filter((e) => e instanceof NavigationEnd)).subscribe(this.onChangeRoute.bind(this)));
this.onChangeRoute();
}
/**
* Checks whether the given `link` is active.
* @param link The link to test.
*/
isActive(link) {
const tree = this.location.path().split('/');
for (let i = 0; i < tree.length; i++) {
const path = tree.slice(0, tree.length - i).join('/');
if (path && path.endsWith(link.href)) {
return true;
}
}
return false;
}
/**
* Checks whether the given `link` includes sub links.
* @param link The link to test.
*/
isExpandable(link) {
return !!link.children?.length;
}
join(a, b) {
if (a.endsWith('/')) {
a = a.slice(0, a.length - 1);
}
if (b.startsWith('/')) {
b = b.slice(1);
}
return a + '/' + b;
}
resolvePageLinks(meta, page) {
const createLink = (link, parent) => {
link.href = this.join(parent, link.href);
this.links.push(link);
link.children?.forEach((child) => {
createLink(child, link.href);
});
};
createLink(page, meta.root);
}
async onChangeRoute() {
if (!this.pages.size) {
return;
}
const path = this.location.path();
const paths = [path, path + '/'];
let meta;
let links = [];
for (const [k, v] of this.pages) {
if (paths.some((path) => path.includes(k))) {
meta = v.meta;
links = v.links;
break;
}
}
if (!meta) {
throw new Error('[nge-doc]: Unregisted page ' + path);
}
let { currLink, prevLink, nextLink } = this.state.value;
// ignore same page navigation (fragment navigation)
if (currLink && paths.some((p) => p.endsWith(currLink.href))) {
return;
}
// calculate current, previous and next links
// https://stackoverflow.com/questions/4467539/javascript-modulo-gives-a-negative-result-for-negative-numbers
const modulo = (a, n) => {
return ((a % n) + n) % n;
};
for (let i = 0; i < this.links.length; i++) {
const link = this.links[i];
if (paths.some((path) => path.endsWith(link.href))) {
const prevIndex = modulo(i - 1, this.links.length);
const nextIndex = modulo(i + 1, this.links.length);
currLink = link;
nextLink = this.links[nextIndex];
prevLink = this.links[prevIndex];
break;
}
}
// navigate to first page if currLink is not defined
if (!currLink) {
this.router.navigateByUrl(links[0].href, {
replaceUrl: true,
});
return;
}
// navigate to first children if currLink doesn't have a renderer
if (!currLink.renderer && currLink.children?.length) {
this.router.navigateByUrl(currLink.children[0].href, {
replaceUrl: true,
});
return;
}
// expand visible links
this.links.forEach((link) => {
if (paths.some((path) => path.endsWith(link.href))) {
link.expanded = true;
}
});
// notify state change
this.state.next({
meta,
links,
prevLink,
currLink,
nextLink,
});
}
reset() {
this.subscriptions.forEach((s) => s.unsubscribe());
this.subscriptions.splice(0, this.subscriptions.length);
this.pages.clear();
this.links.splice(0, this.links.length);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocService, deps: [{ token: i1.Router }, { token: i0.Injector }, { token: i2.Location }, { token: i1.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeDocService, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i1.Router }, { type: i0.Injector }, { type: i2.Location }, { type: i1.ActivatedRoute }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdlLWRvYy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmdlL2RvYy9zcmMvbmdlLWRvYy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxVQUFVLEVBQXVCLE1BQU0sZUFBZSxDQUFBO0FBQy9ELE9BQU8sRUFBa0IsYUFBYSxFQUFVLE1BQU0saUJBQWlCLENBQUE7QUFDdkUsT0FBTyxFQUFFLGVBQWUsRUFBZ0IsTUFBTSxNQUFNLENBQUE7QUFDcEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBQ3ZDLE9BQU8sRUFBdUMscUJBQXFCLEVBQUUsTUFBTSxXQUFXLENBQUE7Ozs7QUFHdEYsTUFBTSxPQUFPLGFBQWE7SUF3QnhCLDBCQUEwQjtJQUMxQixJQUFJLFlBQVk7UUFDZCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFBO0lBQzdELENBQUM7SUFFRCxZQUNtQixNQUFjLEVBQ2QsUUFBa0IsRUFDbEIsUUFBa0IsRUFDbEIsY0FBOEI7UUFIOUIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDbEIsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNsQixtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFoQ2hDLFVBQUssR0FBRyxJQUFJLGVBQWUsQ0FBYztZQUN4RCxJQUFJLEVBQUU7Z0JBQ0osSUFBSSxFQUFFLEVBQUU7Z0JBQ1IsSUFBSSxFQUFFLEVBQUU7YUFDVDtZQUNELEtBQUssRUFBRSxFQUFFO1lBQ1QsUUFBUSxFQUFFLFNBQVM7WUFDbkIsUUFBUSxFQUFFLFNBQVM7WUFDbkIsUUFBUSxFQUFFLFNBQVM7U0FDcEIsQ0FBQyxDQUFBO1FBRWUsVUFB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Q0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQTtRQUNsRCxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUN2RCxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFBO1FBQ2xCLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQ3pDLENBQUM7OEdBdk9VLGFBQWE7a0hBQWIsYUFBYTs7MkZBQWIsYUFBYTtrQkFEekIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExvY2F0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJ1xuaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0b3IsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSwgTmF2aWdhdGlvbkVuZCwgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJ1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJ1xuaW1wb3J0IHsgZmlsdGVyIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnXG5pbXBvcnQgeyBOZ2VEb2NMaW5rLCBOZ2VEb2NNZXRhLCBOZ2VEb2NTdGF0ZSwgZXh0cmFjdE5nZURvY1NldHRpbmdzIH0gZnJvbSAnLi9uZ2UtZG9jJ1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTmdlRG9jU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RhdGUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PE5nZURvY1N0YXRlPih7XG4gICAgbWV0YToge1xuICAgICAgcm9vdDogJycsXG4gICAgICBuYW1lOiAnJyxcbiAgICB9LFxuICAgIGxpbmtzOiBbXSxcbiAgICBwcmV2TGluazogdW5kZWZpbmVkLFxuICAgIG5leHRMaW5rOiB1bmRlZmluZWQsXG4gICAgY3Vyckxpbms6IHVuZGVmaW5lZCxcbiAgfSlcblxuICBwcml2YXRlIHJlYWRvbmx5IHBhZ2VzID0gbmV3IE1hcDxcbiAgICBzdHJpbmcsXG4gICAge1xuICAgICAgbWV0YTogTmdlRG9jTWV0YVxuICAgICAgbGlua3M6IE5nZURvY0xpbmtbXVxuICAgIH1cbiAgPigpXG5cbiAgcHJpdmF0ZSByZWFkb25seSBsaW5rczogTmdlRG9jTGlua1tdID0gW11cblxuICBwcml2YXRlIHJlYWRvbmx5IHN1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbltdID0gW11cblxuICAvKiogZG9jdW1lbnRhdGlvbiBzdGF0ZSAqL1xuICBnZXQgc3RhdGVDaGFuZ2VzKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLnBpcGUoZmlsdGVyKChzdGF0ZSkgPT4gISFzdGF0ZS5jdXJyTGluaykpXG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlcjogUm91dGVyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbG9jYXRpb246IExvY2F0aW9uLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlXG4gICkge31cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnJlc2V0KClcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkcyBuYXZpZ2F0aW9uIGZyb20gdGhlIHJvdXRlciBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgYXN5bmMgc2V0dXAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5yZXNldCgpXG5cbiAgICBjb25zdCB7IGRhdGEgfSA9IHRoaXMuYWN0aXZhdGVkUm91dGUuc25hcHNob3RcbiAgICBjb25zdCBzZXR0aW5ncyA9IGV4dHJhY3ROZ2VEb2NTZXR0aW5ncyhkYXRhKVxuXG4gICAgZm9yIChjb25zdCBzZXR0aW5nIG9mIHNldHRpbmdzKSB7XG4gICAgICBjb25zdCBsaW5rczogTmdlRG9jTGlua1tdID0gW11cblxuICAgICAgbGV0IG1ldGE6IE5nZURvY01ldGEgfCB1bmRlZmluZWRcbiAgICAgIGlmICh0eXBlb2Ygc2V0dGluZy5tZXRhID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIG1ldGEgPSBhd2FpdCBzZXR0aW5nLm1ldGEodGhpcy5pbmplY3RvcilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1ldGEgPSBzZXR0aW5nLm1ldGFcbiAgICAgIH1cblxuICAgICAgaWYgKCFtZXRhKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignW25nZS1kb2NdOiBNaXNzaW5nIHNldHRpbmcubWV0YScpXG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBzZXR0aW5nLnBhZ2VzKSB7XG4gICAgICAgIGNvbnN0IHBhZ2VzOiBOZ2VEb2NMaW5rW10gPSBbXVxuXG4gICAgICAgIGxldCBvYmplY3Q6IGFueVxuICAgICAgICBpZiAodHlwZW9mIGl0ZW0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBvYmplY3QgPSBhd2FpdCBpdGVtKHRoaXMuaW5qZWN0b3IpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb2JqZWN0ID0gaXRlbVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgICAgICAgIHBhZ2VzLnB1c2goLi4ub2JqZWN0KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhZ2VzLnB1c2gob2JqZWN0KVxuICAgICAgICB9XG5cbiAgICAgICAgcGFnZXMuZm9yRWFjaCgocGFnZSkgPT4ge1xuICAgICAgICAgIGxpbmtzLnB1c2gocGFnZSlcbiAgICAgICAgICB0aGlzLnJlc29sdmVQYWdlTGlua3MobWV0YSEsIHBhZ2UpXG4gICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5wYWdlcy5zZXQobWV0YS5yb290LCB7XG4gICAgICAgICAgbWV0YSxcbiAgICAgICAgICBsaW5rczogbGlua3MsXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLnJvdXRlci5ldmVudHMucGlwZShmaWx0ZXIoKGUpID0+IGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uRW5kKSkuc3Vic2NyaWJlKHRoaXMub25DaGFuZ2VSb3V0ZS5iaW5kKHRoaXMpKVxuICAgIClcblxuICAgIHRoaXMub25DaGFuZ2VSb3V0ZSgpXG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGdpdmVuIGBsaW5rYCBpcyBhY3RpdmUuXG4gICAqIEBwYXJhbSBsaW5rIFRoZSBsaW5rIHRvIHRlc3QuXG4gICAqL1xuICBpc0FjdGl2ZShsaW5rOiBOZ2VEb2NMaW5rKTogYm9vbGVhbiB7XG4gICAgY29uc3QgdHJlZSA9IHRoaXMubG9jYXRpb24ucGF0aCgpLnNwbGl0KCcvJylcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRyZWUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHBhdGggPSB0cmVlLnNsaWNlKDAsIHRyZWUubGVuZ3RoIC0gaSkuam9pbignLycpXG4gICAgICBpZiAocGF0aCAmJiBwYXRoLmVuZHNXaXRoKGxpbmsuaHJlZikpIHtcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGdpdmVuIGBsaW5rYCBpbmNsdWRlcyBzdWIgbGlua3MuXG4gICAqIEBwYXJhbSBsaW5rIFRoZSBsaW5rIHRvIHRlc3QuXG4gICAqL1xuICBpc0V4cGFuZGFibGUobGluazogTmdlRG9jTGluayk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIWxpbmsuY2hpbGRyZW4/Lmxlbmd0aFxuICB9XG5cbiAgcHJpdmF0ZSBqb2luKGE6IHN0cmluZywgYjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoYS5lbmRzV2l0aCgnLycpKSB7XG4gICAgICBhID0gYS5zbGljZSgwLCBhLmxlbmd0aCAtIDEpXG4gICAgfVxuICAgIGlmIChiLnN0YXJ0c1dpdGgoJy8nKSkge1xuICAgICAgYiA9IGIuc2xpY2UoMSlcbiAgICB9XG4gICAgcmV0dXJuIGEgKyAnLycgKyBiXG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVQYWdlTGlua3MobWV0YTogTmdlRG9jTWV0YSwgcGFnZTogTmdlRG9jTGluaykge1xuICAgIGNvbnN0IGNyZWF0ZUxpbmsgPSAobGluazogTmdlRG9jTGluaywgcGFyZW50OiBzdHJpbmcpID0+IHtcbiAgICAgIGxpbmsuaHJlZiA9IHRoaXMuam9pbihwYXJlbnQsIGxpbmsuaHJlZilcbiAgICAgIHRoaXMubGlua3MucHVzaChsaW5rKVxuICAgICAgbGluay5jaGlsZHJlbj8uZm9yRWFjaCgoY2hpbGQpID0+IHtcbiAgICAgICAgY3JlYXRlTGluayhjaGlsZCwgbGluay5ocmVmKVxuICAgICAgfSlcbiAgICB9XG4gICAgY3JlYXRlTGluayhwYWdlLCBtZXRhLnJvb3QpXG4gIH1cblxuICBwcml2YXRlIGFzeW5jIG9uQ2hhbmdlUm91dGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLnBhZ2VzLnNpemUpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHBhdGggPSB0aGlzLmxvY2F0aW9uLnBhdGgoKVxuICAgIGNvbnN0IHBhdGhzID0gW3BhdGgsIHBhdGggKyAnLyddXG5cbiAgICBsZXQgbWV0YTogTmdlRG9jTWV0YSB8IHVuZGVmaW5lZFxuICAgIGxldCBsaW5rczogTmdlRG9jTGlua1tdID0gW11cblxuICAgIGZvciAoY29uc3QgW2ssIHZdIG9mIHRoaXMucGFnZXMpIHtcbiAgICAgIGlmIChwYXRocy5zb21lKChwYXRoKSA9PiBwYXRoLmluY2x1ZGVzKGspKSkge1xuICAgICAgICBtZXRhID0gdi5tZXRhXG4gICAgICAgIGxpbmtzID0gdi5saW5rc1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghbWV0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdbbmdlLWRvY106IFVucmVnaXN0ZWQgcGFnZSAnICsgcGF0aClcbiAgICB9XG5cbiAgICBsZXQgeyBjdXJyTGluaywgcHJldkxpbmssIG5leHRMaW5rIH0gPSB0aGlzLnN0YXRlLnZhbHVlXG5cbiAgICAvLyBpZ25vcmUgc2FtZSBwYWdlIG5hdmlnYXRpb24gKGZyYWdtZW50IG5hdmlnYXRpb24pXG4gICAgaWYgKGN1cnJMaW5rICYmIHBhdGhzLnNvbWUoKHApID0+IHAuZW5kc1dpdGgoY3VyckxpbmshLmhyZWYpKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gY2FsY3VsYXRlIGN1cnJlbnQsIHByZXZpb3VzIGFuZCBuZXh0IGxpbmtzXG5cbiAgICAvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80NDY3NTM5L2phdmFzY3JpcHQtbW9kdWxvLWdpdmVzLWEtbmVnYXRpdmUtcmVzdWx0LWZvci1uZWdhdGl2ZS1udW1iZXJzXG4gICAgY29uc3QgbW9kdWxvID0gKGE6IG51bWJlciwgbjogbnVtYmVyKSA9PiB7XG4gICAgICByZXR1cm4gKChhICUgbikgKyBuKSAlIG5cbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubGlua3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGxpbmsgPSB0aGlzLmxpbmtzW2ldXG4gICAgICBpZiAocGF0aHMuc29tZSgocGF0aCkgPT4gcGF0aC5lbmRzV2l0aChsaW5rLmhyZWYpKSkge1xuICAgICAgICBjb25zdCBwcmV2SW5kZXggPSBtb2R1bG8oaSAtIDEsIHRoaXMubGlua3MubGVuZ3RoKVxuICAgICAgICBjb25zdCBuZXh0SW5kZXggPSBtb2R1bG8oaSArIDEsIHRoaXMubGlua3MubGVuZ3RoKVxuICAgICAgICBjdXJyTGluayA9IGxpbmtcbiAgICAgICAgbmV4dExpbmsgPSB0aGlzLmxpbmtzW25leHRJbmRleF1cbiAgICAgICAgcHJldkxpbmsgPSB0aGlzLmxpbmtzW3ByZXZJbmRleF1cbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBuYXZpZ2F0ZSB0byBmaXJzdCBwYWdlIGlmIGN1cnJMaW5rIGlzIG5vdCBkZWZpbmVkXG4gICAgaWYgKCFjdXJyTGluaykge1xuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGVCeVVybChsaW5rc1swXS5ocmVmLCB7XG4gICAgICAgIHJlcGxhY2VVcmw6IHRydWUsXG4gICAgICB9KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gbmF2aWdhdGUgdG8gZmlyc3QgY2hpbGRyZW4gaWYgY3VyckxpbmsgZG9lc24ndCBoYXZlIGEgcmVuZGVyZXJcbiAgICBpZiAoIWN1cnJMaW5rLnJlbmRlcmVyICYmIGN1cnJMaW5rLmNoaWxkcmVuPy5sZW5ndGgpIHtcbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlQnlVcmwoY3VyckxpbmsuY2hpbGRyZW5bMF0uaHJlZiwge1xuICAgICAgICByZXBsYWNlVXJsOiB0cnVlLFxuICAgICAgfSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIGV4cGFuZCB2aXNpYmxlIGxpbmtzXG5cbiAgICB0aGlzLmxpbmtzLmZvckVhY2goKGxpbmspID0+IHtcbiAgICAgIGlmIChwYXRocy5zb21lKChwYXRoKSA9PiBwYXRoLmVuZHNXaXRoKGxpbmsuaHJlZikpKSB7XG4gICAgICAgIGxpbmsuZXhwYW5kZWQgPSB0cnVlXG4gICAgICB9XG4gICAgfSlcblxuICAgIC8vIG5vdGlmeSBzdGF0ZSBjaGFuZ2VcblxuICAgIHRoaXMuc3RhdGUubmV4dCh7XG4gICAgICBtZXRhLFxuICAgICAgbGlua3MsXG4gICAgICBwcmV2TGluayxcbiAgICAgIGN1cnJMaW5rLFxuICAgICAgbmV4dExpbmssXG4gICAgfSlcbiAgfVxuXG4gIHByaXZhdGUgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goKHMpID0+IHMudW5zdWJzY3JpYmUoKSlcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuc3BsaWNlKDAsIHRoaXMuc3Vic2NyaXB0aW9ucy5sZW5ndGgpXG4gICAgdGhpcy5wYWdlcy5jbGVhcigpXG4gICAgdGhpcy5saW5rcy5zcGxpY2UoMCwgdGhpcy5saW5rcy5sZW5ndGgpXG4gIH1cbn1cbiJdfQ==