vendor: 78 bytes, lines 1-3
1/******/ (() => { // webpackBootstrap 2/******/ var __webpack_modules__ = ({ 3
vendor: 37,855 bytes, lines 4-996
4/***/ "./node_modules/@googlemaps/markerclusterer/dist/index.esm.js": 5/*!********************************************************************!*\ 6 !*** ./node_modules/@googlemaps/markerclusterer/dist/index.esm.js ***! 7 \********************************************************************/ 8/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 9 10"use strict"; 11__webpack_require__.r(__webpack_exports__); 12/* harmony export */ __webpack_require__.d(__webpack_exports__, { 13/* harmony export */ AbstractAlgorithm: () => (/* binding */ AbstractAlgorithm), 14/* harmony export */ AbstractViewportAlgorithm: () => (/* binding */ AbstractViewportAlgorithm), 15/* harmony export */ Cluster: () => (/* binding */ Cluster), 16/* harmony export */ ClusterStats: () => (/* binding */ ClusterStats), 17/* harmony export */ DefaultRenderer: () => (/* binding */ DefaultRenderer), 18/* harmony export */ GridAlgorithm: () => (/* binding */ GridAlgorithm), 19/* harmony export */ MarkerClusterer: () => (/* binding */ MarkerClusterer), 20/* harmony export */ MarkerClustererEvents: () => (/* binding */ MarkerClustererEvents), 21/* harmony export */ MarkerUtils: () => (/* binding */ MarkerUtils), 22/* harmony export */ NoopAlgorithm: () => (/* binding */ NoopAlgorithm), 23/* harmony export */ SuperClusterAlgorithm: () => (/* binding */ SuperClusterAlgorithm), 24/* harmony export */ SuperClusterViewportAlgorithm: () => (/* binding */ SuperClusterViewportAlgorithm), 25/* harmony export */ defaultOnClusterClickHandler: () => (/* binding */ defaultOnClusterClickHandler), 26/* harmony export */ distanceBetweenPoints: () => (/* binding */ distanceBetweenPoints), 27/* harmony export */ extendBoundsToPaddedViewport: () => (/* binding */ extendBoundsToPaddedViewport), 28/* harmony export */ extendPixelBounds: () => (/* binding */ extendPixelBounds), 29/* harmony export */ filterMarkersToPaddedViewport: () => (/* binding */ filterMarkersToPaddedViewport), 30/* harmony export */ getPaddedViewport: () => (/* binding */ getPaddedViewport), 31/* harmony export */ noop: () => (/* binding */ noop), 32/* harmony export */ pixelBoundsToLatLngBounds: () => (/* binding */ pixelBoundsToLatLngBounds) 33/* harmony export */ }); 34/* harmony import */ var fast_deep_equal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! fast-deep-equal */ "./node_modules/fast-deep-equal/index.js"); 35/* harmony import */ var fast_deep_equal__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fast_deep_equal__WEBPACK_IMPORTED_MODULE_0__); 36/* harmony import */ var supercluster__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! supercluster */ "./node_modules/supercluster/index.js"); 37 38 39 40/*! ***************************************************************************** 41Copyright (c) Microsoft Corporation. 42 43Permission to use, copy, modify, and/or distribute this software for any 44purpose with or without fee is hereby granted. 45 46THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 47REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 48AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 49INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 50LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 51OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 52PERFORMANCE OF THIS SOFTWARE. 53***************************************************************************** */ 54 55function __rest(s, e) { 56 var t = {}; 57 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 58 t[p] = s[p]; 59 if (s != null && typeof Object.getOwnPropertySymbols === "function") 60 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 61 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 62 t[p[i]] = s[p[i]]; 63 } 64 return t; 65} 66 67/** 68 * Copyright 2023 Google LLC 69 * 70 * Licensed under the Apache License, Version 2.0 (the "License"); 71 * you may not use this file except in compliance with the License. 72 * You may obtain a copy of the License at 73 * 74 * http://www.apache.org/licenses/LICENSE-2.0 75 * 76 * Unless required by applicable law or agreed to in writing, software 77 * distributed under the License is distributed on an "AS IS" BASIS, 78 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 79 * See the License for the specific language governing permissions and 80 * limitations under the License. 81 */ 82/** 83 * util class that creates a common set of convenience functions to wrap 84 * shared behavior of Advanced Markers and Markers. 85 */ 86class MarkerUtils { 87 static isAdvancedMarkerAvailable(map) { 88 return (google.maps.marker && 89 map.getMapCapabilities().isAdvancedMarkersAvailable === true); 90 } 91 static isAdvancedMarker(marker) { 92 return (google.maps.marker && 93 marker instanceof google.maps.marker.AdvancedMarkerElement); 94 } 95 static setMap(marker, map) { 96 if (this.isAdvancedMarker(marker)) { 97 marker.map = map; 98 } 99 else { 100 marker.setMap(map); 101 } 102 } 103 static getPosition(marker) { 104 // SuperClusterAlgorithm.calculate expects a LatLng instance so we fake it for Adv Markers 105 if (this.isAdvancedMarker(marker)) { 106 if (marker.position) { 107 if (marker.position instanceof google.maps.LatLng) { 108 return marker.position; 109 } 110 // since we can't cast to LatLngLiteral for reasons =( 111 if (marker.position.lat && marker.position.lng) { 112 return new google.maps.LatLng(marker.position.lat, marker.position.lng); 113 } 114 } 115 return new google.maps.LatLng(null); 116 } 117 return marker.getPosition(); 118 } 119 static getVisible(marker) { 120 if (this.isAdvancedMarker(marker)) { 121 /** 122 * Always return true for Advanced Markers because the clusterer 123 * uses getVisible as a way to count legacy markers not as an actual 124 * indicator of visibility for some reason. Even when markers are hidden 125 * Marker.getVisible returns `true` and this is used to set the marker count 126 * on the cluster. See the behavior of Cluster.count 127 */ 128 return true; 129 } 130 return marker.getVisible(); 131 } 132} 133 134/** 135 * Copyright 2021 Google LLC 136 * 137 * Licensed under the Apache License, Version 2.0 (the "License"); 138 * you may not use this file except in compliance with the License. 139 * You may obtain a copy of the License at 140 * 141 * http://www.apache.org/licenses/LICENSE-2.0 142 * 143 * Unless required by applicable law or agreed to in writing, software 144 * distributed under the License is distributed on an "AS IS" BASIS, 145 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 146 * See the License for the specific language governing permissions and 147 * limitations under the License. 148 */ 149class Cluster { 150 constructor({ markers, position }) { 151 this.markers = markers; 152 if (position) { 153 if (position instanceof google.maps.LatLng) { 154 this._position = position; 155 } 156 else { 157 this._position = new google.maps.LatLng(position); 158 } 159 } 160 } 161 get bounds() { 162 if (this.markers.length === 0 && !this._position) { 163 return; 164 } 165 const bounds = new google.maps.LatLngBounds(this._position, this._position); 166 for (const marker of this.markers) { 167 bounds.extend(MarkerUtils.getPosition(marker)); 168 } 169 return bounds; 170 } 171 get position() { 172 return this._position || this.bounds.getCenter(); 173 } 174 /** 175 * Get the count of **visible** markers. 176 */ 177 get count() { 178 return this.markers.filter((m) => MarkerUtils.getVisible(m)).length; 179 } 180 /** 181 * Add a marker to the cluster. 182 */ 183 push(marker) { 184 this.markers.push(marker); 185 } 186 /** 187 * Cleanup references and remove marker from map. 188 */ 189 delete() { 190 if (this.marker) { 191 MarkerUtils.setMap(this.marker, null); 192 this.marker = undefined; 193 } 194 this.markers.length = 0; 195 } 196} 197 198/** 199 * Copyright 2021 Google LLC 200 * 201 * Licensed under the Apache License, Version 2.0 (the "License"); 202 * you may not use this file except in compliance with the License. 203 * You may obtain a copy of the License at 204 * 205 * http://www.apache.org/licenses/LICENSE-2.0 206 * 207 * Unless required by applicable law or agreed to in writing, software 208 * distributed under the License is distributed on an "AS IS" BASIS, 209 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 210 * See the License for the specific language governing permissions and 211 * limitations under the License. 212 */ 213/** 214 * Returns the markers visible in a padded map viewport 215 * 216 * @param map 217 * @param mapCanvasProjection 218 * @param markers The list of marker to filter 219 * @param viewportPaddingPixels The padding in pixel 220 * @returns The list of markers in the padded viewport 221 */ 222const filterMarkersToPaddedViewport = (map, mapCanvasProjection, markers, viewportPaddingPixels) => { 223 const extendedMapBounds = extendBoundsToPaddedViewport(map.getBounds(), mapCanvasProjection, viewportPaddingPixels); 224 return markers.filter((marker) => extendedMapBounds.contains(MarkerUtils.getPosition(marker))); 225}; 226/** 227 * Extends a bounds by a number of pixels in each direction 228 */ 229const extendBoundsToPaddedViewport = (bounds, projection, numPixels) => { 230 const { northEast, southWest } = latLngBoundsToPixelBounds(bounds, projection); 231 const extendedPixelBounds = extendPixelBounds({ northEast, southWest }, numPixels); 232 return pixelBoundsToLatLngBounds(extendedPixelBounds, projection); 233}; 234/** 235 * Gets the extended bounds as a bbox [westLng, southLat, eastLng, northLat] 236 */ 237const getPaddedViewport = (bounds, projection, pixels) => { 238 const extended = extendBoundsToPaddedViewport(bounds, projection, pixels); 239 const ne = extended.getNorthEast(); 240 const sw = extended.getSouthWest(); 241 return [sw.lng(), sw.lat(), ne.lng(), ne.lat()]; 242}; 243/** 244 * Returns the distance between 2 positions. 245 * 246 * @hidden 247 */ 248const distanceBetweenPoints = (p1, p2) => { 249 const R = 6371; // Radius of the Earth in km 250 const dLat = ((p2.lat - p1.lat) * Math.PI) / 180; 251 const dLon = ((p2.lng - p1.lng) * Math.PI) / 180; 252 const sinDLat = Math.sin(dLat / 2); 253 const sinDLon = Math.sin(dLon / 2); 254 const a = sinDLat * sinDLat + 255 Math.cos((p1.lat * Math.PI) / 180) * 256 Math.cos((p2.lat * Math.PI) / 180) * 257 sinDLon * 258 sinDLon; 259 const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 260 return R * c; 261}; 262/** 263 * Converts a LatLng bound to pixels. 264 * 265 * @hidden 266 */ 267const latLngBoundsToPixelBounds = (bounds, projection) => { 268 return { 269 northEast: projection.fromLatLngToDivPixel(bounds.getNorthEast()), 270 southWest: projection.fromLatLngToDivPixel(bounds.getSouthWest()), 271 }; 272}; 273/** 274 * Extends a pixel bounds by numPixels in all directions. 275 * 276 * @hidden 277 */ 278const extendPixelBounds = ({ northEast, southWest }, numPixels) => { 279 northEast.x += numPixels; 280 northEast.y -= numPixels; 281 southWest.x -= numPixels; 282 southWest.y += numPixels; 283 return { northEast, southWest }; 284}; 285/** 286 * @hidden 287 */ 288const pixelBoundsToLatLngBounds = ({ northEast, southWest }, projection) => { 289 const sw = projection.fromDivPixelToLatLng(southWest); 290 const ne = projection.fromDivPixelToLatLng(northEast); 291 return new google.maps.LatLngBounds(sw, ne); 292}; 293 294/** 295 * Copyright 2021 Google LLC 296 * 297 * Licensed under the Apache License, Version 2.0 (the "License"); 298 * you may not use this file except in compliance with the License. 299 * You may obtain a copy of the License at 300 * 301 * http://www.apache.org/licenses/LICENSE-2.0 302 * 303 * Unless required by applicable law or agreed to in writing, software 304 * distributed under the License is distributed on an "AS IS" BASIS, 305 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 306 * See the License for the specific language governing permissions and 307 * limitations under the License. 308 */ 309/** 310 * @hidden 311 */ 312class AbstractAlgorithm { 313 constructor({ maxZoom = 16 }) { 314 this.maxZoom = maxZoom; 315 } 316 /** 317 * Helper function to bypass clustering based upon some map state such as 318 * zoom, number of markers, etc. 319 * 320 * ```typescript 321 * cluster({markers, map}: AlgorithmInput): Cluster[] { 322 * if (shouldBypassClustering(map)) { 323 * return this.noop({markers}) 324 * } 325 * } 326 * ``` 327 */ 328 noop({ markers, }) { 329 return noop(markers); 330 } 331} 332/** 333 * Abstract viewport algorithm proves a class to filter markers by a padded 334 * viewport. This is a common optimization. 335 * 336 * @hidden 337 */ 338class AbstractViewportAlgorithm extends AbstractAlgorithm { 339 constructor(_a) { 340 var { viewportPadding = 60 } = _a, options = __rest(_a, ["viewportPadding"]); 341 super(options); 342 this.viewportPadding = 60; 343 this.viewportPadding = viewportPadding; 344 } 345 calculate({ markers, map, mapCanvasProjection, }) { 346 if (map.getZoom() >= this.maxZoom) { 347 return { 348 clusters: this.noop({ 349 markers, 350 }), 351 changed: false, 352 }; 353 } 354 return { 355 clusters: this.cluster({ 356 markers: filterMarkersToPaddedViewport(map, mapCanvasProjection, markers, this.viewportPadding), 357 map, 358 mapCanvasProjection, 359 }), 360 }; 361 } 362} 363/** 364 * @hidden 365 */ 366const noop = (markers) => { 367 const clusters = markers.map((marker) => new Cluster({ 368 position: MarkerUtils.getPosition(marker), 369 markers: [marker], 370 })); 371 return clusters; 372}; 373 374/** 375 * Copyright 2021 Google LLC 376 * 377 * Licensed under the Apache License, Version 2.0 (the "License"); 378 * you may not use this file except in compliance with the License. 379 * You may obtain a copy of the License at 380 * 381 * http://www.apache.org/licenses/LICENSE-2.0 382 * 383 * Unless required by applicable law or agreed to in writing, software 384 * distributed under the License is distributed on an "AS IS" BASIS, 385 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 386 * See the License for the specific language governing permissions and 387 * limitations under the License. 388 */ 389/** 390 * The default Grid algorithm historically used in Google Maps marker 391 * clustering. 392 * 393 * The Grid algorithm does not implement caching and markers may flash as the 394 * viewport changes. Instead use {@link SuperClusterAlgorithm}. 395 */ 396class GridAlgorithm extends AbstractViewportAlgorithm { 397 constructor(_a) { 398 var { maxDistance = 40000, gridSize = 40 } = _a, options = __rest(_a, ["maxDistance", "gridSize"]); 399 super(options); 400 this.clusters = []; 401 this.state = { zoom: -1 }; 402 this.maxDistance = maxDistance; 403 this.gridSize = gridSize; 404 } 405 calculate({ markers, map, mapCanvasProjection, }) { 406 const state = { zoom: map.getZoom() }; 407 let changed = false; 408 if (this.state.zoom >= this.maxZoom && state.zoom >= this.maxZoom) ; 409 else { 410 changed = !fast_deep_equal__WEBPACK_IMPORTED_MODULE_0___default()(this.state, state); 411 } 412 this.state = state; 413 if (map.getZoom() >= this.maxZoom) { 414 return { 415 clusters: this.noop({ 416 markers, 417 }), 418 changed, 419 }; 420 } 421 return { 422 clusters: this.cluster({ 423 markers: filterMarkersToPaddedViewport(map, mapCanvasProjection, markers, this.viewportPadding), 424 map, 425 mapCanvasProjection, 426 }), 427 }; 428 } 429 cluster({ markers, map, mapCanvasProjection, }) { 430 this.clusters = []; 431 markers.forEach((marker) => { 432 this.addToClosestCluster(marker, map, mapCanvasProjection); 433 }); 434 return this.clusters; 435 } 436 addToClosestCluster(marker, map, projection) { 437 let maxDistance = this.maxDistance; // Some large number 438 let cluster = null; 439 for (let i = 0; i < this.clusters.length; i++) { 440 const candidate = this.clusters[i]; 441 const distance = distanceBetweenPoints(candidate.bounds.getCenter().toJSON(), MarkerUtils.getPosition(marker).toJSON()); 442 if (distance < maxDistance) { 443 maxDistance = distance; 444 cluster = candidate; 445 } 446 } 447 if (cluster && 448 extendBoundsToPaddedViewport(cluster.bounds, projection, this.gridSize).contains(MarkerUtils.getPosition(marker))) { 449 cluster.push(marker); 450 } 451 else { 452 const cluster = new Cluster({ markers: [marker] }); 453 this.clusters.push(cluster); 454 } 455 } 456} 457 458/** 459 * Copyright 2021 Google LLC 460 * 461 * Licensed under the Apache License, Version 2.0 (the "License"); 462 * you may not use this file except in compliance with the License. 463 * You may obtain a copy of the License at 464 * 465 * http://www.apache.org/licenses/LICENSE-2.0 466 * 467 * Unless required by applicable law or agreed to in writing, software 468 * distributed under the License is distributed on an "AS IS" BASIS, 469 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 470 * See the License for the specific language governing permissions and 471 * limitations under the License. 472 */ 473/** 474 * Noop algorithm does not generate any clusters or filter markers by the an extended viewport. 475 */ 476class NoopAlgorithm extends AbstractAlgorithm { 477 constructor(_a) { 478 var options = __rest(_a, []); 479 super(options); 480 } 481 calculate({ markers, map, mapCanvasProjection, }) { 482 return { 483 clusters: this.cluster({ markers, map, mapCanvasProjection }), 484 changed: false, 485 }; 486 } 487 cluster(input) { 488 return this.noop(input); 489 } 490} 491 492/** 493 * Copyright 2021 Google LLC 494 * 495 * Licensed under the Apache License, Version 2.0 (the "License"); 496 * you may not use this file except in compliance with the License. 497 * You may obtain a copy of the License at 498 * 499 * http://www.apache.org/licenses/LICENSE-2.0 500 * 501 * Unless required by applicable law or agreed to in writing, software 502 * distributed under the License is distributed on an "AS IS" BASIS, 503 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 504 * See the License for the specific language governing permissions and 505 * limitations under the License. 506 */ 507/** 508 * A very fast JavaScript algorithm for geospatial point clustering using KD trees. 509 * 510 * @see https://www.npmjs.com/package/supercluster for more information on options. 511 */ 512class SuperClusterAlgorithm extends AbstractAlgorithm { 513 constructor(_a) { 514 var { maxZoom, radius = 60 } = _a, options = __rest(_a, ["maxZoom", "radius"]); 515 super({ maxZoom }); 516 this.state = { zoom: -1 }; 517 this.superCluster = new supercluster__WEBPACK_IMPORTED_MODULE_1__["default"](Object.assign({ maxZoom: this.maxZoom, radius }, options)); 518 } 519 calculate(input) { 520 let changed = false; 521 const state = { zoom: input.map.getZoom() }; 522 if (!fast_deep_equal__WEBPACK_IMPORTED_MODULE_0___default()(input.markers, this.markers)) { 523 changed = true; 524 // TODO use proxy to avoid copy? 525 this.markers = [...input.markers]; 526 const points = this.markers.map((marker) => { 527 const position = MarkerUtils.getPosition(marker); 528 const coordinates = [position.lng(), position.lat()]; 529 return { 530 type: "Feature", 531 geometry: { 532 type: "Point", 533 coordinates, 534 }, 535 properties: { marker }, 536 }; 537 }); 538 this.superCluster.load(points); 539 } 540 if (!changed) { 541 if (this.state.zoom <= this.maxZoom || state.zoom <= this.maxZoom) { 542 changed = !fast_deep_equal__WEBPACK_IMPORTED_MODULE_0___default()(this.state, state); 543 } 544 } 545 this.state = state; 546 if (changed) { 547 this.clusters = this.cluster(input); 548 } 549 return { clusters: this.clusters, changed }; 550 } 551 cluster({ map }) { 552 return this.superCluster 553 .getClusters([-180, -90, 180, 90], Math.round(map.getZoom())) 554 .map((feature) => this.transformCluster(feature)); 555 } 556 transformCluster({ geometry: { coordinates: [lng, lat], }, properties, }) { 557 if (properties.cluster) { 558 return new Cluster({ 559 markers: this.superCluster 560 .getLeaves(properties.cluster_id, Infinity) 561 .map((leaf) => leaf.properties.marker), 562 position: { lat, lng }, 563 }); 564 } 565 const marker = properties.marker; 566 return new Cluster({ 567 markers: [marker], 568 position: MarkerUtils.getPosition(marker), 569 }); 570 } 571} 572 573/** 574 * Copyright 2021 Google LLC 575 * 576 * Licensed under the Apache License, Version 2.0 (the "License"); 577 * you may not use this file except in compliance with the License. 578 * You may obtain a copy of the License at 579 * 580 * http://www.apache.org/licenses/LICENSE-2.0 581 * 582 * Unless required by applicable law or agreed to in writing, software 583 * distributed under the License is distributed on an "AS IS" BASIS, 584 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 585 * See the License for the specific language governing permissions and 586 * limitations under the License. 587 */ 588/** 589 * A very fast JavaScript algorithm for geospatial point clustering using KD trees. 590 * 591 * @see https://www.npmjs.com/package/supercluster for more information on options. 592 */ 593class SuperClusterViewportAlgorithm extends AbstractViewportAlgorithm { 594 constructor(_a) { 595 var { maxZoom, radius = 60, viewportPadding = 60 } = _a, options = __rest(_a, ["maxZoom", "radius", "viewportPadding"]); 596 super({ maxZoom, viewportPadding }); 597 this.superCluster = new supercluster__WEBPACK_IMPORTED_MODULE_1__["default"](Object.assign({ maxZoom: this.maxZoom, radius }, options)); 598 this.state = { zoom: -1, view: [0, 0, 0, 0] }; 599 } 600 calculate(input) { 601 const state = { 602 zoom: Math.round(input.map.getZoom()), 603 view: getPaddedViewport(input.map.getBounds(), input.mapCanvasProjection, this.viewportPadding), 604 }; 605 let changed = !fast_deep_equal__WEBPACK_IMPORTED_MODULE_0___default()(this.state, state); 606 if (!fast_deep_equal__WEBPACK_IMPORTED_MODULE_0___default()(input.markers, this.markers)) { 607 changed = true; 608 // TODO use proxy to avoid copy? 609 this.markers = [...input.markers]; 610 const points = this.markers.map((marker) => { 611 const position = MarkerUtils.getPosition(marker); 612 const coordinates = [position.lng(), position.lat()]; 613 return { 614 type: "Feature", 615 geometry: { 616 type: "Point", 617 coordinates, 618 }, 619 properties: { marker }, 620 }; 621 }); 622 this.superCluster.load(points); 623 } 624 if (changed) { 625 this.clusters = this.cluster(input); 626 this.state = state; 627 } 628 return { clusters: this.clusters, changed }; 629 } 630 cluster({ map, mapCanvasProjection }) { 631 /* recalculate new state because we can't use the cached version. */ 632 const state = { 633 zoom: Math.round(map.getZoom()), 634 view: getPaddedViewport(map.getBounds(), mapCanvasProjection, this.viewportPadding), 635 }; 636 return this.superCluster 637 .getClusters(state.view, state.zoom) 638 .map((feature) => this.transformCluster(feature)); 639 } 640 transformCluster({ geometry: { coordinates: [lng, lat], }, properties, }) { 641 if (properties.cluster) { 642 return new Cluster({ 643 markers: this.superCluster 644 .getLeaves(properties.cluster_id, Infinity) 645 .map((leaf) => leaf.properties.marker), 646 position: { lat, lng }, 647 }); 648 } 649 const marker = properties.marker; 650 return new Cluster({ 651 markers: [marker], 652 position: MarkerUtils.getPosition(marker), 653 }); 654 } 655} 656 657/** 658 * Copyright 2021 Google LLC 659 * 660 * Licensed under the Apache License, Version 2.0 (the "License"); 661 * you may not use this file except in compliance with the License. 662 * You may obtain a copy of the License at 663 * 664 * http://www.apache.org/licenses/LICENSE-2.0 665 * 666 * Unless required by applicable law or agreed to in writing, software 667 * distributed under the License is distributed on an "AS IS" BASIS, 668 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 669 * See the License for the specific language governing permissions and 670 * limitations under the License. 671 */ 672/** 673 * Provides statistics on all clusters in the current render cycle for use in {@link Renderer.render}. 674 */ 675class ClusterStats { 676 constructor(markers, clusters) { 677 this.markers = { sum: markers.length }; 678 const clusterMarkerCounts = clusters.map((a) => a.count); 679 const clusterMarkerSum = clusterMarkerCounts.reduce((a, b) => a + b, 0); 680 this.clusters = { 681 count: clusters.length, 682 markers: { 683 mean: clusterMarkerSum / clusters.length, 684 sum: clusterMarkerSum, 685 min: Math.min(...clusterMarkerCounts), 686 max: Math.max(...clusterMarkerCounts), 687 }, 688 }; 689 } 690} 691class DefaultRenderer { 692 /** 693 * The default render function for the library used by {@link MarkerClusterer}. 694 * 695 * Currently set to use the following: 696 * 697 * ```typescript 698 * // change color if this cluster has more markers than the mean cluster 699 * const color = 700 * count > Math.max(10, stats.clusters.markers.mean) 701 * ? "#ff0000" 702 * : "#0000ff"; 703 * 704 * // create svg url with fill color 705 * const svg = window.btoa(` 706 * <svg fill="${color}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240"> 707 * <circle cx="120" cy="120" opacity=".6" r="70" /> 708 * <circle cx="120" cy="120" opacity=".3" r="90" /> 709 * <circle cx="120" cy="120" opacity=".2" r="110" /> 710 * <circle cx="120" cy="120" opacity=".1" r="130" /> 711 * </svg>`); 712 * 713 * // create marker using svg icon 714 * return new google.maps.Marker({ 715 * position, 716 * icon: { 717 * url: `data:image/svg+xml;base64,${svg}`, 718 * scaledSize: new google.maps.Size(45, 45), 719 * }, 720 * label: { 721 * text: String(count), 722 * color: "rgba(255,255,255,0.9)", 723 * fontSize: "12px", 724 * }, 725 * // adjust zIndex to be above other markers 726 * zIndex: 1000 + count, 727 * }); 728 * ``` 729 */ 730 render({ count, position }, stats, map) { 731 // change color if this cluster has more markers than the mean cluster 732 const color = count > Math.max(10, stats.clusters.markers.mean) ? "#ff0000" : "#0000ff"; 733 // create svg literal with fill color 734 const svg = `<svg fill="${color}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240" width="50" height="50"> 735<circle cx="120" cy="120" opacity=".6" r="70" /> 736<circle cx="120" cy="120" opacity=".3" r="90" /> 737<circle cx="120" cy="120" opacity=".2" r="110" /> 738<text x="50%" y="50%" style="fill:#fff" text-anchor="middle" font-size="50" dominant-baseline="middle" font-family="roboto,arial,sans-serif">${count}</text> 739</svg>`; 740 const title = `Cluster of ${count} markers`, 741 // adjust zIndex to be above other markers 742 zIndex = Number(google.maps.Marker.MAX_ZINDEX) + count; 743 if (MarkerUtils.isAdvancedMarkerAvailable(map)) { 744 // create cluster SVG element 745 const parser = new DOMParser(); 746 const svgEl = parser.parseFromString(svg, "image/svg+xml").documentElement; 747 svgEl.setAttribute("transform", "translate(0 25)"); 748 const clusterOptions = { 749 map, 750 position, 751 zIndex, 752 title, 753 content: svgEl, 754 }; 755 return new google.maps.marker.AdvancedMarkerElement(clusterOptions); 756 } 757 const clusterOptions = { 758 position, 759 zIndex, 760 title, 761 icon: { 762 url: `data:image/svg+xml;base64,${btoa(svg)}`, 763 anchor: new google.maps.Point(25, 25), 764 }, 765 }; 766 return new google.maps.Marker(clusterOptions); 767 } 768} 769 770/** 771 * Copyright 2019 Google LLC. All Rights Reserved. 772 * 773 * Licensed under the Apache License, Version 2.0 (the "License"); 774 * you may not use this file except in compliance with the License. 775 * You may obtain a copy of the License at 776 * 777 * http://www.apache.org/licenses/LICENSE-2.0 778 * 779 * Unless required by applicable law or agreed to in writing, software 780 * distributed under the License is distributed on an "AS IS" BASIS, 781 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 782 * See the License for the specific language governing permissions and 783 * limitations under the License. 784 */ 785/** 786 * Extends an object's prototype by another's. 787 * 788 * @param type1 The Type to be extended. 789 * @param type2 The Type to extend with. 790 * @ignore 791 */ 792// eslint-disable-next-line @typescript-eslint/no-explicit-any 793function extend(type1, type2) { 794 /* istanbul ignore next */ 795 // eslint-disable-next-line prefer-const 796 for (let property in type2.prototype) { 797 type1.prototype[property] = type2.prototype[property]; 798 } 799} 800/** 801 * @ignore 802 */ 803class OverlayViewSafe { 804 constructor() { 805 // MarkerClusterer implements google.maps.OverlayView interface. We use the 806 // extend function to extend MarkerClusterer with google.maps.OverlayView 807 // because it might not always be available when the code is defined so we 808 // look for it at the last possible moment. If it doesn't exist now then 809 // there is no point going ahead :) 810 extend(OverlayViewSafe, google.maps.OverlayView); 811 } 812} 813 814/** 815 * Copyright 2021 Google LLC 816 * 817 * Licensed under the Apache License, Version 2.0 (the "License"); 818 * you may not use this file except in compliance with the License. 819 * You may obtain a copy of the License at 820 * 821 * http://www.apache.org/licenses/LICENSE-2.0 822 * 823 * Unless required by applicable law or agreed to in writing, software 824 * distributed under the License is distributed on an "AS IS" BASIS, 825 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 826 * See the License for the specific language governing permissions and 827 * limitations under the License. 828 */ 829var MarkerClustererEvents; 830(function (MarkerClustererEvents) { 831 MarkerClustererEvents["CLUSTERING_BEGIN"] = "clusteringbegin"; 832 MarkerClustererEvents["CLUSTERING_END"] = "clusteringend"; 833 MarkerClustererEvents["CLUSTER_CLICK"] = "click"; 834})(MarkerClustererEvents || (MarkerClustererEvents = {})); 835const defaultOnClusterClickHandler = (_, cluster, map) => { 836 map.fitBounds(cluster.bounds); 837}; 838/** 839 * MarkerClusterer creates and manages per-zoom-level clusters for large amounts 840 * of markers. See {@link MarkerClustererOptions} for more details. 841 * 842 */ 843class MarkerClusterer extends OverlayViewSafe { 844 constructor({ map, markers = [], algorithmOptions = {}, algorithm = new SuperClusterAlgorithm(algorithmOptions), renderer = new DefaultRenderer(), onClusterClick = defaultOnClusterClickHandler, }) { 845 super(); 846 this.markers = [...markers]; 847 this.clusters = []; 848 this.algorithm = algorithm; 849 this.renderer = renderer; 850 this.onClusterClick = onClusterClick; 851 if (map) { 852 this.setMap(map); 853 } 854 } 855 addMarker(marker, noDraw) { 856 if (this.markers.includes(marker)) { 857 return; 858 } 859 this.markers.push(marker); 860 if (!noDraw) { 861 this.render(); 862 } 863 } 864 addMarkers(markers, noDraw) { 865 markers.forEach((marker) => { 866 this.addMarker(marker, true); 867 }); 868 if (!noDraw) { 869 this.render(); 870 } 871 } 872 removeMarker(marker, noDraw) { 873 const index = this.markers.indexOf(marker); 874 if (index === -1) { 875 // Marker is not in our list of markers, so do nothing: 876 return false; 877 } 878 MarkerUtils.setMap(marker, null); 879 this.markers.splice(index, 1); // Remove the marker from the list of managed markers 880 if (!noDraw) { 881 this.render(); 882 } 883 return true; 884 } 885 removeMarkers(markers, noDraw) { 886 let removed = false; 887 markers.forEach((marker) => { 888 removed = this.removeMarker(marker, true) || removed; 889 }); 890 if (removed && !noDraw) { 891 this.render(); 892 } 893 return removed; 894 } 895 clearMarkers(noDraw) { 896 this.markers.length = 0; 897 if (!noDraw) { 898 this.render(); 899 } 900 } 901 /** 902 * Recalculates and draws all the marker clusters. 903 */ 904 render() { 905 const map = this.getMap(); 906 if (map instanceof google.maps.Map && map.getProjection()) { 907 google.maps.event.trigger(this, MarkerClustererEvents.CLUSTERING_BEGIN, this); 908 const { clusters, changed } = this.algorithm.calculate({ 909 markers: this.markers, 910 map, 911 mapCanvasProjection: this.getProjection(), 912 }); 913 // Allow algorithms to return flag on whether the clusters/markers have changed. 914 if (changed || changed == undefined) { 915 // Accumulate the markers of the clusters composed of a single marker. 916 // Those clusters directly use the marker. 917 // Clusters with more than one markers use a group marker generated by a renderer. 918 const singleMarker = new Set(); 919 for (const cluster of clusters) { 920 if (cluster.markers.length == 1) { 921 singleMarker.add(cluster.markers[0]); 922 } 923 } 924 const groupMarkers = []; 925 // Iterate the clusters that are currently rendered. 926 for (const cluster of this.clusters) { 927 if (cluster.marker == null) { 928 continue; 929 } 930 if (cluster.markers.length == 1) { 931 if (!singleMarker.has(cluster.marker)) { 932 // The marker: 933 // - was previously rendered because it is from a cluster with 1 marker, 934 // - should no more be rendered as it is not in singleMarker. 935 MarkerUtils.setMap(cluster.marker, null); 936 } 937 } 938 else { 939 // Delay the removal of old group markers to avoid flickering. 940 groupMarkers.push(cluster.marker); 941 } 942 } 943 this.clusters = clusters; 944 this.renderClusters(); 945 // Delayed removal of the markers of the former groups. 946 requestAnimationFrame(() => groupMarkers.forEach((marker) => MarkerUtils.setMap(marker, null))); 947 } 948 google.maps.event.trigger(this, MarkerClustererEvents.CLUSTERING_END, this); 949 } 950 } 951 onAdd() { 952 this.idleListener = this.getMap().addListener("idle", this.render.bind(this)); 953 this.render(); 954 } 955 onRemove() { 956 google.maps.event.removeListener(this.idleListener); 957 this.reset(); 958 } 959 reset() { 960 this.markers.forEach((marker) => MarkerUtils.setMap(marker, null)); 961 this.clusters.forEach((cluster) => cluster.delete()); 962 this.clusters = []; 963 } 964 renderClusters() { 965 // Generate stats to pass to renderers. 966 const stats = new ClusterStats(this.markers, this.clusters); 967 const map = this.getMap(); 968 this.clusters.forEach((cluster) => { 969 if (cluster.markers.length === 1) { 970 cluster.marker = cluster.markers[0]; 971 } 972 else { 973 // Generate the marker to represent the group. 974 cluster.marker = this.renderer.render(cluster, stats, map); 975 // Make sure all individual markers are removed from the map. 976 cluster.markers.forEach((marker) => MarkerUtils.setMap(marker, null)); 977 if (this.onClusterClick) { 978 cluster.marker.addListener("click", 979 /* istanbul ignore next */ 980 (event) => { 981 google.maps.event.trigger(this, MarkerClustererEvents.CLUSTER_CLICK, cluster); 982 this.onClusterClick(event, cluster, map); 983 }); 984 } 985 } 986 MarkerUtils.setMap(cluster.marker, map); 987 }); 988 } 989} 990 991 992//# sourceMappingURL=index.esm.js.map 993 994 995/***/ }), 996
997/***/ "./js/functions/BottomSheet.js": 998/*!*************************************!*\ 999 !*** ./js/functions/BottomSheet.js ***! 1000 \*************************************/ 1001/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1002 1003"use strict"; 1004__webpack_require__.r(__webpack_exports__); 1005/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1006/* harmony export */ "default": () => (/* binding */ BottomSheet) 1007/* harmony export */ }); 1008/* harmony import */ var _mapUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mapUtils */ "./js/functions/mapUtils.js"); 1009/* harmony import */ var _plugins__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../plugins */ "./js/plugins.js"); 1010function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 1011function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } 1012function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } 1013function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } 1014function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } 1015function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } 1016// Inspiré de ce dépôt GitHub : https://github.com/ivteplo/bottom-sheet 1017 1018 1019function getBrowserMaxHeight() { 1020 var mapHeaderMobile = document.querySelector('.js-map-header-mobile'); 1021 var mapHeaderMobileHeight = mapHeaderMobile.offsetHeight; 1022 var maxBrowserHeight = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0); 1023 return maxBrowserHeight - mapHeaderMobileHeight; 1024} 1025function touchPosition(event) { 1026 return event.touches ? event.touches[0] : event; 1027} 1028var BottomSheet = /*#__PURE__*/function () { 1029 function BottomSheet() { 1030 _classCallCheck(this, BottomSheet); 1031 } 1032 return _createClass(BottomSheet, [{ 1033 key: "init", 1034 value: function init() { 1035 this.sheetContents = document.querySelector('.js-map-sidebar'); 1036 this.draggableArea = document.querySelector('.js-map-sidebar-button-draggable'); 1037 this.sheetSlideDownHeight = 70; // in px 1038 this.sheetHeight = this.sheetSlideDownHeight; 1039 this.dragPosition = undefined; 1040 this.isOpen = false; 1041 if (!(0,_mapUtils__WEBPACK_IMPORTED_MODULE_0__.isTouchDevice)()) { 1042 document.querySelector('.js-map-sidebar-button-draggable'); 1043 _plugins__WEBPACK_IMPORTED_MODULE_1__.OBSERVER.add({ 1044 name: 'BottomSheet', 1045 events: 'click', 1046 targets: '.js-map-sidebar-button-draggable', 1047 "function": this.onClick.bind(this) 1048 }); 1049 } else { 1050 _plugins__WEBPACK_IMPORTED_MODULE_1__.OBSERVER.add({ 1051 name: 'BottomSheet', 1052 events: 'mousedown touchstart', 1053 targets: '.js-map-sidebar, .js-map-sidebar-button-draggable', 1054 "function": this.onDragStart.bind(this) 1055 }); 1056 _plugins__WEBPACK_IMPORTED_MODULE_1__.OBSERVER.add({ 1057 name: 'BottomSheet', 1058 events: 'mousemove touchmove', 1059 targets: 'window', 1060 "function": this.onDragMove.bind(this) 1061 }); 1062 _plugins__WEBPACK_IMPORTED_MODULE_1__.OBSERVER.add({ 1063 name: 'BottomSheet', 1064 events: 'mouseup touchend', 1065 targets: 'window', 1066 "function": this.onDragEnd.bind(this) 1067 }); 1068 } 1069 _plugins__WEBPACK_IMPORTED_MODULE_1__.OBSERVER.add({ 1070 name: 'BottomSheet', 1071 events: 'click', 1072 targets: '.js-open-map-sidebar', 1073 "function": this.onClick.bind(this) 1074 }); 1075 _plugins__WEBPACK_IMPORTED_MODULE_1__.OBSERVER.add({ 1076 name: 'BottomSheet', 1077 events: 'click', 1078 targets: '.js-close-map-sidebar', 1079 "function": this.closeSheet.bind(this) 1080 }); 1081 _plugins__WEBPACK_IMPORTED_MODULE_1__.OBSERVER.on('BottomSheet'); 1082 } 1083 }, { 1084 key: "setSheetHeight", 1085 value: function setSheetHeight(value) { 1086 this.sheetHeight = value; 1087 this.sheetContents.style.height = "".concat(value, "px"); 1088 if (this.sheetHeight === getBrowserMaxHeight()) { 1089 this.sheetContents.classList.add('is-fullscreen'); 1090 } else { 1091 this.sheetContents.classList.remove('is-fullscreen'); 1092 } 1093 if (this.sheetHeight === getBrowserMaxHeight()) { 1094 this.isOpen = true; 1095 } else if (this.sheetHeight === this.sheetSlideDownHeight) { 1096 this.isOpen = false;
1097 } 1098 } 1099 }, { 1100 key: "openSheet", 1101 value: function openSheet(value) { 1102 this.setSheetHeight(value); 1103 } 1104 }, { 1105 key: "openSheetMaxHeight", 1106 value: function openSheetMaxHeight() { 1107 this.setSheetHeight(getBrowserMaxHeight()); 1108 } 1109 }, { 1110 key: "closeSheet", 1111 value: function closeSheet() { 1112 this.setSheetHeight(this.sheetSlideDownHeight); 1113 } 1114 }, { 1115 key: "onClick", 1116 value: function onClick() { 1117 if (this.isOpen) { 1118 this.closeSheet(); 1119 } else { 1120 this.openSheet(getBrowserMaxHeight()); 1121 } 1122 } 1123 }, { 1124 key: "onDragStart", 1125 value: function onDragStart(event) { 1126 // Si le drag est sur la zone de contenu au lieu du bouton déplaçable. 1127 if (event.currentTarget === this.sheetContents) { 1128 var viewActive = document.querySelector('[data-panel-active]'); 1129 1130 // Si l'événement drag est pour scroller le contenu, alors on ne déplace pas le bottom sheet. 1131 if (viewActive.scrollTop !== 0) { 1132 return; 1133 } 1134 } 1135 this.dragPosition = touchPosition(event).pageY; 1136 this.sheetContents.classList.add('dragging'); 1137 if ((0,_mapUtils__WEBPACK_IMPORTED_MODULE_0__.isTouchDevice)()) { 1138 this.draggableArea.style.cursor = 'grabbing'; 1139 document.body.style.cursor = 'grabbing'; 1140 } 1141 } 1142 }, { 1143 key: "onDragMove", 1144 value: function onDragMove(event) { 1145 if (this.dragPosition === undefined) { 1146 return; 1147 } 1148 var y = touchPosition(event).pageY; 1149 var deltaY = this.dragPosition - y; 1150 var browserMaxHeight = getBrowserMaxHeight(); 1151 var currentHeight = parseFloat(this.sheetHeight); 1152 var newHeight = currentHeight + deltaY; 1153 if (newHeight >= this.sheetSlideDownHeight && newHeight <= browserMaxHeight) { 1154 this.openSheet(newHeight); 1155 this.dragPosition = y; 1156 } 1157 } 1158 }, { 1159 key: "onDragEnd", 1160 value: function onDragEnd() { 1161 this.dragPosition = undefined; 1162 this.sheetContents.classList.remove('dragging'); 1163 this.draggableArea.style.cursor = ''; 1164 document.body.style.cursor = ''; 1165 var browserMaxHeight = getBrowserMaxHeight(); 1166 var threshold = 50; // Seuil en pixel quand on glisse le panneau pour l'ouvrir/fermer 1167 1168 if (this.isOpen) { 1169 if (this.sheetHeight > browserMaxHeight - threshold) { 1170 this.openSheet(browserMaxHeight); 1171 } else { 1172 this.closeSheet(); 1173 } 1174 } else if (this.sheetHeight > this.sheetSlideDownHeight + threshold) { 1175 this.openSheet(browserMaxHeight); 1176 } else { 1177 this.closeSheet(); 1178 } 1179 } 1180 }]); 1181}(); 1182 1183 1184/***/ }), 1185
1186/***/ "./js/functions/MapUi.js": 1187/*!*******************************!*\ 1188 !*** ./js/functions/MapUi.js ***! 1189 \*******************************/ 1190/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1191 1192"use strict"; 1193__webpack_require__.r(__webpack_exports__); 1194/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1195/* harmony export */ "default": () => (/* binding */ MapUi) 1196/* harmony export */ }); 1197/* harmony import */ var _mapUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mapUtils */ "./js/functions/mapUtils.js"); 1198function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 1199function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } 1200function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } 1201function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } 1202function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } 1203function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } 1204 1205 1206/** 1207 * Cette classe gère l'interactivité des boutons pour contrôler la carte Google Maps. 1208 */ 1209var MapUi = /*#__PURE__*/function () { 1210 /** 1211 * Constructeur de la classe MapUi. 1212 * @constructor 1213 */ 1214 function MapUi() { 1215 _classCallCheck(this, MapUi); 1216 this.map = null; 1217 } 1218 1219 /** 1220 * Gérer le clic sur le bouton quitter. 1221 */ 1222 return _createClass(MapUi, [{ 1223 key: "initQuitButton", 1224 value: function initQuitButton() { 1225 var quitMapInfo = {}; 1226 quitMapInfo.host = window.location.host; 1227 quitMapInfo.href = window.location.href; 1228 quitMapInfo.referrer = document.referrer; 1229 window.quitMapInfo = quitMapInfo; 1230 var buttonsBackTopPreviousPage = document.querySelectorAll('.js-quit-map'); 1231 buttonsBackTopPreviousPage.forEach(function (bouton) { 1232 bouton.addEventListener('click', function () { 1233 if (window.quitMapInfo.host === window.quitMapInfo.referrer.split('/')[2]) { 1234 window.location.href = window.quitMapInfo.referrer; 1235 } else { 1236 // On vient d'un autre site, donc on se dirige vers l'accueil. 1237 window.location.href = '/'; 1238 } 1239 }); 1240 }); 1241 } 1242 1243 /** 1244 * Gérer le clic sur les boutons de zoom et de dézoom. 1245 */ 1246 }, { 1247 key: "initZoomButtons", 1248 value: function initZoomButtons() { 1249 var _this = this; 1250 var zoomButtonIn = document.querySelector('.js-zoom-button[data-zoom="in"]'); 1251 var zoomButtonOut = document.querySelector('.js-zoom-button[data-zoom="out"]'); 1252 zoomButtonIn.addEventListener('click', function () { 1253 var CURRENT_ZOOM = _this.map.getZoom(); 1254 _this.map.setZoom(CURRENT_ZOOM + 1); 1255 }); 1256 zoomButtonOut.addEventListener('click', function () { 1257 var CURRENT_ZOOM = _this.map.getZoom(); 1258 _this.map.setZoom(CURRENT_ZOOM - 1); 1259 }); 1260 } 1261 1262 /** 1263 * Gérer le bouton type de carte. 1264 */ 1265 }, { 1266 key: "initLayersButton", 1267 value: function initLayersButton() { 1268 var _this2 = this; 1269 // Définir la largeur du popup quand il est ouvert pour l'animation. 1270 var layersInner = document.querySelector('.js-layers-popup'); 1271 layersInner.style.width = "".concat(layersInner.offsetWidth, "px"); 1272 1273 // Gérer les clics des boutons des types de cartes. 1274 var buttons = document.querySelectorAll('.js-layers-button'); 1275 buttons.forEach(function (button) { 1276 button.addEventListener('click', function (e) { 1277 _this2.map.setMapTypeId(e.currentTarget.dataset.layer); 1278 1279 // Enlever la classe active àtous les boutons. 1280 buttons.forEach(function (item) { 1281 item.classList.remove('active'); 1282 }); 1283 // Ajouter la classe active àl'item cliqué. 1284 e.currentTarget.classList.add('active'); 1285 // Ajouter le cookie pour se souvenir du type de carte sélectionné. 1286 localStorage.setItem('active-layer', e.currentTarget.dataset.layer); 1287 }); 1288 }); 1289 1290 // En mobile, le hover du bouton ne fonctionne pas, donc on ajoute un événement clic. 1291 if (_mapUtils__WEBPACK_IMPORTED_MODULE_0__.isTouchDevice) { 1292 document.querySelector('.js-layers-popup-button').addEventListener('click', function (e) { 1293 e.currentTarget.parentElement.parentElement.classList.toggle('open'); 1294 }); 1295 } 1296 1297 // Gérer le cookie pour savoir quel est le type de carte active. 1298 if (localStorage.getItem('active-layer')) { 1299 document.querySelector(".js-layers-button[data-layer=\"".concat(localStorage.getItem('active-layer'), "\"]")).classList.add('active'); 1300 this.map.setMapTypeId(localStorage.getItem('active-layer')); 1301 } else { 1302 localStorage.setItem('active-layer', 'roadmap'); 1303 document.querySelector('.js-layers-button[data-layer="roadmap"]').classList.add('active'); 1304 } 1305 } 1306 1307 /** 1308 * Gérer le clic sur le bouton informations. 1309 */ 1310 }, { 1311 key: "initInfoPopup", 1312 value: function initInfoPopup() { 1313 if (document.querySelector('.js-info-button') !== null) { 1314 // Définir la hauteur du popup quand il est ouvert pour l'animation. 1315 var infoInner = document.querySelector('.js-info-inner-content'); 1316 infoInner.parentElement.style.height = "".concat(infoInner.offsetHeight, "px"); 1317 1318 // Clic sur le bouton pour ouvrir le popup. 1319 var infoButton = document.querySelector('.js-info-button'); 1320 infoButton.addEventListener('click', function (e) { 1321 e.currentTarget.parentElement.classList.remove('c-map-info-popup--collapsed'); 1322 localStorage.setItem('collapsed-infos', 'false'); 1323 }); 1324 1325 // Clic sur le bouton pour fermer le popup. 1326 var closeInfoButton = document.querySelector('.js-close-info-button'); 1327 closeInfoButton.addEventListener('click', function (e) { 1328 e.currentTarget.parentElement.parentElement.classList.add('c-map-info-popup--collapsed'); 1329 localStorage.setItem('collapsed-infos', 'true'); 1330 }); 1331 1332 // Gérer le cookie pour savoir si le popup est ouvert. 1333 if (localStorage.getItem('collapsed-infos')) { 1334 if (localStorage.getItem('collapsed-infos') === 'false') { 1335 document.querySelector('.js-info-button').parentElement.classList.remove('c-map-info-popup--collapsed'); 1336 } 1337 } else { 1338 localStorage.setItem('collapsed-infos', 'false'); 1339 document.querySelector('.js-info-button').parentElement.classList.remove('c-map-info-popup--collapsed'); 1340 } 1341 } 1342 } 1343 1344 /** 1345 * Vérifie la présence de l'overlay de partage. 1346 */ 1347 }, { 1348 key: "checkShareOverlay", 1349 value: function checkShareOverlay() { 1350 setTimeout(function () { 1351 if (typeof window.overlayShare === 'undefined') { 1352 console.warn('CARTE INTERACTIVE -> Le thème doit rendre disponible un overlay \'overlayShare\' dans le window pour assurer le fonctionnement de la fonction partage.'); 1353 } 1354 }, 500); 1355 } 1356 1357 /** 1358 * Initialiser les fonctionnalités de l'interface utilisateur de la carte. 1359 * @param {google.maps.Map} map - La carte Google Maps. 1360 */ 1361 }, { 1362 key: "init", 1363 value: function init(map) { 1364 this.map = map; 1365 this.initQuitButton(); 1366 this.initZoomButtons(); 1367 this.initLayersButton(); 1368 this.initInfoPopup(); 1369 this.checkShareOverlay(); 1370 } 1371 }]); 1372}(); 1373 1374 1375/***/ }), 1376
1377/***/ "./js/functions/hundredVH.js": 1378/*!***********************************!*\ 1379 !*** ./js/functions/hundredVH.js ***! 1380 \***********************************/ 1381/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1382 1383"use strict"; 1384__webpack_require__.r(__webpack_exports__); 1385/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1386/* harmony export */ "default": () => (/* binding */ hundredVH) 1387/* harmony export */ }); 1388/* harmony import */ var _plugins__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../plugins */ "./js/plugins.js"); 1389 1390 1391// Permet de donner la hauteur exacte en mobile de 100vh 1392// Css -> height: calc(var(--vh, 1vh) * 100); 1393function hundredVH() { 1394 function setHeight() { 1395 var vh = window.innerHeight * 0.01; 1396 document.documentElement.style.setProperty('--vh-map', "".concat(vh, "px")); 1397 } 1398 _plugins__WEBPACK_IMPORTED_MODULE_0__.OBSERVER.add({ 1399 name: 'hundredVH', 1400 events: 'resize load', 1401 targets: 'window', 1402 "function": setHeight 1403 }); 1404 _plugins__WEBPACK_IMPORTED_MODULE_0__.OBSERVER.on('hundredVH'); 1405} 1406 1407/***/ }), 1408
1409/***/ "./js/functions/map.js": 1410/*!*****************************!*\ 1411 !*** ./js/functions/map.js ***! 1412 \*****************************/ 1413/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1414 1415"use strict"; 1416__webpack_require__.r(__webpack_exports__); 1417/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1418/* harmony export */ bottomSheet: () => (/* binding */ bottomSheet), 1419/* harmony export */ "default": () => (/* binding */ googleMap), 1420/* harmony export */ mapUi: () => (/* binding */ mapUi), 1421/* harmony export */ urlManager: () => (/* binding */ urlManager) 1422/* harmony export */ }); 1423/* harmony import */ var _googlemaps_markerclusterer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @googlemaps/markerclusterer */ "./node_modules/@googlemaps/markerclusterer/dist/index.esm.js"); 1424/* harmony import */ var _mapMarker__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mapMarker */ "./js/functions/mapMarker.js"); 1425/* harmony import */ var _mapLocationMarker__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./mapLocationMarker */ "./js/functions/mapLocationMarker.js"); 1426/* harmony import */ var _mapMarkerCluster__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mapMarkerCluster */ "./js/functions/mapMarkerCluster.js"); 1427/* harmony import */ var _mapManager__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./mapManager */ "./js/functions/mapManager.js"); 1428/* harmony import */ var _mapUtils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./mapUtils */ "./js/functions/mapUtils.js"); 1429/* harmony import */ var _mapPanels__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./mapPanels */ "./js/functions/mapPanels.js"); 1430/* harmony import */ var _mapStyle__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./mapStyle */ "./js/functions/mapStyle.js"); 1431/* harmony import */ var _mapUrl__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./mapUrl */ "./js/functions/mapUrl.js"); 1432/* harmony import */ var _BottomSheet__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./BottomSheet */ "./js/functions/BottomSheet.js"); 1433/* harmony import */ var _MapUi__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./MapUi */ "./js/functions/MapUi.js"); 1434/* harmony import */ var _hundredVH__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./hundredVH */ "./js/functions/hundredVH.js"); 1435// --------------------------------------------------- 1436// Fonctions reliées àla carte 1437// --------------------------------------------------- 1438 1439// Importation --------------------------------------- 1440 1441 1442 1443 1444 1445 1446 1447 // Récupère le style de la carte 1448 1449 1450 1451 1452window.changeCategory = _mapManager__WEBPACK_IMPORTED_MODULE_4__.changeCategory; 1453window.changeSubcategory = _mapManager__WEBPACK_IMPORTED_MODULE_4__.changeSubcategory; 1454window.selectLocation = _mapManager__WEBPACK_IMPORTED_MODULE_4__.selectLocation; 1455window.returnToRoot = _mapManager__WEBPACK_IMPORTED_MODULE_4__.returnToRoot; 1456window.returnToSubcategories = _mapManager__WEBPACK_IMPORTED_MODULE_4__.returnToSubcategories; 1457window.returnFromLocationDetail = _mapManager__WEBPACK_IMPORTED_MODULE_4__.returnFromLocationDetail; 1458window.locationClick = _mapManager__WEBPACK_IMPORTED_MODULE_4__.locationClick; 1459window.popupClick = _mapManager__WEBPACK_IMPORTED_MODULE_4__.popupClick; 1460window.closePopupClick = _mapManager__WEBPACK_IMPORTED_MODULE_4__.closePopupClick; 1461window.isClosing = false; 1462 1463/* global google */ 1464 1465var map = null; 1466var urlManager = new _mapUrl__WEBPACK_IMPORTED_MODULE_8__["default"](); 1467var bottomSheet = new _BottomSheet__WEBPACK_IMPORTED_MODULE_9__["default"](); 1468var mapUi = new _MapUi__WEBPACK_IMPORTED_MODULE_10__["default"](); 1469var mapBounds = { 1470 // Zone dans laquelle on pourra glisser dans la carte 1471 north: window.mapConfig.center_lat + window.mapConfig.bounds_limit / 2, 1472 south: window.mapConfig.center_lat - window.mapConfig.bounds_limit / 2, 1473 west: window.mapConfig.center_lng - window.mapConfig.bounds_limit, 1474 east: window.mapConfig.center_lng + window.mapConfig.bounds_limit 1475}; 1476 1477/** 1478 * Faire afficher la carte. 1479 */ 1480function initMap() { 1481 map = new google.maps.Map(document.querySelector('.js-map-container'), { 1482 zoom: 15, 1483 center: { 1484 lat: window.mapConfig.center_lat, 1485 lng: window.mapConfig.center_lng 1486 }, 1487 clickableIcons: false, 1488 styles: _mapStyle__WEBPACK_IMPORTED_MODULE_7__["default"], 1489 disableDefaultUI: true, 1490 gestureHandling: 'greedy', 1491 minZoom: window.mapConfig.zoom_min, 1492 maxZoom: window.mapConfig.zoom_max, 1493 restriction: { 1494 latLngBounds: mapBounds,
1495 strictBounds: false 1496 } 1497 }); 1498 window.markerClusterer = new _googlemaps_markerclusterer__WEBPACK_IMPORTED_MODULE_0__.MarkerClusterer({ 1499 map: map, 1500 undefined: undefined, 1501 renderer: { 1502 render: function render(_ref) { 1503 var count = _ref.count, 1504 position = _ref.position, 1505 bounds = _ref.bounds; 1506 return new _mapMarkerCluster__WEBPACK_IMPORTED_MODULE_3__["default"]({ 1507 latlng: position, 1508 map: map, 1509 count: count, 1510 bounds: bounds 1511 }); 1512 } 1513 } 1514 }); 1515 1516 // Initialisation des marqueurs suite au chargement de Google Maps. 1517 urlManager.init(); 1518 (0,_mapMarker__WEBPACK_IMPORTED_MODULE_1__.initMarker)(); 1519} 1520 1521/** 1522 * Met àjour les marqueurs de la carte en utilisant les données fournies. 1523 * @param {object} data - Les données des POIs. 1524 */ 1525function updateMarkers(data) { 1526 var pois = data.pois; 1527 pois.forEach(function (poi) { 1528 var markerPos = poi.position; 1529 var htmlMarker = new _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker({ 1530 map: map, 1531 lat: markerPos.lat, 1532 lng: markerPos.lng, 1533 id: poi.id, 1534 slug: poi.slug, 1535 kmlUrl: poi.kml, 1536 categoriesSlug: poi.categoriesSlug, 1537 accessibility: poi.accessibility, 1538 title: poi.title, 1539 category: poi.category, 1540 image: poi.image 1541 }); 1542 }); 1543} 1544function loadMarkers() { 1545 if (!map) return; 1546 1547 // Créer une nouvelle instance de l'objet XMLHttpRequest. 1548 var xhr = new XMLHttpRequest(); 1549 1550 // Configurer la requête avec la méthode HTTP et l'URL. 1551 xhr.open('GET', '/api/v1/pois', true); 1552 1553 // Définir la fonction àexécuter lors de la réception de la réponse. 1554 xhr.onload = function onLoad() { 1555 if (xhr.status >= 200 && xhr.status < 400) { 1556 // La requête a réussi. 1557 updateMarkers(JSON.parse(xhr.responseText).data); 1558 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.showAll(); 1559 1560 // S'il y a quelque chose dans l'URL, charger sur la carte les bonnes puces. 1561 // Afficher les puces de la catégorie active. 1562 if (urlManager.getSlugCategory() && !urlManager.getSlugSubcategory() && !urlManager.getSlugLocalisation()) { 1563 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.showCategory(urlManager.getSlugCategory()); 1564 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_6__.enableResetButtons)(); 1565 } 1566 // Afficher les puces de la sous-catégorie active. 1567 if (urlManager.getSlugSubcategory() && !urlManager.getSlugLocalisation()) { 1568 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.showCategory(urlManager.getSlugSubcategory()); 1569 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_6__.enableResetButtons)(); 1570 } 1571 // Afficher la localisation. 1572 if (urlManager.getSlugLocalisation()) { 1573 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.showUnique(urlManager.getSlugLocalisation()); 1574 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_6__.enableResetButtons)(); 1575 } 1576 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.refreshClusterer(); 1577 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.fitBounds(); 1578 } else { 1579 // Il y a eu une erreur. 1580 console.error("Erreur: ".concat(xhr.status, "!")); 1581 } 1582 }; 1583 xhr.send(); 1584} 1585function googleMap() { 1586 if (document.querySelector('.js-map-container')) { 1587 (0,_hundredVH__WEBPACK_IMPORTED_MODULE_11__["default"])(); 1588 initMap(); 1589 loadMarkers(); 1590 bottomSheet.init(); 1591 mapUi.init(map); 1592 (0,_mapManager__WEBPACK_IMPORTED_MODULE_4__.manageBackButton)(); 1593 1594 // S'il y a une localisation d'active, monter le panneau mobile. 1595 if (urlManager.slugLocalisation) { 1596 bottomSheet.openSheetMaxHeight(); 1597 } 1598 if ((0,_mapUtils__WEBPACK_IMPORTED_MODULE_5__.hasGeolocation)()) { 1599 navigator.geolocation.getCurrentPosition(function (position) { 1600 var lat = position.coords.latitude; 1601 var lng = position.coords.longitude; 1602 var centerBtnContainer = document.querySelector('.js-center-on-location-container'); 1603 var centerBtn = document.querySelector('.js-center-on-location'); 1604 if ((0,_mapUtils__WEBPACK_IMPORTED_MODULE_5__.isInZone)(lat, lng, mapBounds)) { 1605 centerBtnContainer.classList.remove('is-hidden'); 1606 centerBtn.disabled = false;
1607 (0,_mapLocationMarker__WEBPACK_IMPORTED_MODULE_2__.initLocationMarker)(); 1608 var htmlLocationMarker = new _mapLocationMarker__WEBPACK_IMPORTED_MODULE_2__.HTMLLocationMarker({ 1609 map: map, 1610 lat: lat, 1611 lng: lng 1612 }); 1613 if (document.querySelector('.js-center-on-location')) { 1614 centerBtn.addEventListener('click', function () { 1615 map.setZoom(17); 1616 map.panTo(new google.maps.LatLng(lat, lng)); 1617 }); 1618 } 1619 } 1620 }); 1621 } 1622 } 1623} 1624 1625/***/ }), 1626
1627/***/ "./js/functions/mapLocationMarker.js": 1628/*!*******************************************!*\ 1629 !*** ./js/functions/mapLocationMarker.js ***! 1630 \*******************************************/ 1631/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1632 1633"use strict"; 1634__webpack_require__.r(__webpack_exports__); 1635/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1636/* harmony export */ HTMLLocationMarker: () => (/* binding */ HTMLLocationMarker), 1637/* harmony export */ initLocationMarker: () => (/* binding */ initLocationMarker) 1638/* harmony export */ }); 1639/* 1640Cette classe gère les marqueurs, on utilise les prototypes àcause d’incompatibilités avec Google Map 1641*/ 1642 1643/* global google */ 1644 1645// definir une variable pour recevoir la future définition de marqueur 1646var HTMLLocationMarker; 1647 1648// initMarker est appelé lorsque googlemap est chargé 1649function initLocationMarker() { 1650 // lorsque GoogleMap est chargé on declare un objet et ses prototypes 1651 HTMLLocationMarker = function htmlLocationMarker(args) { 1652 var _this = this; 1653 this.map = args.map; 1654 this.lat = args.lat; 1655 this.lng = args.lng; 1656 this.pos = new google.maps.LatLng(args.lat, args.lng); 1657 HTMLLocationMarker.map = args.map; 1658 if (this.lat != null && this.lng != null) { 1659 var div = document.createElement('div'); 1660 div.classList.add('c-map-location-pin'); 1661 div.setAttribute('title', window.mapConfig.geolocation_label); 1662 div.innerHTML = this.render(); 1663 this.div = div; 1664 } 1665 this.setMap(this.map); 1666 1667 // si on clique sur la pin, center la carte sur l'emplacement 1668 google.maps.event.addDomListener(this.div, 'click', function () { 1669 _this.map.panTo(_this.pos); 1670 }); 1671 }; 1672 HTMLLocationMarker.prototype = new google.maps.OverlayView(); 1673 1674 // Init your html element here 1675 HTMLLocationMarker.prototype.onAdd = function onAdd() { 1676 var panes = this.getPanes(); 1677 // Si pas de latitude et de longitude, c’est uniquement un KML, on skip l’affichage 1678 if (this.lat == null || this.lng == null) { 1679 return; 1680 } 1681 panes.overlayImage.appendChild(this.div); 1682 }; 1683 1684 /** 1685 * Supprime le marqueur. 1686 * @memberof HTMLLocationMarker.prototype 1687 */ 1688 HTMLLocationMarker.prototype.remove = function remove() { 1689 if (this.div) { 1690 this.div.parentNode.removeChild(this.div); 1691 this.div = null; 1692 } 1693 }; 1694 1695 /** 1696 * Rendre le contenu HTML du marqueur en fonction de ses propriétés. 1697 * @memberof HTMLLocationMarker.prototype 1698 * @returns {string} - Le contenu HTML du marqueur. 1699 */ 1700 HTMLLocationMarker.prototype.render = function render() { 1701 return "\n <span class=\"c-map-location-pin__bullet\"></span>\n "; 1702 }; 1703 HTMLLocationMarker.prototype.draw = function draw() { 1704 var overlayProjection = this.getProjection(); 1705 var position = overlayProjection.fromLatLngToDivPixel(this.pos); 1706 this.div.style.left = "".concat(position.x, "px"); 1707 this.div.style.top = "".concat(position.y, "px"); 1708 }; 1709 1710 // Methode appelée automatiquement si on setMap(null) l’objet, voir doc Google 1711 HTMLLocationMarker.prototype.onRemove = function onRemove() { 1712 if (this.div) { 1713 this.div.remove(); 1714 } 1715 return false; 1716 }; 1717 1718 /* ******************************* 1719 PROPRIÉTÉS ET METHODES STATICS 1720 ****************************** */ 1721 HTMLLocationMarker.map = null; 1722 window.HTMLLocationMarker = HTMLLocationMarker; 1723} 1724 1725/***/ }), 1726
1727/***/ "./js/functions/mapManager.js": 1728/*!************************************!*\ 1729 !*** ./js/functions/mapManager.js ***! 1730 \************************************/ 1731/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1732 1733"use strict"; 1734__webpack_require__.r(__webpack_exports__); 1735/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1736/* harmony export */ changeCategory: () => (/* binding */ changeCategory), 1737/* harmony export */ changeSubcategory: () => (/* binding */ changeSubcategory), 1738/* harmony export */ closePopupClick: () => (/* binding */ closePopupClick), 1739/* harmony export */ locationClick: () => (/* binding */ locationClick), 1740/* harmony export */ manageBackButton: () => (/* binding */ manageBackButton), 1741/* harmony export */ popupClick: () => (/* binding */ popupClick), 1742/* harmony export */ returnFromLocationDetail: () => (/* binding */ returnFromLocationDetail), 1743/* harmony export */ returnToRoot: () => (/* binding */ returnToRoot), 1744/* harmony export */ returnToSubcategories: () => (/* binding */ returnToSubcategories), 1745/* harmony export */ selectLocation: () => (/* binding */ selectLocation) 1746/* harmony export */ }); 1747/* harmony import */ var _mapPanels__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mapPanels */ "./js/functions/mapPanels.js"); 1748/* harmony import */ var _mapMarker__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mapMarker */ "./js/functions/mapMarker.js"); 1749/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./map */ "./js/functions/map.js"); 1750/* harmony import */ var _mapUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mapUtils */ "./js/functions/mapUtils.js"); 1751 1752 1753 1754 1755 1756/** 1757 * Changer la catégorie active. 1758 * @param {string} slug - Le slug de la catégorie. 1759 */ 1760function changeCategory(slug) { 1761 _map__WEBPACK_IMPORTED_MODULE_2__.urlManager.setSlugCategory(slug); 1762 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.showCategory(slug); 1763 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.fitBounds(); 1764 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_0__.activatePanelView)('subcategories'); 1765 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_0__.enableResetButtons)(); 1766} 1767 1768/** 1769 * Changer la sous-catégorie active. 1770 * @param {string} slug - Le slug de la sous-catégorie. 1771 */ 1772function changeSubcategory(slug) { 1773 _map__WEBPACK_IMPORTED_MODULE_2__.urlManager.setSlugSubCategory(slug); 1774 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.showCategory(slug); 1775 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.fitBounds(); 1776 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.disableAll(); 1777 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_0__.activatePanelView)('locations'); 1778} 1779 1780/** 1781 * Changer la localisation active. 1782 * @param {string} slug - Le slug de la localisation. 1783 */ 1784function selectLocation(slug) { 1785 _map__WEBPACK_IMPORTED_MODULE_2__.urlManager.setSlugLocalisation(slug); 1786 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.showUnique(slug); 1787 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.fitBounds(); 1788 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_0__.activatePanelView)('location-detail'); 1789} 1790 1791/** 1792 * Revenir àla liste des catégories. 1793 */ 1794function returnToRoot() { 1795 _map__WEBPACK_IMPORTED_MODULE_2__.urlManager.resetSlug(); 1796 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.hideAllPopup(); 1797 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.showAll(); 1798 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.fitBounds(); 1799 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.disableAll(); 1800 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_0__.activatePanelView)('categories'); 1801 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_0__.disableResetButtons)(); 1802} 1803 1804/** 1805 * Revenir àla liste des sous-catégories. 1806 */ 1807function returnToSubcategories(slug) { 1808 _map__WEBPACK_IMPORTED_MODULE_2__.urlManager.resetSubcategory(); 1809 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.hideAllPopup(); 1810 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.showCategory(slug); 1811 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.fitBounds(); 1812 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_0__.activatePanelView)('subcategories'); 1813} 1814 1815/** 1816 * Revenir àla liste de localisations. 1817 * @param {string} slug - Le slug de la localisation. 1818 */ 1819function returnFromLocationDetail(slug) { 1820 _map__WEBPACK_IMPORTED_MODULE_2__.urlManager.resetLocation(); 1821 if (_map__WEBPACK_IMPORTED_MODULE_2__.urlManager.getSlugSubcategory()) { 1822 // Il y a une sous-catégorie, on retourne àla liste des localisations. 1823 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.showCategory(slug); 1824 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_0__.activatePanelView)('locations'); 1825 } else if (_map__WEBPACK_IMPORTED_MODULE_2__.urlManager.getSlugCategory()) { 1826 // Aucune sous-catégorie, on retourne àla liste des sous-catégories. 1827 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.showCategory(slug); 1828 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_0__.activatePanelView)('subcategories'); 1829 } else { 1830 _map__WEBPACK_IMPORTED_MODULE_2__.urlManager.resetLocation(); 1831 // Aucune sous-catégorie ou catégorie, on retourne àla liste des catégories. 1832 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.showAll(); 1833 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_0__.activatePanelView)('categories'); 1834 } 1835 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.hideAllPopup(); 1836 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.disableAll(); // Désactiver la puce qui était active. 1837 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.fitBounds(); 1838} 1839 1840/** 1841 * Cliquer sur une puce. 1842 * @param {string} slug - Le slug de la localisation. 1843 */ 1844function locationClick(slug) { 1845 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.hideAllPopup(slug); 1846 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.togglePopup(slug); 1847 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_0__.enableResetButtons)(); 1848 1849 // Si on est en mobile, centrer sur la puce. 1850 if ((0,_mapUtils__WEBPACK_IMPORTED_MODULE_3__.isTouchDevice)()) { 1851 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.center(slug); 1852 } 1853} 1854 1855/** 1856 * Cliquer sur un popup d'une puce. 1857 * @param {string} slug - Le slug de la localisation. 1858 */ 1859function popupClick(slug) { 1860 _map__WEBPACK_IMPORTED_MODULE_2__.urlManager.setSlugLocalisation(slug); 1861 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.showUnique(slug); 1862 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.fitBounds(); 1863 (0,_mapPanels__WEBPACK_IMPORTED_MODULE_0__.activatePanelView)('location-detail'); 1864 // Si on est en mobile, ouvrir le panneau. 1865 if ((0,_mapUtils__WEBPACK_IMPORTED_MODULE_3__.isTouchDevice)()) { 1866 _map__WEBPACK_IMPORTED_MODULE_2__.bottomSheet.openSheetMaxHeight(); 1867 } 1868} 1869 1870/** 1871 * Cliquer sur un bouton de fermeture d'un popup d'une puce. 1872 */ 1873function closePopupClick() { 1874 _mapMarker__WEBPACK_IMPORTED_MODULE_1__.HTMLMarker.hideAllPopup(); 1875 1876 // Fix un peu broche àfoin pour éviter que le click sur le KML se déclanche et fasse réapparaitre le Popup immédiatement 1877 window.isClosing = true; 1878 setTimeout(function () { 1879 window.isClosing = false;
1880 }, '350'); 1881} 1882function manageBackButton() { 1883 window.addEventListener('popstate', function () { 1884 if (document.querySelector('[data-panel-active] .c-map-back-button')) { 1885 document.querySelector('[data-panel-active] .c-map-back-button').click(); 1886 } else { 1887 document.querySelector('.js-quit-map').click(); 1888 } 1889 }); 1890} 1891 1892/***/ }), 1893
1894/***/ "./js/functions/mapMarker.js": 1895/*!***********************************!*\ 1896 !*** ./js/functions/mapMarker.js ***! 1897 \***********************************/ 1898/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1899 1900"use strict"; 1901__webpack_require__.r(__webpack_exports__); 1902/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1903/* harmony export */ HTMLMarker: () => (/* binding */ HTMLMarker), 1904/* harmony export */ initMarker: () => (/* binding */ initMarker) 1905/* harmony export */ }); 1906/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./map */ "./js/functions/map.js"); 1907/* harmony import */ var _mapManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mapManager */ "./js/functions/mapManager.js"); 1908/* 1909Cette classe gère les marqueurs, on utilise les prototypes àcause d’incompatibilités avec Google Map 1910*/ 1911 1912 1913 1914 1915/* global google */ 1916 1917// definir une variable pour recevoir la future définition de marqueur 1918var HTMLMarker; 1919 1920// initMarker est appelé lorsque googlemap est chargé 1921function initMarker() { 1922 // lorsque GoogleMap est chargé on declare un objet et ses prototypes 1923 HTMLMarker = function htmlMarker(args) { 1924 var _this = this; 1925 this.map = args.map; 1926 this.lat = args.lat; 1927 this.lng = args.lng; 1928 this.image = args.image; 1929 this.pos = new google.maps.LatLng(args.lat, args.lng); 1930 this.id = args.id; 1931 this.accessibility = args.accessibility; 1932 this.kmlUrl = args.kmlUrl; 1933 this.kmlLayer = null; // contient l’objet KML 1934 this.kmlBoundsNE = null; // contient les coordonnés du rectangle contenant le KML ( viewport ) attention, peuplé de manière asynchrone ! 1935 this.kmlBoundsSW = null; 1936 this.title = args.title; 1937 this.category = args.category; 1938 this.slug = args.slug; 1939 this.categoriesSlug = args.categoriesSlug; // tableau des slugs de categorie 1940 this.visibleOnMap = false; // Le Marker est-il visible sur la MAP ? 1941 this.active = false; // Est ce que la puce est active ? 1942 this.visiblePopup = false; // Est ce que le popup de la puce est actif ? 1943 1944 HTMLMarker.map = args.map; 1945 HTMLMarker.markerList.push(this); // Ajout du marqueur àla liste qui est une variable static 1946 1947 if (this.kmlUrl) { 1948 HTMLMarker.kmlMarkerList.push(this); 1949 } 1950 1951 // SI UNE URL DE FICHIER KML EST RENSEIGNÉE 1952 if (this.kmlUrl != null) { 1953 this.lat = 0; 1954 this.lng = 0; 1955 this.kmlLayer = new google.maps.KmlLayer({ 1956 url: this.kmlUrl, 1957 // url: this.id === 27 ? 'https://core.dev2.blankodev.com/storage/app/media/d12.kml' : 'https://core.dev2.blankodev.com/storage/app/media/d13.kml', 1958 suppressInfoWindows: true, 1959 preserveViewport: true, 1960 // pour garder le bon viewport 1961 map: this.map 1962 }); 1963 1964 // Au changement de viewport de la carte, si le KML n'a pas de bounds de défini, les calculer et les sauvegarder dans la propriété de la classe 1965 var curentMarker = this; 1966 google.maps.event.addListener(this.kmlLayer, 'defaultviewport_changed', function defaultViewportChanged() { 1967 // On premier affichage, on enregistre les bounds. 1968 if (curentMarker.kmlBoundsNE == null || curentMarker.kmlBoundsSW == null) { 1969 curentMarker.kmlBoundsNE = this.getDefaultViewport().getNorthEast(); 1970 curentMarker.kmlBoundsSW = this.getDefaultViewport().getSouthWest
1970(); 1971 curentMarker.pos = this.getDefaultViewport().getCenter(); 1972 HTMLMarker.fitBounds(); // Ajuster le zoom 1973 } 1974 }); 1975 1976 // si on clique sur le KML 1977 this.kmlLayer.addListener('click', function () { 1978 if (!window.isClosing) { 1979 (0,_mapManager__WEBPACK_IMPORTED_MODULE_1__.locationClick)(_this.slug); 1980 } 1981 }); 1982 } 1983 if (this.lat != null && this.lng != null || this.kmlUrl) { 1984 var div = document.createElement('div'); 1985 div.classList.add('c-map-pin'); 1986 1987 // Si le POI àun état, l'ajouter 1988 if (this.accessibility) { 1989 div.classList.add("c-map-pin--".concat(this.accessibility)); 1990 } 1991 div.innerHTML = this.render(); 1992 this.div = div; 1993 } 1994 this.setMap(this.map); 1995 }; 1996 HTMLMarker.prototype = new google.maps.OverlayView(); 1997 1998 /** 1999 * Afficher le marqueur courant. 2000 * @memberof HTMLMarker.prototype 2001 */ 2002 HTMLMarker.prototype.show = function show() { 2003 this.visibleOnMap = true; 2004 if (this.kmlLayer != null) { 2005 if (_map__WEBPACK_IMPORTED_MODULE_0__.urlManager.isOnRoot()) { 2006 this.kmlLayer.setMap(null); 2007 } else { 2008 this.kmlLayer.setMap(HTMLMarker.map); 2009 } 2010 } 2011 if (this.div) { 2012 this.div.innerHTML = this.render(); // Il faut rafraichir le data-request des puces 2013 this.div.classList.add('c-map-pin--visible'); 2014 } 2015 }; 2016 2017 /** 2018 * Masquer le marqueur courant. 2019 * @memberof HTMLMarker.prototype 2020 */ 2021 HTMLMarker.prototype.hide = function hide() { 2022 this.visibleOnMap = false; 2023 if (this.kmlLayer != null) { 2024 this.kmlLayer.setMap(null); 2025 } 2026 if (this.div) { 2027 this.div.classList.remove('c-map-pin--visible'); 2028 } 2029 }; 2030 2031 /** 2032 * Afficher le popup du marqueur courant. 2033 * @memberof HTMLMarker.prototype 2034 */ 2035 HTMLMarker.prototype.showPopup = function showPopup() { 2036 if (this.div) { 2037 this.visiblePopup = true; 2038 this.div.classList.add('c-map-pin--show-popup'); 2039 } 2040 }; 2041 2042 /** 2043 * Masquer le popup du marqueur courant. 2044 * @memberof HTMLMarker.prototype 2045 */ 2046 HTMLMarker.prototype.hidePopup = function hidePopup() { 2047 if (this.div) { 2048 this.visiblePopup = false; 2049 this.div.classList.remove('c-map-pin--show-popup'); 2050 } 2051 }; 2052 2053 /** 2054 * Afficher/Masquer le popup du marqueur courant. 2055 * @memberof HTMLMarker.prototype 2056 */ 2057 HTMLMarker.prototype.togglePopup = function togglePopup() { 2058 if (this.div) { 2059 this.visiblePopup = !this.visiblePopup; 2060 if (this.visiblePopup) { 2061 this.div.classList.add('c-map-pin--show-popup'); 2062 } else { 2063 this.div.classList.remove('c-map-pin--show-popup'); 2064 } 2065 } 2066 }; 2067 2068 /** 2069 * Centrer la carte sur un marqueur. 2070 * @memberof HTMLMarker.prototype 2071 */ 2072 HTMLMarker.prototype.center = function center() { 2073 if (this.div) { 2074 if (this.lat && this.lng) { 2075 var coords = new google.maps.LatLng(this.lat, this.lng); 2076 this.map.panTo(coords); 2077 } 2078 } 2079 }; 2080 2081 /** 2082 * Ajouter l'état actif du marqueur courant. 2083 * @memberof HTMLMarker.prototype 2084 */ 2085 HTMLMarker.prototype.activate = function activate() { 2086 if (this.div) { 2087 this.active = true; 2088 this.div.classList.add('c-map-pin--active'); 2089 } 2090 }; 2091 2092 /** 2093 * Enlever l'état actif du marqueur courant. 2094 * @memberof HTMLMarker.prototype 2095 */ 2096 HTMLMarker.prototype.disable = function disable() { 2097 if (this.div) { 2098 this.active = false; 2099 this.div.classList.remove('c-map-pin--active'); 2100 } 2101 }; 2102 2103 // Init your html element here 2104 HTMLMarker.prototype.onAdd = function onAdd() { 2105 var panes = this.getPanes(); 2106 // Si pas de latitude et de longitude, c’est uniquement un KML, on skip l’affichage 2107 if (this.lat == null || this.lng == null) { 2108 return; 2109 } 2110 panes.overlayImage.appendChild(this.div); 2111 }; 2112 2113 /** 2114 * Supprime le marqueur. 2115 * @memberof HTMLMarker.prototype 2116 */ 2117 HTMLMarker.prototype.remove = function remove() { 2118 if (this.div) { 2119 this.div.parentNode.removeChild(this.div); 2120 this.div = null; 2121 } 2122 }; 2123 2124 /** 2125 * Récupèrer la visibilité du marqueur. 2126 * @memberof HTMLMarker.prototype 2127 * @returns {boolean} - Indique si le marqueur est visible ou non. 2128 */ 2129 HTMLMarker.prototype.getVisible = function getVisible() { 2130 return true; 2131 }; 2132 2133 /** 2134 * Définir la position du marqueur. 2135 * @memberof HTMLMarker.prototype 2136 * @param {LatLng} position - La position du marqueur. 2137 */ 2138 HTMLMarker.prototype.setPosition = function setPosition(position) { 2139 this.set('position', position); 2140 }; 2141 2142 /** 2143 * Récupérer la position du marqueur. 2144 * @memberof HTMLMarker.prototype 2145 * @returns {LatLng} - La position du marqueur. 2146 */ 2147 HTMLMarker.prototype.getPosition = function getPosition() { 2148 return this.pos; 2149 }; 2150 2151 /** 2152 * Définir la carte associée au marqueur. 2153 * @memberof HTMLMarker.prototype 2154 * @param {google.maps.Map} map - La carte associée au marqueur. 2155 */
2156 HTMLMarker.prototype.setMap = function setMap(map) { 2157 this.set('map', map); 2158 }; 2159 2160 /** 2161 * Rendre le contenu HTML du marqueur en fonction de ses propriétés. 2162 * @memberof HTMLMarker.prototype 2163 * @returns {string} - Le contenu HTML du marqueur. 2164 */ 2165 HTMLMarker.prototype.render = function render() { 2166 var popupHTML = "\n <span class=\"c-map-popup\">\n <span class=\"c-map-popup__close\">\n <button onclick=\"closePopupClick('".concat(this.slug, "')\" class=\"c-map-close-button\">\n <span class=\"c-map-close-button__x\" title=\"Fermer\"></span>\n </button>\n </span>\n <button\n data-request=\"interactiveMap::onChangeLocation\"\n data-request-update=\"'interactiveMap::panels/location-detail':'#map-location-detail'\"\n data-request-data=\"categorySlug: '").concat(_map__WEBPACK_IMPORTED_MODULE_0__.urlManager.getSlugCategory(), "', subcategorySlug: '").concat(_map__WEBPACK_IMPORTED_MODULE_0__.urlManager.getSlugSubcategory(), "', locationId: ").concat(this.id, "\"\n data-request-complete=\"popupClick('").concat(this.slug, "');\"\n class=\"c-map-popup__inner\">\n <span class=\"c-map-popup__content\">\n <span class=\"c-map-popup__category\">").concat(this.category, "</span>\n <span class=\"c-map-popup__title\">\n <span class=\"c-map-popup__title-text\">").concat(this.title, "</span>\n <svg class=\"c-map-popup__title-arrow\" role=\"img\"><use xlink:href=\"/plugins/blanko/map/assets/images/icons/map.svg#ico-chevron\"></use></svg>\n </span>\n </span>\n ").concat(this.image ? "\n <picture class=\"c-map-popup__picture\">\n <img class=\"c-map-popup__img\" src=\"/storage/app/media".concat(this.image, "\" alt=\"\">\n </picture>\n ") : '', "\n </button>\n </span>\n "); 2167 2168 // Si c'est un marqueur normal 2169 if (!this.kmlUrl) { 2170 return "\n <span class=\"c-map-pin__bullet\">\n <button\n id=\"".concat(this.slug, "\"\n class=\"c-map-pin__inner ").concat(this.accessibility, "\"\n data-slug=\"").concat(this.slug, "\"\n title=\"").concat(this.title, "\"\n onclick=\"locationClick('").concat(this.slug, "');\">\n </button>\n </span>\n <span class=\"c-map-pin__popup\">\n ").concat(popupHTML, "\n </span>\n "); 2171 } 2172 2173 // Si c'est un KML, on met seulement le popup avec un modificateur. 2174 return "\n <span class=\"c-map-pin__popup c-map-pin__popup--kml\">\n ".concat(popupHTML, "\n </span>\n "); 2175 }; 2176 HTMLMarker.prototype.draw = function draw() { 2177 var overlayProjection = this.getProjection(); 2178 var position = overlayProjection.fromLatLngToDivPixel(this.pos); 2179 this.div.style.left = "".concat(position.x, "px"); 2180 this.div.style.top = "".concat(position.y, "px"); 2181 }; 2182 2183 // Methode appelée automatiquement si on setMap(null) l’objet, voir doc Google 2184 HTMLMarker.prototype.onRemove = function onRemove() { 2185 if (this.div) { 2186 this.div.remove(); 2187 } 2188 return false; 2189 }; 2190 2191 /* ******************************* 2192 PROPRIÉTÉS ET METHODES STATICS 2193 ****************************** */ 2194 HTMLMarker.map = null; 2195 HTMLMarker.markerList = []; 2196 HTMLMarker.kmlMarkerList = []; 2197 HTMLMarker.minZoom = 15; // zomm minimum de la carte 2198 2199 // Active visuellement un marqueur 2200 HTMLMarker.activate = function (markerSlug) { 2201 HTMLMarker.markerList.forEach(function (marker) { 2202 if (marker.slug === markerSlug) { 2203 marker.activate(); 2204 } else { 2205 marker.disable(); 2206 } 2207 }); 2208 }; 2209 HTMLMarker.getBySlug = function (slug) { 2210 for (var i = 0; i < HTMLMarker.markerList.length; i += 1) { 2211 if (HTMLMarker.markerList[i].slug === slug) { 2212 return HTMLMarker.markerList[i]; 2213 } 2214 } 2215 return false; 2216 }; 2217 HTMLMarker.disableAll = function () { 2218 HTMLMarker.markerList.forEach(function (marker) { 2219 marker.disable(); 2220 }); 2221 }; 2222 2223 // Cacher touts les marqueurs sur la carte 2224 HTMLMarker.hideAll = function () { 2225 HTMLMarker.markerList.forEach(function (marker) { 2226 marker.hide(); 2227 }); 2228 }; 2229 2230 // Affiche touts les marqueurs de la carte 2231 HTMLMarker.showAll = function () { 2232 HTMLMarker.markerList.forEach(function (marker) { 2233 marker.show(); 2234 }); 2235 HTMLMarker.refreshClusterer(); 2236 }; 2237 2238 // Affiche un marqueur en particulier sur la carte 2239 HTMLMarker.showUnique = function (markerSlug) { 2240 HTMLMarker.hideAllPopup(); 2241 HTMLMarker.markerList.forEach(function (marker) { 2242 if (marker.slug === markerSlug) { 2243 marker.show(); 2244 marker.activate(); 2245 } else { 2246 marker.hide(); 2247 } 2248 }); 2249 HTMLMarker.refreshClusterer(); 2250 }; 2251 2252 // Affiche un popup de marqueur en particulier sur la carte 2253 HTMLMarker.showPopup = function (markerSlug) { 2254 HTMLMarker.markerList.forEach(function (marker) { 2255 if (marker.slug === markerSlug) { 2256 marker.showPopup(); 2257 } 2258 }); 2259 }; 2260 2261 // Cacher touts les popups de marqueurs sur la carte 2262 HTMLMarker.hideAllPopup = function () { 2263 var markerSlug = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 2264 HTMLMarker.markerList.forEach(function (marker) { 2265 if (marker.slug !== markerSlug) { 2266 marker.hidePopup(); 2267 } 2268 }); 2269 }; 2270 2271 /** 2272 * Afficher/cacher le popup du marqueur spécifié par son slug. 2273 * @memberof HTMLMarker 2274 * @param {string} markerSlug - Le slug du marqueur. 2275 */ 2276 HTMLMarker.togglePopup = function (markerSlug) { 2277 HTMLMarker.markerList.forEach(function (marker) { 2278 if (marker.slug === markerSlug) { 2279 marker.togglePopup(); 2280 } 2281 }); 2282 }; 2283 2284 /** 2285 * Centrer la carte sur le marqueur spécifié par son slug. 2286 * @memberof HTMLMarker 2287 * @param {string} markerSlug - Le slug du marqueur. 2288 */ 2289 HTMLMarker.center = function (markerSlug) { 2290 HTMLMarker.markerList.forEach(function (marker) { 2291 if (marker.slug === markerSlug) { 2292 marker.center(); 2293 } 2294 }); 2295 }; 2296 2297 /** 2298 * Afficher les marqueurs de la catégorie spécifiée sur la carte et met àjour les Clusters. 2299 * @memberof HTMLMarker 2300 * @param {string} categorySlug - Le slug de la catégorie. 2301 */ 2302 HTMLMarker.showCategory = function (categorySlug) { 2303 HTMLMarker.markerList.forEach(function (marker) { 2304 if (marker.categoriesSlug.includes(categorySlug)) { 2305 marker.show(); 2306 } else { 2307 marker.hide(); 2308 } 2309 }); 2310 HTMLMarker.refreshClusterer(); 2311 }; 2312 2313 // Rafraichir le clusterer 2314 HTMLMarker.refreshClusterer = function () { 2315 var pois = HTMLMarker.markerList; 2316 var filteredPois = []; 2317 pois.forEach(function (element) { 2318 if (element.visibleOnMap && !element.kmlLayer) { 2319 filteredPois.push(element); 2320 } 2321 }); 2322 window.markerClusterer.clearMarkers(); 2323 window.markerClusterer.addMarkers(filteredPois); 2324 }; 2325 2326 /** 2327 * Ajuster la vue de la carte pour inclure àla fois les KML et les marqueurs visibles. 2328 * @memberof HTMLMarker 2329 */ 2330 HTMLMarker.fitBounds = function () { 2331 var bounds = new google.maps.LatLngBounds();
2332 window.markerClusterer.markers.forEach(function (marker) { 2333 // pour chaque marker activé on étend le rectangle de visualisation si le POI dispose de coordonnés ( sinon ça signifie que c’est un KML ) 2334 if (marker.visibleOnMap && marker.lat != null && marker.lng != null) { 2335 bounds.extend(marker.pos); 2336 } 2337 }); 2338 2339 // Ajouter les bounds des KML affichés 2340 HTMLMarker.kmlMarkerList.forEach(function (marker) { 2341 if (marker.visibleOnMap && marker.kmlLayer != null) { 2342 if (marker.kmlLayer.getMap()) { 2343 if (marker.kmlBoundsNE != null) { 2344 bounds.extend(marker.kmlBoundsNE); 2345 } 2346 if (marker.kmlBoundsSW != null) { 2347 bounds.extend(marker.kmlBoundsSW); 2348 } 2349 } 2350 } 2351 }); 2352 HTMLMarker.map.fitBounds(bounds); 2353 var zoom = HTMLMarker.map.getZoom(); 2354 if (zoom > HTMLMarker.minZoom) { 2355 zoom = HTMLMarker.minZoom; 2356 } 2357 HTMLMarker.map.setZoom(zoom); 2358 }; 2359 window.HTMLMarker = HTMLMarker; 2360} 2361 2362/***/ }), 2363
2364/***/ "./js/functions/mapMarkerCluster.js": 2365/*!******************************************!*\ 2366 !*** ./js/functions/mapMarkerCluster.js ***! 2367 \******************************************/ 2368/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 2369 2370"use strict"; 2371__webpack_require__.r(__webpack_exports__); 2372/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2373/* harmony export */ "default": () => (/* binding */ htmlMarkerCluster) 2374/* harmony export */ }); 2375/* harmony import */ var _mapMarker__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mapMarker */ "./js/functions/mapMarker.js"); 2376 2377/* global google */ 2378 2379/** 2380 * Initialise les marqueurs de type Cluster sur la carte. 2381 * @param {Object} args - Les arguments pour initialiser le marqueur de type Cluster. 2382 */ 2383function htmlMarkerCluster(args) { 2384 this.latlng = args.latlng; 2385 this.count = args.count; 2386 this.bounds = args.bounds; 2387 this.map = args.map; 2388 this.setMap(this.map); 2389} 2390 2391/** 2392 * Classe représentant un marqueur personnalisé sur la carte Google Maps. 2393 * @class 2394 * @extends google.maps.OverlayView 2395 * @memberof htmlMarkerCluster 2396 */ 2397htmlMarkerCluster.prototype = new google.maps.OverlayView(); 2398 2399/** 2400 * Dessiner le marqueur. 2401 * @memberof htmlMarkerCluster.prototype 2402 */ 2403htmlMarkerCluster.prototype.draw = function draw() { 2404 var _this = this; 2405 var div = this.div; 2406 var point = this.getProjection().fromLatLngToDivPixel(this.latlng); 2407 if (!div) { 2408 div = this.div = document.createElement('div'); 2409 div.className = 'c-map-pin c-map-pin--cluster'; 2410 div.innerHTML = "<div class=\"c-map-pin__cluster\">\n <span class=\"c-map-pin__bullet\">\n <button class=\"c-map-pin__inner\">\n <span class=\"c-map-pin__count\">".concat(this.count, "</span>\n </button>\n </span>\n </div>"); 2411 google.maps.event.addDomListener(div, 'click', function () { 2412 // Gérer le clic sur un cluster. 2413 if (typeof _this.bounds !== 'undefined') { 2414 _this.map.fitBounds(_this.bounds); 2415 } 2416 // Fermer tous les popups de puces. 2417 _mapMarker__WEBPACK_IMPORTED_MODULE_0__.HTMLMarker.hideAllPopup(); 2418 }); 2419 var panes = this.getPanes(); 2420 panes.overlayImage.appendChild(div); 2421 } 2422 if (point) { 2423 div.style.left = "".concat(point.x, "px"); 2424 div.style.top = "".concat(point.y, "px"); 2425 } 2426}; 2427 2428/** 2429 * Supprimer le marqueur. 2430 * @memberof htmlMarkerCluster.prototype 2431 */ 2432htmlMarkerCluster.prototype.remove = function remove() { 2433 if (this.div) { 2434 this.div.parentNode.removeChild(this.div); 2435 this.div = null; 2436 } 2437}; 2438 2439/** 2440 * Définir la position du marqueur. 2441 * @memberof htmlMarkerCluster.prototype 2442 * @param {LatLng} position - La position du marqueur. 2443 */ 2444htmlMarkerCluster.prototype.setPosition = function setPosition(position) { 2445 this.set('position', position); 2446}; 2447 2448/** 2449 * Récupérer la position du marqueur. 2450 * @memberof htmlMarkerCluster.prototype 2451 * @returns {LatLng} - La position du marqueur. 2452 */ 2453htmlMarkerCluster.prototype.getPosition = function getPosition() { 2454 return this.latlng; 2455}; 2456 2457/** 2458 * Définir la carte associée au marqueur. 2459 * @memberof htmlMarkerCluster.prototype 2460 * @param {google.maps.Map} map - La carte associée au marqueur. 2461 */
2462htmlMarkerCluster.prototype.setMap = function setMap(map) { 2463 this.set('map', map); 2464}; 2465 2466/***/ }), 2467
2468/***/ "./js/functions/mapPanels.js": 2469/*!***********************************!*\ 2470 !*** ./js/functions/mapPanels.js ***! 2471 \***********************************/ 2472/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 2473 2474"use strict"; 2475__webpack_require__.r(__webpack_exports__); 2476/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2477/* harmony export */ activatePanelView: () => (/* binding */ activatePanelView), 2478/* harmony export */ deactivatePanelView: () => (/* binding */ deactivatePanelView), 2479/* harmony export */ disableResetButtons: () => (/* binding */ disableResetButtons), 2480/* harmony export */ enableResetButtons: () => (/* binding */ enableResetButtons) 2481/* harmony export */ }); 2482/** 2483 * Désactiver tous les panneaux dans l'interface de la carte. 2484 */ 2485function deactivatePanelView() { 2486 var SIDEBAR = document.querySelector('.js-map-panels'); 2487 if (SIDEBAR) { 2488 var VIEWS = SIDEBAR.querySelectorAll('.js-map-panels-view'); 2489 // Désactiver toutes les vues 2490 for (var i = 0; i < VIEWS.length; i += 1) { 2491 VIEWS[i].removeAttribute('data-panel-active'); 2492 } 2493 } 2494} 2495 2496/** 2497 * Active le panneau spécifié dans l'interface de la carte. 2498 * @param {string} view - La vue àactiver. 2499 */ 2500function activatePanelView(view) { 2501 // Assurer qu'aucune autre vue de panneau n'est active avant d'activer la nouvelle 2502 deactivatePanelView(); 2503 2504 // Vérifie si le panneau de la carte existent dans le DOM 2505 if (document.querySelector('.js-map-panels')) { 2506 // Déclenche un événement personnalisé en fonction de la vue àactiver 2507 switch (view) { 2508 case 'categories': 2509 document.dispatchEvent(new Event('mapShowPanelViewCategories')); 2510 break; 2511 case 'subcategories': 2512 document.dispatchEvent(new Event('mapShowPanelViewSubcategories')); 2513 break; 2514 case 'locations': 2515 document.dispatchEvent(new Event('mapShowPanelViewLocations')); 2516 break; 2517 case 'location-detail': 2518 document.dispatchEvent(new Event('mapShowPanelViewLocationDetail')); 2519 break; 2520 default: 2521 return; 2522 } 2523 2524 // Activer la bonne vue dans le panneau 2525 var VIEW = document.querySelector(".js-map-panels-view[data-view=\"".concat(view, "\"]")); 2526 VIEW.setAttribute('data-panel-active', ''); 2527 } 2528} 2529 2530/** 2531 * Activer les boutons de réinitialisation dans l'interface de la carte. 2532 */ 2533function enableResetButtons() { 2534 var BUTTONS = document.querySelectorAll('.js-map-reset'); 2535 for (var i = 0; i < BUTTONS.length; i += 1) { 2536 BUTTONS[i].disabled = false; 2537 } 2538} 2539 2540/** 2541 * Désactiver les boutons de réinitialisation dans l'interface de la carte. 2542 */ 2543function disableResetButtons() { 2544 var BUTTONS = document.querySelectorAll('.js-map-reset'); 2545 for (var i = 0; i < BUTTONS.length; i += 1) { 2546 BUTTONS[i].disabled = true; 2547 } 2548} 2549 2550/***/ }), 2551
2552/***/ "./js/functions/mapStyle.js": 2553/*!**********************************!*\ 2554 !*** ./js/functions/mapStyle.js ***! 2555 \**********************************/ 2556/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 2557 2558"use strict"; 2559__webpack_require__.r(__webpack_exports__); 2560/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2561/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) 2562/* harmony export */ }); 2563/** 2564 * Définir le style visuel de la carte Google Maps. 2565 * Ce style est importé dans le fichier map.js afin d'être appliqué àla carte. 2566 */ 2567/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ([{ 2568 featureType: 'administrative', 2569 elementType: 'labels.text.fill' 2570}, { 2571 featureType: 'administrative.locality', 2572 elementType: 'labels', 2573 stylers: [{ 2574 visibility: 'on' 2575 }] 2576}, { 2577 featureType: 'landscape', 2578 elementType: 'all', 2579 stylers: [{ 2580 color: window.mapConfig.color_background 2581 }, { 2582 visibility: 'simplified' 2583 }] 2584}, { 2585 featureType: 'poi', 2586 elementType: 'all', 2587 stylers: [{ 2588 visibility: 'off' 2589 }] 2590}, { 2591 featureType: 'poi.park', 2592 elementType: 'all', 2593 stylers: [{ 2594 visibility: 'on' 2595 }] 2596}, { 2597 featureType: 'poi.park', 2598 elementType: 'labels.icon', 2599 stylers: [{ 2600 visibility: 'off' 2601 }] 2602}, { 2603 featureType: 'poi.park', 2604 elementType: 'geometry', 2605 stylers: [{ 2606 color: window.mapConfig.color_parks 2607 }] 2608}, { 2609 featureType: 'poi', 2610 elementType: 'labels', 2611 stylers: [{ 2612 visibility: 'off' 2613 }] 2614}, { 2615 featureType: 'road', 2616 elementType: 'all', 2617 stylers: [{ 2618 saturation: -100 2619 }, { 2620 lightness: 45 2621 }] 2622}, { 2623 featureType: 'road', 2624 elementType: 'labels', 2625 stylers: [{ 2626 visibility: 'on' 2627 }] 2628}, { 2629 featureType: 'road', 2630 elementType: 'labels.icon', 2631 stylers: [{ 2632 visibility: 'off' 2633 }] 2634}, { 2635 featureType: 'road.highway', 2636 elementType: 'all', 2637 stylers: [{ 2638 visibility: 'simplified' 2639 }] 2640}, { 2641 featureType: 'road.highway', 2642 elementType: 'labels.icon', 2643 stylers: [{ 2644 visibility: 'off' 2645 }] 2646}, { 2647 featureType: 'road.arterial', 2648 elementType: 'labels.icon', 2649 stylers: [{ 2650 visibility: 'off' 2651 }] 2652}, { 2653 featureType: 'transit', 2654 elementType: 'all', 2655 stylers: [{ 2656 visibility: 'off' 2657 }] 2658}, { 2659 featureType: 'water', 2660 elementType: 'all', 2661 stylers: [{ 2662 color: window.mapConfig.color_water 2663 }, { 2664 visibility: 'simplified' 2665 }] 2666}]); 2667 2668/***/ }), 2669
2670/***/ "./js/functions/mapUrl.js": 2671/*!********************************!*\ 2672 !*** ./js/functions/mapUrl.js ***! 2673 \********************************/ 2674/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 2675 2676"use strict"; 2677__webpack_require__.r(__webpack_exports__); 2678/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2679/* harmony export */ "default": () => (/* binding */ MapUrl) 2680/* harmony export */ }); 2681function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 2682function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } 2683function _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."); } 2684function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } 2685function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } 2686function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } 2687function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } 2688function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } 2689function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } 2690function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } 2691function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } 2692function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } 2693/** 2694 * Cette classe est utilisée pour gérer et créer les URLs de la carte. 2695 * Lorsqu'on clique sur une catégorie, sous-catégorie ou une localisation, 2696 * l'objet est mis àjour, construit l'URL et la pousse dans le navigateur. 2697 */ 2698var MapUrl = /*#__PURE__*/function () { 2699 /** 2700 * Constructeur de la classe MapUrl. 2701 * @constructor 2702 */ 2703 function MapUrl() { 2704 _classCallCheck(this, MapUrl); 2705 this.slugCategory = null; 2706 this.slugSubCategory = null; 2707 this.slugLocalisation = null; 2708 } 2709 2710 /** 2711 * Indique si l'URL de la page se trouve àla racine (sans catégorie et sous-catégorie) ou non. 2712 * @returns {boolean} True si l'URL de la page est àla racine, sinon False. 2713 */ 2714 return _createClass(MapUrl, [{ 2715 key: "isOnRoot", 2716 value: function isOnRoot() { 2717 return !this.slugCategory && !this.slugSubCategory && !this.slugLocalisation; 2718 } 2719 2720 /** 2721 * Réinitialiser les slugs de catégorie, sous-catégorie et localisation, et met àjour l'URL. 2722 */ 2723 }, { 2724 key: "resetSlug", 2725 value: function resetSlug() { 2726 this.slugCategory = null; 2727 this.slugSubCategory = null; 2728 this.slugLocalisation = null; 2729 this.updateUrl(); 2730 } 2731 2732 /** 2733 * Réinitialiser les slugs de sous-catégorie et de localisation, et met àjour l'URL. 2734 */ 2735 }, { 2736 key: "resetSubcategory", 2737 value: function resetSubcategory() { 2738 this.slugSubCategory = null; 2739 this.slugLocalisation = null; 2740 this.updateUrl(); 2741 } 2742 2743 /** 2744 * Réinitialiser le slug de la localisation et met àjour l'URL. 2745 */ 2746 }, { 2747 key: "resetLocation", 2748 value: function resetLocation() { 2749 this.slugLocalisation = null; 2750 this.updateUrl(); 2751 } 2752 2753 /** 2754 * Définir le slug de la catégorie et met àjour l'URL. 2755 * @param {string|null} slug - Le slug de la catégorie. 2756 */ 2757 }, { 2758 key: "setSlugCategory", 2759 value: function setSlugCategory(slug) { 2760 this.slugCategory = slug; 2761 this.slugSubCategory = null; 2762 this.slugLocalisation = null; 2763 this.updateUrl(); 2764 } 2765 2766 /** 2767 * Récupère le slug de la catégorie. 2768 * @returns {string|null} Le slug de la catégorie. 2769 */ 2770 }, { 2771 key: "getSlugCategory", 2772 value: function getSlugCategory() { 2773 return this.slugCategory; 2774 } 2775 2776 /** 2777 * Définir le slug de la sous-catégorie et met àjour l'URL. 2778 * @param {string|null} slug - Le slug de la sous-catégorie. 2779 */ 2780 }, { 2781 key: "setSlugSubCategory", 2782 value: function setSlugSubCategory(slug) { 2783 this.slugSubCategory = slug; 2784 this.slugLocalisation = null; // reinitialise les fils 2785 this.updateUrl(); 2786 } 2787 2788 /** 2789 * Récupère le slug de la sous-catégorie. 2790 * @returns {string|null} Le slug de la sous-catégorie. 2791 */ 2792 }, { 2793 key: "getSlugSubcategory", 2794 value: function getSlugSubcategory() { 2795 return this.slugSubCategory; 2796 } 2797 2798 /** 2799 * Définir le slug de la localisation et met àjour l'URL. 2800 * @param {string|null} slug - Le slug de la localisation. 2801 */ 2802 }, { 2803 key: "setSlugLocalisation", 2804 value: function setSlugLocalisation(slug) { 2805 this.slugLocalisation = slug; 2806 this.updateUrl(); 2807 } 2808 2809 /** 2810 * Récupère le slug de la localisation. 2811 * @returns {string|null} Le slug de la localisation. 2812 */ 2813 }, { 2814 key: "getSlugLocalisation", 2815 value: function getSlugLocalisation() { 2816 return this.slugLocalisation; 2817 } 2818 2819 /** 2820 * Met àjour l'URL dans le navigateur en fonction des propriétés actuelles. 2821 */ 2822 }, { 2823 key: "updateUrl", 2824 value: function updateUrl() { 2825 // Récupérer le path de l'URL actuelle. 2826 var currentURL = new URL(window.location); 2827 var urlPath = currentURL.pathname; 2828 var urlPathParts = urlPath.split('/'); 2829 urlPathParts.shift(); // Retirer le premier slash 2830 2831 // Construction de la nouvelle section de l'URL.
2832 var newUrlPath = []; 2833 newUrlPath[0] = this.slugCategory; 2834 newUrlPath[1] = this.slugSubCategory; 2835 newUrlPath[2] = this.slugLocalisation; 2836 var mapSection = newUrlPath.filter(Boolean).join('/'); 2837 var newUrl = ''; 2838 2839 // Création de la nouvelle URL en utilisant la base de l'URL précédente et en ajoutant la nouvelle section. 2840 if (window.mapConfig.is_multilingual) { 2841 newUrl = "/".concat(urlPathParts[0], "/").concat(urlPathParts[1], "/").concat(mapSection); 2842 } else { 2843 newUrl = "/".concat(urlPathParts[0], "/").concat(mapSection); 2844 } 2845 2846 // Mettre àjour l'historique du navigateur avec la nouvelle URL sans recharger la page. 2847 window.history.pushState({}, '', newUrl); 2848 } 2849 2850 /** 2851 * Analyse l'URL actuelle et met àjour les propriétés de la classe en fonction des sections d'URL correspondantes. 2852 */ 2853 }, { 2854 key: "parseUrl", 2855 value: function parseUrl() { 2856 // Récupérer le path de l'URL actuelle. 2857 var currentURL = new URL(window.location); 2858 var urlPath = currentURL.pathname; 2859 var urlPathParts = urlPath.split('/'); 2860 urlPathParts.shift(); // Retirer le premier slash 2861 if (window.mapConfig.is_multilingual) { 2862 urlPathParts.shift(); // Retirer la langue 2863 } 2864 urlPathParts.shift(); // Retirer le nom de la page de carte 2865 2866 // Remplir les propriétés de la classe avec les valeurs du tableau de l'URL. 2867 // Si l'URl est vide, le premier élément du tableau sera une chaine vide, il faut remplacer ça par null. 2868 var _urlPathParts = _slicedToArray(urlPathParts, 3); 2869 this.slugCategory = _urlPathParts[0]; 2870 this.slugSubCategory = _urlPathParts[1]; 2871 this.slugLocalisation = _urlPathParts[2]; 2872 if (this.slugCategory === '') { 2873 this.slugCategory = null; 2874 } 2875 2876 // S'il y a seulement un paramètre dans l'URL. 2877 if (this.slugSubCategory == null && this.slugLocalisation == null) { 2878 // S'il n'y a pas de catégorie qui correspond, c'est probablement le slug d'un POI. 2879 if (!document.querySelector(".c-map-categories__item[data-slug=\"".concat(this.slugCategory, "\"]"))) { 2880 this.slugLocalisation = this.slugCategory; 2881 this.slugSubCategory = null; 2882 this.slugCategory = null; 2883 } 2884 } else if (this.slugLocalisation == null) { 2885 // S'il n'y a pas de sous-catégorie qui correspond, c'est probablement le slug d'un POI. 2886 if (!document.querySelector(".c-map-subcategories__item[data-slug=\"".concat(this.slugSubCategory, "\"]"))) { 2887 this.slugLocalisation = this.slugSubCategory; 2888 this.slugSubCategory = null; 2889 this.slugCategory = null; 2890 } 2891 } 2892 } 2893 2894 /** 2895 * Initialise la classe MapUrl 2896 */ 2897 }, { 2898 key: "init", 2899 value: function init() { 2900 this.parseUrl(); 2901 } 2902 }]); 2903}(); 2904 2905 2906/***/ }), 2907
2908/***/ "./js/functions/mapUtils.js": 2909/*!**********************************!*\ 2910 !*** ./js/functions/mapUtils.js ***! 2911 \**********************************/ 2912/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 2913 2914"use strict"; 2915__webpack_require__.r(__webpack_exports__); 2916/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2917/* harmony export */ hasGeolocation: () => (/* binding */ hasGeolocation), 2918/* harmony export */ isInZone: () => (/* binding */ isInZone), 2919/* harmony export */ isTouchDevice: () => (/* binding */ isTouchDevice) 2920/* harmony export */ }); 2921/** 2922 * Détermine si l'appareil dispose de la fonctionnalité tactile. 2923 * @returns {boolean} True si l'appareil est tactile, sinon False. 2924 */ 2925function isTouchDevice() { 2926 return 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0; 2927} 2928 2929/** 2930 * Détermine si l'appareil dispose de la fonctionnalité de géolocalisation. 2931 * @returns {boolean} True si l'appareil supporte la géolocalisation, sinon False. 2932 */ 2933function hasGeolocation() { 2934 return navigator.geolocation; 2935} 2936 2937/** 2938 * Détermine si une coordonnée GPS se trouve àl'intérieur d'un carré de coordonnées GPS. 2939 * @returns {boolean} True la coordonée se trouve àl'intéreur de la zone, sinon False. 2940 */ 2941function isInZone(lat, lng, zone) { 2942 var result = false;
2943 if (lat < zone.north && lat > zone.south && lng > zone.west && lng < zone.east) { 2944 result = true; 2945 } 2946 return result; 2947} 2948 2949/***/ }), 2950
2951/***/ "./js/plugins.js": 2952/*!***********************!*\ 2953 !*** ./js/plugins.js ***! 2954 \***********************/ 2955/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 2956 2957"use strict"; 2958__webpack_require__.r(__webpack_exports__); 2959/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2960/* harmony export */ OBSERVER: () => (/* binding */ OBSERVER) 2961/* harmony export */ }); 2962/* harmony import */ var _vendor_observer_min__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./vendor/observer.min */ "./js/vendor/observer.min.js"); 2963/* harmony import */ var _vendor_observer_min__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_vendor_observer_min__WEBPACK_IMPORTED_MODULE_0__); 2964 2965var OBSERVER = _vendor_observer_min__WEBPACK_IMPORTED_MODULE_0___default().getInstance(); 2966 2967/***/ }), 2968
2969/***/ "./js/vendor/observer.min.js": 2970/*!***********************************!*\ 2971 !*** ./js/vendor/observer.min.js ***! 2972 \***********************************/ 2973/***/ ((module, exports, __webpack_require__) => { 2974 2975/* module decorator */ module = __webpack_require__.nmd(module); 2976var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } 2977function _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."); } 2978function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } 2979function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } 2980function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } 2981function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } 2982function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } 2983function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } 2984function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } 2985function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } 2986function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } 2987function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 2988!function (e, t) { 2989 "object" == ( false ? 0 : _typeof(exports)) && "object" == ( false ? 0 : _typeof(module)) ? module.exports = t() : true ? !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (t), 2990 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 2991 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 2992 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)) : 0; 2993}(self, function () { 2994 return function () { 2995 "use strict"; 2996 2997 var e = { 2998 607: function _(e, t, s) { 2999 e.exports = s(400)["default"]; 3000 }, 3001 400: function _(e, t, s) { 3002 s.d(t, { 3003 "default": function _default() { 3004 return i; 3005 } 3006 }); 3007 var n = function n(e) { 3008 var t, 3009 s = 0; 3010 for (t in e) e.hasOwnProperty(t) && s++; 3011 return s; 3012 }; 3013 var i = /*#__PURE__*/function () { 3014 function i() { 3015 _classCallCheck(this, i); 3016 this.eventList = {}; 3017 } 3018 return _createClass(i, [{ 3019 key: "list", 3020 get: function get() { 3021 return this.eventList; 3022 } 3023 }, { 3024 key: "throwMessage", 3025 value: function throwMessage(e) { 3026 console.warn("Observer => ".concat(e)); 3027 } 3028 }, { 3029 key: "toggle", 3030 value: function toggle(e) { 3031 var t, s; 3032 var _i = n(this.eventList); 3033 for (t = 0; t < _i; t += 1) s = "event".concat(t), e(s); 3034 } 3035 }, { 3036 key: "manageListeners", 3037 value: function manageListeners(e, t, s) { 3038 var n, _i2; 3039 var r = this.eventList[s].targets.length, 3040 o = this.eventList[s].events.length; 3041 for (n = 0; n < r; n += 1) for (_i2 = 0; _i2 < o; _i2 += 1) this.eventList[s].targets[n][e](this.eventList[s].events[_i2], this.eventList[s]["function"]); 3042 this.eventList[s].active = t; 3043 } 3044 }, { 3045 key: "manageTargets", 3046 value: function manageTargets(e) { 3047 var t; 3048 return t = "document" === e || e === document ? [document] : "window" === e || e === window ? [window] : "string" == typeof e ? _toConsumableArray(document.querySelectorAll(e)) : e instanceof NodeList ? _toConsumableArray(e) : e instanceof HTMLElement ? [e] : [window], t; 3049 } 3050 }, { 3051 key: "manageEvents", 3052 value: function manageEvents(e) { 3053 return e.split(" "); 3054 } 3055 }, { 3056 key: "on", 3057 value: function on(e) { 3058 var _this = this; 3059 this.toggle(function (t) { 3060 _this.eventList[t].name === e && _this.manageListeners("addEventListener", !0, t); 3061 }); 3062 } 3063 }, { 3064 key: "off", 3065 value: function off(e) { 3066 var _this2 = this; 3067 this.toggle(function (t) { 3068 _this2.eventList[t].name === e && _this2.manageListeners("removeEventListener", !1, t); 3069 }); 3070 } 3071 }, { 3072 key: "allOn", 3073 value: function allOn() { 3074 var _this3 = this; 3075 this.toggle(function (e) { 3076 return _this3.manageListeners("addEventListener", !0, e); 3077 }); 3078 } 3079 }, { 3080 key: "allOff", 3081 value: function allOff() { 3082 var _this4 = this; 3083 this.toggle(function (e) { 3084 return _this4.manageListeners("removeEventListener", !1, e); 3085 }); 3086 } 3087 }, { 3088 key: "refresh", 3089 value: function refresh(e) { 3090 this.off(e), this.on(e); 3091 } 3092 }, { 3093 key: "refreshAll", 3094 value: function refreshAll() { 3095 this.allOff(), this.allOn(); 3096 } 3097 }, { 3098 key: "add", 3099 value: function add(e) { 3100 var t = "event".concat(n(this.eventList)); 3101 this.eventList[t] = {}, this.eventList[t].name = e.name, this.eventList[t].active = !1, this.eventList[t].events = this.manageEvents(e.events), this.eventList[t].eventsCount = this.eventList[t].events.length, this.eventList[t]["function"] = e["function"], this.eventList[t].targets = this.manageTargets(e.targets), this.eventList[t].targetsCount = this.eventList[t].targets.length; 3102 } 3103 }, { 3104 key: "remove", 3105 value: function remove(e) { 3106 var _this5 = this; 3107 this.toggle(function (t) { 3108 _this5.eventList[t].name === e && (_this5.manageListeners("removeEventListener", !1, t), _this5.eventList[t].active || delete _this5.eventList[t]); 3109 }); 3110 } 3111 }, { 3112 key: "removeAll", 3113 value: function removeAll() { 3114 var _this6 = this; 3115 this.toggle(function (e) { 3116 _this6.manageListeners("removeEventListener", !1, e), _this6.eventList[e].active || delete _this6.eventList[e]; 3117 }); 3118 } 3119 }], [{ 3120 key: "getInstance", 3121 value: function getInstance() { 3122 return i.instance || (this.instance = new i()), this.instance; 3123 } 3124 }]); 3125 }(); 3126 } 3127 }, 3128 t = {}; 3129 function s(n) { 3130 var i = t[n]; 3131 if (void 0 !== i) return i.exports; 3132 var r = t[n] = { 3133 exports: {} 3134 }; 3135 return e[n](r, r.exports, s), r.exports; 3136 } 3137 return s.d = function (e, t) { 3138 for (var n in t) s.o(t, n) && !s.o(e, n) && Object.defineProperty(e, n, { 3139 enumerable: !0, 3140 get: t[n] 3141 }); 3142 }, s.o = function (e, t) { 3143 return Object.prototype.hasOwnProperty.call(e, t); 3144 }, s(607); 3145 }(); 3146}); 3147 3148/***/ }), 3149
vendor: 1,420 bytes, lines 3150-3206
3150/***/ "./node_modules/fast-deep-equal/index.js": 3151/*!***********************************************!*\ 3152 !*** ./node_modules/fast-deep-equal/index.js ***! 3153 \***********************************************/ 3154/***/ ((module) => { 3155 3156"use strict"; 3157 3158 3159// do not edit .js files directly - edit src/index.jst 3160 3161 3162 3163module.exports = function equal(a, b) { 3164 if (a === b) return true; 3165 3166 if (a && b && typeof a == 'object' && typeof b == 'object') { 3167 if (a.constructor !== b.constructor) return false; 3168 3169 var length, i, keys; 3170 if (Array.isArray(a)) { 3171 length = a.length; 3172 if (length != b.length) return false; 3173 for (i = length; i-- !== 0;) 3174 if (!equal(a[i], b[i])) return false; 3175 return true; 3176 } 3177 3178 3179 3180 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 3181 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 3182 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 3183 3184 keys = Object.keys(a); 3185 length = keys.length; 3186 if (length !== Object.keys(b).length) return false; 3187 3188 for (i = length; i-- !== 0;) 3189 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; 3190 3191 for (i = length; i-- !== 0;) { 3192 var key = keys[i]; 3193 3194 if (!equal(a[key], b[key])) return false; 3195 } 3196 3197 return true; 3198 } 3199 3200 // true if both NaN, false otherwise 3201 return a!==a && b!==b; 3202}; 3203 3204 3205/***/ }), 3206
vendor: 11,772 bytes, lines 3207-3548
3207/***/ "./node_modules/kdbush/index.js": 3208/*!**************************************!*\ 3209 !*** ./node_modules/kdbush/index.js ***! 3210 \**************************************/ 3211/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 3212 3213"use strict"; 3214__webpack_require__.r(__webpack_exports__); 3215/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3216/* harmony export */ "default": () => (/* binding */ KDBush) 3217/* harmony export */ }); 3218 3219const ARRAY_TYPES = [ 3220 Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, 3221 Int32Array, Uint32Array, Float32Array, Float64Array 3222]; 3223 3224/** @typedef {Int8ArrayConstructor | Uint8ArrayConstructor | Uint8ClampedArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor | Float64ArrayConstructor} TypedArrayConstructor */ 3225 3226const VERSION = 1; // serialized format version 3227const HEADER_SIZE = 8; 3228 3229class KDBush { 3230 3231 /** 3232 * Creates an index from raw `ArrayBuffer` data. 3233 * @param {ArrayBuffer} data 3234 */ 3235 static from(data) { 3236 if (!(data instanceof ArrayBuffer)) { 3237 throw new Error('Data must be an instance of ArrayBuffer.'); 3238 } 3239 const [magic, versionAndType] = new Uint8Array(data, 0, 2); 3240 if (magic !== 0xdb) { 3241 throw new Error('Data does not appear to be in a KDBush format.'); 3242 } 3243 const version = versionAndType >> 4; 3244 if (version !== VERSION) { 3245 throw new Error(`Got v${version} data when expected v${VERSION}.`); 3246 } 3247 const ArrayType = ARRAY_TYPES[versionAndType & 0x0f]; 3248 if (!ArrayType) { 3249 throw new Error('Unrecognized array type.'); 3250 } 3251 const [nodeSize] = new Uint16Array(data, 2, 1); 3252 const [numItems] = new Uint32Array(data, 4, 1); 3253 3254 return new KDBush(numItems, nodeSize, ArrayType, data); 3255 } 3256 3257 /** 3258 * Creates an index that will hold a given number of items. 3259 * @param {number} numItems 3260 * @param {number} [nodeSize=64] Size of the KD-tree node (64 by default). 3261 * @param {TypedArrayConstructor} [ArrayType=Float64Array] The array type used for coordinates storage (`Float64Array` by default). 3262 * @param {ArrayBuffer} [data] (For internal use only) 3263 */ 3264 constructor(numItems, nodeSize = 64, ArrayType = Float64Array, data) { 3265 if (isNaN(numItems) || numItems < 0) throw new Error(`Unpexpected numItems value: ${numItems}.`); 3266 3267 this.numItems = +numItems; 3268 this.nodeSize = Math.min(Math.max(+nodeSize, 2), 65535); 3269 this.ArrayType = ArrayType; 3270 this.IndexArrayType = numItems < 65536 ? Uint16Array : Uint32Array; 3271 3272 const arrayTypeIndex = ARRAY_TYPES.indexOf(this.ArrayType); 3273 const coordsByteSize = numItems * 2 * this.ArrayType.BYTES_PER_ELEMENT; 3274 const idsByteSize = numItems * this.IndexArrayType.BYTES_PER_ELEMENT; 3275 const padCoords = (8 - idsByteSize % 8) % 8; 3276 3277 if (arrayTypeIndex < 0) { 3278 throw new Error(`Unexpected typed array class: ${ArrayType}.`); 3279 } 3280 3281 if (data && (data instanceof ArrayBuffer)) { // reconstruct an index from a buffer 3282 this.data = data; 3283 this.ids = new this.IndexArrayType(this.data, HEADER_SIZE, numItems); 3284 this.coords = new this.ArrayType(this.data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2); 3285 this._pos = numItems * 2; 3286 this._finished = true; 3287 } else { // initialize a new index 3288 this.data = new ArrayBuffer(HEADER_SIZE + coordsByteSize + idsByteSize + padCoords); 3289 this.ids = new this.IndexArrayType(this.data, HEADER_SIZE, numItems); 3290 this.coords = new this.ArrayType(this.data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2); 3291 this._pos = 0; 3292 this._finished = false; 3293 3294 // set header 3295 new Uint8Array(this.data, 0, 2).set([0xdb, (VERSION << 4) + arrayTypeIndex]); 3296 new Uint16Array(this.data, 2, 1)[0] = nodeSize; 3297 new Uint32Array(this.data, 4, 1)[0] = numItems; 3298 } 3299 } 3300 3301 /** 3302 * Add a point to the index. 3303 * @param {number} x 3304 * @param {number} y 3305 * @returns {number} An incremental index associated with the added item (starting from `0`). 3306 */ 3307 add(x, y) { 3308 const index = this._pos >> 1; 3309 this.ids[index] = index; 3310 this.coords[this._pos++] = x; 3311 this.coords[this._pos++] = y; 3312 return index; 3313 } 3314 3315 /** 3316 * Perform indexing of the added points. 3317 */ 3318 finish() { 3319 const numAdded = this._pos >> 1; 3320 if (numAdded !== this.numItems) { 3321 throw new Error(`Added ${numAdded} items when expected ${this.numItems}.`); 3322 } 3323 // kd-sort both arrays for efficient search 3324 sort(this.ids, this.coords, this.nodeSize, 0, this.numItems - 1, 0); 3325 3326 this._finished = true; 3327 return this; 3328 } 3329 3330 /** 3331 * Search the index for items within a given bounding box. 3332 * @param {number} minX 3333 * @param {number} minY 3334 * @param {number} maxX 3335 * @param {number} maxY 3336 * @returns {number[]} An array of indices correponding to the found items. 3337 */ 3338 range(minX, minY, maxX, maxY) { 3339 if (!this._finished) throw new Error('Data not yet indexed - call index.finish().'); 3340 3341 const {ids, coords, nodeSize} = this; 3342 const stack = [0, ids.length - 1, 0]; 3343 const result = []; 3344 3345 // recursively search for items in range in the kd-sorted arrays 3346 while (stack.length) { 3347 const axis = stack.pop() || 0; 3348 const right = stack.pop() || 0; 3349 const left = stack.pop() || 0; 3350 3351 // if we reached "tree node", search linearly 3352 if (right - left <= nodeSize) { 3353 for (let i = left; i <= right; i++) { 3354 const x = coords[2 * i]; 3355 const y = coords[2 * i + 1]; 3356 if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[i]); 3357 } 3358 continue; 3359 } 3360 3361 // otherwise find the middle index 3362 const m = (left + right) >> 1; 3363 3364 // include the middle item if it's in range 3365 const x = coords[2 * m]; 3366 const y = coords[2 * m + 1]; 3367 if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[m]); 3368 3369 // queue search in halves that intersect the query 3370 if (axis === 0 ? minX <= x : minY <= y) { 3371 stack.push(left); 3372 stack.push(m - 1); 3373 stack.push(1 - axis); 3374 } 3375 if (axis === 0 ? maxX >= x : maxY >= y) { 3376 stack.push(m + 1); 3377 stack.push(right); 3378 stack.push(1 - axis); 3379 } 3380 } 3381 3382 return result; 3383 } 3384 3385 /** 3386 * Search the index for items within a given radius. 3387 * @param {number} qx 3388 * @param {number} qy 3389 * @param {number} r Query radius. 3390 * @returns {number[]} An array of indices correponding to the found items. 3391 */ 3392 within(qx, qy, r) { 3393 if (!this._finished) throw new Error('Data not yet indexed - call index.finish().'); 3394 3395 const {ids, coords, nodeSize} = this; 3396 const stack = [0, ids.length - 1, 0]; 3397 const result = []; 3398 const r2 = r * r; 3399 3400 // recursively search for items within radius in the kd-sorted arrays 3401 while (stack.length) { 3402 const axis = stack.pop() || 0; 3403 const right = stack.pop() || 0; 3404 const left = stack.pop() || 0; 3405 3406 // if we reached "tree node", search linearly 3407 if (right - left <= nodeSize) { 3408 for (let i = left; i <= right; i++) { 3409 if (sqDist(coords[2 * i], coords[2 * i + 1], qx, qy) <= r2) result.push(ids[i]); 3410 } 3411 continue; 3412 } 3413 3414 // otherwise find the middle index 3415 const m = (left + right) >> 1; 3416 3417 // include the middle item if it's in range 3418 const x = coords[2 * m]; 3419 const y = coords[2 * m + 1]; 3420 if (sqDist(x, y, qx, qy) <= r2) result.push(ids[m]); 3421 3422 // queue search in halves that intersect the query 3423 if (axis === 0 ? qx - r <= x : qy - r <= y) { 3424 stack.push(left); 3425 stack.push(m - 1); 3426 stack.push(1 - axis); 3427 } 3428 if (axis === 0 ? qx + r >= x : qy + r >= y) { 3429 stack.push(m + 1); 3430 stack.push(right); 3431 stack.push(1 - axis); 3432 } 3433 } 3434 3435 return result; 3436 } 3437} 3438 3439/** 3440 * @param {Uint16Array | Uint32Array} ids 3441 * @param {InstanceType<TypedArrayConstructor>} coords 3442 * @param {number} nodeSize 3443 * @param {number} left 3444 * @param {number} right 3445 * @param {number} axis 3446 */ 3447function sort(ids, coords, nodeSize, left, right, axis) { 3448 if (right - left <= nodeSize) return; 3449 3450 const m = (left + right) >> 1; // middle index 3451 3452 // sort ids and coords around the middle index so that the halves lie 3453 // either left/right or top/bottom correspondingly (taking turns) 3454 select(ids, coords, m, left, right, axis); 3455 3456 // recursively kd-sort first half and second half on the opposite axis 3457 sort(ids, coords, nodeSize, left, m - 1, 1 - axis); 3458 sort(ids, coords, nodeSize, m + 1, right, 1 - axis); 3459} 3460 3461/** 3462 * Custom Floyd-Rivest selection algorithm: sort ids and coords so that 3463 * [left..k-1] items are smaller than k-th item (on either x or y axis) 3464 * @param {Uint16Array | Uint32Array} ids 3465 * @param {InstanceType<TypedArrayConstructor>} coords 3466 * @param {number} k 3467 * @param {number} left 3468 * @param {number} right 3469 * @param {number} axis 3470 */ 3471function select(ids, coords, k, left, right, axis) { 3472 3473 while (right > left) { 3474 if (right - left > 600) { 3475 const n = right - left + 1; 3476 const m = k - left + 1; 3477 const z = Math.log(n); 3478 const s = 0.5 * Math.exp(2 * z / 3); 3479 const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1); 3480 const newLeft = Math.max(left, Math.floor(k - m * s / n + sd)); 3481 const newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd)); 3482 select(ids, coords, k, newLeft, newRight, axis); 3483 } 3484 3485 const t = coords[2 * k + axis]; 3486 let i = left; 3487 let j = right; 3488 3489 swapItem(ids, coords, left, k); 3490 if (coords[2 * right + axis] > t) swapItem(ids, coords, left, right); 3491 3492 while (i < j) { 3493 swapItem(ids, coords, i, j); 3494 i++; 3495 j--; 3496 while (coords[2 * i + axis] < t) i++; 3497 while (coords[2 * j + axis] > t) j--; 3498 } 3499 3500 if (coords[2 * left + axis] === t) swapItem(ids, coords, left, j); 3501 else { 3502 j++; 3503 swapItem(ids, coords, j, right); 3504 } 3505 3506 if (j <= k) left = j + 1; 3507 if (k <= j) right = j - 1; 3508 } 3509} 3510 3511/** 3512 * @param {Uint16Array | Uint32Array} ids 3513 * @param {InstanceType<TypedArrayConstructor>} coords 3514 * @param {number} i 3515 * @param {number} j 3516 */ 3517function swapItem(ids, coords, i, j) { 3518 swap(ids, i, j); 3519 swap(coords, 2 * i, 2 * j); 3520 swap(coords, 2 * i + 1, 2 * j + 1); 3521} 3522 3523/** 3524 * @param {InstanceType<TypedArrayConstructor>} arr 3525 * @param {number} i 3526 * @param {number} j 3527 */ 3528function swap(arr, i, j) { 3529 const tmp = arr[i]; 3530 arr[i] = arr[j]; 3531 arr[j] = tmp; 3532} 3533 3534/** 3535 * @param {number} ax 3536 * @param {number} ay 3537 * @param {number} bx 3538 * @param {number} by 3539 */ 3540function sqDist(ax, ay, bx, by) { 3541 const dx = ax - bx; 3542 const dy = ay - by; 3543 return dx * dx + dy * dy; 3544} 3545 3546 3547/***/ }), 3548
vendor: 15,752 bytes, lines 3549-3987
3549/***/ "./node_modules/supercluster/index.js": 3550/*!********************************************!*\ 3551 !*** ./node_modules/supercluster/index.js ***! 3552 \********************************************/ 3553/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 3554 3555"use strict"; 3556__webpack_require__.r(__webpack_exports__); 3557/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3558/* harmony export */ "default": () => (/* binding */ Supercluster) 3559/* harmony export */ }); 3560/* harmony import */ var kdbush__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! kdbush */ "./node_modules/kdbush/index.js"); 3561 3562 3563 3564const defaultOptions = { 3565 minZoom: 0, // min zoom to generate clusters on 3566 maxZoom: 16, // max zoom level to cluster the points on 3567 minPoints: 2, // minimum points to form a cluster 3568 radius: 40, // cluster radius in pixels 3569 extent: 512, // tile extent (radius is calculated relative to it) 3570 nodeSize: 64, // size of the KD-tree leaf node, affects performance 3571 log: false, // whether to log timing info 3572 3573 // whether to generate numeric ids for input features (in vector tiles) 3574 generateId: false, 3575 3576 // a reduce function for calculating custom cluster properties 3577 reduce: null, // (accumulated, props) => { accumulated.sum += props.sum; } 3578 3579 // properties to use for individual points when running the reducer 3580 map: props => props // props => ({sum: props.my_value}) 3581}; 3582 3583const fround = Math.fround || (tmp => ((x) => { tmp[0] = +x; return tmp[0]; }))(new Float32Array(1)); 3584 3585const OFFSET_ZOOM = 2; 3586const OFFSET_ID = 3; 3587const OFFSET_PARENT = 4; 3588const OFFSET_NUM = 5; 3589const OFFSET_PROP = 6; 3590 3591class Supercluster { 3592 constructor(options) { 3593 this.options = Object.assign(Object.create(defaultOptions), options); 3594 this.trees = new Array(this.options.maxZoom + 1); 3595 this.stride = this.options.reduce ? 7 : 6; 3596 this.clusterProps = []; 3597 } 3598 3599 load(points) { 3600 const {log, minZoom, maxZoom} = this.options; 3601 3602 if (log) console.time('total time'); 3603 3604 const timerId = `prepare ${ points.length } points`; 3605 if (log) console.time(timerId); 3606 3607 this.points = points; 3608 3609 // generate a cluster object for each point and index input points into a KD-tree 3610 const data = []; 3611 3612 for (let i = 0; i < points.length; i++) { 3613 const p = points[i]; 3614 if (!p.geometry) continue; 3615 3616 const [lng, lat] = p.geometry.coordinates; 3617 const x = fround(lngX(lng)); 3618 const y = fround(latY(lat)); 3619 // store internal point/cluster data in flat numeric arrays for performance 3620 data.push( 3621 x, y, // projected point coordinates 3622 Infinity, // the last zoom the point was processed at 3623 i, // index of the source feature in the original input array 3624 -1, // parent cluster id 3625 1 // number of points in a cluster 3626 ); 3627 if (this.options.reduce) data.push(0); // noop 3628 } 3629 let tree = this.trees[maxZoom + 1] = this._createTree(data); 3630 3631 if (log) console.timeEnd(timerId); 3632 3633 // cluster points on max zoom, then cluster the results on previous zoom, etc.; 3634 // results in a cluster hierarchy across zoom levels 3635 for (let z = maxZoom; z >= minZoom; z--) { 3636 const now = +Date.now(); 3637 3638 // create a new set of clusters for the zoom and index them with a KD-tree 3639 tree = this.trees[z] = this._createTree(this._cluster(tree, z)); 3640 3641 if (log) console.log('z%d: %d clusters in %dms', z, tree.numItems, +Date.now() - now); 3642 } 3643 3644 if (log) console.timeEnd('total time'); 3645 3646 return this; 3647 } 3648 3649 getClusters(bbox, zoom) { 3650 let minLng = ((bbox[0] + 180) % 360 + 360) % 360 - 180; 3651 const minLat = Math.max(-90, Math.min(90, bbox[1])); 3652 let maxLng = bbox[2] === 180 ? 180 : ((bbox[2] + 180) % 360 + 360) % 360 - 180; 3653 const maxLat = Math.max(-90, Math.min(90, bbox[3])); 3654 3655 if (bbox[2] - bbox[0] >= 360) { 3656 minLng = -180; 3657 maxLng = 180; 3658 } else if (minLng > maxLng) { 3659 const easternHem = this.getClusters([minLng, minLat, 180, maxLat], zoom); 3660 const westernHem = this.getClusters([-180, minLat, maxLng, maxLat], zoom); 3661 return easternHem.concat(westernHem); 3662 } 3663 3664 const tree = this.trees[this._limitZoom(zoom)]; 3665 const ids = tree.range(lngX(minLng), latY(maxLat), lngX(maxLng), latY(minLat)); 3666 const data = tree.data; 3667 const clusters = []; 3668 for (const id of ids) { 3669 const k = this.stride * id; 3670 clusters.push(data[k + OFFSET_NUM] > 1 ? getClusterJSON(data, k, this.clusterProps) : this.points[data[k + OFFSET_ID]]); 3671 } 3672 return clusters; 3673 } 3674 3675 getChildren(clusterId) { 3676 const originId = this._getOriginId(clusterId); 3677 const originZoom = this._getOriginZoom(clusterId); 3678 const errorMsg = 'No cluster with the specified id.'; 3679 3680 const tree = this.trees[originZoom]; 3681 if (!tree) throw new Error(errorMsg); 3682 3683 const data = tree.data; 3684 if (originId * this.stride >= data.length) throw new Error(errorMsg); 3685 3686 const r = this.options.radius / (this.options.extent * Math.pow(2, originZoom - 1)); 3687 const x = data[originId * this.stride]; 3688 const y = data[originId * this.stride + 1]; 3689 const ids = tree.within(x, y, r); 3690 const children = []; 3691 for (const id of ids) { 3692 const k = id * this.stride; 3693 if (data[k + OFFSET_PARENT] === clusterId) { 3694 children.push(data[k + OFFSET_NUM] > 1 ? getClusterJSON(data, k, this.clusterProps) : this.points[data[k + OFFSET_ID]]); 3695 } 3696 } 3697 3698 if (children.length === 0) throw new Error(errorMsg); 3699 3700 return children; 3701 } 3702 3703 getLeaves(clusterId, limit, offset) { 3704 limit = limit || 10; 3705 offset = offset || 0; 3706 3707 const leaves = []; 3708 this._appendLeaves(leaves, clusterId, limit, offset, 0); 3709 3710 return leaves; 3711 } 3712 3713 getTile(z, x, y) { 3714 const tree = this.trees[this._limitZoom(z)]; 3715 const z2 = Math.pow(2, z); 3716 const {extent, radius} = this.options; 3717 const p = radius / extent; 3718 const top = (y - p) / z2; 3719 const bottom = (y + 1 + p) / z2; 3720 3721 const tile = { 3722 features: [] 3723 }; 3724 3725 this._addTileFeatures( 3726 tree.range((x - p) / z2, top, (x + 1 + p) / z2, bottom), 3727 tree.data, x, y, z2, tile); 3728 3729 if (x === 0) { 3730 this._addTileFeatures( 3731 tree.range(1 - p / z2, top, 1, bottom), 3732 tree.data, z2, y, z2, tile); 3733 } 3734 if (x === z2 - 1) { 3735 this._addTileFeatures( 3736 tree.range(0, top, p / z2, bottom), 3737 tree.data, -1, y, z2, tile); 3738 } 3739 3740 return tile.features.length ? tile : null; 3741 } 3742 3743 getClusterExpansionZoom(clusterId) { 3744 let expansionZoom = this._getOriginZoom(clusterId) - 1; 3745 while (expansionZoom <= this.options.maxZoom) { 3746 const children = this.getChildren(clusterId); 3747 expansionZoom++; 3748 if (children.length !== 1) break; 3749 clusterId = children[0].properties.cluster_id; 3750 } 3751 return expansionZoom; 3752 } 3753 3754 _appendLeaves(result, clusterId, limit, offset, skipped) { 3755 const children = this.getChildren(clusterId); 3756 3757 for (const child of children) { 3758 const props = child.properties; 3759 3760 if (props && props.cluster) { 3761 if (skipped + props.point_count <= offset) { 3762 // skip the whole cluster 3763 skipped += props.point_count; 3764 } else { 3765 // enter the cluster 3766 skipped = this._appendLeaves(result, props.cluster_id, limit, offset, skipped); 3767 // exit the cluster 3768 } 3769 } else if (skipped < offset) { 3770 // skip a single point 3771 skipped++; 3772 } else { 3773 // add a single point 3774 result.push(child); 3775 } 3776 if (result.length === limit) break; 3777 } 3778 3779 return skipped; 3780 } 3781 3782 _createTree(data) { 3783 const tree = new kdbush__WEBPACK_IMPORTED_MODULE_0__["default"](data.length / this.stride | 0, this.options.nodeSize, Float32Array); 3784 for (let i = 0; i < data.length; i += this.stride) tree.add(data[i], data[i + 1]); 3785 tree.finish(); 3786 tree.data = data; 3787 return tree; 3788 } 3789 3790 _addTileFeatures(ids, data, x, y, z2, tile) { 3791 for (const i of ids) { 3792 const k = i * this.stride; 3793 const isCluster = data[k + OFFSET_NUM] > 1; 3794 3795 let tags, px, py; 3796 if (isCluster) { 3797 tags = getClusterProperties(data, k, this.clusterProps); 3798 px = data[k]; 3799 py = data[k + 1]; 3800 } else { 3801 const p = this.points[data[k + OFFSET_ID]]; 3802 tags = p.properties; 3803 const [lng, lat] = p.geometry.coordinates; 3804 px = lngX(lng); 3805 py = latY(lat); 3806 } 3807 3808 const f = { 3809 type: 1, 3810 geometry: [[ 3811 Math.round(this.options.extent * (px * z2 - x)), 3812 Math.round(this.options.extent * (py * z2 - y)) 3813 ]], 3814 tags 3815 }; 3816 3817 // assign id 3818 let id; 3819 if (isCluster || this.options.generateId) { 3820 // optionally generate id for points 3821 id = data[k + OFFSET_ID]; 3822 } else { 3823 // keep id if already assigned 3824 id = this.points[data[k + OFFSET_ID]].id; 3825 } 3826 3827 if (id !== undefined) f.id = id; 3828 3829 tile.features.push(f); 3830 } 3831 } 3832 3833 _limitZoom(z) { 3834 return Math.max(this.options.minZoom, Math.min(Math.floor(+z), this.options.maxZoom + 1)); 3835 } 3836 3837 _cluster(tree, zoom) { 3838 const {radius, extent, reduce, minPoints} = this.options; 3839 const r = radius / (extent * Math.pow(2, zoom)); 3840 const data = tree.data; 3841 const nextData = []; 3842 const stride = this.stride; 3843 3844 // loop through each point 3845 for (let i = 0; i < data.length; i += stride) { 3846 // if we've already visited the point at this zoom level, skip it 3847 if (data[i + OFFSET_ZOOM] <= zoom) continue; 3848 data[i + OFFSET_ZOOM] = zoom; 3849 3850 // find all nearby points 3851 const x = data[i]; 3852 const y = data[i + 1]; 3853 const neighborIds = tree.within(data[i], data[i + 1], r); 3854 3855 const numPointsOrigin = data[i + OFFSET_NUM]; 3856 let numPoints = numPointsOrigin; 3857 3858 // count the number of points in a potential cluster 3859 for (const neighborId of neighborIds) { 3860 const k = neighborId * stride; 3861 // filter out neighbors that are already processed 3862 if (data[k + OFFSET_ZOOM] > zoom) numPoints += data[k + OFFSET_NUM]; 3863 } 3864 3865 // if there were neighbors to merge, and there are enough points to form a cluster 3866 if (numPoints > numPointsOrigin && numPoints >= minPoints) { 3867 let wx = x * numPointsOrigin; 3868 let wy = y * numPointsOrigin; 3869 3870 let clusterProperties; 3871 let clusterPropIndex = -1; 3872 3873 // encode both zoom and point index on which the cluster originated -- offset by total length of features 3874 const id = ((i / stride | 0) << 5) + (zoom + 1) + this.points.length; 3875 3876 for (const neighborId of neighborIds) { 3877 const k = neighborId * stride; 3878 3879 if (data[k + OFFSET_ZOOM] <= zoom) continue; 3880 data[k + OFFSET_ZOOM] = zoom; // save the zoom (so it doesn't get processed twice) 3881 3882 const numPoints2 = data[k + OFFSET_NUM]; 3883 wx += data[k] * numPoints2; // accumulate coordinates for calculating weighted center 3884 wy += data[k + 1] * numPoints2; 3885 3886 data[k + OFFSET_PARENT] = id; 3887 3888 if (reduce) { 3889 if (!clusterProperties) { 3890 clusterProperties = this._map(data, i, true); 3891 clusterPropIndex = this.clusterProps.length; 3892 this.clusterProps.push(clusterProperties); 3893 } 3894 reduce(clusterProperties, this._map(data, k)); 3895 } 3896 } 3897 3898 data[i + OFFSET_PARENT] = id; 3899 nextData.push(wx / numPoints, wy / numPoints, Infinity, id, -1, numPoints); 3900 if (reduce) nextData.push(clusterPropIndex); 3901 3902 } else { // left points as unclustered 3903 for (let j = 0; j < stride; j++) nextData.push(data[i + j]); 3904 3905 if (numPoints > 1) { 3906 for (const neighborId of neighborIds) { 3907 const k = neighborId * stride; 3908 if (data[k + OFFSET_ZOOM] <= zoom) continue; 3909 data[k + OFFSET_ZOOM] = zoom; 3910 for (let j = 0; j < stride; j++) nextData.push(data[k + j]); 3911 } 3912 } 3913 } 3914 } 3915 3916 return nextData; 3917 } 3918 3919 // get index of the point from which the cluster originated 3920 _getOriginId(clusterId) { 3921 return (clusterId - this.points.length) >> 5; 3922 } 3923 3924 // get zoom of the point from which the cluster originated 3925 _getOriginZoom(clusterId) { 3926 return (clusterId - this.points.length) % 32; 3927 } 3928 3929 _map(data, i, clone) { 3930 if (data[i + OFFSET_NUM] > 1) { 3931 const props = this.clusterProps[data[i + OFFSET_PROP]]; 3932 return clone ? Object.assign({}, props) : props; 3933 } 3934 const original = this.points[data[i + OFFSET_ID]].properties; 3935 const result = this.options.map(original); 3936 return clone && result === original ? Object.assign({}, result) : result; 3937 } 3938} 3939 3940function getClusterJSON(data, i, clusterProps) { 3941 return { 3942 type: 'Feature', 3943 id: data[i + OFFSET_ID], 3944 properties: getClusterProperties(data, i, clusterProps), 3945 geometry: { 3946 type: 'Point', 3947 coordinates: [xLng(data[i]), yLat(data[i + 1])] 3948 } 3949 }; 3950} 3951 3952function getClusterProperties(data, i, clusterProps) { 3953 const count = data[i + OFFSET_NUM]; 3954 const abbrev = 3955 count >= 10000 ? `${Math.round(count / 1000) }k` : 3956 count >= 1000 ? `${Math.round(count / 100) / 10 }k` : count; 3957 const propIndex = data[i + OFFSET_PROP]; 3958 const properties = propIndex === -1 ? {} : Object.assign({}, clusterProps[propIndex]); 3959 return Object.assign(properties, { 3960 cluster: true, 3961 cluster_id: data[i + OFFSET_ID], 3962 point_count: count, 3963 point_count_abbreviated: abbrev 3964 }); 3965} 3966 3967// longitude/latitude to spherical mercator in [0..1] range 3968function lngX(lng) { 3969 return lng / 360 + 0.5; 3970} 3971function latY(lat) { 3972 const sin = Math.sin(lat * Math.PI / 180); 3973 const y = (0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI); 3974 return y < 0 ? 0 : y > 1 ? 1 : y; 3975} 3976 3977// spherical mercator to longitude/latitude 3978function xLng(x) { 3979 return (x - 0.5) * 360; 3980} 3981function yLat(y) { 3982 const y2 = (180 - y * 360) * Math.PI / 180; 3983 return 360 * Math.atan(Math.exp(y2)) / Math.PI - 90; 3984} 3985 3986 3987/***/ })
vendor: 4,814 bytes, lines 3987-4084
3987 3988 3989/******/ }); 3990/************************************************************************/ 3991/******/ // The module cache 3992/******/ var __webpack_module_cache__ = {}; 3993/******/ 3994/******/ // The require function 3995/******/ function __webpack_require__(moduleId) { 3996/******/ // Check if module is in cache 3997/******/ var cachedModule = __webpack_module_cache__[moduleId]; 3998/******/ if (cachedModule !== undefined) { 3999/******/ return cachedModule.exports; 4000/******/ } 4001/******/ // Create a new module (and put it into the cache) 4002/******/ var module = __webpack_module_cache__[moduleId] = { 4003/******/ id: moduleId, 4004/******/ loaded: false, 4005/******/ exports: {} 4006/******/ }; 4007/******/ 4008/******/ // Execute the module function 4009/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 4010/******/ 4011/******/ // Flag the module as loaded 4012/******/ module.loaded = true; 4013/******/ 4014/******/ // Return the exports of the module 4015/******/ return module.exports; 4016/******/ } 4017/******/ 4018/************************************************************************/ 4019/******/ /* webpack/runtime/compat get default export */ 4020/******/ (() => { 4021/******/ // getDefaultExport function for compatibility with non-harmony modules 4022/******/ __webpack_require__.n = (module) => { 4023/******/ var getter = module && module.__esModule ? 4024/******/ () => (module['default']) : 4025/******/ () => (module); 4026/******/ __webpack_require__.d(getter, { a: getter }); 4027/******/ return getter; 4028/******/ }; 4029/******/ })(); 4030/******/ 4031/******/ /* webpack/runtime/define property getters */ 4032/******/ (() => { 4033/******/ // define getter functions for harmony exports 4034/******/ __webpack_require__.d = (exports, definition) => { 4035/******/ for(var key in definition) { 4036/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 4037/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 4038/******/ } 4039/******/ } 4040/******/ }; 4041/******/ })(); 4042/******/ 4043/******/ /* webpack/runtime/hasOwnProperty shorthand */ 4044/******/ (() => { 4045/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 4046/******/ })(); 4047/******/ 4048/******/ /* webpack/runtime/make namespace object */ 4049/******/ (() => { 4050/******/ // define __esModule on exports 4051/******/ __webpack_require__.r = (exports) => { 4052/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 4053/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 4054/******/ } 4055/******/ Object.defineProperty(exports, '__esModule', { value: true }); 4056/******/ }; 4057/******/ })(); 4058/******/ 4059/******/ /* webpack/runtime/node module decorator */ 4060/******/ (() => { 4061/******/ __webpack_require__.nmd = (module) => { 4062/******/ module.paths = []; 4063/******/ if (!module.children) module.children = []; 4064/******/ return module; 4065/******/ }; 4066/******/ })(); 4067/******/ 4068/************************************************************************/ 4069var __webpack_exports__ = {}; 4070// This entry needs to be wrapped in an IIFE because it needs to be in strict mode. 4071(() => { 4072"use strict"; 4073/*!********************!*\ 4074 !*** ./js/main.js ***! 4075 \********************/ 4076__webpack_require__.r(__webpack_exports__); 4077/* harmony import */ var _functions_map__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./functions/map */ "./js/functions/map.js"); 4078 4079(0,_functions_map__WEBPACK_IMPORTED_MODULE_0__["default"])(); 4080})(); 4081 4082/******/ })() 4083; 4084//# sourceMappingURL=data:application/json;charset=utf-8;base64,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BQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsMkJBQTJCO0FBQ3ZELDJCQUEyQiwrQkFBK0I7QUFDMUQ7QUFDQSw2Q0FBNkMsa0JBQWtCO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7VUN2YUE7VUFDQTs7VUFFQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTs7VUFFQTtVQUNBOztVQUVBO1VBQ0E7O1VBRUE7VUFDQTtVQUNBOzs7OztXQ3pCQTtXQUNBO1dBQ0E7V0FDQTtXQUNBO1dBQ0EsaUNBQWlDLFdBQVc7V0FDNUM7V0FDQTs7Ozs7V0NQQTtXQUNBO1dBQ0E7V0FDQTtXQUNBLHlDQUF5Qyx3Q0FBd0M7V0FDakY7V0FDQTtXQUNBOzs7OztXQ1BBOzs7OztXQ0FBO1dBQ0E7V0FDQTtXQUNBLHVEQUF1RCxpQkFBaUI7V0FDeEU7V0FDQSxnREFBZ0QsYUFBYTtXQUM3RDs7Ozs7V0NOQTtXQUNBO1dBQ0E7V0FDQTtXQUNBOzs7Ozs7Ozs7Ozs7O0FDSndDO0FBRXhDOUosMERBQVMsQ0FBQyxDQUFDLEMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9ibGFua28tbWFwLy4vbm9kZV9tb2R1bGVzL0Bnb29nbGVtYXBzL21hcmtlcmNsdXN0ZXJlci9kaXN0L2luZGV4LmVzbS5qcyIsIndlYnBhY2s6Ly9ibGFua28tbWFwLy4vanMvZnVuY3Rpb25zL0JvdHRvbVNoZWV0LmpzIiwid2VicGFjazovL2JsYW5rby1tYXAvLi9qcy9mdW5jdGlvbnMvTWFwVWkuanMiLCJ3ZWJwYWNrOi8vYmxhbmtvLW1hcC8uL2pzL2Z1bmN0aW9ucy9odW5kcmVkVkguanMiLCJ3ZWJwYWNrOi8vYmxhbmtvLW1hcC8uL2pzL2Z1bmN0aW9ucy9tYXAuanMiLCJ3ZWJwYWNrOi8vYmxhbmtvLW1hcC8uL2pzL2Z1bmN0aW9ucy9tYXBMb2NhdGlvbk1hcmtlci5qcyIsIndlYnBhY2s6Ly9ibGFua28tbWFwLy4vanMvZnVuY3Rpb25zL21hcE1hbmFnZXIuanMiLCJ3ZWJwYWNrOi8vYmxhbmtvLW1hcC8uL2pzL2Z1bmN0aW9ucy9tYXBNYXJrZXIuanMiLCJ3ZWJwYWNrOi8vYmxhbmtvLW1hcC8uL2pzL2Z1bmN0aW9ucy9tYXBNYXJrZXJDbHVzdGVyLmpzIiwid2VicGFjazovL2JsYW5rby1tYXAvLi9qcy9mdW5jdGlvbnMvbWFwUGFuZWxzLmpzIiwid2VicGFjazovL2JsYW5rby1tYXAvLi9qcy9mdW5jdGlvbnMvbWFwU3R5bGUuanMiLCJ3ZWJwYWNrOi8vYmxhbmtvLW1hcC8uL2pzL2Z1bmN0aW9ucy9tYXBVcmwuanMiLCJ3ZWJwYWNrOi8vYmxhbmtvLW1hcC8uL2pzL2Z1bmN0aW9ucy9tYXBVdGlscy5qcyIsIndlYnBhY2s6Ly9ibGFua28tbWFwLy4vanMvcGx1Z2lucy5qcyIsIndlYnBhY2s6Ly9ibGFua28tbWFwLy4vanMvdmVuZG9yL29ic2VydmVyLm1pbi5qcyIsIndlYnBhY2s6Ly9ibGFua28tbWFwLy4vbm9kZV9tb2R1bGVzL2Zhc3QtZGVlcC1lcXVhbC9pbmRleC5qcyIsIndlYnBhY2s6Ly9ibGFua28tbWFwLy4vbm9kZV9tb2R1bGVzL2tkYnVzaC9pbmRleC5qcyIsIndlYnBhY2s6Ly9ibGFua28tbWFwLy4vbm9kZV9tb2R1bGVzL3N1cGVyY2x1c3Rlci9pbmRleC5qcyIsIndlYnBhY2s6Ly9ibGFua28tbWFwL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL2JsYW5rby1tYXAvd2VicGFjay9ydW50aW1lL2NvbXBhdCBnZXQgZGVmYXVsdCBleHBvcnQiLCJ3ZWJwYWNrOi8vYmxhbmtvLW1hcC93ZWJwYWNrL3J1bnRpbWUvZGVmaW5lIHByb3BlcnR5IGdldHRlcnMiLCJ3ZWJwYWNrOi8vYmxhbmtvLW1hcC93ZWJwYWNrL3J1bnRpbWUvaGFzT3duUHJvcGVydHkgc2hvcnRoYW5kIiwid2VicGFjazovL2JsYW5rby1tYXAvd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly9ibGFua28tbWFwL3dlYnBhY2svcnVudGltZS9ub2RlIG1vZHVsZSBkZWNvcmF0b3IiLCJ3ZWJwYWNrOi8vYmxhbmtvLW1hcC8uL2pzL21haW4uanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGVxdWFsIGZyb20gJ2Zhc3QtZGVlcC1lcXVhbCc7XG5pbXBvcnQgU3VwZXJDbHVzdGVyIGZyb20gJ3N1cGVyY2x1c3Rlcic7XG5cbi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcblxyXG5mdW5jdGlvbiBfX3Jlc3QocywgZSkge1xyXG4gICAgdmFyIHQgPSB7fTtcclxuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgI
4084HRbcF0gPSBzW3BdO1xyXG4gICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDAgJiYgT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHMsIHBbaV0pKVxyXG4gICAgICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XHJcbiAgICAgICAgfVxyXG4gICAgcmV0dXJuIHQ7XHJcbn1cblxuLyoqXG4gKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLyoqXG4gKiB1dGlsIGNsYXNzIHRoYXQgY3JlYXRlcyBhIGNvbW1vbiBzZXQgb2YgY29udmVuaWVuY2UgZnVuY3Rpb25zIHRvIHdyYXBcbiAqIHNoYXJlZCBiZWhhdmlvciBvZiBBZHZhbmNlZCBNYXJrZXJzIGFuZCBNYXJrZXJzLlxuICovXG5jbGFzcyBNYXJrZXJVdGlscyB7XG4gICAgc3RhdGljIGlzQWR2YW5jZWRNYXJrZXJBdmFpbGFibGUobWFwKSB7XG4gICAgICAgIHJldHVybiAoZ29vZ2xlLm1hcHMubWFya2VyICYmXG4gICAgICAgICAgICBtYXAuZ2V0TWFwQ2FwYWJpbGl0aWVzKCkuaXNBZHZhbmNlZE1hcmtlcnNBdmFpbGFibGUgPT09IHRydWUpO1xuICAgIH1cbiAgICBzdGF0aWMgaXNBZHZhbmNlZE1hcmtlcihtYXJrZXIpIHtcbiAgICAgICAgcmV0dXJuIChnb29nbGUubWFwcy5tYXJrZXIgJiZcbiAgICAgICAgICAgIG1hcmtlciBpbnN0YW5jZW9mIGdvb2dsZS5tYXBzLm1hcmtlci5BZHZhbmNlZE1hcmtlckVsZW1lbnQpO1xuICAgIH1cbiAgICBzdGF0aWMgc2V0TWFwKG1hcmtlciwgbWFwKSB7XG4gICAgICAgIGlmICh0aGlzLmlzQWR2YW5jZWRNYXJrZXIobWFya2VyKSkge1xuICAgICAgICAgICAgbWFya2VyLm1hcCA9IG1hcDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG1hcmtlci5zZXRNYXAobWFwKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0UG9zaXRpb24obWFya2VyKSB7XG4gICAgICAgIC8vIFN1cGVyQ2x1c3RlckFsZ29yaXRobS5jYWxjdWxhdGUgZXhwZWN0cyBhIExhdExuZyBpbnN0YW5jZSBzbyB3ZSBmYWtlIGl0IGZvciBBZHYgTWFya2Vyc1xuICAgICAgICBpZiAodGhpcy5pc0FkdmFuY2VkTWFya2VyKG1hcmtlcikpIHtcbiAgICAgICAgICAgIGlmIChtYXJrZXIucG9zaXRpb24pIHtcbiAgICAgICAgICAgICAgICBpZiAobWFya2VyLnBvc2l0aW9uIGluc3RhbmNlb2YgZ29vZ2xlLm1hcHMuTGF0TG5nKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXJrZXIucG9zaXRpb247XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIHNpbmNlIHdlIGNhbid0IGNhc3QgdG8gTGF0TG5nTGl0ZXJhbCBmb3IgcmVhc29ucyA9KFxuICAgICAgICAgICAgICAgIGlmIChtYXJrZXIucG9zaXRpb24ubGF0ICYmIG1hcmtlci5wb3NpdGlvbi5sbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBnb29nbGUubWFwcy5MYXRMbmcobWFya2VyLnBvc2l0aW9uLmxhdCwgbWFya2VyLnBvc2l0aW9uLmxuZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBnb29nbGUubWFwcy5MYXRMbmcobnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1hcmtlci5nZXRQb3NpdGlvbigpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0VmlzaWJsZShtYXJrZXIpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNBZHZhbmNlZE1hcmtlcihtYXJrZXIpKSB7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEFsd2F5cyByZXR1cm4gdHJ1ZSBmb3IgQWR2YW5jZWQgTWFya2VycyBiZWNhdXNlIHRoZSBjbHVzdGVyZXJcbiAgICAgICAgICAgICAqIHVzZXMgZ2V0VmlzaWJsZSBhcyBhIHdheSB0byBjb3VudCBsZWdhY3kgbWFya2VycyBub3QgYXMgYW4gYWN0dWFsXG4gICAgICAgICAgICAgKiBpbmRpY2F0b3Igb2YgdmlzaWJpbGl0eSBmb3Igc29tZSByZWFzb24uIEV2ZW4gd2hlbiBtYXJrZXJzIGFyZSBoaWRkZW5cbiAgICAgICAgICAgICAqIE1hcmtlci5nZXRWaXNpYmxlIHJldHVybnMgYHRydWVgIGFuZCB0aGlzIGlzIHVzZWQgdG8gc2V0IHRoZSBtYXJrZXIgY291bnRcbiAgICAgICAgICAgICAqIG9uIHRoZSBjbHVzdGVyLiBTZWUgdGhlIGJlaGF2aW9yIG9mIENsdXN0ZXIuY291bnRcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1hcmtlci5nZXRWaXNpYmxlKCk7XG4gICAgfVxufVxuXG4vKipcbiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTENcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5jbGFzcyBDbHVzdGVyIHtcbiAgICBjb25zdHJ1Y3Rvcih7IG1hcmtlcnMsIHBvc2l0aW9uIH0pIHtcbiAgICAgICAgdGhpcy5tYXJrZXJzID0gbWFya2VycztcbiAgICAgICAgaWYgKHBvc2l0aW9uKSB7XG4gICAgICAgICAgICBpZiAocG9zaXRpb24gaW5zdGFuY2VvZiBnb29nbGUubWFwcy5MYXRMbmcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wb3NpdGlvbiA9IHBvc2l0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcG9zaXRpb24gPSBuZXcgZ29vZ2xlLm1hcHMuTGF0TG5nKHBvc2l0aW9uKTtcbiAgICAgICAgICAgI
4084H1cbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgYm91bmRzKCkge1xuICAgICAgICBpZiAodGhpcy5tYXJrZXJzLmxlbmd0aCA9PT0gMCAmJiAhdGhpcy5fcG9zaXRpb24pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBib3VuZHMgPSBuZXcgZ29vZ2xlLm1hcHMuTGF0TG5nQm91bmRzKHRoaXMuX3Bvc2l0aW9uLCB0aGlzLl9wb3NpdGlvbik7XG4gICAgICAgIGZvciAoY29uc3QgbWFya2VyIG9mIHRoaXMubWFya2Vycykge1xuICAgICAgICAgICAgYm91bmRzLmV4dGVuZChNYXJrZXJVdGlscy5nZXRQb3NpdGlvbihtYXJrZXIpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYm91bmRzO1xuICAgIH1cbiAgICBnZXQgcG9zaXRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wb3NpdGlvbiB8fCB0aGlzLmJvdW5kcy5nZXRDZW50ZXIoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjb3VudCBvZiAqKnZpc2libGUqKiBtYXJrZXJzLlxuICAgICAqL1xuICAgIGdldCBjb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFya2Vycy5maWx0ZXIoKG0pID0+IE1hcmtlclV0aWxzLmdldFZpc2libGUobSkpLmxlbmd0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgbWFya2VyIHRvIHRoZSBjbHVzdGVyLlxuICAgICAqL1xuICAgIHB1c2gobWFya2VyKSB7XG4gICAgICAgIHRoaXMubWFya2Vycy5wdXNoKG1hcmtlcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFudXAgcmVmZXJlbmNlcyBhbmQgcmVtb3ZlIG1hcmtlciBmcm9tIG1hcC5cbiAgICAgKi9cbiAgICBkZWxldGUoKSB7XG4gICAgICAgIGlmICh0aGlzLm1hcmtlcikge1xuICAgICAgICAgICAgTWFya2VyVXRpbHMuc2V0TWFwKHRoaXMubWFya2VyLCBudWxsKTtcbiAgICAgICAgICAgIHRoaXMubWFya2VyID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubWFya2Vycy5sZW5ndGggPSAwO1xuICAgIH1cbn1cblxuLyoqXG4gKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLyoqXG4gKiBSZXR1cm5zIHRoZSBtYXJrZXJzIHZpc2libGUgaW4gYSBwYWRkZWQgbWFwIHZpZXdwb3J0XG4gKlxuICogQHBhcmFtIG1hcFxuICogQHBhcmFtIG1hcENhbnZhc1Byb2plY3Rpb25cbiAqIEBwYXJhbSBtYXJrZXJzIFRoZSBsaXN0IG9mIG1hcmtlciB0byBmaWx0ZXJcbiAqIEBwYXJhbSB2aWV3cG9ydFBhZGRpbmdQaXhlbHMgVGhlIHBhZGRpbmcgaW4gcGl4ZWxcbiAqIEByZXR1cm5zIFRoZSBsaXN0IG9mIG1hcmtlcnMgaW4gdGhlIHBhZGRlZCB2aWV3cG9ydFxuICovXG5jb25zdCBmaWx0ZXJNYXJrZXJzVG9QYWRkZWRWaWV3cG9ydCA9IChtYXAsIG1hcENhbnZhc1Byb2plY3Rpb24sIG1hcmtlcnMsIHZpZXdwb3J0UGFkZGluZ1BpeGVscykgPT4ge1xuICAgIGNvbnN0IGV4dGVuZGVkTWFwQm91bmRzID0gZXh0ZW5kQm91bmRzVG9QYWRkZWRWaWV3cG9ydChtYXAuZ2V0Qm91bmRzKCksIG1hcENhbnZhc1Byb2plY3Rpb24sIHZpZXdwb3J0UGFkZGluZ1BpeGVscyk7XG4gICAgcmV0dXJuIG1hcmtlcnMuZmlsdGVyKChtYXJrZXIpID0+IGV4dGVuZGVkTWFwQm91bmRzLmNvbnRhaW5zKE1hcmtlclV0aWxzLmdldFBvc2l0aW9uKG1hcmtlcikpKTtcbn07XG4vKipcbiAqIEV4dGVuZHMgYSBib3VuZHMgYnkgYSBudW1iZXIgb2YgcGl4ZWxzIGluIGVhY2ggZGlyZWN0aW9uXG4gKi9cbmNvbnN0IGV4dGVuZEJvdW5kc1RvUGFkZGVkVmlld3BvcnQgPSAoYm91bmRzLCBwcm9qZWN0aW9uLCBudW1QaXhlbHMpID0+IHtcbiAgICBjb25zdCB7IG5vcnRoRWFzdCwgc291dGhXZXN0IH0gPSBsYXRMbmdCb3VuZHNUb1BpeGVsQm91bmRzKGJvdW5kcywgcHJvamVjdGlvbik7XG4gICAgY29uc3QgZXh0ZW5kZWRQaXhlbEJvdW5kcyA9IGV4dGVuZFBpeGVsQm91bmRzKHsgbm9ydGhFYXN0LCBzb3V0aFdlc3QgfSwgbnVtUGl4ZWxzKTtcbiAgICByZXR1cm4gcGl4ZWxCb3VuZHNUb0xhdExuZ0JvdW5kcyhleHRlbmRlZFBpeGVsQm91bmRzLCBwcm9qZWN0aW9uKTtcbn07XG4vKipcbiAqIEdldHMgdGhlIGV4dGVuZGVkIGJvdW5kcyBhcyBhIGJib3ggW3dlc3RMbmcsIHNvdXRoTGF0LCBlYXN0TG5nLCBub3J0aExhdF1cbiAqL1xuY29uc3QgZ2V0UGFkZGVkVmlld3BvcnQgPSAoYm91bmRzLCBwcm9qZWN0aW9uLCBwaXhlbHMpID0+IHtcbiAgICBjb25zdCBleHRlbmRlZCA9IGV4dGVuZEJvdW5kc1RvUGFkZGVkVmlld3BvcnQoYm91bmRzLCBwcm9qZWN0aW9uLCBwaXhlbHMpO1xuICAgIGNvbnN0IG5lID0gZXh0ZW5kZWQuZ2V0Tm9ydGhFYXN0KCk7XG4gICAgY29uc3Qgc3cgPSBleHRlbmRlZC5nZXRTb3V0aFdlc3QoKTtcbiAgICByZXR1cm4gW3N3LmxuZygpLCBzdy5sYXQoKSwgbmUubG5nKCksIG5lLmxhdCgpXTtcbn07XG4vKipcbiAqIFJldHVybnMgdGhlIGRpc3RhbmNlIGJldHdlZW4gMiBwb3NpdGlvbnMuXG4gKlxuICogQGhpZGRlblxuICovXG5jb25zdCBkaXN0YW5jZUJldHdlZW5Qb2ludHMgPSAocDEsIHAyKSA9PiB7XG4gICAgY29uc3QgUiA9IDYzNzE7IC8vIFJhZGl1cyBvZiB0aGUgRWFydGggaW4ga21cbiAgICBjb25zdCBkTGF0ID0gKChwMi5sYXQgLSBwMS5sYXQpICogTWF0aC5QSSkgLyAxODA7XG4gICAgY29uc3QgZExvbiA9ICgocDIubG5nIC0gcDEubG5nKSAqIE1hdGguUEkpIC8gMTgwO1xuICAgIGNvbnN0IHNpbkRMYXQgPSBNYXRoLnNpbihkTGF0IC8gMik7XG4gICAgY29uc3Qgc2luRExvb
4084iA9IE1hdGguc2luKGRMb24gLyAyKTtcbiAgICBjb25zdCBhID0gc2luRExhdCAqIHNpbkRMYXQgK1xuICAgICAgICBNYXRoLmNvcygocDEubGF0ICogTWF0aC5QSSkgLyAxODApICpcbiAgICAgICAgICAgIE1hdGguY29zKChwMi5sYXQgKiBNYXRoLlBJKSAvIDE4MCkgKlxuICAgICAgICAgICAgc2luRExvbiAqXG4gICAgICAgICAgICBzaW5ETG9uO1xuICAgIGNvbnN0IGMgPSAyICogTWF0aC5hdGFuMihNYXRoLnNxcnQoYSksIE1hdGguc3FydCgxIC0gYSkpO1xuICAgIHJldHVybiBSICogYztcbn07XG4vKipcbiAqIENvbnZlcnRzIGEgTGF0TG5nIGJvdW5kIHRvIHBpeGVscy5cbiAqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxhdExuZ0JvdW5kc1RvUGl4ZWxCb3VuZHMgPSAoYm91bmRzLCBwcm9qZWN0aW9uKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbm9ydGhFYXN0OiBwcm9qZWN0aW9uLmZyb21MYXRMbmdUb0RpdlBpeGVsKGJvdW5kcy5nZXROb3J0aEVhc3QoKSksXG4gICAgICAgIHNvdXRoV2VzdDogcHJvamVjdGlvbi5mcm9tTGF0TG5nVG9EaXZQaXhlbChib3VuZHMuZ2V0U291dGhXZXN0KCkpLFxuICAgIH07XG59O1xuLyoqXG4gKiBFeHRlbmRzIGEgcGl4ZWwgYm91bmRzIGJ5IG51bVBpeGVscyBpbiBhbGwgZGlyZWN0aW9ucy5cbiAqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGV4dGVuZFBpeGVsQm91bmRzID0gKHsgbm9ydGhFYXN0LCBzb3V0aFdlc3QgfSwgbnVtUGl4ZWxzKSA9PiB7XG4gICAgbm9ydGhFYXN0LnggKz0gbnVtUGl4ZWxzO1xuICAgIG5vcnRoRWFzdC55IC09IG51bVBpeGVscztcbiAgICBzb3V0aFdlc3QueCAtPSBudW1QaXhlbHM7XG4gICAgc291dGhXZXN0LnkgKz0gbnVtUGl4ZWxzO1xuICAgIHJldHVybiB7IG5vcnRoRWFzdCwgc291dGhXZXN0IH07XG59O1xuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHBpeGVsQm91bmRzVG9MYXRMbmdCb3VuZHMgPSAoeyBub3J0aEVhc3QsIHNvdXRoV2VzdCB9LCBwcm9qZWN0aW9uKSA9PiB7XG4gICAgY29uc3Qgc3cgPSBwcm9qZWN0aW9uLmZyb21EaXZQaXhlbFRvTGF0TG5nKHNvdXRoV2VzdCk7XG4gICAgY29uc3QgbmUgPSBwcm9qZWN0aW9uLmZyb21EaXZQaXhlbFRvTGF0TG5nKG5vcnRoRWFzdCk7XG4gICAgcmV0dXJuIG5ldyBnb29nbGUubWFwcy5MYXRMbmdCb3VuZHMoc3csIG5lKTtcbn07XG5cbi8qKlxuICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQ1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbi8qKlxuICogQGhpZGRlblxuICovXG5jbGFzcyBBYnN0cmFjdEFsZ29yaXRobSB7XG4gICAgY29uc3RydWN0b3IoeyBtYXhab29tID0gMTYgfSkge1xuICAgICAgICB0aGlzLm1heFpvb20gPSBtYXhab29tO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gYnlwYXNzIGNsdXN0ZXJpbmcgYmFzZWQgdXBvbiBzb21lIG1hcCBzdGF0ZSBzdWNoIGFzXG4gICAgICogem9vbSwgbnVtYmVyIG9mIG1hcmtlcnMsIGV0Yy5cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAgY2x1c3Rlcih7bWFya2VycywgbWFwfTogQWxnb3JpdGhtSW5wdXQpOiBDbHVzdGVyW10ge1xuICAgICAqICAgIGlmIChzaG91bGRCeXBhc3NDbHVzdGVyaW5nKG1hcCkpIHtcbiAgICAgKiAgICAgIHJldHVybiB0aGlzLm5vb3Aoe21hcmtlcnN9KVxuICAgICAqICAgIH1cbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgbm9vcCh7IG1hcmtlcnMsIH0pIHtcbiAgICAgICAgcmV0dXJuIG5vb3AobWFya2Vycyk7XG4gICAgfVxufVxuLyoqXG4gKiBBYnN0cmFjdCB2aWV3cG9ydCBhbGdvcml0aG0gcHJvdmVzIGEgY2xhc3MgdG8gZmlsdGVyIG1hcmtlcnMgYnkgYSBwYWRkZWRcbiAqIHZpZXdwb3J0LiBUaGlzIGlzIGEgY29tbW9uIG9wdGltaXphdGlvbi5cbiAqXG4gKiBAaGlkZGVuXG4gKi9cbmNsYXNzIEFic3RyYWN0Vmlld3BvcnRBbGdvcml0aG0gZXh0ZW5kcyBBYnN0cmFjdEFsZ29yaXRobSB7XG4gICAgY29uc3RydWN0b3IoX2EpIHtcbiAgICAgICAgdmFyIHsgdmlld3BvcnRQYWRkaW5nID0gNjAgfSA9IF9hLCBvcHRpb25zID0gX19yZXN0KF9hLCBbXCJ2aWV3cG9ydFBhZGRpbmdcIl0pO1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy52aWV3cG9ydFBhZGRpbmcgPSA2MDtcbiAgICAgICAgdGhpcy52aWV3cG9ydFBhZGRpbmcgPSB2aWV3cG9ydFBhZGRpbmc7XG4gICAgfVxuICAgIGNhbGN1bGF0ZSh7IG1hcmtlcnMsIG1hcCwgbWFwQ2FudmFzUHJvamVjdGlvbiwgfSkge1xuICAgICAgICBpZiAobWFwLmdldFpvb20oKSA+PSB0aGlzLm1heFpvb20pIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgY2x1c3RlcnM6IHRoaXMubm9vcCh7XG4gICAgICAgICAgICAgICAgICAgIG1hcmtlcnMsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgY2hhbmdlZDogZmFsc2UsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybi
4084B7XG4gICAgICAgICAgICBjbHVzdGVyczogdGhpcy5jbHVzdGVyKHtcbiAgICAgICAgICAgICAgICBtYXJrZXJzOiBmaWx0ZXJNYXJrZXJzVG9QYWRkZWRWaWV3cG9ydChtYXAsIG1hcENhbnZhc1Byb2plY3Rpb24sIG1hcmtlcnMsIHRoaXMudmlld3BvcnRQYWRkaW5nKSxcbiAgICAgICAgICAgICAgICBtYXAsXG4gICAgICAgICAgICAgICAgbWFwQ2FudmFzUHJvamVjdGlvbixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9O1xuICAgIH1cbn1cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBub29wID0gKG1hcmtlcnMpID0+IHtcbiAgICBjb25zdCBjbHVzdGVycyA9IG1hcmtlcnMubWFwKChtYXJrZXIpID0+IG5ldyBDbHVzdGVyKHtcbiAgICAgICAgcG9zaXRpb246IE1hcmtlclV0aWxzLmdldFBvc2l0aW9uKG1hcmtlciksXG4gICAgICAgIG1hcmtlcnM6IFttYXJrZXJdLFxuICAgIH0pKTtcbiAgICByZXR1cm4gY2x1c3RlcnM7XG59O1xuXG4vKipcbiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTENcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIFRoZSBkZWZhdWx0IEdyaWQgYWxnb3JpdGhtIGhpc3RvcmljYWxseSB1c2VkIGluIEdvb2dsZSBNYXBzIG1hcmtlclxuICogY2x1c3RlcmluZy5cbiAqXG4gKiBUaGUgR3JpZCBhbGdvcml0aG0gZG9lcyBub3QgaW1wbGVtZW50IGNhY2hpbmcgYW5kIG1hcmtlcnMgbWF5IGZsYXNoIGFzIHRoZVxuICogdmlld3BvcnQgY2hhbmdlcy4gSW5zdGVhZCB1c2Uge0BsaW5rIFN1cGVyQ2x1c3RlckFsZ29yaXRobX0uXG4gKi9cbmNsYXNzIEdyaWRBbGdvcml0aG0gZXh0ZW5kcyBBYnN0cmFjdFZpZXdwb3J0QWxnb3JpdGhtIHtcbiAgICBjb25zdHJ1Y3RvcihfYSkge1xuICAgICAgICB2Y
4084XIgeyBtYXhEaXN0YW5jZSA9IDQwMDAwLCBncmlkU2l6ZSA9IDQwIH0gPSBfYSwgb3B0aW9ucyA9IF9fcmVzdChfYSwgW1wibWF4RGlzdGFuY2VcIiwgXCJncmlkU2l6ZVwiXSk7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLmNsdXN0ZXJzID0gW107XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IHpvb206IC0xIH07XG4gICAgICAgIHRoaXMubWF4RGlzdGFuY2UgPSBtYXhEaXN0YW5jZTtcbiAgICAgICAgdGhpcy5ncmlkU2l6ZSA9IGdyaWRTaXplO1xuICAgIH1cbiAgICBjYWxjdWxhdGUoeyBtYXJrZXJzLCBtYXAsIG1hcENhbnZhc1Byb2plY3Rpb24sIH0pIHtcbiAgICAgICAgY29uc3Qgc3RhdGUgPSB7IHpvb206IG1hcC5nZXRab29tKCkgfTtcbiAgICAgICAgbGV0IGNoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuem9vbSA+PSB0aGlzLm1heFpvb20gJiYgc3RhdGUuem9vbSA+PSB0aGlzLm1heFpvb20pIDtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjaGFuZ2VkID0gIWVxdWFsKHRoaXMuc3RhdGUsIHN0YXRlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0YXRlID0gc3RhdGU7XG4gICAgICAgIGlmIChtYXAuZ2V0Wm9vbSgpID49IHRoaXMubWF4Wm9vbSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBjbHVzdGVyczogdGhpcy5ub29wKHtcbiAgICAgICAgICAgICAgICAgICAgbWFya2VycyxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBjaGFuZ2VkLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY2x1c3RlcnM6IHRoaXMuY2x1c3Rlcih7XG4gICAgICAgICAgICAgICAgbWFya2VyczogZmlsdGVyTWFya2Vyc1RvUGFkZGVkVmlld3BvcnQobWFwLCBtYXBDYW52YXNQcm9qZWN0aW9uLCBtYXJrZXJzLCB0aGlzLnZpZXdwb3J0UGFkZGluZyksXG4gICAgICAgICAgICAgICAgbWFwLFxuICAgICAgICAgICAgICAgIG1hcENhbnZhc1Byb2plY3Rpb24sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY2x1c3Rlcih7IG1hcmtlcnMsIG1hcCwgbWFwQ2FudmFzUHJvamVjdGlvbiwgfSkge1xuICAgICAgICB0aGlzLmNsdXN0ZXJzID0gW107XG4gICAgICAgIG1hcmtlcnMuZm9yRWFjaCgobWFya2VyKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFkZFRvQ2xvc2VzdENsdXN0ZXIobWFya2VyLCBtYXAsIG1hcENhbnZhc1Byb2plY3Rpb24pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2x1c3RlcnM7XG4gICAgfVxuICAgIGFkZFRvQ2xvc2VzdENsdXN0ZXIobWFya2VyLCBtYXAsIHByb2plY3Rpb24pIHtcbiAgICAgICAgbGV0IG1heERpc3RhbmNlID0gdGhpcy5tYXhEaXN0YW5jZTsgLy8gU29tZSBsYXJnZSBudW1iZXJcbiAgICAgICAgbGV0IGNsdXN0ZXIgPSBudWxsO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY2x1c3RlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IGNhbmRpZGF0ZSA9IHRoaXMuY2x1c3RlcnNbaV07XG4gICAgICAgICAgICBjb25zdCBkaXN0YW5jZSA9IGRpc3RhbmNlQmV0d2VlblBvaW50cyhjYW5kaWRhdGUuYm91bmRzLmdldENlbnRlcigpLnRvSlNPTigpLCBNYXJrZXJVdGlscy5nZXRQb3NpdGlvbihtYXJrZXIpLnRvSlNPTigpKTtcbiAgICAgICAgICAgIGlmIChkaXN0YW5jZSA8IG1heERpc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgbWF4RGlzdGFuY2UgPSBkaXN0YW5jZTtcbiAgICAgICAgICAgICAgICBjbHVzdGVyID0gY2FuZGlkYXRlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjbHVzdGVyICYmXG4gICAgICAgICAgICBleHRlbmRCb3VuZHNUb1BhZGRlZFZpZXdwb3J0KGNsdXN0ZXIuYm91bmRzLCBwcm9qZWN0aW9uLCB0aGlzLmdyaWRTaXplKS5jb250YWlucyhNYXJrZXJVdGlscy5nZXRQb3NpdGlvbihtYXJrZXIpKSkge1xuICAgICAgICAgICAgY2x1c3Rlci5wdXNoKG1hcmtlcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBjbHVzdGVyID0gbmV3IENsdXN0ZXIoeyBtYXJrZXJzOiBbbWFya2VyXSB9KTtcbiAgICAgICAgICAgIHRoaXMuY2x1c3RlcnMucHVzaChjbHVzdGVyKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLyoqXG4gKiBOb29wIGFsZ29yaXRobSBkb2VzIG5vdCBnZW5lcmF0ZSBhbnkgY2x1c3RlcnMgb3IgZmlsdGVyIG1hcmtlcnMgYnkgdGhlIGFuIGV4dGVuZGVkIHZpZXdwb3J0LlxuICovXG5jbGFzcyBOb29wQWxnb3JpdGhtIGV4dGVuZHMgQWJzdHJhY3RBbGdvcml0aG0ge1xuICAgIGNvbnN0cnVjdG9yKF9hKSB7XG4gICAgICAgIHZhciBvcHRpb25zID0gX19yZXN0KF9hLCBbXSk7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIH1cbiAgICBjYWxjdWxhdGUoeyBtYXJrZXJzLCBtY
4084XAsIG1hcENhbnZhc1Byb2plY3Rpb24sIH0pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNsdXN0ZXJzOiB0aGlzLmNsdXN0ZXIoeyBtYXJrZXJzLCBtYXAsIG1hcENhbnZhc1Byb2plY3Rpb24gfSksXG4gICAgICAgICAgICBjaGFuZ2VkOiBmYWxzZSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY2x1c3RlcihpbnB1dCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ub29wKGlucHV0KTtcbiAgICB9XG59XG5cbi8qKlxuICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQ1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbi8qKlxuICogQSB2ZXJ5IGZhc3QgSmF2YVNjcmlwdCBhbGdvcml0aG0gZm9yIGdlb3NwYXRpYWwgcG9pbnQgY2x1c3RlcmluZyB1c2luZyBLRCB0cmVlcy5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL3N1cGVyY2x1c3RlciBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBvcHRpb25zLlxuICovXG5jbGFzcyBTdXBlckNsdXN0ZXJBbGdvcml0aG0gZXh0ZW5kcyBBYnN0cmFjdEFsZ29yaXRobSB7XG4gICAgY29uc3RydWN0b3IoX2EpIHtcbiAgICAgICAgdmFyIHsgbWF4Wm9vbSwgcmFkaXVzID0gNjAgfSA9IF9hLCBvcHRpb25zID0gX19yZXN0KF9hLCBbXCJtYXhab29tXCIsIFwicmFkaXVzXCJdKTtcbiAgICAgICAgc3VwZXIoeyBtYXhab29tIH0pO1xuICAgICAgICB0aGlzLnN0YXRlID0geyB6b29tOiAtMSB9O1xuICAgICAgICB0aGlzLnN1cGVyQ2x1c3RlciA9IG5ldyBTdXBlckNsdXN0ZXIoT2JqZWN0LmFzc2lnbih7IG1heFpvb206IHRoaXMubWF4Wm9vbSwgcmFkaXVzIH0sIG9wdGlvbnMpKTtcbiAgICB9XG4gICAgY2FsY3VsYXRlKGlucHV0KSB7XG4gICAgICAgIGxldCBjaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IHN0YXRlID0geyB6b29tOiBpbnB1dC5tYXAuZ2V0Wm9vbSgpIH07XG4gICAgICAgIGlmICghZXF1YWwoaW5wdXQubWFya2VycywgdGhpcy5tYXJrZXJzKSkge1xuICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgICAvLyBUT0RPIHVzZSBwcm94eSB0byBhdm9pZCBjb3B5P1xuICAgICAgICAgICAgdGhpcy5tYXJrZXJzID0gWy4uLmlucHV0Lm1hcmtlcnNdO1xuICAgICAgICAgICAgY29uc3QgcG9pbnRzID0gdGhpcy5tYXJrZXJzLm1hcCgobWFya2VyKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpb24gPSBNYXJrZXJVdGlscy5nZXRQb3NpdGlvbihtYXJrZXIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvb3JkaW5hdGVzID0gW3Bvc2l0aW9uLmxuZygpLCBwb3NpdGlvbi5sYXQoKV07XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJGZWF0dXJlXCIsXG4gICAgICAgICAgICAgICAgICAgIGdlb21ldHJ5OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcIlBvaW50XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlcyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgcHJvcGVydGllczogeyBtYXJrZXIgfSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnN1cGVyQ2x1c3Rlci5sb2FkKHBvaW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjaGFuZ2VkKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS56b29tIDw9IHRoaXMubWF4Wm9vbSB8fCBzdGF0ZS56b29tIDw9IHRoaXMubWF4Wm9vbSkge1xuICAgICAgICAgICAgICAgIGNoYW5nZWQgPSAhZXF1YWwodGhpcy5zdGF0ZSwgc3RhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RhdGUgPSBzdGF0ZTtcbiAgICAgICAgaWYgKGNoYW5nZWQpIHtcbiAgICAgICAgICAgIHRoaXMuY2x1c3RlcnMgPSB0aGlzLmNsdXN0ZXIoaW5wdXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IGNsdXN0ZXJzOiB0aGlzLmNsdXN0ZXJzLCBjaGFuZ2VkIH07XG4gICAgfVxuICAgIGNsdXN0ZXIoeyBtYXAgfSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdXBlckNsdXN0ZXJcbiAgICAgICAgICAgIC5nZXRDbHVzdGVycyhbLTE4MCwgLTkwLCAxODAsIDkwXSwgTWF0aC5yb3VuZChtYXAuZ2V0Wm9vbSgpKSlcbiAgICAgICAgICAgIC5tYXAoKGZlYXR1cmUpID0+IHRoaXMudHJhbnNmb3JtQ2x1c3RlcihmZWF0dXJlKSk7XG4gICAgfVxuICAgIHRyYW5zZm9ybUNsdXN0ZXIoeyBnZW9tZXRyeTogeyBjb29yZGluYXRlczogW2xuZywgbGF0XSwgfSwgcHJvcGVydGllcywgfSkge1xuICAgICAgICBpZiAocHJvcGVydGllcy5jbHVzdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IENsdXN0ZXIoe1xuICAgICAgICAgICAgICAgIG1hcmtlcnM6IHRoaXMuc3VwZXJDbHVzdGVyXG4gICAgICAgICAgICAgICAgICAgIC5nZXRMZWF2ZXMocHJvcGVydGllcy5jbHVzdGVyX2lkLCBJbmZpbml0eSlcbiAgICAgICAgICAgICAgICAgICAgLm1hcCgobGVhZikgPT4gbGVhZi5wcm9wZXJ0aWVzLm1hcmtlciksXG4gICAgICAgICAgICAgICAgcG9zaXRpb246IHsgbGF0LCBsbmcgfSxcbiAgICAgICAgICAgI
4084H0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1hcmtlciA9IHByb3BlcnRpZXMubWFya2VyO1xuICAgICAgICByZXR1cm4gbmV3IENsdXN0ZXIoe1xuICAgICAgICAgICAgbWFya2VyczogW21hcmtlcl0sXG4gICAgICAgICAgICBwb3NpdGlvbjogTWFya2VyVXRpbHMuZ2V0UG9zaXRpb24obWFya2VyKSxcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG4vKipcbiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTENcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIEEgdmVyeSBmYXN0IEphdmFTY3JpcHQgYWxnb3JpdGhtIGZvciBnZW9zcGF0aWFsIHBvaW50IGNsdXN0ZXJpbmcgdXNpbmcgS0QgdHJlZXMuXG4gKlxuICogQHNlZSBodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9zdXBlcmNsdXN0ZXIgZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gb3B0aW9ucy5cbiAqL1xuY2xhc3MgU3VwZXJDbHVzdGVyVmlld3BvcnRBbGdvcml0aG0gZXh0ZW5kcyBBYnN0cmFjdFZpZXdwb3J0QWxnb3JpdGhtIHtcbiAgICBjb25zdHJ1Y3RvcihfYSkge1xuICAgICAgICB2Y
4084XIgeyBtYXhab29tLCByYWRpdXMgPSA2MCwgdmlld3BvcnRQYWRkaW5nID0gNjAgfSA9IF9hLCBvcHRpb25zID0gX19yZXN0KF9hLCBbXCJtYXhab29tXCIsIFwicmFkaXVzXCIsIFwidmlld3BvcnRQYWRkaW5nXCJdKTtcbiAgICAgICAgc3VwZXIoeyBtYXhab29tLCB2aWV3cG9ydFBhZGRpbmcgfSk7XG4gICAgICAgIHRoaXMuc3VwZXJDbHVzdGVyID0gbmV3IFN1cGVyQ2x1c3RlcihPYmplY3QuYXNzaWduKHsgbWF4Wm9vbTogdGhpcy5tYXhab29tLCByYWRpdXMgfSwgb3B0aW9ucykpO1xuICAgICAgICB0aGlzLnN0YXRlID0geyB6b29tOiAtMSwgdmlldzogWzAsIDAsIDAsIDBdIH07XG4gICAgfVxuICAgIGNhbGN1bGF0ZShpbnB1dCkge1xuICAgICAgICBjb25zdCBzdGF0ZSA9IHtcbiAgICAgICAgICAgIHpvb206IE1hdGgucm91bmQoaW5wdXQubWFwLmdldFpvb20oKSksXG4gICAgICAgICAgICB2aWV3OiBnZXRQYWRkZWRWaWV3cG9ydChpbnB1dC5tYXAuZ2V0Qm91bmRzKCksIGlucHV0Lm1hcENhbnZhc1Byb2plY3Rpb24sIHRoaXMudmlld3BvcnRQYWRkaW5nKSxcbiAgICAgICAgfTtcbiAgICAgICAgbGV0IGNoYW5nZWQgPSAhZXF1YWwodGhpcy5zdGF0ZSwgc3RhdGUpO1xuICAgICAgICBpZiAoIWVxdWFsKGlucHV0Lm1hcmtlcnMsIHRoaXMubWFya2VycykpIHtcbiAgICAgICAgICAgIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gVE9ETyB1c2UgcHJveHkgdG8gYXZvaWQgY29weT9cbiAgICAgICAgICAgIHRoaXMubWFya2VycyA9IFsuLi5pbnB1dC5tYXJrZXJzXTtcbiAgICAgICAgICAgIGNvbnN0IHBvaW50cyA9IHRoaXMubWFya2Vycy5tYXAoKG1hcmtlcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gTWFya2VyVXRpbHMuZ2V0UG9zaXRpb24obWFya2VyKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjb29yZGluYXRlcyA9IFtwb3NpdGlvbi5sbmcoKSwgcG9zaXRpb24ubGF0KCldO1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwiRmVhdHVyZVwiLFxuICAgICAgICAgICAgICAgICAgICBnZW9tZXRyeToge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJQb2ludFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnRpZXM6IHsgbWFya2VyIH0sXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5zdXBlckNsdXN0ZXIubG9hZChwb2ludHMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGFuZ2VkKSB7XG4gICAgICAgICAgICB0aGlzLmNsdXN0ZXJzID0gdGhpcy5jbHVzdGVyKGlucHV0KTtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBzdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBjbHVzdGVyczogdGhpcy5jbHVzdGVycywgY2hhbmdlZCB9O1xuICAgIH1cbiAgICBjbHVzdGVyKHsgbWFwLCBtYXBDYW52YXNQcm9qZWN0aW9uIH0pIHtcbiAgICAgICAgLyogcmVjYWxjdWxhdGUgbmV3IHN0YXRlIGJlY2F1c2Ugd2UgY2FuJ3QgdXNlIHRoZSBjYWNoZWQgdmVyc2lvbi4gKi9cbiAgICAgICAgY29uc3Qgc3RhdGUgPSB7XG4gICAgICAgICAgICB6b29tOiBNYXRoLnJvdW5kKG1hcC5nZXRab29tKCkpLFxuICAgICAgICAgICAgdmlldzogZ2V0UGFkZGVkVmlld3BvcnQobWFwLmdldEJvdW5kcygpLCBtYXBDYW52YXNQcm9qZWN0aW9uLCB0aGlzLnZpZXdwb3J0UGFkZGluZyksXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB0aGlzLnN1cGVyQ2x1c3RlclxuICAgICAgICAgICAgLmdldENsdXN0ZXJzKHN0YXRlLnZpZXcsIHN0YXRlLnpvb20pXG4gICAgICAgICAgICAubWFwKChmZWF0dXJlKSA9PiB0aGlzLnRyYW5zZm9ybUNsdXN0ZXIoZmVhdHVyZSkpO1xuICAgIH1cbiAgICB0cmFuc2Zvcm1DbHVzdGVyKHsgZ2VvbWV0cnk6IHsgY29vcmRpbmF0ZXM6IFtsbmcsIGxhdF0sIH0sIHByb3BlcnRpZXMsIH0pIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuY2x1c3Rlcikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBDbHVzdGVyKHtcbiAgICAgICAgICAgICAgICBtYXJrZXJzOiB0aGlzLnN1cGVyQ2x1c3RlclxuICAgICAgICAgICAgICAgICAgICAuZ2V0TGVhdmVzKHByb3BlcnRpZXMuY2x1c3Rlcl9pZCwgSW5maW5pdHkpXG4gICAgICAgICAgICAgICAgICAgIC5tYXAoKGxlYWYpID0+IGxlYWYucHJvcGVydGllcy5tYXJrZXIpLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiB7IGxhdCwgbG5nIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtYXJrZXIgPSBwcm9wZXJ0aWVzLm1hcmtlcjtcbiAgICAgICAgcmV0dXJuIG5ldyBDbHVzdGVyKHtcbiAgICAgICAgICAgIG1hcmtlcnM6IFttYXJrZXJdLFxuICAgICAgICAgICAgcG9zaXRpb246IE1hcmtlclV0aWxzLmdldFBvc2l0aW9uKG1hcmtlciksXG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuLyoqXG4gKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLyoqXG4gKiBQcm92aWRlcyBzdGF0aXN0aWNzIG9uIGFsbCBjbHVzdGVycyBpbiB0aGUgY3VycmVudCByZW5kZXIgY3ljbGUgZm9yIHVzZSBpbiB7QGxpbmsgUmVuZGVyZXIucmVuZGVyfS5cbiAqL1xuY2xhc3MgQ2x1c3RlclN0YXRzIHtcbiAgICBjb25zdHJ1Y3RvcihtYXJrZXJzLCBjbHVzdGVycykge1xuICAgICAgICB0aGlzLm1hcmtlcnMgPSB7IHN1bTogbWFya2Vycy5sZW5ndGggfTtcbiAgICAgICAgY29uc3QgY2x1c3Rlck1hcmtlckNvdW50cyA9IGNsdXN0ZXJzLm1hcCgoYSkgPT4gYS5jb3VudCk7XG4gICAgICAgIGNvbnN0IGNsdXN0ZXJNYXJrZXJTdW0gPSBjbHVzdGVyTWFya2VyQ291bnRzLnJlZHVjZSgoYSwgYikgPT4gYSArIGIsIDApO1xuICAgICAgICB0aGlzLmNsdXN0ZXJzID0ge1xuICAgICAgICAgICAgY291bnQ6IGNsdXN0ZXJzLmxlbmd0aCxcbiAgICAgICAgICAgIG1hcmtlcnM6IHtcbiAgICAgICAgICAgICAgICBtZWFuOiBjbHVzdGVyTWFya2VyU3VtIC8gY2x1c3RlcnMubGVuZ3RoLFxuICAgICAgICAgICAgICAgI
4084HN1bTogY2x1c3Rlck1hcmtlclN1bSxcbiAgICAgICAgICAgICAgICBtaW46IE1hdGgubWluKC4uLmNsdXN0ZXJNYXJrZXJDb3VudHMpLFxuICAgICAgICAgICAgICAgIG1heDogTWF0aC5tYXgoLi4uY2x1c3Rlck1hcmtlckNvdW50cyksXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH1cbn1cbmNsYXNzIERlZmF1bHRSZW5kZXJlciB7XG4gICAgLyoqXG4gICAgICogVGhlIGRlZmF1bHQgcmVuZGVyIGZ1bmN0aW9uIGZvciB0aGUgbGlicmFyeSB1c2VkIGJ5IHtAbGluayBNYXJrZXJDbHVzdGVyZXJ9LlxuICAgICAqXG4gICAgICogQ3VycmVudGx5IHNldCB0byB1c2UgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAvLyBjaGFuZ2UgY29sb3IgaWYgdGhpcyBjbHVzdGVyIGhhcyBtb3JlIG1hcmtlcnMgdGhhbiB0aGUgbWVhbiBjbHVzdGVyXG4gICAgICogY29uc3QgY29sb3IgPVxuICAgICAqICAgY291bnQgPiBNYXRoLm1heCgxMCwgc3RhdHMuY2x1c3RlcnMubWFya2Vycy5tZWFuKVxuICAgICAqICAgICA/IFwiI2ZmMDAwMFwiXG4gICAgICogICAgIDogXCIjMDAwMGZmXCI7XG4gICAgICpcbiAgICAgKiAvLyBjcmVhdGUgc3ZnIHVybCB3aXRoIGZpbGwgY29sb3JcbiAgICAgKiBjb25zdCBzdmcgPSB3aW5kb3cuYnRvYShgXG4gICAgICogPHN2ZyBmaWxsPVwiJHtjb2xvcn1cIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAyNDAgMjQwXCI+XG4gICAgICogICA8Y2lyY2xlIGN4PVwiMTIwXCIgY3k9XCIxMjBcIiBvcGFjaXR5PVwiLjZcIiByPVwiNzBcIiAvPlxuICAgICAqICAgPGNpcmNsZSBjeD1cIjEyMFwiIGN5PVwiMTIwXCIgb3BhY2l0eT1cIi4zXCIgcj1cIjkwXCIgLz5cbiAgICAgKiAgIDxjaXJjbGUgY3g9XCIxMjBcIiBjeT1cIjEyMFwiIG9wYWNpdHk9XCIuMlwiIHI9XCIxMTBcIiAvPlxuICAgICAqICAgPGNpcmNsZSBjeD1cIjEyMFwiIGN5PVwiMTIwXCIgb3BhY2l0eT1cIi4xXCIgcj1cIjEzMFwiIC8+XG4gICAgICogPC9zdmc+YCk7XG4gICAgICpcbiAgICAgKiAvLyBjcmVhdGUgbWFya2VyIHVzaW5nIHN2ZyBpY29uXG4gICAgICogcmV0dXJuIG5ldyBnb29nbGUubWFwcy5NYXJrZXIoe1xuICAgICAqICAgcG9zaXRpb24sXG4gICAgICogICBpY29uOiB7XG4gICAgICogICAgIHVybDogYGRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsJHtzdmd9YCxcbiAgICAgKiAgICAgc2NhbGVkU2l6ZTogbmV3IGdvb2dsZS5tYXBzLlNpemUoNDUsIDQ1KSxcbiAgICAgKiAgIH0sXG4gICAgICogICBsYWJlbDoge1xuICAgICAqICAgICB0ZXh0OiBTdHJpbmcoY291bnQpLFxuICAgICAqICAgICBjb2xvcjogXCJyZ2JhKDI1NSwyNTUsMjU1LDAuOSlcIixcbiAgICAgKiAgICAgZm9udFNpemU6IFwiMTJweFwiLFxuICAgICAqICAgfSxcbiAgICAgKiAgIC8vIGFkanVzdCB6SW5kZXggdG8gYmUgYWJvdmUgb3RoZXIgbWFya2Vyc1xuICAgICAqICAgekluZGV4OiAxMDAwICsgY291bnQsXG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcmVuZGVyKHsgY291bnQsIHBvc2l0aW9uIH0sIHN0YXRzLCBtYXApIHtcbiAgICAgICAgLy8gY2hhbmdlIGNvbG9yIGlmIHRoaXMgY2x1c3RlciBoYXMgbW9yZSBtYXJrZXJzIHRoYW4gdGhlIG1lYW4gY2x1c3RlclxuICAgICAgICBjb25zdCBjb2xvciA9IGNvdW50ID4gTWF0aC5tYXgoMTAsIHN0YXRzLmNsdXN0ZXJzLm1hcmtlcnMubWVhbikgPyBcIiNmZjAwMDBcIiA6IFwiIzAwMDBmZlwiO1xuICAgICAgICAvLyBjcmVhdGUgc3ZnIGxpdGVyYWwgd2l0aCBmaWxsIGNvbG9yXG4gICAgICAgIGNvbnN0IHN2ZyA9IGA8c3ZnIGZpbGw9XCIke2NvbG9yfVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDI0MCAyNDBcIiB3aWR0aD1cIjUwXCIgaGVpZ2h0PVwiNTBcIj5cbjxjaXJjbGUgY3g9XCIxMjBcIiBjeT1cIjEyMFwiIG9wYWNpdHk9XCIuNlwiIHI9XCI3MFwiIC8+XG48Y2lyY2xlIGN4PVwiMTIwXCIgY3k9XCIxMjBcIiBvcGFjaXR5PVwiLjNcIiByPVwiOTBcIiAvPlxuPGNpcmNsZSBjeD1cIjEyMFwiIGN5PVwiMTIwXCIgb3BhY2l0eT1cIi4yXCIgcj1cIjExMFwiIC8+XG48dGV4dCB4PVwiNTAlXCIgeT1cIjUwJVwiIHN0eWxlPVwiZmlsbDojZmZmXCIgdGV4dC1hbmNob3I9XCJtaWRkbGVcIiBmb250LXNpemU9XCI1MFwiIGRvbWluYW50LWJhc2VsaW5lPVwibWlkZGxlXCIgZm9udC1mYW1pbHk9XCJyb2JvdG8sYXJpYWwsc2Fucy1zZXJpZlwiPiR7Y291bnR9PC90ZXh0PlxuPC9zdmc+YDtcbiAgICAgICAgY29uc3QgdGl0bGUgPSBgQ2x1c3RlciBvZiAke2NvdW50fSBtYXJrZXJzYCwgXG4gICAgICAgIC8vIGFkanVzdCB6SW5kZXggdG8gYmUgYWJvdmUgb3RoZXIgbWFya2Vyc1xuICAgICAgICB6SW5kZXggPSBOdW1iZXIoZ29vZ2xlLm1hcHMuTWFya2VyLk1BWF9aSU5ERVgpICsgY291bnQ7XG4gICAgICAgIGlmIChNYXJrZXJVdGlscy5pc0FkdmFuY2VkTWFya2VyQXZhaWxhYmxlKG1hcCkpIHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBjbHVzdGVyIFNWRyBlbGVtZW50XG4gICAgICAgICAgICBjb25zdCBwYXJzZXIgPSBuZXcgRE9NUGFyc2VyKCk7XG4gICAgICAgICAgICBjb25zdCBzdmdFbCA9IHBhcnNlci5wYXJzZUZyb21TdHJpbmcoc3ZnLCBcImltYWdlL3N2Zyt4bWxcIikuZG9jdW1lbnRFbGVtZW50O1xuICAgICAgICAgICAgc3ZnRWwuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKDAgMjUpXCIpO1xuICAgICAgICAgICAgY29uc3QgY2x1c3Rlck9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgbWFwLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uLFxuICAgICAgICAgICAgICAgIHpJbmRleCxcbiAgICAgICAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICAgICAgICBjb250ZW50OiBzdmdFbCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4gbmV3IGdvb2dsZS5tYXBzLm1hcmtlci5BZHZhbmNlZE1hcmtlckVsZW1lbnQoY2x1c3Rlck9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNsdXN0ZXJPcHRpb25zID0ge1xuICAgICAgICAgICAgcG9zaXRpb24sXG4gICAgICAgICAgICB6SW5kZXgsXG4gICAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICAgIGljb246IHtcbiAgICAgICAgICAgICAgICB1cmw6IGBkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LCR7YnRvYShzdmcpfWAsXG4gICAgICAgICAgICAgICAgYW5jaG9yOiBuZXcgZ29vZ2xlLm1hcHMuUG9pbnQoMjUsIDI1KSxcbiAgICAgICAgICAgI
4084H0sXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgZ29vZ2xlLm1hcHMuTWFya2VyKGNsdXN0ZXJPcHRpb25zKTtcbiAgICB9XG59XG5cbi8qKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIEV4dGVuZHMgYW4gb2JqZWN0J3MgcHJvdG90eXBlIGJ5IGFub3RoZXIncy5cbiAqXG4gKiBAcGFyYW0gdHlwZTEgVGhlIFR5cGUgdG8gYmUgZXh0ZW5kZWQuXG4gKiBAcGFyYW0gdHlwZTIgVGhlIFR5cGUgdG8gZXh0ZW5kIHdpdGguXG4gKiBAaWdub3JlXG4gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG5mdW5jdGlvbiBleHRlbmQodHlwZTEsIHR5cGUyKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0XG4gICAgZm9yIChsZXQgcHJvcGVydHkgaW4gdHlwZTIucHJvdG90eXBlKSB7XG4gICAgICAgIHR5cGUxLnByb3RvdHlwZVtwcm9wZXJ0eV0gPSB0eXBlMi5wcm90b3R5cGVbcHJvcGVydHldO1xuICAgIH1cbn1cbi8qKlxuICogQGlnbm9yZVxuICovXG5jbGFzcyBPdmVybGF5Vmlld1NhZmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAvLyBNYXJrZXJDbHVzdGVyZXIgaW1wbGVtZW50cyBnb29nbGUubWFwcy5PdmVybGF5VmlldyBpbnRlcmZhY2UuIFdlIHVzZSB0aGVcbiAgICAgICAgLy8gZXh0ZW5kIGZ1bmN0aW9uIHRvIGV4dGVuZCBNYXJrZXJDbHVzdGVyZXIgd2l0aCBnb29nbGUubWFwcy5PdmVybGF5Vmlld1xuICAgICAgICAvLyBiZWNhdXNlIGl0IG1pZ2h0IG5vdCBhbHdheXMgYmUgYXZhaWxhYmxlIHdoZW4gdGhlIGNvZGUgaXMgZGVmaW5lZCBzbyB3ZVxuICAgICAgICAvLyBsb29rIGZvciBpdCBhdCB0aGUgbGFzdCBwb3NzaWJsZSBtb21lbnQuIElmIGl0IGRvZXNuJ3QgZXhpc3Qgbm93IHRoZW5cbiAgICAgICAgLy8gdGhlcmUgaXMgbm8gcG9pbnQgZ29pbmcgYWhlYWQgOilcbiAgICAgICAgZXh0ZW5kKE92ZXJsYXlWaWV3U2FmZSwgZ29vZ2xlLm1hcHMuT3ZlcmxheVZpZXcpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xudmFyIE1hcmtlckNsdXN0ZXJlckV2ZW50cztcbihmdW5jdGlvbiAoTWFya2VyQ2x1c3RlcmVyRXZlbnRzKSB7XG4gICAgTWFya2VyQ2x1c3RlcmVyRXZlbnRzW1wiQ0xVU1RFUklOR19CRUdJTlwiXSA9IFwiY2x1c3RlcmluZ2JlZ2luXCI7XG4gICAgTWFya2VyQ2x1c3RlcmVyRXZlbnRzW1wiQ0xVU1RFUklOR19FTkRcIl0gPSBcImNsdXN0ZXJpbmdlbmRcIjtcbiAgICBNYXJrZXJDbHVzdGVyZXJFdmVudHNbXCJDTFVTVEVSX0NMSUNLXCJdID0gXCJjbGlja1wiO1xufSkoTWFya2VyQ2x1c3RlcmVyRXZlbnRzIHx8IChNYXJrZXJDbHVzdGVyZXJFdmVudHMgPSB7fSkpO1xuY29uc3QgZGVmYXVsdE9uQ2x1c3RlckNsaWNrSGFuZGxlciA9IChfLCBjbHVzdGVyLCBtYXApID0+IHtcbiAgICBtYXAuZml0Qm91bmRzKGNsdXN0ZXIuYm91bmRzKTtcbn07XG4vKipcbiAqIE1hcmtlckNsdXN0ZXJlciBjcmVhdGVzIGFuZCBtYW5hZ2VzIHBlci16b29tLWxldmVsIGNsdXN0ZXJzIGZvciBsYXJnZSBhbW91bnRzXG4gKiBvZiBtYXJrZXJzLiBTZWUge0BsaW5rIE1hcmtlckNsdXN0ZXJlck9wdGlvbnN9IGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICovXG5jbGFzcyBNYXJrZXJDbHVzdGVyZXIgZXh0ZW5kcyBPdmVybGF5Vmlld1NhZmUge1xuICAgIGNvbnN0cnVjdG9yKHsgbWFwLCBtYXJrZXJzID0gW10sIGFsZ29yaXRobU9wdGlvbnMgPSB7fSwgYWxnb3JpdGhtID0gbmV3IFN1cGVyQ2x1c3RlckFsZ29yaXRobShhbGdvcml0aG1PcHRpb25zKSwgcmVuZGVyZXIgPSBuZXcgRGVmYXVsdFJlbmRlcmVyKCksIG9uQ2x1c3RlckNsaWNrID0gZGVmYXVsdE9uQ2x1c3RlckNsaWNrSGFuZGxlciwgfSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLm1hcmtlcnMgPSBbLi4ubWFya2Vyc107XG4gICAgICAgI
4084HRoaXMuY2x1c3RlcnMgPSBbXTtcbiAgICAgICAgdGhpcy5hbGdvcml0aG0gPSBhbGdvcml0aG07XG4gICAgICAgIHRoaXMucmVuZGVyZXIgPSByZW5kZXJlcjtcbiAgICAgICAgdGhpcy5vbkNsdXN0ZXJDbGljayA9IG9uQ2x1c3RlckNsaWNrO1xuICAgICAgICBpZiAobWFwKSB7XG4gICAgICAgICAgICB0aGlzLnNldE1hcChtYXApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFkZE1hcmtlcihtYXJrZXIsIG5vRHJhdykge1xuICAgICAgICBpZiAodGhpcy5tYXJrZXJzLmluY2x1ZGVzKG1hcmtlcikpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm1hcmtlcnMucHVzaChtYXJrZXIpO1xuICAgICAgICBpZiAoIW5vRHJhdykge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRNYXJrZXJzKG1hcmtlcnMsIG5vRHJhdykge1xuICAgICAgICBtYXJrZXJzLmZvckVhY2goKG1hcmtlcikgPT4ge1xuICAgICAgICAgICAgdGhpcy5hZGRNYXJrZXIobWFya2VyLCB0cnVlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghbm9EcmF3KSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJlbW92ZU1hcmtlcihtYXJrZXIsIG5vRHJhdykge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMubWFya2Vycy5pbmRleE9mKG1hcmtlcik7XG4gICAgICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIC8vIE1hcmtlciBpcyBub3QgaW4gb3VyIGxpc3Qgb2YgbWFya2Vycywgc28gZG8gbm90aGluZzpcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBNYXJrZXJVdGlscy5zZXRNYXAobWFya2VyLCBudWxsKTtcbiAgICAgICAgdGhpcy5tYXJrZXJzLnNwbGljZShpbmRleCwgMSk7IC8vIFJlbW92ZSB0aGUgbWFya2VyIGZyb20gdGhlIGxpc3Qgb2YgbWFuYWdlZCBtYXJrZXJzXG4gICAgICAgIGlmICghbm9EcmF3KSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZW1vdmVNYXJrZXJzKG1hcmtlcnMsIG5vRHJhdykge1xuICAgICAgICBsZXQgcmVtb3ZlZCA9IGZhbHNlO1xuICAgICAgICBtYXJrZXJzLmZvckVhY2goKG1hcmtlcikgPT4ge1xuICAgICAgICAgICAgcmVtb3ZlZCA9IHRoaXMucmVtb3ZlTWFya2VyKG1hcmtlciwgdHJ1ZSkgfHwgcmVtb3ZlZDtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZW1vdmVkICYmICFub0RyYXcpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlbW92ZWQ7XG4gICAgfVxuICAgIGNsZWFyTWFya2Vycyhub0RyYXcpIHtcbiAgICAgICAgdGhpcy5tYXJrZXJzLmxlbmd0aCA9IDA7XG4gICAgICAgIGlmICghbm9EcmF3KSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlY2FsY3VsYXRlcyBhbmQgZHJhd3MgYWxsIHRoZSBtYXJrZXIgY2x1c3RlcnMuXG4gICAgICovXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBjb25zdCBtYXAgPSB0aGlzLmdldE1hcCgpO1xuICAgICAgICBpZiAobWFwIGluc3RhbmNlb2YgZ29vZ2xlLm1hcHMuTWFwICYmIG1hcC5nZXRQcm9qZWN0aW9uKCkpIHtcbiAgICAgICAgICAgIGdvb2dsZS5tYXBzLmV2ZW50LnRyaWdnZXIodGhpcywgTWFya2VyQ2x1c3RlcmVyRXZlbnRzLkNMVVNURVJJTkdfQkVHSU4sIHRoaXMpO1xuICAgICAgICAgICAgY29uc3QgeyBjbHVzdGVycywgY2hhbmdlZCB9ID0gdGhpcy5hbGdvcml0aG0uY2FsY3VsYXRlKHtcbiAgICAgICAgICAgICAgICBtYXJrZXJzOiB0aGlzLm1hcmtlcnMsXG4gICAgICAgICAgICAgICAgbWFwLFxuICAgICAgICAgICAgICAgIG1hcENhbnZhc1Byb2plY3Rpb246IHRoaXMuZ2V0UHJvamVjdGlvbigpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBBbGxvdyBhbGdvcml0aG1zIHRvIHJldHVybiBmbGFnIG9uIHdoZXRoZXIgdGhlIGNsdXN0ZXJzL21hcmtlcnMgaGF2ZSBjaGFuZ2VkLlxuICAgICAgICAgICAgaWYgKGNoYW5nZWQgfHwgY2hhbmdlZCA9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBBY2N1bXVsYXRlIHRoZSBtYXJrZXJzIG9mIHRoZSBjbHVzdGVycyBjb21wb3NlZCBvZiBhIHNpbmdsZSBtYXJrZXIuXG4gICAgICAgICAgICAgICAgLy8gVGhvc2UgY2x1c3RlcnMgZGlyZWN0bHkgdXNlIHRoZSBtYXJrZXIuXG4gICAgICAgICAgICAgICAgLy8gQ2x1c3RlcnMgd2l0aCBtb3JlIHRoYW4gb25lIG1hcmtlcnMgdXNlIGEgZ3JvdXAgbWFya2VyIGdlbmVyYXRlZCBieSBhIHJlbmRlcmVyLlxuICAgICAgICAgICAgICAgIGNvbnN0IHNpbmdsZU1hcmtlciA9IG5ldyBTZXQoKTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNsdXN0ZXIgb2YgY2x1c3RlcnMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNsdXN0ZXIubWFya2Vycy5sZW5ndGggPT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlTWFya2VyLmFkZChjbHVzdGVyLm1hcmtlcnNbMF0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGdyb3VwTWFya2VycyA9IFtdO1xuICAgICAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhlIGNsdXN0ZXJzIHRoYXQgYXJlIGN1cnJlbnRseSByZW5kZXJlZC5cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNsdXN0ZXIgb2YgdGhpcy5jbHVzdGVycykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2x1c3Rlci5tYXJrZXIgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNsdXN0ZXIubWFya2Vycy5sZW5ndGggPT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzaW5nbGVNYXJrZXIuaGFzKGNsdXN0ZXIubWFya2VyKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBtYXJrZXI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gLSB3YXMgcHJldmlvdXNseSByZW5kZXJlZCBiZWNhdXNlIGl0IGlzIGZyb20gYSBjbHVzdGVyIHdpdGggMSBtYXJrZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gLSBzaG91bGQgbm8gbW9yZSBiZSByZW5kZXJlZCBhcyBpdCBpcyBub3QgaW4gc2luZ2xlTWFya2VyLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcmtlclV0aWxzLnNldE1hcChjbHVzdGVyLm1hcmtlciwgbnVsbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgI
4084H1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWxheSB0aGUgcmVtb3ZhbCBvZiBvbGQgZ3JvdXAgbWFya2VycyB0byBhdm9pZCBmbGlja2VyaW5nLlxuICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBNYXJrZXJzLnB1c2goY2x1c3Rlci5tYXJrZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuY2x1c3RlcnMgPSBjbHVzdGVycztcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlckNsdXN0ZXJzKCk7XG4gICAgICAgICAgICAgICAgLy8gRGVsYXllZCByZW1vdmFsIG9mIHRoZSBtYXJrZXJzIG9mIHRoZSBmb3JtZXIgZ3JvdXBzLlxuICAgICAgICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiBncm91cE1hcmtlcnMuZm9yRWFjaCgobWFya2VyKSA9PiBNYXJrZXJVdGlscy5zZXRNYXAobWFya2VyLCBudWxsKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZ29vZ2xlLm1hcHMuZXZlbnQudHJpZ2dlcih0aGlzLCBNYXJrZXJDbHVzdGVyZXJFdmVudHMuQ0xVU1RFUklOR19FTkQsIHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIG9uQWRkKCkge1xuICAgICAgICB0aGlzLmlkbGVMaXN0ZW5lciA9IHRoaXMuZ2V0TWFwKCkuYWRkTGlzdGVuZXIoXCJpZGxlXCIsIHRoaXMucmVuZGVyLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgICBvblJlbW92ZSgpIHtcbiAgICAgICAgZ29vZ2xlLm1hcHMuZXZlbnQucmVtb3ZlTGlzdGVuZXIodGhpcy5pZGxlTGlzdGVuZXIpO1xuICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgfVxuICAgIHJlc2V0KCkge1xuICAgICAgICB0aGlzLm1hcmtlcnMuZm9yRWFjaCgobWFya2VyKSA9PiBNYXJrZXJVdGlscy5zZXRNYXAobWFya2VyLCBudWxsKSk7XG4gICAgICAgIHRoaXMuY2x1c3RlcnMuZm9yRWFjaCgoY2x1c3RlcikgPT4gY2x1c3Rlci5kZWxldGUoKSk7XG4gICAgICAgIHRoaXMuY2x1c3RlcnMgPSBbXTtcbiAgICB9XG4gICAgcmVuZGVyQ2x1c3RlcnMoKSB7XG4gICAgICAgIC8vIEdlbmVyYXRlIHN0YXRzIHRvIHBhc3MgdG8gcmVuZGVyZXJzLlxuICAgICAgICBjb25zdCBzdGF0cyA9IG5ldyBDbHVzdGVyU3RhdHModGhpcy5tYXJrZXJzLCB0aGlzLmNsdXN0ZXJzKTtcbiAgICAgICAgY29uc3QgbWFwID0gdGhpcy5nZXRNYXAoKTtcbiAgICAgICAgdGhpcy5jbHVzdGVycy5mb3JFYWNoKChjbHVzdGVyKSA9PiB7XG4gICAgICAgICAgICBpZiAoY2x1c3Rlci5tYXJrZXJzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgIGNsdXN0ZXIubWFya2VyID0gY2x1c3Rlci5tYXJrZXJzWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgdGhlIG1hcmtlciB0byByZXByZXNlbnQgdGhlIGdyb3VwLlxuICAgICAgICAgICAgICAgIGNsdXN0ZXIubWFya2VyID0gdGhpcy5yZW5kZXJlci5yZW5kZXIoY2x1c3Rlciwgc3RhdHMsIG1hcCk7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBzdXJlIGFsbCBpbmRpdmlkdWFsIG1hcmtlcnMgYXJlIHJlbW92ZWQgZnJvbSB0aGUgbWFwLlxuICAgICAgICAgICAgICAgIGNsdXN0ZXIubWFya2Vycy5mb3JFYWNoKChtYXJrZXIpID0+IE1hcmtlclV0aWxzLnNldE1hcChtYXJrZXIsIG51bGwpKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5vbkNsdXN0ZXJDbGljaykge1xuICAgICAgICAgICAgICAgICAgICBjbHVzdGVyLm1hcmtlci5hZGRMaXN0ZW5lcihcImNsaWNrXCIsIFxuICAgICAgICAgICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICAgICAgICAgICAgICAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdvb2dsZS5tYXBzLmV2ZW50LnRyaWdnZXIodGhpcywgTWFya2VyQ2x1c3RlcmVyRXZlbnRzLkNMVVNURVJfQ0xJQ0ssIGNsdXN0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkNsdXN0ZXJDbGljayhldmVudCwgY2x1c3RlciwgbWFwKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgTWFya2VyVXRpbHMuc2V0TWFwKGNsdXN0ZXIubWFya2VyLCBtYXApO1xuICAgICAgICB9KTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IEFic3RyYWN0QWxnb3JpdGhtLCBBYnN0cmFjdFZpZXdwb3J0QWxnb3JpdGhtLCBDbHVzdGVyLCBDbHVzdGVyU3RhdHMsIERlZmF1bHRSZW5kZXJlciwgR3JpZEFsZ29yaXRobSwgTWFya2VyQ2x1c3RlcmVyLCBNYXJrZXJDbHVzdGVyZXJFdmVudHMsIE1hcmtlclV0aWxzLCBOb29wQWxnb3JpdGhtLCBTdXBlckNsdXN0ZXJBbGdvcml0aG0sIFN1cGVyQ2x1c3RlclZpZXdwb3J0QWxnb3JpdGhtLCBkZWZhdWx0T25DbHVzdGVyQ2xpY2tIYW5kbGVyLCBkaXN0YW5jZUJldHdlZW5Qb2ludHMsIGV4dGVuZEJvdW5kc1RvUGFkZGVkVmlld3BvcnQsIGV4dGVuZFBpeGVsQm91bmRzLCBmaWx0ZXJNYXJrZXJzVG9QYWRkZWRWaWV3cG9ydCwgZ2V0UGFkZGVkVmlld3BvcnQsIG5vb3AsIHBpeGVsQm91bmRzVG9MYXRMbmdCb3VuZHMgfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmVzbS5qcy5tYXBcbiIsIi8vIEluc3BpcsOpIGRlIGNlIGTDqXDDtHQgR2l0SHViIDogaHR0cHM6Ly9naXRodWIuY29tL2l2dGVwbG8vYm90dG9tLXNoZWV0XG5pbXBvcnQgeyBpc1RvdWNoRGV2aWNlIH0gZnJvbSAnLi9tYXBVdGlscyc7XG5pbXBvcnQgeyBPQlNFUlZFUiB9IGZyb20gJy4uL3BsdWdpbnMnO1xuXG5mdW5jdGlvbiBnZXRCcm93c2VyTWF4SGVpZ2h0KCkge1xuICBjb25zdCBtYXBIZWFkZXJNb2JpbGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtbWFwLWhlYWRlci1tb2JpbGUnKTtcbiAgY29uc3QgbWFwSGVhZGVyTW9iaWxlSGVpZ2h0ID0gbWFwSGVhZGVyTW9iaWxlLm9mZnNldEhlaWdodDtcbiAgY29uc3QgbWF4QnJvd3NlckhlaWdodCA9IE1hdGgubWF4KGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQgfHwgMCwgd2luZG93LmlubmVySGVpZ2h0IHx8IDApO1xuXG4gIHJldHVybi
4084BtYXhCcm93c2VySGVpZ2h0IC0gbWFwSGVhZGVyTW9iaWxlSGVpZ2h0O1xufVxuXG5mdW5jdGlvbiB0b3VjaFBvc2l0aW9uKGV2ZW50KSB7XG4gIHJldHVybiBldmVudC50b3VjaGVzID8gZXZlbnQudG91Y2hlc1swXSA6IGV2ZW50O1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCb3R0b21TaGVldCB7XG4gIGluaXQoKSB7XG4gICAgdGhpcy5zaGVldENvbnRlbnRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmpzLW1hcC1zaWRlYmFyJyk7XG4gICAgdGhpcy5kcmFnZ2FibGVBcmVhID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmpzLW1hcC1zaWRlYmFyLWJ1dHRvbi1kcmFnZ2FibGUnKTtcbiAgICB0aGlzLnNoZWV0U2xpZGVEb3duSGVpZ2h0ID0gNzA7IC8vIGluIHB4XG4gICAgdGhpcy5zaGVldEhlaWdodCA9IHRoaXMuc2hlZXRTbGlkZURvd25IZWlnaHQ7XG4gICAgdGhpcy5kcmFnUG9zaXRpb24gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcblxuICAgIGlmICghaXNUb3VjaERldmljZSgpKSB7XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtbWFwLXNpZGViYXItYnV0dG9uLWRyYWdnYWJsZScpO1xuICAgICAgT0JTRVJWRVIuYWRkKHtcbiAgICAgICAgbmFtZTogJ0JvdHRvbVNoZWV0JyxcbiAgICAgICAgZXZlbnRzOiAnY2xpY2snLFxuICAgICAgICB0YXJnZXRzOiAnLmpzLW1hcC1zaWRlYmFyLWJ1dHRvbi1kcmFnZ2FibGUnLFxuICAgICAgICBmdW5jdGlvbjogdGhpcy5vbkNsaWNrLmJpbmQodGhpcyksXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgT0JTRVJWRVIuYWRkKHtcbiAgICAgICAgbmFtZTogJ0JvdHRvbVNoZWV0JyxcbiAgICAgICAgZXZlbnRzOiAnbW91c2Vkb3duIHRvdWNoc3RhcnQnLFxuICAgICAgICB0YXJnZXRzOiAnLmpzLW1hcC1zaWRlYmFyLCAuanMtbWFwLXNpZGViYXItYnV0dG9uLWRyYWdnYWJsZScsXG4gICAgICAgIGZ1bmN0aW9uOiB0aGlzLm9uRHJhZ1N0YXJ0LmJpbmQodGhpcyksXG4gICAgICB9KTtcbiAgICAgIE9CU0VSVkVSLmFkZCh7XG4gICAgICAgIG5hbWU6ICdCb3R0b21TaGVldCcsXG4gICAgICAgIGV2ZW50czogJ21vdXNlbW92ZSB0b3VjaG1vdmUnLFxuICAgICAgICB0YXJnZXRzOiAnd2luZG93JyxcbiAgICAgICAgZnVuY3Rpb246IHRoaXMub25EcmFnTW92ZS5iaW5kKHRoaXMpLFxuICAgICAgfSk7XG4gICAgICBPQlNFUlZFUi5hZGQoe1xuICAgICAgICBuYW1lOiAnQm90dG9tU2hlZXQnLFxuICAgICAgICBldmVudHM6ICdtb3VzZXVwIHRvdWNoZW5kJyxcbiAgICAgICAgdGFyZ2V0czogJ3dpbmRvdycsXG4gICAgICAgIGZ1bmN0aW9uOiB0aGlzLm9uRHJhZ0VuZC5iaW5kKHRoaXMpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgT0JTRVJWRVIuYWRkKHtcbiAgICAgIG5hbWU6ICdCb3R0b21TaGVldCcsXG4gICAgICBldmVudHM6ICdjbGljaycsXG4gICAgICB0YXJnZXRzOiAnLmpzLW9wZW4tbWFwLXNpZGViYXInLFxuICAgICAgZnVuY3Rpb246IHRoaXMub25DbGljay5iaW5kKHRoaXMpLFxuICAgIH0pO1xuICAgIE9CU0VSVkVSLmFkZCh7XG4gICAgICBuYW1lOiAnQm90dG9tU2hlZXQnLFxuICAgICAgZXZlbnRzOiAnY2xpY2snLFxuICAgICAgdGFyZ2V0czogJy5qcy1jbG9zZS1tYXAtc2lkZWJhcicsXG4gICAgICBmdW5jdGlvbjogdGhpcy5jbG9zZVNoZWV0LmJpbmQodGhpcyksXG4gICAgfSk7XG4gICAgT0JTRVJWRVIub24oJ0JvdHRvbVNoZWV0Jyk7XG4gIH1cblxuICBzZXRTaGVldEhlaWdodCh2YWx1ZSkge1xuICAgIHRoaXMuc2hlZXRIZWlnaHQgPSB2YWx1ZTtcbiAgICB0aGlzLnNoZWV0Q29udGVudHMuc3R5bGUuaGVpZ2h0ID0gYCR7dmFsdWV9cHhgO1xuXG4gICAgaWYgKHRoaXMuc2hlZXRIZWlnaHQgPT09IGdldEJyb3dzZXJNYXhIZWlnaHQoKSkge1xuICAgICAgdGhpcy5zaGVldENvbnRlbnRzLmNsYXNzTGlzdC5hZGQoJ2lzLWZ1bGxzY3JlZW4nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zaGVldENvbnRlbnRzLmNsYXNzTGlzdC5yZW1vdmUoJ2lzLWZ1bGxzY3JlZW4nKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zaGVldEhlaWdodCA9PT0gZ2V0QnJvd3Nlck1heEhlaWdodCgpKSB7XG4gICAgICB0aGlzLmlzT3BlbiA9IHRydWU7XG4gICAgfSBlbHNlIGlmICh0aGlzLnNoZWV0SGVpZ2h0ID09PSB0aGlzLnNoZWV0U2xpZGVEb3duSGVpZ2h0KSB7XG4gICAgICB0aGlzLmlzT3BlbiA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIG9wZW5TaGVldCh2YWx1ZSkge1xuICAgIHRoaXMuc2V0U2hlZXRIZWlnaHQodmFsdWUpO1xuICB9XG5cbiAgb3BlblNoZWV0TWF4SGVpZ2h0KCkge1xuICAgIHRoaXMuc2V0U2hlZXRIZWlnaHQoZ2V0QnJvd3Nlck1heEhlaWdodCgpKTtcbiAgfVxuXG4gIGNsb3NlU2hlZXQoKSB7XG4gICAgdGhpcy5zZXRTaGVldEhlaWdodCh0aGlzLnNoZWV0U2xpZGVEb3duSGVpZ2h0KTtcbiAgfVxuXG4gIG9uQ2xpY2soKSB7XG4gICAgaWYgKHRoaXMuaXNPcGVuKSB7XG4gICAgICB0aGlzLmNsb3NlU2hlZXQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vcGVuU2hlZXQoZ2V0QnJvd3Nlck1heEhlaWdodCgpKTtcbiAgICB9XG4gIH1cblxuICBvbkRyYWdTdGFydChldmVudCkge1xuICAgIC8vIFNpIGxlIGRyYWcgZXN0IHN1ciBsYSB6b25lIGRlIGNvbnRlbnUgYXUgbGlldSBkdSBib3V0b24gZMOpcGxhw6dhYmxlLlxuICAgIGlmIChldmVudC5jdXJyZW50VGFyZ2V0ID09PSB0aGlzLnNoZWV0Q29udGVudHMpIHtcbiAgICAgIGNvbnN0IHZpZXdBY3RpdmUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1wYW5lbC1hY3RpdmVdJyk7XG5cbiAgICAgIC8vIFNpIGwnw6l2w6luZW1lbnQgZHJhZyBlc3QgcG91ciBzY3JvbGxlciBsZSBjb250ZW51LCBhbG9ycyBvbiBuZSBkw6lwbGFjZSBwYXMgbGUgYm90dG9tIHNoZWV0LlxuICAgICAgaWYgKHZpZXdBY3RpdmUuc2Nyb2xsVG9wICE9PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmRyYWdQb3NpdGlvbiA9IHRvdWNoUG9zaXRpb24oZXZlbnQpLnBhZ2VZO1xuICAgIHRoaXMuc2hlZXRDb250ZW50cy5jbGFzc0xpc3QuYWRkKCdkcmFnZ2luZycpO1xuXG4gICAgaWYgKGlzVG91Y2hEZXZpY2UoKSkge1xuICAgICAgdGhpcy5kcmFnZ2FibGVBcmVhLnN0eWxlLmN1cnNvciA9ICdncmFiYmluZyc7XG4gICAgICBkb2
4084N1bWVudC5ib2R5LnN0eWxlLmN1cnNvciA9ICdncmFiYmluZyc7XG4gICAgfVxuICB9XG5cbiAgb25EcmFnTW92ZShldmVudCkge1xuICAgIGlmICh0aGlzLmRyYWdQb3NpdGlvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgeSA9IHRvdWNoUG9zaXRpb24oZXZlbnQpLnBhZ2VZO1xuICAgIGNvbnN0IGRlbHRhWSA9IHRoaXMuZHJhZ1Bvc2l0aW9uIC0geTtcbiAgICBjb25zdCBicm93c2VyTWF4SGVpZ2h0ID0gZ2V0QnJvd3Nlck1heEhlaWdodCgpO1xuICAgIGNvbnN0IGN1cnJlbnRIZWlnaHQgPSBwYXJzZUZsb2F0KHRoaXMuc2hlZXRIZWlnaHQpO1xuICAgIGNvbnN0IG5ld0hlaWdodCA9IGN1cnJlbnRIZWlnaHQgKyBkZWx0YVk7XG5cbiAgICBpZiAobmV3SGVpZ2h0ID49IHRoaXMuc2hlZXRTbGlkZURvd25IZWlnaHQgJiYgbmV3SGVpZ2h0IDw9IGJyb3dzZXJNYXhIZWlnaHQpIHtcbiAgICAgIHRoaXMub3BlblNoZWV0KG5ld0hlaWdodCk7XG4gICAgICB0aGlzLmRyYWdQb3NpdGlvbiA9IHk7XG4gICAgfVxuICB9XG5cbiAgb25EcmFnRW5kKCkge1xuICAgIHRoaXMuZHJhZ1Bvc2l0aW9uID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuc2hlZXRDb250ZW50cy5jbGFzc0xpc3QucmVtb3ZlKCdkcmFnZ2luZycpO1xuICAgIHRoaXMuZHJhZ2dhYmxlQXJlYS5zdHlsZS5jdXJzb3IgPSAnJztcbiAgICBkb2N1bWVudC5ib2R5LnN0eWxlLmN1cnNvciA9ICcnO1xuXG4gICAgY29uc3QgYnJvd3Nlck1heEhlaWdodCA9IGdldEJyb3dzZXJNYXhIZWlnaHQoKTtcbiAgICBjb25zdCB0aHJlc2hvbGQgPSA1MDsgLy8gU2V1aWwgZW4gcGl4ZWwgcXVhbmQgb24gZ2xpc3NlIGxlIHBhbm5lYXUgcG91ciBsJ291dnJpci9mZXJtZXJcblxuICAgIGlmICh0aGlzLmlzT3Blbikge1xuICAgICAgaWYgKHRoaXMuc2hlZXRIZWlnaHQgPiBicm93c2VyTWF4SGVpZ2h0IC0gdGhyZXNob2xkKSB7XG4gICAgICAgIHRoaXMub3BlblNoZWV0KGJyb3dzZXJNYXhIZWlnaHQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5jbG9zZVNoZWV0KCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0aGlzLnNoZWV0SGVpZ2h0ID4gdGhpcy5zaGVldFNsaWRlRG93bkhlaWdodCArIHRocmVzaG9sZCkge1xuICAgICAgdGhpcy5vcGVuU2hlZXQoYnJvd3Nlck1heEhlaWdodCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2xvc2VTaGVldCgpO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgaXNUb3VjaERldmljZSB9IGZyb20gJy4vbWFwVXRpbHMnO1xuXG4vKipcbiAqIENldHRlIGNsYXNzZSBnw6hyZSBsJ2ludGVyYWN0aXZpdMOpIGRlcyBib3V0b25zIHBvdXIgY29udHLDtGxlciBsYSBjYXJ0ZSBHb29nbGUgTWFwcy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWFwVWkge1xuICAvKipcbiAgICogQ29uc3RydWN0ZXVyIGRlIGxhIGNsYXNzZSBNYXBVaS5cbiAgICogQGNvbnN0cnVjdG9yXG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLm1hcCA9IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogR8OpcmVyIGxlIGNsaWMgc3VyIGxlIGJvdXRvbiBxdWl0dGVyLlxuICAgKi9cbiAgaW5pdFF1aXRCdXR0b24oKSB7XG4gICAgY29uc3QgcXVpdE1hcEluZm8gPSB7fTtcbiAgICBxdWl0TWFwSW5mby5ob3N0ID0gd2luZG93LmxvY2F0aW9uLmhvc3Q7XG4gICAgcXVpdE1hcEluZm8uaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuICAgIHF1aXRNYXBJbmZvLnJlZmVycmVyID0gZG9jdW1lbnQucmVmZXJyZXI7XG5cbiAgICB3aW5kb3cucXVpdE1hcEluZm8gPSBxdWl0TWFwSW5mbztcblxuICAgIGNvbnN0IGJ1dHRvbnNCYWNrVG9wUHJldmlvdXNQYWdlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmpzLXF1aXQtbWFwJyk7XG4gICAgYnV0dG9uc0JhY2tUb3BQcmV2aW91c1BhZ2UuZm9yRWFjaCgoYm91dG9uKSA9PiB7XG4gICAgICBib3V0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgIGlmICh3aW5kb3cucXVpdE1hcEluZm8uaG9zdCA9PT0gd2luZG93LnF1aXRNYXBJbmZvLnJlZmVycmVyLnNwbGl0KCcvJylbMl0pIHtcbiAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHdpbmRvdy5xdWl0TWFwSW5mby5yZWZlcnJlcjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBPbiB2aWVudCBkJ3VuIGF1dHJlIHNpdGUsIGRvbmMgb24gc2UgZGlyaWdlIHZlcnMgbCdhY2N1ZWlsLlxuICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gJy8nO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHw6lyZXIgbGUgY2xpYyBzdXIgbGVzIGJvdXRvbnMgZGUgem9vbSBldCBkZSBkw6l6b29tLlxuICAgKi9cbiAgaW5pdFpvb21CdXR0b25zKCkge1xuICAgIGNvbnN0IHpvb21CdXR0b25JbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5qcy16b29tLWJ1dHRvbltkYXRhLXpvb209XCJpblwiXScpO1xuICAgIGNvbnN0IHpvb21CdXR0b25PdXQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtem9vbS1idXR0b25bZGF0YS16b29tPVwib3V0XCJdJyk7XG5cbiAgICB6b29tQnV0dG9uSW4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICBjb25zdCBDVVJSRU5UX1pPT00gPSB0aGlzLm1hcC5nZXRab29tKCk7XG4gICAgICB0aGlzLm1hcC5zZXRab29tKENVUlJFTlRfWk9PTSArIDEpO1xuICAgIH0pO1xuXG4gICAgem9vbUJ1dHRvbk91dC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgIGNvbnN0IENVUlJFTlRfWk9PTSA9IHRoaXMubWFwLmdldFpvb20oKTtcbiAgICAgIHRoaXMubWFwLnNldFpvb20oQ1VSUkVOVF9aT09NIC0gMSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogR8OpcmVyIGxlIGJvdXRvbiB0eXBlIGRlIGNhcnRlLlxuICAgKi9cbiAgaW5pdExheWVyc0J1dHRvbigpIHtcbiAgICAvLyBEw6lmaW5pciBsYSBsYXJnZXVyIGR1IHBvcHVwIHF1YW5kIGlsIGVzdCBvdXZlcnQgcG91ciBsJ2FuaW1hdGlvbi5cbiAgICBjb25zdCBsYXllcnNJbm5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5qcy1sYXllcnMtcG9wdXAnKTtcbiAgICBsYXllcnNJbm5lci5zdHlsZS53aWR0aCA9IGAke2xheWVyc0lubmVyLm9mZnNldFdpZHRofXB4YDtcblxuICAgIC8vIEfDqXJl
4084ciBsZXMgY2xpY3MgZGVzIGJvdXRvbnMgZGVzIHR5cGVzIGRlIGNhcnRlcy5cbiAgICBjb25zdCBidXR0b25zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmpzLWxheWVycy1idXR0b24nKTtcbiAgICBidXR0b25zLmZvckVhY2goKGJ1dHRvbikgPT4ge1xuICAgICAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgdGhpcy5tYXAuc2V0TWFwVHlwZUlkKGUuY3VycmVudFRhcmdldC5kYXRhc2V0LmxheWVyKTtcblxuICAgICAgICAvLyBFbmxldmVyIGxhIGNsYXNzZSBhY3RpdmUgw6AgdG91cyBsZXMgYm91dG9ucy5cbiAgICAgICAgYnV0dG9ucy5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICAgICAgaXRlbS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEFqb3V0ZXIgbGEgY2xhc3NlIGFjdGl2ZSDDoCBsJ2l0ZW0gY2xpcXXDqS5cbiAgICAgICAgZS5jdXJyZW50VGFyZ2V0LmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuICAgICAgICAvLyBBam91dGVyIGxlIGNvb2tpZSBwb3VyIHNlIHNvdXZlbmlyIGR1IHR5cGUgZGUgY2FydGUgc8OpbGVjdGlvbm7DqS5cbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2FjdGl2ZS1sYXllcicsIGUuY3VycmVudFRhcmdldC5kYXRhc2V0LmxheWVyKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gRW4gbW9iaWxlLCBsZSBob3ZlciBkdSBib3V0b24gbmUgZm9uY3Rpb25uZSBwYXMsIGRvbmMgb24gYWpvdXRlIHVuIMOpdsOpbmVtZW50IGNsaWMuXG4gICAgaWYgKGlzVG91Y2hEZXZpY2UpIHtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5qcy1sYXllcnMtcG9wdXAtYnV0dG9uJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICBlLmN1cnJlbnRUYXJnZXQucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoJ29wZW4nKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEfDqXJlciBsZSBjb29raWUgcG91ciBzYXZvaXIgcXVlbCBlc3QgbGUgdHlwZSBkZSBjYXJ0ZSBhY3RpdmUuXG4gICAgaWYgKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdhY3RpdmUtbGF5ZXInKSkge1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgLmpzLWxheWVycy1idXR0b25bZGF0YS1sYXllcj1cIiR7bG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2FjdGl2ZS1sYXllcicpfVwiXWApLmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuICAgICAgdGhpcy5tYXAuc2V0TWFwVHlwZUlkKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdhY3RpdmUtbGF5ZXInKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdhY3RpdmUtbGF5ZXInLCAncm9hZG1hcCcpO1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmpzLWxheWVycy1idXR0b25bZGF0YS1sYXllcj1cInJvYWRtYXBcIl0nKS5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR8OpcmVyIGxlIGNsaWMgc3VyIGxlIGJvdXRvbiBpbmZvcm1hdGlvbnMuXG4gICAqL1xuICBpbml0SW5mb1BvcHVwKCkge1xuICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtaW5mby1idXR0b24nKSAhPT0gbnVsbCkge1xuICAgICAgLy8gRMOpZmluaXIgbGEgaGF1dGV1ciBkdSBwb3B1cCBxdWFuZCBpbCBlc3Qgb3V2ZXJ0IHBvdXIgbCdhbmltYXRpb24uXG4gICAgICBjb25zdCBpbmZvSW5uZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtaW5mby1pbm5lci1jb250ZW50Jyk7XG4gICAgICBpbmZvSW5uZXIucGFyZW50RWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtpbmZvSW5uZXIub2Zmc2V0SGVpZ2h0fXB4YDtcblxuICAgICAgLy8gQ2xpYyBzdXIgbGUgYm91dG9uIHBvdXIgb3V2cmlyIGxlIHBvcHVwLlxuICAgICAgY29uc3QgaW5mb0J1dHRvbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5qcy1pbmZvLWJ1dHRvbicpO1xuICAgICAgaW5mb0J1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgIGUuY3VycmVudFRhcmdldC5wYXJlbnRFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2MtbWFwLWluZm8tcG9wdXAtLWNvbGxhcHNlZCcpO1xuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnY29sbGFwc2VkLWluZm9zJywgJ2ZhbHNlJyk7XG4gICAgICB9KTtcblxuICAgICAgLy8gQ2xpYyBzdXIgbGUgYm91dG9uIHBvdXIgZmVybWVyIGxlIHBvcHVwLlxuICAgICAgY29uc3QgY2xvc2VJbmZvQnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmpzLWNsb3NlLWluZm8tYnV0dG9uJyk7XG4gICAgICBjbG9zZUluZm9CdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICBlLmN1cnJlbnRUYXJnZXQucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2MtbWFwLWluZm8tcG9wdXAtLWNvbGxhcHNlZCcpO1xuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnY29sbGFwc2VkLWluZm9zJywgJ3RydWUnKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBHw6lyZXIgbGUgY29va2llIHBvdXIgc2F2b2lyIHNpIGxlIHBvcHVwIGVzdCBvdXZlcnQuXG4gICAgICBpZiAobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2NvbGxhcHNlZC1pbmZvcycpKSB7XG4gICAgICAgIGlmIChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnY29sbGFwc2VkLWluZm9zJykgPT09ICdmYWxzZScpIHtcbiAgICAgICAgICBkb2
4084N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtaW5mby1idXR0b24nKS5wYXJlbnRFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2MtbWFwLWluZm8tcG9wdXAtLWNvbGxhcHNlZCcpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnY29sbGFwc2VkLWluZm9zJywgJ2ZhbHNlJyk7XG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5qcy1pbmZvLWJ1dHRvbicpLnBhcmVudEVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnYy1tYXAtaW5mby1wb3B1cC0tY29sbGFwc2VkJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFbDqXJpZmllIGxhIHByw6lzZW5jZSBkZSBsJ292ZXJsYXkgZGUgcGFydGFnZS5cbiAgICovXG4gIGNoZWNrU2hhcmVPdmVybGF5KCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKHR5cGVvZiB3aW5kb3cub3ZlcmxheVNoYXJlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0NBUlRFIElOVEVSQUNUSVZFIC0+IExlIHRow6htZSBkb2l0IHJlbmRyZSBkaXNwb25pYmxlIHVuIG92ZXJsYXkgXFwnb3ZlcmxheVNoYXJlXFwnIGRhbnMgbGUgd2luZG93IHBvdXIgYXNzdXJlciBsZSBmb25jdGlvbm5lbWVudCBkZSBsYSBmb25jdGlvbiBwYXJ0YWdlLicpO1xuICAgICAgfVxuICAgIH0sIDUwMCk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGlzZXIgbGVzIGZvbmN0aW9ubmFsaXTDqXMgZGUgbCdpbnRlcmZhY2UgdXRpbGlzYXRldXIgZGUgbGEgY2FydGUuXG4gICAqIEBwYXJhbSB7Z29vZ2xlLm1hcHMuTWFwfSBtYXAgLSBMYSBjYXJ0ZSBHb29nbGUgTWFwcy5cbiAgICovXG4gIGluaXQobWFwKSB7XG4gICAgdGhpcy5tYXAgPSBtYXA7XG4gICAgdGhpcy5pbml0UXVpdEJ1dHRvbigpO1xuICAgIHRoaXMuaW5pdFpvb21CdXR0b25zKCk7XG4gICAgdGhpcy5pbml0TGF5ZXJzQnV0dG9uKCk7XG4gICAgdGhpcy5pbml0SW5mb1BvcHVwKCk7XG4gICAgdGhpcy5jaGVja1NoYXJlT3ZlcmxheSgpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBPQlNFUlZFUiB9IGZyb20gJy4uL3BsdWdpbnMnO1xuXG4vLyBQZXJtZXQgZGUgZG9ubmVyIGxhIGhhdXRldXIgZXhhY3RlIGVuIG1vYmlsZSBkZSAxMDB2aFxuLy8gQ3NzIC0+IGhlaWdodDogY2FsYyh2YXIoLS12aCwgMXZoKSAqIDEwMCk7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBodW5kcmVkVkgoKSB7XG4gIGZ1bmN0aW9uIHNldEhlaWdodCgpIHtcbiAgICBjb25zdCB2aCA9IHdpbmRvdy5pbm5lckhlaWdodCAqIDAuMDE7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCctLXZoLW1hcCcsIGAke3ZofXB4YCk7XG4gIH1cblxuICBPQlNFUlZFUi5hZGQoe1xuICAgIG5hbWU6ICdodW5kcmVkVkgnLFxuICAgIGV2ZW50czogJ3Jlc2l6ZSBsb2FkJyxcbiAgICB0YXJnZXRzOiAnd2luZG93JyxcbiAgICBmdW5jdGlvbjogc2V0SGVpZ2h0LFxuICB9KTtcbiAgT0JTRVJWRVIub24oJ2h1bmRyZWRWSCcpO1xufVxuIiwiLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBGb25jdGlvbnMgcmVsacOpZXMgw6AgbGEgY2FydGVcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBJbXBvcnRhdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmltcG9ydCB7IE1hcmtlckNsdXN0ZXJlciB9IGZyb20gJ0Bnb29nbGVtYXBzL21hcmtlcmNsdXN0ZXJlcic7XG5pbXBvcnQgeyBIVE1MTWFya2VyLCBpbml0TWFya2VyIH0gZnJvbSAnLi9tYXBNYXJrZXInO1xuaW1wb3J0IHsgSFRNTExvY2F0aW9uTWFya2VyLCBpbml0TG9jYXRpb25NYXJrZXIgfSBmcm9tICcuL21hcExvY2F0aW9uTWFya2VyJztcbmltcG9ydCBIVE1MTWFya2VyQ2x1c3RlciBmcm9tICcuL21hcE1hcmtlckNsdXN0ZXInO1xuaW1wb3J0IHtcbiAgY2hhbmdlQ2F0ZWdvcnksIGNoYW5nZVN1YmNhdGVnb3J5LCBzZWxlY3RMb2NhdGlvbiwgcmV0dXJuVG9Sb290LCByZXR1cm5Ub1N1YmNhdGVnb3JpZXMsIHJldHVybkZyb21Mb2NhdGlvbkRldGFpbCxcbiAgbG9jYXRpb25DbGljaywgcG9wdXBDbGljaywgY2xvc2VQb3B1cENsaWNrLCBtYW5hZ2VCYWNrQnV0dG9uLFxufSBmcm9tICcuL21hcE1hbmFnZXInO1xuaW1wb3J0IHsgaGFzR2VvbG9jYXRpb24sIGlzSW5ab25lIH0gZnJvbSAnLi9tYXBVdGlscyc7XG5pbXBvcnQgeyBlbmFibGVSZXNldEJ1dHRvbnMgfSBmcm9tICcuL21hcFBhbmVscyc7XG5pbXBvcnQgbWFwU3R5bGUgZnJvbSAnLi9tYXBTdHlsZSc7IC8vIFLDqWN1cMOocmUgbGUgc3R5bGUgZGUgbGEgY2FydGVcbmltcG9ydCBNYXBVcmwgZnJvbSAnLi9tYXBVcmwnO1xuXG5pbXBvcnQgQm90dG9tU2hlZXQgZnJvbSAnLi9Cb3R0b21TaGVldCc7XG5pbXBvcnQgTWFwVWkgZnJvbSAnLi9NYXBVaSc7XG5pbXBvcnQgaHVuZHJlZFZIIGZyb20gJy4vaHVuZHJlZFZIJztcblxud2luZG93LmNoYW5nZUNhdGVnb3J5ID0gY2hhbmdlQ2F0ZWdvcnk7XG53aW5kb3cuY2hhbmdlU3ViY2F0ZWdvcnkgPSBjaGFuZ2VTdWJjYXRlZ29yeTtcbndpbmRvdy5zZWxlY3RMb2NhdGlvbiA9IHNlbGVjdExvY2F0aW9uO1xud2luZG93LnJldHVyblRvUm9vdCA9IHJldHVyblRvUm9vdDtcbndpbmRvdy5yZXR1cm5Ub1N1YmNhdGVnb3JpZXMgPSByZXR1cm5Ub1N1YmNhdGVnb3JpZXM7XG53aW5kb3cucmV0dXJuRnJvbUxvY2F0aW9uRGV0YWlsID0gcmV0dXJuRnJvbUxvY2F0aW9uRGV0YWlsO1xud2luZG93LmxvY2F0aW9uQ2xpY2sgPSBsb2NhdGlvbkNsaWNrO1xud2luZG93LnBvcHVwQ2xpY2sgPSBwb3B1cENsaWNrO1xud2luZG93LmNsb3NlUG9wdXBDbGljayA9IGNsb3NlUG9wdXBDbGljaztcblxud2luZG93LmlzQ2xvc2luZyA9IGZhbHNlO1xuXG4vKiBnbG9iYWwgZ29vZ2xlICovXG5cbmxldCBtYXAgPSBudWxsO1xuZXhwb3J0IGNvbnN0IHVybE1hbmFnZXIgPSBuZXcgTWFwVXJsKCk7XG5leHBvcnQgY29uc3QgYm90dG9tU2hlZXQgPSBuZXcgQm90dG9tU2hlZXQoKTtcbmV4cG9ydCBjb25zdCBtYXBVaSA9IG5ldyBNYXBVaSgpO1xuXG5jb25zdCBtYXBCb3VuZHMgPSB7IC8vIFpvbmUgZGFucyBsYXF1ZWxsZSBvbiBwb3VycmEgZ2xpc3NlciBkYW5zIGxhIGNhcnRlXG4gIG5vcnRoOiB3aW5kb3cubWFwQ29uZmlnLmNlbnRlcl9sYXQgKyB3aW5kb3cubWFwQ29uZmlnLmJvdW5kc19saW1pdCAvID
4084IsXG4gIHNvdXRoOiB3aW5kb3cubWFwQ29uZmlnLmNlbnRlcl9sYXQgLSB3aW5kb3cubWFwQ29uZmlnLmJvdW5kc19saW1pdCAvIDIsXG4gIHdlc3Q6IHdpbmRvdy5tYXBDb25maWcuY2VudGVyX2xuZyAtIHdpbmRvdy5tYXBDb25maWcuYm91bmRzX2xpbWl0LFxuICBlYXN0OiB3aW5kb3cubWFwQ29uZmlnLmNlbnRlcl9sbmcgKyB3aW5kb3cubWFwQ29uZmlnLmJvdW5kc19saW1pdCxcbn07XG5cbi8qKlxuICogRmFpcmUgYWZmaWNoZXIgbGEgY2FydGUuXG4gKi9cbmZ1bmN0aW9uIGluaXRNYXAoKSB7XG4gIG1hcCA9IG5ldyBnb29nbGUubWFwcy5NYXAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmpzLW1hcC1jb250YWluZXInKSwge1xuICAgIHpvb206IDE1LFxuICAgIGNlbnRlcjoge1xuICAgICAgbGF0OiB3aW5kb3cubWFwQ29uZmlnLmNlbnRlcl9sYXQsXG4gICAgICBsbmc6IHdpbmRvdy5tYXBDb25maWcuY2VudGVyX2xuZyxcbiAgICB9LFxuICAgIGNsaWNrYWJsZUljb25zOiBmYWxzZSxcbiAgICBzdHlsZXM6IG1hcFN0eWxlLFxuICAgIGRpc2FibGVEZWZhdWx0VUk6IHRydWUsXG4gICAgZ2VzdHVyZUhhbmRsaW5nOiAnZ3JlZWR5JyxcbiAgICBtaW5ab29tOiB3aW5kb3cubWFwQ29uZmlnLnpvb21fbWluLFxuICAgIG1heFpvb206IHdpbmRvdy5tYXBDb25maWcuem9vbV9tYXgsXG4gICAgcmVzdHJpY3Rpb246IHtcbiAgICAgIGxhdExuZ0JvdW5kczogbWFwQm91bmRzLFxuICAgICAgc3RyaWN0Qm91bmRzOiBmYWxzZSxcbiAgICB9LFxuICB9KTtcblxuICB3aW5kb3cubWFya2VyQ2x1c3RlcmVyID0gbmV3IE1hcmtlckNsdXN0ZXJlcih7XG4gICAgbWFwLFxuICAgIHVuZGVmaW5lZCxcbiAgICByZW5kZXJlcjoge1xuICAgICAgcmVuZGVyOiAoeyBjb3VudCwgcG9zaXRpb24sIGJvdW5kcyB9KSA9PiBuZXcgSFRNTE1hcmtlckNsdXN0ZXIoe1xuICAgICAgICBsYXRsbmc6IHBvc2l0aW9uLFxuICAgICAgICBtYXAsXG4gICAgICAgIGNvdW50LFxuICAgICAgICBib3VuZHMsXG4gICAgICB9KSxcbiAgICB9LFxuICB9KTtcblxuICAvLyBJbml0aWFsaXNhdGlvbiBkZXMgbWFycXVldXJzIHN1aXRlIGF1IGNoYXJnZW1lbnQgZGUgR29vZ2xlIE1hcHMuXG4gIHVybE1hbmFnZXIuaW5pdCgpO1xuICBpbml0TWFya2VyKCk7XG59XG5cbi8qKlxuICogTWV0IMOgIGpvdXIgbGVzIG1hcnF1ZXVycyBkZSBsYSBjYXJ0ZSBlbiB1dGlsaXNhbnQgbGVzIGRvbm7DqWVzIGZvdXJuaWVzLlxuICogQHBhcmFtIHtvYmplY3R9IGRhdGEgLSBMZXMgZG9ubsOpZXMgZGVzIFBPSXMuXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZU1hcmtlcnMoZGF0YSkge1xuICBjb25zdCB7IHBvaXMgfSA9IGRhdGE7XG5cbiAgcG9pcy5mb3JFYWNoKChwb2kpID0+IHtcbiAgICBjb25zdCBtYXJrZXJQb3MgPSBwb2kucG9zaXRpb247XG4gICAgY29uc3QgaHRtbE1hcmtlciA9IG5ldyBIVE1MTWFya2VyKHtcbiAgICAgIG1hcCxcbiAgICAgIGxhdDogbWFya2VyUG9zLmxhdCxcbiAgICAgIGxuZzogbWFya2VyUG9zLmxuZyxcbiAgICAgIGlkOiBwb2kuaWQsXG4gICAgICBzbHVnOiBwb2kuc2x1ZyxcbiAgICAgIGttbFVybDogcG9pLmttbCxcbiAgICAgIGNhdGVnb3JpZXNTbHVnOiBwb2kuY2F0ZWdvcmllc1NsdWcsXG4gICAgICBhY2Nlc3NpYmlsaXR5OiBwb2kuYWNjZXNzaWJpbGl0eSxcbiAgICAgIHRpdGxlOiBwb2kudGl0bGUsXG4gICAgICBjYXRlZ29yeTogcG9pLmNhdGVnb3J5LFxuICAgICAgaW1hZ2U6IHBvaS5pbWFnZSxcbiAgICB9KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGxvYWRNYXJrZXJzKCkge1xuICBpZiAoIW1hcCkgcmV0dXJuO1xuXG4gIC8vIENyw6llciB1bmUgbm91dmVsbGUgaW5zdGFuY2UgZGUgbCdvYmpldCBYTUxIdHRwUmVxdWVzdC5cbiAgY29uc3QgeGhyID0gbmV3IFhNTEh0dHBSZXF1
4084ZXN0KCk7XG5cbiAgLy8gQ29uZmlndXJlciBsYSByZXF1w6p0ZSBhdmVjIGxhIG3DqXRob2RlIEhUVFAgZXQgbCdVUkwuXG4gIHhoci5vcGVuKCdHRVQnLCAnL2FwaS92MS9wb2lzJywgdHJ1ZSk7XG5cbiAgLy8gRMOpZmluaXIgbGEgZm9uY3Rpb24gw6AgZXjDqWN1dGVyIGxvcnMgZGUgbGEgcsOpY2VwdGlvbiBkZSBsYSByw6lwb25zZS5cbiAgeGhyLm9ubG9hZCA9IGZ1bmN0aW9uIG9uTG9hZCgpIHtcbiAgICBpZiAoeGhyLnN0YXR1cyA+PSAyMDAgJiYgeGhyLnN0YXR1cyA8IDQwMCkge1xuICAgICAgLy8gTGEgcmVxdcOqdGUgYSByw6l1c3NpLlxuICAgICAgdXBkYXRlTWFya2VycyhKU09OLnBhcnNlKHhoci5yZXNwb25zZVRleHQpLmRhdGEpO1xuICAgICAgSFRNTE1hcmtlci5zaG93QWxsKCk7XG5cbiAgICAgIC8vIFMnaWwgeSBhIHF1ZWxxdWUgY2hvc2UgZGFucyBsJ1VSTCwgY2hhcmdlciBzdXIgbGEgY2FydGUgbGVzIGJvbm5lcyBwdWNlcy5cbiAgICAgIC8vIEFmZmljaGVyIGxlcyBwdWNlcyBkZSBsYSBjYXTDqWdvcmllIGFjdGl2ZS5cbiAgICAgIGlmICh1cmxNYW5hZ2VyLmdldFNsdWdDYXRlZ29yeSgpICYmICF1cmxNYW5hZ2VyLmdldFNsdWdTdWJjYXRlZ29yeSgpICYmICF1cmxNYW5hZ2VyLmdldFNsdWdMb2NhbGlzYXRpb24oKSkge1xuICAgICAgICBIVE1MTWFya2VyLnNob3dDYXRlZ29yeSh1cmxNYW5hZ2VyLmdldFNsdWdDYXRlZ29yeSgpKTtcbiAgICAgICAgZW5hYmxlUmVzZXRCdXR0b25zKCk7XG4gICAgICB9XG4gICAgICAvLyBBZmZpY2hlciBsZXMgcHVjZXMgZGUgbGEgc291cy1jYXTDqWdvcmllIGFjdGl2ZS5cbiAgICAgIGlmICh1cmxNYW5hZ2VyLmdldFNsdWdTdWJjYXRlZ29yeSgpICYmICF1cmxNYW5hZ2VyLmdldFNsdWdMb2NhbGlzYXRpb24oKSkge1xuICAgICAgICBIVE1MTWFya2VyLnNob3dDYXRlZ29yeSh1cmxNYW5hZ2VyLmdldFNsdWdTdWJjYXRlZ29yeSgpKTtcbiAgICAgICAgZW5hYmxlUmVzZXRCdXR0b25zKCk7XG4gICAgICB9XG4gICAgICAvLyBBZmZpY2hlciBsYSBsb2NhbGlzYXRpb24uXG4gICAgICBpZiAodXJsTWFuYWdlci5nZXRTbHVnTG9jYWxpc2F0aW9uKCkpIHtcbiAgICAgICAgSFRNTE1hcmtlci5zaG93VW5pcXVlKHVybE1hbmFnZXIuZ2V0U2x1Z0xvY2FsaXNhdGlvbigpKTtcbiAgICAgICAgZW5hYmxlUmVzZXRCdXR0b25zKCk7XG4gICAgICB9XG5cbiAgICAgIEhUTUxNYXJrZXIucmVmcmVzaENsdXN0ZXJlcigpO1xuICAgICAgSFRNTE1hcmtlci5maXRCb3VuZHMoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWwgeSBhIGV1IHVuZSBlcnJldXIuXG4gICAgICBjb25zb2xlLmVycm9yKGBFcnJldXI6ICR7eGhyLnN0YXR1c30hYCk7XG4gICAgfVxuICB9O1xuXG4gIHhoci5zZW5kKCk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdvb2dsZU1hcCgpIHtcbiAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5qcy1tYXAtY29udGFpbmVyJykpIHtcbiAgICBodW5kcmVkVkgoKTtcbiAgICBpbml0TWFwKCk7XG4gICAgbG9hZE1hcmtlcnMoKTtcblxuICAgIGJvdHRvbVNoZWV0LmluaXQoKTtcbiAgICBtYXBVaS5pbml0KG1hcCk7XG4gICAgbWFuYWdlQmFja0J1dHRvbigpO1xuXG4gICAgLy8gUydpbCB5IGEgdW5lIGxvY2FsaXNhdGlvbiBkJ2FjdGl2ZSwgbW9udGVyIGxlIHBhbm5lYXUgbW9iaWxlLlxuICAgIGlmICh1cmxNYW5hZ2VyLnNsdWdMb2NhbGlzYXRpb24pIHtcbiAgICAgIGJvdHRvbVNoZWV0Lm9wZW5TaGVldE1heEhlaWdodCgpO1xuICAgIH1cblxuICAgIGlmIChoYXNHZW9sb2NhdGlvbigpKSB7XG4gICAgICBuYXZpZ2F0b3IuZ2VvbG9jYXRpb24uZ2V0Q3VycmVudFBvc2l0aW9uKChwb3NpdGlvbikgPT4ge1xuICAgICAgICBjb25zdCBsYXQgPSBwb3NpdGlvbi5jb29yZHMubGF0aXR1ZGU7XG4gICAgICAgIGNvbnN0IGxuZyA9IHBvc2l0aW9uLmNvb3Jkcy5sb25naXR1ZGU7XG5cbiAgICAgICAgY29uc3QgY2VudGVyQnRuQ29udGFpbmVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmpzLWNlbnRlci1vbi1sb2NhdGlvbi1jb250YWluZXInKTtcbiAgICAgICAgY29uc3QgY2VudGVyQnRuID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmpzLWNlbnRlci1vbi1sb2NhdGlvbicpO1xuICAgICAgICBpZiAoaXNJblpvbmUobGF0LCBsbmcsIG1hcEJvdW5kcykpIHtcbiAgICAgICAgICBjZW50ZXJCdG5Db250YWluZXIuY2xhc3NMaXN0LnJlbW92ZSgnaXMtaGlkZGVuJyk7XG4gICAgICAgICAgY2VudGVyQnRuLmRpc2FibGVkID0gZmFsc2U7XG5cbiAgICAgICAgICBpbml0TG9jYXRpb25NYXJrZXIoKTtcbiAgICAgICAgICBjb25zdCBodG1sTG9jYXRpb25NYXJrZXIgPSBuZXcgSFRNTExvY2F0aW9uTWFya2VyKHtcbiAgICAgICAgICAgIG1hcCxcbiAgICAgICAgICAgIGxhdCxcbiAgICAgICAgICAgIGxuZyxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtY2VudGVyLW9uLWxvY2F0aW9uJykpIHtcbiAgICAgICAgICAgIGNlbnRlckJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgICAgbWFwLnNldFpvb20oMTcpO1xuICAgICAgICAgICAgICBtYXAucGFuVG8obmV3IGdvb2dsZS5tYXBzLkxhdExuZyhsYXQsIGxuZykpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cbiIsIi8qXG5DZXR0ZSBjbGFzc2UgZ8OocmUgbGVzIG1hcnF1ZXVycywgb24gdXRpbGlzZSBsZXMgcHJvdG90eXBlcyDDoCBjYXVzZSBk4oCZaW5jb21wYXRpYmlsaXTDqXMgYXZlYyBHb29nbGUgTWFwXG4qL1xuXG4vKiBnbG9iYWwgZ29vZ2xlICovXG5cbi8vIGRlZmluaXIgdW5lIHZhcmlhYmxlIHBvdXIgcmVjZXZvaXIgbGEgZnV0dXJlIGTDqWZpbml0aW9uIGRlIG1hcnF1ZXVyXG5leHBvcnQgbGV0IEhUTUxMb2NhdGlvbk1hcmtlcjtcblxuLy8gaW5pdE1hcmtlciBlc3QgYXBwZWzDqSBsb3JzcXVlIGdvb2dsZW1hcCBlc3QgY2hhcmfDqVxuZXhwb3J0IGZ1bmN0aW9uIGluaXRMb2NhdGlvbk1hcmtlcigpIHtcbiAgLy8gbG9yc3F1ZSBHb29nbGVNYXAgZXN0IGNoYXJnw6kgb24gZGVjbGFyZSB1bi
4084BvYmpldCBldCBzZXMgcHJvdG90eXBlc1xuICBIVE1MTG9jYXRpb25NYXJrZXIgPSBmdW5jdGlvbiBodG1sTG9jYXRpb25NYXJrZXIoYXJncykge1xuICAgIHRoaXMubWFwID0gYXJncy5tYXA7XG4gICAgdGhpcy5sYXQgPSBhcmdzLmxhdDtcbiAgICB0aGlzLmxuZyA9IGFyZ3MubG5nO1xuICAgIHRoaXMucG9zID0gbmV3IGdvb2dsZS5tYXBzLkxhdExuZyhhcmdzLmxhdCwgYXJncy5sbmcpO1xuXG4gICAgSFRNTExvY2F0aW9uTWFya2VyLm1hcCA9IGFyZ3MubWFwO1xuXG4gICAgaWYgKHRoaXMubGF0ICE9IG51bGwgJiYgdGhpcy5sbmcgIT0gbnVsbCkge1xuICAgICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBkaXYuY2xhc3NMaXN0LmFkZCgnYy1tYXAtbG9jYXRpb24tcGluJyk7XG4gICAgICBkaXYuc2V0QXR0cmlidXRlKCd0aXRsZScsIHdpbmRvdy5tYXBDb25maWcuZ2VvbG9jYXRpb25fbGFiZWwpO1xuXG4gICAgICBkaXYuaW5uZXJIVE1MID0gdGhpcy5yZW5kZXIoKTtcbiAgICAgIHRoaXMuZGl2ID0gZGl2O1xuICAgIH1cbiAgICB0aGlzLnNldE1hcCh0aGlzLm1hcCk7XG5cbiAgICAvLyBzaSBvbiBjbGlxdWUgc3VyIGxhIHBpbiwgY2VudGVyIGxhIGNhcnRlIHN1ciBsJ2VtcGxhY2VtZW50XG4gICAgZ29vZ2xlLm1hcHMuZXZlbnQuYWRkRG9tTGlzdGVuZXIodGhpcy5kaXYsICdjbGljaycsICgpID0+IHtcbiAgICAgIHRoaXMubWFwLnBhblRvKHRoaXMucG9zKTtcbiAgICB9KTtcbiAgfTtcblxuICBIVE1MTG9jYXRpb25NYXJrZXIucHJvdG90eXBlID0gbmV3IGdvb2dsZS5tYXBzLk92ZXJsYXlWaWV3KCk7XG5cbiAgLy8gSW5pdCB5b3VyIGh0bWwgZWxlbWVudCBoZXJlXG4gIEhUTUxMb2NhdGlvbk1hcmtlci5wcm90b3R5cGUub25BZGQgPSBmdW5jdGlvbiBvbkFkZCgpIHtcbiAgICBjb25zdCBwYW5lcyA9IHRoaXMuZ2V0UGFuZXMoKTtcbiAgICAvLyBTaSBwYXMgZGUgbGF0aXR1ZGUgZXQgZGUgbG9uZ2l0dWRlLCBj4oCZZXN0IHVuaXF1ZW1lbnQgdW4gS01MLCBvbiBza2lwIGzigJlhZmZpY2hhZ2VcbiAgICBpZiAodGhpcy5sYXQgPT0gbnVsbCB8fCB0aGlzLmxuZyA9PSBudWxsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcGFuZXMub3ZlcmxheUltYWdlLmFwcGVuZENoaWxkKHRoaXMuZGl2KTtcbiAgfTtcblxuICAvKipcbiAgICogU3VwcHJpbWUgbGUgbWFycXVldXIuXG4gICAqIEBtZW1iZXJvZiBIVE1MTG9jYXRpb25NYXJrZXIucHJvdG90eXBlXG4gICAqL1xuICBIVE1MTG9jYXRpb25NYXJrZXIucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uIHJlbW92ZSgpIHtcbiAgICBpZiAodGhpcy5kaXYpIHtcbiAgICAgIHRoaXMuZGl2LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5kaXYpO1xuICAgICAgdGhpcy5kaXYgPSBudWxsO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogUmVuZHJlIGxlIGNvbnRlbnUgSFRNTCBkdSBtYXJxdWV1ciBlbiBmb25jdGlvbiBkZSBzZXMgcHJvcHJpw6l0w6lzLlxuICAgKiBAbWVtYmVyb2YgSFRNTExvY2F0aW9uTWFya2VyLnByb3RvdHlwZVxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIExlIGNvbnRlbnUgSFRNTCBkdSBtYXJxdWV1ci5cbiAgICovXG4gIEhUTUxMb2NhdGlvbk1hcmtlci5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgIHJldHVybiBgXG4gICAgICA8c3BhbiBjbGFzcz1cImMtbWFwLWxvY2F0aW9uLXBpbl9fYnVsbGV0XCI+P
4084C9zcGFuPlxuICAgIGA7XG4gIH07XG5cbiAgSFRNTExvY2F0aW9uTWFya2VyLnByb3RvdHlwZS5kcmF3ID0gZnVuY3Rpb24gZHJhdygpIHtcbiAgICBjb25zdCBvdmVybGF5UHJvamVjdGlvbiA9IHRoaXMuZ2V0UHJvamVjdGlvbigpO1xuICAgIGNvbnN0IHBvc2l0aW9uID0gb3ZlcmxheVByb2plY3Rpb24uZnJvbUxhdExuZ1RvRGl2UGl4ZWwodGhpcy5wb3MpO1xuICAgIHRoaXMuZGl2LnN0eWxlLmxlZnQgPSBgJHtwb3NpdGlvbi54fXB4YDtcbiAgICB0aGlzLmRpdi5zdHlsZS50b3AgPSBgJHtwb3NpdGlvbi55fXB4YDtcbiAgfTtcblxuICAvLyBNZXRob2RlIGFwcGVsw6llIGF1dG9tYXRpcXVlbWVudCBzaSBvbiBzZXRNYXAobnVsbCkgbOKAmW9iamV0LCB2b2lyIGRvYyBHb29nbGVcbiAgSFRNTExvY2F0aW9uTWFya2VyLnByb3RvdHlwZS5vblJlbW92ZSA9IGZ1bmN0aW9uIG9uUmVtb3ZlKCkge1xuICAgIGlmICh0aGlzLmRpdikge1xuICAgICAgdGhpcy5kaXYucmVtb3ZlKCk7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICAvKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgUFJPUFJJw4lUw4lTIEVUIE1FVEhPREVTIFNUQVRJQ1NcbiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xuICBIVE1MTG9jYXRpb25NYXJrZXIubWFwID0gbnVsbDtcblxuICB3aW5kb3cuSFRNTExvY2F0aW9uTWFya2VyID0gSFRNTExvY2F0aW9uTWFya2VyO1xufVxuIiwiaW1wb3J0IHsgYWN0aXZhdGVQYW5lbFZpZXcsIGVuYWJsZVJlc2V0QnV0dG9ucywgZGlzYWJsZVJlc2V0QnV0dG9ucyB9IGZyb20gJy4vbWFwUGFuZWxzJztcbmltcG9ydCB7IEhUTUxNYXJrZXIgfSBmcm9tICcuL21hcE1hcmtlcic7XG5pbXBvcnQgeyB1cmxNYW5hZ2VyLCBib3R0b21TaGVldCB9IGZyb20gJy4vbWFwJztcbmltcG9ydCB7IGlzVG91Y2hEZXZpY2UgfSBmcm9tICcuL21hcFV0aWxzJztcblxuLyoqXG4gKiBDaGFuZ2VyIGxhIGNhdMOpZ29yaWUgYWN0aXZlLlxuICogQHBhcmFtIHtzdHJpbmd9IHNsdWcgLSBMZSBzbHVnIGRlIGxhIGNhdMOpZ29yaWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGFuZ2VDYXRlZ29yeShzbHVnKSB7XG4gIHVybE1hbmFnZXIuc2V0U2x1Z0NhdGVnb3J5KHNsdWcpO1xuICBIVE1MTWFya2VyLnNob3dDYXRlZ29yeShzbHVnKTtcbiAgSFRNTE1hcmtlci5maXRCb3VuZHMoKTtcblxuICBhY3RpdmF0ZVBhbmVsVmlldygnc3ViY2F0ZWdvcmllcycpO1xuICBlbmFibGVSZXNldEJ1dHRvbnMoKTtcbn1cblxuLyoqXG4gKiBDaGFuZ2VyIGxhIHNvdXMtY2F0w6lnb3JpZSBhY3RpdmUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc2x1ZyAtIExlIHNsdWcgZGUgbGEgc291cy1jYXTDqWdvcmllLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2hhbmdlU3ViY2F0ZWdvcnkoc2x1Zykge1xuICB1cmxNYW5hZ2VyLnNldFNsdWdTdWJDYXRlZ29yeShzbHVnKTtcbiAgSFRNTE1hcmtlci5zaG93Q2F0ZWdvcnkoc2x1Zyk7XG4gIEhUTUxNYXJrZXIuZml0Qm91bmRzKCk7XG4gIEhUTUxNYXJrZXIuZGlzYWJsZUFsbCgpO1xuXG4gIGFjdGl2YXRlUGFuZWxWaWV3KCdsb2NhdGlvbnMnKTtcbn1cblxuLyoqXG4gKiBDaGFuZ2VyIGxhIGxvY2FsaXNhdGlvbiBhY3RpdmUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc2x1ZyAtIExlIHNsdWcgZGUgbGEgbG9jYWxpc2F0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VsZWN0TG9jYXRpb24oc2x1Zykge1xuICB1cmxNYW5hZ2VyLnNldFNsdWdMb2NhbGlzYXRpb24oc2x1Zyk7XG4gIEhUTUxNYXJrZXIuc2hvd1VuaXF1ZShzbHVnKTtcbiAgSFRNTE1hcmtlci5maXRCb3VuZHMoKTtcblxuICBhY3RpdmF0ZVBhbmVsVmlldygnbG9jYXRpb24tZGV0YWlsJyk7XG59XG5cbi8qKlxuICogUmV2ZW5pciDDoCBsYSBsaXN0ZSBkZXMgY2F0w6lnb3JpZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXR1cm5Ub1Jvb3QoKSB7XG4gIHVybE1hbmFnZXIucmVzZXRTbHVnKCk7XG4gIEhUTUxNYXJrZXIuaGlkZUFsbFBvcHVwKCk7XG4gIEhUTUxNYXJrZXIuc2hvd0FsbCgpO1xuICBIVE1MTWFya2VyLmZpdEJvdW5kcygpO1xuICBIVE1MTWFya2VyLmRpc2FibGVBbGwoKTtcblxuICBhY3RpdmF0ZVBhbmVsVmlldygnY2F0ZWdvcmllcycpO1xuICBkaXNhYmxlUmVzZXRCdXR0b25zKCk7XG59XG5cbi8qKlxuICogUmV2ZW5pciDDoCBsYSBsaXN0ZSBkZXMgc291cy1jYXTDqWdvcmllcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJldHVyblRvU3ViY2F0ZWdvcmllcyhzbHVnKSB7XG4gIHVybE1hbmFnZXIucmVzZXRTdWJjYXRlZ29yeSgpO1xuICBIVE1MTWFya2VyLmhpZGVBbGxQb3B1cCgpO1xuICBIVE1MTWFya2VyLnNob3dDYXRlZ29yeShzbHVnKTtcbiAgSFRNTE1hcmtlci5maXRCb3VuZHMoKTtcblxuICBhY3RpdmF0ZVBhbmVsVmlldygnc3ViY2F0ZWdvcmllcycpO1xufVxuXG4vKipcbiAqIFJldmVuaXIgw6AgbGEgbGlzdGUgZGUgbG9jYWxpc2F0aW9ucy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzbHVnIC0gTGUgc2x1ZyBkZSBsYSBsb2NhbGlzYXRpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXR1cm5Gcm9tTG9jYXRpb25EZXRhaWwoc2x1Zykge1xuICB1cmxNYW5hZ2VyLnJlc2V0TG9jYXRpb24oKTtcbiAgaWYgKHVybE1hbmFnZXIuZ2V0U2x1Z1N1YmNhdGVnb3J5KCkpIHtcbiAgICAvLyBJbCB5IGEgdW5lIHNvdXMtY2F0w6lnb3JpZSwgb24gcmV0b3VybmUgw6AgbGEgbGlzdGUgZGVzIGxvY2FsaXNhdGlvbnMuXG4gICAgSFRNTE1hcmtlci5zaG93Q2F0ZWdvcnkoc2x1Zyk7XG4gICAgYWN0aXZhdGVQYW5lbFZpZXcoJ2xvY2F0aW9ucycpO1xuICB9IGVsc2UgaWYgKHVybE1hbmFnZXIuZ2V0U2x1Z0NhdGVnb3J5KCkpIHtcbiAgICAvLyBBdWN1bmUgc291cy1jYXTDqWdvcmllLCBvbiByZXRvdXJuZSDDoCBsYSBsaXN0ZSBkZXMgc291cy1jYXTDqWdvcmllcy5cbiAgICBIVE1MTWFya2VyLnNob3dDYXRlZ29yeShzbHVnKTtcbiAgICBhY3RpdmF0ZVBhbmVsVmlldygnc3ViY2F0ZWdvcmllcycpO1xuICB9IGVsc2Uge1xuICAgIHVybE1hbmFnZXIucmVzZXRMb2NhdGlvbigpO1xuICAgIC8vIEF1Y3VuZSBzb3VzLWNhdMOpZ29yaWUgb3UgY2F0w6lnb3JpZSwgb24gcmV0b3VybmUgw6AgbGEgbGlzdGUgZGVzIGNhdMOpZ29yaWVzLlxuICAgIEhUTUxNYXJrZXIuc2hvd0FsbCgpO1xuICAgIGFjdGl2YXRlUGFuZWxWaWV3KCdjYXRlZ29yaWVzJyk7XG4gIH1cblxuICB
4084IVE1MTWFya2VyLmhpZGVBbGxQb3B1cCgpO1xuICBIVE1MTWFya2VyLmRpc2FibGVBbGwoKTsgLy8gRMOpc2FjdGl2ZXIgbGEgcHVjZSBxdWkgw6l0YWl0IGFjdGl2ZS5cbiAgSFRNTE1hcmtlci5maXRCb3VuZHMoKTtcbn1cblxuLyoqXG4gKiBDbGlxdWVyIHN1ciB1bmUgcHVjZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzbHVnIC0gTGUgc2x1ZyBkZSBsYSBsb2NhbGlzYXRpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2NhdGlvbkNsaWNrKHNsdWcpIHtcbiAgSFRNTE1hcmtlci5oaWRlQWxsUG9wdXAoc2x1Zyk7XG4gIEhUTUxNYXJrZXIudG9nZ2xlUG9wdXAoc2x1Zyk7XG4gIGVuYWJsZVJlc2V0QnV0dG9ucygpO1xuXG4gIC8vIFNpIG9uIGVzdCBlbiBtb2JpbGUsIGNlbnRyZXIgc3VyIGxhIHB1Y2UuXG4gIGlmIChpc1RvdWNoRGV2aWNlKCkpIHtcbiAgICBIVE1MTWFya2VyLmNlbnRlcihzbHVnKTtcbiAgfVxufVxuXG4vKipcbiAqIENsaXF1ZXIgc3VyIHVuIHBvcHVwIGQndW5lIHB1Y2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gc2x1ZyAtIExlIHNsdWcgZGUgbGEgbG9jYWxpc2F0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcG9wdXBDbGljayhzbHVnKSB7XG4gIHVybE1hbmFnZXIuc2V0U2x1Z0xvY2FsaXNhdGlvbihzbHVnKTtcbiAgSFRNTE1hcmtlci5zaG93VW5pcXVlKHNsdWcpO1xuICBIVE1MTWFya2VyLmZpdEJvdW5kcygpO1xuXG4gIGFjdGl2YXRlUGFuZWxWaWV3KCdsb2NhdGlvbi1kZXRhaWwnKTtcbiAgLy8gU2kgb24gZXN0IGVuIG1vYmlsZSwgb3V2cmlyIGxlIHBhbm5lYXUuXG4gIGlmIChpc1RvdWNoRGV2aWNlKCkpIHtcbiAgICBib3R0b21TaGVldC5vcGVuU2hlZXRNYXhIZWlnaHQoKTtcbiAgfVxufVxuXG4vKipcbiAqIENsaXF1ZXIgc3VyIHVuIGJvdXRvbiBkZSBmZXJtZXR1cmUgZCd1biBwb3B1cCBkJ3VuZSBwdWNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2xvc2VQb3B1cENsaWNrKCkge1xuICBIVE1MTWFya2VyLmhpZGVBbGxQb3B1cCgpO1xuXG4gIC8vIEZpeCB1biBwZXUgYnJvY2hlIMOgIGZvaW4gcG91ciDDqXZpdGVyIHF1ZSBsZSBjbGljayBzdXIgbGUgS01MIHNlIGTDqWNsYW5jaGUgZXQgZmFzc2UgcsOpYXBwYXJhaXRyZSBsZSBQb3B1cCBpbW3DqWRpYXRlbWVudFxuICB3aW5kb3cuaXNDbG9zaW5nID0gdHJ1ZTtcbiAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgd2luZG93LmlzQ2xvc2luZyA9IGZhbHNlO1xuICB9LCAnMzUwJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYW5hZ2VCYWNrQnV0dG9uKCkge1xuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncG9wc3RhdGUnLCAoKSA9PiB7XG4gICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXBhbmVsLWFjdGl2ZV0gLmMtbWFwLWJhY2stYnV0dG9uJykpIHtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXBhbmVsLWFjdGl2ZV0gLmMtbWFwLWJhY2stYnV0dG9uJykuY2xpY2soKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmpzLXF1aXQtbWFwJykuY2xpY2soKTtcbiAgICB9XG4gIH0pO1xufVxuIiwiLypcbkNldHRlIGNsYXNzZSBnw6hyZSBsZXMgbWFycXVldXJzLCBvbiB1dGlsaXNlIGxlcyBwcm90b3R5cGVzIMOgIGNhdXNlIGTigJlpbmNvbXBhdGliaWxpdMOpcyBhdmVjIEdvb2dsZSBNYXBcbiovXG5cbmltcG9ydCB7IHVybE1hbmFnZXIgfSBmcm9tICcuL21hcCc7XG5pbXBvcnQgeyBsb2NhdGlvbkNsaWNrIH0gZnJvbSAnLi9tYXBNYW5hZ2VyJztcblxuLyogZ2xvYmFsIGdvb2dsZSAqL1xuXG4vLyBkZWZpbmlyIHVuZSB2YXJpYWJsZSBwb3VyIHJlY2V2b2lyIGxhIGZ1dHVyZSBkw6lmaW5pdGlvbiBkZSBtYXJxdWV1clxuZXhwb3J0IGxldCBIVE1MTWFya2VyO1xuXG4vLyBpbml0TWFya2VyIGVzdCBhcHBlbMOpIGxvcnNxdWUgZ29vZ2xlbWFwIGVzdCBjaGFyZ8OpXG5leHBvcnQgZnVuY3Rpb24gaW5pdE1hcmtlcigpIHtcbiAgLy8gbG9yc3F1ZSBHb29nbGVNYXAgZXN0IGNoYXJnw6kgb24gZGVjbGFyZSB1biBvYmpldCBldCBzZXMgcHJvdG90eXBlc1xuICBIVE1MTWFya2VyID0gZnVuY3Rpb24gaHRtbE1hcmtlcihhcmdzKSB7XG4gICAgdGhpcy5tYXAgPSBhcmdzLm1hcDtcbiAgICB0aGlzLmxhdCA9IGFyZ3MubGF0O1xuICAgIHRoaXMubG5nID0gYXJncy5sbmc7XG4gICAgdGhpcy5pbWFnZSA9IGFyZ3MuaW1hZ2U7XG4gICAgdGhpcy5wb3MgPSBuZXcgZ29vZ2xlLm1hcHMuTGF0TG5nKGFyZ3MubGF0LCBhcmdzLmxuZyk7XG4gICAgdGhpcy5pZCA9IGFyZ3MuaWQ7XG4gICAgdGhpcy5hY2Nlc3NpYmlsaXR5ID0gYXJncy5hY2Nlc3NpYmlsaXR5O1xuXG4gICAgdGhpcy5rbWxVcmwgPSBhcmdzLmttbFVybDtcbiAgICB0aGlzLmttbExheWVyID0gbnVsbDsgLy8gY29udGllbnQgbOKAmW9iamV0IEtNTFxuICAgIHRoaXMua21sQm91bmRzTkUgPSBudWxsOyAvLyBjb250aWVudCBsZXMgY29vcmRvbm7DqXMgZHUgcmVjdGFuZ2xlIGNvbnRlbmFudCBsZSBLTUwgKCB2aWV3cG9ydCApIGF0dGVudGlvbiwgcGV1cGzDqSBkZSBtYW5pw6hyZSBhc3luY2hyb25lICFcbiAgICB0aGlzLmttbEJvdW5kc1NXID0gbnVsbDtcblxuICAgIHRoaXMudGl0bGUgPSBhcmdzLnRpdGxlO1xuICAgIHRoaXMuY2F0ZWdvcnkgPSBhcmdzLmNhdGVnb3J5O1xuICAgIHRoaXMuc2x1ZyA9IGFyZ3Muc2x1ZztcbiAgICB0aGlzLmNhdGVnb3JpZXNTbHVnID0gYXJncy5jYXRlZ29yaWVzU2x1ZzsgLy8gdGFibGVhdSBkZXMgc2x1Z3MgZGUgY2F0ZWdvcmllXG4gICAgdGhpcy52aXNpYmxlT25NYXAgPSBmYWxzZTsgLy8gTGUgTWFya2VyIGVzdC1pbCB2aXNpYmxlIHN1ciBsYSBNQVAgP1xuICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7IC8vIEVzdCBjZSBxdWUgbGEgcHVjZSBlc3QgYWN0aXZlID9cbiAgICB0aGlzLnZpc2libGVQb3B1cCA9IGZhbHNlOyAvLyBFc3QgY2UgcXVlIGxlIHBvcHVwIGRlIGxhIHB1Y2UgZXN0IGFjdGlmID9cblxuICAgIEhUTUxNYXJrZXIubWFwID0gYXJncy5tYXA7XG5cbiAgICBIVE1MTWFya2VyLm1hcmtlckxpc3QucHVzaCh0aGlzKTsgLy8gQWpvdXQgZHUgbWFycXVldXIgw6AgbGEgbGlzdGUgcXVpIGVzdCB1bmUgdmFyaWFibGUgc3RhdGljXG5cbiAgICBpZiAodGhpcy5rbWxVcmwpIHtcbiAgICAgIEhUTUxNYXJrZXIua21sTWFya2VyTGlzdC5wdXNoKHRoaXMpO1xuICAgIH1cblxuICAgIC8vIFNJIFVORSBVUkwgREUgRklDSElFUiBLTUwgRVNUIFJFTlNFSUdOw4lFXG4gICAgaWYgKHRoaXMua21sVXJsICE9IG51bGwpIHtcbiAgICAgIHRoaXMubGF0ID0gMDtcbiAgICAgIHRoaXMubG5nID0gMDtcbiAgICAgIHRoaXMua21sTGF5ZXIgPSBuZXcgZ29vZ2xlLm1hcHMuS21sTGF5ZXIoe1xuICAgICAgICB1cmw6IHRoaXMua21sVXJsLFxuICAgICAgICAvLyB1cmw6IHRoaXMuaWQgPT09IDI3ID8gJ2h0dHBzOi8vY29yZS5kZXYyLmJsYW5rb2Rldi5jb20vc3RvcmFnZS9hcHAvbWVkaWEvZDEyLmttbCcgOiAnaHR0cHM6Ly9jb3JlLmRldjIuYmxhbmtvZGV2LmNvbS9zdG9yYWdlL2FwcC9tZWRpYS9kMTMua21sJyxcbiAgICAgICAgc3VwcHJlc3NJbmZvV2luZG93czogdHJ1ZSxcbiAgICAgICAgcHJlc2VydmVWaWV3cG9ydDogdHJ1ZSwgLy8gcG91ciBnYXJkZXIgbGUgYm9uIHZpZXdwb3J0XG4gICAgICAgIG1hcDogdGhpcy5tYXAsXG4gICAgICB9KTtcblxuICAgICAgLy8gQXUgY2hhbmdlbWVudCBkZSB2aWV3cG9ydCBkZSBsYSBjYXJ0ZSwgc2kgbGUgS01MIG4nYSBwYXMgZGUgYm91bmRzIGRlIGTDqWZpbmksIGxlcyBjYWxjdWxlciBldCBsZXMgc2F1dmVnYXJkZXIgZGFucyBsYSBwcm9wcmnDqXTDqSBkZSBsYSBjbGFzc2VcbiAgICAgIGNvbnN0IGN1cmVudE1hcmtlciA9IHRoaXM7XG4gICAgICBnb29nbGUubWFwcy5ldmVudC5hZGRMaXN0ZW5lcih0aGlzLmttbExheWVyLCAnZGVmYXVsdHZpZXdwb3J0X2NoYW5nZWQnLCBmdW5jdGlvbiBkZWZh
4084dWx0Vmlld3BvcnRDaGFuZ2VkKCkge1xuICAgICAgLy8gT24gcHJlbWllciBhZmZpY2hhZ2UsIG9uIGVucmVnaXN0cmUgbGVzIGJvdW5kcy5cbiAgICAgICAgaWYgKGN1cmVudE1hcmtlci5rbWxCb3VuZHNORSA9PSBudWxsIHx8IGN1cmVudE1hcmtlci5rbWxCb3VuZHNTVyA9PSBudWxsKSB7XG4gICAgICAgICAgY3VyZW50TWFya2VyLmttbEJvdW5kc05FID0gdGhpcy5nZXREZWZhdWx0Vmlld3BvcnQoKS5nZXROb3J0aEVhc3QoKTtcbiAgICAgICAgICBjdXJlbnRNYXJrZXIua21sQm91bmRzU1cgPSB0aGlzLmdldERlZmF1bHRWaWV3cG9ydCgpLmdldFNvdXRoV2VzdCgpO1xuICAgICAgICAgIGN1cmVudE1hcmtlci5wb3MgPSB0aGlzLmdldERlZmF1bHRWaWV3cG9ydCgpLmdldENlbnRlcigpO1xuICAgICAgICAgIEhUTUxNYXJrZXIuZml0Qm91bmRzKCk7IC8vIEFqdXN0ZXIgbGUgem9vbVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gc2kgb24gY2xpcXVlIHN1ciBsZSBLTUxcbiAgICAgIHRoaXMua21sTGF5ZXIuYWRkTGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICBpZiAoIXdpbmRvdy5pc0Nsb3NpbmcpIHtcbiAgICAgICAgICBsb2NhdGlvbkNsaWNrKHRoaXMuc2x1Zyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICgodGhpcy5sYXQgIT0gbnVsbCAmJiB0aGlzLmxuZyAhPSBudWxsKSB8fCB0aGlzLmttbFVybCkge1xuICAgICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBkaXYuY2xhc3NMaXN0LmFkZCgnYy1tYXAtcGluJyk7XG5cbiAgICAgIC8vIFNpIGxlIFBPSSDDoCB1biDDqXRhdCwgbCdham91dGVyXG4gICAgICBpZiAodGhpcy5hY2Nlc3NpYmlsaXR5KSB7XG4gICAgICAgIGRpdi5jbGFzc0xpc3QuYWRkKGBjLW1hcC1waW4tLSR7dGhpcy5hY2Nlc3NpYmlsaXR5fWApO1xuICAgICAgfVxuXG4gICAgICBkaXYuaW5uZXJIVE1MID0gdGhpcy5yZW5kZXIoKTtcbiAgICAgIHRoaXMuZGl2ID0gZGl2O1xuICAgIH1cbiAgICB0aGlzLnNldE1hcCh0aGlzLm1hcCk7XG4gIH07XG5cbiAgSFRNTE1hcmtlci5wcm90b3R5cGUgPSBuZXcgZ29vZ2xlLm1hcHMuT3ZlcmxheVZpZXcoKTtcblxuICAvKipcbiAgICogQWZmaWNoZXIgbGUgbWFycXVldXIgY291cmFudC5cbiAgICogQG1lbWJlcm9mIEhUTUxNYXJrZXIucHJvdG90eXBlXG4gICAqL1xuICBIVE1MTWFya2VyLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gc2hvdygpIHtcbiAgICB0aGlzLnZpc2libGVPbk1hcCA9IHRydWU7XG5cbiAgICBpZiAodGhpcy5rbWxMYXllciAhPSBudWxsKSB7XG4gICAgICBpZiAodXJsTWFuYWdlci5pc09uUm9vdCgpKSB7XG4gICAgICAgIHRoaXMua21sTGF5ZXIuc2V0TWFwKG51bGwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5rbWxMYXllci5zZXRNYXAoSFRNTE1hcmtlci5tYXApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmRpdikge1xuICAgICAgdGhpcy5kaXYuaW5uZXJIVE1MID0gdGhpcy5yZW5kZXIoKTsgLy8gSWwgZmF1dCByYWZyYWljaGlyIGxlIGRhdGEtcmVxdWVzdCBkZXMgcHVjZXNcbiAgICAgIHRoaXMuZGl2LmNsYXNzTGlzdC5hZGQoJ2MtbWFwLXBpbi0tdmlzaWJsZScpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogTWFzcXVlciBsZSBtYXJxdWV1ciBjb3VyYW50LlxuICAgKiBAbWVtYmVyb2YgSFRNTE1hcmtlci5wcm90b3R5cGVcbiAgICovXG4gIEhUTUxNYXJrZXIucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbiBoaWRlKCkge1xuICAgIHRoaXMudmlzaWJsZU9uTWFwID0gZmFsc2U7XG4gICAgaWYgKHRoaXMua21sTGF5ZXIgIT0gbnVsbCkge1xuICAgICAgdGhpcy5rbWxMYXllci5zZXRNYXAobnVsbCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmRpdikge1xuICAgICAgdGhpcy5kaXYuY2xhc3NMaXN0LnJlbW92ZSgnYy1tYXAtcGluLS12aXNpYmxlJyk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBBZmZpY2hlciBsZSBwb3B1cCBkdSBtYXJxdWV1ciBjb3VyYW50LlxuICAgKiBAbWVtYmVyb2YgSFRNTE1hcmtlci5wcm90b3R5cGVcbiAgICovXG4gIEhUTUxNYXJrZXIucHJvdG90eXBlLnNob3dQb3B1cCA9IGZ1bmN0aW9uIHNob3dQb3B1cCgpIHtcbiAgICBpZiAodGhpcy5kaXYpIHtcbiAgICAgIHRoaXMudmlzaWJsZVBvcHVwID0gdHJ1ZTtcbiAgICAgIHRoaXMuZGl2LmNsYXNzTGlzdC5hZGQoJ2MtbWFwLXBpbi0tc2hvdy1wb3B1cCcpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogTWFzcXVlciBsZSBwb3B1cCBkdSBtYXJxdWV1ciBjb3VyYW50LlxuICAgKiBAbWVtYmVyb2YgSFRNTE1hcmtlci5wcm90b3R5cGVcbiAgICovXG4gIEhUTUxNYXJrZXIucHJvdG90eXBlLmhpZGVQb3B1cCA9IGZ1bmN0aW9uIGhpZGVQb3B1cCgpIHtcbiAgICBpZiAodGhpcy5kaXYpIHtcbiAgICAgIHRoaXMudmlzaWJsZVBvcHVwID0gZmFsc2U7XG4gICAgICB0aGlzLmRpdi5jbGFzc0xpc3QucmVtb3ZlKCdjLW1hcC1waW4tLXNob3ctcG9wdXAnKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEFmZmljaGVyL01hc3F1ZXIgbGUgcG9wdXAgZHUgbWFycXVldXIgY291cmFudC5cbiAgICogQG1lbWJlcm9mIEhUTUxNYXJrZXIucHJvdG90eXBlXG4gICAqL1xuICBIVE1MTWFya2VyLnByb3RvdHlwZS50b2dnbGVQb3B1cCA9IGZ1bmN0aW9uIHRvZ2dsZVBvcHVwKCkge1xuICAgIGlmICh0aGlzLmRpdikge1xuICAgICAgdGhpcy52aXNpYmxlUG9wdXAgPSAhdGhpcy52aXNpYmxlUG9wdXA7XG4gICAgICBpZiAodGhpcy52aXNpYmxlUG9wdXApIHtcbiAgICAgICAgdGhpcy5kaXYuY2xhc3NMaXN0LmFkZCgnYy1tYXAtcGluLS1zaG93LXBvcHVwJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRpdi5jbGFzc0xpc3QucmVtb3ZlKCdjLW1hcC1waW4tLXNob3ctcG9wdXAnKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIENlbnRyZXIgbGEgY2FydGUgc3VyIHVuIG1hcnF1ZXVyLlxuICAgKiBAbWVtYmVyb2YgSFRNTE1hcmtlci5wcm90b3R5cGVcbiAgICovXG4gIEhUTUxNYXJrZXIucHJvdG90eXBlLmNlbnRlciA9IGZ1bmN0aW9uIGNlbnRlcigpIHtcbiAgICBpZiAodGhpcy5kaXYpIHtcbiAgICAgIGlmICh0aGlzLmxhdCAmJiB0aGlzLmxuZykge1xuICAgICAgICBjb25zdCBjb29yZHMgPSBuZXcgZ29vZ2xlLm1hcHMuTGF0TG5nKHRoaXMubGF0LCB0aGlzLmxuZyk7XG4gICAgICAgI
4084HRoaXMubWFwLnBhblRvKGNvb3Jkcyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBBam91dGVyIGwnw6l0YXQgYWN0aWYgZHUgbWFycXVldXIgY291cmFudC5cbiAgICogQG1lbWJlcm9mIEhUTUxNYXJrZXIucHJvdG90eXBlXG4gICAqL1xuICBIVE1MTWFya2VyLnByb3RvdHlwZS5hY3RpdmF0ZSA9IGZ1bmN0aW9uIGFjdGl2YXRlKCkge1xuICAgIGlmICh0aGlzLmRpdikge1xuICAgICAgdGhpcy5hY3RpdmUgPSB0cnVlO1xuICAgICAgdGhpcy5kaXYuY2xhc3NMaXN0LmFkZCgnYy1tYXAtcGluLS1hY3RpdmUnKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEVubGV2ZXIgbCfDqXRhdCBhY3RpZiBkdSBtYXJxdWV1ciBjb3VyYW50LlxuICAgKiBAbWVtYmVyb2YgSFRNTE1hcmtlci5wcm90b3R5cGVcbiAgICovXG4gIEhUTUxNYXJrZXIucHJvdG90eXBlLmRpc2FibGUgPSBmdW5jdGlvbiBkaXNhYmxlKCkge1xuICAgIGlmICh0aGlzLmRpdikge1xuICAgICAgdGhpcy5hY3RpdmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuZGl2LmNsYXNzTGlzdC5yZW1vdmUoJ2MtbWFwLXBpbi0tYWN0aXZlJyk7XG4gICAgfVxuICB9O1xuXG4gIC8vIEluaXQgeW91ciBodG1sIGVsZW1lbnQgaGVyZVxuICBIVE1MTWFya2VyLnByb3RvdHlwZS5vbkFkZCA9IGZ1bmN0aW9uIG9uQWRkKCkge1xuICAgIGNvbnN0IHBhbmVzID0gdGhpcy5nZXRQYW5lcygpO1xuICAgIC8vIFNpIHBhcyBkZSBsYXRpdHVkZSBldCBkZSBsb25naXR1ZGUsIGPigJllc3QgdW5pcXVlbWVudCB1biBLTUwsIG9uIHNraXAgbOKAmWFmZmljaGFnZVxuICAgIGlmICh0aGlzLmxhdCA9PSBudWxsIHx8IHRoaXMubG5nID09IG51bGwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwYW5lcy5vdmVybGF5SW1hZ2UuYXBwZW5kQ2hpbGQodGhpcy5kaXYpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBTdXBwcmltZSBsZSBtYXJxdWV1ci5cbiAgICogQG1lbWJlcm9mIEhUTUxNYXJrZXIucHJvdG90eXBlXG4gICAqL1xuICBIVE1MTWFya2VyLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiByZW1vdmUoKSB7XG4gICAgaWYgKHRoaXMuZGl2KSB7XG4gICAgICB0aGlzLmRpdi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuZGl2KTtcbiAgICAgIHRoaXMuZGl2ID0gbnVsbDtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIFLDqWN1cMOocmVyIGxhIHZpc2liaWxpdMOpIGR1IG1hcnF1ZXVyLlxuICAgKiBAbWVtYmVyb2YgSFRNTE1hcmtlci5wcm90b3R5cGVcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gSW5kaXF1ZSBzaSBsZSBtYXJxdWV1ciBlc3QgdmlzaWJsZSBvdSBub24uXG4gICAqL1xuICBIVE1MTWFya2VyLnByb3RvdHlwZS5nZXRWaXNpYmxlID0gZnVuY3Rpb24gZ2V0VmlzaWJsZSgpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICAvKipcbiAgICogRMOpZmluaXIgbGEgcG9zaXRpb24gZHUgbWFycXVldXIuXG4gICAqIEBtZW1iZXJvZiBIVE1MTWFya2VyLnByb3RvdHlwZVxuICAgKiBAcGFyYW0ge0xhdExuZ30gcG9zaXRpb24gLSBMYSBwb3NpdGlvbiBkdSBtYXJxdWV1ci5cbiAgICovXG4gIEhUTUxNYXJrZXIucHJvdG90eXBlLnNldFBvc2l0aW9uID0gZnVuY3Rpb24gc2V0UG9zaXRpb24ocG9zaXRpb24pIHtcbiAgICB0aGlzLnNldCgncG9zaXRpb24nLCBwb3NpdGlvbik7XG4gIH07XG5cbiAgLyoqXG4gICAqIFLDqWN1cMOpcmVyIGxhIHBvc2l0aW9uIGR1IG1hcnF1ZXVyLlxuICAgKiBAbWVtYmVyb2YgSFRNTE1hcmtlci5wcm90b3R5cGVcbiAgICogQHJldHVybnMge0xhdExuZ30gLSBMYSBwb3NpdGlvbiBkdSBtYXJxdWV1ci5cbiAgICovXG4gIEhUTUxNYXJrZXIucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24gZ2V0UG9zaXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMucG9zO1xuICB9O1xuXG4gIC8qKlxuICAgKiBEw6lmaW5pciBsYSBjYXJ0ZSBhc3NvY2nDqWUgYXUgbWFycXVldXIuXG4gICAqIEBtZW1iZXJvZiBIVE1MTWFya2VyLnByb3RvdHlwZVxuICAgKiBAcGFyYW0ge2dvb2dsZS5tYXBzLk1hcH0gbWFwIC0gTGEgY2FydGUgYXNzb2Npw6llIGF1IG1hcnF1ZXVyLlxuICAgKi9cbiAgSFRNTE1hcmtlci5wcm90b3R5cGUuc2V0TWFwID0gZnVuY3Rpb24gc2V0TWFwKG1hcCkge1xuICAgIHRoaXMuc2V0KCdtYXAnLCBtYXApO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZW5kcmUgbGUgY29udGVudSBIVE1MIGR1IG1hcnF1ZXVyIGVuIGZvbmN0aW9uIGRlIHNlcyBwcm9wcmnDqXTDqXMuXG4gICAqIEBtZW1iZXJvZiBIVE1MTWFya2VyLnByb3RvdHlwZVxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIExlIGNvbnRlbnUgSFRNTCBkdSBtYXJxdWV1ci5cbiAgICovXG4gIEhUTUxNYXJrZXIucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICBjb25zdCBwb3B1cEhUTUwgPSBgXG4gICAgICA8c3BhbiBjbGFzcz1cImMtbWFwLXBvcHVwXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiYy1tYXAtcG9wdXBfX2Nsb3NlXCI+XG4gICAgICAgICAgPGJ1dHRvbiBvbmNsaWNrPVwiY2xvc2VQb3B1cENsaWNrKCcke3RoaXMuc2x1Z30nKVwiIGNsYXNzPVwiYy1tYXAtY2xvc2UtYnV0dG9uXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImMtbWFwLWNsb3NlLWJ1dHRvbl9feFwiIHRpdGxlPVwiRmVybWVyXCI+PC9zcGFuPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L3NwYW4+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICBkYXRhLXJlcXVlc3Q9XCJpbnRlcmFjdGl2ZU1hcDo6b25DaGFuZ2VMb2NhdGlvblwiXG4gICAgICAgICAgZGF0YS1yZXF1ZXN0LXVwZGF0ZT1cIidpbnRlcmFjdGl2ZU1hcDo6cGFuZWxzL2xvY2F0aW9uLWRldGFpbCc6JyNtYXAtbG9jYXRpb24tZGV0YWlsJ1wiXG4gICAgICAgICAgZGF0YS1yZXF1ZXN0LWRhdGE9XCJjYXRlZ29yeVNsdWc6ICcke3VybE1hbmFnZXIuZ2V0U2x1Z0NhdGVnb3J5KCl9Jywgc3ViY2F0ZWdvcnlTbHVnOiAnJHt1cmxNYW5hZ2VyLmdldFNsdWdTdWJjYXRlZ29yeSgpfScsIGxvY2F0aW9uSWQ6ICR7dGhpcy5pZH1cIlxuICAgICAgICAgIGRhdGEtcmVxdWVzdC1jb21wbGV0ZT1cInBvcHVwQ2xpY2soJyR7dGhpcy5zbHVnfScpO1wiXG4gICAgICAgICAgY2xhc3M9XCJjLW1hcC1wb3B1cF9faW5uZXJcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImMtbWFwLXBvcHVwX19jb250ZW50XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImMtbWFwLXBvcHVwX19jYXRlZ29yeVwiPiR7dGhpcy5jYXRlZ29yeX08L3NwYW4+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImMtbWFwLXBvcHVwX190aXRsZVwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImMtbWFwLXBvcHVwX190aXRsZS10ZXh0XCI+JHt0aGlzLnRpdGxlfTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImMtbWFwLXBvcHVwX190aXRsZS1hcnJvd1wiIHJvbGU9XCJpbWdcIj48dXNlIHhsaW5rOmhyZWY9XCIvcGx1Z2lucy9ibGFua28vbWFwL2Fzc2V0cy9pbWFnZXMvaWNvbnMvbWFwLnN2ZyNpY28tY2hldnJvblwiPjwvdXNlPjwvc3ZnPlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAke3RoaXMuaW1hZ2UgPyBgXG4gICAgICAgICAgICA8cGljdHVyZSBjbGFzcz1cImMtbWFwLXBvcHVwX19waWN0dXJlXCI+XG4gICAgICAgICAgICAgIDxpbWcgY2xhc3M9XCJjLW1hcC1wb3B1cF9faW1nXCIgc3JjPVwiL3N0b3JhZ2UvYXBwL21lZGlhJHt0aGlzLmltYWdlfVwiIGFsdD1cIlwiPlxuICAgICAgICAgICAgPC9waWN0dXJlPlxuICAgICAgICAgIGAgOiAnJ31cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L3NwYW4+XG4gICAgYDtcblxuICAgIC8vIFNpIGMnZXN0IHVuIG1hcnF1ZXVyIG5vcm1hbFxuICAgIGlmICghdGhpcy5rbWxVcmwpIHtcbiAgICAgIHJldHVybi
4084BgXG4gICAgICAgIDxzcGFuIGNsYXNzPVwiYy1tYXAtcGluX19idWxsZXRcIj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBpZD1cIiR7dGhpcy5zbHVnfVwiXG4gICAgICAgICAgICBjbGFzcz1cImMtbWFwLXBpbl9faW5uZXIgJHt0aGlzLmFjY2Vzc2liaWxpdHl9XCJcbiAgICAgICAgICAgIGRhdGEtc2x1Zz1cIiR7dGhpcy5zbHVnfVwiXG4gICAgICAgICAgICB0aXRsZT1cIiR7dGhpcy50aXRsZX1cIlxuICAgICAgICAgICAgb25jbGljaz1cImxvY2F0aW9uQ2xpY2soJyR7dGhpcy5zbHVnfScpO1wiPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiYy1tYXAtcGluX19wb3B1cFwiPlxuICAgICAgICAgICR7cG9wdXBIVE1MfVxuICAgICAgICA8L3NwYW4+XG4gICAgICBgO1xuICAgIH1cblxuICAgIC8vIFNpIGMnZXN0IHVuIEtNTCwgb24gbWV0IHNldWxlbWVudCBsZSBwb3B1cCBhdmVjIHVuIG1vZGlmaWNhdGV1ci5cbiAgICByZXR1cm4gYFxuICAgICAgPHNwYW4gY2xhc3M9XCJjLW1hcC1waW5fX3BvcHVwIGMtbWFwLXBpbl9fcG9wdXAtLWttbFwiPlxuICAgICAgICAke3BvcHVwSFRNTH1cbiAgICAgIDwvc3Bhbj5cbiAgICBgO1xuICB9O1xuXG4gIEhUTUxNYXJrZXIucHJvdG90eXBlLmRyYXcgPSBmdW5jdGlvbiBkcmF3KCkge1xuICAgIGNvbnN0IG92ZXJsYXlQcm9qZWN0aW9uID0gdGhpcy5nZXRQcm9qZWN0aW9uKCk7XG4gICAgY29uc3QgcG9zaXRpb24gPSBvdmVybGF5UHJvamVjdGlvbi5mcm9tTGF0TG5nVG9EaXZQaXhlbCh0aGlzLnBvcyk7XG4gICAgdGhpcy5kaXYuc3R5bGUubGVmdCA9IGAke3Bvc2l0aW9uLnh9cHhgO1xuICAgIHRoaXMuZGl2LnN0eWxlLnRvcCA9IGAke3Bvc2l0aW9uLnl9cHhgO1xuICB9O1xuXG4gIC8vIE1ldGhvZGUgYXBwZWzDqWUgYXV0b21hdGlxdWVtZW50IHNpIG9uIHNldE1hcChudWxsKSBs4oCZb2JqZXQsIHZvaXIgZG9jIEdvb2dsZVxuICBIVE1MTWFya2VyLnByb3RvdHlwZS5vblJlbW92ZSA9IGZ1bmN0aW9uIG9uUmVtb3ZlKCkge1xuICAgIGlmICh0aGlzLmRpdikge1xuICAgICAgdGhpcy5kaXYucmVtb3ZlKCk7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICAvKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgUFJPUFJJw4lUw4lTIEVUIE1FVEhPREVTIFNUQVRJQ1NcbiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xuICBIVE1MTWFya2VyLm1hcCA9IG51bGw7XG4gIEhUTUxNYXJrZXIubWFya2VyTGlzdCA9IFtdO1xuICBIVE1MTWFya2VyLmttbE1hcmtlckxpc3QgPSBbXTtcbiAgSFRNTE1hcmtlci5taW5ab29tID0gMTU7IC8vIHpvbW0gbWluaW11bSBkZSBsYSBjYXJ0ZVxuXG4gIC8vIEFjdGl2ZSB2aXN1ZWxsZW1lbnQgdW4gbWFycXVldXJcbiAgSFRNTE1hcmtlci5hY3RpdmF0ZSA9IChtYXJrZXJTbHVnKSA9PiB7XG4gICAgSFRNTE1hcmtlci5tYXJrZXJMaXN0LmZvckVhY2goKG1hcmtlcikgPT4ge1xuICAgICAgaWYgKG1hcmtlci5zbHVnID09PSBtYXJrZXJTbHVnKSB7XG4gICAgICAgIG1hcmtlci5hY3RpdmF0ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWFya2VyLmRpc2FibGUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICBIVE1MTWFya2VyLmdldEJ5U2x1ZyA9IChzbHVnKSA9PiB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBIVE1MTWFya2VyLm1hcmtlckxpc3QubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGlmIChIVE1MTWFya2VyLm1hcmtlckxpc3RbaV0uc2x1ZyA9PT0gc2x1Zykge1xuICAgICAgICByZXR1cm4gSFRNTE1hcmtlci5tYXJrZXJMaXN0W2ldO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG5cbiAgSFRNTE1hcmtlci5kaXNhYmxlQWxsID0gKCkgPT4ge1xuICAgIEhUTUxNYXJrZXIubWFya2VyTGlzdC5mb3JFYWNoKChtYXJrZXIpID0+IHtcbiAgICAgIG1hcmtlci5kaXNhYmxlKCk7XG4gICAgfSk7XG4gIH07XG5cbiAgLy8gQ2FjaGVyIHRvdXRzIGxlcyBtYXJxdWV1cnMgc3VyIGxhIGNhcnRlXG4gIEhUTUxNYXJrZXIuaGlkZUFsbCA9ICgpID0+IHtcbiAgICBIVE1MTWFya2VyLm1hcmtlckxpc3QuZm9yRWFjaCgobWFya2VyKSA9PiB7XG4gICAgICBtYXJrZXIuaGlkZSgpO1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIEFmZmljaGUgdG91dHMgbGVzIG1hcnF1ZXVycyBkZSBsYSBjYXJ0ZVxuICBIVE1MTWFya2VyLnNob3dBbGwgPSAoKSA9PiB7XG4gICAgSFRNTE1hcmtlci5tYXJrZXJMaXN0LmZvckVhY2goKG1hcmtlcikgPT4ge1xuICAgICAgbWFya2VyLnNob3coKTtcbiAgICB9KTtcbiAgICBIVE1MTWFya2VyLnJlZnJlc2hDbHVzdGVyZXIoKTtcbiAgfTtcblxuICAvLyBBZmZpY2hlIHVuIG1hcnF1ZXVyIGVuIHBhcnRpY3VsaWVyIHN1ciBsYSBjYXJ0ZVxuICBIVE1MTWFya2VyLnNob3dVbmlxdWUgPSAobWFya2VyU2x1ZykgPT4ge1xuICAgIEhUTUxNYXJrZXIuaGlkZUFsbFBvcHVwKCk7XG4gICAgSFRNTE1hcmtlci5tYXJrZXJMaXN0LmZvckVhY2goKG1hcmtlcikgPT4ge1xuICAgICAgaWYgKG1hcmtlci5zbHVnID09PSBtYXJrZXJTbHVnKSB7XG4gICAgICAgIG1hcmtlci5zaG93KCk7XG4gICAgICAgIG1hcmtlci5hY3RpdmF0ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWFya2VyLmhpZGUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBIVE1MTWFya2VyLnJlZnJlc2hDbHVzdGVyZXIoKTtcbiAgfTtcblxuICAvLyBBZmZpY2hlIHVuIHBvcHVwIGRlIG1hcnF1ZXVyIGVuIHBhcnRpY3VsaWVyIHN1ciBsYSBjYXJ0ZVxuICBIVE1MTWFya2VyLnNob3dQb3B1cCA9IChtYXJrZXJTbHVnKSA9PiB7XG4gICAgSFRNTE1hcmtlci5tYXJrZXJMaXN0LmZvckVhY2goKG1hcmtlcikgPT4ge1xuICAgICAgaWYgKG1hcmtlci5zbHVnID09PSBtYXJrZXJTbHVnKSB7XG4gICAgICAgIG1hcmtlci5zaG93UG9wdXAoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvLyBDYWNoZXIgdG91dHMgbGVzIHBvcHVwcyBkZSBtYXJxdWV1cnMgc3VyIGxhIGNhcnRlXG4gIEhUTUxNYXJrZXIuaGlkZUFsbFBvcHVwID0gKG1hcmtlclNsdWcgPSBudWxsKSA9PiB7XG4gICAgSFRNTE1hcmtlci5tYXJrZXJMaXN0LmZvckVhY2goKG1hcmtlcikgPT4ge1xuICAgICAgaWYgKG1hcmtlci5zbHVnICE9PSBtYXJrZXJTbHVnKSB7XG4gICAgICAgIG1hcmtlci5oaWRlUG9wdXAoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvKipcbiAgICogQWZmaWNoZXIvY2FjaGVyIGxlIHBvcHVwIGR1IG1hcnF1ZXVyIHNww6ljaWZpw6kgcGFyIHNvbiBzbHVnLlxuICAgKiBAbWVtYmVyb2YgSFRNTE1hcmtlclxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWFya2VyU2x1ZyAtIExlIHNsdWcgZHUgbWFycXVldXIuXG4gICAqL1xuICBIVE1MTWFya2VyLnRvZ2dsZVBvcHVwID0gKG1hcmtlclNsdWcpID0+IHtcbiAgICBIVE1MTWFya2VyLm1hcmtlckxpc3QuZm9yRWFjaCgobWFya2VyKSA9PiB7XG4gICAgICBpZiAobWFya2VyLnNsdWcgPT09IG1hcmtlclNsdWcpIHtcbiAgICAgICAgbWFya2VyLnRvZ2dsZVBvcHVwKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENlbnRyZXIgbGEgY2FydGUgc3VyIGxlIG1hcnF1ZXVyIHNww6ljaWZpw6kgcGFyIHNvbiBzbHVnLlxuICAgKiBAbWVtYmVyb2YgSFRNTE1hcmtlclxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWFya2VyU2x1ZyAtIExlIHNsdWcgZHUgbWFycXVldXIuXG4gICAqL1xuICBIVE1MTWFya2VyLmNlbnRlciA9IChtYXJrZXJTbHVnKSA9PiB7XG4gICAgSFRNTE1hcmtlci5tYXJrZXJMaXN0LmZvckVhY2goKG1hcmtlcikgPT4ge1xuICAgICAgaWYgKG1hcmtlci5zbHVnID09PSBtYXJrZXJTbHVnKSB7XG4gICAgICAgIG1hcmtlci5jZW50ZXIoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvKipcbiAgICogQWZmaWNoZXIgbGVzIG1hcnF1ZXVycyBkZSBsYSBjYXTDqWdvcmllIHNww6ljaWZpw6llIHN1ciBsYSBjYXJ0ZSBldCBtZXQgw6Agam91ciBsZXMgQ2x1c3RlcnMuXG4gICAqIEBtZW1iZXJvZiBIVE1MTWFya2VyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjYXRlZ29yeVNsdWcgLSBMZSBzbHVnIGRlIGxhIGNhdMOpZ29yaWUuXG4gICAqL1xuICBIVE1MTWFya2VyLnNob3dDYXRlZ29yeSA9IChjYXRlZ29yeVNsdWcpID0+IHtcbiAgICBIVE1MTWFya2VyLm1hcmtlckxpc3QuZm9yRWFjaCgobWFya2VyKSA9PiB7XG4gICAgICBpZiAobWFya2VyLmNhdGVnb3JpZXNTbHVnLmluY2x1ZGVzKGNhdGVnb3J5U2x1ZykpIHtcbiAgICAgICAgbWFya2VyLnNob3coKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1hcmtlci5oaWRlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgSFRNTE1hcmtlci5yZWZyZXNoQ2x1c3RlcmVyKCk7XG4gIH07XG5cbiAgLy8gUmFmcmFpY2hpciBsZSBjbHVzdGVyZXJcbiAgSFRNTE1hcmtlci5yZWZyZXNoQ2x1c3RlcmVyID0gKCkgPT4ge1xuICAgIGNvbnN0IHBvaXMgPSBIVE1MTWFya2VyLm1hcmtlckxpc3Q7XG4gICAgY29uc3QgZmlsdGVyZWRQb2lzID0gW107XG5cbiAgICBwb2lzLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgIGlmIChlbGVtZW50LnZpc2libGVPbk1hcCAmJiAhZWxlbWVudC5rbWxMYXllcikge1xuICAgICAgICBmaWx0ZXJlZFBvaXMucHVzaChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB3aW5kb3cubWFya2VyQ2x1c3RlcmVyLmNsZWFyTWFya2VycygpO1xuICAgIHdpbmRvdy5tYXJrZXJDbHVzdGVyZXIuYWRkTWFya2VycyhmaWx0ZXJlZFBvaXMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBanVzdGVyIGxhIHZ1ZSBk
4084ZSBsYSBjYXJ0ZSBwb3VyIGluY2x1cmUgw6AgbGEgZm9pcyBsZXMgS01MIGV0IGxlcyBtYXJxdWV1cnMgdmlzaWJsZXMuXG4gICAqIEBtZW1iZXJvZiBIVE1MTWFya2VyXG4gICAqL1xuICBIVE1MTWFya2VyLmZpdEJvdW5kcyA9ICgpID0+IHtcbiAgICBjb25zdCBib3VuZHMgPSBuZXcgZ29vZ2xlLm1hcHMuTGF0TG5nQm91bmRzKCk7XG4gICAgd2luZG93Lm1hcmtlckNsdXN0ZXJlci5tYXJrZXJzLmZvckVhY2goKG1hcmtlcikgPT4ge1xuICAgICAgLy8gcG91ciBjaGFxdWUgbWFya2VyIGFjdGl2w6kgb24gw6l0ZW5kIGxlIHJlY3RhbmdsZSBkZSB2aXN1YWxpc2F0aW9uIHNpIGxlIFBPSSBkaXNwb3NlIGRlIGNvb3Jkb25uw6lzICggc2lub24gw6dhIHNpZ25pZmllIHF1ZSBj4oCZZXN0IHVuIEtNTCApXG4gICAgICBpZiAobWFya2VyLnZpc2libGVPbk1hcCAmJiBtYXJrZXIubGF0ICE9IG51bGwgJiYgbWFya2VyLmxuZyAhPSBudWxsKSB7XG4gICAgICAgIGJvdW5kcy5leHRlbmQobWFya2VyLnBvcyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBBam91dGVyIGxlcyBib3VuZHMgZGVzIEtNTCBhZmZpY2jDqXNcbiAgICBIVE1MTWFya2VyLmttbE1hcmtlckxpc3QuZm9yRWFjaCgobWFya2VyKSA9PiB7XG4gICAgICBpZiAobWFya2VyLnZpc2libGVPbk1hcCAmJiBtYXJrZXIua21sTGF5ZXIgIT0gbnVsbCkge1xuICAgICAgICBpZiAobWFya2VyLmttbExheWVyLmdldE1hcCgpKSB7XG4gICAgICAgICAgaWYgKG1hcmtlci5rbWxCb3VuZHNORSAhPSBudWxsKSB7XG4gICAgICAgICAgICBib3VuZHMuZXh0ZW5kKG1hcmtlci5rbWxCb3VuZHNORSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChtYXJrZXIua21sQm91bmRzU1cgIT0gbnVsbCkge1xuICAgICAgICAgICAgYm91bmRzLmV4dGVuZChtYXJrZXIua21sQm91bmRzU1cpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgSFRNTE1hcmtlci5tYXAuZml0Qm91bmRzKGJvdW5kcyk7XG4gICAgbGV0IHpvb20gPSBIVE1MTWFya2VyLm1hcC5nZXRab29tKCk7XG4gICAgaWYgKHpvb20gPiBIVE1MTWFya2VyLm1pblpvb20pIHtcbiAgICAgIHpvb20gPSBIVE1MTWFya2VyLm1pblpvb207XG4gICAgfVxuICAgIEhUTUxNYXJrZXIubWFwLnNldFpvb20oem9vbSk7XG4gIH07XG5cbiAgd2luZG93LkhUTUxNYXJrZXIgPSBIVE1MTWFya2VyO1xufVxuIiwiaW1wb3J0IHsgSFRNTE1hcmtlciB9IGZyb20gJy4vbWFwTWFya2VyJztcbi8qIGdsb2JhbCBnb29nbGUgKi9cblxuLyoqXG4gKiBJbml0aWFsaXNlIGxlcyBtYXJxdWV1cnMgZGUgdHlwZSBDbHVzdGVyIHN1ciBsYSBjYXJ0ZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBhcmdzIC0gTGVzIGFyZ3VtZW50cyBwb3VyIGluaXRpYWxpc2VyIGxlIG1hcnF1ZXVyIGRlIHR5cGUgQ2x1c3Rlci5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gaHRtbE1hcmtlckNsdXN0ZXIoYXJncykge1xuICB0aGlzLmxhdGxuZyA9IGFyZ3MubGF0bG5nO1xuICB0aGlzLmNvdW50ID0gYXJncy5jb3VudDtcbiAgdGhpcy5ib3VuZHMgPSBhcmdzLmJvdW5kcztcbiAgdGhpcy5tYXAgPSBhcmdzLm1hcDtcbiAgdGhpcy5zZXRNYXAodGhpcy5tYXApO1xufVxuXG4vKipcbiAqIENsYXNzZSByZXByw6lzZW50YW50IHVuIG1hcnF1ZXVyIHBlcnNvbm5hbGlzw6kgc3VyIGxhIGNhcnRlIEdvb2dsZSBNYXBzLlxuICogQGNsYXNzXG4gKiBAZXh0ZW5kcyBnb29nbGUubWFwcy5PdmVybGF5Vmlld1xuICogQG1lbWJlcm9mIGh0bWxNYXJrZXJDbHVzdGVyXG4gKi9cbmh0bWxNYXJrZXJDbHVzdGVyLnByb3RvdHlwZSA9IG5ldyBnb29nbGUubWFwcy5PdmVybGF5VmlldygpO1xuXG4vKipcbiAqIERlc3NpbmVyIGxlIG1hcnF1ZXVyLlxuICogQG1lbWJlcm9mIGh0bWxNYXJrZXJDbHVzdGVyLnByb3RvdHlwZVxuICovXG5odG1sTWFya2VyQ2x1c3Rlci5wcm90b3R5cGUuZHJhdyA9IGZ1bmN0aW9uIGRyYXcoKSB7XG4gIGxldCB7IGRpdiB9ID0gdGhpcztcbiAgY29uc3QgcG9pbnQgPSB0aGlzLmdldFByb2plY3Rpb24oKS5mcm9tTGF0TG5nVG9EaXZQaXhlbCh0aGlzLmxhdGxuZyk7XG5cbiAgaWYgKCFkaXYpIHtcbiAgICBkaXYgPSB0aGlzLmRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG4gICAgZGl2LmNsYXNzTmFtZSA9ICdjLW1hcC1waW4gYy1tYXAtcGluLS1jbHVzdGVyJztcblxuICAgIGRpdi5pbm5lckhUTUwgPSBgPGRpdiBjbGFzcz1cImMtbWFwLXBpbl9fY2x1c3RlclwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYy1tYXAtcGluX19idWxsZXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjLW1hcC1waW5fX2lubmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYy1tYXAtcGluX19jb3VudFwiPiR7dGhpcy5jb3VudH08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuXG4gICAgZ29vZ2xlLm1hcHMuZXZlbnQuYWRkRG9tTGlzdGVuZXIoZGl2LCAnY2xpY2snLCAoKSA9PiB7XG4gICAgICAvLyBHw6lyZXIgbGUgY2xpYyBzdXIgdW4gY2x1c3Rlci5cbiAgICAgIGlmICh0eXBlb2YgKHRoaXMuYm91bmRzKSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhpcy5tYXAuZml0Qm91bmRzKHRoaXMuYm91bmRzKTtcbiAgICAgIH1cbiAgICAgIC8vIEZlcm1lciB0b3VzIGxlcyBwb3B1cHMgZGUgcHVjZXMuXG4gICAgICBIVE1MTWFya2VyLmhpZGVBbGxQb3B1cCgpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgcGFuZXMgPSB0aGlzLmdldFBhbmVzKCk7XG4gICAgcGFuZXMub3ZlcmxheUltYWdlLmFwcGVuZENoaWxkKGRpdik7XG4gIH1cblxuICBpZiAocG9pbnQpIHtcbiAgICBkaXYuc3R5bGUubGVmdCA9IGAke3BvaW50Lnh9cHhgO1xuICAgIGRpdi5zdHlsZS50b3AgPSBgJHtwb2ludC55fXB4YDtcbiAgfVxufTtcblxuLyoqXG4gKiBTdXBwcmltZXIgbGUgbWFycXVldXIuXG4gKiBAbWVtYmVyb2YgaHRtbE1hcmtlckNsdXN0ZXIucHJvdG90eXBlXG4gKi9cbmh0bWxNYXJrZXJDbHVzdGVyLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiByZW1vdmUoKSB7XG4gIGlmICh0aGlzLmRpdikge1xuICAgIHRoaXMuZGl2LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5kaXYpO1xuICAgIHRoaXMuZGl2ID0gbnVsbDtcbiAgfVxufTtcblxuLyoqXG4gKiBEw6lmaW5pciBsYSBwb3NpdGlvbiBkdSBtYXJxdWV1ci5cbiAqIEBtZW1iZXJvZiBodG1sTWFya2VyQ2x1c3Rlci5wcm90b3R5cGVcbiAqIEBwYXJhbSB7TGF0TG5nfSBwb3NpdGlvbiAtIExhIHBvc2l0aW9uIGR1IG1hcnF1ZXVyLlxuICovXG5odG1sTWFya2VyQ2x1c3Rlci5wcm90b3R5cGUuc2V0UG9zaXRpb24gPSBmdW5jdGlvbiBzZXRQb3NpdGlvbihwb3NpdGlvbikge1xuICB0aGlzLnNldCgncG9zaXRpb24nLCBwb3NpdGlvbik7XG59O1xuXG4vKipcbiAqIFLDqWN1cMOpcmVyIGxhIHBvc2l0aW9uIGR1IG1hcnF1ZXVyLlxuICogQG1lbWJlcm9mIGh0bWxNYXJrZXJDbHVzdGVyLnByb3RvdHlwZVxuICogQHJldHVybnMge0xhdExuZ30gLSBMYSBwb3NpdGlvbiBkdSBtYXJxdWV1ci5cbiAqL1xuaHRtbE1hcmtlckNsdXN0ZXIucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24gZ2V0UG9zaXRpb24oKSB7XG4gIHJldHVybi
4084B0aGlzLmxhdGxuZztcbn07XG5cbi8qKlxuICogRMOpZmluaXIgbGEgY2FydGUgYXNzb2Npw6llIGF1IG1hcnF1ZXVyLlxuICogQG1lbWJlcm9mIGh0bWxNYXJrZXJDbHVzdGVyLnByb3RvdHlwZVxuICogQHBhcmFtIHtnb29nbGUubWFwcy5NYXB9IG1hcCAtIExhIGNhcnRlIGFzc29jacOpZSBhdSBtYXJxdWV1ci5cbiAqL1xuaHRtbE1hcmtlckNsdXN0ZXIucHJvdG90eXBlLnNldE1hcCA9IGZ1bmN0aW9uIHNldE1hcChtYXApIHtcbiAgdGhpcy5zZXQoJ21hcCcsIG1hcCk7XG59O1xuIiwiLyoqXG4gKiBEw6lzYWN0aXZlciB0b3VzIGxlcyBwYW5uZWF1eCBkYW5zIGwnaW50ZXJmYWNlIGRlIGxhIGNhcnRlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVhY3RpdmF0ZVBhbmVsVmlldygpIHtcbiAgY29uc3QgU0lERUJBUiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5qcy1tYXAtcGFuZWxzJyk7XG5cbiAgaWYgKFNJREVCQVIpIHtcbiAgICBjb25zdCBWSUVXUyA9IFNJREVCQVIucXVlcnlTZWxlY3RvckFsbCgnLmpzLW1hcC1wYW5lbHMtdmlldycpO1xuICAgIC8vIETDqXNhY3RpdmVyIHRvdXRlcyBsZXMgdnVlc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgVklFV1MubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIFZJRVdTW2ldLnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS1wYW5lbC1hY3RpdmUnKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBBY3RpdmUgbGUgcGFubmVhdSBzcMOpY2lmacOpIGRhbnMgbCdpbnRlcmZhY2UgZGUgbGEgY2FydGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdmlldyAtIExhIHZ1ZSDDoCBhY3RpdmVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWN0aXZhdGVQYW5lbFZpZXcodmlldykge1xuICAvLyBBc3N1cmVyIHF1J2F1Y3VuZSBhdXRyZSB2dWUgZGUgcGFubmVhdSBuJ2VzdCBhY3RpdmUgYXZhbnQgZCdhY3RpdmVyIGxhIG5vdXZlbGxlXG4gIGRlYWN0aXZhdGVQYW5lbFZpZXcoKTtcblxuICAvLyBWw6lyaWZpZSBzaSBsZSBwYW5uZWF1IGRlIGxhIGNhcnRlIGV4aXN0ZW50IGRhbnMgbGUgRE9NXG4gIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuanMtbWFwLXBhbmVscycpKSB7XG4gICAgLy8gRMOpY2xlbmNoZSB1biDDqXbDqW5lbWVudCBwZXJzb25uYWxpc8OpIGVuIGZvbmN0aW9uIGRlIGxhIHZ1ZSDDoCBhY3RpdmVyXG4gICAgc3dpdGNoICh2aWV3KSB7XG4gICAgICBjYXNlICdjYXRlZ29yaWVzJzpcbiAgICAgICAgZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ21hcFNob3dQYW5lbFZpZXdDYXRlZ29yaWVzJykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3N1YmNhdGVnb3JpZXMnOlxuICAgICAgICBkb2
4084N1bWVudC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgnbWFwU2hvd1BhbmVsVmlld1N1YmNhdGVnb3JpZXMnKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbG9jYXRpb25zJzpcbiAgICAgICAgZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ21hcFNob3dQYW5lbFZpZXdMb2NhdGlvbnMnKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbG9jYXRpb24tZGV0YWlsJzpcbiAgICAgICAgZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ21hcFNob3dQYW5lbFZpZXdMb2NhdGlvbkRldGFpbCcpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQWN0aXZlciBsYSBib25uZSB2dWUgZGFucyBsZSBwYW5uZWF1XG4gICAgY29uc3QgVklFVyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYC5qcy1tYXAtcGFuZWxzLXZpZXdbZGF0YS12aWV3PVwiJHt2aWV3fVwiXWApO1xuICAgIFZJRVcuc2V0QXR0cmlidXRlKCdkYXRhLXBhbmVsLWFjdGl2ZScsICcnKTtcbiAgfVxufVxuXG4vKipcbiAqIEFjdGl2ZXIgbGVzIGJvdXRvbnMgZGUgcsOpaW5pdGlhbGlzYXRpb24gZGFucyBsJ2ludGVyZmFjZSBkZSBsYSBjYXJ0ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuYWJsZVJlc2V0QnV0dG9ucygpIHtcbiAgY29uc3QgQlVUVE9OUyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5qcy1tYXAtcmVzZXQnKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IEJVVFRPTlMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBCVVRUT05TW2ldLmRpc2FibGVkID0gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBEw6lzYWN0aXZlciBsZXMgYm91dG9ucyBkZSByw6lpbml0aWFsaXNhdGlvbiBkYW5zIGwnaW50ZXJmYWNlIGRlIGxhIGNhcnRlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGlzYWJsZVJlc2V0QnV0dG9ucygpIHtcbiAgY29uc3QgQlVUVE9OUyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5qcy1tYXAtcmVzZXQnKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IEJVVFRPTlMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBCVVRUT05TW2ldLmRpc2FibGVkID0gdHJ1ZTtcbiAgfVxufVxuIiwiLyoqXG4gKiBEw6lmaW5pciBsZSBzdHlsZSB2aXN1ZWwgZGUgbGEgY2FydGUgR29vZ2xlIE1hcHMuXG4gKiBDZSBzdHlsZSBlc3QgaW1wb3J0w6kgZGFucyBsZSBmaWNoaWVyIG1hcC5qcyBhZmluIGQnw6p0cmUgYXBwbGlxdcOpIMOgIGxhIGNhcnRlLlxuICovXG5leHBvcnQgZGVmYXVsdCBbXG4gIHtcbiAgICBmZWF0dXJlVHlwZTogJ2FkbWluaXN0cmF0aXZlJyxcbiAgICBlbGVtZW50VHlwZTogJ2xhYmVscy50ZXh0LmZpbGwnLFxuICB9LFxuICB7XG4gICAgZmVhdHVyZVR5cGU6ICdhZG1pbmlzdHJhdGl2ZS5sb2NhbGl0eScsXG4gICAgZWxlbWVudFR5cGU6ICdsYWJlbHMnLFxuICAgIHN0eWxlcnM6IFtcbiAgICAgIHtcbiAgICAgICAgdmlzaWJpbGl0eTogJ29uJyxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGZlYXR1cmVUeXBlOiAnbGFuZHNjYXBlJyxcbiAgICBlbGVtZW50VHlwZTogJ2FsbCcsXG4gICAgc3R5bGVyczogW1xuICAgICAge1xuICAgICAgICBjb2xvcjogd2luZG93Lm1hcENvbmZpZy5jb2xvcl9iYWNrZ3JvdW5kLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdmlzaWJpbGl0eTogJ3NpbXBsaWZpZWQnLFxuICAgICAgfSxcbiAgICBdLFxuICB9LFxuICB7XG4gICAgZmVhdHVyZVR5cGU6ICdwb2knLFxuICAgIGVsZW1lbnRUeXBlOiAnYWxsJyxcbiAgICBzdHlsZXJzOiBbXG4gICAgICB7XG4gICAgICAgIHZpc2liaWxpdHk6ICdvZmYnLFxuICAgICAgfSxcbiAgICBdLFxuICB9LFxuICB7XG4gICAgZmVhdHVyZVR5cGU6ICdwb2kucGFyaycsXG4gICAgZWxlbWVudFR5cGU6ICdhbGwnLFxuICAgIHN0eWxlcnM6IFtcbiAgICAgIHtcbiAgICAgICAgdmlzaWJpbGl0eTogJ29uJyxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGZlYXR1cmVUeXBlOiAncG9pLnBhcmsnLFxuICAgIGVsZW1lbnRUeXBlOiAnbGFiZWxzLmljb24nLFxuICAgIHN0eWxlcnM6IFtcbiAgICAgIHtcbiAgICAgICAgdmlzaWJpbGl0eTogJ29mZicsXG4gICAgICB9LFxuICAgIF0sXG4gIH0sXG4gIHtcbiAgICBmZWF0dXJlVHlwZTogJ3BvaS5wYXJrJyxcbiAgICBlbGVtZW50VHlwZTogJ2dlb21ldHJ5JyxcbiAgICBzdHlsZXJzOiBbXG4gICAgICB7XG4gICAgICAgIGNvbG9yOiB3aW5kb3cubWFwQ29uZmlnLmNvbG9yX3BhcmtzLFxuICAgICAgfSxcbiAgICBdLFxuICB9LFxuICB7XG4gICAgZmVhdHVyZVR5cGU6ICdwb2knLFxuICAgIGVsZW1lbnRUeXBlOiAnbGFiZWxzJyxcbiAgICBzdHlsZXJzOiBbXG4gICAgICB7XG4gICAgICAgIHZpc2liaWxpdHk6ICdvZmYnLFxuICAgICAgfSxcbiAgICBdLFxuICB9LFxuICB7XG4gICAgZmVhdHVyZVR5cGU6ICdyb2FkJyxcbiAgICBlbGVtZW50VHlwZTogJ2FsbCcsXG4gICAgc3R5bGVyczogW1xuICAgICAge1xuICAgICAgICBzYXR1cmF0aW9uOiAtMTAwLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbGlnaHRuZXNzOiA0NSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGZlYXR1cmVUeXBlOiAncm9hZCcsXG4gICAgZWxlbWVudFR5cGU6ICdsYWJlbHMnLFxuICAgIHN0eWxlcnM6IFtcbiAgICAgIHtcbiAgICAgICAgdmlzaWJpbGl0eTogJ29uJyxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGZlYXR1cmVUeXBlOiAncm9hZCcsXG4gICAgZWxlbWVudFR5cGU6ICdsYWJlbHMuaWNvbicsXG4gICAgc3R5bGVyczogW1xuICAgICAge1xuICAgICAgICB2aXNpYmlsaXR5OiAnb2ZmJyxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGZlYXR1cmVUeXBlOiAncm9hZC5oaWdod2F5JyxcbiAgICBlbGVtZW50VHlwZTogJ2FsbCcsXG4gICAgc3R5bGVyczogW1xuICAgICAge1xuICAgICAgICB2aXNpYmlsaXR5OiAnc2ltcGxpZmllZCcsXG4gICAgICB9LFxuICAgIF0sXG4gIH0sXG4gIHtcbiAgICBmZWF0dXJlVHlwZTogJ3JvYWQuaGlnaHdheScsXG4gICAgZWxlbWVudFR5cGU6ICdsYWJlbHMuaWNvbicsXG4gICAgc3R5bGVyczogW1xuICAgICAge1xuICAgICAgICB2aXNpYmlsaXR5OiAnb2ZmJyxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGZlYXR1cmVUeXBlOiAncm9hZC5hcnRlcmlhbCcsXG4gICAgZWxlbWVudFR5cGU6ICdsYWJlbHMuaWNvbicsXG4gICAgc3R5bGVyczogW1xuICAgICAge1xuICAgICAgICB2aXNpYmlsaXR5OiAnb2ZmJyxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcbiAge1xuICAgIGZlYXR1cmVUeXBlOiAndHJhbnNpdCcsXG4gICAgZWxlbWVudFR5cGU6ICdhbGwnLFxuICAgIHN0eWxlcnM6IFtcbiAgICAgIHtcbiAgICAgICAgdmlzaWJpbGl0eTogJ29mZicsXG4gICAgICB9LFxuICAgIF0sXG4gIH0sXG4gIHtcbiAgICBmZWF0dXJlVHlwZTogJ3dhdGVyJyxcbiAgICBlbGVtZW50VHlwZTogJ2FsbCcsXG4gICAgc3R5bGVyczogW1xuICAgICAge1xuICAgICAgICBjb2xvcjogd2luZG93Lm1hcENvbmZpZy5jb2xvcl93YXRlcixcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgI
4084HZpc2liaWxpdHk6ICdzaW1wbGlmaWVkJyxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcbl07XG4iLCIvKipcbiAqIENldHRlIGNsYXNzZSBlc3QgdXRpbGlzw6llIHBvdXIgZ8OpcmVyIGV0IGNyw6llciBsZXMgVVJMcyBkZSBsYSBjYXJ0ZS5cbiAqIExvcnNxdSdvbiBjbGlxdWUgc3VyIHVuZSBjYXTDqWdvcmllLCBzb3VzLWNhdMOpZ29yaWUgb3UgdW5lIGxvY2FsaXNhdGlvbixcbiAqIGwnb2JqZXQgZXN0IG1pcyDDoCBqb3VyLCBjb25zdHJ1aXQgbCdVUkwgZXQgbGEgcG91c3NlIGRhbnMgbGUgbmF2aWdhdGV1ci5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWFwVXJsIHtcbiAgLyoqXG4gICAqIENvbnN0cnVjdGV1ciBkZSBsYSBjbGFzc2UgTWFwVXJsLlxuICAgKiBAY29uc3RydWN0b3JcbiAgICovXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuc2x1Z0NhdGVnb3J5ID0gbnVsbDtcbiAgICB0aGlzLnNsdWdTdWJDYXRlZ29yeSA9IG51bGw7XG4gICAgdGhpcy5zbHVnTG9jYWxpc2F0aW9uID0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbmRpcXVlIHNpIGwnVVJMIGRlIGxhIHBhZ2Ugc2UgdHJvdXZlIMOgIGxhIHJhY2luZSAoc2FucyBjYXTDqWdvcmllIGV0IHNvdXMtY2F0w6lnb3JpZSkgb3Ugbm9uLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBzaSBsJ1VSTCBkZSBsYSBwYWdlIGVzdCDDoCBsYSByYWNpbmUsIHNpbm9uIEZhbHNlLlxuICAgKi9cbiAgaXNPblJvb3QoKSB7XG4gICAgcmV0dXJuICF0aGlzLnNsdWdDYXRlZ29yeSAmJiAhdGhpcy5zbHVnU3ViQ2F0ZWdvcnkgJiYgIXRoaXMuc2x1Z0xvY2FsaXNhdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSw6lpbml0aWFsaXNlciBsZXMgc2x1Z3MgZGUgY2F0w6lnb3JpZSwgc291cy1jYXTDqWdvcmllIGV0IGxvY2FsaXNhdGlvbiwgZXQgbWV0IMOgIGpvdXIgbCdVUkwuXG4gICAqL1xuICByZXNldFNsdWcoKSB7XG4gICAgdGhpcy5zbHVnQ2F0ZWdvcnkgPSBudWxsO1xuICAgIHRoaXMuc2x1Z1N1YkNhdGVnb3J5ID0gbnVsbDtcbiAgICB0aGlzLnNsdWdMb2NhbGlzYXRpb24gPSBudWxsO1xuICAgIHRoaXMudXBkYXRlVXJsKCk7XG4gIH1cblxuICAvKipcbiAgICogUsOpaW5pdGlhbGlzZXIgbGVzIHNsdWdzIGRlIHNvdXMtY2F0w6lnb3JpZSBldCBkZSBsb2NhbGlzYXRpb24sIGV0IG1ldCDDoCBqb3VyIGwnVVJMLlxuICAgKi9cbiAgcmVzZXRTdWJjYXRlZ29yeSgpIHtcbiAgICB0aGlzLnNsdWdTdWJDYXRlZ29yeSA9IG51bGw7XG4gICAgdGhpcy5zbHVnTG9jYWxpc2F0aW9uID0gbnVsbDtcbiAgICB0aGlzLnVwZGF0ZVVybCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFLDqWluaXRpYWxpc2VyIGxlIHNsdWcgZGUgbGEgbG9jYWxpc2F0aW9uIGV0IG1ldCDDoCBqb3VyIGwnVVJMLlxuICAgKi9cbiAgcmVzZXRMb2NhdGlvbigpIHtcbiAgICB0aGlzLnNsdWdMb2NhbGlzYXRpb24gPSBudWxsO1xuICAgIHRoaXMudXBkYXRlVXJsKCk7XG4gIH1cblxuICAvKipcbiAgICogRMOpZmluaXIgbGUgc2x1ZyBkZSBsYSBjYXTDqWdvcmllIGV0IG1ldCDDoCBqb3VyIGwnVVJMLlxuICAgKiBAcGFyYW0ge3N0cmluZ3xudWxsfSBzbHVnIC0gTGUgc2x1ZyBkZSBsYSBjYXTDqWdvcmllLlxuICAgKi9cbiAgc2V0U2x1Z0NhdGVnb3J5KHNsdWcpIHtcbiAgICB0aGlzLnNsdWdDYXRlZ29yeSA9IHNsdWc7XG4gICAgdGhpcy5zbHVnU3ViQ2F0ZWdvcnkgPSBudWxsO1xuICAgIHRoaXMuc2x1Z0xvY2FsaXNhdGlvbiA9IG51bGw7XG4gICAgdGhpcy51cGRhdGVVcmwoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSw6ljdXDDqHJlIGxlIHNsdWcgZGUgbGEgY2F0w6lnb3JpZS5cbiAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBMZSBzbHVnIGRlIGxhIGNhdMOpZ29yaWUuXG4gICAqL1xuICBnZXRTbHVnQ2F0ZWdvcnkoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2x1Z0NhdGVnb3J5O1xuICB9XG5cbiAgLyoqXG4gICAqIETDqWZpbmlyIGxlIHNsdWcgZGUgbGEgc291cy1jYXTDqWdvcmllIGV0IG1ldCDDoCBqb3VyIGwnVVJMLlxuICAgKiBAcGFyYW0ge3N0cmluZ3xudWxsfSBzbHVnIC0gTGUgc2x1ZyBkZSBsYSBzb3VzLWNhdMOpZ29yaWUuXG4gICAqL1xuICBzZXRTbHVnU3ViQ2F0ZWdvcnkoc2x1Zykge1xuICAgIHRoaXMuc2x1Z1N1YkNhdGVnb3J5ID0gc2x1ZztcbiAgICB0aGlzLnNsdWdMb2NhbGlzYXRpb24gPSBudWxsOyAvLyByZWluaXRpYWxpc2UgbGVzIGZpbHNcbiAgICB0aGlzLnVwZGF0ZVVybCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFLDqWN1cMOocmUgbGUgc2x1ZyBkZSBsYSBzb3VzLWNhdMOpZ29yaWUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gTGUgc2x1ZyBkZSBsYSBzb3VzLWNhdMOpZ29yaWUuXG4gICAqL1xuICBnZXRTbHVnU3ViY2F0ZWdvcnkoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2x1Z1N1YkNhdGVnb3J5O1xuICB9XG5cbiAgLyoqXG4gICAqIETDqWZpbmlyIGxlIHNsdWcgZGUgbGEgbG9jYWxpc2F0aW9uIGV0IG1ldCDDoCBqb3VyIGwnVVJMLlxuICAgKiBAcGFyYW0ge3N0cmluZ3xudWxsfSBzbHVnIC0gTGUgc2x1ZyBkZSBsYSBsb2NhbGlzYXRpb24uXG4gICAqL1xuICBzZXRTbHVnTG9jYWxpc2F0aW9uKHNsdWcpIHtcbiAgICB0aGlzLnNsdWdMb2NhbGlzYXRpb24gPSBzbHVnO1xuICAgIHRoaXMudXBkYXRlVXJsKCk7XG4gIH1cblxuICAvKipcbiAgICogUsOpY3Vww6hyZSBsZSBzbHVnIGRlIGxhIGxvY2FsaXNhdGlvbi5cbiAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBMZSBzbHVnIGRlIGxhIGxvY2FsaXNhdGlvbi5cbiAgICovXG4gIGdldFNsdWdMb2NhbGlzYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuc2x1Z0xvY2FsaXNhdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXQgw6Agam91ciBsJ1VSTCBkYW5zIGxlIG5hdmlnYXRldXIgZW4gZm9uY3Rpb24gZGVzIHByb3ByacOpdMOpcyBhY3R1ZWxsZXMuXG4gICAqL1xuICB1cGRhdGVVcmwoKSB7XG4gICAgLy8gUsOpY3Vww6lyZXIgbGUgcGF0aCBkZSBsJ1VSTCBhY3R1ZWxsZS5cbiAgICBjb25zdCBjdXJyZW50VVJMID0gbmV3IFVSTCh3aW5kb3cubG9jYXRpb24pO1xuICAgIGNvbnN0IHVybFBhdGggPSBjdXJyZW50VVJMLnBhdGhuYW1lO1xuICAgIGNvbnN0IHVybFBhdGhQYXJ0cyA9IHVybFBhdGguc3BsaXQoJy8nKTtcbiAgICB1cmxQYXRoUGFydHMuc2hpZnQoKTsgLy8gUmV0aXJlciBsZSBwcmVtaWVyIHNsYXNoXG5cbiAgICAvLyBDb25zdHJ1Y3Rpb24gZGUgbGEgbm91dmVsbGUgc2VjdGlvbiBkZSBsJ1VSTC5cbiAgICBjb25zdCBuZXdVcmxQYXRoID0gW107XG4gICAgbmV3VXJsUGF0aFswXSA9IHRoaXMuc2x1Z0NhdGVnb3J5O1xuICAgIG5ld1VybFBhdGhbMV0gPSB0aGlzLnNsdWdTdWJDYXRlZ29yeTtcbiAgICBuZXdVcmxQYXRoWzJdID0gdGhpcy5zbHVnTG9jYWxpc2F0aW9uO1xuXG4gICAgY29uc3QgbWFwU2VjdGlvbiA9IG5ld1VybFBhdGguZmlsdGVyKEJvb2xlYW4pLmpvaW4oJy8nKTtcblxuICAgIGxldCBuZXdVcmwgPSAnJztcblxuICAgIC8vIENyw6lhdGlvbiBkZSBsYSBub3V2ZWxsZSBVUkwgZW4gdXRpbGlzYW50IGxhIGJhc2UgZGUgbCdVUkwgcHLDqWPDqWRlbnRlIGV0IGVuIGFqb3V0YW50IGxhIG5vdXZlbGxlIHNlY3Rpb24uXG4gICAgaWYgKHdpbmRvdy5tYXBDb25maWcuaXNfbXVsdGlsaW5ndWFsKSB7XG4gICAgICBuZXdVcmwgPSBgLyR7dXJsUGF0aFBhcnRzWzBdfS8ke3VybFBhdGhQYXJ0c1sxXX0vJHttYXBTZWN0aW9ufWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld1VybCA9IGAvJHt1cmxQYXRoUGFydHNbMF19LyR7bWFwU2VjdGlvbn1gO1xuICAgIH1cblxuICAgIC8vIE1ldHRyZSDDoCBqb3VyIGwnaGlzdG9yaXF1ZSBkdSBuYXZpZ2F0ZXVyIGF2ZWMgbGEgbm91dmVsbGUgVVJMIHNhbnMgcmVjaGFyZ2VyIGxhIHBhZ2UuXG4gICAgd2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKHt9LCAnJ
4084ywgbmV3VXJsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbmFseXNlIGwnVVJMIGFjdHVlbGxlIGV0IG1ldCDDoCBqb3VyIGxlcyBwcm9wcmnDqXTDqXMgZGUgbGEgY2xhc3NlIGVuIGZvbmN0aW9uIGRlcyBzZWN0aW9ucyBkJ1VSTCBjb3JyZXNwb25kYW50ZXMuXG4gICAqL1xuICBwYXJzZVVybCgpIHtcbiAgICAvLyBSw6ljdXDDqXJlciBsZSBwYXRoIGRlIGwnVVJMIGFjdHVlbGxlLlxuICAgIGNvbnN0IGN1cnJlbnRVUkwgPSBuZXcgVVJMKHdpbmRvdy5sb2NhdGlvbik7XG4gICAgY29uc3QgdXJsUGF0aCA9IGN1cnJlbnRVUkwucGF0aG5hbWU7XG4gICAgY29uc3QgdXJsUGF0aFBhcnRzID0gdXJsUGF0aC5zcGxpdCgnLycpO1xuXG4gICAgdXJsUGF0aFBhcnRzLnNoaWZ0KCk7IC8vIFJldGlyZXIgbGUgcHJlbWllciBzbGFzaFxuICAgIGlmICh3aW5kb3cubWFwQ29uZmlnLmlzX211bHRpbGluZ3VhbCkge1xuICAgICAgdXJsUGF0aFBhcnRzLnNoaWZ0KCk7IC8vIFJldGlyZXIgbGEgbGFuZ3VlXG4gICAgfVxuICAgIHVybFBhdGhQYXJ0cy5zaGlmdCgpOyAvLyBSZXRpcmVyIGxlIG5vbSBkZSBsYSBwYWdlIGRlIGNhcnRlXG5cbiAgICAvLyBSZW1wbGlyIGxlcyBwcm9wcmnDqXTDqXMgZGUgbGEgY2xhc3NlIGF2ZWMgbGVzIHZhbGV1cnMgZHUgdGFibGVhdSBkZSBsJ1VSTC5cbiAgICBbdGhpcy5zbHVnQ2F0ZWdvcnksIHRoaXMuc2x1Z1N1YkNhdGVnb3J5LCB0aGlzLnNsdWdMb2NhbGlzYXRpb25dID0gdXJsUGF0aFBhcnRzO1xuXG4gICAgLy8gU2kgbCdVUmwgZXN0IHZpZGUsIGxlIHByZW1pZXIgw6lsw6ltZW50IGR1IHRhYmxlYXUgc2VyYSB1bmUgY2hhaW5lIHZpZGUsIGlsIGZhdXQgcmVtcGxhY2VyIMOnYSBwYXIgbnVsbC5cbiAgICBpZiAodGhpcy5zbHVnQ2F0ZWdvcnkgPT09ICcnKSB7XG4gICAgICB0aGlzLnNsdWdDYXRlZ29yeSA9IG51bGw7XG4gICAgfVxuXG4gICAgLy8gUydpbCB5IGEgc2V1bGVtZW50IHVuIHBhcmFtw6h0cmUgZGFucyBsJ1VSTC5cbiAgICBpZiAodGhpcy5zbHVnU3ViQ2F0ZWdvcnkgPT0gbnVsbCAmJiB0aGlzLnNsdWdMb2NhbGlzYXRpb24gPT0gbnVsbCkge1xuICAgICAgLy8gUydpbCBuJ3kgYSBwYXMgZGUgY2F0w6lnb3JpZSBxdWkgY29ycmVzcG9uZCwgYydlc3QgcHJvYmFibGVtZW50IGxlIHNsdWcgZCd1biBQT0kuXG4gICAgICBpZiAoIWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYC5jLW1hcC1jYXRlZ29yaWVzX19pdGVtW2RhdGEtc2x1Zz1cIiR7dGhpcy5zbHVnQ2F0ZWdvcnl9XCJdYCkpIHtcbiAgICAgICAgdGhpcy5zbHVnTG9jYWxpc2F0aW9uID0gdGhpcy5zbHVnQ2F0ZWdvcnk7XG4gICAgICAgIHRoaXMuc2x1Z1N1YkNhdGVnb3J5ID0gbnVsbDtcbiAgICAgICAgdGhpcy5zbHVnQ2F0ZWdvcnkgPSBudWxsO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodGhpcy5zbHVnTG9jYWxpc2F0aW9uID09IG51bGwpIHtcbiAgICAgIC8vIFMnaWwgbid5IGEgcGFzIGRlIHNvdXMtY2F0w6lnb3JpZSBxdWkgY29ycmVzcG9uZCwgYydlc3QgcHJvYmFibGVtZW50IGxlIHNsdWcgZCd1biBQT0kuXG4gICAgICBpZiAoIWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYC5jLW1hcC1zdWJjYXRlZ29yaWVzX19pdGVtW2RhdGEtc2x1Zz1cIiR7dGhpcy5zbHVnU3ViQ2F0ZWdvcnl9XCJdYCkpIHtcbiAgICAgICAgdGhpcy5zbHVnTG9jYWxpc2F0aW9uID0gdGhpcy5zbHVnU3ViQ2F0ZWdvcnk7XG4gICAgICAgIHRoaXMuc2x1Z1N1YkNhdGVnb3J5ID0gbnVsbDtcbiAgICAgICAgdGhpcy5zbHVnQ2F0ZWdvcnkgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXNlIGxhIGNsYXNzZSBNYXBVcmxcbiAgICovXG4gIGluaXQoKSB7XG4gICAgdGhpcy5wYXJzZVVybCgpO1xuICB9XG59XG4iLCIvKipcbiAqIETDqXRlcm1pbmUgc2kgbCdhcHBhcmVpbCBkaXNwb3NlIGRlIGxhIGZvbmN0aW9ubmFsaXTDqSB0YWN0aWxlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgc2kgbCdhcHBhcmVpbCBlc3QgdGFjdGlsZSwgc2lub24gRmFsc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1RvdWNoRGV2aWNlKCkge1xuICByZXR1cm4gKCgnb250b3VjaHN0YXJ0JyBpbiB3aW5kb3cpIHx8IChuYXZpZ2F0b3IubWF4VG91Y2hQb2ludHMgPiAwKSB8fCAobmF2aWdhdG9yLm1zTWF4VG91Y2hQb2ludHMgPiAwKSk7XG59XG5cbi8qKlxuICogRMOpdGVybWluZSBzaSBsJ2FwcGFyZWlsIGRpc3Bvc2UgZGUgbGEgZm9uY3Rpb25uYWxpdMOpIGRlIGfDqW9sb2NhbGlzYXRpb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBzaSBsJ2FwcGFyZWlsIHN1cHBvcnRlIGxhIGfDqW9sb2NhbGlzYXRpb24sIHNpbm9uIEZhbHNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzR2VvbG9jYXRpb24oKSB7XG4gIHJldHVybiBuYXZpZ2F0b3IuZ2VvbG9jYXRpb247XG59XG5cbi8qKlxuICogRMOpdGVybWluZSBzaSB1bmUgY29vcmRvbm7DqWUgR1BTIHNlIHRyb3V2ZSDDoCBsJ2ludMOpcmlldXIgZCd1biBjYXJyw6kgZGUgY29vcmRvbm7DqWVzIEdQUy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGxhIGNvb3Jkb27DqWUgc2UgdHJvdXZlIMOgIGwnaW50w6lyZXVyIGRlIGxhIHpvbmUsIHNpbm9uIEZhbHNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNJblpvbmUobGF0LCBsbmcsIHpvbmUpIHtcbiAgbGV0IHJlc3VsdCA9IGZhbHNlO1xuICBpZiAobGF0IDwgem9uZS5ub3J0aCAmJiBsYXQgPiB6b25lLnNvdXRoICYmIGxuZyA+IHpvbmUud2VzdCAmJiBsbmcgPCB6b25lLmVhc3QpIHtcbiAgICByZXN1bHQgPSB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiIsImltcG9ydCBPYnNlcnZlciBmcm9tICcuL3ZlbmRvci9vYnNlcnZlci5taW4nO1xuXG5leHBvcnQgY29uc3QgT0JTRVJWRVIgPSBPYnNlcnZlci5nZXRJbnN0YW5jZSgpO1xuIiwiIWZ1bmN0aW9uKGUsdCl7XCJvYmplY3RcIj09dHlwZW9mIGV4cG9ydHMmJlwib2JqZWN0XCI9PXR5cGVvZiBtb2R1bGU/bW9kdWxlLmV4cG9ydHM9dCgpOlwiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUoW10sdCk6XCJvYmplY3RcIj09dHlwZW9mIGV4cG9ydHM/ZXhwb3J0cy5PYnNlcnZlcj10KCk6ZS5PYnNlcnZlcj10KCl9KHNlbGYsKGZ1bmN0aW9uKCl7cmV0dXJuKCgpPT57XCJ1c2Ugc3RyaWN0XCI7dmFyIGU9ezYwNzooZSx0LHMpPT57ZS5leHBvcnRzPXMoNDAwKS5kZWZh
4084dWx0fSw0MDA6KGUsdCxzKT0+e3MuZCh0LHtkZWZhdWx0OigpPT5pfSk7Y29uc3Qgbj1lPT57bGV0IHQscz0wO2Zvcih0IGluIGUpZS5oYXNPd25Qcm9wZXJ0eSh0KSYmcysrO3JldHVybiBzfTtjbGFzcyBpe2NvbnN0cnVjdG9yKCl7dGhpcy5ldmVudExpc3Q9e319Z2V0IGxpc3QoKXtyZXR1cm4gdGhpcy5ldmVudExpc3R9dGhyb3dNZXNzYWdlKGUpe2NvbnNvbGUud2FybihgT2JzZXJ2ZXIgPT4gJHtlfWApfXRvZ2dsZShlKXtsZXQgdCxzO2NvbnN0IGk9bih0aGlzLmV2ZW50TGlzdCk7Zm9yKHQ9MDt0PGk7dCs9MSlzPWBldmVudCR7dH1gLGUocyl9bWFuYWdlTGlzdGVuZXJzKGUsdCxzKXtsZXQgbixpO2NvbnN0IHI9dGhpcy5ldmVudExpc3Rbc10udGFyZ2V0cy5sZW5ndGgsbz10aGlzLmV2ZW50TGlzdFtzXS5ldmVudHMubGVuZ3RoO2ZvcihuPTA7bjxyO24rPTEpZm9yKGk9MDtpPG87aSs9MSl0aGlzLmV2ZW50TGlzdFtzXS50YXJnZXRzW25dW2VdKHRoaXMuZXZlbnRMaXN0W3NdLmV2ZW50c1tpXSx0aGlzLmV2ZW50TGlzdFtzXS5mdW5jdGlvbik7dGhpcy5ldmVudExpc3Rbc10uYWN0aXZlPXR9bWFuYWdlVGFyZ2V0cyhlKXtsZXQgdDtyZXR1cm4gdD1cImRvY3VtZW50XCI9PT1lfHxlPT09ZG9jdW1lbnQ/W2RvY3VtZW50XTpcIndpbmRvd1wiPT09ZXx8ZT09PXdpbmRvdz9bd2luZG93XTpcInN0cmluZ1wiPT10eXBlb2YgZT9bLi4uZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChlKV06ZSBpbnN0YW5jZW9mIE5vZGVMaXN0P1suLi5lXTplIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQ/W2VdOlt3aW5kb3ddLHR9bWFuYWdlRXZlbnRzKGUpe3JldHVybiBlLnNwbGl0KFwiIFwiKX1zdGF0aWMgZ2V0SW5zdGFuY2UoKXtyZXR1cm4gaS5pbnN0YW5jZXx8KHRoaXMuaW5zdGFuY2U9bmV3IGkpLHRoaXMuaW5zdGFuY2V9b24oZSl7dGhpcy50b2dnbGUoKHQ9Pnt0aGlzLmV2ZW50TGlzdFt0XS5uYW1lPT09ZSYmdGhpcy5tYW5hZ2VMaXN0ZW5lcnMoXCJhZGRFdmVudExpc3RlbmVyXCIsITAsdCl9KSl9b2ZmKGUpe3RoaXMudG9nZ2xlKCh0PT57dGhpcy5ldmVudExpc3RbdF0ubmFtZT09PWUmJnRoaXMubWFuYWdlTGlzdGVuZXJzKFwicmVtb3ZlRXZlbnRMaXN0ZW5lclwiLCExLHQpfSkpfWFsbE9uKCl7dGhpcy50b2dnbGUoKGU9PnRoaXMubWFuYWdlTGlzdGVuZXJzKFwiYWRkRXZlbnRMaXN0ZW5lclwiLCEwLGUpKSl9YWxsT2ZmKCl7dGhpcy50b2dnbGUoKGU9PnRoaXMubWFuYWdlTGlzdGVuZXJzKFwicmVtb3ZlRXZlbnRMaXN0ZW5lclwiLCExLGUpKSl9cmVmcmVzaChlKXt0aGlzLm9mZihlKSx0aGlzLm9uKGUpfXJlZnJlc2hBbGwoKXt0aGlzLmFsbE9mZigpLHRoaXMuYWxsT24oKX1hZGQoZSl7Y29uc3QgdD1gZXZlbnQke24odGhpcy5ldmVudExpc3QpfWA7dGhpcy5ldmVudExpc3RbdF09e30sdGhpcy5ldmVudExpc3RbdF0ubmFtZT1lLm5hbWUsdGhpcy5ldmVudExpc3RbdF0uYWN0aXZlPSExLHRoaXMuZXZlbnRMaXN0W3RdLmV2ZW50cz10aGlzLm1hbmFnZUV2ZW50cyhlLmV2ZW50cyksdGhpcy5ldmVudExpc3RbdF0uZXZlbnRzQ291bnQ9dGhpcy5ldmVudExpc3RbdF0uZXZlbnRzLmxlbmd0aCx0aGlzLmV2ZW50TGlzdFt0XS5mdW5jdGlvbj1lLmZ1bmN0aW9uLHRoaXMuZXZlbnRMaXN0W3RdLnRhcmdldHM9dGhpcy5tYW5hZ2VUYXJnZXRzKGUudGFyZ2V0cyksdGhpcy5ldmVudExpc3RbdF0udGFyZ2V0c0NvdW50PXRoaXMuZXZlbnRMaXN0W3RdLnRhcmdldHMubGVuZ3RofXJlbW92ZShlKXt0aGlzLnRvZ2dsZSgodD0+e3RoaXMuZXZlbnRMaXN0W3RdLm5hbWU9PT1lJiYodGhpcy5tYW5hZ2VMaXN0ZW5lcnMoXCJyZW1vdmVFdmVudExpc3RlbmVyXCIsITEsdCksdGhpcy5ldmVudExpc3RbdF0uYWN0aXZlfHxkZWxldGUgdGhpcy5ldmVudExpc3RbdF0pfSkpfXJlbW92ZUFsbCgpe3RoaXMudG9nZ2xlKChlPT57dGhpcy5tYW5hZ2VMaXN0ZW5lcnMoXCJyZW1vdmVFdmVudExpc3RlbmVyXCIsITEsZSksdGhpcy5ldmVudExpc3RbZV0uYWN0aXZlfHxkZWxldGUgdGhpcy5ldmVudExpc3RbZV19KSl9fX19LHQ9e307ZnVuY3Rpb24gcyhuKXt2YXIgaT10W25dO2lmKHZvaWQgMCE9PWkpcmV0dXJuIGkuZXhwb3J0czt2YXIgcj10W25dPXtleHBvcnRzOnt9fTtyZXR1cm4gZVtuXShyLHIuZXhwb3J0cyxzKSxyLmV4cG9ydHN9cmV0dXJuIHMuZD0oZSx0KT0+e2Zvcih2YXIgbiBpbiB0KXMubyh0LG4pJiYhcy5vKGUsbikmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eShlLG4se2VudW1lcmFibGU6ITAsZ2V0OnRbbl19KX0scy5vPShlLHQpPT5PYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZSx0KSxzKDYwNyl9KSgpfSkpOyIsIid1c2Ugc3RyaWN0JztcblxuLy8gZG8gbm90IGVkaXQgLmpzIGZpbGVzIGRpcmVjdGx5IC0gZWRpdCBzcmMvaW5kZXguanN0XG5cblxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGVxdWFsKGEsIGIpIHtcbiAgaWYgKGEgPT09IGIpIHJldHVybiB0cnVlO1xuXG4gIGlmIChhICYmIGIgJiYgdHlwZW9mIGEgPT0gJ29iamVjdCcgJiYgdHlwZW9mIGIgPT0gJ29iamVjdCcpIHtcbiAgICBpZiAoYS5jb25zdHJ1Y3RvciAhPT0gYi5jb25zdHJ1Y3RvcikgcmV0dXJuIGZhbHNlO1xuXG4gICAgdmFyIGxlbmd0aCwgaSwga2V5cztcbiAgICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgICAgbGVuZ3RoID0gYS5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoICE9IGIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gICAgICBmb3IgKGkgPSBsZW5ndGg7IGktLSAhPT0gMDspXG4gICAgICAgIGlmICghZXF1YWwoYVtpXSwgYltpXSkpIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuXG5cbiAgICBpZiAoYS5jb25zdHJ1Y3RvciA9PT0gUmVnRXhwKSByZXR1cm4gYS5zb3VyY2UgPT09IGIuc291cmNlICYmIGEuZmxhZ3MgPT09IGIuZmxhZ3M7XG4gICAgaWYgKGEudmFsdWVPZiAhPT0gT2JqZWN0LnByb3RvdHlwZS52YWx1ZU9mKSByZXR1cm4gYS52YWx1ZU9mKCkgPT09IGIudmFsdWVPZigpO1xuICAgIGlmIChhLnRvU3RyaW5nICE9PSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKSByZXR1cm4gYS50b1N0cmluZygpID09PSBiLnRvU3RyaW5nKCk7XG5cbiAgICBrZXlzID0gT2JqZWN0LmtleXMoYSk7XG4gICAgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgaWYgKGxlbmd0aCAhPT0gT2JqZWN0LmtleXMoYikubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG5cbiAgICBmb3IgKGkgPSBsZW5ndGg7IGktLSAhPT0gMDspXG4gICAgICBpZiAoIU9i
4084amVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBrZXlzW2ldKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgZm9yIChpID0gbGVuZ3RoOyBpLS0gIT09IDA7KSB7XG4gICAgICB2YXIga2V5ID0ga2V5c1tpXTtcblxuICAgICAgaWYgKCFlcXVhbChhW2tleV0sIGJba2V5XSkpIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIHRydWUgaWYgYm90aCBOYU4sIGZhbHNlIG90aGVyd2lzZVxuICByZXR1cm4gYSE9PWEgJiYgYiE9PWI7XG59O1xuIiwiXG5jb25zdCBBUlJBWV9UWVBFUyA9IFtcbiAgICBJbnQ4QXJyYXksIFVpbnQ4QXJyYXksIFVpbnQ4Q2xhbXBlZEFycmF5LCBJbnQxNkFycmF5LCBVaW50MTZBcnJheSxcbiAgICBJbnQzMkFycmF5LCBVaW50MzJBcnJheSwgRmxvYXQzMkFycmF5LCBGbG9hdDY0QXJyYXlcbl07XG5cbi8qKiBAdHlwZWRlZiB7SW50OEFycmF5Q29uc3RydWN0b3IgfCBVaW50OEFycmF5Q29uc3RydWN0b3IgfCBVaW50OENsYW1wZWRBcnJheUNvbnN0cnVjdG9yIHwgSW50MTZBcnJheUNvbnN0cnVjdG9yIHwgVWludDE2QXJyYXlDb25zdHJ1Y3RvciB8IEludDMyQXJyYXlDb25zdHJ1Y3RvciB8IFVpbnQzMkFycmF5Q29uc3RydWN0b3IgfCBGbG9hdDMyQXJyYXlDb25zdHJ1Y3RvciB8IEZsb2F0NjRBcnJheUNvbnN0cnVjdG9yfSBUeXBlZEFycmF5Q29uc3RydWN0b3IgKi9cblxuY29uc3QgVkVSU0lPTiA9IDE7IC8vIHNlcmlhbGl6ZWQgZm9ybWF0IHZlcnNpb25cbmNvbnN0IEhFQURFUl9TSVpFID0gODtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgS0RCdXNoIHtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5kZXggZnJvbSByYXcgYEFycmF5QnVmZmVyYCBkYXRhLlxuICAgICAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGRhdGFcbiAgICAgKi9cbiAgICBzdGF0aWMgZnJvbShkYXRhKSB7XG4gICAgICAgIGlmICghKGRhdGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRGF0YSBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIEFycmF5QnVmZmVyLicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IFttYWdpYywgdmVyc2lvbkFuZFR5cGVdID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSwgMCwgMik7XG4gICAgICAgIGlmIChtYWdpYyAhPT0gMHhkYikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEYXRhIGRvZXMgbm90IGFwcGVhciB0byBiZSBpbiBhIEtEQnVzaCBmb3JtYXQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdmVyc2lvbiA9IHZlcnNpb25BbmRUeXBlID4+IDQ7XG4gICAgICAgIGlmICh2ZXJzaW9uICE9PSBWRVJTSU9OKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEdvdCB2JHt2ZXJzaW9ufSBkYXRhIHdoZW4gZXhwZWN0ZWQgdiR7VkVSU0lPTn0uYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgQXJyYXlUeXBlID0gQVJSQVlfVFlQRVNbdmVyc2lvbkFuZFR5cGUgJiAweDBmXTtcbiAgICAgICAgaWYgKCFBcnJheVR5cGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5yZWNvZ25pemVkIGFycmF5IHR5cGUuJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgW25vZGVTaXplXSA9IG5ldyBVaW50MTZBcnJheShkYXRhLCAyLCAxKTtcbiAgICAgICAgY29uc3QgW251bUl0ZW1zXSA9IG5ldyBVaW50MzJBcnJheShkYXRhLCA0LCAxKTtcblxuICAgICAgICByZXR1cm4gbmV3IEtEQnVzaChudW1JdGVtcywgbm9kZVNpemUsIEFycmF5VHlwZSwgZGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbmRleCB0aGF0IHdpbGwgaG9sZCBhIGdpdmVuIG51bWJlciBvZiBpdGVtcy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtSXRlbXNcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW25vZGVTaXplPTY0XSBTaXplIG9mIHRoZSBLRC10cmVlIG5vZGUgKDY0IGJ5IGRlZmF1bHQpLlxuICAgICAqIEBwYXJhbSB7VHlwZWRBcnJheUNvbnN0cnVjdG9yfSBbQXJyYXlUeXBlPUZsb2F0NjRBcnJheV0gVGhlIGFycmF5IHR5cGUgdXNlZCBmb3IgY29vcmRpbmF0ZXMgc3RvcmFnZSAoYEZsb2F0NjRBcnJheWAgYnkgZGVmYXVsdCkuXG4gICAgICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gW2RhdGFdIChGb3IgaW50ZXJuYWwgdXNlIG9ubHkpXG4gICAgICovXG4gICAgY29uc3RydWN0b3IobnVtSXRlbXMsIG5vZGVTaXplID0gNjQsIEFycmF5VHlwZSA9IEZsb2F0NjRBcnJheSwgZGF0YSkge1xuICAgICAgICBpZiAoaXNOYU4obnVtSXRlbXMpIHx8IG51bUl0ZW1zIDwgMCkgdGhyb3cgbmV3IEVycm9yKGBVbnBleHBlY3RlZCBudW1JdGVtcyB2YWx1ZTogJHtudW1JdGVtc30uYCk7XG5cbiAgICAgICAgdGhpcy5udW1JdGVtcyA9ICtudW1JdGVtcztcbiAgICAgICAgdGhpcy5ub2RlU2l6ZSA9IE1hdGgubWluKE1hdGgubWF4KCtub2RlU2l6ZSwgMiksIDY1NTM1KTtcbiAgICAgICAgdGhpcy5BcnJheVR5cGUgPSBBcnJheVR5cGU7XG4gICAgICAgIHRoaXMuSW5kZXhBcnJheVR5cGUgPSBudW1JdGVtcyA8IDY1NTM2ID8gVWludDE2QXJyYXkgOiBVaW50MzJBcnJheTtcblxuICAgICAgICBjb25zdCBhcnJheVR5cGVJbmRleCA9IEFSUkFZX1RZUEVTLmluZGV4T2YodGhpcy5BcnJheVR5cGUpO1xuICAgICAgICBjb25zdCBjb29yZHNCeXRlU2l6ZSA9IG51bUl0ZW1zICogMiAqIHRoaXMuQXJyYXlUeXBlLkJZVEVTX1BFUl9FTEVNRU5UO1xuICAgICAgICBjb25zdCBpZHNCeXRlU2l6ZSA9IG51bUl0ZW1zICogdGhpcy5JbmRleEFycmF5VHlwZS5CWVRFU19QRVJfRUxFTUVOVDtcbiAgICAgICAgY29uc3QgcGFkQ29vcmRzID0gKDggLSBpZHNCeXRlU2l6ZSAlIDgpICUgODtcblxuICAgICAgICBpZiAoYXJyYXlUeXBlSW5kZXggPCAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgdHlwZWQgYXJyYXkgY2xhc3M6ICR7QXJyYXlUeXBlfS5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkYXRhICYmIChkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpKSB7IC8vIHJlY29uc3RydWN0IGFuIGluZGV4IGZyb20gYSBidWZmZXJcbiAgICAgICAgICAgI
4084HRoaXMuZGF0YSA9IGRhdGE7XG4gICAgICAgICAgICB0aGlzLmlkcyA9IG5ldyB0aGlzLkluZGV4QXJyYXlUeXBlKHRoaXMuZGF0YSwgSEVBREVSX1NJWkUsIG51bUl0ZW1zKTtcbiAgICAgICAgICAgIHRoaXMuY29vcmRzID0gbmV3IHRoaXMuQXJyYXlUeXBlKHRoaXMuZGF0YSwgSEVBREVSX1NJWkUgKyBpZHNCeXRlU2l6ZSArIHBhZENvb3JkcywgbnVtSXRlbXMgKiAyKTtcbiAgICAgICAgICAgIHRoaXMuX3BvcyA9IG51bUl0ZW1zICogMjtcbiAgICAgICAgICAgIHRoaXMuX2ZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHsgLy8gaW5pdGlhbGl6ZSBhIG5ldyBpbmRleFxuICAgICAgICAgICAgdGhpcy5kYXRhID0gbmV3IEFycmF5QnVmZmVyKEhFQURFUl9TSVpFICsgY29vcmRzQnl0ZVNpemUgKyBpZHNCeXRlU2l6ZSArIHBhZENvb3Jkcyk7XG4gICAgICAgICAgICB0aGlzLmlkcyA9IG5ldyB0aGlzLkluZGV4QXJyYXlUeXBlKHRoaXMuZGF0YSwgSEVBREVSX1NJWkUsIG51bUl0ZW1zKTtcbiAgICAgICAgICAgIHRoaXMuY29vcmRzID0gbmV3IHRoaXMuQXJyYXlUeXBlKHRoaXMuZGF0YSwgSEVBREVSX1NJWkUgKyBpZHNCeXRlU2l6ZSArIHBhZENvb3JkcywgbnVtSXRlbXMgKiAyKTtcbiAgICAgICAgICAgIHRoaXMuX3BvcyA9IDA7XG4gICAgICAgICAgICB0aGlzLl9maW5pc2hlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAvLyBzZXQgaGVhZGVyXG4gICAgICAgICAgICBuZXcgVWludDhBcnJheSh0aGlzLmRhdGEsIDAsIDIpLnNldChbMHhkYiwgKFZFUlNJT04gPDwgNCkgKyBhcnJheVR5cGVJbmRleF0pO1xuICAgICAgICAgICAgbmV3IFVpbnQxNkFycmF
40845KHRoaXMuZGF0YSwgMiwgMSlbMF0gPSBub2RlU2l6ZTtcbiAgICAgICAgICAgIG5ldyBVaW50MzJBcnJheSh0aGlzLmRhdGEsIDQsIDEpWzBdID0gbnVtSXRlbXM7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBwb2ludCB0byB0aGUgaW5kZXguXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IEFuIGluY3JlbWVudGFsIGluZGV4IGFzc29jaWF0ZWQgd2l0aCB0aGUgYWRkZWQgaXRlbSAoc3RhcnRpbmcgZnJvbSBgMGApLlxuICAgICAqL1xuICAgIGFkZCh4LCB5KSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fcG9zID4+IDE7XG4gICAgICAgIHRoaXMuaWRzW2luZGV4XSA9IGluZGV4O1xuICAgICAgICB0aGlzLmNvb3Jkc1t0aGlzLl9wb3MrK10gPSB4O1xuICAgICAgICB0aGlzLmNvb3Jkc1t0aGlzLl9wb3MrK10gPSB5O1xuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGVyZm9ybSBpbmRleGluZyBvZiB0aGUgYWRkZWQgcG9pbnRzLlxuICAgICAqL1xuICAgIGZpbmlzaCgpIHtcbiAgICAgICAgY29uc3QgbnVtQWRkZWQgPSB0aGlzLl9wb3MgPj4gMTtcbiAgICAgICAgaWYgKG51bUFkZGVkICE9PSB0aGlzLm51bUl0ZW1zKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEFkZGVkICR7bnVtQWRkZWR9IGl0ZW1zIHdoZW4gZXhwZWN0ZWQgJHt0aGlzLm51bUl0ZW1zfS5gKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBrZC1zb3J0IGJvdGggYXJyYXlzIGZvciBlZmZpY2llbnQgc2VhcmNoXG4gICAgICAgIHNvcnQodGhpcy5pZHMsIHRoaXMuY29vcmRzLCB0aGlzLm5vZGVTaXplLCAwLCB0aGlzLm51bUl0ZW1zIC0gMSwgMCk7XG5cbiAgICAgICAgdGhpcy5fZmluaXNoZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWFyY2ggdGhlIGluZGV4IGZvciBpdGVtcyB3aXRoaW4gYSBnaXZlbiBib3VuZGluZyBib3guXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1pblhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWluWVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtYXhYXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1heFlcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyW119IEFuIGFycmF5IG9mIGluZGljZXMgY29ycmVwb25kaW5nIHRvIHRoZSBmb3VuZCBpdGVtcy5cbiAgICAgKi9cbiAgICByYW5nZShtaW5YLCBtaW5ZLCBtYXhYLCBtYXhZKSB7XG4gICAgICAgIGlmICghdGhpcy5fZmluaXNoZWQpIHRocm93IG5ldyBFcnJvcignRGF0YSBub3QgeWV0IGluZGV4ZWQgLSBjYWxsIGluZGV4LmZpbmlzaCgpLicpO1xuXG4gICAgICAgIGNvbnN0IHtpZHMsIGNvb3Jkcywgbm9kZVNpemV9ID0gdGhpcztcbiAgICAgICAgY29uc3Qgc3RhY2sgPSBbMCwgaWRzLmxlbmd0aCAtIDEsIDBdO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBbXTtcblxuICAgICAgICAvLyByZWN1cnNpdmVseSBzZWFyY2ggZm9yIGl0ZW1zIGluIHJhbmdlIGluIHRoZSBrZC1zb3J0ZWQgYXJyYXlzXG4gICAgICAgIHdoaWxlIChzdGFjay5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGF4aXMgPSBzdGFjay5wb3AoKSB8fCAwO1xuICAgICAgICAgICAgY29uc3QgcmlnaHQgPSBzdGFjay5wb3AoKSB8fCAwO1xuICAgICAgICAgICAgY29uc3QgbGVmdCA9IHN0YWNrLnBvcCgpIHx8IDA7XG5cbiAgICAgICAgICAgIC8vIGlmIHdlIHJlYWNoZWQgXCJ0cmVlIG5vZGVcIiwgc2VhcmNoIGxpbmVhcmx5XG4gICAgICAgICAgICBpZiAocmlnaHQgLSBsZWZ0IDw9IG5vZGVTaXplKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGxlZnQ7IGkgPD0gcmlnaHQ7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB4ID0gY29vcmRzWzIgKiBpXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeSA9IGNvb3Jkc1syICogaSArIDFdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoeCA+PSBtaW5YICYmIHggPD0gbWF4WCAmJiB5ID49IG1pblkgJiYgeSA8PSBtYXhZKSByZXN1bHQucHVzaChpZHNbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGZpbmQgdGhlIG1pZGRsZSBpbmRleFxuICAgICAgICAgICAgY29uc3QgbSA9IChsZWZ0ICsgcmlnaHQpID4+IDE7XG5cbiAgICAgICAgICAgIC8vIGluY2x1ZGUgdGhlIG1pZGRsZSBpdGVtIGlmIGl0J3MgaW4gcmFuZ2VcbiAgICAgICAgICAgIGNvbnN0IHggPSBjb29yZHNbMiAqIG1dO1xuICAgICAgICAgICAgY29uc3QgeSA9IGNvb3Jkc1syICogbSArIDFdO1xuICAgICAgICAgICAgaWYgKHggPj0gbWluWCAmJiB4IDw9IG1heFggJiYgeSA+PSBtaW5ZICYmIHkgPD0gbWF4WSkgcmVzdWx0LnB1c2goaWRzW21dKTtcblxuICAgICAgICAgICAgLy8gcXVldWUgc2VhcmNoIGluIGhhbHZlcyB0aGF0IGludGVyc2VjdCB0aGUgcXVlcnlcbiAgICAgICAgICAgIGlmIChheGlzID09PSAwID8gbWluWCA8PSB4IDogbWluWSA8PSB5KSB7XG4gICAgICAgICAgICAgICAgc3RhY2sucHVzaChsZWZ0KTtcbiAgICAgICAgICAgICAgICBzdGFjay5wdXNoKG0gLSAxKTtcbiAgICAgICAgICAgICAgICBzdGFjay5wdXNoKDEgLSBheGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChheGlzID09PSAwID8gbWF4WCA+PSB4IDogbWF4WSA+PSB5KSB7XG4gICAgICAgICAgICAgICAgc3RhY2sucHVzaChtICsgMSk7XG4gICAgICAgICAgICAgICAgc3RhY2sucHVzaChyaWdodCk7XG4gICAgICAgICAgICAgICAgc3RhY2sucHVzaCgxIC0gYXhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlYXJjaCB0aGUgaW5kZXggZm9yIGl0ZW1zIHdpdGhpbiBhIGdpdmVuIHJhZGl1cy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcXhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcXlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gciBRdWVyeSByYWRpdXMuXG4gICAgICogQHJldHVybnMge251bWJlcltdfSBBbiBhcnJheSBvZiBpbmRpY2VzIGNvcnJlcG9uZGluZyB0byB0aGUgZm91bmQgaXRlbXMuXG4gICAgICovXG4gICAgd2l0aGluKHF4LCBxeSwgcikge1xuICAgICAgICBpZiAoIXRoaXMuX2ZpbmlzaGVkKSB0aHJvdyBuZXcgRXJyb3IoJ0RhdGEgbm90IHlldCBpbmRleGVkIC0gY2FsbCBpbmRleC5maW5pc2goKS4nKTtcblxuICAgICAgICBjb25zdCB7aWRzLCBjb29yZHMsIG5vZGVTaXplfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IHN0YWNrID0gWzAsIGlkcy5sZW5ndGggLSAxLCAwXTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgICAgIGNvbnN0IHIyID0gciAqIHI7XG5cbiAgICAgICAgLy8gcmVjdXJzaXZlbHkgc2VhcmNoIGZvciBpdGVtcyB3aXRoaW4gcmFkaXVzIGluIHRoZSBrZC1zb3J0ZWQgYXJyYXlzXG4gICAgICAgI
4084HdoaWxlIChzdGFjay5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGF4aXMgPSBzdGFjay5wb3AoKSB8fCAwO1xuICAgICAgICAgICAgY29uc3QgcmlnaHQgPSBzdGFjay5wb3AoKSB8fCAwO1xuICAgICAgICAgICAgY29uc3QgbGVmdCA9IHN0YWNrLnBvcCgpIHx8IDA7XG5cbiAgICAgICAgICAgIC8vIGlmIHdlIHJlYWNoZWQgXCJ0cmVlIG5vZGVcIiwgc2VhcmNoIGxpbmVhcmx5XG4gICAgICAgICAgICBpZiAocmlnaHQgLSBsZWZ0IDw9IG5vZGVTaXplKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGxlZnQ7IGkgPD0gcmlnaHQ7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3FEaXN0KGNvb3Jkc1syICogaV0sIGNvb3Jkc1syICogaSArIDFdLCBxeCwgcXkpIDw9IHIyKSByZXN1bHQucHVzaChpZHNbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGZpbmQgdGhlIG1pZGRsZSBpbmRleFxuICAgICAgICAgICAgY29uc3QgbSA9IChsZWZ0ICsgcmlnaHQpID4+IDE7XG5cbiAgICAgICAgICAgIC8vIGluY2x1ZGUgdGhlIG1pZGRsZSBpdGVtIGlmIGl0J3MgaW4gcmFuZ2VcbiAgICAgICAgICAgIGNvbnN0IHggPSBjb29yZHNbMiAqIG1dO1xuICAgICAgICAgICAgY29uc3QgeSA9IGNvb3Jkc1syICogbSArIDFdO1xuICAgICAgICAgICAgaWYgKHNxRGlzdCh4LCB5LCBxeCwgcXkpIDw9IHIyKSByZXN1bHQucHVzaChpZHNbbV0pO1xuXG4gICAgICAgICAgICAvLyBxdWV1ZSBzZWFyY2ggaW4gaGFsdmVzIHRoYXQgaW50ZXJzZWN0IHRoZSBxdWVyeVxuICAgICAgICAgICAgaWYgKGF4aXMgPT09IDAgPyBxeCAtIHIgPD0geCA6IHF5IC0gciA8PSB5KSB7XG4gICAgICAgICAgICAgICAgc3RhY2sucHVzaChsZWZ0KTtcbiAgICAgICAgICAgICAgICBzdGFjay5wdXNoKG0gLSAxKTtcbiAgICAgICAgICAgICAgICBzdGFjay5wdXNoKDEgLSBheGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChheGlzID09PSAwID8gcXggKyByID49IHggOiBxeSArIHIgPj0geSkge1xuICAgICAgICAgICAgICAgIHN0YWNrLnB1c2gobSArIDEpO1xuICAgICAgICAgICAgICAgIHN0YWNrLnB1c2gocmlnaHQpO1xuICAgICAgICAgICAgICAgIHN0YWNrLnB1c2goMSAtIGF4aXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtVaW50MTZBcnJheSB8IFVpbnQzMkFycmF5fSBpZHNcbiAqIEBwYXJhbSB7SW5zdGFuY2VUeXBlPFR5cGVkQXJyYXlDb25zdHJ1Y3Rvcj59IGNvb3Jkc1xuICogQHBhcmFtIHtudW1iZXJ9IG5vZGVTaXplXG4gKiBAcGFyYW0ge251bWJlcn0gbGVmdFxuICogQHBhcmFtIHtudW1iZXJ9IHJpZ2h0XG4gKiBAcGFyYW0ge251bWJlcn0gYXhpc1xuICovXG5mdW5jdGlvbiBzb3J0KGlkcywgY29vcmRzLCBub2RlU2l6ZSwgbGVmdCwgcmlnaHQsIGF4aXMpIHtcbiAgICBpZiAocmlnaHQgLSBsZWZ0IDw9IG5vZGVTaXplKSByZXR1cm47XG5cbiAgICBjb25zdCBtID0gKGxlZnQgKyByaWdodCkgPj4gMTsgLy8gbWlkZGxlIGluZGV4XG5cbiAgICAvLyBzb3J0IGlkcyBhbmQgY29vcmRzIGFyb3VuZCB0aGUgbWlkZGxlIGluZGV4IHNvIHRoYXQgdGhlIGhhbHZlcyBsaWVcbiAgICAvLyBlaXRoZXIgbGVmdC9yaWdodCBvciB0b3AvYm90dG9tIGNvcnJlc3BvbmRpbmdseSAodGFraW5nIHR1cm5zKVxuICAgIHNlbGVjdChpZHMsIGNvb3JkcywgbSwgbGVmdCwgcmlnaHQsIGF4aXMpO1xuXG4gICAgLy8gcmVjdXJzaXZlbHkga2Qtc29ydCBmaXJzdCBoYWxmIGFuZCBzZWNvbmQgaGFsZiBvbiB0aGUgb3Bwb3NpdGUgYXhpc1xuICAgIHNvcnQoaWRzLCBjb29yZHMsIG5vZGVTaXplLCBsZWZ0LCBtIC0gMSwgMSAtIGF4aXMpO1xuICAgIHNvcnQoaWRzLCBjb29yZHMsIG5vZGVTaXplLCBtICsgMSwgcmlnaHQsIDEgLSBheGlzKTtcbn1cblxuLyoqXG4gKiBDdXN0b20gRmxveWQtUml2ZXN0IHNlbGVjdGlvbiBhbGdvcml0aG06IHNvcnQgaWRzIGFuZCBjb29yZHMgc28gdGhhdFxuICogW2xlZnQuLmstMV0gaXRlbXMgYXJlIHNtYWxsZXIgdGhhbiBrLXRoIGl0ZW0gKG9uIGVpdGhlciB4IG9yIHkgYXhpcylcbiAqIEBwYXJhbSB7VWludDE2QXJyYXkgfCBVaW50MzJBcnJheX0gaWRzXG4gKiBAcGFyYW0ge0luc3RhbmNlVHlwZTxUeXBlZEFycmF5Q29uc3RydWN0b3I+fSBjb29yZHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBrXG4gKiBAcGFyYW0ge251bWJlcn0gbGVmdFxuICogQHBhcmFtIHtudW1iZXJ9IHJpZ2h0XG4gKiBAcGFyYW0ge251bWJlcn0gYXhpc1xuICovXG5mdW5jdGlvbiBzZWxlY3QoaWRzLCBjb29yZHMsIGssIGxlZnQsIHJpZ2h0LCBheGlzKSB7XG5cbiAgICB3aGlsZSAocmlnaHQgPiBsZWZ0KSB7XG4gICAgICAgIGlmIChyaWdodCAtIGxlZnQgPiA2MDApIHtcbiAgICAgICAgICAgIGNvbnN0IG4gPSByaWdodCAtIGxlZnQgKyAxO1xuICAgICAgICAgICAgY29uc3QgbSA9IGsgLSBsZWZ0ICsgMTtcbiAgICAgICAgICAgIGNvbnN0IHogPSBNYXRoLmxvZyhuKTtcbiAgICAgICAgICAgIGNvbnN0IHMgPSAwLjUgKiBNYXRoLmV4cCgyICogeiAvIDMpO1xuICAgICAgICAgICAgY29uc3Qgc2QgPSAwLjUgKiBNYXRoLnNxcnQoeiAqIHMgKiAobiAtIHMpIC8gbikgKiAobSAtIG4gLyAyIDwgMCA/IC0xIDogMSk7XG4gICAgICAgICAgICBjb25zdCBuZXdMZWZ0ID0gTWF0aC5tYXgobGVmdCwgTWF0aC5mbG9vcihrIC0gbSAqIHMgLyBuICsgc2QpKTtcbiAgICAgICAgICAgIGNvbnN0IG5ld1JpZ2h0ID0gTWF0aC5taW4ocmlnaHQsIE1hdGguZmxvb3IoayArIChuIC0gbSkgKiBzIC8gbiArIHNkKSk7XG4gICAgICAgICAgICBzZWxlY3QoaWRzLCBjb29yZHMsIGssIG5ld0xlZnQsIG5ld1JpZ2h0LCBheGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHQgPSBjb29yZHNbMiAqIGsgKyBheGlzXTtcbiAgICAgICAgbGV0IGkgPSBsZWZ0O1xuICAgICAgICBsZXQgaiA9IHJpZ2h0O1xuXG4gICAgICAgI
4084HN3YXBJdGVtKGlkcywgY29vcmRzLCBsZWZ0LCBrKTtcbiAgICAgICAgaWYgKGNvb3Jkc1syICogcmlnaHQgKyBheGlzXSA+IHQpIHN3YXBJdGVtKGlkcywgY29vcmRzLCBsZWZ0LCByaWdodCk7XG5cbiAgICAgICAgd2hpbGUgKGkgPCBqKSB7XG4gICAgICAgICAgICBzd2FwSXRlbShpZHMsIGNvb3JkcywgaSwgaik7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgICAgICBqLS07XG4gICAgICAgICAgICB3aGlsZSAoY29vcmRzWzIgKiBpICsgYXhpc10gPCB0KSBpKys7XG4gICAgICAgICAgICB3aGlsZSAoY29vcmRzWzIgKiBqICsgYXhpc10gPiB0KSBqLS07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29vcmRzWzIgKiBsZWZ0ICsgYXhpc10gPT09IHQpIHN3YXBJdGVtKGlkcywgY29vcmRzLCBsZWZ0LCBqKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBqKys7XG4gICAgICAgICAgICBzd2FwSXRlbShpZHMsIGNvb3JkcywgaiwgcmlnaHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGogPD0gaykgbGVmdCA9IGogKyAxO1xuICAgICAgICBpZiAoayA8PSBqKSByaWdodCA9IGogLSAxO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQxNkFycmF5IHwgVWludDMyQXJyYXl9IGlkc1xuICogQHBhcmFtIHtJbnN0YW5jZVR5cGU8VHlwZWRBcnJheUNvbnN0cnVjdG9yPn0gY29vcmRzXG4gKiBAcGFyYW0ge251bWJlcn0gaVxuICogQHBhcmFtIHtudW1iZXJ9IGpcbiAqL1xuZnVuY3Rpb24gc3dhcEl0ZW0oaWRzLCBjb29yZHMsIGksIGopIHtcbiAgICBzd2FwKGlkcywgaSwgaik7XG4gICAgc3dhcChjb29yZHMsIDIgKiBpLCAyICogaik7XG4gICAgc3dhcChjb29yZHMsIDIgKiBpICsgMSwgMiAqIGogKyAxKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0luc3RhbmNlVHlwZTxUeXBlZEFycmF5Q29uc3RydWN0b3I+fSBhcnJcbiAqIEBwYXJhbSB7bnVtYmVyfSBpXG4gKiBAcGFyYW0ge251bWJlcn0galxuICovXG5mdW5jdGlvbiBzd2FwKGFyciwgaSwgaikge1xuICAgIGNvbnN0IHRtcCA9IGFycltpXTtcbiAgICBhcnJbaV0gPSBhcnJbal07XG4gICAgYXJyW2pdID0gdG1wO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBheFxuICogQHBhcmFtIHtudW1iZXJ9IGF5XG4gKiBAcGFyYW0ge251bWJlcn0gYnhcbiAqIEBwYXJhbSB7bnVtYmVyfSBieVxuICovXG5mdW5jdGlvbiBzcURpc3QoYXgsIGF5LCBieCwgYnkpIHtcbiAgICBjb25zdCBkeCA9IGF4IC0gYng7XG4gICAgY29uc3QgZHkgPSBheSAtIGJ5O1xuICAgIHJldHVybiBkeCAqIGR4ICsgZHkgKiBkeTtcbn1cbiIsIlxuaW1wb3J0IEtEQnVzaCBmcm9tICdrZGJ1c2gnO1xuXG5jb25zdCBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICBtaW5ab29tOiAwLCAgIC8vIG1pbiB6b29tIHRvIGdlbmVyYXRlIGNsdXN0ZXJzIG9uXG4gICAgbWF4Wm9vbTogMTYsICAvLyBtYXggem9vbSBsZXZlbCB0byBjbHVzdGVyIHRoZSBwb2ludHMgb25cbiAgICBtaW5Qb2ludHM6IDIsIC8vIG1pbmltdW0gcG9pbnRzIHRvIGZvcm0gYSBjbHVzdGVyXG4gICAgcmFkaXVzOiA0MCwgICAvLyBjbHVzdGVyIHJhZGl1cyBpbiBwaXhlbHNcbiAgICBleHRlbnQ6IDUxMiwgIC8vIHRpbGUgZXh0ZW50IChyYWRpdXMgaXMgY2FsY3VsYXRlZCByZWxhdGl2ZSB0byBpdClcbiAgICBub2RlU2l6ZTogNjQsIC8vIHNpemUgb2YgdGhlIEtELXRyZWUgbGVhZiBub2RlLCBhZmZlY3RzIHBlcmZvcm1hbmNlXG4gICAgbG9nOiBmYWxzZSwgICAvLyB3aGV0aGVyIHRvIGxvZyB0aW1pbmcgaW5mb1xuXG4gICAgLy8gd2hldGhlciB0byBnZW5lcmF0ZSBudW1lcmljIGlkcyBmb3IgaW5wdXQgZmVhdHVyZXMgKGluIHZlY3RvciB0aWxlcylcbiAgICBnZW5lcmF0ZUlkOiBmYWxzZSxcblxuICAgIC8vIGEgcmVkdWNlIGZ1bmN0aW9uIGZvciBjYWxjdWxhdGluZyBjdXN0b20gY2x1c3RlciBwcm9wZXJ0aWVzXG4gICAgcmVkdWNlOiBudWxsLCAvLyAoYWNjdW11bGF0ZWQsIHByb3BzKSA9PiB7IGFjY3VtdWxhdGVkLnN1bSArPSBwcm9wcy5zdW07IH1cblxuICAgIC8vIHByb3BlcnRpZXMgdG8gdXNlIGZvciBpbmRpdmlkdWFsIHBvaW50cyB3aGVuIHJ1bm5pbmcgdGhlIHJlZHVjZXJcbiAgICBtYXA6IHByb3BzID0+IHByb3BzIC8vIHByb3BzID0+ICh7c3VtOiBwcm9wcy5teV92YWx1ZX0pXG59O1xuXG5jb25zdCBmcm91bmQgPSBNYXRoLmZyb3VuZCB8fCAodG1wID0+ICgoeCkgPT4geyB0bXBbMF0gPSAreDsgcmV0dXJuIHRtcFswXTsgfSkpKG5ldyBGbG9hdDMyQXJyYXkoMSkpO1xuXG5jb25zdCBPRkZTRVRfWk9PTSA9IDI7XG5jb25zdCBPRkZTRVRfSUQgPSAzO1xuY29uc3QgT0ZGU0VUX1BBUkVOVCA9IDQ7XG5jb25zdCBPRkZTRVRfTlVNID0gNTtcbmNvbnN0IE9GRlNFVF9QUk9QID0gNjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3VwZXJjbHVzdGVyIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmNyZWF0ZShkZWZhdWx0T3B0aW9ucyksIG9wdGlvbnMpO1xuICAgICAgICB0aGlzLnRyZWVzID0gbmV3IEFycmF5KHRoaXMub3B0aW9ucy5tYXhab29tICsgMSk7XG4gICAgICAgIHRoaXMuc3RyaWRlID0gdGhpcy5vcHRpb25zLnJlZHVjZSA/IDcgOiA2O1xuICAgICAgICB0aGlzLmNsdXN0ZXJQcm9wcyA9IFtdO1xuICAgIH1cblxuICAgIGxvYWQocG9pbnRzKSB7XG4gICAgICAgIGNvbnN0IHtsb2csIG1pblpvb20sIG1heFpvb219ID0gdGhpcy5vcHRpb25zO1xuXG4gICAgICAgIGlmIChsb2cpIGNvbnNvbGUudGltZSgndG90YWwgdGltZScpO1xuXG4gICAgICAgIGNvbnN0IHRpbWVySWQgPSBgcHJlcGFyZSAkeyAgcG9pbnRzLmxlbmd0aCAgfSBwb2ludHNgO1xuICAgICAgICBpZiAobG9nKSBjb25zb2xlLnRpbWUodGltZXJJZCk7XG5cbiAgICAgICAgdGhpcy5wb2ludHMgPSBwb2ludHM7XG5cbiAgICAgICAgLy8gZ2VuZXJhdGUgYSBjbHVzdGVyIG9iamVjdCBmb3IgZWFjaCBwb2ludCBhbmQgaW5kZXggaW5wdXQgcG9pbnRzIGludG8gYSBLRC10cmVlXG4gICAgICAgIGNvbnN0IGRhdGEgPSBbXTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgcCA9IHBvaW50c1tpXTtcbiAgICAgICAgICAgIGlmICghcC5nZW9tZXRyeSkgY29udGludWU7XG5cbiAgICAgICAgICAgIGNvbnN0IFtsbmcsIGxhdF0gPSBwLmdlb21ldHJ5LmNvb3JkaW5hdGVzO1
4084xuICAgICAgICAgICAgY29uc3QgeCA9IGZyb3VuZChsbmdYKGxuZykpO1xuICAgICAgICAgICAgY29uc3QgeSA9IGZyb3VuZChsYXRZKGxhdCkpO1xuICAgICAgICAgICAgLy8gc3RvcmUgaW50ZXJuYWwgcG9pbnQvY2x1c3RlciBkYXRhIGluIGZsYXQgbnVtZXJpYyBhcnJheXMgZm9yIHBlcmZvcm1hbmNlXG4gICAgICAgICAgICBkYXRhLnB1c2goXG4gICAgICAgICAgICAgICAgeCwgeSwgLy8gcHJvamVjdGVkIHBvaW50IGNvb3JkaW5hdGVzXG4gICAgICAgICAgICAgICAgSW5maW5pdHksIC8vIHRoZSBsYXN0IHpvb20gdGhlIHBvaW50IHdhcyBwcm9jZXNzZWQgYXRcbiAgICAgICAgICAgICAgICBpLCAvLyBpbmRleCBvZiB0aGUgc291cmNlIGZlYXR1cmUgaW4gdGhlIG9yaWdpbmFsIGlucHV0IGFycmF5XG4gICAgICAgICAgICAgICAgLTEsIC8vIHBhcmVudCBjbHVzdGVyIGlkXG4gICAgICAgICAgICAgICAgMSAvLyBudW1iZXIgb2YgcG9pbnRzIGluIGEgY2x1c3RlclxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMucmVkdWNlKSBkYXRhLnB1c2goMCk7IC8vIG5vb3BcbiAgICAgICAgfVxuICAgICAgICBsZXQgdHJlZSA9IHRoaXMudHJlZXNbbWF4Wm9vbSArIDFdID0gdGhpcy5fY3JlYXRlVHJlZShkYXRhKTtcblxuICAgICAgICBpZiAobG9nKSBjb25zb2xlLnRpbWVFbmQodGltZXJJZCk7XG5cbiAgICAgICAgLy8gY2x1c3RlciBwb2ludHMgb24gbWF4IHpvb20sIHRoZW4gY2x1c3RlciB0aGUgcmVzdWx0cyBvbiBwcmV2aW91cyB6b29tLCBldGMuO1xuICAgICAgICAvLyByZXN1bHRzIGluIGEgY2x1c3RlciBoaWVyYXJjaHkgYWNyb3NzIHpvb20gbGV2ZWxzXG4gICAgICAgIGZvciAobGV0IHogPSBtYXhab29tOyB6ID49IG1pblpvb207IHotLSkge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gK0RhdGUubm93KCk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhIG5ldyBzZXQgb2YgY2x1c3RlcnMgZm9yIHRoZSB6b29tIGFuZCBpbmRleCB0aGVtIHdpdGggYSBLRC10cmVlXG4gICAgICAgICAgICB0cmVlID0gdGhpcy50cmVlc1t6XSA9IHRoaXMuX2NyZWF0ZVRyZWUodGhpcy5fY2x1c3Rlcih0cmVlLCB6KSk7XG5cbiAgICAgICAgICAgIGlmIChsb2cpIGNvbnNvbGUubG9nKCd6JWQ6ICVkIGNsdXN0ZXJzIGluICVkbXMnLCB6LCB0cmVlLm51bUl0ZW1zLCArRGF0ZS5ub3coKSAtIG5vdyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobG9nKSBjb25zb2xlLnRpbWVFbmQoJ3RvdGFsIHRpbWUnKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBnZXRDbHVzdGVycyhiYm94LCB6b29tKSB7XG4gICAgICAgIGxldCBtaW5MbmcgPSAoKGJib3hbMF0gKyAxODApICUgMzYwICsgMzYwKSAlIDM2MCAtIDE4MDtcbiAgICAgICAgY29uc3QgbWluTGF0ID0gTWF0aC5tYXgoLTkwLCBNYXRoLm1pbig5MCwgYmJveFsxXSkpO1xuICAgICAgICBsZXQgbWF4TG5nID0gYmJveFsyXSA9PT0gMTgwID8gMTgwIDogKChiYm94WzJdICsgMTgwKSAlIDM2MCArIDM2MCkgJSAzNjAgLSAxODA7XG4gICAgICAgIGNvbnN0IG1heExhdCA9IE1hdGgubWF4KC05MCwgTWF0aC5taW4oOTAsIGJib3hbM10pKTtcblxuICAgICAgICBpZiAoYmJveFsyXSAtIGJib3hbMF0gPj0gMzYwKSB7XG4gICAgICAgICAgICBtaW5MbmcgPSAtMTgwO1xuICAgICAgICAgICAgbWF4TG5nID0gMTgwO1xuICAgICAgICB9IGVsc2UgaWYgKG1pbkxuZyA+IG1heExuZykge1xuICAgICAgICAgICAgY29uc3QgZWFzdGVybkhlbSA9IHRoaXMuZ2V0Q2x1c3RlcnMoW21pbkxuZywgbWluTGF0LCAxODAsIG1heExhdF0sIHpvb20pO1xuICAgICAgICAgICAgY29uc3Qgd2VzdGVybkhlbSA9IHRoaXMuZ2V0Q2x1c3RlcnMoWy0xODAsIG1pbkxhdCwgbWF4TG5nLCBtYXhMYXRdLCB6b29tKTtcbiAgICAgICAgICAgIHJldHVybiBlYXN0ZXJuSGVtLmNvbmNhdCh3ZXN0ZXJuSGVtKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRyZWUgPSB0aGlzLnRyZWVzW3RoaXMuX2xpbWl0Wm9vbSh6b29tKV07XG4gICAgICAgIGNvbnN0IGlkcyA9IHRyZWUucmFuZ2UobG5nWChtaW5MbmcpLCBsYXRZKG1heExhdCksIGxuZ1gobWF4TG5nKSwgbGF0WShtaW5MYXQpKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IHRyZWUuZGF0YTtcbiAgICAgICAgY29uc3QgY2x1c3RlcnMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpZCBvZiBpZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGsgPSB0aGlzLnN0cmlkZSAqIGlkO1xuICAgICAgICAgICAgY2x1c3RlcnMucHVzaChkYXRhW2sgKyBPRkZTRVRfTlVNXSA+IDEgPyBnZXRDbHVzdGVySlNPTihkYXRhLCBrLCB0aGlzLmNsdXN0ZXJQcm9wcykgOiB0aGlzLnBvaW50c1tkYXRhW2sgKyBPRkZTRVRfSURdXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNsdXN0ZXJzO1xuICAgIH1cblxuICAgIGdldENoaWxkcmVuKGNsdXN0ZXJJZCkge1xuICAgICAgICBjb25zdCBvcmlnaW5JZCA9IHRoaXMuX2dldE9yaWdpbklkKGNsdXN0ZXJJZCk7XG4gICAgICAgIGNvbnN0IG9yaWdpblpvb20gPSB0aGlzLl9nZXRPcmlnaW5ab29tKGNsdXN0ZXJJZCk7XG4gICAgICAgIGNvbnN0IGVycm9yTXNnID0gJ05vIGNsdXN0ZXIgd2l0aCB0aGUgc3BlY2lmaWVkIGlkLic7XG5cbiAgICAgICAgY29uc3QgdHJlZSA9IHRoaXMudHJlZXNbb3JpZ2luWm9vbV07XG4gICAgICAgIGlmICghdHJlZSkgdGhyb3cgbmV3IEVycm9yKGVycm9yTXNnKTtcblxuICAgICAgICBjb25zdCBkYXRhID0gdHJlZS5kYXRhO1xuICAgICAgICBpZiAob3JpZ2luSWQgKiB0aGlzLnN0cmlkZSA+PSBkYXRhLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKGVycm9yTXNnKTtcblxuICAgICAgICBjb25zdCByID0gdGhpcy5vcHRpb25zLnJhZGl1cyAvICh0aGlzLm9wdGlvbnMuZXh0ZW50ICogTWF0aC5wb3coMiwgb3JpZ2luWm9vbSAtIDEpKTtcbiAgICAgICAgY29uc3QgeCA9IGRhdGFbb3JpZ2luSWQgKiB0aGlzLnN0cmlkZV07XG4gICAgICAgIGNvbnN0IHkgPSBkYXRhW29yaWdpbklkICogdGhpcy5zdHJpZGUgKyAxXTtcbiAgICAgICAgY29uc3QgaWRzID0gdHJlZS53aXRoaW4oeCwgeSwgcik7XG4gICAgICAgIGNvbnN0IGNoaWxkcmVuID0gW107XG4gICAgICAgIGZvciAoY29uc3QgaWQgb2YgaWRzKSB7XG4gICAgICAgICAgICBjb25zdCBrID0gaWQgKiB0aGlzLnN0cmlkZTtcbiAgICAgICAgICAgIGlmIChkYXRhW2sgKyBPRkZTRVRfUEFSRU5UXSA9PT0gY2x1c3RlcklkKSB7XG4gICAgICAgICAgICAgICAgY2hpbGRyZW4ucHVzaChkYXRhW2sgKyBPRkZTRVRfTlVNXSA+IDEgPyBnZXRDbHVzdGVySlNPTihkYXRhLCBrLCB0aGlzLmNsdXN0ZXJQcm9wcykgOiB0aGlzLnBvaW50c1tkYXRhW2sgKyBPRkZTRVRfSURdXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgI
4084H1cblxuICAgICAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID09PSAwKSB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuXG4gICAgICAgIHJldHVybiBjaGlsZHJlbjtcbiAgICB9XG5cbiAgICBnZXRMZWF2ZXMoY2x1c3RlcklkLCBsaW1pdCwgb2Zmc2V0KSB7XG4gICAgICAgIGxpbWl0ID0gbGltaXQgfHwgMTA7XG4gICAgICAgIG9mZnNldCA9IG9mZnNldCB8fCAwO1xuXG4gICAgICAgIGNvbnN0IGxlYXZlcyA9IFtdO1xuICAgICAgICB0aGlzLl9hcHBlbmRMZWF2ZXMobGVhdmVzLCBjbHVzdGVySWQsIGxpbWl0LCBvZmZzZXQsIDApO1xuXG4gICAgICAgIHJldHVybiBsZWF2ZXM7XG4gICAgfVxuXG4gICAgZ2V0VGlsZSh6LCB4LCB5KSB7XG4gICAgICAgIGNvbnN0IHRyZWUgPSB0aGlzLnRyZWVzW3RoaXMuX2xpbWl0Wm9vbSh6KV07XG4gICAgICAgIGNvbnN0IHoyID0gTWF0aC5wb3coMiwgeik7XG4gICAgICAgIGNvbnN0IHtleHRlbnQsIHJhZGl1c30gPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IHAgPSByYWRpdXMgLyBleHRlbnQ7XG4gICAgICAgIGNvbnN0IHRvcCA9ICh5IC0gcCkgLyB6MjtcbiAgICAgICAgY29uc3QgYm90dG9tID0gKHkgKyAxICsgcCkgLyB6MjtcblxuICAgICAgICBjb25zdCB0aWxlID0ge1xuICAgICAgICAgICAgZmVhdHVyZXM6IFtdXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fYWRkVGlsZUZlYXR1cmVzKFxuICAgICAgICAgICAgdHJlZS5yYW5nZSgoeCAtIHApIC8gejIsIHRvcCwgKHggKyAxICsgcCkgLyB6MiwgYm90dG9tKSxcbiAgICAgICAgICAgIHRyZWUuZGF0YSwgeCwgeSwgejIsIHRpbGUpO1xuXG4gICAgICAgIGlmICh4ID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9hZGRUaWxlRmVhdHVyZXMoXG4gICAgICAgICAgICAgICAgdHJlZS5yYW5nZSgxIC0gcCAvIHoyLCB0b3AsIDEsIGJvdHRvbSksXG4gICAgICAgICAgICAgICAgdHJlZS5kYXRhLCB6MiwgeSwgejIsIHRpbGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh4ID09PSB6MiAtIDEpIHtcbiAgICAgICAgICAgIHRoaXMuX2FkZFRpbGVGZWF0dXJlcyhcbiAgICAgICAgICAgICAgICB0cmVlLnJhbmdlKDAsIHRvcCwgcCAvIHoyLCBib3R0b20pLFxuICAgICAgICAgICAgICAgIHRyZWUuZGF0YSwgLTEsIHksIHoyLCB0aWxlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aWxlLmZlYXR1cmVzLmxlbmd0aCA/IHRpbGUgOiBudWxsO1xuICAgIH1cblxuICAgIGdldENsdXN0ZXJFeHBhbnNpb25ab29tKGNsdXN0ZXJJZCkge1xuICAgICAgICBsZXQgZXhwYW5zaW9uWm9vbSA9IHRoaXMuX2dldE9yaWdpblpvb20oY2x1c3RlcklkKSAtIDE7XG4gICAgICAgIHdoaWxlIChleHBhbnNpb25ab29tIDw9IHRoaXMub3B0aW9ucy5tYXhab29tKSB7XG4gICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMuZ2V0Q2hpbGRyZW4oY2x1c3RlcklkKTtcbiAgICAgICAgICAgIGV4cGFuc2lvblpvb20rKztcbiAgICAgICAgICAgIGlmIChjaGlsZHJlbi5sZW5ndGggIT09IDEpIGJyZWFrO1xuICAgICAgICAgICAgY2x1c3RlcklkID0gY2hpbGRyZW5bMF0ucHJvcGVydGllcy5jbHVzdGVyX2lkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBleHBhbnNpb25ab29tO1xuICAgIH1cblxuICAgIF9hcHBlbmRMZWF2ZXMocmVzdWx0LCBjbHVzdGVySWQsIGxpbWl0LCBvZmZzZXQsIHNraXBwZWQpIHtcbiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSB0aGlzLmdldENoaWxkcmVuKGNsdXN0ZXJJZCk7XG5cbiAgICAgICAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikge1xuICAgICAgICAgICAgY29uc3QgcHJvcHMgPSBjaGlsZC5wcm9wZXJ0aWVzO1xuXG4gICAgICAgICAgICBpZiAocHJvcHMgJiYgcHJvcHMuY2x1c3Rlcikge1xuICAgICAgICAgICAgICAgIGlmIChza2lwcGVkICsgcHJvcHMucG9pbnRfY291bnQgPD0gb2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHNraXAgdGhlIHdob2xlIGNsdXN0ZXJcbiAgICAgICAgICAgICAgICAgICAgc2tpcHBlZCArPSBwcm9wcy5wb2ludF9jb3VudDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBlbnRlciB0aGUgY2x1c3RlclxuICAgICAgICAgICAgICAgICAgICBza2lwcGVkID0gdGhpcy5fYXBwZW5kTGVhdmVzKHJlc3VsdCwgcHJvcHMuY2x1c3Rlcl9pZCwgbGltaXQsIG9mZnNldCwgc2tpcHBlZCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIGV4aXQgdGhlIGNsdXN0ZXJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHNraXBwZWQgPCBvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAvLyBza2lwIGEgc2luZ2xlIHBvaW50XG4gICAgICAgICAgICAgICAgc2tpcHBlZCsrO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBhZGQgYSBzaW5nbGUgcG9pbnRcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChjaGlsZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aCA9PT0gbGltaXQpIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNraXBwZWQ7XG4gICAgfVxuXG4gICAgX2NyZWF0ZVRyZWUoZGF0YSkge1xuICAgICAgICBjb25zdCB0cmVlID0gbmV3IEtEQnVzaChkYXRhLmxlbmd0aCAvIHRoaXMuc3RyaWRlIHwgMCwgdGhpcy5vcHRpb25zLm5vZGVTaXplLCBGbG9hdDMyQXJyYXkpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpICs9IHRoaXMuc3RyaWRlKSB0cmVlLmFkZChkYXRhW2ldLCBkYXRhW2kgKyAxXSk7XG4gICAgICAgIHRyZWUuZmluaXNoKCk7XG4gICAgICAgIHRyZWUuZGF0YSA9IGRhdGE7XG4gICAgICAgIHJldHVybiB0cmVlO1xuICAgIH1cblxuICAgIF9hZGRUaWxlRmVhdHVyZXMoaWRzLCBkYXRhLCB4LCB5LCB6MiwgdGlsZSkge1xuICAgICAgICBmb3IgKGNvbnN0IGkgb2YgaWRzKSB7XG4gICAgICAgICAgICBjb25zdCBrID0gaSAqIHRoaXMuc3RyaWRlO1xuICAgICAgICAgICAgY29uc3QgaXNDbHVzdGVyID0gZGF0YVtrICsgT0ZGU0VUX05VTV0gPiAxO1xuXG4gICAgICAgICAgICBsZXQgdGFncywgcHgsIHB5O1xuICAgICAgICAgICAgaWYgKGlzQ2x1c3Rlcikge1xuICAgICAgICAgICAgICAgI
4084HRhZ3MgPSBnZXRDbHVzdGVyUHJvcGVydGllcyhkYXRhLCBrLCB0aGlzLmNsdXN0ZXJQcm9wcyk7XG4gICAgICAgICAgICAgICAgcHggPSBkYXRhW2tdO1xuICAgICAgICAgICAgICAgIHB5ID0gZGF0YVtrICsgMV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHAgPSB0aGlzLnBvaW50c1tkYXRhW2sgKyBPRkZTRVRfSURdXTtcbiAgICAgICAgICAgICAgICB0YWdzID0gcC5wcm9wZXJ0aWVzO1xuICAgICAgICAgICAgICAgIGNvbnN0IFtsbmcsIGxhdF0gPSBwLmdlb21ldHJ5LmNvb3JkaW5hdGVzO1xuICAgICAgICAgICAgICAgIHB4ID0gbG5nWChsbmcpO1xuICAgICAgICAgICAgICAgIHB5ID0gbGF0WShsYXQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBmID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6IDEsXG4gICAgICAgICAgICAgICAgZ2VvbWV0cnk6IFtbXG4gICAgICAgICAgICAgICAgICAgIE1hdGgucm91bmQodGhpcy5vcHRpb25zLmV4dGVudCAqIChweCAqIHoyIC0geCkpLFxuICAgICAgICAgICAgICAgICAgICBNYXRoLnJvdW5kKHRoaXMub3B0aW9ucy5leHRlbnQgKiAocHkgKiB6MiAtIHkpKVxuICAgICAgICAgICAgICAgIF1dLFxuICAgICAgICAgICAgICAgIHRhZ3NcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8vIGFzc2lnbiBpZFxuICAgICAgICAgICAgbGV0IGlkO1xuICAgICAgICAgICAgaWYgKGlzQ2x1c3RlciB8fCB0aGlzLm9wdGlvbnMuZ2VuZXJhdGVJZCkge1xuICAgICAgICAgICAgICAgIC8vIG9wdGlvbmFsbHkgZ2VuZXJhdGUgaWQgZm9yIHBvaW50c1xuICAgICAgICAgICAgICAgIGlkID0gZGF0YVtrICsgT0ZGU0VUX0lEXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8ga2VlcCBpZCBpZiBhbHJlYWR5IGFzc2lnbmVkXG4gICAgICAgICAgICAgICAgaWQgPSB0aGlzLnBvaW50c1tkYXRhW2sgKyBPRkZTRVRfSURdXS5pZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlkICE9PSB1bmRlZmluZWQpIGYuaWQgPSBpZDtcblxuICAgICAgICAgICAgdGlsZS5mZWF0dXJlcy5wdXNoKGYpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2xpbWl0Wm9vbSh6KSB7XG4gICAgICAgIHJldHVybiBNYXRoLm1heCh0aGlzLm9wdGlvbnMubWluWm9vbSwgTWF0aC5taW4oTWF0aC5mbG9vcigreiksIHRoaXMub3B0aW9ucy5tYXhab29tICsgMSkpO1xuICAgIH1cblxuICAgIF9jbHVzdGVyKHRyZWUsIHpvb20pIHtcbiAgICAgICAgY29uc3Qge3JhZGl1cywgZXh0ZW50LCByZWR1Y2UsIG1pblBvaW50c30gPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IHIgPSByYWRpdXMgLyAoZXh0ZW50ICogTWF0aC5wb3coMiwgem9vbSkpO1xuICAgICAgICBjb25zdCBkYXRhID0gdHJlZS5kYXRhO1xuICAgICAgICBjb25zdCBuZXh0RGF0YSA9IFtdO1xuICAgICAgICBjb25zdCBzdHJpZGUgPSB0aGlzLnN0cmlkZTtcblxuICAgICAgICAvLyBsb29wIHRocm91Z2ggZWFjaCBwb2ludFxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpICs9IHN0cmlkZSkge1xuICAgICAgICAgICAgLy8gaWYgd2UndmUgYWxyZWFkeSB2aXNpdGVkIHRoZSBwb2ludCBhdCB0aGlzIHpvb20gbGV2ZWwsIHNraXAgaXRcbiAgICAgICAgICAgIGlmIChkYXRhW2kgKyBPRkZTRVRfWk9PTV0gPD0gem9vbSkgY29udGludWU7XG4gICAgICAgICAgICBkYXRhW2kgKyBPRkZTRVRfWk9PTV0gPSB6b29tO1xuXG4gICAgICAgICAgICAvLyBmaW5kIGFsbCBuZWFyYnkgcG9pbnRzXG4gICAgICAgICAgICBjb25zdCB4ID0gZGF0YVtpXTtcbiAgICAgICAgICAgIGNvbnN0IHkgPSBkYXRhW2kgKyAxXTtcbiAgICAgICAgICAgIGNvbnN0IG5laWdoYm9ySWRzID0gdHJlZS53aXRoaW4oZGF0YVtpXSwgZGF0YVtpICsgMV0sIHIpO1xuXG4gICAgICAgICAgICBjb25zdCBudW1Qb2ludHNPcmlnaW4gPSBkYXRhW2kgKyBPRkZTRVRfTlVNXTtcbiAgICAgICAgICAgIGxldCBudW1Qb2ludHMgPSBudW1Qb2ludHNPcmlnaW47XG5cbiAgICAgICAgICAgIC8vIGNvdW50IHRoZSBudW1iZXIgb2YgcG9pbnRzIGluIGEgcG90ZW50aWFsIGNsdXN0ZXJcbiAgICAgICAgICAgIGZvciAoY29uc3QgbmVpZ2hib3JJZCBvZiBuZWlnaGJvcklkcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGsgPSBuZWlnaGJvcklkICogc3RyaWRlO1xuICAgICAgICAgICAgICAgIC8vIGZpbHRlciBvdXQgbmVpZ2hib3JzIHRoYXQgYXJlIGFscmVhZHkgcHJvY2Vzc2VkXG4gICAgICAgICAgICAgICAgaWYgKGRhdGFbayArIE9GRlNFVF9aT09NXSA+IHpvb20pIG51bVBvaW50cyArPSBkYXRhW2sgKyBPRkZTRVRfTlVNXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gaWYgdGhlcmUgd2VyZSBuZWlnaGJvcnMgdG8gbWVyZ2UsIGFuZCB0aGVyZSBhcmUgZW5vdWdoIHBvaW50cyB0byBmb3JtIGEgY2x1c3RlclxuICAgICAgICAgICAgaWYgKG51bVBvaW50cyA+IG51bVBvaW50c09yaWdpbiAmJiBudW1Qb2ludHMgPj0gbWluUG9pbnRzKSB7XG4gICAgICAgICAgICAgICAgbGV0IHd4ID0geCAqIG51bVBvaW50c09yaWdpbjtcbiAgICAgICAgICAgICAgICBsZXQgd3kgPSB5ICogbnVtUG9pbnRzT3JpZ2luO1xuXG4gICAgICAgICAgICAgICAgbGV0IGNsdXN0ZXJQcm9wZXJ0aWVzO1xuICAgICAgICAgICAgICAgIGxldCBjbHVzdGVyUHJvcEluZGV4ID0gLTE7XG5cbiAgICAgICAgICAgICAgICAvLyBlbmNvZGUgYm90aCB6b29tIGFuZCBwb2ludCBpbmRleCBvbiB3aGljaCB0aGUgY2x1c3RlciBvcmlnaW5hdGVkIC0tIG9mZnNldCBieSB0b3RhbCBsZW5ndGggb2YgZmVhdHVyZXNcbiAgICAgICAgICAgICAgICBjb25zdCBpZCA9ICgoaSAvIHN0cmlkZSB8IDApIDw8IDUpICsgKHpvb20gKyAxKSArIHRoaXMucG9pbnRzLmxlbmd0aDtcblxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgbmVpZ2hib3JJZCBvZiBuZWlnaGJvcklkcykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBrID0gbmVpZ2hib3JJZCAqIHN0cmlkZTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YVtrICsgT0ZGU0VUX1pPT01dIDw9IHpvb20pIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICBkYXRhW2sgKyBPRkZTRVRfWk9PTV0gPSB6b29tOyAvLyBzYXZlIHRoZSB6b29tIChzbyBpdCBkb2Vzbid0IGdldCBwcm9jZXNzZWQgdHdpY2UpXG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtUG9pbnRzMiA9IGRhdGFbayArIE9GRlNFVF9OVU1dO1xuICAgICAgICAgICAgICAgICAgICB3eCArPSBkYXRhW2tdICogbnVtUG9pbnRzMjsgLy8gYWNjdW11bGF0ZSBjb29yZGluYX
4084RlcyBmb3IgY2FsY3VsYXRpbmcgd2VpZ2h0ZWQgY2VudGVyXG4gICAgICAgICAgICAgICAgICAgIHd5ICs9IGRhdGFbayArIDFdICogbnVtUG9pbnRzMjtcblxuICAgICAgICAgICAgICAgICAgICBkYXRhW2sgKyBPRkZTRVRfUEFSRU5UXSA9IGlkO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZWR1Y2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2x1c3RlclByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbHVzdGVyUHJvcGVydGllcyA9IHRoaXMuX21hcChkYXRhLCBpLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbHVzdGVyUHJvcEluZGV4ID0gdGhpcy5jbHVzdGVyUHJvcHMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2x1c3RlclByb3BzLnB1c2goY2x1c3RlclByb3BlcnRpZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVkdWNlKGNsdXN0ZXJQcm9wZXJ0aWVzLCB0aGlzLl9tYXAoZGF0YSwgaykpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZGF0YVtpICsgT0ZGU0VUX1BBUkVOVF0gPSBpZDtcbiAgICAgICAgICAgICAgICBuZXh0RGF0YS5wdXNoKHd4IC8gbnVtUG9pbnRzLCB3eSAvIG51bVBvaW50cywgSW5maW5pdHksIGlkLCAtMSwgbnVtUG9pbnRzKTtcbiAgICAgICAgICAgICAgICBpZiAocmVkdWNlKSBuZXh0RGF0YS5wdXNoKGNsdXN0ZXJQcm9wSW5kZXgpO1xuXG4gICAgICAgICAgICB9IGVsc2UgeyAvLyBsZWZ0IHBvaW50cyBhcyB1bmNsdXN0ZXJlZFxuICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgc3RyaWRlOyBqKyspIG5leHREYXRhLnB1c2goZGF0YVtpICsgal0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKG51bVBvaW50cyA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBuZWlnaGJvcklkIG9mIG5laWdoYm9ySWRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBrID0gbmVpZ2hib3JJZCAqIHN0cmlkZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhW2sgKyBPRkZTRVRfWk9PTV0gPD0gem9vbSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhW2sgKyBPRkZTRVRfWk9PTV0gPSB6b29tO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBzdHJpZGU7IGorKykgbmV4dERhdGEucHVzaChkYXRhW2sgKyBqXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV4dERhdGE7XG4gICAgfVxuXG4gICAgLy8gZ2V0IGluZGV4IG9mIHRoZSBwb2ludCBmcm9tIHdoaWNoIHRoZSBjbHVzdGVyIG9yaWdpbmF0ZWRcbiAgICBfZ2V0T3JpZ2luSWQoY2x1c3RlcklkKSB7XG4gICAgICAgIHJldHVybiAoY2x1c3RlcklkIC0gdGhpcy5wb2ludHMubGVuZ3RoKSA+PiA1O1xuICAgIH1cblxuICAgIC8vIGdldCB6b29tIG9mIHRoZSBwb2ludCBmcm9tIHdoaWNoIHRoZSBjbHVzdGVyIG9yaWdpbmF0ZWRcbiAgICBfZ2V0T3JpZ2luWm9vbShjbHVzdGVySWQpIHtcbiAgICAgICAgcmV0dXJuIChjbHVzdGVySWQgLSB0aGlzLnBvaW50cy5sZW5ndGgpICUgMzI7XG4gICAgfVxuXG4gICAgX21hcChkYXRhLCBpLCBjbG9uZSkge1xuICAgICAgICBpZiAoZGF0YVtpICsgT0ZGU0VUX05VTV0gPiAxKSB7XG4gICAgICAgICAgICBjb25zdCBwcm9wcyA9IHRoaXMuY2x1c3RlclByb3BzW2RhdGFbaSArIE9GRlNFVF9QUk9QXV07XG4gICAgICAgICAgICByZXR1cm4gY2xvbmUgPyBPYmplY3QuYXNzaWduKHt9LCBwcm9wcykgOiBwcm9wcztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcmlnaW5hbCA9IHRoaXMucG9pbnRzW2RhdGFbaSArIE9GRlNFVF9JRF1dLnByb3BlcnRpZXM7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMub3B0aW9ucy5tYXAob3JpZ2luYWwpO1xuICAgICAgICByZXR1cm4gY2xvbmUgJiYgcmVzdWx0ID09PSBvcmlnaW5hbCA/IE9iamVjdC5hc3NpZ24oe30sIHJlc3VsdCkgOiByZXN1bHQ7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBnZXRDbHVzdGVySlNPTihkYXRhLCBpLCBjbHVzdGVyUHJvcHMpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnRmVhdHVyZScsXG4gICAgICAgIGlkOiBkYXRhW2kgKyBPRkZTRVRfSURdLFxuICAgICAgICBwcm9wZXJ0aWVzOiBnZXRDbHVzdGVyUHJvcGVydGllcyhkYXRhLCBpLCBjbHVzdGVyUHJvcHMpLFxuICAgICAgICBnZW9tZXRyeToge1xuICAgICAgICAgICAgdHlwZTogJ1BvaW50JyxcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzOiBbeExuZyhkYXRhW2ldKSwgeUxhdChkYXRhW2kgKyAxXSldXG4gICAgICAgIH1cbiAgICB9O1xufVxuXG5mdW5jdGlvbiBnZXRDbHVzdGVyUHJvcGVydGllcyhkYXRhLCBpLCBjbHVzdGVyUHJvcHMpIHtcbiAgICBjb25zdCBjb3VudCA9IGRhdGFbaSArIE9GRlNFVF9OVU1dO1xuICAgIGNvbnN0IGFiYnJldiA9XG4gICAgICAgIGNvdW50ID49IDEwMDAwID8gYCR7TWF0aC5yb3VuZChjb3VudCAvIDEwMDApICB9a2AgOlxuICAgICAgICBjb3VudCA+PSAxMDAwID8gYCR7TWF0aC5yb3VuZChjb3VudCAvIDEwMCkgLyAxMCAgfWtgIDogY291bnQ7XG4gICAgY29uc3QgcHJvcEluZGV4ID0gZGF0YVtpICsgT0ZGU0VUX1BST1BdO1xuICAgIGNvbnN0IHByb3BlcnRpZXMgPSBwcm9wSW5kZXggPT09IC0xID8ge30gOiBPYmplY3QuYXNzaWduKHt9LCBjbHVzdGVyUHJvcHNbcHJvcEluZGV4XSk7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24ocHJvcGVydGllcywge1xuICAgICAgICBjbHVzdGVyOiB0cnVlLFxuICAgICAgICBjbHVzdGVyX2lkOiBkYXRhW2kgKyBPRkZTRVRfSURdLFxuICAgICAgICBwb2ludF9jb3VudDogY291bnQsXG4gICAgICAgIHBvaW50X2NvdW50X2FiYnJldmlhdGVkOiBhYmJyZXZcbiAgICB9KTtcbn1cblxuLy8gbG9uZ2l0dWRlL2xhdGl0dWRlIHRvIHNwaGVyaWNhbCBtZXJjYXRvciBpbiBbMC4uMV0gcmFuZ2VcbmZ1bmN0aW9uIGxuZ1gobG5nKSB7XG4gICAgcmV0dXJuIGxuZyAvIDM2MCArIDAuNTtcbn1cbmZ1bmN0aW9uIGxhdFkobGF0KSB7XG4gICAgY29uc3Qgc2luID0gTWF0aC5zaW4obGF0ICogTWF0aC5QSSAvIDE4MCk7XG4gICAgY29uc3QgeSA9ICgwLjUgLSAwLjI1ICogTWF0aC5sb2coKDEgKyBzaW4pIC8gKDEgLSBzaW4pKSAvIE1hdGguUEkpO1xuICAgIHJldHVybi
4084B5IDwgMCA/IDAgOiB5ID4gMSA/IDEgOiB5O1xufVxuXG4vLyBzcGhlcmljYWwgbWVyY2F0b3IgdG8gbG9uZ2l0dWRlL2xhdGl0dWRlXG5mdW5jdGlvbiB4TG5nKHgpIHtcbiAgICByZXR1cm4gKHggLSAwLjUpICogMzYwO1xufVxuZnVuY3Rpb24geUxhdCh5KSB7XG4gICAgY29uc3QgeTIgPSAoMTgwIC0geSAqIDM2MCkgKiBNYXRoLlBJIC8gMTgwO1xuICAgIHJldHVybiAzNjAgKiBNYXRoLmF0YW4oTWF0aC5leHAoeTIpKSAvIE1hdGguUEkgLSA5MDtcbn1cbiIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0aWQ6IG1vZHVsZUlkLFxuXHRcdGxvYWRlZDogZmFsc2UsXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0obW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cblx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuXHRtb2R1bGUubG9hZGVkID0gdHJ1ZTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIi8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG5fX3dlYn
4084BhY2tfcmVxdWlyZV9fLm4gPSAobW9kdWxlKSA9PiB7XG5cdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuXHRcdCgpID0+IChtb2R1bGVbJ2RlZmF1bHQnXSkgOlxuXHRcdCgpID0+IChtb2R1bGUpO1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCB7IGE6IGdldHRlciB9KTtcblx0cmV0dXJuIGdldHRlcjtcbn07IiwiLy8gZGVmaW5lIGdldHRlciBmdW5jdGlvbnMgZm9yIGhhcm1vbnkgZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5kID0gKGV4cG9ydHMsIGRlZmluaXRpb24pID0+IHtcblx0Zm9yKHZhciBrZXkgaW4gZGVmaW5pdGlvbikge1xuXHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhkZWZpbml0aW9uLCBrZXkpICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywga2V5KSkge1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIGtleSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGRlZmluaXRpb25ba2V5XSB9KTtcblx0XHR9XG5cdH1cbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5vID0gKG9iaiwgcHJvcCkgPT4gKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSIsIi8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uciA9IChleHBvcnRzKSA9PiB7XG5cdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuXHR9XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG59OyIsIl9fd2VicGFja19yZXF1aXJlX18ubm1kID0gKG1vZHVsZSkgPT4ge1xuXHRtb2R1bGUucGF0aHMgPSBbXTtcblx0aWYgKCFtb2R1bGUuY2hpbGRyZW4pIG1vZHVsZS5jaGlsZHJlbiA9IFtdO1xuXHRyZXR1cm4gbW9kdWxlO1xufTsiLCJpbXBvcnQgZ29vZ2xlTWFwIGZyb20gJy4vZnVuY3Rpb25zL21hcCc7XG5cbmdvb2dsZU1hcCgpO1xuIl0sIm5hbWVzIjpbImlzVG91Y2hEZXZpY2UiLCJPQlNFUlZFUiIsImdldEJyb3dzZXJNYXhIZWlnaHQiLCJtYXBIZWFkZXJNb2JpbGUiLCJkb2N1bWVudCIsInF1ZXJ5U2VsZWN0b3IiLCJtYXBIZWFkZXJNb2JpbGVIZWlnaHQiLCJvZmZzZXRIZWlnaHQiLCJtYXhCcm93c2VySGVpZ2h0IiwiTWF0aCIsIm1heCIsImRvY3VtZW50RWxlbWVudCIsImNsaWVudEhlaWdodCIsIndpbmRvdyIsImlubmVySGVpZ2h0IiwidG91Y2hQb3NpdGlvbiIsImV2ZW50IiwidG91Y2hlcyIsIkJvdHRvbVNoZWV0IiwiX2NsYXNzQ2FsbENoZWNrIiwiX2NyZWF0ZUNsYXNzIiwia2V5IiwidmFsdWUiLCJpbml0Iiwic2hlZXRDb250ZW50cyIsImRyYWdnYWJsZUFyZWEiLCJzaGVldFNsaWRlRG93bkhlaWdodCIsInNoZWV0SGVpZ2h0IiwiZHJhZ1Bvc2l0aW9uIiwidW5kZWZpbmVkIiwiaXNPcGVuIiwiYWRkIiwibmFtZSIsImV2ZW50cyIsInRhcmdldHMiLCJvbkNsaWNrIiwiYmluZCIsIm9uRHJhZ1N0YXJ0Iiwib25EcmFnTW92ZSIsIm9uRHJhZ0VuZCIsImNsb3NlU2hlZXQiLCJvbiIsInNldFNoZWV0SGVpZ2h0Iiwic3R5bGUiLCJoZWlnaHQiLCJjb25jYXQiLCJjbGFzc0xpc3QiLCJyZW1vdmUiLCJvcGVuU2hlZXQiLCJvcGVuU2hlZXRNYXhIZWlnaHQiLCJjdXJyZW50VGFyZ2V0Iiwidmlld0FjdGl2ZSIsInNjcm9sbFRvcCIsInBhZ2VZIiwiY3Vyc29yIiwiYm9keSIsInkiLCJkZWx0YVkiLCJicm93c2VyTWF4SGVpZ2h0IiwiY3VycmVudEhlaWdodCIsInBhcnNlRmxvYXQiLCJuZXdIZWlnaHQiLCJ0aHJlc2hvbGQiLCJkZWZhdWx0IiwiTWFwVWkiLCJtYXAiLCJpbml0UXVpdEJ1dHRvbiIsInF1aXRNYXBJbmZvIiwiaG9zdCIsImxvY2F0aW9uIiwiaHJlZiIsInJlZmVycmVyIiwiYnV0dG9uc0JhY2tUb3BQcmV2aW91c1BhZ2UiLCJxdWVyeVNlbGVjdG9yQWxsIiwiZm9yRWFjaCIsImJvdXRvbiIsImFkZEV2ZW50TGlzdGVuZXIiLCJzcGxpdCIsImluaXRab29tQnV0dG9ucyIsIl90aGlzIiwiem9vbUJ1dHRvbkluIiwiem9vbUJ1dHRvbk91dCIsIkNVUlJFTlRfWk9PTSIsImdldFpvb20iLCJzZXRab29tIiwiaW5pdExheWVyc0J1dHRvbiIsIl90aGlzMiIsImxheWVyc0lubmVyIiwid2lkdGgiLCJvZmZzZXRXaWR0aCIsImJ1dHRvbnMiLCJidXR0b24iLCJlIiwic2V0TWFwVHlwZUlkIiwiZGF0YXNldCIsImxheWVyIiwiaXRlbSIsImxvY2FsU3RvcmFnZSIsInNldEl0ZW0iLCJwYXJlbnRFbGVtZW50IiwidG9nZ2xlIiwiZ2V0SXRlbSIsImluaXRJbmZvUG9wdXAiLCJpbmZvSW5uZXIiLCJpbmZvQnV0dG9uIiwiY2xvc2VJbmZvQnV0dG9uIiwiY2hlY2tTaGFyZU92ZXJsYXkiLCJzZXRUaW1lb3V0Iiwib3ZlcmxheVNoYXJlIiwiY29uc29sZSIsIndhcm4iLCJodW5kcmVkVkgiLCJzZXRIZWlnaHQiLCJ2aCIsInNldFByb3BlcnR5IiwiTWFya2VyQ2x1c3RlcmVyIiwiSFRNTE1hcmtlciIsImluaXRNYXJrZXIiLCJIVE1MTG9jYXRpb25NYXJrZXIiLCJpbml0TG9jYXRpb25NYXJrZXIiLCJIVE1MTWFya2VyQ2x1c3RlciIsImNoYW5nZUNhdGVnb3J5IiwiY2hhbmdlU3ViY2F0ZWdvcnkiLCJzZWxlY3RMb2NhdGlvbiIsInJldHVyblRvUm9vdCIsInJldHVyblRvU3ViY2F0ZWdvcmllcyIsInJldHVybkZyb21Mb2NhdGlvbkRldGFpbCIsImxvY2F0aW9uQ2xpY2siLCJwb3B1cENsaWNrIiwiY2xvc2VQb3B1cENsaWNrIiwibWFuYWdlQmFja0J1dHRvbiIsImhhc0dlb2xvY2F0aW9uIiwiaXNJblpvbmUiLCJlbmFibGVSZXNldEJ1dHRvbnMiLCJtYXBTdHlsZSIsIk1hcFVybCIsImlzQ2xvc2luZyIsInVybE1hbmFnZXIiLCJib3R0b21TaGVldCIsIm1hcFVpIiwibWFwQm91bmRzIiwibm9ydGgiLCJtYXBDb25maWciLCJjZW50ZXJfbGF0IiwiYm91bmRzX2xpbWl0Iiwic291dGgiLCJ3ZXN0IiwiY2VudGVyX2xuZyIsImVhc3QiLCJpbml0TWFwIiwiZ29vZ2xlIiwibWFwcyIsIk1hcCIsInpvb20iLCJjZW50ZXIiLCJsYXQiLCJsbmciLCJ
4084jbGlja2FibGVJY29ucyIsInN0eWxlcyIsImRpc2FibGVEZWZhdWx0VUkiLCJnZXN0dXJlSGFuZGxpbmciLCJtaW5ab29tIiwiem9vbV9taW4iLCJtYXhab29tIiwiem9vbV9tYXgiLCJyZXN0cmljdGlvbiIsImxhdExuZ0JvdW5kcyIsInN0cmljdEJvdW5kcyIsIm1hcmtlckNsdXN0ZXJlciIsInJlbmRlcmVyIiwicmVuZGVyIiwiX3JlZiIsImNvdW50IiwicG9zaXRpb24iLCJib3VuZHMiLCJsYXRsbmciLCJ1cGRhdGVNYXJrZXJzIiwiZGF0YSIsInBvaXMiLCJwb2kiLCJtYXJrZXJQb3MiLCJodG1sTWFya2VyIiwiaWQiLCJzbHVnIiwia21sVXJsIiwia21sIiwiY2F0ZWdvcmllc1NsdWciLCJhY2Nlc3NpYmlsaXR5IiwidGl0bGUiLCJjYXRlZ29yeSIsImltYWdlIiwibG9hZE1hcmtlcnMiLCJ4aHIiLCJYTUxIdHRwUmVxdWVzdCIsIm9wZW4iLCJvbmxvYWQiLCJvbkxvYWQiLCJzdGF0dXMiLCJKU09OIiwicGFyc2UiLCJyZXNwb25zZVRleHQiLCJzaG93QWxsIiwiZ2V0U2x1Z0NhdGVnb3J5IiwiZ2V0U2x1Z1N1YmNhdGVnb3J5IiwiZ2V0U2x1Z0xvY2FsaXNhdGlvbiIsInNob3dDYXRlZ29yeSIsInNob3dVbmlxdWUiLCJyZWZyZXNoQ2x1c3RlcmVyIiwiZml0Qm91bmRzIiwiZXJyb3IiLCJzZW5kIiwiZ29vZ2xlTWFwIiwic2x1Z0xvY2FsaXNhdGlvbiIsIm5hdmlnYXRvciIsImdlb2xvY2F0aW9uIiwiZ2V0Q3VycmVudFBvc2l0aW9uIiwiY29vcmRzIiwibGF0aXR1ZGUiLCJsb25naXR1ZGUiLCJjZW50ZXJCdG5Db250YWluZXIiLCJjZW50ZXJCdG4iLCJkaXNhYmxlZCIsImh0bWxMb2NhdGlvbk1hcmtlciIsInBhblRvIiwiTGF0TG5nIiwiYXJncyIsInBvcyIsImRpdiIsImNyZWF0ZUVsZW1lbnQiLCJzZXRBdHRyaWJ1dGUiLCJnZW9sb2NhdGlvbl9sYWJlbCIsImlubmVySFRNTCIsInNldE1hcCIsImFkZERvbUxpc3RlbmVyIiwicHJvdG90eXBlIiwiT3ZlcmxheVZpZXciLCJvbkFkZCIsInBhbmVzIiwiZ2V0UGFuZXMiLCJvdmVybGF5SW1hZ2UiLCJhcHBlbmRDaGlsZCIsInBhcmVudE5vZGUiLCJyZW1vdmVDaGlsZCIsImRyYXciLCJvdmVybGF5UHJvamVjdGlvbiIsImdldFByb2plY3Rpb24iLCJmcm9tTGF0TG5nVG9EaXZQaXhlbCIsImxlZnQiLCJ4IiwidG9wIiwib25SZW1vdmUiLCJhY3RpdmF0ZVBhbmVsVmlldyIsImRpc2FibGVSZXNldEJ1dHRvbnMiLCJzZXRTbHVnQ2F0ZWdvcnkiLCJzZXRTbHVnU3ViQ2F0ZWdvcnkiLCJkaXNhYmxlQWxsIiwic2V0U2x1Z0xvY2FsaXNhdGlvbiIsInJlc2V0U2x1ZyIsImhpZGVBbGxQb3B1cCIsInJlc2V0U3ViY2F0ZWdvcnkiLCJyZXNldExvY2F0aW9uIiwidG9nZ2xlUG9wdXAiLCJjbGljayIsImttbExheWVyIiwia21sQm91bmRzTkUiLCJrbWxCb3VuZHNTVyIsInZpc2libGVPbk1hcCIsImFjdGl2ZSIsInZpc2libGVQb3B1cCIsIm1hcmtlckxpc3QiLCJwdXNoIiwia21sTWFya2VyTGlzdCIsIkttbExheWVyIiwidXJsIiwic3VwcHJlc3NJbmZvV2luZG93cyIsInByZXNlcnZlVmlld3BvcnQiLCJjdXJlbnRNYXJrZXIiLCJhZGRMaXN0ZW5lciIsImRlZmF1bHRWaWV3cG9ydENoYW5nZWQiLCJnZXREZWZhdWx0Vmlld3BvcnQiLCJnZXROb3J0aEVhc3QiLCJnZXRTb3V0aFdlc3QiLCJnZXRDZW50ZXIiLCJzaG93IiwiaXNPblJvb3QiLCJoaWRlIiwic2hvd1BvcHVwIiwiaGlkZVBvcHVwIiwiYWN0aXZhdGUiLCJkaXNhYmxlIiwiZ2V0VmlzaWJsZSIsInNldFBvc2l0aW9uIiwic2V0IiwiZ2V0UG9zaXRpb24iLCJwb3B1cEhUTUwiLCJtYXJrZXJTbHVnIiwibWFya2VyIiwiZ2V0QnlTbHVnIiwiaSIsImxlbmd0aCIsImhpZGVBbGwiLCJhcmd1bWVudHMiLCJ
4084jYXRlZ29yeVNsdWciLCJpbmNsdWRlcyIsImZpbHRlcmVkUG9pcyIsImVsZW1lbnQiLCJjbGVhck1hcmtlcnMiLCJhZGRNYXJrZXJzIiwiTGF0TG5nQm91bmRzIiwibWFya2VycyIsImV4dGVuZCIsImdldE1hcCIsImh0bWxNYXJrZXJDbHVzdGVyIiwicG9pbnQiLCJjbGFzc05hbWUiLCJkZWFjdGl2YXRlUGFuZWxWaWV3IiwiU0lERUJBUiIsIlZJRVdTIiwicmVtb3ZlQXR0cmlidXRlIiwidmlldyIsImRpc3BhdGNoRXZlbnQiLCJFdmVudCIsIlZJRVciLCJCVVRUT05TIiwiZmVhdHVyZVR5cGUiLCJlbGVtZW50VHlwZSIsInN0eWxlcnMiLCJ2aXNpYmlsaXR5IiwiY29sb3IiLCJjb2xvcl9iYWNrZ3JvdW5kIiwiY29sb3JfcGFya3MiLCJzYXR1cmF0aW9uIiwibGlnaHRuZXNzIiwiY29sb3Jfd2F0ZXIiLCJzbHVnQ2F0ZWdvcnkiLCJzbHVnU3ViQ2F0ZWdvcnkiLCJ1cGRhdGVVcmwiLCJjdXJyZW50VVJMIiwiVVJMIiwidXJsUGF0aCIsInBhdGhuYW1lIiwidXJsUGF0aFBhcnRzIiwic2hpZnQiLCJuZXdVcmxQYXRoIiwibWFwU2VjdGlvbiIsImZpbHRlciIsIkJvb2xlYW4iLCJqb2luIiwibmV3VXJsIiwiaXNfbXVsdGlsaW5ndWFsIiwiaGlzdG9yeSIsInB1c2hTdGF0ZSIsInBhcnNlVXJsIiwiX3VybFBhdGhQYXJ0cyIsIl9zbGljZWRUb0FycmF5IiwibWF4VG91Y2hQb2ludHMiLCJtc01heFRvdWNoUG9pbnRzIiwiem9uZSIsInJlc3VsdCIsIk9ic2VydmVyIiwiZ2V0SW5zdGFuY2UiLCJ0IiwiZXhwb3J0cyIsIl90eXBlb2YiLCJtb2R1bGUiLCJkZWZpbmUiLCJhbWQiLCJzZWxmIiwiXyIsInMiLCJkIiwibiIsImhhc093blByb3BlcnR5IiwiZXZlbnRMaXN0IiwiZ2V0IiwidGhyb3dNZXNzYWdlIiwibWFuYWdlTGlzdGVuZXJzIiwiciIsIm8iLCJtYW5hZ2VUYXJnZXRzIiwiX3RvQ29uc3VtYWJsZUFycmF5IiwiTm9kZUxpc3QiLCJIVE1MRWxlbWVudCIsIm1hbmFnZUV2ZW50cyIsIm9mZiIsImFsbE9uIiwiX3RoaXMzIiwiYWxsT2ZmIiwiX3RoaXM0IiwicmVmcmVzaCIsInJlZnJlc2hBbGwiLCJldmVudHNDb3VudCIsInRhcmdldHNDb3VudCIsIl90aGlzNSIsInJlbW92ZUFsbCIsIl90aGlzNiIsImluc3RhbmNlIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJlbnVtZXJhYmxlIiwiY2FsbCJdLCJzb3VyY2VSb290IjoiIn0=
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.