occam-directed-graphs 3.0.82 → 3.0.84

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.
@@ -8,413 +8,271 @@ Object.defineProperty(exports, "default", {
8
8
  return DirectedGraph;
9
9
  }
10
10
  });
11
- var _necessary = require("necessary");
12
- var _edge = /*#__PURE__*/ _interop_require_default(require("./edge"));
13
- var _cycle = /*#__PURE__*/ _interop_require_default(require("./cycle"));
14
- var _vertex = /*#__PURE__*/ _interop_require_default(require("./vertex"));
15
- var _index = require("./utilities/index");
16
- var _vertex1 = require("./utilities/vertex");
17
- function _array_like_to_array(arr, len) {
18
- if (len == null || len > arr.length) len = arr.length;
19
- for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
20
- return arr2;
21
- }
22
- function _array_without_holes(arr) {
23
- if (Array.isArray(arr)) return _array_like_to_array(arr);
24
- }
25
- function _class_call_check(instance, Constructor) {
26
- if (!(instance instanceof Constructor)) {
27
- throw new TypeError("Cannot call a class as a function");
28
- }
29
- }
30
- function _defineProperties(target, props) {
31
- for(var i = 0; i < props.length; i++){
32
- var descriptor = props[i];
33
- descriptor.enumerable = descriptor.enumerable || false;
34
- descriptor.configurable = true;
35
- if ("value" in descriptor) descriptor.writable = true;
36
- Object.defineProperty(target, descriptor.key, descriptor);
37
- }
38
- }
39
- function _create_class(Constructor, protoProps, staticProps) {
40
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
41
- if (staticProps) _defineProperties(Constructor, staticProps);
42
- return Constructor;
43
- }
11
+ const _necessary = require("necessary");
12
+ const _edge = /*#__PURE__*/ _interop_require_default(require("./edge"));
13
+ const _cycle = /*#__PURE__*/ _interop_require_default(require("./cycle"));
14
+ const _vertex = /*#__PURE__*/ _interop_require_default(require("./vertex"));
15
+ const _index = require("./utilities/index");
16
+ const _vertex1 = require("./utilities/vertex");
44
17
  function _interop_require_default(obj) {
45
18
  return obj && obj.__esModule ? obj : {
46
19
  default: obj
47
20
  };
48
21
  }
49
- function _iterable_to_array(iter) {
50
- if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
51
- }
52
- function _non_iterable_spread() {
53
- throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
54
- }
55
- function _to_consumable_array(arr) {
56
- return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
57
- }
58
- function _unsupported_iterable_to_array(o, minLen) {
59
- if (!o) return;
60
- if (typeof o === "string") return _array_like_to_array(o, minLen);
61
- var n = Object.prototype.toString.call(o).slice(8, -1);
62
- if (n === "Object" && o.constructor) n = o.constructor.name;
63
- if (n === "Map" || n === "Set") return Array.from(n);
64
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
65
- }
66
- var first = _necessary.arrayUtilities.first;
67
- var DirectedGraph = /*#__PURE__*/ function() {
68
- function DirectedGraph(vertexMap) {
69
- _class_call_check(this, DirectedGraph);
22
+ const { first } = _necessary.arrayUtilities;
23
+ class DirectedGraph {
24
+ constructor(vertexMap){
70
25
  this.vertexMap = vertexMap;
71
26
  }
72
- _create_class(DirectedGraph, [
73
- {
74
- key: "getVertexNap",
75
- value: function getVertexNap() {
76
- return this.vertexMap;
77
- }
78
- },
79
- {
80
- key: "getVertexes",
81
- value: function getVertexes() {
82
- var vertexMapValues = Object.values(this.vertexMap), vertexes = vertexMapValues; ///
83
- return vertexes;
84
- }
85
- },
86
- {
87
- key: "getVertexNames",
88
- value: function getVertexNames() {
89
- var vertexMapKeys = Object.keys(this.vertexMap), vertexNames = vertexMapKeys; ///
90
- return vertexNames;
91
- }
92
- },
93
- {
94
- key: "getOrderedVertexNames",
95
- value: function getOrderedVertexNames() {
96
- var vertexes = this.getVertexes();
97
- (0, _vertex1.orderVertexes)(vertexes);
98
- var orderedVertexes = vertexes, orderedVertexNames = (0, _vertex1.vertexNamesFromVertexes)(orderedVertexes);
99
- return orderedVertexNames;
100
- }
101
- },
102
- {
103
- key: "getVertexByVertexName",
104
- value: function getVertexByVertexName(vertexName) {
105
- var vertexPresent = this.isVertexPresentByVertexName(vertexName), vertex = vertexPresent ? this.vertexMap[vertexName] : null;
106
- return vertex;
107
- }
108
- },
109
- {
110
- key: "getEdgesBySourceVertexName",
111
- value: function getEdgesBySourceVertexName(sourceVertexName) {
112
- var edges = [], sourceVertex = this.getVertexByVertexName(sourceVertexName);
113
- if (sourceVertex !== null) {
114
- var immediateSuccessorVertexes = sourceVertex.getImmediateSuccessorVertexes(), immediateSuccessorVertexNames = (0, _vertex1.vertexNamesFromVertexes)(immediateSuccessorVertexes), targetVertexNames = immediateSuccessorVertexNames; ///
115
- targetVertexNames.forEach(function(targetVertexName) {
116
- var edge = _edge.default.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
117
- edges.push(edge);
118
- });
119
- }
120
- return edges;
121
- }
122
- },
123
- {
124
- key: "getEdgesByTargetVertexName",
125
- value: function getEdgesByTargetVertexName(targetVertexName) {
126
- var edges = [], targetVertex = this.getVertexByVertexName(targetVertexName);
127
- if (targetVertex !== null) {
128
- var immediatePredecessorVertexes = targetVertex.getImmediatePredecessorVertexes(), immediatePredecessorVertexNames = (0, _vertex1.vertexNamesFromVertexes)(immediatePredecessorVertexes), sourceVertexNames = immediatePredecessorVertexNames; ///
129
- sourceVertexNames.forEach(function(sourceVertexName) {
130
- var edge = _edge.default.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
131
- edges.push(edge);
132
- });
133
- }
134
- return edges;
135
- }
136
- },
137
- {
138
- key: "getFirstCycle",
139
- value: function getFirstCycle() {
140
- var firstCycle = null;
141
- var cyclesPresent = this.areCyclesPresent();
142
- if (cyclesPresent) {
143
- var cyclicEdges = this.getCyclicEdges(), firstCyclicEdge = first(cyclicEdges), sourceVertexName = firstCyclicEdge.getSourceVertexName(), targetVertexName = firstCyclicEdge.getTargetVertexName(), sourceVertex = this.getVertexByVertexName(sourceVertexName), targetVertex = this.getVertexByVertexName(targetVertexName);
144
- targetVertex.forwardsDepthFirstSearch(function(vertex, predecessorVertexes) {
145
- var terminate = false;
146
- if (vertex === sourceVertex) {
147
- terminate = true;
148
- var cycle = _cycle.default.fromSourceVertexAndPredecessorVertexes(sourceVertex, predecessorVertexes); ///
149
- firstCycle = cycle; ///
150
- }
151
- return terminate;
152
- });
153
- }
154
- return firstCycle;
155
- }
156
- },
157
- {
158
- key: "getCyclicEdges",
159
- value: function getCyclicEdges() {
160
- var cyclicEdges = [], vertexes = this.getVertexes();
161
- vertexes.forEach(function(vertex) {
162
- var sourceVertex = vertex, sourceVertexIndex = sourceVertex.getIndex();
163
- vertex.forEachImmediateSuccessorVertex(function(immediateSuccessorVertex) {
164
- var targetVertex = immediateSuccessorVertex, targetVertexIndex = targetVertex.getIndex();
165
- if (targetVertexIndex < sourceVertexIndex) {
166
- var sourceVertexName = sourceVertex.getName(), targetVertexName = targetVertex.getName(), edge = _edge.default.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName), cyclicEdge = edge; ///
167
- cyclicEdges.push(cyclicEdge);
168
- }
169
- });
170
- sourceVertex;
171
- });
172
- return cyclicEdges;
173
- }
174
- },
175
- {
176
- key: "areCyclesPresent",
177
- value: function areCyclesPresent() {
178
- var vertexes = this.getVertexes(), cyclesPresent = vertexes.some(function(vertex) {
179
- var sourceVertex = vertex, sourceVertexIndex = sourceVertex.getIndex(), cyclicEdgePresent = vertex.someImmediateSuccessorVertex(function(immediateSuccessorVertex) {
180
- var targetVertex = immediateSuccessorVertex, targetVertexIndex = targetVertex.getIndex();
181
- if (targetVertexIndex < sourceVertexIndex) {
182
- return true;
183
- }
184
- });
185
- if (cyclicEdgePresent) {
186
- return true;
187
- }
188
- });
189
- return cyclesPresent;
190
- }
191
- },
192
- {
193
- key: "isEdgePresent",
194
- value: function isEdgePresent(edge) {
195
- var edgePresent = false;
196
- var sourceVertexName = edge.getSourceVertexName(), sourceVertex = this.getVertexByVertexName(sourceVertexName);
197
- if (sourceVertex !== null) {
198
- var targetVertexName = edge.getTargetVertexName(), targetVertex = this.getVertexByVertexName(targetVertexName);
199
- if (targetVertex !== null) {
200
- edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
201
- }
202
- }
203
- return edgePresent;
204
- }
205
- },
206
- {
207
- key: "isVertexPresentByVertexName",
208
- value: function isVertexPresentByVertexName(vertexName) {
209
- var vertexNames = this.getVertexNames(), vertexNamesIncludesVertexName = vertexNames.includes(vertexName), vertexPresent = vertexNamesIncludesVertexName; ///
210
- return vertexPresent;
211
- }
212
- },
213
- {
214
- key: "getImmediateSuccessorVertexNamesByVertexName",
215
- value: function getImmediateSuccessorVertexNamesByVertexName(vertexName) {
216
- var vertex = this.getVertexByVertexName(vertexName), immediateSuccessorVertexNames = vertex.getImmediateSuccessorVertexNames();
217
- return immediateSuccessorVertexNames;
218
- }
219
- },
220
- {
221
- key: "getImmediatePredecessorVertexNamesByVertexName",
222
- value: function getImmediatePredecessorVertexNamesByVertexName(vertexName) {
223
- var vertex = this.getVertexByVertexName(vertexName), immediatePredecessorVertexNames = vertex.getImmediatePredecessorVertexNames();
224
- return immediatePredecessorVertexNames;
225
- }
226
- },
227
- {
228
- key: "isEdgePresentBySourceVertexNameAndTargetVertexName",
229
- value: function isEdgePresentBySourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName) {
230
- var edge = _edge.default.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName), edgePresent = this.isEdgePresent(edge);
231
- return edgePresent;
232
- }
233
- },
234
- {
235
- key: "addVertexByVertexName",
236
- value: function addVertexByVertexName(vertexName) {
237
- var vertexPresent = this.isVertexPresentByVertexName(vertexName);
238
- if (!vertexPresent) {
239
- var vertexNames = this.getVertexNames(), vertexNamesLength = vertexNames.length, name = vertexName, index = vertexNamesLength, vertex = _vertex.default.fromNameAndIndex(name, index);
240
- this.setVertexByVertexName(vertexName, vertex);
241
- }
242
- var vertex1 = this.getVertexByVertexName(vertexName);
243
- return vertex1;
244
- }
245
- },
246
- {
247
- key: "removeVertexByVertexName",
248
- value: function removeVertexByVertexName(vertexName) {
249
- var vertexPresent = this.isVertexPresentByVertexName(vertexName);
250
- if (!vertexPresent) {
251
- return;
252
- }
253
- var vertex = this.getVertexByVertexName(vertexName);
254
- vertex.forEachImmediateSuccessorVertex(function(immediateSuccessVertex) {
255
- var immediatePredecessorVertex = vertex; ///
256
- immediateSuccessVertex.removeImmediatePredecessorVertex(immediatePredecessorVertex);
257
- });
258
- vertex.forEachImmediatePredecessorVertex(function(immediatePredecessorVertex) {
259
- var immediateSuccessVertex = vertex; ///
260
- immediatePredecessorVertex.removeImmediateSuccessorVertex(immediateSuccessVertex);
261
- });
262
- this.deleteVertexByVertexName(vertexName);
263
- var vertexes = this.getVertexes(), deletedVertex = vertex, deletedVertexIndex = deletedVertex.getIndex();
264
- vertexes.forEach(function(vertex) {
265
- var vertexIndex = vertex.getIndex();
266
- if (vertexIndex > deletedVertexIndex) {
267
- vertex.decrementIndex();
268
- }
269
- });
270
- this.filterCyclicEdges();
271
- }
272
- },
273
- {
274
- key: "addVertexesByVertexNames",
275
- value: function addVertexesByVertexNames(vertexNames) {
276
- var _this = this;
277
- vertexNames.forEach(function(vertexName) {
278
- _this.addVertexByVertexName(vertexName);
279
- });
280
- }
281
- },
282
- {
283
- key: "removeVertexesByVertexNames",
284
- value: function removeVertexesByVertexNames(vertexNames) {
285
- var _this = this;
286
- vertexNames.forEach(function(vertexName) {
287
- _this.removeVertexByVertexName(vertexName);
288
- });
289
- }
290
- },
291
- {
292
- key: "addEdge",
293
- value: function addEdge(edge) {
294
- var sourceVertexName = edge.getSourceVertexName(), targetVertexName = edge.getTargetVertexName();
295
- if (sourceVertexName === targetVertexName) {
296
- return;
297
- }
298
- var sourceVertex = this.addVertexByVertexName(sourceVertexName), targetVertex = this.addVertexByVertexName(targetVertexName), edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
299
- if (edgePresent) {
300
- return;
301
- }
302
- var sourceVertexIndex = sourceVertex.getIndex(), targetVertexIndex = targetVertex.getIndex();
303
- if (sourceVertexIndex > targetVertexIndex) {
304
- this.reorderVertexesBySourceVertexAndTargetVertex(sourceVertex, targetVertex);
27
+ getVertexNap() {
28
+ return this.vertexMap;
29
+ }
30
+ getVertexes() {
31
+ const vertexMapValues = Object.values(this.vertexMap), vertexes = vertexMapValues; ///
32
+ return vertexes;
33
+ }
34
+ getVertexNames() {
35
+ const vertexMapKeys = Object.keys(this.vertexMap), vertexNames = vertexMapKeys; ///
36
+ return vertexNames;
37
+ }
38
+ getOrderedVertexNames() {
39
+ const vertexes = this.getVertexes();
40
+ (0, _vertex1.orderVertexes)(vertexes);
41
+ const orderedVertexes = vertexes, orderedVertexNames = (0, _vertex1.vertexNamesFromVertexes)(orderedVertexes);
42
+ return orderedVertexNames;
43
+ }
44
+ getVertexByVertexName(vertexName) {
45
+ const vertexPresent = this.isVertexPresentByVertexName(vertexName), vertex = vertexPresent ? this.vertexMap[vertexName] : null;
46
+ return vertex;
47
+ }
48
+ getEdgesBySourceVertexName(sourceVertexName) {
49
+ const edges = [], sourceVertex = this.getVertexByVertexName(sourceVertexName);
50
+ if (sourceVertex !== null) {
51
+ const immediateSuccessorVertexes = sourceVertex.getImmediateSuccessorVertexes(), immediateSuccessorVertexNames = (0, _vertex1.vertexNamesFromVertexes)(immediateSuccessorVertexes), targetVertexNames = immediateSuccessorVertexNames; ///
52
+ targetVertexNames.forEach((targetVertexName)=>{
53
+ const edge = _edge.default.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
54
+ edges.push(edge);
55
+ });
56
+ }
57
+ return edges;
58
+ }
59
+ getEdgesByTargetVertexName(targetVertexName) {
60
+ const edges = [], targetVertex = this.getVertexByVertexName(targetVertexName);
61
+ if (targetVertex !== null) {
62
+ const immediatePredecessorVertexes = targetVertex.getImmediatePredecessorVertexes(), immediatePredecessorVertexNames = (0, _vertex1.vertexNamesFromVertexes)(immediatePredecessorVertexes), sourceVertexNames = immediatePredecessorVertexNames; ///
63
+ sourceVertexNames.forEach((sourceVertexName)=>{
64
+ const edge = _edge.default.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
65
+ edges.push(edge);
66
+ });
67
+ }
68
+ return edges;
69
+ }
70
+ getFirstCycle() {
71
+ let firstCycle = null;
72
+ const cyclesPresent = this.areCyclesPresent();
73
+ if (cyclesPresent) {
74
+ const cyclicEdges = this.getCyclicEdges(), firstCyclicEdge = first(cyclicEdges), sourceVertexName = firstCyclicEdge.getSourceVertexName(), targetVertexName = firstCyclicEdge.getTargetVertexName(), sourceVertex = this.getVertexByVertexName(sourceVertexName), targetVertex = this.getVertexByVertexName(targetVertexName);
75
+ targetVertex.forwardsDepthFirstSearch((vertex, predecessorVertexes)=>{
76
+ let terminate = false;
77
+ if (vertex === sourceVertex) {
78
+ terminate = true;
79
+ const cycle = _cycle.default.fromSourceVertexAndPredecessorVertexes(sourceVertex, predecessorVertexes); ///
80
+ firstCycle = cycle; ///
305
81
  }
306
- var immediatePredecessorVertex = sourceVertex, immediateSuccessorVertex = targetVertex; ///
307
- immediatePredecessorVertex.addImmediateSuccessorVertex(immediateSuccessorVertex);
308
- immediateSuccessorVertex.addImmediatePredecessorVertex(immediatePredecessorVertex);
309
- }
310
- },
311
- {
312
- key: "addEdges",
313
- value: function addEdges(edges) {
314
- var _this = this;
315
- edges.forEach(function(edge) {
316
- _this.addEdge(edge);
317
- });
318
- }
319
- },
320
- {
321
- key: "removeEdge",
322
- value: function removeEdge(edge, removeStrandedVertexes) {
323
- var sourceVertexName = edge.getSourceVertexName(), targetVertexName = edge.getTargetVertexName(), sourceVertex = this.addVertexByVertexName(sourceVertexName), targetVertex = this.addVertexByVertexName(targetVertexName), edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
324
- if (!edgePresent) {
325
- return;
82
+ return terminate;
83
+ });
84
+ }
85
+ return firstCycle;
86
+ }
87
+ getCyclicEdges() {
88
+ const cyclicEdges = [], vertexes = this.getVertexes();
89
+ vertexes.forEach((vertex)=>{
90
+ const sourceVertex = vertex, sourceVertexIndex = sourceVertex.getIndex();
91
+ vertex.forEachImmediateSuccessorVertex((immediateSuccessorVertex)=>{
92
+ const targetVertex = immediateSuccessorVertex, targetVertexIndex = targetVertex.getIndex();
93
+ if (targetVertexIndex < sourceVertexIndex) {
94
+ const sourceVertexName = sourceVertex.getName(), targetVertexName = targetVertex.getName(), edge = _edge.default.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName), cyclicEdge = edge; ///
95
+ cyclicEdges.push(cyclicEdge);
326
96
  }
327
- sourceVertex.removeImmediateSuccessorVertex(targetVertex);
328
- targetVertex.removeImmediatePredecessorVertex(sourceVertex);
329
- if (removeStrandedVertexes) {
330
- var sourceVertexStranded = sourceVertex.isStranded(), targetVertexStranded = targetVertex.isStranded();
331
- if (sourceVertexStranded) {
332
- this.removeVertexByVertexName(sourceVertexName);
333
- }
334
- if (targetVertexStranded) {
335
- this.removeVertexByVertexName(targetVertexName);
336
- }
97
+ });
98
+ sourceVertex;
99
+ });
100
+ return cyclicEdges;
101
+ }
102
+ areCyclesPresent() {
103
+ const vertexes = this.getVertexes(), cyclesPresent = vertexes.some((vertex)=>{
104
+ const sourceVertex = vertex, sourceVertexIndex = sourceVertex.getIndex(), cyclicEdgePresent = vertex.someImmediateSuccessorVertex((immediateSuccessorVertex)=>{
105
+ const targetVertex = immediateSuccessorVertex, targetVertexIndex = targetVertex.getIndex();
106
+ if (targetVertexIndex < sourceVertexIndex) {
107
+ return true;
337
108
  }
338
- this.filterCyclicEdges();
339
- }
340
- },
341
- {
342
- key: "removeEdges",
343
- value: function removeEdges(edges) {
344
- var _this = this;
345
- var removeStrandedVertexes = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false;
346
- edges.forEach(function(edge) {
347
- _this.removeEdge(edge, removeStrandedVertexes);
348
- });
349
- }
350
- },
351
- {
352
- key: "removeAllEdgesAndVertexes",
353
- value: function removeAllEdgesAndVertexes() {
354
- this.vertexMap = {};
355
- }
356
- },
357
- {
358
- key: "addEdgeBySourceVertexNameAndTargetVertexName",
359
- value: function addEdgeBySourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName) {
360
- var edge = _edge.default.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
361
- this.addEdge(edge);
109
+ });
110
+ if (cyclicEdgePresent) {
111
+ return true;
362
112
  }
363
- },
364
- {
365
- key: "reorderVertexesBySourceVertexAndTargetVertex",
366
- value: function reorderVertexesBySourceVertexAndTargetVertex(sourceVertex, targetVertex) {
367
- var sourceVertexForwardsReachable = targetVertex.isVertexForwardsReachable(sourceVertex);
368
- if (sourceVertexForwardsReachable) {
369
- return;
370
- }
371
- var forwardsReachableVertexes = targetVertex.retrieveForwardsReachableVertexes(), backwardsReachableVertexes = sourceVertex.retrieveBackwardsReachableVertexes();
372
- (0, _vertex1.orderVertexes)(backwardsReachableVertexes);
373
- (0, _vertex1.orderVertexes)(forwardsReachableVertexes);
374
- var reachableVertexes = _to_consumable_array(backwardsReachableVertexes).concat(_to_consumable_array(forwardsReachableVertexes)), reachableIndexes = (0, _index.indexesFromVertexes)(reachableVertexes);
375
- (0, _index.orderIndexes)(reachableIndexes);
376
- reachableVertexes.forEach(function(reachableVertex, index) {
377
- var reachableIndex = reachableIndexes[index];
378
- index = reachableIndex; ///
379
- reachableVertex.setIndex(index);
380
- });
113
+ });
114
+ return cyclesPresent;
115
+ }
116
+ isEdgePresent(edge) {
117
+ let edgePresent = false;
118
+ const sourceVertexName = edge.getSourceVertexName(), sourceVertex = this.getVertexByVertexName(sourceVertexName);
119
+ if (sourceVertex !== null) {
120
+ const targetVertexName = edge.getTargetVertexName(), targetVertex = this.getVertexByVertexName(targetVertexName);
121
+ if (targetVertex !== null) {
122
+ edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
381
123
  }
382
- },
383
- {
384
- key: "filterCyclicEdges",
385
- value: function filterCyclicEdges() {
386
- var _this = this;
387
- var cyclicEdges = this.getCyclicEdges(), edges = cyclicEdges; ///
388
- edges.forEach(function(edge) {
389
- var sourceVertexName = edge.getSourceVertexName(), targetVertexName = edge.getTargetVertexName(), sourceVertex = _this.getVertexByVertexName(sourceVertexName), targetVertex = _this.getVertexByVertexName(targetVertexName), sourceVertexForwardsReachable = targetVertex.isVertexForwardsReachable(sourceVertex);
390
- if (!sourceVertexForwardsReachable) {
391
- _this.reorderVertexesBySourceVertexAndTargetVertex(sourceVertex, targetVertex);
392
- }
393
- });
124
+ }
125
+ return edgePresent;
126
+ }
127
+ isVertexPresentByVertexName(vertexName) {
128
+ const vertexNames = this.getVertexNames(), vertexNamesIncludesVertexName = vertexNames.includes(vertexName), vertexPresent = vertexNamesIncludesVertexName; ///
129
+ return vertexPresent;
130
+ }
131
+ getImmediateSuccessorVertexNamesByVertexName(vertexName) {
132
+ const vertex = this.getVertexByVertexName(vertexName), immediateSuccessorVertexNames = vertex.getImmediateSuccessorVertexNames();
133
+ return immediateSuccessorVertexNames;
134
+ }
135
+ getImmediatePredecessorVertexNamesByVertexName(vertexName) {
136
+ const vertex = this.getVertexByVertexName(vertexName), immediatePredecessorVertexNames = vertex.getImmediatePredecessorVertexNames();
137
+ return immediatePredecessorVertexNames;
138
+ }
139
+ isEdgePresentBySourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName) {
140
+ const edge = _edge.default.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName), edgePresent = this.isEdgePresent(edge);
141
+ return edgePresent;
142
+ }
143
+ addVertexByVertexName(vertexName) {
144
+ const vertexPresent = this.isVertexPresentByVertexName(vertexName);
145
+ if (!vertexPresent) {
146
+ const vertexNames = this.getVertexNames(), vertexNamesLength = vertexNames.length, name = vertexName, index = vertexNamesLength, vertex = _vertex.default.fromNameAndIndex(name, index);
147
+ this.setVertexByVertexName(vertexName, vertex);
148
+ }
149
+ const vertex = this.getVertexByVertexName(vertexName);
150
+ return vertex;
151
+ }
152
+ removeVertexByVertexName(vertexName) {
153
+ const vertexPresent = this.isVertexPresentByVertexName(vertexName);
154
+ if (!vertexPresent) {
155
+ return;
156
+ }
157
+ const vertex = this.getVertexByVertexName(vertexName);
158
+ vertex.forEachImmediateSuccessorVertex((immediateSuccessVertex)=>{
159
+ const immediatePredecessorVertex = vertex; ///
160
+ immediateSuccessVertex.removeImmediatePredecessorVertex(immediatePredecessorVertex);
161
+ });
162
+ vertex.forEachImmediatePredecessorVertex((immediatePredecessorVertex)=>{
163
+ const immediateSuccessVertex = vertex; ///
164
+ immediatePredecessorVertex.removeImmediateSuccessorVertex(immediateSuccessVertex);
165
+ });
166
+ this.deleteVertexByVertexName(vertexName);
167
+ const vertexes = this.getVertexes(), deletedVertex = vertex, deletedVertexIndex = deletedVertex.getIndex();
168
+ vertexes.forEach((vertex)=>{
169
+ const vertexIndex = vertex.getIndex();
170
+ if (vertexIndex > deletedVertexIndex) {
171
+ vertex.decrementIndex();
394
172
  }
395
- },
396
- {
397
- key: "setVertexByVertexName",
398
- value: function setVertexByVertexName(vertexName, vertex) {
399
- this.vertexMap[vertexName] = vertex;
173
+ });
174
+ this.filterCyclicEdges();
175
+ }
176
+ addVertexesByVertexNames(vertexNames) {
177
+ vertexNames.forEach((vertexName)=>{
178
+ this.addVertexByVertexName(vertexName);
179
+ });
180
+ }
181
+ removeVertexesByVertexNames(vertexNames) {
182
+ vertexNames.forEach((vertexName)=>{
183
+ this.removeVertexByVertexName(vertexName);
184
+ });
185
+ }
186
+ addEdge(edge) {
187
+ const sourceVertexName = edge.getSourceVertexName(), targetVertexName = edge.getTargetVertexName();
188
+ if (sourceVertexName === targetVertexName) {
189
+ return;
190
+ }
191
+ const sourceVertex = this.addVertexByVertexName(sourceVertexName), targetVertex = this.addVertexByVertexName(targetVertexName), edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
192
+ if (edgePresent) {
193
+ return;
194
+ }
195
+ const sourceVertexIndex = sourceVertex.getIndex(), targetVertexIndex = targetVertex.getIndex();
196
+ if (sourceVertexIndex > targetVertexIndex) {
197
+ this.reorderVertexesBySourceVertexAndTargetVertex(sourceVertex, targetVertex);
198
+ }
199
+ const immediatePredecessorVertex = sourceVertex, immediateSuccessorVertex = targetVertex; ///
200
+ immediatePredecessorVertex.addImmediateSuccessorVertex(immediateSuccessorVertex);
201
+ immediateSuccessorVertex.addImmediatePredecessorVertex(immediatePredecessorVertex);
202
+ }
203
+ addEdges(edges) {
204
+ edges.forEach((edge)=>{
205
+ this.addEdge(edge);
206
+ });
207
+ }
208
+ removeEdge(edge, removeStrandedVertexes) {
209
+ const sourceVertexName = edge.getSourceVertexName(), targetVertexName = edge.getTargetVertexName(), sourceVertex = this.addVertexByVertexName(sourceVertexName), targetVertex = this.addVertexByVertexName(targetVertexName), edgePresent = sourceVertex.isEdgePresentByTargetVertex(targetVertex);
210
+ if (!edgePresent) {
211
+ return;
212
+ }
213
+ sourceVertex.removeImmediateSuccessorVertex(targetVertex);
214
+ targetVertex.removeImmediatePredecessorVertex(sourceVertex);
215
+ if (removeStrandedVertexes) {
216
+ const sourceVertexStranded = sourceVertex.isStranded(), targetVertexStranded = targetVertex.isStranded();
217
+ if (sourceVertexStranded) {
218
+ this.removeVertexByVertexName(sourceVertexName);
400
219
  }
401
- },
402
- {
403
- key: "deleteVertexByVertexName",
404
- value: function deleteVertexByVertexName(vertexName) {
405
- delete this.vertexMap[vertexName];
220
+ if (targetVertexStranded) {
221
+ this.removeVertexByVertexName(targetVertexName);
406
222
  }
407
223
  }
408
- ], [
409
- {
410
- key: "fromNothing",
411
- value: function fromNothing() {
412
- var vertexMap = {}, directedGraph = new DirectedGraph(vertexMap);
413
- return directedGraph;
414
- }
224
+ this.filterCyclicEdges();
225
+ }
226
+ removeEdges(edges, removeStrandedVertexes = false) {
227
+ edges.forEach((edge)=>{
228
+ this.removeEdge(edge, removeStrandedVertexes);
229
+ });
230
+ }
231
+ removeAllEdgesAndVertexes() {
232
+ this.vertexMap = {};
233
+ }
234
+ addEdgeBySourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName) {
235
+ const edge = _edge.default.fromSourceVertexNameAndTargetVertexName(sourceVertexName, targetVertexName);
236
+ this.addEdge(edge);
237
+ }
238
+ reorderVertexesBySourceVertexAndTargetVertex(sourceVertex, targetVertex) {
239
+ const sourceVertexForwardsReachable = targetVertex.isVertexForwardsReachable(sourceVertex);
240
+ if (sourceVertexForwardsReachable) {
241
+ return;
415
242
  }
416
- ]);
417
- return DirectedGraph;
418
- }();
243
+ const forwardsReachableVertexes = targetVertex.retrieveForwardsReachableVertexes(), backwardsReachableVertexes = sourceVertex.retrieveBackwardsReachableVertexes();
244
+ (0, _vertex1.orderVertexes)(backwardsReachableVertexes);
245
+ (0, _vertex1.orderVertexes)(forwardsReachableVertexes);
246
+ const reachableVertexes = [
247
+ ...backwardsReachableVertexes,
248
+ ...forwardsReachableVertexes
249
+ ], reachableIndexes = (0, _index.indexesFromVertexes)(reachableVertexes);
250
+ (0, _index.orderIndexes)(reachableIndexes);
251
+ reachableVertexes.forEach((reachableVertex, index)=>{
252
+ const reachableIndex = reachableIndexes[index];
253
+ index = reachableIndex; ///
254
+ reachableVertex.setIndex(index);
255
+ });
256
+ }
257
+ filterCyclicEdges() {
258
+ const cyclicEdges = this.getCyclicEdges(), edges = cyclicEdges; ///
259
+ edges.forEach((edge)=>{
260
+ const sourceVertexName = edge.getSourceVertexName(), targetVertexName = edge.getTargetVertexName(), sourceVertex = this.getVertexByVertexName(sourceVertexName), targetVertex = this.getVertexByVertexName(targetVertexName), sourceVertexForwardsReachable = targetVertex.isVertexForwardsReachable(sourceVertex);
261
+ if (!sourceVertexForwardsReachable) {
262
+ this.reorderVertexesBySourceVertexAndTargetVertex(sourceVertex, targetVertex);
263
+ }
264
+ });
265
+ }
266
+ setVertexByVertexName(vertexName, vertex) {
267
+ this.vertexMap[vertexName] = vertex;
268
+ }
269
+ deleteVertexByVertexName(vertexName) {
270
+ delete this.vertexMap[vertexName];
271
+ }
272
+ static fromNothing() {
273
+ const vertexMap = {}, directedGraph = new DirectedGraph(vertexMap);
274
+ return directedGraph;
275
+ }
276
+ }
419
277
 
420
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kaXJlY3RlZEdyYXBoLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgeyBhcnJheVV0aWxpdGllcyB9IGZyb20gXCJuZWNlc3NhcnlcIjtcblxuaW1wb3J0IEVkZ2UgZnJvbSBcIi4vZWRnZVwiO1xuaW1wb3J0IEN5Y2xlIGZyb20gXCIuL2N5Y2xlXCI7XG5pbXBvcnQgVmVydGV4IGZyb20gXCIuL3ZlcnRleFwiO1xuXG5pbXBvcnQgeyBvcmRlckluZGV4ZXMsIGluZGV4ZXNGcm9tVmVydGV4ZXMgfSBmcm9tIFwiLi91dGlsaXRpZXMvaW5kZXhcIjtcbmltcG9ydCB7IG9yZGVyVmVydGV4ZXMsIHZlcnRleE5hbWVzRnJvbVZlcnRleGVzIH0gZnJvbSBcIi4vdXRpbGl0aWVzL3ZlcnRleFwiO1xuXG5jb25zdCB7IGZpcnN0IH0gPSBhcnJheVV0aWxpdGllcztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRGlyZWN0ZWRHcmFwaCB7XG4gIGNvbnN0cnVjdG9yKHZlcnRleE1hcCkge1xuICAgIHRoaXMudmVydGV4TWFwID0gdmVydGV4TWFwO1xuICB9XG5cbiAgZ2V0VmVydGV4TmFwKCkge1xuICAgIHJldHVybiB0aGlzLnZlcnRleE1hcDtcbiAgfVxuXG4gIGdldFZlcnRleGVzKCkge1xuICAgIGNvbnN0IHZlcnRleE1hcFZhbHVlcyA9IE9iamVjdC52YWx1ZXModGhpcy52ZXJ0ZXhNYXApLFxuICAgICAgICAgIHZlcnRleGVzID0gdmVydGV4TWFwVmFsdWVzOyAvLy9cblxuICAgIHJldHVybiB2ZXJ0ZXhlcztcbiAgfVxuXG4gIGdldFZlcnRleE5hbWVzKCkge1xuICAgIGNvbnN0IHZlcnRleE1hcEtleXMgPSBPYmplY3Qua2V5cyh0aGlzLnZlcnRleE1hcCksXG4gICAgICAgICAgdmVydGV4TmFtZXMgPSB2ZXJ0ZXhNYXBLZXlzOyAgLy8vXG5cbiAgICByZXR1cm4gdmVydGV4TmFtZXM7XG4gIH1cblxuICBnZXRPcmRlcmVkVmVydGV4TmFtZXMoKSB7XG4gICAgY29uc3QgdmVydGV4ZXMgPSB0aGlzLmdldFZlcnRleGVzKCk7XG5cbiAgICBvcmRlclZlcnRleGVzKHZlcnRleGVzKTtcblxuICAgIGNvbnN0IG9yZGVyZWRWZXJ0ZXhlcyA9IHZlcnRleGVzLCAvLy9cbiAgICAgICAgICBvcmRlcmVkVmVydGV4TmFtZXMgPSB2ZXJ0ZXhOYW1lc0Zyb21WZXJ0ZXhlcyhvcmRlcmVkVmVydGV4ZXMpO1xuXG4gICAgcmV0dXJuIG9yZGVyZWRWZXJ0ZXhOYW1lcztcbiAgfVxuXG4gIGdldFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgdmVydGV4UHJlc2VudCA9IHRoaXMuaXNWZXJ0ZXhQcmVzZW50QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpLFxuICAgICAgICAgIHZlcnRleCA9IHZlcnRleFByZXNlbnQgP1xuICAgICAgICAgICAgICAgICAgICAgdGhpcy52ZXJ0ZXhNYXBbdmVydGV4TmFtZV0gOlxuICAgICAgICAgICAgICAgICAgICAgICBudWxsO1xuXG4gICAgcmV0dXJuIHZlcnRleDtcbiAgfVxuXG4gIGdldEVkZ2VzQnlTb3VyY2VWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUpIHtcbiAgICBjb25zdCBlZGdlcyA9IFtdLFxuICAgICAgICAgIHNvdXJjZVZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUpO1xuXG4gICAgaWYgKHNvdXJjZVZlcnRleCAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMgPSBzb3VyY2VWZXJ0ZXguZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMoKSxcbiAgICAgICAgICAgIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleE5hbWVzID0gdmVydGV4TmFtZXNGcm9tVmVydGV4ZXMoaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMpLFxuICAgICAgICAgICAgdGFyZ2V0VmVydGV4TmFtZXMgPSBpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lczsgIC8vL1xuXG4gICAgICB0YXJnZXRWZXJ0ZXhOYW1lcy5mb3JFYWNoKCh0YXJnZXRWZXJ0ZXhOYW1lKSA9PiB7XG4gICAgICAgIGNvbnN0IGVkZ2UgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgICAgICBlZGdlcy5wdXNoKGVkZ2UpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVkZ2VzO1xuICB9XG5cbiAgZ2V0RWRnZXNCeVRhcmdldFZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSkge1xuICAgIGNvbnN0IGVkZ2VzID0gW10sXG4gICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSk7XG5cbiAgICBpZiAodGFyZ2V0VmVydGV4ICE9PSBudWxsKSB7XG4gICAgICBjb25zdCBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzID0gdGFyZ2V0VmVydGV4LmdldEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMoKSxcbiAgICAgICAgICAgIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXMgPSB2ZXJ0ZXhOYW1lc0Zyb21WZXJ0ZXhlcyhpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzKSxcbiAgICAgICAgICAgIHNvdXJjZVZlcnRleE5hbWVzID0gaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lczsgIC8vL1xuXG4gICAgICBzb3VyY2VWZXJ0ZXhOYW1lcy5mb3JFYWNoKChzb3VyY2VWZXJ0ZXhOYW1lKSA9PiB7XG4gICAgICAgIGNvbnN0IGVkZ2UgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgICAgICBlZGdlcy5wdXNoKGVkZ2UpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVkZ2VzO1xuICB9XG5cbiAgZ2V0Rmlyc3RDeWNsZSgpIHtcbiAgICBsZXQgZmlyc3RDeWNsZSA9IG51bGw7XG5cbiAgICBjb25zdCBjeWNsZXNQcmVzZW50ID0gdGhpcy5hcmVDeWNsZXNQcmVzZW50KCk7XG5cbiAgICBpZiAoY3ljbGVzUHJlc2VudCkge1xuICAgICAgY29uc3QgY3ljbGljRWRnZXMgPSB0aGlzLmdldEN5Y2xpY0VkZ2VzKCksXG4gICAgICAgICAgICBmaXJzdEN5Y2xpY0VkZ2UgPSBmaXJzdChjeWNsaWNFZGdlcyksXG4gICAgICAgICAgICBzb3VyY2VWZXJ0ZXhOYW1lID0gZmlyc3RDeWNsaWNFZGdlLmdldFNvdXJjZVZlcnRleE5hbWUoKSwgLy8vXG4gICAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gZmlyc3RDeWNsaWNFZGdlLmdldFRhcmdldFZlcnRleE5hbWUoKSwgLy8vXG4gICAgICAgICAgICBzb3VyY2VWZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lKSxcbiAgICAgICAgICAgIHRhcmdldFZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHRhcmdldFZlcnRleE5hbWUpO1xuXG4gICAgICB0YXJnZXRWZXJ0ZXguZm9yd2FyZHNEZXB0aEZpcnN0U2VhcmNoKCh2ZXJ0ZXgsIHByZWRlY2Vzc29yVmVydGV4ZXMpID0+IHtcbiAgICAgICAgbGV0IHRlcm1pbmF0ZSA9IGZhbHNlO1xuXG4gICAgICAgIGlmICh2ZXJ0ZXggPT09IHNvdXJjZVZlcnRleCkge1xuICAgICAgICAgIHRlcm1pbmF0ZSA9IHRydWU7XG5cbiAgICAgICAgICBjb25zdCBjeWNsZSA9IEN5Y2xlLmZyb21Tb3VyY2VWZXJ0ZXhBbmRQcmVkZWNlc3NvclZlcnRleGVzKHNvdXJjZVZlcnRleCwgcHJlZGVjZXNzb3JWZXJ0ZXhlcyk7ICAvLy9cblxuICAgICAgICAgIGZpcnN0Q3ljbGUgPSBjeWNsZTsgLy8vXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGVybWluYXRlO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpcnN0Q3ljbGU7XG4gIH1cblxuICBnZXRDeWNsaWNFZGdlcygpIHtcbiAgICBjb25zdCBjeWNsaWNFZGdlcyA9IFtdLFxuICAgICAgICAgIHZlcnRleGVzID0gdGhpcy5nZXRWZXJ0ZXhlcygpO1xuXG4gICAgdmVydGV4ZXMuZm9yRWFjaCgodmVydGV4KSA9PiB7XG4gICAgICBjb25zdCBzb3VyY2VWZXJ0ZXggPSB2ZXJ0ZXgsICAvLy9cbiAgICAgICAgICAgIHNvdXJjZVZlcnRleEluZGV4ID0gc291cmNlVmVydGV4LmdldEluZGV4KCk7XG5cbiAgICAgIHZlcnRleC5mb3JFYWNoSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KChpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgpID0+IHtcbiAgICAgICAgY29uc3QgdGFyZ2V0VmVydGV4ID0gaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4LCAgLy8vXG4gICAgICAgICAgICAgIHRhcmdldFZlcnRleEluZGV4ID0gdGFyZ2V0VmVydGV4LmdldEluZGV4KCk7XG5cbiAgICAgICAgaWYgKHRhcmdldFZlcnRleEluZGV4IDwgc291cmNlVmVydGV4SW5kZXgpIHtcbiAgICAgICAgICBjb25zdCBzb3VyY2VWZXJ0ZXhOYW1lID0gc291cmNlVmVydGV4LmdldE5hbWUoKSxcbiAgICAgICAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gdGFyZ2V0VmVydGV4LmdldE5hbWUoKSxcbiAgICAgICAgICAgICAgICBlZGdlID0gRWRnZS5mcm9tU291cmNlVmVydGV4TmFtZUFuZFRhcmdldFZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSwgdGFyZ2V0VmVydGV4TmFtZSksXG4gICAgICAgICAgICAgICAgY3ljbGljRWRnZSA9IGVkZ2U7ICAvLy9cblxuICAgICAgICAgIGN5Y2xpY0VkZ2VzLnB1c2goY3ljbGljRWRnZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBzb3VyY2VWZXJ0ZXhcbiAgICB9KTtcblxuICAgIHJldHVybiBjeWNsaWNFZGdlcztcbiAgfVxuXG4gIGFyZUN5Y2xlc1ByZXNlbnQoKSB7XG4gICAgY29uc3QgdmVydGV4ZXMgPSB0aGlzLmdldFZlcnRleGVzKCksXG4gICAgICAgICAgY3ljbGVzUHJlc2VudCA9IHZlcnRleGVzLnNvbWUoKHZlcnRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlVmVydGV4ID0gdmVydGV4LCAgLy8vXG4gICAgICAgICAgICAgICAgICBzb3VyY2VWZXJ0ZXhJbmRleCA9IHNvdXJjZVZlcnRleC5nZXRJbmRleCgpLFxuICAgICAgICAgICAgICAgICAgY3ljbGljRWRnZVByZXNlbnQgPSB2ZXJ0ZXguc29tZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCgoaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldFZlcnRleCA9IGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCwgIC8vL1xuICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRWZXJ0ZXhJbmRleCA9IHRhcmdldFZlcnRleC5nZXRJbmRleCgpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXRWZXJ0ZXhJbmRleCA8IHNvdXJjZVZlcnRleEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAoY3ljbGljRWRnZVByZXNlbnQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICByZXR1cm4gY3ljbGVzUHJlc2VudDtcbiAgfVxuXG4gIGlzRWRnZVByZXNlbnQoZWRnZSkge1xuICAgIGxldCBlZGdlUHJlc2VudCA9IGZhbHNlO1xuXG4gICAgY29uc3Qgc291cmNlVmVydGV4TmFtZSA9IGVkZ2UuZ2V0U291cmNlVmVydGV4TmFtZSgpLFxuICAgICAgICAgIHNvdXJjZVZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUpO1xuXG4gICAgaWYgKHNvdXJjZVZlcnRleCAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgdGFyZ2V0VmVydGV4TmFtZSA9IGVkZ2UuZ2V0VGFyZ2V0VmVydGV4TmFtZSgpLFxuICAgICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSk7XG5cbiAgICAgIGlmICh0YXJnZXRWZXJ0ZXggIT09IG51bGwpIHtcbiAgICAgICAgZWRnZVByZXNlbnQgPSBzb3VyY2VWZXJ0ZXguaXNFZGdlUHJlc2VudEJ5VGFyZ2V0VmVydGV4KHRhcmdldFZlcnRleCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGVkZ2VQcmVzZW50O1xuICB9XG5cbiAgaXNWZXJ0ZXhQcmVzZW50QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBjb25zdCB2ZXJ0ZXhOYW1lcyA9IHRoaXMuZ2V0VmVydGV4TmFtZXMoKSxcbiAgICAgICAgICB2ZXJ0ZXhOYW1lc0luY2x1ZGVzVmVydGV4TmFtZSA9IHZlcnRleE5hbWVzLmluY2x1ZGVzKHZlcnRleE5hbWUpLFxuICAgICAgICAgIHZlcnRleFByZXNlbnQgPSB2ZXJ0ZXhOYW1lc0luY2x1ZGVzVmVydGV4TmFtZTsgIC8vL1xuXG4gICAgcmV0dXJuIHZlcnRleFByZXNlbnQ7XG4gIH1cblxuICBnZXRJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lc0J5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgdmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodmVydGV4TmFtZSksXG4gICAgICAgICAgaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXMgPSB2ZXJ0ZXguZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXMoKTtcblxuICAgIHJldHVybiBpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lcztcbiAgfVxuXG4gIGdldEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXNCeVZlcnRleE5hbWUodmVydGV4TmFtZSkge1xuICAgIGNvbnN0IHZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpLFxuICAgICAgICAgIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXMgPSB2ZXJ0ZXguZ2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcygpO1xuXG4gICAgcmV0dXJuIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXM7XG4gIH1cblxuICBpc0VkZ2VQcmVzZW50QnlTb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgZWRnZSA9IEVkZ2UuZnJvbVNvdXJjZVZlcnRleE5hbWVBbmRUYXJnZXRWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUsIHRhcmdldFZlcnRleE5hbWUpLFxuICAgICAgICAgIGVkZ2VQcmVzZW50ID0gdGhpcy5pc0VkZ2VQcmVzZW50KGVkZ2UpO1xuXG4gICAgcmV0dXJuIGVkZ2VQcmVzZW50O1xuICB9XG5cbiAgYWRkVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBjb25zdCB2ZXJ0ZXhQcmVzZW50ID0gdGhpcy5pc1ZlcnRleFByZXNlbnRCeVZlcnRleE5hbWUodmVydGV4TmFtZSk7XG5cbiAgICBpZiAoIXZlcnRleFByZXNlbnQpIHtcbiAgICAgIGNvbnN0IHZlcnRleE5hbWVzID0gdGhpcy5nZXRWZXJ0ZXhOYW1lcygpLFxuICAgICAgICAgICAgdmVydGV4TmFtZXNMZW5ndGggPSB2ZXJ0ZXhOYW1lcy5sZW5ndGgsXG4gICAgICAgICAgICBuYW1lID0gdmVydGV4TmFtZSwgIC8vL1xuICAgICAgICAgICAgaW5kZXggPSB2ZXJ0ZXhOYW1lc0xlbmd0aCwgLy8vXG4gICAgICAgICAgICB2ZXJ0ZXggPSBWZXJ0ZXguZnJvbU5hbWVBbmRJbmRleChuYW1lLCBpbmRleCk7XG5cbiAgICAgIHRoaXMuc2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUsIHZlcnRleCk7XG4gICAgfVxuXG4gICAgY29uc3QgdmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodmVydGV4TmFtZSk7XG5cbiAgICByZXR1cm4gdmVydGV4O1xuICB9XG5cbiAgcmVtb3ZlVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBjb25zdCB2ZXJ0ZXhQcmVzZW50ID0gdGhpcy5pc1ZlcnRleFByZXNlbnRCeVZlcnRleE5hbWUodmVydGV4TmFtZSk7XG5cbiAgICBpZiAoIXZlcnRleFByZXNlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB2ZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKTtcblxuICAgIHZlcnRleC5mb3JFYWNoSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KChpbW1lZGlhdGVTdWNjZXNzVmVydGV4KSA9PiB7XG4gICAgICBjb25zdCBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCA9IHZlcnRleDsgIC8vL1xuXG4gICAgICBpbW1lZGlhdGVTdWNjZXNzVmVydGV4LnJlbW92ZUltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KTtcbiAgICB9KTtcblxuICAgIHZlcnRleC5mb3JFYWNoSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgoKGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KSA9PiB7XG4gICAgICBjb25zdCBpbW1lZGlhdGVTdWNjZXNzVmVydGV4ID0gdmVydGV4OyAgLy8vXG5cbiAgICAgIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4LnJlbW92ZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleChpbW1lZGlhdGVTdWNjZXNzVmVydGV4KTtcbiAgICB9KTtcblxuICAgIHRoaXMuZGVsZXRlVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpO1xuXG4gICAgY29uc3QgdmVydGV4ZXMgPSB0aGlzLmdldFZlcnRleGVzKCksXG4gICAgICAgICAgZGVsZXRlZFZlcnRleCA9IHZlcnRleCwgLy8vXG4gICAgICAgICAgZGVsZXRlZFZlcnRleEluZGV4ID0gZGVsZXRlZFZlcnRleC5nZXRJbmRleCgpO1xuXG4gICAgdmVydGV4ZXMuZm9yRWFjaCgodmVydGV4KSA9PiB7XG4gICAgICBjb25zdCB2ZXJ0ZXhJbmRleCA9IHZlcnRleC5nZXRJbmRleCgpO1xuXG4gICAgICBpZiAodmVydGV4SW5kZXggPiBkZWxldGVkVmVydGV4SW5kZXgpIHtcbiAgICAgICAgdmVydGV4LmRlY3JlbWVudEluZGV4KCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmZpbHRlckN5Y2xpY0VkZ2VzKCk7XG4gIH1cblxuICBhZGRWZXJ0ZXhlc0J5VmVydGV4TmFtZXModmVydGV4TmFtZXMpIHtcbiAgICB2ZXJ0ZXhOYW1lcy5mb3JFYWNoKCh2ZXJ0ZXhOYW1lKSA9PiB7XG4gICAgICB0aGlzLmFkZFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJlbW92ZVZlcnRleGVzQnlWZXJ0ZXhOYW1lcyh2ZXJ0ZXhOYW1lcykge1xuICAgIHZlcnRleE5hbWVzLmZvckVhY2goKHZlcnRleE5hbWUpID0+IHtcbiAgICAgIHRoaXMucmVtb3ZlVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpO1xuICAgIH0pO1xuICB9XG5cbiAgYWRkRWRnZShlZGdlKSB7XG4gICAgY29uc3Qgc291cmNlVmVydGV4TmFtZSA9IGVkZ2UuZ2V0U291cmNlVmVydGV4TmFtZSgpLFxuICAgICAgICAgIHRhcmdldFZlcnRleE5hbWUgPSBlZGdlLmdldFRhcmdldFZlcnRleE5hbWUoKTtcblxuICAgIGlmIChzb3VyY2VWZXJ0ZXhOYW1lID09PSB0YXJnZXRWZXJ0ZXhOYW1lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc291cmNlVmVydGV4ID0gdGhpcy5hZGRWZXJ0ZXhCeVZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSksXG4gICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5hZGRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSksXG4gICAgICAgICAgZWRnZVByZXNlbnQgPSBzb3VyY2VWZXJ0ZXguaXNFZGdlUHJlc2VudEJ5VGFyZ2V0VmVydGV4KHRhcmdldFZlcnRleCk7XG5cbiAgICBpZiAoZWRnZVByZXNlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2VWZXJ0ZXhJbmRleCA9IHNvdXJjZVZlcnRleC5nZXRJbmRleCgpLFxuICAgICAgICAgIHRhcmdldFZlcnRleEluZGV4ID0gdGFyZ2V0VmVydGV4LmdldEluZGV4KCk7XG5cbiAgICBpZiAoc291cmNlVmVydGV4SW5kZXggPiB0YXJnZXRWZXJ0ZXhJbmRleCkge1xuICAgICAgdGhpcy5yZW9yZGVyVmVydGV4ZXNCeVNvdXJjZVZlcnRleEFuZFRhcmdldFZlcnRleChzb3VyY2VWZXJ0ZXgsIHRhcmdldFZlcnRleCk7XG4gICAgfVxuXG4gICAgY29uc3QgaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXggPSBzb3VyY2VWZXJ0ZXgsIC8vL1xuICAgICAgICAgIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCA9IHRhcmdldFZlcnRleDsgLy8vXG5cbiAgICBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleC5hZGRJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgoaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KTtcblxuICAgIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleC5hZGRJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleChpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCk7XG4gIH1cblxuICBhZGRFZGdlcyhlZGdlcykge1xuICAgIGVkZ2VzLmZvckVhY2goKGVkZ2UpID0+IHtcbiAgICAgIHRoaXMuYWRkRWRnZShlZGdlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJlbW92ZUVkZ2UoZWRnZSwgcmVtb3ZlU3RyYW5kZWRWZXJ0ZXhlcykge1xuICAgIGNvbnN0IHNvdXJjZVZlcnRleE5hbWUgPSBlZGdlLmdldFNvdXJjZVZlcnRleE5hbWUoKSxcbiAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gZWRnZS5nZXRUYXJnZXRWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgc291cmNlVmVydGV4ID0gdGhpcy5hZGRWZXJ0ZXhCeVZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSksXG4gICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5hZGRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSksXG4gICAgICAgICAgZWRnZVByZXNlbnQgPSBzb3VyY2VWZXJ0ZXguaXNFZGdlUHJlc2VudEJ5VGFyZ2V0VmVydGV4KHRhcmdldFZlcnRleCk7XG5cbiAgICBpZiAoIWVkZ2VQcmVzZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc291cmNlVmVydGV4LnJlbW92ZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCh0YXJnZXRWZXJ0ZXgpO1xuXG4gICAgdGFyZ2V0VmVydGV4LnJlbW92ZUltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KHNvdXJjZVZlcnRleCk7XG5cbiAgICBpZiAocmVtb3ZlU3RyYW5kZWRWZXJ0ZXhlcykge1xuICAgICAgY29uc3Qgc291cmNlVmVydGV4U3RyYW5kZWQgPSBzb3VyY2VWZXJ0ZXguaXNTdHJhbmRlZCgpLFxuICAgICAgICAgICAgdGFyZ2V0VmVydGV4U3RyYW5kZWQgPSB0YXJnZXRWZXJ0ZXguaXNTdHJhbmRlZCgpO1xuXG4gICAgICBpZiAoc291cmNlVmVydGV4U3RyYW5kZWQpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVWZXJ0ZXhCeVZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0YXJnZXRWZXJ0ZXhTdHJhbmRlZCkge1xuICAgICAgICB0aGlzLnJlbW92ZVZlcnRleEJ5VmVydGV4TmFtZSh0YXJnZXRWZXJ0ZXhOYW1lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmZpbHRlckN5Y2xpY0VkZ2VzKCk7XG4gIH1cblxuICByZW1vdmVFZGdlcyhlZGdlcywgcmVtb3ZlU3RyYW5kZWRWZXJ0ZXhlcyA9IGZhbHNlKSB7XG4gICAgZWRnZXMuZm9yRWFjaCgoZWRnZSkgPT4ge1xuICAgICAgdGhpcy5yZW1vdmVFZGdlKGVkZ2UsIHJlbW92ZVN0cmFuZGVkVmVydGV4ZXMpO1xuICAgIH0pO1xuICB9XG5cbiAgcmVtb3ZlQWxsRWRnZXNBbmRWZXJ0ZXhlcygpIHtcbiAgICB0aGlzLnZlcnRleE1hcCA9IHt9O1xuICB9XG5cbiAgYWRkRWRnZUJ5U291cmNlVmVydGV4TmFtZUFuZFRhcmdldFZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSwgdGFyZ2V0VmVydGV4TmFtZSkge1xuICAgIGNvbnN0IGVkZ2UgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgIHRoaXMuYWRkRWRnZShlZGdlKTtcbiAgfVxuXG4gIHJlb3JkZXJWZXJ0ZXhlc0J5U291cmNlVmVydGV4QW5kVGFyZ2V0VmVydGV4KHNvdXJjZVZlcnRleCwgdGFyZ2V0VmVydGV4KSB7XG4gICAgY29uc3Qgc291cmNlVmVydGV4Rm9yd2FyZHNSZWFjaGFibGUgPSB0YXJnZXRWZXJ0ZXguaXNWZXJ0ZXhGb3J3YXJkc1JlYWNoYWJsZShzb3VyY2VWZXJ0ZXgpO1xuXG4gICAgaWYgKHNvdXJjZVZlcnRleEZvcndhcmRzUmVhY2hhYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyA9IHRhcmdldFZlcnRleC5yZXRyaWV2ZUZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXMoKSxcbiAgICAgICAgICBiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyA9IHNvdXJjZVZlcnRleC5yZXRyaWV2ZUJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzKCk7XG5cbiAgICBvcmRlclZlcnRleGVzKGJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzKTtcblxuICAgIG9yZGVyVmVydGV4ZXMoZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyk7XG5cbiAgICBjb25zdCByZWFjaGFibGVWZXJ0ZXhlcyA9IFtcbiAgICAgICAgICAgIC4uLmJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzLFxuICAgICAgICAgICAgLi4uZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlc1xuICAgICAgICAgIF0sXG4gICAgICAgICAgcmVhY2hhYmxlSW5kZXhlcyA9IGluZGV4ZXNGcm9tVmVydGV4ZXMocmVhY2hhYmxlVmVydGV4ZXMpO1xuXG4gICAgb3JkZXJJbmRleGVzKHJlYWNoYWJsZUluZGV4ZXMpO1xuXG4gICAgcmVhY2hhYmxlVmVydGV4ZXMuZm9yRWFjaCgocmVhY2hhYmxlVmVydGV4LCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgcmVhY2hhYmxlSW5kZXggPSByZWFjaGFibGVJbmRleGVzW2luZGV4XTtcblxuICAgICAgaW5kZXggPSByZWFjaGFibGVJbmRleDsgLy8vXG5cbiAgICAgIHJlYWNoYWJsZVZlcnRleC5zZXRJbmRleChpbmRleCk7XG4gICAgfSk7XG4gIH1cblxuICBmaWx0ZXJDeWNsaWNFZGdlcygpIHtcbiAgICBjb25zdCBjeWNsaWNFZGdlcyA9IHRoaXMuZ2V0Q3ljbGljRWRnZXMoKSxcbiAgICAgICAgICBlZGdlcyA9IGN5Y2xpY0VkZ2VzOyAgLy8vXG5cbiAgICBlZGdlcy5mb3JFYWNoKChlZGdlKSA9PiB7XG4gICAgICBjb25zdCBzb3VyY2VWZXJ0ZXhOYW1lID0gZWRnZS5nZXRTb3VyY2VWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gZWRnZS5nZXRUYXJnZXRWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgICBzb3VyY2VWZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lKSxcbiAgICAgICAgICAgIHRhcmdldFZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHRhcmdldFZlcnRleE5hbWUpLFxuICAgICAgICAgICAgc291cmNlVmVydGV4Rm9yd2FyZHNSZWFjaGFibGUgPSB0YXJnZXRWZXJ0ZXguaXNWZXJ0ZXhGb3J3YXJkc1JlYWNoYWJsZShzb3VyY2VWZXJ0ZXgpO1xuXG4gICAgICBpZiAoIXNvdXJjZVZlcnRleEZvcndhcmRzUmVhY2hhYmxlKSB7XG4gICAgICAgIHRoaXMucmVvcmRlclZlcnRleGVzQnlTb3VyY2VWZXJ0ZXhBbmRUYXJnZXRWZXJ0ZXgoc291cmNlVmVydGV4LCB0YXJnZXRWZXJ0ZXgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgc2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUsIHZlcnRleCkge1xuICAgIHRoaXMudmVydGV4TWFwW3ZlcnRleE5hbWVdID0gdmVydGV4O1xuICB9XG5cbiAgZGVsZXRlVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBkZWxldGUgdGhpcy52ZXJ0ZXhNYXBbdmVydGV4TmFtZV07XG4gIH1cblxuICBzdGF0aWMgZnJvbU5vdGhpbmcoKSB7XG4gICAgY29uc3QgdmVydGV4TWFwID0ge30sXG4gICAgICAgICAgZGlyZWN0ZWRHcmFwaCA9IG5ldyBEaXJlY3RlZEdyYXBoKHZlcnRleE1hcCk7XG4gICAgXG4gICAgcmV0dXJuIGRpcmVjdGVkR3JhcGg7ICAgIFxuICB9XG59XG4iXSwibmFtZXMiOlsiRGlyZWN0ZWRHcmFwaCIsImZpcnN0IiwiYXJyYXlVdGlsaXRpZXMiLCJ2ZXJ0ZXhNYXAiLCJnZXRWZXJ0ZXhOYXAiLCJnZXRWZXJ0ZXhlcyIsInZlcnRleE1hcFZhbHVlcyIsIk9iamVjdCIsInZhbHVlcyIsInZlcnRleGVzIiwiZ2V0VmVydGV4TmFtZXMiLCJ2ZXJ0ZXhNYXBLZXlzIiwia2V5cyIsInZlcnRleE5hbWVzIiwiZ2V0T3JkZXJlZFZlcnRleE5hbWVzIiwib3JkZXJWZXJ0ZXhlcyIsIm9yZGVyZWRWZXJ0ZXhlcyIsIm9yZGVyZWRWZXJ0ZXhOYW1lcyIsInZlcnRleE5hbWVzRnJvbVZlcnRleGVzIiwiZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lIiwidmVydGV4TmFtZSIsInZlcnRleFByZXNlbnQiLCJpc1ZlcnRleFByZXNlbnRCeVZlcnRleE5hbWUiLCJ2ZXJ0ZXgiLCJnZXRFZGdlc0J5U291cmNlVmVydGV4TmFtZSIsInNvdXJjZVZlcnRleE5hbWUiLCJlZGdlcyIsInNvdXJjZVZlcnRleCIsImltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzIiwiZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMiLCJpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lcyIsInRhcmdldFZlcnRleE5hbWVzIiwiZm9yRWFjaCIsInRhcmdldFZlcnRleE5hbWUiLCJlZGdlIiwiRWRnZSIsImZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZSIsInB1c2giLCJnZXRFZGdlc0J5VGFyZ2V0VmVydGV4TmFtZSIsInRhcmdldFZlcnRleCIsImltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMiLCJnZXRJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzIiwiaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcyIsInNvdXJjZVZlcnRleE5hbWVzIiwiZ2V0Rmlyc3RDeWNsZSIsImZpcnN0Q3ljbGUiLCJjeWNsZXNQcmVzZW50IiwiYXJlQ3ljbGVzUHJlc2VudCIsImN5Y2xpY0VkZ2VzIiwiZ2V0Q3ljbGljRWRnZXMiLCJmaXJzdEN5Y2xpY0VkZ2UiLCJnZXRTb3VyY2VWZXJ0ZXhOYW1lIiwiZ2V0VGFyZ2V0VmVydGV4TmFtZSIsImZvcndhcmRzRGVwdGhGaXJzdFNlYXJjaCIsInByZWRlY2Vzc29yVmVydGV4ZXMiLCJ0ZXJtaW5hdGUiLCJjeWNsZSIsIkN5Y2xlIiwiZnJvbVNvdXJjZVZlcnRleEFuZFByZWRlY2Vzc29yVmVydGV4ZXMiLCJzb3VyY2VWZXJ0ZXhJbmRleCIsImdldEluZGV4IiwiZm9yRWFjaEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsImltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsInRhcmdldFZlcnRleEluZGV4IiwiZ2V0TmFtZSIsImN5Y2xpY0VkZ2UiLCJzb21lIiwiY3ljbGljRWRnZVByZXNlbnQiLCJzb21lSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4IiwiaXNFZGdlUHJlc2VudCIsImVkZ2VQcmVzZW50IiwiaXNFZGdlUHJlc2VudEJ5VGFyZ2V0VmVydGV4IiwidmVydGV4TmFtZXNJbmNsdWRlc1ZlcnRleE5hbWUiLCJpbmNsdWRlcyIsImdldEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleE5hbWVzQnlWZXJ0ZXhOYW1lIiwiZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXMiLCJnZXRJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleE5hbWVzQnlWZXJ0ZXhOYW1lIiwiZ2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcyIsImlzRWRnZVByZXNlbnRCeVNvdXJjZVZlcnRleE5hbWVBbmRUYXJnZXRWZXJ0ZXhOYW1lIiwiYWRkVmVydGV4QnlWZXJ0ZXhOYW1lIiwidmVydGV4TmFtZXNMZW5ndGgiLCJsZW5ndGgiLCJuYW1lIiwiaW5kZXgiLCJWZXJ0ZXgiLCJmcm9tTmFtZUFuZEluZGV4Iiwic2V0VmVydGV4QnlWZXJ0ZXhOYW1lIiwicmVtb3ZlVmVydGV4QnlWZXJ0ZXhOYW1lIiwiaW1tZWRpYXRlU3VjY2Vzc1ZlcnRleCIsImltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4IiwicmVtb3ZlSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJmb3JFYWNoSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJyZW1vdmVJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgiLCJkZWxldGVWZXJ0ZXhCeVZlcnRleE5hbWUiLCJkZWxldGVkVmVydGV4IiwiZGVsZXRlZFZlcnRleEluZGV4IiwidmVydGV4SW5kZXgiLCJkZWNyZW1lbnRJbmRleCIsImZpbHRlckN5Y2xpY0VkZ2VzIiwiYWRkVmVydGV4ZXNCeVZlcnRleE5hbWVzIiwicmVtb3ZlVmVydGV4ZXNCeVZlcnRleE5hbWVzIiwiYWRkRWRnZSIsInJlb3JkZXJWZXJ0ZXhlc0J5U291cmNlVmVydGV4QW5kVGFyZ2V0VmVydGV4IiwiYWRkSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4IiwiYWRkSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJhZGRFZGdlcyIsInJlbW92ZUVkZ2UiLCJyZW1vdmVTdHJhbmRlZFZlcnRleGVzIiwic291cmNlVmVydGV4U3RyYW5kZWQiLCJpc1N0cmFuZGVkIiwidGFyZ2V0VmVydGV4U3RyYW5kZWQiLCJyZW1vdmVFZGdlcyIsInJlbW92ZUFsbEVkZ2VzQW5kVmVydGV4ZXMiLCJhZGRFZGdlQnlTb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZSIsInNvdXJjZVZlcnRleEZvcndhcmRzUmVhY2hhYmxlIiwiaXNWZXJ0ZXhGb3J3YXJkc1JlYWNoYWJsZSIsImZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXMiLCJyZXRyaWV2ZUZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXMiLCJiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyIsInJldHJpZXZlQmFja3dhcmRzUmVhY2hhYmxlVmVydGV4ZXMiLCJyZWFjaGFibGVWZXJ0ZXhlcyIsInJlYWNoYWJsZUluZGV4ZXMiLCJpbmRleGVzRnJvbVZlcnRleGVzIiwib3JkZXJJbmRleGVzIiwicmVhY2hhYmxlVmVydGV4IiwicmVhY2hhYmxlSW5kZXgiLCJzZXRJbmRleCIsImZyb21Ob3RoaW5nIiwiZGlyZWN0ZWRHcmFwaCJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7ZUFhcUJBOzs7eUJBWFU7MkRBRWQ7NERBQ0M7NkRBQ0M7cUJBRStCO3VCQUNLOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUV2RCxJQUFNLEFBQUVDLFFBQVVDLHlCQUFjLENBQXhCRDtBQUVPLElBQUEsQUFBTUQsOEJBQU47YUFBTUEsY0FDUEcsU0FBUztnQ0FERkg7UUFFakIsSUFBSSxDQUFDRyxTQUFTLEdBQUdBOztrQkFGQUg7O1lBS25CSSxLQUFBQTttQkFBQUEsU0FBQUE7Z0JBQ0UsT0FBTyxJQUFJLENBQUNELFNBQVM7WUFDdkI7OztZQUVBRSxLQUFBQTttQkFBQUEsU0FBQUE7Z0JBQ0UsSUFBTUMsa0JBQWtCQyxPQUFPQyxNQUFNLENBQUMsSUFBSSxDQUFDTCxTQUFTLEdBQzlDTSxXQUFXSCxpQkFBaUIsR0FBRztnQkFFckMsT0FBT0c7WUFDVDs7O1lBRUFDLEtBQUFBO21CQUFBQSxTQUFBQTtnQkFDRSxJQUFNQyxnQkFBZ0JKLE9BQU9LLElBQUksQ0FBQyxJQUFJLENBQUNULFNBQVMsR0FDMUNVLGNBQWNGLGVBQWdCLEdBQUc7Z0JBRXZDLE9BQU9FO1lBQ1Q7OztZQUVBQyxLQUFBQTttQkFBQUEsU0FBQUE7Z0JBQ0UsSUFBTUwsV0FBVyxJQUFJLENBQUNKLFdBQVc7Z0JBRWpDVSxJQUFBQSxzQkFBYSxFQUFDTjtnQkFFZCxJQUFNTyxrQkFBa0JQLFVBQ2xCUSxxQkFBcUJDLElBQUFBLGdDQUF1QixFQUFDRjtnQkFFbkQsT0FBT0M7WUFDVDs7O1lBRUFFLEtBQUFBO21CQUFBQSxTQUFBQSxzQkFBc0JDLFVBQVU7Z0JBQzlCLElBQU1DLGdCQUFnQixJQUFJLENBQUNDLDJCQUEyQixDQUFDRixhQUNqREcsU0FBU0YsZ0JBQ0UsSUFBSSxDQUFDbEIsU0FBUyxDQUFDaUIsV0FBVyxHQUN4QjtnQkFF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
278
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kaXJlY3RlZEdyYXBoLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgeyBhcnJheVV0aWxpdGllcyB9IGZyb20gXCJuZWNlc3NhcnlcIjtcblxuaW1wb3J0IEVkZ2UgZnJvbSBcIi4vZWRnZVwiO1xuaW1wb3J0IEN5Y2xlIGZyb20gXCIuL2N5Y2xlXCI7XG5pbXBvcnQgVmVydGV4IGZyb20gXCIuL3ZlcnRleFwiO1xuXG5pbXBvcnQgeyBvcmRlckluZGV4ZXMsIGluZGV4ZXNGcm9tVmVydGV4ZXMgfSBmcm9tIFwiLi91dGlsaXRpZXMvaW5kZXhcIjtcbmltcG9ydCB7IG9yZGVyVmVydGV4ZXMsIHZlcnRleE5hbWVzRnJvbVZlcnRleGVzIH0gZnJvbSBcIi4vdXRpbGl0aWVzL3ZlcnRleFwiO1xuXG5jb25zdCB7IGZpcnN0IH0gPSBhcnJheVV0aWxpdGllcztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRGlyZWN0ZWRHcmFwaCB7XG4gIGNvbnN0cnVjdG9yKHZlcnRleE1hcCkge1xuICAgIHRoaXMudmVydGV4TWFwID0gdmVydGV4TWFwO1xuICB9XG5cbiAgZ2V0VmVydGV4TmFwKCkge1xuICAgIHJldHVybiB0aGlzLnZlcnRleE1hcDtcbiAgfVxuXG4gIGdldFZlcnRleGVzKCkge1xuICAgIGNvbnN0IHZlcnRleE1hcFZhbHVlcyA9IE9iamVjdC52YWx1ZXModGhpcy52ZXJ0ZXhNYXApLFxuICAgICAgICAgIHZlcnRleGVzID0gdmVydGV4TWFwVmFsdWVzOyAvLy9cblxuICAgIHJldHVybiB2ZXJ0ZXhlcztcbiAgfVxuXG4gIGdldFZlcnRleE5hbWVzKCkge1xuICAgIGNvbnN0IHZlcnRleE1hcEtleXMgPSBPYmplY3Qua2V5cyh0aGlzLnZlcnRleE1hcCksXG4gICAgICAgICAgdmVydGV4TmFtZXMgPSB2ZXJ0ZXhNYXBLZXlzOyAgLy8vXG5cbiAgICByZXR1cm4gdmVydGV4TmFtZXM7XG4gIH1cblxuICBnZXRPcmRlcmVkVmVydGV4TmFtZXMoKSB7XG4gICAgY29uc3QgdmVydGV4ZXMgPSB0aGlzLmdldFZlcnRleGVzKCk7XG5cbiAgICBvcmRlclZlcnRleGVzKHZlcnRleGVzKTtcblxuICAgIGNvbnN0IG9yZGVyZWRWZXJ0ZXhlcyA9IHZlcnRleGVzLCAvLy9cbiAgICAgICAgICBvcmRlcmVkVmVydGV4TmFtZXMgPSB2ZXJ0ZXhOYW1lc0Zyb21WZXJ0ZXhlcyhvcmRlcmVkVmVydGV4ZXMpO1xuXG4gICAgcmV0dXJuIG9yZGVyZWRWZXJ0ZXhOYW1lcztcbiAgfVxuXG4gIGdldFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgdmVydGV4UHJlc2VudCA9IHRoaXMuaXNWZXJ0ZXhQcmVzZW50QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpLFxuICAgICAgICAgIHZlcnRleCA9IHZlcnRleFByZXNlbnQgP1xuICAgICAgICAgICAgICAgICAgICAgdGhpcy52ZXJ0ZXhNYXBbdmVydGV4TmFtZV0gOlxuICAgICAgICAgICAgICAgICAgICAgICBudWxsO1xuXG4gICAgcmV0dXJuIHZlcnRleDtcbiAgfVxuXG4gIGdldEVkZ2VzQnlTb3VyY2VWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUpIHtcbiAgICBjb25zdCBlZGdlcyA9IFtdLFxuICAgICAgICAgIHNvdXJjZVZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUpO1xuXG4gICAgaWYgKHNvdXJjZVZlcnRleCAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMgPSBzb3VyY2VWZXJ0ZXguZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMoKSxcbiAgICAgICAgICAgIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleE5hbWVzID0gdmVydGV4TmFtZXNGcm9tVmVydGV4ZXMoaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMpLFxuICAgICAgICAgICAgdGFyZ2V0VmVydGV4TmFtZXMgPSBpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lczsgIC8vL1xuXG4gICAgICB0YXJnZXRWZXJ0ZXhOYW1lcy5mb3JFYWNoKCh0YXJnZXRWZXJ0ZXhOYW1lKSA9PiB7XG4gICAgICAgIGNvbnN0IGVkZ2UgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgICAgICBlZGdlcy5wdXNoKGVkZ2UpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVkZ2VzO1xuICB9XG5cbiAgZ2V0RWRnZXNCeVRhcmdldFZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSkge1xuICAgIGNvbnN0IGVkZ2VzID0gW10sXG4gICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSk7XG5cbiAgICBpZiAodGFyZ2V0VmVydGV4ICE9PSBudWxsKSB7XG4gICAgICBjb25zdCBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzID0gdGFyZ2V0VmVydGV4LmdldEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMoKSxcbiAgICAgICAgICAgIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXMgPSB2ZXJ0ZXhOYW1lc0Zyb21WZXJ0ZXhlcyhpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzKSxcbiAgICAgICAgICAgIHNvdXJjZVZlcnRleE5hbWVzID0gaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lczsgIC8vL1xuXG4gICAgICBzb3VyY2VWZXJ0ZXhOYW1lcy5mb3JFYWNoKChzb3VyY2VWZXJ0ZXhOYW1lKSA9PiB7XG4gICAgICAgIGNvbnN0IGVkZ2UgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgICAgICBlZGdlcy5wdXNoKGVkZ2UpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVkZ2VzO1xuICB9XG5cbiAgZ2V0Rmlyc3RDeWNsZSgpIHtcbiAgICBsZXQgZmlyc3RDeWNsZSA9IG51bGw7XG5cbiAgICBjb25zdCBjeWNsZXNQcmVzZW50ID0gdGhpcy5hcmVDeWNsZXNQcmVzZW50KCk7XG5cbiAgICBpZiAoY3ljbGVzUHJlc2VudCkge1xuICAgICAgY29uc3QgY3ljbGljRWRnZXMgPSB0aGlzLmdldEN5Y2xpY0VkZ2VzKCksXG4gICAgICAgICAgICBmaXJzdEN5Y2xpY0VkZ2UgPSBmaXJzdChjeWNsaWNFZGdlcyksXG4gICAgICAgICAgICBzb3VyY2VWZXJ0ZXhOYW1lID0gZmlyc3RDeWNsaWNFZGdlLmdldFNvdXJjZVZlcnRleE5hbWUoKSwgLy8vXG4gICAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gZmlyc3RDeWNsaWNFZGdlLmdldFRhcmdldFZlcnRleE5hbWUoKSwgLy8vXG4gICAgICAgICAgICBzb3VyY2VWZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lKSxcbiAgICAgICAgICAgIHRhcmdldFZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHRhcmdldFZlcnRleE5hbWUpO1xuXG4gICAgICB0YXJnZXRWZXJ0ZXguZm9yd2FyZHNEZXB0aEZpcnN0U2VhcmNoKCh2ZXJ0ZXgsIHByZWRlY2Vzc29yVmVydGV4ZXMpID0+IHtcbiAgICAgICAgbGV0IHRlcm1pbmF0ZSA9IGZhbHNlO1xuXG4gICAgICAgIGlmICh2ZXJ0ZXggPT09IHNvdXJjZVZlcnRleCkge1xuICAgICAgICAgIHRlcm1pbmF0ZSA9IHRydWU7XG5cbiAgICAgICAgICBjb25zdCBjeWNsZSA9IEN5Y2xlLmZyb21Tb3VyY2VWZXJ0ZXhBbmRQcmVkZWNlc3NvclZlcnRleGVzKHNvdXJjZVZlcnRleCwgcHJlZGVjZXNzb3JWZXJ0ZXhlcyk7ICAvLy9cblxuICAgICAgICAgIGZpcnN0Q3ljbGUgPSBjeWNsZTsgLy8vXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGVybWluYXRlO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpcnN0Q3ljbGU7XG4gIH1cblxuICBnZXRDeWNsaWNFZGdlcygpIHtcbiAgICBjb25zdCBjeWNsaWNFZGdlcyA9IFtdLFxuICAgICAgICAgIHZlcnRleGVzID0gdGhpcy5nZXRWZXJ0ZXhlcygpO1xuXG4gICAgdmVydGV4ZXMuZm9yRWFjaCgodmVydGV4KSA9PiB7XG4gICAgICBjb25zdCBzb3VyY2VWZXJ0ZXggPSB2ZXJ0ZXgsICAvLy9cbiAgICAgICAgICAgIHNvdXJjZVZlcnRleEluZGV4ID0gc291cmNlVmVydGV4LmdldEluZGV4KCk7XG5cbiAgICAgIHZlcnRleC5mb3JFYWNoSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KChpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgpID0+IHtcbiAgICAgICAgY29uc3QgdGFyZ2V0VmVydGV4ID0gaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4LCAgLy8vXG4gICAgICAgICAgICAgIHRhcmdldFZlcnRleEluZGV4ID0gdGFyZ2V0VmVydGV4LmdldEluZGV4KCk7XG5cbiAgICAgICAgaWYgKHRhcmdldFZlcnRleEluZGV4IDwgc291cmNlVmVydGV4SW5kZXgpIHtcbiAgICAgICAgICBjb25zdCBzb3VyY2VWZXJ0ZXhOYW1lID0gc291cmNlVmVydGV4LmdldE5hbWUoKSxcbiAgICAgICAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gdGFyZ2V0VmVydGV4LmdldE5hbWUoKSxcbiAgICAgICAgICAgICAgICBlZGdlID0gRWRnZS5mcm9tU291cmNlVmVydGV4TmFtZUFuZFRhcmdldFZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSwgdGFyZ2V0VmVydGV4TmFtZSksXG4gICAgICAgICAgICAgICAgY3ljbGljRWRnZSA9IGVkZ2U7ICAvLy9cblxuICAgICAgICAgIGN5Y2xpY0VkZ2VzLnB1c2goY3ljbGljRWRnZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBzb3VyY2VWZXJ0ZXhcbiAgICB9KTtcblxuICAgIHJldHVybiBjeWNsaWNFZGdlcztcbiAgfVxuXG4gIGFyZUN5Y2xlc1ByZXNlbnQoKSB7XG4gICAgY29uc3QgdmVydGV4ZXMgPSB0aGlzLmdldFZlcnRleGVzKCksXG4gICAgICAgICAgY3ljbGVzUHJlc2VudCA9IHZlcnRleGVzLnNvbWUoKHZlcnRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlVmVydGV4ID0gdmVydGV4LCAgLy8vXG4gICAgICAgICAgICAgICAgICBzb3VyY2VWZXJ0ZXhJbmRleCA9IHNvdXJjZVZlcnRleC5nZXRJbmRleCgpLFxuICAgICAgICAgICAgICAgICAgY3ljbGljRWRnZVByZXNlbnQgPSB2ZXJ0ZXguc29tZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCgoaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldFZlcnRleCA9IGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCwgIC8vL1xuICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRWZXJ0ZXhJbmRleCA9IHRhcmdldFZlcnRleC5nZXRJbmRleCgpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXRWZXJ0ZXhJbmRleCA8IHNvdXJjZVZlcnRleEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAoY3ljbGljRWRnZVByZXNlbnQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICByZXR1cm4gY3ljbGVzUHJlc2VudDtcbiAgfVxuXG4gIGlzRWRnZVByZXNlbnQoZWRnZSkge1xuICAgIGxldCBlZGdlUHJlc2VudCA9IGZhbHNlO1xuXG4gICAgY29uc3Qgc291cmNlVmVydGV4TmFtZSA9IGVkZ2UuZ2V0U291cmNlVmVydGV4TmFtZSgpLFxuICAgICAgICAgIHNvdXJjZVZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUpO1xuXG4gICAgaWYgKHNvdXJjZVZlcnRleCAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgdGFyZ2V0VmVydGV4TmFtZSA9IGVkZ2UuZ2V0VGFyZ2V0VmVydGV4TmFtZSgpLFxuICAgICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSk7XG5cbiAgICAgIGlmICh0YXJnZXRWZXJ0ZXggIT09IG51bGwpIHtcbiAgICAgICAgZWRnZVByZXNlbnQgPSBzb3VyY2VWZXJ0ZXguaXNFZGdlUHJlc2VudEJ5VGFyZ2V0VmVydGV4KHRhcmdldFZlcnRleCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGVkZ2VQcmVzZW50O1xuICB9XG5cbiAgaXNWZXJ0ZXhQcmVzZW50QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBjb25zdCB2ZXJ0ZXhOYW1lcyA9IHRoaXMuZ2V0VmVydGV4TmFtZXMoKSxcbiAgICAgICAgICB2ZXJ0ZXhOYW1lc0luY2x1ZGVzVmVydGV4TmFtZSA9IHZlcnRleE5hbWVzLmluY2x1ZGVzKHZlcnRleE5hbWUpLFxuICAgICAgICAgIHZlcnRleFByZXNlbnQgPSB2ZXJ0ZXhOYW1lc0luY2x1ZGVzVmVydGV4TmFtZTsgIC8vL1xuXG4gICAgcmV0dXJuIHZlcnRleFByZXNlbnQ7XG4gIH1cblxuICBnZXRJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lc0J5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgdmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodmVydGV4TmFtZSksXG4gICAgICAgICAgaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXMgPSB2ZXJ0ZXguZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXMoKTtcblxuICAgIHJldHVybiBpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lcztcbiAgfVxuXG4gIGdldEltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXNCeVZlcnRleE5hbWUodmVydGV4TmFtZSkge1xuICAgIGNvbnN0IHZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpLFxuICAgICAgICAgIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXMgPSB2ZXJ0ZXguZ2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcygpO1xuXG4gICAgcmV0dXJuIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4TmFtZXM7XG4gIH1cblxuICBpc0VkZ2VQcmVzZW50QnlTb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKSB7XG4gICAgY29uc3QgZWRnZSA9IEVkZ2UuZnJvbVNvdXJjZVZlcnRleE5hbWVBbmRUYXJnZXRWZXJ0ZXhOYW1lKHNvdXJjZVZlcnRleE5hbWUsIHRhcmdldFZlcnRleE5hbWUpLFxuICAgICAgICAgIGVkZ2VQcmVzZW50ID0gdGhpcy5pc0VkZ2VQcmVzZW50KGVkZ2UpO1xuXG4gICAgcmV0dXJuIGVkZ2VQcmVzZW50O1xuICB9XG5cbiAgYWRkVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBjb25zdCB2ZXJ0ZXhQcmVzZW50ID0gdGhpcy5pc1ZlcnRleFByZXNlbnRCeVZlcnRleE5hbWUodmVydGV4TmFtZSk7XG5cbiAgICBpZiAoIXZlcnRleFByZXNlbnQpIHtcbiAgICAgIGNvbnN0IHZlcnRleE5hbWVzID0gdGhpcy5nZXRWZXJ0ZXhOYW1lcygpLFxuICAgICAgICAgICAgdmVydGV4TmFtZXNMZW5ndGggPSB2ZXJ0ZXhOYW1lcy5sZW5ndGgsXG4gICAgICAgICAgICBuYW1lID0gdmVydGV4TmFtZSwgIC8vL1xuICAgICAgICAgICAgaW5kZXggPSB2ZXJ0ZXhOYW1lc0xlbmd0aCwgLy8vXG4gICAgICAgICAgICB2ZXJ0ZXggPSBWZXJ0ZXguZnJvbU5hbWVBbmRJbmRleChuYW1lLCBpbmRleCk7XG5cbiAgICAgIHRoaXMuc2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUsIHZlcnRleCk7XG4gICAgfVxuXG4gICAgY29uc3QgdmVydGV4ID0gdGhpcy5nZXRWZXJ0ZXhCeVZlcnRleE5hbWUodmVydGV4TmFtZSk7XG5cbiAgICByZXR1cm4gdmVydGV4O1xuICB9XG5cbiAgcmVtb3ZlVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBjb25zdCB2ZXJ0ZXhQcmVzZW50ID0gdGhpcy5pc1ZlcnRleFByZXNlbnRCeVZlcnRleE5hbWUodmVydGV4TmFtZSk7XG5cbiAgICBpZiAoIXZlcnRleFByZXNlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB2ZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKTtcblxuICAgIHZlcnRleC5mb3JFYWNoSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KChpbW1lZGlhdGVTdWNjZXNzVmVydGV4KSA9PiB7XG4gICAgICBjb25zdCBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCA9IHZlcnRleDsgIC8vL1xuXG4gICAgICBpbW1lZGlhdGVTdWNjZXNzVmVydGV4LnJlbW92ZUltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KTtcbiAgICB9KTtcblxuICAgIHZlcnRleC5mb3JFYWNoSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgoKGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KSA9PiB7XG4gICAgICBjb25zdCBpbW1lZGlhdGVTdWNjZXNzVmVydGV4ID0gdmVydGV4OyAgLy8vXG5cbiAgICAgIGltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4LnJlbW92ZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleChpbW1lZGlhdGVTdWNjZXNzVmVydGV4KTtcbiAgICB9KTtcblxuICAgIHRoaXMuZGVsZXRlVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpO1xuXG4gICAgY29uc3QgdmVydGV4ZXMgPSB0aGlzLmdldFZlcnRleGVzKCksXG4gICAgICAgICAgZGVsZXRlZFZlcnRleCA9IHZlcnRleCwgLy8vXG4gICAgICAgICAgZGVsZXRlZFZlcnRleEluZGV4ID0gZGVsZXRlZFZlcnRleC5nZXRJbmRleCgpO1xuXG4gICAgdmVydGV4ZXMuZm9yRWFjaCgodmVydGV4KSA9PiB7XG4gICAgICBjb25zdCB2ZXJ0ZXhJbmRleCA9IHZlcnRleC5nZXRJbmRleCgpO1xuXG4gICAgICBpZiAodmVydGV4SW5kZXggPiBkZWxldGVkVmVydGV4SW5kZXgpIHtcbiAgICAgICAgdmVydGV4LmRlY3JlbWVudEluZGV4KCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmZpbHRlckN5Y2xpY0VkZ2VzKCk7XG4gIH1cblxuICBhZGRWZXJ0ZXhlc0J5VmVydGV4TmFtZXModmVydGV4TmFtZXMpIHtcbiAgICB2ZXJ0ZXhOYW1lcy5mb3JFYWNoKCh2ZXJ0ZXhOYW1lKSA9PiB7XG4gICAgICB0aGlzLmFkZFZlcnRleEJ5VmVydGV4TmFtZSh2ZXJ0ZXhOYW1lKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJlbW92ZVZlcnRleGVzQnlWZXJ0ZXhOYW1lcyh2ZXJ0ZXhOYW1lcykge1xuICAgIHZlcnRleE5hbWVzLmZvckVhY2goKHZlcnRleE5hbWUpID0+IHtcbiAgICAgIHRoaXMucmVtb3ZlVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpO1xuICAgIH0pO1xuICB9XG5cbiAgYWRkRWRnZShlZGdlKSB7XG4gICAgY29uc3Qgc291cmNlVmVydGV4TmFtZSA9IGVkZ2UuZ2V0U291cmNlVmVydGV4TmFtZSgpLFxuICAgICAgICAgIHRhcmdldFZlcnRleE5hbWUgPSBlZGdlLmdldFRhcmdldFZlcnRleE5hbWUoKTtcblxuICAgIGlmIChzb3VyY2VWZXJ0ZXhOYW1lID09PSB0YXJnZXRWZXJ0ZXhOYW1lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc291cmNlVmVydGV4ID0gdGhpcy5hZGRWZXJ0ZXhCeVZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSksXG4gICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5hZGRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSksXG4gICAgICAgICAgZWRnZVByZXNlbnQgPSBzb3VyY2VWZXJ0ZXguaXNFZGdlUHJlc2VudEJ5VGFyZ2V0VmVydGV4KHRhcmdldFZlcnRleCk7XG5cbiAgICBpZiAoZWRnZVByZXNlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2VWZXJ0ZXhJbmRleCA9IHNvdXJjZVZlcnRleC5nZXRJbmRleCgpLFxuICAgICAgICAgIHRhcmdldFZlcnRleEluZGV4ID0gdGFyZ2V0VmVydGV4LmdldEluZGV4KCk7XG5cbiAgICBpZiAoc291cmNlVmVydGV4SW5kZXggPiB0YXJnZXRWZXJ0ZXhJbmRleCkge1xuICAgICAgdGhpcy5yZW9yZGVyVmVydGV4ZXNCeVNvdXJjZVZlcnRleEFuZFRhcmdldFZlcnRleChzb3VyY2VWZXJ0ZXgsIHRhcmdldFZlcnRleCk7XG4gICAgfVxuXG4gICAgY29uc3QgaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXggPSBzb3VyY2VWZXJ0ZXgsIC8vL1xuICAgICAgICAgIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCA9IHRhcmdldFZlcnRleDsgLy8vXG5cbiAgICBpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleC5hZGRJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgoaW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4KTtcblxuICAgIGltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleC5hZGRJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleChpbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleCk7XG4gIH1cblxuICBhZGRFZGdlcyhlZGdlcykge1xuICAgIGVkZ2VzLmZvckVhY2goKGVkZ2UpID0+IHtcbiAgICAgIHRoaXMuYWRkRWRnZShlZGdlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJlbW92ZUVkZ2UoZWRnZSwgcmVtb3ZlU3RyYW5kZWRWZXJ0ZXhlcykge1xuICAgIGNvbnN0IHNvdXJjZVZlcnRleE5hbWUgPSBlZGdlLmdldFNvdXJjZVZlcnRleE5hbWUoKSxcbiAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gZWRnZS5nZXRUYXJnZXRWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgc291cmNlVmVydGV4ID0gdGhpcy5hZGRWZXJ0ZXhCeVZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSksXG4gICAgICAgICAgdGFyZ2V0VmVydGV4ID0gdGhpcy5hZGRWZXJ0ZXhCeVZlcnRleE5hbWUodGFyZ2V0VmVydGV4TmFtZSksXG4gICAgICAgICAgZWRnZVByZXNlbnQgPSBzb3VyY2VWZXJ0ZXguaXNFZGdlUHJlc2VudEJ5VGFyZ2V0VmVydGV4KHRhcmdldFZlcnRleCk7XG5cbiAgICBpZiAoIWVkZ2VQcmVzZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc291cmNlVmVydGV4LnJlbW92ZUltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCh0YXJnZXRWZXJ0ZXgpO1xuXG4gICAgdGFyZ2V0VmVydGV4LnJlbW92ZUltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4KHNvdXJjZVZlcnRleCk7XG5cbiAgICBpZiAocmVtb3ZlU3RyYW5kZWRWZXJ0ZXhlcykge1xuICAgICAgY29uc3Qgc291cmNlVmVydGV4U3RyYW5kZWQgPSBzb3VyY2VWZXJ0ZXguaXNTdHJhbmRlZCgpLFxuICAgICAgICAgICAgdGFyZ2V0VmVydGV4U3RyYW5kZWQgPSB0YXJnZXRWZXJ0ZXguaXNTdHJhbmRlZCgpO1xuXG4gICAgICBpZiAoc291cmNlVmVydGV4U3RyYW5kZWQpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVWZXJ0ZXhCeVZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0YXJnZXRWZXJ0ZXhTdHJhbmRlZCkge1xuICAgICAgICB0aGlzLnJlbW92ZVZlcnRleEJ5VmVydGV4TmFtZSh0YXJnZXRWZXJ0ZXhOYW1lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmZpbHRlckN5Y2xpY0VkZ2VzKCk7XG4gIH1cblxuICByZW1vdmVFZGdlcyhlZGdlcywgcmVtb3ZlU3RyYW5kZWRWZXJ0ZXhlcyA9IGZhbHNlKSB7XG4gICAgZWRnZXMuZm9yRWFjaCgoZWRnZSkgPT4ge1xuICAgICAgdGhpcy5yZW1vdmVFZGdlKGVkZ2UsIHJlbW92ZVN0cmFuZGVkVmVydGV4ZXMpO1xuICAgIH0pO1xuICB9XG5cbiAgcmVtb3ZlQWxsRWRnZXNBbmRWZXJ0ZXhlcygpIHtcbiAgICB0aGlzLnZlcnRleE1hcCA9IHt9O1xuICB9XG5cbiAgYWRkRWRnZUJ5U291cmNlVmVydGV4TmFtZUFuZFRhcmdldFZlcnRleE5hbWUoc291cmNlVmVydGV4TmFtZSwgdGFyZ2V0VmVydGV4TmFtZSkge1xuICAgIGNvbnN0IGVkZ2UgPSBFZGdlLmZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lLCB0YXJnZXRWZXJ0ZXhOYW1lKTtcblxuICAgIHRoaXMuYWRkRWRnZShlZGdlKTtcbiAgfVxuXG4gIHJlb3JkZXJWZXJ0ZXhlc0J5U291cmNlVmVydGV4QW5kVGFyZ2V0VmVydGV4KHNvdXJjZVZlcnRleCwgdGFyZ2V0VmVydGV4KSB7XG4gICAgY29uc3Qgc291cmNlVmVydGV4Rm9yd2FyZHNSZWFjaGFibGUgPSB0YXJnZXRWZXJ0ZXguaXNWZXJ0ZXhGb3J3YXJkc1JlYWNoYWJsZShzb3VyY2VWZXJ0ZXgpO1xuXG4gICAgaWYgKHNvdXJjZVZlcnRleEZvcndhcmRzUmVhY2hhYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyA9IHRhcmdldFZlcnRleC5yZXRyaWV2ZUZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXMoKSxcbiAgICAgICAgICBiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyA9IHNvdXJjZVZlcnRleC5yZXRyaWV2ZUJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzKCk7XG5cbiAgICBvcmRlclZlcnRleGVzKGJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzKTtcblxuICAgIG9yZGVyVmVydGV4ZXMoZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyk7XG5cbiAgICBjb25zdCByZWFjaGFibGVWZXJ0ZXhlcyA9IFtcbiAgICAgICAgICAgIC4uLmJhY2t3YXJkc1JlYWNoYWJsZVZlcnRleGVzLFxuICAgICAgICAgICAgLi4uZm9yd2FyZHNSZWFjaGFibGVWZXJ0ZXhlc1xuICAgICAgICAgIF0sXG4gICAgICAgICAgcmVhY2hhYmxlSW5kZXhlcyA9IGluZGV4ZXNGcm9tVmVydGV4ZXMocmVhY2hhYmxlVmVydGV4ZXMpO1xuXG4gICAgb3JkZXJJbmRleGVzKHJlYWNoYWJsZUluZGV4ZXMpO1xuXG4gICAgcmVhY2hhYmxlVmVydGV4ZXMuZm9yRWFjaCgocmVhY2hhYmxlVmVydGV4LCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgcmVhY2hhYmxlSW5kZXggPSByZWFjaGFibGVJbmRleGVzW2luZGV4XTtcblxuICAgICAgaW5kZXggPSByZWFjaGFibGVJbmRleDsgLy8vXG5cbiAgICAgIHJlYWNoYWJsZVZlcnRleC5zZXRJbmRleChpbmRleCk7XG4gICAgfSk7XG4gIH1cblxuICBmaWx0ZXJDeWNsaWNFZGdlcygpIHtcbiAgICBjb25zdCBjeWNsaWNFZGdlcyA9IHRoaXMuZ2V0Q3ljbGljRWRnZXMoKSxcbiAgICAgICAgICBlZGdlcyA9IGN5Y2xpY0VkZ2VzOyAgLy8vXG5cbiAgICBlZGdlcy5mb3JFYWNoKChlZGdlKSA9PiB7XG4gICAgICBjb25zdCBzb3VyY2VWZXJ0ZXhOYW1lID0gZWRnZS5nZXRTb3VyY2VWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgICB0YXJnZXRWZXJ0ZXhOYW1lID0gZWRnZS5nZXRUYXJnZXRWZXJ0ZXhOYW1lKCksXG4gICAgICAgICAgICBzb3VyY2VWZXJ0ZXggPSB0aGlzLmdldFZlcnRleEJ5VmVydGV4TmFtZShzb3VyY2VWZXJ0ZXhOYW1lKSxcbiAgICAgICAgICAgIHRhcmdldFZlcnRleCA9IHRoaXMuZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHRhcmdldFZlcnRleE5hbWUpLFxuICAgICAgICAgICAgc291cmNlVmVydGV4Rm9yd2FyZHNSZWFjaGFibGUgPSB0YXJnZXRWZXJ0ZXguaXNWZXJ0ZXhGb3J3YXJkc1JlYWNoYWJsZShzb3VyY2VWZXJ0ZXgpO1xuXG4gICAgICBpZiAoIXNvdXJjZVZlcnRleEZvcndhcmRzUmVhY2hhYmxlKSB7XG4gICAgICAgIHRoaXMucmVvcmRlclZlcnRleGVzQnlTb3VyY2VWZXJ0ZXhBbmRUYXJnZXRWZXJ0ZXgoc291cmNlVmVydGV4LCB0YXJnZXRWZXJ0ZXgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgc2V0VmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUsIHZlcnRleCkge1xuICAgIHRoaXMudmVydGV4TWFwW3ZlcnRleE5hbWVdID0gdmVydGV4O1xuICB9XG5cbiAgZGVsZXRlVmVydGV4QnlWZXJ0ZXhOYW1lKHZlcnRleE5hbWUpIHtcbiAgICBkZWxldGUgdGhpcy52ZXJ0ZXhNYXBbdmVydGV4TmFtZV07XG4gIH1cblxuICBzdGF0aWMgZnJvbU5vdGhpbmcoKSB7XG4gICAgY29uc3QgdmVydGV4TWFwID0ge30sXG4gICAgICAgICAgZGlyZWN0ZWRHcmFwaCA9IG5ldyBEaXJlY3RlZEdyYXBoKHZlcnRleE1hcCk7XG4gICAgXG4gICAgcmV0dXJuIGRpcmVjdGVkR3JhcGg7ICAgIFxuICB9XG59XG4iXSwibmFtZXMiOlsiRGlyZWN0ZWRHcmFwaCIsImZpcnN0IiwiYXJyYXlVdGlsaXRpZXMiLCJ2ZXJ0ZXhNYXAiLCJnZXRWZXJ0ZXhOYXAiLCJnZXRWZXJ0ZXhlcyIsInZlcnRleE1hcFZhbHVlcyIsIk9iamVjdCIsInZhbHVlcyIsInZlcnRleGVzIiwiZ2V0VmVydGV4TmFtZXMiLCJ2ZXJ0ZXhNYXBLZXlzIiwia2V5cyIsInZlcnRleE5hbWVzIiwiZ2V0T3JkZXJlZFZlcnRleE5hbWVzIiwib3JkZXJWZXJ0ZXhlcyIsIm9yZGVyZWRWZXJ0ZXhlcyIsIm9yZGVyZWRWZXJ0ZXhOYW1lcyIsInZlcnRleE5hbWVzRnJvbVZlcnRleGVzIiwiZ2V0VmVydGV4QnlWZXJ0ZXhOYW1lIiwidmVydGV4TmFtZSIsInZlcnRleFByZXNlbnQiLCJpc1ZlcnRleFByZXNlbnRCeVZlcnRleE5hbWUiLCJ2ZXJ0ZXgiLCJnZXRFZGdlc0J5U291cmNlVmVydGV4TmFtZSIsInNvdXJjZVZlcnRleE5hbWUiLCJlZGdlcyIsInNvdXJjZVZlcnRleCIsImltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleGVzIiwiZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4ZXMiLCJpbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXhOYW1lcyIsInRhcmdldFZlcnRleE5hbWVzIiwiZm9yRWFjaCIsInRhcmdldFZlcnRleE5hbWUiLCJlZGdlIiwiRWRnZSIsImZyb21Tb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZSIsInB1c2giLCJnZXRFZGdlc0J5VGFyZ2V0VmVydGV4TmFtZSIsInRhcmdldFZlcnRleCIsImltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4ZXMiLCJnZXRJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleGVzIiwiaW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcyIsInNvdXJjZVZlcnRleE5hbWVzIiwiZ2V0Rmlyc3RDeWNsZSIsImZpcnN0Q3ljbGUiLCJjeWNsZXNQcmVzZW50IiwiYXJlQ3ljbGVzUHJlc2VudCIsImN5Y2xpY0VkZ2VzIiwiZ2V0Q3ljbGljRWRnZXMiLCJmaXJzdEN5Y2xpY0VkZ2UiLCJnZXRTb3VyY2VWZXJ0ZXhOYW1lIiwiZ2V0VGFyZ2V0VmVydGV4TmFtZSIsImZvcndhcmRzRGVwdGhGaXJzdFNlYXJjaCIsInByZWRlY2Vzc29yVmVydGV4ZXMiLCJ0ZXJtaW5hdGUiLCJjeWNsZSIsIkN5Y2xlIiwiZnJvbVNvdXJjZVZlcnRleEFuZFByZWRlY2Vzc29yVmVydGV4ZXMiLCJzb3VyY2VWZXJ0ZXhJbmRleCIsImdldEluZGV4IiwiZm9yRWFjaEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsImltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleCIsInRhcmdldFZlcnRleEluZGV4IiwiZ2V0TmFtZSIsImN5Y2xpY0VkZ2UiLCJzb21lIiwiY3ljbGljRWRnZVByZXNlbnQiLCJzb21lSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4IiwiaXNFZGdlUHJlc2VudCIsImVkZ2VQcmVzZW50IiwiaXNFZGdlUHJlc2VudEJ5VGFyZ2V0VmVydGV4IiwidmVydGV4TmFtZXNJbmNsdWRlc1ZlcnRleE5hbWUiLCJpbmNsdWRlcyIsImdldEltbWVkaWF0ZVN1Y2Nlc3NvclZlcnRleE5hbWVzQnlWZXJ0ZXhOYW1lIiwiZ2V0SW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4TmFtZXMiLCJnZXRJbW1lZGlhdGVQcmVkZWNlc3NvclZlcnRleE5hbWVzQnlWZXJ0ZXhOYW1lIiwiZ2V0SW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXhOYW1lcyIsImlzRWRnZVByZXNlbnRCeVNvdXJjZVZlcnRleE5hbWVBbmRUYXJnZXRWZXJ0ZXhOYW1lIiwiYWRkVmVydGV4QnlWZXJ0ZXhOYW1lIiwidmVydGV4TmFtZXNMZW5ndGgiLCJsZW5ndGgiLCJuYW1lIiwiaW5kZXgiLCJWZXJ0ZXgiLCJmcm9tTmFtZUFuZEluZGV4Iiwic2V0VmVydGV4QnlWZXJ0ZXhOYW1lIiwicmVtb3ZlVmVydGV4QnlWZXJ0ZXhOYW1lIiwiaW1tZWRpYXRlU3VjY2Vzc1ZlcnRleCIsImltbWVkaWF0ZVByZWRlY2Vzc29yVmVydGV4IiwicmVtb3ZlSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJmb3JFYWNoSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJyZW1vdmVJbW1lZGlhdGVTdWNjZXNzb3JWZXJ0ZXgiLCJkZWxldGVWZXJ0ZXhCeVZlcnRleE5hbWUiLCJkZWxldGVkVmVydGV4IiwiZGVsZXRlZFZlcnRleEluZGV4IiwidmVydGV4SW5kZXgiLCJkZWNyZW1lbnRJbmRleCIsImZpbHRlckN5Y2xpY0VkZ2VzIiwiYWRkVmVydGV4ZXNCeVZlcnRleE5hbWVzIiwicmVtb3ZlVmVydGV4ZXNCeVZlcnRleE5hbWVzIiwiYWRkRWRnZSIsInJlb3JkZXJWZXJ0ZXhlc0J5U291cmNlVmVydGV4QW5kVGFyZ2V0VmVydGV4IiwiYWRkSW1tZWRpYXRlU3VjY2Vzc29yVmVydGV4IiwiYWRkSW1tZWRpYXRlUHJlZGVjZXNzb3JWZXJ0ZXgiLCJhZGRFZGdlcyIsInJlbW92ZUVkZ2UiLCJyZW1vdmVTdHJhbmRlZFZlcnRleGVzIiwic291cmNlVmVydGV4U3RyYW5kZWQiLCJpc1N0cmFuZGVkIiwidGFyZ2V0VmVydGV4U3RyYW5kZWQiLCJyZW1vdmVFZGdlcyIsInJlbW92ZUFsbEVkZ2VzQW5kVmVydGV4ZXMiLCJhZGRFZGdlQnlTb3VyY2VWZXJ0ZXhOYW1lQW5kVGFyZ2V0VmVydGV4TmFtZSIsInNvdXJjZVZlcnRleEZvcndhcmRzUmVhY2hhYmxlIiwiaXNWZXJ0ZXhGb3J3YXJkc1JlYWNoYWJsZSIsImZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXMiLCJyZXRyaWV2ZUZvcndhcmRzUmVhY2hhYmxlVmVydGV4ZXMiLCJiYWNrd2FyZHNSZWFjaGFibGVWZXJ0ZXhlcyIsInJldHJpZXZlQmFja3dhcmRzUmVhY2hhYmxlVmVydGV4ZXMiLCJyZWFjaGFibGVWZXJ0ZXhlcyIsInJlYWNoYWJsZUluZGV4ZXMiLCJpbmRleGVzRnJvbVZlcnRleGVzIiwib3JkZXJJbmRleGVzIiwicmVhY2hhYmxlVmVydGV4IiwicmVhY2hhYmxlSW5kZXgiLCJzZXRJbmRleCIsImZyb21Ob3RoaW5nIiwiZGlyZWN0ZWRHcmFwaCJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7K0JBYUE7OztlQUFxQkE7OzsyQkFYVTs2REFFZDs4REFDQzsrREFDQzt1QkFFK0I7eUJBQ0s7Ozs7OztBQUV2RCxNQUFNLEVBQUVDLEtBQUssRUFBRSxHQUFHQyx5QkFBYztBQUVqQixNQUFNRjtJQUNuQixZQUFZRyxTQUFTLENBQUU7UUFDckIsSUFBSSxDQUFDQSxTQUFTLEdBQUdBO0lBQ25CO0lBRUFDLGVBQWU7UUFDYixPQUFPLElBQUksQ0FBQ0QsU0FBUztJQUN2QjtJQUVBRSxjQUFjO1FBQ1osTUFBTUMsa0JBQWtCQyxPQUFPQyxNQUFNLENBQUMsSUFBSSxDQUFDTCxTQUFTLEdBQzlDTSxXQUFXSCxpQkFBaUIsR0FBRztRQUVyQyxPQUFPRztJQUNUO0lBRUFDLGlCQUFpQjtRQUNmLE1BQU1DLGdCQUFnQkosT0FBT0ssSUFBSSxDQUFDLElBQUksQ0FBQ1QsU0FBUyxHQUMxQ1UsY0FBY0YsZUFBZ0IsR0FBRztRQUV2QyxPQUFPRTtJQUNUO0lBRUFDLHdCQUF3QjtRQUN0QixNQUFNTCxXQUFXLElBQUksQ0FBQ0osV0FBVztRQUVqQ1UsSUFBQUEsc0JBQWEsRUFBQ047UUFFZCxNQUFNTyxrQkFBa0JQLFVBQ2xCUSxxQkFBcUJDLElBQUFBLGdDQUF1QixFQUFDRjtRQUVuRCxPQUFPQztJQUNUO0lBRUFFLHNCQUFzQkMsVUFBVSxFQUFFO1FBQ2hDLE1BQU1DLGdCQUFnQixJQUFJLENBQUNDLDJCQUEyQixDQUFDRixhQUNqREcsU0FBU0YsZ0JBQ0UsSUFBSSxDQUFDbEIsU0FBUyxDQUFDaUIsV0FBVyxHQUN4QjtRQUVuQixPQUFPRztJQUNUO0lBRUFDLDJCQUEyQkMsZ0JBQWdCLEVBQUU7UUFDM0MsTUFBTUMsUUFBUSxFQUFFLEVBQ1ZDLGVBQWUsSUFBSSxDQUFDUixxQkFBcUIsQ0FBQ007UUFFaEQsSUFBSUUsaUJBQWlCLE1BQU07WUFDekIsTUFBTUMsNkJB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