@smarterplan/ngx-smarterplan-core 1.4.20 → 1.4.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -24
- package/esm2022/lib/components/csv-export/csv-export.component.mjs +3 -3
- package/esm2022/lib/components/loader/loader.component.mjs +3 -3
- package/esm2022/lib/components/menu-bar/avatar/avatar.component.mjs +1 -1
- package/esm2022/lib/components/menu-bar/menu-bar.component.mjs +3 -3
- package/esm2022/lib/components/menu-bar/navigation-bar/navigation-bar.component.mjs +3 -3
- package/esm2022/lib/components/modal-switch-visit/modal-switch-visit.component.mjs +3 -3
- package/esm2022/lib/components/search-bar/search-bar.component.mjs +3 -3
- package/esm2022/lib/components/support-modal/support-modal.component.mjs +3 -3
- package/esm2022/lib/config.mjs +1 -1
- package/esm2022/lib/helpers.service.mjs +1 -1
- package/esm2022/lib/matterport-extensions/nest-thermostat/CanvasImage.mjs +1 -1
- package/esm2022/lib/matterport-extensions/nest-thermostat/CanvasRenderer.mjs +1 -1
- package/esm2022/lib/matterport-extensions/nest-thermostat/NestThermostat.mjs +1 -1
- package/esm2022/lib/matterport-extensions/nest-thermostat/PlaneRenderer.mjs +1 -1
- package/esm2022/lib/matterport-extensions/scene-component/SceneComponent.mjs +1 -1
- package/esm2022/lib/matterport-extensions/security-camera/SecurityCamera.mjs +49 -28
- package/esm2022/lib/matterport-extensions/tv-player/TvPlayer.mjs +1 -1
- package/esm2022/lib/matterport-extensions/view-frustum-mesh/ViewFrustumMesh.mjs +22 -22
- package/esm2022/lib/mattertagData.mjs +1 -1
- package/esm2022/lib/ngx-smarterplan-core.module.mjs +1 -1
- package/esm2022/lib/ngx-smarterplan-core.service.mjs +1 -1
- package/esm2022/lib/pipes/duration-to-string.pipe.mjs +1 -1
- package/esm2022/lib/pipes/format-date-number-to-digits.pipe.mjs +1 -1
- package/esm2022/lib/pipes/hashtag-from-id.pipe.mjs +1 -1
- package/esm2022/lib/pipes/safe-url.pipe.mjs +1 -1
- package/esm2022/lib/pipes/time-date-to-local-string.pipe.mjs +1 -1
- package/esm2022/lib/pipes/username-from-id.pipe.mjs +1 -1
- package/esm2022/lib/services/amplify-cache.service.mjs +1 -1
- package/esm2022/lib/services/base-tab.service.mjs +1 -1
- package/esm2022/lib/services/baseVisibility.service.mjs +1 -1
- package/esm2022/lib/services/content.service.mjs +1 -1
- package/esm2022/lib/services/filter.service.mjs +1 -1
- package/esm2022/lib/services/intervention.service.mjs +1 -1
- package/esm2022/lib/services/locale.service.mjs +1 -1
- package/esm2022/lib/services/matterport-import.service.mjs +1 -1
- package/esm2022/lib/services/matterport-measurement.service.mjs +1 -1
- package/esm2022/lib/services/matterport-navigation.service.mjs +1 -1
- package/esm2022/lib/services/matterport-object3d.service.mjs +657 -133
- package/esm2022/lib/services/matterport-pointer.service.mjs +6 -6
- package/esm2022/lib/services/matterport-tag-copy.service.mjs +1 -1
- package/esm2022/lib/services/matterport-tag.service.mjs +1 -1
- package/esm2022/lib/services/matterport.service.mjs +346 -25
- package/esm2022/lib/services/models/affectation.service.mjs +1 -1
- package/esm2022/lib/services/models/base-object.service.mjs +1 -1
- package/esm2022/lib/services/models/capture.service.mjs +1 -1
- package/esm2022/lib/services/models/comment.service.mjs +1 -1
- package/esm2022/lib/services/models/domain.service.mjs +1 -1
- package/esm2022/lib/services/models/equipment.service.mjs +1 -1
- package/esm2022/lib/services/models/event.service.mjs +1 -1
- package/esm2022/lib/services/models/feature.service.mjs +1 -1
- package/esm2022/lib/services/models/hashtag.service.mjs +1 -1
- package/esm2022/lib/services/models/layer.service.mjs +1 -1
- package/esm2022/lib/services/models/measurement.service.mjs +1 -1
- package/esm2022/lib/services/models/mission.service.mjs +1 -1
- package/esm2022/lib/services/models/navigation.service.mjs +1 -1
- package/esm2022/lib/services/models/node.service.mjs +1 -1
- package/esm2022/lib/services/models/object3D.service.mjs +1 -1
- package/esm2022/lib/services/models/operation.service.mjs +1 -1
- package/esm2022/lib/services/models/organisation.service.mjs +1 -1
- package/esm2022/lib/services/models/plan.service.mjs +1 -1
- package/esm2022/lib/services/models/poi.service.mjs +27 -27
- package/esm2022/lib/services/models/profile.service.mjs +1 -1
- package/esm2022/lib/services/models/property.service.mjs +1 -1
- package/esm2022/lib/services/models/space.service.mjs +1 -1
- package/esm2022/lib/services/models/template.service.mjs +1 -1
- package/esm2022/lib/services/models/ticket.service.mjs +1 -1
- package/esm2022/lib/services/models/visit.service.mjs +1 -1
- package/esm2022/lib/services/models/zone.service.mjs +1 -1
- package/esm2022/lib/services/navigator.service.mjs +1 -1
- package/esm2022/lib/services/s3.service.mjs +1 -1
- package/esm2022/lib/services/search.service.mjs +1 -1
- package/esm2022/lib/services/support.service.mjs +1 -1
- package/esm2022/lib/services/sweep-locator.service.mjs +1 -1
- package/esm2022/lib/services/tag.service.mjs +16 -16
- package/esm2022/lib/services/threejs-import.service.mjs +1 -1
- package/esm2022/lib/services/threejs.service.mjs +1 -1
- package/esm2022/lib/services/user.service.mjs +1 -1
- package/esm2022/lib/services/utils/matterport-framing.util.mjs +63 -0
- package/esm2022/lib/services/utils/matterport-transform.util.mjs +1 -1
- package/esm2022/lib/services/validators.service.mjs +1 -1
- package/esm2022/lib/services/viewer.service.mjs +1 -1
- package/esm2022/lib/services/zone-drawer.service.mjs +1 -1
- package/esm2022/lib/services/zoneChange.service.mjs +1 -1
- package/esm2022/lib/tokens/matterport-sdk-key.token.mjs +1 -1
- package/esm2022/lib/types.service.mjs +3 -1
- package/esm2022/lib/validators/email.directive.mjs +1 -1
- package/esm2022/lib/validators/no-empty.directive.mjs +1 -1
- package/esm2022/lib/validators/number.directive.mjs +1 -1
- package/esm2022/lib/validators/text.directive.mjs +1 -1
- package/esm2022/public-api.mjs +1 -1
- package/fesm2022/smarterplan-ngx-smarterplan-core.mjs +1192 -263
- package/fesm2022/smarterplan-ngx-smarterplan-core.mjs.map +1 -1
- package/lib/services/matterport-object3d.service.d.ts +125 -5
- package/lib/services/matterport.service.d.ts +106 -7
- package/lib/services/utils/matterport-framing.util.d.ts +40 -0
- package/lib/types.service.d.ts +42 -1
- package/package.json +1 -1
- package/src/assets/vs-app.json +67 -67
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Injectable } from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { Subject } from 'rxjs';
|
|
3
|
+
import { PoiType, } from '../types.service';
|
|
4
|
+
import { Box3, MathUtils, Object3D, Vector3 } from 'three';
|
|
4
5
|
import { NestThermostat } from '../matterport-extensions/nest-thermostat/NestThermostat';
|
|
5
6
|
import { PlaneRenderer } from '../matterport-extensions/nest-thermostat/PlaneRenderer';
|
|
6
7
|
import { CanvasRenderer } from "../matterport-extensions/nest-thermostat/CanvasRenderer";
|
|
@@ -15,6 +16,28 @@ export class MatterportObject3DService {
|
|
|
15
16
|
azimuthalCrown;
|
|
16
17
|
threeJSScene;
|
|
17
18
|
noLightForObjects = true;
|
|
19
|
+
/** Max time (ms) to wait for a model to be loaded by the SDK */
|
|
20
|
+
loadTimeoutMs = 15000;
|
|
21
|
+
/** Max distance (m) an object can travel from where a translate drag started */
|
|
22
|
+
maxDragDistance = 2;
|
|
23
|
+
/** Max vertical travel (m, up and down) during a translate drag, so an object cannot jump to another floor */
|
|
24
|
+
maxDragHeight = 1.5;
|
|
25
|
+
/** Emits on every gizmo change and on setObject3DTransform */
|
|
26
|
+
object3DTransformChanged$ = new Subject();
|
|
27
|
+
/** Security camera animators by object uuid (`securityCameraAnimator` stays the last loaded one) */
|
|
28
|
+
securityCameraAnimators = new Map();
|
|
29
|
+
viewFrustumVisible = new Map();
|
|
30
|
+
lastSecurityCameraUuid = null;
|
|
31
|
+
/** Loader component of each model (outputs.objectRoot is set once loaded) */
|
|
32
|
+
loaderComponents = new Map();
|
|
33
|
+
gizmos = new Map();
|
|
34
|
+
activeGizmoUuid = null;
|
|
35
|
+
gizmoSnap = null;
|
|
36
|
+
/** Sweeps disabled by setNavigationLocked(true), re-enabled on unlock */
|
|
37
|
+
sweepsDisabledByLock = [];
|
|
38
|
+
/** Sweeps re-enabled by the last unlock (the SDK may still report them disabled for a moment) */
|
|
39
|
+
sweepsEnabledByUnlock = [];
|
|
40
|
+
tmpBox = new Box3();
|
|
18
41
|
constructor() { }
|
|
19
42
|
async init3DObjectViewer(sdk) {
|
|
20
43
|
const [sceneObject] = await sdk.Scene.createObjects(1);
|
|
@@ -25,112 +48,184 @@ export class MatterportObject3DService {
|
|
|
25
48
|
this.objectControl = nodeControl.addComponent('mp.transformControls');
|
|
26
49
|
nodeControl.start();
|
|
27
50
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
component = modelNode.addComponent('mp.fbxLoader', initial);
|
|
52
|
-
break;
|
|
53
|
-
case '.gltf':
|
|
54
|
-
case 'gltf':
|
|
55
|
-
case '.glb':
|
|
56
|
-
case 'glb':
|
|
57
|
-
component = modelNode.addComponent('mp.gltfLoader', initial);
|
|
58
|
-
break;
|
|
59
|
-
case '.dae':
|
|
60
|
-
case 'dae':
|
|
61
|
-
component = modelNode.addComponent('mp.daeLoader', initial);
|
|
62
|
-
break;
|
|
63
|
-
default:
|
|
64
|
-
console.log('Format not supported');
|
|
65
|
-
break;
|
|
66
|
-
}
|
|
67
|
-
if (this.noLightForObjects) {
|
|
68
|
-
const lightsNode = sceneObject.addNode();
|
|
69
|
-
lightsNode.addComponent('mp.ambientLight', {
|
|
70
|
-
intensity: 1,
|
|
71
|
-
color: { r: 1.0, g: 1.0, b: 1.0 },
|
|
72
|
-
});
|
|
73
|
-
this.noLightForObjects = false;
|
|
74
|
-
}
|
|
75
|
-
modelNode.obj3D.position.set(obj.position.x, obj.position.y, obj.position.z);
|
|
76
|
-
modelNode.obj3D.rotation.set(obj.rotation.x, obj.rotation.y, obj.rotation.z);
|
|
77
|
-
modelNode.obj3D.scale.set(obj.scale.x, obj.scale.y, obj.scale.z);
|
|
78
|
-
if (isAzimuthalCrown) {
|
|
79
|
-
this.azimuthalCrown = modelNode;
|
|
80
|
-
}
|
|
81
|
-
if (mode && !isNestThermostat) {
|
|
82
|
-
this.attachGizmoControlTo3DObject(sdk, modelNode, sceneObject, mode, true, true).catch((e) => console.log(e));
|
|
83
|
-
}
|
|
84
|
-
if (this.lastObject3D && typeof this.lastObject3D.id === 'string') {
|
|
85
|
-
modelNode.obj3D.uuid = this.lastObject3D.id;
|
|
86
|
-
}
|
|
87
|
-
else if (obj.id) {
|
|
88
|
-
modelNode.obj3D.uuid = obj.id;
|
|
51
|
+
/** SDK loader component name for a model format, null when the format is not supported */
|
|
52
|
+
getLoaderComponentName(format) {
|
|
53
|
+
switch ((format || '').toLowerCase()) {
|
|
54
|
+
case '.obj':
|
|
55
|
+
case 'obj': return 'mp.objLoader';
|
|
56
|
+
case '.fbx':
|
|
57
|
+
case 'fbx': return 'mp.fbxLoader';
|
|
58
|
+
case '.gltf':
|
|
59
|
+
case 'gltf':
|
|
60
|
+
case '.glb':
|
|
61
|
+
case 'glb': return 'mp.gltfLoader';
|
|
62
|
+
case '.dae':
|
|
63
|
+
case 'dae': return 'mp.daeLoader';
|
|
64
|
+
default: return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** Resolves once the loader component has produced its objectRoot, rejects after `timeoutMs` */
|
|
68
|
+
waitForModelLoaded(component, timeoutMs) {
|
|
69
|
+
return new Promise((resolve, reject) => {
|
|
70
|
+
const isLoaded = () => !!component?.outputs?.objectRoot;
|
|
71
|
+
if (isLoaded()) {
|
|
72
|
+
resolve();
|
|
73
|
+
return;
|
|
89
74
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
"nearPlane": 0.1, "farPlane": 10, "horizontalFOV": 52, "aspect": 1.7777777777777777,
|
|
96
|
-
"localPosition": { "x": 0.3, "y": 0.18, "z": 0 },
|
|
97
|
-
"localRotation": { "x": -15, "y": -90, "z": 0 },
|
|
98
|
-
"color": 65280, "panPeriod": 5, "panAngle": -45
|
|
99
|
-
});
|
|
100
|
-
this.securityCameraAnimator = animator;
|
|
101
|
-
if (!obj.viewFrustum) {
|
|
102
|
-
setTimeout(() => { animator.toggleViewFrustum(); }, 1000);
|
|
75
|
+
const poll = setInterval(() => {
|
|
76
|
+
if (isLoaded()) {
|
|
77
|
+
clearInterval(poll);
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
resolve();
|
|
103
80
|
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
plane.outputs = { objectRoot: new Object3D(), collider: new Object3D() };
|
|
110
|
-
const inputTexture = cv.outputs.texture;
|
|
111
|
-
plane.setRootScene(this.threeJSScene);
|
|
112
|
-
plane.onInit(modelNode, inputTexture);
|
|
113
|
-
const sc = new NestThermostat();
|
|
114
|
-
sc.setComponent(component, plane, cv);
|
|
115
|
-
sc.setRootScene(this.threeJSScene);
|
|
116
|
-
sc.onInit(modelNode, plane, inputTexture);
|
|
117
|
-
cv.setCanvasNestThermostatPainter(sc);
|
|
118
|
-
setTimeout(() => { sc.inputs.loadingState = "Loaded"; sc.onInputsUpdated(); }, 5000);
|
|
119
|
-
}
|
|
120
|
-
if (isSmarterplanPromotionalVideo) {
|
|
121
|
-
const sc = new TvPlayer();
|
|
122
|
-
sc.setComponent(component);
|
|
123
|
-
sc.onInit(modelNode);
|
|
124
|
-
setTimeout(() => { sc.inputs.loadingState = "Loaded"; sc.onInputsUpdated(); }, 5000);
|
|
125
|
-
}
|
|
126
|
-
sceneObject.start();
|
|
127
|
-
resolve(this.lastObject3D);
|
|
81
|
+
}, 50);
|
|
82
|
+
const timer = setTimeout(() => {
|
|
83
|
+
clearInterval(poll);
|
|
84
|
+
reject(new Error(`3D model not loaded after ${timeoutMs} ms`));
|
|
85
|
+
}, timeoutMs);
|
|
128
86
|
});
|
|
129
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Adds a 3D model to the scene.
|
|
90
|
+
* The promise resolves with the three.js object once the model is actually loaded, and rejects
|
|
91
|
+
* (after cleaning the scene) when the format is unknown or the load times out.
|
|
92
|
+
* The position / rotation / scale of `obj` are applied to the model origin, as stored in DB.
|
|
93
|
+
*/
|
|
94
|
+
async add3DObject(sdk, obj, mode) {
|
|
95
|
+
const loaderName = this.getLoaderComponentName(obj.format);
|
|
96
|
+
if (!loaderName) {
|
|
97
|
+
throw new Error(`3D object format not supported: ${obj.format}`);
|
|
98
|
+
}
|
|
99
|
+
const [sceneObject] = await sdk.Scene.createObjects(1);
|
|
100
|
+
const isAnimatedSecurityCamera = (!obj.url && obj.object === 'security_camera');
|
|
101
|
+
const isNestThermostat = (!obj.url && obj.object === 'nest_thermostat');
|
|
102
|
+
const isSmarterplanPromotionalVideo = (!obj.url && obj.object === 'video');
|
|
103
|
+
const isAzimuthalCrown = (!obj.url && obj.object === 'azimuth');
|
|
104
|
+
const modelNode = sceneObject.addNode();
|
|
105
|
+
const initial = {
|
|
106
|
+
url: obj.url || `/assets/3Dobjects/objects/${obj.object}${obj.format.indexOf('.') === -1 ? '.' + obj.format : obj.format}`,
|
|
107
|
+
localRotation: { 'x': 0, 'y': 0, 'z': 0 },
|
|
108
|
+
localPosition: { 'x': 0, 'y': 0, 'z': 0 },
|
|
109
|
+
visible: true,
|
|
110
|
+
colliderEnabled: true
|
|
111
|
+
};
|
|
112
|
+
const component = modelNode.addComponent(loaderName, initial);
|
|
113
|
+
if (this.noLightForObjects) {
|
|
114
|
+
const lightsNode = sceneObject.addNode();
|
|
115
|
+
lightsNode.addComponent('mp.ambientLight', {
|
|
116
|
+
intensity: 1,
|
|
117
|
+
color: { r: 1.0, g: 1.0, b: 1.0 },
|
|
118
|
+
});
|
|
119
|
+
this.noLightForObjects = false;
|
|
120
|
+
}
|
|
121
|
+
modelNode.obj3D.position.set(obj.position.x, obj.position.y, obj.position.z);
|
|
122
|
+
modelNode.obj3D.rotation.set(obj.rotation.x, obj.rotation.y, obj.rotation.z);
|
|
123
|
+
modelNode.obj3D.scale.set(obj.scale.x, obj.scale.y, obj.scale.z);
|
|
124
|
+
// The DB id replaces the three.js uuid. The id pre-set through setLastObject3D is only a fallback
|
|
125
|
+
// for callers without id: taking it first gave the same id to every object loaded meanwhile
|
|
126
|
+
// (several cameras or cubes loading while an add is starting), which then overwrote each other.
|
|
127
|
+
if (obj.id) {
|
|
128
|
+
modelNode.obj3D.uuid = obj.id;
|
|
129
|
+
}
|
|
130
|
+
else if (this.lastObject3D && typeof this.lastObject3D.id === 'string') {
|
|
131
|
+
modelNode.obj3D.uuid = this.lastObject3D.id;
|
|
132
|
+
}
|
|
133
|
+
const uuid = modelNode.obj3D.uuid;
|
|
134
|
+
this.lastObject3D = modelNode.obj3D;
|
|
135
|
+
this.dictionnaryObjects3D.set(uuid, modelNode);
|
|
136
|
+
this.dictionnarySceneObjects3D.set(uuid, sceneObject);
|
|
137
|
+
this.loaderComponents.set(uuid, component);
|
|
138
|
+
if (isAzimuthalCrown) {
|
|
139
|
+
this.azimuthalCrown = modelNode;
|
|
140
|
+
}
|
|
141
|
+
if (mode && !isNestThermostat) {
|
|
142
|
+
this.attachGizmo(uuid, mode).catch(() => { });
|
|
143
|
+
}
|
|
144
|
+
let animator = null;
|
|
145
|
+
if (isAnimatedSecurityCamera) {
|
|
146
|
+
animator = modelNode.addComponent('mp.securityCamera', {
|
|
147
|
+
'nearPlane': 0.1, 'farPlane': 10, 'horizontalFOV': 52, 'aspect': 1.7777777777777777,
|
|
148
|
+
'localPosition': { 'x': 0.3, 'y': 0.18, 'z': 0 },
|
|
149
|
+
'localRotation': { 'x': -15, 'y': -90, 'z': 0 },
|
|
150
|
+
'color': 65280, 'panPeriod': 5, 'panAngle': -45
|
|
151
|
+
});
|
|
152
|
+
this.securityCameraAnimator = animator;
|
|
153
|
+
this.securityCameraAnimators.set(uuid, animator);
|
|
154
|
+
this.viewFrustumVisible.set(uuid, true); // the component shows its frustum by default
|
|
155
|
+
this.lastSecurityCameraUuid = uuid;
|
|
156
|
+
}
|
|
157
|
+
if (isNestThermostat) {
|
|
158
|
+
const cv = new CanvasRenderer();
|
|
159
|
+
cv.onInit();
|
|
160
|
+
const plane = new PlaneRenderer();
|
|
161
|
+
plane.outputs = { objectRoot: new Object3D(), collider: new Object3D() };
|
|
162
|
+
const inputTexture = cv.outputs.texture;
|
|
163
|
+
plane.setRootScene(this.threeJSScene);
|
|
164
|
+
plane.onInit(modelNode, inputTexture);
|
|
165
|
+
const sc = new NestThermostat();
|
|
166
|
+
sc.setComponent(component, plane, cv);
|
|
167
|
+
sc.setRootScene(this.threeJSScene);
|
|
168
|
+
sc.onInit(modelNode, plane, inputTexture);
|
|
169
|
+
cv.setCanvasNestThermostatPainter(sc);
|
|
170
|
+
setTimeout(() => { sc.inputs.loadingState = 'Loaded'; sc.onInputsUpdated(); }, 5000);
|
|
171
|
+
}
|
|
172
|
+
if (isSmarterplanPromotionalVideo) {
|
|
173
|
+
const sc = new TvPlayer();
|
|
174
|
+
sc.setComponent(component);
|
|
175
|
+
sc.onInit(modelNode);
|
|
176
|
+
setTimeout(() => { sc.inputs.loadingState = 'Loaded'; sc.onInputsUpdated(); }, 5000);
|
|
177
|
+
}
|
|
178
|
+
sceneObject.start();
|
|
179
|
+
try {
|
|
180
|
+
await this.waitForModelLoaded(component, this.loadTimeoutMs);
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
await this.deleteObject3D(uuid);
|
|
184
|
+
throw e;
|
|
185
|
+
}
|
|
186
|
+
if (animator && !obj.viewFrustum) {
|
|
187
|
+
// The camera component starts with the model node, so it is ready now that the model is loaded
|
|
188
|
+
this.applyViewFrustum(uuid, false);
|
|
189
|
+
}
|
|
190
|
+
return modelNode.obj3D;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Removes a 3D object for good: detaches its gizmo, stops its scene object and forgets it.
|
|
194
|
+
*/
|
|
130
195
|
async deleteObject3D(uuid) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
196
|
+
this.detachGizmo(uuid);
|
|
197
|
+
const node = this.dictionnaryObjects3D.get(uuid);
|
|
198
|
+
const sceneObject = this.dictionnarySceneObjects3D.get(uuid);
|
|
199
|
+
if (node) {
|
|
200
|
+
try {
|
|
201
|
+
node.obj3D.visible = false;
|
|
202
|
+
}
|
|
203
|
+
catch { /* already destroyed */ }
|
|
204
|
+
}
|
|
205
|
+
if (sceneObject && typeof sceneObject.stop === 'function') {
|
|
206
|
+
try {
|
|
207
|
+
sceneObject.stop();
|
|
208
|
+
}
|
|
209
|
+
catch { /* already stopped */ }
|
|
210
|
+
}
|
|
211
|
+
this.dictionnaryObjects3D.delete(uuid);
|
|
212
|
+
this.dictionnarySceneObjects3D.delete(uuid);
|
|
213
|
+
this.loaderComponents.delete(uuid);
|
|
214
|
+
if (this.lastObject3D && (this.lastObject3D.uuid === uuid || this.lastObject3D.id === uuid)) {
|
|
215
|
+
this.lastObject3D = null;
|
|
216
|
+
}
|
|
217
|
+
if (node && this.azimuthalCrown === node) {
|
|
218
|
+
this.azimuthalCrown = null;
|
|
219
|
+
}
|
|
220
|
+
const animator = this.securityCameraAnimators.get(uuid);
|
|
221
|
+
if (animator && this.securityCameraAnimator === animator) {
|
|
222
|
+
this.securityCameraAnimator = null;
|
|
223
|
+
}
|
|
224
|
+
this.securityCameraAnimators.delete(uuid);
|
|
225
|
+
this.viewFrustumVisible.delete(uuid);
|
|
226
|
+
if (this.lastSecurityCameraUuid === uuid) {
|
|
227
|
+
this.lastSecurityCameraUuid = null;
|
|
228
|
+
}
|
|
134
229
|
}
|
|
135
230
|
getObject3DModelNodeFromDictionnary(uuid) {
|
|
136
231
|
let obj = this.dictionnaryObjects3D.get(uuid);
|
|
@@ -150,10 +245,32 @@ export class MatterportObject3DService {
|
|
|
150
245
|
let obj = this.dictionnaryObjects3D.get(objectId);
|
|
151
246
|
return obj ? obj.obj3D.visible : false;
|
|
152
247
|
}
|
|
248
|
+
/** Shows / hides a model (used by the placement preview) */
|
|
249
|
+
setObject3DVisible(uuid, visible) {
|
|
250
|
+
const node = this.dictionnaryObjects3D.get(uuid);
|
|
251
|
+
if (node)
|
|
252
|
+
node.obj3D.visible = visible;
|
|
253
|
+
}
|
|
254
|
+
/** Enables / disables the pointer collider of a model (disabled while it follows the cursor) */
|
|
255
|
+
setObject3DColliderEnabled(uuid, enabled) {
|
|
256
|
+
const component = this.loaderComponents.get(uuid);
|
|
257
|
+
if (component?.inputs) {
|
|
258
|
+
component.inputs.colliderEnabled = enabled;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Moves the camera next to a 3D object by creating a temporary tag on the object centre.
|
|
263
|
+
* @returns false when the object is unknown or no tag could be reached
|
|
264
|
+
*/
|
|
153
265
|
async pointCameraTo3DObject(sdk, objectId, createTagCallback, goToTagCallback, deleteLastTagCallback, getTagFromElementId) {
|
|
154
|
-
|
|
266
|
+
const obj = this.dictionnaryObjects3D.get(objectId);
|
|
267
|
+
if (!obj)
|
|
268
|
+
return false;
|
|
269
|
+
// Tag on the bounding box centre (the model origin is a corner for most models)
|
|
270
|
+
const box = this.getObject3DBoundingBox(objectId);
|
|
271
|
+
const anchor = box ? box.center : this.toPoint(obj.obj3D.position);
|
|
155
272
|
const poiObject = {
|
|
156
|
-
coordinate: JSON.stringify(
|
|
273
|
+
coordinate: JSON.stringify(anchor),
|
|
157
274
|
type: PoiType.OBJECT3D,
|
|
158
275
|
elementID: objectId,
|
|
159
276
|
};
|
|
@@ -162,9 +279,16 @@ export class MatterportObject3DService {
|
|
|
162
279
|
await createTagCallback(PoiType.OBJECT3D, objectDb, poiObject);
|
|
163
280
|
}
|
|
164
281
|
catch (err) { }
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
282
|
+
try {
|
|
283
|
+
const result = getTagFromElementId(objectId);
|
|
284
|
+
if (!result?.tag)
|
|
285
|
+
return false;
|
|
286
|
+
await goToTagCallback(result.tag);
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
finally {
|
|
290
|
+
deleteLastTagCallback();
|
|
291
|
+
}
|
|
168
292
|
}
|
|
169
293
|
getSceneNodeFromObject3DId(uuid) {
|
|
170
294
|
return this.dictionnarySceneObjects3D.get(uuid);
|
|
@@ -174,49 +298,449 @@ export class MatterportObject3DService {
|
|
|
174
298
|
this.azimuthalCrown.obj3D.position.set(poseCamera.position.x, poseCamera.position.y, poseCamera.position.z);
|
|
175
299
|
}
|
|
176
300
|
}
|
|
301
|
+
//
|
|
302
|
+
// ---------- Geometry helpers ----------
|
|
303
|
+
//
|
|
304
|
+
toPoint(v) {
|
|
305
|
+
return { x: v.x, y: v.y, z: v.z };
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Geometry of the model itself (the loader output): the node also holds the helpers added by other
|
|
309
|
+
* components, like the view frustum of a security camera, which must not count in its size.
|
|
310
|
+
*/
|
|
311
|
+
modelRoot(uuid, node) {
|
|
312
|
+
return this.loaderComponents.get(uuid)?.outputs?.objectRoot ?? node.obj3D;
|
|
313
|
+
}
|
|
314
|
+
/** World-space bounding box of the model, null when unknown or when nothing is loaded yet */
|
|
315
|
+
getObject3DBoundingBox(uuid) {
|
|
316
|
+
const node = this.dictionnaryObjects3D.get(uuid);
|
|
317
|
+
if (!node)
|
|
318
|
+
return null;
|
|
319
|
+
node.obj3D.updateWorldMatrix(true, true);
|
|
320
|
+
const box = this.tmpBox.setFromObject(this.modelRoot(uuid, node));
|
|
321
|
+
if (box.isEmpty())
|
|
322
|
+
return null;
|
|
323
|
+
const size = box.getSize(new Vector3());
|
|
324
|
+
const center = box.getCenter(new Vector3());
|
|
325
|
+
return {
|
|
326
|
+
min: this.toPoint(box.min),
|
|
327
|
+
max: this.toPoint(box.max),
|
|
328
|
+
size: this.toPoint(size),
|
|
329
|
+
center: this.toPoint(center),
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Real dimensions of the model in meters (width x, height y, depth z), scale included but not
|
|
334
|
+
* its rotation: the world bounding box of a rotated object is larger than the object itself.
|
|
335
|
+
*/
|
|
336
|
+
getObject3DDimensions(uuid) {
|
|
337
|
+
const node = this.dictionnaryObjects3D.get(uuid);
|
|
338
|
+
if (!node)
|
|
339
|
+
return null;
|
|
340
|
+
const rotation = node.obj3D.rotation.clone();
|
|
341
|
+
node.obj3D.rotation.set(0, 0, 0);
|
|
342
|
+
try {
|
|
343
|
+
node.obj3D.updateWorldMatrix(true, true);
|
|
344
|
+
const box = this.tmpBox.setFromObject(this.modelRoot(uuid, node));
|
|
345
|
+
return box.isEmpty() ? null : this.toPoint(box.getSize(new Vector3()));
|
|
346
|
+
}
|
|
347
|
+
finally {
|
|
348
|
+
node.obj3D.rotation.copy(rotation);
|
|
349
|
+
node.obj3D.updateWorldMatrix(true, true);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Uniform scale so that the largest bounding box dimension equals `targetSizeMeters`.
|
|
354
|
+
* The node position is untouched, so call placeObject3DOnSurface afterwards.
|
|
355
|
+
* @returns the new scale, null when the object is unknown / not loaded / `targetSizeMeters` invalid
|
|
356
|
+
*/
|
|
357
|
+
normalizeObject3DSize(uuid, targetSizeMeters) {
|
|
358
|
+
const node = this.dictionnaryObjects3D.get(uuid);
|
|
359
|
+
const box = this.getObject3DBoundingBox(uuid);
|
|
360
|
+
if (!node || !box || !(targetSizeMeters > 0))
|
|
361
|
+
return null;
|
|
362
|
+
const largest = Math.max(box.size.x, box.size.y, box.size.z);
|
|
363
|
+
if (!(largest > 0))
|
|
364
|
+
return null;
|
|
365
|
+
const factor = targetSizeMeters / largest;
|
|
366
|
+
node.obj3D.scale.multiplyScalar(factor);
|
|
367
|
+
this.emitTransformChanged(uuid);
|
|
368
|
+
return this.toPoint(node.obj3D.scale);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Places the model on a surface point without touching its pivot: the node position is
|
|
372
|
+
* adjusted so that the bounding box bottom-center lies on `point`.
|
|
373
|
+
* - floor (normal pointing up, or no normal): bottom-center on the point
|
|
374
|
+
* - wall (mostly horizontal normal): model turned around Y so its +Z faces away from the wall,
|
|
375
|
+
* and pushed along the normal by half its depth so it does not cut the wall
|
|
376
|
+
* - ceiling (normal pointing down): the model hangs, top-center on the point
|
|
377
|
+
* @returns the new transform, null when the object is unknown or not loaded
|
|
378
|
+
*/
|
|
379
|
+
/**
|
|
380
|
+
* @param frontYawOffset rotation (radians, around Y) that turns the front of the model toward its +Z
|
|
381
|
+
* axis, for models whose front is another axis (e.g. -PI/2 when it is +X)
|
|
382
|
+
*/
|
|
383
|
+
placeObject3DOnSurface(uuid, point, normal, frontYawOffset = 0) {
|
|
384
|
+
const node = this.dictionnaryObjects3D.get(uuid);
|
|
385
|
+
if (!node || !this.getObject3DBoundingBox(uuid))
|
|
386
|
+
return null;
|
|
387
|
+
const obj = node.obj3D;
|
|
388
|
+
const n = normal ? new Vector3(normal.x, normal.y, normal.z) : new Vector3(0, 1, 0);
|
|
389
|
+
if (n.lengthSq() === 0)
|
|
390
|
+
n.set(0, 1, 0);
|
|
391
|
+
n.normalize();
|
|
392
|
+
const isWall = Math.abs(n.y) < 0.5;
|
|
393
|
+
const isCeiling = !isWall && n.y < 0;
|
|
394
|
+
const target = new Vector3(point.x, point.y, point.z);
|
|
395
|
+
if (isWall) {
|
|
396
|
+
// Face away from the wall; the box has to be measured after the rotation
|
|
397
|
+
obj.rotation.y = Math.atan2(n.x, n.z) + frontYawOffset;
|
|
398
|
+
}
|
|
399
|
+
const box = this.getObject3DBoundingBox(uuid);
|
|
400
|
+
if (isWall) {
|
|
401
|
+
const horizontal = new Vector3(n.x, 0, n.z).normalize();
|
|
402
|
+
const halfDepth = 0.5 * (Math.abs(horizontal.x) * box.size.x + Math.abs(horizontal.z) * box.size.z);
|
|
403
|
+
target.addScaledVector(horizontal, halfDepth);
|
|
404
|
+
}
|
|
405
|
+
const anchorY = isCeiling ? box.max.y : box.min.y;
|
|
406
|
+
obj.position.x += target.x - box.center.x;
|
|
407
|
+
obj.position.y += target.y - anchorY;
|
|
408
|
+
obj.position.z += target.z - box.center.z;
|
|
409
|
+
this.emitTransformChanged(uuid);
|
|
410
|
+
return this.getObject3DTransform(uuid);
|
|
411
|
+
}
|
|
412
|
+
getObject3DTransform(uuid) {
|
|
413
|
+
const node = this.dictionnaryObjects3D.get(uuid);
|
|
414
|
+
if (!node)
|
|
415
|
+
return null;
|
|
416
|
+
const o = node.obj3D;
|
|
417
|
+
return {
|
|
418
|
+
position: this.toPoint(o.position),
|
|
419
|
+
rotation: { x: o.rotation.x, y: o.rotation.y, z: o.rotation.z },
|
|
420
|
+
scale: this.toPoint(o.scale),
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
/** Applies a (partial) transform. Rotation is in radians. */
|
|
424
|
+
setObject3DTransform(uuid, transform) {
|
|
425
|
+
const node = this.dictionnaryObjects3D.get(uuid);
|
|
426
|
+
if (!node)
|
|
427
|
+
return false;
|
|
428
|
+
const o = node.obj3D;
|
|
429
|
+
if (transform.position)
|
|
430
|
+
o.position.set(transform.position.x, transform.position.y, transform.position.z);
|
|
431
|
+
if (transform.rotation)
|
|
432
|
+
o.rotation.set(transform.rotation.x, transform.rotation.y, transform.rotation.z);
|
|
433
|
+
if (transform.scale)
|
|
434
|
+
o.scale.set(transform.scale.x, transform.scale.y, transform.scale.z);
|
|
435
|
+
this.emitTransformChanged(uuid);
|
|
436
|
+
return true;
|
|
437
|
+
}
|
|
438
|
+
emitTransformChanged(uuid) {
|
|
439
|
+
const transform = this.getObject3DTransform(uuid);
|
|
440
|
+
if (transform) {
|
|
441
|
+
this.object3DTransformChanged$.next({ uuid, ...transform });
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
//
|
|
445
|
+
// ---------- Gizmo ----------
|
|
446
|
+
//
|
|
447
|
+
/** Creates the mp.transformControls node of a model and wires it (events, snap) */
|
|
448
|
+
createGizmo(uuid, modelNode, sceneObject, mode, visible, node) {
|
|
449
|
+
const gizmoNode = node ?? sceneObject.addNode();
|
|
450
|
+
const component = gizmoNode.addComponent('mp.transformControls');
|
|
451
|
+
gizmoNode.start();
|
|
452
|
+
const tc = component.transformControls;
|
|
453
|
+
tc.visible = visible;
|
|
454
|
+
component.inputs.selection = modelNode;
|
|
455
|
+
component.inputs.mode = mode;
|
|
456
|
+
modelNode.obj3D.controls = component;
|
|
457
|
+
const entry = {
|
|
458
|
+
uuid,
|
|
459
|
+
node: gizmoNode,
|
|
460
|
+
component,
|
|
461
|
+
mode,
|
|
462
|
+
dragStart: null,
|
|
463
|
+
lastPosition: modelNode.obj3D.position.clone(),
|
|
464
|
+
onDraggingChanged: (event) => {
|
|
465
|
+
entry.dragStart = event?.value ? modelNode.obj3D.position.clone() : null;
|
|
466
|
+
entry.lastPosition = modelNode.obj3D.position.clone();
|
|
467
|
+
},
|
|
468
|
+
onObjectChange: () => this.onGizmoObjectChange(entry, modelNode),
|
|
469
|
+
};
|
|
470
|
+
if (typeof tc.addEventListener === 'function') {
|
|
471
|
+
tc.addEventListener('dragging-changed', entry.onDraggingChanged);
|
|
472
|
+
tc.addEventListener('objectChange', entry.onObjectChange);
|
|
473
|
+
}
|
|
474
|
+
this.applySnap(tc);
|
|
475
|
+
this.gizmos.set(uuid, entry);
|
|
476
|
+
this.activeGizmoUuid = uuid;
|
|
477
|
+
return entry;
|
|
478
|
+
}
|
|
479
|
+
/** Keeps a translate drag within maxDragDistance / maxDragHeight of where it started, then notifies */
|
|
480
|
+
onGizmoObjectChange(entry, modelNode) {
|
|
481
|
+
const pos = modelNode.obj3D.position;
|
|
482
|
+
if (entry.mode === 'translate') {
|
|
483
|
+
const start = entry.dragStart ?? entry.lastPosition;
|
|
484
|
+
const delta = pos.clone().sub(start);
|
|
485
|
+
delta.y = MathUtils.clamp(delta.y, -this.maxDragHeight, this.maxDragHeight);
|
|
486
|
+
const length = delta.length();
|
|
487
|
+
if (length > this.maxDragDistance) {
|
|
488
|
+
delta.multiplyScalar(this.maxDragDistance / length);
|
|
489
|
+
}
|
|
490
|
+
pos.copy(start).add(delta);
|
|
491
|
+
}
|
|
492
|
+
entry.lastPosition = pos.clone();
|
|
493
|
+
this.emitTransformChanged(entry.uuid);
|
|
494
|
+
}
|
|
495
|
+
applySnap(tc) {
|
|
496
|
+
if (!tc)
|
|
497
|
+
return;
|
|
498
|
+
const snap = this.gizmoSnap;
|
|
499
|
+
const translation = snap?.translation ?? null;
|
|
500
|
+
const rotation = snap?.rotationDeg != null ? MathUtils.degToRad(snap.rotationDeg) : null;
|
|
501
|
+
const scale = snap?.scale ?? null;
|
|
502
|
+
if (typeof tc.setTranslationSnap === 'function')
|
|
503
|
+
tc.setTranslationSnap(translation);
|
|
504
|
+
else
|
|
505
|
+
tc.translationSnap = translation;
|
|
506
|
+
if (typeof tc.setRotationSnap === 'function')
|
|
507
|
+
tc.setRotationSnap(rotation);
|
|
508
|
+
else
|
|
509
|
+
tc.rotationSnap = rotation;
|
|
510
|
+
if (typeof tc.setScaleSnap === 'function')
|
|
511
|
+
tc.setScaleSnap(scale);
|
|
512
|
+
else
|
|
513
|
+
tc.scaleSnap = scale;
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Shows the transform gizmo on an object (any previous gizmo is detached first).
|
|
517
|
+
* Re-attaching to the object that already has the gizmo only changes its mode.
|
|
518
|
+
*/
|
|
519
|
+
async attachGizmo(uuid, mode, sdk) {
|
|
520
|
+
const modelNode = this.dictionnaryObjects3D.get(uuid);
|
|
521
|
+
const sceneObject = this.dictionnarySceneObjects3D.get(uuid);
|
|
522
|
+
if (!modelNode || !sceneObject)
|
|
523
|
+
return false;
|
|
524
|
+
const existing = this.gizmos.get(uuid);
|
|
525
|
+
if (existing && this.activeGizmoUuid === uuid) {
|
|
526
|
+
this.setGizmoMode(mode);
|
|
527
|
+
return true;
|
|
528
|
+
}
|
|
529
|
+
// A started scene object refuses new nodes (addNode returns null): use a dedicated one
|
|
530
|
+
let node = sceneObject.addNode();
|
|
531
|
+
let gizmoSceneObject = null;
|
|
532
|
+
if (!node) {
|
|
533
|
+
if (!sdk?.Scene)
|
|
534
|
+
return false;
|
|
535
|
+
[gizmoSceneObject] = await sdk.Scene.createObjects(1);
|
|
536
|
+
node = gizmoSceneObject.addNode();
|
|
537
|
+
}
|
|
538
|
+
this.detachGizmo();
|
|
539
|
+
const entry = this.createGizmo(uuid, modelNode, sceneObject, mode, true, node);
|
|
540
|
+
entry.sceneObject = gizmoSceneObject;
|
|
541
|
+
this.lastObject3D = modelNode.obj3D;
|
|
542
|
+
return true;
|
|
543
|
+
}
|
|
544
|
+
/** Switches the active gizmo between translate / rotate / scale without re-attaching it */
|
|
545
|
+
setGizmoMode(mode) {
|
|
546
|
+
const entry = this.activeGizmoUuid ? this.gizmos.get(this.activeGizmoUuid) : null;
|
|
547
|
+
if (!entry)
|
|
548
|
+
return;
|
|
549
|
+
entry.mode = mode;
|
|
550
|
+
entry.dragStart = null;
|
|
551
|
+
entry.component.inputs.mode = mode;
|
|
552
|
+
const tc = entry.component.transformControls;
|
|
553
|
+
if (tc && typeof tc.setMode === 'function')
|
|
554
|
+
tc.setMode(mode);
|
|
555
|
+
}
|
|
556
|
+
/** Really removes the gizmo from the scene (default: the active one) */
|
|
557
|
+
detachGizmo(uuid) {
|
|
558
|
+
const id = uuid ?? this.activeGizmoUuid;
|
|
559
|
+
if (!id)
|
|
560
|
+
return;
|
|
561
|
+
const entry = this.gizmos.get(id);
|
|
562
|
+
if (!entry)
|
|
563
|
+
return;
|
|
564
|
+
const tc = entry.component?.transformControls;
|
|
565
|
+
if (tc) {
|
|
566
|
+
if (typeof tc.removeEventListener === 'function') {
|
|
567
|
+
tc.removeEventListener('dragging-changed', entry.onDraggingChanged);
|
|
568
|
+
tc.removeEventListener('objectChange', entry.onObjectChange);
|
|
569
|
+
}
|
|
570
|
+
tc.visible = false;
|
|
571
|
+
if (typeof tc.detach === 'function')
|
|
572
|
+
tc.detach();
|
|
573
|
+
if (typeof tc.dispose === 'function')
|
|
574
|
+
tc.dispose();
|
|
575
|
+
if (tc.parent && typeof tc.parent.remove === 'function')
|
|
576
|
+
tc.parent.remove(tc);
|
|
577
|
+
}
|
|
578
|
+
try {
|
|
579
|
+
entry.node.stop();
|
|
580
|
+
}
|
|
581
|
+
catch { /* already stopped */ }
|
|
582
|
+
try {
|
|
583
|
+
entry.sceneObject?.stop();
|
|
584
|
+
}
|
|
585
|
+
catch { /* already stopped */ }
|
|
586
|
+
const modelNode = this.dictionnaryObjects3D.get(id);
|
|
587
|
+
if (modelNode?.obj3D)
|
|
588
|
+
modelNode.obj3D.controls = null;
|
|
589
|
+
this.gizmos.delete(id);
|
|
590
|
+
if (this.activeGizmoUuid === id)
|
|
591
|
+
this.activeGizmoUuid = null;
|
|
592
|
+
}
|
|
593
|
+
isGizmoAttached(uuid) {
|
|
594
|
+
return uuid ? this.gizmos.has(uuid) : this.activeGizmoUuid !== null;
|
|
595
|
+
}
|
|
596
|
+
/** Snap steps for all gizmos (null / missing value = no snap) */
|
|
597
|
+
setGizmoSnap(snap) {
|
|
598
|
+
this.gizmoSnap = snap ? { ...snap } : null;
|
|
599
|
+
this.gizmos.forEach((entry) => this.applySnap(entry.component?.transformControls));
|
|
600
|
+
}
|
|
601
|
+
setGizmoMaxDragDistance(maxDistance, maxHeight) {
|
|
602
|
+
if (maxDistance > 0)
|
|
603
|
+
this.maxDragDistance = maxDistance;
|
|
604
|
+
if (maxHeight !== undefined && maxHeight > 0)
|
|
605
|
+
this.maxDragHeight = maxHeight;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Prevents camera navigation to other sweeps while a gizmo is edited.
|
|
609
|
+
* The SDK has no "freeze camera" switch, so every enabled sweep except the current one is
|
|
610
|
+
* disabled (Sweep.disable); exactly those sweeps are re-enabled on unlock. Sweeps already
|
|
611
|
+
* disabled (forbidden sweeps, edit mode) are never touched, and `keepDisabled` lists sweeps
|
|
612
|
+
* that must stay disabled on unlock.
|
|
613
|
+
* @returns false when the lock could not be applied (SDK without Sweep.disable, unknown current sweep)
|
|
614
|
+
*/
|
|
615
|
+
async setNavigationLocked(sdk, locked, sweepCollection, currentSweepId, keepDisabled = []) {
|
|
616
|
+
if (!sdk?.Sweep || typeof sdk.Sweep.disable !== 'function' || typeof sdk.Sweep.enable !== 'function') {
|
|
617
|
+
return false;
|
|
618
|
+
}
|
|
619
|
+
if (locked) {
|
|
620
|
+
if (this.sweepsDisabledByLock.length > 0)
|
|
621
|
+
return true;
|
|
622
|
+
if (!sweepCollection || !currentSweepId)
|
|
623
|
+
return false;
|
|
624
|
+
// a sweep this lock re-enabled just before may still be reported disabled by the SDK
|
|
625
|
+
const ids = Object.keys(sweepCollection).filter((sid) => sid !== currentSweepId &&
|
|
626
|
+
(sweepCollection[sid]?.enabled !== false || this.sweepsEnabledByUnlock.includes(sid)));
|
|
627
|
+
if (ids.length === 0)
|
|
628
|
+
return true;
|
|
629
|
+
try {
|
|
630
|
+
await sdk.Sweep.disable(...ids);
|
|
631
|
+
this.sweepsDisabledByLock = ids;
|
|
632
|
+
}
|
|
633
|
+
catch {
|
|
634
|
+
// fall back to one call per sweep to know exactly which ones were disabled
|
|
635
|
+
const results = await Promise.allSettled(ids.map((sid) => sdk.Sweep.disable(sid)));
|
|
636
|
+
this.sweepsDisabledByLock = ids.filter((_, i) => results[i].status === 'fulfilled');
|
|
637
|
+
}
|
|
638
|
+
return true;
|
|
639
|
+
}
|
|
640
|
+
const toEnable = this.sweepsDisabledByLock.filter((sid) => !keepDisabled.includes(sid));
|
|
641
|
+
this.sweepsDisabledByLock = [];
|
|
642
|
+
this.sweepsEnabledByUnlock = toEnable;
|
|
643
|
+
if (toEnable.length > 0) {
|
|
644
|
+
try {
|
|
645
|
+
await sdk.Sweep.enable(...toEnable);
|
|
646
|
+
}
|
|
647
|
+
catch {
|
|
648
|
+
await Promise.allSettled(toEnable.map((sid) => sdk.Sweep.enable(sid)));
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return true;
|
|
652
|
+
}
|
|
653
|
+
isNavigationLocked() {
|
|
654
|
+
return this.sweepsDisabledByLock.length > 0;
|
|
655
|
+
}
|
|
656
|
+
/** Sweeps currently disabled by the navigation lock */
|
|
657
|
+
getSweepsDisabledByLock() {
|
|
658
|
+
return [...this.sweepsDisabledByLock];
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Legacy API: attaches a gizmo to a model node. Prefer attachGizmo(uuid, mode).
|
|
662
|
+
*/
|
|
177
663
|
async attachGizmoControlTo3DObject(sdk, modelNode, sceneObject, mode, visible, isNewObject) {
|
|
178
664
|
let node = sceneObject.addNode();
|
|
179
665
|
if (!node) {
|
|
180
666
|
const [newSceneObject] = await sdk.Scene.createObjects(1);
|
|
181
667
|
node = newSceneObject.addNode();
|
|
182
668
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (isNewObject) {
|
|
190
|
-
if (!this.lastObject3D || !this.lastObject3D.controls) {
|
|
191
|
-
try {
|
|
192
|
-
modelNode.obj3D.uuid = this.lastObject3D.uuid || this.lastObject3D.id;
|
|
193
|
-
}
|
|
194
|
-
catch (e) {
|
|
195
|
-
console.log(`id obj in Scene was not assigned to id from DB`);
|
|
196
|
-
}
|
|
197
|
-
this.lastObject3D = modelNode.obj3D;
|
|
669
|
+
if (isNewObject && (!this.lastObject3D || !this.lastObject3D.controls)) {
|
|
670
|
+
try {
|
|
671
|
+
modelNode.obj3D.uuid = this.lastObject3D.uuid || this.lastObject3D.id;
|
|
672
|
+
}
|
|
673
|
+
catch (e) {
|
|
674
|
+
// lastObject3D is not set: the model keeps its own uuid
|
|
198
675
|
}
|
|
199
676
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
677
|
+
this.detachGizmo();
|
|
678
|
+
this.createGizmo(modelNode.obj3D.uuid, modelNode, sceneObject, mode, visible, node);
|
|
679
|
+
this.lastObject3D = modelNode.obj3D;
|
|
203
680
|
return modelNode;
|
|
204
681
|
}
|
|
682
|
+
/** Removes the gizmo of the last added / edited object */
|
|
205
683
|
removeGizmoFromLastObject() {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
684
|
+
const last = this.lastObject3D;
|
|
685
|
+
if (!last)
|
|
686
|
+
return;
|
|
687
|
+
const uuid = last.uuid ?? last.id;
|
|
688
|
+
if (uuid && this.gizmos.has(uuid)) {
|
|
689
|
+
this.detachGizmo(uuid);
|
|
690
|
+
}
|
|
691
|
+
else if (last.controls) {
|
|
692
|
+
// gizmo not created by this service: best effort
|
|
693
|
+
last.controls.transformControls.visible = false;
|
|
694
|
+
last.controls.transformControls.dispose();
|
|
695
|
+
last.controls = null;
|
|
210
696
|
}
|
|
211
697
|
}
|
|
212
|
-
|
|
213
|
-
|
|
698
|
+
//
|
|
699
|
+
// ---------- Security camera ----------
|
|
700
|
+
//
|
|
701
|
+
applyViewFrustum(uuid, visible) {
|
|
702
|
+
const animator = this.securityCameraAnimators.get(uuid);
|
|
703
|
+
if (!animator)
|
|
704
|
+
return false;
|
|
705
|
+
const current = this.viewFrustumVisible.get(uuid) ?? true;
|
|
706
|
+
if (current === visible)
|
|
707
|
+
return true;
|
|
708
|
+
try {
|
|
709
|
+
animator.toggleViewFrustum();
|
|
710
|
+
}
|
|
711
|
+
catch {
|
|
712
|
+
return false;
|
|
713
|
+
}
|
|
714
|
+
this.viewFrustumVisible.set(uuid, visible);
|
|
715
|
+
return true;
|
|
716
|
+
}
|
|
717
|
+
/** Shows / hides the view frustum of the security camera `uuid` */
|
|
718
|
+
setViewFrustum(uuid, visible) {
|
|
719
|
+
return this.applyViewFrustum(uuid, visible);
|
|
720
|
+
}
|
|
721
|
+
isViewFrustumVisible(uuid) {
|
|
722
|
+
return this.viewFrustumVisible.get(uuid) ?? false;
|
|
723
|
+
}
|
|
724
|
+
/** Toggles the frustum of `uuid`, or of the last loaded security camera when omitted */
|
|
725
|
+
toggleViewFrustum(uuid) {
|
|
726
|
+
const id = uuid ?? this.lastSecurityCameraUuid;
|
|
727
|
+
if (id && this.securityCameraAnimators.has(id)) {
|
|
728
|
+
this.applyViewFrustum(id, !(this.viewFrustumVisible.get(id) ?? true));
|
|
729
|
+
}
|
|
730
|
+
else if (!uuid && this.securityCameraAnimator) {
|
|
731
|
+
// animator set by hand (legacy)
|
|
214
732
|
this.securityCameraAnimator.toggleViewFrustum();
|
|
215
733
|
}
|
|
216
734
|
}
|
|
217
735
|
clear() {
|
|
736
|
+
Array.from(this.gizmos.keys()).forEach((id) => this.detachGizmo(id));
|
|
218
737
|
this.dictionnaryObjects3D.clear();
|
|
219
738
|
this.dictionnarySceneObjects3D.clear();
|
|
739
|
+
this.loaderComponents.clear();
|
|
740
|
+
this.securityCameraAnimators.clear();
|
|
741
|
+
this.viewFrustumVisible.clear();
|
|
742
|
+
this.lastSecurityCameraUuid = null;
|
|
743
|
+
this.sweepsDisabledByLock = [];
|
|
220
744
|
this.lastObject3D = null;
|
|
221
745
|
this.azimuthalCrown = null;
|
|
222
746
|
this.securityCameraAnimator = null;
|
|
@@ -231,4 +755,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
231
755
|
providedIn: 'root',
|
|
232
756
|
}]
|
|
233
757
|
}], ctorParameters: () => [] });
|
|
234
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0dGVycG9ydC1vYmplY3QzZC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWNvcmUvc3JjL2xpYi9zZXJ2aWNlcy9tYXR0ZXJwb3J0LW9iamVjdDNkLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWEsT0FBTyxFQUFxQixNQUFNLGtCQUFrQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFDakMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlEQUF5RCxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3REFBd0QsQ0FBQztBQUN2RixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seURBQXlELENBQUM7QUFDekYsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDZDQUE2QyxDQUFDOztBQUt2RSxNQUFNLE9BQU8seUJBQXlCO0lBQzdCLG9CQUFvQixHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ25ELHlCQUF5QixHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ3hELFlBQVksQ0FBTSxDQUFDLGtCQUFrQjtJQUNyQyxhQUFhLENBQU07SUFDbkIsc0JBQXNCLENBQU07SUFDNUIsY0FBYyxDQUFNO0lBQ3BCLFlBQVksQ0FBTTtJQUNsQixpQkFBaUIsR0FBRyxJQUFJLENBQUM7SUFFaEMsZ0JBQWdCLENBQUM7SUFFakIsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEdBQVE7UUFDL0IsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkQsTUFBTSxJQUFJLEdBQUcsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FB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QUcsSUFBSSxDQUFDO1FBQ3BDLENBQUM7SUFDSCxDQUFDO0lBRUQsaUJBQWlCO1FBQ2YsSUFBSSxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUNsRCxDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUs7UUFDSCxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbEMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1FBQzNCLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLENBQUM7UUFDbkMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztJQUNoQyxDQUFDO3dHQXJPVSx5QkFBeUI7NEdBQXpCLHlCQUF5QixjQUZ4QixNQUFNOzs0RkFFUCx5QkFBeUI7a0JBSHJDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSU9iamVjdDNELCBQb2lUeXBlLCBQT0ksIERiT2JqZWN0VHlwZSB9IGZyb20gJy4uL3R5cGVzLnNlcnZpY2UnO1xuaW1wb3J0IHsgT2JqZWN0M0QgfSBmcm9tICd0aHJlZSc7XG5pbXBvcnQgeyBOZXN0VGhlcm1vc3RhdCB9IGZyb20gJy4uL21hdHRlcnBvcnQtZXh0ZW5zaW9ucy9uZXN0LXRoZXJtb3N0YXQvTmVzdFRoZXJtb3N0YXQnO1xuaW1wb3J0IHsgUGxhbmVSZW5kZXJlciB9IGZyb20gJy4uL21hdHRlcnBvcnQtZXh0ZW5zaW9ucy9uZXN0LXRoZXJtb3N0YXQvUGxhbmVSZW5kZXJlcic7XG5pbXBvcnQgeyBDYW52YXNSZW5kZXJlciB9IGZyb20gXCIuLi9tYXR0ZXJwb3J0LWV4dGVuc2lvbnMvbmVzdC10aGVybW9zdGF0L0NhbnZhc1JlbmRlcmVyXCI7XG5pbXBvcnQgeyBUdlBsYXllciB9IGZyb20gXCIuLi9tYXR0ZXJwb3J0LWV4dGVuc2lvbnMvdHYtcGxheWVyL1R2UGxheWVyXCI7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBNYXR0ZXJwb3J0T2JqZWN0M0RTZXJ2aWNlIHtcbiAgcHVibGljIGRpY3Rpb25uYXJ5T2JqZWN0czNEOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xuICBwdWJsaWMgZGljdGlvbm5hcnlTY2VuZU9iamVjdHMzRDogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcbiAgcHVibGljIGxhc3RPYmplY3QzRDogYW55OyAvLyBUaHJlZSBKUyBvYmplY3RcbiAgcHVibGljIG9iamVjdENvbnRyb2w6IGFueTtcbiAgcHVibGljIHNlY3VyaXR5Q2FtZXJhQW5pbWF0b3I6IGFueTtcbiAgcHVibGljIGF6aW11dGhhbENyb3duOiBhbnk7XG4gIHB1YmxpYyB0aHJlZUpTU2NlbmU6IGFueTtcbiAgcHVibGljIG5vTGlnaHRGb3JPYmplY3RzID0gdHJ1ZTtcblxuICBjb25zdHJ1Y3RvcigpIHsgfVxuXG4gIGFzeW5jIGluaXQzRE9iamVjdFZpZXdlcihzZGs6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IFtzY2VuZU9iamVjdF0gPSBhd2FpdCBzZGsuU2NlbmUuY3JlYXRlT2JqZWN0cygxKTtcbiAgICBjb25zdCBub2RlID0gc2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgIG5vZGUuc3RhcnQoKTtcbiAgICB0aGlzLnRocmVlSlNTY2VuZSA9IG5vZGUub2JqM0QucGFyZW50O1xuXG4gICAgY29uc3Qgbm9kZUNvbnRyb2wgPSBzY2VuZU9iamVjdC5hZGROb2RlKCk7XG4gICAgdGhpcy5vYmplY3RDb250cm9sID0gbm9kZUNvbnRyb2wuYWRkQ29tcG9uZW50KCdtcC50cmFuc2Zvcm1Db250cm9scycpO1xuICAgIG5vZGVDb250cm9sLnN0YXJ0KCk7XG4gIH1cblxuICBhc3luYyBhZGQzRE9iamVjdChcbiAgICBzZGs6IGFueSxcbiAgICBvYmo6IElPYmplY3QzRCxcbiAgICBtb2RlPzogJ3RyYW5zbGF0ZScgfCAncm90YXRlJ1xuICApOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSkgPT4ge1xuICAgICAgY29uc3QgW3NjZW5lT2JqZWN0XSA9IGF3YWl0IHNkay5TY2VuZS5jcmVhdGVPYmplY3RzKDEpO1xuXG4gICAgICBsZXQgaXNBbmltYXRlZFNlY3VyaXR5Q2FtZXJhID0gKG9iai5vYmplY3QgPT09IFwic2VjdXJpdHlfY2FtZXJhXCIpO1xuICAgICAgbGV0IGlzTmVzdFRoZXJtb3N0YXQgPSAob2JqLm9iamVjdCA9PT0gXCJuZXN0X3RoZXJtb3N0YXRcIik7XG4gICAgICBsZXQgaXNTbWFydGVycGxhblByb21vdGlvbmFsVmlkZW8gPSAob2JqLm9iamVjdCA9PT0gJ3ZpZGVvJyk7XG4gICAgICBsZXQgaXNBemltdXRoYWxDcm93biA9IChvYmoub2JqZWN0ID09PSAnYXppbXV0aCcpO1xuXG4gICAgICBjb25zdCBtb2RlbE5vZGUgPSBzY2VuZU9iamVjdC5hZGROb2RlKCk7XG4gICAgICBsZXQgY29tcG9uZW50ID0gbnVsbDtcbiAgICAgIGNvbnN0IGluaXRpYWwgPSB7XG4gICAgICAgIHVybDogYC9hc3NldHMvM0RvYmplY3RzL29iamVjdHMvJHtvYmoub2JqZWN0fSR7b2JqLmZvcm1hdC5pbmRleE9mKCcuJykgPT09IC0xID8gJy4nICsgb2JqLmZvcm1hdCA6IG9iai5mb3JtYXR9YCxcbiAgICAgICAgbG9jYWxSb3RhdGlvbjogeyBcInhcIjogMCwgXCJ5XCI6IDAsIFwielwiOiAwIH0sXG4gICAgICAgIGxvY2FsUG9zaXRpb246IHsgXCJ4XCI6IDAsIFwieVwiOiAwLCBcInpcIjogMCB9LFxuICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICBjb2xsaWRlckVuYWJsZWQ6IHRydWVcbiAgICAgIH07XG5cbiAgICAgIHN3aXRjaCAob2JqLmZvcm1hdCkge1xuICAgICAgICBjYXNlICcub2JqJzogY2FzZSAnb2JqJzogY29tcG9uZW50ID0gbW9kZWxOb2RlLmFkZENvbXBvbmVudCgnbXAub2JqTG9hZGVyJywgaW5pdGlhbCk7IGJyZWFrO1xuICAgICAgICBjYXNlICcuZmJ4JzogY2FzZSAnZmJ4JzogY29tcG9uZW50ID0gbW9kZWxOb2RlLmFkZENvbXBvbmVudCgnbXAuZmJ4TG9hZGVyJywgaW5pdGlhbCk7IGJyZWFrO1xuICAgICAgICBjYXNlICcuZ2x0Zic6IGNhc2UgJ2dsdGYnOiBjYXNlICcuZ2xiJzogY2FzZSAnZ2xiJzogY29tcG9uZW50ID0gbW9kZWxOb2RlLmFkZENvbXBvbmVudCgnbXAuZ2x0ZkxvYWRlcicsIGluaXRpYWwpOyBicmVhaztcbiAgICAgICAgY2FzZSAnLmRhZSc6IGNhc2UgJ2RhZSc6IGNvbXBvbmVudCA9IG1vZGVsTm9kZS5hZGRDb21wb25lbnQoJ21wLmRhZUxvYWRlcicsIGluaXRpYWwpOyBicmVhaztcbiAgICAgICAgZGVmYXVsdDogY29uc29sZS5sb2coJ0Zvcm1hdCBub3Qgc3VwcG9ydGVkJyk7IGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5ub0xpZ2h0Rm9yT2JqZWN0cykge1xuICAgICAgICBjb25zdCBsaWdodHNOb2RlID0gc2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgICAgICBsaWdodHNOb2RlLmFkZENvbXBvbmVudCgnbXAuYW1iaWVudExpZ2h0Jywge1xuICAgICAgICAgIGludGVuc2l0eTogMSxcbiAgICAgICAgICBjb2xvcjogeyByOiAxLjAsIGc6IDEuMCwgYjogMS4wIH0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm5vTGlnaHRGb3JPYmplY3RzID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIG1vZGVsTm9kZS5vYmozRC5wb3NpdGlvbi5zZXQob2JqLnBvc2l0aW9uLngsIG9iai5wb3NpdGlvbi55LCBvYmoucG9zaXRpb24ueik7XG4gICAgICBtb2RlbE5vZGUub2JqM0Qucm90YXRpb24uc2V0KG9iai5yb3RhdGlvbi54LCBvYmoucm90YXRpb24ueSwgb2JqLnJvdGF0aW9uLnopO1xuICAgICAgbW9kZWxOb2RlLm9iajNELnNjYWxlLnNldChvYmouc2NhbGUueCwgb2JqLnNjYWxlLnksIG9iai5zY2FsZS56KTtcblxuICAgICAgaWYgKGlzQXppbXV0aGFsQ3Jvd24pIHtcbiAgICAgICAgdGhpcy5hemltdXRoYWxDcm93biA9IG1vZGVsTm9kZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vZGUgJiYgIWlzTmVzdFRoZXJtb3N0YXQpIHtcbiAgICAgICAgdGhpcy5hdHRhY2hHaXptb0NvbnRyb2xUbzNET2JqZWN0KHNkaywgbW9kZWxOb2RlLCBzY2VuZU9iamVjdCwgbW9kZSwgdHJ1ZSwgdHJ1ZSkuY2F0Y2goKGUpID0+IGNvbnNvbGUubG9nKGUpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMubGFzdE9iamVjdDNEICYmIHR5cGVvZiB0aGlzLmxhc3RPYmplY3QzRC5pZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbW9kZWxOb2RlLm9iajNELnV1aWQgPSB0aGlzLmxhc3RPYmplY3QzRC5pZDtcbiAgICAgIH0gZWxzZSBpZiAob2JqLmlkKSB7XG4gICAgICAgIG1vZGVsTm9kZS5vYmozRC51dWlkID0gb2JqLmlkO1xuICAgICAgfVxuICAgICAgdGhpcy5sYXN0T2JqZWN0M0QgPSBtb2RlbE5vZGUub2JqM0Q7XG5cbiAgICAgIHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0Quc2V0KG1vZGVsTm9kZS5vYmozRC51dWlkLCBtb2RlbE5vZGUpO1xuICAgICAgdGhpcy5kaWN0aW9ubmFyeVNjZW5lT2JqZWN0czNELnNldChtb2RlbE5vZGUub2JqM0QudXVpZCwgc2NlbmVPYmplY3QpO1xuXG4gICAgICBpZiAoaXNBbmltYXRlZFNlY3VyaXR5Q2FtZXJhKSB7XG4gICAgICAgIGNvbnN0IGFuaW1hdG9yID0gbW9kZWxOb2RlLmFkZENvbXBvbmVudCgnbXAuc2VjdXJpdHlDYW1lcmEnLCB7XG4gICAgICAgICAgXCJuZWFyUGxhbmVcIjogMC4xLCBcImZhclBsYW5lXCI6IDEwLCBcImhvcml6b250YWxGT1ZcIjogNTIsIFwiYXNwZWN0XCI6IDEuNzc3Nzc3Nzc3Nzc3Nzc3NyxcbiAgICAgICAgICBcImxvY2FsUG9zaXRpb25cIjogeyBcInhcIjogMC4zLCBcInlcIjogMC4xOCwgXCJ6XCI6IDAgfSxcbiAgICAgICAgICBcImxvY2FsUm90YXRpb25cIjogeyBcInhcIjogLTE1LCBcInlcIjogLTkwLCBcInpcIjogMCB9LFxuICAgICAgICAgIFwiY29sb3JcIjogNjUyODAsIFwicGFuUGVyaW9kXCI6IDUsIFwicGFuQW5nbGVcIjogLTQ1XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNlY3VyaXR5Q2FtZXJhQW5pbWF0b3IgPSBhbmltYXRvcjtcbiAgICAgICAgaWYgKCFvYmoudmlld0ZydXN0dW0pIHtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgYW5pbWF0b3IudG9nZ2xlVmlld0ZydXN0dW0oKTsgfSwgMTAwMCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGlzTmVzdFRoZXJtb3N0YXQpIHtcbiAgICAgICAgY29uc3QgY3YgPSBuZXcgQ2FudmFzUmVuZGVyZXIoKTsgY3Yub25Jbml0KCk7XG4gICAgICAgIGNvbnN0IHBsYW5lID0gbmV3IFBsYW5lUmVuZGVyZXIoKTtcbiAgICAgICAgcGxhbmUub3V0cHV0cyA9IHsgb2JqZWN0Um9vdDogbmV3IE9iamVjdDNEKCksIGNvbGxpZGVyOiBuZXcgT2JqZWN0M0QoKSB9O1xuICAgICAgICBjb25zdCBpbnB1dFRleHR1cmUgPSBjdi5vdXRwdXRzLnRleHR1cmU7XG4gICAgICAgIHBsYW5lLnNldFJvb3RTY2VuZSh0aGlzLnRocmVlSlNTY2VuZSk7XG4gICAgICAgIHBsYW5lLm9uSW5pdChtb2RlbE5vZGUsIGlucHV0VGV4dHVyZSk7XG4gICAgICAgIGNvbnN0IHNjID0gbmV3IE5lc3RUaGVybW9zdGF0KCk7XG4gICAgICAgIHNjLnNldENvbXBvbmVudChjb21wb25lbnQsIHBsYW5lLCBjdik7XG4gICAgICAgIHNjLnNldFJvb3RTY2VuZSh0aGlzLnRocmVlSlNTY2VuZSk7XG4gICAgICAgIHNjLm9uSW5pdChtb2RlbE5vZGUsIHBsYW5lLCBpbnB1dFRleHR1cmUpO1xuICAgICAgICBjdi5zZXRDYW52YXNOZXN0VGhlcm1vc3RhdFBhaW50ZXIoc2MpO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgc2MuaW5wdXRzLmxvYWRpbmdTdGF0ZSA9IFwiTG9hZGVkXCI7IHNjLm9uSW5wdXRzVXBkYXRlZCgpOyB9LCA1MDAwKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzU21hcnRlcnBsYW5Qcm9tb3Rpb25hbFZpZGVvKSB7XG4gICAgICAgIGNvbnN0IHNjID0gbmV3IFR2UGxheWVyKCk7IHNjLnNldENvbXBvbmVudChjb21wb25lbnQpOyBzYy5vbkluaXQobW9kZWxOb2RlKTtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IHNjLmlucHV0cy5sb2FkaW5nU3RhdGUgPSBcIkxvYWRlZFwiOyBzYy5vbklucHV0c1VwZGF0ZWQoKTsgfSwgNTAwMCk7XG4gICAgICB9XG5cbiAgICAgIHNjZW5lT2JqZWN0LnN0YXJ0KCk7XG4gICAgICByZXNvbHZlKHRoaXMubGFzdE9iamVjdDNEKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZU9iamVjdDNEKHV1aWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG9iaiA9IHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuZ2V0KHV1aWQpO1xuICAgIGlmIChvYmopIG9iai5vYmozRC52aXNpYmxlID0gZmFsc2U7XG4gIH1cblxuICBnZXRPYmplY3QzRE1vZGVsTm9kZUZyb21EaWN0aW9ubmFyeSh1dWlkOiBzdHJpbmcpOiBhbnkge1xuICAgIGxldCBvYmogPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldCh1dWlkKTtcbiAgICBpZiAoIW9iaikgcmV0dXJuIG51bGw7XG4gICAgaWYgKG9iai5vYmozRC51dWlkICE9IHV1aWQpIHtcbiAgICAgIG9iai5vYmozRC51dWlkID0gdXVpZDtcbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIHRvZ2dsZU9iamVjdFZpc2liaWxpdHkob2JqZWN0SWQ6IGFueSkge1xuICAgIGxldCBvYmogPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldChvYmplY3RJZCk7XG4gICAgaWYgKG9iaikgb2JqLm9iajNELnZpc2libGUgPSAhb2JqLm9iajNELnZpc2libGU7XG4gIH1cblxuICBpc09iamVjdFZpc2libGUob2JqZWN0SWQ6IGFueSk6IGJvb2xlYW4ge1xuICAgIGxldCBvYmogPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldChvYmplY3RJZCk7XG4gICAgcmV0dXJuIG9iaiA/IG9iai5vYmozRC52aXNpYmxlIDogZmFsc2U7XG4gIH1cblxuICBhc3luYyBwb2ludENhbWVyYVRvM0RPYmplY3Qoc2RrOiBhbnksIG9iamVjdElkOiBhbnksIGNyZWF0ZVRhZ0NhbGxiYWNrOiAodGFnVHlwZTogUG9pVHlwZSwgb2JqZWN0OiBEYk9iamVjdFR5cGUsIHBvaTogUE9JKSA9PiBQcm9taXNlPGFueT4sIGdvVG9UYWdDYWxsYmFjazogKHNpZDogc3RyaW5nKSA9PiBQcm9taXNlPGFueT4sIGRlbGV0ZUxhc3RUYWdDYWxsYmFjazogKCkgPT4gdm9pZCwgZ2V0VGFnRnJvbUVsZW1lbnRJZDogKGlkOiBzdHJpbmcpID0+IHsgdGFnOiBzdHJpbmcsIHN3ZWVwOiBzdHJpbmcgfSkge1xuICAgIGxldCBvYmogPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldChvYmplY3RJZCk7XG4gICAgY29uc3QgcG9pT2JqZWN0ID0ge1xuICAgICAgY29vcmRpbmF0ZTogSlNPTi5zdHJpbmdpZnkob2JqLm9iajNELnBvc2l0aW9uKSxcbiAgICAgIHR5cGU6IFBvaVR5cGUuT0JKRUNUM0QsXG4gICAgICBlbGVtZW50SUQ6IG9iamVjdElkLFxuICAgIH0gYXMgUE9JO1xuICAgIGNvbnN0IG9iamVjdERiID0geyBpZDogb2JqZWN0SWQgfSBhcyBEYk9iamVjdFR5cGU7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGNyZWF0ZVRhZ0NhbGxiYWNrKFBvaVR5cGUuT0JKRUNUM0QsIG9iamVjdERiLCBwb2lPYmplY3QpO1xuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7IH1cblxuICAgIGxldCByZXN1bHQgPSBnZXRUYWdGcm9tRWxlbWVudElkKG9iamVjdElkKTtcbiAgICBhd2FpdCBnb1RvVGFnQ2FsbGJhY2socmVzdWx0LnRhZyk7XG4gICAgZGVsZXRlTGFzdFRhZ0NhbGxiYWNrKCk7XG4gIH1cblxuICBnZXRTY2VuZU5vZGVGcm9tT2JqZWN0M0RJZCh1dWlkOiBzdHJpbmcpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLmRpY3Rpb25uYXJ5U2NlbmVPYmplY3RzM0QuZ2V0KHV1aWQpO1xuICB9XG5cbiAgYXN5bmMgZGlzcGxheUF6aW11dGFsQ3Jvd24ocG9zZUNhbWVyYTogYW55KSB7XG4gICAgaWYgKHRoaXMuYXppbXV0aGFsQ3Jvd24gJiYgcG9zZUNhbWVyYSkge1xuICAgICAgdGhpcy5hemltdXRoYWxDcm93bi5vYmozRC5wb3NpdGlvbi5zZXQocG9zZUNhbWVyYS5wb3NpdGlvbi54LCBwb3NlQ2FtZXJhLnBvc2l0aW9uLnksIHBvc2VDYW1lcmEucG9zaXRpb24ueilcbiAgICB9XG4gIH1cblxuICBhc3luYyBhdHRhY2hHaXptb0NvbnRyb2xUbzNET2JqZWN0KFxuICAgIHNkazogYW55LFxuICAgIG1vZGVsTm9kZTogYW55LFxuICAgIHNjZW5lT2JqZWN0OiBhbnksXG4gICAgbW9kZTogJ3RyYW5zbGF0ZScgfCAncm90YXRlJyB8ICdzY2FsZScsXG4gICAgdmlzaWJsZTogYm9vbGVhbixcbiAgICBpc05ld09iamVjdDogYm9vbGVhblxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGxldCBub2RlID0gc2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgIGlmICghbm9kZSkge1xuICAgICAgY29uc3QgW25ld1NjZW5lT2JqZWN0XSA9IGF3YWl0IHNkay5TY2VuZS5jcmVhdGVPYmplY3RzKDEpO1xuICAgICAgbm9kZSA9IG5ld1NjZW5lT2JqZWN0LmFkZE5vZGUoKTtcbiAgICB9XG4gICAgY29uc3QgbXlDb250cm9sID0gbm9kZS5hZGRDb21wb25lbnQoJ21wLnRyYW5zZm9ybUNvbnRyb2xzJyk7XG4gICAgbm9kZS5zdGFydCgpO1xuICAgIG15Q29udHJvbC50cmFuc2Zvcm1Db250cm9scy52aXNpYmxlID0gdmlzaWJsZTtcbiAgICBteUNvbnRyb2wuaW5wdXRzLnNlbGVjdGlvbiA9IG1vZGVsTm9kZTtcbiAgICBteUNvbnRyb2wuaW5wdXRzLm1vZGUgPSBtb2RlO1xuICAgIG1vZGVsTm9kZS5vYmozRC5jb250cm9scyA9IG15Q29udHJvbDtcbiAgICBpZiAoaXNOZXdPYmplY3QpIHtcbiAgICAgIGlmICghdGhpcy5sYXN0T2JqZWN0M0QgfHwgIXRoaXMubGFzdE9iamVjdDNELmNvbnRyb2xzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbW9kZWxOb2RlLm9iajNELnV1aWQgPSB0aGlzLmxhc3RPYmplY3QzRC51dWlkIHx8IHRoaXMubGFzdE9iamVjdDNELmlkO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYGlkIG9iaiBpbiBTY2VuZSB3YXMgbm90IGFzc2lnbmVkIHRvIGlkIGZyb20gREJgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxhc3RPYmplY3QzRCA9IG1vZGVsTm9kZS5vYmozRDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sYXN0T2JqZWN0M0QgPSBtb2RlbE5vZGUub2JqM0Q7XG4gICAgfVxuICAgIHJldHVybiBtb2RlbE5vZGU7XG4gIH1cblxuICByZW1vdmVHaXptb0Zyb21MYXN0T2JqZWN0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmxhc3RPYmplY3QzRCAmJiB0aGlzLmxhc3RPYmplY3QzRC5jb250cm9scykge1xuICAgICAgdGhpcy5sYXN0T2JqZWN0M0QuY29udHJvbHMudHJhbnNmb3JtQ29udHJvbHMudmlzaWJsZSA9IGZhbHNlO1xuICAgICAgdGhpcy5sYXN0T2JqZWN0M0QuY29udHJvbHMudHJhbnNmb3JtQ29udHJvbHMuZGlzcG9zZSgpO1xuICAgICAgdGhpcy5sYXN0T2JqZWN0M0QuY29udHJvbHMgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHRvZ2dsZVZpZXdGcnVzdHVtKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNlY3VyaXR5Q2FtZXJhQW5pbWF0b3IpIHtcbiAgICAgIHRoaXMuc2VjdXJpdHlDYW1lcmFBbmltYXRvci50b2dnbGVWaWV3RnJ1c3R1bSgpO1xuICAgIH1cbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuY2xlYXIoKTtcbiAgICB0aGlzLmRpY3Rpb25uYXJ5U2NlbmVPYmplY3RzM0QuY2xlYXIoKTtcbiAgICB0aGlzLmxhc3RPYmplY3QzRCA9IG51bGw7XG4gICAgdGhpcy5hemltdXRoYWxDcm93biA9IG51bGw7XG4gICAgdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9yID0gbnVsbDtcbiAgICB0aGlzLm5vTGlnaHRGb3JPYmplY3RzID0gdHJ1ZTtcbiAgfVxufVxuIl19
|
|
758
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0dGVycG9ydC1vYmplY3QzZC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWNvcmUvc3JjL2xpYi9zZXJ2aWNlcy9tYXR0ZXJwb3J0LW9iamVjdDNkLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFFTCxPQUFPLEdBU1IsTUFBTSxrQkFBa0IsQ0FBQztBQUMxQixPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBQzNELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5REFBeUQsQ0FBQztBQUN6RixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0RBQXdELENBQUM7QUFDdkYsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlEQUF5RCxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQzs7QUFxQnZFLE1BQU0sT0FBTyx5QkFBeUI7SUFDN0Isb0JBQW9CLEdBQXFCLElBQUksR0FBRyxFQUFFLENBQUM7SUFDbkQseUJBQXlCLEdBQXFCLElBQUksR0FBRyxFQUFFLENBQUM7SUFDeEQsWUFBWSxDQUFNLENBQUMsa0JBQWtCO0lBQ3JDLGFBQWEsQ0FBTTtJQUNuQixzQkFBc0IsQ0FBTTtJQUM1QixjQUFjLENBQU07SUFDcEIsWUFBWSxDQUFNO0lBQ2xCLGlCQUFpQixHQUFHLElBQUksQ0FBQztJQUVoQyxnRUFBZ0U7SUFDekQsYUFBYSxHQUFHLEtBQUssQ0FBQztJQUM3QixnRkFBZ0Y7SUFDekUsZUFBZSxHQUFHLENBQUMsQ0FBQztJQUMzQiw4R0FBOEc7SUFDdkcsYUFBYSxHQUFHLEdBQUcsQ0FBQztJQUUzQiw4REFBOEQ7SUFDOUMseUJBQXlCLEdBQUcsSUFBSSxPQUFPLEVBQTJCLENBQUM7SUFFbkYsb0dBQW9HO0lBQzdGLHVCQUF1QixHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ3JELGtCQUFrQixHQUF5QixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ3JELHNCQUFzQixHQUFrQixJQUFJLENBQUM7SUFFckQsNkVBQTZFO0lBQ3JFLGdCQUFnQixHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRS9DLE1BQU0sR0FBNEIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUM1QyxlQUFlLEdBQWtCLElBQUksQ0FBQztJQUN0QyxTQUFTLEdBQXFCLElBQUksQ0FBQztJQUUzQyx5RUFBeUU7SUFDakUsb0JBQW9CLEdBQWEsRUFBRSxDQUFDO0lBQzVDLGlHQUFpRztJQUN6RixxQkFBcUIsR0FBYSxFQUFFLENBQUM7SUFFNUIsTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7SUFFckMsZ0JBQWdCLENBQUM7SUFFakIsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEdBQVE7UUFDL0IsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkQsTUFBTSxJQUFJLEdBQUcsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFFdEMsTUFBTSxXQUFXLEdBQUcsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzFDLElBQUksQ0FBQyxhQUFhLEdBQUcsV0FBVyxDQUFDLFlBQVksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3RFLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBRUQsMEZBQTBGO0lBQ2xGLHNCQUFzQixDQUFDLE1BQWM7UUFDM0MsUUFBUSxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDO1lBQ3JDLEtBQUssTUFBTSxDQUFDO1lBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQyxPQUFPLGNBQWMsQ0FBQztZQUMvQyxLQUFLLE1BQU0sQ0FBQztZQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsT0FBTyxjQUFjLENBQUM7WUFDL0MsS0FBSyxPQUFPLENBQUM7WUFBQyxLQUFLLE1BQU0sQ0FBQztZQUFDLEtBQUssTUFBTSxDQUFDO1lBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQyxPQUFPLGVBQWUsQ0FBQztZQUMzRSxLQUFLLE1BQU0sQ0FBQztZQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsT0FBTyxjQUFjLENBQUM7WUFDL0MsT0FBTyxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUM7UUFDdkIsQ0FBQztJQUNILENBQUM7SUFFRCxnR0FBZ0c7SUFDeEYsa0JBQWtCLENBQUMsU0FBYyxFQUFFLFNBQWlCO1FBQzFELE9BQU8sSUFBSSxPQUFPLENBQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDM0MsTUFBTSxRQUFRLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDO1lBQ3hELElBQUksUUFBUSxFQUFFLEVBQUUsQ0FBQztnQkFDZixPQUFPLEVBQUUsQ0FBQztnQkFDVixPQUFPO1lBQ1QsQ0FBQztZQUNELE1BQU0sSUFBSSxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUU7Z0JBQzVCLElBQUksUUFBUSxFQUFFLEVBQUUsQ0FBQztvQkFDZixhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ3BCLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDcEIsT0FBTyxFQUFFLENBQUM7Z0JBQ1osQ0FBQztZQUNILENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNQLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQzVCLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDcEIsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLDZCQUE2QixTQUFTLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDakUsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ2hCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLFdBQVcsQ0FDZixHQUFRLEVBQ1IsR0FBYyxFQUNkLElBQWdCO1FBRWhCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDM0QsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ25FLENBQUM7UUFFRCxNQUFNLENBQUMsV0FBVyxDQUFDLEdBQUcsTUFBTSxHQUFHLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV2RCxNQUFNLHdCQUF3QixHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssaUJBQWlCLENBQUMsQ0FBQztRQUNoRixNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssaUJBQWlCLENBQUMsQ0FBQztRQUN4RSxNQUFNLDZCQUE2QixHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssT0FBTyxDQUFDLENBQUM7UUFDM0UsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDO1FBRWhFLE1BQU0sU0FBUyxHQUFHLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN4QyxNQUFNLE9BQU8sR0FBRztZQUNkLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxJQUFJLDZCQUE2QixHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRTtZQUMxSCxhQUFhLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRTtZQUN6QyxhQUFhLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRTtZQUN6QyxPQUFPLEVBQUUsSUFBSTtZQUNiLGVBQWUsRUFBRSxJQUFJO1NBQ3RCLENBQUM7UUFDRixNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsWUFBWSxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUU5RCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzNCLE1BQU0sVUFBVSxHQUFHLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUN6QyxVQUFVLENBQUMsWUFBWSxDQUFDLGlCQUFpQixFQUFFO2dCQUN6QyxTQUFTLEVBQUUsQ0FBQztnQkFDWixLQUFLLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRTthQUNsQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsS0FBSyxDQUFDO1FBQ2pDLENBQUM7UUFFRCxTQUFTLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3RSxTQUFTLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3RSxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVqRSxrR0FBa0c7UUFDbEcsNEZBQTRGO1FBQzVGLGdHQUFnRztRQUNoRyxJQUFJLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNYLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDaEMsQ0FBQzthQUFNLElBQUksSUFBSSxDQUFDLFlBQVksSUFBSSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3pFLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1FBQzlDLENBQUM7UUFDRCxNQUFNLElBQUksR0FBVyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQztRQUMxQyxJQUFJLENBQUMsWUFBWSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFFcEMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFM0MsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDO1FBQ2xDLENBQUM7UUFFRCxJQUFJLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDOUIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUE4QyxDQUFDLENBQUMsQ0FBQztRQUMzRixDQUFDO1FBRUQsSUFBSSxRQUFRLEdBQVEsSUFBSSxDQUFDO1FBQ3pCLElBQUksd0JBQXdCLEVBQUUsQ0FBQztZQUM3QixRQUFRLEdBQUcsU0FBUyxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsRUFBRTtnQkFDckQsV0FBVyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLGVBQWUsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLGtCQUFrQjtnQkFDbkYsZUFBZSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUU7Z0JBQ2hELGVBQWUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRTtnQkFDL0MsT0FBTyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUU7YUFDaEQsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLHNCQUFzQixHQUFHLFFBQVEsQ0FBQztZQUN2QyxJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztZQUNqRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLDZDQUE2QztZQUN0RixJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDO1FBQ3JDLENBQUM7UUFFRCxJQUFJLGdCQUFnQixFQUFFLENBQUM7WUFDckIsTUFBTSxFQUFFLEdBQUcsSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUM3QyxNQUFNLEtBQUssR0FBRyxJQUFJLGFBQWEsRUFBRSxDQUFDO1lBQ2xDLEtBQUssQ0FBQyxPQUFPLEdBQUcsRUFBRSxVQUFVLEVBQUUsSUFBSSxRQUFRLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxRQUFRLEVBQUUsRUFBRSxDQUFDO1lBQ3pFLE1BQU0sWUFBWSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO1lBQ3hDLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3RDLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQ3RDLE1BQU0sRUFBRSxHQUFHLElBQUksY0FBYyxFQUFFLENBQUM7WUFDaEMsRUFBRSxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3RDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ25DLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FBQztZQUMxQyxFQUFFLENBQUMsOEJBQThCLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDdEMsVUFBVSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN2RixDQUFDO1FBRUQsSUFBSSw2QkFBNkIsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sRUFBRSxHQUFHLElBQUksUUFBUSxFQUFFLENBQUM7WUFBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUM1RSxVQUFVLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3ZGLENBQUM7UUFFRCxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFcEIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUMvRCxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNoQyxNQUFNLENBQUMsQ0FBQztRQUNWLENBQUM7UUFFRCxJQUFJLFFBQVEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqQywrRkFBK0Y7WUFDL0YsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNyQyxDQUFDO1FBRUQsT0FBTyxTQUFTLENBQUMsS0FBSyxDQUFDO0lBQ3pCLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxjQUFjLENBQUMsSUFBWTtRQUMvQixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXZCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3RCxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsSUFBSSxDQUFDO2dCQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztZQUFDLENBQUM7WUFBQyxNQUFNLENBQUMsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQ3ZFLENBQUM7UUFDRCxJQUFJLFdBQVcsSUFBSSxPQUFPLFdBQVcsQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDMUQsSUFBSSxDQUFDO2dCQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUFDLENBQUM7WUFBQyxNQUFNLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQzdELENBQUM7UUFFRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVuQyxJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUM1RixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUMzQixDQUFDO1FBQ0QsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUN6QyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUM3QixDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4RCxJQUFJLFFBQVEsSUFBSSxJQUFJLENBQUMsc0JBQXNCLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDekQsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQztRQUNyQyxDQUFDO1FBQ0QsSUFBSSxDQUFDLHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3JDLElBQUksSUFBSSxDQUFDLHNCQUFzQixLQUFLLElBQUksRUFBRSxDQUFDO1lBQ3pDLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLENBQUM7UUFDckMsQ0FBQztJQUNILENBQUM7SUFFRCxtQ0FBbUMsQ0FBQyxJQUFZO1FBQzlDLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLEdBQUc7WUFBRSxPQUFPLElBQUksQ0FBQztRQUN0QixJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLElBQUksRUFBRSxDQUFDO1lBQzNCLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUN4QixDQUFDO1FBQ0QsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUQsc0JBQXNCLENBQUMsUUFBYTtRQUNsQyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2xELElBQUksR0FBRztZQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7SUFDbEQsQ0FBQztJQUVELGVBQWUsQ0FBQyxRQUFhO1FBQzNCLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDbEQsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDekMsQ0FBQztJQUVELDREQUE0RDtJQUM1RCxrQkFBa0IsQ0FBQyxJQUFZLEVBQUUsT0FBZ0I7UUFDL0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRCxJQUFJLElBQUk7WUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDekMsQ0FBQztJQUVELGdHQUFnRztJQUNoRywwQkFBMEIsQ0FBQyxJQUFZLEVBQUUsT0FBZ0I7UUFDdkQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsRCxJQUFJLFNBQVMsRUFBRSxNQUFNLEVBQUUsQ0FBQztZQUN0QixTQUFTLENBQUMsTUFBTSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUM7UUFDN0MsQ0FBQztJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMscUJBQXFCLENBQUMsR0FBUSxFQUFFLFFBQWEsRUFBRSxpQkFBcUYsRUFBRSxlQUE4QyxFQUFFLHFCQUFpQyxFQUFFLG1CQUFtRTtRQUNoUyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxHQUFHO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFFdkIsZ0ZBQWdGO1FBQ2hGLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNsRCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNuRSxNQUFNLFNBQVMsR0FBRztZQUNoQixVQUFVLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7WUFDbEMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxRQUFRO1lBQ3RCLFNBQVMsRUFBRSxRQUFRO1NBQ2IsQ0FBQztRQUNULE1BQU0sUUFBUSxHQUFHLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBa0IsQ0FBQztRQUNsRCxJQUFJLENBQUM7WUFDSCxNQUFNLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ2pFLENBQUM7UUFBQyxPQUFPLEdBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUV0QixJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM3QyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUc7Z0JBQUUsT0FBTyxLQUFLLENBQUM7WUFDL0IsTUFBTSxlQUFlLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2xDLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztnQkFBUyxDQUFDO1lBQ1QscUJBQXFCLEVBQUUsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQztJQUVELDBCQUEwQixDQUFDLElBQVk7UUFDckMsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRCxLQUFLLENBQUMsb0JBQW9CLENBQUMsVUFBZTtRQUN4QyxJQUFJLElBQUksQ0FBQyxjQUFjLElBQUksVUFBVSxFQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQzdHLENBQUM7SUFDSCxDQUFDO0lBRUQsRUFBRTtJQUNGLHlDQUF5QztJQUN6QyxFQUFFO0lBQ00sT0FBTyxDQUFDLENBQXNDO1FBQ3BELE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7O09BR0c7SUFDSyxTQUFTLENBQUMsSUFBWSxFQUFFLElBQVM7UUFDdkMsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxVQUFVLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQztJQUM1RSxDQUFDO0lBRUQsNkZBQTZGO0lBQzdGLHNCQUFzQixDQUFDLElBQVk7UUFDakMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3pDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDbEUsSUFBSSxHQUFHLENBQUMsT0FBTyxFQUFFO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDL0IsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDeEMsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDNUMsT0FBTztZQUNMLEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7WUFDMUIsR0FBRyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztZQUMxQixJQUFJLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDeEIsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1NBQzdCLENBQUM7SUFDSixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gscUJBQXFCLENBQUMsSUFBWTtRQUNoQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDdkIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDN0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDO1lBQ0gsSUFBSSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDekMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNsRSxPQUFPLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDekUsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ25DLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzNDLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILHFCQUFxQixDQUFDLElBQVksRUFBRSxnQkFBd0I7UUFDMUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDMUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdELElBQUksQ0FBQyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUNoQyxNQUFNLE1BQU0sR0FBRyxnQkFBZ0IsR0FBRyxPQUFPLENBQUM7UUFDMUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSDs7O09BR0c7SUFDSCxzQkFBc0IsQ0FBQyxJQUFZLEVBQUUsS0FBYyxFQUFFLE1BQWdCLEVBQUUsY0FBYyxHQUFHLENBQUM7UUFDdkYsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQzdELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFFdkIsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3BGLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUM7WUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDdkMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO1FBQ25DLE1BQU0sU0FBUyxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sTUFBTSxHQUFHLElBQUksT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFdEQsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUNYLHlFQUF5RTtZQUN6RSxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLGNBQWMsQ0FBQztRQUN6RCxDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBRSxDQUFDO1FBRS9DLElBQUksTUFBTSxFQUFFLENBQUM7WUFDWCxNQUFNLFVBQVUsR0FBRyxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDeEQsTUFBTSxTQUFTLEdBQUcsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwRyxNQUFNLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNoRCxDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDbEQsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksTUFBTSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUMxQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQztRQUNyQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBRTFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoQyxPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsb0JBQW9CLENBQUMsSUFBWTtRQUMvQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDdkIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNyQixPQUFPO1lBQ0wsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztZQUNsQyxRQUFRLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRTtZQUMvRCxLQUFLLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO1NBQzdCLENBQUM7SUFDSixDQUFDO0lBRUQsNkRBQTZEO0lBQzdELG9CQUFvQixDQUFDLElBQVksRUFBRSxTQUFxQztRQUN0RSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFDeEIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNyQixJQUFJLFNBQVMsQ0FBQyxRQUFRO1lBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6RyxJQUFJLFNBQVMsQ0FBQyxRQUFRO1lBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6RyxJQUFJLFNBQVMsQ0FBQyxLQUFLO1lBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxRixJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU8sb0JBQW9CLENBQUMsSUFBWTtRQUN2QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEQsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsR0FBRyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQzlELENBQUM7SUFDSCxDQUFDO0lBRUQsRUFBRTtJQUNGLDhCQUE4QjtJQUM5QixFQUFFO0lBQ0YsbUZBQW1GO0lBQzNFLFdBQVcsQ0FBQyxJQUFZLEVBQUUsU0FBYyxFQUFFLFdBQWdCLEVBQUUsSUFBZSxFQUFFLE9BQWdCLEVBQUUsSUFBVTtRQUMvRyxNQUFNLFNBQVMsR0FBRyxJQUFJLElBQUksV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2hELE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxZQUFZLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUNqRSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbEIsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLGlCQUFpQixDQUFDO1FBQ3ZDLEVBQUUsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3JCLFNBQVMsQ0FBQyxNQUFNLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUN2QyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDN0IsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDO1FBRXJDLE1BQU0sS0FBSyxHQUFlO1lBQ3hCLElBQUk7WUFDSixJQUFJLEVBQUUsU0FBUztZQUNmLFNBQVM7WUFDVCxJQUFJO1lBQ0osU0FBUyxFQUFFLElBQUk7WUFDZixZQUFZLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFO1lBQzlDLGlCQUFpQixFQUFFLENBQUMsS0FBVSxFQUFFLEVBQUU7Z0JBQ2hDLEtBQUssQ0FBQyxTQUFTLEdBQUcsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztnQkFDekUsS0FBSyxDQUFDLFlBQVksR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN4RCxDQUFDO1lBQ0QsY0FBYyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDO1NBQ2pFLENBQUM7UUFDRixJQUFJLE9BQU8sRUFBRSxDQUFDLGdCQUFnQixLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQzlDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsRUFBRSxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUNqRSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxFQUFFLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUM1RCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNuQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDN0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7UUFDNUIsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsdUdBQXVHO0lBQy9GLG1CQUFtQixDQUFDLEtBQWlCLEVBQUUsU0FBYztRQUMzRCxNQUFNLEdBQUcsR0FBWSxTQUFTLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQztRQUM5QyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDL0IsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLFNBQVMsSUFBSSxLQUFLLENBQUMsWUFBWSxDQUFDO1lBQ3BELE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckMsS0FBSyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUM1RSxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDOUIsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUNsQyxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxlQUFlLEdBQUcsTUFBTSxDQUFDLENBQUM7WUFDdEQsQ0FBQztZQUNELEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdCLENBQUM7UUFDRCxLQUFLLENBQUMsWUFBWSxHQUFHLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNqQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFTyxTQUFTLENBQUMsRUFBTztRQUN2QixJQUFJLENBQUMsRUFBRTtZQUFFLE9BQU87UUFDaEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUM1QixNQUFNLFdBQVcsR0FBRyxJQUFJLEVBQUUsV0FBVyxJQUFJLElBQUksQ0FBQztRQUM5QyxNQUFNLFFBQVEsR0FBRyxJQUFJLEVBQUUsV0FBVyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUN6RixNQUFNLEtBQUssR0FBRyxJQUFJLEVBQUUsS0FBSyxJQUFJLElBQUksQ0FBQztRQUNsQyxJQUFJLE9BQU8sRUFBRSxDQUFDLGtCQUFrQixLQUFLLFVBQVU7WUFBRSxFQUFFLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLENBQUM7O1lBQU0sRUFBRSxDQUFDLGVBQWUsR0FBRyxXQUFXLENBQUM7UUFDM0gsSUFBSSxPQUFPLEVBQUUsQ0FBQyxlQUFlLEtBQUssVUFBVTtZQUFFLEVBQUUsQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLENBQUM7O1lBQU0sRUFBRSxDQUFDLFlBQVksR0FBRyxRQUFRLENBQUM7UUFDNUcsSUFBSSxPQUFPLEVBQUUsQ0FBQyxZQUFZLEtBQUssVUFBVTtZQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7O1lBQU0sRUFBRSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDL0YsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBWSxFQUFFLElBQWUsRUFBRSxHQUFTO1FBQ3hELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3RCxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsV0FBVztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBRTdDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZDLElBQUksUUFBUSxJQUFJLElBQUksQ0FBQyxlQUFlLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDOUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN4QixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFDRCx1RkFBdUY7UUFDdkYsSUFBSSxJQUFJLEdBQUcsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pDLElBQUksZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQzVCLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNWLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSztnQkFBRSxPQUFPLEtBQUssQ0FBQztZQUM5QixDQUFDLGdCQUFnQixDQUFDLEdBQUcsTUFBTSxHQUFHLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0RCxJQUFJLEdBQUcsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDcEMsQ0FBQztRQUNELElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNuQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDL0UsS0FBSyxDQUFDLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQztRQUNyQyxJQUFJLENBQUMsWUFBWSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFDcEMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsMkZBQTJGO0lBQzNGLFlBQVksQ0FBQyxJQUFlO1FBQzFCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ2xGLElBQUksQ0FBQyxLQUFLO1lBQUUsT0FBTztRQUNuQixLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNsQixLQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN2QixLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ25DLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQUM7UUFDN0MsSUFBSSxFQUFFLElBQUksT0FBTyxFQUFFLENBQUMsT0FBTyxLQUFLLFVBQVU7WUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9ELENBQUM7SUFFRCx3RUFBd0U7SUFDeEUsV0FBVyxDQUFDLElBQWE7UUFDdkIsTUFBTSxFQUFFLEdBQUcsSUFBSSxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDeEMsSUFBSSxDQUFDLEVBQUU7WUFBRSxPQUFPO1FBQ2hCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxLQUFLO1lBQUUsT0FBTztRQUNuQixNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsU0FBUyxFQUFFLGlCQUFpQixDQUFDO1FBQzlDLElBQUksRUFBRSxFQUFFLENBQUM7WUFDUCxJQUFJLE9BQU8sRUFBRSxDQUFDLG1CQUFtQixLQUFLLFVBQVUsRUFBRSxDQUFDO2dCQUNqRCxFQUFFLENBQUMsbUJBQW1CLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQUM7Z0JBQ3BFLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxjQUFjLEVBQUUsS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQy9ELENBQUM7WUFDRCxFQUFFLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztZQUNuQixJQUFJLE9BQU8sRUFBRSxDQUFDLE1BQU0sS0FBSyxVQUFVO2dCQUFFLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNqRCxJQUFJLE9BQU8sRUFBRSxDQUFDLE9BQU8sS0FBSyxVQUFVO2dCQUFFLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNuRCxJQUFJLEVBQUUsQ0FBQyxNQUFNLElBQUksT0FBTyxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sS0FBSyxVQUFVO2dCQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2hGLENBQUM7UUFDRCxJQUFJLENBQUM7WUFBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQUMsQ0FBQztRQUFDLE1BQU0sQ0FBQyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDO1lBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUFDLENBQUM7UUFBQyxNQUFNLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ2xFLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDcEQsSUFBSSxTQUFTLEVBQUUsS0FBSztZQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUN0RCxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN2QixJQUFJLElBQUksQ0FBQyxlQUFlLEtBQUssRUFBRTtZQUFFLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO0lBQy9ELENBQUM7SUFFRCxlQUFlLENBQUMsSUFBYTtRQUMzQixPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLEtBQUssSUFBSSxDQUFDO0lBQ3RFLENBQUM7SUFFRCxpRUFBaUU7SUFDakUsWUFBWSxDQUFDLElBQXNCO1FBQ2pDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUMzQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLGlCQUFpQixDQUFDLENBQUMsQ0FBQztJQUNyRixDQUFDO0lBRUQsdUJBQXVCLENBQUMsV0FBbUIsRUFBRSxTQUFrQjtRQUM3RCxJQUFJLFdBQVcsR0FBRyxDQUFDO1lBQUUsSUFBSSxDQUFDLGVBQWUsR0FBRyxXQUFXLENBQUM7UUFDeEQsSUFBSSxTQUFTLEtBQUssU0FBUyxJQUFJLFNBQVMsR0FBRyxDQUFDO1lBQUUsSUFBSSxDQUFDLGFBQWEsR0FBRyxTQUFTLENBQUM7SUFDL0UsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxLQUFLLENBQUMsbUJBQW1CLENBQ3ZCLEdBQVEsRUFDUixNQUFlLEVBQ2YsZUFBNEMsRUFDNUMsY0FBOEIsRUFDOUIsZUFBeUIsRUFBRTtRQUUzQixJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssSUFBSSxPQUFPLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxLQUFLLFVBQVUsSUFBSSxPQUFPLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQ3JHLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUNELElBQUksTUFBTSxFQUFFLENBQUM7WUFDWCxJQUFJLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQkFBRSxPQUFPLElBQUksQ0FBQztZQUN0RCxJQUFJLENBQUMsZUFBZSxJQUFJLENBQUMsY0FBYztnQkFBRSxPQUFPLEtBQUssQ0FBQztZQUN0RCxxRkFBcUY7WUFDckYsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUN0RCxHQUFHLEtBQUssY0FBYztnQkFDdEIsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEVBQUUsT0FBTyxLQUFLLEtBQUssSUFBSSxJQUFJLENBQUMscUJBQXFCLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN6RixJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssQ0FBQztnQkFBRSxPQUFPLElBQUksQ0FBQztZQUNsQyxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO2dCQUNoQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsR0FBRyxDQUFDO1lBQ2xDLENBQUM7WUFBQyxNQUFNLENBQUM7Z0JBQ1AsMkVBQTJFO2dCQUMzRSxNQUFNLE9BQU8sR0FBRyxNQUFNLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNuRixJQUFJLENBQUMsb0JBQW9CLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEtBQUssV0FBVyxDQUFDLENBQUM7WUFDdEYsQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3hGLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLHFCQUFxQixHQUFHLFFBQVEsQ0FBQztRQUN0QyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDO2dCQUNILE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQztZQUN0QyxDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLE1BQU0sT0FBTyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekUsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxrQkFBa0I7UUFDaEIsT0FBTyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRUQsdURBQXVEO0lBQ3ZELHVCQUF1QjtRQUNyQixPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsNEJBQTRCLENBQ2hDLEdBQVEsRUFDUixTQUFjLEVBQ2QsV0FBZ0IsRUFDaEIsSUFBZSxFQUNmLE9BQWdCLEVBQ2hCLFdBQW9CO1FBRXBCLElBQUksSUFBSSxHQUFHLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNqQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDVixNQUFNLENBQUMsY0FBYyxDQUFDLEdBQUcsTUFBTSxHQUFHLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMxRCxJQUFJLEdBQUcsY0FBYyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2xDLENBQUM7UUFDRCxJQUFJLFdBQVcsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUN2RSxJQUFJLENBQUM7Z0JBQ0gsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDeEUsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1gsd0RBQXdEO1lBQzFELENBQUM7UUFDSCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3BGLElBQUksQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQztRQUNwQyxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsMERBQTBEO0lBQzFELHlCQUF5QjtRQUN2QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQy9CLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUNsQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDbEMsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pCLENBQUM7YUFBTSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUN6QixpREFBaUQ7WUFDakQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1lBQ2hELElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDMUMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDdkIsQ0FBQztJQUNILENBQUM7SUFFRCxFQUFFO0lBQ0Ysd0NBQXdDO0lBQ3hDLEVBQUU7SUFDTSxnQkFBZ0IsQ0FBQyxJQUFZLEVBQUUsT0FBZ0I7UUFDckQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4RCxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQzVCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDO1FBQzFELElBQUksT0FBTyxLQUFLLE9BQU87WUFBRSxPQUFPLElBQUksQ0FBQztRQUNyQyxJQUFJLENBQUM7WUFDSCxRQUFRLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUMvQixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBQ0QsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDM0MsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsbUVBQW1FO0lBQ25FLGNBQWMsQ0FBQyxJQUFZLEVBQUUsT0FBZ0I7UUFDM0MsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxJQUFZO1FBQy9CLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLENBQUM7SUFDcEQsQ0FBQztJQUVELHdGQUF3RjtJQUN4RixpQkFBaUIsQ0FBQyxJQUFhO1FBQzdCLE1BQU0sRUFBRSxHQUFHLElBQUksSUFBSSxJQUFJLENBQUMsc0JBQXNCLENBQUM7UUFDL0MsSUFBSSxFQUFFLElBQUksSUFBSSxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQy9DLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN4RSxDQUFDO2FBQU0sSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztZQUNoRCxnQ0FBZ0M7WUFDaEMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDbEQsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLO1FBQ0gsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN2QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDOUIsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3JDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDO1FBQ25DLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDM0IsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQztRQUNuQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO0lBQ2hDLENBQUM7d0dBcnZCVSx5QkFBeUI7NEdBQXpCLHlCQUF5QixjQUZ4QixNQUFNOzs0RkFFUCx5QkFBeUI7a0JBSHJDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgSU9iamVjdDNELFxuICBQb2lUeXBlLFxuICBQT0ksXG4gIERiT2JqZWN0VHlwZSxcbiAgR2l6bW9Nb2RlLFxuICBHaXptb1NuYXAsXG4gIE9iamVjdDNEQm91bmRpbmdCb3gsXG4gIE9iamVjdDNEVHJhbnNmb3JtLFxuICBPYmplY3QzRFRyYW5zZm9ybUNoYW5nZSxcbiAgUG9pbnQzRCxcbn0gZnJvbSAnLi4vdHlwZXMuc2VydmljZSc7XG5pbXBvcnQgeyBCb3gzLCBNYXRoVXRpbHMsIE9iamVjdDNELCBWZWN0b3IzIH0gZnJvbSAndGhyZWUnO1xuaW1wb3J0IHsgTmVzdFRoZXJtb3N0YXQgfSBmcm9tICcuLi9tYXR0ZXJwb3J0LWV4dGVuc2lvbnMvbmVzdC10aGVybW9zdGF0L05lc3RUaGVybW9zdGF0JztcbmltcG9ydCB7IFBsYW5lUmVuZGVyZXIgfSBmcm9tICcuLi9tYXR0ZXJwb3J0LWV4dGVuc2lvbnMvbmVzdC10aGVybW9zdGF0L1BsYW5lUmVuZGVyZXInO1xuaW1wb3J0IHsgQ2FudmFzUmVuZGVyZXIgfSBmcm9tIFwiLi4vbWF0dGVycG9ydC1leHRlbnNpb25zL25lc3QtdGhlcm1vc3RhdC9DYW52YXNSZW5kZXJlclwiO1xuaW1wb3J0IHsgVHZQbGF5ZXIgfSBmcm9tIFwiLi4vbWF0dGVycG9ydC1leHRlbnNpb25zL3R2LXBsYXllci9UdlBsYXllclwiO1xuXG4vKiogR2l6bW8gKG1wLnRyYW5zZm9ybUNvbnRyb2xzKSBib29ra2VlcGluZyBmb3Igb25lIG9iamVjdCAqL1xuaW50ZXJmYWNlIEdpem1vRW50cnkge1xuICB1dWlkOiBzdHJpbmc7XG4gIG5vZGU6IGFueTtcbiAgLyoqIGRlZGljYXRlZCBzY2VuZSBvYmplY3Qgd2hlbiB0aGUgb2JqZWN0J3Mgb3duIG9uZSB3YXMgYWxyZWFkeSBzdGFydGVkICovXG4gIHNjZW5lT2JqZWN0PzogYW55O1xuICBjb21wb25lbnQ6IGFueTtcbiAgbW9kZTogR2l6bW9Nb2RlO1xuICAvKiogcG9zaXRpb24gb2YgdGhlIG9iamVjdCB3aGVuIHRoZSBjdXJyZW50IGRyYWcgc3RhcnRlZCAqL1xuICBkcmFnU3RhcnQ6IFZlY3RvcjMgfCBudWxsO1xuICAvKiogcG9zaXRpb24gb2YgdGhlIG9iamVjdCBhdCB0aGUgbGFzdCBjaGFuZ2UgKGZhbGxiYWNrIHdoZW4gZHJhZyBzdGFydCB3YXMgbWlzc2VkKSAqL1xuICBsYXN0UG9zaXRpb246IFZlY3RvcjM7XG4gIG9uRHJhZ2dpbmdDaGFuZ2VkOiAoZXZlbnQ6IGFueSkgPT4gdm9pZDtcbiAgb25PYmplY3RDaGFuZ2U6ICgpID0+IHZvaWQ7XG59XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBNYXR0ZXJwb3J0T2JqZWN0M0RTZXJ2aWNlIHtcbiAgcHVibGljIGRpY3Rpb25uYXJ5T2JqZWN0czNEOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xuICBwdWJsaWMgZGljdGlvbm5hcnlTY2VuZU9iamVjdHMzRDogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcbiAgcHVibGljIGxhc3RPYmplY3QzRDogYW55OyAvLyBUaHJlZSBKUyBvYmplY3RcbiAgcHVibGljIG9iamVjdENvbnRyb2w6IGFueTtcbiAgcHVibGljIHNlY3VyaXR5Q2FtZXJhQW5pbWF0b3I6IGFueTtcbiAgcHVibGljIGF6aW11dGhhbENyb3duOiBhbnk7XG4gIHB1YmxpYyB0aHJlZUpTU2NlbmU6IGFueTtcbiAgcHVibGljIG5vTGlnaHRGb3JPYmplY3RzID0gdHJ1ZTtcblxuICAvKiogTWF4IHRpbWUgKG1zKSB0byB3YWl0IGZvciBhIG1vZGVsIHRvIGJlIGxvYWRlZCBieSB0aGUgU0RLICovXG4gIHB1YmxpYyBsb2FkVGltZW91dE1zID0gMTUwMDA7XG4gIC8qKiBNYXggZGlzdGFuY2UgKG0pIGFuIG9iamVjdCBjYW4gdHJhdmVsIGZyb20gd2hlcmUgYSB0cmFuc2xhdGUgZHJhZyBzdGFydGVkICovXG4gIHB1YmxpYyBtYXhEcmFnRGlzdGFuY2UgPSAyO1xuICAvKiogTWF4IHZlcnRpY2FsIHRyYXZlbCAobSwgdXAgYW5kIGRvd24pIGR1cmluZyBhIHRyYW5zbGF0ZSBkcmFnLCBzbyBhbiBvYmplY3QgY2Fubm90IGp1bXAgdG8gYW5vdGhlciBmbG9vciAqL1xuICBwdWJsaWMgbWF4RHJhZ0hlaWdodCA9IDEuNTtcblxuICAvKiogRW1pdHMgb24gZXZlcnkgZ2l6bW8gY2hhbmdlIGFuZCBvbiBzZXRPYmplY3QzRFRyYW5zZm9ybSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgb2JqZWN0M0RUcmFuc2Zvcm1DaGFuZ2VkJCA9IG5ldyBTdWJqZWN0PE9iamVjdDNEVHJhbnNmb3JtQ2hhbmdlPigpO1xuXG4gIC8qKiBTZWN1cml0eSBjYW1lcmEgYW5pbWF0b3JzIGJ5IG9iamVjdCB1dWlkIChgc2VjdXJpdHlDYW1lcmFBbmltYXRvcmAgc3RheXMgdGhlIGxhc3QgbG9hZGVkIG9uZSkgKi9cbiAgcHVibGljIHNlY3VyaXR5Q2FtZXJhQW5pbWF0b3JzOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIHZpZXdGcnVzdHVtVmlzaWJsZTogTWFwPHN0cmluZywgYm9vbGVhbj4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgbGFzdFNlY3VyaXR5Q2FtZXJhVXVpZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIExvYWRlciBjb21wb25lbnQgb2YgZWFjaCBtb2RlbCAob3V0cHV0cy5vYmplY3RSb290IGlzIHNldCBvbmNlIGxvYWRlZCkgKi9cbiAgcHJpdmF0ZSBsb2FkZXJDb21wb25lbnRzOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xuXG4gIHByaXZhdGUgZ2l6bW9zOiBNYXA8c3RyaW5nLCBHaXptb0VudHJ5PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBhY3RpdmVHaXptb1V1aWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGdpem1vU25hcDogR2l6bW9TbmFwIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIFN3ZWVwcyBkaXNhYmxlZCBieSBzZXROYXZpZ2F0aW9uTG9ja2VkKHRydWUpLCByZS1lbmFibGVkIG9uIHVubG9jayAqL1xuICBwcml2YXRlIHN3ZWVwc0Rpc2FibGVkQnlMb2NrOiBzdHJpbmdbXSA9IFtdO1xuICAvKiogU3dlZXBzIHJlLWVuYWJsZWQgYnkgdGhlIGxhc3QgdW5sb2NrICh0aGUgU0RLIG1heSBzdGlsbCByZXBvcnQgdGhlbSBkaXNhYmxlZCBmb3IgYSBtb21lbnQpICovXG4gIHByaXZhdGUgc3dlZXBzRW5hYmxlZEJ5VW5sb2NrOiBzdHJpbmdbXSA9IFtdO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgdG1wQm94ID0gbmV3IEJveDMoKTtcblxuICBjb25zdHJ1Y3RvcigpIHsgfVxuXG4gIGFzeW5jIGluaXQzRE9iamVjdFZpZXdlcihzZGs6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IFtzY2VuZU9iamVjdF0gPSBhd2FpdCBzZGsuU2NlbmUuY3JlYXRlT2JqZWN0cygxKTtcbiAgICBjb25zdCBub2RlID0gc2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgIG5vZGUuc3RhcnQoKTtcbiAgICB0aGlzLnRocmVlSlNTY2VuZSA9IG5vZGUub2JqM0QucGFyZW50O1xuXG4gICAgY29uc3Qgbm9kZUNvbnRyb2wgPSBzY2VuZU9iamVjdC5hZGROb2RlKCk7XG4gICAgdGhpcy5vYmplY3RDb250cm9sID0gbm9kZUNvbnRyb2wuYWRkQ29tcG9uZW50KCdtcC50cmFuc2Zvcm1Db250cm9scycpO1xuICAgIG5vZGVDb250cm9sLnN0YXJ0KCk7XG4gIH1cblxuICAvKiogU0RLIGxvYWRlciBjb21wb25lbnQgbmFtZSBmb3IgYSBtb2RlbCBmb3JtYXQsIG51bGwgd2hlbiB0aGUgZm9ybWF0IGlzIG5vdCBzdXBwb3J0ZWQgKi9cbiAgcHJpdmF0ZSBnZXRMb2FkZXJDb21wb25lbnROYW1lKGZvcm1hdDogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgc3dpdGNoICgoZm9ybWF0IHx8ICcnKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlICcub2JqJzogY2FzZSAnb2JqJzogcmV0dXJuICdtcC5vYmpMb2FkZXInO1xuICAgICAgY2FzZSAnLmZieCc6IGNhc2UgJ2ZieCc6IHJldHVybiAnbXAuZmJ4TG9hZGVyJztcbiAgICAgIGNhc2UgJy5nbHRmJzogY2FzZSAnZ2x0Zic6IGNhc2UgJy5nbGInOiBjYXNlICdnbGInOiByZXR1cm4gJ21wLmdsdGZMb2FkZXInO1xuICAgICAgY2FzZSAnLmRhZSc6IGNhc2UgJ2RhZSc6IHJldHVybiAnbXAuZGFlTG9hZGVyJztcbiAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBSZXNvbHZlcyBvbmNlIHRoZSBsb2FkZXIgY29tcG9uZW50IGhhcyBwcm9kdWNlZCBpdHMgb2JqZWN0Um9vdCwgcmVqZWN0cyBhZnRlciBgdGltZW91dE1zYCAqL1xuICBwcml2YXRlIHdhaXRGb3JNb2RlbExvYWRlZChjb21wb25lbnQ6IGFueSwgdGltZW91dE1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgaXNMb2FkZWQgPSAoKSA9PiAhIWNvbXBvbmVudD8ub3V0cHV0cz8ub2JqZWN0Um9vdDtcbiAgICAgIGlmIChpc0xvYWRlZCgpKSB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgcG9sbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgaWYgKGlzTG9hZGVkKCkpIHtcbiAgICAgICAgICBjbGVhckludGVydmFsKHBvbGwpO1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICB9LCA1MCk7XG4gICAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBjbGVhckludGVydmFsKHBvbGwpO1xuICAgICAgICByZWplY3QobmV3IEVycm9yKGAzRCBtb2RlbCBub3QgbG9hZGVkIGFmdGVyICR7dGltZW91dE1zfSBtc2ApKTtcbiAgICAgIH0sIHRpbWVvdXRNcyk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIDNEIG1vZGVsIHRvIHRoZSBzY2VuZS5cbiAgICogVGhlIHByb21pc2UgcmVzb2x2ZXMgd2l0aCB0aGUgdGhyZWUuanMgb2JqZWN0IG9uY2UgdGhlIG1vZGVsIGlzIGFjdHVhbGx5IGxvYWRlZCwgYW5kIHJlamVjdHNcbiAgICogKGFmdGVyIGNsZWFuaW5nIHRoZSBzY2VuZSkgd2hlbiB0aGUgZm9ybWF0IGlzIHVua25vd24gb3IgdGhlIGxvYWQgdGltZXMgb3V0LlxuICAgKiBUaGUgcG9zaXRpb24gLyByb3RhdGlvbiAvIHNjYWxlIG9mIGBvYmpgIGFyZSBhcHBsaWVkIHRvIHRoZSBtb2RlbCBvcmlnaW4sIGFzIHN0b3JlZCBpbiBEQi5cbiAgICovXG4gIGFzeW5jIGFkZDNET2JqZWN0KFxuICAgIHNkazogYW55LFxuICAgIG9iajogSU9iamVjdDNELFxuICAgIG1vZGU/OiBHaXptb01vZGVcbiAgKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBsb2FkZXJOYW1lID0gdGhpcy5nZXRMb2FkZXJDb21wb25lbnROYW1lKG9iai5mb3JtYXQpO1xuICAgIGlmICghbG9hZGVyTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAzRCBvYmplY3QgZm9ybWF0IG5vdCBzdXBwb3J0ZWQ6ICR7b2JqLmZvcm1hdH1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBbc2NlbmVPYmplY3RdID0gYXdhaXQgc2RrLlNjZW5lLmNyZWF0ZU9iamVjdHMoMSk7XG5cbiAgICBjb25zdCBpc0FuaW1hdGVkU2VjdXJpdHlDYW1lcmEgPSAoIW9iai51cmwgJiYgb2JqLm9iamVjdCA9PT0gJ3NlY3VyaXR5X2NhbWVyYScpO1xuICAgIGNvbnN0IGlzTmVzdFRoZXJtb3N0YXQgPSAoIW9iai51cmwgJiYgb2JqLm9iamVjdCA9PT0gJ25lc3RfdGhlcm1vc3RhdCcpO1xuICAgIGNvbnN0IGlzU21hcnRlcnBsYW5Qcm9tb3Rpb25hbFZpZGVvID0gKCFvYmoudXJsICYmIG9iai5vYmplY3QgPT09ICd2aWRlbycpO1xuICAgIGNvbnN0IGlzQXppbXV0aGFsQ3Jvd24gPSAoIW9iai51cmwgJiYgb2JqLm9iamVjdCA9PT0gJ2F6aW11dGgnKTtcblxuICAgIGNvbnN0IG1vZGVsTm9kZSA9IHNjZW5lT2JqZWN0LmFkZE5vZGUoKTtcbiAgICBjb25zdCBpbml0aWFsID0ge1xuICAgICAgdXJsOiBvYmoudXJsIHx8IGAvYXNzZXRzLzNEb2JqZWN0cy9vYmplY3RzLyR7b2JqLm9iamVjdH0ke29iai5mb3JtYXQuaW5kZXhPZignLicpID09PSAtMSA/ICcuJyArIG9iai5mb3JtYXQgOiBvYmouZm9ybWF0fWAsXG4gICAgICBsb2NhbFJvdGF0aW9uOiB7ICd4JzogMCwgJ3knOiAwLCAneic6IDAgfSxcbiAgICAgIGxvY2FsUG9zaXRpb246IHsgJ3gnOiAwLCAneSc6IDAsICd6JzogMCB9LFxuICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgIGNvbGxpZGVyRW5hYmxlZDogdHJ1ZVxuICAgIH07XG4gICAgY29uc3QgY29tcG9uZW50ID0gbW9kZWxOb2RlLmFkZENvbXBvbmVudChsb2FkZXJOYW1lLCBpbml0aWFsKTtcblxuICAgIGlmICh0aGlzLm5vTGlnaHRGb3JPYmplY3RzKSB7XG4gICAgICBjb25zdCBsaWdodHNOb2RlID0gc2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgICAgbGlnaHRzTm9kZS5hZGRDb21wb25lbnQoJ21wLmFtYmllbnRMaWdodCcsIHtcbiAgICAgICAgaW50ZW5zaXR5OiAxLFxuICAgICAgICBjb2xvcjogeyByOiAxLjAsIGc6IDEuMCwgYjogMS4wIH0sXG4gICAgICB9KTtcbiAgICAgIHRoaXMubm9MaWdodEZvck9iamVjdHMgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBtb2RlbE5vZGUub2JqM0QucG9zaXRpb24uc2V0KG9iai5wb3NpdGlvbi54LCBvYmoucG9zaXRpb24ueSwgb2JqLnBvc2l0aW9uLnopO1xuICAgIG1vZGVsTm9kZS5vYmozRC5yb3RhdGlvbi5zZXQob2JqLnJvdGF0aW9uLngsIG9iai5yb3RhdGlvbi55LCBvYmoucm90YXRpb24ueik7XG4gICAgbW9kZWxOb2RlLm9iajNELnNjYWxlLnNldChvYmouc2NhbGUueCwgb2JqLnNjYWxlLnksIG9iai5zY2FsZS56KTtcblxuICAgIC8vIFRoZSBEQiBpZCByZXBsYWNlcyB0aGUgdGhyZWUuanMgdXVpZC4gVGhlIGlkIHByZS1zZXQgdGhyb3VnaCBzZXRMYXN0T2JqZWN0M0QgaXMgb25seSBhIGZhbGxiYWNrXG4gICAgLy8gZm9yIGNhbGxlcnMgd2l0aG91dCBpZDogdGFraW5nIGl0IGZpcnN0IGdhdmUgdGhlIHNhbWUgaWQgdG8gZXZlcnkgb2JqZWN0IGxvYWRlZCBtZWFud2hpbGVcbiAgICAvLyAoc2V2ZXJhbCBjYW1lcmFzIG9yIGN1YmVzIGxvYWRpbmcgd2hpbGUgYW4gYWRkIGlzIHN0YXJ0aW5nKSwgd2hpY2ggdGhlbiBvdmVyd3JvdGUgZWFjaCBvdGhlci5cbiAgICBpZiAob2JqLmlkKSB7XG4gICAgICBtb2RlbE5vZGUub2JqM0QudXVpZCA9IG9iai5pZDtcbiAgICB9IGVsc2UgaWYgKHRoaXMubGFzdE9iamVjdDNEICYmIHR5cGVvZiB0aGlzLmxhc3RPYmplY3QzRC5pZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG1vZGVsTm9kZS5vYmozRC51dWlkID0gdGhpcy5sYXN0T2JqZWN0M0QuaWQ7XG4gICAgfVxuICAgIGNvbnN0IHV1aWQ6IHN0cmluZyA9IG1vZGVsTm9kZS5vYmozRC51dWlkO1xuICAgIHRoaXMubGFzdE9iamVjdDNEID0gbW9kZWxOb2RlLm9iajNEO1xuXG4gICAgdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5zZXQodXVpZCwgbW9kZWxOb2RlKTtcbiAgICB0aGlzLmRpY3Rpb25uYXJ5U2NlbmVPYmplY3RzM0Quc2V0KHV1aWQsIHNjZW5lT2JqZWN0KTtcbiAgICB0aGlzLmxvYWRlckNvbXBvbmVudHMuc2V0KHV1aWQsIGNvbXBvbmVudCk7XG5cbiAgICBpZiAoaXNBemltdXRoYWxDcm93bikge1xuICAgICAgdGhpcy5hemltdXRoYWxDcm93biA9IG1vZGVsTm9kZTtcbiAgICB9XG5cbiAgICBpZiAobW9kZSAmJiAhaXNOZXN0VGhlcm1vc3RhdCkge1xuICAgICAgdGhpcy5hdHRhY2hHaXptbyh1dWlkLCBtb2RlKS5jYXRjaCgoKSA9PiB7IC8qIG5vIGdpem1vLCB0aGUgb2JqZWN0IGlzIHN0aWxsIGxvYWRlZCAqLyB9KTtcbiAgICB9XG5cbiAgICBsZXQgYW5pbWF0b3I6IGFueSA9IG51bGw7XG4gICAgaWYgKGlzQW5pbWF0ZWRTZWN1cml0eUNhbWVyYSkge1xuICAgICAgYW5pbWF0b3IgPSBtb2RlbE5vZGUuYWRkQ29tcG9uZW50KCdtcC5zZWN1cml0eUNhbWVyYScsIHtcbiAgICAgICAgJ25lYXJQbGFuZSc6IDAuMSwgJ2ZhclBsYW5lJzogMTAsICdob3Jpem9udGFsRk9WJzogNTIsICdhc3BlY3QnOiAxLjc3Nzc3Nzc3Nzc3Nzc3NzcsXG4gICAgICAgICdsb2NhbFBvc2l0aW9uJzogeyAneCc6IDAuMywgJ3knOiAwLjE4LCAneic6IDAgfSxcbiAgICAgICAgJ2xvY2FsUm90YXRpb24nOiB7ICd4JzogLTE1LCAneSc6IC05MCwgJ3onOiAwIH0sXG4gICAgICAgICdjb2xvcic6IDY1MjgwLCAncGFuUGVyaW9kJzogNSwgJ3BhbkFuZ2xlJzogLTQ1XG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2VjdXJpdHlDYW1lcmFBbmltYXRvciA9IGFuaW1hdG9yO1xuICAgICAgdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9ycy5zZXQodXVpZCwgYW5pbWF0b3IpO1xuICAgICAgdGhpcy52aWV3RnJ1c3R1bVZpc2libGUuc2V0KHV1aWQsIHRydWUpOyAvLyB0aGUgY29tcG9uZW50IHNob3dzIGl0cyBmcnVzdHVtIGJ5IGRlZmF1bHRcbiAgICAgIHRoaXMubGFzdFNlY3VyaXR5Q2FtZXJhVXVpZCA9IHV1aWQ7XG4gICAgfVxuXG4gICAgaWYgKGlzTmVzdFRoZXJtb3N0YXQpIHtcbiAgICAgIGNvbnN0IGN2ID0gbmV3IENhbnZhc1JlbmRlcmVyKCk7IGN2Lm9uSW5pdCgpO1xuICAgICAgY29uc3QgcGxhbmUgPSBuZXcgUGxhbmVSZW5kZXJlcigpO1xuICAgICAgcGxhbmUub3V0cHV0cyA9IHsgb2JqZWN0Um9vdDogbmV3IE9iamVjdDNEKCksIGNvbGxpZGVyOiBuZXcgT2JqZWN0M0QoKSB9O1xuICAgICAgY29uc3QgaW5wdXRUZXh0dXJlID0gY3Yub3V0cHV0cy50ZXh0dXJlO1xuICAgICAgcGxhbmUuc2V0Um9vdFNjZW5lKHRoaXMudGhyZWVKU1NjZW5lKTtcbiAgICAgIHBsYW5lLm9uSW5pdChtb2RlbE5vZGUsIGlucHV0VGV4dHVyZSk7XG4gICAgICBjb25zdCBzYyA9IG5ldyBOZXN0VGhlcm1vc3RhdCgpO1xuICAgICAgc2Muc2V0Q29tcG9uZW50KGNvbXBvbmVudCwgcGxhbmUsIGN2KTtcbiAgICAgIHNjLnNldFJvb3RTY2VuZSh0aGlzLnRocmVlSlNTY2VuZSk7XG4gICAgICBzYy5vbkluaXQobW9kZWxOb2RlLCBwbGFuZSwgaW5wdXRUZXh0dXJlKTtcbiAgICAgIGN2LnNldENhbnZhc05lc3RUaGVybW9zdGF0UGFpbnRlcihzYyk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHsgc2MuaW5wdXRzLmxvYWRpbmdTdGF0ZSA9ICdMb2FkZWQnOyBzYy5vbklucHV0c1VwZGF0ZWQoKTsgfSwgNTAwMCk7XG4gICAgfVxuXG4gICAgaWYgKGlzU21hcnRlcnBsYW5Qcm9tb3Rpb25hbFZpZGVvKSB7XG4gICAgICBjb25zdCBzYyA9IG5ldyBUdlBsYXllcigpOyBzYy5zZXRDb21wb25lbnQoY29tcG9uZW50KTsgc2Mub25Jbml0KG1vZGVsTm9kZSk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHsgc2MuaW5wdXRzLmxvYWRpbmdTdGF0ZSA9ICdMb2FkZWQnOyBzYy5vbklucHV0c1VwZGF0ZWQoKTsgfSwgNTAwMCk7XG4gICAgfVxuXG4gICAgc2NlbmVPYmplY3Quc3RhcnQoKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLndhaXRGb3JNb2RlbExvYWRlZChjb21wb25lbnQsIHRoaXMubG9hZFRpbWVvdXRNcyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgYXdhaXQgdGhpcy5kZWxldGVPYmplY3QzRCh1dWlkKTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuXG4gICAgaWYgKGFuaW1hdG9yICYmICFvYmoudmlld0ZydXN0dW0pIHtcbiAgICAgIC8vIFRoZSBjYW1lcmEgY29tcG9uZW50IHN0YXJ0cyB3aXRoIHRoZSBtb2RlbCBub2RlLCBzbyBpdCBpcyByZWFkeSBub3cgdGhhdCB0aGUgbW9kZWwgaXMgbG9hZGVkXG4gICAgICB0aGlzLmFwcGx5Vmlld0ZydXN0dW0odXVpZCwgZmFsc2UpO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlbE5vZGUub2JqM0Q7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIDNEIG9iamVjdCBmb3IgZ29vZDogZGV0YWNoZXMgaXRzIGdpem1vLCBzdG9wcyBpdHMgc2NlbmUgb2JqZWN0IGFuZCBmb3JnZXRzIGl0LlxuICAgKi9cbiAgYXN5bmMgZGVsZXRlT2JqZWN0M0QodXVpZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5kZXRhY2hHaXptbyh1dWlkKTtcblxuICAgIGNvbnN0IG5vZGUgPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldCh1dWlkKTtcbiAgICBjb25zdCBzY2VuZU9iamVjdCA9IHRoaXMuZGljdGlvbm5hcnlTY2VuZU9iamVjdHMzRC5nZXQodXVpZCk7XG4gICAgaWYgKG5vZGUpIHtcbiAgICAgIHRyeSB7IG5vZGUub2JqM0QudmlzaWJsZSA9IGZhbHNlOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBkZXN0cm95ZWQgKi8gfVxuICAgIH1cbiAgICBpZiAoc2NlbmVPYmplY3QgJiYgdHlwZW9mIHNjZW5lT2JqZWN0LnN0b3AgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRyeSB7IHNjZW5lT2JqZWN0LnN0b3AoKTsgfSBjYXRjaCB7IC8qIGFscmVhZHkgc3RvcHBlZCAqLyB9XG4gICAgfVxuXG4gICAgdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5kZWxldGUodXVpZCk7XG4gICAgdGhpcy5kaWN0aW9ubmFyeVNjZW5lT2JqZWN0czNELmRlbGV0ZSh1dWlkKTtcbiAgICB0aGlzLmxvYWRlckNvbXBvbmVudHMuZGVsZXRlKHV1aWQpO1xuXG4gICAgaWYgKHRoaXMubGFzdE9iamVjdDNEICYmICh0aGlzLmxhc3RPYmplY3QzRC51dWlkID09PSB1dWlkIHx8IHRoaXMubGFzdE9iamVjdDNELmlkID09PSB1dWlkKSkge1xuICAgICAgdGhpcy5sYXN0T2JqZWN0M0QgPSBudWxsO1xuICAgIH1cbiAgICBpZiAobm9kZSAmJiB0aGlzLmF6aW11dGhhbENyb3duID09PSBub2RlKSB7XG4gICAgICB0aGlzLmF6aW11dGhhbENyb3duID0gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgYW5pbWF0b3IgPSB0aGlzLnNlY3VyaXR5Q2FtZXJhQW5pbWF0b3JzLmdldCh1dWlkKTtcbiAgICBpZiAoYW5pbWF0b3IgJiYgdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9yID09PSBhbmltYXRvcikge1xuICAgICAgdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9yID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9ycy5kZWxldGUodXVpZCk7XG4gICAgdGhpcy52aWV3RnJ1c3R1bVZpc2libGUuZGVsZXRlKHV1aWQpO1xuICAgIGlmICh0aGlzLmxhc3RTZWN1cml0eUNhbWVyYVV1aWQgPT09IHV1aWQpIHtcbiAgICAgIHRoaXMubGFzdFNlY3VyaXR5Q2FtZXJhVXVpZCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgZ2V0T2JqZWN0M0RNb2RlbE5vZGVGcm9tRGljdGlvbm5hcnkodXVpZDogc3RyaW5nKTogYW55IHtcbiAgICBsZXQgb2JqID0gdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5nZXQodXVpZCk7XG4gICAgaWYgKCFvYmopIHJldHVybiBudWxsO1xuICAgIGlmIChvYmoub2JqM0QudXVpZCAhPSB1dWlkKSB7XG4gICAgICBvYmoub2JqM0QudXVpZCA9IHV1aWQ7XG4gICAgfVxuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICB0b2dnbGVPYmplY3RWaXNpYmlsaXR5KG9iamVjdElkOiBhbnkpIHtcbiAgICBsZXQgb2JqID0gdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5nZXQob2JqZWN0SWQpO1xuICAgIGlmIChvYmopIG9iai5vYmozRC52aXNpYmxlID0gIW9iai5vYmozRC52aXNpYmxlO1xuICB9XG5cbiAgaXNPYmplY3RWaXNpYmxlKG9iamVjdElkOiBhbnkpOiBib29sZWFuIHtcbiAgICBsZXQgb2JqID0gdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5nZXQob2JqZWN0SWQpO1xuICAgIHJldHVybiBvYmogPyBvYmoub2JqM0QudmlzaWJsZSA6IGZhbHNlO1xuICB9XG5cbiAgLyoqIFNob3dzIC8gaGlkZXMgYSBtb2RlbCAodXNlZCBieSB0aGUgcGxhY2VtZW50IHByZXZpZXcpICovXG4gIHNldE9iamVjdDNEVmlzaWJsZSh1dWlkOiBzdHJpbmcsIHZpc2libGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBub2RlID0gdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5nZXQodXVpZCk7XG4gICAgaWYgKG5vZGUpIG5vZGUub2JqM0QudmlzaWJsZSA9IHZpc2libGU7XG4gIH1cblxuICAvKiogRW5hYmxlcyAvIGRpc2FibGVzIHRoZSBwb2ludGVyIGNvbGxpZGVyIG9mIGEgbW9kZWwgKGRpc2FibGVkIHdoaWxlIGl0IGZvbGxvd3MgdGhlIGN1cnNvcikgKi9cbiAgc2V0T2JqZWN0M0RDb2xsaWRlckVuYWJsZWQodXVpZDogc3RyaW5nLCBlbmFibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgY29uc3QgY29tcG9uZW50ID0gdGhpcy5sb2FkZXJDb21wb25lbnRzLmdldCh1dWlkKTtcbiAgICBpZiAoY29tcG9uZW50Py5pbnB1dHMpIHtcbiAgICAgIGNvbXBvbmVudC5pbnB1dHMuY29sbGlkZXJFbmFibGVkID0gZW5hYmxlZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTW92ZXMgdGhlIGNhbWVyYSBuZXh0IHRvIGEgM0Qgb2JqZWN0IGJ5IGNyZWF0aW5nIGEgdGVtcG9yYXJ5IHRhZyBvbiB0aGUgb2JqZWN0IGNlbnRyZS5cbiAgICogQHJldHVybnMgZmFsc2Ugd2hlbiB0aGUgb2JqZWN0IGlzIHVua25vd24gb3Igbm8gdGFnIGNvdWxkIGJlIHJlYWNoZWRcbiAgICovXG4gIGFzeW5jIHBvaW50Q2FtZXJhVG8zRE9iamVjdChzZGs6IGFueSwgb2JqZWN0SWQ6IGFueSwgY3JlYXRlVGFnQ2FsbGJhY2s6ICh0YWdUeXBlOiBQb2lUeXBlLCBvYmplY3Q6IERiT2JqZWN0VHlwZSwgcG9pOiBQT0kpID0+IFByb21pc2U8YW55PiwgZ29Ub1RhZ0NhbGxiYWNrOiAoc2lkOiBzdHJpbmcpID0+IFByb21pc2U8YW55PiwgZGVsZXRlTGFzdFRhZ0NhbGxiYWNrOiAoKSA9PiB2b2lkLCBnZXRUYWdGcm9tRWxlbWVudElkOiAoaWQ6IHN0cmluZykgPT4geyB0YWc6IHN0cmluZywgc3dlZXA6IHN0cmluZyB9KTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgb2JqID0gdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5nZXQob2JqZWN0SWQpO1xuICAgIGlmICghb2JqKSByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBUYWcgb24gdGhlIGJvdW5kaW5nIGJveCBjZW50cmUgKHRoZSBtb2RlbCBvcmlnaW4gaXMgYSBjb3JuZXIgZm9yIG1vc3QgbW9kZWxzKVxuICAgIGNvbnN0IGJveCA9IHRoaXMuZ2V0T2JqZWN0M0RCb3VuZGluZ0JveChvYmplY3RJZCk7XG4gICAgY29uc3QgYW5jaG9yID0gYm94ID8gYm94LmNlbnRlciA6IHRoaXMudG9Qb2ludChvYmoub2JqM0QucG9zaXRpb24pO1xuICAgIGNvbnN0IHBvaU9iamVjdCA9IHtcbiAgICAgIGNvb3JkaW5hdGU6IEpTT04uc3RyaW5naWZ5KGFuY2hvciksXG4gICAgICB0eXBlOiBQb2lUeXBlLk9CSkVDVDNELFxuICAgICAgZWxlbWVudElEOiBvYmplY3RJZCxcbiAgICB9IGFzIFBPSTtcbiAgICBjb25zdCBvYmplY3REYiA9IHsgaWQ6IG9iamVjdElkIH0gYXMgRGJPYmplY3RUeXBlO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjcmVhdGVUYWdDYWxsYmFjayhQb2lUeXBlLk9CSkVDVDNELCBvYmplY3REYiwgcG9pT2JqZWN0KTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkgeyB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gZ2V0VGFnRnJvbUVsZW1lbnRJZChvYmplY3RJZCk7XG4gICAgICBpZiAoIXJlc3VsdD8udGFnKSByZXR1cm4gZmFsc2U7XG4gICAgICBhd2FpdCBnb1RvVGFnQ2FsbGJhY2socmVzdWx0LnRhZyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZGVsZXRlTGFzdFRhZ0NhbGxiYWNrKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0U2NlbmVOb2RlRnJvbU9iamVjdDNESWQodXVpZDogc3RyaW5nKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5kaWN0aW9ubmFyeVNjZW5lT2JqZWN0czNELmdldCh1dWlkKTtcbiAgfVxuXG4gIGFzeW5jIGRpc3BsYXlBemltdXRhbENyb3duKHBvc2VDYW1lcmE6IGFueSkge1xuICAgIGlmICh0aGlzLmF6aW11dGhhbENyb3duICYmIHBvc2VDYW1lcmEpIHtcbiAgICAgIHRoaXMuYXppbXV0aGFsQ3Jvd24ub2JqM0QucG9zaXRpb24uc2V0KHBvc2VDYW1lcmEucG9zaXRpb24ueCwgcG9zZUNhbWVyYS5wb3NpdGlvbi55LCBwb3NlQ2FtZXJhLnBvc2l0aW9uLnopXG4gICAgfVxuICB9XG5cbiAgLy9cbiAgLy8gLS0tLS0tLS0tLSBHZW9tZXRyeSBoZWxwZXJzIC0tLS0tLS0tLS1cbiAgLy9cbiAgcHJpdmF0ZSB0b1BvaW50KHY6IHsgeDogbnVtYmVyLCB5OiBudW1iZXIsIHo6IG51bWJlciB9KTogUG9pbnQzRCB7XG4gICAgcmV0dXJuIHsgeDogdi54LCB5OiB2LnksIHo6IHYueiB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdlb21ldHJ5IG9mIHRoZSBtb2RlbCBpdHNlbGYgKHRoZSBsb2FkZXIgb3V0cHV0KTogdGhlIG5vZGUgYWxzbyBob2xkcyB0aGUgaGVscGVycyBhZGRlZCBieSBvdGhlclxuICAgKiBjb21wb25lbnRzLCBsaWtlIHRoZSB2aWV3IGZydXN0dW0gb2YgYSBzZWN1cml0eSBjYW1lcmEsIHdoaWNoIG11c3Qgbm90IGNvdW50IGluIGl0cyBzaXplLlxuICAgKi9cbiAgcHJpdmF0ZSBtb2RlbFJvb3QodXVpZDogc3RyaW5nLCBub2RlOiBhbnkpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLmxvYWRlckNvbXBvbmVudHMuZ2V0KHV1aWQpPy5vdXRwdXRzPy5vYmplY3RSb290ID8/IG5vZGUub2JqM0Q7XG4gIH1cblxuICAvKiogV29ybGQtc3BhY2UgYm91bmRpbmcgYm94IG9mIHRoZSBtb2RlbCwgbnVsbCB3aGVuIHVua25vd24gb3Igd2hlbiBub3RoaW5nIGlzIGxvYWRlZCB5ZXQgKi9cbiAgZ2V0T2JqZWN0M0RCb3VuZGluZ0JveCh1dWlkOiBzdHJpbmcpOiBPYmplY3QzREJvdW5kaW5nQm94IHwgbnVsbCB7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuZ2V0KHV1aWQpO1xuICAgIGlmICghbm9kZSkgcmV0dXJuIG51bGw7XG4gICAgbm9kZS5vYmozRC51cGRhdGVXb3JsZE1hdHJpeCh0cnVlLCB0cnVlKTtcbiAgICBjb25zdCBib3ggPSB0aGlzLnRtcEJveC5zZXRGcm9tT2JqZWN0KHRoaXMubW9kZWxSb290KHV1aWQsIG5vZGUpKTtcbiAgICBpZiAoYm94LmlzRW1wdHkoKSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3Qgc2l6ZSA9IGJveC5nZXRTaXplKG5ldyBWZWN0b3IzKCkpO1xuICAgIGNvbnN0IGNlbnRlciA9IGJveC5nZXRDZW50ZXIobmV3IFZlY3RvcjMoKSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1pbjogdGhpcy50b1BvaW50KGJveC5taW4pLFxuICAgICAgbWF4OiB0aGlzLnRvUG9pbnQoYm94Lm1heCksXG4gICAgICBzaXplOiB0aGlzLnRvUG9pbnQoc2l6ZSksXG4gICAgICBjZW50ZXI6IHRoaXMudG9Qb2ludChjZW50ZXIpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVhbCBkaW1lbnNpb25zIG9mIHRoZSBtb2RlbCBpbiBtZXRlcnMgKHdpZHRoIHgsIGhlaWdodCB5LCBkZXB0aCB6KSwgc2NhbGUgaW5jbHVkZWQgYnV0IG5vdFxuICAgKiBpdHMgcm90YXRpb246IHRoZSB3b3JsZCBib3VuZGluZyBib3ggb2YgYSByb3RhdGVkIG9iamVjdCBpcyBsYXJnZXIgdGhhbiB0aGUgb2JqZWN0IGl0c2VsZi5cbiAgICovXG4gIGdldE9iamVjdDNERGltZW5zaW9ucyh1dWlkOiBzdHJpbmcpOiBQb2ludDNEIHwgbnVsbCB7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuZ2V0KHV1aWQpO1xuICAgIGlmICghbm9kZSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3Qgcm90YXRpb24gPSBub2RlLm9iajNELnJvdGF0aW9uLmNsb25lKCk7XG4gICAgbm9kZS5vYmozRC5yb3RhdGlvbi5zZXQoMCwgMCwgMCk7XG4gICAgdHJ5IHtcbiAgICAgIG5vZGUub2JqM0QudXBkYXRlV29ybGRNYXRyaXgodHJ1ZSwgdHJ1ZSk7XG4gICAgICBjb25zdCBib3ggPSB0aGlzLnRtcEJveC5zZXRGcm9tT2JqZWN0KHRoaXMubW9kZWxSb290KHV1aWQsIG5vZGUpKTtcbiAgICAgIHJldHVybiBib3guaXNFbXB0eSgpID8gbnVsbCA6IHRoaXMudG9Qb2ludChib3guZ2V0U2l6ZShuZXcgVmVjdG9yMygpKSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIG5vZGUub2JqM0Qucm90YXRpb24uY29weShyb3RhdGlvbik7XG4gICAgICBub2RlLm9iajNELnVwZGF0ZVdvcmxkTWF0cml4KHRydWUsIHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVbmlmb3JtIHNjYWxlIHNvIHRoYXQgdGhlIGxhcmdlc3QgYm91bmRpbmcgYm94IGRpbWVuc2lvbiBlcXVhbHMgYHRhcmdldFNpemVNZXRlcnNgLlxuICAgKiBUaGUgbm9kZSBwb3NpdGlvbiBpcyB1bnRvdWNoZWQsIHNvIGNhbGwgcGxhY2VPYmplY3QzRE9uU3VyZmFjZSBhZnRlcndhcmRzLlxuICAgKiBAcmV0dXJucyB0aGUgbmV3IHNjYWxlLCBudWxsIHdoZW4gdGhlIG9iamVjdCBpcyB1bmtub3duIC8gbm90IGxvYWRlZCAvIGB0YXJnZXRTaXplTWV0ZXJzYCBpbnZhbGlkXG4gICAqL1xuICBub3JtYWxpemVPYmplY3QzRFNpemUodXVpZDogc3RyaW5nLCB0YXJnZXRTaXplTWV0ZXJzOiBudW1iZXIpOiBQb2ludDNEIHwgbnVsbCB7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuZ2V0KHV1aWQpO1xuICAgIGNvbnN0IGJveCA9IHRoaXMuZ2V0T2JqZWN0M0RCb3VuZGluZ0JveCh1dWlkKTtcbiAgICBpZiAoIW5vZGUgfHwgIWJveCB8fCAhKHRhcmdldFNpemVNZXRlcnMgPiAwKSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgbGFyZ2VzdCA9IE1hdGgubWF4KGJveC5zaXplLngsIGJveC5zaXplLnksIGJveC5zaXplLnopO1xuICAgIGlmICghKGxhcmdlc3QgPiAwKSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgZmFjdG9yID0gdGFyZ2V0U2l6ZU1ldGVycyAvIGxhcmdlc3Q7XG4gICAgbm9kZS5vYmozRC5zY2FsZS5tdWx0aXBseVNjYWxhcihmYWN0b3IpO1xuICAgIHRoaXMuZW1pdFRyYW5zZm9ybUNoYW5nZWQodXVpZCk7XG4gICAgcmV0dXJuIHRoaXMudG9Qb2ludChub2RlLm9iajNELnNjYWxlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQbGFjZXMgdGhlIG1vZGVsIG9uIGEgc3VyZmFjZSBwb2ludCB3aXRob3V0IHRvdWNoaW5nIGl0cyBwaXZvdDogdGhlIG5vZGUgcG9zaXRpb24gaXNcbiAgICogYWRqdXN0ZWQgc28gdGhhdCB0aGUgYm91bmRpbmcgYm94IGJvdHRvbS1jZW50ZXIgbGllcyBvbiBgcG9pbnRgLlxuICAgKiAtIGZsb29yIChub3JtYWwgcG9pbnRpbmcgdXAsIG9yIG5vIG5vcm1hbCk6IGJvdHRvbS1jZW50ZXIgb24gdGhlIHBvaW50XG4gICAqIC0gd2FsbCAobW9zdGx5IGhvcml6b250YWwgbm9ybWFsKTogbW9kZWwgdHVybmVkIGFyb3VuZCBZIHNvIGl0cyArWiBmYWNlcyBhd2F5IGZyb20gdGhlIHdhbGwsXG4gICAqICAgYW5kIHB1c2hlZCBhbG9uZyB0aGUgbm9ybWFsIGJ5IGhhbGYgaXRzIGRlcHRoIHNvIGl0IGRvZXMgbm90IGN1dCB0aGUgd2FsbFxuICAgKiAtIGNlaWxpbmcgKG5vcm1hbCBwb2ludGluZyBkb3duKTogdGhlIG1vZGVsIGhhbmdzLCB0b3AtY2VudGVyIG9uIHRoZSBwb2ludFxuICAgKiBAcmV0dXJucyB0aGUgbmV3IHRyYW5zZm9ybSwgbnVsbCB3aGVuIHRoZSBvYmplY3QgaXMgdW5rbm93biBvciBub3QgbG9hZGVkXG4gICAqL1xuICAvKipcbiAgICogQHBhcmFtIGZyb250WWF3T2Zmc2V0IHJvdGF0aW9uIChyYWRpYW5zLCBhcm91bmQgWSkgdGhhdCB0dXJucyB0aGUgZnJvbnQgb2YgdGhlIG1vZGVsIHRvd2FyZCBpdHMgK1pcbiAgICogICAgICAgICAgICAgICAgICAgICAgIGF4aXMsIGZvciBtb2RlbHMgd2hvc2UgZnJvbnQgaXMgYW5vdGhlciBheGlzIChlLmcuIC1QSS8yIHdoZW4gaXQgaXMgK1gpXG4gICAqL1xuICBwbGFjZU9iamVjdDNET25TdXJmYWNlKHV1aWQ6IHN0cmluZywgcG9pbnQ6IFBvaW50M0QsIG5vcm1hbD86IFBvaW50M0QsIGZyb250WWF3T2Zmc2V0ID0gMCk6IE9iamVjdDNEVHJhbnNmb3JtIHwgbnVsbCB7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuZ2V0KHV1aWQpO1xuICAgIGlmICghbm9kZSB8fCAhdGhpcy5nZXRPYmplY3QzREJvdW5kaW5nQm94KHV1aWQpKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBvYmogPSBub2RlLm9iajNEO1xuXG4gICAgY29uc3QgbiA9IG5vcm1hbCA/IG5ldyBWZWN0b3IzKG5vcm1hbC54LCBub3JtYWwueSwgbm9ybWFsLnopIDogbmV3IFZlY3RvcjMoMCwgMSwgMCk7XG4gICAgaWYgKG4ubGVuZ3RoU3EoKSA9PT0gMCkgbi5zZXQoMCwgMSwgMCk7XG4gICAgbi5ub3JtYWxpemUoKTtcblxuICAgIGNvbnN0IGlzV2FsbCA9IE1hdGguYWJzKG4ueSkgPCAwLjU7XG4gICAgY29uc3QgaXNDZWlsaW5nID0gIWlzV2FsbCAmJiBuLnkgPCAwO1xuICAgIGNvbnN0IHRhcmdldCA9IG5ldyBWZWN0b3IzKHBvaW50LngsIHBvaW50LnksIHBvaW50LnopO1xuXG4gICAgaWYgKGlzV2FsbCkge1xuICAgICAgLy8gRmFjZSBhd2F5IGZyb20gdGhlIHdhbGw7IHRoZSBib3ggaGFzIHRvIGJlIG1lYXN1cmVkIGFmdGVyIHRoZSByb3RhdGlvblxuICAgICAgb2JqLnJvdGF0aW9uLnkgPSBNYXRoLmF0YW4yKG4ueCwgbi56KSArIGZyb250WWF3T2Zmc2V0O1xuICAgIH1cbiAgICBjb25zdCBib3ggPSB0aGlzLmdldE9iamVjdDNEQm91bmRpbmdCb3godXVpZCkhO1xuXG4gICAgaWYgKGlzV2FsbCkge1xuICAgICAgY29uc3QgaG9yaXpvbnRhbCA9IG5ldyBWZWN0b3IzKG4ueCwgMCwgbi56KS5ub3JtYWxpemUoKTtcbiAgICAgIGNvbnN0IGhhbGZEZXB0aCA9IDAuNSAqIChNYXRoLmFicyhob3Jpem9udGFsLngpICogYm94LnNpemUueCArIE1hdGguYWJzKGhvcml6b250YWwueikgKiBib3guc2l6ZS56KTtcbiAgICAgIHRhcmdldC5hZGRTY2FsZWRWZWN0b3IoaG9yaXpvbnRhbCwgaGFsZkRlcHRoKTtcbiAgICB9XG5cbiAgICBjb25zdCBhbmNob3JZID0gaXNDZWlsaW5nID8gYm94Lm1heC55IDogYm94Lm1pbi55O1xuICAgIG9iai5wb3NpdGlvbi54ICs9IHRhcmdldC54IC0gYm94LmNlbnRlci54O1xuICAgIG9iai5wb3NpdGlvbi55ICs9IHRhcmdldC55IC0gYW5jaG9yWTtcbiAgICBvYmoucG9zaXRpb24ueiArPSB0YXJnZXQueiAtIGJveC5jZW50ZXIuejtcblxuICAgIHRoaXMuZW1pdFRyYW5zZm9ybUNoYW5nZWQodXVpZCk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0M0RUcmFuc2Zvcm0odXVpZCk7XG4gIH1cblxuICBnZXRPYmplY3QzRFRyYW5zZm9ybSh1dWlkOiBzdHJpbmcpOiBPYmplY3QzRFRyYW5zZm9ybSB8IG51bGwge1xuICAgIGNvbnN0IG5vZGUgPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldCh1dWlkKTtcbiAgICBpZiAoIW5vZGUpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IG8gPSBub2RlLm9iajNEO1xuICAgIHJldHVybiB7XG4gICAgICBwb3NpdGlvbjogdGhpcy50b1BvaW50KG8ucG9zaXRpb24pLFxuICAgICAgcm90YXRpb246IHsgeDogby5yb3RhdGlvbi54LCB5OiBvLnJvdGF0aW9uLnksIHo6IG8ucm90YXRpb24ueiB9LFxuICAgICAgc2NhbGU6IHRoaXMudG9Qb2ludChvLnNjYWxlKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIEFwcGxpZXMgYSAocGFydGlhbCkgdHJhbnNmb3JtLiBSb3RhdGlvbiBpcyBpbiByYWRpYW5zLiAqL1xuICBzZXRPYmplY3QzRFRyYW5zZm9ybSh1dWlkOiBzdHJpbmcsIHRyYW5zZm9ybTogUGFydGlhbDxPYmplY3QzRFRyYW5zZm9ybT4pOiBib29sZWFuIHtcbiAgICBjb25zdCBub2RlID0gdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5nZXQodXVpZCk7XG4gICAgaWYgKCFub2RlKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgbyA9IG5vZGUub2JqM0Q7XG4gICAgaWYgKHRyYW5zZm9ybS5wb3NpdGlvbikgby5wb3NpdGlvbi5zZXQodHJhbnNmb3JtLnBvc2l0aW9uLngsIHRyYW5zZm9ybS5wb3NpdGlvbi55LCB0cmFuc2Zvcm0ucG9zaXRpb24ueik7XG4gICAgaWYgKHRyYW5zZm9ybS5yb3RhdGlvbikgby5yb3RhdGlvbi5zZXQodHJhbnNmb3JtLnJvdGF0aW9uLngsIHRyYW5zZm9ybS5yb3RhdGlvbi55LCB0cmFuc2Zvcm0ucm90YXRpb24ueik7XG4gICAgaWYgKHRyYW5zZm9ybS5zY2FsZSkgby5zY2FsZS5zZXQodHJhbnNmb3JtLnNjYWxlLngsIHRyYW5zZm9ybS5zY2FsZS55LCB0cmFuc2Zvcm0uc2NhbGUueik7XG4gICAgdGhpcy5lbWl0VHJhbnNmb3JtQ2hhbmdlZCh1dWlkKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgZW1pdFRyYW5zZm9ybUNoYW5nZWQodXVpZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gdGhpcy5nZXRPYmplY3QzRFRyYW5zZm9ybSh1dWlkKTtcbiAgICBpZiAodHJhbnNmb3JtKSB7XG4gICAgICB0aGlzLm9iamVjdDNEVHJhbnNmb3JtQ2hhbmdlZCQubmV4dCh7IHV1aWQsIC4uLnRyYW5zZm9ybSB9KTtcbiAgICB9XG4gIH1cblxuICAvL1xuICAvLyAtLS0tLS0tLS0tIEdpem1vIC0tLS0tLS0tLS1cbiAgLy9cbiAgLyoqIENyZWF0ZXMgdGhlIG1wLnRyYW5zZm9ybUNvbnRyb2xzIG5vZGUgb2YgYSBtb2RlbCBhbmQgd2lyZXMgaXQgKGV2ZW50cywgc25hcCkgKi9cbiAgcHJpdmF0ZSBjcmVhdGVHaXptbyh1dWlkOiBzdHJpbmcsIG1vZGVsTm9kZTogYW55LCBzY2VuZU9iamVjdDogYW55LCBtb2RlOiBHaXptb01vZGUsIHZpc2libGU6IGJvb2xlYW4sIG5vZGU/OiBhbnkpOiBHaXptb0VudHJ5IHtcbiAgICBjb25zdCBnaXptb05vZGUgPSBub2RlID8/IHNjZW5lT2JqZWN0LmFkZE5vZGUoKTtcbiAgICBjb25zdCBjb21wb25lbnQgPSBnaXptb05vZGUuYWRkQ29tcG9uZW50KCdtcC50cmFuc2Zvcm1Db250cm9scycpO1xuICAgIGdpem1vTm9kZS5zdGFydCgpO1xuICAgIGNvbnN0IHRjID0gY29tcG9uZW50LnRyYW5zZm9ybUNvbnRyb2xzO1xuICAgIHRjLnZpc2libGUgPSB2aXNpYmxlO1xuICAgIGNvbXBvbmVudC5pbnB1dHMuc2VsZWN0aW9uID0gbW9kZWxOb2RlO1xuICAgIGNvbXBvbmVudC5pbnB1dHMubW9kZSA9IG1vZGU7XG4gICAgbW9kZWxOb2RlLm9iajNELmNvbnRyb2xzID0gY29tcG9uZW50O1xuXG4gICAgY29uc3QgZW50cnk6IEdpem1vRW50cnkgPSB7XG4gICAgICB1dWlkLFxuICAgICAgbm9kZTogZ2l6bW9Ob2RlLFxuICAgICAgY29tcG9uZW50LFxuICAgICAgbW9kZSxcbiAgICAgIGRyYWdTdGFydDogbnVsbCxcbiAgICAgIGxhc3RQb3NpdGlvbjogbW9kZWxOb2RlLm9iajNELnBvc2l0aW9uLmNsb25lKCksXG4gICAgICBvbkRyYWdnaW5nQ2hhbmdlZDogKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgICAgZW50cnkuZHJhZ1N0YXJ0ID0gZXZlbnQ/LnZhbHVlID8gbW9kZWxOb2RlLm9iajNELnBvc2l0aW9uLmNsb25lKCkgOiBudWxsO1xuICAgICAgICBlbnRyeS5sYXN0UG9zaXRpb24gPSBtb2RlbE5vZGUub2JqM0QucG9zaXRpb24uY2xvbmUoKTtcbiAgICAgIH0sXG4gICAgICBvbk9iamVjdENoYW5nZTogKCkgPT4gdGhpcy5vbkdpem1vT2JqZWN0Q2hhbmdlKGVudHJ5LCBtb2RlbE5vZGUpLFxuICAgIH07XG4gICAgaWYgKHR5cGVvZiB0Yy5hZGRFdmVudExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0Yy5hZGRFdmVudExpc3RlbmVyKCdkcmFnZ2luZy1jaGFuZ2VkJywgZW50cnkub25EcmFnZ2luZ0NoYW5nZWQpO1xuICAgICAgdGMuYWRkRXZlbnRMaXN0ZW5lcignb2JqZWN0Q2hhbmdlJywgZW50cnkub25PYmplY3RDaGFuZ2UpO1xuICAgIH1cbiAgICB0aGlzLmFwcGx5U25hcCh0Yyk7XG4gICAgdGhpcy5naXptb3Muc2V0KHV1aWQsIGVudHJ5KTtcbiAgICB0aGlzLmFjdGl2ZUdpem1vVXVpZCA9IHV1aWQ7XG4gICAgcmV0dXJuIGVudHJ5O1xuICB9XG5cbiAgLyoqIEtlZXBzIGEgdHJhbnNsYXRlIGRyYWcgd2l0aGluIG1heERyYWdEaXN0YW5jZSAvIG1heERyYWdIZWlnaHQgb2Ygd2hlcmUgaXQgc3RhcnRlZCwgdGhlbiBub3RpZmllcyAqL1xuICBwcml2YXRlIG9uR2l6bW9PYmplY3RDaGFuZ2UoZW50cnk6IEdpem1vRW50cnksIG1vZGVsTm9kZTogYW55KTogdm9pZCB7XG4gICAgY29uc3QgcG9zOiBWZWN0b3IzID0gbW9kZWxOb2RlLm9iajNELnBvc2l0aW9uO1xuICAgIGlmIChlbnRyeS5tb2RlID09PSAndHJhbnNsYXRlJykge1xuICAgICAgY29uc3Qgc3RhcnQgPSBlbnRyeS5kcmFnU3RhcnQgPz8gZW50cnkubGFzdFBvc2l0aW9uO1xuICAgICAgY29uc3QgZGVsdGEgPSBwb3MuY2xvbmUoKS5zdWIoc3RhcnQpO1xuICAgICAgZGVsdGEueSA9IE1hdGhVdGlscy5jbGFtcChkZWx0YS55LCAtdGhpcy5tYXhEcmFnSGVpZ2h0LCB0aGlzLm1heERyYWdIZWlnaHQpO1xuICAgICAgY29uc3QgbGVuZ3RoID0gZGVsdGEubGVuZ3RoKCk7XG4gICAgICBpZiAobGVuZ3RoID4gdGhpcy5tYXhEcmFnRGlzdGFuY2UpIHtcbiAgICAgICAgZGVsdGEubXVsdGlwbHlTY2FsYXIodGhpcy5tYXhEcmFnRGlzdGFuY2UgLyBsZW5ndGgpO1xuICAgICAgfVxuICAgICAgcG9zLmNvcHkoc3RhcnQpLmFkZChkZWx0YSk7XG4gICAgfVxuICAgIGVudHJ5Lmxhc3RQb3NpdGlvbiA9IHBvcy5jbG9uZSgpO1xuICAgIHRoaXMuZW1pdFRyYW5zZm9ybUNoYW5nZWQoZW50cnkudXVpZCk7XG4gIH1cblxuICBwcml2YXRlIGFwcGx5U25hcCh0YzogYW55KTogdm9pZCB7XG4gICAgaWYgKCF0YykgcmV0dXJuO1xuICAgIGNvbnN0IHNuYXAgPSB0aGlzLmdpem1vU25hcDtcbiAgICBjb25zdCB0cmFuc2xhdGlvbiA9IHNuYXA/LnRyYW5zbGF0aW9uID8/IG51bGw7XG4gICAgY29uc3Qgcm90YXRpb24gPSBzbmFwPy5yb3RhdGlvbkRlZyAhPSBudWxsID8gTWF0aFV0aWxzLmRlZ1RvUmFkKHNuYXAucm90YXRpb25EZWcpIDogbnVsbDtcbiAgICBjb25zdCBzY2FsZSA9IHNuYXA/LnNjYWxlID8/IG51bGw7XG4gICAgaWYgKHR5cGVvZiB0Yy5zZXRUcmFuc2xhdGlvblNuYXAgPT09ICdmdW5jdGlvbicpIHRjLnNldFRyYW5zbGF0aW9uU25hcCh0cmFuc2xhdGlvbik7IGVsc2UgdGMudHJhbnNsYXRpb25TbmFwID0gdHJhbnNsYXRpb247XG4gICAgaWYgKHR5cGVvZiB0Yy5zZXRSb3RhdGlvblNuYXAgPT09ICdmdW5jdGlvbicpIHRjLnNldFJvdGF0aW9uU25hcChyb3RhdGlvbik7IGVsc2UgdGMucm90YXRpb25TbmFwID0gcm90YXRpb247XG4gICAgaWYgKHR5cGVvZiB0Yy5zZXRTY2FsZVNuYXAgPT09ICdmdW5jdGlvbicpIHRjLnNldFNjYWxlU25hcChzY2FsZSk7IGVsc2UgdGMuc2NhbGVTbmFwID0gc2NhbGU7XG4gIH1cblxuICAvKipcbiAgICogU2hvd3MgdGhlIHRyYW5zZm9ybSBnaXptbyBvbiBhbiBvYmplY3QgKGFueSBwcmV2aW91cyBnaXptbyBpcyBkZXRhY2hlZCBmaXJzdCkuXG4gICAqIFJlLWF0dGFjaGluZyB0byB0aGUgb2JqZWN0IHRoYXQgYWxyZWFkeSBoYXMgdGhlIGdpem1vIG9ubHkgY2hhbmdlcyBpdHMgbW9kZS5cbiAgICovXG4gIGFzeW5jIGF0dGFjaEdpem1vKHV1aWQ6IHN0cmluZywgbW9kZTogR2l6bW9Nb2RlLCBzZGs/OiBhbnkpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBtb2RlbE5vZGUgPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldCh1dWlkKTtcbiAgICBjb25zdCBzY2VuZU9iamVjdCA9IHRoaXMuZGljdGlvbm5hcnlTY2VuZU9iamVjdHMzRC5nZXQodXVpZCk7XG4gICAgaWYgKCFtb2RlbE5vZGUgfHwgIXNjZW5lT2JqZWN0KSByZXR1cm4gZmFsc2U7XG5cbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuZ2l6bW9zLmdldCh1dWlkKTtcbiAgICBpZiAoZXhpc3RpbmcgJiYgdGhpcy5hY3RpdmVHaXptb1V1aWQgPT09IHV1aWQpIHtcbiAgICAgIHRoaXMuc2V0R2l6bW9Nb2RlKG1vZGUpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIEEgc3RhcnRlZCBzY2VuZSBvYmplY3QgcmVmdXNlcyBuZXcgbm9kZXMgKGFkZE5vZGUgcmV0dXJucyBudWxsKTogdXNlIGEgZGVkaWNhdGVkIG9uZVxuICAgIGxldCBub2RlID0gc2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgIGxldCBnaXptb1NjZW5lT2JqZWN0ID0gbnVsbDtcbiAgICBpZiAoIW5vZGUpIHtcbiAgICAgIGlmICghc2RrPy5TY2VuZSkgcmV0dXJuIGZhbHNlO1xuICAgICAgW2dpem1vU2NlbmVPYmplY3RdID0gYXdhaXQgc2RrLlNjZW5lLmNyZWF0ZU9iamVjdHMoMSk7XG4gICAgICBub2RlID0gZ2l6bW9TY2VuZU9iamVjdC5hZGROb2RlKCk7XG4gICAgfVxuICAgIHRoaXMuZGV0YWNoR2l6bW8oKTtcbiAgICBjb25zdCBlbnRyeSA9IHRoaXMuY3JlYXRlR2l6bW8odXVpZCwgbW9kZWxOb2RlLCBzY2VuZU9iamVjdCwgbW9kZSwgdHJ1ZSwgbm9kZSk7XG4gICAgZW50cnkuc2NlbmVPYmplY3QgPSBnaXptb1NjZW5lT2JqZWN0O1xuICAgIHRoaXMubGFzdE9iamVjdDNEID0gbW9kZWxOb2RlLm9iajNEO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIFN3aXRjaGVzIHRoZSBhY3RpdmUgZ2l6bW8gYmV0d2VlbiB0cmFuc2xhdGUgLyByb3RhdGUgLyBzY2FsZSB3aXRob3V0IHJlLWF0dGFjaGluZyBpdCAqL1xuICBzZXRHaXptb01vZGUobW9kZTogR2l6bW9Nb2RlKTogdm9pZCB7XG4gICAgY29uc3QgZW50cnkgPSB0aGlzLmFjdGl2ZUdpem1vVXVpZCA/IHRoaXMuZ2l6bW9zLmdldCh0aGlzLmFjdGl2ZUdpem1vVXVpZCkgOiBudWxsO1xuICAgIGlmICghZW50cnkpIHJldHVybjtcbiAgICBlbnRyeS5tb2RlID0gbW9kZTtcbiAgICBlbnRyeS5kcmFnU3RhcnQgPSBudWxsO1xuICAgIGVudHJ5LmNvbXBvbmVudC5pbnB1dHMubW9kZSA9IG1vZGU7XG4gICAgY29uc3QgdGMgPSBlbnRyeS5jb21wb25lbnQudHJhbnNmb3JtQ29udHJvbHM7XG4gICAgaWYgKHRjICYmIHR5cGVvZiB0Yy5zZXRNb2RlID09PSAnZnVuY3Rpb24nKSB0Yy5zZXRNb2RlKG1vZGUpO1xuICB9XG5cbiAgLyoqIFJlYWxseSByZW1vdmVzIHRoZSBnaXptbyBmcm9tIHRoZSBzY2VuZSAoZGVmYXVsdDogdGhlIGFjdGl2ZSBvbmUpICovXG4gIGRldGFjaEdpem1vKHV1aWQ/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBpZCA9IHV1aWQgPz8gdGhpcy5hY3RpdmVHaXptb1V1aWQ7XG4gICAgaWYgKCFpZCkgcmV0dXJuO1xuICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5naXptb3MuZ2V0KGlkKTtcbiAgICBpZiAoIWVudHJ5KSByZXR1cm47XG4gICAgY29uc3QgdGMgPSBlbnRyeS5jb21wb25lbnQ/LnRyYW5zZm9ybUNvbnRyb2xzO1xuICAgIGlmICh0Yykge1xuICAgICAgaWYgKHR5cGVvZiB0Yy5yZW1vdmVFdmVudExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRjLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2RyYWdnaW5nLWNoYW5nZWQnLCBlbnRyeS5vbkRyYWdnaW5nQ2hhbmdlZCk7XG4gICAgICAgIHRjLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ29iamVjdENoYW5nZScsIGVudHJ5Lm9uT2JqZWN0Q2hhbmdlKTtcbiAgICAgIH1cbiAgICAgIHRjLnZpc2libGUgPSBmYWxzZTtcbiAgICAgIGlmICh0eXBlb2YgdGMuZGV0YWNoID09PSAnZnVuY3Rpb24nKSB0Yy5kZXRhY2goKTtcbiAgICAgIGlmICh0eXBlb2YgdGMuZGlzcG9zZSA9PT0gJ2Z1bmN0aW9uJykgdGMuZGlzcG9zZSgpO1xuICAgICAgaWYgKHRjLnBhcmVudCAmJiB0eXBlb2YgdGMucGFyZW50LnJlbW92ZSA9PT0gJ2Z1bmN0aW9uJykgdGMucGFyZW50LnJlbW92ZSh0Yyk7XG4gICAgfVxuICAgIHRyeSB7IGVudHJ5Lm5vZGUuc3RvcCgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBzdG9wcGVkICovIH1cbiAgICB0cnkgeyBlbnRyeS5zY2VuZU9iamVjdD8uc3RvcCgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBzdG9wcGVkICovIH1cbiAgICBjb25zdCBtb2RlbE5vZGUgPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldChpZCk7XG4gICAgaWYgKG1vZGVsTm9kZT8ub2JqM0QpIG1vZGVsTm9kZS5vYmozRC5jb250cm9scyA9IG51bGw7XG4gICAgdGhpcy5naXptb3MuZGVsZXRlKGlkKTtcbiAgICBpZiAodGhpcy5hY3RpdmVHaXptb1V1aWQgPT09IGlkKSB0aGlzLmFjdGl2ZUdpem1vVXVpZCA9IG51bGw7XG4gIH1cblxuICBpc0dpem1vQXR0YWNoZWQodXVpZD86IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1dWlkID8gdGhpcy5naXptb3MuaGFzKHV1aWQpIDogdGhpcy5hY3RpdmVHaXptb1V1aWQgIT09IG51bGw7XG4gIH1cblxuICAvKiogU25hcCBzdGVwcyBmb3IgYWxsIGdpem1vcyAobnVsbCAvIG1pc3NpbmcgdmFsdWUgPSBubyBzbmFwKSAqL1xuICBzZXRHaXptb1NuYXAoc25hcDogR2l6bW9TbmFwIHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuZ2l6bW9TbmFwID0gc25hcCA/IHsgLi4uc25hcCB9IDogbnVsbDtcbiAgICB0aGlzLmdpem1vcy5mb3JFYWNoKChlbnRyeSkgPT4gdGhpcy5hcHBseVNuYXAoZW50cnkuY29tcG9uZW50Py50cmFuc2Zvcm1Db250cm9scykpO1xuICB9XG5cbiAgc2V0R2l6bW9NYXhEcmFnRGlzdGFuY2UobWF4RGlzdGFuY2U6IG51bWJlciwgbWF4SGVpZ2h0PzogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKG1heERpc3RhbmNlID4gMCkgdGhpcy5tYXhEcmFnRGlzdGFuY2UgPSBtYXhEaXN0YW5jZTtcbiAgICBpZiAobWF4SGVpZ2h0ICE9PSB1bmRlZmluZWQgJiYgbWF4SGVpZ2h0ID4gMCkgdGhpcy5tYXhEcmFnSGVpZ2h0ID0gbWF4SGVpZ2h0O1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXZlbnRzIGNhbWVyYSBuYXZpZ2F0aW9uIHRvIG90aGVyIHN3ZWVwcyB3aGlsZSBhIGdpem1vIGlzIGVkaXRlZC5cbiAgICogVGhlIFNESyBoYXMgbm8gXCJmcmVlemUgY2FtZXJhXCIgc3dpdGNoLCBzbyBldmVyeSBlbmFibGVkIHN3ZWVwIGV4Y2VwdCB0aGUgY3VycmVudCBvbmUgaXNcbiAgICogZGlzYWJsZWQgKFN3ZWVwLmRpc2FibGUpOyBleGFjdGx5IHRob3NlIHN3ZWVwcyBhcmUgcmUtZW5hYmxlZCBvbiB1bmxvY2suIFN3ZWVwcyBhbHJlYWR5XG4gICAqIGRpc2FibGVkIChmb3JiaWRkZW4gc3dlZXBzLCBlZGl0IG1vZGUpIGFyZSBuZXZlciB0b3VjaGVkLCBhbmQgYGtlZXBEaXNhYmxlZGAgbGlzdHMgc3dlZXBzXG4gICAqIHRoYXQgbXVzdCBzdGF5IGRpc2FibGVkIG9uIHVubG9jay5cbiAgICogQHJldHVybnMgZmFsc2Ugd2hlbiB0aGUgbG9jayBjb3VsZCBub3QgYmUgYXBwbGllZCAoU0RLIHdpdGhvdXQgU3dlZXAuZGlzYWJsZSwgdW5rbm93biBjdXJyZW50IHN3ZWVwKVxuICAgKi9cbiAgYXN5bmMgc2V0TmF2aWdhdGlvbkxvY2tlZChcbiAgICBzZGs6IGFueSxcbiAgICBsb2NrZWQ6IGJvb2xlYW4sXG4gICAgc3dlZXBDb2xsZWN0aW9uPzogUmVjb3JkPHN0cmluZywgYW55PiB8IG51bGwsXG4gICAgY3VycmVudFN3ZWVwSWQ/OiBzdHJpbmcgfCBudWxsLFxuICAgIGtlZXBEaXNhYmxlZDogc3RyaW5nW10gPSBbXVxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAoIXNkaz8uU3dlZXAgfHwgdHlwZW9mIHNkay5Td2VlcC5kaXNhYmxlICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBzZGsuU3dlZXAuZW5hYmxlICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChsb2NrZWQpIHtcbiAgICAgIGlmICh0aGlzLnN3ZWVwc0Rpc2FibGVkQnlMb2NrLmxlbmd0aCA+IDApIHJldHVybiB0cnVlO1xuICAgICAgaWYgKCFzd2VlcENvbGxlY3Rpb24gfHwgIWN1cnJlbnRTd2VlcElkKSByZXR1cm4gZmFsc2U7XG4gICAgICAvLyBhIHN3ZWVwIHRoaXMgbG9jayByZS1lbmFibGVkIGp1c3QgYmVmb3JlIG1heSBzdGlsbCBiZSByZXBvcnRlZCBkaXNhYmxlZCBieSB0aGUgU0RLXG4gICAgICBjb25zdCBpZHMgPSBPYmplY3Qua2V5cyhzd2VlcENvbGxlY3Rpb24pLmZpbHRlcigoc2lkKSA9PlxuICAgICAgICBzaWQgIT09IGN1cnJlbnRTd2VlcElkICYmXG4gICAgICAgIChzd2VlcENvbGxlY3Rpb25bc2lkXT8uZW5hYmxlZCAhPT0gZmFsc2UgfHwgdGhpcy5zd2VlcHNFbmFibGVkQnlVbmxvY2suaW5jbHVkZXMoc2lkKSkpO1xuICAgICAgaWYgKGlkcy5sZW5ndGggPT09IDApIHJldHVybiB0cnVlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2RrLlN3ZWVwLmRpc2FibGUoLi4uaWRzKTtcbiAgICAgICAgdGhpcy5zd2VlcHNEaXNhYmxlZEJ5TG9jayA9IGlkcztcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBmYWxsIGJhY2sgdG8gb25lIGNhbGwgcGVyIHN3ZWVwIHRvIGtub3cgZXhhY3RseSB3aGljaCBvbmVzIHdlcmUgZGlzYWJsZWRcbiAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChpZHMubWFwKChzaWQpID0+IHNkay5Td2VlcC5kaXNhYmxlKHNpZCkpKTtcbiAgICAgICAgdGhpcy5zd2VlcHNEaXNhYmxlZEJ5TG9jayA9IGlkcy5maWx0ZXIoKF8sIGkpID0+IHJlc3VsdHNbaV0uc3RhdHVzID09PSAnZnVsZmlsbGVkJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgdG9FbmFibGUgPSB0aGlzLnN3ZWVwc0Rpc2FibGVkQnlMb2NrLmZpbHRlcigoc2lkKSA9PiAha2VlcERpc2FibGVkLmluY2x1ZGVzKHNpZCkpO1xuICAgIHRoaXMuc3dlZXBzRGlzYWJsZWRCeUxvY2sgPSBbXTtcbiAgICB0aGlzLnN3ZWVwc0VuYWJsZWRCeVVubG9jayA9IHRvRW5hYmxlO1xuICAgIGlmICh0b0VuYWJsZS5sZW5ndGggPiAwKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBzZGsuU3dlZXAuZW5hYmxlKC4uLnRvRW5hYmxlKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQodG9FbmFibGUubWFwKChzaWQpID0+IHNkay5Td2VlcC5lbmFibGUoc2lkKSkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlzTmF2aWdhdGlvbkxvY2tlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zd2VlcHNEaXNhYmxlZEJ5TG9jay5sZW5ndGggPiAwO1xuICB9XG5cbiAgLyoqIFN3ZWVwcyBjdXJyZW50bHkgZGlzYWJsZWQgYnkgdGhlIG5hdmlnYXRpb24gbG9jayAqL1xuICBnZXRTd2VlcHNEaXNhYmxlZEJ5TG9jaygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLnN3ZWVwc0Rpc2FibGVkQnlMb2NrXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMZWdhY3kgQVBJOiBhdHRhY2hlcyBhIGdpem1vIHRvIGEgbW9kZWwgbm9kZS4gUHJlZmVyIGF0dGFjaEdpem1vKHV1aWQsIG1vZGUpLlxuICAgKi9cbiAgYXN5bmMgYXR0YWNoR2l6bW9Db250cm9sVG8zRE9iamVjdChcbiAgICBzZGs6IGFueSxcbiAgICBtb2RlbE5vZGU6IGFueSxcbiAgICBzY2VuZU9iamVjdDogYW55LFxuICAgIG1vZGU6IEdpem1vTW9kZSxcbiAgICB2aXNpYmxlOiBib29sZWFuLFxuICAgIGlzTmV3T2JqZWN0OiBib29sZWFuXG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgbGV0IG5vZGUgPSBzY2VuZU9iamVjdC5hZGROb2RlKCk7XG4gICAgaWYgKCFub2RlKSB7XG4gICAgICBjb25zdCBbbmV3U2NlbmVPYmplY3RdID0gYXdhaXQgc2RrLlNjZW5lLmNyZWF0ZU9iamVjdHMoMSk7XG4gICAgICBub2RlID0gbmV3U2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgIH1cbiAgICBpZiAoaXNOZXdPYmplY3QgJiYgKCF0aGlzLmxhc3RPYmplY3QzRCB8fCAhdGhpcy5sYXN0T2JqZWN0M0QuY29udHJvbHMpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBtb2RlbE5vZGUub2JqM0QudXVpZCA9IHRoaXMubGFzdE9iamVjdDNELnV1aWQgfHwgdGhpcy5sYXN0T2JqZWN0M0QuaWQ7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGxhc3RPYmplY3QzRCBpcyBub3Qgc2V0OiB0aGUgbW9kZWwga2VlcHMgaXRzIG93biB1dWlkXG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuZGV0YWNoR2l6bW8oKTtcbiAgICB0aGlzLmNyZWF0ZUdpem1vKG1vZGVsTm9kZS5vYmozRC51dWlkLCBtb2RlbE5vZGUsIHNjZW5lT2JqZWN0LCBtb2RlLCB2aXNpYmxlLCBub2RlKTtcbiAgICB0aGlzLmxhc3RPYmplY3QzRCA9IG1vZGVsTm9kZS5vYmozRDtcbiAgICByZXR1cm4gbW9kZWxOb2RlO1xuICB9XG5cbiAgLyoqIFJlbW92ZXMgdGhlIGdpem1vIG9mIHRoZSBsYXN0IGFkZGVkIC8gZWRpdGVkIG9iamVjdCAqL1xuICByZW1vdmVHaXptb0Zyb21MYXN0T2JqZWN0KCk6IHZvaWQge1xuICAgIGNvbnN0IGxhc3QgPSB0aGlzLmxhc3RPYmplY3QzRDtcbiAgICBpZiAoIWxhc3QpIHJldHVybjtcbiAgICBjb25zdCB1dWlkID0gbGFzdC51dWlkID8/IGxhc3QuaWQ7XG4gICAgaWYgKHV1aWQgJiYgdGhpcy5naXptb3MuaGFzKHV1aWQpKSB7XG4gICAgICB0aGlzLmRldGFjaEdpem1vKHV1aWQpO1xuICAgIH0gZWxzZSBpZiAobGFzdC5jb250cm9scykge1xuICAgICAgLy8gZ2l6bW8gbm90IGNyZWF0ZWQgYnkgdGhpcyBzZXJ2aWNlOiBiZXN0IGVmZm9ydFxuICAgICAgbGFzdC5jb250cm9scy50cmFuc2Zvcm1Db250cm9scy52aXNpYmxlID0gZmFsc2U7XG4gICAgICBsYXN0LmNvbnRyb2xzLnRyYW5zZm9ybUNvbnRyb2xzLmRpc3Bvc2UoKTtcbiAgICAgIGxhc3QuY29udHJvbHMgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8vXG4gIC8vIC0tLS0tLS0tLS0gU2VjdXJpdHkgY2FtZXJhIC0tLS0tLS0tLS1cbiAgLy9cbiAgcHJpdmF0ZSBhcHBseVZpZXdGcnVzdHVtKHV1aWQ6IHN0cmluZywgdmlzaWJsZTogYm9vbGVhbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGFuaW1hdG9yID0gdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9ycy5nZXQodXVpZCk7XG4gICAgaWYgKCFhbmltYXRvcikgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLnZpZXdGcnVzdHVtVmlzaWJsZS5nZXQodXVpZCkgPz8gdHJ1ZTtcbiAgICBpZiAoY3VycmVudCA9PT0gdmlzaWJsZSkgcmV0dXJuIHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIGFuaW1hdG9yLnRvZ2dsZVZpZXdGcnVzdHVtKCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMudmlld0ZydXN0dW1WaXNpYmxlLnNldCh1dWlkLCB2aXNpYmxlKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBTaG93cyAvIGhpZGVzIHRoZSB2aWV3IGZydXN0dW0gb2YgdGhlIHNlY3VyaXR5IGNhbWVyYSBgdXVpZGAgKi9cbiAgc2V0Vmlld0ZydXN0dW0odXVpZDogc3RyaW5nLCB2aXNpYmxlOiBib29sZWFuKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYXBwbHlWaWV3RnJ1c3R1bSh1dWlkLCB2aXNpYmxlKTtcbiAgfVxuXG4gIGlzVmlld0ZydXN0dW1WaXNpYmxlKHV1aWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZpZXdGcnVzdHVtVmlzaWJsZS5nZXQodXVpZCkgPz8gZmFsc2U7XG4gIH1cblxuICAvKiogVG9nZ2xlcyB0aGUgZnJ1c3R1bSBvZiBgdXVpZGAsIG9yIG9mIHRoZSBsYXN0IGxvYWRlZCBzZWN1cml0eSBjYW1lcmEgd2hlbiBvbWl0dGVkICovXG4gIHRvZ2dsZVZpZXdGcnVzdHVtKHV1aWQ/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBpZCA9IHV1aWQgPz8gdGhpcy5sYXN0U2VjdXJpdHlDYW1lcmFVdWlkO1xuICAgIGlmIChpZCAmJiB0aGlzLnNlY3VyaXR5Q2FtZXJhQW5pbWF0b3JzLmhhcyhpZCkpIHtcbiAgICAgIHRoaXMuYXBwbHlWaWV3RnJ1c3R1bShpZCwgISh0aGlzLnZpZXdGcnVzdHVtVmlzaWJsZS5nZXQoaWQpID8/IHRydWUpKTtcbiAgICB9IGVsc2UgaWYgKCF1dWlkICYmIHRoaXMuc2VjdXJpdHlDYW1lcmFBbmltYXRvcikge1xuICAgICAgLy8gYW5pbWF0b3Igc2V0IGJ5IGhhbmQgKGxlZ2FjeSlcbiAgICAgIHRoaXMuc2VjdXJpdHlDYW1lcmFBbmltYXRvci50b2dnbGVWaWV3RnJ1c3R1bSgpO1xuICAgIH1cbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIEFycmF5LmZyb20odGhpcy5naXptb3Mua2V5cygpKS5mb3JFYWNoKChpZCkgPT4gdGhpcy5kZXRhY2hHaXptbyhpZCkpO1xuICAgIHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuY2xlYXIoKTtcbiAgICB0aGlzLmRpY3Rpb25uYXJ5U2NlbmVPYmplY3RzM0QuY2xlYXIoKTtcbiAgICB0aGlzLmxvYWRlckNvbXBvbmVudHMuY2xlYXIoKTtcbiAgICB0aGlzLnNlY3VyaXR5Q2FtZXJhQW5pbWF0b3JzLmNsZWFyKCk7XG4gICAgdGhpcy52aWV3RnJ1c3R1bVZpc2libGUuY2xlYXIoKTtcbiAgICB0aGlzLmxhc3RTZWN1cml0eUNhbWVyYVV1aWQgPSBudWxsO1xuICAgIHRoaXMuc3dlZXBzRGlzYWJsZWRCeUxvY2sgPSBbXTtcbiAgICB0aGlzLmxhc3RPYmplY3QzRCA9IG51bGw7XG4gICAgdGhpcy5hemltdXRoYWxDcm93biA9IG51bGw7XG4gICAgdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9yID0gbnVsbDtcbiAgICB0aGlzLm5vTGlnaHRGb3JPYmplY3RzID0gdHJ1ZTtcbiAgfVxufVxuIl19
|