cloud-ide-layout 0.0.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +466 -13
- package/esm2022/lib/cloud-ide-layout.routes.mjs +24 -10
- package/esm2022/lib/layout/console/console-wrapper/console-wrapper.component.mjs +6 -6
- package/esm2022/lib/layout/console/console.service.mjs +28 -0
- package/esm2022/lib/layout/footer/footer-wrapper/footer-wrapper.component.mjs +16 -8
- package/esm2022/lib/layout/footer/footer.service.mjs +28 -0
- package/esm2022/lib/layout/header/header-wrapper/header-wrapper.component.mjs +69 -18
- package/esm2022/lib/layout/header/header.service.mjs +17 -6
- package/esm2022/lib/layout/home/home-wrapper/home-wrapper.component.mjs +194 -7
- package/esm2022/lib/layout/layout/layout-wrapper/layout-wrapper.component.mjs +18 -9
- package/esm2022/lib/layout/request/request-wrapper/request-wrapper.component.mjs +54 -6
- package/esm2022/lib/layout/request/request.service.mjs +235 -0
- package/esm2022/lib/layout/request/tab-content/tab-content.component.mjs +84 -0
- package/esm2022/lib/layout/shared/shared-wrapper/shared-wrapper.component.mjs +32 -20
- package/esm2022/lib/layout/shared/shared.service.mjs +490 -14
- package/esm2022/lib/layout/sidebar/sidebar-wrapper/sidebar-wrapper.component.mjs +480 -15
- package/esm2022/lib/layout/sidebar/sidebar.service.mjs +20 -7
- package/esm2022/lib/layout/sidedrawer/cide-lyt-drawer-base.class.mjs +40 -0
- package/esm2022/lib/layout/sidedrawer/drawer-theme/drawer-theme.component.mjs +296 -0
- package/esm2022/lib/layout/sidedrawer/sidedrawer-notes/sidedrawer-notes.component.mjs +175 -0
- package/esm2022/lib/layout/sidedrawer/sidedrawer-notes/sidedrawer-notes.service.mjs +51 -0
- package/esm2022/lib/layout/sidedrawer/sidedrawer-wrapper/sidedrawer-wrapper.component.mjs +254 -9
- package/esm2022/lib/layout/sidedrawer/sidedrawer.service.mjs +70 -0
- package/esm2022/lib/services/app-state/app-state-helper.service.mjs +222 -0
- package/esm2022/lib/services/app-state/app-state.service.mjs +256 -0
- package/esm2022/lib/services/app-state/index.mjs +3 -0
- package/esm2022/lib/services/cache-manager/cache-manager.service.mjs +112 -0
- package/esm2022/lib/services/file-manager/file-manager.service.mjs +7 -7
- package/esm2022/lib/services/tab-state.service.mjs +128 -0
- package/esm2022/lib/services/theme/theme.service.mjs +151 -0
- package/esm2022/lib/services/user-status/user-status.service.mjs +135 -0
- package/esm2022/lib/utils/custom-route-reuse-strategy.mjs +61 -0
- package/esm2022/lib/utils/index.mjs +2 -0
- package/esm2022/public-api.mjs +7 -1
- package/fesm2022/cloud-ide-layout-cloud-ide-layout-DqL3A73V.mjs +2914 -0
- package/fesm2022/cloud-ide-layout-cloud-ide-layout-DqL3A73V.mjs.map +1 -0
- package/fesm2022/cloud-ide-layout-drawer-theme.component-xd8IG3WP.mjs +443 -0
- package/fesm2022/cloud-ide-layout-drawer-theme.component-xd8IG3WP.mjs.map +1 -0
- package/fesm2022/cloud-ide-layout-home-wrapper.component-DEdsEiaq.mjs +197 -0
- package/fesm2022/cloud-ide-layout-home-wrapper.component-DEdsEiaq.mjs.map +1 -0
- package/fesm2022/cloud-ide-layout-sidedrawer-notes.component-ds12wZbh.mjs +260 -0
- package/fesm2022/cloud-ide-layout-sidedrawer-notes.component-ds12wZbh.mjs.map +1 -0
- package/fesm2022/cloud-ide-layout.mjs +1 -261
- package/fesm2022/cloud-ide-layout.mjs.map +1 -1
- package/lib/cloud-ide-layout.routes.d.ts +1 -0
- package/lib/layout/console/console-wrapper/console-wrapper.component.d.ts +3 -3
- package/lib/layout/console/console.service.d.ts +9 -0
- package/lib/layout/footer/footer-wrapper/footer-wrapper.component.d.ts +7 -3
- package/lib/layout/footer/footer.service.d.ts +9 -0
- package/lib/layout/header/header-wrapper/header-wrapper.component.d.ts +17 -9
- package/lib/layout/header/header.service.d.ts +4 -3
- package/lib/layout/home/home-wrapper/home-wrapper.component.d.ts +90 -1
- package/lib/layout/request/request-wrapper/request-wrapper.component.d.ts +10 -1
- package/lib/layout/request/request.service.d.ts +60 -0
- package/lib/layout/request/tab-content/tab-content.component.d.ts +19 -0
- package/lib/layout/shared/shared-wrapper/shared-wrapper.component.d.ts +4 -5
- package/lib/layout/shared/shared.service.d.ts +104 -6
- package/lib/layout/sidebar/sidebar-wrapper/sidebar-wrapper.component.d.ts +135 -6
- package/lib/layout/sidebar/sidebar.service.d.ts +3 -2
- package/lib/layout/sidedrawer/cide-lyt-drawer-base.class.d.ts +16 -0
- package/lib/layout/sidedrawer/drawer-theme/drawer-theme.component.d.ts +71 -0
- package/lib/layout/sidedrawer/sidedrawer-notes/sidedrawer-notes.component.d.ts +48 -0
- package/lib/layout/sidedrawer/sidedrawer-notes/sidedrawer-notes.service.d.ts +13 -0
- package/lib/layout/sidedrawer/sidedrawer-wrapper/sidedrawer-wrapper.component.d.ts +28 -3
- package/lib/layout/sidedrawer/sidedrawer.service.d.ts +30 -0
- package/lib/services/app-state/app-state-helper.service.d.ts +150 -0
- package/lib/services/app-state/app-state.service.d.ts +85 -0
- package/lib/services/app-state/index.d.ts +3 -0
- package/lib/services/cache-manager/cache-manager.service.d.ts +64 -0
- package/lib/services/file-manager/file-manager.service.d.ts +0 -2
- package/lib/services/tab-state.service.d.ts +79 -0
- package/lib/services/theme/theme.service.d.ts +71 -0
- package/lib/services/user-status/user-status.service.d.ts +57 -0
- package/lib/utils/custom-route-reuse-strategy.d.ts +15 -0
- package/lib/utils/index.d.ts +1 -0
- package/package.json +2 -2
- package/public-api.d.ts +4 -0
- package/src/lib/assets/css/cide-lyt-style.scss +182 -0
- package/src/lib/assets/css/cide-lyt-variable.scss +119 -0
- package/fesm2022/cloud-ide-layout-home-wrapper.component-BV7ptL0Y.mjs +0 -14
- package/fesm2022/cloud-ide-layout-home-wrapper.component-BV7ptL0Y.mjs.map +0 -1
|
@@ -1,26 +1,502 @@
|
|
|
1
|
-
import { Injectable } from '@angular/core';
|
|
1
|
+
import { Injectable, inject, signal, computed } from '@angular/core';
|
|
2
2
|
import { cidePath, designConfigRoutesUrl, hostManagerRoutesUrl } from 'cloud-ide-lms-model';
|
|
3
|
+
import { HttpClient } from '@angular/common/http';
|
|
4
|
+
import { of, throwError } from 'rxjs';
|
|
5
|
+
import { tap, catchError, shareReplay, filter, take } from 'rxjs/operators';
|
|
6
|
+
import { Router, NavigationEnd } from '@angular/router';
|
|
7
|
+
import { Title } from '@angular/platform-browser';
|
|
8
|
+
import { CideElementsService } from 'cloud-ide-element';
|
|
9
|
+
import { CideLytSidebarService } from '../sidebar/sidebar.service';
|
|
10
|
+
import { CideLytHeaderService } from '../header/header.service';
|
|
11
|
+
import { CideLytFooterService } from '../footer/footer.service';
|
|
12
|
+
import { CideLytConsoleService } from '../console/console.service';
|
|
13
|
+
import { CideLytSidedrawerService } from '../sidedrawer/sidedrawer.service';
|
|
14
|
+
import { AppStateHelperService } from '../../services/app-state/app-state-helper.service';
|
|
3
15
|
import * as i0 from "@angular/core";
|
|
4
|
-
import * as i1 from "cloud-ide-element";
|
|
5
|
-
import * as i2 from "@angular/common/http";
|
|
6
|
-
import * as i3 from "@angular/platform-browser";
|
|
7
16
|
export class CideLytSharedService {
|
|
8
|
-
constructor(
|
|
9
|
-
|
|
10
|
-
this.
|
|
11
|
-
|
|
17
|
+
constructor() {
|
|
18
|
+
// Clean up expired cache entries every minute
|
|
19
|
+
// setInterval(() => this.cleanExpiredCache(), 60000);
|
|
20
|
+
// Enhanced reactive cache with signals
|
|
21
|
+
this.pageDataCacheSignal = signal({});
|
|
22
|
+
this.loadingStateSignal = signal({});
|
|
23
|
+
// Public readonly access to cache
|
|
24
|
+
this.pageDataCache = this.pageDataCacheSignal.asReadonly();
|
|
25
|
+
this.loadingStates = this.loadingStateSignal.asReadonly();
|
|
26
|
+
// Computed signal for cache status
|
|
27
|
+
this.cacheInfo = computed(() => {
|
|
28
|
+
const cache = this.pageDataCacheSignal();
|
|
29
|
+
return {
|
|
30
|
+
totalCached: Object.keys(cache).length,
|
|
31
|
+
validCached: Object.values(cache).filter(item => this.isCacheValid(item)).length,
|
|
32
|
+
expiredCached: Object.values(cache).filter(item => !this.isCacheValid(item)).length
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
// In-flight requests to prevent duplicate API calls
|
|
36
|
+
this.inflightRequests = {};
|
|
37
|
+
// Default cache TTL (5 minutes)
|
|
38
|
+
this.DEFAULT_CACHE_TTL = 5 * 60 * 1000;
|
|
39
|
+
// Modern Angular v20 dependency injection pattern
|
|
40
|
+
this.elementService = inject(CideElementsService);
|
|
41
|
+
this.http = inject(HttpClient);
|
|
42
|
+
this.titleService = inject(Title);
|
|
43
|
+
this.sidebarService = inject(CideLytSidebarService);
|
|
44
|
+
this.headerService = inject(CideLytHeaderService);
|
|
45
|
+
this.footerService = inject(CideLytFooterService);
|
|
46
|
+
this.consoleService = inject(CideLytConsoleService);
|
|
47
|
+
this.sidedrawerService = inject(CideLytSidedrawerService);
|
|
48
|
+
this.router = inject(Router);
|
|
49
|
+
// Import AppStateHelperService for sidebar sync
|
|
50
|
+
this.appState = inject(AppStateHelperService);
|
|
51
|
+
// Listen to route changes - moved from request service
|
|
52
|
+
this.routeSubscription = this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe(() => {
|
|
53
|
+
// Cancel any ongoing page data fetching
|
|
54
|
+
this.pageDataSubscription?.unsubscribe();
|
|
55
|
+
this.handleRouteChange();
|
|
56
|
+
});
|
|
12
57
|
}
|
|
13
|
-
|
|
14
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Register tab management callback from request service
|
|
60
|
+
* This allows shared service to call request service without circular dependency
|
|
61
|
+
*/
|
|
62
|
+
registerTabManagement(callback) {
|
|
63
|
+
this.tabManagementCallback = callback;
|
|
64
|
+
console.log('✅ Tab management callback registered');
|
|
15
65
|
}
|
|
16
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Register request visibility callback from request service
|
|
68
|
+
* This allows shared service to control request wrapper visibility
|
|
69
|
+
*/
|
|
70
|
+
registerRequestVisibility(callback) {
|
|
71
|
+
this.requestVisibilityCallback = callback;
|
|
72
|
+
console.log('✅ Request visibility callback registered');
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Enhanced loadPageData with caching and deduplication
|
|
76
|
+
* @param body - Request payload
|
|
77
|
+
* @param forceRefresh - Force API call even if cached data exists
|
|
78
|
+
* @param customTTL - Custom cache TTL in milliseconds
|
|
79
|
+
*/
|
|
80
|
+
loadPageData(body, forceRefresh = false, customTTL = this.DEFAULT_CACHE_TTL) {
|
|
81
|
+
const pageCode = body.sypg_page_code?.toString() || '';
|
|
82
|
+
if (!pageCode) {
|
|
83
|
+
return throwError(() => new Error('Page code is required'));
|
|
84
|
+
}
|
|
85
|
+
// Check if we have valid cached data and not forcing refresh
|
|
86
|
+
if (!forceRefresh && this.hasValidCache(pageCode)) {
|
|
87
|
+
console.log(`🔄 CACHE HIT: Using cached data for page code: ${pageCode}`);
|
|
88
|
+
const cachedData = this.pageDataCacheSignal()[pageCode];
|
|
89
|
+
return of(cachedData.response);
|
|
90
|
+
}
|
|
91
|
+
// Check if there's already an in-flight request for this page code
|
|
92
|
+
if (this.inflightRequests[pageCode]) {
|
|
93
|
+
console.log(`🔄 INFLIGHT REQUEST: Returning existing request for page code: ${pageCode}`);
|
|
94
|
+
return this.inflightRequests[pageCode];
|
|
95
|
+
}
|
|
96
|
+
// Set loading state
|
|
97
|
+
this.setLoadingState(pageCode, true);
|
|
98
|
+
console.log(`🌐 API CALL: Loading fresh data for page code: ${pageCode}`);
|
|
99
|
+
// Create new API request
|
|
100
|
+
const request$ = this.http.post(cidePath.join([hostManagerRoutesUrl.cideSuiteHost, designConfigRoutesUrl?.module, designConfigRoutesUrl?.getPageData]), body);
|
|
101
|
+
// Cache the observable to prevent duplicate requests
|
|
102
|
+
this.inflightRequests[pageCode] = request$.pipe(tap(response => {
|
|
103
|
+
console.log(`✅ API SUCCESS: Caching data for page code: ${pageCode}`);
|
|
104
|
+
this.cachePageData(pageCode, body, response, customTTL);
|
|
105
|
+
this.setLoadingState(pageCode, false);
|
|
106
|
+
}), catchError(error => {
|
|
107
|
+
console.error(`❌ API ERROR: Failed to load data for page code: ${pageCode}`, error);
|
|
108
|
+
this.setLoadingState(pageCode, false);
|
|
109
|
+
return throwError(() => error);
|
|
110
|
+
}), shareReplay(1) // Share the result with multiple subscribers
|
|
111
|
+
);
|
|
112
|
+
// Clean up inflight request after completion
|
|
113
|
+
this.inflightRequests[pageCode].subscribe({
|
|
114
|
+
complete: () => {
|
|
115
|
+
delete this.inflightRequests[pageCode];
|
|
116
|
+
},
|
|
117
|
+
error: () => {
|
|
118
|
+
delete this.inflightRequests[pageCode];
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return this.inflightRequests[pageCode];
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Consolidated method to load and process page data
|
|
125
|
+
* This replaces the separate calls in request service and shared wrapper
|
|
126
|
+
*/
|
|
127
|
+
loadAndProcessPageData(body, options = {}) {
|
|
128
|
+
const { forceRefresh = false, customTTL = this.DEFAULT_CACHE_TTL, setTitle = true, setSidebarContext = true, updateLayout = true } = options;
|
|
129
|
+
return this.loadPageData(body, forceRefresh, customTTL).pipe(tap(response => {
|
|
130
|
+
if (response) {
|
|
131
|
+
console.log('🔍 SHARED SERVICE: loadAndProcessPageData', response);
|
|
132
|
+
// Process the response
|
|
133
|
+
if (updateLayout) {
|
|
134
|
+
this.setPageData(response, body);
|
|
135
|
+
}
|
|
136
|
+
// Set page title
|
|
137
|
+
if (setTitle && response.data?.page?.sypg_title) {
|
|
138
|
+
this.titleService.setTitle(response.data.page.sypg_title);
|
|
139
|
+
}
|
|
140
|
+
// Set sidebar context
|
|
141
|
+
if (setSidebarContext) {
|
|
142
|
+
// This will be handled by the component that needs the context
|
|
143
|
+
// as it's specific to the sidedrawer service
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Get cached page data without making API call
|
|
150
|
+
*/
|
|
151
|
+
getCachedPageData(pageCode) {
|
|
152
|
+
const cached = this.pageDataCacheSignal()[pageCode];
|
|
153
|
+
return this.isCacheValid(cached) ? cached.response : null;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Check if loading for a specific page code
|
|
157
|
+
*/
|
|
158
|
+
isLoading(pageCode) {
|
|
159
|
+
return this.loadingStates()[pageCode] || false;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Invalidate cache for specific page code
|
|
163
|
+
*/
|
|
164
|
+
invalidateCache(pageCode) {
|
|
165
|
+
const cache = { ...this.pageDataCacheSignal() };
|
|
166
|
+
delete cache[pageCode];
|
|
167
|
+
this.pageDataCacheSignal.set(cache);
|
|
168
|
+
console.log(`🗑️ CACHE INVALIDATED: Removed cache for page code: ${pageCode}`);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Clear all cached data
|
|
172
|
+
*/
|
|
173
|
+
clearAllCache() {
|
|
174
|
+
this.pageDataCacheSignal.set({});
|
|
175
|
+
this.loadingStateSignal.set({});
|
|
176
|
+
console.log('🗑️ CACHE CLEARED: All cached data removed');
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Preload page data for better performance
|
|
180
|
+
*/
|
|
181
|
+
preloadPageData(pageCodes) {
|
|
182
|
+
pageCodes.forEach(pageCode => {
|
|
183
|
+
if (!this.hasValidCache(pageCode) && !this.isLoading(pageCode)) {
|
|
184
|
+
this.loadPageData({ sypg_page_code: pageCode }).subscribe({
|
|
185
|
+
next: () => console.log(`🚀 PRELOADED: Page data for ${pageCode}`),
|
|
186
|
+
error: (err) => console.warn(`⚠️ PRELOAD FAILED: Could not preload ${pageCode}`, err)
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
// Private helper methods
|
|
192
|
+
hasValidCache(pageCode) {
|
|
193
|
+
const cached = this.pageDataCacheSignal()[pageCode];
|
|
194
|
+
return cached && this.isCacheValid(cached);
|
|
195
|
+
}
|
|
196
|
+
isCacheValid(cached) {
|
|
197
|
+
if (!cached)
|
|
198
|
+
return false;
|
|
199
|
+
return Date.now() - cached.timestamp < cached.ttl;
|
|
200
|
+
}
|
|
201
|
+
cachePageData(pageCode, request, response, ttl) {
|
|
202
|
+
const cache = { ...this.pageDataCacheSignal() };
|
|
203
|
+
cache[pageCode] = {
|
|
204
|
+
request,
|
|
205
|
+
response,
|
|
206
|
+
timestamp: Date.now(),
|
|
207
|
+
ttl
|
|
208
|
+
};
|
|
209
|
+
this.pageDataCacheSignal.set(cache);
|
|
210
|
+
}
|
|
211
|
+
setLoadingState(pageCode, loading) {
|
|
212
|
+
const loadingStates = { ...this.loadingStateSignal() };
|
|
213
|
+
if (loading) {
|
|
214
|
+
loadingStates[pageCode] = true;
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
delete loadingStates[pageCode];
|
|
218
|
+
}
|
|
219
|
+
this.loadingStateSignal.set(loadingStates);
|
|
220
|
+
}
|
|
221
|
+
cleanExpiredCache() {
|
|
222
|
+
const cache = { ...this.pageDataCacheSignal() };
|
|
223
|
+
let cleaned = false;
|
|
224
|
+
Object.keys(cache).forEach(pageCode => {
|
|
225
|
+
if (!this.isCacheValid(cache[pageCode])) {
|
|
226
|
+
delete cache[pageCode];
|
|
227
|
+
cleaned = true;
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
if (cleaned) {
|
|
231
|
+
this.pageDataCacheSignal.set(cache);
|
|
232
|
+
console.log('🧹 CACHE CLEANUP: Removed expired cache entries');
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
setPageData(page_data_response, page_data_payload) {
|
|
236
|
+
// to set the controls data to the element service
|
|
237
|
+
console.log('🔍 SHARED SERVICE: setPageData', page_data_response, page_data_payload);
|
|
17
238
|
if (page_data_response?.data?.controls) {
|
|
18
239
|
// Set controls here
|
|
19
240
|
this.elementService.cide_element_data = { ...this.elementService.cide_element_data, ...page_data_response?.data?.controls };
|
|
20
241
|
this.elementService.is_cide_element_data_updated?.next(true);
|
|
21
242
|
}
|
|
243
|
+
// while doing this we need to think about not to touch if this page is not pening in the popup or drower insted of main window
|
|
244
|
+
// Set the layout data
|
|
245
|
+
console.log('🔍 Layout data:', page_data_response);
|
|
246
|
+
if (page_data_response?.data?.theme?.sytm_layout) {
|
|
247
|
+
console.log('🔍 SIDEBAR DEBUG - Layout data:', page_data_response?.data?.theme?.sytm_layout, page_data_payload);
|
|
248
|
+
// check is sidebar is hiden or not (default is visible)
|
|
249
|
+
if (page_data_response?.data?.theme?.sytm_layout?.sytm_layout_sidebar) {
|
|
250
|
+
const sidebarStatus = page_data_response?.data?.theme?.sytm_layout?.sytm_layout_sidebar?.status;
|
|
251
|
+
console.log('🔍 SIDEBAR DEBUG - Sidebar status found:', sidebarStatus);
|
|
252
|
+
if (!sidebarStatus) {
|
|
253
|
+
console.log('🚫 SIDEBAR DEBUG - Hiding sidebar because status is false');
|
|
254
|
+
this.sidebarService.hideSidebar();
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
console.log('✅ SIDEBAR DEBUG - Showing sidebar because status is true');
|
|
258
|
+
this.sidebarService.showSidebar();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
console.log('⚠️ SIDEBAR DEBUG - No sidebar config found, hiding sidebar');
|
|
263
|
+
this.sidebarService.hideSidebar();
|
|
264
|
+
}
|
|
265
|
+
// check header visible or not
|
|
266
|
+
console.log('🔍 HEADER DEBUG - Header config found:', page_data_response?.data?.theme?.sytm_layout?.sytm_layout_header);
|
|
267
|
+
if (page_data_response?.data?.theme?.sytm_layout?.sytm_layout_header) {
|
|
268
|
+
if (!page_data_response?.data?.theme?.sytm_layout?.sytm_layout_header?.status) {
|
|
269
|
+
this.headerService.hideHeader();
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
this.headerService.showHeader();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
this.headerService.hideHeader();
|
|
277
|
+
}
|
|
278
|
+
// check footer visible or not
|
|
279
|
+
if (page_data_response?.data?.theme?.sytm_layout?.sytm_layout_footer) {
|
|
280
|
+
if (!page_data_response?.data?.theme?.sytm_layout?.sytm_layout_footer?.status) {
|
|
281
|
+
this.footerService.hideFooter();
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
this.footerService.showFooter();
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
this.footerService.hideFooter();
|
|
289
|
+
}
|
|
290
|
+
// check console visible or not
|
|
291
|
+
if (page_data_response?.data?.theme?.sytm_layout?.sytm_layout_console) {
|
|
292
|
+
if (!page_data_response?.data?.theme?.sytm_layout?.sytm_layout_console?.status) {
|
|
293
|
+
this.consoleService.hideConsole();
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
this.consoleService.showConsole();
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
this.consoleService.hideConsole();
|
|
301
|
+
}
|
|
302
|
+
// check for the request status and log it for debugging
|
|
303
|
+
console.log('🔍 REQUEST DEBUG - Request config found:', page_data_response?.data?.theme?.sytm_layout?.sytm_layout_request);
|
|
304
|
+
if (page_data_response?.data?.theme?.sytm_layout?.sytm_layout_request) {
|
|
305
|
+
const requestStatus = page_data_response?.data?.theme?.sytm_layout?.sytm_layout_request?.status;
|
|
306
|
+
console.log('🔍 REQUEST DEBUG - Request status:', requestStatus, 'Type:', typeof requestStatus);
|
|
307
|
+
// The request status controls whether this page should support tabs
|
|
308
|
+
// This is used by the request service to determine if tabs should be created
|
|
309
|
+
if (requestStatus === true) {
|
|
310
|
+
console.log('✅ REQUEST DEBUG - Request is enabled for tabbing');
|
|
311
|
+
// Show request wrapper when request is enabled
|
|
312
|
+
if (this.requestVisibilityCallback) {
|
|
313
|
+
this.requestVisibilityCallback(true);
|
|
314
|
+
console.log('📋 REQUEST VISIBILITY - Showing request wrapper');
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
else if (requestStatus === false) {
|
|
318
|
+
console.log('🚫 REQUEST DEBUG - Request is disabled for tabbing');
|
|
319
|
+
// Hide request wrapper when request is disabled
|
|
320
|
+
if (this.requestVisibilityCallback) {
|
|
321
|
+
this.requestVisibilityCallback(false);
|
|
322
|
+
console.log('📋 REQUEST VISIBILITY - Hiding request wrapper');
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
console.log('⚠️ REQUEST DEBUG - Unexpected request status value:', requestStatus);
|
|
327
|
+
// Default to hiding request wrapper for unexpected values
|
|
328
|
+
if (this.requestVisibilityCallback) {
|
|
329
|
+
this.requestVisibilityCallback(false);
|
|
330
|
+
console.log('📋 REQUEST VISIBILITY - Hiding request wrapper (unexpected value)');
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
console.log('⚠️ REQUEST DEBUG - No request config found, tabs will not be created');
|
|
336
|
+
// Hide request wrapper when no request config found
|
|
337
|
+
if (this.requestVisibilityCallback) {
|
|
338
|
+
this.requestVisibilityCallback(false);
|
|
339
|
+
console.log('📋 REQUEST VISIBILITY - Hiding request wrapper (no config)');
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Handle route changes - moved from request service for better architecture
|
|
346
|
+
* This method loads page data and calls request service to manage tabs
|
|
347
|
+
*/
|
|
348
|
+
handleRouteChange() {
|
|
349
|
+
const parsedUrl = this.router.parseUrl(this.router.url);
|
|
350
|
+
const currentRoutePath = '/' + (parsedUrl.root.children['primary']?.segments.map(s => s.path).join('/') || '');
|
|
351
|
+
const queryParams = parsedUrl.queryParams;
|
|
352
|
+
console.log('🔍 Route change:', {
|
|
353
|
+
currentRoutePath,
|
|
354
|
+
queryParams
|
|
355
|
+
});
|
|
356
|
+
// Get page code from route data
|
|
357
|
+
let route = this.router.routerState.snapshot.root;
|
|
358
|
+
while (route.firstChild) {
|
|
359
|
+
route = route.firstChild;
|
|
360
|
+
}
|
|
361
|
+
const pageCode = route.data && route.data['sypg_page_code'];
|
|
362
|
+
console.log('📄 Processing route with page code:', pageCode);
|
|
363
|
+
if (pageCode) {
|
|
364
|
+
const entityId = this.appState.getActiveEntityId();
|
|
365
|
+
console.log(`📡 Loading and processing page data for pageCode: ${pageCode}`);
|
|
366
|
+
this.pageDataSubscription = this.loadAndProcessPageData({ sypg_page_code: pageCode, sytm_entity_id_syen: entityId || undefined }, {
|
|
367
|
+
forceRefresh: false,
|
|
368
|
+
setTitle: true,
|
|
369
|
+
setSidebarContext: true,
|
|
370
|
+
updateLayout: true
|
|
371
|
+
}).pipe(take(1))
|
|
372
|
+
.subscribe({
|
|
373
|
+
next: (page_data_response) => {
|
|
374
|
+
const layout = page_data_response?.data?.theme?.sytm_layout;
|
|
375
|
+
// Update sidedrawer with processed layout
|
|
376
|
+
this.sidedrawerService.updateDrawerItems(layout);
|
|
377
|
+
// Sync sidebar active menu with loaded page
|
|
378
|
+
this.syncSidebarActiveMenu(page_data_response, pageCode);
|
|
379
|
+
if (layout?.sytm_layout_request?.status === true) {
|
|
380
|
+
console.log('✅ Layout processed - calling request service to manage tabs');
|
|
381
|
+
// Call request service to handle tab creation
|
|
382
|
+
this.handleTabRequest(currentRoutePath, queryParams, layout, page_data_response, pageCode);
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
console.log('❌ Layout request disabled - tab not created');
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
error: (err) => {
|
|
389
|
+
console.error(`❌ Error loading page data for sypg_page_code '${pageCode}':`, err);
|
|
390
|
+
this.sidedrawerService.updateDrawerItems(undefined);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
console.log('⚠️ No page code found in route data - clearing drawer');
|
|
396
|
+
this.sidedrawerService.updateDrawerItems(undefined);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Handle tab request by calling request service
|
|
401
|
+
*/
|
|
402
|
+
handleTabRequest(currentRoutePath, queryParams, layout, pageData, pageCode) {
|
|
403
|
+
if (this.tabManagementCallback) {
|
|
404
|
+
console.log('🔄 Calling registered tab management callback');
|
|
405
|
+
this.tabManagementCallback(currentRoutePath, queryParams, layout, pageData, pageCode);
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
console.log('⚠️ No tab management callback registered');
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Sync the active menu in the sidebar based on the loaded page data.
|
|
413
|
+
* This ensures the correct module is highlighted in the sidebar.
|
|
414
|
+
*/
|
|
415
|
+
syncSidebarActiveMenu(page_data_response, pageCode) {
|
|
416
|
+
console.log('🔍 SIDEBAR SYNC: Starting sidebar active menu sync for:', pageCode);
|
|
417
|
+
// Try to extract module information from route
|
|
418
|
+
const currentRoute = this.router.url;
|
|
419
|
+
const routeParts = currentRoute.split('/').filter(part => part);
|
|
420
|
+
let routeModuleName = '';
|
|
421
|
+
// Look for control-panel or module identifier in route
|
|
422
|
+
if (routeParts.includes('control-panel') && routeParts.length > 1) {
|
|
423
|
+
const moduleIndex = routeParts.indexOf('control-panel') + 1;
|
|
424
|
+
routeModuleName = routeParts[moduleIndex] || '';
|
|
425
|
+
}
|
|
426
|
+
else if (routeParts.length > 0) {
|
|
427
|
+
routeModuleName = routeParts[0];
|
|
428
|
+
}
|
|
429
|
+
console.log('🔍 SIDEBAR SYNC: Route module name:', routeModuleName);
|
|
430
|
+
console.log('🔍 SIDEBAR SYNC: Current route:', currentRoute);
|
|
431
|
+
console.log('🔍 SIDEBAR SYNC: Page code:', pageCode);
|
|
432
|
+
// Load sidebar modules and find the matching one
|
|
433
|
+
this.sidebarService.getSidebarMenues({ syme_type: "module", sort: 'asc', syme_title: "" })
|
|
434
|
+
.subscribe({
|
|
435
|
+
next: (modulesResponse) => {
|
|
436
|
+
const modules = modulesResponse?.data || [];
|
|
437
|
+
console.log('🔍 SIDEBAR SYNC: Available modules:', modules.map(m => ({ id: m._id, title: m.syme_title, path: m.syme_path })));
|
|
438
|
+
let matchedModule = null;
|
|
439
|
+
// Try to match by route path
|
|
440
|
+
if (routeModuleName) {
|
|
441
|
+
matchedModule = modules.find(m => m.syme_path?.includes(routeModuleName) ||
|
|
442
|
+
m.syme_title?.toLowerCase().includes(routeModuleName.toLowerCase()) ||
|
|
443
|
+
routeModuleName.includes(m.syme_path || '') ||
|
|
444
|
+
m.syme_path === routeModuleName);
|
|
445
|
+
if (matchedModule) {
|
|
446
|
+
console.log('✅ SIDEBAR SYNC: Matched module by route:', matchedModule.syme_title);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
// If not found, try to match by page code pattern
|
|
450
|
+
if (!matchedModule && pageCode) {
|
|
451
|
+
matchedModule = modules.find(m => pageCode.includes(m.syme_path || '') ||
|
|
452
|
+
(m.syme_path && pageCode.toLowerCase().includes(m.syme_path.toLowerCase())) ||
|
|
453
|
+
m.syme_path === pageCode);
|
|
454
|
+
if (matchedModule) {
|
|
455
|
+
console.log('✅ SIDEBAR SYNC: Matched module by page code:', matchedModule.syme_title);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
// If still not found, try partial matching for common patterns
|
|
459
|
+
if (!matchedModule) {
|
|
460
|
+
// Try to match common patterns like 'admin', 'dashboard', etc.
|
|
461
|
+
const searchTerms = [routeModuleName, pageCode].filter(Boolean);
|
|
462
|
+
for (const term of searchTerms) {
|
|
463
|
+
matchedModule = modules.find(m => m.syme_title?.toLowerCase().includes(term.toLowerCase()) ||
|
|
464
|
+
term.toLowerCase().includes(m.syme_title?.toLowerCase() || '') ||
|
|
465
|
+
m.syme_path?.toLowerCase().includes(term.toLowerCase()) ||
|
|
466
|
+
term.toLowerCase().includes(m.syme_path?.toLowerCase() || ''));
|
|
467
|
+
if (matchedModule) {
|
|
468
|
+
console.log('✅ SIDEBAR SYNC: Matched module by pattern:', matchedModule.syme_title, 'for term:', term);
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
// Check if we should set the matched module as active
|
|
474
|
+
if (matchedModule) {
|
|
475
|
+
const currentActiveModule = this.appState.getActiveModule();
|
|
476
|
+
// Be more conservative about overriding user selections
|
|
477
|
+
// Only set the module if no module is currently active
|
|
478
|
+
const shouldSetModule = !currentActiveModule;
|
|
479
|
+
if (shouldSetModule) {
|
|
480
|
+
console.log('🎯 SIDEBAR SYNC: No active module, setting:', matchedModule.syme_title, matchedModule._id);
|
|
481
|
+
this.appState.setActiveModule(matchedModule);
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
console.log('✅ SIDEBAR SYNC: Module already active, respecting user selection:', currentActiveModule?.syme_title);
|
|
485
|
+
console.log('🔍 SIDEBAR SYNC: Route suggests:', matchedModule.syme_title, '- not overriding');
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
console.log('⚠️ SIDEBAR SYNC: No matching module found for page:', pageCode);
|
|
490
|
+
console.log('🔍 SIDEBAR SYNC: Available modules:', modules.map(m => m.syme_title).join(', '));
|
|
491
|
+
console.log('🔍 SIDEBAR SYNC: Searched for route:', routeModuleName, 'and page code:', pageCode);
|
|
492
|
+
}
|
|
493
|
+
},
|
|
494
|
+
error: (err) => {
|
|
495
|
+
console.error('❌ SIDEBAR SYNC: Error loading modules for sync:', err);
|
|
496
|
+
}
|
|
497
|
+
});
|
|
22
498
|
}
|
|
23
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideLytSharedService, deps: [
|
|
499
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideLytSharedService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
24
500
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideLytSharedService, providedIn: 'root' }); }
|
|
25
501
|
}
|
|
26
502
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideLytSharedService, decorators: [{
|
|
@@ -28,5 +504,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImpor
|
|
|
28
504
|
args: [{
|
|
29
505
|
providedIn: 'root'
|
|
30
506
|
}]
|
|
31
|
-
}], ctorParameters: () => [
|
|
32
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jbG91ZC1pZGUtbGF5b3V0L3NyYy9saWIvbGF5b3V0L3NoYXJlZC9zaGFyZWQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxRQUFRLEVBQWtDLHFCQUFxQixFQUFFLG9CQUFvQixFQUFpQixNQUFNLHFCQUFxQixDQUFDOzs7OztBQVMzSSxNQUFNLE9BQU8sb0JBQW9CO0lBRS9CLFlBQW9CLGNBQW1DLEVBQVUsSUFBZ0IsRUFBUyxZQUFtQjtRQUF6RixtQkFBYyxHQUFkLGNBQWMsQ0FBcUI7UUFBVSxTQUFJLEdBQUosSUFBSSxDQUFZO1FBQVMsaUJBQVksR0FBWixZQUFZLENBQU87SUFDN0csQ0FBQztJQUVELFlBQVksQ0FBQyxJQUFtQjtRQUM5QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxFQUFFLHFCQUFxQixFQUFFLFdBQVcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUErQyxDQUFDO0lBQ3BNLENBQUM7SUFFRCxXQUFXLENBQUMsa0JBQWtEO1FBQzVELElBQUksa0JBQWtCLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFDO1lBQ3ZDLG9CQUFvQjtZQUNwQixJQUFJLENBQUMsY0FBYyxDQUFDLGlCQUFpQixHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLGlCQUFpQixFQUFFLEdBQUcsa0JBQWtCLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFDO1lBQzVILElBQUksQ0FBQyxjQUFjLENBQUMsNEJBQTRCLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQy9ELENBQUM7SUFDSCxDQUFDOzhHQWZVLG9CQUFvQjtrSEFBcEIsb0JBQW9CLGNBRm5CLE1BQU07OzJGQUVQLG9CQUFvQjtrQkFIaEMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IGNpZGVQYXRoLCBkZXNpZ25Db25maWdDb250cm9sbGVyUmVzcG9uc2UsIGRlc2lnbkNvbmZpZ1JvdXRlc1VybCwgaG9zdE1hbmFnZXJSb3V0ZXNVcmwsIE1EZXNpZ25Db25maWcgfSBmcm9tICdjbG91ZC1pZGUtbG1zLW1vZGVsJztcclxuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBUaXRsZSB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xyXG5pbXBvcnQgeyBDaWRlRWxlbWVudHNTZXJ2aWNlIH0gZnJvbSAnY2xvdWQtaWRlLWVsZW1lbnQnO1xyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290J1xyXG59KVxyXG5leHBvcnQgY2xhc3MgQ2lkZUx5dFNoYXJlZFNlcnZpY2Uge1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZW1lbnRTZXJ2aWNlOiBDaWRlRWxlbWVudHNTZXJ2aWNlLCBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsIHB1YmxpYyB0aXRsZVNlcnZpY2U6IFRpdGxlKSB7XHJcbiAgfVxyXG5cclxuICBsb2FkUGFnZURhdGEoYm9keTogTURlc2lnbkNvbmZpZyk6IE9ic2VydmFibGU8ZGVzaWduQ29uZmlnQ29udHJvbGxlclJlc3BvbnNlPiB7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QoY2lkZVBhdGguam9pbihbaG9zdE1hbmFnZXJSb3V0ZXNVcmwuY2lkZVN1aXRlSG9zdCwgZGVzaWduQ29uZmlnUm91dGVzVXJsPy5tb2R1bGUsIGRlc2lnbkNvbmZpZ1JvdXRlc1VybD8uZ2V0UGFnZURhdGFdKSwgYm9keSkgYXMgT2JzZXJ2YWJsZTxkZXNpZ25Db25maWdDb250cm9sbGVyUmVzcG9uc2U+O1xyXG4gIH1cclxuXHJcbiAgc2V0UGFnZURhdGEocGFnZV9kYXRhX3Jlc3BvbnNlOiBkZXNpZ25Db25maWdDb250cm9sbGVyUmVzcG9uc2UpIHtcclxuICAgIGlmIChwYWdlX2RhdGFfcmVzcG9uc2U/LmRhdGE/LmNvbnRyb2xzKSB7XHJcbiAgICAgIC8vIFNldCBjb250cm9scyBoZXJlXHJcbiAgICAgIHRoaXMuZWxlbWVudFNlcnZpY2UuY2lkZV9lbGVtZW50X2RhdGEgPSB7IC4uLnRoaXMuZWxlbWVudFNlcnZpY2UuY2lkZV9lbGVtZW50X2RhdGEsIC4uLnBhZ2VfZGF0YV9yZXNwb25zZT8uZGF0YT8uY29udHJvbHMgfTtcclxuICAgICAgdGhpcy5lbGVtZW50U2VydmljZS5pc19jaWRlX2VsZW1lbnRfZGF0YV91cGRhdGVkPy5uZXh0KHRydWUpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iXX0=
|
|
507
|
+
}], ctorParameters: () => [] });
|
|
508
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jbG91ZC1pZGUtbGF5b3V0L3NyYy9saWIvbGF5b3V0L3NoYXJlZC9zaGFyZWQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxRQUFRLEVBQWtDLHFCQUFxQixFQUFFLG9CQUFvQixFQUE4QixNQUFNLHFCQUFxQixDQUFDO0FBQ3hKLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQWMsRUFBRSxFQUFFLFVBQVUsRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDaEUsT0FBTyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM1RSxPQUFPLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUVuRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUM1RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxtREFBbUQs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QUNOLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUVBQW1FLEVBQUUsbUJBQW1CLEVBQUUsVUFBVSxDQUFDLENBQUM7d0JBQ2xILE9BQU8sQ0FBQyxHQUFHLENBQUMsa0NBQWtDLEVBQUUsYUFBYSxDQUFDLFVBQVUsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO29CQUNoRyxDQUFDO2dCQUNILENBQUM7cUJBQU0sQ0FBQztvQkFDTixPQUFPLENBQUMsR0FBRyxDQUFDLHFEQUFxRCxFQUFFLFFBQVEsQ0FBQyxDQUFDO29CQUM3RSxPQUFPLENBQUMsR0FBRyxDQUFDLHFDQUFxQyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQzlGLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0NBQXNDLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUNuRyxDQUFDO1lBQ0gsQ0FBQztZQUNELEtBQUssRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUNiLE9BQU8sQ0FBQyxLQUFLLENBQUMsaURBQWlELEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDeEUsQ0FBQztTQUNGLENBQUMsQ0FBQztJQUNQLENBQUM7OEdBdmxCVSxvQkFBb0I7a0hBQXBCLG9CQUFvQixjQUZuQixNQUFNOzsyRkFFUCxvQkFBb0I7a0JBSGhDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0LCBzaWduYWwsIGNvbXB1dGVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBjaWRlUGF0aCwgZGVzaWduQ29uZmlnQ29udHJvbGxlclJlc3BvbnNlLCBkZXNpZ25Db25maWdSb3V0ZXNVcmwsIGhvc3RNYW5hZ2VyUm91dGVzVXJsLCBJU3l0bUxheW91dCwgTURlc2lnbkNvbmZpZyB9IGZyb20gJ2Nsb3VkLWlkZS1sbXMtbW9kZWwnO1xuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mLCB0aHJvd0Vycm9yLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRhcCwgY2F0Y2hFcnJvciwgc2hhcmVSZXBsYXksIGZpbHRlciwgdGFrZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFJvdXRlciwgTmF2aWdhdGlvbkVuZCB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBUaXRsZSB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHsgQ2lkZUVsZW1lbnRzU2VydmljZSB9IGZyb20gJ2Nsb3VkLWlkZS1lbGVtZW50JztcbmltcG9ydCB7IENpZGVMeXRTaWRlYmFyU2VydmljZSB9IGZyb20gJy4uL3NpZGViYXIvc2lkZWJhci5zZXJ2aWNlJztcbmltcG9ydCB7IENpZGVMeXRTaGFyZWRXcmFwcGVyU2V0dXBQYXJhbSB9IGZyb20gJy4vc2hhcmVkLXdyYXBwZXIvc2hhcmVkLXdyYXBwZXIuY29tcG9uZW50JztcbmltcG9ydCB7IENpZGVMeXRIZWFkZXJTZXJ2aWNlIH0gZnJvbSAnLi4vaGVhZGVyL2hlYWRlci5zZXJ2aWNlJztcbmltcG9ydCB7IENpZGVMeXRGb290ZXJTZXJ2aWNlIH0gZnJvbSAnLi4vZm9vdGVyL2Zvb3Rlci5zZXJ2aWNlJztcbmltcG9ydCB7IENpZGVMeXRDb25zb2xlU2VydmljZSB9IGZyb20gJy4uL2NvbnNvbGUvY29uc29sZS5zZXJ2aWNlJztcbmltcG9ydCB7IENpZGVMeXRTaWRlZHJhd2VyU2VydmljZSB9IGZyb20gJy4uL3NpZGVkcmF3ZXIvc2lkZWRyYXdlci5zZXJ2aWNlJztcbmltcG9ydCB7IEFwcFN0YXRlSGVscGVyU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2FwcC1zdGF0ZS9hcHAtc3RhdGUtaGVscGVyLnNlcnZpY2UnO1xuXG4vLyBFbmhhbmNlZCBjYWNoZSBpbnRlcmZhY2Ugd2l0aCBUVEwgc3VwcG9ydFxuaW50ZXJmYWNlIENhY2hlZFBhZ2VEYXRhIHtcbiAgcmVxdWVzdDogUGFydGlhbDxDaWRlTHl0U2hhcmVkV3JhcHBlclNldHVwUGFyYW0+O1xuICByZXNwb25zZTogZGVzaWduQ29uZmlnQ29udHJvbGxlclJlc3BvbnNlO1xuICB0aW1lc3RhbXA6IG51bWJlcjtcbiAgdHRsOiBudW1iZXI7IC8vIFRpbWUgdG8gbGl2ZSBpbiBtaWxsaXNlY29uZHNcbn1cblxuLy8gTG9hZGluZyBzdGF0ZSB0cmFja2luZ1xudHlwZSBMb2FkaW5nU3RhdGUgPSB7IFtrZXk6IHN0cmluZ106IE9ic2VydmFibGU8ZGVzaWduQ29uZmlnQ29udHJvbGxlclJlc3BvbnNlPiB9O1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBDaWRlTHl0U2hhcmVkU2VydmljZSB7XG4gIC8vIEVuaGFuY2VkIHJlYWN0aXZlIGNhY2hlIHdpdGggc2lnbmFsc1xuICBwcml2YXRlIHBhZ2VEYXRhQ2FjaGVTaWduYWwgPSBzaWduYWw8eyBba2V5OiBzdHJpbmddOiBDYWNoZWRQYWdlRGF0YSB9Pih7fSk7XG4gIHByaXZhdGUgbG9hZGluZ1N0YXRlU2lnbmFsID0gc2lnbmFsPHsgW2tleTogc3RyaW5nXTogYm9vbGVhbiB9Pih7fSk7XG4gIFxuICAvLyBQdWJsaWMgcmVhZG9ubHkgYWNjZXNzIHRvIGNhY2hlXG4gIHB1YmxpYyByZWFkb25seSBwYWdlRGF0YUNhY2hlID0gdGhpcy5wYWdlRGF0YUNhY2hlU2lnbmFsLmFzUmVhZG9ubHkoKTtcbiAgcHVibGljIHJlYWRvbmx5IGxvYWRpbmdTdGF0ZXMgPSB0aGlzLmxvYWRpbmdTdGF0ZVNpZ25hbC5hc1JlYWRvbmx5KCk7XG4gIFxuICAvLyBDb21wdXRlZCBzaWduYWwgZm9yIGNhY2hlIHN0YXR1c1xuICBwdWJsaWMgcmVhZG9ubHkgY2FjaGVJbmZvID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGNhY2hlID0gdGhpcy5wYWdlRGF0YUNhY2hlU2lnbmFsKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRvdGFsQ2FjaGVkOiBPYmplY3Qua2V5cyhjYWNoZSkubGVuZ3RoLFxuICAgICAgdmFsaWRDYWNoZWQ6IE9iamVjdC52YWx1ZXMoY2FjaGUpLmZpbHRlcihpdGVtID0+IHRoaXMuaXNDYWNoZVZhbGlkKGl0ZW0pKS5sZW5ndGgsXG4gICAgICBleHBpcmVkQ2FjaGVkOiBPYmplY3QudmFsdWVzKGNhY2hlKS5maWx0ZXIoaXRlbSA9PiAhdGhpcy5pc0NhY2hlVmFsaWQoaXRlbSkpLmxlbmd0aFxuICAgIH07XG4gIH0pO1xuICBcbiAgLy8gSW4tZmxpZ2h0IHJlcXVlc3RzIHRvIHByZXZlbnQgZHVwbGljYXRlIEFQSSBjYWxsc1xuICBwcml2YXRlIGluZmxpZ2h0UmVxdWVzdHM6IExvYWRpbmdTdGF0ZSA9IHt9O1xuICBcbiAgLy8gRGVmYXVsdCBjYWNoZSBUVEwgKDUgbWludXRlcylcbiAgcHJpdmF0ZSByZWFkb25seSBERUZBVUxUX0NBQ0hFX1RUTCA9IDUgKiA2MCAqIDEwMDA7XG4gIFxuICAvLyBNb2Rlcm4gQW5ndWxhciB2MjAgZGVwZW5kZW5jeSBpbmplY3Rpb24gcGF0dGVyblxuICBwcml2YXRlIGVsZW1lbnRTZXJ2aWNlID0gaW5qZWN0KENpZGVFbGVtZW50c1NlcnZpY2UpO1xuICBwcml2YXRlIGh0dHAgPSBpbmplY3QoSHR0cENsaWVudCk7XG4gIHB1YmxpYyB0aXRsZVNlcnZpY2UgPSBpbmplY3QoVGl0bGUpO1xuICBwcml2YXRlIHNpZGViYXJTZXJ2aWNlID0gaW5qZWN0KENpZGVMeXRTaWRlYmFyU2VydmljZSk7XG4gIHByaXZhdGUgaGVhZGVyU2VydmljZSA9IGluamVjdChDaWRlTHl0SGVhZGVyU2VydmljZSk7XG4gIHByaXZhdGUgZm9vdGVyU2VydmljZSA9IGluamVjdChDaWRlTHl0Rm9vdGVyU2VydmljZSk7XG4gIHByaXZhdGUgY29uc29sZVNlcnZpY2UgPSBpbmplY3QoQ2lkZUx5dENvbnNvbGVTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBzaWRlZHJhd2VyU2VydmljZSA9IGluamVjdChDaWRlTHl0U2lkZWRyYXdlclNlcnZpY2UpO1xuICBwcml2YXRlIHJvdXRlciA9IGluamVjdChSb3V0ZXIpO1xuICBcbiAgLy8gSW1wb3J0IEFwcFN0YXRlSGVscGVyU2VydmljZSBmb3Igc2lkZWJhciBzeW5jXG4gIHByaXZhdGUgYXBwU3RhdGUgPSBpbmplY3QoQXBwU3RhdGVIZWxwZXJTZXJ2aWNlKTtcbiAgXG4gIC8vIFJvdXRlIGNoYW5nZSBzdWJzY3JpcHRpb24gZm9yIGNsZWFudXBcbiAgcHJpdmF0ZSByb3V0ZVN1YnNjcmlwdGlvbj86IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSBwYWdlRGF0YVN1YnNjcmlwdGlvbj86IFN1YnNjcmlwdGlvbjtcbiAgXG4gIC8vIFRhYiBtYW5hZ2VtZW50IGNhbGxiYWNrIC0gdG8gYXZvaWQgY2lyY3VsYXIgZGVwZW5kZW5jeVxuICBwcml2YXRlIHRhYk1hbmFnZW1lbnRDYWxsYmFjaz86IChcbiAgICBjdXJyZW50Um91dGVQYXRoOiBzdHJpbmcsXG4gICAgcXVlcnlQYXJhbXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgIGxheW91dDogSVN5dG1MYXlvdXQsXG4gICAgcGFnZURhdGE6IGRlc2lnbkNvbmZpZ0NvbnRyb2xsZXJSZXNwb25zZSxcbiAgICBwYWdlQ29kZTogc3RyaW5nXG4gICkgPT4gdm9pZDtcbiAgXG4gIC8vIFJlcXVlc3QgdmlzaWJpbGl0eSBjYWxsYmFja1xuICBwcml2YXRlIHJlcXVlc3RWaXNpYmlsaXR5Q2FsbGJhY2s/OiAoc2hvdzogYm9vbGVhbikgPT4gdm9pZDtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvLyBDbGVhbiB1cCBleHBpcmVkIGNhY2hlIGVudHJpZXMgZXZlcnkgbWludXRlXG4gICAgLy8gc2V0SW50ZXJ2YWwoKCkgPT4gdGhpcy5jbGVhbkV4cGlyZWRDYWNoZSgpLCA2MDAwMCk7XG4gICAgXG4gICAgLy8gTGlzdGVuIHRvIHJvdXRlIGNoYW5nZXMgLSBtb3ZlZCBmcm9tIHJlcXVlc3Qgc2VydmljZVxuICAgIHRoaXMucm91dGVTdWJzY3JpcHRpb24gPSB0aGlzLnJvdXRlci5ldmVudHMucGlwZShcbiAgICAgIGZpbHRlcihldmVudCA9PiBldmVudCBpbnN0YW5jZW9mIE5hdmlnYXRpb25FbmQpXG4gICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgLy8gQ2FuY2VsIGFueSBvbmdvaW5nIHBhZ2UgZGF0YSBmZXRjaGluZ1xuICAgICAgdGhpcy5wYWdlRGF0YVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMuaGFuZGxlUm91dGVDaGFuZ2UoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciB0YWIgbWFuYWdlbWVudCBjYWxsYmFjayBmcm9tIHJlcXVlc3Qgc2VydmljZVxuICAgKiBUaGlzIGFsbG93cyBzaGFyZWQgc2VydmljZSB0byBjYWxsIHJlcXVlc3Qgc2VydmljZSB3aXRob3V0IGNpcmN1bGFyIGRlcGVuZGVuY3lcbiAgICovXG4gIHJlZ2lzdGVyVGFiTWFuYWdlbWVudChjYWxsYmFjazogKFxuICAgIGN1cnJlbnRSb3V0ZVBhdGg6IHN0cmluZyxcbiAgICBxdWVyeVBhcmFtczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgbGF5b3V0OiBJU3l0bUxheW91dCxcbiAgICBwYWdlRGF0YTogZGVzaWduQ29uZmlnQ29udHJvbGxlclJlc3BvbnNlLFxuICAgIHBhZ2VDb2RlOiBzdHJpbmdcbiAgKSA9PiB2b2lkKSB7XG4gICAgdGhpcy50YWJNYW5hZ2VtZW50Q2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICBjb25zb2xlLmxvZygn4pyFIFRhYiBtYW5hZ2VtZW50IGNhbGxiYWNrIHJlZ2lzdGVyZWQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciByZXF1ZXN0IHZpc2liaWxpdHkgY2FsbGJhY2sgZnJvbSByZXF1ZXN0IHNlcnZpY2VcbiAgICogVGhpcyBhbGxvd3Mgc2hhcmVkIHNlcnZpY2UgdG8gY29udHJvbCByZXF1ZXN0IHdyYXBwZXIgdmlzaWJpbGl0eVxuICAgKi9cbiAgcmVnaXN0ZXJSZXF1ZXN0VmlzaWJpbGl0eShjYWxsYmFjazogKHNob3c6IGJvb2xlYW4pID0+IHZvaWQpIHtcbiAgICB0aGlzLnJlcXVlc3RWaXNpYmlsaXR5Q2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICBjb25zb2xlLmxvZygn4pyFIFJlcXVlc3QgdmlzaWJpbGl0eSBjYWxsYmFjayByZWdpc3RlcmVkJyk7XG4gIH1cblxuICAvKipcbiAgICogRW5oYW5jZWQgbG9hZFBhZ2VEYXRhIHdpdGggY2FjaGluZyBhbmQgZGVkdXBsaWNhdGlvblxuICAgKiBAcGFyYW0gYm9keSAtIFJlcXVlc3QgcGF5bG9hZFxuICAgKiBAcGFyYW0gZm9yY2VSZWZyZXNoIC0gRm9yY2UgQVBJIGNhbGwgZXZlbiBpZiBjYWNoZWQgZGF0YSBleGlzdHNcbiAgICogQHBhcmFtIGN1c3RvbVRUTCAtIEN1c3RvbSBjYWNoZSBUVEwgaW4gbWlsbGlzZWNvbmRzXG4gICAqL1xuICBsb2FkUGFnZURhdGEoXG4gICAgYm9keTogTURlc2lnbkNvbmZpZywgXG4gICAgZm9yY2VSZWZyZXNoOiBib29sZWFuID0gZmFsc2UsIFxuICAgIGN1c3RvbVRUTDogbnVtYmVyID0gdGhpcy5ERUZBVUxUX0NBQ0hFX1RUTFxuICApOiBPYnNlcnZhYmxlPGRlc2lnbkNvbmZpZ0NvbnRyb2xsZXJSZXNwb25zZT4ge1xuICAgIGNvbnN0IHBhZ2VDb2RlID0gYm9keS5zeXBnX3BhZ2VfY29kZT8udG9TdHJpbmcoKSB8fCAnJztcbiAgICBcbiAgICBpZiAoIXBhZ2VDb2RlKSB7XG4gICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgRXJyb3IoJ1BhZ2UgY29kZSBpcyByZXF1aXJlZCcpKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIHZhbGlkIGNhY2hlZCBkYXRhIGFuZCBub3QgZm9yY2luZyByZWZyZXNoXG4gICAgaWYgKCFmb3JjZVJlZnJlc2ggJiYgdGhpcy5oYXNWYWxpZENhY2hlKHBhZ2VDb2RlKSkge1xuICAgICAgY29uc29sZS5sb2coYPCflIQgQ0FDSEUgSElUOiBVc2luZyBjYWNoZWQgZGF0YSBmb3IgcGFnZSBjb2RlOiAke3BhZ2VDb2RlfWApO1xuICAgICAgY29uc3QgY2FjaGVkRGF0YSA9IHRoaXMucGFnZURhdGFDYWNoZVNpZ25hbCgpW3BhZ2VDb2RlXTtcbiAgICAgIHJldHVybiBvZihjYWNoZWREYXRhLnJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiB0aGVyZSdzIGFscmVhZHkgYW4gaW4tZmxpZ2h0IHJlcXVlc3QgZm9yIHRoaXMgcGFnZSBjb2RlXG4gICAgaWYgKHRoaXMuaW5mbGlnaHRSZXF1ZXN0c1twYWdlQ29kZV0pIHtcbiAgICAgIGNvbnNvbGUubG9nKGDwn5SEIElORkxJR0hUIFJFUVVFU1Q6IFJldHVybmluZyBleGlzdGluZyByZXF1ZXN0IGZvciBwYWdlIGNvZGU6ICR7cGFnZUNvZGV9YCk7XG4gICAgICByZXR1cm4gdGhpcy5pbmZsaWdodFJlcXVlc3RzW3BhZ2VDb2RlXTtcbiAgICB9XG5cbiAgICAvLyBTZXQgbG9hZGluZyBzdGF0ZVxuICAgIHRoaXMuc2V0TG9hZGluZ1N0YXRlKHBhZ2VDb2RlLCB0cnVlKTtcblxuICAgIGNvbnNvbGUubG9nKGDwn4yQIEFQSSBDQUxMOiBMb2FkaW5nIGZyZXNoIGRhdGEgZm9yIHBhZ2UgY29kZTogJHtwYWdlQ29kZX1gKTtcbiAgICBcbiAgICAvLyBDcmVhdGUgbmV3IEFQSSByZXF1ZXN0XG4gICAgY29uc3QgcmVxdWVzdCQgPSB0aGlzLmh0dHAucG9zdChcbiAgICAgIGNpZGVQYXRoLmpvaW4oW2hvc3RNYW5hZ2VyUm91dGVzVXJsLmNpZGVTdWl0ZUhvc3QsIGRlc2lnbkNvbmZpZ1JvdXRlc1VybD8ubW9kdWxlLCBkZXNpZ25Db25maWdSb3V0ZXNVcmw/LmdldFBhZ2VEYXRhXSksIFxuICAgICAgYm9keVxuICAgICkgYXMgT2JzZXJ2YWJsZTxkZXNpZ25Db25maWdDb250cm9sbGVyUmVzcG9uc2U+O1xuXG4gICAgLy8gQ2FjaGUgdGhlIG9ic2VydmFibGUgdG8gcHJldmVudCBkdXBsaWNhdGUgcmVxdWVzdHNcbiAgICB0aGlzLmluZmxpZ2h0UmVxdWVzdHNbcGFnZUNvZGVdID0gcmVxdWVzdCQucGlwZShcbiAgICAgIHRhcChyZXNwb25zZSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKGDinIUgQVBJIFNVQ0NFU1M6IENhY2hpbmcgZGF0YSBmb3IgcGFnZSBjb2RlOiAke3BhZ2VDb2RlfWApO1xuICAgICAgICB0aGlzLmNhY2hlUGFnZURhdGEocGFnZUNvZGUsIGJvZHksIHJlc3BvbnNlLCBjdXN0b21UVEwpO1xuICAgICAgICB0aGlzLnNldExvYWRpbmdTdGF0ZShwYWdlQ29kZSwgZmFsc2UpO1xuICAgICAgfSksXG4gICAgICBjYXRjaEVycm9yKGVycm9yID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcihg4p2MIEFQSSBFUlJPUjogRmFpbGVkIHRvIGxvYWQgZGF0YSBmb3IgcGFnZSBjb2RlOiAke3BhZ2VDb2RlfWAsIGVycm9yKTtcbiAgICAgICAgdGhpcy5zZXRMb2FkaW5nU3RhdGUocGFnZUNvZGUsIGZhbHNlKTtcbiAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xuICAgICAgfSksXG4gICAgICBzaGFyZVJlcGxheSgxKSAvLyBTaGFyZSB0aGUgcmVzdWx0IHdpdGggbXVsdGlwbGUgc3Vic2NyaWJlcnNcbiAgICApO1xuXG4gICAgLy8gQ2xlYW4gdXAgaW5mbGlnaHQgcmVxdWVzdCBhZnRlciBjb21wbGV0aW9uXG4gICAgdGhpcy5pbmZsaWdodFJlcXVlc3RzW3BhZ2VDb2RlXS5zdWJzY3JpYmUoe1xuICAgICAgY29tcGxldGU6ICgpID0+IHtcbiAgICAgICAgZGVsZXRlIHRoaXMuaW5mbGlnaHRSZXF1ZXN0c1twYWdlQ29kZV07XG4gICAgICB9LFxuICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgZGVsZXRlIHRoaXMuaW5mbGlnaHRSZXF1ZXN0c1twYWdlQ29kZV07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5pbmZsaWdodFJlcXVlc3RzW3BhZ2VDb2RlXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zb2xpZGF0ZWQgbWV0aG9kIHRvIGxvYWQgYW5kIHByb2Nlc3MgcGFnZSBkYXRhXG4gICAqIFRoaXMgcmVwbGFjZXMgdGhlIHNlcGFyYXRlIGNhbGxzIGluIHJlcXVlc3Qgc2VydmljZSBhbmQgc2hhcmVkIHdyYXBwZXJcbiAgICovXG4gIGxvYWRBbmRQcm9jZXNzUGFnZURhdGEoXG4gICAgYm9keTogTURlc2lnbkNvbmZpZywgXG4gICAgb3B0aW9uczoge1xuICAgICAgZm9yY2VSZWZyZXNoPzogYm9vbGVhbjtcbiAgICAgIGN1c3RvbVRUTD86IG51bWJlcjtcbiAgICAgIHNldFRpdGxlPzogYm9vbGVhbjtcbiAgICAgIHNldFNpZGViYXJDb250ZXh0PzogYm9vbGVhbjtcbiAgICAgIHVwZGF0ZUxheW91dD86IGJvb2xlYW47XG4gICAgfSA9IHt9XG4gICk6IE9ic2VydmFibGU8ZGVzaWduQ29uZmlnQ29udHJvbGxlclJlc3BvbnNlPiB7XG4gICAgY29uc3Qge1xuICAgICAgZm9yY2VSZWZyZXNoID0gZmFsc2UsXG4gICAgICBjdXN0b21UVEwgPSB0aGlzLkRFRkFVTFRfQ0FDSEVfVFRMLFxuICAgICAgc2V0VGl0bGUgPSB0cnVlLFxuICAgICAgc2V0U2lkZWJhckNvbnRleHQgPSB0cnVlLFxuICAgICAgdXBkYXRlTGF5b3V0ID0gdHJ1ZVxuICAgIH0gPSBvcHRpb25zO1xuXG4gICAgcmV0dXJuIHRoaXMubG9hZFBhZ2VEYXRhKGJvZHksIGZvcmNlUmVmcmVzaCwgY3VzdG9tVFRMKS5waXBlKFxuICAgICAgdGFwKHJlc3BvbnNlID0+IHtcbiAgICAgICAgaWYgKHJlc3BvbnNlKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ/CflI0gU0hBUkVEIFNFUlZJQ0U6IGxvYWRBbmRQcm9jZXNzUGFnZURhdGEnLCByZXNwb25zZSk7XG4gICAgICAgICAgLy8gUHJvY2VzcyB0aGUgcmVzcG9uc2VcbiAgICAgICAgICBpZiAodXBkYXRlTGF5b3V0KSB7XG4gICAgICAgICAgICB0aGlzLnNldFBhZ2VEYXRhKHJlc3BvbnNlLCBib2R5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gU2V0IHBhZ2UgdGl0bGVcbiAgICAgICAgICBpZiAoc2V0VGl0bGUgJiYgcmVzcG9uc2UuZGF0YT8ucGFnZT8uc3lwZ190aXRsZSkge1xuICAgICAgICAgICAgdGhpcy50aXRsZVNlcnZpY2Uuc2V0VGl0bGUocmVzcG9uc2UuZGF0YS5wYWdlLnN5cGdfdGl0bGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBcbiAgICAgICAgICAvLyBTZXQgc2lkZWJhciBjb250ZXh0XG4gICAgICAgICAgaWYgKHNldFNpZGViYXJDb250ZXh0KSB7XG4gICAgICAgICAgICAvLyBUaGlzIHdpbGwgYmUgaGFuZGxlZCBieSB0aGUgY29tcG9uZW50IHRoYXQgbmVlZHMgdGhlIGNvbnRleHRcbiAgICAgICAgICAgIC8vIGFzIGl0J3Mgc3BlY2lmaWMgdG8gdGhlIHNpZGVkcmF3ZXIgc2VydmljZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjYWNoZWQgcGFnZSBkYXRhIHdpdGhvdXQgbWFraW5nIEFQSSBjYWxsXG4gICAqL1xuICBnZXRDYWNoZWRQYWdlRGF0YShwYWdlQ29kZTogc3RyaW5nKTogZGVzaWduQ29uZmlnQ29udHJvbGxlclJlc3BvbnNlIHwgbnVsbCB7XG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5wYWdlRGF0YUNhY2hlU2lnbmFsKClbcGFnZUNvZGVdO1xuICAgIHJldHVybiB0aGlzLmlzQ2FjaGVWYWxpZChjYWNoZWQpID8gY2FjaGVkLnJlc3BvbnNlIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBsb2FkaW5nIGZvciBhIHNwZWNpZmljIHBhZ2UgY29kZVxuICAgKi9cbiAgaXNMb2FkaW5nKHBhZ2VDb2RlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sb2FkaW5nU3RhdGVzKClbcGFnZUNvZGVdIHx8IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEludmFsaWRhdGUgY2FjaGUgZm9yIHNwZWNpZmljIHBhZ2UgY29kZVxuICAgKi9cbiAgaW52YWxpZGF0ZUNhY2hlKHBhZ2VDb2RlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjYWNoZSA9IHsgLi4udGhpcy5wYWdlRGF0YUNhY2hlU2lnbmFsKCkgfTtcbiAgICBkZWxldGUgY2FjaGVbcGFnZUNvZGVdO1xuICAgIHRoaXMucGFnZURhdGFDYWNoZVNpZ25hbC5zZXQoY2FjaGUpO1xuICAgIGNvbnNvbGUubG9nKGDwn5eR77iPIENBQ0hFIElOVkFMSURBVEVEOiBSZW1vdmVkIGNhY2hlIGZvciBwYWdlIGNvZGU6ICR7cGFnZUNvZGV9YCk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgYWxsIGNhY2hlZCBkYXRhXG4gICAqL1xuICBjbGVhckFsbENhY2hlKCk6IHZvaWQge1xuICAgIHRoaXMucGFnZURhdGFDYWNoZVNpZ25hbC5zZXQoe30pO1xuICAgIHRoaXMubG9hZGluZ1N0YXRlU2lnbmFsLnNldCh7fSk7XG4gICAgY29uc29sZS5sb2coJ/Cfl5HvuI8gQ0FDSEUgQ0xFQVJFRDogQWxsIGNhY2hlZCBkYXRhIHJlbW92ZWQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcmVsb2FkIHBhZ2UgZGF0YSBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlXG4gICAqL1xuICBwcmVsb2FkUGFnZURhdGEocGFnZUNvZGVzOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIHBhZ2VDb2Rlcy5mb3JFYWNoKHBhZ2VDb2RlID0+IHtcbiAgICAgIGlmICghdGhpcy5oYXNWYWxpZENhY2hlKHBhZ2VDb2RlKSAmJiAhdGhpcy5pc0xvYWRpbmcocGFnZUNvZGUpKSB7XG4gICAgICAgIHRoaXMubG9hZFBhZ2VEYXRhKHsgc3lwZ19wYWdlX2NvZGU6IHBhZ2VDb2RlIH0pLnN1YnNjcmliZSh7XG4gICAgICAgICAgbmV4dDogKCkgPT4gY29uc29sZS5sb2coYPCfmoAgUFJFTE9BREVEOiBQYWdlIGRhdGEgZm9yICR7cGFnZUNvZGV9YCksXG4gICAgICAgICAgZXJyb3I6IChlcnIpID0+IGNvbnNvbGUud2Fybihg4pqg77iPIFBSRUxPQUQgRkFJTEVEOiBDb3VsZCBub3QgcHJlbG9hZCAke3BhZ2VDb2RlfWAsIGVycilcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBQcml2YXRlIGhlbHBlciBtZXRob2RzXG4gIHByaXZhdGUgaGFzVmFsaWRDYWNoZShwYWdlQ29kZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5wYWdlRGF0YUNhY2hlU2lnbmFsKClbcGFnZUNvZGVdO1xuICAgIHJldHVybiBjYWNoZWQgJiYgdGhpcy5pc0NhY2hlVmFsaWQoY2FjaGVkKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNDYWNoZVZhbGlkKGNhY2hlZDogQ2FjaGVkUGFnZURhdGEgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgICBpZiAoIWNhY2hlZCkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiBEYXRlLm5vdygpIC0gY2FjaGVkLnRpbWVzdGFtcCA8IGNhY2hlZC50dGw7XG4gIH1cblxuICBwcml2YXRlIGNhY2hlUGFnZURhdGEoXG4gICAgcGFnZUNvZGU6IHN0cmluZywgXG4gICAgcmVxdWVzdDogTURlc2lnbkNvbmZpZywgXG4gICAgcmVzcG9uc2U6IGRlc2lnbkNvbmZpZ0NvbnRyb2xsZXJSZXNwb25zZSwgXG4gICAgdHRsOiBudW1iZXJcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgY2FjaGUgPSB7IC4uLnRoaXMucGFnZURhdGFDYWNoZVNpZ25hbCgpIH07XG4gICAgY2FjaGVbcGFnZUNvZGVdID0ge1xuICAgICAgcmVxdWVzdCxcbiAgICAgIHJlc3BvbnNlLFxuICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgdHRsXG4gICAgfTtcbiAgICB0aGlzLnBhZ2VEYXRhQ2FjaGVTaWduYWwuc2V0KGNhY2hlKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0TG9hZGluZ1N0YXRlKHBhZ2VDb2RlOiBzdHJpbmcsIGxvYWRpbmc6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBsb2FkaW5nU3RhdGVzID0geyAuLi50aGlzLmxvYWRpbmdTdGF0ZVNpZ25hbCgpIH07XG4gICAgaWYgKGxvYWRpbmcpIHtcbiAgICAgIGxvYWRpbmdTdGF0ZXNbcGFnZUNvZGVdID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVsZXRlIGxvYWRpbmdTdGF0ZXNbcGFnZUNvZGVdO1xuICAgIH1cbiAgICB0aGlzLmxvYWRpbmdTdGF0ZVNpZ25hbC5zZXQobG9hZGluZ1N0YXRlcyk7XG4gIH1cblxuICBwcml2YXRlIGNsZWFuRXhwaXJlZENhY2hlKCk6IHZvaWQge1xuICAgIGNvbnN0IGNhY2hlID0geyAuLi50aGlzLnBhZ2VEYXRhQ2FjaGVTaWduYWwoKSB9O1xuICAgIGxldCBjbGVhbmVkID0gZmFsc2U7XG4gICAgXG4gICAgT2JqZWN0LmtleXMoY2FjaGUpLmZvckVhY2gocGFnZUNvZGUgPT4ge1xuICAgICAgaWYgKCF0aGlzLmlzQ2FjaGVWYWxpZChjYWNoZVtwYWdlQ29kZV0pKSB7XG4gICAgICAgIGRlbGV0ZSBjYWNoZVtwYWdlQ29kZV07XG4gICAgICAgIGNsZWFuZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIFxuICAgIGlmIChjbGVhbmVkKSB7XG4gICAgICB0aGlzLnBhZ2VEYXRhQ2FjaGVTaWduYWwuc2V0KGNhY2hlKTtcbiAgICAgIGNvbnNvbGUubG9nKCfwn6e5IENBQ0hFIENMRUFOVVA6IFJlbW92ZWQgZXhwaXJlZCBjYWNoZSBlbnRyaWVzJyk7XG4gICAgfVxuICB9XG5cbiAgc2V0UGFnZURhdGEocGFnZV9kYXRhX3Jlc3BvbnNlOiBkZXNpZ25Db25maWdDb250cm9sbGVyUmVzcG9uc2UsIHBhZ2VfZGF0YV9wYXlsb2FkOiBQYXJ0aWFsPENpZGVMeXRTaGFyZWRXcmFwcGVyU2V0dXBQYXJhbT4pOiB2b2lkIHtcbiAgICAvLyB0byBzZXQgdGhlIGNvbnRyb2xzIGRhdGEgdG8gdGhlIGVsZW1lbnQgc2VydmljZVxuICAgIGNvbnNvbGUubG9nKCfwn5SNIFNIQVJFRCBTRVJWSUNFOiBzZXRQYWdlRGF0YScsIHBhZ2VfZGF0YV9yZXNwb25zZSwgcGFnZV9kYXRhX3BheWxvYWQpO1xuICAgIGlmIChwYWdlX2RhdGFfcmVzcG9uc2U/LmRhdGE/LmNvbnRyb2xzKSB7XG4gICAgICAvLyBTZXQgY29udHJvbHMgaGVyZVxuICAgICAgdGhpcy5lbGVtZW50U2VydmljZS5jaWRlX2VsZW1lbnRfZGF0YSA9IHsgLi4udGhpcy5lbGVtZW50U2VydmljZS5jaWRlX2VsZW1lbnRfZGF0YSwgLi4ucGFnZV9kYXRhX3Jlc3BvbnNlPy5kYXRhPy5jb250cm9scyB9O1xuICAgICAgdGhpcy5lbGVtZW50U2VydmljZS5pc19jaWRlX2VsZW1lbnRfZGF0YV91cGRhdGVkPy5uZXh0KHRydWUpO1xuICAgIH1cblxuICAgIC8vIHdoaWxlIGRvaW5nIHRoaXMgd2UgbmVlZCB0byB0aGluayBhYm91dCBub3QgdG8gdG91Y2ggaWYgdGhpcyBwYWdlIGlzIG5vdCBwZW5pbmcgaW4gdGhlIHBvcHVwIG9yIGRyb3dlciBpbnN0ZWQgb2YgbWFpbiB3aW5kb3dcbiAgICAvLyBTZXQgdGhlIGxheW91dCBkYXRhXG4gICAgY29uc29sZS5sb2coJ/CflI0gTGF5b3V0IGRhdGE6JywgcGFnZV9kYXRhX3Jlc3BvbnNlKTtcbiAgICBpZiAocGFnZV9kYXRhX3Jlc3BvbnNlPy5kYXRhPy50aGVtZT8uc3l0bV9sYXlvdXQpIHtcbiAgICAgIGNvbnNvbGUubG9nKCfwn5SNIFNJREVCQVIgREVCVUcgLSBMYXlvdXQgZGF0YTonLCBwYWdlX2RhdGFfcmVzcG9uc2U/LmRhdGE/LnRoZW1lPy5zeXRtX2xheW91dCwgcGFnZV9kYXRhX3BheWxvYWQpO1xuICAgICAgLy8gY2hlY2sgaXMgc2lkZWJhciBpcyBoaWRlbiBvciBub3QgKGRlZmF1bHQgaXMgdmlzaWJsZSlcbiAgICAgIGlmIChwYWdlX2RhdGFfcmVzcG9uc2U/LmRhdGE/LnRoZW1lPy5zeXRtX2xheW91dD8uc3l0bV9sYXlvdXRfc2lkZWJhcikge1xuICAgICAgICBjb25zdCBzaWRlYmFyU3RhdHVzID0gcGFnZV9kYXRhX3Jlc3BvbnNlPy5kYXRhPy50aGVtZT8uc3l0bV9sYXlvdXQ/LnN5dG1fbGF5b3V0X3NpZGViYXI/LnN0YXR1cztcbiAgICAgICAgY29uc29sZS5sb2coJ/CflI0gU0lERUJBUiBERUJVRyAtIFNpZGViYXIgc3RhdHVzIGZvdW5kOicsIHNpZGViYXJTdGF0dXMpO1xuICAgICAgICBpZiAoIXNpZGViYXJTdGF0dXMpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygn8J+aqyBTSURFQkFSIERFQlVHIC0gSGlkaW5nIHNpZGViYXIgYmVjYXVzZSBzdGF0dXMgaXMgZmFsc2UnKTtcbiAgICAgICAgICB0aGlzLnNpZGViYXJTZXJ2aWNlLmhpZGVTaWRlYmFyKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ+KchSBTSURFQkFSIERFQlVHIC0gU2hvd2luZyBzaWRlYmFyIGJlY2F1c2Ugc3RhdHVzIGlzIHRydWUnKTtcbiAgICAgICAgICB0aGlzLnNpZGViYXJTZXJ2aWNlLnNob3dTaWRlYmFyKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCfimqDvuI8gU0lERUJBUiBERUJVRyAtIE5vIHNpZGViYXIgY29uZmlnIGZvdW5kLCBoaWRpbmcgc2lkZWJhcicpO1xuICAgICAgICB0aGlzLnNpZGViYXJTZXJ2aWNlLmhpZGVTaWRlYmFyKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIGNoZWNrIGhlYWRlciB2aXNpYmxlIG9yIG5vdFxuICAgICAgY29uc29sZS5sb2coJ/CflI0gSEVBREVSIERFQlVHIC0gSGVhZGVyIGNvbmZpZyBmb3VuZDonLCBwYWdlX2RhdGFfcmVzcG9uc2U/LmRhdGE/LnRoZW1lPy5zeXRtX2xheW91dD8uc3l0bV9sYXlvdXRfaGVhZGVyKTtcbiAgICAgIGlmIChwYWdlX2RhdGFfcmVzcG9uc2U/LmRhdGE/LnRoZW1lPy5zeXRtX2xheW91dD8uc3l0bV9sYXlvdXRfaGVhZGVyKSB7XG4gICAgICAgIGlmICghcGFnZV9kYXRhX3Jlc3BvbnNlPy5kYXRhPy50aGVtZT8uc3l0bV9sYXlvdXQ/LnN5dG1fbGF5b3V0X2hlYWRlcj8uc3RhdHVzKSB7XG4gICAgICAgICAgdGhpcy5oZWFkZXJTZXJ2aWNlLmhpZGVIZWFkZXIoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmhlYWRlclNlcnZpY2Uuc2hvd0hlYWRlcigpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmhlYWRlclNlcnZpY2UuaGlkZUhlYWRlcigpO1xuICAgICAgfVxuXG4gICAgICAvLyBjaGVjayBmb290ZXIgdmlzaWJsZSBvciBub3QgXG4gICAgICBpZiAocGFnZV9kYXRhX3Jlc3BvbnNlPy5kYXRhPy50aGVtZT8uc3l0bV9sYXlvdXQ/LnN5dG1fbGF5b3V0X2Zvb3Rlcikge1xuICAgICAgICBpZiAoIXBhZ2VfZGF0YV9yZXNwb25zZT8uZGF0YT8udGhlbWU/LnN5dG1fbGF5b3V0Py5zeXRtX2xheW91dF9mb290ZXI/LnN0YXR1cykge1xuICAgICAgICAgIHRoaXMuZm9vdGVyU2VydmljZS5oaWRlRm9vdGVyKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5mb290ZXJTZXJ2aWNlLnNob3dGb290ZXIoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5mb290ZXJTZXJ2aWNlLmhpZGVGb290ZXIoKTtcbiAgICAgIH1cblxuICAgICAgLy8gY2hlY2sgY29uc29sZSB2aXNpYmxlIG9yIG5vdFxuICAgICAgaWYgKHBhZ2VfZGF0YV9yZXNwb25zZT8uZGF0YT8udGhlbWU/LnN5dG1fbGF5b3V0Py5zeXRtX2xheW91dF9jb25zb2xlKSB7XG4gICAgICAgIGlmICghcGFnZV9kYXRhX3Jlc3BvbnNlPy5kYXRhPy50aGVtZT8uc3l0bV9sYXlvdXQ/LnN5dG1fbGF5b3V0X2NvbnNvbGU/LnN0YXR1cykge1xuICAgICAgICAgIHRoaXMuY29uc29sZVNlcnZpY2UuaGlkZUNvbnNvbGUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNvbnNvbGVTZXJ2aWNlLnNob3dDb25zb2xlKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY29uc29sZVNlcnZpY2UuaGlkZUNvbnNvbGUoKTtcbiAgICAgIH1cblxuICAgICAgLy8gY2hlY2sgZm9yIHRoZSByZXF1ZXN0IHN0YXR1cyBhbmQgbG9nIGl0IGZvciBkZWJ1Z2dpbmdcbiAgICAgIGNvbnNvbGUubG9nKCfwn5SNIFJFUVVFU1QgREVCVUcgLSBSZXF1ZXN0IGNvbmZpZyBmb3VuZDonLCBwYWdlX2RhdGFfcmVzcG9uc2U/LmRhdGE/LnRoZW1lPy5zeXRtX2xheW91dD8uc3l0bV9sYXlvdXRfcmVxdWVzdCk7XG4gICAgICBpZiAocGFnZV9kYXRhX3Jlc3BvbnNlPy5kYXRhPy50aGVtZT8uc3l0bV9sYXlvdXQ/LnN5dG1fbGF5b3V0X3JlcXVlc3QpIHtcbiAgICAgICAgY29uc3QgcmVxdWVzdFN0YXR1cyA9IHBhZ2VfZGF0YV9yZXNwb25zZT8uZGF0YT8udGhlbWU/LnN5dG1fbGF5b3V0Py5zeXRtX2xheW91dF9yZXF1ZXN0Py5zdGF0dXM7XG4gICAgICAgIGNvbnNvbGUubG9nKCfwn5SNIFJFUVVFU1QgREVCVUcgLSBSZXF1ZXN0IHN0YXR1czonLCByZXF1ZXN0U3RhdHVzLCAnVHlwZTonLCB0eXBlb2YgcmVxdWVzdFN0YXR1cyk7XG4gICAgICAgIFxuICAgICAgICAvLyBUaGUgcmVxdWVzdCBzdGF0dXMgY29udHJvbHMgd2hldGhlciB0aGlzIHBhZ2Ugc2hvdWxkIHN1cHBvcnQgdGFic1xuICAgICAgICAvLyBUaGlzIGlzIHVzZWQgYnkgdGhlIHJlcXVlc3Qgc2VydmljZSB0byBkZXRlcm1pbmUgaWYgdGFicyBzaG91bGQgYmUgY3JlYXRlZFxuICAgICAgICBpZiAocmVxdWVzdFN0YXR1cyA9PT0gdHJ1ZSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCfinIUgUkVRVUVTVCBERUJVRyAtIFJlcXVlc3QgaXMgZW5hYmxlZCBmb3IgdGFiYmluZycpO1xuICAgICAgICAgIC8vIFNob3cgcmVxdWVzdCB3cmFwcGVyIHdoZW4gcmVxdWVzdCBpcyBlbmFibGVkXG4gICAgICAgICAgaWYgKHRoaXMucmVxdWVzdFZpc2liaWxpdHlDYWxsYmFjaykge1xuICAgICAgICAgICAgdGhpcy5yZXF1ZXN0VmlzaWJpbGl0eUNhbGxiYWNrKHRydWUpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ/Cfk4sgUkVRVUVTVCBWSVNJQklMSVRZIC0gU2hvd2luZyByZXF1ZXN0IHdyYXBwZXInKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAocmVxdWVzdFN0YXR1cyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygn8J+aqyBSRVFVRVNUIERFQlVHIC0gUmVxdWVzdCBpcyBkaXNhYmxlZCBmb3IgdGFiYmluZycpO1xuICAgICAgICAgIC8vIEhpZGUgcmVxdWVzdCB3cmFwcGVyIHdoZW4gcmVxdWVzdCBpcyBkaXNhYmxlZFxuICAgICAgICAgIGlmICh0aGlzLnJlcXVlc3RWaXNpYmlsaXR5Q2FsbGJhY2spIHtcbiAgICAgICAgICAgIHRoaXMucmVxdWVzdFZpc2liaWxpdHlDYWxsYmFjayhmYWxzZSk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygn8J+TiyBSRVFVRVNUIFZJU0lCSUxJVFkgLSBIaWRpbmcgcmVxdWVzdCB3cmFwcGVyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCfimqDvuI8gUkVRVUVTVCBERUJVRyAtIFVuZXhwZWN0ZWQgcmVxdWVzdCBzdGF0dXMgdmFsdWU6JywgcmVxdWVzdFN0YXR1cyk7XG4gICAgICAgICAgLy8gRGVmYXVsdCB0byBoaWRpbmcgcmVxdWVzdCB3cmFwcGVyIGZvciB1bmV4cGVjdGVkIHZhbHVlc1xuICAgICAgICAgIGlmICh0aGlzLnJlcXVlc3RWaXNpYmlsaXR5Q2FsbGJhY2spIHtcbiAgICAgICAgICAgIHRoaXMucmVxdWVzdFZpc2liaWxpdHlDYWxsYmFjayhmYWxzZSk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygn8J+TiyBSRVFVRVNUIFZJU0lCSUxJVFkgLSBIaWRpbmcgcmVxdWVzdCB3cmFwcGVyICh1bmV4cGVjdGVkIHZhbHVlKScpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coJ+KaoO+4jyBSRVFVRVNUIERFQlVHIC0gTm8gcmVxdWVzdCBjb25maWcgZm91bmQsIHRhYnMgd2lsbCBub3QgYmUgY3JlYXRlZCcpO1xuICAgICAgICAvLyBIaWRlIHJlcXVlc3Qgd3JhcHBlciB3aGVuIG5vIHJlcXVlc3QgY29uZmlnIGZvdW5kXG4gICAgICAgIGlmICh0aGlzLnJlcXVlc3RWaXNpYmlsaXR5Q2FsbGJhY2spIHtcbiAgICAgICAgICB0aGlzLnJlcXVlc3RWaXNpYmlsaXR5Q2FsbGJhY2soZmFsc2UpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKCfwn5OLIFJFUVVFU1QgVklTSUJJTElUWSAtIEhpZGluZyByZXF1ZXN0IHdyYXBwZXIgKG5vIGNvbmZpZyknKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSByb3V0ZSBjaGFuZ2VzIC0gbW92ZWQgZnJvbSByZXF1ZXN0IHNlcnZpY2UgZm9yIGJldHRlciBhcmNoaXRlY3R1cmVcbiAgICogVGhpcyBtZXRob2QgbG9hZHMgcGFnZSBkYXRhIGFuZCBjYWxscyByZXF1ZXN0IHNlcnZpY2UgdG8gbWFuYWdlIHRhYnNcbiAgICovXG4gIHByaXZhdGUgaGFuZGxlUm91dGVDaGFuZ2UoKSB7XG4gICAgY29uc3QgcGFyc2VkVXJsID0gdGhpcy5yb3V0ZXIucGFyc2VVcmwodGhpcy5yb3V0ZXIudXJsKTtcbiAgICBjb25zdCBjdXJyZW50Um91dGVQYXRoID0gJy8nICsgKHBhcnNlZFVybC5yb290LmNoaWxkcmVuWydwcmltYXJ5J10/LnNlZ21lbnRzLm1hcChzID0+IHMucGF0aCkuam9pbignLycpIHx8ICcnKTtcbiAgICBjb25zdCBxdWVyeVBhcmFtcyA9IHBhcnNlZFVybC5xdWVyeVBhcmFtcztcblxuICAgIGNvbnNvbGUubG9nKCfwn5SNIFJvdXRlIGNoYW5nZTonLCB7XG4gICAgICBjdXJyZW50Um91dGVQYXRoLFxuICAgICAgcXVlcnlQYXJhbXNcbiAgICB9KTtcblxuICAgIC8vIEdldCBwYWdlIGNvZGUgZnJvbSByb3V0ZSBkYXRhXG4gICAgbGV0IHJvdXRlID0gdGhpcy5yb3V0ZXIucm91dGVyU3RhdGUuc25hcHNob3Qucm9vdDtcbiAgICB3aGlsZSAocm91dGUuZmlyc3RDaGlsZCkge1xuICAgICAgcm91dGUgPSByb3V0ZS5maXJzdENoaWxkO1xuICAgIH1cblxuICAgIGNvbnN0IHBhZ2VDb2RlID0gcm91dGUuZGF0YSAmJiByb3V0ZS5kYXRhWydzeXBnX3BhZ2VfY29kZSddO1xuICAgIGNvbnNvbGUubG9nKCfwn5OEIFByb2Nlc3Npbmcgcm91dGUgd2l0aCBwYWdlIGNvZGU6JywgcGFnZUNvZGUpO1xuXG4gICAgaWYgKHBhZ2VDb2RlKSB7XG4gICAgICBjb25zdCBlbnRpdHlJZCA9IHRoaXMuYXBwU3RhdGUuZ2V0QWN0aXZlRW50aXR5SWQoKTtcbiAgICAgIGNvbnNvbGUubG9nKGDwn5OhIExvYWRpbmcgYW5kIHByb2Nlc3NpbmcgcGFnZSBkYXRhIGZvciBwYWdlQ29kZTogJHtwYWdlQ29kZX1gKTtcbiAgICAgIHRoaXMucGFnZURhdGFTdWJzY3JpcHRpb24gPSB0aGlzLmxvYWRBbmRQcm9jZXNzUGFnZURhdGEoXG4gICAgICAgIHsgc3lwZ19wYWdlX2NvZGU6IHBhZ2VDb2RlLCBzeXRtX2VudGl0eV9pZF9zeWVuOiBlbnRpdHlJZCB8fCB1bmRlZmluZWQgfSxcbiAgICAgICAge1xuICAgICAgICAgIGZvcmNlUmVmcmVzaDogZmFsc2UsXG4gICAgICAgICAgc2V0VGl0bGU6IHRydWUsXG4gICAgICAgICAgc2V0U2lkZWJhckNvbnRleHQ6IHRydWUsXG4gICAgICAgICAgdXBkYXRlTGF5b3V0OiB0cnVlXG4gICAgICAgIH1cbiAgICAgICkucGlwZSh0YWtlKDEpKVxuICAgICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgICBuZXh0OiAocGFnZV9kYXRhX3Jlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBsYXlvdXQgPSBwYWdlX2RhdGFfcmVzcG9uc2U/LmRhdGE/LnRoZW1lPy5zeXRtX2xheW91dDtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gVXBkYXRlIHNpZGVkcmF3ZXIgd2l0aCBwcm9jZXNzZWQgbGF5b3V0XG4gICAgICAgICAgICB0aGlzLnNpZGVkcmF3ZXJTZXJ2aWNlLnVwZGF0ZURyYXdlckl0ZW1zKGxheW91dCk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8vIFN5bmMgc2lkZWJhciBhY3RpdmUgbWVudSB3aXRoIGxvYWRlZCBwYWdlXG4gICAgICAgICAgICB0aGlzLnN5bmNTaWRlYmFyQWN0aXZlTWVudShwYWdlX2RhdGFfcmVzcG9uc2UsIHBhZ2VDb2RlKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgKGxheW91dD8uc3l0bV9sYXlvdXRfcmVxdWVzdD8uc3RhdHVzID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKCfinIUgTGF5b3V0IHByb2Nlc3NlZCAtIGNhbGxpbmcgcmVxdWVzdCBzZXJ2aWNlIHRvIG1hbmFnZSB0YWJzJyk7XG4gICAgICAgICAgICAgIC8vIENhbGwgcmVxdWVzdCBzZXJ2aWNlIHRvIGhhbmRsZSB0YWIgY3JlYXRpb25cbiAgICAgICAgICAgICAgdGhpcy5oYW5kbGVUYWJSZXF1ZXN0KGN1cnJlbnRSb3V0ZVBhdGgsIHF1ZXJ5UGFyYW1zLCBsYXlvdXQsIHBhZ2VfZGF0YV9yZXNwb25zZSwgcGFnZUNvZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY29uc29sZS5sb2coJ+KdjCBMYXlvdXQgcmVxdWVzdCBkaXNhYmxlZCAtIHRhYiBub3QgY3JlYXRlZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYOKdjCBFcnJvciBsb2FkaW5nIHBhZ2UgZGF0YSBmb3Igc3lwZ19wYWdlX2NvZGUgJyR7cGFnZUNvZGV9JzpgLCBlcnIpO1xuICAgICAgICAgICAgdGhpcy5zaWRlZHJhd2VyU2VydmljZS51cGRhdGVEcmF3ZXJJdGVtcyh1bmRlZmluZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKCfimqDvuI8gTm8gcGFnZSBjb2RlIGZvdW5kIGluIHJvdXRlIGRhdGEgLSBjbGVhcmluZyBkcmF3ZXInKTtcbiAgICAgIHRoaXMuc2lkZWRyYXdlclNlcnZpY2UudXBkYXRlRHJhd2VySXRlbXModW5kZWZpbmVkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHRhYiByZXF1ZXN0IGJ5IGNhbGxpbmcgcmVxdWVzdCBzZXJ2aWNlXG4gICAqL1xuICBwcml2YXRlIGhhbmRsZVRhYlJlcXVlc3QoXG4gICAgY3VycmVudFJvdXRlUGF0aDogc3RyaW5nLCBcbiAgICBxdWVyeVBhcmFtczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIFxuICAgIGxheW91dDogSVN5dG1MYXlvdXQsIFxuICAgIHBhZ2VEYXRhOiBkZXNpZ25Db25maWdDb250cm9sbGVyUmVzcG9uc2UsIFxuICAgIHBhZ2VDb2RlOiBzdHJpbmdcbiAgKSB7XG4gICAgaWYgKHRoaXMudGFiTWFuYWdlbWVudENhbGxiYWNrKSB7XG4gICAgICBjb25zb2xlLmxvZygn8J+UhCBDYWxsaW5nIHJlZ2lzdGVyZWQgdGFiIG1hbmFnZW1lbnQgY2FsbGJhY2snKTtcbiAgICAgIHRoaXMudGFiTWFuYWdlbWVudENhbGxiYWNrKGN1cnJlbnRSb3V0ZVBhdGgsIHF1ZXJ5UGFyYW1zLCBsYXlvdXQsIHBhZ2VEYXRhLCBwYWdlQ29kZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKCfimqDvuI8gTm8gdGFiIG1hbmFnZW1lbnQgY2FsbGJhY2sgcmVnaXN0ZXJlZCcpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTeW5jIHRoZSBhY3RpdmUgbWVudSBpbiB0aGUgc2lkZWJhciBiYXNlZCBvbiB0aGUgbG9hZGVkIHBhZ2UgZGF0YS5cbiAgICogVGhpcyBlbnN1cmVzIHRoZSBjb3JyZWN0IG1vZHVsZSBpcyBoaWdobGlnaHRlZCBpbiB0aGUgc2lkZWJhci5cbiAgICovXG4gIHByaXZhdGUgc3luY1NpZGViYXJBY3RpdmVNZW51KHBhZ2VfZGF0YV9yZXNwb25zZTogZGVzaWduQ29uZmlnQ29udHJvbGxlclJlc3BvbnNlLCBwYWdlQ29kZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2coJ/CflI0gU0lERUJBUiBTWU5DOiBTdGFydGluZyBzaWRlYmFyIGFjdGl2ZSBtZW51IHN5bmMgZm9yOicsIHBhZ2VDb2RlKTtcbiAgICBcbiAgICAvLyBUcnkgdG8gZXh0cmFjdCBtb2R1bGUgaW5mb3JtYXRpb24gZnJvbSByb3V0ZVxuICAgIGNvbnN0IGN1cnJlbnRSb3V0ZSA9IHRoaXMucm91dGVyLnVybDtcbiAgICBjb25zdCByb3V0ZVBhcnRzID0gY3VycmVudFJvdXRlLnNwbGl0KCcvJykuZmlsdGVyKHBhcnQgPT4gcGFydCk7XG4gICAgbGV0IHJvdXRlTW9kdWxlTmFtZSA9ICcnO1xuICAgIFxuICAgIC8vIExvb2sgZm9yIGNvbnRyb2wtcGFuZWwgb3IgbW9kdWxlIGlkZW50aWZpZXIgaW4gcm91dGVcbiAgICBpZiAocm91dGVQYXJ0cy5pbmNsdWRlcygnY29udHJvbC1wYW5lbCcpICYmIHJvdXRlUGFydHMubGVuZ3RoID4gMSkge1xuICAgICAgY29uc3QgbW9kdWxlSW5kZXggPSByb3V0ZVBhcnRzLmluZGV4T2YoJ2NvbnRyb2wtcGFuZWwnKSArIDE7XG4gICAgICByb3V0ZU1vZHVsZU5hbWUgPSByb3V0ZVBhcnRzW21vZHVsZUluZGV4XSB8fCAnJztcbiAgICB9IGVsc2UgaWYgKHJvdXRlUGFydHMubGVuZ3RoID4gMCkge1xuICAgICAgcm91dGVNb2R1bGVOYW1lID0gcm91dGVQYXJ0c1swXTtcbiAgICB9XG4gICAgXG4gICAgY29uc29sZS5sb2coJ/CflI0gU0lERUJBUiBTWU5DOiBSb3V0ZSBtb2R1bGUgbmFtZTonLCByb3V0ZU1vZHVsZU5hbWUpO1xuICAgIGNvbnNvbGUubG9nKCfwn5SNIFNJREVCQVIgU1lOQzogQ3VycmVudCByb3V0ZTonLCBjdXJyZW50Um91dGUpO1xuICAgIGNvbnNvbGUubG9nKCfwn5SNIFNJREVCQVIgU1lOQzogUGFnZSBjb2RlOicsIHBhZ2VDb2RlKTtcbiAgICBcbiAgICAvLyBMb2FkIHNpZGViYXIgbW9kdWxlcyBhbmQgZmluZCB0aGUgbWF0Y2hpbmcgb25lXG4gICAgdGhpcy5zaWRlYmFyU2VydmljZS5nZXRTaWRlYmFyTWVudWVzKHsgc3ltZV90eXBlOiBcIm1vZHVsZVwiLCBzb3J0OiAnYXNjJywgc3ltZV90aXRsZTogXCJcIiB9KVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChtb2R1bGVzUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICBjb25zdCBtb2R1bGVzID0gbW9kdWxlc1Jlc3BvbnNlPy5kYXRhIHx8IFtdO1xuICAgICAgICAgIGNvbnNvbGUubG9nKCfwn5SNIFNJREVCQVIgU1lOQzogQXZhaWxhYmxlIG1vZHVsZXM6JywgbW9kdWxlcy5tYXAobSA9PiAoeyBpZDogbS5faWQsIHRpdGxlOiBtLnN5bWVfdGl0bGUsIHBhdGg6IG0uc3ltZV9wYXRoIH0pKSk7XG4gICAgICAgICAgXG4gICAgICAgICAgbGV0IG1hdGNoZWRNb2R1bGUgPSBudWxsO1xuICAgICAgICAgIFxuICAgICAgICAgIC8vIFRyeSB0byBtYXRjaCBieSByb3V0ZSBwYXRoXG4gICAgICAgICAgaWYgKHJvdXRlTW9kdWxlTmFtZSkge1xuICAgICAgICAgICAgbWF0Y2hlZE1vZHVsZSA9IG1vZHVsZXMuZmluZChtID0+IFxuICAgICAgICAgICAgICBtLnN5bWVfcGF0aD8uaW5jbHVkZXMocm91dGVNb2R1bGVOYW1lKSB8fCBcbiAgICAgICAgICAgICAgbS5zeW1lX3RpdGxlPy50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHJvdXRlTW9kdWxlTmFtZS50b0xvd2VyQ2FzZSgpKSB8fFxuICAgICAgICAgICAgICByb3V0ZU1vZHVsZU5hbWUuaW5jbHVkZXMobS5zeW1lX3BhdGggfHwgJycpIHx8XG4gICAgICAgICAgICAgIG0uc3ltZV9wYXRoID09PSByb3V0ZU1vZHVsZU5hbWVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAobWF0Y2hlZE1vZHVsZSkge1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZygn4pyFIFNJREVCQVIgU1lOQzogTWF0Y2hlZCBtb2R1bGUgYnkgcm91dGU6JywgbWF0Y2hlZE1vZHVsZS5zeW1lX3RpdGxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gSWYgbm90IGZvdW5kLCB0cnkgdG8gbWF0Y2ggYnkgcGFnZSBjb2RlIHBhdHRlcm5cbiAgICAgICAgICBpZiAoIW1hdGNoZWRNb2R1bGUgJiYgcGFnZUNvZGUpIHtcbiAgICAgICAgICAgIG1hdGNoZWRNb2R1bGUgPSBtb2R1bGVzLmZpbmQobSA9PiBcbiAgICAgICAgICAgICAgcGFnZUNvZGUuaW5jbHVkZXMobS5zeW1lX3BhdGggfHwgJycpIHx8XG4gICAgICAgICAgICAgIChtLnN5bWVfcGF0aCAmJiBwYWdlQ29kZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKG0uc3ltZV9wYXRoLnRvTG93ZXJDYXNlKCkpKSB8fFxuICAgICAgICAgICAgICBtLnN5bWVfcGF0aCA9PT0gcGFnZUNvZGVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAobWF0Y2hlZE1vZHVsZSkge1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZygn4pyFIFNJREVCQVIgU1lOQzogTWF0Y2hlZCBtb2R1bGUgYnkgcGFnZSBjb2RlOicsIG1hdGNoZWRNb2R1bGUuc3ltZV90aXRsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIFxuICAgICAgICAgIC8vIElmIHN0aWxsIG5vdCBmb3VuZCwgdHJ5IHBhcnRpYWwgbWF0Y2hpbmcgZm9yIGNvbW1vbiBwYXR0ZXJuc1xuICAgICAgICAgIGlmICghbWF0Y2hlZE1vZHVsZSkge1xuICAgICAgICAgICAgLy8gVHJ5IHRvIG1hdGNoIGNvbW1vbiBwYXR0ZXJucyBsaWtlICdhZG1pbicsICdkYXNoYm9hcmQnLCBldGMuXG4gICAgICAgICAgICBjb25zdCBzZWFyY2hUZXJtcyA9IFtyb3V0ZU1vZHVsZU5hbWUsIHBhZ2VDb2RlXS5maWx0ZXIoQm9vbGVhbik7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRlcm0gb2Ygc2VhcmNoVGVybXMpIHtcbiAgICAgICAgICAgICAgbWF0Y2hlZE1vZHVsZSA9IG1vZHVsZXMuZmluZChtID0+IFxuICAgICAgICAgICAgICAgIG0uc3ltZV90aXRsZT8udG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0ZXJtLnRvTG93ZXJDYXNlKCkpIHx8XG4gICAgICAgICAgICAgICAgdGVybS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKG0uc3ltZV90aXRsZT8udG9Mb3dlckNhc2UoKSB8fCAnJykgfHxcbiAgICAgICAgICAgICAgICBtLnN5bWVfcGF0aD8udG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0ZXJtLnRvTG93ZXJDYXNlKCkpIHx8XG4gICAgICAgICAgICAgICAgdGVybS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKG0uc3ltZV9wYXRoPy50b0xvd2VyQ2FzZSgpIHx8ICcnKVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBpZiAobWF0Y2hlZE1vZHVsZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCfinIUgU0lERUJBUiBTWU5DOiBNYXRjaGVkIG1vZHVsZSBieSBwYXR0ZXJuOicsIG1hdGNoZWRNb2R1bGUuc3ltZV90aXRsZSwgJ2ZvciB0ZXJtOicsIHRlcm0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIFxuICAgICAgICAgIC8vIENoZWNrIGlmIHdlIHNob3VsZCBzZXQgdGhlIG1hdGNoZWQgbW9kdWxlIGFzIGFjdGl2ZVxuICAgICAgICAgIGlmIChtYXRjaGVkTW9kdWxlKSB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50QWN0aXZlTW9kdWxlID0gdGhpcy5hcHBTdGF0ZS5nZXRBY3RpdmVNb2R1bGUoKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gQmUgbW9yZSBjb25zZXJ2YXRpdmUgYWJvdXQgb3ZlcnJpZGluZyB1c2VyIHNlbGVjdGlvbnNcbiAgICAgICAgICAgIC8vIE9ubHkgc2V0IHRoZSBtb2R1bGUgaWYgbm8gbW9kdWxlIGlzIGN1cnJlbnRseSBhY3RpdmVcbiAgICAgICAgICAgIGNvbnN0IHNob3VsZFNldE1vZHVsZSA9ICFjdXJyZW50QWN0aXZlTW9kdWxlO1xuICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAoc2hvdWxkU2V0TW9kdWxlKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKCfwn46vIFNJREVCQVIgU1lOQzogTm8gYWN0aXZlIG1vZHVsZSwgc2V0dGluZzonLCBtYXRjaGVkTW9kdWxlLnN5bWVfdGl0bGUsIG1hdGNoZWRNb2R1bGUuX2lkKTtcbiAgICAgICAgICAgICAgdGhpcy5hcHBTdGF0ZS5zZXRBY3RpdmVNb2R1bGUobWF0Y2hlZE1vZHVsZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZygn4pyFIFNJREVCQVIgU1lOQzogTW9kdWxlIGFscmVhZHkgYWN0aXZlLCByZXNwZWN0aW5nIHVzZXIgc2VsZWN0aW9uOicsIGN1cnJlbnRBY3RpdmVNb2R1bGU/LnN5bWVfdGl0bGUpO1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZygn8J+UjSBTSURFQkFSIFNZTkM6IFJvdXRlIHN1Z2dlc3RzOicsIG1hdGNoZWRNb2R1bGUuc3ltZV90aXRsZSwgJy0gbm90IG92ZXJyaWRpbmcnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ+KaoO+4jyBTSURFQkFSIFNZTkM6IE5vIG1hdGNoaW5nIG1vZHVsZSBmb3VuZCBmb3IgcGFnZTonLCBwYWdlQ29kZSk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygn8J+UjSBTSURFQkFSIFNZTkM6IEF2YWlsYWJsZSBtb2R1bGVzOicsIG1vZHVsZXMubWFwKG0gPT4gbS5zeW1lX3RpdGxlKS5qb2luKCcsICcpKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCfwn5SNIFNJREVCQVIgU1lOQzogU2VhcmNoZWQgZm9yIHJvdXRlOicsIHJvdXRlTW9kdWxlTmFtZSwgJ2FuZCBwYWdlIGNvZGU6JywgcGFnZUNvZGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCfinYwgU0lERUJBUiBTWU5DOiBFcnJvciBsb2FkaW5nIG1vZHVsZXMgZm9yIHN5bmM6JywgZXJyKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxufVxuIl19
|