hart-estate-widget 0.0.66 → 0.0.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +3 -0
  2. package/build/assets/css/index.css +2 -0
  3. package/build/assets/img/floor-dark.jpg +0 -0
  4. package/build/assets/img/floor-white.jpg +0 -0
  5. package/build/assets/img/grass.jpg +0 -0
  6. package/build/bundle.js +2 -0
  7. package/build/components/Application.js +2 -135
  8. package/build/components/Buttons/FullScreenButton.js +2 -50
  9. package/build/components/Buttons/TabButton.js +2 -24
  10. package/build/components/Instructions.js +2 -54
  11. package/build/components/Loader.js +2 -22
  12. package/build/components/ModelTab.js +2 -213
  13. package/build/components/PanoramaTab.js +2 -620
  14. package/build/components/RotationTab/DefaultView.js +2 -124
  15. package/build/components/RotationTab/ThreesixtyView.js +2 -45
  16. package/build/components/RotationTab/index.js +2 -194
  17. package/build/components/Widget.js +2 -110
  18. package/build/config/defaultConfig.js +2 -32
  19. package/build/enums/deviceOrientationStatuses.js +2 -11
  20. package/build/enums/deviceWidth.js +2 -21
  21. package/build/enums/imageExtentions.js +2 -16
  22. package/build/enums/rotationModes.js +2 -11
  23. package/build/index.css +1 -1
  24. package/build/index.js +2 -75
  25. package/build/locale/index.js +2 -71
  26. package/build/store/apiStore.js +2 -231
  27. package/build/store/deviceStore.js +2 -60
  28. package/build/store/fullScreenStore.js +2 -159
  29. package/build/store/houseStore.js +2 -952
  30. package/build/store/index.js +2 -124
  31. package/build/store/modelStore.js +2 -338
  32. package/build/threesixty/events.js +2 -220
  33. package/build/threesixty/index.js +2 -264
  34. package/build/utils/csg/csg-lib.js +2 -472
  35. package/build/utils/csg/csg-worker.js +2 -84
  36. package/build/utils/csg/three-csg.js +2 -277
  37. package/build/utils/helpers.js +2 -12
  38. package/build/utils/modelHelpers.js +2 -161
  39. package/build/utils/panoramaHelpers.js +2 -117
  40. package/package.json +17 -5
  41. package/build/assets/css/app.css +0 -1
  42. package/build/assets/css/app.css.map +0 -1
  43. package/build/assets/img/floor-dark.png +0 -0
  44. package/build/assets/img/floor-white.png +0 -0
  45. package/build/assets/img/grass.png +0 -0
@@ -1,620 +1,2 @@
1
- "use strict";
2
-
3
- function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.default = void 0;
9
-
10
- var _react = _interopRequireWildcard(require("react"));
11
-
12
- var _deviceStore = _interopRequireDefault(require("../store/deviceStore"));
13
-
14
- var _locale = _interopRequireDefault(require("../locale"));
15
-
16
- var _store = _interopRequireDefault(require("../store"));
17
-
18
- var THREE = _interopRequireWildcard(require("three"));
19
-
20
- var PANOLENS = _interopRequireWildcard(require("panolens"));
21
-
22
- var _threeDeviceOrientation = _interopRequireDefault(require("three-device-orientation"));
23
-
24
- var _geometric = require("geometric");
25
-
26
- var _deviceOrientationStatuses = require("../enums/deviceOrientationStatuses");
27
-
28
- var _deviceWidth = require("../enums/deviceWidth");
29
-
30
- var _imageExtentions = require("../enums/imageExtentions");
31
-
32
- var _helpers = require("../utils/helpers");
33
-
34
- var _panoramaHelpers = require("../utils/panoramaHelpers");
35
-
36
- var _Loader = _interopRequireDefault(require("./Loader"));
37
-
38
- var _Instructions = _interopRequireDefault(require("./Instructions"));
39
-
40
- var _spotIcon = _interopRequireDefault(require("../assets/img/spot-icon.png"));
41
-
42
- var _doorIcon = _interopRequireDefault(require("../assets/img/door-icon.png"));
43
-
44
- var _handMove = _interopRequireDefault(require("../assets/icons/hand-move.svg"));
45
-
46
- var _handResearch = _interopRequireDefault(require("../assets/icons/hand-research.svg"));
47
-
48
- var _rotationClose = _interopRequireDefault(require("../assets/icons/rotation-close.svg"));
49
-
50
- var _rotation = _interopRequireDefault(require("../assets/icons/rotation.svg"));
51
-
52
- var _x = _interopRequireDefault(require("../assets/icons/1x.svg"));
53
-
54
- var _x2 = _interopRequireDefault(require("../assets/icons/2x.svg"));
55
-
56
- var _close = _interopRequireDefault(require("../assets/icons/close.svg"));
57
-
58
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
59
-
60
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
61
-
62
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
63
-
64
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
65
-
66
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
67
-
68
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
69
-
70
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
71
-
72
- function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
73
-
74
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
75
-
76
- var _PANOLENS$CONTROLS = PANOLENS.CONTROLS,
77
- DEVICEORIENTATION = _PANOLENS$CONTROLS.DEVICEORIENTATION,
78
- ORBIT = _PANOLENS$CONTROLS.ORBIT;
79
- var pathName = 'Panorama_0_0_';
80
- var cameraFovValues = {
81
- x1: 90,
82
- x2: 60
83
- };
84
-
85
- var getDefaultUserData = function getDefaultUserData() {
86
- return {
87
- left: 0,
88
- top: 0,
89
- points: []
90
- };
91
- };
92
-
93
- var createPanorama = function createPanorama(image, index, setLoadingState) {
94
- var panorama = new PANOLENS.ImagePanorama(image);
95
- panorama.userData = getDefaultUserData();
96
- panorama['panorama_id'] = index + 1;
97
- panorama.addEventListener('progress', function (event) {
98
- setLoadingState(true);
99
-
100
- if (event.progress.loaded / event.progress.total * 100 === 100) {
101
- setLoadingState(false);
102
- }
103
- });
104
- panorama.addEventListener('enter', function () {
105
- return setLoadingState(false);
106
- });
107
- return panorama;
108
- };
109
-
110
- var getPanoramas = function getPanoramas(json, images, setLoadingState) {
111
- if (!json) return images.map(function (image, index) {
112
- return createPanorama(image, index, setLoadingState);
113
- });
114
- var panoramas = json.Floors[0].Units[0].Rooms.reduce(function (acc, jsonRoom, index) {
115
- var roomImages = images.filter(function (img) {
116
- var panoramaIdIndex = img.indexOf(pathName) + pathName.length;
117
- if (panoramaIdIndex < pathName.length) return false;
118
- var indexAsString = String(index);
119
- var panoramaId = String((0, _imageExtentions.removeExtention)(img.substring(panoramaIdIndex))).split('.')[0];
120
-
121
- if (panoramaId.toLowerCase().includes(_panoramaHelpers.cameraIdBeginning)) {
122
- var cameraIdIndex = panoramaId.toLowerCase().indexOf(_panoramaHelpers.cameraIdBeginning) - 1;
123
- panoramaId = panoramaId.slice(0, cameraIdIndex);
124
- }
125
-
126
- var maxIndexLength = Math.max(indexAsString.length, panoramaId.length);
127
- var imageInRoom = (0, _panoramaHelpers.getArrayFromNumber)(maxIndexLength).every(function (i) {
128
- return panoramaId[i] === indexAsString[i];
129
- });
130
- return imageInRoom;
131
- });
132
- if (!roomImages.length) return acc;
133
- roomImages.forEach(function (image) {
134
- var panorama = createPanorama(image, index, setLoadingState);
135
- panorama['room_images'] = roomImages;
136
- panorama['room_id'] = jsonRoom.ID;
137
- var roomPoints = (0, _panoramaHelpers.getRoomCoordinates)(jsonRoom, json.Floors[0].Walls, json.Vertices);
138
-
139
- var _polygonMean = (0, _geometric.polygonMean)(roomPoints),
140
- _polygonMean2 = _slicedToArray(_polygonMean, 2),
141
- left = _polygonMean2[0],
142
- top = _polygonMean2[1];
143
-
144
- if (panorama.src.toLowerCase().includes(_panoramaHelpers.cameraIdBeginning)) {
145
- var currentCamera = (0, _panoramaHelpers.getCameraFromSrc)(json, panorama.src);
146
- left = currentCamera.Location.X;
147
- top = currentCamera.Location.Y;
148
- }
149
-
150
- panorama.userData = {
151
- left: left,
152
- top: top,
153
- points: roomPoints
154
- };
155
-
156
- if (panorama['room_id'] === _store.default.initialPanoramaRoomId) {
157
- acc.unshift(panorama);
158
- } else {
159
- acc.push(panorama);
160
- }
161
- });
162
- return acc;
163
- }, []);
164
- return panoramas.map(function (panorama, index) {
165
- panorama['panorama_index'] = index;
166
- var currentRoom = json.Floors[0].Units[0].Rooms.find(function (room) {
167
- return room.ID === panorama['room_id'];
168
- });
169
-
170
- if (!panorama.linkedSpots.length) {
171
- return setPanoramaLinks(json, currentRoom, panorama, panoramas);
172
- }
173
-
174
- return panorama;
175
- });
176
- };
177
-
178
- var setPanoramaLinks = function setPanoramaLinks(json, currentRoom, panorama, panoramas) {
179
- var center = [panorama.userData.left, panorama.userData.top];
180
- panorama['room_images'].forEach(function (image) {
181
- if (image === panorama.src) return;
182
- var connectedPanorama = panoramas.find(function (_ref) {
183
- var src = _ref.src;
184
- return src === image;
185
- });
186
- var currentCamera = (0, _panoramaHelpers.getCameraFromSrc)(json, connectedPanorama.src);
187
- if (!currentCamera) return;
188
- connectPanorama(panorama, connectedPanorama, currentCamera.Location, center, false);
189
- });
190
- json.Floors[0].Doors.forEach(function (_ref2) {
191
- var Location = _ref2.Location,
192
- Walls = _ref2.Walls;
193
- if (!Walls.some(function (doorWallId) {
194
- return currentRoom.Walls.some(function (roomWallId) {
195
- return roomWallId === doorWallId;
196
- });
197
- })) return;
198
- var connectedRoom = json.Floors[0].Units[0].Rooms.find(function (room) {
199
- var roomHasSameWall = room.Walls.some(function (roomWallId) {
200
- return Walls.some(function (doorWallId) {
201
- return roomWallId === doorWallId;
202
- });
203
- });
204
- var isSameRoom = room.ID === currentRoom.ID;
205
- return roomHasSameWall && !isSameRoom;
206
- });
207
- if (!connectedRoom) return;
208
- var availablePanoramas = panoramas.filter(function (_ref3) {
209
- var room_id = _ref3.room_id;
210
- return room_id === connectedRoom.ID;
211
- });
212
-
213
- var _getClosestPanorama = (0, _panoramaHelpers.getClosestPanorama)([Location.X, Location.Y], availablePanoramas),
214
- connectedPanorama = _getClosestPanorama.panorama;
215
-
216
- if (!connectedPanorama) return;
217
- connectPanorama(panorama, connectedPanorama, Location, center, true);
218
- });
219
- return panorama;
220
- };
221
-
222
- var connectPanorama = function connectPanorama(panorama, connectedPanorama, location, center) {
223
- var isDoorLink = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
224
- var locationX = location.Y - center[1];
225
- var locationY = location.X - center[0];
226
- var locationZ = isDoorLink ? -10 : -100;
227
- var icon = isDoorLink ? _doorIcon.default : _spotIcon.default;
228
- var iconUrl = "".concat(icon, "?id=").concat(panorama['panorama_index'], "-").concat(panorama['panorama_id'], "-").concat(Math.random());
229
- var defaultScale = 20;
230
- var maxScale = 50;
231
- var defaultLength = 120;
232
- var length = (0, _geometric.lineLength)([[0, 0], [locationX, locationY]]);
233
- var scale = length / defaultLength * defaultScale;
234
- var finalScale = scale > maxScale ? maxScale : scale;
235
- var resultScale = isDoorLink ? finalScale : finalScale - 15;
236
- var position = new THREE.Vector3(locationX, locationZ, locationY);
237
- panorama.link(connectedPanorama, position, resultScale, iconUrl);
238
- };
239
-
240
- var PanoramaTab = function PanoramaTab(_ref4) {
241
- var _panoramas$currentRoo;
242
-
243
- var json = _ref4.json,
244
- planImage = _ref4.planImage,
245
- images = _ref4.images,
246
- disabled = _ref4.disabled;
247
- var instructionSteps = [{
248
- icon: _handMove.default,
249
- text: _locale.default.getLocaleText('rotate-plan')
250
- }, {
251
- icon: _handResearch.default,
252
- text: _locale.default.getLocaleText('research-plan')
253
- }];
254
-
255
- var _useState = (0, _react.useState)(_deviceOrientationStatuses.deviceOrientationStatuses.DENIED),
256
- _useState2 = _slicedToArray(_useState, 2),
257
- deviceOrientationStatus = _useState2[0],
258
- setDeviceOrientationStatus = _useState2[1];
259
-
260
- var _useState3 = (0, _react.useState)(true),
261
- _useState4 = _slicedToArray(_useState3, 2),
262
- showInstructions = _useState4[0],
263
- setInstructionsState = _useState4[1];
264
-
265
- var _useState5 = (0, _react.useState)(true),
266
- _useState6 = _slicedToArray(_useState5, 2),
267
- loadingState = _useState6[0],
268
- setLoadingState = _useState6[1];
269
-
270
- var _useState7 = (0, _react.useState)({
271
- width: '200px',
272
- height: 'auto'
273
- }),
274
- _useState8 = _slicedToArray(_useState7, 2),
275
- mapSize = _useState8[0],
276
- setMapSize = _useState8[1];
277
-
278
- var _useState9 = (0, _react.useState)(false),
279
- _useState10 = _slicedToArray(_useState9, 2),
280
- mapOpen = _useState10[0],
281
- setMapState = _useState10[1];
282
-
283
- var _useState11 = (0, _react.useState)({
284
- X: 1,
285
- Y: 1
286
- }),
287
- _useState12 = _slicedToArray(_useState11, 2),
288
- planScale = _useState12[0],
289
- setPlanScale = _useState12[1];
290
-
291
- var _useState13 = (0, _react.useState)(true),
292
- _useState14 = _slicedToArray(_useState13, 2),
293
- isMapDisabled = _useState14[0],
294
- setMapDisabledState = _useState14[1];
295
-
296
- var _useState15 = (0, _react.useState)(false),
297
- _useState16 = _slicedToArray(_useState15, 2),
298
- autoplayEnabled = _useState16[0],
299
- setAutoplayState = _useState16[1];
300
-
301
- var _useState17 = (0, _react.useState)(cameraFovValues.x1),
302
- _useState18 = _slicedToArray(_useState17, 2),
303
- cameraFov = _useState18[0],
304
- setCameraFov = _useState18[1];
305
-
306
- var _useState19 = (0, _react.useState)(0),
307
- _useState20 = _slicedToArray(_useState19, 2),
308
- currentRoomIndex = _useState20[0],
309
- setCurrentRoomIndex = _useState20[1];
310
-
311
- var _useState21 = (0, _react.useState)([]),
312
- _useState22 = _slicedToArray(_useState21, 2),
313
- panoramas = _useState22[0],
314
- setPanoramas = _useState22[1];
315
-
316
- var _useState23 = (0, _react.useState)(null),
317
- _useState24 = _slicedToArray(_useState23, 2),
318
- viewer = _useState24[0],
319
- setViewer = _useState24[1];
320
-
321
- var changePanorama = function changePanorama(panorama) {
322
- setCurrentRoomIndex(panorama['panorama_index']);
323
- viewer.setPanorama(panorama);
324
- };
325
-
326
- var setScale = function setScale() {
327
- if (!viewer) return;
328
- var image = document.querySelector('.widget-tab__panorama-map img');
329
- var imageWidth = image.naturalWidth;
330
- var imageHeight = image.naturalHeight;
331
- var imageDelta = imageWidth / imageHeight;
332
- var maxWidth = 200;
333
- var maxHeight = _store.default.config.height - 200;
334
- var width = maxWidth;
335
- var height = width / imageDelta;
336
-
337
- if (height >= maxHeight) {
338
- height = maxHeight;
339
- width = height * imageDelta;
340
- }
341
-
342
- setMapSize({
343
- width: "".concat(width, "px"),
344
- height: "".concat(height, "px")
345
- });
346
- setPlanScale((0, _panoramaHelpers.getScale)({
347
- width: width,
348
- height: height
349
- }, json));
350
- viewer.onWindowResize(_store.default.config.width, _store.default.config.height);
351
- };
352
-
353
- var onImageLoaded = function onImageLoaded() {
354
- setScale();
355
- setMapDisabledState(!json);
356
- };
357
-
358
- var getDotPosition = function getDotPosition(_ref5) {
359
- var left = _ref5.left,
360
- top = _ref5.top;
361
- return {
362
- left: "".concat(left * planScale.X, "px"),
363
- top: "".concat(top * planScale.Y, "px")
364
- };
365
- };
366
-
367
- var updateCameraFov = function updateCameraFov(fov) {
368
- setCameraFov(fov);
369
- viewer.camera.fov = fov;
370
- viewer.camera.currentFov = fov;
371
- viewer.camera.updateProjectionMatrix();
372
- };
373
-
374
- var toggleFov = function toggleFov() {
375
- if (viewer.camera.fov === cameraFovValues.x1) {
376
- updateCameraFov(cameraFovValues.x2);
377
- return;
378
- }
379
-
380
- updateCameraFov(cameraFovValues.x1);
381
- };
382
-
383
- var getAngle = function getAngle(control) {
384
- if (control.alpha) {
385
- return control.alpha - THREE.MathUtils.degToRad(control.screenOrientation);
386
- }
387
-
388
- return control.getAzimuthalAngle();
389
- };
390
-
391
- var toggleAutoplay = function toggleAutoplay() {
392
- setAutoplayState(!autoplayEnabled);
393
-
394
- if (autoplayEnabled) {
395
- viewer.disableAutoRate();
396
-
397
- if (deviceOrientationStatus === _deviceOrientationStatuses.deviceOrientationStatuses.GRANTED) {
398
- viewer.enableControl(DEVICEORIENTATION);
399
- }
400
-
401
- return;
402
- }
403
-
404
- if (viewer.getControlId() !== 'orbit') {
405
- viewer.enableControl(ORBIT);
406
- }
407
-
408
- viewer.enableAutoRate();
409
- };
410
-
411
- (0, _react.useEffect)(function () {
412
- if (!panoramas.length) return;
413
- var container = document.querySelector('.widget-tab__panorama-overlay');
414
- var newViewer = new PANOLENS.Viewer({
415
- autoRotateActivationDuration: 1000,
416
- cameraFov: cameraFovValues.x1,
417
- autoHideInfospot: false,
418
- controlButtons: [],
419
- container: container
420
- });
421
-
422
- var preventCameraFovChange = function preventCameraFovChange(e) {
423
- e.preventDefault();
424
- e.stopPropagation();
425
- newViewer.camera.fov = newViewer.camera.currentFov;
426
- newViewer.camera.updateProjectionMatrix();
427
- };
428
-
429
- container.addEventListener('mousewheel', preventCameraFovChange);
430
- container.addEventListener('touchmove', preventCameraFovChange);
431
- panoramas.forEach(function (panorama) {
432
- if (!panorama.panorama_id) return;
433
- panorama.addEventListener('enter', function (_ref6) {
434
- var target = _ref6.target;
435
- return setCurrentRoomIndex(target['panorama_index']);
436
- });
437
- newViewer.add(panorama);
438
- });
439
- newViewer.scene.rotation.y = Math.PI / 2;
440
- newViewer.camera.currentFov = cameraFovValues.x1;
441
- setViewer(newViewer);
442
- var camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 1, 1000);
443
- var orientationControls = new _threeDeviceOrientation.default(camera);
444
-
445
- var animate = function animate() {
446
- window.requestAnimationFrame(animate);
447
- orientationControls.update();
448
- var fovElement = document.querySelector('.widget-tab__panorama-map__fov');
449
- if (!fovElement) return;
450
- var angle = -getAngle(newViewer.getControl());
451
- fovElement.style.transform = "translate(-50%, -50%) rotate(".concat(angle, "rad)");
452
- };
453
-
454
- animate();
455
- }, [panoramas]);
456
- (0, _react.useEffect)(setScale, [json, viewer, _store.default.config.width, _store.default.config.height]);
457
- (0, _react.useEffect)(function () {
458
- return setPanoramas(getPanoramas(json, images, setLoadingState));
459
- }, [json, images]);
460
-
461
- var requestDeviceOrientation = function requestDeviceOrientation() {
462
- return DeviceOrientationEvent.requestPermission().then(function (status) {
463
- setDeviceOrientationStatus(status);
464
-
465
- if (status !== _deviceOrientationStatuses.deviceOrientationStatuses.GRANTED) {
466
- viewer.enableControl(ORBIT);
467
- return;
468
- }
469
-
470
- viewer.enableControl(DEVICEORIENTATION);
471
- });
472
- };
473
-
474
- var onStart = function onStart() {
475
- setInstructionsState(false);
476
- if (!_deviceStore.default.isMobile && !_deviceStore.default.isTablet) return;
477
-
478
- var allowDeviceOrientation = function allowDeviceOrientation() {
479
- window.removeEventListener('deviceorientation', allowDeviceOrientation);
480
- setDeviceOrientationStatus(_deviceOrientationStatuses.deviceOrientationStatuses.GRANTED);
481
- viewer.enableControl(DEVICEORIENTATION);
482
- };
483
-
484
- try {
485
- if (!DeviceOrientationEvent.requestPermission) {
486
- window.addEventListener('deviceorientation', allowDeviceOrientation);
487
- return;
488
- }
489
-
490
- return requestDeviceOrientation();
491
- } catch (error) {
492
- console.error(error.message);
493
- }
494
- };
495
-
496
- var getRoomPointsAsString = function getRoomPointsAsString(points) {
497
- return points.map(function (_ref7) {
498
- var _ref8 = _slicedToArray(_ref7, 2),
499
- x = _ref8[0],
500
- y = _ref8[1];
501
-
502
- return [x * planScale.X, y * planScale.Y];
503
- }).flat().filter(function (num) {
504
- return !isNaN(num);
505
- }).toString();
506
- };
507
-
508
- var openMap = function openMap() {
509
- _store.default.hideControls();
510
-
511
- setMapState(true);
512
- };
513
-
514
- var closeMap = function closeMap() {
515
- _store.default.showControls();
516
-
517
- setMapState(false);
518
- };
519
-
520
- var onMapClick = function onMapClick(event) {
521
- if (loadingState) return;
522
-
523
- if (_store.default.config.width <= _deviceWidth.deviceWidth.tablet) {
524
- if (!mapOpen) {
525
- openMap();
526
- return;
527
- }
528
- }
529
-
530
- var map = document.querySelector('.widget-tab__panorama-map');
531
- var mapScale = map.getBoundingClientRect().width / map.offsetWidth;
532
- var image = document.querySelector('.widget-tab__panorama-map img');
533
- var offset = image.getBoundingClientRect();
534
- var clientX = event.clientX,
535
- clientY = event.clientY;
536
- var x = (clientX - offset.left) / mapScale / planScale.X;
537
- var y = (clientY - offset.top) / mapScale / planScale.Y;
538
- var availablePanoramas = panoramas.filter(function (_ref9) {
539
- var userData = _ref9.userData;
540
- return (0, _geometric.pointInPolygon)([x, y], userData.points);
541
- });
542
-
543
- var _getClosestPanorama2 = (0, _panoramaHelpers.getClosestPanorama)([x, y], availablePanoramas),
544
- panorama = _getClosestPanorama2.panorama;
545
-
546
- closeMap();
547
- if (!panorama) return;
548
- changePanorama(panorama);
549
- };
550
-
551
- var getMapClass = function getMapClass() {
552
- var className = 'widget-tab__panorama-map';
553
-
554
- if (isMapDisabled) {
555
- className += ' widget-tab__panorama-map--hidden';
556
- }
557
-
558
- if (mapOpen) {
559
- className += ' widget-tab__panorama-map--scaled';
560
- }
561
-
562
- return className;
563
- };
564
-
565
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
566
- className: "widget-tab__panorama"
567
- }, /*#__PURE__*/_react.default.createElement("div", {
568
- className: "widget-tab__panorama-overlay",
569
- onContextMenu: _helpers.preventRightClick
570
- }), loadingState && /*#__PURE__*/_react.default.createElement(_Loader.default, {
571
- absolute: true
572
- }), mapOpen && /*#__PURE__*/_react.default.createElement("div", {
573
- className: "widget-tab__panorama-close-map",
574
- onClick: closeMap
575
- }, /*#__PURE__*/_react.default.createElement("img", {
576
- src: _close.default,
577
- alt: "close-map"
578
- })), /*#__PURE__*/_react.default.createElement("div", {
579
- className: getMapClass()
580
- }, /*#__PURE__*/_react.default.createElement("img", {
581
- src: planImage,
582
- style: mapSize,
583
- alt: "plan",
584
- onLoad: onImageLoaded
585
- }), !isMapDisabled && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
586
- className: "widget-tab__panorama-map__fov",
587
- style: getDotPosition(((_panoramas$currentRoo = panoramas[currentRoomIndex]) === null || _panoramas$currentRoo === void 0 ? void 0 : _panoramas$currentRoo.userData) || getDefaultUserData())
588
- }), /*#__PURE__*/_react.default.createElement("svg", {
589
- width: mapSize.width,
590
- key: "X-".concat(planScale.X, "-Y-").concat(planScale.Y),
591
- onClick: onMapClick
592
- }, panoramas.map(function (_ref10, index) {
593
- var userData = _ref10.userData;
594
- return /*#__PURE__*/_react.default.createElement("polygon", {
595
- key: index,
596
- points: getRoomPointsAsString(userData.points)
597
- });
598
- })))), /*#__PURE__*/_react.default.createElement("div", {
599
- className: "widget-tab__panorama-controls"
600
- }, /*#__PURE__*/_react.default.createElement("button", {
601
- className: "widget-tab__panorama-controls-button",
602
- onClick: toggleFov
603
- }, /*#__PURE__*/_react.default.createElement("img", {
604
- src: cameraFov === cameraFovValues.x1 ? _x.default : _x2.default,
605
- alt: "scale-icon"
606
- })), /*#__PURE__*/_react.default.createElement("button", {
607
- className: "widget-tab__panorama-controls-button",
608
- onClick: toggleAutoplay
609
- }, /*#__PURE__*/_react.default.createElement("img", {
610
- src: autoplayEnabled ? _rotationClose.default : _rotation.default,
611
- alt: "rotation-icon"
612
- })))), showInstructions && /*#__PURE__*/_react.default.createElement(_Instructions.default, {
613
- disabled: disabled,
614
- steps: instructionSteps,
615
- onClick: onStart
616
- }));
617
- };
618
-
619
- var _default = PanoramaTab;
620
- exports.default = _default;
1
+ "use strict";function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var _react=_interopRequireWildcard(require("react")),_deviceStore=_interopRequireDefault(require("../store/deviceStore")),_locale=_interopRequireDefault(require("../locale")),_store=_interopRequireDefault(require("../store")),THREE=_interopRequireWildcard(require("three")),PANOLENS=_interopRequireWildcard(require("panolens")),_threeDeviceOrientation=_interopRequireDefault(require("three-device-orientation")),_geometric=require("geometric"),_deviceOrientationStatuses=require("../enums/deviceOrientationStatuses"),_deviceWidth=require("../enums/deviceWidth"),_imageExtentions=require("../enums/imageExtentions"),_helpers=require("../utils/helpers"),_panoramaHelpers=require("../utils/panoramaHelpers"),_Loader=_interopRequireDefault(require("./Loader")),_Instructions=_interopRequireDefault(require("./Instructions")),_spotIcon=_interopRequireDefault(require("../assets/img/spot-icon.png")),_doorIcon=_interopRequireDefault(require("../assets/img/door-icon.png")),_handMove=_interopRequireDefault(require("../assets/icons/hand-move.svg")),_handResearch=_interopRequireDefault(require("../assets/icons/hand-research.svg")),_rotationClose=_interopRequireDefault(require("../assets/icons/rotation-close.svg")),_rotation=_interopRequireDefault(require("../assets/icons/rotation.svg")),_x=_interopRequireDefault(require("../assets/icons/1x.svg")),_x2=_interopRequireDefault(require("../assets/icons/2x.svg")),_close=_interopRequireDefault(require("../assets/icons/close.svg"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,a=new WeakMap;return(_getRequireWildcardCache=function(e){return e?a:t})(e)}function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!==_typeof(e)&&"function"!=typeof e)return{default:e};t=_getRequireWildcardCache(t);if(t&&t.has(e))return t.get(e);var a,r,n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(a in e)"default"!==a&&Object.prototype.hasOwnProperty.call(e,a)&&((r=o?Object.getOwnPropertyDescriptor(e,a):null)&&(r.get||r.set)?Object.defineProperty(n,a,r):n[a]=e[a]);return n.default=e,t&&t.set(e,n),n}function _slicedToArray(e,t){return _arrayWithHoles(e)||_iterableToArrayLimit(e,t)||_unsupportedIterableToArray(e,t)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var a=Object.prototype.toString.call(e).slice(8,-1);return"Map"===(a="Object"===a&&e.constructor?e.constructor.name:a)||"Set"===a?Array.from(e):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var a=0,r=new Array(t);a<t;a++)r[a]=e[a];return r}function _iterableToArrayLimit(e,t){var a=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=a){var r,n,o=[],i=!0,c=!1;try{for(a=a.call(e);!(i=(r=a.next()).done)&&(o.push(r.value),!t||o.length!==t);i=!0);}catch(e){c=!0,n=e}finally{try{i||null==a.return||a.return()}finally{if(c)throw n}}return o}}function _arrayWithHoles(e){if(Array.isArray(e))return e}var _PANOLENS$CONTROLS=PANOLENS.CONTROLS,DEVICEORIENTATION=_PANOLENS$CONTROLS.DEVICEORIENTATION,ORBIT=_PANOLENS$CONTROLS.ORBIT,pathName="Panorama_0_0_",cameraFovValues={x1:90,x2:60},getDefaultUserData=function(){return{left:0,top:0,points:[]}},createPanorama=function(e,t,a){e=new PANOLENS.ImagePanorama(e);return e.userData=getDefaultUserData(),e.panorama_id=t+1,e.addEventListener("progress",function(e){a(!0),e.progress.loaded/e.progress.total*100==100&&a(!1)}),e.addEventListener("enter",function(){return a(!1)}),e},getPanoramas=function(l,e,s){if(!l)return e.map(function(e,t){return createPanorama(e,t,s)});var a=l.Floors[0].Units[0].Rooms.reduce(function(o,i,c){var u=e.filter(function(e){var t=e.indexOf(pathName)+pathName.length;if(t<pathName.length)return!1;var a=String(c),r=String((0,_imageExtentions.removeExtention)(e.substring(t))).split(".")[0],t=(r.toLowerCase().includes(_panoramaHelpers.cameraIdBeginning)&&(e=r.toLowerCase().indexOf(_panoramaHelpers.cameraIdBeginning)-1,r=r.slice(0,e)),Math.max(a.length,r.length));return(0,_panoramaHelpers.getArrayFromNumber)(t).every(function(e){return r[e]===a[e]})});return u.length&&u.forEach(function(e){var t,e=createPanorama(e,c,s),a=(e.room_images=u,e.room_id=i.ID,(0,_panoramaHelpers.getRoomCoordinates)(i,l.Floors[0].Walls,l.Vertices)),r=_slicedToArray((0,_geometric.polygonMean)(a),2),n=r[0],r=r[1];e.src.toLowerCase().includes(_panoramaHelpers.cameraIdBeginning)&&(n=(t=(0,_panoramaHelpers.getCameraFromSrc)(l,e.src)).Location.X,r=t.Location.Y),e.userData={left:n,top:r,points:a},e.room_id===_store.default.initialPanoramaRoomId?o.unshift(e):o.push(e)}),o},[]);return a.map(function(t,e){t.panorama_index=e;e=l.Floors[0].Units[0].Rooms.find(function(e){return e.ID===t.room_id});return t.linkedSpots.length?t:setPanoramaLinks(l,e,t,a)})},setPanoramaLinks=function(n,o,i,c){var u=[i.userData.left,i.userData.top];return i.room_images.forEach(function(t){var e,a;t!==i.src&&(e=c.find(function(e){return e.src===t}),(a=(0,_panoramaHelpers.getCameraFromSrc)(n,e.src))&&connectPanorama(i,e,a.Location,u,!1))}),n.Floors[0].Doors.forEach(function(e){var t,a=e.Location,r=e.Walls;!r.some(function(t){return o.Walls.some(function(e){return e===t})})||(t=n.Floors[0].Units[0].Rooms.find(function(e){var t=e.Walls.some(function(t){return r.some(function(e){return t===e})}),e=e.ID===o.ID;return t&&!e}))&&(e=c.filter(function(e){return e.room_id===t.ID}),(e=(0,_panoramaHelpers.getClosestPanorama)([a.X,a.Y],e).panorama)&&connectPanorama(i,e,a,u,!0))}),i},connectPanorama=function(e,t,a,r){var n=4<arguments.length&&void 0!==arguments[4]&&arguments[4],o=a.Y-r[1],a=a.X-r[0],r=n?-10:-100,i=(n?_doorIcon:_spotIcon).default,i="".concat(i,"?id=").concat(e.panorama_index,"-").concat(e.panorama_id,"-").concat(Math.random()),c=(0,_geometric.lineLength)([[0,0],[o,a]])/120*20,c=50<c?50:c,n=n?c:c-15,c=new THREE.Vector3(o,r,a);e.link(t,c,n,i)},PanoramaTab=function(e){function t(){var e,t,a,r;N&&(e=(e=document.querySelector(".widget-tab__panorama-map img")).naturalWidth/e.naturalHeight,(t=_store.default.config.height-200)<=(r=(a=200)/e)&&(a=(r=t)*e),g({width:"".concat(a,"px"),height:"".concat(r,"px")}),E((0,_panoramaHelpers.getScale)({width:a,height:r},n)),N.onWindowResize(_store.default.config.width,_store.default.config.height))}function a(e){T(e),N.camera.fov=e,N.camera.currentFov=e,N.camera.updateProjectionMatrix()}function i(){_store.default.showControls(),h(!1)}var n=e.json,r=e.planImage,o=e.images,e=e.disabled,c=[{icon:_handMove.default,text:_locale.default.getLocaleText("rotate-plan")},{icon:_handResearch.default,text:_locale.default.getLocaleText("research-plan")}],u=_slicedToArray((0,_react.useState)(_deviceOrientationStatuses.deviceOrientationStatuses.DENIED),2),l=u[0],s=u[1],u=_slicedToArray((0,_react.useState)(!0),2),d=u[0],_=u[1],u=_slicedToArray((0,_react.useState)(!0),2),f=u[0],m=u[1],u=_slicedToArray((0,_react.useState)({width:"200px",height:"auto"}),2),p=u[0],g=u[1],u=_slicedToArray((0,_react.useState)(!1),2),v=u[0],h=u[1],u=_slicedToArray((0,_react.useState)({X:1,Y:1}),2),y=u[0],E=u[1],u=_slicedToArray((0,_react.useState)(!0),2),b=u[0],R=u[1],u=_slicedToArray((0,_react.useState)(!1),2),S=u[0],O=u[1],u=_slicedToArray((0,_react.useState)(cameraFovValues.x1),2),q=u[0],T=u[1],u=_slicedToArray((0,_react.useState)(0),2),D=u[0],w=u[1],u=_slicedToArray((0,_react.useState)([]),2),A=u[0],I=u[1],u=_slicedToArray((0,_react.useState)(null),2),N=u[0],x=u[1];(0,_react.useEffect)(function(){var e,r,t,n;A.length&&(e=document.querySelector(".widget-tab__panorama-overlay"),r=new PANOLENS.Viewer({autoRotateActivationDuration:1e3,cameraFov:cameraFovValues.x1,autoHideInfospot:!1,controlButtons:[],container:e}),e.addEventListener("mousewheel",t=function(e){e.preventDefault(),e.stopPropagation(),r.camera.fov=r.camera.currentFov,r.camera.updateProjectionMatrix()}),e.addEventListener("touchmove",t),A.forEach(function(e){e.panorama_id&&(e.addEventListener("enter",function(e){e=e.target;return w(e.panorama_index)}),r.add(e))}),r.scene.rotation.y=Math.PI/2,r.camera.currentFov=cameraFovValues.x1,x(r),t=new THREE.PerspectiveCamera(75,e.clientWidth/e.clientHeight,1,1e3),n=new _threeDeviceOrientation.default(t),function e(){window.requestAnimationFrame(e),n.update();var t,a=document.querySelector(".widget-tab__panorama-map__fov");a&&(t=-((t=r.getControl()).alpha?t.alpha-THREE.MathUtils.degToRad(t.screenOrientation):t.getAzimuthalAngle()),a.style.transform="translate(-50%, -50%) rotate(".concat(t,"rad)"))}())},[A]),(0,_react.useEffect)(t,[n,N,_store.default.config.width,_store.default.config.height]),(0,_react.useEffect)(function(){return I(getPanoramas(n,o,m))},[n,o]);return _react.default.createElement(_react.default.Fragment,null,_react.default.createElement("div",{className:"widget-tab__panorama"},_react.default.createElement("div",{className:"widget-tab__panorama-overlay",onContextMenu:_helpers.preventRightClick}),f&&_react.default.createElement(_Loader.default,{absolute:!0}),v&&_react.default.createElement("div",{className:"widget-tab__panorama-close-map",onClick:i},_react.default.createElement("img",{src:_close.default,alt:"close-map"})),_react.default.createElement("div",{className:(u="widget-tab__panorama-map",b&&(u+=" widget-tab__panorama-map--hidden"),v&&(u+=" widget-tab__panorama-map--scaled"),u)},_react.default.createElement("img",{src:r,style:p,alt:"plan",onLoad:function(){t(),R(!n)}}),!b&&_react.default.createElement(_react.default.Fragment,null,_react.default.createElement("div",{className:"widget-tab__panorama-map__fov",style:(r=(null==(u=A[D])?void 0:u.userData)||getDefaultUserData(),b=r.left,r=r.top,{left:"".concat(b*y.X,"px"),top:"".concat(r*y.Y,"px")})}),_react.default.createElement("svg",{width:p.width,key:"X-".concat(y.X,"-Y-").concat(y.Y),onClick:function(e){if(!f){if(_store.default.config.width<=_deviceWidth.deviceWidth.tablet&&!v)return _store.default.hideControls(),void h(!0);var t=document.querySelector(".widget-tab__panorama-map"),t=t.getBoundingClientRect().width/t.offsetWidth,a=document.querySelector(".widget-tab__panorama-map img").getBoundingClientRect(),r=e.clientX,e=e.clientY,n=(r-a.left)/t/y.X,o=(e-a.top)/t/y.Y,r=A.filter(function(e){e=e.userData;return(0,_geometric.pointInPolygon)([n,o],e.points)}),e=(0,_panoramaHelpers.getClosestPanorama)([n,o],r).panorama;i(),e&&(w((a=e).panorama_index),N.setPanorama(a))}}},A.map(function(e,t){e=e.userData;return _react.default.createElement("polygon",{key:t,points:e.points.map(function(e){var e=_slicedToArray(e,2),t=e[0],e=e[1];return[t*y.X,e*y.Y]}).flat().filter(function(e){return!isNaN(e)}).toString()})})))),_react.default.createElement("div",{className:"widget-tab__panorama-controls"},_react.default.createElement("button",{className:"widget-tab__panorama-controls-button",onClick:function(){N.camera.fov===cameraFovValues.x1?a(cameraFovValues.x2):a(cameraFovValues.x1)}},_react.default.createElement("img",{src:(q===cameraFovValues.x1?_x:_x2).default,alt:"scale-icon"})),_react.default.createElement("button",{className:"widget-tab__panorama-controls-button",onClick:function(){if(O(!S),S)return N.disableAutoRate(),void(l===_deviceOrientationStatuses.deviceOrientationStatuses.GRANTED&&N.enableControl(DEVICEORIENTATION));"orbit"!==N.getControlId()&&N.enableControl(ORBIT),N.enableAutoRate()}},_react.default.createElement("img",{src:(S?_rotationClose:_rotation).default,alt:"rotation-icon"})))),d&&_react.default.createElement(_Instructions.default,{disabled:e,steps:c,onClick:function(){if(_(!1),_deviceStore.default.isMobile||_deviceStore.default.isTablet){var e=function e(){window.removeEventListener("deviceorientation",e),s(_deviceOrientationStatuses.deviceOrientationStatuses.GRANTED),N.enableControl(DEVICEORIENTATION)};try{return DeviceOrientationEvent.requestPermission?DeviceOrientationEvent.requestPermission().then(function(e){s(e),e!==_deviceOrientationStatuses.deviceOrientationStatuses.GRANTED?N.enableControl(ORBIT):N.enableControl(DEVICEORIENTATION)}):void window.addEventListener("deviceorientation",e)}catch(e){console.error(e.message)}}}}))},_default=PanoramaTab;exports.default=_default;
2
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNvbXBvbmVudHMvUGFub3JhbWFUYWIuanMiXSwibmFtZXMiOlsiX3JlYWN0IiwiX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQiLCJyZXF1aXJlIiwiX2RldmljZVN0b3JlIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9sb2NhbGUiLCJfc3RvcmUiLCJUSFJFRSIsIlBBTk9MRU5TIiwiX3RocmVlRGV2aWNlT3JpZW50YXRpb24iLCJfZ2VvbWV0cmljIiwiX2RldmljZU9yaWVudGF0aW9uU3RhdHVzZXMiLCJfZGV2aWNlV2lkdGgiLCJfaW1hZ2VFeHRlbnRpb25zIiwiX2hlbHBlcnMiLCJfcGFub3JhbWFIZWxwZXJzIiwiX0xvYWRlciIsIl9JbnN0cnVjdGlvbnMiLCJfc3BvdEljb24iLCJfZG9vckljb24iLCJfaGFuZE1vdmUiLCJfaGFuZFJlc2VhcmNoIiwiX3JvdGF0aW9uQ2xvc2UiLCJfcm90YXRpb24iLCJfeCIsIl94MiIsIl9jbG9zZSIsIl9QQU5PTEVOUyRDT05UUk9MUyIsIkNPTlRST0xTIiwiREVWSUNFT1JJRU5UQVRJT04iLCJPUkJJVCIsInBhdGhOYW1lIiwiY2FtZXJhRm92VmFsdWVzIiwieDEiLCJ4MiIsImdldERlZmF1bHRVc2VyRGF0YSIsImxlZnQiLCJ0b3AiLCJwb2ludHMiLCJjcmVhdGVQYW5vcmFtYSIsImltYWdlIiwiaW5kZXgiLCJzZXRMb2FkaW5nU3RhdGUiLCJwYW5vcmFtYSIsIkltYWdlUGFub3JhbWEiLCJ1c2VyRGF0YSIsImFkZEV2ZW50TGlzdGVuZXIiLCJldmVudCIsInByb2dyZXNzIiwibG9hZGVkIiwidG90YWwiLCJnZXRQYW5vcmFtYXMiLCJqc29uIiwiaW1hZ2VzIiwibWFwIiwicGFub3JhbWFzIiwiRmxvb3JzIiwiVW5pdHMiLCJSb29tcyIsInJlZHVjZSIsImFjYyIsImpzb25Sb29tIiwicm9vbUltYWdlcyIsImZpbHRlciIsImltZyIsInBhbm9yYW1hSWRJbmRleCIsImluZGV4T2YiLCJsZW5ndGgiLCJpbmRleEFzU3RyaW5nIiwiU3RyaW5nIiwicGFub3JhbWFJZCIsInJlbW92ZUV4dGVudGlvbiIsInN1YnN0cmluZyIsInNwbGl0IiwibWF4SW5kZXhMZW5ndGgiLCJ0b0xvd2VyQ2FzZSIsImluY2x1ZGVzIiwiY2FtZXJhSWRCZWdpbm5pbmciLCJjYW1lcmFJZEluZGV4Iiwic2xpY2UiLCJNYXRoIiwibWF4IiwiZ2V0QXJyYXlGcm9tTnVtYmVyIiwiZXZlcnkiLCJpIiwiZm9yRWFjaCIsInJvb21Qb2ludHMiLCJJRCIsImdldFJvb21Db29yZGluYXRlcyIsIldhbGxzIiwiVmVydGljZXMiLCJfcG9seWdvbk1lYW4yIiwiX3NsaWNlZFRvQXJyYXkiLCJwb2x5Z29uTWVhbiIsInNyYyIsIkxvY2F0aW9uIiwicHVzaCIsImN1cnJlbnRSb29tIiwicm9vbSIsImxpbmtlZFNwb3RzIiwic2V0UGFub3JhbWFMaW5rcyIsImNlbnRlciIsImltYWdlSW5Sb29tIiwiZ2V0Q2FtZXJhRnJvbVNyYyIsImNvbm5lY3RQYW5vcmFtYSIsImNvbm5lY3RlZFBhbm9yYW1hIiwiY3VycmVudENhbWVyYSIsInNvbWUiLCJkb29yV2FsbElkIiwicm9vbVdhbGxJZCIsInJvb21IYXNTYW1lV2FsbCIsImlzU2FtZVJvb20iLCJhdmFpbGFibGVQYW5vcmFtYXMiLCJnZXRDbG9zZXN0UGFub3JhbWEiLCJYIiwiWSIsInN0b3JlIiwiaW5pdGlhbFBhbm9yYW1hUm9vbUlkIiwiaXNEb29yTGluayIsImFyZ3VtZW50cyIsInVuZGVmaW5lZCIsImxvY2F0aW9uWSIsImxvY2F0aW9uIiwiaWNvbiIsImRvb3JJY29uIiwic3BvdEljb24iLCJpY29uVXJsIiwiY29uY2F0IiwicmFuZG9tIiwic2NhbGUiLCJmaW5hbFNjYWxlIiwicmVzdWx0U2NhbGUiLCJwb3NpdGlvbiIsIlZlY3RvcjMiLCJsb2NhdGlvblgiLCJsb2NhdGlvbloiLCJsaW5rIiwiUGFub3JhbWFUYWIiLCJfcmVmNCIsInNldFNjYWxlIiwiaW1hZ2VEZWx0YSIsIndpZHRoIiwiaGVpZ2h0Iiwidmlld2VyIiwiZG9jdW1lbnQiLCJxdWVyeVNlbGVjdG9yIiwibmF0dXJhbEhlaWdodCIsImNvbmZpZyIsImNvbm5lY3RlZFJvb20iLCJtYXhIZWlnaHQiLCJzZXRQbGFuU2NhbGUiLCJnZXRTY2FsZSIsIm9uV2luZG93UmVzaXplIiwibGluZUxlbmd0aCIsInNldENhbWVyYUZvdiIsImZvdiIsImN1cnJlbnRGb3YiLCJ1cGRhdGVQcm9qZWN0aW9uTWF0cml4IiwidXBkYXRlQ2FtZXJhRm92IiwiY2FtZXJhIiwicGxhbkltYWdlIiwiZGlzYWJsZWQiLCJpbnN0cnVjdGlvblN0ZXBzIiwiSGFuZE1vdmVJY29uIiwidGV4dCIsImxvY2FsZVN0b3JlIiwiZ2V0TG9jYWxlVGV4dCIsIl91c2VTdGF0ZTIiLCJ1c2VTdGF0ZSIsImRldmljZU9yaWVudGF0aW9uU3RhdHVzZXMiLCJERU5JRUQiLCJzZXREZXZpY2VPcmllbnRhdGlvblN0YXR1cyIsIl91c2VTdGF0ZTQiLCJzZXRJbnN0cnVjdGlvbnNTdGF0ZSIsIl91c2VTdGF0ZTYiLCJsb2FkaW5nU3RhdGUiLCJfdXNlU3RhdGU4IiwibWFwU2l6ZSIsInNldE1hcFNpemUiLCJfdXNlU3RhdGUxMCIsIm1hcE9wZW4iLCJzZXRNYXBTdGF0ZSIsIl91c2VTdGF0ZTEyIiwiX3VzZVN0YXRlMTQiLCJfdXNlU3RhdGUxNiIsImF1dG9wbGF5RW5hYmxlZCIsInNldEF1dG9wbGF5U3RhdGUiLCJEb29ycyIsIl91c2VTdGF0ZTIwIiwiX3VzZVN0YXRlMjIiLCJzZXRQYW5vcmFtYXMiLCJfdXNlU3RhdGUyNCIsInVzZUVmZmVjdCIsImNvbnRhaW5lciIsIm5ld1ZpZXdlciIsImNhbWVyYUZvdiIsIlZpZXdlciIsImF1dG9Sb3RhdGVBY3RpdmF0aW9uRHVyYXRpb24iLCJjb250cm9sQnV0dG9ucyIsImUiLCJwcmV2ZW50RGVmYXVsdCIsInN0b3BQcm9wYWdhdGlvbiIsInByZXZlbnRDYW1lcmFGb3ZDaGFuZ2UiLCJpc01hcERpc2FibGVkIiwicGFub3JhbWFfaWQiLCJzZXRNYXBEaXNhYmxlZFN0YXRlIiwiX3JlZjYiLCJ0YXJnZXQiLCJzZXRDdXJyZW50Um9vbUluZGV4IiwiYWRkIiwieSIsIlBJIiwic2V0Vmlld2VyIiwiUGVyc3BlY3RpdmVDYW1lcmEiLCJjbGllbnRXaWR0aCIsImNsaWVudEhlaWdodCIsIkRldmljZU9yaWVudGF0aW9uQ29udHJvbHMiLCJhbmltYXRlIiwid2luZG93IiwicmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwiY3VycmVudFJvb21JbmRleCIsInVwZGF0ZSIsImZvdkVsZW1lbnQiLCJnZXRDb250cm9sIiwiZGVnVG9SYWQiLCJjb250cm9sIiwic2NyZWVuT3JpZW50YXRpb24iLCJIYW5kUmVzZWFyY2hJY29uIiwic3R5bGUiLCJ0cmFuc2Zvcm0iLCJhbmdsZSIsImNoYW5nZVBhbm9yYW1hIiwic2V0UGFub3JhbWEiLCJkZWZhdWx0IiwiY3JlYXRlRWxlbWVudCIsIkZyYWdtZW50Iiwib25Db250ZXh0TWVudSIsInByZXZlbnRSaWdodENsaWNrIiwiY2xhc3NOYW1lIiwiQ2xvc2VJY29uIiwiYWx0IiwiZ2V0Q29udHJvbElkIiwib25Mb2FkIiwiX3JlZjUiLCJkZWZhdWx0U2NhbGUiLCJwbGFuU2NhbGUiLCJrZXkiLCJvbkNsaWNrIiwiaGlkZUNvbnRyb2xzIiwiZ2V0QW5nbGUiLCJnZXRCb3VuZGluZ0NsaWVudFJlY3QiLCJvZmZzZXRXaWR0aCIsIm9mZnNldCIsImFscGhhIiwiY2xpZW50WCIsImNsaWVudFkiLCJ4IiwibWFwU2NhbGUiLCJnZXRBemltdXRoYWxBbmdsZSIsIl9yZWY5IiwicG9pbnRJblBvbHlnb24iLCJjbG9zZU1hcCIsImVuYWJsZUNvbnRyb2wiLCJmbGF0IiwibnVtIiwiaXNOYU4iLCJ0b1N0cmluZyIsIm9yaWVudGF0aW9uQ29udHJvbHMiLCJkZXZpY2VPcmllbnRhdGlvblN0YXR1cyIsIkdSQU5URUQiLCJlbmFibGVBdXRvUmF0ZSIsIlJvdGF0aW9uQ2xvc2VJY29uIiwiUm90YXRpb25JY29uIiwic2hvd0luc3RydWN0aW9ucyIsInN0ZXBzIiwiaXNNb2JpbGUiLCJkZXZpY2VTdG9yZSIsImlzVGFibGV0IiwiYWxsb3dEZXZpY2VPcmllbnRhdGlvbiIsInJlcXVlc3RQZXJtaXNzaW9uIiwidGhlbiIsInN0YXR1cyIsImltYWdlV2lkdGgiLCJuYXR1cmFsV2lkdGgiLCJtYXhXaWR0aCIsIm9uSW1hZ2VMb2FkZWQiLCJlcnJvciIsIm1lc3NhZ2UiXSwibWFwcGluZ3MiOiI0VUFBQSxJQUFBQSxPQUFBQyx3QkFBQUMsUUFBQSxVQUNBQyxhQUFBQyx1QkFBQUYsUUFBQSx5QkFDQUcsUUFBQUQsdUJBQUFGLFFBQUEsY0FDQUksT0FBQUYsdUJBQUFGLFFBQUEsYUFDQUssTUFBQU4sd0JBQUFDLFFBQUEsVUFDQU0sU0FBQVAsd0JBQUFDLFFBQUEsYUFDQU8sd0JBQUFMLHVCQUFBRixRQUFBLDZCQUNBUSxXQUFBUixRQUFBLGFBQ0FTLDJCQUFBVCxRQUFBLHNDQVJBVSxhQUFBVixRQUFBLHdCQVVBVyxpQkFBQVgsUUFBQSw0QkFUQVksU0FBQVosUUFBQSxvQkFXQWEsaUJBQUFiLFFBQUEsNEJBTkFjLFFBQUFaLHVCQUFBRixRQUFBLGFBZ0JBZSxjQUFBYix1QkFBQUYsUUFBQSxtQkFFQWdCLFVBQUFkLHVCQUFBRixRQUFBLGdDQWhCQWlCLFVBQUFmLHVCQUFBRixRQUFBLGdDQWtCQWtCLFVBQUFoQix1QkFBQUYsUUFBQSxrQ0FqQkFtQixjQUFBakIsdUJBQUFGLFFBQUEsc0NBbUJBb0IsZUFBQWxCLHVCQUFBRixRQUFBLHVDQWxCQXFCLFVBQUFuQix1QkFBQUYsUUFBQSxpQ0FvQkFzQixHQUFBcEIsdUJBQUFGLFFBQUEsMkJBbkJBdUIsSUFBQXJCLHVCQUFBRixRQUFBLDJCQXFCQXdCLE9BQUF0Qix1QkFBQUYsUUFBQSw4QixzM0RBRUEsSUFBQXlCLG1CQUFxQ25CLFNBQVNvQixTQUF0Q0Msa0JBQVJGLG1CQUFRRSxrQkFBbUJDLE1BQTNCSCxtQkFBMkJHLE1BRXJCQyxTQUFXLGdCQWRqQkMsZ0JBQUEsQ0FBQUMsR0FBQSxH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LDBCQUFQb0csU0FBdUIvSCxFQUFNd0gsY0FBS3hILG9CQWtJN0MsSUFqSStCQSxPQUFBQSx1QkFBQUEsa0JBbEIzQkgsdUJBQVc0SSxvQkFBTUMsS0FBQSxTQUFBQyxHQUNyQjlHLEVBQWE4RyxHQUVQalAsSUFBUXdHLDJCQUFBQSwwQkFBdUI2SCxRQUMvQmEsRUFBQUEsY0FBbUJDLE9BR3pCNUksRUFBTTZJLGNBQU4vUCwwQkFXeUN1QixPQUF6Q04saUJBQUEsb0JBQUF3TyxHQUtJTyxNQUFBQSxHQUNKbEosUUFBUW1KLE1BQUFBLEVBQUFDLGdCLFNBbUdWL0YiLCJmaWxlIjoiY29tcG9uZW50cy9QYW5vcmFtYVRhYi5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBSZWFjdCwgeyB1c2VTdGF0ZSwgdXNlRWZmZWN0IH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IGRldmljZVN0b3JlIGZyb20gJy4uL3N0b3JlL2RldmljZVN0b3JlJztcbmltcG9ydCBsb2NhbGVTdG9yZSBmcm9tICcuLi9sb2NhbGUnO1xuaW1wb3J0IHN0b3JlIGZyb20gJy4uL3N0b3JlJztcbmltcG9ydCAqIGFzIFRIUkVFIGZyb20gJ3RocmVlJztcbmltcG9ydCAqIGFzIFBBTk9MRU5TIGZyb20gJ3Bhbm9sZW5zJztcbmltcG9ydCBEZXZpY2VPcmllbnRhdGlvbkNvbnRyb2xzIGZyb20gJ3RocmVlLWRldmljZS1vcmllbnRhdGlvbic7XG5pbXBvcnQgeyBsaW5lTGVuZ3RoLCBwb2x5Z29uTWVhbiwgcG9pbnRJblBvbHlnb24gfSBmcm9tICdnZW9tZXRyaWMnO1xuaW1wb3J0IHsgZGV2aWNlT3JpZW50YXRpb25TdGF0dXNlcyB9IGZyb20gJy4uL2VudW1zL2RldmljZU9yaWVudGF0aW9uU3RhdHVzZXMnO1xuaW1wb3J0IHsgZGV2aWNlV2lkdGggfSBmcm9tICcuLi9lbnVtcy9kZXZpY2VXaWR0aCc7XG5pbXBvcnQgeyByZW1vdmVFeHRlbnRpb24gfSBmcm9tICcuLi9lbnVtcy9pbWFnZUV4dGVudGlvbnMnO1xuaW1wb3J0IHsgcHJldmVudFJpZ2h0Q2xpY2sgfSBmcm9tICcuLi91dGlscy9oZWxwZXJzJztcbmltcG9ydCB7XG4gIGdldFNjYWxlLFxuICBnZXRDYW1lcmFGcm9tU3JjLFxuICBjYW1lcmFJZEJlZ2lubmluZyxcbiAgZ2V0Um9vbUNvb3JkaW5hdGVzLFxuICBnZXRBcnJheUZyb21OdW1iZXIsXG4gIGdldENsb3Nlc3RQYW5vcmFtYSxcbn0gZnJvbSAnLi4vdXRpbHMvcGFub3JhbWFIZWxwZXJzJztcblxuaW1wb3J0IExvYWRlciBmcm9tICcuL0xvYWRlcic7XG5pbXBvcnQgSW5zdHJ1Y3Rpb25zIGZyb20gJy4vSW5zdHJ1Y3Rpb25zJztcblxuaW1wb3J0IHNwb3RJY29uIGZyb20gJy4uL2Fzc2V0cy9pbWcvc3BvdC1pY29uLnBuZyc7XG5pbXBvcnQgZG9vckljb24gZnJvbSAnLi4vYXNzZXRzL2ltZy9kb29yLWljb24ucG5nJztcbmltcG9ydCBIYW5kTW92ZUljb24gZnJvbSAnLi4vYXNzZXRzL2ljb25zL2hhbmQtbW92ZS5zdmcnO1xuaW1wb3J0IEhhbmRSZXNlYXJjaEljb24gZnJvbSAnLi4vYXNzZXRzL2ljb25zL2hhbmQtcmVzZWFyY2guc3ZnJztcbmltcG9ydCBSb3RhdGlvbkNsb3NlSWNvbiBmcm9tICcuLi9hc3NldHMvaWNvbnMvcm90YXRpb24tY2xvc2Uuc3ZnJztcbmltcG9ydCBSb3RhdGlvbkljb24gZnJvbSAnLi4vYXNzZXRzL2ljb25zL3JvdGF0aW9uLnN2Zyc7XG5pbXBvcnQgU2NhbGVJY29uMXggZnJvbSAnLi4vYXNzZXRzL2ljb25zLzF4LnN2Zyc7XG5pbXBvcnQgU2NhbGVJY29uMnggZnJvbSAnLi4vYXNzZXRzL2ljb25zLzJ4LnN2Zyc7XG5pbXBvcnQgQ2xvc2VJY29uIGZyb20gJy4uL2Fzc2V0cy9pY29ucy9jbG9zZS5zdmcnO1xuXG5jb25zdCB7IERFVklDRU9SSUVOVEFUSU9OLCBPUkJJVCB9ID0gUEFOT0xFTlMuQ09OVFJPTFM7XG5cbmNvbnN0IHBhdGhOYW1lID0gJ1Bhbm9yYW1hXzBfMF8nO1xuY29uc3QgY2FtZXJhRm92VmFsdWVzID0geyB4MTogOTAsIHgyOiA2MCB9O1xuXG5jb25zdCBnZXREZWZhdWx0VXNlckRhdGEgPSAoKSA9PiAoeyBsZWZ0OiAwLCB0b3A6IDAsIHBvaW50czogW10gfSk7XG5cbmNvbnN0IGNyZWF0ZVBhbm9yYW1hID0gKGltYWdlLCBpbmRleCwgc2V0TG9hZGluZ1N0YXRlKSA9PiB7XG4gIGNvbnN0IHBhbm9yYW1hID0gbmV3IFBBTk9MRU5TLkltYWdlUGFub3JhbWEoaW1hZ2UpO1xuICBwYW5vcmFtYS51c2VyRGF0YSA9IGdldERlZmF1bHRVc2VyRGF0YSgpO1xuICBwYW5vcmFtYVsncGFub3JhbWFfaWQnXSA9IGluZGV4ICsgMTtcblxuICBwYW5vcmFtYS5hZGRFdmVudExpc3RlbmVyKCdwcm9ncmVzcycsIChldmVudCkgPT4ge1xuICAgIHNldExvYWRpbmdTdGF0ZSh0cnVlKTtcbiAgICBpZiAoKGV2ZW50LnByb2dyZXNzLmxvYWRlZCAvIGV2ZW50LnByb2dyZXNzLnRvdGFsKSAqIDEwMCA9PT0gMTAwKSB7XG4gICAgICBzZXRMb2FkaW5nU3RhdGUoZmFsc2UpO1xuICAgIH1cbiAgfSk7XG4gIHBhbm9yYW1hLmFkZEV2ZW50TGlzdGVuZXIoJ2VudGVyJywgKCkgPT4gc2V0TG9hZGluZ1N0YXRlKGZhbHNlKSk7XG5cbiAgcmV0dXJuIHBhbm9yYW1hO1xufTtcblxuY29uc3QgZ2V0UGFub3JhbWFzID0gKGpzb24sIGltYWdlcywgc2V0TG9hZGluZ1N0YXRlKSA9PiB7XG4gIGlmICghanNvbikgcmV0dXJuIGltYWdlcy5tYXAoKGltYWdlLCBpbmRleCkgPT4gY3JlYXRlUGFub3JhbWEoaW1hZ2UsIGluZGV4LCBzZXRMb2FkaW5nU3RhdGUpKTtcblxuICBjb25zdCBwYW5vcmFtYXMgPSBqc29uLkZsb29yc1swXS5Vbml0c1swXS5Sb29tcy5yZWR1Y2UoKGFjYywganNvblJvb20sIGluZGV4KSA9PiB7XG4gICAgY29uc3Qgcm9vbUltYWdlcyA9IGltYWdlcy5maWx0ZXIoKGltZykgPT4ge1xuICAgICAgY29uc3QgcGFub3JhbWFJZEluZGV4ID0gaW1nLmluZGV4T2YocGF0aE5hbWUpICsgcGF0aE5hbWUubGVuZ3RoO1xuICAgICAgaWYgKHBhbm9yYW1hSWRJbmRleCA8IHBhdGhOYW1lLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICBjb25zdCBpbmRleEFzU3RyaW5nID0gU3RyaW5nKGluZGV4KTtcbiAgICAgIGxldCBwYW5vcmFtYUlkID0gU3RyaW5nKHJlbW92ZUV4dGVudGlvbihpbWcuc3Vic3RyaW5nKHBhbm9yYW1hSWRJbmRleCkpKS5zcGxpdCgnLicpWzBdO1xuXG4gICAgICBpZiAocGFub3JhbWFJZC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGNhbWVyYUlkQmVnaW5uaW5nKSkge1xuICAgICAgICBjb25zdCBjYW1lcmFJZEluZGV4ID0gcGFub3JhbWFJZC50b0xvd2VyQ2FzZSgpLmluZGV4T2YoY2FtZXJhSWRCZWdpbm5pbmcpIC0gMTtcbiAgICAgICAgcGFub3JhbWFJZCA9IHBhbm9yYW1hSWQuc2xpY2UoMCwgY2FtZXJhSWRJbmRleCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1heEluZGV4TGVuZ3RoID0gTWF0aC5tYXgoaW5kZXhBc1N0cmluZy5sZW5ndGgsIHBhbm9yYW1hSWQubGVuZ3RoKTtcbiAgICAgIGNvbnN0IGltYWdlSW5Sb29tID0gZ2V0QXJyYXlGcm9tTnVtYmVyKG1heEluZGV4TGVuZ3RoKS5ldmVyeSgoaSkgPT4ge1xuICAgICAgICByZXR1cm4gcGFub3JhbWFJZFtpXSA9PT0gaW5kZXhBc1N0cmluZ1tpXTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gaW1hZ2VJblJvb207XG4gICAgfSk7XG5cbiAgICBpZiAoIXJvb21JbWFnZXMubGVuZ3RoKSByZXR1cm4gYWNjO1xuXG4gICAgcm9vbUltYWdlcy5mb3JFYWNoKChpbWFnZSkgPT4ge1xuICAgICAgY29uc3QgcGFub3JhbWEgPSBjcmVhdGVQYW5vcmFtYShpbWFnZSwgaW5kZXgsIHNldExvYWRpbmdTdGF0ZSk7XG4gICAgICBwYW5vcmFtYVsncm9vbV9pbWFnZXMnXSA9IHJvb21JbWFnZXM7XG4gICAgICBwYW5vcmFtYVsncm9vbV9pZCddID0ganNvblJvb20uSUQ7XG5cbiAgICAgIGNvbnN0IHJvb21Qb2ludHMgPSBnZXRSb29tQ29vcmRpbmF0ZXMoanNvblJvb20sIGpzb24uRmxvb3JzWzBdLldhbGxzLCBqc29uLlZlcnRpY2VzKTtcbiAgICAgIGxldCBbbGVmdCwgdG9wXSA9IHBvbHlnb25NZWFuKHJvb21Qb2ludHMpO1xuXG4gICAgICBpZiAocGFub3JhbWEuc3JjLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoY2FtZXJhSWRCZWdpbm5pbmcpKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRDYW1lcmEgPSBnZXRDYW1lcmFGcm9tU3JjKGpzb24sIHBhbm9yYW1hLnNyYyk7XG4gICAgICAgIGxlZnQgPSBjdXJyZW50Q2FtZXJhLkxvY2F0aW9uLlg7XG4gICAgICAgIHRvcCA9IGN1cnJlbnRDYW1lcmEuTG9jYXRpb24uWTtcbiAgICAgIH1cblxuICAgICAgcGFub3JhbWEudXNlckRhdGEgPSB7IGxlZnQsIHRvcCwgcG9pbnRzOiByb29tUG9pbnRzIH07XG5cbiAgICAgIGlmIChwYW5vcmFtYVsncm9vbV9pZCddID09PSBzdG9yZS5pbml0aWFsUGFub3JhbWFSb29tSWQpIHtcbiAgICAgICAgYWNjLnVuc2hpZnQocGFub3JhbWEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWNjLnB1c2gocGFub3JhbWEpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGFjYztcbiAgfSwgW10pO1xuXG4gIHJldHVybiBwYW5vcmFtYXMubWFwKChwYW5vcmFtYSwgaW5kZXgpID0+IHtcbiAgICBwYW5vcmFtYVsncGFub3JhbWFfaW5kZXgnXSA9IGluZGV4O1xuICAgIGNvbnN0IGN1cnJlbnRSb29tID0ganNvbi5GbG9vcnNbMF0uVW5pdHNbMF0uUm9vbXMuZmluZCgocm9vbSkgPT4gcm9vbS5JRCA9PT0gcGFub3JhbWFbJ3Jvb21faWQnXSk7XG4gICAgaWYgKCFwYW5vcmFtYS5saW5rZWRTcG90cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBzZXRQYW5vcmFtYUxpbmtzKGpzb24sIGN1cnJlbnRSb29tLCBwYW5vcmFtYSwgcGFub3JhbWFzKTtcbiAgICB9XG4gICAgcmV0dXJuIHBhbm9yYW1hO1xuICB9KTtcbn07XG5cbmNvbnN0IHNldFBhbm9yYW1hTGlua3MgPSAoanNvbiwgY3VycmVudFJvb20sIHBhbm9yYW1hLCBwYW5vcmFtYXMpID0+IHtcbiAgY29uc3QgY2VudGVyID0gW3Bhbm9yYW1hLnVzZXJEYXRhLmxlZnQsIHBhbm9yYW1hLnVzZXJEYXRhLnRvcF07XG5cbiAgcGFub3JhbWFbJ3Jvb21faW1hZ2VzJ10uZm9yRWFjaCgoaW1hZ2UpID0+IHtcbiAgICBpZiAoaW1hZ2UgPT09IHBhbm9yYW1hLnNyYykgcmV0dXJuO1xuXG4gICAgY29uc3QgY29ubmVjdGVkUGFub3JhbWEgPSBwYW5vcmFtYXMuZmluZCgoeyBzcmMgfSkgPT4gc3JjID09PSBpbWFnZSk7XG4gICAgY29uc3QgY3VycmVudENhbWVyYSA9IGdldENhbWVyYUZyb21TcmMoanNvbiwgY29ubmVjdGVkUGFub3JhbWEuc3JjKTtcblxuICAgIGlmICghY3VycmVudENhbWVyYSkgcmV0dXJuO1xuXG4gICAgY29ubmVjdFBhbm9yYW1hKHBhbm9yYW1hLCBjb25uZWN0ZWRQYW5vcmFtYSwgY3VycmVudENhbWVyYS5Mb2NhdGlvbiwgY2VudGVyLCBmYWxzZSk7XG4gIH0pO1xuXG4gIGpzb24uRmxvb3JzWzBdLkRvb3JzLmZvckVhY2goKHsgTG9jYXRpb24sIFdhbGxzIH0pID0+IHtcbiAgICBpZiAoIVdhbGxzLnNvbWUoKGRvb3JXYWxsSWQpID0+IGN1cnJlbnRSb29tLldhbGxzLnNvbWUoKHJvb21XYWxsSWQpID0+IHJvb21XYWxsSWQgPT09IGRvb3JXYWxsSWQpKSkgcmV0dXJuO1xuXG4gICAgY29uc3QgY29ubmVjdGVkUm9vbSA9IGpzb24uRmxvb3JzWzBdLlVuaXRzWzBdLlJvb21zLmZpbmQoKHJvb20pID0+IHtcbiAgICAgIGNvbnN0IHJvb21IYXNTYW1lV2FsbCA9IHJvb20uV2FsbHMuc29tZSgocm9vbVdhbGxJZCkgPT4gV2FsbHMuc29tZSgoZG9vcldhbGxJZCkgPT4gcm9vbVdhbGxJZCA9PT0gZG9vcldhbGxJZCkpO1xuICAgICAgY29uc3QgaXNTYW1lUm9vbSA9IHJvb20uSUQgPT09IGN1cnJlbnRSb29tLklEO1xuICAgICAgcmV0dXJuIHJvb21IYXNTYW1lV2FsbCAmJiAhaXNTYW1lUm9vbTtcbiAgICB9KTtcblxuICAgIGlmICghY29ubmVjdGVkUm9vbSkgcmV0dXJuO1xuXG4gICAgY29uc3QgYXZhaWxhYmxlUGFub3JhbWFzID0gcGFub3JhbWFzLmZpbHRlcigoeyByb29tX2lkIH0pID0+IHJvb21faWQgPT09IGNvbm5lY3RlZFJvb20uSUQpO1xuICAgIGNvbnN0IHsgcGFub3JhbWE6IGNvbm5lY3RlZFBhbm9yYW1hIH0gPSBnZXRDbG9zZXN0UGFub3JhbWEoW0xvY2F0aW9uLlgsIExvY2F0aW9uLlldLCBhdmFpbGFibGVQYW5vcmFtYXMpO1xuXG4gICAgaWYgKCFjb25uZWN0ZWRQYW5vcmFtYSkgcmV0dXJuO1xuXG4gICAgY29ubmVjdFBhbm9yYW1hKHBhbm9yYW1hLCBjb25uZWN0ZWRQYW5vcmFtYSwgTG9jYXRpb24sIGNlbnRlciwgdHJ1ZSk7XG4gIH0pO1xuXG4gIHJldHVybiBwYW5vcmFtYTtcbn07XG5cbmNvbnN0IGNvbm5lY3RQYW5vcmFtYSA9IChwYW5vcmFtYSwgY29ubmVjdGVkUGFub3JhbWEsIGxvY2F0aW9uLCBjZW50ZXIsIGlzRG9vckxpbmsgPSBmYWxzZSkgPT4ge1xuICBjb25zdCBsb2NhdGlvblggPSBsb2NhdGlvbi5ZIC0gY2VudGVyWzFdO1xuICBjb25zdCBsb2NhdGlvblkgPSBsb2NhdGlvbi5YIC0gY2VudGVyWzBdO1xuICBjb25zdCBsb2NhdGlvblogPSBpc0Rvb3JMaW5rID8gLTEwIDogLTEwMDtcbiAgY29uc3QgaWNvbiA9IGlzRG9vckxpbmsgPyBkb29ySWNvbiA6IHNwb3RJY29uO1xuICBjb25zdCBpY29uVXJsID0gYCR7aWNvbn0/aWQ9JHtwYW5vcmFtYVsncGFub3JhbWFfaW5kZXgnXX0tJHtwYW5vcmFtYVsncGFub3JhbWFfaWQnXX0tJHtNYXRoLnJhbmRvbSgpfWA7XG4gIGNvbnN0IGRlZmF1bHRTY2FsZSA9IDIwO1xuICBjb25zdCBtYXhTY2FsZSA9IDUwO1xuXG4gIGNvbnN0IGRlZmF1bHRMZW5ndGggPSAxMjA7XG4gIGNvbnN0IGxlbmd0aCA9IGxpbmVMZW5ndGgoW1swLCAwXSwgW2xvY2F0aW9uWCwgbG9jYXRpb25ZXV0pO1xuICBjb25zdCBzY2FsZSA9IChsZW5ndGggLyBkZWZhdWx0TGVuZ3RoKSAqIGRlZmF1bHRTY2FsZTtcbiAgY29uc3QgZmluYWxTY2FsZSA9IHNjYWxlID4gbWF4U2NhbGUgPyBtYXhTY2FsZSA6IHNjYWxlO1xuICBjb25zdCByZXN1bHRTY2FsZSA9IGlzRG9vckxpbmsgPyBmaW5hbFNjYWxlIDogZmluYWxTY2FsZSAtIDE1O1xuICBjb25zdCBwb3NpdGlvbiA9IG5ldyBUSFJFRS5WZWN0b3IzKGxvY2F0aW9uWCwgbG9jYXRpb25aLCBsb2NhdGlvblkpO1xuXG4gIHBhbm9yYW1hLmxpbmsoY29ubmVjdGVkUGFub3JhbWEsIHBvc2l0aW9uLCByZXN1bHRTY2FsZSwgaWNvblVybCk7XG59O1xuXG5jb25zdCBQYW5vcmFtYVRhYiA9ICh7IGpzb24sIHBsYW5JbWFnZSwgaW1hZ2VzLCBkaXNhYmxlZCB9KSA9PiB7XG4gIGNvbnN0IGluc3RydWN0aW9uU3RlcHMgPSBbXG4gICAgeyBpY29uOiBIYW5kTW92ZUljb24sIHRleHQ6IGxvY2FsZVN0b3JlLmdldExvY2FsZVRleHQoJ3JvdGF0ZS1wbGFuJykgfSxcbiAgICB7IGljb246IEhhbmRSZXNlYXJjaEljb24sIHRleHQ6IGxvY2FsZVN0b3JlLmdldExvY2FsZVRleHQoJ3Jlc2VhcmNoLXBsYW4nKSB9LFxuICBdO1xuXG4gIGNvbnN0IFtkZXZpY2VPcmllbnRhdGlvblN0YXR1cywgc2V0RGV2aWNlT3JpZW50YXRpb25TdGF0dXNdID0gdXNlU3RhdGUoZGV2aWNlT3JpZW50YXRpb25TdGF0dXNlcy5ERU5JRUQpO1xuICBjb25zdCBbc2hvd0luc3RydWN0aW9ucywgc2V0SW5zdHJ1Y3Rpb25zU3RhdGVdID0gdXNlU3RhdGUodHJ1ZSk7XG4gIGNvbnN0IFtsb2FkaW5nU3RhdGUsIHNldExvYWRpbmdTdGF0ZV0gPSB1c2VTdGF0ZSh0cnVlKTtcbiAgY29uc3QgW21hcFNpemUsIHNldE1hcFNpemVdID0gdXNlU3RhdGUoeyB3aWR0aDogJzIwMHB4JywgaGVpZ2h0OiAnYXV0bycgfSk7XG4gIGNvbnN0IFttYXBPcGVuLCBzZXRNYXBTdGF0ZV0gPSB1c2VTdGF0ZShmYWxzZSk7XG4gIFxuICBjb25zdCBbcGxhblNjYWxlLCBzZXRQbGFuU2NhbGVdID0gdXNlU3RhdGUoeyBYOiAxLCBZOiAxIH0pO1xuICBjb25zdCBbaXNNYXBEaXNhYmxlZCwgc2V0TWFwRGlzYWJsZWRTdGF0ZV0gPSB1c2VTdGF0ZSh0cnVlKTtcbiAgY29uc3QgW2F1dG9wbGF5RW5hYmxlZCwgc2V0QXV0b3BsYXlTdGF0ZV0gPSB1c2VTdGF0ZShmYWxzZSk7XG4gIGNvbnN0IFtjYW1lcmFGb3YsIHNldENhbWVyYUZvdl0gPSB1c2VTdGF0ZShjYW1lcmFGb3ZWYWx1ZXMueDEpO1xuICBjb25zdCBbY3VycmVudFJvb21JbmRleCwgc2V0Q3VycmVudFJvb21JbmRleF0gPSB1c2VTdGF0ZSgwKTtcbiAgY29uc3QgW3Bhbm9yYW1hcywgc2V0UGFub3JhbWFzXSA9IHVzZVN0YXRlKFtdKTtcbiAgY29uc3QgW3ZpZXdlciwgc2V0Vmlld2VyXSA9IHVzZVN0YXRlKG51bGwpO1xuXG4gIGNvbnN0IGNoYW5nZVBhbm9yYW1hID0gKHBhbm9yYW1hKSA9PiB7XG4gICAgc2V0Q3VycmVudFJvb21JbmRleChwYW5vcmFtYVsncGFub3JhbWFfaW5kZXgnXSk7XG4gICAgdmlld2VyLnNldFBhbm9yYW1hKHBhbm9yYW1hKTtcbiAgfTtcblxuICBjb25zdCBzZXRTY2FsZSA9ICgpID0+IHtcbiAgICBpZiAoIXZpZXdlcikgcmV0dXJuO1xuXG4gICAgY29uc3QgaW1hZ2UgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcud2lkZ2V0LXRhYl9fcGFub3JhbWEtbWFwIGltZycpO1xuICAgIGNvbnN0IGltYWdlV2lkdGggPSBpbWFnZS5uYXR1cmFsV2lkdGg7XG4gICAgY29uc3QgaW1hZ2VIZWlnaHQgPSBpbWFnZS5uYXR1cmFsSGVpZ2h0O1xuICAgIGNvbnN0IGltYWdlRGVsdGEgPSBpbWFnZVdpZHRoIC8gaW1hZ2VIZWlnaHQ7XG4gICAgY29uc3QgbWF4V2lkdGggPSAyMDA7XG4gICAgY29uc3QgbWF4SGVpZ2h0ID0gc3RvcmUuY29uZmlnLmhlaWdodCAtIDIwMDtcbiAgICBsZXQgd2lkdGggPSBtYXhXaWR0aDtcbiAgICBsZXQgaGVpZ2h0ID0gd2lkdGggLyBpbWFnZURlbHRhO1xuXG4gICAgaWYgKGhlaWdodCA+PSBtYXhIZWlnaHQpIHtcbiAgICAgIGhlaWdodCA9IG1heEhlaWdodDtcbiAgICAgIHdpZHRoID0gaGVpZ2h0ICogaW1hZ2VEZWx0YTtcbiAgICB9XG5cbiAgICBzZXRNYXBTaXplKHsgd2lkdGg6IGAke3dpZHRofXB4YCwgaGVpZ2h0OiBgJHtoZWlnaHR9cHhgIH0pO1xuICAgIHNldFBsYW5TY2FsZShnZXRTY2FsZSh7IHdpZHRoLCBoZWlnaHQgfSwganNvbikpO1xuXG4gICAgdmlld2VyLm9uV2luZG93UmVzaXplKHN0b3JlLmNvbmZpZy53aWR0aCwgc3RvcmUuY29uZmlnLmhlaWdodCk7XG4gIH07XG5cbiAgY29uc3Qgb25JbWFnZUxvYWRlZCA9ICgpID0+IHtcbiAgICBzZXRTY2FsZSgpO1xuICAgIHNldE1hcERpc2FibGVkU3RhdGUoIWpzb24pO1xuICB9O1xuXG4gIGNvbnN0IGdldERvdFBvc2l0aW9uID0gKHsgbGVmdCwgdG9wIH0pID0+IHtcbiAgICByZXR1cm4geyBsZWZ0OiBgJHtsZWZ0ICogcGxhblNjYWxlLlh9cHhgLCB0b3A6IGAke3RvcCAqIHBsYW5TY2FsZS5ZfXB4YCB9O1xuICB9O1xuXG4gIGNvbnN0IHVwZGF0ZUNhbWVyYUZvdiA9IChmb3YpID0+IHtcbiAgICBzZXRDYW1lcmFGb3YoZm92KTtcbiAgICB2aWV3ZXIuY2FtZXJhLmZvdiA9IGZvdjtcbiAgICB2aWV3ZXIuY2FtZXJhLmN1cnJlbnRGb3YgPSBmb3Y7XG4gICAgdmlld2VyLmNhbWVyYS51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XG4gIH07XG5cbiAgY29uc3QgdG9nZ2xlRm92ID0gKCkgPT4ge1xuICAgIGlmICh2aWV3ZXIuY2FtZXJhLmZvdiA9PT0gY2FtZXJhRm92VmFsdWVzLngxKSB7XG4gICAgICB1cGRhdGVDYW1lcmFGb3YoY2FtZXJhRm92VmFsdWVzLngyKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdXBkYXRlQ2FtZXJhRm92KGNhbWVyYUZvdlZhbHVlcy54MSk7XG4gIH07XG5cbiAgY29uc3QgZ2V0QW5nbGUgPSAoY29udHJvbCkgPT4ge1xuICAgIGlmIChjb250cm9sLmFscGhhKSB7XG4gICAgICByZXR1cm4gY29udHJvbC5hbHBoYSAtIFRIUkVFLk1hdGhVdGlscy5kZWdUb1JhZChjb250cm9sLnNjcmVlbk9yaWVudGF0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRyb2wuZ2V0QXppbXV0aGFsQW5nbGUoKTtcbiAgfTtcblxuICBjb25zdCB0b2dnbGVBdXRvcGxheSA9ICgpID0+IHtcbiAgICBzZXRBdXRvcGxheVN0YXRlKCFhdXRvcGxheUVuYWJsZWQpO1xuICAgIGlmIChhdXRvcGxheUVuYWJsZWQpIHtcbiAgICAgIHZpZXdlci5kaXNhYmxlQXV0b1JhdGUoKTtcbiAgICAgIGlmIChkZXZpY2VPcmllbnRhdGlvblN0YXR1cyA9PT0gZGV2aWNlT3JpZW50YXRpb25TdGF0dXNlcy5HUkFOVEVEKSB7XG4gICAgICAgIHZpZXdlci5lbmFibGVDb250cm9sKERFVklDRU9SSUVOVEFUSU9OKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHZpZXdlci5nZXRDb250cm9sSWQoKSAhPT0gJ29yYml0Jykge1xuICAgICAgdmlld2VyLmVuYWJsZUNvbnRyb2woT1JCSVQpO1xuICAgIH1cbiAgICB2aWV3ZXIuZW5hYmxlQXV0b1JhdGUoKTtcbiAgfTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghcGFub3JhbWFzLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLndpZGdldC10YWJfX3Bhbm9yYW1hLW92ZXJsYXknKTtcbiAgICBjb25zdCBuZXdWaWV3ZXIgPSBuZXcgUEFOT0xFTlMuVmlld2VyKHtcbiAgICAgIGF1dG9Sb3RhdGVBY3RpdmF0aW9uRHVyYXRpb246IDEwMDAsXG4gICAgICBjYW1lcmFGb3Y6IGNhbWVyYUZvdlZhbHVlcy54MSxcbiAgICAgIGF1dG9IaWRlSW5mb3Nwb3Q6IGZhbHNlLFxuICAgICAgY29udHJvbEJ1dHRvbnM6IFtdLFxuICAgICAgY29udGFpbmVyLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcHJldmVudENhbWVyYUZvdkNoYW5nZSA9IChlKSA9PiB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICBuZXdWaWV3ZXIuY2FtZXJhLmZvdiA9IG5ld1ZpZXdlci5jYW1lcmEuY3VycmVudEZvdjtcbiAgICAgIG5ld1ZpZXdlci5jYW1lcmEudXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpO1xuICAgIH07XG5cbiAgICBjb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V3aGVlbCcsIHByZXZlbnRDYW1lcmFGb3ZDaGFuZ2UpO1xuICAgIGNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCBwcmV2ZW50Q2FtZXJhRm92Q2hhbmdlKTtcblxuICAgIHBhbm9yYW1hcy5mb3JFYWNoKChwYW5vcmFtYSkgPT4ge1xuICAgICAgaWYgKCFwYW5vcmFtYS5wYW5vcmFtYV9pZCkgcmV0dXJuO1xuICAgICAgcGFub3JhbWEuYWRkRXZlbnRMaXN0ZW5lcignZW50ZXInLCAoeyB0YXJnZXQgfSkgPT4gc2V0Q3VycmVudFJvb21JbmRleCh0YXJnZXRbJ3Bhbm9yYW1hX2luZGV4J10pKTtcbiAgICAgIG5ld1ZpZXdlci5hZGQocGFub3JhbWEpO1xuICAgIH0pO1xuXG4gICAgbmV3Vmlld2VyLnNjZW5lLnJvdGF0aW9uLnkgPSBNYXRoLlBJIC8gMjtcbiAgICBuZXdWaWV3ZXIuY2FtZXJhLmN1cnJlbnRGb3YgPSBjYW1lcmFGb3ZWYWx1ZXMueDE7XG5cbiAgICBzZXRWaWV3ZXIobmV3Vmlld2VyKTtcblxuICAgIGNvbnN0IGNhbWVyYSA9IG5ldyBUSFJFRS5QZXJzcGVjdGl2ZUNhbWVyYSg3NSwgY29udGFpbmVyLmNsaWVudFdpZHRoIC8gY29udGFpbmVyLmNsaWVudEhlaWdodCwgMSwgMTAwMCk7XG4gICAgY29uc3Qgb3JpZW50YXRpb25Db250cm9scyA9IG5ldyBEZXZpY2VPcmllbnRhdGlvbkNvbnRyb2xzKGNhbWVyYSk7XG5cbiAgICBjb25zdCBhbmltYXRlID0gKCkgPT4ge1xuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZShhbmltYXRlKTtcbiAgICAgIG9yaWVudGF0aW9uQ29udHJvbHMudXBkYXRlKCk7XG5cbiAgICAgIGNvbnN0IGZvdkVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcud2lkZ2V0LXRhYl9fcGFub3JhbWEtbWFwX19mb3YnKTtcblxuICAgICAgaWYgKCFmb3ZFbGVtZW50KSByZXR1cm47XG5cbiAgICAgIGNvbnN0IGFuZ2xlID0gLWdldEFuZ2xlKG5ld1ZpZXdlci5nZXRDb250cm9sKCkpO1xuICAgICAgZm92RWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlKC01MCUsIC01MCUpIHJvdGF0ZSgke2FuZ2xlfXJhZClgO1xuICAgIH07XG5cbiAgICBhbmltYXRlKCk7XG4gIH0sIFtwYW5vcmFtYXNdKTtcblxuICB1c2VFZmZlY3Qoc2V0U2NhbGUsIFtqc29uLCB2aWV3ZXIsIHN0b3JlLmNvbmZpZy53aWR0aCwgc3RvcmUuY29uZmlnLmhlaWdodF0pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiBzZXRQYW5vcmFtYXMoZ2V0UGFub3JhbWFzKGpzb24sIGltYWdlcywgc2V0TG9hZGluZ1N0YXRlKSksIFtqc29uLCBpbWFnZXNdKTtcblxuICBjb25zdCByZXF1ZXN0RGV2aWNlT3JpZW50YXRpb24gPSAoKSA9PiB7XG4gICAgcmV0dXJuIERldmljZU9yaWVudGF0aW9uRXZlbnQucmVxdWVzdFBlcm1pc3Npb24oKS50aGVuKChzdGF0dXMpID0+IHtcbiAgICAgIHNldERldmljZU9yaWVudGF0aW9uU3RhdHVzKHN0YXR1cyk7XG4gICAgICBpZiAoc3RhdHVzICE9PSBkZXZpY2VPcmllbnRhdGlvblN0YXR1c2VzLkdSQU5URUQpIHtcbiAgICAgICAgdmlld2VyLmVuYWJsZUNvbnRyb2woT1JCSVQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2aWV3ZXIuZW5hYmxlQ29udHJvbChERVZJQ0VPUklFTlRBVElPTik7XG4gICAgfSk7XG4gIH07XG5cbiAgY29uc3Qgb25TdGFydCA9ICgpID0+IHtcbiAgICBzZXRJbnN0cnVjdGlvbnNTdGF0ZShmYWxzZSk7XG5cbiAgICBpZiAoIWRldmljZVN0b3JlLmlzTW9iaWxlICYmICFkZXZpY2VTdG9yZS5pc1RhYmxldCkgcmV0dXJuO1xuXG4gICAgY29uc3QgYWxsb3dEZXZpY2VPcmllbnRhdGlvbiA9ICgpID0+IHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdkZXZpY2VvcmllbnRhdGlvbicsIGFsbG93RGV2aWNlT3JpZW50YXRpb24pO1xuICAgICAgc2V0RGV2aWNlT3JpZW50YXRpb25TdGF0dXMoZGV2aWNlT3JpZW50YXRpb25TdGF0dXNlcy5HUkFOVEVEKTtcbiAgICAgIHZpZXdlci5lbmFibGVDb250cm9sKERFVklDRU9SSUVOVEFUSU9OKTtcbiAgICB9O1xuXG4gICAgdHJ5IHtcbiAgICAgIGlmICghRGV2aWNlT3JpZW50YXRpb25FdmVudC5yZXF1ZXN0UGVybWlzc2lvbikge1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignZGV2aWNlb3JpZW50YXRpb24nLCBhbGxvd0RldmljZU9yaWVudGF0aW9uKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcXVlc3REZXZpY2VPcmllbnRhdGlvbigpO1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGdldFJvb21Qb2ludHNBc1N0cmluZyA9IChwb2ludHMpID0+IHtcbiAgICByZXR1cm4gcG9pbnRzLm1hcCgoW3gsIHldKSA9PiBbeCAqIHBsYW5TY2FsZS5YLCB5ICogcGxhblNjYWxlLlldKS5mbGF0KCkuZmlsdGVyKChudW0pID0+ICFpc05hTihudW0pKS50b1N0cmluZygpO1xuICB9O1xuXG4gIGNvbnN0IG9wZW5NYXAgPSAoKSA9PiB7XG4gICAgc3RvcmUuaGlkZUNvbnRyb2xzKCk7XG4gICAgc2V0TWFwU3RhdGUodHJ1ZSk7XG4gIH07XG5cbiAgY29uc3QgY2xvc2VNYXAgPSAoKSA9PiB7XG4gICAgc3RvcmUuc2hvd0NvbnRyb2xzKCk7XG4gICAgc2V0TWFwU3RhdGUoZmFsc2UpO1xuICB9O1xuXG4gIGNvbnN0IG9uTWFwQ2xpY2sgPSAoZXZlbnQpID0+IHtcbiAgICBpZiAobG9hZGluZ1N0YXRlKSByZXR1cm47XG5cbiAgICBpZiAoc3RvcmUuY29uZmlnLndpZHRoIDw9IGRldmljZVdpZHRoLnRhYmxldCkge1xuICAgICAgaWYgKCFtYXBPcGVuKSB7XG4gICAgICAgIG9wZW5NYXAoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG1hcCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy53aWRnZXQtdGFiX19wYW5vcmFtYS1tYXAnKTtcbiAgICBjb25zdCBtYXBTY2FsZSA9IG1hcC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCAvIG1hcC5vZmZzZXRXaWR0aDtcbiAgICBjb25zdCBpbWFnZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy53aWRnZXQtdGFiX19wYW5vcmFtYS1tYXAgaW1nJyk7XG4gICAgY29uc3Qgb2Zmc2V0ID0gaW1hZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgeyBjbGllbnRYLCBjbGllbnRZIH0gPSBldmVudDtcbiAgICBjb25zdCB4ID0gKChjbGllbnRYIC0gb2Zmc2V0LmxlZnQpIC8gbWFwU2NhbGUpIC8gcGxhblNjYWxlLlg7XG4gICAgY29uc3QgeSA9ICgoY2xpZW50WSAtIG9mZnNldC50b3ApIC8gbWFwU2NhbGUpIC8gcGxhblNjYWxlLlk7XG4gICAgXG4gICAgY29uc3QgYXZhaWxhYmxlUGFub3JhbWFzID0gcGFub3JhbWFzLmZpbHRlcigoeyB1c2VyRGF0YSB9KSA9PiBwb2ludEluUG9seWdvbihbeCwgeV0sIHVzZXJEYXRhLnBvaW50cykpO1xuXG4gICAgY29uc3QgeyBwYW5vcmFtYSB9ID0gZ2V0Q2xvc2VzdFBhbm9yYW1hKFt4LCB5XSwgYXZhaWxhYmxlUGFub3JhbWFzKTtcblxuICAgIGNsb3NlTWFwKCk7XG5cbiAgICBpZiAoIXBhbm9yYW1hKSByZXR1cm47XG5cbiAgICBjaGFuZ2VQYW5vcmFtYShwYW5vcmFtYSk7XG4gIH07XG5cbiAgY29uc3QgZ2V0TWFwQ2xhc3MgPSAoKSA9PiB7XG4gICAgbGV0IGNsYXNzTmFtZSA9ICd3aWRnZXQtdGFiX19wYW5vcmFtYS1tYXAnO1xuICAgIGlmIChpc01hcERpc2FibGVkKSB7XG4gICAgICBjbGFzc05hbWUgKz0gJyB3aWRnZXQtdGFiX19wYW5vcmFtYS1tYXAtLWhpZGRlbic7XG4gICAgfVxuICAgIGlmIChtYXBPcGVuKSB7XG4gICAgICBjbGFzc05hbWUgKz0gJyB3aWRnZXQtdGFiX19wYW5vcmFtYS1tYXAtLXNjYWxlZCc7XG4gICAgfVxuICAgIHJldHVybiBjbGFzc05hbWU7XG4gIH07XG5cbiAgcmV0dXJuIChcbiAgICA8PlxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJ3aWRnZXQtdGFiX19wYW5vcmFtYVwiPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIndpZGdldC10YWJfX3Bhbm9yYW1hLW92ZXJsYXlcIiBvbkNvbnRleHRNZW51PXtwcmV2ZW50UmlnaHRDbGlja30gLz5cbiAgICAgICAge2xvYWRpbmdTdGF0ZSAmJiA8TG9hZGVyIGFic29sdXRlPXt0cnVlfSAvPn1cblxuICAgICAgICB7bWFwT3BlbiAmJiAoXG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJ3aWRnZXQtdGFiX19wYW5vcmFtYS1jbG9zZS1tYXBcIiBvbkNsaWNrPXtjbG9zZU1hcH0+XG4gICAgICAgICAgICA8aW1nIHNyYz17Q2xvc2VJY29ufSBhbHQ9XCJjbG9zZS1tYXBcIiAvPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICApfVxuXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPXtnZXRNYXBDbGFzcygpfT5cbiAgICAgICAgICA8aW1nIHNyYz17cGxhbkltYWdlfSBzdHlsZT17bWFwU2l6ZX0gYWx0PVwicGxhblwiIG9uTG9hZD17b25JbWFnZUxvYWRlZH0gLz5cblxuICAgICAgICAgIHshaXNNYXBEaXNhYmxlZCAmJiAoXG4gICAgICAgICAgICA8PlxuICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwid2lkZ2V0LXRhYl9fcGFub3JhbWEtbWFwX19mb3ZcIlxuICAgICAgICAgICAgICAgIHN0eWxlPXtnZXREb3RQb3NpdGlvbihwYW5vcmFtYXNbY3VycmVudFJvb21JbmRleF0/LnVzZXJEYXRhIHx8IGdldERlZmF1bHRVc2VyRGF0YSgpKX0gLz5cblxuICAgICAgICAgICAgICA8c3ZnIHdpZHRoPXttYXBTaXplLndpZHRofSBrZXk9e2BYLSR7cGxhblNjYWxlLlh9LVktJHtwbGFuU2NhbGUuWX1gfSBvbkNsaWNrPXtvbk1hcENsaWNrfT5cbiAgICAgICAgICAgICAgICB7cGFub3JhbWFzLm1hcCgoeyB1c2VyRGF0YSB9LCBpbmRleCkgPT4gKFxuICAgICAgICAgICAgICAgICAgPHBvbHlnb24ga2V5PXtpbmRleH0gcG9pbnRzPXtnZXRSb29tUG9pbnRzQXNTdHJpbmcodXNlckRhdGEucG9pbnRzKX0gLz5cbiAgICAgICAgICAgICAgICApKX1cbiAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICA8Lz5cbiAgICAgICAgICApfVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJ3aWRnZXQtdGFiX19wYW5vcmFtYS1jb250cm9sc1wiPlxuICAgICAgICAgIDxidXR0b24gY2xhc3NOYW1lPVwid2lkZ2V0LXRhYl9fcGFub3JhbWEtY29udHJvbHMtYnV0dG9uXCIgb25DbGljaz17dG9nZ2xlRm92fT5cbiAgICAgICAgICAgIDxpbWcgc3JjPXtjYW1lcmFGb3YgPT09IGNhbWVyYUZvdlZhbHVlcy54MSA/IFNjYWxlSWNvbjF4IDogU2NhbGVJY29uMnh9IGFsdD1cInNjYWxlLWljb25cIiAvPlxuICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9XCJ3aWRnZXQtdGFiX19wYW5vcmFtYS1jb250cm9scy1idXR0b25cIiBvbkNsaWNrPXt0b2dnbGVBdXRvcGxheX0+XG4gICAgICAgICAgICA8aW1nIHNyYz17YXV0b3BsYXlFbmFibGVkID8gUm90YXRpb25DbG9zZUljb24gOiBSb3RhdGlvbkljb259IGFsdD1cInJvdGF0aW9uLWljb25cIiAvPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICB7c2hvd0luc3RydWN0aW9ucyAmJiA8SW5zdHJ1Y3Rpb25zIGRpc2FibGVkPXtkaXNhYmxlZH0gc3RlcHM9e2luc3RydWN0aW9uU3RlcHN9IG9uQ2xpY2s9e29uU3RhcnR9IC8+fVxuICAgIDwvPlxuICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgUGFub3JhbWFUYWI7XG4iXX0=