@flowmap.gl/layers 8.0.0-alpha.3 → 8.0.0-alpha.7

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.
@@ -1,313 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- /*
11
- * Copyright 2022 FlowmapBlue
12
- *
13
- * Licensed under the Apache License, Version 2.0 (the "License");
14
- * you may not use this file except in compliance with the License.
15
- * You may obtain a copy of the License at
16
- *
17
- * http://www.apache.org/licenses/LICENSE-2.0
18
- *
19
- * Unless required by applicable law or agreed to in writing, software
20
- * distributed under the License is distributed on an "AS IS" BASIS,
21
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
- * See the License for the specific language governing permissions and
23
- * limitations under the License.
24
- *
25
- */
26
- import { CompositeLayer } from '@deck.gl/core';
27
- import { ScatterplotLayer } from '@deck.gl/layers';
28
- import { colorAsRgba, getFlowLineAttributesByIndex, getFlowMapColors, getOuterCircleRadiusByIndex, getLocationCentroidByIndex, isFlowMapData, isFlowMapDataProvider, LocalFlowMapDataProvider, LocationFilterMode, FlowMapAggregateAccessors, } from '@flowmap.gl/data';
29
- import AnimatedFlowLinesLayer from './AnimatedFlowLinesLayer';
30
- import FlowCirclesLayer from './FlowCirclesLayer';
31
- import FlowLinesLayer from './FlowLinesLayer';
32
- import { PickingType, } from './types';
33
- var HighlightType;
34
- (function (HighlightType) {
35
- HighlightType["LOCATION"] = "location";
36
- HighlightType["FLOW"] = "flow";
37
- })(HighlightType || (HighlightType = {}));
38
- export default class FlowMapLayer extends CompositeLayer {
39
- constructor(props) {
40
- super(Object.assign(Object.assign({}, props), { onHover: (info, event) => {
41
- // TODO: if (lastHoverEventStartTimeRef > startTime) {
42
- // // Skipping, because this is not the latest hover event
43
- // return;
44
- // }
45
- this.setState({ highlightedObject: this._getHighlightedObject(info) });
46
- const { onHover } = props;
47
- if (onHover) {
48
- this._getFlowLayerPickingInfo(info).then((info) => onHover(info, event));
49
- }
50
- }, onClick: (info, event) => {
51
- const { onClick } = props;
52
- if (onClick) {
53
- this._getFlowLayerPickingInfo(info).then((info) => {
54
- if (info) {
55
- onClick(info, event);
56
- }
57
- });
58
- }
59
- } }));
60
- }
61
- initializeState() {
62
- this.state = {
63
- accessors: new FlowMapAggregateAccessors(this.props),
64
- dataProvider: this._makeDataProvider(),
65
- layersData: undefined,
66
- highlightedObject: undefined,
67
- };
68
- }
69
- _updateAccessors() {
70
- var _a, _b;
71
- (_b = (_a = this.state) === null || _a === void 0 ? void 0 : _a.dataProvider) === null || _b === void 0 ? void 0 : _b.setAccessors(this.props);
72
- this.setState({ accessors: new FlowMapAggregateAccessors(this.props) });
73
- }
74
- _makeDataProvider() {
75
- const { data } = this.props;
76
- if (isFlowMapDataProvider(data)) {
77
- return data;
78
- }
79
- else if (isFlowMapData(data)) {
80
- const dataProvider = new LocalFlowMapDataProvider(this.props);
81
- dataProvider.setFlowMapData(data);
82
- return dataProvider;
83
- }
84
- throw new Error('FlowMapLayer: data must be a FlowMapDataProvider or FlowMapData');
85
- }
86
- _updateDataProvider() {
87
- this.setState({ dataProvider: this._makeDataProvider() });
88
- }
89
- shouldUpdateState(params) {
90
- const { changeFlags } = params;
91
- // if (this._viewportChanged()) {
92
- // return true;
93
- // }
94
- if (changeFlags.viewportChanged) {
95
- return true;
96
- }
97
- return super.shouldUpdateState(params);
98
- // TODO: be smarter on when to update
99
- // (e.g. ignore viewport changes when adaptiveScalesEnabled and clustering are false)
100
- }
101
- updateState({ oldProps, props, changeFlags }) {
102
- const { dataProvider, highlightedObject } = this.state || {};
103
- if (!dataProvider) {
104
- return;
105
- }
106
- if (changeFlags.propsChanged) {
107
- this._updateAccessors();
108
- }
109
- if (changeFlags.dataChanged) {
110
- this._updateDataProvider();
111
- }
112
- if (changeFlags.viewportChanged || changeFlags.dataChanged) {
113
- this.setState({
114
- highlightedObject: undefined,
115
- });
116
- }
117
- if (changeFlags.viewportChanged || changeFlags.propsOrDataChanged) {
118
- dataProvider.setFlowMapState(this._getFlowMapState());
119
- (() => __awaiter(this, void 0, void 0, function* () {
120
- const layersData = yield dataProvider.getLayersData();
121
- this.setState({ layersData });
122
- }))();
123
- }
124
- }
125
- _getSettingsState() {
126
- const { locationTotalsEnabled, adaptiveScalesEnabled, animationEnabled, clusteringEnabled, clusteringLevel, fadeEnabled, fadeOpacityEnabled, clusteringAuto, darkMode, fadeAmount, colorScheme, } = this.props;
127
- return {
128
- locationTotalsEnabled,
129
- adaptiveScalesEnabled,
130
- animationEnabled,
131
- clusteringEnabled,
132
- clusteringLevel,
133
- fadeEnabled,
134
- fadeOpacityEnabled,
135
- clusteringAuto,
136
- darkMode,
137
- fadeAmount,
138
- colorScheme,
139
- };
140
- }
141
- _getFlowMapState() {
142
- return {
143
- viewport: asViewState(this.context.viewport),
144
- filterState: {
145
- selectedLocations: undefined,
146
- locationFilterMode: LocationFilterMode.ALL,
147
- selectedTimeRange: undefined,
148
- },
149
- settingsState: this._getSettingsState(),
150
- };
151
- }
152
- _getFlowLayerPickingInfo(info) {
153
- var _a;
154
- return __awaiter(this, void 0, void 0, function* () {
155
- const { index, sourceLayer } = info;
156
- const { dataProvider, accessors } = this.state || {};
157
- if (!dataProvider || !accessors) {
158
- return undefined;
159
- }
160
- const commonInfo = {
161
- // ...info,
162
- layer: info.layer,
163
- index: info.index,
164
- x: info.x,
165
- y: info.y,
166
- coordinate: info.coordinate,
167
- };
168
- if (sourceLayer instanceof FlowLinesLayer ||
169
- sourceLayer instanceof AnimatedFlowLinesLayer) {
170
- const flow = index === -1 ? undefined : yield dataProvider.getFlowByIndex(index);
171
- if (flow) {
172
- const origin = yield dataProvider.getLocationById(accessors.getFlowOriginId(flow));
173
- const dest = yield dataProvider.getLocationById(accessors.getFlowDestId(flow));
174
- if (origin && dest) {
175
- return Object.assign(Object.assign({}, commonInfo), { type: PickingType.FLOW, object: flow, origin: origin, dest: dest, count: accessors.getFlowMagnitude(flow) });
176
- }
177
- }
178
- }
179
- else if (sourceLayer instanceof FlowCirclesLayer) {
180
- const location = index === -1 ? undefined : yield dataProvider.getLocationByIndex(index);
181
- if (location) {
182
- const id = accessors.getLocationId(location);
183
- const name = accessors.getLocationName(location);
184
- const totals = yield dataProvider.getTotalsForLocation(id);
185
- const { circleAttributes } = ((_a = this.state) === null || _a === void 0 ? void 0 : _a.layersData) || {};
186
- if (totals && circleAttributes) {
187
- const circleRadius = getOuterCircleRadiusByIndex(circleAttributes, info.index);
188
- return Object.assign(Object.assign({}, commonInfo), { type: PickingType.LOCATION, object: location, id,
189
- name,
190
- totals, circleRadius: circleRadius, event: undefined });
191
- }
192
- }
193
- }
194
- return undefined;
195
- });
196
- }
197
- _getHighlightedObject(info) {
198
- var _a, _b;
199
- const { index, sourceLayer } = info;
200
- if (index < 0)
201
- return undefined;
202
- if (sourceLayer instanceof FlowLinesLayer ||
203
- sourceLayer instanceof AnimatedFlowLinesLayer) {
204
- const { lineAttributes } = ((_a = this.state) === null || _a === void 0 ? void 0 : _a.layersData) || {};
205
- if (lineAttributes) {
206
- return {
207
- type: HighlightType.FLOW,
208
- lineAttributes: getFlowLineAttributesByIndex(lineAttributes, index),
209
- };
210
- }
211
- }
212
- else if (sourceLayer instanceof FlowCirclesLayer) {
213
- const { circleAttributes } = ((_b = this.state) === null || _b === void 0 ? void 0 : _b.layersData) || {};
214
- if (circleAttributes) {
215
- return {
216
- type: HighlightType.LOCATION,
217
- centroid: getLocationCentroidByIndex(circleAttributes, index),
218
- radius: getOuterCircleRadiusByIndex(circleAttributes, index),
219
- };
220
- }
221
- }
222
- return undefined;
223
- }
224
- renderLayers() {
225
- var _a;
226
- const layers = [];
227
- if ((_a = this.state) === null || _a === void 0 ? void 0 : _a.layersData) {
228
- const { layersData, highlightedObject } = this.state;
229
- const { circleAttributes, lineAttributes } = layersData || {};
230
- if (circleAttributes && lineAttributes) {
231
- const flowMapColors = getFlowMapColors(this._getSettingsState());
232
- const outlineColor = colorAsRgba(flowMapColors.outlineColor || (this.props.darkMode ? '#000' : '#fff'));
233
- const commonLineLayerProps = {
234
- data: lineAttributes,
235
- parameters: Object.assign(Object.assign({}, this.props.parameters), {
236
- // prevent z-fighting at non-zero bearing/pitch
237
- depthTest: false }),
238
- };
239
- if (this.props.animationEnabled) {
240
- layers.push(
241
- // @ts-ignore
242
- new AnimatedFlowLinesLayer(Object.assign({}, this.getSubLayerProps(Object.assign(Object.assign({}, commonLineLayerProps), { id: 'animated-flow-lines', drawOutline: false, thicknessUnit: 20 })))));
243
- }
244
- else {
245
- layers.push(new FlowLinesLayer(Object.assign({}, this.getSubLayerProps(Object.assign(Object.assign({}, commonLineLayerProps), { id: 'flow-lines', drawOutline: true, outlineColor: outlineColor })))));
246
- }
247
- layers.push(new FlowCirclesLayer(this.getSubLayerProps({
248
- id: 'circles',
249
- data: circleAttributes,
250
- emptyColor: [0, 0, 0, 255],
251
- emptyOutlineColor: [0, 0, 0, 255],
252
- })));
253
- if (highlightedObject) {
254
- switch (highlightedObject.type) {
255
- case HighlightType.LOCATION:
256
- layers.push(new ScatterplotLayer(Object.assign({}, this.getSubLayerProps({
257
- id: 'location-highlight',
258
- data: [highlightedObject],
259
- pickable: false,
260
- stroked: true,
261
- filled: false,
262
- lineWidthUnits: 'pixels',
263
- getLineWidth: 2,
264
- radiusUnits: 'pixels',
265
- getRadius: (d) => d.radius,
266
- getLineColor: colorAsRgba(this.props.highlightColor),
267
- getPosition: (d) => d.centroid,
268
- }))));
269
- break;
270
- case HighlightType.FLOW:
271
- layers.push(new FlowLinesLayer(Object.assign({}, this.getSubLayerProps({
272
- id: 'flow-highlight',
273
- data: highlightedObject.lineAttributes,
274
- drawOutline: true,
275
- pickable: false,
276
- outlineColor: colorAsRgba(this.props.highlightColor),
277
- outlineThickness: 1,
278
- }))));
279
- break;
280
- }
281
- }
282
- }
283
- }
284
- return layers;
285
- }
286
- }
287
- FlowMapLayer.defaultProps = {
288
- darkMode: true,
289
- fadeAmount: 50,
290
- locationTotalsEnabled: true,
291
- animationEnabled: false,
292
- clusteringEnabled: true,
293
- fadeEnabled: true,
294
- fadeOpacityEnabled: false,
295
- clusteringAuto: true,
296
- clusteringLevel: undefined,
297
- adaptiveScalesEnabled: true,
298
- colorScheme: 'Teal',
299
- highlightColor: 'orange',
300
- };
301
- function asViewState(viewport) {
302
- const { width, height, longitude, latitude, zoom, pitch, bearing } = viewport;
303
- return {
304
- width,
305
- height,
306
- longitude,
307
- latitude,
308
- zoom,
309
- pitch,
310
- bearing,
311
- };
312
- }
313
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmxvd01hcExheWVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0Zsb3dNYXBMYXllci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQzdDLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ2pELE9BQU8sRUFDTCxXQUFXLEVBS1gsNEJBQTRCLEVBQzVCLGdCQUFnQixFQUNoQiwyQkFBMkIsRUFDM0IsMEJBQTBCLEVBQzFCLGFBQWEsRUFDYixxQkFBcUIsRUFFckIsd0JBQXdCLEVBQ3hCLGtCQUFrQixFQUVsQix5QkFBeUIsR0FHMUIsTUFBTSxrQkFBa0IsQ0FBQztBQUMxQixPQUFPLHNCQUFzQixNQUFNLDBCQUEwQixDQUFDO0FBQzlELE9BQU8sZ0JBQWdCLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxjQUFjLE1BQU0sa0JBQWtCLENBQUM7QUFDOUMsT0FBTyxFQUlMLFdBQVcsR0FDWixNQUFNLFNBQVMsQ0FBQztBQXdCakIsSUFBSyxhQUdKO0FBSEQsV0FBSyxhQUFhO0lBQ2hCLHNDQUFxQixDQUFBO0lBQ3JCLDhCQUFhLENBQUE7QUFDZixDQUFDLEVBSEksYUFBYSxLQUFiLGFBQWEsUUFHakI7QUF3QkQsTUFBTSxDQUFDLE9BQU8sT0FBTyxZQUFtQixTQUFRLGNBQWM7SUFpQjVELFlBQW1CLEtBQThCO1FBQy9DLEtBQUssaUNBQ0EsS0FBSyxLQUNSLE9BQU8sRUFBRSxDQUFDLElBQXNCLEVBQUUsS0FBa0IsRUFBRSxFQUFFO2dCQUN0RCxzREFBc0Q7Z0JBQ3RELDREQUE0RDtnQkFDNUQsWUFBWTtnQkFDWixJQUFJO2dCQUNKLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBQyxpQkFBaUIsRUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLEVBQUMsQ0FBQyxDQUFDO2dCQUNyRSxNQUFNLEVBQUMsT0FBTyxFQUFDLEdBQUcsS0FBSyxDQUFDO2dCQUN4QixJQUFJLE9BQU8sRUFBRTtvQkFDWCxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FDaEQsT0FBTyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FDckIsQ0FBQztpQkFDSDtZQUNILENBQUMsRUFDRCxPQUFPLEVBQUUsQ0FBQyxJQUFzQixFQUFFLEtBQWtCLEVBQUUsRUFBRTtnQkFDdEQsTUFBTSxFQUFDLE9BQU8sRUFBQyxHQUFHLEtBQUssQ0FBQztnQkFDeEIsSUFBSSxPQUFPLEVBQUU7b0JBQ1gsSUFBSSxDQUFDLHdCQUF3QixDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO3dCQUNoRCxJQUFJLElBQUksRUFBRTs0QkFDUixPQUFPLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO3lCQUN0QjtvQkFDSCxDQUFDLENBQUMsQ0FBQztpQkFDSjtZQUNILENBQUMsSUFDRCxDQUFDO0lBQ0wsQ0FBQztJQUVELGVBQWU7UUFDYixJQUFJLENBQUMsS0FBSyxHQUFHO1lBQ1gsU0FBUyxFQUFFLElBQUkseUJBQXlCLENBQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztZQUMxRCxZQUFZLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQ3RDLFVBQVUsRUFBRSxTQUFTO1lBQ3JCLGlCQUFpQixFQUFFLFNBQVM7U0FDN0IsQ0FBQztJQUNKLENBQUM7SUFFTyxnQkFBZ0I7O1FBQ3RCLE1BQUEsTUFBQSxJQUFJLENBQUMsS0FBSywwQ0FBRSxZQUFZLDBDQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFDLFNBQVMsRUFBRSxJQUFJLHlCQUF5QixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBQyxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVPLGlCQUFpQjtRQUN2QixNQUFNLEVBQUMsSUFBSSxFQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUMxQixJQUFJLHFCQUFxQixDQUFPLElBQUksQ0FBQyxFQUFFO1lBQ3JDLE9BQU8sSUFBSSxDQUFDO1NBQ2I7YUFBTSxJQUFJLGFBQWEsQ0FBTyxJQUFJLENBQUMsRUFBRTtZQUNwQyxNQUFNLFlBQVksR0FBRyxJQUFJLHdCQUF3QixDQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNwRSxZQUFZLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xDLE9BQU8sWUFBWSxDQUFDO1NBQ3JCO1FBQ0QsTUFBTSxJQUFJLEtBQUssQ0FDYixpRUFBaUUsQ0FDbEUsQ0FBQztJQUNKLENBQUM7SUFFTyxtQkFBbUI7UUFDekIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsRUFBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVELGlCQUFpQixDQUFDLE1BQTJCO1FBQzNDLE1BQU0sRUFBQyxXQUFXLEVBQUMsR0FBRyxNQUFNLENBQUM7UUFDN0IsaUNBQWlDO1FBQ2pDLGlCQUFpQjtRQUNqQixJQUFJO1FBQ0osSUFBSSxXQUFXLENBQUMsZUFBZSxFQUFFO1lBQy9CLE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFDRCxPQUFPLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2QyxxQ0FBcUM7UUFDckMscUZBQXFGO0lBQ3ZGLENBQUM7SUFFRCxXQUFXLENBQUMsRUFBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBc0I7UUFDN0QsTUFBTSxFQUFDLFlBQVksRUFBRSxpQkFBaUIsRUFBQyxHQUFHLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQzNELElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDakIsT0FBTztTQUNSO1FBRUQsSUFBSSxXQUFXLENBQUMsWUFBWSxFQUFFO1lBQzVCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1NBQ3pCO1FBQ0QsSUFBSSxXQUFXLENBQUMsV0FBVyxFQUFFO1lBQzNCLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1NBQzVCO1FBQ0QsSUFBSSxXQUFXLENBQUMsZUFBZSxJQUFJLFdBQVcsQ0FBQyxXQUFXLEVBQUU7WUFDMUQsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDWixpQkFBaUIsRUFBRSxTQUFTO2FBQzdCLENBQUMsQ0FBQztTQUNKO1FBRUQsSUFBSSxXQUFXLENBQUMsZUFBZSxJQUFJLFdBQVcsQ0FBQyxrQkFBa0IsRUFBRTtZQUNqRSxZQUFZLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7WUFDdEQsQ0FBQyxHQUFTLEVBQUU7Z0JBQ1YsTUFBTSxVQUFVLEdBQUcsTUFBTSxZQUFZLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ3RELElBQUksQ0FBQyxRQUFRLENBQUMsRUFBQyxVQUFVLEVBQUMsQ0FBQyxDQUFDO1lBQzlCLENBQUMsQ0FBQSxDQUFDLEVBQUUsQ0FBQztTQUNOO0lBQ0gsQ0FBQztJQUVPLGlCQUFpQjtRQUN2QixNQUFNLEVBQ0oscUJBQXFCLEVBQ3JCLHFCQUFxQixFQUNyQixnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2pCLGVBQWUsRUFDZixXQUFXLEVBQ1gsa0JBQWtCLEVBQ2xCLGNBQWMsRUFDZCxRQUFRLEVBQ1IsVUFBVSxFQUNWLFdBQVcsR0FDWixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDZixPQUFPO1lBQ0wscUJBQXFCO1lBQ3JCLHFCQUFxQjtZQUNyQixnQkFBZ0I7WUFDaEIsaUJBQWlCO1lBQ2pCLGVBQWU7WUFDZixXQUFXO1lBQ1gsa0JBQWtCO1lBQ2xCLGNBQWM7WUFDZCxRQUFRO1lBQ1IsVUFBVTtZQUNWLFdBQVc7U0FDWixDQUFDO0lBQ0osQ0FBQztJQUVPLGdCQUFnQjtRQUN0QixPQUFPO1lBQ0wsUUFBUSxFQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQztZQUM1QyxXQUFXLEVBQUU7Z0JBQ1gsaUJBQWlCLEVBQUUsU0FBUztnQkFDNUIsa0JBQWtCLEVBQUUsa0JBQWtCLENBQUMsR0FBRztnQkFDMUMsaUJBQWlCLEVBQUUsU0FBUzthQUM3QjtZQUNELGFBQWEsRUFBRSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7U0FDeEMsQ0FBQztJQUNKLENBQUM7SUFFYSx3QkFBd0IsQ0FDcEMsSUFBeUI7OztZQUV6QixNQUFNLEVBQUMsS0FBSyxFQUFFLFdBQVcsRUFBQyxHQUFHLElBQUksQ0FBQztZQUNsQyxNQUFNLEVBQUMsWUFBWSxFQUFFLFNBQVMsRUFBQyxHQUFHLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ25ELElBQUksQ0FBQyxZQUFZLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQy9CLE9BQU8sU0FBUyxDQUFDO2FBQ2xCO1lBQ0QsTUFBTSxVQUFVLEdBQUc7Z0JBQ2pCLFdBQVc7Z0JBQ1gsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO2dCQUNqQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7Z0JBQ2pCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDVCxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ1QsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO2FBQzVCLENBQUM7WUFDRixJQUNFLFdBQVcsWUFBWSxjQUFjO2dCQUNyQyxXQUFXLFlBQVksc0JBQXNCLEVBQzdDO2dCQUNBLE1BQU0sSUFBSSxHQUNSLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLFlBQVksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3RFLElBQUksSUFBSSxFQUFFO29CQUNSLE1BQU0sTUFBTSxHQUFHLE1BQU0sWUFBWSxDQUFDLGVBQWUsQ0FDL0MsU0FBUyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FDaEMsQ0FBQztvQkFDRixNQUFNLElBQUksR0FBRyxNQUFNLFlBQVksQ0FBQyxlQUFlLENBQzdDLFNBQVMsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQzlCLENBQUM7b0JBQ0YsSUFBSSxNQUFNLElBQUksSUFBSSxFQUFFO3dCQUNsQix1Q0FDSyxVQUFVLEtBQ2IsSUFBSSxFQUFFLFdBQVcsQ0FBQyxJQUFJLEVBQ3RCLE1BQU0sRUFBRSxJQUFJLEVBQ1osTUFBTSxFQUFFLE1BQU0sRUFDZCxJQUFJLEVBQUUsSUFBSSxFQUNWLEtBQUssRUFBRSxTQUFTLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQ3ZDO3FCQUNIO2lCQUNGO2FBQ0Y7aUJBQU0sSUFBSSxXQUFXLFlBQVksZ0JBQWdCLEVBQUU7Z0JBQ2xELE1BQU0sUUFBUSxHQUNaLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFFMUUsSUFBSSxRQUFRLEVBQUU7b0JBQ1osTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDN0MsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDakQsTUFBTSxNQUFNLEdBQUcsTUFBTSxZQUFZLENBQUMsb0JBQW9CLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQzNELE1BQU0sRUFBQyxnQkFBZ0IsRUFBQyxHQUFHLENBQUEsTUFBQSxJQUFJLENBQUMsS0FBSywwQ0FBRSxVQUFVLEtBQUksRUFBRSxDQUFDO29CQUN4RCxJQUFJLE1BQU0sSUFBSSxnQkFBZ0IsRUFBRTt3QkFDOUIsTUFBTSxZQUFZLEdBQUcsMkJBQTJCLENBQzlDLGdCQUFnQixFQUNoQixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7d0JBQ0YsdUNBQ0ssVUFBVSxLQUNiLElBQUksRUFBRSxXQUFXLENBQUMsUUFBUSxFQUMxQixNQUFNLEVBQUUsUUFBUSxFQUNoQixFQUFFOzRCQUNGLElBQUk7NEJBQ0osTUFBTSxFQUNOLFlBQVksRUFBRSxZQUFZLEVBQzFCLEtBQUssRUFBRSxTQUFTLElBQ2hCO3FCQUNIO2lCQUNGO2FBQ0Y7WUFFRCxPQUFPLFNBQVMsQ0FBQzs7S0FDbEI7SUFFTyxxQkFBcUIsQ0FDM0IsSUFBeUI7O1FBRXpCLE1BQU0sRUFBQyxLQUFLLEVBQUUsV0FBVyxFQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ2xDLElBQUksS0FBSyxHQUFHLENBQUM7WUFBRSxPQUFPLFNBQVMsQ0FBQztRQUNoQyxJQUNFLFdBQVcsWUFBWSxjQUFjO1lBQ3JDLFdBQVcsWUFBWSxzQkFBc0IsRUFDN0M7WUFDQSxNQUFNLEVBQUMsY0FBYyxFQUFDLEdBQUcsQ0FBQSxNQUFBLElBQUksQ0FBQyxLQUFLLDBDQUFFLFVBQVUsS0FBSSxFQUFFLENBQUM7WUFDdEQsSUFBSSxjQUFjLEVBQUU7Z0JBQ2xCLE9BQU87b0JBQ0wsSUFBSSxFQUFFLGFBQWEsQ0FBQyxJQUFJO29CQUN4QixjQUFjLEVBQUUsNEJBQTRCLENBQUMsY0FBYyxFQUFFLEtBQUssQ0FBQztpQkFDcEUsQ0FBQzthQUNIO1NBQ0Y7YUFBTSxJQUFJLFdBQVcsWUFBWSxnQkFBZ0IsRUFBRTtZQUNsRCxNQUFNLEVBQUMsZ0JBQWdCLEVBQUMsR0FBRyxDQUFBLE1BQUEsSUFBSSxDQUFDLEtBQUssMENBQUUsVUFBVSxLQUFJLEVBQUUsQ0FBQztZQUN4RCxJQUFJLGdCQUFnQixFQUFFO2dCQUNwQixPQUFPO29CQUNMLElBQUksRUFBRSxhQUFhLENBQUMsUUFBUTtvQkFDNUIsUUFBUSxFQUFFLDBCQUEwQixDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQztvQkFDN0QsTUFBTSxFQUFFLDJCQUEyQixDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQztpQkFDN0QsQ0FBQzthQUNIO1NBQ0Y7UUFDRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsWUFBWTs7UUFDVixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFDbEIsSUFBSSxNQUFBLElBQUksQ0FBQyxLQUFLLDBDQUFFLFVBQVUsRUFBRTtZQUMxQixNQUFNLEVBQUMsVUFBVSxFQUFFLGlCQUFpQixFQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUNuRCxNQUFNLEVBQUMsZ0JBQWdCLEVBQUUsY0FBYyxFQUFDLEdBQUcsVUFBVSxJQUFJLEVBQUUsQ0FBQztZQUM1RCxJQUFJLGdCQUFnQixJQUFJLGNBQWMsRUFBRTtnQkFDdEMsTUFBTSxhQUFhLEdBQUcsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztnQkFDakUsTUFBTSxZQUFZLEdBQUcsV0FBVyxDQUM5QixhQUFhLENBQUMsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQ3RFLENBQUM7Z0JBQ0YsTUFBTSxvQkFBb0IsR0FBRztvQkFDM0IsSUFBSSxFQUFFLGNBQWM7b0JBQ3BCLFVBQVUsa0NBQ0wsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVO3dCQUN4QiwrQ0FBK0M7d0JBQy9DLFNBQVMsRUFBRSxLQUFLLEdBQ2pCO2lCQUNGLENBQUM7Z0JBQ0YsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUFFO29CQUMvQixNQUFNLENBQUMsSUFBSTtvQkFDVCxhQUFhO29CQUNiLElBQUksc0JBQXNCLG1CQUNyQixJQUFJLENBQUMsZ0JBQWdCLGlDQUNuQixvQkFBb0IsS0FDdkIsRUFBRSxFQUFFLHFCQUFxQixFQUN6QixXQUFXLEVBQUUsS0FBSyxFQUNsQixhQUFhLEVBQUUsRUFBRSxJQUNqQixFQUNGLENBQ0gsQ0FBQztpQkFDSDtxQkFBTTtvQkFDTCxNQUFNLENBQUMsSUFBSSxDQUNULElBQUksY0FBYyxtQkFDYixJQUFJLENBQUMsZ0JBQWdCLGlDQUNuQixvQkFBb0IsS0FDdkIsRUFBRSxFQUFFLFlBQVksRUFDaEIsV0FBVyxFQUFFLElBQUksRUFDakIsWUFBWSxFQUFFLFlBQVksSUFDMUIsRUFDRixDQUNILENBQUM7aUJBQ0g7Z0JBQ0QsTUFBTSxDQUFDLElBQUksQ0FDVCxJQUFJLGdCQUFnQixDQUNsQixJQUFJLENBQUMsZ0JBQWdCLENBQUM7b0JBQ3BCLEVBQUUsRUFBRSxTQUFTO29CQUNiLElBQUksRUFBRSxnQkFBZ0I7b0JBQ3RCLFVBQVUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQztvQkFDMUIsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUM7aUJBQ2xDLENBQUMsQ0FDSCxDQUNGLENBQUM7Z0JBQ0YsSUFBSSxpQkFBaUIsRUFBRTtvQkFDckIsUUFBUSxpQkFBaUIsQ0FBQyxJQUFJLEVBQUU7d0JBQzlCLEtBQUssYUFBYSxDQUFDLFFBQVE7NEJBQ3pCLE1BQU0sQ0FBQyxJQUFJLENBQ1QsSUFBSSxnQkFBZ0IsbUJBQ2YsSUFBSSxDQUFDLGdCQUFnQixDQUFDO2dDQUN2QixFQUFFLEVBQUUsb0JBQW9CO2dDQUN4QixJQUFJLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQztnQ0FDekIsUUFBUSxFQUFFLEtBQUs7Z0NBQ2YsT0FBTyxFQUFFLElBQUk7Z0NBQ2IsTUFBTSxFQUFFLEtBQUs7Z0NBQ2IsY0FBYyxFQUFFLFFBQVE7Z0NBQ3hCLFlBQVksRUFBRSxDQUFDO2dDQUNmLFdBQVcsRUFBRSxRQUFRO2dDQUNyQixTQUFTLEVBQUUsQ0FBQyxDQUE0QixFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTTtnQ0FDckQsWUFBWSxFQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQztnQ0FDcEQsV0FBVyxFQUFFLENBQUMsQ0FBNEIsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVE7NkJBQzFELENBQUMsRUFDRixDQUNILENBQUM7NEJBQ0YsTUFBTTt3QkFDUixLQUFLLGFBQWEsQ0FBQyxJQUFJOzRCQUNyQixNQUFNLENBQUMsSUFBSSxDQUNULElBQUksY0FBYyxtQkFDYixJQUFJLENBQUMsZ0JBQWdCLENBQUM7Z0NBQ3ZCLEVBQUUsRUFBRSxnQkFBZ0I7Z0NBQ3BCLElBQUksRUFBRSxpQkFBaUIsQ0FBQyxjQUFjO2dDQUN0QyxXQUFXLEVBQUUsSUFBSTtnQ0FDakIsUUFBUSxFQUFFLEtBQUs7Z0NBQ2YsWUFBWSxFQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQztnQ0FDcEQsZ0JBQWdCLEVBQUUsQ0FBQzs2QkFDcEIsQ0FBQyxFQUNGLENBQ0gsQ0FBQzs0QkFDRixNQUFNO3FCQUNUO2lCQUNGO2FBQ0Y7U0FDRjtRQUVELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7O0FBL1ZNLHlCQUFZLEdBQUc7SUFDcEIsUUFBUSxFQUFFLElBQUk7SUFDZCxVQUFVLEVBQUUsRUFBRTtJQUNkLHFCQUFxQixFQUFFLElBQUk7SUFDM0IsZ0JBQWdCLEVBQUUsS0FBSztJQUN2QixpQkFBaUIsRUFBRSxJQUFJO0lBQ3ZCLFdBQVcsRUFBRSxJQUFJO0lBQ2pCLGtCQUFrQixFQUFFLEtBQUs7SUFDekIsY0FBYyxFQUFFLElBQUk7SUFDcEIsZUFBZSxFQUFFLFNBQVM7SUFDMUIscUJBQXFCLEVBQUUsSUFBSTtJQUMzQixXQUFXLEVBQUUsTUFBTTtJQUNuQixjQUFjLEVBQUUsUUFBUTtDQUN6QixDQUFDO0FBcVZKLFNBQVMsV0FBVyxDQUFDLFFBQTZCO0lBQ2hELE1BQU0sRUFBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUMsR0FBRyxRQUFRLENBQUM7SUFDNUUsT0FBTztRQUNMLEtBQUs7UUFDTCxNQUFNO1FBQ04sU0FBUztRQUNULFFBQVE7UUFDUixJQUFJO1FBQ0osS0FBSztRQUNMLE9BQU87S0FDUixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgMjAyMiBGbG93bWFwQmx1ZVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuaW1wb3J0IHtDb21wb3NpdGVMYXllcn0gZnJvbSAnQGRlY2suZ2wvY29yZSc7XG5pbXBvcnQge1NjYXR0ZXJwbG90TGF5ZXJ9IGZyb20gJ0BkZWNrLmdsL2xheWVycyc7XG5pbXBvcnQge1xuICBjb2xvckFzUmdiYSxcbiAgRmxvd0xpbmVzTGF5ZXJBdHRyaWJ1dGVzLFxuICBGbG93TWFwRGF0YSxcbiAgRmxvd01hcERhdGFBY2Nlc3NvcnMsXG4gIEZsb3dNYXBEYXRhUHJvdmlkZXIsXG4gIGdldEZsb3dMaW5lQXR0cmlidXRlc0J5SW5kZXgsXG4gIGdldEZsb3dNYXBDb2xvcnMsXG4gIGdldE91dGVyQ2lyY2xlUmFkaXVzQnlJbmRleCxcbiAgZ2V0TG9jYXRpb25DZW50cm9pZEJ5SW5kZXgsXG4gIGlzRmxvd01hcERhdGEsXG4gIGlzRmxvd01hcERhdGFQcm92aWRlcixcbiAgTGF5ZXJzRGF0YSxcbiAgTG9jYWxGbG93TWFwRGF0YVByb3ZpZGVyLFxuICBMb2NhdGlvbkZpbHRlck1vZGUsXG4gIFZpZXdwb3J0UHJvcHMsXG4gIEZsb3dNYXBBZ2dyZWdhdGVBY2Nlc3NvcnMsXG4gIENsdXN0ZXJOb2RlLFxuICBBZ2dyZWdhdGVGbG93LFxufSBmcm9tICdAZmxvd21hcC5nbC9kYXRhJztcbmltcG9ydCBBbmltYXRlZEZsb3dMaW5lc0xheWVyIGZyb20gJy4vQW5pbWF0ZWRGbG93TGluZXNMYXllcic7XG5pbXBvcnQgRmxvd0NpcmNsZXNMYXllciBmcm9tICcuL0Zsb3dDaXJjbGVzTGF5ZXInO1xuaW1wb3J0IEZsb3dMaW5lc0xheWVyIGZyb20gJy4vRmxvd0xpbmVzTGF5ZXInO1xuaW1wb3J0IHtcbiAgRmxvd0xheWVyUGlja2luZ0luZm8sXG4gIExheWVyUHJvcHMsXG4gIFBpY2tpbmdJbmZvLFxuICBQaWNraW5nVHlwZSxcbn0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCB0eXBlIEZsb3dNYXBMYXllclByb3BzPEwsIEY+ID0ge1xuICBkYXRhOiBGbG93TWFwRGF0YTxMLCBGPiB8IEZsb3dNYXBEYXRhUHJvdmlkZXI8TCwgRj47XG4gIGxvY2F0aW9uVG90YWxzRW5hYmxlZD86IGJvb2xlYW47XG4gIGFkYXB0aXZlU2NhbGVzRW5hYmxlZD86IGJvb2xlYW47XG4gIGFuaW1hdGlvbkVuYWJsZWQ/OiBib29sZWFuO1xuICBjbHVzdGVyaW5nRW5hYmxlZD86IGJvb2xlYW47XG4gIGNsdXN0ZXJpbmdMZXZlbD86IG51bWJlcjtcbiAgZmFkZUVuYWJsZWQ/OiBib29sZWFuO1xuICBmYWRlT3BhY2l0eUVuYWJsZWQ/OiBib29sZWFuO1xuICBjbHVzdGVyaW5nQXV0bz86IGJvb2xlYW47XG4gIGRhcmtNb2RlPzogYm9vbGVhbjtcbiAgZmFkZUFtb3VudD86IG51bWJlcjtcbiAgY29sb3JTY2hlbWU/OiBzdHJpbmc7XG4gIGhpZ2hsaWdodENvbG9yPzogc3RyaW5nO1xuICBvbkhvdmVyPzogKFxuICAgIGluZm86IEZsb3dMYXllclBpY2tpbmdJbmZvPEwsIEY+IHwgdW5kZWZpbmVkLFxuICAgIGV2ZW50OiBTb3VyY2VFdmVudCxcbiAgKSA9PiB2b2lkO1xuICBvbkNsaWNrPzogKGluZm86IEZsb3dMYXllclBpY2tpbmdJbmZvPEwsIEY+LCBldmVudDogU291cmNlRXZlbnQpID0+IHZvaWQ7XG59ICYgUGFydGlhbDxGbG93TWFwRGF0YUFjY2Vzc29yczxMLCBGPj4gJlxuICBMYXllclByb3BzO1xuXG5lbnVtIEhpZ2hsaWdodFR5cGUge1xuICBMT0NBVElPTiA9ICdsb2NhdGlvbicsXG4gIEZMT1cgPSAnZmxvdycsXG59XG5cbnR5cGUgSGlnaGxpZ2h0ZWRMb2NhdGlvbk9iamVjdCA9IHtcbiAgdHlwZTogSGlnaGxpZ2h0VHlwZS5MT0NBVElPTjtcbiAgY2VudHJvaWQ6IFtudW1iZXIsIG51bWJlcl07XG4gIHJhZGl1czogbnVtYmVyO1xufTtcblxudHlwZSBIaWdobGlnaHRlZEZsb3dPYmplY3QgPSB7XG4gIHR5cGU6IEhpZ2hsaWdodFR5cGUuRkxPVztcbiAgbGluZUF0dHJpYnV0ZXM6IEZsb3dMaW5lc0xheWVyQXR0cmlidXRlcztcbn07XG5cbnR5cGUgSGlnaGxpZ2h0ZWRPYmplY3QgPSBIaWdobGlnaHRlZExvY2F0aW9uT2JqZWN0IHwgSGlnaGxpZ2h0ZWRGbG93T2JqZWN0O1xuXG50eXBlIFN0YXRlPEwsIEY+ID0ge1xuICBhY2Nlc3NvcnM6IEZsb3dNYXBBZ2dyZWdhdGVBY2Nlc3NvcnM8TCwgRj47XG4gIGRhdGFQcm92aWRlcjogRmxvd01hcERhdGFQcm92aWRlcjxMLCBGPjtcbiAgbGF5ZXJzRGF0YTogTGF5ZXJzRGF0YSB8IHVuZGVmaW5lZDtcbiAgaGlnaGxpZ2h0ZWRPYmplY3Q6IEhpZ2hsaWdodGVkT2JqZWN0IHwgdW5kZWZpbmVkO1xufTtcblxuZXhwb3J0IHR5cGUgU291cmNlRXZlbnQgPSB7c3JjRXZlbnQ6IE1vdXNlRXZlbnR9O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGbG93TWFwTGF5ZXI8TCwgRj4gZXh0ZW5kcyBDb21wb3NpdGVMYXllciB7XG4gIHN0YXRpYyBkZWZhdWx0UHJvcHMgPSB7XG4gICAgZGFya01vZGU6IHRydWUsXG4gICAgZmFkZUFtb3VudDogNTAsXG4gICAgbG9jYXRpb25Ub3RhbHNFbmFibGVkOiB0cnVlLFxuICAgIGFuaW1hdGlvbkVuYWJsZWQ6IGZhbHNlLFxuICAgIGNsdXN0ZXJpbmdFbmFibGVkOiB0cnVlLFxuICAgIGZhZGVFbmFibGVkOiB0cnVlLFxuICAgIGZhZGVPcGFjaXR5RW5hYmxlZDogZmFsc2UsXG4gICAgY2x1c3RlcmluZ0F1dG86IHRydWUsXG4gICAgY2x1c3RlcmluZ0xldmVsOiB1bmRlZmluZWQsXG4gICAgYWRhcHRpdmVTY2FsZXNFbmFibGVkOiB0cnVlLFxuICAgIGNvbG9yU2NoZW1lOiAnVGVhbCcsXG4gICAgaGlnaGxpZ2h0Q29sb3I6ICdvcmFuZ2UnLFxuICB9O1xuICBzdGF0ZTogU3RhdGU8TCwgRj4gfCB1bmRlZmluZWQ7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKHByb3BzOiBGbG93TWFwTGF5ZXJQcm9wczxMLCBGPikge1xuICAgIHN1cGVyKHtcbiAgICAgIC4uLnByb3BzLFxuICAgICAgb25Ib3ZlcjogKGluZm86IFBpY2tpbmdJbmZvPGFueT4sIGV2ZW50OiBTb3VyY2VFdmVudCkgPT4ge1xuICAgICAgICAvLyBUT0RPOiBpZiAobGFzdEhvdmVyRXZlbnRTdGFydFRpbWVSZWYgPiBzdGFydFRpbWUpIHtcbiAgICAgICAgLy8gICAvLyBTa2lwcGluZywgYmVjYXVzZSB0aGlzIGlzIG5vdCB0aGUgbGF0ZXN0IGhvdmVyIGV2ZW50XG4gICAgICAgIC8vICAgcmV0dXJuO1xuICAgICAgICAvLyB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe2hpZ2hsaWdodGVkT2JqZWN0OiB0aGlzLl9nZXRIaWdobGlnaHRlZE9iamVjdChpbmZvKX0pO1xuICAgICAgICBjb25zdCB7b25Ib3Zlcn0gPSBwcm9wcztcbiAgICAgICAgaWYgKG9uSG92ZXIpIHtcbiAgICAgICAgICB0aGlzLl9nZXRGbG93TGF5ZXJQaWNraW5nSW5mbyhpbmZvKS50aGVuKChpbmZvKSA9PlxuICAgICAgICAgICAgb25Ib3ZlcihpbmZvLCBldmVudCksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIG9uQ2xpY2s6IChpbmZvOiBQaWNraW5nSW5mbzxhbnk+LCBldmVudDogU291cmNlRXZlbnQpID0+IHtcbiAgICAgICAgY29uc3Qge29uQ2xpY2t9ID0gcHJvcHM7XG4gICAgICAgIGlmIChvbkNsaWNrKSB7XG4gICAgICAgICAgdGhpcy5fZ2V0Rmxvd0xheWVyUGlja2luZ0luZm8oaW5mbykudGhlbigoaW5mbykgPT4ge1xuICAgICAgICAgICAgaWYgKGluZm8pIHtcbiAgICAgICAgICAgICAgb25DbGljayhpbmZvLCBldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBpbml0aWFsaXplU3RhdGUoKSB7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGFjY2Vzc29yczogbmV3IEZsb3dNYXBBZ2dyZWdhdGVBY2Nlc3NvcnM8TCwgRj4odGhpcy5wcm9wcyksXG4gICAgICBkYXRhUHJvdmlkZXI6IHRoaXMuX21ha2VEYXRhUHJvdmlkZXIoKSxcbiAgICAgIGxheWVyc0RhdGE6IHVuZGVmaW5lZCxcbiAgICAgIGhpZ2hsaWdodGVkT2JqZWN0OiB1bmRlZmluZWQsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgX3VwZGF0ZUFjY2Vzc29ycygpIHtcbiAgICB0aGlzLnN0YXRlPy5kYXRhUHJvdmlkZXI/LnNldEFjY2Vzc29ycyh0aGlzLnByb3BzKTtcbiAgICB0aGlzLnNldFN0YXRlKHthY2Nlc3NvcnM6IG5ldyBGbG93TWFwQWdncmVnYXRlQWNjZXNzb3JzKHRoaXMucHJvcHMpfSk7XG4gIH1cblxuICBwcml2YXRlIF9tYWtlRGF0YVByb3ZpZGVyKCkge1xuICAgIGNvbnN0IHtkYXRhfSA9IHRoaXMucHJvcHM7XG4gICAgaWYgKGlzRmxvd01hcERhdGFQcm92aWRlcjxMLCBGPihkYXRhKSkge1xuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSBlbHNlIGlmIChpc0Zsb3dNYXBEYXRhPEwsIEY+KGRhdGEpKSB7XG4gICAgICBjb25zdCBkYXRhUHJvdmlkZXIgPSBuZXcgTG9jYWxGbG93TWFwRGF0YVByb3ZpZGVyPEwsIEY+KHRoaXMucHJvcHMpO1xuICAgICAgZGF0YVByb3ZpZGVyLnNldEZsb3dNYXBEYXRhKGRhdGEpO1xuICAgICAgcmV0dXJuIGRhdGFQcm92aWRlcjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0Zsb3dNYXBMYXllcjogZGF0YSBtdXN0IGJlIGEgRmxvd01hcERhdGFQcm92aWRlciBvciBGbG93TWFwRGF0YScsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX3VwZGF0ZURhdGFQcm92aWRlcigpIHtcbiAgICB0aGlzLnNldFN0YXRlKHtkYXRhUHJvdmlkZXI6IHRoaXMuX21ha2VEYXRhUHJvdmlkZXIoKX0pO1xuICB9XG5cbiAgc2hvdWxkVXBkYXRlU3RhdGUocGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KTogYm9vbGVhbiB7XG4gICAgY29uc3Qge2NoYW5nZUZsYWdzfSA9IHBhcmFtcztcbiAgICAvLyBpZiAodGhpcy5fdmlld3BvcnRDaGFuZ2VkKCkpIHtcbiAgICAvLyAgIHJldHVybiB0cnVlO1xuICAgIC8vIH1cbiAgICBpZiAoY2hhbmdlRmxhZ3Mudmlld3BvcnRDaGFuZ2VkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHN1cGVyLnNob3VsZFVwZGF0ZVN0YXRlKHBhcmFtcyk7XG4gICAgLy8gVE9ETzogYmUgc21hcnRlciBvbiB3aGVuIHRvIHVwZGF0ZVxuICAgIC8vIChlLmcuIGlnbm9yZSB2aWV3cG9ydCBjaGFuZ2VzIHdoZW4gYWRhcHRpdmVTY2FsZXNFbmFibGVkIGFuZCBjbHVzdGVyaW5nIGFyZSBmYWxzZSlcbiAgfVxuXG4gIHVwZGF0ZVN0YXRlKHtvbGRQcm9wcywgcHJvcHMsIGNoYW5nZUZsYWdzfTogUmVjb3JkPHN0cmluZywgYW55Pik6IHZvaWQge1xuICAgIGNvbnN0IHtkYXRhUHJvdmlkZXIsIGhpZ2hsaWdodGVkT2JqZWN0fSA9IHRoaXMuc3RhdGUgfHwge307XG4gICAgaWYgKCFkYXRhUHJvdmlkZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlRmxhZ3MucHJvcHNDaGFuZ2VkKSB7XG4gICAgICB0aGlzLl91cGRhdGVBY2Nlc3NvcnMoKTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZUZsYWdzLmRhdGFDaGFuZ2VkKSB7XG4gICAgICB0aGlzLl91cGRhdGVEYXRhUHJvdmlkZXIoKTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZUZsYWdzLnZpZXdwb3J0Q2hhbmdlZCB8fCBjaGFuZ2VGbGFncy5kYXRhQ2hhbmdlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIGhpZ2hsaWdodGVkT2JqZWN0OiB1bmRlZmluZWQsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlRmxhZ3Mudmlld3BvcnRDaGFuZ2VkIHx8IGNoYW5nZUZsYWdzLnByb3BzT3JEYXRhQ2hhbmdlZCkge1xuICAgICAgZGF0YVByb3ZpZGVyLnNldEZsb3dNYXBTdGF0ZSh0aGlzLl9nZXRGbG93TWFwU3RhdGUoKSk7XG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBsYXllcnNEYXRhID0gYXdhaXQgZGF0YVByb3ZpZGVyLmdldExheWVyc0RhdGEoKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7bGF5ZXJzRGF0YX0pO1xuICAgICAgfSkoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9nZXRTZXR0aW5nc1N0YXRlKCkge1xuICAgIGNvbnN0IHtcbiAgICAgIGxvY2F0aW9uVG90YWxzRW5hYmxlZCxcbiAgICAgIGFkYXB0aXZlU2NhbGVzRW5hYmxlZCxcbiAgICAgIGFuaW1hdGlvbkVuYWJsZWQsXG4gICAgICBjbHVzdGVyaW5nRW5hYmxlZCxcbiAgICAgIGNsdXN0ZXJpbmdMZXZlbCxcbiAgICAgIGZhZGVFbmFibGVkLFxuICAgICAgZmFkZU9wYWNpdHlFbmFibGVkLFxuICAgICAgY2x1c3RlcmluZ0F1dG8sXG4gICAgICBkYXJrTW9kZSxcbiAgICAgIGZhZGVBbW91bnQsXG4gICAgICBjb2xvclNjaGVtZSxcbiAgICB9ID0gdGhpcy5wcm9wcztcbiAgICByZXR1cm4ge1xuICAgICAgbG9jYXRpb25Ub3RhbHNFbmFibGVkLFxuICAgICAgYWRhcHRpdmVTY2FsZXNFbmFibGVkLFxuICAgICAgYW5pbWF0aW9uRW5hYmxlZCxcbiAgICAgIGNsdXN0ZXJpbmdFbmFibGVkLFxuICAgICAgY2x1c3RlcmluZ0xldmVsLFxuICAgICAgZmFkZUVuYWJsZWQsXG4gICAgICBmYWRlT3BhY2l0eUVuYWJsZWQsXG4gICAgICBjbHVzdGVyaW5nQXV0byxcbiAgICAgIGRhcmtNb2RlLFxuICAgICAgZmFkZUFtb3VudCxcbiAgICAgIGNvbG9yU2NoZW1lLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIF9nZXRGbG93TWFwU3RhdGUoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZpZXdwb3J0OiBhc1ZpZXdTdGF0ZSh0aGlzLmNvbnRleHQudmlld3BvcnQpLFxuICAgICAgZmlsdGVyU3RhdGU6IHtcbiAgICAgICAgc2VsZWN0ZWRMb2NhdGlvbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgbG9jYXRpb25GaWx0ZXJNb2RlOiBMb2NhdGlvbkZpbHRlck1vZGUuQUxMLFxuICAgICAgICBzZWxlY3RlZFRpbWVSYW5nZTogdW5kZWZpbmVkLFxuICAgICAgfSxcbiAgICAgIHNldHRpbmdzU3RhdGU6IHRoaXMuX2dldFNldHRpbmdzU3RhdGUoKSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfZ2V0Rmxvd0xheWVyUGlja2luZ0luZm8oXG4gICAgaW5mbzogUmVjb3JkPHN0cmluZywgYW55PixcbiAgKTogUHJvbWlzZTxGbG93TGF5ZXJQaWNraW5nSW5mbzxMLCBGPiB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IHtpbmRleCwgc291cmNlTGF5ZXJ9ID0gaW5mbztcbiAgICBjb25zdCB7ZGF0YVByb3ZpZGVyLCBhY2Nlc3NvcnN9ID0gdGhpcy5zdGF0ZSB8fCB7fTtcbiAgICBpZiAoIWRhdGFQcm92aWRlciB8fCAhYWNjZXNzb3JzKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBjb25zdCBjb21tb25JbmZvID0ge1xuICAgICAgLy8gLi4uaW5mbyxcbiAgICAgIGxheWVyOiBpbmZvLmxheWVyLFxuICAgICAgaW5kZXg6IGluZm8uaW5kZXgsXG4gICAgICB4OiBpbmZvLngsXG4gICAgICB5OiBpbmZvLnksXG4gICAgICBjb29yZGluYXRlOiBpbmZvLmNvb3JkaW5hdGUsXG4gICAgfTtcbiAgICBpZiAoXG4gICAgICBzb3VyY2VMYXllciBpbnN0YW5jZW9mIEZsb3dMaW5lc0xheWVyIHx8XG4gICAgICBzb3VyY2VMYXllciBpbnN0YW5jZW9mIEFuaW1hdGVkRmxvd0xpbmVzTGF5ZXJcbiAgICApIHtcbiAgICAgIGNvbnN0IGZsb3cgPVxuICAgICAgICBpbmRleCA9PT0gLTEgPyB1bmRlZmluZWQgOiBhd2FpdCBkYXRhUHJvdmlkZXIuZ2V0Rmxvd0J5SW5kZXgoaW5kZXgpO1xuICAgICAgaWYgKGZsb3cpIHtcbiAgICAgICAgY29uc3Qgb3JpZ2luID0gYXdhaXQgZGF0YVByb3ZpZGVyLmdldExvY2F0aW9uQnlJZChcbiAgICAgICAgICBhY2Nlc3NvcnMuZ2V0Rmxvd09yaWdpbklkKGZsb3cpLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBkZXN0ID0gYXdhaXQgZGF0YVByb3ZpZGVyLmdldExvY2F0aW9uQnlJZChcbiAgICAgICAgICBhY2Nlc3NvcnMuZ2V0Rmxvd0Rlc3RJZChmbG93KSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKG9yaWdpbiAmJiBkZXN0KSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmNvbW1vbkluZm8sXG4gICAgICAgICAgICB0eXBlOiBQaWNraW5nVHlwZS5GTE9XLFxuICAgICAgICAgICAgb2JqZWN0OiBmbG93LFxuICAgICAgICAgICAgb3JpZ2luOiBvcmlnaW4sXG4gICAgICAgICAgICBkZXN0OiBkZXN0LFxuICAgICAgICAgICAgY291bnQ6IGFjY2Vzc29ycy5nZXRGbG93TWFnbml0dWRlKGZsb3cpLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHNvdXJjZUxheWVyIGluc3RhbmNlb2YgRmxvd0NpcmNsZXNMYXllcikge1xuICAgICAgY29uc3QgbG9jYXRpb24gPVxuICAgICAgICBpbmRleCA9PT0gLTEgPyB1bmRlZmluZWQgOiBhd2FpdCBkYXRhUHJvdmlkZXIuZ2V0TG9jYXRpb25CeUluZGV4KGluZGV4KTtcblxuICAgICAgaWYgKGxvY2F0aW9uKSB7XG4gICAgICAgIGNvbnN0IGlkID0gYWNjZXNzb3JzLmdldExvY2F0aW9uSWQobG9jYXRpb24pO1xuICAgICAgICBjb25zdCBuYW1lID0gYWNjZXNzb3JzLmdldExvY2F0aW9uTmFtZShsb2NhdGlvbik7XG4gICAgICAgIGNvbnN0IHRvdGFscyA9IGF3YWl0IGRhdGFQcm92aWRlci5nZXRUb3RhbHNGb3JMb2NhdGlvbihpZCk7XG4gICAgICAgIGNvbnN0IHtjaXJjbGVBdHRyaWJ1dGVzfSA9IHRoaXMuc3RhdGU/LmxheWVyc0RhdGEgfHwge307XG4gICAgICAgIGlmICh0b3RhbHMgJiYgY2lyY2xlQXR0cmlidXRlcykge1xuICAgICAgICAgIGNvbnN0IGNpcmNsZVJhZGl1cyA9IGdldE91dGVyQ2lyY2xlUmFkaXVzQnlJbmRleChcbiAgICAgICAgICAgIGNpcmNsZUF0dHJpYnV0ZXMsXG4gICAgICAgICAgICBpbmZvLmluZGV4LFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmNvbW1vbkluZm8sXG4gICAgICAgICAgICB0eXBlOiBQaWNraW5nVHlwZS5MT0NBVElPTixcbiAgICAgICAgICAgIG9iamVjdDogbG9jYXRpb24sXG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICB0b3RhbHMsXG4gICAgICAgICAgICBjaXJjbGVSYWRpdXM6IGNpcmNsZVJhZGl1cyxcbiAgICAgICAgICAgIGV2ZW50OiB1bmRlZmluZWQsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIF9nZXRIaWdobGlnaHRlZE9iamVjdChcbiAgICBpbmZvOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICApOiBIaWdobGlnaHRlZE9iamVjdCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qge2luZGV4LCBzb3VyY2VMYXllcn0gPSBpbmZvO1xuICAgIGlmIChpbmRleCA8IDApIHJldHVybiB1bmRlZmluZWQ7XG4gICAgaWYgKFxuICAgICAgc291cmNlTGF5ZXIgaW5zdGFuY2VvZiBGbG93TGluZXNMYXllciB8fFxuICAgICAgc291cmNlTGF5ZXIgaW5zdGFuY2VvZiBBbmltYXRlZEZsb3dMaW5lc0xheWVyXG4gICAgKSB7XG4gICAgICBjb25zdCB7bGluZUF0dHJpYnV0ZXN9ID0gdGhpcy5zdGF0ZT8ubGF5ZXJzRGF0YSB8fCB7fTtcbiAgICAgIGlmIChsaW5lQXR0cmlidXRlcykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGU6IEhpZ2hsaWdodFR5cGUuRkxPVyxcbiAgICAgICAgICBsaW5lQXR0cmlidXRlczogZ2V0Rmxvd0xpbmVBdHRyaWJ1dGVzQnlJbmRleChsaW5lQXR0cmlidXRlcywgaW5kZXgpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc291cmNlTGF5ZXIgaW5zdGFuY2VvZiBGbG93Q2lyY2xlc0xheWVyKSB7XG4gICAgICBjb25zdCB7Y2lyY2xlQXR0cmlidXRlc30gPSB0aGlzLnN0YXRlPy5sYXllcnNEYXRhIHx8IHt9O1xuICAgICAgaWYgKGNpcmNsZUF0dHJpYnV0ZXMpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0eXBlOiBIaWdobGlnaHRUeXBlLkxPQ0FUSU9OLFxuICAgICAgICAgIGNlbnRyb2lkOiBnZXRMb2NhdGlvbkNlbnRyb2lkQnlJbmRleChjaXJjbGVBdHRyaWJ1dGVzLCBpbmRleCksXG4gICAgICAgICAgcmFkaXVzOiBnZXRPdXRlckNpcmNsZVJhZGl1c0J5SW5kZXgoY2lyY2xlQXR0cmlidXRlcywgaW5kZXgpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcmVuZGVyTGF5ZXJzKCk6IEFycmF5PGFueT4ge1xuICAgIGNvbnN0IGxheWVycyA9IFtdO1xuICAgIGlmICh0aGlzLnN0YXRlPy5sYXllcnNEYXRhKSB7XG4gICAgICBjb25zdCB7bGF5ZXJzRGF0YSwgaGlnaGxpZ2h0ZWRPYmplY3R9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIGNvbnN0IHtjaXJjbGVBdHRyaWJ1dGVzLCBsaW5lQXR0cmlidXRlc30gPSBsYXllcnNEYXRhIHx8IHt9O1xuICAgICAgaWYgKGNpcmNsZUF0dHJpYnV0ZXMgJiYgbGluZUF0dHJpYnV0ZXMpIHtcbiAgICAgICAgY29uc3QgZmxvd01hcENvbG9ycyA9IGdldEZsb3dNYXBDb2xvcnModGhpcy5fZ2V0U2V0dGluZ3NTdGF0ZSgpKTtcbiAgICAgICAgY29uc3Qgb3V0bGluZUNvbG9yID0gY29sb3JBc1JnYmEoXG4gICAgICAgICAgZmxvd01hcENvbG9ycy5vdXRsaW5lQ29sb3IgfHwgKHRoaXMucHJvcHMuZGFya01vZGUgPyAnIzAwMCcgOiAnI2ZmZicpLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBjb21tb25MaW5lTGF5ZXJQcm9wcyA9IHtcbiAgICAgICAgICBkYXRhOiBsaW5lQXR0cmlidXRlcyxcbiAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAuLi50aGlzLnByb3BzLnBhcmFtZXRlcnMsXG4gICAgICAgICAgICAvLyBwcmV2ZW50IHotZmlnaHRpbmcgYXQgbm9uLXplcm8gYmVhcmluZy9waXRjaFxuICAgICAgICAgICAgZGVwdGhUZXN0OiBmYWxzZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5hbmltYXRpb25FbmFibGVkKSB7XG4gICAgICAgICAgbGF5ZXJzLnB1c2goXG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICBuZXcgQW5pbWF0ZWRGbG93TGluZXNMYXllcih7XG4gICAgICAgICAgICAgIC4uLnRoaXMuZ2V0U3ViTGF5ZXJQcm9wcyh7XG4gICAgICAgICAgICAgICAgLi4uY29tbW9uTGluZUxheWVyUHJvcHMsXG4gICAgICAgICAgICAgICAgaWQ6ICdhbmltYXRlZC1mbG93LWxpbmVzJyxcbiAgICAgICAgICAgICAgICBkcmF3T3V0bGluZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgdGhpY2tuZXNzVW5pdDogMjAsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsYXllcnMucHVzaChcbiAgICAgICAgICAgIG5ldyBGbG93TGluZXNMYXllcih7XG4gICAgICAgICAgICAgIC4uLnRoaXMuZ2V0U3ViTGF5ZXJQcm9wcyh7XG4gICAgICAgICAgICAgICAgLi4uY29tbW9uTGluZUxheWVyUHJvcHMsXG4gICAgICAgICAgICAgICAgaWQ6ICdmbG93LWxpbmVzJyxcbiAgICAgICAgICAgICAgICBkcmF3T3V0bGluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvdXRsaW5lQ29sb3I6IG91dGxpbmVDb2xvcixcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGxheWVycy5wdXNoKFxuICAgICAgICAgIG5ldyBGbG93Q2lyY2xlc0xheWVyKFxuICAgICAgICAgICAgdGhpcy5nZXRTdWJMYXllclByb3BzKHtcbiAgICAgICAgICAgICAgaWQ6ICdjaXJjbGVzJyxcbiAgICAgICAgICAgICAgZGF0YTogY2lyY2xlQXR0cmlidXRlcyxcbiAgICAgICAgICAgICAgZW1wdHlDb2xvcjogWzAsIDAsIDAsIDI1NV0sXG4gICAgICAgICAgICAgIGVtcHR5T3V0bGluZUNvbG9yOiBbMCwgMCwgMCwgMjU1XSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIGlmIChoaWdobGlnaHRlZE9iamVjdCkge1xuICAgICAgICAgIHN3aXRjaCAoaGlnaGxpZ2h0ZWRPYmplY3QudHlwZSkge1xuICAgICAgICAgICAgY2FzZSBIaWdobGlnaHRUeXBlLkxPQ0FUSU9OOlxuICAgICAgICAgICAgICBsYXllcnMucHVzaChcbiAgICAgICAgICAgICAgICBuZXcgU2NhdHRlcnBsb3RMYXllcih7XG4gICAgICAgICAgICAgICAgICAuLi50aGlzLmdldFN1YkxheWVyUHJvcHMoe1xuICAgICAgICAgICAgICAgICAgICBpZDogJ2xvY2F0aW9uLWhpZ2hsaWdodCcsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IFtoaWdobGlnaHRlZE9iamVjdF0sXG4gICAgICAgICAgICAgICAgICAgIHBpY2thYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgc3Ryb2tlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZmlsbGVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbGluZVdpZHRoVW5pdHM6ICdwaXhlbHMnLFxuICAgICAgICAgICAgICAgICAgICBnZXRMaW5lV2lkdGg6IDIsXG4gICAgICAgICAgICAgICAgICAgIHJhZGl1c1VuaXRzOiAncGl4ZWxzJyxcbiAgICAgICAgICAgICAgICAgICAgZ2V0UmFkaXVzOiAoZDogSGlnaGxpZ2h0ZWRMb2NhdGlvbk9iamVjdCkgPT4gZC5yYWRpdXMsXG4gICAgICAgICAgICAgICAgICAgIGdldExpbmVDb2xvcjogY29sb3JBc1JnYmEodGhpcy5wcm9wcy5oaWdobGlnaHRDb2xvciksXG4gICAgICAgICAgICAgICAgICAgIGdldFBvc2l0aW9uOiAoZDogSGlnaGxpZ2h0ZWRMb2NhdGlvbk9iamVjdCkgPT4gZC5jZW50cm9pZCxcbiAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgSGlnaGxpZ2h0VHlwZS5GTE9XOlxuICAgICAgICAgICAgICBsYXllcnMucHVzaChcbiAgICAgICAgICAgICAgICBuZXcgRmxvd0xpbmVzTGF5ZXIoe1xuICAgICAgICAgICAgICAgICAgLi4udGhpcy5nZXRTdWJMYXllclByb3BzKHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6ICdmbG93LWhpZ2hsaWdodCcsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IGhpZ2hsaWdodGVkT2JqZWN0LmxpbmVBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgICAgICAgICBkcmF3T3V0bGluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgcGlja2FibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBvdXRsaW5lQ29sb3I6IGNvbG9yQXNSZ2JhKHRoaXMucHJvcHMuaGlnaGxpZ2h0Q29sb3IpLFxuICAgICAgICAgICAgICAgICAgICBvdXRsaW5lVGhpY2tuZXNzOiAxLFxuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBsYXllcnM7XG4gIH1cbn1cblxuZnVuY3Rpb24gYXNWaWV3U3RhdGUodmlld3BvcnQ6IFJlY29yZDxzdHJpbmcsIGFueT4pOiBWaWV3cG9ydFByb3BzIHtcbiAgY29uc3Qge3dpZHRoLCBoZWlnaHQsIGxvbmdpdHVkZSwgbGF0aXR1ZGUsIHpvb20sIHBpdGNoLCBiZWFyaW5nfSA9IHZpZXdwb3J0O1xuICByZXR1cm4ge1xuICAgIHdpZHRoLFxuICAgIGhlaWdodCxcbiAgICBsb25naXR1ZGUsXG4gICAgbGF0aXR1ZGUsXG4gICAgem9vbSxcbiAgICBwaXRjaCxcbiAgICBiZWFyaW5nLFxuICB9O1xufVxuIl19