@alauda-fe/common
Version:
Alauda frontend team common codes.
223 lines • 39.7 kB
JavaScript
/**
* @packageDocumentation
* @module k8s-resource-list
*/
import { EMPTY, Subject, merge, of, catchError, distinctUntilChanged, exhaustMap, filter, map, scan, startWith, switchMap, takeUntil, tap, finalize, ReplaySubject, } from 'rxjs';
import { WatchEvent } from '../api/types';
import { DOWNGRADE_WATCH_ENABLED, publishRef, } from '../core/public-api';
import { LoadAction, } from './types';
import { extractListParamsFromRoute, normalizeParams } from './utils';
export class K8SResourceList {
constructor({ fetcher, fetchParams$, activatedRoute, limit = 20, polling = 0, watcher, insertFn = defaultInsert, }) {
this.reloadAction$$ = new Subject();
this.loadMoreAction$$ = new Subject();
this.itemsScanner$$ = new Subject();
this.destroy$$ = new Subject();
this.bypassItems$ = new ReplaySubject(1);
this.snapshot = {};
this.insertFn = insertFn;
this.queryParams$ = (fetchParams$ ||
(activatedRoute
? extractListParamsFromRoute(activatedRoute)
: of(null))).pipe(publishRef());
const validPolling = (polling && watcher && DOWNGRADE_WATCH_ENABLED) || (polling && !watcher)
? polling
: 0;
this.loadState$ = this.buildLoadStateStream({
queryParams$: this.queryParams$,
fetcher,
limit,
polling: validPolling,
});
this.insertFn = insertFn;
this.initStreams(validPolling ? null : watcher);
}
reload(silent = false) {
this.reloadAction$$.next(silent);
}
loadMore() {
this.loadMoreAction$$.next();
}
scanItems(scanner) {
this.itemsScanner$$.next(scanner);
}
destroy() {
this.destroy$$.next();
this.destroy$$.complete();
}
create(resource) {
this.scanItems(this._create(resource));
}
update(resource) {
this.scanItems(this._update(resource));
}
delete(resource) {
if (!resource) {
return;
}
this.scanItems(this._delete(resource));
}
_create(resource) {
return (items) => {
if (!resource.metadata.name
.toLowerCase()
.includes(this.snapshot.queryParams?.keyword?.toLowerCase() ??
'')) {
return items;
}
return this.insertFn(items, resource, this.snapshot.hasMore);
};
}
_update(resource) {
return (items) => items.map(item => item.metadata.uid === resource.metadata.uid ? resource : item);
}
_delete({ metadata: { uid } }) {
return (items) => items.filter(item => item.metadata.uid !== uid);
}
buildLoadStateStream({ queryParams$, fetcher, polling, limit, }) {
const load$ = merge(queryParams$.pipe(map(queryParams => () => ({ queryParams, action: LoadAction.Reload }))), this.reloadAction$$.pipe(map(silent => (prev) => ({
...prev,
action: silent ? LoadAction.SilentReload : LoadAction.Reload,
})))).pipe(scan((acc, scanner) => scanner(acc), {}), tap(({ action, queryParams }) => {
if (action === LoadAction.Reload) {
this.snapshot = {
queryParams,
};
this.bypassItems$.next(null);
}
}));
return load$.pipe(switchMap(({ action: leadAction, queryParams }) => this.loadMoreAction$$.pipe(filter(() => this.snapshot.hasMore), map(() => true), startWith(false), exhaustMap(loadMore => {
if (this.timer) {
window.clearTimeout(this.timer);
}
const token = this.snapshot.continueToken;
const hasMore = this.snapshot.hasMore;
const currLength = this.snapshot.items?.length ?? limit;
const action = loadMore ? LoadAction.LoadMore : leadAction;
return fetcher(normalizeParams({
limit: `${action === LoadAction.SilentReload
? hasMore
? currLength
: 0
: limit}`,
continue: action === LoadAction.LoadMore ? token : '',
...queryParams,
})).pipe(map(rawResponse => ({ rawResponse, loadingError: null })), catchError((err) => of({
loadingError: action === LoadAction.SilentReload ? null : err,
})), tap(res => {
if (polling && !res.loadingError) {
this.timer = window.setTimeout(() => {
this.reload(true);
}, polling);
}
}), map(state => ({
...state,
action,
})), startWith({
action,
loading: true,
}));
}))), map(state => ({
action: LoadAction.LoadMore,
rawResponse: null,
loading: false,
loadingError: null,
...state,
})), tap(state => {
this.snapshot.rawResponse = state.rawResponse;
this.snapshot.loadingError = state.loadingError;
this.snapshot.loading =
state.loading && state.action !== LoadAction.SilentReload;
this.snapshot.continueToken = this.extractContinueTokenFromState(state);
this.snapshot.hasMore = !!this.snapshot.continueToken;
}), finalize(() => {
this.snapshot = {};
this.bypassItems$.next(null);
if (this.timer) {
window.clearTimeout(this.timer);
}
}), takeUntil(this.destroy$$), publishRef());
}
extractContinueTokenFromState({ rawResponse, loadingError, }) {
if (rawResponse) {
return rawResponse.metadata?.continue ?? '';
}
if (loadingError && 'code' in loadingError && loadingError.code === 410) {
return loadingError.metadata?.continue;
}
return this.snapshot.continueToken;
}
initStreams(watcher) {
this.rawResponse$ = this.loadState$.pipe(map(data => data.rawResponse), distinctUntilChanged(), publishRef());
this.loading$ = this.loadState$.pipe(map(({ loading, action }) => loading && action !== LoadAction.SilentReload), distinctUntilChanged(), publishRef());
this.loadingError$ = this.loadState$.pipe(map(state => state.loadingError), distinctUntilChanged(), publishRef());
this.continueToken$ = this.loadState$.pipe(filter(({ loading }) => !loading), switchMap(({ rawResponse, loadingError: err }) => {
if (rawResponse) {
return of(rawResponse.metadata?.continue ?? '');
}
if (err && 'code' in err && err.code === 410) {
return of(err.metadata?.continue);
}
return EMPTY;
}), distinctUntilChanged(), publishRef());
this.hasMore$ = this.continueToken$.pipe(map(token => !!token), distinctUntilChanged(), publishRef());
this.items$ = merge(this.loadState$.pipe(map(state => (items) => {
const newItems = state.rawResponse
? (state.rawResponse.items ?? [])
: null;
if (state.action === LoadAction.Reload) {
return newItems ?? [];
}
if (state.action === LoadAction.SilentReload) {
return newItems ?? items;
}
if (state.action === LoadAction.LoadMore) {
return newItems ? [...items, ...newItems] : items;
}
return items;
})), this.itemsScanner$$, watcher ? this.buildWatcher(watcher) : EMPTY).pipe(scan((acc, scanner) => scanner(acc), []), tap(items => {
this.snapshot.items = items;
this.bypassItems$.next(items);
}), takeUntil(this.destroy$$), publishRef());
}
buildWatcher(watcher) {
return this.rawResponse$.pipe(filter(res => !!res), distinctUntilChanged((a, b) => a.metadata?.resourceVersion === b.metadata?.resourceVersion), switchMap(list => watcher(list.metadata?.resourceVersion, this.snapshot.queryParams).pipe(catchError(() => {
this.reload(true);
return EMPTY;
}))), switchMap(({ type, object: resource }) => {
switch (type) {
case WatchEvent.Added: {
return of(this._create(resource));
}
case WatchEvent.Modified: {
return of(this._update(resource));
}
case WatchEvent.Deleted: {
return of(this._delete(resource));
}
default: {
return EMPTY;
}
}
}));
}
}
function defaultInsert(items, res, hasMore) {
for (let i = 0; i < items.length; i++) {
const compare = resourceCompare(res, items[i]);
if (compare === 0) {
return items.map((item, index) => (index === i ? res : item));
}
if (compare < 0) {
return [...items.slice(0, i), res, ...items.slice(i)];
}
}
return hasMore ? items : [...items, res];
}
function resourceCompare(a, b) {
const nsCompare = a.metadata.namespace?.localeCompare(b.metadata.namespace) ?? 0;
return nsCompare === 0
? a.metadata.name.localeCompare(b.metadata.name)
: nsCompare;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiazhzLXJlc291cmNlLWxpc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9zcmMvazhzLXJlc291cmNlLWxpc3QvazhzLXJlc291cmNlLWxpc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBR0gsT0FBTyxFQUNMLEtBQUssRUFFTCxPQUFPLEVBQ1AsS0FBSyxFQUNMLEVBQUUsRUFDRixVQUFVLEVBQ1Ysb0JBQW9CLEVBQ3BCLFVBQVUsRUFDVixNQUFNLEVBQ04sR0FBRyxFQUNILElBQUksRUFDSixTQUFTLEVBQ1QsU0FBUyxFQUNULFNBQVMsRUFDVCxHQUFHLEVBQ0gsUUFBUSxFQUNSLGFBQWEsR0FDZCxNQUFNLE1BQU0sQ0FBQztBQUVkLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDMUMsT0FBTyxFQUtMLHVCQUF1QixFQUN2QixVQUFVLEdBRVgsTUFBTSxvQkFBb0IsQ0FBQztBQUU1QixPQUFPLEVBTUwsVUFBVSxHQUtYLE1BQU0sU0FBUyxDQUFDO0FBQ2pCLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxlQUFlLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFdEUsTUFBTSxPQUFPLGVBQWU7SUE4QjFCLFlBQVksRUFDVixPQUFPLEVBQ1AsWUFBWSxFQUNaLGNBQWMsRUFDZCxLQUFLLEdBQUcsRUFBRSxFQUNWLE9BQU8sR0FBRyxDQUFDLEVBQ1gsT0FBTyxFQUNQLFFBQVEsR0FBRyxhQUFhLEdBQzZCO1FBaEN0QyxtQkFBYyxHQUFHLElBQUksT0FBTyxFQUFXLENBQUM7UUFDeEMscUJBQWdCLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUN2QyxtQkFBYyxHQUFHLElBQUksT0FBTyxFQUFtQixDQUFDO1FBQ2hELGNBQVMsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBWWpELGlCQUFZLEdBQUcsSUFBSSxhQUFhLENBQU0sQ0FBQyxDQUFDLENBQUM7UUFJ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UUFDL0MsSUFBSSxPQUFPLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDbEIsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDaEUsQ0FBQztRQUNELElBQUksT0FBTyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2hCLE9BQU8sQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4RCxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDM0MsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLENBQXFCLEVBQUUsQ0FBcUI7SUFDbkUsTUFBTSxTQUFTLEdBQ2IsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2pFLE9BQU8sU0FBUyxLQUFLLENBQUM7UUFDcEIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztRQUNoRCxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICogQG1vZHVsZSBrOHMtcmVzb3VyY2UtbGlzdFxuICovXG5cbmltcG9ydCB7IEh0dHBFcnJvclJlc3BvbnNlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHtcbiAgRU1QVFksXG4gIE9ic2VydmFibGUsXG4gIFN1YmplY3QsXG4gIG1lcmdlLFxuICBvZixcbiAgY2F0Y2hFcnJvcixcbiAgZGlzdGluY3RVbnRpbENoYW5nZWQsXG4gIGV4aGF1c3RNYXAsXG4gIGZpbHRlcixcbiAgbWFwLFxuICBzY2FuLFxuICBzdGFydFdpdGgsXG4gIHN3aXRjaE1hcCxcbiAgdGFrZVVudGlsLFxuICB0YXAsXG4gIGZpbmFsaXplLFxuICBSZXBsYXlTdWJqZWN0LFxufSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgV2F0Y2hFdmVudCB9IGZyb20gJy4uL2FwaS90eXBlcyc7XG5pbXBvcnQge1xuICBLdWJlcm5ldGVzUmVzb3VyY2UsXG4gIEt1YmVybmV0ZXNSZXNvdXJjZUxpc3QsXG4gIFJlc291cmNlTGlzdFBhcmFtcyxcbiAgU3RhdHVzLFxuICBET1dOR1JBREVfV0FUQ0hfRU5BQkxFRCxcbiAgcHVibGlzaFJlZixcbiAgU3RyaW5nTWFwLFxufSBmcm9tICcuLi9jb3JlL3B1YmxpYy1hcGknO1xuXG5pbXBvcnQge1xuICBDb25maWdXaXRoUGFyYW1zLFxuICBDb25maWdXaXRoUm91dGUsXG4gIEluc2VydEZuLFxuICBJdGVtc1NjYW5uZXIsXG4gIExpc3RQYXJhbXMsXG4gIExvYWRBY3Rpb24sXG4gIExvYWRTbmFwc2hvdCxcbiAgTG9hZFN0YXRlLFxuICBTdHJlYW1MaXN0TG9hZGVyLFxuICBXYXRjaGVyLFxufSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IGV4dHJhY3RMaXN0UGFyYW1zRnJvbVJvdXRlLCBub3JtYWxpemVQYXJhbXMgfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGNsYXNzIEs4U1Jlc291cmNlTGlzdDxcbiAgUiBleHRlbmRzIEt1YmVybmV0ZXNSZXNvdXJjZSA9IEt1YmVybmV0ZXNSZXNvdXJjZSxcbiAgUSBleHRlbmRzIG9iamVjdCA9IFJlc291cmNlTGlzdFBhcmFtcyxcbiAgUCBleHRlbmRzIFEgJiBMaXN0UGFyYW1zID0gUSAmIExpc3RQYXJhbXMsXG4+IGltcGxlbWVudHMgU3RyZWFtTGlzdExvYWRlcjxLdWJlcm5ldGVzUmVzb3VyY2VMaXN0PFI+LCBSPlxue1xuICBwcml2YXRlIHJlYWRvbmx5IHJlbG9hZEFjdGlvbiQkID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBsb2FkTW9yZUFjdGlvbiQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBpdGVtc1NjYW5uZXIkJCA9IG5ldyBTdWJqZWN0PEl0ZW1zU2Nhbm5lcjxSPj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95JCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGluc2VydEZuOiBJbnNlcnRGbjxSPjtcblxuICBsb2FkU3RhdGUkOiBPYnNlcnZhYmxlPExvYWRTdGF0ZTxLdWJlcm5ldGVzUmVzb3VyY2VMaXN0PFI+Pj47XG5cbiAgcXVlcnlQYXJhbXMkOiBPYnNlcnZhYmxlPFE+O1xuICByYXdSZXNwb25zZSQ6IE9ic2VydmFibGU8S3ViZXJuZXRlc1Jlc291cmNlTGlzdDxSPj47XG4gIGxvYWRpbmckOiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xuICBsb2FkaW5nRXJyb3IkOiBPYnNlcnZhYmxlPEh0dHBFcnJvclJlc3BvbnNlIHwgU3RhdHVzPjtcbiAgaGFzTW9yZSQ6IE9ic2VydmFibGU8Ym9vbGVhbj47XG4gIGNvbnRpbnVlVG9rZW4kOiBPYnNlcnZhYmxlPHN0cmluZz47XG4gIGl0ZW1zJDogT2JzZXJ2YWJsZTxSW10+O1xuICBieXBhc3NJdGVtcyQgPSBuZXcgUmVwbGF5U3ViamVjdDxSW10+KDEpO1xuXG4gIHRpbWVyOiBudW1iZXI7XG5cbiAgc25hcHNob3Q6IExvYWRTbmFwc2hvdDxLdWJlcm5ldGVzUmVzb3VyY2VMaXN0PFI+LCBSLCBRPiA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKHsgZmV0Y2hlciwgYWN0aXZhdGVkUm91dGUgfTogQ29uZmlnV2l0aFJvdXRlPFIsIFEsIFA+KTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC91bmlmaWVkLXNpZ25hdHVyZXNcbiAgY29uc3RydWN0b3IoeyBmZXRjaGVyLCBmZXRjaFBhcmFtcyQgfTogQ29uZmlnV2l0aFBhcmFtczxSLCBRLCBQPik7XG4gIGNvbnN0cnVjdG9yKHtcbiAgICBmZXRjaGVyLFxuICAgIGZldGNoUGFyYW1zJCxcbiAgICBhY3RpdmF0ZWRSb3V0ZSxcbiAgICBsaW1pdCA9IDIwLFxuICAgIHBvbGxpbmcgPSAwLFxuICAgIHdhdGNoZXIsXG4gICAgaW5zZXJ0Rm4gPSBkZWZhdWx0SW5zZXJ0LFxuICB9OiBDb25maWdXaXRoUm91dGU8UiwgUSwgUD4gJiBDb25maWdXaXRoUGFyYW1zPFIsIFEsIFA+KSB7XG4gICAgdGhpcy5pbnNlcnRGbiA9IGluc2VydEZuO1xuXG4gICAgdGhpcy5xdWVyeVBhcmFtcyQgPSAoXG4gICAgICAoZmV0Y2hQYXJhbXMkIHx8XG4gICAgICAgIChhY3RpdmF0ZWRSb3V0ZVxuICAgICAgICAgID8gZXh0cmFjdExpc3RQYXJhbXNGcm9tUm91dGUoYWN0aXZhdGVkUm91dGUpXG4gICAgICAgICAgOiBvZihudWxsKSkpIGFzIE9ic2VydmFibGU8UT5cbiAgICApLnBpcGUocHVibGlzaFJlZigpKTtcblxuICAgIGNvbnN0IHZhbGlkUG9sbGluZyA9XG4gICAgICAocG9sbGluZyAmJiB3YXRjaGVyICYmIERPV05HUkFERV9XQVRDSF9FTkFCTEVEKSB8fCAocG9sbGluZyAmJiAhd2F0Y2hlcilcbiAgICAgICAgPyBwb2xsaW5nXG4gICAgICAgIDogMDtcblxuICAgIHRoaXMubG9hZFN0YXRlJCA9IHRoaXMuYnVpbGRMb2FkU3RhdGVTdHJlYW0oe1xuICAgICAgcXVlcnlQYXJhbXMkOiB0aGlzLnF1ZXJ5UGFyYW1zJCxcbiAgICAgIGZldGNoZXIsXG4gICAgICBsaW1pdCxcbiAgICAgIHBvbGxpbmc6IHZhbGlkUG9sbGluZyxcbiAgICB9KTtcblxuICAgIHRoaXMuaW5zZXJ0Rm4gPSBpbnNlcnRGbjtcblxuICAgIHRoaXMuaW5pdFN0cmVhbXModmFsaWRQb2xsaW5nID8gbnVsbCA6IHdhdGNoZXIpO1xuICB9XG5cbiAgcmVsb2FkKHNpbGVudCA9IGZhbHNlKSB7XG4gICAgdGhpcy5yZWxvYWRBY3Rpb24kJC5uZXh0KHNpbGVudCk7XG4gIH1cblxuICBsb2FkTW9yZSgpIHtcbiAgICB0aGlzLmxvYWRNb3JlQWN0aW9uJCQubmV4dCgpO1xuICB9XG5cbiAgc2Nhbkl0ZW1zKHNjYW5uZXI6IEl0ZW1zU2Nhbm5lcjxSPikge1xuICAgIHRoaXMuaXRlbXNTY2FubmVyJCQubmV4dChzY2FubmVyKTtcbiAgfVxuXG4gIGRlc3Ryb3koKSB7XG4gICAgdGhpcy5kZXN0cm95JCQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveSQkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBjcmVhdGUocmVzb3VyY2U6IFIpIHtcbiAgICB0aGlzLnNjYW5JdGVtcyh0aGlzLl9jcmVhdGUocmVzb3VyY2UpKTtcbiAgfVxuXG4gIHVwZGF0ZShyZXNvdXJjZTogUikge1xuICAgIHRoaXMuc2Nhbkl0ZW1zKHRoaXMuX3VwZGF0ZShyZXNvdXJjZSkpO1xuICB9XG5cbiAgZGVsZXRlKHJlc291cmNlPzogUikge1xuICAgIGlmICghcmVzb3VyY2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zY2FuSXRlbXModGhpcy5fZGVsZXRlKHJlc291cmNlKSk7XG4gIH1cblxuICBwcml2YXRlIF9jcmVhdGUocmVzb3VyY2U6IFIpIHtcbiAgICByZXR1cm4gKGl0ZW1zOiBSW10pID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgIXJlc291cmNlLm1ldGFkYXRhLm5hbWVcbiAgICAgICAgICAudG9Mb3dlckNhc2UoKVxuICAgICAgICAgIC5pbmNsdWRlcyhcbiAgICAgICAgICAgICh0aGlzLnNuYXBzaG90LnF1ZXJ5UGFyYW1zIGFzIFN0cmluZ01hcCk/LmtleXdvcmQ/LnRvTG93ZXJDYXNlKCkgPz9cbiAgICAgICAgICAgICAgJycsXG4gICAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBpdGVtcztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmluc2VydEZuKGl0ZW1zLCByZXNvdXJjZSwgdGhpcy5zbmFwc2hvdC5oYXNNb3JlKTtcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBfdXBkYXRlKHJlc291cmNlOiBSKSB7XG4gICAgcmV0dXJuIChpdGVtczogUltdKSA9PlxuICAgICAgaXRlbXMubWFwKGl0ZW0gPT5cbiAgICAgICAgaXRlbS5tZXRhZGF0YS51aWQgPT09IHJlc291cmNlLm1ldGFkYXRhLnVpZCA/IHJlc291cmNlIDogaXRlbSxcbiAgICAgICk7XG4gIH1cblxuICBwcml2YXRlIF9kZWxldGUoeyBtZXRhZGF0YTogeyB1aWQgfSB9OiBSKSB7XG4gICAgcmV0dXJuIChpdGVtczogUltdKSA9PiBpdGVtcy5maWx0ZXIoaXRlbSA9PiBpdGVtLm1ldGFkYXRhLnVpZCAhPT0gdWlkKTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRMb2FkU3RhdGVTdHJlYW0oe1xuICAgIHF1ZXJ5UGFyYW1zJCxcbiAgICBmZXRjaGVyLFxuICAgIHBvbGxpbmcsXG4gICAgbGltaXQsXG4gIH06IHtcbiAgICBxdWVyeVBhcmFtcyQ6IE9ic2VydmFibGU8UT47XG4gICAgZmV0Y2hlcjogKHA6IFApID0+IE9ic2VydmFibGU8S3ViZXJuZXRlc1Jlc291cmNlTGlzdDxSPj47XG4gICAgcG9sbGluZzogbnVtYmVyO1xuICAgIGxpbWl0OiBudW1iZXI7XG4gIH0pIHtcbiAgICBjb25zdCBsb2FkJCA9IG1lcmdlKFxuICAgICAgcXVlcnlQYXJhbXMkLnBpcGUoXG4gICAgICAgIG1hcChxdWVyeVBhcmFtcyA9PiAoKSA9PiAoeyBxdWVyeVBhcmFtcywgYWN0aW9uOiBMb2FkQWN0aW9uLlJlbG9hZCB9KSksXG4gICAgICApLFxuICAgICAgdGhpcy5yZWxvYWRBY3Rpb24kJC5waXBlKFxuICAgICAgICBtYXAoc2lsZW50ID0+IChwcmV2OiB7IHF1ZXJ5UGFyYW1zPzogUDsgYWN0aW9uPzogTG9hZEFjdGlvbiB9KSA9PiAoe1xuICAgICAgICAgIC4uLnByZXYsXG4gICAgICAgICAgYWN0aW9uOiBzaWxlbnQgPyBMb2FkQWN0aW9uLlNpbGVudFJlbG9hZCA6IExvYWRBY3Rpb24uUmVsb2FkLFxuICAgICAgICB9KSksXG4gICAgICApLFxuICAgICkucGlwZShcbiAgICAgIHNjYW4oXG4gICAgICAgIChhY2MsIHNjYW5uZXIpID0+IHNjYW5uZXIoYWNjKSxcbiAgICAgICAge30gYXMgeyBxdWVyeVBhcmFtcz86IFA7IGFjdGlvbj86IExvYWRBY3Rpb24gfSxcbiAgICAgICksXG4gICAgICB0YXAoKHsgYWN0aW9uLCBxdWVyeVBhcmFtcyB9KSA9PiB7XG4gICAgICAgIGlmIChhY3Rpb24gPT09IExvYWRBY3Rpb24uUmVsb2FkKSB7XG4gICAgICAgICAgdGhpcy5zbmFwc2hvdCA9IHtcbiAgICAgICAgICAgIHF1ZXJ5UGFyYW1zLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdGhpcy5ieXBhc3NJdGVtcyQubmV4dChudWxsKTtcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgKTtcblxuICAgIHJldHVybiBsb2FkJC5waXBlKFxuICAgICAgc3dpdGNoTWFwKCh7IGFjdGlvbjogbGVhZEFjdGlvbiwgcXVlcnlQYXJhbXMgfSkgPT5cbiAgICAgICAgdGhpcy5sb2FkTW9yZUFjdGlvbiQkLnBpcGUoXG4gICAgICAgICAgZmlsdGVyKCgpID0+IHRoaXMuc25hcHNob3QuaGFzTW9yZSksXG4gICAgICAgICAgbWFwKCgpID0+IHRydWUpLFxuICAgICAgICAgIHN0YXJ0V2l0aChmYWxzZSksXG4gICAgICAgICAgZXhoYXVzdE1hcChsb2FkTW9yZSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy50aW1lcikge1xuICAgICAgICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgdG9rZW4gPSB0aGlzLnNuYXBzaG90LmNvbnRpbnVlVG9rZW47XG4gICAgICAgICAgICBjb25zdCBoYXNNb3JlID0gdGhpcy5zbmFwc2hvdC5oYXNNb3JlO1xuICAgICAgICAgICAgY29uc3QgY3Vyckxlbmd0aCA9IHRoaXMuc25hcHNob3QuaXRlbXM/Lmxlbmd0aCA/PyBsaW1pdDtcbiAgICAgICAgICAgIGNvbnN0IGFjdGlvbiA9IGxvYWRNb3JlID8gTG9hZEFjdGlvbi5Mb2FkTW9yZSA6IGxlYWRBY3Rpb247XG4gICAgICAgICAgICByZXR1cm4gZmV0Y2hlcihcbiAgICAgICAgICAgICAgbm9ybWFsaXplUGFyYW1zKHtcbiAgICAgICAgICAgICAgICBsaW1pdDogYCR7XG4gICAgICAgICAgICAgICAgICBhY3Rpb24gPT09IExvYWRBY3Rpb24uU2lsZW50UmVsb2FkXG4gICAgICAgICAgICAgICAgICAgID8gaGFzTW9yZVxuICAgICAgICAgICAgICAgICAgICAgID8gY3Vyckxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgIDogMFxuICAgICAgICAgICAgICAgICAgICA6IGxpbWl0XG4gICAgICAgICAgICAgICAgfWAsXG4gICAgICAgICAgICAgICAgY29udGludWU6IGFjdGlvbiA9PT0gTG9hZEFjdGlvbi5Mb2FkTW9yZSA/IHRva2VuIDogJycsXG4gICAgICAgICAgICAgICAgLi4ucXVlcnlQYXJhbXMsXG4gICAgICAgICAgICAgIH0pIGFzIFAsXG4gICAgICAgICAgICApLnBpcGUoXG4gICAgICAgICAgICAgIG1hcChyYXdSZXNwb25zZSA9PiAoeyByYXdSZXNwb25zZSwgbG9hZGluZ0Vycm9yOiBudWxsIH0pKSxcbiAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoZXJyOiBTdGF0dXMgfCBIdHRwRXJyb3JSZXNwb25zZSkgPT5cbiAgICAgICAgICAgICAgICBvZih7XG4gICAgICAgICAgICAgICAgICBsb2FkaW5nRXJyb3I6IGFjdGlvbiA9PT0gTG9hZEFjdGlvbi5TaWxlbnRSZWxvYWQgPyBudWxsIDogZXJyLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICB0YXAocmVzID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocG9sbGluZyAmJiAhcmVzLmxvYWRpbmdFcnJvcikge1xuICAgICAgICAgICAgICAgICAgdGhpcy50aW1lciA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWxvYWQodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICB9LCBwb2xsaW5nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBtYXAoc3RhdGUgPT4gKHtcbiAgICAgICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgICAgICBhY3Rpb24sXG4gICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgICAgc3RhcnRXaXRoKHtcbiAgICAgICAgICAgICAgICBhY3Rpb24sXG4gICAgICAgICAgICAgICAgbG9hZGluZzogdHJ1ZSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICAgIG1hcChzdGF0ZSA9PiAoe1xuICAgICAgICBhY3Rpb246IExvYWRBY3Rpb24uTG9hZE1vcmUsXG4gICAgICAgIHJhd1Jlc3BvbnNlOiBudWxsLFxuICAgICAgICBsb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgbG9hZGluZ0Vycm9yOiBudWxsLFxuICAgICAgICAuLi5zdGF0ZSxcbiAgICAgIH0pKSxcbiAgICAgIHRhcChzdGF0ZSA9PiB7XG4gICAgICAgIHRoaXMuc25hcHNob3QucmF3UmVzcG9uc2UgPSBzdGF0ZS5yYXdSZXNwb25zZTtcbiAgICAgICAgdGhpcy5zbmFwc2hvdC5sb2FkaW5nRXJyb3IgPSBzdGF0ZS5sb2FkaW5nRXJyb3I7XG4gICAgICAgIHRoaXMuc25hcHNob3QubG9hZGluZyA9XG4gICAgICAgICAgc3RhdGUubG9hZGluZyAmJiBzdGF0ZS5hY3Rpb24gIT09IExvYWRBY3Rpb24uU2lsZW50UmVsb2FkO1xuICAgICAgICB0aGlzLnNuYXBzaG90LmNvbnRpbnVlVG9rZW4gPSB0aGlzLmV4dHJhY3RDb250aW51ZVRva2VuRnJvbVN0YXRlKHN0YXRlKTtcbiAgICAgICAgdGhpcy5zbmFwc2hvdC5oYXNNb3JlID0gISF0aGlzLnNuYXBzaG90LmNvbnRpbnVlVG9rZW47XG4gICAgICB9KSxcbiAgICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgICAgdGhpcy5zbmFwc2hvdCA9IHt9O1xuICAgICAgICB0aGlzLmJ5cGFzc0l0ZW1zJC5uZXh0KG51bGwpO1xuICAgICAgICBpZiAodGhpcy50aW1lcikge1xuICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy50aW1lcik7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQkKSxcbiAgICAgIHB1Ymxpc2hSZWYoKSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0Q29udGludWVUb2tlbkZyb21TdGF0ZSh7XG4gICAgcmF3UmVzcG9uc2UsXG4gICAgbG9hZGluZ0Vycm9yLFxuICB9OiBMb2FkU3RhdGU8S3ViZXJuZXRlc1Jlc291cmNlTGlzdDxSPj4pIHtcbiAgICBpZiAocmF3UmVzcG9uc2UpIHtcbiAgICAgIHJldHVybiByYXdSZXNwb25zZS5tZXRhZGF0YT8uY29udGludWUgPz8gJyc7XG4gICAgfVxuXG4gICAgaWYgKGxvYWRpbmdFcnJvciAmJiAnY29kZScgaW4gbG9hZGluZ0Vycm9yICYmIGxvYWRpbmdFcnJvci5jb2RlID09PSA0MTApIHtcbiAgICAgIHJldHVybiBsb2FkaW5nRXJyb3IubWV0YWRhdGE/LmNvbnRpbnVlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnNuYXBzaG90LmNvbnRpbnVlVG9rZW47XG4gIH1cblxuICBwcml2YXRlIGluaXRTdHJlYW1zKHdhdGNoZXI6IFdhdGNoZXI8UiwgUT4pIHtcbiAgICB0aGlzLnJhd1Jlc3BvbnNlJCA9IHRoaXMubG9hZFN0YXRlJC5waXBlKFxuICAgICAgbWFwKGRhdGEgPT4gZGF0YS5yYXdSZXNwb25zZSksXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgcHVibGlzaFJlZigpLFxuICAgICk7XG5cbiAgICB0aGlzLmxvYWRpbmckID0gdGhpcy5sb2FkU3RhdGUkLnBpcGUoXG4gICAgICBtYXAoXG4gICAgICAgICh7IGxvYWRpbmcsIGFjdGlvbiB9KSA9PiBsb2FkaW5nICYmIGFjdGlvbiAhPT0gTG9hZEFjdGlvbi5TaWxlbnRSZWxvYWQsXG4gICAgICApLFxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgIHB1Ymxpc2hSZWYoKSxcbiAgICApO1xuXG4gICAgdGhpcy5sb2FkaW5nRXJyb3IkID0gdGhpcy5sb2FkU3RhdGUkLnBpcGUoXG4gICAgICBtYXAoc3RhdGUgPT4gc3RhdGUubG9hZGluZ0Vycm9yKSxcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICBwdWJsaXNoUmVmKCksXG4gICAgKTtcblxuICAgIHRoaXMuY29udGludWVUb2tlbiQgPSB0aGlzLmxvYWRTdGF0ZSQucGlwZShcbiAgICAgIGZpbHRlcigoeyBsb2FkaW5nIH0pID0+ICFsb2FkaW5nKSxcbiAgICAgIHN3aXRjaE1hcCgoeyByYXdSZXNwb25zZSwgbG9hZGluZ0Vycm9yOiBlcnIgfSkgPT4ge1xuICAgICAgICBpZiAocmF3UmVzcG9uc2UpIHtcbiAgICAgICAgICByZXR1cm4gb2YocmF3UmVzcG9uc2UubWV0YWRhdGE/LmNvbnRpbnVlID8/ICcnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXJyICYmICdjb2RlJyBpbiBlcnIgJiYgZXJyLmNvZGUgPT09IDQxMCkge1xuICAgICAgICAgIHJldHVybiBvZihlcnIubWV0YWRhdGE/LmNvbnRpbnVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gRU1QVFk7XG4gICAgICB9KSxcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICBwdWJsaXNoUmVmKCksXG4gICAgKTtcblxuICAgIHRoaXMuaGFzTW9yZSQgPSB0aGlzLmNvbnRpbnVlVG9rZW4kLnBpcGUoXG4gICAgICBtYXAodG9rZW4gPT4gISF0b2tlbiksXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgcHVibGlzaFJlZigpLFxuICAgICk7XG5cbiAgICB0aGlzLml0ZW1zJCA9IG1lcmdlKFxuICAgICAgdGhpcy5sb2FkU3RhdGUkLnBpcGUoXG4gICAgICAgIG1hcChzdGF0ZSA9PiAoaXRlbXM6IFJbXSkgPT4ge1xuICAgICAgICAgIGNvbnN0IG5ld0l0ZW1zID0gc3RhdGUucmF3UmVzcG9uc2VcbiAgICAgICAgICAgID8gKHN0YXRlLnJhd1Jlc3BvbnNlLml0ZW1zID8/IFtdKVxuICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgIGlmIChzdGF0ZS5hY3Rpb24gPT09IExvYWRBY3Rpb24uUmVsb2FkKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3SXRlbXMgPz8gW107XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzdGF0ZS5hY3Rpb24gPT09IExvYWRBY3Rpb24uU2lsZW50UmVsb2FkKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3SXRlbXMgPz8gaXRlbXM7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzdGF0ZS5hY3Rpb24gPT09IExvYWRBY3Rpb24uTG9hZE1vcmUpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXdJdGVtcyA/IFsuLi5pdGVtcywgLi4ubmV3SXRlbXNdIDogaXRlbXM7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBpdGVtcztcbiAgICAgICAgfSksXG4gICAgICApLFxuICAgICAgdGhpcy5pdGVtc1NjYW5uZXIkJCxcbiAgICAgIHdhdGNoZXIgPyB0aGlzLmJ1aWxkV2F0Y2hlcih3YXRjaGVyKSA6IEVNUFRZLFxuICAgICkucGlwZShcbiAgICAgIHNjYW48SXRlbXNTY2FubmVyPFI+LCBSW10+KChhY2MsIHNjYW5uZXIpID0+IHNjYW5uZXIoYWNjKSwgW10pLFxuICAgICAgdGFwKGl0ZW1zID0+IHtcbiAgICAgICAgdGhpcy5zbmFwc2hvdC5pdGVtcyA9IGl0ZW1zO1xuICAgICAgICB0aGlzLmJ5cGFzc0l0ZW1zJC5uZXh0KGl0ZW1zKTtcbiAgICAgIH0pLFxuICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQkKSxcbiAgICAgIHB1Ymxpc2hSZWYoKSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFdhdGNoZXIod2F0Y2hlcjogV2F0Y2hlcjxSLCBRPikge1xuICAgIHJldHVybiB0aGlzLnJhd1Jlc3BvbnNlJC5waXBlKFxuICAgICAgZmlsdGVyKHJlcyA9PiAhIXJlcyksXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZChcbiAgICAgICAgKGEsIGIpID0+IGEubWV0YWRhdGE/LnJlc291cmNlVmVyc2lvbiA9PT0gYi5tZXRhZGF0YT8ucmVzb3VyY2VWZXJzaW9uLFxuICAgICAgKSxcbiAgICAgIHN3aXRjaE1hcChsaXN0ID0+XG4gICAgICAgIHdhdGNoZXIobGlzdC5tZXRhZGF0YT8ucmVzb3VyY2VWZXJzaW9uLCB0aGlzLnNuYXBzaG90LnF1ZXJ5UGFyYW1zKS5waXBlKFxuICAgICAgICAgIGNhdGNoRXJyb3IoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZWxvYWQodHJ1ZSk7XG4gICAgICAgICAgICByZXR1cm4gRU1QVFk7XG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICApLFxuICAgICAgc3dpdGNoTWFwKCh7IHR5cGUsIG9iamVjdDogcmVzb3VyY2UgfSkgPT4ge1xuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICBjYXNlIFdhdGNoRXZlbnQuQWRkZWQ6IHtcbiAgICAgICAgICAgIHJldHVybiBvZih0aGlzLl9jcmVhdGUocmVzb3VyY2UpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSBXYXRjaEV2ZW50Lk1vZGlmaWVkOiB7XG4gICAgICAgICAgICByZXR1cm4gb2YodGhpcy5fdXBkYXRlKHJlc291cmNlKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgV2F0Y2hFdmVudC5EZWxldGVkOiB7XG4gICAgICAgICAgICByZXR1cm4gb2YodGhpcy5fZGVsZXRlKHJlc291cmNlKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgIHJldHVybiBFTVBUWTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVmYXVsdEluc2VydDxUIGV4dGVuZHMgS3ViZXJuZXRlc1Jlc291cmNlPihcbiAgaXRlbXM6IFRbXSxcbiAgcmVzOiBULFxuICBoYXNNb3JlOiBib29sZWFuLFxuKSB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjb21wYXJlID0gcmVzb3VyY2VDb21wYXJlKHJlcywgaXRlbXNbaV0pO1xuICAgIGlmIChjb21wYXJlID09PSAwKSB7XG4gICAgICByZXR1cm4gaXRlbXMubWFwKChpdGVtLCBpbmRleCkgPT4gKGluZGV4ID09PSBpID8gcmVzIDogaXRlbSkpO1xuICAgIH1cbiAgICBpZiAoY29tcGFyZSA8IDApIHtcbiAgICAgIHJldHVybiBbLi4uaXRlbXMuc2xpY2UoMCwgaSksIHJlcywgLi4uaXRlbXMuc2xpY2UoaSldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBoYXNNb3JlID8gaXRlbXMgOiBbLi4uaXRlbXMsIHJlc107XG59XG5cbmZ1bmN0aW9uIHJlc291cmNlQ29tcGFyZShhOiBLdWJlcm5ldGVzUmVzb3VyY2UsIGI6IEt1YmVybmV0ZXNSZXNvdXJjZSkge1xuICBjb25zdCBuc0NvbXBhcmUgPVxuICAgIGEubWV0YWRhdGEubmFtZXNwYWNlPy5sb2NhbGVDb21wYXJlKGIubWV0YWRhdGEubmFtZXNwYWNlKSA/PyAwO1xuICByZXR1cm4gbnNDb21wYXJlID09PSAwXG4gICAgPyBhLm1ldGFkYXRhLm5hbWUubG9jYWxlQ29tcGFyZShiLm1ldGFkYXRhLm5hbWUpXG4gICAgOiBuc0NvbXBhcmU7XG59XG4iXX0=