@igo2/context 1.14.3 → 1.14.4

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.
Files changed (125) hide show
  1. package/esm2020/igo2-context.mjs +4 -4
  2. package/esm2020/lib/context-import-export/context-import-export/context-import-export.component.mjs +228 -228
  3. package/esm2020/lib/context-import-export/context-import-export.module.mjs +84 -84
  4. package/esm2020/lib/context-import-export/index.mjs +2 -2
  5. package/esm2020/lib/context-import-export/shared/context-export.errors.mjs +14 -14
  6. package/esm2020/lib/context-import-export/shared/context-export.interface.mjs +1 -1
  7. package/esm2020/lib/context-import-export/shared/context-export.service.mjs +37 -37
  8. package/esm2020/lib/context-import-export/shared/context-export.utils.mjs +23 -23
  9. package/esm2020/lib/context-import-export/shared/context-import.errors.mjs +32 -32
  10. package/esm2020/lib/context-import-export/shared/context-import.service.mjs +78 -78
  11. package/esm2020/lib/context-import-export/shared/context-import.utils.mjs +157 -157
  12. package/esm2020/lib/context-import-export/shared/index.mjs +7 -7
  13. package/esm2020/lib/context-manager/context-edit/context-edit-binding.directive.mjs +53 -53
  14. package/esm2020/lib/context-manager/context-edit/context-edit.component.mjs +45 -45
  15. package/esm2020/lib/context-manager/context-edit/index.mjs +2 -2
  16. package/esm2020/lib/context-manager/context-form/context-form.component.mjs +146 -146
  17. package/esm2020/lib/context-manager/context-form/index.mjs +1 -1
  18. package/esm2020/lib/context-manager/context-item/context-item.component.mjs +244 -244
  19. package/esm2020/lib/context-manager/context-item/index.mjs +1 -1
  20. package/esm2020/lib/context-manager/context-list/context-list-binding.directive.mjs +259 -259
  21. package/esm2020/lib/context-manager/context-list/context-list.component.mjs +591 -591
  22. package/esm2020/lib/context-manager/context-list/context-list.enum.mjs +6 -6
  23. package/esm2020/lib/context-manager/context-list/index.mjs +2 -2
  24. package/esm2020/lib/context-manager/context-manager.module.mjs +161 -161
  25. package/esm2020/lib/context-manager/context-permissions/context-permissions-binding.directive.mjs +115 -115
  26. package/esm2020/lib/context-manager/context-permissions/context-permissions.component.mjs +305 -305
  27. package/esm2020/lib/context-manager/context-permissions/index.mjs +2 -2
  28. package/esm2020/lib/context-manager/index.mjs +6 -6
  29. package/esm2020/lib/context-manager/shared/context.enum.mjs +12 -12
  30. package/esm2020/lib/context-manager/shared/context.interface.mjs +1 -1
  31. package/esm2020/lib/context-manager/shared/context.service.mjs +628 -628
  32. package/esm2020/lib/context-manager/shared/index.mjs +5 -5
  33. package/esm2020/lib/context-manager/shared/layer-context.directive.mjs +145 -145
  34. package/esm2020/lib/context-manager/shared/map-context.directive.mjs +69 -69
  35. package/esm2020/lib/context-map-button/bookmark-button/bookmark-button.component.mjs +71 -71
  36. package/esm2020/lib/context-map-button/bookmark-button/bookmark-dialog.component.mjs +49 -49
  37. package/esm2020/lib/context-map-button/bookmark-button/index.mjs +2 -2
  38. package/esm2020/lib/context-map-button/context-map-button.module.mjs +95 -95
  39. package/esm2020/lib/context-map-button/index.mjs +3 -3
  40. package/esm2020/lib/context-map-button/poi-button/index.mjs +3 -3
  41. package/esm2020/lib/context-map-button/poi-button/poi-button.component.mjs +170 -170
  42. package/esm2020/lib/context-map-button/poi-button/poi-dialog.component.mjs +49 -49
  43. package/esm2020/lib/context-map-button/poi-button/shared/index.mjs +2 -2
  44. package/esm2020/lib/context-map-button/poi-button/shared/poi.interface.mjs +1 -1
  45. package/esm2020/lib/context-map-button/poi-button/shared/poi.service.mjs +32 -32
  46. package/esm2020/lib/context-map-button/user-button/index.mjs +2 -2
  47. package/esm2020/lib/context-map-button/user-button/user-button.animation.mjs +16 -16
  48. package/esm2020/lib/context-map-button/user-button/user-button.component.mjs +103 -103
  49. package/esm2020/lib/context-map-button/user-button/user-dialog.component.mjs +65 -65
  50. package/esm2020/lib/context.module.mjs +44 -44
  51. package/esm2020/lib/share-map/index.mjs +4 -4
  52. package/esm2020/lib/share-map/share-map/share-map-api.component.mjs +180 -180
  53. package/esm2020/lib/share-map/share-map/share-map-url.component.mjs +242 -242
  54. package/esm2020/lib/share-map/share-map/share-map.component.mjs +56 -56
  55. package/esm2020/lib/share-map/share-map.module.mjs +66 -66
  56. package/esm2020/lib/share-map/shared/index.mjs +1 -1
  57. package/esm2020/lib/share-map/shared/share-map.service.mjs +209 -209
  58. package/esm2020/lib/sidenav/index.mjs +1 -1
  59. package/esm2020/lib/sidenav/sidenav.component.mjs +169 -169
  60. package/esm2020/lib/sidenav/sidenav.module.mjs +60 -60
  61. package/esm2020/public_api.mjs +14 -14
  62. package/fesm2015/igo2-context.mjs +5035 -5035
  63. package/fesm2020/igo2-context.mjs +4684 -4684
  64. package/index.d.ts +5 -5
  65. package/lib/context-import-export/context-import-export/context-import-export.component.d.ts +45 -45
  66. package/lib/context-import-export/context-import-export.module.d.ts +23 -23
  67. package/lib/context-import-export/index.d.ts +2 -2
  68. package/lib/context-import-export/shared/context-export.errors.d.ts +8 -8
  69. package/lib/context-import-export/shared/context-export.interface.d.ts +5 -5
  70. package/lib/context-import-export/shared/context-export.service.d.ts +10 -10
  71. package/lib/context-import-export/shared/context-export.utils.d.ts +4 -4
  72. package/lib/context-import-export/shared/context-import.errors.d.ts +17 -17
  73. package/lib/context-import-export/shared/context-import.service.d.ts +18 -18
  74. package/lib/context-import-export/shared/context-import.utils.d.ts +17 -17
  75. package/lib/context-import-export/shared/index.d.ts +7 -7
  76. package/lib/context-manager/context-edit/context-edit-binding.directive.d.ts +21 -21
  77. package/lib/context-manager/context-edit/context-edit.component.d.ts +14 -14
  78. package/lib/context-manager/context-edit/index.d.ts +2 -2
  79. package/lib/context-manager/context-form/context-form.component.d.ts +31 -31
  80. package/lib/context-manager/context-form/index.d.ts +1 -1
  81. package/lib/context-manager/context-item/context-item.component.d.ts +32 -32
  82. package/lib/context-manager/context-item/index.d.ts +1 -1
  83. package/lib/context-manager/context-list/context-list-binding.directive.d.ts +46 -46
  84. package/lib/context-manager/context-list/context-list.component.d.ts +93 -93
  85. package/lib/context-manager/context-list/context-list.enum.d.ts +5 -5
  86. package/lib/context-manager/context-list/index.d.ts +2 -2
  87. package/lib/context-manager/context-manager.module.d.ts +37 -37
  88. package/lib/context-manager/context-permissions/context-permissions-binding.directive.d.ts +23 -23
  89. package/lib/context-manager/context-permissions/context-permissions.component.d.ts +40 -40
  90. package/lib/context-manager/context-permissions/index.d.ts +2 -2
  91. package/lib/context-manager/index.d.ts +6 -6
  92. package/lib/context-manager/shared/context.enum.d.ts +10 -10
  93. package/lib/context-manager/shared/context.interface.d.ts +75 -75
  94. package/lib/context-manager/shared/context.service.d.ts +75 -75
  95. package/lib/context-manager/shared/index.d.ts +5 -5
  96. package/lib/context-manager/shared/layer-context.directive.d.ts +27 -27
  97. package/lib/context-manager/shared/map-context.directive.d.ts +19 -19
  98. package/lib/context-map-button/bookmark-button/bookmark-button.component.d.ts +21 -21
  99. package/lib/context-map-button/bookmark-button/bookmark-dialog.component.d.ts +9 -9
  100. package/lib/context-map-button/bookmark-button/index.d.ts +2 -2
  101. package/lib/context-map-button/context-map-button.module.d.ts +27 -27
  102. package/lib/context-map-button/index.d.ts +3 -3
  103. package/lib/context-map-button/poi-button/index.d.ts +3 -3
  104. package/lib/context-map-button/poi-button/poi-button.component.d.ts +34 -34
  105. package/lib/context-map-button/poi-button/poi-dialog.component.d.ts +9 -9
  106. package/lib/context-map-button/poi-button/shared/index.d.ts +2 -2
  107. package/lib/context-map-button/poi-button/shared/poi.interface.d.ts +7 -7
  108. package/lib/context-map-button/poi-button/shared/poi.service.d.ts +16 -16
  109. package/lib/context-map-button/user-button/index.d.ts +2 -2
  110. package/lib/context-map-button/user-button/user-button.animation.d.ts +2 -2
  111. package/lib/context-map-button/user-button/user-button.component.d.ts +25 -25
  112. package/lib/context-map-button/user-button/user-dialog.component.d.ts +15 -15
  113. package/lib/context.module.d.ts +16 -16
  114. package/lib/share-map/index.d.ts +4 -4
  115. package/lib/share-map/share-map/share-map-api.component.d.ts +27 -27
  116. package/lib/share-map/share-map/share-map-url.component.d.ts +26 -26
  117. package/lib/share-map/share-map/share-map.component.d.ts +11 -11
  118. package/lib/share-map/share-map.module.d.ts +21 -21
  119. package/lib/share-map/shared/index.d.ts +1 -1
  120. package/lib/share-map/shared/share-map.service.d.ts +17 -17
  121. package/lib/sidenav/index.d.ts +1 -1
  122. package/lib/sidenav/sidenav.component.d.ts +35 -35
  123. package/lib/sidenav/sidenav.module.d.ts +18 -18
  124. package/package.json +6 -6
  125. package/public_api.d.ts +11 -11
@@ -1,629 +1,629 @@
1
- import { Injectable, Optional } from '@angular/core';
2
- import { BehaviorSubject, of, Subject } from 'rxjs';
3
- import { map, tap, catchError, debounceTime, mergeMap, first, skip } from 'rxjs/operators';
4
- import olPoint from 'ol/geom/Point';
5
- import GeoJSON from 'ol/format/GeoJSON';
6
- import Cluster from 'ol/source/Cluster';
7
- import olVectorSource from 'ol/source/Vector';
8
- import { uuid, ObjectUtils } from '@igo2/utils';
9
- import { TypePermission } from './context.enum';
10
- import * as i0 from "@angular/core";
11
- import * as i1 from "@angular/common/http";
12
- import * as i2 from "@igo2/auth";
13
- import * as i3 from "@igo2/core";
14
- import * as i4 from "@igo2/geo";
15
- export class ContextService {
16
- constructor(http, authService, languageService, config, messageService, storageService, exportService, route) {
17
- this.http = http;
18
- this.authService = authService;
19
- this.languageService = languageService;
20
- this.config = config;
21
- this.messageService = messageService;
22
- this.storageService = storageService;
23
- this.exportService = exportService;
24
- this.route = route;
25
- this.context$ = new BehaviorSubject(undefined);
26
- this.contexts$ = new BehaviorSubject({ ours: [] });
27
- this.defaultContextId$ = new BehaviorSubject(undefined);
28
- this.editedContext$ = new BehaviorSubject(undefined);
29
- this.importedContext = [];
30
- this.toolsChanged$ = new Subject();
31
- this.mapViewFromRoute = {};
32
- this.options = Object.assign({
33
- basePath: 'contexts',
34
- contextListFile: '_contexts.json',
35
- defaultContextUri: '_default'
36
- }, this.config.getConfig('context'));
37
- this.baseUrl = this.options.url;
38
- this.readParamsFromRoute();
39
- if (this.authService.hasAuthService) {
40
- this.authService.logged$.subscribe((logged) => {
41
- if (logged) {
42
- this.contexts$.pipe(skip(1), first()).subscribe((c) => {
43
- this.handleContextsChange();
44
- });
45
- this.loadContexts();
46
- }
47
- });
48
- }
49
- else {
50
- this.loadContexts();
51
- this.handleContextsChange(false);
52
- }
53
- }
54
- get defaultContextUri() {
55
- return this.storageService.get('favorite.context.uri') || this._defaultContextUri || this.options.defaultContextUri;
56
- }
57
- set defaultContextUri(uri) {
58
- this._defaultContextUri = uri;
59
- }
60
- get(permissions, hidden) {
61
- let url = this.baseUrl + '/contexts';
62
- if (permissions && this.authService.authenticated) {
63
- url += '?permission=' + permissions.join();
64
- if (hidden) {
65
- url += '&hidden=true';
66
- }
67
- }
68
- return this.http.get(url);
69
- }
70
- getById(id) {
71
- const url = this.baseUrl + '/contexts/' + id;
72
- return this.http.get(url);
73
- }
74
- getDetails(id) {
75
- const url = `${this.baseUrl}/contexts/${id}/details`;
76
- return this.http.get(url).pipe(catchError((res) => {
77
- this.handleError(res, id);
78
- throw res;
79
- }));
80
- }
81
- getDefault() {
82
- if (this.authService.authenticated) {
83
- const url = this.baseUrl + '/contexts/default';
84
- return this.http.get(url).pipe(tap((context) => {
85
- this.defaultContextId$.next(context.id);
86
- }));
87
- }
88
- else {
89
- const uri = this.storageService.get('favorite.context.uri');
90
- this.defaultContextId$.next(uri);
91
- return this.getContextByUri(uri);
92
- }
93
- }
94
- getProfilByUser() {
95
- if (this.baseUrl) {
96
- const url = this.baseUrl + '/profils?';
97
- return this.http.get(url);
98
- }
99
- return of([]);
100
- }
101
- setDefault(id) {
102
- if (this.authService.authenticated) {
103
- const url = this.baseUrl + '/contexts/default';
104
- return this.http.post(url, { defaultContextId: id });
105
- }
106
- else {
107
- this.storageService.set('favorite.context.uri', id);
108
- return of(undefined);
109
- }
110
- }
111
- hideContext(id) {
112
- const url = this.baseUrl + '/contexts/' + id + '/hide';
113
- return this.http.post(url, {});
114
- }
115
- showContext(id) {
116
- const url = this.baseUrl + '/contexts/' + id + '/show';
117
- return this.http.post(url, {});
118
- }
119
- delete(id, imported = false) {
120
- const contexts = { ours: [] };
121
- Object.keys(this.contexts$.value).forEach((key) => (contexts[key] = this.contexts$.value[key].filter((c) => c.id !== id)));
122
- if (imported) {
123
- this.importedContext = this.importedContext.filter((c) => c.id !== id);
124
- return of(this.contexts$.next(contexts));
125
- }
126
- const url = this.baseUrl + '/contexts/' + id;
127
- return this.http.delete(url).pipe(tap((res) => {
128
- this.contexts$.next(contexts);
129
- }));
130
- }
131
- create(context) {
132
- const url = this.baseUrl + '/contexts';
133
- return this.http.post(url, context).pipe(map((contextCreated) => {
134
- if (this.authService.authenticated) {
135
- contextCreated.permission = TypePermission[TypePermission.write];
136
- }
137
- else {
138
- contextCreated.permission = TypePermission[TypePermission.read];
139
- }
140
- this.contexts$.value.ours.unshift(contextCreated);
141
- this.contexts$.next(this.contexts$.value);
142
- return contextCreated;
143
- }));
144
- }
145
- clone(id, properties = {}) {
146
- const url = this.baseUrl + '/contexts/' + id + '/clone';
147
- return this.http.post(url, properties).pipe(map((contextCloned) => {
148
- contextCloned.permission = TypePermission[TypePermission.write];
149
- this.contexts$.value.ours.unshift(contextCloned);
150
- this.contexts$.next(this.contexts$.value);
151
- return contextCloned;
152
- }));
153
- }
154
- update(id, context) {
155
- const url = this.baseUrl + '/contexts/' + id;
156
- return this.http.patch(url, context);
157
- }
158
- // =================================================================
159
- addToolAssociation(contextId, toolId) {
160
- const url = `${this.baseUrl}/contexts/${contextId}/tools`;
161
- const association = {
162
- toolId
163
- };
164
- return this.http.post(url, association);
165
- }
166
- deleteToolAssociation(contextId, toolId) {
167
- const url = `${this.baseUrl}/contexts/${contextId}/tools/${toolId}`;
168
- return this.http.delete(url);
169
- }
170
- getPermissions(id) {
171
- const url = this.baseUrl + '/contexts/' + id + '/permissions';
172
- return this.http.get(url);
173
- }
174
- addPermissionAssociation(contextId, profil, type) {
175
- const url = `${this.baseUrl}/contexts/${contextId}/permissions`;
176
- const association = {
177
- profil,
178
- typePermission: type
179
- };
180
- return this.http.post(url, association).pipe(catchError((res) => {
181
- this.handleError(res, undefined, true);
182
- throw [res]; // TODO Not sure about this.
183
- }));
184
- }
185
- deletePermissionAssociation(contextId, permissionId) {
186
- const url = `${this.baseUrl}/contexts/${contextId}/permissions/${permissionId}`;
187
- return this.http.delete(url);
188
- }
189
- // ======================================================================
190
- getLocalContexts() {
191
- const url = this.getPath(this.options.contextListFile);
192
- return this.http.get(url).pipe(map((res) => {
193
- return { ours: res };
194
- }));
195
- }
196
- getLocalContext(uri) {
197
- const url = this.getPath(`${uri}.json`);
198
- return this.http.get(url).pipe(mergeMap((res) => {
199
- if (!res.base) {
200
- return of(res);
201
- }
202
- const urlBase = this.getPath(`${res.base}.json`);
203
- return this.http.get(urlBase).pipe(map((resBase) => {
204
- const resMerge = res;
205
- resMerge.map = ObjectUtils.mergeDeep(resBase.map, res.map);
206
- resMerge.layers = (resBase.layers || [])
207
- .concat(res.layers || [])
208
- .reverse()
209
- .filter((l, index, self) => !l.id || self.findIndex((l2) => l2.id === l.id) === index)
210
- .reverse();
211
- resMerge.toolbar = res.toolbar || resBase.toolbar;
212
- resMerge.message = res.message || resBase.message;
213
- resMerge.messages = res.messages || resBase.messages;
214
- resMerge.tools = (res.tools || [])
215
- .concat(resBase.tools || [])
216
- .filter((t, index, self) => self.findIndex((t2) => t2.name === t.name) === index);
217
- return resMerge;
218
- }), catchError((err) => {
219
- this.handleError(err, uri);
220
- throw err;
221
- }));
222
- }), catchError((err2) => {
223
- this.handleError(err2, uri);
224
- throw err2;
225
- }));
226
- }
227
- loadContexts(permissions, hidden) {
228
- let request;
229
- if (this.baseUrl) {
230
- request = this.get(permissions, hidden);
231
- }
232
- else {
233
- request = this.getLocalContexts();
234
- }
235
- request.subscribe((contexts) => {
236
- contexts.ours = this.importedContext.concat(contexts.ours);
237
- this.contexts$.next(contexts);
238
- });
239
- }
240
- loadDefaultContext() {
241
- const loadFct = (direct = false) => {
242
- if (!direct && this.baseUrl && this.authService.authenticated) {
243
- this.getDefault().subscribe((_context) => {
244
- this.defaultContextUri = _context.uri;
245
- this.addContextToList(_context);
246
- this.setContext(_context);
247
- }, () => {
248
- this.defaultContextId$.next(undefined);
249
- this.loadContext(this.defaultContextUri);
250
- });
251
- }
252
- else {
253
- this.loadContext(this.defaultContextUri);
254
- }
255
- };
256
- if (this.route && this.route.options.contextKey) {
257
- this.route.queryParams.pipe(debounceTime(100)).subscribe((params) => {
258
- const contextParam = params[this.route.options.contextKey];
259
- let direct = false;
260
- if (contextParam) {
261
- this.defaultContextUri = contextParam;
262
- direct = true;
263
- }
264
- loadFct(direct);
265
- });
266
- }
267
- else {
268
- loadFct();
269
- }
270
- }
271
- loadContext(uri) {
272
- const context = this.context$.value;
273
- if (context && context.uri === uri) {
274
- return;
275
- }
276
- this.getContextByUri(uri)
277
- .pipe(first())
278
- .subscribe((_context) => {
279
- this.addContextToList(_context);
280
- this.setContext(_context);
281
- }, (err) => {
282
- if (uri !== this.options.defaultContextUri) {
283
- this.loadContext(this.options.defaultContextUri);
284
- }
285
- });
286
- }
287
- setContext(context) {
288
- this.handleContextMessage(context);
289
- const currentContext = this.context$.value;
290
- if (currentContext && context && context.id === currentContext.id) {
291
- if (context.map.view.keepCurrentView === undefined) {
292
- context.map.view.keepCurrentView = true;
293
- }
294
- this.context$.next(context);
295
- return;
296
- }
297
- if (!context.map) {
298
- context.map = { view: {} };
299
- }
300
- Object.assign(context.map.view, this.mapViewFromRoute);
301
- this.context$.next(context);
302
- }
303
- loadEditedContext(uri) {
304
- this.getContextByUri(uri).subscribe((_context) => {
305
- this.setEditedContext(_context);
306
- });
307
- }
308
- setEditedContext(context) {
309
- this.editedContext$.next(context);
310
- }
311
- getContextFromMap(igoMap, empty) {
312
- const view = igoMap.ol.getView();
313
- const proj = view.getProjection().getCode();
314
- const center = new olPoint(view.getCenter()).transform(proj, 'EPSG:4326');
315
- const context = {
316
- uri: uuid(),
317
- title: '',
318
- scope: 'private',
319
- map: {
320
- view: {
321
- center: center.getCoordinates(),
322
- zoom: view.getZoom(),
323
- projection: proj,
324
- maxZoomOnExtent: igoMap.viewController.maxZoomOnExtent
325
- }
326
- },
327
- layers: [],
328
- tools: []
329
- };
330
- let layers = [];
331
- if (empty === true) {
332
- layers = igoMap.layers$
333
- .getValue()
334
- .filter((lay) => lay.baseLayer === true ||
335
- lay.options.id === 'searchPointerSummaryId')
336
- .sort((a, b) => a.zIndex - b.zIndex);
337
- }
338
- else {
339
- layers = igoMap.layers$.getValue().filter(lay => !lay.id.includes('WfsWorkspaceTableDest')).sort((a, b) => a.zIndex - b.zIndex);
340
- }
341
- let i = 0;
342
- for (const l of layers) {
343
- const layer = l;
344
- const opts = {
345
- id: layer.options.id ? String(layer.options.id) : undefined,
346
- layerOptions: {
347
- title: layer.options.title,
348
- zIndex: ++i,
349
- visible: layer.visible,
350
- security: layer.security
351
- },
352
- sourceOptions: {
353
- type: layer.dataSource.options.type,
354
- params: layer.dataSource.options.params,
355
- url: layer.dataSource.options.url,
356
- queryable: layer.queryable
357
- }
358
- };
359
- if (opts.sourceOptions.type) {
360
- context.layers.push(opts);
361
- }
362
- }
363
- context.tools = this.tools.map((tool) => {
364
- return { id: String(tool.id), global: tool.global };
365
- });
366
- return context;
367
- }
368
- getContextFromLayers(igoMap, layers, name) {
369
- const currentContext = this.context$.getValue();
370
- const view = igoMap.ol.getView();
371
- const proj = view.getProjection().getCode();
372
- const center = new olPoint(view.getCenter()).transform(proj, 'EPSG:4326');
373
- const context = {
374
- uri: name,
375
- title: name,
376
- map: {
377
- view: {
378
- center: center.getCoordinates(),
379
- zoom: view.getZoom(),
380
- projection: proj
381
- }
382
- },
383
- layers: [],
384
- toolbar: [],
385
- tools: [],
386
- extraFeatures: []
387
- };
388
- const currentLayers = igoMap.layers$.getValue();
389
- context.layers = currentLayers
390
- .filter((l) => l.baseLayer)
391
- .map((l) => {
392
- return {
393
- baseLayer: true,
394
- sourceOptions: l.options.sourceOptions,
395
- title: l.options.title,
396
- visible: l.visible
397
- };
398
- });
399
- layers.forEach((layer) => {
400
- const layerFound = currentContext.layers.find((contextLayer) => {
401
- const source = contextLayer.source;
402
- return source && layer.id === source.id && !contextLayer.baseLayer;
403
- });
404
- if (layerFound) {
405
- let layerStyle = layerFound[`style`];
406
- if (layerFound[`styleByAttribute`]) {
407
- layerStyle = undefined;
408
- }
409
- else if (layerFound[`clusterBaseStyle`]) {
410
- layerStyle = undefined;
411
- delete layerFound.sourceOptions[`source`];
412
- delete layerFound.sourceOptions[`format`];
413
- }
414
- const opts = {
415
- baseLayer: layerFound.baseLayer,
416
- title: layer.options.title,
417
- zIndex: layer.zIndex,
418
- styleByAttribute: layerFound[`styleByAttribute`],
419
- clusterBaseStyle: layerFound[`clusterBaseStyle`],
420
- style: layerStyle,
421
- clusterParam: layerFound[`clusterParam`],
422
- visible: layer.visible,
423
- opacity: layer.opacity,
424
- sourceOptions: layerFound.sourceOptions
425
- };
426
- context.layers.push(opts);
427
- }
428
- else {
429
- if (!(layer.ol.getSource() instanceof olVectorSource)) {
430
- const catalogLayer = layer.options;
431
- catalogLayer.zIndex = layer.zIndex;
432
- delete catalogLayer.source;
433
- context.layers.push(catalogLayer);
434
- }
435
- else {
436
- let features;
437
- const writer = new GeoJSON();
438
- if (layer.ol.getSource() instanceof Cluster) {
439
- const clusterSource = layer.ol.getSource();
440
- let olFeatures = clusterSource.getFeatures();
441
- olFeatures = olFeatures.flatMap((cluster) => cluster.get('features'));
442
- const cleanedOlFeatures = this.exportService.generateFeature(olFeatures, 'GeoJSON', '_featureStore');
443
- features = writer.writeFeatures(cleanedOlFeatures, {
444
- dataProjection: 'EPSG:4326',
445
- featureProjection: 'EPSG:3857'
446
- });
447
- }
448
- else {
449
- const source = layer.ol.getSource();
450
- const olFeatures = source.getFeatures();
451
- const cleanedOlFeatures = this.exportService.generateFeature(olFeatures, 'GeoJSON', '_featureStore');
452
- features = writer.writeFeatures(cleanedOlFeatures, {
453
- dataProjection: 'EPSG:4326',
454
- featureProjection: 'EPSG:3857'
455
- });
456
- }
457
- features = JSON.parse(features);
458
- features.name = layer.options.title;
459
- context.extraFeatures.push(features);
460
- }
461
- }
462
- });
463
- context.toolbar = this.toolbar;
464
- context.tools = this.tools;
465
- return context;
466
- }
467
- setTools(tools) {
468
- this.tools = tools;
469
- }
470
- setToolbar(toolbar) {
471
- this.toolbar = toolbar;
472
- }
473
- handleContextMessage(context) {
474
- if (this.context$.value && context.uri && this.context$.value.uri !== context.uri) {
475
- this.messageService.removeAllAreNotError();
476
- }
477
- context.messages = context.messages ? context.messages : [];
478
- context.messages.push(context.message);
479
- context.messages.map(message => {
480
- if (message) {
481
- this.messageService.message(message);
482
- }
483
- });
484
- }
485
- getContextByUri(uri) {
486
- if (this.baseUrl) {
487
- let contextToLoad;
488
- for (const key of Object.keys(this.contexts$.value)) {
489
- contextToLoad = this.contexts$.value[key].find((c) => {
490
- return c.uri === uri;
491
- });
492
- if (contextToLoad) {
493
- break;
494
- }
495
- }
496
- if (contextToLoad && contextToLoad.imported) {
497
- return of(contextToLoad);
498
- }
499
- // TODO : use always id or uri
500
- const id = contextToLoad ? contextToLoad.id : uri;
501
- return this.getDetails(id);
502
- }
503
- const importedContext = this.contexts$.value.ours.find((currentContext) => {
504
- return currentContext.uri === uri && currentContext.imported === true;
505
- });
506
- if (importedContext) {
507
- return of(importedContext);
508
- }
509
- else {
510
- return this.getLocalContext(uri);
511
- }
512
- }
513
- getContextLayers(igoMap) {
514
- const layers = [];
515
- const mapLayers = igoMap.layers$.getValue();
516
- mapLayers.forEach((layer) => {
517
- if (!layer.baseLayer && layer.options.id !== 'searchPointerSummaryId') {
518
- layers.push(layer);
519
- }
520
- });
521
- return layers;
522
- }
523
- readParamsFromRoute() {
524
- if (!this.route) {
525
- return;
526
- }
527
- this.route.queryParams.subscribe((params) => {
528
- const centerKey = this.route.options.centerKey;
529
- if (centerKey && params[centerKey]) {
530
- const centerParams = params[centerKey];
531
- this.mapViewFromRoute.center = centerParams.split(',').map(Number);
532
- }
533
- const projectionKey = this.route.options.projectionKey;
534
- if (projectionKey && params[projectionKey]) {
535
- const projectionParam = params[projectionKey];
536
- this.mapViewFromRoute.projection = projectionParam;
537
- }
538
- const zoomKey = this.route.options.zoomKey;
539
- if (zoomKey && params[zoomKey]) {
540
- const zoomParam = params[zoomKey];
541
- this.mapViewFromRoute.zoom = Number(zoomParam);
542
- }
543
- });
544
- }
545
- getPath(file) {
546
- const basePath = this.options.basePath.replace(/\/$/, '');
547
- return `${basePath}/${file}`;
548
- }
549
- handleError(error, uri, permissionError) {
550
- const context = this.contexts$.value.ours.find((obj) => obj.uri === uri);
551
- const titleContext = context ? context.title : uri;
552
- error.error.title = this.languageService.translate.instant('igo.context.contextManager.invalid.title');
553
- error.error.message = this.languageService.translate.instant('igo.context.contextManager.invalid.text', { value: titleContext });
554
- error.error.toDisplay = true;
555
- if (permissionError) {
556
- error.error.title = this.languageService.translate.instant('igo.context.contextManager.errors.addPermissionTitle');
557
- error.error.message = this.languageService.translate.instant('igo.context.contextManager.errors.addPermission');
558
- }
559
- this.messageService.error(error.error.message, error.error.title);
560
- }
561
- handleContextsChange(keepCurrentContext = true) {
562
- const context = this.context$.value;
563
- const editedContext = this.editedContext$.value;
564
- if (!context || context.uri === this.options.defaultContextUri) {
565
- keepCurrentContext = false;
566
- }
567
- if (!keepCurrentContext || !this.findContext(context)) {
568
- this.defaultContextUri = undefined;
569
- this.loadDefaultContext();
570
- }
571
- else {
572
- this.getContextByUri(context.uri)
573
- .pipe(first())
574
- .subscribe((newContext) => {
575
- this.toolsChanged$.next(newContext);
576
- });
577
- if (this.baseUrl && this.authService.authenticated) {
578
- this.getDefault().subscribe();
579
- }
580
- }
581
- const editedFound = this.findContext(editedContext);
582
- if (!editedFound || editedFound.permission !== 'write') {
583
- this.setEditedContext(undefined);
584
- }
585
- }
586
- addContextToList(context) {
587
- const contextFound = this.findContext(context);
588
- if (!contextFound) {
589
- const contextSimplifie = {
590
- id: context.id,
591
- uri: context.uri,
592
- title: context.title,
593
- scope: context.scope,
594
- permission: TypePermission[TypePermission.read]
595
- };
596
- if (this.contexts$.value && this.contexts$.value.public) {
597
- this.contexts$.value.public.push(contextSimplifie);
598
- this.contexts$.next(this.contexts$.value);
599
- }
600
- }
601
- }
602
- findContext(context) {
603
- if (!context) {
604
- return false;
605
- }
606
- const contexts = this.contexts$.value;
607
- let found;
608
- for (const key of Object.keys(contexts)) {
609
- const value = contexts[key];
610
- found = value.find((c) => (context.id && c.id === context.id) ||
611
- (context.uri && c.uri === context.uri));
612
- if (found) {
613
- break;
614
- }
615
- }
616
- return found;
617
- }
618
- }
619
- ContextService.ɵfac = function ContextService_Factory(t) { return new (t || ContextService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(i2.AuthService), i0.ɵɵinject(i3.LanguageService), i0.ɵɵinject(i3.ConfigService), i0.ɵɵinject(i3.MessageService), i0.ɵɵinject(i3.StorageService), i0.ɵɵinject(i4.ExportService), i0.ɵɵinject(i3.RouteService, 8)); };
620
- ContextService.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: ContextService, factory: ContextService.ɵfac, providedIn: 'root' });
621
- (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ContextService, [{
622
- type: Injectable,
623
- args: [{
624
- providedIn: 'root'
625
- }]
626
- }], function () { return [{ type: i1.HttpClient }, { type: i2.AuthService }, { type: i3.LanguageService }, { type: i3.ConfigService }, { type: i3.MessageService }, { type: i3.StorageService }, { type: i4.ExportService }, { type: i3.RouteService, decorators: [{
627
- type: Optional
628
- }] }]; }, null); })();
1
+ import { Injectable, Optional } from '@angular/core';
2
+ import { BehaviorSubject, of, Subject } from 'rxjs';
3
+ import { map, tap, catchError, debounceTime, mergeMap, first, skip } from 'rxjs/operators';
4
+ import olPoint from 'ol/geom/Point';
5
+ import GeoJSON from 'ol/format/GeoJSON';
6
+ import Cluster from 'ol/source/Cluster';
7
+ import olVectorSource from 'ol/source/Vector';
8
+ import { uuid, ObjectUtils } from '@igo2/utils';
9
+ import { TypePermission } from './context.enum';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "@angular/common/http";
12
+ import * as i2 from "@igo2/auth";
13
+ import * as i3 from "@igo2/core";
14
+ import * as i4 from "@igo2/geo";
15
+ export class ContextService {
16
+ constructor(http, authService, languageService, config, messageService, storageService, exportService, route) {
17
+ this.http = http;
18
+ this.authService = authService;
19
+ this.languageService = languageService;
20
+ this.config = config;
21
+ this.messageService = messageService;
22
+ this.storageService = storageService;
23
+ this.exportService = exportService;
24
+ this.route = route;
25
+ this.context$ = new BehaviorSubject(undefined);
26
+ this.contexts$ = new BehaviorSubject({ ours: [] });
27
+ this.defaultContextId$ = new BehaviorSubject(undefined);
28
+ this.editedContext$ = new BehaviorSubject(undefined);
29
+ this.importedContext = [];
30
+ this.toolsChanged$ = new Subject();
31
+ this.mapViewFromRoute = {};
32
+ this.options = Object.assign({
33
+ basePath: 'contexts',
34
+ contextListFile: '_contexts.json',
35
+ defaultContextUri: '_default'
36
+ }, this.config.getConfig('context'));
37
+ this.baseUrl = this.options.url;
38
+ this.readParamsFromRoute();
39
+ if (this.authService.hasAuthService) {
40
+ this.authService.logged$.subscribe((logged) => {
41
+ if (logged) {
42
+ this.contexts$.pipe(skip(1), first()).subscribe((c) => {
43
+ this.handleContextsChange();
44
+ });
45
+ this.loadContexts();
46
+ }
47
+ });
48
+ }
49
+ else {
50
+ this.loadContexts();
51
+ this.handleContextsChange(false);
52
+ }
53
+ }
54
+ get defaultContextUri() {
55
+ return this.storageService.get('favorite.context.uri') || this._defaultContextUri || this.options.defaultContextUri;
56
+ }
57
+ set defaultContextUri(uri) {
58
+ this._defaultContextUri = uri;
59
+ }
60
+ get(permissions, hidden) {
61
+ let url = this.baseUrl + '/contexts';
62
+ if (permissions && this.authService.authenticated) {
63
+ url += '?permission=' + permissions.join();
64
+ if (hidden) {
65
+ url += '&hidden=true';
66
+ }
67
+ }
68
+ return this.http.get(url);
69
+ }
70
+ getById(id) {
71
+ const url = this.baseUrl + '/contexts/' + id;
72
+ return this.http.get(url);
73
+ }
74
+ getDetails(id) {
75
+ const url = `${this.baseUrl}/contexts/${id}/details`;
76
+ return this.http.get(url).pipe(catchError((res) => {
77
+ this.handleError(res, id);
78
+ throw res;
79
+ }));
80
+ }
81
+ getDefault() {
82
+ if (this.authService.authenticated) {
83
+ const url = this.baseUrl + '/contexts/default';
84
+ return this.http.get(url).pipe(tap((context) => {
85
+ this.defaultContextId$.next(context.id);
86
+ }));
87
+ }
88
+ else {
89
+ const uri = this.storageService.get('favorite.context.uri');
90
+ this.defaultContextId$.next(uri);
91
+ return this.getContextByUri(uri);
92
+ }
93
+ }
94
+ getProfilByUser() {
95
+ if (this.baseUrl) {
96
+ const url = this.baseUrl + '/profils?';
97
+ return this.http.get(url);
98
+ }
99
+ return of([]);
100
+ }
101
+ setDefault(id) {
102
+ if (this.authService.authenticated) {
103
+ const url = this.baseUrl + '/contexts/default';
104
+ return this.http.post(url, { defaultContextId: id });
105
+ }
106
+ else {
107
+ this.storageService.set('favorite.context.uri', id);
108
+ return of(undefined);
109
+ }
110
+ }
111
+ hideContext(id) {
112
+ const url = this.baseUrl + '/contexts/' + id + '/hide';
113
+ return this.http.post(url, {});
114
+ }
115
+ showContext(id) {
116
+ const url = this.baseUrl + '/contexts/' + id + '/show';
117
+ return this.http.post(url, {});
118
+ }
119
+ delete(id, imported = false) {
120
+ const contexts = { ours: [] };
121
+ Object.keys(this.contexts$.value).forEach((key) => (contexts[key] = this.contexts$.value[key].filter((c) => c.id !== id)));
122
+ if (imported) {
123
+ this.importedContext = this.importedContext.filter((c) => c.id !== id);
124
+ return of(this.contexts$.next(contexts));
125
+ }
126
+ const url = this.baseUrl + '/contexts/' + id;
127
+ return this.http.delete(url).pipe(tap((res) => {
128
+ this.contexts$.next(contexts);
129
+ }));
130
+ }
131
+ create(context) {
132
+ const url = this.baseUrl + '/contexts';
133
+ return this.http.post(url, context).pipe(map((contextCreated) => {
134
+ if (this.authService.authenticated) {
135
+ contextCreated.permission = TypePermission[TypePermission.write];
136
+ }
137
+ else {
138
+ contextCreated.permission = TypePermission[TypePermission.read];
139
+ }
140
+ this.contexts$.value.ours.unshift(contextCreated);
141
+ this.contexts$.next(this.contexts$.value);
142
+ return contextCreated;
143
+ }));
144
+ }
145
+ clone(id, properties = {}) {
146
+ const url = this.baseUrl + '/contexts/' + id + '/clone';
147
+ return this.http.post(url, properties).pipe(map((contextCloned) => {
148
+ contextCloned.permission = TypePermission[TypePermission.write];
149
+ this.contexts$.value.ours.unshift(contextCloned);
150
+ this.contexts$.next(this.contexts$.value);
151
+ return contextCloned;
152
+ }));
153
+ }
154
+ update(id, context) {
155
+ const url = this.baseUrl + '/contexts/' + id;
156
+ return this.http.patch(url, context);
157
+ }
158
+ // =================================================================
159
+ addToolAssociation(contextId, toolId) {
160
+ const url = `${this.baseUrl}/contexts/${contextId}/tools`;
161
+ const association = {
162
+ toolId
163
+ };
164
+ return this.http.post(url, association);
165
+ }
166
+ deleteToolAssociation(contextId, toolId) {
167
+ const url = `${this.baseUrl}/contexts/${contextId}/tools/${toolId}`;
168
+ return this.http.delete(url);
169
+ }
170
+ getPermissions(id) {
171
+ const url = this.baseUrl + '/contexts/' + id + '/permissions';
172
+ return this.http.get(url);
173
+ }
174
+ addPermissionAssociation(contextId, profil, type) {
175
+ const url = `${this.baseUrl}/contexts/${contextId}/permissions`;
176
+ const association = {
177
+ profil,
178
+ typePermission: type
179
+ };
180
+ return this.http.post(url, association).pipe(catchError((res) => {
181
+ this.handleError(res, undefined, true);
182
+ throw [res]; // TODO Not sure about this.
183
+ }));
184
+ }
185
+ deletePermissionAssociation(contextId, permissionId) {
186
+ const url = `${this.baseUrl}/contexts/${contextId}/permissions/${permissionId}`;
187
+ return this.http.delete(url);
188
+ }
189
+ // ======================================================================
190
+ getLocalContexts() {
191
+ const url = this.getPath(this.options.contextListFile);
192
+ return this.http.get(url).pipe(map((res) => {
193
+ return { ours: res };
194
+ }));
195
+ }
196
+ getLocalContext(uri) {
197
+ const url = this.getPath(`${uri}.json`);
198
+ return this.http.get(url).pipe(mergeMap((res) => {
199
+ if (!res.base) {
200
+ return of(res);
201
+ }
202
+ const urlBase = this.getPath(`${res.base}.json`);
203
+ return this.http.get(urlBase).pipe(map((resBase) => {
204
+ const resMerge = res;
205
+ resMerge.map = ObjectUtils.mergeDeep(resBase.map, res.map);
206
+ resMerge.layers = (resBase.layers || [])
207
+ .concat(res.layers || [])
208
+ .reverse()
209
+ .filter((l, index, self) => !l.id || self.findIndex((l2) => l2.id === l.id) === index)
210
+ .reverse();
211
+ resMerge.toolbar = res.toolbar || resBase.toolbar;
212
+ resMerge.message = res.message || resBase.message;
213
+ resMerge.messages = res.messages || resBase.messages;
214
+ resMerge.tools = (res.tools || [])
215
+ .concat(resBase.tools || [])
216
+ .filter((t, index, self) => self.findIndex((t2) => t2.name === t.name) === index);
217
+ return resMerge;
218
+ }), catchError((err) => {
219
+ this.handleError(err, uri);
220
+ throw err;
221
+ }));
222
+ }), catchError((err2) => {
223
+ this.handleError(err2, uri);
224
+ throw err2;
225
+ }));
226
+ }
227
+ loadContexts(permissions, hidden) {
228
+ let request;
229
+ if (this.baseUrl) {
230
+ request = this.get(permissions, hidden);
231
+ }
232
+ else {
233
+ request = this.getLocalContexts();
234
+ }
235
+ request.subscribe((contexts) => {
236
+ contexts.ours = this.importedContext.concat(contexts.ours);
237
+ this.contexts$.next(contexts);
238
+ });
239
+ }
240
+ loadDefaultContext() {
241
+ const loadFct = (direct = false) => {
242
+ if (!direct && this.baseUrl && this.authService.authenticated) {
243
+ this.getDefault().subscribe((_context) => {
244
+ this.defaultContextUri = _context.uri;
245
+ this.addContextToList(_context);
246
+ this.setContext(_context);
247
+ }, () => {
248
+ this.defaultContextId$.next(undefined);
249
+ this.loadContext(this.defaultContextUri);
250
+ });
251
+ }
252
+ else {
253
+ this.loadContext(this.defaultContextUri);
254
+ }
255
+ };
256
+ if (this.route && this.route.options.contextKey) {
257
+ this.route.queryParams.pipe(debounceTime(100)).subscribe((params) => {
258
+ const contextParam = params[this.route.options.contextKey];
259
+ let direct = false;
260
+ if (contextParam) {
261
+ this.defaultContextUri = contextParam;
262
+ direct = true;
263
+ }
264
+ loadFct(direct);
265
+ });
266
+ }
267
+ else {
268
+ loadFct();
269
+ }
270
+ }
271
+ loadContext(uri) {
272
+ const context = this.context$.value;
273
+ if (context && context.uri === uri) {
274
+ return;
275
+ }
276
+ this.getContextByUri(uri)
277
+ .pipe(first())
278
+ .subscribe((_context) => {
279
+ this.addContextToList(_context);
280
+ this.setContext(_context);
281
+ }, (err) => {
282
+ if (uri !== this.options.defaultContextUri) {
283
+ this.loadContext(this.options.defaultContextUri);
284
+ }
285
+ });
286
+ }
287
+ setContext(context) {
288
+ this.handleContextMessage(context);
289
+ const currentContext = this.context$.value;
290
+ if (currentContext && context && context.id === currentContext.id) {
291
+ if (context.map.view.keepCurrentView === undefined) {
292
+ context.map.view.keepCurrentView = true;
293
+ }
294
+ this.context$.next(context);
295
+ return;
296
+ }
297
+ if (!context.map) {
298
+ context.map = { view: {} };
299
+ }
300
+ Object.assign(context.map.view, this.mapViewFromRoute);
301
+ this.context$.next(context);
302
+ }
303
+ loadEditedContext(uri) {
304
+ this.getContextByUri(uri).subscribe((_context) => {
305
+ this.setEditedContext(_context);
306
+ });
307
+ }
308
+ setEditedContext(context) {
309
+ this.editedContext$.next(context);
310
+ }
311
+ getContextFromMap(igoMap, empty) {
312
+ const view = igoMap.ol.getView();
313
+ const proj = view.getProjection().getCode();
314
+ const center = new olPoint(view.getCenter()).transform(proj, 'EPSG:4326');
315
+ const context = {
316
+ uri: uuid(),
317
+ title: '',
318
+ scope: 'private',
319
+ map: {
320
+ view: {
321
+ center: center.getCoordinates(),
322
+ zoom: view.getZoom(),
323
+ projection: proj,
324
+ maxZoomOnExtent: igoMap.viewController.maxZoomOnExtent
325
+ }
326
+ },
327
+ layers: [],
328
+ tools: []
329
+ };
330
+ let layers = [];
331
+ if (empty === true) {
332
+ layers = igoMap.layers$
333
+ .getValue()
334
+ .filter((lay) => lay.baseLayer === true ||
335
+ lay.options.id === 'searchPointerSummaryId')
336
+ .sort((a, b) => a.zIndex - b.zIndex);
337
+ }
338
+ else {
339
+ layers = igoMap.layers$.getValue().filter(lay => !lay.id.includes('WfsWorkspaceTableDest')).sort((a, b) => a.zIndex - b.zIndex);
340
+ }
341
+ let i = 0;
342
+ for (const l of layers) {
343
+ const layer = l;
344
+ const opts = {
345
+ id: layer.options.id ? String(layer.options.id) : undefined,
346
+ layerOptions: {
347
+ title: layer.options.title,
348
+ zIndex: ++i,
349
+ visible: layer.visible,
350
+ security: layer.security
351
+ },
352
+ sourceOptions: {
353
+ type: layer.dataSource.options.type,
354
+ params: layer.dataSource.options.params,
355
+ url: layer.dataSource.options.url,
356
+ queryable: layer.queryable
357
+ }
358
+ };
359
+ if (opts.sourceOptions.type) {
360
+ context.layers.push(opts);
361
+ }
362
+ }
363
+ context.tools = this.tools.map((tool) => {
364
+ return { id: String(tool.id), global: tool.global };
365
+ });
366
+ return context;
367
+ }
368
+ getContextFromLayers(igoMap, layers, name) {
369
+ const currentContext = this.context$.getValue();
370
+ const view = igoMap.ol.getView();
371
+ const proj = view.getProjection().getCode();
372
+ const center = new olPoint(view.getCenter()).transform(proj, 'EPSG:4326');
373
+ const context = {
374
+ uri: name,
375
+ title: name,
376
+ map: {
377
+ view: {
378
+ center: center.getCoordinates(),
379
+ zoom: view.getZoom(),
380
+ projection: proj
381
+ }
382
+ },
383
+ layers: [],
384
+ toolbar: [],
385
+ tools: [],
386
+ extraFeatures: []
387
+ };
388
+ const currentLayers = igoMap.layers$.getValue();
389
+ context.layers = currentLayers
390
+ .filter((l) => l.baseLayer)
391
+ .map((l) => {
392
+ return {
393
+ baseLayer: true,
394
+ sourceOptions: l.options.sourceOptions,
395
+ title: l.options.title,
396
+ visible: l.visible
397
+ };
398
+ });
399
+ layers.forEach((layer) => {
400
+ const layerFound = currentContext.layers.find((contextLayer) => {
401
+ const source = contextLayer.source;
402
+ return source && layer.id === source.id && !contextLayer.baseLayer;
403
+ });
404
+ if (layerFound) {
405
+ let layerStyle = layerFound[`style`];
406
+ if (layerFound[`styleByAttribute`]) {
407
+ layerStyle = undefined;
408
+ }
409
+ else if (layerFound[`clusterBaseStyle`]) {
410
+ layerStyle = undefined;
411
+ delete layerFound.sourceOptions[`source`];
412
+ delete layerFound.sourceOptions[`format`];
413
+ }
414
+ const opts = {
415
+ baseLayer: layerFound.baseLayer,
416
+ title: layer.options.title,
417
+ zIndex: layer.zIndex,
418
+ styleByAttribute: layerFound[`styleByAttribute`],
419
+ clusterBaseStyle: layerFound[`clusterBaseStyle`],
420
+ style: layerStyle,
421
+ clusterParam: layerFound[`clusterParam`],
422
+ visible: layer.visible,
423
+ opacity: layer.opacity,
424
+ sourceOptions: layerFound.sourceOptions
425
+ };
426
+ context.layers.push(opts);
427
+ }
428
+ else {
429
+ if (!(layer.ol.getSource() instanceof olVectorSource)) {
430
+ const catalogLayer = layer.options;
431
+ catalogLayer.zIndex = layer.zIndex;
432
+ delete catalogLayer.source;
433
+ context.layers.push(catalogLayer);
434
+ }
435
+ else {
436
+ let features;
437
+ const writer = new GeoJSON();
438
+ if (layer.ol.getSource() instanceof Cluster) {
439
+ const clusterSource = layer.ol.getSource();
440
+ let olFeatures = clusterSource.getFeatures();
441
+ olFeatures = olFeatures.flatMap((cluster) => cluster.get('features'));
442
+ const cleanedOlFeatures = this.exportService.generateFeature(olFeatures, 'GeoJSON', '_featureStore');
443
+ features = writer.writeFeatures(cleanedOlFeatures, {
444
+ dataProjection: 'EPSG:4326',
445
+ featureProjection: 'EPSG:3857'
446
+ });
447
+ }
448
+ else {
449
+ const source = layer.ol.getSource();
450
+ const olFeatures = source.getFeatures();
451
+ const cleanedOlFeatures = this.exportService.generateFeature(olFeatures, 'GeoJSON', '_featureStore');
452
+ features = writer.writeFeatures(cleanedOlFeatures, {
453
+ dataProjection: 'EPSG:4326',
454
+ featureProjection: 'EPSG:3857'
455
+ });
456
+ }
457
+ features = JSON.parse(features);
458
+ features.name = layer.options.title;
459
+ context.extraFeatures.push(features);
460
+ }
461
+ }
462
+ });
463
+ context.toolbar = this.toolbar;
464
+ context.tools = this.tools;
465
+ return context;
466
+ }
467
+ setTools(tools) {
468
+ this.tools = tools;
469
+ }
470
+ setToolbar(toolbar) {
471
+ this.toolbar = toolbar;
472
+ }
473
+ handleContextMessage(context) {
474
+ if (this.context$.value && context.uri && this.context$.value.uri !== context.uri) {
475
+ this.messageService.removeAllAreNotError();
476
+ }
477
+ context.messages = context.messages ? context.messages : [];
478
+ context.messages.push(context.message);
479
+ context.messages.map(message => {
480
+ if (message) {
481
+ this.messageService.message(message);
482
+ }
483
+ });
484
+ }
485
+ getContextByUri(uri) {
486
+ if (this.baseUrl) {
487
+ let contextToLoad;
488
+ for (const key of Object.keys(this.contexts$.value)) {
489
+ contextToLoad = this.contexts$.value[key].find((c) => {
490
+ return c.uri === uri;
491
+ });
492
+ if (contextToLoad) {
493
+ break;
494
+ }
495
+ }
496
+ if (contextToLoad && contextToLoad.imported) {
497
+ return of(contextToLoad);
498
+ }
499
+ // TODO : use always id or uri
500
+ const id = contextToLoad ? contextToLoad.id : uri;
501
+ return this.getDetails(id);
502
+ }
503
+ const importedContext = this.contexts$.value.ours.find((currentContext) => {
504
+ return currentContext.uri === uri && currentContext.imported === true;
505
+ });
506
+ if (importedContext) {
507
+ return of(importedContext);
508
+ }
509
+ else {
510
+ return this.getLocalContext(uri);
511
+ }
512
+ }
513
+ getContextLayers(igoMap) {
514
+ const layers = [];
515
+ const mapLayers = igoMap.layers$.getValue();
516
+ mapLayers.forEach((layer) => {
517
+ if (!layer.baseLayer && layer.options.id !== 'searchPointerSummaryId') {
518
+ layers.push(layer);
519
+ }
520
+ });
521
+ return layers;
522
+ }
523
+ readParamsFromRoute() {
524
+ if (!this.route) {
525
+ return;
526
+ }
527
+ this.route.queryParams.subscribe((params) => {
528
+ const centerKey = this.route.options.centerKey;
529
+ if (centerKey && params[centerKey]) {
530
+ const centerParams = params[centerKey];
531
+ this.mapViewFromRoute.center = centerParams.split(',').map(Number);
532
+ }
533
+ const projectionKey = this.route.options.projectionKey;
534
+ if (projectionKey && params[projectionKey]) {
535
+ const projectionParam = params[projectionKey];
536
+ this.mapViewFromRoute.projection = projectionParam;
537
+ }
538
+ const zoomKey = this.route.options.zoomKey;
539
+ if (zoomKey && params[zoomKey]) {
540
+ const zoomParam = params[zoomKey];
541
+ this.mapViewFromRoute.zoom = Number(zoomParam);
542
+ }
543
+ });
544
+ }
545
+ getPath(file) {
546
+ const basePath = this.options.basePath.replace(/\/$/, '');
547
+ return `${basePath}/${file}`;
548
+ }
549
+ handleError(error, uri, permissionError) {
550
+ const context = this.contexts$.value.ours.find((obj) => obj.uri === uri);
551
+ const titleContext = context ? context.title : uri;
552
+ error.error.title = this.languageService.translate.instant('igo.context.contextManager.invalid.title');
553
+ error.error.message = this.languageService.translate.instant('igo.context.contextManager.invalid.text', { value: titleContext });
554
+ error.error.toDisplay = true;
555
+ if (permissionError) {
556
+ error.error.title = this.languageService.translate.instant('igo.context.contextManager.errors.addPermissionTitle');
557
+ error.error.message = this.languageService.translate.instant('igo.context.contextManager.errors.addPermission');
558
+ }
559
+ this.messageService.error(error.error.message, error.error.title);
560
+ }
561
+ handleContextsChange(keepCurrentContext = true) {
562
+ const context = this.context$.value;
563
+ const editedContext = this.editedContext$.value;
564
+ if (!context || context.uri === this.options.defaultContextUri) {
565
+ keepCurrentContext = false;
566
+ }
567
+ if (!keepCurrentContext || !this.findContext(context)) {
568
+ this.defaultContextUri = undefined;
569
+ this.loadDefaultContext();
570
+ }
571
+ else {
572
+ this.getContextByUri(context.uri)
573
+ .pipe(first())
574
+ .subscribe((newContext) => {
575
+ this.toolsChanged$.next(newContext);
576
+ });
577
+ if (this.baseUrl && this.authService.authenticated) {
578
+ this.getDefault().subscribe();
579
+ }
580
+ }
581
+ const editedFound = this.findContext(editedContext);
582
+ if (!editedFound || editedFound.permission !== 'write') {
583
+ this.setEditedContext(undefined);
584
+ }
585
+ }
586
+ addContextToList(context) {
587
+ const contextFound = this.findContext(context);
588
+ if (!contextFound) {
589
+ const contextSimplifie = {
590
+ id: context.id,
591
+ uri: context.uri,
592
+ title: context.title,
593
+ scope: context.scope,
594
+ permission: TypePermission[TypePermission.read]
595
+ };
596
+ if (this.contexts$.value && this.contexts$.value.public) {
597
+ this.contexts$.value.public.push(contextSimplifie);
598
+ this.contexts$.next(this.contexts$.value);
599
+ }
600
+ }
601
+ }
602
+ findContext(context) {
603
+ if (!context) {
604
+ return false;
605
+ }
606
+ const contexts = this.contexts$.value;
607
+ let found;
608
+ for (const key of Object.keys(contexts)) {
609
+ const value = contexts[key];
610
+ found = value.find((c) => (context.id && c.id === context.id) ||
611
+ (context.uri && c.uri === context.uri));
612
+ if (found) {
613
+ break;
614
+ }
615
+ }
616
+ return found;
617
+ }
618
+ }
619
+ ContextService.ɵfac = function ContextService_Factory(t) { return new (t || ContextService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(i2.AuthService), i0.ɵɵinject(i3.LanguageService), i0.ɵɵinject(i3.ConfigService), i0.ɵɵinject(i3.MessageService), i0.ɵɵinject(i3.StorageService), i0.ɵɵinject(i4.ExportService), i0.ɵɵinject(i3.RouteService, 8)); };
620
+ ContextService.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: ContextService, factory: ContextService.ɵfac, providedIn: 'root' });
621
+ (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ContextService, [{
622
+ type: Injectable,
623
+ args: [{
624
+ providedIn: 'root'
625
+ }]
626
+ }], function () { return [{ type: i1.HttpClient }, { type: i2.AuthService }, { type: i3.LanguageService }, { type: i3.ConfigService }, { type: i3.MessageService }, { type: i3.StorageService }, { type: i4.ExportService }, { type: i3.RouteService, decorators: [{
627
+ type: Optional
628
+ }] }]; }, null); })();
629
629
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29udGV4dC9zcmMvbGliL2NvbnRleHQtbWFuYWdlci9zaGFyZWQvY29udGV4dC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3JELE9BQU8sRUFBRSxlQUFlLEVBQWMsRUFBRSxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNoRSxPQUFPLEVBQ0wsR0FBRyxFQUNILEdBQUcsRUFDSCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFFBQVEsRUFDUixLQUFLLEVBQ0wsSUFBSSxFQUNMLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3BDLE9BQU8sT0FBTyxNQUFNLG1CQUFtQixDQUFDO0FBQ3hDLE9BQU8sT0FBTyxNQUFNLG1CQUFtQixDQUFDO0FBQ3hDLE9BQU8sY0FBYyxNQUFNLGtCQUFrQixDQUFDO0FBRzlDLE9BQU8sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBY2hELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7O0FBY2hELE1BQU0sT0FBTyxjQUFjO0lBd0J6QixZQUNVLElBQWdCLEVBQ2hCLFdBQXdCLEVBQ3hCLGVBQWdDLEVBQ2hDLE1BQXFCLEVBQ3JCLGNBQThCLEVBQzlCLGNBQThCLEVBQzlCLGFBQTRCLEVBQ2hCLEtBQW1CO1FBUC9CLFNBQUksR0FBSixJQUFJLENBQVk7UUFDaEIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLFdBQU0sR0FBTixNQUFNLENBQWU7UUFDckIsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLG1CQUFjLEdBQWQsY0FB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QUFLLENBQUM7SUFDZixDQUFDOzs0RUE1dkJVLGNBQWM7b0VBQWQsY0FBYyxXQUFkLGNBQWMsbUJBRmIsTUFBTTt1RkFFUCxjQUFjO2NBSDFCLFVBQVU7ZUFBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQjs7c0JBaUNJLFFBQVEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSHR0cENsaWVudCwgSHR0cEVycm9yUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5cbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgb2YsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIG1hcCxcbiAgdGFwLFxuICBjYXRjaEVycm9yLFxuICBkZWJvdW5jZVRpbWUsXG4gIG1lcmdlTWFwLFxuICBmaXJzdCxcbiAgc2tpcFxufSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCBvbFBvaW50IGZyb20gJ29sL2dlb20vUG9pbnQnO1xuaW1wb3J0IEdlb0pTT04gZnJvbSAnb2wvZm9ybWF0L0dlb0pTT04nO1xuaW1wb3J0IENsdXN0ZXIgZnJvbSAnb2wvc291cmNlL0NsdXN0ZXInO1xuaW1wb3J0IG9sVmVjdG9yU291cmNlIGZyb20gJ29sL3NvdXJjZS9WZWN0b3InO1xuXG5pbXBvcnQgeyBUb29sIH0gZnJvbSAnQGlnbzIvY29tbW9uJztcbmltcG9ydCB7IHV1aWQsIE9iamVjdFV0aWxzIH0gZnJvbSAnQGlnbzIvdXRpbHMnO1xuaW1wb3J0IHtcbiAgQ29uZmlnU2VydmljZSxcbiAgUm91dGVTZXJ2aWNlLFxuICBNZXNzYWdlLFxuICBNZXNzYWdlU2VydmljZSxcbiAgTGFuZ3VhZ2VTZXJ2aWNlLFxuICBTdG9yYWdlU2VydmljZVxufSBmcm9tICdAaWdvMi9jb3JlJztcblxuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICdAaWdvMi9hdXRoJztcbmltcG9ydCB0eXBlIHsgSWdvTWFwLCBMYXllciwgTGF5ZXJPcHRpb25zIH0gZnJvbSAnQGlnbzIvZ2VvJztcbmltcG9ydCB7IEV4cG9ydFNlcnZpY2UgfSBmcm9tICdAaWdvMi9nZW8nO1xuXG5pbXBvcnQgeyBUeXBlUGVybWlzc2lvbiB9IGZyb20gJy4vY29udGV4dC5lbnVtJztcbmltcG9ydCB7XG4gIENvbnRleHRzTGlzdCxcbiAgQ29udGV4dFNlcnZpY2VPcHRpb25zLFxuICBDb250ZXh0LFxuICBEZXRhaWxlZENvbnRleHQsXG4gIENvbnRleHRNYXBWaWV3LFxuICBDb250ZXh0UGVybWlzc2lvbixcbiAgQ29udGV4dFByb2ZpbHNcbn0gZnJvbSAnLi9jb250ZXh0LmludGVyZmFjZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIENvbnRleHRTZXJ2aWNlIHtcbiAgcHVibGljIGNvbnRleHQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxEZXRhaWxlZENvbnRleHQ+KHVuZGVmaW5lZCk7XG4gIHB1YmxpYyBjb250ZXh0cyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PENvbnRleHRzTGlzdD4oeyBvdXJzOiBbXSB9KTtcbiAgcHVibGljIGRlZmF1bHRDb250ZXh0SWQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KHVuZGVmaW5lZCk7XG4gIHB1YmxpYyBlZGl0ZWRDb250ZXh0JCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RGV0YWlsZWRDb250ZXh0Pih1bmRlZmluZWQpO1xuICBwdWJsaWMgaW1wb3J0ZWRDb250ZXh0OiBBcnJheTxEZXRhaWxlZENvbnRleHQ+ID0gW107XG4gIHB1YmxpYyB0b29sc0NoYW5nZWQkID0gbmV3IFN1YmplY3Q8RGV0YWlsZWRDb250ZXh0PigpO1xuICBwcml2YXRlIG1hcFZpZXdGcm9tUm91dGU6IENvbnRleHRNYXBWaWV3ID0ge307XG4gIHByaXZhdGUgb3B0aW9uczogQ29udGV4dFNlcnZpY2VPcHRpb25zO1xuICBwcml2YXRlIGJhc2VVcmw6IHN0cmluZztcblxuICAvLyBVbnRpbCB0aGUgQ29udGV4dFNlcnZpY2UgaXMgY29tcGxldGVseSByZWZhY3RvcmVkLCB0aGlzIGlzIG5lZWRlZFxuICAvLyB0byB0cmFjayB0aGUgY3VycmVudCB0b29sc1xuICBwcml2YXRlIHRvb2xzOiBUb29sW107XG4gIHByaXZhdGUgdG9vbGJhcjogc3RyaW5nW107XG5cbiAgZ2V0IGRlZmF1bHRDb250ZXh0VXJpKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc3RvcmFnZVNlcnZpY2UuZ2V0KCdmYXZvcml0ZS5jb250ZXh0LnVyaScpIGFzIHN0cmluZyB8fCB0aGlzLl9kZWZhdWx0Q29udGV4dFVyaSB8fCB0aGlzLm9wdGlvbnMuZGVmYXVsdENvbnRleHRVcmk7XG4gIH1cbiAgc2V0IGRlZmF1bHRDb250ZXh0VXJpKHVyaTogc3RyaW5nKSB7XG4gICAgdGhpcy5fZGVmYXVsdENvbnRleHRVcmkgPSB1cmk7XG4gIH1cbiAgcHJpdmF0ZSBfZGVmYXVsdENvbnRleHRVcmk6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsXG4gICAgcHJpdmF0ZSBhdXRoU2VydmljZTogQXV0aFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBsYW5ndWFnZVNlcnZpY2U6IExhbmd1YWdlU2VydmljZSxcbiAgICBwcml2YXRlIGNvbmZpZzogQ29uZmlnU2VydmljZSxcbiAgICBwcml2YXRlIG1lc3NhZ2VTZXJ2aWNlOiBNZXNzYWdlU2VydmljZSxcbiAgICBwcml2YXRlIHN0b3JhZ2VTZXJ2aWNlOiBTdG9yYWdlU2VydmljZSxcbiAgICBwcml2YXRlIGV4cG9ydFNlcnZpY2U6IEV4cG9ydFNlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSByb3V0ZTogUm91dGVTZXJ2aWNlXG4gICkge1xuICAgIHRoaXMub3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oXG4gICAgICB7XG4gICAgICAgIGJhc2VQYXRoOiAnY29udGV4dHMnLFxuICAgICAgICBjb250ZXh0TGlzdEZpbGU6ICdfY29udGV4dHMuanNvbicsXG4gICAgICAgIGRlZmF1bHRDb250ZXh0VXJpOiAnX2RlZmF1bHQnXG4gICAgICB9LFxuICAgICAgdGhpcy5jb25maWcuZ2V0Q29uZmlnKCdjb250ZXh0JylcbiAgICApO1xuXG4gICAgdGhpcy5iYXNlVXJsID0gdGhpcy5vcHRpb25zLnVybDtcblxuICAgIHRoaXMucmVhZFBhcmFtc0Zyb21Sb3V0ZSgpO1xuXG4gICAgaWYgKHRoaXMuYXV0aFNlcnZpY2UuaGFzQXV0aFNlcnZpY2UpIHtcbiAgICAgIHRoaXMuYXV0aFNlcnZpY2UubG9nZ2VkJC5zdWJzY3JpYmUoKGxvZ2dlZCkgPT4ge1xuICAgICAgICBpZiAobG9nZ2VkKSB7XG4gICAgICAgICAgdGhpcy5jb250ZXh0cyQucGlwZShza2lwKDEpLCBmaXJzdCgpKS5zdWJzY3JpYmUoKGMpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlQ29udGV4dHNDaGFuZ2UoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLmxvYWRDb250ZXh0cygpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2FkQ29udGV4dHMoKTtcbiAgICAgIHRoaXMuaGFuZGxlQ29udGV4dHNDaGFuZ2UoZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIGdldChwZXJtaXNzaW9ucz86IHN0cmluZ1tdLCBoaWRkZW4/OiBib29sZWFuKTogT2JzZXJ2YWJsZTxDb250ZXh0c0xpc3Q+IHtcbiAgICBsZXQgdXJsID0gdGhpcy5iYXNlVXJsICsgJy9jb250ZXh0cyc7XG4gICAgaWYgKHBlcm1pc3Npb25zICYmIHRoaXMuYXV0aFNlcnZpY2UuYXV0aGVudGljYXRlZCkge1xuICAgICAgdXJsICs9ICc/cGVybWlzc2lvbj0nICsgcGVybWlzc2lvbnMuam9pbigpO1xuICAgICAgaWYgKGhpZGRlbikge1xuICAgICAgICB1cmwgKz0gJyZoaWRkZW49dHJ1ZSc7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PENvbnRleHRzTGlzdD4odXJsKTtcbiAgfVxuXG4gIGdldEJ5SWQoaWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Q29udGV4dD4ge1xuICAgIGNvbnN0IHVybCA9IHRoaXMuYmFzZVVybCArICcvY29udGV4dHMvJyArIGlkO1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PENvbnRleHQ+KHVybCk7XG4gIH1cblxuICBnZXREZXRhaWxzKGlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPERldGFpbGVkQ29udGV4dD4ge1xuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuYmFzZVVybH0vY29udGV4dHMvJHtpZH0vZGV0YWlsc2A7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8RGV0YWlsZWRDb250ZXh0Pih1cmwpLnBpcGUoXG4gICAgICBjYXRjaEVycm9yKChyZXMpID0+IHtcbiAgICAgICAgdGhpcy5oYW5kbGVFcnJvcihyZXMsIGlkKTtcbiAgICAgICAgdGhyb3cgcmVzO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgZ2V0RGVmYXVsdCgpOiBPYnNlcnZhYmxlPERldGFpbGVkQ29udGV4dD4ge1xuICAgIGlmICh0aGlzLmF1dGhTZXJ2aWNlLmF1dGhlbnRpY2F0ZWQpIHtcbiAgICAgIGNvbnN0IHVybCA9IHRoaXMuYmFzZVVybCArICcvY29udGV4dHMvZGVmYXVsdCc7XG4gICAgICByZXR1cm4gdGhpcy5odHRwLmdldDxEZXRhaWxlZENvbnRleHQ+KHVybCkucGlwZShcbiAgICAgICAgdGFwKChjb250ZXh0KSA9PiB7XG4gICAgICAgICAgdGhpcy5kZWZhdWx0Q29udGV4dElkJC5uZXh0KGNvbnRleHQuaWQpO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdXJpID0gdGhpcy5zdG9yYWdlU2VydmljZS5nZXQoJ2Zhdm9yaXRlLmNvbnRleHQudXJpJykgYXMgc3RyaW5nO1xuICAgICAgdGhpcy5kZWZhdWx0Q29udGV4dElkJC5uZXh0KHVyaSk7XG4gICAgICByZXR1cm4gdGhpcy5nZXRDb250ZXh0QnlVcmkodXJpKTtcbiAgICB9XG5cbiAgfVxuXG4gIGdldFByb2ZpbEJ5VXNlcigpOiBPYnNlcnZhYmxlPENvbnRleHRQcm9maWxzW10+IHtcbiAgICBpZiAodGhpcy5iYXNlVXJsKSB7XG4gICAgICBjb25zdCB1cmwgPSB0aGlzLmJhc2VVcmwgKyAnL3Byb2ZpbHM/JztcbiAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PENvbnRleHRQcm9maWxzW10+KHVybCk7XG4gICAgfVxuICAgIHJldHVybiBvZihbXSk7XG4gIH1cblxuICBzZXREZWZhdWx0KGlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIGlmICh0aGlzLmF1dGhTZXJ2aWNlLmF1dGhlbnRpY2F0ZWQpIHtcbiAgICAgIGNvbnN0IHVybCA9IHRoaXMuYmFzZVVybCArICcvY29udGV4dHMvZGVmYXVsdCc7XG4gICAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QodXJsLCB7IGRlZmF1bHRDb250ZXh0SWQ6IGlkIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0b3JhZ2VTZXJ2aWNlLnNldCgnZmF2b3JpdGUuY29udGV4dC51cmknLCBpZCk7XG4gICAgICByZXR1cm4gb2YodW5kZWZpbmVkKTtcbiAgICB9XG4gIH1cblxuICBoaWRlQ29udGV4dChpZDogc3RyaW5nKSB7XG4gICAgY29uc3QgdXJsID0gdGhpcy5iYXNlVXJsICsgJy9jb250ZXh0cy8nICsgaWQgKyAnL2hpZGUnO1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdCh1cmwsIHt9KTtcbiAgfVxuXG4gIHNob3dDb250ZXh0KGlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmJhc2VVcmwgKyAnL2NvbnRleHRzLycgKyBpZCArICcvc2hvdyc7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KHVybCwge30pO1xuICB9XG5cbiAgZGVsZXRlKGlkOiBzdHJpbmcsIGltcG9ydGVkID0gZmFsc2UpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICBjb25zdCBjb250ZXh0czogQ29udGV4dHNMaXN0ID0geyBvdXJzOiBbXSB9O1xuICAgIE9iamVjdC5rZXlzKHRoaXMuY29udGV4dHMkLnZhbHVlKS5mb3JFYWNoKFxuICAgICAgKGtleSkgPT5cbiAgICAgICAgKGNvbnRleHRzW2tleV0gPSB0aGlzLmNvbnRleHRzJC52YWx1ZVtrZXldLmZpbHRlcigoYykgPT4gYy5pZCAhPT0gaWQpKVxuICAgICk7XG5cbiAgICBpZiAoaW1wb3J0ZWQpIHtcbiAgICAgIHRoaXMuaW1wb3J0ZWRDb250ZXh0ID0gdGhpcy5pbXBvcnRlZENvbnRleHQuZmlsdGVyKChjKSA9PiBjLmlkICE9PSBpZCk7XG4gICAgICByZXR1cm4gb2YodGhpcy5jb250ZXh0cyQubmV4dChjb250ZXh0cykpO1xuICAgIH1cblxuICAgIGNvbnN0IHVybCA9IHRoaXMuYmFzZVVybCArICcvY29udGV4dHMvJyArIGlkO1xuICAgIHJldHVybiB0aGlzLmh0dHAuZGVsZXRlPHZvaWQ+KHVybCkucGlwZShcbiAgICAgIHRhcCgocmVzKSA9PiB7XG4gICAgICAgIHRoaXMuY29udGV4dHMkLm5leHQoY29udGV4dHMpO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgY3JlYXRlKGNvbnRleHQ6IERldGFpbGVkQ29udGV4dCk6IE9ic2VydmFibGU8Q29udGV4dD4ge1xuICAgIGNvbnN0IHVybCA9IHRoaXMuYmFzZVVybCArICcvY29udGV4dHMnO1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDxDb250ZXh0Pih1cmwsIGNvbnRleHQpLnBpcGUoXG4gICAgICBtYXAoKGNvbnRleHRDcmVhdGVkKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLmF1dGhTZXJ2aWNlLmF1dGhlbnRpY2F0ZWQpIHtcbiAgICAgICAgICBjb250ZXh0Q3JlYXRlZC5wZXJtaXNzaW9uID0gVHlwZVBlcm1pc3Npb25bVHlwZVBlcm1pc3Npb24ud3JpdGVdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnRleHRDcmVhdGVkLnBlcm1pc3Npb24gPSBUeXBlUGVybWlzc2lvbltUeXBlUGVybWlzc2lvbi5yZWFkXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvbnRleHRzJC52YWx1ZS5vdXJzLnVuc2hpZnQoY29udGV4dENyZWF0ZWQpO1xuICAgICAgICB0aGlzLmNvbnRleHRzJC5uZXh0KHRoaXMuY29udGV4dHMkLnZhbHVlKTtcbiAgICAgICAgcmV0dXJuIGNvbnRleHRDcmVhdGVkO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgY2xvbmUoaWQ6IHN0cmluZywgcHJvcGVydGllcyA9IHt9KTogT2JzZXJ2YWJsZTxDb250ZXh0PiB7XG4gICAgY29uc3QgdXJsID0gdGhpcy5iYXNlVXJsICsgJy9jb250ZXh0cy8nICsgaWQgKyAnL2Nsb25lJztcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8Q29udGV4dD4odXJsLCBwcm9wZXJ0aWVzKS5waXBlKFxuICAgICAgbWFwKChjb250ZXh0Q2xvbmVkKSA9PiB7XG4gICAgICAgIGNvbnRleHRDbG9uZWQucGVybWlzc2lvbiA9IFR5cGVQZXJtaXNzaW9uW1R5cGVQZXJtaXNzaW9uLndyaXRlXTtcbiAgICAgICAgdGhpcy5jb250ZXh0cyQudmFsdWUub3Vycy51bnNoaWZ0KGNvbnRleHRDbG9uZWQpO1xuICAgICAgICB0aGlzLmNvbnRleHRzJC5uZXh0KHRoaXMuY29udGV4dHMkLnZhbHVlKTtcbiAgICAgICAgcmV0dXJuIGNvbnRleHRDbG9uZWQ7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICB1cGRhdGUoaWQ6IHN0cmluZywgY29udGV4dDogQ29udGV4dCk6IE9ic2VydmFibGU8Q29udGV4dD4ge1xuICAgIGNvbnN0IHVybCA9IHRoaXMuYmFzZVVybCArICcvY29udGV4dHMvJyArIGlkO1xuICAgIHJldHVybiB0aGlzLmh0dHAucGF0Y2g8Q29udGV4dD4odXJsLCBjb250ZXh0KTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgYWRkVG9vbEFzc29jaWF0aW9uKGNvbnRleHRJZDogc3RyaW5nLCB0b29sSWQ6IHN0cmluZyk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuYmFzZVVybH0vY29udGV4dHMvJHtjb250ZXh0SWR9L3Rvb2xzYDtcbiAgICBjb25zdCBhc3NvY2lhdGlvbiA9IHtcbiAgICAgIHRvb2xJZFxuICAgIH07XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PHZvaWQ+KHVybCwgYXNzb2NpYXRpb24pO1xuICB9XG5cbiAgZGVsZXRlVG9vbEFzc29jaWF0aW9uKGNvbnRleHRJZDogc3RyaW5nLCB0b29sSWQ6IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5iYXNlVXJsfS9jb250ZXh0cy8ke2NvbnRleHRJZH0vdG9vbHMvJHt0b29sSWR9YDtcbiAgICByZXR1cm4gdGhpcy5odHRwLmRlbGV0ZSh1cmwpO1xuICB9XG5cbiAgZ2V0UGVybWlzc2lvbnMoaWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Q29udGV4dFBlcm1pc3Npb25bXT4ge1xuICAgIGNvbnN0IHVybCA9IHRoaXMuYmFzZVVybCArICcvY29udGV4dHMvJyArIGlkICsgJy9wZXJtaXNzaW9ucyc7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8Q29udGV4dFBlcm1pc3Npb25bXT4odXJsKTtcbiAgfVxuXG4gIGFkZFBlcm1pc3Npb25Bc3NvY2lhdGlvbihcbiAgICBjb250ZXh0SWQ6IHN0cmluZyxcbiAgICBwcm9maWw6IHN0cmluZyxcbiAgICB0eXBlOiBUeXBlUGVybWlzc2lvblxuICApOiBPYnNlcnZhYmxlPENvbnRleHRQZXJtaXNzaW9uW10+IHtcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmJhc2VVcmx9L2NvbnRleHRzLyR7Y29udGV4dElkfS9wZXJtaXNzaW9uc2A7XG4gICAgY29uc3QgYXNzb2NpYXRpb24gPSB7XG4gICAgICBwcm9maWwsXG4gICAgICB0eXBlUGVybWlzc2lvbjogdHlwZVxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8Q29udGV4dFBlcm1pc3Npb25bXT4odXJsLCBhc3NvY2lhdGlvbikucGlwZShcbiAgICAgIGNhdGNoRXJyb3IoKHJlcykgPT4ge1xuICAgICAgICB0aGlzLmhhbmRsZUVycm9yKHJlcywgdW5kZWZpbmVkLCB0cnVlKTtcbiAgICAgICAgdGhyb3cgW3Jlc107IC8vIFRPRE8gTm90IHN1cmUgYWJvdXQgdGhpcy5cbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGRlbGV0ZVBlcm1pc3Npb25Bc3NvY2lhdGlvbihcbiAgICBjb250ZXh0SWQ6IHN0cmluZyxcbiAgICBwZXJtaXNzaW9uSWQ6IHN0cmluZ1xuICApOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmJhc2VVcmx9L2NvbnRleHRzLyR7Y29udGV4dElkfS9wZXJtaXNzaW9ucy8ke3Blcm1pc3Npb25JZH1gO1xuICAgIHJldHVybiB0aGlzLmh0dHAuZGVsZXRlPHZvaWQ+KHVybCk7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgZ2V0TG9jYWxDb250ZXh0cygpOiBPYnNlcnZhYmxlPENvbnRleHRzTGlzdD4ge1xuICAgIGNvbnN0IHVybCA9IHRoaXMuZ2V0UGF0aCh0aGlzLm9wdGlvbnMuY29udGV4dExpc3RGaWxlKTtcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldDxDb250ZXh0c0xpc3Q+KHVybCkucGlwZShcbiAgICAgIG1hcCgocmVzOiBhbnkpID0+IHtcbiAgICAgICAgcmV0dXJuIHsgb3VyczogcmVzIH07XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBnZXRMb2NhbENvbnRleHQodXJpOiBzdHJpbmcpOiBPYnNlcnZhYmxlPERldGFpbGVkQ29udGV4dD4ge1xuICAgIGNvbnN0IHVybCA9IHRoaXMuZ2V0UGF0aChgJHt1cml9Lmpzb25gKTtcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldDxEZXRhaWxlZENvbnRleHQ+KHVybCkucGlwZShcbiAgICAgIG1lcmdlTWFwKChyZXMpID0+IHtcbiAgICAgICAgaWYgKCFyZXMuYmFzZSkge1xuICAgICAgICAgIHJldHVybiBvZihyZXMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVybEJhc2UgPSB0aGlzLmdldFBhdGgoYCR7cmVzLmJhc2V9Lmpzb25gKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8RGV0YWlsZWRDb250ZXh0Pih1cmxCYXNlKS5waXBlKFxuICAgICAgICAgIG1hcCgocmVzQmFzZTogRGV0YWlsZWRDb250ZXh0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXNNZXJnZSA9IHJlcztcbiAgICAgICAgICAgIHJlc01lcmdlLm1hcCA9IE9iamVjdFV0aWxzLm1lcmdlRGVlcChyZXNCYXNlLm1hcCwgcmVzLm1hcCk7XG4gICAgICAgICAgICByZXNNZXJnZS5sYXllcnMgPSAocmVzQmFzZS5sYXllcnMgfHwgW10pXG4gICAgICAgICAgICAgIC5jb25jYXQocmVzLmxheWVycyB8fCBbXSlcbiAgICAgICAgICAgICAgLnJldmVyc2UoKVxuICAgICAgICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgICAgICAgIChsLCBpbmRleCwgc2VsZikgPT5cbiAgICAgICAgICAgICAgICAgICFsLmlkIHx8IHNlbGYuZmluZEluZGV4KChsMikgPT4gbDIuaWQgPT09IGwuaWQpID09PSBpbmRleFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIC5yZXZlcnNlKCk7XG4gICAgICAgICAgICByZXNNZXJnZS50b29sYmFyID0gcmVzLnRvb2xiYXIgfHwgcmVzQmFzZS50b29sYmFyO1xuICAgICAgICAgICAgcmVzTWVyZ2UubWVzc2FnZSA9IHJlcy5tZXNzYWdlIHx8IHJlc0Jhc2UubWVzc2FnZTtcbiAgICAgICAgICAgIHJlc01lcmdlLm1lc3NhZ2VzID0gcmVzLm1lc3NhZ2VzIHx8IHJlc0Jhc2UubWVzc2FnZXM7XG4gICAgICAgICAgICByZXNNZXJnZS50b29scyA9IChyZXMudG9vbHMgfHwgW10pXG4gICAgICAgICAgICAgIC5jb25jYXQocmVzQmFzZS50b29scyB8fCBbXSlcbiAgICAgICAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAgICAgICAodCwgaW5kZXgsIHNlbGYpID0+XG4gICAgICAgICAgICAgICAgICBzZWxmLmZpbmRJbmRleCgodDIpID0+IHQyLm5hbWUgPT09IHQubmFtZSkgPT09IGluZGV4XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4gcmVzTWVyZ2U7XG4gICAgICAgICAgfSksXG4gICAgICAgICAgY2F0Y2hFcnJvcigoZXJyKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZUVycm9yKGVyciwgdXJpKTtcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSksXG4gICAgICBjYXRjaEVycm9yKChlcnIyKSA9PiB7XG4gICAgICAgIHRoaXMuaGFuZGxlRXJyb3IoZXJyMiwgdXJpKTtcbiAgICAgICAgdGhyb3cgZXJyMjtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGxvYWRDb250ZXh0cyhwZXJtaXNzaW9ucz86IHN0cmluZ1tdLCBoaWRkZW4/OiBib29sZWFuKSB7XG4gICAgbGV0IHJlcXVlc3Q7XG4gICAgaWYgKHRoaXMuYmFzZVVybCkge1xuICAgICAgcmVxdWVzdCA9IHRoaXMuZ2V0KHBlcm1pc3Npb25zLCBoaWRkZW4pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXF1ZXN0ID0gdGhpcy5nZXRMb2NhbENvbnRleHRzKCk7XG4gICAgfVxuICAgIHJlcXVlc3Quc3Vic2NyaWJlKChjb250ZXh0cykgPT4ge1xuICAgICAgY29udGV4dHMub3VycyA9IHRoaXMuaW1wb3J0ZWRDb250ZXh0LmNvbmNhdChjb250ZXh0cy5vdXJzKTtcbiAgICAgIHRoaXMuY29udGV4dHMkLm5leHQoY29udGV4dHMpO1xuICAgIH0pO1xuICB9XG5cbiAgbG9hZERlZmF1bHRDb250ZXh0KCkge1xuICAgIGNvbnN0IGxvYWRGY3QgPSAoZGlyZWN0ID0gZmFsc2UpID0+IHtcbiAgICAgIGlmICghZGlyZWN0ICYmIHRoaXMuYmFzZVVybCAmJiB0aGlzLmF1dGhTZXJ2aWNlLmF1dGhlbnRpY2F0ZWQpIHtcbiAgICAgICAgdGhpcy5nZXREZWZhdWx0KCkuc3Vic2NyaWJlKFxuICAgICAgICAgIChfY29udGV4dDogRGV0YWlsZWRDb250ZXh0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmRlZmF1bHRDb250ZXh0VXJpID0gX2NvbnRleHQudXJpO1xuICAgICAgICAgICAgdGhpcy5hZGRDb250ZXh0VG9MaXN0KF9jb250ZXh0KTtcbiAgICAgICAgICAgIHRoaXMuc2V0Q29udGV4dChfY29udGV4dCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmRlZmF1bHRDb250ZXh0SWQkLm5leHQodW5kZWZpbmVkKTtcbiAgICAgICAgICAgIHRoaXMubG9hZENvbnRleHQodGhpcy5kZWZhdWx0Q29udGV4dFVyaSk7XG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sb2FkQ29udGV4dCh0aGlzLmRlZmF1bHRDb250ZXh0VXJpKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHRoaXMucm91dGUgJiYgdGhpcy5yb3V0ZS5vcHRpb25zLmNvbnRleHRLZXkpIHtcbiAgICAgIHRoaXMucm91dGUucXVlcnlQYXJhbXMucGlwZShkZWJvdW5jZVRpbWUoMTAwKSkuc3Vic2NyaWJlKChwYXJhbXMpID0+IHtcbiAgICAgICAgY29uc3QgY29udGV4dFBhcmFtID0gcGFyYW1zW3RoaXMucm91dGUub3B0aW9ucy5jb250ZXh0S2V5IGFzIHN0cmluZ107XG4gICAgICAgIGxldCBkaXJlY3QgPSBmYWxzZTtcbiAgICAgICAgaWYgKGNvbnRleHRQYXJhbSkge1xuICAgICAgICAgIHRoaXMuZGVmYXVsdENvbnRleHRVcmkgPSBjb250ZXh0UGFyYW07XG4gICAgICAgICAgZGlyZWN0ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBsb2FkRmN0KGRpcmVjdCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9hZEZjdCgpO1xuICAgIH1cbiAgfVxuXG4gIGxvYWRDb250ZXh0KHVyaTogc3RyaW5nKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHRoaXMuY29udGV4dCQudmFsdWU7XG5cbiAgICBpZiAoY29udGV4dCAmJiBjb250ZXh0LnVyaSA9PT0gdXJpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5nZXRDb250ZXh0QnlVcmkodXJpKVxuICAgICAgLnBpcGUoZmlyc3QoKSlcbiAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgIChfY29udGV4dDogRGV0YWlsZWRDb250ZXh0KSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRDb250ZXh0VG9MaXN0KF9jb250ZXh0KTtcbiAgICAgICAgICB0aGlzLnNldENvbnRleHQoX2NvbnRleHQpO1xuICAgICAgICB9LFxuICAgICAgICAoZXJyKSA9PiB7XG4gICAgICAgICAgaWYgKHVyaSAhPT0gdGhpcy5vcHRpb25zLmRlZmF1bHRDb250ZXh0VXJpKSB7XG4gICAgICAgICAgICB0aGlzLmxvYWRDb250ZXh0KHRoaXMub3B0aW9ucy5kZWZhdWx0Q29udGV4dFVyaSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICB9XG5cbiAgc2V0Q29udGV4dChjb250ZXh0OiBEZXRhaWxlZENvbnRleHQpIHtcbiAgICB0aGlzLmhhbmRsZUNvbnRleHRNZXNzYWdlKGNvbnRleHQpO1xuICAgIGNvbnN0IGN1cnJlbnRDb250ZXh0ID0gdGhpcy5jb250ZXh0JC52YWx1ZTtcbiAgICBpZiAoY3VycmVudENvbnRleHQgJiYgY29udGV4dCAmJiBjb250ZXh0LmlkID09PSBjdXJyZW50Q29udGV4dC5pZCkge1xuICAgICAgaWYgKGNvbnRleHQubWFwLnZpZXcua2VlcEN1cnJlbnRWaWV3ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29udGV4dC5tYXAudmlldy5rZWVwQ3VycmVudFZpZXcgPSB0cnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5jb250ZXh0JC5uZXh0KGNvbnRleHQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghY29udGV4dC5tYXApIHtcbiAgICAgIGNvbnRleHQubWFwID0geyB2aWV3OiB7fSB9O1xuICAgIH1cblxuICAgIE9iamVjdC5hc3NpZ24oY29udGV4dC5tYXAudmlldywgdGhpcy5tYXBWaWV3RnJvbVJvdXRlKTtcblxuICAgIHRoaXMuY29udGV4dCQubmV4dChjb250ZXh0KTtcbiAgfVxuXG4gIGxvYWRFZGl0ZWRDb250ZXh0KHVyaTogc3RyaW5nKSB7XG4gICAgdGhpcy5nZXRDb250ZXh0QnlVcmkodXJpKS5zdWJzY3JpYmUoKF9jb250ZXh0OiBEZXRhaWxlZENvbnRleHQpID0+IHtcbiAgICAgIHRoaXMuc2V0RWRpdGVkQ29udGV4dChfY29udGV4dCk7XG4gICAgfSk7XG4gIH1cblxuICBzZXRFZGl0ZWRDb250ZXh0KGNvbnRleHQ6IERldGFpbGVkQ29udGV4dCkge1xuICAgIHRoaXMuZWRpdGVkQ29udGV4dCQubmV4dChjb250ZXh0KTtcbiAgfVxuXG4gIGdldENvbnRleHRGcm9tTWFwKGlnb01hcDogSWdvTWFwLCBlbXB0eT86IGJvb2xlYW4pOiBEZXRhaWxlZENvbnRleHQge1xuICAgIGNvbnN0IHZpZXcgPSBpZ29NYXAub2wuZ2V0VmlldygpO1xuICAgIGNvbnN0IHByb2ogPSB2aWV3LmdldFByb2plY3Rpb24oKS5nZXRDb2RlKCk7XG4gICAgY29uc3QgY2VudGVyOiBhbnkgPSBuZXcgb2xQb2ludCh2aWV3LmdldENlbnRlcigpKS50cmFuc2Zvcm0oXG4gICAgICBwcm9qLFxuICAgICAgJ0VQU0c6NDMyNidcbiAgICApO1xuXG4gICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgIHVyaTogdXVpZCgpLFxuICAgICAgdGl0bGU6ICcnLFxuICAgICAgc2NvcGU6ICdwcml2YXRlJyxcbiAgICAgIG1hcDoge1xuICAgICAgICB2aWV3OiB7XG4gICAgICAgICAgY2VudGVyOiBjZW50ZXIuZ2V0Q29vcmRpbmF0ZXMoKSxcbiAgICAgICAgICB6b29tOiB2aWV3LmdldFpvb20oKSxcbiAgICAgICAgICBwcm9qZWN0aW9uOiBwcm9qLFxuICAgICAgICAgIG1heFpvb21PbkV4dGVudDogaWdvTWFwLnZpZXdDb250cm9sbGVyLm1heFpvb21PbkV4dGVudFxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgbGF5ZXJzOiBbXSxcbiAgICAgIHRvb2xzOiBbXVxuICAgIH07XG5cbiAgICBsZXQgbGF5ZXJzID0gW107XG4gICAgaWYgKGVtcHR5ID09PSB0cnVlKSB7XG4gICAgICBsYXllcnMgPSBpZ29NYXAubGF5ZXJzJFxuICAgICAgICAuZ2V0VmFsdWUoKVxuICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgIChsYXkpID0+XG4gICAgICAgICAgICBsYXkuYmFzZUxheWVyID09PSB0cnVlIHx8XG4gICAgICAgICAgICBsYXkub3B0aW9ucy5pZCA9PT0gJ3NlYXJjaFBvaW50ZXJTdW1tYXJ5SWQnXG4gICAgICAgIClcbiAgICAgICAgLnNvcnQoKGEsIGIpID0+IGEuekluZGV4IC0gYi56SW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsYXllcnMgPSBpZ29NYXAubGF5ZXJzJC5nZXRWYWx1ZSgpLmZpbHRlcihsYXkgPT4gIWxheS5pZC5pbmNsdWRlcygnV2ZzV29ya3NwYWNlVGFibGVEZXN0JykpLnNvcnQoKGEsIGIpID0+IGEuekluZGV4IC0gYi56SW5kZXgpO1xuICAgIH1cblxuICAgIGxldCBpID0gMDtcbiAgICBmb3IgKGNvbnN0IGwgb2YgbGF5ZXJzKSB7XG4gICAgICBjb25zdCBsYXllcjogYW55ID0gbDtcbiAgICAgIGNvbnN0IG9wdHMgPSB7XG4gICAgICAgIGlkOiBsYXllci5vcHRpb25zLmlkID8gU3RyaW5nKGxheWVyLm9wdGlvbnMuaWQpIDogdW5kZWZpbmVkLFxuICAgICAgICBsYXllck9wdGlvbnM6IHtcbiAgICAgICAgICB0aXRsZTogbGF5ZXIub3B0aW9ucy50aXRsZSxcbiAgICAgICAgICB6SW5kZXg6ICsraSxcbiAgICAgICAgICB2aXNpYmxlOiBsYXllci52aXNpYmxlLFxuICAgICAgICAgIHNlY3VyaXR5OiBsYXllci5zZWN1cml0eVxuICAgICAgICB9IGFzIExheWVyT3B0aW9ucyxcbiAgICAgICAgc291cmNlT3B0aW9uczoge1xuICAgICAgICAgIHR5cGU6IGxheWVyLmRhdGFTb3VyY2Uub3B0aW9ucy50eXBlLFxuICAgICAgICAgIHBhcmFtczogbGF5ZXIuZGF0YVNvdXJjZS5vcHRpb25zLnBhcmFtcyxcbiAgICAgICAgICB1cmw6IGxheWVyLmRhdGFTb3VyY2Uub3B0aW9ucy51cmwsXG4gICAgICAgICAgcXVlcnlhYmxlOiBsYXllci5xdWVyeWFibGVcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGlmIChvcHRzLnNvdXJjZU9wdGlvbnMudHlwZSkge1xuICAgICAgICBjb250ZXh0LmxheWVycy5wdXNoKG9wdHMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnRleHQudG9vbHMgPSB0aGlzLnRvb2xzLm1hcCgodG9vbCkgPT4ge1xuICAgICAgcmV0dXJuIHsgaWQ6IFN0cmluZyh0b29sLmlkKSwgZ2xvYmFsOiB0b29sLmdsb2JhbCB9O1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNvbnRleHQ7XG4gIH1cblxuICBnZXRDb250ZXh0RnJvbUxheWVycyhcbiAgICBpZ29NYXA6IElnb01hcCxcbiAgICBsYXllcnM6IExheWVyW10sXG4gICAgbmFtZTogc3RyaW5nXG4gICk6IERldGFpbGVkQ29udGV4dCB7XG4gICAgY29uc3QgY3VycmVudENvbnRleHQgPSB0aGlzLmNvbnRleHQkLmdldFZhbHVlKCk7XG4gICAgY29uc3QgdmlldyA9IGlnb01hcC5vbC5nZXRWaWV3KCk7XG4gICAgY29uc3QgcHJvaiA9IHZpZXcuZ2V0UHJvamVjdGlvbigpLmdldENvZGUoKTtcbiAgICBjb25zdCBjZW50ZXI6IGFueSA9IG5ldyBvbFBvaW50KHZpZXcuZ2V0Q2VudGVyKCkpLnRyYW5zZm9ybShcbiAgICAgIHByb2osXG4gICAgICAnRVBTRzo0MzI2J1xuICAgICk7XG5cbiAgICBjb25zdCBjb250ZXh0ID0ge1xuICAgICAgdXJpOiBuYW1lLFxuICAgICAgdGl0bGU6IG5hbWUsXG4gICAgICBtYXA6IHtcbiAgICAgICAgdmlldzoge1xuICAgICAgICAgIGNlbnRlcjogY2VudGVyLmdldENvb3JkaW5hdGVzKCksXG4gICAgICAgICAgem9vbTogdmlldy5nZXRab29tKCksXG4gICAgICAgICAgcHJvamVjdGlvbjogcHJvalxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgbGF5ZXJzOiBbXSxcbiAgICAgIHRvb2xiYXI6IFtdLFxuICAgICAgdG9vbHM6IFtdLFxuICAgICAgZXh0cmFGZWF0dXJlczogW11cbiAgICB9O1xuXG4gICAgY29uc3QgY3VycmVudExheWVycyA9IGlnb01hcC5sYXllcnMkLmdldFZhbHVlKCk7XG4gICAgY29udGV4dC5sYXllcnMgPSBjdXJyZW50TGF5ZXJzXG4gICAgICAuZmlsdGVyKChsKSA9PiBsLmJhc2VMYXllcilcbiAgICAgIC5tYXAoKGwpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBiYXNlTGF5ZXI6IHRydWUsXG4gICAgICAgICAgc291cmNlT3B0aW9uczogbC5vcHRpb25zLnNvdXJjZU9wdGlvbnMsXG4gICAgICAgICAgdGl0bGU6IGwub3B0aW9ucy50aXRsZSxcbiAgICAgICAgICB2aXNpYmxlOiBsLnZpc2libGVcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuXG4gICAgbGF5ZXJzLmZvckVhY2goKGxheWVyKSA9PiB7XG4gICAgICBjb25zdCBsYXllckZvdW5kID0gY3VycmVudENvbnRleHQubGF5ZXJzLmZpbmQoXG4gICAgICAgIChjb250ZXh0TGF5ZXIpID0+IHtcbiAgICAgICAgICBjb25zdCBzb3VyY2UgPSBjb250ZXh0TGF5ZXIuc291cmNlO1xuICAgICAgICAgIHJldHVybiBzb3VyY2UgJiYgbGF5ZXIuaWQgPT09IHNvdXJjZS5pZCAmJiAhY29udGV4dExheWVyLmJhc2VMYXllcjtcbiAgICAgICAgfSk7XG5cbiAgICAgIGlmIChsYXllckZvdW5kKSB7XG4gICAgICAgIGxldCBsYXllclN0eWxlID0gbGF5ZXJGb3VuZFtgc3R5bGVgXTtcbiAgICAgICAgaWYgKGxheWVyRm91bmRbYHN0eWxlQnlBdHRyaWJ1dGVgXSkge1xuICAgICAgICAgIGxheWVyU3R5bGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIH0gZWxzZSBpZiAobGF5ZXJGb3VuZFtgY2x1c3RlckJhc2VTdHlsZWBdKSB7XG4gICAgICAgICAgbGF5ZXJTdHlsZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBkZWxldGUgbGF5ZXJGb3VuZC5zb3VyY2VPcHRpb25zW2Bzb3VyY2VgXTtcbiAgICAgICAgICBkZWxldGUgbGF5ZXJGb3VuZC5zb3VyY2VPcHRpb25zW2Bmb3JtYXRgXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHRzID0ge1xuICAgICAgICAgIGJhc2VMYXllcjogbGF5ZXJGb3VuZC5iYXNlTGF5ZXIsXG4gICAgICAgICAgdGl0bGU6IGxheWVyLm9wdGlvbnMudGl0bGUsXG4gICAgICAgICAgekluZGV4OiBsYXllci56SW5kZXgsXG4gICAgICAgICAgc3R5bGVCeUF0dHJpYnV0ZTogbGF5ZXJGb3VuZFtgc3R5bGVCeUF0dHJpYnV0ZWBdLFxuICAgICAgICAgIGNsdXN0ZXJCYXNlU3R5bGU6IGxheWVyRm91bmRbYGNsdXN0ZXJCYXNlU3R5bGVgXSxcbiAgICAgICAgICBzdHlsZTogbGF5ZXJTdHlsZSxcbiAgICAgICAgICBjbHVzdGVyUGFyYW06IGxheWVyRm91bmRbYGNsdXN0ZXJQYXJhbWBdLFxuICAgICAgICAgIHZpc2libGU6IGxheWVyLnZpc2libGUsXG4gICAgICAgICAgb3BhY2l0eTogbGF5ZXIub3BhY2l0eSxcbiAgICAgICAgICBzb3VyY2VPcHRpb25zOiBsYXllckZvdW5kLnNvdXJjZU9wdGlvbnNcbiAgICAgICAgfTtcbiAgICAgICAgY29udGV4dC5sYXllcnMucHVzaChvcHRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghKGxheWVyLm9sLmdldFNvdXJjZSgpIGluc3RhbmNlb2Ygb2xWZWN0b3JTb3VyY2UpKSB7XG4gICAgICAgICAgY29uc3QgY2F0YWxvZ0xheWVyID0gbGF5ZXIub3B0aW9ucztcbiAgICAgICAgICBjYXRhbG9nTGF5ZXIuekluZGV4ID0gbGF5ZXIuekluZGV4O1xuICAgICAgICAgIGRlbGV0ZSBjYXRhbG9nTGF5ZXIuc291cmNlO1xuICAgICAgICAgIGNvbnRleHQubGF5ZXJzLnB1c2goY2F0YWxvZ0xheWVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsZXQgZmVhdHVyZXM7XG4gICAgICAgICAgY29uc3Qgd3JpdGVyID0gbmV3IEdlb0pTT04oKTtcbiAgICAgICAgICBpZiAobGF5ZXIub2wuZ2V0U291cmNlKCkgaW5zdGFuY2VvZiBDbHVzdGVyKSB7XG4gICAgICAgICAgICBjb25zdCBjbHVzdGVyU291cmNlID0gbGF5ZXIub2wuZ2V0U291cmNlKCkgYXMgQ2x1c3RlcjtcbiAgICAgICAgICAgIGxldCBvbEZlYXR1cmVzID0gY2x1c3RlclNvdXJjZS5nZXRGZWF0dXJlcygpO1xuICAgICAgICAgICAgb2xGZWF0dXJlcyA9IChvbEZlYXR1cmVzIGFzIGFueSkuZmxhdE1hcCgoY2x1c3RlcjogYW55KSA9PiBjbHVzdGVyLmdldCgnZmVhdHVyZXMnKSk7XG4gICAgICAgICAgICBjb25zdCBjbGVhbmVkT2xGZWF0dXJlcyA9IHRoaXMuZXhwb3J0U2VydmljZS5nZW5lcmF0ZUZlYXR1cmUob2xGZWF0dXJlcywgJ0dlb0pTT04nLCAnX2ZlYXR1cmVTdG9yZScpO1xuICAgICAgICAgICAgZmVhdHVyZXMgPSB3cml0ZXIud3JpdGVGZWF0dXJlcyhcbiAgICAgICAgICAgICAgY2xlYW5lZE9sRmVhdHVyZXMsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBkYXRhUHJvamVjdGlvbjogJ0VQU0c6NDMyNicsXG4gICAgICAgICAgICAgICAgZmVhdHVyZVByb2plY3Rpb246ICdFUFNHOjM4NTcnXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IGxheWVyLm9sLmdldFNvdXJjZSgpIGFzIG9sVmVjdG9yU291cmNlO1xuICAgICAgICAgICAgY29uc3Qgb2xGZWF0dXJlcyA9IHNvdXJjZS5nZXRGZWF0dXJlcygpO1xuICAgICAgICAgICAgY29uc3QgY2xlYW5lZE9sRmVhdHVyZXMgPSB0aGlzLmV4cG9ydFNlcnZpY2UuZ2VuZXJhdGVGZWF0dXJlKG9sRmVhdHVyZXMsICdHZW9KU09OJywgJ19mZWF0dXJlU3RvcmUnKTtcbiAgICAgICAgICAgIGZlYXR1cmVzID0gd3JpdGVyLndyaXRlRmVhdHVyZXMoXG4gICAgICAgICAgICAgIGNsZWFuZWRPbEZlYXR1cmVzLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZGF0YVByb2plY3Rpb246ICdFUFNHOjQzMjYnLFxuICAgICAgICAgICAgICAgIGZlYXR1cmVQcm9qZWN0aW9uOiAnRVBTRzozODU3J1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmZWF0dXJlcyA9IEpTT04ucGFyc2UoZmVhdHVyZXMpO1xuICAgICAgICAgIGZlYXR1cmVzLm5hbWUgPSBsYXllci5vcHRpb25zLnRpdGxlO1xuICAgICAgICAgIGNvbnRleHQuZXh0cmFGZWF0dXJlcy5wdXNoKGZlYXR1cmVzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29udGV4dC50b29sYmFyID0gdGhpcy50b29sYmFyO1xuICAgIGNvbnRleHQudG9vbHMgPSB0aGlzLnRvb2xzO1xuXG4gICAgcmV0dXJuIGNvbnRleHQ7XG4gIH1cblxuICBzZXRUb29scyh0b29sczogVG9vbFtdKSB7XG4gICAgdGhpcy50b29scyA9IHRvb2xzO1xuICB9XG5cbiAgc2V0VG9vbGJhcih0b29sYmFyOiBzdHJpbmdbXSkge1xuICAgIHRoaXMudG9vbGJhciA9IHRvb2xiYXI7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUNvbnRleHRNZXNzYWdlKGNvbnRleHQ6IERldGFpbGVkQ29udGV4dCkge1xuICAgIGlmICh0aGlzLmNvbnRleHQkLnZhbHVlICYmIGNvbnRleHQudXJpICYmIHRoaXMuY29udGV4dCQudmFsdWUudXJpICE9PSBjb250ZXh0LnVyaSkge1xuICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5yZW1vdmVBbGxBcmVOb3RFcnJvcigpO1xuICAgIH1cblxuICAgIGNvbnRleHQubWVzc2FnZXMgPSBjb250ZXh0Lm1lc3NhZ2VzID8gY29udGV4dC5tZXNzYWdlcyA6IFtdO1xuICAgIGNvbnRleHQubWVzc2FnZXMucHVzaChjb250ZXh0Lm1lc3NhZ2UpO1xuICAgIGNvbnRleHQubWVzc2FnZXMubWFwKG1lc3NhZ2UgPT4ge1xuICAgICAgaWYgKG1lc3NhZ2UpIHtcbiAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5tZXNzYWdlKG1lc3NhZ2UgYXMgTWVzc2FnZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldENvbnRleHRCeVVyaSh1cmk6IHN0cmluZyk6IE9ic2VydmFibGU8RGV0YWlsZWRDb250ZXh0PiB7XG4gICAgaWYgKHRoaXMuYmFzZVVybCkge1xuICAgICAgbGV0IGNvbnRleHRUb0xvYWQ7XG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLmNvbnRleHRzJC52YWx1ZSkpIHtcbiAgICAgICAgY29udGV4dFRvTG9hZCA9IHRoaXMuY29udGV4dHMkLnZhbHVlW2tleV0uZmluZCgoYykgPT4ge1xuICAgICAgICAgIHJldHVybiBjLnVyaSA9PT0gdXJpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGNvbnRleHRUb0xvYWQpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoY29udGV4dFRvTG9hZCAmJiBjb250ZXh0VG9Mb2FkLmltcG9ydGVkKSB7XG4gICAgICAgIHJldHVybiBvZihjb250ZXh0VG9Mb2FkKTtcbiAgICAgIH1cblxuICAgICAgLy8gVE9ETyA6IHVzZSBhbHdheXMgaWQgb3IgdXJpXG4gICAgICBjb25zdCBpZCA9IGNvbnRleHRUb0xvYWQgPyBjb250ZXh0VG9Mb2FkLmlkIDogdXJpO1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0RGV0YWlscyhpZCk7XG4gICAgfVxuXG4gICAgY29uc3QgaW1wb3J0ZWRDb250ZXh0ID0gdGhpcy5jb250ZXh0cyQudmFsdWUub3Vycy5maW5kKChjdXJyZW50Q29udGV4dCkgPT4ge1xuICAgICAgcmV0dXJuIGN1cnJlbnRDb250ZXh0LnVyaSA9PT0gdXJpICYmIGN1cnJlbnRDb250ZXh0LmltcG9ydGVkID09PSB0cnVlO1xuICAgIH0pO1xuXG4gICAgaWYgKGltcG9ydGVkQ29udGV4dCkge1xuICAgICAgcmV0dXJuIG9mKGltcG9ydGVkQ29udGV4dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmdldExvY2FsQ29udGV4dCh1cmkpO1xuICAgIH1cbiAgfVxuXG4gIGdldENvbnRleHRMYXllcnMoaWdvTWFwOiBJZ29NYXApIHtcbiAgICBjb25zdCBsYXllcnM6IExheWVyW10gPSBbXTtcbiAgICBjb25zdCBtYXBMYXllcnMgPSBpZ29NYXAubGF5ZXJzJC5nZXRWYWx1ZSgpO1xuICAgIG1hcExheWVycy5mb3JFYWNoKChsYXllcikgPT4ge1xuICAgICAgaWYgKCFsYXllci5iYXNlTGF5ZXIgJiYgbGF5ZXIub3B0aW9ucy5pZCAhPT0gJ3NlYXJjaFBvaW50ZXJTdW1tYXJ5SWQnKSB7XG4gICAgICAgIGxheWVycy5wdXNoKGxheWVyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gbGF5ZXJzO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkUGFyYW1zRnJvbVJvdXRlKCkge1xuICAgIGlmICghdGhpcy5yb3V0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMucm91dGUucXVlcnlQYXJhbXMuc3Vic2NyaWJlKChwYXJhbXMpID0+IHtcbiAgICAgIGNvbnN0IGNlbnRlcktleSA9IHRoaXMucm91dGUub3B0aW9ucy5jZW50ZXJLZXk7XG4gICAgICBpZiAoY2VudGVyS2V5ICYmIHBhcmFtc1tjZW50ZXJLZXkgYXMgc3RyaW5nXSkge1xuICAgICAgICBjb25zdCBjZW50ZXJQYXJhbXMgPSBwYXJhbXNbY2VudGVyS2V5IGFzIHN0cmluZ107XG4gICAgICAgIHRoaXMubWFwVmlld0Zyb21Sb3V0ZS5jZW50ZXIgPSBjZW50ZXJQYXJhbXMuc3BsaXQoJywnKS5tYXAoTnVtYmVyKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcHJvamVjdGlvbktleSA9IHRoaXMucm91dGUub3B0aW9ucy5wcm9qZWN0aW9uS2V5O1xuICAgICAgaWYgKHByb2plY3Rpb25LZXkgJiYgcGFyYW1zW3Byb2plY3Rpb25LZXkgYXMgc3RyaW5nXSkge1xuICAgICAgICBjb25zdCBwcm9qZWN0aW9uUGFyYW0gPSBwYXJhbXNbcHJvamVjdGlvbktleSBhcyBzdHJpbmddO1xuICAgICAgICB0aGlzLm1hcFZpZXdGcm9tUm91dGUucHJvamVjdGlvbiA9IHByb2plY3Rpb25QYXJhbTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgem9vbUtleSA9IHRoaXMucm91dGUub3B0aW9ucy56b29tS2V5O1xuICAgICAgaWYgKHpvb21LZXkgJiYgcGFyYW1zW3pvb21LZXkgYXMgc3RyaW5nXSkge1xuICAgICAgICBjb25zdCB6b29tUGFyYW0gPSBwYXJhbXNbem9vbUtleSBhcyBzdHJpbmddO1xuICAgICAgICB0aGlzLm1hcFZpZXdGcm9tUm91dGUuem9vbSA9IE51bWJlcih6b29tUGFyYW0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQYXRoKGZpbGU6IHN0cmluZykge1xuICAgIGNvbnN0IGJhc2VQYXRoID0gdGhpcy5vcHRpb25zLmJhc2VQYXRoLnJlcGxhY2UoL1xcLyQvLCAnJyk7XG5cbiAgICByZXR1cm4gYCR7YmFzZVBhdGh9LyR7ZmlsZX1gO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVFcnJvcihcbiAgICBlcnJvcjogSHR0cEVycm9yUmVzcG9uc2UsXG4gICAgdXJpOiBzdHJpbmcsXG4gICAgcGVybWlzc2lvbkVycm9yPzogYm9vbGVhblxuICApIHtcbiAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5jb250ZXh0cyQudmFsdWUub3Vycy5maW5kKChvYmopID0+IG9iai51cmkgPT09IHVyaSk7XG4gICAgY29uc3QgdGl0bGVDb250ZXh0ID0gY29udGV4dCA/IGNvbnRleHQudGl0bGUgOiB1cmk7XG4gICAgZXJyb3IuZXJyb3IudGl0bGUgPSB0aGlzLmxhbmd1YWdlU2VydmljZS50cmFuc2xhdGUuaW5zdGFudChcbiAgICAgICdpZ28uY29udGV4dC5jb250ZXh0TWFuYWdlci5pbnZhbGlkLnRpdGxlJ1xuICAgICk7XG5cbiAgICBlcnJvci5lcnJvci5tZXNzYWdlID0gdGhpcy5sYW5ndWFnZVNlcnZpY2UudHJhbnNsYXRlLmluc3RhbnQoXG4gICAgICAnaWdvLmNvbnRleHQuY29udGV4dE1hbmFnZXIuaW52YWxpZC50ZXh0JyxcbiAgICAgIHsgdmFsdWU6IHRpdGxlQ29udGV4dCB9XG4gICAgKTtcblxuICAgIGVycm9yLmVycm9yLnRvRGlzcGxheSA9IHRydWU7XG5cbiAgICBpZiAocGVybWlzc2lvbkVycm9yKSB7XG4gICAgICBlcnJvci5lcnJvci50aXRsZSA9IHRoaXMubGFuZ3VhZ2VTZXJ2aWNlLnRyYW5zbGF0ZS5pbnN0YW50KFxuICAgICAgICAnaWdvLmNvbnRleHQuY29udGV4dE1hbmFnZXIuZXJyb3JzLmFkZFBlcm1pc3Npb25UaXRsZSdcbiAgICAgICk7XG4gICAgICBlcnJvci5lcnJvci5tZXNzYWdlID0gdGhpcy5sYW5ndWFnZVNlcnZpY2UudHJhbnNsYXRlLmluc3RhbnQoXG4gICAgICAgICdpZ28uY29udGV4dC5jb250ZXh0TWFuYWdlci5lcnJvcnMuYWRkUGVybWlzc2lvbidcbiAgICAgICk7XG4gICAgfVxuICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuZXJyb3IoZXJyb3IuZXJyb3IubWVzc2FnZSwgZXJyb3IuZXJyb3IudGl0bGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVDb250ZXh0c0NoYW5nZShcbiAgICBrZWVwQ3VycmVudENvbnRleHQgPSB0cnVlXG4gICkge1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmNvbnRleHQkLnZhbHVlO1xuICAgIGNvbnN0IGVkaXRlZENvbnRleHQgPSB0aGlzLmVkaXRlZENvbnRleHQkLnZhbHVlO1xuICAgIGlmICghY29udGV4dCB8fCBjb250ZXh0LnVyaSA9PT0gdGhpcy5vcHRpb25zLmRlZmF1bHRDb250ZXh0VXJpKSB7XG4gICAgICBrZWVwQ3VycmVudENvbnRleHQgPSBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFrZWVwQ3VycmVudENvbnRleHQgfHwgIXRoaXMuZmluZENvbnRleHQoY29udGV4dCkpIHtcbiAgICAgIHRoaXMuZGVmYXVsdENvbnRleHRVcmkgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLmxvYWREZWZhdWx0Q29udGV4dCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmdldENvbnRleHRCeVVyaShjb250ZXh0LnVyaSlcbiAgICAgICAgLnBpcGUoZmlyc3QoKSlcbiAgICAgICAgLnN1YnNjcmliZShcbiAgICAgICAgICAobmV3Q29udGV4dDogRGV0YWlsZWRDb250ZXh0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnRvb2xzQ2hhbmdlZCQubmV4dChuZXdDb250ZXh0KTtcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgIGlmICh0aGlzLmJhc2VVcmwgJiYgdGhpcy5hdXRoU2VydmljZS5hdXRoZW50aWNhdGVkKSB7XG4gICAgICAgIHRoaXMuZ2V0RGVmYXVsdCgpLnN1YnNjcmliZSgpO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBlZGl0ZWRGb3VuZCA9IHRoaXMuZmluZENvbnRleHQoZWRpdGVkQ29udGV4dCk7XG4gICAgaWYgKCFlZGl0ZWRGb3VuZCB8fCBlZGl0ZWRGb3VuZC5wZXJtaXNzaW9uICE9PSAnd3JpdGUnKSB7XG4gICAgICB0aGlzLnNldEVkaXRlZENvbnRleHQodW5kZWZpbmVkKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFkZENvbnRleHRUb0xpc3QoY29udGV4dDogQ29udGV4dCkge1xuICAgIGNvbnN0IGNvbnRleHRGb3VuZCA9IHRoaXMuZmluZENvbnRleHQoY29udGV4dCk7XG4gICAgaWYgKCFjb250ZXh0Rm91bmQpIHtcbiAgICAgIGNvbnN0IGNvbnRleHRTaW1wbGlmaWUgPSB7XG4gICAgICAgIGlkOiBjb250ZXh0LmlkLFxuICAgICAgICB1cmk6IGNvbnRleHQudXJpLFxuICAgICAgICB0aXRsZTogY29udGV4dC50aXRsZSxcbiAgICAgICAgc2NvcGU6IGNvbnRleHQuc2NvcGUsXG4gICAgICAgIHBlcm1pc3Npb246IFR5cGVQZXJtaXNzaW9uW1R5cGVQZXJtaXNzaW9uLnJlYWRdXG4gICAgICB9O1xuXG4gICAgICBpZiAodGhpcy5jb250ZXh0cyQudmFsdWUgJiYgdGhpcy5jb250ZXh0cyQudmFsdWUucHVibGljKSB7XG4gICAgICAgIHRoaXMuY29udGV4dHMkLnZhbHVlLnB1YmxpYy5wdXNoKGNvbnRleHRTaW1wbGlmaWUpO1xuICAgICAgICB0aGlzLmNvbnRleHRzJC5uZXh0KHRoaXMuY29udGV4dHMkLnZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZpbmRDb250ZXh0KGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICBpZiAoIWNvbnRleHQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBjb250ZXh0cyA9IHRoaXMuY29udGV4dHMkLnZhbHVlO1xuICAgIGxldCBmb3VuZDtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhjb250ZXh0cykpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gY29udGV4dHNba2V5XTtcbiAgICAgIGZvdW5kID0gdmFsdWUuZmluZChcbiAgICAgICAgKGMpID0+XG4gICAgICAgICAgKGNvbnRleHQuaWQgJiYgYy5pZCA9PT0gY29udGV4dC5pZCkgfHxcbiAgICAgICAgICAoY29udGV4dC51cmkgJiYgYy51cmkgPT09IGNvbnRleHQudXJpKVxuICAgICAgKTtcbiAgICAgIGlmIChmb3VuZCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZm91bmQ7XG4gIH1cbn1cbiJdfQ==