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,952 +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 = _interopRequireDefault(require("react"));
11
-
12
- var _mobx = require("mobx");
13
-
14
- var _apiStore = _interopRequireDefault(require("../store/apiStore"));
15
-
16
- var _store = _interopRequireDefault(require("../store"));
17
-
18
- var THREE = _interopRequireWildcard(require("three"));
19
-
20
- var _FBXLoader = require("three/examples/jsm/loaders/FBXLoader");
21
-
22
- var _modelHelpers = require("../utils/modelHelpers");
23
-
24
- var _threeCsg = _interopRequireDefault(require("../utils/csg/three-csg"));
25
-
26
- var _wallTexture = _interopRequireDefault(require("../assets/img/wall-texture.jpg"));
27
-
28
- var _doorTexture = _interopRequireDefault(require("../assets/img/door-texture.jpeg"));
29
-
30
- var _exteriorWallTexture = _interopRequireDefault(require("../assets/img/exterior-wall-texture.jpeg"));
31
-
32
- var _exteriorWallTextureRoughness = _interopRequireDefault(require("../assets/img/exterior-wall-texture-roughness.jpg"));
33
-
34
- 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); }
35
-
36
- 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; }
37
-
38
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
39
-
40
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
41
-
42
- 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."); }
43
-
44
- 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; }
45
-
46
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
47
-
48
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
49
-
50
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
51
-
52
- 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); }
53
-
54
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
55
-
56
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
57
-
58
- 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; }
59
-
60
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
61
-
62
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
63
-
64
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
65
-
66
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
67
-
68
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
69
-
70
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
71
-
72
- (0, _mobx.configure)({
73
- useProxies: 'never'
74
- });
75
- var clippedBuildingConstant = 0.4;
76
- var doorMaterialOptions = {
77
- color: '#DADADA',
78
- side: THREE.DoubleSide
79
- };
80
- var modelLoader = new _FBXLoader.FBXLoader();
81
-
82
- var createDefaultMaterial = function createDefaultMaterial(options) {
83
- return new THREE.MeshStandardMaterial(_objectSpread({
84
- roughness: 1,
85
- metalness: 0
86
- }, options));
87
- };
88
-
89
- var HouseStore = /*#__PURE__*/function () {
90
- function HouseStore(modelStore) {
91
- var _this = this;
92
-
93
- _classCallCheck(this, HouseStore);
94
-
95
- _defineProperty(this, "modelStore", null);
96
-
97
- _defineProperty(this, "apiStore", new _apiStore.default(_store.default.config.API_URL));
98
-
99
- _defineProperty(this, "houseGroup", new THREE.Group());
100
-
101
- _defineProperty(this, "wallsGroup", new THREE.Group());
102
-
103
- _defineProperty(this, "doorsGroup", new THREE.Group());
104
-
105
- _defineProperty(this, "doorMaterial", null);
106
-
107
- _defineProperty(this, "wallsMaterial", null);
108
-
109
- _defineProperty(this, "wallsColor", '#FFFFFF');
110
-
111
- _defineProperty(this, "exteriorWallsMaps", {
112
- map: null,
113
- roughnessMap: null
114
- });
115
-
116
- _defineProperty(this, "exteriorWallsMaterial", null);
117
-
118
- _defineProperty(this, "wallsTextures", []);
119
-
120
- _defineProperty(this, "isDoorsVisible", true);
121
-
122
- _defineProperty(this, "isFullBuildingVisible", true);
123
-
124
- _defineProperty(this, "wallsMaterialType", 'texture');
125
-
126
- _defineProperty(this, "globalPlane", null);
127
-
128
- _defineProperty(this, "clippingPlanes", []);
129
-
130
- _defineProperty(this, "furnitureData", []);
131
-
132
- _defineProperty(this, "loadedModels", {});
133
-
134
- _defineProperty(this, "loadedTextures", {});
135
-
136
- _defineProperty(this, "isShadowsVisible", true);
137
-
138
- (0, _mobx.makeAutoObservable)(this);
139
- this.modelStore = modelStore;
140
- this.houseGroup.name = 'House-Group';
141
- this.globalPlane = new THREE.Plane(new THREE.Vector3(0, -this.wallsHeight - 0.5, 0), 1);
142
- this.clippingPlanes = [this.globalPlane];
143
- this.setCenterPosition().loadTextures().then(function () {
144
- _this.createFloors().createSpaceBetweenWalls().createWalls().createDoors();
145
- });
146
- this.apiStore.loadFurnitureData().then(function (resp) {
147
- _this.furnitureData = resp;
148
-
149
- _this.loadFurniture(0);
150
- });
151
- }
152
-
153
- _createClass(HouseStore, [{
154
- key: "textureLoader",
155
- get: function get() {
156
- return this.modelStore.textureLoader;
157
- }
158
- }, {
159
- key: "sceneScale",
160
- get: function get() {
161
- return this.modelStore.sceneScale;
162
- }
163
- }, {
164
- key: "wallsHeight",
165
- get: function get() {
166
- return this.modelStore.wallsHeight;
167
- }
168
- }, {
169
- key: "json",
170
- get: function get() {
171
- return this.modelStore.json;
172
- }
173
- }, {
174
- key: "vertices",
175
- get: function get() {
176
- return this.json.Vertices;
177
- }
178
- }, {
179
- key: "rooms",
180
- get: function get() {
181
- return this.json.Floors[0].Units[0].Rooms;
182
- }
183
- }, {
184
- key: "walls",
185
- get: function get() {
186
- return this.json.Floors[0].Walls;
187
- }
188
- }, {
189
- key: "exteriorWalls",
190
- get: function get() {
191
- return this.json.Floors[0].ExteriorWalls;
192
- }
193
- }, {
194
- key: "doors",
195
- get: function get() {
196
- var _this2 = this;
197
-
198
- return this.json.Floors[0].Doors.map(function (door) {
199
- return _this2.getParsedAperture(door, 'Door');
200
- });
201
- }
202
- }, {
203
- key: "windows",
204
- get: function get() {
205
- var _this3 = this;
206
-
207
- return this.json.Floors[0].Windows.map(function (window) {
208
- return _this3.getParsedAperture(window, 'Window');
209
- });
210
- }
211
- }, {
212
- key: "apertures",
213
- get: function get() {
214
- return [].concat(_toConsumableArray(this.doors), _toConsumableArray(this.windows));
215
- }
216
- }, {
217
- key: "doorsHeight",
218
- get: function get() {
219
- return this.wallsHeight / 2 + this.wallsHeight / 4;
220
- }
221
- }, {
222
- key: "wallMaterialOptions",
223
- get: function get() {
224
- return {
225
- clippingPlanes: this.clippingPlanes,
226
- color: this.wallsColor,
227
- side: THREE.DoubleSide
228
- };
229
- }
230
- }, {
231
- key: "furniture",
232
- get: function get() {
233
- return this.rooms.reduce(function (acc, _ref) {
234
- var Furniture = _ref.Furniture;
235
- if (!Furniture || !Furniture.length) return acc;
236
- return [].concat(_toConsumableArray(acc), _toConsumableArray(Furniture));
237
- }, []);
238
- }
239
- }, {
240
- key: "getVertexById",
241
- value: function getVertexById(vertexId) {
242
- return this.vertices.find(function (_ref2) {
243
- var ID = _ref2.ID;
244
- return ID === vertexId;
245
- });
246
- }
247
- }, {
248
- key: "getWallById",
249
- value: function getWallById(wallId) {
250
- return this.walls.find(function (_ref3) {
251
- var ID = _ref3.ID;
252
- return ID === wallId;
253
- });
254
- }
255
- }, {
256
- key: "getParsedAperture",
257
- value: function getParsedAperture(aperture, type) {
258
- var Location = aperture.Location,
259
- Walls = aperture.Walls;
260
- var position = new THREE.Vector3(Location.X, Location.Y, Location.Z);
261
- var secondWall = this.getParsedWallById(Walls[1], 1);
262
- var line = new THREE.Line3(secondWall.start, secondWall.end);
263
- var positionOnFirstWall = new THREE.Vector3();
264
- line.closestPointToPoint(position, true, positionOnFirstWall);
265
- var lineBetweenWalls = new THREE.Line3(position, positionOnFirstWall);
266
- var distanceBetweenWalls = lineBetweenWalls.distance();
267
- var positionBetweenWalls = lineBetweenWalls.getCenter(positionOnFirstWall);
268
-
269
- var parsedAperture = _objectSpread(_objectSpread({}, aperture), {}, {
270
- Type: type,
271
- Depth: distanceBetweenWalls,
272
- Location: {
273
- X: positionBetweenWalls.x,
274
- Y: positionBetweenWalls.y,
275
- Z: positionBetweenWalls.z
276
- }
277
- });
278
-
279
- return parsedAperture;
280
- }
281
- }, {
282
- key: "getParsedWallById",
283
- value: function getParsedWallById(wallId) {
284
- var _this4 = this;
285
-
286
- var scale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.sceneScale;
287
- var currentWall = this.getWallById(wallId);
288
-
289
- var _currentWall$Vertices = currentWall.Vertices.map(function (vertexId) {
290
- return _this4.getVertexById(vertexId).Location;
291
- }),
292
- _currentWall$Vertices2 = _slicedToArray(_currentWall$Vertices, 2),
293
- coord1 = _currentWall$Vertices2[0],
294
- coord2 = _currentWall$Vertices2[1];
295
-
296
- return {
297
- id: wallId,
298
- start: {
299
- x: coord1.X * scale,
300
- y: coord1.Y * scale,
301
- z: 0
302
- },
303
- end: {
304
- x: coord2.X * scale,
305
- y: coord2.Y * scale,
306
- z: 0
307
- }
308
- };
309
- }
310
- }, {
311
- key: "getVerticesFromParsedWalls",
312
- value: function getVerticesFromParsedWalls(walls) {
313
- return walls.reduce(function (acc, _ref4) {
314
- var start = _ref4.start,
315
- end = _ref4.end;
316
- acc.push(new THREE.Vector2(start.x, start.y), new THREE.Vector2(end.x, end.y));
317
- return acc;
318
- }, []);
319
- }
320
- }, {
321
- key: "createFloors",
322
- value: function createFloors() {
323
- var _this5 = this;
324
-
325
- this.rooms.forEach(function (_ref5) {
326
- var Walls = _ref5.Walls,
327
- Type = _ref5.Type;
328
- var walls = Walls.map(function (wallId) {
329
- return _this5.getParsedWallById(wallId);
330
- });
331
- var params = (0, _modelHelpers.getFloorParams)(Type);
332
-
333
- var vertices = _this5.getVerticesFromParsedWalls(walls);
334
-
335
- var shape = new THREE.Shape(vertices);
336
- var geometry = new THREE.ShapeGeometry(shape);
337
- var material = createDefaultMaterial({
338
- color: params.color,
339
- side: THREE.DoubleSide
340
- });
341
- var mesh = new THREE.Mesh(geometry, material);
342
- mesh.receiveShadow = true;
343
- mesh.castShadow = false;
344
- mesh.name = 'FloorMesh';
345
-
346
- var callback = function callback(texture, roughnessMap) {
347
- var textureMaterial = createDefaultMaterial({
348
- color: params.color,
349
- side: THREE.DoubleSide,
350
- map: texture
351
- });
352
- mesh.material = textureMaterial;
353
- if (roughnessMap) mesh.material.roughnessMap = roughnessMap;
354
-
355
- _this5.houseGroup.add(mesh);
356
- };
357
-
358
- _this5.loadTexture(params.texture, [0.5, 0.5], function (texture) {
359
- if (!params.roughnessMap) {
360
- callback(texture);
361
- return;
362
- }
363
-
364
- _this5.loadTexture(params.roughnessMap, [0.5, 0.5], function (roughnessMap) {
365
- return callback(texture, roughnessMap);
366
- });
367
- });
368
- });
369
- return this;
370
- }
371
- }, {
372
- key: "createSpaceBetweenWalls",
373
- value: function createSpaceBetweenWalls() {
374
- var _this6 = this;
375
-
376
- var walls = this.exteriorWalls.map(function (wallId) {
377
- return _this6.getParsedWallById(wallId);
378
- });
379
- var vertices = this.getVerticesFromParsedWalls(walls);
380
- var clippedDepth = (this.wallsHeight + 0.5) * clippedBuildingConstant + 0.006;
381
- var depth = this.wallsHeight + 0.002;
382
- var shapeWithHoles = new THREE.Shape(vertices);
383
- var shape = new THREE.Shape(vertices);
384
- this.rooms.forEach(function (_ref6) {
385
- var Walls = _ref6.Walls;
386
- var roomWalls = Walls.map(function (wallId) {
387
- return _this6.getParsedWallById(wallId);
388
- });
389
-
390
- var roomVertices = _this6.getVerticesFromParsedWalls(roomWalls);
391
-
392
- shapeWithHoles.holes.push(new THREE.Shape(roomVertices));
393
- });
394
- var clippedGeometry = new THREE.ExtrudeGeometry(shapeWithHoles, {
395
- depth: clippedDepth,
396
- bevelEnabled: false
397
- });
398
- var flatGeometry = new THREE.ExtrudeGeometry(shape, {
399
- depth: 0.001,
400
- bevelEnabled: false
401
- });
402
- var geometry = new THREE.ExtrudeGeometry(shapeWithHoles, {
403
- depth: depth,
404
- bevelEnabled: false
405
- });
406
- var clippedMaterial = createDefaultMaterial({
407
- side: THREE.DoubleSide,
408
- color: '#5C5C5C'
409
- });
410
- var material = createDefaultMaterial(_objectSpread(_objectSpread({}, this.wallMaterialOptions), {}, {
411
- color: '#5C5C5C'
412
- }));
413
- var clippedMesh = new THREE.Mesh(clippedGeometry, clippedMaterial);
414
- var flatMesh = new THREE.Mesh(flatGeometry, material);
415
- var mesh = new THREE.Mesh(geometry, material);
416
- flatMesh.receiveShadow = false;
417
- flatMesh.castShadow = false;
418
- clippedMesh.position.z = -0.005;
419
- flatMesh.position.z = -0.005;
420
- mesh.position.z = -0.001;
421
- var additionalApertureWidth = 0.25;
422
- var clippedMeshWithApertures = this.subtractApertures(clippedMesh, this.apertures, additionalApertureWidth);
423
- var meshWithApertures = this.subtractApertures(mesh, this.apertures, additionalApertureWidth);
424
- clippedMeshWithApertures.name = 'ClippedSpaceBetweenWalls';
425
- meshWithApertures.name = 'SpaceBetweenWalls';
426
- flatMesh.name = 'FlatSpaceBetweenWalls';
427
- clippedMeshWithApertures.receiveShadow = false;
428
- clippedMeshWithApertures.castShadow = false;
429
- meshWithApertures.receiveShadow = false;
430
- meshWithApertures.castShadow = false;
431
- this.houseGroup.add(flatMesh, clippedMeshWithApertures, meshWithApertures);
432
- return this;
433
- }
434
- }, {
435
- key: "createWalls",
436
- value: function createWalls() {
437
- var _this7 = this;
438
-
439
- var createWall = function createWall(wallId, isExterior) {
440
- var _this7$getParsedWallB = _this7.getParsedWallById(wallId),
441
- start = _this7$getParsedWallB.start,
442
- end = _this7$getParsedWallB.end;
443
-
444
- var wallHalfWidth = 0.005;
445
- var wallShape = new THREE.Shape([new THREE.Vector2(start.x + wallHalfWidth, start.y - wallHalfWidth), new THREE.Vector2(end.x + wallHalfWidth, end.y - wallHalfWidth), new THREE.Vector2(end.x - wallHalfWidth, end.y + wallHalfWidth), new THREE.Vector2(start.x - wallHalfWidth, start.y + wallHalfWidth)]);
446
- var wallGeometry = new THREE.ExtrudeGeometry(wallShape, {
447
- depth: _this7.wallsHeight,
448
- bevelEnabled: false
449
- });
450
- var wallPadGeometry = new THREE.ExtrudeGeometry(wallShape, {
451
- depth: 0.001,
452
- bevelEnabled: false
453
- });
454
- var wallMaterial = isExterior ? _this7.exteriorWallsMaterial : _this7.wallsMaterial;
455
- var wallPadMaterial = createDefaultMaterial(_objectSpread(_objectSpread({}, _this7.wallMaterialOptions), {}, {
456
- color: '#5C5C5C'
457
- }));
458
- var wallClippedPadMaterial = createDefaultMaterial({
459
- side: THREE.DoubleSide,
460
- color: '#5C5C5C'
461
- });
462
-
463
- var apertures = _this7.apertures.filter(function (aperture) {
464
- return aperture.Walls.some(function (id) {
465
- return wallId === id;
466
- });
467
- });
468
-
469
- var wallMesh = _this7.subtractApertures(new THREE.Mesh(wallGeometry, wallMaterial), apertures);
470
-
471
- var wallPadMesh = new THREE.Mesh(wallPadGeometry, wallPadMaterial);
472
- var wallClippedPadMesh = new THREE.Mesh(wallPadGeometry, wallClippedPadMaterial);
473
- wallMesh.castShadow = true;
474
- wallMesh.receiveShadow = !isExterior;
475
- wallPadMesh.castShadow = false;
476
- wallPadMesh.receiveShadow = false;
477
- wallClippedPadMesh.castShadow = false;
478
- wallClippedPadMesh.receiveShadow = false;
479
- wallPadMesh.position.z = _this7.wallsHeight;
480
- wallClippedPadMesh.position.z = (_this7.wallsHeight + 0.5) * clippedBuildingConstant + 0.001;
481
-
482
- var wallClippedPadMeshWithApertures = _this7.subtractApertures(wallClippedPadMesh, apertures);
483
-
484
- wallClippedPadMeshWithApertures.visible = false;
485
- wallClippedPadMeshWithApertures.castShadow = false;
486
- wallClippedPadMeshWithApertures.receiveShadow = false;
487
- var wallGroup = new THREE.Group();
488
- wallGroup.name = 'Wall';
489
- wallGroup.buildingId = wallId;
490
- wallGroup.isExterior = isExterior;
491
- wallGroup.add(wallMesh, wallPadMesh, wallClippedPadMeshWithApertures);
492
-
493
- _this7.wallsGroup.add(wallGroup);
494
- };
495
-
496
- this.exteriorWallsMaterial = createDefaultMaterial(_objectSpread(_objectSpread({}, this.wallMaterialOptions), {}, {
497
- map: this.exteriorWallsMaps.map,
498
- roughnessMap: this.exteriorWallsMaps.roughnessMap,
499
- color: '#FFFFFF'
500
- }));
501
- this.rooms.forEach(function (_ref7) {
502
- var Walls = _ref7.Walls;
503
- return Walls.forEach(function (wallId) {
504
- return createWall(wallId, false);
505
- });
506
- });
507
- this.exteriorWalls.forEach(function (wallId) {
508
- return createWall(wallId, true);
509
- });
510
- this.houseGroup.add(this.wallsGroup);
511
- return this;
512
- }
513
- }, {
514
- key: "createDoors",
515
- value: function createDoors() {
516
- var _this8 = this;
517
-
518
- this.doors.forEach(function (_ref8) {
519
- var Width = _ref8.Width,
520
- Location = _ref8.Location,
521
- Rotation = _ref8.Rotation;
522
- var geometry = new THREE.BoxGeometry(Width * _this8.sceneScale, 0.1, _this8.doorsHeight);
523
- var mesh = new THREE.Mesh(geometry, _this8.doorMaterial);
524
- mesh.position.x = Location.X * _this8.sceneScale;
525
- mesh.position.y = Location.Y * _this8.sceneScale;
526
- mesh.position.z = _this8.doorsHeight / 2;
527
- mesh.rotation.z = THREE.Math.degToRad(Rotation.Yaw);
528
- mesh.receiveShadow = true;
529
- mesh.castShadow = true;
530
-
531
- _this8.doorsGroup.add(mesh);
532
- });
533
- this.houseGroup.add(this.doorsGroup);
534
- return this;
535
- }
536
- }, {
537
- key: "subtractApertures",
538
- value: function subtractApertures(mesh, apertures) {
539
- var _this9 = this;
540
-
541
- var additionalWidth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
542
- var resultMesh = mesh;
543
- apertures.forEach(function (_ref9) {
544
- var Width = _ref9.Width,
545
- Depth = _ref9.Depth,
546
- Location = _ref9.Location,
547
- Rotation = _ref9.Rotation,
548
- Type = _ref9.Type;
549
- var isDoor = Type === 'Door';
550
- var apertureGeometry = new THREE.BoxGeometry((Width + additionalWidth) * _this9.sceneScale, Depth * _this9.sceneScale + 1, (isDoor ? _this9.doorsHeight : _this9.wallsHeight / 2) + additionalWidth * _this9.sceneScale);
551
- var apertureMaterial = createDefaultMaterial({
552
- color: '#00B4F7'
553
- });
554
- var apertureMesh = new THREE.Mesh(apertureGeometry, apertureMaterial);
555
- apertureMesh.rotation.z = THREE.Math.degToRad(Rotation.Yaw);
556
- apertureMesh.position.x = Location.X * _this9.sceneScale;
557
- apertureMesh.position.y = Location.Y * _this9.sceneScale;
558
- apertureMesh.position.z = isDoor ? _this9.doorsHeight / 2 : _this9.wallsHeight / 2;
559
- apertureMesh.updateMatrix();
560
- resultMesh.updateMatrix();
561
-
562
- var apertureBSP = _threeCsg.default.fromMesh(apertureMesh);
563
-
564
- var wallBSP = _threeCsg.default.fromMesh(resultMesh);
565
-
566
- var resultBSP = wallBSP.subtract(apertureBSP);
567
- resultMesh = _threeCsg.default.toMesh(resultBSP, mesh.matrix, resultMesh.material);
568
- });
569
- return resultMesh;
570
- }
571
- }, {
572
- key: "setCenterPosition",
573
- value: function setCenterPosition() {
574
- var _this10 = this;
575
-
576
- var walls = this.exteriorWalls.map(function (wallId) {
577
- return _this10.getParsedWallById(wallId);
578
- });
579
-
580
- var _getMinMaxCoordinates = (0, _modelHelpers.getMinMaxCoordinates)(walls),
581
- maxX = _getMinMaxCoordinates.maxX,
582
- minX = _getMinMaxCoordinates.minX,
583
- maxY = _getMinMaxCoordinates.maxY,
584
- minY = _getMinMaxCoordinates.minY;
585
-
586
- var centerX = (maxX + minX) / 2;
587
- var centerY = (maxY + minY) / 2;
588
- var lightsOffset = 25;
589
- this.houseGroup.position.set(-centerX, -centerY);
590
- var lights = [{
591
- x: centerX - lightsOffset,
592
- y: centerY - lightsOffset,
593
- z: this.wallsHeight * 3,
594
- power: 0.4,
595
- castShadow: true
596
- }, {
597
- x: centerX - lightsOffset,
598
- y: centerY - lightsOffset,
599
- z: this.wallsHeight * 2,
600
- power: 1,
601
- castShadow: false
602
- }, {
603
- x: centerX + lightsOffset,
604
- y: centerY + lightsOffset,
605
- z: this.wallsHeight * 2,
606
- power: 1.1,
607
- castShadow: false
608
- }, {
609
- x: centerX,
610
- y: centerY,
611
- z: this.wallsHeight * 5,
612
- power: 0.1,
613
- castShadow: false
614
- }];
615
- var targetObject = new THREE.Object3D();
616
- targetObject.position.set(centerX, centerY, 0);
617
- this.houseGroup.add(targetObject);
618
- lights.forEach(function (_ref10) {
619
- var x = _ref10.x,
620
- y = _ref10.y,
621
- z = _ref10.z,
622
- power = _ref10.power,
623
- castShadow = _ref10.castShadow;
624
- var light = new THREE.DirectionalLight(0xffffff, power);
625
- light.position.set(x, y, z);
626
- light.shadowLight = castShadow;
627
- light.castShadow = castShadow;
628
- light.shadow.camera.left = -centerX * 2;
629
- light.shadow.camera.right = centerX * 2;
630
- light.shadow.camera.top = centerY * 2;
631
- light.shadow.camera.bottom = -centerY * 2;
632
- light.shadow.camera.zoom = 1;
633
- light.shadow.mapSize = new THREE.Vector2(2048, 2048);
634
- light.shadow.normalBias = 1;
635
- light.target = targetObject;
636
-
637
- _this10.houseGroup.add(light);
638
- });
639
- return this;
640
- }
641
- }, {
642
- key: "loadTexture",
643
- value: function loadTexture(img) {
644
- var repeat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [1, 1];
645
- var callback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {};
646
- this.textureLoader.load(img, function (texture) {
647
- texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
648
- texture.repeat.set(repeat[0], repeat[1]);
649
- texture.flipY = false;
650
- callback(texture);
651
- });
652
- }
653
- }, {
654
- key: "loadTextures",
655
- value: function loadTextures() {
656
- var _this11 = this;
657
-
658
- var assets = [{
659
- img: _wallTexture.default,
660
- repeat: [0.5, 0.5],
661
- callback: function callback(texture) {
662
- _this11.wallsTextures.push({
663
- image: _wallTexture.default,
664
- texture: texture
665
- });
666
-
667
- _this11.wallsMaterial = createDefaultMaterial(_objectSpread(_objectSpread({}, _this11.wallMaterialOptions), {}, {
668
- map: texture
669
- }));
670
- }
671
- }, {
672
- img: _exteriorWallTexture.default,
673
- repeat: [1, 1],
674
- callback: function callback(texture) {
675
- _this11.wallsTextures.push({
676
- image: _exteriorWallTexture.default,
677
- texture: texture
678
- });
679
-
680
- _this11.exteriorWallsMaps.map = texture;
681
- }
682
- }, {
683
- img: _exteriorWallTextureRoughness.default,
684
- repeat: [1, 1],
685
- callback: function callback(texture) {
686
- _this11.wallsTextures.push({
687
- image: _exteriorWallTextureRoughness.default,
688
- texture: texture
689
- });
690
-
691
- _this11.exteriorWallsMaps.roughnessMap = texture;
692
- }
693
- }, {
694
- img: _doorTexture.default,
695
- repeat: [1, 1],
696
- callback: function callback(texture) {
697
- _this11.doorMaterial = createDefaultMaterial(_objectSpread(_objectSpread({}, doorMaterialOptions), {}, {
698
- map: texture
699
- }));
700
- }
701
- }];
702
- return Promise.all(assets.map(function (_ref11) {
703
- var img = _ref11.img,
704
- repeat = _ref11.repeat,
705
- callback = _ref11.callback;
706
- return new Promise(function (resolve) {
707
- _this11.loadTexture(img, repeat, function (texture) {
708
- callback(texture);
709
- resolve();
710
- });
711
- });
712
- }));
713
- }
714
- }, {
715
- key: "loadFurniture",
716
- value: function loadFurniture(index) {
717
- var _this12 = this;
718
-
719
- var furniture = this.furniture[index];
720
- if (!furniture) return;
721
- var furnitureData = this.furnitureData.find(function (_ref12) {
722
- var name = _ref12.name,
723
- type = _ref12.type;
724
- return name === furniture.Model && type === furniture.Type;
725
- });
726
-
727
- if (!furnitureData) {
728
- this.loadFurniture(index + 1);
729
- return;
730
- }
731
-
732
- var mesh = furnitureData.mesh,
733
- textures = furnitureData.textures;
734
- var modelPath = "".concat(this.apiStore.API_URL, "/storage/furniture/").concat(mesh);
735
- var Location = furniture.Location,
736
- Rotation = furniture.Rotation,
737
- ModelName = furniture.Model;
738
- var X = Location.X,
739
- Y = Location.Y,
740
- Z = Location.Z;
741
- var promises = textures.map(function (url) {
742
- var texturePath = "".concat(_this12.apiStore.API_URL, "/storage/furniture/").concat(url);
743
- return new Promise(function (resolve) {
744
- _this12.textureLoader.load(texturePath, function (texture) {
745
- return resolve(texture);
746
- });
747
- });
748
- });
749
-
750
- var onTexturesLoaded = function onTexturesLoaded(result, model) {
751
- var materialsCount = result.reduce(function (acc, _ref13) {
752
- var image = _ref13.image;
753
- if (!image.currentSrc.includes('_D.') && !image.currentSrc.includes('_DA.')) return acc;
754
- return acc += 1;
755
- }, 0);
756
-
757
- var createMaterial = function createMaterial(num) {
758
- var map = result.find(function (_ref14) {
759
- var image = _ref14.image;
760
- return image.currentSrc.includes("".concat(num, "_D.")) || image.currentSrc.includes("".concat(num, "_DA."));
761
- });
762
- var envMap = result.find(function (_ref15) {
763
- var image = _ref15.image;
764
- return image.currentSrc.includes("".concat(num, "_RMO."));
765
- });
766
- var normalMap = result.find(function (_ref16) {
767
- var image = _ref16.image;
768
- return image.currentSrc.includes("".concat(num, "_N."));
769
- });
770
- var material = new THREE.MeshStandardMaterial({
771
- roughness: 1,
772
- transparent: true
773
- });
774
- material.depthWrite = !(ModelName === 'Flower' && num === '01');
775
- if (map) material.map = map;
776
- if (envMap) material.envMap = envMap;
777
- if (normalMap) material.normalMap = normalMap;
778
- return material;
779
- };
780
-
781
- var materials = new THREE.MeshPhysicalMaterial({
782
- roughness: 1,
783
- clearcoat: 1,
784
- clearcoatRoughness: 1,
785
- reflectivity: 0,
786
- fog: false
787
- });
788
-
789
- if (materialsCount === 1) {
790
- materials = createMaterial('');
791
- }
792
-
793
- if (materialsCount > 1) {
794
- materials = _toConsumableArray(Array(materialsCount).keys()).map(function (i) {
795
- var num = i + 1;
796
- var realNum = num < 10 ? "0".concat(num) : num;
797
- return createMaterial(realNum);
798
- });
799
- }
800
-
801
- model.traverse(function (node) {
802
- if (node.isMesh) {
803
- node.material = materials;
804
- node.receiveShadow = true;
805
- node.castShadow = true;
806
- }
807
- });
808
-
809
- _this12.houseGroup.add(model);
810
-
811
- _this12.loadFurniture(index + 1);
812
- };
813
-
814
- var onModelLoaded = function onModelLoaded(originalModel) {
815
- var model = originalModel.clone();
816
- model.scale.set(_this12.sceneScale, _this12.sceneScale, _this12.sceneScale);
817
- model.position.set(X * _this12.sceneScale, Y * _this12.sceneScale, Z * _this12.sceneScale);
818
- model.rotation.set(Math.PI / 2, THREE.Math.degToRad(Rotation.Yaw), 0);
819
- var loadedTextures = _this12.loadedTextures[ModelName];
820
-
821
- if (loadedTextures) {
822
- onTexturesLoaded(loadedTextures, model);
823
- return;
824
- }
825
-
826
- Promise.all(promises).then(function (result) {
827
- onTexturesLoaded(result, model);
828
- _this12.loadedTextures[ModelName] = result;
829
- });
830
- };
831
-
832
- var loadedModel = this.loadedModels[ModelName];
833
-
834
- if (loadedModel) {
835
- onModelLoaded(loadedModel);
836
- return;
837
- }
838
-
839
- modelLoader.load(modelPath, function (model) {
840
- _this12.loadedModels[ModelName] = model;
841
- onModelLoaded(model);
842
- });
843
- } // Actions
844
-
845
- }, {
846
- key: "setShadowsVisibility",
847
- value: function setShadowsVisibility(value) {
848
- this.isShadowsVisible = value;
849
- this.houseGroup.children.forEach(function (node) {
850
- var isLight = node instanceof THREE.DirectionalLight;
851
- if (!isLight) return;
852
- if (!node.shadowLight) return;
853
- node.castShadow = value;
854
- });
855
- }
856
- }, {
857
- key: "setDoorsVisibility",
858
- value: function setDoorsVisibility(value) {
859
- this.isDoorsVisible = value;
860
- this.doorsGroup.children.forEach(function (door) {
861
- return door.visible = value;
862
- });
863
- }
864
- }, {
865
- key: "setCurrentWallsMaterialType",
866
- value: function setCurrentWallsMaterialType(value) {
867
- var _this13 = this;
868
-
869
- this.wallsMaterialType = value;
870
- this.wallsGroup.children.forEach(function (_ref17) {
871
- var children = _ref17.children,
872
- isExterior = _ref17.isExterior;
873
- var wall = children[0];
874
-
875
- if (value === 'texture') {
876
- wall.material = isExterior ? _this13.exteriorWallsMaterial : _this13.wallsMaterial;
877
- return;
878
- }
879
-
880
- var color = isExterior ? '#FFFFFF' : _this13.wallsColor;
881
- wall.material = createDefaultMaterial(_objectSpread(_objectSpread({}, _this13.wallMaterialOptions), {}, {
882
- color: color
883
- }));
884
- });
885
- this.doorsGroup.children.forEach(function (door) {
886
- if (value === 'texture') {
887
- door.material = _this13.doorMaterial;
888
- return;
889
- }
890
-
891
- door.material = createDefaultMaterial(doorMaterialOptions);
892
- });
893
- }
894
- }, {
895
- key: "setCurrentWallColor",
896
- value: function setCurrentWallColor(color) {
897
- this.wallsColor = color;
898
- this.wallsMaterial.color.set(color);
899
- this.wallsGroup.children.forEach(function (_ref18) {
900
- var children = _ref18.children,
901
- isExterior = _ref18.isExterior;
902
- if (isExterior) return;
903
- var wall = children[0];
904
- wall.material.color.set(color);
905
- });
906
- }
907
- }, {
908
- key: "setCurrentWallTexture",
909
- value: function setCurrentWallTexture(texture) {
910
- this.wallsMaterial = createDefaultMaterial(_objectSpread(_objectSpread({}, this.wallMaterialOptions), {}, {
911
- map: texture
912
- }));
913
- this.setCurrentWallsMaterialType('texture');
914
- }
915
- }, {
916
- key: "addWallTexture",
917
- value: function addWallTexture(image) {
918
- var _this14 = this;
919
-
920
- this.loadTexture(image, [0.5, 0.5], function (texture) {
921
- _this14.wallsTextures.push({
922
- image: image,
923
- texture: texture
924
- });
925
-
926
- _this14.setCurrentWallTexture(texture);
927
- });
928
- }
929
- }, {
930
- key: "setFullBuildingVisibility",
931
- value: function setFullBuildingVisibility(value) {
932
- this.isFullBuildingVisible = value;
933
- this.globalPlane.constant = this.isFullBuildingVisible ? 1 : clippedBuildingConstant;
934
- this.wallsGroup.children.forEach(function (_ref19) {
935
- var children = _ref19.children;
936
- return children[2].visible = !value;
937
- });
938
- }
939
- }, {
940
- key: "setPlanMode",
941
- value: function setPlanMode() {
942
- this.setDoorsVisibility(false);
943
- this.setFullBuildingVisibility(false);
944
- this.setCurrentWallsMaterialType('color');
945
- }
946
- }]);
947
-
948
- return HouseStore;
949
- }();
950
-
951
- var _default = HouseStore;
952
- 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=_interopRequireDefault(require("react")),_mobx=require("mobx"),_apiStore=_interopRequireDefault(require("../store/apiStore")),_store=_interopRequireDefault(require("../store")),THREE=_interopRequireWildcard(require("three")),_FBXLoader=require("three/examples/jsm/loaders/FBXLoader"),_modelHelpers=require("../utils/modelHelpers"),_threeCsg=_interopRequireDefault(require("../utils/csg/three-csg")),_wallTexture=_interopRequireDefault(require("../assets/img/wall-texture.jpg")),_doorTexture=_interopRequireDefault(require("../assets/img/door-texture.jpeg")),_exteriorWallTexture=_interopRequireDefault(require("../assets/img/exterior-wall-texture.jpeg")),_exteriorWallTextureRoughness=_interopRequireDefault(require("../assets/img/exterior-wall-texture-roughness.jpg"));function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(_getRequireWildcardCache=function(e){return e?r: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 r,a,o={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&((a=i?Object.getOwnPropertyDescriptor(e,r):null)&&(a.get||a.set)?Object.defineProperty(o,r,a):o[r]=e[r]);return o.default=e,t&&t.set(e,o),o}function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}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 _iterableToArrayLimit(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var a,o,i=[],n=!0,l=!1;try{for(r=r.call(e);!(n=(a=r.next()).done)&&(i.push(a.value),!t||i.length!==t);n=!0);}catch(e){l=!0,o=e}finally{try{n||null==r.return||r.return()}finally{if(l)throw o}}return i}}function _arrayWithHoles(e){if(Array.isArray(e))return e}function _toConsumableArray(e){return _arrayWithoutHoles(e)||_iterableToArray(e)||_unsupportedIterableToArray(e)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread 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 r=Object.prototype.toString.call(e).slice(8,-1);return"Map"===(r="Object"===r&&e.constructor?e.constructor.name:r)||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(e,t):void 0}}function _iterableToArray(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,a=new Array(t);r<t;r++)a[r]=e[r];return a}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var r=0;r<t.length;r++){var a=t[r];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}function _createClass(e,t,r){return t&&_defineProperties(e.prototype,t),r&&_defineProperties(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function ownKeys(t,e){var r,a=Object.keys(t);return Object.getOwnPropertySymbols&&(r=Object.getOwnPropertySymbols(t),e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),a.push.apply(a,r)),a}function _objectSpread(t){for(var e=1;e<arguments.length;e++){var r=null!=arguments[e]?arguments[e]:{};e%2?ownKeys(Object(r),!0).forEach(function(e){_defineProperty(t,e,r[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):ownKeys(Object(r)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))})}return t}function _defineProperty(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}(0,_mobx.configure)({useProxies:"never"});var clippedBuildingConstant=.4,doorMaterialOptions={color:"#DADADA",side:THREE.DoubleSide},modelLoader=new _FBXLoader.FBXLoader,createDefaultMaterial=function(e){return new THREE.MeshStandardMaterial(_objectSpread({roughness:1,metalness:0},e))},HouseStore=function(){function r(e){var t=this;_classCallCheck(this,r),_defineProperty(this,"modelStore",null),_defineProperty(this,"apiStore",new _apiStore.default(_store.default.config.API_URL)),_defineProperty(this,"houseGroup",new THREE.Group),_defineProperty(this,"wallsGroup",new THREE.Group),_defineProperty(this,"doorsGroup",new THREE.Group),_defineProperty(this,"doorMaterial",null),_defineProperty(this,"wallsMaterial",null),_defineProperty(this,"wallsColor","#FFFFFF"),_defineProperty(this,"exteriorWallsMaps",{map:null,roughnessMap:null}),_defineProperty(this,"exteriorWallsMaterial",null),_defineProperty(this,"wallsTextures",[]),_defineProperty(this,"isDoorsVisible",!0),_defineProperty(this,"isFullBuildingVisible",!0),_defineProperty(this,"wallsMaterialType","texture"),_defineProperty(this,"globalPlane",null),_defineProperty(this,"clippingPlanes",[]),_defineProperty(this,"furnitureData",[]),_defineProperty(this,"loadedModels",{}),_defineProperty(this,"loadedTextures",{}),_defineProperty(this,"isShadowsVisible",!0),(0,_mobx.makeAutoObservable)(this),this.modelStore=e,this.houseGroup.name="House-Group",this.globalPlane=new THREE.Plane(new THREE.Vector3(0,-this.wallsHeight-.5,0),1),this.clippingPlanes=[this.globalPlane],this.setCenterPosition().loadTextures().then(function(){t.createFloors().createSpaceBetweenWalls().createWalls().createDoors()}),this.apiStore.loadFurnitureData().then(function(e){t.furnitureData=e,t.loadFurniture(0)})}return _createClass(r,[{key:"textureLoader",get:function(){return this.modelStore.textureLoader}},{key:"sceneScale",get:function(){return this.modelStore.sceneScale}},{key:"wallsHeight",get:function(){return this.modelStore.wallsHeight}},{key:"json",get:function(){return this.modelStore.json}},{key:"vertices",get:function(){return this.json.Vertices}},{key:"rooms",get:function(){return this.json.Floors[0].Units[0].Rooms}},{key:"walls",get:function(){return this.json.Floors[0].Walls}},{key:"exteriorWalls",get:function(){return this.json.Floors[0].ExteriorWalls}},{key:"doors",get:function(){var t=this;return this.json.Floors[0].Doors.map(function(e){return t.getParsedAperture(e,"Door")})}},{key:"windows",get:function(){var t=this;return this.json.Floors[0].Windows.map(function(e){return t.getParsedAperture(e,"Window")})}},{key:"apertures",get:function(){return[].concat(_toConsumableArray(this.doors),_toConsumableArray(this.windows))}},{key:"doorsHeight",get:function(){return this.wallsHeight/2+this.wallsHeight/4}},{key:"wallMaterialOptions",get:function(){return{clippingPlanes:this.clippingPlanes,color:this.wallsColor,side:THREE.DoubleSide}}},{key:"furniture",get:function(){return this.rooms.reduce(function(e,t){t=t.Furniture;return t&&t.length?[].concat(_toConsumableArray(e),_toConsumableArray(t)):e},[])}},{key:"getVertexById",value:function(t){return this.vertices.find(function(e){return e.ID===t})}},{key:"getWallById",value:function(t){return this.walls.find(function(e){return e.ID===t})}},{key:"getParsedAperture",value:function(e,t){var r=e.Location,a=e.Walls,r=new THREE.Vector3(r.X,r.Y,r.Z),a=this.getParsedWallById(a[1],1),a=new THREE.Line3(a.start,a.end),o=new THREE.Vector3,a=(a.closestPointToPoint(r,!0,o),new THREE.Line3(r,o)),r=a.distance(),a=a.getCenter(o);return _objectSpread(_objectSpread({},e),{},{Type:t,Depth:r,Location:{X:a.x,Y:a.y,Z:a.z}})}},{key:"getParsedWallById",value:function(e){var t=this,r=1<arguments.length&&void 0!==arguments[1]?arguments[1]:this.sceneScale,a=_slicedToArray(this.getWallById(e).Vertices.map(function(e){return t.getVertexById(e).Location}),2),o=a[0],a=a[1];return{id:e,start:{x:o.X*r,y:o.Y*r,z:0},end:{x:a.X*r,y:a.Y*r,z:0}}}},{key:"getVerticesFromParsedWalls",value:function(e){return e.reduce(function(e,t){var r=t.start,t=t.end;return e.push(new THREE.Vector2(r.x,r.y),new THREE.Vector2(t.x,t.y)),e},[])}},{key:"createFloors",value:function(){var i=this;return this.rooms.forEach(function(e){function r(e,t){e=createDefaultMaterial({color:a.color,side:THREE.DoubleSide,map:e}),o.material=e,t&&(o.material.roughnessMap=t),i.houseGroup.add(o)}var t=e.Walls,e=e.Type,t=t.map(function(e){return i.getParsedWallById(e)}),a=(0,_modelHelpers.getFloorParams)(e),e=i.getVerticesFromParsedWalls(t),t=new THREE.Shape(e),e=new THREE.ShapeGeometry(t),t=createDefaultMaterial({color:a.color,side:THREE.DoubleSide}),o=new THREE.Mesh(e,t);o.receiveShadow=!0,o.castShadow=!1,o.name="FloorMesh";i.loadTexture(a.texture,[.5,.5],function(t){a.roughnessMap?i.loadTexture(a.roughnessMap,[.5,.5],function(e){return r(t,e)}):r(t)})}),this}},{key:"createSpaceBetweenWalls",value:function(){var t=this,e=this.exteriorWalls.map(function(e){return t.getParsedWallById(e)}),e=this.getVerticesFromParsedWalls(e),r=(this.wallsHeight+.5)*clippedBuildingConstant+.006,a=this.wallsHeight+.002,o=new THREE.Shape(e),e=new THREE.Shape(e),r=(this.rooms.forEach(function(e){e=e.Walls.map(function(e){return t.getParsedWallById(e)}),e=t.getVerticesFromParsedWalls(e);o.holes.push(new THREE.Shape(e))}),new THREE.ExtrudeGeometry(o,{depth:r,bevelEnabled:!1})),e=new THREE.ExtrudeGeometry(e,{depth:.001,bevelEnabled:!1}),a=new THREE.ExtrudeGeometry(o,{depth:a,bevelEnabled:!1}),i=createDefaultMaterial({side:THREE.DoubleSide,color:"#5C5C5C"}),n=createDefaultMaterial(_objectSpread(_objectSpread({},this.wallMaterialOptions),{},{color:"#5C5C5C"})),r=new THREE.Mesh(r,i),i=new THREE.Mesh(e,n),e=new THREE.Mesh(a,n),a=(i.receiveShadow=!1,i.castShadow=!1,r.position.z=-.005,i.position.z=-.005,e.position.z=-.001,this.subtractApertures(r,this.apertures,.25)),n=this.subtractApertures(e,this.apertures,.25);return a.name="ClippedSpaceBetweenWalls",n.name="SpaceBetweenWalls",i.name="FlatSpaceBetweenWalls",a.receiveShadow=!1,a.castShadow=!1,n.receiveShadow=!1,n.castShadow=!1,this.houseGroup.add(i,a,n),this}},{key:"createWalls",value:function(){function t(t,e){var r=(a=s.getParsedWallById(t)).start,a=a.end,o=.005,a=new THREE.Shape([new THREE.Vector2(r.x+o,r.y-o),new THREE.Vector2(a.x+o,a.y-o),new THREE.Vector2(a.x-o,a.y+o),new THREE.Vector2(r.x-o,r.y+o)]),r=new THREE.ExtrudeGeometry(a,{depth:s.wallsHeight,bevelEnabled:!1}),o=new THREE.ExtrudeGeometry(a,{depth:.001,bevelEnabled:!1}),a=e?s.exteriorWallsMaterial:s.wallsMaterial,i=createDefaultMaterial(_objectSpread(_objectSpread({},s.wallMaterialOptions),{},{color:"#5C5C5C"})),n=createDefaultMaterial({side:THREE.DoubleSide,color:"#5C5C5C"}),l=s.apertures.filter(function(e){return e.Walls.some(function(e){return t===e})}),r=s.subtractApertures(new THREE.Mesh(r,a),l),a=new THREE.Mesh(o,i),i=new THREE.Mesh(o,n);r.castShadow=!0,r.receiveShadow=!e,a.castShadow=!1,a.receiveShadow=!1,i.castShadow=!1,i.receiveShadow=!1,a.position.z=s.wallsHeight,i.position.z=(s.wallsHeight+.5)*clippedBuildingConstant+.001,(o=s.subtractApertures(i,l)).visible=!1,o.castShadow=!1,o.receiveShadow=!1,(n=new THREE.Group).name="Wall",n.buildingId=t,n.isExterior=e,n.add(r,a,o),s.wallsGroup.add(n)}var s=this;return this.exteriorWallsMaterial=createDefaultMaterial(_objectSpread(_objectSpread({},this.wallMaterialOptions),{},{map:this.exteriorWallsMaps.map,roughnessMap:this.exteriorWallsMaps.roughnessMap,color:"#FFFFFF"})),this.rooms.forEach(function(e){return e.Walls.forEach(function(e){return t(e,!1)})}),this.exteriorWalls.forEach(function(e){return t(e,!0)}),this.houseGroup.add(this.wallsGroup),this}},{key:"createDoors",value:function(){var a=this;return this.doors.forEach(function(e){var t=e.Width,r=e.Location,e=e.Rotation,t=new THREE.BoxGeometry(t*a.sceneScale,.1,a.doorsHeight),t=new THREE.Mesh(t,a.doorMaterial);t.position.x=r.X*a.sceneScale,t.position.y=r.Y*a.sceneScale,t.position.z=a.doorsHeight/2,t.rotation.z=THREE.Math.degToRad(e.Yaw),t.receiveShadow=!0,t.castShadow=!0,a.doorsGroup.add(t)}),this.houseGroup.add(this.doorsGroup),this}},{key:"subtractApertures",value:function(i,e){var n=this,l=2<arguments.length&&void 0!==arguments[2]?arguments[2]:0,s=i;return e.forEach(function(e){var t=e.Width,r=e.Depth,a=e.Location,o=e.Rotation,e="Door"===e.Type,t=new THREE.BoxGeometry((t+l)*n.sceneScale,r*n.sceneScale+1,(e?n.doorsHeight:n.wallsHeight/2)+l*n.sceneScale),r=createDefaultMaterial({color:"#00B4F7"}),t=new THREE.Mesh(t,r),r=(t.rotation.z=THREE.Math.degToRad(o.Yaw),t.position.x=a.X*n.sceneScale,t.position.y=a.Y*n.sceneScale,t.position.z=e?n.doorsHeight/2:n.wallsHeight/2,t.updateMatrix(),s.updateMatrix(),_threeCsg.default.fromMesh(t)),o=_threeCsg.default.fromMesh(s).subtract(r);s=_threeCsg.default.toMesh(o,i.matrix,s.material)}),s}},{key:"setCenterPosition",value:function(){var i=this,e=this.exteriorWalls.map(function(e){return i.getParsedWallById(e)}),e=(0,_modelHelpers.getMinMaxCoordinates)(e),t=e.maxX,r=e.minX,a=e.maxY,e=e.minY,n=(t+r)/2,l=(a+e)/2,t=(this.houseGroup.position.set(-n,-l),[{x:n-25,y:l-25,z:3*this.wallsHeight,power:.4,castShadow:!0},{x:n-25,y:l-25,z:2*this.wallsHeight,power:1,castShadow:!1},{x:25+n,y:25+l,z:2*this.wallsHeight,power:1.1,castShadow:!1},{x:n,y:l,z:5*this.wallsHeight,power:.1,castShadow:!1}]),s=new THREE.Object3D;return s.position.set(n,l,0),this.houseGroup.add(s),t.forEach(function(e){var t=e.x,r=e.y,a=e.z,o=e.power,e=e.castShadow,o=new THREE.DirectionalLight(16777215,o);o.position.set(t,r,a),o.shadowLight=e,o.castShadow=e,o.shadow.camera.left=2*-n,o.shadow.camera.right=2*n,o.shadow.camera.top=2*l,o.shadow.camera.bottom=2*-l,o.shadow.camera.zoom=1,o.shadow.mapSize=new THREE.Vector2(2048,2048),o.shadow.normalBias=1,o.target=s,i.houseGroup.add(o)}),this}},{key:"loadTexture",value:function(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:[1,1],r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:function(){};this.textureLoader.load(e,function(e){e.wrapS=e.wrapT=THREE.RepeatWrapping,e.repeat.set(t[0],t[1]),e.flipY=!1,r(e)})}},{key:"loadTextures",value:function(){var i=this,e=[{img:_wallTexture.default,repeat:[.5,.5],callback:function(e){i.wallsTextures.push({image:_wallTexture.default,texture:e}),i.wallsMaterial=createDefaultMaterial(_objectSpread(_objectSpread({},i.wallMaterialOptions),{},{map:e}))}},{img:_exteriorWallTexture.default,repeat:[1,1],callback:function(e){i.wallsTextures.push({image:_exteriorWallTexture.default,texture:e}),i.exteriorWallsMaps.map=e}},{img:_exteriorWallTextureRoughness.default,repeat:[1,1],callback:function(e){i.wallsTextures.push({image:_exteriorWallTextureRoughness.default,texture:e}),i.exteriorWallsMaps.roughnessMap=e}},{img:_doorTexture.default,repeat:[1,1],callback:function(e){i.doorMaterial=createDefaultMaterial(_objectSpread(_objectSpread({},doorMaterialOptions),{},{map:e}))}}];return Promise.all(e.map(function(e){var r=e.img,a=e.repeat,o=e.callback;return new Promise(function(t){i.loadTexture(r,a,function(e){o(e),t()})})}))}},{key:"loadFurniture",value:function(o){var e,t,r,n,a,i,l,s,u,c,d,h=this,p=this.furniture[o];p&&((e=this.furnitureData.find(function(e){var t=e.name,e=e.type;return t===p.Model&&e===p.Type}))?(t=e.mesh,e=e.textures,t="".concat(this.apiStore.API_URL,"/storage/furniture/").concat(t),d=p.Location,r=p.Rotation,n=p.Model,a=d.X,i=d.Y,l=d.Z,s=e.map(function(e){var r="".concat(h.apiStore.API_URL,"/storage/furniture/").concat(e);return new Promise(function(t){h.textureLoader.load(r,function(e){return t(e)})})}),u=function(i,e){function t(t){var e=i.find(function(e){e=e.image;return e.currentSrc.includes("".concat(t,"_D."))||e.currentSrc.includes("".concat(t,"_DA."))}),r=i.find(function(e){return e.image.currentSrc.includes("".concat(t,"_RMO."))}),a=i.find(function(e){return e.image.currentSrc.includes("".concat(t,"_N."))}),o=new THREE.MeshStandardMaterial({roughness:1,transparent:!0});return o.depthWrite=!("Flower"===n&&"01"===t),e&&(o.map=e),r&&(o.envMap=r),a&&(o.normalMap=a),o}var r=i.reduce(function(e,t){t=t.image;return t.currentSrc.includes("_D.")||t.currentSrc.includes("_DA.")?e+1:e},0),a=new THREE.MeshPhysicalMaterial({roughness:1,clearcoat:1,clearcoatRoughness:1,reflectivity:0,fog:!1});1===r&&(a=t("")),1<r&&(a=_toConsumableArray(Array(r).keys()).map(function(e){e+=1,e=e<10?"0".concat(e):e;return t(e)})),e.traverse(function(e){e.isMesh&&(e.material=a,e.receiveShadow=!0,e.castShadow=!0)}),h.houseGroup.add(e),h.loadFurniture(o+1)},c=function(e){var t=e.clone(),e=(t.scale.set(h.sceneScale,h.sceneScale,h.sceneScale),t.position.set(a*h.sceneScale,i*h.sceneScale,l*h.sceneScale),t.rotation.set(Math.PI/2,THREE.Math.degToRad(r.Yaw),0),h.loadedTextures[n]);e?u(e,t):Promise.all(s).then(function(e){u(e,t),h.loadedTextures[n]=e})},(d=this.loadedModels[n])?c(d):modelLoader.load(t,function(e){h.loadedModels[n]=e,c(e)})):this.loadFurniture(o+1))}},{key:"setShadowsVisibility",value:function(t){this.isShadowsVisible=t,this.houseGroup.children.forEach(function(e){e instanceof THREE.DirectionalLight&&e.shadowLight&&(e.castShadow=t)})}},{key:"setDoorsVisibility",value:function(t){this.isDoorsVisible=t,this.doorsGroup.children.forEach(function(e){return e.visible=t})}},{key:"setCurrentWallsMaterialType",value:function(r){var a=this;this.wallsMaterialType=r,this.wallsGroup.children.forEach(function(e){var t=e.children,e=e.isExterior,t=t[0];"texture"===r?t.material=e?a.exteriorWallsMaterial:a.wallsMaterial:(e=e?"#FFFFFF":a.wallsColor,t.material=createDefaultMaterial(_objectSpread(_objectSpread({},a.wallMaterialOptions),{},{color:e})))}),this.doorsGroup.children.forEach(function(e){e.material="texture"===r?a.doorMaterial:createDefaultMaterial(doorMaterialOptions)})}},{key:"setCurrentWallColor",value:function(r){this.wallsColor=r,this.wallsMaterial.color.set(r),this.wallsGroup.children.forEach(function(e){var t=e.children;e.isExterior||t[0].material.color.set(r)})}},{key:"setCurrentWallTexture",value:function(e){this.wallsMaterial=createDefaultMaterial(_objectSpread(_objectSpread({},this.wallMaterialOptions),{},{map:e})),this.setCurrentWallsMaterialType("texture")}},{key:"addWallTexture",value:function(t){var r=this;this.loadTexture(t,[.5,.5],function(e){r.wallsTextures.push({image:t,texture:e}),r.setCurrentWallTexture(e)})}},{key:"setFullBuildingVisibility",value:function(t){this.isFullBuildingVisible=t,this.globalPlane.constant=this.isFullBuildingVisible?1:clippedBuildingConstant,this.wallsGroup.children.forEach(function(e){return e.children[2].visible=!t})}},{key:"setPlanMode",value:function(){this.setDoorsVisibility(!1),this.setFullBuildingVisibility(!1),this.setCurrentWallsMaterialType("color")}}]),r}(),_default=HouseStore;exports.default=_default;
2
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0b3JlL2hvdXNlU3RvcmUuanMiXSwibmFtZXMiOlsiX3JlYWN0IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfbW9ieCIsIl9hcGlTdG9yZSIsIl9zdG9yZSIsIlRIUkVFIiwiX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQiLCJfRkJYTG9hZGVyIiwiX21vZGVsSGVscGVycyIsIl90aHJlZUNzZyIsIl93YWxsVGV4dHVyZSIsIl9kb29yVGV4dHVyZSIsIl9leHRlcmlvcldhbGxUZXh0dXJlIiwiX2V4dGVyaW9yV2FsbFRleHR1cmVSb3VnaG5lc3MiLCJjb25maWd1cmUiLCJ1c2VQcm94aWVzIiwiY2xpcHBlZEJ1aWxkaW5nQ29uc3RhbnQiLCJkb29yTWF0ZXJpYWxPcHRpb25zIiwiY29sb3IiLCJzaWRlIiwiRG91YmxlU2lkZSIsIm1vZGVsTG9hZGVyIiwiRkJYTG9hZGVyIiwiY3JlYXRlRGVmYXVsdE1hdGVyaWFsIiwib3B0aW9ucyIsIk1lc2hTdGFuZGFyZE1hdGVyaWFsIiwiX29iamVjdFNwcmVhZCIsInJvdWdobmVzcyIsIm1ldGFsbmVzcyIsIkhvdXNlU3RvcmUiLCJtb2RlbFN0b3JlIiwiX3RoaXMiLCJ0aGlzIiwiX2NsYXNzQ2FsbENoZWNrIiwiX2RlZmluZVByb3BlcnR5IiwiQXBpU3RvcmUiLCJzdG9yZSIsImNvbmZpZyIsIkFQSV9VUkwiLCJHcm91cCIsIm1hcCIsInJvdWdobmVzc01hcCIsIm1ha2VBdXRvT2JzZXJ2YWJsZSIsImhvdXNlR3JvdXAiLCJuYW1lIiwiZ2xvYmFsUGxhbmUiLCJQbGFuZSIsIlZlY3RvcjMiLCJ3YWxsc0hlaWdodCIsImNsaXBwaW5nUGxhbmVzIiwic2V0Q2VudGVyUG9zaXRpb24iLCJsb2FkVGV4dHVyZXMiLCJ0aGVuIiwiY3JlYXRlRmxvb3JzIiwiY3JlYXRlU3BhY2VCZXR3ZWVuV2FsbHMiLCJjcmVhdGVXYWxscyIsImNyZWF0ZURvb3JzIiwicmVzcCIsImxvYWRGdXJuaXR1cmUiLCJ0ZXh0dXJlTG9hZGVyIiwianNvbiIsIlZlcnRpY2VzIiwiRmxvb3JzIiwiVW5pdHMiLCJSb29tcyIsIldhbGxzIiwiRXh0ZXJpb3JXYWxscyIsIl90aGlzMiIsIkRvb3JzIiwiZG9vciIsImdldFBhcnNlZEFwZXJ0dXJlIiwiX3RoaXMzIiwiV2luZG93cyIsIndpbmRvdyIsImNvbmNhdCIsIl90b0NvbnN1bWFibGVBcnJheSIsImRvb3JzIiwid2luZG93cyIsIndhbGxzQ29sb3IiLCJyb29tcyIsInJlZHVjZSIsImFjYyIsIl9yZWYiLCJGdXJuaXR1cmUiLCJsZW5ndGgiLCJmaW5kIiwiX3JlZjIiLCJ2ZXJ0ZXhJZCIsIndhbGxJZCIsImFwaVN0b3JlIiwibG9hZEZ1cm5pdHVyZURhdGEiLCJ0eXBlIiwiTG9jYXRpb24iLCJhcGVydHVyZSIsInBvc2l0aW9uIiwiWCIsIlkiLCJaIiwic2Vjb25kV2FsbCIsImdldFBhcnNlZFdhbGxCeUlkIiwibGluZSIsIkxpbmUzIiwic3RhcnQiLCJlbmQiLCJwb3NpdGlvbk9uRmlyc3RXYWxsIiwibGluZUJldHdlZW5XYWxscyIsImNsb3Nlc3RQb2ludFRvUG9pbnQiLCJkaXN0YW5jZUJldHdlZW5XYWxscyIsImRpc3RhbmNlIiwicG9zaXRpb25CZXR3ZWVuV2FsbHMiLCJnZXRDZW50ZXIiLCJUeXBlIiwiRGVwdGgiLCJ4IiwieSIsInoiLCJfdGhpczQiLCJzY2FsZSIsImFyZ3VtZW50cyIsInVuZGVmaW5lZCIsInNjZW5lU2NhbGUiLCJfY3VycmVudFdhbGwkVmVydGljZXMyIiwiX3NsaWNlZFRvQXJyYXkiLCJnZXRWZXJ0ZXhCeUlkIiwiY29vcmQxIiwiY29vcmQyIiwiaWQiLCJ3YWxscyIsIl9yZWY0IiwicHVzaCIsIlZlY3RvcjIiLCJfdGhpczUiLCJmb3JFYWNoIiwiX3JlZjUiLCJjYWxsYmFjayIsInRleHR1cmUiLCJ0ZXh0dXJlTWF0ZXJpYWwiLCJwYXJhbXMiLCJtZXNoIiwibWF0ZXJpYWwiLCJhZGQiLCJnZXRGbG9vclBhcmFtcyIsInZlcnRpY2VzIiwic2hhcGUiLCJTaGFwZSIsImdlb21ldHJ5IiwiU2hhcGVHZW9tZXRyeSIsIk1lc2giLCJyZWNlaXZlU2hhZG93IiwiY2FzdFNoYWRvdyIsImxvYWRUZXh0dXJlIiwiX3RoaXM2IiwiZXh0ZXJpb3JXYWxscyIsImdldFZlcnRpY2VzRnJvbVBhcnNlZFdhbGxzIiwiY2xpcHBlZERlcHRoIiwiY2xpcHBlZEdlb21ldHJ5IiwiX3JlZjYiLCJyb29tV2FsbHMiLCJyb29tVmVydGljZXMiLCJzaGFwZVdpdGhIb2xlcyIsIkV4dHJ1ZGVHZW9tZXRyeSIsImJldmVsRW5hYmxlZCIsImZsYXRHZW9tZXRyeSIsImRlcHRoIiwiY2xpcHBlZE1hdGVyaWFsIiwid2FsbE1hdGVyaWFsT3B0aW9ucyIsImNsaXBwZWRNZXNoIiwiSUQiLCJmbGF0TWVzaCIsImNsaXBwZWRNZXNoV2l0aEFwZXJ0dXJlcyIsInN1YnRyYWN0QXBlcnR1cmVzIiwiYXBlcnR1cmVzIiwibWVzaFdpdGhBcGVydHVyZXMiLCJpc0V4dGVyaW9yIiwiX3RoaXM3JGdldFBhcnNlZFdhbGxCIiwid2FsbEhhbGZXaWR0aCIsIndhbGxTaGFwZSIsInBhcnNlZEFwZXJ0dXJlIiwid2FsbEdlb21ldHJ5IiwiX3RoaXM3Iiwid2FsbFBhZEdlb21ldHJ5Iiwid2FsbE1hdGVyaWFsIiwiZXh0ZXJpb3JXYWxsc01hdGVyaWFsIiwid2FsbHNNYXRlcmlhbCIsIndhbGxQYWRNYXRlcmlhbCIsImZpbHRlciIsInNvbWUiLCJ3YWxsTWVzaCIsIndhbGxQYWRNZXNoIiwid2FsbENsaXBwZWRQYWRNZXNoIiwid2FsbENsaXBwZWRQYWRNYXRlcmlhbCIsIndhbGxDbGlwcGVkUGFkTWVzaFdpdGhBcGVydHVyZXMiLCJ2aXNpYmxlIiwid2FsbEdyb3VwIiwiYnVpbGRpbmdJZCIsIndhbGxzR3JvdXAiLCJleHRlcmlvcldhbGxzTWFwcyIsIl9yZWY3IiwiY3JlYXRlV2FsbCIsIl90aGlzOCIsIl9yZWY4IiwiV2lkdGgiLCJCb3hHZW9tZXRyeSIsImRvb3JzSGVpZ2h0IiwiZG9vck1hdGVyaWFsIiwiZG9vcnNHcm91cCIsIl90aGlzOSIsImFkZGl0aW9uYWxXaWR0aCIsInJlc3VsdE1lc2giLCJfcmVmOSIsIlJvdGF0aW9uIiwiaXNEb29yIiwiYXBlcnR1cmVHZW9tZXRyeSIsImFwZXJ0dXJlTWF0ZXJpYWwiLCJhcGVydHVyZU1lc2giLCJhcGVydHVyZUJTUCIsInJvdGF0aW9uIiwiTWF0aCIsImRlZ1RvUmFkIiwiWWF3IiwidXBkYXRlTWF0cml4IiwiQ1NHIiwiZnJvbU1lc2giLCJyZXN1bHRCU1AiLCJzdWJ0cmFjdCIsInRvTWVzaCIsIm1hdHJpeCIsIl90aGlzMTAiLCJfZ2V0TWluTWF4Q29vcmRpbmF0ZXMiLCJtaW5YIiwiY2VudGVyWCIsImNlbnRlclkiLCJtYXhZIiwibGlnaHRzIiwicG93ZXIiLCJPYmplY3QzRCIsInRhcmdldE9iamVjdCIsInNldCIsIl9yZWYxMCIsImxpZ2h0IiwiRGlyZWN0aW9uYWxMaWdodCIsInNoYWRvdyIsImNhbWVyYSIsImxlZnQiLCJyaWdodCIsImJvdHRvbSIsInpvb20iLCJtYXBTaXplIiwibm9ybWFsQmlhcyIsInRhcmdldCIsInJlcGVhdCIsImFkZGl0aW9uYWxBcGVydHVyZVdpZHRoIiwiYXNzZXRzIiwiaW1nIiwiV2FsbFRleHR1cmVJbWciLCJfdGhpczExIiwid2FsbHNUZXh0dXJlcyIsImltYWdlIiwiRXh0ZXJpb3JXYWxsVGV4dHVyZUltZyIsIkV4dGVyaW9yV2FsbFRleHR1cmVSb3VnaG5lc3NJbWciLCJEb29yVGV4dHVyZSIsIlByb21pc2UiLCJfcmVmMTEiLCJyZXNvbHZlIiwiaW5kZXgiLCJ0ZXh0dXJlcyIsIk1vZGVsTmFtZSIsImxvYWRlZE1vZGVsIiwiX3JlZjEyIiwiZnVybml0dXJlIiwiTW9kZWwiLCJmdXJuaXR1cmVEYXRhIiwiX3RoaXMxMiIsInVybCIsImNyZWF0ZU1hdGVyaWFsIiwibnVtIiwiY3VycmVudFNyYyIsImluY2x1ZGVzIiwiZW52TWFwIiwiX3JlZjE1Iiwibm9ybWFsTWFwIiwicmVzdWx0IiwiX3JlZjE2IiwidHJhbnNwYXJlbnQiLCJkZXB0aFdyaXRlIiwiX3JlZjEzIiwibWF0ZXJpYWxzIiwiY2xlYXJjb2F0IiwiY2xlYXJjb2F0Um91Z2huZXNzIiwibWF0ZXJpYWxzQ291bnQiLCJrZXlzIiwiaSIsInJlYWxOdW0iLCJtb2RlbCIsInRyYXZlcnNlIiwibm9kZSIsIm9yaWdpbmFsTW9kZWwiLCJjbG9uZSIsIm9uVGV4dHVyZXNMb2FkZWQiLCJsb2FkZWRUZXh0dXJlcyIsImFsbCIsInByb21pc2VzIiwid2FsbEJTUCIsImxvYWRlZE1vZGVscyIsIm9uTW9kZWxMb2FkZWQiLCJsb2FkIiwibW9kZWxQYXRoIiwibWF4WCIsImlzU2hhZG93c1Zpc2libGUiLCJtaW5ZIiwibGlnaHRzT2Zmc2V0IiwidmFsdWUiLCJpc0Rvb3JzVmlzaWJsZSIsImNoaWxkcmVuIiwiX3RoaXMxMyIsIndhbGxzTWF0ZXJpYWxUeXBlIiwiX3JlZjE3Iiwid2FsbCIsInNoYWRvd0xpZ2h0IiwiX3JlZjE4IiwiX3RoaXMxNCIsInNldEN1cnJlbnRXYWxsVGV4dHVyZSIsImlzRnVsbEJ1aWxkaW5nVmlzaWJsZSIsImNvbnN0YW50Iiwid3JhcFQiLCJfcmVmMTkiLCJzZXREb29yc1Zpc2liaWxpdHkiLCJzZXRGdWxsQnVpbGRpbmdWaXNpYmlsaXR5Iiwic2V0Q3VycmVudFdhbGxzTWF0ZXJpYWxUeXBlIl0sIm1hcHBpbmdzIjoiNFVBQUEsSUFBQUEsT0FBQUMsdUJBQUFDLFFBQUEsVUFDQUMsTUFBQUQsUUFBQSxRQUNBRSxVQUFBSCx1QkFBQUMsUUFBQSxzQkFDQUcsT0FBQUosdUJBQUFDLFFBQUEsYUFDQUksTUFBQUMsd0JBQUFMLFFBQUEsVUFDQU0sV0FBQU4sUUFBQSx3Q0FDQU8sY0FBQVAsUUFBQSx5QkFDQVEsVUFBQVQsdUJBQUFDLFFBQUEsMkJBUEFTLGFBQUFWLHVCQUFBQyxRQUFBLG1DQVVBVSxhQUFBWCx1QkFBQUMsUUFBQSxvQ0FUQVcscUJBQUFaLHVCQUFBQyxRQUFBLDZDQVdBWSw4QkFBQWIsdUJBQUFDLFFBQUEsc0Qs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OiJzdG9yZS9ob3VzZVN0b3JlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IGNvbmZpZ3VyZSwgbWFrZUF1dG9PYnNlcnZhYmxlIH0gZnJvbSAnbW9ieCc7XG5pbXBvcnQgQXBpU3RvcmUgZnJvbSAnLi4vc3RvcmUvYXBpU3RvcmUnO1xuaW1wb3J0IHN0b3JlIGZyb20gJy4uL3N0b3JlJztcbmltcG9ydCAqIGFzIFRIUkVFIGZyb20gJ3RocmVlJztcbmltcG9ydCB7IEZCWExvYWRlciB9IGZyb20gJ3RocmVlL2V4YW1wbGVzL2pzbS9sb2FkZXJzL0ZCWExvYWRlcic7XG5pbXBvcnQgeyBnZXRGbG9vclBhcmFtcywgZ2V0TWluTWF4Q29vcmRpbmF0ZXMgfSBmcm9tICcuLi91dGlscy9tb2RlbEhlbHBlcnMnO1xuaW1wb3J0IENTRyBmcm9tICcuLi91dGlscy9jc2cvdGhyZWUtY3NnJztcblxuaW1wb3J0IFdhbGxUZXh0dXJlSW1nIGZyb20gJy4uL2Fzc2V0cy9pbWcvd2FsbC10ZXh0dXJlLmpwZyc7XG5pbXBvcnQgRG9vclRleHR1cmUgZnJvbSAnLi4vYXNzZXRzL2ltZy9kb29yLXRleHR1cmUuanBlZyc7XG5pbXBvcnQgRXh0ZXJpb3JXYWxsVGV4dHVyZUltZyBmcm9tICcuLi9hc3NldHMvaW1nL2V4dGVyaW9yLXdhbGwtdGV4dHVyZS5qcGVnJztcbmltcG9ydCBFeHRlcmlvcldhbGxUZXh0dXJlUm91Z2huZXNzSW1nIGZyb20gJy4uL2Fzc2V0cy9pbWcvZXh0ZXJpb3Itd2FsbC10ZXh0dXJlLXJvdWdobmVzcy5qcGcnO1xuXG5jb25maWd1cmUoeyB1c2VQcm94aWVzOiAnbmV2ZXInIH0pO1xuXG5jb25zdCBjbGlwcGVkQnVpbGRpbmdDb25zdGFudCA9IDAuNDtcblxuY29uc3QgZG9vck1hdGVyaWFsT3B0aW9ucyA9IHsgY29sb3I6ICcjREFEQURBJywgc2lkZTogVEhSRUUuRG91YmxlU2lkZSB9O1xuXG5jb25zdCBtb2RlbExvYWRlciA9IG5ldyBGQlhMb2FkZXIoKTtcblxuY29uc3QgY3JlYXRlRGVmYXVsdE1hdGVyaWFsID0gKG9wdGlvbnMpID0+IG5ldyBUSFJFRS5NZXNoU3RhbmRhcmRNYXRlcmlhbCh7XG4gIHJvdWdobmVzczogMSxcbiAgbWV0YWxuZXNzOiAwLFxuICAuLi5vcHRpb25zLFxufSk7XG5cbmNsYXNzIEhvdXNlU3RvcmUge1xuICBtb2RlbFN0b3JlID0gbnVsbDtcbiAgYXBpU3RvcmUgPSBuZXcgQXBpU3RvcmUoc3RvcmUuY29uZmlnLkFQSV9VUkwpO1xuXG4gIGhvdXNlR3JvdXAgPSBuZXcgVEhSRUUuR3JvdXAoKTtcbiAgd2FsbHNHcm91cCA9IG5ldyBUSFJFRS5Hcm91cCgpO1xuICBkb29yc0dyb3VwID0gbmV3IFRIUkVFLkdyb3VwKCk7XG5cbiAgZG9vck1hdGVyaWFsID0gbnVsbDtcbiAgd2FsbHNNYXRlcmlhbCA9IG51bGw7XG4gIHdhbGxzQ29sb3IgPSAnI0ZGRkZGRic7XG4gIGV4dGVyaW9yV2FsbHNNYXBzID0geyBtYXA6IG51bGwsIHJvdWdobmVzc01hcDogbnVsbCB9O1xuICBleHRlcmlvcldhbGxzTWF0ZXJpYWwgPSBudWxsO1xuXG4gIHdhbGxzVGV4dHVyZXMgPSBbXTtcblxuICBpc0Rvb3JzVmlzaWJsZSA9IHRydWU7XG4gIGlzRnVsbEJ1aWxkaW5nVmlzaWJsZSA9IHRydWU7XG4gIHdhbGxzTWF0ZXJpYWxUeXBlID0gJ3RleHR1cmUnO1xuXG4gIGdsb2JhbFBsYW5lID0gbnVsbDtcbiAgY2xpcHBpbmdQbGFuZXMgPSBbXTtcblxuICBmdXJuaXR1cmVEYXRhID0gW107XG4gIGxvYWRlZE1vZGVscyA9IHt9O1xuICBsb2FkZWRUZXh0dXJlcyA9IHt9O1xuXG4gIGlzU2hhZG93c1Zpc2libGUgPSB0cnVlO1xuXG4gIGNvbnN0cnVjdG9yKG1vZGVsU3RvcmUpIHtcbiAgICBtYWtlQXV0b09ic2VydmFibGUodGhpcyk7XG5cbiAgICB0aGlzLm1vZGVsU3RvcmUgPSBtb2RlbFN0b3JlO1xuXG4gICAgdGhpcy5ob3VzZUdyb3VwLm5hbWUgPSAnSG91c2UtR3JvdXAnO1xuXG4gICAgdGhpcy5nbG9iYWxQbGFuZSA9IG5ldyBUSFJFRS5QbGFuZShuZXcgVEhSRUUuVmVjdG9yMygwLCAtdGhpcy53YWxsc0hlaWdodCAtIDAuNSwgMCksIDEpO1xuICAgIHRoaXMuY2xpcHBpbmdQbGFuZXMgPSBbdGhpcy5nbG9iYWxQbGFuZV07XG5cbiAgICB0aGlzLnNldENlbnRlclBvc2l0aW9uKCkubG9hZFRleHR1cmVzKCkudGhlbigoKSA9PiB7XG4gICAgICB0aGlzLmNyZWF0ZUZsb29ycygpLmNyZWF0ZVNwYWNlQmV0d2VlbldhbGxzKCkuY3JlYXRlV2FsbHMoKS5jcmVhdGVEb29ycygpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5hcGlTdG9yZS5sb2FkRnVybml0dXJlRGF0YSgpLnRoZW4oKHJlc3ApID0+IHtcbiAgICAgIHRoaXMuZnVybml0dXJlRGF0YSA9IHJlc3A7XG4gICAgICB0aGlzLmxvYWRGdXJuaXR1cmUoMCk7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgdGV4dHVyZUxvYWRlcigpIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlbFN0b3JlLnRleHR1cmVMb2FkZXI7XG4gIH1cblxuICBnZXQgc2NlbmVTY2FsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlbFN0b3JlLnNjZW5lU2NhbGU7XG4gIH1cblxuICBnZXQgd2FsbHNIZWlnaHQoKSB7XG4gICAgcmV0dXJuIHRoaXMubW9kZWxTdG9yZS53YWxsc0hlaWdodDtcbiAgfVxuXG4gIGdldCBqc29uKCkge1xuICAgIHJldHVybiB0aGlzLm1vZGVsU3RvcmUuanNvbjtcbiAgfVxuXG4gIGdldCB2ZXJ0aWNlcygpIHtcbiAgICByZXR1cm4gdGhpcy5qc29uLlZlcnRpY2VzO1xuICB9XG5cbiAgZ2V0IHJvb21zKCkge1xuICAgIHJldHVybiB0aGlzLmpzb24uRmxvb3JzWzBdLlVuaXRzWzBdLlJvb21zO1xuICB9XG5cbiAgZ2V0IHdhbGxzKCkge1xuICAgIHJldHVybiB0aGlzLmpzb24uRmxvb3JzWzBdLldhbGxzO1xuICB9XG5cbiAgZ2V0IGV4dGVyaW9yV2FsbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuanNvbi5GbG9vcnNbMF0uRXh0ZXJpb3JXYWxscztcbiAgfVxuXG4gIGdldCBkb29ycygpIHtcbiAgICByZXR1cm4gdGhpcy5qc29uLkZsb29yc1swXS5Eb29ycy5tYXAoKGRvb3IpID0+IHRoaXMuZ2V0UGFyc2VkQXBlcnR1cmUoZG9vciwgJ0Rvb3InKSk7XG4gIH1cblxuICBnZXQgd2luZG93cygpIHtcbiAgICByZXR1cm4gdGhpcy5qc29uLkZsb29yc1swXS5XaW5kb3dzLm1hcCgod2luZG93KSA9PiB0aGlzLmdldFBhcnNlZEFwZXJ0dXJlKHdpbmRvdywgJ1dpbmRvdycpKTtcbiAgfVxuXG4gIGdldCBhcGVydHVyZXMoKSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLmRvb3JzLCAuLi50aGlzLndpbmRvd3NdO1xuICB9XG5cbiAgZ2V0IGRvb3JzSGVpZ2h0KCkge1xuICAgIHJldHVybiAodGhpcy53YWxsc0hlaWdodCAvIDIpICsgKHRoaXMud2FsbHNIZWlnaHQgLyA0KTtcbiAgfVxuXG4gIGdldCB3YWxsTWF0ZXJpYWxPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBjbGlwcGluZ1BsYW5lczogdGhpcy5jbGlwcGluZ1BsYW5lcyxcbiAgICAgIGNvbG9yOiB0aGlzLndhbGxzQ29sb3IsXG4gICAgICBzaWRlOiBUSFJFRS5Eb3VibGVTaWRlLFxuICAgIH07XG4gIH1cblxuICBnZXQgZnVybml0dXJlKCkge1xuICAgIHJldHVybiB0aGlzLnJvb21zLnJlZHVjZSgoYWNjLCB7IEZ1cm5pdHVyZSB9KSA9PiB7XG4gICAgICBpZiAoIUZ1cm5pdHVyZSB8fCAhRnVybml0dXJlLmxlbmd0aCkgcmV0dXJuIGFjYztcbiAgICAgIHJldHVybiBbLi4uYWNjLCAuLi5GdXJuaXR1cmVdO1xuICAgIH0sIFtdKTtcbiAgfVxuXG4gIGdldFZlcnRleEJ5SWQodmVydGV4SWQpIHtcbiAgICByZXR1cm4gdGhpcy52ZXJ0aWNlcy5maW5kKCh7IElEIH0pID0+IElEID09PSB2ZXJ0ZXhJZCk7XG4gIH1cblxuICBnZXRXYWxsQnlJZCh3YWxsSWQpIHtcbiAgICByZXR1cm4gdGhpcy53YWxscy5maW5kKCh7IElEIH0pID0+IElEID09PSB3YWxsSWQpO1xuICB9XG5cbiAgZ2V0UGFyc2VkQXBlcnR1cmUoYXBlcnR1cmUsIHR5cGUpIHtcbiAgICBjb25zdCB7IExvY2F0aW9uLCBXYWxscyB9ID0gYXBlcnR1cmU7XG4gICAgY29uc3QgcG9zaXRpb24gPSBuZXcgVEhSRUUuVmVjdG9yMyhMb2NhdGlvbi5YLCBMb2NhdGlvbi5ZLCBMb2NhdGlvbi5aKTtcbiAgICBjb25zdCBzZWNvbmRXYWxsID0gdGhpcy5nZXRQYXJzZWRXYWxsQnlJZChXYWxsc1sxXSwgMSk7XG4gICAgY29uc3QgbGluZSA9IG5ldyBUSFJFRS5MaW5lMyhzZWNvbmRXYWxsLnN0YXJ0LCBzZWNvbmRXYWxsLmVuZCk7XG4gICAgY29uc3QgcG9zaXRpb25PbkZpcnN0V2FsbCA9IG5ldyBUSFJFRS5WZWN0b3IzKCk7XG4gICAgbGluZS5jbG9zZXN0UG9pbnRUb1BvaW50KHBvc2l0aW9uLCB0cnVlLCBwb3NpdGlvbk9uRmlyc3RXYWxsKTtcbiAgICBjb25zdCBsaW5lQmV0d2VlbldhbGxzID0gbmV3IFRIUkVFLkxpbmUzKHBvc2l0aW9uLCBwb3NpdGlvbk9uRmlyc3RXYWxsKTtcbiAgICBjb25zdCBkaXN0YW5jZUJldHdlZW5XYWxscyA9IGxpbmVCZXR3ZWVuV2FsbHMuZGlzdGFuY2UoKTtcbiAgICBjb25zdCBwb3NpdGlvbkJldHdlZW5XYWxscyA9IGxpbmVCZXR3ZWVuV2FsbHMuZ2V0Q2VudGVyKHBvc2l0aW9uT25GaXJzdFdhbGwpO1xuXG4gICAgY29uc3QgcGFyc2VkQXBlcnR1cmUgPSB7XG4gICAgICAuLi5hcGVydHVyZSxcbiAgICAgIFR5cGU6IHR5cGUsXG4gICAgICBEZXB0aDogZGlzdGFuY2VCZXR3ZWVuV2FsbHMsXG4gICAgICBMb2NhdGlvbjogeyBYOiBwb3NpdGlvbkJldHdlZW5XYWxscy54LCBZOiBwb3NpdGlvbkJldHdlZW5XYWxscy55LCBaOiBwb3NpdGlvbkJldHdlZW5XYWxscy56IH0sXG4gICAgfTtcblxuICAgIHJldHVybiBwYXJzZWRBcGVydHVyZTtcbiAgfVxuXG4gIGdldFBhcnNlZFdhbGxCeUlkKHdhbGxJZCwgc2NhbGUgPSB0aGlzLnNjZW5lU2NhbGUpIHtcbiAgICBjb25zdCBjdXJyZW50V2FsbCA9IHRoaXMuZ2V0V2FsbEJ5SWQod2FsbElkKTtcbiAgICBjb25zdCBbY29vcmQxLCBjb29yZDJdID0gY3VycmVudFdhbGwuVmVydGljZXMubWFwKCh2ZXJ0ZXhJZCkgPT4gdGhpcy5nZXRWZXJ0ZXhCeUlkKHZlcnRleElkKS5Mb2NhdGlvbik7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiB3YWxsSWQsXG4gICAgICBzdGFydDogeyB4OiBjb29yZDEuWCAqIHNjYWxlLCB5OiBjb29yZDEuWSAqIHNjYWxlLCB6OiAwIH0sXG4gICAgICBlbmQ6IHsgeDogY29vcmQyLlggKiBzY2FsZSwgeTogY29vcmQyLlkgKiBzY2FsZSwgejogMCB9LFxuICAgIH07XG4gIH1cblxuICBnZXRWZXJ0aWNlc0Zyb21QYXJzZWRXYWxscyh3YWxscykge1xuICAgIHJldHVybiB3YWxscy5yZWR1Y2UoKGFjYywgeyBzdGFydCwgZW5kIH0pID0+IHtcbiAgICAgIGFjYy5wdXNoKG5ldyBUSFJFRS5WZWN0b3IyKHN0YXJ0LngsIHN0YXJ0LnkpLCBuZXcgVEhSRUUuVmVjdG9yMihlbmQueCwgZW5kLnkpKTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgW10pO1xuICB9XG5cbiAgY3JlYXRlRmxvb3JzKCkge1xuICAgIHRoaXMucm9vbXMuZm9yRWFjaCgoeyBXYWxscywgVHlwZSB9KSA9PiB7XG4gICAgICBjb25zdCB3YWxscyA9IFdhbGxzLm1hcCgod2FsbElkKSA9PiB0aGlzLmdldFBhcnNlZFdhbGxCeUlkKHdhbGxJZCkpO1xuICAgICAgY29uc3QgcGFyYW1zID0gZ2V0Rmxvb3JQYXJhbXMoVHlwZSk7XG4gICAgICBjb25zdCB2ZXJ0aWNlcyA9IHRoaXMuZ2V0VmVydGljZXNGcm9tUGFyc2VkV2FsbHMod2FsbHMpO1xuXG4gICAgICBjb25zdCBzaGFwZSA9IG5ldyBUSFJFRS5TaGFwZSh2ZXJ0aWNlcyk7XG4gICAgICBjb25zdCBnZW9tZXRyeSA9IG5ldyBUSFJFRS5TaGFwZUdlb21ldHJ5KHNoYXBlKTtcbiAgICAgIGNvbnN0IG1hdGVyaWFsID0gY3JlYXRlRGVmYXVsdE1hdGVyaWFsKHsgY29sb3I6IHBhcmFtcy5jb2xvciwgc2lkZTogVEhSRUUuRG91YmxlU2lkZSB9KTtcbiAgICAgIGNvbnN0IG1lc2ggPSBuZXcgVEhSRUUuTWVzaChnZW9tZXRyeSwgbWF0ZXJpYWwpO1xuICAgICAgbWVzaC5yZWNlaXZlU2hhZG93ID0gdHJ1ZTtcbiAgICAgIG1lc2guY2FzdFNoYWRvdyA9IGZhbHNlO1xuICAgICAgbWVzaC5uYW1lID0gJ0Zsb29yTWVzaCc7XG5cbiAgICAgIGNvbnN0IGNhbGxiYWNrID0gKHRleHR1cmUsIHJvdWdobmVzc01hcCkgPT4ge1xuICAgICAgICBjb25zdCB0ZXh0dXJlTWF0ZXJpYWwgPSBjcmVhdGVEZWZhdWx0TWF0ZXJpYWwoeyBjb2xvcjogcGFyYW1zLmNvbG9yLCBzaWRlOiBUSFJFRS5Eb3VibGVTaWRlLCBtYXA6IHRleHR1cmUgfSk7XG4gICAgICAgIG1lc2gubWF0ZXJpYWwgPSB0ZXh0dXJlTWF0ZXJpYWw7XG4gICAgICAgIGlmIChyb3VnaG5lc3NNYXApIG1lc2gubWF0ZXJpYWwucm91Z2huZXNzTWFwID0gcm91Z2huZXNzTWFwO1xuXG4gICAgICAgIHRoaXMuaG91c2VHcm91cC5hZGQobWVzaCk7XG4gICAgICB9O1xuXG4gICAgICB0aGlzLmxvYWRUZXh0dXJlKHBhcmFtcy50ZXh0dXJlLCBbMC41LCAwLjVdLCAodGV4dHVyZSkgPT4ge1xuICAgICAgICBpZiAoIXBhcmFtcy5yb3VnaG5lc3NNYXApIHtcbiAgICAgICAgICBjYWxsYmFjayh0ZXh0dXJlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sb2FkVGV4dHVyZShwYXJhbXMucm91Z2huZXNzTWFwLCBbMC41LCAwLjVdLCAocm91Z2huZXNzTWFwKSA9PiBjYWxsYmFjayh0ZXh0dXJlLCByb3VnaG5lc3NNYXApKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBjcmVhdGVTcGFjZUJldHdlZW5XYWxscygpIHtcbiAgICBjb25zdCB3YWxscyA9IHRoaXMuZXh0ZXJpb3JXYWxscy5tYXAoKHdhbGxJZCkgPT4gdGhpcy5nZXRQYXJzZWRXYWxsQnlJZCh3YWxsSWQpKTtcbiAgICBjb25zdCB2ZXJ0aWNlcyA9IHRoaXMuZ2V0VmVydGljZXNGcm9tUGFyc2VkV2FsbHMod2FsbHMpO1xuICAgIGNvbnN0IGNsaXBwZWREZXB0aCA9ICgodGhpcy53YWxsc0hlaWdodCArIDAuNSkgKiBjbGlwcGVkQnVpbGRpbmdDb25zdGFudCkgKyAwLjAwNjtcbiAgICBjb25zdCBkZXB0aCA9IHRoaXMud2FsbHNIZWlnaHQgKyAwLjAwMjtcblxuICAgIGNvbnN0IHNoYXBlV2l0aEhvbGVzID0gbmV3IFRIUkVFLlNoYXBlKHZlcnRpY2VzKTtcbiAgICBjb25zdCBzaGFwZSA9IG5ldyBUSFJFRS5TaGFwZSh2ZXJ0aWNlcyk7XG5cbiAgICB0aGlzLnJvb21zLmZvckVhY2goKHsgV2FsbHMgfSkgPT4ge1xuICAgICAgY29uc3Qgcm9vbVdhbGxzID0gV2FsbHMubWFwKCh3YWxsSWQpID0+IHRoaXMuZ2V0UGFyc2VkV2FsbEJ5SWQod2FsbElkKSk7XG4gICAgICBjb25zdCByb29tVmVydGljZXMgPSB0aGlzLmdldFZlcnRpY2VzRnJvbVBhcnNlZFdhbGxzKHJvb21XYWxscyk7XG4gICAgICBzaGFwZVdpdGhIb2xlcy5ob2xlcy5wdXNoKG5ldyBUSFJFRS5TaGFwZShyb29tVmVydGljZXMpKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGNsaXBwZWRHZW9tZXRyeSA9IG5ldyBUSFJFRS5FeHRydWRlR2VvbWV0cnkoc2hhcGVXaXRoSG9sZXMsIHsgZGVwdGg6IGNsaXBwZWREZXB0aCwgYmV2ZWxFbmFibGVkOiBmYWxzZSB9KTtcbiAgICBjb25zdCBmbGF0R2VvbWV0cnkgPSBuZXcgVEhSRUUuRXh0cnVkZUdlb21ldHJ5KHNoYXBlLCB7IGRlcHRoOiAwLjAwMSwgYmV2ZWxFbmFibGVkOiBmYWxzZSB9KTtcbiAgICBjb25zdCBnZW9tZXRyeSA9IG5ldyBUSFJFRS5FeHRydWRlR2VvbWV0cnkoc2hhcGVXaXRoSG9sZXMsIHsgZGVwdGgsIGJldmVsRW5hYmxlZDogZmFsc2UgfSk7XG5cbiAgICBjb25zdCBjbGlwcGVkTWF0ZXJpYWwgPSBjcmVhdGVEZWZhdWx0TWF0ZXJpYWwoeyBzaWRlOiBUSFJFRS5Eb3VibGVTaWRlLCBjb2xvcjogJyM1QzVDNUMnIH0pO1xuICAgIGNvbnN0IG1hdGVyaWFsID0gY3JlYXRlRGVmYXVsdE1hdGVyaWFsKHsgLi4udGhpcy53YWxsTWF0ZXJpYWxPcHRpb25zLCBjb2xvcjogJyM1QzVDNUMnIH0pO1xuXG4gICAgY29uc3QgY2xpcHBlZE1lc2ggPSBuZXcgVEhSRUUuTWVzaChjbGlwcGVkR2VvbWV0cnksIGNsaXBwZWRNYXRlcmlhbCk7XG4gICAgY29uc3QgZmxhdE1lc2ggPSBuZXcgVEhSRUUuTWVzaChmbGF0R2VvbWV0cnksIG1hdGVyaWFsKTtcbiAgICBjb25zdCBtZXNoID0gbmV3IFRIUkVFLk1lc2goZ2VvbWV0cnksIG1hdGVyaWFsKTtcblxuICAgIGZsYXRNZXNoLnJlY2VpdmVTaGFkb3cgPSBmYWxzZTtcbiAgICBmbGF0TWVzaC5jYXN0U2hhZG93ID0gZmFsc2U7XG5cbiAgICBjbGlwcGVkTWVzaC5wb3NpdGlvbi56ID0gLTAuMDA1O1xuICAgIGZsYXRNZXNoLnBvc2l0aW9uLnogPSAtMC4wMDU7XG4gICAgbWVzaC5wb3NpdGlvbi56ID0gLTAuMDAxO1xuXG4gICAgY29uc3QgYWRkaXRpb25hbEFwZXJ0dXJlV2lkdGggPSAwLjI1O1xuICAgIGNvbnN0IGNsaXBwZWRNZXNoV2l0aEFwZXJ0dXJlcyA9IHRoaXMuc3VidHJhY3RBcGVydHVyZXMoY2xpcHBlZE1lc2gsIHRoaXMuYXBlcnR1cmVzLCBhZGRpdGlvbmFsQXBlcnR1cmVXaWR0aCk7XG4gICAgY29uc3QgbWVzaFdpdGhBcGVydHVyZXMgPSB0aGlzLnN1YnRyYWN0QXBlcnR1cmVzKG1lc2gsIHRoaXMuYXBlcnR1cmVzLCBhZGRpdGlvbmFsQXBlcnR1cmVXaWR0aCk7XG4gICAgY2xpcHBlZE1lc2hXaXRoQXBlcnR1cmVzLm5hbWUgPSAnQ2xpcHBlZFNwYWNlQmV0d2VlbldhbGxzJztcbiAgICBtZXNoV2l0aEFwZXJ0dXJlcy5uYW1lID0gJ1NwYWNlQmV0d2VlbldhbGxzJztcbiAgICBmbGF0TWVzaC5uYW1lID0gJ0ZsYXRTcGFjZUJldHdlZW5XYWxscyc7XG5cbiAgICBjbGlwcGVkTWVzaFdpdGhBcGVydHVyZXMucmVjZWl2ZVNoYWRvdyA9IGZhbHNlO1xuICAgIGNsaXBwZWRNZXNoV2l0aEFwZXJ0dXJlcy5jYXN0U2hhZG93ID0gZmFsc2U7XG4gICAgbWVzaFdpdGhBcGVydHVyZXMucmVjZWl2ZVNoYWRvdyA9IGZhbHNlO1xuICAgIG1lc2hXaXRoQXBlcnR1cmVzLmNhc3RTaGFkb3cgPSBmYWxzZTtcblxuICAgIHRoaXMuaG91c2VHcm91cC5hZGQoZmxhdE1lc2gsIGNsaXBwZWRNZXNoV2l0aEFwZXJ0dXJlcywgbWVzaFdpdGhBcGVydHVyZXMpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBjcmVhdGVXYWxscygpIHtcbiAgICBjb25zdCBjcmVhdGVXYWxsID0gKHdhbGxJZCwgaXNFeHRlcmlvcikgPT4ge1xuICAgICAgY29uc3QgeyBzdGFydCwgZW5kIH0gPSB0aGlzLmdldFBhcnNlZFdhbGxCeUlkKHdhbGxJZCk7XG4gICAgICBjb25zdCB3YWxsSGFsZldpZHRoID0gMC4wMDU7XG4gICAgICBjb25zdCB3YWxsU2hhcGUgPSBuZXcgVEhSRUUuU2hhcGUoW1xuICAgICAgICBuZXcgVEhSRUUuVmVjdG9yMihzdGFydC54ICsgd2FsbEhhbGZXaWR0aCwgc3RhcnQueSAtIHdhbGxIYWxmV2lkdGgpLFxuICAgICAgICBuZXcgVEhSRUUuVmVjdG9yMihlbmQueCArIHdhbGxIYWxmV2lkdGgsIGVuZC55IC0gd2FsbEhhbGZXaWR0aCksXG4gICAgICAgIG5ldyBUSFJFRS5WZWN0b3IyKGVuZC54IC0gd2FsbEhhbGZXaWR0aCwgZW5kLnkgKyB3YWxsSGFsZldpZHRoKSxcbiAgICAgICAgbmV3IFRIUkVFLlZlY3RvcjIoc3RhcnQueCAtIHdhbGxIYWxmV2lkdGgsIHN0YXJ0LnkgKyB3YWxsSGFsZldpZHRoKSxcbiAgICAgIF0pO1xuICAgICAgY29uc3Qgd2FsbEdlb21ldHJ5ID0gbmV3IFRIUkVFLkV4dHJ1ZGVHZW9tZXRyeSh3YWxsU2hhcGUsIHsgZGVwdGg6IHRoaXMud2FsbHNIZWlnaHQsIGJldmVsRW5hYmxlZDogZmFsc2UgfSk7XG4gICAgICBjb25zdCB3YWxsUGFkR2VvbWV0cnkgPSBuZXcgVEhSRUUuRXh0cnVkZUdlb21ldHJ5KHdhbGxTaGFwZSwgeyBkZXB0aDogMC4wMDEsIGJldmVsRW5hYmxlZDogZmFsc2UgfSk7XG5cbiAgICAgIGNvbnN0IHdhbGxNYXRlcmlhbCA9IGlzRXh0ZXJpb3IgPyB0aGlzLmV4dGVyaW9yV2FsbHNNYXRlcmlhbCA6IHRoaXMud2FsbHNNYXRlcmlhbDtcbiAgICAgIGNvbnN0IHdhbGxQYWRNYXRlcmlhbCA9IGNyZWF0ZURlZmF1bHRNYXRlcmlhbCh7IC4uLnRoaXMud2FsbE1hdGVyaWFsT3B0aW9ucywgY29sb3I6ICcjNUM1QzVDJyB9KTtcbiAgICAgIGNvbnN0IHdhbGxDbGlwcGVkUGFkTWF0ZXJpYWwgPSBjcmVhdGVEZWZhdWx0TWF0ZXJpYWwoeyBzaWRlOiBUSFJFRS5Eb3VibGVTaWRlLCBjb2xvcjogJyM1QzVDNUMnIH0pO1xuXG4gICAgICBjb25zdCBhcGVydHVyZXMgPSB0aGlzLmFwZXJ0dXJlcy5maWx0ZXIoKGFwZXJ0dXJlKSA9PiBhcGVydHVyZS5XYWxscy5zb21lKChpZCkgPT4gd2FsbElkID09PSBpZCkpO1xuICAgICAgY29uc3Qgd2FsbE1lc2ggPSB0aGlzLnN1YnRyYWN0QXBlcnR1cmVzKG5ldyBUSFJFRS5NZXNoKHdhbGxHZW9tZXRyeSwgd2FsbE1hdGVyaWFsKSwgYXBlcnR1cmVzKTtcbiAgICAgIGNvbnN0IHdhbGxQYWRNZXNoID0gbmV3IFRIUkVFLk1lc2god2FsbFBhZEdlb21ldHJ5LCB3YWxsUGFkTWF0ZXJpYWwpO1xuICAgICAgY29uc3Qgd2FsbENsaXBwZWRQYWRNZXNoID0gbmV3IFRIUkVFLk1lc2god2FsbFBhZEdlb21ldHJ5LCB3YWxsQ2xpcHBlZFBhZE1hdGVyaWFsKTtcbiAgICAgIHdhbGxNZXNoLmNhc3RTaGFkb3cgPSB0cnVlO1xuICAgICAgd2FsbE1lc2gucmVjZWl2ZVNoYWRvdyA9ICFpc0V4dGVyaW9yO1xuICAgICAgd2FsbFBhZE1lc2guY2FzdFNoYWRvdyA9IGZhbHNlO1xuICAgICAgd2FsbFBhZE1lc2gucmVjZWl2ZVNoYWRvdyA9IGZhbHNlO1xuICAgICAgd2FsbENsaXBwZWRQYWRNZXNoLmNhc3RTaGFkb3cgPSBmYWxzZTtcbiAgICAgIHdhbGxDbGlwcGVkUGFkTWVzaC5yZWNlaXZlU2hhZG93ID0gZmFsc2U7XG5cbiAgICAgIHdhbGxQYWRNZXNoLnBvc2l0aW9uLnogPSB0aGlzLndhbGxzSGVpZ2h0O1xuICAgICAgd2FsbENsaXBwZWRQYWRNZXNoLnBvc2l0aW9uLnogPSAoKHRoaXMud2FsbHNIZWlnaHQgKyAwLjUpICogY2xpcHBlZEJ1aWxkaW5nQ29uc3RhbnQpICsgMC4wMDE7XG5cbiAgICAgIGNvbnN0IHdhbGxDbGlwcGVkUGFkTWVzaFdpdGhBcGVydHVyZXMgPSB0aGlzLnN1YnRyYWN0QXBlcnR1cmVzKHdhbGxDbGlwcGVkUGFkTWVzaCwgYXBlcnR1cmVzKTtcbiAgICAgIHdhbGxDbGlwcGVkUGFkTWVzaFdpdGhBcGVydHVyZXMudmlzaWJsZSA9IGZhbHNlO1xuICAgICAgd2FsbENsaXBwZWRQYWRNZXNoV2l0aEFwZXJ0dXJlcy5jYXN0U2hhZG93ID0gZmFsc2U7XG4gICAgICB3YWxsQ2xpcHBlZFBhZE1lc2hXaXRoQXBlcnR1cmVzLnJlY2VpdmVTaGFkb3cgPSBmYWxzZTtcblxuICAgICAgY29uc3Qgd2FsbEdyb3VwID0gbmV3IFRIUkVFLkdyb3VwKCk7XG4gICAgICB3YWxsR3JvdXAubmFtZSA9ICdXYWxsJztcbiAgICAgIHdhbGxHcm91cC5idWlsZGluZ0lkID0gd2FsbElkO1xuICAgICAgd2FsbEdyb3VwLmlzRXh0ZXJpb3IgPSBpc0V4dGVyaW9yO1xuICAgICAgd2FsbEdyb3VwLmFkZCh3YWxsTWVzaCwgd2FsbFBhZE1lc2gsIHdhbGxDbGlwcGVkUGFkTWVzaFdpdGhBcGVydHVyZXMpO1xuXG4gICAgICB0aGlzLndhbGxzR3JvdXAuYWRkKHdhbGxHcm91cCk7XG4gICAgfTtcblxuICAgIHRoaXMuZXh0ZXJpb3JXYWxsc01hdGVyaWFsID0gY3JlYXRlRGVmYXVsdE1hdGVyaWFsKHtcbiAgICAgIC4uLnRoaXMud2FsbE1hdGVyaWFsT3B0aW9ucyxcbiAgICAgIG1hcDogdGhpcy5leHRlcmlvcldhbGxzTWFwcy5tYXAsXG4gICAgICByb3VnaG5lc3NNYXA6IHRoaXMuZXh0ZXJpb3JXYWxsc01hcHMucm91Z2huZXNzTWFwLFxuICAgICAgY29sb3I6ICcjRkZGRkZGJyxcbiAgICB9KTtcblxuICAgIHRoaXMucm9vbXMuZm9yRWFjaCgoeyBXYWxscyB9KSA9PiBXYWxscy5mb3JFYWNoKCh3YWxsSWQpID0+IGNyZWF0ZVdhbGwod2FsbElkLCBmYWxzZSkpKTtcblxuICAgIHRoaXMuZXh0ZXJpb3JXYWxscy5mb3JFYWNoKCh3YWxsSWQpID0+IGNyZWF0ZVdhbGwod2FsbElkLCB0cnVlKSk7XG5cbiAgICB0aGlzLmhvdXNlR3JvdXAuYWRkKHRoaXMud2FsbHNHcm91cCk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGNyZWF0ZURvb3JzKCkge1xuICAgIHRoaXMuZG9vcnMuZm9yRWFjaCgoeyBXaWR0aCwgTG9jYXRpb24sIFJvdGF0aW9uIH0pID0+IHtcbiAgICAgIGNvbnN0IGdlb21ldHJ5ID0gbmV3IFRIUkVFLkJveEdlb21ldHJ5KFdpZHRoICogdGhpcy5zY2VuZVNjYWxlLCAwLjEsIHRoaXMuZG9vcnNIZWlnaHQpO1xuICAgICAgbGV0IG1lc2ggPSBuZXcgVEhSRUUuTWVzaChnZW9tZXRyeSwgdGhpcy5kb29yTWF0ZXJpYWwpO1xuICAgICAgbWVzaC5wb3NpdGlvbi54ID0gTG9jYXRpb24uWCAqIHRoaXMuc2NlbmVTY2FsZTtcbiAgICAgIG1lc2gucG9zaXRpb24ueSA9IExvY2F0aW9uLlkgKiB0aGlzLnNjZW5lU2NhbGU7XG4gICAgICBtZXNoLnBvc2l0aW9uLnogPSB0aGlzLmRvb3JzSGVpZ2h0IC8gMjtcbiAgICAgIG1lc2gucm90YXRpb24ueiA9IFRIUkVFLk1hdGguZGVnVG9SYWQoUm90YXRpb24uWWF3KTtcbiAgICAgIG1lc2gucmVjZWl2ZVNoYWRvdyA9IHRydWU7XG4gICAgICBtZXNoLmNhc3RTaGFkb3cgPSB0cnVlO1xuICAgICAgXG4gICAgICB0aGlzLmRvb3JzR3JvdXAuYWRkKG1lc2gpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5ob3VzZUdyb3VwLmFkZCh0aGlzLmRvb3JzR3JvdXApO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdWJ0cmFjdEFwZXJ0dXJlcyhtZXNoLCBhcGVydHVyZXMsIGFkZGl0aW9uYWxXaWR0aCA9IDApIHtcbiAgICBsZXQgcmVzdWx0TWVzaCA9IG1lc2g7XG5cbiAgICBhcGVydHVyZXMuZm9yRWFjaCgoeyBXaWR0aCwgRGVwdGgsIExvY2F0aW9uLCBSb3RhdGlvbiwgVHlwZSB9KSA9PiB7XG4gICAgICBjb25zdCBpc0Rvb3IgPSBUeXBlID09PSAnRG9vcic7XG4gICAgICBjb25zdCBhcGVydHVyZUdlb21ldHJ5ID0gbmV3IFRIUkVFLkJveEdlb21ldHJ5KFxuICAgICAgICAoV2lkdGggKyBhZGRpdGlvbmFsV2lkdGgpICogdGhpcy5zY2VuZVNjYWxlLFxuICAgICAgICBEZXB0aCAqIHRoaXMuc2NlbmVTY2FsZSArIDEsXG4gICAgICAgIChpc0Rvb3IgPyB0aGlzLmRvb3JzSGVpZ2h0IDogdGhpcy53YWxsc0hlaWdodCAvIDIpICsgKGFkZGl0aW9uYWxXaWR0aCAqIHRoaXMuc2NlbmVTY2FsZSksXG4gICAgICApO1xuICAgICAgY29uc3QgYXBlcnR1cmVNYXRlcmlhbCA9IGNyZWF0ZURlZmF1bHRNYXRlcmlhbCh7IGNvbG9yOiAnIzAwQjRGNycgfSk7XG4gICAgICBjb25zdCBhcGVydHVyZU1lc2ggPSBuZXcgVEhSRUUuTWVzaChhcGVydHVyZUdlb21ldHJ5LCBhcGVydHVyZU1hdGVyaWFsKTtcbiAgICAgIGFwZXJ0dXJlTWVzaC5yb3RhdGlvbi56ID0gVEhSRUUuTWF0aC5kZWdUb1JhZChSb3RhdGlvbi5ZYXcpO1xuICAgICAgYXBlcnR1cmVNZXNoLnBvc2l0aW9uLnggPSBMb2NhdGlvbi5YICogdGhpcy5zY2VuZVNjYWxlO1xuICAgICAgYXBlcnR1cmVNZXNoLnBvc2l0aW9uLnkgPSBMb2NhdGlvbi5ZICogdGhpcy5zY2VuZVNjYWxlO1xuICAgICAgYXBlcnR1cmVNZXNoLnBvc2l0aW9uLnogPSBpc0Rvb3IgPyB0aGlzLmRvb3JzSGVpZ2h0IC8gMiA6IHRoaXMud2FsbHNIZWlnaHQgLyAyO1xuXG4gICAgICBhcGVydHVyZU1lc2gudXBkYXRlTWF0cml4KCk7XG4gICAgICByZXN1bHRNZXNoLnVwZGF0ZU1hdHJpeCgpO1xuXG4gICAgICBjb25zdCBhcGVydHVyZUJTUCA9IENTRy5mcm9tTWVzaChhcGVydHVyZU1lc2gpO1xuICAgICAgY29uc3Qgd2FsbEJTUCA9IENTRy5mcm9tTWVzaChyZXN1bHRNZXNoKTtcblxuICAgICAgY29uc3QgcmVzdWx0QlNQID0gd2FsbEJTUC5zdWJ0cmFjdChhcGVydHVyZUJTUCk7XG4gICAgICByZXN1bHRNZXNoID0gQ1NHLnRvTWVzaChyZXN1bHRCU1AsIG1lc2gubWF0cml4LCByZXN1bHRNZXNoLm1hdGVyaWFsKTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHRNZXNoO1xuICB9XG5cbiAgc2V0Q2VudGVyUG9zaXRpb24oKSB7XG4gICAgY29uc3Qgd2FsbHMgPSB0aGlzLmV4dGVyaW9yV2FsbHMubWFwKCh3YWxsSWQpID0+IHRoaXMuZ2V0UGFyc2VkV2FsbEJ5SWQod2FsbElkKSk7XG4gICAgY29uc3QgeyBtYXhYLCBtaW5YLCBtYXhZLCBtaW5ZIH0gPSBnZXRNaW5NYXhDb29yZGluYXRlcyh3YWxscyk7XG4gICAgY29uc3QgY2VudGVyWCA9IChtYXhYICsgbWluWCkgLyAyO1xuICAgIGNvbnN0IGNlbnRlclkgPSAobWF4WSArIG1pblkpIC8gMjtcbiAgICBjb25zdCBsaWdodHNPZmZzZXQgPSAyNTtcbiAgICB0aGlzLmhvdXNlR3JvdXAucG9zaXRpb24uc2V0KC1jZW50ZXJYLCAtY2VudGVyWSk7XG5cbiAgICBjb25zdCBsaWdodHMgPSBbXG4gICAgICB7IHg6IGNlbnRlclggLSBsaWdodHNPZmZzZXQsIHk6IGNlbnRlclkgLSBsaWdodHNPZmZzZXQsIHo6IHRoaXMud2FsbHNIZWlnaHQgKiAzLCBwb3dlcjogMC40LCBjYXN0U2hhZG93OiB0cnVlIH0sXG4gICAgICB7IHg6IGNlbnRlclggLSBsaWdodHNPZmZzZXQsIHk6IGNlbnRlclkgLSBsaWdodHNPZmZzZXQsIHo6IHRoaXMud2FsbHNIZWlnaHQgKiAyLCBwb3dlcjogMSwgY2FzdFNoYWRvdzogZmFsc2UgfSxcbiAgICAgIHsgeDogY2VudGVyWCArIGxpZ2h0c09mZnNldCwgeTogY2VudGVyWSArIGxpZ2h0c09mZnNldCwgejogdGhpcy53YWxsc0hlaWdodCAqIDIsIHBvd2VyOiAxLjEsIGNhc3RTaGFkb3c6IGZhbHNlIH0sXG4gICAgICB7IHg6IGNlbnRlclgsIHk6IGNlbnRlclksIHo6IHRoaXMud2FsbHNIZWlnaHQgKiA1LCBwb3dlcjogMC4xLCBjYXN0U2hhZG93OiBmYWxzZSB9LFxuICAgIF07XG5cbiAgICBjb25zdCB0YXJnZXRPYmplY3QgPSBuZXcgVEhSRUUuT2JqZWN0M0QoKTtcbiAgICB0YXJnZXRPYmplY3QucG9zaXRpb24uc2V0KGNlbnRlclgsIGNlbnRlclksIDApO1xuICAgIHRoaXMuaG91c2VHcm91cC5hZGQodGFyZ2V0T2JqZWN0KTtcblxuICAgIGxpZ2h0cy5mb3JFYWNoKCh7IHgsIHksIHosIHBvd2VyLCBjYXN0U2hhZG93IH0pID0+IHtcbiAgICAgIGNvbnN0IGxpZ2h0ID0gbmV3IFRIUkVFLkRpcmVjdGlvbmFsTGlnaHQoMHhmZmZmZmYsIHBvd2VyKTtcbiAgICAgIGxpZ2h0LnBvc2l0aW9uLnNldCh4LCB5LCB6KTtcbiAgICAgIGxpZ2h0LnNoYWRvd0xpZ2h0ID0gY2FzdFNoYWRvdztcbiAgICAgIGxpZ2h0LmNhc3RTaGFkb3cgPSBjYXN0U2hhZG93O1xuICAgICAgbGlnaHQuc2hhZG93LmNhbWVyYS5sZWZ0ID0gLWNlbnRlclggKiAyO1xuICAgICAgbGlnaHQuc2hhZG93LmNhbWVyYS5yaWdodCA9IGNlbnRlclggKiAyO1xuICAgICAgbGlnaHQuc2hhZG93LmNhbWVyYS50b3AgPSBjZW50ZXJZICogMjtcbiAgICAgIGxpZ2h0LnNoYWRvdy5jYW1lcmEuYm90dG9tID0gLWNlbnRlclkgKiAyO1xuICAgICAgbGlnaHQuc2hhZG93LmNhbWVyYS56b29tID0gMTtcbiAgICAgIGxpZ2h0LnNoYWRvdy5tYXBTaXplID0gbmV3IFRIUkVFLlZlY3RvcjIoMjA0OCwgMjA0OCk7XG4gICAgICBsaWdodC5zaGFkb3cubm9ybWFsQmlhcyA9IDE7XG4gICAgICBsaWdodC50YXJnZXQgPSB0YXJnZXRPYmplY3Q7XG5cbiAgICAgIHRoaXMuaG91c2VHcm91cC5hZGQobGlnaHQpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBsb2FkVGV4dHVyZShpbWcsIHJlcGVhdCA9IFsxLCAxXSwgY2FsbGJhY2sgPSAoKSA9PiB7fSkge1xuICAgIHRoaXMudGV4dHVyZUxvYWRlci5sb2FkKGltZywgKHRleHR1cmUpID0+IHtcbiAgICAgIHRleHR1cmUud3JhcFMgPSB0ZXh0dXJlLndyYXBUID0gVEhSRUUuUmVwZWF0V3JhcHBpbmc7XG4gICAgICB0ZXh0dXJlLnJlcGVhdC5zZXQocmVwZWF0WzBdLCByZXBlYXRbMV0pO1xuICAgICAgdGV4dHVyZS5mbGlwWSA9IGZhbHNlO1xuXG4gICAgICBjYWxsYmFjayh0ZXh0dXJlKTtcbiAgICB9KTtcbiAgfVxuXG4gIGxvYWRUZXh0dXJlcygpIHtcbiAgICBjb25zdCBhc3NldHMgPSBbXG4gICAgICB7XG4gICAgICAgIGltZzogV2FsbFRleHR1cmVJbWcsXG4gICAgICAgIHJlcGVhdDogWzAuNSwgMC41XSxcbiAgICAgICAgY2FsbGJhY2s6ICh0ZXh0dXJlKSA9PiB7XG4gICAgICAgICAgdGhpcy53YWxsc1RleHR1cmVzLnB1c2goeyBpbWFnZTogV2FsbFRleHR1cmVJbWcsIHRleHR1cmU6IHRleHR1cmUgfSk7XG4gICAgICAgICAgdGhpcy53YWxsc01hdGVyaWFsID0gY3JlYXRlRGVmYXVsdE1hdGVyaWFsKHsgLi4udGhpcy53YWxsTWF0ZXJpYWxPcHRpb25zLCBtYXA6IHRleHR1cmUgfSk7XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBpbWc6IEV4dGVyaW9yV2FsbFRleHR1cmVJbWcsXG4gICAgICAgIHJlcGVhdDogWzEsIDFdLFxuICAgICAgICBjYWxsYmFjazogKHRleHR1cmUpID0+IHtcbiAgICAgICAgICB0aGlzLndhbGxzVGV4dHVyZXMucHVzaCh7IGltYWdlOiBFeHRlcmlvcldhbGxUZXh0dXJlSW1nLCB0ZXh0dXJlOiB0ZXh0dXJlIH0pO1xuICAgICAgICAgIHRoaXMuZXh0ZXJpb3JXYWxsc01hcHMubWFwID0gdGV4dHVyZTtcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGltZzogRXh0ZXJpb3JXYWxsVGV4dHVyZVJvdWdobmVzc0ltZyxcbiAgICAgICAgcmVwZWF0OiBbMSwgMV0sXG4gICAgICAgIGNhbGxiYWNrOiAodGV4dHVyZSkgPT4ge1xuICAgICAgICAgIHRoaXMud2FsbHNUZXh0dXJlcy5wdXNoKHsgaW1hZ2U6IEV4dGVyaW9yV2FsbFRleHR1cmVSb3VnaG5lc3NJbWcsIHRleHR1cmU6IHRleHR1cmUgfSk7XG4gICAgICAgICAgdGhpcy5leHRlcmlvcldhbGxzTWFwcy5yb3VnaG5lc3NNYXAgPSB0ZXh0dXJlO1xuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaW1nOiBEb29yVGV4dHVyZSxcbiAgICAgICAgcmVwZWF0OiBbMSwgMV0sXG4gICAgICAgIGNhbGxiYWNrOiAodGV4dHVyZSkgPT4ge1xuICAgICAgICAgIHRoaXMuZG9vck1hdGVyaWFsID0gY3JlYXRlRGVmYXVsdE1hdGVyaWFsKHsgLi4uZG9vck1hdGVyaWFsT3B0aW9ucywgbWFwOiB0ZXh0dXJlIH0pO1xuICAgICAgICB9LFxuICAgICAgfSxcbiAgICBdO1xuXG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGFzc2V0cy5tYXAoKHsgaW1nLCByZXBlYXQsIGNhbGxiYWNrIH0pID0+IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICB0aGlzLmxvYWRUZXh0dXJlKGltZywgcmVwZWF0LCAodGV4dHVyZSkgPT4ge1xuICAgICAgICBjYWxsYmFjayh0ZXh0dXJlKTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSk7XG4gICAgfSkpKTtcbiAgfVxuXG4gIGxvYWRGdXJuaXR1cmUoaW5kZXgpIHtcbiAgICBjb25zdCBmdXJuaXR1cmUgPSB0aGlzLmZ1cm5pdHVyZVtpbmRleF07XG4gICAgaWYgKCFmdXJuaXR1cmUpIHJldHVybjtcblxuICAgIGNvbnN0IGZ1cm5pdHVyZURhdGEgPSB0aGlzLmZ1cm5pdHVyZURhdGEuZmluZCgoeyBuYW1lLCB0eXBlIH0pID0+IChuYW1lID09PSBmdXJuaXR1cmUuTW9kZWwgJiYgdHlwZSA9PT0gZnVybml0dXJlLlR5cGUpKTtcbiAgICBpZiAoIWZ1cm5pdHVyZURhdGEpIHtcbiAgICAgIHRoaXMubG9hZEZ1cm5pdHVyZShpbmRleCArIDEpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgbWVzaCwgdGV4dHVyZXMgfSA9IGZ1cm5pdHVyZURhdGE7XG4gICAgY29uc3QgbW9kZWxQYXRoID0gYCR7dGhpcy5hcGlTdG9yZS5BUElfVVJMfS9zdG9yYWdlL2Z1cm5pdHVyZS8ke21lc2h9YDtcblxuICAgIGNvbnN0IHsgTG9jYXRpb24sIFJvdGF0aW9uLCBNb2RlbDogTW9kZWxOYW1lIH0gPSBmdXJuaXR1cmU7XG4gICAgY29uc3QgeyBYLCBZLCBaIH0gPSBMb2NhdGlvbjtcblxuICAgIGNvbnN0IHByb21pc2VzID0gdGV4dHVyZXMubWFwKCh1cmwpID0+IHtcbiAgICAgIGNvbnN0IHRleHR1cmVQYXRoID0gYCR7dGhpcy5hcGlTdG9yZS5BUElfVVJMfS9zdG9yYWdlL2Z1cm5pdHVyZS8ke3VybH1gO1xuXG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgdGhpcy50ZXh0dXJlTG9hZGVyLmxvYWQodGV4dHVyZVBhdGgsICh0ZXh0dXJlKSA9PiByZXNvbHZlKHRleHR1cmUpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgb25UZXh0dXJlc0xvYWRlZCA9IChyZXN1bHQsIG1vZGVsKSA9PiB7XG4gICAgICBjb25zdCBtYXRlcmlhbHNDb3VudCA9IHJlc3VsdC5yZWR1Y2UoKGFjYywgeyBpbWFnZSB9KSA9PiB7XG4gICAgICAgIGlmICghaW1hZ2UuY3VycmVudFNyYy5pbmNsdWRlcygnX0QuJykgJiYgIWltYWdlLmN1cnJlbnRTcmMuaW5jbHVkZXMoJ19EQS4nKSkgcmV0dXJuIGFjYztcbiAgICAgICAgcmV0dXJuIGFjYyArPSAxO1xuICAgICAgfSwgMCk7XG5cbiAgICAgIGNvbnN0IGNyZWF0ZU1hdGVyaWFsID0gKG51bSkgPT4ge1xuICAgICAgICBjb25zdCBtYXAgPSByZXN1bHQuZmluZCgoeyBpbWFnZSB9KSA9PiAoXG4gICAgICAgICAgaW1hZ2UuY3VycmVudFNyYy5pbmNsdWRlcyhgJHtudW19X0QuYCkgfHxcbiAgICAgICAgICBpbWFnZS5jdXJyZW50U3JjLmluY2x1ZGVzKGAke251bX1fREEuYClcbiAgICAgICAgKSk7XG4gICAgICAgIGNvbnN0IGVudk1hcCA9IHJlc3VsdC5maW5kKCh7IGltYWdlIH0pID0+IGltYWdlLmN1cnJlbnRTcmMuaW5jbHVkZXMoYCR7bnVtfV9STU8uYCkpO1xuICAgICAgICBjb25zdCBub3JtYWxNYXAgPSByZXN1bHQuZmluZCgoeyBpbWFnZSB9KSA9PiBpbWFnZS5jdXJyZW50U3JjLmluY2x1ZGVzKGAke251bX1fTi5gKSk7XG4gICAgICAgIGNvbnN0IG1hdGVyaWFsID0gbmV3IFRIUkVFLk1lc2hTdGFuZGFyZE1hdGVyaWFsKHsgcm91Z2huZXNzOiAxLCB0cmFuc3BhcmVudDogdHJ1ZSB9KTtcbiAgICAgICAgbWF0ZXJpYWwuZGVwdGhXcml0ZSA9ICEoTW9kZWxOYW1lID09PSAnRmxvd2VyJyAmJiBudW0gPT09ICcwMScpO1xuXG4gICAgICAgIGlmIChtYXApIG1hdGVyaWFsLm1hcCA9IG1hcDtcbiAgICAgICAgaWYgKGVudk1hcCkgbWF0ZXJpYWwuZW52TWFwID0gZW52TWFwO1xuICAgICAgICBpZiAobm9ybWFsTWFwKSBtYXRlcmlhbC5ub3JtYWxNYXAgPSBub3JtYWxNYXA7XG5cbiAgICAgICAgcmV0dXJuIG1hdGVyaWFsO1xuICAgICAgfTtcblxuICAgICAgbGV0IG1hdGVyaWFscyA9IG5ldyBUSFJFRS5NZXNoUGh5c2ljYWxNYXRlcmlhbCh7XG4gICAgICAgIHJvdWdobmVzczogMSxcbiAgICAgICAgY2xlYXJjb2F0OiAxLFxuICAgICAgICBjbGVhcmNvYXRSb3VnaG5lc3M6IDEsXG4gICAgICAgIHJlZmxlY3Rpdml0eTogMCxcbiAgICAgICAgZm9nOiBmYWxzZSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAobWF0ZXJpYWxzQ291bnQgPT09IDEpIHtcbiAgICAgICAgbWF0ZXJpYWxzID0gY3JlYXRlTWF0ZXJpYWwoJycpO1xuICAgICAgfVxuXG4gICAgICBpZiAobWF0ZXJpYWxzQ291bnQgPiAxKSB7XG4gICAgICAgIG1hdGVyaWFscyA9IFsuLi5BcnJheShtYXRlcmlhbHNDb3VudCkua2V5cygpXS5tYXAoKGkpID0+IHtcbiAgICAgICAgICBjb25zdCBudW0gPSBpICsgMTtcbiAgICAgICAgICBjb25zdCByZWFsTnVtID0gbnVtIDwgMTAgPyBgMCR7bnVtfWAgOiBudW07XG4gICAgICAgICAgcmV0dXJuIGNyZWF0ZU1hdGVyaWFsKHJlYWxOdW0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgbW9kZWwudHJhdmVyc2UoKG5vZGUpID0+IHtcbiAgICAgICAgaWYgKG5vZGUuaXNNZXNoKSB7XG4gICAgICAgICAgbm9kZS5tYXRlcmlhbCA9IG1hdGVyaWFscztcbiAgICAgICAgICBub2RlLnJlY2VpdmVTaGFkb3cgPSB0cnVlO1xuICAgICAgICAgIG5vZGUuY2FzdFNoYWRvdyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLmhvdXNlR3JvdXAuYWRkKG1vZGVsKTtcbiAgICAgIHRoaXMubG9hZEZ1cm5pdHVyZShpbmRleCArIDEpO1xuICAgIH07XG5cbiAgICBjb25zdCBvbk1vZGVsTG9hZGVkID0gKG9yaWdpbmFsTW9kZWwpID0+IHtcbiAgICAgIGNvbnN0IG1vZGVsID0gb3JpZ2luYWxNb2RlbC5jbG9uZSgpO1xuICAgICAgbW9kZWwuc2NhbGUuc2V0KHRoaXMuc2NlbmVTY2FsZSwgdGhpcy5zY2VuZVNjYWxlLCB0aGlzLnNjZW5lU2NhbGUpO1xuICAgICAgbW9kZWwucG9zaXRpb24uc2V0KFggKiB0aGlzLnNjZW5lU2NhbGUsIFkgKiB0aGlzLnNjZW5lU2NhbGUsIFogKiB0aGlzLnNjZW5lU2NhbGUpO1xuICAgICAgbW9kZWwucm90YXRpb24uc2V0KE1hdGguUEkgLyAyLCBUSFJFRS5NYXRoLmRlZ1RvUmFkKFJvdGF0aW9uLllhdyksIDApO1xuXG4gICAgICBjb25zdCBsb2FkZWRUZXh0dXJlcyA9IHRoaXMubG9hZGVkVGV4dHVyZXNbTW9kZWxOYW1lXTtcblxuICAgICAgaWYgKGxvYWRlZFRleHR1cmVzKSB7XG4gICAgICAgIG9uVGV4dHVyZXNMb2FkZWQobG9hZGVkVGV4dHVyZXMsIG1vZGVsKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgIG9uVGV4dHVyZXNMb2FkZWQocmVzdWx0LCBtb2RlbCk7XG4gICAgICAgIHRoaXMubG9hZGVkVGV4dHVyZXNbTW9kZWxOYW1lXSA9IHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBjb25zdCBsb2FkZWRNb2RlbCA9IHRoaXMubG9hZGVkTW9kZWxzW01vZGVsTmFtZV07XG5cbiAgICBpZiAobG9hZGVkTW9kZWwpIHtcbiAgICAgIG9uTW9kZWxMb2FkZWQobG9hZGVkTW9kZWwpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG1vZGVsTG9hZGVyLmxvYWQobW9kZWxQYXRoLCAobW9kZWwpID0+IHtcbiAgICAgIHRoaXMubG9hZGVkTW9kZWxzW01vZGVsTmFtZV0gPSBtb2RlbDtcbiAgICAgIG9uTW9kZWxMb2FkZWQobW9kZWwpO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gQWN0aW9uc1xuXG4gIHNldFNoYWRvd3NWaXNpYmlsaXR5KHZhbHVlKSB7XG4gICAgdGhpcy5pc1NoYWRvd3NWaXNpYmxlID0gdmFsdWU7XG4gICAgdGhpcy5ob3VzZUdyb3VwLmNoaWxkcmVuLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICAgIGNvbnN0IGlzTGlnaHQgPSBub2RlIGluc3RhbmNlb2YgVEhSRUUuRGlyZWN0aW9uYWxMaWdodDtcbiAgICAgIGlmICghaXNMaWdodCkgcmV0dXJuO1xuICAgICAgaWYgKCFub2RlLnNoYWRvd0xpZ2h0KSByZXR1cm47XG4gICAgICBub2RlLmNhc3RTaGFkb3cgPSB2YWx1ZTtcbiAgICB9KTtcbiAgfVxuXG4gIHNldERvb3JzVmlzaWJpbGl0eSh2YWx1ZSkge1xuICAgIHRoaXMuaXNEb29yc1Zpc2libGUgPSB2YWx1ZTtcbiAgICB0aGlzLmRvb3JzR3JvdXAuY2hpbGRyZW4uZm9yRWFjaCgoZG9vcikgPT4gZG9vci52aXNpYmxlID0gdmFsdWUpO1xuICB9XG5cbiAgc2V0Q3VycmVudFdhbGxzTWF0ZXJpYWxUeXBlKHZhbHVlKSB7XG4gICAgdGhpcy53YWxsc01hdGVyaWFsVHlwZSA9IHZhbHVlO1xuXG4gICAgdGhpcy53YWxsc0dyb3VwLmNoaWxkcmVuLmZvckVhY2goKHsgY2hpbGRyZW4sIGlzRXh0ZXJpb3IgfSkgPT4ge1xuICAgICAgY29uc3Qgd2FsbCA9IGNoaWxkcmVuWzBdO1xuICAgICAgaWYgKHZhbHVlID09PSAndGV4dHVyZScpIHtcbiAgICAgICAgd2FsbC5tYXRlcmlhbCA9IGlzRXh0ZXJpb3IgPyB0aGlzLmV4dGVyaW9yV2FsbHNNYXRlcmlhbCA6IHRoaXMud2FsbHNNYXRlcmlhbDtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgY29sb3IgPSBpc0V4dGVyaW9yID8gJyNGRkZGRkYnIDogdGhpcy53YWxsc0NvbG9yO1xuICAgICAgd2FsbC5tYXRlcmlhbCA9IGNyZWF0ZURlZmF1bHRNYXRlcmlhbCh7IC4uLnRoaXMud2FsbE1hdGVyaWFsT3B0aW9ucywgY29sb3IgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmRvb3JzR3JvdXAuY2hpbGRyZW4uZm9yRWFjaCgoZG9vcikgPT4ge1xuICAgICAgaWYgKHZhbHVlID09PSAndGV4dHVyZScpIHtcbiAgICAgICAgZG9vci5tYXRlcmlhbCA9IHRoaXMuZG9vck1hdGVyaWFsO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBkb29yLm1hdGVyaWFsID0gY3JlYXRlRGVmYXVsdE1hdGVyaWFsKGRvb3JNYXRlcmlhbE9wdGlvbnMpO1xuICAgIH0pO1xuICB9XG5cbiAgc2V0Q3VycmVudFdhbGxDb2xvcihjb2xvcikge1xuICAgIHRoaXMud2FsbHNDb2xvciA9IGNvbG9yO1xuICAgIHRoaXMud2FsbHNNYXRlcmlhbC5jb2xvci5zZXQoY29sb3IpO1xuICAgIHRoaXMud2FsbHNHcm91cC5jaGlsZHJlbi5mb3JFYWNoKCh7IGNoaWxkcmVuLCBpc0V4dGVyaW9yIH0pID0+IHtcbiAgICAgIGlmIChpc0V4dGVyaW9yKSByZXR1cm47XG4gICAgICBjb25zdCB3YWxsID0gY2hpbGRyZW5bMF07XG4gICAgICB3YWxsLm1hdGVyaWFsLmNvbG9yLnNldChjb2xvcik7XG4gICAgfSk7XG4gIH1cblxuICBzZXRDdXJyZW50V2FsbFRleHR1cmUodGV4dHVyZSkge1xuICAgIHRoaXMud2FsbHNNYXRlcmlhbCA9IGNyZWF0ZURlZmF1bHRNYXRlcmlhbCh7IC4uLnRoaXMud2FsbE1hdGVyaWFsT3B0aW9ucywgbWFwOiB0ZXh0dXJlIH0pO1xuICAgIHRoaXMuc2V0Q3VycmVudFdhbGxzTWF0ZXJpYWxUeXBlKCd0ZXh0dXJlJyk7XG4gIH1cblxuICBhZGRXYWxsVGV4dHVyZShpbWFnZSkge1xuICAgIHRoaXMubG9hZFRleHR1cmUoaW1hZ2UsIFswLjUsIDAuNV0sICh0ZXh0dXJlKSA9PiB7XG4gICAgICB0aGlzLndhbGxzVGV4dHVyZXMucHVzaCh7IGltYWdlLCB0ZXh0dXJlIH0pO1xuICAgICAgdGhpcy5zZXRDdXJyZW50V2FsbFRleHR1cmUodGV4dHVyZSk7XG4gICAgfSk7XG4gIH1cblxuICBzZXRGdWxsQnVpbGRpbmdWaXNpYmlsaXR5KHZhbHVlKSB7XG4gICAgdGhpcy5pc0Z1bGxCdWlsZGluZ1Zpc2libGUgPSB2YWx1ZTtcbiAgICB0aGlzLmdsb2JhbFBsYW5lLmNvbnN0YW50ID0gdGhpcy5pc0Z1bGxCdWlsZGluZ1Zpc2libGUgPyAxIDogY2xpcHBlZEJ1aWxkaW5nQ29uc3RhbnQ7XG4gICAgdGhpcy53YWxsc0dyb3VwLmNoaWxkcmVuLmZvckVhY2goKHsgY2hpbGRyZW4gfSkgPT4gY2hpbGRyZW5bMl0udmlzaWJsZSA9ICF2YWx1ZSk7XG4gIH1cblxuICBzZXRQbGFuTW9kZSgpIHtcbiAgICB0aGlzLnNldERvb3JzVmlzaWJpbGl0eShmYWxzZSk7XG4gICAgdGhpcy5zZXRGdWxsQnVpbGRpbmdWaXNpYmlsaXR5KGZhbHNlKTtcbiAgICB0aGlzLnNldEN1cnJlbnRXYWxsc01hdGVyaWFsVHlwZSgnY29sb3InKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBIb3VzZVN0b3JlO1xuIl19