UNPKG

@alauda-fe/common

Version:

Alauda frontend team common codes.

282 lines 40 kB
import { MessageService, MessageType as Type, NotificationService, } from '@alauda/ui'; import { Injectable } from '@angular/core'; import { get } from 'lodash-es'; import { Subject, of, map, switchMap, takeUntil, tap } from 'rxjs'; import { K8sApiService } from '../../../api/k8s-api.service'; import { WatchEvent } from '../../../api/types'; import { AuthorizationStateService } from '../../../authorization/state.service'; import { K8sUtilService } from '../../../core/public-api'; import { K8SResourceList } from '../../../k8s-resource-list/k8s-resource-list'; import { MESSAGE_CONFIG, MessageType, NOTIFY_INFO_TYPE, NOTIFY_NOT_FIXED, NOTIFY_PUSH_TYPE, dateValueOf, } from './utils'; import * as i0 from "@angular/core"; import * as i1 from "../../../api/k8s-api.service"; import * as i2 from "../../../authorization/state.service"; import * as i3 from "../../../core/public-api"; import * as i4 from "@alauda/ui"; const NOTIFY_TYPE_MAP = { [MessageType.WarningMessage]: Type.Error, [MessageType.SystemMessage]: Type.Info, [MessageType.ProductMessage]: Type.Success, [MessageType.PlatformAnnouncement]: '', }; export class NotifyService { constructor(k8sApi, auth, k8sUtil, notification, messages) { this.k8sApi = k8sApi; this.auth = auth; this.k8sUtil = k8sUtil; this.notification = notification; this.messages = messages; this.triggerNotify$ = new Subject(); this.pushEnabled = true; this.auiNotificationList = []; this.windowUnload = false; this.onDestroy$ = new Subject(); this.userName$ = this.auth.getTokenPayload().pipe(takeUntil(this.onDestroy$), map(account => account.email || account.name), tap(name => { this.userName = name; this.settingDefaultPushStatus(); })); // 这个版本没有自动发送的消息,用户手册没有办法描述这部分功能, 先注释 // 因占用并发数,后续如产品需要重新加入此功能,可以和产品讨论下是否可以阉割此功能 // watchConfigMap$ = this.k8sApi // .watchGlobalResource({ // definition: { // type: 'configmaps', // }, // namespaced: true, // name: 'message-config', // }) // .pipe( // takeUntil(this.onDestroy$), // catchError(() => of(null)), // map(() => { // return this.pushEnabled; // }), // ); // watchMessageConfigMap$ = this.watchConfigMap$.pipe( // switchMap(res => // this.userName$.pipe( // map(() => { // return res; // }), // ), // ), // ); this.list = new K8SResourceList({ fetchParams$: of({}), // 使用空参数否则路由参数变化会导致重新触发 get list fetcher: this.fetcher.bind(this), watcher: seed => this.k8sApi .watchGlobalResourceChange(seed, { definition: MESSAGE_CONFIG, }) .pipe(tap(item => { const cacheInfo = this.getCacheLocalValue(NOTIFY_INFO_TYPE); const infoValue = cacheInfo?.split(',') || []; this.removePush(item); if ([WatchEvent.Added, WatchEvent.Modified].includes(item.type) && !infoValue.includes(this.k8sUtil.getName(item.object))) { this.dispatchNotify(item.object); const value = [...infoValue, this.k8sUtil.getName(item.object)]; this.cacheNotifyInfo(value.join(',')); } })), polling: 10_000, }); } watchNotify() { this.triggerNotify$.pipe(takeUntil(this.onDestroy$)).subscribe(res => { this.notifyMessage(res); }); } getNotifyList() { return this.list.items$.pipe(takeUntil(this.onDestroy$), switchMap(res => this.userName$.pipe(map(() => res))), map(res => this.messageSort(res, 'desc'))); } messageSort(data, type = 'asc') { return data.sort((a, b) => { const start = type === 'asc' ? a.metadata.creationTimestamp : b.metadata.creationTimestamp; const end = type === 'asc' ? b.metadata.creationTimestamp : a.metadata.creationTimestamp; return dateValueOf(start) - dateValueOf(end); }); } fetcher() { return this.k8sApi .getGlobalResourceList({ definition: MESSAGE_CONFIG, }) .pipe(tap(res => { this.handleNotify(res.items); })); } handleNotify(data) { const cacheInfo = this.getCacheLocalValue(NOTIFY_INFO_TYPE); const infoValue = cacheInfo?.split(',') || []; const messages = this.messageSort(data, 'desc').reduce((acc, item) => { const { isResident } = item.spec; if (isResident && !this.expired(item) && !infoValue.includes(this.k8sUtil.getName(item))) { const pre = acc ? `${acc},` : ''; this.dispatchNotify(item); // 触发提示消息 return `${pre}${this.k8sUtil.getName(item)}`; } return acc; }, ''); if (messages) { this.cacheNotifyInfo(messages); } } cacheNotifyInfo(values) { this.addCacheLocalValue(NOTIFY_INFO_TYPE, values); } dispatchNotify(data) { const notFixed = this.getCacheLocalValue(NOTIFY_NOT_FIXED); const pass = !notFixed?.split(',')?.includes(this.k8sUtil.getName(data)); const push = this.getCacheLocalValue(NOTIFY_PUSH_TYPE); if (((!data.spec.isResident && this.pushEnabled && push) || !this.expired(data)) && pass) { this.triggerNotify$.next(data); } } expired(item) { const expiredTimestamp = item.spec.expiredTimestamp; if (!expiredTimestamp) { return true; } return new Date(expiredTimestamp).valueOf() < Date.now(); } getCacheLocalValue(type) { const value = window.localStorage.getItem(type); return value && JSON.parse(value)[this.userName]; } addCacheLocalValue(type, value) { const preValue = window.localStorage.getItem(type); window.localStorage.setItem(type, JSON.stringify({ ...(preValue ? JSON.parse(preValue) : {}), [this.userName]: value, })); } notifyMessage(data) { const { isResident, subject, content } = data.spec; const name = this.k8sUtil.getName(data); const type = this.getMessageType(data); if (isResident) { const notificationRef = this.notification.create({ type: type || Type.Info, title: subject, ...(type ? {} : { customClass: 'platform-class' }), content, ...(isResident ? { duration: 0 } : {}), }); this.auiNotificationList.push(notificationRef); Object.assign(notificationRef.instance, { data }); notificationRef.instance.afterClosed.subscribe(() => { this.closedNotifyCallback(data, name, get(notificationRef.instance, 'windowUnload', false)); }); return; } this.messages.create({ type: type || Type.Info, content: subject, }); } /** * 关闭通知: 手动关闭存储 添加不再展示状态记录 * 关闭页面、删除消息 不记录 */ closedNotifyCallback(data, name, windowUnload) { this.removeNotificationList(name); if (!this.windowUnload && !windowUnload) { this.addNotFixed(data); } this.windowUnload = false; } /** * 记录 不再展示状态 存储在 local storage */ addNotFixed(data) { if (data.spec.isResident) { const notFixedVal = this.getCacheLocalValue(NOTIFY_NOT_FIXED); const value = [ ...(notFixedVal?.split(',') || []), this.k8sUtil.getName(data), ]; this.addCacheLocalValue(NOTIFY_NOT_FIXED, value.join(',')); } this.windowUnload = false; } /** * 触发删除消息 * - 删除 local storage NOT_FIXED 存储的消息 * - 手动触发关闭常驻通知弹框 */ removePush(item) { const name = this.k8sUtil.getName(item.object); const notFixedVal = this.getCacheLocalValue(NOTIFY_NOT_FIXED)?.split(',') || []; if (WatchEvent.Deleted === item.type) { this.removeMessage(name); this.manualCloseNotify(name); } if (WatchEvent.Deleted === item.type && item.object.spec.isResident && !notFixedVal.includes(name)) { this.manualCloseNotify(name); } } removeMessage(name) { const cacheNotFixed = this.getCacheLocalValue(NOTIFY_NOT_FIXED)?.split(',') || []; if (cacheNotFixed.length > 0) { const index = cacheNotFixed.indexOf(name); if (index !== -1) { cacheNotFixed.splice(index, 1); this.addCacheLocalValue(NOTIFY_NOT_FIXED, cacheNotFixed.join(',')); } } } manualCloseNotify(name) { const notifyInstance = this.auiNotificationList.find(item => this.k8sUtil.getName(get(item.instance, 'data')) === name); if (notifyInstance) { this.windowUnload = true; notifyInstance.instance.close(); } } removeNotificationList(name) { this.auiNotificationList = this.auiNotificationList.filter(item => this.k8sUtil.getName(get(item.instance, 'data')) !== name); } getMessageType(data) { const type = this.k8sUtil.getLabel(data, 'type'); return NOTIFY_TYPE_MAP[type]; } settingDefaultPushStatus() { if (!window.localStorage.getItem(NOTIFY_PUSH_TYPE)) { this.addCacheLocalValue(NOTIFY_PUSH_TYPE, true); } } closeAllNotification() { for (const notify of this.auiNotificationList) { // 将 windowUnload 存储 instance 在 afterClosed 进行判断 // remove 异步 循环中 windowUnload 值已发生改变但还未触发 afterClosed 回调 Object.assign(notify.instance, { windowUnload: true }); notify.instance.close(); } this.auiNotificationList = []; } destroy() { // 重新加载 header 关闭所有通知,重新加载 header 重新弹出 this.closeAllNotification(); window.localStorage.removeItem(NOTIFY_INFO_TYPE); this.onDestroy$.next(); } static { this.ɵfac = function NotifyService_Factory(t) { return new (t || NotifyService)(i0.ɵɵinject(i1.K8sApiService), i0.ɵɵinject(i2.AuthorizationStateService), i0.ɵɵinject(i3.K8sUtilService), i0.ɵɵinject(i4.NotificationService), i0.ɵɵinject(i4.MessageService)); }; } static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: NotifyService, factory: NotifyService.ɵfac, providedIn: 'root' }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NotifyService, [{ type: Injectable, args: [{ providedIn: 'root', }] }], () => [{ type: i1.K8sApiService }, { type: i2.AuthorizationStateService }, { type: i3.K8sUtilService }, { type: i4.NotificationService }, { type: i4.MessageService }], null); })(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90aWZ5LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9zcmMvcGFnZS1zY2FmZm9sZC9wYWdlLWhlYWRlci9oZWFkZXItbm90aWZ5L25vdGlmeS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxjQUFjLEVBQ2QsV0FBVyxJQUFJLElBQUksRUFFbkIsbUJBQW1CLEdBQ3BCLE1BQU0sWUFBWSxDQUFDO0FBQ3BCLE9BQU8sRUFBZ0IsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDaEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRW5FLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM3RCxPQUFPLEVBQW9CLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRWxFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sOENBQThDLENBQUM7QUFFL0UsT0FBTyxFQUNMLGNBQWMsRUFFZCxXQUFXLEVBQ1gsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFDaEIsV0FBVyxHQUNaLE1BQU0sU0FBUyxDQUFDOzs7Ozs7QUFFakIsTUFBTSxlQUFlLEdBQUc7SUFDdEIsQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUs7SUFDeEMsQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUk7SUFDdEMsQ0FBQyxXQUFXLENB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RUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxPQUFPO1FBQ0wsc0NBQXNDO1FBQ3RDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN6QixDQUFDOzhFQTNUVSxhQUFhO3VFQUFiLGFBQWEsV0FBYixhQUFhLG1CQUZaLE1BQU07O2lGQUVQLGFBQWE7Y0FIekIsVUFBVTtlQUFDO2dCQUNWLFVBQVUsRUFBRSxNQUFNO2FBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgTWVzc2FnZVNlcnZpY2UsXG4gIE1lc3NhZ2VUeXBlIGFzIFR5cGUsXG4gIE5vdGlmaWNhdGlvbkNvbXBvbmVudCxcbiAgTm90aWZpY2F0aW9uU2VydmljZSxcbn0gZnJvbSAnQGFsYXVkYS91aSc7XG5pbXBvcnQgeyBDb21wb25lbnRSZWYsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGdldCB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQgeyBTdWJqZWN0LCBvZiwgbWFwLCBzd2l0Y2hNYXAsIHRha2VVbnRpbCwgdGFwIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IEs4c0FwaVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9hcGkvazhzLWFwaS5zZXJ2aWNlJztcbmltcG9ydCB7IFdhdGNoQVBJUmVzcG9uc2UsIFdhdGNoRXZlbnQgfSBmcm9tICcuLi8uLi8uLi9hcGkvdHlwZXMnO1xuaW1wb3J0IHsgQWNjb3VudEluZm8gfSBmcm9tICcuLi8uLi8uLi9hdXRob3JpemF0aW9uL3B1YmxpYy1hcGknO1xuaW1wb3J0IHsgQXV0aG9yaXphdGlvblN0YXRlU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2F1dGhvcml6YXRpb24vc3RhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBLOHNVdGlsU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2NvcmUvcHVibGljLWFwaSc7XG5pbXBvcnQgeyBLOFNSZXNvdXJjZUxpc3QgfSBmcm9tICcuLi8uLi8uLi9rOHMtcmVzb3VyY2UtbGlzdC9rOHMtcmVzb3VyY2UtbGlzdCc7XG5cbmltcG9ydCB7XG4gIE1FU1NBR0VfQ09ORklHLFxuICBNZXNzYWdlLFxuICBNZXNzYWdlVHlwZSxcbiAgTk9USUZZX0lORk9fVFlQRSxcbiAgTk9USUZZX05PVF9GSVhFRCxcbiAgTk9USUZZX1BVU0hfVFlQRSxcbiAgZGF0ZVZhbHVlT2YsXG59IGZyb20gJy4vdXRpbHMnO1xuXG5jb25zdCBOT1RJRllfVFlQRV9NQVAgPSB7XG4gIFtNZXNzYWdlVHlwZS5XYXJuaW5nTWVzc2FnZV06IFR5cGUuRXJyb3IsXG4gIFtNZXNzYWdlVHlwZS5TeXN0ZW1NZXNzYWdlXTogVHlwZS5JbmZvLFxuICBbTWVzc2FnZVR5cGUuUHJvZHVjdE1lc3NhZ2VdOiBUeXBlLlN1Y2Nlc3MsXG4gIFtNZXNzYWdlVHlwZS5QbGF0Zm9ybUFubm91bmNlbWVudF06ICcnLFxufTtcbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBOb3RpZnlTZXJ2aWNlIHtcbiAgcHJpdmF0ZSB1c2VyTmFtZTogc3RyaW5nO1xuICB0cmlnZ2VyTm90aWZ5JCA9IG5ldyBTdWJqZWN0PE1lc3NhZ2U+KCk7XG4gIHB1c2hFbmFibGVkID0gdHJ1ZTtcbiAgYXVpTm90aWZpY2F0aW9uTGlzdDogQXJyYXk8Q29tcG9uZW50UmVmPE5vdGlmaWNhdGlvbkNvbXBvbmVudD4+ID0gW107XG4gIHdpbmRvd1VubG9hZCA9IGZhbHNlO1xuICBvbkRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgdXNlck5hbWUkID0gdGhpcy5hdXRoLmdldFRva2VuUGF5bG9hZDxBY2NvdW50SW5mbz4oKS5waXBlKFxuICAgIHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSQpLFxuICAgIG1hcChhY2NvdW50ID0+IGFjY291bnQuZW1haWwgfHwgYWNjb3VudC5uYW1lKSxcbiAgICB0YXAobmFtZSA9PiB7XG4gICAgICB0aGlzLnVzZXJOYW1lID0gbmFtZTtcbiAgICAgIHRoaXMuc2V0dGluZ0RlZmF1bHRQdXNoU3RhdHVzKCk7XG4gICAgfSksXG4gICk7XG4gIC8vIOi/meS4queJiOacrOayoeacieiHquWKqOWPkemAgeeahOa2iOaBr++8jOeUqOaIt+aJi+WGjOayoeacieWKnuazleaPj+i/sOi/memDqOWIhuWKn+iDvSwg5YWI5rOo6YeKXG4gIC8vIOWboOWNoOeUqOW5tuWPkeaVsO+8jOWQjue7reWmguS6p+WTgemcgOimgemHjeaWsOWKoOWFpeatpOWKn+iDve+8jOWPr+S7peWSjOS6p+WTgeiuqOiuuuS4i+aYr+WQpuWPr+S7pemYieWJsuatpOWKn+iDvVxuICAvLyB3YXRjaENvbmZpZ01hcCQgPSB0aGlzLms4c0FwaVxuICAvLyAgIC53YXRjaEdsb2JhbFJlc291cmNlKHtcbiAgLy8gICAgIGRlZmluaXRpb246IHtcbiAgLy8gICAgICAgdHlwZTogJ2NvbmZpZ21hcHMnLFxuICAvLyAgICAgfSxcbiAgLy8gICAgIG5hbWVzcGFjZWQ6IHRydWUsXG4gIC8vICAgICBuYW1lOiAnbWVzc2FnZS1jb25maWcnLFxuICAvLyAgIH0pXG4gIC8vICAgLnBpcGUoXG4gIC8vICAgICB0YWtlVW50aWwodGhpcy5vbkRlc3Ryb3kkKSxcbiAgLy8gICAgIGNhdGNoRXJyb3IoKCkgPT4gb2YobnVsbCkpLFxuICAvLyAgICAgbWFwKCgpID0+IHtcbiAgLy8gICAgICAgcmV0dXJuIHRoaXMucHVzaEVuYWJsZWQ7XG4gIC8vICAgICB9KSxcbiAgLy8gICApO1xuICAvLyB3YXRjaE1lc3NhZ2VDb25maWdNYXAkID0gdGhpcy53YXRjaENvbmZpZ01hcCQucGlwZShcbiAgLy8gICBzd2l0Y2hNYXAocmVzID0+XG4gIC8vICAgICB0aGlzLnVzZXJOYW1lJC5waXBlKFxuICAvLyAgICAgICBtYXAoKCkgPT4ge1xuICAvLyAgICAgICAgIHJldHVybiByZXM7XG4gIC8vICAgICAgIH0pLFxuICAvLyAgICAgKSxcbiAgLy8gICApLFxuICAvLyApO1xuXG4gIGxpc3QgPSBuZXcgSzhTUmVzb3VyY2VMaXN0KHtcbiAgICBmZXRjaFBhcmFtcyQ6IG9mKHt9KSwgLy8g5L2/55So56m65Y+C5pWw5ZCm5YiZ6Lev55Sx5Y+C5pWw5Y+Y5YyW5Lya5a+86Ie06YeN5paw6Kem5Y+RIGdldCBsaXN0XG4gICAgZmV0Y2hlcjogdGhpcy5mZXRjaGVyLmJpbmQodGhpcyksXG4gICAgd2F0Y2hlcjogc2VlZCA9PlxuICAgICAgdGhpcy5rOHNBcGlcbiAgICAgICAgLndhdGNoR2xvYmFsUmVzb3VyY2VDaGFuZ2U8TWVzc2FnZT4oc2VlZCwge1xuICAgICAgICAgIGRlZmluaXRpb246IE1FU1NBR0VfQ09ORklHLFxuICAgICAgICB9KVxuICAgICAgICAucGlwZShcbiAgICAgICAgICB0YXAoaXRlbSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjYWNoZUluZm8gPSB0aGlzLmdldENhY2hlTG9jYWxWYWx1ZShOT1RJRllfSU5GT19UWVBFKTtcbiAgICAgICAgICAgIGNvbnN0IGluZm9WYWx1ZTogc3RyaW5nW10gPSBjYWNoZUluZm8/LnNwbGl0KCcsJykgfHwgW107XG4gICAgICAgICAgICB0aGlzLnJlbW92ZVB1c2goaXRlbSk7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIFtXYXRjaEV2ZW50LkFkZGVkLCBXYXRjaEV2ZW50Lk1vZGlmaWVkXS5pbmNsdWRlcyhpdGVtLnR5cGUpICYmXG4gICAgICAgICAgICAgICFpbmZvVmFsdWUuaW5jbHVkZXModGhpcy5rOHNVdGlsLmdldE5hbWUoaXRlbS5vYmplY3QpKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hOb3RpZnkoaXRlbS5vYmplY3QpO1xuICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IFsuLi5pbmZvVmFsdWUsIHRoaXMuazhzVXRpbC5nZXROYW1lKGl0ZW0ub2JqZWN0KV07XG4gICAgICAgICAgICAgIHRoaXMuY2FjaGVOb3RpZnlJbmZvKHZhbHVlLmpvaW4oJywnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgcG9sbGluZzogMTBfMDAwLFxuICB9KTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGs4c0FwaTogSzhzQXBpU2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGF1dGg6IEF1dGhvcml6YXRpb25TdGF0ZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWFkb25seSBrOHNVdGlsOiBLOHNVdGlsU2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG5vdGlmaWNhdGlvbjogTm90aWZpY2F0aW9uU2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1lc3NhZ2VzOiBNZXNzYWdlU2VydmljZSxcbiAgKSB7fVxuXG4gIHdhdGNoTm90aWZ5KCkge1xuICAgIHRoaXMudHJpZ2dlck5vdGlmeSQucGlwZSh0YWtlVW50aWwodGhpcy5vbkRlc3Ryb3kkKSkuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICB0aGlzLm5vdGlmeU1lc3NhZ2UocmVzKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldE5vdGlmeUxpc3QoKSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdC5pdGVtcyQucGlwZShcbiAgICAgIHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSQpLFxuICAgICAgc3dpdGNoTWFwKHJlcyA9PiB0aGlzLnVzZXJOYW1lJC5waXBlKG1hcCgoKSA9PiByZXMpKSksXG4gICAgICBtYXAocmVzID0+IHRoaXMubWVzc2FnZVNvcnQocmVzLCAnZGVzYycpKSxcbiAgICApO1xuICB9XG5cbiAgbWVzc2FnZVNvcnQoZGF0YTogTWVzc2FnZVtdLCB0eXBlOiAnYXNjJyB8ICdkZXNjJyA9ICdhc2MnKSB7XG4gICAgcmV0dXJuIGRhdGEuc29ydCgoYSwgYikgPT4ge1xuICAgICAgY29uc3Qgc3RhcnQgPVxuICAgICAgICB0eXBlID09PSAnYXNjJ1xuICAgICAgICAgID8gYS5tZXRhZGF0YS5jcmVhdGlvblRpbWVzdGFtcFxuICAgICAgICAgIDogYi5tZXRhZGF0YS5jcmVhdGlvblRpbWVzdGFtcDtcbiAgICAgIGNvbnN0IGVuZCA9XG4gICAgICAgIHR5cGUgPT09ICdhc2MnXG4gICAgICAgICAgPyBiLm1ldGFkYXRhLmNyZWF0aW9uVGltZXN0YW1wXG4gICAgICAgICAgOiBhLm1ldGFkYXRhLmNyZWF0aW9uVGltZXN0YW1wO1xuICAgICAgcmV0dXJuIGRhdGVWYWx1ZU9mKHN0YXJ0KSAtIGRhdGVWYWx1ZU9mKGVuZCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGZldGNoZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuazhzQXBpXG4gICAgICAuZ2V0R2xvYmFsUmVzb3VyY2VMaXN0PE1lc3NhZ2U+KHtcbiAgICAgICAgZGVmaW5pdGlvbjogTUVTU0FHRV9DT05GSUcsXG4gICAgICB9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRhcChyZXMgPT4ge1xuICAgICAgICAgIHRoaXMuaGFuZGxlTm90aWZ5KHJlcy5pdGVtcyk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlTm90aWZ5KGRhdGE6IE1lc3NhZ2VbXSkge1xuICAgIGNvbnN0IGNhY2hlSW5mbyA9IHRoaXMuZ2V0Q2FjaGVMb2NhbFZhbHVlKE5PVElGWV9JTkZPX1RZUEUpO1xuICAgIGNvbnN0IGluZm9WYWx1ZTogc3RyaW5nW10gPSBjYWNoZUluZm8/LnNwbGl0KCcsJykgfHwgW107XG4gICAgY29uc3QgbWVzc2FnZXMgPSB0aGlzLm1lc3NhZ2VTb3J0KGRhdGEsICdkZXNjJykucmVkdWNlKChhY2MsIGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IHsgaXNSZXNpZGVudCB9ID0gaXRlbS5zcGVjO1xuICAgICAgaWYgKFxuICAgICAgICBpc1Jlc2lkZW50ICYmXG4gICAgICAgICF0aGlzLmV4cGlyZWQoaXRlbSkgJiZcbiAgICAgICAgIWluZm9WYWx1ZS5pbmNsdWRlcyh0aGlzLms4c1V0aWwuZ2V0TmFtZShpdGVtKSlcbiAgICAgICkge1xuICAgICAgICBjb25zdCBwcmUgPSBhY2MgPyBgJHthY2N9LGAgOiAnJztcbiAgICAgICAgdGhpcy5kaXNwYXRjaE5vdGlmeShpdGVtKTsgLy8g6Kem5Y+R5o+Q56S65raI5oGvXG4gICAgICAgIHJldHVybiBgJHtwcmV9JHt0aGlzLms4c1V0aWwuZ2V0TmFtZShpdGVtKX1gO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCAnJyk7XG4gICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICB0aGlzLmNhY2hlTm90aWZ5SW5mbyhtZXNzYWdlcyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjYWNoZU5vdGlmeUluZm8odmFsdWVzOiBzdHJpbmcpIHtcbiAgICB0aGlzLmFkZENhY2hlTG9jYWxWYWx1ZShOT1RJRllfSU5GT19UWVBFLCB2YWx1ZXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBkaXNwYXRjaE5vdGlmeShkYXRhOiBNZXNzYWdlKSB7XG4gICAgY29uc3Qgbm90Rml4ZWQgPSB0aGlzLmdldENhY2hlTG9jYWxWYWx1ZShOT1RJRllfTk9UX0ZJWEVEKTtcbiAgICBjb25zdCBwYXNzID0gIW5vdEZpeGVkPy5zcGxpdCgnLCcpPy5pbmNsdWRlcyh0aGlzLms4c1V0aWwuZ2V0TmFtZShkYXRhKSk7XG4gICAgY29uc3QgcHVzaCA9IHRoaXMuZ2V0Q2FjaGVMb2NhbFZhbHVlKE5PVElGWV9QVVNIX1RZUEUpO1xuICAgIGlmIChcbiAgICAgICgoIWRhdGEuc3BlYy5pc1Jlc2lkZW50ICYmIHRoaXMucHVzaEVuYWJsZWQgJiYgcHVzaCkgfHxcbiAgICAgICAgIXRoaXMuZXhwaXJlZChkYXRhKSkgJiZcbiAgICAgIHBhc3NcbiAgICApIHtcbiAgICAgIHRoaXMudHJpZ2dlck5vdGlmeSQubmV4dChkYXRhKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGV4cGlyZWQoaXRlbTogTWVzc2FnZSkge1xuICAgIGNvbnN0IGV4cGlyZWRUaW1lc3RhbXAgPSBpdGVtLnNwZWMuZXhwaXJlZFRpbWVzdGFtcDtcbiAgICBpZiAoIWV4cGlyZWRUaW1lc3RhbXApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IERhdGUoZXhwaXJlZFRpbWVzdGFtcCkudmFsdWVPZigpIDwgRGF0ZS5ub3coKTtcbiAgfVxuXG4gIGdldENhY2hlTG9jYWxWYWx1ZSh0eXBlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHZhbHVlID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKHR5cGUpO1xuICAgIHJldHVybiB2YWx1ZSAmJiBKU09OLnBhcnNlKHZhbHVlKVt0aGlzLnVzZXJOYW1lXTtcbiAgfVxuXG4gIGFkZENhY2hlTG9jYWxWYWx1ZSh0eXBlOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBib29sZWFuKSB7XG4gICAgY29uc3QgcHJlVmFsdWUgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0odHlwZSk7XG4gICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKFxuICAgICAgdHlwZSxcbiAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgLi4uKHByZVZhbHVlID8gSlNPTi5wYXJzZShwcmVWYWx1ZSkgOiB7fSksXG4gICAgICAgIFt0aGlzLnVzZXJOYW1lXTogdmFsdWUsXG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBub3RpZnlNZXNzYWdlKGRhdGE6IE1lc3NhZ2UpIHtcbiAgICBjb25zdCB7IGlzUmVzaWRlbnQsIHN1YmplY3QsIGNvbnRlbnQgfSA9IGRhdGEuc3BlYztcbiAgICBjb25zdCBuYW1lID0gdGhpcy5rOHNVdGlsLmdldE5hbWUoZGF0YSk7XG4gICAgY29uc3QgdHlwZSA9IHRoaXMuZ2V0TWVzc2FnZVR5cGUoZGF0YSk7XG5cbiAgICBpZiAoaXNSZXNpZGVudCkge1xuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uUmVmID0gdGhpcy5ub3RpZmljYXRpb24uY3JlYXRlKHtcbiAgICAgICAgdHlwZTogdHlwZSB8fCBUeXBlLkluZm8sXG4gICAgICAgIHRpdGxlOiBzdWJqZWN0LFxuICAgICAgICAuLi4odHlwZSA/IHt9IDogeyBjdXN0b21DbGFzczogJ3BsYXRmb3JtLWNsYXNzJyB9KSxcbiAgICAgICAgY29udGVudCxcbiAgICAgICAgLi4uKGlzUmVzaWRlbnQgPyB7IGR1cmF0aW9uOiAwIH0gOiB7fSksXG4gICAgICB9KTtcbiAgICAgIHRoaXMuYXVpTm90aWZpY2F0aW9uTGlzdC5wdXNoKG5vdGlmaWNhdGlvblJlZik7XG4gICAgICBPYmplY3QuYXNzaWduKG5vdGlmaWNhdGlvblJlZi5pbnN0YW5jZSwgeyBkYXRhIH0pO1xuICAgICAgbm90aWZpY2F0aW9uUmVmLmluc3RhbmNlLmFmdGVyQ2xvc2VkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuY2xvc2VkTm90aWZ5Q2FsbGJhY2soXG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIGdldChub3RpZmljYXRpb25SZWYuaW5zdGFuY2UsICd3aW5kb3dVbmxvYWQnLCBmYWxzZSksXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5tZXNzYWdlcy5jcmVhdGUoe1xuICAgICAgdHlwZTogdHlwZSB8fCBUeXBlLkluZm8sXG4gICAgICBjb250ZW50OiBzdWJqZWN0LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOWFs+mXremAmuefpTog5omL5Yqo5YWz6Zet5a2Y5YKoIOa3u+WKoOS4jeWGjeWxleekuueKtuaAgeiusOW9lVxuICAgKiDlhbPpl63pobXpnaLjgIHliKDpmaTmtojmga8g5LiN6K6w5b2VXG4gICAqL1xuICBwcml2YXRlIGNsb3NlZE5vdGlmeUNhbGxiYWNrKFxuICAgIGRhdGE6IE1lc3NhZ2UsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHdpbmRvd1VubG9hZDogYm9vbGVhbixcbiAgKSB7XG4gICAgdGhpcy5yZW1vdmVOb3RpZmljYXRpb25MaXN0KG5hbWUpO1xuICAgIGlmICghdGhpcy53aW5kb3dVbmxvYWQgJiYgIXdpbmRvd1VubG9hZCkge1xuICAgICAgdGhpcy5hZGROb3RGaXhlZChkYXRhKTtcbiAgICB9XG4gICAgdGhpcy53aW5kb3dVbmxvYWQgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDorrDlvZUg5LiN5YaN5bGV56S654q25oCBIOWtmOWCqOWcqCBsb2NhbCBzdG9yYWdlXG4gICAqL1xuICBwcml2YXRlIGFkZE5vdEZpeGVkKGRhdGE6IE1lc3NhZ2UpIHtcbiAgICBpZiAoZGF0YS5zcGVjLmlzUmVzaWRlbnQpIHtcbiAgICAgIGNvbnN0IG5vdEZpeGVkVmFsID0gdGhpcy5nZXRDYWNoZUxvY2FsVmFsdWUoTk9USUZZX05PVF9GSVhFRCk7XG4gICAgICBjb25zdCB2YWx1ZSA9IFtcbiAgICAgICAgLi4uKG5vdEZpeGVkVmFsPy5zcGxpdCgnLCcpIHx8IFtdKSxcbiAgICAgICAgdGhpcy5rOHNVdGlsLmdldE5hbWUoZGF0YSksXG4gICAgICBdO1xuICAgICAgdGhpcy5hZGRDYWNoZUxvY2FsVmFsdWUoTk9USUZZX05PVF9GSVhFRCwgdmFsdWUuam9pbignLCcpKTtcbiAgICB9XG4gICAgdGhpcy53aW5kb3dVbmxvYWQgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDop6blj5HliKDpmaTmtojmga9cbiAgICogLSDliKDpmaQgbG9jYWwgc3RvcmFnZSBOT1RfRklYRUQg5a2Y5YKo55qE5raI5oGvXG4gICAqIC0g5omL5Yqo6Kem5Y+R5YWz6Zet5bi46am76YCa55+l5by55qGGXG4gICAqL1xuICBwcml2YXRlIHJlbW92ZVB1c2goaXRlbTogV2F0Y2hBUElSZXNwb25zZTxNZXNzYWdlPikge1xuICAgIGNvbnN0IG5hbWUgPSB0aGlzLms4c1V0aWwuZ2V0TmFtZShpdGVtLm9iamVjdCk7XG4gICAgY29uc3Qgbm90Rml4ZWRWYWwgPVxuICAgICAgdGhpcy5nZXRDYWNoZUxvY2FsVmFsdWUoTk9USUZZX05PVF9GSVhFRCk/LnNwbGl0KCcsJykgfHwgW107XG4gICAgaWYgKFdhdGNoRXZlbnQuRGVsZXRlZCA9PT0gaXRlbS50eXBlKSB7XG4gICAgICB0aGlzLnJlbW92ZU1lc3NhZ2UobmFtZSk7XG4gICAgICB0aGlzLm1hbnVhbENsb3NlTm90aWZ5KG5hbWUpO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICBXYXRjaEV2ZW50LkRlbGV0ZWQgPT09IGl0ZW0udHlwZSAmJlxuICAgICAgaXRlbS5vYmplY3Quc3BlYy5pc1Jlc2lkZW50ICYmXG4gICAgICAhbm90Rml4ZWRWYWwuaW5jbHVkZXMobmFtZSlcbiAgICApIHtcbiAgICAgIHRoaXMubWFudWFsQ2xvc2VOb3RpZnkobmFtZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVNZXNzYWdlKG5hbWU6IHN0cmluZykge1xuICAgIGNvbnN0IGNhY2hlTm90Rml4ZWQgPVxuICAgICAgdGhpcy5nZXRDYWNoZUxvY2FsVmFsdWUoTk9USUZZX05PVF9GSVhFRCk/LnNwbGl0KCcsJykgfHwgW107XG4gICAgaWYgKGNhY2hlTm90Rml4ZWQubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgaW5kZXggPSBjYWNoZU5vdEZpeGVkLmluZGV4T2YobmFtZSk7XG4gICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgIGNhY2hlTm90Rml4ZWQuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgdGhpcy5hZGRDYWNoZUxvY2FsVmFsdWUoTk9USUZZX05PVF9GSVhFRCwgY2FjaGVOb3RGaXhlZC5qb2luKCcsJykpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbWFudWFsQ2xvc2VOb3RpZnkobmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3Qgbm90aWZ5SW5zdGFuY2UgPSB0aGlzLmF1aU5vdGlmaWNhdGlvbkxpc3QuZmluZChcbiAgICAgIGl0ZW0gPT4gdGhpcy5rOHNVdGlsLmdldE5hbWUoZ2V0KGl0ZW0uaW5zdGFuY2UsICdkYXRhJykpID09PSBuYW1lLFxuICAgICk7XG4gICAgaWYgKG5vdGlmeUluc3RhbmNlKSB7XG4gICAgICB0aGlzLndpbmRvd1VubG9hZCA9IHRydWU7XG4gICAgICBub3RpZnlJbnN0YW5jZS5pbnN0YW5jZS5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlTm90aWZpY2F0aW9uTGlzdChuYW1lOiBzdHJpbmcpIHtcbiAgICB0aGlzLmF1aU5vdGlmaWNhdGlvbkxpc3QgPSB0aGlzLmF1aU5vdGlmaWNhdGlvbkxpc3QuZmlsdGVyKFxuICAgICAgaXRlbSA9PiB0aGlzLms4c1V0aWwuZ2V0TmFtZShnZXQoaXRlbS5pbnN0YW5jZSwgJ2RhdGEnKSkgIT09IG5hbWUsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TWVzc2FnZVR5cGUoZGF0YTogTWVzc2FnZSkge1xuICAgIGNvbnN0IHR5cGUgPSB0aGlzLms4c1V0aWwuZ2V0TGFiZWwoZGF0YSwgJ3R5cGUnKSBhcyBNZXNzYWdlVHlwZTtcbiAgICByZXR1cm4gTk9USUZZX1RZUEVfTUFQW3R5cGVdIGFzIFR5cGU7XG4gIH1cblxuICBwcml2YXRlIHNldHRpbmdEZWZhdWx0UHVzaFN0YXR1cygpIHtcbiAgICBpZiAoIXdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShOT1RJRllfUFVTSF9UWVBFKSkge1xuICAgICAgdGhpcy5hZGRDYWNoZUxvY2FsVmFsdWUoTk9USUZZX1BVU0hfVFlQRSwgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgY2xvc2VBbGxOb3RpZmljYXRpb24oKSB7XG4gICAgZm9yIChjb25zdCBub3RpZnkgb2YgdGhpcy5hdWlOb3RpZmljYXRpb25MaXN0KSB7XG4gICAgICAvLyDlsIYgd2luZG93VW5sb2FkIOWtmOWCqCBpbnN0YW5jZSDlnKggYWZ0ZXJDbG9zZWQg6L+b6KGM5Yik5patXG4gICAgICAvLyByZW1vdmUg5byC5q2lIOW+queOr+S4rSB3aW5kb3dVbmxvYWQg5YC85bey5Y+R55Sf5pS55Y+Y5L2G6L+Y5pyq6Kem5Y+RIGFmdGVyQ2xvc2VkIOWbnuiwg1xuICAgICAgT2JqZWN0LmFzc2lnbihub3RpZnkuaW5zdGFuY2UsIHsgd2luZG93VW5sb2FkOiB0cnVlIH0pO1xuICAgICAgbm90aWZ5Lmluc3RhbmNlLmNsb3NlKCk7XG4gICAgfVxuICAgIHRoaXMuYXVpTm90aWZpY2F0aW9uTGlzdCA9IFtdO1xuICB9XG5cbiAgZGVzdHJveSgpIHtcbiAgICAvLyDph43mlrDliqDovb0gaGVhZGVyIOWFs+mXreaJgOaciemAmuefpe+8jOmHjeaWsOWKoOi9vSBoZWFkZXIg6YeN5paw5by55Ye6XG4gICAgdGhpcy5jbG9zZUFsbE5vdGlmaWNhdGlvbigpO1xuICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShOT1RJRllfSU5GT19UWVBFKTtcbiAgICB0aGlzLm9uRGVzdHJveSQubmV4dCgpO1xuICB9XG59XG4iXX0=