cloud-ide-admin 1.0.0
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 +24 -0
- package/esm2022/cloud-ide-admin.mjs +5 -0
- package/esm2022/lib/admin-module/entity/create/cide-adm-entity.component.mjs +834 -0
- package/esm2022/lib/admin-module/entity/create/cide-adm-entity.service.mjs +79 -0
- package/esm2022/lib/admin-module/entity/create/country-select.service.mjs +33 -0
- package/esm2022/lib/admin-module/entity/create/currency-select.service.mjs +48 -0
- package/esm2022/lib/admin-module/entity/create/general-master-select.service.mjs +44 -0
- package/esm2022/lib/admin-module/entity/create/pin-code-select.service.mjs +60 -0
- package/esm2022/lib/admin-module/entity/create/user-select.service.mjs +58 -0
- package/esm2022/lib/admin-module/entity/list/cide-adm-entity-list.component.mjs +600 -0
- package/esm2022/lib/admin-module/entity/list/cide-adm-entity-list.service.mjs +52 -0
- package/esm2022/lib/admin-module/home/home-wrapper/cide-adm-home-wrapper.component.mjs +21 -0
- package/esm2022/lib/cide-adm-admin.component.mjs +29 -0
- package/esm2022/lib/cide-adm-admin.service.mjs +14 -0
- package/esm2022/lib/cloud-ide-admin.routes.mjs +38 -0
- package/esm2022/public-api.mjs +10 -0
- package/fesm2022/cloud-ide-admin-cide-adm-home-wrapper.component-Cu0sr3ST.mjs +24 -0
- package/fesm2022/cloud-ide-admin-cide-adm-home-wrapper.component-Cu0sr3ST.mjs.map +1 -0
- package/fesm2022/cloud-ide-admin.mjs +1867 -0
- package/fesm2022/cloud-ide-admin.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/admin-module/entity/create/cide-adm-entity.component.d.ts +73 -0
- package/lib/admin-module/entity/create/cide-adm-entity.service.d.ts +39 -0
- package/lib/admin-module/entity/create/country-select.service.d.ts +13 -0
- package/lib/admin-module/entity/create/currency-select.service.d.ts +19 -0
- package/lib/admin-module/entity/create/general-master-select.service.d.ts +24 -0
- package/lib/admin-module/entity/create/pin-code-select.service.d.ts +31 -0
- package/lib/admin-module/entity/create/user-select.service.d.ts +31 -0
- package/lib/admin-module/entity/list/cide-adm-entity-list.component.d.ts +94 -0
- package/lib/admin-module/entity/list/cide-adm-entity-list.service.d.ts +25 -0
- package/lib/admin-module/home/home-wrapper/cide-adm-home-wrapper.component.d.ts +9 -0
- package/lib/cide-adm-admin.component.d.ts +9 -0
- package/lib/cide-adm-admin.service.d.ts +6 -0
- package/lib/cloud-ide-admin.routes.d.ts +2 -0
- package/package.json +25 -0
- package/public-api.d.ts +6 -0
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
import { Component, signal, inject, ViewChild } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { FormsModule } from '@angular/forms';
|
|
4
|
+
import { Router } from '@angular/router';
|
|
5
|
+
import { CideInputComponent, CideIconComponent, TooltipDirective } from 'cloud-ide-element';
|
|
6
|
+
import { CideEleButtonComponent, CideSelectComponent } from 'cloud-ide-element';
|
|
7
|
+
import { CideEleDataGridComponent } from 'cloud-ide-element';
|
|
8
|
+
import { CideAdmEntityListService } from './cide-adm-entity-list.service';
|
|
9
|
+
import { generateStringFromObject } from 'cloud-ide-lms-model';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
import * as i1 from "@angular/forms";
|
|
12
|
+
export class CideAdmEntityListComponent {
|
|
13
|
+
constructor() {
|
|
14
|
+
// Modern dependency injection using inject()
|
|
15
|
+
this.router = inject(Router); // Made public for template access
|
|
16
|
+
this.entityService = inject(CideAdmEntityListService);
|
|
17
|
+
// State management using Angular Signals
|
|
18
|
+
this.entities = signal([]);
|
|
19
|
+
this.loading = signal(false);
|
|
20
|
+
this.error = signal(null);
|
|
21
|
+
this.searchQuery = signal('');
|
|
22
|
+
this.currentPage = signal(1);
|
|
23
|
+
this.pageSize = signal(10);
|
|
24
|
+
this.totalItems = signal(0);
|
|
25
|
+
this.selectedEntityType = signal('');
|
|
26
|
+
// Pagination calculations
|
|
27
|
+
this.totalPages = signal(0);
|
|
28
|
+
this.hasNextPage = signal(false);
|
|
29
|
+
this.hasPreviousPage = signal(false);
|
|
30
|
+
this.jumpToPage = 1;
|
|
31
|
+
this.loadStartTime = 0;
|
|
32
|
+
// Filter options
|
|
33
|
+
this.entityTypeOptions = signal([
|
|
34
|
+
{ value: '', label: 'All Entity Types' },
|
|
35
|
+
{ value: 'school', label: 'School' },
|
|
36
|
+
{ value: 'college', label: 'College' },
|
|
37
|
+
{ value: 'university', label: 'University' },
|
|
38
|
+
{ value: 'institute', label: 'Institute' }
|
|
39
|
+
]);
|
|
40
|
+
// Grid configuration signal
|
|
41
|
+
this.gridConfig = signal({
|
|
42
|
+
id: 'entity-list-grid',
|
|
43
|
+
title: '',
|
|
44
|
+
subtitle: '',
|
|
45
|
+
columns: [
|
|
46
|
+
{
|
|
47
|
+
key: 'details',
|
|
48
|
+
header: 'Entity Details',
|
|
49
|
+
type: 'custom',
|
|
50
|
+
width: 'lg',
|
|
51
|
+
truncate: true,
|
|
52
|
+
align: 'left',
|
|
53
|
+
renderer: 'entityDetailsRenderer'
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
key: 'contact',
|
|
57
|
+
header: 'Contact Information',
|
|
58
|
+
type: 'custom',
|
|
59
|
+
width: 'lg',
|
|
60
|
+
truncate: true,
|
|
61
|
+
align: 'left',
|
|
62
|
+
renderer: 'contactInfoRenderer'
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
key: 'syen_isactive',
|
|
66
|
+
header: 'Status',
|
|
67
|
+
type: 'status',
|
|
68
|
+
width: 'md',
|
|
69
|
+
truncate: false,
|
|
70
|
+
align: 'center',
|
|
71
|
+
statusConfig: {
|
|
72
|
+
activeValue: true,
|
|
73
|
+
activeLabel: 'Active',
|
|
74
|
+
inactiveLabel: 'Inactive',
|
|
75
|
+
activeClass: 'tw-bg-green-100 tw-text-green-800',
|
|
76
|
+
inactiveClass: 'tw-bg-red-100 tw-text-red-800'
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
key: 'syen_entity_type_gmst',
|
|
81
|
+
header: 'Entity Type',
|
|
82
|
+
type: 'text',
|
|
83
|
+
width: 'md',
|
|
84
|
+
truncate: false,
|
|
85
|
+
align: 'center'
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
key: 'actions',
|
|
89
|
+
header: 'Actions',
|
|
90
|
+
type: 'actions',
|
|
91
|
+
width: 'md',
|
|
92
|
+
truncate: false,
|
|
93
|
+
align: 'right',
|
|
94
|
+
actions: [
|
|
95
|
+
{
|
|
96
|
+
key: 'edit',
|
|
97
|
+
label: 'Edit',
|
|
98
|
+
icon: 'pencil',
|
|
99
|
+
variant: 'outline',
|
|
100
|
+
tooltip: 'Edit entity',
|
|
101
|
+
onClick: 'onEditEntity'
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
key: 'delete',
|
|
105
|
+
label: 'Delete',
|
|
106
|
+
icon: 'trash',
|
|
107
|
+
variant: 'danger',
|
|
108
|
+
tooltip: 'Delete entity',
|
|
109
|
+
onClick: 'onDeleteEntity'
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
data: [],
|
|
115
|
+
trackBy: '_id',
|
|
116
|
+
pagination: {
|
|
117
|
+
enabled: true,
|
|
118
|
+
pageSize: 10,
|
|
119
|
+
pageSizeOptions: [10, 25, 50, 100],
|
|
120
|
+
showQuickJump: true,
|
|
121
|
+
showPageInfo: true,
|
|
122
|
+
showRefresh: true
|
|
123
|
+
},
|
|
124
|
+
search: {
|
|
125
|
+
enabled: true,
|
|
126
|
+
placeholder: 'Search entities...',
|
|
127
|
+
searchableColumns: ['syen_name', 'syen_entity_code', 'syen_corporate_email'],
|
|
128
|
+
debounceMs: 300
|
|
129
|
+
},
|
|
130
|
+
loading: {
|
|
131
|
+
useDefer: true,
|
|
132
|
+
skeletonRows: 5,
|
|
133
|
+
showOverlay: false
|
|
134
|
+
},
|
|
135
|
+
responsive: true,
|
|
136
|
+
striped: false,
|
|
137
|
+
bordered: true,
|
|
138
|
+
compact: false,
|
|
139
|
+
fullHeight: true,
|
|
140
|
+
onRowClick: 'onEntityRowClick',
|
|
141
|
+
onRefresh: 'onEntityRefresh',
|
|
142
|
+
tree: {
|
|
143
|
+
enabled: true,
|
|
144
|
+
primaryKey: '_id',
|
|
145
|
+
foreignKey: 'syen_parent_entity_id',
|
|
146
|
+
childrenKey: 'children',
|
|
147
|
+
levelKey: 'level',
|
|
148
|
+
expandedKey: 'isExpanded',
|
|
149
|
+
hasChildrenKey: 'hasChildren'
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
// Custom renderers for complex columns
|
|
153
|
+
this.customRenderers = {
|
|
154
|
+
entityDetailsRenderer: (value, row) => {
|
|
155
|
+
const entityCode = row.syen_entity_code || 'N/A';
|
|
156
|
+
const entityName = row.syen_name || 'Unknown Entity';
|
|
157
|
+
return `
|
|
158
|
+
<div class="tw-flex tw-items-center tw-space-x-3">
|
|
159
|
+
<div class="tw-flex-shrink-0 tw-w-10 tw-h-10 tw-bg-blue-100 tw-rounded-full tw-flex tw-items-center tw-justify-center">
|
|
160
|
+
<span class="tw-text-blue-600 tw-font-semibold tw-text-sm">
|
|
161
|
+
${entityCode.substring(0, 2).toUpperCase()}
|
|
162
|
+
</span>
|
|
163
|
+
</div>
|
|
164
|
+
<div class="tw-flex-1 tw-min-w-0">
|
|
165
|
+
<p class="tw-text-sm tw-font-medium tw-text-gray-900 tw-truncate" title="${entityName}">
|
|
166
|
+
${entityName}
|
|
167
|
+
</p>
|
|
168
|
+
<p class="tw-text-sm tw-text-gray-500 tw-truncate" title="${entityCode}">
|
|
169
|
+
Code: ${entityCode}
|
|
170
|
+
</p>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
`;
|
|
174
|
+
},
|
|
175
|
+
contactInfoRenderer: (value, row) => {
|
|
176
|
+
const contactPerson = row.syen_corporate_contact_person_user || 'N/A';
|
|
177
|
+
const email = row.syen_corporate_email || 'N/A';
|
|
178
|
+
const phone = row.syen_corporate_phone ? String(row.syen_corporate_phone) : 'N/A';
|
|
179
|
+
return `
|
|
180
|
+
<div class="tw-space-y-1">
|
|
181
|
+
<p class="tw-text-sm tw-text-gray-900 tw-truncate tw-flex tw-items-center" title="${contactPerson}">
|
|
182
|
+
<svg class="tw-flex-shrink-0 tw-w-4 tw-h-4 tw-text-gray-400 tw-mr-2" fill="currentColor" viewBox="0 0 20 20">
|
|
183
|
+
<path d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"/>
|
|
184
|
+
</svg>
|
|
185
|
+
<span class="tw-truncate">${contactPerson}</span>
|
|
186
|
+
</p>
|
|
187
|
+
<p class="tw-text-sm tw-text-gray-600 tw-truncate tw-flex tw-items-center" title="${email}">
|
|
188
|
+
<svg class="tw-flex-shrink-0 tw-w-4 tw-h-4 tw-text-gray-400 tw-mr-2" fill="currentColor" viewBox="0 0 20 20">
|
|
189
|
+
<path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z"/>
|
|
190
|
+
<path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z"/>
|
|
191
|
+
</svg>
|
|
192
|
+
<span class="tw-truncate">${email}</span>
|
|
193
|
+
</p>
|
|
194
|
+
<p class="tw-text-sm tw-text-gray-600 tw-truncate tw-flex tw-items-center" title="${phone}">
|
|
195
|
+
<svg class="tw-flex-shrink-0 tw-w-4 tw-h-4 tw-text-gray-400 tw-mr-2" fill="currentColor" viewBox="0 0 20 20">
|
|
196
|
+
<path d="M2 3a1 1 0 011-1h2.153a1 1 0 01.986.836l.74 4.435a1 1 0 01-.54 1.06l-1.548.773a11.037 11.037 0 006.105 6.105l.774-1.548a1 1 0 011.059-.54l4.435.74a1 1 0 01.836.986V17a1 1 0 01-1 1h-2C7.82 18 2 12.18 2 5V3z"/>
|
|
197
|
+
</svg>
|
|
198
|
+
<span class="tw-truncate">${phone}</span>
|
|
199
|
+
</p>
|
|
200
|
+
</div>
|
|
201
|
+
`;
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
// Action handlers
|
|
205
|
+
this.actionHandlers = {
|
|
206
|
+
onEditEntity: (entity) => {
|
|
207
|
+
const query = generateStringFromObject({
|
|
208
|
+
syen_id: entity._id
|
|
209
|
+
});
|
|
210
|
+
this.router.navigate(['control-panel', 'entity-create', query]);
|
|
211
|
+
},
|
|
212
|
+
onDeleteEntity: (entity) => {
|
|
213
|
+
const entityName = entity.syen_name || 'this entity';
|
|
214
|
+
if (confirm(`Are you sure you want to delete ${entityName}?`)) {
|
|
215
|
+
this.onDeleteEntityConfirmed(entity._id || '');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
// Getter and setter for ngModel compatibility
|
|
221
|
+
get selectedEntityTypeValue() {
|
|
222
|
+
return this.selectedEntityType();
|
|
223
|
+
}
|
|
224
|
+
set selectedEntityTypeValue(value) {
|
|
225
|
+
this.selectedEntityType.set(value);
|
|
226
|
+
}
|
|
227
|
+
ngOnInit() {
|
|
228
|
+
console.log('🔧 ENTITY LIST: Component initializing');
|
|
229
|
+
this.updatePaginationState();
|
|
230
|
+
// Set initial loading state to false to allow grid to render
|
|
231
|
+
this.loading.set(false);
|
|
232
|
+
// Load entities from API
|
|
233
|
+
this.loadEntities();
|
|
234
|
+
}
|
|
235
|
+
// Grid event handler
|
|
236
|
+
onGridEvent(event) {
|
|
237
|
+
console.log('📡 GRID EVENT: Received grid event:', event.type, event);
|
|
238
|
+
switch (event.type) {
|
|
239
|
+
case 'rowClick':
|
|
240
|
+
this.onEntityRowClick(event.data);
|
|
241
|
+
break;
|
|
242
|
+
case 'refresh':
|
|
243
|
+
this.onEntityRefresh();
|
|
244
|
+
break;
|
|
245
|
+
case 'search':
|
|
246
|
+
this.onEntitySearch(event.data);
|
|
247
|
+
break;
|
|
248
|
+
case 'pageChange':
|
|
249
|
+
this.onEntityPageChange(event.data);
|
|
250
|
+
break;
|
|
251
|
+
default:
|
|
252
|
+
console.log('Unhandled grid event:', event.type);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Event handlers for grid events
|
|
256
|
+
onEntityRowClick(entity) {
|
|
257
|
+
console.log('Entity row clicked:', entity);
|
|
258
|
+
this.router.navigate(['admin', 'entity', 'view', entity._id]);
|
|
259
|
+
}
|
|
260
|
+
onEntityRefresh() {
|
|
261
|
+
console.log('Refreshing entities...');
|
|
262
|
+
this.loadEntities(true);
|
|
263
|
+
}
|
|
264
|
+
onEntitySearch(query) {
|
|
265
|
+
console.log('Search entities:', query);
|
|
266
|
+
this.searchQuery.set(query);
|
|
267
|
+
// The grid handles the actual filtering
|
|
268
|
+
}
|
|
269
|
+
onEntityPageChange(page) {
|
|
270
|
+
console.log('Page changed to:', page);
|
|
271
|
+
this.currentPage.set(page);
|
|
272
|
+
// Reload data for the new page
|
|
273
|
+
this.loadEntities(false);
|
|
274
|
+
}
|
|
275
|
+
onDeleteEntityConfirmed(entityId) {
|
|
276
|
+
// In a real app, you'd call the API to delete
|
|
277
|
+
console.log('Deleting entity:', entityId);
|
|
278
|
+
// For now, just reload the entities
|
|
279
|
+
this.loadEntities(true);
|
|
280
|
+
}
|
|
281
|
+
// Update grid data method
|
|
282
|
+
updateGridData(entities) {
|
|
283
|
+
console.log('📊 GRID UPDATE: Updating grid with', entities.length, 'entities');
|
|
284
|
+
console.log('📊 GRID UPDATE: Sample entity data:', entities[0] || 'No entities');
|
|
285
|
+
// Set the entities signal
|
|
286
|
+
this.entities.set(entities);
|
|
287
|
+
// Update grid configuration with new data and ensure loading is false
|
|
288
|
+
this.gridConfig.update(config => ({
|
|
289
|
+
...config,
|
|
290
|
+
data: entities
|
|
291
|
+
}));
|
|
292
|
+
// Ensure loading states are cleared
|
|
293
|
+
this.loading.set(false);
|
|
294
|
+
// Clear page change loading state in the grid component
|
|
295
|
+
if (this.gridComponent) {
|
|
296
|
+
this.gridComponent.clearPageChangeLoading();
|
|
297
|
+
}
|
|
298
|
+
console.log('📊 GRID UPDATE: Grid config updated successfully');
|
|
299
|
+
console.log('📊 GRID UPDATE: Current grid data length:', this.gridConfig().data.length);
|
|
300
|
+
console.log('📊 GRID UPDATE: Loading state:', this.loading());
|
|
301
|
+
console.log('📊 GRID UPDATE: Full grid config for debugging:', JSON.stringify(this.gridConfig(), null, 2));
|
|
302
|
+
}
|
|
303
|
+
loadEntities(isRefresh = false) {
|
|
304
|
+
if (isRefresh) {
|
|
305
|
+
console.log('🔄 ENTITY LIST: Refreshing entities');
|
|
306
|
+
// Set the grid's refresh state to true
|
|
307
|
+
if (this.gridComponent) {
|
|
308
|
+
this.gridComponent.setRefreshing(true);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
this.loading.set(true);
|
|
313
|
+
console.log('🔍 ENTITY LIST: Loading entities from API');
|
|
314
|
+
}
|
|
315
|
+
this.error.set(null);
|
|
316
|
+
this.loadStartTime = Date.now();
|
|
317
|
+
this.entityService.getAllEntities().subscribe({
|
|
318
|
+
next: (response) => {
|
|
319
|
+
console.log('✅ ENTITY LIST: API response received:', response);
|
|
320
|
+
// Process the response data
|
|
321
|
+
if (response?.data) {
|
|
322
|
+
// Handle both array and single object responses
|
|
323
|
+
const entitiesData = Array.isArray(response.data) ? response.data : [response.data];
|
|
324
|
+
console.log('📋 ENTITY LIST: Processed entities data:', entitiesData.length, 'entities');
|
|
325
|
+
if (entitiesData.length > 0) {
|
|
326
|
+
console.log('📊 ENTITY LIST: First entity sample:', entitiesData[0]);
|
|
327
|
+
this.updateGridData(entitiesData);
|
|
328
|
+
this.totalItems.set(entitiesData.length);
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
console.log('📊 ENTITY LIST: No entities returned, showing test data');
|
|
332
|
+
this.loadTestData();
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
console.warn('⚠️ ENTITY LIST: No data in API response, loading test data');
|
|
337
|
+
this.loadTestData();
|
|
338
|
+
}
|
|
339
|
+
this.updatePaginationState();
|
|
340
|
+
this.loading.set(false);
|
|
341
|
+
// Clear page change loading state in the grid component
|
|
342
|
+
if (this.gridComponent) {
|
|
343
|
+
this.gridComponent.clearPageChangeLoading();
|
|
344
|
+
}
|
|
345
|
+
// Set the grid's refresh state to false when done
|
|
346
|
+
if (isRefresh && this.gridComponent) {
|
|
347
|
+
this.gridComponent.setRefreshing(false);
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
error: (err) => {
|
|
351
|
+
console.error('❌ ENTITY LIST: API error:', err);
|
|
352
|
+
console.log('🧪 ENTITY LIST: API failed, loading test data for demonstration');
|
|
353
|
+
// Load test data when API fails
|
|
354
|
+
this.loadTestData();
|
|
355
|
+
this.error.set('API unavailable. Showing sample data.');
|
|
356
|
+
this.loading.set(false);
|
|
357
|
+
// Clear page change loading state in the grid component
|
|
358
|
+
if (this.gridComponent) {
|
|
359
|
+
this.gridComponent.clearPageChangeLoading();
|
|
360
|
+
}
|
|
361
|
+
// Set the grid's refresh state to false when done
|
|
362
|
+
if (isRefresh && this.gridComponent) {
|
|
363
|
+
this.gridComponent.setRefreshing(false);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
loadTestData() {
|
|
369
|
+
console.log('🧪 ENTITY LIST: Loading test data');
|
|
370
|
+
const testData = [
|
|
371
|
+
{
|
|
372
|
+
_id: 'test-1',
|
|
373
|
+
syen_name: 'Test University',
|
|
374
|
+
syen_entity_code: 'TEST001',
|
|
375
|
+
syen_corporate_email: 'test@university.com',
|
|
376
|
+
syen_corporate_contact_person_user: 'John Doe',
|
|
377
|
+
syen_corporate_phone: 9876543210, // Now a number
|
|
378
|
+
syen_isactive: true,
|
|
379
|
+
syen_entity_type_gmst: 'university',
|
|
380
|
+
children: []
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
_id: 'test-2',
|
|
384
|
+
syen_name: 'Sample College',
|
|
385
|
+
syen_entity_code: 'SAMP002',
|
|
386
|
+
syen_corporate_email: 'info@samplecollege.edu',
|
|
387
|
+
syen_corporate_contact_person_user: 'Jane Smith',
|
|
388
|
+
syen_corporate_phone: 9876543211,
|
|
389
|
+
syen_isactive: false,
|
|
390
|
+
syen_entity_type_gmst: 'college',
|
|
391
|
+
children: []
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
_id: 'test-3',
|
|
395
|
+
syen_name: 'Global Institute of Technology',
|
|
396
|
+
syen_entity_code: 'GIT003',
|
|
397
|
+
syen_corporate_email: 'admin@git.edu',
|
|
398
|
+
syen_corporate_contact_person_user: 'Bob Johnson',
|
|
399
|
+
syen_corporate_phone: 9876543212,
|
|
400
|
+
syen_isactive: true,
|
|
401
|
+
syen_entity_type_gmst: 'institute',
|
|
402
|
+
children: []
|
|
403
|
+
}
|
|
404
|
+
];
|
|
405
|
+
console.log('🧪 ENTITY LIST: Test data prepared:', testData);
|
|
406
|
+
this.updateGridData(testData);
|
|
407
|
+
this.totalItems.set(testData.length);
|
|
408
|
+
}
|
|
409
|
+
updatePaginationState() {
|
|
410
|
+
const total = Math.ceil(this.totalItems() / this.pageSize());
|
|
411
|
+
this.totalPages.set(total);
|
|
412
|
+
this.hasNextPage.set(this.currentPage() < total);
|
|
413
|
+
this.hasPreviousPage.set(this.currentPage() > 1);
|
|
414
|
+
}
|
|
415
|
+
onSearch() {
|
|
416
|
+
this.currentPage.set(1);
|
|
417
|
+
this.loadEntities();
|
|
418
|
+
}
|
|
419
|
+
onFilterChange() {
|
|
420
|
+
this.currentPage.set(1);
|
|
421
|
+
this.loadEntities();
|
|
422
|
+
}
|
|
423
|
+
onPageChange(page) {
|
|
424
|
+
if (parseInt(page) >= 1 && parseInt(page) <= this.totalPages()) {
|
|
425
|
+
this.currentPage.set(parseInt(page));
|
|
426
|
+
this.loadEntities();
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
onPageSizeChange() {
|
|
430
|
+
this.currentPage.set(1);
|
|
431
|
+
this.loadEntities();
|
|
432
|
+
}
|
|
433
|
+
onRefresh() {
|
|
434
|
+
this.loadEntities(true); // Pass true for refresh
|
|
435
|
+
}
|
|
436
|
+
onAddEntity() {
|
|
437
|
+
// Navigate to entity create form
|
|
438
|
+
this.router.navigate(['/control-panel/entity-create']);
|
|
439
|
+
}
|
|
440
|
+
onEditEntity(entity) {
|
|
441
|
+
// TODO: Implement edit functionality - navigate to edit form with entity ID
|
|
442
|
+
this.router.navigate(['/control-panel/entity-create'], {
|
|
443
|
+
queryParams: { id: entity._id, mode: 'edit' }
|
|
444
|
+
});
|
|
445
|
+
console.log('Edit entity:', entity);
|
|
446
|
+
}
|
|
447
|
+
onViewEntity(entity) {
|
|
448
|
+
// TODO: Implement view functionality
|
|
449
|
+
console.log('View entity:', entity);
|
|
450
|
+
}
|
|
451
|
+
onDeleteEntity(entity) {
|
|
452
|
+
if (confirm(`Are you sure you want to delete "${entity.syen_name}"?`)) {
|
|
453
|
+
// TODO: Implement delete functionality
|
|
454
|
+
console.log('Delete entity:', entity);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
getStatusClass(isActive) {
|
|
458
|
+
return isActive
|
|
459
|
+
? 'tw-bg-green-100 tw-text-green-800'
|
|
460
|
+
: 'tw-bg-red-100 tw-text-red-800';
|
|
461
|
+
}
|
|
462
|
+
getStatusText(isActive) {
|
|
463
|
+
return isActive ? 'Active' : 'Inactive';
|
|
464
|
+
}
|
|
465
|
+
formatDate(date) {
|
|
466
|
+
if (!date)
|
|
467
|
+
return 'N/A';
|
|
468
|
+
return new Date(date).toLocaleDateString();
|
|
469
|
+
}
|
|
470
|
+
// Pagination helper methods
|
|
471
|
+
getPageNumbers() {
|
|
472
|
+
const total = this.totalPages();
|
|
473
|
+
const current = this.currentPage();
|
|
474
|
+
const delta = 2; // Number of pages to show on each side of current page
|
|
475
|
+
const pages = [];
|
|
476
|
+
const start = Math.max(1, current - delta);
|
|
477
|
+
const end = Math.min(total, current + delta);
|
|
478
|
+
for (let i = start; i <= end; i++) {
|
|
479
|
+
pages.push(i);
|
|
480
|
+
}
|
|
481
|
+
return pages;
|
|
482
|
+
}
|
|
483
|
+
getItemRangeText() {
|
|
484
|
+
const start = (this.currentPage() - 1) * this.pageSize() + 1;
|
|
485
|
+
const end = Math.min(this.currentPage() * this.pageSize(), this.totalItems());
|
|
486
|
+
const total = this.totalItems();
|
|
487
|
+
return `${start}-${end} of ${total}`;
|
|
488
|
+
}
|
|
489
|
+
trackByEntityId(index, entity) {
|
|
490
|
+
return entity?._id || '';
|
|
491
|
+
}
|
|
492
|
+
// ===== Enhanced Pagination Methods =====
|
|
493
|
+
/**
|
|
494
|
+
* Get enhanced page numbers with ellipsis for better navigation
|
|
495
|
+
*/
|
|
496
|
+
getEnhancedPageNumbers() {
|
|
497
|
+
const total = this.totalPages();
|
|
498
|
+
const current = this.currentPage();
|
|
499
|
+
const pages = [];
|
|
500
|
+
if (total <= 7) {
|
|
501
|
+
// Show all pages if 7 or fewer
|
|
502
|
+
for (let i = 1; i <= total; i++) {
|
|
503
|
+
pages.push(i);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
// Always show first page
|
|
508
|
+
pages.push(1);
|
|
509
|
+
if (current <= 4) {
|
|
510
|
+
// Current page is near the beginning
|
|
511
|
+
for (let i = 2; i <= 5; i++) {
|
|
512
|
+
pages.push(i);
|
|
513
|
+
}
|
|
514
|
+
pages.push('...');
|
|
515
|
+
pages.push(total);
|
|
516
|
+
}
|
|
517
|
+
else if (current >= total - 3) {
|
|
518
|
+
// Current page is near the end
|
|
519
|
+
pages.push('...');
|
|
520
|
+
for (let i = total - 4; i <= total; i++) {
|
|
521
|
+
pages.push(i);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
// Current page is in the middle
|
|
526
|
+
pages.push('...');
|
|
527
|
+
for (let i = current - 1; i <= current + 1; i++) {
|
|
528
|
+
pages.push(i);
|
|
529
|
+
}
|
|
530
|
+
pages.push('...');
|
|
531
|
+
pages.push(total);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
return pages;
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Calculate progress percentage based on current position
|
|
538
|
+
*/
|
|
539
|
+
getProgressPercentage() {
|
|
540
|
+
if (this.totalPages() === 0)
|
|
541
|
+
return 0;
|
|
542
|
+
return Math.round((this.currentPage() / this.totalPages()) * 100);
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Jump to specific page functionality
|
|
546
|
+
*/
|
|
547
|
+
onJumpToPage() {
|
|
548
|
+
if (this.jumpToPage >= 1 && this.jumpToPage <= this.totalPages()) {
|
|
549
|
+
this.onPageChange(this.jumpToPage);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Get simulated load time for performance display
|
|
554
|
+
*/
|
|
555
|
+
getLoadTime() {
|
|
556
|
+
return this.loadStartTime > 0 ? Date.now() - this.loadStartTime : 0;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Get total data size for display
|
|
560
|
+
*/
|
|
561
|
+
getTotalDataSize() {
|
|
562
|
+
return this.totalItems();
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Export current page entities
|
|
566
|
+
*/
|
|
567
|
+
onExportCurrentPage() {
|
|
568
|
+
const currentPageEntities = this.entities();
|
|
569
|
+
console.log('Exporting current page:', currentPageEntities);
|
|
570
|
+
// TODO: Implement actual export functionality
|
|
571
|
+
alert(`Exporting ${currentPageEntities.length} entities from current page`);
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Export all entities
|
|
575
|
+
*/
|
|
576
|
+
onExportAll() {
|
|
577
|
+
console.log('Exporting all entities');
|
|
578
|
+
// TODO: Implement actual export functionality
|
|
579
|
+
alert(`Exporting all ${this.totalItems()} entities`);
|
|
580
|
+
}
|
|
581
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideAdmEntityListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
582
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: CideAdmEntityListComponent, isStandalone: true, selector: "cide-adm-entity-list", viewQueries: [{ propertyName: "gridComponent", first: true, predicate: CideEleDataGridComponent, descendants: true }], ngImport: i0, template: "<!-- Entity List Container -->\n<div class=\"entity-list-container tw-bg-white tw-shadow-lg tw-rounded-lg tw-overflow-hidden\">\n \n <!-- Header Section with Filters -->\n <div class=\"tw-px-6 tw-py-4 tw-border-b tw-border-gray-200 tw-bg-gray-50\">\n <div class=\"tw-flex tw-flex-col sm:tw-flex-row tw-justify-between tw-items-start sm:tw-items-center tw-space-y-4 sm:tw-space-y-0\">\n \n <!-- Title -->\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\n <cide-ele-icon class=\"tw-text-blue-600\">apartment</cide-ele-icon>\n <div>\n <h5 class=\"tw-text-md tw-font-semibold tw-text-gray-900\">Entity Management</h5>\n <p class=\"tw-text-sm tw-text-gray-600\">Manage and view all entities in the system</p>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\n <!-- Entity Type Filter -->\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <label for=\"entityTypeFilter\" class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Type:</label>\n <cide-ele-select\n id=\"entityTypeFilter\"\n [options]=\"entityTypeOptions()\"\n [(ngModel)]=\"selectedEntityTypeValue\"\n (ngModelChange)=\"loadEntities()\"\n class=\"tw-min-w-40\">\n </cide-ele-select>\n </div>\n\n <!-- Add Entity Button -->\n <button\n cideEleButton\n variant=\"primary\"\n size=\"sm\"\n (click)=\"router.navigate(['control-panel', 'entity-create'])\"\n class=\"tw-whitespace-nowrap tw-flex tw-items-center tw-gap-2\">\n <cide-ele-icon size=\"xs\" class=\"tw-w-6 tw-h-5\">add</cide-ele-icon>\n Add Entity\n </button>\n </div>\n </div>\n\n <!-- Error Message -->\n @if (error()) {\n <div class=\"tw-mt-4 tw-p-4 tw-bg-red-50 tw-border tw-border-red-200 tw-rounded-md\">\n <div class=\"tw-flex\">\n <cide-ele-icon name=\"exclamation-triangle\" class=\"tw-text-red-400\"></cide-ele-icon>\n <div class=\"tw-ml-3\">\n <h3 class=\"tw-text-sm tw-font-medium tw-text-red-800\">Error</h3>\n <p class=\"tw-text-sm tw-text-red-700 tw-mt-1\">{{ error() }}</p>\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Data Grid Component -->\n <cide-ele-data-grid\n [config]=\"gridConfig()\"\n [customRenderers]=\"customRenderers\"\n [actionHandlers]=\"actionHandlers\"\n (gridEvent)=\"onGridEvent($event)\">\n </cide-ele-data-grid>\n\n</div>", styles: [".entity-list-container table tr{transition:background-color .15s ease}.entity-list-container table th{font-weight:600;letter-spacing:.025em}.entity-list-container table td{vertical-align:top}.entity-list-container .tw-text-red-600:hover{background-color:theme(\"colors.red.50\")}.entity-list-container .tw-animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.entity-list-container .tw-overflow-x-auto{scrollbar-width:thin;scrollbar-color:theme(\"colors.gray.300\") theme(\"colors.gray.100\")}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar{height:8px}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar-track{background:theme(\"colors.gray.100\");border-radius:4px}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar-thumb{background:theme(\"colors.gray.300\");border-radius:4px}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover{background:theme(\"colors.gray.400\")}@media (max-width: 768px){.entity-list-container .tw-px-6{padding-left:theme(\"spacing.4\");padding-right:theme(\"spacing.4\")}}\n", ":host{height:100%;display:flex;flex-direction:column}.entity-list-container{height:100%;display:flex;flex-direction:column;overflow:hidden}.tw-overflow-auto{flex:1;min-height:0}cide-ele-data-grid{flex:1;min-height:0;display:flex;flex-direction:column}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton]", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }, { kind: "component", type: CideSelectComponent, selector: "cide-ele-select", inputs: ["label", "labelHide", "placeholder", "helperText", "errorText", "required", "disabled", "id", "ngModel", "size", "fill", "labelPlacement", "labelDir", "leadingIcon", "trailingIcon", "clearInput", "options", "multiple", "searchable", "showSearchInput", "loading"], outputs: ["ngModelChange", "change", "searchChange"] }, { kind: "component", type: CideEleDataGridComponent, selector: "cide-ele-data-grid", inputs: ["config", "customRenderers", "templateRenderers", "customFormatters", "actionHandlers", "serverSidePagination", "totalServerItems", "currentServerPage", "currentServerPageSize", "dragDropEnabled"], outputs: ["gridEvent"] }] }); }
|
|
583
|
+
}
|
|
584
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideAdmEntityListComponent, decorators: [{
|
|
585
|
+
type: Component,
|
|
586
|
+
args: [{ selector: 'cide-adm-entity-list', standalone: true, imports: [
|
|
587
|
+
CommonModule,
|
|
588
|
+
FormsModule,
|
|
589
|
+
CideInputComponent,
|
|
590
|
+
CideIconComponent,
|
|
591
|
+
CideEleButtonComponent,
|
|
592
|
+
CideSelectComponent,
|
|
593
|
+
TooltipDirective,
|
|
594
|
+
CideEleDataGridComponent
|
|
595
|
+
], template: "<!-- Entity List Container -->\n<div class=\"entity-list-container tw-bg-white tw-shadow-lg tw-rounded-lg tw-overflow-hidden\">\n \n <!-- Header Section with Filters -->\n <div class=\"tw-px-6 tw-py-4 tw-border-b tw-border-gray-200 tw-bg-gray-50\">\n <div class=\"tw-flex tw-flex-col sm:tw-flex-row tw-justify-between tw-items-start sm:tw-items-center tw-space-y-4 sm:tw-space-y-0\">\n \n <!-- Title -->\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\n <cide-ele-icon class=\"tw-text-blue-600\">apartment</cide-ele-icon>\n <div>\n <h5 class=\"tw-text-md tw-font-semibold tw-text-gray-900\">Entity Management</h5>\n <p class=\"tw-text-sm tw-text-gray-600\">Manage and view all entities in the system</p>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\n <!-- Entity Type Filter -->\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <label for=\"entityTypeFilter\" class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Type:</label>\n <cide-ele-select\n id=\"entityTypeFilter\"\n [options]=\"entityTypeOptions()\"\n [(ngModel)]=\"selectedEntityTypeValue\"\n (ngModelChange)=\"loadEntities()\"\n class=\"tw-min-w-40\">\n </cide-ele-select>\n </div>\n\n <!-- Add Entity Button -->\n <button\n cideEleButton\n variant=\"primary\"\n size=\"sm\"\n (click)=\"router.navigate(['control-panel', 'entity-create'])\"\n class=\"tw-whitespace-nowrap tw-flex tw-items-center tw-gap-2\">\n <cide-ele-icon size=\"xs\" class=\"tw-w-6 tw-h-5\">add</cide-ele-icon>\n Add Entity\n </button>\n </div>\n </div>\n\n <!-- Error Message -->\n @if (error()) {\n <div class=\"tw-mt-4 tw-p-4 tw-bg-red-50 tw-border tw-border-red-200 tw-rounded-md\">\n <div class=\"tw-flex\">\n <cide-ele-icon name=\"exclamation-triangle\" class=\"tw-text-red-400\"></cide-ele-icon>\n <div class=\"tw-ml-3\">\n <h3 class=\"tw-text-sm tw-font-medium tw-text-red-800\">Error</h3>\n <p class=\"tw-text-sm tw-text-red-700 tw-mt-1\">{{ error() }}</p>\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Data Grid Component -->\n <cide-ele-data-grid\n [config]=\"gridConfig()\"\n [customRenderers]=\"customRenderers\"\n [actionHandlers]=\"actionHandlers\"\n (gridEvent)=\"onGridEvent($event)\">\n </cide-ele-data-grid>\n\n</div>", styles: [".entity-list-container table tr{transition:background-color .15s ease}.entity-list-container table th{font-weight:600;letter-spacing:.025em}.entity-list-container table td{vertical-align:top}.entity-list-container .tw-text-red-600:hover{background-color:theme(\"colors.red.50\")}.entity-list-container .tw-animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.entity-list-container .tw-overflow-x-auto{scrollbar-width:thin;scrollbar-color:theme(\"colors.gray.300\") theme(\"colors.gray.100\")}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar{height:8px}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar-track{background:theme(\"colors.gray.100\");border-radius:4px}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar-thumb{background:theme(\"colors.gray.300\");border-radius:4px}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover{background:theme(\"colors.gray.400\")}@media (max-width: 768px){.entity-list-container .tw-px-6{padding-left:theme(\"spacing.4\");padding-right:theme(\"spacing.4\")}}\n", ":host{height:100%;display:flex;flex-direction:column}.entity-list-container{height:100%;display:flex;flex-direction:column;overflow:hidden}.tw-overflow-auto{flex:1;min-height:0}cide-ele-data-grid{flex:1;min-height:0;display:flex;flex-direction:column}\n"] }]
|
|
596
|
+
}], propDecorators: { gridComponent: [{
|
|
597
|
+
type: ViewChild,
|
|
598
|
+
args: [CideEleDataGridComponent]
|
|
599
|
+
}] } });
|
|
600
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2lkZS1hZG0tZW50aXR5LWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2xvdWQtaWRlLWFkbWluL3NyYy9saWIvYWRtaW4tbW9kdWxlL2VudGl0eS9saXN0L2NpZGUtYWRtLWVudGl0eS1saXN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Nsb3VkLWlkZS1hZG1pbi9zcmMvbGliL2FkbWluLW1vZHVsZS9lbnRpdHkvbGlzdC9jaWRlLWFkbS1lbnRpdHktbGlzdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBVSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFDTCxrQkFBa0IsRUFDbEIsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNqQixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2hGLE9BQU8sRUFBRSx3QkFBd0IsRUFBK0IsTUFBTSxtQkFBbUIsQ0FBQztBQUMxRixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMxRSxPQUFPLEVBQWdELHdCQUF3QixFQUFFLE1BQU0scUJBQXFCLENBQUM7OztBQTZDN0csTUFBTSxPQUFPLDBCQUEwQjtJQTFDdkM7UUEyQ0UsNkNBQTZDO1FBQzdDLFdBQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBRSxrQ0FB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IHNpZ25hbCwgT25Jbml0LCBpbmplY3QsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7XG4gIENpZGVJbnB1dENvbXBvbmVudCxcbiAgQ2lkZUljb25Db21wb25lbnQsXG4gIFRvb2x0aXBEaXJlY3RpdmVcbn0gZnJvbSAnY2xvdWQtaWRlLWVsZW1lbnQnO1xuaW1wb3J0IHsgQ2lkZUVsZUJ1dHRvbkNvbXBvbmVudCwgQ2lkZVNlbGVjdENvbXBvbmVudCB9IGZyb20gJ2Nsb3VkLWlkZS1lbGVtZW50JztcbmltcG9ydCB7IENpZGVFbGVEYXRhR3JpZENvbXBvbmVudCAsR3JpZENvbmZpZ3VyYXRpb24sIEdyaWRFdmVudH0gZnJvbSAnY2xvdWQtaWRlLWVsZW1lbnQnO1xuaW1wb3J0IHsgQ2lkZUFkbUVudGl0eUxpc3RTZXJ2aWNlIH0gZnJvbSAnLi9jaWRlLWFkbS1lbnRpdHktbGlzdC5zZXJ2aWNlJztcbmltcG9ydCB7IGVudGl0eUNvbnRyb2xsZXJSZXNwb25zZSwgZW50aXR5UmVzcG9uc2VEYXRhLCBnZW5lcmF0ZVN0cmluZ0Zyb21PYmplY3QgfSBmcm9tICdjbG91ZC1pZGUtbG1zLW1vZGVsJztcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjaWRlLWFkbS1lbnRpdHktbGlzdCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgQ2lkZUlucHV0Q29tcG9uZW50LFxuICAgIENpZGVJY29uQ29tcG9uZW50LFxuICAgIENpZGVFbGVCdXR0b25Db21wb25lbnQsXG4gICAgQ2lkZVNlbGVjdENvbXBvbmVudCxcbiAgICBUb29sdGlwRGlyZWN0aXZlLFxuICAgIENpZGVFbGVEYXRhR3JpZENvbXBvbmVudFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vY2lkZS1hZG0tZW50aXR5LWxpc3QuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vY2lkZS1hZG0tZW50aXR5LWxpc3QuY29tcG9uZW50LnNjc3MnLFxuICBzdHlsZXM6IFtgXG4gICAgOmhvc3Qge1xuICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgfVxuICAgIFxuICAgIC5lbnRpdHktbGlzdC1jb250YWluZXIge1xuICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIH1cbiAgICBcbiAgICAudHctb3ZlcmZsb3ctYXV0byB7XG4gICAgICBmbGV4OiAxO1xuICAgICAgbWluLWhlaWdodDogMDtcbiAgICB9XG4gICAgXG4gICAgY2lkZS1lbGUtZGF0YS1ncmlkIHtcbiAgICAgIGZsZXg6IDE7XG4gICAgICBtaW4taGVpZ2h0OiAwO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgfVxuICBgXVxufSlcbmV4cG9ydCBjbGFzcyBDaWRlQWRtRW50aXR5TGlzdENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIC8vIE1vZGVybiBkZXBlbmRlbmN5IGluamVjdGlvbiB1c2luZyBpbmplY3QoKVxuICByb3V0ZXIgPSBpbmplY3QoUm91dGVyKTsgIC8vIE1hZGUgcHVibGljIGZvciB0ZW1wbGF0ZSBhY2Nlc3NcbiAgcHJpdmF0ZSBlbnRpdHlTZXJ2aWNlID0gaW5qZWN0KENpZGVBZG1FbnRpdHlMaXN0U2VydmljZSk7XG5cbiAgLy8gVmlld0NoaWxkIHJlZmVyZW5jZSB0byB0aGUgZ3JpZCBjb21wb25lbnRcbiAgQFZpZXdDaGlsZChDaWRlRWxlRGF0YUdyaWRDb21wb25lbnQpIGdyaWRDb21wb25lbnQhOiBDaWRlRWxlRGF0YUdyaWRDb21wb25lbnQ8ZW50aXR5UmVzcG9uc2VEYXRhPjtcblxuICAvLyBTdGF0ZSBtYW5hZ2VtZW50IHVzaW5nIEFuZ3VsYXIgU2lnbmFsc1xuICBlbnRpdGllcyA9IHNpZ25hbDxlbnRpdHlSZXNwb25zZURhdGFbXT4oW10pO1xuICBsb2FkaW5nID0gc2lnbmFsKGZhbHNlKTtcbiAgZXJyb3IgPSBzaWduYWw8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gIHNlYXJjaFF1ZXJ5ID0gc2lnbmFsKCcnKTtcbiAgY3VycmVudFBhZ2UgPSBzaWduYWwoMSk7XG4gIHBhZ2VTaXplID0gc2lnbmFsKDEwKTtcbiAgdG90YWxJdGVtcyA9IHNpZ25hbCgwKTtcbiAgc2VsZWN0ZWRFbnRpdHlUeXBlID0gc2lnbmFsKCcnKTtcblxuICAvLyBHZXR0ZXIgYW5kIHNldHRlciBmb3IgbmdNb2RlbCBjb21wYXRpYmlsaXR5XG4gIGdldCBzZWxlY3RlZEVudGl0eVR5cGVWYWx1ZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkRW50aXR5VHlwZSgpO1xuICB9XG5cbiAgc2V0IHNlbGVjdGVkRW50aXR5VHlwZVZhbHVlKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLnNlbGVjdGVkRW50aXR5VHlwZS5zZXQodmFsdWUpO1xuICB9XG5cbiAgLy8gUGFnaW5hdGlvbiBjYWxjdWxhdGlvbnNcbiAgdG90YWxQYWdlcyA9IHNpZ25hbCgwKTtcbiAgaGFzTmV4dFBhZ2UgPSBzaWduYWwoZmFsc2UpO1xuICBoYXNQcmV2aW91c1BhZ2UgPSBzaWduYWwoZmFsc2UpO1xuICBqdW1wVG9QYWdlOiBudW1iZXIgPSAxO1xuICBsb2FkU3RhcnRUaW1lOiBudW1iZXIgPSAwO1xuXG4gIC8vIEZpbHRlciBvcHRpb25zXG4gIGVudGl0eVR5cGVPcHRpb25zID0gc2lnbmFsKFtcbiAgICB7IHZhbHVlOiAnJywgbGFiZWw6ICdBbGwgRW50aXR5IFR5cGVzJyB9LFxuICAgIHsgdmFsdWU6ICdzY2hvb2wnLCBsYWJlbDogJ1NjaG9vbCcgfSxcbiAgICB7IHZhbHVlOiAnY29sbGVnZScsIGxhYmVsOiAnQ29sbGVnZScgfSxcbiAgICB7IHZhbHVlOiAndW5pdmVyc2l0eScsIGxhYmVsOiAnVW5pdmVyc2l0eScgfSxcbiAgICB7IHZhbHVlOiAnaW5zdGl0dXRlJywgbGFiZWw6ICdJbnN0aXR1dGUnIH1cbiAgXSk7XG5cbiAgLy8gR3JpZCBjb25maWd1cmF0aW9uIHNpZ25hbFxuICBncmlkQ29uZmlnID0gc2lnbmFsPEdyaWRDb25maWd1cmF0aW9uPGVudGl0eVJlc3BvbnNlRGF0YT4+KHtcbiAgICBpZDogJ2VudGl0eS1saXN0LWdyaWQnLFxuICAgIHRpdGxlOiAnJyxcbiAgICBzdWJ0aXRsZTogJycsXG4gICAgY29sdW1uczogW1xuICAgICAge1xuICAgICAgICBrZXk6ICdkZXRhaWxzJyxcbiAgICAgICAgaGVhZGVyOiAnRW50aXR5IERldGFpbHMnLFxuICAgICAgICB0eXBlOiAnY3VzdG9tJyxcbiAgICAgICAgd2lkdGg6ICdsZycsXG4gICAgICAgIHRydW5jYXRlOiB0cnVlLFxuICAgICAgICBhbGlnbjogJ2xlZnQnLFxuICAgICAgICByZW5kZXJlcjogJ2VudGl0eURldGFpbHNSZW5kZXJlcidcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGtleTogJ2NvbnRhY3QnLFxuICAgICAgICBoZWFkZXI6ICdDb250YWN0IEluZm9ybWF0aW9uJyxcbiAgICAgICAgdHlwZTogJ2N1c3RvbScsXG4gICAgICAgIHdpZHRoOiAnbGcnLFxuICAgICAgICB0cnVuY2F0ZTogdHJ1ZSxcbiAgICAgICAgYWxpZ246ICdsZWZ0JyxcbiAgICAgICAgcmVuZGVyZXI6ICdjb250YWN0SW5mb1JlbmRlcmVyJ1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAga2V5OiAnc3llbl9pc2FjdGl2ZScsXG4gICAgICAgIGhlYWRlcjogJ1N0YXR1cycsXG4gICAgICAgIHR5cGU6ICdzdGF0dXMnLFxuICAgICAgICB3aWR0aDogJ21kJyxcbiAgICAgICAgdHJ1bmNhdGU6IGZhbHNlLFxuICAgICAgICBhbGlnbjogJ2NlbnRlcicsXG4gICAgICAgIHN0YXR1c0NvbmZpZzoge1xuICAgICAgICAgIGFjdGl2ZVZhbHVlOiB0cnVlLFxuICAgICAgICAgIGFjdGl2ZUxhYmVsOiAnQWN0aXZlJyxcbiAgICAgICAgICBpbmFjdGl2ZUxhYmVsOiAnSW5hY3RpdmUnLFxuICAgICAgICAgIGFjdGl2ZUNsYXNzOiAndHctYmctZ3JlZW4tMTAwIHR3LXRleHQtZ3JlZW4tODAwJyxcbiAgICAgICAgICBpbmFjdGl2ZUNsYXNzOiAndHctYmctcmVkLTEwMCB0dy10ZXh0LXJlZC04MDAnXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGtleTogJ3N5ZW5fZW50aXR5X3R5cGVfZ21zdCcsXG4gICAgICAgIGhlYWRlcjogJ0VudGl0eSBUeXBlJyxcbiAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICB3aWR0aDogJ21kJyxcbiAgICAgICAgdHJ1bmNhdGU6IGZhbHNlLFxuICAgICAgICBhbGlnbjogJ2NlbnRlcidcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGtleTogJ2FjdGlvbnMnLFxuICAgICAgICBoZWFkZXI6ICdBY3Rpb25zJyxcbiAgICAgICAgdHlwZTogJ2FjdGlvbnMnLFxuICAgICAgICB3aWR0aDogJ21kJyxcbiAgICAgICAgdHJ1bmNhdGU6IGZhbHNlLFxuICAgICAgICBhbGlnbjogJ3JpZ2h0JyxcbiAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGtleTogJ2VkaXQnLFxuICAgICAgICAgICAgbGFiZWw6ICdFZGl0JyxcbiAgICAgICAgICAgIGljb246ICdwZW5jaWwnLFxuICAgICAgICAgICAgdmFyaWFudDogJ291dGxpbmUnLFxuICAgICAgICAgICAgdG9vbHRpcDogJ0VkaXQgZW50aXR5JyxcbiAgICAgICAgICAgIG9uQ2xpY2s6ICdvbkVkaXRFbnRpdHknXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBrZXk6ICdkZWxldGUnLFxuICAgICAgICAgICAgbGFiZWw6ICdEZWxldGUnLFxuICAgICAgICAgICAgaWNvbjogJ3RyYXNoJyxcbiAgICAgICAgICAgIHZhcmlhbnQ6ICdkYW5nZXInLFxuICAgICAgICAgICAgdG9vbHRpcDogJ0RlbGV0ZSBlbnRpdHknLFxuICAgICAgICAgICAgb25DbGljazogJ29uRGVsZXRlRW50aXR5J1xuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgZGF0YTogW10sXG4gICAgdHJhY2tCeTogJ19pZCcsXG4gICAgcGFnaW5hdGlvbjoge1xuICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgIHBhZ2VTaXplOiAxMCxcbiAgICAgIHBhZ2VTaXplT3B0aW9uczogWzEwLCAyNSwgNTAsIDEwMF0sXG4gICAgICBzaG93UXVpY2tKdW1wOiB0cnVlLFxuICAgICAgc2hvd1BhZ2VJbmZvOiB0cnVlLFxuICAgICAgc2hvd1JlZnJlc2g6IHRydWVcbiAgICB9LFxuICAgIHNlYXJjaDoge1xuICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgIHBsYWNlaG9sZGVyOiAnU2VhcmNoIGVudGl0aWVzLi4uJyxcbiAgICAgIHNlYXJjaGFibGVDb2x1bW5zOiBbJ3N5ZW5fbmFtZScsICdzeWVuX2VudGl0eV9jb2RlJywgJ3N5ZW5fY29ycG9yYXRlX2VtYWlsJ10sXG4gICAgICBkZWJvdW5jZU1zOiAzMDBcbiAgICB9LFxuICAgIGxvYWRpbmc6IHtcbiAgICAgIHVzZURlZmVyOiB0cnVlLFxuICAgICAgc2tlbGV0b25Sb3dzOiA1LFxuICAgICAgc2hvd092ZXJsYXk6IGZhbHNlXG4gICAgfSxcbiAgICByZXNwb25zaXZlOiB0cnVlLFxuICAgIHN0cmlwZWQ6IGZhbHNlLFxuICAgIGJvcmRlcmVkOiB0cnVlLFxuICAgIGNvbXBhY3Q6IGZhbHNlLFxuICAgIGZ1bGxIZWlnaHQ6IHRydWUsXG4gICAgb25Sb3dDbGljazogJ29uRW50aXR5Um93Q2xpY2snLFxuICAgIG9uUmVmcmVzaDogJ29uRW50aXR5UmVmcmVzaCcsXG4gICAgdHJlZToge1xuICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgIHByaW1hcnlLZXk6ICdfaWQnLFxuICAgICAgZm9yZWlnbktleTogJ3N5ZW5fcGFyZW50X2VudGl0eV9pZCcsXG4gICAgICBjaGlsZHJlbktleTogJ2NoaWxkcmVuJyxcbiAgICAgIGxldmVsS2V5OiAnbGV2ZWwnLFxuICAgICAgZXhwYW5kZWRLZXk6ICdpc0V4cGFuZGVkJyxcbiAgICAgIGhhc0NoaWxkcmVuS2V5OiAnaGFzQ2hpbGRyZW4nXG4gICAgfVxuICB9KTtcblxuICAvLyBDdXN0b20gcmVuZGVyZXJzIGZvciBjb21wbGV4IGNvbHVtbnNcbiAgY3VzdG9tUmVuZGVyZXJzID0ge1xuICAgIGVudGl0eURldGFpbHNSZW5kZXJlcjogKHZhbHVlOiB1bmtub3duLCByb3c6IGVudGl0eVJlc3BvbnNlRGF0YSk6IHN0cmluZyA9PiB7XG4gICAgICBjb25zdCBlbnRpdHlDb2RlID0gcm93LnN5ZW5fZW50aXR5X2NvZGUgfHwgJ04vQSc7XG4gICAgICBjb25zdCBlbnRpdHlOYW1lID0gcm93LnN5ZW5fbmFtZSB8fCAnVW5rbm93biBFbnRpdHknO1xuXG4gICAgICByZXR1cm4gYFxuICAgICAgICA8ZGl2IGNsYXNzPVwidHctZmxleCB0dy1pdGVtcy1jZW50ZXIgdHctc3BhY2UteC0zXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInR3LWZsZXgtc2hyaW5rLTAgdHctdy0xMCB0dy1oLTEwIHR3LWJnLWJsdWUtMTAwIHR3LXJvdW5kZWQtZnVsbCB0dy1mbGV4IHR3LWl0ZW1zLWNlbnRlciB0dy1qdXN0aWZ5LWNlbnRlclwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0dy10ZXh0LWJsdWUtNjAwIHR3LWZvbnQtc2VtaWJvbGQgdHctdGV4dC1zbVwiPlxuICAgICAgICAgICAgICAke2VudGl0eUNvZGUuc3Vic3RyaW5nKDAsIDIpLnRvVXBwZXJDYXNlKCl9XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInR3LWZsZXgtMSB0dy1taW4tdy0wXCI+XG4gICAgICAgICAgICA8cCBjbGFzcz1cInR3LXRleHQtc20gdHctZm9udC1tZWRpdW0gdHctdGV4dC1ncmF5LTkwMCB0dy10cnVuY2F0ZVwiIHRpdGxlPVwiJHtlbnRpdHlOYW1lfVwiPlxuICAgICAgICAgICAgICAke2VudGl0eU5hbWV9XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8cCBjbGFzcz1cInR3LXRleHQtc20gdHctdGV4dC1ncmF5LTUwMCB0dy10cnVuY2F0ZVwiIHRpdGxlPVwiJHtlbnRpdHlDb2RlfVwiPlxuICAgICAgICAgICAgICBDb2RlOiAke2VudGl0eUNvZGV9XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgYDtcbiAgICB9LFxuXG4gICAgY29udGFjdEluZm9SZW5kZXJlcjogKHZhbHVlOiB1bmtub3duLCByb3c6IGVudGl0eVJlc3BvbnNlRGF0YSk6IHN0cmluZyA9PiB7XG4gICAgICBjb25zdCBjb250YWN0UGVyc29uID0gcm93LnN5ZW5fY29ycG9yYXRlX2NvbnRhY3RfcGVyc29uX3VzZXIgfHwgJ04vQSc7XG4gICAgICBjb25zdCBlbWFpbCA9IHJvdy5zeWVuX2NvcnBvcmF0ZV9lbWFpbCB8fCAnTi9BJztcbiAgICAgIGNvbnN0IHBob25lID0gcm93LnN5ZW5fY29ycG9yYXRlX3Bob25lID8gU3RyaW5nKHJvdy5zeWVuX2NvcnBvcmF0ZV9waG9uZSkgOiAnTi9BJztcblxuICAgICAgcmV0dXJuIGBcbiAgICAgICAgPGRpdiBjbGFzcz1cInR3LXNwYWNlLXktMVwiPlxuICAgICAgICAgIDxwIGNsYXNzPVwidHctdGV4dC1zbSB0dy10ZXh0LWdyYXktOTAwIHR3LXRydW5jYXRlIHR3LWZsZXggdHctaXRlbXMtY2VudGVyXCIgdGl0bGU9XCIke2NvbnRhY3RQZXJzb259XCI+XG4gICAgICAgICAgICA8c3ZnIGNsYXNzPVwidHctZmxleC1zaHJpbmstMCB0dy13LTQgdHctaC00IHR3LXRleHQtZ3JheS00MDAgdHctbXItMlwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIiB2aWV3Qm94PVwiMCAwIDIwIDIwXCI+XG4gICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTAgOWEzIDMgMCAxMDAtNiAzIDMgMCAwMDAgNnptLTcgOWE3IDcgMCAxMTE0IDBIM3pcIi8+XG4gICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidHctdHJ1bmNhdGVcIj4ke2NvbnRhY3RQZXJzb259PC9zcGFuPlxuICAgICAgICAgIDwvcD5cbiAgICAgICAgICA8cCBjbGFzcz1cInR3LXRleHQtc20gdHctdGV4dC1ncmF5LTYwMCB0dy10cnVuY2F0ZSB0dy1mbGV4IHR3LWl0ZW1zLWNlbnRlclwiIHRpdGxlPVwiJHtlbWFpbH1cIj5cbiAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJ0dy1mbGV4LXNocmluay0wIHR3LXctNCB0dy1oLTQgdHctdGV4dC1ncmF5LTQwMCB0dy1tci0yXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiIHZpZXdCb3g9XCIwIDAgMjAgMjBcIj5cbiAgICAgICAgICAgICAgPHBhdGggZD1cIk0yLjAwMyA1Ljg4NEwxMCA5Ljg4Mmw3Ljk5Ny0zLjk5OEEyIDIgMCAwMDE2IDRINGEyIDIgMCAwMC0xLjk5NyAxLjg4NHpcIi8+XG4gICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTggOC4xMThsLTggNC04LTRWMTRhMiAyIDAgMDAyIDJoMTJhMiAyIDAgMDAyLTJWOC4xMTh6XCIvPlxuICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInR3LXRydW5jYXRlXCI+JHtlbWFpbH08L3NwYW4+XG4gICAgICAgICAgPC9wPlxuICAgICAgICAgIDxwIGNsYXNzPVwidHctdGV4dC1zbSB0dy10ZXh0LWdyYXktNjAwIHR3LXRydW5jYXRlIHR3LWZsZXggdHctaXRlbXMtY2VudGVyXCIgdGl0bGU9XCIke3Bob25lfVwiPlxuICAgICAgICAgICAgPHN2ZyBjbGFzcz1cInR3LWZsZXgtc2hyaW5rLTAgdHctdy00IHR3LWgtNCB0dy10ZXh0LWdyYXktNDAwIHR3LW1yLTJcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiPlxuICAgICAgICAgICAgICA8cGF0aCBkPVwiTTIgM2ExIDEgMCAwMTEtMWgyLjE1M2ExIDEgMCAwMS45ODYuODM2bC43NCA0LjQzNWExIDEgMCAwMS0uNTQgMS4wNmwtMS41NDguNzczYTExLjAzNyAxMS4wMzcgMCAwMDYuMTA1IDYuMTA1bC43NzQtMS41NDhhMSAxIDAgMDExLjA1OS0uNTRsNC40MzUuNzRhMSAxIDAgMDEuODM2Ljk4NlYxN2ExIDEgMCAwMS0xIDFoLTJDNy44MiAxOCAyIDEyLjE4IDIgNVYzelwiLz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0dy10cnVuY2F0ZVwiPiR7cGhvbmV9PC9zcGFuPlxuICAgICAgICAgIDwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICBgO1xuICAgIH1cbiAgfTtcblxuICAvLyBBY3Rpb24gaGFuZGxlcnNcbiAgYWN0aW9uSGFuZGxlcnMgPSB7XG4gICAgb25FZGl0RW50aXR5OiAoZW50aXR5OiBlbnRpdHlSZXNwb25zZURhdGEpID0+IHtcbiAgICAgIGNvbnN0IHF1ZXJ5OiBzdHJpbmcgPSBnZW5lcmF0ZVN0cmluZ0Zyb21PYmplY3Qoe1xuICAgICAgICBzeWVuX2lkOiBlbnRpdHkuX2lkXG4gICAgICB9KVxuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWydjb250cm9sLXBhbmVsJywgJ2VudGl0eS1jcmVhdGUnLCBxdWVyeV0pO1xuICAgIH0sXG5cbiAgICBvbkRlbGV0ZUVudGl0eTogKGVudGl0eTogZW50aXR5UmVzcG9uc2VEYXRhKSA9PiB7XG4gICAgICBjb25zdCBlbnRpdHlOYW1lID0gZW50aXR5LnN5ZW5fbmFtZSB8fCAndGhpcyBlbnRpdHknO1xuICAgICAgaWYgKGNvbmZpcm0oYEFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgJHtlbnRpdHlOYW1lfT9gKSkge1xuICAgICAgICB0aGlzLm9uRGVsZXRlRW50aXR5Q29uZmlybWVkKGVudGl0eS5faWQgfHwgJycpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBuZ09uSW5pdCgpIHtcbiAgICBjb25zb2xlLmxvZygn8J+UpyBFTlRJVFkgTElTVDogQ29tcG9uZW50IGluaXRpYWxpemluZycpO1xuICAgIHRoaXMudXBkYXRlUGFnaW5hdGlvblN0YXRlKCk7XG5cbiAgICAvLyBTZXQgaW5pdGlhbCBsb2FkaW5nIHN0YXRlIHRvIGZhbHNlIHRvIGFsbG93IGdyaWQgdG8gcmVuZGVyXG4gICAgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7XG5cbiAgICAvLyBMb2FkIGVudGl0aWVzIGZyb20gQVBJXG4gICAgdGhpcy5sb2FkRW50aXRpZXMoKTtcbiAgfVxuXG4gIC8vIEdyaWQgZXZlbnQgaGFuZGxlclxuICBvbkdyaWRFdmVudChldmVudDogR3JpZEV2ZW50PGVudGl0eVJlc3BvbnNlRGF0YT4pIHtcbiAgICBjb25zb2xlLmxvZygn8J+ToSBHUklEIEVWRU5UOiBSZWNlaXZlZCBncmlkIGV2ZW50OicsIGV2ZW50LnR5cGUsIGV2ZW50KTtcblxuICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xuICAgICAgY2FzZSAncm93Q2xpY2snOlxuICAgICAgICB0aGlzLm9uRW50aXR5Um93Q2xpY2soZXZlbnQuZGF0YSBhcyBlbnRpdHlSZXNwb25zZURhdGEpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3JlZnJlc2gnOlxuICAgICAgICB0aGlzLm9uRW50aXR5UmVmcmVzaCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3NlYXJjaCc6XG4gICAgICAgIHRoaXMub25FbnRpdHlTZWFyY2goZXZlbnQuZGF0YSBhcyBzdHJpbmcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3BhZ2VDaGFuZ2UnOlxuICAgICAgICB0aGlzLm9uRW50aXR5UGFnZUNoYW5nZShldmVudC5kYXRhIGFzIG51bWJlcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgY29uc29sZS5sb2coJ1VuaGFuZGxlZCBncmlkIGV2ZW50OicsIGV2ZW50LnR5cGUpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEV2ZW50IGhhbmRsZXJzIGZvciBncmlkIGV2ZW50c1xuICBwcml2YXRlIG9uRW50aXR5Um93Q2xpY2soZW50aXR5OiBlbnRpdHlSZXNwb25zZURhdGEpIHtcbiAgICBjb25zb2xlLmxvZygnRW50aXR5IHJvdyBjbGlja2VkOicsIGVudGl0eSk7XG4gICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWydhZG1pbicsICdlbnRpdHknLCAndmlldycsIGVudGl0eS5faWRdKTtcbiAgfVxuXG4gIHByaXZhdGUgb25FbnRpdHlSZWZyZXNoKCkge1xuICAgIGNvbnNvbGUubG9nKCdSZWZyZXNoaW5nIGVudGl0aWVzLi4uJyk7XG4gICAgdGhpcy5sb2FkRW50aXRpZXModHJ1ZSk7XG4gIH1cblxuICBwcml2YXRlIG9uRW50aXR5U2VhcmNoKHF1ZXJ5OiBzdHJpbmcpIHtcbiAgICBjb25zb2xlLmxvZygnU2VhcmNoIGVudGl0aWVzOicsIHF1ZXJ5KTtcbiAgICB0aGlzLnNlYXJjaFF1ZXJ5LnNldChxdWVyeSk7XG4gICAgLy8gVGhlIGdyaWQgaGFuZGxlcyB0aGUgYWN0dWFsIGZpbHRlcmluZ1xuICB9XG5cbiAgcHJpdmF0ZSBvbkVudGl0eVBhZ2VDaGFuZ2UocGFnZTogbnVtYmVyKSB7XG4gICAgY29uc29sZS5sb2coJ1BhZ2UgY2hhbmdlZCB0bzonLCBwYWdlKTtcbiAgICB0aGlzLmN1cnJlbnRQYWdlLnNldChwYWdlKTtcbiAgICBcbiAgICAvLyBSZWxvYWQgZGF0YSBmb3IgdGhlIG5ldyBwYWdlXG4gICAgdGhpcy5sb2FkRW50aXRpZXMoZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBvbkRlbGV0ZUVudGl0eUNvbmZpcm1lZChlbnRpdHlJZDogc3RyaW5nKSB7XG4gICAgLy8gSW4gYSByZWFsIGFwcCwgeW91J2QgY2FsbCB0aGUgQVBJIHRvIGRlbGV0ZVxuICAgIGNvbnNvbGUubG9nKCdEZWxldGluZyBlbnRpdHk6JywgZW50aXR5SWQpO1xuICAgIC8vIEZvciBub3csIGp1c3QgcmVsb2FkIHRoZSBlbnRpdGllc1xuICAgIHRoaXMubG9hZEVudGl0aWVzKHRydWUpO1xuICB9XG5cbiAgLy8gVXBkYXRlIGdyaWQgZGF0YSBtZXRob2RcbiAgcHJpdmF0ZSB1cGRhdGVHcmlkRGF0YShlbnRpdGllczogZW50aXR5UmVzcG9uc2VEYXRhW10pIHtcbiAgICBjb25zb2xlLmxvZygn8J+TiiBHUklEIFVQREFURTogVXBkYXRpbmcgZ3JpZCB3aXRoJywgZW50aXRpZXMubGVuZ3RoLCAnZW50aXRpZXMnKTtcbiAgICBjb25zb2xlLmxvZygn8J+TiiBHUklEIFVQREFURTogU2FtcGxlIGVudGl0eSBkYXRhOicsIGVudGl0aWVzWzBdIHx8ICdObyBlbnRpdGllcycpO1xuXG4gICAgLy8gU2V0IHRoZSBlbnRpdGllcyBzaWduYWxcbiAgICB0aGlzLmVudGl0aWVzLnNldChlbnRpdGllcyk7XG5cbiAgICAvLyBVcGRhdGUgZ3JpZCBjb25maWd1cmF0aW9uIHdpdGggbmV3IGRhdGEgYW5kIGVuc3VyZSBsb2FkaW5nIGlzIGZhbHNlXG4gICAgdGhpcy5ncmlkQ29uZmlnLnVwZGF0ZShjb25maWcgPT4gKHtcbiAgICAgIC4uLmNvbmZpZyxcbiAgICAgIGRhdGE6IGVudGl0aWVzXG4gICAgfSkpO1xuXG4gICAgLy8gRW5zdXJlIGxvYWRpbmcgc3RhdGVzIGFyZSBjbGVhcmVkXG4gICAgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7XG4gICAgXG4gICAgLy8gQ2xlYXIgcGFnZSBjaGFuZ2UgbG9hZGluZyBzdGF0ZSBpbiB0aGUgZ3JpZCBjb21wb25lbnRcbiAgICBpZiAodGhpcy5ncmlkQ29tcG9uZW50KSB7XG4gICAgICB0aGlzLmdyaWRDb21wb25lbnQuY2xlYXJQYWdlQ2hhbmdlTG9hZGluZygpO1xuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKCfwn5OKIEdSSUQgVVBEQVRFOiBHcmlkIGNvbmZpZyB1cGRhdGVkIHN1Y2Nlc3NmdWxseScpO1xuICAgIGNvbnNvbGUubG9nKCfwn5OKIEdSSUQgVVBEQVRFOiBDdXJyZW50IGdyaWQgZGF0YSBsZW5ndGg6JywgdGhpcy5ncmlkQ29uZmlnKCkuZGF0YS5sZW5ndGgpO1xuICAgIGNvbnNvbGUubG9nKCfwn5OKIEdSSUQgVVBEQVRFOiBMb2FkaW5nIHN0YXRlOicsIHRoaXMubG9hZGluZygpKTtcbiAgICBjb25zb2xlLmxvZygn8J+TiiBHUklEIFVQREFURTogRnVsbCBncmlkIGNvbmZpZyBmb3IgZGVidWdnaW5nOicsIEpTT04uc3RyaW5naWZ5KHRoaXMuZ3JpZENvbmZpZygpLCBudWxsLCAyKSk7XG4gIH1cblxuICBsb2FkRW50aXRpZXMoaXNSZWZyZXNoOiBib29sZWFuID0gZmFsc2UpIHtcbiAgICBpZiAoaXNSZWZyZXNoKSB7XG4gICAgICBjb25zb2xlLmxvZygn8J+UhCBFTlRJVFkgTElTVDogUmVmcmVzaGluZyBlbnRpdGllcycpO1xuICAgICAgLy8gU2V0IHRoZSBncmlkJ3MgcmVmcmVzaCBzdGF0ZSB0byB0cnVlXG4gICAgICBpZiAodGhpcy5ncmlkQ29tcG9uZW50KSB7XG4gICAgICAgIHRoaXMuZ3JpZENvbXBvbmVudC5zZXRSZWZyZXNoaW5nKHRydWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvYWRpbmcuc2V0KHRydWUpO1xuICAgICAgY29uc29sZS5sb2coJ/CflI0gRU5USVRZIExJU1Q6IExvYWRpbmcgZW50aXRpZXMgZnJvbSBBUEknKTtcbiAgICB9XG4gICAgdGhpcy5lcnJvci5zZXQobnVsbCk7XG4gICAgdGhpcy5sb2FkU3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgIHRoaXMuZW50aXR5U2VydmljZS5nZXRBbGxFbnRpdGllcygpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzcG9uc2U6IGVudGl0eUNvbnRyb2xsZXJSZXNwb25zZSkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygn4pyFIEVOVElUWSBMSVNUOiBBUEkgcmVzcG9uc2UgcmVjZWl2ZWQ6JywgcmVzcG9uc2UpO1xuXG4gICAgICAgIC8vIFByb2Nlc3MgdGhlIHJlc3BvbnNlIGRhdGFcbiAgICAgICAgaWYgKHJlc3BvbnNlPy5kYXRhKSB7XG4gICAgICAgICAgLy8gSGFuZGxlIGJvdGggYXJyYXkgYW5kIHNpbmdsZSBvYmplY3QgcmVzcG9uc2VzXG4gICAgICAgICAgY29uc3QgZW50aXRpZXNEYXRhID0gQXJyYXkuaXNBcnJheShyZXNwb25zZS5kYXRhKSA/IHJlc3BvbnNlLmRhdGEgOiBbcmVzcG9uc2UuZGF0YV07XG4gICAgICAgICAgY29uc29sZS5sb2coJ/Cfk4sgRU5USVRZIExJU1Q6IFByb2Nlc3NlZCBlbnRpdGllcyBkYXRhOicsIGVudGl0aWVzRGF0YS5sZW5ndGgsICdlbnRpdGllcycpO1xuXG4gICAgICAgICAgaWYgKGVudGl0aWVzRGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygn8J+TiiBFTlRJVFkgTElTVDogRmlyc3QgZW50aXR5IHNhbXBsZTonLCBlbnRpdGllc0RhdGFbMF0pO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVHcmlkRGF0YShlbnRpdGllc0RhdGEpO1xuICAgICAgICAgICAgdGhpcy50b3RhbEl0ZW1zLnNldChlbnRpdGllc0RhdGEubGVuZ3RoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ/Cfk4ogRU5USVRZIExJU1Q6IE5vIGVudGl0aWVzIHJldHVybmVkLCBzaG93aW5nIHRlc3QgZGF0YScpO1xuICAgICAgICAgICAgdGhpcy5sb2FkVGVzdERhdGEoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCfimqDvuI8gRU5USVRZIExJU1Q6IE5vIGRhdGEgaW4gQVBJIHJlc3BvbnNlLCBsb2FkaW5nIHRlc3QgZGF0YScpO1xuICAgICAgICAgIHRoaXMubG9hZFRlc3REYXRhKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnVwZGF0ZVBhZ2luYXRpb25TdGF0ZSgpO1xuICAgICAgICB0aGlzLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgXG4gICAgICAgIC8vIENsZWFyIHBhZ2UgY2hhbmdlIGxvYWRpbmcgc3RhdGUgaW4gdGhlIGdyaWQgY29tcG9uZW50XG4gICAgICAgIGlmICh0aGlzLmdyaWRDb21wb25lbnQpIHtcbiAgICAgICAgICB0aGlzLmdyaWRDb21wb25lbnQuY2xlYXJQYWdlQ2hhbmdlTG9hZGluZygpO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAvLyBTZXQgdGhlIGdyaWQncyByZWZyZXNoIHN0YXRlIHRvIGZhbHNlIHdoZW4gZG9uZVxuICAgICAgICBpZiAoaXNSZWZyZXNoICYmIHRoaXMuZ3JpZENvbXBvbmVudCkge1xuICAgICAgICAgIHRoaXMuZ3JpZENvbXBvbmVudC5zZXRSZWZyZXNoaW5nKGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ+KdjCBFTlRJVFkgTElTVDogQVBJIGVycm9yOicsIGVycik7XG4gICAgICAgIGNvbnNvbGUubG9nKCfwn6eqIEVOVElUWSBMSVNUOiBBUEkgZmFpbGVkLCBsb2FkaW5nIHRlc3QgZGF0YSBmb3IgZGVtb25zdHJhdGlvbicpO1xuXG4gICAgICAgIC8vIExvYWQgdGVzdCBkYXRhIHdoZW4gQVBJIGZhaWxzXG4gICAgICAgIHRoaXMubG9hZFRlc3REYXRhKCk7XG4gICAgICAgIHRoaXMuZXJyb3Iuc2V0KCdBUEkgdW5hdmFpbGFibGUuIFNob3dpbmcgc2FtcGxlIGRhdGEuJyk7XG5cbiAgICAgICAgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgIFxuICAgICAgICAvLyBDbGVhciBwYWdlIGNoYW5nZSBsb2FkaW5nIHN0YXRlIGluIHRoZSBncmlkIGNvbXBvbmVudFxuICAgICAgICBpZiAodGhpcy5ncmlkQ29tcG9uZW50KSB7XG4gICAgICAgICAgdGhpcy5ncmlkQ29tcG9uZW50LmNsZWFyUGFnZUNoYW5nZUxvYWRpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gU2V0IHRoZSBncmlkJ3MgcmVmcmVzaCBzdGF0ZSB0byBmYWxzZSB3aGVuIGRvbmVcbiAgICAgICAgaWYgKGlzUmVmcmVzaCAmJiB0aGlzLmdyaWRDb21wb25lbnQpIHtcbiAgICAgICAgICB0aGlzLmdyaWRDb21wb25lbnQuc2V0UmVmcmVzaGluZyhmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZFRlc3REYXRhKCkge1xuICAgIGNvbnNvbGUubG9nKCfwn6eqIEVOVElUWSBMSVNUOiBMb2FkaW5nIHRlc3QgZGF0YScpO1xuICAgIGNvbnN0IHRlc3REYXRhOiBlbnRpdHlSZXNwb25zZURhdGFbXSA9IFtcbiAgICAgIHtcbiAgICAgICAgX2lkOiAndGVzdC0xJyxcbiAgICAgICAgc3llbl9uYW1lOiAnVGVzdCBVbml2ZXJzaXR5JyxcbiAgICAgICAgc3llbl9lbnRpdHlfY29kZTogJ1RFU1QwMDEnLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9lbWFpbDogJ3Rlc3RAdW5pdmVyc2l0eS5jb20nLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9jb250YWN0X3BlcnNvbl91c2VyOiAnSm9obiBEb2UnLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9waG9uZTogOTg3NjU0MzIxMCwgIC8vIE5vdyBhIG51bWJlclxuICAgICAgICBzeWVuX2lzYWN0aXZlOiB0cnVlLFxuICAgICAgICBzeWVuX2VudGl0eV90eXBlX2dtc3Q6ICd1bml2ZXJzaXR5JyxcbiAgICAgICAgY2hpbGRyZW46IFtdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBfaWQ6ICd0ZXN0LTInLFxuICAgICAgICBzeWVuX25hbWU6ICdTYW1wbGUgQ29sbGVnZScsXG4gICAgICAgIHN5ZW5fZW50aXR5X2NvZGU6ICdTQU1QMDAyJyxcbiAgICAgICAgc3llbl9jb3Jwb3JhdGVfZW1haWw6ICdpbmZvQHNhbXBsZWNvbGxlZ2UuZWR1JyxcbiAgICAgICAgc3llbl9jb3Jwb3JhdGVfY29udGFjdF9wZXJzb25fdXNlcjogJ0phbmUgU21pdGgnLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9waG9uZTogOTg3NjU0MzIxMSxcbiAgICAgICAgc3llbl9pc2FjdGl2ZTogZmFsc2UsXG4gICAgICAgIHN5ZW5fZW50aXR5X3R5cGVfZ21zdDogJ2NvbGxlZ2UnLFxuICAgICAgICBjaGlsZHJlbjogW11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIF9pZDogJ3Rlc3QtMycsXG4gICAgICAgIHN5ZW5fbmFtZTogJ0dsb2JhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neScsXG4gICAgICAgIHN5ZW5fZW50aXR5X2NvZGU6ICdHSVQwMDMnLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9lbWFpbDogJ2FkbWluQGdpdC5lZHUnLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9jb250YWN0X3BlcnNvbl91c2VyOiAnQm9iIEpvaG5zb24nLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9waG9uZTogOTg3NjU0MzIxMixcbiAgICAgICAgc3llbl9pc2FjdGl2ZTogdHJ1ZSxcbiAgICAgICAgc3llbl9lbnRpdHlfdHlwZV9nbXN0OiAnaW5zdGl0dXRlJyxcbiAgICAgICAgY2hpbGRyZW46IFtdXG4gICAgICB9XG4gICAgXTtcblxuICAgIGNvbnNvbGUubG9nKCfwn6eqIEVOVElUWSBMSVNUOiBUZXN0IGRhdGEgcHJlcGFyZWQ6JywgdGVzdERhdGEpO1xuICAgIHRoaXMudXBkYXRlR3JpZERhdGEodGVzdERhdGEpO1xuICAgIHRoaXMudG90YWxJdGVtcy5zZXQodGVzdERhdGEubGVuZ3RoKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlUGFnaW5hdGlvblN0YXRlKCkge1xuICAgIGNvbnN0IHRvdGFsID0gTWF0aC5jZWlsKHRoaXMudG90YWxJdGVtcygpIC8gdGhpcy5wYWdlU2l6ZSgpKTtcbiAgICB0aGlzLnRvdGFsUGFnZXMuc2V0KHRvdGFsKTtcbiAgICB0aGlzLmhhc05leHRQYWdlLnNldCh0aGlzLmN1cnJlbnRQYWdlKCkgPCB0b3RhbCk7XG4gICAgdGhpcy5oYXNQcmV2aW91c1BhZ2Uuc2V0KHRoaXMuY3VycmVudFBhZ2UoKSA+IDEpO1xuICB9XG5cbiAgb25TZWFyY2goKSB7XG4gICAgdGhpcy5jdXJyZW50UGFnZS5zZXQoMSk7XG4gICAgdGhpcy5sb2FkRW50aXRpZXMoKTtcbiAgfVxuXG4gIG9uRmlsdGVyQ2hhbmdlKCkge1xuICAgIHRoaXMuY3VycmVudFBhZ2Uuc2V0KDEpO1xuICAgIHRoaXMubG9hZEVudGl0aWVzKCk7XG4gIH1cblxuICBvblBhZ2VDaGFuZ2UocGFnZTogbnVtYmVyIHwgc3RyaW5nKSB7XG4gICAgaWYgKHBhcnNlSW50KHBhZ2UgYXMgc3RyaW5nKSA+PSAxICYmIHBhcnNlSW50KHBhZ2UgYXMgc3RyaW5nKSA8PSB0aGlzLnRvdGFsUGFnZXMoKSkge1xuICAgICAgdGhpcy5jdXJyZW50UGFnZS5zZXQocGFyc2VJbnQocGFnZSBhcyBzdHJpbmcpKTtcbiAgICAgIHRoaXMubG9hZEVudGl0aWVzKCk7XG4gICAgfVxuICB9XG5cbiAgb25QYWdlU2l6ZUNoYW5nZSgpIHtcbiAgICB0aGlzLmN1cnJlbnRQYWdlLnNldCgxKTtcbiAgICB0aGlzLmxvYWRFbnRpdGllcygpO1xuICB9XG5cbiAgb25SZWZyZXNoKCkge1xuICAgIHRoaXMubG9hZEVudGl0aWVzKHRydWUpOyAvLyBQYXNzIHRydWUgZm9yIHJlZnJlc2hcbiAgfVxuXG4gIG9uQWRkRW50aXR5KCkge1xuICAgIC8vIE5hdmlnYXRlIHRvIGVudGl0eSBjcmVhdGUgZm9ybVxuICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnL2NvbnRyb2wtcGFuZWwvZW50aXR5LWNyZWF0ZSddKTtcbiAgfVxuXG4gIG9uRWRpdEVudGl0eShlbnRpdHk6IGVudGl0eVJlc3BvbnNlRGF0YSkge1xuICAgIC8vIFRPRE86IEltcGxlbWVudCBlZGl0IGZ1bmN0aW9uYWxpdHkgLSBuYXZpZ2F0ZSB0byBlZGl0IGZvcm0gd2l0aCBlbnRpdHkgSURcbiAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbJy9jb250cm9sLXBhbmVsL2VudGl0eS1jcmVhdGUnXSwge1xuICAgICAgcXVlcnlQYXJhbXM6IHsgaWQ6IGVudGl0eS5faWQsIG1vZGU6ICdlZGl0JyB9XG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coJ0VkaXQgZW50aXR5OicsIGVudGl0eSk7XG4gIH1cblxuICBvblZpZXdFbnRpdHkoZW50aXR5OiBlbnRpdHlSZXNwb25zZURhdGEpIHtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgdmlldyBmdW5jdGlvbmFsaXR5XG4gICAgY29uc29sZS5sb2coJ1ZpZXcgZW50aXR5OicsIGVudGl0eSk7XG4gIH1cblxuICBvbkRlbGV0ZUVudGl0eShlbnRpdHk6IGVudGl0eVJlc3BvbnNlRGF0YSkge1xuICAgIGlmIChjb25maXJtKGBBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIFwiJHtlbnRpdHkuc3llbl9uYW1lfVwiP2ApKSB7XG4gICAgICAvLyBUT0RPOiBJbXBsZW1lbnQgZGVsZXRlIGZ1bmN0aW9uYWxpdHlcbiAgICAgIGNvbnNvbGUubG9nKCdEZWxldGUgZW50aXR5OicsIGVudGl0eSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0U3RhdHVzQ2xhc3MoaXNBY3RpdmU6IGJvb2xlYW4pOiBzdHJpbmcge1xuICAgIHJldHVybiBpc0FjdGl2ZVxuICAgICAgPyAndHctYmctZ3JlZW4tMTAwIHR3LXRleHQtZ3JlZW4tODAwJ1xuICAgICAgOiAndHctYmctcmVkLTEwMCB0dy10ZXh0LXJlZC04MDAnO1xuICB9XG5cbiAgZ2V0U3RhdHVzVGV4dChpc0FjdGl2ZTogYm9vbGVhbik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGlzQWN0aXZlID8gJ0FjdGl2ZScgOiAnSW5hY3RpdmUnO1xuICB9XG5cbiAgZm9ybWF0RGF0ZShkYXRlOiBEYXRlIHwgc3RyaW5nIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcbiAgICBpZiAoIWRhdGUpIHJldHVybiAnTi9BJztcbiAgICByZXR1cm4gbmV3IERhdGUoZGF0ZSkudG9Mb2NhbGVEYXRlU3RyaW5nKCk7XG4gIH1cblxuICAvLyBQYWdpbmF0aW9uIGhlbHBlciBtZXRob2RzXG4gIGdldFBhZ2VOdW1iZXJzKCk6IG51bWJlcltdIHtcbiAgICBjb25zdCB0b3RhbCA9IHRoaXMudG90YWxQYWdlcygpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmN1cnJlbnRQYWdlKCk7XG4gICAgY29uc3QgZGVsdGEgPSAyOyAvLyBOdW1iZXIgb2YgcGFnZXMgdG8gc2hvdyBvbiBlYWNoIHNpZGUgb2YgY3VycmVudCBwYWdlXG5cbiAgICBjb25zdCBwYWdlczogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCBzdGFydCA9IE1hdGgubWF4KDEsIGN1cnJlbnQgLSBkZWx0YSk7XG4gICAgY29uc3QgZW5kID0gTWF0aC5taW4odG90YWwsIGN1cnJlbnQgKyBkZWx0YSk7XG5cbiAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPD0gZW5kOyBpKyspIHtcbiAgICAgIHBhZ2VzLnB1c2goaSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhZ2VzO1xuICB9XG5cbiAgZ2V0SXRlbVJhbmdlVGV4dCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IHN0YXJ0ID0gKHRoaXMuY3VycmVudFBhZ2UoKSAtIDEpICogdGhpcy5wYWdlU2l6ZSgpICsgMTtcbiAgICBjb25zdCBlbmQgPSBNYXRoLm1pbih0aGlzLmN1cnJlbnRQYWdlKCkgKiB0aGlzLnBhZ2VTaXplKCksIHRoaXMudG90YWxJdGVtcygpKTtcbiAgICBjb25zdCB0b3RhbCA9IHRoaXMudG90YWxJdGVtcygpO1xuXG4gICAgcmV0dXJuIGAke3N0YXJ0fS0ke2VuZH0gb2YgJHt0b3RhbH1gO1xuICB9XG5cbiAgdHJhY2tCeUVudGl0eUlkKGluZGV4OiBudW1iZXIsIGVudGl0eTogZW50aXR5UmVzcG9uc2VEYXRhKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZW50aXR5Py5faWQgfHwgJyc7XG4gIH1cblxuICAvLyA9PT09PSBFbmhhbmNlZCBQYWdpbmF0aW9uIE1ldGhvZHMgPT09PT1cblxuICAvKipcbiAgICogR2V0IGVuaGFuY2VkIHBhZ2UgbnVtYmVycyB3aXRoIGVsbGlwc2lzIGZvciBiZXR0ZXIgbmF2aWdhdGlvblxuICAgKi9cbiAgZ2V0RW5oYW5jZWRQYWdlTnVtYmVycygpOiAobnVtYmVyIHwgc3RyaW5nKVtdIHtcbiAgICBjb25zdCB0b3RhbCA9IHRoaXMudG90YWxQYWdlcygpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmN1cnJlbnRQYWdlKCk7XG4gICAgY29uc3QgcGFnZXM6IChudW1iZXIgfCBzdHJpbmcpW10gPSBbXTtcblxuICAgIGlmICh0b3RhbCA8PSA3KSB7XG4gICAgICAvLyBTaG93IGFsbCBwYWdlcyBpZiA3IG9yIGZld2VyXG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8PSB0b3RhbDsgaSsrKSB7XG4gICAgICAgIHBhZ2VzLnB1c2goaSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEFsd2F5cyBzaG93IGZpcnN0IHBhZ2VcbiAgICAgIHBhZ2VzLnB1c2goMSk7XG5cbiAgICAgIGlmIChjdXJyZW50IDw9IDQpIHtcbiAgICAgICAgLy8gQ3VycmVudCBwYWdlIGlzIG5lYXIgdGhlIGJlZ2lubmluZ1xuICAgICAgICBmb3IgKGxldCBpID0gMjsgaSA8PSA1OyBpKyspIHtcbiAgICAgICAgICBwYWdlcy5wdXNoKGkpO1xuICAgICAgICB9XG4gICAgICAgIHBhZ2VzLnB1c2goJy4uLicpO1xuICAgICAgICBwYWdlcy5wdXNoKHRvdGFsKTtcbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudCA+PSB0b3RhbCAtIDMpIHtcbiAgICAgICAgLy8gQ3VycmVudCBwYWdlIGlzIG5lYXIgdGhlIGVuZFxuICAgICAgICBwYWdlcy5wdXNoKCcuLi4nKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRvdGFsIC0gNDsgaSA8PSB0b3RhbDsgaSsrKSB7XG4gICAgICAgICAgcGFnZXMucHVzaChpKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ3VycmVudCBwYWdlIGlzIGluIHRoZSBtaWRkbGVcbiAgICAgICAgcGFnZXMucHVzaCgnLi4uJyk7XG4gICAgICAgIGZvciAobGV0IGkgPSBjdXJyZW50IC0gMTsgaSA8PSBjdXJyZW50ICsgMTsgaSsrKSB7XG4gICAgICAgICAgcGFnZXMucHVzaChpKTtcbiAgICAgICAgfVxuICAgICAgICBwYWdlcy5wdXNoKCcuLi4nKTtcbiAgICAgICAgcGFnZXMucHVzaCh0b3RhbCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhZ2VzO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSBwcm9ncmVzcyBwZXJjZW50YWdlIGJhc2VkIG9uIGN1cnJlbnQgcG9zaXRpb25cbiAgICovXG4gIGdldFByb2dyZXNzUGVyY2VudGFnZSgpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLnRvdGFsUGFnZXMoKSA9PT0gMCkgcmV0dXJuIDA7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoKHRoaXMuY3VycmVudFBhZ2UoKSAvIHRoaXMudG90YWxQYWdlcygpKSAqIDEwMCk7XG4gIH1cblxuICAvKipcbiAgICogSnVtcCB0byBzcGVjaWZpYyBwYWdlIGZ1bmN0aW9uYWxpdHlcbiAgICovXG4gIG9uSnVtcFRvUGFnZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5qdW1wVG9QYWdlID49IDEgJiYgdGhpcy5qdW1wVG9QYWdlIDw9IHRoaXMudG90YWxQYWdlcygpKSB7XG4gICAgICB0aGlzLm9uUGFnZUNoYW5nZSh0aGlzLmp1bXBUb1BhZ2UpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgc2ltdWxhdGVkIGxvYWQgdGltZSBmb3IgcGVyZm9ybWFuY2UgZGlzcGxheVxuICAgKi9cbiAgZ2V0TG9hZFRpbWUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5sb2FkU3RhcnRUaW1lID4gMCA/IERhdGUubm93KCkgLSB0aGlzLmxvYWRTdGFydFRpbWUgOiAwO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0b3RhbCBkYXRhIHNpemUgZm9yIGRpc3BsYXlcbiAgICovXG4gIGdldFRvdGFsRGF0YVNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50b3RhbEl0ZW1zKCk7XG4gIH1cblxuICAvKipcbiAgICogRXhwb3J0IGN1cnJlbnQgcGFnZSBlbnRpdGllc1xuICAgKi9cbiAgb25FeHBvcnRDdXJyZW50UGFnZSgpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50UGFnZUVudGl0aWVzID0gdGhpcy5lbnRpdGllcygpO1xuICAgIGNvbnNvbGUubG9nKCdFeHBvcnRpbmcgY3VycmVudCBwYWdlOicsIGN1cnJlbnRQYWdlRW50aXRpZXMpO1xuICAgIC8vIFRPRE86IEltcGxlbWVudCBhY3R1YWwgZXhwb3J0IGZ1bmN0aW9uYWxpdHlcbiAgICBhbGVydChgRXhwb3J0aW5nICR7Y3VycmVudFBhZ2VFbnRpdGllcy5sZW5ndGh9IGVudGl0aWVzIGZyb20gY3VycmVudCBwYWdlYCk7XG4gIH1cblxuICAvKipcbiAgICogRXhwb3J0IGFsbCBlbnRpdGllc1xuICAgKi9cbiAgb25FeHBvcnRBbGwoKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2coJ0V4cG9ydGluZyBhbGwgZW50aXRpZXMnKTtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgYWN0dWFsIGV4cG9ydCBmdW5jdGlvbmFsaXR5XG4gICAgYWxlcnQoYEV4cG9ydGluZyBhbGwgJHt0aGlzLnRvdGFsSXRlbXMoKX0gZW50aXRpZXNgKTtcbiAgfVxufSAiLCI8IS0tIEVudGl0eSBMaXN0IENvbnRhaW5lciAtLT5cbjxkaXYgY2xhc3M9XCJlbnRpdHktbGlzdC1jb250YWluZXIgdHctYmctd2hpdGUgdHctc2hhZG93LWxnIHR3LXJvdW5kZWQtbGcgdHctb3ZlcmZsb3ctaGlkZGVuXCI+XG4gIFxuICA8IS0tIEhlYWRlciBTZWN0aW9uIHdpdGggRmlsdGVycyAtLT5cbiAgPGRpdiBjbGFzcz1cInR3LXB4LTYgdHctcHktNCB0dy1ib3JkZXItYiB0dy1ib3JkZXItZ3JheS0yMDAgdHctYmctZ3JheS01MFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ0dy1mbGV4IHR3LWZsZXgtY29sIHNtOnR3LWZsZXgtcm93IHR3LWp1c3RpZnktYmV0d2VlbiB0dy1pdGVtcy1zdGFydCBzbTp0dy1pdGVtcy1jZW50ZXIgdHctc3BhY2UteS00IHNtOnR3LXNwYWNlLXktMFwiPlxuICAgICAgXG4gICAgICA8IS0tIFRpdGxlIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInR3LWZsZXggdHctaXRlbXMtY2VudGVyIHR3LXNwYWNlLXgtM1wiPlxuICAgICAgICA8Y2lkZS1lbGUtaWNvbiBjbGFzcz1cInR3LXRleHQtYmx1ZS02MDBcIj5hcGFydG1lbnQ8L2NpZGUtZWxlLWljb24+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGg1IGNsYXNzPVwidHctdGV4dC1tZCB0dy1mb250LXNlbWlib2xkIHR3LXRleHQtZ3JheS05MDBcIj5FbnRpdHkgTWFuYWdlbWVudDwvaDU+XG4gICAgICAgICAgPHAgY2xhc3M9XCJ0dy10ZXh0LXNtIHR3LXRleHQtZ3JheS02MDBcIj5NYW5hZ2UgYW5kIHZpZXcgYWxsIGVudGl0aWVzIGluIHRoZSBzeXN0ZW08L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQWN0aW9ucyAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0dy1mbGV4IHR3LWl0ZW1zLWNlbnRlciB0dy1zcGFjZS14LTNcIj5cbiAgICAgICAgPCEtLSBFbnRpdHkgVHlwZSBGaWx0ZXIgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0dy1mbGV4IHR3LWl0ZW1zLWNlbnRlciB0dy1zcGFjZS14LTJcIj5cbiAgICAgICAgICA8bGFiZWwgZm9yPVwiZW50aXR5VHlwZUZpbHRlclwiIGNsYXNzPVwidHctdGV4dC1zbSB0dy1mb250LW1lZGl1bSB0dy10ZXh0LWdyYXktNzAwXCI+VHlwZTo8L2xhYmVsPlxuICAgICAgICAgIDxjaWRlLWVsZS1zZWxlY3RcbiAgICAgICAgICAgIGlkPVwiZW50aXR5VHlwZUZpbHRlclwiXG4gICAgICAgICAgICBbb3B0aW9uc109XCJlbnRpdHlUeXBlT3B0aW9ucygpXCJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwic2VsZWN0ZWRFbnRpdHlUeXBlVmFsdWVcIlxuICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwibG9hZEVudGl0aWVzKClcIlxuICAgICAgICAgICAgY2xhc3M9XCJ0dy1taW4tdy00MFwiPlxuICAgICAgICAgIDwvY2lkZS1lbGUtc2VsZWN0PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIEFkZCBFbnRpdHkgQnV0dG9uIC0tPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgY2lkZUVsZUJ1dHRvblxuICAgICAgICAgIHZhcmlhbnQ9XCJwcmltYXJ5XCJcbiAgICAgICAgICBzaXplPVwic21cIlxuICAgICAgICAgIChjbGljayk9XCJyb3V0ZXIubmF2aWdhdGUoWydjb250cm9sLXBhbmVsJywgJ2VudGl0eS1jcmVhdGUnXSlcIlxuICAgICAgICAgIGNsYXNzPVwidHctd2hpdGVzcGFjZS1ub3dyYXAgdHctZmxleCB0dy1pdGVtcy1jZW50ZXIgdHctZ2FwLTJcIj5cbiAgICAgICAgICA8Y2lkZS1lbGUtaWNvbiBzaXplPVwieHNcIiBjbGFzcz1cInR3LXctNiB0dy1oLTVcIj5hZGQ8L2NpZGUtZWxlLWljb24+XG4gICAgICAgICAgQWRkIEVudGl0eVxuICAgICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPCEtLSBFcnJvciBNZXNzYWdlIC0tPlxuICAgIEBpZiAoZXJyb3IoKSkge1xuICAgICAgPGRpdiBjbGFzcz1cInR3LW10LTQgdHctcC00IHR3LWJnLXJlZC01MCB0dy1ib3JkZXIgdHctYm9yZGVyLXJlZC0yMDAgdHctcm91bmRlZC1tZFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ0dy1mbGV4XCI+XG4gICAgICAgICAgPGNpZGUtZWxlLWljb24gbmFtZT1cImV4Y2xhbWF0aW9uLXRyaWFuZ2xlXCIgY2xhc3M9XCJ0dy10ZXh0LXJlZC00MDBcIj48L2NpZGUtZWxlLWljb24+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInR3LW1sLTNcIj5cbiAgICAgICAgICAgIDxoMyBjbGFzcz1cInR3LXRleHQtc20gdHctZm9udC1tZWRpdW0gdHctdGV4dC1yZWQtODAwXCI+RXJyb3I8L2gzPlxuICAgICAgICAgICAgPHAgY2xhc3M9XCJ0dy10ZXh0LXNtIHR3LXRleHQtcmVkLTcwMCB0dy1tdC0xXCI+e3sgZXJyb3IoKSB9fTwvcD5cbiAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgPC9kaXY+XG5cbiAgPCEtLSBEYXRhIEdyaWQgQ29tcG9uZW50IC0tPlxuICA8Y2lkZS1lbGUtZGF0YS1ncmlkXG4gICAgW2NvbmZpZ109XCJncmlkQ29uZmlnKClcIlxuICAgIFtjdXN0b21SZW5kZXJlcnNdPVwiY3VzdG9tUmVuZGVyZXJzXCJcbiAgICBbYWN0aW9uSGFuZGxlcnNdPVwiYWN0aW9uSGFuZGxlcnNcIlxuICAgIChncmlkRXZlbnQpPVwib25HcmlkRXZlbnQoJGV2ZW50KVwiPlxuICA8L2NpZGUtZWxlLWRhdGEtZ3JpZD5cblxuPC9kaXY+Il19
|