@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.
- package/esm2020/igo2-context.mjs +4 -4
- package/esm2020/lib/context-import-export/context-import-export/context-import-export.component.mjs +228 -228
- package/esm2020/lib/context-import-export/context-import-export.module.mjs +84 -84
- package/esm2020/lib/context-import-export/index.mjs +2 -2
- package/esm2020/lib/context-import-export/shared/context-export.errors.mjs +14 -14
- package/esm2020/lib/context-import-export/shared/context-export.interface.mjs +1 -1
- package/esm2020/lib/context-import-export/shared/context-export.service.mjs +37 -37
- package/esm2020/lib/context-import-export/shared/context-export.utils.mjs +23 -23
- package/esm2020/lib/context-import-export/shared/context-import.errors.mjs +32 -32
- package/esm2020/lib/context-import-export/shared/context-import.service.mjs +78 -78
- package/esm2020/lib/context-import-export/shared/context-import.utils.mjs +157 -157
- package/esm2020/lib/context-import-export/shared/index.mjs +7 -7
- package/esm2020/lib/context-manager/context-edit/context-edit-binding.directive.mjs +53 -53
- package/esm2020/lib/context-manager/context-edit/context-edit.component.mjs +45 -45
- package/esm2020/lib/context-manager/context-edit/index.mjs +2 -2
- package/esm2020/lib/context-manager/context-form/context-form.component.mjs +146 -146
- package/esm2020/lib/context-manager/context-form/index.mjs +1 -1
- package/esm2020/lib/context-manager/context-item/context-item.component.mjs +244 -244
- package/esm2020/lib/context-manager/context-item/index.mjs +1 -1
- package/esm2020/lib/context-manager/context-list/context-list-binding.directive.mjs +259 -259
- package/esm2020/lib/context-manager/context-list/context-list.component.mjs +591 -591
- package/esm2020/lib/context-manager/context-list/context-list.enum.mjs +6 -6
- package/esm2020/lib/context-manager/context-list/index.mjs +2 -2
- package/esm2020/lib/context-manager/context-manager.module.mjs +161 -161
- package/esm2020/lib/context-manager/context-permissions/context-permissions-binding.directive.mjs +115 -115
- package/esm2020/lib/context-manager/context-permissions/context-permissions.component.mjs +305 -305
- package/esm2020/lib/context-manager/context-permissions/index.mjs +2 -2
- package/esm2020/lib/context-manager/index.mjs +6 -6
- package/esm2020/lib/context-manager/shared/context.enum.mjs +12 -12
- package/esm2020/lib/context-manager/shared/context.interface.mjs +1 -1
- package/esm2020/lib/context-manager/shared/context.service.mjs +628 -628
- package/esm2020/lib/context-manager/shared/index.mjs +5 -5
- package/esm2020/lib/context-manager/shared/layer-context.directive.mjs +145 -145
- package/esm2020/lib/context-manager/shared/map-context.directive.mjs +69 -69
- package/esm2020/lib/context-map-button/bookmark-button/bookmark-button.component.mjs +71 -71
- package/esm2020/lib/context-map-button/bookmark-button/bookmark-dialog.component.mjs +49 -49
- package/esm2020/lib/context-map-button/bookmark-button/index.mjs +2 -2
- package/esm2020/lib/context-map-button/context-map-button.module.mjs +95 -95
- package/esm2020/lib/context-map-button/index.mjs +3 -3
- package/esm2020/lib/context-map-button/poi-button/index.mjs +3 -3
- package/esm2020/lib/context-map-button/poi-button/poi-button.component.mjs +170 -170
- package/esm2020/lib/context-map-button/poi-button/poi-dialog.component.mjs +49 -49
- package/esm2020/lib/context-map-button/poi-button/shared/index.mjs +2 -2
- package/esm2020/lib/context-map-button/poi-button/shared/poi.interface.mjs +1 -1
- package/esm2020/lib/context-map-button/poi-button/shared/poi.service.mjs +32 -32
- package/esm2020/lib/context-map-button/user-button/index.mjs +2 -2
- package/esm2020/lib/context-map-button/user-button/user-button.animation.mjs +16 -16
- package/esm2020/lib/context-map-button/user-button/user-button.component.mjs +103 -103
- package/esm2020/lib/context-map-button/user-button/user-dialog.component.mjs +65 -65
- package/esm2020/lib/context.module.mjs +44 -44
- package/esm2020/lib/share-map/index.mjs +4 -4
- package/esm2020/lib/share-map/share-map/share-map-api.component.mjs +180 -180
- package/esm2020/lib/share-map/share-map/share-map-url.component.mjs +242 -242
- package/esm2020/lib/share-map/share-map/share-map.component.mjs +56 -56
- package/esm2020/lib/share-map/share-map.module.mjs +66 -66
- package/esm2020/lib/share-map/shared/index.mjs +1 -1
- package/esm2020/lib/share-map/shared/share-map.service.mjs +209 -209
- package/esm2020/lib/sidenav/index.mjs +1 -1
- package/esm2020/lib/sidenav/sidenav.component.mjs +169 -169
- package/esm2020/lib/sidenav/sidenav.module.mjs +60 -60
- package/esm2020/public_api.mjs +14 -14
- package/fesm2015/igo2-context.mjs +5035 -5035
- package/fesm2020/igo2-context.mjs +4684 -4684
- package/index.d.ts +5 -5
- package/lib/context-import-export/context-import-export/context-import-export.component.d.ts +45 -45
- package/lib/context-import-export/context-import-export.module.d.ts +23 -23
- package/lib/context-import-export/index.d.ts +2 -2
- package/lib/context-import-export/shared/context-export.errors.d.ts +8 -8
- package/lib/context-import-export/shared/context-export.interface.d.ts +5 -5
- package/lib/context-import-export/shared/context-export.service.d.ts +10 -10
- package/lib/context-import-export/shared/context-export.utils.d.ts +4 -4
- package/lib/context-import-export/shared/context-import.errors.d.ts +17 -17
- package/lib/context-import-export/shared/context-import.service.d.ts +18 -18
- package/lib/context-import-export/shared/context-import.utils.d.ts +17 -17
- package/lib/context-import-export/shared/index.d.ts +7 -7
- package/lib/context-manager/context-edit/context-edit-binding.directive.d.ts +21 -21
- package/lib/context-manager/context-edit/context-edit.component.d.ts +14 -14
- package/lib/context-manager/context-edit/index.d.ts +2 -2
- package/lib/context-manager/context-form/context-form.component.d.ts +31 -31
- package/lib/context-manager/context-form/index.d.ts +1 -1
- package/lib/context-manager/context-item/context-item.component.d.ts +32 -32
- package/lib/context-manager/context-item/index.d.ts +1 -1
- package/lib/context-manager/context-list/context-list-binding.directive.d.ts +46 -46
- package/lib/context-manager/context-list/context-list.component.d.ts +93 -93
- package/lib/context-manager/context-list/context-list.enum.d.ts +5 -5
- package/lib/context-manager/context-list/index.d.ts +2 -2
- package/lib/context-manager/context-manager.module.d.ts +37 -37
- package/lib/context-manager/context-permissions/context-permissions-binding.directive.d.ts +23 -23
- package/lib/context-manager/context-permissions/context-permissions.component.d.ts +40 -40
- package/lib/context-manager/context-permissions/index.d.ts +2 -2
- package/lib/context-manager/index.d.ts +6 -6
- package/lib/context-manager/shared/context.enum.d.ts +10 -10
- package/lib/context-manager/shared/context.interface.d.ts +75 -75
- package/lib/context-manager/shared/context.service.d.ts +75 -75
- package/lib/context-manager/shared/index.d.ts +5 -5
- package/lib/context-manager/shared/layer-context.directive.d.ts +27 -27
- package/lib/context-manager/shared/map-context.directive.d.ts +19 -19
- package/lib/context-map-button/bookmark-button/bookmark-button.component.d.ts +21 -21
- package/lib/context-map-button/bookmark-button/bookmark-dialog.component.d.ts +9 -9
- package/lib/context-map-button/bookmark-button/index.d.ts +2 -2
- package/lib/context-map-button/context-map-button.module.d.ts +27 -27
- package/lib/context-map-button/index.d.ts +3 -3
- package/lib/context-map-button/poi-button/index.d.ts +3 -3
- package/lib/context-map-button/poi-button/poi-button.component.d.ts +34 -34
- package/lib/context-map-button/poi-button/poi-dialog.component.d.ts +9 -9
- package/lib/context-map-button/poi-button/shared/index.d.ts +2 -2
- package/lib/context-map-button/poi-button/shared/poi.interface.d.ts +7 -7
- package/lib/context-map-button/poi-button/shared/poi.service.d.ts +16 -16
- package/lib/context-map-button/user-button/index.d.ts +2 -2
- package/lib/context-map-button/user-button/user-button.animation.d.ts +2 -2
- package/lib/context-map-button/user-button/user-button.component.d.ts +25 -25
- package/lib/context-map-button/user-button/user-dialog.component.d.ts +15 -15
- package/lib/context.module.d.ts +16 -16
- package/lib/share-map/index.d.ts +4 -4
- package/lib/share-map/share-map/share-map-api.component.d.ts +27 -27
- package/lib/share-map/share-map/share-map-url.component.d.ts +26 -26
- package/lib/share-map/share-map/share-map.component.d.ts +11 -11
- package/lib/share-map/share-map.module.d.ts +21 -21
- package/lib/share-map/shared/index.d.ts +1 -1
- package/lib/share-map/shared/share-map.service.d.ts +17 -17
- package/lib/sidenav/index.d.ts +1 -1
- package/lib/sidenav/sidenav.component.d.ts +35 -35
- package/lib/sidenav/sidenav.module.d.ts +18 -18
- package/package.json +6 -6
- 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==
|