@yuuvis/client-core 0.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/README.md +111 -0
  2. package/esm2022/index.mjs +65 -0
  3. package/esm2022/lib/client-core.module.mjs +117 -0
  4. package/esm2022/lib/client-core.shared.module.mjs +18 -0
  5. package/esm2022/lib/common/pipes/filesize.pipe.mjs +37 -0
  6. package/esm2022/lib/common/pipes/index.mjs +6 -0
  7. package/esm2022/lib/common/pipes/keys.pipe.mjs +17 -0
  8. package/esm2022/lib/common/pipes/locale-date.pipe.mjs +45 -0
  9. package/esm2022/lib/common/pipes/locale-number.pipe.mjs +115 -0
  10. package/esm2022/lib/common/pipes/safe-html.pipe.mjs +44 -0
  11. package/esm2022/lib/common/services/native-notifications.interface.mjs +2 -0
  12. package/esm2022/lib/common/services/native-notifications.mjs +40 -0
  13. package/esm2022/lib/model/dms-object.interface.mjs +2 -0
  14. package/esm2022/lib/model/dms-object.model.mjs +79 -0
  15. package/esm2022/lib/model/object-flavor.interface.mjs +2 -0
  16. package/esm2022/lib/model/range-value.interface.mjs +2 -0
  17. package/esm2022/lib/model/yuv-error.model.mjs +37 -0
  18. package/esm2022/lib/model/yuv-user.model.mjs +38 -0
  19. package/esm2022/lib/service/audit/audit.interface.mjs +2 -0
  20. package/esm2022/lib/service/audit/audit.service.mjs +135 -0
  21. package/esm2022/lib/service/auth/auth.interceptor.mjs +50 -0
  22. package/esm2022/lib/service/auth/auth.interface.mjs +7 -0
  23. package/esm2022/lib/service/auth/auth.service.mjs +130 -0
  24. package/esm2022/lib/service/auth/oidc.service.mjs +81 -0
  25. package/esm2022/lib/service/backend/api.enum.mjs +11 -0
  26. package/esm2022/lib/service/backend/backend.interface.mjs +2 -0
  27. package/esm2022/lib/service/backend/backend.service.mjs +206 -0
  28. package/esm2022/lib/service/bpm/bpm.interface.mjs +8 -0
  29. package/esm2022/lib/service/bpm/bpm.service.mjs +51 -0
  30. package/esm2022/lib/service/cache/app-cache.service.mjs +51 -0
  31. package/esm2022/lib/service/catalog/catalog.interface.mjs +2 -0
  32. package/esm2022/lib/service/catalog/catalog.service.mjs +13 -0
  33. package/esm2022/lib/service/clipboard/clipboard.interface.mjs +2 -0
  34. package/esm2022/lib/service/clipboard/clipboard.service.mjs +90 -0
  35. package/esm2022/lib/service/config/config.interface.mjs +6 -0
  36. package/esm2022/lib/service/config/config.service.mjs +115 -0
  37. package/esm2022/lib/service/config/core-config.mjs +20 -0
  38. package/esm2022/lib/service/config/core-config.tokens.mjs +9 -0
  39. package/esm2022/lib/service/connection/connection.service.mjs +36 -0
  40. package/esm2022/lib/service/connection/offline.interceptor.mjs +28 -0
  41. package/esm2022/lib/service/core-init/core-init.service.mjs +29 -0
  42. package/esm2022/lib/service/core-init/missing-translation-handler.mjs +10 -0
  43. package/esm2022/lib/service/core-init/translate-json-loader.mjs +117 -0
  44. package/esm2022/lib/service/device/device.interface.mjs +6 -0
  45. package/esm2022/lib/service/device/device.service.mjs +144 -0
  46. package/esm2022/lib/service/dms/dms.service.interface.mjs +2 -0
  47. package/esm2022/lib/service/dms/dms.service.mjs +440 -0
  48. package/esm2022/lib/service/event/event.interface.mjs +2 -0
  49. package/esm2022/lib/service/event/event.service.mjs +38 -0
  50. package/esm2022/lib/service/event/events.mjs +14 -0
  51. package/esm2022/lib/service/idm/idm.interface.mjs +2 -0
  52. package/esm2022/lib/service/idm/idm.service.mjs +34 -0
  53. package/esm2022/lib/service/logger/logger-console.service.mjs +73 -0
  54. package/esm2022/lib/service/logger/logger.interface.mjs +2 -0
  55. package/esm2022/lib/service/logger/logger.mjs +27 -0
  56. package/esm2022/lib/service/notification/notification.service.mjs +131 -0
  57. package/esm2022/lib/service/object-config/object-config.interface.mjs +2 -0
  58. package/esm2022/lib/service/object-config/object-config.service.mjs +229 -0
  59. package/esm2022/lib/service/pending-changes/pending-changes-component.interface.mjs +5 -0
  60. package/esm2022/lib/service/pending-changes/pending-changes-guard.service.mjs +25 -0
  61. package/esm2022/lib/service/pending-changes/pending-changes.service.mjs +123 -0
  62. package/esm2022/lib/service/prediction/prediction.interface.mjs +2 -0
  63. package/esm2022/lib/service/prediction/prediction.service.mjs +60 -0
  64. package/esm2022/lib/service/search/search.service.interface.mjs +39 -0
  65. package/esm2022/lib/service/search/search.service.mjs +178 -0
  66. package/esm2022/lib/service/session-storage/session-storage.service.mjs +50 -0
  67. package/esm2022/lib/service/system/object-form.interface.mjs +2 -0
  68. package/esm2022/lib/service/system/system.enum.mjs +179 -0
  69. package/esm2022/lib/service/system/system.interface.mjs +2 -0
  70. package/esm2022/lib/service/system/system.service.mjs +597 -0
  71. package/esm2022/lib/service/upload/upload.interface.mjs +2 -0
  72. package/esm2022/lib/service/upload/upload.service.mjs +228 -0
  73. package/esm2022/lib/service/user/user.service.mjs +211 -0
  74. package/esm2022/lib/util/utils.helper.enum.mjs +15 -0
  75. package/esm2022/lib/util/utils.mjs +373 -0
  76. package/esm2022/yuuvis-client-core.mjs +5 -0
  77. package/fesm2022/yuuvis-client-core.mjs +4775 -0
  78. package/fesm2022/yuuvis-client-core.mjs.map +1 -0
  79. package/index.d.ts +61 -0
  80. package/lib/client-core.module.d.ts +20 -0
  81. package/lib/client-core.shared.module.d.ts +10 -0
  82. package/lib/common/pipes/filesize.pipe.d.ts +18 -0
  83. package/lib/common/pipes/index.d.ts +5 -0
  84. package/lib/common/pipes/keys.pipe.d.ts +10 -0
  85. package/lib/common/pipes/locale-date.pipe.d.ts +12 -0
  86. package/lib/common/pipes/locale-number.pipe.d.ts +47 -0
  87. package/lib/common/pipes/safe-html.pipe.d.ts +28 -0
  88. package/lib/common/services/native-notifications.d.ts +8 -0
  89. package/lib/common/services/native-notifications.interface.d.ts +5 -0
  90. package/lib/model/dms-object.interface.d.ts +16 -0
  91. package/lib/model/dms-object.model.d.ts +26 -0
  92. package/lib/model/object-flavor.interface.d.ts +30 -0
  93. package/lib/model/range-value.interface.d.ts +9 -0
  94. package/lib/model/yuv-error.model.d.ts +18 -0
  95. package/lib/model/yuv-user.model.d.ts +44 -0
  96. package/lib/service/audit/audit.interface.d.ts +47 -0
  97. package/lib/service/audit/audit.service.d.ts +35 -0
  98. package/lib/service/auth/auth.interceptor.d.ts +12 -0
  99. package/lib/service/auth/auth.interface.d.ts +34 -0
  100. package/lib/service/auth/auth.service.d.ts +50 -0
  101. package/lib/service/auth/oidc.service.d.ts +16 -0
  102. package/lib/service/backend/api.enum.d.ts +7 -0
  103. package/lib/service/backend/backend.interface.d.ts +29 -0
  104. package/lib/service/backend/backend.service.d.ts +118 -0
  105. package/lib/service/bpm/bpm.interface.d.ts +86 -0
  106. package/lib/service/bpm/bpm.service.d.ts +19 -0
  107. package/lib/service/cache/app-cache.service.d.ts +18 -0
  108. package/lib/service/catalog/catalog.interface.d.ts +12 -0
  109. package/lib/service/catalog/catalog.service.d.ts +5 -0
  110. package/lib/service/clipboard/clipboard.interface.d.ts +11 -0
  111. package/lib/service/clipboard/clipboard.service.d.ts +23 -0
  112. package/lib/service/config/config.interface.d.ts +34 -0
  113. package/lib/service/config/config.service.d.ts +45 -0
  114. package/lib/service/config/core-config.d.ts +14 -0
  115. package/lib/service/config/core-config.tokens.d.ts +7 -0
  116. package/lib/service/connection/connection.service.d.ts +25 -0
  117. package/lib/service/connection/offline.interceptor.d.ts +15 -0
  118. package/lib/service/core-init/core-init.service.d.ts +11 -0
  119. package/lib/service/core-init/missing-translation-handler.d.ts +8 -0
  120. package/lib/service/core-init/translate-json-loader.d.ts +20 -0
  121. package/lib/service/device/device.interface.d.ts +15 -0
  122. package/lib/service/device/device.service.d.ts +54 -0
  123. package/lib/service/dms/dms.service.d.ts +153 -0
  124. package/lib/service/dms/dms.service.interface.d.ts +59 -0
  125. package/lib/service/event/event.interface.d.ts +13 -0
  126. package/lib/service/event/event.service.d.ts +23 -0
  127. package/lib/service/event/events.d.ts +12 -0
  128. package/lib/service/idm/idm.interface.d.ts +5 -0
  129. package/lib/service/idm/idm.service.d.ts +9 -0
  130. package/lib/service/logger/logger-console.service.d.ts +20 -0
  131. package/lib/service/logger/logger.d.ts +17 -0
  132. package/lib/service/logger/logger.interface.d.ts +10 -0
  133. package/lib/service/notification/notification.service.d.ts +71 -0
  134. package/lib/service/object-config/object-config.interface.d.ts +62 -0
  135. package/lib/service/object-config/object-config.service.d.ts +38 -0
  136. package/lib/service/pending-changes/pending-changes-component.interface.d.ts +6 -0
  137. package/lib/service/pending-changes/pending-changes-guard.service.d.ts +14 -0
  138. package/lib/service/pending-changes/pending-changes.service.d.ts +57 -0
  139. package/lib/service/prediction/prediction.interface.d.ts +18 -0
  140. package/lib/service/prediction/prediction.service.d.ts +15 -0
  141. package/lib/service/search/search.service.d.ts +46 -0
  142. package/lib/service/search/search.service.interface.d.ts +119 -0
  143. package/lib/service/session-storage/session-storage.service.d.ts +15 -0
  144. package/lib/service/system/object-form.interface.d.ts +46 -0
  145. package/lib/service/system/system.enum.d.ts +141 -0
  146. package/lib/service/system/system.interface.d.ts +146 -0
  147. package/lib/service/system/system.service.d.ts +168 -0
  148. package/lib/service/upload/upload.interface.d.ts +55 -0
  149. package/lib/service/upload/upload.service.d.ts +34 -0
  150. package/lib/service/user/user.service.d.ts +69 -0
  151. package/lib/util/utils.d.ts +118 -0
  152. package/lib/util/utils.helper.enum.d.ts +13 -0
  153. package/package.json +33 -0
@@ -0,0 +1,597 @@
1
+ import { inject, Injectable } from '@angular/core';
2
+ import { forkJoin, of, ReplaySubject } from 'rxjs';
3
+ import { catchError, map, switchMap, tap } from 'rxjs/operators';
4
+ import { Utils } from '../../util/utils';
5
+ import { ApiBase } from '../backend/api.enum';
6
+ import { BackendService } from '../backend/backend.service';
7
+ import { AppCacheService } from '../cache/app-cache.service';
8
+ import { Logger } from '../logger/logger';
9
+ import { BaseObjectTypeField, Classification, ContentStreamAllowed, InternalFieldType, ObjectTypeClassification, SystemType } from './system.enum';
10
+ import * as i0 from "@angular/core";
11
+ /**
12
+ * Providing system definitions.
13
+ */
14
+ export class SystemService {
15
+ constructor() {
16
+ this.#backend = inject(BackendService);
17
+ this.#appCache = inject(AppCacheService);
18
+ this.#logger = inject(Logger);
19
+ this.#STORAGE_KEY = 'yuv.core.system.definition';
20
+ this.#STORAGE_KEY_AUTH_DATA = 'yuv.core.auth.data';
21
+ // cached icons to avoid backend calls (session cache)
22
+ this.#iconCache = {};
23
+ this.#resolvedClassificationsCache = {};
24
+ this.#systemSource = new ReplaySubject();
25
+ this.system$ = this.#systemSource.asObservable();
26
+ // cache for resolved visible tags because they are used in lists and therefore should not be re-evaluated all the time
27
+ this.#visibleTagsCache = {};
28
+ }
29
+ #backend;
30
+ #appCache;
31
+ #logger;
32
+ #STORAGE_KEY;
33
+ #STORAGE_KEY_AUTH_DATA;
34
+ // cached icons to avoid backend calls (session cache)
35
+ #iconCache;
36
+ #resolvedClassificationsCache;
37
+ #systemSource;
38
+ // cache for resolved visible tags because they are used in lists and therefore should not be re-evaluated all the time
39
+ #visibleTagsCache;
40
+ #permissions;
41
+ /**
42
+ * Get all object types
43
+ * @param withLabels Whether or not to also add the types labels
44
+ */
45
+ getObjectTypes(withLabels, situation) {
46
+ // Filter by user permissions based on situation
47
+ const objectTypes = this.#filterByPermissions([...this.system.objectTypes, ...this.system.secondaryObjectTypes.map((sot) => this.#sotToGenericType(sot))], situation);
48
+ return withLabels ? objectTypes.map((t) => ({ ...t, label: this.getLocalizedResource(`${t.id}_label`) })) : objectTypes;
49
+ }
50
+ #sotToGenericType(sot) {
51
+ return {
52
+ ...sot,
53
+ isFolder: false,
54
+ creatable: true,
55
+ secondaryObjectTypes: [],
56
+ isSot: true
57
+ };
58
+ }
59
+ /**
60
+ * Get all secondary object types
61
+ * @param withLabels Whether or not to also add the types labels
62
+ */
63
+ getSecondaryObjectTypes(withLabels, situation) {
64
+ const sots = this.#filterByPermissions(this.system.secondaryObjectTypes.map((sot) => this.#sotToGenericType(sot)), situation);
65
+ return ((withLabels ? sots.map((t) => ({ ...t, label: this.getLocalizedResource(`${t.id}_label`) })) : sots)
66
+ // ignore
67
+ .filter((t) => t.id !== t.baseId && !t.id.startsWith('system:') && t.id !== 'appClientsystem:leadingType'));
68
+ }
69
+ #filterByPermissions(types, situation) {
70
+ if (!situation)
71
+ return types;
72
+ const allowedTypes = situation === 'search' ? this.#permissions.searchableObjectTypes : this.#permissions.createableObjectTypes;
73
+ return types.filter((t) => allowedTypes.includes(t.id));
74
+ }
75
+ /**
76
+ * Get a particular object type
77
+ * @param objectTypeId ID of the object type
78
+ * @param withLabel Whether or not to also add the types label
79
+ */
80
+ getObjectType(objectTypeId, withLabel) {
81
+ let objectType = objectTypeId === SystemType.OBJECT ? this.getBaseType() : this.system.objectTypes.find((ot) => ot.id === objectTypeId);
82
+ if (objectType && withLabel) {
83
+ objectType.label = this.getLocalizedResource(`${objectType.id}_label`) || objectTypeId;
84
+ }
85
+ if (!objectType) {
86
+ // no 'real' object type found. Try to find a matching SOT and treat it like a real type
87
+ // by filling up the missing properties
88
+ const sot = this.getSecondaryObjectType(objectTypeId, withLabel);
89
+ if (sot) {
90
+ objectType = this.#sotToGenericType(sot);
91
+ }
92
+ }
93
+ return objectType;
94
+ }
95
+ /**
96
+ * Get a particular secondary object type
97
+ * @param objectTypeId ID of the object type
98
+ * @param withLabel Whether or not to also add the types label
99
+ */
100
+ getSecondaryObjectType(objectTypeId, withLabel) {
101
+ const objectType = this.system.secondaryObjectTypes.find((ot) => ot.id === objectTypeId);
102
+ if (objectType && withLabel) {
103
+ objectType.label = this.getLocalizedResource(`${objectType.id}_label`) || objectType.id;
104
+ }
105
+ return objectType;
106
+ }
107
+ /**
108
+ * Get the base document type all documents belong to
109
+ * @param withLabel Whether or not to also add the types label
110
+ */
111
+ getBaseDocumentType(withLabel) {
112
+ return this.getObjectType(SystemType.DOCUMENT, withLabel);
113
+ }
114
+ /**
115
+ * Get the base folder type all folders belong to
116
+ * @param withLabel Whether or not to also add the types label
117
+ */
118
+ getBaseFolderType(withLabel) {
119
+ return this.getObjectType(SystemType.FOLDER, withLabel);
120
+ }
121
+ /**
122
+ * Get the base object type all dms objects belong to
123
+ */
124
+ getBaseType() {
125
+ const sysFolder = this.getBaseFolderType();
126
+ const sysDocument = this.getBaseDocumentType();
127
+ // base type contains only fields that are shared by base document and base folder ...
128
+ const folderTypeFieldIDs = sysFolder.fields.map((f) => f.id);
129
+ const baseTypeFields = sysDocument.fields.filter((f) => folderTypeFieldIDs.includes(f.id));
130
+ return {
131
+ id: SystemType.OBJECT,
132
+ creatable: false,
133
+ isFolder: false,
134
+ secondaryObjectTypes: [],
135
+ fields: baseTypeFields
136
+ // rawFields: baseTypeFields
137
+ };
138
+ }
139
+ /**
140
+ * Get the resolved object type with all fields ( including fields from related secondary types )
141
+ */
142
+ getResolvedType(objectTypeId) {
143
+ const abstractTypes = Object.values(SystemType);
144
+ if (!objectTypeId || abstractTypes.includes(objectTypeId)) {
145
+ const baseType = this.getBaseType();
146
+ return { id: baseType.id, fields: baseType.fields };
147
+ }
148
+ const ot = this.getObjectType(objectTypeId);
149
+ if (!ot) {
150
+ const sot = this.getSecondaryObjectType(objectTypeId) || { id: objectTypeId, fields: [] };
151
+ const baseType = this.getBaseType();
152
+ return {
153
+ id: sot.id,
154
+ fields: [...sot.fields, ...baseType.fields]
155
+ };
156
+ }
157
+ return {
158
+ id: ot.id,
159
+ fields: ot.fields
160
+ };
161
+ }
162
+ /**
163
+ * Get the resolved object tags
164
+ */
165
+ getResolvedTags(objectTypeId) {
166
+ const vTags = this.getVisibleTags(objectTypeId);
167
+ return Object.keys(vTags).map((k) => ({
168
+ id: objectTypeId,
169
+ tagName: k,
170
+ tagValues: vTags[k],
171
+ fields: this.getBaseType().fields.filter((f) => f.id === BaseObjectTypeField.TAGS)
172
+ }));
173
+ }
174
+ /**
175
+ * Get a list of classifications for a given object type including the
176
+ * classifications of its static secondary object types
177
+ * @param objectTypeId ID of the object type
178
+ */
179
+ getResolvedClassifications(objectTypeId) {
180
+ return this.#resolvedClassificationsCache[objectTypeId] || this.#resolveClassifications(objectTypeId);
181
+ }
182
+ #resolveClassifications(objectTypeId) {
183
+ let classifications = [];
184
+ const ot = this.getObjectType(objectTypeId);
185
+ if (ot) {
186
+ classifications = ot.classification || [];
187
+ const staticSOTs = ot.secondaryObjectTypes ? ot.secondaryObjectTypes.filter((sot) => sot.static).map((sot) => sot.id) : [];
188
+ staticSOTs.forEach((id) => {
189
+ const sot = this.getSecondaryObjectType(id);
190
+ classifications = sot?.classification
191
+ ? [
192
+ ...classifications,
193
+ ...sot.classification.filter((c) => {
194
+ // also filter classifications that should not be inherited
195
+ return c !== ObjectTypeClassification.CREATE_FALSE && c !== ObjectTypeClassification.SEARCH_FALSE;
196
+ })
197
+ ]
198
+ : classifications;
199
+ });
200
+ this.#resolvedClassificationsCache[objectTypeId] = classifications;
201
+ }
202
+ return classifications;
203
+ }
204
+ /**
205
+ * Visible tags are defined by a classification on the object type (e.g. 'tag[tenkolibri:process,1,2,3]').
206
+ *
207
+ * The example will only return tags with the name 'tenkolibri:process'
208
+ * and values of either 1, 2 or 3. All other tags will be ignored.
209
+ *
210
+ * @param objectTypeId ID of the object type to get the visible tags for
211
+ * @returns object where the property name is the name of the tag and its value are the visible values
212
+ * for that tag (if values is emoty all values are allowed)
213
+ */
214
+ getVisibleTags(objectTypeId) {
215
+ return this.#visibleTagsCache[objectTypeId] || this.fetchVisibleTags(objectTypeId);
216
+ }
217
+ fetchVisibleTags(objectTypeId) {
218
+ const ot = this.getObjectType(objectTypeId) || this.getSecondaryObjectType(objectTypeId);
219
+ const tagClassifications = this.getResolvedClassifications(objectTypeId).filter((t) => t.startsWith('tag['));
220
+ const parentType = ot && ot.id;
221
+ const to = {};
222
+ (tagClassifications || []).forEach((tag) => {
223
+ const m = tag.match(/\[(.*)\]/i)[1].split(',');
224
+ const tagName = m.splice(0, 1)[0];
225
+ const tagValues = m.map((v) => parseInt(v.trim()));
226
+ to[tagName] = tagValues;
227
+ });
228
+ this.#visibleTagsCache[objectTypeId] = parentType ? { ...this.getVisibleTags(parentType), ...to } : to;
229
+ return this.#visibleTagsCache[objectTypeId];
230
+ }
231
+ filterVisibleTags(objectTypeId, tagsValue) {
232
+ if (!tagsValue)
233
+ return [];
234
+ const vTags = this.getVisibleTags(objectTypeId);
235
+ // Tag value looks like this: [tagName: string, state: number, date: Date, traceId: string]
236
+ return tagsValue.filter((v) => !!vTags[v[0]] && vTags[v[0]].includes(v[1]));
237
+ }
238
+ /**
239
+ * Get the icon for an object type. This will return an SVG as a string.
240
+ * @param objectTypeId ID of the object type
241
+ * @param fallback ID of a fallback icon that should be used if the given object type has no icon yet
242
+ */
243
+ getObjectTypeIcon(objectTypeId, fallback) {
244
+ if (this.#iconCache[objectTypeId] && this.#iconCache[objectTypeId].icon) {
245
+ return of(this.#iconCache[objectTypeId].icon);
246
+ }
247
+ else {
248
+ const iconUri = this.getObjectTypeIconUri(objectTypeId, fallback);
249
+ return this.#backend.get(iconUri).pipe(tap((icon) => (this.#iconCache[objectTypeId] = { uri: iconUri, icon })));
250
+ }
251
+ }
252
+ /**
253
+ * Get the URI of an object type icon.
254
+ * @param objectTypeId ID of the object type
255
+ * @param fallback ID of a fallback icon that should be used if the given object type has no icon yet
256
+ */
257
+ getObjectTypeIconUri(objectTypeId, fallback) {
258
+ if (this.#iconCache[objectTypeId]) {
259
+ return this.#iconCache[objectTypeId].uri;
260
+ }
261
+ else {
262
+ const ci = this.#getIconFromClassification(objectTypeId);
263
+ const fb = this.getFallbackIcon(objectTypeId, fallback);
264
+ const uri = `/resources/icons/${encodeURIComponent(ci || objectTypeId)}${fb ? `?fallback=${encodeURIComponent(fb)}` : ''}`;
265
+ this.#iconCache[objectTypeId] = { uri: `${this.#backend.getApiBase(ApiBase.apiWeb)}${uri}` };
266
+ return this.#iconCache[objectTypeId].uri;
267
+ }
268
+ }
269
+ getFallbackIcon(objectTypeId, fallback) {
270
+ const ot = this.getObjectType(objectTypeId);
271
+ if (ot && !fallback) {
272
+ // add default fallbacks for system:document and system:folder if now other fallback has been provided
273
+ fallback = ot.isFolder ? 'system:folder' : 'system:document';
274
+ // if (this.isFloatingObjectType(ot)) {
275
+ // // types that do not have no object type assigned to them (primary FSOTs)
276
+ // fallback = 'system:dlm';
277
+ // }
278
+ }
279
+ return fallback;
280
+ }
281
+ #getIconFromClassification(objectTypeId) {
282
+ const ce = this.getClassifications(this.getResolvedClassifications(objectTypeId));
283
+ return ce.has(ObjectTypeClassification.OBJECT_TYPE_ICON) ? ce.get(ObjectTypeClassification.OBJECT_TYPE_ICON).options[0] : null;
284
+ }
285
+ getLocalizedResource(key) {
286
+ return this.system.i18n[key];
287
+ }
288
+ getLocalizedLabel(id) {
289
+ return this.getLocalizedResource(`${id}_label`);
290
+ }
291
+ getLocalizedDescription(id) {
292
+ return this.getLocalizedResource(`${id}_description`);
293
+ }
294
+ /**
295
+ * Determine whether or not the given object type field is a system field
296
+ * @param field Object type field to be checked
297
+ */
298
+ isSystemProperty(field) {
299
+ return field.id.startsWith('system:');
300
+ }
301
+ /**
302
+ * Fetches the backends system definition and updates system$ Observable.
303
+ * Subscribe to the system$ observable instead of calling this function, otherwise you'll trigger fetching the
304
+ * system definition every time.
305
+ *
306
+ * @param user The user to load the system definition for
307
+ */
308
+ getSystemDefinition(authData) {
309
+ // TODO: Supposed to return 304 if nothing changes
310
+ return this.#fetchSystemDefinition(authData);
311
+ // TODO: remove when 304 is there???
312
+ // // try to fetch system definition from cache first
313
+ // return this.appCache.getItem(this.STORAGE_KEY).pipe(
314
+ // switchMap(res => {
315
+ // if (res) {
316
+ // // check if the system definition from the cache is up to date
317
+ // this.system = res;
318
+ // this.systemSource.next(this.system);
319
+ // return of(true);
320
+ // } else {
321
+ // // nothing cached so far
322
+ // return this.fetchSystemDefinition();
323
+ // }
324
+ // })
325
+ // );
326
+ }
327
+ /**
328
+ * Actually fetch the system definition from the backend.
329
+ * @param user User to fetch definition for
330
+ */
331
+ #fetchSystemDefinition(authData) {
332
+ return (authData ? of(authData) : this.#appCache.getItem(this.#STORAGE_KEY_AUTH_DATA)).pipe(switchMap((data) => {
333
+ this.updateAuthData(data).subscribe();
334
+ const fetchTasks = [this.#backend.get('/dms/schema/native.json', ApiBase.core), this.#fetchLocalizations()];
335
+ return forkJoin(fetchTasks);
336
+ }), catchError((error) => {
337
+ this.#logger.error('Error fetching recent version of system definition from server.', error);
338
+ this.#systemSource.error('Error fetching recent version of system definition from server.');
339
+ return of(null);
340
+ }), map((data) => {
341
+ if (data?.length) {
342
+ this.setSchema(data[0], data[1]);
343
+ }
344
+ return !!data;
345
+ }));
346
+ }
347
+ setPermissions(p) {
348
+ this.#permissions = p;
349
+ }
350
+ /**
351
+ * Create the schema from the servers schema response
352
+ * @param schemaResponse Response from the backend
353
+ */
354
+ setSchema(schemaResponse, localizedResource = {}) {
355
+ // prepare a quick access object for the fields
356
+ const propertiesQA = {};
357
+ const orgTypeFields = [BaseObjectTypeField.MODIFIED_BY, BaseObjectTypeField.CREATED_BY];
358
+ schemaResponse.propertyDefinition.forEach((p) => {
359
+ p.classifications = p.classification;
360
+ // TODO: Remove once schema supports organization classification for base params
361
+ // map certain fields to organization type (fake it until you make it ;-)
362
+ if (orgTypeFields.includes(p.id)) {
363
+ p.classifications = [Classification.STRING_ORGANIZATION];
364
+ }
365
+ propertiesQA[p.id] = p;
366
+ });
367
+ // prepare a quick access object for object types (including secondary objects)
368
+ const objectTypesQA = {};
369
+ schemaResponse.typeFolderDefinition.forEach((ot) => {
370
+ objectTypesQA[ot.id] = ot;
371
+ });
372
+ schemaResponse.typeDocumentDefinition.forEach((ot) => {
373
+ objectTypesQA[ot.id] = ot;
374
+ });
375
+ schemaResponse.typeSecondaryDefinition.forEach((sot) => {
376
+ objectTypesQA[sot.id] = sot;
377
+ });
378
+ const objectTypes = [
379
+ // folder types
380
+ ...schemaResponse.typeFolderDefinition.map((fd) => ({
381
+ id: fd.id,
382
+ description: fd.description,
383
+ classification: fd.classification,
384
+ baseId: fd.baseId,
385
+ creatable: this.#isCreatable(fd.id),
386
+ contentStreamAllowed: ContentStreamAllowed.NOT_ALLOWED,
387
+ isFolder: true,
388
+ secondaryObjectTypes: fd.secondaryObjectTypeId ? fd.secondaryObjectTypeId.map((t) => ({ id: t.value, static: t.static })) : [],
389
+ fields: this.#resolveObjectTypeFields(fd, propertiesQA, objectTypesQA)
390
+ // rawFields: this.resolveObjectTypeFields(fd, propertiesQA, objectTypesQA, true),
391
+ })),
392
+ // document types
393
+ ...schemaResponse.typeDocumentDefinition.map((dd) => ({
394
+ id: dd.id,
395
+ description: dd.description,
396
+ classification: dd.classification,
397
+ baseId: dd.baseId,
398
+ creatable: this.#isCreatable(dd.id),
399
+ contentStreamAllowed: dd.contentStreamAllowed,
400
+ isFolder: false,
401
+ secondaryObjectTypes: dd.secondaryObjectTypeId ? dd.secondaryObjectTypeId.map((t) => ({ id: t.value, static: t.static })) : [],
402
+ fields: this.#resolveObjectTypeFields(dd, propertiesQA, objectTypesQA)
403
+ // rawFields: this.resolveObjectTypeFields(dd, propertiesQA, objectTypesQA, true),
404
+ }))
405
+ ];
406
+ const secondaryObjectTypes = schemaResponse.typeSecondaryDefinition.map((std) => ({
407
+ id: std.id,
408
+ description: std.description,
409
+ classification: std.classification,
410
+ contentStreamAllowed: std.contentStreamAllowed,
411
+ baseId: std.baseId,
412
+ // TODO: Could a SOT be a folder too?
413
+ isFolder: false,
414
+ fields: this.#resolveObjectTypeFields(std, propertiesQA, objectTypesQA)
415
+ }));
416
+ this.system = {
417
+ version: schemaResponse.version,
418
+ lastModificationDate: schemaResponse.lastModificationDate,
419
+ objectTypes,
420
+ secondaryObjectTypes,
421
+ i18n: localizedResource,
422
+ allFields: propertiesQA
423
+ };
424
+ this.#appCache.setItem(this.#STORAGE_KEY, this.system).subscribe();
425
+ this.#systemSource.next(this.system);
426
+ }
427
+ /**
428
+ * Resolve all the fields for an object type. This also includes secondary object types and the fields inherited from
429
+ * the base type (... and of course the base type (and its secondary object types) of the base type and so on)
430
+ * @param schemaTypeDefinition object type definition from the native schema
431
+ * @param propertiesQA Quick access object of all properties
432
+ * @param objectTypesQA Quick access object of all object types
433
+ * @param raw If set to 'true' only the properties of the object type itself will be returned (without SOTs)
434
+ */
435
+ #resolveObjectTypeFields(schemaTypeDefinition, propertiesQA, objectTypesQA) {
436
+ const objectTypeFieldIDs = schemaTypeDefinition.propertyReference.map((pr) => pr.value);
437
+ if (schemaTypeDefinition.secondaryObjectTypeId) {
438
+ schemaTypeDefinition.secondaryObjectTypeId
439
+ .filter((sot) => sot.static)
440
+ .map((sot) => sot.value)
441
+ .forEach((sotID) => objectTypesQA[sotID].propertyReference.forEach((pr) => objectTypeFieldIDs.push(pr.value)));
442
+ }
443
+ let fields = objectTypeFieldIDs.map((id) => ({
444
+ ...propertiesQA[id],
445
+ _internalType: this.getInternalFormElementType(propertiesQA[id].propertyType, propertiesQA[id].classifications)
446
+ }));
447
+ // also resolve properties of the base type
448
+ if (schemaTypeDefinition.baseId !== schemaTypeDefinition.id && !!objectTypesQA[schemaTypeDefinition.baseId]) {
449
+ fields = fields.concat(this.#resolveObjectTypeFields(objectTypesQA[schemaTypeDefinition.baseId], propertiesQA, objectTypesQA));
450
+ }
451
+ return fields;
452
+ }
453
+ #isCreatable(objectTypeId) {
454
+ return ![SystemType.FOLDER, SystemType.DOCUMENT].includes(objectTypeId);
455
+ }
456
+ /**
457
+ * Fetch a collection of form models.
458
+ * @param objectTypeIDs Object type IDs to fetch form model for
459
+ * @param situation Form situation
460
+ * @returns Object where the object type id is key and the form model is the value
461
+ */
462
+ getObjectTypeForms(objectTypeIDs, situation) {
463
+ return forkJoin(objectTypeIDs.map((o) => this.getObjectTypeForm(o, situation).pipe(catchError((e) => of(null)), map((res) => ({
464
+ id: o,
465
+ formModel: res
466
+ }))))).pipe(map((res) => {
467
+ const resMap = {};
468
+ res.filter((r) => this.#formHasElements(r.formModel)).forEach((r) => (resMap[r.id] = r.formModel));
469
+ return resMap;
470
+ }));
471
+ }
472
+ /**
473
+ * Get the form model of an object type.
474
+ *
475
+ * @param objectTypeId ID of the object type to fetch the form for
476
+ * @param situation The form situation to be fetched
477
+ * @returns Form model
478
+ */
479
+ getObjectTypeForm(objectTypeId, situation) {
480
+ return this.#backend.get(Utils.buildUri(`/dms/forms/${objectTypeId}`, { situation }));
481
+ }
482
+ /**
483
+ * Check whether or not the model has at least one form element. Recursive.
484
+ * @param element Form element to check child elements for
485
+ */
486
+ #formHasElements(element) {
487
+ let hasElement = false;
488
+ element.elements?.forEach((e) => {
489
+ if (!['o2mGroup', 'o2mGroupStack'].includes(e.type)) {
490
+ hasElement = true;
491
+ }
492
+ else if (!hasElement) {
493
+ hasElement = this.#formHasElements(e);
494
+ }
495
+ });
496
+ return hasElement;
497
+ }
498
+ /**
499
+ * Generates an internal type for a given object type field.
500
+ * Adding this to a form element or object type field enables us to render forms
501
+ * based on object type fields in a more performant way. Otherwise we would
502
+ * have to evaluate the conditions for every form element on every digest cycle.
503
+ * @param type propertyType of the ObjectTypeField
504
+ * @param classifications classifications of the ObjectTypeField
505
+ */
506
+ getInternalFormElementType(type, classifications) {
507
+ const _classifications = this.getClassifications(classifications || []);
508
+ if (type === 'string' && _classifications.has(Classification.STRING_REFERENCE)) {
509
+ return InternalFieldType.STRING_REFERENCE;
510
+ }
511
+ else if (type === 'string' && _classifications.has(Classification.STRING_ORGANIZATION)) {
512
+ return InternalFieldType.STRING_ORGANIZATION;
513
+ }
514
+ else if (type === 'string' && _classifications.has(Classification.STRING_ORGANIZATION_SET)) {
515
+ return InternalFieldType.STRING_ORGANIZATION_SET;
516
+ }
517
+ else if (type === 'string' && _classifications.has(Classification.STRING_CATALOG)) {
518
+ return InternalFieldType.STRING_CATALOG;
519
+ }
520
+ else if (type === 'boolean' && _classifications.has(Classification.BOOLEAN_SWITCH)) {
521
+ return InternalFieldType.BOOLEAN_SWITCH;
522
+ }
523
+ else if (type === 'string' &&
524
+ (_classifications.has(Classification.STRING_CATALOG_DYNAMIC) || _classifications.has(Classification.STRING_CATALOG_CUSTOM))) {
525
+ return InternalFieldType.STRING_DYNAMIC_CATALOG;
526
+ }
527
+ else {
528
+ // if there are no matching conditions just return the original type
529
+ return type;
530
+ }
531
+ }
532
+ getObjectTypeField(id) {
533
+ const f = this.system?.allFields[id];
534
+ return f ? { ...f, _internalType: this.getInternalFormElementType(f.propertyType, f.classifications) } : undefined;
535
+ }
536
+ /**
537
+ * Extract classifications from object type fields classification
538
+ * string. This string may contain more than one classification entry.
539
+ *
540
+ * Classification is a comma separated string that may contain additional
541
+ * properties related to on classification entry. Example:
542
+ *
543
+ * `id:reference[system:folder], email`
544
+ *
545
+ * @param classifications Object type fields classification property (schema)
546
+ */
547
+ getClassifications(classifications) {
548
+ const res = new Map();
549
+ if (classifications) {
550
+ classifications.forEach((c) => {
551
+ const matches = c.match(/^([^\[]*)(\[(.*)\])?$/);
552
+ if (matches && matches.length) {
553
+ res.set(matches[1], {
554
+ classification: matches[1],
555
+ options: matches[3] ? matches[3].split(',').map((o) => o.trim()) : []
556
+ });
557
+ }
558
+ });
559
+ }
560
+ return res;
561
+ }
562
+ toFormElement(field) {
563
+ return { ...field, label: this.getLocalizedLabel(field.id), name: field.id, type: field.propertyType };
564
+ }
565
+ updateAuthData(data) {
566
+ this.authData = { ...this.authData, ...data };
567
+ this.#backend.setHeader('Accept-Language', this.authData.language);
568
+ return this.#appCache.setItem(this.#STORAGE_KEY_AUTH_DATA, this.authData);
569
+ }
570
+ updateLocalizations(iso) {
571
+ return this.updateAuthData({ language: iso }).pipe(switchMap(() => this.#fetchLocalizations()), tap((res) => {
572
+ this.system.i18n = res;
573
+ this.#appCache.setItem(this.#STORAGE_KEY, this.system).subscribe();
574
+ this.#systemSource.next(this.system);
575
+ }));
576
+ }
577
+ #fetchLocalizations() {
578
+ return this.#backend.get('/resources/text');
579
+ }
580
+ fetchResources(id) {
581
+ return this.#backend
582
+ .batch([
583
+ { uri: `/system/resources/${id}`, base: ApiBase.core },
584
+ { uri: `/admin/resources/${id}`, base: ApiBase.core }
585
+ ])
586
+ .pipe(map(([global, tenant]) => ({ global, tenant })));
587
+ }
588
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
589
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, providedIn: 'root' }); }
590
+ }
591
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, decorators: [{
592
+ type: Injectable,
593
+ args: [{
594
+ providedIn: 'root'
595
+ }]
596
+ }] });
597
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3lzdGVtLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL3l1dXZpcy9jbGllbnQtY29yZS9zcmMvbGliL3NlcnZpY2Uvc3lzdGVtL3N5c3RlbS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQWMsRUFBRSxFQUFFLGFBQWEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvRCxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDakUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzdELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUcxQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsY0FBYyxFQUFFLG9CQUFvQixFQUFFLGlCQUFpQixFQUFFLHdCQUF3QixFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7QUFlbko7O0dBRUc7QUFJSCxNQUFNLE9BQU8sYUFBYTtJQUgxQjtRQUlFLGFBQVEsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDbEMsY0FBUyxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNwQyxZQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXpCLGlCQUFZLEdBQUcsNEJBQTRCLENBQUM7UUFDNUMsMkJBQXNCLEdBQUcsb0JBQW9CLENBQUM7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Q0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVELGNBQWMsQ0FBQyxFQUFVO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLFFBQVE7YUFDakIsS0FBSyxDQUFDO1lBQ0wsRUFBRSxHQUFHLEVBQUUscUJBQXFCLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxFQUFFO1lBQ3RELEVBQUUsR0FBRyxFQUFFLG9CQUFvQixFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksRUFBRTtTQUN0RCxDQUFDO2FBQ0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzNELENBQUM7K0dBdG9CVSxhQUFhO21IQUFiLGFBQWEsY0FGWixNQUFNOzs0RkFFUCxhQUFhO2tCQUh6QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZm9ya0pvaW4sIE9ic2VydmFibGUsIG9mLCBSZXBsYXlTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBtYXAsIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVXRpbHMgfSBmcm9tICcuLi8uLi91dGlsL3V0aWxzJztcbmltcG9ydCB7IEFwaUJhc2UgfSBmcm9tICcuLi9iYWNrZW5kL2FwaS5lbnVtJztcbmltcG9ydCB7IEJhY2tlbmRTZXJ2aWNlIH0gZnJvbSAnLi4vYmFja2VuZC9iYWNrZW5kLnNlcnZpY2UnO1xuaW1wb3J0IHsgQXBwQ2FjaGVTZXJ2aWNlIH0gZnJvbSAnLi4vY2FjaGUvYXBwLWNhY2hlLnNlcnZpY2UnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vbG9nZ2VyL2xvZ2dlcic7XG5pbXBvcnQgeyBBdXRoRGF0YSB9IGZyb20gJy4vLi4vYXV0aC9hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgT2JqZWN0VHlwZUZpZWxkSW50ZXJuYWxUeXBlLCBPYmplY3RUeXBlRmllbGRUeXBlIH0gZnJvbSAnLi9vYmplY3QtZm9ybS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQmFzZU9iamVjdFR5cGVGaWVsZCwgQ2xhc3NpZmljYXRpb24sIENvbnRlbnRTdHJlYW1BbGxvd2VkLCBJbnRlcm5hbEZpZWxkVHlwZSwgT2JqZWN0VHlwZUNsYXNzaWZpY2F0aW9uLCBTeXN0ZW1UeXBlIH0gZnJvbSAnLi9zeXN0ZW0uZW51bSc7XG5pbXBvcnQge1xuICBDbGFzc2lmaWNhdGlvbkVudHJ5LFxuICBHZW5lcmljT2JqZWN0VHlwZSxcbiAgTG9jYWxpemF0aW9uLFxuICBPYmplY3RUeXBlLFxuICBPYmplY3RUeXBlRmllbGQsXG4gIE9iamVjdFR5cGVQZXJtaXNzaW9ucyxcbiAgU2NoZW1hUmVzcG9uc2UsXG4gIFNjaGVtYVJlc3BvbnNlRmllbGREZWZpbml0aW9uLFxuICBTY2hlbWFSZXNwb25zZVR5cGVEZWZpbml0aW9uLFxuICBTZWNvbmRhcnlPYmplY3RUeXBlLFxuICBTeXN0ZW1EZWZpbml0aW9uXG59IGZyb20gJy4vc3lzdGVtLmludGVyZmFjZSc7XG5cbi8qKlxuICogUHJvdmlkaW5nIHN5c3RlbSBkZWZpbml0aW9ucy5cbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgU3lzdGVtU2VydmljZSB7XG4gICNiYWNrZW5kID0gaW5qZWN0KEJhY2tlbmRTZXJ2aWNlKTtcbiAgI2FwcENhY2hlID0gaW5qZWN0KEFwcENhY2hlU2VydmljZSk7XG4gICNsb2dnZXIgPSBpbmplY3QoTG9nZ2VyKTtcblxuICAjU1RPUkFHRV9LRVkgPSAneXV2LmNvcmUuc3lzdGVtLmRlZmluaXRpb24nO1xuICAjU1RPUkFHRV9LRVlfQVVUSF9EQVRBID0gJ3l1di5jb3JlLmF1dGguZGF0YSc7XG4gIC8vIGNhY2hlZCBpY29ucyB0byBhdm9pZCBiYWNrZW5kIGNhbGxzIChzZXNzaW9uIGNhY2hlKVxuICAjaWNvbkNhY2hlOiB7XG4gICAgW29iamVjdFR5cGVJZDogc3RyaW5nXToge1xuICAgICAgdXJpOiBzdHJpbmc7XG4gICAgICBpY29uPzogc3RyaW5nO1xuICAgIH07XG4gIH0gPSB7fTtcbiAgI3Jlc29sdmVkQ2xhc3NpZmljYXRpb25zQ2FjaGU6IHsgW29iamVjdFR5cGVJZDogc3RyaW5nXTogYW55IH0gPSB7fTtcblxuICBzeXN0ZW0/OiBTeXN0ZW1EZWZpbml0aW9uO1xuICAjc3lzdGVtU291cmNlID0gbmV3IFJlcGxheVN1YmplY3Q8U3lzdGVtRGVmaW5pdGlvbj4oKTtcbiAgc3lzdGVtJDogT2JzZXJ2YWJsZTxTeXN0ZW1EZWZpbml0aW9uPiA9IHRoaXMuI3N5c3RlbVNvdXJjZS5hc09ic2VydmFibGUoKTtcblxuICAvLyBjYWNoZSBmb3IgcmVzb2x2ZWQgdmlzaWJsZSB0YWdzIGJlY2F1c2UgdGhleSBhcmUgdXNlZCBpbiBsaXN0cyBhbmQgdGhlcmVmb3JlIHNob3VsZCBub3QgYmUgcmUtZXZhbHVhdGVkIGFsbCB0aGUgdGltZVxuICAjdmlzaWJsZVRhZ3NDYWNoZTogeyBbb2JqZWN0SWQ6IHN0cmluZ106IHsgW3RhZ05hbWU6IHN0cmluZ106IGFueVtdIH0gfSA9IHt9O1xuICAjcGVybWlzc2lvbnM/OiBPYmplY3RUeXBlUGVybWlzc2lvbnM7XG4gIGF1dGhEYXRhPzogQXV0aERhdGE7XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgb2JqZWN0IHR5cGVzXG4gICAqIEBwYXJhbSB3aXRoTGFiZWxzIFdoZXRoZXIgb3Igbm90IHRvIGFsc28gYWRkIHRoZSB0eXBlcyBsYWJlbHNcbiAgICovXG4gIGdldE9iamVjdFR5cGVzKHdpdGhMYWJlbHM/OiBib29sZWFuLCBzaXR1YXRpb24/OiAnc2VhcmNoJyB8ICdjcmVhdGUnKTogR2VuZXJpY09iamVjdFR5cGVbXSB7XG4gICAgLy8gRmlsdGVyIGJ5IHVzZXIgcGVybWlzc2lvbnMgYmFzZWQgb24gc2l0dWF0aW9uXG4gICAgY29uc3Qgb2JqZWN0VHlwZXMgPSB0aGlzLiNmaWx0ZXJCeVBlcm1pc3Npb25zKFxuICAgICAgWy4uLnRoaXMuc3lzdGVtIS5vYmplY3RUeXBlcywgLi4udGhpcy5zeXN0ZW0hLnNlY29uZGFyeU9iamVjdFR5cGVzLm1hcCgoc290KSA9PiB0aGlzLiNzb3RUb0dlbmVyaWNUeXBlKHNvdCkpXSxcbiAgICAgIHNpdHVhdGlvblxuICAgICkgYXMgR2VuZXJpY09iamVjdFR5cGVbXTtcbiAgICByZXR1cm4gd2l0aExhYmVscyA/IG9iamVjdFR5cGVzLm1hcCgodCkgPT4gKHsgLi4udCwgbGFiZWw6IHRoaXMuZ2V0TG9jYWxpemVkUmVzb3VyY2UoYCR7dC5pZH1fbGFiZWxgKSB9KSkgOiBvYmplY3RUeXBlcztcbiAgfVxuXG4gICNzb3RUb0dlbmVyaWNUeXBlKHNvdDogU2Vjb25kYXJ5T2JqZWN0VHlwZSk6IEdlbmVyaWNPYmplY3RUeXBlIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc290LFxuICAgICAgaXNGb2xkZXI6IGZhbHNlLFxuICAgICAgY3JlYXRhYmxlOiB0cnVlLFxuICAgICAgc2Vjb25kYXJ5T2JqZWN0VHlwZXM6IFtdLFxuICAgICAgaXNTb3Q6IHRydWVcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgc2Vjb25kYXJ5IG9iamVjdCB0eXBlc1xuICAgKiBAcGFyYW0gd2l0aExhYmVscyBXaGV0aGVyIG9yIG5vdCB0byBhbHNvIGFkZCB0aGUgdHlwZXMgbGFiZWxzXG4gICAqL1xuICBnZXRTZWNvbmRhcnlPYmplY3RUeXBlcyh3aXRoTGFiZWxzPzogYm9vbGVhbiwgc2l0dWF0aW9uPzogJ3NlYXJjaCcgfCAnY3JlYXRlJyk6IFNlY29uZGFyeU9iamVjdFR5cGVbXSB7XG4gICAgY29uc3Qgc290cyA9IHRoaXMuI2ZpbHRlckJ5UGVybWlzc2lvbnMoXG4gICAgICB0aGlzLnN5c3RlbSEuc2Vjb25kYXJ5T2JqZWN0VHlwZXMubWFwKChzb3QpID0+IHRoaXMuI3NvdFRvR2VuZXJpY1R5cGUoc290KSksXG4gICAgICBzaXR1YXRpb25cbiAgICApIGFzIFNlY29uZGFyeU9iamVjdFR5cGVbXTtcblxuICAgIHJldHVybiAoXG4gICAgICAod2l0aExhYmVscyA/IHNvdHMubWFwKCh0KSA9PiAoeyAuLi50LCBsYWJlbDogdGhpcy5nZXRMb2NhbGl6ZWRSZXNvdXJjZShgJHt0LmlkfV9sYWJlbGApIH0pKSA6IHNvdHMpXG4gICAgICAgIC8vIGlnbm9yZVxuICAgICAgICAuZmlsdGVyKCh0KSA9PiB0LmlkICE9PSB0LmJhc2VJZCAmJiAhdC5pZC5zdGFydHNXaXRoKCdzeXN0ZW06JykgJiYgdC5pZCAhPT0gJ2FwcENsaWVudHN5c3RlbTpsZWFkaW5nVHlwZScpXG4gICAgKTtcbiAgfVxuXG4gICNmaWx0ZXJCeVBlcm1pc3Npb25zKHR5cGVzOiBHZW5lcmljT2JqZWN0VHlwZVtdLCBzaXR1YXRpb24/OiAnc2VhcmNoJyB8ICdjcmVhdGUnKTogR2VuZXJpY09iamVjdFR5cGVbXSB7XG4gICAgaWYgKCFzaXR1YXRpb24pIHJldHVybiB0eXBlcztcbiAgICBjb25zdCBhbGxvd2VkVHlwZXMgPSBzaXR1YXRpb24gPT09ICdzZWFyY2gnID8gdGhpcy4jcGVybWlzc2lvbnMhLnNlYXJjaGFibGVPYmplY3RUeXBlcyA6IHRoaXMuI3Blcm1pc3Npb25zIS5jcmVhdGVhYmxlT2JqZWN0VHlwZXM7XG4gICAgcmV0dXJuIHR5cGVzLmZpbHRlcigodCkgPT4gYWxsb3dlZFR5cGVzLmluY2x1ZGVzKHQuaWQpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBwYXJ0aWN1bGFyIG9iamVjdCB0eXBlXG4gICAqIEBwYXJhbSBvYmplY3RUeXBlSWQgSUQgb2YgdGhlIG9iamVjdCB0eXBlXG4gICAqIEBwYXJhbSB3aXRoTGFiZWwgV2hldGhlciBvciBub3QgdG8gYWxzbyBhZGQgdGhlIHR5cGVzIGxhYmVsXG4gICAqL1xuICBnZXRPYmplY3RUeXBlKG9iamVjdFR5cGVJZDogc3RyaW5nLCB3aXRoTGFiZWw/OiBib29sZWFuKTogR2VuZXJpY09iamVjdFR5cGUgfCB1bmRlZmluZWQge1xuICAgIGxldCBvYmplY3RUeXBlOiBHZW5lcmljT2JqZWN0VHlwZSB8IHVuZGVmaW5lZCA9XG4gICAgICBvYmplY3RUeXBlSWQgPT09IFN5c3RlbVR5cGUuT0JKRUNUID8gdGhpcy5nZXRCYXNlVHlwZSgpIDogdGhpcy5zeXN0ZW0hLm9iamVjdFR5cGVzLmZpbmQoKG90KSA9PiBvdC5pZCA9PT0gb2JqZWN0VHlwZUlkKTtcblxuICAgIGlmIChvYmplY3RUeXBlICYmIHdpdGhMYWJlbCkge1xuICAgICAgb2JqZWN0VHlwZS5sYWJlbCA9IHRoaXMuZ2V0TG9jYWxpemVkUmVzb3VyY2UoYCR7b2JqZWN0VHlwZS5pZH1fbGFiZWxgKSB8fCBvYmplY3RUeXBlSWQ7XG4gICAgfVxuXG4gICAgaWYgKCFvYmplY3RUeXBlKSB7XG4gICAgICAvLyBubyAncmVhbCcgb2JqZWN0IHR5cGUgZm91bmQuIFRyeSB0byBmaW5kIGEgbWF0Y2hpbmcgU09UIGFuZCB0cmVhdCBpdCBsaWtlIGEgcmVhbCB0eXBlXG4gICAgICAvLyBieSBmaWxsaW5nIHVwIHRoZSBtaXNzaW5nIHByb3BlcnRpZXNcbiAgICAgIGNvbnN0IHNvdCA9IHRoaXMuZ2V0U2Vjb25kYXJ5T2JqZWN0VHlwZShvYmplY3RUeXBlSWQsIHdpdGhMYWJlbCk7XG4gICAgICBpZiAoc290KSB7XG4gICAgICAgIG9iamVjdFR5cGUgPSB0aGlzLiNzb3RUb0dlbmVyaWNUeXBlKHNvdCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmplY3RUeXBlO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgYSBwYXJ0aWN1bGFyIHNlY29uZGFyeSBvYmplY3QgdHlwZVxuICAgKiBAcGFyYW0gb2JqZWN0VHlwZUlkIElEIG9mIHRoZSBvYmplY3QgdHlwZVxuICAgKiBAcGFyYW0gd2l0aExhYmVsIFdoZXRoZXIgb3Igbm90IHRvIGFsc28gYWRkIHRoZSB0eXBlcyBsYWJlbFxuICAgKi9cbiAgZ2V0U2Vjb25kYXJ5T2JqZWN0VHlwZShvYmplY3RUeXBlSWQ6IHN0cmluZywgd2l0aExhYmVsPzogYm9vbGVhbik6IFNlY29uZGFyeU9iamVjdFR5cGUgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG9iamVjdFR5cGU6IFNlY29uZGFyeU9iamVjdFR5cGUgfCB1bmRlZmluZWQgPSB0aGlzLnN5c3RlbSEuc2Vjb25kYXJ5T2JqZWN0VHlwZXMuZmluZCgob3QpID0+IG90LmlkID09PSBvYmplY3RUeXBlSWQpO1xuICAgIGlmIChvYmplY3RUeXBlICYmIHdpdGhMYWJlbCkge1xuICAgICAgb2JqZWN0VHlwZS5sYWJlbCA9IHRoaXMuZ2V0TG9jYWxpemVkUmVzb3VyY2UoYCR7b2JqZWN0VHlwZS5pZH1fbGFiZWxgKSB8fCBvYmplY3RUeXBlLmlkO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0VHlwZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGJhc2UgZG9jdW1lbnQgdHlwZSBhbGwgZG9jdW1lbnRzIGJlbG9uZyB0b1xuICAgKiBAcGFyYW0gd2l0aExhYmVsIFdoZXRoZXIgb3Igbm90IHRvIGFsc28gYWRkIHRoZSB0eXBlcyBsYWJlbFxuICAgKi9cbiAgZ2V0QmFzZURvY3VtZW50VHlwZSh3aXRoTGFiZWw/OiBib29sZWFuKTogT2JqZWN0VHlwZSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0VHlwZShTeXN0ZW1UeXBlLkRPQ1VNRU5ULCB3aXRoTGFiZWwpITtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGJhc2UgZm9sZGVyIHR5cGUgYWxsIGZvbGRlcnMgYmVsb25nIHRvXG4gICAqIEBwYXJhbSB3aXRoTGFiZWwgV2hldGhlciBvciBub3QgdG8gYWxzbyBhZGQgdGhlIHR5cGVzIGxhYmVsXG4gICAqL1xuICBnZXRCYXNlRm9sZGVyVHlwZSh3aXRoTGFiZWw/OiBib29sZWFuKTogT2JqZWN0VHlwZSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0VHlwZShTeXN0ZW1UeXBlLkZPTERFUiwgd2l0aExhYmVsKSE7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBiYXNlIG9iamVjdCB0eXBlIGFsbCBkbXMgb2JqZWN0cyBiZWxvbmcgdG9cbiAgICovXG4gIGdldEJhc2VUeXBlKCk6IE9iamVjdFR5cGUge1xuICAgIGNvbnN0IHN5c0ZvbGRlciA9IHRoaXMuZ2V0QmFzZUZvbGRlclR5cGUoKTtcbiAgICBjb25zdCBzeXNEb2N1bWVudCA9IHRoaXMuZ2V0QmFzZURvY3VtZW50VHlwZSgpO1xuXG4gICAgLy8gYmFzZSB0eXBlIGNvbnRhaW5zIG9ubHkgZmllbGRzIHRoYXQgYXJlIHNoYXJlZCBieSBiYXNlIGRvY3VtZW50IGFuZCBiYXNlIGZvbGRlciAuLi5cbiAgICBjb25zdCBmb2xkZXJUeXBlRmllbGRJRHMgPSBzeXNGb2xkZXIuZmllbGRzLm1hcCgoZikgPT4gZi5pZCk7XG4gICAgY29uc3QgYmFzZVR5cGVGaWVsZHM6IE9iamVjdFR5cGVGaWVsZFtdID0gc3lzRG9jdW1lbnQuZmllbGRzLmZpbHRlcigoZikgPT4gZm9sZGVyVHlwZUZpZWxkSURzLmluY2x1ZGVzKGYuaWQpKTtcblxuICAgIHJldHVybiB7XG4gICAgICBpZDogU3lzdGVtVHlwZS5PQkpFQ1QsXG4gICAgICBjcmVhdGFibGU6IGZhbHNlLFxuICAgICAgaXNGb2xkZXI6IGZhbHNlLFxuICAgICAgc2Vjb25kYXJ5T2JqZWN0VHlwZXM6IFtdLFxuICAgICAgZmllbGRzOiBiYXNlVHlwZUZpZWxkc1xuICAgICAgLy8gcmF3RmllbGRzOiBiYXNlVHlwZUZpZWxkc1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSByZXNvbHZlZCBvYmplY3QgdHlwZSB3aXRoIGFsbCBmaWVsZHMgKCBpbmNsdWRpbmcgZmllbGRzIGZyb20gcmVsYXRlZCBzZWNvbmRhcnkgdHlwZXMgKVxuICAgKi9cbiAgZ2V0UmVzb2x2ZWRUeXBlKG9iamVjdFR5cGVJZD86IHN0cmluZyk6IHsgaWQ6IHN0cmluZzsgZmllbGRzOiBPYmplY3RUeXBlRmllbGRbXSB9IHtcbiAgICBjb25zdCBhYnN0cmFjdFR5cGVzID0gT2JqZWN0LnZhbHVlcyhTeXN0ZW1UeXBlKTtcbiAgICBpZiAoIW9iamVjdFR5cGVJZCB8fCBhYnN0cmFjdFR5cGVzLmluY2x1ZGVzKG9iamVjdFR5cGVJZCkpIHtcbiAgICAgIGNvbnN0IGJhc2VUeXBlID0gdGhpcy5nZXRCYXNlVHlwZSgpO1xuICAgICAgcmV0dXJuIHsgaWQ6IGJhc2VUeXBlLmlkLCBmaWVsZHM6IGJhc2VUeXBlLmZpZWxkcyB9O1xuICAgIH1cblxuICAgIGNvbnN0IG90ID0gdGhpcy5nZXRPYmplY3RUeXBlKG9iamVjdFR5cGVJZCk7XG4gICAgaWYgKCFvdCkge1xuICAgICAgY29uc3Qgc290ID0gdGhpcy5nZXRTZWNvbmRhcnlPYmplY3RUeXBlKG9iamVjdFR5cGVJZCkgfHwgeyBpZDogb2JqZWN0VHlwZUlkLCBmaWVsZHM6IFtdIH07XG4gICAgICBjb25zdCBiYXNlVHlwZSA9IHRoaXMuZ2V0QmFzZVR5cGUoKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGlkOiBzb3QuaWQsXG4gICAgICAgIGZpZWxkczogWy4uLnNvdC5maWVsZHMsIC4uLmJhc2VUeXBlLmZpZWxkc11cbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiBvdC5pZCxcbiAgICAgIGZpZWxkczogb3QuZmllbGRzXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHJlc29sdmVkIG9iamVjdCB0YWdzXG4gICAqL1xuICBnZXRSZXNvbHZlZFRhZ3Mob2JqZWN0VHlwZUlkOiBzdHJpbmcpOiB7IGlkOiBzdHJpbmc7IHRhZ05hbWU6IHN0cmluZzsgdGFnVmFsdWVzOiBhbnk7IGZpZWxkczogT2JqZWN0VHlwZUZpZWxkW10gfVtdIHtcbiAgICBjb25zdCB2VGFncyA9IHRoaXMuZ2V0VmlzaWJsZVRhZ3Mob2JqZWN0VHlwZUlkKTtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModlRhZ3MpLm1hcCgoaykgPT4gKHtcbiAgICAgIGlkOiBvYmplY3RUeXBlSWQsXG4gICAgICB0YWdOYW1lOiBrLFxuICAgICAgdGFnVmFsdWVzOiB2VGFnc1trXSxcbiAgICAgIGZpZWxkczogdGhpcy5nZXRCYXNlVHlwZSgpLmZpZWxkcy5maWx0ZXIoKGYpID0+IGYuaWQgPT09IEJhc2VPYmplY3RUeXBlRmllbGQuVEFHUylcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGEgbGlzdCBvZiBjbGFzc2lmaWNhdGlvbnMgZm9yIGEgZ2l2ZW4gb2JqZWN0IHR5cGUgaW5jbHVkaW5nIHRoZVxuICAgKiBjbGFzc2lmaWNhdGlvbnMgb2YgaXRzIHN0YXRpYyBzZWNvbmRhcnkgb2JqZWN0IHR5cGVzXG4gICAqIEBwYXJhbSBvYmplY3RUeXBlSWQgSUQgb2YgdGhlIG9iamVjdCB0eXBlXG4gICAqL1xuICBnZXRSZXNvbHZlZENsYXNzaWZpY2F0aW9ucyhvYmplY3RUeXBlSWQ6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy4jcmVzb2x2ZWRDbGFzc2lmaWNhdGlvbnNDYWNoZVtvYmplY3RUeXBlSWRdIHx8IHRoaXMuI3Jlc29sdmVDbGFzc2lmaWNhdGlvbnMob2JqZWN0VHlwZUlkKTtcbiAgfVxuXG4gICNyZXNvbHZlQ2xhc3NpZmljYXRpb25zKG9iamVjdFR5cGVJZDogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIGxldCBjbGFzc2lmaWNhdGlvbnM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3Qgb3QgPSB0aGlzLmdldE9iamVjdFR5cGUob2JqZWN0VHlwZUlkKTtcbiAgICBpZiAob3QpIHtcbiAgICAgIGNsYXNzaWZpY2F0aW9ucyA9IG90LmNsYXNzaWZpY2F0aW9uIHx8IFtdO1xuICAgICAgY29uc3Qgc3RhdGljU09Uczogc3RyaW5nW10gPSBvdC5zZWNvbmRhcnlPYmplY3RUeXBlcyA/IG90LnNlY29uZGFyeU9iamVjdFR5cGVzLmZpbHRlcigoc290KSA9PiBzb3Quc3RhdGljKS5tYXAoKHNvdCkgPT4gc290LmlkKSA6IFtdO1xuICAgICAgc3RhdGljU09Ucy5mb3JFYWNoKChpZCkgPT4ge1xuICAgICAgICBjb25zdCBzb3QgPSB0aGlzLmdldFNlY29uZGFyeU9iamVjdFR5cGUoaWQpO1xuICAgICAgICBjbGFzc2lmaWNhdGlvbnMgPSBzb3Q/LmNsYXNzaWZpY2F0aW9uXG4gICAgICAgICAgPyBbXG4gICAgICAgICAgICAgIC4uLmNsYXNzaWZpY2F0aW9ucyxcbiAgICAgICAgICAgICAgLi4uc290LmNsYXNzaWZpY2F0aW9uLmZpbHRlcigoYykgPT4ge1xuICAgICAgICAgICAgICAgIC8vIGFsc28gZmlsdGVyIGNsYXNzaWZpY2F0aW9ucyB0aGF0IHNob3VsZCBub3QgYmUgaW5oZXJpdGVkXG4gICAgICAgICAgICAgICAgcmV0dXJuIGMgIT09IE9iamVjdFR5cGVDbGFzc2lmaWNhdGlvbi5DUkVBVEVfRkFMU0UgJiYgYyAhPT0gT2JqZWN0VHlwZUNsYXNzaWZpY2F0aW9uLlNFQVJDSF9GQUxTRTtcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIF1cbiAgICAgICAgICA6IGNsYXNzaWZpY2F0aW9ucztcbiAgICAgIH0pO1xuICAgICAgdGhpcy4jcmVzb2x2ZWRDbGFzc2lmaWNhdGlvbnNDYWNoZVtvYmplY3RUeXBlSWRdID0gY2xhc3NpZmljYXRpb25zO1xuICAgIH1cbiAgICByZXR1cm4gY2xhc3NpZmljYXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIFZpc2libGUgdGFncyBhcmUgZGVmaW5lZCBieSBhIGNsYXNzaWZpY2F0aW9uIG9uIHRoZSBvYmplY3QgdHlwZSAoZS5nLiAndGFnW3RlbmtvbGlicmk6cHJvY2VzcywxLDIsM10nKS5cbiAgICpcbiAgICogVGhlIGV4YW1wbGUgd2lsbCBvbmx5IHJldHVybiB0YWdzIHdpdGggdGhlIG5hbWUgJ3RlbmtvbGlicmk6cHJvY2VzcydcbiAgICogYW5kIHZhbHVlcyBvZiBlaXRoZXIgMSwgMiBvciAzLiBBbGwgb3RoZXIgdGFncyB3aWxsIGJlIGlnbm9yZWQuXG4gICAqXG4gICAqIEBwYXJhbSBvYmplY3RUeXBlSWQgSUQgb2YgdGhlIG9iamVjdCB0eXBlIHRvIGdldCB0aGUgdmlzaWJsZSB0YWdzIGZvclxuICAgKiBAcmV0dXJucyBvYmplY3Qgd2hlcmUgdGhlIHByb3BlcnR5IG5hbWUgaXMgdGhlIG5hbWUgb2YgdGhlIHRhZyBhbmQgaXRzIHZhbHVlIGFyZSB0aGUgdmlzaWJsZSB2YWx1ZXNcbiAgICogZm9yIHRoYXQgdGFnIChpZiB2YWx1ZXMgaXMgZW1vdHkgYWxsIHZhbHVlcyBhcmUgYWxsb3dlZClcbiAgICovXG4gIGdldFZpc2libGVUYWdzKG9iamVjdFR5cGVJZDogc3RyaW5nKTogeyBbdGFnTmFtZTogc3RyaW5nXTogYW55W10gfSB7XG4gICAgcmV0dXJuIHRoaXMuI3Zpc2libGVUYWdzQ2FjaGVbb2JqZWN0VHlwZUlkXSB8fCB0aGlzLmZldGNoVmlzaWJsZVRhZ3Mob2JqZWN0VHlwZUlkKTtcbiAgfVxuXG4gIHByaXZhdGUgZmV0Y2hWaXNpYmxlVGFncyhvYmplY3RUeXBlSWQ6IHN0cmluZyk6IHsgW3RhZ05hbWU6IHN0cmluZ106IGFueVtdIH0ge1xuICAgIGNvbnN0IG90ID0gdGhpcy5nZXRPYmplY3RUeXBlKG9iamVjdFR5cGVJZCkgfHwgdGhpcy5nZXRTZWNvbmRhcnlPYmplY3RUeXBlKG9iamVjdFR5cGVJZCk7XG4gICAgY29uc3QgdGFnQ2xhc3NpZmljYXRpb25zID0gdGhpcy5nZXRSZXNvbHZlZENsYXNzaWZpY2F0aW9ucyhvYmplY3RUeXBlSWQpLmZpbHRlcigodCkgPT4gdC5zdGFydHNXaXRoKCd0YWdbJykpO1xuICAgIGNvbnN0IHBhcmVudFR5cGUgPSBvdCAmJiAob3QgYXMgT2JqZWN0VHlwZSkuaWQ7XG5cbiAgICBjb25zdCB0bzogeyBbdGFnTmFtZTogc3RyaW5nXTogYW55W10gfSA9IHt9O1xuICAgICh0YWdDbGFzc2lmaWNhdGlvbnMgfHwgW10pLmZvckVhY2goKHRhZykgPT4ge1xuICAgICAgY29uc3QgbSA9IHRhZy5tYXRjaCgvXFxbKC4qKVxcXS9pKSFbMV0uc3BsaXQoJywnKTtcbiAgICAgIGNvbnN0IHRhZ05hbWUgPSBtLnNwbGljZSgwLCAxKVswXTtcbiAgICAgIGNvbnN0IHRhZ1ZhbHVlcyA9IG0ubWFwKCh2KSA9PiBwYXJzZUludCh2LnRyaW0oKSkpO1xuICAgICAgdG9bdGFnTmFtZV0gPSB0YWdWYWx1ZXM7XG4gICAgfSk7XG5cbiAgICB0aGlzLiN2aXNpYmxlVGFnc0NhY2hlW29iamVjdFR5cGVJZF0gPSBwYXJlbnRUeXBlID8geyAuLi50aGlzLmdldFZpc2libGVUYWdzKHBhcmVudFR5cGUpLCAuLi50byB9IDogdG87XG4gICAgcmV0dXJuIHRoaXMuI3Zpc2libGVUYWdzQ2FjaGVbb2JqZWN0VHlwZUlkXTtcbiAgfVxuXG4gIGZpbHRlclZpc2libGVUYWdzKG9iamVjdFR5cGVJZDogc3RyaW5nLCB0YWdzVmFsdWU6IEFycmF5PEFycmF5PGFueT4+KTogQXJyYXk8QXJyYXk8YW55Pj4ge1xuICAgIGlmICghdGFnc1ZhbHVlKSByZXR1cm4gW107XG4gICAgY29uc3QgdlRhZ3M6IHsgW3RhZ05hbWU6IHN0cmluZ106IGFueVtdIH0gPSB0aGlzLmdldFZpc2libGVUYWdzKG9iamVjdFR5cGVJZCk7XG4gICAgLy8gVGFnIHZhbHVlIGxvb2tzIGxpa2UgdGhpczogW3RhZ05hbWU6IHN0cmluZywgc3RhdGU6IG51bWJlciwgZGF0ZTogRGF0ZSwgdHJhY2VJZDogc3RyaW5nXVxuICAgIHJldHVybiB0YWdzVmFsdWUuZmlsdGVyKCh2OiBhbnlbXSkgPT4gISF2VGFnc1t2WzBdXSAmJiB2VGFnc1t2WzBdXS5pbmNsdWRlcyh2WzFdKSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBpY29uIGZvciBhbiBvYmplY3QgdHlwZS4gVGhpcyB3aWxsIHJldHVybiBhbiBTVkcgYXMgYSBzdHJpbmcuXG4gICAqIEBwYXJhbSBvYmplY3RUeXBlSWQgSUQgb2YgdGhlIG9iamVjdCB0eXBlXG4gICAqIEBwYXJhbSBmYWxsYmFjayBJRCBvZiBhIGZhbGxiYWNrIGljb24gdGhhdCBzaG91bGQgYmUgdXNlZCBpZiB0aGUgZ2l2ZW4gb2JqZWN0IHR5cGUgaGFzIG5vIGljb24geWV0XG4gICAqL1xuICBnZXRPYmplY3RUeXBlSWNvbihvYmplY3RUeXBlSWQ6IHN0cmluZywgZmFsbGJhY2s/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgIGlmICh0aGlzLiNpY29uQ2FjaGVbb2JqZWN0VHlwZUlkXSAmJiB0aGlzLiNpY29uQ2FjaGVbb2JqZWN0VHlwZUlkXS5pY29uKSB7XG4gICAgICByZXR1cm4gb2YodGhpcy4jaWNvbkNhY2hlW29iamVjdFR5cGVJZF0uaWNvbiEpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBpY29uVXJpID0gdGhpcy5nZXRPYmplY3RUeXBlSWNvblVyaShvYmplY3RUeXBlSWQsIGZhbGxiYWNrKTtcbiAgICAgIHJldHVybiB0aGlzLiNiYWNrZW5kLmdldChpY29uVXJpKS5waXBlKHRhcCgoaWNvbikgPT4gKHRoaXMuI2ljb25DYWNoZVtvYmplY3RUeXBlSWRdID0geyB1cmk6IGljb25VcmksIGljb24gfSkpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBVUkkgb2YgYW4gb2JqZWN0IHR5cGUgaWNvbi5cbiAgICogQHBhcmFtIG9iamVjdFR5cGVJZCBJRCBvZiB0aGUgb2JqZWN0IHR5cGVcbiAgICogQHBhcmFtIGZhbGxiYWNrIElEIG9mIGEgZmFsbGJhY2sgaWNvbiB0aGF0IHNob3VsZCBiZSB1c2VkIGlmIHRoZSBnaXZlbiBvYmplY3QgdHlwZSBoYXMgbm8gaWNvbiB5ZXRcbiAgICovXG4gIGdldE9iamVjdFR5cGVJY29uVXJpKG9iamVjdFR5cGVJZDogc3RyaW5nLCBmYWxsYmFjaz86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMuI2ljb25DYWNoZVtvYmplY3RUeXBlSWRdKSB7XG4gICAgICByZXR1cm4gdGhpcy4jaWNvbkNhY2hlW29iamVjdFR5cGVJZF0udXJpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBjaSA9IHRoaXMuI2dldEljb25Gcm9tQ2xhc3NpZmljYXRpb24ob2JqZWN0VHlwZUlkKTtcbiAgICAgIGNvbnN0IGZiID0gdGhpcy5nZXRGYWxsYmFja0ljb24ob2JqZWN0VHlwZUlkLCBmYWxsYmFjayk7XG4gICAgICBjb25zdCB1cmkgPSBgL3Jlc291cmNlcy9pY29ucy8ke2VuY29kZVVSSUNvbXBvbmVudChjaSB8fCBvYmplY3RUeXBlSWQpfSR7ZmIgPyBgP2ZhbGxiYWNrPSR7ZW5jb2RlVVJJQ29tcG9uZW50KGZiKX1gIDogJyd9YDtcbiAgICAgIHRoaXMuI2ljb25DYWNoZVtvYmplY3RUeXBlSWRdID0geyB1cmk6IGAke3RoaXMuI2JhY2tlbmQuZ2V0QXBpQmFzZShBcGlCYXNlLmFwaVdlYil9JHt1cml9YCB9O1xuICAgICAgcmV0dXJuIHRoaXMuI2ljb25DYWNoZVtvYmplY3RUeXBlSWRdLnVyaTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldEZhbGxiYWNrSWNvbihvYmplY3RUeXBlSWQ6IHN0cmluZywgZmFsbGJhY2s/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IG90ID0gdGhpcy5nZXRPYmplY3RUeXBlKG9iamVjdFR5cGVJZCk7XG4gICAgaWYgKG90ICYmICFmYWxsYmFjaykge1xuICAgICAgLy8gYWRkIGRlZmF1bHQgZmFsbGJhY2tzIGZvciBzeXN0ZW06ZG9jdW1lbnQgYW5kIHN5c3RlbTpmb2xkZXIgaWYgbm93IG90aGVyIGZhbGxiYWNrIGhhcyBiZWVuIHByb3ZpZGVkXG4gICAgICBmYWxsYmFjayA9IG90LmlzRm9sZGVyID8gJ3N5c3RlbTpmb2xkZXInIDogJ3N5c3RlbTpkb2N1bWVudCc7XG4gICAgICAvLyBpZiAodGhpcy5pc0Zsb2F0aW5nT2JqZWN0VHlwZShvdCkpIHtcbiAgICAgIC8vICAgLy8gdHlwZXMgdGhhdCBkbyBub3QgaGF2ZSBubyBvYmplY3QgdHlwZSBhc3NpZ25lZCB0byB0aGVtIChwcmltYXJ5IEZTT1RzKVxuICAgICAgLy8gICBmYWxsYmFjayA9ICdzeXN0ZW06ZGxtJztcbiAgICAgIC8vIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbGxiYWNrITtcbiAgfVxuXG4gICNnZXRJY29uRnJvbUNsYXNzaWZpY2F0aW9uKG9iamVjdFR5cGVJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgY2U6IE1hcDxzdHJpbmcsIENsYXNzaWZpY2F0aW9uRW50cnk+ID0gdGhpcy5nZXRDbGFzc2lmaWNhdGlvbnModGhpcy5nZXRSZXNvbHZlZENsYXNzaWZpY2F0aW9ucyhvYmplY3RUeXBlSWQpKTtcbiAgICByZXR1cm4gY2UuaGFzKE9iamVjdFR5cGVDbGFzc2lmaWNhdGlvbi5PQkpFQ1RfVFlQRV9JQ09OKSA/IGNlLmdldChPYmplY3RUeXBlQ2xhc3NpZmljYXRpb24uT0JKRUNUX1RZUEVfSUNPTikhLm9wdGlvbnNbMF0gOiBudWxsO1xuICB9XG5cbiAgZ2V0TG9jYWxpemVkUmVzb3VyY2Uoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnN5c3RlbSEuaTE4bltrZXldO1xuICB9XG5cbiAgZ2V0TG9jYWxpemVkTGFiZWwoaWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmdldExvY2FsaXplZFJlc291cmNlKGAke2lkfV9sYWJlbGApO1xuICB9XG5cbiAgZ2V0TG9jYWxpemVkRGVzY3JpcHRpb24oaWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmdldExvY2FsaXplZFJlc291cmNlKGAke2lkfV9kZXNjcmlwdGlvbmApO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZSB3aGV0aGVyIG9yIG5vdCB0aGUgZ2l2ZW4gb2JqZWN0IHR5cGUgZmllbGQgaXMgYSBzeXN0ZW0gZmllbGRcbiAgICogQHBhcmFtIGZpZWxkIE9iamVjdCB0eXBlIGZpZWxkIHRvIGJlIGNoZWNrZWRcbiAgICovXG4gIGlzU3lzdGVtUHJvcGVydHkoZmllbGQ6IE9iamVjdFR5cGVGaWVsZCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmaWVsZC5pZC5zdGFydHNXaXRoKCdzeXN0ZW06Jyk7XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2hlcyB0aGUgYmFja2VuZHMgc3lzdGVtIGRlZmluaXRpb24gYW5kIHVwZGF0ZXMgc3lzdGVtJCBPYnNlcnZhYmxlLlxuICAgKiBTdWJzY3JpYmUgdG8gdGhlIHN5c3RlbSQgb2JzZXJ2YWJsZSBpbnN0ZWFkIG9mIGNhbGxpbmcgdGhpcyBmdW5jdGlvbiwgb3RoZXJ3aXNlIHlvdSdsbCB0cmlnZ2VyIGZldGNoaW5nIHRoZVxuICAgKiBzeXN0ZW0gZGVmaW5pdGlvbiBldmVyeSB0aW1lLlxuICAgKlxuICAgKiBAcGFyYW0gdXNlciBUaGUgdXNlciB0byBsb2FkIHRoZSBzeXN0ZW0gZGVmaW5pdGlvbiBmb3JcbiAgICovXG4gIGdldFN5c3RlbURlZmluaXRpb24oYXV0aERhdGE/OiBBdXRoRGF0YSk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIC8vIFRPRE86IFN1cHBvc2VkIHRvIHJldHVybiAzMDQgaWYgbm90aGluZyBjaGFuZ2VzXG4gICAgcmV0dXJuIHRoaXMuI2ZldGNoU3lzdGVtRGVmaW5pdGlvbihhdXRoRGF0YSk7XG5cbiAgICAvLyBUT0RPOiByZW1vdmUgd2hlbiAzMDQgaXMgdGhlcmU/Pz9cbiAgICAvLyAvLyB0cnkgdG8gZmV0Y2ggc3lzdGVtIGRlZmluaXRpb24gZnJvbSBjYWNoZSBmaXJzdFxuICAgIC8vIHJldHVybiB0aGlzLmFwcENhY2hlLmdldEl0ZW0odGhpcy5TVE9SQUdFX0tFWSkucGlwZShcbiAgICAvLyAgIHN3aXRjaE1hcChyZXMgPT4ge1xuICAgIC8vICAgICBpZiAocmVzKSB7XG4gICAgLy8gICAgICAgLy8gY2hlY2sgaWYgdGhlIHN5c3RlbSBkZWZpbml0aW9uIGZyb20gdGhlIGNhY2hlIGlzIHVwIHRvIGRhdGVcbiAgICAvLyAgICAgICB0aGlzLnN5c3RlbSA9IHJlcztcbiAgICAvLyAgICAgICB0aGlzLnN5c3RlbVNvdXJjZS5uZXh0KHRoaXMuc3lzdGVtKTtcbiAgICAvLyAgICAgICByZXR1cm4gb2YodHJ1ZSk7XG4gICAgLy8gICAgIH0gZWxzZSB7XG4gICAgLy8gICAgICAgLy8gbm90aGluZyBjYWNoZWQgc28gZmFyXG4gICAgLy8gICAgICAgcmV0dXJuIHRoaXMuZmV0Y2hTeXN0ZW1EZWZpbml0aW9uKCk7XG4gICAgLy8gICAgIH1cbiAgICAvLyAgIH0pXG4gICAgLy8gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY3R1YWxseSBmZXRjaCB0aGUgc3lzdGVtIGRlZmluaXRpb24gZnJvbSB0aGUgYmFja2VuZC5cbiAgICogQHBhcmFtIHVzZXIgVXNlciB0byBmZXRjaCBkZWZpbml0aW9uIGZvclxuICAgKi9cbiAgI2ZldGNoU3lzdGVtRGVmaW5pdGlvbihhdXRoRGF0YT86IEF1dGhEYXRhKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIChhdXRoRGF0YSA/IG9mKGF1dGhEYXRhKSA6IHRoaXMuI2FwcENhY2hlLmdldEl0ZW0odGhpcy4jU1RPUkFHRV9LRVlfQVVUSF9EQVRBKSkucGlwZShcbiAgICAgIHN3aXRjaE1hcCgoZGF0YTogQXV0aERhdGEpID0+IHtcbiAgICAgICAgdGhpcy51cGRhdGVBdXRoRGF0YShkYXRhKS5zdWJzY3JpYmUoKTtcbiAgICAgICAgY29uc3QgZmV0Y2hUYXNrcyA9IFt0aGlzLiNiYWNrZW5kLmdldCgnL2Rtcy9zY2hlbWEvbmF0aXZlLmpzb24nLCBBcGlCYXNlLmNvcmUpLCB0aGlzLiNmZXRjaExvY2FsaXphdGlvbnMoKV07XG4gICAgICAgIHJldHVybiBmb3JrSm9pbihmZXRjaFRhc2tzKTtcbiAgICAgIH0pLFxuICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy4jbG9nZ2VyLmVycm9yKCdFcnJvciBmZXRjaGluZyByZWNlbnQgdmVyc2lvbiBvZiBzeXN0ZW0gZGVmaW5pdGlvbiBmcm9tIHNlcnZlci4nLCBlcnJvcik7XG4gICAgICAgIHRoaXMuI3N5c3RlbVNvdXJjZS5lcnJvcignRXJyb3IgZmV0Y2hpbmcgcmVjZW50IHZlcnNpb24gb2Ygc3lzdGVtIGRlZmluaXRpb24gZnJvbSBzZXJ2ZXIuJyk7XG4gICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgIH0pLFxuICAgICAgbWFwKChkYXRhKSA9PiB7XG4gICAgICAgIGlmIChkYXRhPy5sZW5ndGgpIHtcbiAgICAgICAgICB0aGlzLnNldFNjaGVtYShkYXRhWzBdLCBkYXRhWzFdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gISFkYXRhO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgc2V0UGVybWlzc2lvbnMocDogT2JqZWN0VHlwZVBlcm1pc3Npb25zKSB7XG4gICAgdGhpcy4jcGVybWlzc2lvbnMgPSBwO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSB0aGUgc2NoZW1hIGZyb20gdGhlIHNlcnZlcnMgc2NoZW1hIHJlc3BvbnNlXG4gICAqIEBwYXJhbSBzY2hlbWFSZXNwb25zZSBSZXNwb25zZSBmcm9tIHRoZSBiYWNrZW5kXG4gICAqL1xuICBzZXRTY2hlbWEoc2NoZW1hUmVzcG9uc2U6IFNjaGVtYVJlc3BvbnNlLCBsb2NhbGl6ZWRSZXNvdXJjZTogTG9jYWxpemF0aW9uID0ge30pIHtcbiAgICAvLyBwcmVwYXJlIGEgcXVpY2sgYWNjZXNzIG9iamVjdCBmb3IgdGhlIGZpZWxkc1xuICAgIGNvbnN0IHByb3BlcnRpZXNRQTogUmVjb3JkPHN0cmluZywgU2NoZW1hUmVzcG9uc2VGaWVsZERlZmluaXRpb24+ID0ge307XG4gICAgY29uc3Qgb3JnVHlwZUZpZWxkcyA9IFtCYXNlT2JqZWN0VHlwZUZpZWxkLk1PRElGSUVEX0JZLCBCYXNlT2JqZWN0VHlwZUZpZWxkLkNSRUFURURfQlldO1xuICAgIHNjaGVtYVJlc3BvbnNlLnByb3BlcnR5RGVmaW5pdGlvbi5mb3JFYWNoKChwOiBhbnkpID0+IHtcbiAgICAgIHAuY2xhc3NpZmljYXRpb25zID0gcC5jbGFzc2lmaWNhdGlvbjtcbiAgICAgIC8vIFRPRE86IFJlbW92ZSBvbmNlIHNjaGVtYSBzdXBwb3J0cyBvcmdhbml6YXRpb24gY2xhc3NpZmljYXRpb24gZm9yIGJhc2UgcGFyYW1zXG4gICAgICAvLyBtYXAgY2VydGFpbiBmaWVsZHMgdG8gb3JnYW5pemF0aW9uIHR5cGUgKGZha2UgaXQgdW50aWwgeW91IG1ha2UgaXQgOy0pXG4gICAgICBpZiAob3JnVHlwZUZpZWxkcy5pbmNsdWRlcyhwLmlkKSkge1xuICAgICAgICBwLmNsYXNzaWZpY2F0aW9ucyA9IFtDbGFzc2lmaWNhdGlvbi5TVFJJTkdfT1JHQU5JWkFUSU9OXTtcbiAgICAgIH1cbiAgICAgIHByb3BlcnRpZXNRQVtwLmlkXSA9IHA7XG4gICAgfSk7XG4gICAgLy8gcHJlcGFyZSBhIHF1aWNrIGFjY2VzcyBvYmplY3QgZm9yIG9iamVjdCB0eXBlcyAoaW5jbHVkaW5nIHNlY29uZGFyeSBvYmplY3RzKVxuICAgIGNvbnN0IG9iamVjdFR5cGVzUUE6IHsgW2lkOiBzdHJpbmddOiBTY2hlbWFSZXNwb25zZVR5cGVEZWZpbml0aW9uIH0gPSB7fTtcbiAgICBzY2hlbWFSZXNwb25zZS50eXBlRm9sZGVyRGVmaW5pdGlvbi5mb3JFYWNoKChvdDogYW55KSA9PiB7XG4gICAgICBvYmplY3RUeXBlc1FBW290LmlkXSA9IG90O1xuICAgIH0pO1xuICAgIHNjaGVtYVJlc3BvbnNlLnR5cGVEb2N1bWVudERlZmluaXRpb24uZm9yRWFjaCgob3Q6IGFueSkgPT4ge1xuICAgICAgb2JqZWN0VHlwZXNRQVtvdC5pZF0gPSBvdDtcbiAgICB9KTtcbiAgICBzY2hlbWFSZXNwb25zZS50eXBlU2Vjb25kYXJ5RGVmaW5pdGlvbi5mb3JFYWNoKChzb3Q6IGFueSkgPT4ge1xuICAgICAgb2JqZWN0VHlwZXNRQVtzb3QuaWRdID0gc290O1xuICAgIH0pO1xuXG4gICAgY29uc3Qgb2JqZWN0VHlwZXM6IE9iamVjdFR5cGVbXSA9IFtcbiAgICAgIC8vIGZvbGRlciB0eXBlc1xuICAgICAgLi4uc2NoZW1hUmVzcG9uc2UudHlwZUZvbGRlckRlZmluaXRpb24ubWFwKChmZCkgPT4gKHtcbiAgICAgICAgaWQ6IGZkLmlkLFxuICAgICAgICBkZXNjcmlwdGlvbjogZmQuZGVzY3JpcHRpb24sXG4gICAgICAgIGNsYXNzaWZpY2F0aW9uOiBmZC5jbGFzc2lmaWNhdGlvbixcbiAgICAgICAgYmFzZUlkOiBmZC5iYXNlSWQsXG4gICAgICAgIGNyZWF0YWJsZTogdGhpcy4jaXNDcmVhdGFibGUoZmQuaWQpLFxuICAgICAgICBjb250ZW50U3RyZWFtQWxsb3dlZDogQ29udGVudFN0cmVhbUFsbG93ZWQuTk9UX0FMTE9XRUQsXG4gICAgICAgIGlzRm9sZGVyOiB0cnVlLFxuICAgICAgICBzZWNvbmRhcnlPYmplY3RUeXBlczogZmQuc2Vjb25kYXJ5T2JqZWN0VHlwZUlkID8gZmQuc2Vjb25kYXJ5T2JqZWN0VHlwZUlkLm1hcCgodCkgPT4gKHsgaWQ6IHQudmFsdWUsIHN0YXRpYzogdC5zdGF0aWMgfSkpIDogW10sXG4gICAgICAgIGZpZWxkczogdGhpcy4jcmVzb2x2ZU9iamVjdFR5cGVGaWVsZHMoZmQsIHByb3BlcnRpZXNRQSwgb2JqZWN0VHlwZXNRQSlcbiAgICAgICAgLy8gcmF3RmllbGRzOiB0aGlzLnJlc29sdmVPYmplY3RUeXBlRmllbGRzKGZkLCBwcm9wZXJ0aWVzUUEsIG9iamVjdFR5cGVzUUEsIHRydWUpLFxuICAgICAgfSkpLFxuICAgICAgLy8gZG9jdW1lbnQgdHlwZXNcbiAgICAgIC4uLnNjaGVtYVJlc3BvbnNlLnR5cGVEb2N1bWVudERlZmluaXRpb24ubWFwKChkZCkgPT4gKHtcbiAgICAgICAgaWQ6IGRkLmlkLFxuICAgICAgICBkZXNjcmlwdGlvbjogZGQuZGVzY3JpcHRpb24sXG4gICAgICAgIGNsYXNzaWZpY2F0aW9uOiBkZC5jbGFzc2lmaWNhdGlvbixcbiAgICAgICAgYmFzZUlkOiBkZC5iYXNlSWQsXG4gICAgICAgIGNyZWF0YWJsZTogdGhpcy4jaXNDcmVhdGFibGUoZGQuaWQpLFxuICAgICAgICBjb250ZW50U3RyZWFtQWxsb3dlZDogZGQuY29udGVudFN0cmVhbUFsbG93ZWQsXG4gICAgICAgIGlzRm9sZGVyOiBmYWxzZSxcbiAgICAgICAgc2Vjb25kYXJ5T2JqZWN0VHlwZXM6IGRkLnNlY29uZGFyeU9iamVjdFR5cGVJZCA/IGRkLnNlY29uZGFyeU9iamVjdFR5cGVJZC5tYXAoKHQpID0+ICh7IGlkOiB0LnZhbHVlLCBzdGF0aWM6IHQuc3RhdGljIH0pKSA6IFtdLFxuICAgICAgICBmaWVsZHM6IHRoaXMuI3Jlc29sdmVPYmplY3RUeXBlRmllbGRzKGRkLCBwcm9wZXJ0aWVzUUEsIG9iamVjdFR5cGVzUUEpXG4gICAgICAgIC8vIHJhd0ZpZWxkczogdGhpcy5yZXNvbHZlT2JqZWN0VHlwZUZpZWxkcyhkZCwgcHJvcGVydGllc1FBLCBvYmplY3RUeXBlc1FBLCB0cnVlKSxcbiAgICAgIH0pKVxuICAgIF07XG5cbiAgICBjb25zdCBzZWNvbmRhcnlPYmplY3RUeXBlczogU2Vjb25kYXJ5T2JqZWN0VHlwZVtdID0gc2NoZW1hUmVzcG9uc2UudHlwZVNlY29uZGFyeURlZmluaXRpb24ubWFwKChzdGQpID0+ICh7XG4gICAgICBpZDogc3RkLmlkLFxuICAgICAgZGVzY3JpcHRpb246IHN0ZC5kZXNjcmlwdGlvbixcbiAgICAgIGNsYXNzaWZpY2F0aW9uOiBzdGQuY2xhc3NpZmljYXRpb24sXG4gICAgICBjb250ZW50U3RyZWFtQWxsb3dlZDogc3RkLmNvbnRlbnRTdHJlYW1BbGxvd2VkLFxuICAgICAgYmFzZUlkOiBzdGQuYmFzZUlkLFxuICAgICAgLy8gVE9ETzogQ291bGQgYSBTT1QgYmUgYSBmb2xkZXIgdG9vP1xuICAgICAgaXNGb2xkZXI6IGZhbHNlLFxuICAgICAgZmllbGRzOiB0aGlzLiNyZXNvbHZlT2JqZWN0VHlwZUZpZWxkcyhzdGQsIHByb3BlcnRpZXNRQSwgb2JqZWN0VHlwZXNRQSlcbiAgICB9KSk7XG5cbiAgICB0aGlzLnN5c3RlbSA9IHtcbiAgICAgIHZlcnNpb246IHNjaGVtYVJlc3BvbnNlLnZlcnNpb24sXG4gICAgICBsYXN0TW9kaWZpY2F0aW9uRGF0ZTogc2NoZW1hUmVzcG9uc2UubGFzdE1vZGlmaWNhdGlvbkRhdGUsXG4gICAgICBvYmplY3RUeXBlcyxcbiAgICAgIHNlY29uZGFyeU9iamVjdFR5cGVzLFxuICAgICAgaTE4bjogbG9jYWxpemVkUmVzb3VyY2UsXG4gICAgICBhbGxGaWVsZHM6IHByb3BlcnRpZXNRQVxuICAgIH07XG4gICAgdGhpcy4jYXBwQ2FjaGUuc2V0SXRlbSh0aGlzLiNTVE9SQUdFX0tFWSwgdGhpcy5zeXN0ZW0pLnN1YnNjcmliZSgpO1xuICAgIHRoaXMuI3N5c3RlbVNvdXJjZS5uZXh0KHRoaXMuc3lzdGVtKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIGFsbCB0aGUgZmllbGRzIGZvciBhbiBvYmplY3QgdHlwZS4gVGhpcyBhbHNvIGluY2x1ZGVzIHNlY29uZGFyeSBvYmplY3QgdHlwZXMgYW5kIHRoZSBmaWVsZHMgaW5oZXJpdGVkIGZyb21cbiAgICogdGhlIGJhc2UgdHlwZSAoLi4uIGFuZCBvZiBjb3Vyc2UgdGhlIGJhc2UgdHlwZSAoYW5kIGl0cyBzZWNvbmRhcnkgb2JqZWN0IHR5cGVzKSBvZiB0aGUgYmFzZSB0eXBlIGFuZCBzbyBvbilcbiAgICogQHBhcmFtIHNjaGVtYVR5cGVEZWZpbml0aW9uIG9iamVjdCB0eXBlIGRlZmluaXRpb24gZnJvbSB0aGUgbmF0aXZlIHNjaGVtYVxuICAgKiBAcGFyYW0gcHJvcGVydGllc1FBIFF1aWNrIGFjY2VzcyBvYmplY3Qgb2YgYWxsIHByb3BlcnRpZXNcbiAgICogQHBhcmFtIG9iamVjdFR5cGVzUUEgUXVpY2sgYWNjZXNzIG9iamVjdCBvZiBhbGwgb2JqZWN0IHR5cGVzXG4gICAqIEBwYXJhbSByYXcgSWYgc2V0IHRvICd0cnVlJyBvbmx5IHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBvYmplY3QgdHlwZSBpdHNlbGYgd2lsbCBiZSByZXR1cm5lZCAod2l0aG91dCBTT1RzKVxuICAgKi9cbiAgI3Jlc29sdmVPYmplY3RUeXBlRmllbGRzKFxuICAgIHNjaGVtYVR5cGVEZWZpbml0aW9uOiBTY2hlbWFSZXNwb25zZVR5cGVEZWZpbml0aW9uLFxuICAgIHByb3BlcnRpZXNRQTogeyBbaWQ6IHN0cmluZ106IFNjaGVtYVJlc3BvbnNlRmllbGREZWZpbml0aW9uIH0sXG4gICAgb2JqZWN0VHlwZXNRQTogeyBbaWQ6IHN0cmluZ106IFNjaGVtYVJlc3BvbnNlVHlwZURlZmluaXRpb24gfVxuICApOiBPYmplY3RUeXBlRmllbGRbXSB7XG4gICAgY29uc3Qgb2JqZWN0VHlwZUZpZWxkSURzID0gc2NoZW1hVHlwZURlZmluaXRpb24ucHJvcGVydHlSZWZlcmVuY2UubWFwKChwcikgPT4gcHIudmFsdWUpO1xuICAgIGlmIChzY2hlbWFUeXBlRGVmaW5pdGlvbi5zZWNvbmRhcnlPYmplY3RUeXBlSWQpIHtcbiAgICAgIHNjaGVtYVR5cGVEZWZpbml0aW9uLnNlY29uZGFyeU9iamVjdFR5cGVJZFxuICAgICAgICAuZmlsdGVyKChzb3QpID0+IHNvdC5zdGF0aWMpXG4gICAgICAgIC5tYXAoKHNvdCkgPT4gc290LnZhbHVlKVxuICAgICAgICAuZm9yRWFjaCgoc290SUQpID0+IG9iamVjdFR5cGVzUUFbc290SURdLnByb3BlcnR5UmVmZXJlbmNlLmZvckVhY2goKHByOiB7IHZhbHVlOiBzdHJpbmcgfSkgPT4gb2JqZWN0VHlwZUZpZWxkSURzLnB1c2gocHIudmFsdWUpKSk7XG4gICAgfVxuXG4gICAgbGV0IGZpZWxkczogT2JqZWN0VHlwZUZpZWxkW10gPSBvYmplY3RUeXBlRmllbGRJRHMubWFwKChpZCkgPT4gKHtcbiAgICAgIC4uLnByb3BlcnRpZXNRQVtpZF0sXG4gICAgICBfaW50ZXJuYWxUeXBlOiB0aGlzLmdldEludGVybmFsRm9ybUVsZW1lbnRUeXBlKHByb3BlcnRpZXNRQVtpZF0ucHJvcGVydHlUeXBlLCBwcm9wZXJ0aWVzUUFbaWRdLmNsYXNzaWZpY2F0aW9ucylcbiAgICB9KSk7XG5cbiAgICAvLyBhbHNvIHJlc29sdmUgcHJvcGVydGllcyBvZiB0aGUgYmFzZSB0eXBlXG4gICAgaWYgKHNjaGVtYVR5cGVEZWZpbml0aW9uLmJhc2VJZCAhPT0gc2NoZW1hVHlwZURlZmluaXRpb24uaWQgJiYgISFvYmplY3RUeXBlc1FBW3NjaGVtYVR5cGVEZWZpbml0aW9uLmJhc2VJZF0pIHtcbiAgICAgIGZpZWxkcyA9IGZpZWxkcy5jb25jYXQodGhpcy4jcmVzb2x2ZU9iamVjdFR5cGVGaWVsZHMob2JqZWN0VHlwZXNRQVtzY2hlbWFUeXBlRGVmaW5pdGlvbi5iYXNlSWRdLCBwcm9wZXJ0aWVzUUEsIG9iamVjdFR5cGVzUUEpKTtcbiAgICB9XG4gICAgcmV0dXJuIGZpZWxkcztcbiAgfVxuXG4gICNpc0NyZWF0YWJsZShvYmplY3RUeXBlSWQ6IHN0cmluZykge1xuICAgIHJldHVybiAhW1N5c3RlbVR5cGUuRk9MREVSLCBTeXN0ZW1UeXBlLkRPQ1VNRU5UXS5pbmNsdWRlcyhvYmplY3RUeXBlSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoIGEgY29sbGVjdGlvbiBvZiBmb3JtIG1vZGVscy5cbiAgICogQHBhcmFtIG9iamVjdFR5cGVJRHMgT2JqZWN0IHR5cGUgSURzIHRvIGZldGNoIGZvcm0gbW9kZWwgZm9yXG4gICAqIEBwYXJhbSBzaXR1YXRpb24gRm9ybSBzaXR1YXRpb25cbiAgICogQHJldHVybnMgT2JqZWN0IHdoZXJlIHRoZSBvYmplY3QgdHlwZSBpZCBpcyBrZXkgYW5kIHRoZSBmb3JtIG1vZGVsIGlzIHRoZSB2YWx1ZVxuICAgKi9cbiAgZ2V0T2JqZWN0VHlwZUZvcm1zKG9iamVjdFR5cGVJRHM6IHN0cmluZ1tdLCBzaXR1YXRpb246IHN0cmluZyk6IE9ic2VydmFibGU8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICAgIHJldHVybiBmb3JrSm9pbihcbiAgICAgIG9iamVjdFR5cGVJRHMubWFwKChvKSA9PlxuICAgICAgICB0aGlzLmdldE9iamVjdFR5cGVGb3JtKG8sIHNpdHVhdGlvbikucGlwZShcbiAgICAgICAgICBjYXRjaEVycm9yKChlKSA9PiBvZihudWxsKSksXG4gICAgICAgICAgbWFwKChyZXMpID0+ICh7XG4gICAgICAgICAgICBpZDogbyxcbiAgICAgICAgICAgIGZvcm1Nb2RlbDogcmVzXG4gICAgICAgICAgfSkpXG4gICAgICAgIClcbiAgICAgIClcbiAgICApLnBpcGUoXG4gICAgICBtYXAoKHJlcykgPT4ge1xuICAgICAgICBjb25zdCByZXNNYXA6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICAgICAgcmVzLmZpbHRlcigocikgPT4gdGhpcy4jZm9ybUhhc0VsZW1lbnRzKHIuZm9ybU1vZGVsKSkuZm9yRWFjaCgocjogYW55KSA9PiAocmVzTWFwW3IuaWRdID0gci5mb3JtTW9kZWwpKTtcbiAgICAgICAgcmV0dXJuIHJlc01hcDtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGZvcm0gbW9kZWwgb2YgYW4gb2JqZWN0IHR5cGUuXG4gICAqXG4gICAqIEBwYXJhbSBvYmplY3RUeXBlSWQgSUQgb2YgdGhlIG9iamVjdCB0eXBlIHRvIGZldGNoIHRoZSBmb3JtIGZvclxuICAgKiBAcGFyYW0gc2l0dWF0aW9uIFRoZSBmb3JtIHNpdHVhdGlvbiB0byBiZSBmZXRjaGVkXG4gICAqIEByZXR1cm5zIEZvcm0gbW9kZWxcbiAgICovXG4gIGdldE9iamVjdFR5cGVGb3JtKG9iamVjdFR5cGVJZDogc3RyaW5nLCBzaXR1YXRpb246IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuI2JhY2tlbmQuZ2V0KFV0aWxzLmJ1aWxkVXJpKGAvZG1zL2Zvcm1zLyR7b2JqZWN0VHlwZUlkfWAsIHsgc2l0dWF0aW9uIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayB3aGV0aGVyIG9yIG5vdCB0aGUgbW9kZWwgaGFzIGF0IGxlYXN0IG9uZSBmb3JtIGVsZW1lbnQuIFJlY3Vyc2l2ZS5cbiAgICogQHBhcmFtIGVsZW1lbnQgRm9ybSBlbGVtZW50IHRvIGNoZWNrIGNoaWxkIGVsZW1lbnRzIGZvclxuICAgKi9cbiAgI2Zvcm1IYXNFbGVtZW50cyhlbGVtZW50OiBhbnkpOiBib29sZWFuIHtcbiAgICBsZXQgaGFzRWxlbWVudCA9IGZhbHNlO1xuICAgIGVsZW1lbnQuZWxlbWVudHM/LmZvckVhY2goKGU6IGFueSkgPT4ge1xuICAgICAgaWYgKCFbJ28ybUdyb3VwJywgJ28ybUdyb3VwU3RhY2snXS5pbmNsdWRlcyhlLnR5cGUpKSB7XG4gICAgICAgIGhhc0VsZW1lbnQgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmICghaGFzRWxlbWVudCkge1xuICAgICAgICBoYXNFbGVtZW50ID0gdGhpcy4jZm9ybUhhc0VsZW1lbnRzKGUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBoYXNFbGVtZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBhbiBpbnRlcm5hbCB0eXBlIGZvciBhIGdpdmVuIG9iamVjdCB0eXBlIGZpZWxkLlxuICAgKiBBZGRpbmcgdGhpcyB0byBhIGZvcm0gZWxlbWVudCBvciBvYmplY3QgdHlwZSBmaWVsZCBlbmFibGVzIHVzIHRvIHJlbmRlciBmb3Jtc1xuICAgKiBiYXNlZCBvbiBvYmplY3QgdHlwZSBmaWVsZHMgaW4gYSBtb3JlIHBlcmZvcm1hbnQgd2F5LiBPdGhlcndpc2Ugd2Ugd291bGRcbiAgICogaGF2ZSB0byBldmFsdWF0ZSB0aGUgY29uZGl0aW9ucyBmb3IgZXZlcnkgZm9ybSBlbGVtZW50IG9uIGV2ZXJ5IGRpZ2VzdCBjeWNsZS5cbiAgICogQHBhcmFtIHR5cGUgcHJvcGVydHlUeXBlIG9mIHRoZSBPYmplY3RUeXBlRmllbGRcbiAgICogQHBhcmFtIGNsYXNzaWZpY2F0aW9ucyBjbGFzc2lmaWNhdGlvbnMgb2YgdGhlIE9iamVjdFR5cGVGaWVsZFxuICAgKi9cbiAgZ2V0SW50ZXJuYWxGb3JtRWxlbWVudFR5cGUodHlwZTogc3RyaW5nLCBjbGFzc2lmaWNhdGlvbnM/OiBzdHJpbmdbXSk6IE9iamVjdFR5cGVGaWVsZEludGVybmFsVHlwZSB7XG4gICAgY29uc3QgX2NsYXNzaWZpY2F0aW9ucyA9IHRoaXMuZ2V0Q2xhc3NpZmljYXRpb25zKGNsYXNzaWZpY2F0aW9ucyB8fCBbXSk7XG5cbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycgJiYgX2NsYXNzaWZpY2F0aW9ucy5oYXMoQ2xhc3NpZmljYXRpb24uU1RSSU5HX1JFRkVSRU5DRSkpIHtcbiAgICAgIHJldHVybiBJbnRlcm5hbEZpZWxkVHlwZS5TVFJJTkdfUkVGRVJFTkNFO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycgJiYgX2NsYXNzaWZpY2F0aW9ucy5oYXMoQ2xhc3NpZmljYXRpb24uU1RSSU5HX09SR0FOSVpBVElPTikpIHtcbiAgICAgIHJldHVybiBJbnRlcm5hbEZpZWxkVHlwZS5TVFJJTkdfT1JHQU5JWkFUSU9OO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycgJiYgX2NsYXNzaWZpY2F0aW9ucy5oYXMoQ2xhc3NpZmljYXRpb24uU1RSSU5HX09SR0FOSVpBVElPTl9TRVQpKSB7XG4gICAgICByZXR1cm4gSW50ZXJuYWxGaWVsZFR5cGUuU1RSSU5HX09SR0FOSVpBVElPTl9TRVQ7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJyAmJiBfY2xhc3NpZmljYXRpb25zLmhhcyhDbGFzc2lmaWNhdGlvbi5TVFJJTkdfQ0FUQUxPRykpIHtcbiAgICAgIHJldHVybiBJbnRlcm5hbEZpZWxkVHlwZS5TVFJJTkdfQ0FUQUxPRztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJyAmJiBfY2xhc3NpZmljYXRpb25zLmhhcyhDbGFzc2lmaWNhdGlvbi5CT09MRUFOX1NXSVRDSCkpIHtcbiAgICAgIHJldHVybiBJbnRlcm5hbEZpZWxkVHlwZS5CT09MRUFOX1NXSVRDSDtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdHlwZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgIChfY2xhc3NpZmljYXRpb25zLmhhcyhDbGFzc2lmaWNhdGlvbi5TVFJJTkdfQ0FUQUxPR19EWU5BTUlDKSB8fCBfY2xhc3NpZmljYXRpb25zLmhhcyhDbGFzc2lmaWNhdGlvbi5TVFJJTkdfQ0FUQUxPR19DVVNUT00pKVxuICAgICkge1xuICAgICAgcmV0dXJuIEludGVybmFsRmllbGRUeXBlLlNUUklOR19EWU5BTUlDX0NBVEFMT0c7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGlmIHRoZXJlIGFyZSBubyBtYXRjaGluZyBjb25kaXRpb25zIGp1c3QgcmV0dXJuIHRoZSBvcmlnaW5hbCB0eXBlXG4gICAgICByZXR1cm4gdHlwZSBhcyBPYmplY3RUeXBlRmllbGRUeXBlO1xuICAgIH1cbiAgfVxuXG4gIGdldE9iamVjdFR5cGVGaWVsZChpZDogc3RyaW5nKTogT2JqZWN0VHlwZUZpZWxkIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBmID0gdGhpcy5zeXN0ZW0/LmFsbEZpZWxkc1tpZF07XG4gICAgcmV0dXJuIGYgPyB7IC4uLmYsIF9pbnRlcm5hbFR5cGU6IHRoaXMuZ2V0SW50ZXJuYWxGb3JtRWxlbWVudFR5cGUoZi5wcm9wZXJ0eVR5cGUsIGYuY2xhc3NpZmljYXRpb25zKSB9IDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3QgY2xhc3NpZmljYXRpb25zIGZyb20gb2JqZWN0IHR5cGUgZmllbGRzIGNsYXNzaWZpY2F0aW9uXG4gICAqIHN0cmluZy4gVGhpcyBzdHJpbmcgbWF5IGNvbnRhaW4gbW9yZSB0aGFuIG9uZSBjbGFzc2lmaWNhdGlvbiBlbnRyeS5cbiAgICpcbiAgICogQ2xhc3NpZmljYXRpb24gaXMgYSBjb21tYSBzZXBhcmF0ZWQgc3RyaW5nIHRoYXQgbWF5IGNvbnRhaW4gYWRkaXRpb25hbFxuICAgKiBwcm9wZXJ0aWVzIHJlbGF0ZWQgdG8gb24gY2xhc3NpZmljYXRpb24gZW50cnkuIEV4YW1wbGU6XG4gICAqXG4gICAqIGBpZDpyZWZlcmVuY2Vbc3lzdGVtOmZvbGRlcl0sIGVtYWlsYFxuICAgKlxuICAgKiBAcGFyYW0gY2xhc3NpZmljYXRpb25zIE9iamVjdCB0eXBlIGZpZWxkcyBjbGFzc2lmaWNhdGlvbiBwcm9wZXJ0eSAoc2NoZW1hKVxuICAgKi9cbiAgZ2V0Q2xhc3NpZmljYXRpb25zKGNsYXNzaWZpY2F0aW9uczogc3RyaW5nW10pOiBNYXA8c3RyaW5nLCBDbGFzc2lmaWNhdGlvbkVudHJ5PiB7XG4gICAgY29uc3QgcmVzID0gbmV3IE1hcDxzdHJpbmcsIENsYXNzaWZpY2F0aW9uRW50cnk+KCk7XG4gICAgaWYgKGNsYXNzaWZpY2F0aW9ucykge1xuICAgICAgY2xhc3NpZmljYXRpb25zLmZvckVhY2goKGMpID0+IHtcbiAgICAgICAgY29uc3QgbWF0Y2hlczogUmVnRXhwTWF0Y2hBcnJheSB8IG51bGwgPSBjLm1hdGNoKC9eKFteXFxbXSopKFxcWyguKilcXF0pPyQvKTtcbiAgICAgICAgaWYgKG1hdGNoZXMgJiYgbWF0Y2hlcy5sZW5ndGgpIHtcbiAgICAgICAgICByZXMuc2V0KG1hdGNoZXNbMV0sIHtcbiAgICAgICAgICAgIGNsYXNzaWZpY2F0aW9uOiBtYXRjaGVzWzFdLFxuICAgICAgICAgICAgb3B0aW9uczogbWF0Y2hlc1szXSA/IG1hdGNoZXNbM10uc3BsaXQoJywnKS5tYXAoKG8pID0+IG8udHJpbSgpKSA6IFtdXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9XG5cbiAgdG9Gb3JtRWxlbWVudChmaWVsZDogT2JqZWN0VHlwZUZpZWxkKTogYW55IHtcbiAgICByZXR1cm4geyAuLi5maWVsZCwgbGFiZWw6IHRoaXMuZ2V0TG9jYWxpemVkTGFiZWwoZmllbGQuaWQpLCBuYW1lOiBmaWVsZC5pZCwgdHlwZTogZmllbGQucHJvcGVydHlUeXBlIH07XG4gIH1cblxuICB1cGRhdGVBdXRoRGF0YShkYXRhOiBQYXJ0aWFsPEF1dGhEYXRhPikge1xuICAgIHRoaXMuYXV0aERhdGEgPSB7IC4uLnRoaXMuYXV0aERhdGEhLCAuLi5kYXRhIH07XG4gICAgdGhpcy4jYmFja2VuZC5zZXRIZWFkZXIoJ0FjY2VwdC1MYW5ndWFnZScsIHRoaXMuYXV0aERhdGEubGFuZ3VhZ2UpO1xuICAgIHJldHVybiB0aGlzLiNhcHBDYWNoZS5zZXRJdGVtKHRoaXMuI1NUT1JBR0VfS0VZX0FVVEhfREFUQSwgdGhpcy5hdXRoRGF0YSk7XG4gIH1cblxuICB1cGRhdGVMb2NhbGl6YXRpb25zKGlzbzogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVBdXRoRGF0YSh7IGxhbmd1YWdlOiBpc28gfSkucGlwZShcbiAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLiNmZXRjaExvY2FsaXphdGlvbnMoKSksXG4gICAgICB0YXAoKHJlcykgPT4ge1xuICAgICAgICB0aGlzLnN5c3RlbSEuaTE4biA9IHJlcztcbiAgICAgICAgdGhpcy4jYXBwQ2FjaGUuc2V0SXRlbSh0aGlzLiNTVE9SQUdFX0tFWSwgdGhpcy5zeXN0ZW0pLnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLiNzeXN0ZW1Tb3VyY2UubmV4dCh0aGlzLnN5c3RlbSEpO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgI2ZldGNoTG9jYWxpemF0aW9ucygpOiBPYnNlcnZhYmxlPExvY2FsaXphdGlvbj4ge1xuICAgIHJldHVybiB0aGlzLiNiYWNrZW5kLmdldCgnL3Jlc291cmNlcy90ZXh0Jyk7XG4gIH1cblxuICBmZXRjaFJlc291cmNlcyhpZDogc3RyaW5nKTogT2JzZXJ2YWJsZTx7IGdsb2JhbDogYW55OyB0ZW5hbnQ6IGFueSB9PiB7XG4gICAgcmV0dXJuIHRoaXMuI2JhY2tlbmRcbiAgICAgIC5iYXRjaChbXG4gICAgICAgIHsgdXJpOiBgL3N5c3RlbS9yZXNvdXJjZXMvJHtpZH1gLCBiYXNlOiBBcGlCYXNlLmNvcmUgfSxcbiAgICAgICAgeyB1cmk6IGAvYWRtaW4vcmVzb3VyY2VzLyR7aWR9YCwgYmFzZTogQXBpQmFzZS5jb3JlIH1cbiAgICAgIF0pXG4gICAgICAucGlwZShtYXAoKFtnbG9iYWwsIHRlbmFudF0pID0+ICh7IGdsb2JhbCwgdGVuYW50IH0pKSk7XG4gIH1cbn1cbiJdfQ==