@smarterplan/ngx-smarterplan-core 1.2.45 → 1.2.47
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/esm2020/lib/components/csv-export/csv-export.component.mjs +59 -59
- package/esm2020/lib/components/loader/loader.component.mjs +23 -23
- package/esm2020/lib/components/menu-bar/avatar/avatar.component.mjs +80 -80
- package/esm2020/lib/components/menu-bar/menu-bar.component.mjs +99 -99
- package/esm2020/lib/components/menu-bar/navigation-bar/navigation-bar.component.mjs +384 -384
- package/esm2020/lib/components/menu-bar/range-date-picker/range-date-picker.component.mjs +147 -147
- package/esm2020/lib/components/modal-switch-visit/modal-switch-visit.component.mjs +40 -40
- package/esm2020/lib/components/search-bar/search-bar.component.mjs +63 -63
- package/esm2020/lib/components/support-modal/support-modal.component.mjs +66 -66
- package/esm2020/lib/config.mjs +4 -4
- package/esm2020/lib/helpers.service.mjs +470 -470
- package/esm2020/lib/matterport-extensions/hsl-loader/HlsLoader.mjs +69 -69
- package/esm2020/lib/matterport-extensions/nest-thermostat/CanvasImage.mjs +51 -51
- package/esm2020/lib/matterport-extensions/nest-thermostat/CanvasRenderer.mjs +61 -61
- package/esm2020/lib/matterport-extensions/nest-thermostat/NestThermostat.mjs +158 -158
- package/esm2020/lib/matterport-extensions/nest-thermostat/PlaneRenderer.mjs +85 -85
- package/esm2020/lib/matterport-extensions/scene-component/SceneComponent.mjs +128 -128
- package/esm2020/lib/matterport-extensions/security-camera/SecurityCamera.mjs +249 -249
- package/esm2020/lib/matterport-extensions/tv-player/TvPlayer.mjs +98 -98
- package/esm2020/lib/matterport-extensions/video-renderer/VideoRenderer.mjs +64 -64
- package/esm2020/lib/matterport-extensions/view-frustum-mesh/ViewFrustumMesh.mjs +221 -221
- package/esm2020/lib/mattertagData.mjs +165 -165
- package/esm2020/lib/ngx-smarterplan-core.module.mjs +122 -122
- package/esm2020/lib/ngx-smarterplan-core.service.mjs +14 -14
- package/esm2020/lib/pipes/duration-to-string.pipe.mjs +66 -66
- package/esm2020/lib/pipes/format-date-number-to-digits.pipe.mjs +30 -30
- package/esm2020/lib/pipes/hashtag-from-id.pipe.mjs +26 -26
- package/esm2020/lib/pipes/safe-url.pipe.mjs +20 -20
- package/esm2020/lib/pipes/time-date-to-local-string.pipe.mjs +104 -104
- package/esm2020/lib/pipes/username-from-id.pipe.mjs +29 -29
- package/esm2020/lib/services/amplify-cache.service.mjs +72 -72
- package/esm2020/lib/services/base-tab.service.mjs +24 -24
- package/esm2020/lib/services/baseVisibility.service.mjs +18 -18
- package/esm2020/lib/services/content.service.mjs +135 -135
- package/esm2020/lib/services/filter.service.mjs +599 -599
- package/esm2020/lib/services/intervention.service.mjs +236 -236
- package/esm2020/lib/services/locale.service.mjs +45 -45
- package/esm2020/lib/services/matterport-import.service.mjs +340 -340
- package/esm2020/lib/services/matterport.service.mjs +1587 -1587
- package/esm2020/lib/services/models/affectation.service.mjs +60 -60
- package/esm2020/lib/services/models/base-object.service.mjs +70 -70
- package/esm2020/lib/services/models/capture.service.mjs +34 -34
- package/esm2020/lib/services/models/comment.service.mjs +98 -98
- package/esm2020/lib/services/models/domain.service.mjs +78 -78
- package/esm2020/lib/services/models/equipment.service.mjs +683 -683
- package/esm2020/lib/services/models/event.service.mjs +128 -128
- package/esm2020/lib/services/models/feature.service.mjs +380 -380
- package/esm2020/lib/services/models/hashtag.service.mjs +38 -38
- package/esm2020/lib/services/models/layer.service.mjs +33 -33
- package/esm2020/lib/services/models/measurement.service.mjs +199 -199
- package/esm2020/lib/services/models/mission.service.mjs +206 -206
- package/esm2020/lib/services/models/navigation.service.mjs +92 -92
- package/esm2020/lib/services/models/node.service.mjs +31 -31
- package/esm2020/lib/services/models/object3D.service.mjs +364 -364
- package/esm2020/lib/services/models/operation.service.mjs +59 -59
- package/esm2020/lib/services/models/organisation.service.mjs +73 -73
- package/esm2020/lib/services/models/plan.service.mjs +799 -799
- package/esm2020/lib/services/models/poi.service.mjs +103 -103
- package/esm2020/lib/services/models/profile.service.mjs +58 -58
- package/esm2020/lib/services/models/property.service.mjs +44 -44
- package/esm2020/lib/services/models/space.service.mjs +204 -204
- package/esm2020/lib/services/models/template.service.mjs +41 -41
- package/esm2020/lib/services/models/ticket.service.mjs +526 -526
- package/esm2020/lib/services/models/visit.service.mjs +130 -130
- package/esm2020/lib/services/models/zone.service.mjs +225 -225
- package/esm2020/lib/services/navigator.service.mjs +212 -212
- package/esm2020/lib/services/s3.service.mjs +137 -137
- package/esm2020/lib/services/search.service.mjs +124 -124
- package/esm2020/lib/services/support.service.mjs +42 -42
- package/esm2020/lib/services/tag.service.mjs +111 -111
- package/esm2020/lib/services/user.service.mjs +501 -501
- package/esm2020/lib/services/validators.service.mjs +50 -50
- package/esm2020/lib/services/viewer.service.mjs +389 -389
- package/esm2020/lib/services/zone-drawer.service.mjs +76 -76
- package/esm2020/lib/services/zoneChange.service.mjs +30 -30
- package/esm2020/lib/types.service.mjs +311 -311
- package/esm2020/lib/validators/email.directive.mjs +7 -7
- package/esm2020/lib/validators/no-empty.directive.mjs +12 -12
- package/esm2020/lib/validators/number.directive.mjs +12 -12
- package/esm2020/lib/validators/text.directive.mjs +12 -12
- package/esm2020/public-api.mjs +72 -72
- package/esm2020/smarterplan-ngx-smarterplan-core.mjs +4 -4
- package/fesm2015/smarterplan-ngx-smarterplan-core.mjs +13014 -13014
- package/fesm2015/smarterplan-ngx-smarterplan-core.mjs.map +1 -1
- package/fesm2020/smarterplan-ngx-smarterplan-core.mjs +12263 -12263
- package/fesm2020/smarterplan-ngx-smarterplan-core.mjs.map +1 -1
- package/lib/components/csv-export/csv-export.component.d.ts +18 -18
- package/lib/components/loader/loader.component.d.ts +10 -10
- package/lib/components/menu-bar/avatar/avatar.component.d.ts +21 -21
- package/lib/components/menu-bar/menu-bar.component.d.ts +38 -38
- package/lib/components/menu-bar/navigation-bar/navigation-bar.component.d.ts +73 -73
- package/lib/components/menu-bar/range-date-picker/range-date-picker.component.d.ts +35 -35
- package/lib/components/modal-switch-visit/modal-switch-visit.component.d.ts +22 -22
- package/lib/components/search-bar/search-bar.component.d.ts +16 -16
- package/lib/components/support-modal/support-modal.component.d.ts +26 -26
- package/lib/config.d.ts +22 -22
- package/lib/helpers.service.d.ts +79 -79
- package/lib/matterport-extensions/hsl-loader/HlsLoader.d.ts +26 -26
- package/lib/matterport-extensions/nest-thermostat/CanvasImage.d.ts +31 -31
- package/lib/matterport-extensions/nest-thermostat/CanvasRenderer.d.ts +37 -37
- package/lib/matterport-extensions/nest-thermostat/NestThermostat.d.ts +42 -42
- package/lib/matterport-extensions/nest-thermostat/PlaneRenderer.d.ts +46 -46
- package/lib/matterport-extensions/scene-component/SceneComponent.d.ts +388 -388
- package/lib/matterport-extensions/security-camera/SecurityCamera.d.ts +47 -47
- package/lib/matterport-extensions/tv-player/TvPlayer.d.ts +26 -26
- package/lib/matterport-extensions/video-renderer/VideoRenderer.d.ts +26 -26
- package/lib/matterport-extensions/view-frustum-mesh/ViewFrustumMesh.d.ts +43 -43
- package/lib/mattertagData.d.ts +70 -70
- package/lib/ngx-smarterplan-core.module.d.ts +29 -29
- package/lib/ngx-smarterplan-core.service.d.ts +6 -6
- package/lib/pipes/duration-to-string.pipe.d.ts +12 -12
- package/lib/pipes/format-date-number-to-digits.pipe.d.ts +10 -10
- package/lib/pipes/hashtag-from-id.pipe.d.ts +10 -10
- package/lib/pipes/safe-url.pipe.d.ts +10 -10
- package/lib/pipes/time-date-to-local-string.pipe.d.ts +16 -16
- package/lib/pipes/username-from-id.pipe.d.ts +11 -11
- package/lib/services/amplify-cache.service.d.ts +37 -37
- package/lib/services/base-tab.service.d.ts +10 -10
- package/lib/services/baseVisibility.service.d.ts +9 -9
- package/lib/services/content.service.d.ts +28 -28
- package/lib/services/filter.service.d.ts +60 -60
- package/lib/services/intervention.service.d.ts +25 -25
- package/lib/services/locale.service.d.ts +23 -23
- package/lib/services/matterport-import.service.d.ts +53 -53
- package/lib/services/matterport.service.d.ts +336 -336
- package/lib/services/models/affectation.service.d.ts +14 -14
- package/lib/services/models/base-object.service.d.ts +20 -20
- package/lib/services/models/capture.service.d.ts +13 -13
- package/lib/services/models/comment.service.d.ts +26 -26
- package/lib/services/models/domain.service.d.ts +19 -19
- package/lib/services/models/equipment.service.d.ts +93 -93
- package/lib/services/models/event.service.d.ts +43 -43
- package/lib/services/models/feature.service.d.ts +75 -75
- package/lib/services/models/hashtag.service.d.ts +13 -13
- package/lib/services/models/layer.service.d.ts +11 -11
- package/lib/services/models/measurement.service.d.ts +51 -51
- package/lib/services/models/mission.service.d.ts +39 -39
- package/lib/services/models/navigation.service.d.ts +29 -29
- package/lib/services/models/node.service.d.ts +12 -12
- package/lib/services/models/object3D.service.d.ts +57 -57
- package/lib/services/models/operation.service.d.ts +15 -15
- package/lib/services/models/organisation.service.d.ts +19 -19
- package/lib/services/models/plan.service.d.ts +133 -133
- package/lib/services/models/poi.service.d.ts +25 -25
- package/lib/services/models/profile.service.d.ts +16 -16
- package/lib/services/models/property.service.d.ts +13 -13
- package/lib/services/models/space.service.d.ts +46 -46
- package/lib/services/models/template.service.d.ts +15 -15
- package/lib/services/models/ticket.service.d.ts +93 -93
- package/lib/services/models/visit.service.d.ts +24 -24
- package/lib/services/models/zone.service.d.ts +50 -50
- package/lib/services/navigator.service.d.ts +61 -61
- package/lib/services/s3.service.d.ts +14 -14
- package/lib/services/search.service.d.ts +20 -20
- package/lib/services/support.service.d.ts +17 -17
- package/lib/services/tag.service.d.ts +29 -29
- package/lib/services/user.service.d.ts +118 -118
- package/lib/services/validators.service.d.ts +18 -18
- package/lib/services/viewer.service.d.ts +110 -110
- package/lib/services/zone-drawer.service.d.ts +7 -7
- package/lib/services/zoneChange.service.d.ts +17 -17
- package/lib/types.service.d.ts +842 -842
- package/lib/validators/email.directive.d.ts +2 -2
- package/lib/validators/no-empty.directive.d.ts +2 -2
- package/lib/validators/number.directive.d.ts +2 -2
- package/lib/validators/text.directive.d.ts +2 -2
- package/package.json +2 -2
- package/public-api.d.ts +64 -64
- package/smarterplan-ngx-smarterplan-core.d.ts +5 -5
|
@@ -1,799 +1,799 @@
|
|
|
1
|
-
/* eslint-disable func-names */
|
|
2
|
-
/* eslint-disable class-methods-use-this */
|
|
3
|
-
import { Inject, Injectable } from '@angular/core';
|
|
4
|
-
import { getDocument, GlobalWorkerOptions } from 'pdfjs-dist';
|
|
5
|
-
import panzoom from 'panzoom';
|
|
6
|
-
import videojs from "video.js";
|
|
7
|
-
import { Subject } from 'rxjs';
|
|
8
|
-
import { CommentType, FeatureType, PoiType, } from '../../types.service';
|
|
9
|
-
import { getSignedFile, uploadFileToS3 } from '../s3.service';
|
|
10
|
-
import { getCoefficientsForImage } from '../zone-drawer.service';
|
|
11
|
-
import { getMetaForImage } from '../../helpers.service';
|
|
12
|
-
import * as i0 from "@angular/core";
|
|
13
|
-
import * as i1 from "./zone.service";
|
|
14
|
-
import * as i2 from "./navigation.service";
|
|
15
|
-
import * as i3 from "../viewer.service";
|
|
16
|
-
import * as i4 from "@angular/router";
|
|
17
|
-
import * as i5 from "../matterport.service";
|
|
18
|
-
import * as i6 from "../baseVisibility.service";
|
|
19
|
-
import * as i7 from "../content.service";
|
|
20
|
-
export class PlanService {
|
|
21
|
-
constructor(apiInjected, zoneService, navigationService,
|
|
22
|
-
// tagService: BaseTagService,
|
|
23
|
-
viewerService, router, matterportService,
|
|
24
|
-
// private config: AppConfig,
|
|
25
|
-
visibilityService, contentService) {
|
|
26
|
-
this.zoneService = zoneService;
|
|
27
|
-
this.navigationService = navigationService;
|
|
28
|
-
this.viewerService = viewerService;
|
|
29
|
-
this.router = router;
|
|
30
|
-
this.matterportService = matterportService;
|
|
31
|
-
this.visibilityService = visibilityService;
|
|
32
|
-
this.contentService = contentService;
|
|
33
|
-
this.isReady = false;
|
|
34
|
-
this.detailTagDivIsHover = false;
|
|
35
|
-
this.btnTagIsHover = false;
|
|
36
|
-
this.resizePlanSubscription = new Subject();
|
|
37
|
-
this.lastTouchTime = 0;
|
|
38
|
-
this.delayDblTouch = 500;
|
|
39
|
-
this.lastRotation = 0;
|
|
40
|
-
this.htmlContentToInject = [];
|
|
41
|
-
this.focusMouseTagDiv = false;
|
|
42
|
-
this.API = apiInjected;
|
|
43
|
-
this.matterportService.currentCameraPose.subscribe((pose) => {
|
|
44
|
-
this.updateRotation(pose.rotation.y);
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
async createPlan(planInput) {
|
|
48
|
-
return this.API.__proto__.CreatePlan(planInput);
|
|
49
|
-
}
|
|
50
|
-
async deletePlan(plan) {
|
|
51
|
-
// await deleteFromS3(plan.annexe);
|
|
52
|
-
return this.API.__proto__.DeletePlan({ id: plan.id });
|
|
53
|
-
}
|
|
54
|
-
async getPlansForSpace(spaceID) {
|
|
55
|
-
return this.API.__proto__
|
|
56
|
-
.PlansBySpace(spaceID)
|
|
57
|
-
.then((response) => response.items);
|
|
58
|
-
}
|
|
59
|
-
async getPlansForZone(zoneID) {
|
|
60
|
-
return this.API.__proto__
|
|
61
|
-
.PlansByZone(zoneID)
|
|
62
|
-
.then((response) => response.items);
|
|
63
|
-
}
|
|
64
|
-
async getSingedPlansForSpace(spaceID) {
|
|
65
|
-
const plansFromDB = await this.getPlansForSpace(spaceID);
|
|
66
|
-
// console.log(plansFromDB);
|
|
67
|
-
const plans = [];
|
|
68
|
-
if (plansFromDB.length > 0) {
|
|
69
|
-
await Promise.all(plansFromDB.map(async (plan) => {
|
|
70
|
-
const planObject = { ...plan };
|
|
71
|
-
// annexe looks like visits/modelID/plans/file.extension
|
|
72
|
-
const signed = await getSignedFile(plan.annexe);
|
|
73
|
-
if (signed) {
|
|
74
|
-
planObject.filepath = signed;
|
|
75
|
-
}
|
|
76
|
-
if (plan.annexe) {
|
|
77
|
-
const [, modelID, , filenameWithExtension] = plan.annexe.split('/');
|
|
78
|
-
const [, extention] = filenameWithExtension.split('.');
|
|
79
|
-
planObject.model3d = modelID;
|
|
80
|
-
planObject.extension = extention;
|
|
81
|
-
plans.push(planObject);
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
console.log(`Error plan have not annexe => `);
|
|
85
|
-
console.log(plan.id);
|
|
86
|
-
}
|
|
87
|
-
}));
|
|
88
|
-
}
|
|
89
|
-
return plans;
|
|
90
|
-
}
|
|
91
|
-
async getPlansWithZonesForSpace(spaceID) {
|
|
92
|
-
const plans = await this.getPlansForSpace(spaceID);
|
|
93
|
-
const plansZones = plans.filter((plan) => plan.zone && plan.calibration);
|
|
94
|
-
return plansZones;
|
|
95
|
-
}
|
|
96
|
-
setChosenPlan(chosenPlan) {
|
|
97
|
-
this.chosenPlan = chosenPlan;
|
|
98
|
-
}
|
|
99
|
-
getChosenPlan() {
|
|
100
|
-
return this.chosenPlan;
|
|
101
|
-
}
|
|
102
|
-
setPlanFileCache(planFileCache) {
|
|
103
|
-
this.planFileCache = planFileCache;
|
|
104
|
-
return Promise.resolve();
|
|
105
|
-
}
|
|
106
|
-
getPlanFileCache() {
|
|
107
|
-
return this.planFileCache;
|
|
108
|
-
}
|
|
109
|
-
async createPlanWithAnnexe(plan, file) {
|
|
110
|
-
const createdPlan = await this.createPlan(plan);
|
|
111
|
-
const model3D = await this.zoneService.getModel3DForZone(plan.zoneID);
|
|
112
|
-
const url = await uploadFileToS3(`visits/${model3D}/plans/`, file, createdPlan.id);
|
|
113
|
-
if (url) {
|
|
114
|
-
return this.API.__proto__.UpdatePlan({ id: createdPlan.id, annexe: url });
|
|
115
|
-
}
|
|
116
|
-
return createdPlan;
|
|
117
|
-
}
|
|
118
|
-
async updatePlan(plan) {
|
|
119
|
-
return this.API.__proto__.UpdatePlan(plan);
|
|
120
|
-
}
|
|
121
|
-
async updatePlanFile() {
|
|
122
|
-
if (this.chosenPlan && this.planFileCache) {
|
|
123
|
-
const model3D = await this.zoneService.getModel3DForZone(this.chosenPlan.zoneID);
|
|
124
|
-
return uploadFileToS3(`visits/${model3D}/plans/`, this.planFileCache, this.chosenPlan.id);
|
|
125
|
-
}
|
|
126
|
-
return Promise.reject();
|
|
127
|
-
}
|
|
128
|
-
async setAllPlansForZoneNotCurrent(zoneID, currentPlanID) {
|
|
129
|
-
const plans = await this.API.__proto__.ListPlans({
|
|
130
|
-
zoneID: { eq: zoneID },
|
|
131
|
-
});
|
|
132
|
-
await Promise.all(plans.items.map(async (plan) => {
|
|
133
|
-
if (plan.isCurrentForZone && plan.id !== currentPlanID) {
|
|
134
|
-
await this.updatePlan({
|
|
135
|
-
id: plan.id,
|
|
136
|
-
isCurrentForZone: false,
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
}));
|
|
140
|
-
}
|
|
141
|
-
async configurePlan(currentPlan, divId = 'planDivPane', divContentId = 'planDivPaneContent') {
|
|
142
|
-
this.isReady = false;
|
|
143
|
-
if (!this.detailTagDiv) {
|
|
144
|
-
this.detailTagDiv = document.querySelector(`#detailTagDiv`);
|
|
145
|
-
}
|
|
146
|
-
this.detailTagDiv.addEventListener('mouseenter', () => {
|
|
147
|
-
this.focusMouseTagDiv = true;
|
|
148
|
-
});
|
|
149
|
-
this.detailTagDiv.addEventListener('mouseleave', () => {
|
|
150
|
-
this.btnTagIsHover = false;
|
|
151
|
-
this.detailTagDiv.style.display = 'none';
|
|
152
|
-
this.focusMouseTagDiv = false;
|
|
153
|
-
});
|
|
154
|
-
this.calibrationPlan = JSON.parse(currentPlan.calibration);
|
|
155
|
-
this.currentPlan = currentPlan;
|
|
156
|
-
this.planDiv = document.querySelector(`#${divId}`);
|
|
157
|
-
this.planDivContent = document.querySelector(`#${divContentId}`);
|
|
158
|
-
this.planDiv.addEventListener('touchstart', this.handleTouch.bind(this));
|
|
159
|
-
this.planDiv.addEventListener('dblclick', this.onDblClickPlan.bind(this));
|
|
160
|
-
if (!currentPlan.annexe.includes('pdf')) {
|
|
161
|
-
this.imgPlan = await getMetaForImage(currentPlan.filepath);
|
|
162
|
-
//Rect use offsetWidth : height, not actual boundingClientRect because will be modified by the zoom.
|
|
163
|
-
const rect = {
|
|
164
|
-
width: this.planDivContent.offsetWidth,
|
|
165
|
-
height: this.planDivContent.offsetHeight,
|
|
166
|
-
};
|
|
167
|
-
const { coeffX, coeffY } = getCoefficientsForImage(this.imgPlan, rect);
|
|
168
|
-
this.coeffPlanX = coeffX;
|
|
169
|
-
this.coeffPlanY = coeffY;
|
|
170
|
-
this.planDivContent.style.backgroundImage = `url(${currentPlan.filepath})`;
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
await this.drawPdf(currentPlan);
|
|
174
|
-
}
|
|
175
|
-
this.planDivContent.style.backgroundSize = 'contain';
|
|
176
|
-
this.planDivContent.style.backgroundRepeat = 'no-repeat';
|
|
177
|
-
this.panzoom = panzoom(this.planDiv, {
|
|
178
|
-
bounds: true,
|
|
179
|
-
boundsPadding: 0,
|
|
180
|
-
maxZoom: 4,
|
|
181
|
-
zoomDoubleClickSpeed: 1, //disables double click zoom
|
|
182
|
-
//initialZoom: 4
|
|
183
|
-
});
|
|
184
|
-
this.panzoom.zoomAbs(0, 0, 4);
|
|
185
|
-
setTimeout(() => {
|
|
186
|
-
this.updateRotation(this.lastRotation);
|
|
187
|
-
}, 200);
|
|
188
|
-
return true;
|
|
189
|
-
}
|
|
190
|
-
clearPlanImage() {
|
|
191
|
-
if (this.planDivContent) {
|
|
192
|
-
this.planDivContent.style.backgroundImage = null;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
async drawPdf(currentPlan) {
|
|
196
|
-
return new Promise(async (resolve) => {
|
|
197
|
-
const canvas = document.createElement('canvas');
|
|
198
|
-
const context = canvas.getContext('2d');
|
|
199
|
-
const pdfjsWorker = await import('pdfjs-dist/build/pdf.worker.entry');
|
|
200
|
-
GlobalWorkerOptions.workerSrc = pdfjsWorker;
|
|
201
|
-
const pdf = await getDocument(currentPlan.filepath).promise;
|
|
202
|
-
const page = await pdf.getPage(1);
|
|
203
|
-
const viewPortParameters = { scale: 1.5 };
|
|
204
|
-
const viewport = page.getViewport(viewPortParameters);
|
|
205
|
-
canvas.height = viewport.height;
|
|
206
|
-
canvas.width = viewport.width;
|
|
207
|
-
const renderContext = {
|
|
208
|
-
canvasContext: context,
|
|
209
|
-
viewport,
|
|
210
|
-
};
|
|
211
|
-
const renderTask = page.render(renderContext).promise;
|
|
212
|
-
renderTask.then(async () => {
|
|
213
|
-
const imgUrl = canvas.toDataURL('image/png');
|
|
214
|
-
this.imgPlan = await getMetaForImage(imgUrl);
|
|
215
|
-
const rect = {
|
|
216
|
-
width: this.planDivContent.offsetWidth,
|
|
217
|
-
height: this.planDivContent.offsetHeight,
|
|
218
|
-
};
|
|
219
|
-
const { coeffX, coeffY } = getCoefficientsForImage(this.imgPlan, rect);
|
|
220
|
-
this.coeffPlanX = coeffX;
|
|
221
|
-
this.coeffPlanY = coeffY;
|
|
222
|
-
this.planDiv.style.backgroundImage = `url(${imgUrl})`;
|
|
223
|
-
resolve();
|
|
224
|
-
});
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
async drawElement(element, tagType, currentPlan, tagService, config, sizeButton = 10) {
|
|
228
|
-
const [poi] = element.pois.items;
|
|
229
|
-
if (poi && poi.coordinate && currentPlan) {
|
|
230
|
-
const { zone } = currentPlan;
|
|
231
|
-
if (zone) {
|
|
232
|
-
const position = JSON.parse(poi.coordinate);
|
|
233
|
-
const button = document.createElement('button');
|
|
234
|
-
let elementTitle;
|
|
235
|
-
const url = tagService.getUrlForSeeDetails(element, tagType);
|
|
236
|
-
let tagIconImage;
|
|
237
|
-
switch (tagType) {
|
|
238
|
-
case PoiType.TICKET: {
|
|
239
|
-
tagIconImage = config.my_config.icon_ticket;
|
|
240
|
-
break;
|
|
241
|
-
}
|
|
242
|
-
case PoiType.EQUIPMENT: {
|
|
243
|
-
tagIconImage = config.my_config.icon_equipment;
|
|
244
|
-
break;
|
|
245
|
-
}
|
|
246
|
-
case PoiType.MEASURE:
|
|
247
|
-
tagIconImage = config.my_config.icon_measure;
|
|
248
|
-
break;
|
|
249
|
-
case PoiType.OBJECT3D:
|
|
250
|
-
tagIconImage = config.my_config.icon_object3d;
|
|
251
|
-
break;
|
|
252
|
-
case PoiType.DATA:
|
|
253
|
-
tagIconImage = config.my_config.icon_data;
|
|
254
|
-
break;
|
|
255
|
-
case PoiType.DESK:
|
|
256
|
-
tagIconImage = config.my_config.icon_data;
|
|
257
|
-
break;
|
|
258
|
-
default:
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
if (poi.tagIcon) {
|
|
262
|
-
const tagIcon = JSON.parse(poi.tagIcon);
|
|
263
|
-
if (tagType === PoiType.DATA &&
|
|
264
|
-
element.type === FeatureType.INDICATOR_TEMP) {
|
|
265
|
-
tagIcon.src = tagService.getIconTagImageForFeature(element, poi);
|
|
266
|
-
}
|
|
267
|
-
// poi.tagIcon = tagIcon;
|
|
268
|
-
if (tagIcon.src) {
|
|
269
|
-
const source = await getSignedFile(tagIcon.src);
|
|
270
|
-
if (source) {
|
|
271
|
-
tagIconImage = source;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
this.styleButton(button, tagIconImage, sizeButton);
|
|
276
|
-
button.id = element.id;
|
|
277
|
-
this.planDivContent.append(button);
|
|
278
|
-
let x;
|
|
279
|
-
let y;
|
|
280
|
-
if (this.calibrationPlan.new) {
|
|
281
|
-
// alert("new calibration plan: positioning not ready yet");
|
|
282
|
-
const position2D = this.transformPosition3DForNewCalibration(position);
|
|
283
|
-
x = position2D.x;
|
|
284
|
-
y = position2D.y;
|
|
285
|
-
button.style.top = `${y / position2D.coeffY - 5}px`;
|
|
286
|
-
button.style.left = `${x / position2D.coeffX - 5}px`;
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
// to remove when all calibrations are new
|
|
290
|
-
x =
|
|
291
|
-
this.calibrationPlan.offsetX + position.x * this.calibrationPlan.x;
|
|
292
|
-
y =
|
|
293
|
-
this.calibrationPlan.offsetY + position.z * this.calibrationPlan.y;
|
|
294
|
-
button.style.top = `${y / this.coeffPlanY - 5}px`;
|
|
295
|
-
button.style.left = `${x / this.coeffPlanX - 5}px`;
|
|
296
|
-
}
|
|
297
|
-
const html = await tagService.getHtmlToInject(tagType, element);
|
|
298
|
-
if (html != '') {
|
|
299
|
-
this.htmlContentToInject.push({
|
|
300
|
-
elementID: element.id,
|
|
301
|
-
title: '',
|
|
302
|
-
content: html,
|
|
303
|
-
y,
|
|
304
|
-
x,
|
|
305
|
-
tagIcon: tagIconImage,
|
|
306
|
-
url,
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
else {
|
|
310
|
-
// when we don't have html => case of EMBED Comment type
|
|
311
|
-
const commentEmbed = element.comments?.items.find((com) => com.type === CommentType.EMBED && com.shownInTag);
|
|
312
|
-
if (commentEmbed) {
|
|
313
|
-
this.htmlContentToInject.push({
|
|
314
|
-
elementID: element.id,
|
|
315
|
-
title: element.title,
|
|
316
|
-
content: `<iframe src=${commentEmbed.externalLink} height="200px" width="100%"></iframe>`,
|
|
317
|
-
y,
|
|
318
|
-
x,
|
|
319
|
-
tagIcon: tagIconImage,
|
|
320
|
-
url,
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
this.addListenersToButton(button, url, tagService, element);
|
|
325
|
-
this.updateRotation(this.lastRotation);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
async drawUserPosition(currentSweep = this.currentSweep, sizeButton = 10) {
|
|
330
|
-
this.currentSweep = currentSweep;
|
|
331
|
-
if (this.calibrationPlan && currentSweep) {
|
|
332
|
-
const position = this.matterportService.getCurrentCameraPosition()?.position;
|
|
333
|
-
if (position) {
|
|
334
|
-
if (!this.userPositionBtn) {
|
|
335
|
-
this.userPositionBtn = document.createElement('button');
|
|
336
|
-
this.userPositionBtn.id = 'currentPosition';
|
|
337
|
-
this.planDivContent.append(this.userPositionBtn);
|
|
338
|
-
this.userPositionBtn.title = 'You are here';
|
|
339
|
-
this.styleButton(this.userPositionBtn, 'https://api.iconify.design/bx:bxs-user-circle.svg?color=green&height=17&width=17', sizeButton);
|
|
340
|
-
}
|
|
341
|
-
let x;
|
|
342
|
-
let y;
|
|
343
|
-
if (this.calibrationPlan.new) {
|
|
344
|
-
const position2D = this.transformPosition3DForNewCalibration(position);
|
|
345
|
-
x = position2D.x / position2D.coeffX - 5;
|
|
346
|
-
y = position2D.y / position2D.coeffY - 5;
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
x =
|
|
350
|
-
(this.calibrationPlan.offsetX +
|
|
351
|
-
position.x * this.calibrationPlan.x) /
|
|
352
|
-
this.coeffPlanX;
|
|
353
|
-
y =
|
|
354
|
-
(this.calibrationPlan.offsetY +
|
|
355
|
-
position.z * this.calibrationPlan.y) /
|
|
356
|
-
this.coeffPlanY;
|
|
357
|
-
}
|
|
358
|
-
this.userPositionBtn.style.top = `${y}px`;
|
|
359
|
-
this.userPositionBtn.style.left = `${x}px`;
|
|
360
|
-
this.moveOnPoint({ x: x + 5, y: y + 5 });
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* Center the view of the plan on coordinates
|
|
366
|
-
* @param coordinate Coordinate on the plan
|
|
367
|
-
*/
|
|
368
|
-
moveOnPoint(coordinate) {
|
|
369
|
-
if (this.planDiv) {
|
|
370
|
-
const scale = this.panzoom.getTransform().scale;
|
|
371
|
-
const moveX = this.planDiv.clientWidth / 2 - coordinate.x * scale;
|
|
372
|
-
const moveY = this.planDiv.clientHeight / 2 - coordinate.y * scale;
|
|
373
|
-
this.panzoom.moveTo(moveX, moveY);
|
|
374
|
-
this.planDivContent.style.transformOrigin = `${coordinate.x}px ${coordinate.y}px`;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* Apply a rotation to the plan
|
|
379
|
-
* Buttons will remain in the correct rotation
|
|
380
|
-
* @param rotation
|
|
381
|
-
*/
|
|
382
|
-
updateRotation(rotation) {
|
|
383
|
-
this.lastRotation = rotation;
|
|
384
|
-
if (this.planDivContent) {
|
|
385
|
-
this.planDivContent.style.transform = `rotate(${rotation}deg)`;
|
|
386
|
-
const buttons = this.planDivContent.querySelectorAll('button');
|
|
387
|
-
let rotationRegex = /(rotate\(-?\d*\.?\d+deg\))/g;
|
|
388
|
-
// eslint-disable-next-line unicorn/no-array-for-each
|
|
389
|
-
buttons.forEach((button) => {
|
|
390
|
-
button.style.transform = button.style.transform.replace(rotationRegex, "") + ` rotate(${-rotation}deg)`;
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
removeCurrentPosition() {
|
|
395
|
-
const button = document.querySelector('#currentPosition');
|
|
396
|
-
if (button) {
|
|
397
|
-
button.remove();
|
|
398
|
-
this.userPositionBtn = null;
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
styleButton(button, url, sizeButton = 10) {
|
|
402
|
-
button.style.backgroundImage = `url(${url})`;
|
|
403
|
-
button.style.backgroundColor = 'transparent';
|
|
404
|
-
button.style.position = 'absolute';
|
|
405
|
-
button.style.border = 'none';
|
|
406
|
-
button.style.width = `10px`;
|
|
407
|
-
button.style.height = `10px`;
|
|
408
|
-
button.disabled = false;
|
|
409
|
-
button.style.backgroundSize = 'contain';
|
|
410
|
-
button.style.backgroundRepeat = 'no-repeat';
|
|
411
|
-
button.style.transform = `scale(${sizeButton / 10})`;
|
|
412
|
-
}
|
|
413
|
-
addListenersToButton(button, url, tagService = null, element = null) {
|
|
414
|
-
let videoJsPlayer;
|
|
415
|
-
button.addEventListener('mouseenter', async (event) => {
|
|
416
|
-
const contentForButton = this.htmlContentToInject.find((object) => object.elementID === button.id);
|
|
417
|
-
this.btnTagIsHover = true;
|
|
418
|
-
const title = document.querySelector(`#titleTagDiv`);
|
|
419
|
-
if (contentForButton.title) {
|
|
420
|
-
title.style.display = 'inline';
|
|
421
|
-
title.innerHTML = contentForButton.title;
|
|
422
|
-
}
|
|
423
|
-
else {
|
|
424
|
-
title.style.display = 'none';
|
|
425
|
-
}
|
|
426
|
-
const content = document.querySelector(`#htmlTagDiv`);
|
|
427
|
-
this.detailTagDiv.style.top = `${event.clientY + 10}px`;
|
|
428
|
-
this.detailTagDiv.style.left = `${event.clientX < 120 ? 0 : event.clientX - 120}px`;
|
|
429
|
-
this.detailTagDiv.style.display = 'block';
|
|
430
|
-
// console.log(contentForButton.content);
|
|
431
|
-
content.innerHTML = contentForButton.content;
|
|
432
|
-
const detailButton = content.querySelector('#detailBtn');
|
|
433
|
-
if (detailButton) {
|
|
434
|
-
detailButton.addEventListener('click', () => {
|
|
435
|
-
this.visibilityService.detailShowing.next(true);
|
|
436
|
-
this.router.navigate([url]);
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
// handle image carousel fullscreen button
|
|
440
|
-
const imageFullscreenBtn = content.querySelector('#image-footer');
|
|
441
|
-
if (imageFullscreenBtn) {
|
|
442
|
-
imageFullscreenBtn.addEventListener('click', function () {
|
|
443
|
-
if (tagService) {
|
|
444
|
-
tagService.onActionImageClick(contentForButton.elementID);
|
|
445
|
-
}
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
// handle booking fullscreen button
|
|
449
|
-
const bookingButton = content.querySelector('#bookingBtn');
|
|
450
|
-
if (bookingButton) {
|
|
451
|
-
bookingButton.addEventListener('click', () => {
|
|
452
|
-
this.visibilityService.detailShowing.next(true);
|
|
453
|
-
this.router.navigate([url]);
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
// handle document pdf fullscreen button
|
|
457
|
-
const docFullscreenBtn = content.querySelector('#doc-footer');
|
|
458
|
-
if (docFullscreenBtn && element) {
|
|
459
|
-
const documentUrl = tagService.getAnnexeForCommentTypeInFeature(element, CommentType.DOCUMENT);
|
|
460
|
-
docFullscreenBtn.addEventListener('click', function () {
|
|
461
|
-
if (tagService) {
|
|
462
|
-
tagService.onActionDocClick(documentUrl);
|
|
463
|
-
}
|
|
464
|
-
});
|
|
465
|
-
}
|
|
466
|
-
// handle video fullscreen button
|
|
467
|
-
const videoFullscreenBtn = content.querySelector('#btn-video-fullscreen');
|
|
468
|
-
if (videoFullscreenBtn && element) {
|
|
469
|
-
const videoUrl = tagService.getAnnexeForCommentTypeInFeature(element, CommentType.VIDEO);
|
|
470
|
-
videoFullscreenBtn.addEventListener('click', function () {
|
|
471
|
-
if (tagService) {
|
|
472
|
-
tagService.onActionVideoClick(videoUrl);
|
|
473
|
-
}
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
|
-
// handle Youtube video fullscreen button
|
|
477
|
-
const youtubeFullScreen = content.querySelector('#btn-video-fullscreen-youtube');
|
|
478
|
-
if (youtubeFullScreen && element) {
|
|
479
|
-
const youtubeUrl = tagService.getAnnexeForCommentTypeInFeature(element, CommentType.YOUTUBE);
|
|
480
|
-
youtubeFullScreen.addEventListener('click', function () {
|
|
481
|
-
if (tagService) {
|
|
482
|
-
tagService.onActionYoutubeClick(youtubeUrl);
|
|
483
|
-
}
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
// handle mute video button
|
|
487
|
-
const btnMute = document.getElementById('btn-mute');
|
|
488
|
-
const imgOn = document.getElementById('sound-on');
|
|
489
|
-
const imgOff = document.getElementById('sound-off');
|
|
490
|
-
const playerElement = document.getElementById("mus-video-tag");
|
|
491
|
-
if (playerElement) {
|
|
492
|
-
videoJsPlayer = videojs("mus-video-tag");
|
|
493
|
-
if (btnMute && videoJsPlayer) {
|
|
494
|
-
btnMute.addEventListener('click', function () {
|
|
495
|
-
if (videoJsPlayer.muted()) {
|
|
496
|
-
videoJsPlayer.muted(false);
|
|
497
|
-
if (imgOn && imgOff) {
|
|
498
|
-
imgOn.style.display = 'inline-block';
|
|
499
|
-
imgOff.style.display = 'none';
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
else {
|
|
503
|
-
videoJsPlayer.muted(true);
|
|
504
|
-
if (imgOn && imgOff) {
|
|
505
|
-
imgOn.style.display = 'none';
|
|
506
|
-
imgOff.style.display = 'inline-block';
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
// handle audio player buttons
|
|
513
|
-
const playerButton = document.querySelector('.audio-play-button');
|
|
514
|
-
const audio = document.getElementById('audio-tag');
|
|
515
|
-
const timeline = document.querySelector('.timeline-tag');
|
|
516
|
-
// const timelineValue = document.querySelector('.timeline-tag').value;
|
|
517
|
-
const soundButton = document.querySelector('.audio-sound-btn');
|
|
518
|
-
const playAudio = document.getElementById('play');
|
|
519
|
-
const pauseAudio = document.getElementById('pause');
|
|
520
|
-
const imgSoundOn = document.getElementById('audio-sound-on');
|
|
521
|
-
const imgSoundOff = document.getElementById('audio-sound-off');
|
|
522
|
-
const audioModal = document.getElementById('btn-audio-modal');
|
|
523
|
-
if (audio && playerButton && timeline) {
|
|
524
|
-
playerButton.addEventListener('click', function () {
|
|
525
|
-
if (audio.paused) {
|
|
526
|
-
audio.play();
|
|
527
|
-
pauseAudio.style.display = 'inline-block';
|
|
528
|
-
playAudio.style.display = 'none';
|
|
529
|
-
}
|
|
530
|
-
else {
|
|
531
|
-
audio.pause();
|
|
532
|
-
pauseAudio.style.display = 'none';
|
|
533
|
-
playAudio.style.display = 'inline-block';
|
|
534
|
-
}
|
|
535
|
-
});
|
|
536
|
-
soundButton.addEventListener('click', function () {
|
|
537
|
-
if (audio.muted) {
|
|
538
|
-
audio.muted = false;
|
|
539
|
-
imgSoundOn.style.display = 'inline-block';
|
|
540
|
-
imgSoundOff.style.display = 'none';
|
|
541
|
-
}
|
|
542
|
-
else {
|
|
543
|
-
audio.muted = true;
|
|
544
|
-
imgSoundOn.style.display = 'none';
|
|
545
|
-
imgSoundOff.style.display = 'inline-block';
|
|
546
|
-
}
|
|
547
|
-
});
|
|
548
|
-
function changeTimelinePosition() {
|
|
549
|
-
if (audio.duration) {
|
|
550
|
-
const percentagePosition = (100 * audio.currentTime) / audio.duration;
|
|
551
|
-
const percentagePositionString = percentagePosition + '%';
|
|
552
|
-
timeline.style.backgroundSize = percentagePositionString + ' 100%';
|
|
553
|
-
timeline.value = percentagePosition.toString();
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
audio.ontimeupdate = changeTimelinePosition;
|
|
557
|
-
function changeSeek() {
|
|
558
|
-
const time = (parseInt(timeline.value) * audio.duration) / 100;
|
|
559
|
-
audio.currentTime = time;
|
|
560
|
-
}
|
|
561
|
-
timeline.addEventListener('change', changeSeek);
|
|
562
|
-
timeline.addEventListener('input', changeSeek);
|
|
563
|
-
// handle audio click
|
|
564
|
-
if (audioModal && element) {
|
|
565
|
-
const audioComment = element.comments?.items.find((com) => com.type === CommentType.AUDIO && com.shownInTag);
|
|
566
|
-
const audioCommentID = audioComment ? audioComment.id : '';
|
|
567
|
-
audioModal.addEventListener('click', function () {
|
|
568
|
-
if (tagService) {
|
|
569
|
-
tagService.onActionAudioClick(audioCommentID);
|
|
570
|
-
}
|
|
571
|
-
});
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
});
|
|
575
|
-
button.addEventListener('mouseleave', async () => {
|
|
576
|
-
// we wait if user hovers on to div of the tag (changes this.focusMouseTagDiv)
|
|
577
|
-
this.btnTagIsHover = false;
|
|
578
|
-
setTimeout(() => {
|
|
579
|
-
if (!this.focusMouseTagDiv && !this.btnTagIsHover) {
|
|
580
|
-
this.detailTagDiv.style.display = 'none';
|
|
581
|
-
if (videoJsPlayer) {
|
|
582
|
-
videoJsPlayer.dispose();
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
}, 100);
|
|
586
|
-
});
|
|
587
|
-
button.addEventListener('click', async () => {
|
|
588
|
-
this.detailTagDiv.style.display = 'none';
|
|
589
|
-
if (videoJsPlayer) {
|
|
590
|
-
videoJsPlayer.dispose();
|
|
591
|
-
}
|
|
592
|
-
await this.viewerService.action_move_to_tag(button.id);
|
|
593
|
-
this.visibilityService.detailShowing.next(true);
|
|
594
|
-
this.router.navigate([url]);
|
|
595
|
-
});
|
|
596
|
-
}
|
|
597
|
-
clearBtn(idList) {
|
|
598
|
-
for (const id of idList) {
|
|
599
|
-
const button = document.getElementById(id);
|
|
600
|
-
if (button) {
|
|
601
|
-
button.remove();
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
clearAllButtons() {
|
|
606
|
-
if (this.planDivContent) {
|
|
607
|
-
const buttons = this.planDivContent.querySelectorAll('button');
|
|
608
|
-
// eslint-disable-next-line unicorn/no-array-for-each
|
|
609
|
-
buttons.forEach(function (currentValue) {
|
|
610
|
-
currentValue.remove();
|
|
611
|
-
});
|
|
612
|
-
this.userPositionBtn = null;
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
updateAllButtonsStyle(properties, values) {
|
|
616
|
-
if (this.planDivContent) {
|
|
617
|
-
const buttons = this.planDivContent.querySelectorAll('button');
|
|
618
|
-
// eslint-disable-next-line unicorn/no-array-for-each
|
|
619
|
-
buttons.forEach(function (currentValue) {
|
|
620
|
-
properties.forEach((property, i) => {
|
|
621
|
-
if (property === "transform") {
|
|
622
|
-
//For saving the rotation and adding scale
|
|
623
|
-
let rotationRegex = /(rotate\(-?\d*\.?\d+deg\))/g;
|
|
624
|
-
let rotationMatch = currentValue.style[property].match(rotationRegex);
|
|
625
|
-
if (rotationMatch.length > 0) {
|
|
626
|
-
currentValue.style[property] = `${values[i]} ${rotationMatch[0]}`;
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
else {
|
|
630
|
-
currentValue.style[property] = values[i];
|
|
631
|
-
}
|
|
632
|
-
});
|
|
633
|
-
});
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
onPlanRemove() {
|
|
637
|
-
this.userPositionBtn = null;
|
|
638
|
-
this.calibrationPlan = null;
|
|
639
|
-
this.currentSweep = null;
|
|
640
|
-
this.detailTagDiv = null;
|
|
641
|
-
}
|
|
642
|
-
async resizePlan(isRemoving) {
|
|
643
|
-
this.resizePlanSubscription.next(false);
|
|
644
|
-
if (isRemoving) {
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
|
-
console.log('in resizePlan');
|
|
648
|
-
if (this.planDiv && this.currentSweep) {
|
|
649
|
-
this.panzoom = panzoom(this.planDiv, {
|
|
650
|
-
bounds: true,
|
|
651
|
-
boundsPadding: 0,
|
|
652
|
-
maxZoom: 4,
|
|
653
|
-
});
|
|
654
|
-
setTimeout(() => {
|
|
655
|
-
const rect = {
|
|
656
|
-
width: this.planDivContent.offsetWidth,
|
|
657
|
-
height: this.planDivContent.offsetHeight,
|
|
658
|
-
};
|
|
659
|
-
const { coeffX, coeffY } = getCoefficientsForImage(this.imgPlan, rect);
|
|
660
|
-
this.coeffPlanX = coeffX;
|
|
661
|
-
this.coeffPlanY = coeffY;
|
|
662
|
-
this.panzoom.zoomAbs(0, 0, 4);
|
|
663
|
-
this.resizePlanSubscription.next(true);
|
|
664
|
-
}, 200);
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
handleTouch(event) {
|
|
668
|
-
const now = Date.now();
|
|
669
|
-
if (now - this.lastTouchTime < this.delayDblTouch) {
|
|
670
|
-
this.lastTouchTime = 0;
|
|
671
|
-
// this.onDblClickPlan(event);
|
|
672
|
-
/** Simulate a dblclick for phone (we don't get offsetX/Y on touchevent) */
|
|
673
|
-
const newEvent = document.createEvent('MouseEvents');
|
|
674
|
-
const touch = event.changedTouches[0];
|
|
675
|
-
newEvent.initMouseEvent('dblclick', true, true, event.target.ownerDocument.defaultView, 0, touch.screenX, touch.screenY, touch.clientX, touch.clientY, event.ctrlKey, event.altKey, event.shirtKey, event.metaKey, 0, null);
|
|
676
|
-
event.target.dispatchEvent(newEvent);
|
|
677
|
-
}
|
|
678
|
-
else {
|
|
679
|
-
this.lastTouchTime = now;
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
async onDblClickPlan(event) {
|
|
683
|
-
event.preventDefault();
|
|
684
|
-
const clickX = event.offsetX;
|
|
685
|
-
const clickY = event.offsetY;
|
|
686
|
-
const zonePlan = this.currentPlan.zone;
|
|
687
|
-
if (zonePlan) {
|
|
688
|
-
const navigations = await this.navigationService.getNavigationsForZone(zonePlan);
|
|
689
|
-
if (navigations.length > 0) {
|
|
690
|
-
await Promise.all(navigations.map(async (nav) => {
|
|
691
|
-
const position = JSON.parse(nav.position);
|
|
692
|
-
let x;
|
|
693
|
-
let y;
|
|
694
|
-
if (this.calibrationPlan.new) {
|
|
695
|
-
const position2D = this.transformPosition3DForNewCalibration(position);
|
|
696
|
-
x = position2D.x / position2D.coeffX;
|
|
697
|
-
y = position2D.y / position2D.coeffY;
|
|
698
|
-
}
|
|
699
|
-
else {
|
|
700
|
-
x =
|
|
701
|
-
(this.calibrationPlan.offsetX +
|
|
702
|
-
position.x * this.calibrationPlan.x) /
|
|
703
|
-
this.coeffPlanX;
|
|
704
|
-
y =
|
|
705
|
-
(this.calibrationPlan.offsetY +
|
|
706
|
-
position.z * this.calibrationPlan.y) /
|
|
707
|
-
this.coeffPlanY;
|
|
708
|
-
}
|
|
709
|
-
const distX = Math.abs(clickX - x);
|
|
710
|
-
const distY = Math.abs(clickY - y);
|
|
711
|
-
nav.dist = Math.sqrt(Math.pow(distX, 2) + Math.pow(distY, 2));
|
|
712
|
-
}));
|
|
713
|
-
navigations.sort((a, b) => {
|
|
714
|
-
return a.dist - b.dist;
|
|
715
|
-
});
|
|
716
|
-
this.matterportService.action_go_to_sweep(navigations[0].matterportSweepID);
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
/**
|
|
721
|
-
* Configures plan from cache (previous plan).
|
|
722
|
-
*/
|
|
723
|
-
async uploadPlanFromCache() {
|
|
724
|
-
this.htmlContentToInject = this.cache.htmlContent;
|
|
725
|
-
await this.configurePlan(this.cache.plan);
|
|
726
|
-
return Promise.resolve();
|
|
727
|
-
}
|
|
728
|
-
/**
|
|
729
|
-
* Puts buttons (tags) from cache according to passed element IDs (for filter if any)
|
|
730
|
-
* @param elementIDs elements (tickets, equipments, etc) to be shown on plan
|
|
731
|
-
*/
|
|
732
|
-
uploadTagsFromCache(sizeButton = 10) {
|
|
733
|
-
// console.log("uploading tags from cache");
|
|
734
|
-
for (const cached of this.cache.htmlContent) {
|
|
735
|
-
const button = document.createElement('button');
|
|
736
|
-
this.styleButton(button, cached.tagIcon, sizeButton);
|
|
737
|
-
button.id = cached.elementID;
|
|
738
|
-
this.planDivContent.append(button);
|
|
739
|
-
if (this.calibrationPlan.new) {
|
|
740
|
-
const newCoeffX = this.coeffPlanX /
|
|
741
|
-
(this.imgPlan.width / this.calibrationPlan.imgWidth);
|
|
742
|
-
const newCoeffY = this.coeffPlanY /
|
|
743
|
-
(this.imgPlan.height / this.calibrationPlan.imgHeight);
|
|
744
|
-
button.style.top = `${cached.y / newCoeffY - 5}px`;
|
|
745
|
-
button.style.left = `${cached.x / newCoeffX - 5}px`;
|
|
746
|
-
}
|
|
747
|
-
else {
|
|
748
|
-
button.style.top = `${cached.y / this.coeffPlanY - 5}px`;
|
|
749
|
-
button.style.left = `${cached.x / this.coeffPlanX - 5}px`;
|
|
750
|
-
}
|
|
751
|
-
this.addListenersToButton(button, cached.url);
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
async getCalibratedPlanForZone(zone) {
|
|
755
|
-
let plans = (await this.API.PlansByZone(zone.id)).items;
|
|
756
|
-
let parentZone = null;
|
|
757
|
-
if (plans.length === 0) {
|
|
758
|
-
// try to find parent zone
|
|
759
|
-
parentZone = await this.API.GetZone(zone.parentID);
|
|
760
|
-
plans = (await this.API.PlansByZone(zone.parentID)).items;
|
|
761
|
-
}
|
|
762
|
-
const calibratedPlan = plans.find((plan) => plan.calibration && plan.isCurrentForZone);
|
|
763
|
-
if (calibratedPlan) {
|
|
764
|
-
const signed = await getSignedFile(calibratedPlan.annexe);
|
|
765
|
-
if (signed) {
|
|
766
|
-
calibratedPlan.filepath = signed;
|
|
767
|
-
}
|
|
768
|
-
calibratedPlan.navigationIDs = parentZone
|
|
769
|
-
? parentZone.sweepIDs
|
|
770
|
-
: zone.sweepIDs;
|
|
771
|
-
}
|
|
772
|
-
return calibratedPlan || null;
|
|
773
|
-
}
|
|
774
|
-
transformPosition3DForNewCalibration(position) {
|
|
775
|
-
const positionX = this.calibrationPlan.nameXAxis === 'x' ? position.x : position.z;
|
|
776
|
-
const positionY = this.calibrationPlan.nameYAxis === 'x' ? position.x : position.z;
|
|
777
|
-
let x = this.calibrationPlan.offsetX + positionX * this.calibrationPlan.scaleX;
|
|
778
|
-
let y = this.calibrationPlan.offsetY + positionY * this.calibrationPlan.scaleY;
|
|
779
|
-
const newCoeffX = this.coeffPlanX / (this.imgPlan.width / this.calibrationPlan.imgWidth);
|
|
780
|
-
// console.log("newCoeffX", newCoeffX);
|
|
781
|
-
const newCoeffY = this.coeffPlanY / (this.imgPlan.height / this.calibrationPlan.imgHeight);
|
|
782
|
-
x = (x - this.calibrationPlan.offsetXPlan) / this.calibrationPlan.scalePlan;
|
|
783
|
-
y = (y - this.calibrationPlan.offsetYPlan) / this.calibrationPlan.scalePlan;
|
|
784
|
-
// console.log(x, y);
|
|
785
|
-
return { x, y, coeffX: newCoeffX, coeffY: newCoeffY };
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
PlanService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: PlanService, deps: [{ token: 'currentAPIService' }, { token: i1.ZoneService }, { token: i2.NavigationService }, { token: i3.ViewerService }, { token: i4.Router }, { token: i5.MatterportService }, { token: i6.BaseVisibilityService }, { token: i7.ContentService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
789
|
-
PlanService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: PlanService, providedIn: 'root' });
|
|
790
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: PlanService, decorators: [{
|
|
791
|
-
type: Injectable,
|
|
792
|
-
args: [{
|
|
793
|
-
providedIn: 'root',
|
|
794
|
-
}]
|
|
795
|
-
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
796
|
-
type: Inject,
|
|
797
|
-
args: ['currentAPIService']
|
|
798
|
-
}] }, { type: i1.ZoneService }, { type: i2.NavigationService }, { type: i3.ViewerService }, { type: i4.Router }, { type: i5.MatterportService }, { type: i6.BaseVisibilityService }, { type: i7.ContentService }]; } });
|
|
799
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWNvcmUvc3JjL2xpYi9zZXJ2aWNlcy9tb2RlbHMvcGxhbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtCQUErQjtBQUMvQiwyQ0FBMkM7QUFDM0MsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUM5RCxPQUFPLE9BQU8sTUFBTSxTQUFTLENBQUM7QUFDOUIsT0FBTyxPQUFPLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFL0IsT0FBTyxFQUNILFdBQVcsRUFDWCxXQUFXLEVBRVgsT0FBTyxHQUVWLE1BQU0scUJBQXFCLENBQUM7QUFNN0IsT0FBTyxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHOUQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDOzs7Ozs7Ozs7QUFNeEQsTUFBTSxPQUFPLFdBQVc7SUEwRXBCLFlBQ2lDLFdBQWdCLEVBQ3JDLFdBQXdCLEVBQ3hCLGlCQUFvQztJQUM1Qyw4QkFBOEI7SUFDdEIsYUFBNEIsRUFDNUIsTUFBYyxFQUNkLGlCQUFvQztJQUM1Qyw2QkFBNkI7SUFDckIsaUJBQXdDLEVBQ3hDLGNBQThCO1FBUjlCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFFcEMsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLHNCQUFpQixHQUFq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U0FBUyxFQUFFLENBQUM7SUFDMUQsQ0FBQzs7d0dBcjlCUSxXQUFXLGtCQTJFUixtQkFBbUI7NEdBM0V0QixXQUFXLGNBRlIsTUFBTTsyRkFFVCxXQUFXO2tCQUh2QixVQUFVO21CQUFDO29CQUNSLFVBQVUsRUFBRSxNQUFNO2lCQUNyQjs7MEJBNEVRLE1BQU07MkJBQUMsbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgZnVuYy1uYW1lcyAqL1xuLyogZXNsaW50LWRpc2FibGUgY2xhc3MtbWV0aG9kcy11c2UtdGhpcyAqL1xuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBnZXREb2N1bWVudCwgR2xvYmFsV29ya2VyT3B0aW9ucyB9IGZyb20gJ3BkZmpzLWRpc3QnO1xuaW1wb3J0IHBhbnpvb20gZnJvbSAncGFuem9vbSc7XG5pbXBvcnQgdmlkZW9qcyBmcm9tIFwidmlkZW8uanNcIjtcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge1xuICAgIENvbW1lbnRUeXBlLFxuICAgIEZlYXR1cmVUeXBlLFxuICAgIFBsYW4sXG4gICAgUG9pVHlwZSxcbiAgICBab25lLFxufSBmcm9tICcuLi8uLi90eXBlcy5zZXJ2aWNlJztcbmltcG9ydCB7IEJhc2VWaXNpYmlsaXR5U2VydmljZSB9IGZyb20gJy4uL2Jhc2VWaXNpYmlsaXR5LnNlcnZpY2UnO1xuaW1wb3J0IHsgTWF0dGVycG9ydFNlcnZpY2UgfSBmcm9tICcuLi9tYXR0ZXJwb3J0LnNlcnZpY2UnO1xuaW1wb3J0IHsgVmlld2VyU2VydmljZSB9IGZyb20gJy4uL3ZpZXdlci5zZXJ2aWNlJztcbmltcG9ydCB7IFpvbmVTZXJ2aWNlIH0gZnJvbSAnLi96b25lLnNlcnZpY2UnO1xuaW1wb3J0IHsgTmF2aWdhdGlvblNlcnZpY2UgfSBmcm9tICcuL25hdmlnYXRpb24uc2VydmljZSc7XG5pbXBvcnQgeyBnZXRTaWduZWRGaWxlLCB1cGxvYWRGaWxlVG9TMyB9IGZyb20gJy4uL3MzLnNlcnZpY2UnO1xuaW1wb3J0IHsgQmFzZVRhZ1NlcnZpY2UgfSBmcm9tICcuLi90YWcuc2VydmljZSc7XG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLi8uLi9jb25maWcnO1xuaW1wb3J0IHsgZ2V0Q29lZmZpY2llbnRzRm9ySW1hZ2UgfSBmcm9tICcuLi96b25lLWRyYXdlci5zZXJ2aWNlJztcbmltcG9ydCB7IGdldE1ldGFGb3JJbWFnZSB9IGZyb20gJy4uLy4uL2hlbHBlcnMuc2VydmljZSc7XG5pbXBvcnQgeyBDb250ZW50U2VydmljZSB9IGZyb20gJy4uL2NvbnRlbnQuc2VydmljZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFBsYW5TZXJ2aWNlIHtcbiAgICBjaG9zZW5QbGFuOiBQbGFuO1xuXG4gICAgY3VycmVudFBsYW46IFBsYW47XG5cbiAgICBjdXJyZW50U3dlZXA6IHN0cmluZztcblxuICAgIHBsYW5GaWxlQ2FjaGU6IEZpbGU7XG5cbiAgICBwbGFuQ2FudmFzOiBhbnk7XG5cbiAgICBwbGFuRGl2OiBIVE1MRWxlbWVudCB8IFNWR0VsZW1lbnQ7XG4gICAgcGxhbkRpdkNvbnRlbnQ6IEhUTUxFbGVtZW50O1xuXG4gICAgcGFuem9vbTogYW55O1xuXG4gICAgaXNSZWFkeTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgdXNlclBvc2l0aW9uQnRuOiBIVE1MQnV0dG9uRWxlbWVudDtcblxuICAgIGNvZWZmUGxhblg6IG51bWJlcjtcblxuICAgIGNvZWZmUGxhblk6IG51bWJlcjtcblxuICAgIGNhbGlicmF0aW9uUGxhbjogYW55O1xuXG4gICAgZGV0YWlsVGFnRGl2OiBIVE1MRWxlbWVudDtcblxuICAgIGRldGFpbFRhZ0RpdklzSG92ZXIgPSBmYWxzZTtcblxuICAgIGJ0blRhZ0lzSG92ZXIgPSBmYWxzZTtcblxuICAgIHJlc2l6ZVBsYW5TdWJzY3JpcHRpb24gPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuXG4gICAgaW1nUGxhbjogSFRNTEltYWdlRWxlbWVudDtcblxuICAgIGxhc3RUb3VjaFRpbWUgPSAwO1xuXG4gICAgZGVsYXlEYmxUb3VjaCA9IDUwMDtcblxuICAgIGxhc3RSb3RhdGlvbjogbnVtYmVyID0gMDtcblxuICAgIGh0bWxDb250ZW50VG9JbmplY3Q6IHtcbiAgICAgICAgdGl0bGU6IHN0cmluZztcbiAgICAgICAgY29udGVudDogc3RyaW5nO1xuICAgICAgICBlbGVtZW50SUQ6IHN0cmluZztcbiAgICAgICAgeTogbnVtYmVyO1xuICAgICAgICB4OiBudW1iZXI7XG4gICAgICAgIHRhZ0ljb246IHN0cmluZztcbiAgICAgICAgdXJsOiBzdHJpbmc7XG4gICAgfVtdID0gW107XG5cbiAgICBjYWNoZToge1xuICAgICAgICBlcXVpcElEczogc3RyaW5nW107XG4gICAgICAgIHRpY2tldElEczogc3RyaW5nW107XG4gICAgICAgIG1lYXN1cmVtZW50c0lEczogc3RyaW5nW107XG4gICAgICAgIGZlYXR1cmVJRHM6IHN0cmluZ1tdO1xuICAgICAgICB6b25lSUQ6IHN0cmluZztcbiAgICAgICAgcGxhbjogUGxhbjtcbiAgICAgICAgaHRtbENvbnRlbnQ6IHtcbiAgICAgICAgICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgICAgICAgICBjb250ZW50OiBzdHJpbmc7XG4gICAgICAgICAgICBlbGVtZW50SUQ6IHN0cmluZztcbiAgICAgICAgICAgIHk6IG51bWJlcjtcbiAgICAgICAgICAgIHg6IG51bWJlcjtcbiAgICAgICAgICAgIHRhZ0ljb246IHN0cmluZztcbiAgICAgICAgICAgIHVybDogc3RyaW5nO1xuICAgICAgICB9W107XG4gICAgfTtcblxuICAgIGZvY3VzTW91c2VUYWdEaXY6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIEFQSTogYW55OyAvL0FXU1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIEBJbmplY3QoJ2N1cnJlbnRBUElTZXJ2aWNlJykgYXBpSW5qZWN0ZWQ6IGFueSxcbiAgICAgICAgcHJpdmF0ZSB6b25lU2VydmljZTogWm9uZVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbmF2aWdhdGlvblNlcnZpY2U6IE5hdmlnYXRpb25TZXJ2aWNlLFxuICAgICAgICAvLyB0YWdTZXJ2aWNlOiBCYXNlVGFnU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSB2aWV3ZXJTZXJ2aWNlOiBWaWV3ZXJTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxuICAgICAgICBwcml2YXRlIG1hdHRlcnBvcnRTZXJ2aWNlOiBNYXR0ZXJwb3J0U2VydmljZSxcbiAgICAgICAgLy8gcHJpdmF0ZSBjb25maWc6IEFwcENvbmZpZyxcbiAgICAgICAgcHJpdmF0ZSB2aXNpYmlsaXR5U2VydmljZTogQmFzZVZpc2liaWxpdHlTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIGNvbnRlbnRTZXJ2aWNlOiBDb250ZW50U2VydmljZVxuICAgICkge1xuICAgICAgICB0aGlzLkFQSSA9IGFwaUluamVjdGVkO1xuICAgICAgICB0aGlzLm1hdHRlcnBvcnRTZXJ2aWNlLmN1cnJlbnRDYW1lcmFQb3NlLnN1YnNjcmliZSgocG9zZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVSb3RhdGlvbihwb3NlLnJvdGF0aW9uLnkpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBjcmVhdGVQbGFuKHBsYW5JbnB1dDogUGxhbik6IFByb21pc2U8UGxhbj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5BUEkuX19wcm90b19fLkNyZWF0ZVBsYW4ocGxhbklucHV0KTtcbiAgICB9XG5cbiAgICBhc3luYyBkZWxldGVQbGFuKHBsYW46IFBsYW4pOiBQcm9taXNlPFBsYW4+IHtcbiAgICAgICAgLy8gYXdhaXQgZGVsZXRlRnJvbVMzKHBsYW4uYW5uZXhlKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuQVBJLl9fcHJvdG9fXy5EZWxldGVQbGFuKHsgaWQ6IHBsYW4uaWQgfSk7XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0UGxhbnNGb3JTcGFjZShzcGFjZUlEOiBzdHJpbmcpOiBQcm9taXNlPFBsYW5bXT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5BUEkuX19wcm90b19fXG4gICAgICAgICAgICAuUGxhbnNCeVNwYWNlKHNwYWNlSUQpXG4gICAgICAgICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLml0ZW1zKTtcbiAgICB9XG5cbiAgICBhc3luYyBnZXRQbGFuc0ZvclpvbmUoem9uZUlEOiBzdHJpbmcpOiBQcm9taXNlPFBsYW5bXT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5BUEkuX19wcm90b19fXG4gICAgICAgICAgICAuUGxhbnNCeVpvbmUoem9uZUlEKVxuICAgICAgICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5pdGVtcyk7XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0U2luZ2VkUGxhbnNGb3JTcGFjZShzcGFjZUlEOiBzdHJpbmcpOiBQcm9taXNlPFBsYW5bXT4ge1xuICAgICAgICBjb25zdCBwbGFuc0Zyb21EQiA9IGF3YWl0IHRoaXMuZ2V0UGxhbnNGb3JTcGFjZShzcGFjZUlEKTtcbiAgICAgICAgLy8gY29uc29sZS5sb2cocGxhbnNGcm9tREIpO1xuICAgICAgICBjb25zdCBwbGFucyA9IFtdO1xuICAgICAgICBpZiAocGxhbnNGcm9tREIubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICAgICAgcGxhbnNGcm9tREIubWFwKGFzeW5jIChwbGFuKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBsYW5PYmplY3QgPSB7IC4uLnBsYW4gfSBhcyBQbGFuO1xuICAgICAgICAgICAgICAgICAgICAvLyBhbm5leGUgbG9va3MgbGlrZSB2aXNpdHMvbW9kZWxJRC9wbGFucy9maWxlLmV4dGVuc2lvblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaWduZWQgPSBhd2FpdCBnZXRTaWduZWRGaWxlKHBsYW4uYW5uZXhlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpZ25lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGxhbk9iamVjdC5maWxlcGF0aCA9IHNpZ25lZDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAocGxhbi5hbm5leGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFssIG1vZGVsSUQsICwgZmlsZW5hbWVXaXRoRXh0ZW5zaW9uXSA9IHBsYW4uYW5uZXhlLnNwbGl0KCcvJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBbLCBleHRlbnRpb25dID0gZmlsZW5hbWVXaXRoRXh0ZW5zaW9uLnNwbGl0KCcuJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwbGFuT2JqZWN0Lm1vZGVsM2QgPSBtb2RlbElEO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGxhbk9iamVjdC5leHRlbnNpb24gPSBleHRlbnRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBwbGFucy5wdXNoKHBsYW5PYmplY3QpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYEVycm9yIHBsYW4gaGF2ZSBub3QgYW5uZXhlID0+IGApO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2cocGxhbi5pZCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGxhbnM7XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0UGxhbnNXaXRoWm9uZXNGb3JTcGFjZShzcGFjZUlEOiBzdHJpbmcpOiBQcm9taXNlPFBsYW5bXT4ge1xuICAgICAgICBjb25zdCBwbGFucyA9IGF3YWl0IHRoaXMuZ2V0UGxhbnNGb3JTcGFjZShzcGFjZUlEKTtcbiAgICAgICAgY29uc3QgcGxhbnNab25lcyA9IHBsYW5zLmZpbHRlcigocGxhbikgPT4gcGxhbi56b25lICYmIHBsYW4uY2FsaWJyYXRpb24pO1xuICAgICAgICByZXR1cm4gcGxhbnNab25lcztcbiAgICB9XG5cbiAgICBzZXRDaG9zZW5QbGFuKGNob3NlblBsYW46IFBsYW4pIHtcbiAgICAgICAgdGhpcy5jaG9zZW5QbGFuID0gY2hvc2VuUGxhbjtcbiAgICB9XG5cbiAgICBnZXRDaG9zZW5QbGFuKCk6IFBsYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5jaG9zZW5QbGFuO1xuICAgIH1cblxuICAgIHNldFBsYW5GaWxlQ2FjaGUocGxhbkZpbGVDYWNoZTogRmlsZSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnBsYW5GaWxlQ2FjaGUgPSBwbGFuRmlsZUNhY2hlO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgZ2V0UGxhbkZpbGVDYWNoZSgpOiBGaWxlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGxhbkZpbGVDYWNoZTtcbiAgICB9XG5cbiAgICBhc3luYyBjcmVhdGVQbGFuV2l0aEFubmV4ZShwbGFuOiBQbGFuLCBmaWxlOiBGaWxlKTogUHJvbWlzZTxQbGFuPiB7XG4gICAgICAgIGNvbnN0IGNyZWF0ZWRQbGFuID0gYXdhaXQgdGhpcy5jcmVhdGVQbGFuKHBsYW4pO1xuICAgICAgICBjb25zdCBtb2RlbDNEID0gYXdhaXQgdGhpcy56b25lU2VydmljZS5nZXRNb2RlbDNERm9yWm9uZShwbGFuLnpvbmVJRCk7XG4gICAgICAgIGNvbnN0IHVybCA9IGF3YWl0IHVwbG9hZEZpbGVUb1MzKFxuICAgICAgICAgICAgYHZpc2l0cy8ke21vZGVsM0R9L3BsYW5zL2AsXG4gICAgICAgICAgICBmaWxlLFxuICAgICAgICAgICAgY3JlYXRlZFBsYW4uaWRcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHVybCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuQVBJLl9fcHJvdG9fXy5VcGRhdGVQbGFuKHsgaWQ6IGNyZWF0ZWRQbGFuLmlkLCBhbm5leGU6IHVybCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY3JlYXRlZFBsYW47XG4gICAgfVxuXG4gICAgYXN5bmMgdXBkYXRlUGxhbihwbGFuOiBhbnkpOiBQcm9taXNlPFBsYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuQVBJLl9fcHJvdG9fXy5VcGRhdGVQbGFuKHBsYW4pO1xuICAgIH1cblxuICAgIGFzeW5jIHVwZGF0ZVBsYW5GaWxlKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIGlmICh0aGlzLmNob3NlblBsYW4gJiYgdGhpcy5wbGFuRmlsZUNhY2hlKSB7XG4gICAgICAgICAgICBjb25zdCBtb2RlbDNEID0gYXdhaXQgdGhpcy56b25lU2VydmljZS5nZXRNb2RlbDNERm9yWm9uZShcbiAgICAgICAgICAgICAgICB0aGlzLmNob3NlblBsYW4uem9uZUlEXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIHVwbG9hZEZpbGVUb1MzKFxuICAgICAgICAgICAgICAgIGB2aXNpdHMvJHttb2RlbDNEfS9wbGFucy9gLFxuICAgICAgICAgICAgICAgIHRoaXMucGxhbkZpbGVDYWNoZSxcbiAgICAgICAgICAgICAgICB0aGlzLmNob3NlblBsYW4uaWRcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCk7XG4gICAgfVxuXG4gICAgYXN5bmMgc2V0QWxsUGxhbnNGb3Jab25lTm90Q3VycmVudCh6b25lSUQ6IHN0cmluZywgY3VycmVudFBsYW5JRDogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IHBsYW5zID0gYXdhaXQgdGhpcy5BUEkuX19wcm90b19fLkxpc3RQbGFucyh7XG4gICAgICAgICAgICB6b25lSUQ6IHsgZXE6IHpvbmVJRCB9LFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBwbGFucy5pdGVtcy5tYXAoYXN5bmMgKHBsYW4pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocGxhbi5pc0N1cnJlbnRGb3Jab25lICYmIHBsYW4uaWQgIT09IGN1cnJlbnRQbGFuSUQpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVQbGFuKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBwbGFuLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgaXNDdXJyZW50Rm9yWm9uZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgYXN5bmMgY29uZmlndXJlUGxhbihcbiAgICAgICAgY3VycmVudFBsYW46IFBsYW4sXG4gICAgICAgIGRpdklkOiBzdHJpbmcgPSAncGxhbkRpdlBhbmUnLFxuICAgICAgICBkaXZDb250ZW50SWQ6IHN0cmluZyA9ICdwbGFuRGl2UGFuZUNvbnRlbnQnXG4gICAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIHRoaXMuaXNSZWFkeSA9IGZhbHNlO1xuICAgICAgICBpZiAoIXRoaXMuZGV0YWlsVGFnRGl2KSB7XG4gICAgICAgICAgICB0aGlzLmRldGFpbFRhZ0RpdiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgICAgICAgYCNkZXRhaWxUYWdEaXZgXG4gICAgICAgICAgICApIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGV0YWlsVGFnRGl2LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmZvY3VzTW91c2VUYWdEaXYgPSB0cnVlO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXRhaWxUYWdEaXYuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYnRuVGFnSXNIb3ZlciA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5kZXRhaWxUYWdEaXYuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIHRoaXMuZm9jdXNNb3VzZVRhZ0RpdiA9IGZhbHNlO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmNhbGlicmF0aW9uUGxhbiA9IEpTT04ucGFyc2UoY3VycmVudFBsYW4uY2FsaWJyYXRpb24pO1xuICAgICAgICB0aGlzLmN1cnJlbnRQbGFuID0gY3VycmVudFBsYW47XG4gICAgICAgIHRoaXMucGxhbkRpdiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYCMke2RpdklkfWApIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICB0aGlzLnBsYW5EaXZDb250ZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgICAgIGAjJHtkaXZDb250ZW50SWR9YFxuICAgICAgICApIGFzIEhUTUxFbGVtZW50O1xuXG4gICAgICAgIHRoaXMucGxhbkRpdi5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgdGhpcy5oYW5kbGVUb3VjaC5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5wbGFuRGl2LmFkZEV2ZW50TGlzdGVuZXIoJ2RibGNsaWNrJywgdGhpcy5vbkRibENsaWNrUGxhbi5iaW5kKHRoaXMpKTtcblxuICAgICAgICBpZiAoIWN1cnJlbnRQbGFuLmFubmV4ZS5pbmNsdWRlcygncGRmJykpIHtcbiAgICAgICAgICAgIHRoaXMuaW1nUGxhbiA9IGF3YWl0IGdldE1ldGFGb3JJbWFnZShjdXJyZW50UGxhbi5maWxlcGF0aCk7XG4gICAgICAgICAgICAvL1JlY3QgdXNlIG9mZnNldFdpZHRoIDogaGVpZ2h0LCBub3QgYWN0dWFsIGJvdW5kaW5nQ2xpZW50UmVjdCBiZWNhdXNlIHdpbGwgYmUgbW9kaWZpZWQgYnkgdGhlIHpvb20uXG4gICAgICAgICAgICBjb25zdCByZWN0ID0ge1xuICAgICAgICAgICAgICAgIHdpZHRoOiB0aGlzLnBsYW5EaXZDb250ZW50Lm9mZnNldFdpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy5wbGFuRGl2Q29udGVudC5vZmZzZXRIZWlnaHQsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgeyBjb2VmZlgsIGNvZWZmWSB9ID0gZ2V0Q29lZmZpY2llbnRzRm9ySW1hZ2UodGhpcy5pbWdQbGFuLCByZWN0KTtcbiAgICAgICAgICAgIHRoaXMuY29lZmZQbGFuWCA9IGNvZWZmWDtcbiAgICAgICAgICAgIHRoaXMuY29lZmZQbGFuWSA9IGNvZWZmWTtcblxuICAgICAgICAgICAgdGhpcy5wbGFuRGl2Q29udGVudC5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UgPSBgdXJsKCR7Y3VycmVudFBsYW4uZmlsZXBhdGh9KWA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmRyYXdQZGYoY3VycmVudFBsYW4pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGxhbkRpdkNvbnRlbnQuc3R5bGUuYmFja2dyb3VuZFNpemUgPSAnY29udGFpbic7XG4gICAgICAgIHRoaXMucGxhbkRpdkNvbnRlbnQuc3R5bGUuYmFja2dyb3VuZFJlcGVhdCA9ICduby1yZXBlYXQnO1xuXG4gICAgICAgIHRoaXMucGFuem9vbSA9IHBhbnpvb20odGhpcy5wbGFuRGl2LCB7XG4gICAgICAgICAgICBib3VuZHM6IHRydWUsXG4gICAgICAgICAgICBib3VuZHNQYWRkaW5nOiAwLFxuICAgICAgICAgICAgbWF4Wm9vbTogNCxcbiAgICAgICAgICAgIHpvb21Eb3VibGVDbGlja1NwZWVkOiAxLCAvL2Rpc2FibGVzIGRvdWJsZSBjbGljayB6b29tXG4gICAgICAgICAgICAvL2luaXRpYWxab29tOiA0XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBhbnpvb20uem9vbUFicygwLCAwLCA0KTtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVJvdGF0aW9uKHRoaXMubGFzdFJvdGF0aW9uKTtcbiAgICAgICAgfSwgMjAwKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgY2xlYXJQbGFuSW1hZ2UoKSB7XG4gICAgICAgIGlmICh0aGlzLnBsYW5EaXZDb250ZW50KSB7XG4gICAgICAgICAgICB0aGlzLnBsYW5EaXZDb250ZW50LnN0eWxlLmJhY2tncm91bmRJbWFnZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBkcmF3UGRmKGN1cnJlbnRQbGFuOiBQbGFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykgYXMgSFRNTENhbnZhc0VsZW1lbnQ7XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKSBhcyBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XG4gICAgICAgICAgICBjb25zdCBwZGZqc1dvcmtlciA9IGF3YWl0IGltcG9ydCgncGRmanMtZGlzdC9idWlsZC9wZGYud29ya2VyLmVudHJ5Jyk7XG5cbiAgICAgICAgICAgIEdsb2JhbFdvcmtlck9wdGlvbnMud29ya2VyU3JjID0gcGRmanNXb3JrZXI7XG4gICAgICAgICAgICBjb25zdCBwZGYgPSBhd2FpdCBnZXREb2N1bWVudChjdXJyZW50UGxhbi5maWxlcGF0aCkucHJvbWlzZTtcbiAgICAgICAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBwZGYuZ2V0UGFnZSgxKTtcblxuICAgICAgICAgICAgY29uc3Qgdmlld1BvcnRQYXJhbWV0ZXJzID0geyBzY2FsZTogMS41IH07XG4gICAgICAgICAgICBjb25zdCB2aWV3cG9ydCA9IHBhZ2UuZ2V0Vmlld3BvcnQodmlld1BvcnRQYXJhbWV0ZXJzKTtcblxuICAgICAgICAgICAgY2FudmFzLmhlaWdodCA9IHZpZXdwb3J0LmhlaWdodDtcbiAgICAgICAgICAgIGNhbnZhcy53aWR0aCA9IHZpZXdwb3J0LndpZHRoO1xuICAgICAgICAgICAgY29uc3QgcmVuZGVyQ29udGV4dCA9IHtcbiAgICAgICAgICAgICAgICBjYW52YXNDb250ZXh0OiBjb250ZXh0LFxuICAgICAgICAgICAgICAgIHZpZXdwb3J0LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlclRhc2sgPSBwYWdlLnJlbmRlcihyZW5kZXJDb250ZXh0KS5wcm9taXNlO1xuICAgICAgICAgICAgcmVuZGVyVGFzay50aGVuKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbWdVcmwgPSBjYW52YXMudG9EYXRhVVJMKCdpbWFnZS9wbmcnKTtcbiAgICAgICAgICAgICAgICB0aGlzLmltZ1BsYW4gPSBhd2FpdCBnZXRNZXRhRm9ySW1hZ2UoaW1nVXJsKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZWN0ID0ge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy5wbGFuRGl2Q29udGVudC5vZmZzZXRXaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnBsYW5EaXZDb250ZW50Lm9mZnNldEhlaWdodCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgY29lZmZYLCBjb2VmZlkgfSA9IGdldENvZWZmaWNpZW50c0ZvckltYWdlKHRoaXMuaW1nUGxhbiwgcmVjdCk7XG4gICAgICAgICAgICAgICAgdGhpcy5jb2VmZlBsYW5YID0gY29lZmZYO1xuICAgICAgICAgICAgICAgIHRoaXMuY29lZmZQbGFuWSA9IGNvZWZmWTtcbiAgICAgICAgICAgICAgICB0aGlzLnBsYW5EaXYuc3R5bGUuYmFja2dyb3VuZEltYWdlID0gYHVybCgke2ltZ1VybH0pYDtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYXN5bmMgZHJhd0VsZW1lbnQoXG4gICAgICAgIGVsZW1lbnQ6IGFueSxcbiAgICAgICAgdGFnVHlwZTogUG9pVHlwZSxcbiAgICAgICAgY3VycmVudFBsYW46IFBsYW4sXG4gICAgICAgIHRhZ1NlcnZpY2U6IEJhc2VUYWdTZXJ2aWNlLFxuICAgICAgICBjb25maWc6IENvbmZpZyxcbiAgICAgICAgc2l6ZUJ1dHRvbjogbnVtYmVyID0gMTBcbiAgICApIHtcbiAgICAgICAgY29uc3QgW3BvaV0gPSBlbGVtZW50LnBvaXMuaXRlbXM7XG4gICAgICAgIGlmIChwb2kgJiYgcG9pLmNvb3JkaW5hdGUgJiYgY3VycmVudFBsYW4pIHtcbiAgICAgICAgICAgIGNvbnN0IHsgem9uZSB9ID0gY3VycmVudFBsYW47XG4gICAgICAgICAgICBpZiAoem9uZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gSlNPTi5wYXJzZShwb2kuY29vcmRpbmF0ZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnRUaXRsZTogc3RyaW5nO1xuICAgICAgICAgICAgICAgIGNvbnN0IHVybCA9IHRhZ1NlcnZpY2UuZ2V0VXJsRm9yU2VlRGV0YWlscyhlbGVtZW50LCB0YWdUeXBlKTtcbiAgICAgICAgICAgICAgICBsZXQgdGFnSWNvbkltYWdlOiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh0YWdUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgUG9pVHlwZS5USUNLRVQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhZ0ljb25JbWFnZSA9IGNvbmZpZy5teV9jb25maWcuaWNvbl90aWNrZXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFBvaVR5cGUuRVFVSVBNRU5UOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdJY29uSW1hZ2UgPSBjb25maWcubXlfY29uZmlnLmljb25fZXF1aXBtZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBQb2lUeXBlLk1FQVNVUkU6XG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdJY29uSW1hZ2UgPSBjb25maWcubXlfY29uZmlnLmljb25fbWVhc3VyZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFBvaVR5cGUuT0JKRUNUM0Q6XG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdJY29uSW1hZ2UgPSBjb25maWcubXlfY29uZmlnLmljb25fb2JqZWN0M2Q7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBQb2lUeXBlLkRBVEE6XG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdJY29uSW1hZ2UgPSBjb25maWcubXlfY29uZmlnLmljb25fZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFBvaVR5cGUuREVTSzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhZ0ljb25JbWFnZSA9IGNvbmZpZy5teV9jb25maWcuaWNvbl9kYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChwb2kudGFnSWNvbikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0YWdJY29uID0gSlNPTi5wYXJzZShwb2kudGFnSWNvbik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhZ1R5cGUgPT09IFBvaVR5cGUuREFUQSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC50eXBlID09PSBGZWF0dXJlVHlwZS5JTkRJQ0FUT1JfVEVNUFxuICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhZ0ljb24uc3JjID0gdGFnU2VydmljZS5nZXRJY29uVGFnSW1hZ2VGb3JGZWF0dXJlKGVsZW1lbnQsIHBvaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gcG9pLnRhZ0ljb24gPSB0YWdJY29uO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0YWdJY29uLnNyYykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc291cmNlID0gYXdhaXQgZ2V0U2lnbmVkRmlsZSh0YWdJY29uLnNyYyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc291cmNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnSWNvbkltYWdlID0gc291cmNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc3R5bGVCdXR0b24oYnV0dG9uLCB0YWdJY29uSW1hZ2UsIHNpemVCdXR0b24pO1xuICAgICAgICAgICAgICAgIGJ1dHRvbi5pZCA9IGVsZW1lbnQuaWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5wbGFuRGl2Q29udGVudC5hcHBlbmQoYnV0dG9uKTtcbiAgICAgICAgICAgICAgICBsZXQgeDogbnVtYmVyO1xuICAgICAgICAgICAgICAgIGxldCB5OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY2FsaWJyYXRpb25QbGFuLm5ldykge1xuICAgICAgICAgICAgICAgICAgICAvLyBhbGVydChcIm5ldyBjYWxpYnJhdGlvbiBwbGFuOiBwb3NpdGlvbmluZyBub3QgcmVhZHkgeWV0XCIpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbjJEID1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJhbnNmb3JtUG9zaXRpb24zREZvck5ld0NhbGlicmF0aW9uKHBvc2l0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgeCA9IHBvc2l0aW9uMkQueDtcbiAgICAgICAgICAgICAgICAgICAgeSA9IHBvc2l0aW9uMkQueTtcbiAgICAgICAgICAgICAgICAgICAgYnV0dG9uLnN0eWxlLnRvcCA9IGAke3kgLyBwb3NpdGlvbjJELmNvZWZmWSAtIDV9cHhgO1xuICAgICAgICAgICAgICAgICAgICBidXR0b24uc3R5bGUubGVmdCA9IGAke3ggLyBwb3NpdGlvbjJELmNvZWZmWCAtIDV9cHhgO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRvIHJlbW92ZSB3aGVuIGFsbCBjYWxpYnJhdGlvbnMgYXJlIG5ld1xuICAgICAgICAgICAgICAgICAgICB4ID1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2FsaWJyYXRpb25QbGFuLm9mZnNldFggKyBwb3NpdGlvbi54ICogdGhpcy5jYWxpYnJhdGlvblBsYW4ueDtcbiAgICAgICAgICAgICAgICAgICAgeSA9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbGlicmF0aW9uUGxhbi5vZmZzZXRZICsgcG9zaXRpb24ueiAqIHRoaXMuY2FsaWJyYXRpb25QbGFuLnk7XG4gICAgICAgICAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS50b3AgPSBgJHt5IC8gdGhpcy5jb2VmZlBsYW5ZIC0gNX1weGA7XG4gICAgICAgICAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS5sZWZ0ID0gYCR7eCAvIHRoaXMuY29lZmZQbGFuWCAtIDV9cHhgO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IGh0bWwgPSBhd2FpdCB0YWdTZXJ2aWNlLmdldEh0bWxUb0luamVjdCh0YWdUeXBlLCBlbGVtZW50KTtcbiAgICAgICAgICAgICAgICBpZiAoaHRtbCAhPSAnJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmh0bWxDb250ZW50VG9JbmplY3QucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50SUQ6IGVsZW1lbnQuaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogJycsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBodG1sLFxuICAgICAgICAgICAgICAgICAgICAgICAgeSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHgsXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdJY29uOiB0YWdJY29uSW1hZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgICB1cmwsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHdoZW4gd2UgZG9uJ3QgaGF2ZSBodG1sID0+IGNhc2Ugb2YgRU1CRUQgQ29tbWVudCB0eXBlXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbW1lbnRFbWJlZCA9IGVsZW1lbnQuY29tbWVudHM/Lml0ZW1zLmZpbmQoXG4gICAgICAgICAgICAgICAgICAgICAgICAoY29tKSA9PiBjb20udHlwZSA9PT0gQ29tbWVudFR5cGUuRU1CRUQgJiYgY29tLnNob3duSW5UYWdcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbW1lbnRFbWJlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5odG1sQ29udGVudFRvSW5qZWN0LnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRJRDogZWxlbWVudC5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogZWxlbWVudC50aXRsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBgPGlmcmFtZSBzcmM9JHtjb21tZW50RW1iZWQuZXh0ZXJuYWxMaW5rfSBoZWlnaHQ9XCIyMDBweFwiIHdpZHRoPVwiMTAwJVwiPjwvaWZyYW1lPmAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZ0ljb246IHRhZ0ljb25JbWFnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmwsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuYWRkTGlzdGVuZXJzVG9CdXR0b24oYnV0dG9uLCB1cmwsIHRhZ1NlcnZpY2UsIGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlUm90YXRpb24odGhpcy5sYXN0Um90YXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgZHJhd1VzZXJQb3NpdGlvbihjdXJyZW50U3dlZXAgPSB0aGlzLmN1cnJlbnRTd2VlcCwgc2l6ZUJ1dHRvbjogbnVtYmVyID0gMTApIHtcbiAgICAgICAgdGhpcy5jdXJyZW50U3dlZXAgPSBjdXJyZW50U3dlZXA7XG4gICAgICAgIGlmICh0aGlzLmNhbGlicmF0aW9uUGxhbiAmJiBjdXJyZW50U3dlZXApIHtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID1cbiAgICAgICAgICAgICAgICB0aGlzLm1hdHRlcnBvcnRTZXJ2aWNlLmdldEN1cnJlbnRDYW1lcmFQb3NpdGlvbigpPy5wb3NpdGlvbjtcbiAgICAgICAgICAgIGlmIChwb3NpdGlvbikge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy51c2VyUG9zaXRpb25CdG4pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51c2VyUG9zaXRpb25CdG4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51c2VyUG9zaXRpb25CdG4uaWQgPSAnY3VycmVudFBvc2l0aW9uJztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFuRGl2Q29udGVudC5hcHBlbmQodGhpcy51c2VyUG9zaXRpb25CdG4pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVzZXJQb3NpdGlvbkJ0bi50aXRsZSA9ICdZb3UgYXJlIGhlcmUnO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0eWxlQnV0dG9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51c2VyUG9zaXRpb25CdG4sXG4gICAgICAgICAgICAgICAgICAgICAgICAnaHR0cHM6Ly9hcGkuaWNvbmlmeS5kZXNpZ24vYng6YnhzLXVzZXItY2lyY2xlLnN2Zz9jb2xvcj1ncmVlbiZoZWlnaHQ9MTcmd2lkdGg9MTcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZUJ1dHRvblxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgeDogbnVtYmVyO1xuICAgICAgICAgICAgICAgIGxldCB5OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY2FsaWJyYXRpb25QbGFuLm5ldykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbjJEID1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJhbnNmb3JtUG9zaXRpb24zREZvck5ld0NhbGlicmF0aW9uKHBvc2l0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgeCA9IHBvc2l0aW9uMkQueCAvIHBvc2l0aW9uMkQuY29lZmZYIC0gNTtcbiAgICAgICAgICAgICAgICAgICAgeSA9IHBvc2l0aW9uMkQueSAvIHBvc2l0aW9uMkQuY29lZmZZIC0gNTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB4ID1cbiAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzLmNhbGlicmF0aW9uUGxhbi5vZmZzZXRYICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbi54ICogdGhpcy5jYWxpYnJhdGlvblBsYW4ueCkgL1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb2VmZlBsYW5YO1xuICAgICAgICAgICAgICAgICAgICB5ID1cbiAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzLmNhbGlicmF0aW9uUGxhbi5vZmZzZXRZICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbi56ICogdGhpcy5jYWxpYnJhdGlvblBsYW4ueSkgL1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb2VmZlBsYW5ZO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnVzZXJQb3NpdGlvbkJ0bi5zdHlsZS50b3AgPSBgJHt5fXB4YDtcbiAgICAgICAgICAgICAgICB0aGlzLnVzZXJQb3NpdGlvbkJ0bi5zdHlsZS5sZWZ0ID0gYCR7eH1weGA7XG4gICAgICAgICAgICAgICAgdGhpcy5tb3ZlT25Qb2ludCh7IHg6IHggKyA1LCB5OiB5ICsgNSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENlbnRlciB0aGUgdmlldyBvZiB0aGUgcGxhbiBvbiBjb29yZGluYXRlc1xuICAgICAqIEBwYXJhbSBjb29yZGluYXRlIENvb3JkaW5hdGUgb24gdGhlIHBsYW5cbiAgICAgKi9cbiAgICBtb3ZlT25Qb2ludChjb29yZGluYXRlKSB7XG4gICAgICAgIGlmICh0aGlzLnBsYW5EaXYpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjYWxlID0gdGhpcy5wYW56b29tLmdldFRyYW5zZm9ybSgpLnNjYWxlO1xuICAgICAgICAgICAgY29uc3QgbW92ZVggPSB0aGlzLnBsYW5EaXYuY2xpZW50V2lkdGggLyAyIC0gY29vcmRpbmF0ZS54ICogc2NhbGU7XG4gICAgICAgICAgICBjb25zdCBtb3ZlWSA9IHRoaXMucGxhbkRpdi5jbGllbnRIZWlnaHQgLyAyIC0gY29vcmRpbmF0ZS55ICogc2NhbGU7XG4gICAgICAgICAgICB0aGlzLnBhbnpvb20ubW92ZVRvKG1vdmVYLCBtb3ZlWSk7XG4gICAgICAgICAgICB0aGlzLnBsYW5EaXZDb250ZW50LnN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IGAke2Nvb3JkaW5hdGUueH1weCAke2Nvb3JkaW5hdGUueX1weGA7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBseSBhIHJvdGF0aW9uIHRvIHRoZSBwbGFuXG4gICAgICogQnV0dG9ucyB3aWxsIHJlbWFpbiBpbiB0aGUgY29ycmVjdCByb3RhdGlvblxuICAgICAqIEBwYXJhbSByb3RhdGlvblxuICAgICAqL1xuICAgIHVwZGF0ZVJvdGF0aW9uKHJvdGF0aW9uKSB7XG4gICAgICAgIHRoaXMubGFzdFJvdGF0aW9uID0gcm90YXRpb247XG4gICAgICAgIGlmICh0aGlzLnBsYW5EaXZDb250ZW50KSB7XG4gICAgICAgICAgICB0aGlzLnBsYW5EaXZDb250ZW50LnN0eWxlLnRyYW5zZm9ybSA9IGByb3RhdGUoJHtyb3RhdGlvbn1kZWcpYDtcbiAgICAgICAgICAgIGNvbnN0IGJ1dHRvbnMgPSB0aGlzLnBsYW5EaXZDb250ZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2J1dHRvbicpO1xuICAgICAgICAgICAgbGV0IHJvdGF0aW9uUmVnZXggPSAvKHJvdGF0ZVxcKC0/XFxkKlxcLj9cXGQrZGVnXFwpKS9nO1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHVuaWNvcm4vbm8tYXJyYXktZm9yLWVhY2hcbiAgICAgICAgICAgIGJ1dHRvbnMuZm9yRWFjaCgoYnV0dG9uKSA9PiB7XG4gICAgICAgICAgICAgICAgYnV0dG9uLnN0eWxlLnRyYW5zZm9ybSA9IGJ1dHRvbi5zdHlsZS50cmFuc2Zvcm0ucmVwbGFjZShyb3RhdGlvblJlZ2V4LCBcIlwiKSArIGAgcm90YXRlKCR7LXJvdGF0aW9ufWRlZylgO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZW1vdmVDdXJyZW50UG9zaXRpb24oKSB7XG4gICAgICAgIGNvbnN0IGJ1dHRvbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNjdXJyZW50UG9zaXRpb24nKTtcbiAgICAgICAgaWYgKGJ1dHRvbikge1xuICAgICAgICAgICAgYnV0dG9uLnJlbW92ZSgpO1xuICAgICAgICAgICAgdGhpcy51c2VyUG9zaXRpb25CdG4gPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3R5bGVCdXR0b24oYnV0dG9uOiBIVE1MQnV0dG9uRWxlbWVudCwgdXJsOiBzdHJpbmcsIHNpemVCdXR0b246IG51bWJlciA9IDEwKSB7XG4gICAgICAgIGJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UgPSBgdXJsKCR7dXJsfSlgO1xuICAgICAgICBidXR0b24uc3R5bGUuYmFja2dyb3VuZENvbG9yID0gJ3RyYW5zcGFyZW50JztcbiAgICAgICAgYnV0dG9uLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgICAgYnV0dG9uLnN0eWxlLmJvcmRlciA9ICdub25lJztcbiAgICAgICAgYnV0dG9uLnN0eWxlLndpZHRoID0gYDEwcHhgO1xuICAgICAgICBidXR0b24uc3R5bGUuaGVpZ2h0ID0gYDEwcHhgO1xuICAgICAgICBidXR0b24uZGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgYnV0dG9uLnN0eWxlLmJhY2tncm91bmRTaXplID0gJ2NvbnRhaW4nO1xuICAgICAgICBidXR0b24uc3R5bGUuYmFja2dyb3VuZFJlcGVhdCA9ICduby1yZXBlYXQnO1xuICAgICAgICBidXR0b24uc3R5bGUudHJhbnNmb3JtID0gYHNjYWxlKCR7c2l6ZUJ1dHRvbi8xMH0pYFxuICB9XG5cbiAgICBhZGRMaXN0ZW5lcnNUb0J1dHRvbihcbiAgICAgICAgYnV0dG9uOiBIVE1MQnV0dG9uRWxlbWVudCxcbiAgICAgICAgdXJsOiBzdHJpbmcsXG4gICAgICAgIHRhZ1NlcnZpY2U6IEJhc2VUYWdTZXJ2aWNlID0gbnVsbCxcbiAgICAgICAgZWxlbWVudDogYW55ID0gbnVsbFxuICAgICkge1xuICAgICAgICBsZXQgdmlkZW9Kc1BsYXllcjtcbiAgICAgICAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCBhc3luYyAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRGb3JCdXR0b24gPSB0aGlzLmh0bWxDb250ZW50VG9JbmplY3QuZmluZChcbiAgICAgICAgICAgICAgICAob2JqZWN0KSA9PiBvYmplY3QuZWxlbWVudElEID09PSBidXR0b24uaWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLmJ0blRhZ0lzSG92ZXIgPSB0cnVlO1xuICAgICAgICAgICAgY29uc3QgdGl0bGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAjdGl0bGVUYWdEaXZgKSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgICAgIGlmIChjb250ZW50Rm9yQnV0dG9uLnRpdGxlKSB7XG4gICAgICAgICAgICAgICAgdGl0bGUuc3R5bGUuZGlzcGxheSA9ICdpbmxpbmUnO1xuICAgICAgICAgICAgICAgIHRpdGxlLmlubmVySFRNTCA9IGNvbnRlbnRGb3JCdXR0b24udGl0bGU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRpdGxlLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAjaHRtbFRhZ0RpdmApIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICAgICAgdGhpcy5kZXRhaWxUYWdEaXYuc3R5bGUudG9wID0gYCR7ZXZlbnQuY2xpZW50WSArIDEwfXB4YDtcbiAgICAgICAgICAgIHRoaXMuZGV0YWlsVGFnRGl2LnN0eWxlLmxlZnQgPSBgJHtldmVudC5jbGllbnRYIDwgMTIwID8gMCA6IGV2ZW50LmNsaWVudFggLSAxMjBcbiAgICAgICAgICAgICAgICB9cHhgO1xuICAgICAgICAgICAgdGhpcy5kZXRhaWxUYWdEaXYuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhjb250ZW50Rm9yQnV0dG9uLmNvbnRlbnQpO1xuICAgICAgICAgICAgY29udGVudC5pbm5lckhUTUwgPSBjb250ZW50Rm9yQnV0dG9uLmNvbnRlbnQ7XG4gICAgICAgICAgICBjb25zdCBkZXRhaWxCdXR0b24gPSBjb250ZW50LnF1ZXJ5U2VsZWN0b3IoJyNkZXRhaWxCdG4nKTtcbiAgICAgICAgICAgIGlmIChkZXRhaWxCdXR0b24pIHtcbiAgICAgICAgICAgICAgICBkZXRhaWxCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlzaWJpbGl0eVNlcnZpY2UuZGV0YWlsU2hvd2luZy5uZXh0KHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbdXJsXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGhhbmRsZSBpbWFnZSBjYXJvdXNlbCBmdWxsc2NyZWVuIGJ1dHRvblxuICAgICAgICAgICAgY29uc3QgaW1hZ2VGdWxsc2NyZWVuQnRuID0gY29udGVudC5xdWVyeVNlbGVjdG9yKCcjaW1hZ2UtZm9vdGVyJyk7XG4gICAgICAgICAgICBpZiAoaW1hZ2VGdWxsc2NyZWVuQnRuKSB7XG4gICAgICAgICAgICAgICAgaW1hZ2VGdWxsc2NyZWVuQnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGFnU2VydmljZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGFnU2VydmljZS5vbkFjdGlvbkltYWdlQ2xpY2soY29udGVudEZvckJ1dHRvbi5lbGVtZW50SUQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGhhbmRsZSBib29raW5nIGZ1bGxzY3JlZW4gYnV0dG9uXG4gICAgICAgICAgICBjb25zdCBib29raW5nQnV0dG9uID0gY29udGVudC5xdWVyeVNlbGVjdG9yKCcjYm9va2luZ0J0bicpO1xuICAgICAgICAgICAgaWYgKGJvb2tpbmdCdXR0b24pIHtcbiAgICAgICAgICAgICAgICBib29raW5nQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnZpc2liaWxpdHlTZXJ2aWNlLmRldGFpbFNob3dpbmcubmV4dCh0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW3VybF0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBoYW5kbGUgZG9jdW1lbnQgcGRmIGZ1bGxzY3JlZW4gYnV0dG9uXG4gICAgICAgICAgICBjb25zdCBkb2NGdWxsc2NyZWVuQnRuID0gY29udGVudC5xdWVyeVNlbGVjdG9yKCcjZG9jLWZvb3RlcicpO1xuICAgICAgICAgICAgaWYgKGRvY0Z1bGxzY3JlZW5CdG4gJiYgZWxlbWVudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRvY3VtZW50VXJsID0gdGFnU2VydmljZS5nZXRBbm5leGVGb3JDb21tZW50VHlwZUluRmVhdHVyZShcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgQ29tbWVudFR5cGUuRE9DVU1FTlRcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGRvY0Z1bGxzY3JlZW5CdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0YWdTZXJ2aWNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdTZXJ2aWNlLm9uQWN0aW9uRG9jQ2xpY2soZG9jdW1lbnRVcmwpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGhhbmRsZSB2aWRlbyBmdWxsc2NyZWVuIGJ1dHRvblxuICAgICAgICAgICAgY29uc3QgdmlkZW9GdWxsc2NyZWVuQnRuID0gY29udGVudC5xdWVyeVNlbGVjdG9yKCcjYnRuLXZpZGVvLWZ1bGxzY3JlZW4nKTtcbiAgICAgICAgICAgIGlmICh2aWRlb0Z1bGxzY3JlZW5CdG4gJiYgZWxlbWVudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZpZGVvVXJsID0gdGFnU2VydmljZS5nZXRBbm5leGVGb3JDb21tZW50VHlwZUluRmVhdHVyZShcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgQ29tbWVudFR5cGUuVklERU9cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHZpZGVvRnVsbHNjcmVlbkJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRhZ1NlcnZpY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhZ1NlcnZpY2Uub25BY3Rpb25WaWRlb0NsaWNrKHZpZGVvVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBoYW5kbGUgWW91dHViZSB2aWRlbyBmdWxsc2NyZWVuIGJ1dHRvblxuICAgICAgICAgICAgY29uc3QgeW91dHViZUZ1bGxTY3JlZW4gPSBjb250ZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgICAgICAgJyNidG4tdmlkZW8tZnVsbHNjcmVlbi15b3V0dWJlJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmICh5b3V0dWJlRnVsbFNjcmVlbiAmJiBlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeW91dHViZVVybCA9IHRhZ1NlcnZpY2UuZ2V0QW5uZXhlRm9yQ29tbWVudFR5cGVJbkZlYXR1cmUoXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIENvbW1lbnRUeXBlLllPVVRVQkVcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHlvdXR1YmVGdWxsU2NyZWVuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGFnU2VydmljZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGFnU2VydmljZS5vbkFjdGlvbllvdXR1YmVDbGljayh5b3V0dWJlVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBoYW5kbGUgbXV0ZSB2aWRlbyBidXR0b25cbiAgICAgICAgICAgIGNvbnN0IGJ0bk11dGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYnRuLW11dGUnKTtcbiAgICAgICAgICAgIGNvbnN0IGltZ09uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NvdW5kLW9uJyk7XG4gICAgICAgICAgICBjb25zdCBpbWdPZmYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc291bmQtb2ZmJyk7XG4gICAgICAgICAgICBjb25zdCBwbGF5ZXJFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtdXMtdmlkZW8tdGFnXCIpO1xuXG4gICAgICAgICAgICBpZiAocGxheWVyRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHZpZGVvSnNQbGF5ZXIgPSB2aWRlb2pzKFwibXVzLXZpZGVvLXRhZ1wiKTtcbiAgICAgICAgICAgICAgICBpZiAoYnRuTXV0ZSAmJiB2aWRlb0pzUGxheWVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGJ0bk11dGUuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmlkZW9Kc1BsYXllci5tdXRlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW9Kc1BsYXllci5tdXRlZChmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGltZ09uICYmIGltZ09mZikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWdPbi5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltZ09mZi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW9Kc1BsYXllci5tdXRlZCh0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW1nT24gJiYgaW1nT2ZmKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltZ09uLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltZ09mZi5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgLy8gaGFuZGxlIGF1ZGlvIHBsYXllciBidXR0b25zXG4gICAgICAgICAgICBjb25zdCBwbGF5ZXJCdXR0b24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYXVkaW8tcGxheS1idXR0b24nKTtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2F1ZGlvLXRhZycpIGFzIEhUTUxNZWRpYUVsZW1lbnQ7XG4gICAgICAgICAgICBjb25zdCB0aW1lbGluZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgICAgICAgJy50aW1lbGluZS10YWcnXG4gICAgICAgICAgICApIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgICAgICAgICAvLyBjb25zdCB0aW1lbGluZVZhbHVlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRpbWVsaW5lLXRhZycpLnZhbHVlO1xuICAgICAgICAgICAgY29uc3Qgc291bmRCdXR0b24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYXVkaW8tc291bmQtYnRuJyk7XG4gICAgICAgICAgICBjb25zdCBwbGF5QXVkaW8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGxheScpO1xuICAgICAgICAgICAgY29uc3QgcGF1c2VBdWRpbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYXVzZScpO1xuICAgICAgICAgICAgY29uc3QgaW1nU291bmRPbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdWRpby1zb3VuZC1vbicpO1xuICAgICAgICAgICAgY29uc3QgaW1nU291bmRPZmYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXVkaW8tc291bmQtb2ZmJyk7XG4gICAgICAgICAgICBjb25zdCBhdWRpb01vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2J0bi1hdWRpby1tb2RhbCcpO1xuICAgICAgICAgICAgaWYgKGF1ZGlvICYmIHBsYXllckJ1dHRvbiAmJiB0aW1lbGluZSkge1xuICAgICAgICAgICAgICAgIHBsYXllckJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1ZGlvLnBhdXNlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW8ucGxheSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF1c2VBdWRpby5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XG4gICAgICAgICAgICAgICAgICAgICAgICBwbGF5QXVkaW8uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvLnBhdXNlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXVzZUF1ZGlvLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgICAgICAgICAgICAgICBwbGF5QXVkaW8uc3R5bGUuZGlzcGxheSA9ICdpbmxpbmUtYmxvY2snO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgc291bmRCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhdWRpby5tdXRlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW8ubXV0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGltZ1NvdW5kT24uc3R5bGUuZGlzcGxheSA9ICdpbmxpbmUtYmxvY2snO1xuICAgICAgICAgICAgICAgICAgICAgICAgaW1nU291bmRPZmYuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGltZ1NvdW5kT24uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgIGltZ1NvdW5kT2ZmLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGNoYW5nZVRpbWVsaW5lUG9zaXRpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhdWRpby5kdXJhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGVyY2VudGFnZVBvc2l0aW9uID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMTAwICogYXVkaW8uY3VycmVudFRpbWUpIC8gYXVkaW8uZHVyYXRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwZXJjZW50YWdlUG9zaXRpb25TdHJpbmcgPSBwZXJjZW50YWdlUG9zaXRpb24gKyAnJSc7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aW1lbGluZS5zdHlsZS5iYWNrZ3JvdW5kU2l6ZSA9IHBlcmNlbnRhZ2VQb3NpdGlvblN0cmluZyArICcgMTAwJSc7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aW1lbGluZS52YWx1ZSA9IHBlcmNlbnRhZ2VQb3NpdGlvbi50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1ZGlvLm9udGltZXVwZGF0ZSA9IGNoYW5nZVRpbWVsaW5lUG9zaXRpb247XG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gY2hhbmdlU2VlaygpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGltZSA9IChwYXJzZUludCh0aW1lbGluZS52YWx1ZSkgKiBhdWRpby5kdXJhdGlvbikgLyAxMDA7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvLmN1cnJlbnRUaW1lID0gdGltZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGltZWxpbmUuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgY2hhbmdlU2Vlayk7XG4gICAgICAgICAgICAgICAgdGltZWxpbmUuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCBjaGFuZ2VTZWVrKTtcbiAgICAgICAgICAgICAgICAvLyBoYW5kbGUgYXVkaW8gY2xpY2tcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9Nb2RhbCAmJiBlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGF1ZGlvQ29tbWVudCA9IGVsZW1lbnQuY29tbWVudHM/Lml0ZW1zLmZpbmQoXG4gICAgICAgICAgICAgICAgICAgICAgICAoY29tKSA9PiBjb20udHlwZSA9PT0gQ29tbWVudFR5cGUuQVVESU8gJiYgY29tLnNob3duSW5UYWdcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYXVkaW9Db21tZW50SUQgPSBhdWRpb0NvbW1lbnQgPyBhdWRpb0NvbW1lbnQuaWQgOiAnJztcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9Nb2RhbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YWdTZXJ2aWNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnU2VydmljZS5vbkFjdGlvbkF1ZGlvQ2xpY2soYXVkaW9Db21tZW50SUQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgLy8gd2Ugd2FpdCBpZiB1c2VyIGhvdmVycyBvbiB0byBkaXYgb2YgdGhlIHRhZyAoY2hhbmdlcyB0aGlzLmZvY3VzTW91c2VUYWdEaXYpXG4gICAgICAgICAgICB0aGlzLmJ0blRhZ0lzSG92ZXIgPSBmYWxzZTtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5mb2N1c01vdXNlVGFnRGl2ICYmICF0aGlzLmJ0blRhZ0lzSG92ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXRhaWxUYWdEaXYuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZpZGVvSnNQbGF5ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvSnNQbGF5ZXIuZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZGV0YWlsVGFnRGl2LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgICBpZiAodmlkZW9Kc1BsYXllcikge1xuICAgICAgICAgICAgICAgIHZpZGVvSnNQbGF5ZXIuZGlzcG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgdGhpcy52aWV3ZXJTZXJ2aWNlLmFjdGlvbl9tb3ZlX3RvX3RhZyhidXR0b24uaWQpO1xuICAgICAgICAgICAgdGhpcy52aXNpYmlsaXR5U2VydmljZS5kZXRhaWxTaG93aW5nLm5leHQodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbdXJsXSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGNsZWFyQnRuKGlkTGlzdDogYW55W10pIHtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBpZExpc3QpIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1dHRvbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcbiAgICAgICAgICAgIGlmIChidXR0b24pIHtcbiAgICAgICAgICAgICAgICBidXR0b24ucmVtb3ZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjbGVhckFsbEJ1dHRvbnMoKSB7XG4gICAgICAgIGlmICh0aGlzLnBsYW5EaXZDb250ZW50KSB7XG4gICAgICAgICAgICBjb25zdCBidXR0b25zID0gdGhpcy5wbGFuRGl2Q29udGVudC5xdWVyeVNlbGVjdG9yQWxsKCdidXR0b24nKTtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB1bmljb3JuL25vLWFycmF5LWZvci1lYWNoXG4gICAgICAgICAgICBidXR0b25zLmZvckVhY2goZnVuY3Rpb24gKGN1cnJlbnRWYWx1ZSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRWYWx1ZS5yZW1vdmUoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy51c2VyUG9zaXRpb25CdG4gPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlQWxsQnV0dG9uc1N0eWxlKHByb3BlcnRpZXM6IEFycmF5PHN0cmluZz4sIHZhbHVlczogQXJyYXk8c3RyaW5nPikge1xuICAgICAgICBpZiAodGhpcy5wbGFuRGl2Q29udGVudCkge1xuICAgICAgICAgICAgY29uc3QgYnV0dG9ucyA9IHRoaXMucGxhbkRpdkNvbnRlbnQucXVlcnlTZWxlY3RvckFsbCgnYnV0dG9uJyk7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgdW5pY29ybi9uby1hcnJheS1mb3ItZWFjaFxuICAgICAgICAgICAgYnV0dG9ucy5mb3JFYWNoKGZ1bmN0aW9uIChjdXJyZW50VmFsdWUpIHtcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzLmZvckVhY2goKHByb3BlcnR5LCBpKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0eSA9PT0gXCJ0cmFuc2Zvcm1cIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy9Gb3Igc2F2aW5nIHRoZSByb3RhdGlvbiBhbmQgYWRkaW5nIHNjYWxlXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcm90YXRpb25SZWdleCA9IC8ocm90YXRlXFwoLT9cXGQqXFwuP1xcZCtkZWdcXCkpL2c7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcm90YXRpb25NYXRjaCA9IGN1cnJlbnRWYWx1ZS5zdHlsZVtwcm9wZXJ0eV0ubWF0Y2gocm90YXRpb25SZWdleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocm90YXRpb25NYXRjaC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudFZhbHVlLnN0eWxlW3Byb3BlcnR5XSA9IGAke3ZhbHVlc1tpXX0gJHtyb3RhdGlvbk1hdGNoWzBdfWA7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50VmFsdWUuc3R5bGVbcHJvcGVydHldID0gdmFsdWVzW2ldO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25QbGFuUmVtb3ZlKCkge1xuICAgICAgICB0aGlzLnVzZXJQb3NpdGlvbkJ0biA9IG51bGw7XG4gICAgICAgIHRoaXMuY2FsaWJyYXRpb25QbGFuID0gbnVsbDtcbiAgICAgICAgdGhpcy5jdXJyZW50U3dlZXAgPSBudWxsO1xuICAgICAgICB0aGlzLmRldGFpbFRhZ0RpdiA9IG51bGw7XG4gICAgfVxuXG4gICAgYXN5bmMgcmVzaXplUGxhbihpc1JlbW92aW5nOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMucmVzaXplUGxhblN1YnNjcmlwdGlvbi5uZXh0KGZhbHNlKTtcbiAgICAgICAgaWYgKGlzUmVtb3ZpbmcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZygnaW4gcmVzaXplUGxhbicpO1xuICAgICAgICBpZiAodGhpcy5wbGFuRGl2ICYmIHRoaXMuY3VycmVudFN3ZWVwKSB7XG4gICAgICAgICAgICB0aGlzLnBhbnpvb20gPSBwYW56b29tKHRoaXMucGxhbkRpdiwge1xuICAgICAgICAgICAgICAgIGJvdW5kczogdHJ1ZSxcbiAgICAgICAgICAgICAgICBib3VuZHNQYWRkaW5nOiAwLFxuICAgICAgICAgICAgICAgIG1heFpvb206IDQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlY3QgPSB7XG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiB0aGlzLnBsYW5EaXZDb250ZW50Lm9mZnNldFdpZHRoLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMucGxhbkRpdkNvbnRlbnQub2Zmc2V0SGVpZ2h0LFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgY29uc3QgeyBjb2VmZlgsIGNvZWZmWSB9ID0gZ2V0Q29lZmZpY2llbnRzRm9ySW1hZ2UodGhpcy5pbWdQbGFuLCByZWN0KTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvZWZmUGxhblggPSBjb2VmZlg7XG4gICAgICAgICAgICAgICAgdGhpcy5jb2VmZlBsYW5ZID0gY29lZmZZO1xuICAgICAgICAgICAgICAgIHRoaXMucGFuem9vbS56b29tQWJzKDAsIDAsIDQpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplUGxhblN1YnNjcmlwdGlvbi5uZXh0KHRydWUpO1xuICAgICAgICAgICAgfSwgMjAwKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGhhbmRsZVRvdWNoKGV2ZW50KSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgIGlmIChub3cgLSB0aGlzLmxhc3RUb3VjaFRpbWUgPCB0aGlzLmRlbGF5RGJsVG91Y2gpIHtcbiAgICAgICAgICAgIHRoaXMubGFzdFRvdWNoVGltZSA9IDA7XG4gICAgICAgICAgICAvLyB0aGlzLm9uRGJsQ2xpY2tQbGFuKGV2ZW50KTtcbiAgICAgICAgICAgIC8qKiBTaW11bGF0ZSBhIGRibGNsaWNrIGZvciBwaG9uZSAod2UgZG9uJ3QgZ2V0IG9mZnNldFgvWSBvbiB0b3VjaGV2ZW50KSAqL1xuICAgICAgICAgICAgY29uc3QgbmV3RXZlbnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnTW91c2VFdmVudHMnKTtcbiAgICAgICAgICAgIGNvbnN0IHRvdWNoID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07XG4gICAgICAgICAgICBuZXdFdmVudC5pbml0TW91c2VFdmVudChcbiAgICAgICAgICAgICAgICAnZGJsY2xpY2snLFxuICAgICAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgICAgICBldmVudC50YXJnZXQub3duZXJEb2N1bWVudC5kZWZhdWx0VmlldyxcbiAgICAgICAgICAgICAgICAwLFxuICAgICAgICAgICAgICAgIHRvdWNoLnNjcmVlblgsXG4gICAgICAgICAgICAgICAgdG91Y2guc2NyZWVuWSxcbiAgICAgICAgICAgICAgICB0b3VjaC5jbGllbnRYLFxuICAgICAgICAgICAgICAgIHRvdWNoLmNsaWVudFksXG4gICAgICAgICAgICAgICAgZXZlbnQuY3RybEtleSxcbiAgICAgICAgICAgICAgICBldmVudC5hbHRLZXksXG4gICAgICAgICAgICAgICAgZXZlbnQuc2hpcnRLZXksXG4gICAgICAgICAgICAgICAgZXZlbnQubWV0YUtleSxcbiAgICAgICAgICAgICAgICAwLFxuICAgICAgICAgICAgICAgIG51bGxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBldmVudC50YXJnZXQuZGlzcGF0Y2hFdmVudChuZXdFdmVudCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmxhc3RUb3VjaFRpbWUgPSBub3c7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBvbkRibENsaWNrUGxhbihldmVudCkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zdCBjbGlja1ggPSBldmVudC5vZmZzZXRYO1xuICAgICAgICBjb25zdCBjbGlja1kgPSBldmVudC5vZmZzZXRZO1xuICAgICAgICBjb25zdCB6b25lUGxhbiA9IHRoaXMuY3VycmVudFBsYW4uem9uZTtcbiAgICAgICAgaWYgKHpvbmVQbGFuKSB7XG4gICAgICAgICAgICBjb25zdCBuYXZpZ2F0aW9uczogYW55ID1cbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLm5hdmlnYXRpb25TZXJ2aWNlLmdldE5hdmlnYXRpb25zRm9yWm9uZSh6b25lUGxhbik7XG4gICAgICAgICAgICBpZiAobmF2aWdhdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0aW9ucy5tYXAoYXN5bmMgKG5hdikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpb24gPSBKU09OLnBhcnNlKG5hdi5wb3NpdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgeDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHk6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNhbGlicmF0aW9uUGxhbi5uZXcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbjJEID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm1Qb3NpdGlvbjNERm9yTmV3Q2FsaWJyYXRpb24ocG9zaXRpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSBwb3NpdGlvbjJELnggLyBwb3NpdGlvbjJELmNvZWZmWDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gcG9zaXRpb24yRC55IC8gcG9zaXRpb24yRC5jb2VmZlk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodGhpcy5jYWxpYnJhdGlvblBsYW4ub2Zmc2V0WCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbi54ICogdGhpcy5jYWxpYnJhdGlvblBsYW4ueCkgL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvZWZmUGxhblg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzLmNhbGlicmF0aW9uUGxhbi5vZmZzZXRZICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uLnogKiB0aGlzLmNhbGlicmF0aW9uUGxhbi55KSAvXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29lZmZQbGFuWTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGlzdFggPSBNYXRoLmFicyhjbGlja1ggLSB4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpc3RZID0gTWF0aC5hYnMoY2xpY2tZIC0geSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXYuZGlzdCA9IE1hdGguc3FydChNYXRoLnBvdyhkaXN0WCwgMikgKyBNYXRoLnBvdyhkaXN0WSwgMikpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgbmF2aWdhdGlvbnMuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYS5kaXN0IC0gYi5kaXN0O1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMubWF0dGVycG9ydFNlcnZpY2UuYWN0aW9uX2dvX3RvX3N3ZWVwKFxuICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0aW9uc1swXS5tYXR0ZXJwb3J0U3dlZXBJRFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb25maWd1cmVzIHBsYW4gZnJvbSBjYWNoZSAocHJldmlvdXMgcGxhbikuXG4gICAgICovXG4gICAgYXN5bmMgdXBsb2FkUGxhbkZyb21DYWNoZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5odG1sQ29udGVudFRvSW5qZWN0ID0gdGhpcy5jYWNoZS5odG1sQ29udGVudDtcbiAgICAgICAgYXdhaXQgdGhpcy5jb25maWd1cmVQbGFuKHRoaXMuY2FjaGUucGxhbik7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQdXRzIGJ1dHRvbnMgKHRhZ3MpIGZyb20gY2FjaGUgYWNjb3JkaW5nIHRvIHBhc3NlZCBlbGVtZW50IElEcyAoZm9yIGZpbHRlciBpZiBhbnkpXG4gICAgICogQHBhcmFtIGVsZW1lbnRJRHMgZWxlbWVudHMgKHRpY2tldHMsIGVxdWlwbWVudHMsIGV0YykgdG8gYmUgc2hvd24gb24gcGxhblxuICAgICAqL1xuICAgIHVwbG9hZFRhZ3NGcm9tQ2FjaGUoc2l6ZUJ1dHRvbjogbnVtYmVyID0gMTApIHtcbiAgICAgICAgLy8gY29uc29sZS5sb2coXCJ1cGxvYWRpbmcgdGFncyBmcm9tIGNhY2hlXCIpO1xuXG4gICAgICAgIGZvciAoY29uc3QgY2FjaGVkIG9mIHRoaXMuY2FjaGUuaHRtbENvbnRlbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xuICAgICAgICAgICAgdGhpcy5zdHlsZUJ1dHRvbihidXR0b24sIGNhY2hlZC50YWdJY29uLCBzaXplQnV0dG9uKTtcbiAgICAgICAgICAgIGJ1dHRvbi5pZCA9IGNhY2hlZC5lbGVtZW50SUQ7XG4gICAgICAgICAgICB0aGlzLnBsYW5EaXZDb250ZW50LmFwcGVuZChidXR0b24pO1xuICAgICAgICAgICAgaWYgKHRoaXMuY2FsaWJyYXRpb25QbGFuLm5ldykge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld0NvZWZmWCA9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29lZmZQbGFuWCAvXG4gICAgICAgICAgICAgICAgICAgICh0aGlzLmltZ1BsYW4ud2lkdGggLyB0aGlzLmNhbGlicmF0aW9uUGxhbi5pbWdXaWR0aCk7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3Q29lZmZZID1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb2VmZlBsYW5ZIC9cbiAgICAgICAgICAgICAgICAgICAgKHRoaXMuaW1nUGxhbi5oZWlnaHQgLyB0aGlzLmNhbGlicmF0aW9uUGxhbi5pbWdIZWlnaHQpO1xuICAgICAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS50b3AgPSBgJHtjYWNoZWQueSAvIG5ld0NvZWZmWSAtIDV9cHhgO1xuICAgICAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS5sZWZ0ID0gYCR7Y2FjaGVkLnggLyBuZXdDb2VmZlggLSA1fXB4YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYnV0dG9uLnN0eWxlLnRvcCA9IGAke2NhY2hlZC55IC8gdGhpcy5jb2VmZlBsYW5ZIC0gNX1weGA7XG4gICAgICAgICAgICAgICAgYnV0dG9uLnN0eWxlLmxlZnQgPSBgJHtjYWNoZWQueCAvIHRoaXMuY29lZmZQbGFuWCAtIDV9cHhgO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmFkZExpc3RlbmVyc1RvQnV0dG9uKGJ1dHRvbiwgY2FjaGVkLnVybCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBnZXRDYWxpYnJhdGVkUGxhbkZvclpvbmUoem9uZTogWm9uZSk6IFByb21pc2U8UGxhbj4ge1xuICAgICAgICBsZXQgcGxhbnMgPSAoYXdhaXQgdGhpcy5BUEkuUGxhbnNCeVpvbmUoem9uZS5pZCkpLml0ZW1zO1xuICAgICAgICBsZXQgcGFyZW50Wm9uZSA9IG51bGw7XG4gICAgICAgIGlmIChwbGFucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIHRyeSB0byBmaW5kIHBhcmVudCB6b25lXG4gICAgICAgICAgICBwYXJlbnRab25lID0gYXdhaXQgdGhpcy5BUEkuR2V0Wm9uZSh6b25lLnBhcmVudElEKTtcbiAgICAgICAgICAgIHBsYW5zID0gKGF3YWl0IHRoaXMuQVBJLlBsYW5zQnlab25lKHpvbmUucGFyZW50SUQpKS5pdGVtcztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjYWxpYnJhdGVkUGxhbiA9IHBsYW5zLmZpbmQoXG4gICAgICAgICAgICAocGxhbikgPT4gcGxhbi5jYWxpYnJhdGlvbiAmJiBwbGFuLmlzQ3VycmVudEZvclpvbmVcbiAgICAgICAgKSBhcyBQbGFuO1xuICAgICAgICBpZiAoY2FsaWJyYXRlZFBsYW4pIHtcbiAgICAgICAgICAgIGNvbnN0IHNpZ25lZCA9IGF3YWl0IGdldFNpZ25lZEZpbGUoY2FsaWJyYXRlZFBsYW4uYW5uZXhlKTtcbiAgICAgICAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgICAgICAgICBjYWxpYnJhdGVkUGxhbi5maWxlcGF0aCA9IHNpZ25lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhbGlicmF0ZWRQbGFuLm5hdmlnYXRpb25JRHMgPSBwYXJlbnRab25lXG4gICAgICAgICAgICAgICAgPyBwYXJlbnRab25lLnN3ZWVwSURzXG4gICAgICAgICAgICAgICAgOiB6b25lLnN3ZWVwSURzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYWxpYnJhdGVkUGxhbiB8fCBudWxsO1xuICAgIH1cblxuICAgIHRyYW5zZm9ybVBvc2l0aW9uM0RGb3JOZXdDYWxpYnJhdGlvbihwb3NpdGlvbjoge1xuICAgICAgICB4OiBudW1iZXI7XG4gICAgICAgIHk6IG51bWJlcjtcbiAgICAgICAgejogbnVtYmVyO1xuICAgIH0pOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyOyBjb2VmZlg6IG51bWJlcjsgY29lZmZZOiBudW1iZXI7IH0ge1xuICAgICAgICBjb25zdCBwb3NpdGlvblggPVxuICAgICAgICAgICAgdGhpcy5jYWxpYnJhdGlvblBsYW4ubmFtZVhBeGlzID09PSAneCcgPyBwb3NpdGlvbi54IDogcG9zaXRpb24uejtcbiAgICAgICAgY29uc3QgcG9zaXRpb25ZID1cbiAgICAgICAgICAgIHRoaXMuY2FsaWJyYXRpb25QbGFuLm5hbWVZQXhpcyA9PT0gJ3gnID8gcG9zaXRpb24ueCA6IHBvc2l0aW9uLno7XG4gICAgICAgIGxldCB4ID1cbiAgICAgICAgICAgIHRoaXMuY2FsaWJyYXRpb25QbGFuLm9mZnNldFggKyBwb3NpdGlvblggKiB0aGlzLmNhbGlicmF0aW9uUGxhbi5zY2FsZVg7XG4gICAgICAgIGxldCB5ID1cbiAgICAgICAgICAgIHRoaXMuY2FsaWJyYXRpb25QbGFuLm9mZnNldFkgKyBwb3NpdGlvblkgKiB0aGlzLmNhbGlicmF0aW9uUGxhbi5zY2FsZVk7XG4gICAgICAgIGNvbnN0IG5ld0NvZWZmWCA9XG4gICAgICAgICAgICB0aGlzLmNvZWZmUGxhblggLyAodGhpcy5pbWdQbGFuLndpZHRoIC8gdGhpcy5jYWxpYnJhdGlvblBsYW4uaW1nV2lkdGgpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIm5ld0NvZWZmWFwiLCBuZXdDb2VmZlgpO1xuICAgICAgICBjb25zdCBuZXdDb2VmZlkgPVxuICAgICAgICAgICAgdGhpcy5jb2VmZlBsYW5ZIC8gKHRoaXMuaW1nUGxhbi5oZWlnaHQgLyB0aGlzLmNhbGlicmF0aW9uUGxhbi5pbWdIZWlnaHQpO1xuICAgICAgICB4ID0gKHggLSB0aGlzLmNhbGlicmF0aW9uUGxhbi5vZmZzZXRYUGxhbikgLyB0aGlzLmNhbGlicmF0aW9uUGxhbi5zY2FsZVBsYW47XG5cbiAgICAgICAgeSA9ICh5IC0gdGhpcy5jYWxpYnJhdGlvblBsYW4ub2Zmc2V0WVBsYW4pIC8gdGhpcy5jYWxpYnJhdGlvblBsYW4uc2NhbGVQbGFuO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyh4LCB5KTtcblxuICAgICAgICByZXR1cm4geyB4LCB5LCBjb2VmZlg6IG5ld0NvZWZmWCwgY29lZmZZOiBuZXdDb2VmZlkgfTtcbiAgICB9XG59XG4iXX0=
|
|
1
|
+
/* eslint-disable func-names */
|
|
2
|
+
/* eslint-disable class-methods-use-this */
|
|
3
|
+
import { Inject, Injectable } from '@angular/core';
|
|
4
|
+
import { getDocument, GlobalWorkerOptions } from 'pdfjs-dist';
|
|
5
|
+
import panzoom from 'panzoom';
|
|
6
|
+
import videojs from "video.js";
|
|
7
|
+
import { Subject } from 'rxjs';
|
|
8
|
+
import { CommentType, FeatureType, PoiType, } from '../../types.service';
|
|
9
|
+
import { getSignedFile, uploadFileToS3 } from '../s3.service';
|
|
10
|
+
import { getCoefficientsForImage } from '../zone-drawer.service';
|
|
11
|
+
import { getMetaForImage } from '../../helpers.service';
|
|
12
|
+
import * as i0 from "@angular/core";
|
|
13
|
+
import * as i1 from "./zone.service";
|
|
14
|
+
import * as i2 from "./navigation.service";
|
|
15
|
+
import * as i3 from "../viewer.service";
|
|
16
|
+
import * as i4 from "@angular/router";
|
|
17
|
+
import * as i5 from "../matterport.service";
|
|
18
|
+
import * as i6 from "../baseVisibility.service";
|
|
19
|
+
import * as i7 from "../content.service";
|
|
20
|
+
export class PlanService {
|
|
21
|
+
constructor(apiInjected, zoneService, navigationService,
|
|
22
|
+
// tagService: BaseTagService,
|
|
23
|
+
viewerService, router, matterportService,
|
|
24
|
+
// private config: AppConfig,
|
|
25
|
+
visibilityService, contentService) {
|
|
26
|
+
this.zoneService = zoneService;
|
|
27
|
+
this.navigationService = navigationService;
|
|
28
|
+
this.viewerService = viewerService;
|
|
29
|
+
this.router = router;
|
|
30
|
+
this.matterportService = matterportService;
|
|
31
|
+
this.visibilityService = visibilityService;
|
|
32
|
+
this.contentService = contentService;
|
|
33
|
+
this.isReady = false;
|
|
34
|
+
this.detailTagDivIsHover = false;
|
|
35
|
+
this.btnTagIsHover = false;
|
|
36
|
+
this.resizePlanSubscription = new Subject();
|
|
37
|
+
this.lastTouchTime = 0;
|
|
38
|
+
this.delayDblTouch = 500;
|
|
39
|
+
this.lastRotation = 0;
|
|
40
|
+
this.htmlContentToInject = [];
|
|
41
|
+
this.focusMouseTagDiv = false;
|
|
42
|
+
this.API = apiInjected;
|
|
43
|
+
this.matterportService.currentCameraPose.subscribe((pose) => {
|
|
44
|
+
this.updateRotation(pose.rotation.y);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
async createPlan(planInput) {
|
|
48
|
+
return this.API.__proto__.CreatePlan(planInput);
|
|
49
|
+
}
|
|
50
|
+
async deletePlan(plan) {
|
|
51
|
+
// await deleteFromS3(plan.annexe);
|
|
52
|
+
return this.API.__proto__.DeletePlan({ id: plan.id });
|
|
53
|
+
}
|
|
54
|
+
async getPlansForSpace(spaceID) {
|
|
55
|
+
return this.API.__proto__
|
|
56
|
+
.PlansBySpace(spaceID)
|
|
57
|
+
.then((response) => response.items);
|
|
58
|
+
}
|
|
59
|
+
async getPlansForZone(zoneID) {
|
|
60
|
+
return this.API.__proto__
|
|
61
|
+
.PlansByZone(zoneID)
|
|
62
|
+
.then((response) => response.items);
|
|
63
|
+
}
|
|
64
|
+
async getSingedPlansForSpace(spaceID) {
|
|
65
|
+
const plansFromDB = await this.getPlansForSpace(spaceID);
|
|
66
|
+
// console.log(plansFromDB);
|
|
67
|
+
const plans = [];
|
|
68
|
+
if (plansFromDB.length > 0) {
|
|
69
|
+
await Promise.all(plansFromDB.map(async (plan) => {
|
|
70
|
+
const planObject = { ...plan };
|
|
71
|
+
// annexe looks like visits/modelID/plans/file.extension
|
|
72
|
+
const signed = await getSignedFile(plan.annexe);
|
|
73
|
+
if (signed) {
|
|
74
|
+
planObject.filepath = signed;
|
|
75
|
+
}
|
|
76
|
+
if (plan.annexe) {
|
|
77
|
+
const [, modelID, , filenameWithExtension] = plan.annexe.split('/');
|
|
78
|
+
const [, extention] = filenameWithExtension.split('.');
|
|
79
|
+
planObject.model3d = modelID;
|
|
80
|
+
planObject.extension = extention;
|
|
81
|
+
plans.push(planObject);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
console.log(`Error plan have not annexe => `);
|
|
85
|
+
console.log(plan.id);
|
|
86
|
+
}
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
return plans;
|
|
90
|
+
}
|
|
91
|
+
async getPlansWithZonesForSpace(spaceID) {
|
|
92
|
+
const plans = await this.getPlansForSpace(spaceID);
|
|
93
|
+
const plansZones = plans.filter((plan) => plan.zone && plan.calibration);
|
|
94
|
+
return plansZones;
|
|
95
|
+
}
|
|
96
|
+
setChosenPlan(chosenPlan) {
|
|
97
|
+
this.chosenPlan = chosenPlan;
|
|
98
|
+
}
|
|
99
|
+
getChosenPlan() {
|
|
100
|
+
return this.chosenPlan;
|
|
101
|
+
}
|
|
102
|
+
setPlanFileCache(planFileCache) {
|
|
103
|
+
this.planFileCache = planFileCache;
|
|
104
|
+
return Promise.resolve();
|
|
105
|
+
}
|
|
106
|
+
getPlanFileCache() {
|
|
107
|
+
return this.planFileCache;
|
|
108
|
+
}
|
|
109
|
+
async createPlanWithAnnexe(plan, file) {
|
|
110
|
+
const createdPlan = await this.createPlan(plan);
|
|
111
|
+
const model3D = await this.zoneService.getModel3DForZone(plan.zoneID);
|
|
112
|
+
const url = await uploadFileToS3(`visits/${model3D}/plans/`, file, createdPlan.id);
|
|
113
|
+
if (url) {
|
|
114
|
+
return this.API.__proto__.UpdatePlan({ id: createdPlan.id, annexe: url });
|
|
115
|
+
}
|
|
116
|
+
return createdPlan;
|
|
117
|
+
}
|
|
118
|
+
async updatePlan(plan) {
|
|
119
|
+
return this.API.__proto__.UpdatePlan(plan);
|
|
120
|
+
}
|
|
121
|
+
async updatePlanFile() {
|
|
122
|
+
if (this.chosenPlan && this.planFileCache) {
|
|
123
|
+
const model3D = await this.zoneService.getModel3DForZone(this.chosenPlan.zoneID);
|
|
124
|
+
return uploadFileToS3(`visits/${model3D}/plans/`, this.planFileCache, this.chosenPlan.id);
|
|
125
|
+
}
|
|
126
|
+
return Promise.reject();
|
|
127
|
+
}
|
|
128
|
+
async setAllPlansForZoneNotCurrent(zoneID, currentPlanID) {
|
|
129
|
+
const plans = await this.API.__proto__.ListPlans({
|
|
130
|
+
zoneID: { eq: zoneID },
|
|
131
|
+
});
|
|
132
|
+
await Promise.all(plans.items.map(async (plan) => {
|
|
133
|
+
if (plan.isCurrentForZone && plan.id !== currentPlanID) {
|
|
134
|
+
await this.updatePlan({
|
|
135
|
+
id: plan.id,
|
|
136
|
+
isCurrentForZone: false,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
141
|
+
async configurePlan(currentPlan, divId = 'planDivPane', divContentId = 'planDivPaneContent') {
|
|
142
|
+
this.isReady = false;
|
|
143
|
+
if (!this.detailTagDiv) {
|
|
144
|
+
this.detailTagDiv = document.querySelector(`#detailTagDiv`);
|
|
145
|
+
}
|
|
146
|
+
this.detailTagDiv.addEventListener('mouseenter', () => {
|
|
147
|
+
this.focusMouseTagDiv = true;
|
|
148
|
+
});
|
|
149
|
+
this.detailTagDiv.addEventListener('mouseleave', () => {
|
|
150
|
+
this.btnTagIsHover = false;
|
|
151
|
+
this.detailTagDiv.style.display = 'none';
|
|
152
|
+
this.focusMouseTagDiv = false;
|
|
153
|
+
});
|
|
154
|
+
this.calibrationPlan = JSON.parse(currentPlan.calibration);
|
|
155
|
+
this.currentPlan = currentPlan;
|
|
156
|
+
this.planDiv = document.querySelector(`#${divId}`);
|
|
157
|
+
this.planDivContent = document.querySelector(`#${divContentId}`);
|
|
158
|
+
this.planDiv.addEventListener('touchstart', this.handleTouch.bind(this));
|
|
159
|
+
this.planDiv.addEventListener('dblclick', this.onDblClickPlan.bind(this));
|
|
160
|
+
if (!currentPlan.annexe.includes('pdf')) {
|
|
161
|
+
this.imgPlan = await getMetaForImage(currentPlan.filepath);
|
|
162
|
+
//Rect use offsetWidth : height, not actual boundingClientRect because will be modified by the zoom.
|
|
163
|
+
const rect = {
|
|
164
|
+
width: this.planDivContent.offsetWidth,
|
|
165
|
+
height: this.planDivContent.offsetHeight,
|
|
166
|
+
};
|
|
167
|
+
const { coeffX, coeffY } = getCoefficientsForImage(this.imgPlan, rect);
|
|
168
|
+
this.coeffPlanX = coeffX;
|
|
169
|
+
this.coeffPlanY = coeffY;
|
|
170
|
+
this.planDivContent.style.backgroundImage = `url(${currentPlan.filepath})`;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
await this.drawPdf(currentPlan);
|
|
174
|
+
}
|
|
175
|
+
this.planDivContent.style.backgroundSize = 'contain';
|
|
176
|
+
this.planDivContent.style.backgroundRepeat = 'no-repeat';
|
|
177
|
+
this.panzoom = panzoom(this.planDiv, {
|
|
178
|
+
bounds: true,
|
|
179
|
+
boundsPadding: 0,
|
|
180
|
+
maxZoom: 4,
|
|
181
|
+
zoomDoubleClickSpeed: 1, //disables double click zoom
|
|
182
|
+
//initialZoom: 4
|
|
183
|
+
});
|
|
184
|
+
this.panzoom.zoomAbs(0, 0, 4);
|
|
185
|
+
setTimeout(() => {
|
|
186
|
+
this.updateRotation(this.lastRotation);
|
|
187
|
+
}, 200);
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
clearPlanImage() {
|
|
191
|
+
if (this.planDivContent) {
|
|
192
|
+
this.planDivContent.style.backgroundImage = null;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async drawPdf(currentPlan) {
|
|
196
|
+
return new Promise(async (resolve) => {
|
|
197
|
+
const canvas = document.createElement('canvas');
|
|
198
|
+
const context = canvas.getContext('2d');
|
|
199
|
+
const pdfjsWorker = await import('pdfjs-dist/build/pdf.worker.entry');
|
|
200
|
+
GlobalWorkerOptions.workerSrc = pdfjsWorker;
|
|
201
|
+
const pdf = await getDocument(currentPlan.filepath).promise;
|
|
202
|
+
const page = await pdf.getPage(1);
|
|
203
|
+
const viewPortParameters = { scale: 1.5 };
|
|
204
|
+
const viewport = page.getViewport(viewPortParameters);
|
|
205
|
+
canvas.height = viewport.height;
|
|
206
|
+
canvas.width = viewport.width;
|
|
207
|
+
const renderContext = {
|
|
208
|
+
canvasContext: context,
|
|
209
|
+
viewport,
|
|
210
|
+
};
|
|
211
|
+
const renderTask = page.render(renderContext).promise;
|
|
212
|
+
renderTask.then(async () => {
|
|
213
|
+
const imgUrl = canvas.toDataURL('image/png');
|
|
214
|
+
this.imgPlan = await getMetaForImage(imgUrl);
|
|
215
|
+
const rect = {
|
|
216
|
+
width: this.planDivContent.offsetWidth,
|
|
217
|
+
height: this.planDivContent.offsetHeight,
|
|
218
|
+
};
|
|
219
|
+
const { coeffX, coeffY } = getCoefficientsForImage(this.imgPlan, rect);
|
|
220
|
+
this.coeffPlanX = coeffX;
|
|
221
|
+
this.coeffPlanY = coeffY;
|
|
222
|
+
this.planDiv.style.backgroundImage = `url(${imgUrl})`;
|
|
223
|
+
resolve();
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
async drawElement(element, tagType, currentPlan, tagService, config, sizeButton = 10) {
|
|
228
|
+
const [poi] = element.pois.items;
|
|
229
|
+
if (poi && poi.coordinate && currentPlan) {
|
|
230
|
+
const { zone } = currentPlan;
|
|
231
|
+
if (zone) {
|
|
232
|
+
const position = JSON.parse(poi.coordinate);
|
|
233
|
+
const button = document.createElement('button');
|
|
234
|
+
let elementTitle;
|
|
235
|
+
const url = tagService.getUrlForSeeDetails(element, tagType);
|
|
236
|
+
let tagIconImage;
|
|
237
|
+
switch (tagType) {
|
|
238
|
+
case PoiType.TICKET: {
|
|
239
|
+
tagIconImage = config.my_config.icon_ticket;
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
case PoiType.EQUIPMENT: {
|
|
243
|
+
tagIconImage = config.my_config.icon_equipment;
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
case PoiType.MEASURE:
|
|
247
|
+
tagIconImage = config.my_config.icon_measure;
|
|
248
|
+
break;
|
|
249
|
+
case PoiType.OBJECT3D:
|
|
250
|
+
tagIconImage = config.my_config.icon_object3d;
|
|
251
|
+
break;
|
|
252
|
+
case PoiType.DATA:
|
|
253
|
+
tagIconImage = config.my_config.icon_data;
|
|
254
|
+
break;
|
|
255
|
+
case PoiType.DESK:
|
|
256
|
+
tagIconImage = config.my_config.icon_data;
|
|
257
|
+
break;
|
|
258
|
+
default:
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
if (poi.tagIcon) {
|
|
262
|
+
const tagIcon = JSON.parse(poi.tagIcon);
|
|
263
|
+
if (tagType === PoiType.DATA &&
|
|
264
|
+
element.type === FeatureType.INDICATOR_TEMP) {
|
|
265
|
+
tagIcon.src = tagService.getIconTagImageForFeature(element, poi);
|
|
266
|
+
}
|
|
267
|
+
// poi.tagIcon = tagIcon;
|
|
268
|
+
if (tagIcon.src) {
|
|
269
|
+
const source = await getSignedFile(tagIcon.src);
|
|
270
|
+
if (source) {
|
|
271
|
+
tagIconImage = source;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
this.styleButton(button, tagIconImage, sizeButton);
|
|
276
|
+
button.id = element.id;
|
|
277
|
+
this.planDivContent.append(button);
|
|
278
|
+
let x;
|
|
279
|
+
let y;
|
|
280
|
+
if (this.calibrationPlan.new) {
|
|
281
|
+
// alert("new calibration plan: positioning not ready yet");
|
|
282
|
+
const position2D = this.transformPosition3DForNewCalibration(position);
|
|
283
|
+
x = position2D.x;
|
|
284
|
+
y = position2D.y;
|
|
285
|
+
button.style.top = `${y / position2D.coeffY - 5}px`;
|
|
286
|
+
button.style.left = `${x / position2D.coeffX - 5}px`;
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
// to remove when all calibrations are new
|
|
290
|
+
x =
|
|
291
|
+
this.calibrationPlan.offsetX + position.x * this.calibrationPlan.x;
|
|
292
|
+
y =
|
|
293
|
+
this.calibrationPlan.offsetY + position.z * this.calibrationPlan.y;
|
|
294
|
+
button.style.top = `${y / this.coeffPlanY - 5}px`;
|
|
295
|
+
button.style.left = `${x / this.coeffPlanX - 5}px`;
|
|
296
|
+
}
|
|
297
|
+
const html = await tagService.getHtmlToInject(tagType, element);
|
|
298
|
+
if (html != '') {
|
|
299
|
+
this.htmlContentToInject.push({
|
|
300
|
+
elementID: element.id,
|
|
301
|
+
title: '',
|
|
302
|
+
content: html,
|
|
303
|
+
y,
|
|
304
|
+
x,
|
|
305
|
+
tagIcon: tagIconImage,
|
|
306
|
+
url,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
// when we don't have html => case of EMBED Comment type
|
|
311
|
+
const commentEmbed = element.comments?.items.find((com) => com.type === CommentType.EMBED && com.shownInTag);
|
|
312
|
+
if (commentEmbed) {
|
|
313
|
+
this.htmlContentToInject.push({
|
|
314
|
+
elementID: element.id,
|
|
315
|
+
title: element.title,
|
|
316
|
+
content: `<iframe src=${commentEmbed.externalLink} height="200px" width="100%"></iframe>`,
|
|
317
|
+
y,
|
|
318
|
+
x,
|
|
319
|
+
tagIcon: tagIconImage,
|
|
320
|
+
url,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
this.addListenersToButton(button, url, tagService, element);
|
|
325
|
+
this.updateRotation(this.lastRotation);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
async drawUserPosition(currentSweep = this.currentSweep, sizeButton = 10) {
|
|
330
|
+
this.currentSweep = currentSweep;
|
|
331
|
+
if (this.calibrationPlan && currentSweep) {
|
|
332
|
+
const position = this.matterportService.getCurrentCameraPosition()?.position;
|
|
333
|
+
if (position) {
|
|
334
|
+
if (!this.userPositionBtn) {
|
|
335
|
+
this.userPositionBtn = document.createElement('button');
|
|
336
|
+
this.userPositionBtn.id = 'currentPosition';
|
|
337
|
+
this.planDivContent.append(this.userPositionBtn);
|
|
338
|
+
this.userPositionBtn.title = 'You are here';
|
|
339
|
+
this.styleButton(this.userPositionBtn, 'https://api.iconify.design/bx:bxs-user-circle.svg?color=green&height=17&width=17', sizeButton);
|
|
340
|
+
}
|
|
341
|
+
let x;
|
|
342
|
+
let y;
|
|
343
|
+
if (this.calibrationPlan.new) {
|
|
344
|
+
const position2D = this.transformPosition3DForNewCalibration(position);
|
|
345
|
+
x = position2D.x / position2D.coeffX - 5;
|
|
346
|
+
y = position2D.y / position2D.coeffY - 5;
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
x =
|
|
350
|
+
(this.calibrationPlan.offsetX +
|
|
351
|
+
position.x * this.calibrationPlan.x) /
|
|
352
|
+
this.coeffPlanX;
|
|
353
|
+
y =
|
|
354
|
+
(this.calibrationPlan.offsetY +
|
|
355
|
+
position.z * this.calibrationPlan.y) /
|
|
356
|
+
this.coeffPlanY;
|
|
357
|
+
}
|
|
358
|
+
this.userPositionBtn.style.top = `${y}px`;
|
|
359
|
+
this.userPositionBtn.style.left = `${x}px`;
|
|
360
|
+
this.moveOnPoint({ x: x + 5, y: y + 5 });
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Center the view of the plan on coordinates
|
|
366
|
+
* @param coordinate Coordinate on the plan
|
|
367
|
+
*/
|
|
368
|
+
moveOnPoint(coordinate) {
|
|
369
|
+
if (this.planDiv) {
|
|
370
|
+
const scale = this.panzoom.getTransform().scale;
|
|
371
|
+
const moveX = this.planDiv.clientWidth / 2 - coordinate.x * scale;
|
|
372
|
+
const moveY = this.planDiv.clientHeight / 2 - coordinate.y * scale;
|
|
373
|
+
this.panzoom.moveTo(moveX, moveY);
|
|
374
|
+
this.planDivContent.style.transformOrigin = `${coordinate.x}px ${coordinate.y}px`;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Apply a rotation to the plan
|
|
379
|
+
* Buttons will remain in the correct rotation
|
|
380
|
+
* @param rotation
|
|
381
|
+
*/
|
|
382
|
+
updateRotation(rotation) {
|
|
383
|
+
this.lastRotation = rotation;
|
|
384
|
+
if (this.planDivContent) {
|
|
385
|
+
this.planDivContent.style.transform = `rotate(${rotation}deg)`;
|
|
386
|
+
const buttons = this.planDivContent.querySelectorAll('button');
|
|
387
|
+
let rotationRegex = /(rotate\(-?\d*\.?\d+deg\))/g;
|
|
388
|
+
// eslint-disable-next-line unicorn/no-array-for-each
|
|
389
|
+
buttons.forEach((button) => {
|
|
390
|
+
button.style.transform = button.style.transform.replace(rotationRegex, "") + ` rotate(${-rotation}deg)`;
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
removeCurrentPosition() {
|
|
395
|
+
const button = document.querySelector('#currentPosition');
|
|
396
|
+
if (button) {
|
|
397
|
+
button.remove();
|
|
398
|
+
this.userPositionBtn = null;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
styleButton(button, url, sizeButton = 10) {
|
|
402
|
+
button.style.backgroundImage = `url(${url})`;
|
|
403
|
+
button.style.backgroundColor = 'transparent';
|
|
404
|
+
button.style.position = 'absolute';
|
|
405
|
+
button.style.border = 'none';
|
|
406
|
+
button.style.width = `10px`;
|
|
407
|
+
button.style.height = `10px`;
|
|
408
|
+
button.disabled = false;
|
|
409
|
+
button.style.backgroundSize = 'contain';
|
|
410
|
+
button.style.backgroundRepeat = 'no-repeat';
|
|
411
|
+
button.style.transform = `scale(${sizeButton / 10})`;
|
|
412
|
+
}
|
|
413
|
+
addListenersToButton(button, url, tagService = null, element = null) {
|
|
414
|
+
let videoJsPlayer;
|
|
415
|
+
button.addEventListener('mouseenter', async (event) => {
|
|
416
|
+
const contentForButton = this.htmlContentToInject.find((object) => object.elementID === button.id);
|
|
417
|
+
this.btnTagIsHover = true;
|
|
418
|
+
const title = document.querySelector(`#titleTagDiv`);
|
|
419
|
+
if (contentForButton.title) {
|
|
420
|
+
title.style.display = 'inline';
|
|
421
|
+
title.innerHTML = contentForButton.title;
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
title.style.display = 'none';
|
|
425
|
+
}
|
|
426
|
+
const content = document.querySelector(`#htmlTagDiv`);
|
|
427
|
+
this.detailTagDiv.style.top = `${event.clientY + 10}px`;
|
|
428
|
+
this.detailTagDiv.style.left = `${event.clientX < 120 ? 0 : event.clientX - 120}px`;
|
|
429
|
+
this.detailTagDiv.style.display = 'block';
|
|
430
|
+
// console.log(contentForButton.content);
|
|
431
|
+
content.innerHTML = contentForButton.content;
|
|
432
|
+
const detailButton = content.querySelector('#detailBtn');
|
|
433
|
+
if (detailButton) {
|
|
434
|
+
detailButton.addEventListener('click', () => {
|
|
435
|
+
this.visibilityService.detailShowing.next(true);
|
|
436
|
+
this.router.navigate([url]);
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
// handle image carousel fullscreen button
|
|
440
|
+
const imageFullscreenBtn = content.querySelector('#image-footer');
|
|
441
|
+
if (imageFullscreenBtn) {
|
|
442
|
+
imageFullscreenBtn.addEventListener('click', function () {
|
|
443
|
+
if (tagService) {
|
|
444
|
+
tagService.onActionImageClick(contentForButton.elementID);
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
// handle booking fullscreen button
|
|
449
|
+
const bookingButton = content.querySelector('#bookingBtn');
|
|
450
|
+
if (bookingButton) {
|
|
451
|
+
bookingButton.addEventListener('click', () => {
|
|
452
|
+
this.visibilityService.detailShowing.next(true);
|
|
453
|
+
this.router.navigate([url]);
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
// handle document pdf fullscreen button
|
|
457
|
+
const docFullscreenBtn = content.querySelector('#doc-footer');
|
|
458
|
+
if (docFullscreenBtn && element) {
|
|
459
|
+
const documentUrl = tagService.getAnnexeForCommentTypeInFeature(element, CommentType.DOCUMENT);
|
|
460
|
+
docFullscreenBtn.addEventListener('click', function () {
|
|
461
|
+
if (tagService) {
|
|
462
|
+
tagService.onActionDocClick(documentUrl);
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
// handle video fullscreen button
|
|
467
|
+
const videoFullscreenBtn = content.querySelector('#btn-video-fullscreen');
|
|
468
|
+
if (videoFullscreenBtn && element) {
|
|
469
|
+
const videoUrl = tagService.getAnnexeForCommentTypeInFeature(element, CommentType.VIDEO);
|
|
470
|
+
videoFullscreenBtn.addEventListener('click', function () {
|
|
471
|
+
if (tagService) {
|
|
472
|
+
tagService.onActionVideoClick(videoUrl);
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
// handle Youtube video fullscreen button
|
|
477
|
+
const youtubeFullScreen = content.querySelector('#btn-video-fullscreen-youtube');
|
|
478
|
+
if (youtubeFullScreen && element) {
|
|
479
|
+
const youtubeUrl = tagService.getAnnexeForCommentTypeInFeature(element, CommentType.YOUTUBE);
|
|
480
|
+
youtubeFullScreen.addEventListener('click', function () {
|
|
481
|
+
if (tagService) {
|
|
482
|
+
tagService.onActionYoutubeClick(youtubeUrl);
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
// handle mute video button
|
|
487
|
+
const btnMute = document.getElementById('btn-mute');
|
|
488
|
+
const imgOn = document.getElementById('sound-on');
|
|
489
|
+
const imgOff = document.getElementById('sound-off');
|
|
490
|
+
const playerElement = document.getElementById("mus-video-tag");
|
|
491
|
+
if (playerElement) {
|
|
492
|
+
videoJsPlayer = videojs("mus-video-tag");
|
|
493
|
+
if (btnMute && videoJsPlayer) {
|
|
494
|
+
btnMute.addEventListener('click', function () {
|
|
495
|
+
if (videoJsPlayer.muted()) {
|
|
496
|
+
videoJsPlayer.muted(false);
|
|
497
|
+
if (imgOn && imgOff) {
|
|
498
|
+
imgOn.style.display = 'inline-block';
|
|
499
|
+
imgOff.style.display = 'none';
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
videoJsPlayer.muted(true);
|
|
504
|
+
if (imgOn && imgOff) {
|
|
505
|
+
imgOn.style.display = 'none';
|
|
506
|
+
imgOff.style.display = 'inline-block';
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
// handle audio player buttons
|
|
513
|
+
const playerButton = document.querySelector('.audio-play-button');
|
|
514
|
+
const audio = document.getElementById('audio-tag');
|
|
515
|
+
const timeline = document.querySelector('.timeline-tag');
|
|
516
|
+
// const timelineValue = document.querySelector('.timeline-tag').value;
|
|
517
|
+
const soundButton = document.querySelector('.audio-sound-btn');
|
|
518
|
+
const playAudio = document.getElementById('play');
|
|
519
|
+
const pauseAudio = document.getElementById('pause');
|
|
520
|
+
const imgSoundOn = document.getElementById('audio-sound-on');
|
|
521
|
+
const imgSoundOff = document.getElementById('audio-sound-off');
|
|
522
|
+
const audioModal = document.getElementById('btn-audio-modal');
|
|
523
|
+
if (audio && playerButton && timeline) {
|
|
524
|
+
playerButton.addEventListener('click', function () {
|
|
525
|
+
if (audio.paused) {
|
|
526
|
+
audio.play();
|
|
527
|
+
pauseAudio.style.display = 'inline-block';
|
|
528
|
+
playAudio.style.display = 'none';
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
audio.pause();
|
|
532
|
+
pauseAudio.style.display = 'none';
|
|
533
|
+
playAudio.style.display = 'inline-block';
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
soundButton.addEventListener('click', function () {
|
|
537
|
+
if (audio.muted) {
|
|
538
|
+
audio.muted = false;
|
|
539
|
+
imgSoundOn.style.display = 'inline-block';
|
|
540
|
+
imgSoundOff.style.display = 'none';
|
|
541
|
+
}
|
|
542
|
+
else {
|
|
543
|
+
audio.muted = true;
|
|
544
|
+
imgSoundOn.style.display = 'none';
|
|
545
|
+
imgSoundOff.style.display = 'inline-block';
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
function changeTimelinePosition() {
|
|
549
|
+
if (audio.duration) {
|
|
550
|
+
const percentagePosition = (100 * audio.currentTime) / audio.duration;
|
|
551
|
+
const percentagePositionString = percentagePosition + '%';
|
|
552
|
+
timeline.style.backgroundSize = percentagePositionString + ' 100%';
|
|
553
|
+
timeline.value = percentagePosition.toString();
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
audio.ontimeupdate = changeTimelinePosition;
|
|
557
|
+
function changeSeek() {
|
|
558
|
+
const time = (parseInt(timeline.value) * audio.duration) / 100;
|
|
559
|
+
audio.currentTime = time;
|
|
560
|
+
}
|
|
561
|
+
timeline.addEventListener('change', changeSeek);
|
|
562
|
+
timeline.addEventListener('input', changeSeek);
|
|
563
|
+
// handle audio click
|
|
564
|
+
if (audioModal && element) {
|
|
565
|
+
const audioComment = element.comments?.items.find((com) => com.type === CommentType.AUDIO && com.shownInTag);
|
|
566
|
+
const audioCommentID = audioComment ? audioComment.id : '';
|
|
567
|
+
audioModal.addEventListener('click', function () {
|
|
568
|
+
if (tagService) {
|
|
569
|
+
tagService.onActionAudioClick(audioCommentID);
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
});
|
|
575
|
+
button.addEventListener('mouseleave', async () => {
|
|
576
|
+
// we wait if user hovers on to div of the tag (changes this.focusMouseTagDiv)
|
|
577
|
+
this.btnTagIsHover = false;
|
|
578
|
+
setTimeout(() => {
|
|
579
|
+
if (!this.focusMouseTagDiv && !this.btnTagIsHover) {
|
|
580
|
+
this.detailTagDiv.style.display = 'none';
|
|
581
|
+
if (videoJsPlayer) {
|
|
582
|
+
videoJsPlayer.dispose();
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}, 100);
|
|
586
|
+
});
|
|
587
|
+
button.addEventListener('click', async () => {
|
|
588
|
+
this.detailTagDiv.style.display = 'none';
|
|
589
|
+
if (videoJsPlayer) {
|
|
590
|
+
videoJsPlayer.dispose();
|
|
591
|
+
}
|
|
592
|
+
await this.viewerService.action_move_to_tag(button.id);
|
|
593
|
+
this.visibilityService.detailShowing.next(true);
|
|
594
|
+
this.router.navigate([url]);
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
clearBtn(idList) {
|
|
598
|
+
for (const id of idList) {
|
|
599
|
+
const button = document.getElementById(id);
|
|
600
|
+
if (button) {
|
|
601
|
+
button.remove();
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
clearAllButtons() {
|
|
606
|
+
if (this.planDivContent) {
|
|
607
|
+
const buttons = this.planDivContent.querySelectorAll('button');
|
|
608
|
+
// eslint-disable-next-line unicorn/no-array-for-each
|
|
609
|
+
buttons.forEach(function (currentValue) {
|
|
610
|
+
currentValue.remove();
|
|
611
|
+
});
|
|
612
|
+
this.userPositionBtn = null;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
updateAllButtonsStyle(properties, values) {
|
|
616
|
+
if (this.planDivContent) {
|
|
617
|
+
const buttons = this.planDivContent.querySelectorAll('button');
|
|
618
|
+
// eslint-disable-next-line unicorn/no-array-for-each
|
|
619
|
+
buttons.forEach(function (currentValue) {
|
|
620
|
+
properties.forEach((property, i) => {
|
|
621
|
+
if (property === "transform") {
|
|
622
|
+
//For saving the rotation and adding scale
|
|
623
|
+
let rotationRegex = /(rotate\(-?\d*\.?\d+deg\))/g;
|
|
624
|
+
let rotationMatch = currentValue.style[property].match(rotationRegex);
|
|
625
|
+
if (rotationMatch.length > 0) {
|
|
626
|
+
currentValue.style[property] = `${values[i]} ${rotationMatch[0]}`;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
else {
|
|
630
|
+
currentValue.style[property] = values[i];
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
onPlanRemove() {
|
|
637
|
+
this.userPositionBtn = null;
|
|
638
|
+
this.calibrationPlan = null;
|
|
639
|
+
this.currentSweep = null;
|
|
640
|
+
this.detailTagDiv = null;
|
|
641
|
+
}
|
|
642
|
+
async resizePlan(isRemoving) {
|
|
643
|
+
this.resizePlanSubscription.next(false);
|
|
644
|
+
if (isRemoving) {
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
console.log('in resizePlan');
|
|
648
|
+
if (this.planDiv && this.currentSweep) {
|
|
649
|
+
this.panzoom = panzoom(this.planDiv, {
|
|
650
|
+
bounds: true,
|
|
651
|
+
boundsPadding: 0,
|
|
652
|
+
maxZoom: 4,
|
|
653
|
+
});
|
|
654
|
+
setTimeout(() => {
|
|
655
|
+
const rect = {
|
|
656
|
+
width: this.planDivContent.offsetWidth,
|
|
657
|
+
height: this.planDivContent.offsetHeight,
|
|
658
|
+
};
|
|
659
|
+
const { coeffX, coeffY } = getCoefficientsForImage(this.imgPlan, rect);
|
|
660
|
+
this.coeffPlanX = coeffX;
|
|
661
|
+
this.coeffPlanY = coeffY;
|
|
662
|
+
this.panzoom.zoomAbs(0, 0, 4);
|
|
663
|
+
this.resizePlanSubscription.next(true);
|
|
664
|
+
}, 200);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
handleTouch(event) {
|
|
668
|
+
const now = Date.now();
|
|
669
|
+
if (now - this.lastTouchTime < this.delayDblTouch) {
|
|
670
|
+
this.lastTouchTime = 0;
|
|
671
|
+
// this.onDblClickPlan(event);
|
|
672
|
+
/** Simulate a dblclick for phone (we don't get offsetX/Y on touchevent) */
|
|
673
|
+
const newEvent = document.createEvent('MouseEvents');
|
|
674
|
+
const touch = event.changedTouches[0];
|
|
675
|
+
newEvent.initMouseEvent('dblclick', true, true, event.target.ownerDocument.defaultView, 0, touch.screenX, touch.screenY, touch.clientX, touch.clientY, event.ctrlKey, event.altKey, event.shirtKey, event.metaKey, 0, null);
|
|
676
|
+
event.target.dispatchEvent(newEvent);
|
|
677
|
+
}
|
|
678
|
+
else {
|
|
679
|
+
this.lastTouchTime = now;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
async onDblClickPlan(event) {
|
|
683
|
+
event.preventDefault();
|
|
684
|
+
const clickX = event.offsetX;
|
|
685
|
+
const clickY = event.offsetY;
|
|
686
|
+
const zonePlan = this.currentPlan.zone;
|
|
687
|
+
if (zonePlan) {
|
|
688
|
+
const navigations = await this.navigationService.getNavigationsForZone(zonePlan);
|
|
689
|
+
if (navigations.length > 0) {
|
|
690
|
+
await Promise.all(navigations.map(async (nav) => {
|
|
691
|
+
const position = JSON.parse(nav.position);
|
|
692
|
+
let x;
|
|
693
|
+
let y;
|
|
694
|
+
if (this.calibrationPlan.new) {
|
|
695
|
+
const position2D = this.transformPosition3DForNewCalibration(position);
|
|
696
|
+
x = position2D.x / position2D.coeffX;
|
|
697
|
+
y = position2D.y / position2D.coeffY;
|
|
698
|
+
}
|
|
699
|
+
else {
|
|
700
|
+
x =
|
|
701
|
+
(this.calibrationPlan.offsetX +
|
|
702
|
+
position.x * this.calibrationPlan.x) /
|
|
703
|
+
this.coeffPlanX;
|
|
704
|
+
y =
|
|
705
|
+
(this.calibrationPlan.offsetY +
|
|
706
|
+
position.z * this.calibrationPlan.y) /
|
|
707
|
+
this.coeffPlanY;
|
|
708
|
+
}
|
|
709
|
+
const distX = Math.abs(clickX - x);
|
|
710
|
+
const distY = Math.abs(clickY - y);
|
|
711
|
+
nav.dist = Math.sqrt(Math.pow(distX, 2) + Math.pow(distY, 2));
|
|
712
|
+
}));
|
|
713
|
+
navigations.sort((a, b) => {
|
|
714
|
+
return a.dist - b.dist;
|
|
715
|
+
});
|
|
716
|
+
this.matterportService.action_go_to_sweep(navigations[0].matterportSweepID);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Configures plan from cache (previous plan).
|
|
722
|
+
*/
|
|
723
|
+
async uploadPlanFromCache() {
|
|
724
|
+
this.htmlContentToInject = this.cache.htmlContent;
|
|
725
|
+
await this.configurePlan(this.cache.plan);
|
|
726
|
+
return Promise.resolve();
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Puts buttons (tags) from cache according to passed element IDs (for filter if any)
|
|
730
|
+
* @param elementIDs elements (tickets, equipments, etc) to be shown on plan
|
|
731
|
+
*/
|
|
732
|
+
uploadTagsFromCache(sizeButton = 10) {
|
|
733
|
+
// console.log("uploading tags from cache");
|
|
734
|
+
for (const cached of this.cache.htmlContent) {
|
|
735
|
+
const button = document.createElement('button');
|
|
736
|
+
this.styleButton(button, cached.tagIcon, sizeButton);
|
|
737
|
+
button.id = cached.elementID;
|
|
738
|
+
this.planDivContent.append(button);
|
|
739
|
+
if (this.calibrationPlan.new) {
|
|
740
|
+
const newCoeffX = this.coeffPlanX /
|
|
741
|
+
(this.imgPlan.width / this.calibrationPlan.imgWidth);
|
|
742
|
+
const newCoeffY = this.coeffPlanY /
|
|
743
|
+
(this.imgPlan.height / this.calibrationPlan.imgHeight);
|
|
744
|
+
button.style.top = `${cached.y / newCoeffY - 5}px`;
|
|
745
|
+
button.style.left = `${cached.x / newCoeffX - 5}px`;
|
|
746
|
+
}
|
|
747
|
+
else {
|
|
748
|
+
button.style.top = `${cached.y / this.coeffPlanY - 5}px`;
|
|
749
|
+
button.style.left = `${cached.x / this.coeffPlanX - 5}px`;
|
|
750
|
+
}
|
|
751
|
+
this.addListenersToButton(button, cached.url);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
async getCalibratedPlanForZone(zone) {
|
|
755
|
+
let plans = (await this.API.PlansByZone(zone.id)).items;
|
|
756
|
+
let parentZone = null;
|
|
757
|
+
if (plans.length === 0) {
|
|
758
|
+
// try to find parent zone
|
|
759
|
+
parentZone = await this.API.GetZone(zone.parentID);
|
|
760
|
+
plans = (await this.API.PlansByZone(zone.parentID)).items;
|
|
761
|
+
}
|
|
762
|
+
const calibratedPlan = plans.find((plan) => plan.calibration && plan.isCurrentForZone);
|
|
763
|
+
if (calibratedPlan) {
|
|
764
|
+
const signed = await getSignedFile(calibratedPlan.annexe);
|
|
765
|
+
if (signed) {
|
|
766
|
+
calibratedPlan.filepath = signed;
|
|
767
|
+
}
|
|
768
|
+
calibratedPlan.navigationIDs = parentZone
|
|
769
|
+
? parentZone.sweepIDs
|
|
770
|
+
: zone.sweepIDs;
|
|
771
|
+
}
|
|
772
|
+
return calibratedPlan || null;
|
|
773
|
+
}
|
|
774
|
+
transformPosition3DForNewCalibration(position) {
|
|
775
|
+
const positionX = this.calibrationPlan.nameXAxis === 'x' ? position.x : position.z;
|
|
776
|
+
const positionY = this.calibrationPlan.nameYAxis === 'x' ? position.x : position.z;
|
|
777
|
+
let x = this.calibrationPlan.offsetX + positionX * this.calibrationPlan.scaleX;
|
|
778
|
+
let y = this.calibrationPlan.offsetY + positionY * this.calibrationPlan.scaleY;
|
|
779
|
+
const newCoeffX = this.coeffPlanX / (this.imgPlan.width / this.calibrationPlan.imgWidth);
|
|
780
|
+
// console.log("newCoeffX", newCoeffX);
|
|
781
|
+
const newCoeffY = this.coeffPlanY / (this.imgPlan.height / this.calibrationPlan.imgHeight);
|
|
782
|
+
x = (x - this.calibrationPlan.offsetXPlan) / this.calibrationPlan.scalePlan;
|
|
783
|
+
y = (y - this.calibrationPlan.offsetYPlan) / this.calibrationPlan.scalePlan;
|
|
784
|
+
// console.log(x, y);
|
|
785
|
+
return { x, y, coeffX: newCoeffX, coeffY: newCoeffY };
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
PlanService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: PlanService, deps: [{ token: 'currentAPIService' }, { token: i1.ZoneService }, { token: i2.NavigationService }, { token: i3.ViewerService }, { token: i4.Router }, { token: i5.MatterportService }, { token: i6.BaseVisibilityService }, { token: i7.ContentService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
789
|
+
PlanService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: PlanService, providedIn: 'root' });
|
|
790
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: PlanService, decorators: [{
|
|
791
|
+
type: Injectable,
|
|
792
|
+
args: [{
|
|
793
|
+
providedIn: 'root',
|
|
794
|
+
}]
|
|
795
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
796
|
+
type: Inject,
|
|
797
|
+
args: ['currentAPIService']
|
|
798
|
+
}] }, { type: i1.ZoneService }, { type: i2.NavigationService }, { type: i3.ViewerService }, { type: i4.Router }, { type: i5.MatterportService }, { type: i6.BaseVisibilityService }, { type: i7.ContentService }]; } });
|
|
799
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWNvcmUvc3JjL2xpYi9zZXJ2aWNlcy9tb2RlbHMvcGxhbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtCQUErQjtBQUMvQiwyQ0FBMkM7QUFDM0MsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUM5RCxPQUFPLE9BQU8sTUFBTSxTQUFTLENBQUM7QUFDOUIsT0FBTyxPQUFPLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFL0IsT0FBTyxFQUNILFdBQVcsRUFDWCxXQUFXLEVBRVgsT0FBTyxHQUVWLE1BQU0scUJBQXFCLENBQUM7QUFNN0IsT0FBTyxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHOUQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDOzs7Ozs7Ozs7QUFNeEQsTUFBTSxPQUFPLFdBQVc7SUEwRXBCLFlBQ2lDLFdBQWdCLEVBQ3JDLFdBQXdCLEVBQ3hCLGlCQUFvQztJQUM1Qyw4QkFBOEI7SUFDdEIsYUFBNEIsRUFDNUIsTUFBYyxFQUNkLGlCQUFvQztJQUM1Qyw2QkFBNkI7SUFDckIsaUJBQXdDLEVBQ3hDLGNBQThCO1FBUjlCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFFcEMsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLHNCQUFpQixHQUFq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U0FBUyxFQUFFLENBQUM7SUFDMUQsQ0FBQzs7d0dBcjlCUSxXQUFXLGtCQTJFUixtQkFBbUI7NEdBM0V0QixXQUFXLGNBRlIsTUFBTTsyRkFFVCxXQUFXO2tCQUh2QixVQUFVO21CQUFDO29CQUNSLFVBQVUsRUFBRSxNQUFNO2lCQUNyQjs7MEJBNEVRLE1BQU07MkJBQUMsbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgZnVuYy1uYW1lcyAqL1xyXG4vKiBlc2xpbnQtZGlzYWJsZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzICovXHJcbmltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBnZXREb2N1bWVudCwgR2xvYmFsV29ya2VyT3B0aW9ucyB9IGZyb20gJ3BkZmpzLWRpc3QnO1xyXG5pbXBvcnQgcGFuem9vbSBmcm9tICdwYW56b29tJztcclxuaW1wb3J0IHZpZGVvanMgZnJvbSBcInZpZGVvLmpzXCI7XHJcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuaW1wb3J0IHtcclxuICAgIENvbW1lbnRUeXBlLFxyXG4gICAgRmVhdHVyZVR5cGUsXHJcbiAgICBQbGFuLFxyXG4gICAgUG9pVHlwZSxcclxuICAgIFpvbmUsXHJcbn0gZnJvbSAnLi4vLi4vdHlwZXMuc2VydmljZSc7XHJcbmltcG9ydCB7IEJhc2VWaXNpYmlsaXR5U2VydmljZSB9IGZyb20gJy4uL2Jhc2VWaXNpYmlsaXR5LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBNYXR0ZXJwb3J0U2VydmljZSB9IGZyb20gJy4uL21hdHRlcnBvcnQuc2VydmljZSc7XHJcbmltcG9ydCB7IFZpZXdlclNlcnZpY2UgfSBmcm9tICcuLi92aWV3ZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IFpvbmVTZXJ2aWNlIH0gZnJvbSAnLi96b25lLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBOYXZpZ2F0aW9uU2VydmljZSB9IGZyb20gJy4vbmF2aWdhdGlvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgZ2V0U2lnbmVkRmlsZSwgdXBsb2FkRmlsZVRvUzMgfSBmcm9tICcuLi9zMy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQmFzZVRhZ1NlcnZpY2UgfSBmcm9tICcuLi90YWcuc2VydmljZSc7XHJcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4uLy4uL2NvbmZpZyc7XHJcbmltcG9ydCB7IGdldENvZWZmaWNpZW50c0ZvckltYWdlIH0gZnJvbSAnLi4vem9uZS1kcmF3ZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IGdldE1ldGFGb3JJbWFnZSB9IGZyb20gJy4uLy4uL2hlbHBlcnMuc2VydmljZSc7XHJcbmltcG9ydCB7IENvbnRlbnRTZXJ2aWNlIH0gZnJvbSAnLi4vY29udGVudC5zZXJ2aWNlJztcclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICAgIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIFBsYW5TZXJ2aWNlIHtcclxuICAgIGNob3NlblBsYW46IFBsYW47XHJcblxyXG4gICAgY3VycmVudFBsYW46IFBsYW47XHJcblxyXG4gICAgY3VycmVudFN3ZWVwOiBzdHJpbmc7XHJcblxyXG4gICAgcGxhbkZpbGVDYWNoZTogRmlsZTtcclxuXHJcbiAgICBwbGFuQ2FudmFzOiBhbnk7XHJcblxyXG4gICAgcGxhbkRpdjogSFRNTEVsZW1lbnQgfCBTVkdFbGVtZW50O1xyXG4gICAgcGxhbkRpdkNvbnRlbnQ6IEhUTUxFbGVtZW50O1xyXG5cclxuICAgIHBhbnpvb206IGFueTtcclxuXHJcbiAgICBpc1JlYWR5OiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gICAgdXNlclBvc2l0aW9uQnRuOiBIVE1MQnV0dG9uRWxlbWVudDtcclxuXHJcbiAgICBjb2VmZlBsYW5YOiBudW1iZXI7XHJcblxyXG4gICAgY29lZmZQbGFuWTogbnVtYmVyO1xyXG5cclxuICAgIGNhbGlicmF0aW9uUGxhbjogYW55O1xyXG5cclxuICAgIGRldGFpbFRhZ0RpdjogSFRNTEVsZW1lbnQ7XHJcblxyXG4gICAgZGV0YWlsVGFnRGl2SXNIb3ZlciA9IGZhbHNlO1xyXG5cclxuICAgIGJ0blRhZ0lzSG92ZXIgPSBmYWxzZTtcclxuXHJcbiAgICByZXNpemVQbGFuU3Vic2NyaXB0aW9uID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcclxuXHJcbiAgICBpbWdQbGFuOiBIVE1MSW1hZ2VFbGVtZW50O1xyXG5cclxuICAgIGxhc3RUb3VjaFRpbWUgPSAwO1xyXG5cclxuICAgIGRlbGF5RGJsVG91Y2ggPSA1MDA7XHJcblxyXG4gICAgbGFzdFJvdGF0aW9uOiBudW1iZXIgPSAwO1xyXG5cclxuICAgIGh0bWxDb250ZW50VG9JbmplY3Q6IHtcclxuICAgICAgICB0aXRsZTogc3RyaW5nO1xyXG4gICAgICAgIGNvbnRlbnQ6IHN0cmluZztcclxuICAgICAgICBlbGVtZW50SUQ6IHN0cmluZztcclxuICAgICAgICB5OiBudW1iZXI7XHJcbiAgICAgICAgeDogbnVtYmVyO1xyXG4gICAgICAgIHRhZ0ljb246IHN0cmluZztcclxuICAgICAgICB1cmw6IHN0cmluZztcclxuICAgIH1bXSA9IFtdO1xyXG5cclxuICAgIGNhY2hlOiB7XHJcbiAgICAgICAgZXF1aXBJRHM6IHN0cmluZ1tdO1xyXG4gICAgICAgIHRpY2tldElEczogc3RyaW5nW107XHJcbiAgICAgICAgbWVhc3VyZW1lbnRzSURzOiBzdHJpbmdbXTtcclxuICAgICAgICBmZWF0dXJlSURzOiBzdHJpbmdbXTtcclxuICAgICAgICB6b25lSUQ6IHN0cmluZztcclxuICAgICAgICBwbGFuOiBQbGFuO1xyXG4gICAgICAgIGh0bWxDb250ZW50OiB7XHJcbiAgICAgICAgICAgIHRpdGxlOiBzdHJpbmc7XHJcbiAgICAgICAgICAgIGNvbnRlbnQ6IHN0cmluZztcclxuICAgICAgICAgICAgZWxlbWVudElEOiBzdHJpbmc7XHJcbiAgICAgICAgICAgIHk6IG51bWJlcjtcclxuICAgICAgICAgICAgeDogbnVtYmVyO1xyXG4gICAgICAgICAgICB0YWdJY29uOiBzdHJpbmc7XHJcbiAgICAgICAgICAgIHVybDogc3RyaW5nO1xyXG4gICAgICAgIH1bXTtcclxuICAgIH07XHJcblxyXG4gICAgZm9jdXNNb3VzZVRhZ0RpdjogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIEFQSTogYW55OyAvL0FXU1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIEBJbmplY3QoJ2N1cnJlbnRBUElTZXJ2aWNlJykgYXBpSW5qZWN0ZWQ6IGFueSxcclxuICAgICAgICBwcml2YXRlIHpvbmVTZXJ2aWNlOiBab25lU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIG5hdmlnYXRpb25TZXJ2aWNlOiBOYXZpZ2F0aW9uU2VydmljZSxcclxuICAgICAgICAvLyB0YWdTZXJ2aWNlOiBCYXNlVGFnU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIHZpZXdlclNlcnZpY2U6IFZpZXdlclNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcclxuICAgICAgICBwcml2YXRlIG1hdHRlcnBvcnRTZXJ2aWNlOiBNYXR0ZXJwb3J0U2VydmljZSxcclxuICAgICAgICAvLyBwcml2YXRlIGNvbmZpZzogQXBwQ29uZmlnLFxyXG4gICAgICAgIHByaXZhdGUgdmlzaWJpbGl0eVNlcnZpY2U6IEJhc2VWaXNpYmlsaXR5U2VydmljZSxcclxuICAgICAgICBwcml2YXRlIGNvbnRlbnRTZXJ2aWNlOiBDb250ZW50U2VydmljZVxyXG4gICAgKSB7XHJcbiAgICAgICAgdGhpcy5BUEkgPSBhcGlJbmplY3RlZDtcclxuICAgICAgICB0aGlzLm1hdHRlcnBvcnRTZXJ2aWNlLmN1cnJlbnRDYW1lcmFQb3NlLnN1YnNjcmliZSgocG9zZSkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVJvdGF0aW9uKHBvc2Uucm90YXRpb24ueSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgY3JlYXRlUGxhbihwbGFuSW5wdXQ6IFBsYW4pOiBQcm9taXNlPFBsYW4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5BUEkuX19wcm90b19fLkNyZWF0ZVBsYW4ocGxhbklucHV0KTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBkZWxldGVQbGFuKHBsYW46IFBsYW4pOiBQcm9taXNlPFBsYW4+IHtcclxuICAgICAgICAvLyBhd2FpdCBkZWxldGVGcm9tUzMocGxhbi5hbm5leGUpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLkFQSS5fX3Byb3RvX18uRGVsZXRlUGxhbih7IGlkOiBwbGFuLmlkIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGdldFBsYW5zRm9yU3BhY2Uoc3BhY2VJRDogc3RyaW5nKTogUHJvbWlzZTxQbGFuW10+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5BUEkuX19wcm90b19fXHJcbiAgICAgICAgICAgIC5QbGFuc0J5U3BhY2Uoc3BhY2VJRClcclxuICAgICAgICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5pdGVtcyk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgZ2V0UGxhbnNGb3Jab25lKHpvbmVJRDogc3RyaW5nKTogUHJvbWlzZTxQbGFuW10+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5BUEkuX19wcm90b19fXHJcbiAgICAgICAgICAgIC5QbGFuc0J5Wm9uZSh6b25lSUQpXHJcbiAgICAgICAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuaXRlbXMpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGdldFNpbmdlZFBsYW5zRm9yU3BhY2Uoc3BhY2VJRDogc3RyaW5nKTogUHJvbWlzZTxQbGFuW10+IHtcclxuICAgICAgICBjb25zdCBwbGFuc0Zyb21EQiA9IGF3YWl0IHRoaXMuZ2V0UGxhbnNGb3JTcGFjZShzcGFjZUlEKTtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZyhwbGFuc0Zyb21EQik7XHJcbiAgICAgICAgY29uc3QgcGxhbnMgPSBbXTtcclxuICAgICAgICBpZiAocGxhbnNGcm9tREIubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChcclxuICAgICAgICAgICAgICAgIHBsYW5zRnJvbURCLm1hcChhc3luYyAocGxhbikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBsYW5PYmplY3QgPSB7IC4uLnBsYW4gfSBhcyBQbGFuO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGFubmV4ZSBsb29rcyBsaWtlIHZpc2l0cy9tb2RlbElEL3BsYW5zL2ZpbGUuZXh0ZW5zaW9uXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2lnbmVkID0gYXdhaXQgZ2V0U2lnbmVkRmlsZShwbGFuLmFubmV4ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpZ25lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGFuT2JqZWN0LmZpbGVwYXRoID0gc2lnbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAocGxhbi5hbm5leGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgWywgbW9kZWxJRCwgLCBmaWxlbmFtZVdpdGhFeHRlbnNpb25dID0gcGxhbi5hbm5leGUuc3BsaXQoJy8nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgWywgZXh0ZW50aW9uXSA9IGZpbGVuYW1lV2l0aEV4dGVuc2lvbi5zcGxpdCgnLicpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGFuT2JqZWN0Lm1vZGVsM2QgPSBtb2RlbElEO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGFuT2JqZWN0LmV4dGVuc2lvbiA9IGV4dGVudGlvbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhbnMucHVzaChwbGFuT2JqZWN0KTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgRXJyb3IgcGxhbiBoYXZlIG5vdCBhbm5leGUgPT4gYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHBsYW4uaWQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwbGFucztcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBnZXRQbGFuc1dpdGhab25lc0ZvclNwYWNlKHNwYWNlSUQ6IHN0cmluZyk6IFByb21pc2U8UGxhbltdPiB7XHJcbiAgICAgICAgY29uc3QgcGxhbnMgPSBhd2FpdCB0aGlzLmdldFBsYW5zRm9yU3BhY2Uoc3BhY2VJRCk7XHJcbiAgICAgICAgY29uc3QgcGxhbnNab25lcyA9IHBsYW5zLmZpbHRlcigocGxhbikgPT4gcGxhbi56b25lICYmIHBsYW4uY2FsaWJyYXRpb24pO1xyXG4gICAgICAgIHJldHVybiBwbGFuc1pvbmVzO1xyXG4gICAgfVxyXG5cclxuICAgIHNldENob3NlblBsYW4oY2hvc2VuUGxhbjogUGxhbikge1xyXG4gICAgICAgIHRoaXMuY2hvc2VuUGxhbiA9IGNob3NlblBsYW47XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0Q2hvc2VuUGxhbigpOiBQbGFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jaG9zZW5QbGFuO1xyXG4gICAgfVxyXG5cclxuICAgIHNldFBsYW5GaWxlQ2FjaGUocGxhbkZpbGVDYWNoZTogRmlsZSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHRoaXMucGxhbkZpbGVDYWNoZSA9IHBsYW5GaWxlQ2FjaGU7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFBsYW5GaWxlQ2FjaGUoKTogRmlsZSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucGxhbkZpbGVDYWNoZTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBjcmVhdGVQbGFuV2l0aEFubmV4ZShwbGFuOiBQbGFuLCBmaWxlOiBGaWxlKTogUHJvbWlzZTxQbGFuPiB7XHJcbiAgICAgICAgY29uc3QgY3JlYXRlZFBsYW4gPSBhd2FpdCB0aGlzLmNyZWF0ZVBsYW4ocGxhbik7XHJcbiAgICAgICAgY29uc3QgbW9kZWwzRCA9IGF3YWl0IHRoaXMuem9uZVNlcnZpY2UuZ2V0TW9kZWwzREZvclpvbmUocGxhbi56b25lSUQpO1xyXG4gICAgICAgIGNvbnN0IHVybCA9IGF3YWl0IHVwbG9hZEZpbGVUb1MzKFxyXG4gICAgICAgICAgICBgdmlzaXRzLyR7bW9kZWwzRH0vcGxhbnMvYCxcclxuICAgICAgICAgICAgZmlsZSxcclxuICAgICAgICAgICAgY3JlYXRlZFBsYW4uaWRcclxuICAgICAgICApO1xyXG4gICAgICAgIGlmICh1cmwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuQVBJLl9fcHJvdG9fXy5VcGRhdGVQbGFuKHsgaWQ6IGNyZWF0ZWRQbGFuLmlkLCBhbm5leGU6IHVybCB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGNyZWF0ZWRQbGFuO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHVwZGF0ZVBsYW4ocGxhbjogYW55KTogUHJvbWlzZTxQbGFuPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuQVBJLl9fcHJvdG9fXy5VcGRhdGVQbGFuKHBsYW4pO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHVwZGF0ZVBsYW5GaWxlKCk6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICAgICAgaWYgKHRoaXMuY2hvc2VuUGxhbiAmJiB0aGlzLnBsYW5GaWxlQ2FjaGUpIHtcclxuICAgICAgICAgICAgY29uc3QgbW9kZWwzRCA9IGF3YWl0IHRoaXMuem9uZVNlcnZpY2UuZ2V0TW9kZWwzREZvclpvbmUoXHJcbiAgICAgICAgICAgICAgICB0aGlzLmNob3NlblBsYW4uem9uZUlEXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIHJldHVybiB1cGxvYWRGaWxlVG9TMyhcclxuICAgICAgICAgICAgICAgIGB2aXNpdHMvJHttb2RlbDNEfS9wbGFucy9gLFxyXG4gICAgICAgICAgICAgICAgdGhpcy5wbGFuRmlsZUNhY2hlLFxyXG4gICAgICAgICAgICAgICAgdGhpcy5jaG9zZW5QbGFuLmlkXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHNldEFsbFBsYW5zRm9yWm9uZU5vdEN1cnJlbnQoem9uZUlEOiBzdHJpbmcsIGN1cnJlbnRQbGFuSUQ6IHN0cmluZykge1xyXG4gICAgICAgIGNvbnN0IHBsYW5zID0gYXdhaXQgdGhpcy5BUEkuX19wcm90b19fLkxpc3RQbGFucyh7XHJcbiAgICAgICAgICAgIHpvbmVJRDogeyBlcTogem9uZUlEIH0sXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXHJcbiAgICAgICAgICAgIHBsYW5zLml0ZW1zLm1hcChhc3luYyAocGxhbikgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHBsYW4uaXNDdXJyZW50Rm9yWm9uZSAmJiBwbGFuLmlkICE9PSBjdXJyZW50UGxhbklEKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVQbGFuKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IHBsYW4uaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQ3VycmVudEZvclpvbmU6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgY29uZmlndXJlUGxhbihcclxuICAgICAgICBjdXJyZW50UGxhbjogUGxhbixcclxuICAgICAgICBkaXZJZDogc3RyaW5nID0gJ3BsYW5EaXZQYW5lJyxcclxuICAgICAgICBkaXZDb250ZW50SWQ6IHN0cmluZyA9ICdwbGFuRGl2UGFuZUNvbnRlbnQnXHJcbiAgICApOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgICAgICB0aGlzLmlzUmVhZHkgPSBmYWxzZTtcclxuICAgICAgICBpZiAoIXRoaXMuZGV0YWlsVGFnRGl2KSB7XHJcbiAgICAgICAgICAgIHRoaXMuZGV0YWlsVGFnRGl2ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcclxuICAgICAgICAgICAgICAgIGAjZGV0YWlsVGFnRGl2YFxyXG4gICAgICAgICAgICApIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmRldGFpbFRhZ0Rpdi5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWVudGVyJywgKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmZvY3VzTW91c2VUYWdEaXYgPSB0cnVlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuZGV0YWlsVGFnRGl2LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCAoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuYnRuVGFnSXNIb3ZlciA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLmRldGFpbFRhZ0Rpdi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgICAgICB0aGlzLmZvY3VzTW91c2VUYWdEaXYgPSBmYWxzZTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5jYWxpYnJhdGlvblBsYW4gPSBKU09OLnBhcnNlKGN1cnJlbnRQbGFuLmNhbGlicmF0aW9uKTtcclxuICAgICAgICB0aGlzLmN1cnJlbnRQbGFuID0gY3VycmVudFBsYW47XHJcbiAgICAgICAgdGhpcy5wbGFuRGl2ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgIyR7ZGl2SWR9YCkgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgdGhpcy5wbGFuRGl2Q29udGVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXHJcbiAgICAgICAgICAgIGAjJHtkaXZDb250ZW50SWR9YFxyXG4gICAgICAgICkgYXMgSFRNTEVsZW1lbnQ7XHJcblxyXG4gICAgICAgIHRoaXMucGxhbkRpdi5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgdGhpcy5oYW5kbGVUb3VjaC5iaW5kKHRoaXMpKTtcclxuICAgICAgICB0aGlzLnBsYW5EaXYuYWRkRXZlbnRMaXN0ZW5lcignZGJsY2xpY2snLCB0aGlzLm9uRGJsQ2xpY2tQbGFuLmJpbmQodGhpcykpO1xyXG5cclxuICAgICAgICBpZiAoIWN1cnJlbnRQbGFuLmFubmV4ZS5pbmNsdWRlcygncGRmJykpIHtcclxuICAgICAgICAgICAgdGhpcy5pbWdQbGFuID0gYXdhaXQgZ2V0TWV0YUZvckltYWdlKGN1cnJlbnRQbGFuLmZpbGVwYXRoKTtcclxuICAgICAgICAgICAgLy9SZWN0IHVzZSBvZmZzZXRXaWR0aCA6IGhlaWdodCwgbm90IGFjdHVhbCBib3VuZGluZ0NsaWVudFJlY3QgYmVjYXVzZSB3aWxsIGJlIG1vZGlmaWVkIGJ5IHRoZSB6b29tLlxyXG4gICAgICAgICAgICBjb25zdCByZWN0ID0ge1xyXG4gICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMucGxhbkRpdkNvbnRlbnQub2Zmc2V0V2lkdGgsXHJcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMucGxhbkRpdkNvbnRlbnQub2Zmc2V0SGVpZ2h0LFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBjb25zdCB7IGNvZWZmWCwgY29lZmZZIH0gPSBnZXRDb2VmZmljaWVudHNGb3JJbWFnZSh0aGlzLmltZ1BsYW4sIHJlY3QpO1xyXG4gICAgICAgICAgICB0aGlzLmNvZWZmUGxhblggPSBjb2VmZlg7XHJcbiAgICAgICAgICAgIHRoaXMuY29lZmZQbGFuWSA9IGNvZWZmWTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMucGxhbkRpdkNvbnRlbnQuc3R5bGUuYmFja2dyb3VuZEltYWdlID0gYHVybCgke2N1cnJlbnRQbGFuLmZpbGVwYXRofSlgO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZHJhd1BkZihjdXJyZW50UGxhbik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMucGxhbkRpdkNvbnRlbnQuc3R5bGUuYmFja2dyb3VuZFNpemUgPSAnY29udGFpbic7XHJcbiAgICAgICAgdGhpcy5wbGFuRGl2Q29udGVudC5zdHlsZS5iYWNrZ3JvdW5kUmVwZWF0ID0gJ25vLXJlcGVhdCc7XHJcblxyXG4gICAgICAgIHRoaXMucGFuem9vbSA9IHBhbnpvb20odGhpcy5wbGFuRGl2LCB7XHJcbiAgICAgICAgICAgIGJvdW5kczogdHJ1ZSxcclxuICAgICAgICAgICAgYm91bmRzUGFkZGluZzogMCxcclxuICAgICAgICAgICAgbWF4Wm9vbTogNCxcclxuICAgICAgICAgICAgem9vbURvdWJsZUNsaWNrU3BlZWQ6IDEsIC8vZGlzYWJsZXMgZG91YmxlIGNsaWNrIHpvb21cclxuICAgICAgICAgICAgLy9pbml0aWFsWm9vbTogNFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMucGFuem9vbS56b29tQWJzKDAsIDAsIDQpO1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVJvdGF0aW9uKHRoaXMubGFzdFJvdGF0aW9uKTtcclxuICAgICAgICB9LCAyMDApO1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGNsZWFyUGxhbkltYWdlKCkge1xyXG4gICAgICAgIGlmICh0aGlzLnBsYW5EaXZDb250ZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMucGxhbkRpdkNvbnRlbnQuc3R5bGUuYmFja2dyb3VuZEltYWdlID0gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgZHJhd1BkZihjdXJyZW50UGxhbjogUGxhbik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKSBhcyBIVE1MQ2FudmFzRWxlbWVudDtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKSBhcyBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XHJcbiAgICAgICAgICAgIGNvbnN0IHBkZmpzV29ya2VyID0gYXdhaXQgaW1wb3J0KCdwZGZqcy1kaXN0L2J1aWxkL3BkZi53b3JrZXIuZW50cnknKTtcclxuXHJcbiAgICAgICAgICAgIEdsb2JhbFdvcmtlck9wdGlvbnMud29ya2VyU3JjID0gcGRmanNXb3JrZXI7XHJcbiAgICAgICAgICAgIGNvbnN0IHBkZiA9IGF3YWl0IGdldERvY3VtZW50KGN1cnJlbnRQbGFuLmZpbGVwYXRoKS5wcm9taXNlO1xyXG4gICAgICAgICAgICBjb25zdCBwYWdlID0gYXdhaXQgcGRmLmdldFBhZ2UoMSk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCB2aWV3UG9ydFBhcmFtZXRlcnMgPSB7IHNjYWxlOiAxLjUgfTtcclxuICAgICAgICAgICAgY29uc3Qgdmlld3BvcnQgPSBwYWdlLmdldFZpZXdwb3J0KHZpZXdQb3J0UGFyYW1ldGVycyk7XHJcblxyXG4gICAgICAgICAgICBjYW52YXMuaGVpZ2h0ID0gdmlld3BvcnQuaGVpZ2h0O1xyXG4gICAgICAgICAgICBjYW52YXMud2lkdGggPSB2aWV3cG9ydC53aWR0aDtcclxuICAgICAgICAgICAgY29uc3QgcmVuZGVyQ29udGV4dCA9IHtcclxuICAgICAgICAgICAgICAgIGNhbnZhc0NvbnRleHQ6IGNvbnRleHQsXHJcbiAgICAgICAgICAgICAgICB2aWV3cG9ydCxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgY29uc3QgcmVuZGVyVGFzayA9IHBhZ2UucmVuZGVyKHJlbmRlckNvbnRleHQpLnByb21pc2U7XHJcbiAgICAgICAgICAgIHJlbmRlclRhc2sudGhlbihhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpbWdVcmwgPSBjYW52YXMudG9EYXRhVVJMKCdpbWFnZS9wbmcnKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuaW1nUGxhbiA9IGF3YWl0IGdldE1ldGFGb3JJbWFnZShpbWdVcmwpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmVjdCA9IHtcclxuICAgICAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy5wbGFuRGl2Q29udGVudC5vZmZzZXRXaWR0aCxcclxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMucGxhbkRpdkNvbnRlbnQub2Zmc2V0SGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHsgY29lZmZYLCBjb2VmZlkgfSA9IGdldENvZWZmaWNpZW50c0ZvckltYWdlKHRoaXMuaW1nUGxhbiwgcmVjdCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvZWZmUGxhblggPSBjb2VmZlg7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvZWZmUGxhblkgPSBjb2VmZlk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBsYW5EaXYuc3R5bGUuYmFja2dyb3VuZEltYWdlID0gYHVybCgke2ltZ1VybH0pYDtcclxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgZHJhd0VsZW1lbnQoXHJcbiAgICAgICAgZWxlbWVudDogYW55LFxyXG4gICAgICAgIHRhZ1R5cGU6IFBvaVR5cGUsXHJcbiAgICAgICAgY3VycmVudFBsYW46IFBsYW4sXHJcbiAgICAgICAgdGFnU2VydmljZTogQmFzZVRhZ1NlcnZpY2UsXHJcbiAgICAgICAgY29uZmlnOiBDb25maWcsXHJcbiAgICAgICAgc2l6ZUJ1dHRvbjogbnVtYmVyID0gMTBcclxuICAgICkge1xyXG4gICAgICAgIGNvbnN0IFtwb2ldID0gZWxlbWVudC5wb2lzLml0ZW1zO1xyXG4gICAgICAgIGlmIChwb2kgJiYgcG9pLmNvb3JkaW5hdGUgJiYgY3VycmVudFBsYW4pIHtcclxuICAgICAgICAgICAgY29uc3QgeyB6b25lIH0gPSBjdXJyZW50UGxhbjtcclxuICAgICAgICAgICAgaWYgKHpvbmUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gSlNPTi5wYXJzZShwb2kuY29vcmRpbmF0ZSk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBidXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcclxuICAgICAgICAgICAgICAgIGxldCBlbGVtZW50VGl0bGU6IHN0cmluZztcclxuICAgICAgICAgICAgICAgIGNvbnN0IHVybCA9IHRhZ1NlcnZpY2UuZ2V0VXJsRm9yU2VlRGV0YWlscyhlbGVtZW50LCB0YWdUeXBlKTtcclxuICAgICAgICAgICAgICAgIGxldCB0YWdJY29uSW1hZ2U6IHN0cmluZztcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnVHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgUG9pVHlwZS5USUNLRVQ6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFnSWNvbkltYWdlID0gY29uZmlnLm15X2NvbmZpZy5pY29uX3RpY2tldDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgUG9pVHlwZS5FUVVJUE1FTlQ6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFnSWNvbkltYWdlID0gY29uZmlnLm15X2NvbmZpZy5pY29uX2VxdWlwbWVudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgUG9pVHlwZS5NRUFTVVJFOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdJY29uSW1hZ2UgPSBjb25maWcubXlfY29uZmlnLmljb25fbWVhc3VyZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBQb2lUeXBlLk9CSkVDVDNEOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdJY29uSW1hZ2UgPSBjb25maWcubXlfY29uZmlnLmljb25fb2JqZWN0M2Q7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgUG9pVHlwZS5EQVRBOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdJY29uSW1hZ2UgPSBjb25maWcubXlfY29uZmlnLmljb25fZGF0YTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBQb2lUeXBlLkRFU0s6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhZ0ljb25JbWFnZSA9IGNvbmZpZy5teV9jb25maWcuaWNvbl9kYXRhO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocG9pLnRhZ0ljb24pIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0YWdJY29uID0gSlNPTi5wYXJzZShwb2kudGFnSWNvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdUeXBlID09PSBQb2lUeXBlLkRBVEEgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC50eXBlID09PSBGZWF0dXJlVHlwZS5JTkRJQ0FUT1JfVEVNUFxyXG4gICAgICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdJY29uLnNyYyA9IHRhZ1NlcnZpY2UuZ2V0SWNvblRhZ0ltYWdlRm9yRmVhdHVyZShlbGVtZW50LCBwb2kpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyBwb2kudGFnSWNvbiA9IHRhZ0ljb247XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0YWdJY29uLnNyYykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2UgPSBhd2FpdCBnZXRTaWduZWRGaWxlKHRhZ0ljb24uc3JjKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNvdXJjZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnSWNvbkltYWdlID0gc291cmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5zdHlsZUJ1dHRvbihidXR0b24sIHRhZ0ljb25JbWFnZSwgc2l6ZUJ1dHRvbik7XHJcbiAgICAgICAgICAgICAgICBidXR0b24uaWQgPSBlbGVtZW50LmlkO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wbGFuRGl2Q29udGVudC5hcHBlbmQoYnV0dG9uKTtcclxuICAgICAgICAgICAgICAgIGxldCB4OiBudW1iZXI7XHJcbiAgICAgICAgICAgICAgICBsZXQgeTogbnVtYmVyO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY2FsaWJyYXRpb25QbGFuLm5ldykge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGFsZXJ0KFwibmV3IGNhbGlicmF0aW9uIHBsYW46IHBvc2l0aW9uaW5nIG5vdCByZWFkeSB5ZXRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpb24yRCA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJhbnNmb3JtUG9zaXRpb24zREZvck5ld0NhbGlicmF0aW9uKHBvc2l0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICB4ID0gcG9zaXRpb24yRC54O1xyXG4gICAgICAgICAgICAgICAgICAgIHkgPSBwb3NpdGlvbjJELnk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnV0dG9uLnN0eWxlLnRvcCA9IGAke3kgLyBwb3NpdGlvbjJELmNvZWZmWSAtIDV9cHhgO1xyXG4gICAgICAgICAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS5sZWZ0ID0gYCR7eCAvIHBvc2l0aW9uMkQuY29lZmZYIC0gNX1weGA7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHRvIHJlbW92ZSB3aGVuIGFsbCBjYWxpYnJhdGlvbnMgYXJlIG5ld1xyXG4gICAgICAgICAgICAgICAgICAgIHggPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbGlicmF0aW9uUGxhbi5vZmZzZXRYICsgcG9zaXRpb24ueCAqIHRoaXMuY2FsaWJyYXRpb25QbGFuLng7XHJcbiAgICAgICAgICAgICAgICAgICAgeSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2FsaWJyYXRpb25QbGFuLm9mZnNldFkgKyBwb3NpdGlvbi56ICogdGhpcy5jYWxpYnJhdGlvblBsYW4ueTtcclxuICAgICAgICAgICAgICAgICAgICBidXR0b24uc3R5bGUudG9wID0gYCR7eSAvIHRoaXMuY29lZmZQbGFuWSAtIDV9cHhgO1xyXG4gICAgICAgICAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS5sZWZ0ID0gYCR7eCAvIHRoaXMuY29lZmZQbGFuWCAtIDV9cHhgO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGh0bWwgPSBhd2FpdCB0YWdTZXJ2aWNlLmdldEh0bWxUb0luamVjdCh0YWdUeXBlLCBlbGVtZW50KTtcclxuICAgICAgICAgICAgICAgIGlmIChodG1sICE9ICcnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5odG1sQ29udGVudFRvSW5qZWN0LnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50SUQ6IGVsZW1lbnQuaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogaHRtbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgeSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgeCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFnSWNvbjogdGFnSWNvbkltYWdlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cmwsXHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHdoZW4gd2UgZG9uJ3QgaGF2ZSBodG1sID0+IGNhc2Ugb2YgRU1CRUQgQ29tbWVudCB0eXBlXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29tbWVudEVtYmVkID0gZWxlbWVudC5jb21tZW50cz8uaXRlbXMuZmluZChcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNvbSkgPT4gY29tLnR5cGUgPT09IENvbW1lbnRUeXBlLkVNQkVEICYmIGNvbS5zaG93bkluVGFnXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWVudEVtYmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaHRtbENvbnRlbnRUb0luamVjdC5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRJRDogZWxlbWVudC5pZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBlbGVtZW50LnRpdGxlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogYDxpZnJhbWUgc3JjPSR7Y29tbWVudEVtYmVkLmV4dGVybmFsTGlua30gaGVpZ2h0PVwiMjAwcHhcIiB3aWR0aD1cIjEwMCVcIj48L2lmcmFtZT5gLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWdJY29uOiB0YWdJY29uSW1hZ2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmFkZExpc3RlbmVyc1RvQnV0dG9uKGJ1dHRvbiwgdXJsLCB0YWdTZXJ2aWNlLCBlbGVtZW50KTtcclxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlUm90YXRpb24odGhpcy5sYXN0Um90YXRpb24pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGRyYXdVc2VyUG9zaXRpb24oY3VycmVudFN3ZWVwID0gdGhpcy5jdXJyZW50U3dlZXAsIHNpemVCdXR0b246IG51bWJlciA9IDEwKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50U3dlZXAgPSBjdXJyZW50U3dlZXA7XHJcbiAgICAgICAgaWYgKHRoaXMuY2FsaWJyYXRpb25QbGFuICYmIGN1cnJlbnRTd2VlcCkge1xyXG4gICAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9XHJcbiAgICAgICAgICAgICAgICB0aGlzLm1hdHRlcnBvcnRTZXJ2aWNlLmdldEN1cnJlbnRDYW1lcmFQb3NpdGlvbigpPy5wb3NpdGlvbjtcclxuICAgICAgICAgICAgaWYgKHBvc2l0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMudXNlclBvc2l0aW9uQnRuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51c2VyUG9zaXRpb25CdG4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVzZXJQb3NpdGlvbkJ0bi5pZCA9ICdjdXJyZW50UG9zaXRpb24nO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhbkRpdkNvbnRlbnQuYXBwZW5kKHRoaXMudXNlclBvc2l0aW9uQnRuKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVzZXJQb3NpdGlvbkJ0bi50aXRsZSA9ICdZb3UgYXJlIGhlcmUnO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3R5bGVCdXR0b24oXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXNlclBvc2l0aW9uQnRuLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAnaHR0cHM6Ly9hcGkuaWNvbmlmeS5kZXNpZ24vYng6YnhzLXVzZXItY2lyY2xlLnN2Zz9jb2xvcj1ncmVlbiZoZWlnaHQ9MTcmd2lkdGg9MTcnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplQnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxldCB4OiBudW1iZXI7XHJcbiAgICAgICAgICAgICAgICBsZXQgeTogbnVtYmVyO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY2FsaWJyYXRpb25QbGFuLm5ldykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uMkQgPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyYW5zZm9ybVBvc2l0aW9uM0RGb3JOZXdDYWxpYnJhdGlvbihwb3NpdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgeCA9IHBvc2l0aW9uMkQueCAvIHBvc2l0aW9uMkQuY29lZmZYIC0gNTtcclxuICAgICAgICAgICAgICAgICAgICB5ID0gcG9zaXRpb24yRC55IC8gcG9zaXRpb24yRC5jb2VmZlkgLSA1O1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB4ID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgKHRoaXMuY2FsaWJyYXRpb25QbGFuLm9mZnNldFggK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24ueCAqIHRoaXMuY2FsaWJyYXRpb25QbGFuLngpIC9cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb2VmZlBsYW5YO1xyXG4gICAgICAgICAgICAgICAgICAgIHkgPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAodGhpcy5jYWxpYnJhdGlvblBsYW4ub2Zmc2V0WSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbi56ICogdGhpcy5jYWxpYnJhdGlvblBsYW4ueSkgL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvZWZmUGxhblk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLnVzZXJQb3NpdGlvbkJ0bi5zdHlsZS50b3AgPSBgJHt5fXB4YDtcclxuICAgICAgICAgICAgICAgIHRoaXMudXNlclBvc2l0aW9uQnRuLnN0eWxlLmxlZnQgPSBgJHt4fXB4YDtcclxuICAgICAgICAgICAgICAgIHRoaXMubW92ZU9uUG9pbnQoeyB4OiB4ICsgNSwgeTogeSArIDUgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDZW50ZXIgdGhlIHZpZXcgb2YgdGhlIHBsYW4gb24gY29vcmRpbmF0ZXNcclxuICAgICAqIEBwYXJhbSBjb29yZGluYXRlIENvb3JkaW5hdGUgb24gdGhlIHBsYW5cclxuICAgICAqL1xyXG4gICAgbW92ZU9uUG9pbnQoY29vcmRpbmF0ZSkge1xyXG4gICAgICAgIGlmICh0aGlzLnBsYW5EaXYpIHtcclxuICAgICAgICAgICAgY29uc3Qgc2NhbGUgPSB0aGlzLnBhbnpvb20uZ2V0VHJhbnNmb3JtKCkuc2NhbGU7XHJcbiAgICAgICAgICAgIGNvbnN0IG1vdmVYID0gdGhpcy5wbGFuRGl2LmNsaWVudFdpZHRoIC8gMiAtIGNvb3JkaW5hdGUueCAqIHNjYWxlO1xyXG4gICAgICAgICAgICBjb25zdCBtb3ZlWSA9IHRoaXMucGxhbkRpdi5jbGllbnRIZWlnaHQgLyAyIC0gY29vcmRpbmF0ZS55ICogc2NhbGU7XHJcbiAgICAgICAgICAgIHRoaXMucGFuem9vbS5tb3ZlVG8obW92ZVgsIG1vdmVZKTtcclxuICAgICAgICAgICAgdGhpcy5wbGFuRGl2Q29udGVudC5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSBgJHtjb29yZGluYXRlLnh9cHggJHtjb29yZGluYXRlLnl9cHhgO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGx5IGEgcm90YXRpb24gdG8gdGhlIHBsYW5cclxuICAgICAqIEJ1dHRvbnMgd2lsbCByZW1haW4gaW4gdGhlIGNvcnJlY3Qgcm90YXRpb25cclxuICAgICAqIEBwYXJhbSByb3RhdGlvblxyXG4gICAgICovXHJcbiAgICB1cGRhdGVSb3RhdGlvbihyb3RhdGlvbikge1xyXG4gICAgICAgIHRoaXMubGFzdFJvdGF0aW9uID0gcm90YXRpb247XHJcbiAgICAgICAgaWYgKHRoaXMucGxhbkRpdkNvbnRlbnQpIHtcclxuICAgICAgICAgICAgdGhpcy5wbGFuRGl2Q29udGVudC5zdHlsZS50cmFuc2Zvcm0gPSBgcm90YXRlKCR7cm90YXRpb259ZGVnKWA7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1dHRvbnMgPSB0aGlzLnBsYW5EaXZDb250ZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2J1dHRvbicpO1xyXG4gICAgICAgICAgICBsZXQgcm90YXRpb25SZWdleCA9IC8ocm90YXRlXFwoLT9cXGQqXFwuP1xcZCtkZWdcXCkpL2c7XHJcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB1bmljb3JuL25vLWFycmF5LWZvci1lYWNoXHJcbiAgICAgICAgICAgIGJ1dHRvbnMuZm9yRWFjaCgoYnV0dG9uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBidXR0b24uc3R5bGUudHJhbnNmb3JtID0gYnV0dG9uLnN0eWxlLnRyYW5zZm9ybS5yZXBsYWNlKHJvdGF0aW9uUmVnZXgsIFwiXCIpICsgYCByb3RhdGUoJHstcm90YXRpb259ZGVnKWA7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZW1vdmVDdXJyZW50UG9zaXRpb24oKSB7XHJcbiAgICAgICAgY29uc3QgYnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2N1cnJlbnRQb3NpdGlvbicpO1xyXG4gICAgICAgIGlmIChidXR0b24pIHtcclxuICAgICAgICAgICAgYnV0dG9uLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICB0aGlzLnVzZXJQb3NpdGlvbkJ0biA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0eWxlQnV0dG9uKGJ1dHRvbjogSFRNTEJ1dHRvbkVsZW1lbnQsIHVybDogc3RyaW5nLCBzaXplQnV0dG9uOiBudW1iZXIgPSAxMCkge1xyXG4gICAgICAgIGJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UgPSBgdXJsKCR7dXJsfSlgO1xyXG4gICAgICAgIGJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAndHJhbnNwYXJlbnQnO1xyXG4gICAgICAgIGJ1dHRvbi5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XHJcbiAgICAgICAgYnV0dG9uLnN0eWxlLmJvcmRlciA9ICdub25lJztcclxuICAgICAgICBidXR0b24uc3R5bGUud2lkdGggPSBgMTBweGA7XHJcbiAgICAgICAgYnV0dG9uLnN0eWxlLmhlaWdodCA9IGAxMHB4YDtcclxuICAgICAgICBidXR0b24uZGlzYWJsZWQgPSBmYWxzZTtcclxuICAgICAgICBidXR0b24uc3R5bGUuYmFja2dyb3VuZFNpemUgPSAnY29udGFpbic7XHJcbiAgICAgICAgYnV0dG9uLnN0eWxlLmJhY2tncm91bmRSZXBlYXQgPSAnbm8tcmVwZWF0JztcclxuICAgICAgICBidXR0b24uc3R5bGUudHJhbnNmb3JtID0gYHNjYWxlKCR7c2l6ZUJ1dHRvbi8xMH0pYFxyXG4gIH1cclxuXHJcbiAgICBhZGRMaXN0ZW5lcnNUb0J1dHRvbihcclxuICAgICAgICBidXR0b246IEhUTUxCdXR0b25FbGVtZW50LFxyXG4gICAgICAgIHVybDogc3RyaW5nLFxyXG4gICAgICAgIHRhZ1NlcnZpY2U6IEJhc2VUYWdTZXJ2aWNlID0gbnVsbCxcclxuICAgICAgICBlbGVtZW50OiBhbnkgPSBudWxsXHJcbiAgICApIHtcclxuICAgICAgICBsZXQgdmlkZW9Kc1BsYXllcjtcclxuICAgICAgICBidXR0b24uYWRkRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsIGFzeW5jIChldmVudCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBjb250ZW50Rm9yQnV0dG9uID0gdGhpcy5odG1sQ29udGVudFRvSW5qZWN0LmZpbmQoXHJcbiAgICAgICAgICAgICAgICAob2JqZWN0KSA9PiBvYmplY3QuZWxlbWVudElEID09PSBidXR0b24uaWRcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgdGhpcy5idG5UYWdJc0hvdmVyID0gdHJ1ZTtcclxuICAgICAgICAgICAgY29uc3QgdGl0bGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAjdGl0bGVUYWdEaXZgKSBhcyBIVE1MRWxlbWVudDtcclxuICAgICAgICAgICAgaWYgKGNvbnRlbnRGb3JCdXR0b24udGl0bGUpIHtcclxuICAgICAgICAgICAgICAgIHRpdGxlLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lJztcclxuICAgICAgICAgICAgICAgIHRpdGxlLmlubmVySFRNTCA9IGNvbnRlbnRGb3JCdXR0b24udGl0bGU7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aXRsZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBjb250ZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgI2h0bWxUYWdEaXZgKSBhcyBIVE1MRWxlbWVudDtcclxuICAgICAgICAgICAgdGhpcy5kZXRhaWxUYWdEaXYuc3R5bGUudG9wID0gYCR7ZXZlbnQuY2xpZW50WSArIDEwfXB4YDtcclxuICAgICAgICAgICAgdGhpcy5kZXRhaWxUYWdEaXYuc3R5bGUubGVmdCA9IGAke2V2ZW50LmNsaWVudFggPCAxMjAgPyAwIDogZXZlbnQuY2xpZW50WCAtIDEyMFxyXG4gICAgICAgICAgICAgICAgfXB4YDtcclxuICAgICAgICAgICAgdGhpcy5kZXRhaWxUYWdEaXYuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGNvbnRlbnRGb3JCdXR0b24uY29udGVudCk7XHJcbiAgICAgICAgICAgIGNvbnRlbnQuaW5uZXJIVE1MID0gY29udGVudEZvckJ1dHRvbi5jb250ZW50O1xyXG4gICAgICAgICAgICBjb25zdCBkZXRhaWxCdXR0b24gPSBjb250ZW50LnF1ZXJ5U2VsZWN0b3IoJyNkZXRhaWxCdG4nKTtcclxuICAgICAgICAgICAgaWYgKGRldGFpbEJ1dHRvbikge1xyXG4gICAgICAgICAgICAgICAgZGV0YWlsQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlzaWJpbGl0eVNlcnZpY2UuZGV0YWlsU2hvd2luZy5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFt1cmxdKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBoYW5kbGUgaW1hZ2UgY2Fyb3VzZWwgZnVsbHNjcmVlbiBidXR0b25cclxuICAgICAgICAgICAgY29uc3QgaW1hZ2VGdWxsc2NyZWVuQnRuID0gY29udGVudC5xdWVyeVNlbGVjdG9yKCcjaW1hZ2UtZm9vdGVyJyk7XHJcbiAgICAgICAgICAgIGlmIChpbWFnZUZ1bGxzY3JlZW5CdG4pIHtcclxuICAgICAgICAgICAgICAgIGltYWdlRnVsbHNjcmVlbkJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGFnU2VydmljZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdTZXJ2aWNlLm9uQWN0aW9uSW1hZ2VDbGljayhjb250ZW50Rm9yQnV0dG9uLmVsZW1lbnRJRCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGhhbmRsZSBib29raW5nIGZ1bGxzY3JlZW4gYnV0dG9uXHJcbiAgICAgICAgICAgIGNvbnN0IGJvb2tpbmdCdXR0b24gPSBjb250ZW50LnF1ZXJ5U2VsZWN0b3IoJyNib29raW5nQnRuJyk7XHJcbiAgICAgICAgICAgIGlmIChib29raW5nQnV0dG9uKSB7XHJcbiAgICAgICAgICAgICAgICBib29raW5nQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlzaWJpbGl0eVNlcnZpY2UuZGV0YWlsU2hvd2luZy5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFt1cmxdKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBoYW5kbGUgZG9jdW1lbnQgcGRmIGZ1bGxzY3JlZW4gYnV0dG9uXHJcbiAgICAgICAgICAgIGNvbnN0IGRvY0Z1bGxzY3JlZW5CdG4gPSBjb250ZW50LnF1ZXJ5U2VsZWN0b3IoJyNkb2MtZm9vdGVyJyk7XHJcbiAgICAgICAgICAgIGlmIChkb2NGdWxsc2NyZWVuQnRuICYmIGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGRvY3VtZW50VXJsID0gdGFnU2VydmljZS5nZXRBbm5leGVGb3JDb21tZW50VHlwZUluRmVhdHVyZShcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgIENvbW1lbnRUeXBlLkRPQ1VNRU5UXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgZG9jRnVsbHNjcmVlbkJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGFnU2VydmljZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdTZXJ2aWNlLm9uQWN0aW9uRG9jQ2xpY2soZG9jdW1lbnRVcmwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBoYW5kbGUgdmlkZW8gZnVsbHNjcmVlbiBidXR0b25cclxuICAgICAgICAgICAgY29uc3QgdmlkZW9GdWxsc2NyZWVuQnRuID0gY29udGVudC5xdWVyeVNlbGVjdG9yKCcjYnRuLXZpZGVvLWZ1bGxzY3JlZW4nKTtcclxuICAgICAgICAgICAgaWYgKHZpZGVvRnVsbHNjcmVlbkJ0biAmJiBlbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB2aWRlb1VybCA9IHRhZ1NlcnZpY2UuZ2V0QW5uZXhlRm9yQ29tbWVudFR5cGVJbkZlYXR1cmUoXHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICBDb21tZW50VHlwZS5WSURFT1xyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIHZpZGVvRnVsbHNjcmVlbkJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGFnU2VydmljZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdTZXJ2aWNlLm9uQWN0aW9uVmlkZW9DbGljayh2aWRlb1VybCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGhhbmRsZSBZb3V0dWJlIHZpZGVvIGZ1bGxzY3JlZW4gYnV0dG9uXHJcbiAgICAgICAgICAgIGNvbnN0IHlvdXR1YmVGdWxsU2NyZWVuID0gY29udGVudC5xdWVyeVNlbGVjdG9yKFxyXG4gICAgICAgICAgICAgICAgJyNidG4tdmlkZW8tZnVsbHNjcmVlbi15b3V0dWJlJ1xyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICBpZiAoeW91dHViZUZ1bGxTY3JlZW4gJiYgZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgeW91dHViZVVybCA9IHRhZ1NlcnZpY2UuZ2V0QW5uZXhlRm9yQ29tbWVudFR5cGVJbkZlYXR1cmUoXHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICBDb21tZW50VHlwZS5ZT1VUVUJFXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgeW91dHViZUZ1bGxTY3JlZW4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRhZ1NlcnZpY2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFnU2VydmljZS5vbkFjdGlvbllvdXR1YmVDbGljayh5b3V0dWJlVXJsKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gaGFuZGxlIG11dGUgdmlkZW8gYnV0dG9uXHJcbiAgICAgICAgICAgIGNvbnN0IGJ0bk11dGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYnRuLW11dGUnKTtcclxuICAgICAgICAgICAgY29uc3QgaW1nT24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc291bmQtb24nKTtcclxuICAgICAgICAgICAgY29uc3QgaW1nT2ZmID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NvdW5kLW9mZicpO1xyXG4gICAgICAgICAgICBjb25zdCBwbGF5ZXJFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtdXMtdmlkZW8tdGFnXCIpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHBsYXllckVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgIHZpZGVvSnNQbGF5ZXIgPSB2aWRlb2pzKFwibXVzLXZpZGVvLXRhZ1wiKTtcclxuICAgICAgICAgICAgICAgIGlmIChidG5NdXRlICYmIHZpZGVvSnNQbGF5ZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICBidG5NdXRlLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmlkZW9Kc1BsYXllci5tdXRlZCgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0pzUGxheWVyLm11dGVkKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbWdPbiAmJiBpbWdPZmYpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWdPbi5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1nT2ZmLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0pzUGxheWVyLm11dGVkKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGltZ09uICYmIGltZ09mZikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltZ09uLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1nT2ZmLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgLy8gaGFuZGxlIGF1ZGlvIHBsYXllciBidXR0b25zXHJcbiAgICAgICAgICAgIGNvbnN0IHBsYXllckJ1dHRvbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5hdWRpby1wbGF5LWJ1dHRvbicpO1xyXG4gICAgICAgICAgICBjb25zdCBhdWRpbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdWRpby10YWcnKSBhcyBIVE1MTWVkaWFFbGVtZW50O1xyXG4gICAgICAgICAgICBjb25zdCB0aW1lbGluZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXHJcbiAgICAgICAgICAgICAgICAnLnRpbWVsaW5lLXRhZydcclxuICAgICAgICAgICAgKSBhcyBIVE1MSW5wdXRFbGVtZW50O1xyXG4gICAgICAgICAgICAvLyBjb25zdCB0aW1lbGluZVZhbHVlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRpbWVsaW5lLXRhZycpLnZhbHVlO1xyXG4gICAgICAgICAgICBjb25zdCBzb3VuZEJ1dHRvbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5hdWRpby1zb3VuZC1idG4nKTtcclxuICAgICAgICAgICAgY29uc3QgcGxheUF1ZGlvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BsYXknKTtcclxuICAgICAgICAgICAgY29uc3QgcGF1c2VBdWRpbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYXVzZScpO1xyXG4gICAgICAgICAgICBjb25zdCBpbWdTb3VuZE9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2F1ZGlvLXNvdW5kLW9uJyk7XHJcbiAgICAgICAgICAgIGNvbnN0IGltZ1NvdW5kT2ZmID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2F1ZGlvLXNvdW5kLW9mZicpO1xyXG4gICAgICAgICAgICBjb25zdCBhdWRpb01vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2J0bi1hdWRpby1tb2RhbCcpO1xyXG4gICAgICAgICAgICBpZiAoYXVkaW8gJiYgcGxheWVyQnV0dG9uICYmIHRpbWVsaW5lKSB7XHJcbiAgICAgICAgICAgICAgICBwbGF5ZXJCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1ZGlvLnBhdXNlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdWRpby5wbGF5KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdXNlQXVkaW8uc3R5bGUuZGlzcGxheSA9ICdpbmxpbmUtYmxvY2snO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGF5QXVkaW8uc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdWRpby5wYXVzZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXVzZUF1ZGlvLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsYXlBdWRpby5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICBzb3VuZEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXVkaW8ubXV0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW8ubXV0ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW1nU291bmRPbi5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGltZ1NvdW5kT2ZmLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW8ubXV0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbWdTb3VuZE9uLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGltZ1NvdW5kT2ZmLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGNoYW5nZVRpbWVsaW5lUG9zaXRpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1ZGlvLmR1cmF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBlcmNlbnRhZ2VQb3NpdGlvbiA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMTAwICogYXVkaW8uY3VycmVudFRpbWUpIC8gYXVkaW8uZHVyYXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBlcmNlbnRhZ2VQb3NpdGlvblN0cmluZyA9IHBlcmNlbnRhZ2VQb3NpdGlvbiArICclJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGltZWxpbmUuc3R5bGUuYmFja2dyb3VuZFNpemUgPSBwZXJjZW50YWdlUG9zaXRpb25TdHJpbmcgKyAnIDEwMCUnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aW1lbGluZS52YWx1ZSA9IHBlcmNlbnRhZ2VQb3NpdGlvbi50b1N0cmluZygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGF1ZGlvLm9udGltZXVwZGF0ZSA9IGNoYW5nZVRpbWVsaW5lUG9zaXRpb247XHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBjaGFuZ2VTZWVrKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRpbWUgPSAocGFyc2VJbnQodGltZWxpbmUudmFsdWUpICogYXVkaW8uZHVyYXRpb24pIC8gMTAwO1xyXG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvLmN1cnJlbnRUaW1lID0gdGltZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRpbWVsaW5lLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGNoYW5nZVNlZWspO1xyXG4gICAgICAgICAgICAgICAgdGltZWxpbmUuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCBjaGFuZ2VTZWVrKTtcclxuICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBhdWRpbyBjbGlja1xyXG4gICAgICAgICAgICAgICAgaWYgKGF1ZGlvTW9kYWwgJiYgZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGF1ZGlvQ29tbWVudCA9IGVsZW1lbnQuY29tbWVudHM/Lml0ZW1zLmZpbmQoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjb20pID0+IGNvbS50eXBlID09PSBDb21tZW50VHlwZS5BVURJTyAmJiBjb20uc2hvd25JblRhZ1xyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYXVkaW9Db21tZW50SUQgPSBhdWRpb0NvbW1lbnQgPyBhdWRpb0NvbW1lbnQuaWQgOiAnJztcclxuICAgICAgICAgICAgICAgICAgICBhdWRpb01vZGFsLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFnU2VydmljZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnU2VydmljZS5vbkFjdGlvbkF1ZGlvQ2xpY2soYXVkaW9Db21tZW50SUQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICAgIC8vIHdlIHdhaXQgaWYgdXNlciBob3ZlcnMgb24gdG8gZGl2IG9mIHRoZSB0YWcgKGNoYW5nZXMgdGhpcy5mb2N1c01vdXNlVGFnRGl2KVxyXG4gICAgICAgICAgICB0aGlzLmJ0blRhZ0lzSG92ZXIgPSBmYWxzZTtcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZm9jdXNNb3VzZVRhZ0RpdiAmJiAhdGhpcy5idG5UYWdJc0hvdmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXRhaWxUYWdEaXYuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgICAgICBpZiAodmlkZW9Kc1BsYXllcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0pzUGxheWVyLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sIDEwMCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmRldGFpbFRhZ0Rpdi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgICAgICBpZiAodmlkZW9Kc1BsYXllcikge1xyXG4gICAgICAgICAgICAgICAgdmlkZW9Kc1BsYXllci5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYXdhaXQgdGhpcy52aWV3ZXJTZXJ2aWNlLmFjdGlvbl9tb3ZlX3RvX3RhZyhidXR0b24uaWQpO1xyXG4gICAgICAgICAgICB0aGlzLnZpc2liaWxpdHlTZXJ2aWNlLmRldGFpbFNob3dpbmcubmV4dCh0cnVlKTtcclxuICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW3VybF0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGNsZWFyQnRuKGlkTGlzdDogYW55W10pIHtcclxuICAgICAgICBmb3IgKGNvbnN0IGlkIG9mIGlkTGlzdCkge1xyXG4gICAgICAgICAgICBjb25zdCBidXR0b24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XHJcbiAgICAgICAgICAgIGlmIChidXR0b24pIHtcclxuICAgICAgICAgICAgICAgIGJ1dHRvbi5yZW1vdmUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjbGVhckFsbEJ1dHRvbnMoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMucGxhbkRpdkNvbnRlbnQpIHtcclxuICAgICAgICAgICAgY29uc3QgYnV0dG9ucyA9IHRoaXMucGxhbkRpdkNvbnRlbnQucXVlcnlTZWxlY3RvckFsbCgnYnV0dG9uJyk7XHJcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB1bmljb3JuL25vLWFycmF5LWZvci1lYWNoXHJcbiAgICAgICAgICAgIGJ1dHRvbnMuZm9yRWFjaChmdW5jdGlvbiAoY3VycmVudFZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICBjdXJyZW50VmFsdWUucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB0aGlzLnVzZXJQb3NpdGlvbkJ0biA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZUFsbEJ1dHRvbnNTdHlsZShwcm9wZXJ0aWVzOiBBcnJheTxzdHJpbmc+LCB2YWx1ZXM6IEFycmF5PHN0cmluZz4pIHtcclxuICAgICAgICBpZiAodGhpcy5wbGFuRGl2Q29udGVudCkge1xyXG4gICAgICAgICAgICBjb25zdCBidXR0b25zID0gdGhpcy5wbGFuRGl2Q29udGVudC5xdWVyeVNlbGVjdG9yQWxsKCdidXR0b24nKTtcclxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHVuaWNvcm4vbm8tYXJyYXktZm9yLWVhY2hcclxuICAgICAgICAgICAgYnV0dG9ucy5mb3JFYWNoKGZ1bmN0aW9uIChjdXJyZW50VmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIHByb3BlcnRpZXMuZm9yRWFjaCgocHJvcGVydHksIGkpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydHkgPT09IFwidHJhbnNmb3JtXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9Gb3Igc2F2aW5nIHRoZSByb3RhdGlvbiBhbmQgYWRkaW5nIHNjYWxlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCByb3RhdGlvblJlZ2V4ID0gLyhyb3RhdGVcXCgtP1xcZCpcXC4/XFxkK2RlZ1xcKSkvZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJvdGF0aW9uTWF0Y2ggPSBjdXJyZW50VmFsdWUuc3R5bGVbcHJvcGVydHldLm1hdGNoKHJvdGF0aW9uUmVnZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocm90YXRpb25NYXRjaC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50VmFsdWUuc3R5bGVbcHJvcGVydHldID0gYCR7dmFsdWVzW2ldfSAke3JvdGF0aW9uTWF0Y2hbMF19YDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRWYWx1ZS5zdHlsZVtwcm9wZXJ0eV0gPSB2YWx1ZXNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgb25QbGFuUmVtb3ZlKCkge1xyXG4gICAgICAgIHRoaXMudXNlclBvc2l0aW9uQnRuID0gbnVsbDtcclxuICAgICAgICB0aGlzLmNhbGlicmF0aW9uUGxhbiA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50U3dlZXAgPSBudWxsO1xyXG4gICAgICAgIHRoaXMuZGV0YWlsVGFnRGl2ID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyByZXNpemVQbGFuKGlzUmVtb3Zpbmc6IGJvb2xlYW4pIHtcclxuICAgICAgICB0aGlzLnJlc2l6ZVBsYW5TdWJzY3JpcHRpb24ubmV4dChmYWxzZSk7XHJcbiAgICAgICAgaWYgKGlzUmVtb3ZpbmcpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zb2xlLmxvZygnaW4gcmVzaXplUGxhbicpO1xyXG4gICAgICAgIGlmICh0aGlzLnBsYW5EaXYgJiYgdGhpcy5jdXJyZW50U3dlZXApIHtcclxuICAgICAgICAgICAgdGhpcy5wYW56b29tID0gcGFuem9vbSh0aGlzLnBsYW5EaXYsIHtcclxuICAgICAgICAgICAgICAgIGJvdW5kczogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGJvdW5kc1BhZGRpbmc6IDAsXHJcbiAgICAgICAgICAgICAgICBtYXhab29tOiA0LFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZWN0ID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiB0aGlzLnBsYW5EaXZDb250ZW50Lm9mZnNldFdpZHRoLFxyXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy5wbGFuRGl2Q29udGVudC5vZmZzZXRIZWlnaHQsXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgY29uc3QgeyBjb2VmZlgsIGNvZWZmWSB9ID0gZ2V0Q29lZmZpY2llbnRzRm9ySW1hZ2UodGhpcy5pbWdQbGFuLCByZWN0KTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29lZmZQbGFuWCA9IGNvZWZmWDtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29lZmZQbGFuWSA9IGNvZWZmWTtcclxuICAgICAgICAgICAgICAgIHRoaXMucGFuem9vbS56b29tQWJzKDAsIDAsIDQpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemVQbGFuU3Vic2NyaXB0aW9uLm5leHQodHJ1ZSk7XHJcbiAgICAgICAgICAgIH0sIDIwMCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGhhbmRsZVRvdWNoKGV2ZW50KSB7XHJcbiAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcclxuICAgICAgICBpZiAobm93IC0gdGhpcy5sYXN0VG91Y2hUaW1lIDwgdGhpcy5kZWxheURibFRvdWNoKSB7XHJcbiAgICAgICAgICAgIHRoaXMubGFzdFRvdWNoVGltZSA9IDA7XHJcbiAgICAgICAgICAgIC8vIHRoaXMub25EYmxDbGlja1BsYW4oZXZlbnQpO1xyXG4gICAgICAgICAgICAvKiogU2ltdWxhdGUgYSBkYmxjbGljayBmb3IgcGhvbmUgKHdlIGRvbid0IGdldCBvZmZzZXRYL1kgb24gdG91Y2hldmVudCkgKi9cclxuICAgICAgICAgICAgY29uc3QgbmV3RXZlbnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnTW91c2VFdmVudHMnKTtcclxuICAgICAgICAgICAgY29uc3QgdG91Y2ggPSBldmVudC5jaGFuZ2VkVG91Y2hlc1swXTtcclxuICAgICAgICAgICAgbmV3RXZlbnQuaW5pdE1vdXNlRXZlbnQoXHJcbiAgICAgICAgICAgICAgICAnZGJsY2xpY2snLFxyXG4gICAgICAgICAgICAgICAgdHJ1ZSxcclxuICAgICAgICAgICAgICAgIHRydWUsXHJcbiAgICAgICAgICAgICAgICBldmVudC50YXJnZXQub3duZXJEb2N1bWVudC5kZWZhdWx0VmlldyxcclxuICAgICAgICAgICAgICAgIDAsXHJcbiAgICAgICAgICAgICAgICB0b3VjaC5zY3JlZW5YLFxyXG4gICAgICAgICAgICAgICAgdG91Y2guc2NyZWVuWSxcclxuICAgICAgICAgICAgICAgIHRvdWNoLmNsaWVudFgsXHJcbiAgICAgICAgICAgICAgICB0b3VjaC5jbGllbnRZLFxyXG4gICAgICAgICAgICAgICAgZXZlbnQuY3RybEtleSxcclxuICAgICAgICAgICAgICAgIGV2ZW50LmFsdEtleSxcclxuICAgICAgICAgICAgICAgIGV2ZW50LnNoaXJ0S2V5LFxyXG4gICAgICAgICAgICAgICAgZXZlbnQubWV0YUtleSxcclxuICAgICAgICAgICAgICAgIDAsXHJcbiAgICAgICAgICAgICAgICBudWxsXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIGV2ZW50LnRhcmdldC5kaXNwYXRjaEV2ZW50KG5ld0V2ZW50KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmxhc3RUb3VjaFRpbWUgPSBub3c7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIG9uRGJsQ2xpY2tQbGFuKGV2ZW50KSB7XHJcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBjb25zdCBjbGlja1ggPSBldmVudC5vZmZzZXRYO1xyXG4gICAgICAgIGNvbnN0IGNsaWNrWSA9IGV2ZW50Lm9mZnNldFk7XHJcbiAgICAgICAgY29uc3Qgem9uZVBsYW4gPSB0aGlzLmN1cnJlbnRQbGFuLnpvbmU7XHJcbiAgICAgICAgaWYgKHpvbmVQbGFuKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG5hdmlnYXRpb25zOiBhbnkgPVxyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5nZXROYXZpZ2F0aW9uc0ZvclpvbmUoem9uZVBsYW4pO1xyXG4gICAgICAgICAgICBpZiAobmF2aWdhdGlvbnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXHJcbiAgICAgICAgICAgICAgICAgICAgbmF2aWdhdGlvbnMubWFwKGFzeW5jIChuYXYpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpb24gPSBKU09OLnBhcnNlKG5hdi5wb3NpdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB4OiBudW1iZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB5OiBudW1iZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNhbGlicmF0aW9uUGxhbi5uZXcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uMkQgPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJhbnNmb3JtUG9zaXRpb24zREZvck5ld0NhbGlicmF0aW9uKHBvc2l0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSBwb3NpdGlvbjJELnggLyBwb3NpdGlvbjJELmNvZWZmWDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBwb3NpdGlvbjJELnkgLyBwb3NpdGlvbjJELmNvZWZmWTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzLmNhbGlicmF0aW9uUGxhbi5vZmZzZXRYICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24ueCAqIHRoaXMuY2FsaWJyYXRpb25QbGFuLngpIC9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvZWZmUGxhblg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodGhpcy5jYWxpYnJhdGlvblBsYW4ub2Zmc2V0WSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uLnogKiB0aGlzLmNhbGlicmF0aW9uUGxhbi55KSAvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb2VmZlBsYW5ZO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkaXN0WCA9IE1hdGguYWJzKGNsaWNrWCAtIHgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkaXN0WSA9IE1hdGguYWJzKGNsaWNrWSAtIHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuYXYuZGlzdCA9IE1hdGguc3FydChNYXRoLnBvdyhkaXN0WCwgMikgKyBNYXRoLnBvdyhkaXN0WSwgMikpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgbmF2aWdhdGlvbnMuc29ydCgoYSwgYikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhLmRpc3QgLSBiLmRpc3Q7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHRoaXMubWF0dGVycG9ydFNlcnZpY2UuYWN0aW9uX2dvX3RvX3N3ZWVwKFxyXG4gICAgICAgICAgICAgICAgICAgIG5hdmlnYXRpb25zWzBdLm1hdHRlcnBvcnRTd2VlcElEXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29uZmlndXJlcyBwbGFuIGZyb20gY2FjaGUgKHByZXZpb3VzIHBsYW4pLlxyXG4gICAgICovXHJcbiAgICBhc3luYyB1cGxvYWRQbGFuRnJvbUNhY2hlKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHRoaXMuaHRtbENvbnRlbnRUb0luamVjdCA9IHRoaXMuY2FjaGUuaHRtbENvbnRlbnQ7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5jb25maWd1cmVQbGFuKHRoaXMuY2FjaGUucGxhbik7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHV0cyBidXR0b25zICh0YWdzKSBmcm9tIGNhY2hlIGFjY29yZGluZyB0byBwYXNzZWQgZWxlbWVudCBJRHMgKGZvciBmaWx0ZXIgaWYgYW55KVxyXG4gICAgICogQHBhcmFtIGVsZW1lbnRJRHMgZWxlbWVudHMgKHRpY2tldHMsIGVxdWlwbWVudHMsIGV0YykgdG8gYmUgc2hvd24gb24gcGxhblxyXG4gICAgICovXHJcbiAgICB1cGxvYWRUYWdzRnJvbUNhY2hlKHNpemVCdXR0b246IG51bWJlciA9IDEwKSB7XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2coXCJ1cGxvYWRpbmcgdGFncyBmcm9tIGNhY2hlXCIpO1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IGNhY2hlZCBvZiB0aGlzLmNhY2hlLmh0bWxDb250ZW50KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xyXG4gICAgICAgICAgICB0aGlzLnN0eWxlQnV0dG9uKGJ1dHRvbiwgY2FjaGVkLnRhZ0ljb24sIHNpemVCdXR0b24pO1xyXG4gICAgICAgICAgICBidXR0b24uaWQgPSBjYWNoZWQuZWxlbWVudElEO1xyXG4gICAgICAgICAgICB0aGlzLnBsYW5EaXZDb250ZW50LmFwcGVuZChidXR0b24pO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5jYWxpYnJhdGlvblBsYW4ubmV3KSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdDb2VmZlggPVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29lZmZQbGFuWCAvXHJcbiAgICAgICAgICAgICAgICAgICAgKHRoaXMuaW1nUGxhbi53aWR0aCAvIHRoaXMuY2FsaWJyYXRpb25QbGFuLmltZ1dpZHRoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5ld0NvZWZmWSA9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb2VmZlBsYW5ZIC9cclxuICAgICAgICAgICAgICAgICAgICAodGhpcy5pbWdQbGFuLmhlaWdodCAvIHRoaXMuY2FsaWJyYXRpb25QbGFuLmltZ0hlaWdodCk7XHJcbiAgICAgICAgICAgICAgICBidXR0b24uc3R5bGUudG9wID0gYCR7Y2FjaGVkLnkgLyBuZXdDb2VmZlkgLSA1fXB4YDtcclxuICAgICAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS5sZWZ0ID0gYCR7Y2FjaGVkLnggLyBuZXdDb2VmZlggLSA1fXB4YDtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGJ1dHRvbi5zdHlsZS50b3AgPSBgJHtjYWNoZWQueSAvIHRoaXMuY29lZmZQbGFuWSAtIDV9cHhgO1xyXG4gICAgICAgICAgICAgICAgYnV0dG9uLnN0eWxlLmxlZnQgPSBgJHtjYWNoZWQueCAvIHRoaXMuY29lZmZQbGFuWCAtIDV9cHhgO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmFkZExpc3RlbmVyc1RvQnV0dG9uKGJ1dHRvbiwgY2FjaGVkLnVybCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGdldENhbGlicmF0ZWRQbGFuRm9yWm9uZSh6b25lOiBab25lKTogUHJvbWlzZTxQbGFuPiB7XHJcbiAgICAgICAgbGV0IHBsYW5zID0gKGF3YWl0IHRoaXMuQVBJLlBsYW5zQnlab25lKHpvbmUuaWQpKS5pdGVtcztcclxuICAgICAgICBsZXQgcGFyZW50Wm9uZSA9IG51bGw7XHJcbiAgICAgICAgaWYgKHBsYW5zLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAvLyB0cnkgdG8gZmluZCBwYXJlbnQgem9uZVxyXG4gICAgICAgICAgICBwYXJlbnRab25lID0gYXdhaXQgdGhpcy5BUEkuR2V0Wm9uZSh6b25lLnBhcmVudElEKTtcclxuICAgICAgICAgICAgcGxhbnMgPSAoYXdhaXQgdGhpcy5BUEkuUGxhbnNCeVpvbmUoem9uZS5wYXJlbnRJRCkpLml0ZW1zO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBjYWxpYnJhdGVkUGxhbiA9IHBsYW5zLmZpbmQoXHJcbiAgICAgICAgICAgIChwbGFuKSA9PiBwbGFuLmNhbGlicmF0aW9uICYmIHBsYW4uaXNDdXJyZW50Rm9yWm9uZVxyXG4gICAgICAgICkgYXMgUGxhbjtcclxuICAgICAgICBpZiAoY2FsaWJyYXRlZFBsYW4pIHtcclxuICAgICAgICAgICAgY29uc3Qgc2lnbmVkID0gYXdhaXQgZ2V0U2lnbmVkRmlsZShjYWxpYnJhdGVkUGxhbi5hbm5leGUpO1xyXG4gICAgICAgICAgICBpZiAoc2lnbmVkKSB7XHJcbiAgICAgICAgICAgICAgICBjYWxpYnJhdGVkUGxhbi5maWxlcGF0aCA9IHNpZ25lZDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYWxpYnJhdGVkUGxhbi5uYXZpZ2F0aW9uSURzID0gcGFyZW50Wm9uZVxyXG4gICAgICAgICAgICAgICAgPyBwYXJlbnRab25lLnN3ZWVwSURzXHJcbiAgICAgICAgICAgICAgICA6IHpvbmUuc3dlZXBJRHM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBjYWxpYnJhdGVkUGxhbiB8fCBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHRyYW5zZm9ybVBvc2l0aW9uM0RGb3JOZXdDYWxpYnJhdGlvbihwb3NpdGlvbjoge1xyXG4gICAgICAgIHg6IG51bWJlcjtcclxuICAgICAgICB5OiBudW1iZXI7XHJcbiAgICAgICAgejogbnVtYmVyO1xyXG4gICAgfSk6IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IGNvZWZmWDogbnVtYmVyOyBjb2VmZlk6IG51bWJlcjsgfSB7XHJcbiAgICAgICAgY29uc3QgcG9zaXRpb25YID1cclxuICAgICAgICAgICAgdGhpcy5jYWxpYnJhdGlvblBsYW4ubmFtZVhBeGlzID09PSAneCcgPyBwb3NpdGlvbi54IDogcG9zaXRpb24uejtcclxuICAgICAgICBjb25zdCBwb3NpdGlvblkgPVxyXG4gICAgICAgICAgICB0aGlzLmNhbGlicmF0aW9uUGxhbi5uYW1lWUF4aXMgPT09ICd4JyA/IHBvc2l0aW9uLnggOiBwb3NpdGlvbi56O1xyXG4gICAgICAgIGxldCB4ID1cclxuICAgICAgICAgICAgdGhpcy5jYWxpYnJhdGlvblBsYW4ub2Zmc2V0WCArIHBvc2l0aW9uWCAqIHRoaXMuY2FsaWJyYXRpb25QbGFuLnNjYWxlWDtcclxuICAgICAgICBsZXQgeSA9XHJcbiAgICAgICAgICAgIHRoaXMuY2FsaWJyYXRpb25QbGFuLm9mZnNldFkgKyBwb3NpdGlvblkgKiB0aGlzLmNhbGlicmF0aW9uUGxhbi5zY2FsZVk7XHJcbiAgICAgICAgY29uc3QgbmV3Q29lZmZYID1cclxuICAgICAgICAgICAgdGhpcy5jb2VmZlBsYW5YIC8gKHRoaXMuaW1nUGxhbi53aWR0aCAvIHRoaXMuY2FsaWJyYXRpb25QbGFuLmltZ1dpZHRoKTtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIm5ld0NvZWZmWFwiLCBuZXdDb2VmZlgpO1xyXG4gICAgICAgIGNvbnN0IG5ld0NvZWZmWSA9XHJcbiAgICAgICAgICAgIHRoaXMuY29lZmZQbGFuWSAvICh0aGlzLmltZ1BsYW4uaGVpZ2h0IC8gdGhpcy5jYWxpYnJhdGlvblBsYW4uaW1nSGVpZ2h0KTtcclxuICAgICAgICB4ID0gKHggLSB0aGlzLmNhbGlicmF0aW9uUGxhbi5vZmZzZXRYUGxhbikgLyB0aGlzLmNhbGlicmF0aW9uUGxhbi5zY2FsZVBsYW47XHJcblxyXG4gICAgICAgIHkgPSAoeSAtIHRoaXMuY2FsaWJyYXRpb25QbGFuLm9mZnNldFlQbGFuKSAvIHRoaXMuY2FsaWJyYXRpb25QbGFuLnNjYWxlUGxhbjtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZyh4LCB5KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHsgeCwgeSwgY29lZmZYOiBuZXdDb2VmZlgsIGNvZWZmWTogbmV3Q29lZmZZIH07XHJcbiAgICB9XHJcbn1cclxuIl19
|