From 64da64d0daacd8ec10fde5da4741f5be32c9f9a6 Mon Sep 17 00:00:00 2001 From: cx20 Date: Fri, 22 Nov 2024 07:01:13 +0900 Subject: [PATCH] Update Babylon.js v7.31.0 to v7.35.0 --- examples/babylonjs/index.html | 10 +- .../7.35.0/babylon.glTF2FileLoader.js | 9221 ++++++++++ .../7.35.0/babylon.glTF2FileLoader.min.js | 2 + .../7.35.0/babylon.glTF2Serializer.js | 6474 +++++++ .../7.35.0/babylon.glTF2Serializer.min.js | 2 + .../7.35.0/babylon.glTFFileLoader.js | 11768 +++++++++++++ .../7.35.0/babylon.glTFFileLoader.min.js | 2 + .../7.35.0/babylon.inspector.bundle.js | 3 + libs/babylonjs/7.35.0/babylon.js | 2 + .../babylonjs/7.35.0/babylon.stlSerializer.js | 332 + .../7.35.0/babylon.stlSerializer.min.js | 2 + libs/babylonjs/7.35.0/babylonjs.loaders.js | 14157 ++++++++++++++++ .../babylonjs/7.35.0/babylonjs.loaders.min.js | 2 + .../babylonjs/7.35.0/babylonjs.serializers.js | 7543 ++++++++ .../7.35.0/babylonjs.serializers.min.js | 2 + libs/babylonjs/7.35.0/draco.license | 201 + libs/babylonjs/7.35.0/draco_decoder.js | 36 + libs/babylonjs/7.35.0/draco_decoder.wasm | Bin 0 -> 285747 bytes libs/babylonjs/7.35.0/draco_decoder_gltf.js | 35 + libs/babylonjs/7.35.0/draco_decoder_gltf.wasm | Bin 0 -> 192420 bytes libs/babylonjs/7.35.0/draco_wasm_wrapper.js | 117 + .../7.35.0/draco_wasm_wrapper_gltf.js | 116 + libs/babylonjs/7.35.0/gltf_validator.js | 13352 +++++++++++++++ 23 files changed, 63374 insertions(+), 5 deletions(-) create mode 100644 libs/babylonjs/7.35.0/babylon.glTF2FileLoader.js create mode 100644 libs/babylonjs/7.35.0/babylon.glTF2FileLoader.min.js create mode 100644 libs/babylonjs/7.35.0/babylon.glTF2Serializer.js create mode 100644 libs/babylonjs/7.35.0/babylon.glTF2Serializer.min.js create mode 100644 libs/babylonjs/7.35.0/babylon.glTFFileLoader.js create mode 100644 libs/babylonjs/7.35.0/babylon.glTFFileLoader.min.js create mode 100644 libs/babylonjs/7.35.0/babylon.inspector.bundle.js create mode 100644 libs/babylonjs/7.35.0/babylon.js create mode 100644 libs/babylonjs/7.35.0/babylon.stlSerializer.js create mode 100644 libs/babylonjs/7.35.0/babylon.stlSerializer.min.js create mode 100644 libs/babylonjs/7.35.0/babylonjs.loaders.js create mode 100644 libs/babylonjs/7.35.0/babylonjs.loaders.min.js create mode 100644 libs/babylonjs/7.35.0/babylonjs.serializers.js create mode 100644 libs/babylonjs/7.35.0/babylonjs.serializers.min.js create mode 100644 libs/babylonjs/7.35.0/draco.license create mode 100644 libs/babylonjs/7.35.0/draco_decoder.js create mode 100644 libs/babylonjs/7.35.0/draco_decoder.wasm create mode 100644 libs/babylonjs/7.35.0/draco_decoder_gltf.js create mode 100644 libs/babylonjs/7.35.0/draco_decoder_gltf.wasm create mode 100644 libs/babylonjs/7.35.0/draco_wasm_wrapper.js create mode 100644 libs/babylonjs/7.35.0/draco_wasm_wrapper_gltf.js create mode 100644 libs/babylonjs/7.35.0/gltf_validator.js diff --git a/examples/babylonjs/index.html b/examples/babylonjs/index.html index 2063525f..aa31c284 100644 --- a/examples/babylonjs/index.html +++ b/examples/babylonjs/index.html @@ -14,15 +14,15 @@ - - + + - + - + - + diff --git a/libs/babylonjs/7.35.0/babylon.glTF2FileLoader.js b/libs/babylonjs/7.35.0/babylon.glTF2FileLoader.js new file mode 100644 index 00000000..70b0d843 --- /dev/null +++ b/libs/babylonjs/7.35.0/babylon.glTF2FileLoader.js @@ -0,0 +1,9221 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("babylonjs")); + else if(typeof define === 'function' && define.amd) + define("babylonjs-loaders", ["babylonjs"], factory); + else if(typeof exports === 'object') + exports["babylonjs-loaders"] = factory(require("babylonjs")); + else + root["LOADERS"] = factory(root["BABYLON"]); +})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), (__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_tools__) => { +return /******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_lights_image_based.ts": +/*!******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/EXT_lights_image_based.ts ***! + \******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_lights_image_based: () => (/* binding */ EXT_lights_image_based) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Textures/rawCubeTexture */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + +var NAME = "EXT_lights_image_based"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_lights_image_based/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var EXT_lights_image_based = /** @class */ (function () { + /** + * @internal + */ + function EXT_lights_image_based(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + EXT_lights_image_based.prototype.dispose = function () { + this._loader = null; + delete this._lights; + }; + /** @internal */ + EXT_lights_image_based.prototype.onLoading = function () { + var extensions = this._loader.gltf.extensions; + if (extensions && extensions[this.name]) { + var extension = extensions[this.name]; + this._lights = extension.lights; + } + }; + /** + * @internal + */ + EXT_lights_image_based.prototype.loadSceneAsync = function (context, scene) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, scene, this.name, function (extensionContext, extension) { + _this._loader._allMaterialsDirtyRequired = true; + var promises = new Array(); + promises.push(_this._loader.loadSceneAsync(context, scene)); + _this._loader.logOpen("".concat(extensionContext)); + var light = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("".concat(extensionContext, "/light"), _this._lights, extension.light); + promises.push(_this._loadLightAsync("/extensions/".concat(_this.name, "/lights/").concat(extension.light), light).then(function (texture) { + _this._loader.babylonScene.environmentTexture = texture; + })); + _this._loader.logClose(); + return Promise.all(promises).then(function () { }); + }); + }; + EXT_lights_image_based.prototype._loadLightAsync = function (context, light) { + var _this = this; + if (!light._loaded) { + var promises = new Array(); + this._loader.logOpen("".concat(context)); + var imageData_1 = new Array(light.specularImages.length); + var _loop_1 = function (mipmap) { + var faces = light.specularImages[mipmap]; + imageData_1[mipmap] = new Array(faces.length); + var _loop_2 = function (face) { + var specularImageContext = "".concat(context, "/specularImages/").concat(mipmap, "/").concat(face); + this_1._loader.logOpen("".concat(specularImageContext)); + var index = faces[face]; + var image = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get(specularImageContext, this_1._loader.gltf.images, index); + promises.push(this_1._loader.loadImageAsync("/images/".concat(index), image).then(function (data) { + imageData_1[mipmap][face] = data; + })); + this_1._loader.logClose(); + }; + for (var face = 0; face < faces.length; face++) { + _loop_2(face); + } + }; + var this_1 = this; + for (var mipmap = 0; mipmap < light.specularImages.length; mipmap++) { + _loop_1(mipmap); + } + this._loader.logClose(); + light._loaded = Promise.all(promises).then(function () { + var babylonTexture = new babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__.RawCubeTexture(_this._loader.babylonScene, null, light.specularImageSize); + babylonTexture.name = light.name || "environment"; + light._babylonTexture = babylonTexture; + if (light.intensity != undefined) { + babylonTexture.level = light.intensity; + } + if (light.rotation) { + var rotation = babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArray(light.rotation); + // Invert the rotation so that positive rotation is counter-clockwise. + if (!_this._loader.babylonScene.useRightHandedSystem) { + rotation = babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Inverse(rotation); + } + babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__.Matrix.FromQuaternionToRef(rotation, babylonTexture.getReflectionTextureMatrix()); + } + if (!light.irradianceCoefficients) { + throw new Error("".concat(context, ": Irradiance coefficients are missing")); + } + var sphericalHarmonics = babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__.SphericalHarmonics.FromArray(light.irradianceCoefficients); + sphericalHarmonics.scaleInPlace(light.intensity); + sphericalHarmonics.convertIrradianceToLambertianRadiance(); + var sphericalPolynomial = babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__.SphericalPolynomial.FromHarmonics(sphericalHarmonics); + // Compute the lod generation scale to fit exactly to the number of levels available. + var lodGenerationScale = (imageData_1.length - 1) / Math.log2(light.specularImageSize); + return babylonTexture.updateRGBDAsync(imageData_1, sphericalPolynomial, lodGenerationScale); + }); + } + return light._loaded.then(function () { + return light._babylonTexture; + }); + }; + return EXT_lights_image_based; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new EXT_lights_image_based(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts": +/*!*******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_mesh_gpu_instancing: () => (/* binding */ EXT_mesh_gpu_instancing) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Meshes/thinInstanceMesh */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "EXT_mesh_gpu_instancing"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_mesh_gpu_instancing/README.md) + * [Playground Sample](https://playground.babylonjs.com/#QFIGLW#9) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var EXT_mesh_gpu_instancing = /** @class */ (function () { + /** + * @internal + */ + function EXT_mesh_gpu_instancing(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + EXT_mesh_gpu_instancing.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + EXT_mesh_gpu_instancing.prototype.loadNodeAsync = function (context, node, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) { + _this._loader._disableInstancedMesh++; + var promise = _this._loader.loadNodeAsync("/nodes/".concat(node.index), node, assign); + _this._loader._disableInstancedMesh--; + if (!node._primitiveBabylonMeshes) { + return promise; + } + var promises = new Array(); + var instanceCount = 0; + var loadAttribute = function (attribute) { + if (extension.attributes[attribute] == undefined) { + promises.push(Promise.resolve(null)); + return; + } + var accessor = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("".concat(extensionContext, "/attributes/").concat(attribute), _this._loader.gltf.accessors, extension.attributes[attribute]); + promises.push(_this._loader._loadFloatAccessorAsync("/accessors/".concat(accessor.bufferView), accessor)); + if (instanceCount === 0) { + instanceCount = accessor.count; + } + else if (instanceCount !== accessor.count) { + throw new Error("".concat(extensionContext, "/attributes: Instance buffer accessors do not have the same count.")); + } + }; + loadAttribute("TRANSLATION"); + loadAttribute("ROTATION"); + loadAttribute("SCALE"); + return promise.then(function (babylonTransformNode) { + return Promise.all(promises).then(function (_a) { + var translationBuffer = _a[0], rotationBuffer = _a[1], scaleBuffer = _a[2]; + var matrices = new Float32Array(instanceCount * 16); + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[0].copyFromFloats(0, 0, 0); // translation + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Quaternion[0].copyFromFloats(0, 0, 0, 1); // rotation + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[1].copyFromFloats(1, 1, 1); // scale + for (var i = 0; i < instanceCount; ++i) { + translationBuffer && babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArrayToRef(translationBuffer, i * 3, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[0]); + rotationBuffer && babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArrayToRef(rotationBuffer, i * 4, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Quaternion[0]); + scaleBuffer && babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArrayToRef(scaleBuffer, i * 3, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[1]); + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Matrix.ComposeToRef(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[1], babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Quaternion[0], babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[0], babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Matrix[0]); + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Matrix[0].copyToArray(matrices, i * 16); + } + for (var _i = 0, _b = node._primitiveBabylonMeshes; _i < _b.length; _i++) { + var babylonMesh = _b[_i]; + babylonMesh.thinInstanceSetBuffer("matrix", matrices, 16, true); + } + return babylonTransformNode; + }); + }); + }); + }; + return EXT_mesh_gpu_instancing; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new EXT_mesh_gpu_instancing(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_meshopt_compression.ts": +/*!*******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/EXT_meshopt_compression.ts ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_meshopt_compression: () => (/* binding */ EXT_meshopt_compression) +/* harmony export */ }); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var babylonjs_Meshes_Compression_meshoptCompression__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/Compression/meshoptCompression */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Meshes_Compression_meshoptCompression__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_Compression_meshoptCompression__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "EXT_meshopt_compression"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_meshopt_compression/README.md) + * + * This extension uses a WebAssembly decoder module from https://github.com/zeux/meshoptimizer/tree/master/js + * @since 5.0.0 + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var EXT_meshopt_compression = /** @class */ (function () { + /** + * @internal + */ + function EXT_meshopt_compression(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this.enabled = loader.isExtensionUsed(NAME); + this._loader = loader; + } + /** @internal */ + EXT_meshopt_compression.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + EXT_meshopt_compression.prototype.loadBufferViewAsync = function (context, bufferView) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.LoadExtensionAsync(context, bufferView, this.name, function (extensionContext, extension) { + var bufferViewMeshopt = bufferView; + if (bufferViewMeshopt._meshOptData) { + return bufferViewMeshopt._meshOptData; + } + var buffer = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(context, "/buffer"), _this._loader.gltf.buffers, extension.buffer); + bufferViewMeshopt._meshOptData = _this._loader.loadBufferAsync("/buffers/".concat(buffer.index), buffer, extension.byteOffset || 0, extension.byteLength).then(function (buffer) { + return babylonjs_Meshes_Compression_meshoptCompression__WEBPACK_IMPORTED_MODULE_1__.MeshoptCompression.Default.decodeGltfBufferAsync(buffer, extension.count, extension.byteStride, extension.mode, extension.filter); + }); + return bufferViewMeshopt._meshOptData; + }); + }; + return EXT_meshopt_compression; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new EXT_meshopt_compression(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_texture_avif.ts": +/*!************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/EXT_texture_avif.ts ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_texture_avif: () => (/* binding */ EXT_texture_avif) +/* harmony export */ }); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + +var NAME = "EXT_texture_avif"; +/** + * [glTF PR](https://github.com/KhronosGroup/glTF/pull/2235) + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_texture_avif/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var EXT_texture_avif = /** @class */ (function () { + /** + * @internal + */ + function EXT_texture_avif(loader) { + /** The name of this extension. */ + this.name = NAME; + this._loader = loader; + this.enabled = loader.isExtensionUsed(NAME); + } + /** @internal */ + EXT_texture_avif.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + EXT_texture_avif.prototype._loadTextureAsync = function (context, texture, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.LoadExtensionAsync(context, texture, this.name, function (extensionContext, extension) { + var sampler = texture.sampler == undefined ? _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.DefaultSampler : _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(context, "/sampler"), _this._loader.gltf.samplers, texture.sampler); + var image = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(extensionContext, "/source"), _this._loader.gltf.images, extension.source); + return _this._loader._createTextureAsync(context, sampler, image, function (babylonTexture) { + assign(babylonTexture); + }, undefined, !texture._textureInfo.nonColorData); + }); + }; + return EXT_texture_avif; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__.registerGLTFExtension)(NAME, true, function (loader) { return new EXT_texture_avif(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_texture_webp.ts": +/*!************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/EXT_texture_webp.ts ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_texture_webp: () => (/* binding */ EXT_texture_webp) +/* harmony export */ }); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + +var NAME = "EXT_texture_webp"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_texture_webp/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var EXT_texture_webp = /** @class */ (function () { + /** + * @internal + */ + function EXT_texture_webp(loader) { + /** The name of this extension. */ + this.name = NAME; + this._loader = loader; + this.enabled = loader.isExtensionUsed(NAME); + } + /** @internal */ + EXT_texture_webp.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + EXT_texture_webp.prototype._loadTextureAsync = function (context, texture, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.LoadExtensionAsync(context, texture, this.name, function (extensionContext, extension) { + var sampler = texture.sampler == undefined ? _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.DefaultSampler : _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(context, "/sampler"), _this._loader.gltf.samplers, texture.sampler); + var image = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(extensionContext, "/source"), _this._loader.gltf.images, extension.source); + return _this._loader._createTextureAsync(context, sampler, image, function (babylonTexture) { + assign(babylonTexture); + }, undefined, !texture._textureInfo.nonColorData); + }); + }; + return EXT_texture_webp; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__.registerGLTFExtension)(NAME, true, function (loader) { return new EXT_texture_webp(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/ExtrasAsMetadata.ts": +/*!************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/ExtrasAsMetadata.ts ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ ExtrasAsMetadata: () => (/* binding */ ExtrasAsMetadata) +/* harmony export */ }); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + +var NAME = "ExtrasAsMetadata"; +/** + * Store glTF extras (if present) in BJS objects' metadata + */ +var ExtrasAsMetadata = /** @class */ (function () { + /** + * @internal + */ + function ExtrasAsMetadata(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines whether this extension is enabled. + */ + this.enabled = true; + this._loader = loader; + } + ExtrasAsMetadata.prototype._assignExtras = function (babylonObject, gltfProp) { + if (gltfProp.extras && Object.keys(gltfProp.extras).length > 0) { + var metadata = (babylonObject.metadata = babylonObject.metadata || {}); + var gltf = (metadata.gltf = metadata.gltf || {}); + gltf.extras = gltfProp.extras; + } + }; + /** @internal */ + ExtrasAsMetadata.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + ExtrasAsMetadata.prototype.loadNodeAsync = function (context, node, assign) { + var _this = this; + return this._loader.loadNodeAsync(context, node, function (babylonTransformNode) { + _this._assignExtras(babylonTransformNode, node); + assign(babylonTransformNode); + }); + }; + /** + * @internal + */ + ExtrasAsMetadata.prototype.loadCameraAsync = function (context, camera, assign) { + var _this = this; + return this._loader.loadCameraAsync(context, camera, function (babylonCamera) { + _this._assignExtras(babylonCamera, camera); + assign(babylonCamera); + }); + }; + /** + * @internal + */ + ExtrasAsMetadata.prototype.createMaterial = function (context, material, babylonDrawMode) { + var babylonMaterial = this._loader.createMaterial(context, material, babylonDrawMode); + this._assignExtras(babylonMaterial, material); + return babylonMaterial; + }; + return ExtrasAsMetadata; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.registerGLTFExtension)(NAME, false, function (loader) { return new ExtrasAsMetadata(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_animation_pointer.data.ts": +/*!**********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_animation_pointer.data.ts ***! + \**********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ animationPointerTree: () => (/* binding */ animationPointerTree) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoaderAnimation */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderAnimation.ts"); +/* eslint-disable @typescript-eslint/naming-convention */ + + + + +function getColor3(_target, source, offset, scale) { + return babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(source, offset).scale(scale); +} +function getAlpha(_target, source, offset, scale) { + return source[offset + 3] * scale; +} +function getFloat(_target, source, offset, scale) { + return source[offset] * scale; +} +function getMinusFloat(_target, source, offset, scale) { + return -source[offset] * scale; +} +function getNextFloat(_target, source, offset, scale) { + return source[offset + 1] * scale; +} +function getFloatBy2(_target, source, offset, scale) { + return source[offset] * scale * 2; +} +function getTextureTransformTree(textureName) { + return { + scale: [ + new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "".concat(textureName, ".uScale"), getFloat, function () { return 2; }), + new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "".concat(textureName, ".vScale"), getNextFloat, function () { return 2; }), + ], + offset: [ + new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "".concat(textureName, ".uOffset"), getFloat, function () { return 2; }), + new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "".concat(textureName, ".vOffset"), getNextFloat, function () { return 2; }), + ], + rotation: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "".concat(textureName, ".wAng"), getMinusFloat, function () { return 1; })], + }; +} +var CameraAnimationPropertyInfo = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__extends)(CameraAnimationPropertyInfo, _super); + function CameraAnimationPropertyInfo() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** @internal */ + CameraAnimationPropertyInfo.prototype.buildAnimations = function (target, name, fps, keys, callback) { + callback(target._babylonCamera, this._buildAnimation(name, fps, keys)); + }; + return CameraAnimationPropertyInfo; +}(_glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_1__.AnimationPropertyInfo)); +var MaterialAnimationPropertyInfo = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__extends)(MaterialAnimationPropertyInfo, _super); + function MaterialAnimationPropertyInfo() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** @internal */ + MaterialAnimationPropertyInfo.prototype.buildAnimations = function (target, name, fps, keys, callback) { + for (var fillMode in target._data) { + callback(target._data[fillMode].babylonMaterial, this._buildAnimation(name, fps, keys)); + } + }; + return MaterialAnimationPropertyInfo; +}(_glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_1__.AnimationPropertyInfo)); +var LightAnimationPropertyInfo = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__extends)(LightAnimationPropertyInfo, _super); + function LightAnimationPropertyInfo() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** @internal */ + LightAnimationPropertyInfo.prototype.buildAnimations = function (target, name, fps, keys, callback) { + callback(target._babylonLight, this._buildAnimation(name, fps, keys)); + }; + return LightAnimationPropertyInfo; +}(_glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_1__.AnimationPropertyInfo)); +var nodesTree = { + __array__: (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)({ __target__: true }, _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_1__.nodeAnimationData), +}; +var camerasTree = { + __array__: { + __target__: true, + orthographic: { + xmag: [ + new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "orthoLeft", getMinusFloat, function () { return 1; }), + new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "orthoRight", getNextFloat, function () { return 1; }), + ], + ymag: [ + new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "orthoBottom", getMinusFloat, function () { return 1; }), + new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "orthoTop", getNextFloat, function () { return 1; }), + ], + zfar: [new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "maxZ", getFloat, function () { return 1; })], + znear: [new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "minZ", getFloat, function () { return 1; })], + }, + perspective: { + yfov: [new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "fov", getFloat, function () { return 1; })], + zfar: [new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "maxZ", getFloat, function () { return 1; })], + znear: [new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "minZ", getFloat, function () { return 1; })], + }, + }, +}; +var materialsTree = { + __array__: { + __target__: true, + pbrMetallicRoughness: { + baseColorFactor: [ + new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "albedoColor", getColor3, function () { return 4; }), + new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "alpha", getAlpha, function () { return 4; }), + ], + metallicFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "metallic", getFloat, function () { return 1; })], + roughnessFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "roughness", getFloat, function () { return 1; })], + baseColorTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("albedoTexture"), + }, + }, + metallicRoughnessTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("metallicTexture"), + }, + }, + }, + emissiveFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "emissiveColor", getColor3, function () { return 3; })], + normalTexture: { + scale: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "bumpTexture.level", getFloat, function () { return 1; })], + extensions: { + KHR_texture_transform: getTextureTransformTree("bumpTexture"), + }, + }, + occlusionTexture: { + strength: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "ambientTextureStrength", getFloat, function () { return 1; })], + extensions: { + KHR_texture_transform: getTextureTransformTree("ambientTexture"), + }, + }, + emissiveTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("emissiveTexture"), + }, + }, + extensions: { + KHR_materials_anisotropy: { + anisotropyStrength: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "anisotropy.intensity", getFloat, function () { return 1; })], + anisotropyRotation: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "anisotropy.angle", getFloat, function () { return 1; })], + anisotropyTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("anisotropy.texture"), + }, + }, + }, + KHR_materials_clearcoat: { + clearcoatFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "clearCoat.intensity", getFloat, function () { return 1; })], + clearcoatRoughnessFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "clearCoat.roughness", getFloat, function () { return 1; })], + clearcoatTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("clearCoat.texture"), + }, + }, + clearcoatNormalTexture: { + scale: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "clearCoat.bumpTexture.level", getFloat, function () { return 1; })], + extensions: { + KHR_texture_transform: getTextureTransformTree("clearCoat.bumpTexture"), + }, + }, + clearcoatRoughnessTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("clearCoat.textureRoughness"), + }, + }, + }, + KHR_materials_dispersion: { + dispersion: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "subSurface.dispersion", getFloat, function () { return 1; })], + }, + KHR_materials_emissive_strength: { + emissiveStrength: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "emissiveIntensity", getFloat, function () { return 1; })], + }, + KHR_materials_ior: { + ior: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "indexOfRefraction", getFloat, function () { return 1; })], + }, + KHR_materials_iridescence: { + iridescenceFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "iridescence.intensity", getFloat, function () { return 1; })], + iridescenceIor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "iridescence.indexOfRefraction", getFloat, function () { return 1; })], + iridescenceThicknessMinimum: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "iridescence.minimumThickness", getFloat, function () { return 1; })], + iridescenceThicknessMaximum: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "iridescence.maximumThickness", getFloat, function () { return 1; })], + iridescenceTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("iridescence.texture"), + }, + }, + iridescenceThicknessTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("iridescence.thicknessTexture"), + }, + }, + }, + KHR_materials_sheen: { + sheenColorFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "sheen.color", getColor3, function () { return 3; })], + sheenRoughnessFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "sheen.roughness", getFloat, function () { return 1; })], + sheenColorTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("sheen.texture"), + }, + }, + sheenRoughnessTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("sheen.textureRoughness"), + }, + }, + }, + KHR_materials_specular: { + specularFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "metallicF0Factor", getFloat, function () { return 1; })], + specularColorFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "metallicReflectanceColor", getColor3, function () { return 3; })], + specularTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("metallicReflectanceTexture"), + }, + }, + specularColorTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("reflectanceTexture"), + }, + }, + }, + KHR_materials_transmission: { + transmissionFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "subSurface.refractionIntensity", getFloat, function () { return 1; })], + transmissionTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("subSurface.refractionIntensityTexture"), + }, + }, + }, + KHR_materials_volume: { + attenuationColor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "subSurface.tintColor", getColor3, function () { return 3; })], + attenuationDistance: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "subSurface.tintColorAtDistance", getFloat, function () { return 1; })], + thicknessFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "subSurface.maximumThickness", getFloat, function () { return 1; })], + thicknessTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("subSurface.thicknessTexture"), + }, + }, + }, + KHR_materials_diffuse_transmission: { + diffuseTransmissionFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "subSurface.translucencyIntensity", getFloat, function () { return 1; })], + diffuseTransmissionTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("subSurface.translucencyIntensityTexture"), + }, + }, + diffuseTransmissionColorFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "subSurface.translucencyColor", getColor3, function () { return 3; })], + diffuseTransmissionColorTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("subSurface.translucencyColorTexture"), + }, + }, + }, + }, + }, +}; +var extensionsTree = { + KHR_lights_punctual: { + lights: { + __array__: { + __target__: true, + color: [new LightAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "diffuse", getColor3, function () { return 3; })], + intensity: [new LightAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "intensity", getFloat, function () { return 1; })], + range: [new LightAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "range", getFloat, function () { return 1; })], + spot: { + innerConeAngle: [new LightAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "innerAngle", getFloatBy2, function () { return 1; })], + outerConeAngle: [new LightAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "angle", getFloatBy2, function () { return 1; })], + }, + }, + }, + }, +}; +/** @internal */ +var animationPointerTree = { + nodes: nodesTree, + materials: materialsTree, + cameras: camerasTree, + extensions: extensionsTree, +}; + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_animation_pointer.ts": +/*!*****************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_animation_pointer.ts ***! + \*****************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_animation_pointer: () => (/* binding */ KHR_animation_pointer) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _KHR_animation_pointer_data__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./KHR_animation_pointer.data */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_animation_pointer.data.ts"); +/* harmony import */ var _gltfPathToObjectConverter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./gltfPathToObjectConverter */ "../../../dev/loaders/src/glTF/2.0/Extensions/gltfPathToObjectConverter.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + +var NAME = "KHR_animation_pointer"; +/** + * Class to convert an animation pointer path to a smart object that + * gets data from the animation buffer and creates animations. + */ +var AnimationPointerPathToObjectConverter = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__extends)(AnimationPointerPathToObjectConverter, _super); + function AnimationPointerPathToObjectConverter(gltf) { + return _super.call(this, gltf, _KHR_animation_pointer_data__WEBPACK_IMPORTED_MODULE_1__.animationPointerTree) || this; + } + return AnimationPointerPathToObjectConverter; +}(_gltfPathToObjectConverter__WEBPACK_IMPORTED_MODULE_2__.GLTFPathToObjectConverter)); +/** + * [Specification PR](https://github.com/KhronosGroup/glTF/pull/2147) + * !!! Experimental Extension Subject to Changes !!! + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_animation_pointer = /** @class */ (function () { + /** + * @internal + */ + function KHR_animation_pointer(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this._pathToObjectConverter = new AnimationPointerPathToObjectConverter(this._loader.gltf); + } + Object.defineProperty(KHR_animation_pointer.prototype, "enabled", { + /** + * Defines whether this extension is enabled. + */ + get: function () { + return this._loader.isExtensionUsed(NAME); + }, + enumerable: false, + configurable: true + }); + /** @internal */ + KHR_animation_pointer.prototype.dispose = function () { + this._loader = null; + delete this._pathToObjectConverter; // GC + }; + /** + * Loads a glTF animation channel. + * @param context The context when loading the asset + * @param animationContext The context of the animation when loading the asset + * @param animation The glTF animation property + * @param channel The glTF animation channel property + * @param onLoad Called for each animation loaded + * @returns A void promise that resolves when the load is complete or null if not handled + */ + KHR_animation_pointer.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, onLoad) { + var _a; + var extension = (_a = channel.target.extensions) === null || _a === void 0 ? void 0 : _a.KHR_animation_pointer; + if (!extension || !this._pathToObjectConverter) { + return null; + } + if (channel.target.path !== "pointer" /* AnimationChannelTargetPath.POINTER */) { + babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, "/target/path: Value (").concat(channel.target.path, ") must be (").concat("pointer" /* AnimationChannelTargetPath.POINTER */, ") when using the ").concat(this.name, " extension")); + } + if (channel.target.node != undefined) { + babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, "/target/node: Value (").concat(channel.target.node, ") must not be present when using the ").concat(this.name, " extension")); + } + var extensionContext = "".concat(context, "/extensions/").concat(this.name); + var pointer = extension.pointer; + if (!pointer) { + throw new Error("".concat(extensionContext, ": Pointer is missing")); + } + try { + var targetInfo = this._pathToObjectConverter.convert(pointer); + return this._loader._loadAnimationChannelFromTargetInfoAsync(context, animationContext, animation, channel, targetInfo, onLoad); + } + catch (e) { + babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(extensionContext, "/pointer: Invalid pointer (").concat(pointer, ") skipped")); + return null; + } + }; + return KHR_animation_pointer; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_animation_pointer(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts": +/*!**********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts ***! + \**********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_draco_mesh_compression: () => (/* binding */ KHR_draco_mesh_compression) +/* harmony export */ }); +/* harmony import */ var babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Buffers/buffer */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "KHR_draco_mesh_compression"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_draco_mesh_compression = /** @class */ (function () { + /** + * @internal + */ + function KHR_draco_mesh_compression(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines whether to use the normalized flag from the glTF accessor instead of the Draco data. Defaults to true. + */ + this.useNormalizedFlagFromAccessor = true; + this._loader = loader; + this.enabled = babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.DracoCompression.DecoderAvailable && this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_draco_mesh_compression.prototype.dispose = function () { + delete this.dracoCompression; + this._loader = null; + }; + /** + * @internal + */ + KHR_draco_mesh_compression.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, primitive, this.name, function (extensionContext, extension) { + if (primitive.mode != undefined) { + if (primitive.mode !== 4 /* MeshPrimitiveMode.TRIANGLES */ && primitive.mode !== 5 /* MeshPrimitiveMode.TRIANGLE_STRIP */) { + throw new Error("".concat(context, ": Unsupported mode ").concat(primitive.mode)); + } + } + var attributes = {}; + var normalized = {}; + var loadAttribute = function (name, kind) { + var uniqueId = extension.attributes[name]; + if (uniqueId == undefined) { + return; + } + babylonMesh._delayInfo = babylonMesh._delayInfo || []; + if (babylonMesh._delayInfo.indexOf(kind) === -1) { + babylonMesh._delayInfo.push(kind); + } + attributes[kind] = uniqueId; + if (_this.useNormalizedFlagFromAccessor) { + var accessor = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.TryGet(_this._loader.gltf.accessors, primitive.attributes[name]); + if (accessor) { + normalized[kind] = accessor.normalized || false; + } + } + }; + loadAttribute("POSITION", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind); + loadAttribute("NORMAL", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind); + loadAttribute("TANGENT", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind); + loadAttribute("TEXCOORD_0", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UVKind); + loadAttribute("TEXCOORD_1", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV2Kind); + loadAttribute("TEXCOORD_2", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV3Kind); + loadAttribute("TEXCOORD_3", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV4Kind); + loadAttribute("TEXCOORD_4", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV5Kind); + loadAttribute("TEXCOORD_5", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV6Kind); + loadAttribute("JOINTS_0", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesKind); + loadAttribute("WEIGHTS_0", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesWeightsKind); + loadAttribute("COLOR_0", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ColorKind); + var bufferView = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get(extensionContext, _this._loader.gltf.bufferViews, extension.bufferView); + if (!bufferView._dracoBabylonGeometry) { + bufferView._dracoBabylonGeometry = _this._loader.loadBufferViewAsync("/bufferViews/".concat(bufferView.index), bufferView).then(function (data) { + var dracoCompression = _this.dracoCompression || babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.DracoCompression.Default; + return dracoCompression._decodeMeshToGeometryForGltfAsync(babylonMesh.name, _this._loader.babylonScene, data, attributes, normalized).catch(function (error) { + throw new Error("".concat(context, ": ").concat(error.message)); + }); + }); + } + return bufferView._dracoBabylonGeometry; + }); + }; + return KHR_draco_mesh_compression; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_draco_mesh_compression(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_interactivity.ts": +/*!*************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_interactivity.ts ***! + \*************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_interactivity: () => (/* binding */ KHR_interactivity) +/* harmony export */ }); +/* harmony import */ var babylonjs_FlowGraph_flowGraphCoordinator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/FlowGraph/flowGraph */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_FlowGraph_flowGraphCoordinator__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_FlowGraph_flowGraphCoordinator__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _interactivityFunctions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./interactivityFunctions */ "../../../dev/loaders/src/glTF/2.0/Extensions/interactivityFunctions.ts"); +/* harmony import */ var _interactivityPathToObjectConverter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./interactivityPathToObjectConverter */ "../../../dev/loaders/src/glTF/2.0/Extensions/interactivityPathToObjectConverter.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + +var NAME = "KHR_interactivity"; +/** + * Loader extension for KHR_interactivity + */ +var KHR_interactivity = /** @class */ (function () { + /** + * @internal + * @param _loader + */ + function KHR_interactivity(_loader) { + this._loader = _loader; + /** + * The name of this extension. + */ + this.name = NAME; + this.enabled = this._loader.isExtensionUsed(NAME); + this._pathConverter = new _interactivityPathToObjectConverter__WEBPACK_IMPORTED_MODULE_2__.InteractivityPathToObjectConverter(this._loader.gltf); + } + KHR_interactivity.prototype.dispose = function () { + this._loader = null; + delete this._pathConverter; + }; + KHR_interactivity.prototype.onReady = function () { + var _a; + if (!this._loader.babylonScene || !this._pathConverter) { + return; + } + var scene = this._loader.babylonScene; + var interactivityDefinition = (_a = this._loader.gltf.extensions) === null || _a === void 0 ? void 0 : _a.KHR_interactivity; + var json = (0,_interactivityFunctions__WEBPACK_IMPORTED_MODULE_1__.convertGLTFToSerializedFlowGraph)(interactivityDefinition); + var coordinator = new babylonjs_FlowGraph_flowGraphCoordinator__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCoordinator({ scene: scene }); + babylonjs_FlowGraph_flowGraphCoordinator__WEBPACK_IMPORTED_MODULE_0__.FlowGraph.Parse(json, { coordinator: coordinator, pathConverter: this._pathConverter }); + coordinator.start(); + }; + return KHR_interactivity; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_interactivity(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts": +/*!***************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_lights: () => (/* binding */ KHR_lights) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Lights/light */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + + + + +var NAME = "KHR_lights_punctual"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_lights_punctual/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_lights = /** @class */ (function () { + /** + * @internal + */ + function KHR_lights(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_lights.prototype.dispose = function () { + this._loader = null; + delete this._lights; + }; + /** @internal */ + KHR_lights.prototype.onLoading = function () { + var extensions = this._loader.gltf.extensions; + if (extensions && extensions[this.name]) { + var extension = extensions[this.name]; + this._lights = extension.lights; + _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Assign(this._lights); + } + }; + /** + * @internal + */ + KHR_lights.prototype.loadNodeAsync = function (context, node, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) { + _this._loader._allMaterialsDirtyRequired = true; + return _this._loader.loadNodeAsync(context, node, function (babylonMesh) { + var babylonLight; + var light = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get(extensionContext, _this._lights, extension.light); + var name = light.name || babylonMesh.name; + _this._loader.babylonScene._blockEntityCollection = !!_this._loader._assetContainer; + switch (light.type) { + case "directional" /* KHRLightsPunctual_LightType.DIRECTIONAL */: { + var babylonDirectionalLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.DirectionalLight(name, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.Backward(), _this._loader.babylonScene); + babylonDirectionalLight.position.setAll(0); + babylonLight = babylonDirectionalLight; + break; + } + case "point" /* KHRLightsPunctual_LightType.POINT */: { + babylonLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.PointLight(name, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero(), _this._loader.babylonScene); + break; + } + case "spot" /* KHRLightsPunctual_LightType.SPOT */: { + var babylonSpotLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.SpotLight(name, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero(), babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.Backward(), 0, 1, _this._loader.babylonScene); + babylonSpotLight.angle = ((light.spot && light.spot.outerConeAngle) || Math.PI / 4) * 2; + babylonSpotLight.innerAngle = ((light.spot && light.spot.innerConeAngle) || 0) * 2; + babylonLight = babylonSpotLight; + break; + } + default: { + _this._loader.babylonScene._blockEntityCollection = false; + throw new Error("".concat(extensionContext, ": Invalid light type (").concat(light.type, ")")); + } + } + babylonLight._parentContainer = _this._loader._assetContainer; + _this._loader.babylonScene._blockEntityCollection = false; + light._babylonLight = babylonLight; + babylonLight.falloffType = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Light.FALLOFF_GLTF; + babylonLight.diffuse = light.color ? babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(light.color) : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.White(); + babylonLight.intensity = light.intensity == undefined ? 1 : light.intensity; + babylonLight.range = light.range == undefined ? Number.MAX_VALUE : light.range; + babylonLight.parent = babylonMesh; + _this._loader._babylonLights.push(babylonLight); + _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.AddPointerMetadata(babylonLight, extensionContext); + assign(babylonMesh); + }); + }); + }; + return KHR_lights; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_lights(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts": +/*!********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts ***! + \********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_anisotropy: () => (/* binding */ KHR_materials_anisotropy) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_anisotropy"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_anisotropy) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_anisotropy = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_anisotropy(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 195; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_anisotropy.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_anisotropy.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadIridescencePropertiesAsync(extensionContext, extension, babylonMaterial)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_anisotropy.prototype._loadIridescencePropertiesAsync = function (context, properties, babylonMaterial) { + var _a, _b; + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.anisotropy.isEnabled = true; + babylonMaterial.anisotropy.intensity = (_a = properties.anisotropyStrength) !== null && _a !== void 0 ? _a : 0; + babylonMaterial.anisotropy.angle = (_b = properties.anisotropyRotation) !== null && _b !== void 0 ? _b : 0; + if (properties.anisotropyTexture) { + properties.anisotropyTexture.nonColorData = true; + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/anisotropyTexture"), properties.anisotropyTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Anisotropy Intensity)"); + babylonMaterial.anisotropy.texture = texture; + })); + } + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_anisotropy; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_anisotropy(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts": +/*!*******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_clearcoat: () => (/* binding */ KHR_materials_clearcoat) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_clearcoat"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md) + * [Playground Sample](https://www.babylonjs-playground.com/frame.html#7F7PN6#8) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_clearcoat = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_clearcoat(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 190; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_clearcoat.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_clearcoat.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadClearCoatPropertiesAsync(extensionContext, extension, babylonMaterial)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_clearcoat.prototype._loadClearCoatPropertiesAsync = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.clearCoat.isEnabled = true; + babylonMaterial.clearCoat.useRoughnessFromMainTexture = false; + babylonMaterial.clearCoat.remapF0OnInterfaceChange = false; + if (properties.clearcoatFactor != undefined) { + babylonMaterial.clearCoat.intensity = properties.clearcoatFactor; + } + else { + babylonMaterial.clearCoat.intensity = 0; + } + if (properties.clearcoatTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/clearcoatTexture"), properties.clearcoatTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (ClearCoat)"); + babylonMaterial.clearCoat.texture = texture; + })); + } + if (properties.clearcoatRoughnessFactor != undefined) { + babylonMaterial.clearCoat.roughness = properties.clearcoatRoughnessFactor; + } + else { + babylonMaterial.clearCoat.roughness = 0; + } + if (properties.clearcoatRoughnessTexture) { + properties.clearcoatRoughnessTexture.nonColorData = true; + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/clearcoatRoughnessTexture"), properties.clearcoatRoughnessTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (ClearCoat Roughness)"); + babylonMaterial.clearCoat.textureRoughness = texture; + })); + } + if (properties.clearcoatNormalTexture) { + properties.clearcoatNormalTexture.nonColorData = true; + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/clearcoatNormalTexture"), properties.clearcoatNormalTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (ClearCoat Normal)"); + babylonMaterial.clearCoat.bumpTexture = texture; + })); + babylonMaterial.invertNormalMapX = !babylonMaterial.getScene().useRightHandedSystem; + babylonMaterial.invertNormalMapY = babylonMaterial.getScene().useRightHandedSystem; + if (properties.clearcoatNormalTexture.scale != undefined) { + babylonMaterial.clearCoat.bumpTexture.level = properties.clearcoatNormalTexture.scale; + } + } + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_clearcoat; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_clearcoat(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts": +/*!******************************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts ***! + \******************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_diffuse_transmission: () => (/* binding */ KHR_materials_diffuse_transmission) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "KHR_materials_diffuse_transmission"; +/** + * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1825) + * !!! Experimental Extension Subject to Changes !!! + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_diffuse_transmission = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_diffuse_transmission(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 174; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + if (this.enabled) { + loader.parent.transparencyAsCoverage = true; + } + } + /** @internal */ + KHR_materials_diffuse_transmission.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_diffuse_transmission.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadTranslucentPropertiesAsync(extensionContext, material, babylonMaterial, extension)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_diffuse_transmission.prototype._loadTranslucentPropertiesAsync = function (context, material, babylonMaterial, extension) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var pbrMaterial = babylonMaterial; + // Enables "translucency" texture which represents diffusely-transmitted light. + pbrMaterial.subSurface.isTranslucencyEnabled = true; + // Since this extension models thin-surface transmission only, we must make the + // internal IOR == 1.0 and set the thickness to 0. + pbrMaterial.subSurface.volumeIndexOfRefraction = 1.0; + pbrMaterial.subSurface.minimumThickness = 0.0; + pbrMaterial.subSurface.maximumThickness = 0.0; + // Tint color will be used for transmission. + pbrMaterial.subSurface.useAlbedoToTintTranslucency = false; + if (extension.diffuseTransmissionFactor !== undefined) { + pbrMaterial.subSurface.translucencyIntensity = extension.diffuseTransmissionFactor; + } + else { + pbrMaterial.subSurface.translucencyIntensity = 0.0; + pbrMaterial.subSurface.isTranslucencyEnabled = false; + return Promise.resolve(); + } + var promises = new Array(); + pbrMaterial.subSurface.useGltfStyleTextures = true; + if (extension.diffuseTransmissionTexture) { + extension.diffuseTransmissionTexture.nonColorData = true; + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/diffuseTransmissionTexture"), extension.diffuseTransmissionTexture).then(function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Diffuse Transmission)"); + pbrMaterial.subSurface.translucencyIntensityTexture = texture; + })); + } + if (extension.diffuseTransmissionColorFactor !== undefined) { + pbrMaterial.subSurface.translucencyColor = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(extension.diffuseTransmissionColorFactor); + } + else { + pbrMaterial.subSurface.translucencyColor = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Color3.White(); + } + if (extension.diffuseTransmissionColorTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/diffuseTransmissionColorTexture"), extension.diffuseTransmissionColorTexture).then(function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Diffuse Transmission Color)"); + pbrMaterial.subSurface.translucencyColorTexture = texture; + })); + } + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_diffuse_transmission; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_diffuse_transmission(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts": +/*!********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts ***! + \********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_dispersion: () => (/* binding */ KHR_materials_dispersion) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_dispersion"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/87bd64a7f5e23c84b6aef2e6082069583ed0ddb4/extensions/2.0/Khronos/KHR_materials_dispersion/README.md) + * @experimental + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_dispersion = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_dispersion(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 174; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_dispersion.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_dispersion.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadDispersionPropertiesAsync(extensionContext, material, babylonMaterial, extension)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_dispersion.prototype._loadDispersionPropertiesAsync = function (context, material, babylonMaterial, extension) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + // If transparency isn't enabled already, this extension shouldn't do anything. + // i.e. it requires either the KHR_materials_transmission or KHR_materials_diffuse_transmission extensions. + if (!babylonMaterial.subSurface.isRefractionEnabled || !extension.dispersion) { + return Promise.resolve(); + } + babylonMaterial.subSurface.isDispersionEnabled = true; + babylonMaterial.subSurface.dispersion = extension.dispersion; + return Promise.resolve(); + }; + return KHR_materials_dispersion; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_dispersion(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_emissive_strength.ts": +/*!***************************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_emissive_strength.ts ***! + \***************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_emissive_strength: () => (/* binding */ KHR_materials_emissive_strength) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_emissive_strength"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_emissive_strength = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_emissive_strength(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 170; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_emissive_strength.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_emissive_strength.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + return _this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial).then(function () { + _this._loadEmissiveProperties(extensionContext, extension, babylonMaterial); + }); + }); + }; + KHR_materials_emissive_strength.prototype._loadEmissiveProperties = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + if (properties.emissiveStrength !== undefined) { + babylonMaterial.emissiveIntensity = properties.emissiveStrength; + } + }; + return KHR_materials_emissive_strength; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_emissive_strength(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_ior.ts": +/*!*************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_ior.ts ***! + \*************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_ior: () => (/* binding */ KHR_materials_ior) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_ior"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_ior/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_ior = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_ior(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 180; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_ior.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_ior.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadIorPropertiesAsync(extensionContext, extension, babylonMaterial)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_ior.prototype._loadIorPropertiesAsync = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + if (properties.ior !== undefined) { + babylonMaterial.indexOfRefraction = properties.ior; + } + else { + babylonMaterial.indexOfRefraction = KHR_materials_ior._DEFAULT_IOR; + } + return Promise.resolve(); + }; + /** + * Default ior Value from the spec. + */ + KHR_materials_ior._DEFAULT_IOR = 1.5; + return KHR_materials_ior; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_ior(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_iridescence.ts": +/*!*********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_iridescence.ts ***! + \*********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_iridescence: () => (/* binding */ KHR_materials_iridescence) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_iridescence"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_iridescence/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_iridescence = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_iridescence(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 195; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_iridescence.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_iridescence.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadIridescencePropertiesAsync(extensionContext, extension, babylonMaterial)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_iridescence.prototype._loadIridescencePropertiesAsync = function (context, properties, babylonMaterial) { + var _a, _b, _c, _d, _e; + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.iridescence.isEnabled = true; + babylonMaterial.iridescence.intensity = (_a = properties.iridescenceFactor) !== null && _a !== void 0 ? _a : 0; + babylonMaterial.iridescence.indexOfRefraction = (_c = (_b = properties.iridescenceIor) !== null && _b !== void 0 ? _b : properties.iridescenceIOR) !== null && _c !== void 0 ? _c : 1.3; + babylonMaterial.iridescence.minimumThickness = (_d = properties.iridescenceThicknessMinimum) !== null && _d !== void 0 ? _d : 100; + babylonMaterial.iridescence.maximumThickness = (_e = properties.iridescenceThicknessMaximum) !== null && _e !== void 0 ? _e : 400; + if (properties.iridescenceTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/iridescenceTexture"), properties.iridescenceTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Iridescence)"); + babylonMaterial.iridescence.texture = texture; + })); + } + if (properties.iridescenceThicknessTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/iridescenceThicknessTexture"), properties.iridescenceThicknessTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Iridescence Thickness)"); + babylonMaterial.iridescence.thicknessTexture = texture; + })); + } + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_iridescence; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_iridescence(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts": +/*!*******************************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts ***! + \*******************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_pbrSpecularGlossiness: () => (/* binding */ KHR_materials_pbrSpecularGlossiness) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "KHR_materials_pbrSpecularGlossiness"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_pbrSpecularGlossiness = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_pbrSpecularGlossiness(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 200; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_pbrSpecularGlossiness.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_pbrSpecularGlossiness.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialBasePropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadSpecularGlossinessPropertiesAsync(extensionContext, extension, babylonMaterial)); + _this._loader.loadMaterialAlphaProperties(context, material, babylonMaterial); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_pbrSpecularGlossiness.prototype._loadSpecularGlossinessPropertiesAsync = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.metallic = null; + babylonMaterial.roughness = null; + if (properties.diffuseFactor) { + babylonMaterial.albedoColor = babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(properties.diffuseFactor); + babylonMaterial.alpha = properties.diffuseFactor[3]; + } + else { + babylonMaterial.albedoColor = babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.Color3.White(); + } + babylonMaterial.reflectivityColor = properties.specularFactor ? babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(properties.specularFactor) : babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.Color3.White(); + babylonMaterial.microSurface = properties.glossinessFactor == undefined ? 1 : properties.glossinessFactor; + if (properties.diffuseTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/diffuseTexture"), properties.diffuseTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Diffuse)"); + babylonMaterial.albedoTexture = texture; + })); + } + if (properties.specularGlossinessTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/specularGlossinessTexture"), properties.specularGlossinessTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Specular Glossiness)"); + babylonMaterial.reflectivityTexture = texture; + babylonMaterial.reflectivityTexture.hasAlpha = true; + })); + babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true; + } + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_pbrSpecularGlossiness; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_pbrSpecularGlossiness(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_sheen.ts": +/*!***************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_sheen.ts ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_sheen: () => (/* binding */ KHR_materials_sheen) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "KHR_materials_sheen"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_sheen/README.md) + * [Playground Sample](https://www.babylonjs-playground.com/frame.html#BNIZX6#4) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_sheen = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_sheen(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 190; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_sheen.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_sheen.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadSheenPropertiesAsync(extensionContext, extension, babylonMaterial)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_sheen.prototype._loadSheenPropertiesAsync = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.sheen.isEnabled = true; + babylonMaterial.sheen.intensity = 1; + if (properties.sheenColorFactor != undefined) { + babylonMaterial.sheen.color = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(properties.sheenColorFactor); + } + else { + babylonMaterial.sheen.color = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Color3.Black(); + } + if (properties.sheenColorTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/sheenColorTexture"), properties.sheenColorTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Sheen Color)"); + babylonMaterial.sheen.texture = texture; + })); + } + if (properties.sheenRoughnessFactor !== undefined) { + babylonMaterial.sheen.roughness = properties.sheenRoughnessFactor; + } + else { + babylonMaterial.sheen.roughness = 0; + } + if (properties.sheenRoughnessTexture) { + properties.sheenRoughnessTexture.nonColorData = true; + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/sheenRoughnessTexture"), properties.sheenRoughnessTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Sheen Roughness)"); + babylonMaterial.sheen.textureRoughness = texture; + })); + } + babylonMaterial.sheen.albedoScaling = true; + babylonMaterial.sheen.useRoughnessFromMainTexture = false; + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_sheen; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_sheen(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_specular.ts": +/*!******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_specular.ts ***! + \******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_specular: () => (/* binding */ KHR_materials_specular) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "KHR_materials_specular"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_specular/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_specular = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_specular(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 190; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_specular.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_specular.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadSpecularPropertiesAsync(extensionContext, extension, babylonMaterial)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_specular.prototype._loadSpecularPropertiesAsync = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + if (properties.specularFactor !== undefined) { + babylonMaterial.metallicF0Factor = properties.specularFactor; + } + if (properties.specularColorFactor !== undefined) { + babylonMaterial.metallicReflectanceColor = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(properties.specularColorFactor); + } + if (properties.specularTexture) { + properties.specularTexture.nonColorData = true; + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/specularTexture"), properties.specularTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Specular)"); + babylonMaterial.metallicReflectanceTexture = texture; + babylonMaterial.useOnlyMetallicFromMetallicReflectanceTexture = true; + })); + } + if (properties.specularColorTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/specularColorTexture"), properties.specularColorTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Specular Color)"); + babylonMaterial.reflectanceTexture = texture; + })); + } + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_specular; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_specular(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_transmission.ts": +/*!**********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_transmission.ts ***! + \**********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_transmission: () => (/* binding */ KHR_materials_transmission) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + + + + +/** + * A class to handle setting up the rendering of opaque objects to be shown through transmissive objects. + */ +var TransmissionHelper = /** @class */ (function () { + /** + * constructor + * @param options Defines the options we want to customize the helper + * @param scene The scene to add the material to + */ + function TransmissionHelper(options, scene) { + var _this = this; + this._opaqueRenderTarget = null; + this._opaqueMeshesCache = []; + this._transparentMeshesCache = []; + this._materialObservers = {}; + this._options = (0,tslib__WEBPACK_IMPORTED_MODULE_3__.__assign)((0,tslib__WEBPACK_IMPORTED_MODULE_3__.__assign)({}, TransmissionHelper._GetDefaultOptions()), options); + this._scene = scene; + this._scene._transmissionHelper = this; + this.onErrorObservable = new babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Observable(); + this._scene.onDisposeObservable.addOnce(function () { + _this.dispose(); + }); + this._parseScene(); + this._setupRenderTargets(); + } + /** + * Creates the default options for the helper. + * @returns the default options + */ + TransmissionHelper._GetDefaultOptions = function () { + return { + renderSize: 1024, + samples: 4, + lodGenerationScale: 1, + lodGenerationOffset: -4, + renderTargetTextureType: babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Constants.TEXTURETYPE_HALF_FLOAT, + generateMipmaps: true, + }; + }; + /** + * Updates the background according to the new options + * @param options + */ + TransmissionHelper.prototype.updateOptions = function (options) { + var _this = this; + // First check if any options are actually being changed. If not, exit. + var newValues = Object.keys(options).filter(function (key) { return _this._options[key] !== options[key]; }); + if (!newValues.length) { + return; + } + var newOptions = (0,tslib__WEBPACK_IMPORTED_MODULE_3__.__assign)((0,tslib__WEBPACK_IMPORTED_MODULE_3__.__assign)({}, this._options), options); + var oldOptions = this._options; + this._options = newOptions; + // If size changes, recreate everything + if (newOptions.renderSize !== oldOptions.renderSize || + newOptions.renderTargetTextureType !== oldOptions.renderTargetTextureType || + newOptions.generateMipmaps !== oldOptions.generateMipmaps || + !this._opaqueRenderTarget) { + this._setupRenderTargets(); + } + else { + this._opaqueRenderTarget.samples = newOptions.samples; + this._opaqueRenderTarget.lodGenerationScale = newOptions.lodGenerationScale; + this._opaqueRenderTarget.lodGenerationOffset = newOptions.lodGenerationOffset; + } + }; + /** + * @returns the opaque render target texture or null if not available. + */ + TransmissionHelper.prototype.getOpaqueTarget = function () { + return this._opaqueRenderTarget; + }; + TransmissionHelper.prototype._shouldRenderAsTransmission = function (material) { + if (!material) { + return false; + } + if (material instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial && material.subSurface.isRefractionEnabled) { + return true; + } + return false; + }; + TransmissionHelper.prototype._addMesh = function (mesh) { + var _this = this; + this._materialObservers[mesh.uniqueId] = mesh.onMaterialChangedObservable.add(this._onMeshMaterialChanged.bind(this)); + // we need to defer the processing because _addMesh may be called as part as an instance mesh creation, in which case some + // internal properties are not setup yet, like _sourceMesh (needed when doing mesh.material below) + babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Tools.SetImmediate(function () { + if (_this._shouldRenderAsTransmission(mesh.material)) { + mesh.material.refractionTexture = _this._opaqueRenderTarget; + if (_this._transparentMeshesCache.indexOf(mesh) === -1) { + _this._transparentMeshesCache.push(mesh); + } + } + else { + if (_this._opaqueMeshesCache.indexOf(mesh) === -1) { + _this._opaqueMeshesCache.push(mesh); + } + } + }); + }; + TransmissionHelper.prototype._removeMesh = function (mesh) { + mesh.onMaterialChangedObservable.remove(this._materialObservers[mesh.uniqueId]); + delete this._materialObservers[mesh.uniqueId]; + var idx = this._transparentMeshesCache.indexOf(mesh); + if (idx !== -1) { + this._transparentMeshesCache.splice(idx, 1); + } + idx = this._opaqueMeshesCache.indexOf(mesh); + if (idx !== -1) { + this._opaqueMeshesCache.splice(idx, 1); + } + }; + TransmissionHelper.prototype._parseScene = function () { + this._scene.meshes.forEach(this._addMesh.bind(this)); + // Listen for when a mesh is added to the scene and add it to our cache lists. + this._scene.onNewMeshAddedObservable.add(this._addMesh.bind(this)); + // Listen for when a mesh is removed from to the scene and remove it from our cache lists. + this._scene.onMeshRemovedObservable.add(this._removeMesh.bind(this)); + }; + // When one of the meshes in the scene has its material changed, make sure that it's in the correct cache list. + TransmissionHelper.prototype._onMeshMaterialChanged = function (mesh) { + var transparentIdx = this._transparentMeshesCache.indexOf(mesh); + var opaqueIdx = this._opaqueMeshesCache.indexOf(mesh); + // If the material is transparent, make sure that it's added to the transparent list and removed from the opaque list + var useTransmission = this._shouldRenderAsTransmission(mesh.material); + if (useTransmission) { + if (mesh.material instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial) { + mesh.material.subSurface.refractionTexture = this._opaqueRenderTarget; + } + if (opaqueIdx !== -1) { + this._opaqueMeshesCache.splice(opaqueIdx, 1); + this._transparentMeshesCache.push(mesh); + } + else if (transparentIdx === -1) { + this._transparentMeshesCache.push(mesh); + } + // If the material is opaque, make sure that it's added to the opaque list and removed from the transparent list + } + else { + if (transparentIdx !== -1) { + this._transparentMeshesCache.splice(transparentIdx, 1); + this._opaqueMeshesCache.push(mesh); + } + else if (opaqueIdx === -1) { + this._opaqueMeshesCache.push(mesh); + } + } + }; + /** + * @internal + * Check if the opaque render target has not been disposed and can still be used. + * @returns + */ + TransmissionHelper.prototype._isRenderTargetValid = function () { + var _a; + return ((_a = this._opaqueRenderTarget) === null || _a === void 0 ? void 0 : _a.getInternalTexture()) !== null; + }; + /** + * @internal + * Setup the render targets according to the specified options. + */ + TransmissionHelper.prototype._setupRenderTargets = function () { + var _this = this; + var _a, _b; + if (this._opaqueRenderTarget) { + this._opaqueRenderTarget.dispose(); + } + this._opaqueRenderTarget = new babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.RenderTargetTexture("opaqueSceneTexture", this._options.renderSize, this._scene, this._options.generateMipmaps, undefined, this._options.renderTargetTextureType); + this._opaqueRenderTarget.ignoreCameraViewport = true; + this._opaqueRenderTarget.renderList = this._opaqueMeshesCache; + this._opaqueRenderTarget.clearColor = (_b = (_a = this._options.clearColor) === null || _a === void 0 ? void 0 : _a.clone()) !== null && _b !== void 0 ? _b : this._scene.clearColor.clone(); + this._opaqueRenderTarget.gammaSpace = false; + this._opaqueRenderTarget.lodGenerationScale = this._options.lodGenerationScale; + this._opaqueRenderTarget.lodGenerationOffset = this._options.lodGenerationOffset; + this._opaqueRenderTarget.samples = this._options.samples; + this._opaqueRenderTarget.renderSprites = true; + this._opaqueRenderTarget.renderParticles = true; + var sceneImageProcessingapplyByPostProcess; + var saveSceneEnvIntensity; + this._opaqueRenderTarget.onBeforeBindObservable.add(function (opaqueRenderTarget) { + saveSceneEnvIntensity = _this._scene.environmentIntensity; + _this._scene.environmentIntensity = 1.0; + sceneImageProcessingapplyByPostProcess = _this._scene.imageProcessingConfiguration.applyByPostProcess; + if (!_this._options.clearColor) { + _this._scene.clearColor.toLinearSpaceToRef(opaqueRenderTarget.clearColor, _this._scene.getEngine().useExactSrgbConversions); + } + else { + opaqueRenderTarget.clearColor.copyFrom(_this._options.clearColor); + } + // we do not use the applyByPostProcess setter to avoid flagging all the materials as "image processing dirty"! + _this._scene.imageProcessingConfiguration._applyByPostProcess = true; + }); + this._opaqueRenderTarget.onAfterUnbindObservable.add(function () { + _this._scene.environmentIntensity = saveSceneEnvIntensity; + _this._scene.imageProcessingConfiguration._applyByPostProcess = sceneImageProcessingapplyByPostProcess; + }); + this._transparentMeshesCache.forEach(function (mesh) { + if (_this._shouldRenderAsTransmission(mesh.material)) { + mesh.material.refractionTexture = _this._opaqueRenderTarget; + } + }); + }; + /** + * Dispose all the elements created by the Helper. + */ + TransmissionHelper.prototype.dispose = function () { + this._scene._transmissionHelper = undefined; + if (this._opaqueRenderTarget) { + this._opaqueRenderTarget.dispose(); + this._opaqueRenderTarget = null; + } + this._transparentMeshesCache = []; + this._opaqueMeshesCache = []; + }; + return TransmissionHelper; +}()); +var NAME = "KHR_materials_transmission"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_transmission/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_transmission = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_transmission(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 175; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + if (this.enabled) { + loader.parent.transparencyAsCoverage = true; + } + } + /** @internal */ + KHR_materials_transmission.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_transmission.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadTransparentPropertiesAsync(extensionContext, material, babylonMaterial, extension)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_transmission.prototype._loadTransparentPropertiesAsync = function (context, material, babylonMaterial, extension) { + var _a, _b; + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var pbrMaterial = babylonMaterial; + // Enables "refraction" texture which represents transmitted light. + pbrMaterial.subSurface.isRefractionEnabled = true; + // Since this extension models thin-surface transmission only, we must make IOR = 1.0 + pbrMaterial.subSurface.volumeIndexOfRefraction = 1.0; + // Albedo colour will tint transmission. + pbrMaterial.subSurface.useAlbedoToTintRefraction = true; + if (extension.transmissionFactor !== undefined) { + pbrMaterial.subSurface.refractionIntensity = extension.transmissionFactor; + var scene = pbrMaterial.getScene(); + if (pbrMaterial.subSurface.refractionIntensity && !scene._transmissionHelper) { + new TransmissionHelper({}, pbrMaterial.getScene()); + } + else if (pbrMaterial.subSurface.refractionIntensity && !((_a = scene._transmissionHelper) === null || _a === void 0 ? void 0 : _a._isRenderTargetValid())) { + // If the render target is not valid, recreate it. + (_b = scene._transmissionHelper) === null || _b === void 0 ? void 0 : _b._setupRenderTargets(); + } + } + else { + pbrMaterial.subSurface.refractionIntensity = 0.0; + pbrMaterial.subSurface.isRefractionEnabled = false; + return Promise.resolve(); + } + pbrMaterial.subSurface.minimumThickness = 0.0; + pbrMaterial.subSurface.maximumThickness = 0.0; + if (extension.transmissionTexture) { + extension.transmissionTexture.nonColorData = true; + return this._loader.loadTextureInfoAsync("".concat(context, "/transmissionTexture"), extension.transmissionTexture, undefined).then(function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Transmission)"); + pbrMaterial.subSurface.refractionIntensityTexture = texture; + pbrMaterial.subSurface.useGltfStyleTextures = true; + }); + } + else { + return Promise.resolve(); + } + }; + return KHR_materials_transmission; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_transmission(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts": +/*!***************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_unlit: () => (/* binding */ KHR_materials_unlit) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "KHR_materials_unlit"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_unlit/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_unlit = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_unlit(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 210; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_unlit.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_unlit.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function () { + return _this._loadUnlitPropertiesAsync(context, material, babylonMaterial); + }); + }; + KHR_materials_unlit.prototype._loadUnlitPropertiesAsync = function (context, material, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.unlit = true; + var properties = material.pbrMetallicRoughness; + if (properties) { + if (properties.baseColorFactor) { + babylonMaterial.albedoColor = babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(properties.baseColorFactor); + babylonMaterial.alpha = properties.baseColorFactor[3]; + } + else { + babylonMaterial.albedoColor = babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.Color3.White(); + } + if (properties.baseColorTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/baseColorTexture"), properties.baseColorTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Base Color)"); + babylonMaterial.albedoTexture = texture; + })); + } + } + if (material.doubleSided) { + babylonMaterial.backFaceCulling = false; + babylonMaterial.twoSidedLighting = true; + } + this._loader.loadMaterialAlphaProperties(context, material, babylonMaterial); + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_unlit; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_unlit(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_variants.ts": +/*!******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_variants.ts ***! + \******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_variants: () => (/* binding */ KHR_materials_variants) +/* harmony export */ }); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/mesh */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_variants"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_variants/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_variants = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_variants(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_variants.prototype.dispose = function () { + this._loader = null; + }; + /** + * Gets the list of available variant names for this asset. + * @param rootMesh The glTF root mesh + * @returns the list of all the variant names for this model + */ + KHR_materials_variants.GetAvailableVariants = function (rootMesh) { + var extensionMetadata = this._GetExtensionMetadata(rootMesh); + if (!extensionMetadata) { + return []; + } + return Object.keys(extensionMetadata.variants); + }; + /** + * Gets the list of available variant names for this asset. + * @param rootMesh The glTF root mesh + * @returns the list of all the variant names for this model + */ + KHR_materials_variants.prototype.getAvailableVariants = function (rootMesh) { + return KHR_materials_variants.GetAvailableVariants(rootMesh); + }; + /** + * Select a variant given a variant name or a list of variant names. + * @param rootMesh The glTF root mesh + * @param variantName The variant name(s) to select. + */ + KHR_materials_variants.SelectVariant = function (rootMesh, variantName) { + var extensionMetadata = this._GetExtensionMetadata(rootMesh); + if (!extensionMetadata) { + throw new Error("Cannot select variant on a glTF mesh that does not have the ".concat(NAME, " extension")); + } + var select = function (variantName) { + var entries = extensionMetadata.variants[variantName]; + if (entries) { + for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { + var entry = entries_1[_i]; + entry.mesh.material = entry.material; + } + } + }; + if (variantName instanceof Array) { + for (var _i = 0, variantName_1 = variantName; _i < variantName_1.length; _i++) { + var name_1 = variantName_1[_i]; + select(name_1); + } + } + else { + select(variantName); + } + extensionMetadata.lastSelected = variantName; + }; + /** + * Select a variant given a variant name or a list of variant names. + * @param rootMesh The glTF root mesh + * @param variantName The variant name(s) to select. + */ + KHR_materials_variants.prototype.selectVariant = function (rootMesh, variantName) { + KHR_materials_variants.SelectVariant(rootMesh, variantName); + }; + /** + * Reset back to the original before selecting a variant. + * @param rootMesh The glTF root mesh + */ + KHR_materials_variants.Reset = function (rootMesh) { + var extensionMetadata = this._GetExtensionMetadata(rootMesh); + if (!extensionMetadata) { + throw new Error("Cannot reset on a glTF mesh that does not have the ".concat(NAME, " extension")); + } + for (var _i = 0, _a = extensionMetadata.original; _i < _a.length; _i++) { + var entry = _a[_i]; + entry.mesh.material = entry.material; + } + extensionMetadata.lastSelected = null; + }; + /** + * Reset back to the original before selecting a variant. + * @param rootMesh The glTF root mesh + */ + KHR_materials_variants.prototype.reset = function (rootMesh) { + KHR_materials_variants.Reset(rootMesh); + }; + /** + * Gets the last selected variant name(s) or null if original. + * @param rootMesh The glTF root mesh + * @returns The selected variant name(s). + */ + KHR_materials_variants.GetLastSelectedVariant = function (rootMesh) { + var extensionMetadata = this._GetExtensionMetadata(rootMesh); + if (!extensionMetadata) { + throw new Error("Cannot get the last selected variant on a glTF mesh that does not have the ".concat(NAME, " extension")); + } + return extensionMetadata.lastSelected; + }; + /** + * Gets the last selected variant name(s) or null if original. + * @param rootMesh The glTF root mesh + * @returns The selected variant name(s). + */ + KHR_materials_variants.prototype.getLastSelectedVariant = function (rootMesh) { + return KHR_materials_variants.GetLastSelectedVariant(rootMesh); + }; + KHR_materials_variants._GetExtensionMetadata = function (rootMesh) { + var _a, _b; + return ((_b = (_a = rootMesh === null || rootMesh === void 0 ? void 0 : rootMesh._internalMetadata) === null || _a === void 0 ? void 0 : _a.gltf) === null || _b === void 0 ? void 0 : _b[NAME]) || null; + }; + /** @internal */ + KHR_materials_variants.prototype.onLoading = function () { + var extensions = this._loader.gltf.extensions; + if (extensions && extensions[this.name]) { + var extension = extensions[this.name]; + this._variants = extension.variants; + } + }; + /** + * @internal + */ + KHR_materials_variants.prototype._loadMeshPrimitiveAsync = function (context, name, node, mesh, primitive, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.LoadExtensionAsync(context, primitive, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader._loadMeshPrimitiveAsync(context, name, node, mesh, primitive, function (babylonMesh) { + assign(babylonMesh); + if (babylonMesh instanceof babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__.Mesh) { + var babylonDrawMode = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader._GetDrawMode(context, primitive.mode); + var root_1 = _this._loader.rootBabylonMesh; + var metadata = root_1 ? (root_1._internalMetadata = root_1._internalMetadata || {}) : {}; + var gltf = (metadata.gltf = metadata.gltf || {}); + var extensionMetadata_1 = (gltf[NAME] = gltf[NAME] || { lastSelected: null, original: [], variants: {} }); + // Store the original material. + extensionMetadata_1.original.push({ mesh: babylonMesh, material: babylonMesh.material }); + var _loop_1 = function (mappingIndex) { + var mapping = extension.mappings[mappingIndex]; + var material = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(extensionContext, "/mappings/").concat(mappingIndex, "/material"), _this._loader.gltf.materials, mapping.material); + promises.push(_this._loader._loadMaterialAsync("#/materials/".concat(mapping.material), material, babylonMesh, babylonDrawMode, function (babylonMaterial) { + var _loop_2 = function (mappingVariantIndex) { + var variantIndex = mapping.variants[mappingVariantIndex]; + var variant = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("/extensions/".concat(NAME, "/variants/").concat(variantIndex), _this._variants, variantIndex); + extensionMetadata_1.variants[variant.name] = extensionMetadata_1.variants[variant.name] || []; + extensionMetadata_1.variants[variant.name].push({ + mesh: babylonMesh, + material: babylonMaterial, + }); + // Replace the target when original mesh is cloned + babylonMesh.onClonedObservable.add(function (newOne) { + var newMesh = newOne; + var metadata = null; + var newRoot = newMesh; + // Find root to get medata + do { + newRoot = newRoot.parent; + if (!newRoot) { + return; + } + metadata = KHR_materials_variants._GetExtensionMetadata(newRoot); + } while (metadata === null); + // Need to clone the metadata on the root (first time only) + if (root_1 && metadata === KHR_materials_variants._GetExtensionMetadata(root_1)) { + // Copy main metadata + newRoot._internalMetadata = {}; + for (var key in root_1._internalMetadata) { + newRoot._internalMetadata[key] = root_1._internalMetadata[key]; + } + // Copy the gltf metadata + newRoot._internalMetadata.gltf = []; + for (var key in root_1._internalMetadata.gltf) { + newRoot._internalMetadata.gltf[key] = root_1._internalMetadata.gltf[key]; + } + // Duplicate the extension specific metadata + newRoot._internalMetadata.gltf[NAME] = { lastSelected: null, original: [], variants: {} }; + for (var _i = 0, _a = metadata.original; _i < _a.length; _i++) { + var original = _a[_i]; + newRoot._internalMetadata.gltf[NAME].original.push({ + mesh: original.mesh, + material: original.material, + }); + } + for (var key in metadata.variants) { + if (Object.prototype.hasOwnProperty.call(metadata.variants, key)) { + newRoot._internalMetadata.gltf[NAME].variants[key] = []; + for (var _b = 0, _c = metadata.variants[key]; _b < _c.length; _b++) { + var variantEntry = _c[_b]; + newRoot._internalMetadata.gltf[NAME].variants[key].push({ + mesh: variantEntry.mesh, + material: variantEntry.material, + }); + } + } + } + metadata = newRoot._internalMetadata.gltf[NAME]; + } + // Relocate + for (var _d = 0, _e = metadata.original; _d < _e.length; _d++) { + var target = _e[_d]; + if (target.mesh === babylonMesh) { + target.mesh = newMesh; + } + } + for (var _f = 0, _g = metadata.variants[variant.name]; _f < _g.length; _f++) { + var target = _g[_f]; + if (target.mesh === babylonMesh) { + target.mesh = newMesh; + } + } + }); + }; + for (var mappingVariantIndex = 0; mappingVariantIndex < mapping.variants.length; ++mappingVariantIndex) { + _loop_2(mappingVariantIndex); + } + })); + }; + // For each mapping, look at the variants and make a new entry for them. + for (var mappingIndex = 0; mappingIndex < extension.mappings.length; ++mappingIndex) { + _loop_1(mappingIndex); + } + } + })); + return Promise.all(promises).then(function (_a) { + var babylonMesh = _a[0]; + return babylonMesh; + }); + }); + }; + return KHR_materials_variants; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_variants(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts": +/*!****************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts ***! + \****************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_volume: () => (/* binding */ KHR_materials_volume) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_volume"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_volume/README.md) + * @since 5.0.0 + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_volume = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_volume(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 173; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + if (this.enabled) { + // We need to disable instance usage because the attenuation factor depends on the node scale of each individual mesh + this._loader._disableInstancedMesh++; + } + } + /** @internal */ + KHR_materials_volume.prototype.dispose = function () { + if (this.enabled) { + this._loader._disableInstancedMesh--; + } + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_volume.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadVolumePropertiesAsync(extensionContext, material, babylonMaterial, extension)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_volume.prototype._loadVolumePropertiesAsync = function (context, material, babylonMaterial, extension) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + // If transparency isn't enabled already, this extension shouldn't do anything. + // i.e. it requires either the KHR_materials_transmission or KHR_materials_diffuse_transmission extensions. + if ((!babylonMaterial.subSurface.isRefractionEnabled && !babylonMaterial.subSurface.isTranslucencyEnabled) || !extension.thicknessFactor) { + return Promise.resolve(); + } + // IOR in this extension only affects interior. + babylonMaterial.subSurface.volumeIndexOfRefraction = babylonMaterial.indexOfRefraction; + var attenuationDistance = extension.attenuationDistance !== undefined ? extension.attenuationDistance : Number.MAX_VALUE; + babylonMaterial.subSurface.tintColorAtDistance = attenuationDistance; + if (extension.attenuationColor !== undefined && extension.attenuationColor.length == 3) { + babylonMaterial.subSurface.tintColor.copyFromFloats(extension.attenuationColor[0], extension.attenuationColor[1], extension.attenuationColor[2]); + } + babylonMaterial.subSurface.minimumThickness = 0.0; + babylonMaterial.subSurface.maximumThickness = extension.thicknessFactor; + babylonMaterial.subSurface.useThicknessAsDepth = true; + if (extension.thicknessTexture) { + extension.thicknessTexture.nonColorData = true; + return this._loader.loadTextureInfoAsync("".concat(context, "/thicknessTexture"), extension.thicknessTexture).then(function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Thickness)"); + babylonMaterial.subSurface.thicknessTexture = texture; + babylonMaterial.subSurface.useGltfStyleTextures = true; + }); + } + else { + return Promise.resolve(); + } + }; + return KHR_materials_volume; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_volume(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_mesh_quantization.ts": +/*!*****************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_mesh_quantization.ts ***! + \*****************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_mesh_quantization: () => (/* binding */ KHR_mesh_quantization) +/* harmony export */ }); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + +var NAME = "KHR_mesh_quantization"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_mesh_quantization/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_mesh_quantization = /** @class */ (function () { + /** + * @internal + */ + function KHR_mesh_quantization(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this.enabled = loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_mesh_quantization.prototype.dispose = function () { }; + return KHR_mesh_quantization; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_mesh_quantization(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_node_visibility.ts": +/*!***************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_node_visibility.ts ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_node_visibility: () => (/* binding */ KHR_node_visibility) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + +var NAME = "KHR_node_visibility"; +/** + * Loader extension for KHR_node_visibility + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_node_visibility = /** @class */ (function () { + /** + * @internal + */ + function KHR_node_visibility(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = loader.isExtensionUsed(NAME); + } + KHR_node_visibility.prototype.onReady = function () { + return (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__awaiter)(this, void 0, void 0, function () { + var _a; + return (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__generator)(this, function (_b) { + (_a = this._loader.gltf.nodes) === null || _a === void 0 ? void 0 : _a.forEach(function (node) { + var _a, _b, _c, _d; + (_a = node._primitiveBabylonMeshes) === null || _a === void 0 ? void 0 : _a.forEach(function (mesh) { + mesh.inheritVisibility = true; + }); + // When the JSON Pointer is used we need to change both the transform node and the primitive meshes to the new value. + if ((_b = node.extensions) === null || _b === void 0 ? void 0 : _b.KHR_node_visibility) { + if (((_c = node.extensions) === null || _c === void 0 ? void 0 : _c.KHR_node_visibility.visible) === false) { + if (node._babylonTransformNode) { + node._babylonTransformNode.isVisible = false; + } + (_d = node._primitiveBabylonMeshes) === null || _d === void 0 ? void 0 : _d.forEach(function (mesh) { + mesh.isVisible = false; + }); + } + } + }); + return [2 /*return*/]; + }); + }); + }; + KHR_node_visibility.prototype.dispose = function () { + this._loader = null; + }; + return KHR_node_visibility; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_node_visibility(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_texture_basisu.ts": +/*!**************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_texture_basisu.ts ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_texture_basisu: () => (/* binding */ KHR_texture_basisu) +/* harmony export */ }); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + +var NAME = "KHR_texture_basisu"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_texture_basisu/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_texture_basisu = /** @class */ (function () { + /** + * @internal + */ + function KHR_texture_basisu(loader) { + /** The name of this extension. */ + this.name = NAME; + this._loader = loader; + this.enabled = loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_texture_basisu.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_texture_basisu.prototype._loadTextureAsync = function (context, texture, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.LoadExtensionAsync(context, texture, this.name, function (extensionContext, extension) { + var sampler = texture.sampler == undefined ? _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.DefaultSampler : _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(context, "/sampler"), _this._loader.gltf.samplers, texture.sampler); + var image = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(extensionContext, "/source"), _this._loader.gltf.images, extension.source); + return _this._loader._createTextureAsync(context, sampler, image, function (babylonTexture) { + assign(babylonTexture); + }, texture._textureInfo.nonColorData ? { useRGBAIfASTCBC7NotAvailableWhenUASTC: true } : undefined, !texture._textureInfo.nonColorData); + }); + }; + return KHR_texture_basisu; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_texture_basisu(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts": +/*!*****************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts ***! + \*****************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_texture_transform: () => (/* binding */ KHR_texture_transform) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Textures/texture */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_texture_transform"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_texture_transform/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_texture_transform = /** @class */ (function () { + /** + * @internal + */ + function KHR_texture_transform(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_texture_transform.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_texture_transform.prototype.loadTextureInfoAsync = function (context, textureInfo, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, textureInfo, this.name, function (extensionContext, extension) { + return _this._loader.loadTextureInfoAsync(context, textureInfo, function (babylonTexture) { + if (!(babylonTexture instanceof babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__.Texture)) { + throw new Error("".concat(extensionContext, ": Texture type not supported")); + } + if (extension.offset) { + babylonTexture.uOffset = extension.offset[0]; + babylonTexture.vOffset = extension.offset[1]; + } + // Always rotate around the origin. + babylonTexture.uRotationCenter = 0; + babylonTexture.vRotationCenter = 0; + if (extension.rotation) { + babylonTexture.wAng = -extension.rotation; + } + if (extension.scale) { + babylonTexture.uScale = extension.scale[0]; + babylonTexture.vScale = extension.scale[1]; + } + if (extension.texCoord != undefined) { + babylonTexture.coordinatesIndex = extension.texCoord; + } + assign(babylonTexture); + }); + }); + }; + return KHR_texture_transform; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_texture_transform(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_xmp_json_ld.ts": +/*!***********************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_xmp_json_ld.ts ***! + \***********************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_xmp_json_ld: () => (/* binding */ KHR_xmp_json_ld) +/* harmony export */ }); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + +var NAME = "KHR_xmp_json_ld"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_xmp_json_ld/README.md) + * @since 5.0.0 + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_xmp_json_ld = /** @class */ (function () { + /** + * @internal + */ + function KHR_xmp_json_ld(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 100; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_xmp_json_ld.prototype.dispose = function () { + this._loader = null; + }; + /** + * Called after the loader state changes to LOADING. + */ + KHR_xmp_json_ld.prototype.onLoading = function () { + var _a, _b, _c; + if (this._loader.rootBabylonMesh === null) { + return; + } + var xmp_gltf = (_a = this._loader.gltf.extensions) === null || _a === void 0 ? void 0 : _a.KHR_xmp_json_ld; + var xmp_node = (_c = (_b = this._loader.gltf.asset) === null || _b === void 0 ? void 0 : _b.extensions) === null || _c === void 0 ? void 0 : _c.KHR_xmp_json_ld; + if (xmp_gltf && xmp_node) { + var packet = +xmp_node.packet; + if (xmp_gltf.packets && packet < xmp_gltf.packets.length) { + this._loader.rootBabylonMesh.metadata = this._loader.rootBabylonMesh.metadata || {}; + this._loader.rootBabylonMesh.metadata.xmp = xmp_gltf.packets[packet]; + } + } + }; + return KHR_xmp_json_ld; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_xmp_json_ld(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts": +/*!**************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ MSFT_audio_emitter: () => (/* binding */ MSFT_audio_emitter) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Audio/audioSceneComponent */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + + + + +var NAME = "MSFT_audio_emitter"; +/** + * [Specification](https://github.com/najadojo/glTF/blob/MSFT_audio_emitter/extensions/2.0/Vendor/MSFT_audio_emitter/README.md) + * !!! Experimental Extension Subject to Changes !!! + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var MSFT_audio_emitter = /** @class */ (function () { + /** + * @internal + */ + function MSFT_audio_emitter(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + MSFT_audio_emitter.prototype.dispose = function () { + this._loader = null; + this._clips = null; + this._emitters = null; + }; + /** @internal */ + MSFT_audio_emitter.prototype.onLoading = function () { + var extensions = this._loader.gltf.extensions; + if (extensions && extensions[this.name]) { + var extension = extensions[this.name]; + this._clips = extension.clips; + this._emitters = extension.emitters; + _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Assign(this._clips); + _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Assign(this._emitters); + } + }; + /** + * @internal + */ + MSFT_audio_emitter.prototype.loadSceneAsync = function (context, scene) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, scene, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadSceneAsync(context, scene)); + for (var _i = 0, _a = extension.emitters; _i < _a.length; _i++) { + var emitterIndex = _a[_i]; + var emitter = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("".concat(extensionContext, "/emitters"), _this._emitters, emitterIndex); + if (emitter.refDistance != undefined || + emitter.maxDistance != undefined || + emitter.rolloffFactor != undefined || + emitter.distanceModel != undefined || + emitter.innerAngle != undefined || + emitter.outerAngle != undefined) { + throw new Error("".concat(extensionContext, ": Direction or Distance properties are not allowed on emitters attached to a scene")); + } + promises.push(_this._loadEmitterAsync("".concat(extensionContext, "/emitters/").concat(emitter.index), emitter)); + } + return Promise.all(promises).then(function () { }); + }); + }; + /** + * @internal + */ + MSFT_audio_emitter.prototype.loadNodeAsync = function (context, node, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) { + var promises = new Array(); + return _this._loader + .loadNodeAsync(extensionContext, node, function (babylonMesh) { + var _loop_1 = function (emitterIndex) { + var emitter = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("".concat(extensionContext, "/emitters"), _this._emitters, emitterIndex); + promises.push(_this._loadEmitterAsync("".concat(extensionContext, "/emitters/").concat(emitter.index), emitter).then(function () { + for (var _i = 0, _a = emitter._babylonSounds; _i < _a.length; _i++) { + var sound = _a[_i]; + sound.attachToMesh(babylonMesh); + if (emitter.innerAngle != undefined || emitter.outerAngle != undefined) { + sound.setLocalDirectionToMesh(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.Forward()); + sound.setDirectionalCone(2 * babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.ToDegrees(emitter.innerAngle == undefined ? Math.PI : emitter.innerAngle), 2 * babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.ToDegrees(emitter.outerAngle == undefined ? Math.PI : emitter.outerAngle), 0); + } + } + })); + }; + for (var _i = 0, _a = extension.emitters; _i < _a.length; _i++) { + var emitterIndex = _a[_i]; + _loop_1(emitterIndex); + } + assign(babylonMesh); + }) + .then(function (babylonMesh) { + return Promise.all(promises).then(function () { + return babylonMesh; + }); + }); + }); + }; + /** + * @internal + */ + MSFT_audio_emitter.prototype.loadAnimationAsync = function (context, animation) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, animation, this.name, function (extensionContext, extension) { + return _this._loader.loadAnimationAsync(context, animation).then(function (babylonAnimationGroup) { + var promises = new Array(); + _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Assign(extension.events); + for (var _i = 0, _a = extension.events; _i < _a.length; _i++) { + var event_1 = _a[_i]; + promises.push(_this._loadAnimationEventAsync("".concat(extensionContext, "/events/").concat(event_1.index), context, animation, event_1, babylonAnimationGroup)); + } + return Promise.all(promises).then(function () { + return babylonAnimationGroup; + }); + }); + }); + }; + MSFT_audio_emitter.prototype._loadClipAsync = function (context, clip) { + if (clip._objectURL) { + return clip._objectURL; + } + var promise; + if (clip.uri) { + promise = this._loader.loadUriAsync(context, clip, clip.uri); + } + else { + var bufferView = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("".concat(context, "/bufferView"), this._loader.gltf.bufferViews, clip.bufferView); + promise = this._loader.loadBufferViewAsync("/bufferViews/".concat(bufferView.index), bufferView); + } + clip._objectURL = promise.then(function (data) { + return URL.createObjectURL(new Blob([data], { type: clip.mimeType })); + }); + return clip._objectURL; + }; + MSFT_audio_emitter.prototype._loadEmitterAsync = function (context, emitter) { + var _this = this; + emitter._babylonSounds = emitter._babylonSounds || []; + if (!emitter._babylonData) { + var clipPromises = new Array(); + var name_1 = emitter.name || "emitter".concat(emitter.index); + var options_1 = { + loop: false, + autoplay: false, + volume: emitter.volume == undefined ? 1 : emitter.volume, + }; + var _loop_2 = function (i) { + var clipContext = "/extensions/".concat(this_1.name, "/clips"); + var clip = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get(clipContext, this_1._clips, emitter.clips[i].clip); + clipPromises.push(this_1._loadClipAsync("".concat(clipContext, "/").concat(emitter.clips[i].clip), clip).then(function (objectURL) { + var sound = (emitter._babylonSounds[i] = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Sound(name_1, objectURL, _this._loader.babylonScene, null, options_1)); + sound.refDistance = emitter.refDistance || 1; + sound.maxDistance = emitter.maxDistance || 256; + sound.rolloffFactor = emitter.rolloffFactor || 1; + sound.distanceModel = emitter.distanceModel || "exponential"; + })); + }; + var this_1 = this; + for (var i = 0; i < emitter.clips.length; i++) { + _loop_2(i); + } + var promise = Promise.all(clipPromises).then(function () { + var weights = emitter.clips.map(function (clip) { + return clip.weight || 1; + }); + var weightedSound = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.WeightedSound(emitter.loop || false, emitter._babylonSounds, weights); + if (emitter.innerAngle) { + weightedSound.directionalConeInnerAngle = 2 * babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.ToDegrees(emitter.innerAngle); + } + if (emitter.outerAngle) { + weightedSound.directionalConeOuterAngle = 2 * babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.ToDegrees(emitter.outerAngle); + } + if (emitter.volume) { + weightedSound.volume = emitter.volume; + } + emitter._babylonData.sound = weightedSound; + }); + emitter._babylonData = { + loaded: promise, + }; + } + return emitter._babylonData.loaded; + }; + MSFT_audio_emitter.prototype._getEventAction = function (context, sound, action, time, startOffset) { + switch (action) { + case "play" /* IMSFTAudioEmitter_AnimationEventAction.play */: { + return function (currentFrame) { + var frameOffset = (startOffset || 0) + (currentFrame - time); + sound.play(frameOffset); + }; + } + case "stop" /* IMSFTAudioEmitter_AnimationEventAction.stop */: { + return function () { + sound.stop(); + }; + } + case "pause" /* IMSFTAudioEmitter_AnimationEventAction.pause */: { + return function () { + sound.pause(); + }; + } + default: { + throw new Error("".concat(context, ": Unsupported action ").concat(action)); + } + } + }; + MSFT_audio_emitter.prototype._loadAnimationEventAsync = function (context, animationContext, animation, event, babylonAnimationGroup) { + var _this = this; + if (babylonAnimationGroup.targetedAnimations.length == 0) { + return Promise.resolve(); + } + var babylonAnimation = babylonAnimationGroup.targetedAnimations[0]; + var emitterIndex = event.emitter; + var emitter = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("/extensions/".concat(this.name, "/emitters"), this._emitters, emitterIndex); + return this._loadEmitterAsync(context, emitter).then(function () { + var sound = emitter._babylonData.sound; + if (sound) { + var babylonAnimationEvent = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.AnimationEvent(event.time, _this._getEventAction(context, sound, event.action, event.time, event.startOffset)); + babylonAnimation.animation.addEvent(babylonAnimationEvent); + // Make sure all started audio stops when this animation is terminated. + babylonAnimationGroup.onAnimationGroupEndObservable.add(function () { + sound.stop(); + }); + babylonAnimationGroup.onAnimationGroupPauseObservable.add(function () { + sound.pause(); + }); + } + }); + }; + return MSFT_audio_emitter; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new MSFT_audio_emitter(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_lod.ts": +/*!****************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_lod.ts ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ MSFT_lod: () => (/* binding */ MSFT_lod) +/* harmony export */ }); +/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/deferred */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "MSFT_lod"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/MSFT_lod/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var MSFT_lod = /** @class */ (function () { + /** + * @internal + */ + function MSFT_lod(loader) { + var _a, _b; + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 100; + /** + * Maximum number of LODs to load, starting from the lowest LOD. + */ + this.maxLODsToLoad = 10; + /** + * Observable raised when all node LODs of one level are loaded. + * The event data is the index of the loaded LOD starting from zero. + * Dispose the loader to cancel the loading of the next level of LODs. + */ + this.onNodeLODsLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when all material LODs of one level are loaded. + * The event data is the index of the loaded LOD starting from zero. + * Dispose the loader to cancel the loading of the next level of LODs. + */ + this.onMaterialLODsLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + this._bufferLODs = new Array(); + this._nodeIndexLOD = null; + this._nodeSignalLODs = new Array(); + this._nodePromiseLODs = new Array(); + this._nodeBufferLODs = new Array(); + this._materialIndexLOD = null; + this._materialSignalLODs = new Array(); + this._materialPromiseLODs = new Array(); + this._materialBufferLODs = new Array(); + this._loader = loader; + // Options takes precedence. The maxLODsToLoad extension property is retained for back compat. + // For new extensions, they should only use options. + this.maxLODsToLoad = (_b = (_a = this._loader.parent.extensionOptions[NAME]) === null || _a === void 0 ? void 0 : _a.maxLODsToLoad) !== null && _b !== void 0 ? _b : this.maxLODsToLoad; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + MSFT_lod.prototype.dispose = function () { + this._loader = null; + this._nodeIndexLOD = null; + this._nodeSignalLODs.length = 0; + this._nodePromiseLODs.length = 0; + this._nodeBufferLODs.length = 0; + this._materialIndexLOD = null; + this._materialSignalLODs.length = 0; + this._materialPromiseLODs.length = 0; + this._materialBufferLODs.length = 0; + this.onMaterialLODsLoadedObservable.clear(); + this.onNodeLODsLoadedObservable.clear(); + }; + /** @internal */ + MSFT_lod.prototype.onReady = function () { + var _this = this; + var _loop_1 = function (indexLOD) { + var promise = Promise.all(this_1._nodePromiseLODs[indexLOD]).then(function () { + if (indexLOD !== 0) { + _this._loader.endPerformanceCounter("Node LOD ".concat(indexLOD)); + _this._loader.log("Loaded node LOD ".concat(indexLOD)); + } + _this.onNodeLODsLoadedObservable.notifyObservers(indexLOD); + if (indexLOD !== _this._nodePromiseLODs.length - 1) { + _this._loader.startPerformanceCounter("Node LOD ".concat(indexLOD + 1)); + _this._loadBufferLOD(_this._nodeBufferLODs, indexLOD + 1); + if (_this._nodeSignalLODs[indexLOD]) { + _this._nodeSignalLODs[indexLOD].resolve(); + } + } + }); + this_1._loader._completePromises.push(promise); + }; + var this_1 = this; + for (var indexLOD = 0; indexLOD < this._nodePromiseLODs.length; indexLOD++) { + _loop_1(indexLOD); + } + var _loop_2 = function (indexLOD) { + var promise = Promise.all(this_2._materialPromiseLODs[indexLOD]).then(function () { + if (indexLOD !== 0) { + _this._loader.endPerformanceCounter("Material LOD ".concat(indexLOD)); + _this._loader.log("Loaded material LOD ".concat(indexLOD)); + } + _this.onMaterialLODsLoadedObservable.notifyObservers(indexLOD); + if (indexLOD !== _this._materialPromiseLODs.length - 1) { + _this._loader.startPerformanceCounter("Material LOD ".concat(indexLOD + 1)); + _this._loadBufferLOD(_this._materialBufferLODs, indexLOD + 1); + if (_this._materialSignalLODs[indexLOD]) { + _this._materialSignalLODs[indexLOD].resolve(); + } + } + }); + this_2._loader._completePromises.push(promise); + }; + var this_2 = this; + for (var indexLOD = 0; indexLOD < this._materialPromiseLODs.length; indexLOD++) { + _loop_2(indexLOD); + } + }; + /** + * @internal + */ + MSFT_lod.prototype.loadSceneAsync = function (context, scene) { + var promise = this._loader.loadSceneAsync(context, scene); + this._loadBufferLOD(this._bufferLODs, 0); + return promise; + }; + /** + * @internal + */ + MSFT_lod.prototype.loadNodeAsync = function (context, node, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) { + var firstPromise; + var nodeLODs = _this._getLODs(extensionContext, node, _this._loader.gltf.nodes, extension.ids); + _this._loader.logOpen("".concat(extensionContext)); + var _loop_3 = function (indexLOD) { + var nodeLOD = nodeLODs[indexLOD]; + if (indexLOD !== 0) { + _this._nodeIndexLOD = indexLOD; + _this._nodeSignalLODs[indexLOD] = _this._nodeSignalLODs[indexLOD] || new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Deferred(); + } + var assignWrap = function (babylonTransformNode) { + assign(babylonTransformNode); + babylonTransformNode.setEnabled(false); + }; + var promise = _this._loader.loadNodeAsync("/nodes/".concat(nodeLOD.index), nodeLOD, assignWrap).then(function (babylonMesh) { + if (indexLOD !== 0) { + // TODO: should not rely on _babylonTransformNode + var previousNodeLOD = nodeLODs[indexLOD - 1]; + if (previousNodeLOD._babylonTransformNode) { + _this._disposeTransformNode(previousNodeLOD._babylonTransformNode); + delete previousNodeLOD._babylonTransformNode; + } + } + babylonMesh.setEnabled(true); + return babylonMesh; + }); + _this._nodePromiseLODs[indexLOD] = _this._nodePromiseLODs[indexLOD] || []; + if (indexLOD === 0) { + firstPromise = promise; + } + else { + _this._nodeIndexLOD = null; + _this._nodePromiseLODs[indexLOD].push(promise); + } + }; + for (var indexLOD = 0; indexLOD < nodeLODs.length; indexLOD++) { + _loop_3(indexLOD); + } + _this._loader.logClose(); + return firstPromise; + }); + }; + /** + * @internal + */ + MSFT_lod.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) { + var _this = this; + // Don't load material LODs if already loading a node LOD. + if (this._nodeIndexLOD) { + return null; + } + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var firstPromise; + var materialLODs = _this._getLODs(extensionContext, material, _this._loader.gltf.materials, extension.ids); + _this._loader.logOpen("".concat(extensionContext)); + var _loop_4 = function (indexLOD) { + var materialLOD = materialLODs[indexLOD]; + if (indexLOD !== 0) { + _this._materialIndexLOD = indexLOD; + } + var promise = _this._loader + ._loadMaterialAsync("/materials/".concat(materialLOD.index), materialLOD, babylonMesh, babylonDrawMode, function (babylonMaterial) { + if (indexLOD === 0) { + assign(babylonMaterial); + } + }) + .then(function (babylonMaterial) { + if (indexLOD !== 0) { + assign(babylonMaterial); + // TODO: should not rely on _data + var previousDataLOD = materialLODs[indexLOD - 1]._data; + if (previousDataLOD[babylonDrawMode]) { + _this._disposeMaterials([previousDataLOD[babylonDrawMode].babylonMaterial]); + delete previousDataLOD[babylonDrawMode]; + } + } + return babylonMaterial; + }); + _this._materialPromiseLODs[indexLOD] = _this._materialPromiseLODs[indexLOD] || []; + if (indexLOD === 0) { + firstPromise = promise; + } + else { + _this._materialIndexLOD = null; + _this._materialPromiseLODs[indexLOD].push(promise); + } + }; + for (var indexLOD = 0; indexLOD < materialLODs.length; indexLOD++) { + _loop_4(indexLOD); + } + _this._loader.logClose(); + return firstPromise; + }); + }; + /** + * @internal + */ + MSFT_lod.prototype._loadUriAsync = function (context, property, uri) { + var _this = this; + // Defer the loading of uris if loading a node or material LOD. + if (this._nodeIndexLOD !== null) { + this._loader.log("deferred"); + var previousIndexLOD = this._nodeIndexLOD - 1; + this._nodeSignalLODs[previousIndexLOD] = this._nodeSignalLODs[previousIndexLOD] || new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Deferred(); + return this._nodeSignalLODs[this._nodeIndexLOD - 1].promise.then(function () { + return _this._loader.loadUriAsync(context, property, uri); + }); + } + else if (this._materialIndexLOD !== null) { + this._loader.log("deferred"); + var previousIndexLOD = this._materialIndexLOD - 1; + this._materialSignalLODs[previousIndexLOD] = this._materialSignalLODs[previousIndexLOD] || new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Deferred(); + return this._materialSignalLODs[previousIndexLOD].promise.then(function () { + return _this._loader.loadUriAsync(context, property, uri); + }); + } + return null; + }; + /** + * @internal + */ + MSFT_lod.prototype.loadBufferAsync = function (context, buffer, byteOffset, byteLength) { + if (this._loader.parent.useRangeRequests && !buffer.uri) { + if (!this._loader.bin) { + throw new Error("".concat(context, ": Uri is missing or the binary glTF is missing its binary chunk")); + } + var loadAsync = function (bufferLODs, indexLOD) { + var start = byteOffset; + var end = start + byteLength - 1; + var bufferLOD = bufferLODs[indexLOD]; + if (bufferLOD) { + bufferLOD.start = Math.min(bufferLOD.start, start); + bufferLOD.end = Math.max(bufferLOD.end, end); + } + else { + bufferLOD = { start: start, end: end, loaded: new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Deferred() }; + bufferLODs[indexLOD] = bufferLOD; + } + return bufferLOD.loaded.promise.then(function (data) { + return new Uint8Array(data.buffer, data.byteOffset + byteOffset - bufferLOD.start, byteLength); + }); + }; + this._loader.log("deferred"); + if (this._nodeIndexLOD !== null) { + return loadAsync(this._nodeBufferLODs, this._nodeIndexLOD); + } + else if (this._materialIndexLOD !== null) { + return loadAsync(this._materialBufferLODs, this._materialIndexLOD); + } + else { + return loadAsync(this._bufferLODs, 0); + } + } + return null; + }; + MSFT_lod.prototype._loadBufferLOD = function (bufferLODs, indexLOD) { + var bufferLOD = bufferLODs[indexLOD]; + if (bufferLOD) { + this._loader.log("Loading buffer range [".concat(bufferLOD.start, "-").concat(bufferLOD.end, "]")); + this._loader.bin.readAsync(bufferLOD.start, bufferLOD.end - bufferLOD.start + 1).then(function (data) { + bufferLOD.loaded.resolve(data); + }, function (error) { + bufferLOD.loaded.reject(error); + }); + } + }; + /** + * @returns an array of LOD properties from lowest to highest. + * @param context + * @param property + * @param array + * @param ids + */ + MSFT_lod.prototype._getLODs = function (context, property, array, ids) { + if (this.maxLODsToLoad <= 0) { + throw new Error("maxLODsToLoad must be greater than zero"); + } + var properties = []; + for (var i = ids.length - 1; i >= 0; i--) { + properties.push(_glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("".concat(context, "/ids/").concat(ids[i]), array, ids[i])); + if (properties.length === this.maxLODsToLoad) { + return properties; + } + } + properties.push(property); + return properties; + }; + MSFT_lod.prototype._disposeTransformNode = function (babylonTransformNode) { + var _this = this; + var babylonMaterials = []; + var babylonMaterial = babylonTransformNode.material; + if (babylonMaterial) { + babylonMaterials.push(babylonMaterial); + } + for (var _i = 0, _a = babylonTransformNode.getChildMeshes(); _i < _a.length; _i++) { + var babylonMesh = _a[_i]; + if (babylonMesh.material) { + babylonMaterials.push(babylonMesh.material); + } + } + babylonTransformNode.dispose(); + var babylonMaterialsToDispose = babylonMaterials.filter(function (babylonMaterial) { return _this._loader.babylonScene.meshes.every(function (mesh) { return mesh.material != babylonMaterial; }); }); + this._disposeMaterials(babylonMaterialsToDispose); + }; + MSFT_lod.prototype._disposeMaterials = function (babylonMaterials) { + var babylonTextures = {}; + for (var _i = 0, babylonMaterials_1 = babylonMaterials; _i < babylonMaterials_1.length; _i++) { + var babylonMaterial = babylonMaterials_1[_i]; + for (var _a = 0, _b = babylonMaterial.getActiveTextures(); _a < _b.length; _a++) { + var babylonTexture = _b[_a]; + babylonTextures[babylonTexture.uniqueId] = babylonTexture; + } + babylonMaterial.dispose(); + } + for (var uniqueId in babylonTextures) { + for (var _c = 0, _d = this._loader.babylonScene.materials; _c < _d.length; _c++) { + var babylonMaterial = _d[_c]; + if (babylonMaterial.hasTexture(babylonTextures[uniqueId])) { + delete babylonTextures[uniqueId]; + } + } + } + for (var uniqueId in babylonTextures) { + babylonTextures[uniqueId].dispose(); + } + }; + return MSFT_lod; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new MSFT_lod(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_minecraftMesh.ts": +/*!**************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_minecraftMesh.ts ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ MSFT_minecraftMesh: () => (/* binding */ MSFT_minecraftMesh) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "MSFT_minecraftMesh"; +/** @internal */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var MSFT_minecraftMesh = /** @class */ (function () { + /** @internal */ + function MSFT_minecraftMesh(loader) { + /** @internal */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + MSFT_minecraftMesh.prototype.dispose = function () { + this._loader = null; + }; + /** @internal */ + MSFT_minecraftMesh.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtraAsync(context, material, this.name, function (extraContext, extra) { + if (extra) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(extraContext, ": Material type not supported")); + } + var promise = _this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial); + if (babylonMaterial.needAlphaBlending()) { + babylonMaterial.forceDepthWrite = true; + babylonMaterial.separateCullingPass = true; + } + babylonMaterial.backFaceCulling = babylonMaterial.forceDepthWrite; + babylonMaterial.twoSidedLighting = true; + return promise; + } + return null; + }); + }; + return MSFT_minecraftMesh; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new MSFT_minecraftMesh(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts": +/*!************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ MSFT_sRGBFactors: () => (/* binding */ MSFT_sRGBFactors) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "MSFT_sRGBFactors"; +/** @internal */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var MSFT_sRGBFactors = /** @class */ (function () { + /** @internal */ + function MSFT_sRGBFactors(loader) { + /** @internal */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + MSFT_sRGBFactors.prototype.dispose = function () { + this._loader = null; + }; + /** @internal */ + MSFT_sRGBFactors.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtraAsync(context, material, this.name, function (extraContext, extra) { + if (extra) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(extraContext, ": Material type not supported")); + } + var promise = _this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial); + var useExactSrgbConversions = babylonMaterial.getScene().getEngine().useExactSrgbConversions; + if (!babylonMaterial.albedoTexture) { + babylonMaterial.albedoColor.toLinearSpaceToRef(babylonMaterial.albedoColor, useExactSrgbConversions); + } + if (!babylonMaterial.reflectivityTexture) { + babylonMaterial.reflectivityColor.toLinearSpaceToRef(babylonMaterial.reflectivityColor, useExactSrgbConversions); + } + return promise; + } + return null; + }); + }; + return MSFT_sRGBFactors; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new MSFT_sRGBFactors(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/gltfPathToObjectConverter.ts": +/*!*********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/gltfPathToObjectConverter.ts ***! + \*********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFPathToObjectConverter: () => (/* binding */ GLTFPathToObjectConverter) +/* harmony export */ }); +/** + * A converter that takes a glTF Object Model JSON Pointer + * and transforms it into an ObjectAccessorContainer, allowing + * objects referenced in the glTF to be associated with their + * respective Babylon.js objects. + */ +var GLTFPathToObjectConverter = /** @class */ (function () { + function GLTFPathToObjectConverter(_gltf, _infoTree) { + this._gltf = _gltf; + this._infoTree = _infoTree; + } + /** + * The pointer string is represented by a [JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901). + * := /// + * := "nodes" | "materials" | "meshes" | "cameras" | "extensions" + * := | + * := | + * := "extensions"// + * := | / + * := W+ + * := D+ + * + * Examples: + * - "/nodes/0/rotation" + * - "/materials/2/emissiveFactor" + * - "/materials/2/pbrMetallicRoughness/baseColorFactor" + * - "/materials/2/extensions/KHR_materials_emissive_strength/emissiveStrength" + * + * @param path The path to convert + * @returns The object and info associated with the path + */ + GLTFPathToObjectConverter.prototype.convert = function (path) { + var objectTree = this._gltf; + var infoTree = this._infoTree; + var target = undefined; + if (!path.startsWith("/")) { + throw new Error("Path must start with a /"); + } + var parts = path.split("/"); + parts.shift(); + for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) { + var part = parts_1[_i]; + if (infoTree.__array__) { + infoTree = infoTree.__array__; + } + else { + infoTree = infoTree[part]; + if (!infoTree) { + throw new Error("Path ".concat(path, " is invalid")); + } + } + if (objectTree === undefined) { + throw new Error("Path ".concat(path, " is invalid")); + } + objectTree = objectTree[part]; + if (infoTree.__target__) { + target = objectTree; + } + } + return { + object: target, + info: infoTree, + }; + }; + return GLTFPathToObjectConverter; +}()); + + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/index.ts": +/*!*************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/index.ts ***! + \*************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_lights_image_based: () => (/* reexport safe */ _EXT_lights_image_based__WEBPACK_IMPORTED_MODULE_0__.EXT_lights_image_based), +/* harmony export */ EXT_mesh_gpu_instancing: () => (/* reexport safe */ _EXT_mesh_gpu_instancing__WEBPACK_IMPORTED_MODULE_1__.EXT_mesh_gpu_instancing), +/* harmony export */ EXT_meshopt_compression: () => (/* reexport safe */ _EXT_meshopt_compression__WEBPACK_IMPORTED_MODULE_2__.EXT_meshopt_compression), +/* harmony export */ EXT_texture_avif: () => (/* reexport safe */ _EXT_texture_avif__WEBPACK_IMPORTED_MODULE_4__.EXT_texture_avif), +/* harmony export */ EXT_texture_webp: () => (/* reexport safe */ _EXT_texture_webp__WEBPACK_IMPORTED_MODULE_3__.EXT_texture_webp), +/* harmony export */ ExtrasAsMetadata: () => (/* reexport safe */ _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_32__.ExtrasAsMetadata), +/* harmony export */ KHR_animation_pointer: () => (/* reexport safe */ _KHR_animation_pointer__WEBPACK_IMPORTED_MODULE_25__.KHR_animation_pointer), +/* harmony export */ KHR_draco_mesh_compression: () => (/* reexport safe */ _KHR_draco_mesh_compression__WEBPACK_IMPORTED_MODULE_5__.KHR_draco_mesh_compression), +/* harmony export */ KHR_interactivity: () => (/* reexport safe */ _KHR_interactivity__WEBPACK_IMPORTED_MODULE_30__.KHR_interactivity), +/* harmony export */ KHR_lights: () => (/* reexport safe */ _KHR_lights_punctual__WEBPACK_IMPORTED_MODULE_6__.KHR_lights), +/* harmony export */ KHR_materials_anisotropy: () => (/* reexport safe */ _KHR_materials_anisotropy__WEBPACK_IMPORTED_MODULE_11__.KHR_materials_anisotropy), +/* harmony export */ KHR_materials_clearcoat: () => (/* reexport safe */ _KHR_materials_clearcoat__WEBPACK_IMPORTED_MODULE_9__.KHR_materials_clearcoat), +/* harmony export */ KHR_materials_diffuse_transmission: () => (/* reexport safe */ _KHR_materials_diffuse_transmission__WEBPACK_IMPORTED_MODULE_18__.KHR_materials_diffuse_transmission), +/* harmony export */ KHR_materials_dispersion: () => (/* reexport safe */ _KHR_materials_dispersion__WEBPACK_IMPORTED_MODULE_20__.KHR_materials_dispersion), +/* harmony export */ KHR_materials_emissive_strength: () => (/* reexport safe */ _KHR_materials_emissive_strength__WEBPACK_IMPORTED_MODULE_12__.KHR_materials_emissive_strength), +/* harmony export */ KHR_materials_ior: () => (/* reexport safe */ _KHR_materials_ior__WEBPACK_IMPORTED_MODULE_15__.KHR_materials_ior), +/* harmony export */ KHR_materials_iridescence: () => (/* reexport safe */ _KHR_materials_iridescence__WEBPACK_IMPORTED_MODULE_10__.KHR_materials_iridescence), +/* harmony export */ KHR_materials_pbrSpecularGlossiness: () => (/* reexport safe */ _KHR_materials_pbrSpecularGlossiness__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_pbrSpecularGlossiness), +/* harmony export */ KHR_materials_sheen: () => (/* reexport safe */ _KHR_materials_sheen__WEBPACK_IMPORTED_MODULE_13__.KHR_materials_sheen), +/* harmony export */ KHR_materials_specular: () => (/* reexport safe */ _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_14__.KHR_materials_specular), +/* harmony export */ KHR_materials_transmission: () => (/* reexport safe */ _KHR_materials_transmission__WEBPACK_IMPORTED_MODULE_17__.KHR_materials_transmission), +/* harmony export */ KHR_materials_unlit: () => (/* reexport safe */ _KHR_materials_unlit__WEBPACK_IMPORTED_MODULE_8__.KHR_materials_unlit), +/* harmony export */ KHR_materials_variants: () => (/* reexport safe */ _KHR_materials_variants__WEBPACK_IMPORTED_MODULE_16__.KHR_materials_variants), +/* harmony export */ KHR_materials_volume: () => (/* reexport safe */ _KHR_materials_volume__WEBPACK_IMPORTED_MODULE_19__.KHR_materials_volume), +/* harmony export */ KHR_mesh_quantization: () => (/* reexport safe */ _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_21__.KHR_mesh_quantization), +/* harmony export */ KHR_node_visibility: () => (/* reexport safe */ _KHR_node_visibility__WEBPACK_IMPORTED_MODULE_31__.KHR_node_visibility), +/* harmony export */ KHR_texture_basisu: () => (/* reexport safe */ _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_22__.KHR_texture_basisu), +/* harmony export */ KHR_texture_transform: () => (/* reexport safe */ _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_23__.KHR_texture_transform), +/* harmony export */ KHR_xmp_json_ld: () => (/* reexport safe */ _KHR_xmp_json_ld__WEBPACK_IMPORTED_MODULE_24__.KHR_xmp_json_ld), +/* harmony export */ MSFT_audio_emitter: () => (/* reexport safe */ _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_26__.MSFT_audio_emitter), +/* harmony export */ MSFT_lod: () => (/* reexport safe */ _MSFT_lod__WEBPACK_IMPORTED_MODULE_27__.MSFT_lod), +/* harmony export */ MSFT_minecraftMesh: () => (/* reexport safe */ _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_28__.MSFT_minecraftMesh), +/* harmony export */ MSFT_sRGBFactors: () => (/* reexport safe */ _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_29__.MSFT_sRGBFactors) +/* harmony export */ }); +/* harmony import */ var _EXT_lights_image_based__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./EXT_lights_image_based */ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_lights_image_based.ts"); +/* harmony import */ var _EXT_mesh_gpu_instancing__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./EXT_mesh_gpu_instancing */ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts"); +/* harmony import */ var _EXT_meshopt_compression__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./EXT_meshopt_compression */ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_meshopt_compression.ts"); +/* harmony import */ var _EXT_texture_webp__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./EXT_texture_webp */ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_texture_webp.ts"); +/* harmony import */ var _EXT_texture_avif__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./EXT_texture_avif */ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_texture_avif.ts"); +/* harmony import */ var _KHR_draco_mesh_compression__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./KHR_draco_mesh_compression */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts"); +/* harmony import */ var _KHR_lights_punctual__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./KHR_lights_punctual */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts"); +/* harmony import */ var _KHR_materials_pbrSpecularGlossiness__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./KHR_materials_pbrSpecularGlossiness */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts"); +/* harmony import */ var _KHR_materials_unlit__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_materials_unlit */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts"); +/* harmony import */ var _KHR_materials_clearcoat__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_materials_clearcoat */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts"); +/* harmony import */ var _KHR_materials_iridescence__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./KHR_materials_iridescence */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_iridescence.ts"); +/* harmony import */ var _KHR_materials_anisotropy__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./KHR_materials_anisotropy */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts"); +/* harmony import */ var _KHR_materials_emissive_strength__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./KHR_materials_emissive_strength */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_emissive_strength.ts"); +/* harmony import */ var _KHR_materials_sheen__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./KHR_materials_sheen */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_sheen.ts"); +/* harmony import */ var _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./KHR_materials_specular */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_specular.ts"); +/* harmony import */ var _KHR_materials_ior__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./KHR_materials_ior */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_ior.ts"); +/* harmony import */ var _KHR_materials_variants__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./KHR_materials_variants */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_variants.ts"); +/* harmony import */ var _KHR_materials_transmission__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./KHR_materials_transmission */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_transmission.ts"); +/* harmony import */ var _KHR_materials_diffuse_transmission__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./KHR_materials_diffuse_transmission */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts"); +/* harmony import */ var _KHR_materials_volume__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./KHR_materials_volume */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts"); +/* harmony import */ var _KHR_materials_dispersion__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./KHR_materials_dispersion */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts"); +/* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_mesh_quantization.ts"); +/* harmony import */ var _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./KHR_texture_basisu */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_texture_basisu.ts"); +/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./KHR_texture_transform */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts"); +/* harmony import */ var _KHR_xmp_json_ld__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./KHR_xmp_json_ld */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_xmp_json_ld.ts"); +/* harmony import */ var _KHR_animation_pointer__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./KHR_animation_pointer */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_animation_pointer.ts"); +/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts"); +/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./MSFT_lod */ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_lod.ts"); +/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_minecraftMesh.ts"); +/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts"); +/* harmony import */ var _KHR_interactivity__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./KHR_interactivity */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_interactivity.ts"); +/* harmony import */ var _KHR_node_visibility__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./KHR_node_visibility */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_node_visibility.ts"); +/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "../../../dev/loaders/src/glTF/2.0/Extensions/ExtrasAsMetadata.ts"); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/interactivityFunctions.ts": +/*!******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/interactivityFunctions.ts ***! + \******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ convertGLTFToSerializedFlowGraph: () => (/* binding */ convertGLTFToSerializedFlowGraph) +/* harmony export */ }); +/* harmony import */ var babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/guid */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _interactivityUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./interactivityUtils */ "../../../dev/loaders/src/glTF/2.0/Extensions/interactivityUtils.ts"); + + +function convertValueWithType(configObject, definition, context) { + if (configObject.type !== undefined) { + // get the type on the gltf definition + var type = definition.types && definition.types[configObject.type]; + if (!type) { + throw new Error("".concat(context, ": Unknown type: ").concat(configObject.type)); + } + var signature = type.signature; + if (!signature) { + throw new Error("".concat(context, ": Type ").concat(configObject.type, " has no signature")); + } + var convertedType = _interactivityUtils__WEBPACK_IMPORTED_MODULE_1__.gltfTypeToBabylonType[signature]; + return { + value: configObject.value, + className: convertedType, + }; + } + else { + return configObject.value; + } +} +function convertConfiguration(gltfBlock, definition, id) { + var _a; + var converted = {}; + var configurationList = (_a = gltfBlock.configuration) !== null && _a !== void 0 ? _a : []; + for (var _i = 0, configurationList_1 = configurationList; _i < configurationList_1.length; _i++) { + var configObject = configurationList_1[_i]; + if (configObject.id === "customEvent") { + var customEvent = definition.customEvents && definition.customEvents[configObject.value]; + if (!customEvent) { + throw new Error("/extensions/KHR_interactivity/nodes/".concat(id, ": Unknown custom event: ").concat(configObject.value)); + } + converted.eventId = customEvent.id; + converted.eventData = customEvent.values.map(function (v) { return v.id; }); + } + else if (configObject.id === "variable") { + var variable = definition.variables && definition.variables[configObject.value]; + if (!variable) { + throw new Error("/extensions/KHR_interactivity/nodes/".concat(id, ": Unknown variable: ").concat(configObject.value)); + } + converted.variableName = variable.id; + } + else if (configObject.id === "path") { + // Convert from a GLTF path to a reference to the Babylon.js object + var pathValue = configObject.value; + converted.path = pathValue; + } + else { + converted[configObject.id] = convertValueWithType(configObject, definition, "/extensions/KHR_interactivity/nodes/".concat(id)); + } + } + return converted; +} +function convertBlock(id, gltfBlock, definition) { + var className = _interactivityUtils__WEBPACK_IMPORTED_MODULE_1__.gltfToFlowGraphTypeMap[gltfBlock.type]; + if (!className) { + throw new Error("/extensions/KHR_interactivity/nodes/".concat(id, ": Unknown block type: ").concat(gltfBlock.type)); + } + var uniqueId = id.toString(); + var config = convertConfiguration(gltfBlock, definition, uniqueId); + var metadata = gltfBlock.metadata; + var dataInputs = []; + var dataOutputs = []; + var signalInputs = []; + var signalOutputs = []; + return { + className: className, + config: config, + uniqueId: uniqueId, + metadata: metadata, + dataInputs: dataInputs, + dataOutputs: dataOutputs, + signalInputs: signalInputs, + signalOutputs: signalOutputs, + }; +} +/** + * @internal + * Converts a glTF Interactivity Extension to a serialized flow graph. + * @param gltf the interactivity data + * @returns a serialized flow graph + */ +function convertGLTFToSerializedFlowGraph(gltf) { + var _a, _b, _c; + // create an empty serialized context to store the values of the connections + var context = { + uniqueId: (0,babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__.RandomGUID)(), + _userVariables: {}, + _connectionValues: {}, + }; + var executionContexts = [context]; + // Blocks converted to the flow graph json format + var flowGraphJsonBlocks = []; + for (var i = 0; i < gltf.nodes.length; i++) { + var gltfBlock = gltf.nodes[i]; + var flowGraphJsonBlock = convertBlock(i, gltfBlock, gltf); + flowGraphJsonBlocks.push(flowGraphJsonBlock); + } + // Parse the connections + for (var i = 0; i < gltf.nodes.length; i++) { + var gltfBlock = gltf.nodes[i]; + // get the block that was created in the previous step + var fgBlock = flowGraphJsonBlocks[i]; + var gltfFlows = (_a = gltfBlock.flows) !== null && _a !== void 0 ? _a : []; + var _loop_1 = function (flow) { + var socketOutName = flow.id; + // create an output connection for the flow graph block + var socketOut = { + uniqueId: (0,babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__.RandomGUID)(), + name: socketOutName, + _connectionType: 1 /* FlowGraphConnectionType.Output */, // Output + connectedPointIds: [], + }; + fgBlock.signalOutputs.push(socketOut); + // get the input node of this flow + var nodeInId = flow.node; + var nodeInSocketName = flow.socket; + // find the corresponding flow graph node + var nodeIn = flowGraphJsonBlocks[nodeInId]; + if (!nodeIn) { + throw new Error("/extensions/KHR_interactivity/nodes/".concat(i, ": Could not find node with id ").concat(nodeInId, " that connects its input with with node ").concat(i, "'s output ").concat(socketOutName)); + } + // in all of the flow graph input connections, find the one with the same name as the socket + var socketIn = nodeIn.signalInputs.find(function (s) { return s.name === nodeInSocketName; }); + // if the socket doesn't exist, create the input socket for the connection + if (!socketIn) { + socketIn = { + uniqueId: (0,babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__.RandomGUID)(), + name: nodeInSocketName, + _connectionType: 0 /* FlowGraphConnectionType.Input */, // Input + connectedPointIds: [], + }; + nodeIn.signalInputs.push(socketIn); + } + // connect the sockets + socketIn.connectedPointIds.push(socketOut.uniqueId); + socketOut.connectedPointIds.push(socketIn.uniqueId); + }; + // for each output flow of the gltf block + for (var _i = 0, gltfFlows_1 = gltfFlows; _i < gltfFlows_1.length; _i++) { + var flow = gltfFlows_1[_i]; + _loop_1(flow); + } + // for each input value of the gltf block + var gltfValues = (_b = gltfBlock.values) !== null && _b !== void 0 ? _b : []; + var _loop_2 = function (value) { + var socketInName = value.id; + // create an input data connection for the flow graph block + var socketIn = { + uniqueId: (0,babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__.RandomGUID)(), + name: socketInName, + _connectionType: 0 /* FlowGraphConnectionType.Input */, + connectedPointIds: [], + }; + fgBlock.dataInputs.push(socketIn); + if (value.value !== undefined) { + // if the value is set on the socket itself, store it in the context + var convertedValue = convertValueWithType(value, gltf, "/extensions/KHR_interactivity/nodes/".concat(i)); + // convertBlockInputType(gltfBlock, value, convertedValue, `/extensions/KHR_interactivity/nodes/${i}`); + context._connectionValues[socketIn.uniqueId] = convertedValue; + } + else if (value.node !== undefined && value.socket !== undefined) { + // if the value is connected with the output data of another socket, connect the two + var nodeOutId = value.node; + var nodeOutSocketName_1 = value.socket; + // find the flow graph node that owns that output socket + var nodeOut = flowGraphJsonBlocks[nodeOutId]; + if (!nodeOut) { + throw new Error("/extensions/KHR_interactivity/nodes/".concat(i, ": Could not find node with id ").concat(nodeOutId, " that connects its output with node").concat(i, "'s input ").concat(socketInName)); + } + var socketOut = nodeOut.dataOutputs.find(function (s) { return s.name === nodeOutSocketName_1; }); + // if the socket doesn't exist, create it + if (!socketOut) { + socketOut = { + uniqueId: (0,babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__.RandomGUID)(), + name: nodeOutSocketName_1, + _connectionType: 1 /* FlowGraphConnectionType.Output */, + connectedPointIds: [], + }; + nodeOut.dataOutputs.push(socketOut); + } + // connect the sockets + socketIn.connectedPointIds.push(socketOut.uniqueId); + socketOut.connectedPointIds.push(socketIn.uniqueId); + } + else { + throw new Error("/extensions/KHR_interactivity/nodes/".concat(i, ": Invalid socket ").concat(socketInName, " in node ").concat(i)); + } + }; + for (var _d = 0, gltfValues_1 = gltfValues; _d < gltfValues_1.length; _d++) { + var value = gltfValues_1[_d]; + _loop_2(value); + } + } + var variables = (_c = gltf.variables) !== null && _c !== void 0 ? _c : []; + // Parse variables + for (var i = 0; i < variables.length; i++) { + var variable = variables[i]; + var variableName = variable.id; + context._userVariables[variableName] = convertValueWithType(variable, gltf, "/extensions/KHR_interactivity/variables/".concat(i)); + } + return { + allBlocks: flowGraphJsonBlocks, + executionContexts: executionContexts, + }; +} + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/interactivityPathToObjectConverter.ts": +/*!******************************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/interactivityPathToObjectConverter.ts ***! + \******************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ InteractivityPathToObjectConverter: () => (/* binding */ InteractivityPathToObjectConverter) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var _gltfPathToObjectConverter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./gltfPathToObjectConverter */ "../../../dev/loaders/src/glTF/2.0/Extensions/gltfPathToObjectConverter.ts"); + + +/** + * Class to convert an interactivity pointer path to a smart object + */ +var InteractivityPathToObjectConverter = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__extends)(InteractivityPathToObjectConverter, _super); + function InteractivityPathToObjectConverter(gltf) { + return _super.call(this, gltf, gltfTree) || this; + } + return InteractivityPathToObjectConverter; +}(_gltfPathToObjectConverter__WEBPACK_IMPORTED_MODULE_0__.GLTFPathToObjectConverter)); + +var nodesTree = { + __array__: { + __target__: true, + translation: { + type: "Vector3", + get: function (node) { + var babylonObject = node._babylonTransformNode; + return babylonObject.position; + }, + set: function (value, node) { + var babylonObject = node._babylonTransformNode; + babylonObject.position = value; + }, + getObject: function (node) { + return node._babylonTransformNode; + }, + }, + }, +}; +var gltfTree = { + nodes: nodesTree, +}; + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/interactivityUtils.ts": +/*!**************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/interactivityUtils.ts ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ gltfToFlowGraphTypeMap: () => (/* binding */ gltfToFlowGraphTypeMap), +/* harmony export */ gltfTypeToBabylonType: () => (/* binding */ gltfTypeToBabylonType) +/* harmony export */ }); +/* harmony import */ var babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/FlowGraph/Blocks/Execution/ControlFlow/flowGraphWhileLoopBlock */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__); +/* eslint-disable @typescript-eslint/naming-convention */ + + + + + + + + + + + + + + +var gltfToFlowGraphTypeMap = { + "lifecycle/onStart": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSceneReadyEventBlock.ClassName, + "lifecycle/onTick": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSceneTickEventBlock.ClassName, + log: babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphConsoleLogBlock.ClassName, + "flow/delay": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphTimerBlock.ClassName, + "customEvent/send": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSendCustomEventBlock.ClassName, + "customEvent/receive": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphReceiveCustomEventBlock.ClassName, + "flow/sequence": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSequenceBlock.ClassName, + "world/get": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphGetPropertyBlock.ClassName, + "world/set": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSetPropertyBlock.ClassName, + "flow/doN": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphDoNBlock.ClassName, + "variable/get": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphGetVariableBlock.ClassName, + "variable/set": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSetVariableBlock.ClassName, + "flow/whileLoop": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphWhileLoopBlock.ClassName, + "math/random": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphRandomBlock.ClassName, + "math/e": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphEBlock.ClassName, + "math/pi": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphPiBlock.ClassName, + "math/inf": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphInfBlock.ClassName, + "math/nan": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphNaNBlock.ClassName, + "math/abs": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAbsBlock.ClassName, + "math/sign": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSignBlock.ClassName, + "math/trunc": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphTruncBlock.ClassName, + "math/floor": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphFloorBlock.ClassName, + "math/ceil": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCeilBlock.ClassName, + "math/fract": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphFractBlock.ClassName, + "math/neg": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphNegBlock.ClassName, + "math/add": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAddBlock.ClassName, + "math/sub": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSubtractBlock.ClassName, + "math/mul": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphMultiplyBlock.ClassName, + "math/div": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphDivideBlock.ClassName, + "math/rem": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphRemainderBlock.ClassName, + "math/min": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphMinBlock.ClassName, + "math/max": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphMaxBlock.ClassName, + "math/clamp": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphClampBlock.ClassName, + "math/saturate": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSaturateBlock.ClassName, + "math/mix": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphInterpolateBlock.ClassName, + "math/eq": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphEqBlock.ClassName, + "math/lt": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphLessThanBlock.ClassName, + "math/le": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphLessThanOrEqualBlock.ClassName, + "math/gt": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphGreaterThanBlock.ClassName, + "math/ge": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphGreaterThanOrEqualBlock.ClassName, + "math/isnan": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphIsNanBlock.ClassName, + "math/isinf": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphIsInfBlock.ClassName, + "math/rad": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphDegToRadBlock.ClassName, + "math/deg": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphRadToDegBlock.ClassName, + "math/sin": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSinBlock.ClassName, + "math/cos": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCosBlock.ClassName, + "math/tan": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphTanBlock.ClassName, + "math/asin": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAsinBlock.ClassName, + "math/acos": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAcosBlock.ClassName, + "math/atan": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAtanBlock.ClassName, + "math/atan2": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAtan2Block.ClassName, + "math/sinh": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSinhBlock.ClassName, + "math/cosh": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCoshBlock.ClassName, + "math/tanh": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphTanhBlock.ClassName, + "math/asinh": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAsinhBlock.ClassName, + "math/acosh": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAcoshBlock.ClassName, + "math/atanh": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAtanhBlock.ClassName, + "math/exp": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphExpBlock.ClassName, + "math/log": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphLogBlock.ClassName, + "math/log2": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphLog2Block.ClassName, + "math/log10": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphLog10Block.ClassName, + "math/sqrt": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSqrtBlock.ClassName, + "math/cbrt": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCubeRootBlock.ClassName, + "math/pow": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphPowBlock.ClassName, + "math/length": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphLengthBlock.ClassName, + "math/normalize": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphNormalizeBlock.ClassName, + "math/dot": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphDotBlock.ClassName, + "math/cross": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCrossBlock.ClassName, + "math/rotate2d": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphRotate2DBlock.ClassName, + "math/rotate3d": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphRotate3DBlock.ClassName, + "math/transpose": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphTransposeBlock.ClassName, + "math/determinant": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphDeterminantBlock.ClassName, + "math/inverse": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphInvertMatrixBlock.ClassName, + "math/matmul": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphMatMulBlock.ClassName, + "math/not": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphBitwiseNotBlock.ClassName, + "math/and": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphBitwiseAndBlock.ClassName, + "math/or": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphBitwiseOrBlock.ClassName, + "math/xor": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphBitwiseXorBlock.ClassName, + "math/asr": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphBitwiseRightShiftBlock.ClassName, + "math/lsl": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphBitwiseLeftShiftBlock.ClassName, + "math/clz": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCountLeadingZerosBlock.ClassName, + "math/ctz": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCountTrailingZerosBlock.ClassName, + "math/popcnt": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCountOneBitsBlock.ClassName, +}; +var gltfTypeToBabylonType = { + float2: "Vector2", + float3: "Vector3", + float4: "Vector4", + float4x4: "Matrix", + int: "FlowGraphInteger", +}; + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts": +/*!*******************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/glTFLoader.ts ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ ArrayItem: () => (/* binding */ ArrayItem), +/* harmony export */ GLTFFileLoader: () => (/* reexport safe */ _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFFileLoader), +/* harmony export */ GLTFLoader: () => (/* binding */ GLTFLoader) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Culling/boundingInfo */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFFileLoader */ "../../../dev/loaders/src/glTF/glTFFileLoader.ts"); +/* harmony import */ var _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glTFLoaderAnimation */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderAnimation.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + + + + + + + + + + + + + + + + + + + + + + +// https://stackoverflow.com/a/48218209 +function mergeDeep() { + var objects = []; + for (var _i = 0; _i < arguments.length; _i++) { + objects[_i] = arguments[_i]; + } + var isObject = function (obj) { return obj && typeof obj === "object"; }; + return objects.reduce(function (prev, obj) { + Object.keys(obj).forEach(function (key) { + var pVal = prev[key]; + var oVal = obj[key]; + if (Array.isArray(pVal) && Array.isArray(oVal)) { + prev[key] = pVal.concat.apply(pVal, oVal); + } + else if (isObject(pVal) && isObject(oVal)) { + prev[key] = mergeDeep(pVal, oVal); + } + else { + prev[key] = oVal; + } + }); + return prev; + }, {}); +} +/** + * Helper class for working with arrays when loading the glTF asset + */ +var ArrayItem = /** @class */ (function () { + function ArrayItem() { + } + /** + * Gets an item from the given array. + * @param context The context when loading the asset + * @param array The array to get the item from + * @param index The index to the array + * @returns The array item + */ + ArrayItem.Get = function (context, array, index) { + if (!array || index == undefined || !array[index]) { + throw new Error("".concat(context, ": Failed to find index (").concat(index, ")")); + } + return array[index]; + }; + /** + * Gets an item from the given array or returns null if not available. + * @param array The array to get the item from + * @param index The index to the array + * @returns The array item or null + */ + ArrayItem.TryGet = function (array, index) { + if (!array || index == undefined || !array[index]) { + return null; + } + return array[index]; + }; + /** + * Assign an `index` field to each item of the given array. + * @param array The array of items + */ + ArrayItem.Assign = function (array) { + if (array) { + for (var index = 0; index < array.length; index++) { + array[index].index = index; + } + } + }; + return ArrayItem; +}()); + +/** + * The glTF 2.0 loader + */ +var GLTFLoader = /** @class */ (function () { + /** + * @internal + */ + function GLTFLoader(parent) { + /** @internal */ + this._completePromises = new Array(); + /** @internal */ + this._assetContainer = null; + /** Storage */ + this._babylonLights = []; + /** @internal */ + this._disableInstancedMesh = 0; + /** @internal */ + this._allMaterialsDirtyRequired = false; + this._extensions = new Array(); + this._disposed = false; + this._rootUrl = null; + this._fileName = null; + this._uniqueRootUrl = null; + this._bin = null; + this._rootBabylonMesh = null; + this._defaultBabylonMaterialData = {}; + this._postSceneLoadActions = new Array(); + this._parent = parent; + } + /** + * Registers a loader extension. + * @param name The name of the loader extension. + * @param factory The factory function that creates the loader extension. + * @deprecated Please use registerGLTFExtension instead. + */ + GLTFLoader.RegisterExtension = function (name, factory) { + (0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.registerGLTFExtension)(name, false, factory); + }; + /** + * Unregisters a loader extension. + * @param name The name of the loader extension. + * @returns A boolean indicating whether the extension has been unregistered + * @deprecated Please use unregisterGLTFExtension instead. + */ + GLTFLoader.UnregisterExtension = function (name) { + return (0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.unregisterGLTFExtension)(name); + }; + Object.defineProperty(GLTFLoader.prototype, "gltf", { + /** + * The object that represents the glTF JSON. + */ + get: function () { + if (!this._gltf) { + throw new Error("glTF JSON is not available"); + } + return this._gltf; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFLoader.prototype, "bin", { + /** + * The BIN chunk of a binary glTF. + */ + get: function () { + return this._bin; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFLoader.prototype, "parent", { + /** + * The parent file loader. + */ + get: function () { + return this._parent; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFLoader.prototype, "babylonScene", { + /** + * The Babylon scene when loading the asset. + */ + get: function () { + if (!this._babylonScene) { + throw new Error("Scene is not available"); + } + return this._babylonScene; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFLoader.prototype, "rootBabylonMesh", { + /** + * The root Babylon node when loading the asset. + */ + get: function () { + return this._rootBabylonMesh; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFLoader.prototype, "rootUrl", { + /** + * The root url when loading the asset. + */ + get: function () { + return this._rootUrl; + }, + enumerable: false, + configurable: true + }); + /** @internal */ + GLTFLoader.prototype.dispose = function () { + if (this._disposed) { + return; + } + this._disposed = true; + this._completePromises.length = 0; + this._extensions.forEach(function (extension) { return extension.dispose && extension.dispose(); }); + this._extensions.length = 0; + this._gltf = null; // TODO + this._bin = null; + this._babylonScene = null; // TODO + this._rootBabylonMesh = null; + this._defaultBabylonMaterialData = {}; + this._postSceneLoadActions.length = 0; + this._parent.dispose(); + }; + /** + * @internal + */ + GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, container, data, rootUrl, onProgress, fileName) { + var _this = this; + if (fileName === void 0) { fileName = ""; } + return Promise.resolve().then(function () { + _this._babylonScene = scene; + _this._assetContainer = container; + _this._loadData(data); + var nodes = null; + if (meshesNames) { + var nodeMap_1 = {}; + if (_this._gltf.nodes) { + for (var _i = 0, _a = _this._gltf.nodes; _i < _a.length; _i++) { + var node = _a[_i]; + if (node.name) { + nodeMap_1[node.name] = node.index; + } + } + } + var names = meshesNames instanceof Array ? meshesNames : [meshesNames]; + nodes = names.map(function (name) { + var node = nodeMap_1[name]; + if (node === undefined) { + throw new Error("Failed to find node '".concat(name, "'")); + } + return node; + }); + } + return _this._loadAsync(rootUrl, fileName, nodes, function () { + return { + meshes: _this._getMeshes(), + particleSystems: [], + skeletons: _this._getSkeletons(), + animationGroups: _this._getAnimationGroups(), + lights: _this._babylonLights, + transformNodes: _this._getTransformNodes(), + geometries: _this._getGeometries(), + spriteManagers: [], + }; + }); + }); + }; + /** + * @internal + */ + GLTFLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress, fileName) { + var _this = this; + if (fileName === void 0) { fileName = ""; } + return Promise.resolve().then(function () { + _this._babylonScene = scene; + _this._loadData(data); + return _this._loadAsync(rootUrl, fileName, null, function () { return undefined; }); + }); + }; + GLTFLoader.prototype._loadAsync = function (rootUrl, fileName, nodes, resultFunc) { + var _this = this; + return Promise.resolve() + .then(function () { return (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__awaiter)(_this, void 0, void 0, function () { + var loadingToReadyCounterName, loadingToCompleteCounterName, promises, oldBlockMaterialDirtyMechanism, scene, m, material, context_1, babylonDrawMode, resultPromise; + var _this = this; + return (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__generator)(this, function (_a) { + switch (_a.label) { + case 0: + this._rootUrl = rootUrl; + this._uniqueRootUrl = !rootUrl.startsWith("file:") && fileName ? rootUrl : "".concat(rootUrl).concat(Date.now(), "/"); + this._fileName = fileName; + this._allMaterialsDirtyRequired = false; + return [4 /*yield*/, this._loadExtensionsAsync()]; + case 1: + _a.sent(); + loadingToReadyCounterName = "".concat(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState[_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.LOADING], " => ").concat(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState[_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.READY]); + loadingToCompleteCounterName = "".concat(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState[_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.LOADING], " => ").concat(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState[_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.COMPLETE]); + this._parent._startPerformanceCounter(loadingToReadyCounterName); + this._parent._startPerformanceCounter(loadingToCompleteCounterName); + this._parent._setState(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.LOADING); + this._extensionsOnLoading(); + promises = new Array(); + oldBlockMaterialDirtyMechanism = this._babylonScene.blockMaterialDirtyMechanism; + this._babylonScene.blockMaterialDirtyMechanism = true; + if (!this.parent.loadOnlyMaterials) { + if (nodes) { + promises.push(this.loadSceneAsync("/nodes", { nodes: nodes, index: -1 })); + } + else if (this._gltf.scene != undefined || (this._gltf.scenes && this._gltf.scenes[0])) { + scene = ArrayItem.Get("/scene", this._gltf.scenes, this._gltf.scene || 0); + promises.push(this.loadSceneAsync("/scenes/".concat(scene.index), scene)); + } + } + if (!this.parent.skipMaterials && this.parent.loadAllMaterials && this._gltf.materials) { + for (m = 0; m < this._gltf.materials.length; ++m) { + material = this._gltf.materials[m]; + context_1 = "/materials/" + m; + babylonDrawMode = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleFillMode; + promises.push(this._loadMaterialAsync(context_1, material, null, babylonDrawMode, function () { })); + } + } + // Restore the blocking of material dirty. + if (this._allMaterialsDirtyRequired) { + // This can happen if we add a light for instance as it will impact the whole scene. + // This automatically resets everything if needed. + this._babylonScene.blockMaterialDirtyMechanism = oldBlockMaterialDirtyMechanism; + } + else { + // By default a newly created material is dirty so there is no need to flag the full scene as dirty. + // For perf reasons, we then bypass blockMaterialDirtyMechanism as this would "dirty" the entire scene. + this._babylonScene._forceBlockMaterialDirtyMechanism(oldBlockMaterialDirtyMechanism); + } + if (this._parent.compileMaterials) { + promises.push(this._compileMaterialsAsync()); + } + if (this._parent.compileShadowGenerators) { + promises.push(this._compileShadowGeneratorsAsync()); + } + resultPromise = Promise.all(promises).then(function () { + if (_this._rootBabylonMesh && _this._rootBabylonMesh !== _this._parent.customRootNode) { + _this._rootBabylonMesh.setEnabled(true); + } + _this._extensionsOnReady(); + _this._parent._setState(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.READY); + _this._startAnimations(); + return resultFunc(); + }); + return [2 /*return*/, resultPromise.then(function (result) { + _this._parent._endPerformanceCounter(loadingToReadyCounterName); + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Tools.SetImmediate(function () { + if (!_this._disposed) { + Promise.all(_this._completePromises).then(function () { + _this._parent._endPerformanceCounter(loadingToCompleteCounterName); + _this._parent._setState(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.COMPLETE); + _this._parent.onCompleteObservable.notifyObservers(undefined); + _this._parent.onCompleteObservable.clear(); + _this.dispose(); + }, function (error) { + _this._parent.onErrorObservable.notifyObservers(error); + _this._parent.onErrorObservable.clear(); + _this.dispose(); + }); + } + }); + return result; + })]; + } + }); + }); }) + .catch(function (error) { + if (!_this._disposed) { + _this._parent.onErrorObservable.notifyObservers(error); + _this._parent.onErrorObservable.clear(); + _this.dispose(); + } + throw error; + }); + }; + GLTFLoader.prototype._loadData = function (data) { + this._gltf = data.json; + this._setupData(); + if (data.bin) { + var buffers = this._gltf.buffers; + if (buffers && buffers[0] && !buffers[0].uri) { + var binaryBuffer = buffers[0]; + if (binaryBuffer.byteLength < data.bin.byteLength - 3 || binaryBuffer.byteLength > data.bin.byteLength) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("Binary buffer length (".concat(binaryBuffer.byteLength, ") from JSON does not match chunk length (").concat(data.bin.byteLength, ")")); + } + this._bin = data.bin; + } + else { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("Unexpected BIN chunk"); + } + } + }; + GLTFLoader.prototype._setupData = function () { + ArrayItem.Assign(this._gltf.accessors); + ArrayItem.Assign(this._gltf.animations); + ArrayItem.Assign(this._gltf.buffers); + ArrayItem.Assign(this._gltf.bufferViews); + ArrayItem.Assign(this._gltf.cameras); + ArrayItem.Assign(this._gltf.images); + ArrayItem.Assign(this._gltf.materials); + ArrayItem.Assign(this._gltf.meshes); + ArrayItem.Assign(this._gltf.nodes); + ArrayItem.Assign(this._gltf.samplers); + ArrayItem.Assign(this._gltf.scenes); + ArrayItem.Assign(this._gltf.skins); + ArrayItem.Assign(this._gltf.textures); + if (this._gltf.nodes) { + var nodeParents = {}; + for (var _i = 0, _a = this._gltf.nodes; _i < _a.length; _i++) { + var node = _a[_i]; + if (node.children) { + for (var _b = 0, _c = node.children; _b < _c.length; _b++) { + var index = _c[_b]; + nodeParents[index] = node.index; + } + } + } + var rootNode = this._createRootNode(); + for (var _d = 0, _e = this._gltf.nodes; _d < _e.length; _d++) { + var node = _e[_d]; + var parentIndex = nodeParents[node.index]; + node.parent = parentIndex === undefined ? rootNode : this._gltf.nodes[parentIndex]; + } + } + }; + GLTFLoader.prototype._loadExtensionsAsync = function () { + return (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__awaiter)(this, void 0, void 0, function () { + var extensionPromises, _a, _b, _c, _loop_1, this_1, _i, _d, name_1; + var _e; + var _this = this; + var _f; + return (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__generator)(this, function (_g) { + switch (_g.label) { + case 0: + extensionPromises = []; + _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.registeredGLTFExtensions.forEach(function (registeredExtension, name) { + var _a; + // Don't load explicitly disabled extensions. + if (((_a = _this.parent.extensionOptions[name]) === null || _a === void 0 ? void 0 : _a.enabled) === false) { + // But warn if the disabled extension is used by the model. + if (registeredExtension.isGLTFExtension && _this.isExtensionUsed(name)) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("Extension ".concat(name, " is used but has been explicitly disabled.")); + } + } + // Load loader extensions that are not a glTF extension, as well as extensions that are glTF extensions and are used by the model. + else if (!registeredExtension.isGLTFExtension || _this.isExtensionUsed(name)) { + extensionPromises.push((function () { return (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__awaiter)(_this, void 0, void 0, function () { + var extension; + return (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__generator)(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, registeredExtension.factory(this)]; + case 1: + extension = _a.sent(); + if (extension.name !== name) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("The name of the glTF loader extension instance does not match the registered name: ".concat(extension.name, " !== ").concat(name)); + } + this._parent.onExtensionLoadedObservable.notifyObservers(extension); + return [2 /*return*/, extension]; + } + }); + }); })()); + } + }); + _b = (_a = (_e = this._extensions).push).apply; + _c = [_e]; + return [4 /*yield*/, Promise.all(extensionPromises)]; + case 1: + _b.apply(_a, _c.concat([(_g.sent())])); + this._extensions.sort(function (a, b) { return (a.order || Number.MAX_VALUE) - (b.order || Number.MAX_VALUE); }); + this._parent.onExtensionLoadedObservable.clear(); + if (this._gltf.extensionsRequired) { + _loop_1 = function (name_1) { + var available = this_1._extensions.some(function (extension) { return extension.name === name_1 && extension.enabled; }); + if (!available) { + if (((_f = this_1.parent.extensionOptions[name_1]) === null || _f === void 0 ? void 0 : _f.enabled) === false) { + throw new Error("Required extension ".concat(name_1, " is disabled")); + } + throw new Error("Required extension ".concat(name_1, " is not available")); + } + }; + this_1 = this; + for (_i = 0, _d = this._gltf.extensionsRequired; _i < _d.length; _i++) { + name_1 = _d[_i]; + _loop_1(name_1); + } + } + return [2 /*return*/]; + } + }); + }); + }; + GLTFLoader.prototype._createRootNode = function () { + if (this._parent.customRootNode !== undefined) { + this._rootBabylonMesh = this._parent.customRootNode; + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + _babylonTransformNode: this._rootBabylonMesh === null ? undefined : this._rootBabylonMesh, + index: -1, + }; + } + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var rootMesh = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Mesh("__root__", this._babylonScene); + this._rootBabylonMesh = rootMesh; + this._rootBabylonMesh._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + this._rootBabylonMesh.setEnabled(false); + var rootNode = { + // eslint-disable-next-line @typescript-eslint/naming-convention + _babylonTransformNode: this._rootBabylonMesh, + index: -1, + }; + switch (this._parent.coordinateSystemMode) { + case _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderCoordinateSystemMode.AUTO: { + if (!this._babylonScene.useRightHandedSystem) { + rootNode.rotation = [0, 1, 0, 0]; + rootNode.scale = [1, 1, -1]; + GLTFLoader._LoadTransform(rootNode, this._rootBabylonMesh); + } + break; + } + case _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderCoordinateSystemMode.FORCE_RIGHT_HANDED: { + this._babylonScene.useRightHandedSystem = true; + break; + } + default: { + throw new Error("Invalid coordinate system mode (".concat(this._parent.coordinateSystemMode, ")")); + } + } + this._parent.onMeshLoadedObservable.notifyObservers(rootMesh); + return rootNode; + }; + /** + * Loads a glTF scene. + * @param context The context when loading the asset + * @param scene The glTF scene property + * @returns A promise that resolves when the load is complete + */ + GLTFLoader.prototype.loadSceneAsync = function (context, scene) { + var _this = this; + var extensionPromise = this._extensionsLoadSceneAsync(context, scene); + if (extensionPromise) { + return extensionPromise; + } + var promises = new Array(); + this.logOpen("".concat(context, " ").concat(scene.name || "")); + if (scene.nodes) { + for (var _i = 0, _a = scene.nodes; _i < _a.length; _i++) { + var index = _a[_i]; + var node = ArrayItem.Get("".concat(context, "/nodes/").concat(index), this._gltf.nodes, index); + promises.push(this.loadNodeAsync("/nodes/".concat(node.index), node, function (babylonMesh) { + babylonMesh.parent = _this._rootBabylonMesh; + })); + } + } + for (var _b = 0, _c = this._postSceneLoadActions; _b < _c.length; _b++) { + var action = _c[_b]; + action(); + } + promises.push(this._loadAnimationsAsync()); + this.logClose(); + return Promise.all(promises).then(function () { }); + }; + GLTFLoader.prototype._forEachPrimitive = function (node, callback) { + if (node._primitiveBabylonMeshes) { + for (var _i = 0, _a = node._primitiveBabylonMeshes; _i < _a.length; _i++) { + var babylonMesh = _a[_i]; + callback(babylonMesh); + } + } + }; + GLTFLoader.prototype._getGeometries = function () { + var geometries = []; + var nodes = this._gltf.nodes; + if (nodes) { + for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) { + var node = nodes_1[_i]; + this._forEachPrimitive(node, function (babylonMesh) { + var geometry = babylonMesh.geometry; + if (geometry && geometries.indexOf(geometry) === -1) { + geometries.push(geometry); + } + }); + } + } + return geometries; + }; + GLTFLoader.prototype._getMeshes = function () { + var meshes = []; + // Root mesh is always first, if available. + if (this._rootBabylonMesh instanceof babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.AbstractMesh) { + meshes.push(this._rootBabylonMesh); + } + var nodes = this._gltf.nodes; + if (nodes) { + for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) { + var node = nodes_2[_i]; + this._forEachPrimitive(node, function (babylonMesh) { + meshes.push(babylonMesh); + }); + } + } + return meshes; + }; + GLTFLoader.prototype._getTransformNodes = function () { + var transformNodes = []; + var nodes = this._gltf.nodes; + if (nodes) { + for (var _i = 0, nodes_3 = nodes; _i < nodes_3.length; _i++) { + var node = nodes_3[_i]; + if (node._babylonTransformNode && node._babylonTransformNode.getClassName() === "TransformNode") { + transformNodes.push(node._babylonTransformNode); + } + if (node._babylonTransformNodeForSkin) { + transformNodes.push(node._babylonTransformNodeForSkin); + } + } + } + return transformNodes; + }; + GLTFLoader.prototype._getSkeletons = function () { + var skeletons = []; + var skins = this._gltf.skins; + if (skins) { + for (var _i = 0, skins_1 = skins; _i < skins_1.length; _i++) { + var skin = skins_1[_i]; + if (skin._data) { + skeletons.push(skin._data.babylonSkeleton); + } + } + } + return skeletons; + }; + GLTFLoader.prototype._getAnimationGroups = function () { + var animationGroups = []; + var animations = this._gltf.animations; + if (animations) { + for (var _i = 0, animations_1 = animations; _i < animations_1.length; _i++) { + var animation = animations_1[_i]; + if (animation._babylonAnimationGroup) { + animationGroups.push(animation._babylonAnimationGroup); + } + } + } + return animationGroups; + }; + GLTFLoader.prototype._startAnimations = function () { + switch (this._parent.animationStartMode) { + case _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderAnimationStartMode.NONE: { + // do nothing + break; + } + case _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderAnimationStartMode.FIRST: { + var babylonAnimationGroups = this._getAnimationGroups(); + if (babylonAnimationGroups.length !== 0) { + babylonAnimationGroups[0].start(true); + } + break; + } + case _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderAnimationStartMode.ALL: { + var babylonAnimationGroups = this._getAnimationGroups(); + for (var _i = 0, babylonAnimationGroups_1 = babylonAnimationGroups; _i < babylonAnimationGroups_1.length; _i++) { + var babylonAnimationGroup = babylonAnimationGroups_1[_i]; + babylonAnimationGroup.start(true); + } + break; + } + default: { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Error("Invalid animation start mode (".concat(this._parent.animationStartMode, ")")); + return; + } + } + }; + /** + * Loads a glTF node. + * @param context The context when loading the asset + * @param node The glTF node property + * @param assign A function called synchronously after parsing the glTF properties + * @returns A promise that resolves with the loaded Babylon mesh when the load is complete + */ + GLTFLoader.prototype.loadNodeAsync = function (context, node, assign) { + var _this = this; + if (assign === void 0) { assign = function () { }; } + var extensionPromise = this._extensionsLoadNodeAsync(context, node, assign); + if (extensionPromise) { + return extensionPromise; + } + if (node._babylonTransformNode) { + throw new Error("".concat(context, ": Invalid recursive node hierarchy")); + } + var promises = new Array(); + this.logOpen("".concat(context, " ").concat(node.name || "")); + var loadNode = function (babylonTransformNode) { + GLTFLoader.AddPointerMetadata(babylonTransformNode, context); + GLTFLoader._LoadTransform(node, babylonTransformNode); + if (node.camera != undefined) { + var camera = ArrayItem.Get("".concat(context, "/camera"), _this._gltf.cameras, node.camera); + promises.push(_this.loadCameraAsync("/cameras/".concat(camera.index), camera, function (babylonCamera) { + babylonCamera.parent = babylonTransformNode; + })); + } + if (node.children) { + for (var _i = 0, _a = node.children; _i < _a.length; _i++) { + var index = _a[_i]; + var childNode = ArrayItem.Get("".concat(context, "/children/").concat(index), _this._gltf.nodes, index); + promises.push(_this.loadNodeAsync("/nodes/".concat(childNode.index), childNode, function (childBabylonMesh) { + childBabylonMesh.parent = babylonTransformNode; + })); + } + } + assign(babylonTransformNode); + }; + var hasMesh = node.mesh != undefined; + var hasSkin = this._parent.loadSkins && node.skin != undefined; + if (!hasMesh || hasSkin) { + var nodeName = node.name || "node".concat(node.index); + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var transformNode = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.TransformNode(nodeName, this._babylonScene); + transformNode._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + if (node.mesh == undefined) { + node._babylonTransformNode = transformNode; + } + else { + node._babylonTransformNodeForSkin = transformNode; + } + loadNode(transformNode); + } + if (hasMesh) { + if (hasSkin) { + // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note) + // This code path will place the skinned mesh as a sibling of the skeleton root node without loading the + // transform, which effectively ignores the transform of the skinned mesh, as per spec. + var mesh = ArrayItem.Get("".concat(context, "/mesh"), this._gltf.meshes, node.mesh); + promises.push(this._loadMeshAsync("/meshes/".concat(mesh.index), node, mesh, function (babylonTransformNode) { + var babylonTransformNodeForSkin = node._babylonTransformNodeForSkin; + // Merge the metadata from the skin node to the skinned mesh in case a loader extension added metadata. + babylonTransformNode.metadata = mergeDeep(babylonTransformNodeForSkin.metadata, babylonTransformNode.metadata || {}); + var skin = ArrayItem.Get("".concat(context, "/skin"), _this._gltf.skins, node.skin); + promises.push(_this._loadSkinAsync("/skins/".concat(skin.index), node, skin, function (babylonSkeleton) { + _this._forEachPrimitive(node, function (babylonMesh) { + babylonMesh.skeleton = babylonSkeleton; + }); + // Wait until all the nodes are parented before parenting the skinned mesh. + _this._postSceneLoadActions.push(function () { + if (skin.skeleton != undefined) { + // Place the skinned mesh node as a sibling of the skeleton root node. + // Handle special case when the parent of the skeleton root is the skinned mesh. + var parentNode = ArrayItem.Get("/skins/".concat(skin.index, "/skeleton"), _this._gltf.nodes, skin.skeleton).parent; + if (node.index === parentNode.index) { + babylonTransformNode.parent = babylonTransformNodeForSkin.parent; + } + else { + babylonTransformNode.parent = parentNode._babylonTransformNode; + } + } + else { + babylonTransformNode.parent = _this._rootBabylonMesh; + } + _this._parent.onSkinLoadedObservable.notifyObservers({ node: babylonTransformNodeForSkin, skinnedNode: babylonTransformNode }); + }); + })); + })); + } + else { + var mesh = ArrayItem.Get("".concat(context, "/mesh"), this._gltf.meshes, node.mesh); + promises.push(this._loadMeshAsync("/meshes/".concat(mesh.index), node, mesh, loadNode)); + } + } + this.logClose(); + return Promise.all(promises).then(function () { + _this._forEachPrimitive(node, function (babylonMesh) { + if (babylonMesh.geometry && babylonMesh.geometry.useBoundingInfoFromGeometry) { + // simply apply the world matrices to the bounding info - the extends are already ok + babylonMesh._updateBoundingInfo(); + } + else { + babylonMesh.refreshBoundingInfo(true, true); + } + }); + return node._babylonTransformNode; + }); + }; + GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh, assign) { + var primitives = mesh.primitives; + if (!primitives || !primitives.length) { + throw new Error("".concat(context, ": Primitives are missing")); + } + if (primitives[0].index == undefined) { + ArrayItem.Assign(primitives); + } + var promises = new Array(); + this.logOpen("".concat(context, " ").concat(mesh.name || "")); + var name = node.name || "node".concat(node.index); + if (primitives.length === 1) { + var primitive = mesh.primitives[0]; + promises.push(this._loadMeshPrimitiveAsync("".concat(context, "/primitives/").concat(primitive.index), name, node, mesh, primitive, function (babylonMesh) { + node._babylonTransformNode = babylonMesh; + node._primitiveBabylonMeshes = [babylonMesh]; + })); + } + else { + this._babylonScene._blockEntityCollection = !!this._assetContainer; + node._babylonTransformNode = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.TransformNode(name, this._babylonScene); + node._babylonTransformNode._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + node._primitiveBabylonMeshes = []; + for (var _i = 0, primitives_1 = primitives; _i < primitives_1.length; _i++) { + var primitive = primitives_1[_i]; + promises.push(this._loadMeshPrimitiveAsync("".concat(context, "/primitives/").concat(primitive.index), "".concat(name, "_primitive").concat(primitive.index), node, mesh, primitive, function (babylonMesh) { + babylonMesh.parent = node._babylonTransformNode; + node._primitiveBabylonMeshes.push(babylonMesh); + })); + } + } + assign(node._babylonTransformNode); + this.logClose(); + return Promise.all(promises).then(function () { + return node._babylonTransformNode; + }); + }; + /** + * @internal Define this method to modify the default behavior when loading data for mesh primitives. + * @param context The context when loading the asset + * @param name The mesh name when loading the asset + * @param node The glTF node when loading the asset + * @param mesh The glTF mesh when loading the asset + * @param primitive The glTF mesh primitive property + * @param assign A function called synchronously after parsing the glTF properties + * @returns A promise that resolves with the loaded mesh when the load is complete or null if not handled + */ + GLTFLoader.prototype._loadMeshPrimitiveAsync = function (context, name, node, mesh, primitive, assign) { + var _this = this; + var extensionPromise = this._extensionsLoadMeshPrimitiveAsync(context, name, node, mesh, primitive, assign); + if (extensionPromise) { + return extensionPromise; + } + this.logOpen("".concat(context)); + var shouldInstance = this._disableInstancedMesh === 0 && this._parent.createInstances && node.skin == undefined && !mesh.primitives[0].targets; + var babylonAbstractMesh; + var promise; + if (shouldInstance && primitive._instanceData) { + this._babylonScene._blockEntityCollection = !!this._assetContainer; + babylonAbstractMesh = primitive._instanceData.babylonSourceMesh.createInstance(name); + babylonAbstractMesh._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + promise = primitive._instanceData.promise; + } + else { + var promises = new Array(); + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var babylonMesh_1 = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Mesh(name, this._babylonScene); + babylonMesh_1._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + babylonMesh_1.sideOrientation = this._babylonScene.useRightHandedSystem ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.CounterClockWiseSideOrientation : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.ClockWiseSideOrientation; + this._createMorphTargets(context, node, mesh, primitive, babylonMesh_1); + promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh_1).then(function (babylonGeometry) { + return _this._loadMorphTargetsAsync(context, primitive, babylonMesh_1, babylonGeometry).then(function () { + if (_this._disposed) { + return; + } + _this._babylonScene._blockEntityCollection = !!_this._assetContainer; + babylonGeometry.applyToMesh(babylonMesh_1); + babylonGeometry._parentContainer = _this._assetContainer; + _this._babylonScene._blockEntityCollection = false; + }); + })); + var babylonDrawMode = GLTFLoader._GetDrawMode(context, primitive.mode); + if (primitive.material == undefined) { + var babylonMaterial = this._defaultBabylonMaterialData[babylonDrawMode]; + if (!babylonMaterial) { + babylonMaterial = this._createDefaultMaterial("__GLTFLoader._default", babylonDrawMode); + this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial); + this._defaultBabylonMaterialData[babylonDrawMode] = babylonMaterial; + } + babylonMesh_1.material = babylonMaterial; + } + else if (!this.parent.skipMaterials) { + var material = ArrayItem.Get("".concat(context, "/material"), this._gltf.materials, primitive.material); + promises.push(this._loadMaterialAsync("/materials/".concat(material.index), material, babylonMesh_1, babylonDrawMode, function (babylonMaterial) { + babylonMesh_1.material = babylonMaterial; + })); + } + promise = Promise.all(promises); + if (shouldInstance) { + primitive._instanceData = { + babylonSourceMesh: babylonMesh_1, + promise: promise, + }; + } + babylonAbstractMesh = babylonMesh_1; + } + GLTFLoader.AddPointerMetadata(babylonAbstractMesh, context); + this._parent.onMeshLoadedObservable.notifyObservers(babylonAbstractMesh); + assign(babylonAbstractMesh); + this.logClose(); + return promise.then(function () { + return babylonAbstractMesh; + }); + }; + GLTFLoader.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) { + var _this = this; + var extensionPromise = this._extensionsLoadVertexDataAsync(context, primitive, babylonMesh); + if (extensionPromise) { + return extensionPromise; + } + var attributes = primitive.attributes; + if (!attributes) { + throw new Error("".concat(context, ": Attributes are missing")); + } + var promises = new Array(); + var babylonGeometry = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Geometry(babylonMesh.name, this._babylonScene); + if (primitive.indices == undefined) { + babylonMesh.isUnIndexed = true; + } + else { + var accessor = ArrayItem.Get("".concat(context, "/indices"), this._gltf.accessors, primitive.indices); + promises.push(this._loadIndicesAccessorAsync("/accessors/".concat(accessor.index), accessor).then(function (data) { + babylonGeometry.setIndices(data); + })); + } + var loadAttribute = function (name, kind, callback) { + if (attributes[name] == undefined) { + return; + } + babylonMesh._delayInfo = babylonMesh._delayInfo || []; + if (babylonMesh._delayInfo.indexOf(kind) === -1) { + babylonMesh._delayInfo.push(kind); + } + var accessor = ArrayItem.Get("".concat(context, "/attributes/").concat(name), _this._gltf.accessors, attributes[name]); + promises.push(_this._loadVertexAccessorAsync("/accessors/".concat(accessor.index), accessor, kind).then(function (babylonVertexBuffer) { + var _a, _b; + if (babylonVertexBuffer.getKind() === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind && !_this.parent.alwaysComputeBoundingBox && !babylonMesh.skeleton) { + if (accessor.min && accessor.max) { + var min = (_a = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[0]).copyFromFloats.apply(_a, accessor.min); + var max = (_b = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[1]).copyFromFloats.apply(_b, accessor.max); + if (accessor.normalized && accessor.componentType !== 5126 /* AccessorComponentType.FLOAT */) { + var divider = 1; + switch (accessor.componentType) { + case 5120 /* AccessorComponentType.BYTE */: + divider = 127.0; + break; + case 5121 /* AccessorComponentType.UNSIGNED_BYTE */: + divider = 255.0; + break; + case 5122 /* AccessorComponentType.SHORT */: + divider = 32767.0; + break; + case 5123 /* AccessorComponentType.UNSIGNED_SHORT */: + divider = 65535.0; + break; + } + var oneOverDivider = 1 / divider; + min.scaleInPlace(oneOverDivider); + max.scaleInPlace(oneOverDivider); + } + babylonGeometry._boundingInfo = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.BoundingInfo(min, max); + babylonGeometry.useBoundingInfoFromGeometry = true; + } + } + babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count); + })); + if (kind == babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesExtraKind) { + babylonMesh.numBoneInfluencers = 8; + } + if (callback) { + callback(accessor); + } + }; + loadAttribute("POSITION", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind); + loadAttribute("NORMAL", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind); + loadAttribute("TANGENT", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind); + loadAttribute("TEXCOORD_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UVKind); + loadAttribute("TEXCOORD_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV2Kind); + loadAttribute("TEXCOORD_2", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV3Kind); + loadAttribute("TEXCOORD_3", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV4Kind); + loadAttribute("TEXCOORD_4", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV5Kind); + loadAttribute("TEXCOORD_5", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV6Kind); + loadAttribute("JOINTS_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesKind); + loadAttribute("WEIGHTS_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesWeightsKind); + loadAttribute("JOINTS_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesExtraKind); + loadAttribute("WEIGHTS_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesWeightsExtraKind); + loadAttribute("COLOR_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ColorKind, function (accessor) { + if (accessor.type === "VEC4" /* AccessorType.VEC4 */) { + babylonMesh.hasVertexAlpha = true; + } + }); + return Promise.all(promises).then(function () { + return babylonGeometry; + }); + }; + GLTFLoader.prototype._createMorphTargets = function (context, node, mesh, primitive, babylonMesh) { + if (!primitive.targets || !this._parent.loadMorphTargets) { + return; + } + if (node._numMorphTargets == undefined) { + node._numMorphTargets = primitive.targets.length; + } + else if (primitive.targets.length !== node._numMorphTargets) { + throw new Error("".concat(context, ": Primitives do not have the same number of targets")); + } + var targetNames = mesh.extras ? mesh.extras.targetNames : null; + this._babylonScene._blockEntityCollection = !!this._assetContainer; + babylonMesh.morphTargetManager = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.MorphTargetManager(this._babylonScene); + babylonMesh.morphTargetManager._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + babylonMesh.morphTargetManager.areUpdatesFrozen = true; + for (var index = 0; index < primitive.targets.length; index++) { + var weight = node.weights ? node.weights[index] : mesh.weights ? mesh.weights[index] : 0; + var name_2 = targetNames ? targetNames[index] : "morphTarget".concat(index); + babylonMesh.morphTargetManager.addTarget(new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.MorphTarget(name_2, weight, babylonMesh.getScene())); + // TODO: tell the target whether it has positions, normals, tangents + } + }; + GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonGeometry) { + if (!primitive.targets || !this._parent.loadMorphTargets) { + return Promise.resolve(); + } + var promises = new Array(); + var morphTargetManager = babylonMesh.morphTargetManager; + for (var index = 0; index < morphTargetManager.numTargets; index++) { + var babylonMorphTarget = morphTargetManager.getTarget(index); + promises.push(this._loadMorphTargetVertexDataAsync("".concat(context, "/targets/").concat(index), babylonGeometry, primitive.targets[index], babylonMorphTarget)); + } + return Promise.all(promises).then(function () { + morphTargetManager.areUpdatesFrozen = false; + }); + }; + GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonGeometry, attributes, babylonMorphTarget) { + var _this = this; + var promises = new Array(); + var loadAttribute = function (attribute, kind, setData) { + if (attributes[attribute] == undefined) { + return; + } + var babylonVertexBuffer = babylonGeometry.getVertexBuffer(kind); + if (!babylonVertexBuffer) { + return; + } + var accessor = ArrayItem.Get("".concat(context, "/").concat(attribute), _this._gltf.accessors, attributes[attribute]); + promises.push(_this._loadFloatAccessorAsync("/accessors/".concat(accessor.index), accessor).then(function (data) { + setData(babylonVertexBuffer, data); + })); + }; + loadAttribute("POSITION", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind, function (babylonVertexBuffer, data) { + var positions = new Float32Array(data.length); + babylonVertexBuffer.forEach(data.length, function (value, index) { + positions[index] = data[index] + value; + }); + babylonMorphTarget.setPositions(positions); + }); + loadAttribute("NORMAL", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind, function (babylonVertexBuffer, data) { + var normals = new Float32Array(data.length); + babylonVertexBuffer.forEach(normals.length, function (value, index) { + normals[index] = data[index] + value; + }); + babylonMorphTarget.setNormals(normals); + }); + loadAttribute("TANGENT", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind, function (babylonVertexBuffer, data) { + var tangents = new Float32Array((data.length / 3) * 4); + var dataIndex = 0; + babylonVertexBuffer.forEach((data.length / 3) * 4, function (value, index) { + // Tangent data for morph targets is stored as xyz delta. + // The vertexData.tangent is stored as xyzw. + // So we need to skip every fourth vertexData.tangent. + if ((index + 1) % 4 !== 0) { + tangents[dataIndex] = data[dataIndex] + value; + dataIndex++; + } + }); + babylonMorphTarget.setTangents(tangents); + }); + return Promise.all(promises).then(function () { }); + }; + GLTFLoader._LoadTransform = function (node, babylonNode) { + // Ignore the TRS of skinned nodes. + // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note) + if (node.skin != undefined) { + return; + } + var position = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero(); + var rotation = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity(); + var scaling = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.One(); + if (node.matrix) { + var matrix = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Matrix.FromArray(node.matrix); + matrix.decompose(scaling, rotation, position); + } + else { + if (node.translation) { + position = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(node.translation); + } + if (node.rotation) { + rotation = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArray(node.rotation); + } + if (node.scale) { + scaling = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(node.scale); + } + } + babylonNode.position = position; + babylonNode.rotationQuaternion = rotation; + babylonNode.scaling = scaling; + }; + GLTFLoader.prototype._loadSkinAsync = function (context, node, skin, assign) { + var _this = this; + if (!this._parent.loadSkins) { + return Promise.resolve(); + } + var extensionPromise = this._extensionsLoadSkinAsync(context, node, skin); + if (extensionPromise) { + return extensionPromise; + } + if (skin._data) { + assign(skin._data.babylonSkeleton); + return skin._data.promise; + } + var skeletonId = "skeleton".concat(skin.index); + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var babylonSkeleton = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Skeleton(skin.name || skeletonId, skeletonId, this._babylonScene); + babylonSkeleton._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + this._loadBones(context, skin, babylonSkeleton); + var promise = this._loadSkinInverseBindMatricesDataAsync(context, skin).then(function (inverseBindMatricesData) { + _this._updateBoneMatrices(babylonSkeleton, inverseBindMatricesData); + }); + skin._data = { + babylonSkeleton: babylonSkeleton, + promise: promise, + }; + assign(babylonSkeleton); + return promise; + }; + GLTFLoader.prototype._loadBones = function (context, skin, babylonSkeleton) { + if (skin.skeleton == undefined || this._parent.alwaysComputeSkeletonRootNode) { + var rootNode = this._findSkeletonRootNode("".concat(context, "/joints"), skin.joints); + if (rootNode) { + if (skin.skeleton === undefined) { + skin.skeleton = rootNode.index; + } + else { + var isParent = function (a, b) { + for (; b.parent; b = b.parent) { + if (b.parent === a) { + return true; + } + } + return false; + }; + var skeletonNode = ArrayItem.Get("".concat(context, "/skeleton"), this._gltf.nodes, skin.skeleton); + if (skeletonNode !== rootNode && !isParent(skeletonNode, rootNode)) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, "/skeleton: Overriding with nearest common ancestor as skeleton node is not a common root")); + skin.skeleton = rootNode.index; + } + } + } + else { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, ": Failed to find common root")); + } + } + var babylonBones = {}; + for (var _i = 0, _a = skin.joints; _i < _a.length; _i++) { + var index = _a[_i]; + var node = ArrayItem.Get("".concat(context, "/joints/").concat(index), this._gltf.nodes, index); + this._loadBone(node, skin, babylonSkeleton, babylonBones); + } + }; + GLTFLoader.prototype._findSkeletonRootNode = function (context, joints) { + if (joints.length === 0) { + return null; + } + var paths = {}; + for (var _i = 0, joints_1 = joints; _i < joints_1.length; _i++) { + var index = joints_1[_i]; + var path = []; + var node = ArrayItem.Get("".concat(context, "/").concat(index), this._gltf.nodes, index); + while (node.index !== -1) { + path.unshift(node); + node = node.parent; + } + paths[index] = path; + } + var rootNode = null; + for (var i = 0;; ++i) { + var path = paths[joints[0]]; + if (i >= path.length) { + return rootNode; + } + var node = path[i]; + for (var j = 1; j < joints.length; ++j) { + path = paths[joints[j]]; + if (i >= path.length || node !== path[i]) { + return rootNode; + } + } + rootNode = node; + } + }; + GLTFLoader.prototype._loadBone = function (node, skin, babylonSkeleton, babylonBones) { + node._isJoint = true; + var babylonBone = babylonBones[node.index]; + if (babylonBone) { + return babylonBone; + } + var parentBabylonBone = null; + if (node.index !== skin.skeleton) { + if (node.parent && node.parent.index !== -1) { + parentBabylonBone = this._loadBone(node.parent, skin, babylonSkeleton, babylonBones); + } + else if (skin.skeleton !== undefined) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("/skins/".concat(skin.index, "/skeleton: Skeleton node is not a common root")); + } + } + var boneIndex = skin.joints.indexOf(node.index); + babylonBone = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Bone(node.name || "joint".concat(node.index), babylonSkeleton, parentBabylonBone, this._getNodeMatrix(node), null, null, boneIndex); + babylonBones[node.index] = babylonBone; + // Wait until the scene is loaded to ensure the transform nodes are loaded. + this._postSceneLoadActions.push(function () { + // Link the Babylon bone with the corresponding Babylon transform node. + // A glTF joint is a pointer to a glTF node in the glTF node hierarchy similar to Unity3D. + babylonBone.linkTransformNode(node._babylonTransformNode); + }); + return babylonBone; + }; + GLTFLoader.prototype._loadSkinInverseBindMatricesDataAsync = function (context, skin) { + if (skin.inverseBindMatrices == undefined) { + return Promise.resolve(null); + } + var accessor = ArrayItem.Get("".concat(context, "/inverseBindMatrices"), this._gltf.accessors, skin.inverseBindMatrices); + return this._loadFloatAccessorAsync("/accessors/".concat(accessor.index), accessor); + }; + GLTFLoader.prototype._updateBoneMatrices = function (babylonSkeleton, inverseBindMatricesData) { + for (var _i = 0, _a = babylonSkeleton.bones; _i < _a.length; _i++) { + var babylonBone = _a[_i]; + var baseMatrix = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Matrix.Identity(); + var boneIndex = babylonBone._index; + if (inverseBindMatricesData && boneIndex !== -1) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Matrix.FromArrayToRef(inverseBindMatricesData, boneIndex * 16, baseMatrix); + baseMatrix.invertToRef(baseMatrix); + } + var babylonParentBone = babylonBone.getParent(); + if (babylonParentBone) { + baseMatrix.multiplyToRef(babylonParentBone.getAbsoluteInverseBindMatrix(), baseMatrix); + } + babylonBone.updateMatrix(baseMatrix, false, false); + babylonBone._updateAbsoluteBindMatrices(undefined, false); + } + }; + GLTFLoader.prototype._getNodeMatrix = function (node) { + return node.matrix + ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Matrix.FromArray(node.matrix) + : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Matrix.Compose(node.scale ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(node.scale) : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.One(), node.rotation ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArray(node.rotation) : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity(), node.translation ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(node.translation) : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero()); + }; + /** + * Loads a glTF camera. + * @param context The context when loading the asset + * @param camera The glTF camera property + * @param assign A function called synchronously after parsing the glTF properties + * @returns A promise that resolves with the loaded Babylon camera when the load is complete + */ + GLTFLoader.prototype.loadCameraAsync = function (context, camera, assign) { + if (assign === void 0) { assign = function () { }; } + var extensionPromise = this._extensionsLoadCameraAsync(context, camera, assign); + if (extensionPromise) { + return extensionPromise; + } + var promises = new Array(); + this.logOpen("".concat(context, " ").concat(camera.name || "")); + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var babylonCamera = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.FreeCamera(camera.name || "camera".concat(camera.index), babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero(), this._babylonScene, false); + babylonCamera._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + babylonCamera.ignoreParentScaling = true; + camera._babylonCamera = babylonCamera; + // Rotation by 180 as glTF has a different convention than Babylon. + babylonCamera.rotation.set(0, Math.PI, 0); + switch (camera.type) { + case "perspective" /* CameraType.PERSPECTIVE */: { + var perspective = camera.perspective; + if (!perspective) { + throw new Error("".concat(context, ": Camera perspective properties are missing")); + } + babylonCamera.fov = perspective.yfov; + babylonCamera.minZ = perspective.znear; + babylonCamera.maxZ = perspective.zfar || 0; + break; + } + case "orthographic" /* CameraType.ORTHOGRAPHIC */: { + if (!camera.orthographic) { + throw new Error("".concat(context, ": Camera orthographic properties are missing")); + } + babylonCamera.mode = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Camera.ORTHOGRAPHIC_CAMERA; + babylonCamera.orthoLeft = -camera.orthographic.xmag; + babylonCamera.orthoRight = camera.orthographic.xmag; + babylonCamera.orthoBottom = -camera.orthographic.ymag; + babylonCamera.orthoTop = camera.orthographic.ymag; + babylonCamera.minZ = camera.orthographic.znear; + babylonCamera.maxZ = camera.orthographic.zfar; + break; + } + default: { + throw new Error("".concat(context, ": Invalid camera type (").concat(camera.type, ")")); + } + } + GLTFLoader.AddPointerMetadata(babylonCamera, context); + this._parent.onCameraLoadedObservable.notifyObservers(babylonCamera); + assign(babylonCamera); + this.logClose(); + return Promise.all(promises).then(function () { + return babylonCamera; + }); + }; + GLTFLoader.prototype._loadAnimationsAsync = function () { + var animations = this._gltf.animations; + if (!animations) { + return Promise.resolve(); + } + var promises = new Array(); + for (var index = 0; index < animations.length; index++) { + var animation = animations[index]; + promises.push(this.loadAnimationAsync("/animations/".concat(animation.index), animation).then(function (animationGroup) { + // Delete the animation group if it ended up not having any animations in it. + if (animationGroup.targetedAnimations.length === 0) { + animationGroup.dispose(); + } + })); + } + return Promise.all(promises).then(function () { }); + }; + /** + * Loads a glTF animation. + * @param context The context when loading the asset + * @param animation The glTF animation property + * @returns A promise that resolves with the loaded Babylon animation group when the load is complete + */ + GLTFLoader.prototype.loadAnimationAsync = function (context, animation) { + var _this = this; + var promise = this._extensionsLoadAnimationAsync(context, animation); + if (promise) { + return promise; + } + // eslint-disable-next-line @typescript-eslint/naming-convention + return Promise.resolve(/*! import() */).then(__webpack_require__.t.bind(__webpack_require__, /*! babylonjs/Animations/animationGroup */ "babylonjs/Misc/tools", 23)).then(function (_a) { + var AnimationGroup = _a.AnimationGroup; + _this._babylonScene._blockEntityCollection = !!_this._assetContainer; + var babylonAnimationGroup = new AnimationGroup(animation.name || "animation".concat(animation.index), _this._babylonScene); + babylonAnimationGroup._parentContainer = _this._assetContainer; + _this._babylonScene._blockEntityCollection = false; + animation._babylonAnimationGroup = babylonAnimationGroup; + var promises = new Array(); + ArrayItem.Assign(animation.channels); + ArrayItem.Assign(animation.samplers); + for (var _i = 0, _b = animation.channels; _i < _b.length; _i++) { + var channel = _b[_i]; + promises.push(_this._loadAnimationChannelAsync("".concat(context, "/channels/").concat(channel.index), context, animation, channel, function (babylonTarget, babylonAnimation) { + babylonTarget.animations = babylonTarget.animations || []; + babylonTarget.animations.push(babylonAnimation); + babylonAnimationGroup.addTargetedAnimation(babylonAnimation, babylonTarget); + })); + } + return Promise.all(promises).then(function () { + babylonAnimationGroup.normalize(0); + return babylonAnimationGroup; + }); + }); + }; + /** + * @hidden + * Loads a glTF animation channel. + * @param context The context when loading the asset + * @param animationContext The context of the animation when loading the asset + * @param animation The glTF animation property + * @param channel The glTF animation channel property + * @param onLoad Called for each animation loaded + * @returns A void promise that resolves when the load is complete + */ + GLTFLoader.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, onLoad) { + var promise = this._extensionsLoadAnimationChannelAsync(context, animationContext, animation, channel, onLoad); + if (promise) { + return promise; + } + if (channel.target.node == undefined) { + return Promise.resolve(); + } + var targetNode = ArrayItem.Get("".concat(context, "/target/node"), this._gltf.nodes, channel.target.node); + var channelTargetPath = channel.target.path; + var pathIsWeights = channelTargetPath === "weights" /* AnimationChannelTargetPath.WEIGHTS */; + // Ignore animations that have no animation targets. + if ((pathIsWeights && !targetNode._numMorphTargets) || (!pathIsWeights && !targetNode._babylonTransformNode)) { + return Promise.resolve(); + } + // Don't load node animations if disabled. + if (!this._parent.loadNodeAnimations && !pathIsWeights && !targetNode._isJoint) { + return Promise.resolve(); + } + var properties; + switch (channelTargetPath) { + case "translation" /* AnimationChannelTargetPath.TRANSLATION */: { + properties = _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_2__.nodeAnimationData.translation; + break; + } + case "rotation" /* AnimationChannelTargetPath.ROTATION */: { + properties = _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_2__.nodeAnimationData.rotation; + break; + } + case "scale" /* AnimationChannelTargetPath.SCALE */: { + properties = _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_2__.nodeAnimationData.scale; + break; + } + case "weights" /* AnimationChannelTargetPath.WEIGHTS */: { + properties = _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_2__.nodeAnimationData.weights; + break; + } + default: { + throw new Error("".concat(context, "/target/path: Invalid value (").concat(channel.target.path, ")")); + } + } + var targetInfo = { + object: targetNode, + info: properties, + }; + return this._loadAnimationChannelFromTargetInfoAsync(context, animationContext, animation, channel, targetInfo, onLoad); + }; + /** + * @hidden + * Loads a glTF animation channel. + * @param context The context when loading the asset + * @param animationContext The context of the animation when loading the asset + * @param animation The glTF animation property + * @param channel The glTF animation channel property + * @param targetInfo The glTF target and properties + * @param onLoad Called for each animation loaded + * @returns A void promise that resolves when the load is complete + */ + GLTFLoader.prototype._loadAnimationChannelFromTargetInfoAsync = function (context, animationContext, animation, channel, targetInfo, onLoad) { + var fps = this.parent.targetFps; + var invfps = 1 / fps; + var sampler = ArrayItem.Get("".concat(context, "/sampler"), animation.samplers, channel.sampler); + return this._loadAnimationSamplerAsync("".concat(animationContext, "/samplers/").concat(channel.sampler), sampler).then(function (data) { + var numAnimations = 0; + var target = targetInfo.object; + var propertyInfos = targetInfo.info; + // Extract the corresponding values from the read value. + // GLTF values may be dispatched to several Babylon properties. + // For example, baseColorFactor [`r`, `g`, `b`, `a`] is dispatched to + // - albedoColor as Color3(`r`, `g`, `b`) + // - alpha as `a` + for (var _i = 0, propertyInfos_1 = propertyInfos; _i < propertyInfos_1.length; _i++) { + var propertyInfo = propertyInfos_1[_i]; + var stride = propertyInfo.getStride(target); + var input = data.input; + var output = data.output; + var keys = new Array(input.length); + var outputOffset = 0; + switch (data.interpolation) { + case "STEP" /* AnimationSamplerInterpolation.STEP */: { + for (var index = 0; index < input.length; index++) { + var value = propertyInfo.getValue(target, output, outputOffset, 1); + outputOffset += stride; + keys[index] = { + frame: input[index] * fps, + value: value, + interpolation: 1 /* AnimationKeyInterpolation.STEP */, + }; + } + break; + } + case "CUBICSPLINE" /* AnimationSamplerInterpolation.CUBICSPLINE */: { + for (var index = 0; index < input.length; index++) { + var inTangent = propertyInfo.getValue(target, output, outputOffset, invfps); + outputOffset += stride; + var value = propertyInfo.getValue(target, output, outputOffset, 1); + outputOffset += stride; + var outTangent = propertyInfo.getValue(target, output, outputOffset, invfps); + outputOffset += stride; + keys[index] = { + frame: input[index] * fps, + inTangent: inTangent, + value: value, + outTangent: outTangent, + }; + } + break; + } + case "LINEAR" /* AnimationSamplerInterpolation.LINEAR */: { + for (var index = 0; index < input.length; index++) { + var value = propertyInfo.getValue(target, output, outputOffset, 1); + outputOffset += stride; + keys[index] = { + frame: input[index] * fps, + value: value, + }; + } + break; + } + } + if (outputOffset > 0) { + var name_3 = "".concat(animation.name || "animation".concat(animation.index), "_channel").concat(channel.index, "_").concat(numAnimations); + propertyInfo.buildAnimations(target, name_3, fps, keys, function (babylonAnimatable, babylonAnimation) { + ++numAnimations; + onLoad(babylonAnimatable, babylonAnimation); + }); + } + } + }); + }; + GLTFLoader.prototype._loadAnimationSamplerAsync = function (context, sampler) { + if (sampler._data) { + return sampler._data; + } + var interpolation = sampler.interpolation || "LINEAR" /* AnimationSamplerInterpolation.LINEAR */; + switch (interpolation) { + case "STEP" /* AnimationSamplerInterpolation.STEP */: + case "LINEAR" /* AnimationSamplerInterpolation.LINEAR */: + case "CUBICSPLINE" /* AnimationSamplerInterpolation.CUBICSPLINE */: { + break; + } + default: { + throw new Error("".concat(context, "/interpolation: Invalid value (").concat(sampler.interpolation, ")")); + } + } + var inputAccessor = ArrayItem.Get("".concat(context, "/input"), this._gltf.accessors, sampler.input); + var outputAccessor = ArrayItem.Get("".concat(context, "/output"), this._gltf.accessors, sampler.output); + sampler._data = Promise.all([ + this._loadFloatAccessorAsync("/accessors/".concat(inputAccessor.index), inputAccessor), + this._loadFloatAccessorAsync("/accessors/".concat(outputAccessor.index), outputAccessor), + ]).then(function (_a) { + var inputData = _a[0], outputData = _a[1]; + return { + input: inputData, + interpolation: interpolation, + output: outputData, + }; + }); + return sampler._data; + }; + /** + * Loads a glTF buffer. + * @param context The context when loading the asset + * @param buffer The glTF buffer property + * @param byteOffset The byte offset to use + * @param byteLength The byte length to use + * @returns A promise that resolves with the loaded data when the load is complete + */ + GLTFLoader.prototype.loadBufferAsync = function (context, buffer, byteOffset, byteLength) { + var extensionPromise = this._extensionsLoadBufferAsync(context, buffer, byteOffset, byteLength); + if (extensionPromise) { + return extensionPromise; + } + if (!buffer._data) { + if (buffer.uri) { + buffer._data = this.loadUriAsync("".concat(context, "/uri"), buffer, buffer.uri); + } + else { + if (!this._bin) { + throw new Error("".concat(context, ": Uri is missing or the binary glTF is missing its binary chunk")); + } + buffer._data = this._bin.readAsync(0, buffer.byteLength); + } + } + return buffer._data.then(function (data) { + try { + return new Uint8Array(data.buffer, data.byteOffset + byteOffset, byteLength); + } + catch (e) { + throw new Error("".concat(context, ": ").concat(e.message)); + } + }); + }; + /** + * Loads a glTF buffer view. + * @param context The context when loading the asset + * @param bufferView The glTF buffer view property + * @returns A promise that resolves with the loaded data when the load is complete + */ + GLTFLoader.prototype.loadBufferViewAsync = function (context, bufferView) { + var extensionPromise = this._extensionsLoadBufferViewAsync(context, bufferView); + if (extensionPromise) { + return extensionPromise; + } + if (bufferView._data) { + return bufferView._data; + } + var buffer = ArrayItem.Get("".concat(context, "/buffer"), this._gltf.buffers, bufferView.buffer); + bufferView._data = this.loadBufferAsync("/buffers/".concat(buffer.index), buffer, bufferView.byteOffset || 0, bufferView.byteLength); + return bufferView._data; + }; + GLTFLoader.prototype._loadAccessorAsync = function (context, accessor, constructor) { + var _this = this; + if (accessor._data) { + return accessor._data; + } + var numComponents = GLTFLoader._GetNumComponents(context, accessor.type); + var byteStride = numComponents * babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.GetTypeByteLength(accessor.componentType); + var length = numComponents * accessor.count; + if (accessor.bufferView == undefined) { + accessor._data = Promise.resolve(new constructor(length)); + } + else { + var bufferView_1 = ArrayItem.Get("".concat(context, "/bufferView"), this._gltf.bufferViews, accessor.bufferView); + accessor._data = this.loadBufferViewAsync("/bufferViews/".concat(bufferView_1.index), bufferView_1).then(function (data) { + if (accessor.componentType === 5126 /* AccessorComponentType.FLOAT */ && !accessor.normalized && (!bufferView_1.byteStride || bufferView_1.byteStride === byteStride)) { + return GLTFLoader._GetTypedArray(context, accessor.componentType, data, accessor.byteOffset, length); + } + else { + var typedArray_1 = new constructor(length); + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ForEach(data, accessor.byteOffset || 0, bufferView_1.byteStride || byteStride, numComponents, accessor.componentType, typedArray_1.length, accessor.normalized || false, function (value, index) { + typedArray_1[index] = value; + }); + return typedArray_1; + } + }); + } + if (accessor.sparse) { + var sparse_1 = accessor.sparse; + accessor._data = accessor._data.then(function (data) { + var typedArray = data; + var indicesBufferView = ArrayItem.Get("".concat(context, "/sparse/indices/bufferView"), _this._gltf.bufferViews, sparse_1.indices.bufferView); + var valuesBufferView = ArrayItem.Get("".concat(context, "/sparse/values/bufferView"), _this._gltf.bufferViews, sparse_1.values.bufferView); + return Promise.all([ + _this.loadBufferViewAsync("/bufferViews/".concat(indicesBufferView.index), indicesBufferView), + _this.loadBufferViewAsync("/bufferViews/".concat(valuesBufferView.index), valuesBufferView), + ]).then(function (_a) { + var indicesData = _a[0], valuesData = _a[1]; + var indices = GLTFLoader._GetTypedArray("".concat(context, "/sparse/indices"), sparse_1.indices.componentType, indicesData, sparse_1.indices.byteOffset, sparse_1.count); + var sparseLength = numComponents * sparse_1.count; + var values; + if (accessor.componentType === 5126 /* AccessorComponentType.FLOAT */ && !accessor.normalized) { + values = GLTFLoader._GetTypedArray("".concat(context, "/sparse/values"), accessor.componentType, valuesData, sparse_1.values.byteOffset, sparseLength); + } + else { + var sparseData = GLTFLoader._GetTypedArray("".concat(context, "/sparse/values"), accessor.componentType, valuesData, sparse_1.values.byteOffset, sparseLength); + values = new constructor(sparseLength); + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ForEach(sparseData, 0, byteStride, numComponents, accessor.componentType, values.length, accessor.normalized || false, function (value, index) { + values[index] = value; + }); + } + var valuesIndex = 0; + for (var indicesIndex = 0; indicesIndex < indices.length; indicesIndex++) { + var dataIndex = indices[indicesIndex] * numComponents; + for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) { + typedArray[dataIndex++] = values[valuesIndex++]; + } + } + return typedArray; + }); + }); + } + return accessor._data; + }; + /** + * @internal + */ + GLTFLoader.prototype._loadFloatAccessorAsync = function (context, accessor) { + return this._loadAccessorAsync(context, accessor, Float32Array); + }; + /** + * @internal + */ + GLTFLoader.prototype._loadIndicesAccessorAsync = function (context, accessor) { + if (accessor.type !== "SCALAR" /* AccessorType.SCALAR */) { + throw new Error("".concat(context, "/type: Invalid value ").concat(accessor.type)); + } + if (accessor.componentType !== 5121 /* AccessorComponentType.UNSIGNED_BYTE */ && + accessor.componentType !== 5123 /* AccessorComponentType.UNSIGNED_SHORT */ && + accessor.componentType !== 5125 /* AccessorComponentType.UNSIGNED_INT */) { + throw new Error("".concat(context, "/componentType: Invalid value ").concat(accessor.componentType)); + } + if (accessor._data) { + return accessor._data; + } + if (accessor.sparse) { + var constructor = GLTFLoader._GetTypedArrayConstructor("".concat(context, "/componentType"), accessor.componentType); + accessor._data = this._loadAccessorAsync(context, accessor, constructor); + } + else { + var bufferView = ArrayItem.Get("".concat(context, "/bufferView"), this._gltf.bufferViews, accessor.bufferView); + accessor._data = this.loadBufferViewAsync("/bufferViews/".concat(bufferView.index), bufferView).then(function (data) { + return GLTFLoader._GetTypedArray(context, accessor.componentType, data, accessor.byteOffset, accessor.count); + }); + } + return accessor._data; + }; + /** + * @internal + */ + GLTFLoader.prototype._loadVertexBufferViewAsync = function (bufferView) { + if (bufferView._babylonBuffer) { + return bufferView._babylonBuffer; + } + var engine = this._babylonScene.getEngine(); + bufferView._babylonBuffer = this.loadBufferViewAsync("/bufferViews/".concat(bufferView.index), bufferView).then(function (data) { + return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Buffer(engine, data, false); + }); + return bufferView._babylonBuffer; + }; + /** + * @internal + */ + GLTFLoader.prototype._loadVertexAccessorAsync = function (context, accessor, kind) { + var _a; + if ((_a = accessor._babylonVertexBuffer) === null || _a === void 0 ? void 0 : _a[kind]) { + return accessor._babylonVertexBuffer[kind]; + } + if (!accessor._babylonVertexBuffer) { + accessor._babylonVertexBuffer = {}; + } + var engine = this._babylonScene.getEngine(); + if (accessor.sparse || accessor.bufferView == undefined) { + accessor._babylonVertexBuffer[kind] = this._loadFloatAccessorAsync(context, accessor).then(function (data) { + return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer(engine, data, kind, false); + }); + } + else { + var bufferView_2 = ArrayItem.Get("".concat(context, "/bufferView"), this._gltf.bufferViews, accessor.bufferView); + accessor._babylonVertexBuffer[kind] = this._loadVertexBufferViewAsync(bufferView_2).then(function (babylonBuffer) { + var numComponents = GLTFLoader._GetNumComponents(context, accessor.type); + return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer(engine, babylonBuffer, kind, false, undefined, bufferView_2.byteStride, undefined, accessor.byteOffset, numComponents, accessor.componentType, accessor.normalized, true, undefined, true); + }); + } + return accessor._babylonVertexBuffer[kind]; + }; + GLTFLoader.prototype._loadMaterialMetallicRoughnessPropertiesAsync = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + if (properties) { + if (properties.baseColorFactor) { + babylonMaterial.albedoColor = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(properties.baseColorFactor); + babylonMaterial.alpha = properties.baseColorFactor[3]; + } + else { + babylonMaterial.albedoColor = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Color3.White(); + } + babylonMaterial.metallic = properties.metallicFactor == undefined ? 1 : properties.metallicFactor; + babylonMaterial.roughness = properties.roughnessFactor == undefined ? 1 : properties.roughnessFactor; + if (properties.baseColorTexture) { + promises.push(this.loadTextureInfoAsync("".concat(context, "/baseColorTexture"), properties.baseColorTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Base Color)"); + babylonMaterial.albedoTexture = texture; + })); + } + if (properties.metallicRoughnessTexture) { + properties.metallicRoughnessTexture.nonColorData = true; + promises.push(this.loadTextureInfoAsync("".concat(context, "/metallicRoughnessTexture"), properties.metallicRoughnessTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Metallic Roughness)"); + babylonMaterial.metallicTexture = texture; + })); + babylonMaterial.useMetallnessFromMetallicTextureBlue = true; + babylonMaterial.useRoughnessFromMetallicTextureGreen = true; + babylonMaterial.useRoughnessFromMetallicTextureAlpha = false; + } + } + return Promise.all(promises).then(function () { }); + }; + /** + * @internal + */ + GLTFLoader.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) { + if (assign === void 0) { assign = function () { }; } + var extensionPromise = this._extensionsLoadMaterialAsync(context, material, babylonMesh, babylonDrawMode, assign); + if (extensionPromise) { + return extensionPromise; + } + material._data = material._data || {}; + var babylonData = material._data[babylonDrawMode]; + if (!babylonData) { + this.logOpen("".concat(context, " ").concat(material.name || "")); + var babylonMaterial = this.createMaterial(context, material, babylonDrawMode); + babylonData = { + babylonMaterial: babylonMaterial, + babylonMeshes: [], + promise: this.loadMaterialPropertiesAsync(context, material, babylonMaterial), + }; + material._data[babylonDrawMode] = babylonData; + GLTFLoader.AddPointerMetadata(babylonMaterial, context); + this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial); + this.logClose(); + } + if (babylonMesh) { + babylonData.babylonMeshes.push(babylonMesh); + babylonMesh.onDisposeObservable.addOnce(function () { + var index = babylonData.babylonMeshes.indexOf(babylonMesh); + if (index !== -1) { + babylonData.babylonMeshes.splice(index, 1); + } + }); + } + assign(babylonData.babylonMaterial); + return babylonData.promise.then(function () { + return babylonData.babylonMaterial; + }); + }; + GLTFLoader.prototype._createDefaultMaterial = function (name, babylonDrawMode) { + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var babylonMaterial = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial(name, this._babylonScene); + babylonMaterial._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + // Moved to mesh so user can change materials on gltf meshes: babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation; + babylonMaterial.fillMode = babylonDrawMode; + babylonMaterial.enableSpecularAntiAliasing = true; + babylonMaterial.useRadianceOverAlpha = !this._parent.transparencyAsCoverage; + babylonMaterial.useSpecularOverAlpha = !this._parent.transparencyAsCoverage; + babylonMaterial.transparencyMode = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial.PBRMATERIAL_OPAQUE; + babylonMaterial.metallic = 1; + babylonMaterial.roughness = 1; + return babylonMaterial; + }; + /** + * Creates a Babylon material from a glTF material. + * @param context The context when loading the asset + * @param material The glTF material property + * @param babylonDrawMode The draw mode for the Babylon material + * @returns The Babylon material + */ + GLTFLoader.prototype.createMaterial = function (context, material, babylonDrawMode) { + var extensionPromise = this._extensionsCreateMaterial(context, material, babylonDrawMode); + if (extensionPromise) { + return extensionPromise; + } + var name = material.name || "material".concat(material.index); + var babylonMaterial = this._createDefaultMaterial(name, babylonDrawMode); + return babylonMaterial; + }; + /** + * Loads properties from a glTF material into a Babylon material. + * @param context The context when loading the asset + * @param material The glTF material property + * @param babylonMaterial The Babylon material + * @returns A promise that resolves when the load is complete + */ + GLTFLoader.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var extensionPromise = this._extensionsLoadMaterialPropertiesAsync(context, material, babylonMaterial); + if (extensionPromise) { + return extensionPromise; + } + var promises = new Array(); + promises.push(this.loadMaterialBasePropertiesAsync(context, material, babylonMaterial)); + if (material.pbrMetallicRoughness) { + promises.push(this._loadMaterialMetallicRoughnessPropertiesAsync("".concat(context, "/pbrMetallicRoughness"), material.pbrMetallicRoughness, babylonMaterial)); + } + this.loadMaterialAlphaProperties(context, material, babylonMaterial); + return Promise.all(promises).then(function () { }); + }; + /** + * Loads the normal, occlusion, and emissive properties from a glTF material into a Babylon material. + * @param context The context when loading the asset + * @param material The glTF material property + * @param babylonMaterial The Babylon material + * @returns A promise that resolves when the load is complete + */ + GLTFLoader.prototype.loadMaterialBasePropertiesAsync = function (context, material, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.emissiveColor = material.emissiveFactor ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(material.emissiveFactor) : new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Color3(0, 0, 0); + if (material.doubleSided) { + babylonMaterial.backFaceCulling = false; + babylonMaterial.twoSidedLighting = true; + } + if (material.normalTexture) { + material.normalTexture.nonColorData = true; + promises.push(this.loadTextureInfoAsync("".concat(context, "/normalTexture"), material.normalTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Normal)"); + babylonMaterial.bumpTexture = texture; + })); + babylonMaterial.invertNormalMapX = !this._babylonScene.useRightHandedSystem; + babylonMaterial.invertNormalMapY = this._babylonScene.useRightHandedSystem; + if (material.normalTexture.scale != undefined && babylonMaterial.bumpTexture) { + babylonMaterial.bumpTexture.level = material.normalTexture.scale; + } + babylonMaterial.forceIrradianceInFragment = true; + } + if (material.occlusionTexture) { + material.occlusionTexture.nonColorData = true; + promises.push(this.loadTextureInfoAsync("".concat(context, "/occlusionTexture"), material.occlusionTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Occlusion)"); + babylonMaterial.ambientTexture = texture; + })); + babylonMaterial.useAmbientInGrayScale = true; + if (material.occlusionTexture.strength != undefined) { + babylonMaterial.ambientTextureStrength = material.occlusionTexture.strength; + } + } + if (material.emissiveTexture) { + promises.push(this.loadTextureInfoAsync("".concat(context, "/emissiveTexture"), material.emissiveTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Emissive)"); + babylonMaterial.emissiveTexture = texture; + })); + } + return Promise.all(promises).then(function () { }); + }; + /** + * Loads the alpha properties from a glTF material into a Babylon material. + * Must be called after the setting the albedo texture of the Babylon material when the material has an albedo texture. + * @param context The context when loading the asset + * @param material The glTF material property + * @param babylonMaterial The Babylon material + */ + GLTFLoader.prototype.loadMaterialAlphaProperties = function (context, material, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var alphaMode = material.alphaMode || "OPAQUE" /* MaterialAlphaMode.OPAQUE */; + switch (alphaMode) { + case "OPAQUE" /* MaterialAlphaMode.OPAQUE */: { + babylonMaterial.transparencyMode = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial.PBRMATERIAL_OPAQUE; + babylonMaterial.alpha = 1.0; // Force alpha to 1.0 for opaque mode. + break; + } + case "MASK" /* MaterialAlphaMode.MASK */: { + babylonMaterial.transparencyMode = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial.PBRMATERIAL_ALPHATEST; + babylonMaterial.alphaCutOff = material.alphaCutoff == undefined ? 0.5 : material.alphaCutoff; + if (babylonMaterial.albedoTexture) { + babylonMaterial.albedoTexture.hasAlpha = true; + } + break; + } + case "BLEND" /* MaterialAlphaMode.BLEND */: { + babylonMaterial.transparencyMode = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial.PBRMATERIAL_ALPHABLEND; + if (babylonMaterial.albedoTexture) { + babylonMaterial.albedoTexture.hasAlpha = true; + babylonMaterial.useAlphaFromAlbedoTexture = true; + } + break; + } + default: { + throw new Error("".concat(context, "/alphaMode: Invalid value (").concat(material.alphaMode, ")")); + } + } + }; + /** + * Loads a glTF texture info. + * @param context The context when loading the asset + * @param textureInfo The glTF texture info property + * @param assign A function called synchronously after parsing the glTF properties + * @returns A promise that resolves with the loaded Babylon texture when the load is complete + */ + GLTFLoader.prototype.loadTextureInfoAsync = function (context, textureInfo, assign) { + var _this = this; + if (assign === void 0) { assign = function () { }; } + var extensionPromise = this._extensionsLoadTextureInfoAsync(context, textureInfo, assign); + if (extensionPromise) { + return extensionPromise; + } + this.logOpen("".concat(context)); + if (textureInfo.texCoord >= 6) { + throw new Error("".concat(context, "/texCoord: Invalid value (").concat(textureInfo.texCoord, ")")); + } + var texture = ArrayItem.Get("".concat(context, "/index"), this._gltf.textures, textureInfo.index); + texture._textureInfo = textureInfo; + var promise = this._loadTextureAsync("/textures/".concat(textureInfo.index), texture, function (babylonTexture) { + babylonTexture.coordinatesIndex = textureInfo.texCoord || 0; + GLTFLoader.AddPointerMetadata(babylonTexture, context); + _this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture); + assign(babylonTexture); + }); + this.logClose(); + return promise; + }; + /** + * @internal + */ + GLTFLoader.prototype._loadTextureAsync = function (context, texture, assign) { + if (assign === void 0) { assign = function () { }; } + var extensionPromise = this._extensionsLoadTextureAsync(context, texture, assign); + if (extensionPromise) { + return extensionPromise; + } + this.logOpen("".concat(context, " ").concat(texture.name || "")); + var sampler = texture.sampler == undefined ? GLTFLoader.DefaultSampler : ArrayItem.Get("".concat(context, "/sampler"), this._gltf.samplers, texture.sampler); + var image = ArrayItem.Get("".concat(context, "/source"), this._gltf.images, texture.source); + var promise = this._createTextureAsync(context, sampler, image, assign, undefined, !texture._textureInfo.nonColorData); + this.logClose(); + return promise; + }; + /** + * @internal + */ + GLTFLoader.prototype._createTextureAsync = function (context, sampler, image, assign, textureLoaderOptions, useSRGBBuffer) { + var _this = this; + if (assign === void 0) { assign = function () { }; } + var samplerData = this._loadSampler("/samplers/".concat(sampler.index), sampler); + var promises = new Array(); + var deferred = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Deferred(); + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var textureCreationOptions = { + noMipmap: samplerData.noMipMaps, + invertY: false, + samplingMode: samplerData.samplingMode, + onLoad: function () { + if (!_this._disposed) { + deferred.resolve(); + } + }, + onError: function (message, exception) { + if (!_this._disposed) { + deferred.reject(new Error("".concat(context, ": ").concat(exception && exception.message ? exception.message : message || "Failed to load texture"))); + } + }, + mimeType: image.mimeType, + loaderOptions: textureLoaderOptions, + useSRGBBuffer: !!useSRGBBuffer && this._parent.useSRGBBuffers, + }; + var babylonTexture = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture(null, this._babylonScene, textureCreationOptions); + babylonTexture._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + promises.push(deferred.promise); + promises.push(this.loadImageAsync("/images/".concat(image.index), image).then(function (data) { + var name = image.uri || "".concat(_this._fileName, "#image").concat(image.index); + var dataUrl = "data:".concat(_this._uniqueRootUrl).concat(name); + babylonTexture.updateURL(dataUrl, data); + // Set the internal texture label. + var internalTexture = babylonTexture.getInternalTexture(); + if (internalTexture) { + internalTexture.label = image.name; + } + })); + babylonTexture.wrapU = samplerData.wrapU; + babylonTexture.wrapV = samplerData.wrapV; + assign(babylonTexture); + if (this._parent.useGltfTextureNames) { + babylonTexture.name = image.name || image.uri || "image".concat(image.index); + } + return Promise.all(promises).then(function () { + return babylonTexture; + }); + }; + GLTFLoader.prototype._loadSampler = function (context, sampler) { + if (!sampler._data) { + sampler._data = { + noMipMaps: sampler.minFilter === 9728 /* TextureMinFilter.NEAREST */ || sampler.minFilter === 9729 /* TextureMinFilter.LINEAR */, + samplingMode: GLTFLoader._GetTextureSamplingMode(context, sampler), + wrapU: GLTFLoader._GetTextureWrapMode("".concat(context, "/wrapS"), sampler.wrapS), + wrapV: GLTFLoader._GetTextureWrapMode("".concat(context, "/wrapT"), sampler.wrapT), + }; + } + return sampler._data; + }; + /** + * Loads a glTF image. + * @param context The context when loading the asset + * @param image The glTF image property + * @returns A promise that resolves with the loaded data when the load is complete + */ + GLTFLoader.prototype.loadImageAsync = function (context, image) { + if (!image._data) { + this.logOpen("".concat(context, " ").concat(image.name || "")); + if (image.uri) { + image._data = this.loadUriAsync("".concat(context, "/uri"), image, image.uri); + } + else { + var bufferView = ArrayItem.Get("".concat(context, "/bufferView"), this._gltf.bufferViews, image.bufferView); + image._data = this.loadBufferViewAsync("/bufferViews/".concat(bufferView.index), bufferView); + } + this.logClose(); + } + return image._data; + }; + /** + * Loads a glTF uri. + * @param context The context when loading the asset + * @param property The glTF property associated with the uri + * @param uri The base64 or relative uri + * @returns A promise that resolves with the loaded data when the load is complete + */ + GLTFLoader.prototype.loadUriAsync = function (context, property, uri) { + var _this = this; + var extensionPromise = this._extensionsLoadUriAsync(context, property, uri); + if (extensionPromise) { + return extensionPromise; + } + if (!GLTFLoader._ValidateUri(uri)) { + throw new Error("".concat(context, ": '").concat(uri, "' is invalid")); + } + if ((0,babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.IsBase64DataUrl)(uri)) { + var data = new Uint8Array((0,babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.DecodeBase64UrlToBinary)(uri)); + this.log("".concat(context, ": Decoded ").concat(uri.substring(0, 64), "... (").concat(data.length, " bytes)")); + return Promise.resolve(data); + } + this.log("".concat(context, ": Loading ").concat(uri)); + return this._parent.preprocessUrlAsync(this._rootUrl + uri).then(function (url) { + return new Promise(function (resolve, reject) { + _this._parent._loadFile(_this._babylonScene, url, function (data) { + if (!_this._disposed) { + _this.log("".concat(context, ": Loaded ").concat(uri, " (").concat(data.byteLength, " bytes)")); + resolve(new Uint8Array(data)); + } + }, true, function (request) { + reject(new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.LoadFileError("".concat(context, ": Failed to load '").concat(uri, "'").concat(request ? ": " + request.status + " " + request.statusText : ""), request)); + }); + }); + }); + }; + /** + * Adds a JSON pointer to the _internalMetadata of the Babylon object at `._internalMetadata.gltf.pointers`. + * @param babylonObject the Babylon object with _internalMetadata + * @param pointer the JSON pointer + */ + GLTFLoader.AddPointerMetadata = function (babylonObject, pointer) { + babylonObject.metadata = babylonObject.metadata || {}; + var metadata = (babylonObject._internalMetadata = babylonObject._internalMetadata || {}); + var gltf = (metadata.gltf = metadata.gltf || {}); + var pointers = (gltf.pointers = gltf.pointers || []); + pointers.push(pointer); + }; + GLTFLoader._GetTextureWrapMode = function (context, mode) { + // Set defaults if undefined + mode = mode == undefined ? 10497 /* TextureWrapMode.REPEAT */ : mode; + switch (mode) { + case 33071 /* TextureWrapMode.CLAMP_TO_EDGE */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.CLAMP_ADDRESSMODE; + case 33648 /* TextureWrapMode.MIRRORED_REPEAT */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.MIRROR_ADDRESSMODE; + case 10497 /* TextureWrapMode.REPEAT */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.WRAP_ADDRESSMODE; + default: + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, ": Invalid value (").concat(mode, ")")); + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.WRAP_ADDRESSMODE; + } + }; + GLTFLoader._GetTextureSamplingMode = function (context, sampler) { + // Set defaults if undefined + var magFilter = sampler.magFilter == undefined ? 9729 /* TextureMagFilter.LINEAR */ : sampler.magFilter; + var minFilter = sampler.minFilter == undefined ? 9987 /* TextureMinFilter.LINEAR_MIPMAP_LINEAR */ : sampler.minFilter; + if (magFilter === 9729 /* TextureMagFilter.LINEAR */) { + switch (minFilter) { + case 9728 /* TextureMinFilter.NEAREST */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_NEAREST; + case 9729 /* TextureMinFilter.LINEAR */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_LINEAR; + case 9984 /* TextureMinFilter.NEAREST_MIPMAP_NEAREST */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_NEAREST_MIPNEAREST; + case 9985 /* TextureMinFilter.LINEAR_MIPMAP_NEAREST */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_LINEAR_MIPNEAREST; + case 9986 /* TextureMinFilter.NEAREST_MIPMAP_LINEAR */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_NEAREST_MIPLINEAR; + case 9987 /* TextureMinFilter.LINEAR_MIPMAP_LINEAR */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_LINEAR_MIPLINEAR; + default: + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, "/minFilter: Invalid value (").concat(minFilter, ")")); + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_LINEAR_MIPLINEAR; + } + } + else { + if (magFilter !== 9728 /* TextureMagFilter.NEAREST */) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, "/magFilter: Invalid value (").concat(magFilter, ")")); + } + switch (minFilter) { + case 9728 /* TextureMinFilter.NEAREST */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_NEAREST; + case 9729 /* TextureMinFilter.LINEAR */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_LINEAR; + case 9984 /* TextureMinFilter.NEAREST_MIPMAP_NEAREST */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_NEAREST_MIPNEAREST; + case 9985 /* TextureMinFilter.LINEAR_MIPMAP_NEAREST */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_LINEAR_MIPNEAREST; + case 9986 /* TextureMinFilter.NEAREST_MIPMAP_LINEAR */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_NEAREST_MIPLINEAR; + case 9987 /* TextureMinFilter.LINEAR_MIPMAP_LINEAR */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_LINEAR_MIPLINEAR; + default: + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, "/minFilter: Invalid value (").concat(minFilter, ")")); + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_NEAREST_MIPNEAREST; + } + } + }; + GLTFLoader._GetTypedArrayConstructor = function (context, componentType) { + switch (componentType) { + case 5120 /* AccessorComponentType.BYTE */: + return Int8Array; + case 5121 /* AccessorComponentType.UNSIGNED_BYTE */: + return Uint8Array; + case 5122 /* AccessorComponentType.SHORT */: + return Int16Array; + case 5123 /* AccessorComponentType.UNSIGNED_SHORT */: + return Uint16Array; + case 5125 /* AccessorComponentType.UNSIGNED_INT */: + return Uint32Array; + case 5126 /* AccessorComponentType.FLOAT */: + return Float32Array; + default: + throw new Error("".concat(context, ": Invalid component type ").concat(componentType)); + } + }; + GLTFLoader._GetTypedArray = function (context, componentType, bufferView, byteOffset, length) { + var buffer = bufferView.buffer; + byteOffset = bufferView.byteOffset + (byteOffset || 0); + var constructor = GLTFLoader._GetTypedArrayConstructor("".concat(context, "/componentType"), componentType); + var componentTypeLength = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.GetTypeByteLength(componentType); + if (byteOffset % componentTypeLength !== 0) { + // HACK: Copy the buffer if byte offset is not a multiple of component type byte length. + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, ": Copying buffer as byte offset (").concat(byteOffset, ") is not a multiple of component type byte length (").concat(componentTypeLength, ")")); + return new constructor(buffer.slice(byteOffset, byteOffset + length * componentTypeLength), 0); + } + return new constructor(buffer, byteOffset, length); + }; + GLTFLoader._GetNumComponents = function (context, type) { + switch (type) { + case "SCALAR": + return 1; + case "VEC2": + return 2; + case "VEC3": + return 3; + case "VEC4": + return 4; + case "MAT2": + return 4; + case "MAT3": + return 9; + case "MAT4": + return 16; + } + throw new Error("".concat(context, ": Invalid type (").concat(type, ")")); + }; + GLTFLoader._ValidateUri = function (uri) { + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Tools.IsBase64(uri) || uri.indexOf("..") === -1; + }; + /** + * @internal + */ + GLTFLoader._GetDrawMode = function (context, mode) { + if (mode == undefined) { + mode = 4 /* MeshPrimitiveMode.TRIANGLES */; + } + switch (mode) { + case 0 /* MeshPrimitiveMode.POINTS */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.PointListDrawMode; + case 1 /* MeshPrimitiveMode.LINES */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.LineListDrawMode; + case 2 /* MeshPrimitiveMode.LINE_LOOP */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.LineLoopDrawMode; + case 3 /* MeshPrimitiveMode.LINE_STRIP */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.LineStripDrawMode; + case 4 /* MeshPrimitiveMode.TRIANGLES */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleFillMode; + case 5 /* MeshPrimitiveMode.TRIANGLE_STRIP */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleStripDrawMode; + case 6 /* MeshPrimitiveMode.TRIANGLE_FAN */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleFanDrawMode; + } + throw new Error("".concat(context, ": Invalid mesh primitive mode (").concat(mode, ")")); + }; + GLTFLoader.prototype._compileMaterialsAsync = function () { + var _this = this; + this._parent._startPerformanceCounter("Compile materials"); + var promises = new Array(); + if (this._gltf.materials) { + for (var _i = 0, _a = this._gltf.materials; _i < _a.length; _i++) { + var material = _a[_i]; + if (material._data) { + for (var babylonDrawMode in material._data) { + var babylonData = material._data[babylonDrawMode]; + for (var _b = 0, _c = babylonData.babylonMeshes; _b < _c.length; _b++) { + var babylonMesh = _c[_b]; + // Ensure nonUniformScaling is set if necessary. + babylonMesh.computeWorldMatrix(true); + var babylonMaterial = babylonData.babylonMaterial; + promises.push(babylonMaterial.forceCompilationAsync(babylonMesh)); + promises.push(babylonMaterial.forceCompilationAsync(babylonMesh, { useInstances: true })); + if (this._parent.useClipPlane) { + promises.push(babylonMaterial.forceCompilationAsync(babylonMesh, { clipPlane: true })); + promises.push(babylonMaterial.forceCompilationAsync(babylonMesh, { clipPlane: true, useInstances: true })); + } + } + } + } + } + } + return Promise.all(promises).then(function () { + _this._parent._endPerformanceCounter("Compile materials"); + }); + }; + GLTFLoader.prototype._compileShadowGeneratorsAsync = function () { + var _this = this; + this._parent._startPerformanceCounter("Compile shadow generators"); + var promises = new Array(); + var lights = this._babylonScene.lights; + for (var _i = 0, lights_1 = lights; _i < lights_1.length; _i++) { + var light = lights_1[_i]; + var generator = light.getShadowGenerator(); + if (generator) { + promises.push(generator.forceCompilationAsync()); + } + } + return Promise.all(promises).then(function () { + _this._parent._endPerformanceCounter("Compile shadow generators"); + }); + }; + GLTFLoader.prototype._forEachExtensions = function (action) { + for (var _i = 0, _a = this._extensions; _i < _a.length; _i++) { + var extension = _a[_i]; + if (extension.enabled) { + action(extension); + } + } + }; + GLTFLoader.prototype._applyExtensions = function (property, functionName, actionAsync) { + for (var _i = 0, _a = this._extensions; _i < _a.length; _i++) { + var extension = _a[_i]; + if (extension.enabled) { + var id = "".concat(extension.name, ".").concat(functionName); + var loaderProperty = property; + loaderProperty._activeLoaderExtensionFunctions = loaderProperty._activeLoaderExtensionFunctions || {}; + var activeLoaderExtensionFunctions = loaderProperty._activeLoaderExtensionFunctions; + if (!activeLoaderExtensionFunctions[id]) { + activeLoaderExtensionFunctions[id] = true; + try { + var result = actionAsync(extension); + if (result) { + return result; + } + } + finally { + delete activeLoaderExtensionFunctions[id]; + } + } + } + } + return null; + }; + GLTFLoader.prototype._extensionsOnLoading = function () { + this._forEachExtensions(function (extension) { return extension.onLoading && extension.onLoading(); }); + }; + GLTFLoader.prototype._extensionsOnReady = function () { + this._forEachExtensions(function (extension) { return extension.onReady && extension.onReady(); }); + }; + GLTFLoader.prototype._extensionsLoadSceneAsync = function (context, scene) { + return this._applyExtensions(scene, "loadScene", function (extension) { return extension.loadSceneAsync && extension.loadSceneAsync(context, scene); }); + }; + GLTFLoader.prototype._extensionsLoadNodeAsync = function (context, node, assign) { + return this._applyExtensions(node, "loadNode", function (extension) { return extension.loadNodeAsync && extension.loadNodeAsync(context, node, assign); }); + }; + GLTFLoader.prototype._extensionsLoadCameraAsync = function (context, camera, assign) { + return this._applyExtensions(camera, "loadCamera", function (extension) { return extension.loadCameraAsync && extension.loadCameraAsync(context, camera, assign); }); + }; + GLTFLoader.prototype._extensionsLoadVertexDataAsync = function (context, primitive, babylonMesh) { + return this._applyExtensions(primitive, "loadVertexData", function (extension) { return extension._loadVertexDataAsync && extension._loadVertexDataAsync(context, primitive, babylonMesh); }); + }; + GLTFLoader.prototype._extensionsLoadMeshPrimitiveAsync = function (context, name, node, mesh, primitive, assign) { + return this._applyExtensions(primitive, "loadMeshPrimitive", function (extension) { return extension._loadMeshPrimitiveAsync && extension._loadMeshPrimitiveAsync(context, name, node, mesh, primitive, assign); }); + }; + GLTFLoader.prototype._extensionsLoadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) { + return this._applyExtensions(material, "loadMaterial", function (extension) { return extension._loadMaterialAsync && extension._loadMaterialAsync(context, material, babylonMesh, babylonDrawMode, assign); }); + }; + GLTFLoader.prototype._extensionsCreateMaterial = function (context, material, babylonDrawMode) { + return this._applyExtensions(material, "createMaterial", function (extension) { return extension.createMaterial && extension.createMaterial(context, material, babylonDrawMode); }); + }; + GLTFLoader.prototype._extensionsLoadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + return this._applyExtensions(material, "loadMaterialProperties", function (extension) { return extension.loadMaterialPropertiesAsync && extension.loadMaterialPropertiesAsync(context, material, babylonMaterial); }); + }; + GLTFLoader.prototype._extensionsLoadTextureInfoAsync = function (context, textureInfo, assign) { + return this._applyExtensions(textureInfo, "loadTextureInfo", function (extension) { return extension.loadTextureInfoAsync && extension.loadTextureInfoAsync(context, textureInfo, assign); }); + }; + GLTFLoader.prototype._extensionsLoadTextureAsync = function (context, texture, assign) { + return this._applyExtensions(texture, "loadTexture", function (extension) { return extension._loadTextureAsync && extension._loadTextureAsync(context, texture, assign); }); + }; + GLTFLoader.prototype._extensionsLoadAnimationAsync = function (context, animation) { + return this._applyExtensions(animation, "loadAnimation", function (extension) { return extension.loadAnimationAsync && extension.loadAnimationAsync(context, animation); }); + }; + GLTFLoader.prototype._extensionsLoadAnimationChannelAsync = function (context, animationContext, animation, channel, onLoad) { + return this._applyExtensions(animation, "loadAnimationChannel", function (extension) { return extension._loadAnimationChannelAsync && extension._loadAnimationChannelAsync(context, animationContext, animation, channel, onLoad); }); + }; + GLTFLoader.prototype._extensionsLoadSkinAsync = function (context, node, skin) { + return this._applyExtensions(skin, "loadSkin", function (extension) { return extension._loadSkinAsync && extension._loadSkinAsync(context, node, skin); }); + }; + GLTFLoader.prototype._extensionsLoadUriAsync = function (context, property, uri) { + return this._applyExtensions(property, "loadUri", function (extension) { return extension._loadUriAsync && extension._loadUriAsync(context, property, uri); }); + }; + GLTFLoader.prototype._extensionsLoadBufferViewAsync = function (context, bufferView) { + return this._applyExtensions(bufferView, "loadBufferView", function (extension) { return extension.loadBufferViewAsync && extension.loadBufferViewAsync(context, bufferView); }); + }; + GLTFLoader.prototype._extensionsLoadBufferAsync = function (context, buffer, byteOffset, byteLength) { + return this._applyExtensions(buffer, "loadBuffer", function (extension) { return extension.loadBufferAsync && extension.loadBufferAsync(context, buffer, byteOffset, byteLength); }); + }; + /** + * Helper method called by a loader extension to load an glTF extension. + * @param context The context when loading the asset + * @param property The glTF property to load the extension from + * @param extensionName The name of the extension to load + * @param actionAsync The action to run + * @returns The promise returned by actionAsync or null if the extension does not exist + */ + GLTFLoader.LoadExtensionAsync = function (context, property, extensionName, actionAsync) { + if (!property.extensions) { + return null; + } + var extensions = property.extensions; + var extension = extensions[extensionName]; + if (!extension) { + return null; + } + return actionAsync("".concat(context, "/extensions/").concat(extensionName), extension); + }; + /** + * Helper method called by a loader extension to load a glTF extra. + * @param context The context when loading the asset + * @param property The glTF property to load the extra from + * @param extensionName The name of the extension to load + * @param actionAsync The action to run + * @returns The promise returned by actionAsync or null if the extra does not exist + */ + GLTFLoader.LoadExtraAsync = function (context, property, extensionName, actionAsync) { + if (!property.extras) { + return null; + } + var extras = property.extras; + var extra = extras[extensionName]; + if (!extra) { + return null; + } + return actionAsync("".concat(context, "/extras/").concat(extensionName), extra); + }; + /** + * Checks for presence of an extension. + * @param name The name of the extension to check + * @returns A boolean indicating the presence of the given extension name in `extensionsUsed` + */ + GLTFLoader.prototype.isExtensionUsed = function (name) { + return !!this._gltf.extensionsUsed && this._gltf.extensionsUsed.indexOf(name) !== -1; + }; + /** + * Increments the indentation level and logs a message. + * @param message The message to log + */ + GLTFLoader.prototype.logOpen = function (message) { + this._parent._logOpen(message); + }; + /** + * Decrements the indentation level. + */ + GLTFLoader.prototype.logClose = function () { + this._parent._logClose(); + }; + /** + * Logs a message + * @param message The message to log + */ + GLTFLoader.prototype.log = function (message) { + this._parent._log(message); + }; + /** + * Starts a performance counter. + * @param counterName The name of the performance counter + */ + GLTFLoader.prototype.startPerformanceCounter = function (counterName) { + this._parent._startPerformanceCounter(counterName); + }; + /** + * Ends a performance counter. + * @param counterName The name of the performance counter + */ + GLTFLoader.prototype.endPerformanceCounter = function (counterName) { + this._parent._endPerformanceCounter(counterName); + }; + /** + * The default glTF sampler. + */ + GLTFLoader.DefaultSampler = { index: -1 }; + return GLTFLoader; +}()); + +_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFFileLoader._CreateGLTF2Loader = function (parent) { return new GLTFLoader(parent); }; + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/glTFLoaderAnimation.ts": +/*!****************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/glTFLoaderAnimation.ts ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ AnimationPropertyInfo: () => (/* binding */ AnimationPropertyInfo), +/* harmony export */ TransformNodeAnimationPropertyInfo: () => (/* binding */ TransformNodeAnimationPropertyInfo), +/* harmony export */ WeightAnimationPropertyInfo: () => (/* binding */ WeightAnimationPropertyInfo), +/* harmony export */ getQuaternion: () => (/* binding */ getQuaternion), +/* harmony export */ getVector3: () => (/* binding */ getVector3), +/* harmony export */ getWeights: () => (/* binding */ getWeights), +/* harmony export */ nodeAnimationData: () => (/* binding */ nodeAnimationData) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__); + + + +/** @internal */ +function getVector3(_target, source, offset, scale) { + return babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(source, offset).scaleInPlace(scale); +} +/** @internal */ +function getQuaternion(_target, source, offset, scale) { + return babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArray(source, offset).scaleInPlace(scale); +} +/** @internal */ +function getWeights(target, source, offset, scale) { + var value = new Array(target._numMorphTargets); + for (var i = 0; i < value.length; i++) { + value[i] = source[offset++] * scale; + } + return value; +} +/** @internal */ +var AnimationPropertyInfo = /** @class */ (function () { + /** @internal */ + function AnimationPropertyInfo(type, name, getValue, getStride) { + this.type = type; + this.name = name; + this.getValue = getValue; + this.getStride = getStride; + } + AnimationPropertyInfo.prototype._buildAnimation = function (name, fps, keys) { + var babylonAnimation = new babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation(name, this.name, fps, this.type); + babylonAnimation.setKeys(keys); + return babylonAnimation; + }; + return AnimationPropertyInfo; +}()); + +/** @internal */ +var TransformNodeAnimationPropertyInfo = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__extends)(TransformNodeAnimationPropertyInfo, _super); + function TransformNodeAnimationPropertyInfo() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** @internal */ + TransformNodeAnimationPropertyInfo.prototype.buildAnimations = function (target, name, fps, keys, callback) { + callback(target._babylonTransformNode, this._buildAnimation(name, fps, keys)); + }; + return TransformNodeAnimationPropertyInfo; +}(AnimationPropertyInfo)); + +/** @internal */ +var WeightAnimationPropertyInfo = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__extends)(WeightAnimationPropertyInfo, _super); + function WeightAnimationPropertyInfo() { + return _super !== null && _super.apply(this, arguments) || this; + } + WeightAnimationPropertyInfo.prototype.buildAnimations = function (target, name, fps, keys, callback) { + if (target._numMorphTargets) { + var _loop_1 = function (targetIndex) { + var babylonAnimation = new babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation("".concat(name, "_").concat(targetIndex), this_1.name, fps, this_1.type); + babylonAnimation.setKeys(keys.map(function (key) { return ({ + frame: key.frame, + inTangent: key.inTangent ? key.inTangent[targetIndex] : undefined, + value: key.value[targetIndex], + outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined, + interpolation: key.interpolation, + }); })); + if (target._primitiveBabylonMeshes) { + for (var _i = 0, _a = target._primitiveBabylonMeshes; _i < _a.length; _i++) { + var babylonMesh = _a[_i]; + if (babylonMesh.morphTargetManager) { + var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex); + var babylonAnimationClone = babylonAnimation.clone(); + morphTarget.animations.push(babylonAnimationClone); + callback(morphTarget, babylonAnimationClone); + } + } + } + }; + var this_1 = this; + for (var targetIndex = 0; targetIndex < target._numMorphTargets; targetIndex++) { + _loop_1(targetIndex); + } + } + }; + return WeightAnimationPropertyInfo; +}(AnimationPropertyInfo)); + +/** @internal */ +var nodeAnimationData = { + translation: [new TransformNodeAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_VECTOR3, "position", getVector3, function () { return 3; })], + rotation: [new TransformNodeAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_QUATERNION, "rotationQuaternion", getQuaternion, function () { return 4; })], + scale: [new TransformNodeAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_VECTOR3, "scaling", getVector3, function () { return 3; })], + weights: [new WeightAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "influence", getWeights, function (target) { return target._numMorphTargets; })], +}; + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtension.ts": +/*!****************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/glTFLoaderExtension.ts ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); + + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts": +/*!************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ registerGLTFExtension: () => (/* binding */ registerGLTFExtension), +/* harmony export */ registeredGLTFExtensions: () => (/* binding */ registeredGLTFExtensions), +/* harmony export */ unregisterGLTFExtension: () => (/* binding */ unregisterGLTFExtension) +/* harmony export */ }); +/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__); + +var _registeredGLTFExtensions = new Map(); +/** + * All currently registered glTF 2.0 loader extensions. + */ +var registeredGLTFExtensions = _registeredGLTFExtensions; +/** + * Registers a loader extension. + * @param name The name of the loader extension. + * @param isGLTFExtension If the loader extension is a glTF extension, then it will only be used for glTF files that use the corresponding glTF extension. Otherwise, it will be used for all loaded glTF files. + * @param factory The factory function that creates the loader extension. + */ +function registerGLTFExtension(name, isGLTFExtension, factory) { + if (unregisterGLTFExtension(name)) { + babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("Extension with the name '".concat(name, "' already exists")); + } + _registeredGLTFExtensions.set(name, { + isGLTFExtension: isGLTFExtension, + factory: factory, + }); +} +/** + * Unregisters a loader extension. + * @param name The name of the loader extension. + * @returns A boolean indicating whether the extension has been unregistered + */ +function unregisterGLTFExtension(name) { + return _registeredGLTFExtensions.delete(name); +} + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/glTFLoaderInterfaces.ts": +/*!*****************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/glTFLoaderInterfaces.ts ***! + \*****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); + + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/index.ts": +/*!**************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/index.ts ***! + \**************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ ArrayItem: () => (/* reexport safe */ _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem), +/* harmony export */ EXT_lights_image_based: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.EXT_lights_image_based), +/* harmony export */ EXT_mesh_gpu_instancing: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.EXT_mesh_gpu_instancing), +/* harmony export */ EXT_meshopt_compression: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.EXT_meshopt_compression), +/* harmony export */ EXT_texture_avif: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.EXT_texture_avif), +/* harmony export */ EXT_texture_webp: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.EXT_texture_webp), +/* harmony export */ ExtrasAsMetadata: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.ExtrasAsMetadata), +/* harmony export */ GLTFFileLoader: () => (/* reexport safe */ _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFFileLoader), +/* harmony export */ GLTFLoader: () => (/* reexport safe */ _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader), +/* harmony export */ KHR_animation_pointer: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_animation_pointer), +/* harmony export */ KHR_draco_mesh_compression: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_draco_mesh_compression), +/* harmony export */ KHR_interactivity: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_interactivity), +/* harmony export */ KHR_lights: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_lights), +/* harmony export */ KHR_materials_anisotropy: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_anisotropy), +/* harmony export */ KHR_materials_clearcoat: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_clearcoat), +/* harmony export */ KHR_materials_diffuse_transmission: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_diffuse_transmission), +/* harmony export */ KHR_materials_dispersion: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_dispersion), +/* harmony export */ KHR_materials_emissive_strength: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_emissive_strength), +/* harmony export */ KHR_materials_ior: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_ior), +/* harmony export */ KHR_materials_iridescence: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_iridescence), +/* harmony export */ KHR_materials_pbrSpecularGlossiness: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_pbrSpecularGlossiness), +/* harmony export */ KHR_materials_sheen: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_sheen), +/* harmony export */ KHR_materials_specular: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_specular), +/* harmony export */ KHR_materials_transmission: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_transmission), +/* harmony export */ KHR_materials_unlit: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_unlit), +/* harmony export */ KHR_materials_variants: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_variants), +/* harmony export */ KHR_materials_volume: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_volume), +/* harmony export */ KHR_mesh_quantization: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_mesh_quantization), +/* harmony export */ KHR_node_visibility: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_node_visibility), +/* harmony export */ KHR_texture_basisu: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_texture_basisu), +/* harmony export */ KHR_texture_transform: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_texture_transform), +/* harmony export */ KHR_xmp_json_ld: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_xmp_json_ld), +/* harmony export */ MSFT_audio_emitter: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.MSFT_audio_emitter), +/* harmony export */ MSFT_lod: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.MSFT_lod), +/* harmony export */ MSFT_minecraftMesh: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.MSFT_minecraftMesh), +/* harmony export */ MSFT_sRGBFactors: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.MSFT_sRGBFactors), +/* harmony export */ registerGLTFExtension: () => (/* reexport safe */ _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension), +/* harmony export */ registeredGLTFExtensions: () => (/* reexport safe */ _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registeredGLTFExtensions), +/* harmony export */ unregisterGLTFExtension: () => (/* reexport safe */ _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension) +/* harmony export */ }); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtension__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./glTFLoaderExtension */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtension.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); +/* harmony import */ var _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./glTFLoaderInterfaces */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderInterfaces.ts"); +/* harmony import */ var _Extensions_index__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Extensions/index */ "../../../dev/loaders/src/glTF/2.0/Extensions/index.ts"); +/* eslint-disable import/no-internal-modules */ + + + + + + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/glTFFileLoader.metadata.ts": +/*!****************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/glTFFileLoader.metadata.ts ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFFileLoaderMetadata: () => (/* binding */ GLTFFileLoaderMetadata), +/* harmony export */ GLTFMagicBase64Encoded: () => (/* binding */ GLTFMagicBase64Encoded) +/* harmony export */ }); +var GLTFMagicBase64Encoded = "Z2xURg"; // "glTF" base64 encoded (without the quotes!) +var GLTFFileLoaderMetadata = { + name: "gltf", + extensions: { + // eslint-disable-next-line @typescript-eslint/naming-convention + ".gltf": { isBinary: false, mimeType: "model/gltf+json" }, + // eslint-disable-next-line @typescript-eslint/naming-convention + ".glb": { isBinary: true, mimeType: "model/gltf-binary" }, + }, + canDirectLoad: function (data) { + return ((data.indexOf("asset") !== -1 && data.indexOf("version") !== -1) || + data.startsWith("data:base64," + GLTFMagicBase64Encoded) || // this is technically incorrect, but will continue to support for backcompat. + data.startsWith("data:;base64," + GLTFMagicBase64Encoded) || + data.startsWith("data:application/octet-stream;base64," + GLTFMagicBase64Encoded) || + data.startsWith("data:model/gltf-binary;base64," + GLTFMagicBase64Encoded)); + }, +}; + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/glTFFileLoader.ts": +/*!*******************************************************!*\ + !*** ../../../dev/loaders/src/glTF/glTFFileLoader.ts ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFFileLoader: () => (/* binding */ GLTFFileLoader), +/* harmony export */ GLTFLoaderAnimationStartMode: () => (/* binding */ GLTFLoaderAnimationStartMode), +/* harmony export */ GLTFLoaderCoordinateSystemMode: () => (/* binding */ GLTFLoaderCoordinateSystemMode), +/* harmony export */ GLTFLoaderState: () => (/* binding */ GLTFLoaderState) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/error */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFValidation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./glTFValidation */ "../../../dev/loaders/src/glTF/glTFValidation.ts"); +/* harmony import */ var _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glTFFileLoader.metadata */ "../../../dev/loaders/src/glTF/glTFFileLoader.metadata.ts"); + + + + + + + + + + + +function readAsync(arrayBuffer, byteOffset, byteLength) { + try { + return Promise.resolve(new Uint8Array(arrayBuffer, byteOffset, byteLength)); + } + catch (e) { + return Promise.reject(e); + } +} +function readViewAsync(arrayBufferView, byteOffset, byteLength) { + try { + if (byteOffset < 0 || byteOffset >= arrayBufferView.byteLength) { + throw new RangeError("Offset is out of range."); + } + if (byteOffset + byteLength > arrayBufferView.byteLength) { + throw new RangeError("Length is out of range."); + } + return Promise.resolve(new Uint8Array(arrayBufferView.buffer, arrayBufferView.byteOffset + byteOffset, byteLength)); + } + catch (e) { + return Promise.reject(e); + } +} +/** + * Mode that determines the coordinate system to use. + */ +var GLTFLoaderCoordinateSystemMode; +(function (GLTFLoaderCoordinateSystemMode) { + /** + * Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene. + */ + GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["AUTO"] = 0] = "AUTO"; + /** + * Sets the useRightHandedSystem flag on the scene. + */ + GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["FORCE_RIGHT_HANDED"] = 1] = "FORCE_RIGHT_HANDED"; +})(GLTFLoaderCoordinateSystemMode || (GLTFLoaderCoordinateSystemMode = {})); +/** + * Mode that determines what animations will start. + */ +var GLTFLoaderAnimationStartMode; +(function (GLTFLoaderAnimationStartMode) { + /** + * No animation will start. + */ + GLTFLoaderAnimationStartMode[GLTFLoaderAnimationStartMode["NONE"] = 0] = "NONE"; + /** + * The first animation will start. + */ + GLTFLoaderAnimationStartMode[GLTFLoaderAnimationStartMode["FIRST"] = 1] = "FIRST"; + /** + * All animations will start. + */ + GLTFLoaderAnimationStartMode[GLTFLoaderAnimationStartMode["ALL"] = 2] = "ALL"; +})(GLTFLoaderAnimationStartMode || (GLTFLoaderAnimationStartMode = {})); +/** + * Loader state. + */ +var GLTFLoaderState; +(function (GLTFLoaderState) { + /** + * The asset is loading. + */ + GLTFLoaderState[GLTFLoaderState["LOADING"] = 0] = "LOADING"; + /** + * The asset is ready for rendering. + */ + GLTFLoaderState[GLTFLoaderState["READY"] = 1] = "READY"; + /** + * The asset is completely loaded. + */ + GLTFLoaderState[GLTFLoaderState["COMPLETE"] = 2] = "COMPLETE"; +})(GLTFLoaderState || (GLTFLoaderState = {})); +var GLTFLoaderOptions = /** @class */ (function () { + function GLTFLoaderOptions() { + // ---------- + // V2 options + // ---------- + /** + * The coordinate system mode. Defaults to AUTO. + */ + this.coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO; + /** + * The animation start mode. Defaults to FIRST. + */ + this.animationStartMode = GLTFLoaderAnimationStartMode.FIRST; + /** + * Defines if the loader should load node animations. Defaults to true. + * NOTE: The animation of this node will still load if the node is also a joint of a skin and `loadSkins` is true. + */ + this.loadNodeAnimations = true; + /** + * Defines if the loader should load skins. Defaults to true. + */ + this.loadSkins = true; + /** + * Defines if the loader should load morph targets. Defaults to true. + */ + this.loadMorphTargets = true; + /** + * Defines if the loader should compile materials before raising the success callback. Defaults to false. + */ + this.compileMaterials = false; + /** + * Defines if the loader should also compile materials with clip planes. Defaults to false. + */ + this.useClipPlane = false; + /** + * Defines if the loader should compile shadow generators before raising the success callback. Defaults to false. + */ + this.compileShadowGenerators = false; + /** + * Defines if the Alpha blended materials are only applied as coverage. + * If false, (default) The luminance of each pixel will reduce its opacity to simulate the behaviour of most physical materials. + * If true, no extra effects are applied to transparent pixels. + */ + this.transparencyAsCoverage = false; + /** + * Defines if the loader should use range requests when load binary glTF files from HTTP. + * Enabling will disable offline support and glTF validator. + * Defaults to false. + */ + this.useRangeRequests = false; + /** + * Defines if the loader should create instances when multiple glTF nodes point to the same glTF mesh. Defaults to true. + */ + this.createInstances = true; + /** + * Defines if the loader should always compute the bounding boxes of meshes and not use the min/max values from the position accessor. Defaults to false. + */ + this.alwaysComputeBoundingBox = false; + /** + * If true, load all materials defined in the file, even if not used by any mesh. Defaults to false. + */ + this.loadAllMaterials = false; + /** + * If true, load only the materials defined in the file. Defaults to false. + */ + this.loadOnlyMaterials = false; + /** + * If true, do not load any materials defined in the file. Defaults to false. + */ + this.skipMaterials = false; + /** + * If true, load the color (gamma encoded) textures into sRGB buffers (if supported by the GPU), which will yield more accurate results when sampling the texture. Defaults to true. + */ + this.useSRGBBuffers = true; + /** + * When loading glTF animations, which are defined in seconds, target them to this FPS. Defaults to 60. + */ + this.targetFps = 60; + /** + * Defines if the loader should always compute the nearest common ancestor of the skeleton joints instead of using `skin.skeleton`. Defaults to false. + * Set this to true if loading assets with invalid `skin.skeleton` values. + */ + this.alwaysComputeSkeletonRootNode = false; + /** + * If true, the loader will derive the name for Babylon textures from the glTF texture name, image name, or image url. Defaults to false. + * Note that it is possible for multiple Babylon textures to share the same name when the Babylon textures load from the same glTF texture or image. + */ + this.useGltfTextureNames = false; + /** + * Function called before loading a url referenced by the asset. + * @param url url referenced by the asset + * @returns Async url to load + */ + this.preprocessUrlAsync = function (url) { return Promise.resolve(url); }; + /** + * Defines options for glTF extensions. + */ + this.extensionOptions = {}; + } + // eslint-disable-next-line babylonjs/available + GLTFLoaderOptions.prototype.copyFrom = function (options) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w; + if (options) { + this.onParsed = options.onParsed; + this.coordinateSystemMode = (_a = options.coordinateSystemMode) !== null && _a !== void 0 ? _a : this.coordinateSystemMode; + this.animationStartMode = (_b = options.animationStartMode) !== null && _b !== void 0 ? _b : this.animationStartMode; + this.loadNodeAnimations = (_c = options.loadNodeAnimations) !== null && _c !== void 0 ? _c : this.loadNodeAnimations; + this.loadSkins = (_d = options.loadSkins) !== null && _d !== void 0 ? _d : this.loadSkins; + this.loadMorphTargets = (_e = options.loadMorphTargets) !== null && _e !== void 0 ? _e : this.loadMorphTargets; + this.compileMaterials = (_f = options.compileMaterials) !== null && _f !== void 0 ? _f : this.compileMaterials; + this.useClipPlane = (_g = options.useClipPlane) !== null && _g !== void 0 ? _g : this.useClipPlane; + this.compileShadowGenerators = (_h = options.compileShadowGenerators) !== null && _h !== void 0 ? _h : this.compileShadowGenerators; + this.transparencyAsCoverage = (_j = options.transparencyAsCoverage) !== null && _j !== void 0 ? _j : this.transparencyAsCoverage; + this.useRangeRequests = (_k = options.useRangeRequests) !== null && _k !== void 0 ? _k : this.useRangeRequests; + this.createInstances = (_l = options.createInstances) !== null && _l !== void 0 ? _l : this.createInstances; + this.alwaysComputeBoundingBox = (_m = options.alwaysComputeBoundingBox) !== null && _m !== void 0 ? _m : this.alwaysComputeBoundingBox; + this.loadAllMaterials = (_o = options.loadAllMaterials) !== null && _o !== void 0 ? _o : this.loadAllMaterials; + this.loadOnlyMaterials = (_p = options.loadOnlyMaterials) !== null && _p !== void 0 ? _p : this.loadOnlyMaterials; + this.skipMaterials = (_q = options.skipMaterials) !== null && _q !== void 0 ? _q : this.skipMaterials; + this.useSRGBBuffers = (_r = options.useSRGBBuffers) !== null && _r !== void 0 ? _r : this.useSRGBBuffers; + this.targetFps = (_s = options.targetFps) !== null && _s !== void 0 ? _s : this.targetFps; + this.alwaysComputeSkeletonRootNode = (_t = options.alwaysComputeSkeletonRootNode) !== null && _t !== void 0 ? _t : this.alwaysComputeSkeletonRootNode; + this.useGltfTextureNames = (_u = options.useGltfTextureNames) !== null && _u !== void 0 ? _u : this.useGltfTextureNames; + this.preprocessUrlAsync = (_v = options.preprocessUrlAsync) !== null && _v !== void 0 ? _v : this.preprocessUrlAsync; + this.customRootNode = options.customRootNode; + this.onMeshLoaded = options.onMeshLoaded; + this.onSkinLoaded = options.onSkinLoaded; + this.onTextureLoaded = options.onTextureLoaded; + this.onMaterialLoaded = options.onMaterialLoaded; + this.onCameraLoaded = options.onCameraLoaded; + this.extensionOptions = (_w = options.extensionOptions) !== null && _w !== void 0 ? _w : this.extensionOptions; + } + }; + return GLTFLoaderOptions; +}()); +/** + * File loader for loading glTF files into a scene. + */ +var GLTFFileLoader = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_3__.__extends)(GLTFFileLoader, _super); + /** + * Creates a new glTF file loader. + * @param options The options for the loader + */ + function GLTFFileLoader(options) { + var _this = _super.call(this) || this; + // -------------------- + // Begin Common options + // -------------------- + /** + * Raised when the asset has been parsed + */ + _this.onParsedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + // -------------- + // End V1 options + // -------------- + /** + * Observable raised when the loader creates a mesh after parsing the glTF properties of the mesh. + * Note that the observable is raised as soon as the mesh object is created, meaning some data may not have been setup yet for this mesh (vertex data, morph targets, material, ...) + */ + _this.onMeshLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when the loader creates a skin after parsing the glTF properties of the skin node. + * @see https://doc.babylonjs.com/features/featuresDeepDive/importers/glTF/glTFSkinning#ignoring-the-transform-of-the-skinned-mesh + * @param node - the transform node that corresponds to the original glTF skin node used for animations + * @param skinnedNode - the transform node that is the skinned mesh itself or the parent of the skinned meshes + */ + _this.onSkinLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when the loader creates a texture after parsing the glTF properties of the texture. + */ + _this.onTextureLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when the loader creates a material after parsing the glTF properties of the material. + */ + _this.onMaterialLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when the loader creates a camera after parsing the glTF properties of the camera. + */ + _this.onCameraLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when the asset is completely loaded, immediately before the loader is disposed. + * For assets with LODs, raised when all of the LODs are complete. + * For assets without LODs, raised when the model is complete, immediately after the loader resolves the returned promise. + */ + _this.onCompleteObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when an error occurs. + */ + _this.onErrorObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised after the loader is disposed. + */ + _this.onDisposeObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised after a loader extension is created. + * Set additional options for a loader extension in this event. + */ + _this.onExtensionLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Defines if the loader should validate the asset. + */ + _this.validate = false; + /** + * Observable raised after validation when validate is set to true. The event data is the result of the validation. + */ + _this.onValidatedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + _this._loader = null; + _this._state = null; + _this._requests = new Array(); + /** + * Name of the loader ("gltf") + */ + _this.name = _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFFileLoaderMetadata.name; + /** @internal */ + _this.extensions = _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFFileLoaderMetadata.extensions; + /** + * Observable raised when the loader state changes. + */ + _this.onLoaderStateChangedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + _this._logIndentLevel = 0; + _this._loggingEnabled = false; + /** @internal */ + _this._log = _this._logDisabled; + _this._capturePerformanceCounters = false; + /** @internal */ + _this._startPerformanceCounter = _this._startPerformanceCounterDisabled; + /** @internal */ + _this._endPerformanceCounter = _this._endPerformanceCounterDisabled; + _this.copyFrom(options); + return _this; + } + Object.defineProperty(GLTFFileLoader.prototype, "onParsed", { + /** + * Raised when the asset has been parsed + */ + set: function (callback) { + if (this._onParsedObserver) { + this.onParsedObservable.remove(this._onParsedObserver); + } + if (callback) { + this._onParsedObserver = this.onParsedObservable.add(callback); + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onMeshLoaded", { + /** + * Callback raised when the loader creates a mesh after parsing the glTF properties of the mesh. + * Note that the callback is called as soon as the mesh object is created, meaning some data may not have been setup yet for this mesh (vertex data, morph targets, material, ...) + */ + set: function (callback) { + if (this._onMeshLoadedObserver) { + this.onMeshLoadedObservable.remove(this._onMeshLoadedObserver); + } + if (callback) { + this._onMeshLoadedObserver = this.onMeshLoadedObservable.add(callback); + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onSkinLoaded", { + /** + * Callback raised when the loader creates a skin after parsing the glTF properties of the skin node. + * @see https://doc.babylonjs.com/features/featuresDeepDive/importers/glTF/glTFSkinning#ignoring-the-transform-of-the-skinned-mesh + */ + set: function (callback) { + if (this._onSkinLoadedObserver) { + this.onSkinLoadedObservable.remove(this._onSkinLoadedObserver); + } + if (callback) { + this._onSkinLoadedObserver = this.onSkinLoadedObservable.add(function (data) { return callback(data.node, data.skinnedNode); }); + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onTextureLoaded", { + /** + * Callback raised when the loader creates a texture after parsing the glTF properties of the texture. + */ + set: function (callback) { + if (this._onTextureLoadedObserver) { + this.onTextureLoadedObservable.remove(this._onTextureLoadedObserver); + } + if (callback) { + this._onTextureLoadedObserver = this.onTextureLoadedObservable.add(callback); + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onMaterialLoaded", { + /** + * Callback raised when the loader creates a material after parsing the glTF properties of the material. + */ + set: function (callback) { + if (this._onMaterialLoadedObserver) { + this.onMaterialLoadedObservable.remove(this._onMaterialLoadedObserver); + } + if (callback) { + this._onMaterialLoadedObserver = this.onMaterialLoadedObservable.add(callback); + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onCameraLoaded", { + /** + * Callback raised when the loader creates a camera after parsing the glTF properties of the camera. + */ + set: function (callback) { + if (this._onCameraLoadedObserver) { + this.onCameraLoadedObservable.remove(this._onCameraLoadedObserver); + } + if (callback) { + this._onCameraLoadedObserver = this.onCameraLoadedObservable.add(callback); + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onComplete", { + /** + * Callback raised when the asset is completely loaded, immediately before the loader is disposed. + * For assets with LODs, raised when all of the LODs are complete. + * For assets without LODs, raised when the model is complete, immediately after the loader resolves the returned promise. + */ + set: function (callback) { + if (this._onCompleteObserver) { + this.onCompleteObservable.remove(this._onCompleteObserver); + } + this._onCompleteObserver = this.onCompleteObservable.add(callback); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onError", { + /** + * Callback raised when an error occurs. + */ + set: function (callback) { + if (this._onErrorObserver) { + this.onErrorObservable.remove(this._onErrorObserver); + } + this._onErrorObserver = this.onErrorObservable.add(callback); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onDispose", { + /** + * Callback raised after the loader is disposed. + */ + set: function (callback) { + if (this._onDisposeObserver) { + this.onDisposeObservable.remove(this._onDisposeObserver); + } + this._onDisposeObserver = this.onDisposeObservable.add(callback); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", { + /** + * Callback raised after a loader extension is created. + */ + set: function (callback) { + if (this._onExtensionLoadedObserver) { + this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver); + } + this._onExtensionLoadedObserver = this.onExtensionLoadedObservable.add(callback); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "loggingEnabled", { + /** + * Defines if the loader logging is enabled. + */ + get: function () { + return this._loggingEnabled; + }, + set: function (value) { + if (this._loggingEnabled === value) { + return; + } + this._loggingEnabled = value; + if (this._loggingEnabled) { + this._log = this._logEnabled; + } + else { + this._log = this._logDisabled; + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "capturePerformanceCounters", { + /** + * Defines if the loader should capture performance counters. + */ + get: function () { + return this._capturePerformanceCounters; + }, + set: function (value) { + if (this._capturePerformanceCounters === value) { + return; + } + this._capturePerformanceCounters = value; + if (this._capturePerformanceCounters) { + this._startPerformanceCounter = this._startPerformanceCounterEnabled; + this._endPerformanceCounter = this._endPerformanceCounterEnabled; + } + else { + this._startPerformanceCounter = this._startPerformanceCounterDisabled; + this._endPerformanceCounter = this._endPerformanceCounterDisabled; + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onValidated", { + /** + * Callback raised after a loader extension is created. + */ + set: function (callback) { + if (this._onValidatedObserver) { + this.onValidatedObservable.remove(this._onValidatedObserver); + } + this._onValidatedObserver = this.onValidatedObservable.add(callback); + }, + enumerable: false, + configurable: true + }); + /** + * Disposes the loader, releases resources during load, and cancels any outstanding requests. + */ + GLTFFileLoader.prototype.dispose = function () { + if (this._loader) { + this._loader.dispose(); + this._loader = null; + } + for (var _i = 0, _a = this._requests; _i < _a.length; _i++) { + var request = _a[_i]; + request.abort(); + } + this._requests.length = 0; + delete this._progressCallback; + this.preprocessUrlAsync = function (url) { return Promise.resolve(url); }; + this.onMeshLoadedObservable.clear(); + this.onSkinLoadedObservable.clear(); + this.onTextureLoadedObservable.clear(); + this.onMaterialLoadedObservable.clear(); + this.onCameraLoadedObservable.clear(); + this.onCompleteObservable.clear(); + this.onExtensionLoadedObservable.clear(); + this.onDisposeObservable.notifyObservers(undefined); + this.onDisposeObservable.clear(); + }; + /** + * @internal + */ + GLTFFileLoader.prototype.loadFile = function (scene, fileOrUrl, rootUrl, onSuccess, onProgress, useArrayBuffer, onError, name) { + var _this = this; + if (ArrayBuffer.isView(fileOrUrl)) { + this._loadBinary(scene, fileOrUrl, rootUrl, onSuccess, onError, name); + return null; + } + this._progressCallback = onProgress; + var fileName = fileOrUrl.name || babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Tools.GetFilename(fileOrUrl); + if (useArrayBuffer) { + if (this.useRangeRequests) { + if (this.validate) { + babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("glTF validation is not supported when range requests are enabled"); + } + var fileRequest_1 = { + abort: function () { }, + onCompleteObservable: new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(), + }; + var dataBuffer = { + readAsync: function (byteOffset, byteLength) { + return new Promise(function (resolve, reject) { + _this._loadFile(scene, fileOrUrl, function (data) { + resolve(new Uint8Array(data)); + }, true, function (error) { + reject(error); + }, function (webRequest) { + webRequest.setRequestHeader("Range", "bytes=".concat(byteOffset, "-").concat(byteOffset + byteLength - 1)); + }); + }); + }, + byteLength: 0, + }; + this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.DataReader(dataBuffer)).then(function (loaderData) { + fileRequest_1.onCompleteObservable.notifyObservers(fileRequest_1); + onSuccess(loaderData); + }, onError ? function (error) { return onError(undefined, error); } : undefined); + return fileRequest_1; + } + return this._loadFile(scene, fileOrUrl, function (data) { + _this._validate(scene, new Uint8Array(data, 0, data.byteLength), rootUrl, fileName); + _this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.DataReader({ + readAsync: function (byteOffset, byteLength) { return readAsync(data, byteOffset, byteLength); }, + byteLength: data.byteLength, + })).then(function (loaderData) { + onSuccess(loaderData); + }, onError ? function (error) { return onError(undefined, error); } : undefined); + }, true, onError); + } + else { + return this._loadFile(scene, fileOrUrl, function (data) { + try { + _this._validate(scene, data, rootUrl, fileName); + onSuccess({ json: _this._parseJson(data) }); + } + catch (_a) { + if (onError) { + onError(); + } + } + }, false, onError); + } + }; + GLTFFileLoader.prototype._loadBinary = function (scene, data, rootUrl, onSuccess, onError, fileName) { + this._validate(scene, new Uint8Array(data.buffer, data.byteOffset, data.byteLength), rootUrl, fileName); + this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.DataReader({ + readAsync: function (byteOffset, byteLength) { return readViewAsync(data, byteOffset, byteLength); }, + byteLength: data.byteLength, + })).then(function (loaderData) { + onSuccess(loaderData); + }, onError ? function (error) { return onError(undefined, error); } : undefined); + }; + /** + * @internal + */ + GLTFFileLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress, fileName) { + var _this = this; + return Promise.resolve().then(function () { + _this.onParsedObservable.notifyObservers(data); + _this.onParsedObservable.clear(); + _this._log("Loading ".concat(fileName || "")); + _this._loader = _this._getLoader(data); + return _this._loader.importMeshAsync(meshesNames, scene, null, data, rootUrl, onProgress, fileName); + }); + }; + /** + * @internal + */ + GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress, fileName) { + var _this = this; + return Promise.resolve().then(function () { + _this.onParsedObservable.notifyObservers(data); + _this.onParsedObservable.clear(); + _this._log("Loading ".concat(fileName || "")); + _this._loader = _this._getLoader(data); + return _this._loader.loadAsync(scene, data, rootUrl, onProgress, fileName); + }); + }; + /** + * @internal + */ + GLTFFileLoader.prototype.loadAssetContainerAsync = function (scene, data, rootUrl, onProgress, fileName) { + var _this = this; + return Promise.resolve().then(function () { + _this.onParsedObservable.notifyObservers(data); + _this.onParsedObservable.clear(); + _this._log("Loading ".concat(fileName || "")); + _this._loader = _this._getLoader(data); + // Prepare the asset container. + var container = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.AssetContainer(scene); + // Get materials/textures when loading to add to container + var materials = []; + _this.onMaterialLoadedObservable.add(function (material) { + materials.push(material); + }); + var textures = []; + _this.onTextureLoadedObservable.add(function (texture) { + textures.push(texture); + }); + var cameras = []; + _this.onCameraLoadedObservable.add(function (camera) { + cameras.push(camera); + }); + var morphTargetManagers = []; + _this.onMeshLoadedObservable.add(function (mesh) { + if (mesh.morphTargetManager) { + morphTargetManagers.push(mesh.morphTargetManager); + } + }); + return _this._loader.importMeshAsync(null, scene, container, data, rootUrl, onProgress, fileName).then(function (result) { + Array.prototype.push.apply(container.geometries, result.geometries); + Array.prototype.push.apply(container.meshes, result.meshes); + Array.prototype.push.apply(container.particleSystems, result.particleSystems); + Array.prototype.push.apply(container.skeletons, result.skeletons); + Array.prototype.push.apply(container.animationGroups, result.animationGroups); + Array.prototype.push.apply(container.materials, materials); + Array.prototype.push.apply(container.textures, textures); + Array.prototype.push.apply(container.lights, result.lights); + Array.prototype.push.apply(container.transformNodes, result.transformNodes); + Array.prototype.push.apply(container.cameras, cameras); + Array.prototype.push.apply(container.morphTargetManagers, morphTargetManagers); + return container; + }); + }); + }; + /** + * @internal + */ + GLTFFileLoader.prototype.canDirectLoad = function (data) { + return _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFFileLoaderMetadata.canDirectLoad(data); + }; + /** + * @internal + */ + GLTFFileLoader.prototype.directLoad = function (scene, data) { + if (data.startsWith("base64," + _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFMagicBase64Encoded) || // this is technically incorrect, but will continue to support for backcompat. + data.startsWith(";base64," + _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFMagicBase64Encoded) || + data.startsWith("application/octet-stream;base64," + _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFMagicBase64Encoded) || + data.startsWith("model/gltf-binary;base64," + _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFMagicBase64Encoded)) { + var arrayBuffer_1 = (0,babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.DecodeBase64UrlToBinary)(data); + this._validate(scene, new Uint8Array(arrayBuffer_1, 0, arrayBuffer_1.byteLength)); + return this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.DataReader({ + readAsync: function (byteOffset, byteLength) { return readAsync(arrayBuffer_1, byteOffset, byteLength); }, + byteLength: arrayBuffer_1.byteLength, + })); + } + this._validate(scene, data); + return Promise.resolve({ json: this._parseJson(data) }); + }; + /** @internal */ + GLTFFileLoader.prototype.createPlugin = function (options) { + return new GLTFFileLoader(options[_glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFFileLoaderMetadata.name]); + }; + Object.defineProperty(GLTFFileLoader.prototype, "loaderState", { + /** + * The loader state or null if the loader is not active. + */ + get: function () { + return this._state; + }, + enumerable: false, + configurable: true + }); + /** + * Returns a promise that resolves when the asset is completely loaded. + * @returns a promise that resolves when the asset is completely loaded. + */ + GLTFFileLoader.prototype.whenCompleteAsync = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.onCompleteObservable.addOnce(function () { + resolve(); + }); + _this.onErrorObservable.addOnce(function (reason) { + reject(reason); + }); + }); + }; + /** + * @internal + */ + GLTFFileLoader.prototype._setState = function (state) { + if (this._state === state) { + return; + } + this._state = state; + this.onLoaderStateChangedObservable.notifyObservers(this._state); + this._log(GLTFLoaderState[this._state]); + }; + /** + * @internal + */ + GLTFFileLoader.prototype._loadFile = function (scene, fileOrUrl, onSuccess, useArrayBuffer, onError, onOpened) { + var _this = this; + var request = scene._loadFile(fileOrUrl, onSuccess, function (event) { + _this._onProgress(event, request); + }, true, useArrayBuffer, onError, onOpened); + request.onCompleteObservable.add(function () { + // Force the length computable to be true since we can guarantee the data is loaded. + request._lengthComputable = true; + request._total = request._loaded; + }); + this._requests.push(request); + return request; + }; + GLTFFileLoader.prototype._onProgress = function (event, request) { + if (!this._progressCallback) { + return; + } + request._lengthComputable = event.lengthComputable; + request._loaded = event.loaded; + request._total = event.total; + var lengthComputable = true; + var loaded = 0; + var total = 0; + for (var _i = 0, _a = this._requests; _i < _a.length; _i++) { + var request_1 = _a[_i]; + if (request_1._lengthComputable === undefined || request_1._loaded === undefined || request_1._total === undefined) { + return; + } + lengthComputable = lengthComputable && request_1._lengthComputable; + loaded += request_1._loaded; + total += request_1._total; + } + this._progressCallback({ + lengthComputable: lengthComputable, + loaded: loaded, + total: lengthComputable ? total : 0, + }); + }; + GLTFFileLoader.prototype._validate = function (scene, data, rootUrl, fileName) { + var _this = this; + if (rootUrl === void 0) { rootUrl = ""; } + if (fileName === void 0) { fileName = ""; } + if (!this.validate) { + return; + } + this._startPerformanceCounter("Validate JSON"); + _glTFValidation__WEBPACK_IMPORTED_MODULE_1__.GLTFValidation.ValidateAsync(data, rootUrl, fileName, function (uri) { + return _this.preprocessUrlAsync(rootUrl + uri).then(function (url) { + return scene._loadFileAsync(url, undefined, true, true).then(function (data) { + return new Uint8Array(data, 0, data.byteLength); + }); + }); + }).then(function (result) { + _this._endPerformanceCounter("Validate JSON"); + _this.onValidatedObservable.notifyObservers(result); + _this.onValidatedObservable.clear(); + }, function (reason) { + _this._endPerformanceCounter("Validate JSON"); + babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("Failed to validate: ".concat(reason.message)); + _this.onValidatedObservable.clear(); + }); + }; + GLTFFileLoader.prototype._getLoader = function (loaderData) { + var asset = loaderData.json.asset || {}; + this._log("Asset version: ".concat(asset.version)); + asset.minVersion && this._log("Asset minimum version: ".concat(asset.minVersion)); + asset.generator && this._log("Asset generator: ".concat(asset.generator)); + var version = GLTFFileLoader._parseVersion(asset.version); + if (!version) { + throw new Error("Invalid version: " + asset.version); + } + if (asset.minVersion !== undefined) { + var minVersion = GLTFFileLoader._parseVersion(asset.minVersion); + if (!minVersion) { + throw new Error("Invalid minimum version: " + asset.minVersion); + } + if (GLTFFileLoader._compareVersion(minVersion, { major: 2, minor: 0 }) > 0) { + throw new Error("Incompatible minimum version: " + asset.minVersion); + } + } + var createLoaders = { + 1: GLTFFileLoader._CreateGLTF1Loader, + 2: GLTFFileLoader._CreateGLTF2Loader, + }; + var createLoader = createLoaders[version.major]; + if (!createLoader) { + throw new Error("Unsupported version: " + asset.version); + } + return createLoader(this); + }; + GLTFFileLoader.prototype._parseJson = function (json) { + this._startPerformanceCounter("Parse JSON"); + this._log("JSON length: ".concat(json.length)); + var parsed = JSON.parse(json); + this._endPerformanceCounter("Parse JSON"); + return parsed; + }; + GLTFFileLoader.prototype._unpackBinaryAsync = function (dataReader) { + var _this = this; + this._startPerformanceCounter("Unpack Binary"); + // Read magic + version + length + json length + json format + return dataReader.loadAsync(20).then(function () { + var Binary = { + Magic: 0x46546c67, + }; + var magic = dataReader.readUint32(); + if (magic !== Binary.Magic) { + throw new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.RuntimeError("Unexpected magic: " + magic, babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.ErrorCodes.GLTFLoaderUnexpectedMagicError); + } + var version = dataReader.readUint32(); + if (_this.loggingEnabled) { + _this._log("Binary version: ".concat(version)); + } + var length = dataReader.readUint32(); + if (!_this.useRangeRequests && length !== dataReader.buffer.byteLength) { + babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("Length in header does not match actual data length: ".concat(length, " != ").concat(dataReader.buffer.byteLength)); + } + var unpacked; + switch (version) { + case 1: { + unpacked = _this._unpackBinaryV1Async(dataReader, length); + break; + } + case 2: { + unpacked = _this._unpackBinaryV2Async(dataReader, length); + break; + } + default: { + throw new Error("Unsupported version: " + version); + } + } + _this._endPerformanceCounter("Unpack Binary"); + return unpacked; + }); + }; + GLTFFileLoader.prototype._unpackBinaryV1Async = function (dataReader, length) { + var ContentFormat = { + JSON: 0, + }; + var contentLength = dataReader.readUint32(); + var contentFormat = dataReader.readUint32(); + if (contentFormat !== ContentFormat.JSON) { + throw new Error("Unexpected content format: ".concat(contentFormat)); + } + var bodyLength = length - dataReader.byteOffset; + var data = { json: this._parseJson(dataReader.readString(contentLength)), bin: null }; + if (bodyLength !== 0) { + var startByteOffset_1 = dataReader.byteOffset; + data.bin = { + readAsync: function (byteOffset, byteLength) { return dataReader.buffer.readAsync(startByteOffset_1 + byteOffset, byteLength); }, + byteLength: bodyLength, + }; + } + return Promise.resolve(data); + }; + GLTFFileLoader.prototype._unpackBinaryV2Async = function (dataReader, length) { + var _this = this; + var ChunkFormat = { + JSON: 0x4e4f534a, + BIN: 0x004e4942, + }; + // Read the JSON chunk header. + var chunkLength = dataReader.readUint32(); + var chunkFormat = dataReader.readUint32(); + if (chunkFormat !== ChunkFormat.JSON) { + throw new Error("First chunk format is not JSON"); + } + // Bail if there are no other chunks. + if (dataReader.byteOffset + chunkLength === length) { + return dataReader.loadAsync(chunkLength).then(function () { + return { json: _this._parseJson(dataReader.readString(chunkLength)), bin: null }; + }); + } + // Read the JSON chunk and the length and type of the next chunk. + return dataReader.loadAsync(chunkLength + 8).then(function () { + var data = { json: _this._parseJson(dataReader.readString(chunkLength)), bin: null }; + var readAsync = function () { + var chunkLength = dataReader.readUint32(); + var chunkFormat = dataReader.readUint32(); + switch (chunkFormat) { + case ChunkFormat.JSON: { + throw new Error("Unexpected JSON chunk"); + } + case ChunkFormat.BIN: { + var startByteOffset_2 = dataReader.byteOffset; + data.bin = { + readAsync: function (byteOffset, byteLength) { return dataReader.buffer.readAsync(startByteOffset_2 + byteOffset, byteLength); }, + byteLength: chunkLength, + }; + dataReader.skipBytes(chunkLength); + break; + } + default: { + // ignore unrecognized chunkFormat + dataReader.skipBytes(chunkLength); + break; + } + } + if (dataReader.byteOffset !== length) { + return dataReader.loadAsync(8).then(readAsync); + } + return Promise.resolve(data); + }; + return readAsync(); + }); + }; + GLTFFileLoader._parseVersion = function (version) { + if (version === "1.0" || version === "1.0.1") { + return { + major: 1, + minor: 0, + }; + } + var match = (version + "").match(/^(\d+)\.(\d+)/); + if (!match) { + return null; + } + return { + major: parseInt(match[1]), + minor: parseInt(match[2]), + }; + }; + GLTFFileLoader._compareVersion = function (a, b) { + if (a.major > b.major) { + return 1; + } + if (a.major < b.major) { + return -1; + } + if (a.minor > b.minor) { + return 1; + } + if (a.minor < b.minor) { + return -1; + } + return 0; + }; + /** + * @internal + */ + GLTFFileLoader.prototype._logOpen = function (message) { + this._log(message); + this._logIndentLevel++; + }; + /** @internal */ + GLTFFileLoader.prototype._logClose = function () { + --this._logIndentLevel; + }; + GLTFFileLoader.prototype._logEnabled = function (message) { + var spaces = GLTFFileLoader._logSpaces.substring(0, this._logIndentLevel * 2); + babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Logger.Log("".concat(spaces).concat(message)); + }; + GLTFFileLoader.prototype._logDisabled = function (message) { }; + GLTFFileLoader.prototype._startPerformanceCounterEnabled = function (counterName) { + babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Tools.StartPerformanceCounter(counterName); + }; + GLTFFileLoader.prototype._startPerformanceCounterDisabled = function (counterName) { }; + GLTFFileLoader.prototype._endPerformanceCounterEnabled = function (counterName) { + babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Tools.EndPerformanceCounter(counterName); + }; + GLTFFileLoader.prototype._endPerformanceCounterDisabled = function (counterName) { }; + // ------------------ + // End Common options + // ------------------ + // ---------------- + // Begin V1 options + // ---------------- + /** + * Set this property to false to disable incremental loading which delays the loader from calling the success callback until after loading the meshes and shaders. + * Textures always loads asynchronously. For example, the success callback can compute the bounding information of the loaded meshes when incremental loading is disabled. + * Defaults to true. + * @internal + */ + GLTFFileLoader.IncrementalLoading = true; + /** + * Set this property to true in order to work with homogeneous coordinates, available with some converters and exporters. + * Defaults to false. See https://en.wikipedia.org/wiki/Homogeneous_coordinates. + * @internal + */ + GLTFFileLoader.HomogeneousCoordinates = false; + GLTFFileLoader._logSpaces = " "; + return GLTFFileLoader; +}(GLTFLoaderOptions)); + +(0,babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.registerSceneLoaderPlugin)(new GLTFFileLoader()); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/glTFValidation.ts": +/*!*******************************************************!*\ + !*** ../../../dev/loaders/src/glTF/glTFValidation.ts ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFValidation: () => (/* binding */ GLTFValidation) +/* harmony export */ }); +/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__); + +function validateAsync(data, rootUrl, fileName, getExternalResource) { + var options = { + externalResourceFunction: getExternalResource, + }; + if (fileName) { + options.uri = rootUrl === "file:" ? fileName : rootUrl + fileName; + } + return ArrayBuffer.isView(data) ? GLTFValidator.validateBytes(data, options) : GLTFValidator.validateString(data, options); +} +/** + * The worker function that gets converted to a blob url to pass into a worker. + */ +function workerFunc() { + var pendingExternalResources = []; + onmessage = function (message) { + var data = message.data; + switch (data.id) { + case "init": { + importScripts(data.url); + break; + } + case "validate": { + validateAsync(data.data, data.rootUrl, data.fileName, function (uri) { + return new Promise(function (resolve, reject) { + var index = pendingExternalResources.length; + pendingExternalResources.push({ resolve: resolve, reject: reject }); + postMessage({ id: "getExternalResource", index: index, uri: uri }); + }); + }).then(function (value) { + postMessage({ id: "validate.resolve", value: value }); + }, function (reason) { + postMessage({ id: "validate.reject", reason: reason }); + }); + break; + } + case "getExternalResource.resolve": { + pendingExternalResources[data.index].resolve(data.value); + break; + } + case "getExternalResource.reject": { + pendingExternalResources[data.index].reject(data.reason); + break; + } + } + }; +} +/** + * glTF validation + */ +var GLTFValidation = /** @class */ (function () { + function GLTFValidation() { + } + /** + * Validate a glTF asset using the glTF-Validator. + * @param data The JSON of a glTF or the array buffer of a binary glTF + * @param rootUrl The root url for the glTF + * @param fileName The file name for the glTF + * @param getExternalResource The callback to get external resources for the glTF validator + * @returns A promise that resolves with the glTF validation results once complete + */ + GLTFValidation.ValidateAsync = function (data, rootUrl, fileName, getExternalResource) { + var _this = this; + if (typeof Worker === "function") { + return new Promise(function (resolve, reject) { + var workerContent = "".concat(validateAsync, "(").concat(workerFunc, ")()"); + var workerBlobUrl = URL.createObjectURL(new Blob([workerContent], { type: "application/javascript" })); + var worker = new Worker(workerBlobUrl); + var onError = function (error) { + worker.removeEventListener("error", onError); + worker.removeEventListener("message", onMessage); + reject(error); + }; + var onMessage = function (message) { + var data = message.data; + switch (data.id) { + case "getExternalResource": { + getExternalResource(data.uri).then(function (value) { + worker.postMessage({ id: "getExternalResource.resolve", index: data.index, value: value }, [value.buffer]); + }, function (reason) { + worker.postMessage({ id: "getExternalResource.reject", index: data.index, reason: reason }); + }); + break; + } + case "validate.resolve": { + worker.removeEventListener("error", onError); + worker.removeEventListener("message", onMessage); + resolve(data.value); + worker.terminate(); + break; + } + case "validate.reject": { + worker.removeEventListener("error", onError); + worker.removeEventListener("message", onMessage); + reject(data.reason); + worker.terminate(); + } + } + }; + worker.addEventListener("error", onError); + worker.addEventListener("message", onMessage); + worker.postMessage({ id: "init", url: babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__.Tools.GetBabylonScriptURL(_this.Configuration.url) }); + if (ArrayBuffer.isView(data)) { + // Slice the data to avoid copying the whole array buffer. + var slicedData = data.slice(); + worker.postMessage({ id: "validate", data: slicedData, rootUrl: rootUrl, fileName: fileName }, [slicedData.buffer]); + } + else { + worker.postMessage({ id: "validate", data: data, rootUrl: rootUrl, fileName: fileName }); + } + }); + } + else { + if (!this._LoadScriptPromise) { + this._LoadScriptPromise = babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__.Tools.LoadBabylonScriptAsync(this.Configuration.url); + } + return this._LoadScriptPromise.then(function () { + return validateAsync(data, rootUrl, fileName, getExternalResource); + }); + } + }; + /** + * The configuration. Defaults to `{ url: "https://cdn.babylonjs.com/gltf_validator.js" }`. + */ + GLTFValidation.Configuration = { + url: "".concat(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__.Tools._DefaultCdnUrl, "/gltf_validator.js"), + }; + return GLTFValidation; +}()); + + + +/***/ }), + +/***/ "../../../lts/loaders/src/legacy/legacy-glTF.ts": +/*!******************************************************!*\ + !*** ../../../lts/loaders/src/legacy/legacy-glTF.ts ***! + \******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFFileLoader: () => (/* reexport safe */ loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFFileLoader), +/* harmony export */ GLTFLoaderAnimationStartMode: () => (/* reexport safe */ loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderAnimationStartMode), +/* harmony export */ GLTFLoaderCoordinateSystemMode: () => (/* reexport safe */ loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderCoordinateSystemMode), +/* harmony export */ GLTFLoaderState: () => (/* reexport safe */ loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderState), +/* harmony export */ GLTFValidation: () => (/* reexport safe */ loaders_glTF_glTFValidation__WEBPACK_IMPORTED_MODULE_1__.GLTFValidation) +/* harmony export */ }); +/* harmony import */ var loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! loaders/glTF/glTFFileLoader */ "../../../dev/loaders/src/glTF/glTFFileLoader.ts"); +/* harmony import */ var loaders_glTF_glTFValidation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! loaders/glTF/glTFValidation */ "../../../dev/loaders/src/glTF/glTFValidation.ts"); + + +/** + * This is the entry point for the UMD module. + * The entry point for a future ESM package should be index.ts + */ +var globalObject = typeof __webpack_require__.g !== "undefined" ? __webpack_require__.g : typeof window !== "undefined" ? window : undefined; +if (typeof globalObject !== "undefined") { + globalObject.BABYLON = globalObject.BABYLON || {}; + for (var key in loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__) { + globalObject.BABYLON[key] = loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__[key]; + } + for (var key in loaders_glTF_glTFValidation__WEBPACK_IMPORTED_MODULE_1__) { + globalObject.BABYLON[key] = loaders_glTF_glTFValidation__WEBPACK_IMPORTED_MODULE_1__[key]; + } +} + + + + +/***/ }), + +/***/ "../../../lts/loaders/src/legacy/legacy-glTF2.ts": +/*!*******************************************************!*\ + !*** ../../../lts/loaders/src/legacy/legacy-glTF2.ts ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTF2: () => (/* reexport module object */ loaders_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_2__) +/* harmony export */ }); +/* harmony import */ var loaders_glTF_2_0_Extensions_index__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! loaders/glTF/2.0/Extensions/index */ "../../../dev/loaders/src/glTF/2.0/Extensions/index.ts"); +/* harmony import */ var loaders_glTF_2_0_glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! loaders/glTF/2.0/glTFLoaderInterfaces */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderInterfaces.ts"); +/* harmony import */ var loaders_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! loaders/glTF/2.0/index */ "../../../dev/loaders/src/glTF/2.0/index.ts"); +/* eslint-disable import/no-internal-modules */ + + + +/** + * This is the entry point for the UMD module. + * The entry point for a future ESM package should be index.ts + */ +var globalObject = typeof __webpack_require__.g !== "undefined" ? __webpack_require__.g : typeof window !== "undefined" ? window : undefined; +if (typeof globalObject !== "undefined") { + globalObject.BABYLON = globalObject.BABYLON || {}; + var BABYLON_1 = globalObject.BABYLON; + BABYLON_1.GLTF2 = BABYLON_1.GLTF2 || {}; + BABYLON_1.GLTF2.Loader = BABYLON_1.GLTF2.Loader || {}; + BABYLON_1.GLTF2.Loader.Extensions = BABYLON_1.GLTF2.Loader.Extensions || {}; + var keys = []; + for (var key in loaders_glTF_2_0_Extensions_index__WEBPACK_IMPORTED_MODULE_0__) { + BABYLON_1.GLTF2.Loader.Extensions[key] = loaders_glTF_2_0_Extensions_index__WEBPACK_IMPORTED_MODULE_0__[key]; + keys.push(key); + } + for (var key in loaders_glTF_2_0_glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_1__) { + BABYLON_1.GLTF2.Loader[key] = loaders_glTF_2_0_glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_1__[key]; + keys.push(key); + } + for (var key in loaders_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_2__) { + // Prevent Reassignment. + if (keys.indexOf(key) > -1) { + continue; + } + BABYLON_1.GLTF2[key] = loaders_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_2__[key]; + } +} + + + +/***/ }), + +/***/ "../../../lts/loaders/src/legacy/legacy-glTF2FileLoader.ts": +/*!*****************************************************************!*\ + !*** ../../../lts/loaders/src/legacy/legacy-glTF2FileLoader.ts ***! + \*****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTF2: () => (/* reexport safe */ _legacy_glTF2__WEBPACK_IMPORTED_MODULE_1__.GLTF2), +/* harmony export */ GLTFFileLoader: () => (/* reexport safe */ _legacy_glTF__WEBPACK_IMPORTED_MODULE_0__.GLTFFileLoader), +/* harmony export */ GLTFLoaderAnimationStartMode: () => (/* reexport safe */ _legacy_glTF__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderAnimationStartMode), +/* harmony export */ GLTFLoaderCoordinateSystemMode: () => (/* reexport safe */ _legacy_glTF__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderCoordinateSystemMode), +/* harmony export */ GLTFLoaderState: () => (/* reexport safe */ _legacy_glTF__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderState), +/* harmony export */ GLTFValidation: () => (/* reexport safe */ _legacy_glTF__WEBPACK_IMPORTED_MODULE_0__.GLTFValidation) +/* harmony export */ }); +/* harmony import */ var _legacy_glTF__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./legacy-glTF */ "../../../lts/loaders/src/legacy/legacy-glTF.ts"); +/* harmony import */ var _legacy_glTF2__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./legacy-glTF2 */ "../../../lts/loaders/src/legacy/legacy-glTF2.ts"); +// eslint-disable-next-line import/export + + + + +/***/ }), + +/***/ "babylonjs/Misc/tools": +/*!****************************************************************************************************!*\ + !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***! + \****************************************************************************************************/ +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_tools__; + +/***/ }), + +/***/ "../../../../node_modules/tslib/tslib.es6.mjs": +/*!****************************************************!*\ + !*** ../../../../node_modules/tslib/tslib.es6.mjs ***! + \****************************************************/ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ __addDisposableResource: () => (/* binding */ __addDisposableResource), +/* harmony export */ __assign: () => (/* binding */ __assign), +/* harmony export */ __asyncDelegator: () => (/* binding */ __asyncDelegator), +/* harmony export */ __asyncGenerator: () => (/* binding */ __asyncGenerator), +/* harmony export */ __asyncValues: () => (/* binding */ __asyncValues), +/* harmony export */ __await: () => (/* binding */ __await), +/* harmony export */ __awaiter: () => (/* binding */ __awaiter), +/* harmony export */ __classPrivateFieldGet: () => (/* binding */ __classPrivateFieldGet), +/* harmony export */ __classPrivateFieldIn: () => (/* binding */ __classPrivateFieldIn), +/* harmony export */ __classPrivateFieldSet: () => (/* binding */ __classPrivateFieldSet), +/* harmony export */ __createBinding: () => (/* binding */ __createBinding), +/* harmony export */ __decorate: () => (/* binding */ __decorate), +/* harmony export */ __disposeResources: () => (/* binding */ __disposeResources), +/* harmony export */ __esDecorate: () => (/* binding */ __esDecorate), +/* harmony export */ __exportStar: () => (/* binding */ __exportStar), +/* harmony export */ __extends: () => (/* binding */ __extends), +/* harmony export */ __generator: () => (/* binding */ __generator), +/* harmony export */ __importDefault: () => (/* binding */ __importDefault), +/* harmony export */ __importStar: () => (/* binding */ __importStar), +/* harmony export */ __makeTemplateObject: () => (/* binding */ __makeTemplateObject), +/* harmony export */ __metadata: () => (/* binding */ __metadata), +/* harmony export */ __param: () => (/* binding */ __param), +/* harmony export */ __propKey: () => (/* binding */ __propKey), +/* harmony export */ __read: () => (/* binding */ __read), +/* harmony export */ __rest: () => (/* binding */ __rest), +/* harmony export */ __rewriteRelativeImportExtension: () => (/* binding */ __rewriteRelativeImportExtension), +/* harmony export */ __runInitializers: () => (/* binding */ __runInitializers), +/* harmony export */ __setFunctionName: () => (/* binding */ __setFunctionName), +/* harmony export */ __spread: () => (/* binding */ __spread), +/* harmony export */ __spreadArray: () => (/* binding */ __spreadArray), +/* harmony export */ __spreadArrays: () => (/* binding */ __spreadArrays), +/* harmony export */ __values: () => (/* binding */ __values), +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +/* global Reflect, Promise, SuppressedError, Symbol, Iterator */ + +var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); +}; + +function __extends(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} + +var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + } + return __assign.apply(this, arguments); +} + +function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +} + +function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} + +function __param(paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } +} + +function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; + +function __runInitializers(thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; + +function __propKey(x) { + return typeof x === "symbol" ? x : "".concat(x); +}; + +function __setFunctionName(f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); +}; + +function __metadata(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); +} + +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); + return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +} + +var __createBinding = Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +}); + +function __exportStar(m, o) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); +} + +function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); +} + +function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +} + +/** @deprecated */ +function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; +} + +/** @deprecated */ +function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +} + +function __spreadArray(to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +} + +function __await(v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); +} + +function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; + function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } + function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } +} + +function __asyncDelegator(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; + function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } +} + +function __asyncValues(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +} + +function __makeTemplateObject(cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; +}; + +var __setModuleDefault = Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}; + +function __importStar(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +} + +function __importDefault(mod) { + return (mod && mod.__esModule) ? mod : { default: mod }; +} + +function __classPrivateFieldGet(receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +} + +function __classPrivateFieldSet(receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +} + +function __classPrivateFieldIn(state, receiver) { + if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); + return typeof state === "function" ? receiver === state : state.has(receiver); +} + +function __addDisposableResource(env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose, inner; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + if (async) inner = dispose; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } }; + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +} + +var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}; + +function __disposeResources(env) { + function fail(e) { + env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + var r, s = 0; + function next() { + while (r = env.stack.pop()) { + try { + if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); + if (r.dispose) { + var result = r.dispose.call(r.value); + if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + else s |= 1; + } + catch (e) { + fail(e); + } + } + if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); + if (env.hasError) throw env.error; + } + return next(); +} + +function __rewriteRelativeImportExtension(path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); + } + return path; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ + __extends, + __assign, + __rest, + __decorate, + __param, + __esDecorate, + __runInitializers, + __propKey, + __setFunctionName, + __metadata, + __awaiter, + __generator, + __createBinding, + __exportStar, + __values, + __read, + __spread, + __spreadArrays, + __spreadArray, + __await, + __asyncGenerator, + __asyncDelegator, + __asyncValues, + __makeTemplateObject, + __importStar, + __importDefault, + __classPrivateFieldGet, + __classPrivateFieldSet, + __classPrivateFieldIn, + __addDisposableResource, + __disposeResources, + __rewriteRelativeImportExtension, +}); + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/compat get default export */ +/******/ (() => { +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = (module) => { +/******/ var getter = module && module.__esModule ? +/******/ () => (module['default']) : +/******/ () => (module); +/******/ __webpack_require__.d(getter, { a: getter }); +/******/ return getter; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/create fake namespace object */ +/******/ (() => { +/******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__); +/******/ var leafPrototypes; +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 16: return value when it's Promise-like +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = this(value); +/******/ if(mode & 8) return value; +/******/ if(typeof value === 'object' && value) { +/******/ if((mode & 4) && value.__esModule) return value; +/******/ if((mode & 16) && typeof value.then === 'function') return value; +/******/ } +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ var def = {}; +/******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)]; +/******/ for(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) { +/******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key]))); +/******/ } +/******/ def['default'] = () => (value); +/******/ __webpack_require__.d(ns, def); +/******/ return ns; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/global */ +/******/ (() => { +/******/ __webpack_require__.g = (function() { +/******/ if (typeof globalThis === 'object') return globalThis; +/******/ try { +/******/ return this || new Function('return this')(); +/******/ } catch (e) { +/******/ if (typeof window === 'object') return window; +/******/ } +/******/ })(); +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +/*!********************************!*\ + !*** ./src/glTF2FileLoader.ts ***! + \********************************/ +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__), +/* harmony export */ loaders: () => (/* reexport module object */ _lts_loaders_legacy_legacy_glTF2FileLoader__WEBPACK_IMPORTED_MODULE_0__) +/* harmony export */ }); +/* harmony import */ var _lts_loaders_legacy_legacy_glTF2FileLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @lts/loaders/legacy/legacy-glTF2FileLoader */ "../../../lts/loaders/src/legacy/legacy-glTF2FileLoader.ts"); + + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_lts_loaders_legacy_legacy_glTF2FileLoader__WEBPACK_IMPORTED_MODULE_0__); + +})(); + +__webpack_exports__ = __webpack_exports__["default"]; +/******/ return __webpack_exports__; +/******/ })() +; +}); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFieWxvbi5nbFRGMkZpbGVMb2FkZXIuanMiLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDVEE7QUFDQTtBQUVBO0FBS0E7QUFDQTtBQUVBO0FBc0JBOztBQUVBO0FBQ0E7QUFDQTtBQWNBOztBQUVBO0FBQ0E7QUFoQkE7O0FBRUE7QUFDQTtBQWNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBR0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBR0E7O0FBWkE7QUFBQTtBQWFBOzs7QUFoQkE7QUFBQTtBQWlCQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUM1S0E7QUFJQTtBQUlBO0FBRUE7QUFFQTtBQWFBOzs7QUFHQTtBQUNBO0FBQ0E7QUFhQTs7QUFFQTtBQUNBO0FBZkE7O0FBRUE7QUFDQTtBQWFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUMxSEE7QUFHQTtBQUNBO0FBRUE7QUFpQkE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBYUE7O0FBRUE7QUFDQTtBQWZBOztBQUVBO0FBQ0E7QUFhQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7QUM5RUE7QUFLQTtBQUVBO0FBYUE7OztBQUdBO0FBQ0E7QUFDQTtBQVNBOztBQUVBO0FBQ0E7QUFYQTtBQUNBO0FBV0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUtBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7OztBQ3JFQTtBQUtBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFTQTs7QUFFQTtBQUNBO0FBWEE7QUFDQTtBQVdBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFLQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQzVEQTtBQUVBO0FBaUJBOztBQUVBO0FBQ0E7QUFxQkE7O0FBRUE7QUFDQTtBQXZCQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQWdCQTtBQUNBO0FBYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFTQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDL0ZBOztBQUVBO0FBR0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUFBOztBQUtBO0FBSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFBQTtBQUFBOztBQU9BO0FBTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQUE7QUFBQTs7QUFXQTtBQVZBO0FBQ0E7QUFPQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFJQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDdFJBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFhQTs7O0FBR0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBOzs7QUFHQTtBQUNBO0FBQ0E7QUFTQTs7QUFFQTtBQUNBO0FBWEE7O0FBRUE7QUFDQTtBQVNBO0FBQ0E7QUFDQTtBQUtBO0FBSEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7OztBQVFBO0FBQ0E7O0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDdkhBO0FBRUE7QUFRQTtBQUNBO0FBRUE7QUFpQkE7O0FBRUE7QUFDQTtBQUNBO0FBdUJBOztBQUVBO0FBQ0E7QUF6QkE7O0FBRUE7QUFDQTtBQVlBOztBQUVBO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDbElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQWFBOztBQUVBO0FBQ0E7QUFZQTs7O0FBR0E7QUFDQTtBQUFBO0FBZkE7O0FBRUE7QUFDQTtBQWFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBT0E7QUFDQTtBQUVBO0FBYUE7O0FBRUE7QUFDQTtBQUNBO0FBZUE7O0FBRUE7QUFDQTtBQWpCQTs7QUFFQTtBQUNBO0FBZUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNwSUE7QUFLQTtBQUVBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2hHQTtBQUtBO0FBRUE7QUFFQTtBQWFBOzs7QUFHQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDcklBO0FBS0E7QUFFQTtBQUNBO0FBRUE7QUFhQTs7O0FBR0E7QUFDQTtBQUNBO0FBa0JBOztBQUVBO0FBQ0E7QUFwQkE7O0FBRUE7QUFDQTtBQU9BOztBQUVBO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDdElBO0FBSUE7QUFFQTtBQUVBO0FBYUE7OztBQUdBO0FBQ0E7QUFDQTtBQWtCQTs7QUFFQTtBQUNBO0FBcEJBOztBQUVBO0FBQ0E7QUFPQTs7QUFFQTtBQUNBO0FBUUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDdkZBO0FBS0E7QUFFQTtBQUVBO0FBYUE7O0FBRUE7QUFDQTtBQUNBO0FBa0JBOztBQUVBO0FBQ0E7QUFwQkE7O0FBRUE7QUFDQTtBQU9BOztBQUVBO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNoRkE7QUFLQTtBQUVBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUF1QkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUEzREE7O0FBRUE7QUFDQTtBQXlEQTtBQUFBO0FBN0RBO0FBK0RBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUMxRkE7QUFLQTtBQUVBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDMUdBO0FBQ0E7QUFLQTtBQUVBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNySEE7QUFLQTtBQUNBO0FBRUE7QUFFQTtBQWFBOzs7QUFHQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN4SEE7QUFLQTtBQUNBO0FBRUE7QUFFQTtBQWFBOztBQUVBO0FBQ0E7QUFDQTtBQWtCQTs7QUFFQTtBQUNBO0FBcEJBOztBQUVBO0FBQ0E7QUFPQTs7QUFFQTtBQUNBO0FBUUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDOUdBO0FBS0E7QUFLQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBK0NBOztBQUVBO0FBQ0E7QUFrQ0E7Ozs7QUFJQTtBQUNBO0FBQUE7QUFoQkE7QUFDQTtBQUNBO0FBQ0E7QUFjQTtBQUlBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQXJEQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQTBDQTs7O0FBR0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBS0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTs7QUFDQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFBQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzFhQTtBQUNBO0FBS0E7QUFDQTtBQUVBO0FBYUE7O0FBRUE7QUFDQTtBQUNBO0FBa0JBOztBQUVBO0FBQ0E7QUFwQkE7O0FBRUE7QUFDQTtBQU9BOztBQUVBO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3hHQTtBQUdBO0FBTUE7QUFFQTtBQXVCQTs7QUFFQTtBQUNBO0FBQ0E7QUFlQTs7QUFFQTtBQUNBO0FBakJBOztBQUVBO0FBQ0E7QUFlQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBeEVBO0FBQUE7QUF5RUE7QUFDQTs7QUFoRkE7QUFDQTtBQUFBO0FBaUZBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3hUQTtBQUtBO0FBRUE7QUFFQTtBQWFBOzs7QUFHQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7O0FDakhBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFXQTs7QUFFQTtBQUNBO0FBYkE7O0FBRUE7QUFDQTtBQVdBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN6Q0E7QUFFQTtBQWFBOztBQUVBO0FBQ0E7QUFDQTtBQVlBOztBQUVBO0FBQ0E7QUFkQTs7QUFFQTtBQUNBO0FBWUE7QUFDQTtBQUNBO0FBRUE7Ozs7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNsRUE7QUFLQTtBQUVBO0FBYUE7O0FBRUE7QUFDQTtBQUNBO0FBU0E7O0FBRUE7QUFDQTtBQVhBO0FBQ0E7QUFXQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBS0E7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNuRUE7QUFJQTtBQUVBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFhQTs7QUFFQTtBQUNBO0FBZkE7O0FBRUE7QUFDQTtBQWFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ3pGQTtBQUVBO0FBYUE7OztBQUdBO0FBQ0E7QUFDQTtBQWtCQTs7QUFFQTtBQUNBO0FBcEJBOztBQUVBO0FBQ0E7QUFPQTs7QUFFQTtBQUNBO0FBUUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDMUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFJQTtBQUdBO0FBRUE7QUFFQTtBQW9DQTs7O0FBR0E7QUFDQTtBQUNBO0FBZUE7O0FBRUE7QUFDQTtBQWpCQTs7QUFFQTtBQUNBO0FBZUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFLQTtBQUNBO0FBQ0E7O0FBZkE7QUFBQTtBQUFBO0FBaUJBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQVZBO0FBQUE7QUFZQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNoVUE7QUFDQTtBQU9BO0FBRUE7QUFFQTtBQXdCQTs7QUFFQTtBQUNBO0FBQ0E7QUFpREE7O0FBRUE7QUFDQTs7QUFuREE7O0FBRUE7QUFDQTtBQU9BOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7Ozs7QUFJQTtBQUNBO0FBRUE7Ozs7QUFJQTtBQUNBO0FBSUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7QUFsQkE7QUFBQTtBQW1CQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7QUFsQkE7QUFBQTtBQW1CQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7O0FBbENBO0FBQUE7QUFtQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7QUFuQ0E7QUFBQTtBQW9DQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNuYkE7QUFJQTtBQUNBO0FBRUE7QUFhQTtBQUNBO0FBQ0E7QUFTQTtBQUNBO0FBVEE7QUFDQTtBQVNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3JFQTtBQUlBO0FBQ0E7QUFFQTtBQWFBO0FBQ0E7QUFDQTtBQVNBO0FBQ0E7QUFUQTtBQUNBO0FBU0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7OztBQ3JFQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW1CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3RFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzVCQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7OztBQUtBO0FBQ0E7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFuQ0E7QUFDQTtBQUFBO0FBQUE7QUFtQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7O0FBMUNBO0FBQUE7QUFBQTtBQTJDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUM5TUE7QUFJQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQXdFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2xMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUEwQ0E7QUFFQTtBQUNBO0FBRUE7QUFHQTtBQUVBO0FBRUE7QUF1QkE7QUFDQTtBQUFBO0FBQUE7QUFBQTs7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUF5Q0E7QUF4Q0E7Ozs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBV0E7O0FBRUE7QUFDQTtBQXdHQTs7QUFFQTtBQUNBO0FBMUdBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBaUZBO0FBQ0E7QUEzRUE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUtBO0FBSEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7OztBQUFBO0FBS0E7QUFIQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFLQTtBQUhBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQUtBO0FBSEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7OztBQUFBO0FBS0E7QUFIQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFLQTtBQUhBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFPQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBOzs7Ozs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUFBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFHQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTs7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7Ozs7OztBQUNBO0FBRUE7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFFQTs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7OztBQUNBO0FBRUE7QUFDQTtBQUVBOztBQUFBOztBQUFBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBUEE7QUFBQTtBQUFBO0FBUUE7QUFDQTs7Ozs7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7Ozs7O0FBS0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7O0FBTUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7Ozs7O0FBU0E7QUFDQTtBQUFBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFLQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBOzs7OztBQUtBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7Ozs7O0FBU0E7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7Ozs7Ozs7QUFVQTtBQUNBO0FBUUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7Ozs7O0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQVNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQVFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFnQkE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFLQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7Ozs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7Ozs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUlBO0FBSUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7OztBQU1BO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBT0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBUUE7QUFLQTtBQUVBO0FBT0E7QUFLQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFLQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBT0E7QUFLQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7O0FBT0E7QUFDQTtBQU1BO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7Ozs7QUFPQTtBQUNBO0FBTUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFudUZBOztBQUVBO0FBQ0E7QUFpdUZBO0FBQUE7QUFqd0ZBO0FBbXdGQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzE3RkE7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQUE7O0FBRUE7QUFDQTtBQUFBO0FBQUE7O0FBS0E7QUFKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTtBQUFBO0FBQUE7O0FBNEJBO0FBM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFyQkE7QUFBQTtBQXNCQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDMUZBO0FBU0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ0ZBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ25CQTtBQUNBO0FBTUE7QUFDQTtBQUlBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQXlCQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQXNDQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQTBCQTtBQUFBO0FBNENBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUVBOzs7QUFHQTtBQUNBO0FBRUE7Ozs7QUFJQTtBQUNBO0FBbUNBOztBQUVBO0FBQ0E7QUFRQTtBQXhNQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBd0tBO0FBQUE7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFPQTs7O0FBR0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQXVDQTtBQUNBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQWlCQTs7Ozs7QUFLQTtBQUNBO0FBaUJBOztBQUVBO0FBQ0E7QUFnQkE7O0FBRUE7QUFDQTtBQWdCQTs7QUFFQTtBQUNBO0FBZ0JBOzs7O0FBSUE7QUFDQTtBQWdCQTs7QUFFQTtBQUNBO0FBY0E7O0FBRUE7QUFDQTtBQWNBOzs7QUFHQTtBQUNBO0FBMERBOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBY0E7QUFDQTtBQUVBO0FBRUE7O0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFrVEE7O0FBRUE7QUFDQTtBQXVVQTtBQUNBO0FBRUE7QUFDQTtBQXNCQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBNThCQTs7QUFDQTtBQWdCQTtBQUhBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUF5Q0E7QUFKQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQWdCQTtBQUpBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBWUE7QUFIQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBWUE7QUFIQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBWUE7QUFIQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBZ0JBO0FBTEE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFZQTtBQUhBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQVlBO0FBSEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBYUE7QUFIQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFLQTtBQUhBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBOzs7QUFkQTtBQW1CQTtBQUhBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBaEJBO0FBaUNBO0FBSEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBZUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUdBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFFQTtBQUlBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBR0E7QUFJQTtBQUFBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFFQTtBQVFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBR0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFRQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQU9BO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFVQTtBQUNBO0FBQ0E7QUFDQTtBQUtBO0FBSEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBT0E7OztBQUdBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQVFBO0FBSUE7QUFDQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBU0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQVVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUE5N0JBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7OztBQUtBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUE0M0JBO0FBOENBO0FBQUE7QUF0K0JBO0FBdytCQTs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNqM0NBO0FBU0E7QUFNQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBT0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVlBOztBQUVBO0FBQ0E7QUFBQTtBQXlGQTtBQS9FQTs7Ozs7OztBQU9BO0FBQ0E7QUFBQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBdkZBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBbUZBO0FBQUE7QUF6RkE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3RGQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3JDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7O0FDRkE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDdllBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNQQTs7Ozs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ05BO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL0xPQURFUlMvd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvRVhUX2xpZ2h0c19pbWFnZV9iYXNlZC50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0VYVF9tZXNoX2dwdV9pbnN0YW5jaW5nLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvRVhUX21lc2hvcHRfY29tcHJlc3Npb24udHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9FWFRfdGV4dHVyZV9hdmlmLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvRVhUX3RleHR1cmVfd2VicC50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0V4dHJhc0FzTWV0YWRhdGEudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfYW5pbWF0aW9uX3BvaW50ZXIuZGF0YS50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9hbmltYXRpb25fcG9pbnRlci50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9kcmFjb19tZXNoX2NvbXByZXNzaW9uLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX2ludGVyYWN0aXZpdHkudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfbGlnaHRzX3B1bmN0dWFsLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc19hbmlzb3Ryb3B5LnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc19jbGVhcmNvYXQudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfbWF0ZXJpYWxzX2RpZmZ1c2VfdHJhbnNtaXNzaW9uLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc19kaXNwZXJzaW9uLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc19lbWlzc2l2ZV9zdHJlbmd0aC50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfaW9yLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc19pcmlkZXNjZW5jZS50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfcGJyU3BlY3VsYXJHbG9zc2luZXNzLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc19zaGVlbi50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfc3BlY3VsYXIudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfbWF0ZXJpYWxzX3RyYW5zbWlzc2lvbi50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfdW5saXQudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfbWF0ZXJpYWxzX3ZhcmlhbnRzLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc192b2x1bWUudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfbWVzaF9xdWFudGl6YXRpb24udHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfbm9kZV92aXNpYmlsaXR5LnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX3RleHR1cmVfYmFzaXN1LnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX3RleHR1cmVfdHJhbnNmb3JtLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX3htcF9qc29uX2xkLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvTVNGVF9hdWRpb19lbWl0dGVyLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvTVNGVF9sb2QudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9NU0ZUX21pbmVjcmFmdE1lc2gudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9NU0ZUX3NSR0JGYWN0b3JzLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvZ2x0ZlBhdGhUb09iamVjdENvbnZlcnRlci50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL2luZGV4LnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvaW50ZXJhY3Rpdml0eUZ1bmN0aW9ucy50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL2ludGVyYWN0aXZpdHlQYXRoVG9PYmplY3RDb252ZXJ0ZXIudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9pbnRlcmFjdGl2aXR5VXRpbHMudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvZ2xURkxvYWRlci50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9nbFRGTG9hZGVyQW5pbWF0aW9uLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeS50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9pbmRleC50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGL2dsVEZGaWxlTG9hZGVyLm1ldGFkYXRhLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvZ2xURkZpbGVMb2FkZXIudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi9nbFRGVmFsaWRhdGlvbi50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2x0cy9sb2FkZXJzL3NyYy9sZWdhY3kvbGVnYWN5LWdsVEYudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9sdHMvbG9hZGVycy9zcmMvbGVnYWN5L2xlZ2FjeS1nbFRGMi50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2x0cy9sb2FkZXJzL3NyYy9sZWdhY3kvbGVnYWN5LWdsVEYyRmlsZUxvYWRlci50cyIsIndlYnBhY2s6Ly9MT0FERVJTL2V4dGVybmFsIHVtZCB7XCJyb290XCI6XCJCQUJZTE9OXCIsXCJjb21tb25qc1wiOlwiYmFieWxvbmpzXCIsXCJjb21tb25qczJcIjpcImJhYnlsb25qc1wiLFwiYW1kXCI6XCJiYWJ5bG9uanNcIn0iLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdHNsaWIvdHNsaWIuZXM2Lm1qcyIsIndlYnBhY2s6Ly9MT0FERVJTL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL0xPQURFUlMvd2VicGFjay9ydW50aW1lL2NvbXBhdCBnZXQgZGVmYXVsdCBleHBvcnQiLCJ3ZWJwYWNrOi8vTE9BREVSUy93ZWJwYWNrL3J1bnRpbWUvY3JlYXRlIGZha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly9MT0FERVJTL3dlYnBhY2svcnVudGltZS9kZWZpbmUgcHJvcGVydHkgZ2V0dGVycyIsIndlYnBhY2s6Ly9MT0FERVJTL3dlYnBhY2svcnVudGltZS9nbG9iYWwiLCJ3ZWJwYWNrOi8vTE9BREVSUy93ZWJwYWNrL3J1bnRpbWUvaGFzT3duUHJvcGVydHkgc2hvcnRoYW5kIiwid2VicGFjazovL0xPQURFUlMvd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly9MT0FERVJTLy4vc3JjL2dsVEYyRmlsZUxvYWRlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gd2VicGFja1VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24ocm9vdCwgZmFjdG9yeSkge1xuXHRpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcpXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCJiYWJ5bG9uanNcIikpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoXCJiYWJ5bG9uanMtbG9hZGVyc1wiLCBbXCJiYWJ5bG9uanNcIl0sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wiYmFieWxvbmpzLWxvYWRlcnNcIl0gPSBmYWN0b3J5KHJlcXVpcmUoXCJiYWJ5bG9uanNcIikpO1xuXHRlbHNlXG5cdFx0cm9vdFtcIkxPQURFUlNcIl0gPSBmYWN0b3J5KHJvb3RbXCJCQUJZTE9OXCJdKTtcbn0pKCh0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdGhpcyksIChfX1dFQlBBQ0tfRVhURVJOQUxfTU9EVUxFX2JhYnlsb25qc19NaXNjX3Rvb2xzX18pID0+IHtcbnJldHVybiAiLCJpbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgU3BoZXJpY2FsSGFybW9uaWNzLCBTcGhlcmljYWxQb2x5bm9taWFsIH0gZnJvbSBcImNvcmUvTWF0aHMvc3BoZXJpY2FsUG9seW5vbWlhbFwiO1xyXG5pbXBvcnQgeyBRdWF0ZXJuaW9uLCBNYXRyaXggfSBmcm9tIFwiY29yZS9NYXRocy9tYXRoLnZlY3RvclwiO1xyXG5pbXBvcnQgdHlwZSB7IEJhc2VUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL2Jhc2VUZXh0dXJlXCI7XHJcbmltcG9ydCB7IFJhd0N1YmVUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL3Jhd0N1YmVUZXh0dXJlXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IElFWFRMaWdodHNJbWFnZUJhc2VkX0xpZ2h0UmVmZXJlbmNlSW1hZ2VCYXNlZCwgSUVYVExpZ2h0c0ltYWdlQmFzZWRfTGlnaHRJbWFnZUJhc2VkLCBJRVhUTGlnaHRzSW1hZ2VCYXNlZCB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHR5cGUgeyBJU2NlbmUgfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IEdMVEZMb2FkZXIsIEFycmF5SXRlbSB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJFWFRfbGlnaHRzX2ltYWdlX2Jhc2VkXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEVYVF9saWdodHNfaW1hZ2VfYmFzZWQgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIkVYVF9saWdodHNfaW1hZ2VfYmFzZWRcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiIHtcclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuICAgIGludGVyZmFjZSBJRVhUTGlnaHRzSW1hZ2VCYXNlZF9MaWdodEltYWdlQmFzZWQge1xyXG4gICAgICAgIF9iYWJ5bG9uVGV4dHVyZT86IEJhc2VUZXh0dXJlO1xyXG4gICAgICAgIF9sb2FkZWQ/OiBQcm9taXNlPHZvaWQ+O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvVmVuZG9yL0VYVF9saWdodHNfaW1hZ2VfYmFzZWQvUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgRVhUX2xpZ2h0c19pbWFnZV9iYXNlZCBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcbiAgICBwcml2YXRlIF9saWdodHM/OiBJRVhUTGlnaHRzSW1hZ2VCYXNlZF9MaWdodEltYWdlQmFzZWRbXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgICAgIGRlbGV0ZSB0aGlzLl9saWdodHM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIG9uTG9hZGluZygpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25zID0gdGhpcy5fbG9hZGVyLmdsdGYuZXh0ZW5zaW9ucztcclxuICAgICAgICBpZiAoZXh0ZW5zaW9ucyAmJiBleHRlbnNpb25zW3RoaXMubmFtZV0pIHtcclxuICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uc1t0aGlzLm5hbWVdIGFzIElFWFRMaWdodHNJbWFnZUJhc2VkO1xyXG4gICAgICAgICAgICB0aGlzLl9saWdodHMgPSBleHRlbnNpb24ubGlnaHRzO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZFNjZW5lQXN5bmMoY29udGV4dDogc3RyaW5nLCBzY2VuZTogSVNjZW5lKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRlbnNpb25Bc3luYzxJRVhUTGlnaHRzSW1hZ2VCYXNlZF9MaWdodFJlZmVyZW5jZUltYWdlQmFzZWQ+KGNvbnRleHQsIHNjZW5lLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLl9hbGxNYXRlcmlhbHNEaXJ0eVJlcXVpcmVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuXHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZGVyLmxvYWRTY2VuZUFzeW5jKGNvbnRleHQsIHNjZW5lKSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9nT3BlbihgJHtleHRlbnNpb25Db250ZXh0fWApO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgbGlnaHQgPSBBcnJheUl0ZW0uR2V0KGAke2V4dGVuc2lvbkNvbnRleHR9L2xpZ2h0YCwgdGhpcy5fbGlnaHRzLCBleHRlbnNpb24ubGlnaHQpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZExpZ2h0QXN5bmMoYC9leHRlbnNpb25zLyR7dGhpcy5uYW1lfS9saWdodHMvJHtleHRlbnNpb24ubGlnaHR9YCwgbGlnaHQpLnRoZW4oKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIuYmFieWxvblNjZW5lLmVudmlyb25tZW50VGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvZ0Nsb3NlKCk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRMaWdodEFzeW5jKGNvbnRleHQ6IHN0cmluZywgbGlnaHQ6IElFWFRMaWdodHNJbWFnZUJhc2VkX0xpZ2h0SW1hZ2VCYXNlZCk6IFByb21pc2U8QmFzZVRleHR1cmU+IHtcclxuICAgICAgICBpZiAoIWxpZ2h0Ll9sb2FkZWQpIHtcclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvZ09wZW4oYCR7Y29udGV4dH1gKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGltYWdlRGF0YSA9IG5ldyBBcnJheTxBcnJheTxBcnJheUJ1ZmZlclZpZXc+PihsaWdodC5zcGVjdWxhckltYWdlcy5sZW5ndGgpO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBtaXBtYXAgPSAwOyBtaXBtYXAgPCBsaWdodC5zcGVjdWxhckltYWdlcy5sZW5ndGg7IG1pcG1hcCsrKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBmYWNlcyA9IGxpZ2h0LnNwZWN1bGFySW1hZ2VzW21pcG1hcF07XHJcbiAgICAgICAgICAgICAgICBpbWFnZURhdGFbbWlwbWFwXSA9IG5ldyBBcnJheTxBcnJheUJ1ZmZlclZpZXc+KGZhY2VzLmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBmYWNlID0gMDsgZmFjZSA8IGZhY2VzLmxlbmd0aDsgZmFjZSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3BlY3VsYXJJbWFnZUNvbnRleHQgPSBgJHtjb250ZXh0fS9zcGVjdWxhckltYWdlcy8ke21pcG1hcH0vJHtmYWNlfWA7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvZ09wZW4oYCR7c3BlY3VsYXJJbWFnZUNvbnRleHR9YCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gZmFjZXNbZmFjZV07XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW1hZ2UgPSBBcnJheUl0ZW0uR2V0KHNwZWN1bGFySW1hZ2VDb250ZXh0LCB0aGlzLl9sb2FkZXIuZ2x0Zi5pbWFnZXMsIGluZGV4KTtcclxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZEltYWdlQXN5bmMoYC9pbWFnZXMvJHtpbmRleH1gLCBpbWFnZSkudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VEYXRhW21pcG1hcF1bZmFjZV0gPSBkYXRhO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2dDbG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9nQ2xvc2UoKTtcclxuXHJcbiAgICAgICAgICAgIGxpZ2h0Ll9sb2FkZWQgPSBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uVGV4dHVyZSA9IG5ldyBSYXdDdWJlVGV4dHVyZSh0aGlzLl9sb2FkZXIuYmFieWxvblNjZW5lLCBudWxsLCBsaWdodC5zcGVjdWxhckltYWdlU2l6ZSk7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uVGV4dHVyZS5uYW1lID0gbGlnaHQubmFtZSB8fCBcImVudmlyb25tZW50XCI7XHJcbiAgICAgICAgICAgICAgICBsaWdodC5fYmFieWxvblRleHR1cmUgPSBiYWJ5bG9uVGV4dHVyZTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAobGlnaHQuaW50ZW5zaXR5ICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25UZXh0dXJlLmxldmVsID0gbGlnaHQuaW50ZW5zaXR5O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChsaWdodC5yb3RhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCByb3RhdGlvbiA9IFF1YXRlcm5pb24uRnJvbUFycmF5KGxpZ2h0LnJvdGF0aW9uKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gSW52ZXJ0IHRoZSByb3RhdGlvbiBzbyB0aGF0IHBvc2l0aXZlIHJvdGF0aW9uIGlzIGNvdW50ZXItY2xvY2t3aXNlLlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5fbG9hZGVyLmJhYnlsb25TY2VuZS51c2VSaWdodEhhbmRlZFN5c3RlbSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByb3RhdGlvbiA9IFF1YXRlcm5pb24uSW52ZXJzZShyb3RhdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBNYXRyaXguRnJvbVF1YXRlcm5pb25Ub1JlZihyb3RhdGlvbiwgYmFieWxvblRleHR1cmUuZ2V0UmVmbGVjdGlvblRleHR1cmVNYXRyaXgoKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCFsaWdodC5pcnJhZGlhbmNlQ29lZmZpY2llbnRzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBJcnJhZGlhbmNlIGNvZWZmaWNpZW50cyBhcmUgbWlzc2luZ2ApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHNwaGVyaWNhbEhhcm1vbmljcyA9IFNwaGVyaWNhbEhhcm1vbmljcy5Gcm9tQXJyYXkobGlnaHQuaXJyYWRpYW5jZUNvZWZmaWNpZW50cyk7XHJcbiAgICAgICAgICAgICAgICBzcGhlcmljYWxIYXJtb25pY3Muc2NhbGVJblBsYWNlKGxpZ2h0LmludGVuc2l0eSk7XHJcblxyXG4gICAgICAgICAgICAgICAgc3BoZXJpY2FsSGFybW9uaWNzLmNvbnZlcnRJcnJhZGlhbmNlVG9MYW1iZXJ0aWFuUmFkaWFuY2UoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNwaGVyaWNhbFBvbHlub21pYWwgPSBTcGhlcmljYWxQb2x5bm9taWFsLkZyb21IYXJtb25pY3Moc3BoZXJpY2FsSGFybW9uaWNzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBDb21wdXRlIHRoZSBsb2QgZ2VuZXJhdGlvbiBzY2FsZSB0byBmaXQgZXhhY3RseSB0byB0aGUgbnVtYmVyIG9mIGxldmVscyBhdmFpbGFibGUuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBsb2RHZW5lcmF0aW9uU2NhbGUgPSAoaW1hZ2VEYXRhLmxlbmd0aCAtIDEpIC8gTWF0aC5sb2cyKGxpZ2h0LnNwZWN1bGFySW1hZ2VTaXplKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBiYWJ5bG9uVGV4dHVyZS51cGRhdGVSR0JEQXN5bmMoaW1hZ2VEYXRhLCBzcGhlcmljYWxQb2x5bm9taWFsLCBsb2RHZW5lcmF0aW9uU2NhbGUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBsaWdodC5fbG9hZGVkLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gbGlnaHQuX2JhYnlsb25UZXh0dXJlITtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgRVhUX2xpZ2h0c19pbWFnZV9iYXNlZChsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHsgVmVjdG9yMywgUXVhdGVybmlvbiwgTWF0cml4LCBUbXBWZWN0b3JzIH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC52ZWN0b3JcIjtcclxuaW1wb3J0IHR5cGUgeyBNZXNoIH0gZnJvbSBcImNvcmUvTWVzaGVzL21lc2hcIjtcclxuaW1wb3J0IHR5cGUgeyBUcmFuc2Zvcm1Ob2RlIH0gZnJvbSBcImNvcmUvTWVzaGVzL3RyYW5zZm9ybU5vZGVcIjtcclxuaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IEdMVEZMb2FkZXIsIEFycmF5SXRlbSB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgdHlwZSB7IElOb2RlIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUVYVE1lc2hHcHVJbnN0YW5jaW5nIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuaW1wb3J0IFwiY29yZS9NZXNoZXMvdGhpbkluc3RhbmNlTWVzaFwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiRVhUX21lc2hfZ3B1X2luc3RhbmNpbmdcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgRVhUX21lc2hfZ3B1X2luc3RhbmNpbmcgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIkVYVF9tZXNoX2dwdV9pbnN0YW5jaW5nXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL1ZlbmRvci9FWFRfbWVzaF9ncHVfaW5zdGFuY2luZy9SRUFETUUubWQpXHJcbiAqIFtQbGF5Z3JvdW5kIFNhbXBsZV0oaHR0cHM6Ly9wbGF5Z3JvdW5kLmJhYnlsb25qcy5jb20vI1FGSUdMVyM5KVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgRVhUX21lc2hfZ3B1X2luc3RhbmNpbmcgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWROb2RlQXN5bmMoY29udGV4dDogc3RyaW5nLCBub2RlOiBJTm9kZSwgYXNzaWduOiAoYmFieWxvblRyYW5zZm9ybU5vZGU6IFRyYW5zZm9ybU5vZGUpID0+IHZvaWQpOiBOdWxsYWJsZTxQcm9taXNlPFRyYW5zZm9ybU5vZGU+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElFWFRNZXNoR3B1SW5zdGFuY2luZywgVHJhbnNmb3JtTm9kZT4oY29udGV4dCwgbm9kZSwgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5fZGlzYWJsZUluc3RhbmNlZE1lc2grKztcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLl9sb2FkZXIubG9hZE5vZGVBc3luYyhgL25vZGVzLyR7bm9kZS5pbmRleH1gLCBub2RlLCBhc3NpZ24pO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLl9kaXNhYmxlSW5zdGFuY2VkTWVzaC0tO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFub2RlLl9wcmltaXRpdmVCYWJ5bG9uTWVzaGVzKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxOdWxsYWJsZTxGbG9hdDMyQXJyYXk+Pj4oKTtcclxuICAgICAgICAgICAgbGV0IGluc3RhbmNlQ291bnQgPSAwO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgbG9hZEF0dHJpYnV0ZSA9IChhdHRyaWJ1dGU6IHN0cmluZykgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbi5hdHRyaWJ1dGVzW2F0dHJpYnV0ZV0gPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChQcm9taXNlLnJlc29sdmUobnVsbCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBhY2Nlc3NvciA9IEFycmF5SXRlbS5HZXQoYCR7ZXh0ZW5zaW9uQ29udGV4dH0vYXR0cmlidXRlcy8ke2F0dHJpYnV0ZX1gLCB0aGlzLl9sb2FkZXIuZ2x0Zi5hY2Nlc3NvcnMsIGV4dGVuc2lvbi5hdHRyaWJ1dGVzW2F0dHJpYnV0ZV0pO1xyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkZXIuX2xvYWRGbG9hdEFjY2Vzc29yQXN5bmMoYC9hY2Nlc3NvcnMvJHthY2Nlc3Nvci5idWZmZXJWaWV3fWAsIGFjY2Vzc29yKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlQ291bnQgPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUNvdW50ID0gYWNjZXNzb3IuY291bnQ7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluc3RhbmNlQ291bnQgIT09IGFjY2Vzc29yLmNvdW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2V4dGVuc2lvbkNvbnRleHR9L2F0dHJpYnV0ZXM6IEluc3RhbmNlIGJ1ZmZlciBhY2Nlc3NvcnMgZG8gbm90IGhhdmUgdGhlIHNhbWUgY291bnQuYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBsb2FkQXR0cmlidXRlKFwiVFJBTlNMQVRJT05cIik7XHJcbiAgICAgICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJST1RBVElPTlwiKTtcclxuICAgICAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlNDQUxFXCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbigoYmFieWxvblRyYW5zZm9ybU5vZGUpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoW3RyYW5zbGF0aW9uQnVmZmVyLCByb3RhdGlvbkJ1ZmZlciwgc2NhbGVCdWZmZXJdKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0cmljZXMgPSBuZXcgRmxvYXQzMkFycmF5KGluc3RhbmNlQ291bnQgKiAxNik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIFRtcFZlY3RvcnMuVmVjdG9yM1swXS5jb3B5RnJvbUZsb2F0cygwLCAwLCAwKTsgLy8gdHJhbnNsYXRpb25cclxuICAgICAgICAgICAgICAgICAgICBUbXBWZWN0b3JzLlF1YXRlcm5pb25bMF0uY29weUZyb21GbG9hdHMoMCwgMCwgMCwgMSk7IC8vIHJvdGF0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgVG1wVmVjdG9ycy5WZWN0b3IzWzFdLmNvcHlGcm9tRmxvYXRzKDEsIDEsIDEpOyAvLyBzY2FsZVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluc3RhbmNlQ291bnQ7ICsraSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGlvbkJ1ZmZlciAmJiBWZWN0b3IzLkZyb21BcnJheVRvUmVmKHRyYW5zbGF0aW9uQnVmZmVyLCBpICogMywgVG1wVmVjdG9ycy5WZWN0b3IzWzBdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcm90YXRpb25CdWZmZXIgJiYgUXVhdGVybmlvbi5Gcm9tQXJyYXlUb1JlZihyb3RhdGlvbkJ1ZmZlciwgaSAqIDQsIFRtcFZlY3RvcnMuUXVhdGVybmlvblswXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlQnVmZmVyICYmIFZlY3RvcjMuRnJvbUFycmF5VG9SZWYoc2NhbGVCdWZmZXIsIGkgKiAzLCBUbXBWZWN0b3JzLlZlY3RvcjNbMV0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgTWF0cml4LkNvbXBvc2VUb1JlZihUbXBWZWN0b3JzLlZlY3RvcjNbMV0sIFRtcFZlY3RvcnMuUXVhdGVybmlvblswXSwgVG1wVmVjdG9ycy5WZWN0b3IzWzBdLCBUbXBWZWN0b3JzLk1hdHJpeFswXSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBUbXBWZWN0b3JzLk1hdHJpeFswXS5jb3B5VG9BcnJheShtYXRyaWNlcywgaSAqIDE2KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYmFieWxvbk1lc2ggb2Ygbm9kZS5fcHJpbWl0aXZlQmFieWxvbk1lc2hlcyEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGJhYnlsb25NZXNoIGFzIE1lc2gpLnRoaW5JbnN0YW5jZVNldEJ1ZmZlcihcIm1hdHJpeFwiLCBtYXRyaWNlcywgMTYsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJhYnlsb25UcmFuc2Zvcm1Ob2RlO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBFWFRfbWVzaF9ncHVfaW5zdGFuY2luZyhsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBBcnJheUl0ZW0sIEdMVEZMb2FkZXIgfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IElCdWZmZXJWaWV3IH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUVYVE1lc2hvcHRDb21wcmVzc2lvbiB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgTWVzaG9wdENvbXByZXNzaW9uIH0gZnJvbSBcImNvcmUvTWVzaGVzL0NvbXByZXNzaW9uL21lc2hvcHRDb21wcmVzc2lvblwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiRVhUX21lc2hvcHRfY29tcHJlc3Npb25cIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgRVhUX21lc2hvcHRfY29tcHJlc3Npb24gZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIkVYVF9tZXNob3B0X2NvbXByZXNzaW9uXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuaW50ZXJmYWNlIElCdWZmZXJWaWV3TWVzaG9wdCBleHRlbmRzIElCdWZmZXJWaWV3IHtcclxuICAgIF9tZXNoT3B0RGF0YT86IFByb21pc2U8QXJyYXlCdWZmZXJWaWV3PjtcclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL1ZlbmRvci9FWFRfbWVzaG9wdF9jb21wcmVzc2lvbi9SRUFETUUubWQpXHJcbiAqXHJcbiAqIFRoaXMgZXh0ZW5zaW9uIHVzZXMgYSBXZWJBc3NlbWJseSBkZWNvZGVyIG1vZHVsZSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS96ZXV4L21lc2hvcHRpbWl6ZXIvdHJlZS9tYXN0ZXIvanNcclxuICogQHNpbmNlIDUuMC4wXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBFWFRfbWVzaG9wdF9jb21wcmVzc2lvbiBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZEJ1ZmZlclZpZXdBc3luYyhjb250ZXh0OiBzdHJpbmcsIGJ1ZmZlclZpZXc6IElCdWZmZXJWaWV3KTogTnVsbGFibGU8UHJvbWlzZTxBcnJheUJ1ZmZlclZpZXc+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElFWFRNZXNob3B0Q29tcHJlc3Npb24sIEFycmF5QnVmZmVyVmlldz4oY29udGV4dCwgYnVmZmVyVmlldywgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlclZpZXdNZXNob3B0ID0gYnVmZmVyVmlldyBhcyBJQnVmZmVyVmlld01lc2hvcHQ7XHJcbiAgICAgICAgICAgIGlmIChidWZmZXJWaWV3TWVzaG9wdC5fbWVzaE9wdERhdGEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBidWZmZXJWaWV3TWVzaG9wdC5fbWVzaE9wdERhdGE7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vYnVmZmVyYCwgdGhpcy5fbG9hZGVyLmdsdGYuYnVmZmVycywgZXh0ZW5zaW9uLmJ1ZmZlcik7XHJcbiAgICAgICAgICAgIGJ1ZmZlclZpZXdNZXNob3B0Ll9tZXNoT3B0RGF0YSA9IHRoaXMuX2xvYWRlci5sb2FkQnVmZmVyQXN5bmMoYC9idWZmZXJzLyR7YnVmZmVyLmluZGV4fWAsIGJ1ZmZlciwgZXh0ZW5zaW9uLmJ5dGVPZmZzZXQgfHwgMCwgZXh0ZW5zaW9uLmJ5dGVMZW5ndGgpLnRoZW4oKGJ1ZmZlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE1lc2hvcHRDb21wcmVzc2lvbi5EZWZhdWx0LmRlY29kZUdsdGZCdWZmZXJBc3luYyhidWZmZXIgYXMgVWludDhBcnJheSwgZXh0ZW5zaW9uLmNvdW50LCBleHRlbnNpb24uYnl0ZVN0cmlkZSwgZXh0ZW5zaW9uLm1vZGUsIGV4dGVuc2lvbi5maWx0ZXIpO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBidWZmZXJWaWV3TWVzaG9wdC5fbWVzaE9wdERhdGE7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEVYVF9tZXNob3B0X2NvbXByZXNzaW9uKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciwgQXJyYXlJdGVtIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJVGV4dHVyZSB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IEJhc2VUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL2Jhc2VUZXh0dXJlXCI7XHJcbmltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElFWFRUZXh0dXJlQVZJRiB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIkVYVF90ZXh0dXJlX2F2aWZcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgRVhUX3RleHR1cmVfYXZpZiBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiRVhUX3RleHR1cmVfYXZpZlwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbZ2xURiBQUl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL3B1bGwvMjIzNSlcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvVmVuZG9yL0VYVF90ZXh0dXJlX2F2aWYvUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgRVhUX3RleHR1cmVfYXZpZiBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi4gKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKiogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IGxvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvYWRUZXh0dXJlQXN5bmMoY29udGV4dDogc3RyaW5nLCB0ZXh0dXJlOiBJVGV4dHVyZSwgYXNzaWduOiAoYmFieWxvblRleHR1cmU6IEJhc2VUZXh0dXJlKSA9PiB2b2lkKTogTnVsbGFibGU8UHJvbWlzZTxCYXNlVGV4dHVyZT4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUVYVFRleHR1cmVBVklGLCBCYXNlVGV4dHVyZT4oY29udGV4dCwgdGV4dHVyZSwgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHNhbXBsZXIgPSB0ZXh0dXJlLnNhbXBsZXIgPT0gdW5kZWZpbmVkID8gR0xURkxvYWRlci5EZWZhdWx0U2FtcGxlciA6IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vc2FtcGxlcmAsIHRoaXMuX2xvYWRlci5nbHRmLnNhbXBsZXJzLCB0ZXh0dXJlLnNhbXBsZXIpO1xyXG4gICAgICAgICAgICBjb25zdCBpbWFnZSA9IEFycmF5SXRlbS5HZXQoYCR7ZXh0ZW5zaW9uQ29udGV4dH0vc291cmNlYCwgdGhpcy5fbG9hZGVyLmdsdGYuaW1hZ2VzLCBleHRlbnNpb24uc291cmNlKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRlci5fY3JlYXRlVGV4dHVyZUFzeW5jKFxyXG4gICAgICAgICAgICAgICAgY29udGV4dCxcclxuICAgICAgICAgICAgICAgIHNhbXBsZXIsXHJcbiAgICAgICAgICAgICAgICBpbWFnZSxcclxuICAgICAgICAgICAgICAgIChiYWJ5bG9uVGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGFzc2lnbihiYWJ5bG9uVGV4dHVyZSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgIXRleHR1cmUuX3RleHR1cmVJbmZvLm5vbkNvbG9yRGF0YVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBFWFRfdGV4dHVyZV9hdmlmKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciwgQXJyYXlJdGVtIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJVGV4dHVyZSB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IEJhc2VUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL2Jhc2VUZXh0dXJlXCI7XHJcbmltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElFWFRUZXh0dXJlV2ViUCB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIkVYVF90ZXh0dXJlX3dlYnBcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgRVhUX3RleHR1cmVfd2VicCBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiRVhUX3RleHR1cmVfd2VicFwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9WZW5kb3IvRVhUX3RleHR1cmVfd2VicC9SRUFETUUubWQpXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBFWFRfdGV4dHVyZV93ZWJwIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLiAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC4gKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbG9hZFRleHR1cmVBc3luYyhjb250ZXh0OiBzdHJpbmcsIHRleHR1cmU6IElUZXh0dXJlLCBhc3NpZ246IChiYWJ5bG9uVGV4dHVyZTogQmFzZVRleHR1cmUpID0+IHZvaWQpOiBOdWxsYWJsZTxQcm9taXNlPEJhc2VUZXh0dXJlPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRlbnNpb25Bc3luYzxJRVhUVGV4dHVyZVdlYlAsIEJhc2VUZXh0dXJlPihjb250ZXh0LCB0ZXh0dXJlLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3Qgc2FtcGxlciA9IHRleHR1cmUuc2FtcGxlciA9PSB1bmRlZmluZWQgPyBHTFRGTG9hZGVyLkRlZmF1bHRTYW1wbGVyIDogQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9zYW1wbGVyYCwgdGhpcy5fbG9hZGVyLmdsdGYuc2FtcGxlcnMsIHRleHR1cmUuc2FtcGxlcik7XHJcbiAgICAgICAgICAgIGNvbnN0IGltYWdlID0gQXJyYXlJdGVtLkdldChgJHtleHRlbnNpb25Db250ZXh0fS9zb3VyY2VgLCB0aGlzLl9sb2FkZXIuZ2x0Zi5pbWFnZXMsIGV4dGVuc2lvbi5zb3VyY2UpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGVyLl9jcmVhdGVUZXh0dXJlQXN5bmMoXHJcbiAgICAgICAgICAgICAgICBjb250ZXh0LFxyXG4gICAgICAgICAgICAgICAgc2FtcGxlcixcclxuICAgICAgICAgICAgICAgIGltYWdlLFxyXG4gICAgICAgICAgICAgICAgKGJhYnlsb25UZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXNzaWduKGJhYnlsb25UZXh0dXJlKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICAhdGV4dHVyZS5fdGV4dHVyZUluZm8ubm9uQ29sb3JEYXRhXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEVYVF90ZXh0dXJlX3dlYnAobG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IFRyYW5zZm9ybU5vZGUgfSBmcm9tIFwiY29yZS9NZXNoZXMvdHJhbnNmb3JtTm9kZVwiO1xyXG5pbXBvcnQgdHlwZSB7IENhbWVyYSB9IGZyb20gXCJjb3JlL0NhbWVyYXMvY2FtZXJhXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IElQcm9wZXJ0eSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHR5cGUgeyBJTm9kZSwgSUNhbWVyYSwgSU1hdGVyaWFsIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgdHlwZSB7IEdMVEZMb2FkZXIgfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJFeHRyYXNBc01ldGFkYXRhXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEV4dHJhc0FzTWV0YWRhdGEgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIkV4dHJhc0FzTWV0YWRhdGFcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG5pbnRlcmZhY2UgT2JqZWN0V2l0aE1ldGFkYXRhIHtcclxuICAgIG1ldGFkYXRhOiBhbnk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBTdG9yZSBnbFRGIGV4dHJhcyAoaWYgcHJlc2VudCkgaW4gQkpTIG9iamVjdHMnIG1ldGFkYXRhXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgRXh0cmFzQXNNZXRhZGF0YSBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZCA9IHRydWU7XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIHByaXZhdGUgX2Fzc2lnbkV4dHJhcyhiYWJ5bG9uT2JqZWN0OiBPYmplY3RXaXRoTWV0YWRhdGEsIGdsdGZQcm9wOiBJUHJvcGVydHkpOiB2b2lkIHtcclxuICAgICAgICBpZiAoZ2x0ZlByb3AuZXh0cmFzICYmIE9iamVjdC5rZXlzKGdsdGZQcm9wLmV4dHJhcykubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBjb25zdCBtZXRhZGF0YSA9IChiYWJ5bG9uT2JqZWN0Lm1ldGFkYXRhID0gYmFieWxvbk9iamVjdC5tZXRhZGF0YSB8fCB7fSk7XHJcbiAgICAgICAgICAgIGNvbnN0IGdsdGYgPSAobWV0YWRhdGEuZ2x0ZiA9IG1ldGFkYXRhLmdsdGYgfHwge30pO1xyXG4gICAgICAgICAgICBnbHRmLmV4dHJhcyA9IGdsdGZQcm9wLmV4dHJhcztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpOiB2b2lkIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTm9kZUFzeW5jKGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU5vZGUsIGFzc2lnbjogKGJhYnlsb25UcmFuc2Zvcm1Ob2RlOiBUcmFuc2Zvcm1Ob2RlKSA9PiB2b2lkKTogTnVsbGFibGU8UHJvbWlzZTxUcmFuc2Zvcm1Ob2RlPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIubG9hZE5vZGVBc3luYyhjb250ZXh0LCBub2RlLCAoYmFieWxvblRyYW5zZm9ybU5vZGUpOiB2b2lkID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fYXNzaWduRXh0cmFzKGJhYnlsb25UcmFuc2Zvcm1Ob2RlLCBub2RlKTtcclxuICAgICAgICAgICAgYXNzaWduKGJhYnlsb25UcmFuc2Zvcm1Ob2RlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZENhbWVyYUFzeW5jKGNvbnRleHQ6IHN0cmluZywgY2FtZXJhOiBJQ2FtZXJhLCBhc3NpZ246IChiYWJ5bG9uQ2FtZXJhOiBDYW1lcmEpID0+IHZvaWQpOiBOdWxsYWJsZTxQcm9taXNlPENhbWVyYT4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGVyLmxvYWRDYW1lcmFBc3luYyhjb250ZXh0LCBjYW1lcmEsIChiYWJ5bG9uQ2FtZXJhKTogdm9pZCA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Fzc2lnbkV4dHJhcyhiYWJ5bG9uQ2FtZXJhLCBjYW1lcmEpO1xyXG4gICAgICAgICAgICBhc3NpZ24oYmFieWxvbkNhbWVyYSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNyZWF0ZU1hdGVyaWFsKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbkRyYXdNb2RlOiBudW1iZXIpOiBOdWxsYWJsZTxNYXRlcmlhbD4ge1xyXG4gICAgICAgIGNvbnN0IGJhYnlsb25NYXRlcmlhbCA9IHRoaXMuX2xvYWRlci5jcmVhdGVNYXRlcmlhbChjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbkRyYXdNb2RlKTtcclxuICAgICAgICB0aGlzLl9hc3NpZ25FeHRyYXMoYmFieWxvbk1hdGVyaWFsLCBtYXRlcmlhbCk7XHJcbiAgICAgICAgcmV0dXJuIGJhYnlsb25NYXRlcmlhbDtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCBmYWxzZSwgKGxvYWRlcikgPT4gbmV3IEV4dHJhc0FzTWV0YWRhdGEobG9hZGVyKSk7XHJcbiIsIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiAqL1xyXG5cclxuaW1wb3J0IHsgQW5pbWF0aW9uIH0gZnJvbSBcImNvcmUvQW5pbWF0aW9ucy9hbmltYXRpb25cIjtcclxuaW1wb3J0IHR5cGUgeyBJQ2FtZXJhLCBJS0hSTGlnaHRzUHVuY3R1YWxfTGlnaHQsIElNYXRlcmlhbCB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElBbmltYXRhYmxlIH0gZnJvbSBcImNvcmUvQW5pbWF0aW9ucy9hbmltYXRhYmxlLmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyBBbmltYXRpb25Qcm9wZXJ0eUluZm8sIG5vZGVBbmltYXRpb25EYXRhIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJBbmltYXRpb25cIjtcclxuaW1wb3J0IHsgQ29sb3IzIH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC5jb2xvclwiO1xyXG5cclxuZnVuY3Rpb24gZ2V0Q29sb3IzKF90YXJnZXQ6IGFueSwgc291cmNlOiBGbG9hdDMyQXJyYXksIG9mZnNldDogbnVtYmVyLCBzY2FsZTogbnVtYmVyKTogQ29sb3IzIHtcclxuICAgIHJldHVybiBDb2xvcjMuRnJvbUFycmF5KHNvdXJjZSwgb2Zmc2V0KS5zY2FsZShzY2FsZSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEFscGhhKF90YXJnZXQ6IGFueSwgc291cmNlOiBGbG9hdDMyQXJyYXksIG9mZnNldDogbnVtYmVyLCBzY2FsZTogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgIHJldHVybiBzb3VyY2Vbb2Zmc2V0ICsgM10gKiBzY2FsZTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0RmxvYXQoX3RhcmdldDogYW55LCBzb3VyY2U6IEZsb2F0MzJBcnJheSwgb2Zmc2V0OiBudW1iZXIsIHNjYWxlOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHNvdXJjZVtvZmZzZXRdICogc2NhbGU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldE1pbnVzRmxvYXQoX3RhcmdldDogYW55LCBzb3VyY2U6IEZsb2F0MzJBcnJheSwgb2Zmc2V0OiBudW1iZXIsIHNjYWxlOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIC1zb3VyY2Vbb2Zmc2V0XSAqIHNjYWxlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXROZXh0RmxvYXQoX3RhcmdldDogYW55LCBzb3VyY2U6IEZsb2F0MzJBcnJheSwgb2Zmc2V0OiBudW1iZXIsIHNjYWxlOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHNvdXJjZVtvZmZzZXQgKyAxXSAqIHNjYWxlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRGbG9hdEJ5MihfdGFyZ2V0OiBhbnksIHNvdXJjZTogRmxvYXQzMkFycmF5LCBvZmZzZXQ6IG51bWJlciwgc2NhbGU6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICByZXR1cm4gc291cmNlW29mZnNldF0gKiBzY2FsZSAqIDI7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKHRleHR1cmVOYW1lOiBzdHJpbmcpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgc2NhbGU6IFtcclxuICAgICAgICAgICAgbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBgJHt0ZXh0dXJlTmFtZX0udVNjYWxlYCwgZ2V0RmxvYXQsICgpID0+IDIpLFxyXG4gICAgICAgICAgICBuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIGAke3RleHR1cmVOYW1lfS52U2NhbGVgLCBnZXROZXh0RmxvYXQsICgpID0+IDIpLFxyXG4gICAgICAgIF0sXHJcbiAgICAgICAgb2Zmc2V0OiBbXHJcbiAgICAgICAgICAgIG5ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgYCR7dGV4dHVyZU5hbWV9LnVPZmZzZXRgLCBnZXRGbG9hdCwgKCkgPT4gMiksXHJcbiAgICAgICAgICAgIG5ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgYCR7dGV4dHVyZU5hbWV9LnZPZmZzZXRgLCBnZXROZXh0RmxvYXQsICgpID0+IDIpLFxyXG4gICAgICAgIF0sXHJcbiAgICAgICAgcm90YXRpb246IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIGAke3RleHR1cmVOYW1lfS53QW5nYCwgZ2V0TWludXNGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgfTtcclxufVxyXG5cclxuY2xhc3MgQ2FtZXJhQW5pbWF0aW9uUHJvcGVydHlJbmZvIGV4dGVuZHMgQW5pbWF0aW9uUHJvcGVydHlJbmZvIHtcclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBidWlsZEFuaW1hdGlvbnModGFyZ2V0OiBJQ2FtZXJhLCBuYW1lOiBzdHJpbmcsIGZwczogbnVtYmVyLCBrZXlzOiBhbnlbXSwgY2FsbGJhY2s6IChiYWJ5bG9uQW5pbWF0YWJsZTogSUFuaW1hdGFibGUsIGJhYnlsb25BbmltYXRpb246IEFuaW1hdGlvbikgPT4gdm9pZCk6IHZvaWQge1xyXG4gICAgICAgIGNhbGxiYWNrKHRhcmdldC5fYmFieWxvbkNhbWVyYSEsIHRoaXMuX2J1aWxkQW5pbWF0aW9uKG5hbWUsIGZwcywga2V5cykpO1xyXG4gICAgfVxyXG59XHJcblxyXG5jbGFzcyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyBleHRlbmRzIEFuaW1hdGlvblByb3BlcnR5SW5mbyB7XHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgYnVpbGRBbmltYXRpb25zKHRhcmdldDogSU1hdGVyaWFsLCBuYW1lOiBzdHJpbmcsIGZwczogbnVtYmVyLCBrZXlzOiBhbnlbXSwgY2FsbGJhY2s6IChiYWJ5bG9uQW5pbWF0YWJsZTogSUFuaW1hdGFibGUsIGJhYnlsb25BbmltYXRpb246IEFuaW1hdGlvbikgPT4gdm9pZCk6IHZvaWQge1xyXG4gICAgICAgIGZvciAoY29uc3QgZmlsbE1vZGUgaW4gdGFyZ2V0Ll9kYXRhISkge1xyXG4gICAgICAgICAgICBjYWxsYmFjayh0YXJnZXQuX2RhdGEhW2ZpbGxNb2RlXS5iYWJ5bG9uTWF0ZXJpYWwsIHRoaXMuX2J1aWxkQW5pbWF0aW9uKG5hbWUsIGZwcywga2V5cykpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuY2xhc3MgTGlnaHRBbmltYXRpb25Qcm9wZXJ0eUluZm8gZXh0ZW5kcyBBbmltYXRpb25Qcm9wZXJ0eUluZm8ge1xyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGJ1aWxkQW5pbWF0aW9ucyhcclxuICAgICAgICB0YXJnZXQ6IElLSFJMaWdodHNQdW5jdHVhbF9MaWdodCxcclxuICAgICAgICBuYW1lOiBzdHJpbmcsXHJcbiAgICAgICAgZnBzOiBudW1iZXIsXHJcbiAgICAgICAga2V5czogYW55W10sXHJcbiAgICAgICAgY2FsbGJhY2s6IChiYWJ5bG9uQW5pbWF0YWJsZTogSUFuaW1hdGFibGUsIGJhYnlsb25BbmltYXRpb246IEFuaW1hdGlvbikgPT4gdm9pZFxyXG4gICAgKTogdm9pZCB7XHJcbiAgICAgICAgY2FsbGJhY2sodGFyZ2V0Ll9iYWJ5bG9uTGlnaHQhLCB0aGlzLl9idWlsZEFuaW1hdGlvbihuYW1lLCBmcHMsIGtleXMpKTtcclxuICAgIH1cclxufVxyXG5cclxuY29uc3Qgbm9kZXNUcmVlID0ge1xyXG4gICAgX19hcnJheV9fOiB7XHJcbiAgICAgICAgX190YXJnZXRfXzogdHJ1ZSxcclxuICAgICAgICAuLi5ub2RlQW5pbWF0aW9uRGF0YSxcclxuICAgIH0sXHJcbn07XHJcblxyXG5jb25zdCBjYW1lcmFzVHJlZSA9IHtcclxuICAgIF9fYXJyYXlfXzoge1xyXG4gICAgICAgIF9fdGFyZ2V0X186IHRydWUsXHJcbiAgICAgICAgb3J0aG9ncmFwaGljOiB7XHJcbiAgICAgICAgICAgIHhtYWc6IFtcclxuICAgICAgICAgICAgICAgIG5ldyBDYW1lcmFBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwib3J0aG9MZWZ0XCIsIGdldE1pbnVzRmxvYXQsICgpID0+IDEpLFxyXG4gICAgICAgICAgICAgICAgbmV3IENhbWVyYUFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJvcnRob1JpZ2h0XCIsIGdldE5leHRGbG9hdCwgKCkgPT4gMSksXHJcbiAgICAgICAgICAgIF0sXHJcbiAgICAgICAgICAgIHltYWc6IFtcclxuICAgICAgICAgICAgICAgIG5ldyBDYW1lcmFBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwib3J0aG9Cb3R0b21cIiwgZ2V0TWludXNGbG9hdCwgKCkgPT4gMSksXHJcbiAgICAgICAgICAgICAgICBuZXcgQ2FtZXJhQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcIm9ydGhvVG9wXCIsIGdldE5leHRGbG9hdCwgKCkgPT4gMSksXHJcbiAgICAgICAgICAgIF0sXHJcbiAgICAgICAgICAgIHpmYXI6IFtuZXcgQ2FtZXJhQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcIm1heFpcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgem5lYXI6IFtuZXcgQ2FtZXJhQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcIm1pblpcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHBlcnNwZWN0aXZlOiB7XHJcbiAgICAgICAgICAgIHlmb3Y6IFtuZXcgQ2FtZXJhQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcImZvdlwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICB6ZmFyOiBbbmV3IENhbWVyYUFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJtYXhaXCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgIHpuZWFyOiBbbmV3IENhbWVyYUFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJtaW5aXCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgfSxcclxuICAgIH0sXHJcbn07XHJcblxyXG5jb25zdCBtYXRlcmlhbHNUcmVlID0ge1xyXG4gICAgX19hcnJheV9fOiB7XHJcbiAgICAgICAgX190YXJnZXRfXzogdHJ1ZSxcclxuICAgICAgICBwYnJNZXRhbGxpY1JvdWdobmVzczoge1xyXG4gICAgICAgICAgICBiYXNlQ29sb3JGYWN0b3I6IFtcclxuICAgICAgICAgICAgICAgIG5ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9DT0xPUjMsIFwiYWxiZWRvQ29sb3JcIiwgZ2V0Q29sb3IzLCAoKSA9PiA0KSxcclxuICAgICAgICAgICAgICAgIG5ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJhbHBoYVwiLCBnZXRBbHBoYSwgKCkgPT4gNCksXHJcbiAgICAgICAgICAgIF0sXHJcbiAgICAgICAgICAgIG1ldGFsbGljRmFjdG9yOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcIm1ldGFsbGljXCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgIHJvdWdobmVzc0ZhY3RvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJyb3VnaG5lc3NcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgYmFzZUNvbG9yVGV4dHVyZToge1xyXG4gICAgICAgICAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgIEtIUl90ZXh0dXJlX3RyYW5zZm9ybTogZ2V0VGV4dHVyZVRyYW5zZm9ybVRyZWUoXCJhbGJlZG9UZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbWV0YWxsaWNSb3VnaG5lc3NUZXh0dXJlOiB7XHJcbiAgICAgICAgICAgICAgICBleHRlbnNpb25zOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcIm1ldGFsbGljVGV4dHVyZVwiKSxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbWlzc2l2ZUZhY3RvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9DT0xPUjMsIFwiZW1pc3NpdmVDb2xvclwiLCBnZXRDb2xvcjMsICgpID0+IDMpXSxcclxuICAgICAgICBub3JtYWxUZXh0dXJlOiB7XHJcbiAgICAgICAgICAgIHNjYWxlOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcImJ1bXBUZXh0dXJlLmxldmVsXCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgICAgIEtIUl90ZXh0dXJlX3RyYW5zZm9ybTogZ2V0VGV4dHVyZVRyYW5zZm9ybVRyZWUoXCJidW1wVGV4dHVyZVwiKSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIG9jY2x1c2lvblRleHR1cmU6IHtcclxuICAgICAgICAgICAgc3RyZW5ndGg6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwiYW1iaWVudFRleHR1cmVTdHJlbmd0aFwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICBleHRlbnNpb25zOiB7XHJcbiAgICAgICAgICAgICAgICBLSFJfdGV4dHVyZV90cmFuc2Zvcm06IGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKFwiYW1iaWVudFRleHR1cmVcIiksXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbWlzc2l2ZVRleHR1cmU6IHtcclxuICAgICAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcImVtaXNzaXZlVGV4dHVyZVwiKSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgS0hSX21hdGVyaWFsc19hbmlzb3Ryb3B5OiB7XHJcbiAgICAgICAgICAgICAgICBhbmlzb3Ryb3B5U3RyZW5ndGg6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwiYW5pc290cm9weS5pbnRlbnNpdHlcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIGFuaXNvdHJvcHlSb3RhdGlvbjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJhbmlzb3Ryb3B5LmFuZ2xlXCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgICAgICBhbmlzb3Ryb3B5VGV4dHVyZToge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcImFuaXNvdHJvcHkudGV4dHVyZVwiKSxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgS0hSX21hdGVyaWFsc19jbGVhcmNvYXQ6IHtcclxuICAgICAgICAgICAgICAgIGNsZWFyY29hdEZhY3RvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJjbGVhckNvYXQuaW50ZW5zaXR5XCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgICAgICBjbGVhcmNvYXRSb3VnaG5lc3NGYWN0b3I6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwiY2xlYXJDb2F0LnJvdWdobmVzc1wiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICAgICAgY2xlYXJjb2F0VGV4dHVyZToge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcImNsZWFyQ29hdC50ZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgY2xlYXJjb2F0Tm9ybWFsVGV4dHVyZToge1xyXG4gICAgICAgICAgICAgICAgICAgIHNjYWxlOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcImNsZWFyQ29hdC5idW1wVGV4dHVyZS5sZXZlbFwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcImNsZWFyQ29hdC5idW1wVGV4dHVyZVwiKSxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGNsZWFyY29hdFJvdWdobmVzc1RleHR1cmU6IHtcclxuICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEtIUl90ZXh0dXJlX3RyYW5zZm9ybTogZ2V0VGV4dHVyZVRyYW5zZm9ybVRyZWUoXCJjbGVhckNvYXQudGV4dHVyZVJvdWdobmVzc1wiKSxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgS0hSX21hdGVyaWFsc19kaXNwZXJzaW9uOiB7XHJcbiAgICAgICAgICAgICAgICBkaXNwZXJzaW9uOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcInN1YlN1cmZhY2UuZGlzcGVyc2lvblwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBLSFJfbWF0ZXJpYWxzX2VtaXNzaXZlX3N0cmVuZ3RoOiB7XHJcbiAgICAgICAgICAgICAgICBlbWlzc2l2ZVN0cmVuZ3RoOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcImVtaXNzaXZlSW50ZW5zaXR5XCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIEtIUl9tYXRlcmlhbHNfaW9yOiB7XHJcbiAgICAgICAgICAgICAgICBpb3I6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwiaW5kZXhPZlJlZnJhY3Rpb25cIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgS0hSX21hdGVyaWFsc19pcmlkZXNjZW5jZToge1xyXG4gICAgICAgICAgICAgICAgaXJpZGVzY2VuY2VGYWN0b3I6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwiaXJpZGVzY2VuY2UuaW50ZW5zaXR5XCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgICAgICBpcmlkZXNjZW5jZUlvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJpcmlkZXNjZW5jZS5pbmRleE9mUmVmcmFjdGlvblwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICAgICAgaXJpZGVzY2VuY2VUaGlja25lc3NNaW5pbXVtOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcImlyaWRlc2NlbmNlLm1pbmltdW1UaGlja25lc3NcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIGlyaWRlc2NlbmNlVGhpY2tuZXNzTWF4aW11bTogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJpcmlkZXNjZW5jZS5tYXhpbXVtVGhpY2tuZXNzXCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgICAgICBpcmlkZXNjZW5jZVRleHR1cmU6IHtcclxuICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEtIUl90ZXh0dXJlX3RyYW5zZm9ybTogZ2V0VGV4dHVyZVRyYW5zZm9ybVRyZWUoXCJpcmlkZXNjZW5jZS50ZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgaXJpZGVzY2VuY2VUaGlja25lc3NUZXh0dXJlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBLSFJfdGV4dHVyZV90cmFuc2Zvcm06IGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKFwiaXJpZGVzY2VuY2UudGhpY2tuZXNzVGV4dHVyZVwiKSxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgS0hSX21hdGVyaWFsc19zaGVlbjoge1xyXG4gICAgICAgICAgICAgICAgc2hlZW5Db2xvckZhY3RvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9DT0xPUjMsIFwic2hlZW4uY29sb3JcIiwgZ2V0Q29sb3IzLCAoKSA9PiAzKV0sXHJcbiAgICAgICAgICAgICAgICBzaGVlblJvdWdobmVzc0ZhY3RvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJzaGVlbi5yb3VnaG5lc3NcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIHNoZWVuQ29sb3JUZXh0dXJlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBLSFJfdGV4dHVyZV90cmFuc2Zvcm06IGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKFwic2hlZW4udGV4dHVyZVwiKSxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIHNoZWVuUm91Z2huZXNzVGV4dHVyZToge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcInNoZWVuLnRleHR1cmVSb3VnaG5lc3NcIiksXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIEtIUl9tYXRlcmlhbHNfc3BlY3VsYXI6IHtcclxuICAgICAgICAgICAgICAgIHNwZWN1bGFyRmFjdG9yOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcIm1ldGFsbGljRjBGYWN0b3JcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIHNwZWN1bGFyQ29sb3JGYWN0b3I6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfQ09MT1IzLCBcIm1ldGFsbGljUmVmbGVjdGFuY2VDb2xvclwiLCBnZXRDb2xvcjMsICgpID0+IDMpXSxcclxuICAgICAgICAgICAgICAgIHNwZWN1bGFyVGV4dHVyZToge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcIm1ldGFsbGljUmVmbGVjdGFuY2VUZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgc3BlY3VsYXJDb2xvclRleHR1cmU6IHtcclxuICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEtIUl90ZXh0dXJlX3RyYW5zZm9ybTogZ2V0VGV4dHVyZVRyYW5zZm9ybVRyZWUoXCJyZWZsZWN0YW5jZVRleHR1cmVcIiksXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIEtIUl9tYXRlcmlhbHNfdHJhbnNtaXNzaW9uOiB7XHJcbiAgICAgICAgICAgICAgICB0cmFuc21pc3Npb25GYWN0b3I6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwic3ViU3VyZmFjZS5yZWZyYWN0aW9uSW50ZW5zaXR5XCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgICAgICB0cmFuc21pc3Npb25UZXh0dXJlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBLSFJfdGV4dHVyZV90cmFuc2Zvcm06IGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKFwic3ViU3VyZmFjZS5yZWZyYWN0aW9uSW50ZW5zaXR5VGV4dHVyZVwiKSxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgS0hSX21hdGVyaWFsc192b2x1bWU6IHtcclxuICAgICAgICAgICAgICAgIGF0dGVudWF0aW9uQ29sb3I6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfQ09MT1IzLCBcInN1YlN1cmZhY2UudGludENvbG9yXCIsIGdldENvbG9yMywgKCkgPT4gMyldLFxyXG4gICAgICAgICAgICAgICAgYXR0ZW51YXRpb25EaXN0YW5jZTogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJzdWJTdXJmYWNlLnRpbnRDb2xvckF0RGlzdGFuY2VcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIHRoaWNrbmVzc0ZhY3RvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJzdWJTdXJmYWNlLm1heGltdW1UaGlja25lc3NcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIHRoaWNrbmVzc1RleHR1cmU6IHtcclxuICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEtIUl90ZXh0dXJlX3RyYW5zZm9ybTogZ2V0VGV4dHVyZVRyYW5zZm9ybVRyZWUoXCJzdWJTdXJmYWNlLnRoaWNrbmVzc1RleHR1cmVcIiksXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIEtIUl9tYXRlcmlhbHNfZGlmZnVzZV90cmFuc21pc3Npb246IHtcclxuICAgICAgICAgICAgICAgIGRpZmZ1c2VUcmFuc21pc3Npb25GYWN0b3I6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwic3ViU3VyZmFjZS50cmFuc2x1Y2VuY3lJbnRlbnNpdHlcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIGRpZmZ1c2VUcmFuc21pc3Npb25UZXh0dXJlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBLSFJfdGV4dHVyZV90cmFuc2Zvcm06IGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKFwic3ViU3VyZmFjZS50cmFuc2x1Y2VuY3lJbnRlbnNpdHlUZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZGlmZnVzZVRyYW5zbWlzc2lvbkNvbG9yRmFjdG9yOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0NPTE9SMywgXCJzdWJTdXJmYWNlLnRyYW5zbHVjZW5jeUNvbG9yXCIsIGdldENvbG9yMywgKCkgPT4gMyldLFxyXG4gICAgICAgICAgICAgICAgZGlmZnVzZVRyYW5zbWlzc2lvbkNvbG9yVGV4dHVyZToge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcInN1YlN1cmZhY2UudHJhbnNsdWNlbmN5Q29sb3JUZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICB9LFxyXG59O1xyXG5cclxuY29uc3QgZXh0ZW5zaW9uc1RyZWUgPSB7XHJcbiAgICBLSFJfbGlnaHRzX3B1bmN0dWFsOiB7XHJcbiAgICAgICAgbGlnaHRzOiB7XHJcbiAgICAgICAgICAgIF9fYXJyYXlfXzoge1xyXG4gICAgICAgICAgICAgICAgX190YXJnZXRfXzogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGNvbG9yOiBbbmV3IExpZ2h0QW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0NPTE9SMywgXCJkaWZmdXNlXCIsIGdldENvbG9yMywgKCkgPT4gMyldLFxyXG4gICAgICAgICAgICAgICAgaW50ZW5zaXR5OiBbbmV3IExpZ2h0QW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcImludGVuc2l0eVwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICAgICAgcmFuZ2U6IFtuZXcgTGlnaHRBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwicmFuZ2VcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIHNwb3Q6IHtcclxuICAgICAgICAgICAgICAgICAgICBpbm5lckNvbmVBbmdsZTogW25ldyBMaWdodEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJpbm5lckFuZ2xlXCIsIGdldEZsb2F0QnkyLCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgICAgICAgICAgb3V0ZXJDb25lQW5nbGU6IFtuZXcgTGlnaHRBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwiYW5nbGVcIiwgZ2V0RmxvYXRCeTIsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgfSxcclxuICAgIH0sXHJcbn07XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBjb25zdCBhbmltYXRpb25Qb2ludGVyVHJlZSA9IHtcclxuICAgIG5vZGVzOiBub2Rlc1RyZWUsXHJcbiAgICBtYXRlcmlhbHM6IG1hdGVyaWFsc1RyZWUsXHJcbiAgICBjYW1lcmFzOiBjYW1lcmFzVHJlZSxcclxuICAgIGV4dGVuc2lvbnM6IGV4dGVuc2lvbnNUcmVlLFxyXG59O1xyXG4iLCJpbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHR5cGUgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB0eXBlIHsgQW5pbWF0aW9uIH0gZnJvbSBcImNvcmUvQW5pbWF0aW9ucy9hbmltYXRpb25cIjtcclxuaW1wb3J0IHR5cGUgeyBJQW5pbWF0YWJsZSB9IGZyb20gXCJjb3JlL0FuaW1hdGlvbnMvYW5pbWF0YWJsZS5pbnRlcmZhY2VcIjtcclxuaW1wb3J0IHR5cGUgeyBJQW5pbWF0aW9uLCBJQW5pbWF0aW9uQ2hhbm5lbCwgSUdMVEYgfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSQW5pbWF0aW9uUG9pbnRlciB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGggfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gXCJjb3JlL01pc2MvbG9nZ2VyXCI7XHJcbmltcG9ydCB7IGFuaW1hdGlvblBvaW50ZXJUcmVlIH0gZnJvbSBcIi4vS0hSX2FuaW1hdGlvbl9wb2ludGVyLmRhdGFcIjtcclxuaW1wb3J0IHsgR0xURlBhdGhUb09iamVjdENvbnZlcnRlciB9IGZyb20gXCIuL2dsdGZQYXRoVG9PYmplY3RDb252ZXJ0ZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBBbmltYXRpb25Qcm9wZXJ0eUluZm8gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckFuaW1hdGlvblwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX2FuaW1hdGlvbl9wb2ludGVyXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9hbmltYXRpb25fcG9pbnRlciBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiS0hSX2FuaW1hdGlvbl9wb2ludGVyXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIENsYXNzIHRvIGNvbnZlcnQgYW4gYW5pbWF0aW9uIHBvaW50ZXIgcGF0aCB0byBhIHNtYXJ0IG9iamVjdCB0aGF0XHJcbiAqIGdldHMgZGF0YSBmcm9tIHRoZSBhbmltYXRpb24gYnVmZmVyIGFuZCBjcmVhdGVzIGFuaW1hdGlvbnMuXHJcbiAqL1xyXG5jbGFzcyBBbmltYXRpb25Qb2ludGVyUGF0aFRvT2JqZWN0Q29udmVydGVyIGV4dGVuZHMgR0xURlBhdGhUb09iamVjdENvbnZlcnRlcjxBbmltYXRpb25Qcm9wZXJ0eUluZm9bXT4ge1xyXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKGdsdGY6IElHTFRGKSB7XHJcbiAgICAgICAgc3VwZXIoZ2x0ZiwgYW5pbWF0aW9uUG9pbnRlclRyZWUpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb24gUFJdKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9wdWxsLzIxNDcpXHJcbiAqICEhISBFeHBlcmltZW50YWwgRXh0ZW5zaW9uIFN1YmplY3QgdG8gQ2hhbmdlcyAhISFcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9hbmltYXRpb25fcG9pbnRlciBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcbiAgICBwcml2YXRlIF9wYXRoVG9PYmplY3RDb252ZXJ0ZXI/OiBBbmltYXRpb25Qb2ludGVyUGF0aFRvT2JqZWN0Q29udmVydGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLl9wYXRoVG9PYmplY3RDb252ZXJ0ZXIgPSBuZXcgQW5pbWF0aW9uUG9pbnRlclBhdGhUb09iamVjdENvbnZlcnRlcih0aGlzLl9sb2FkZXIuZ2x0Zik7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldCBlbmFibGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICAgICAgZGVsZXRlIHRoaXMuX3BhdGhUb09iamVjdENvbnZlcnRlcjsgLy8gR0NcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIExvYWRzIGEgZ2xURiBhbmltYXRpb24gY2hhbm5lbC5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBhbmltYXRpb25Db250ZXh0IFRoZSBjb250ZXh0IG9mIHRoZSBhbmltYXRpb24gd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIGFuaW1hdGlvbiBUaGUgZ2xURiBhbmltYXRpb24gcHJvcGVydHlcclxuICAgICAqIEBwYXJhbSBjaGFubmVsIFRoZSBnbFRGIGFuaW1hdGlvbiBjaGFubmVsIHByb3BlcnR5XHJcbiAgICAgKiBAcGFyYW0gb25Mb2FkIENhbGxlZCBmb3IgZWFjaCBhbmltYXRpb24gbG9hZGVkXHJcbiAgICAgKiBAcmV0dXJucyBBIHZvaWQgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGxvYWQgaXMgY29tcGxldGUgb3IgbnVsbCBpZiBub3QgaGFuZGxlZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvYWRBbmltYXRpb25DaGFubmVsQXN5bmMoXHJcbiAgICAgICAgY29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIGFuaW1hdGlvbkNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBhbmltYXRpb246IElBbmltYXRpb24sXHJcbiAgICAgICAgY2hhbm5lbDogSUFuaW1hdGlvbkNoYW5uZWwsXHJcbiAgICAgICAgb25Mb2FkOiAoYmFieWxvbkFuaW1hdGFibGU6IElBbmltYXRhYmxlLCBiYWJ5bG9uQW5pbWF0aW9uOiBBbmltYXRpb24pID0+IHZvaWRcclxuICAgICk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb24gPSBjaGFubmVsLnRhcmdldC5leHRlbnNpb25zPy5LSFJfYW5pbWF0aW9uX3BvaW50ZXIgYXMgSUtIUkFuaW1hdGlvblBvaW50ZXI7XHJcbiAgICAgICAgaWYgKCFleHRlbnNpb24gfHwgIXRoaXMuX3BhdGhUb09iamVjdENvbnZlcnRlcikge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChjaGFubmVsLnRhcmdldC5wYXRoICE9PSBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aC5QT0lOVEVSKSB7XHJcbiAgICAgICAgICAgIExvZ2dlci5XYXJuKGAke2NvbnRleHR9L3RhcmdldC9wYXRoOiBWYWx1ZSAoJHtjaGFubmVsLnRhcmdldC5wYXRofSkgbXVzdCBiZSAoJHtBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aC5QT0lOVEVSfSkgd2hlbiB1c2luZyB0aGUgJHt0aGlzLm5hbWV9IGV4dGVuc2lvbmApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGNoYW5uZWwudGFyZ2V0Lm5vZGUgIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIExvZ2dlci5XYXJuKGAke2NvbnRleHR9L3RhcmdldC9ub2RlOiBWYWx1ZSAoJHtjaGFubmVsLnRhcmdldC5ub2RlfSkgbXVzdCBub3QgYmUgcHJlc2VudCB3aGVuIHVzaW5nIHRoZSAke3RoaXMubmFtZX0gZXh0ZW5zaW9uYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBleHRlbnNpb25Db250ZXh0ID0gYCR7Y29udGV4dH0vZXh0ZW5zaW9ucy8ke3RoaXMubmFtZX1gO1xyXG5cclxuICAgICAgICBjb25zdCBwb2ludGVyID0gZXh0ZW5zaW9uLnBvaW50ZXI7XHJcbiAgICAgICAgaWYgKCFwb2ludGVyKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtleHRlbnNpb25Db250ZXh0fTogUG9pbnRlciBpcyBtaXNzaW5nYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCB0YXJnZXRJbmZvID0gdGhpcy5fcGF0aFRvT2JqZWN0Q29udmVydGVyLmNvbnZlcnQocG9pbnRlcik7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIuX2xvYWRBbmltYXRpb25DaGFubmVsRnJvbVRhcmdldEluZm9Bc3luYyhjb250ZXh0LCBhbmltYXRpb25Db250ZXh0LCBhbmltYXRpb24sIGNoYW5uZWwsIHRhcmdldEluZm8sIG9uTG9hZCk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBMb2dnZXIuV2FybihgJHtleHRlbnNpb25Db250ZXh0fS9wb2ludGVyOiBJbnZhbGlkIHBvaW50ZXIgKCR7cG9pbnRlcn0pIHNraXBwZWRgKTtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfYW5pbWF0aW9uX3BvaW50ZXIobG9hZGVyKSk7XHJcbiIsImltcG9ydCB7IERyYWNvQ29tcHJlc3Npb24gfSBmcm9tIFwiY29yZS9NZXNoZXMvQ29tcHJlc3Npb24vZHJhY29Db21wcmVzc2lvblwiO1xyXG5pbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgVmVydGV4QnVmZmVyIH0gZnJvbSBcImNvcmUvQnVmZmVycy9idWZmZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBHZW9tZXRyeSB9IGZyb20gXCJjb3JlL01lc2hlcy9nZW9tZXRyeVwiO1xyXG5pbXBvcnQgdHlwZSB7IE1lc2ggfSBmcm9tIFwiY29yZS9NZXNoZXMvbWVzaFwiO1xyXG5cclxuaW1wb3J0IHsgTWVzaFByaW1pdGl2ZU1vZGUgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB0eXBlIHsgSUtIUkRyYWNvTWVzaENvbXByZXNzaW9uIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElNZXNoUHJpbWl0aXZlLCBJQnVmZmVyVmlldyB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciwgQXJyYXlJdGVtIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl9kcmFjb19tZXNoX2NvbXByZXNzaW9uXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9kcmFjb19tZXNoX2NvbXByZXNzaW9uIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJLSFJfZHJhY29fbWVzaF9jb21wcmVzc2lvblwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbmludGVyZmFjZSBJQnVmZmVyVmlld0RyYWNvIGV4dGVuZHMgSUJ1ZmZlclZpZXcge1xyXG4gICAgX2RyYWNvQmFieWxvbkdlb21ldHJ5PzogUHJvbWlzZTxHZW9tZXRyeT47XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl9kcmFjb19tZXNoX2NvbXByZXNzaW9uL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9kcmFjb19tZXNoX2NvbXByZXNzaW9uIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGRyYWNvIGNvbXByZXNzaW9uIHVzZWQgdG8gZGVjb2RlIHZlcnRleCBkYXRhIG9yIERyYWNvQ29tcHJlc3Npb24uRGVmYXVsdCBpZiBub3QgZGVmaW5lZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZHJhY29Db21wcmVzc2lvbj86IERyYWNvQ29tcHJlc3Npb247XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdG8gdXNlIHRoZSBub3JtYWxpemVkIGZsYWcgZnJvbSB0aGUgZ2xURiBhY2Nlc3NvciBpbnN0ZWFkIG9mIHRoZSBEcmFjbyBkYXRhLiBEZWZhdWx0cyB0byB0cnVlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdXNlTm9ybWFsaXplZEZsYWdGcm9tQWNjZXNzb3IgPSB0cnVlO1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gRHJhY29Db21wcmVzc2lvbi5EZWNvZGVyQXZhaWxhYmxlICYmIHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKTogdm9pZCB7XHJcbiAgICAgICAgZGVsZXRlIHRoaXMuZHJhY29Db21wcmVzc2lvbjtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbG9hZFZlcnRleERhdGFBc3luYyhjb250ZXh0OiBzdHJpbmcsIHByaW1pdGl2ZTogSU1lc2hQcmltaXRpdmUsIGJhYnlsb25NZXNoOiBNZXNoKTogTnVsbGFibGU8UHJvbWlzZTxHZW9tZXRyeT4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUkRyYWNvTWVzaENvbXByZXNzaW9uLCBHZW9tZXRyeT4oY29udGV4dCwgcHJpbWl0aXZlLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgaWYgKHByaW1pdGl2ZS5tb2RlICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHByaW1pdGl2ZS5tb2RlICE9PSBNZXNoUHJpbWl0aXZlTW9kZS5UUklBTkdMRVMgJiYgcHJpbWl0aXZlLm1vZGUgIT09IE1lc2hQcmltaXRpdmVNb2RlLlRSSUFOR0xFX1NUUklQKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBVbnN1cHBvcnRlZCBtb2RlICR7cHJpbWl0aXZlLm1vZGV9YCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGF0dHJpYnV0ZXM6IHsgW2tpbmQ6IHN0cmluZ106IG51bWJlciB9ID0ge307XHJcbiAgICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWQ6IHsgW2tpbmQ6IHN0cmluZ106IGJvb2xlYW4gfSA9IHt9O1xyXG4gICAgICAgICAgICBjb25zdCBsb2FkQXR0cmlidXRlID0gKG5hbWU6IHN0cmluZywga2luZDogc3RyaW5nKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB1bmlxdWVJZCA9IGV4dGVuc2lvbi5hdHRyaWJ1dGVzW25hbWVdO1xyXG4gICAgICAgICAgICAgICAgaWYgKHVuaXF1ZUlkID09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWVzaC5fZGVsYXlJbmZvID0gYmFieWxvbk1lc2guX2RlbGF5SW5mbyB8fCBbXTtcclxuICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTWVzaC5fZGVsYXlJbmZvLmluZGV4T2Yoa2luZCkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1lc2guX2RlbGF5SW5mby5wdXNoKGtpbmQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNba2luZF0gPSB1bmlxdWVJZDtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy51c2VOb3JtYWxpemVkRmxhZ0Zyb21BY2Nlc3Nvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFjY2Vzc29yID0gQXJyYXlJdGVtLlRyeUdldCh0aGlzLl9sb2FkZXIuZ2x0Zi5hY2Nlc3NvcnMsIHByaW1pdGl2ZS5hdHRyaWJ1dGVzW25hbWVdKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYWNjZXNzb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZFtraW5kXSA9IGFjY2Vzc29yLm5vcm1hbGl6ZWQgfHwgZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlBPU0lUSU9OXCIsIFZlcnRleEJ1ZmZlci5Qb3NpdGlvbktpbmQpO1xyXG4gICAgICAgICAgICBsb2FkQXR0cmlidXRlKFwiTk9STUFMXCIsIFZlcnRleEJ1ZmZlci5Ob3JtYWxLaW5kKTtcclxuICAgICAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlRBTkdFTlRcIiwgVmVydGV4QnVmZmVyLlRhbmdlbnRLaW5kKTtcclxuICAgICAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlRFWENPT1JEXzBcIiwgVmVydGV4QnVmZmVyLlVWS2luZCk7XHJcbiAgICAgICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJURVhDT09SRF8xXCIsIFZlcnRleEJ1ZmZlci5VVjJLaW5kKTtcclxuICAgICAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlRFWENPT1JEXzJcIiwgVmVydGV4QnVmZmVyLlVWM0tpbmQpO1xyXG4gICAgICAgICAgICBsb2FkQXR0cmlidXRlKFwiVEVYQ09PUkRfM1wiLCBWZXJ0ZXhCdWZmZXIuVVY0S2luZCk7XHJcbiAgICAgICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJURVhDT09SRF80XCIsIFZlcnRleEJ1ZmZlci5VVjVLaW5kKTtcclxuICAgICAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlRFWENPT1JEXzVcIiwgVmVydGV4QnVmZmVyLlVWNktpbmQpO1xyXG4gICAgICAgICAgICBsb2FkQXR0cmlidXRlKFwiSk9JTlRTXzBcIiwgVmVydGV4QnVmZmVyLk1hdHJpY2VzSW5kaWNlc0tpbmQpO1xyXG4gICAgICAgICAgICBsb2FkQXR0cmlidXRlKFwiV0VJR0hUU18wXCIsIFZlcnRleEJ1ZmZlci5NYXRyaWNlc1dlaWdodHNLaW5kKTtcclxuICAgICAgICAgICAgbG9hZEF0dHJpYnV0ZShcIkNPTE9SXzBcIiwgVmVydGV4QnVmZmVyLkNvbG9yS2luZCk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBidWZmZXJWaWV3ID0gQXJyYXlJdGVtLkdldChleHRlbnNpb25Db250ZXh0LCB0aGlzLl9sb2FkZXIuZ2x0Zi5idWZmZXJWaWV3cywgZXh0ZW5zaW9uLmJ1ZmZlclZpZXcpIGFzIElCdWZmZXJWaWV3RHJhY287XHJcbiAgICAgICAgICAgIGlmICghYnVmZmVyVmlldy5fZHJhY29CYWJ5bG9uR2VvbWV0cnkpIHtcclxuICAgICAgICAgICAgICAgIGJ1ZmZlclZpZXcuX2RyYWNvQmFieWxvbkdlb21ldHJ5ID0gdGhpcy5fbG9hZGVyLmxvYWRCdWZmZXJWaWV3QXN5bmMoYC9idWZmZXJWaWV3cy8ke2J1ZmZlclZpZXcuaW5kZXh9YCwgYnVmZmVyVmlldykudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRyYWNvQ29tcHJlc3Npb24gPSB0aGlzLmRyYWNvQ29tcHJlc3Npb24gfHwgRHJhY29Db21wcmVzc2lvbi5EZWZhdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkcmFjb0NvbXByZXNzaW9uLl9kZWNvZGVNZXNoVG9HZW9tZXRyeUZvckdsdGZBc3luYyhiYWJ5bG9uTWVzaC5uYW1lLCB0aGlzLl9sb2FkZXIuYmFieWxvblNjZW5lLCBkYXRhLCBhdHRyaWJ1dGVzLCBub3JtYWxpemVkKS5jYXRjaCgoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiAke2Vycm9yLm1lc3NhZ2V9YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlclZpZXcuX2RyYWNvQmFieWxvbkdlb21ldHJ5O1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfZHJhY29fbWVzaF9jb21wcmVzc2lvbihsb2FkZXIpKTtcclxuIiwiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXHJcbmltcG9ydCB0eXBlIHsgSUtIUkludGVyYWN0aXZpdHkgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB0eXBlIHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBGbG93R3JhcGhDb29yZGluYXRvciB9IGZyb20gXCJjb3JlL0Zsb3dHcmFwaC9mbG93R3JhcGhDb29yZGluYXRvclwiO1xyXG5pbXBvcnQgeyBGbG93R3JhcGggfSBmcm9tIFwiY29yZS9GbG93R3JhcGgvZmxvd0dyYXBoXCI7XHJcbmltcG9ydCB7IGNvbnZlcnRHTFRGVG9TZXJpYWxpemVkRmxvd0dyYXBoIH0gZnJvbSBcIi4vaW50ZXJhY3Rpdml0eUZ1bmN0aW9uc1wiO1xyXG5pbXBvcnQgeyBJbnRlcmFjdGl2aXR5UGF0aFRvT2JqZWN0Q29udmVydGVyIH0gZnJvbSBcIi4vaW50ZXJhY3Rpdml0eVBhdGhUb09iamVjdENvbnZlcnRlclwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX2ludGVyYWN0aXZpdHlcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX2ludGVyYWN0aXZpdHkgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9pbnRlcmFjdGl2aXR5XCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIExvYWRlciBleHRlbnNpb24gZm9yIEtIUl9pbnRlcmFjdGl2aXR5XHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgS0hSX2ludGVyYWN0aXZpdHkgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICBwcml2YXRlIF9wYXRoQ29udmVydGVyPzogSW50ZXJhY3Rpdml0eVBhdGhUb09iamVjdENvbnZlcnRlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICogQHBhcmFtIF9sb2FkZXJcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgICAgICB0aGlzLl9wYXRoQ29udmVydGVyID0gbmV3IEludGVyYWN0aXZpdHlQYXRoVG9PYmplY3RDb252ZXJ0ZXIodGhpcy5fbG9hZGVyLmdsdGYpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICAgICAgZGVsZXRlIHRoaXMuX3BhdGhDb252ZXJ0ZXI7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIG9uUmVhZHkoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9sb2FkZXIuYmFieWxvblNjZW5lIHx8ICF0aGlzLl9wYXRoQ29udmVydGVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qgc2NlbmUgPSB0aGlzLl9sb2FkZXIuYmFieWxvblNjZW5lO1xyXG4gICAgICAgIGNvbnN0IGludGVyYWN0aXZpdHlEZWZpbml0aW9uID0gdGhpcy5fbG9hZGVyLmdsdGYuZXh0ZW5zaW9ucz8uS0hSX2ludGVyYWN0aXZpdHkgYXMgSUtIUkludGVyYWN0aXZpdHk7XHJcblxyXG4gICAgICAgIGNvbnN0IGpzb24gPSBjb252ZXJ0R0xURlRvU2VyaWFsaXplZEZsb3dHcmFwaChpbnRlcmFjdGl2aXR5RGVmaW5pdGlvbik7XHJcbiAgICAgICAgY29uc3QgY29vcmRpbmF0b3IgPSBuZXcgRmxvd0dyYXBoQ29vcmRpbmF0b3IoeyBzY2VuZSB9KTtcclxuICAgICAgICBGbG93R3JhcGguUGFyc2UoanNvbiwgeyBjb29yZGluYXRvciwgcGF0aENvbnZlcnRlcjogdGhpcy5fcGF0aENvbnZlcnRlciB9KTtcclxuXHJcbiAgICAgICAgY29vcmRpbmF0b3Iuc3RhcnQoKTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX2ludGVyYWN0aXZpdHkobG9hZGVyKSk7XHJcbiIsIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiAqL1xyXG5pbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgVmVjdG9yMyB9IGZyb20gXCJjb3JlL01hdGhzL21hdGgudmVjdG9yXCI7XHJcbmltcG9ydCB7IENvbG9yMyB9IGZyb20gXCJjb3JlL01hdGhzL21hdGguY29sb3JcIjtcclxuaW1wb3J0IHsgRGlyZWN0aW9uYWxMaWdodCB9IGZyb20gXCJjb3JlL0xpZ2h0cy9kaXJlY3Rpb25hbExpZ2h0XCI7XHJcbmltcG9ydCB7IFBvaW50TGlnaHQgfSBmcm9tIFwiY29yZS9MaWdodHMvcG9pbnRMaWdodFwiO1xyXG5pbXBvcnQgeyBTcG90TGlnaHQgfSBmcm9tIFwiY29yZS9MaWdodHMvc3BvdExpZ2h0XCI7XHJcbmltcG9ydCB7IExpZ2h0IH0gZnJvbSBcImNvcmUvTGlnaHRzL2xpZ2h0XCI7XHJcbmltcG9ydCB0eXBlIHsgVHJhbnNmb3JtTm9kZSB9IGZyb20gXCJjb3JlL01lc2hlcy90cmFuc2Zvcm1Ob2RlXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IElLSFJMaWdodHNQdW5jdHVhbF9MaWdodFJlZmVyZW5jZSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgS0hSTGlnaHRzUHVuY3R1YWxfTGlnaHRUeXBlIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElOb2RlLCBJS0hSTGlnaHRzUHVuY3R1YWxfTGlnaHQgfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IEdMVEZMb2FkZXIsIEFycmF5SXRlbSB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbGlnaHRzX3B1bmN0dWFsXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9saWdodHNfcHVuY3R1YWwgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9saWdodHNfcHVuY3R1YWxcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbGlnaHRzX3B1bmN0dWFsL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9saWdodHMgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqIGhpZGRlbiAqL1xyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG4gICAgcHJpdmF0ZSBfbGlnaHRzPzogSUtIUkxpZ2h0c1B1bmN0dWFsX0xpZ2h0W107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgICAgICBkZWxldGUgdGhpcy5fbGlnaHRzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBvbkxvYWRpbmcoKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9ucyA9IHRoaXMuX2xvYWRlci5nbHRmLmV4dGVuc2lvbnM7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvbnMgJiYgZXh0ZW5zaW9uc1t0aGlzLm5hbWVdKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IGV4dGVuc2lvbnNbdGhpcy5uYW1lXSBhcyBhbnk7XHJcbiAgICAgICAgICAgIHRoaXMuX2xpZ2h0cyA9IGV4dGVuc2lvbi5saWdodHM7XHJcbiAgICAgICAgICAgIEFycmF5SXRlbS5Bc3NpZ24odGhpcy5fbGlnaHRzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWROb2RlQXN5bmMoY29udGV4dDogc3RyaW5nLCBub2RlOiBJTm9kZSwgYXNzaWduOiAoYmFieWxvblRyYW5zZm9ybU5vZGU6IFRyYW5zZm9ybU5vZGUpID0+IHZvaWQpOiBOdWxsYWJsZTxQcm9taXNlPFRyYW5zZm9ybU5vZGU+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElLSFJMaWdodHNQdW5jdHVhbF9MaWdodFJlZmVyZW5jZSwgVHJhbnNmb3JtTm9kZT4oY29udGV4dCwgbm9kZSwgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5fYWxsTWF0ZXJpYWxzRGlydHlSZXF1aXJlZCA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGVyLmxvYWROb2RlQXN5bmMoY29udGV4dCwgbm9kZSwgKGJhYnlsb25NZXNoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBsZXQgYmFieWxvbkxpZ2h0OiBMaWdodDtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBsaWdodCA9IEFycmF5SXRlbS5HZXQoZXh0ZW5zaW9uQ29udGV4dCwgdGhpcy5fbGlnaHRzLCBleHRlbnNpb24ubGlnaHQpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmFtZSA9IGxpZ2h0Lm5hbWUgfHwgYmFieWxvbk1lc2gubmFtZTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIuYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSAhIXRoaXMuX2xvYWRlci5fYXNzZXRDb250YWluZXI7XHJcblxyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChsaWdodC50eXBlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBLSFJMaWdodHNQdW5jdHVhbF9MaWdodFR5cGUuRElSRUNUSU9OQUw6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYmFieWxvbkRpcmVjdGlvbmFsTGlnaHQgPSBuZXcgRGlyZWN0aW9uYWxMaWdodChuYW1lLCBWZWN0b3IzLkJhY2t3YXJkKCksIHRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uRGlyZWN0aW9uYWxMaWdodC5wb3NpdGlvbi5zZXRBbGwoMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25MaWdodCA9IGJhYnlsb25EaXJlY3Rpb25hbExpZ2h0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBLSFJMaWdodHNQdW5jdHVhbF9MaWdodFR5cGUuUE9JTlQ6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbkxpZ2h0ID0gbmV3IFBvaW50TGlnaHQobmFtZSwgVmVjdG9yMy5aZXJvKCksIHRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBLSFJMaWdodHNQdW5jdHVhbF9MaWdodFR5cGUuU1BPVDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uU3BvdExpZ2h0ID0gbmV3IFNwb3RMaWdodChuYW1lLCBWZWN0b3IzLlplcm8oKSwgVmVjdG9yMy5CYWNrd2FyZCgpLCAwLCAxLCB0aGlzLl9sb2FkZXIuYmFieWxvblNjZW5lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvblNwb3RMaWdodC5hbmdsZSA9ICgobGlnaHQuc3BvdCAmJiBsaWdodC5zcG90Lm91dGVyQ29uZUFuZ2xlKSB8fCBNYXRoLlBJIC8gNCkgKiAyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uU3BvdExpZ2h0LmlubmVyQW5nbGUgPSAoKGxpZ2h0LnNwb3QgJiYgbGlnaHQuc3BvdC5pbm5lckNvbmVBbmdsZSkgfHwgMCkgKiAyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTGlnaHQgPSBiYWJ5bG9uU3BvdExpZ2h0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIuYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2V4dGVuc2lvbkNvbnRleHR9OiBJbnZhbGlkIGxpZ2h0IHR5cGUgKCR7bGlnaHQudHlwZX0pYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGJhYnlsb25MaWdodC5fcGFyZW50Q29udGFpbmVyID0gdGhpcy5fbG9hZGVyLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgbGlnaHQuX2JhYnlsb25MaWdodCA9IGJhYnlsb25MaWdodDtcclxuXHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTGlnaHQuZmFsbG9mZlR5cGUgPSBMaWdodC5GQUxMT0ZGX0dMVEY7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTGlnaHQuZGlmZnVzZSA9IGxpZ2h0LmNvbG9yID8gQ29sb3IzLkZyb21BcnJheShsaWdodC5jb2xvcikgOiBDb2xvcjMuV2hpdGUoKTtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25MaWdodC5pbnRlbnNpdHkgPSBsaWdodC5pbnRlbnNpdHkgPT0gdW5kZWZpbmVkID8gMSA6IGxpZ2h0LmludGVuc2l0eTtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25MaWdodC5yYW5nZSA9IGxpZ2h0LnJhbmdlID09IHVuZGVmaW5lZCA/IE51bWJlci5NQVhfVkFMVUUgOiBsaWdodC5yYW5nZTtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25MaWdodC5wYXJlbnQgPSBiYWJ5bG9uTWVzaDtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIuX2JhYnlsb25MaWdodHMucHVzaChiYWJ5bG9uTGlnaHQpO1xyXG5cclxuICAgICAgICAgICAgICAgIEdMVEZMb2FkZXIuQWRkUG9pbnRlck1ldGFkYXRhKGJhYnlsb25MaWdodCwgZXh0ZW5zaW9uQ29udGV4dCk7XHJcblxyXG4gICAgICAgICAgICAgICAgYXNzaWduKGJhYnlsb25NZXNoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl9saWdodHMobG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBQQlJNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9QQlIvcGJyTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5cclxuaW1wb3J0IHR5cGUgeyBJTWF0ZXJpYWwsIElUZXh0dXJlSW5mbyB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSUtIUk1hdGVyaWFsc0FuaXNvdHJvcHkgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWF0ZXJpYWxzX2FuaXNvdHJvcHlcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX21hdGVyaWFsc19hbmlzb3Ryb3B5IGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJLSFJfbWF0ZXJpYWxzX2FuaXNvdHJvcHlcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi90cmVlL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbWF0ZXJpYWxzX2FuaXNvdHJvcHkpXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfbWF0ZXJpYWxzX2FuaXNvdHJvcHkgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDE5NTtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUk1hdGVyaWFsc0FuaXNvdHJvcHk+KGNvbnRleHQsIG1hdGVyaWFsLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRlci5sb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCkpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRJcmlkZXNjZW5jZVByb3BlcnRpZXNBc3luYyhleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24sIGJhYnlsb25NYXRlcmlhbCkpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRJcmlkZXNjZW5jZVByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIHByb3BlcnRpZXM6IElLSFJNYXRlcmlhbHNBbmlzb3Ryb3B5LCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogTWF0ZXJpYWwgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcblxyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbmlzb3Ryb3B5LmlzRW5hYmxlZCA9IHRydWU7XHJcblxyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbmlzb3Ryb3B5LmludGVuc2l0eSA9IHByb3BlcnRpZXMuYW5pc290cm9weVN0cmVuZ3RoID8/IDA7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLmFuaXNvdHJvcHkuYW5nbGUgPSBwcm9wZXJ0aWVzLmFuaXNvdHJvcHlSb3RhdGlvbiA/PyAwO1xyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5hbmlzb3Ryb3B5VGV4dHVyZSkge1xyXG4gICAgICAgICAgICAocHJvcGVydGllcy5hbmlzb3Ryb3B5VGV4dHVyZSBhcyBJVGV4dHVyZUluZm8pLm5vbkNvbG9yRGF0YSA9IHRydWU7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vYW5pc290cm9weVRleHR1cmVgLCBwcm9wZXJ0aWVzLmFuaXNvdHJvcHlUZXh0dXJlLCAodGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoQW5pc290cm9weSBJbnRlbnNpdHkpYDtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYW5pc290cm9weS50ZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfbWF0ZXJpYWxzX2FuaXNvdHJvcHkobG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBQQlJNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9QQlIvcGJyTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5cclxuaW1wb3J0IHR5cGUgeyBJTWF0ZXJpYWwsIElUZXh0dXJlSW5mbyB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSUtIUk1hdGVyaWFsc0NsZWFyY29hdCB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl9tYXRlcmlhbHNfY2xlYXJjb2F0XCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9tYXRlcmlhbHNfY2xlYXJjb2F0IGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJLSFJfbWF0ZXJpYWxzX2NsZWFyY29hdFwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl9tYXRlcmlhbHNfY2xlYXJjb2F0L1JFQURNRS5tZClcclxuICogW1BsYXlncm91bmQgU2FtcGxlXShodHRwczovL3d3dy5iYWJ5bG9uanMtcGxheWdyb3VuZC5jb20vZnJhbWUuaHRtbCM3RjdQTjYjOClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfY2xlYXJjb2F0IGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBhIG51bWJlciB0aGF0IGRldGVybWluZXMgdGhlIG9yZGVyIHRoZSBleHRlbnNpb25zIGFyZSBhcHBsaWVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb3JkZXIgPSAxOTA7XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBOdWxsYWJsZTxQcm9taXNlPHZvaWQ+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElLSFJNYXRlcmlhbHNDbGVhcmNvYXQ+KGNvbnRleHQsIG1hdGVyaWFsLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRlci5sb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCkpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRDbGVhckNvYXRQcm9wZXJ0aWVzQXN5bmMoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkQ2xlYXJDb2F0UHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgcHJvcGVydGllczogSUtIUk1hdGVyaWFsc0NsZWFyY29hdCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IE1hdGVyaWFsIHR5cGUgbm90IHN1cHBvcnRlZGApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG5cclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuY2xlYXJDb2F0LmlzRW5hYmxlZCA9IHRydWU7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC51c2VSb3VnaG5lc3NGcm9tTWFpblRleHR1cmUgPSBmYWxzZTtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuY2xlYXJDb2F0LnJlbWFwRjBPbkludGVyZmFjZUNoYW5nZSA9IGZhbHNlO1xyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5jbGVhcmNvYXRGYWN0b3IgIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5jbGVhckNvYXQuaW50ZW5zaXR5ID0gcHJvcGVydGllcy5jbGVhcmNvYXRGYWN0b3I7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC5pbnRlbnNpdHkgPSAwO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuY2xlYXJjb2F0VGV4dHVyZSkge1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L2NsZWFyY29hdFRleHR1cmVgLCBwcm9wZXJ0aWVzLmNsZWFyY29hdFRleHR1cmUsICh0ZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dHVyZS5uYW1lID0gYCR7YmFieWxvbk1hdGVyaWFsLm5hbWV9IChDbGVhckNvYXQpYDtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuY2xlYXJDb2F0LnRleHR1cmUgPSB0ZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmNsZWFyY29hdFJvdWdobmVzc0ZhY3RvciAhPSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC5yb3VnaG5lc3MgPSBwcm9wZXJ0aWVzLmNsZWFyY29hdFJvdWdobmVzc0ZhY3RvcjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuY2xlYXJDb2F0LnJvdWdobmVzcyA9IDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5jbGVhcmNvYXRSb3VnaG5lc3NUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIChwcm9wZXJ0aWVzLmNsZWFyY29hdFJvdWdobmVzc1RleHR1cmUgYXMgSVRleHR1cmVJbmZvKS5ub25Db2xvckRhdGEgPSB0cnVlO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L2NsZWFyY29hdFJvdWdobmVzc1RleHR1cmVgLCBwcm9wZXJ0aWVzLmNsZWFyY29hdFJvdWdobmVzc1RleHR1cmUsICh0ZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dHVyZS5uYW1lID0gYCR7YmFieWxvbk1hdGVyaWFsLm5hbWV9IChDbGVhckNvYXQgUm91Z2huZXNzKWA7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC50ZXh0dXJlUm91Z2huZXNzID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5jbGVhcmNvYXROb3JtYWxUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIChwcm9wZXJ0aWVzLmNsZWFyY29hdE5vcm1hbFRleHR1cmUgYXMgSVRleHR1cmVJbmZvKS5ub25Db2xvckRhdGEgPSB0cnVlO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L2NsZWFyY29hdE5vcm1hbFRleHR1cmVgLCBwcm9wZXJ0aWVzLmNsZWFyY29hdE5vcm1hbFRleHR1cmUsICh0ZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dHVyZS5uYW1lID0gYCR7YmFieWxvbk1hdGVyaWFsLm5hbWV9IChDbGVhckNvYXQgTm9ybWFsKWA7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC5idW1wVGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmludmVydE5vcm1hbE1hcFggPSAhYmFieWxvbk1hdGVyaWFsLmdldFNjZW5lKCkudXNlUmlnaHRIYW5kZWRTeXN0ZW07XHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5pbnZlcnROb3JtYWxNYXBZID0gYmFieWxvbk1hdGVyaWFsLmdldFNjZW5lKCkudXNlUmlnaHRIYW5kZWRTeXN0ZW07XHJcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLmNsZWFyY29hdE5vcm1hbFRleHR1cmUuc2NhbGUgIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuY2xlYXJDb2F0LmJ1bXBUZXh0dXJlIS5sZXZlbCA9IHByb3BlcnRpZXMuY2xlYXJjb2F0Tm9ybWFsVGV4dHVyZS5zY2FsZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX21hdGVyaWFsc19jbGVhcmNvYXQobG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBQQlJNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9QQlIvcGJyTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IEJhc2VUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL2Jhc2VUZXh0dXJlXCI7XHJcbmltcG9ydCB0eXBlIHsgSU1hdGVyaWFsLCBJVGV4dHVyZUluZm8gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IEdMVEZMb2FkZXIgfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IElLSFJNYXRlcmlhbHNEaWZmdXNlVHJhbnNtaXNzaW9uIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyBDb2xvcjMgfSBmcm9tIFwiY29yZS9NYXRocy9tYXRoLmNvbG9yXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWF0ZXJpYWxzX2RpZmZ1c2VfdHJhbnNtaXNzaW9uXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9tYXRlcmlhbHNfZGlmZnVzZV90cmFuc21pc3Npb24gZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfZGlmZnVzZV90cmFuc21pc3Npb25cIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1Byb3Bvc2VkIFNwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9wdWxsLzE4MjUpXHJcbiAqICEhISBFeHBlcmltZW50YWwgRXh0ZW5zaW9uIFN1YmplY3QgdG8gQ2hhbmdlcyAhISFcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfZGlmZnVzZV90cmFuc21pc3Npb24gaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDE3NDtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICAgICAgaWYgKHRoaXMuZW5hYmxlZCkge1xyXG4gICAgICAgICAgICBsb2FkZXIucGFyZW50LnRyYW5zcGFyZW5jeUFzQ292ZXJhZ2UgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRlbnNpb25Bc3luYzxJS0hSTWF0ZXJpYWxzRGlmZnVzZVRyYW5zbWlzc2lvbj4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZFRyYW5zbHVjZW50UHJvcGVydGllc0FzeW5jKGV4dGVuc2lvbkNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwsIGV4dGVuc2lvbikpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRUcmFuc2x1Y2VudFByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwsIGV4dGVuc2lvbjogSUtIUk1hdGVyaWFsc0RpZmZ1c2VUcmFuc21pc3Npb24pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAoIShiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBNYXRlcmlhbCB0eXBlIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHBick1hdGVyaWFsID0gYmFieWxvbk1hdGVyaWFsIGFzIFBCUk1hdGVyaWFsO1xyXG5cclxuICAgICAgICAvLyBFbmFibGVzIFwidHJhbnNsdWNlbmN5XCIgdGV4dHVyZSB3aGljaCByZXByZXNlbnRzIGRpZmZ1c2VseS10cmFuc21pdHRlZCBsaWdodC5cclxuICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLmlzVHJhbnNsdWNlbmN5RW5hYmxlZCA9IHRydWU7XHJcblxyXG4gICAgICAgIC8vIFNpbmNlIHRoaXMgZXh0ZW5zaW9uIG1vZGVscyB0aGluLXN1cmZhY2UgdHJhbnNtaXNzaW9uIG9ubHksIHdlIG11c3QgbWFrZSB0aGVcclxuICAgICAgICAvLyBpbnRlcm5hbCBJT1IgPT0gMS4wIGFuZCBzZXQgdGhlIHRoaWNrbmVzcyB0byAwLlxyXG4gICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2Uudm9sdW1lSW5kZXhPZlJlZnJhY3Rpb24gPSAxLjA7XHJcbiAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS5taW5pbXVtVGhpY2tuZXNzID0gMC4wO1xyXG4gICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UubWF4aW11bVRoaWNrbmVzcyA9IDAuMDtcclxuXHJcbiAgICAgICAgLy8gVGludCBjb2xvciB3aWxsIGJlIHVzZWQgZm9yIHRyYW5zbWlzc2lvbi5cclxuICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLnVzZUFsYmVkb1RvVGludFRyYW5zbHVjZW5jeSA9IGZhbHNlO1xyXG5cclxuICAgICAgICBpZiAoZXh0ZW5zaW9uLmRpZmZ1c2VUcmFuc21pc3Npb25GYWN0b3IgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLnRyYW5zbHVjZW5jeUludGVuc2l0eSA9IGV4dGVuc2lvbi5kaWZmdXNlVHJhbnNtaXNzaW9uRmFjdG9yO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UudHJhbnNsdWNlbmN5SW50ZW5zaXR5ID0gMC4wO1xyXG4gICAgICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLmlzVHJhbnNsdWNlbmN5RW5hYmxlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcblxyXG4gICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UudXNlR2x0ZlN0eWxlVGV4dHVyZXMgPSB0cnVlO1xyXG5cclxuICAgICAgICBpZiAoZXh0ZW5zaW9uLmRpZmZ1c2VUcmFuc21pc3Npb25UZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIChleHRlbnNpb24uZGlmZnVzZVRyYW5zbWlzc2lvblRleHR1cmUgYXMgSVRleHR1cmVJbmZvKS5ub25Db2xvckRhdGEgPSB0cnVlO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L2RpZmZ1c2VUcmFuc21pc3Npb25UZXh0dXJlYCwgZXh0ZW5zaW9uLmRpZmZ1c2VUcmFuc21pc3Npb25UZXh0dXJlKS50aGVuKCh0ZXh0dXJlOiBCYXNlVGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoRGlmZnVzZSBUcmFuc21pc3Npb24pYDtcclxuICAgICAgICAgICAgICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLnRyYW5zbHVjZW5jeUludGVuc2l0eVRleHR1cmUgPSB0ZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChleHRlbnNpb24uZGlmZnVzZVRyYW5zbWlzc2lvbkNvbG9yRmFjdG9yICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS50cmFuc2x1Y2VuY3lDb2xvciA9IENvbG9yMy5Gcm9tQXJyYXkoZXh0ZW5zaW9uLmRpZmZ1c2VUcmFuc21pc3Npb25Db2xvckZhY3Rvcik7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS50cmFuc2x1Y2VuY3lDb2xvciA9IENvbG9yMy5XaGl0ZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGV4dGVuc2lvbi5kaWZmdXNlVHJhbnNtaXNzaW9uQ29sb3JUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vZGlmZnVzZVRyYW5zbWlzc2lvbkNvbG9yVGV4dHVyZWAsIGV4dGVuc2lvbi5kaWZmdXNlVHJhbnNtaXNzaW9uQ29sb3JUZXh0dXJlKS50aGVuKCh0ZXh0dXJlOiBCYXNlVGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoRGlmZnVzZSBUcmFuc21pc3Npb24gQ29sb3IpYDtcclxuICAgICAgICAgICAgICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLnRyYW5zbHVjZW5jeUNvbG9yVGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX21hdGVyaWFsc19kaWZmdXNlX3RyYW5zbWlzc2lvbihsb2FkZXIpKTtcclxuIiwiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXHJcbmltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBQQlJNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9QQlIvcGJyTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IElNYXRlcmlhbCB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSUtIUk1hdGVyaWFsc0Rpc3BlcnNpb24gfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWF0ZXJpYWxzX2Rpc3BlcnNpb25cIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX21hdGVyaWFsc19kaXNwZXJzaW9uIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJLSFJfbWF0ZXJpYWxzX2Rpc3BlcnNpb25cIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iLzg3YmQ2NGE3ZjVlMjNjODRiNmFlZjJlNjA4MjA2OTU4M2VkMGRkYjQvZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbWF0ZXJpYWxzX2Rpc3BlcnNpb24vUkVBRE1FLm1kKVxyXG4gKiBAZXhwZXJpbWVudGFsXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfbWF0ZXJpYWxzX2Rpc3BlcnNpb24gaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDE3NDtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUk1hdGVyaWFsc0Rpc3BlcnNpb24+KGNvbnRleHQsIG1hdGVyaWFsLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRlci5sb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCkpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWREaXNwZXJzaW9uUHJvcGVydGllc0FzeW5jKGV4dGVuc2lvbkNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwsIGV4dGVuc2lvbikpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWREaXNwZXJzaW9uUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCwgZXh0ZW5zaW9uOiBJS0hSTWF0ZXJpYWxzRGlzcGVyc2lvbik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IE1hdGVyaWFsIHR5cGUgbm90IHN1cHBvcnRlZGApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSWYgdHJhbnNwYXJlbmN5IGlzbid0IGVuYWJsZWQgYWxyZWFkeSwgdGhpcyBleHRlbnNpb24gc2hvdWxkbid0IGRvIGFueXRoaW5nLlxyXG4gICAgICAgIC8vIGkuZS4gaXQgcmVxdWlyZXMgZWl0aGVyIHRoZSBLSFJfbWF0ZXJpYWxzX3RyYW5zbWlzc2lvbiBvciBLSFJfbWF0ZXJpYWxzX2RpZmZ1c2VfdHJhbnNtaXNzaW9uIGV4dGVuc2lvbnMuXHJcbiAgICAgICAgaWYgKCFiYWJ5bG9uTWF0ZXJpYWwuc3ViU3VyZmFjZS5pc1JlZnJhY3Rpb25FbmFibGVkIHx8ICFleHRlbnNpb24uZGlzcGVyc2lvbikge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5zdWJTdXJmYWNlLmlzRGlzcGVyc2lvbkVuYWJsZWQgPSB0cnVlO1xyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5zdWJTdXJmYWNlLmRpc3BlcnNpb24gPSBleHRlbnNpb24uZGlzcGVyc2lvbjtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl9tYXRlcmlhbHNfZGlzcGVyc2lvbihsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IElNYXRlcmlhbCB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSUtIUk1hdGVyaWFsc0VtaXNzaXZlU3RyZW5ndGggfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWF0ZXJpYWxzX2VtaXNzaXZlX3N0cmVuZ3RoXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9tYXRlcmlhbHNfZW1pc3NpdmVfc3RyZW5ndGggZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfZW1pc3NpdmVfc3RyZW5ndGhcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbWF0ZXJpYWxzX2VtaXNzaXZlX3N0cmVuZ3RoL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfZW1pc3NpdmVfc3RyZW5ndGggaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDE3MDtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUk1hdGVyaWFsc0VtaXNzaXZlU3RyZW5ndGg+KGNvbnRleHQsIG1hdGVyaWFsLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRlci5sb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkRW1pc3NpdmVQcm9wZXJ0aWVzKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbiwgYmFieWxvbk1hdGVyaWFsKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZEVtaXNzaXZlUHJvcGVydGllcyhjb250ZXh0OiBzdHJpbmcsIHByb3BlcnRpZXM6IElLSFJNYXRlcmlhbHNFbWlzc2l2ZVN0cmVuZ3RoLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogTWF0ZXJpYWwgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5lbWlzc2l2ZVN0cmVuZ3RoICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmVtaXNzaXZlSW50ZW5zaXR5ID0gcHJvcGVydGllcy5lbWlzc2l2ZVN0cmVuZ3RoO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX21hdGVyaWFsc19lbWlzc2l2ZV9zdHJlbmd0aChsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IElNYXRlcmlhbCB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSUtIUk1hdGVyaWFsc0lvciB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl9tYXRlcmlhbHNfaW9yXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9tYXRlcmlhbHNfaW9yIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJLSFJfbWF0ZXJpYWxzX2lvclwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl9tYXRlcmlhbHNfaW9yL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfaW9yIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZhdWx0IGlvciBWYWx1ZSBmcm9tIHRoZSBzcGVjLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBfREVGQVVMVF9JT1IgPSAxLjU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBhIG51bWJlciB0aGF0IGRldGVybWluZXMgdGhlIG9yZGVyIHRoZSBleHRlbnNpb25zIGFyZSBhcHBsaWVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb3JkZXIgPSAxODA7XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBOdWxsYWJsZTxQcm9taXNlPHZvaWQ+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElLSFJNYXRlcmlhbHNJb3I+KGNvbnRleHQsIG1hdGVyaWFsLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRlci5sb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCkpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRJb3JQcm9wZXJ0aWVzQXN5bmMoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkSW9yUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgcHJvcGVydGllczogSUtIUk1hdGVyaWFsc0lvciwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IE1hdGVyaWFsIHR5cGUgbm90IHN1cHBvcnRlZGApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuaW9yICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmluZGV4T2ZSZWZyYWN0aW9uID0gcHJvcGVydGllcy5pb3I7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmluZGV4T2ZSZWZyYWN0aW9uID0gS0hSX21hdGVyaWFsc19pb3IuX0RFRkFVTFRfSU9SO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfbWF0ZXJpYWxzX2lvcihsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IElNYXRlcmlhbCB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSUtIUk1hdGVyaWFsc0lyaWRlc2NlbmNlIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc19pcmlkZXNjZW5jZVwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfbWF0ZXJpYWxzX2lyaWRlc2NlbmNlIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJLSFJfbWF0ZXJpYWxzX2lyaWRlc2NlbmNlXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0tocm9ub3MvS0hSX21hdGVyaWFsc19pcmlkZXNjZW5jZS9SRUFETUUubWQpXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfbWF0ZXJpYWxzX2lyaWRlc2NlbmNlIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBhIG51bWJlciB0aGF0IGRldGVybWluZXMgdGhlIG9yZGVyIHRoZSBleHRlbnNpb25zIGFyZSBhcHBsaWVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb3JkZXIgPSAxOTU7XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBOdWxsYWJsZTxQcm9taXNlPHZvaWQ+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElLSFJNYXRlcmlhbHNJcmlkZXNjZW5jZT4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZElyaWRlc2NlbmNlUHJvcGVydGllc0FzeW5jKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbiwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZElyaWRlc2NlbmNlUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgcHJvcGVydGllczogSUtIUk1hdGVyaWFsc0lyaWRlc2NlbmNlLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogTWF0ZXJpYWwgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcblxyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5pcmlkZXNjZW5jZS5pc0VuYWJsZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuaXJpZGVzY2VuY2UuaW50ZW5zaXR5ID0gcHJvcGVydGllcy5pcmlkZXNjZW5jZUZhY3RvciA/PyAwO1xyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5pcmlkZXNjZW5jZS5pbmRleE9mUmVmcmFjdGlvbiA9IHByb3BlcnRpZXMuaXJpZGVzY2VuY2VJb3IgPz8gKHByb3BlcnRpZXMgYXMgYW55KS5pcmlkZXNjZW5jZUlPUiA/PyAxLjM7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLmlyaWRlc2NlbmNlLm1pbmltdW1UaGlja25lc3MgPSBwcm9wZXJ0aWVzLmlyaWRlc2NlbmNlVGhpY2tuZXNzTWluaW11bSA/PyAxMDA7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLmlyaWRlc2NlbmNlLm1heGltdW1UaGlja25lc3MgPSBwcm9wZXJ0aWVzLmlyaWRlc2NlbmNlVGhpY2tuZXNzTWF4aW11bSA/PyA0MDA7XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmlyaWRlc2NlbmNlVGV4dHVyZSkge1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L2lyaWRlc2NlbmNlVGV4dHVyZWAsIHByb3BlcnRpZXMuaXJpZGVzY2VuY2VUZXh0dXJlLCAodGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoSXJpZGVzY2VuY2UpYDtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuaXJpZGVzY2VuY2UudGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuaXJpZGVzY2VuY2VUaGlja25lc3NUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vaXJpZGVzY2VuY2VUaGlja25lc3NUZXh0dXJlYCwgcHJvcGVydGllcy5pcmlkZXNjZW5jZVRoaWNrbmVzc1RleHR1cmUsICh0ZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dHVyZS5uYW1lID0gYCR7YmFieWxvbk1hdGVyaWFsLm5hbWV9IChJcmlkZXNjZW5jZSBUaGlja25lc3MpYDtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuaXJpZGVzY2VuY2UudGhpY2tuZXNzVGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX21hdGVyaWFsc19pcmlkZXNjZW5jZShsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IENvbG9yMyB9IGZyb20gXCJjb3JlL01hdGhzL21hdGguY29sb3JcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSU1hdGVyaWFsIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSTWF0ZXJpYWxzUGJyU3BlY3VsYXJHbG9zc2luZXNzIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc19wYnJTcGVjdWxhckdsb3NzaW5lc3NcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX21hdGVyaWFsc19wYnJTcGVjdWxhckdsb3NzaW5lc3MgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfcGJyU3BlY3VsYXJHbG9zc2luZXNzXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0FyY2hpdmVkL0tIUl9tYXRlcmlhbHNfcGJyU3BlY3VsYXJHbG9zc2luZXNzL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfcGJyU3BlY3VsYXJHbG9zc2luZXNzIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBhIG51bWJlciB0aGF0IGRldGVybWluZXMgdGhlIG9yZGVyIHRoZSBleHRlbnNpb25zIGFyZSBhcHBsaWVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb3JkZXIgPSAyMDA7XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBOdWxsYWJsZTxQcm9taXNlPHZvaWQ+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElLSFJNYXRlcmlhbHNQYnJTcGVjdWxhckdsb3NzaW5lc3M+KGNvbnRleHQsIG1hdGVyaWFsLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRlci5sb2FkTWF0ZXJpYWxCYXNlUHJvcGVydGllc0FzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkU3BlY3VsYXJHbG9zc2luZXNzUHJvcGVydGllc0FzeW5jKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbiwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2FkTWF0ZXJpYWxBbHBoYVByb3BlcnRpZXMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZFNwZWN1bGFyR2xvc3NpbmVzc1Byb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIHByb3BlcnRpZXM6IElLSFJNYXRlcmlhbHNQYnJTcGVjdWxhckdsb3NzaW5lc3MsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAoIShiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBNYXRlcmlhbCB0eXBlIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuXHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLm1ldGFsbGljID0gbnVsbDtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwucm91Z2huZXNzID0gbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuZGlmZnVzZUZhY3Rvcikge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvQ29sb3IgPSBDb2xvcjMuRnJvbUFycmF5KHByb3BlcnRpZXMuZGlmZnVzZUZhY3Rvcik7XHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbHBoYSA9IHByb3BlcnRpZXMuZGlmZnVzZUZhY3RvclszXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvQ29sb3IgPSBDb2xvcjMuV2hpdGUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5yZWZsZWN0aXZpdHlDb2xvciA9IHByb3BlcnRpZXMuc3BlY3VsYXJGYWN0b3IgPyBDb2xvcjMuRnJvbUFycmF5KHByb3BlcnRpZXMuc3BlY3VsYXJGYWN0b3IpIDogQ29sb3IzLldoaXRlKCk7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLm1pY3JvU3VyZmFjZSA9IHByb3BlcnRpZXMuZ2xvc3NpbmVzc0ZhY3RvciA9PSB1bmRlZmluZWQgPyAxIDogcHJvcGVydGllcy5nbG9zc2luZXNzRmFjdG9yO1xyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5kaWZmdXNlVGV4dHVyZSkge1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L2RpZmZ1c2VUZXh0dXJlYCwgcHJvcGVydGllcy5kaWZmdXNlVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKERpZmZ1c2UpYDtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvVGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuc3BlY3VsYXJHbG9zc2luZXNzVGV4dHVyZSkge1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L3NwZWN1bGFyR2xvc3NpbmVzc1RleHR1cmVgLCBwcm9wZXJ0aWVzLnNwZWN1bGFyR2xvc3NpbmVzc1RleHR1cmUsICh0ZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dHVyZS5uYW1lID0gYCR7YmFieWxvbk1hdGVyaWFsLm5hbWV9IChTcGVjdWxhciBHbG9zc2luZXNzKWA7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnJlZmxlY3Rpdml0eVRleHR1cmUgPSB0ZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5yZWZsZWN0aXZpdHlUZXh0dXJlLmhhc0FscGhhID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwudXNlTWljcm9TdXJmYWNlRnJvbVJlZmxlY3Rpdml0eU1hcEFscGhhID0gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl9tYXRlcmlhbHNfcGJyU3BlY3VsYXJHbG9zc2luZXNzKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSU1hdGVyaWFsLCBJVGV4dHVyZUluZm8gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IEdMVEZMb2FkZXIgfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgeyBDb2xvcjMgfSBmcm9tIFwiY29yZS9NYXRocy9tYXRoLmNvbG9yXCI7XHJcbmltcG9ydCB0eXBlIHsgSUtIUk1hdGVyaWFsc1NoZWVuIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc19zaGVlblwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfbWF0ZXJpYWxzX3NoZWVuIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJLSFJfbWF0ZXJpYWxzX3NoZWVuXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0tocm9ub3MvS0hSX21hdGVyaWFsc19zaGVlbi9SRUFETUUubWQpXHJcbiAqIFtQbGF5Z3JvdW5kIFNhbXBsZV0oaHR0cHM6Ly93d3cuYmFieWxvbmpzLXBsYXlncm91bmQuY29tL2ZyYW1lLmh0bWwjQk5JWlg2IzQpXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfbWF0ZXJpYWxzX3NoZWVuIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBhIG51bWJlciB0aGF0IGRldGVybWluZXMgdGhlIG9yZGVyIHRoZSBleHRlbnNpb25zIGFyZSBhcHBsaWVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb3JkZXIgPSAxOTA7XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBOdWxsYWJsZTxQcm9taXNlPHZvaWQ+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElLSFJNYXRlcmlhbHNTaGVlbj4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZFNoZWVuUHJvcGVydGllc0FzeW5jKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbiwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZFNoZWVuUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgcHJvcGVydGllczogSUtIUk1hdGVyaWFsc1NoZWVuLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogTWF0ZXJpYWwgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcblxyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5zaGVlbi5pc0VuYWJsZWQgPSB0cnVlO1xyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5zaGVlbi5pbnRlbnNpdHkgPSAxO1xyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5zaGVlbkNvbG9yRmFjdG9yICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuc2hlZW4uY29sb3IgPSBDb2xvcjMuRnJvbUFycmF5KHByb3BlcnRpZXMuc2hlZW5Db2xvckZhY3Rvcik7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnNoZWVuLmNvbG9yID0gQ29sb3IzLkJsYWNrKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5zaGVlbkNvbG9yVGV4dHVyZSkge1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L3NoZWVuQ29sb3JUZXh0dXJlYCwgcHJvcGVydGllcy5zaGVlbkNvbG9yVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKFNoZWVuIENvbG9yKWA7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnNoZWVuLnRleHR1cmUgPSB0ZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLnNoZWVuUm91Z2huZXNzRmFjdG9yICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnNoZWVuLnJvdWdobmVzcyA9IHByb3BlcnRpZXMuc2hlZW5Sb3VnaG5lc3NGYWN0b3I7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnNoZWVuLnJvdWdobmVzcyA9IDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5zaGVlblJvdWdobmVzc1RleHR1cmUpIHtcclxuICAgICAgICAgICAgKHByb3BlcnRpZXMuc2hlZW5Sb3VnaG5lc3NUZXh0dXJlIGFzIElUZXh0dXJlSW5mbykubm9uQ29sb3JEYXRhID0gdHJ1ZTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2FkVGV4dHVyZUluZm9Bc3luYyhgJHtjb250ZXh0fS9zaGVlblJvdWdobmVzc1RleHR1cmVgLCBwcm9wZXJ0aWVzLnNoZWVuUm91Z2huZXNzVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKFNoZWVuIFJvdWdobmVzcylgO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5zaGVlbi50ZXh0dXJlUm91Z2huZXNzID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuc2hlZW4uYWxiZWRvU2NhbGluZyA9IHRydWU7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnNoZWVuLnVzZVJvdWdobmVzc0Zyb21NYWluVGV4dHVyZSA9IGZhbHNlO1xyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfbWF0ZXJpYWxzX3NoZWVuKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSU1hdGVyaWFsLCBJVGV4dHVyZUluZm8gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IEdMVEZMb2FkZXIgfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgeyBDb2xvcjMgfSBmcm9tIFwiY29yZS9NYXRocy9tYXRoLmNvbG9yXCI7XHJcbmltcG9ydCB0eXBlIHsgSUtIUk1hdGVyaWFsc1NwZWN1bGFyIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc19zcGVjdWxhclwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfbWF0ZXJpYWxzX3NwZWN1bGFyIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJLSFJfbWF0ZXJpYWxzX3NwZWN1bGFyXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0tocm9ub3MvS0hSX21hdGVyaWFsc19zcGVjdWxhci9SRUFETUUubWQpXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfbWF0ZXJpYWxzX3NwZWN1bGFyIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBhIG51bWJlciB0aGF0IGRldGVybWluZXMgdGhlIG9yZGVyIHRoZSBleHRlbnNpb25zIGFyZSBhcHBsaWVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb3JkZXIgPSAxOTA7XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBOdWxsYWJsZTxQcm9taXNlPHZvaWQ+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElLSFJNYXRlcmlhbHNTcGVjdWxhcj4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZFNwZWN1bGFyUHJvcGVydGllc0FzeW5jKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbiwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZFNwZWN1bGFyUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgcHJvcGVydGllczogSUtIUk1hdGVyaWFsc1NwZWN1bGFyLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogTWF0ZXJpYWwgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLnNwZWN1bGFyRmFjdG9yICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLm1ldGFsbGljRjBGYWN0b3IgPSBwcm9wZXJ0aWVzLnNwZWN1bGFyRmFjdG9yO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuc3BlY3VsYXJDb2xvckZhY3RvciAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5tZXRhbGxpY1JlZmxlY3RhbmNlQ29sb3IgPSBDb2xvcjMuRnJvbUFycmF5KHByb3BlcnRpZXMuc3BlY3VsYXJDb2xvckZhY3Rvcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5zcGVjdWxhclRleHR1cmUpIHtcclxuICAgICAgICAgICAgKHByb3BlcnRpZXMuc3BlY3VsYXJUZXh0dXJlIGFzIElUZXh0dXJlSW5mbykubm9uQ29sb3JEYXRhID0gdHJ1ZTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2FkVGV4dHVyZUluZm9Bc3luYyhgJHtjb250ZXh0fS9zcGVjdWxhclRleHR1cmVgLCBwcm9wZXJ0aWVzLnNwZWN1bGFyVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKFNwZWN1bGFyKWA7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLm1ldGFsbGljUmVmbGVjdGFuY2VUZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwudXNlT25seU1ldGFsbGljRnJvbU1ldGFsbGljUmVmbGVjdGFuY2VUZXh0dXJlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5zcGVjdWxhckNvbG9yVGV4dHVyZSkge1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L3NwZWN1bGFyQ29sb3JUZXh0dXJlYCwgcHJvcGVydGllcy5zcGVjdWxhckNvbG9yVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKFNwZWN1bGFyIENvbG9yKWA7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnJlZmxlY3RhbmNlVGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX21hdGVyaWFsc19zcGVjdWxhcihsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgQmFzZVRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvYmFzZVRleHR1cmVcIjtcclxuaW1wb3J0IHR5cGUgeyBJTWF0ZXJpYWwsIElUZXh0dXJlSW5mbyB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSUtIUk1hdGVyaWFsc1RyYW5zbWlzc2lvbiB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHR5cGUgeyBTY2VuZSB9IGZyb20gXCJjb3JlL3NjZW5lXCI7XHJcbmltcG9ydCB0eXBlIHsgQWJzdHJhY3RNZXNoIH0gZnJvbSBcImNvcmUvTWVzaGVzL2Fic3RyYWN0TWVzaFwiO1xyXG5pbXBvcnQgdHlwZSB7IFRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvdGV4dHVyZVwiO1xyXG5pbXBvcnQgeyBSZW5kZXJUYXJnZXRUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL3JlbmRlclRhcmdldFRleHR1cmVcIjtcclxuaW1wb3J0IHR5cGUgeyBPYnNlcnZlciB9IGZyb20gXCJjb3JlL01pc2Mvb2JzZXJ2YWJsZVwiO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSBcImNvcmUvTWlzYy9vYnNlcnZhYmxlXCI7XHJcbmltcG9ydCB7IENvbnN0YW50cyB9IGZyb20gXCJjb3JlL0VuZ2luZXMvY29uc3RhbnRzXCI7XHJcbmltcG9ydCB7IFRvb2xzIH0gZnJvbSBcImNvcmUvTWlzYy90b29sc1wiO1xyXG5pbXBvcnQgdHlwZSB7IENvbG9yNCB9IGZyb20gXCJjb3JlL01hdGhzL21hdGguY29sb3JcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmludGVyZmFjZSBJVHJhbnNtaXNzaW9uSGVscGVySG9sZGVyIHtcclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIF90cmFuc21pc3Npb25IZWxwZXI6IFRyYW5zbWlzc2lvbkhlbHBlciB8IHVuZGVmaW5lZDtcclxufVxyXG5cclxuaW50ZXJmYWNlIElUcmFuc21pc3Npb25IZWxwZXJPcHRpb25zIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIHNpemUgb2YgdGhlIHJlbmRlciBidWZmZXJzIChkZWZhdWx0OiAxMDI0KVxyXG4gICAgICovXHJcbiAgICByZW5kZXJTaXplOiBudW1iZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbnVtYmVyIG9mIHNhbXBsZXMgdG8gdXNlIHdoZW4gZ2VuZXJhdGluZyB0aGUgcmVuZGVyIHRhcmdldCB0ZXh0dXJlIGZvciBvcGFxdWUgbWVzaGVzIChkZWZhdWx0OiA0KVxyXG4gICAgICovXHJcbiAgICBzYW1wbGVzOiBudW1iZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTY2FsZSB0byBhcHBseSB3aGVuIHNlbGVjdGluZyB0aGUgTE9EIGxldmVsIHRvIHNhbXBsZSB0aGUgcmVmcmFjdGlvbiB0ZXh0dXJlIChkZWZhdWx0OiAxKVxyXG4gICAgICovXHJcbiAgICBsb2RHZW5lcmF0aW9uU2NhbGU6IG51bWJlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE9mZnNldCB0byBhcHBseSB3aGVuIHNlbGVjdGluZyB0aGUgTE9EIGxldmVsIHRvIHNhbXBsZSB0aGUgcmVmcmFjdGlvbiB0ZXh0dXJlIChkZWZhdWx0OiAtNClcclxuICAgICAqL1xyXG4gICAgbG9kR2VuZXJhdGlvbk9mZnNldDogbnVtYmVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVHlwZSBvZiB0aGUgcmVmcmFjdGlvbiByZW5kZXIgdGFyZ2V0IHRleHR1cmUgKGRlZmF1bHQ6IFRFWFRVUkVUWVBFX0hBTEZfRkxPQVQpXHJcbiAgICAgKi9cclxuICAgIHJlbmRlclRhcmdldFRleHR1cmVUeXBlOiBudW1iZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGlmIHRoZSBtaXBtYXBzIGZvciB0aGUgcmVmcmFjdGlvbiByZW5kZXIgdGFyZ2V0IHRleHR1cmUgbXVzdCBiZSBnZW5lcmF0ZWQgKGRlZmF1bHQ6IHRydWUpXHJcbiAgICAgKi9cclxuICAgIGdlbmVyYXRlTWlwbWFwczogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENsZWFyIGNvbG9yIG9mIHRoZSBvcGFxdWUgdGV4dHVyZS4gSWYgbm90IHByb3ZpZGVkLCB1c2UgdGhlIHNjZW5lIGNsZWFyIGNvbG9yICh3aGljaCB3aWxsIGJlIGNvbnZlcnRlZCB0byBsaW5lYXIgc3BhY2UpLlxyXG4gICAgICogSWYgcHJvdmlkZWQsIHNob3VsZCBiZSBpbiBsaW5lYXIgc3BhY2VcclxuICAgICAqL1xyXG4gICAgY2xlYXJDb2xvcj86IENvbG9yNDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEEgY2xhc3MgdG8gaGFuZGxlIHNldHRpbmcgdXAgdGhlIHJlbmRlcmluZyBvZiBvcGFxdWUgb2JqZWN0cyB0byBiZSBzaG93biB0aHJvdWdoIHRyYW5zbWlzc2l2ZSBvYmplY3RzLlxyXG4gKi9cclxuY2xhc3MgVHJhbnNtaXNzaW9uSGVscGVyIHtcclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyB0aGUgZGVmYXVsdCBvcHRpb25zIGZvciB0aGUgaGVscGVyLlxyXG4gICAgICogQHJldHVybnMgdGhlIGRlZmF1bHQgb3B0aW9uc1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfR2V0RGVmYXVsdE9wdGlvbnMoKTogSVRyYW5zbWlzc2lvbkhlbHBlck9wdGlvbnMge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHJlbmRlclNpemU6IDEwMjQsXHJcbiAgICAgICAgICAgIHNhbXBsZXM6IDQsXHJcbiAgICAgICAgICAgIGxvZEdlbmVyYXRpb25TY2FsZTogMSxcclxuICAgICAgICAgICAgbG9kR2VuZXJhdGlvbk9mZnNldDogLTQsXHJcbiAgICAgICAgICAgIHJlbmRlclRhcmdldFRleHR1cmVUeXBlOiBDb25zdGFudHMuVEVYVFVSRVRZUEVfSEFMRl9GTE9BVCxcclxuICAgICAgICAgICAgZ2VuZXJhdGVNaXBtYXBzOiB0cnVlLFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTdG9yZXMgdGhlIGNyZWF0aW9uIG9wdGlvbnMuXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgcmVhZG9ubHkgX3NjZW5lOiBTY2VuZSAmIElUcmFuc21pc3Npb25IZWxwZXJIb2xkZXI7XHJcblxyXG4gICAgcHJpdmF0ZSBfb3B0aW9uczogSVRyYW5zbWlzc2lvbkhlbHBlck9wdGlvbnM7XHJcblxyXG4gICAgcHJpdmF0ZSBfb3BhcXVlUmVuZGVyVGFyZ2V0OiBOdWxsYWJsZTxSZW5kZXJUYXJnZXRUZXh0dXJlPiA9IG51bGw7XHJcbiAgICBwcml2YXRlIF9vcGFxdWVNZXNoZXNDYWNoZTogQWJzdHJhY3RNZXNoW10gPSBbXTtcclxuICAgIHByaXZhdGUgX3RyYW5zcGFyZW50TWVzaGVzQ2FjaGU6IEFic3RyYWN0TWVzaFtdID0gW107XHJcbiAgICBwcml2YXRlIF9tYXRlcmlhbE9ic2VydmVyczogeyBbaWQ6IHN0cmluZ106IE51bGxhYmxlPE9ic2VydmVyPEFic3RyYWN0TWVzaD4+IH0gPSB7fTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoaXMgb2JzZXJ2YWJsZSB3aWxsIGJlIG5vdGlmaWVkIHdpdGggYW55IGVycm9yIGR1cmluZyB0aGUgY3JlYXRpb24gb2YgdGhlIGVudmlyb25tZW50LFxyXG4gICAgICogbWFpbmx5IHRleHR1cmUgY3JlYXRpb24gZXJyb3JzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25FcnJvck9ic2VydmFibGU6IE9ic2VydmFibGU8eyBtZXNzYWdlPzogc3RyaW5nOyBleGNlcHRpb24/OiBhbnkgfT47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIG9wdGlvbnMgRGVmaW5lcyB0aGUgb3B0aW9ucyB3ZSB3YW50IHRvIGN1c3RvbWl6ZSB0aGUgaGVscGVyXHJcbiAgICAgKiBAcGFyYW0gc2NlbmUgVGhlIHNjZW5lIHRvIGFkZCB0aGUgbWF0ZXJpYWwgdG9cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogUGFydGlhbDxJVHJhbnNtaXNzaW9uSGVscGVyT3B0aW9ucz4sIHNjZW5lOiBTY2VuZSkge1xyXG4gICAgICAgIHRoaXMuX29wdGlvbnMgPSB7XHJcbiAgICAgICAgICAgIC4uLlRyYW5zbWlzc2lvbkhlbHBlci5fR2V0RGVmYXVsdE9wdGlvbnMoKSxcclxuICAgICAgICAgICAgLi4ub3B0aW9ucyxcclxuICAgICAgICB9O1xyXG4gICAgICAgIHRoaXMuX3NjZW5lID0gc2NlbmUgYXMgYW55O1xyXG4gICAgICAgIHRoaXMuX3NjZW5lLl90cmFuc21pc3Npb25IZWxwZXIgPSB0aGlzO1xyXG5cclxuICAgICAgICB0aGlzLm9uRXJyb3JPYnNlcnZhYmxlID0gbmV3IE9ic2VydmFibGUoKTtcclxuICAgICAgICB0aGlzLl9zY2VuZS5vbkRpc3Bvc2VPYnNlcnZhYmxlLmFkZE9uY2UoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmRpc3Bvc2UoKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5fcGFyc2VTY2VuZSgpO1xyXG4gICAgICAgIHRoaXMuX3NldHVwUmVuZGVyVGFyZ2V0cygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVXBkYXRlcyB0aGUgYmFja2dyb3VuZCBhY2NvcmRpbmcgdG8gdGhlIG5ldyBvcHRpb25zXHJcbiAgICAgKiBAcGFyYW0gb3B0aW9uc1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdXBkYXRlT3B0aW9ucyhvcHRpb25zOiBQYXJ0aWFsPElUcmFuc21pc3Npb25IZWxwZXJPcHRpb25zPikge1xyXG4gICAgICAgIC8vIEZpcnN0IGNoZWNrIGlmIGFueSBvcHRpb25zIGFyZSBhY3R1YWxseSBiZWluZyBjaGFuZ2VkLiBJZiBub3QsIGV4aXQuXHJcbiAgICAgICAgY29uc3QgbmV3VmFsdWVzID0gT2JqZWN0LmtleXMob3B0aW9ucykuZmlsdGVyKChrZXk6IHN0cmluZykgPT4gKHRoaXMuX29wdGlvbnMgYXMgYW55KVtrZXldICE9PSAob3B0aW9ucyBhcyBhbnkpW2tleV0pO1xyXG4gICAgICAgIGlmICghbmV3VmFsdWVzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBuZXdPcHRpb25zID0ge1xyXG4gICAgICAgICAgICAuLi50aGlzLl9vcHRpb25zLFxyXG4gICAgICAgICAgICAuLi5vcHRpb25zLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGNvbnN0IG9sZE9wdGlvbnMgPSB0aGlzLl9vcHRpb25zO1xyXG4gICAgICAgIHRoaXMuX29wdGlvbnMgPSBuZXdPcHRpb25zO1xyXG5cclxuICAgICAgICAvLyBJZiBzaXplIGNoYW5nZXMsIHJlY3JlYXRlIGV2ZXJ5dGhpbmdcclxuICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgIG5ld09wdGlvbnMucmVuZGVyU2l6ZSAhPT0gb2xkT3B0aW9ucy5yZW5kZXJTaXplIHx8XHJcbiAgICAgICAgICAgIG5ld09wdGlvbnMucmVuZGVyVGFyZ2V0VGV4dHVyZVR5cGUgIT09IG9sZE9wdGlvbnMucmVuZGVyVGFyZ2V0VGV4dHVyZVR5cGUgfHxcclxuICAgICAgICAgICAgbmV3T3B0aW9ucy5nZW5lcmF0ZU1pcG1hcHMgIT09IG9sZE9wdGlvbnMuZ2VuZXJhdGVNaXBtYXBzIHx8XHJcbiAgICAgICAgICAgICF0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXRcclxuICAgICAgICApIHtcclxuICAgICAgICAgICAgdGhpcy5fc2V0dXBSZW5kZXJUYXJnZXRzKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0LnNhbXBsZXMgPSBuZXdPcHRpb25zLnNhbXBsZXM7XHJcbiAgICAgICAgICAgIHRoaXMuX29wYXF1ZVJlbmRlclRhcmdldC5sb2RHZW5lcmF0aW9uU2NhbGUgPSBuZXdPcHRpb25zLmxvZEdlbmVyYXRpb25TY2FsZTtcclxuICAgICAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0LmxvZEdlbmVyYXRpb25PZmZzZXQgPSBuZXdPcHRpb25zLmxvZEdlbmVyYXRpb25PZmZzZXQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHJldHVybnMgdGhlIG9wYXF1ZSByZW5kZXIgdGFyZ2V0IHRleHR1cmUgb3IgbnVsbCBpZiBub3QgYXZhaWxhYmxlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0T3BhcXVlVGFyZ2V0KCk6IE51bGxhYmxlPFRleHR1cmU+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3Nob3VsZFJlbmRlckFzVHJhbnNtaXNzaW9uKG1hdGVyaWFsOiBOdWxsYWJsZTxNYXRlcmlhbD4pOiBib29sZWFuIHtcclxuICAgICAgICBpZiAoIW1hdGVyaWFsKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKG1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwgJiYgbWF0ZXJpYWwuc3ViU3VyZmFjZS5pc1JlZnJhY3Rpb25FbmFibGVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfYWRkTWVzaChtZXNoOiBBYnN0cmFjdE1lc2gpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9tYXRlcmlhbE9ic2VydmVyc1ttZXNoLnVuaXF1ZUlkXSA9IG1lc2gub25NYXRlcmlhbENoYW5nZWRPYnNlcnZhYmxlLmFkZCh0aGlzLl9vbk1lc2hNYXRlcmlhbENoYW5nZWQuYmluZCh0aGlzKSk7XHJcblxyXG4gICAgICAgIC8vIHdlIG5lZWQgdG8gZGVmZXIgdGhlIHByb2Nlc3NpbmcgYmVjYXVzZSBfYWRkTWVzaCBtYXkgYmUgY2FsbGVkIGFzIHBhcnQgYXMgYW4gaW5zdGFuY2UgbWVzaCBjcmVhdGlvbiwgaW4gd2hpY2ggY2FzZSBzb21lXHJcbiAgICAgICAgLy8gaW50ZXJuYWwgcHJvcGVydGllcyBhcmUgbm90IHNldHVwIHlldCwgbGlrZSBfc291cmNlTWVzaCAobmVlZGVkIHdoZW4gZG9pbmcgbWVzaC5tYXRlcmlhbCBiZWxvdylcclxuICAgICAgICBUb29scy5TZXRJbW1lZGlhdGUoKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fc2hvdWxkUmVuZGVyQXNUcmFuc21pc3Npb24obWVzaC5tYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgICAgIChtZXNoLm1hdGVyaWFsIGFzIFBCUk1hdGVyaWFsKS5yZWZyYWN0aW9uVGV4dHVyZSA9IHRoaXMuX29wYXF1ZVJlbmRlclRhcmdldDtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl90cmFuc3BhcmVudE1lc2hlc0NhY2hlLmluZGV4T2YobWVzaCkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdHJhbnNwYXJlbnRNZXNoZXNDYWNoZS5wdXNoKG1lc2gpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX29wYXF1ZU1lc2hlc0NhY2hlLmluZGV4T2YobWVzaCkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb3BhcXVlTWVzaGVzQ2FjaGUucHVzaChtZXNoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3JlbW92ZU1lc2gobWVzaDogQWJzdHJhY3RNZXNoKTogdm9pZCB7XHJcbiAgICAgICAgbWVzaC5vbk1hdGVyaWFsQ2hhbmdlZE9ic2VydmFibGUucmVtb3ZlKHRoaXMuX21hdGVyaWFsT2JzZXJ2ZXJzW21lc2gudW5pcXVlSWRdKTtcclxuICAgICAgICBkZWxldGUgdGhpcy5fbWF0ZXJpYWxPYnNlcnZlcnNbbWVzaC51bmlxdWVJZF07XHJcbiAgICAgICAgbGV0IGlkeCA9IHRoaXMuX3RyYW5zcGFyZW50TWVzaGVzQ2FjaGUuaW5kZXhPZihtZXNoKTtcclxuICAgICAgICBpZiAoaWR4ICE9PSAtMSkge1xyXG4gICAgICAgICAgICB0aGlzLl90cmFuc3BhcmVudE1lc2hlc0NhY2hlLnNwbGljZShpZHgsIDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZHggPSB0aGlzLl9vcGFxdWVNZXNoZXNDYWNoZS5pbmRleE9mKG1lc2gpO1xyXG4gICAgICAgIGlmIChpZHggIT09IC0xKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX29wYXF1ZU1lc2hlc0NhY2hlLnNwbGljZShpZHgsIDEpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9wYXJzZVNjZW5lKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX3NjZW5lLm1lc2hlcy5mb3JFYWNoKHRoaXMuX2FkZE1lc2guYmluZCh0aGlzKSk7XHJcbiAgICAgICAgLy8gTGlzdGVuIGZvciB3aGVuIGEgbWVzaCBpcyBhZGRlZCB0byB0aGUgc2NlbmUgYW5kIGFkZCBpdCB0byBvdXIgY2FjaGUgbGlzdHMuXHJcbiAgICAgICAgdGhpcy5fc2NlbmUub25OZXdNZXNoQWRkZWRPYnNlcnZhYmxlLmFkZCh0aGlzLl9hZGRNZXNoLmJpbmQodGhpcykpO1xyXG4gICAgICAgIC8vIExpc3RlbiBmb3Igd2hlbiBhIG1lc2ggaXMgcmVtb3ZlZCBmcm9tIHRvIHRoZSBzY2VuZSBhbmQgcmVtb3ZlIGl0IGZyb20gb3VyIGNhY2hlIGxpc3RzLlxyXG4gICAgICAgIHRoaXMuX3NjZW5lLm9uTWVzaFJlbW92ZWRPYnNlcnZhYmxlLmFkZCh0aGlzLl9yZW1vdmVNZXNoLmJpbmQodGhpcykpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFdoZW4gb25lIG9mIHRoZSBtZXNoZXMgaW4gdGhlIHNjZW5lIGhhcyBpdHMgbWF0ZXJpYWwgY2hhbmdlZCwgbWFrZSBzdXJlIHRoYXQgaXQncyBpbiB0aGUgY29ycmVjdCBjYWNoZSBsaXN0LlxyXG4gICAgcHJpdmF0ZSBfb25NZXNoTWF0ZXJpYWxDaGFuZ2VkKG1lc2g6IEFic3RyYWN0TWVzaCkge1xyXG4gICAgICAgIGNvbnN0IHRyYW5zcGFyZW50SWR4ID0gdGhpcy5fdHJhbnNwYXJlbnRNZXNoZXNDYWNoZS5pbmRleE9mKG1lc2gpO1xyXG4gICAgICAgIGNvbnN0IG9wYXF1ZUlkeCA9IHRoaXMuX29wYXF1ZU1lc2hlc0NhY2hlLmluZGV4T2YobWVzaCk7XHJcblxyXG4gICAgICAgIC8vIElmIHRoZSBtYXRlcmlhbCBpcyB0cmFuc3BhcmVudCwgbWFrZSBzdXJlIHRoYXQgaXQncyBhZGRlZCB0byB0aGUgdHJhbnNwYXJlbnQgbGlzdCBhbmQgcmVtb3ZlZCBmcm9tIHRoZSBvcGFxdWUgbGlzdFxyXG4gICAgICAgIGNvbnN0IHVzZVRyYW5zbWlzc2lvbiA9IHRoaXMuX3Nob3VsZFJlbmRlckFzVHJhbnNtaXNzaW9uKG1lc2gubWF0ZXJpYWwpO1xyXG4gICAgICAgIGlmICh1c2VUcmFuc21pc3Npb24pIHtcclxuICAgICAgICAgICAgaWYgKG1lc2gubWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkge1xyXG4gICAgICAgICAgICAgICAgbWVzaC5tYXRlcmlhbC5zdWJTdXJmYWNlLnJlZnJhY3Rpb25UZXh0dXJlID0gdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChvcGFxdWVJZHggIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9vcGFxdWVNZXNoZXNDYWNoZS5zcGxpY2Uob3BhcXVlSWR4LCAxKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RyYW5zcGFyZW50TWVzaGVzQ2FjaGUucHVzaChtZXNoKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0cmFuc3BhcmVudElkeCA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RyYW5zcGFyZW50TWVzaGVzQ2FjaGUucHVzaChtZXNoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBJZiB0aGUgbWF0ZXJpYWwgaXMgb3BhcXVlLCBtYWtlIHN1cmUgdGhhdCBpdCdzIGFkZGVkIHRvIHRoZSBvcGFxdWUgbGlzdCBhbmQgcmVtb3ZlZCBmcm9tIHRoZSB0cmFuc3BhcmVudCBsaXN0XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHRyYW5zcGFyZW50SWR4ICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdHJhbnNwYXJlbnRNZXNoZXNDYWNoZS5zcGxpY2UodHJhbnNwYXJlbnRJZHgsIDEpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fb3BhcXVlTWVzaGVzQ2FjaGUucHVzaChtZXNoKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChvcGFxdWVJZHggPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9vcGFxdWVNZXNoZXNDYWNoZS5wdXNoKG1lc2gpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKiBDaGVjayBpZiB0aGUgb3BhcXVlIHJlbmRlciB0YXJnZXQgaGFzIG5vdCBiZWVuIGRpc3Bvc2VkIGFuZCBjYW4gc3RpbGwgYmUgdXNlZC5cclxuICAgICAqIEByZXR1cm5zXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfaXNSZW5kZXJUYXJnZXRWYWxpZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0Py5nZXRJbnRlcm5hbFRleHR1cmUoKSAhPT0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICogU2V0dXAgdGhlIHJlbmRlciB0YXJnZXRzIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIG9wdGlvbnMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfc2V0dXBSZW5kZXJUYXJnZXRzKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQpIHtcclxuICAgICAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0LmRpc3Bvc2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0ID0gbmV3IFJlbmRlclRhcmdldFRleHR1cmUoXHJcbiAgICAgICAgICAgIFwib3BhcXVlU2NlbmVUZXh0dXJlXCIsXHJcbiAgICAgICAgICAgIHRoaXMuX29wdGlvbnMucmVuZGVyU2l6ZSxcclxuICAgICAgICAgICAgdGhpcy5fc2NlbmUsXHJcbiAgICAgICAgICAgIHRoaXMuX29wdGlvbnMuZ2VuZXJhdGVNaXBtYXBzLFxyXG4gICAgICAgICAgICB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIHRoaXMuX29wdGlvbnMucmVuZGVyVGFyZ2V0VGV4dHVyZVR5cGVcclxuICAgICAgICApO1xyXG4gICAgICAgIHRoaXMuX29wYXF1ZVJlbmRlclRhcmdldC5pZ25vcmVDYW1lcmFWaWV3cG9ydCA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0LnJlbmRlckxpc3QgPSB0aGlzLl9vcGFxdWVNZXNoZXNDYWNoZTtcclxuICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQuY2xlYXJDb2xvciA9IHRoaXMuX29wdGlvbnMuY2xlYXJDb2xvcj8uY2xvbmUoKSA/PyB0aGlzLl9zY2VuZS5jbGVhckNvbG9yLmNsb25lKCk7XHJcbiAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0LmdhbW1hU3BhY2UgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQubG9kR2VuZXJhdGlvblNjYWxlID0gdGhpcy5fb3B0aW9ucy5sb2RHZW5lcmF0aW9uU2NhbGU7XHJcbiAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0LmxvZEdlbmVyYXRpb25PZmZzZXQgPSB0aGlzLl9vcHRpb25zLmxvZEdlbmVyYXRpb25PZmZzZXQ7XHJcbiAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0LnNhbXBsZXMgPSB0aGlzLl9vcHRpb25zLnNhbXBsZXM7XHJcbiAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0LnJlbmRlclNwcml0ZXMgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX29wYXF1ZVJlbmRlclRhcmdldC5yZW5kZXJQYXJ0aWNsZXMgPSB0cnVlO1xyXG5cclxuICAgICAgICBsZXQgc2NlbmVJbWFnZVByb2Nlc3NpbmdhcHBseUJ5UG9zdFByb2Nlc3M6IGJvb2xlYW47XHJcblxyXG4gICAgICAgIGxldCBzYXZlU2NlbmVFbnZJbnRlbnNpdHk6IG51bWJlcjtcclxuICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQub25CZWZvcmVCaW5kT2JzZXJ2YWJsZS5hZGQoKG9wYXF1ZVJlbmRlclRhcmdldCkgPT4ge1xyXG4gICAgICAgICAgICBzYXZlU2NlbmVFbnZJbnRlbnNpdHkgPSB0aGlzLl9zY2VuZS5lbnZpcm9ubWVudEludGVuc2l0eTtcclxuICAgICAgICAgICAgdGhpcy5fc2NlbmUuZW52aXJvbm1lbnRJbnRlbnNpdHkgPSAxLjA7XHJcbiAgICAgICAgICAgIHNjZW5lSW1hZ2VQcm9jZXNzaW5nYXBwbHlCeVBvc3RQcm9jZXNzID0gdGhpcy5fc2NlbmUuaW1hZ2VQcm9jZXNzaW5nQ29uZmlndXJhdGlvbi5hcHBseUJ5UG9zdFByb2Nlc3M7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5fb3B0aW9ucy5jbGVhckNvbG9yKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zY2VuZS5jbGVhckNvbG9yLnRvTGluZWFyU3BhY2VUb1JlZihvcGFxdWVSZW5kZXJUYXJnZXQuY2xlYXJDb2xvciwgdGhpcy5fc2NlbmUuZ2V0RW5naW5lKCkudXNlRXhhY3RTcmdiQ29udmVyc2lvbnMpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgb3BhcXVlUmVuZGVyVGFyZ2V0LmNsZWFyQ29sb3IuY29weUZyb20odGhpcy5fb3B0aW9ucy5jbGVhckNvbG9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyB3ZSBkbyBub3QgdXNlIHRoZSBhcHBseUJ5UG9zdFByb2Nlc3Mgc2V0dGVyIHRvIGF2b2lkIGZsYWdnaW5nIGFsbCB0aGUgbWF0ZXJpYWxzIGFzIFwiaW1hZ2UgcHJvY2Vzc2luZyBkaXJ0eVwiIVxyXG4gICAgICAgICAgICB0aGlzLl9zY2VuZS5pbWFnZVByb2Nlc3NpbmdDb25maWd1cmF0aW9uLl9hcHBseUJ5UG9zdFByb2Nlc3MgPSB0cnVlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuX29wYXF1ZVJlbmRlclRhcmdldC5vbkFmdGVyVW5iaW5kT2JzZXJ2YWJsZS5hZGQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9zY2VuZS5lbnZpcm9ubWVudEludGVuc2l0eSA9IHNhdmVTY2VuZUVudkludGVuc2l0eTtcclxuICAgICAgICAgICAgdGhpcy5fc2NlbmUuaW1hZ2VQcm9jZXNzaW5nQ29uZmlndXJhdGlvbi5fYXBwbHlCeVBvc3RQcm9jZXNzID0gc2NlbmVJbWFnZVByb2Nlc3NpbmdhcHBseUJ5UG9zdFByb2Nlc3M7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMuX3RyYW5zcGFyZW50TWVzaGVzQ2FjaGUuZm9yRWFjaCgobWVzaDogQWJzdHJhY3RNZXNoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9zaG91bGRSZW5kZXJBc1RyYW5zbWlzc2lvbihtZXNoLm1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICAgICAgKG1lc2gubWF0ZXJpYWwgYXMgUEJSTWF0ZXJpYWwpLnJlZnJhY3Rpb25UZXh0dXJlID0gdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEaXNwb3NlIGFsbCB0aGUgZWxlbWVudHMgY3JlYXRlZCBieSB0aGUgSGVscGVyLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9zY2VuZS5fdHJhbnNtaXNzaW9uSGVscGVyID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIGlmICh0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQpIHtcclxuICAgICAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0LmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0ID0gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fdHJhbnNwYXJlbnRNZXNoZXNDYWNoZSA9IFtdO1xyXG4gICAgICAgIHRoaXMuX29wYXF1ZU1lc2hlc0NhY2hlID0gW107XHJcbiAgICB9XHJcbn1cclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl9tYXRlcmlhbHNfdHJhbnNtaXNzaW9uXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9tYXRlcmlhbHNfdHJhbnNtaXNzaW9uIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJLSFJfbWF0ZXJpYWxzX3RyYW5zbWlzc2lvblwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl9tYXRlcmlhbHNfdHJhbnNtaXNzaW9uL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfdHJhbnNtaXNzaW9uIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBhIG51bWJlciB0aGF0IGRldGVybWluZXMgdGhlIG9yZGVyIHRoZSBleHRlbnNpb25zIGFyZSBhcHBsaWVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb3JkZXIgPSAxNzU7XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgICAgIGlmICh0aGlzLmVuYWJsZWQpIHtcclxuICAgICAgICAgICAgbG9hZGVyLnBhcmVudC50cmFuc3BhcmVuY3lBc0NvdmVyYWdlID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUk1hdGVyaWFsc1RyYW5zbWlzc2lvbj4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZFRyYW5zcGFyZW50UHJvcGVydGllc0FzeW5jKGV4dGVuc2lvbkNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwsIGV4dGVuc2lvbikpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRUcmFuc3BhcmVudFByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwsIGV4dGVuc2lvbjogSUtIUk1hdGVyaWFsc1RyYW5zbWlzc2lvbik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IE1hdGVyaWFsIHR5cGUgbm90IHN1cHBvcnRlZGApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBwYnJNYXRlcmlhbCA9IGJhYnlsb25NYXRlcmlhbCBhcyBQQlJNYXRlcmlhbDtcclxuXHJcbiAgICAgICAgLy8gRW5hYmxlcyBcInJlZnJhY3Rpb25cIiB0ZXh0dXJlIHdoaWNoIHJlcHJlc2VudHMgdHJhbnNtaXR0ZWQgbGlnaHQuXHJcbiAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS5pc1JlZnJhY3Rpb25FbmFibGVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgLy8gU2luY2UgdGhpcyBleHRlbnNpb24gbW9kZWxzIHRoaW4tc3VyZmFjZSB0cmFuc21pc3Npb24gb25seSwgd2UgbXVzdCBtYWtlIElPUiA9IDEuMFxyXG4gICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2Uudm9sdW1lSW5kZXhPZlJlZnJhY3Rpb24gPSAxLjA7XHJcblxyXG4gICAgICAgIC8vIEFsYmVkbyBjb2xvdXIgd2lsbCB0aW50IHRyYW5zbWlzc2lvbi5cclxuICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLnVzZUFsYmVkb1RvVGludFJlZnJhY3Rpb24gPSB0cnVlO1xyXG5cclxuICAgICAgICBpZiAoZXh0ZW5zaW9uLnRyYW5zbWlzc2lvbkZhY3RvciAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UucmVmcmFjdGlvbkludGVuc2l0eSA9IGV4dGVuc2lvbi50cmFuc21pc3Npb25GYWN0b3I7XHJcbiAgICAgICAgICAgIGNvbnN0IHNjZW5lID0gcGJyTWF0ZXJpYWwuZ2V0U2NlbmUoKSBhcyB1bmtub3duIGFzIElUcmFuc21pc3Npb25IZWxwZXJIb2xkZXI7XHJcbiAgICAgICAgICAgIGlmIChwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLnJlZnJhY3Rpb25JbnRlbnNpdHkgJiYgIXNjZW5lLl90cmFuc21pc3Npb25IZWxwZXIpIHtcclxuICAgICAgICAgICAgICAgIG5ldyBUcmFuc21pc3Npb25IZWxwZXIoe30sIHBick1hdGVyaWFsLmdldFNjZW5lKCkpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHBick1hdGVyaWFsLnN1YlN1cmZhY2UucmVmcmFjdGlvbkludGVuc2l0eSAmJiAhc2NlbmUuX3RyYW5zbWlzc2lvbkhlbHBlcj8uX2lzUmVuZGVyVGFyZ2V0VmFsaWQoKSkge1xyXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIHJlbmRlciB0YXJnZXQgaXMgbm90IHZhbGlkLCByZWNyZWF0ZSBpdC5cclxuICAgICAgICAgICAgICAgIHNjZW5lLl90cmFuc21pc3Npb25IZWxwZXI/Ll9zZXR1cFJlbmRlclRhcmdldHMoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UucmVmcmFjdGlvbkludGVuc2l0eSA9IDAuMDtcclxuICAgICAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS5pc1JlZnJhY3Rpb25FbmFibGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UubWluaW11bVRoaWNrbmVzcyA9IDAuMDtcclxuICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLm1heGltdW1UaGlja25lc3MgPSAwLjA7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvbi50cmFuc21pc3Npb25UZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIChleHRlbnNpb24udHJhbnNtaXNzaW9uVGV4dHVyZSBhcyBJVGV4dHVyZUluZm8pLm5vbkNvbG9yRGF0YSA9IHRydWU7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vdHJhbnNtaXNzaW9uVGV4dHVyZWAsIGV4dGVuc2lvbi50cmFuc21pc3Npb25UZXh0dXJlLCB1bmRlZmluZWQpLnRoZW4oKHRleHR1cmU6IEJhc2VUZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKFRyYW5zbWlzc2lvbilgO1xyXG4gICAgICAgICAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS5yZWZyYWN0aW9uSW50ZW5zaXR5VGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLnVzZUdsdGZTdHlsZVRleHR1cmVzID0gdHJ1ZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX21hdGVyaWFsc190cmFuc21pc3Npb24obG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBDb2xvcjMgfSBmcm9tIFwiY29yZS9NYXRocy9tYXRoLmNvbG9yXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IElNYXRlcmlhbCB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWF0ZXJpYWxzX3VubGl0XCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9tYXRlcmlhbHNfdW5saXQgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfdW5saXRcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbWF0ZXJpYWxzX3VubGl0L1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfdW5saXQgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDIxMDtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmMoY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKCkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZFVubGl0UHJvcGVydGllc0FzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRVbmxpdFByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAoIShiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBNYXRlcmlhbCB0eXBlIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwudW5saXQgPSB0cnVlO1xyXG5cclxuICAgICAgICBjb25zdCBwcm9wZXJ0aWVzID0gbWF0ZXJpYWwucGJyTWV0YWxsaWNSb3VnaG5lc3M7XHJcbiAgICAgICAgaWYgKHByb3BlcnRpZXMpIHtcclxuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMuYmFzZUNvbG9yRmFjdG9yKSB7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvQ29sb3IgPSBDb2xvcjMuRnJvbUFycmF5KHByb3BlcnRpZXMuYmFzZUNvbG9yRmFjdG9yKTtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbHBoYSA9IHByb3BlcnRpZXMuYmFzZUNvbG9yRmFjdG9yWzNdO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmFsYmVkb0NvbG9yID0gQ29sb3IzLldoaXRlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLmJhc2VDb2xvclRleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L2Jhc2VDb2xvclRleHR1cmVgLCBwcm9wZXJ0aWVzLmJhc2VDb2xvclRleHR1cmUsICh0ZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoQmFzZSBDb2xvcilgO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvVGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChtYXRlcmlhbC5kb3VibGVTaWRlZCkge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYmFja0ZhY2VDdWxsaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC50d29TaWRlZExpZ2h0aW5nID0gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2xvYWRlci5sb2FkTWF0ZXJpYWxBbHBoYVByb3BlcnRpZXMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl9tYXRlcmlhbHNfdW5saXQobG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciwgQXJyYXlJdGVtIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuaW1wb3J0IHsgTWVzaCB9IGZyb20gXCJjb3JlL01lc2hlcy9tZXNoXCI7XHJcbmltcG9ydCB0eXBlIHsgTm9kZSB9IGZyb20gXCJjb3JlL25vZGVcIjtcclxuaW1wb3J0IHR5cGUgeyBBYnN0cmFjdE1lc2ggfSBmcm9tIFwiY29yZS9NZXNoZXMvYWJzdHJhY3RNZXNoXCI7XHJcbmltcG9ydCB0eXBlIHsgSU5vZGUsIElNZXNoUHJpbWl0aXZlLCBJTWVzaCB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElLSFJNYXRlcmlhbFZhcmlhbnRzX01hcHBpbmcsIElLSFJNYXRlcmlhbFZhcmlhbnRzX1ZhcmlhbnQsIElLSFJNYXRlcmlhbFZhcmlhbnRzX1ZhcmlhbnRzIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IFRyYW5zZm9ybU5vZGUgfSBmcm9tIFwiY29yZS9NZXNoZXMvdHJhbnNmb3JtTm9kZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc192YXJpYW50c1wiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfbWF0ZXJpYWxzX3ZhcmlhbnRzIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJLSFJfbWF0ZXJpYWxzX3ZhcmlhbnRzXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuaW50ZXJmYWNlIElWYXJpYW50c01hcCB7XHJcbiAgICBba2V5OiBzdHJpbmddOiBBcnJheTx7IG1lc2g6IEFic3RyYWN0TWVzaDsgbWF0ZXJpYWw6IE51bGxhYmxlPE1hdGVyaWFsPiB9PjtcclxufVxyXG5cclxuaW50ZXJmYWNlIElFeHRlbnNpb25NZXRhZGF0YSB7XHJcbiAgICBsYXN0U2VsZWN0ZWQ6IE51bGxhYmxlPHN0cmluZyB8IEFycmF5PHN0cmluZz4+O1xyXG4gICAgb3JpZ2luYWw6IEFycmF5PHsgbWVzaDogQWJzdHJhY3RNZXNoOyBtYXRlcmlhbDogTnVsbGFibGU8TWF0ZXJpYWw+IH0+O1xyXG4gICAgdmFyaWFudHM6IElWYXJpYW50c01hcDtcclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0tocm9ub3MvS0hSX21hdGVyaWFsc192YXJpYW50cy9SRUFETUUubWQpXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfbWF0ZXJpYWxzX3ZhcmlhbnRzIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICBwcml2YXRlIF92YXJpYW50cz86IEFycmF5PElLSFJNYXRlcmlhbFZhcmlhbnRzX1ZhcmlhbnQ+O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBsaXN0IG9mIGF2YWlsYWJsZSB2YXJpYW50IG5hbWVzIGZvciB0aGlzIGFzc2V0LlxyXG4gICAgICogQHBhcmFtIHJvb3RNZXNoIFRoZSBnbFRGIHJvb3QgbWVzaFxyXG4gICAgICogQHJldHVybnMgdGhlIGxpc3Qgb2YgYWxsIHRoZSB2YXJpYW50IG5hbWVzIGZvciB0aGlzIG1vZGVsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgR2V0QXZhaWxhYmxlVmFyaWFudHMocm9vdE1lc2g6IE1lc2gpOiBzdHJpbmdbXSB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uTWV0YWRhdGEgPSB0aGlzLl9HZXRFeHRlbnNpb25NZXRhZGF0YShyb290TWVzaCk7XHJcbiAgICAgICAgaWYgKCFleHRlbnNpb25NZXRhZGF0YSkge1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMoZXh0ZW5zaW9uTWV0YWRhdGEudmFyaWFudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgbGlzdCBvZiBhdmFpbGFibGUgdmFyaWFudCBuYW1lcyBmb3IgdGhpcyBhc3NldC5cclxuICAgICAqIEBwYXJhbSByb290TWVzaCBUaGUgZ2xURiByb290IG1lc2hcclxuICAgICAqIEByZXR1cm5zIHRoZSBsaXN0IG9mIGFsbCB0aGUgdmFyaWFudCBuYW1lcyBmb3IgdGhpcyBtb2RlbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0QXZhaWxhYmxlVmFyaWFudHMocm9vdE1lc2g6IE1lc2gpOiBzdHJpbmdbXSB7XHJcbiAgICAgICAgcmV0dXJuIEtIUl9tYXRlcmlhbHNfdmFyaWFudHMuR2V0QXZhaWxhYmxlVmFyaWFudHMocm9vdE1lc2gpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2VsZWN0IGEgdmFyaWFudCBnaXZlbiBhIHZhcmlhbnQgbmFtZSBvciBhIGxpc3Qgb2YgdmFyaWFudCBuYW1lcy5cclxuICAgICAqIEBwYXJhbSByb290TWVzaCBUaGUgZ2xURiByb290IG1lc2hcclxuICAgICAqIEBwYXJhbSB2YXJpYW50TmFtZSBUaGUgdmFyaWFudCBuYW1lKHMpIHRvIHNlbGVjdC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBTZWxlY3RWYXJpYW50KHJvb3RNZXNoOiBNZXNoLCB2YXJpYW50TmFtZTogc3RyaW5nIHwgc3RyaW5nW10pOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25NZXRhZGF0YSA9IHRoaXMuX0dldEV4dGVuc2lvbk1ldGFkYXRhKHJvb3RNZXNoKTtcclxuICAgICAgICBpZiAoIWV4dGVuc2lvbk1ldGFkYXRhKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHNlbGVjdCB2YXJpYW50IG9uIGEgZ2xURiBtZXNoIHRoYXQgZG9lcyBub3QgaGF2ZSB0aGUgJHtOQU1FfSBleHRlbnNpb25gKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHNlbGVjdCA9ICh2YXJpYW50TmFtZTogc3RyaW5nKTogdm9pZCA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGVudHJpZXMgPSBleHRlbnNpb25NZXRhZGF0YS52YXJpYW50c1t2YXJpYW50TmFtZV07XHJcbiAgICAgICAgICAgIGlmIChlbnRyaWVzKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBlbnRyeS5tZXNoLm1hdGVyaWFsID0gZW50cnkubWF0ZXJpYWw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBpZiAodmFyaWFudE5hbWUgaW5zdGFuY2VvZiBBcnJheSkge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgdmFyaWFudE5hbWUpIHtcclxuICAgICAgICAgICAgICAgIHNlbGVjdChuYW1lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHNlbGVjdCh2YXJpYW50TmFtZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBleHRlbnNpb25NZXRhZGF0YS5sYXN0U2VsZWN0ZWQgPSB2YXJpYW50TmFtZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNlbGVjdCBhIHZhcmlhbnQgZ2l2ZW4gYSB2YXJpYW50IG5hbWUgb3IgYSBsaXN0IG9mIHZhcmlhbnQgbmFtZXMuXHJcbiAgICAgKiBAcGFyYW0gcm9vdE1lc2ggVGhlIGdsVEYgcm9vdCBtZXNoXHJcbiAgICAgKiBAcGFyYW0gdmFyaWFudE5hbWUgVGhlIHZhcmlhbnQgbmFtZShzKSB0byBzZWxlY3QuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZWxlY3RWYXJpYW50KHJvb3RNZXNoOiBNZXNoLCB2YXJpYW50TmFtZTogc3RyaW5nIHwgc3RyaW5nW10pOiB2b2lkIHtcclxuICAgICAgICBLSFJfbWF0ZXJpYWxzX3ZhcmlhbnRzLlNlbGVjdFZhcmlhbnQocm9vdE1lc2gsIHZhcmlhbnROYW1lKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlc2V0IGJhY2sgdG8gdGhlIG9yaWdpbmFsIGJlZm9yZSBzZWxlY3RpbmcgYSB2YXJpYW50LlxyXG4gICAgICogQHBhcmFtIHJvb3RNZXNoIFRoZSBnbFRGIHJvb3QgbWVzaFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIFJlc2V0KHJvb3RNZXNoOiBNZXNoKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uTWV0YWRhdGEgPSB0aGlzLl9HZXRFeHRlbnNpb25NZXRhZGF0YShyb290TWVzaCk7XHJcbiAgICAgICAgaWYgKCFleHRlbnNpb25NZXRhZGF0YSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCByZXNldCBvbiBhIGdsVEYgbWVzaCB0aGF0IGRvZXMgbm90IGhhdmUgdGhlICR7TkFNRX0gZXh0ZW5zaW9uYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGV4dGVuc2lvbk1ldGFkYXRhLm9yaWdpbmFsKSB7XHJcbiAgICAgICAgICAgIGVudHJ5Lm1lc2gubWF0ZXJpYWwgPSBlbnRyeS5tYXRlcmlhbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGV4dGVuc2lvbk1ldGFkYXRhLmxhc3RTZWxlY3RlZCA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXNldCBiYWNrIHRvIHRoZSBvcmlnaW5hbCBiZWZvcmUgc2VsZWN0aW5nIGEgdmFyaWFudC5cclxuICAgICAqIEBwYXJhbSByb290TWVzaCBUaGUgZ2xURiByb290IG1lc2hcclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlc2V0KHJvb3RNZXNoOiBNZXNoKTogdm9pZCB7XHJcbiAgICAgICAgS0hSX21hdGVyaWFsc192YXJpYW50cy5SZXNldChyb290TWVzaCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBsYXN0IHNlbGVjdGVkIHZhcmlhbnQgbmFtZShzKSBvciBudWxsIGlmIG9yaWdpbmFsLlxyXG4gICAgICogQHBhcmFtIHJvb3RNZXNoIFRoZSBnbFRGIHJvb3QgbWVzaFxyXG4gICAgICogQHJldHVybnMgVGhlIHNlbGVjdGVkIHZhcmlhbnQgbmFtZShzKS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBHZXRMYXN0U2VsZWN0ZWRWYXJpYW50KHJvb3RNZXNoOiBNZXNoKTogTnVsbGFibGU8c3RyaW5nIHwgc3RyaW5nW10+IHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25NZXRhZGF0YSA9IHRoaXMuX0dldEV4dGVuc2lvbk1ldGFkYXRhKHJvb3RNZXNoKTtcclxuICAgICAgICBpZiAoIWV4dGVuc2lvbk1ldGFkYXRhKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGdldCB0aGUgbGFzdCBzZWxlY3RlZCB2YXJpYW50IG9uIGEgZ2xURiBtZXNoIHRoYXQgZG9lcyBub3QgaGF2ZSB0aGUgJHtOQU1FfSBleHRlbnNpb25gKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBleHRlbnNpb25NZXRhZGF0YS5sYXN0U2VsZWN0ZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBsYXN0IHNlbGVjdGVkIHZhcmlhbnQgbmFtZShzKSBvciBudWxsIGlmIG9yaWdpbmFsLlxyXG4gICAgICogQHBhcmFtIHJvb3RNZXNoIFRoZSBnbFRGIHJvb3QgbWVzaFxyXG4gICAgICogQHJldHVybnMgVGhlIHNlbGVjdGVkIHZhcmlhbnQgbmFtZShzKS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldExhc3RTZWxlY3RlZFZhcmlhbnQocm9vdE1lc2g6IE1lc2gpOiBOdWxsYWJsZTxzdHJpbmcgfCBzdHJpbmdbXT4ge1xyXG4gICAgICAgIHJldHVybiBLSFJfbWF0ZXJpYWxzX3ZhcmlhbnRzLkdldExhc3RTZWxlY3RlZFZhcmlhbnQocm9vdE1lc2gpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIF9HZXRFeHRlbnNpb25NZXRhZGF0YShyb290TWVzaDogTnVsbGFibGU8VHJhbnNmb3JtTm9kZT4pOiBOdWxsYWJsZTxJRXh0ZW5zaW9uTWV0YWRhdGE+IHtcclxuICAgICAgICByZXR1cm4gcm9vdE1lc2g/Ll9pbnRlcm5hbE1ldGFkYXRhPy5nbHRmPy5bTkFNRV0gfHwgbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgb25Mb2FkaW5nKCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbnMgPSB0aGlzLl9sb2FkZXIuZ2x0Zi5leHRlbnNpb25zO1xyXG4gICAgICAgIGlmIChleHRlbnNpb25zICYmIGV4dGVuc2lvbnNbdGhpcy5uYW1lXSkge1xyXG4gICAgICAgICAgICBjb25zdCBleHRlbnNpb24gPSBleHRlbnNpb25zW3RoaXMubmFtZV0gYXMgSUtIUk1hdGVyaWFsVmFyaWFudHNfVmFyaWFudHM7XHJcbiAgICAgICAgICAgIHRoaXMuX3ZhcmlhbnRzID0gZXh0ZW5zaW9uLnZhcmlhbnRzO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvYWRNZXNoUHJpbWl0aXZlQXN5bmMoXHJcbiAgICAgICAgY29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIG5hbWU6IHN0cmluZyxcclxuICAgICAgICBub2RlOiBJTm9kZSxcclxuICAgICAgICBtZXNoOiBJTWVzaCxcclxuICAgICAgICBwcmltaXRpdmU6IElNZXNoUHJpbWl0aXZlLFxyXG4gICAgICAgIGFzc2lnbjogKGJhYnlsb25NZXNoOiBBYnN0cmFjdE1lc2gpID0+IHZvaWRcclxuICAgICk6IE51bGxhYmxlPFByb21pc2U8QWJzdHJhY3RNZXNoPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRlbnNpb25Bc3luYzxJS0hSTWF0ZXJpYWxWYXJpYW50c19NYXBwaW5nLCBBYnN0cmFjdE1lc2g+KGNvbnRleHQsIHByaW1pdGl2ZSwgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5fbG9hZE1lc2hQcmltaXRpdmVBc3luYyhjb250ZXh0LCBuYW1lLCBub2RlLCBtZXNoLCBwcmltaXRpdmUsIChiYWJ5bG9uTWVzaCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGFzc2lnbihiYWJ5bG9uTWVzaCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTWVzaCBpbnN0YW5jZW9mIE1lc2gpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYmFieWxvbkRyYXdNb2RlID0gR0xURkxvYWRlci5fR2V0RHJhd01vZGUoY29udGV4dCwgcHJpbWl0aXZlLm1vZGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgcm9vdCA9IHRoaXMuX2xvYWRlci5yb290QmFieWxvbk1lc2g7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldGFkYXRhID0gcm9vdCA/IChyb290Ll9pbnRlcm5hbE1ldGFkYXRhID0gcm9vdC5faW50ZXJuYWxNZXRhZGF0YSB8fCB7fSkgOiB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ2x0ZiA9IChtZXRhZGF0YS5nbHRmID0gbWV0YWRhdGEuZ2x0ZiB8fCB7fSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbk1ldGFkYXRhOiBJRXh0ZW5zaW9uTWV0YWRhdGEgPSAoZ2x0ZltOQU1FXSA9IGdsdGZbTkFNRV0gfHwgeyBsYXN0U2VsZWN0ZWQ6IG51bGwsIG9yaWdpbmFsOiBbXSwgdmFyaWFudHM6IHt9IH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RvcmUgdGhlIG9yaWdpbmFsIG1hdGVyaWFsLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25NZXRhZGF0YS5vcmlnaW5hbC5wdXNoKHsgbWVzaDogYmFieWxvbk1lc2gsIG1hdGVyaWFsOiBiYWJ5bG9uTWVzaC5tYXRlcmlhbCB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZvciBlYWNoIG1hcHBpbmcsIGxvb2sgYXQgdGhlIHZhcmlhbnRzIGFuZCBtYWtlIGEgbmV3IGVudHJ5IGZvciB0aGVtLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBtYXBwaW5nSW5kZXggPSAwOyBtYXBwaW5nSW5kZXggPCBleHRlbnNpb24ubWFwcGluZ3MubGVuZ3RoOyArK21hcHBpbmdJbmRleCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWFwcGluZyA9IGV4dGVuc2lvbi5tYXBwaW5nc1ttYXBwaW5nSW5kZXhdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSBBcnJheUl0ZW0uR2V0KGAke2V4dGVuc2lvbkNvbnRleHR9L21hcHBpbmdzLyR7bWFwcGluZ0luZGV4fS9tYXRlcmlhbGAsIHRoaXMuX2xvYWRlci5nbHRmLm1hdGVyaWFscywgbWFwcGluZy5tYXRlcmlhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5fbG9hZE1hdGVyaWFsQXN5bmMoYCMvbWF0ZXJpYWxzLyR7bWFwcGluZy5tYXRlcmlhbH1gLCBtYXRlcmlhbCwgYmFieWxvbk1lc2gsIGJhYnlsb25EcmF3TW9kZSwgKGJhYnlsb25NYXRlcmlhbCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBtYXBwaW5nVmFyaWFudEluZGV4ID0gMDsgbWFwcGluZ1ZhcmlhbnRJbmRleCA8IG1hcHBpbmcudmFyaWFudHMubGVuZ3RoOyArK21hcHBpbmdWYXJpYW50SW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhcmlhbnRJbmRleCA9IG1hcHBpbmcudmFyaWFudHNbbWFwcGluZ1ZhcmlhbnRJbmRleF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YXJpYW50ID0gQXJyYXlJdGVtLkdldChgL2V4dGVuc2lvbnMvJHtOQU1FfS92YXJpYW50cy8ke3ZhcmlhbnRJbmRleH1gLCB0aGlzLl92YXJpYW50cywgdmFyaWFudEluZGV4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbk1ldGFkYXRhLnZhcmlhbnRzW3ZhcmlhbnQubmFtZV0gPSBleHRlbnNpb25NZXRhZGF0YS52YXJpYW50c1t2YXJpYW50Lm5hbWVdIHx8IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uTWV0YWRhdGEudmFyaWFudHNbdmFyaWFudC5uYW1lXS5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNoOiBiYWJ5bG9uTWVzaCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRlcmlhbDogYmFieWxvbk1hdGVyaWFsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVwbGFjZSB0aGUgdGFyZ2V0IHdoZW4gb3JpZ2luYWwgbWVzaCBpcyBjbG9uZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25NZXNoLm9uQ2xvbmVkT2JzZXJ2YWJsZS5hZGQoKG5ld09uZTogTm9kZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld01lc2ggPSBuZXdPbmUgYXMgTWVzaDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgbWV0YWRhdGE6IE51bGxhYmxlPElFeHRlbnNpb25NZXRhZGF0YT4gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBuZXdSb290OiBOdWxsYWJsZTxOb2RlPiA9IG5ld01lc2g7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpbmQgcm9vdCB0byBnZXQgbWVkYXRhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG8ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdSb290ID0gbmV3Um9vdCEucGFyZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5ld1Jvb3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YSA9IEtIUl9tYXRlcmlhbHNfdmFyaWFudHMuX0dldEV4dGVuc2lvbk1ldGFkYXRhKG5ld1Jvb3QgYXMgTWVzaCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAobWV0YWRhdGEgPT09IG51bGwpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOZWVkIHRvIGNsb25lIHRoZSBtZXRhZGF0YSBvbiB0aGUgcm9vdCAoZmlyc3QgdGltZSBvbmx5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyb290ICYmIG1ldGFkYXRhID09PSBLSFJfbWF0ZXJpYWxzX3ZhcmlhbnRzLl9HZXRFeHRlbnNpb25NZXRhZGF0YShyb290KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb3B5IG1haW4gbWV0YWRhdGFcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Um9vdC5faW50ZXJuYWxNZXRhZGF0YSA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiByb290Ll9pbnRlcm5hbE1ldGFkYXRhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdSb290Ll9pbnRlcm5hbE1ldGFkYXRhW2tleV0gPSByb290Ll9pbnRlcm5hbE1ldGFkYXRhW2tleV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvcHkgdGhlIGdsdGYgbWV0YWRhdGFcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Um9vdC5faW50ZXJuYWxNZXRhZGF0YS5nbHRmID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHJvb3QuX2ludGVybmFsTWV0YWRhdGEuZ2x0Zikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Um9vdC5faW50ZXJuYWxNZXRhZGF0YS5nbHRmW2tleV0gPSByb290Ll9pbnRlcm5hbE1ldGFkYXRhLmdsdGZba2V5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRHVwbGljYXRlIHRoZSBleHRlbnNpb24gc3BlY2lmaWMgbWV0YWRhdGFcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Um9vdC5faW50ZXJuYWxNZXRhZGF0YS5nbHRmW05BTUVdID0geyBsYXN0U2VsZWN0ZWQ6IG51bGwsIG9yaWdpbmFsOiBbXSwgdmFyaWFudHM6IHt9IH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgb3JpZ2luYWwgb2YgbWV0YWRhdGEub3JpZ2luYWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Jvb3QuX2ludGVybmFsTWV0YWRhdGEuZ2x0ZltOQU1FXS5vcmlnaW5hbC5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNoOiBvcmlnaW5hbC5tZXNoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGVyaWFsOiBvcmlnaW5hbC5tYXRlcmlhbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIG1ldGFkYXRhLnZhcmlhbnRzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1ldGFkYXRhLnZhcmlhbnRzLCBrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Um9vdC5faW50ZXJuYWxNZXRhZGF0YS5nbHRmW05BTUVdLnZhcmlhbnRzW2tleV0gPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHZhcmlhbnRFbnRyeSBvZiBtZXRhZGF0YS52YXJpYW50c1trZXldKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Jvb3QuX2ludGVybmFsTWV0YWRhdGEuZ2x0ZltOQU1FXS52YXJpYW50c1trZXldLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzaDogdmFyaWFudEVudHJ5Lm1lc2gsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRlcmlhbDogdmFyaWFudEVudHJ5Lm1hdGVyaWFsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhID0gbmV3Um9vdC5faW50ZXJuYWxNZXRhZGF0YS5nbHRmW05BTUVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVsb2NhdGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRhcmdldCBvZiBtZXRhZGF0YSEub3JpZ2luYWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldC5tZXNoID09PSBiYWJ5bG9uTWVzaCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Lm1lc2ggPSBuZXdNZXNoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdGFyZ2V0IG9mIG1ldGFkYXRhIS52YXJpYW50c1t2YXJpYW50Lm5hbWVdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQubWVzaCA9PT0gYmFieWxvbk1lc2gpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldC5tZXNoID0gbmV3TWVzaDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKFtiYWJ5bG9uTWVzaF0pID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBiYWJ5bG9uTWVzaDtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl9tYXRlcmlhbHNfdmFyaWFudHMobG9hZGVyKSk7XHJcbiIsIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiAqL1xyXG5pbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBCYXNlVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy9iYXNlVGV4dHVyZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElNYXRlcmlhbCwgSVRleHR1cmVJbmZvIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSTWF0ZXJpYWxzVm9sdW1lIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc192b2x1bWVcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX21hdGVyaWFsc192b2x1bWUgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfdm9sdW1lXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0tocm9ub3MvS0hSX21hdGVyaWFsc192b2x1bWUvUkVBRE1FLm1kKVxyXG4gKiBAc2luY2UgNS4wLjBcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfdm9sdW1lIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBhIG51bWJlciB0aGF0IGRldGVybWluZXMgdGhlIG9yZGVyIHRoZSBleHRlbnNpb25zIGFyZSBhcHBsaWVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb3JkZXIgPSAxNzM7XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgICAgIGlmICh0aGlzLmVuYWJsZWQpIHtcclxuICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBkaXNhYmxlIGluc3RhbmNlIHVzYWdlIGJlY2F1c2UgdGhlIGF0dGVudWF0aW9uIGZhY3RvciBkZXBlbmRzIG9uIHRoZSBub2RlIHNjYWxlIG9mIGVhY2ggaW5kaXZpZHVhbCBtZXNoXHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5fZGlzYWJsZUluc3RhbmNlZE1lc2grKztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZW5hYmxlZCkge1xyXG4gICAgICAgICAgICB0aGlzLl9sb2FkZXIuX2Rpc2FibGVJbnN0YW5jZWRNZXNoLS07XHJcbiAgICAgICAgfVxyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBOdWxsYWJsZTxQcm9taXNlPHZvaWQ+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElLSFJNYXRlcmlhbHNWb2x1bWU+KGNvbnRleHQsIG1hdGVyaWFsLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRlci5sb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCkpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRWb2x1bWVQcm9wZXJ0aWVzQXN5bmMoZXh0ZW5zaW9uQ29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCwgZXh0ZW5zaW9uKSk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZFZvbHVtZVByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwsIGV4dGVuc2lvbjogSUtIUk1hdGVyaWFsc1ZvbHVtZSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IE1hdGVyaWFsIHR5cGUgbm90IHN1cHBvcnRlZGApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSWYgdHJhbnNwYXJlbmN5IGlzbid0IGVuYWJsZWQgYWxyZWFkeSwgdGhpcyBleHRlbnNpb24gc2hvdWxkbid0IGRvIGFueXRoaW5nLlxyXG4gICAgICAgIC8vIGkuZS4gaXQgcmVxdWlyZXMgZWl0aGVyIHRoZSBLSFJfbWF0ZXJpYWxzX3RyYW5zbWlzc2lvbiBvciBLSFJfbWF0ZXJpYWxzX2RpZmZ1c2VfdHJhbnNtaXNzaW9uIGV4dGVuc2lvbnMuXHJcbiAgICAgICAgaWYgKCghYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2UuaXNSZWZyYWN0aW9uRW5hYmxlZCAmJiAhYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2UuaXNUcmFuc2x1Y2VuY3lFbmFibGVkKSB8fCAhZXh0ZW5zaW9uLnRoaWNrbmVzc0ZhY3Rvcikge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJT1IgaW4gdGhpcyBleHRlbnNpb24gb25seSBhZmZlY3RzIGludGVyaW9yLlxyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5zdWJTdXJmYWNlLnZvbHVtZUluZGV4T2ZSZWZyYWN0aW9uID0gYmFieWxvbk1hdGVyaWFsLmluZGV4T2ZSZWZyYWN0aW9uO1xyXG4gICAgICAgIGNvbnN0IGF0dGVudWF0aW9uRGlzdGFuY2UgPSBleHRlbnNpb24uYXR0ZW51YXRpb25EaXN0YW5jZSAhPT0gdW5kZWZpbmVkID8gZXh0ZW5zaW9uLmF0dGVudWF0aW9uRGlzdGFuY2UgOiBOdW1iZXIuTUFYX1ZBTFVFO1xyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5zdWJTdXJmYWNlLnRpbnRDb2xvckF0RGlzdGFuY2UgPSBhdHRlbnVhdGlvbkRpc3RhbmNlO1xyXG4gICAgICAgIGlmIChleHRlbnNpb24uYXR0ZW51YXRpb25Db2xvciAhPT0gdW5kZWZpbmVkICYmIGV4dGVuc2lvbi5hdHRlbnVhdGlvbkNvbG9yLmxlbmd0aCA9PSAzKSB7XHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5zdWJTdXJmYWNlLnRpbnRDb2xvci5jb3B5RnJvbUZsb2F0cyhleHRlbnNpb24uYXR0ZW51YXRpb25Db2xvclswXSwgZXh0ZW5zaW9uLmF0dGVudWF0aW9uQ29sb3JbMV0sIGV4dGVuc2lvbi5hdHRlbnVhdGlvbkNvbG9yWzJdKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5zdWJTdXJmYWNlLm1pbmltdW1UaGlja25lc3MgPSAwLjA7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2UubWF4aW11bVRoaWNrbmVzcyA9IGV4dGVuc2lvbi50aGlja25lc3NGYWN0b3I7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2UudXNlVGhpY2tuZXNzQXNEZXB0aCA9IHRydWU7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvbi50aGlja25lc3NUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIChleHRlbnNpb24udGhpY2tuZXNzVGV4dHVyZSBhcyBJVGV4dHVyZUluZm8pLm5vbkNvbG9yRGF0YSA9IHRydWU7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vdGhpY2tuZXNzVGV4dHVyZWAsIGV4dGVuc2lvbi50aGlja25lc3NUZXh0dXJlKS50aGVuKCh0ZXh0dXJlOiBCYXNlVGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGV4dHVyZS5uYW1lID0gYCR7YmFieWxvbk1hdGVyaWFsLm5hbWV9IChUaGlja25lc3MpYDtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5zdWJTdXJmYWNlLnRoaWNrbmVzc1RleHR1cmUgPSB0ZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2UudXNlR2x0ZlN0eWxlVGV4dHVyZXMgPSB0cnVlO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfbWF0ZXJpYWxzX3ZvbHVtZShsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB0eXBlIHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWVzaF9xdWFudGl6YXRpb25cIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX21lc2hfcXVhbnRpemF0aW9uIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJLSFJfbWVzaF9xdWFudGl6YXRpb25cIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbWVzaF9xdWFudGl6YXRpb24vUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21lc2hfcXVhbnRpemF0aW9uIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IGxvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7fVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfbWVzaF9xdWFudGl6YXRpb24obG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgQWJzdHJhY3RNZXNoIH0gZnJvbSBcImNvcmUvTWVzaGVzL2Fic3RyYWN0TWVzaFwiO1xuaW1wb3J0IHR5cGUgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcblxuY29uc3QgTkFNRSA9IFwiS0hSX25vZGVfdmlzaWJpbGl0eVwiO1xuXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfbm9kZV92aXNpYmlsaXR5IGV4dGVuc2lvbi5cbiAgICAgICAgICovXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxuICAgICAgICBbXCJLSFJfbm9kZV92aXNpYmlsaXR5XCJdOiB7fTtcbiAgICB9XG59XG5cbi8qKlxuICogTG9hZGVyIGV4dGVuc2lvbiBmb3IgS0hSX25vZGVfdmlzaWJpbGl0eVxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG5leHBvcnQgY2xhc3MgS0hSX25vZGVfdmlzaWJpbGl0eSBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XG4gICAgLyoqXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXG4gICAgICovXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XG5cbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xuICAgICAgICB0aGlzLmVuYWJsZWQgPSBsb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBvblJlYWR5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLl9sb2FkZXIuZ2x0Zi5ub2Rlcz8uZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgICAgICAgICAgbm9kZS5fcHJpbWl0aXZlQmFieWxvbk1lc2hlcz8uZm9yRWFjaCgobWVzaCkgPT4ge1xuICAgICAgICAgICAgICAgIG1lc2guaW5oZXJpdFZpc2liaWxpdHkgPSB0cnVlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBXaGVuIHRoZSBKU09OIFBvaW50ZXIgaXMgdXNlZCB3ZSBuZWVkIHRvIGNoYW5nZSBib3RoIHRoZSB0cmFuc2Zvcm0gbm9kZSBhbmQgdGhlIHByaW1pdGl2ZSBtZXNoZXMgdG8gdGhlIG5ldyB2YWx1ZS5cbiAgICAgICAgICAgIGlmIChub2RlLmV4dGVuc2lvbnM/LktIUl9ub2RlX3Zpc2liaWxpdHkpIHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5leHRlbnNpb25zPy5LSFJfbm9kZV92aXNpYmlsaXR5LnZpc2libGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgKG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlIGFzIEFic3RyYWN0TWVzaCkuaXNWaXNpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbm9kZS5fcHJpbWl0aXZlQmFieWxvbk1lc2hlcz8uZm9yRWFjaCgobWVzaCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzaC5pc1Zpc2libGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcbiAgICB9XG59XG5cbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfbm9kZV92aXNpYmlsaXR5KGxvYWRlcikpO1xuIiwiaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IEdMVEZMb2FkZXIsIEFycmF5SXRlbSB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSVRleHR1cmUgfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBCYXNlVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy9iYXNlVGV4dHVyZVwiO1xyXG5pbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSVGV4dHVyZUJhc2lzVSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl90ZXh0dXJlX2Jhc2lzdVwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfdGV4dHVyZV9iYXNpc3UgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl90ZXh0dXJlX2Jhc2lzdVwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl90ZXh0dXJlX2Jhc2lzdS9SRUFETUUubWQpXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfdGV4dHVyZV9iYXNpc3UgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKiogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLiAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSBsb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9sb2FkVGV4dHVyZUFzeW5jKGNvbnRleHQ6IHN0cmluZywgdGV4dHVyZTogSVRleHR1cmUsIGFzc2lnbjogKGJhYnlsb25UZXh0dXJlOiBCYXNlVGV4dHVyZSkgPT4gdm9pZCk6IE51bGxhYmxlPFByb21pc2U8QmFzZVRleHR1cmU+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElLSFJUZXh0dXJlQmFzaXNVLCBCYXNlVGV4dHVyZT4oY29udGV4dCwgdGV4dHVyZSwgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHNhbXBsZXIgPSB0ZXh0dXJlLnNhbXBsZXIgPT0gdW5kZWZpbmVkID8gR0xURkxvYWRlci5EZWZhdWx0U2FtcGxlciA6IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vc2FtcGxlcmAsIHRoaXMuX2xvYWRlci5nbHRmLnNhbXBsZXJzLCB0ZXh0dXJlLnNhbXBsZXIpO1xyXG4gICAgICAgICAgICBjb25zdCBpbWFnZSA9IEFycmF5SXRlbS5HZXQoYCR7ZXh0ZW5zaW9uQ29udGV4dH0vc291cmNlYCwgdGhpcy5fbG9hZGVyLmdsdGYuaW1hZ2VzLCBleHRlbnNpb24uc291cmNlKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRlci5fY3JlYXRlVGV4dHVyZUFzeW5jKFxyXG4gICAgICAgICAgICAgICAgY29udGV4dCxcclxuICAgICAgICAgICAgICAgIHNhbXBsZXIsXHJcbiAgICAgICAgICAgICAgICBpbWFnZSxcclxuICAgICAgICAgICAgICAgIChiYWJ5bG9uVGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGFzc2lnbihiYWJ5bG9uVGV4dHVyZSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgdGV4dHVyZS5fdGV4dHVyZUluZm8ubm9uQ29sb3JEYXRhID8geyB1c2VSR0JBSWZBU1RDQkM3Tm90QXZhaWxhYmxlV2hlblVBU1RDOiB0cnVlIH0gOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICAhdGV4dHVyZS5fdGV4dHVyZUluZm8ubm9uQ29sb3JEYXRhXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl90ZXh0dXJlX2Jhc2lzdShsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB0eXBlIHsgQmFzZVRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvYmFzZVRleHR1cmVcIjtcclxuaW1wb3J0IHsgVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy90ZXh0dXJlXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IElUZXh0dXJlSW5mbyB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSUtIUlRleHR1cmVUcmFuc2Zvcm0gfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfdGV4dHVyZV90cmFuc2Zvcm1cIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX3RleHR1cmVfdHJhbnNmb3JtIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJLSFJfdGV4dHVyZV90cmFuc2Zvcm1cIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfdGV4dHVyZV90cmFuc2Zvcm0vUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX3RleHR1cmVfdHJhbnNmb3JtIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkVGV4dHVyZUluZm9Bc3luYyhjb250ZXh0OiBzdHJpbmcsIHRleHR1cmVJbmZvOiBJVGV4dHVyZUluZm8sIGFzc2lnbjogKGJhYnlsb25UZXh0dXJlOiBCYXNlVGV4dHVyZSkgPT4gdm9pZCk6IE51bGxhYmxlPFByb21pc2U8QmFzZVRleHR1cmU+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElLSFJUZXh0dXJlVHJhbnNmb3JtLCBCYXNlVGV4dHVyZT4oY29udGV4dCwgdGV4dHVyZUluZm8sIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGVyLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGNvbnRleHQsIHRleHR1cmVJbmZvLCAoYmFieWxvblRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICghKGJhYnlsb25UZXh0dXJlIGluc3RhbmNlb2YgVGV4dHVyZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXh0ZW5zaW9uQ29udGV4dH06IFRleHR1cmUgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbi5vZmZzZXQpIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uVGV4dHVyZS51T2Zmc2V0ID0gZXh0ZW5zaW9uLm9mZnNldFswXTtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uVGV4dHVyZS52T2Zmc2V0ID0gZXh0ZW5zaW9uLm9mZnNldFsxXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBBbHdheXMgcm90YXRlIGFyb3VuZCB0aGUgb3JpZ2luLlxyXG4gICAgICAgICAgICAgICAgYmFieWxvblRleHR1cmUudVJvdGF0aW9uQ2VudGVyID0gMDtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25UZXh0dXJlLnZSb3RhdGlvbkNlbnRlciA9IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbi5yb3RhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25UZXh0dXJlLndBbmcgPSAtZXh0ZW5zaW9uLnJvdGF0aW9uO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChleHRlbnNpb24uc2NhbGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uVGV4dHVyZS51U2NhbGUgPSBleHRlbnNpb24uc2NhbGVbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvblRleHR1cmUudlNjYWxlID0gZXh0ZW5zaW9uLnNjYWxlWzFdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChleHRlbnNpb24udGV4Q29vcmQgIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvblRleHR1cmUuY29vcmRpbmF0ZXNJbmRleCA9IGV4dGVuc2lvbi50ZXhDb29yZDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBhc3NpZ24oYmFieWxvblRleHR1cmUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX3RleHR1cmVfdHJhbnNmb3JtKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHR5cGUgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSWG1wSnNvbkxkX0dsdGYsIElLSFJYbXBKc29uTGRfTm9kZSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl94bXBfanNvbl9sZFwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfeG1wX2pzb25fbGQgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl94bXBfanNvbl9sZFwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl94bXBfanNvbl9sZC9SRUFETUUubWQpXHJcbiAqIEBzaW5jZSA1LjAuMFxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX3htcF9qc29uX2xkIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBhIG51bWJlciB0aGF0IGRldGVybWluZXMgdGhlIG9yZGVyIHRoZSBleHRlbnNpb25zIGFyZSBhcHBsaWVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb3JkZXIgPSAxMDA7XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsZWQgYWZ0ZXIgdGhlIGxvYWRlciBzdGF0ZSBjaGFuZ2VzIHRvIExPQURJTkcuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkxvYWRpbmcoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2xvYWRlci5yb290QmFieWxvbk1lc2ggPT09IG51bGwpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgeG1wX2dsdGYgPSB0aGlzLl9sb2FkZXIuZ2x0Zi5leHRlbnNpb25zPy5LSFJfeG1wX2pzb25fbGQgYXMgSUtIUlhtcEpzb25MZF9HbHRmO1xyXG4gICAgICAgIGNvbnN0IHhtcF9ub2RlID0gdGhpcy5fbG9hZGVyLmdsdGYuYXNzZXQ/LmV4dGVuc2lvbnM/LktIUl94bXBfanNvbl9sZCBhcyBJS0hSWG1wSnNvbkxkX05vZGU7XHJcbiAgICAgICAgaWYgKHhtcF9nbHRmICYmIHhtcF9ub2RlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhY2tldCA9ICt4bXBfbm9kZS5wYWNrZXQ7XHJcbiAgICAgICAgICAgIGlmICh4bXBfZ2x0Zi5wYWNrZXRzICYmIHBhY2tldCA8IHhtcF9nbHRmLnBhY2tldHMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIucm9vdEJhYnlsb25NZXNoLm1ldGFkYXRhID0gdGhpcy5fbG9hZGVyLnJvb3RCYWJ5bG9uTWVzaC5tZXRhZGF0YSB8fCB7fTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5yb290QmFieWxvbk1lc2gubWV0YWRhdGEueG1wID0geG1wX2dsdGYucGFja2V0c1twYWNrZXRdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfeG1wX2pzb25fbGQobG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBWZWN0b3IzIH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC52ZWN0b3JcIjtcclxuaW1wb3J0IHsgVG9vbHMgfSBmcm9tIFwiY29yZS9NaXNjL3Rvb2xzXCI7XHJcbmltcG9ydCB0eXBlIHsgQW5pbWF0aW9uR3JvdXAgfSBmcm9tIFwiY29yZS9BbmltYXRpb25zL2FuaW1hdGlvbkdyb3VwXCI7XHJcbmltcG9ydCB7IEFuaW1hdGlvbkV2ZW50IH0gZnJvbSBcImNvcmUvQW5pbWF0aW9ucy9hbmltYXRpb25FdmVudFwiO1xyXG5pbXBvcnQgdHlwZSB7IFRyYW5zZm9ybU5vZGUgfSBmcm9tIFwiY29yZS9NZXNoZXMvdHJhbnNmb3JtTm9kZVwiO1xyXG5pbXBvcnQgeyBTb3VuZCB9IGZyb20gXCJjb3JlL0F1ZGlvL3NvdW5kXCI7XHJcbmltcG9ydCB7IFdlaWdodGVkU291bmQgfSBmcm9tIFwiY29yZS9BdWRpby93ZWlnaHRlZHNvdW5kXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IElBcnJheUl0ZW0sIElTY2VuZSwgSU5vZGUsIElBbmltYXRpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IEdMVEZMb2FkZXIsIEFycmF5SXRlbSB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSU1TRlRBdWRpb0VtaXR0ZXJfQ2xpcCwgSU1TRlRBdWRpb0VtaXR0ZXJfRW1pdHRlciwgSU1TRlRBdWRpb0VtaXR0ZXJfRW1pdHRlcnNSZWZlcmVuY2UsIElNU0ZUQXVkaW9FbWl0dGVyX0FuaW1hdGlvbkV2ZW50IH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyBJTVNGVEF1ZGlvRW1pdHRlcl9BbmltYXRpb25FdmVudEFjdGlvbiB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmltcG9ydCBcImNvcmUvQXVkaW8vYXVkaW9TY2VuZUNvbXBvbmVudFwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiTVNGVF9hdWRpb19lbWl0dGVyXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIE1TRlRfYXVkaW9fZW1pdHRlciBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiTVNGVF9hdWRpb19lbWl0dGVyXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuaW50ZXJmYWNlIElMb2FkZXJDbGlwIGV4dGVuZHMgSU1TRlRBdWRpb0VtaXR0ZXJfQ2xpcCwgSUFycmF5SXRlbSB7XHJcbiAgICBfb2JqZWN0VVJMPzogUHJvbWlzZTxzdHJpbmc+O1xyXG59XHJcblxyXG5pbnRlcmZhY2UgSUxvYWRlckVtaXR0ZXIgZXh0ZW5kcyBJTVNGVEF1ZGlvRW1pdHRlcl9FbWl0dGVyLCBJQXJyYXlJdGVtIHtcclxuICAgIF9iYWJ5bG9uRGF0YT86IHtcclxuICAgICAgICBzb3VuZD86IFdlaWdodGVkU291bmQ7XHJcbiAgICAgICAgbG9hZGVkOiBQcm9taXNlPHZvaWQ+O1xyXG4gICAgfTtcclxuICAgIF9iYWJ5bG9uU291bmRzOiBTb3VuZFtdO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgSU1TRlRBdWRpb0VtaXR0ZXIge1xyXG4gICAgY2xpcHM6IElMb2FkZXJDbGlwW107XHJcbiAgICBlbWl0dGVyczogSUxvYWRlckVtaXR0ZXJbXTtcclxufVxyXG5cclxuaW50ZXJmYWNlIElMb2FkZXJBbmltYXRpb25FdmVudCBleHRlbmRzIElNU0ZUQXVkaW9FbWl0dGVyX0FuaW1hdGlvbkV2ZW50LCBJQXJyYXlJdGVtIHt9XHJcblxyXG5pbnRlcmZhY2UgSUxvYWRlckFuaW1hdGlvbkV2ZW50cyB7XHJcbiAgICBldmVudHM6IElMb2FkZXJBbmltYXRpb25FdmVudFtdO1xyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9uYWphZG9qby9nbFRGL2Jsb2IvTVNGVF9hdWRpb19lbWl0dGVyL2V4dGVuc2lvbnMvMi4wL1ZlbmRvci9NU0ZUX2F1ZGlvX2VtaXR0ZXIvUkVBRE1FLm1kKVxyXG4gKiAhISEgRXhwZXJpbWVudGFsIEV4dGVuc2lvbiBTdWJqZWN0IHRvIENoYW5nZXMgISEhXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBNU0ZUX2F1ZGlvX2VtaXR0ZXIgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG4gICAgcHJpdmF0ZSBfY2xpcHM6IEFycmF5PElMb2FkZXJDbGlwPjtcclxuICAgIHByaXZhdGUgX2VtaXR0ZXJzOiBBcnJheTxJTG9hZGVyRW1pdHRlcj47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgICAgICAodGhpcy5fY2xpcHMgYXMgYW55KSA9IG51bGw7XHJcbiAgICAgICAgKHRoaXMuX2VtaXR0ZXJzIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBvbkxvYWRpbmcoKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9ucyA9IHRoaXMuX2xvYWRlci5nbHRmLmV4dGVuc2lvbnM7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvbnMgJiYgZXh0ZW5zaW9uc1t0aGlzLm5hbWVdKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IGV4dGVuc2lvbnNbdGhpcy5uYW1lXSBhcyBJTVNGVEF1ZGlvRW1pdHRlcjtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2NsaXBzID0gZXh0ZW5zaW9uLmNsaXBzO1xyXG4gICAgICAgICAgICB0aGlzLl9lbWl0dGVycyA9IGV4dGVuc2lvbi5lbWl0dGVycztcclxuXHJcbiAgICAgICAgICAgIEFycmF5SXRlbS5Bc3NpZ24odGhpcy5fY2xpcHMpO1xyXG4gICAgICAgICAgICBBcnJheUl0ZW0uQXNzaWduKHRoaXMuX2VtaXR0ZXJzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRTY2VuZUFzeW5jKGNvbnRleHQ6IHN0cmluZywgc2NlbmU6IElTY2VuZSk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SU1TRlRBdWRpb0VtaXR0ZXJfRW1pdHRlcnNSZWZlcmVuY2U+KGNvbnRleHQsIHNjZW5lLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG5cclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkZXIubG9hZFNjZW5lQXN5bmMoY29udGV4dCwgc2NlbmUpKTtcclxuXHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgZW1pdHRlckluZGV4IG9mIGV4dGVuc2lvbi5lbWl0dGVycykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZW1pdHRlciA9IEFycmF5SXRlbS5HZXQoYCR7ZXh0ZW5zaW9uQ29udGV4dH0vZW1pdHRlcnNgLCB0aGlzLl9lbWl0dGVycywgZW1pdHRlckluZGV4KTtcclxuICAgICAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAgICAgICBlbWl0dGVyLnJlZkRpc3RhbmNlICE9IHVuZGVmaW5lZCB8fFxyXG4gICAgICAgICAgICAgICAgICAgIGVtaXR0ZXIubWF4RGlzdGFuY2UgIT0gdW5kZWZpbmVkIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgZW1pdHRlci5yb2xsb2ZmRmFjdG9yICE9IHVuZGVmaW5lZCB8fFxyXG4gICAgICAgICAgICAgICAgICAgIGVtaXR0ZXIuZGlzdGFuY2VNb2RlbCAhPSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgICAgICAgICAgICBlbWl0dGVyLmlubmVyQW5nbGUgIT0gdW5kZWZpbmVkIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgZW1pdHRlci5vdXRlckFuZ2xlICE9IHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2V4dGVuc2lvbkNvbnRleHR9OiBEaXJlY3Rpb24gb3IgRGlzdGFuY2UgcHJvcGVydGllcyBhcmUgbm90IGFsbG93ZWQgb24gZW1pdHRlcnMgYXR0YWNoZWQgdG8gYSBzY2VuZWApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZEVtaXR0ZXJBc3luYyhgJHtleHRlbnNpb25Db250ZXh0fS9lbWl0dGVycy8ke2VtaXR0ZXIuaW5kZXh9YCwgZW1pdHRlcikpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTm9kZUFzeW5jKGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU5vZGUsIGFzc2lnbjogKGJhYnlsb25UcmFuc2Zvcm1Ob2RlOiBUcmFuc2Zvcm1Ob2RlKSA9PiB2b2lkKTogTnVsbGFibGU8UHJvbWlzZTxUcmFuc2Zvcm1Ob2RlPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRlbnNpb25Bc3luYzxJTVNGVEF1ZGlvRW1pdHRlcl9FbWl0dGVyc1JlZmVyZW5jZSwgVHJhbnNmb3JtTm9kZT4oY29udGV4dCwgbm9kZSwgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXJcclxuICAgICAgICAgICAgICAgIC5sb2FkTm9kZUFzeW5jKGV4dGVuc2lvbkNvbnRleHQsIG5vZGUsIChiYWJ5bG9uTWVzaCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZW1pdHRlckluZGV4IG9mIGV4dGVuc2lvbi5lbWl0dGVycykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlbWl0dGVyID0gQXJyYXlJdGVtLkdldChgJHtleHRlbnNpb25Db250ZXh0fS9lbWl0dGVyc2AsIHRoaXMuX2VtaXR0ZXJzLCBlbWl0dGVySW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZEVtaXR0ZXJBc3luYyhgJHtleHRlbnNpb25Db250ZXh0fS9lbWl0dGVycy8ke2VtaXR0ZXIuaW5kZXh9YCwgZW1pdHRlcikudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzb3VuZCBvZiBlbWl0dGVyLl9iYWJ5bG9uU291bmRzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdW5kLmF0dGFjaFRvTWVzaChiYWJ5bG9uTWVzaCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbWl0dGVyLmlubmVyQW5nbGUgIT0gdW5kZWZpbmVkIHx8IGVtaXR0ZXIub3V0ZXJBbmdsZSAhPSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdW5kLnNldExvY2FsRGlyZWN0aW9uVG9NZXNoKFZlY3RvcjMuRm9yd2FyZCgpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdW5kLnNldERpcmVjdGlvbmFsQ29uZShcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyICogVG9vbHMuVG9EZWdyZWVzKGVtaXR0ZXIuaW5uZXJBbmdsZSA9PSB1bmRlZmluZWQgPyBNYXRoLlBJIDogZW1pdHRlci5pbm5lckFuZ2xlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyICogVG9vbHMuVG9EZWdyZWVzKGVtaXR0ZXIub3V0ZXJBbmdsZSA9PSB1bmRlZmluZWQgPyBNYXRoLlBJIDogZW1pdHRlci5vdXRlckFuZ2xlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGFzc2lnbihiYWJ5bG9uTWVzaCk7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLnRoZW4oKGJhYnlsb25NZXNoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJhYnlsb25NZXNoO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRBbmltYXRpb25Bc3luYyhjb250ZXh0OiBzdHJpbmcsIGFuaW1hdGlvbjogSUFuaW1hdGlvbik6IE51bGxhYmxlPFByb21pc2U8QW5pbWF0aW9uR3JvdXA+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElMb2FkZXJBbmltYXRpb25FdmVudHMsIEFuaW1hdGlvbkdyb3VwPihjb250ZXh0LCBhbmltYXRpb24sIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGVyLmxvYWRBbmltYXRpb25Bc3luYyhjb250ZXh0LCBhbmltYXRpb24pLnRoZW4oKGJhYnlsb25BbmltYXRpb25Hcm91cCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG5cclxuICAgICAgICAgICAgICAgIEFycmF5SXRlbS5Bc3NpZ24oZXh0ZW5zaW9uLmV2ZW50cyk7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIGV4dGVuc2lvbi5ldmVudHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRBbmltYXRpb25FdmVudEFzeW5jKGAke2V4dGVuc2lvbkNvbnRleHR9L2V2ZW50cy8ke2V2ZW50LmluZGV4fWAsIGNvbnRleHQsIGFuaW1hdGlvbiwgZXZlbnQsIGJhYnlsb25BbmltYXRpb25Hcm91cCkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJhYnlsb25BbmltYXRpb25Hcm91cDtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkQ2xpcEFzeW5jKGNvbnRleHQ6IHN0cmluZywgY2xpcDogSUxvYWRlckNsaXApOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgICAgIGlmIChjbGlwLl9vYmplY3RVUkwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGNsaXAuX29iamVjdFVSTDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBwcm9taXNlOiBQcm9taXNlPEFycmF5QnVmZmVyVmlldz47XHJcbiAgICAgICAgaWYgKGNsaXAudXJpKSB7XHJcbiAgICAgICAgICAgIHByb21pc2UgPSB0aGlzLl9sb2FkZXIubG9hZFVyaUFzeW5jKGNvbnRleHQsIGNsaXAsIGNsaXAudXJpKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBidWZmZXJWaWV3ID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9idWZmZXJWaWV3YCwgdGhpcy5fbG9hZGVyLmdsdGYuYnVmZmVyVmlld3MsIGNsaXAuYnVmZmVyVmlldyk7XHJcbiAgICAgICAgICAgIHByb21pc2UgPSB0aGlzLl9sb2FkZXIubG9hZEJ1ZmZlclZpZXdBc3luYyhgL2J1ZmZlclZpZXdzLyR7YnVmZmVyVmlldy5pbmRleH1gLCBidWZmZXJWaWV3KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNsaXAuX29iamVjdFVSTCA9IHByb21pc2UudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihbZGF0YV0sIHsgdHlwZTogY2xpcC5taW1lVHlwZSB9KSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBjbGlwLl9vYmplY3RVUkw7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZEVtaXR0ZXJBc3luYyhjb250ZXh0OiBzdHJpbmcsIGVtaXR0ZXI6IElMb2FkZXJFbWl0dGVyKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgZW1pdHRlci5fYmFieWxvblNvdW5kcyA9IGVtaXR0ZXIuX2JhYnlsb25Tb3VuZHMgfHwgW107XHJcbiAgICAgICAgaWYgKCFlbWl0dGVyLl9iYWJ5bG9uRGF0YSkge1xyXG4gICAgICAgICAgICBjb25zdCBjbGlwUHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG4gICAgICAgICAgICBjb25zdCBuYW1lID0gZW1pdHRlci5uYW1lIHx8IGBlbWl0dGVyJHtlbWl0dGVyLmluZGV4fWA7XHJcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XHJcbiAgICAgICAgICAgICAgICBsb29wOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGF1dG9wbGF5OiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIHZvbHVtZTogZW1pdHRlci52b2x1bWUgPT0gdW5kZWZpbmVkID8gMSA6IGVtaXR0ZXIudm9sdW1lLFxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbWl0dGVyLmNsaXBzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjbGlwQ29udGV4dCA9IGAvZXh0ZW5zaW9ucy8ke3RoaXMubmFtZX0vY2xpcHNgO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2xpcCA9IEFycmF5SXRlbS5HZXQoY2xpcENvbnRleHQsIHRoaXMuX2NsaXBzLCBlbWl0dGVyLmNsaXBzW2ldLmNsaXApO1xyXG4gICAgICAgICAgICAgICAgY2xpcFByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZENsaXBBc3luYyhgJHtjbGlwQ29udGV4dH0vJHtlbWl0dGVyLmNsaXBzW2ldLmNsaXB9YCwgY2xpcCkudGhlbigob2JqZWN0VVJMOiBzdHJpbmcpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc291bmQgPSAoZW1pdHRlci5fYmFieWxvblNvdW5kc1tpXSA9IG5ldyBTb3VuZChuYW1lLCBvYmplY3RVUkwsIHRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmUsIG51bGwsIG9wdGlvbnMpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc291bmQucmVmRGlzdGFuY2UgPSBlbWl0dGVyLnJlZkRpc3RhbmNlIHx8IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNvdW5kLm1heERpc3RhbmNlID0gZW1pdHRlci5tYXhEaXN0YW5jZSB8fCAyNTY7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNvdW5kLnJvbGxvZmZGYWN0b3IgPSBlbWl0dGVyLnJvbGxvZmZGYWN0b3IgfHwgMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc291bmQuZGlzdGFuY2VNb2RlbCA9IGVtaXR0ZXIuZGlzdGFuY2VNb2RlbCB8fCBcImV4cG9uZW50aWFsXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSBQcm9taXNlLmFsbChjbGlwUHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgd2VpZ2h0cyA9IGVtaXR0ZXIuY2xpcHMubWFwKChjbGlwKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNsaXAud2VpZ2h0IHx8IDE7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHdlaWdodGVkU291bmQgPSBuZXcgV2VpZ2h0ZWRTb3VuZChlbWl0dGVyLmxvb3AgfHwgZmFsc2UsIGVtaXR0ZXIuX2JhYnlsb25Tb3VuZHMsIHdlaWdodHMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGVtaXR0ZXIuaW5uZXJBbmdsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdlaWdodGVkU291bmQuZGlyZWN0aW9uYWxDb25lSW5uZXJBbmdsZSA9IDIgKiBUb29scy5Ub0RlZ3JlZXMoZW1pdHRlci5pbm5lckFuZ2xlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChlbWl0dGVyLm91dGVyQW5nbGUpIHtcclxuICAgICAgICAgICAgICAgICAgICB3ZWlnaHRlZFNvdW5kLmRpcmVjdGlvbmFsQ29uZU91dGVyQW5nbGUgPSAyICogVG9vbHMuVG9EZWdyZWVzKGVtaXR0ZXIub3V0ZXJBbmdsZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoZW1pdHRlci52b2x1bWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB3ZWlnaHRlZFNvdW5kLnZvbHVtZSA9IGVtaXR0ZXIudm9sdW1lO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZW1pdHRlci5fYmFieWxvbkRhdGEhLnNvdW5kID0gd2VpZ2h0ZWRTb3VuZDtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICBlbWl0dGVyLl9iYWJ5bG9uRGF0YSA9IHtcclxuICAgICAgICAgICAgICAgIGxvYWRlZDogcHJvbWlzZSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBlbWl0dGVyLl9iYWJ5bG9uRGF0YS5sb2FkZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZ2V0RXZlbnRBY3Rpb24oXHJcbiAgICAgICAgY29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIHNvdW5kOiBXZWlnaHRlZFNvdW5kLFxyXG4gICAgICAgIGFjdGlvbjogSU1TRlRBdWRpb0VtaXR0ZXJfQW5pbWF0aW9uRXZlbnRBY3Rpb24sXHJcbiAgICAgICAgdGltZTogbnVtYmVyLFxyXG4gICAgICAgIHN0YXJ0T2Zmc2V0PzogbnVtYmVyXHJcbiAgICApOiAoY3VycmVudEZyYW1lOiBudW1iZXIpID0+IHZvaWQge1xyXG4gICAgICAgIHN3aXRjaCAoYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIGNhc2UgSU1TRlRBdWRpb0VtaXR0ZXJfQW5pbWF0aW9uRXZlbnRBY3Rpb24ucGxheToge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIChjdXJyZW50RnJhbWU6IG51bWJlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZyYW1lT2Zmc2V0ID0gKHN0YXJ0T2Zmc2V0IHx8IDApICsgKGN1cnJlbnRGcmFtZSAtIHRpbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNvdW5kLnBsYXkoZnJhbWVPZmZzZXQpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIElNU0ZUQXVkaW9FbWl0dGVyX0FuaW1hdGlvbkV2ZW50QWN0aW9uLnN0b3A6IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgc291bmQuc3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIElNU0ZUQXVkaW9FbWl0dGVyX0FuaW1hdGlvbkV2ZW50QWN0aW9uLnBhdXNlOiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHNvdW5kLnBhdXNlKCk7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogVW5zdXBwb3J0ZWQgYWN0aW9uICR7YWN0aW9ufWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRBbmltYXRpb25FdmVudEFzeW5jKFxyXG4gICAgICAgIGNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBhbmltYXRpb25Db250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgYW5pbWF0aW9uOiBJQW5pbWF0aW9uLFxyXG4gICAgICAgIGV2ZW50OiBJTG9hZGVyQW5pbWF0aW9uRXZlbnQsXHJcbiAgICAgICAgYmFieWxvbkFuaW1hdGlvbkdyb3VwOiBBbmltYXRpb25Hcm91cFxyXG4gICAgKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKGJhYnlsb25BbmltYXRpb25Hcm91cC50YXJnZXRlZEFuaW1hdGlvbnMubGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBiYWJ5bG9uQW5pbWF0aW9uID0gYmFieWxvbkFuaW1hdGlvbkdyb3VwLnRhcmdldGVkQW5pbWF0aW9uc1swXTtcclxuICAgICAgICBjb25zdCBlbWl0dGVySW5kZXggPSBldmVudC5lbWl0dGVyO1xyXG4gICAgICAgIGNvbnN0IGVtaXR0ZXIgPSBBcnJheUl0ZW0uR2V0KGAvZXh0ZW5zaW9ucy8ke3RoaXMubmFtZX0vZW1pdHRlcnNgLCB0aGlzLl9lbWl0dGVycywgZW1pdHRlckluZGV4KTtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbG9hZEVtaXR0ZXJBc3luYyhjb250ZXh0LCBlbWl0dGVyKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgY29uc3Qgc291bmQgPSBlbWl0dGVyLl9iYWJ5bG9uRGF0YSEuc291bmQ7XHJcbiAgICAgICAgICAgIGlmIChzb3VuZCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYmFieWxvbkFuaW1hdGlvbkV2ZW50ID0gbmV3IEFuaW1hdGlvbkV2ZW50KGV2ZW50LnRpbWUsIHRoaXMuX2dldEV2ZW50QWN0aW9uKGNvbnRleHQsIHNvdW5kLCBldmVudC5hY3Rpb24sIGV2ZW50LnRpbWUsIGV2ZW50LnN0YXJ0T2Zmc2V0KSk7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uQW5pbWF0aW9uLmFuaW1hdGlvbi5hZGRFdmVudChiYWJ5bG9uQW5pbWF0aW9uRXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgLy8gTWFrZSBzdXJlIGFsbCBzdGFydGVkIGF1ZGlvIHN0b3BzIHdoZW4gdGhpcyBhbmltYXRpb24gaXMgdGVybWluYXRlZC5cclxuICAgICAgICAgICAgICAgIGJhYnlsb25BbmltYXRpb25Hcm91cC5vbkFuaW1hdGlvbkdyb3VwRW5kT2JzZXJ2YWJsZS5hZGQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHNvdW5kLnN0b3AoKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbkFuaW1hdGlvbkdyb3VwLm9uQW5pbWF0aW9uR3JvdXBQYXVzZU9ic2VydmFibGUuYWRkKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBzb3VuZC5wYXVzZSgpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgTVNGVF9hdWRpb19lbWl0dGVyKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gXCJjb3JlL01pc2Mvb2JzZXJ2YWJsZVwiO1xyXG5pbXBvcnQgeyBEZWZlcnJlZCB9IGZyb20gXCJjb3JlL01pc2MvZGVmZXJyZWRcIjtcclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IFRyYW5zZm9ybU5vZGUgfSBmcm9tIFwiY29yZS9NZXNoZXMvdHJhbnNmb3JtTm9kZVwiO1xyXG5pbXBvcnQgdHlwZSB7IE1lc2ggfSBmcm9tIFwiY29yZS9NZXNoZXMvbWVzaFwiO1xyXG5pbXBvcnQgdHlwZSB7IEJhc2VUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL2Jhc2VUZXh0dXJlXCI7XHJcbmltcG9ydCB0eXBlIHsgSU5vZGUsIElNYXRlcmlhbCwgSUJ1ZmZlciwgSVNjZW5lIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyLCBBcnJheUl0ZW0gfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IElQcm9wZXJ0eSwgSU1TRlRMT0QgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJNU0ZUX2xvZFwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBNU0ZUX2xvZCBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiTVNGVF9sb2RcIl06IFBhcnRpYWw8e1xyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogTWF4aW11bSBudW1iZXIgb2YgTE9EcyB0byBsb2FkLCBzdGFydGluZyBmcm9tIHRoZSBsb3dlc3QgTE9ELlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgbWF4TE9Ec1RvTG9hZDogbnVtYmVyO1xyXG4gICAgICAgIH0+O1xyXG4gICAgfVxyXG59XHJcblxyXG5pbnRlcmZhY2UgSUJ1ZmZlckluZm8ge1xyXG4gICAgc3RhcnQ6IG51bWJlcjtcclxuICAgIGVuZDogbnVtYmVyO1xyXG4gICAgbG9hZGVkOiBEZWZlcnJlZDxBcnJheUJ1ZmZlclZpZXc+O1xyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvVmVuZG9yL01TRlRfbG9kL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIE1TRlRfbG9kIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBhIG51bWJlciB0aGF0IGRldGVybWluZXMgdGhlIG9yZGVyIHRoZSBleHRlbnNpb25zIGFyZSBhcHBsaWVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb3JkZXIgPSAxMDA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYXhpbXVtIG51bWJlciBvZiBMT0RzIHRvIGxvYWQsIHN0YXJ0aW5nIGZyb20gdGhlIGxvd2VzdCBMT0QuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBtYXhMT0RzVG9Mb2FkID0gMTA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPYnNlcnZhYmxlIHJhaXNlZCB3aGVuIGFsbCBub2RlIExPRHMgb2Ygb25lIGxldmVsIGFyZSBsb2FkZWQuXHJcbiAgICAgKiBUaGUgZXZlbnQgZGF0YSBpcyB0aGUgaW5kZXggb2YgdGhlIGxvYWRlZCBMT0Qgc3RhcnRpbmcgZnJvbSB6ZXJvLlxyXG4gICAgICogRGlzcG9zZSB0aGUgbG9hZGVyIHRvIGNhbmNlbCB0aGUgbG9hZGluZyBvZiB0aGUgbmV4dCBsZXZlbCBvZiBMT0RzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25Ob2RlTE9Ec0xvYWRlZE9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZTxudW1iZXI+KCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPYnNlcnZhYmxlIHJhaXNlZCB3aGVuIGFsbCBtYXRlcmlhbCBMT0RzIG9mIG9uZSBsZXZlbCBhcmUgbG9hZGVkLlxyXG4gICAgICogVGhlIGV2ZW50IGRhdGEgaXMgdGhlIGluZGV4IG9mIHRoZSBsb2FkZWQgTE9EIHN0YXJ0aW5nIGZyb20gemVyby5cclxuICAgICAqIERpc3Bvc2UgdGhlIGxvYWRlciB0byBjYW5jZWwgdGhlIGxvYWRpbmcgb2YgdGhlIG5leHQgbGV2ZWwgb2YgTE9Ecy5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uTWF0ZXJpYWxMT0RzTG9hZGVkT2JzZXJ2YWJsZSA9IG5ldyBPYnNlcnZhYmxlPG51bWJlcj4oKTtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgcHJpdmF0ZSBfYnVmZmVyTE9EcyA9IG5ldyBBcnJheTxJQnVmZmVySW5mbz4oKTtcclxuXHJcbiAgICBwcml2YXRlIF9ub2RlSW5kZXhMT0Q6IE51bGxhYmxlPG51bWJlcj4gPSBudWxsO1xyXG4gICAgcHJpdmF0ZSBfbm9kZVNpZ25hbExPRHMgPSBuZXcgQXJyYXk8RGVmZXJyZWQ8dm9pZD4+KCk7XHJcbiAgICBwcml2YXRlIF9ub2RlUHJvbWlzZUxPRHMgPSBuZXcgQXJyYXk8QXJyYXk8UHJvbWlzZTxhbnk+Pj4oKTtcclxuICAgIHByaXZhdGUgX25vZGVCdWZmZXJMT0RzID0gbmV3IEFycmF5PElCdWZmZXJJbmZvPigpO1xyXG5cclxuICAgIHByaXZhdGUgX21hdGVyaWFsSW5kZXhMT0Q6IE51bGxhYmxlPG51bWJlcj4gPSBudWxsO1xyXG4gICAgcHJpdmF0ZSBfbWF0ZXJpYWxTaWduYWxMT0RzID0gbmV3IEFycmF5PERlZmVycmVkPHZvaWQ+PigpO1xyXG4gICAgcHJpdmF0ZSBfbWF0ZXJpYWxQcm9taXNlTE9EcyA9IG5ldyBBcnJheTxBcnJheTxQcm9taXNlPGFueT4+PigpO1xyXG4gICAgcHJpdmF0ZSBfbWF0ZXJpYWxCdWZmZXJMT0RzID0gbmV3IEFycmF5PElCdWZmZXJJbmZvPigpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICAvLyBPcHRpb25zIHRha2VzIHByZWNlZGVuY2UuIFRoZSBtYXhMT0RzVG9Mb2FkIGV4dGVuc2lvbiBwcm9wZXJ0eSBpcyByZXRhaW5lZCBmb3IgYmFjayBjb21wYXQuXHJcbiAgICAgICAgLy8gRm9yIG5ldyBleHRlbnNpb25zLCB0aGV5IHNob3VsZCBvbmx5IHVzZSBvcHRpb25zLlxyXG4gICAgICAgIHRoaXMubWF4TE9Ec1RvTG9hZCA9IHRoaXMuX2xvYWRlci5wYXJlbnQuZXh0ZW5zaW9uT3B0aW9uc1tOQU1FXT8ubWF4TE9Ec1RvTG9hZCA/PyB0aGlzLm1heExPRHNUb0xvYWQ7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG5cclxuICAgICAgICB0aGlzLl9ub2RlSW5kZXhMT0QgPSBudWxsO1xyXG4gICAgICAgIHRoaXMuX25vZGVTaWduYWxMT0RzLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgdGhpcy5fbm9kZVByb21pc2VMT0RzLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgdGhpcy5fbm9kZUJ1ZmZlckxPRHMubGVuZ3RoID0gMDtcclxuXHJcbiAgICAgICAgdGhpcy5fbWF0ZXJpYWxJbmRleExPRCA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5fbWF0ZXJpYWxTaWduYWxMT0RzLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgdGhpcy5fbWF0ZXJpYWxQcm9taXNlTE9Ecy5sZW5ndGggPSAwO1xyXG4gICAgICAgIHRoaXMuX21hdGVyaWFsQnVmZmVyTE9Ecy5sZW5ndGggPSAwO1xyXG5cclxuICAgICAgICB0aGlzLm9uTWF0ZXJpYWxMT0RzTG9hZGVkT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG4gICAgICAgIHRoaXMub25Ob2RlTE9Ec0xvYWRlZE9ic2VydmFibGUuY2xlYXIoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgb25SZWFkeSgpOiB2b2lkIHtcclxuICAgICAgICBmb3IgKGxldCBpbmRleExPRCA9IDA7IGluZGV4TE9EIDwgdGhpcy5fbm9kZVByb21pc2VMT0RzLmxlbmd0aDsgaW5kZXhMT0QrKykge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlID0gUHJvbWlzZS5hbGwodGhpcy5fbm9kZVByb21pc2VMT0RzW2luZGV4TE9EXSkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXhMT0QgIT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIuZW5kUGVyZm9ybWFuY2VDb3VudGVyKGBOb2RlIExPRCAke2luZGV4TE9EfWApO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2coYExvYWRlZCBub2RlIExPRCAke2luZGV4TE9EfWApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMub25Ob2RlTE9Ec0xvYWRlZE9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKGluZGV4TE9EKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXhMT0QgIT09IHRoaXMuX25vZGVQcm9taXNlTE9Ecy5sZW5ndGggLSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLnN0YXJ0UGVyZm9ybWFuY2VDb3VudGVyKGBOb2RlIExPRCAke2luZGV4TE9EICsgMX1gKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkQnVmZmVyTE9EKHRoaXMuX25vZGVCdWZmZXJMT0RzLCBpbmRleExPRCArIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9ub2RlU2lnbmFsTE9Ec1tpbmRleExPRF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbm9kZVNpZ25hbExPRHNbaW5kZXhMT0RdLnJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLl9jb21wbGV0ZVByb21pc2VzLnB1c2gocHJvbWlzZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGxldCBpbmRleExPRCA9IDA7IGluZGV4TE9EIDwgdGhpcy5fbWF0ZXJpYWxQcm9taXNlTE9Ecy5sZW5ndGg7IGluZGV4TE9EKyspIHtcclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZSA9IFByb21pc2UuYWxsKHRoaXMuX21hdGVyaWFsUHJvbWlzZUxPRHNbaW5kZXhMT0RdKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChpbmRleExPRCAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5lbmRQZXJmb3JtYW5jZUNvdW50ZXIoYE1hdGVyaWFsIExPRCAke2luZGV4TE9EfWApO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2coYExvYWRlZCBtYXRlcmlhbCBMT0QgJHtpbmRleExPRH1gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uTWF0ZXJpYWxMT0RzTG9hZGVkT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMoaW5kZXhMT0QpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChpbmRleExPRCAhPT0gdGhpcy5fbWF0ZXJpYWxQcm9taXNlTE9Ecy5sZW5ndGggLSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLnN0YXJ0UGVyZm9ybWFuY2VDb3VudGVyKGBNYXRlcmlhbCBMT0QgJHtpbmRleExPRCArIDF9YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZEJ1ZmZlckxPRCh0aGlzLl9tYXRlcmlhbEJ1ZmZlckxPRHMsIGluZGV4TE9EICsgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX21hdGVyaWFsU2lnbmFsTE9Ec1tpbmRleExPRF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWF0ZXJpYWxTaWduYWxMT0RzW2luZGV4TE9EXS5yZXNvbHZlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5fY29tcGxldGVQcm9taXNlcy5wdXNoKHByb21pc2UpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZFNjZW5lQXN5bmMoY29udGV4dDogc3RyaW5nLCBzY2VuZTogSVNjZW5lKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLl9sb2FkZXIubG9hZFNjZW5lQXN5bmMoY29udGV4dCwgc2NlbmUpO1xyXG4gICAgICAgIHRoaXMuX2xvYWRCdWZmZXJMT0QodGhpcy5fYnVmZmVyTE9EcywgMCk7XHJcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWROb2RlQXN5bmMoY29udGV4dDogc3RyaW5nLCBub2RlOiBJTm9kZSwgYXNzaWduOiAoYmFieWxvblRyYW5zZm9ybU5vZGU6IFRyYW5zZm9ybU5vZGUpID0+IHZvaWQpOiBOdWxsYWJsZTxQcm9taXNlPFRyYW5zZm9ybU5vZGU+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElNU0ZUTE9ELCBUcmFuc2Zvcm1Ob2RlPihjb250ZXh0LCBub2RlLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgbGV0IGZpcnN0UHJvbWlzZTogUHJvbWlzZTxUcmFuc2Zvcm1Ob2RlPjtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IG5vZGVMT0RzID0gdGhpcy5fZ2V0TE9EcyhleHRlbnNpb25Db250ZXh0LCBub2RlLCB0aGlzLl9sb2FkZXIuZ2x0Zi5ub2RlcywgZXh0ZW5zaW9uLmlkcyk7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2dPcGVuKGAke2V4dGVuc2lvbkNvbnRleHR9YCk7XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBpbmRleExPRCA9IDA7IGluZGV4TE9EIDwgbm9kZUxPRHMubGVuZ3RoOyBpbmRleExPRCsrKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBub2RlTE9EID0gbm9kZUxPRHNbaW5kZXhMT0RdO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChpbmRleExPRCAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25vZGVJbmRleExPRCA9IGluZGV4TE9EO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25vZGVTaWduYWxMT0RzW2luZGV4TE9EXSA9IHRoaXMuX25vZGVTaWduYWxMT0RzW2luZGV4TE9EXSB8fCBuZXcgRGVmZXJyZWQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBhc3NpZ25XcmFwID0gKGJhYnlsb25UcmFuc2Zvcm1Ob2RlOiBUcmFuc2Zvcm1Ob2RlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXNzaWduKGJhYnlsb25UcmFuc2Zvcm1Ob2RlKTtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uVHJhbnNmb3JtTm9kZS5zZXRFbmFibGVkKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRoaXMuX2xvYWRlci5sb2FkTm9kZUFzeW5jKGAvbm9kZXMvJHtub2RlTE9ELmluZGV4fWAsIG5vZGVMT0QsIGFzc2lnbldyYXApLnRoZW4oKGJhYnlsb25NZXNoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4TE9EICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IHNob3VsZCBub3QgcmVseSBvbiBfYmFieWxvblRyYW5zZm9ybU5vZGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJldmlvdXNOb2RlTE9EID0gbm9kZUxPRHNbaW5kZXhMT0QgLSAxXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzTm9kZUxPRC5fYmFieWxvblRyYW5zZm9ybU5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2Rpc3Bvc2VUcmFuc2Zvcm1Ob2RlKHByZXZpb3VzTm9kZUxPRC5fYmFieWxvblRyYW5zZm9ybU5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHByZXZpb3VzTm9kZUxPRC5fYmFieWxvblRyYW5zZm9ybU5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NZXNoLnNldEVuYWJsZWQodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJhYnlsb25NZXNoO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbm9kZVByb21pc2VMT0RzW2luZGV4TE9EXSA9IHRoaXMuX25vZGVQcm9taXNlTE9Ec1tpbmRleExPRF0gfHwgW107XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4TE9EID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmlyc3RQcm9taXNlID0gcHJvbWlzZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbm9kZUluZGV4TE9EID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ub2RlUHJvbWlzZUxPRHNbaW5kZXhMT0RdLnB1c2gocHJvbWlzZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2dDbG9zZSgpO1xyXG4gICAgICAgICAgICByZXR1cm4gZmlyc3RQcm9taXNlITtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvYWRNYXRlcmlhbEFzeW5jKFxyXG4gICAgICAgIGNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBtYXRlcmlhbDogSU1hdGVyaWFsLFxyXG4gICAgICAgIGJhYnlsb25NZXNoOiBOdWxsYWJsZTxNZXNoPixcclxuICAgICAgICBiYWJ5bG9uRHJhd01vZGU6IG51bWJlcixcclxuICAgICAgICBhc3NpZ246IChiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKSA9PiB2b2lkXHJcbiAgICApOiBOdWxsYWJsZTxQcm9taXNlPE1hdGVyaWFsPj4ge1xyXG4gICAgICAgIC8vIERvbid0IGxvYWQgbWF0ZXJpYWwgTE9EcyBpZiBhbHJlYWR5IGxvYWRpbmcgYSBub2RlIExPRC5cclxuICAgICAgICBpZiAodGhpcy5fbm9kZUluZGV4TE9EKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElNU0ZUTE9ELCBNYXRlcmlhbD4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBsZXQgZmlyc3RQcm9taXNlOiBQcm9taXNlPE1hdGVyaWFsPjtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsTE9EcyA9IHRoaXMuX2dldExPRHMoZXh0ZW5zaW9uQ29udGV4dCwgbWF0ZXJpYWwsIHRoaXMuX2xvYWRlci5nbHRmLm1hdGVyaWFscywgZXh0ZW5zaW9uLmlkcyk7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2dPcGVuKGAke2V4dGVuc2lvbkNvbnRleHR9YCk7XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBpbmRleExPRCA9IDA7IGluZGV4TE9EIDwgbWF0ZXJpYWxMT0RzLmxlbmd0aDsgaW5kZXhMT0QrKykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxMT0QgPSBtYXRlcmlhbExPRHNbaW5kZXhMT0RdO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChpbmRleExPRCAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX21hdGVyaWFsSW5kZXhMT0QgPSBpbmRleExPRDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlID0gdGhpcy5fbG9hZGVyXHJcbiAgICAgICAgICAgICAgICAgICAgLl9sb2FkTWF0ZXJpYWxBc3luYyhgL21hdGVyaWFscy8ke21hdGVyaWFsTE9ELmluZGV4fWAsIG1hdGVyaWFsTE9ELCBiYWJ5bG9uTWVzaCwgYmFieWxvbkRyYXdNb2RlLCAoYmFieWxvbk1hdGVyaWFsKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleExPRCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzaWduKGJhYnlsb25NYXRlcmlhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKChiYWJ5bG9uTWF0ZXJpYWwpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4TE9EICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NpZ24oYmFieWxvbk1hdGVyaWFsKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBzaG91bGQgbm90IHJlbHkgb24gX2RhdGFcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzRGF0YUxPRCA9IG1hdGVyaWFsTE9Ec1tpbmRleExPRCAtIDFdLl9kYXRhITtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmV2aW91c0RhdGFMT0RbYmFieWxvbkRyYXdNb2RlXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2Rpc3Bvc2VNYXRlcmlhbHMoW3ByZXZpb3VzRGF0YUxPRFtiYWJ5bG9uRHJhd01vZGVdLmJhYnlsb25NYXRlcmlhbF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBwcmV2aW91c0RhdGFMT0RbYmFieWxvbkRyYXdNb2RlXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJhYnlsb25NYXRlcmlhbDtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9tYXRlcmlhbFByb21pc2VMT0RzW2luZGV4TE9EXSA9IHRoaXMuX21hdGVyaWFsUHJvbWlzZUxPRHNbaW5kZXhMT0RdIHx8IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChpbmRleExPRCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZpcnN0UHJvbWlzZSA9IHByb21pc2U7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX21hdGVyaWFsSW5kZXhMT0QgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX21hdGVyaWFsUHJvbWlzZUxPRHNbaW5kZXhMT0RdLnB1c2gocHJvbWlzZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2dDbG9zZSgpO1xyXG4gICAgICAgICAgICByZXR1cm4gZmlyc3RQcm9taXNlITtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvYWRVcmlBc3luYyhjb250ZXh0OiBzdHJpbmcsIHByb3BlcnR5OiBJUHJvcGVydHksIHVyaTogc3RyaW5nKTogTnVsbGFibGU8UHJvbWlzZTxBcnJheUJ1ZmZlclZpZXc+PiB7XHJcbiAgICAgICAgLy8gRGVmZXIgdGhlIGxvYWRpbmcgb2YgdXJpcyBpZiBsb2FkaW5nIGEgbm9kZSBvciBtYXRlcmlhbCBMT0QuXHJcbiAgICAgICAgaWYgKHRoaXMuX25vZGVJbmRleExPRCAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9nKGBkZWZlcnJlZGApO1xyXG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c0luZGV4TE9EID0gdGhpcy5fbm9kZUluZGV4TE9EIC0gMTtcclxuICAgICAgICAgICAgdGhpcy5fbm9kZVNpZ25hbExPRHNbcHJldmlvdXNJbmRleExPRF0gPSB0aGlzLl9ub2RlU2lnbmFsTE9Ec1twcmV2aW91c0luZGV4TE9EXSB8fCBuZXcgRGVmZXJyZWQ8dm9pZD4oKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25vZGVTaWduYWxMT0RzW3RoaXMuX25vZGVJbmRleExPRCAtIDFdLnByb21pc2UudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGVyLmxvYWRVcmlBc3luYyhjb250ZXh0LCBwcm9wZXJ0eSwgdXJpKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9tYXRlcmlhbEluZGV4TE9EICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2coYGRlZmVycmVkYCk7XHJcbiAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzSW5kZXhMT0QgPSB0aGlzLl9tYXRlcmlhbEluZGV4TE9EIC0gMTtcclxuICAgICAgICAgICAgdGhpcy5fbWF0ZXJpYWxTaWduYWxMT0RzW3ByZXZpb3VzSW5kZXhMT0RdID0gdGhpcy5fbWF0ZXJpYWxTaWduYWxMT0RzW3ByZXZpb3VzSW5kZXhMT0RdIHx8IG5ldyBEZWZlcnJlZDx2b2lkPigpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbWF0ZXJpYWxTaWduYWxMT0RzW3ByZXZpb3VzSW5kZXhMT0RdLnByb21pc2UudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGVyLmxvYWRVcmlBc3luYyhjb250ZXh0LCBwcm9wZXJ0eSwgdXJpKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZEJ1ZmZlckFzeW5jKGNvbnRleHQ6IHN0cmluZywgYnVmZmVyOiBJQnVmZmVyLCBieXRlT2Zmc2V0OiBudW1iZXIsIGJ5dGVMZW5ndGg6IG51bWJlcik6IE51bGxhYmxlPFByb21pc2U8QXJyYXlCdWZmZXJWaWV3Pj4ge1xyXG4gICAgICAgIGlmICh0aGlzLl9sb2FkZXIucGFyZW50LnVzZVJhbmdlUmVxdWVzdHMgJiYgIWJ1ZmZlci51cmkpIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLl9sb2FkZXIuYmluKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IFVyaSBpcyBtaXNzaW5nIG9yIHRoZSBiaW5hcnkgZ2xURiBpcyBtaXNzaW5nIGl0cyBiaW5hcnkgY2h1bmtgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgbG9hZEFzeW5jID0gKGJ1ZmZlckxPRHM6IEFycmF5PElCdWZmZXJJbmZvPiwgaW5kZXhMT0Q6IG51bWJlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhcnQgPSBieXRlT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZW5kID0gc3RhcnQgKyBieXRlTGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgICAgIGxldCBidWZmZXJMT0QgPSBidWZmZXJMT0RzW2luZGV4TE9EXTtcclxuICAgICAgICAgICAgICAgIGlmIChidWZmZXJMT0QpIHtcclxuICAgICAgICAgICAgICAgICAgICBidWZmZXJMT0Quc3RhcnQgPSBNYXRoLm1pbihidWZmZXJMT0Quc3RhcnQsIHN0YXJ0KTtcclxuICAgICAgICAgICAgICAgICAgICBidWZmZXJMT0QuZW5kID0gTWF0aC5tYXgoYnVmZmVyTE9ELmVuZCwgZW5kKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyTE9EID0geyBzdGFydDogc3RhcnQsIGVuZDogZW5kLCBsb2FkZWQ6IG5ldyBEZWZlcnJlZCgpIH07XHJcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyTE9Ec1tpbmRleExPRF0gPSBidWZmZXJMT0Q7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlckxPRC5sb2FkZWQucHJvbWlzZS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGRhdGEuYnVmZmVyLCBkYXRhLmJ5dGVPZmZzZXQgKyBieXRlT2Zmc2V0IC0gYnVmZmVyTE9ELnN0YXJ0LCBieXRlTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvZyhgZGVmZXJyZWRgKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9ub2RlSW5kZXhMT0QgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBsb2FkQXN5bmModGhpcy5fbm9kZUJ1ZmZlckxPRHMsIHRoaXMuX25vZGVJbmRleExPRCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fbWF0ZXJpYWxJbmRleExPRCAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGxvYWRBc3luYyh0aGlzLl9tYXRlcmlhbEJ1ZmZlckxPRHMsIHRoaXMuX21hdGVyaWFsSW5kZXhMT0QpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGxvYWRBc3luYyh0aGlzLl9idWZmZXJMT0RzLCAwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZEJ1ZmZlckxPRChidWZmZXJMT0RzOiBBcnJheTxJQnVmZmVySW5mbz4sIGluZGV4TE9EOiBudW1iZXIpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBidWZmZXJMT0QgPSBidWZmZXJMT0RzW2luZGV4TE9EXTtcclxuICAgICAgICBpZiAoYnVmZmVyTE9EKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2coYExvYWRpbmcgYnVmZmVyIHJhbmdlIFske2J1ZmZlckxPRC5zdGFydH0tJHtidWZmZXJMT0QuZW5kfV1gKTtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmJpbiEucmVhZEFzeW5jKGJ1ZmZlckxPRC5zdGFydCwgYnVmZmVyTE9ELmVuZCAtIGJ1ZmZlckxPRC5zdGFydCArIDEpLnRoZW4oXHJcbiAgICAgICAgICAgICAgICAoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlckxPRC5sb2FkZWQucmVzb2x2ZShkYXRhKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBidWZmZXJMT0QubG9hZGVkLnJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHJldHVybnMgYW4gYXJyYXkgb2YgTE9EIHByb3BlcnRpZXMgZnJvbSBsb3dlc3QgdG8gaGlnaGVzdC5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0XHJcbiAgICAgKiBAcGFyYW0gcHJvcGVydHlcclxuICAgICAqIEBwYXJhbSBhcnJheVxyXG4gICAgICogQHBhcmFtIGlkc1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9nZXRMT0RzPFQ+KGNvbnRleHQ6IHN0cmluZywgcHJvcGVydHk6IFQsIGFycmF5OiBBcnJheUxpa2U8VD4gfCB1bmRlZmluZWQsIGlkczogbnVtYmVyW10pOiBUW10ge1xyXG4gICAgICAgIGlmICh0aGlzLm1heExPRHNUb0xvYWQgPD0gMCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtYXhMT0RzVG9Mb2FkIG11c3QgYmUgZ3JlYXRlciB0aGFuIHplcm9cIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9wZXJ0aWVzOiBUW10gPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IGlkcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzLnB1c2goQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9pZHMvJHtpZHNbaV19YCwgYXJyYXksIGlkc1tpXSkpO1xyXG4gICAgICAgICAgICBpZiAocHJvcGVydGllcy5sZW5ndGggPT09IHRoaXMubWF4TE9Ec1RvTG9hZCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3BlcnRpZXM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHByb3BlcnRpZXMucHVzaChwcm9wZXJ0eSk7XHJcbiAgICAgICAgcmV0dXJuIHByb3BlcnRpZXM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZGlzcG9zZVRyYW5zZm9ybU5vZGUoYmFieWxvblRyYW5zZm9ybU5vZGU6IFRyYW5zZm9ybU5vZGUpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBiYWJ5bG9uTWF0ZXJpYWxzOiBNYXRlcmlhbFtdID0gW107XHJcbiAgICAgICAgY29uc3QgYmFieWxvbk1hdGVyaWFsID0gKGJhYnlsb25UcmFuc2Zvcm1Ob2RlIGFzIE1lc2gpLm1hdGVyaWFsO1xyXG4gICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFscy5wdXNoKGJhYnlsb25NYXRlcmlhbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAoY29uc3QgYmFieWxvbk1lc2ggb2YgYmFieWxvblRyYW5zZm9ybU5vZGUuZ2V0Q2hpbGRNZXNoZXMoKSkge1xyXG4gICAgICAgICAgICBpZiAoYmFieWxvbk1lc2gubWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbHMucHVzaChiYWJ5bG9uTWVzaC5tYXRlcmlhbCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGJhYnlsb25UcmFuc2Zvcm1Ob2RlLmRpc3Bvc2UoKTtcclxuXHJcbiAgICAgICAgY29uc3QgYmFieWxvbk1hdGVyaWFsc1RvRGlzcG9zZSA9IGJhYnlsb25NYXRlcmlhbHMuZmlsdGVyKChiYWJ5bG9uTWF0ZXJpYWwpID0+IHRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmUubWVzaGVzLmV2ZXJ5KChtZXNoKSA9PiBtZXNoLm1hdGVyaWFsICE9IGJhYnlsb25NYXRlcmlhbCkpO1xyXG4gICAgICAgIHRoaXMuX2Rpc3Bvc2VNYXRlcmlhbHMoYmFieWxvbk1hdGVyaWFsc1RvRGlzcG9zZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZGlzcG9zZU1hdGVyaWFscyhiYWJ5bG9uTWF0ZXJpYWxzOiBNYXRlcmlhbFtdKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgYmFieWxvblRleHR1cmVzOiB7IFt1bmlxdWVJZDogbnVtYmVyXTogQmFzZVRleHR1cmUgfSA9IHt9O1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IGJhYnlsb25NYXRlcmlhbCBvZiBiYWJ5bG9uTWF0ZXJpYWxzKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgYmFieWxvblRleHR1cmUgb2YgYmFieWxvbk1hdGVyaWFsLmdldEFjdGl2ZVRleHR1cmVzKCkpIHtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25UZXh0dXJlc1tiYWJ5bG9uVGV4dHVyZS51bmlxdWVJZF0gPSBiYWJ5bG9uVGV4dHVyZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmRpc3Bvc2UoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgdW5pcXVlSWQgaW4gYmFieWxvblRleHR1cmVzKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgYmFieWxvbk1hdGVyaWFsIG9mIHRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmUubWF0ZXJpYWxzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsLmhhc1RleHR1cmUoYmFieWxvblRleHR1cmVzW3VuaXF1ZUlkXSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgYmFieWxvblRleHR1cmVzW3VuaXF1ZUlkXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yIChjb25zdCB1bmlxdWVJZCBpbiBiYWJ5bG9uVGV4dHVyZXMpIHtcclxuICAgICAgICAgICAgYmFieWxvblRleHR1cmVzW3VuaXF1ZUlkXS5kaXNwb3NlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBNU0ZUX2xvZChsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IElNYXRlcmlhbCB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJNU0ZUX21pbmVjcmFmdE1lc2hcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgTVNGVF9taW5lY3JhZnRNZXNoIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJNU0ZUX21pbmVjcmFmdE1lc2hcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIE1TRlRfbWluZWNyYWZ0TWVzaCBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0cmFBc3luYzxib29sZWFuPihjb250ZXh0LCBtYXRlcmlhbCwgdGhpcy5uYW1lLCAoZXh0cmFDb250ZXh0LCBleHRyYSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoZXh0cmEpIHtcclxuICAgICAgICAgICAgICAgIGlmICghKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtleHRyYUNvbnRleHR9OiBNYXRlcmlhbCB0eXBlIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlID0gdGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsLm5lZWRBbHBoYUJsZW5kaW5nKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuZm9yY2VEZXB0aFdyaXRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuc2VwYXJhdGVDdWxsaW5nUGFzcyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmJhY2tGYWNlQ3VsbGluZyA9IGJhYnlsb25NYXRlcmlhbC5mb3JjZURlcHRoV3JpdGU7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwudHdvU2lkZWRMaWdodGluZyA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBNU0ZUX21pbmVjcmFmdE1lc2gobG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5cclxuaW1wb3J0IHR5cGUgeyBJTWF0ZXJpYWwgfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IEdMVEZMb2FkZXIgfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiTVNGVF9zUkdCRmFjdG9yc1wiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBNU0ZUX3NSR0JGYWN0b3JzIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJNU0ZUX3NSR0JGYWN0b3JzXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBNU0ZUX3NSR0JGYWN0b3JzIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBsb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRyYUFzeW5jPGJvb2xlYW4+KGNvbnRleHQsIG1hdGVyaWFsLCB0aGlzLm5hbWUsIChleHRyYUNvbnRleHQsIGV4dHJhKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChleHRyYSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2V4dHJhQ29udGV4dH06IE1hdGVyaWFsIHR5cGUgbm90IHN1cHBvcnRlZGApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLl9sb2FkZXIubG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHVzZUV4YWN0U3JnYkNvbnZlcnNpb25zID0gYmFieWxvbk1hdGVyaWFsLmdldFNjZW5lKCkuZ2V0RW5naW5lKCkudXNlRXhhY3RTcmdiQ29udmVyc2lvbnM7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWJhYnlsb25NYXRlcmlhbC5hbGJlZG9UZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmFsYmVkb0NvbG9yLnRvTGluZWFyU3BhY2VUb1JlZihiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvQ29sb3IsIHVzZUV4YWN0U3JnYkNvbnZlcnNpb25zKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWJhYnlsb25NYXRlcmlhbC5yZWZsZWN0aXZpdHlUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnJlZmxlY3Rpdml0eUNvbG9yLnRvTGluZWFyU3BhY2VUb1JlZihiYWJ5bG9uTWF0ZXJpYWwucmVmbGVjdGl2aXR5Q29sb3IsIHVzZUV4YWN0U3JnYkNvbnZlcnNpb25zKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IE1TRlRfc1JHQkZhY3RvcnMobG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgSU9iamVjdEluZm8sIElQYXRoVG9PYmplY3RDb252ZXJ0ZXIgfSBmcm9tIFwiY29yZS9PYmplY3RNb2RlbC9vYmplY3RNb2RlbEludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURiB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5cclxuLyoqXHJcbiAqIEEgY29udmVydGVyIHRoYXQgdGFrZXMgYSBnbFRGIE9iamVjdCBNb2RlbCBKU09OIFBvaW50ZXJcclxuICogYW5kIHRyYW5zZm9ybXMgaXQgaW50byBhbiBPYmplY3RBY2Nlc3NvckNvbnRhaW5lciwgYWxsb3dpbmdcclxuICogb2JqZWN0cyByZWZlcmVuY2VkIGluIHRoZSBnbFRGIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGVpclxyXG4gKiByZXNwZWN0aXZlIEJhYnlsb24uanMgb2JqZWN0cy5cclxuICovXHJcbmV4cG9ydCBjbGFzcyBHTFRGUGF0aFRvT2JqZWN0Q29udmVydGVyPFQ+IGltcGxlbWVudHMgSVBhdGhUb09iamVjdENvbnZlcnRlcjxUPiB7XHJcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHJpdmF0ZSBfZ2x0ZjogSUdMVEYsXHJcbiAgICAgICAgcHJpdmF0ZSBfaW5mb1RyZWU6IGFueVxyXG4gICAgKSB7fVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHBvaW50ZXIgc3RyaW5nIGlzIHJlcHJlc2VudGVkIGJ5IGEgW0pTT04gcG9pbnRlcl0oaHR0cHM6Ly9kYXRhdHJhY2tlci5pZXRmLm9yZy9kb2MvaHRtbC9yZmM2OTAxKS5cclxuICAgICAqIDxhbmltYXRpb25Qb2ludGVyPiA6PSAvPHJvb3ROb2RlPi88YXNzZXRJbmRleD4vPHByb3BlcnR5UGF0aD5cclxuICAgICAqIDxyb290Tm9kZT4gOj0gXCJub2Rlc1wiIHwgXCJtYXRlcmlhbHNcIiB8IFwibWVzaGVzXCIgfCBcImNhbWVyYXNcIiB8IFwiZXh0ZW5zaW9uc1wiXHJcbiAgICAgKiA8YXNzZXRJbmRleD4gOj0gPGRpZ2l0PiB8IDxuYW1lPlxyXG4gICAgICogPHByb3BlcnR5UGF0aD4gOj0gPGV4dGVuc2lvblBhdGg+IHwgPHN0YW5kYXJkUGF0aD5cclxuICAgICAqIDxleHRlbnNpb25QYXRoPiA6PSBcImV4dGVuc2lvbnNcIi88bmFtZT4vPHN0YW5kYXJkUGF0aD5cclxuICAgICAqIDxzdGFuZGFyZFBhdGg+IDo9IDxuYW1lPiB8IDxuYW1lPi88c3RhbmRhcmRQYXRoPlxyXG4gICAgICogPG5hbWU+IDo9IFcrXHJcbiAgICAgKiA8ZGlnaXQ+IDo9IEQrXHJcbiAgICAgKlxyXG4gICAgICogRXhhbXBsZXM6XHJcbiAgICAgKiAgLSBcIi9ub2Rlcy8wL3JvdGF0aW9uXCJcclxuICAgICAqICAtIFwiL21hdGVyaWFscy8yL2VtaXNzaXZlRmFjdG9yXCJcclxuICAgICAqICAtIFwiL21hdGVyaWFscy8yL3Bick1ldGFsbGljUm91Z2huZXNzL2Jhc2VDb2xvckZhY3RvclwiXHJcbiAgICAgKiAgLSBcIi9tYXRlcmlhbHMvMi9leHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfZW1pc3NpdmVfc3RyZW5ndGgvZW1pc3NpdmVTdHJlbmd0aFwiXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHBhdGggVGhlIHBhdGggdG8gY29udmVydFxyXG4gICAgICogQHJldHVybnMgVGhlIG9iamVjdCBhbmQgaW5mbyBhc3NvY2lhdGVkIHdpdGggdGhlIHBhdGhcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvbnZlcnQocGF0aDogc3RyaW5nKTogSU9iamVjdEluZm88VD4ge1xyXG4gICAgICAgIGxldCBvYmplY3RUcmVlOiBhbnkgPSB0aGlzLl9nbHRmO1xyXG4gICAgICAgIGxldCBpbmZvVHJlZTogYW55ID0gdGhpcy5faW5mb1RyZWU7XHJcbiAgICAgICAgbGV0IHRhcmdldDogYW55ID0gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICBpZiAoIXBhdGguc3RhcnRzV2l0aChcIi9cIikpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUGF0aCBtdXN0IHN0YXJ0IHdpdGggYSAvXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBwYXJ0cyA9IHBhdGguc3BsaXQoXCIvXCIpO1xyXG4gICAgICAgIHBhcnRzLnNoaWZ0KCk7XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xyXG4gICAgICAgICAgICBpZiAoaW5mb1RyZWUuX19hcnJheV9fKSB7XHJcbiAgICAgICAgICAgICAgICBpbmZvVHJlZSA9IGluZm9UcmVlLl9fYXJyYXlfXztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGluZm9UcmVlID0gaW5mb1RyZWVbcGFydF07XHJcbiAgICAgICAgICAgICAgICBpZiAoIWluZm9UcmVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQYXRoICR7cGF0aH0gaXMgaW52YWxpZGApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChvYmplY3RUcmVlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUGF0aCAke3BhdGh9IGlzIGludmFsaWRgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvYmplY3RUcmVlID0gb2JqZWN0VHJlZVtwYXJ0XTtcclxuXHJcbiAgICAgICAgICAgIGlmIChpbmZvVHJlZS5fX3RhcmdldF9fKSB7XHJcbiAgICAgICAgICAgICAgICB0YXJnZXQgPSBvYmplY3RUcmVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBvYmplY3Q6IHRhcmdldCxcclxuICAgICAgICAgICAgaW5mbzogaW5mb1RyZWUsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG4iLCJleHBvcnQgKiBmcm9tIFwiLi9FWFRfbGlnaHRzX2ltYWdlX2Jhc2VkXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0VYVF9tZXNoX2dwdV9pbnN0YW5jaW5nXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0VYVF9tZXNob3B0X2NvbXByZXNzaW9uXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0VYVF90ZXh0dXJlX3dlYnBcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vRVhUX3RleHR1cmVfYXZpZlwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfZHJhY29fbWVzaF9jb21wcmVzc2lvblwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbGlnaHRzX3B1bmN0dWFsXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfcGJyU3BlY3VsYXJHbG9zc2luZXNzXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfdW5saXRcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX21hdGVyaWFsc19jbGVhcmNvYXRcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX21hdGVyaWFsc19pcmlkZXNjZW5jZVwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWF0ZXJpYWxzX2FuaXNvdHJvcHlcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX21hdGVyaWFsc19lbWlzc2l2ZV9zdHJlbmd0aFwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWF0ZXJpYWxzX3NoZWVuXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfc3BlY3VsYXJcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX21hdGVyaWFsc19pb3JcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX21hdGVyaWFsc192YXJpYW50c1wiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWF0ZXJpYWxzX3RyYW5zbWlzc2lvblwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWF0ZXJpYWxzX2RpZmZ1c2VfdHJhbnNtaXNzaW9uXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfdm9sdW1lXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfZGlzcGVyc2lvblwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWVzaF9xdWFudGl6YXRpb25cIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX3RleHR1cmVfYmFzaXN1XCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl90ZXh0dXJlX3RyYW5zZm9ybVwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfeG1wX2pzb25fbGRcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX2FuaW1hdGlvbl9wb2ludGVyXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL01TRlRfYXVkaW9fZW1pdHRlclwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9NU0ZUX2xvZFwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9NU0ZUX21pbmVjcmFmdE1lc2hcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vTVNGVF9zUkdCRmFjdG9yc1wiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfaW50ZXJhY3Rpdml0eVwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbm9kZV92aXNpYmlsaXR5XCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0V4dHJhc0FzTWV0YWRhdGFcIjtcclxuIiwiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXHJcbmltcG9ydCB0eXBlIHsgSUtIUkludGVyYWN0aXZpdHksIElLSFJJbnRlcmFjdGl2aXR5X0NvbmZpZ3VyYXRpb24sIElLSFJJbnRlcmFjdGl2aXR5X05vZGUsIElLSFJJbnRlcmFjdGl2aXR5X1ZhcmlhYmxlIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElGbG93R3JhcGhCbG9ja0NvbmZpZ3VyYXRpb24gfSBmcm9tIFwiY29yZS9GbG93R3JhcGgvZmxvd0dyYXBoQmxvY2tcIjtcclxuaW1wb3J0IHR5cGUgeyBJU2VyaWFsaXplZEZsb3dHcmFwaCwgSVNlcmlhbGl6ZWRGbG93R3JhcGhCbG9jaywgSVNlcmlhbGl6ZWRGbG93R3JhcGhDb25uZWN0aW9uLCBJU2VyaWFsaXplZEZsb3dHcmFwaENvbnRleHQgfSBmcm9tIFwiY29yZS9GbG93R3JhcGgvdHlwZURlZmluaXRpb25zXCI7XHJcbmltcG9ydCB7IFJhbmRvbUdVSUQgfSBmcm9tIFwiY29yZS9NaXNjL2d1aWRcIjtcclxuaW1wb3J0IHsgZ2x0ZlRvRmxvd0dyYXBoVHlwZU1hcCwgZ2x0ZlR5cGVUb0JhYnlsb25UeXBlIH0gZnJvbSBcIi4vaW50ZXJhY3Rpdml0eVV0aWxzXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaENvbm5lY3Rpb25UeXBlIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL2Zsb3dHcmFwaENvbm5lY3Rpb25cIjtcclxuXHJcbmZ1bmN0aW9uIGNvbnZlcnRWYWx1ZVdpdGhUeXBlKGNvbmZpZ09iamVjdDogSUtIUkludGVyYWN0aXZpdHlfQ29uZmlndXJhdGlvbiwgZGVmaW5pdGlvbjogSUtIUkludGVyYWN0aXZpdHksIGNvbnRleHQ6IHN0cmluZykge1xyXG4gICAgaWYgKGNvbmZpZ09iamVjdC50eXBlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAvLyBnZXQgdGhlIHR5cGUgb24gdGhlIGdsdGYgZGVmaW5pdGlvblxyXG4gICAgICAgIGNvbnN0IHR5cGUgPSBkZWZpbml0aW9uLnR5cGVzICYmIGRlZmluaXRpb24udHlwZXNbY29uZmlnT2JqZWN0LnR5cGVdO1xyXG4gICAgICAgIGlmICghdHlwZSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IFVua25vd24gdHlwZTogJHtjb25maWdPYmplY3QudHlwZX1gKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdHlwZS5zaWduYXR1cmU7XHJcbiAgICAgICAgaWYgKCFzaWduYXR1cmUpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBUeXBlICR7Y29uZmlnT2JqZWN0LnR5cGV9IGhhcyBubyBzaWduYXR1cmVgKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgY29udmVydGVkVHlwZSA9IGdsdGZUeXBlVG9CYWJ5bG9uVHlwZVtzaWduYXR1cmVdO1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZhbHVlOiBjb25maWdPYmplY3QudmFsdWUsXHJcbiAgICAgICAgICAgIGNsYXNzTmFtZTogY29udmVydGVkVHlwZSxcclxuICAgICAgICB9O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICByZXR1cm4gY29uZmlnT2JqZWN0LnZhbHVlO1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBjb252ZXJ0Q29uZmlndXJhdGlvbihnbHRmQmxvY2s6IElLSFJJbnRlcmFjdGl2aXR5X05vZGUsIGRlZmluaXRpb246IElLSFJJbnRlcmFjdGl2aXR5LCBpZDogc3RyaW5nKTogSUZsb3dHcmFwaEJsb2NrQ29uZmlndXJhdGlvbiB7XHJcbiAgICBjb25zdCBjb252ZXJ0ZWQ6IElGbG93R3JhcGhCbG9ja0NvbmZpZ3VyYXRpb24gPSB7fTtcclxuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb25MaXN0OiBJS0hSSW50ZXJhY3Rpdml0eV9Db25maWd1cmF0aW9uW10gPSBnbHRmQmxvY2suY29uZmlndXJhdGlvbiA/PyBbXTtcclxuICAgIGZvciAoY29uc3QgY29uZmlnT2JqZWN0IG9mIGNvbmZpZ3VyYXRpb25MaXN0KSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZ09iamVjdC5pZCA9PT0gXCJjdXN0b21FdmVudFwiKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGN1c3RvbUV2ZW50ID0gZGVmaW5pdGlvbi5jdXN0b21FdmVudHMgJiYgZGVmaW5pdGlvbi5jdXN0b21FdmVudHNbY29uZmlnT2JqZWN0LnZhbHVlXTtcclxuICAgICAgICAgICAgaWYgKCFjdXN0b21FdmVudCkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAvZXh0ZW5zaW9ucy9LSFJfaW50ZXJhY3Rpdml0eS9ub2Rlcy8ke2lkfTogVW5rbm93biBjdXN0b20gZXZlbnQ6ICR7Y29uZmlnT2JqZWN0LnZhbHVlfWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnZlcnRlZC5ldmVudElkID0gY3VzdG9tRXZlbnQuaWQ7XHJcbiAgICAgICAgICAgIGNvbnZlcnRlZC5ldmVudERhdGEgPSBjdXN0b21FdmVudC52YWx1ZXMubWFwKCh2KSA9PiB2LmlkKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGNvbmZpZ09iamVjdC5pZCA9PT0gXCJ2YXJpYWJsZVwiKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHZhcmlhYmxlID0gZGVmaW5pdGlvbi52YXJpYWJsZXMgJiYgZGVmaW5pdGlvbi52YXJpYWJsZXNbY29uZmlnT2JqZWN0LnZhbHVlXTtcclxuICAgICAgICAgICAgaWYgKCF2YXJpYWJsZSkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAvZXh0ZW5zaW9ucy9LSFJfaW50ZXJhY3Rpdml0eS9ub2Rlcy8ke2lkfTogVW5rbm93biB2YXJpYWJsZTogJHtjb25maWdPYmplY3QudmFsdWV9YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29udmVydGVkLnZhcmlhYmxlTmFtZSA9IHZhcmlhYmxlLmlkO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoY29uZmlnT2JqZWN0LmlkID09PSBcInBhdGhcIikge1xyXG4gICAgICAgICAgICAvLyBDb252ZXJ0IGZyb20gYSBHTFRGIHBhdGggdG8gYSByZWZlcmVuY2UgdG8gdGhlIEJhYnlsb24uanMgb2JqZWN0XHJcbiAgICAgICAgICAgIGNvbnN0IHBhdGhWYWx1ZSA9IGNvbmZpZ09iamVjdC52YWx1ZSBhcyBzdHJpbmc7XHJcbiAgICAgICAgICAgIGNvbnZlcnRlZC5wYXRoID0gcGF0aFZhbHVlO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnZlcnRlZFtjb25maWdPYmplY3QuaWRdID0gY29udmVydFZhbHVlV2l0aFR5cGUoY29uZmlnT2JqZWN0LCBkZWZpbml0aW9uLCBgL2V4dGVuc2lvbnMvS0hSX2ludGVyYWN0aXZpdHkvbm9kZXMvJHtpZH1gKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY29udmVydGVkO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjb252ZXJ0QmxvY2soaWQ6IG51bWJlciwgZ2x0ZkJsb2NrOiBJS0hSSW50ZXJhY3Rpdml0eV9Ob2RlLCBkZWZpbml0aW9uOiBJS0hSSW50ZXJhY3Rpdml0eSk6IElTZXJpYWxpemVkRmxvd0dyYXBoQmxvY2sge1xyXG4gICAgY29uc3QgY2xhc3NOYW1lID0gZ2x0ZlRvRmxvd0dyYXBoVHlwZU1hcFtnbHRmQmxvY2sudHlwZV07XHJcbiAgICBpZiAoIWNsYXNzTmFtZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgL2V4dGVuc2lvbnMvS0hSX2ludGVyYWN0aXZpdHkvbm9kZXMvJHtpZH06IFVua25vd24gYmxvY2sgdHlwZTogJHtnbHRmQmxvY2sudHlwZX1gKTtcclxuICAgIH1cclxuICAgIGNvbnN0IHVuaXF1ZUlkID0gaWQudG9TdHJpbmcoKTtcclxuICAgIGNvbnN0IGNvbmZpZyA9IGNvbnZlcnRDb25maWd1cmF0aW9uKGdsdGZCbG9jaywgZGVmaW5pdGlvbiwgdW5pcXVlSWQpO1xyXG4gICAgY29uc3QgbWV0YWRhdGEgPSBnbHRmQmxvY2subWV0YWRhdGE7XHJcbiAgICBjb25zdCBkYXRhSW5wdXRzOiBJU2VyaWFsaXplZEZsb3dHcmFwaENvbm5lY3Rpb25bXSA9IFtdO1xyXG4gICAgY29uc3QgZGF0YU91dHB1dHM6IElTZXJpYWxpemVkRmxvd0dyYXBoQ29ubmVjdGlvbltdID0gW107XHJcbiAgICBjb25zdCBzaWduYWxJbnB1dHM6IElTZXJpYWxpemVkRmxvd0dyYXBoQ29ubmVjdGlvbltdID0gW107XHJcbiAgICBjb25zdCBzaWduYWxPdXRwdXRzOiBJU2VyaWFsaXplZEZsb3dHcmFwaENvbm5lY3Rpb25bXSA9IFtdO1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBjbGFzc05hbWUsXHJcbiAgICAgICAgY29uZmlnLFxyXG4gICAgICAgIHVuaXF1ZUlkLFxyXG4gICAgICAgIG1ldGFkYXRhLFxyXG4gICAgICAgIGRhdGFJbnB1dHMsXHJcbiAgICAgICAgZGF0YU91dHB1dHMsXHJcbiAgICAgICAgc2lnbmFsSW5wdXRzLFxyXG4gICAgICAgIHNpZ25hbE91dHB1dHMsXHJcbiAgICB9O1xyXG59XHJcblxyXG4vKipcclxuICogQGludGVybmFsXHJcbiAqIENvbnZlcnRzIGEgZ2xURiBJbnRlcmFjdGl2aXR5IEV4dGVuc2lvbiB0byBhIHNlcmlhbGl6ZWQgZmxvdyBncmFwaC5cclxuICogQHBhcmFtIGdsdGYgdGhlIGludGVyYWN0aXZpdHkgZGF0YVxyXG4gKiBAcmV0dXJucyBhIHNlcmlhbGl6ZWQgZmxvdyBncmFwaFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRHTFRGVG9TZXJpYWxpemVkRmxvd0dyYXBoKGdsdGY6IElLSFJJbnRlcmFjdGl2aXR5KTogSVNlcmlhbGl6ZWRGbG93R3JhcGgge1xyXG4gICAgLy8gY3JlYXRlIGFuIGVtcHR5IHNlcmlhbGl6ZWQgY29udGV4dCB0byBzdG9yZSB0aGUgdmFsdWVzIG9mIHRoZSBjb25uZWN0aW9uc1xyXG4gICAgY29uc3QgY29udGV4dDogSVNlcmlhbGl6ZWRGbG93R3JhcGhDb250ZXh0ID0ge1xyXG4gICAgICAgIHVuaXF1ZUlkOiBSYW5kb21HVUlEKCksXHJcbiAgICAgICAgX3VzZXJWYXJpYWJsZXM6IHt9LFxyXG4gICAgICAgIF9jb25uZWN0aW9uVmFsdWVzOiB7fSxcclxuICAgIH07XHJcbiAgICBjb25zdCBleGVjdXRpb25Db250ZXh0cyA9IFtjb250ZXh0XTtcclxuXHJcbiAgICAvLyBCbG9ja3MgY29udmVydGVkIHRvIHRoZSBmbG93IGdyYXBoIGpzb24gZm9ybWF0XHJcbiAgICBjb25zdCBmbG93R3JhcGhKc29uQmxvY2tzOiBJU2VyaWFsaXplZEZsb3dHcmFwaEJsb2NrW10gPSBbXTtcclxuXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdsdGYubm9kZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBjb25zdCBnbHRmQmxvY2sgPSBnbHRmLm5vZGVzW2ldO1xyXG4gICAgICAgIGNvbnN0IGZsb3dHcmFwaEpzb25CbG9jayA9IGNvbnZlcnRCbG9jayhpLCBnbHRmQmxvY2ssIGdsdGYpO1xyXG4gICAgICAgIGZsb3dHcmFwaEpzb25CbG9ja3MucHVzaChmbG93R3JhcGhKc29uQmxvY2spO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFBhcnNlIHRoZSBjb25uZWN0aW9uc1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBnbHRmLm5vZGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgY29uc3QgZ2x0ZkJsb2NrID0gZ2x0Zi5ub2Rlc1tpXTtcclxuICAgICAgICAvLyBnZXQgdGhlIGJsb2NrIHRoYXQgd2FzIGNyZWF0ZWQgaW4gdGhlIHByZXZpb3VzIHN0ZXBcclxuICAgICAgICBjb25zdCBmZ0Jsb2NrID0gZmxvd0dyYXBoSnNvbkJsb2Nrc1tpXTtcclxuICAgICAgICBjb25zdCBnbHRmRmxvd3MgPSBnbHRmQmxvY2suZmxvd3MgPz8gW107XHJcbiAgICAgICAgLy8gZm9yIGVhY2ggb3V0cHV0IGZsb3cgb2YgdGhlIGdsdGYgYmxvY2tcclxuICAgICAgICBmb3IgKGNvbnN0IGZsb3cgb2YgZ2x0ZkZsb3dzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHNvY2tldE91dE5hbWUgPSBmbG93LmlkO1xyXG4gICAgICAgICAgICAvLyBjcmVhdGUgYW4gb3V0cHV0IGNvbm5lY3Rpb24gZm9yIHRoZSBmbG93IGdyYXBoIGJsb2NrXHJcbiAgICAgICAgICAgIGNvbnN0IHNvY2tldE91dDogSVNlcmlhbGl6ZWRGbG93R3JhcGhDb25uZWN0aW9uID0ge1xyXG4gICAgICAgICAgICAgICAgdW5pcXVlSWQ6IFJhbmRvbUdVSUQoKSxcclxuICAgICAgICAgICAgICAgIG5hbWU6IHNvY2tldE91dE5hbWUsXHJcbiAgICAgICAgICAgICAgICBfY29ubmVjdGlvblR5cGU6IEZsb3dHcmFwaENvbm5lY3Rpb25UeXBlLk91dHB1dCwgLy8gT3V0cHV0XHJcbiAgICAgICAgICAgICAgICBjb25uZWN0ZWRQb2ludElkczogW10sXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGZnQmxvY2suc2lnbmFsT3V0cHV0cy5wdXNoKHNvY2tldE91dCk7XHJcbiAgICAgICAgICAgIC8vIGdldCB0aGUgaW5wdXQgbm9kZSBvZiB0aGlzIGZsb3dcclxuICAgICAgICAgICAgY29uc3Qgbm9kZUluSWQgPSBmbG93Lm5vZGU7XHJcbiAgICAgICAgICAgIGNvbnN0IG5vZGVJblNvY2tldE5hbWUgPSBmbG93LnNvY2tldDtcclxuICAgICAgICAgICAgLy8gZmluZCB0aGUgY29ycmVzcG9uZGluZyBmbG93IGdyYXBoIG5vZGVcclxuICAgICAgICAgICAgY29uc3Qgbm9kZUluID0gZmxvd0dyYXBoSnNvbkJsb2Nrc1tub2RlSW5JZF07XHJcbiAgICAgICAgICAgIGlmICghbm9kZUluKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICAgICAgICAgICAgICAgICAgYC9leHRlbnNpb25zL0tIUl9pbnRlcmFjdGl2aXR5L25vZGVzLyR7aX06IENvdWxkIG5vdCBmaW5kIG5vZGUgd2l0aCBpZCAke25vZGVJbklkfSB0aGF0IGNvbm5lY3RzIGl0cyBpbnB1dCB3aXRoIHdpdGggbm9kZSAke2l9J3Mgb3V0cHV0ICR7c29ja2V0T3V0TmFtZX1gXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGluIGFsbCBvZiB0aGUgZmxvdyBncmFwaCBpbnB1dCBjb25uZWN0aW9ucywgZmluZCB0aGUgb25lIHdpdGggdGhlIHNhbWUgbmFtZSBhcyB0aGUgc29ja2V0XHJcbiAgICAgICAgICAgIGxldCBzb2NrZXRJbiA9IG5vZGVJbi5zaWduYWxJbnB1dHMuZmluZCgocykgPT4gcy5uYW1lID09PSBub2RlSW5Tb2NrZXROYW1lKTtcclxuICAgICAgICAgICAgLy8gaWYgdGhlIHNvY2tldCBkb2Vzbid0IGV4aXN0LCBjcmVhdGUgdGhlIGlucHV0IHNvY2tldCBmb3IgdGhlIGNvbm5lY3Rpb25cclxuICAgICAgICAgICAgaWYgKCFzb2NrZXRJbikge1xyXG4gICAgICAgICAgICAgICAgc29ja2V0SW4gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdW5pcXVlSWQ6IFJhbmRvbUdVSUQoKSxcclxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBub2RlSW5Tb2NrZXROYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jb25uZWN0aW9uVHlwZTogRmxvd0dyYXBoQ29ubmVjdGlvblR5cGUuSW5wdXQsIC8vIElucHV0XHJcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGVkUG9pbnRJZHM6IFtdLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIG5vZGVJbi5zaWduYWxJbnB1dHMucHVzaChzb2NrZXRJbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gY29ubmVjdCB0aGUgc29ja2V0c1xyXG4gICAgICAgICAgICBzb2NrZXRJbi5jb25uZWN0ZWRQb2ludElkcy5wdXNoKHNvY2tldE91dC51bmlxdWVJZCk7XHJcbiAgICAgICAgICAgIHNvY2tldE91dC5jb25uZWN0ZWRQb2ludElkcy5wdXNoKHNvY2tldEluLnVuaXF1ZUlkKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gZm9yIGVhY2ggaW5wdXQgdmFsdWUgb2YgdGhlIGdsdGYgYmxvY2tcclxuICAgICAgICBjb25zdCBnbHRmVmFsdWVzID0gZ2x0ZkJsb2NrLnZhbHVlcyA/PyBbXTtcclxuICAgICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIGdsdGZWYWx1ZXMpIHtcclxuICAgICAgICAgICAgY29uc3Qgc29ja2V0SW5OYW1lID0gdmFsdWUuaWQ7XHJcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhbiBpbnB1dCBkYXRhIGNvbm5lY3Rpb24gZm9yIHRoZSBmbG93IGdyYXBoIGJsb2NrXHJcbiAgICAgICAgICAgIGNvbnN0IHNvY2tldEluOiBJU2VyaWFsaXplZEZsb3dHcmFwaENvbm5lY3Rpb24gPSB7XHJcbiAgICAgICAgICAgICAgICB1bmlxdWVJZDogUmFuZG9tR1VJRCgpLFxyXG4gICAgICAgICAgICAgICAgbmFtZTogc29ja2V0SW5OYW1lLFxyXG4gICAgICAgICAgICAgICAgX2Nvbm5lY3Rpb25UeXBlOiBGbG93R3JhcGhDb25uZWN0aW9uVHlwZS5JbnB1dCxcclxuICAgICAgICAgICAgICAgIGNvbm5lY3RlZFBvaW50SWRzOiBbXSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgZmdCbG9jay5kYXRhSW5wdXRzLnB1c2goc29ja2V0SW4pO1xyXG4gICAgICAgICAgICBpZiAodmFsdWUudmFsdWUgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgLy8gaWYgdGhlIHZhbHVlIGlzIHNldCBvbiB0aGUgc29ja2V0IGl0c2VsZiwgc3RvcmUgaXQgaW4gdGhlIGNvbnRleHRcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnZlcnRlZFZhbHVlID0gY29udmVydFZhbHVlV2l0aFR5cGUodmFsdWUgYXMgSUtIUkludGVyYWN0aXZpdHlfQ29uZmlndXJhdGlvbiwgZ2x0ZiwgYC9leHRlbnNpb25zL0tIUl9pbnRlcmFjdGl2aXR5L25vZGVzLyR7aX1gKTtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnZlcnRCbG9ja0lucHV0VHlwZShnbHRmQmxvY2ssIHZhbHVlLCBjb252ZXJ0ZWRWYWx1ZSwgYC9leHRlbnNpb25zL0tIUl9pbnRlcmFjdGl2aXR5L25vZGVzLyR7aX1gKTtcclxuICAgICAgICAgICAgICAgIGNvbnRleHQuX2Nvbm5lY3Rpb25WYWx1ZXNbc29ja2V0SW4udW5pcXVlSWRdID0gY29udmVydGVkVmFsdWU7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUubm9kZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlLnNvY2tldCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgdmFsdWUgaXMgY29ubmVjdGVkIHdpdGggdGhlIG91dHB1dCBkYXRhIG9mIGFub3RoZXIgc29ja2V0LCBjb25uZWN0IHRoZSB0d29cclxuICAgICAgICAgICAgICAgIGNvbnN0IG5vZGVPdXRJZCA9IHZhbHVlLm5vZGU7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBub2RlT3V0U29ja2V0TmFtZSA9IHZhbHVlLnNvY2tldDtcclxuICAgICAgICAgICAgICAgIC8vIGZpbmQgdGhlIGZsb3cgZ3JhcGggbm9kZSB0aGF0IG93bnMgdGhhdCBvdXRwdXQgc29ja2V0XHJcbiAgICAgICAgICAgICAgICBjb25zdCBub2RlT3V0ID0gZmxvd0dyYXBoSnNvbkJsb2Nrc1tub2RlT3V0SWRdO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFub2RlT3V0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBgL2V4dGVuc2lvbnMvS0hSX2ludGVyYWN0aXZpdHkvbm9kZXMvJHtpfTogQ291bGQgbm90IGZpbmQgbm9kZSB3aXRoIGlkICR7bm9kZU91dElkfSB0aGF0IGNvbm5lY3RzIGl0cyBvdXRwdXQgd2l0aCBub2RlJHtpfSdzIGlucHV0ICR7c29ja2V0SW5OYW1lfWBcclxuICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGV0IHNvY2tldE91dCA9IG5vZGVPdXQuZGF0YU91dHB1dHMuZmluZCgocykgPT4gcy5uYW1lID09PSBub2RlT3V0U29ja2V0TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgc29ja2V0IGRvZXNuJ3QgZXhpc3QsIGNyZWF0ZSBpdFxyXG4gICAgICAgICAgICAgICAgaWYgKCFzb2NrZXRPdXQpIHtcclxuICAgICAgICAgICAgICAgICAgICBzb2NrZXRPdXQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHVuaXF1ZUlkOiBSYW5kb21HVUlEKCksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IG5vZGVPdXRTb2NrZXROYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY29ubmVjdGlvblR5cGU6IEZsb3dHcmFwaENvbm5lY3Rpb25UeXBlLk91dHB1dCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGVkUG9pbnRJZHM6IFtdLFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgbm9kZU91dC5kYXRhT3V0cHV0cy5wdXNoKHNvY2tldE91dCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBjb25uZWN0IHRoZSBzb2NrZXRzXHJcbiAgICAgICAgICAgICAgICBzb2NrZXRJbi5jb25uZWN0ZWRQb2ludElkcy5wdXNoKHNvY2tldE91dC51bmlxdWVJZCk7XHJcbiAgICAgICAgICAgICAgICBzb2NrZXRPdXQuY29ubmVjdGVkUG9pbnRJZHMucHVzaChzb2NrZXRJbi51bmlxdWVJZCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYC9leHRlbnNpb25zL0tIUl9pbnRlcmFjdGl2aXR5L25vZGVzLyR7aX06IEludmFsaWQgc29ja2V0ICR7c29ja2V0SW5OYW1lfSBpbiBub2RlICR7aX1gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB2YXJpYWJsZXMgPSBnbHRmLnZhcmlhYmxlcyA/PyBbXTtcclxuICAgIC8vIFBhcnNlIHZhcmlhYmxlc1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YXJpYWJsZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBjb25zdCB2YXJpYWJsZTogSUtIUkludGVyYWN0aXZpdHlfVmFyaWFibGUgPSB2YXJpYWJsZXNbaV07XHJcbiAgICAgICAgY29uc3QgdmFyaWFibGVOYW1lID0gdmFyaWFibGUuaWQ7XHJcbiAgICAgICAgY29udGV4dC5fdXNlclZhcmlhYmxlc1t2YXJpYWJsZU5hbWVdID0gY29udmVydFZhbHVlV2l0aFR5cGUodmFyaWFibGUgYXMgSUtIUkludGVyYWN0aXZpdHlfQ29uZmlndXJhdGlvbiwgZ2x0ZiwgYC9leHRlbnNpb25zL0tIUl9pbnRlcmFjdGl2aXR5L3ZhcmlhYmxlcy8ke2l9YCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBhbGxCbG9ja3M6IGZsb3dHcmFwaEpzb25CbG9ja3MsXHJcbiAgICAgICAgZXhlY3V0aW9uQ29udGV4dHMsXHJcbiAgICB9O1xyXG59XHJcbiIsIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiAqL1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGLCBJTm9kZSB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgeyBHTFRGUGF0aFRvT2JqZWN0Q29udmVydGVyIH0gZnJvbSBcIi4vZ2x0ZlBhdGhUb09iamVjdENvbnZlcnRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IFRyYW5zZm9ybU5vZGUgfSBmcm9tIFwiY29yZS9NZXNoZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJT2JqZWN0QWNjZXNzb3IgfSBmcm9tIFwiY29yZS9GbG93R3JhcGgvdHlwZURlZmluaXRpb25zXCI7XHJcblxyXG4vKipcclxuICogQ2xhc3MgdG8gY29udmVydCBhbiBpbnRlcmFjdGl2aXR5IHBvaW50ZXIgcGF0aCB0byBhIHNtYXJ0IG9iamVjdFxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEludGVyYWN0aXZpdHlQYXRoVG9PYmplY3RDb252ZXJ0ZXIgZXh0ZW5kcyBHTFRGUGF0aFRvT2JqZWN0Q29udmVydGVyPElPYmplY3RBY2Nlc3Nvcj4ge1xyXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKGdsdGY6IElHTFRGKSB7XHJcbiAgICAgICAgc3VwZXIoZ2x0ZiwgZ2x0ZlRyZWUpO1xyXG4gICAgfVxyXG59XHJcblxyXG5jb25zdCBub2Rlc1RyZWUgPSB7XHJcbiAgICBfX2FycmF5X186IHtcclxuICAgICAgICBfX3RhcmdldF9fOiB0cnVlLFxyXG4gICAgICAgIHRyYW5zbGF0aW9uOiB7XHJcbiAgICAgICAgICAgIHR5cGU6IFwiVmVjdG9yM1wiLFxyXG4gICAgICAgICAgICBnZXQ6IChub2RlOiBJTm9kZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYmFieWxvbk9iamVjdCA9IG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlIGFzIFRyYW5zZm9ybU5vZGU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYmFieWxvbk9iamVjdC5wb3NpdGlvbjtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgc2V0OiAodmFsdWU6IGFueSwgbm9kZTogSU5vZGUpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJhYnlsb25PYmplY3QgPSBub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSBhcyBUcmFuc2Zvcm1Ob2RlO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk9iamVjdC5wb3NpdGlvbiA9IHZhbHVlO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBnZXRPYmplY3Qobm9kZTogSU5vZGUpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgfSxcclxufTtcclxuXHJcbmNvbnN0IGdsdGZUcmVlID0ge1xyXG4gICAgbm9kZXM6IG5vZGVzVHJlZSxcclxufTtcclxuIiwiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXHJcbmltcG9ydCB7IEZsb3dHcmFwaFNjZW5lUmVhZHlFdmVudEJsb2NrIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL0Jsb2Nrcy9FdmVudC9mbG93R3JhcGhTY2VuZVJlYWR5RXZlbnRCbG9ja1wiO1xyXG5pbXBvcnQgeyBGbG93R3JhcGhTY2VuZVRpY2tFdmVudEJsb2NrIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL0Jsb2Nrcy9FdmVudC9mbG93R3JhcGhTY2VuZVRpY2tFdmVudEJsb2NrXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaENvbnNvbGVMb2dCbG9jayB9IGZyb20gXCJjb3JlL0Zsb3dHcmFwaC9CbG9ja3MvRXhlY3V0aW9uL2Zsb3dHcmFwaENvbnNvbGVMb2dCbG9ja1wiO1xyXG5pbXBvcnQgeyBGbG93R3JhcGhUaW1lckJsb2NrIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL0Jsb2Nrcy9FeGVjdXRpb24vQ29udHJvbEZsb3cvZmxvd0dyYXBoVGltZXJCbG9ja1wiO1xyXG5pbXBvcnQgeyBGbG93R3JhcGhTZW5kQ3VzdG9tRXZlbnRCbG9jayB9IGZyb20gXCJjb3JlL0Zsb3dHcmFwaC9CbG9ja3MvRXhlY3V0aW9uL2Zsb3dHcmFwaFNlbmRDdXN0b21FdmVudEJsb2NrXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaFJlY2VpdmVDdXN0b21FdmVudEJsb2NrIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL0Jsb2Nrcy9FdmVudC9mbG93R3JhcGhSZWNlaXZlQ3VzdG9tRXZlbnRCbG9ja1wiO1xyXG5pbXBvcnQgeyBGbG93R3JhcGhTZXF1ZW5jZUJsb2NrIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL0Jsb2Nrcy9FeGVjdXRpb24vQ29udHJvbEZsb3cvZmxvd0dyYXBoU2VxdWVuY2VCbG9ja1wiO1xyXG5pbXBvcnQgeyBGbG93R3JhcGhHZXRQcm9wZXJ0eUJsb2NrIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL0Jsb2Nrcy9EYXRhL2Zsb3dHcmFwaEdldFByb3BlcnR5QmxvY2tcIjtcclxuaW1wb3J0IHsgRmxvd0dyYXBoU2V0UHJvcGVydHlCbG9jayB9IGZyb20gXCJjb3JlL0Zsb3dHcmFwaC9CbG9ja3MvRXhlY3V0aW9uL2Zsb3dHcmFwaFNldFByb3BlcnR5QmxvY2tcIjtcclxuaW1wb3J0IHtcclxuICAgIEZsb3dHcmFwaEFkZEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoUmFuZG9tQmxvY2ssXHJcbiAgICBGbG93R3JhcGhMZXNzVGhhbkJsb2NrLFxyXG4gICAgRmxvd0dyYXBoTXVsdGlwbHlCbG9jayxcclxuICAgIEZsb3dHcmFwaFN1YnRyYWN0QmxvY2ssXHJcbiAgICBGbG93R3JhcGhEb3RCbG9jayxcclxuICAgIEZsb3dHcmFwaEVCbG9jayxcclxuICAgIEZsb3dHcmFwaFBpQmxvY2ssXHJcbiAgICBGbG93R3JhcGhJbmZCbG9jayxcclxuICAgIEZsb3dHcmFwaE5hTkJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQWJzQmxvY2ssXHJcbiAgICBGbG93R3JhcGhTaWduQmxvY2ssXHJcbiAgICBGbG93R3JhcGhUcnVuY0Jsb2NrLFxyXG4gICAgRmxvd0dyYXBoRmxvb3JCbG9jayxcclxuICAgIEZsb3dHcmFwaENlaWxCbG9jayxcclxuICAgIEZsb3dHcmFwaEZyYWN0QmxvY2ssXHJcbiAgICBGbG93R3JhcGhOZWdCbG9jayxcclxuICAgIEZsb3dHcmFwaERpdmlkZUJsb2NrLFxyXG4gICAgRmxvd0dyYXBoUmVtYWluZGVyQmxvY2ssXHJcbiAgICBGbG93R3JhcGhNaW5CbG9jayxcclxuICAgIEZsb3dHcmFwaE1heEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQ2xhbXBCbG9jayxcclxuICAgIEZsb3dHcmFwaFNhdHVyYXRlQmxvY2ssXHJcbiAgICBGbG93R3JhcGhJbnRlcnBvbGF0ZUJsb2NrLFxyXG4gICAgRmxvd0dyYXBoRXFCbG9jayxcclxuICAgIEZsb3dHcmFwaExlc3NUaGFuT3JFcXVhbEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoR3JlYXRlclRoYW5CbG9jayxcclxuICAgIEZsb3dHcmFwaEdyZWF0ZXJUaGFuT3JFcXVhbEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoSXNOYW5CbG9jayxcclxuICAgIEZsb3dHcmFwaElzSW5mQmxvY2ssXHJcbiAgICBGbG93R3JhcGhEZWdUb1JhZEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoUmFkVG9EZWdCbG9jayxcclxuICAgIEZsb3dHcmFwaFNpbkJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQ29zQmxvY2ssXHJcbiAgICBGbG93R3JhcGhUYW5CbG9jayxcclxuICAgIEZsb3dHcmFwaEFzaW5CbG9jayxcclxuICAgIEZsb3dHcmFwaEFjb3NCbG9jayxcclxuICAgIEZsb3dHcmFwaEF0YW5CbG9jayxcclxuICAgIEZsb3dHcmFwaEF0YW4yQmxvY2ssXHJcbiAgICBGbG93R3JhcGhTaW5oQmxvY2ssXHJcbiAgICBGbG93R3JhcGhDb3NoQmxvY2ssXHJcbiAgICBGbG93R3JhcGhUYW5oQmxvY2ssXHJcbiAgICBGbG93R3JhcGhBc2luaEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQWNvc2hCbG9jayxcclxuICAgIEZsb3dHcmFwaEF0YW5oQmxvY2ssXHJcbiAgICBGbG93R3JhcGhFeHBCbG9jayxcclxuICAgIEZsb3dHcmFwaExvZzJCbG9jayxcclxuICAgIEZsb3dHcmFwaExvZ0Jsb2NrLFxyXG4gICAgRmxvd0dyYXBoTG9nMTBCbG9jayxcclxuICAgIEZsb3dHcmFwaFNxcnRCbG9jayxcclxuICAgIEZsb3dHcmFwaEN1YmVSb290QmxvY2ssXHJcbiAgICBGbG93R3JhcGhQb3dCbG9jayxcclxuICAgIEZsb3dHcmFwaExlbmd0aEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoTm9ybWFsaXplQmxvY2ssXHJcbiAgICBGbG93R3JhcGhDcm9zc0Jsb2NrLFxyXG4gICAgRmxvd0dyYXBoUm90YXRlMkRCbG9jayxcclxuICAgIEZsb3dHcmFwaFJvdGF0ZTNEQmxvY2ssXHJcbiAgICBGbG93R3JhcGhUcmFuc3Bvc2VCbG9jayxcclxuICAgIEZsb3dHcmFwaERldGVybWluYW50QmxvY2ssXHJcbiAgICBGbG93R3JhcGhJbnZlcnRNYXRyaXhCbG9jayxcclxuICAgIEZsb3dHcmFwaE1hdE11bEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQml0d2lzZU5vdEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQml0d2lzZUFuZEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQml0d2lzZU9yQmxvY2ssXHJcbiAgICBGbG93R3JhcGhCaXR3aXNlWG9yQmxvY2ssXHJcbiAgICBGbG93R3JhcGhCaXR3aXNlUmlnaHRTaGlmdEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQml0d2lzZUxlZnRTaGlmdEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQ291bnRMZWFkaW5nWmVyb3NCbG9jayxcclxuICAgIEZsb3dHcmFwaENvdW50VHJhaWxpbmdaZXJvc0Jsb2NrLFxyXG4gICAgRmxvd0dyYXBoQ291bnRPbmVCaXRzQmxvY2ssXHJcbn0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL0Jsb2Nrcy9EYXRhL01hdGgvZmxvd0dyYXBoTWF0aEJsb2Nrc1wiO1xyXG5pbXBvcnQgeyBGbG93R3JhcGhEb05CbG9jayB9IGZyb20gXCJjb3JlL0Zsb3dHcmFwaC9CbG9ja3MvRXhlY3V0aW9uL0NvbnRyb2xGbG93L2Zsb3dHcmFwaERvTkJsb2NrXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaEdldFZhcmlhYmxlQmxvY2sgfSBmcm9tIFwiY29yZS9GbG93R3JhcGgvQmxvY2tzL0RhdGEvZmxvd0dyYXBoR2V0VmFyaWFibGVCbG9ja1wiO1xyXG5pbXBvcnQgeyBGbG93R3JhcGhTZXRWYXJpYWJsZUJsb2NrIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL0Jsb2Nrcy9FeGVjdXRpb24vZmxvd0dyYXBoU2V0VmFyaWFibGVCbG9ja1wiO1xyXG5pbXBvcnQgeyBGbG93R3JhcGhXaGlsZUxvb3BCbG9jayB9IGZyb20gXCJjb3JlL0Zsb3dHcmFwaC9CbG9ja3MvRXhlY3V0aW9uL0NvbnRyb2xGbG93L2Zsb3dHcmFwaFdoaWxlTG9vcEJsb2NrXCI7XHJcblxyXG5leHBvcnQgY29uc3QgZ2x0ZlRvRmxvd0dyYXBoVHlwZU1hcDogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcclxuICAgIFwibGlmZWN5Y2xlL29uU3RhcnRcIjogRmxvd0dyYXBoU2NlbmVSZWFkeUV2ZW50QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJsaWZlY3ljbGUvb25UaWNrXCI6IEZsb3dHcmFwaFNjZW5lVGlja0V2ZW50QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgbG9nOiBGbG93R3JhcGhDb25zb2xlTG9nQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJmbG93L2RlbGF5XCI6IEZsb3dHcmFwaFRpbWVyQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJjdXN0b21FdmVudC9zZW5kXCI6IEZsb3dHcmFwaFNlbmRDdXN0b21FdmVudEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwiY3VzdG9tRXZlbnQvcmVjZWl2ZVwiOiBGbG93R3JhcGhSZWNlaXZlQ3VzdG9tRXZlbnRCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcImZsb3cvc2VxdWVuY2VcIjogRmxvd0dyYXBoU2VxdWVuY2VCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIndvcmxkL2dldFwiOiBGbG93R3JhcGhHZXRQcm9wZXJ0eUJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwid29ybGQvc2V0XCI6IEZsb3dHcmFwaFNldFByb3BlcnR5QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJmbG93L2RvTlwiOiBGbG93R3JhcGhEb05CbG9jay5DbGFzc05hbWUsXHJcbiAgICBcInZhcmlhYmxlL2dldFwiOiBGbG93R3JhcGhHZXRWYXJpYWJsZUJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwidmFyaWFibGUvc2V0XCI6IEZsb3dHcmFwaFNldFZhcmlhYmxlQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJmbG93L3doaWxlTG9vcFwiOiBGbG93R3JhcGhXaGlsZUxvb3BCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvcmFuZG9tXCI6IEZsb3dHcmFwaFJhbmRvbUJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9lXCI6IEZsb3dHcmFwaEVCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvcGlcIjogRmxvd0dyYXBoUGlCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvaW5mXCI6IEZsb3dHcmFwaEluZkJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9uYW5cIjogRmxvd0dyYXBoTmFOQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2Fic1wiOiBGbG93R3JhcGhBYnNCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvc2lnblwiOiBGbG93R3JhcGhTaWduQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL3RydW5jXCI6IEZsb3dHcmFwaFRydW5jQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2Zsb29yXCI6IEZsb3dHcmFwaEZsb29yQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2NlaWxcIjogRmxvd0dyYXBoQ2VpbEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9mcmFjdFwiOiBGbG93R3JhcGhGcmFjdEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9uZWdcIjogRmxvd0dyYXBoTmVnQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2FkZFwiOiBGbG93R3JhcGhBZGRCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvc3ViXCI6IEZsb3dHcmFwaFN1YnRyYWN0QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL211bFwiOiBGbG93R3JhcGhNdWx0aXBseUJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9kaXZcIjogRmxvd0dyYXBoRGl2aWRlQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL3JlbVwiOiBGbG93R3JhcGhSZW1haW5kZXJCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvbWluXCI6IEZsb3dHcmFwaE1pbkJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9tYXhcIjogRmxvd0dyYXBoTWF4QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2NsYW1wXCI6IEZsb3dHcmFwaENsYW1wQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL3NhdHVyYXRlXCI6IEZsb3dHcmFwaFNhdHVyYXRlQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL21peFwiOiBGbG93R3JhcGhJbnRlcnBvbGF0ZUJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9lcVwiOiBGbG93R3JhcGhFcUJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9sdFwiOiBGbG93R3JhcGhMZXNzVGhhbkJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9sZVwiOiBGbG93R3JhcGhMZXNzVGhhbk9yRXF1YWxCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvZ3RcIjogRmxvd0dyYXBoR3JlYXRlclRoYW5CbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvZ2VcIjogRmxvd0dyYXBoR3JlYXRlclRoYW5PckVxdWFsQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2lzbmFuXCI6IEZsb3dHcmFwaElzTmFuQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2lzaW5mXCI6IEZsb3dHcmFwaElzSW5mQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL3JhZFwiOiBGbG93R3JhcGhEZWdUb1JhZEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9kZWdcIjogRmxvd0dyYXBoUmFkVG9EZWdCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvc2luXCI6IEZsb3dHcmFwaFNpbkJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9jb3NcIjogRmxvd0dyYXBoQ29zQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL3RhblwiOiBGbG93R3JhcGhUYW5CbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvYXNpblwiOiBGbG93R3JhcGhBc2luQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2Fjb3NcIjogRmxvd0dyYXBoQWNvc0Jsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9hdGFuXCI6IEZsb3dHcmFwaEF0YW5CbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvYXRhbjJcIjogRmxvd0dyYXBoQXRhbjJCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvc2luaFwiOiBGbG93R3JhcGhTaW5oQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2Nvc2hcIjogRmxvd0dyYXBoQ29zaEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC90YW5oXCI6IEZsb3dHcmFwaFRhbmhCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvYXNpbmhcIjogRmxvd0dyYXBoQXNpbmhCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvYWNvc2hcIjogRmxvd0dyYXBoQWNvc2hCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvYXRhbmhcIjogRmxvd0dyYXBoQXRhbmhCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvZXhwXCI6IEZsb3dHcmFwaEV4cEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9sb2dcIjogRmxvd0dyYXBoTG9nQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2xvZzJcIjogRmxvd0dyYXBoTG9nMkJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9sb2cxMFwiOiBGbG93R3JhcGhMb2cxMEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9zcXJ0XCI6IEZsb3dHcmFwaFNxcnRCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvY2JydFwiOiBGbG93R3JhcGhDdWJlUm9vdEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9wb3dcIjogRmxvd0dyYXBoUG93QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2xlbmd0aFwiOiBGbG93R3JhcGhMZW5ndGhCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvbm9ybWFsaXplXCI6IEZsb3dHcmFwaE5vcm1hbGl6ZUJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9kb3RcIjogRmxvd0dyYXBoRG90QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2Nyb3NzXCI6IEZsb3dHcmFwaENyb3NzQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL3JvdGF0ZTJkXCI6IEZsb3dHcmFwaFJvdGF0ZTJEQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL3JvdGF0ZTNkXCI6IEZsb3dHcmFwaFJvdGF0ZTNEQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL3RyYW5zcG9zZVwiOiBGbG93R3JhcGhUcmFuc3Bvc2VCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvZGV0ZXJtaW5hbnRcIjogRmxvd0dyYXBoRGV0ZXJtaW5hbnRCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvaW52ZXJzZVwiOiBGbG93R3JhcGhJbnZlcnRNYXRyaXhCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvbWF0bXVsXCI6IEZsb3dHcmFwaE1hdE11bEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9ub3RcIjogRmxvd0dyYXBoQml0d2lzZU5vdEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9hbmRcIjogRmxvd0dyYXBoQml0d2lzZUFuZEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9vclwiOiBGbG93R3JhcGhCaXR3aXNlT3JCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgveG9yXCI6IEZsb3dHcmFwaEJpdHdpc2VYb3JCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvYXNyXCI6IEZsb3dHcmFwaEJpdHdpc2VSaWdodFNoaWZ0QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2xzbFwiOiBGbG93R3JhcGhCaXR3aXNlTGVmdFNoaWZ0QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2NselwiOiBGbG93R3JhcGhDb3VudExlYWRpbmdaZXJvc0Jsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9jdHpcIjogRmxvd0dyYXBoQ291bnRUcmFpbGluZ1plcm9zQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL3BvcGNudFwiOiBGbG93R3JhcGhDb3VudE9uZUJpdHNCbG9jay5DbGFzc05hbWUsXHJcbn07XHJcblxyXG5leHBvcnQgY29uc3QgZ2x0ZlR5cGVUb0JhYnlsb25UeXBlOiBhbnkgPSB7XHJcbiAgICBmbG9hdDI6IFwiVmVjdG9yMlwiLFxyXG4gICAgZmxvYXQzOiBcIlZlY3RvcjNcIixcclxuICAgIGZsb2F0NDogXCJWZWN0b3I0XCIsXHJcbiAgICBmbG9hdDR4NDogXCJNYXRyaXhcIixcclxuICAgIGludDogXCJGbG93R3JhcGhJbnRlZ2VyXCIsXHJcbn07XHJcbiIsImltcG9ydCB0eXBlIHsgSW5kaWNlc0FycmF5LCBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IERlZmVycmVkIH0gZnJvbSBcImNvcmUvTWlzYy9kZWZlcnJlZFwiO1xyXG5pbXBvcnQgeyBRdWF0ZXJuaW9uLCBWZWN0b3IzLCBNYXRyaXgsIFRtcFZlY3RvcnMgfSBmcm9tIFwiY29yZS9NYXRocy9tYXRoLnZlY3RvclwiO1xyXG5pbXBvcnQgeyBDb2xvcjMgfSBmcm9tIFwiY29yZS9NYXRocy9tYXRoLmNvbG9yXCI7XHJcbmltcG9ydCB7IFRvb2xzIH0gZnJvbSBcImNvcmUvTWlzYy90b29sc1wiO1xyXG5pbXBvcnQgeyBDYW1lcmEgfSBmcm9tIFwiY29yZS9DYW1lcmFzL2NhbWVyYVwiO1xyXG5pbXBvcnQgeyBGcmVlQ2FtZXJhIH0gZnJvbSBcImNvcmUvQ2FtZXJhcy9mcmVlQ2FtZXJhXCI7XHJcbmltcG9ydCB0eXBlIHsgQW5pbWF0aW9uIH0gZnJvbSBcImNvcmUvQW5pbWF0aW9ucy9hbmltYXRpb25cIjtcclxuaW1wb3J0IHR5cGUgeyBJQW5pbWF0YWJsZSB9IGZyb20gXCJjb3JlL0FuaW1hdGlvbnMvYW5pbWF0YWJsZS5pbnRlcmZhY2VcIjtcclxuaW1wb3J0IHR5cGUgeyBJQW5pbWF0aW9uS2V5IH0gZnJvbSBcImNvcmUvQW5pbWF0aW9ucy9hbmltYXRpb25LZXlcIjtcclxuaW1wb3J0IHsgQW5pbWF0aW9uS2V5SW50ZXJwb2xhdGlvbiB9IGZyb20gXCJjb3JlL0FuaW1hdGlvbnMvYW5pbWF0aW9uS2V5XCI7XHJcbmltcG9ydCB0eXBlIHsgQW5pbWF0aW9uR3JvdXAgfSBmcm9tIFwiY29yZS9BbmltYXRpb25zL2FuaW1hdGlvbkdyb3VwXCI7XHJcbmltcG9ydCB7IEJvbmUgfSBmcm9tIFwiY29yZS9Cb25lcy9ib25lXCI7XHJcbmltcG9ydCB7IFNrZWxldG9uIH0gZnJvbSBcImNvcmUvQm9uZXMvc2tlbGV0b25cIjtcclxuaW1wb3J0IHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgQmFzZVRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvYmFzZVRleHR1cmVcIjtcclxuaW1wb3J0IHR5cGUgeyBJVGV4dHVyZUNyZWF0aW9uT3B0aW9ucyB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy90ZXh0dXJlXCI7XHJcbmltcG9ydCB7IFRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvdGV4dHVyZVwiO1xyXG5pbXBvcnQgeyBUcmFuc2Zvcm1Ob2RlIH0gZnJvbSBcImNvcmUvTWVzaGVzL3RyYW5zZm9ybU5vZGVcIjtcclxuaW1wb3J0IHsgQnVmZmVyLCBWZXJ0ZXhCdWZmZXIgfSBmcm9tIFwiY29yZS9CdWZmZXJzL2J1ZmZlclwiO1xyXG5pbXBvcnQgeyBHZW9tZXRyeSB9IGZyb20gXCJjb3JlL01lc2hlcy9nZW9tZXRyeVwiO1xyXG5pbXBvcnQgeyBBYnN0cmFjdE1lc2ggfSBmcm9tIFwiY29yZS9NZXNoZXMvYWJzdHJhY3RNZXNoXCI7XHJcbmltcG9ydCB0eXBlIHsgSW5zdGFuY2VkTWVzaCB9IGZyb20gXCJjb3JlL01lc2hlcy9pbnN0YW5jZWRNZXNoXCI7XHJcbmltcG9ydCB7IE1lc2ggfSBmcm9tIFwiY29yZS9NZXNoZXMvbWVzaFwiO1xyXG5pbXBvcnQgeyBNb3JwaFRhcmdldCB9IGZyb20gXCJjb3JlL01vcnBoL21vcnBoVGFyZ2V0XCI7XHJcbmltcG9ydCB7IE1vcnBoVGFyZ2V0TWFuYWdlciB9IGZyb20gXCJjb3JlL01vcnBoL21vcnBoVGFyZ2V0TWFuYWdlclwiO1xyXG5pbXBvcnQgdHlwZSB7IElTY2VuZUxvYWRlckFzeW5jUmVzdWx0LCBJU2NlbmVMb2FkZXJQcm9ncmVzc0V2ZW50IH0gZnJvbSBcImNvcmUvTG9hZGluZy9zY2VuZUxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IFNjZW5lIH0gZnJvbSBcImNvcmUvc2NlbmVcIjtcclxuaW1wb3J0IHR5cGUgeyBJUHJvcGVydHkgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7XHJcbiAgICBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCxcclxuICAgIEFuaW1hdGlvblNhbXBsZXJJbnRlcnBvbGF0aW9uLFxyXG4gICAgQWNjZXNzb3JUeXBlLFxyXG4gICAgQ2FtZXJhVHlwZSxcclxuICAgIEFjY2Vzc29yQ29tcG9uZW50VHlwZSxcclxuICAgIE1hdGVyaWFsQWxwaGFNb2RlLFxyXG4gICAgVGV4dHVyZU1pbkZpbHRlcixcclxuICAgIFRleHR1cmVXcmFwTW9kZSxcclxuICAgIFRleHR1cmVNYWdGaWx0ZXIsXHJcbiAgICBNZXNoUHJpbWl0aXZlTW9kZSxcclxufSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB0eXBlIHtcclxuICAgIElHTFRGLFxyXG4gICAgSVNhbXBsZXIsXHJcbiAgICBJTm9kZSxcclxuICAgIElTY2VuZSxcclxuICAgIElNZXNoLFxyXG4gICAgSUFjY2Vzc29yLFxyXG4gICAgSVNraW4sXHJcbiAgICBJQ2FtZXJhLFxyXG4gICAgSUFuaW1hdGlvbixcclxuICAgIElCdWZmZXIsXHJcbiAgICBJQnVmZmVyVmlldyxcclxuICAgIElNYXRlcmlhbFBick1ldGFsbGljUm91Z2huZXNzLFxyXG4gICAgSU1hdGVyaWFsLFxyXG4gICAgSVRleHR1cmVJbmZvLFxyXG4gICAgSVRleHR1cmUsXHJcbiAgICBJSW1hZ2UsXHJcbiAgICBJTWVzaFByaW1pdGl2ZSxcclxuICAgIElBcnJheUl0ZW0sXHJcbiAgICBfSVNhbXBsZXJEYXRhLFxyXG4gICAgSUFuaW1hdGlvbkNoYW5uZWwsXHJcbiAgICBJQW5pbWF0aW9uU2FtcGxlcixcclxuICAgIF9JQW5pbWF0aW9uU2FtcGxlckRhdGEsXHJcbn0gZnJvbSBcIi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlciwgSUdMVEZMb2FkZXJEYXRhIH0gZnJvbSBcIi4uL2dsVEZGaWxlTG9hZGVyXCI7XHJcbmltcG9ydCB7IEdMVEZGaWxlTG9hZGVyLCBHTFRGTG9hZGVyU3RhdGUsIEdMVEZMb2FkZXJDb29yZGluYXRlU3lzdGVtTW9kZSwgR0xURkxvYWRlckFuaW1hdGlvblN0YXJ0TW9kZSB9IGZyb20gXCIuLi9nbFRGRmlsZUxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IElEYXRhQnVmZmVyIH0gZnJvbSBcImNvcmUvTWlzYy9kYXRhUmVhZGVyXCI7XHJcbmltcG9ydCB7IERlY29kZUJhc2U2NFVybFRvQmluYXJ5LCBJc0Jhc2U2NERhdGFVcmwsIExvYWRGaWxlRXJyb3IgfSBmcm9tIFwiY29yZS9NaXNjL2ZpbGVUb29sc1wiO1xyXG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tIFwiY29yZS9NaXNjL2xvZ2dlclwiO1xyXG5pbXBvcnQgdHlwZSB7IExpZ2h0IH0gZnJvbSBcImNvcmUvTGlnaHRzL2xpZ2h0XCI7XHJcbmltcG9ydCB7IEJvdW5kaW5nSW5mbyB9IGZyb20gXCJjb3JlL0N1bGxpbmcvYm91bmRpbmdJbmZvXCI7XHJcbmltcG9ydCB0eXBlIHsgQXNzZXRDb250YWluZXIgfSBmcm9tIFwiY29yZS9hc3NldENvbnRhaW5lclwiO1xyXG5pbXBvcnQgdHlwZSB7IEFuaW1hdGlvblByb3BlcnR5SW5mbyB9IGZyb20gXCIuL2dsVEZMb2FkZXJBbmltYXRpb25cIjtcclxuaW1wb3J0IHsgbm9kZUFuaW1hdGlvbkRhdGEgfSBmcm9tIFwiLi9nbFRGTG9hZGVyQW5pbWF0aW9uXCI7XHJcbmltcG9ydCB0eXBlIHsgSU9iamVjdEluZm8gfSBmcm9tIFwiY29yZS9PYmplY3RNb2RlbC9vYmplY3RNb2RlbEludGVyZmFjZXNcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJlZEdMVEZFeHRlbnNpb25zLCByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcbmltcG9ydCB0eXBlIHsgR0xURkV4dGVuc2lvbkZhY3RvcnkgfSBmcm9tIFwiLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuZXhwb3J0IHsgR0xURkZpbGVMb2FkZXIgfTtcclxuXHJcbmludGVyZmFjZSBUeXBlZEFycmF5TGlrZSBleHRlbmRzIEFycmF5QnVmZmVyVmlldyB7XHJcbiAgICByZWFkb25seSBsZW5ndGg6IG51bWJlcjtcclxuICAgIFtuOiBudW1iZXJdOiBudW1iZXI7XHJcbn1cclxuXHJcbmludGVyZmFjZSBUeXBlZEFycmF5Q29uc3RydWN0b3Ige1xyXG4gICAgbmV3IChsZW5ndGg6IG51bWJlcik6IFR5cGVkQXJyYXlMaWtlO1xyXG4gICAgbmV3IChidWZmZXI6IEFycmF5QnVmZmVyTGlrZSwgYnl0ZU9mZnNldDogbnVtYmVyLCBsZW5ndGg/OiBudW1iZXIpOiBUeXBlZEFycmF5TGlrZTtcclxufVxyXG5cclxuaW50ZXJmYWNlIElMb2FkZXJQcm9wZXJ0eSBleHRlbmRzIElQcm9wZXJ0eSB7XHJcbiAgICBfYWN0aXZlTG9hZGVyRXh0ZW5zaW9uRnVuY3Rpb25zOiB7XHJcbiAgICAgICAgW2lkOiBzdHJpbmddOiBib29sZWFuO1xyXG4gICAgfTtcclxufVxyXG5cclxuaW50ZXJmYWNlIElXaXRoTWV0YWRhdGEge1xyXG4gICAgbWV0YWRhdGE6IGFueTtcclxuICAgIF9pbnRlcm5hbE1ldGFkYXRhOiBhbnk7XHJcbn1cclxuXHJcbi8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS80ODIxODIwOVxyXG5mdW5jdGlvbiBtZXJnZURlZXAoLi4ub2JqZWN0czogYW55W10pOiBhbnkge1xyXG4gICAgY29uc3QgaXNPYmplY3QgPSAob2JqOiBhbnkpID0+IG9iaiAmJiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiO1xyXG5cclxuICAgIHJldHVybiBvYmplY3RzLnJlZHVjZSgocHJldiwgb2JqKSA9PiB7XHJcbiAgICAgICAgT2JqZWN0LmtleXMob2JqKS5mb3JFYWNoKChrZXkpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcFZhbCA9IHByZXZba2V5XTtcclxuICAgICAgICAgICAgY29uc3Qgb1ZhbCA9IG9ialtrZXldO1xyXG5cclxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocFZhbCkgJiYgQXJyYXkuaXNBcnJheShvVmFsKSkge1xyXG4gICAgICAgICAgICAgICAgcHJldltrZXldID0gcFZhbC5jb25jYXQoLi4ub1ZhbCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QocFZhbCkgJiYgaXNPYmplY3Qob1ZhbCkpIHtcclxuICAgICAgICAgICAgICAgIHByZXZba2V5XSA9IG1lcmdlRGVlcChwVmFsLCBvVmFsKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHByZXZba2V5XSA9IG9WYWw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHByZXY7XHJcbiAgICB9LCB7fSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBIZWxwZXIgY2xhc3MgZm9yIHdvcmtpbmcgd2l0aCBhcnJheXMgd2hlbiBsb2FkaW5nIHRoZSBnbFRGIGFzc2V0XHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgQXJyYXlJdGVtIHtcclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhbiBpdGVtIGZyb20gdGhlIGdpdmVuIGFycmF5LlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIGFycmF5IFRoZSBhcnJheSB0byBnZXQgdGhlIGl0ZW0gZnJvbVxyXG4gICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byB0aGUgYXJyYXlcclxuICAgICAqIEByZXR1cm5zIFRoZSBhcnJheSBpdGVtXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgR2V0PFQ+KGNvbnRleHQ6IHN0cmluZywgYXJyYXk6IEFycmF5TGlrZTxUPiB8IHVuZGVmaW5lZCwgaW5kZXg6IG51bWJlciB8IHVuZGVmaW5lZCk6IFQge1xyXG4gICAgICAgIGlmICghYXJyYXkgfHwgaW5kZXggPT0gdW5kZWZpbmVkIHx8ICFhcnJheVtpbmRleF0pIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBGYWlsZWQgdG8gZmluZCBpbmRleCAoJHtpbmRleH0pYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYXJyYXlbaW5kZXhdO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhbiBpdGVtIGZyb20gdGhlIGdpdmVuIGFycmF5IG9yIHJldHVybnMgbnVsbCBpZiBub3QgYXZhaWxhYmxlLlxyXG4gICAgICogQHBhcmFtIGFycmF5IFRoZSBhcnJheSB0byBnZXQgdGhlIGl0ZW0gZnJvbVxyXG4gICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byB0aGUgYXJyYXlcclxuICAgICAqIEByZXR1cm5zIFRoZSBhcnJheSBpdGVtIG9yIG51bGxcclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBUcnlHZXQ8VD4oYXJyYXk6IEFycmF5TGlrZTxUPiB8IHVuZGVmaW5lZCwgaW5kZXg6IG51bWJlciB8IHVuZGVmaW5lZCk6IE51bGxhYmxlPFQ+IHtcclxuICAgICAgICBpZiAoIWFycmF5IHx8IGluZGV4ID09IHVuZGVmaW5lZCB8fCAhYXJyYXlbaW5kZXhdKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGFycmF5W2luZGV4XTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFzc2lnbiBhbiBgaW5kZXhgIGZpZWxkIHRvIGVhY2ggaXRlbSBvZiB0aGUgZ2l2ZW4gYXJyYXkuXHJcbiAgICAgKiBAcGFyYW0gYXJyYXkgVGhlIGFycmF5IG9mIGl0ZW1zXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgQXNzaWduKGFycmF5PzogSUFycmF5SXRlbVtdKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGFycmF5KSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBhcnJheS5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICAgICAgICAgIGFycmF5W2luZGV4XS5pbmRleCA9IGluZGV4O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUFuaW1hdGlvblRhcmdldEluZm8ge1xyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgdGFyZ2V0OiB1bmtub3duO1xyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHByb3BlcnRpZXM6IEFycmF5PEFuaW1hdGlvblByb3BlcnR5SW5mbz47XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUaGUgZ2xURiAyLjAgbG9hZGVyXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgR0xURkxvYWRlciBpbXBsZW1lbnRzIElHTFRGTG9hZGVyIHtcclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBfY29tcGxldGVQcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHVua25vd24+PigpO1xyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBfYXNzZXRDb250YWluZXI6IE51bGxhYmxlPEFzc2V0Q29udGFpbmVyPiA9IG51bGw7XHJcblxyXG4gICAgLyoqIFN0b3JhZ2UgKi9cclxuICAgIHB1YmxpYyBfYmFieWxvbkxpZ2h0czogTGlnaHRbXSA9IFtdO1xyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBfZGlzYWJsZUluc3RhbmNlZE1lc2ggPSAwO1xyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBfYWxsTWF0ZXJpYWxzRGlydHlSZXF1aXJlZCA9IGZhbHNlO1xyXG5cclxuICAgIHByaXZhdGUgcmVhZG9ubHkgX3BhcmVudDogR0xURkZpbGVMb2FkZXI7XHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9leHRlbnNpb25zID0gbmV3IEFycmF5PElHTFRGTG9hZGVyRXh0ZW5zaW9uPigpO1xyXG4gICAgcHJpdmF0ZSBfZGlzcG9zZWQgPSBmYWxzZTtcclxuICAgIHByaXZhdGUgX3Jvb3RVcmw6IE51bGxhYmxlPHN0cmluZz4gPSBudWxsO1xyXG4gICAgcHJpdmF0ZSBfZmlsZU5hbWU6IE51bGxhYmxlPHN0cmluZz4gPSBudWxsO1xyXG4gICAgcHJpdmF0ZSBfdW5pcXVlUm9vdFVybDogTnVsbGFibGU8c3RyaW5nPiA9IG51bGw7XHJcbiAgICBwcml2YXRlIF9nbHRmOiBJR0xURjtcclxuICAgIHByaXZhdGUgX2JpbjogTnVsbGFibGU8SURhdGFCdWZmZXI+ID0gbnVsbDtcclxuICAgIHByaXZhdGUgX2JhYnlsb25TY2VuZTogU2NlbmU7XHJcbiAgICBwcml2YXRlIF9yb290QmFieWxvbk1lc2g6IE51bGxhYmxlPFRyYW5zZm9ybU5vZGU+ID0gbnVsbDtcclxuICAgIHByaXZhdGUgX2RlZmF1bHRCYWJ5bG9uTWF0ZXJpYWxEYXRhOiB7IFtkcmF3TW9kZTogbnVtYmVyXTogTWF0ZXJpYWwgfSA9IHt9O1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBfcG9zdFNjZW5lTG9hZEFjdGlvbnMgPSBuZXcgQXJyYXk8KCkgPT4gdm9pZD4oKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBkZWZhdWx0IGdsVEYgc2FtcGxlci5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBEZWZhdWx0U2FtcGxlcjogSVNhbXBsZXIgPSB7IGluZGV4OiAtMSB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVnaXN0ZXJzIGEgbG9hZGVyIGV4dGVuc2lvbi5cclxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBsb2FkZXIgZXh0ZW5zaW9uLlxyXG4gICAgICogQHBhcmFtIGZhY3RvcnkgVGhlIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIHRoZSBsb2FkZXIgZXh0ZW5zaW9uLlxyXG4gICAgICogQGRlcHJlY2F0ZWQgUGxlYXNlIHVzZSByZWdpc3RlckdMVEZFeHRlbnNpb24gaW5zdGVhZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBSZWdpc3RlckV4dGVuc2lvbihuYW1lOiBzdHJpbmcsIGZhY3Rvcnk6IEdMVEZFeHRlbnNpb25GYWN0b3J5KTogdm9pZCB7XHJcbiAgICAgICAgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKG5hbWUsIGZhbHNlLCBmYWN0b3J5KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFVucmVnaXN0ZXJzIGEgbG9hZGVyIGV4dGVuc2lvbi5cclxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBsb2FkZXIgZXh0ZW5zaW9uLlxyXG4gICAgICogQHJldHVybnMgQSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgZXh0ZW5zaW9uIGhhcyBiZWVuIHVucmVnaXN0ZXJlZFxyXG4gICAgICogQGRlcHJlY2F0ZWQgUGxlYXNlIHVzZSB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiBpbnN0ZWFkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIFVucmVnaXN0ZXJFeHRlbnNpb24obmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKG5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIGdsVEYgSlNPTi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldCBnbHRmKCk6IElHTFRGIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2dsdGYpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZ2xURiBKU09OIGlzIG5vdCBhdmFpbGFibGVcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2x0ZjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBCSU4gY2h1bmsgb2YgYSBiaW5hcnkgZ2xURi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldCBiaW4oKTogTnVsbGFibGU8SURhdGFCdWZmZXI+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYmluO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHBhcmVudCBmaWxlIGxvYWRlci5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldCBwYXJlbnQoKTogR0xURkZpbGVMb2FkZXIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJlbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgQmFieWxvbiBzY2VuZSB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IGJhYnlsb25TY2VuZSgpOiBTY2VuZSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9iYWJ5bG9uU2NlbmUpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU2NlbmUgaXMgbm90IGF2YWlsYWJsZVwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9iYWJ5bG9uU2NlbmU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgcm9vdCBCYWJ5bG9uIG5vZGUgd2hlbiBsb2FkaW5nIHRoZSBhc3NldC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldCByb290QmFieWxvbk1lc2goKTogTnVsbGFibGU8VHJhbnNmb3JtTm9kZT4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yb290QmFieWxvbk1lc2g7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgcm9vdCB1cmwgd2hlbiBsb2FkaW5nIHRoZSBhc3NldC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldCByb290VXJsKCk6IE51bGxhYmxlPHN0cmluZz4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yb290VXJsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKHBhcmVudDogR0xURkZpbGVMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9wYXJlbnQgPSBwYXJlbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2Rpc3Bvc2VkKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2Rpc3Bvc2VkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgdGhpcy5fY29tcGxldGVQcm9taXNlcy5sZW5ndGggPSAwO1xyXG5cclxuICAgICAgICB0aGlzLl9leHRlbnNpb25zLmZvckVhY2goKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLmRpc3Bvc2UgJiYgZXh0ZW5zaW9uLmRpc3Bvc2UoKSk7XHJcbiAgICAgICAgdGhpcy5fZXh0ZW5zaW9ucy5sZW5ndGggPSAwO1xyXG5cclxuICAgICAgICAodGhpcy5fZ2x0ZiBhcyBOdWxsYWJsZTxJR0xURj4pID0gbnVsbDsgLy8gVE9ET1xyXG4gICAgICAgIHRoaXMuX2JpbiA9IG51bGw7XHJcbiAgICAgICAgKHRoaXMuX2JhYnlsb25TY2VuZSBhcyBOdWxsYWJsZTxTY2VuZT4pID0gbnVsbDsgLy8gVE9ET1xyXG4gICAgICAgIHRoaXMuX3Jvb3RCYWJ5bG9uTWVzaCA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5fZGVmYXVsdEJhYnlsb25NYXRlcmlhbERhdGEgPSB7fTtcclxuICAgICAgICB0aGlzLl9wb3N0U2NlbmVMb2FkQWN0aW9ucy5sZW5ndGggPSAwO1xyXG5cclxuICAgICAgICB0aGlzLl9wYXJlbnQuZGlzcG9zZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBpbXBvcnRNZXNoQXN5bmMoXHJcbiAgICAgICAgbWVzaGVzTmFtZXM6IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdIHwgbnVsbCB8IHVuZGVmaW5lZCxcclxuICAgICAgICBzY2VuZTogU2NlbmUsXHJcbiAgICAgICAgY29udGFpbmVyOiBOdWxsYWJsZTxBc3NldENvbnRhaW5lcj4sXHJcbiAgICAgICAgZGF0YTogSUdMVEZMb2FkZXJEYXRhLFxyXG4gICAgICAgIHJvb3RVcmw6IHN0cmluZyxcclxuICAgICAgICBvblByb2dyZXNzPzogKGV2ZW50OiBJU2NlbmVMb2FkZXJQcm9ncmVzc0V2ZW50KSA9PiB2b2lkLFxyXG4gICAgICAgIGZpbGVOYW1lID0gXCJcIlxyXG4gICAgKTogUHJvbWlzZTxJU2NlbmVMb2FkZXJBc3luY1Jlc3VsdD4ge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lID0gc2NlbmU7XHJcbiAgICAgICAgICAgIHRoaXMuX2Fzc2V0Q29udGFpbmVyID0gY29udGFpbmVyO1xyXG4gICAgICAgICAgICB0aGlzLl9sb2FkRGF0YShkYXRhKTtcclxuXHJcbiAgICAgICAgICAgIGxldCBub2RlczogTnVsbGFibGU8QXJyYXk8bnVtYmVyPj4gPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgaWYgKG1lc2hlc05hbWVzKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBub2RlTWFwOiB7IFtuYW1lOiBzdHJpbmddOiBudW1iZXIgfSA9IHt9O1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2dsdGYubm9kZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5fZ2x0Zi5ub2Rlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZS5uYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlTWFwW25vZGUubmFtZV0gPSBub2RlLmluZGV4O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IG5hbWVzID0gbWVzaGVzTmFtZXMgaW5zdGFuY2VvZiBBcnJheSA/IG1lc2hlc05hbWVzIDogW21lc2hlc05hbWVzXTtcclxuICAgICAgICAgICAgICAgIG5vZGVzID0gbmFtZXMubWFwKChuYW1lKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IG5vZGVNYXBbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBmaW5kIG5vZGUgJyR7bmFtZX0nYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZEFzeW5jKHJvb3RVcmwsIGZpbGVOYW1lLCBub2RlcywgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICBtZXNoZXM6IHRoaXMuX2dldE1lc2hlcygpLFxyXG4gICAgICAgICAgICAgICAgICAgIHBhcnRpY2xlU3lzdGVtczogW10sXHJcbiAgICAgICAgICAgICAgICAgICAgc2tlbGV0b25zOiB0aGlzLl9nZXRTa2VsZXRvbnMoKSxcclxuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25Hcm91cHM6IHRoaXMuX2dldEFuaW1hdGlvbkdyb3VwcygpLFxyXG4gICAgICAgICAgICAgICAgICAgIGxpZ2h0czogdGhpcy5fYmFieWxvbkxpZ2h0cyxcclxuICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1Ob2RlczogdGhpcy5fZ2V0VHJhbnNmb3JtTm9kZXMoKSxcclxuICAgICAgICAgICAgICAgICAgICBnZW9tZXRyaWVzOiB0aGlzLl9nZXRHZW9tZXRyaWVzKCksXHJcbiAgICAgICAgICAgICAgICAgICAgc3ByaXRlTWFuYWdlcnM6IFtdLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRBc3luYyhzY2VuZTogU2NlbmUsIGRhdGE6IElHTFRGTG9hZGVyRGF0YSwgcm9vdFVybDogc3RyaW5nLCBvblByb2dyZXNzPzogKGV2ZW50OiBJU2NlbmVMb2FkZXJQcm9ncmVzc0V2ZW50KSA9PiB2b2lkLCBmaWxlTmFtZSA9IFwiXCIpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZSA9IHNjZW5lO1xyXG4gICAgICAgICAgICB0aGlzLl9sb2FkRGF0YShkYXRhKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRBc3luYyhyb290VXJsLCBmaWxlTmFtZSwgbnVsbCwgKCkgPT4gdW5kZWZpbmVkKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkQXN5bmM8VD4ocm9vdFVybDogc3RyaW5nLCBmaWxlTmFtZTogc3RyaW5nLCBub2RlczogTnVsbGFibGU8QXJyYXk8bnVtYmVyPj4sIHJlc3VsdEZ1bmM6ICgpID0+IFQpOiBQcm9taXNlPFQ+IHtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcclxuICAgICAgICAgICAgLnRoZW4oYXN5bmMgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fcm9vdFVybCA9IHJvb3RVcmw7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl91bmlxdWVSb290VXJsID0gIXJvb3RVcmwuc3RhcnRzV2l0aChcImZpbGU6XCIpICYmIGZpbGVOYW1lID8gcm9vdFVybCA6IGAke3Jvb3RVcmx9JHtEYXRlLm5vdygpfS9gO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZmlsZU5hbWUgPSBmaWxlTmFtZTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2FsbE1hdGVyaWFsc0RpcnR5UmVxdWlyZWQgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLl9sb2FkRXh0ZW5zaW9uc0FzeW5jKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgbG9hZGluZ1RvUmVhZHlDb3VudGVyTmFtZSA9IGAke0dMVEZMb2FkZXJTdGF0ZVtHTFRGTG9hZGVyU3RhdGUuTE9BRElOR119ID0+ICR7R0xURkxvYWRlclN0YXRlW0dMVEZMb2FkZXJTdGF0ZS5SRUFEWV19YDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGxvYWRpbmdUb0NvbXBsZXRlQ291bnRlck5hbWUgPSBgJHtHTFRGTG9hZGVyU3RhdGVbR0xURkxvYWRlclN0YXRlLkxPQURJTkddfSA9PiAke0dMVEZMb2FkZXJTdGF0ZVtHTFRGTG9hZGVyU3RhdGUuQ09NUExFVEVdfWA7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5fcGFyZW50Ll9zdGFydFBlcmZvcm1hbmNlQ291bnRlcihsb2FkaW5nVG9SZWFkeUNvdW50ZXJOYW1lKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3BhcmVudC5fc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXIobG9hZGluZ1RvQ29tcGxldGVDb3VudGVyTmFtZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5fcGFyZW50Ll9zZXRTdGF0ZShHTFRGTG9hZGVyU3RhdGUuTE9BRElORyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9leHRlbnNpb25zT25Mb2FkaW5nKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTx1bmtub3duPj4oKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBCbG9jayB0aGUgbWFya2luZyBvZiBtYXRlcmlhbHMgZGlydHkgdW50aWwgdGhlIHNjZW5lIGlzIGxvYWRlZC5cclxuICAgICAgICAgICAgICAgIGNvbnN0IG9sZEJsb2NrTWF0ZXJpYWxEaXJ0eU1lY2hhbmlzbSA9IHRoaXMuX2JhYnlsb25TY2VuZS5ibG9ja01hdGVyaWFsRGlydHlNZWNoYW5pc207XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuYmxvY2tNYXRlcmlhbERpcnR5TWVjaGFuaXNtID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMucGFyZW50LmxvYWRPbmx5TWF0ZXJpYWxzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5sb2FkU2NlbmVBc3luYyhcIi9ub2Rlc1wiLCB7IG5vZGVzOiBub2RlcywgaW5kZXg6IC0xIH0pKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2dsdGYuc2NlbmUgIT0gdW5kZWZpbmVkIHx8ICh0aGlzLl9nbHRmLnNjZW5lcyAmJiB0aGlzLl9nbHRmLnNjZW5lc1swXSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2NlbmUgPSBBcnJheUl0ZW0uR2V0KGAvc2NlbmVgLCB0aGlzLl9nbHRmLnNjZW5lcywgdGhpcy5fZ2x0Zi5zY2VuZSB8fCAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLmxvYWRTY2VuZUFzeW5jKGAvc2NlbmVzLyR7c2NlbmUuaW5kZXh9YCwgc2NlbmUpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnBhcmVudC5za2lwTWF0ZXJpYWxzICYmIHRoaXMucGFyZW50LmxvYWRBbGxNYXRlcmlhbHMgJiYgdGhpcy5fZ2x0Zi5tYXRlcmlhbHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBtID0gMDsgbSA8IHRoaXMuX2dsdGYubWF0ZXJpYWxzLmxlbmd0aDsgKyttKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsID0gdGhpcy5fZ2x0Zi5tYXRlcmlhbHNbbV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBcIi9tYXRlcmlhbHMvXCIgKyBtO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uRHJhd01vZGUgPSBNYXRlcmlhbC5UcmlhbmdsZUZpbGxNb2RlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkTWF0ZXJpYWxBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgbnVsbCwgYmFieWxvbkRyYXdNb2RlLCAoKSA9PiB7fSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBSZXN0b3JlIHRoZSBibG9ja2luZyBvZiBtYXRlcmlhbCBkaXJ0eS5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9hbGxNYXRlcmlhbHNEaXJ0eVJlcXVpcmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBjYW4gaGFwcGVuIGlmIHdlIGFkZCBhIGxpZ2h0IGZvciBpbnN0YW5jZSBhcyBpdCB3aWxsIGltcGFjdCB0aGUgd2hvbGUgc2NlbmUuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBhdXRvbWF0aWNhbGx5IHJlc2V0cyBldmVyeXRoaW5nIGlmIG5lZWRlZC5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuYmxvY2tNYXRlcmlhbERpcnR5TWVjaGFuaXNtID0gb2xkQmxvY2tNYXRlcmlhbERpcnR5TWVjaGFuaXNtO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBCeSBkZWZhdWx0IGEgbmV3bHkgY3JlYXRlZCBtYXRlcmlhbCBpcyBkaXJ0eSBzbyB0aGVyZSBpcyBubyBuZWVkIHRvIGZsYWcgdGhlIGZ1bGwgc2NlbmUgYXMgZGlydHkuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gRm9yIHBlcmYgcmVhc29ucywgd2UgdGhlbiBieXBhc3MgYmxvY2tNYXRlcmlhbERpcnR5TWVjaGFuaXNtIGFzIHRoaXMgd291bGQgXCJkaXJ0eVwiIHRoZSBlbnRpcmUgc2NlbmUuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9mb3JjZUJsb2NrTWF0ZXJpYWxEaXJ0eU1lY2hhbmlzbShvbGRCbG9ja01hdGVyaWFsRGlydHlNZWNoYW5pc20pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9wYXJlbnQuY29tcGlsZU1hdGVyaWFscykge1xyXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fY29tcGlsZU1hdGVyaWFsc0FzeW5jKCkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9wYXJlbnQuY29tcGlsZVNoYWRvd0dlbmVyYXRvcnMpIHtcclxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2NvbXBpbGVTaGFkb3dHZW5lcmF0b3JzQXN5bmMoKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0UHJvbWlzZSA9IFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fcm9vdEJhYnlsb25NZXNoICYmIHRoaXMuX3Jvb3RCYWJ5bG9uTWVzaCAhPT0gdGhpcy5fcGFyZW50LmN1c3RvbVJvb3ROb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Jvb3RCYWJ5bG9uTWVzaC5zZXRFbmFibGVkKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXh0ZW5zaW9uc09uUmVhZHkoKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJlbnQuX3NldFN0YXRlKEdMVEZMb2FkZXJTdGF0ZS5SRUFEWSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0QW5pbWF0aW9ucygpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0RnVuYygpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdFByb21pc2UudGhlbigocmVzdWx0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFyZW50Ll9lbmRQZXJmb3JtYW5jZUNvdW50ZXIobG9hZGluZ1RvUmVhZHlDb3VudGVyTmFtZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIFRvb2xzLlNldEltbWVkaWF0ZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5fZGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByb21pc2UuYWxsKHRoaXMuX2NvbXBsZXRlUHJvbWlzZXMpLnRoZW4oXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJlbnQuX2VuZFBlcmZvcm1hbmNlQ291bnRlcihsb2FkaW5nVG9Db21wbGV0ZUNvdW50ZXJOYW1lKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcmVudC5fc2V0U3RhdGUoR0xURkxvYWRlclN0YXRlLkNPTVBMRVRFKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcmVudC5vbkNvbXBsZXRlT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnModW5kZWZpbmVkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFyZW50Lm9uQ29tcGxldGVPYnNlcnZhYmxlLmNsZWFyKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJlbnQub25FcnJvck9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKGVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFyZW50Lm9uRXJyb3JPYnNlcnZhYmxlLmNsZWFyKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9kaXNwb3NlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcmVudC5vbkVycm9yT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcmVudC5vbkVycm9yT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZERhdGEoZGF0YTogSUdMVEZMb2FkZXJEYXRhKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fZ2x0ZiA9IGRhdGEuanNvbiBhcyBJR0xURjtcclxuICAgICAgICB0aGlzLl9zZXR1cERhdGEoKTtcclxuXHJcbiAgICAgICAgaWYgKGRhdGEuYmluKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlcnMgPSB0aGlzLl9nbHRmLmJ1ZmZlcnM7XHJcbiAgICAgICAgICAgIGlmIChidWZmZXJzICYmIGJ1ZmZlcnNbMF0gJiYgIWJ1ZmZlcnNbMF0udXJpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBiaW5hcnlCdWZmZXIgPSBidWZmZXJzWzBdO1xyXG4gICAgICAgICAgICAgICAgaWYgKGJpbmFyeUJ1ZmZlci5ieXRlTGVuZ3RoIDwgZGF0YS5iaW4uYnl0ZUxlbmd0aCAtIDMgfHwgYmluYXJ5QnVmZmVyLmJ5dGVMZW5ndGggPiBkYXRhLmJpbi5ieXRlTGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLldhcm4oYEJpbmFyeSBidWZmZXIgbGVuZ3RoICgke2JpbmFyeUJ1ZmZlci5ieXRlTGVuZ3RofSkgZnJvbSBKU09OIGRvZXMgbm90IG1hdGNoIGNodW5rIGxlbmd0aCAoJHtkYXRhLmJpbi5ieXRlTGVuZ3RofSlgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9iaW4gPSBkYXRhLmJpbjtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIExvZ2dlci5XYXJuKFwiVW5leHBlY3RlZCBCSU4gY2h1bmtcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfc2V0dXBEYXRhKCk6IHZvaWQge1xyXG4gICAgICAgIEFycmF5SXRlbS5Bc3NpZ24odGhpcy5fZ2x0Zi5hY2Nlc3NvcnMpO1xyXG4gICAgICAgIEFycmF5SXRlbS5Bc3NpZ24odGhpcy5fZ2x0Zi5hbmltYXRpb25zKTtcclxuICAgICAgICBBcnJheUl0ZW0uQXNzaWduKHRoaXMuX2dsdGYuYnVmZmVycyk7XHJcbiAgICAgICAgQXJyYXlJdGVtLkFzc2lnbih0aGlzLl9nbHRmLmJ1ZmZlclZpZXdzKTtcclxuICAgICAgICBBcnJheUl0ZW0uQXNzaWduKHRoaXMuX2dsdGYuY2FtZXJhcyk7XHJcbiAgICAgICAgQXJyYXlJdGVtLkFzc2lnbih0aGlzLl9nbHRmLmltYWdlcyk7XHJcbiAgICAgICAgQXJyYXlJdGVtLkFzc2lnbih0aGlzLl9nbHRmLm1hdGVyaWFscyk7XHJcbiAgICAgICAgQXJyYXlJdGVtLkFzc2lnbih0aGlzLl9nbHRmLm1lc2hlcyk7XHJcbiAgICAgICAgQXJyYXlJdGVtLkFzc2lnbih0aGlzLl9nbHRmLm5vZGVzKTtcclxuICAgICAgICBBcnJheUl0ZW0uQXNzaWduKHRoaXMuX2dsdGYuc2FtcGxlcnMpO1xyXG4gICAgICAgIEFycmF5SXRlbS5Bc3NpZ24odGhpcy5fZ2x0Zi5zY2VuZXMpO1xyXG4gICAgICAgIEFycmF5SXRlbS5Bc3NpZ24odGhpcy5fZ2x0Zi5za2lucyk7XHJcbiAgICAgICAgQXJyYXlJdGVtLkFzc2lnbih0aGlzLl9nbHRmLnRleHR1cmVzKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX2dsdGYubm9kZXMpIHtcclxuICAgICAgICAgICAgY29uc3Qgbm9kZVBhcmVudHM6IHsgW2luZGV4OiBudW1iZXJdOiBudW1iZXIgfSA9IHt9O1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5fZ2x0Zi5ub2Rlcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuY2hpbGRyZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGluZGV4IG9mIG5vZGUuY2hpbGRyZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVBhcmVudHNbaW5kZXhdID0gbm9kZS5pbmRleDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHJvb3ROb2RlID0gdGhpcy5fY3JlYXRlUm9vdE5vZGUoKTtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMuX2dsdGYubm9kZXMpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHBhcmVudEluZGV4ID0gbm9kZVBhcmVudHNbbm9kZS5pbmRleF07XHJcbiAgICAgICAgICAgICAgICBub2RlLnBhcmVudCA9IHBhcmVudEluZGV4ID09PSB1bmRlZmluZWQgPyByb290Tm9kZSA6IHRoaXMuX2dsdGYubm9kZXNbcGFyZW50SW5kZXhdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgX2xvYWRFeHRlbnNpb25zQXN5bmMoKSB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uUHJvbWlzZXM6IFByb21pc2U8SUdMVEZMb2FkZXJFeHRlbnNpb24+W10gPSBbXTtcclxuXHJcbiAgICAgICAgcmVnaXN0ZXJlZEdMVEZFeHRlbnNpb25zLmZvckVhY2goKHJlZ2lzdGVyZWRFeHRlbnNpb24sIG5hbWUpID0+IHtcclxuICAgICAgICAgICAgLy8gRG9uJ3QgbG9hZCBleHBsaWNpdGx5IGRpc2FibGVkIGV4dGVuc2lvbnMuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnBhcmVudC5leHRlbnNpb25PcHRpb25zW25hbWVdPy5lbmFibGVkID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgLy8gQnV0IHdhcm4gaWYgdGhlIGRpc2FibGVkIGV4dGVuc2lvbiBpcyB1c2VkIGJ5IHRoZSBtb2RlbC5cclxuICAgICAgICAgICAgICAgIGlmIChyZWdpc3RlcmVkRXh0ZW5zaW9uLmlzR0xURkV4dGVuc2lvbiAmJiB0aGlzLmlzRXh0ZW5zaW9uVXNlZChuYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5XYXJuKGBFeHRlbnNpb24gJHtuYW1lfSBpcyB1c2VkIGJ1dCBoYXMgYmVlbiBleHBsaWNpdGx5IGRpc2FibGVkLmApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIExvYWQgbG9hZGVyIGV4dGVuc2lvbnMgdGhhdCBhcmUgbm90IGEgZ2xURiBleHRlbnNpb24sIGFzIHdlbGwgYXMgZXh0ZW5zaW9ucyB0aGF0IGFyZSBnbFRGIGV4dGVuc2lvbnMgYW5kIGFyZSB1c2VkIGJ5IHRoZSBtb2RlbC5cclxuICAgICAgICAgICAgZWxzZSBpZiAoIXJlZ2lzdGVyZWRFeHRlbnNpb24uaXNHTFRGRXh0ZW5zaW9uIHx8IHRoaXMuaXNFeHRlbnNpb25Vc2VkKG5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICBleHRlbnNpb25Qcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgIChhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IGF3YWl0IHJlZ2lzdGVyZWRFeHRlbnNpb24uZmFjdG9yeSh0aGlzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbi5uYW1lICE9PSBuYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuV2FybihgVGhlIG5hbWUgb2YgdGhlIGdsVEYgbG9hZGVyIGV4dGVuc2lvbiBpbnN0YW5jZSBkb2VzIG5vdCBtYXRjaCB0aGUgcmVnaXN0ZXJlZCBuYW1lOiAke2V4dGVuc2lvbi5uYW1lfSAhPT0gJHtuYW1lfWApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJlbnQub25FeHRlbnNpb25Mb2FkZWRPYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyhleHRlbnNpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXh0ZW5zaW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pKClcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5fZXh0ZW5zaW9ucy5wdXNoKC4uLihhd2FpdCBQcm9taXNlLmFsbChleHRlbnNpb25Qcm9taXNlcykpKTtcclxuXHJcbiAgICAgICAgdGhpcy5fZXh0ZW5zaW9ucy5zb3J0KChhLCBiKSA9PiAoYS5vcmRlciB8fCBOdW1iZXIuTUFYX1ZBTFVFKSAtIChiLm9yZGVyIHx8IE51bWJlci5NQVhfVkFMVUUpKTtcclxuICAgICAgICB0aGlzLl9wYXJlbnQub25FeHRlbnNpb25Mb2FkZWRPYnNlcnZhYmxlLmNsZWFyKCk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9nbHRmLmV4dGVuc2lvbnNSZXF1aXJlZCkge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgdGhpcy5fZ2x0Zi5leHRlbnNpb25zUmVxdWlyZWQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGF2YWlsYWJsZSA9IHRoaXMuX2V4dGVuc2lvbnMuc29tZSgoZXh0ZW5zaW9uKSA9PiBleHRlbnNpb24ubmFtZSA9PT0gbmFtZSAmJiBleHRlbnNpb24uZW5hYmxlZCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWF2YWlsYWJsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnBhcmVudC5leHRlbnNpb25PcHRpb25zW25hbWVdPy5lbmFibGVkID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlcXVpcmVkIGV4dGVuc2lvbiAke25hbWV9IGlzIGRpc2FibGVkYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUmVxdWlyZWQgZXh0ZW5zaW9uICR7bmFtZX0gaXMgbm90IGF2YWlsYWJsZWApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2NyZWF0ZVJvb3ROb2RlKCk6IElOb2RlIHtcclxuICAgICAgICBpZiAodGhpcy5fcGFyZW50LmN1c3RvbVJvb3ROb2RlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5fcm9vdEJhYnlsb25NZXNoID0gdGhpcy5fcGFyZW50LmN1c3RvbVJvb3ROb2RlO1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG4gICAgICAgICAgICAgICAgX2JhYnlsb25UcmFuc2Zvcm1Ob2RlOiB0aGlzLl9yb290QmFieWxvbk1lc2ggPT09IG51bGwgPyB1bmRlZmluZWQgOiB0aGlzLl9yb290QmFieWxvbk1lc2gsXHJcbiAgICAgICAgICAgICAgICBpbmRleDogLTEsXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gISF0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICBjb25zdCByb290TWVzaCA9IG5ldyBNZXNoKFwiX19yb290X19cIiwgdGhpcy5fYmFieWxvblNjZW5lKTtcclxuICAgICAgICB0aGlzLl9yb290QmFieWxvbk1lc2ggPSByb290TWVzaDtcclxuICAgICAgICB0aGlzLl9yb290QmFieWxvbk1lc2guX3BhcmVudENvbnRhaW5lciA9IHRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5fcm9vdEJhYnlsb25NZXNoLnNldEVuYWJsZWQoZmFsc2UpO1xyXG5cclxuICAgICAgICBjb25zdCByb290Tm9kZTogSU5vZGUgPSB7XHJcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuICAgICAgICAgICAgX2JhYnlsb25UcmFuc2Zvcm1Ob2RlOiB0aGlzLl9yb290QmFieWxvbk1lc2gsXHJcbiAgICAgICAgICAgIGluZGV4OiAtMSxcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBzd2l0Y2ggKHRoaXMuX3BhcmVudC5jb29yZGluYXRlU3lzdGVtTW9kZSkge1xyXG4gICAgICAgICAgICBjYXNlIEdMVEZMb2FkZXJDb29yZGluYXRlU3lzdGVtTW9kZS5BVVRPOiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2JhYnlsb25TY2VuZS51c2VSaWdodEhhbmRlZFN5c3RlbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJvb3ROb2RlLnJvdGF0aW9uID0gWzAsIDEsIDAsIDBdO1xyXG4gICAgICAgICAgICAgICAgICAgIHJvb3ROb2RlLnNjYWxlID0gWzEsIDEsIC0xXTtcclxuICAgICAgICAgICAgICAgICAgICBHTFRGTG9hZGVyLl9Mb2FkVHJhbnNmb3JtKHJvb3ROb2RlLCB0aGlzLl9yb290QmFieWxvbk1lc2gpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBHTFRGTG9hZGVyQ29vcmRpbmF0ZVN5c3RlbU1vZGUuRk9SQ0VfUklHSFRfSEFOREVEOiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUudXNlUmlnaHRIYW5kZWRTeXN0ZW0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZGVmYXVsdDoge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGNvb3JkaW5hdGUgc3lzdGVtIG1vZGUgKCR7dGhpcy5fcGFyZW50LmNvb3JkaW5hdGVTeXN0ZW1Nb2RlfSlgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fcGFyZW50Lm9uTWVzaExvYWRlZE9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKHJvb3RNZXNoKTtcclxuICAgICAgICByZXR1cm4gcm9vdE5vZGU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMb2FkcyBhIGdsVEYgc2NlbmUuXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gc2NlbmUgVGhlIGdsVEYgc2NlbmUgcHJvcGVydHlcclxuICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGxvYWQgaXMgY29tcGxldGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRTY2VuZUFzeW5jKGNvbnRleHQ6IHN0cmluZywgc2NlbmU6IElTY2VuZSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvblByb21pc2UgPSB0aGlzLl9leHRlbnNpb25zTG9hZFNjZW5lQXN5bmMoY29udGV4dCwgc2NlbmUpO1xyXG4gICAgICAgIGlmIChleHRlbnNpb25Qcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHRlbnNpb25Qcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTx1bmtub3duPj4oKTtcclxuXHJcbiAgICAgICAgdGhpcy5sb2dPcGVuKGAke2NvbnRleHR9ICR7c2NlbmUubmFtZSB8fCBcIlwifWApO1xyXG5cclxuICAgICAgICBpZiAoc2NlbmUubm9kZXMpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBpbmRleCBvZiBzY2VuZS5ub2Rlcykge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vbm9kZXMvJHtpbmRleH1gLCB0aGlzLl9nbHRmLm5vZGVzLCBpbmRleCk7XHJcbiAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZE5vZGVBc3luYyhgL25vZGVzLyR7bm9kZS5pbmRleH1gLCBub2RlLCAoYmFieWxvbk1lc2gpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1lc2gucGFyZW50ID0gdGhpcy5fcm9vdEJhYnlsb25NZXNoO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IGFjdGlvbiBvZiB0aGlzLl9wb3N0U2NlbmVMb2FkQWN0aW9ucykge1xyXG4gICAgICAgICAgICBhY3Rpb24oKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZEFuaW1hdGlvbnNBc3luYygpKTtcclxuXHJcbiAgICAgICAgdGhpcy5sb2dDbG9zZSgpO1xyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2ZvckVhY2hQcmltaXRpdmUobm9kZTogSU5vZGUsIGNhbGxiYWNrOiAoYmFieWxvbk1lc2g6IEFic3RyYWN0TWVzaCkgPT4gdm9pZCk6IHZvaWQge1xyXG4gICAgICAgIGlmIChub2RlLl9wcmltaXRpdmVCYWJ5bG9uTWVzaGVzKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgYmFieWxvbk1lc2ggb2Ygbm9kZS5fcHJpbWl0aXZlQmFieWxvbk1lc2hlcykge1xyXG4gICAgICAgICAgICAgICAgY2FsbGJhY2soYmFieWxvbk1lc2gpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2dldEdlb21ldHJpZXMoKTogR2VvbWV0cnlbXSB7XHJcbiAgICAgICAgY29uc3QgZ2VvbWV0cmllczogR2VvbWV0cnlbXSA9IFtdO1xyXG5cclxuICAgICAgICBjb25zdCBub2RlcyA9IHRoaXMuX2dsdGYubm9kZXM7XHJcbiAgICAgICAgaWYgKG5vZGVzKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBub2Rlcykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZm9yRWFjaFByaW1pdGl2ZShub2RlLCAoYmFieWxvbk1lc2gpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBnZW9tZXRyeSA9IChiYWJ5bG9uTWVzaCBhcyBNZXNoKS5nZW9tZXRyeTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZ2VvbWV0cnkgJiYgZ2VvbWV0cmllcy5pbmRleE9mKGdlb21ldHJ5KSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbWV0cmllcy5wdXNoKGdlb21ldHJ5KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGdlb21ldHJpZXM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZ2V0TWVzaGVzKCk6IEFic3RyYWN0TWVzaFtdIHtcclxuICAgICAgICBjb25zdCBtZXNoZXM6IEFic3RyYWN0TWVzaFtdID0gW107XHJcblxyXG4gICAgICAgIC8vIFJvb3QgbWVzaCBpcyBhbHdheXMgZmlyc3QsIGlmIGF2YWlsYWJsZS5cclxuICAgICAgICBpZiAodGhpcy5fcm9vdEJhYnlsb25NZXNoIGluc3RhbmNlb2YgQWJzdHJhY3RNZXNoKSB7XHJcbiAgICAgICAgICAgIG1lc2hlcy5wdXNoKHRoaXMuX3Jvb3RCYWJ5bG9uTWVzaCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBub2RlcyA9IHRoaXMuX2dsdGYubm9kZXM7XHJcbiAgICAgICAgaWYgKG5vZGVzKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBub2Rlcykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZm9yRWFjaFByaW1pdGl2ZShub2RlLCAoYmFieWxvbk1lc2gpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBtZXNoZXMucHVzaChiYWJ5bG9uTWVzaCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG1lc2hlcztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9nZXRUcmFuc2Zvcm1Ob2RlcygpOiBUcmFuc2Zvcm1Ob2RlW10ge1xyXG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybU5vZGVzOiBUcmFuc2Zvcm1Ob2RlW10gPSBbXTtcclxuXHJcbiAgICAgICAgY29uc3Qgbm9kZXMgPSB0aGlzLl9nbHRmLm5vZGVzO1xyXG4gICAgICAgIGlmIChub2Rlcykge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygbm9kZXMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSAmJiBub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZS5nZXRDbGFzc05hbWUoKSA9PT0gXCJUcmFuc2Zvcm1Ob2RlXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1Ob2Rlcy5wdXNoKG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZUZvclNraW4pIHtcclxuICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1Ob2Rlcy5wdXNoKG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlRm9yU2tpbik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0cmFuc2Zvcm1Ob2RlcztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9nZXRTa2VsZXRvbnMoKTogU2tlbGV0b25bXSB7XHJcbiAgICAgICAgY29uc3Qgc2tlbGV0b25zOiBTa2VsZXRvbltdID0gW107XHJcblxyXG4gICAgICAgIGNvbnN0IHNraW5zID0gdGhpcy5fZ2x0Zi5za2lucztcclxuICAgICAgICBpZiAoc2tpbnMpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBza2luIG9mIHNraW5zKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2tpbi5fZGF0YSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNrZWxldG9ucy5wdXNoKHNraW4uX2RhdGEuYmFieWxvblNrZWxldG9uKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHNrZWxldG9ucztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9nZXRBbmltYXRpb25Hcm91cHMoKTogQW5pbWF0aW9uR3JvdXBbXSB7XHJcbiAgICAgICAgY29uc3QgYW5pbWF0aW9uR3JvdXBzOiBBbmltYXRpb25Hcm91cFtdID0gW107XHJcblxyXG4gICAgICAgIGNvbnN0IGFuaW1hdGlvbnMgPSB0aGlzLl9nbHRmLmFuaW1hdGlvbnM7XHJcbiAgICAgICAgaWYgKGFuaW1hdGlvbnMpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBhbmltYXRpb24gb2YgYW5pbWF0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFuaW1hdGlvbi5fYmFieWxvbkFuaW1hdGlvbkdyb3VwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uR3JvdXBzLnB1c2goYW5pbWF0aW9uLl9iYWJ5bG9uQW5pbWF0aW9uR3JvdXApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYW5pbWF0aW9uR3JvdXBzO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3N0YXJ0QW5pbWF0aW9ucygpOiB2b2lkIHtcclxuICAgICAgICBzd2l0Y2ggKHRoaXMuX3BhcmVudC5hbmltYXRpb25TdGFydE1vZGUpIHtcclxuICAgICAgICAgICAgY2FzZSBHTFRGTG9hZGVyQW5pbWF0aW9uU3RhcnRNb2RlLk5PTkU6IHtcclxuICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmdcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgR0xURkxvYWRlckFuaW1hdGlvblN0YXJ0TW9kZS5GSVJTVDoge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYmFieWxvbkFuaW1hdGlvbkdyb3VwcyA9IHRoaXMuX2dldEFuaW1hdGlvbkdyb3VwcygpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGJhYnlsb25BbmltYXRpb25Hcm91cHMubGVuZ3RoICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbkFuaW1hdGlvbkdyb3Vwc1swXS5zdGFydCh0cnVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgR0xURkxvYWRlckFuaW1hdGlvblN0YXJ0TW9kZS5BTEw6IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJhYnlsb25BbmltYXRpb25Hcm91cHMgPSB0aGlzLl9nZXRBbmltYXRpb25Hcm91cHMoKTtcclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYmFieWxvbkFuaW1hdGlvbkdyb3VwIG9mIGJhYnlsb25BbmltYXRpb25Hcm91cHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uQW5pbWF0aW9uR3JvdXAuc3RhcnQodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBkZWZhdWx0OiB7XHJcbiAgICAgICAgICAgICAgICBMb2dnZXIuRXJyb3IoYEludmFsaWQgYW5pbWF0aW9uIHN0YXJ0IG1vZGUgKCR7dGhpcy5fcGFyZW50LmFuaW1hdGlvblN0YXJ0TW9kZX0pYCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMb2FkcyBhIGdsVEYgbm9kZS5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBub2RlIFRoZSBnbFRGIG5vZGUgcHJvcGVydHlcclxuICAgICAqIEBwYXJhbSBhc3NpZ24gQSBmdW5jdGlvbiBjYWxsZWQgc3luY2hyb25vdXNseSBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXNcclxuICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGxvYWRlZCBCYWJ5bG9uIG1lc2ggd2hlbiB0aGUgbG9hZCBpcyBjb21wbGV0ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE5vZGVBc3luYyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IElOb2RlLCBhc3NpZ246IChiYWJ5bG9uVHJhbnNmb3JtTm9kZTogVHJhbnNmb3JtTm9kZSkgPT4gdm9pZCA9ICgpID0+IHt9KTogUHJvbWlzZTxUcmFuc2Zvcm1Ob2RlPiB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uUHJvbWlzZSA9IHRoaXMuX2V4dGVuc2lvbnNMb2FkTm9kZUFzeW5jKGNvbnRleHQsIG5vZGUsIGFzc2lnbik7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvblByb21pc2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvblByb21pc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAobm9kZS5fYmFieWxvblRyYW5zZm9ybU5vZGUpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBJbnZhbGlkIHJlY3Vyc2l2ZSBub2RlIGhpZXJhcmNoeWApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTx1bmtub3duPj4oKTtcclxuXHJcbiAgICAgICAgdGhpcy5sb2dPcGVuKGAke2NvbnRleHR9ICR7bm9kZS5uYW1lIHx8IFwiXCJ9YCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGxvYWROb2RlID0gKGJhYnlsb25UcmFuc2Zvcm1Ob2RlOiBUcmFuc2Zvcm1Ob2RlKSA9PiB7XHJcbiAgICAgICAgICAgIEdMVEZMb2FkZXIuQWRkUG9pbnRlck1ldGFkYXRhKGJhYnlsb25UcmFuc2Zvcm1Ob2RlLCBjb250ZXh0KTtcclxuICAgICAgICAgICAgR0xURkxvYWRlci5fTG9hZFRyYW5zZm9ybShub2RlLCBiYWJ5bG9uVHJhbnNmb3JtTm9kZSk7XHJcblxyXG4gICAgICAgICAgICBpZiAobm9kZS5jYW1lcmEgIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjYW1lcmEgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L2NhbWVyYWAsIHRoaXMuX2dsdGYuY2FtZXJhcywgbm9kZS5jYW1lcmEpO1xyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRDYW1lcmFBc3luYyhgL2NhbWVyYXMvJHtjYW1lcmEuaW5kZXh9YCwgY2FtZXJhLCAoYmFieWxvbkNhbWVyYSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uQ2FtZXJhLnBhcmVudCA9IGJhYnlsb25UcmFuc2Zvcm1Ob2RlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAobm9kZS5jaGlsZHJlbikge1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBpbmRleCBvZiBub2RlLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hpbGROb2RlID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9jaGlsZHJlbi8ke2luZGV4fWAsIHRoaXMuX2dsdGYubm9kZXMsIGluZGV4KTtcclxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWROb2RlQXN5bmMoYC9ub2Rlcy8ke2NoaWxkTm9kZS5pbmRleH1gLCBjaGlsZE5vZGUsIChjaGlsZEJhYnlsb25NZXNoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZEJhYnlsb25NZXNoLnBhcmVudCA9IGJhYnlsb25UcmFuc2Zvcm1Ob2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGFzc2lnbihiYWJ5bG9uVHJhbnNmb3JtTm9kZSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgY29uc3QgaGFzTWVzaCA9IG5vZGUubWVzaCAhPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgY29uc3QgaGFzU2tpbiA9IHRoaXMuX3BhcmVudC5sb2FkU2tpbnMgJiYgbm9kZS5za2luICE9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgaWYgKCFoYXNNZXNoIHx8IGhhc1NraW4pIHtcclxuICAgICAgICAgICAgY29uc3Qgbm9kZU5hbWUgPSBub2RlLm5hbWUgfHwgYG5vZGUke25vZGUuaW5kZXh9YDtcclxuICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSAhIXRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1Ob2RlID0gbmV3IFRyYW5zZm9ybU5vZGUobm9kZU5hbWUsIHRoaXMuX2JhYnlsb25TY2VuZSk7XHJcbiAgICAgICAgICAgIHRyYW5zZm9ybU5vZGUuX3BhcmVudENvbnRhaW5lciA9IHRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICBpZiAobm9kZS5tZXNoID09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgbm9kZS5fYmFieWxvblRyYW5zZm9ybU5vZGUgPSB0cmFuc2Zvcm1Ob2RlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgbm9kZS5fYmFieWxvblRyYW5zZm9ybU5vZGVGb3JTa2luID0gdHJhbnNmb3JtTm9kZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBsb2FkTm9kZSh0cmFuc2Zvcm1Ob2RlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChoYXNNZXNoKSB7XHJcbiAgICAgICAgICAgIGlmIChoYXNTa2luKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL3RyZWUvbWFzdGVyL3NwZWNpZmljYXRpb24vMi4wI3NraW5zIChzZWNvbmQgaW1wbGVtZW50YXRpb24gbm90ZSlcclxuICAgICAgICAgICAgICAgIC8vIFRoaXMgY29kZSBwYXRoIHdpbGwgcGxhY2UgdGhlIHNraW5uZWQgbWVzaCBhcyBhIHNpYmxpbmcgb2YgdGhlIHNrZWxldG9uIHJvb3Qgbm9kZSB3aXRob3V0IGxvYWRpbmcgdGhlXHJcbiAgICAgICAgICAgICAgICAvLyB0cmFuc2Zvcm0sIHdoaWNoIGVmZmVjdGl2ZWx5IGlnbm9yZXMgdGhlIHRyYW5zZm9ybSBvZiB0aGUgc2tpbm5lZCBtZXNoLCBhcyBwZXIgc3BlYy5cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBtZXNoID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9tZXNoYCwgdGhpcy5fZ2x0Zi5tZXNoZXMsIG5vZGUubWVzaCk7XHJcbiAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRNZXNoQXN5bmMoYC9tZXNoZXMvJHttZXNoLmluZGV4fWAsIG5vZGUsIG1lc2gsIChiYWJ5bG9uVHJhbnNmb3JtTm9kZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uVHJhbnNmb3JtTm9kZUZvclNraW4gPSBub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZUZvclNraW4hO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWVyZ2UgdGhlIG1ldGFkYXRhIGZyb20gdGhlIHNraW4gbm9kZSB0byB0aGUgc2tpbm5lZCBtZXNoIGluIGNhc2UgYSBsb2FkZXIgZXh0ZW5zaW9uIGFkZGVkIG1ldGFkYXRhLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uVHJhbnNmb3JtTm9kZS5tZXRhZGF0YSA9IG1lcmdlRGVlcChiYWJ5bG9uVHJhbnNmb3JtTm9kZUZvclNraW4ubWV0YWRhdGEsIGJhYnlsb25UcmFuc2Zvcm1Ob2RlLm1ldGFkYXRhIHx8IHt9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNraW4gPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L3NraW5gLCB0aGlzLl9nbHRmLnNraW5zLCBub2RlLnNraW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZFNraW5Bc3luYyhgL3NraW5zLyR7c2tpbi5pbmRleH1gLCBub2RlLCBza2luLCAoYmFieWxvblNrZWxldG9uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZm9yRWFjaFByaW1pdGl2ZShub2RlLCAoYmFieWxvbk1lc2gpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1lc2guc2tlbGV0b24gPSBiYWJ5bG9uU2tlbGV0b247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdhaXQgdW50aWwgYWxsIHRoZSBub2RlcyBhcmUgcGFyZW50ZWQgYmVmb3JlIHBhcmVudGluZyB0aGUgc2tpbm5lZCBtZXNoLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Bvc3RTY2VuZUxvYWRBY3Rpb25zLnB1c2goKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2tpbi5za2VsZXRvbiAhPSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBsYWNlIHRoZSBza2lubmVkIG1lc2ggbm9kZSBhcyBhIHNpYmxpbmcgb2YgdGhlIHNrZWxldG9uIHJvb3Qgbm9kZS5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBzcGVjaWFsIGNhc2Ugd2hlbiB0aGUgcGFyZW50IG9mIHRoZSBza2VsZXRvbiByb290IGlzIHRoZSBza2lubmVkIG1lc2guXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnROb2RlID0gQXJyYXlJdGVtLkdldChgL3NraW5zLyR7c2tpbi5pbmRleH0vc2tlbGV0b25gLCB0aGlzLl9nbHRmLm5vZGVzLCBza2luLnNrZWxldG9uKS5wYXJlbnQhO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUuaW5kZXggPT09IHBhcmVudE5vZGUuaW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uVHJhbnNmb3JtTm9kZS5wYXJlbnQgPSBiYWJ5bG9uVHJhbnNmb3JtTm9kZUZvclNraW4ucGFyZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uVHJhbnNmb3JtTm9kZS5wYXJlbnQgPSBwYXJlbnROb2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uVHJhbnNmb3JtTm9kZS5wYXJlbnQgPSB0aGlzLl9yb290QmFieWxvbk1lc2g7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcmVudC5vblNraW5Mb2FkZWRPYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyh7IG5vZGU6IGJhYnlsb25UcmFuc2Zvcm1Ob2RlRm9yU2tpbiwgc2tpbm5lZE5vZGU6IGJhYnlsb25UcmFuc2Zvcm1Ob2RlIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG1lc2ggPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L21lc2hgLCB0aGlzLl9nbHRmLm1lc2hlcywgbm9kZS5tZXNoKTtcclxuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZE1lc2hBc3luYyhgL21lc2hlcy8ke21lc2guaW5kZXh9YCwgbm9kZSwgbWVzaCwgbG9hZE5vZGUpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5sb2dDbG9zZSgpO1xyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9mb3JFYWNoUHJpbWl0aXZlKG5vZGUsIChiYWJ5bG9uTWVzaCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKChiYWJ5bG9uTWVzaCBhcyBNZXNoKS5nZW9tZXRyeSAmJiAoYmFieWxvbk1lc2ggYXMgTWVzaCkuZ2VvbWV0cnkhLnVzZUJvdW5kaW5nSW5mb0Zyb21HZW9tZXRyeSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHNpbXBseSBhcHBseSB0aGUgd29ybGQgbWF0cmljZXMgdG8gdGhlIGJvdW5kaW5nIGluZm8gLSB0aGUgZXh0ZW5kcyBhcmUgYWxyZWFkeSBva1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NZXNoLl91cGRhdGVCb3VuZGluZ0luZm8oKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1lc2gucmVmcmVzaEJvdW5kaW5nSW5mbyh0cnVlLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gbm9kZS5fYmFieWxvblRyYW5zZm9ybU5vZGUhO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRNZXNoQXN5bmMoY29udGV4dDogc3RyaW5nLCBub2RlOiBJTm9kZSwgbWVzaDogSU1lc2gsIGFzc2lnbjogKGJhYnlsb25UcmFuc2Zvcm1Ob2RlOiBUcmFuc2Zvcm1Ob2RlKSA9PiB2b2lkKTogUHJvbWlzZTxUcmFuc2Zvcm1Ob2RlPiB7XHJcbiAgICAgICAgY29uc3QgcHJpbWl0aXZlcyA9IG1lc2gucHJpbWl0aXZlcztcclxuICAgICAgICBpZiAoIXByaW1pdGl2ZXMgfHwgIXByaW1pdGl2ZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogUHJpbWl0aXZlcyBhcmUgbWlzc2luZ2ApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHByaW1pdGl2ZXNbMF0uaW5kZXggPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIEFycmF5SXRlbS5Bc3NpZ24ocHJpbWl0aXZlcyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHVua25vd24+PigpO1xyXG5cclxuICAgICAgICB0aGlzLmxvZ09wZW4oYCR7Y29udGV4dH0gJHttZXNoLm5hbWUgfHwgXCJcIn1gKTtcclxuXHJcbiAgICAgICAgY29uc3QgbmFtZSA9IG5vZGUubmFtZSB8fCBgbm9kZSR7bm9kZS5pbmRleH1gO1xyXG5cclxuICAgICAgICBpZiAocHJpbWl0aXZlcy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICAgICAgY29uc3QgcHJpbWl0aXZlID0gbWVzaC5wcmltaXRpdmVzWzBdO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZE1lc2hQcmltaXRpdmVBc3luYyhgJHtjb250ZXh0fS9wcmltaXRpdmVzLyR7cHJpbWl0aXZlLmluZGV4fWAsIG5hbWUsIG5vZGUsIG1lc2gsIHByaW1pdGl2ZSwgKGJhYnlsb25NZXNoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbm9kZS5fYmFieWxvblRyYW5zZm9ybU5vZGUgPSBiYWJ5bG9uTWVzaDtcclxuICAgICAgICAgICAgICAgICAgICBub2RlLl9wcmltaXRpdmVCYWJ5bG9uTWVzaGVzID0gW2JhYnlsb25NZXNoXTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSAhIXRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICBub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSA9IG5ldyBUcmFuc2Zvcm1Ob2RlKG5hbWUsIHRoaXMuX2JhYnlsb25TY2VuZSk7XHJcbiAgICAgICAgICAgIG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlLl9wYXJlbnRDb250YWluZXIgPSB0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSBmYWxzZTtcclxuICAgICAgICAgICAgbm9kZS5fcHJpbWl0aXZlQmFieWxvbk1lc2hlcyA9IFtdO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHByaW1pdGl2ZSBvZiBwcmltaXRpdmVzKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRNZXNoUHJpbWl0aXZlQXN5bmMoYCR7Y29udGV4dH0vcHJpbWl0aXZlcy8ke3ByaW1pdGl2ZS5pbmRleH1gLCBgJHtuYW1lfV9wcmltaXRpdmUke3ByaW1pdGl2ZS5pbmRleH1gLCBub2RlLCBtZXNoLCBwcmltaXRpdmUsIChiYWJ5bG9uTWVzaCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWVzaC5wYXJlbnQgPSBub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuX3ByaW1pdGl2ZUJhYnlsb25NZXNoZXMhLnB1c2goYmFieWxvbk1lc2gpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBhc3NpZ24obm9kZS5fYmFieWxvblRyYW5zZm9ybU5vZGUhKTtcclxuXHJcbiAgICAgICAgdGhpcy5sb2dDbG9zZSgpO1xyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gbm9kZS5fYmFieWxvblRyYW5zZm9ybU5vZGUhO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsIERlZmluZSB0aGlzIG1ldGhvZCB0byBtb2RpZnkgdGhlIGRlZmF1bHQgYmVoYXZpb3Igd2hlbiBsb2FkaW5nIGRhdGEgZm9yIG1lc2ggcHJpbWl0aXZlcy5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBtZXNoIG5hbWUgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIG5vZGUgVGhlIGdsVEYgbm9kZSB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gbWVzaCBUaGUgZ2xURiBtZXNoIHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBwcmltaXRpdmUgVGhlIGdsVEYgbWVzaCBwcmltaXRpdmUgcHJvcGVydHlcclxuICAgICAqIEBwYXJhbSBhc3NpZ24gQSBmdW5jdGlvbiBjYWxsZWQgc3luY2hyb25vdXNseSBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXNcclxuICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGxvYWRlZCBtZXNoIHdoZW4gdGhlIGxvYWQgaXMgY29tcGxldGUgb3IgbnVsbCBpZiBub3QgaGFuZGxlZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvYWRNZXNoUHJpbWl0aXZlQXN5bmMoXHJcbiAgICAgICAgY29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIG5hbWU6IHN0cmluZyxcclxuICAgICAgICBub2RlOiBJTm9kZSxcclxuICAgICAgICBtZXNoOiBJTWVzaCxcclxuICAgICAgICBwcmltaXRpdmU6IElNZXNoUHJpbWl0aXZlLFxyXG4gICAgICAgIGFzc2lnbjogKGJhYnlsb25NZXNoOiBBYnN0cmFjdE1lc2gpID0+IHZvaWRcclxuICAgICk6IFByb21pc2U8QWJzdHJhY3RNZXNoPiB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uUHJvbWlzZSA9IHRoaXMuX2V4dGVuc2lvbnNMb2FkTWVzaFByaW1pdGl2ZUFzeW5jKGNvbnRleHQsIG5hbWUsIG5vZGUsIG1lc2gsIHByaW1pdGl2ZSwgYXNzaWduKTtcclxuICAgICAgICBpZiAoZXh0ZW5zaW9uUHJvbWlzZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZXh0ZW5zaW9uUHJvbWlzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMubG9nT3BlbihgJHtjb250ZXh0fWApO1xyXG5cclxuICAgICAgICBjb25zdCBzaG91bGRJbnN0YW5jZSA9IHRoaXMuX2Rpc2FibGVJbnN0YW5jZWRNZXNoID09PSAwICYmIHRoaXMuX3BhcmVudC5jcmVhdGVJbnN0YW5jZXMgJiYgbm9kZS5za2luID09IHVuZGVmaW5lZCAmJiAhbWVzaC5wcmltaXRpdmVzWzBdLnRhcmdldHM7XHJcblxyXG4gICAgICAgIGxldCBiYWJ5bG9uQWJzdHJhY3RNZXNoOiBBYnN0cmFjdE1lc2g7XHJcbiAgICAgICAgbGV0IHByb21pc2U6IFByb21pc2U8dW5rbm93bj47XHJcblxyXG4gICAgICAgIGlmIChzaG91bGRJbnN0YW5jZSAmJiBwcmltaXRpdmUuX2luc3RhbmNlRGF0YSkge1xyXG4gICAgICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9ICEhdGhpcy5fYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgICAgIGJhYnlsb25BYnN0cmFjdE1lc2ggPSBwcmltaXRpdmUuX2luc3RhbmNlRGF0YS5iYWJ5bG9uU291cmNlTWVzaC5jcmVhdGVJbnN0YW5jZShuYW1lKSBhcyBJbnN0YW5jZWRNZXNoO1xyXG4gICAgICAgICAgICBiYWJ5bG9uQWJzdHJhY3RNZXNoLl9wYXJlbnRDb250YWluZXIgPSB0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSBmYWxzZTtcclxuICAgICAgICAgICAgcHJvbWlzZSA9IHByaW1pdGl2ZS5faW5zdGFuY2VEYXRhLnByb21pc2U7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTx1bmtub3duPj4oKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gISF0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICAgICAgY29uc3QgYmFieWxvbk1lc2ggPSBuZXcgTWVzaChuYW1lLCB0aGlzLl9iYWJ5bG9uU2NlbmUpO1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWVzaC5fcGFyZW50Q29udGFpbmVyID0gdGhpcy5fYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGJhYnlsb25NZXNoLnNpZGVPcmllbnRhdGlvbiA9IHRoaXMuX2JhYnlsb25TY2VuZS51c2VSaWdodEhhbmRlZFN5c3RlbSA/IE1hdGVyaWFsLkNvdW50ZXJDbG9ja1dpc2VTaWRlT3JpZW50YXRpb24gOiBNYXRlcmlhbC5DbG9ja1dpc2VTaWRlT3JpZW50YXRpb247XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVNb3JwaFRhcmdldHMoY29udGV4dCwgbm9kZSwgbWVzaCwgcHJpbWl0aXZlLCBiYWJ5bG9uTWVzaCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkVmVydGV4RGF0YUFzeW5jKGNvbnRleHQsIHByaW1pdGl2ZSwgYmFieWxvbk1lc2gpLnRoZW4oKGJhYnlsb25HZW9tZXRyeSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkTW9ycGhUYXJnZXRzQXN5bmMoY29udGV4dCwgcHJpbWl0aXZlLCBiYWJ5bG9uTWVzaCwgYmFieWxvbkdlb21ldHJ5KS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2Rpc3Bvc2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gISF0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbkdlb21ldHJ5LmFwcGx5VG9NZXNoKGJhYnlsb25NZXNoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbkdlb21ldHJ5Ll9wYXJlbnRDb250YWluZXIgPSB0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBiYWJ5bG9uRHJhd01vZGUgPSBHTFRGTG9hZGVyLl9HZXREcmF3TW9kZShjb250ZXh0LCBwcmltaXRpdmUubW9kZSk7XHJcbiAgICAgICAgICAgIGlmIChwcmltaXRpdmUubWF0ZXJpYWwgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgYmFieWxvbk1hdGVyaWFsID0gdGhpcy5fZGVmYXVsdEJhYnlsb25NYXRlcmlhbERhdGFbYmFieWxvbkRyYXdNb2RlXTtcclxuICAgICAgICAgICAgICAgIGlmICghYmFieWxvbk1hdGVyaWFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsID0gdGhpcy5fY3JlYXRlRGVmYXVsdE1hdGVyaWFsKFwiX19HTFRGTG9hZGVyLl9kZWZhdWx0XCIsIGJhYnlsb25EcmF3TW9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFyZW50Lm9uTWF0ZXJpYWxMb2FkZWRPYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyhiYWJ5bG9uTWF0ZXJpYWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2RlZmF1bHRCYWJ5bG9uTWF0ZXJpYWxEYXRhW2JhYnlsb25EcmF3TW9kZV0gPSBiYWJ5bG9uTWF0ZXJpYWw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWVzaC5tYXRlcmlhbCA9IGJhYnlsb25NYXRlcmlhbDtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5wYXJlbnQuc2tpcE1hdGVyaWFscykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L21hdGVyaWFsYCwgdGhpcy5fZ2x0Zi5tYXRlcmlhbHMsIHByaW1pdGl2ZS5tYXRlcmlhbCk7XHJcbiAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRNYXRlcmlhbEFzeW5jKGAvbWF0ZXJpYWxzLyR7bWF0ZXJpYWwuaW5kZXh9YCwgbWF0ZXJpYWwsIGJhYnlsb25NZXNoLCBiYWJ5bG9uRHJhd01vZGUsIChiYWJ5bG9uTWF0ZXJpYWwpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1lc2gubWF0ZXJpYWwgPSBiYWJ5bG9uTWF0ZXJpYWw7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHByb21pc2UgPSBQcm9taXNlLmFsbChwcm9taXNlcyk7XHJcblxyXG4gICAgICAgICAgICBpZiAoc2hvdWxkSW5zdGFuY2UpIHtcclxuICAgICAgICAgICAgICAgIHByaW1pdGl2ZS5faW5zdGFuY2VEYXRhID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25Tb3VyY2VNZXNoOiBiYWJ5bG9uTWVzaCxcclxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlOiBwcm9taXNlLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgYmFieWxvbkFic3RyYWN0TWVzaCA9IGJhYnlsb25NZXNoO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgR0xURkxvYWRlci5BZGRQb2ludGVyTWV0YWRhdGEoYmFieWxvbkFic3RyYWN0TWVzaCwgY29udGV4dCk7XHJcbiAgICAgICAgdGhpcy5fcGFyZW50Lm9uTWVzaExvYWRlZE9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKGJhYnlsb25BYnN0cmFjdE1lc2gpO1xyXG4gICAgICAgIGFzc2lnbihiYWJ5bG9uQWJzdHJhY3RNZXNoKTtcclxuXHJcbiAgICAgICAgdGhpcy5sb2dDbG9zZSgpO1xyXG5cclxuICAgICAgICByZXR1cm4gcHJvbWlzZS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIGJhYnlsb25BYnN0cmFjdE1lc2g7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZFZlcnRleERhdGFBc3luYyhjb250ZXh0OiBzdHJpbmcsIHByaW1pdGl2ZTogSU1lc2hQcmltaXRpdmUsIGJhYnlsb25NZXNoOiBNZXNoKTogUHJvbWlzZTxHZW9tZXRyeT4ge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvblByb21pc2UgPSB0aGlzLl9leHRlbnNpb25zTG9hZFZlcnRleERhdGFBc3luYyhjb250ZXh0LCBwcmltaXRpdmUsIGJhYnlsb25NZXNoKTtcclxuICAgICAgICBpZiAoZXh0ZW5zaW9uUHJvbWlzZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZXh0ZW5zaW9uUHJvbWlzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBwcmltaXRpdmUuYXR0cmlidXRlcztcclxuICAgICAgICBpZiAoIWF0dHJpYnV0ZXMpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBBdHRyaWJ1dGVzIGFyZSBtaXNzaW5nYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHVua25vd24+PigpO1xyXG5cclxuICAgICAgICBjb25zdCBiYWJ5bG9uR2VvbWV0cnkgPSBuZXcgR2VvbWV0cnkoYmFieWxvbk1lc2gubmFtZSwgdGhpcy5fYmFieWxvblNjZW5lKTtcclxuXHJcbiAgICAgICAgaWYgKHByaW1pdGl2ZS5pbmRpY2VzID09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWVzaC5pc1VuSW5kZXhlZCA9IHRydWU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgYWNjZXNzb3IgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L2luZGljZXNgLCB0aGlzLl9nbHRmLmFjY2Vzc29ycywgcHJpbWl0aXZlLmluZGljZXMpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZEluZGljZXNBY2Nlc3NvckFzeW5jKGAvYWNjZXNzb3JzLyR7YWNjZXNzb3IuaW5kZXh9YCwgYWNjZXNzb3IpLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uR2VvbWV0cnkuc2V0SW5kaWNlcyhkYXRhKTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBsb2FkQXR0cmlidXRlID0gKG5hbWU6IHN0cmluZywga2luZDogc3RyaW5nLCBjYWxsYmFjaz86IChhY2Nlc3NvcjogSUFjY2Vzc29yKSA9PiB2b2lkKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzW25hbWVdID09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBiYWJ5bG9uTWVzaC5fZGVsYXlJbmZvID0gYmFieWxvbk1lc2guX2RlbGF5SW5mbyB8fCBbXTtcclxuICAgICAgICAgICAgaWYgKGJhYnlsb25NZXNoLl9kZWxheUluZm8uaW5kZXhPZihraW5kKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NZXNoLl9kZWxheUluZm8ucHVzaChraW5kKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgYWNjZXNzb3IgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L2F0dHJpYnV0ZXMvJHtuYW1lfWAsIHRoaXMuX2dsdGYuYWNjZXNzb3JzLCBhdHRyaWJ1dGVzW25hbWVdKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRWZXJ0ZXhBY2Nlc3NvckFzeW5jKGAvYWNjZXNzb3JzLyR7YWNjZXNzb3IuaW5kZXh9YCwgYWNjZXNzb3IsIGtpbmQpLnRoZW4oKGJhYnlsb25WZXJ0ZXhCdWZmZXIpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYmFieWxvblZlcnRleEJ1ZmZlci5nZXRLaW5kKCkgPT09IFZlcnRleEJ1ZmZlci5Qb3NpdGlvbktpbmQgJiYgIXRoaXMucGFyZW50LmFsd2F5c0NvbXB1dGVCb3VuZGluZ0JveCAmJiAhYmFieWxvbk1lc2guc2tlbGV0b24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFjY2Vzc29yLm1pbiAmJiBhY2Nlc3Nvci5tYXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1pbiA9IFRtcFZlY3RvcnMuVmVjdG9yM1swXS5jb3B5RnJvbUZsb2F0cyguLi4oYWNjZXNzb3IubWluIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF4ID0gVG1wVmVjdG9ycy5WZWN0b3IzWzFdLmNvcHlGcm9tRmxvYXRzKC4uLihhY2Nlc3Nvci5tYXggYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXJdKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWNjZXNzb3Iubm9ybWFsaXplZCAmJiBhY2Nlc3Nvci5jb21wb25lbnRUeXBlICE9PSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuRkxPQVQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZGl2aWRlciA9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChhY2Nlc3Nvci5jb21wb25lbnRUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQWNjZXNzb3JDb21wb25lbnRUeXBlLkJZVEU6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXZpZGVyID0gMTI3LjA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuVU5TSUdORURfQllURTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpdmlkZXIgPSAyNTUuMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEFjY2Vzc29yQ29tcG9uZW50VHlwZS5TSE9SVDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpdmlkZXIgPSAzMjc2Ny4wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQWNjZXNzb3JDb21wb25lbnRUeXBlLlVOU0lHTkVEX1NIT1JUOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGl2aWRlciA9IDY1NTM1LjA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb25lT3ZlckRpdmlkZXIgPSAxIC8gZGl2aWRlcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4uc2NhbGVJblBsYWNlKG9uZU92ZXJEaXZpZGVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXguc2NhbGVJblBsYWNlKG9uZU92ZXJEaXZpZGVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25HZW9tZXRyeS5fYm91bmRpbmdJbmZvID0gbmV3IEJvdW5kaW5nSW5mbyhtaW4sIG1heCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uR2VvbWV0cnkudXNlQm91bmRpbmdJbmZvRnJvbUdlb21ldHJ5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uR2VvbWV0cnkuc2V0VmVydGljZXNCdWZmZXIoYmFieWxvblZlcnRleEJ1ZmZlciwgYWNjZXNzb3IuY291bnQpO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChraW5kID09IFZlcnRleEJ1ZmZlci5NYXRyaWNlc0luZGljZXNFeHRyYUtpbmQpIHtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NZXNoLm51bUJvbmVJbmZsdWVuY2VycyA9IDg7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xyXG4gICAgICAgICAgICAgICAgY2FsbGJhY2soYWNjZXNzb3IpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlBPU0lUSU9OXCIsIFZlcnRleEJ1ZmZlci5Qb3NpdGlvbktpbmQpO1xyXG4gICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJOT1JNQUxcIiwgVmVydGV4QnVmZmVyLk5vcm1hbEtpbmQpO1xyXG4gICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJUQU5HRU5UXCIsIFZlcnRleEJ1ZmZlci5UYW5nZW50S2luZCk7XHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlRFWENPT1JEXzBcIiwgVmVydGV4QnVmZmVyLlVWS2luZCk7XHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlRFWENPT1JEXzFcIiwgVmVydGV4QnVmZmVyLlVWMktpbmQpO1xyXG4gICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJURVhDT09SRF8yXCIsIFZlcnRleEJ1ZmZlci5VVjNLaW5kKTtcclxuICAgICAgICBsb2FkQXR0cmlidXRlKFwiVEVYQ09PUkRfM1wiLCBWZXJ0ZXhCdWZmZXIuVVY0S2luZCk7XHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlRFWENPT1JEXzRcIiwgVmVydGV4QnVmZmVyLlVWNUtpbmQpO1xyXG4gICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJURVhDT09SRF81XCIsIFZlcnRleEJ1ZmZlci5VVjZLaW5kKTtcclxuICAgICAgICBsb2FkQXR0cmlidXRlKFwiSk9JTlRTXzBcIiwgVmVydGV4QnVmZmVyLk1hdHJpY2VzSW5kaWNlc0tpbmQpO1xyXG4gICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJXRUlHSFRTXzBcIiwgVmVydGV4QnVmZmVyLk1hdHJpY2VzV2VpZ2h0c0tpbmQpO1xyXG4gICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJKT0lOVFNfMVwiLCBWZXJ0ZXhCdWZmZXIuTWF0cmljZXNJbmRpY2VzRXh0cmFLaW5kKTtcclxuICAgICAgICBsb2FkQXR0cmlidXRlKFwiV0VJR0hUU18xXCIsIFZlcnRleEJ1ZmZlci5NYXRyaWNlc1dlaWdodHNFeHRyYUtpbmQpO1xyXG4gICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJDT0xPUl8wXCIsIFZlcnRleEJ1ZmZlci5Db2xvcktpbmQsIChhY2Nlc3NvcikgPT4ge1xyXG4gICAgICAgICAgICBpZiAoYWNjZXNzb3IudHlwZSA9PT0gQWNjZXNzb3JUeXBlLlZFQzQpIHtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NZXNoLmhhc1ZlcnRleEFscGhhID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gYmFieWxvbkdlb21ldHJ5O1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2NyZWF0ZU1vcnBoVGFyZ2V0cyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IElOb2RlLCBtZXNoOiBJTWVzaCwgcHJpbWl0aXZlOiBJTWVzaFByaW1pdGl2ZSwgYmFieWxvbk1lc2g6IE1lc2gpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXByaW1pdGl2ZS50YXJnZXRzIHx8ICF0aGlzLl9wYXJlbnQubG9hZE1vcnBoVGFyZ2V0cykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAobm9kZS5fbnVtTW9ycGhUYXJnZXRzID09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBub2RlLl9udW1Nb3JwaFRhcmdldHMgPSBwcmltaXRpdmUudGFyZ2V0cy5sZW5ndGg7XHJcbiAgICAgICAgfSBlbHNlIGlmIChwcmltaXRpdmUudGFyZ2V0cy5sZW5ndGggIT09IG5vZGUuX251bU1vcnBoVGFyZ2V0cykge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IFByaW1pdGl2ZXMgZG8gbm90IGhhdmUgdGhlIHNhbWUgbnVtYmVyIG9mIHRhcmdldHNgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHRhcmdldE5hbWVzID0gbWVzaC5leHRyYXMgPyBtZXNoLmV4dHJhcy50YXJnZXROYW1lcyA6IG51bGw7XHJcblxyXG4gICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gISF0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICBiYWJ5bG9uTWVzaC5tb3JwaFRhcmdldE1hbmFnZXIgPSBuZXcgTW9ycGhUYXJnZXRNYW5hZ2VyKHRoaXMuX2JhYnlsb25TY2VuZSk7XHJcbiAgICAgICAgYmFieWxvbk1lc2gubW9ycGhUYXJnZXRNYW5hZ2VyLl9wYXJlbnRDb250YWluZXIgPSB0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9IGZhbHNlO1xyXG5cclxuICAgICAgICBiYWJ5bG9uTWVzaC5tb3JwaFRhcmdldE1hbmFnZXIuYXJlVXBkYXRlc0Zyb3plbiA9IHRydWU7XHJcblxyXG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBwcmltaXRpdmUudGFyZ2V0cy5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICAgICAgY29uc3Qgd2VpZ2h0ID0gbm9kZS53ZWlnaHRzID8gbm9kZS53ZWlnaHRzW2luZGV4XSA6IG1lc2gud2VpZ2h0cyA/IG1lc2gud2VpZ2h0c1tpbmRleF0gOiAwO1xyXG4gICAgICAgICAgICBjb25zdCBuYW1lID0gdGFyZ2V0TmFtZXMgPyB0YXJnZXROYW1lc1tpbmRleF0gOiBgbW9ycGhUYXJnZXQke2luZGV4fWA7XHJcbiAgICAgICAgICAgIGJhYnlsb25NZXNoLm1vcnBoVGFyZ2V0TWFuYWdlci5hZGRUYXJnZXQobmV3IE1vcnBoVGFyZ2V0KG5hbWUsIHdlaWdodCwgYmFieWxvbk1lc2guZ2V0U2NlbmUoKSkpO1xyXG4gICAgICAgICAgICAvLyBUT0RPOiB0ZWxsIHRoZSB0YXJnZXQgd2hldGhlciBpdCBoYXMgcG9zaXRpb25zLCBub3JtYWxzLCB0YW5nZW50c1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkTW9ycGhUYXJnZXRzQXN5bmMoY29udGV4dDogc3RyaW5nLCBwcmltaXRpdmU6IElNZXNoUHJpbWl0aXZlLCBiYWJ5bG9uTWVzaDogTWVzaCwgYmFieWxvbkdlb21ldHJ5OiBHZW9tZXRyeSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghcHJpbWl0aXZlLnRhcmdldHMgfHwgIXRoaXMuX3BhcmVudC5sb2FkTW9ycGhUYXJnZXRzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dW5rbm93bj4+KCk7XHJcblxyXG4gICAgICAgIGNvbnN0IG1vcnBoVGFyZ2V0TWFuYWdlciA9IGJhYnlsb25NZXNoLm1vcnBoVGFyZ2V0TWFuYWdlciE7XHJcbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IG1vcnBoVGFyZ2V0TWFuYWdlci5udW1UYXJnZXRzOyBpbmRleCsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJhYnlsb25Nb3JwaFRhcmdldCA9IG1vcnBoVGFyZ2V0TWFuYWdlci5nZXRUYXJnZXQoaW5kZXgpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRNb3JwaFRhcmdldFZlcnRleERhdGFBc3luYyhgJHtjb250ZXh0fS90YXJnZXRzLyR7aW5kZXh9YCwgYmFieWxvbkdlb21ldHJ5LCBwcmltaXRpdmUudGFyZ2V0c1tpbmRleF0sIGJhYnlsb25Nb3JwaFRhcmdldCkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgbW9ycGhUYXJnZXRNYW5hZ2VyLmFyZVVwZGF0ZXNGcm96ZW4gPSBmYWxzZTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkTW9ycGhUYXJnZXRWZXJ0ZXhEYXRhQXN5bmMoY29udGV4dDogc3RyaW5nLCBiYWJ5bG9uR2VvbWV0cnk6IEdlb21ldHJ5LCBhdHRyaWJ1dGVzOiB7IFtuYW1lOiBzdHJpbmddOiBudW1iZXIgfSwgYmFieWxvbk1vcnBoVGFyZ2V0OiBNb3JwaFRhcmdldCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dW5rbm93bj4+KCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGxvYWRBdHRyaWJ1dGUgPSAoYXR0cmlidXRlOiBzdHJpbmcsIGtpbmQ6IHN0cmluZywgc2V0RGF0YTogKGJhYnlsb25WZXJ0ZXhCdWZmZXI6IFZlcnRleEJ1ZmZlciwgZGF0YTogRmxvYXQzMkFycmF5KSA9PiB2b2lkKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzW2F0dHJpYnV0ZV0gPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGJhYnlsb25WZXJ0ZXhCdWZmZXIgPSBiYWJ5bG9uR2VvbWV0cnkuZ2V0VmVydGV4QnVmZmVyKGtpbmQpO1xyXG4gICAgICAgICAgICBpZiAoIWJhYnlsb25WZXJ0ZXhCdWZmZXIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgYWNjZXNzb3IgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9LyR7YXR0cmlidXRlfWAsIHRoaXMuX2dsdGYuYWNjZXNzb3JzLCBhdHRyaWJ1dGVzW2F0dHJpYnV0ZV0pO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZEZsb2F0QWNjZXNzb3JBc3luYyhgL2FjY2Vzc29ycy8ke2FjY2Vzc29yLmluZGV4fWAsIGFjY2Vzc29yKS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0RGF0YShiYWJ5bG9uVmVydGV4QnVmZmVyLCBkYXRhKTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlBPU0lUSU9OXCIsIFZlcnRleEJ1ZmZlci5Qb3NpdGlvbktpbmQsIChiYWJ5bG9uVmVydGV4QnVmZmVyLCBkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9ucyA9IG5ldyBGbG9hdDMyQXJyYXkoZGF0YS5sZW5ndGgpO1xyXG4gICAgICAgICAgICBiYWJ5bG9uVmVydGV4QnVmZmVyLmZvckVhY2goZGF0YS5sZW5ndGgsICh2YWx1ZSwgaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgICAgIHBvc2l0aW9uc1tpbmRleF0gPSBkYXRhW2luZGV4XSArIHZhbHVlO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGJhYnlsb25Nb3JwaFRhcmdldC5zZXRQb3NpdGlvbnMocG9zaXRpb25zKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIk5PUk1BTFwiLCBWZXJ0ZXhCdWZmZXIuTm9ybWFsS2luZCwgKGJhYnlsb25WZXJ0ZXhCdWZmZXIsIGRhdGEpID0+IHtcclxuICAgICAgICAgICAgY29uc3Qgbm9ybWFscyA9IG5ldyBGbG9hdDMyQXJyYXkoZGF0YS5sZW5ndGgpO1xyXG4gICAgICAgICAgICBiYWJ5bG9uVmVydGV4QnVmZmVyLmZvckVhY2gobm9ybWFscy5sZW5ndGgsICh2YWx1ZSwgaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgICAgIG5vcm1hbHNbaW5kZXhdID0gZGF0YVtpbmRleF0gKyB2YWx1ZTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICBiYWJ5bG9uTW9ycGhUYXJnZXQuc2V0Tm9ybWFscyhub3JtYWxzKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlRBTkdFTlRcIiwgVmVydGV4QnVmZmVyLlRhbmdlbnRLaW5kLCAoYmFieWxvblZlcnRleEJ1ZmZlciwgZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCB0YW5nZW50cyA9IG5ldyBGbG9hdDMyQXJyYXkoKGRhdGEubGVuZ3RoIC8gMykgKiA0KTtcclxuICAgICAgICAgICAgbGV0IGRhdGFJbmRleCA9IDA7XHJcbiAgICAgICAgICAgIGJhYnlsb25WZXJ0ZXhCdWZmZXIuZm9yRWFjaCgoZGF0YS5sZW5ndGggLyAzKSAqIDQsICh2YWx1ZSwgaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIFRhbmdlbnQgZGF0YSBmb3IgbW9ycGggdGFyZ2V0cyBpcyBzdG9yZWQgYXMgeHl6IGRlbHRhLlxyXG4gICAgICAgICAgICAgICAgLy8gVGhlIHZlcnRleERhdGEudGFuZ2VudCBpcyBzdG9yZWQgYXMgeHl6dy5cclxuICAgICAgICAgICAgICAgIC8vIFNvIHdlIG5lZWQgdG8gc2tpcCBldmVyeSBmb3VydGggdmVydGV4RGF0YS50YW5nZW50LlxyXG4gICAgICAgICAgICAgICAgaWYgKChpbmRleCArIDEpICUgNCAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRhbmdlbnRzW2RhdGFJbmRleF0gPSBkYXRhW2RhdGFJbmRleF0gKyB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICBkYXRhSW5kZXgrKztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIGJhYnlsb25Nb3JwaFRhcmdldC5zZXRUYW5nZW50cyh0YW5nZW50cyk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX0xvYWRUcmFuc2Zvcm0obm9kZTogSU5vZGUsIGJhYnlsb25Ob2RlOiBUcmFuc2Zvcm1Ob2RlKTogdm9pZCB7XHJcbiAgICAgICAgLy8gSWdub3JlIHRoZSBUUlMgb2Ygc2tpbm5lZCBub2Rlcy5cclxuICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL3RyZWUvbWFzdGVyL3NwZWNpZmljYXRpb24vMi4wI3NraW5zIChzZWNvbmQgaW1wbGVtZW50YXRpb24gbm90ZSlcclxuICAgICAgICBpZiAobm9kZS5za2luICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgcG9zaXRpb24gPSBWZWN0b3IzLlplcm8oKTtcclxuICAgICAgICBsZXQgcm90YXRpb24gPSBRdWF0ZXJuaW9uLklkZW50aXR5KCk7XHJcbiAgICAgICAgbGV0IHNjYWxpbmcgPSBWZWN0b3IzLk9uZSgpO1xyXG5cclxuICAgICAgICBpZiAobm9kZS5tYXRyaXgpIHtcclxuICAgICAgICAgICAgY29uc3QgbWF0cml4ID0gTWF0cml4LkZyb21BcnJheShub2RlLm1hdHJpeCk7XHJcbiAgICAgICAgICAgIG1hdHJpeC5kZWNvbXBvc2Uoc2NhbGluZywgcm90YXRpb24sIHBvc2l0aW9uKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAobm9kZS50cmFuc2xhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgcG9zaXRpb24gPSBWZWN0b3IzLkZyb21BcnJheShub2RlLnRyYW5zbGF0aW9uKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAobm9kZS5yb3RhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgcm90YXRpb24gPSBRdWF0ZXJuaW9uLkZyb21BcnJheShub2RlLnJvdGF0aW9uKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAobm9kZS5zY2FsZSkge1xyXG4gICAgICAgICAgICAgICAgc2NhbGluZyA9IFZlY3RvcjMuRnJvbUFycmF5KG5vZGUuc2NhbGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBiYWJ5bG9uTm9kZS5wb3NpdGlvbiA9IHBvc2l0aW9uO1xyXG4gICAgICAgIGJhYnlsb25Ob2RlLnJvdGF0aW9uUXVhdGVybmlvbiA9IHJvdGF0aW9uO1xyXG4gICAgICAgIGJhYnlsb25Ob2RlLnNjYWxpbmcgPSBzY2FsaW5nO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRTa2luQXN5bmMoY29udGV4dDogc3RyaW5nLCBub2RlOiBJTm9kZSwgc2tpbjogSVNraW4sIGFzc2lnbjogKGJhYnlsb25Ta2VsZXRvbjogU2tlbGV0b24pID0+IHZvaWQpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAoIXRoaXMuX3BhcmVudC5sb2FkU2tpbnMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uUHJvbWlzZSA9IHRoaXMuX2V4dGVuc2lvbnNMb2FkU2tpbkFzeW5jKGNvbnRleHQsIG5vZGUsIHNraW4pO1xyXG4gICAgICAgIGlmIChleHRlbnNpb25Qcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHRlbnNpb25Qcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHNraW4uX2RhdGEpIHtcclxuICAgICAgICAgICAgYXNzaWduKHNraW4uX2RhdGEuYmFieWxvblNrZWxldG9uKTtcclxuICAgICAgICAgICAgcmV0dXJuIHNraW4uX2RhdGEucHJvbWlzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHNrZWxldG9uSWQgPSBgc2tlbGV0b24ke3NraW4uaW5kZXh9YDtcclxuICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9ICEhdGhpcy5fYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgY29uc3QgYmFieWxvblNrZWxldG9uID0gbmV3IFNrZWxldG9uKHNraW4ubmFtZSB8fCBza2VsZXRvbklkLCBza2VsZXRvbklkLCB0aGlzLl9iYWJ5bG9uU2NlbmUpO1xyXG4gICAgICAgIGJhYnlsb25Ta2VsZXRvbi5fcGFyZW50Q29udGFpbmVyID0gdGhpcy5fYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSBmYWxzZTtcclxuXHJcbiAgICAgICAgdGhpcy5fbG9hZEJvbmVzKGNvbnRleHQsIHNraW4sIGJhYnlsb25Ta2VsZXRvbik7XHJcbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRoaXMuX2xvYWRTa2luSW52ZXJzZUJpbmRNYXRyaWNlc0RhdGFBc3luYyhjb250ZXh0LCBza2luKS50aGVuKChpbnZlcnNlQmluZE1hdHJpY2VzRGF0YSkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl91cGRhdGVCb25lTWF0cmljZXMoYmFieWxvblNrZWxldG9uLCBpbnZlcnNlQmluZE1hdHJpY2VzRGF0YSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHNraW4uX2RhdGEgPSB7XHJcbiAgICAgICAgICAgIGJhYnlsb25Ta2VsZXRvbjogYmFieWxvblNrZWxldG9uLFxyXG4gICAgICAgICAgICBwcm9taXNlOiBwcm9taXNlLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGFzc2lnbihiYWJ5bG9uU2tlbGV0b24pO1xyXG5cclxuICAgICAgICByZXR1cm4gcHJvbWlzZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkQm9uZXMoY29udGV4dDogc3RyaW5nLCBza2luOiBJU2tpbiwgYmFieWxvblNrZWxldG9uOiBTa2VsZXRvbik6IHZvaWQge1xyXG4gICAgICAgIGlmIChza2luLnNrZWxldG9uID09IHVuZGVmaW5lZCB8fCB0aGlzLl9wYXJlbnQuYWx3YXlzQ29tcHV0ZVNrZWxldG9uUm9vdE5vZGUpIHtcclxuICAgICAgICAgICAgY29uc3Qgcm9vdE5vZGUgPSB0aGlzLl9maW5kU2tlbGV0b25Sb290Tm9kZShgJHtjb250ZXh0fS9qb2ludHNgLCBza2luLmpvaW50cyk7XHJcbiAgICAgICAgICAgIGlmIChyb290Tm9kZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHNraW4uc2tlbGV0b24gPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNraW4uc2tlbGV0b24gPSByb290Tm9kZS5pbmRleDtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaXNQYXJlbnQgPSAoYTogSU5vZGUsIGI6IElOb2RlKTogYm9vbGVhbiA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBiLnBhcmVudDsgYiA9IGIucGFyZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYi5wYXJlbnQgPT09IGEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNrZWxldG9uTm9kZSA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vc2tlbGV0b25gLCB0aGlzLl9nbHRmLm5vZGVzLCBza2luLnNrZWxldG9uKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2tlbGV0b25Ob2RlICE9PSByb290Tm9kZSAmJiAhaXNQYXJlbnQoc2tlbGV0b25Ob2RlLCByb290Tm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLldhcm4oYCR7Y29udGV4dH0vc2tlbGV0b246IE92ZXJyaWRpbmcgd2l0aCBuZWFyZXN0IGNvbW1vbiBhbmNlc3RvciBhcyBza2VsZXRvbiBub2RlIGlzIG5vdCBhIGNvbW1vbiByb290YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNraW4uc2tlbGV0b24gPSByb290Tm9kZS5pbmRleDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2dnZXIuV2FybihgJHtjb250ZXh0fTogRmFpbGVkIHRvIGZpbmQgY29tbW9uIHJvb3RgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgYmFieWxvbkJvbmVzOiB7IFtpbmRleDogbnVtYmVyXTogQm9uZSB9ID0ge307XHJcbiAgICAgICAgZm9yIChjb25zdCBpbmRleCBvZiBza2luLmpvaW50cykge1xyXG4gICAgICAgICAgICBjb25zdCBub2RlID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9qb2ludHMvJHtpbmRleH1gLCB0aGlzLl9nbHRmLm5vZGVzLCBpbmRleCk7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRCb25lKG5vZGUsIHNraW4sIGJhYnlsb25Ta2VsZXRvbiwgYmFieWxvbkJvbmVzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZmluZFNrZWxldG9uUm9vdE5vZGUoY29udGV4dDogc3RyaW5nLCBqb2ludHM6IEFycmF5PG51bWJlcj4pOiBOdWxsYWJsZTxJTm9kZT4ge1xyXG4gICAgICAgIGlmIChqb2ludHMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcGF0aHM6IHsgW2pvaW50OiBudW1iZXJdOiBBcnJheTxJTm9kZT4gfSA9IHt9O1xyXG4gICAgICAgIGZvciAoY29uc3QgaW5kZXggb2Ygam9pbnRzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhdGg6IElOb2RlW10gPSBbXTtcclxuICAgICAgICAgICAgbGV0IG5vZGUgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9LyR7aW5kZXh9YCwgdGhpcy5fZ2x0Zi5ub2RlcywgaW5kZXgpO1xyXG4gICAgICAgICAgICB3aGlsZSAobm9kZS5pbmRleCAhPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHBhdGgudW5zaGlmdChub2RlKTtcclxuICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudCE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcGF0aHNbaW5kZXhdID0gcGF0aDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCByb290Tm9kZTogTnVsbGFibGU8SU5vZGU+ID0gbnVsbDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgOyArK2kpIHtcclxuICAgICAgICAgICAgbGV0IHBhdGggPSBwYXRoc1tqb2ludHNbMF1dO1xyXG4gICAgICAgICAgICBpZiAoaSA+PSBwYXRoLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJvb3ROb2RlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBub2RlID0gcGF0aFtpXTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDE7IGogPCBqb2ludHMubGVuZ3RoOyArK2opIHtcclxuICAgICAgICAgICAgICAgIHBhdGggPSBwYXRoc1tqb2ludHNbal1dO1xyXG4gICAgICAgICAgICAgICAgaWYgKGkgPj0gcGF0aC5sZW5ndGggfHwgbm9kZSAhPT0gcGF0aFtpXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByb290Tm9kZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcm9vdE5vZGUgPSBub2RlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkQm9uZShub2RlOiBJTm9kZSwgc2tpbjogSVNraW4sIGJhYnlsb25Ta2VsZXRvbjogU2tlbGV0b24sIGJhYnlsb25Cb25lczogeyBbaW5kZXg6IG51bWJlcl06IEJvbmUgfSk6IEJvbmUge1xyXG4gICAgICAgIG5vZGUuX2lzSm9pbnQgPSB0cnVlO1xyXG5cclxuICAgICAgICBsZXQgYmFieWxvbkJvbmUgPSBiYWJ5bG9uQm9uZXNbbm9kZS5pbmRleF07XHJcbiAgICAgICAgaWYgKGJhYnlsb25Cb25lKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBiYWJ5bG9uQm9uZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBwYXJlbnRCYWJ5bG9uQm9uZTogTnVsbGFibGU8Qm9uZT4gPSBudWxsO1xyXG4gICAgICAgIGlmIChub2RlLmluZGV4ICE9PSBza2luLnNrZWxldG9uKSB7XHJcbiAgICAgICAgICAgIGlmIChub2RlLnBhcmVudCAmJiBub2RlLnBhcmVudC5pbmRleCAhPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHBhcmVudEJhYnlsb25Cb25lID0gdGhpcy5fbG9hZEJvbmUobm9kZS5wYXJlbnQsIHNraW4sIGJhYnlsb25Ta2VsZXRvbiwgYmFieWxvbkJvbmVzKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChza2luLnNrZWxldG9uICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIExvZ2dlci5XYXJuKGAvc2tpbnMvJHtza2luLmluZGV4fS9za2VsZXRvbjogU2tlbGV0b24gbm9kZSBpcyBub3QgYSBjb21tb24gcm9vdGApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBib25lSW5kZXggPSBza2luLmpvaW50cy5pbmRleE9mKG5vZGUuaW5kZXgpO1xyXG4gICAgICAgIGJhYnlsb25Cb25lID0gbmV3IEJvbmUobm9kZS5uYW1lIHx8IGBqb2ludCR7bm9kZS5pbmRleH1gLCBiYWJ5bG9uU2tlbGV0b24sIHBhcmVudEJhYnlsb25Cb25lLCB0aGlzLl9nZXROb2RlTWF0cml4KG5vZGUpLCBudWxsLCBudWxsLCBib25lSW5kZXgpO1xyXG4gICAgICAgIGJhYnlsb25Cb25lc1tub2RlLmluZGV4XSA9IGJhYnlsb25Cb25lO1xyXG5cclxuICAgICAgICAvLyBXYWl0IHVudGlsIHRoZSBzY2VuZSBpcyBsb2FkZWQgdG8gZW5zdXJlIHRoZSB0cmFuc2Zvcm0gbm9kZXMgYXJlIGxvYWRlZC5cclxuICAgICAgICB0aGlzLl9wb3N0U2NlbmVMb2FkQWN0aW9ucy5wdXNoKCgpID0+IHtcclxuICAgICAgICAgICAgLy8gTGluayB0aGUgQmFieWxvbiBib25lIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgQmFieWxvbiB0cmFuc2Zvcm0gbm9kZS5cclxuICAgICAgICAgICAgLy8gQSBnbFRGIGpvaW50IGlzIGEgcG9pbnRlciB0byBhIGdsVEYgbm9kZSBpbiB0aGUgZ2xURiBub2RlIGhpZXJhcmNoeSBzaW1pbGFyIHRvIFVuaXR5M0QuXHJcbiAgICAgICAgICAgIGJhYnlsb25Cb25lLmxpbmtUcmFuc2Zvcm1Ob2RlKG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlISk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBiYWJ5bG9uQm9uZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkU2tpbkludmVyc2VCaW5kTWF0cmljZXNEYXRhQXN5bmMoY29udGV4dDogc3RyaW5nLCBza2luOiBJU2tpbik6IFByb21pc2U8TnVsbGFibGU8RmxvYXQzMkFycmF5Pj4ge1xyXG4gICAgICAgIGlmIChza2luLmludmVyc2VCaW5kTWF0cmljZXMgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBhY2Nlc3NvciA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vaW52ZXJzZUJpbmRNYXRyaWNlc2AsIHRoaXMuX2dsdGYuYWNjZXNzb3JzLCBza2luLmludmVyc2VCaW5kTWF0cmljZXMpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkRmxvYXRBY2Nlc3NvckFzeW5jKGAvYWNjZXNzb3JzLyR7YWNjZXNzb3IuaW5kZXh9YCwgYWNjZXNzb3IpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3VwZGF0ZUJvbmVNYXRyaWNlcyhiYWJ5bG9uU2tlbGV0b246IFNrZWxldG9uLCBpbnZlcnNlQmluZE1hdHJpY2VzRGF0YTogTnVsbGFibGU8RmxvYXQzMkFycmF5Pik6IHZvaWQge1xyXG4gICAgICAgIGZvciAoY29uc3QgYmFieWxvbkJvbmUgb2YgYmFieWxvblNrZWxldG9uLmJvbmVzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJhc2VNYXRyaXggPSBNYXRyaXguSWRlbnRpdHkoKTtcclxuICAgICAgICAgICAgY29uc3QgYm9uZUluZGV4ID0gYmFieWxvbkJvbmUuX2luZGV4ITtcclxuICAgICAgICAgICAgaWYgKGludmVyc2VCaW5kTWF0cmljZXNEYXRhICYmIGJvbmVJbmRleCAhPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIE1hdHJpeC5Gcm9tQXJyYXlUb1JlZihpbnZlcnNlQmluZE1hdHJpY2VzRGF0YSwgYm9uZUluZGV4ICogMTYsIGJhc2VNYXRyaXgpO1xyXG4gICAgICAgICAgICAgICAgYmFzZU1hdHJpeC5pbnZlcnRUb1JlZihiYXNlTWF0cml4KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgYmFieWxvblBhcmVudEJvbmUgPSBiYWJ5bG9uQm9uZS5nZXRQYXJlbnQoKTtcclxuICAgICAgICAgICAgaWYgKGJhYnlsb25QYXJlbnRCb25lKSB7XHJcbiAgICAgICAgICAgICAgICBiYXNlTWF0cml4Lm11bHRpcGx5VG9SZWYoYmFieWxvblBhcmVudEJvbmUuZ2V0QWJzb2x1dGVJbnZlcnNlQmluZE1hdHJpeCgpLCBiYXNlTWF0cml4KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgYmFieWxvbkJvbmUudXBkYXRlTWF0cml4KGJhc2VNYXRyaXgsIGZhbHNlLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGJhYnlsb25Cb25lLl91cGRhdGVBYnNvbHV0ZUJpbmRNYXRyaWNlcyh1bmRlZmluZWQsIGZhbHNlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZ2V0Tm9kZU1hdHJpeChub2RlOiBJTm9kZSk6IE1hdHJpeCB7XHJcbiAgICAgICAgcmV0dXJuIG5vZGUubWF0cml4XHJcbiAgICAgICAgICAgID8gTWF0cml4LkZyb21BcnJheShub2RlLm1hdHJpeClcclxuICAgICAgICAgICAgOiBNYXRyaXguQ29tcG9zZShcclxuICAgICAgICAgICAgICAgICAgbm9kZS5zY2FsZSA/IFZlY3RvcjMuRnJvbUFycmF5KG5vZGUuc2NhbGUpIDogVmVjdG9yMy5PbmUoKSxcclxuICAgICAgICAgICAgICAgICAgbm9kZS5yb3RhdGlvbiA/IFF1YXRlcm5pb24uRnJvbUFycmF5KG5vZGUucm90YXRpb24pIDogUXVhdGVybmlvbi5JZGVudGl0eSgpLFxyXG4gICAgICAgICAgICAgICAgICBub2RlLnRyYW5zbGF0aW9uID8gVmVjdG9yMy5Gcm9tQXJyYXkobm9kZS50cmFuc2xhdGlvbikgOiBWZWN0b3IzLlplcm8oKVxyXG4gICAgICAgICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMb2FkcyBhIGdsVEYgY2FtZXJhLlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIGNhbWVyYSBUaGUgZ2xURiBjYW1lcmEgcHJvcGVydHlcclxuICAgICAqIEBwYXJhbSBhc3NpZ24gQSBmdW5jdGlvbiBjYWxsZWQgc3luY2hyb25vdXNseSBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXNcclxuICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGxvYWRlZCBCYWJ5bG9uIGNhbWVyYSB3aGVuIHRoZSBsb2FkIGlzIGNvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkQ2FtZXJhQXN5bmMoY29udGV4dDogc3RyaW5nLCBjYW1lcmE6IElDYW1lcmEsIGFzc2lnbjogKGJhYnlsb25DYW1lcmE6IENhbWVyYSkgPT4gdm9pZCA9ICgpID0+IHt9KTogUHJvbWlzZTxDYW1lcmE+IHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25Qcm9taXNlID0gdGhpcy5fZXh0ZW5zaW9uc0xvYWRDYW1lcmFBc3luYyhjb250ZXh0LCBjYW1lcmEsIGFzc2lnbik7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvblByb21pc2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvblByb21pc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHVua25vd24+PigpO1xyXG5cclxuICAgICAgICB0aGlzLmxvZ09wZW4oYCR7Y29udGV4dH0gJHtjYW1lcmEubmFtZSB8fCBcIlwifWApO1xyXG5cclxuICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9ICEhdGhpcy5fYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgY29uc3QgYmFieWxvbkNhbWVyYSA9IG5ldyBGcmVlQ2FtZXJhKGNhbWVyYS5uYW1lIHx8IGBjYW1lcmEke2NhbWVyYS5pbmRleH1gLCBWZWN0b3IzLlplcm8oKSwgdGhpcy5fYmFieWxvblNjZW5lLCBmYWxzZSk7XHJcbiAgICAgICAgYmFieWxvbkNhbWVyYS5fcGFyZW50Q29udGFpbmVyID0gdGhpcy5fYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSBmYWxzZTtcclxuICAgICAgICBiYWJ5bG9uQ2FtZXJhLmlnbm9yZVBhcmVudFNjYWxpbmcgPSB0cnVlO1xyXG4gICAgICAgIGNhbWVyYS5fYmFieWxvbkNhbWVyYSA9IGJhYnlsb25DYW1lcmE7XHJcblxyXG4gICAgICAgIC8vIFJvdGF0aW9uIGJ5IDE4MCBhcyBnbFRGIGhhcyBhIGRpZmZlcmVudCBjb252ZW50aW9uIHRoYW4gQmFieWxvbi5cclxuICAgICAgICBiYWJ5bG9uQ2FtZXJhLnJvdGF0aW9uLnNldCgwLCBNYXRoLlBJLCAwKTtcclxuXHJcbiAgICAgICAgc3dpdGNoIChjYW1lcmEudHlwZSkge1xyXG4gICAgICAgICAgICBjYXNlIENhbWVyYVR5cGUuUEVSU1BFQ1RJVkU6IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHBlcnNwZWN0aXZlID0gY2FtZXJhLnBlcnNwZWN0aXZlO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFwZXJzcGVjdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogQ2FtZXJhIHBlcnNwZWN0aXZlIHByb3BlcnRpZXMgYXJlIG1pc3NpbmdgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uQ2FtZXJhLmZvdiA9IHBlcnNwZWN0aXZlLnlmb3Y7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uQ2FtZXJhLm1pblogPSBwZXJzcGVjdGl2ZS56bmVhcjtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25DYW1lcmEubWF4WiA9IHBlcnNwZWN0aXZlLnpmYXIgfHwgMDtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgQ2FtZXJhVHlwZS5PUlRIT0dSQVBISUM6IHtcclxuICAgICAgICAgICAgICAgIGlmICghY2FtZXJhLm9ydGhvZ3JhcGhpYykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogQ2FtZXJhIG9ydGhvZ3JhcGhpYyBwcm9wZXJ0aWVzIGFyZSBtaXNzaW5nYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgYmFieWxvbkNhbWVyYS5tb2RlID0gQ2FtZXJhLk9SVEhPR1JBUEhJQ19DQU1FUkE7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uQ2FtZXJhLm9ydGhvTGVmdCA9IC1jYW1lcmEub3J0aG9ncmFwaGljLnhtYWc7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uQ2FtZXJhLm9ydGhvUmlnaHQgPSBjYW1lcmEub3J0aG9ncmFwaGljLnhtYWc7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uQ2FtZXJhLm9ydGhvQm90dG9tID0gLWNhbWVyYS5vcnRob2dyYXBoaWMueW1hZztcclxuICAgICAgICAgICAgICAgIGJhYnlsb25DYW1lcmEub3J0aG9Ub3AgPSBjYW1lcmEub3J0aG9ncmFwaGljLnltYWc7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uQ2FtZXJhLm1pblogPSBjYW1lcmEub3J0aG9ncmFwaGljLnpuZWFyO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbkNhbWVyYS5tYXhaID0gY2FtZXJhLm9ydGhvZ3JhcGhpYy56ZmFyO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZGVmYXVsdDoge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBJbnZhbGlkIGNhbWVyYSB0eXBlICgke2NhbWVyYS50eXBlfSlgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgR0xURkxvYWRlci5BZGRQb2ludGVyTWV0YWRhdGEoYmFieWxvbkNhbWVyYSwgY29udGV4dCk7XHJcbiAgICAgICAgdGhpcy5fcGFyZW50Lm9uQ2FtZXJhTG9hZGVkT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMoYmFieWxvbkNhbWVyYSk7XHJcbiAgICAgICAgYXNzaWduKGJhYnlsb25DYW1lcmEpO1xyXG5cclxuICAgICAgICB0aGlzLmxvZ0Nsb3NlKCk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBiYWJ5bG9uQ2FtZXJhO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRBbmltYXRpb25zQXN5bmMoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgY29uc3QgYW5pbWF0aW9ucyA9IHRoaXMuX2dsdGYuYW5pbWF0aW9ucztcclxuICAgICAgICBpZiAoIWFuaW1hdGlvbnMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTx2b2lkPj4oKTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGFuaW1hdGlvbnMubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGFuaW1hdGlvbiA9IGFuaW1hdGlvbnNbaW5kZXhdO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkQW5pbWF0aW9uQXN5bmMoYC9hbmltYXRpb25zLyR7YW5pbWF0aW9uLmluZGV4fWAsIGFuaW1hdGlvbikudGhlbigoYW5pbWF0aW9uR3JvdXApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBEZWxldGUgdGhlIGFuaW1hdGlvbiBncm91cCBpZiBpdCBlbmRlZCB1cCBub3QgaGF2aW5nIGFueSBhbmltYXRpb25zIGluIGl0LlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhbmltYXRpb25Hcm91cC50YXJnZXRlZEFuaW1hdGlvbnMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbkdyb3VwLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIExvYWRzIGEgZ2xURiBhbmltYXRpb24uXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gYW5pbWF0aW9uIFRoZSBnbFRGIGFuaW1hdGlvbiBwcm9wZXJ0eVxyXG4gICAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgbG9hZGVkIEJhYnlsb24gYW5pbWF0aW9uIGdyb3VwIHdoZW4gdGhlIGxvYWQgaXMgY29tcGxldGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRBbmltYXRpb25Bc3luYyhjb250ZXh0OiBzdHJpbmcsIGFuaW1hdGlvbjogSUFuaW1hdGlvbik6IFByb21pc2U8QW5pbWF0aW9uR3JvdXA+IHtcclxuICAgICAgICBjb25zdCBwcm9taXNlID0gdGhpcy5fZXh0ZW5zaW9uc0xvYWRBbmltYXRpb25Bc3luYyhjb250ZXh0LCBhbmltYXRpb24pO1xyXG4gICAgICAgIGlmIChwcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG4gICAgICAgIHJldHVybiBpbXBvcnQoXCJjb3JlL0FuaW1hdGlvbnMvYW5pbWF0aW9uR3JvdXBcIikudGhlbigoeyBBbmltYXRpb25Hcm91cCB9KSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gISF0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICAgICAgY29uc3QgYmFieWxvbkFuaW1hdGlvbkdyb3VwID0gbmV3IEFuaW1hdGlvbkdyb3VwKGFuaW1hdGlvbi5uYW1lIHx8IGBhbmltYXRpb24ke2FuaW1hdGlvbi5pbmRleH1gLCB0aGlzLl9iYWJ5bG9uU2NlbmUpO1xyXG4gICAgICAgICAgICBiYWJ5bG9uQW5pbWF0aW9uR3JvdXAuX3BhcmVudENvbnRhaW5lciA9IHRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICBhbmltYXRpb24uX2JhYnlsb25BbmltYXRpb25Hcm91cCA9IGJhYnlsb25BbmltYXRpb25Hcm91cDtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dW5rbm93bj4+KCk7XHJcblxyXG4gICAgICAgICAgICBBcnJheUl0ZW0uQXNzaWduKGFuaW1hdGlvbi5jaGFubmVscyk7XHJcbiAgICAgICAgICAgIEFycmF5SXRlbS5Bc3NpZ24oYW5pbWF0aW9uLnNhbXBsZXJzKTtcclxuXHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgY2hhbm5lbCBvZiBhbmltYXRpb24uY2hhbm5lbHMpIHtcclxuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZEFuaW1hdGlvbkNoYW5uZWxBc3luYyhgJHtjb250ZXh0fS9jaGFubmVscy8ke2NoYW5uZWwuaW5kZXh9YCwgY29udGV4dCwgYW5pbWF0aW9uLCBjaGFubmVsLCAoYmFieWxvblRhcmdldCwgYmFieWxvbkFuaW1hdGlvbikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uVGFyZ2V0LmFuaW1hdGlvbnMgPSBiYWJ5bG9uVGFyZ2V0LmFuaW1hdGlvbnMgfHwgW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25UYXJnZXQuYW5pbWF0aW9ucy5wdXNoKGJhYnlsb25BbmltYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uQW5pbWF0aW9uR3JvdXAuYWRkVGFyZ2V0ZWRBbmltYXRpb24oYmFieWxvbkFuaW1hdGlvbiwgYmFieWxvblRhcmdldCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uQW5pbWF0aW9uR3JvdXAubm9ybWFsaXplKDApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJhYnlsb25BbmltYXRpb25Hcm91cDtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaGlkZGVuXHJcbiAgICAgKiBMb2FkcyBhIGdsVEYgYW5pbWF0aW9uIGNoYW5uZWwuXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gYW5pbWF0aW9uQ29udGV4dCBUaGUgY29udGV4dCBvZiB0aGUgYW5pbWF0aW9uIHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBhbmltYXRpb24gVGhlIGdsVEYgYW5pbWF0aW9uIHByb3BlcnR5XHJcbiAgICAgKiBAcGFyYW0gY2hhbm5lbCBUaGUgZ2xURiBhbmltYXRpb24gY2hhbm5lbCBwcm9wZXJ0eVxyXG4gICAgICogQHBhcmFtIG9uTG9hZCBDYWxsZWQgZm9yIGVhY2ggYW5pbWF0aW9uIGxvYWRlZFxyXG4gICAgICogQHJldHVybnMgQSB2b2lkIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBsb2FkIGlzIGNvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbG9hZEFuaW1hdGlvbkNoYW5uZWxBc3luYyhcclxuICAgICAgICBjb250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgYW5pbWF0aW9uQ29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIGFuaW1hdGlvbjogSUFuaW1hdGlvbixcclxuICAgICAgICBjaGFubmVsOiBJQW5pbWF0aW9uQ2hhbm5lbCxcclxuICAgICAgICBvbkxvYWQ6IChiYWJ5bG9uQW5pbWF0YWJsZTogSUFuaW1hdGFibGUsIGJhYnlsb25BbmltYXRpb246IEFuaW1hdGlvbikgPT4gdm9pZFxyXG4gICAgKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRoaXMuX2V4dGVuc2lvbnNMb2FkQW5pbWF0aW9uQ2hhbm5lbEFzeW5jKGNvbnRleHQsIGFuaW1hdGlvbkNvbnRleHQsIGFuaW1hdGlvbiwgY2hhbm5lbCwgb25Mb2FkKTtcclxuICAgICAgICBpZiAocHJvbWlzZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChjaGFubmVsLnRhcmdldC5ub2RlID09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB0YXJnZXROb2RlID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS90YXJnZXQvbm9kZWAsIHRoaXMuX2dsdGYubm9kZXMsIGNoYW5uZWwudGFyZ2V0Lm5vZGUpO1xyXG4gICAgICAgIGNvbnN0IGNoYW5uZWxUYXJnZXRQYXRoID0gY2hhbm5lbC50YXJnZXQucGF0aDtcclxuICAgICAgICBjb25zdCBwYXRoSXNXZWlnaHRzID0gY2hhbm5lbFRhcmdldFBhdGggPT09IEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLldFSUdIVFM7XHJcblxyXG4gICAgICAgIC8vIElnbm9yZSBhbmltYXRpb25zIHRoYXQgaGF2ZSBubyBhbmltYXRpb24gdGFyZ2V0cy5cclxuICAgICAgICBpZiAoKHBhdGhJc1dlaWdodHMgJiYgIXRhcmdldE5vZGUuX251bU1vcnBoVGFyZ2V0cykgfHwgKCFwYXRoSXNXZWlnaHRzICYmICF0YXJnZXROb2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRG9uJ3QgbG9hZCBub2RlIGFuaW1hdGlvbnMgaWYgZGlzYWJsZWQuXHJcbiAgICAgICAgaWYgKCF0aGlzLl9wYXJlbnQubG9hZE5vZGVBbmltYXRpb25zICYmICFwYXRoSXNXZWlnaHRzICYmICF0YXJnZXROb2RlLl9pc0pvaW50KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBwcm9wZXJ0aWVzOiBBcnJheTxBbmltYXRpb25Qcm9wZXJ0eUluZm8+O1xyXG4gICAgICAgIHN3aXRjaCAoY2hhbm5lbFRhcmdldFBhdGgpIHtcclxuICAgICAgICAgICAgY2FzZSBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aC5UUkFOU0xBVElPTjoge1xyXG4gICAgICAgICAgICAgICAgcHJvcGVydGllcyA9IG5vZGVBbmltYXRpb25EYXRhLnRyYW5zbGF0aW9uO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aC5ST1RBVElPTjoge1xyXG4gICAgICAgICAgICAgICAgcHJvcGVydGllcyA9IG5vZGVBbmltYXRpb25EYXRhLnJvdGF0aW9uO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aC5TQ0FMRToge1xyXG4gICAgICAgICAgICAgICAgcHJvcGVydGllcyA9IG5vZGVBbmltYXRpb25EYXRhLnNjYWxlO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aC5XRUlHSFRTOiB7XHJcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzID0gbm9kZUFuaW1hdGlvbkRhdGEud2VpZ2h0cztcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fS90YXJnZXQvcGF0aDogSW52YWxpZCB2YWx1ZSAoJHtjaGFubmVsLnRhcmdldC5wYXRofSlgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgdGFyZ2V0SW5mbzogSU9iamVjdEluZm88QW5pbWF0aW9uUHJvcGVydHlJbmZvW10+ID0ge1xyXG4gICAgICAgICAgICBvYmplY3Q6IHRhcmdldE5vZGUsXHJcbiAgICAgICAgICAgIGluZm86IHByb3BlcnRpZXMsXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRBbmltYXRpb25DaGFubmVsRnJvbVRhcmdldEluZm9Bc3luYyhjb250ZXh0LCBhbmltYXRpb25Db250ZXh0LCBhbmltYXRpb24sIGNoYW5uZWwsIHRhcmdldEluZm8sIG9uTG9hZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaGlkZGVuXHJcbiAgICAgKiBMb2FkcyBhIGdsVEYgYW5pbWF0aW9uIGNoYW5uZWwuXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gYW5pbWF0aW9uQ29udGV4dCBUaGUgY29udGV4dCBvZiB0aGUgYW5pbWF0aW9uIHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBhbmltYXRpb24gVGhlIGdsVEYgYW5pbWF0aW9uIHByb3BlcnR5XHJcbiAgICAgKiBAcGFyYW0gY2hhbm5lbCBUaGUgZ2xURiBhbmltYXRpb24gY2hhbm5lbCBwcm9wZXJ0eVxyXG4gICAgICogQHBhcmFtIHRhcmdldEluZm8gVGhlIGdsVEYgdGFyZ2V0IGFuZCBwcm9wZXJ0aWVzXHJcbiAgICAgKiBAcGFyYW0gb25Mb2FkIENhbGxlZCBmb3IgZWFjaCBhbmltYXRpb24gbG9hZGVkXHJcbiAgICAgKiBAcmV0dXJucyBBIHZvaWQgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGxvYWQgaXMgY29tcGxldGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9sb2FkQW5pbWF0aW9uQ2hhbm5lbEZyb21UYXJnZXRJbmZvQXN5bmMoXHJcbiAgICAgICAgY29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIGFuaW1hdGlvbkNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBhbmltYXRpb246IElBbmltYXRpb24sXHJcbiAgICAgICAgY2hhbm5lbDogSUFuaW1hdGlvbkNoYW5uZWwsXHJcbiAgICAgICAgdGFyZ2V0SW5mbzogSU9iamVjdEluZm88QW5pbWF0aW9uUHJvcGVydHlJbmZvW10+LFxyXG4gICAgICAgIG9uTG9hZDogKGJhYnlsb25BbmltYXRhYmxlOiBJQW5pbWF0YWJsZSwgYmFieWxvbkFuaW1hdGlvbjogQW5pbWF0aW9uKSA9PiB2b2lkXHJcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBjb25zdCBmcHMgPSB0aGlzLnBhcmVudC50YXJnZXRGcHM7XHJcbiAgICAgICAgY29uc3QgaW52ZnBzID0gMSAvIGZwcztcclxuXHJcbiAgICAgICAgY29uc3Qgc2FtcGxlciA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vc2FtcGxlcmAsIGFuaW1hdGlvbi5zYW1wbGVycywgY2hhbm5lbC5zYW1wbGVyKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbG9hZEFuaW1hdGlvblNhbXBsZXJBc3luYyhgJHthbmltYXRpb25Db250ZXh0fS9zYW1wbGVycy8ke2NoYW5uZWwuc2FtcGxlcn1gLCBzYW1wbGVyKS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgIGxldCBudW1BbmltYXRpb25zID0gMDtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IHRhcmdldEluZm8ub2JqZWN0O1xyXG4gICAgICAgICAgICBjb25zdCBwcm9wZXJ0eUluZm9zID0gdGFyZ2V0SW5mby5pbmZvO1xyXG4gICAgICAgICAgICAvLyBFeHRyYWN0IHRoZSBjb3JyZXNwb25kaW5nIHZhbHVlcyBmcm9tIHRoZSByZWFkIHZhbHVlLlxyXG4gICAgICAgICAgICAvLyBHTFRGIHZhbHVlcyBtYXkgYmUgZGlzcGF0Y2hlZCB0byBzZXZlcmFsIEJhYnlsb24gcHJvcGVydGllcy5cclxuICAgICAgICAgICAgLy8gRm9yIGV4YW1wbGUsIGJhc2VDb2xvckZhY3RvciBbYHJgLCBgZ2AsIGBiYCwgYGFgXSBpcyBkaXNwYXRjaGVkIHRvXHJcbiAgICAgICAgICAgIC8vIC0gYWxiZWRvQ29sb3IgYXMgQ29sb3IzKGByYCwgYGdgLCBgYmApXHJcbiAgICAgICAgICAgIC8vIC0gYWxwaGEgYXMgYGFgXHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgcHJvcGVydHlJbmZvIG9mIHByb3BlcnR5SW5mb3MpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmlkZSA9IHByb3BlcnR5SW5mby5nZXRTdHJpZGUodGFyZ2V0KTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gZGF0YS5pbnB1dDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dCA9IGRhdGEub3V0cHV0O1xyXG4gICAgICAgICAgICAgICAgY29uc3Qga2V5cyA9IG5ldyBBcnJheTxJQW5pbWF0aW9uS2V5PihpbnB1dC5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgbGV0IG91dHB1dE9mZnNldCA9IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChkYXRhLmludGVycG9sYXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIEFuaW1hdGlvblNhbXBsZXJJbnRlcnBvbGF0aW9uLlNURVA6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGlucHV0Lmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBwcm9wZXJ0eUluZm8uZ2V0VmFsdWUodGFyZ2V0LCBvdXRwdXQsIG91dHB1dE9mZnNldCwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRPZmZzZXQgKz0gc3RyaWRlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleXNbaW5kZXhdID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lOiBpbnB1dFtpbmRleF0gKiBmcHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVycG9sYXRpb246IEFuaW1hdGlvbktleUludGVycG9sYXRpb24uU1RFUCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uQ1VCSUNTUExJTkU6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGlucHV0Lmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5UYW5nZW50ID0gcHJvcGVydHlJbmZvLmdldFZhbHVlKHRhcmdldCwgb3V0cHV0LCBvdXRwdXRPZmZzZXQsIGludmZwcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRPZmZzZXQgKz0gc3RyaWRlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBwcm9wZXJ0eUluZm8uZ2V0VmFsdWUodGFyZ2V0LCBvdXRwdXQsIG91dHB1dE9mZnNldCwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRPZmZzZXQgKz0gc3RyaWRlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0VGFuZ2VudCA9IHByb3BlcnR5SW5mby5nZXRWYWx1ZSh0YXJnZXQsIG91dHB1dCwgb3V0cHV0T2Zmc2V0LCBpbnZmcHMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0T2Zmc2V0ICs9IHN0cmlkZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlzW2luZGV4XSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZTogaW5wdXRbaW5kZXhdICogZnBzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluVGFuZ2VudDogaW5UYW5nZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRUYW5nZW50OiBvdXRUYW5nZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBBbmltYXRpb25TYW1wbGVySW50ZXJwb2xhdGlvbi5MSU5FQVI6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGlucHV0Lmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBwcm9wZXJ0eUluZm8uZ2V0VmFsdWUodGFyZ2V0LCBvdXRwdXQsIG91dHB1dE9mZnNldCwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRPZmZzZXQgKz0gc3RyaWRlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleXNbaW5kZXhdID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lOiBpbnB1dFtpbmRleF0gKiBmcHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKG91dHB1dE9mZnNldCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBuYW1lID0gYCR7YW5pbWF0aW9uLm5hbWUgfHwgYGFuaW1hdGlvbiR7YW5pbWF0aW9uLmluZGV4fWB9X2NoYW5uZWwke2NoYW5uZWwuaW5kZXh9XyR7bnVtQW5pbWF0aW9uc31gO1xyXG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnR5SW5mby5idWlsZEFuaW1hdGlvbnModGFyZ2V0LCBuYW1lLCBmcHMsIGtleXMsIChiYWJ5bG9uQW5pbWF0YWJsZSwgYmFieWxvbkFuaW1hdGlvbikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICArK251bUFuaW1hdGlvbnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uTG9hZChiYWJ5bG9uQW5pbWF0YWJsZSwgYmFieWxvbkFuaW1hdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkQW5pbWF0aW9uU2FtcGxlckFzeW5jKGNvbnRleHQ6IHN0cmluZywgc2FtcGxlcjogSUFuaW1hdGlvblNhbXBsZXIpOiBQcm9taXNlPF9JQW5pbWF0aW9uU2FtcGxlckRhdGE+IHtcclxuICAgICAgICBpZiAoc2FtcGxlci5fZGF0YSkge1xyXG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlci5fZGF0YTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGludGVycG9sYXRpb24gPSBzYW1wbGVyLmludGVycG9sYXRpb24gfHwgQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uTElORUFSO1xyXG4gICAgICAgIHN3aXRjaCAoaW50ZXJwb2xhdGlvbikge1xyXG4gICAgICAgICAgICBjYXNlIEFuaW1hdGlvblNhbXBsZXJJbnRlcnBvbGF0aW9uLlNURVA6XHJcbiAgICAgICAgICAgIGNhc2UgQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uTElORUFSOlxyXG4gICAgICAgICAgICBjYXNlIEFuaW1hdGlvblNhbXBsZXJJbnRlcnBvbGF0aW9uLkNVQklDU1BMSU5FOiB7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBkZWZhdWx0OiB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH0vaW50ZXJwb2xhdGlvbjogSW52YWxpZCB2YWx1ZSAoJHtzYW1wbGVyLmludGVycG9sYXRpb259KWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBpbnB1dEFjY2Vzc29yID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9pbnB1dGAsIHRoaXMuX2dsdGYuYWNjZXNzb3JzLCBzYW1wbGVyLmlucHV0KTtcclxuICAgICAgICBjb25zdCBvdXRwdXRBY2Nlc3NvciA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vb3V0cHV0YCwgdGhpcy5fZ2x0Zi5hY2Nlc3NvcnMsIHNhbXBsZXIub3V0cHV0KTtcclxuICAgICAgICBzYW1wbGVyLl9kYXRhID0gUHJvbWlzZS5hbGwoW1xyXG4gICAgICAgICAgICB0aGlzLl9sb2FkRmxvYXRBY2Nlc3NvckFzeW5jKGAvYWNjZXNzb3JzLyR7aW5wdXRBY2Nlc3Nvci5pbmRleH1gLCBpbnB1dEFjY2Vzc29yKSxcclxuICAgICAgICAgICAgdGhpcy5fbG9hZEZsb2F0QWNjZXNzb3JBc3luYyhgL2FjY2Vzc29ycy8ke291dHB1dEFjY2Vzc29yLmluZGV4fWAsIG91dHB1dEFjY2Vzc29yKSxcclxuICAgICAgICBdKS50aGVuKChbaW5wdXREYXRhLCBvdXRwdXREYXRhXSkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgaW5wdXQ6IGlucHV0RGF0YSxcclxuICAgICAgICAgICAgICAgIGludGVycG9sYXRpb246IGludGVycG9sYXRpb24sXHJcbiAgICAgICAgICAgICAgICBvdXRwdXQ6IG91dHB1dERhdGEsXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBzYW1wbGVyLl9kYXRhO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9hZHMgYSBnbFRGIGJ1ZmZlci5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBidWZmZXIgVGhlIGdsVEYgYnVmZmVyIHByb3BlcnR5XHJcbiAgICAgKiBAcGFyYW0gYnl0ZU9mZnNldCBUaGUgYnl0ZSBvZmZzZXQgdG8gdXNlXHJcbiAgICAgKiBAcGFyYW0gYnl0ZUxlbmd0aCBUaGUgYnl0ZSBsZW5ndGggdG8gdXNlXHJcbiAgICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBsb2FkZWQgZGF0YSB3aGVuIHRoZSBsb2FkIGlzIGNvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkQnVmZmVyQXN5bmMoY29udGV4dDogc3RyaW5nLCBidWZmZXI6IElCdWZmZXIsIGJ5dGVPZmZzZXQ6IG51bWJlciwgYnl0ZUxlbmd0aDogbnVtYmVyKTogUHJvbWlzZTxBcnJheUJ1ZmZlclZpZXc+IHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25Qcm9taXNlID0gdGhpcy5fZXh0ZW5zaW9uc0xvYWRCdWZmZXJBc3luYyhjb250ZXh0LCBidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpO1xyXG4gICAgICAgIGlmIChleHRlbnNpb25Qcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHRlbnNpb25Qcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFidWZmZXIuX2RhdGEpIHtcclxuICAgICAgICAgICAgaWYgKGJ1ZmZlci51cmkpIHtcclxuICAgICAgICAgICAgICAgIGJ1ZmZlci5fZGF0YSA9IHRoaXMubG9hZFVyaUFzeW5jKGAke2NvbnRleHR9L3VyaWAsIGJ1ZmZlciwgYnVmZmVyLnVyaSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2Jpbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogVXJpIGlzIG1pc3Npbmcgb3IgdGhlIGJpbmFyeSBnbFRGIGlzIG1pc3NpbmcgaXRzIGJpbmFyeSBjaHVua2ApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGJ1ZmZlci5fZGF0YSA9IHRoaXMuX2Jpbi5yZWFkQXN5bmMoMCwgYnVmZmVyLmJ5dGVMZW5ndGgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYnVmZmVyLl9kYXRhLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShkYXRhLmJ1ZmZlciwgZGF0YS5ieXRlT2Zmc2V0ICsgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogJHtlLm1lc3NhZ2V9YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIExvYWRzIGEgZ2xURiBidWZmZXIgdmlldy5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBidWZmZXJWaWV3IFRoZSBnbFRGIGJ1ZmZlciB2aWV3IHByb3BlcnR5XHJcbiAgICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBsb2FkZWQgZGF0YSB3aGVuIHRoZSBsb2FkIGlzIGNvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkQnVmZmVyVmlld0FzeW5jKGNvbnRleHQ6IHN0cmluZywgYnVmZmVyVmlldzogSUJ1ZmZlclZpZXcpOiBQcm9taXNlPEFycmF5QnVmZmVyVmlldz4ge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvblByb21pc2UgPSB0aGlzLl9leHRlbnNpb25zTG9hZEJ1ZmZlclZpZXdBc3luYyhjb250ZXh0LCBidWZmZXJWaWV3KTtcclxuICAgICAgICBpZiAoZXh0ZW5zaW9uUHJvbWlzZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZXh0ZW5zaW9uUHJvbWlzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChidWZmZXJWaWV3Ll9kYXRhKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBidWZmZXJWaWV3Ll9kYXRhO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgYnVmZmVyID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9idWZmZXJgLCB0aGlzLl9nbHRmLmJ1ZmZlcnMsIGJ1ZmZlclZpZXcuYnVmZmVyKTtcclxuICAgICAgICBidWZmZXJWaWV3Ll9kYXRhID0gdGhpcy5sb2FkQnVmZmVyQXN5bmMoYC9idWZmZXJzLyR7YnVmZmVyLmluZGV4fWAsIGJ1ZmZlciwgYnVmZmVyVmlldy5ieXRlT2Zmc2V0IHx8IDAsIGJ1ZmZlclZpZXcuYnl0ZUxlbmd0aCk7XHJcblxyXG4gICAgICAgIHJldHVybiBidWZmZXJWaWV3Ll9kYXRhO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRBY2Nlc3NvckFzeW5jKGNvbnRleHQ6IHN0cmluZywgYWNjZXNzb3I6IElBY2Nlc3NvciwgY29uc3RydWN0b3I6IFR5cGVkQXJyYXlDb25zdHJ1Y3Rvcik6IFByb21pc2U8QXJyYXlCdWZmZXJWaWV3PiB7XHJcbiAgICAgICAgaWYgKGFjY2Vzc29yLl9kYXRhKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBhY2Nlc3Nvci5fZGF0YTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IG51bUNvbXBvbmVudHMgPSBHTFRGTG9hZGVyLl9HZXROdW1Db21wb25lbnRzKGNvbnRleHQsIGFjY2Vzc29yLnR5cGUpO1xyXG4gICAgICAgIGNvbnN0IGJ5dGVTdHJpZGUgPSBudW1Db21wb25lbnRzICogVmVydGV4QnVmZmVyLkdldFR5cGVCeXRlTGVuZ3RoKGFjY2Vzc29yLmNvbXBvbmVudFR5cGUpO1xyXG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IG51bUNvbXBvbmVudHMgKiBhY2Nlc3Nvci5jb3VudDtcclxuXHJcbiAgICAgICAgaWYgKGFjY2Vzc29yLmJ1ZmZlclZpZXcgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGFjY2Vzc29yLl9kYXRhID0gUHJvbWlzZS5yZXNvbHZlKG5ldyBjb25zdHJ1Y3RvcihsZW5ndGgpKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBidWZmZXJWaWV3ID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9idWZmZXJWaWV3YCwgdGhpcy5fZ2x0Zi5idWZmZXJWaWV3cywgYWNjZXNzb3IuYnVmZmVyVmlldyk7XHJcbiAgICAgICAgICAgIGFjY2Vzc29yLl9kYXRhID0gdGhpcy5sb2FkQnVmZmVyVmlld0FzeW5jKGAvYnVmZmVyVmlld3MvJHtidWZmZXJWaWV3LmluZGV4fWAsIGJ1ZmZlclZpZXcpLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChhY2Nlc3Nvci5jb21wb25lbnRUeXBlID09PSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuRkxPQVQgJiYgIWFjY2Vzc29yLm5vcm1hbGl6ZWQgJiYgKCFidWZmZXJWaWV3LmJ5dGVTdHJpZGUgfHwgYnVmZmVyVmlldy5ieXRlU3RyaWRlID09PSBieXRlU3RyaWRlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBHTFRGTG9hZGVyLl9HZXRUeXBlZEFycmF5KGNvbnRleHQsIGFjY2Vzc29yLmNvbXBvbmVudFR5cGUsIGRhdGEsIGFjY2Vzc29yLmJ5dGVPZmZzZXQsIGxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVkQXJyYXkgPSBuZXcgY29uc3RydWN0b3IobGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhCdWZmZXIuRm9yRWFjaChcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3IuYnl0ZU9mZnNldCB8fCAwLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBidWZmZXJWaWV3LmJ5dGVTdHJpZGUgfHwgYnl0ZVN0cmlkZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgbnVtQ29tcG9uZW50cyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3IuY29tcG9uZW50VHlwZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZWRBcnJheS5sZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzc29yLm5vcm1hbGl6ZWQgfHwgZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICh2YWx1ZSwgaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVkQXJyYXlbaW5kZXhdID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlZEFycmF5O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChhY2Nlc3Nvci5zcGFyc2UpIHtcclxuICAgICAgICAgICAgY29uc3Qgc3BhcnNlID0gYWNjZXNzb3Iuc3BhcnNlO1xyXG4gICAgICAgICAgICBhY2Nlc3Nvci5fZGF0YSA9IGFjY2Vzc29yLl9kYXRhLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVkQXJyYXkgPSBkYXRhIGFzIFR5cGVkQXJyYXlMaWtlO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaW5kaWNlc0J1ZmZlclZpZXcgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L3NwYXJzZS9pbmRpY2VzL2J1ZmZlclZpZXdgLCB0aGlzLl9nbHRmLmJ1ZmZlclZpZXdzLCBzcGFyc2UuaW5kaWNlcy5idWZmZXJWaWV3KTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlc0J1ZmZlclZpZXcgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L3NwYXJzZS92YWx1ZXMvYnVmZmVyVmlld2AsIHRoaXMuX2dsdGYuYnVmZmVyVmlld3MsIHNwYXJzZS52YWx1ZXMuYnVmZmVyVmlldyk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZEJ1ZmZlclZpZXdBc3luYyhgL2J1ZmZlclZpZXdzLyR7aW5kaWNlc0J1ZmZlclZpZXcuaW5kZXh9YCwgaW5kaWNlc0J1ZmZlclZpZXcpLFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZEJ1ZmZlclZpZXdBc3luYyhgL2J1ZmZlclZpZXdzLyR7dmFsdWVzQnVmZmVyVmlldy5pbmRleH1gLCB2YWx1ZXNCdWZmZXJWaWV3KSxcclxuICAgICAgICAgICAgICAgIF0pLnRoZW4oKFtpbmRpY2VzRGF0YSwgdmFsdWVzRGF0YV0pID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRpY2VzID0gR0xURkxvYWRlci5fR2V0VHlwZWRBcnJheShcclxuICAgICAgICAgICAgICAgICAgICAgICAgYCR7Y29udGV4dH0vc3BhcnNlL2luZGljZXNgLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzcGFyc2UuaW5kaWNlcy5jb21wb25lbnRUeXBlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRpY2VzRGF0YSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3BhcnNlLmluZGljZXMuYnl0ZU9mZnNldCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3BhcnNlLmNvdW50XHJcbiAgICAgICAgICAgICAgICAgICAgKSBhcyBJbmRpY2VzQXJyYXk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwYXJzZUxlbmd0aCA9IG51bUNvbXBvbmVudHMgKiBzcGFyc2UuY291bnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHZhbHVlczogVHlwZWRBcnJheUxpa2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhY2Nlc3Nvci5jb21wb25lbnRUeXBlID09PSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuRkxPQVQgJiYgIWFjY2Vzc29yLm5vcm1hbGl6ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gR0xURkxvYWRlci5fR2V0VHlwZWRBcnJheShgJHtjb250ZXh0fS9zcGFyc2UvdmFsdWVzYCwgYWNjZXNzb3IuY29tcG9uZW50VHlwZSwgdmFsdWVzRGF0YSwgc3BhcnNlLnZhbHVlcy5ieXRlT2Zmc2V0LCBzcGFyc2VMZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwYXJzZURhdGEgPSBHTFRGTG9hZGVyLl9HZXRUeXBlZEFycmF5KGAke2NvbnRleHR9L3NwYXJzZS92YWx1ZXNgLCBhY2Nlc3Nvci5jb21wb25lbnRUeXBlLCB2YWx1ZXNEYXRhLCBzcGFyc2UudmFsdWVzLmJ5dGVPZmZzZXQsIHNwYXJzZUxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IG5ldyBjb25zdHJ1Y3RvcihzcGFyc2VMZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhCdWZmZXIuRm9yRWFjaChzcGFyc2VEYXRhLCAwLCBieXRlU3RyaWRlLCBudW1Db21wb25lbnRzLCBhY2Nlc3Nvci5jb21wb25lbnRUeXBlLCB2YWx1ZXMubGVuZ3RoLCBhY2Nlc3Nvci5ub3JtYWxpemVkIHx8IGZhbHNlLCAodmFsdWUsIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbaW5kZXhdID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHZhbHVlc0luZGV4ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpbmRpY2VzSW5kZXggPSAwOyBpbmRpY2VzSW5kZXggPCBpbmRpY2VzLmxlbmd0aDsgaW5kaWNlc0luZGV4KyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGRhdGFJbmRleCA9IGluZGljZXNbaW5kaWNlc0luZGV4XSAqIG51bUNvbXBvbmVudHM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNvbXBvbmVudEluZGV4ID0gMDsgY29tcG9uZW50SW5kZXggPCBudW1Db21wb25lbnRzOyBjb21wb25lbnRJbmRleCsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlZEFycmF5W2RhdGFJbmRleCsrXSA9IHZhbHVlc1t2YWx1ZXNJbmRleCsrXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVkQXJyYXk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYWNjZXNzb3IuX2RhdGE7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9sb2FkRmxvYXRBY2Nlc3NvckFzeW5jKGNvbnRleHQ6IHN0cmluZywgYWNjZXNzb3I6IElBY2Nlc3Nvcik6IFByb21pc2U8RmxvYXQzMkFycmF5PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRBY2Nlc3NvckFzeW5jKGNvbnRleHQsIGFjY2Vzc29yLCBGbG9hdDMyQXJyYXkpIGFzIFByb21pc2U8RmxvYXQzMkFycmF5PjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvYWRJbmRpY2VzQWNjZXNzb3JBc3luYyhjb250ZXh0OiBzdHJpbmcsIGFjY2Vzc29yOiBJQWNjZXNzb3IpOiBQcm9taXNlPEluZGljZXNBcnJheT4ge1xyXG4gICAgICAgIGlmIChhY2Nlc3Nvci50eXBlICE9PSBBY2Nlc3NvclR5cGUuU0NBTEFSKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fS90eXBlOiBJbnZhbGlkIHZhbHVlICR7YWNjZXNzb3IudHlwZX1gKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChcclxuICAgICAgICAgICAgYWNjZXNzb3IuY29tcG9uZW50VHlwZSAhPT0gQWNjZXNzb3JDb21wb25lbnRUeXBlLlVOU0lHTkVEX0JZVEUgJiZcclxuICAgICAgICAgICAgYWNjZXNzb3IuY29tcG9uZW50VHlwZSAhPT0gQWNjZXNzb3JDb21wb25lbnRUeXBlLlVOU0lHTkVEX1NIT1JUICYmXHJcbiAgICAgICAgICAgIGFjY2Vzc29yLmNvbXBvbmVudFR5cGUgIT09IEFjY2Vzc29yQ29tcG9uZW50VHlwZS5VTlNJR05FRF9JTlRcclxuICAgICAgICApIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9L2NvbXBvbmVudFR5cGU6IEludmFsaWQgdmFsdWUgJHthY2Nlc3Nvci5jb21wb25lbnRUeXBlfWApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGFjY2Vzc29yLl9kYXRhKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBhY2Nlc3Nvci5fZGF0YSBhcyBQcm9taXNlPEluZGljZXNBcnJheT47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoYWNjZXNzb3Iuc3BhcnNlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnN0cnVjdG9yID0gR0xURkxvYWRlci5fR2V0VHlwZWRBcnJheUNvbnN0cnVjdG9yKGAke2NvbnRleHR9L2NvbXBvbmVudFR5cGVgLCBhY2Nlc3Nvci5jb21wb25lbnRUeXBlKTtcclxuICAgICAgICAgICAgYWNjZXNzb3IuX2RhdGEgPSB0aGlzLl9sb2FkQWNjZXNzb3JBc3luYyhjb250ZXh0LCBhY2Nlc3NvciwgY29uc3RydWN0b3IpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlclZpZXcgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L2J1ZmZlclZpZXdgLCB0aGlzLl9nbHRmLmJ1ZmZlclZpZXdzLCBhY2Nlc3Nvci5idWZmZXJWaWV3KTtcclxuICAgICAgICAgICAgYWNjZXNzb3IuX2RhdGEgPSB0aGlzLmxvYWRCdWZmZXJWaWV3QXN5bmMoYC9idWZmZXJWaWV3cy8ke2J1ZmZlclZpZXcuaW5kZXh9YCwgYnVmZmVyVmlldykudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuX0dldFR5cGVkQXJyYXkoY29udGV4dCwgYWNjZXNzb3IuY29tcG9uZW50VHlwZSwgZGF0YSwgYWNjZXNzb3IuYnl0ZU9mZnNldCwgYWNjZXNzb3IuY291bnQpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBhY2Nlc3Nvci5fZGF0YSBhcyBQcm9taXNlPEluZGljZXNBcnJheT47XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9sb2FkVmVydGV4QnVmZmVyVmlld0FzeW5jKGJ1ZmZlclZpZXc6IElCdWZmZXJWaWV3KTogUHJvbWlzZTxCdWZmZXI+IHtcclxuICAgICAgICBpZiAoYnVmZmVyVmlldy5fYmFieWxvbkJ1ZmZlcikge1xyXG4gICAgICAgICAgICByZXR1cm4gYnVmZmVyVmlldy5fYmFieWxvbkJ1ZmZlcjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGVuZ2luZSA9IHRoaXMuX2JhYnlsb25TY2VuZS5nZXRFbmdpbmUoKTtcclxuICAgICAgICBidWZmZXJWaWV3Ll9iYWJ5bG9uQnVmZmVyID0gdGhpcy5sb2FkQnVmZmVyVmlld0FzeW5jKGAvYnVmZmVyVmlld3MvJHtidWZmZXJWaWV3LmluZGV4fWAsIGJ1ZmZlclZpZXcpLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXIoZW5naW5lLCBkYXRhLCBmYWxzZSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBidWZmZXJWaWV3Ll9iYWJ5bG9uQnVmZmVyO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbG9hZFZlcnRleEFjY2Vzc29yQXN5bmMoY29udGV4dDogc3RyaW5nLCBhY2Nlc3NvcjogSUFjY2Vzc29yLCBraW5kOiBzdHJpbmcpOiBQcm9taXNlPFZlcnRleEJ1ZmZlcj4ge1xyXG4gICAgICAgIGlmIChhY2Nlc3Nvci5fYmFieWxvblZlcnRleEJ1ZmZlcj8uW2tpbmRdKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBhY2Nlc3Nvci5fYmFieWxvblZlcnRleEJ1ZmZlcltraW5kXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghYWNjZXNzb3IuX2JhYnlsb25WZXJ0ZXhCdWZmZXIpIHtcclxuICAgICAgICAgICAgYWNjZXNzb3IuX2JhYnlsb25WZXJ0ZXhCdWZmZXIgPSB7fTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGVuZ2luZSA9IHRoaXMuX2JhYnlsb25TY2VuZS5nZXRFbmdpbmUoKTtcclxuXHJcbiAgICAgICAgaWYgKGFjY2Vzc29yLnNwYXJzZSB8fCBhY2Nlc3Nvci5idWZmZXJWaWV3ID09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBhY2Nlc3Nvci5fYmFieWxvblZlcnRleEJ1ZmZlcltraW5kXSA9IHRoaXMuX2xvYWRGbG9hdEFjY2Vzc29yQXN5bmMoY29udGV4dCwgYWNjZXNzb3IpLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVmVydGV4QnVmZmVyKGVuZ2luZSwgZGF0YSwga2luZCwgZmFsc2UpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBidWZmZXJWaWV3ID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9idWZmZXJWaWV3YCwgdGhpcy5fZ2x0Zi5idWZmZXJWaWV3cywgYWNjZXNzb3IuYnVmZmVyVmlldyk7XHJcbiAgICAgICAgICAgIGFjY2Vzc29yLl9iYWJ5bG9uVmVydGV4QnVmZmVyW2tpbmRdID0gdGhpcy5fbG9hZFZlcnRleEJ1ZmZlclZpZXdBc3luYyhidWZmZXJWaWV3KS50aGVuKChiYWJ5bG9uQnVmZmVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBudW1Db21wb25lbnRzID0gR0xURkxvYWRlci5fR2V0TnVtQ29tcG9uZW50cyhjb250ZXh0LCBhY2Nlc3Nvci50eXBlKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVmVydGV4QnVmZmVyKFxyXG4gICAgICAgICAgICAgICAgICAgIGVuZ2luZSxcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uQnVmZmVyLFxyXG4gICAgICAgICAgICAgICAgICAgIGtpbmQsXHJcbiAgICAgICAgICAgICAgICAgICAgZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlclZpZXcuYnl0ZVN0cmlkZSxcclxuICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3IuYnl0ZU9mZnNldCxcclxuICAgICAgICAgICAgICAgICAgICBudW1Db21wb25lbnRzLFxyXG4gICAgICAgICAgICAgICAgICAgIGFjY2Vzc29yLmNvbXBvbmVudFR5cGUsXHJcbiAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3Iubm9ybWFsaXplZCxcclxuICAgICAgICAgICAgICAgICAgICB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgICAgICAgICB0cnVlXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBhY2Nlc3Nvci5fYmFieWxvblZlcnRleEJ1ZmZlcltraW5kXTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkTWF0ZXJpYWxNZXRhbGxpY1JvdWdobmVzc1Byb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIHByb3BlcnRpZXM6IElNYXRlcmlhbFBick1ldGFsbGljUm91Z2huZXNzLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogTWF0ZXJpYWwgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHVua25vd24+PigpO1xyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcykge1xyXG4gICAgICAgICAgICBpZiAocHJvcGVydGllcy5iYXNlQ29sb3JGYWN0b3IpIHtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbGJlZG9Db2xvciA9IENvbG9yMy5Gcm9tQXJyYXkocHJvcGVydGllcy5iYXNlQ29sb3JGYWN0b3IpO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmFscGhhID0gcHJvcGVydGllcy5iYXNlQ29sb3JGYWN0b3JbM107XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvQ29sb3IgPSBDb2xvcjMuV2hpdGUoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLm1ldGFsbGljID0gcHJvcGVydGllcy5tZXRhbGxpY0ZhY3RvciA9PSB1bmRlZmluZWQgPyAxIDogcHJvcGVydGllcy5tZXRhbGxpY0ZhY3RvcjtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnJvdWdobmVzcyA9IHByb3BlcnRpZXMucm91Z2huZXNzRmFjdG9yID09IHVuZGVmaW5lZCA/IDEgOiBwcm9wZXJ0aWVzLnJvdWdobmVzc0ZhY3RvcjtcclxuXHJcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLmJhc2VDb2xvclRleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkVGV4dHVyZUluZm9Bc3luYyhgJHtjb250ZXh0fS9iYXNlQ29sb3JUZXh0dXJlYCwgcHJvcGVydGllcy5iYXNlQ29sb3JUZXh0dXJlLCAodGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKEJhc2UgQ29sb3IpYDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmFsYmVkb1RleHR1cmUgPSB0ZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAocHJvcGVydGllcy5tZXRhbGxpY1JvdWdobmVzc1RleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgIHByb3BlcnRpZXMubWV0YWxsaWNSb3VnaG5lc3NUZXh0dXJlLm5vbkNvbG9yRGF0YSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vbWV0YWxsaWNSb3VnaG5lc3NUZXh0dXJlYCwgcHJvcGVydGllcy5tZXRhbGxpY1JvdWdobmVzc1RleHR1cmUsICh0ZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoTWV0YWxsaWMgUm91Z2huZXNzKWA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5tZXRhbGxpY1RleHR1cmUgPSB0ZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC51c2VNZXRhbGxuZXNzRnJvbU1ldGFsbGljVGV4dHVyZUJsdWUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnVzZVJvdWdobmVzc0Zyb21NZXRhbGxpY1RleHR1cmVHcmVlbiA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwudXNlUm91Z2huZXNzRnJvbU1ldGFsbGljVGV4dHVyZUFscGhhID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9sb2FkTWF0ZXJpYWxBc3luYyhcclxuICAgICAgICBjb250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgbWF0ZXJpYWw6IElNYXRlcmlhbCxcclxuICAgICAgICBiYWJ5bG9uTWVzaDogTnVsbGFibGU8TWVzaD4sXHJcbiAgICAgICAgYmFieWxvbkRyYXdNb2RlOiBudW1iZXIsXHJcbiAgICAgICAgYXNzaWduOiAoYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCkgPT4gdm9pZCA9ICgpID0+IHt9XHJcbiAgICApOiBQcm9taXNlPE1hdGVyaWFsPiB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uUHJvbWlzZSA9IHRoaXMuX2V4dGVuc2lvbnNMb2FkTWF0ZXJpYWxBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1lc2gsIGJhYnlsb25EcmF3TW9kZSwgYXNzaWduKTtcclxuICAgICAgICBpZiAoZXh0ZW5zaW9uUHJvbWlzZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZXh0ZW5zaW9uUHJvbWlzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG1hdGVyaWFsLl9kYXRhID0gbWF0ZXJpYWwuX2RhdGEgfHwge307XHJcbiAgICAgICAgbGV0IGJhYnlsb25EYXRhID0gbWF0ZXJpYWwuX2RhdGFbYmFieWxvbkRyYXdNb2RlXTtcclxuICAgICAgICBpZiAoIWJhYnlsb25EYXRhKSB7XHJcbiAgICAgICAgICAgIHRoaXMubG9nT3BlbihgJHtjb250ZXh0fSAke21hdGVyaWFsLm5hbWUgfHwgXCJcIn1gKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGJhYnlsb25NYXRlcmlhbCA9IHRoaXMuY3JlYXRlTWF0ZXJpYWwoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25EcmF3TW9kZSk7XHJcblxyXG4gICAgICAgICAgICBiYWJ5bG9uRGF0YSA9IHtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbDogYmFieWxvbk1hdGVyaWFsLFxyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1lc2hlczogW10sXHJcbiAgICAgICAgICAgICAgICBwcm9taXNlOiB0aGlzLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKSxcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIG1hdGVyaWFsLl9kYXRhW2JhYnlsb25EcmF3TW9kZV0gPSBiYWJ5bG9uRGF0YTtcclxuXHJcbiAgICAgICAgICAgIEdMVEZMb2FkZXIuQWRkUG9pbnRlck1ldGFkYXRhKGJhYnlsb25NYXRlcmlhbCwgY29udGV4dCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3BhcmVudC5vbk1hdGVyaWFsTG9hZGVkT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMoYmFieWxvbk1hdGVyaWFsKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMubG9nQ2xvc2UoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChiYWJ5bG9uTWVzaCkge1xyXG4gICAgICAgICAgICBiYWJ5bG9uRGF0YS5iYWJ5bG9uTWVzaGVzLnB1c2goYmFieWxvbk1lc2gpO1xyXG5cclxuICAgICAgICAgICAgYmFieWxvbk1lc2gub25EaXNwb3NlT2JzZXJ2YWJsZS5hZGRPbmNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gYmFieWxvbkRhdGEuYmFieWxvbk1lc2hlcy5pbmRleE9mKGJhYnlsb25NZXNoKTtcclxuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uRGF0YS5iYWJ5bG9uTWVzaGVzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYXNzaWduKGJhYnlsb25EYXRhLmJhYnlsb25NYXRlcmlhbCk7XHJcblxyXG4gICAgICAgIHJldHVybiBiYWJ5bG9uRGF0YS5wcm9taXNlLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gYmFieWxvbkRhdGEuYmFieWxvbk1hdGVyaWFsO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2NyZWF0ZURlZmF1bHRNYXRlcmlhbChuYW1lOiBzdHJpbmcsIGJhYnlsb25EcmF3TW9kZTogbnVtYmVyKTogTWF0ZXJpYWwge1xyXG4gICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gISF0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICBjb25zdCBiYWJ5bG9uTWF0ZXJpYWwgPSBuZXcgUEJSTWF0ZXJpYWwobmFtZSwgdGhpcy5fYmFieWxvblNjZW5lKTtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuX3BhcmVudENvbnRhaW5lciA9IHRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgLy8gTW92ZWQgdG8gbWVzaCBzbyB1c2VyIGNhbiBjaGFuZ2UgbWF0ZXJpYWxzIG9uIGdsdGYgbWVzaGVzOiBiYWJ5bG9uTWF0ZXJpYWwuc2lkZU9yaWVudGF0aW9uID0gdGhpcy5fYmFieWxvblNjZW5lLnVzZVJpZ2h0SGFuZGVkU3lzdGVtID8gTWF0ZXJpYWwuQ291bnRlckNsb2NrV2lzZVNpZGVPcmllbnRhdGlvbiA6IE1hdGVyaWFsLkNsb2NrV2lzZVNpZGVPcmllbnRhdGlvbjtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuZmlsbE1vZGUgPSBiYWJ5bG9uRHJhd01vZGU7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLmVuYWJsZVNwZWN1bGFyQW50aUFsaWFzaW5nID0gdHJ1ZTtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwudXNlUmFkaWFuY2VPdmVyQWxwaGEgPSAhdGhpcy5fcGFyZW50LnRyYW5zcGFyZW5jeUFzQ292ZXJhZ2U7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnVzZVNwZWN1bGFyT3ZlckFscGhhID0gIXRoaXMuX3BhcmVudC50cmFuc3BhcmVuY3lBc0NvdmVyYWdlO1xyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC50cmFuc3BhcmVuY3lNb2RlID0gUEJSTWF0ZXJpYWwuUEJSTUFURVJJQUxfT1BBUVVFO1xyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5tZXRhbGxpYyA9IDE7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnJvdWdobmVzcyA9IDE7XHJcbiAgICAgICAgcmV0dXJuIGJhYnlsb25NYXRlcmlhbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBCYWJ5bG9uIG1hdGVyaWFsIGZyb20gYSBnbFRGIG1hdGVyaWFsLlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIG1hdGVyaWFsIFRoZSBnbFRGIG1hdGVyaWFsIHByb3BlcnR5XHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbkRyYXdNb2RlIFRoZSBkcmF3IG1vZGUgZm9yIHRoZSBCYWJ5bG9uIG1hdGVyaWFsXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgQmFieWxvbiBtYXRlcmlhbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY3JlYXRlTWF0ZXJpYWwoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uRHJhd01vZGU6IG51bWJlcik6IE1hdGVyaWFsIHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25Qcm9taXNlID0gdGhpcy5fZXh0ZW5zaW9uc0NyZWF0ZU1hdGVyaWFsKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uRHJhd01vZGUpO1xyXG4gICAgICAgIGlmIChleHRlbnNpb25Qcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHRlbnNpb25Qcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgbmFtZSA9IG1hdGVyaWFsLm5hbWUgfHwgYG1hdGVyaWFsJHttYXRlcmlhbC5pbmRleH1gO1xyXG4gICAgICAgIGNvbnN0IGJhYnlsb25NYXRlcmlhbCA9IHRoaXMuX2NyZWF0ZURlZmF1bHRNYXRlcmlhbChuYW1lLCBiYWJ5bG9uRHJhd01vZGUpO1xyXG5cclxuICAgICAgICByZXR1cm4gYmFieWxvbk1hdGVyaWFsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9hZHMgcHJvcGVydGllcyBmcm9tIGEgZ2xURiBtYXRlcmlhbCBpbnRvIGEgQmFieWxvbiBtYXRlcmlhbC5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBtYXRlcmlhbCBUaGUgZ2xURiBtYXRlcmlhbCBwcm9wZXJ0eVxyXG4gICAgICogQHBhcmFtIGJhYnlsb25NYXRlcmlhbCBUaGUgQmFieWxvbiBtYXRlcmlhbFxyXG4gICAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgbG9hZCBpcyBjb21wbGV0ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvblByb21pc2UgPSB0aGlzLl9leHRlbnNpb25zTG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpO1xyXG4gICAgICAgIGlmIChleHRlbnNpb25Qcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHRlbnNpb25Qcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTx1bmtub3duPj4oKTtcclxuXHJcbiAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLmxvYWRNYXRlcmlhbEJhc2VQcm9wZXJ0aWVzQXN5bmMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCkpO1xyXG5cclxuICAgICAgICBpZiAobWF0ZXJpYWwucGJyTWV0YWxsaWNSb3VnaG5lc3MpIHtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkTWF0ZXJpYWxNZXRhbGxpY1JvdWdobmVzc1Byb3BlcnRpZXNBc3luYyhgJHtjb250ZXh0fS9wYnJNZXRhbGxpY1JvdWdobmVzc2AsIG1hdGVyaWFsLnBick1ldGFsbGljUm91Z2huZXNzLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMubG9hZE1hdGVyaWFsQWxwaGFQcm9wZXJ0aWVzKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpO1xyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9hZHMgdGhlIG5vcm1hbCwgb2NjbHVzaW9uLCBhbmQgZW1pc3NpdmUgcHJvcGVydGllcyBmcm9tIGEgZ2xURiBtYXRlcmlhbCBpbnRvIGEgQmFieWxvbiBtYXRlcmlhbC5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBtYXRlcmlhbCBUaGUgZ2xURiBtYXRlcmlhbCBwcm9wZXJ0eVxyXG4gICAgICogQHBhcmFtIGJhYnlsb25NYXRlcmlhbCBUaGUgQmFieWxvbiBtYXRlcmlhbFxyXG4gICAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgbG9hZCBpcyBjb21wbGV0ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsQmFzZVByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAoIShiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBNYXRlcmlhbCB0eXBlIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dW5rbm93bj4+KCk7XHJcblxyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5lbWlzc2l2ZUNvbG9yID0gbWF0ZXJpYWwuZW1pc3NpdmVGYWN0b3IgPyBDb2xvcjMuRnJvbUFycmF5KG1hdGVyaWFsLmVtaXNzaXZlRmFjdG9yKSA6IG5ldyBDb2xvcjMoMCwgMCwgMCk7XHJcbiAgICAgICAgaWYgKG1hdGVyaWFsLmRvdWJsZVNpZGVkKSB7XHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5iYWNrRmFjZUN1bGxpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnR3b1NpZGVkTGlnaHRpbmcgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKG1hdGVyaWFsLm5vcm1hbFRleHR1cmUpIHtcclxuICAgICAgICAgICAgbWF0ZXJpYWwubm9ybWFsVGV4dHVyZS5ub25Db2xvckRhdGEgPSB0cnVlO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkVGV4dHVyZUluZm9Bc3luYyhgJHtjb250ZXh0fS9ub3JtYWxUZXh0dXJlYCwgbWF0ZXJpYWwubm9ybWFsVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKE5vcm1hbClgO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5idW1wVGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmludmVydE5vcm1hbE1hcFggPSAhdGhpcy5fYmFieWxvblNjZW5lLnVzZVJpZ2h0SGFuZGVkU3lzdGVtO1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuaW52ZXJ0Tm9ybWFsTWFwWSA9IHRoaXMuX2JhYnlsb25TY2VuZS51c2VSaWdodEhhbmRlZFN5c3RlbTtcclxuICAgICAgICAgICAgaWYgKG1hdGVyaWFsLm5vcm1hbFRleHR1cmUuc2NhbGUgIT0gdW5kZWZpbmVkICYmIGJhYnlsb25NYXRlcmlhbC5idW1wVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmJ1bXBUZXh0dXJlLmxldmVsID0gbWF0ZXJpYWwubm9ybWFsVGV4dHVyZS5zY2FsZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmZvcmNlSXJyYWRpYW5jZUluRnJhZ21lbnQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKG1hdGVyaWFsLm9jY2x1c2lvblRleHR1cmUpIHtcclxuICAgICAgICAgICAgbWF0ZXJpYWwub2NjbHVzaW9uVGV4dHVyZS5ub25Db2xvckRhdGEgPSB0cnVlO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkVGV4dHVyZUluZm9Bc3luYyhgJHtjb250ZXh0fS9vY2NsdXNpb25UZXh0dXJlYCwgbWF0ZXJpYWwub2NjbHVzaW9uVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKE9jY2x1c2lvbilgO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbWJpZW50VGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnVzZUFtYmllbnRJbkdyYXlTY2FsZSA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmIChtYXRlcmlhbC5vY2NsdXNpb25UZXh0dXJlLnN0cmVuZ3RoICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmFtYmllbnRUZXh0dXJlU3RyZW5ndGggPSBtYXRlcmlhbC5vY2NsdXNpb25UZXh0dXJlLnN0cmVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAobWF0ZXJpYWwuZW1pc3NpdmVUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L2VtaXNzaXZlVGV4dHVyZWAsIG1hdGVyaWFsLmVtaXNzaXZlVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKEVtaXNzaXZlKWA7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmVtaXNzaXZlVGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIExvYWRzIHRoZSBhbHBoYSBwcm9wZXJ0aWVzIGZyb20gYSBnbFRGIG1hdGVyaWFsIGludG8gYSBCYWJ5bG9uIG1hdGVyaWFsLlxyXG4gICAgICogTXVzdCBiZSBjYWxsZWQgYWZ0ZXIgdGhlIHNldHRpbmcgdGhlIGFsYmVkbyB0ZXh0dXJlIG9mIHRoZSBCYWJ5bG9uIG1hdGVyaWFsIHdoZW4gdGhlIG1hdGVyaWFsIGhhcyBhbiBhbGJlZG8gdGV4dHVyZS5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBtYXRlcmlhbCBUaGUgZ2xURiBtYXRlcmlhbCBwcm9wZXJ0eVxyXG4gICAgICogQHBhcmFtIGJhYnlsb25NYXRlcmlhbCBUaGUgQmFieWxvbiBtYXRlcmlhbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsQWxwaGFQcm9wZXJ0aWVzKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IHZvaWQge1xyXG4gICAgICAgIGlmICghKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IE1hdGVyaWFsIHR5cGUgbm90IHN1cHBvcnRlZGApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgYWxwaGFNb2RlID0gbWF0ZXJpYWwuYWxwaGFNb2RlIHx8IE1hdGVyaWFsQWxwaGFNb2RlLk9QQVFVRTtcclxuICAgICAgICBzd2l0Y2ggKGFscGhhTW9kZSkge1xyXG4gICAgICAgICAgICBjYXNlIE1hdGVyaWFsQWxwaGFNb2RlLk9QQVFVRToge1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnRyYW5zcGFyZW5jeU1vZGUgPSBQQlJNYXRlcmlhbC5QQlJNQVRFUklBTF9PUEFRVUU7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxwaGEgPSAxLjA7IC8vIEZvcmNlIGFscGhhIHRvIDEuMCBmb3Igb3BhcXVlIG1vZGUuXHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIE1hdGVyaWFsQWxwaGFNb2RlLk1BU0s6IHtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC50cmFuc3BhcmVuY3lNb2RlID0gUEJSTWF0ZXJpYWwuUEJSTUFURVJJQUxfQUxQSEFURVNUO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmFscGhhQ3V0T2ZmID0gbWF0ZXJpYWwuYWxwaGFDdXRvZmYgPT0gdW5kZWZpbmVkID8gMC41IDogbWF0ZXJpYWwuYWxwaGFDdXRvZmY7XHJcbiAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsLmFsYmVkb1RleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvVGV4dHVyZS5oYXNBbHBoYSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIE1hdGVyaWFsQWxwaGFNb2RlLkJMRU5EOiB7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwudHJhbnNwYXJlbmN5TW9kZSA9IFBCUk1hdGVyaWFsLlBCUk1BVEVSSUFMX0FMUEhBQkxFTkQ7XHJcbiAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsLmFsYmVkb1RleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvVGV4dHVyZS5oYXNBbHBoYSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnVzZUFscGhhRnJvbUFsYmVkb1RleHR1cmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZGVmYXVsdDoge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9L2FscGhhTW9kZTogSW52YWxpZCB2YWx1ZSAoJHttYXRlcmlhbC5hbHBoYU1vZGV9KWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9hZHMgYSBnbFRGIHRleHR1cmUgaW5mby5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSB0ZXh0dXJlSW5mbyBUaGUgZ2xURiB0ZXh0dXJlIGluZm8gcHJvcGVydHlcclxuICAgICAqIEBwYXJhbSBhc3NpZ24gQSBmdW5jdGlvbiBjYWxsZWQgc3luY2hyb25vdXNseSBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXNcclxuICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGxvYWRlZCBCYWJ5bG9uIHRleHR1cmUgd2hlbiB0aGUgbG9hZCBpcyBjb21wbGV0ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZFRleHR1cmVJbmZvQXN5bmMoY29udGV4dDogc3RyaW5nLCB0ZXh0dXJlSW5mbzogSVRleHR1cmVJbmZvLCBhc3NpZ246IChiYWJ5bG9uVGV4dHVyZTogQmFzZVRleHR1cmUpID0+IHZvaWQgPSAoKSA9PiB7fSk6IFByb21pc2U8QmFzZVRleHR1cmU+IHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25Qcm9taXNlID0gdGhpcy5fZXh0ZW5zaW9uc0xvYWRUZXh0dXJlSW5mb0FzeW5jKGNvbnRleHQsIHRleHR1cmVJbmZvLCBhc3NpZ24pO1xyXG4gICAgICAgIGlmIChleHRlbnNpb25Qcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHRlbnNpb25Qcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5sb2dPcGVuKGAke2NvbnRleHR9YCk7XHJcblxyXG4gICAgICAgIGlmICh0ZXh0dXJlSW5mby50ZXhDb29yZCEgPj0gNikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH0vdGV4Q29vcmQ6IEludmFsaWQgdmFsdWUgKCR7dGV4dHVyZUluZm8udGV4Q29vcmR9KWApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgdGV4dHVyZSA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vaW5kZXhgLCB0aGlzLl9nbHRmLnRleHR1cmVzLCB0ZXh0dXJlSW5mby5pbmRleCk7XHJcbiAgICAgICAgdGV4dHVyZS5fdGV4dHVyZUluZm8gPSB0ZXh0dXJlSW5mbztcclxuXHJcbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRoaXMuX2xvYWRUZXh0dXJlQXN5bmMoYC90ZXh0dXJlcy8ke3RleHR1cmVJbmZvLmluZGV4fWAsIHRleHR1cmUsIChiYWJ5bG9uVGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICBiYWJ5bG9uVGV4dHVyZS5jb29yZGluYXRlc0luZGV4ID0gdGV4dHVyZUluZm8udGV4Q29vcmQgfHwgMDtcclxuICAgICAgICAgICAgR0xURkxvYWRlci5BZGRQb2ludGVyTWV0YWRhdGEoYmFieWxvblRleHR1cmUsIGNvbnRleHQpO1xyXG4gICAgICAgICAgICB0aGlzLl9wYXJlbnQub25UZXh0dXJlTG9hZGVkT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMoYmFieWxvblRleHR1cmUpO1xyXG4gICAgICAgICAgICBhc3NpZ24oYmFieWxvblRleHR1cmUpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLmxvZ0Nsb3NlKCk7XHJcblxyXG4gICAgICAgIHJldHVybiBwcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbG9hZFRleHR1cmVBc3luYyhjb250ZXh0OiBzdHJpbmcsIHRleHR1cmU6IElUZXh0dXJlLCBhc3NpZ246IChiYWJ5bG9uVGV4dHVyZTogQmFzZVRleHR1cmUpID0+IHZvaWQgPSAoKSA9PiB7fSk6IFByb21pc2U8QmFzZVRleHR1cmU+IHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25Qcm9taXNlID0gdGhpcy5fZXh0ZW5zaW9uc0xvYWRUZXh0dXJlQXN5bmMoY29udGV4dCwgdGV4dHVyZSwgYXNzaWduKTtcclxuICAgICAgICBpZiAoZXh0ZW5zaW9uUHJvbWlzZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZXh0ZW5zaW9uUHJvbWlzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMubG9nT3BlbihgJHtjb250ZXh0fSAke3RleHR1cmUubmFtZSB8fCBcIlwifWApO1xyXG5cclxuICAgICAgICBjb25zdCBzYW1wbGVyID0gdGV4dHVyZS5zYW1wbGVyID09IHVuZGVmaW5lZCA/IEdMVEZMb2FkZXIuRGVmYXVsdFNhbXBsZXIgOiBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L3NhbXBsZXJgLCB0aGlzLl9nbHRmLnNhbXBsZXJzLCB0ZXh0dXJlLnNhbXBsZXIpO1xyXG4gICAgICAgIGNvbnN0IGltYWdlID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9zb3VyY2VgLCB0aGlzLl9nbHRmLmltYWdlcywgdGV4dHVyZS5zb3VyY2UpO1xyXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLl9jcmVhdGVUZXh0dXJlQXN5bmMoY29udGV4dCwgc2FtcGxlciwgaW1hZ2UsIGFzc2lnbiwgdW5kZWZpbmVkLCAhdGV4dHVyZS5fdGV4dHVyZUluZm8ubm9uQ29sb3JEYXRhKTtcclxuXHJcbiAgICAgICAgdGhpcy5sb2dDbG9zZSgpO1xyXG5cclxuICAgICAgICByZXR1cm4gcHJvbWlzZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2NyZWF0ZVRleHR1cmVBc3luYyhcclxuICAgICAgICBjb250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgc2FtcGxlcjogSVNhbXBsZXIsXHJcbiAgICAgICAgaW1hZ2U6IElJbWFnZSxcclxuICAgICAgICBhc3NpZ246IChiYWJ5bG9uVGV4dHVyZTogQmFzZVRleHR1cmUpID0+IHZvaWQgPSAoKSA9PiB7fSxcclxuICAgICAgICB0ZXh0dXJlTG9hZGVyT3B0aW9ucz86IHVua25vd24sXHJcbiAgICAgICAgdXNlU1JHQkJ1ZmZlcj86IGJvb2xlYW5cclxuICAgICk6IFByb21pc2U8QmFzZVRleHR1cmU+IHtcclxuICAgICAgICBjb25zdCBzYW1wbGVyRGF0YSA9IHRoaXMuX2xvYWRTYW1wbGVyKGAvc2FtcGxlcnMvJHtzYW1wbGVyLmluZGV4fWAsIHNhbXBsZXIpO1xyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHVua25vd24+PigpO1xyXG5cclxuICAgICAgICBjb25zdCBkZWZlcnJlZCA9IG5ldyBEZWZlcnJlZDx2b2lkPigpO1xyXG4gICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gISF0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICBjb25zdCB0ZXh0dXJlQ3JlYXRpb25PcHRpb25zOiBJVGV4dHVyZUNyZWF0aW9uT3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgbm9NaXBtYXA6IHNhbXBsZXJEYXRhLm5vTWlwTWFwcyxcclxuICAgICAgICAgICAgaW52ZXJ0WTogZmFsc2UsXHJcbiAgICAgICAgICAgIHNhbXBsaW5nTW9kZTogc2FtcGxlckRhdGEuc2FtcGxpbmdNb2RlLFxyXG4gICAgICAgICAgICBvbkxvYWQ6ICgpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5fZGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIG9uRXJyb3I6IChtZXNzYWdlPzogc3RyaW5nLCBleGNlcHRpb24/OiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5fZGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QobmV3IEVycm9yKGAke2NvbnRleHR9OiAke2V4Y2VwdGlvbiAmJiBleGNlcHRpb24ubWVzc2FnZSA/IGV4Y2VwdGlvbi5tZXNzYWdlIDogbWVzc2FnZSB8fCBcIkZhaWxlZCB0byBsb2FkIHRleHR1cmVcIn1gKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIG1pbWVUeXBlOiBpbWFnZS5taW1lVHlwZSxcclxuICAgICAgICAgICAgbG9hZGVyT3B0aW9uczogdGV4dHVyZUxvYWRlck9wdGlvbnMsXHJcbiAgICAgICAgICAgIHVzZVNSR0JCdWZmZXI6ICEhdXNlU1JHQkJ1ZmZlciAmJiB0aGlzLl9wYXJlbnQudXNlU1JHQkJ1ZmZlcnMsXHJcbiAgICAgICAgfTtcclxuICAgICAgICBjb25zdCBiYWJ5bG9uVGV4dHVyZSA9IG5ldyBUZXh0dXJlKG51bGwsIHRoaXMuX2JhYnlsb25TY2VuZSwgdGV4dHVyZUNyZWF0aW9uT3B0aW9ucyk7XHJcbiAgICAgICAgYmFieWxvblRleHR1cmUuX3BhcmVudENvbnRhaW5lciA9IHRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgcHJvbWlzZXMucHVzaChkZWZlcnJlZC5wcm9taXNlKTtcclxuXHJcbiAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgdGhpcy5sb2FkSW1hZ2VBc3luYyhgL2ltYWdlcy8ke2ltYWdlLmluZGV4fWAsIGltYWdlKS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBuYW1lID0gaW1hZ2UudXJpIHx8IGAke3RoaXMuX2ZpbGVOYW1lfSNpbWFnZSR7aW1hZ2UuaW5kZXh9YDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGFVcmwgPSBgZGF0YToke3RoaXMuX3VuaXF1ZVJvb3RVcmx9JHtuYW1lfWA7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uVGV4dHVyZS51cGRhdGVVUkwoZGF0YVVybCwgZGF0YSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gU2V0IHRoZSBpbnRlcm5hbCB0ZXh0dXJlIGxhYmVsLlxyXG4gICAgICAgICAgICAgICAgY29uc3QgaW50ZXJuYWxUZXh0dXJlID0gYmFieWxvblRleHR1cmUuZ2V0SW50ZXJuYWxUZXh0dXJlKCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoaW50ZXJuYWxUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJuYWxUZXh0dXJlLmxhYmVsID0gaW1hZ2UubmFtZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICBiYWJ5bG9uVGV4dHVyZS53cmFwVSA9IHNhbXBsZXJEYXRhLndyYXBVO1xyXG4gICAgICAgIGJhYnlsb25UZXh0dXJlLndyYXBWID0gc2FtcGxlckRhdGEud3JhcFY7XHJcbiAgICAgICAgYXNzaWduKGJhYnlsb25UZXh0dXJlKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX3BhcmVudC51c2VHbHRmVGV4dHVyZU5hbWVzKSB7XHJcbiAgICAgICAgICAgIGJhYnlsb25UZXh0dXJlLm5hbWUgPSBpbWFnZS5uYW1lIHx8IGltYWdlLnVyaSB8fCBgaW1hZ2Uke2ltYWdlLmluZGV4fWA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gYmFieWxvblRleHR1cmU7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZFNhbXBsZXIoY29udGV4dDogc3RyaW5nLCBzYW1wbGVyOiBJU2FtcGxlcik6IF9JU2FtcGxlckRhdGEge1xyXG4gICAgICAgIGlmICghc2FtcGxlci5fZGF0YSkge1xyXG4gICAgICAgICAgICBzYW1wbGVyLl9kYXRhID0ge1xyXG4gICAgICAgICAgICAgICAgbm9NaXBNYXBzOiBzYW1wbGVyLm1pbkZpbHRlciA9PT0gVGV4dHVyZU1pbkZpbHRlci5ORUFSRVNUIHx8IHNhbXBsZXIubWluRmlsdGVyID09PSBUZXh0dXJlTWluRmlsdGVyLkxJTkVBUixcclxuICAgICAgICAgICAgICAgIHNhbXBsaW5nTW9kZTogR0xURkxvYWRlci5fR2V0VGV4dHVyZVNhbXBsaW5nTW9kZShjb250ZXh0LCBzYW1wbGVyKSxcclxuICAgICAgICAgICAgICAgIHdyYXBVOiBHTFRGTG9hZGVyLl9HZXRUZXh0dXJlV3JhcE1vZGUoYCR7Y29udGV4dH0vd3JhcFNgLCBzYW1wbGVyLndyYXBTKSxcclxuICAgICAgICAgICAgICAgIHdyYXBWOiBHTFRGTG9hZGVyLl9HZXRUZXh0dXJlV3JhcE1vZGUoYCR7Y29udGV4dH0vd3JhcFRgLCBzYW1wbGVyLndyYXBUKSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBzYW1wbGVyLl9kYXRhO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9hZHMgYSBnbFRGIGltYWdlLlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIGltYWdlIFRoZSBnbFRGIGltYWdlIHByb3BlcnR5XHJcbiAgICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBsb2FkZWQgZGF0YSB3aGVuIHRoZSBsb2FkIGlzIGNvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkSW1hZ2VBc3luYyhjb250ZXh0OiBzdHJpbmcsIGltYWdlOiBJSW1hZ2UpOiBQcm9taXNlPEFycmF5QnVmZmVyVmlldz4ge1xyXG4gICAgICAgIGlmICghaW1hZ2UuX2RhdGEpIHtcclxuICAgICAgICAgICAgdGhpcy5sb2dPcGVuKGAke2NvbnRleHR9ICR7aW1hZ2UubmFtZSB8fCBcIlwifWApO1xyXG5cclxuICAgICAgICAgICAgaWYgKGltYWdlLnVyaSkge1xyXG4gICAgICAgICAgICAgICAgaW1hZ2UuX2RhdGEgPSB0aGlzLmxvYWRVcmlBc3luYyhgJHtjb250ZXh0fS91cmlgLCBpbWFnZSwgaW1hZ2UudXJpKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlclZpZXcgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L2J1ZmZlclZpZXdgLCB0aGlzLl9nbHRmLmJ1ZmZlclZpZXdzLCBpbWFnZS5idWZmZXJWaWV3KTtcclxuICAgICAgICAgICAgICAgIGltYWdlLl9kYXRhID0gdGhpcy5sb2FkQnVmZmVyVmlld0FzeW5jKGAvYnVmZmVyVmlld3MvJHtidWZmZXJWaWV3LmluZGV4fWAsIGJ1ZmZlclZpZXcpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmxvZ0Nsb3NlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gaW1hZ2UuX2RhdGE7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMb2FkcyBhIGdsVEYgdXJpLlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIHByb3BlcnR5IFRoZSBnbFRGIHByb3BlcnR5IGFzc29jaWF0ZWQgd2l0aCB0aGUgdXJpXHJcbiAgICAgKiBAcGFyYW0gdXJpIFRoZSBiYXNlNjQgb3IgcmVsYXRpdmUgdXJpXHJcbiAgICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBsb2FkZWQgZGF0YSB3aGVuIHRoZSBsb2FkIGlzIGNvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkVXJpQXN5bmMoY29udGV4dDogc3RyaW5nLCBwcm9wZXJ0eTogSVByb3BlcnR5LCB1cmk6IHN0cmluZyk6IFByb21pc2U8QXJyYXlCdWZmZXJWaWV3PiB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uUHJvbWlzZSA9IHRoaXMuX2V4dGVuc2lvbnNMb2FkVXJpQXN5bmMoY29udGV4dCwgcHJvcGVydHksIHVyaSk7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvblByb21pc2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvblByb21pc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIUdMVEZMb2FkZXIuX1ZhbGlkYXRlVXJpKHVyaSkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiAnJHt1cml9JyBpcyBpbnZhbGlkYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoSXNCYXNlNjREYXRhVXJsKHVyaSkpIHtcclxuICAgICAgICAgICAgY29uc3QgZGF0YSA9IG5ldyBVaW50OEFycmF5KERlY29kZUJhc2U2NFVybFRvQmluYXJ5KHVyaSkpO1xyXG4gICAgICAgICAgICB0aGlzLmxvZyhgJHtjb250ZXh0fTogRGVjb2RlZCAke3VyaS5zdWJzdHJpbmcoMCwgNjQpfS4uLiAoJHtkYXRhLmxlbmd0aH0gYnl0ZXMpYCk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZGF0YSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmxvZyhgJHtjb250ZXh0fTogTG9hZGluZyAke3VyaX1gKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmVudC5wcmVwcm9jZXNzVXJsQXN5bmModGhpcy5fcm9vdFVybCArIHVyaSkudGhlbigodXJsKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJlbnQuX2xvYWRGaWxlKFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZSxcclxuICAgICAgICAgICAgICAgICAgICB1cmwsXHJcbiAgICAgICAgICAgICAgICAgICAgKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9kaXNwb3NlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2coYCR7Y29udGV4dH06IExvYWRlZCAke3VyaX0gKCR7KGRhdGEgYXMgQXJyYXlCdWZmZXIpLmJ5dGVMZW5ndGh9IGJ5dGVzKWApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgVWludDhBcnJheShkYXRhIGFzIEFycmF5QnVmZmVyKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgKHJlcXVlc3QpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBMb2FkRmlsZUVycm9yKGAke2NvbnRleHR9OiBGYWlsZWQgdG8gbG9hZCAnJHt1cml9JyR7cmVxdWVzdCA/IFwiOiBcIiArIHJlcXVlc3Quc3RhdHVzICsgXCIgXCIgKyByZXF1ZXN0LnN0YXR1c1RleHQgOiBcIlwifWAsIHJlcXVlc3QpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgYSBKU09OIHBvaW50ZXIgdG8gdGhlIF9pbnRlcm5hbE1ldGFkYXRhIG9mIHRoZSBCYWJ5bG9uIG9iamVjdCBhdCBgPG9iamVjdD4uX2ludGVybmFsTWV0YWRhdGEuZ2x0Zi5wb2ludGVyc2AuXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk9iamVjdCB0aGUgQmFieWxvbiBvYmplY3Qgd2l0aCBfaW50ZXJuYWxNZXRhZGF0YVxyXG4gICAgICogQHBhcmFtIHBvaW50ZXIgdGhlIEpTT04gcG9pbnRlclxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIEFkZFBvaW50ZXJNZXRhZGF0YShiYWJ5bG9uT2JqZWN0OiBJV2l0aE1ldGFkYXRhLCBwb2ludGVyOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICBiYWJ5bG9uT2JqZWN0Lm1ldGFkYXRhID0gYmFieWxvbk9iamVjdC5tZXRhZGF0YSB8fCB7fTtcclxuICAgICAgICBjb25zdCBtZXRhZGF0YSA9IChiYWJ5bG9uT2JqZWN0Ll9pbnRlcm5hbE1ldGFkYXRhID0gYmFieWxvbk9iamVjdC5faW50ZXJuYWxNZXRhZGF0YSB8fCB7fSk7XHJcbiAgICAgICAgY29uc3QgZ2x0ZiA9IChtZXRhZGF0YS5nbHRmID0gbWV0YWRhdGEuZ2x0ZiB8fCB7fSk7XHJcbiAgICAgICAgY29uc3QgcG9pbnRlcnMgPSAoZ2x0Zi5wb2ludGVycyA9IGdsdGYucG9pbnRlcnMgfHwgW10pO1xyXG4gICAgICAgIHBvaW50ZXJzLnB1c2gocG9pbnRlcik7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX0dldFRleHR1cmVXcmFwTW9kZShjb250ZXh0OiBzdHJpbmcsIG1vZGU6IFRleHR1cmVXcmFwTW9kZSB8IHVuZGVmaW5lZCk6IG51bWJlciB7XHJcbiAgICAgICAgLy8gU2V0IGRlZmF1bHRzIGlmIHVuZGVmaW5lZFxyXG4gICAgICAgIG1vZGUgPSBtb2RlID09IHVuZGVmaW5lZCA/IFRleHR1cmVXcmFwTW9kZS5SRVBFQVQgOiBtb2RlO1xyXG5cclxuICAgICAgICBzd2l0Y2ggKG1vZGUpIHtcclxuICAgICAgICAgICAgY2FzZSBUZXh0dXJlV3JhcE1vZGUuQ0xBTVBfVE9fRURHRTpcclxuICAgICAgICAgICAgICAgIHJldHVybiBUZXh0dXJlLkNMQU1QX0FERFJFU1NNT0RFO1xyXG4gICAgICAgICAgICBjYXNlIFRleHR1cmVXcmFwTW9kZS5NSVJST1JFRF9SRVBFQVQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5NSVJST1JfQUREUkVTU01PREU7XHJcbiAgICAgICAgICAgIGNhc2UgVGV4dHVyZVdyYXBNb2RlLlJFUEVBVDpcclxuICAgICAgICAgICAgICAgIHJldHVybiBUZXh0dXJlLldSQVBfQUREUkVTU01PREU7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICBMb2dnZXIuV2FybihgJHtjb250ZXh0fTogSW52YWxpZCB2YWx1ZSAoJHttb2RlfSlgKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBUZXh0dXJlLldSQVBfQUREUkVTU01PREU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIF9HZXRUZXh0dXJlU2FtcGxpbmdNb2RlKGNvbnRleHQ6IHN0cmluZywgc2FtcGxlcjogSVNhbXBsZXIpOiBudW1iZXIge1xyXG4gICAgICAgIC8vIFNldCBkZWZhdWx0cyBpZiB1bmRlZmluZWRcclxuICAgICAgICBjb25zdCBtYWdGaWx0ZXIgPSBzYW1wbGVyLm1hZ0ZpbHRlciA9PSB1bmRlZmluZWQgPyBUZXh0dXJlTWFnRmlsdGVyLkxJTkVBUiA6IHNhbXBsZXIubWFnRmlsdGVyO1xyXG4gICAgICAgIGNvbnN0IG1pbkZpbHRlciA9IHNhbXBsZXIubWluRmlsdGVyID09IHVuZGVmaW5lZCA/IFRleHR1cmVNaW5GaWx0ZXIuTElORUFSX01JUE1BUF9MSU5FQVIgOiBzYW1wbGVyLm1pbkZpbHRlcjtcclxuXHJcbiAgICAgICAgaWYgKG1hZ0ZpbHRlciA9PT0gVGV4dHVyZU1hZ0ZpbHRlci5MSU5FQVIpIHtcclxuICAgICAgICAgICAgc3dpdGNoIChtaW5GaWx0ZXIpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgVGV4dHVyZU1pbkZpbHRlci5ORUFSRVNUOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBUZXh0dXJlLkxJTkVBUl9ORUFSRVNUO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBUZXh0dXJlTWluRmlsdGVyLkxJTkVBUjpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5MSU5FQVJfTElORUFSO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBUZXh0dXJlTWluRmlsdGVyLk5FQVJFU1RfTUlQTUFQX05FQVJFU1Q6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuTElORUFSX05FQVJFU1RfTUlQTkVBUkVTVDtcclxuICAgICAgICAgICAgICAgIGNhc2UgVGV4dHVyZU1pbkZpbHRlci5MSU5FQVJfTUlQTUFQX05FQVJFU1Q6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuTElORUFSX0xJTkVBUl9NSVBORUFSRVNUO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBUZXh0dXJlTWluRmlsdGVyLk5FQVJFU1RfTUlQTUFQX0xJTkVBUjpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5MSU5FQVJfTkVBUkVTVF9NSVBMSU5FQVI7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFRleHR1cmVNaW5GaWx0ZXIuTElORUFSX01JUE1BUF9MSU5FQVI6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuTElORUFSX0xJTkVBUl9NSVBMSU5FQVI7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5XYXJuKGAke2NvbnRleHR9L21pbkZpbHRlcjogSW52YWxpZCB2YWx1ZSAoJHttaW5GaWx0ZXJ9KWApO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBUZXh0dXJlLkxJTkVBUl9MSU5FQVJfTUlQTElORUFSO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKG1hZ0ZpbHRlciAhPT0gVGV4dHVyZU1hZ0ZpbHRlci5ORUFSRVNUKSB7XHJcbiAgICAgICAgICAgICAgICBMb2dnZXIuV2FybihgJHtjb250ZXh0fS9tYWdGaWx0ZXI6IEludmFsaWQgdmFsdWUgKCR7bWFnRmlsdGVyfSlgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgc3dpdGNoIChtaW5GaWx0ZXIpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgVGV4dHVyZU1pbkZpbHRlci5ORUFSRVNUOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBUZXh0dXJlLk5FQVJFU1RfTkVBUkVTVDtcclxuICAgICAgICAgICAgICAgIGNhc2UgVGV4dHVyZU1pbkZpbHRlci5MSU5FQVI6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuTkVBUkVTVF9MSU5FQVI7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFRleHR1cmVNaW5GaWx0ZXIuTkVBUkVTVF9NSVBNQVBfTkVBUkVTVDpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5ORUFSRVNUX05FQVJFU1RfTUlQTkVBUkVTVDtcclxuICAgICAgICAgICAgICAgIGNhc2UgVGV4dHVyZU1pbkZpbHRlci5MSU5FQVJfTUlQTUFQX05FQVJFU1Q6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuTkVBUkVTVF9MSU5FQVJfTUlQTkVBUkVTVDtcclxuICAgICAgICAgICAgICAgIGNhc2UgVGV4dHVyZU1pbkZpbHRlci5ORUFSRVNUX01JUE1BUF9MSU5FQVI6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuTkVBUkVTVF9ORUFSRVNUX01JUExJTkVBUjtcclxuICAgICAgICAgICAgICAgIGNhc2UgVGV4dHVyZU1pbkZpbHRlci5MSU5FQVJfTUlQTUFQX0xJTkVBUjpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5ORUFSRVNUX0xJTkVBUl9NSVBMSU5FQVI7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5XYXJuKGAke2NvbnRleHR9L21pbkZpbHRlcjogSW52YWxpZCB2YWx1ZSAoJHttaW5GaWx0ZXJ9KWApO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBUZXh0dXJlLk5FQVJFU1RfTkVBUkVTVF9NSVBORUFSRVNUO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIF9HZXRUeXBlZEFycmF5Q29uc3RydWN0b3IoY29udGV4dDogc3RyaW5nLCBjb21wb25lbnRUeXBlOiBBY2Nlc3NvckNvbXBvbmVudFR5cGUpOiBUeXBlZEFycmF5Q29uc3RydWN0b3Ige1xyXG4gICAgICAgIHN3aXRjaCAoY29tcG9uZW50VHlwZSkge1xyXG4gICAgICAgICAgICBjYXNlIEFjY2Vzc29yQ29tcG9uZW50VHlwZS5CWVRFOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIEludDhBcnJheTtcclxuICAgICAgICAgICAgY2FzZSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuVU5TSUdORURfQllURTpcclxuICAgICAgICAgICAgICAgIHJldHVybiBVaW50OEFycmF5O1xyXG4gICAgICAgICAgICBjYXNlIEFjY2Vzc29yQ29tcG9uZW50VHlwZS5TSE9SVDpcclxuICAgICAgICAgICAgICAgIHJldHVybiBJbnQxNkFycmF5O1xyXG4gICAgICAgICAgICBjYXNlIEFjY2Vzc29yQ29tcG9uZW50VHlwZS5VTlNJR05FRF9TSE9SVDpcclxuICAgICAgICAgICAgICAgIHJldHVybiBVaW50MTZBcnJheTtcclxuICAgICAgICAgICAgY2FzZSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuVU5TSUdORURfSU5UOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFVpbnQzMkFycmF5O1xyXG4gICAgICAgICAgICBjYXNlIEFjY2Vzc29yQ29tcG9uZW50VHlwZS5GTE9BVDpcclxuICAgICAgICAgICAgICAgIHJldHVybiBGbG9hdDMyQXJyYXk7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IEludmFsaWQgY29tcG9uZW50IHR5cGUgJHtjb21wb25lbnRUeXBlfWApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfR2V0VHlwZWRBcnJheShcclxuICAgICAgICBjb250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgY29tcG9uZW50VHlwZTogQWNjZXNzb3JDb21wb25lbnRUeXBlLFxyXG4gICAgICAgIGJ1ZmZlclZpZXc6IEFycmF5QnVmZmVyVmlldyxcclxuICAgICAgICBieXRlT2Zmc2V0OiBudW1iZXIgfCB1bmRlZmluZWQsXHJcbiAgICAgICAgbGVuZ3RoOiBudW1iZXJcclxuICAgICk6IFR5cGVkQXJyYXlMaWtlIHtcclxuICAgICAgICBjb25zdCBidWZmZXIgPSBidWZmZXJWaWV3LmJ1ZmZlcjtcclxuICAgICAgICBieXRlT2Zmc2V0ID0gYnVmZmVyVmlldy5ieXRlT2Zmc2V0ICsgKGJ5dGVPZmZzZXQgfHwgMCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGNvbnN0cnVjdG9yID0gR0xURkxvYWRlci5fR2V0VHlwZWRBcnJheUNvbnN0cnVjdG9yKGAke2NvbnRleHR9L2NvbXBvbmVudFR5cGVgLCBjb21wb25lbnRUeXBlKTtcclxuXHJcbiAgICAgICAgY29uc3QgY29tcG9uZW50VHlwZUxlbmd0aCA9IFZlcnRleEJ1ZmZlci5HZXRUeXBlQnl0ZUxlbmd0aChjb21wb25lbnRUeXBlKTtcclxuICAgICAgICBpZiAoYnl0ZU9mZnNldCAlIGNvbXBvbmVudFR5cGVMZW5ndGggIT09IDApIHtcclxuICAgICAgICAgICAgLy8gSEFDSzogQ29weSB0aGUgYnVmZmVyIGlmIGJ5dGUgb2Zmc2V0IGlzIG5vdCBhIG11bHRpcGxlIG9mIGNvbXBvbmVudCB0eXBlIGJ5dGUgbGVuZ3RoLlxyXG4gICAgICAgICAgICBMb2dnZXIuV2FybihgJHtjb250ZXh0fTogQ29weWluZyBidWZmZXIgYXMgYnl0ZSBvZmZzZXQgKCR7Ynl0ZU9mZnNldH0pIGlzIG5vdCBhIG11bHRpcGxlIG9mIGNvbXBvbmVudCB0eXBlIGJ5dGUgbGVuZ3RoICgke2NvbXBvbmVudFR5cGVMZW5ndGh9KWApO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IGNvbnN0cnVjdG9yKGJ1ZmZlci5zbGljZShieXRlT2Zmc2V0LCBieXRlT2Zmc2V0ICsgbGVuZ3RoICogY29tcG9uZW50VHlwZUxlbmd0aCksIDApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBjb25zdHJ1Y3RvcihidWZmZXIsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX0dldE51bUNvbXBvbmVudHMoY29udGV4dDogc3RyaW5nLCB0eXBlOiBzdHJpbmcpOiBudW1iZXIge1xyXG4gICAgICAgIHN3aXRjaCAodHlwZSkge1xyXG4gICAgICAgICAgICBjYXNlIFwiU0NBTEFSXCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gMTtcclxuICAgICAgICAgICAgY2FzZSBcIlZFQzJcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiAyO1xyXG4gICAgICAgICAgICBjYXNlIFwiVkVDM1wiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIDM7XHJcbiAgICAgICAgICAgIGNhc2UgXCJWRUM0XCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gNDtcclxuICAgICAgICAgICAgY2FzZSBcIk1BVDJcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiA0O1xyXG4gICAgICAgICAgICBjYXNlIFwiTUFUM1wiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIDk7XHJcbiAgICAgICAgICAgIGNhc2UgXCJNQVQ0XCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gMTY7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IEludmFsaWQgdHlwZSAoJHt0eXBlfSlgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfVmFsaWRhdGVVcmkodXJpOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gVG9vbHMuSXNCYXNlNjQodXJpKSB8fCB1cmkuaW5kZXhPZihcIi4uXCIpID09PSAtMTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIF9HZXREcmF3TW9kZShjb250ZXh0OiBzdHJpbmcsIG1vZGU6IG51bWJlciB8IHVuZGVmaW5lZCk6IG51bWJlciB7XHJcbiAgICAgICAgaWYgKG1vZGUgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIG1vZGUgPSBNZXNoUHJpbWl0aXZlTW9kZS5UUklBTkdMRVM7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzd2l0Y2ggKG1vZGUpIHtcclxuICAgICAgICAgICAgY2FzZSBNZXNoUHJpbWl0aXZlTW9kZS5QT0lOVFM6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gTWF0ZXJpYWwuUG9pbnRMaXN0RHJhd01vZGU7XHJcbiAgICAgICAgICAgIGNhc2UgTWVzaFByaW1pdGl2ZU1vZGUuTElORVM6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gTWF0ZXJpYWwuTGluZUxpc3REcmF3TW9kZTtcclxuICAgICAgICAgICAgY2FzZSBNZXNoUHJpbWl0aXZlTW9kZS5MSU5FX0xPT1A6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gTWF0ZXJpYWwuTGluZUxvb3BEcmF3TW9kZTtcclxuICAgICAgICAgICAgY2FzZSBNZXNoUHJpbWl0aXZlTW9kZS5MSU5FX1NUUklQOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE1hdGVyaWFsLkxpbmVTdHJpcERyYXdNb2RlO1xyXG4gICAgICAgICAgICBjYXNlIE1lc2hQcmltaXRpdmVNb2RlLlRSSUFOR0xFUzpcclxuICAgICAgICAgICAgICAgIHJldHVybiBNYXRlcmlhbC5UcmlhbmdsZUZpbGxNb2RlO1xyXG4gICAgICAgICAgICBjYXNlIE1lc2hQcmltaXRpdmVNb2RlLlRSSUFOR0xFX1NUUklQOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE1hdGVyaWFsLlRyaWFuZ2xlU3RyaXBEcmF3TW9kZTtcclxuICAgICAgICAgICAgY2FzZSBNZXNoUHJpbWl0aXZlTW9kZS5UUklBTkdMRV9GQU46XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gTWF0ZXJpYWwuVHJpYW5nbGVGYW5EcmF3TW9kZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogSW52YWxpZCBtZXNoIHByaW1pdGl2ZSBtb2RlICgke21vZGV9KWApO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2NvbXBpbGVNYXRlcmlhbHNBc3luYygpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICB0aGlzLl9wYXJlbnQuX3N0YXJ0UGVyZm9ybWFuY2VDb3VudGVyKFwiQ29tcGlsZSBtYXRlcmlhbHNcIik7XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dW5rbm93bj4+KCk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9nbHRmLm1hdGVyaWFscykge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IG1hdGVyaWFsIG9mIHRoaXMuX2dsdGYubWF0ZXJpYWxzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAobWF0ZXJpYWwuX2RhdGEpIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGJhYnlsb25EcmF3TW9kZSBpbiBtYXRlcmlhbC5fZGF0YSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uRGF0YSA9IG1hdGVyaWFsLl9kYXRhW2JhYnlsb25EcmF3TW9kZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYmFieWxvbk1lc2ggb2YgYmFieWxvbkRhdGEuYmFieWxvbk1lc2hlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRW5zdXJlIG5vblVuaWZvcm1TY2FsaW5nIGlzIHNldCBpZiBuZWNlc3NhcnkuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWVzaC5jb21wdXRlV29ybGRNYXRyaXgodHJ1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYmFieWxvbk1hdGVyaWFsID0gYmFieWxvbkRhdGEuYmFieWxvbk1hdGVyaWFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChiYWJ5bG9uTWF0ZXJpYWwuZm9yY2VDb21waWxhdGlvbkFzeW5jKGJhYnlsb25NZXNoKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKGJhYnlsb25NYXRlcmlhbC5mb3JjZUNvbXBpbGF0aW9uQXN5bmMoYmFieWxvbk1lc2gsIHsgdXNlSW5zdGFuY2VzOiB0cnVlIH0pKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9wYXJlbnQudXNlQ2xpcFBsYW5lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChiYWJ5bG9uTWF0ZXJpYWwuZm9yY2VDb21waWxhdGlvbkFzeW5jKGJhYnlsb25NZXNoLCB7IGNsaXBQbGFuZTogdHJ1ZSB9KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChiYWJ5bG9uTWF0ZXJpYWwuZm9yY2VDb21waWxhdGlvbkFzeW5jKGJhYnlsb25NZXNoLCB7IGNsaXBQbGFuZTogdHJ1ZSwgdXNlSW5zdGFuY2VzOiB0cnVlIH0pKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fcGFyZW50Ll9lbmRQZXJmb3JtYW5jZUNvdW50ZXIoXCJDb21waWxlIG1hdGVyaWFsc1wiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9jb21waWxlU2hhZG93R2VuZXJhdG9yc0FzeW5jKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHRoaXMuX3BhcmVudC5fc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXIoXCJDb21waWxlIHNoYWRvdyBnZW5lcmF0b3JzXCIpO1xyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHVua25vd24+PigpO1xyXG5cclxuICAgICAgICBjb25zdCBsaWdodHMgPSB0aGlzLl9iYWJ5bG9uU2NlbmUubGlnaHRzO1xyXG4gICAgICAgIGZvciAoY29uc3QgbGlnaHQgb2YgbGlnaHRzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGdlbmVyYXRvciA9IGxpZ2h0LmdldFNoYWRvd0dlbmVyYXRvcigpO1xyXG4gICAgICAgICAgICBpZiAoZ2VuZXJhdG9yKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKGdlbmVyYXRvci5mb3JjZUNvbXBpbGF0aW9uQXN5bmMoKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX3BhcmVudC5fZW5kUGVyZm9ybWFuY2VDb3VudGVyKFwiQ29tcGlsZSBzaGFkb3cgZ2VuZXJhdG9yc1wiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9mb3JFYWNoRXh0ZW5zaW9ucyhhY3Rpb246IChleHRlbnNpb246IElHTFRGTG9hZGVyRXh0ZW5zaW9uKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICAgICAgZm9yIChjb25zdCBleHRlbnNpb24gb2YgdGhpcy5fZXh0ZW5zaW9ucykge1xyXG4gICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLmVuYWJsZWQpIHtcclxuICAgICAgICAgICAgICAgIGFjdGlvbihleHRlbnNpb24pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2FwcGx5RXh0ZW5zaW9uczxUPihwcm9wZXJ0eTogSVByb3BlcnR5LCBmdW5jdGlvbk5hbWU6IHN0cmluZywgYWN0aW9uQXN5bmM6IChleHRlbnNpb246IElHTFRGTG9hZGVyRXh0ZW5zaW9uKSA9PiBOdWxsYWJsZTxUPiB8IHVuZGVmaW5lZCk6IE51bGxhYmxlPFQ+IHtcclxuICAgICAgICBmb3IgKGNvbnN0IGV4dGVuc2lvbiBvZiB0aGlzLl9leHRlbnNpb25zKSB7XHJcbiAgICAgICAgICAgIGlmIChleHRlbnNpb24uZW5hYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSBgJHtleHRlbnNpb24ubmFtZX0uJHtmdW5jdGlvbk5hbWV9YDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGxvYWRlclByb3BlcnR5ID0gcHJvcGVydHkgYXMgSUxvYWRlclByb3BlcnR5O1xyXG4gICAgICAgICAgICAgICAgbG9hZGVyUHJvcGVydHkuX2FjdGl2ZUxvYWRlckV4dGVuc2lvbkZ1bmN0aW9ucyA9IGxvYWRlclByb3BlcnR5Ll9hY3RpdmVMb2FkZXJFeHRlbnNpb25GdW5jdGlvbnMgfHwge307XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhY3RpdmVMb2FkZXJFeHRlbnNpb25GdW5jdGlvbnMgPSBsb2FkZXJQcm9wZXJ0eS5fYWN0aXZlTG9hZGVyRXh0ZW5zaW9uRnVuY3Rpb25zO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFhY3RpdmVMb2FkZXJFeHRlbnNpb25GdW5jdGlvbnNbaWRdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlTG9hZGVyRXh0ZW5zaW9uRnVuY3Rpb25zW2lkXSA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGFjdGlvbkFzeW5jKGV4dGVuc2lvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgYWN0aXZlTG9hZGVyRXh0ZW5zaW9uRnVuY3Rpb25zW2lkXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNPbkxvYWRpbmcoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fZm9yRWFjaEV4dGVuc2lvbnMoKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLm9uTG9hZGluZyAmJiBleHRlbnNpb24ub25Mb2FkaW5nKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNPblJlYWR5KCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX2ZvckVhY2hFeHRlbnNpb25zKChleHRlbnNpb24pID0+IGV4dGVuc2lvbi5vblJlYWR5ICYmIGV4dGVuc2lvbi5vblJlYWR5KCkpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNMb2FkU2NlbmVBc3luYyhjb250ZXh0OiBzdHJpbmcsIHNjZW5lOiBJU2NlbmUpOiBOdWxsYWJsZTxQcm9taXNlPHZvaWQ+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5RXh0ZW5zaW9ucyhzY2VuZSwgXCJsb2FkU2NlbmVcIiwgKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLmxvYWRTY2VuZUFzeW5jICYmIGV4dGVuc2lvbi5sb2FkU2NlbmVBc3luYyhjb250ZXh0LCBzY2VuZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNMb2FkTm9kZUFzeW5jKGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU5vZGUsIGFzc2lnbjogKGJhYnlsb25UcmFuc2Zvcm1Ob2RlOiBUcmFuc2Zvcm1Ob2RlKSA9PiB2b2lkKTogTnVsbGFibGU8UHJvbWlzZTxUcmFuc2Zvcm1Ob2RlPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUV4dGVuc2lvbnMobm9kZSwgXCJsb2FkTm9kZVwiLCAoZXh0ZW5zaW9uKSA9PiBleHRlbnNpb24ubG9hZE5vZGVBc3luYyAmJiBleHRlbnNpb24ubG9hZE5vZGVBc3luYyhjb250ZXh0LCBub2RlLCBhc3NpZ24pKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9leHRlbnNpb25zTG9hZENhbWVyYUFzeW5jKGNvbnRleHQ6IHN0cmluZywgY2FtZXJhOiBJQ2FtZXJhLCBhc3NpZ246IChiYWJ5bG9uQ2FtZXJhOiBDYW1lcmEpID0+IHZvaWQpOiBOdWxsYWJsZTxQcm9taXNlPENhbWVyYT4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlFeHRlbnNpb25zKGNhbWVyYSwgXCJsb2FkQ2FtZXJhXCIsIChleHRlbnNpb24pID0+IGV4dGVuc2lvbi5sb2FkQ2FtZXJhQXN5bmMgJiYgZXh0ZW5zaW9uLmxvYWRDYW1lcmFBc3luYyhjb250ZXh0LCBjYW1lcmEsIGFzc2lnbikpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNMb2FkVmVydGV4RGF0YUFzeW5jKGNvbnRleHQ6IHN0cmluZywgcHJpbWl0aXZlOiBJTWVzaFByaW1pdGl2ZSwgYmFieWxvbk1lc2g6IE1lc2gpOiBOdWxsYWJsZTxQcm9taXNlPEdlb21ldHJ5Pj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUV4dGVuc2lvbnMocHJpbWl0aXZlLCBcImxvYWRWZXJ0ZXhEYXRhXCIsIChleHRlbnNpb24pID0+IGV4dGVuc2lvbi5fbG9hZFZlcnRleERhdGFBc3luYyAmJiBleHRlbnNpb24uX2xvYWRWZXJ0ZXhEYXRhQXN5bmMoY29udGV4dCwgcHJpbWl0aXZlLCBiYWJ5bG9uTWVzaCkpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNMb2FkTWVzaFByaW1pdGl2ZUFzeW5jKFxyXG4gICAgICAgIGNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBuYW1lOiBzdHJpbmcsXHJcbiAgICAgICAgbm9kZTogSU5vZGUsXHJcbiAgICAgICAgbWVzaDogSU1lc2gsXHJcbiAgICAgICAgcHJpbWl0aXZlOiBJTWVzaFByaW1pdGl2ZSxcclxuICAgICAgICBhc3NpZ246IChiYWJ5bG9uTWVzaDogQWJzdHJhY3RNZXNoKSA9PiB2b2lkXHJcbiAgICApOiBOdWxsYWJsZTxQcm9taXNlPEFic3RyYWN0TWVzaD4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlFeHRlbnNpb25zKFxyXG4gICAgICAgICAgICBwcmltaXRpdmUsXHJcbiAgICAgICAgICAgIFwibG9hZE1lc2hQcmltaXRpdmVcIixcclxuICAgICAgICAgICAgKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLl9sb2FkTWVzaFByaW1pdGl2ZUFzeW5jICYmIGV4dGVuc2lvbi5fbG9hZE1lc2hQcmltaXRpdmVBc3luYyhjb250ZXh0LCBuYW1lLCBub2RlLCBtZXNoLCBwcmltaXRpdmUsIGFzc2lnbilcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNMb2FkTWF0ZXJpYWxBc3luYyhcclxuICAgICAgICBjb250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgbWF0ZXJpYWw6IElNYXRlcmlhbCxcclxuICAgICAgICBiYWJ5bG9uTWVzaDogTnVsbGFibGU8TWVzaD4sXHJcbiAgICAgICAgYmFieWxvbkRyYXdNb2RlOiBudW1iZXIsXHJcbiAgICAgICAgYXNzaWduOiAoYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCkgPT4gdm9pZFxyXG4gICAgKTogTnVsbGFibGU8UHJvbWlzZTxNYXRlcmlhbD4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlFeHRlbnNpb25zKFxyXG4gICAgICAgICAgICBtYXRlcmlhbCxcclxuICAgICAgICAgICAgXCJsb2FkTWF0ZXJpYWxcIixcclxuICAgICAgICAgICAgKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLl9sb2FkTWF0ZXJpYWxBc3luYyAmJiBleHRlbnNpb24uX2xvYWRNYXRlcmlhbEFzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWVzaCwgYmFieWxvbkRyYXdNb2RlLCBhc3NpZ24pXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9leHRlbnNpb25zQ3JlYXRlTWF0ZXJpYWwoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uRHJhd01vZGU6IG51bWJlcik6IE51bGxhYmxlPE1hdGVyaWFsPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5RXh0ZW5zaW9ucyhtYXRlcmlhbCwgXCJjcmVhdGVNYXRlcmlhbFwiLCAoZXh0ZW5zaW9uKSA9PiBleHRlbnNpb24uY3JlYXRlTWF0ZXJpYWwgJiYgZXh0ZW5zaW9uLmNyZWF0ZU1hdGVyaWFsKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uRHJhd01vZGUpKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9leHRlbnNpb25zTG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlFeHRlbnNpb25zKFxyXG4gICAgICAgICAgICBtYXRlcmlhbCxcclxuICAgICAgICAgICAgXCJsb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzXCIsXHJcbiAgICAgICAgICAgIChleHRlbnNpb24pID0+IGV4dGVuc2lvbi5sb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMgJiYgZXh0ZW5zaW9uLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXh0ZW5zaW9uc0xvYWRUZXh0dXJlSW5mb0FzeW5jKGNvbnRleHQ6IHN0cmluZywgdGV4dHVyZUluZm86IElUZXh0dXJlSW5mbywgYXNzaWduOiAoYmFieWxvblRleHR1cmU6IEJhc2VUZXh0dXJlKSA9PiB2b2lkKTogTnVsbGFibGU8UHJvbWlzZTxCYXNlVGV4dHVyZT4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlFeHRlbnNpb25zKHRleHR1cmVJbmZvLCBcImxvYWRUZXh0dXJlSW5mb1wiLCAoZXh0ZW5zaW9uKSA9PiBleHRlbnNpb24ubG9hZFRleHR1cmVJbmZvQXN5bmMgJiYgZXh0ZW5zaW9uLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGNvbnRleHQsIHRleHR1cmVJbmZvLCBhc3NpZ24pKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9leHRlbnNpb25zTG9hZFRleHR1cmVBc3luYyhjb250ZXh0OiBzdHJpbmcsIHRleHR1cmU6IElUZXh0dXJlLCBhc3NpZ246IChiYWJ5bG9uVGV4dHVyZTogQmFzZVRleHR1cmUpID0+IHZvaWQpOiBOdWxsYWJsZTxQcm9taXNlPEJhc2VUZXh0dXJlPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUV4dGVuc2lvbnModGV4dHVyZSwgXCJsb2FkVGV4dHVyZVwiLCAoZXh0ZW5zaW9uKSA9PiBleHRlbnNpb24uX2xvYWRUZXh0dXJlQXN5bmMgJiYgZXh0ZW5zaW9uLl9sb2FkVGV4dHVyZUFzeW5jKGNvbnRleHQsIHRleHR1cmUsIGFzc2lnbikpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNMb2FkQW5pbWF0aW9uQXN5bmMoY29udGV4dDogc3RyaW5nLCBhbmltYXRpb246IElBbmltYXRpb24pOiBOdWxsYWJsZTxQcm9taXNlPEFuaW1hdGlvbkdyb3VwPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUV4dGVuc2lvbnMoYW5pbWF0aW9uLCBcImxvYWRBbmltYXRpb25cIiwgKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLmxvYWRBbmltYXRpb25Bc3luYyAmJiBleHRlbnNpb24ubG9hZEFuaW1hdGlvbkFzeW5jKGNvbnRleHQsIGFuaW1hdGlvbikpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNMb2FkQW5pbWF0aW9uQ2hhbm5lbEFzeW5jKFxyXG4gICAgICAgIGNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBhbmltYXRpb25Db250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgYW5pbWF0aW9uOiBJQW5pbWF0aW9uLFxyXG4gICAgICAgIGNoYW5uZWw6IElBbmltYXRpb25DaGFubmVsLFxyXG4gICAgICAgIG9uTG9hZDogKGJhYnlsb25BbmltYXRhYmxlOiBJQW5pbWF0YWJsZSwgYmFieWxvbkFuaW1hdGlvbjogQW5pbWF0aW9uKSA9PiB2b2lkXHJcbiAgICApOiBOdWxsYWJsZTxQcm9taXNlPHZvaWQ+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5RXh0ZW5zaW9ucyhcclxuICAgICAgICAgICAgYW5pbWF0aW9uLFxyXG4gICAgICAgICAgICBcImxvYWRBbmltYXRpb25DaGFubmVsXCIsXHJcbiAgICAgICAgICAgIChleHRlbnNpb24pID0+IGV4dGVuc2lvbi5fbG9hZEFuaW1hdGlvbkNoYW5uZWxBc3luYyAmJiBleHRlbnNpb24uX2xvYWRBbmltYXRpb25DaGFubmVsQXN5bmMoY29udGV4dCwgYW5pbWF0aW9uQ29udGV4dCwgYW5pbWF0aW9uLCBjaGFubmVsLCBvbkxvYWQpXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9leHRlbnNpb25zTG9hZFNraW5Bc3luYyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IElOb2RlLCBza2luOiBJU2tpbik6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlFeHRlbnNpb25zKHNraW4sIFwibG9hZFNraW5cIiwgKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLl9sb2FkU2tpbkFzeW5jICYmIGV4dGVuc2lvbi5fbG9hZFNraW5Bc3luYyhjb250ZXh0LCBub2RlLCBza2luKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXh0ZW5zaW9uc0xvYWRVcmlBc3luYyhjb250ZXh0OiBzdHJpbmcsIHByb3BlcnR5OiBJUHJvcGVydHksIHVyaTogc3RyaW5nKTogTnVsbGFibGU8UHJvbWlzZTxBcnJheUJ1ZmZlclZpZXc+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5RXh0ZW5zaW9ucyhwcm9wZXJ0eSwgXCJsb2FkVXJpXCIsIChleHRlbnNpb24pID0+IGV4dGVuc2lvbi5fbG9hZFVyaUFzeW5jICYmIGV4dGVuc2lvbi5fbG9hZFVyaUFzeW5jKGNvbnRleHQsIHByb3BlcnR5LCB1cmkpKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9leHRlbnNpb25zTG9hZEJ1ZmZlclZpZXdBc3luYyhjb250ZXh0OiBzdHJpbmcsIGJ1ZmZlclZpZXc6IElCdWZmZXJWaWV3KTogTnVsbGFibGU8UHJvbWlzZTxBcnJheUJ1ZmZlclZpZXc+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5RXh0ZW5zaW9ucyhidWZmZXJWaWV3LCBcImxvYWRCdWZmZXJWaWV3XCIsIChleHRlbnNpb24pID0+IGV4dGVuc2lvbi5sb2FkQnVmZmVyVmlld0FzeW5jICYmIGV4dGVuc2lvbi5sb2FkQnVmZmVyVmlld0FzeW5jKGNvbnRleHQsIGJ1ZmZlclZpZXcpKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9leHRlbnNpb25zTG9hZEJ1ZmZlckFzeW5jKGNvbnRleHQ6IHN0cmluZywgYnVmZmVyOiBJQnVmZmVyLCBieXRlT2Zmc2V0OiBudW1iZXIsIGJ5dGVMZW5ndGg6IG51bWJlcik6IE51bGxhYmxlPFByb21pc2U8QXJyYXlCdWZmZXJWaWV3Pj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUV4dGVuc2lvbnMoYnVmZmVyLCBcImxvYWRCdWZmZXJcIiwgKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLmxvYWRCdWZmZXJBc3luYyAmJiBleHRlbnNpb24ubG9hZEJ1ZmZlckFzeW5jKGNvbnRleHQsIGJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGVscGVyIG1ldGhvZCBjYWxsZWQgYnkgYSBsb2FkZXIgZXh0ZW5zaW9uIHRvIGxvYWQgYW4gZ2xURiBleHRlbnNpb24uXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gcHJvcGVydHkgVGhlIGdsVEYgcHJvcGVydHkgdG8gbG9hZCB0aGUgZXh0ZW5zaW9uIGZyb21cclxuICAgICAqIEBwYXJhbSBleHRlbnNpb25OYW1lIFRoZSBuYW1lIG9mIHRoZSBleHRlbnNpb24gdG8gbG9hZFxyXG4gICAgICogQHBhcmFtIGFjdGlvbkFzeW5jIFRoZSBhY3Rpb24gdG8gcnVuXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgcHJvbWlzZSByZXR1cm5lZCBieSBhY3Rpb25Bc3luYyBvciBudWxsIGlmIHRoZSBleHRlbnNpb24gZG9lcyBub3QgZXhpc3RcclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBMb2FkRXh0ZW5zaW9uQXN5bmM8VEV4dGVuc2lvbiA9IHVua25vd24sIFRSZXN1bHQgPSB2b2lkPihcclxuICAgICAgICBjb250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgcHJvcGVydHk6IElQcm9wZXJ0eSxcclxuICAgICAgICBleHRlbnNpb25OYW1lOiBzdHJpbmcsXHJcbiAgICAgICAgYWN0aW9uQXN5bmM6IChleHRlbnNpb25Db250ZXh0OiBzdHJpbmcsIGV4dGVuc2lvbjogVEV4dGVuc2lvbikgPT4gTnVsbGFibGU8UHJvbWlzZTxUUmVzdWx0Pj5cclxuICAgICk6IE51bGxhYmxlPFByb21pc2U8VFJlc3VsdD4+IHtcclxuICAgICAgICBpZiAoIXByb3BlcnR5LmV4dGVuc2lvbnMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBleHRlbnNpb25zID0gcHJvcGVydHkuZXh0ZW5zaW9ucztcclxuXHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uc1tleHRlbnNpb25OYW1lXSBhcyBURXh0ZW5zaW9uO1xyXG4gICAgICAgIGlmICghZXh0ZW5zaW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGFjdGlvbkFzeW5jKGAke2NvbnRleHR9L2V4dGVuc2lvbnMvJHtleHRlbnNpb25OYW1lfWAsIGV4dGVuc2lvbik7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIZWxwZXIgbWV0aG9kIGNhbGxlZCBieSBhIGxvYWRlciBleHRlbnNpb24gdG8gbG9hZCBhIGdsVEYgZXh0cmEuXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gcHJvcGVydHkgVGhlIGdsVEYgcHJvcGVydHkgdG8gbG9hZCB0aGUgZXh0cmEgZnJvbVxyXG4gICAgICogQHBhcmFtIGV4dGVuc2lvbk5hbWUgVGhlIG5hbWUgb2YgdGhlIGV4dGVuc2lvbiB0byBsb2FkXHJcbiAgICAgKiBAcGFyYW0gYWN0aW9uQXN5bmMgVGhlIGFjdGlvbiB0byBydW5cclxuICAgICAqIEByZXR1cm5zIFRoZSBwcm9taXNlIHJldHVybmVkIGJ5IGFjdGlvbkFzeW5jIG9yIG51bGwgaWYgdGhlIGV4dHJhIGRvZXMgbm90IGV4aXN0XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgTG9hZEV4dHJhQXN5bmM8VEV4dHJhID0gdW5rbm93biwgVFJlc3VsdCA9IHZvaWQ+KFxyXG4gICAgICAgIGNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBwcm9wZXJ0eTogSVByb3BlcnR5LFxyXG4gICAgICAgIGV4dGVuc2lvbk5hbWU6IHN0cmluZyxcclxuICAgICAgICBhY3Rpb25Bc3luYzogKGV4dHJhQ29udGV4dDogc3RyaW5nLCBleHRyYTogVEV4dHJhKSA9PiBOdWxsYWJsZTxQcm9taXNlPFRSZXN1bHQ+PlxyXG4gICAgKTogTnVsbGFibGU8UHJvbWlzZTxUUmVzdWx0Pj4ge1xyXG4gICAgICAgIGlmICghcHJvcGVydHkuZXh0cmFzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZXh0cmFzID0gcHJvcGVydHkuZXh0cmFzO1xyXG5cclxuICAgICAgICBjb25zdCBleHRyYSA9IGV4dHJhc1tleHRlbnNpb25OYW1lXSBhcyBURXh0cmE7XHJcbiAgICAgICAgaWYgKCFleHRyYSkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBhY3Rpb25Bc3luYyhgJHtjb250ZXh0fS9leHRyYXMvJHtleHRlbnNpb25OYW1lfWAsIGV4dHJhKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENoZWNrcyBmb3IgcHJlc2VuY2Ugb2YgYW4gZXh0ZW5zaW9uLlxyXG4gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGV4dGVuc2lvbiB0byBjaGVja1xyXG4gICAgICogQHJldHVybnMgQSBib29sZWFuIGluZGljYXRpbmcgdGhlIHByZXNlbmNlIG9mIHRoZSBnaXZlbiBleHRlbnNpb24gbmFtZSBpbiBgZXh0ZW5zaW9uc1VzZWRgXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBpc0V4dGVuc2lvblVzZWQobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZ2x0Zi5leHRlbnNpb25zVXNlZCAmJiB0aGlzLl9nbHRmLmV4dGVuc2lvbnNVc2VkLmluZGV4T2YobmFtZSkgIT09IC0xO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5jcmVtZW50cyB0aGUgaW5kZW50YXRpb24gbGV2ZWwgYW5kIGxvZ3MgYSBtZXNzYWdlLlxyXG4gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gbG9nXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2dPcGVuKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX3BhcmVudC5fbG9nT3BlbihtZXNzYWdlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERlY3JlbWVudHMgdGhlIGluZGVudGF0aW9uIGxldmVsLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9nQ2xvc2UoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fcGFyZW50Ll9sb2dDbG9zZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9ncyBhIG1lc3NhZ2VcclxuICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGxvZ1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9nKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX3BhcmVudC5fbG9nKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3RhcnRzIGEgcGVyZm9ybWFuY2UgY291bnRlci5cclxuICAgICAqIEBwYXJhbSBjb3VudGVyTmFtZSBUaGUgbmFtZSBvZiB0aGUgcGVyZm9ybWFuY2UgY291bnRlclxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXIoY291bnRlck5hbWU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX3BhcmVudC5fc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXIoY291bnRlck5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5kcyBhIHBlcmZvcm1hbmNlIGNvdW50ZXIuXHJcbiAgICAgKiBAcGFyYW0gY291bnRlck5hbWUgVGhlIG5hbWUgb2YgdGhlIHBlcmZvcm1hbmNlIGNvdW50ZXJcclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuZFBlcmZvcm1hbmNlQ291bnRlcihjb3VudGVyTmFtZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fcGFyZW50Ll9lbmRQZXJmb3JtYW5jZUNvdW50ZXIoY291bnRlck5hbWUpO1xyXG4gICAgfVxyXG59XHJcblxyXG5HTFRGRmlsZUxvYWRlci5fQ3JlYXRlR0xURjJMb2FkZXIgPSAocGFyZW50KSA9PiBuZXcgR0xURkxvYWRlcihwYXJlbnQpO1xyXG4iLCJpbXBvcnQgeyBBbmltYXRpb24gfSBmcm9tIFwiY29yZS9BbmltYXRpb25zL2FuaW1hdGlvblwiO1xyXG5pbXBvcnQgeyBRdWF0ZXJuaW9uLCBWZWN0b3IzIH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC52ZWN0b3JcIjtcclxuaW1wb3J0IHR5cGUgeyBJTm9kZSB9IGZyb20gXCIuL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUFuaW1hdGFibGUgfSBmcm9tIFwiY29yZS9BbmltYXRpb25zL2FuaW1hdGFibGUuaW50ZXJmYWNlXCI7XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCB0eXBlIEdldFZhbHVlRm4gPSAodGFyZ2V0OiBhbnksIHNvdXJjZTogRmxvYXQzMkFycmF5LCBvZmZzZXQ6IG51bWJlciwgc2NhbGU6IG51bWJlcikgPT4gYW55O1xyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmVjdG9yMyhfdGFyZ2V0OiBhbnksIHNvdXJjZTogRmxvYXQzMkFycmF5LCBvZmZzZXQ6IG51bWJlciwgc2NhbGU6IG51bWJlcik6IFZlY3RvcjMge1xyXG4gICAgcmV0dXJuIFZlY3RvcjMuRnJvbUFycmF5KHNvdXJjZSwgb2Zmc2V0KS5zY2FsZUluUGxhY2Uoc2NhbGUpO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRRdWF0ZXJuaW9uKF90YXJnZXQ6IGFueSwgc291cmNlOiBGbG9hdDMyQXJyYXksIG9mZnNldDogbnVtYmVyLCBzY2FsZTogbnVtYmVyKTogUXVhdGVybmlvbiB7XHJcbiAgICByZXR1cm4gUXVhdGVybmlvbi5Gcm9tQXJyYXkoc291cmNlLCBvZmZzZXQpLnNjYWxlSW5QbGFjZShzY2FsZSk7XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldFdlaWdodHModGFyZ2V0OiBJTm9kZSwgc291cmNlOiBGbG9hdDMyQXJyYXksIG9mZnNldDogbnVtYmVyLCBzY2FsZTogbnVtYmVyKTogQXJyYXk8bnVtYmVyPiB7XHJcbiAgICBjb25zdCB2YWx1ZSA9IG5ldyBBcnJheTxudW1iZXI+KHRhcmdldC5fbnVtTW9ycGhUYXJnZXRzISk7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgdmFsdWVbaV0gPSBzb3VyY2Vbb2Zmc2V0KytdICogc2NhbGU7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBbmltYXRpb25Qcm9wZXJ0eUluZm8ge1xyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHB1YmxpYyByZWFkb25seSB0eXBlOiBudW1iZXIsXHJcbiAgICAgICAgcHVibGljIHJlYWRvbmx5IG5hbWU6IHN0cmluZyxcclxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgZ2V0VmFsdWU6IEdldFZhbHVlRm4sXHJcbiAgICAgICAgcHVibGljIHJlYWRvbmx5IGdldFN0cmlkZTogKHRhcmdldDogYW55KSA9PiBudW1iZXJcclxuICAgICkge31cclxuXHJcbiAgICBwcm90ZWN0ZWQgX2J1aWxkQW5pbWF0aW9uKG5hbWU6IHN0cmluZywgZnBzOiBudW1iZXIsIGtleXM6IGFueVtdKTogQW5pbWF0aW9uIHtcclxuICAgICAgICBjb25zdCBiYWJ5bG9uQW5pbWF0aW9uID0gbmV3IEFuaW1hdGlvbihuYW1lLCB0aGlzLm5hbWUsIGZwcywgdGhpcy50eXBlKTtcclxuICAgICAgICBiYWJ5bG9uQW5pbWF0aW9uLnNldEtleXMoa2V5cyk7XHJcbiAgICAgICAgcmV0dXJuIGJhYnlsb25BbmltYXRpb247XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGFic3RyYWN0IGJ1aWxkQW5pbWF0aW9ucyh0YXJnZXQ6IGFueSwgbmFtZTogc3RyaW5nLCBmcHM6IG51bWJlciwga2V5czogYW55W10sIGNhbGxiYWNrOiAoYmFieWxvbkFuaW1hdGFibGU6IElBbmltYXRhYmxlLCBiYWJ5bG9uQW5pbWF0aW9uOiBBbmltYXRpb24pID0+IHZvaWQpOiB2b2lkO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBjbGFzcyBUcmFuc2Zvcm1Ob2RlQW5pbWF0aW9uUHJvcGVydHlJbmZvIGV4dGVuZHMgQW5pbWF0aW9uUHJvcGVydHlJbmZvIHtcclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBidWlsZEFuaW1hdGlvbnModGFyZ2V0OiBJTm9kZSwgbmFtZTogc3RyaW5nLCBmcHM6IG51bWJlciwga2V5czogYW55W10sIGNhbGxiYWNrOiAoYmFieWxvbkFuaW1hdGFibGU6IElBbmltYXRhYmxlLCBiYWJ5bG9uQW5pbWF0aW9uOiBBbmltYXRpb24pID0+IHZvaWQpOiB2b2lkIHtcclxuICAgICAgICBjYWxsYmFjayh0YXJnZXQuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlISwgdGhpcy5fYnVpbGRBbmltYXRpb24obmFtZSwgZnBzLCBrZXlzKSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGNsYXNzIFdlaWdodEFuaW1hdGlvblByb3BlcnR5SW5mbyBleHRlbmRzIEFuaW1hdGlvblByb3BlcnR5SW5mbyB7XHJcbiAgICBwdWJsaWMgYnVpbGRBbmltYXRpb25zKHRhcmdldDogSU5vZGUsIG5hbWU6IHN0cmluZywgZnBzOiBudW1iZXIsIGtleXM6IGFueVtdLCBjYWxsYmFjazogKGJhYnlsb25BbmltYXRhYmxlOiBJQW5pbWF0YWJsZSwgYmFieWxvbkFuaW1hdGlvbjogQW5pbWF0aW9uKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRhcmdldC5fbnVtTW9ycGhUYXJnZXRzKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IHRhcmdldEluZGV4ID0gMDsgdGFyZ2V0SW5kZXggPCB0YXJnZXQuX251bU1vcnBoVGFyZ2V0czsgdGFyZ2V0SW5kZXgrKykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYmFieWxvbkFuaW1hdGlvbiA9IG5ldyBBbmltYXRpb24oYCR7bmFtZX1fJHt0YXJnZXRJbmRleH1gLCB0aGlzLm5hbWUsIGZwcywgdGhpcy50eXBlKTtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25BbmltYXRpb24uc2V0S2V5cyhcclxuICAgICAgICAgICAgICAgICAgICBrZXlzLm1hcCgoa2V5KSA9PiAoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmcmFtZToga2V5LmZyYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpblRhbmdlbnQ6IGtleS5pblRhbmdlbnQgPyBrZXkuaW5UYW5nZW50W3RhcmdldEluZGV4XSA6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGtleS52YWx1ZVt0YXJnZXRJbmRleF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dFRhbmdlbnQ6IGtleS5vdXRUYW5nZW50ID8ga2V5Lm91dFRhbmdlbnRbdGFyZ2V0SW5kZXhdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnBvbGF0aW9uOiBrZXkuaW50ZXJwb2xhdGlvbixcclxuICAgICAgICAgICAgICAgICAgICB9KSlcclxuICAgICAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRhcmdldC5fcHJpbWl0aXZlQmFieWxvbk1lc2hlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYmFieWxvbk1lc2ggb2YgdGFyZ2V0Ll9wcmltaXRpdmVCYWJ5bG9uTWVzaGVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTWVzaC5tb3JwaFRhcmdldE1hbmFnZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1vcnBoVGFyZ2V0ID0gYmFieWxvbk1lc2gubW9ycGhUYXJnZXRNYW5hZ2VyLmdldFRhcmdldCh0YXJnZXRJbmRleCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uQW5pbWF0aW9uQ2xvbmUgPSBiYWJ5bG9uQW5pbWF0aW9uLmNsb25lKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3JwaFRhcmdldC5hbmltYXRpb25zLnB1c2goYmFieWxvbkFuaW1hdGlvbkNsb25lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG1vcnBoVGFyZ2V0LCBiYWJ5bG9uQW5pbWF0aW9uQ2xvbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBjb25zdCBub2RlQW5pbWF0aW9uRGF0YSA9IHtcclxuICAgIHRyYW5zbGF0aW9uOiBbbmV3IFRyYW5zZm9ybU5vZGVBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfVkVDVE9SMywgXCJwb3NpdGlvblwiLCBnZXRWZWN0b3IzLCAoKSA9PiAzKV0sXHJcbiAgICByb3RhdGlvbjogW25ldyBUcmFuc2Zvcm1Ob2RlQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX1FVQVRFUk5JT04sIFwicm90YXRpb25RdWF0ZXJuaW9uXCIsIGdldFF1YXRlcm5pb24sICgpID0+IDQpXSxcclxuICAgIHNjYWxlOiBbbmV3IFRyYW5zZm9ybU5vZGVBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfVkVDVE9SMywgXCJzY2FsaW5nXCIsIGdldFZlY3RvcjMsICgpID0+IDMpXSxcclxuICAgIHdlaWdodHM6IFtuZXcgV2VpZ2h0QW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcImluZmx1ZW5jZVwiLCBnZXRXZWlnaHRzLCAodGFyZ2V0KSA9PiB0YXJnZXQuX251bU1vcnBoVGFyZ2V0cyEpXSxcclxufTtcclxuIiwiaW1wb3J0IHR5cGUgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5cclxuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcImNvcmUvTWlzYy9sb2dnZXJcIjtcclxuXHJcbmludGVyZmFjZSBJUmVnaXN0ZXJlZEdMVEZFeHRlbnNpb24ge1xyXG4gICAgaXNHTFRGRXh0ZW5zaW9uOiBib29sZWFuO1xyXG4gICAgZmFjdG9yeTogR0xURkV4dGVuc2lvbkZhY3Rvcnk7XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIEdMVEZFeHRlbnNpb25GYWN0b3J5ID0gKGxvYWRlcjogR0xURkxvYWRlcikgPT4gSUdMVEZMb2FkZXJFeHRlbnNpb24gfCBQcm9taXNlPElHTFRGTG9hZGVyRXh0ZW5zaW9uPjtcclxuXHJcbmNvbnN0IF9yZWdpc3RlcmVkR0xURkV4dGVuc2lvbnMgPSBuZXcgTWFwPHN0cmluZywgSVJlZ2lzdGVyZWRHTFRGRXh0ZW5zaW9uPigpO1xyXG5cclxuLyoqXHJcbiAqIEFsbCBjdXJyZW50bHkgcmVnaXN0ZXJlZCBnbFRGIDIuMCBsb2FkZXIgZXh0ZW5zaW9ucy5cclxuICovXHJcbmV4cG9ydCBjb25zdCByZWdpc3RlcmVkR0xURkV4dGVuc2lvbnM6IFJlYWRvbmx5TWFwPHN0cmluZywgUmVhZG9ubHk8SVJlZ2lzdGVyZWRHTFRGRXh0ZW5zaW9uPj4gPSBfcmVnaXN0ZXJlZEdMVEZFeHRlbnNpb25zO1xyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhIGxvYWRlciBleHRlbnNpb24uXHJcbiAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBsb2FkZXIgZXh0ZW5zaW9uLlxyXG4gKiBAcGFyYW0gaXNHTFRGRXh0ZW5zaW9uIElmIHRoZSBsb2FkZXIgZXh0ZW5zaW9uIGlzIGEgZ2xURiBleHRlbnNpb24sIHRoZW4gaXQgd2lsbCBvbmx5IGJlIHVzZWQgZm9yIGdsVEYgZmlsZXMgdGhhdCB1c2UgdGhlIGNvcnJlc3BvbmRpbmcgZ2xURiBleHRlbnNpb24uIE90aGVyd2lzZSwgaXQgd2lsbCBiZSB1c2VkIGZvciBhbGwgbG9hZGVkIGdsVEYgZmlsZXMuXHJcbiAqIEBwYXJhbSBmYWN0b3J5IFRoZSBmYWN0b3J5IGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyB0aGUgbG9hZGVyIGV4dGVuc2lvbi5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckdMVEZFeHRlbnNpb24obmFtZTogc3RyaW5nLCBpc0dMVEZFeHRlbnNpb246IGJvb2xlYW4sIGZhY3Rvcnk6IEdMVEZFeHRlbnNpb25GYWN0b3J5KTogdm9pZCB7XHJcbiAgICBpZiAodW5yZWdpc3RlckdMVEZFeHRlbnNpb24obmFtZSkpIHtcclxuICAgICAgICBMb2dnZXIuV2FybihgRXh0ZW5zaW9uIHdpdGggdGhlIG5hbWUgJyR7bmFtZX0nIGFscmVhZHkgZXhpc3RzYCk7XHJcbiAgICB9XHJcblxyXG4gICAgX3JlZ2lzdGVyZWRHTFRGRXh0ZW5zaW9ucy5zZXQobmFtZSwge1xyXG4gICAgICAgIGlzR0xURkV4dGVuc2lvbixcclxuICAgICAgICBmYWN0b3J5LFxyXG4gICAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBVbnJlZ2lzdGVycyBhIGxvYWRlciBleHRlbnNpb24uXHJcbiAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBsb2FkZXIgZXh0ZW5zaW9uLlxyXG4gKiBAcmV0dXJucyBBIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBleHRlbnNpb24gaGFzIGJlZW4gdW5yZWdpc3RlcmVkXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gdW5yZWdpc3RlckdMVEZFeHRlbnNpb24obmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gX3JlZ2lzdGVyZWRHTFRGRXh0ZW5zaW9ucy5kZWxldGUobmFtZSk7XHJcbn1cclxuIiwiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWludGVybmFsLW1vZHVsZXMgKi9cclxuZXhwb3J0ICogZnJvbSBcIi4vZ2xURkxvYWRlclwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9FeHRlbnNpb25zL2luZGV4XCI7XHJcbiIsIi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8taW50ZXJuYWwtbW9kdWxlc1xyXG5pbXBvcnQgdHlwZSB7IElTY2VuZUxvYWRlclBsdWdpbkV4dGVuc2lvbnMsIElTY2VuZUxvYWRlclBsdWdpbk1ldGFkYXRhIH0gZnJvbSBcImNvcmUvaW5kZXhcIjtcclxuXHJcbmV4cG9ydCBjb25zdCBHTFRGTWFnaWNCYXNlNjRFbmNvZGVkID0gXCJaMnhVUmdcIjsgLy8gXCJnbFRGXCIgYmFzZTY0IGVuY29kZWQgKHdpdGhvdXQgdGhlIHF1b3RlcyEpXHJcblxyXG5leHBvcnQgY29uc3QgR0xURkZpbGVMb2FkZXJNZXRhZGF0YSA9IHtcclxuICAgIG5hbWU6IFwiZ2x0ZlwiLFxyXG5cclxuICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbiAgICAgICAgXCIuZ2x0ZlwiOiB7IGlzQmluYXJ5OiBmYWxzZSwgbWltZVR5cGU6IFwibW9kZWwvZ2x0Zitqc29uXCIgfSxcclxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbiAgICAgICAgXCIuZ2xiXCI6IHsgaXNCaW5hcnk6IHRydWUsIG1pbWVUeXBlOiBcIm1vZGVsL2dsdGYtYmluYXJ5XCIgfSxcclxuICAgIH0gYXMgY29uc3Qgc2F0aXNmaWVzIElTY2VuZUxvYWRlclBsdWdpbkV4dGVuc2lvbnMsXHJcblxyXG4gICAgY2FuRGlyZWN0TG9hZChkYXRhOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgICAoZGF0YS5pbmRleE9mKFwiYXNzZXRcIikgIT09IC0xICYmIGRhdGEuaW5kZXhPZihcInZlcnNpb25cIikgIT09IC0xKSB8fFxyXG4gICAgICAgICAgICBkYXRhLnN0YXJ0c1dpdGgoXCJkYXRhOmJhc2U2NCxcIiArIEdMVEZNYWdpY0Jhc2U2NEVuY29kZWQpIHx8IC8vIHRoaXMgaXMgdGVjaG5pY2FsbHkgaW5jb3JyZWN0LCBidXQgd2lsbCBjb250aW51ZSB0byBzdXBwb3J0IGZvciBiYWNrY29tcGF0LlxyXG4gICAgICAgICAgICBkYXRhLnN0YXJ0c1dpdGgoXCJkYXRhOjtiYXNlNjQsXCIgKyBHTFRGTWFnaWNCYXNlNjRFbmNvZGVkKSB8fFxyXG4gICAgICAgICAgICBkYXRhLnN0YXJ0c1dpdGgoXCJkYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTtiYXNlNjQsXCIgKyBHTFRGTWFnaWNCYXNlNjRFbmNvZGVkKSB8fFxyXG4gICAgICAgICAgICBkYXRhLnN0YXJ0c1dpdGgoXCJkYXRhOm1vZGVsL2dsdGYtYmluYXJ5O2Jhc2U2NCxcIiArIEdMVEZNYWdpY0Jhc2U2NEVuY29kZWQpXHJcbiAgICAgICAgKTtcclxuICAgIH0sXHJcbn0gYXMgY29uc3Qgc2F0aXNmaWVzIElTY2VuZUxvYWRlclBsdWdpbk1ldGFkYXRhO1xyXG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cclxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXHJcbmltcG9ydCB0eXBlICogYXMgR0xURjIgZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBPYnNlcnZlciB9IGZyb20gXCJjb3JlL01pc2Mvb2JzZXJ2YWJsZVwiO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSBcImNvcmUvTWlzYy9vYnNlcnZhYmxlXCI7XHJcbmltcG9ydCB7IFRvb2xzIH0gZnJvbSBcImNvcmUvTWlzYy90b29sc1wiO1xyXG5pbXBvcnQgdHlwZSB7IENhbWVyYSB9IGZyb20gXCJjb3JlL0NhbWVyYXMvY2FtZXJhXCI7XHJcbmltcG9ydCB0eXBlIHsgQmFzZVRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvYmFzZVRleHR1cmVcIjtcclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IEFic3RyYWN0TWVzaCB9IGZyb20gXCJjb3JlL01lc2hlcy9hYnN0cmFjdE1lc2hcIjtcclxuaW1wb3J0IHR5cGUgeyBJU2NlbmVMb2FkZXJQbHVnaW5GYWN0b3J5LCBJU2NlbmVMb2FkZXJQbHVnaW5Bc3luYywgSVNjZW5lTG9hZGVyUHJvZ3Jlc3NFdmVudCwgSVNjZW5lTG9hZGVyQXN5bmNSZXN1bHQsIFNjZW5lTG9hZGVyUGx1Z2luT3B0aW9ucyB9IGZyb20gXCJjb3JlL0xvYWRpbmcvc2NlbmVMb2FkZXJcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJTY2VuZUxvYWRlclBsdWdpbiB9IGZyb20gXCJjb3JlL0xvYWRpbmcvc2NlbmVMb2FkZXJcIjtcclxuaW1wb3J0IHsgQXNzZXRDb250YWluZXIgfSBmcm9tIFwiY29yZS9hc3NldENvbnRhaW5lclwiO1xyXG5pbXBvcnQgdHlwZSB7IFNjZW5lLCBJRGlzcG9zYWJsZSB9IGZyb20gXCJjb3JlL3NjZW5lXCI7XHJcbmltcG9ydCB0eXBlIHsgV2ViUmVxdWVzdCB9IGZyb20gXCJjb3JlL01pc2Mvd2ViUmVxdWVzdFwiO1xyXG5pbXBvcnQgdHlwZSB7IElGaWxlUmVxdWVzdCB9IGZyb20gXCJjb3JlL01pc2MvZmlsZVJlcXVlc3RcIjtcclxuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcImNvcmUvTWlzYy9sb2dnZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJRGF0YUJ1ZmZlciB9IGZyb20gXCJjb3JlL01pc2MvZGF0YVJlYWRlclwiO1xyXG5pbXBvcnQgeyBEYXRhUmVhZGVyIH0gZnJvbSBcImNvcmUvTWlzYy9kYXRhUmVhZGVyXCI7XHJcbmltcG9ydCB7IEdMVEZWYWxpZGF0aW9uIH0gZnJvbSBcIi4vZ2xURlZhbGlkYXRpb25cIjtcclxuaW1wb3J0IHsgR0xURkZpbGVMb2FkZXJNZXRhZGF0YSwgR0xURk1hZ2ljQmFzZTY0RW5jb2RlZCB9IGZyb20gXCIuL2dsVEZGaWxlTG9hZGVyLm1ldGFkYXRhXCI7XHJcbmltcG9ydCB0eXBlIHsgTG9hZEZpbGVFcnJvciB9IGZyb20gXCJjb3JlL01pc2MvZmlsZVRvb2xzXCI7XHJcbmltcG9ydCB7IERlY29kZUJhc2U2NFVybFRvQmluYXJ5IH0gZnJvbSBcImNvcmUvTWlzYy9maWxlVG9vbHNcIjtcclxuaW1wb3J0IHsgUnVudGltZUVycm9yLCBFcnJvckNvZGVzIH0gZnJvbSBcImNvcmUvTWlzYy9lcnJvclwiO1xyXG5pbXBvcnQgdHlwZSB7IFRyYW5zZm9ybU5vZGUgfSBmcm9tIFwiY29yZS9NZXNoZXMvdHJhbnNmb3JtTm9kZVwiO1xyXG5pbXBvcnQgdHlwZSB7IE1vcnBoVGFyZ2V0TWFuYWdlciB9IGZyb20gXCJjb3JlL01vcnBoL21vcnBoVGFyZ2V0TWFuYWdlclwiO1xyXG5cclxuLyoqXHJcbiAqIERlZmluZXMgb3B0aW9ucyBmb3IgZ2xURiBsb2FkZXIgZXh0ZW5zaW9ucy4gVGhpcyBpbnRlcmZhY2UgaXMgZXh0ZW5kZWQgYnkgc3BlY2lmaWMgZXh0ZW5zaW9ucy5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZD4ge31cclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiY29yZS9Mb2FkaW5nL3NjZW5lTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgU2NlbmVMb2FkZXJQbHVnaW5PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBnbFRGIGxvYWRlci5cclxuICAgICAgICAgKi9cclxuICAgICAgICBbR0xURkZpbGVMb2FkZXJNZXRhZGF0YS5uYW1lXTogUGFydGlhbDxHTFRGTG9hZGVyT3B0aW9ucz47XHJcbiAgICB9XHJcbn1cclxuXHJcbmludGVyZmFjZSBJRmlsZVJlcXVlc3RJbmZvIGV4dGVuZHMgSUZpbGVSZXF1ZXN0IHtcclxuICAgIF9sZW5ndGhDb21wdXRhYmxlPzogYm9vbGVhbjtcclxuICAgIF9sb2FkZWQ/OiBudW1iZXI7XHJcbiAgICBfdG90YWw/OiBudW1iZXI7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlYWRBc3luYyhhcnJheUJ1ZmZlcjogQXJyYXlCdWZmZXIsIGJ5dGVPZmZzZXQ6IG51bWJlciwgYnl0ZUxlbmd0aDogbnVtYmVyKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IFVpbnQ4QXJyYXkoYXJyYXlCdWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpKTtcclxuICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlYWRWaWV3QXN5bmMoYXJyYXlCdWZmZXJWaWV3OiBBcnJheUJ1ZmZlclZpZXcsIGJ5dGVPZmZzZXQ6IG51bWJlciwgYnl0ZUxlbmd0aDogbnVtYmVyKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIGlmIChieXRlT2Zmc2V0IDwgMCB8fCBieXRlT2Zmc2V0ID49IGFycmF5QnVmZmVyVmlldy5ieXRlTGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiT2Zmc2V0IGlzIG91dCBvZiByYW5nZS5cIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoYnl0ZU9mZnNldCArIGJ5dGVMZW5ndGggPiBhcnJheUJ1ZmZlclZpZXcuYnl0ZUxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkxlbmd0aCBpcyBvdXQgb2YgcmFuZ2UuXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlclZpZXcuYnVmZmVyLCBhcnJheUJ1ZmZlclZpZXcuYnl0ZU9mZnNldCArIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpKTtcclxuICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBNb2RlIHRoYXQgZGV0ZXJtaW5lcyB0aGUgY29vcmRpbmF0ZSBzeXN0ZW0gdG8gdXNlLlxyXG4gKi9cclxuZXhwb3J0IGVudW0gR0xURkxvYWRlckNvb3JkaW5hdGVTeXN0ZW1Nb2RlIHtcclxuICAgIC8qKlxyXG4gICAgICogQXV0b21hdGljYWxseSBjb252ZXJ0IHRoZSBnbFRGIHJpZ2h0LWhhbmRlZCBkYXRhIHRvIHRoZSBhcHByb3ByaWF0ZSBzeXN0ZW0gYmFzZWQgb24gdGhlIGN1cnJlbnQgY29vcmRpbmF0ZSBzeXN0ZW0gbW9kZSBvZiB0aGUgc2NlbmUuXHJcbiAgICAgKi9cclxuICAgIEFVVE8sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHRoZSB1c2VSaWdodEhhbmRlZFN5c3RlbSBmbGFnIG9uIHRoZSBzY2VuZS5cclxuICAgICAqL1xyXG4gICAgRk9SQ0VfUklHSFRfSEFOREVELFxyXG59XHJcblxyXG4vKipcclxuICogTW9kZSB0aGF0IGRldGVybWluZXMgd2hhdCBhbmltYXRpb25zIHdpbGwgc3RhcnQuXHJcbiAqL1xyXG5leHBvcnQgZW51bSBHTFRGTG9hZGVyQW5pbWF0aW9uU3RhcnRNb2RlIHtcclxuICAgIC8qKlxyXG4gICAgICogTm8gYW5pbWF0aW9uIHdpbGwgc3RhcnQuXHJcbiAgICAgKi9cclxuICAgIE5PTkUsXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgZmlyc3QgYW5pbWF0aW9uIHdpbGwgc3RhcnQuXHJcbiAgICAgKi9cclxuICAgIEZJUlNULFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsIGFuaW1hdGlvbnMgd2lsbCBzdGFydC5cclxuICAgICAqL1xyXG4gICAgQUxMLFxyXG59XHJcblxyXG4vKipcclxuICogSW50ZXJmYWNlIHRoYXQgY29udGFpbnMgdGhlIGRhdGEgZm9yIHRoZSBnbFRGIGFzc2V0LlxyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBJR0xURkxvYWRlckRhdGEge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgZ2xURiBKU09OLlxyXG4gICAgICovXHJcbiAgICBqc29uOiBPYmplY3Q7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgQklOIGNodW5rIG9mIGEgYmluYXJ5IGdsVEYuXHJcbiAgICAgKi9cclxuICAgIGJpbjogTnVsbGFibGU8SURhdGFCdWZmZXI+O1xyXG59XHJcblxyXG4vKipcclxuICogSW50ZXJmYWNlIGZvciBleHRlbmRpbmcgdGhlIGxvYWRlci5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHRoZSBvcmRlciBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqIFRoZSBsb2FkZXIgc29ydHMgdGhlIGV4dGVuc2lvbnMgdXNpbmcgdGhlc2UgdmFsdWVzIHdoZW4gbG9hZGluZy5cclxuICAgICAqL1xyXG4gICAgb3JkZXI/OiBudW1iZXI7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBMb2FkZXIgc3RhdGUuXHJcbiAqL1xyXG5leHBvcnQgZW51bSBHTFRGTG9hZGVyU3RhdGUge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgYXNzZXQgaXMgbG9hZGluZy5cclxuICAgICAqL1xyXG4gICAgTE9BRElORyxcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBhc3NldCBpcyByZWFkeSBmb3IgcmVuZGVyaW5nLlxyXG4gICAgICovXHJcbiAgICBSRUFEWSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBhc3NldCBpcyBjb21wbGV0ZWx5IGxvYWRlZC5cclxuICAgICAqL1xyXG4gICAgQ09NUExFVEUsXHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGludGVyZmFjZSBJR0xURkxvYWRlciBleHRlbmRzIElEaXNwb3NhYmxlIHtcclxuICAgIGltcG9ydE1lc2hBc3luYzogKFxyXG4gICAgICAgIG1lc2hlc05hbWVzOiBzdHJpbmcgfCByZWFkb25seSBzdHJpbmdbXSB8IG51bGwgfCB1bmRlZmluZWQsXHJcbiAgICAgICAgc2NlbmU6IFNjZW5lLFxyXG4gICAgICAgIGNvbnRhaW5lcjogTnVsbGFibGU8QXNzZXRDb250YWluZXI+LFxyXG4gICAgICAgIGRhdGE6IElHTFRGTG9hZGVyRGF0YSxcclxuICAgICAgICByb290VXJsOiBzdHJpbmcsXHJcbiAgICAgICAgb25Qcm9ncmVzcz86IChldmVudDogSVNjZW5lTG9hZGVyUHJvZ3Jlc3NFdmVudCkgPT4gdm9pZCxcclxuICAgICAgICBmaWxlTmFtZT86IHN0cmluZ1xyXG4gICAgKSA9PiBQcm9taXNlPElTY2VuZUxvYWRlckFzeW5jUmVzdWx0PjtcclxuICAgIGxvYWRBc3luYzogKHNjZW5lOiBTY2VuZSwgZGF0YTogSUdMVEZMb2FkZXJEYXRhLCByb290VXJsOiBzdHJpbmcsIG9uUHJvZ3Jlc3M/OiAoZXZlbnQ6IElTY2VuZUxvYWRlclByb2dyZXNzRXZlbnQpID0+IHZvaWQsIGZpbGVOYW1lPzogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+O1xyXG59XHJcblxyXG4vKipcclxuICogQWRkcyBkZWZhdWx0L2ltcGxpY2l0IG9wdGlvbnMgdG8gZXh0ZW5zaW9uIHNwZWNpZmljIG9wdGlvbnMuXHJcbiAqL1xyXG50eXBlIERlZmF1bHRFeHRlbnNpb25PcHRpb25zPEJhc2VFeHRlbnNpb25PcHRpb25zPiA9IHtcclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBpZiB0aGUgZXh0ZW5zaW9uIGlzIGVuYWJsZWRcclxuICAgICAqL1xyXG4gICAgZW5hYmxlZD86IGJvb2xlYW47XHJcbn0gJiBCYXNlRXh0ZW5zaW9uT3B0aW9ucztcclxuXHJcbmFic3RyYWN0IGNsYXNzIEdMVEZMb2FkZXJPcHRpb25zIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBiYWJ5bG9uanMvYXZhaWxhYmxlXHJcbiAgICBwcm90ZWN0ZWQgY29weUZyb20ob3B0aW9ucz86IFBhcnRpYWw8UmVhZG9ubHk8R0xURkxvYWRlck9wdGlvbnM+Pikge1xyXG4gICAgICAgIGlmIChvcHRpb25zKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25QYXJzZWQgPSBvcHRpb25zLm9uUGFyc2VkO1xyXG4gICAgICAgICAgICB0aGlzLmNvb3JkaW5hdGVTeXN0ZW1Nb2RlID0gb3B0aW9ucy5jb29yZGluYXRlU3lzdGVtTW9kZSA/PyB0aGlzLmNvb3JkaW5hdGVTeXN0ZW1Nb2RlO1xyXG4gICAgICAgICAgICB0aGlzLmFuaW1hdGlvblN0YXJ0TW9kZSA9IG9wdGlvbnMuYW5pbWF0aW9uU3RhcnRNb2RlID8/IHRoaXMuYW5pbWF0aW9uU3RhcnRNb2RlO1xyXG4gICAgICAgICAgICB0aGlzLmxvYWROb2RlQW5pbWF0aW9ucyA9IG9wdGlvbnMubG9hZE5vZGVBbmltYXRpb25zID8/IHRoaXMubG9hZE5vZGVBbmltYXRpb25zO1xyXG4gICAgICAgICAgICB0aGlzLmxvYWRTa2lucyA9IG9wdGlvbnMubG9hZFNraW5zID8/IHRoaXMubG9hZFNraW5zO1xyXG4gICAgICAgICAgICB0aGlzLmxvYWRNb3JwaFRhcmdldHMgPSBvcHRpb25zLmxvYWRNb3JwaFRhcmdldHMgPz8gdGhpcy5sb2FkTW9ycGhUYXJnZXRzO1xyXG4gICAgICAgICAgICB0aGlzLmNvbXBpbGVNYXRlcmlhbHMgPSBvcHRpb25zLmNvbXBpbGVNYXRlcmlhbHMgPz8gdGhpcy5jb21waWxlTWF0ZXJpYWxzO1xyXG4gICAgICAgICAgICB0aGlzLnVzZUNsaXBQbGFuZSA9IG9wdGlvbnMudXNlQ2xpcFBsYW5lID8/IHRoaXMudXNlQ2xpcFBsYW5lO1xyXG4gICAgICAgICAgICB0aGlzLmNvbXBpbGVTaGFkb3dHZW5lcmF0b3JzID0gb3B0aW9ucy5jb21waWxlU2hhZG93R2VuZXJhdG9ycyA/PyB0aGlzLmNvbXBpbGVTaGFkb3dHZW5lcmF0b3JzO1xyXG4gICAgICAgICAgICB0aGlzLnRyYW5zcGFyZW5jeUFzQ292ZXJhZ2UgPSBvcHRpb25zLnRyYW5zcGFyZW5jeUFzQ292ZXJhZ2UgPz8gdGhpcy50cmFuc3BhcmVuY3lBc0NvdmVyYWdlO1xyXG4gICAgICAgICAgICB0aGlzLnVzZVJhbmdlUmVxdWVzdHMgPSBvcHRpb25zLnVzZVJhbmdlUmVxdWVzdHMgPz8gdGhpcy51c2VSYW5nZVJlcXVlc3RzO1xyXG4gICAgICAgICAgICB0aGlzLmNyZWF0ZUluc3RhbmNlcyA9IG9wdGlvbnMuY3JlYXRlSW5zdGFuY2VzID8/IHRoaXMuY3JlYXRlSW5zdGFuY2VzO1xyXG4gICAgICAgICAgICB0aGlzLmFsd2F5c0NvbXB1dGVCb3VuZGluZ0JveCA9IG9wdGlvbnMuYWx3YXlzQ29tcHV0ZUJvdW5kaW5nQm94ID8/IHRoaXMuYWx3YXlzQ29tcHV0ZUJvdW5kaW5nQm94O1xyXG4gICAgICAgICAgICB0aGlzLmxvYWRBbGxNYXRlcmlhbHMgPSBvcHRpb25zLmxvYWRBbGxNYXRlcmlhbHMgPz8gdGhpcy5sb2FkQWxsTWF0ZXJpYWxzO1xyXG4gICAgICAgICAgICB0aGlzLmxvYWRPbmx5TWF0ZXJpYWxzID0gb3B0aW9ucy5sb2FkT25seU1hdGVyaWFscyA/PyB0aGlzLmxvYWRPbmx5TWF0ZXJpYWxzO1xyXG4gICAgICAgICAgICB0aGlzLnNraXBNYXRlcmlhbHMgPSBvcHRpb25zLnNraXBNYXRlcmlhbHMgPz8gdGhpcy5za2lwTWF0ZXJpYWxzO1xyXG4gICAgICAgICAgICB0aGlzLnVzZVNSR0JCdWZmZXJzID0gb3B0aW9ucy51c2VTUkdCQnVmZmVycyA/PyB0aGlzLnVzZVNSR0JCdWZmZXJzO1xyXG4gICAgICAgICAgICB0aGlzLnRhcmdldEZwcyA9IG9wdGlvbnMudGFyZ2V0RnBzID8/IHRoaXMudGFyZ2V0RnBzO1xyXG4gICAgICAgICAgICB0aGlzLmFsd2F5c0NvbXB1dGVTa2VsZXRvblJvb3ROb2RlID0gb3B0aW9ucy5hbHdheXNDb21wdXRlU2tlbGV0b25Sb290Tm9kZSA/PyB0aGlzLmFsd2F5c0NvbXB1dGVTa2VsZXRvblJvb3ROb2RlO1xyXG4gICAgICAgICAgICB0aGlzLnVzZUdsdGZUZXh0dXJlTmFtZXMgPSBvcHRpb25zLnVzZUdsdGZUZXh0dXJlTmFtZXMgPz8gdGhpcy51c2VHbHRmVGV4dHVyZU5hbWVzO1xyXG4gICAgICAgICAgICB0aGlzLnByZXByb2Nlc3NVcmxBc3luYyA9IG9wdGlvbnMucHJlcHJvY2Vzc1VybEFzeW5jID8/IHRoaXMucHJlcHJvY2Vzc1VybEFzeW5jO1xyXG4gICAgICAgICAgICB0aGlzLmN1c3RvbVJvb3ROb2RlID0gb3B0aW9ucy5jdXN0b21Sb290Tm9kZTtcclxuICAgICAgICAgICAgdGhpcy5vbk1lc2hMb2FkZWQgPSBvcHRpb25zLm9uTWVzaExvYWRlZDtcclxuICAgICAgICAgICAgdGhpcy5vblNraW5Mb2FkZWQgPSBvcHRpb25zLm9uU2tpbkxvYWRlZDtcclxuICAgICAgICAgICAgdGhpcy5vblRleHR1cmVMb2FkZWQgPSBvcHRpb25zLm9uVGV4dHVyZUxvYWRlZDtcclxuICAgICAgICAgICAgdGhpcy5vbk1hdGVyaWFsTG9hZGVkID0gb3B0aW9ucy5vbk1hdGVyaWFsTG9hZGVkO1xyXG4gICAgICAgICAgICB0aGlzLm9uQ2FtZXJhTG9hZGVkID0gb3B0aW9ucy5vbkNhbWVyYUxvYWRlZDtcclxuICAgICAgICAgICAgdGhpcy5leHRlbnNpb25PcHRpb25zID0gb3B0aW9ucy5leHRlbnNpb25PcHRpb25zID8/IHRoaXMuZXh0ZW5zaW9uT3B0aW9ucztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS1cclxuICAgIC8vIENvbW1vbiBvcHRpb25zXHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmFpc2VkIHdoZW4gdGhlIGFzc2V0IGhhcyBiZWVuIHBhcnNlZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWJzdHJhY3Qgb25QYXJzZWQ/OiAoKGxvYWRlckRhdGE6IElHTFRGTG9hZGVyRGF0YSkgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XHJcblxyXG4gICAgLy8gLS0tLS0tLS0tLVxyXG4gICAgLy8gVjIgb3B0aW9uc1xyXG4gICAgLy8gLS0tLS0tLS0tLVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGNvb3JkaW5hdGUgc3lzdGVtIG1vZGUuIERlZmF1bHRzIHRvIEFVVE8uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb29yZGluYXRlU3lzdGVtTW9kZSA9IEdMVEZMb2FkZXJDb29yZGluYXRlU3lzdGVtTW9kZS5BVVRPO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGFuaW1hdGlvbiBzdGFydCBtb2RlLiBEZWZhdWx0cyB0byBGSVJTVC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGFuaW1hdGlvblN0YXJ0TW9kZSA9IEdMVEZMb2FkZXJBbmltYXRpb25TdGFydE1vZGUuRklSU1Q7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGlmIHRoZSBsb2FkZXIgc2hvdWxkIGxvYWQgbm9kZSBhbmltYXRpb25zLiBEZWZhdWx0cyB0byB0cnVlLlxyXG4gICAgICogTk9URTogVGhlIGFuaW1hdGlvbiBvZiB0aGlzIG5vZGUgd2lsbCBzdGlsbCBsb2FkIGlmIHRoZSBub2RlIGlzIGFsc28gYSBqb2ludCBvZiBhIHNraW4gYW5kIGBsb2FkU2tpbnNgIGlzIHRydWUuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTm9kZUFuaW1hdGlvbnMgPSB0cnVlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBpZiB0aGUgbG9hZGVyIHNob3VsZCBsb2FkIHNraW5zLiBEZWZhdWx0cyB0byB0cnVlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZFNraW5zID0gdHJ1ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgaWYgdGhlIGxvYWRlciBzaG91bGQgbG9hZCBtb3JwaCB0YXJnZXRzLiBEZWZhdWx0cyB0byB0cnVlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1vcnBoVGFyZ2V0cyA9IHRydWU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGlmIHRoZSBsb2FkZXIgc2hvdWxkIGNvbXBpbGUgbWF0ZXJpYWxzIGJlZm9yZSByYWlzaW5nIHRoZSBzdWNjZXNzIGNhbGxiYWNrLiBEZWZhdWx0cyB0byBmYWxzZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvbXBpbGVNYXRlcmlhbHMgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgaWYgdGhlIGxvYWRlciBzaG91bGQgYWxzbyBjb21waWxlIG1hdGVyaWFscyB3aXRoIGNsaXAgcGxhbmVzLiBEZWZhdWx0cyB0byBmYWxzZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHVzZUNsaXBQbGFuZSA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBpZiB0aGUgbG9hZGVyIHNob3VsZCBjb21waWxlIHNoYWRvdyBnZW5lcmF0b3JzIGJlZm9yZSByYWlzaW5nIHRoZSBzdWNjZXNzIGNhbGxiYWNrLiBEZWZhdWx0cyB0byBmYWxzZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvbXBpbGVTaGFkb3dHZW5lcmF0b3JzID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGlmIHRoZSBBbHBoYSBibGVuZGVkIG1hdGVyaWFscyBhcmUgb25seSBhcHBsaWVkIGFzIGNvdmVyYWdlLlxyXG4gICAgICogSWYgZmFsc2UsIChkZWZhdWx0KSBUaGUgbHVtaW5hbmNlIG9mIGVhY2ggcGl4ZWwgd2lsbCByZWR1Y2UgaXRzIG9wYWNpdHkgdG8gc2ltdWxhdGUgdGhlIGJlaGF2aW91ciBvZiBtb3N0IHBoeXNpY2FsIG1hdGVyaWFscy5cclxuICAgICAqIElmIHRydWUsIG5vIGV4dHJhIGVmZmVjdHMgYXJlIGFwcGxpZWQgdG8gdHJhbnNwYXJlbnQgcGl4ZWxzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdHJhbnNwYXJlbmN5QXNDb3ZlcmFnZSA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBpZiB0aGUgbG9hZGVyIHNob3VsZCB1c2UgcmFuZ2UgcmVxdWVzdHMgd2hlbiBsb2FkIGJpbmFyeSBnbFRGIGZpbGVzIGZyb20gSFRUUC5cclxuICAgICAqIEVuYWJsaW5nIHdpbGwgZGlzYWJsZSBvZmZsaW5lIHN1cHBvcnQgYW5kIGdsVEYgdmFsaWRhdG9yLlxyXG4gICAgICogRGVmYXVsdHMgdG8gZmFsc2UuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB1c2VSYW5nZVJlcXVlc3RzID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGlmIHRoZSBsb2FkZXIgc2hvdWxkIGNyZWF0ZSBpbnN0YW5jZXMgd2hlbiBtdWx0aXBsZSBnbFRGIG5vZGVzIHBvaW50IHRvIHRoZSBzYW1lIGdsVEYgbWVzaC4gRGVmYXVsdHMgdG8gdHJ1ZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGNyZWF0ZUluc3RhbmNlcyA9IHRydWU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGlmIHRoZSBsb2FkZXIgc2hvdWxkIGFsd2F5cyBjb21wdXRlIHRoZSBib3VuZGluZyBib3hlcyBvZiBtZXNoZXMgYW5kIG5vdCB1c2UgdGhlIG1pbi9tYXggdmFsdWVzIGZyb20gdGhlIHBvc2l0aW9uIGFjY2Vzc29yLiBEZWZhdWx0cyB0byBmYWxzZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGFsd2F5c0NvbXB1dGVCb3VuZGluZ0JveCA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSWYgdHJ1ZSwgbG9hZCBhbGwgbWF0ZXJpYWxzIGRlZmluZWQgaW4gdGhlIGZpbGUsIGV2ZW4gaWYgbm90IHVzZWQgYnkgYW55IG1lc2guIERlZmF1bHRzIHRvIGZhbHNlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZEFsbE1hdGVyaWFscyA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSWYgdHJ1ZSwgbG9hZCBvbmx5IHRoZSBtYXRlcmlhbHMgZGVmaW5lZCBpbiB0aGUgZmlsZS4gRGVmYXVsdHMgdG8gZmFsc2UuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkT25seU1hdGVyaWFscyA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSWYgdHJ1ZSwgZG8gbm90IGxvYWQgYW55IG1hdGVyaWFscyBkZWZpbmVkIGluIHRoZSBmaWxlLiBEZWZhdWx0cyB0byBmYWxzZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHNraXBNYXRlcmlhbHMgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIElmIHRydWUsIGxvYWQgdGhlIGNvbG9yIChnYW1tYSBlbmNvZGVkKSB0ZXh0dXJlcyBpbnRvIHNSR0IgYnVmZmVycyAoaWYgc3VwcG9ydGVkIGJ5IHRoZSBHUFUpLCB3aGljaCB3aWxsIHlpZWxkIG1vcmUgYWNjdXJhdGUgcmVzdWx0cyB3aGVuIHNhbXBsaW5nIHRoZSB0ZXh0dXJlLiBEZWZhdWx0cyB0byB0cnVlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdXNlU1JHQkJ1ZmZlcnMgPSB0cnVlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV2hlbiBsb2FkaW5nIGdsVEYgYW5pbWF0aW9ucywgd2hpY2ggYXJlIGRlZmluZWQgaW4gc2Vjb25kcywgdGFyZ2V0IHRoZW0gdG8gdGhpcyBGUFMuIERlZmF1bHRzIHRvIDYwLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdGFyZ2V0RnBzID0gNjA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGlmIHRoZSBsb2FkZXIgc2hvdWxkIGFsd2F5cyBjb21wdXRlIHRoZSBuZWFyZXN0IGNvbW1vbiBhbmNlc3RvciBvZiB0aGUgc2tlbGV0b24gam9pbnRzIGluc3RlYWQgb2YgdXNpbmcgYHNraW4uc2tlbGV0b25gLiBEZWZhdWx0cyB0byBmYWxzZS5cclxuICAgICAqIFNldCB0aGlzIHRvIHRydWUgaWYgbG9hZGluZyBhc3NldHMgd2l0aCBpbnZhbGlkIGBza2luLnNrZWxldG9uYCB2YWx1ZXMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhbHdheXNDb21wdXRlU2tlbGV0b25Sb290Tm9kZSA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSWYgdHJ1ZSwgdGhlIGxvYWRlciB3aWxsIGRlcml2ZSB0aGUgbmFtZSBmb3IgQmFieWxvbiB0ZXh0dXJlcyBmcm9tIHRoZSBnbFRGIHRleHR1cmUgbmFtZSwgaW1hZ2UgbmFtZSwgb3IgaW1hZ2UgdXJsLiBEZWZhdWx0cyB0byBmYWxzZS5cclxuICAgICAqIE5vdGUgdGhhdCBpdCBpcyBwb3NzaWJsZSBmb3IgbXVsdGlwbGUgQmFieWxvbiB0ZXh0dXJlcyB0byBzaGFyZSB0aGUgc2FtZSBuYW1lIHdoZW4gdGhlIEJhYnlsb24gdGV4dHVyZXMgbG9hZCBmcm9tIHRoZSBzYW1lIGdsVEYgdGV4dHVyZSBvciBpbWFnZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHVzZUdsdGZUZXh0dXJlTmFtZXMgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZ1bmN0aW9uIGNhbGxlZCBiZWZvcmUgbG9hZGluZyBhIHVybCByZWZlcmVuY2VkIGJ5IHRoZSBhc3NldC5cclxuICAgICAqIEBwYXJhbSB1cmwgdXJsIHJlZmVyZW5jZWQgYnkgdGhlIGFzc2V0XHJcbiAgICAgKiBAcmV0dXJucyBBc3luYyB1cmwgdG8gbG9hZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcHJlcHJvY2Vzc1VybEFzeW5jID0gKHVybDogc3RyaW5nKSA9PiBQcm9taXNlLnJlc29sdmUodXJsKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgdGhlIG5vZGUgdG8gdXNlIGFzIHRoZSByb290IG9mIHRoZSBoaWVyYXJjaHkgd2hlbiBsb2FkaW5nIHRoZSBzY2VuZSAoZGVmYXVsdDogdW5kZWZpbmVkKS4gSWYgbm90IGRlZmluZWQsIGEgcm9vdCBub2RlIHdpbGwgYmUgYXV0b21hdGljYWxseSBjcmVhdGVkLlxyXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgbnVsbCBpZiB5b3UgZG9uJ3Qgd2FudCBhIHJvb3Qgbm9kZSB0byBiZSBjcmVhdGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY3VzdG9tUm9vdE5vZGU/OiBOdWxsYWJsZTxUcmFuc2Zvcm1Ob2RlPjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGxiYWNrIHJhaXNlZCB3aGVuIHRoZSBsb2FkZXIgY3JlYXRlcyBhIG1lc2ggYWZ0ZXIgcGFyc2luZyB0aGUgZ2xURiBwcm9wZXJ0aWVzIG9mIHRoZSBtZXNoLlxyXG4gICAgICogTm90ZSB0aGF0IHRoZSBjYWxsYmFjayBpcyBjYWxsZWQgYXMgc29vbiBhcyB0aGUgbWVzaCBvYmplY3QgaXMgY3JlYXRlZCwgbWVhbmluZyBzb21lIGRhdGEgbWF5IG5vdCBoYXZlIGJlZW4gc2V0dXAgeWV0IGZvciB0aGlzIG1lc2ggKHZlcnRleCBkYXRhLCBtb3JwaCB0YXJnZXRzLCBtYXRlcmlhbCwgLi4uKVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWJzdHJhY3Qgb25NZXNoTG9hZGVkPzogKChtZXNoOiBBYnN0cmFjdE1lc2gpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgcmFpc2VkIHdoZW4gdGhlIGxvYWRlciBjcmVhdGVzIGEgc2tpbiBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXMgb2YgdGhlIHNraW4gbm9kZS5cclxuICAgICAqIEBzZWUgaHR0cHM6Ly9kb2MuYmFieWxvbmpzLmNvbS9mZWF0dXJlcy9mZWF0dXJlc0RlZXBEaXZlL2ltcG9ydGVycy9nbFRGL2dsVEZTa2lubmluZyNpZ25vcmluZy10aGUtdHJhbnNmb3JtLW9mLXRoZS1za2lubmVkLW1lc2hcclxuICAgICAqL1xyXG4gICAgcHVibGljIGFic3RyYWN0IG9uU2tpbkxvYWRlZD86ICgobm9kZTogVHJhbnNmb3JtTm9kZSwgc2tpbm5lZE5vZGU6IFRyYW5zZm9ybU5vZGUpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgcmFpc2VkIHdoZW4gdGhlIGxvYWRlciBjcmVhdGVzIGEgdGV4dHVyZSBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXMgb2YgdGhlIHRleHR1cmUuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhYnN0cmFjdCBvblRleHR1cmVMb2FkZWQ/OiAoKHRleHR1cmU6IEJhc2VUZXh0dXJlKSA9PiB2b2lkKSB8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGxiYWNrIHJhaXNlZCB3aGVuIHRoZSBsb2FkZXIgY3JlYXRlcyBhIG1hdGVyaWFsIGFmdGVyIHBhcnNpbmcgdGhlIGdsVEYgcHJvcGVydGllcyBvZiB0aGUgbWF0ZXJpYWwuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhYnN0cmFjdCBvbk1hdGVyaWFsTG9hZGVkPzogKChtYXRlcmlhbDogTWF0ZXJpYWwpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgcmFpc2VkIHdoZW4gdGhlIGxvYWRlciBjcmVhdGVzIGEgY2FtZXJhIGFmdGVyIHBhcnNpbmcgdGhlIGdsVEYgcHJvcGVydGllcyBvZiB0aGUgY2FtZXJhLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWJzdHJhY3Qgb25DYW1lcmFMb2FkZWQ/OiAoKGNhbWVyYTogQ2FtZXJhKSA9PiB2b2lkKSB8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgZ2xURiBleHRlbnNpb25zLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZXh0ZW5zaW9uT3B0aW9uczoge1xyXG4gICAgICAgIC8vIE5PVEU6IFRoaXMgdHlwZSBpcyBkb2luZyB0d28gdGhpbmdzOlxyXG4gICAgICAgIC8vIDEuIEFkZGluZyBhbiBpbXBsaWNpdCAnZW5hYmxlZCcgcHJvcGVydHkgdG8gdGhlIG9wdGlvbnMgZm9yIGVhY2ggZXh0ZW5zaW9uLlxyXG4gICAgICAgIC8vIDIuIENyZWF0aW5nIGEgbWFwcGVkIHR5cGUgb2YgYWxsIHRoZSBvcHRpb25zIG9mIGFsbCB0aGUgZXh0ZW5zaW9ucyB0byBtYWtlIGl0IGp1c3QgbG9vayBsaWtlIGEgY29uc29saWRhdGVkIHBsYWluIG9iamVjdCBpbiBpbnRlbGxpc2Vuc2UgZm9yIHRoZSB1c2VyLlxyXG4gICAgICAgIFtFeHRlbnNpb24gaW4ga2V5b2YgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnNdPzoge1xyXG4gICAgICAgICAgICBbT3B0aW9uIGluIGtleW9mIERlZmF1bHRFeHRlbnNpb25PcHRpb25zPEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zW0V4dGVuc2lvbl0+XTogRGVmYXVsdEV4dGVuc2lvbk9wdGlvbnM8R0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnNbRXh0ZW5zaW9uXT5bT3B0aW9uXTtcclxuICAgICAgICB9O1xyXG4gICAgfSA9IHt9O1xyXG59XHJcblxyXG4vKipcclxuICogRmlsZSBsb2FkZXIgZm9yIGxvYWRpbmcgZ2xURiBmaWxlcyBpbnRvIGEgc2NlbmUuXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgR0xURkZpbGVMb2FkZXIgZXh0ZW5kcyBHTFRGTG9hZGVyT3B0aW9ucyBpbXBsZW1lbnRzIElEaXNwb3NhYmxlLCBJU2NlbmVMb2FkZXJQbHVnaW5Bc3luYywgSVNjZW5lTG9hZGVyUGx1Z2luRmFjdG9yeSB7XHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgc3RhdGljIF9DcmVhdGVHTFRGMUxvYWRlcjogKHBhcmVudDogR0xURkZpbGVMb2FkZXIpID0+IElHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgX0NyZWF0ZUdMVEYyTG9hZGVyOiAocGFyZW50OiBHTFRGRmlsZUxvYWRlcikgPT4gSUdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGdsVEYgZmlsZSBsb2FkZXIuXHJcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBUaGUgb3B0aW9ucyBmb3IgdGhlIGxvYWRlclxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9ucz86IFBhcnRpYWw8UmVhZG9ubHk8R0xURkxvYWRlck9wdGlvbnM+Pikge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdGhpcy5jb3B5RnJvbShvcHRpb25zKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgLy8gQmVnaW4gQ29tbW9uIG9wdGlvbnNcclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSYWlzZWQgd2hlbiB0aGUgYXNzZXQgaGFzIGJlZW4gcGFyc2VkXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvblBhcnNlZE9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZTxJR0xURkxvYWRlckRhdGE+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfb25QYXJzZWRPYnNlcnZlcjogTnVsbGFibGU8T2JzZXJ2ZXI8SUdMVEZMb2FkZXJEYXRhPj47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSYWlzZWQgd2hlbiB0aGUgYXNzZXQgaGFzIGJlZW4gcGFyc2VkXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgb25QYXJzZWQoY2FsbGJhY2s6ICgobG9hZGVyRGF0YTogSUdMVEZMb2FkZXJEYXRhKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9vblBhcnNlZE9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25QYXJzZWRPYnNlcnZhYmxlLnJlbW92ZSh0aGlzLl9vblBhcnNlZE9ic2VydmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX29uUGFyc2VkT2JzZXJ2ZXIgPSB0aGlzLm9uUGFyc2VkT2JzZXJ2YWJsZS5hZGQoY2FsbGJhY2spO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS1cclxuICAgIC8vIEVuZCBDb21tb24gb3B0aW9uc1xyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgLy8gQmVnaW4gVjEgb3B0aW9uc1xyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0IHRoaXMgcHJvcGVydHkgdG8gZmFsc2UgdG8gZGlzYWJsZSBpbmNyZW1lbnRhbCBsb2FkaW5nIHdoaWNoIGRlbGF5cyB0aGUgbG9hZGVyIGZyb20gY2FsbGluZyB0aGUgc3VjY2VzcyBjYWxsYmFjayB1bnRpbCBhZnRlciBsb2FkaW5nIHRoZSBtZXNoZXMgYW5kIHNoYWRlcnMuXHJcbiAgICAgKiBUZXh0dXJlcyBhbHdheXMgbG9hZHMgYXN5bmNocm9ub3VzbHkuIEZvciBleGFtcGxlLCB0aGUgc3VjY2VzcyBjYWxsYmFjayBjYW4gY29tcHV0ZSB0aGUgYm91bmRpbmcgaW5mb3JtYXRpb24gb2YgdGhlIGxvYWRlZCBtZXNoZXMgd2hlbiBpbmNyZW1lbnRhbCBsb2FkaW5nIGlzIGRpc2FibGVkLlxyXG4gICAgICogRGVmYXVsdHMgdG8gdHJ1ZS5cclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIEluY3JlbWVudGFsTG9hZGluZyA9IHRydWU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXQgdGhpcyBwcm9wZXJ0eSB0byB0cnVlIGluIG9yZGVyIHRvIHdvcmsgd2l0aCBob21vZ2VuZW91cyBjb29yZGluYXRlcywgYXZhaWxhYmxlIHdpdGggc29tZSBjb252ZXJ0ZXJzIGFuZCBleHBvcnRlcnMuXHJcbiAgICAgKiBEZWZhdWx0cyB0byBmYWxzZS4gU2VlIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0hvbW9nZW5lb3VzX2Nvb3JkaW5hdGVzLlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgSG9tb2dlbmVvdXNDb29yZGluYXRlcyA9IGZhbHNlO1xyXG5cclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tXHJcbiAgICAvLyBFbmQgVjEgb3B0aW9uc1xyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmFpc2VkIHdoZW4gdGhlIGxvYWRlciBjcmVhdGVzIGEgbWVzaCBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXMgb2YgdGhlIG1lc2guXHJcbiAgICAgKiBOb3RlIHRoYXQgdGhlIG9ic2VydmFibGUgaXMgcmFpc2VkIGFzIHNvb24gYXMgdGhlIG1lc2ggb2JqZWN0IGlzIGNyZWF0ZWQsIG1lYW5pbmcgc29tZSBkYXRhIG1heSBub3QgaGF2ZSBiZWVuIHNldHVwIHlldCBmb3IgdGhpcyBtZXNoICh2ZXJ0ZXggZGF0YSwgbW9ycGggdGFyZ2V0cywgbWF0ZXJpYWwsIC4uLilcclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG9uTWVzaExvYWRlZE9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZTxBYnN0cmFjdE1lc2g+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfb25NZXNoTG9hZGVkT2JzZXJ2ZXI6IE51bGxhYmxlPE9ic2VydmVyPEFic3RyYWN0TWVzaD4+O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgcmFpc2VkIHdoZW4gdGhlIGxvYWRlciBjcmVhdGVzIGEgbWVzaCBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXMgb2YgdGhlIG1lc2guXHJcbiAgICAgKiBOb3RlIHRoYXQgdGhlIGNhbGxiYWNrIGlzIGNhbGxlZCBhcyBzb29uIGFzIHRoZSBtZXNoIG9iamVjdCBpcyBjcmVhdGVkLCBtZWFuaW5nIHNvbWUgZGF0YSBtYXkgbm90IGhhdmUgYmVlbiBzZXR1cCB5ZXQgZm9yIHRoaXMgbWVzaCAodmVydGV4IGRhdGEsIG1vcnBoIHRhcmdldHMsIG1hdGVyaWFsLCAuLi4pXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgb25NZXNoTG9hZGVkKGNhbGxiYWNrOiAoKG1lc2g6IEFic3RyYWN0TWVzaCkgPT4gdm9pZCkgfCB1bmRlZmluZWQpIHtcclxuICAgICAgICBpZiAodGhpcy5fb25NZXNoTG9hZGVkT2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5vbk1lc2hMb2FkZWRPYnNlcnZhYmxlLnJlbW92ZSh0aGlzLl9vbk1lc2hMb2FkZWRPYnNlcnZlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjYWxsYmFjaykge1xyXG4gICAgICAgICAgICB0aGlzLl9vbk1lc2hMb2FkZWRPYnNlcnZlciA9IHRoaXMub25NZXNoTG9hZGVkT2JzZXJ2YWJsZS5hZGQoY2FsbGJhY2spO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmFpc2VkIHdoZW4gdGhlIGxvYWRlciBjcmVhdGVzIGEgc2tpbiBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXMgb2YgdGhlIHNraW4gbm9kZS5cclxuICAgICAqIEBzZWUgaHR0cHM6Ly9kb2MuYmFieWxvbmpzLmNvbS9mZWF0dXJlcy9mZWF0dXJlc0RlZXBEaXZlL2ltcG9ydGVycy9nbFRGL2dsVEZTa2lubmluZyNpZ25vcmluZy10aGUtdHJhbnNmb3JtLW9mLXRoZS1za2lubmVkLW1lc2hcclxuICAgICAqIEBwYXJhbSBub2RlIC0gdGhlIHRyYW5zZm9ybSBub2RlIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIG9yaWdpbmFsIGdsVEYgc2tpbiBub2RlIHVzZWQgZm9yIGFuaW1hdGlvbnNcclxuICAgICAqIEBwYXJhbSBza2lubmVkTm9kZSAtIHRoZSB0cmFuc2Zvcm0gbm9kZSB0aGF0IGlzIHRoZSBza2lubmVkIG1lc2ggaXRzZWxmIG9yIHRoZSBwYXJlbnQgb2YgdGhlIHNraW5uZWQgbWVzaGVzXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBvblNraW5Mb2FkZWRPYnNlcnZhYmxlID0gbmV3IE9ic2VydmFibGU8eyBub2RlOiBUcmFuc2Zvcm1Ob2RlOyBza2lubmVkTm9kZTogVHJhbnNmb3JtTm9kZSB9PigpO1xyXG5cclxuICAgIHByaXZhdGUgX29uU2tpbkxvYWRlZE9ic2VydmVyOiBOdWxsYWJsZTxPYnNlcnZlcjx7IG5vZGU6IFRyYW5zZm9ybU5vZGU7IHNraW5uZWROb2RlOiBUcmFuc2Zvcm1Ob2RlIH0+PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGxiYWNrIHJhaXNlZCB3aGVuIHRoZSBsb2FkZXIgY3JlYXRlcyBhIHNraW4gYWZ0ZXIgcGFyc2luZyB0aGUgZ2xURiBwcm9wZXJ0aWVzIG9mIHRoZSBza2luIG5vZGUuXHJcbiAgICAgKiBAc2VlIGh0dHBzOi8vZG9jLmJhYnlsb25qcy5jb20vZmVhdHVyZXMvZmVhdHVyZXNEZWVwRGl2ZS9pbXBvcnRlcnMvZ2xURi9nbFRGU2tpbm5pbmcjaWdub3JpbmctdGhlLXRyYW5zZm9ybS1vZi10aGUtc2tpbm5lZC1tZXNoXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgb25Ta2luTG9hZGVkKGNhbGxiYWNrOiAoKG5vZGU6IFRyYW5zZm9ybU5vZGUsIHNraW5uZWROb2RlOiBUcmFuc2Zvcm1Ob2RlKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9vblNraW5Mb2FkZWRPYnNlcnZlcikge1xyXG4gICAgICAgICAgICB0aGlzLm9uU2tpbkxvYWRlZE9ic2VydmFibGUucmVtb3ZlKHRoaXMuX29uU2tpbkxvYWRlZE9ic2VydmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX29uU2tpbkxvYWRlZE9ic2VydmVyID0gdGhpcy5vblNraW5Mb2FkZWRPYnNlcnZhYmxlLmFkZCgoZGF0YSkgPT4gY2FsbGJhY2soZGF0YS5ub2RlLCBkYXRhLnNraW5uZWROb2RlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2JzZXJ2YWJsZSByYWlzZWQgd2hlbiB0aGUgbG9hZGVyIGNyZWF0ZXMgYSB0ZXh0dXJlIGFmdGVyIHBhcnNpbmcgdGhlIGdsVEYgcHJvcGVydGllcyBvZiB0aGUgdGV4dHVyZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG9uVGV4dHVyZUxvYWRlZE9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZTxCYXNlVGV4dHVyZT4oKTtcclxuXHJcbiAgICBwcml2YXRlIF9vblRleHR1cmVMb2FkZWRPYnNlcnZlcjogTnVsbGFibGU8T2JzZXJ2ZXI8QmFzZVRleHR1cmU+PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGxiYWNrIHJhaXNlZCB3aGVuIHRoZSBsb2FkZXIgY3JlYXRlcyBhIHRleHR1cmUgYWZ0ZXIgcGFyc2luZyB0aGUgZ2xURiBwcm9wZXJ0aWVzIG9mIHRoZSB0ZXh0dXJlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0IG9uVGV4dHVyZUxvYWRlZChjYWxsYmFjazogKCh0ZXh0dXJlOiBCYXNlVGV4dHVyZSkgPT4gdm9pZCkgfCB1bmRlZmluZWQpIHtcclxuICAgICAgICBpZiAodGhpcy5fb25UZXh0dXJlTG9hZGVkT2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5vblRleHR1cmVMb2FkZWRPYnNlcnZhYmxlLnJlbW92ZSh0aGlzLl9vblRleHR1cmVMb2FkZWRPYnNlcnZlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjYWxsYmFjaykge1xyXG4gICAgICAgICAgICB0aGlzLl9vblRleHR1cmVMb2FkZWRPYnNlcnZlciA9IHRoaXMub25UZXh0dXJlTG9hZGVkT2JzZXJ2YWJsZS5hZGQoY2FsbGJhY2spO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmFpc2VkIHdoZW4gdGhlIGxvYWRlciBjcmVhdGVzIGEgbWF0ZXJpYWwgYWZ0ZXIgcGFyc2luZyB0aGUgZ2xURiBwcm9wZXJ0aWVzIG9mIHRoZSBtYXRlcmlhbC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG9uTWF0ZXJpYWxMb2FkZWRPYnNlcnZhYmxlID0gbmV3IE9ic2VydmFibGU8TWF0ZXJpYWw+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfb25NYXRlcmlhbExvYWRlZE9ic2VydmVyOiBOdWxsYWJsZTxPYnNlcnZlcjxNYXRlcmlhbD4+O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgcmFpc2VkIHdoZW4gdGhlIGxvYWRlciBjcmVhdGVzIGEgbWF0ZXJpYWwgYWZ0ZXIgcGFyc2luZyB0aGUgZ2xURiBwcm9wZXJ0aWVzIG9mIHRoZSBtYXRlcmlhbC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHNldCBvbk1hdGVyaWFsTG9hZGVkKGNhbGxiYWNrOiAoKG1hdGVyaWFsOiBNYXRlcmlhbCkgPT4gdm9pZCkgfCB1bmRlZmluZWQpIHtcclxuICAgICAgICBpZiAodGhpcy5fb25NYXRlcmlhbExvYWRlZE9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25NYXRlcmlhbExvYWRlZE9ic2VydmFibGUucmVtb3ZlKHRoaXMuX29uTWF0ZXJpYWxMb2FkZWRPYnNlcnZlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjYWxsYmFjaykge1xyXG4gICAgICAgICAgICB0aGlzLl9vbk1hdGVyaWFsTG9hZGVkT2JzZXJ2ZXIgPSB0aGlzLm9uTWF0ZXJpYWxMb2FkZWRPYnNlcnZhYmxlLmFkZChjYWxsYmFjayk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2JzZXJ2YWJsZSByYWlzZWQgd2hlbiB0aGUgbG9hZGVyIGNyZWF0ZXMgYSBjYW1lcmEgYWZ0ZXIgcGFyc2luZyB0aGUgZ2xURiBwcm9wZXJ0aWVzIG9mIHRoZSBjYW1lcmEuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBvbkNhbWVyYUxvYWRlZE9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZTxDYW1lcmE+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfb25DYW1lcmFMb2FkZWRPYnNlcnZlcjogTnVsbGFibGU8T2JzZXJ2ZXI8Q2FtZXJhPj47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayByYWlzZWQgd2hlbiB0aGUgbG9hZGVyIGNyZWF0ZXMgYSBjYW1lcmEgYWZ0ZXIgcGFyc2luZyB0aGUgZ2xURiBwcm9wZXJ0aWVzIG9mIHRoZSBjYW1lcmEuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgb25DYW1lcmFMb2FkZWQoY2FsbGJhY2s6ICgoY2FtZXJhOiBDYW1lcmEpID0+IHZvaWQpIHwgdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX29uQ2FtZXJhTG9hZGVkT2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5vbkNhbWVyYUxvYWRlZE9ic2VydmFibGUucmVtb3ZlKHRoaXMuX29uQ2FtZXJhTG9hZGVkT2JzZXJ2ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgdGhpcy5fb25DYW1lcmFMb2FkZWRPYnNlcnZlciA9IHRoaXMub25DYW1lcmFMb2FkZWRPYnNlcnZhYmxlLmFkZChjYWxsYmFjayk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2JzZXJ2YWJsZSByYWlzZWQgd2hlbiB0aGUgYXNzZXQgaXMgY29tcGxldGVseSBsb2FkZWQsIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgbG9hZGVyIGlzIGRpc3Bvc2VkLlxyXG4gICAgICogRm9yIGFzc2V0cyB3aXRoIExPRHMsIHJhaXNlZCB3aGVuIGFsbCBvZiB0aGUgTE9EcyBhcmUgY29tcGxldGUuXHJcbiAgICAgKiBGb3IgYXNzZXRzIHdpdGhvdXQgTE9EcywgcmFpc2VkIHdoZW4gdGhlIG1vZGVsIGlzIGNvbXBsZXRlLCBpbW1lZGlhdGVseSBhZnRlciB0aGUgbG9hZGVyIHJlc29sdmVzIHRoZSByZXR1cm5lZCBwcm9taXNlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgb25Db21wbGV0ZU9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZTx2b2lkPigpO1xyXG5cclxuICAgIHByaXZhdGUgX29uQ29tcGxldGVPYnNlcnZlcjogTnVsbGFibGU8T2JzZXJ2ZXI8dm9pZD4+O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgcmFpc2VkIHdoZW4gdGhlIGFzc2V0IGlzIGNvbXBsZXRlbHkgbG9hZGVkLCBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGxvYWRlciBpcyBkaXNwb3NlZC5cclxuICAgICAqIEZvciBhc3NldHMgd2l0aCBMT0RzLCByYWlzZWQgd2hlbiBhbGwgb2YgdGhlIExPRHMgYXJlIGNvbXBsZXRlLlxyXG4gICAgICogRm9yIGFzc2V0cyB3aXRob3V0IExPRHMsIHJhaXNlZCB3aGVuIHRoZSBtb2RlbCBpcyBjb21wbGV0ZSwgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIGxvYWRlciByZXNvbHZlcyB0aGUgcmV0dXJuZWQgcHJvbWlzZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHNldCBvbkNvbXBsZXRlKGNhbGxiYWNrOiAoKSA9PiB2b2lkKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX29uQ29tcGxldGVPYnNlcnZlcikge1xyXG4gICAgICAgICAgICB0aGlzLm9uQ29tcGxldGVPYnNlcnZhYmxlLnJlbW92ZSh0aGlzLl9vbkNvbXBsZXRlT2JzZXJ2ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9vbkNvbXBsZXRlT2JzZXJ2ZXIgPSB0aGlzLm9uQ29tcGxldGVPYnNlcnZhYmxlLmFkZChjYWxsYmFjayk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPYnNlcnZhYmxlIHJhaXNlZCB3aGVuIGFuIGVycm9yIG9jY3Vycy5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG9uRXJyb3JPYnNlcnZhYmxlID0gbmV3IE9ic2VydmFibGU8YW55PigpO1xyXG5cclxuICAgIHByaXZhdGUgX29uRXJyb3JPYnNlcnZlcjogTnVsbGFibGU8T2JzZXJ2ZXI8YW55Pj47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayByYWlzZWQgd2hlbiBhbiBlcnJvciBvY2N1cnMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgb25FcnJvcihjYWxsYmFjazogKHJlYXNvbjogYW55KSA9PiB2b2lkKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX29uRXJyb3JPYnNlcnZlcikge1xyXG4gICAgICAgICAgICB0aGlzLm9uRXJyb3JPYnNlcnZhYmxlLnJlbW92ZSh0aGlzLl9vbkVycm9yT2JzZXJ2ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9vbkVycm9yT2JzZXJ2ZXIgPSB0aGlzLm9uRXJyb3JPYnNlcnZhYmxlLmFkZChjYWxsYmFjayk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPYnNlcnZhYmxlIHJhaXNlZCBhZnRlciB0aGUgbG9hZGVyIGlzIGRpc3Bvc2VkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgb25EaXNwb3NlT2JzZXJ2YWJsZSA9IG5ldyBPYnNlcnZhYmxlPHZvaWQ+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfb25EaXNwb3NlT2JzZXJ2ZXI6IE51bGxhYmxlPE9ic2VydmVyPHZvaWQ+PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGxiYWNrIHJhaXNlZCBhZnRlciB0aGUgbG9hZGVyIGlzIGRpc3Bvc2VkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0IG9uRGlzcG9zZShjYWxsYmFjazogKCkgPT4gdm9pZCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9vbkRpc3Bvc2VPYnNlcnZlcikge1xyXG4gICAgICAgICAgICB0aGlzLm9uRGlzcG9zZU9ic2VydmFibGUucmVtb3ZlKHRoaXMuX29uRGlzcG9zZU9ic2VydmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fb25EaXNwb3NlT2JzZXJ2ZXIgPSB0aGlzLm9uRGlzcG9zZU9ic2VydmFibGUuYWRkKGNhbGxiYWNrKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmFpc2VkIGFmdGVyIGEgbG9hZGVyIGV4dGVuc2lvbiBpcyBjcmVhdGVkLlxyXG4gICAgICogU2V0IGFkZGl0aW9uYWwgb3B0aW9ucyBmb3IgYSBsb2FkZXIgZXh0ZW5zaW9uIGluIHRoaXMgZXZlbnQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBvbkV4dGVuc2lvbkxvYWRlZE9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZTxJR0xURkxvYWRlckV4dGVuc2lvbj4oKTtcclxuXHJcbiAgICBwcml2YXRlIF9vbkV4dGVuc2lvbkxvYWRlZE9ic2VydmVyOiBOdWxsYWJsZTxPYnNlcnZlcjxJR0xURkxvYWRlckV4dGVuc2lvbj4+O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgcmFpc2VkIGFmdGVyIGEgbG9hZGVyIGV4dGVuc2lvbiBpcyBjcmVhdGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0IG9uRXh0ZW5zaW9uTG9hZGVkKGNhbGxiYWNrOiAoZXh0ZW5zaW9uOiBJR0xURkxvYWRlckV4dGVuc2lvbikgPT4gdm9pZCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9vbkV4dGVuc2lvbkxvYWRlZE9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25FeHRlbnNpb25Mb2FkZWRPYnNlcnZhYmxlLnJlbW92ZSh0aGlzLl9vbkV4dGVuc2lvbkxvYWRlZE9ic2VydmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fb25FeHRlbnNpb25Mb2FkZWRPYnNlcnZlciA9IHRoaXMub25FeHRlbnNpb25Mb2FkZWRPYnNlcnZhYmxlLmFkZChjYWxsYmFjayk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGlmIHRoZSBsb2FkZXIgbG9nZ2luZyBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IGxvZ2dpbmdFbmFibGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9sb2dnaW5nRW5hYmxlZDtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc2V0IGxvZ2dpbmdFbmFibGVkKHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2xvZ2dpbmdFbmFibGVkID09PSB2YWx1ZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9sb2dnaW5nRW5hYmxlZCA9IHZhbHVlO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5fbG9nZ2luZ0VuYWJsZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5fbG9nID0gdGhpcy5fbG9nRW5hYmxlZDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9sb2cgPSB0aGlzLl9sb2dEaXNhYmxlZDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGlmIHRoZSBsb2FkZXIgc2hvdWxkIGNhcHR1cmUgcGVyZm9ybWFuY2UgY291bnRlcnMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXQgY2FwdHVyZVBlcmZvcm1hbmNlQ291bnRlcnMoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcHR1cmVQZXJmb3JtYW5jZUNvdW50ZXJzO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzZXQgY2FwdHVyZVBlcmZvcm1hbmNlQ291bnRlcnModmFsdWU6IGJvb2xlYW4pIHtcclxuICAgICAgICBpZiAodGhpcy5fY2FwdHVyZVBlcmZvcm1hbmNlQ291bnRlcnMgPT09IHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2NhcHR1cmVQZXJmb3JtYW5jZUNvdW50ZXJzID0gdmFsdWU7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9jYXB0dXJlUGVyZm9ybWFuY2VDb3VudGVycykge1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydFBlcmZvcm1hbmNlQ291bnRlciA9IHRoaXMuX3N0YXJ0UGVyZm9ybWFuY2VDb3VudGVyRW5hYmxlZDtcclxuICAgICAgICAgICAgdGhpcy5fZW5kUGVyZm9ybWFuY2VDb3VudGVyID0gdGhpcy5fZW5kUGVyZm9ybWFuY2VDb3VudGVyRW5hYmxlZDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydFBlcmZvcm1hbmNlQ291bnRlciA9IHRoaXMuX3N0YXJ0UGVyZm9ybWFuY2VDb3VudGVyRGlzYWJsZWQ7XHJcbiAgICAgICAgICAgIHRoaXMuX2VuZFBlcmZvcm1hbmNlQ291bnRlciA9IHRoaXMuX2VuZFBlcmZvcm1hbmNlQ291bnRlckRpc2FibGVkO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgaWYgdGhlIGxvYWRlciBzaG91bGQgdmFsaWRhdGUgdGhlIGFzc2V0LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdmFsaWRhdGUgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmFpc2VkIGFmdGVyIHZhbGlkYXRpb24gd2hlbiB2YWxpZGF0ZSBpcyBzZXQgdG8gdHJ1ZS4gVGhlIGV2ZW50IGRhdGEgaXMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG9uVmFsaWRhdGVkT2JzZXJ2YWJsZSA9IG5ldyBPYnNlcnZhYmxlPEdMVEYyLklHTFRGVmFsaWRhdGlvblJlc3VsdHM+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfb25WYWxpZGF0ZWRPYnNlcnZlcjogTnVsbGFibGU8T2JzZXJ2ZXI8R0xURjIuSUdMVEZWYWxpZGF0aW9uUmVzdWx0cz4+O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgcmFpc2VkIGFmdGVyIGEgbG9hZGVyIGV4dGVuc2lvbiBpcyBjcmVhdGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0IG9uVmFsaWRhdGVkKGNhbGxiYWNrOiAocmVzdWx0czogR0xURjIuSUdMVEZWYWxpZGF0aW9uUmVzdWx0cykgPT4gdm9pZCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9vblZhbGlkYXRlZE9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25WYWxpZGF0ZWRPYnNlcnZhYmxlLnJlbW92ZSh0aGlzLl9vblZhbGlkYXRlZE9ic2VydmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fb25WYWxpZGF0ZWRPYnNlcnZlciA9IHRoaXMub25WYWxpZGF0ZWRPYnNlcnZhYmxlLmFkZChjYWxsYmFjayk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBOdWxsYWJsZTxJR0xURkxvYWRlcj4gPSBudWxsO1xyXG4gICAgcHJpdmF0ZSBfc3RhdGU6IE51bGxhYmxlPEdMVEZMb2FkZXJTdGF0ZT4gPSBudWxsO1xyXG4gICAgcHJpdmF0ZSBfcHJvZ3Jlc3NDYWxsYmFjaz86IChldmVudDogSVNjZW5lTG9hZGVyUHJvZ3Jlc3NFdmVudCkgPT4gdm9pZDtcclxuICAgIHByaXZhdGUgX3JlcXVlc3RzID0gbmV3IEFycmF5PElGaWxlUmVxdWVzdEluZm8+KCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBOYW1lIG9mIHRoZSBsb2FkZXIgKFwiZ2x0ZlwiKVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IEdMVEZGaWxlTG9hZGVyTWV0YWRhdGEubmFtZTtcclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgZXh0ZW5zaW9ucyA9IEdMVEZGaWxlTG9hZGVyTWV0YWRhdGEuZXh0ZW5zaW9ucztcclxuXHJcbiAgICAvKipcclxuICAgICAqIERpc3Bvc2VzIHRoZSBsb2FkZXIsIHJlbGVhc2VzIHJlc291cmNlcyBkdXJpbmcgbG9hZCwgYW5kIGNhbmNlbHMgYW55IG91dHN0YW5kaW5nIHJlcXVlc3RzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpOiB2b2lkIHtcclxuICAgICAgICBpZiAodGhpcy5fbG9hZGVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlciA9IG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IHJlcXVlc3Qgb2YgdGhpcy5fcmVxdWVzdHMpIHtcclxuICAgICAgICAgICAgcmVxdWVzdC5hYm9ydCgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fcmVxdWVzdHMubGVuZ3RoID0gMDtcclxuXHJcbiAgICAgICAgZGVsZXRlIHRoaXMuX3Byb2dyZXNzQ2FsbGJhY2s7XHJcblxyXG4gICAgICAgIHRoaXMucHJlcHJvY2Vzc1VybEFzeW5jID0gKHVybCkgPT4gUHJvbWlzZS5yZXNvbHZlKHVybCk7XHJcblxyXG4gICAgICAgIHRoaXMub25NZXNoTG9hZGVkT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG4gICAgICAgIHRoaXMub25Ta2luTG9hZGVkT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG4gICAgICAgIHRoaXMub25UZXh0dXJlTG9hZGVkT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG4gICAgICAgIHRoaXMub25NYXRlcmlhbExvYWRlZE9ic2VydmFibGUuY2xlYXIoKTtcclxuICAgICAgICB0aGlzLm9uQ2FtZXJhTG9hZGVkT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG4gICAgICAgIHRoaXMub25Db21wbGV0ZU9ic2VydmFibGUuY2xlYXIoKTtcclxuICAgICAgICB0aGlzLm9uRXh0ZW5zaW9uTG9hZGVkT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG5cclxuICAgICAgICB0aGlzLm9uRGlzcG9zZU9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKHVuZGVmaW5lZCk7XHJcbiAgICAgICAgdGhpcy5vbkRpc3Bvc2VPYnNlcnZhYmxlLmNsZWFyKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRGaWxlKFxyXG4gICAgICAgIHNjZW5lOiBTY2VuZSxcclxuICAgICAgICBmaWxlT3JVcmw6IEZpbGUgfCBzdHJpbmcgfCBBcnJheUJ1ZmZlclZpZXcsXHJcbiAgICAgICAgcm9vdFVybDogc3RyaW5nLFxyXG4gICAgICAgIG9uU3VjY2VzczogKGRhdGE6IHVua25vd24sIHJlc3BvbnNlVVJMPzogc3RyaW5nKSA9PiB2b2lkLFxyXG4gICAgICAgIG9uUHJvZ3Jlc3M/OiAoZXY6IElTY2VuZUxvYWRlclByb2dyZXNzRXZlbnQpID0+IHZvaWQsXHJcbiAgICAgICAgdXNlQXJyYXlCdWZmZXI/OiBib29sZWFuLFxyXG4gICAgICAgIG9uRXJyb3I/OiAocmVxdWVzdD86IFdlYlJlcXVlc3QsIGV4Y2VwdGlvbj86IExvYWRGaWxlRXJyb3IpID0+IHZvaWQsXHJcbiAgICAgICAgbmFtZT86IHN0cmluZ1xyXG4gICAgKTogTnVsbGFibGU8SUZpbGVSZXF1ZXN0PiB7XHJcbiAgICAgICAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhmaWxlT3JVcmwpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRCaW5hcnkoc2NlbmUsIGZpbGVPclVybCBhcyBBcnJheUJ1ZmZlclZpZXcsIHJvb3RVcmwsIG9uU3VjY2Vzcywgb25FcnJvciwgbmFtZSk7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fcHJvZ3Jlc3NDYWxsYmFjayA9IG9uUHJvZ3Jlc3M7XHJcblxyXG4gICAgICAgIGNvbnN0IGZpbGVOYW1lID0gKGZpbGVPclVybCBhcyBGaWxlKS5uYW1lIHx8IFRvb2xzLkdldEZpbGVuYW1lKGZpbGVPclVybCBhcyBzdHJpbmcpO1xyXG5cclxuICAgICAgICBpZiAodXNlQXJyYXlCdWZmZXIpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMudXNlUmFuZ2VSZXF1ZXN0cykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudmFsaWRhdGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuV2FybihcImdsVEYgdmFsaWRhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHdoZW4gcmFuZ2UgcmVxdWVzdHMgYXJlIGVuYWJsZWRcIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZVJlcXVlc3Q6IElGaWxlUmVxdWVzdCA9IHtcclxuICAgICAgICAgICAgICAgICAgICBhYm9ydDogKCkgPT4ge30sXHJcbiAgICAgICAgICAgICAgICAgICAgb25Db21wbGV0ZU9ic2VydmFibGU6IG5ldyBPYnNlcnZhYmxlPElGaWxlUmVxdWVzdD4oKSxcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YUJ1ZmZlciA9IHtcclxuICAgICAgICAgICAgICAgICAgICByZWFkQXN5bmM6IChieXRlT2Zmc2V0OiBudW1iZXIsIGJ5dGVMZW5ndGg6IG51bWJlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8QXJyYXlCdWZmZXJWaWV3PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkRmlsZShcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2VuZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlT3JVcmwgYXMgRmlsZSB8IHN0cmluZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBVaW50OEFycmF5KGRhdGEgYXMgQXJyYXlCdWZmZXIpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAod2ViUmVxdWVzdCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWJSZXF1ZXN0LnNldFJlcXVlc3RIZWFkZXIoXCJSYW5nZVwiLCBgYnl0ZXM9JHtieXRlT2Zmc2V0fS0ke2J5dGVPZmZzZXQgKyBieXRlTGVuZ3RoIC0gMX1gKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIGJ5dGVMZW5ndGg6IDAsXHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX3VucGFja0JpbmFyeUFzeW5jKG5ldyBEYXRhUmVhZGVyKGRhdGFCdWZmZXIpKS50aGVuKFxyXG4gICAgICAgICAgICAgICAgICAgIChsb2FkZXJEYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVSZXF1ZXN0Lm9uQ29tcGxldGVPYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyhmaWxlUmVxdWVzdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uU3VjY2Vzcyhsb2FkZXJEYXRhKTtcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIG9uRXJyb3IgPyAoZXJyb3IpID0+IG9uRXJyb3IodW5kZWZpbmVkLCBlcnJvcikgOiB1bmRlZmluZWRcclxuICAgICAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVSZXF1ZXN0O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZEZpbGUoXHJcbiAgICAgICAgICAgICAgICBzY2VuZSxcclxuICAgICAgICAgICAgICAgIGZpbGVPclVybCBhcyBGaWxlIHwgc3RyaW5nLFxyXG4gICAgICAgICAgICAgICAgKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWxpZGF0ZShzY2VuZSwgbmV3IFVpbnQ4QXJyYXkoZGF0YSBhcyBBcnJheUJ1ZmZlciwgMCwgKGRhdGEgYXMgQXJyYXlCdWZmZXIpLmJ5dGVMZW5ndGgpLCByb290VXJsLCBmaWxlTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdW5wYWNrQmluYXJ5QXN5bmMoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBEYXRhUmVhZGVyKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRBc3luYzogKGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpID0+IHJlYWRBc3luYyhkYXRhIGFzIEFycmF5QnVmZmVyLCBieXRlT2Zmc2V0LCBieXRlTGVuZ3RoKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVMZW5ndGg6IChkYXRhIGFzIEFycmF5QnVmZmVyKS5ieXRlTGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgICkudGhlbihcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGxvYWRlckRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uU3VjY2Vzcyhsb2FkZXJEYXRhKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgb25FcnJvciA/IChlcnJvcikgPT4gb25FcnJvcih1bmRlZmluZWQsIGVycm9yKSA6IHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgdHJ1ZSxcclxuICAgICAgICAgICAgICAgIG9uRXJyb3JcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZEZpbGUoXHJcbiAgICAgICAgICAgICAgICBzY2VuZSxcclxuICAgICAgICAgICAgICAgIGZpbGVPclVybCxcclxuICAgICAgICAgICAgICAgIChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsaWRhdGUoc2NlbmUsIGRhdGEgYXMgc3RyaW5nLCByb290VXJsLCBmaWxlTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uU3VjY2Vzcyh7IGpzb246IHRoaXMuX3BhcnNlSnNvbihkYXRhIGFzIHN0cmluZykgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbkVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkVycm9yKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBvbkVycm9yXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRCaW5hcnkoXHJcbiAgICAgICAgc2NlbmU6IFNjZW5lLFxyXG4gICAgICAgIGRhdGE6IEFycmF5QnVmZmVyVmlldyxcclxuICAgICAgICByb290VXJsOiBzdHJpbmcsXHJcbiAgICAgICAgb25TdWNjZXNzOiAoZGF0YTogdW5rbm93biwgcmVzcG9uc2VVUkw/OiBzdHJpbmcpID0+IHZvaWQsXHJcbiAgICAgICAgb25FcnJvcj86IChyZXF1ZXN0PzogV2ViUmVxdWVzdCwgZXhjZXB0aW9uPzogTG9hZEZpbGVFcnJvcikgPT4gdm9pZCxcclxuICAgICAgICBmaWxlTmFtZT86IHN0cmluZ1xyXG4gICAgKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fdmFsaWRhdGUoc2NlbmUsIG5ldyBVaW50OEFycmF5KGRhdGEuYnVmZmVyLCBkYXRhLmJ5dGVPZmZzZXQsIGRhdGEuYnl0ZUxlbmd0aCksIHJvb3RVcmwsIGZpbGVOYW1lKTtcclxuICAgICAgICB0aGlzLl91bnBhY2tCaW5hcnlBc3luYyhcclxuICAgICAgICAgICAgbmV3IERhdGFSZWFkZXIoe1xyXG4gICAgICAgICAgICAgICAgcmVhZEFzeW5jOiAoYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCkgPT4gcmVhZFZpZXdBc3luYyhkYXRhLCBieXRlT2Zmc2V0LCBieXRlTGVuZ3RoKSxcclxuICAgICAgICAgICAgICAgIGJ5dGVMZW5ndGg6IGRhdGEuYnl0ZUxlbmd0aCxcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICApLnRoZW4oXHJcbiAgICAgICAgICAgIChsb2FkZXJEYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBvblN1Y2Nlc3MobG9hZGVyRGF0YSk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIG9uRXJyb3IgPyAoZXJyb3IpID0+IG9uRXJyb3IodW5kZWZpbmVkLCBlcnJvcikgOiB1bmRlZmluZWRcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBpbXBvcnRNZXNoQXN5bmMoXHJcbiAgICAgICAgbWVzaGVzTmFtZXM6IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdIHwgbnVsbCB8IHVuZGVmaW5lZCxcclxuICAgICAgICBzY2VuZTogU2NlbmUsXHJcbiAgICAgICAgZGF0YTogSUdMVEZMb2FkZXJEYXRhLFxyXG4gICAgICAgIHJvb3RVcmw6IHN0cmluZyxcclxuICAgICAgICBvblByb2dyZXNzPzogKGV2ZW50OiBJU2NlbmVMb2FkZXJQcm9ncmVzc0V2ZW50KSA9PiB2b2lkLFxyXG4gICAgICAgIGZpbGVOYW1lPzogc3RyaW5nXHJcbiAgICApOiBQcm9taXNlPElTY2VuZUxvYWRlckFzeW5jUmVzdWx0PiB7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLm9uUGFyc2VkT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMoZGF0YSk7XHJcbiAgICAgICAgICAgIHRoaXMub25QYXJzZWRPYnNlcnZhYmxlLmNsZWFyKCk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9sb2coYExvYWRpbmcgJHtmaWxlTmFtZSB8fCBcIlwifWApO1xyXG4gICAgICAgICAgICB0aGlzLl9sb2FkZXIgPSB0aGlzLl9nZXRMb2FkZXIoZGF0YSk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIuaW1wb3J0TWVzaEFzeW5jKG1lc2hlc05hbWVzLCBzY2VuZSwgbnVsbCwgZGF0YSwgcm9vdFVybCwgb25Qcm9ncmVzcywgZmlsZU5hbWUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkQXN5bmMoc2NlbmU6IFNjZW5lLCBkYXRhOiBJR0xURkxvYWRlckRhdGEsIHJvb3RVcmw6IHN0cmluZywgb25Qcm9ncmVzcz86IChldmVudDogSVNjZW5lTG9hZGVyUHJvZ3Jlc3NFdmVudCkgPT4gdm9pZCwgZmlsZU5hbWU/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMub25QYXJzZWRPYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyhkYXRhKTtcclxuICAgICAgICAgICAgdGhpcy5vblBhcnNlZE9ic2VydmFibGUuY2xlYXIoKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2xvZyhgTG9hZGluZyAke2ZpbGVOYW1lIHx8IFwiXCJ9YCk7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlciA9IHRoaXMuX2dldExvYWRlcihkYXRhKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRlci5sb2FkQXN5bmMoc2NlbmUsIGRhdGEsIHJvb3RVcmwsIG9uUHJvZ3Jlc3MsIGZpbGVOYW1lKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZEFzc2V0Q29udGFpbmVyQXN5bmMoXHJcbiAgICAgICAgc2NlbmU6IFNjZW5lLFxyXG4gICAgICAgIGRhdGE6IElHTFRGTG9hZGVyRGF0YSxcclxuICAgICAgICByb290VXJsOiBzdHJpbmcsXHJcbiAgICAgICAgb25Qcm9ncmVzcz86IChldmVudDogSVNjZW5lTG9hZGVyUHJvZ3Jlc3NFdmVudCkgPT4gdm9pZCxcclxuICAgICAgICBmaWxlTmFtZT86IHN0cmluZ1xyXG4gICAgKTogUHJvbWlzZTxBc3NldENvbnRhaW5lcj4ge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5vblBhcnNlZE9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKGRhdGEpO1xyXG4gICAgICAgICAgICB0aGlzLm9uUGFyc2VkT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fbG9nKGBMb2FkaW5nICR7ZmlsZU5hbWUgfHwgXCJcIn1gKTtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyID0gdGhpcy5fZ2V0TG9hZGVyKGRhdGEpO1xyXG5cclxuICAgICAgICAgICAgLy8gUHJlcGFyZSB0aGUgYXNzZXQgY29udGFpbmVyLlxyXG4gICAgICAgICAgICBjb25zdCBjb250YWluZXIgPSBuZXcgQXNzZXRDb250YWluZXIoc2NlbmUpO1xyXG5cclxuICAgICAgICAgICAgLy8gR2V0IG1hdGVyaWFscy90ZXh0dXJlcyB3aGVuIGxvYWRpbmcgdG8gYWRkIHRvIGNvbnRhaW5lclxyXG4gICAgICAgICAgICBjb25zdCBtYXRlcmlhbHM6IEFycmF5PE1hdGVyaWFsPiA9IFtdO1xyXG4gICAgICAgICAgICB0aGlzLm9uTWF0ZXJpYWxMb2FkZWRPYnNlcnZhYmxlLmFkZCgobWF0ZXJpYWwpID0+IHtcclxuICAgICAgICAgICAgICAgIG1hdGVyaWFscy5wdXNoKG1hdGVyaWFsKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIGNvbnN0IHRleHR1cmVzOiBBcnJheTxCYXNlVGV4dHVyZT4gPSBbXTtcclxuICAgICAgICAgICAgdGhpcy5vblRleHR1cmVMb2FkZWRPYnNlcnZhYmxlLmFkZCgodGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGV4dHVyZXMucHVzaCh0ZXh0dXJlKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIGNvbnN0IGNhbWVyYXM6IEFycmF5PENhbWVyYT4gPSBbXTtcclxuICAgICAgICAgICAgdGhpcy5vbkNhbWVyYUxvYWRlZE9ic2VydmFibGUuYWRkKChjYW1lcmEpID0+IHtcclxuICAgICAgICAgICAgICAgIGNhbWVyYXMucHVzaChjYW1lcmEpO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IG1vcnBoVGFyZ2V0TWFuYWdlcnM6IEFycmF5PE1vcnBoVGFyZ2V0TWFuYWdlcj4gPSBbXTtcclxuICAgICAgICAgICAgdGhpcy5vbk1lc2hMb2FkZWRPYnNlcnZhYmxlLmFkZCgobWVzaCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKG1lc2gubW9ycGhUYXJnZXRNYW5hZ2VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbW9ycGhUYXJnZXRNYW5hZ2Vycy5wdXNoKG1lc2gubW9ycGhUYXJnZXRNYW5hZ2VyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGVyLmltcG9ydE1lc2hBc3luYyhudWxsLCBzY2VuZSwgY29udGFpbmVyLCBkYXRhLCByb290VXJsLCBvblByb2dyZXNzLCBmaWxlTmFtZSkudGhlbigocmVzdWx0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShjb250YWluZXIuZ2VvbWV0cmllcywgcmVzdWx0Lmdlb21ldHJpZXMpO1xyXG4gICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoY29udGFpbmVyLm1lc2hlcywgcmVzdWx0Lm1lc2hlcyk7XHJcbiAgICAgICAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShjb250YWluZXIucGFydGljbGVTeXN0ZW1zLCByZXN1bHQucGFydGljbGVTeXN0ZW1zKTtcclxuICAgICAgICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGNvbnRhaW5lci5za2VsZXRvbnMsIHJlc3VsdC5za2VsZXRvbnMpO1xyXG4gICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoY29udGFpbmVyLmFuaW1hdGlvbkdyb3VwcywgcmVzdWx0LmFuaW1hdGlvbkdyb3Vwcyk7XHJcbiAgICAgICAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShjb250YWluZXIubWF0ZXJpYWxzLCBtYXRlcmlhbHMpO1xyXG4gICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoY29udGFpbmVyLnRleHR1cmVzLCB0ZXh0dXJlcyk7XHJcbiAgICAgICAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShjb250YWluZXIubGlnaHRzLCByZXN1bHQubGlnaHRzKTtcclxuICAgICAgICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGNvbnRhaW5lci50cmFuc2Zvcm1Ob2RlcywgcmVzdWx0LnRyYW5zZm9ybU5vZGVzKTtcclxuICAgICAgICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGNvbnRhaW5lci5jYW1lcmFzLCBjYW1lcmFzKTtcclxuICAgICAgICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGNvbnRhaW5lci5tb3JwaFRhcmdldE1hbmFnZXJzLCBtb3JwaFRhcmdldE1hbmFnZXJzKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjb250YWluZXI7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjYW5EaXJlY3RMb2FkKGRhdGE6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGRmlsZUxvYWRlck1ldGFkYXRhLmNhbkRpcmVjdExvYWQoZGF0YSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGRpcmVjdExvYWQoc2NlbmU6IFNjZW5lLCBkYXRhOiBzdHJpbmcpOiBQcm9taXNlPE9iamVjdD4ge1xyXG4gICAgICAgIGlmIChcclxuICAgICAgICAgICAgZGF0YS5zdGFydHNXaXRoKFwiYmFzZTY0LFwiICsgR0xURk1hZ2ljQmFzZTY0RW5jb2RlZCkgfHwgLy8gdGhpcyBpcyB0ZWNobmljYWxseSBpbmNvcnJlY3QsIGJ1dCB3aWxsIGNvbnRpbnVlIHRvIHN1cHBvcnQgZm9yIGJhY2tjb21wYXQuXHJcbiAgICAgICAgICAgIGRhdGEuc3RhcnRzV2l0aChcIjtiYXNlNjQsXCIgKyBHTFRGTWFnaWNCYXNlNjRFbmNvZGVkKSB8fFxyXG4gICAgICAgICAgICBkYXRhLnN0YXJ0c1dpdGgoXCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW07YmFzZTY0LFwiICsgR0xURk1hZ2ljQmFzZTY0RW5jb2RlZCkgfHxcclxuICAgICAgICAgICAgZGF0YS5zdGFydHNXaXRoKFwibW9kZWwvZ2x0Zi1iaW5hcnk7YmFzZTY0LFwiICsgR0xURk1hZ2ljQmFzZTY0RW5jb2RlZClcclxuICAgICAgICApIHtcclxuICAgICAgICAgICAgY29uc3QgYXJyYXlCdWZmZXIgPSBEZWNvZGVCYXNlNjRVcmxUb0JpbmFyeShkYXRhKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRlKHNjZW5lLCBuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlciwgMCwgYXJyYXlCdWZmZXIuYnl0ZUxlbmd0aCkpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdW5wYWNrQmluYXJ5QXN5bmMoXHJcbiAgICAgICAgICAgICAgICBuZXcgRGF0YVJlYWRlcih7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVhZEFzeW5jOiAoYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCkgPT4gcmVhZEFzeW5jKGFycmF5QnVmZmVyLCBieXRlT2Zmc2V0LCBieXRlTGVuZ3RoKSxcclxuICAgICAgICAgICAgICAgICAgICBieXRlTGVuZ3RoOiBhcnJheUJ1ZmZlci5ieXRlTGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3ZhbGlkYXRlKHNjZW5lLCBkYXRhKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHsganNvbjogdGhpcy5fcGFyc2VKc29uKGRhdGEpIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGNhbGxiYWNrIHRoYXQgYWxsb3dzIGN1c3RvbSBoYW5kbGluZyBvZiB0aGUgcm9vdCB1cmwgYmFzZWQgb24gdGhlIHJlc3BvbnNlIHVybC5cclxuICAgICAqIEBwYXJhbSByb290VXJsIHRoZSBvcmlnaW5hbCByb290IHVybFxyXG4gICAgICogQHBhcmFtIHJlc3BvbnNlVVJMIHRoZSByZXNwb25zZSB1cmwgaWYgYXZhaWxhYmxlXHJcbiAgICAgKiBAcmV0dXJucyB0aGUgbmV3IHJvb3QgdXJsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZXdyaXRlUm9vdFVSTD8ocm9vdFVybDogc3RyaW5nLCByZXNwb25zZVVSTD86IHN0cmluZyk6IHN0cmluZztcclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgY3JlYXRlUGx1Z2luKG9wdGlvbnM6IFNjZW5lTG9hZGVyUGx1Z2luT3B0aW9ucyk6IElTY2VuZUxvYWRlclBsdWdpbkFzeW5jIHtcclxuICAgICAgICByZXR1cm4gbmV3IEdMVEZGaWxlTG9hZGVyKG9wdGlvbnNbR0xURkZpbGVMb2FkZXJNZXRhZGF0YS5uYW1lXSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbG9hZGVyIHN0YXRlIG9yIG51bGwgaWYgdGhlIGxvYWRlciBpcyBub3QgYWN0aXZlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IGxvYWRlclN0YXRlKCk6IE51bGxhYmxlPEdMVEZMb2FkZXJTdGF0ZT4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmFpc2VkIHdoZW4gdGhlIGxvYWRlciBzdGF0ZSBjaGFuZ2VzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25Mb2FkZXJTdGF0ZUNoYW5nZWRPYnNlcnZhYmxlID0gbmV3IE9ic2VydmFibGU8TnVsbGFibGU8R0xURkxvYWRlclN0YXRlPj4oKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgYXNzZXQgaXMgY29tcGxldGVseSBsb2FkZWQuXHJcbiAgICAgKiBAcmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBhc3NldCBpcyBjb21wbGV0ZWx5IGxvYWRlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHdoZW5Db21wbGV0ZUFzeW5jKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMub25Db21wbGV0ZU9ic2VydmFibGUuYWRkT25jZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB0aGlzLm9uRXJyb3JPYnNlcnZhYmxlLmFkZE9uY2UoKHJlYXNvbikgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmVqZWN0KHJlYXNvbik7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfc2V0U3RhdGUoc3RhdGU6IEdMVEZMb2FkZXJTdGF0ZSk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gc3RhdGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc3RhdGUgPSBzdGF0ZTtcclxuICAgICAgICB0aGlzLm9uTG9hZGVyU3RhdGVDaGFuZ2VkT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnModGhpcy5fc3RhdGUpO1xyXG4gICAgICAgIHRoaXMuX2xvZyhHTFRGTG9hZGVyU3RhdGVbdGhpcy5fc3RhdGVdKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvYWRGaWxlKFxyXG4gICAgICAgIHNjZW5lOiBTY2VuZSxcclxuICAgICAgICBmaWxlT3JVcmw6IEZpbGUgfCBzdHJpbmcsXHJcbiAgICAgICAgb25TdWNjZXNzOiAoZGF0YTogc3RyaW5nIHwgQXJyYXlCdWZmZXIpID0+IHZvaWQsXHJcbiAgICAgICAgdXNlQXJyYXlCdWZmZXI/OiBib29sZWFuLFxyXG4gICAgICAgIG9uRXJyb3I/OiAocmVxdWVzdD86IFdlYlJlcXVlc3QpID0+IHZvaWQsXHJcbiAgICAgICAgb25PcGVuZWQ/OiAocmVxdWVzdDogV2ViUmVxdWVzdCkgPT4gdm9pZFxyXG4gICAgKTogSUZpbGVSZXF1ZXN0IHtcclxuICAgICAgICBjb25zdCByZXF1ZXN0ID0gc2NlbmUuX2xvYWRGaWxlKFxyXG4gICAgICAgICAgICBmaWxlT3JVcmwsXHJcbiAgICAgICAgICAgIG9uU3VjY2VzcyxcclxuICAgICAgICAgICAgKGV2ZW50KSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9vblByb2dyZXNzKGV2ZW50LCByZXF1ZXN0KTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgdHJ1ZSxcclxuICAgICAgICAgICAgdXNlQXJyYXlCdWZmZXIsXHJcbiAgICAgICAgICAgIG9uRXJyb3IsXHJcbiAgICAgICAgICAgIG9uT3BlbmVkXHJcbiAgICAgICAgKSBhcyBJRmlsZVJlcXVlc3RJbmZvO1xyXG4gICAgICAgIHJlcXVlc3Qub25Db21wbGV0ZU9ic2VydmFibGUuYWRkKCgpID0+IHtcclxuICAgICAgICAgICAgLy8gRm9yY2UgdGhlIGxlbmd0aCBjb21wdXRhYmxlIHRvIGJlIHRydWUgc2luY2Ugd2UgY2FuIGd1YXJhbnRlZSB0aGUgZGF0YSBpcyBsb2FkZWQuXHJcbiAgICAgICAgICAgIHJlcXVlc3QuX2xlbmd0aENvbXB1dGFibGUgPSB0cnVlO1xyXG4gICAgICAgICAgICByZXF1ZXN0Ll90b3RhbCA9IHJlcXVlc3QuX2xvYWRlZDtcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLl9yZXF1ZXN0cy5wdXNoKHJlcXVlc3QpO1xyXG4gICAgICAgIHJldHVybiByZXF1ZXN0O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX29uUHJvZ3Jlc3MoZXZlbnQ6IFByb2dyZXNzRXZlbnQsIHJlcXVlc3Q6IElGaWxlUmVxdWVzdEluZm8pOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXRoaXMuX3Byb2dyZXNzQ2FsbGJhY2spIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmVxdWVzdC5fbGVuZ3RoQ29tcHV0YWJsZSA9IGV2ZW50Lmxlbmd0aENvbXB1dGFibGU7XHJcbiAgICAgICAgcmVxdWVzdC5fbG9hZGVkID0gZXZlbnQubG9hZGVkO1xyXG4gICAgICAgIHJlcXVlc3QuX3RvdGFsID0gZXZlbnQudG90YWw7XHJcblxyXG4gICAgICAgIGxldCBsZW5ndGhDb21wdXRhYmxlID0gdHJ1ZTtcclxuICAgICAgICBsZXQgbG9hZGVkID0gMDtcclxuICAgICAgICBsZXQgdG90YWwgPSAwO1xyXG4gICAgICAgIGZvciAoY29uc3QgcmVxdWVzdCBvZiB0aGlzLl9yZXF1ZXN0cykge1xyXG4gICAgICAgICAgICBpZiAocmVxdWVzdC5fbGVuZ3RoQ29tcHV0YWJsZSA9PT0gdW5kZWZpbmVkIHx8IHJlcXVlc3QuX2xvYWRlZCA9PT0gdW5kZWZpbmVkIHx8IHJlcXVlc3QuX3RvdGFsID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGVuZ3RoQ29tcHV0YWJsZSA9IGxlbmd0aENvbXB1dGFibGUgJiYgcmVxdWVzdC5fbGVuZ3RoQ29tcHV0YWJsZTtcclxuICAgICAgICAgICAgbG9hZGVkICs9IHJlcXVlc3QuX2xvYWRlZDtcclxuICAgICAgICAgICAgdG90YWwgKz0gcmVxdWVzdC5fdG90YWw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9wcm9ncmVzc0NhbGxiYWNrKHtcclxuICAgICAgICAgICAgbGVuZ3RoQ29tcHV0YWJsZTogbGVuZ3RoQ29tcHV0YWJsZSxcclxuICAgICAgICAgICAgbG9hZGVkOiBsb2FkZWQsXHJcbiAgICAgICAgICAgIHRvdGFsOiBsZW5ndGhDb21wdXRhYmxlID8gdG90YWwgOiAwLFxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3ZhbGlkYXRlKHNjZW5lOiBTY2VuZSwgZGF0YTogc3RyaW5nIHwgVWludDhBcnJheSwgcm9vdFVybCA9IFwiXCIsIGZpbGVOYW1lID0gXCJcIik6IHZvaWQge1xyXG4gICAgICAgIGlmICghdGhpcy52YWxpZGF0ZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9zdGFydFBlcmZvcm1hbmNlQ291bnRlcihcIlZhbGlkYXRlIEpTT05cIik7XHJcbiAgICAgICAgR0xURlZhbGlkYXRpb24uVmFsaWRhdGVBc3luYyhkYXRhLCByb290VXJsLCBmaWxlTmFtZSwgKHVyaSkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wcmVwcm9jZXNzVXJsQXN5bmMocm9vdFVybCArIHVyaSkudGhlbigodXJsKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NlbmUuX2xvYWRGaWxlQXN5bmModXJsLCB1bmRlZmluZWQsIHRydWUsIHRydWUpLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoZGF0YSwgMCwgZGF0YS5ieXRlTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KS50aGVuKFxyXG4gICAgICAgICAgICAocmVzdWx0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9lbmRQZXJmb3JtYW5jZUNvdW50ZXIoXCJWYWxpZGF0ZSBKU09OXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vblZhbGlkYXRlZE9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKHJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uVmFsaWRhdGVkT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAocmVhc29uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9lbmRQZXJmb3JtYW5jZUNvdW50ZXIoXCJWYWxpZGF0ZSBKU09OXCIpO1xyXG4gICAgICAgICAgICAgICAgVG9vbHMuV2FybihgRmFpbGVkIHRvIHZhbGlkYXRlOiAke3JlYXNvbi5tZXNzYWdlfWApO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vblZhbGlkYXRlZE9ic2VydmFibGUuY2xlYXIoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZ2V0TG9hZGVyKGxvYWRlckRhdGE6IElHTFRGTG9hZGVyRGF0YSk6IElHTFRGTG9hZGVyIHtcclxuICAgICAgICBjb25zdCBhc3NldCA9ICg8YW55PmxvYWRlckRhdGEuanNvbikuYXNzZXQgfHwge307XHJcblxyXG4gICAgICAgIHRoaXMuX2xvZyhgQXNzZXQgdmVyc2lvbjogJHthc3NldC52ZXJzaW9ufWApO1xyXG4gICAgICAgIGFzc2V0Lm1pblZlcnNpb24gJiYgdGhpcy5fbG9nKGBBc3NldCBtaW5pbXVtIHZlcnNpb246ICR7YXNzZXQubWluVmVyc2lvbn1gKTtcclxuICAgICAgICBhc3NldC5nZW5lcmF0b3IgJiYgdGhpcy5fbG9nKGBBc3NldCBnZW5lcmF0b3I6ICR7YXNzZXQuZ2VuZXJhdG9yfWApO1xyXG5cclxuICAgICAgICBjb25zdCB2ZXJzaW9uID0gR0xURkZpbGVMb2FkZXIuX3BhcnNlVmVyc2lvbihhc3NldC52ZXJzaW9uKTtcclxuICAgICAgICBpZiAoIXZlcnNpb24pIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB2ZXJzaW9uOiBcIiArIGFzc2V0LnZlcnNpb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGFzc2V0Lm1pblZlcnNpb24gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBjb25zdCBtaW5WZXJzaW9uID0gR0xURkZpbGVMb2FkZXIuX3BhcnNlVmVyc2lvbihhc3NldC5taW5WZXJzaW9uKTtcclxuICAgICAgICAgICAgaWYgKCFtaW5WZXJzaW9uKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIG1pbmltdW0gdmVyc2lvbjogXCIgKyBhc3NldC5taW5WZXJzaW9uKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKEdMVEZGaWxlTG9hZGVyLl9jb21wYXJlVmVyc2lvbihtaW5WZXJzaW9uLCB7IG1ham9yOiAyLCBtaW5vcjogMCB9KSA+IDApIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkluY29tcGF0aWJsZSBtaW5pbXVtIHZlcnNpb246IFwiICsgYXNzZXQubWluVmVyc2lvbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGNyZWF0ZUxvYWRlcnM6IHsgW2tleTogbnVtYmVyXTogKHBhcmVudDogR0xURkZpbGVMb2FkZXIpID0+IElHTFRGTG9hZGVyIH0gPSB7XHJcbiAgICAgICAgICAgIDE6IEdMVEZGaWxlTG9hZGVyLl9DcmVhdGVHTFRGMUxvYWRlcixcclxuICAgICAgICAgICAgMjogR0xURkZpbGVMb2FkZXIuX0NyZWF0ZUdMVEYyTG9hZGVyLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGNvbnN0IGNyZWF0ZUxvYWRlciA9IGNyZWF0ZUxvYWRlcnNbdmVyc2lvbi5tYWpvcl07XHJcbiAgICAgICAgaWYgKCFjcmVhdGVMb2FkZXIpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgdmVyc2lvbjogXCIgKyBhc3NldC52ZXJzaW9uKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBjcmVhdGVMb2FkZXIodGhpcyk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfcGFyc2VKc29uKGpzb246IHN0cmluZyk6IE9iamVjdCB7XHJcbiAgICAgICAgdGhpcy5fc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXIoXCJQYXJzZSBKU09OXCIpO1xyXG4gICAgICAgIHRoaXMuX2xvZyhgSlNPTiBsZW5ndGg6ICR7anNvbi5sZW5ndGh9YCk7XHJcbiAgICAgICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZShqc29uKTtcclxuICAgICAgICB0aGlzLl9lbmRQZXJmb3JtYW5jZUNvdW50ZXIoXCJQYXJzZSBKU09OXCIpO1xyXG4gICAgICAgIHJldHVybiBwYXJzZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfdW5wYWNrQmluYXJ5QXN5bmMoZGF0YVJlYWRlcjogRGF0YVJlYWRlcik6IFByb21pc2U8SUdMVEZMb2FkZXJEYXRhPiB7XHJcbiAgICAgICAgdGhpcy5fc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXIoXCJVbnBhY2sgQmluYXJ5XCIpO1xyXG5cclxuICAgICAgICAvLyBSZWFkIG1hZ2ljICsgdmVyc2lvbiArIGxlbmd0aCArIGpzb24gbGVuZ3RoICsganNvbiBmb3JtYXRcclxuICAgICAgICByZXR1cm4gZGF0YVJlYWRlci5sb2FkQXN5bmMoMjApLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBCaW5hcnkgPSB7XHJcbiAgICAgICAgICAgICAgICBNYWdpYzogMHg0NjU0NmM2NyxcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IG1hZ2ljID0gZGF0YVJlYWRlci5yZWFkVWludDMyKCk7XHJcbiAgICAgICAgICAgIGlmIChtYWdpYyAhPT0gQmluYXJ5Lk1hZ2ljKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKFwiVW5leHBlY3RlZCBtYWdpYzogXCIgKyBtYWdpYywgRXJyb3JDb2Rlcy5HTFRGTG9hZGVyVW5leHBlY3RlZE1hZ2ljRXJyb3IpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCB2ZXJzaW9uID0gZGF0YVJlYWRlci5yZWFkVWludDMyKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5sb2dnaW5nRW5hYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9nKGBCaW5hcnkgdmVyc2lvbjogJHt2ZXJzaW9ufWApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBsZW5ndGggPSBkYXRhUmVhZGVyLnJlYWRVaW50MzIoKTtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLnVzZVJhbmdlUmVxdWVzdHMgJiYgbGVuZ3RoICE9PSBkYXRhUmVhZGVyLmJ1ZmZlci5ieXRlTGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICBMb2dnZXIuV2FybihgTGVuZ3RoIGluIGhlYWRlciBkb2VzIG5vdCBtYXRjaCBhY3R1YWwgZGF0YSBsZW5ndGg6ICR7bGVuZ3RofSAhPSAke2RhdGFSZWFkZXIuYnVmZmVyLmJ5dGVMZW5ndGh9YCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGxldCB1bnBhY2tlZDogUHJvbWlzZTxJR0xURkxvYWRlckRhdGE+O1xyXG4gICAgICAgICAgICBzd2l0Y2ggKHZlcnNpb24pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMToge1xyXG4gICAgICAgICAgICAgICAgICAgIHVucGFja2VkID0gdGhpcy5fdW5wYWNrQmluYXJ5VjFBc3luYyhkYXRhUmVhZGVyLCBsZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY2FzZSAyOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQgPSB0aGlzLl91bnBhY2tCaW5hcnlWMkFzeW5jKGRhdGFSZWFkZXIsIGxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgdmVyc2lvbjogXCIgKyB2ZXJzaW9uKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5fZW5kUGVyZm9ybWFuY2VDb3VudGVyKFwiVW5wYWNrIEJpbmFyeVwiKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiB1bnBhY2tlZDtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF91bnBhY2tCaW5hcnlWMUFzeW5jKGRhdGFSZWFkZXI6IERhdGFSZWFkZXIsIGxlbmd0aDogbnVtYmVyKTogUHJvbWlzZTxJR0xURkxvYWRlckRhdGE+IHtcclxuICAgICAgICBjb25zdCBDb250ZW50Rm9ybWF0ID0ge1xyXG4gICAgICAgICAgICBKU09OOiAwLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGNvbnN0IGNvbnRlbnRMZW5ndGggPSBkYXRhUmVhZGVyLnJlYWRVaW50MzIoKTtcclxuICAgICAgICBjb25zdCBjb250ZW50Rm9ybWF0ID0gZGF0YVJlYWRlci5yZWFkVWludDMyKCk7XHJcblxyXG4gICAgICAgIGlmIChjb250ZW50Rm9ybWF0ICE9PSBDb250ZW50Rm9ybWF0LkpTT04pIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIGNvbnRlbnQgZm9ybWF0OiAke2NvbnRlbnRGb3JtYXR9YCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBib2R5TGVuZ3RoID0gbGVuZ3RoIC0gZGF0YVJlYWRlci5ieXRlT2Zmc2V0O1xyXG5cclxuICAgICAgICBjb25zdCBkYXRhOiBJR0xURkxvYWRlckRhdGEgPSB7IGpzb246IHRoaXMuX3BhcnNlSnNvbihkYXRhUmVhZGVyLnJlYWRTdHJpbmcoY29udGVudExlbmd0aCkpLCBiaW46IG51bGwgfTtcclxuICAgICAgICBpZiAoYm9keUxlbmd0aCAhPT0gMCkge1xyXG4gICAgICAgICAgICBjb25zdCBzdGFydEJ5dGVPZmZzZXQgPSBkYXRhUmVhZGVyLmJ5dGVPZmZzZXQ7XHJcbiAgICAgICAgICAgIGRhdGEuYmluID0ge1xyXG4gICAgICAgICAgICAgICAgcmVhZEFzeW5jOiAoYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCkgPT4gZGF0YVJlYWRlci5idWZmZXIucmVhZEFzeW5jKHN0YXJ0Qnl0ZU9mZnNldCArIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpLFxyXG4gICAgICAgICAgICAgICAgYnl0ZUxlbmd0aDogYm9keUxlbmd0aCxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZGF0YSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfdW5wYWNrQmluYXJ5VjJBc3luYyhkYXRhUmVhZGVyOiBEYXRhUmVhZGVyLCBsZW5ndGg6IG51bWJlcik6IFByb21pc2U8SUdMVEZMb2FkZXJEYXRhPiB7XHJcbiAgICAgICAgY29uc3QgQ2h1bmtGb3JtYXQgPSB7XHJcbiAgICAgICAgICAgIEpTT046IDB4NGU0ZjUzNGEsXHJcbiAgICAgICAgICAgIEJJTjogMHgwMDRlNDk0MixcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvLyBSZWFkIHRoZSBKU09OIGNodW5rIGhlYWRlci5cclxuICAgICAgICBjb25zdCBjaHVua0xlbmd0aCA9IGRhdGFSZWFkZXIucmVhZFVpbnQzMigpO1xyXG4gICAgICAgIGNvbnN0IGNodW5rRm9ybWF0ID0gZGF0YVJlYWRlci5yZWFkVWludDMyKCk7XHJcbiAgICAgICAgaWYgKGNodW5rRm9ybWF0ICE9PSBDaHVua0Zvcm1hdC5KU09OKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkZpcnN0IGNodW5rIGZvcm1hdCBpcyBub3QgSlNPTlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEJhaWwgaWYgdGhlcmUgYXJlIG5vIG90aGVyIGNodW5rcy5cclxuICAgICAgICBpZiAoZGF0YVJlYWRlci5ieXRlT2Zmc2V0ICsgY2h1bmtMZW5ndGggPT09IGxlbmd0aCkge1xyXG4gICAgICAgICAgICByZXR1cm4gZGF0YVJlYWRlci5sb2FkQXN5bmMoY2h1bmtMZW5ndGgpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsganNvbjogdGhpcy5fcGFyc2VKc29uKGRhdGFSZWFkZXIucmVhZFN0cmluZyhjaHVua0xlbmd0aCkpLCBiaW46IG51bGwgfTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBSZWFkIHRoZSBKU09OIGNodW5rIGFuZCB0aGUgbGVuZ3RoIGFuZCB0eXBlIG9mIHRoZSBuZXh0IGNodW5rLlxyXG4gICAgICAgIHJldHVybiBkYXRhUmVhZGVyLmxvYWRBc3luYyhjaHVua0xlbmd0aCArIDgpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBkYXRhOiBJR0xURkxvYWRlckRhdGEgPSB7IGpzb246IHRoaXMuX3BhcnNlSnNvbihkYXRhUmVhZGVyLnJlYWRTdHJpbmcoY2h1bmtMZW5ndGgpKSwgYmluOiBudWxsIH07XHJcblxyXG4gICAgICAgICAgICBjb25zdCByZWFkQXN5bmMgPSAoKTogUHJvbWlzZTxJR0xURkxvYWRlckRhdGE+ID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNodW5rTGVuZ3RoID0gZGF0YVJlYWRlci5yZWFkVWludDMyKCk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaHVua0Zvcm1hdCA9IGRhdGFSZWFkZXIucmVhZFVpbnQzMigpO1xyXG5cclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoY2h1bmtGb3JtYXQpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIENodW5rRm9ybWF0LkpTT046IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5leHBlY3RlZCBKU09OIGNodW5rXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjYXNlIENodW5rRm9ybWF0LkJJTjoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGFydEJ5dGVPZmZzZXQgPSBkYXRhUmVhZGVyLmJ5dGVPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEuYmluID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZEFzeW5jOiAoYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCkgPT4gZGF0YVJlYWRlci5idWZmZXIucmVhZEFzeW5jKHN0YXJ0Qnl0ZU9mZnNldCArIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZUxlbmd0aDogY2h1bmtMZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFSZWFkZXIuc2tpcEJ5dGVzKGNodW5rTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIHVucmVjb2duaXplZCBjaHVua0Zvcm1hdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhUmVhZGVyLnNraXBCeXRlcyhjaHVua0xlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoZGF0YVJlYWRlci5ieXRlT2Zmc2V0ICE9PSBsZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVJlYWRlci5sb2FkQXN5bmMoOCkudGhlbihyZWFkQXN5bmMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZGF0YSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcmVhZEFzeW5jKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX3BhcnNlVmVyc2lvbih2ZXJzaW9uOiBzdHJpbmcpOiBOdWxsYWJsZTx7IG1ham9yOiBudW1iZXI7IG1pbm9yOiBudW1iZXIgfT4ge1xyXG4gICAgICAgIGlmICh2ZXJzaW9uID09PSBcIjEuMFwiIHx8IHZlcnNpb24gPT09IFwiMS4wLjFcIikge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgbWFqb3I6IDEsXHJcbiAgICAgICAgICAgICAgICBtaW5vcjogMCxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IG1hdGNoID0gKHZlcnNpb24gKyBcIlwiKS5tYXRjaCgvXihcXGQrKVxcLihcXGQrKS8pO1xyXG4gICAgICAgIGlmICghbWF0Y2gpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBtYWpvcjogcGFyc2VJbnQobWF0Y2hbMV0pLFxyXG4gICAgICAgICAgICBtaW5vcjogcGFyc2VJbnQobWF0Y2hbMl0pLFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX2NvbXBhcmVWZXJzaW9uKGE6IHsgbWFqb3I6IG51bWJlcjsgbWlub3I6IG51bWJlciB9LCBiOiB7IG1ham9yOiBudW1iZXI7IG1pbm9yOiBudW1iZXIgfSk6IG51bWJlciB7XHJcbiAgICAgICAgaWYgKGEubWFqb3IgPiBiLm1ham9yKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAxO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYS5tYWpvciA8IGIubWFqb3IpIHtcclxuICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYS5taW5vciA+IGIubWlub3IpIHtcclxuICAgICAgICAgICAgcmV0dXJuIDE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChhLm1pbm9yIDwgYi5taW5vcikge1xyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAwO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IF9sb2dTcGFjZXMgPSBcIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCI7XHJcbiAgICBwcml2YXRlIF9sb2dJbmRlbnRMZXZlbCA9IDA7XHJcbiAgICBwcml2YXRlIF9sb2dnaW5nRW5hYmxlZCA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBfbG9nID0gdGhpcy5fbG9nRGlzYWJsZWQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9sb2dPcGVuKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX2xvZyhtZXNzYWdlKTtcclxuICAgICAgICB0aGlzLl9sb2dJbmRlbnRMZXZlbCsrO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBfbG9nQ2xvc2UoKTogdm9pZCB7XHJcbiAgICAgICAgLS10aGlzLl9sb2dJbmRlbnRMZXZlbDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2dFbmFibGVkKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHNwYWNlcyA9IEdMVEZGaWxlTG9hZGVyLl9sb2dTcGFjZXMuc3Vic3RyaW5nKDAsIHRoaXMuX2xvZ0luZGVudExldmVsICogMik7XHJcbiAgICAgICAgTG9nZ2VyLkxvZyhgJHtzcGFjZXN9JHttZXNzYWdlfWApO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvZ0Rpc2FibGVkKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge31cclxuXHJcbiAgICBwcml2YXRlIF9jYXB0dXJlUGVyZm9ybWFuY2VDb3VudGVycyA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBfc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXIgPSB0aGlzLl9zdGFydFBlcmZvcm1hbmNlQ291bnRlckRpc2FibGVkO1xyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBfZW5kUGVyZm9ybWFuY2VDb3VudGVyID0gdGhpcy5fZW5kUGVyZm9ybWFuY2VDb3VudGVyRGlzYWJsZWQ7XHJcblxyXG4gICAgcHJpdmF0ZSBfc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXJFbmFibGVkKGNvdW50ZXJOYW1lOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICBUb29scy5TdGFydFBlcmZvcm1hbmNlQ291bnRlcihjb3VudGVyTmFtZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXJEaXNhYmxlZChjb3VudGVyTmFtZTogc3RyaW5nKTogdm9pZCB7fVxyXG5cclxuICAgIHByaXZhdGUgX2VuZFBlcmZvcm1hbmNlQ291bnRlckVuYWJsZWQoY291bnRlck5hbWU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIFRvb2xzLkVuZFBlcmZvcm1hbmNlQ291bnRlcihjb3VudGVyTmFtZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZW5kUGVyZm9ybWFuY2VDb3VudGVyRGlzYWJsZWQoY291bnRlck5hbWU6IHN0cmluZyk6IHZvaWQge31cclxufVxyXG5cclxucmVnaXN0ZXJTY2VuZUxvYWRlclBsdWdpbihuZXcgR0xURkZpbGVMb2FkZXIoKSk7XHJcbiIsImltcG9ydCB0eXBlICogYXMgR0xURjIgZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyBUb29scyB9IGZyb20gXCJjb3JlL01pc2MvdG9vbHNcIjtcclxuXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZGVjbGFyZSBsZXQgR0xURlZhbGlkYXRvcjogR0xURjIuSUdMVEZWYWxpZGF0b3I7XHJcblxyXG4vLyBXb3JrZXJHbG9iYWxTY29wZVxyXG5kZWNsYXJlIGZ1bmN0aW9uIGltcG9ydFNjcmlwdHMoLi4udXJsczogc3RyaW5nW10pOiB2b2lkO1xyXG5kZWNsYXJlIGZ1bmN0aW9uIHBvc3RNZXNzYWdlKG1lc3NhZ2U6IGFueSwgdHJhbnNmZXI/OiBhbnlbXSk6IHZvaWQ7XHJcblxyXG5mdW5jdGlvbiB2YWxpZGF0ZUFzeW5jKFxyXG4gICAgZGF0YTogc3RyaW5nIHwgVWludDhBcnJheSxcclxuICAgIHJvb3RVcmw6IHN0cmluZyxcclxuICAgIGZpbGVOYW1lOiBzdHJpbmcsXHJcbiAgICBnZXRFeHRlcm5hbFJlc291cmNlOiAodXJpOiBzdHJpbmcpID0+IFByb21pc2U8VWludDhBcnJheT5cclxuKTogUHJvbWlzZTxHTFRGMi5JR0xURlZhbGlkYXRpb25SZXN1bHRzPiB7XHJcbiAgICBjb25zdCBvcHRpb25zOiBHTFRGMi5JR0xURlZhbGlkYXRpb25PcHRpb25zID0ge1xyXG4gICAgICAgIGV4dGVybmFsUmVzb3VyY2VGdW5jdGlvbjogZ2V0RXh0ZXJuYWxSZXNvdXJjZSxcclxuICAgIH07XHJcblxyXG4gICAgaWYgKGZpbGVOYW1lKSB7XHJcbiAgICAgICAgb3B0aW9ucy51cmkgPSByb290VXJsID09PSBcImZpbGU6XCIgPyBmaWxlTmFtZSA6IHJvb3RVcmwgKyBmaWxlTmFtZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gQXJyYXlCdWZmZXIuaXNWaWV3KGRhdGEpID8gR0xURlZhbGlkYXRvci52YWxpZGF0ZUJ5dGVzKGRhdGEsIG9wdGlvbnMpIDogR0xURlZhbGlkYXRvci52YWxpZGF0ZVN0cmluZyhkYXRhLCBvcHRpb25zKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRoZSB3b3JrZXIgZnVuY3Rpb24gdGhhdCBnZXRzIGNvbnZlcnRlZCB0byBhIGJsb2IgdXJsIHRvIHBhc3MgaW50byBhIHdvcmtlci5cclxuICovXHJcbmZ1bmN0aW9uIHdvcmtlckZ1bmMoKTogdm9pZCB7XHJcbiAgICBjb25zdCBwZW5kaW5nRXh0ZXJuYWxSZXNvdXJjZXM6IEFycmF5PHsgcmVzb2x2ZTogKGRhdGE6IGFueSkgPT4gdm9pZDsgcmVqZWN0OiAocmVhc29uOiBhbnkpID0+IHZvaWQgfT4gPSBbXTtcclxuXHJcbiAgICBvbm1lc3NhZ2UgPSAobWVzc2FnZSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGRhdGEgPSBtZXNzYWdlLmRhdGE7XHJcbiAgICAgICAgc3dpdGNoIChkYXRhLmlkKSB7XHJcbiAgICAgICAgICAgIGNhc2UgXCJpbml0XCI6IHtcclxuICAgICAgICAgICAgICAgIGltcG9ydFNjcmlwdHMoZGF0YS51cmwpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBcInZhbGlkYXRlXCI6IHtcclxuICAgICAgICAgICAgICAgIHZhbGlkYXRlQXN5bmMoXHJcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5kYXRhLFxyXG4gICAgICAgICAgICAgICAgICAgIGRhdGEucm9vdFVybCxcclxuICAgICAgICAgICAgICAgICAgICBkYXRhLmZpbGVOYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICh1cmkpID0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gcGVuZGluZ0V4dGVybmFsUmVzb3VyY2VzLmxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlbmRpbmdFeHRlcm5hbFJlc291cmNlcy5wdXNoKHsgcmVzb2x2ZSwgcmVqZWN0IH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zdE1lc3NhZ2UoeyBpZDogXCJnZXRFeHRlcm5hbFJlc291cmNlXCIsIGluZGV4OiBpbmRleCwgdXJpOiB1cmkgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICApLnRoZW4oXHJcbiAgICAgICAgICAgICAgICAgICAgKHZhbHVlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgaWQ6IFwidmFsaWRhdGUucmVzb2x2ZVwiLCB2YWx1ZTogdmFsdWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAocmVhc29uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgaWQ6IFwidmFsaWRhdGUucmVqZWN0XCIsIHJlYXNvbjogcmVhc29uIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFwiZ2V0RXh0ZXJuYWxSZXNvdXJjZS5yZXNvbHZlXCI6IHtcclxuICAgICAgICAgICAgICAgIHBlbmRpbmdFeHRlcm5hbFJlc291cmNlc1tkYXRhLmluZGV4XS5yZXNvbHZlKGRhdGEudmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBcImdldEV4dGVybmFsUmVzb3VyY2UucmVqZWN0XCI6IHtcclxuICAgICAgICAgICAgICAgIHBlbmRpbmdFeHRlcm5hbFJlc291cmNlc1tkYXRhLmluZGV4XS5yZWplY3QoZGF0YS5yZWFzb24pO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG59XHJcblxyXG4vKipcclxuICogQ29uZmlndXJhdGlvbiBmb3IgZ2xURiB2YWxpZGF0aW9uXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGVmFsaWRhdGlvbkNvbmZpZ3VyYXRpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgdXJsIG9mIHRoZSBnbFRGIHZhbGlkYXRvci5cclxuICAgICAqL1xyXG4gICAgdXJsOiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBnbFRGIHZhbGlkYXRpb25cclxuICovXHJcbmV4cG9ydCBjbGFzcyBHTFRGVmFsaWRhdGlvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBjb25maWd1cmF0aW9uLiBEZWZhdWx0cyB0byBgeyB1cmw6IFwiaHR0cHM6Ly9jZG4uYmFieWxvbmpzLmNvbS9nbHRmX3ZhbGlkYXRvci5qc1wiIH1gLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIENvbmZpZ3VyYXRpb246IElHTFRGVmFsaWRhdGlvbkNvbmZpZ3VyYXRpb24gPSB7XHJcbiAgICAgICAgdXJsOiBgJHtUb29scy5fRGVmYXVsdENkblVybH0vZ2x0Zl92YWxpZGF0b3IuanNgLFxyXG4gICAgfTtcclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfTG9hZFNjcmlwdFByb21pc2U6IFByb21pc2U8dm9pZD47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBWYWxpZGF0ZSBhIGdsVEYgYXNzZXQgdXNpbmcgdGhlIGdsVEYtVmFsaWRhdG9yLlxyXG4gICAgICogQHBhcmFtIGRhdGEgVGhlIEpTT04gb2YgYSBnbFRGIG9yIHRoZSBhcnJheSBidWZmZXIgb2YgYSBiaW5hcnkgZ2xURlxyXG4gICAgICogQHBhcmFtIHJvb3RVcmwgVGhlIHJvb3QgdXJsIGZvciB0aGUgZ2xURlxyXG4gICAgICogQHBhcmFtIGZpbGVOYW1lIFRoZSBmaWxlIG5hbWUgZm9yIHRoZSBnbFRGXHJcbiAgICAgKiBAcGFyYW0gZ2V0RXh0ZXJuYWxSZXNvdXJjZSBUaGUgY2FsbGJhY2sgdG8gZ2V0IGV4dGVybmFsIHJlc291cmNlcyBmb3IgdGhlIGdsVEYgdmFsaWRhdG9yXHJcbiAgICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBnbFRGIHZhbGlkYXRpb24gcmVzdWx0cyBvbmNlIGNvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgVmFsaWRhdGVBc3luYyhcclxuICAgICAgICBkYXRhOiBzdHJpbmcgfCBVaW50OEFycmF5LFxyXG4gICAgICAgIHJvb3RVcmw6IHN0cmluZyxcclxuICAgICAgICBmaWxlTmFtZTogc3RyaW5nLFxyXG4gICAgICAgIGdldEV4dGVybmFsUmVzb3VyY2U6ICh1cmk6IHN0cmluZykgPT4gUHJvbWlzZTxVaW50OEFycmF5PlxyXG4gICAgKTogUHJvbWlzZTxHTFRGMi5JR0xURlZhbGlkYXRpb25SZXN1bHRzPiB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBXb3JrZXIgPT09IFwiZnVuY3Rpb25cIikge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgd29ya2VyQ29udGVudCA9IGAke3ZhbGlkYXRlQXN5bmN9KCR7d29ya2VyRnVuY30pKClgO1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgd29ya2VyQmxvYlVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwobmV3IEJsb2IoW3dvcmtlckNvbnRlbnRdLCB7IHR5cGU6IFwiYXBwbGljYXRpb24vamF2YXNjcmlwdFwiIH0pKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHdvcmtlciA9IG5ldyBXb3JrZXIod29ya2VyQmxvYlVybCk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3Qgb25FcnJvciA9IChlcnJvcjogRXJyb3JFdmVudCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHdvcmtlci5yZW1vdmVFdmVudExpc3RlbmVyKFwiZXJyb3JcIiwgb25FcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgd29ya2VyLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIG9uTWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3Qgb25NZXNzYWdlID0gKG1lc3NhZ2U6IE1lc3NhZ2VFdmVudCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBtZXNzYWdlLmRhdGE7XHJcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChkYXRhLmlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJnZXRFeHRlcm5hbFJlc291cmNlXCI6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEV4dGVybmFsUmVzb3VyY2UoZGF0YS51cmkpLnRoZW4oXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZhbHVlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvcmtlci5wb3N0TWVzc2FnZSh7IGlkOiBcImdldEV4dGVybmFsUmVzb3VyY2UucmVzb2x2ZVwiLCBpbmRleDogZGF0YS5pbmRleCwgdmFsdWU6IHZhbHVlIH0sIFt2YWx1ZS5idWZmZXJdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZWFzb24pID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd29ya2VyLnBvc3RNZXNzYWdlKHsgaWQ6IFwiZ2V0RXh0ZXJuYWxSZXNvdXJjZS5yZWplY3RcIiwgaW5kZXg6IGRhdGEuaW5kZXgsIHJlYXNvbjogcmVhc29uIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwidmFsaWRhdGUucmVzb2x2ZVwiOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JrZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImVycm9yXCIsIG9uRXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd29ya2VyLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIG9uTWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGRhdGEudmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd29ya2VyLnRlcm1pbmF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcInZhbGlkYXRlLnJlamVjdFwiOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JrZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImVycm9yXCIsIG9uRXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd29ya2VyLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIG9uTWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZGF0YS5yZWFzb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd29ya2VyLnRlcm1pbmF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICB3b3JrZXIuYWRkRXZlbnRMaXN0ZW5lcihcImVycm9yXCIsIG9uRXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgd29ya2VyLmFkZEV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIG9uTWVzc2FnZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgd29ya2VyLnBvc3RNZXNzYWdlKHsgaWQ6IFwiaW5pdFwiLCB1cmw6IFRvb2xzLkdldEJhYnlsb25TY3JpcHRVUkwodGhpcy5Db25maWd1cmF0aW9uLnVybCkgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhkYXRhKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFNsaWNlIHRoZSBkYXRhIHRvIGF2b2lkIGNvcHlpbmcgdGhlIHdob2xlIGFycmF5IGJ1ZmZlci5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzbGljZWREYXRhID0gZGF0YS5zbGljZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHdvcmtlci5wb3N0TWVzc2FnZSh7IGlkOiBcInZhbGlkYXRlXCIsIGRhdGE6IHNsaWNlZERhdGEsIHJvb3RVcmw6IHJvb3RVcmwsIGZpbGVOYW1lOiBmaWxlTmFtZSB9LCBbc2xpY2VkRGF0YS5idWZmZXJdKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd29ya2VyLnBvc3RNZXNzYWdlKHsgaWQ6IFwidmFsaWRhdGVcIiwgZGF0YTogZGF0YSwgcm9vdFVybDogcm9vdFVybCwgZmlsZU5hbWU6IGZpbGVOYW1lIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuX0xvYWRTY3JpcHRQcm9taXNlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9Mb2FkU2NyaXB0UHJvbWlzZSA9IFRvb2xzLkxvYWRCYWJ5bG9uU2NyaXB0QXN5bmModGhpcy5Db25maWd1cmF0aW9uLnVybCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9Mb2FkU2NyaXB0UHJvbWlzZS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB2YWxpZGF0ZUFzeW5jKGRhdGEsIHJvb3RVcmwsIGZpbGVOYW1lLCBnZXRFeHRlcm5hbFJlc291cmNlKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCAqIGFzIEZpbGVMb2FkZXIgZnJvbSBcImxvYWRlcnMvZ2xURi9nbFRGRmlsZUxvYWRlclwiO1xyXG5pbXBvcnQgKiBhcyBWYWxpZGF0aW9uIGZyb20gXCJsb2FkZXJzL2dsVEYvZ2xURlZhbGlkYXRpb25cIjtcclxuXHJcbi8qKlxyXG4gKiBUaGlzIGlzIHRoZSBlbnRyeSBwb2ludCBmb3IgdGhlIFVNRCBtb2R1bGUuXHJcbiAqIFRoZSBlbnRyeSBwb2ludCBmb3IgYSBmdXR1cmUgRVNNIHBhY2thZ2Ugc2hvdWxkIGJlIGluZGV4LnRzXHJcbiAqL1xyXG5jb25zdCBnbG9iYWxPYmplY3QgPSB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHVuZGVmaW5lZDtcclxuaWYgKHR5cGVvZiBnbG9iYWxPYmplY3QgIT09IFwidW5kZWZpbmVkXCIpIHtcclxuICAgICg8YW55Pmdsb2JhbE9iamVjdCkuQkFCWUxPTiA9ICg8YW55Pmdsb2JhbE9iamVjdCkuQkFCWUxPTiB8fCB7fTtcclxuICAgIGZvciAoY29uc3Qga2V5IGluIEZpbGVMb2FkZXIpIHtcclxuICAgICAgICAoPGFueT5nbG9iYWxPYmplY3QpLkJBQllMT05ba2V5XSA9ICg8YW55PkZpbGVMb2FkZXIpW2tleV07XHJcbiAgICB9XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBWYWxpZGF0aW9uKSB7XHJcbiAgICAgICAgKDxhbnk+Z2xvYmFsT2JqZWN0KS5CQUJZTE9OW2tleV0gPSAoPGFueT5WYWxpZGF0aW9uKVtrZXldO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgKiBmcm9tIFwibG9hZGVycy9nbFRGL2dsVEZGaWxlTG9hZGVyXCI7XHJcbmV4cG9ydCAqIGZyb20gXCJsb2FkZXJzL2dsVEYvZ2xURlZhbGlkYXRpb25cIjtcclxuIiwiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWludGVybmFsLW1vZHVsZXMgKi9cclxuaW1wb3J0ICogYXMgRXh0ZW5zaW9ucyBmcm9tIFwibG9hZGVycy9nbFRGLzIuMC9FeHRlbnNpb25zL2luZGV4XCI7XHJcbmltcG9ydCAqIGFzIEludGVyZmFjZXMgZnJvbSBcImxvYWRlcnMvZ2xURi8yLjAvZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0ICogYXMgR0xURjIgZnJvbSBcImxvYWRlcnMvZ2xURi8yLjAvaW5kZXhcIjtcclxuXHJcbi8qKlxyXG4gKiBUaGlzIGlzIHRoZSBlbnRyeSBwb2ludCBmb3IgdGhlIFVNRCBtb2R1bGUuXHJcbiAqIFRoZSBlbnRyeSBwb2ludCBmb3IgYSBmdXR1cmUgRVNNIHBhY2thZ2Ugc2hvdWxkIGJlIGluZGV4LnRzXHJcbiAqL1xyXG5jb25zdCBnbG9iYWxPYmplY3QgPSB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHVuZGVmaW5lZDtcclxuaWYgKHR5cGVvZiBnbG9iYWxPYmplY3QgIT09IFwidW5kZWZpbmVkXCIpIHtcclxuICAgICg8YW55Pmdsb2JhbE9iamVjdCkuQkFCWUxPTiA9ICg8YW55Pmdsb2JhbE9iamVjdCkuQkFCWUxPTiB8fCB7fTtcclxuICAgIGNvbnN0IEJBQllMT04gPSAoPGFueT5nbG9iYWxPYmplY3QpLkJBQllMT047XHJcbiAgICBCQUJZTE9OLkdMVEYyID0gQkFCWUxPTi5HTFRGMiB8fCB7fTtcclxuICAgIEJBQllMT04uR0xURjIuTG9hZGVyID0gQkFCWUxPTi5HTFRGMi5Mb2FkZXIgfHwge307XHJcbiAgICBCQUJZTE9OLkdMVEYyLkxvYWRlci5FeHRlbnNpb25zID0gQkFCWUxPTi5HTFRGMi5Mb2FkZXIuRXh0ZW5zaW9ucyB8fCB7fTtcclxuXHJcbiAgICBjb25zdCBrZXlzID0gW107XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBFeHRlbnNpb25zKSB7XHJcbiAgICAgICAgQkFCWUxPTi5HTFRGMi5Mb2FkZXIuRXh0ZW5zaW9uc1trZXldID0gKDxhbnk+RXh0ZW5zaW9ucylba2V5XTtcclxuICAgICAgICBrZXlzLnB1c2goa2V5KTtcclxuICAgIH1cclxuICAgIGZvciAoY29uc3Qga2V5IGluIEludGVyZmFjZXMpIHtcclxuICAgICAgICBCQUJZTE9OLkdMVEYyLkxvYWRlcltrZXldID0gKDxhbnk+SW50ZXJmYWNlcylba2V5XTtcclxuICAgICAgICBrZXlzLnB1c2goa2V5KTtcclxuICAgIH1cclxuXHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBHTFRGMikge1xyXG4gICAgICAgIC8vIFByZXZlbnQgUmVhc3NpZ25tZW50LlxyXG4gICAgICAgIGlmIChrZXlzLmluZGV4T2Yoa2V5KSA+IC0xKSB7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgQkFCWUxPTi5HTFRGMltrZXldID0gKDxhbnk+R0xURjIpW2tleV07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCB7IEdMVEYyIH07XHJcbiIsIi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvZXhwb3J0XHJcbmV4cG9ydCAqIGZyb20gXCIuL2xlZ2FjeS1nbFRGXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL2xlZ2FjeS1nbFRGMlwiO1xyXG4iLCJtb2R1bGUuZXhwb3J0cyA9IF9fV0VCUEFDS19FWFRFUk5BTF9NT0RVTEVfYmFieWxvbmpzX01pc2NfdG9vbHNfXzsiLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cblxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXG5cblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSwgU3VwcHJlc3NlZEVycm9yLCBTeW1ib2wsIEl0ZXJhdG9yICovXG5cbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xuICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XG4gICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XG4gICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xuICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xuICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xuICBleHRlbmRTdGF0aWNzKGQsIGIpO1xuICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cbiAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xufVxuXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XG4gIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XG4gICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xuICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XG4gICAgICB9XG4gICAgICByZXR1cm4gdDtcbiAgfVxuICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XG4gIHZhciB0ID0ge307XG4gIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxuICAgICAgdFtwXSA9IHNbcF07XG4gIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcbiAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXG4gICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xuICAgICAgfVxuICByZXR1cm4gdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcbiAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcbiAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcbiAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcbiAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XG4gIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gX19lc0RlY29yYXRlKGN0b3IsIGRlc2NyaXB0b3JJbiwgZGVjb3JhdG9ycywgY29udGV4dEluLCBpbml0aWFsaXplcnMsIGV4dHJhSW5pdGlhbGl6ZXJzKSB7XG4gIGZ1bmN0aW9uIGFjY2VwdChmKSB7IGlmIChmICE9PSB2b2lkIDAgJiYgdHlwZW9mIGYgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZ1bmN0aW9uIGV4cGVjdGVkXCIpOyByZXR1cm4gZjsgfVxuICB2YXIga2luZCA9IGNvbnRleHRJbi5raW5kLCBrZXkgPSBraW5kID09PSBcImdldHRlclwiID8gXCJnZXRcIiA6IGtpbmQgPT09IFwic2V0dGVyXCIgPyBcInNldFwiIDogXCJ2YWx1ZVwiO1xuICB2YXIgdGFyZ2V0ID0gIWRlc2NyaXB0b3JJbiAmJiBjdG9yID8gY29udGV4dEluW1wic3RhdGljXCJdID8gY3RvciA6IGN0b3IucHJvdG90eXBlIDogbnVsbDtcbiAgdmFyIGRlc2NyaXB0b3IgPSBkZXNjcmlwdG9ySW4gfHwgKHRhcmdldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSkgOiB7fSk7XG4gIHZhciBfLCBkb25lID0gZmFsc2U7XG4gIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgY29udGV4dCA9IHt9O1xuICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4pIGNvbnRleHRbcF0gPSBwID09PSBcImFjY2Vzc1wiID8ge30gOiBjb250ZXh0SW5bcF07XG4gICAgICBmb3IgKHZhciBwIGluIGNvbnRleHRJbi5hY2Nlc3MpIGNvbnRleHQuYWNjZXNzW3BdID0gY29udGV4dEluLmFjY2Vzc1twXTtcbiAgICAgIGNvbnRleHQuYWRkSW5pdGlhbGl6ZXIgPSBmdW5jdGlvbiAoZikgeyBpZiAoZG9uZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBhZGQgaW5pdGlhbGl6ZXJzIGFmdGVyIGRlY29yYXRpb24gaGFzIGNvbXBsZXRlZFwiKTsgZXh0cmFJbml0aWFsaXplcnMucHVzaChhY2NlcHQoZiB8fCBudWxsKSk7IH07XG4gICAgICB2YXIgcmVzdWx0ID0gKDAsIGRlY29yYXRvcnNbaV0pKGtpbmQgPT09IFwiYWNjZXNzb3JcIiA/IHsgZ2V0OiBkZXNjcmlwdG9yLmdldCwgc2V0OiBkZXNjcmlwdG9yLnNldCB9IDogZGVzY3JpcHRvcltrZXldLCBjb250ZXh0KTtcbiAgICAgIGlmIChraW5kID09PSBcImFjY2Vzc29yXCIpIHtcbiAgICAgICAgICBpZiAocmVzdWx0ID09PSB2b2lkIDApIGNvbnRpbnVlO1xuICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuZ2V0KSkgZGVzY3JpcHRvci5nZXQgPSBfO1xuICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5zZXQpKSBkZXNjcmlwdG9yLnNldCA9IF87XG4gICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmluaXQpKSBpbml0aWFsaXplcnMudW5zaGlmdChfKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKF8gPSBhY2NlcHQocmVzdWx0KSkge1xuICAgICAgICAgIGlmIChraW5kID09PSBcImZpZWxkXCIpIGluaXRpYWxpemVycy51bnNoaWZ0KF8pO1xuICAgICAgICAgIGVsc2UgZGVzY3JpcHRvcltrZXldID0gXztcbiAgICAgIH1cbiAgfVxuICBpZiAodGFyZ2V0KSBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSwgZGVzY3JpcHRvcik7XG4gIGRvbmUgPSB0cnVlO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9fcnVuSW5pdGlhbGl6ZXJzKHRoaXNBcmcsIGluaXRpYWxpemVycywgdmFsdWUpIHtcbiAgdmFyIHVzZVZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaW5pdGlhbGl6ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YWx1ZSA9IHVzZVZhbHVlID8gaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZywgdmFsdWUpIDogaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZyk7XG4gIH1cbiAgcmV0dXJuIHVzZVZhbHVlID8gdmFsdWUgOiB2b2lkIDA7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gX19wcm9wS2V5KHgpIHtcbiAgcmV0dXJuIHR5cGVvZiB4ID09PSBcInN5bWJvbFwiID8geCA6IFwiXCIuY29uY2F0KHgpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9fc2V0RnVuY3Rpb25OYW1lKGYsIG5hbWUsIHByZWZpeCkge1xuICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3ltYm9sXCIpIG5hbWUgPSBuYW1lLmRlc2NyaXB0aW9uID8gXCJbXCIuY29uY2F0KG5hbWUuZGVzY3JpcHRpb24sIFwiXVwiKSA6IFwiXCI7XG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoZiwgXCJuYW1lXCIsIHsgY29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogcHJlZml4ID8gXCJcIi5jb25jYXQocHJlZml4LCBcIiBcIiwgbmFtZSkgOiBuYW1lIH0pO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcbiAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcbiAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XG4gIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxuICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxuICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcbiAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZyA9IE9iamVjdC5jcmVhdGUoKHR5cGVvZiBJdGVyYXRvciA9PT0gXCJmdW5jdGlvblwiID8gSXRlcmF0b3IgOiBPYmplY3QpLnByb3RvdHlwZSk7XG4gIHJldHVybiBnLm5leHQgPSB2ZXJiKDApLCBnW1widGhyb3dcIl0gPSB2ZXJiKDEpLCBnW1wicmV0dXJuXCJdID0gdmVyYigyKSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xuICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cbiAgZnVuY3Rpb24gc3RlcChvcCkge1xuICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xuICAgICAgd2hpbGUgKGcgJiYgKGcgPSAwLCBvcFswXSAmJiAoXyA9IDApKSwgXykgdHJ5IHtcbiAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XG4gICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xuICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcbiAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XG4gICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcbiAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XG4gICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxuICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XG4gICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cbiAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xuICB9XG59XG5cbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG4gIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XG4gICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuICB9XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG59KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICBvW2syXSA9IG1ba107XG59KTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XG4gIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobywgcCkpIF9fY3JlYXRlQmluZGluZyhvLCBtLCBwKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcbiAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcbiAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XG4gIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcbiAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xuICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcbiAgICAgIH1cbiAgfTtcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcbiAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xuICBpZiAoIW0pIHJldHVybiBvO1xuICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcbiAgdHJ5IHtcbiAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xuICB9XG4gIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxuICBmaW5hbGx5IHtcbiAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XG4gICAgICB9XG4gICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cbiAgfVxuICByZXR1cm4gYXI7XG59XG5cbi8qKiBAZGVwcmVjYXRlZCAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xuICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcbiAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcbiAgcmV0dXJuIGFyO1xufVxuXG4vKiogQGRlcHJlY2F0ZWQgKi9cbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcbiAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XG4gIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcbiAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxuICAgICAgICAgIHJba10gPSBhW2pdO1xuICByZXR1cm4gcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20sIHBhY2spIHtcbiAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcbiAgICAgIGlmIChhciB8fCAhKGkgaW4gZnJvbSkpIHtcbiAgICAgICAgICBpZiAoIWFyKSBhciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20sIDAsIGkpO1xuICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcbiAgICAgIH1cbiAgfVxuICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xuICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XG4gIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XG4gIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XG4gIHJldHVybiBpID0gT2JqZWN0LmNyZWF0ZSgodHlwZW9mIEFzeW5jSXRlcmF0b3IgPT09IFwiZnVuY3Rpb25cIiA/IEFzeW5jSXRlcmF0b3IgOiBPYmplY3QpLnByb3RvdHlwZSksIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiwgYXdhaXRSZXR1cm4pLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XG4gIGZ1bmN0aW9uIGF3YWl0UmV0dXJuKGYpIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBQcm9taXNlLnJlc29sdmUodikudGhlbihmLCByZWplY3QpOyB9OyB9XG4gIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpZiAoZ1tuXSkgeyBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyBpZiAoZikgaVtuXSA9IGYoaVtuXSk7IH0gfVxuICBmdW5jdGlvbiByZXN1bWUobiwgdikgeyB0cnkgeyBzdGVwKGdbbl0odikpOyB9IGNhdGNoIChlKSB7IHNldHRsZShxWzBdWzNdLCBlKTsgfSB9XG4gIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxuICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XG4gIGZ1bmN0aW9uIHJlamVjdCh2YWx1ZSkgeyByZXN1bWUoXCJ0aHJvd1wiLCB2YWx1ZSk7IH1cbiAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XG4gIHZhciBpLCBwO1xuICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIsIGZ1bmN0aW9uIChlKSB7IHRocm93IGU7IH0pLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xuICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBmYWxzZSB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XG4gIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XG4gIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XG4gIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcbiAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxuICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xuICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxuICByZXR1cm4gY29va2VkO1xufTtcblxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgXCJkZWZhdWx0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHYgfSk7XG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcbiAgb1tcImRlZmF1bHRcIl0gPSB2O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcbiAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcbiAgdmFyIHJlc3VsdCA9IHt9O1xuICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoayAhPT0gXCJkZWZhdWx0XCIgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwgayk7XG4gIF9fc2V0TW9kdWxlRGVmYXVsdChyZXN1bHQsIG1vZCk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XG4gIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcbiAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRJbihzdGF0ZSwgcmVjZWl2ZXIpIHtcbiAgaWYgKHJlY2VpdmVyID09PSBudWxsIHx8ICh0eXBlb2YgcmVjZWl2ZXIgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlY2VpdmVyICE9PSBcImZ1bmN0aW9uXCIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHVzZSAnaW4nIG9wZXJhdG9yIG9uIG5vbi1vYmplY3RcIik7XG4gIHJldHVybiB0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyID09PSBzdGF0ZSA6IHN0YXRlLmhhcyhyZWNlaXZlcik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZShlbnYsIHZhbHVlLCBhc3luYykge1xuICBpZiAodmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09IHZvaWQgMCkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHZhbHVlICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3QgZXhwZWN0ZWQuXCIpO1xuICAgIHZhciBkaXNwb3NlLCBpbm5lcjtcbiAgICBpZiAoYXN5bmMpIHtcbiAgICAgIGlmICghU3ltYm9sLmFzeW5jRGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0Rpc3Bvc2UgaXMgbm90IGRlZmluZWQuXCIpO1xuICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5hc3luY0Rpc3Bvc2VdO1xuICAgIH1cbiAgICBpZiAoZGlzcG9zZSA9PT0gdm9pZCAwKSB7XG4gICAgICBpZiAoIVN5bWJvbC5kaXNwb3NlKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmRpc3Bvc2UgaXMgbm90IGRlZmluZWQuXCIpO1xuICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5kaXNwb3NlXTtcbiAgICAgIGlmIChhc3luYykgaW5uZXIgPSBkaXNwb3NlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGRpc3Bvc2UgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBub3QgZGlzcG9zYWJsZS5cIik7XG4gICAgaWYgKGlubmVyKSBkaXNwb3NlID0gZnVuY3Rpb24oKSB7IHRyeSB7IGlubmVyLmNhbGwodGhpcyk7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIFByb21pc2UucmVqZWN0KGUpOyB9IH07XG4gICAgZW52LnN0YWNrLnB1c2goeyB2YWx1ZTogdmFsdWUsIGRpc3Bvc2U6IGRpc3Bvc2UsIGFzeW5jOiBhc3luYyB9KTtcbiAgfVxuICBlbHNlIGlmIChhc3luYykge1xuICAgIGVudi5zdGFjay5wdXNoKHsgYXN5bmM6IHRydWUgfSk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG52YXIgX1N1cHByZXNzZWRFcnJvciA9IHR5cGVvZiBTdXBwcmVzc2VkRXJyb3IgPT09IFwiZnVuY3Rpb25cIiA/IFN1cHByZXNzZWRFcnJvciA6IGZ1bmN0aW9uIChlcnJvciwgc3VwcHJlc3NlZCwgbWVzc2FnZSkge1xuICB2YXIgZSA9IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgcmV0dXJuIGUubmFtZSA9IFwiU3VwcHJlc3NlZEVycm9yXCIsIGUuZXJyb3IgPSBlcnJvciwgZS5zdXBwcmVzc2VkID0gc3VwcHJlc3NlZCwgZTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2Rpc3Bvc2VSZXNvdXJjZXMoZW52KSB7XG4gIGZ1bmN0aW9uIGZhaWwoZSkge1xuICAgIGVudi5lcnJvciA9IGVudi5oYXNFcnJvciA/IG5ldyBfU3VwcHJlc3NlZEVycm9yKGUsIGVudi5lcnJvciwgXCJBbiBlcnJvciB3YXMgc3VwcHJlc3NlZCBkdXJpbmcgZGlzcG9zYWwuXCIpIDogZTtcbiAgICBlbnYuaGFzRXJyb3IgPSB0cnVlO1xuICB9XG4gIHZhciByLCBzID0gMDtcbiAgZnVuY3Rpb24gbmV4dCgpIHtcbiAgICB3aGlsZSAociA9IGVudi5zdGFjay5wb3AoKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCFyLmFzeW5jICYmIHMgPT09IDEpIHJldHVybiBzID0gMCwgZW52LnN0YWNrLnB1c2gociksIFByb21pc2UucmVzb2x2ZSgpLnRoZW4obmV4dCk7XG4gICAgICAgIGlmIChyLmRpc3Bvc2UpIHtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gci5kaXNwb3NlLmNhbGwoci52YWx1ZSk7XG4gICAgICAgICAgaWYgKHIuYXN5bmMpIHJldHVybiBzIHw9IDIsIFByb21pc2UucmVzb2x2ZShyZXN1bHQpLnRoZW4obmV4dCwgZnVuY3Rpb24oZSkgeyBmYWlsKGUpOyByZXR1cm4gbmV4dCgpOyB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHMgfD0gMTtcbiAgICAgIH1cbiAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgIGZhaWwoZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChzID09PSAxKSByZXR1cm4gZW52Lmhhc0Vycm9yID8gUHJvbWlzZS5yZWplY3QoZW52LmVycm9yKSA6IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIGlmIChlbnYuaGFzRXJyb3IpIHRocm93IGVudi5lcnJvcjtcbiAgfVxuICByZXR1cm4gbmV4dCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19yZXdyaXRlUmVsYXRpdmVJbXBvcnRFeHRlbnNpb24ocGF0aCwgcHJlc2VydmVKc3gpIHtcbiAgaWYgKHR5cGVvZiBwYXRoID09PSBcInN0cmluZ1wiICYmIC9eXFwuXFwuP1xcLy8udGVzdChwYXRoKSkge1xuICAgICAgcmV0dXJuIHBhdGgucmVwbGFjZSgvXFwuKHRzeCkkfCgoPzpcXC5kKT8pKCg/OlxcLlteLi9dKz8pPylcXC4oW2NtXT8pdHMkL2ksIGZ1bmN0aW9uIChtLCB0c3gsIGQsIGV4dCwgY20pIHtcbiAgICAgICAgICByZXR1cm4gdHN4ID8gcHJlc2VydmVKc3ggPyBcIi5qc3hcIiA6IFwiLmpzXCIgOiBkICYmICghZXh0IHx8ICFjbSkgPyBtIDogKGQgKyBleHQgKyBcIi5cIiArIGNtLnRvTG93ZXJDYXNlKCkgKyBcImpzXCIpO1xuICAgICAgfSk7XG4gIH1cbiAgcmV0dXJuIHBhdGg7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19leHRlbmRzLFxuICBfX2Fzc2lnbixcbiAgX19yZXN0LFxuICBfX2RlY29yYXRlLFxuICBfX3BhcmFtLFxuICBfX2VzRGVjb3JhdGUsXG4gIF9fcnVuSW5pdGlhbGl6ZXJzLFxuICBfX3Byb3BLZXksXG4gIF9fc2V0RnVuY3Rpb25OYW1lLFxuICBfX21ldGFkYXRhLFxuICBfX2F3YWl0ZXIsXG4gIF9fZ2VuZXJhdG9yLFxuICBfX2NyZWF0ZUJpbmRpbmcsXG4gIF9fZXhwb3J0U3RhcixcbiAgX192YWx1ZXMsXG4gIF9fcmVhZCxcbiAgX19zcHJlYWQsXG4gIF9fc3ByZWFkQXJyYXlzLFxuICBfX3NwcmVhZEFycmF5LFxuICBfX2F3YWl0LFxuICBfX2FzeW5jR2VuZXJhdG9yLFxuICBfX2FzeW5jRGVsZWdhdG9yLFxuICBfX2FzeW5jVmFsdWVzLFxuICBfX21ha2VUZW1wbGF0ZU9iamVjdCxcbiAgX19pbXBvcnRTdGFyLFxuICBfX2ltcG9ydERlZmF1bHQsXG4gIF9fY2xhc3NQcml2YXRlRmllbGRHZXQsXG4gIF9fY2xhc3NQcml2YXRlRmllbGRTZXQsXG4gIF9fY2xhc3NQcml2YXRlRmllbGRJbixcbiAgX19hZGREaXNwb3NhYmxlUmVzb3VyY2UsXG4gIF9fZGlzcG9zZVJlc291cmNlcyxcbiAgX19yZXdyaXRlUmVsYXRpdmVJbXBvcnRFeHRlbnNpb24sXG59O1xuIiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHQvLyBubyBtb2R1bGUuaWQgbmVlZGVkXG5cdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXShtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIi8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSAobW9kdWxlKSA9PiB7XG5cdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuXHRcdCgpID0+IChtb2R1bGVbJ2RlZmF1bHQnXSkgOlxuXHRcdCgpID0+IChtb2R1bGUpO1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCB7IGE6IGdldHRlciB9KTtcblx0cmV0dXJuIGdldHRlcjtcbn07IiwidmFyIGdldFByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mID8gKG9iaikgPT4gKE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopKSA6IChvYmopID0+IChvYmouX19wcm90b19fKTtcbnZhciBsZWFmUHJvdG90eXBlcztcbi8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuLy8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4vLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbi8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuLy8gbW9kZSAmIDE2OiByZXR1cm4gdmFsdWUgd2hlbiBpdCdzIFByb21pc2UtbGlrZVxuLy8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuX193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcblx0aWYobW9kZSAmIDEpIHZhbHVlID0gdGhpcyh2YWx1ZSk7XG5cdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG5cdGlmKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUpIHtcblx0XHRpZigobW9kZSAmIDQpICYmIHZhbHVlLl9fZXNNb2R1bGUpIHJldHVybiB2YWx1ZTtcblx0XHRpZigobW9kZSAmIDE2KSAmJiB0eXBlb2YgdmFsdWUudGhlbiA9PT0gJ2Z1bmN0aW9uJykgcmV0dXJuIHZhbHVlO1xuXHR9XG5cdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG5cdHZhciBkZWYgPSB7fTtcblx0bGVhZlByb3RvdHlwZXMgPSBsZWFmUHJvdG90eXBlcyB8fCBbbnVsbCwgZ2V0UHJvdG8oe30pLCBnZXRQcm90byhbXSksIGdldFByb3RvKGdldFByb3RvKV07XG5cdGZvcih2YXIgY3VycmVudCA9IG1vZGUgJiAyICYmIHZhbHVlOyB0eXBlb2YgY3VycmVudCA9PSAnb2JqZWN0JyAmJiAhfmxlYWZQcm90b3R5cGVzLmluZGV4T2YoY3VycmVudCk7IGN1cnJlbnQgPSBnZXRQcm90byhjdXJyZW50KSkge1xuXHRcdE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGN1cnJlbnQpLmZvckVhY2goKGtleSkgPT4gKGRlZltrZXldID0gKCkgPT4gKHZhbHVlW2tleV0pKSk7XG5cdH1cblx0ZGVmWydkZWZhdWx0J10gPSAoKSA9PiAodmFsdWUpO1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQobnMsIGRlZik7XG5cdHJldHVybiBucztcbn07IiwiLy8gZGVmaW5lIGdldHRlciBmdW5jdGlvbnMgZm9yIGhhcm1vbnkgZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5kID0gKGV4cG9ydHMsIGRlZmluaXRpb24pID0+IHtcblx0Zm9yKHZhciBrZXkgaW4gZGVmaW5pdGlvbikge1xuXHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhkZWZpbml0aW9uLCBrZXkpICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywga2V5KSkge1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIGtleSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGRlZmluaXRpb25ba2V5XSB9KTtcblx0XHR9XG5cdH1cbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5nID0gKGZ1bmN0aW9uKCkge1xuXHRpZiAodHlwZW9mIGdsb2JhbFRoaXMgPT09ICdvYmplY3QnKSByZXR1cm4gZ2xvYmFsVGhpcztcblx0dHJ5IHtcblx0XHRyZXR1cm4gdGhpcyB8fCBuZXcgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JykgcmV0dXJuIHdpbmRvdztcblx0fVxufSkoKTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gKGV4cG9ydHMpID0+IHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiaW1wb3J0ICogYXMgbG9hZGVycyBmcm9tIFwiQGx0cy9sb2FkZXJzL2xlZ2FjeS9sZWdhY3ktZ2xURjJGaWxlTG9hZGVyXCI7XHJcbmV4cG9ydCB7IGxvYWRlcnMgfTtcclxuZXhwb3J0IGRlZmF1bHQgbG9hZGVycztcclxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/libs/babylonjs/7.35.0/babylon.glTF2FileLoader.min.js b/libs/babylonjs/7.35.0/babylon.glTF2FileLoader.min.js new file mode 100644 index 00000000..5d00f254 --- /dev/null +++ b/libs/babylonjs/7.35.0/babylon.glTF2FileLoader.min.js @@ -0,0 +1,2 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("babylonjs")):"function"==typeof define&&define.amd?define("babylonjs-loaders",["babylonjs"],t):"object"==typeof exports?exports["babylonjs-loaders"]=t(require("babylonjs")):e.LOADERS=t(e.BABYLON)}("undefined"!=typeof self?self:"undefined"!=typeof global?global:this,(e=>(()=>{"use strict";var t,n,r={597:t=>{t.exports=e}},o={};function a(e){var t=o[e];if(void 0!==t)return t.exports;var n=o[e]={exports:{}};return r[e](n,n.exports,a),n.exports}n=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,a.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var o=Object.create(null);a.r(o);var i={};t=t||[null,n({}),n([]),n(n)];for(var s=2&r&&e;"object"==typeof s&&!~t.indexOf(s);s=n(s))Object.getOwnPropertyNames(s).forEach((t=>i[t]=()=>e[t]));return i.default=()=>e,a.d(o,i),o},a.d=(e,t)=>{for(var n in t)a.o(t,n)&&!a.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var i={};a.d(i,{default:()=>Mt});var s={};a.r(s),a.d(s,{GLTFValidation:()=>w});var l={};a.r(l),a.d(l,{GLTFFileLoader:()=>E,GLTFLoaderAnimationStartMode:()=>T,GLTFLoaderCoordinateSystemMode:()=>A,GLTFLoaderState:()=>x});var c={};a.r(c),a.d(c,{EXT_lights_image_based:()=>q,EXT_mesh_gpu_instancing:()=>W,EXT_meshopt_compression:()=>z,EXT_texture_avif:()=>$,EXT_texture_webp:()=>Q,ExtrasAsMetadata:()=>Tt,KHR_animation_pointer:()=>nt,KHR_draco_mesh_compression:()=>te,KHR_interactivity:()=>vt,KHR_lights:()=>re,KHR_materials_anisotropy:()=>fe,KHR_materials_clearcoat:()=>ce,KHR_materials_diffuse_transmission:()=>Le,KHR_materials_dispersion:()=>Pe,KHR_materials_emissive_strength:()=>_e,KHR_materials_ior:()=>Ae,KHR_materials_iridescence:()=>de,KHR_materials_pbrSpecularGlossiness:()=>ae,KHR_materials_sheen:()=>ye,KHR_materials_specular:()=>be,KHR_materials_transmission:()=>Ce,KHR_materials_unlit:()=>se,KHR_materials_variants:()=>xe,KHR_materials_volume:()=>Re,KHR_mesh_quantization:()=>Ie,KHR_node_visibility:()=>gt,KHR_texture_basisu:()=>Be,KHR_texture_transform:()=>Ge,KHR_xmp_json_ld:()=>Ve,MSFT_audio_emitter:()=>ot,MSFT_lod:()=>it,MSFT_minecraftMesh:()=>lt,MSFT_sRGBFactors:()=>ut});var u={};a.r(u);var d={};a.r(d),a.d(d,{ArrayItem:()=>K,EXT_lights_image_based:()=>q,EXT_mesh_gpu_instancing:()=>W,EXT_meshopt_compression:()=>z,EXT_texture_avif:()=>$,EXT_texture_webp:()=>Q,ExtrasAsMetadata:()=>Tt,GLTFFileLoader:()=>E,GLTFLoader:()=>H,KHR_animation_pointer:()=>nt,KHR_draco_mesh_compression:()=>te,KHR_interactivity:()=>vt,KHR_lights:()=>re,KHR_materials_anisotropy:()=>fe,KHR_materials_clearcoat:()=>ce,KHR_materials_diffuse_transmission:()=>Le,KHR_materials_dispersion:()=>Pe,KHR_materials_emissive_strength:()=>_e,KHR_materials_ior:()=>Ae,KHR_materials_iridescence:()=>de,KHR_materials_pbrSpecularGlossiness:()=>ae,KHR_materials_sheen:()=>ye,KHR_materials_specular:()=>be,KHR_materials_transmission:()=>Ce,KHR_materials_unlit:()=>se,KHR_materials_variants:()=>xe,KHR_materials_volume:()=>Re,KHR_mesh_quantization:()=>Ie,KHR_node_visibility:()=>gt,KHR_texture_basisu:()=>Be,KHR_texture_transform:()=>Ge,KHR_xmp_json_ld:()=>Ve,MSFT_audio_emitter:()=>ot,MSFT_lod:()=>it,MSFT_minecraftMesh:()=>lt,MSFT_sRGBFactors:()=>ut,registerGLTFExtension:()=>D,registeredGLTFExtensions:()=>G,unregisterGLTFExtension:()=>V});var h={};a.r(h),a.d(h,{GLTF2:()=>d,GLTFFileLoader:()=>E,GLTFLoaderAnimationStartMode:()=>T,GLTFLoaderCoordinateSystemMode:()=>A,GLTFLoaderState:()=>x,GLTFValidation:()=>w});var f=function(e,t){return f=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},f(e,t)};function p(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}f(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var _=function(){return _=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])||6!==s[0]&&2!==s[0])){a=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]=e.byteLength)throw new RangeError("Offset is out of range.");if(t+n>e.byteLength)throw new RangeError("Length is out of range.");return Promise.resolve(new Uint8Array(e.buffer,e.byteOffset+t,n))}catch(e){return Promise.reject(e)}}(t,e,n)},byteLength:t.byteLength})).then((function(e){r(e)}),o?function(e){return o(void 0,e)}:void 0)},t.prototype.importMeshAsync=function(e,t,n,r,o,a){var i=this;return Promise.resolve().then((function(){return i.onParsedObservable.notifyObservers(n),i.onParsedObservable.clear(),i._log("Loading ".concat(a||"")),i._loader=i._getLoader(n),i._loader.importMeshAsync(e,t,null,n,r,o,a)}))},t.prototype.loadAsync=function(e,t,n,r,o){var a=this;return Promise.resolve().then((function(){return a.onParsedObservable.notifyObservers(t),a.onParsedObservable.clear(),a._log("Loading ".concat(o||"")),a._loader=a._getLoader(t),a._loader.loadAsync(e,t,n,r,o)}))},t.prototype.loadAssetContainerAsync=function(e,t,n,r,o){var a=this;return Promise.resolve().then((function(){a.onParsedObservable.notifyObservers(t),a.onParsedObservable.clear(),a._log("Loading ".concat(o||"")),a._loader=a._getLoader(t);var i=new v.AssetContainer(e),s=[];a.onMaterialLoadedObservable.add((function(e){s.push(e)}));var l=[];a.onTextureLoadedObservable.add((function(e){l.push(e)}));var c=[];a.onCameraLoadedObservable.add((function(e){c.push(e)}));var u=[];return a.onMeshLoadedObservable.add((function(e){e.morphTargetManager&&u.push(e.morphTargetManager)})),a._loader.importMeshAsync(null,e,i,t,n,r,o).then((function(e){return Array.prototype.push.apply(i.geometries,e.geometries),Array.prototype.push.apply(i.meshes,e.meshes),Array.prototype.push.apply(i.particleSystems,e.particleSystems),Array.prototype.push.apply(i.skeletons,e.skeletons),Array.prototype.push.apply(i.animationGroups,e.animationGroups),Array.prototype.push.apply(i.materials,s),Array.prototype.push.apply(i.textures,l),Array.prototype.push.apply(i.lights,e.lights),Array.prototype.push.apply(i.transformNodes,e.transformNodes),Array.prototype.push.apply(i.cameras,c),Array.prototype.push.apply(i.morphTargetManagers,u),i}))}))},t.prototype.canDirectLoad=function(e){return function(e){return-1!==e.indexOf("asset")&&-1!==e.indexOf("version")||e.startsWith("data:base64,"+O)||e.startsWith("data:;base64,"+O)||e.startsWith("data:application/octet-stream;base64,"+O)||e.startsWith("data:model/gltf-binary;base64,"+O)}(e)},t.prototype.directLoad=function(e,t){if(t.startsWith("base64,"+O)||t.startsWith(";base64,"+O)||t.startsWith("application/octet-stream;base64,"+O)||t.startsWith("model/gltf-binary;base64,"+O)){var n=(0,v.DecodeBase64UrlToBinary)(t);return this._validate(e,new Uint8Array(n,0,n.byteLength)),this._unpackBinaryAsync(new v.DataReader({readAsync:function(e,t){return L(n,e,t)},byteLength:n.byteLength}))}return this._validate(e,t),Promise.resolve({json:this._parseJson(t)})},t.prototype.createPlugin=function(e){return new t(e[C])},Object.defineProperty(t.prototype,"loaderState",{get:function(){return this._state},enumerable:!1,configurable:!0}),t.prototype.whenCompleteAsync=function(){var e=this;return new Promise((function(t,n){e.onCompleteObservable.addOnce((function(){t()})),e.onErrorObservable.addOnce((function(e){n(e)}))}))},t.prototype._setState=function(e){this._state!==e&&(this._state=e,this.onLoaderStateChangedObservable.notifyObservers(this._state),this._log(x[this._state]))},t.prototype._loadFile=function(e,t,n,r,o,a){var i=this,s=e._loadFile(t,n,(function(e){i._onProgress(e,s)}),!0,r,o,a);return s.onCompleteObservable.add((function(){s._lengthComputable=!0,s._total=s._loaded})),this._requests.push(s),s},t.prototype._onProgress=function(e,t){if(this._progressCallback){t._lengthComputable=e.lengthComputable,t._loaded=e.loaded,t._total=e.total;for(var n=!0,r=0,o=0,a=0,i=this._requests;a0)throw new Error("Incompatible minimum version: "+n.minVersion)}var a={1:t._CreateGLTF1Loader,2:t._CreateGLTF2Loader}[r.major];if(!a)throw new Error("Unsupported version: "+n.version);return a(this)},t.prototype._parseJson=function(e){this._startPerformanceCounter("Parse JSON"),this._log("JSON length: ".concat(e.length));var t=JSON.parse(e);return this._endPerformanceCounter("Parse JSON"),t},t.prototype._unpackBinaryAsync=function(e){var t=this;return this._startPerformanceCounter("Unpack Binary"),e.loadAsync(20).then((function(){var n=e.readUint32();if(1179937895!==n)throw new v.RuntimeError("Unexpected magic: "+n,v.ErrorCodes.GLTFLoaderUnexpectedMagicError);var r=e.readUint32();t.loggingEnabled&&t._log("Binary version: ".concat(r));var o,a=e.readUint32();switch(t.useRangeRequests||a===e.buffer.byteLength||v.Logger.Warn("Length in header does not match actual data length: ".concat(a," != ").concat(e.buffer.byteLength)),r){case 1:o=t._unpackBinaryV1Async(e,a);break;case 2:o=t._unpackBinaryV2Async(e,a);break;default:throw new Error("Unsupported version: "+r)}return t._endPerformanceCounter("Unpack Binary"),o}))},t.prototype._unpackBinaryV1Async=function(e,t){var n=e.readUint32(),r=e.readUint32();if(0!==r)throw new Error("Unexpected content format: ".concat(r));var o=t-e.byteOffset,a={json:this._parseJson(e.readString(n)),bin:null};if(0!==o){var i=e.byteOffset;a.bin={readAsync:function(t,n){return e.buffer.readAsync(i+t,n)},byteLength:o}}return Promise.resolve(a)},t.prototype._unpackBinaryV2Async=function(e,t){var n=this,r=1313821514,o=e.readUint32();if(e.readUint32()!==r)throw new Error("First chunk format is not JSON");return e.byteOffset+o===t?e.loadAsync(o).then((function(){return{json:n._parseJson(e.readString(o)),bin:null}})):e.loadAsync(o+8).then((function(){var a={json:n._parseJson(e.readString(o)),bin:null},i=function(){var n=e.readUint32();switch(e.readUint32()){case r:throw new Error("Unexpected JSON chunk");case 5130562:var o=e.byteOffset;a.bin={readAsync:function(t,n){return e.buffer.readAsync(o+t,n)},byteLength:n},e.skipBytes(n);break;default:e.skipBytes(n)}return e.byteOffset!==t?e.loadAsync(8).then(i):Promise.resolve(a)};return i()}))},t._parseVersion=function(e){if("1.0"===e||"1.0.1"===e)return{major:1,minor:0};var t=(e+"").match(/^(\d+)\.(\d+)/);return t?{major:parseInt(t[1]),minor:parseInt(t[2])}:null},t._compareVersion=function(e,t){return e.major>t.major?1:e.majort.minor?1:e.minor ").concat(x[x.READY]),a="".concat(x[x.LOADING]," => ").concat(x[x.COMPLETE]),this._parent._startPerformanceCounter(o),this._parent._startPerformanceCounter(a),this._parent._setState(x.LOADING),this._extensionsOnLoading(),i=new Array,s=this._babylonScene.blockMaterialDirtyMechanism,this._babylonScene.blockMaterialDirtyMechanism=!0,this.parent.loadOnlyMaterials||(n?i.push(this.loadSceneAsync("/nodes",{nodes:n,index:-1})):(null!=this._gltf.scene||this._gltf.scenes&&this._gltf.scenes[0])&&(l=K.Get("/scene",this._gltf.scenes,this._gltf.scene||0),i.push(this.loadSceneAsync("/scenes/".concat(l.index),l)))),!this.parent.skipMaterials&&this.parent.loadAllMaterials&&this._gltf.materials)for(c=0;ce.bin.byteLength)&&v.Logger.Warn("Binary buffer length (".concat(n.byteLength,") from JSON does not match chunk length (").concat(e.bin.byteLength,")")),this._bin=e.bin}else v.Logger.Warn("Unexpected BIN chunk")}},e.prototype._setupData=function(){if(K.Assign(this._gltf.accessors),K.Assign(this._gltf.animations),K.Assign(this._gltf.buffers),K.Assign(this._gltf.bufferViews),K.Assign(this._gltf.cameras),K.Assign(this._gltf.images),K.Assign(this._gltf.materials),K.Assign(this._gltf.meshes),K.Assign(this._gltf.nodes),K.Assign(this._gltf.samplers),K.Assign(this._gltf.scenes),K.Assign(this._gltf.skins),K.Assign(this._gltf.textures),this._gltf.nodes){for(var e={},t=0,n=this._gltf.nodes;t=(i=n[t[0]]).length)return l;s=i[c];for(var u=1;u=(i=n[t[u]]).length||s!==i[c])return l;l=s}},e.prototype._loadBone=function(e,t,n,r){e._isJoint=!0;var o=r[e.index];if(o)return o;var a=null;e.index!==t.skeleton&&(e.parent&&-1!==e.parent.index?a=this._loadBone(e.parent,t,n,r):void 0!==t.skeleton&&v.Logger.Warn("/skins/".concat(t.index,"/skeleton: Skeleton node is not a common root")));var i=t.joints.indexOf(e.index);return o=new v.Bone(e.name||"joint".concat(e.index),n,a,this._getNodeMatrix(e),null,null,i),r[e.index]=o,this._postSceneLoadActions.push((function(){o.linkTransformNode(e._babylonTransformNode)})),o},e.prototype._loadSkinInverseBindMatricesDataAsync=function(e,t){if(null==t.inverseBindMatrices)return Promise.resolve(null);var n=K.Get("".concat(e,"/inverseBindMatrices"),this._gltf.accessors,t.inverseBindMatrices);return this._loadFloatAccessorAsync("/accessors/".concat(n.index),n)},e.prototype._updateBoneMatrices=function(e,t){for(var n=0,r=e.bones;n0){var A="".concat(n.name||"animation".concat(n.index),"_channel").concat(r.index,"_").concat(t);d.buildAnimations(l,A,i,_,(function(e,n){++t,a(e,n)}))}}}))},e.prototype._loadAnimationSamplerAsync=function(e,t){if(t._data)return t._data;var n=t.interpolation||"LINEAR";switch(n){case"STEP":case"LINEAR":case"CUBICSPLINE":break;default:throw new Error("".concat(e,"/interpolation: Invalid value (").concat(t.interpolation,")"))}var r=K.Get("".concat(e,"/input"),this._gltf.accessors,t.input),o=K.Get("".concat(e,"/output"),this._gltf.accessors,t.output);return t._data=Promise.all([this._loadFloatAccessorAsync("/accessors/".concat(r.index),r),this._loadFloatAccessorAsync("/accessors/".concat(o.index),o)]).then((function(e){var t=e[0],r=e[1];return{input:t,interpolation:n,output:r}})),t._data},e.prototype.loadBufferAsync=function(e,t,n,r){var o=this._extensionsLoadBufferAsync(e,t,n,r);if(o)return o;if(!t._data)if(t.uri)t._data=this.loadUriAsync("".concat(e,"/uri"),t,t.uri);else{if(!this._bin)throw new Error("".concat(e,": Uri is missing or the binary glTF is missing its binary chunk"));t._data=this._bin.readAsync(0,t.byteLength)}return t._data.then((function(t){try{return new Uint8Array(t.buffer,t.byteOffset+n,r)}catch(t){throw new Error("".concat(e,": ").concat(t.message))}}))},e.prototype.loadBufferViewAsync=function(e,t){var n=this._extensionsLoadBufferViewAsync(e,t);if(n)return n;if(t._data)return t._data;var r=K.Get("".concat(e,"/buffer"),this._gltf.buffers,t.buffer);return t._data=this.loadBufferAsync("/buffers/".concat(r.index),r,t.byteOffset||0,t.byteLength),t._data},e.prototype._loadAccessorAsync=function(t,n,r){var o=this;if(n._data)return n._data;var a=e._GetNumComponents(t,n.type),i=a*v.VertexBuffer.GetTypeByteLength(n.componentType),s=a*n.count;if(null==n.bufferView)n._data=Promise.resolve(new r(s));else{var l=K.Get("".concat(t,"/bufferView"),this._gltf.bufferViews,n.bufferView);n._data=this.loadBufferViewAsync("/bufferViews/".concat(l.index),l).then((function(o){if(5126!==n.componentType||n.normalized||l.byteStride&&l.byteStride!==i){var c=new r(s);return v.VertexBuffer.ForEach(o,n.byteOffset||0,l.byteStride||i,a,n.componentType,c.length,n.normalized||!1,(function(e,t){c[t]=e})),c}return e._GetTypedArray(t,n.componentType,o,n.byteOffset,s)}))}if(n.sparse){var c=n.sparse;n._data=n._data.then((function(s){var l=s,u=K.Get("".concat(t,"/sparse/indices/bufferView"),o._gltf.bufferViews,c.indices.bufferView),d=K.Get("".concat(t,"/sparse/values/bufferView"),o._gltf.bufferViews,c.values.bufferView);return Promise.all([o.loadBufferViewAsync("/bufferViews/".concat(u.index),u),o.loadBufferViewAsync("/bufferViews/".concat(d.index),d)]).then((function(o){var s,u=o[0],d=o[1],h=e._GetTypedArray("".concat(t,"/sparse/indices"),c.indices.componentType,u,c.indices.byteOffset,c.count),f=a*c.count;if(5126!==n.componentType||n.normalized){var p=e._GetTypedArray("".concat(t,"/sparse/values"),n.componentType,d,c.values.byteOffset,f);s=new r(f),v.VertexBuffer.ForEach(p,0,i,a,n.componentType,s.length,n.normalized||!1,(function(e,t){s[t]=e}))}else s=e._GetTypedArray("".concat(t,"/sparse/values"),n.componentType,d,c.values.byteOffset,f);for(var _=0,m=0;m=6)throw new Error("".concat(t,"/texCoord: Invalid value (").concat(n.texCoord,")"));var i=K.Get("".concat(t,"/index"),this._gltf.textures,n.index);i._textureInfo=n;var s=this._loadTextureAsync("/textures/".concat(n.index),i,(function(a){a.coordinatesIndex=n.texCoord||0,e.AddPointerMetadata(a,t),o._parent.onTextureLoadedObservable.notifyObservers(a),r(a)}));return this.logClose(),s},e.prototype._loadTextureAsync=function(t,n,r){void 0===r&&(r=function(){});var o=this._extensionsLoadTextureAsync(t,n,r);if(o)return o;this.logOpen("".concat(t," ").concat(n.name||""));var a=null==n.sampler?e.DefaultSampler:K.Get("".concat(t,"/sampler"),this._gltf.samplers,n.sampler),i=K.Get("".concat(t,"/source"),this._gltf.images,n.source),s=this._createTextureAsync(t,a,i,r,void 0,!n._textureInfo.nonColorData);return this.logClose(),s},e.prototype._createTextureAsync=function(e,t,n,r,o,a){var i=this;void 0===r&&(r=function(){});var s=this._loadSampler("/samplers/".concat(t.index),t),l=new Array,c=new v.Deferred;this._babylonScene._blockEntityCollection=!!this._assetContainer;var u={noMipmap:s.noMipMaps,invertY:!1,samplingMode:s.samplingMode,onLoad:function(){i._disposed||c.resolve()},onError:function(t,n){i._disposed||c.reject(new Error("".concat(e,": ").concat(n&&n.message?n.message:t||"Failed to load texture")))},mimeType:n.mimeType,loaderOptions:o,useSRGBBuffer:!!a&&this._parent.useSRGBBuffers},d=new v.Texture(null,this._babylonScene,u);return d._parentContainer=this._assetContainer,this._babylonScene._blockEntityCollection=!1,l.push(c.promise),l.push(this.loadImageAsync("/images/".concat(n.index),n).then((function(e){var t=n.uri||"".concat(i._fileName,"#image").concat(n.index),r="data:".concat(i._uniqueRootUrl).concat(t);d.updateURL(r,e);var o=d.getInternalTexture();o&&(o.label=n.name)}))),d.wrapU=s.wrapU,d.wrapV=s.wrapV,r(d),this._parent.useGltfTextureNames&&(d.name=n.name||n.uri||"image".concat(n.index)),Promise.all(l).then((function(){return d}))},e.prototype._loadSampler=function(t,n){return n._data||(n._data={noMipMaps:9728===n.minFilter||9729===n.minFilter,samplingMode:e._GetTextureSamplingMode(t,n),wrapU:e._GetTextureWrapMode("".concat(t,"/wrapS"),n.wrapS),wrapV:e._GetTextureWrapMode("".concat(t,"/wrapT"),n.wrapT)}),n._data},e.prototype.loadImageAsync=function(e,t){if(!t._data){if(this.logOpen("".concat(e," ").concat(t.name||"")),t.uri)t._data=this.loadUriAsync("".concat(e,"/uri"),t,t.uri);else{var n=K.Get("".concat(e,"/bufferView"),this._gltf.bufferViews,t.bufferView);t._data=this.loadBufferViewAsync("/bufferViews/".concat(n.index),n)}this.logClose()}return t._data},e.prototype.loadUriAsync=function(t,n,r){var o=this,a=this._extensionsLoadUriAsync(t,n,r);if(a)return a;if(!e._ValidateUri(r))throw new Error("".concat(t,": '").concat(r,"' is invalid"));if((0,v.IsBase64DataUrl)(r)){var i=new Uint8Array((0,v.DecodeBase64UrlToBinary)(r));return this.log("".concat(t,": Decoded ").concat(r.substring(0,64),"... (").concat(i.length," bytes)")),Promise.resolve(i)}return this.log("".concat(t,": Loading ").concat(r)),this._parent.preprocessUrlAsync(this._rootUrl+r).then((function(e){return new Promise((function(n,a){o._parent._loadFile(o._babylonScene,e,(function(e){o._disposed||(o.log("".concat(t,": Loaded ").concat(r," (").concat(e.byteLength," bytes)")),n(new Uint8Array(e)))}),!0,(function(e){a(new v.LoadFileError("".concat(t,": Failed to load '").concat(r,"'").concat(e?": "+e.status+" "+e.statusText:""),e))}))}))}))},e.AddPointerMetadata=function(e,t){e.metadata=e.metadata||{};var n=e._internalMetadata=e._internalMetadata||{},r=n.gltf=n.gltf||{};(r.pointers=r.pointers||[]).push(t)},e._GetTextureWrapMode=function(e,t){switch(t=null==t?10497:t){case 33071:return v.Texture.CLAMP_ADDRESSMODE;case 33648:return v.Texture.MIRROR_ADDRESSMODE;case 10497:return v.Texture.WRAP_ADDRESSMODE;default:return v.Logger.Warn("".concat(e,": Invalid value (").concat(t,")")),v.Texture.WRAP_ADDRESSMODE}},e._GetTextureSamplingMode=function(e,t){var n=null==t.magFilter?9729:t.magFilter,r=null==t.minFilter?9987:t.minFilter;if(9729===n)switch(r){case 9728:return v.Texture.LINEAR_NEAREST;case 9729:return v.Texture.LINEAR_LINEAR;case 9984:return v.Texture.LINEAR_NEAREST_MIPNEAREST;case 9985:return v.Texture.LINEAR_LINEAR_MIPNEAREST;case 9986:return v.Texture.LINEAR_NEAREST_MIPLINEAR;case 9987:return v.Texture.LINEAR_LINEAR_MIPLINEAR;default:return v.Logger.Warn("".concat(e,"/minFilter: Invalid value (").concat(r,")")),v.Texture.LINEAR_LINEAR_MIPLINEAR}else switch(9728!==n&&v.Logger.Warn("".concat(e,"/magFilter: Invalid value (").concat(n,")")),r){case 9728:return v.Texture.NEAREST_NEAREST;case 9729:return v.Texture.NEAREST_LINEAR;case 9984:return v.Texture.NEAREST_NEAREST_MIPNEAREST;case 9985:return v.Texture.NEAREST_LINEAR_MIPNEAREST;case 9986:return v.Texture.NEAREST_NEAREST_MIPLINEAR;case 9987:return v.Texture.NEAREST_LINEAR_MIPLINEAR;default:return v.Logger.Warn("".concat(e,"/minFilter: Invalid value (").concat(r,")")),v.Texture.NEAREST_NEAREST_MIPNEAREST}},e._GetTypedArrayConstructor=function(e,t){switch(t){case 5120:return Int8Array;case 5121:return Uint8Array;case 5122:return Int16Array;case 5123:return Uint16Array;case 5125:return Uint32Array;case 5126:return Float32Array;default:throw new Error("".concat(e,": Invalid component type ").concat(t))}},e._GetTypedArray=function(t,n,r,o,a){var i=r.buffer;o=r.byteOffset+(o||0);var s=e._GetTypedArrayConstructor("".concat(t,"/componentType"),n),l=v.VertexBuffer.GetTypeByteLength(n);return o%l!=0?(v.Logger.Warn("".concat(t,": Copying buffer as byte offset (").concat(o,") is not a multiple of component type byte length (").concat(l,")")),new s(i.slice(o,o+a*l),0)):new s(i,o,a)},e._GetNumComponents=function(e,t){switch(t){case"SCALAR":return 1;case"VEC2":return 2;case"VEC3":return 3;case"VEC4":case"MAT2":return 4;case"MAT3":return 9;case"MAT4":return 16}throw new Error("".concat(e,": Invalid type (").concat(t,")"))},e._ValidateUri=function(e){return v.Tools.IsBase64(e)||-1===e.indexOf("..")},e._GetDrawMode=function(e,t){switch(null==t&&(t=4),t){case 0:return v.Material.PointListDrawMode;case 1:return v.Material.LineListDrawMode;case 2:return v.Material.LineLoopDrawMode;case 3:return v.Material.LineStripDrawMode;case 4:return v.Material.TriangleFillMode;case 5:return v.Material.TriangleStripDrawMode;case 6:return v.Material.TriangleFanDrawMode}throw new Error("".concat(e,": Invalid mesh primitive mode (").concat(t,")"))},e.prototype._compileMaterialsAsync=function(){var e=this;this._parent._startPerformanceCounter("Compile materials");var t=new Array;if(this._gltf.materials)for(var n=0,r=this._gltf.materials;n=0;a--)if(o.push(K.Get("".concat(e,"/ids/").concat(r[a]),n,r[a])),o.length===this.maxLODsToLoad)return o;return o.push(t),o},e.prototype._disposeTransformNode=function(e){var t=this,n=[],r=e.material;r&&n.push(r);for(var o=0,a=e.getChildMeshes();o0){var n=e.metadata=e.metadata||{};(n.gltf=n.gltf||{}).extras=t.extras}},e.prototype.dispose=function(){this._loader=null},e.prototype.loadNodeAsync=function(e,t,n){var r=this;return this._loader.loadNodeAsync(e,t,(function(e){r._assignExtras(e,t),n(e)}))},e.prototype.loadCameraAsync=function(e,t,n){var r=this;return this._loader.loadCameraAsync(e,t,(function(e){r._assignExtras(e,t),n(e)}))},e.prototype.createMaterial=function(e,t,n){var r=this._loader.createMaterial(e,t,n);return this._assignExtras(r,t),r},e}();V(At),D(At,!1,(function(e){return new Tt(e)}));var xt=void 0!==a.g?a.g:"undefined"!=typeof window?window:void 0;if(void 0!==xt){xt.BABYLON=xt.BABYLON||{};var wt=xt.BABYLON;wt.GLTF2=wt.GLTF2||{},wt.GLTF2.Loader=wt.GLTF2.Loader||{},wt.GLTF2.Loader.Extensions=wt.GLTF2.Loader.Extensions||{};var Ot=[];for(var Ct in c)wt.GLTF2.Loader.Extensions[Ct]=c[Ct],Ot.push(Ct);for(var Ct in u)wt.GLTF2.Loader[Ct]=u[Ct],Ot.push(Ct);for(var Ct in d)Ot.indexOf(Ct)>-1||(wt.GLTF2[Ct]=d[Ct])}const Mt=h;return i.default})())); +//# sourceMappingURL=babylon.glTF2FileLoader.min.js.map \ No newline at end of file diff --git a/libs/babylonjs/7.35.0/babylon.glTF2Serializer.js b/libs/babylonjs/7.35.0/babylon.glTF2Serializer.js new file mode 100644 index 00000000..486df2d0 --- /dev/null +++ b/libs/babylonjs/7.35.0/babylon.glTF2Serializer.js @@ -0,0 +1,6474 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("babylonjs")); + else if(typeof define === 'function' && define.amd) + define("babylonjs-serializers", ["babylonjs"], factory); + else if(typeof exports === 'object') + exports["babylonjs-serializers"] = factory(require("babylonjs")); + else + root["SERIALIZERS"] = factory(root["BABYLON"]); +})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), (__WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__) => { +return /******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts": +/*!***********************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts ***! + \***********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_mesh_gpu_instancing: () => (/* binding */ EXT_mesh_gpu_instancing) +/* harmony export */ }); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Buffers/buffer */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__); + + + + + +var NAME = "EXT_mesh_gpu_instancing"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_mesh_gpu_instancing/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var EXT_mesh_gpu_instancing = /** @class */ (function () { + function EXT_mesh_gpu_instancing(exporter) { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._wasUsed = false; + this._exporter = exporter; + } + EXT_mesh_gpu_instancing.prototype.dispose = function () { }; + Object.defineProperty(EXT_mesh_gpu_instancing.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + /** + * After node is exported + * @param context the GLTF context when loading the asset + * @param node the node exported + * @param babylonNode the corresponding babylon node + * @param nodeMap map from babylon node id to node index + * @param binaryWriter binary writer + * @returns nullable promise, resolves with the node + */ + EXT_mesh_gpu_instancing.prototype.postExportNodeAsync = function (context, node, babylonNode, nodeMap, binaryWriter) { + var _this = this; + return new Promise(function (resolve) { + if (node && babylonNode instanceof babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__.Mesh) { + if (babylonNode.hasThinInstances && binaryWriter) { + _this._wasUsed = true; + var noTranslation = babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero(); + var noRotation = babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__.Quaternion.Identity(); + var noScale = babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__.Vector3.One(); + // retrieve all the instance world matrix + var matrix = babylonNode.thinInstanceGetWorldMatrices(); + var iwt = babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__.TmpVectors.Vector3[2]; + var iwr = babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__.TmpVectors.Quaternion[1]; + var iws = babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__.TmpVectors.Vector3[3]; + var hasAnyInstanceWorldTranslation = false; + var hasAnyInstanceWorldRotation = false; + var hasAnyInstanceWorldScale = false; + // prepare temp buffers + var translationBuffer = new Float32Array(babylonNode.thinInstanceCount * 3); + var rotationBuffer = new Float32Array(babylonNode.thinInstanceCount * 4); + var scaleBuffer = new Float32Array(babylonNode.thinInstanceCount * 3); + var i = 0; + for (var _i = 0, matrix_1 = matrix; _i < matrix_1.length; _i++) { + var m = matrix_1[_i]; + m.decompose(iws, iwr, iwt); + // fill the temp buffer + translationBuffer.set(iwt.asArray(), i * 3); + rotationBuffer.set(iwr.normalize().asArray(), i * 4); // ensure the quaternion is normalized + scaleBuffer.set(iws.asArray(), i * 3); + // this is where we decide if there is any transformation + hasAnyInstanceWorldTranslation = hasAnyInstanceWorldTranslation || !iwt.equalsWithEpsilon(noTranslation); + hasAnyInstanceWorldRotation = hasAnyInstanceWorldRotation || !iwr.equalsWithEpsilon(noRotation); + hasAnyInstanceWorldScale = hasAnyInstanceWorldScale || !iws.equalsWithEpsilon(noScale); + i++; + } + var extension = { + attributes: {}, + }; + // do we need to write TRANSLATION ? + if (hasAnyInstanceWorldTranslation) { + extension.attributes["TRANSLATION"] = _this._buildAccessor(translationBuffer, "VEC3" /* AccessorType.VEC3 */, babylonNode.thinInstanceCount, binaryWriter, 5126 /* AccessorComponentType.FLOAT */); + } + // do we need to write ROTATION ? + if (hasAnyInstanceWorldRotation) { + var componentType = 5126 /* AccessorComponentType.FLOAT */; // we decided to stay on FLOAT for now see https://github.com/BabylonJS/Babylon.js/pull/12495 + extension.attributes["ROTATION"] = _this._buildAccessor(rotationBuffer, "VEC4" /* AccessorType.VEC4 */, babylonNode.thinInstanceCount, binaryWriter, componentType); + } + // do we need to write SCALE ? + if (hasAnyInstanceWorldScale) { + extension.attributes["SCALE"] = _this._buildAccessor(scaleBuffer, "VEC3" /* AccessorType.VEC3 */, babylonNode.thinInstanceCount, binaryWriter, 5126 /* AccessorComponentType.FLOAT */); + } + /* eslint-enable @typescript-eslint/naming-convention*/ + node.extensions = node.extensions || {}; + node.extensions[NAME] = extension; + } + } + resolve(node); + }); + }; + EXT_mesh_gpu_instancing.prototype._buildAccessor = function (buffer, type, count, binaryWriter, componentType) { + // write the buffer + var bufferOffset = binaryWriter.getByteOffset(); + switch (componentType) { + case 5126 /* AccessorComponentType.FLOAT */: { + for (var i = 0; i != buffer.length; i++) { + binaryWriter.setFloat32(buffer[i]); + } + break; + } + case 5120 /* AccessorComponentType.BYTE */: { + for (var i = 0; i != buffer.length; i++) { + binaryWriter.setByte(buffer[i] * 127); + } + break; + } + case 5122 /* AccessorComponentType.SHORT */: { + for (var i = 0; i != buffer.length; i++) { + binaryWriter.setInt16(buffer[i] * 32767); + } + break; + } + } + // build the buffer view + var bv = { buffer: 0, byteOffset: bufferOffset, byteLength: buffer.length * babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__.VertexBuffer.GetTypeByteLength(componentType) }; + var bufferViewIndex = this._exporter._bufferViews.length; + this._exporter._bufferViews.push(bv); + // finally build the accessor + var accessorIndex = this._exporter._accessors.length; + var accessor = { + bufferView: bufferViewIndex, + componentType: componentType, + count: count, + type: type, + normalized: componentType == 5120 /* AccessorComponentType.BYTE */ || componentType == 5122 /* AccessorComponentType.SHORT */, + }; + this._exporter._accessors.push(accessor); + return accessorIndex; + }; + return EXT_mesh_gpu_instancing; +}()); + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +_glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter.RegisterExtension(NAME, function (exporter) { return new EXT_mesh_gpu_instancing(exporter); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_lights_punctual.ts": +/*!*******************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_lights_punctual.ts ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_lights_punctual: () => (/* binding */ KHR_lights_punctual) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); + + + + + + +var NAME = "KHR_lights_punctual"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_lights_punctual = /** @class */ (function () { + /** + * @internal + */ + function KHR_lights_punctual(exporter) { + /** The name of this extension. */ + this.name = NAME; + /** Defines whether this extension is enabled. */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._exporter = exporter; + } + /** @internal */ + KHR_lights_punctual.prototype.dispose = function () { + this._lights = null; + }; + Object.defineProperty(KHR_lights_punctual.prototype, "wasUsed", { + /** @internal */ + get: function () { + return !!this._lights; + }, + enumerable: false, + configurable: true + }); + /** @internal */ + KHR_lights_punctual.prototype.onExporting = function () { + this._exporter._glTF.extensions[NAME] = this._lights; + }; + /** + * Define this method to modify the default behavior when exporting a node + * @param context The context when exporting the node + * @param node glTF node + * @param babylonNode BabylonJS node + * @param nodeMap Node mapping of unique id to glTF node index + * @returns nullable INode promise + */ + KHR_lights_punctual.prototype.postExportNodeAsync = function (context, node, babylonNode, nodeMap) { + var _this = this; + return new Promise(function (resolve) { + if (node && babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.ShadowLight) { + var light = void 0; + var lightType = babylonNode.getTypeID() == babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Light.LIGHTTYPEID_POINTLIGHT + ? "point" /* KHRLightsPunctual_LightType.POINT */ + : babylonNode.getTypeID() == babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Light.LIGHTTYPEID_DIRECTIONALLIGHT + ? "directional" /* KHRLightsPunctual_LightType.DIRECTIONAL */ + : babylonNode.getTypeID() == babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Light.LIGHTTYPEID_SPOTLIGHT + ? "spot" /* KHRLightsPunctual_LightType.SPOT */ + : null; + if (lightType == null) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, ": Light ").concat(babylonNode.name, " is not supported in ").concat(NAME)); + } + else { + if (!babylonNode.position.equalsToFloats(0, 0, 0)) { + node.translation = babylonNode.position.asArray(); + } + if (lightType !== "point" /* KHRLightsPunctual_LightType.POINT */) { + var localAxis = babylonNode.direction; + var yaw = -Math.atan2(localAxis.z, localAxis.x) + Math.PI / 2; + var len = Math.sqrt(localAxis.x * localAxis.x + localAxis.z * localAxis.z); + var pitch = -Math.atan2(localAxis.y, len); + var lightRotationQuaternion = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.RotationYawPitchRoll(yaw + Math.PI, pitch, 0); + if (!babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.IsIdentity(lightRotationQuaternion)) { + node.rotation = lightRotationQuaternion.asArray(); + } + } + if (babylonNode.falloffType !== babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Light.FALLOFF_GLTF) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, ": Light falloff for ").concat(babylonNode.name, " does not match the ").concat(NAME, " specification!")); + } + light = { + type: lightType, + }; + if (!babylonNode.diffuse.equals(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.White())) { + light.color = babylonNode.diffuse.asArray(); + } + if (babylonNode.intensity !== 1.0) { + light.intensity = babylonNode.intensity; + } + if (babylonNode.range !== Number.MAX_VALUE) { + light.range = babylonNode.range; + } + if (lightType === "spot" /* KHRLightsPunctual_LightType.SPOT */) { + var babylonSpotLight = babylonNode; + if (babylonSpotLight.angle !== Math.PI / 2.0) { + if (light.spot == null) { + light.spot = {}; + } + light.spot.outerConeAngle = babylonSpotLight.angle / 2.0; + } + if (babylonSpotLight.innerAngle !== 0) { + if (light.spot == null) { + light.spot = {}; + } + light.spot.innerConeAngle = babylonSpotLight.innerAngle / 2.0; + } + } + _this._lights || (_this._lights = { + lights: [], + }); + _this._lights.lights.push(light); + var lightReference = { + light: _this._lights.lights.length - 1, + }; + // Avoid duplicating the Light's parent node if possible. + var parentBabylonNode = babylonNode.parent; + if (parentBabylonNode && parentBabylonNode.getChildren().length == 1) { + var parentNode = _this._exporter._nodes[nodeMap[parentBabylonNode.uniqueId]]; + if (parentNode) { + var parentTranslation = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArrayToRef(parentNode.translation || [0, 0, 0], 0, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[0]); + var parentRotation = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArrayToRef(parentNode.rotation || [0, 0, 0, 1], 0, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Quaternion[0]); + var parentScale = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArrayToRef(parentNode.scale || [1, 1, 1], 0, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[1]); + var parentMatrix = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Matrix.ComposeToRef(parentScale, parentRotation, parentTranslation, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Matrix[0]); + var translation = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArrayToRef(node.translation || [0, 0, 0], 0, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[2]); + var rotation = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArrayToRef(node.rotation || [0, 0, 0, 1], 0, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Quaternion[1]); + var matrix = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Matrix.ComposeToRef(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.OneReadOnly, rotation, translation, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Matrix[1]); + parentMatrix.multiplyToRef(matrix, matrix); + matrix.decompose(parentScale, parentRotation, parentTranslation); + if (parentTranslation.equalsToFloats(0, 0, 0)) { + delete parentNode.translation; + } + else { + parentNode.translation = parentTranslation.asArray(); + } + if (babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.IsIdentity(parentRotation)) { + delete parentNode.rotation; + } + else { + parentNode.rotation = parentRotation.asArray(); + } + if (parentScale.equalsToFloats(1, 1, 1)) { + delete parentNode.scale; + } + else { + parentNode.scale = parentScale.asArray(); + } + parentNode.extensions || (parentNode.extensions = {}); + parentNode.extensions[NAME] = lightReference; + // Do not export the original node + resolve(null); + return; + } + } + node.extensions || (node.extensions = {}); + node.extensions[NAME] = lightReference; + } + } + resolve(node); + }); + }; + return KHR_lights_punctual; +}()); + +_glTFExporter__WEBPACK_IMPORTED_MODULE_1__._Exporter.RegisterExtension(NAME, function (exporter) { return new KHR_lights_punctual(exporter); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts": +/*!************************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_anisotropy: () => (/* binding */ KHR_materials_anisotropy) +/* harmony export */ }); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrBaseMaterial */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__); + + +var NAME = "KHR_materials_anisotropy"; +/** + * @internal + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_anisotropy = /** @class */ (function () { + function KHR_materials_anisotropy(exporter) { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._wasUsed = false; + this._exporter = exporter; + } + KHR_materials_anisotropy.prototype.dispose = function () { }; + Object.defineProperty(KHR_materials_anisotropy.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + KHR_materials_anisotropy.prototype.postExportMaterialAdditionalTextures = function (context, node, babylonMaterial) { + var additionalTextures = []; + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRBaseMaterial) { + if (babylonMaterial.anisotropy.isEnabled && !babylonMaterial.anisotropy.legacy) { + if (babylonMaterial.anisotropy.texture) { + additionalTextures.push(babylonMaterial.anisotropy.texture); + } + return additionalTextures; + } + } + return []; + }; + KHR_materials_anisotropy.prototype.postExportMaterialAsync = function (context, node, babylonMaterial) { + var _this = this; + return new Promise(function (resolve) { + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRBaseMaterial) { + if (!babylonMaterial.anisotropy.isEnabled || babylonMaterial.anisotropy.legacy) { + resolve(node); + return; + } + _this._wasUsed = true; + node.extensions = node.extensions || {}; + var anisotropyTextureInfo = _this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.anisotropy.texture); + var anisotropyInfo_1 = { + anisotropyStrength: babylonMaterial.anisotropy.intensity, + anisotropyRotation: babylonMaterial.anisotropy.angle, + anisotropyTexture: anisotropyTextureInfo !== null && anisotropyTextureInfo !== void 0 ? anisotropyTextureInfo : undefined, + hasTextures: function () { + return anisotropyInfo_1.anisotropyTexture !== null; + }, + }; + node.extensions[NAME] = anisotropyInfo_1; + } + resolve(node); + }); + }; + return KHR_materials_anisotropy; +}()); + +_glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter.RegisterExtension(NAME, function (exporter) { return new KHR_materials_anisotropy(exporter); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts": +/*!***********************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts ***! + \***********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_clearcoat: () => (/* binding */ KHR_materials_clearcoat) +/* harmony export */ }); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__); + + + +var NAME = "KHR_materials_clearcoat"; +/** + * @internal + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_clearcoat = /** @class */ (function () { + function KHR_materials_clearcoat(exporter) { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._wasUsed = false; + this._exporter = exporter; + } + KHR_materials_clearcoat.prototype.dispose = function () { }; + Object.defineProperty(KHR_materials_clearcoat.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + KHR_materials_clearcoat.prototype.postExportMaterialAdditionalTextures = function (context, node, babylonMaterial) { + var additionalTextures = []; + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRBaseMaterial) { + if (babylonMaterial.clearCoat.isEnabled) { + if (babylonMaterial.clearCoat.texture) { + additionalTextures.push(babylonMaterial.clearCoat.texture); + } + if (!babylonMaterial.clearCoat.useRoughnessFromMainTexture && babylonMaterial.clearCoat.textureRoughness) { + additionalTextures.push(babylonMaterial.clearCoat.textureRoughness); + } + if (babylonMaterial.clearCoat.bumpTexture) { + additionalTextures.push(babylonMaterial.clearCoat.bumpTexture); + } + return additionalTextures; + } + } + return []; + }; + KHR_materials_clearcoat.prototype.postExportMaterialAsync = function (context, node, babylonMaterial) { + var _this = this; + return new Promise(function (resolve) { + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRBaseMaterial) { + if (!babylonMaterial.clearCoat.isEnabled) { + resolve(node); + return; + } + _this._wasUsed = true; + node.extensions = node.extensions || {}; + var clearCoatTextureInfo = _this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.clearCoat.texture); + var clearCoatTextureRoughnessInfo = void 0; + if (babylonMaterial.clearCoat.useRoughnessFromMainTexture) { + clearCoatTextureRoughnessInfo = _this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.clearCoat.texture); + } + else { + clearCoatTextureRoughnessInfo = _this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.clearCoat.textureRoughness); + } + if (babylonMaterial.clearCoat.isTintEnabled) { + babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__.Tools.Warn("Clear Color tint is not supported for glTF export. Ignoring for: ".concat(babylonMaterial.name)); + } + if (babylonMaterial.clearCoat.remapF0OnInterfaceChange) { + babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__.Tools.Warn("Clear Color F0 remapping is not supported for glTF export. Ignoring for: ".concat(babylonMaterial.name)); + } + var clearCoatNormalTextureInfo = _this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.clearCoat.bumpTexture); + var clearCoatInfo_1 = { + clearcoatFactor: babylonMaterial.clearCoat.intensity, + clearcoatTexture: clearCoatTextureInfo !== null && clearCoatTextureInfo !== void 0 ? clearCoatTextureInfo : undefined, + clearcoatRoughnessFactor: babylonMaterial.clearCoat.roughness, + clearcoatRoughnessTexture: clearCoatTextureRoughnessInfo !== null && clearCoatTextureRoughnessInfo !== void 0 ? clearCoatTextureRoughnessInfo : undefined, + clearcoatNormalTexture: clearCoatNormalTextureInfo !== null && clearCoatNormalTextureInfo !== void 0 ? clearCoatNormalTextureInfo : undefined, + hasTextures: function () { + return clearCoatInfo_1.clearcoatTexture !== null || clearCoatInfo_1.clearcoatRoughnessTexture !== null || clearCoatInfo_1.clearcoatRoughnessTexture !== null; + }, + }; + node.extensions[NAME] = clearCoatInfo_1; + } + resolve(node); + }); + }; + return KHR_materials_clearcoat; +}()); + +_glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter.RegisterExtension(NAME, function (exporter) { return new KHR_materials_clearcoat(exporter); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts": +/*!**********************************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts ***! + \**********************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_diffuse_transmission: () => (/* binding */ KHR_materials_diffuse_transmission) +/* harmony export */ }); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__); + + +var NAME = "KHR_materials_diffuse_transmission"; +/** + * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1825) + * !!! Experimental Extension Subject to Changes !!! + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_diffuse_transmission = /** @class */ (function () { + function KHR_materials_diffuse_transmission(exporter) { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._wasUsed = false; + this._exporter = exporter; + } + KHR_materials_diffuse_transmission.prototype.dispose = function () { }; + Object.defineProperty(KHR_materials_diffuse_transmission.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + /** + * After exporting a material, deal with additional textures + * @param context GLTF context of the material + * @param node exported GLTF node + * @param babylonMaterial corresponding babylon material + * @returns array of additional textures to export + */ + KHR_materials_diffuse_transmission.prototype.postExportMaterialAdditionalTextures = function (context, node, babylonMaterial) { + var additionalTextures = []; + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial) { + if (this._isExtensionEnabled(babylonMaterial)) { + if (babylonMaterial.subSurface.thicknessTexture) { + additionalTextures.push(babylonMaterial.subSurface.thicknessTexture); + } + return additionalTextures; + } + } + return additionalTextures; + }; + KHR_materials_diffuse_transmission.prototype._isExtensionEnabled = function (mat) { + // This extension must not be used on a material that also uses KHR_materials_unlit + if (mat.unlit) { + return false; + } + var subs = mat.subSurface; + if (!subs.isTranslucencyEnabled) { + return false; + } + return (!mat.unlit && + !subs.useAlbedoToTintTranslucency && + subs.useGltfStyleTextures && + subs.volumeIndexOfRefraction === 1 && + subs.minimumThickness === 0 && + subs.maximumThickness === 0); + }; + KHR_materials_diffuse_transmission.prototype._hasTexturesExtension = function (mat) { + return mat.subSurface.translucencyIntensityTexture != null || mat.subSurface.translucencyColorTexture != null; + }; + /** + * After exporting a material + * @param context GLTF context of the material + * @param node exported GLTF node + * @param babylonMaterial corresponding babylon material + * @returns promise that resolves with the updated node + */ + KHR_materials_diffuse_transmission.prototype.postExportMaterialAsync = function (context, node, babylonMaterial) { + var _this = this; + return new Promise(function (resolve) { + var _a, _b; + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial && _this._isExtensionEnabled(babylonMaterial)) { + _this._wasUsed = true; + var subs = babylonMaterial.subSurface; + var diffuseTransmissionFactor = subs.translucencyIntensity == 1 ? undefined : subs.translucencyIntensity; + var diffuseTransmissionTexture = (_a = _this._exporter._glTFMaterialExporter._getTextureInfo(subs.translucencyIntensityTexture)) !== null && _a !== void 0 ? _a : undefined; + var diffuseTransmissionColorFactor = !subs.translucencyColor || subs.translucencyColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : subs.translucencyColor.asArray(); + var diffuseTransmissionColorTexture = (_b = _this._exporter._glTFMaterialExporter._getTextureInfo(subs.translucencyColorTexture)) !== null && _b !== void 0 ? _b : undefined; + var diffuseTransmissionInfo = { + diffuseTransmissionFactor: diffuseTransmissionFactor, + diffuseTransmissionTexture: diffuseTransmissionTexture, + diffuseTransmissionColorFactor: diffuseTransmissionColorFactor, + diffuseTransmissionColorTexture: diffuseTransmissionColorTexture, + hasTextures: function () { + return _this._hasTexturesExtension(babylonMaterial); + }, + }; + node.extensions = node.extensions || {}; + node.extensions[NAME] = diffuseTransmissionInfo; + } + resolve(node); + }); + }; + return KHR_materials_diffuse_transmission; +}()); + +_glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter.RegisterExtension(NAME, function (exporter) { return new KHR_materials_diffuse_transmission(exporter); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts": +/*!************************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts ***! + \************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_dispersion: () => (/* binding */ KHR_materials_dispersion) +/* harmony export */ }); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__); + + +var NAME = "KHR_materials_dispersion"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/87bd64a7f5e23c84b6aef2e6082069583ed0ddb4/extensions/2.0/Khronos/KHR_materials_dispersion/README.md) + * @experimental + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_dispersion = /** @class */ (function () { + /** Constructor */ + function KHR_materials_dispersion() { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._wasUsed = false; + } + /** Dispose */ + KHR_materials_dispersion.prototype.dispose = function () { }; + Object.defineProperty(KHR_materials_dispersion.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + KHR_materials_dispersion.prototype._isExtensionEnabled = function (mat) { + // This extension must not be used on a material that also uses KHR_materials_unlit + if (mat.unlit) { + return false; + } + var subs = mat.subSurface; + // this extension requires refraction to be enabled. + if (!subs.isRefractionEnabled && !subs.isDispersionEnabled) { + return false; + } + return true; + }; + /** + * After exporting a material + * @param context GLTF context of the material + * @param node exported GLTF node + * @param babylonMaterial corresponding babylon material + * @returns promise, resolves with the material + */ + KHR_materials_dispersion.prototype.postExportMaterialAsync = function (context, node, babylonMaterial) { + var _this = this; + return new Promise(function (resolve) { + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial && _this._isExtensionEnabled(babylonMaterial)) { + _this._wasUsed = true; + var subs = babylonMaterial.subSurface; + var dispersion = subs.dispersion; + var dispersionInfo = { + dispersion: dispersion, + }; + node.extensions = node.extensions || {}; + node.extensions[NAME] = dispersionInfo; + } + resolve(node); + }); + }; + return KHR_materials_dispersion; +}()); + +_glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter.RegisterExtension(NAME, function () { return new KHR_materials_dispersion(); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_emissive_strength.ts": +/*!*******************************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_emissive_strength.ts ***! + \*******************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_emissive_strength: () => (/* binding */ KHR_materials_emissive_strength) +/* harmony export */ }); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__); + + +var NAME = "KHR_materials_emissive_strength"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_emissive_strength = /** @class */ (function () { + function KHR_materials_emissive_strength() { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._wasUsed = false; + } + /** Dispose */ + KHR_materials_emissive_strength.prototype.dispose = function () { }; + Object.defineProperty(KHR_materials_emissive_strength.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + /** + * After exporting a material + * @param context GLTF context of the material + * @param node exported GLTF node + * @param babylonMaterial corresponding babylon material + * @returns promise, resolves with the material + */ + KHR_materials_emissive_strength.prototype.postExportMaterialAsync = function (context, node, babylonMaterial) { + var _this = this; + return new Promise(function (resolve) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial)) { + return resolve(node); + } + var emissiveColor = babylonMaterial.emissiveColor.asArray(); + var tempEmissiveStrength = Math.max.apply(Math, emissiveColor); + if (tempEmissiveStrength > 1) { + _this._wasUsed = true; + node.extensions || (node.extensions = {}); + var emissiveStrengthInfo = { + emissiveStrength: tempEmissiveStrength, + }; + // Normalize each value of the emissive factor to have a max value of 1 + var newEmissiveFactor = babylonMaterial.emissiveColor.scale(1 / emissiveStrengthInfo.emissiveStrength); + node.emissiveFactor = newEmissiveFactor.asArray(); + node.extensions[NAME] = emissiveStrengthInfo; + } + return resolve(node); + }); + }; + return KHR_materials_emissive_strength; +}()); + +_glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter.RegisterExtension(NAME, function (exporter) { return new KHR_materials_emissive_strength(); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_ior.ts": +/*!*****************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_ior.ts ***! + \*****************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_ior: () => (/* binding */ KHR_materials_ior) +/* harmony export */ }); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__); + + +var NAME = "KHR_materials_ior"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_ior/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_ior = /** @class */ (function () { + function KHR_materials_ior() { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._wasUsed = false; + } + /** Dispose */ + KHR_materials_ior.prototype.dispose = function () { }; + Object.defineProperty(KHR_materials_ior.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + KHR_materials_ior.prototype._isExtensionEnabled = function (mat) { + // This extension must not be used on a material that also uses KHR_materials_unlit + if (mat.unlit) { + return false; + } + return mat.indexOfRefraction != undefined && mat.indexOfRefraction != 1.5; // 1.5 is normative default value. + }; + /** + * After exporting a material + * @param context GLTF context of the material + * @param node exported GLTF node + * @param babylonMaterial corresponding babylon material + * @returns promise, resolves with the material + */ + KHR_materials_ior.prototype.postExportMaterialAsync = function (context, node, babylonMaterial) { + var _this = this; + return new Promise(function (resolve) { + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial && _this._isExtensionEnabled(babylonMaterial)) { + _this._wasUsed = true; + var iorInfo = { + ior: babylonMaterial.indexOfRefraction, + }; + node.extensions = node.extensions || {}; + node.extensions[NAME] = iorInfo; + } + resolve(node); + }); + }; + return KHR_materials_ior; +}()); + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +_glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter.RegisterExtension(NAME, function (exporter) { return new KHR_materials_ior(); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_iridescence.ts": +/*!*************************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_iridescence.ts ***! + \*************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_iridescence: () => (/* binding */ KHR_materials_iridescence) +/* harmony export */ }); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrBaseMaterial */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__); + + +var NAME = "KHR_materials_iridescence"; +/** + * @internal + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_iridescence = /** @class */ (function () { + function KHR_materials_iridescence(exporter) { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._wasUsed = false; + this._exporter = exporter; + } + KHR_materials_iridescence.prototype.dispose = function () { }; + Object.defineProperty(KHR_materials_iridescence.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + KHR_materials_iridescence.prototype.postExportMaterialAdditionalTextures = function (context, node, babylonMaterial) { + var additionalTextures = []; + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRBaseMaterial) { + if (babylonMaterial.iridescence.isEnabled) { + if (babylonMaterial.iridescence.texture) { + additionalTextures.push(babylonMaterial.iridescence.texture); + } + if (babylonMaterial.iridescence.thicknessTexture && babylonMaterial.iridescence.thicknessTexture !== babylonMaterial.iridescence.texture) { + additionalTextures.push(babylonMaterial.iridescence.thicknessTexture); + } + return additionalTextures; + } + } + return []; + }; + KHR_materials_iridescence.prototype.postExportMaterialAsync = function (context, node, babylonMaterial) { + var _this = this; + return new Promise(function (resolve) { + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRBaseMaterial) { + if (!babylonMaterial.iridescence.isEnabled) { + resolve(node); + return; + } + _this._wasUsed = true; + node.extensions = node.extensions || {}; + var iridescenceTextureInfo = _this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.iridescence.texture); + var iridescenceThicknessTextureInfo = _this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.iridescence.thicknessTexture); + var iridescenceInfo_1 = { + iridescenceFactor: babylonMaterial.iridescence.intensity, + iridescenceIor: babylonMaterial.iridescence.indexOfRefraction, + iridescenceThicknessMinimum: babylonMaterial.iridescence.minimumThickness, + iridescenceThicknessMaximum: babylonMaterial.iridescence.maximumThickness, + iridescenceTexture: iridescenceTextureInfo !== null && iridescenceTextureInfo !== void 0 ? iridescenceTextureInfo : undefined, + iridescenceThicknessTexture: iridescenceThicknessTextureInfo !== null && iridescenceThicknessTextureInfo !== void 0 ? iridescenceThicknessTextureInfo : undefined, + hasTextures: function () { + return iridescenceInfo_1.iridescenceTexture !== null || iridescenceInfo_1.iridescenceThicknessTexture !== null; + }, + }; + node.extensions[NAME] = iridescenceInfo_1; + } + resolve(node); + }); + }; + return KHR_materials_iridescence; +}()); + +_glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter.RegisterExtension(NAME, function (exporter) { return new KHR_materials_iridescence(exporter); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_sheen.ts": +/*!*******************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_sheen.ts ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_sheen: () => (/* binding */ KHR_materials_sheen) +/* harmony export */ }); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__); + + +var NAME = "KHR_materials_sheen"; +/** + * @internal + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_sheen = /** @class */ (function () { + function KHR_materials_sheen(exporter) { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._wasUsed = false; + this._exporter = exporter; + } + KHR_materials_sheen.prototype.dispose = function () { }; + Object.defineProperty(KHR_materials_sheen.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + KHR_materials_sheen.prototype.postExportMaterialAdditionalTextures = function (context, node, babylonMaterial) { + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial) { + if (babylonMaterial.sheen.isEnabled && babylonMaterial.sheen.texture) { + return [babylonMaterial.sheen.texture]; + } + } + return []; + }; + KHR_materials_sheen.prototype.postExportMaterialAsync = function (context, node, babylonMaterial) { + var _this = this; + return new Promise(function (resolve) { + var _a, _b, _c, _d; + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial) { + if (!babylonMaterial.sheen.isEnabled) { + resolve(node); + return; + } + _this._wasUsed = true; + if (node.extensions == null) { + node.extensions = {}; + } + var sheenInfo_1 = { + sheenColorFactor: babylonMaterial.sheen.color.asArray(), + sheenRoughnessFactor: (_a = babylonMaterial.sheen.roughness) !== null && _a !== void 0 ? _a : 0, + hasTextures: function () { + return sheenInfo_1.sheenColorTexture !== null || sheenInfo_1.sheenRoughnessTexture !== null; + }, + }; + if (babylonMaterial.sheen.texture) { + sheenInfo_1.sheenColorTexture = (_b = _this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.sheen.texture)) !== null && _b !== void 0 ? _b : undefined; + } + if (babylonMaterial.sheen.textureRoughness && !babylonMaterial.sheen.useRoughnessFromMainTexture) { + sheenInfo_1.sheenRoughnessTexture = (_c = _this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.sheen.textureRoughness)) !== null && _c !== void 0 ? _c : undefined; + } + else if (babylonMaterial.sheen.texture && babylonMaterial.sheen.useRoughnessFromMainTexture) { + sheenInfo_1.sheenRoughnessTexture = (_d = _this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.sheen.texture)) !== null && _d !== void 0 ? _d : undefined; + } + node.extensions[NAME] = sheenInfo_1; + } + resolve(node); + }); + }; + return KHR_materials_sheen; +}()); + +_glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter.RegisterExtension(NAME, function (exporter) { return new KHR_materials_sheen(exporter); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_specular.ts": +/*!**********************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_specular.ts ***! + \**********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_specular: () => (/* binding */ KHR_materials_specular) +/* harmony export */ }); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__); + + +var NAME = "KHR_materials_specular"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_specular/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_specular = /** @class */ (function () { + function KHR_materials_specular(exporter) { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._wasUsed = false; + this._exporter = exporter; + } + /** Dispose */ + KHR_materials_specular.prototype.dispose = function () { }; + Object.defineProperty(KHR_materials_specular.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + /** + * After exporting a material, deal with the additional textures + * @param context GLTF context of the material + * @param node exported GLTF node + * @param babylonMaterial corresponding babylon material + * @returns array of additional textures to export + */ + KHR_materials_specular.prototype.postExportMaterialAdditionalTextures = function (context, node, babylonMaterial) { + var additionalTextures = []; + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial) { + if (this._isExtensionEnabled(babylonMaterial)) { + if (babylonMaterial.metallicReflectanceTexture) { + additionalTextures.push(babylonMaterial.metallicReflectanceTexture); + } + if (babylonMaterial.reflectanceTexture) { + additionalTextures.push(babylonMaterial.reflectanceTexture); + } + return additionalTextures; + } + } + return additionalTextures; + }; + KHR_materials_specular.prototype._isExtensionEnabled = function (mat) { + // This extension must not be used on a material that also uses KHR_materials_unlit + if (mat.unlit) { + return false; + } + return ((mat.metallicF0Factor != undefined && mat.metallicF0Factor != 1.0) || + (mat.metallicReflectanceColor != undefined && !mat.metallicReflectanceColor.equalsFloats(1.0, 1.0, 1.0)) || + this._hasTexturesExtension(mat)); + }; + KHR_materials_specular.prototype._hasTexturesExtension = function (mat) { + return mat.metallicReflectanceTexture != null || mat.reflectanceTexture != null; + }; + /** + * After exporting a material + * @param context GLTF context of the material + * @param node exported GLTF node + * @param babylonMaterial corresponding babylon material + * @returns promise, resolves with the material + */ + KHR_materials_specular.prototype.postExportMaterialAsync = function (context, node, babylonMaterial) { + var _this = this; + return new Promise(function (resolve) { + var _a, _b; + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial && _this._isExtensionEnabled(babylonMaterial)) { + _this._wasUsed = true; + node.extensions = node.extensions || {}; + var metallicReflectanceTexture = (_a = _this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.metallicReflectanceTexture)) !== null && _a !== void 0 ? _a : undefined; + var reflectanceTexture = (_b = _this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.reflectanceTexture)) !== null && _b !== void 0 ? _b : undefined; + var metallicF0Factor = babylonMaterial.metallicF0Factor == 1.0 ? undefined : babylonMaterial.metallicF0Factor; + var metallicReflectanceColor = babylonMaterial.metallicReflectanceColor.equalsFloats(1.0, 1.0, 1.0) + ? undefined + : babylonMaterial.metallicReflectanceColor.asArray(); + var specularInfo = { + specularFactor: metallicF0Factor, + specularTexture: metallicReflectanceTexture, + specularColorFactor: metallicReflectanceColor, + specularColorTexture: reflectanceTexture, + hasTextures: function () { + return _this._hasTexturesExtension(babylonMaterial); + }, + }; + node.extensions[NAME] = specularInfo; + } + resolve(node); + }); + }; + return KHR_materials_specular; +}()); + +_glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter.RegisterExtension(NAME, function (exporter) { return new KHR_materials_specular(exporter); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_transmission.ts": +/*!**************************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_transmission.ts ***! + \**************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_transmission: () => (/* binding */ KHR_materials_transmission) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__); + + + + +var NAME = "KHR_materials_transmission"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_transmission/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_transmission = /** @class */ (function () { + function KHR_materials_transmission(exporter) { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._wasUsed = false; + this._exporter = exporter; + } + /** Dispose */ + KHR_materials_transmission.prototype.dispose = function () { }; + Object.defineProperty(KHR_materials_transmission.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + /** + * After exporting a material, deal with additional textures + * @param context GLTF context of the material + * @param node exported GLTF node + * @param babylonMaterial corresponding babylon material + * @returns array of additional textures to export + */ + KHR_materials_transmission.prototype.postExportMaterialAdditionalTextures = function (context, node, babylonMaterial) { + var additionalTextures = []; + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial) { + if (this._isExtensionEnabled(babylonMaterial)) { + if (babylonMaterial.subSurface.thicknessTexture) { + additionalTextures.push(babylonMaterial.subSurface.thicknessTexture); + } + return additionalTextures; + } + } + return additionalTextures; + }; + KHR_materials_transmission.prototype._isExtensionEnabled = function (mat) { + // This extension must not be used on a material that also uses KHR_materials_unlit + if (mat.unlit) { + return false; + } + var subs = mat.subSurface; + return (subs.isRefractionEnabled && subs.refractionIntensity != undefined && subs.refractionIntensity != 0) || this._hasTexturesExtension(mat); + }; + KHR_materials_transmission.prototype._hasTexturesExtension = function (mat) { + return mat.subSurface.refractionIntensityTexture != null; + }; + /** + * After exporting a material + * @param context GLTF context of the material + * @param node exported GLTF node + * @param babylonMaterial corresponding babylon material + * @returns true if successful + */ + KHR_materials_transmission.prototype.postExportMaterialAsync = function (context, node, babylonMaterial) { + return (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__awaiter)(this, void 0, void 0, function () { + var subSurface, transmissionFactor, volumeInfo, transmissionTexture; + var _this = this; + return (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__generator)(this, function (_a) { + switch (_a.label) { + case 0: + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial && this._isExtensionEnabled(babylonMaterial))) return [3 /*break*/, 4]; + this._wasUsed = true; + subSurface = babylonMaterial.subSurface; + transmissionFactor = subSurface.refractionIntensity === 0 ? undefined : subSurface.refractionIntensity; + volumeInfo = { + transmissionFactor: transmissionFactor, + hasTextures: function () { + return _this._hasTexturesExtension(babylonMaterial); + }, + }; + if (!subSurface.refractionIntensityTexture) return [3 /*break*/, 3]; + if (!subSurface.useGltfStyleTextures) return [3 /*break*/, 2]; + return [4 /*yield*/, this._exporter._glTFMaterialExporter._exportTextureInfoAsync(subSurface.refractionIntensityTexture, "image/png" /* ImageMimeType.PNG */)]; + case 1: + transmissionTexture = _a.sent(); + if (transmissionTexture) { + volumeInfo.transmissionTexture = transmissionTexture; + } + return [3 /*break*/, 3]; + case 2: + babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.Logger.Warn("".concat(context, ": Exporting a subsurface refraction intensity texture without `useGltfStyleTextures` is not supported")); + _a.label = 3; + case 3: + node.extensions || (node.extensions = {}); + node.extensions[NAME] = volumeInfo; + _a.label = 4; + case 4: return [2 /*return*/, node]; + } + }); + }); + }; + return KHR_materials_transmission; +}()); + +_glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter.RegisterExtension(NAME, function (exporter) { return new KHR_materials_transmission(exporter); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_unlit.ts": +/*!*******************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_unlit.ts ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_unlit: () => (/* binding */ KHR_materials_unlit) +/* harmony export */ }); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/standardMaterial */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__); + + + +var NAME = "KHR_materials_unlit"; +/** + * @internal + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_unlit = /** @class */ (function () { + function KHR_materials_unlit() { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._wasUsed = false; + } + Object.defineProperty(KHR_materials_unlit.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + KHR_materials_unlit.prototype.dispose = function () { }; + KHR_materials_unlit.prototype.postExportMaterialAsync = function (context, node, babylonMaterial) { + var _this = this; + return new Promise(function (resolve) { + var unlitMaterial = false; + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial) { + unlitMaterial = babylonMaterial.unlit; + } + else if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.StandardMaterial) { + unlitMaterial = babylonMaterial.disableLighting; + } + if (unlitMaterial) { + _this._wasUsed = true; + if (node.extensions == null) { + node.extensions = {}; + } + node.extensions[NAME] = {}; + } + resolve(node); + }); + }; + return KHR_materials_unlit; +}()); + +_glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter.RegisterExtension(NAME, function () { return new KHR_materials_unlit(); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts": +/*!********************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts ***! + \********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_volume: () => (/* binding */ KHR_materials_volume) +/* harmony export */ }); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__); + + + +var NAME = "KHR_materials_volume"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_volume/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_volume = /** @class */ (function () { + function KHR_materials_volume(exporter) { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + this._wasUsed = false; + this._exporter = exporter; + } + KHR_materials_volume.prototype.dispose = function () { }; + Object.defineProperty(KHR_materials_volume.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + /** + * After exporting a material, deal with additional textures + * @param context GLTF context of the material + * @param node exported GLTF node + * @param babylonMaterial corresponding babylon material + * @returns array of additional textures to export + */ + KHR_materials_volume.prototype.postExportMaterialAdditionalTextures = function (context, node, babylonMaterial) { + var additionalTextures = []; + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial) { + if (this._isExtensionEnabled(babylonMaterial)) { + if (babylonMaterial.subSurface.thicknessTexture) { + additionalTextures.push(babylonMaterial.subSurface.thicknessTexture); + } + return additionalTextures; + } + } + return additionalTextures; + }; + KHR_materials_volume.prototype._isExtensionEnabled = function (mat) { + // This extension must not be used on a material that also uses KHR_materials_unlit + if (mat.unlit) { + return false; + } + var subs = mat.subSurface; + // this extension requires either the KHR_materials_transmission or KHR_materials_diffuse_transmission extensions. + if (!subs.isRefractionEnabled && !subs.isTranslucencyEnabled) { + return false; + } + return ((subs.maximumThickness != undefined && subs.maximumThickness != 0) || + (subs.tintColorAtDistance != undefined && subs.tintColorAtDistance != Number.POSITIVE_INFINITY) || + (subs.tintColor != undefined && subs.tintColor != babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.Color3.White()) || + this._hasTexturesExtension(mat)); + }; + KHR_materials_volume.prototype._hasTexturesExtension = function (mat) { + return mat.subSurface.thicknessTexture != null; + }; + /** + * After exporting a material + * @param context GLTF context of the material + * @param node exported GLTF node + * @param babylonMaterial corresponding babylon material + * @returns promise that resolves with the updated node + */ + KHR_materials_volume.prototype.postExportMaterialAsync = function (context, node, babylonMaterial) { + var _this = this; + return new Promise(function (resolve) { + var _a; + if (babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__.PBRMaterial && _this._isExtensionEnabled(babylonMaterial)) { + _this._wasUsed = true; + var subs = babylonMaterial.subSurface; + var thicknessFactor = subs.maximumThickness == 0 ? undefined : subs.maximumThickness; + var thicknessTexture = (_a = _this._exporter._glTFMaterialExporter._getTextureInfo(subs.thicknessTexture)) !== null && _a !== void 0 ? _a : undefined; + var attenuationDistance = subs.tintColorAtDistance == Number.POSITIVE_INFINITY ? undefined : subs.tintColorAtDistance; + var attenuationColor = subs.tintColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : subs.tintColor.asArray(); + var volumeInfo = { + thicknessFactor: thicknessFactor, + thicknessTexture: thicknessTexture, + attenuationDistance: attenuationDistance, + attenuationColor: attenuationColor, + hasTextures: function () { + return _this._hasTexturesExtension(babylonMaterial); + }, + }; + node.extensions = node.extensions || {}; + node.extensions[NAME] = volumeInfo; + } + resolve(node); + }); + }; + return KHR_materials_volume; +}()); + +_glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter.RegisterExtension(NAME, function (exporter) { return new KHR_materials_volume(exporter); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_texture_transform.ts": +/*!*********************************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/KHR_texture_transform.ts ***! + \*********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_texture_transform: () => (/* binding */ KHR_texture_transform) +/* harmony export */ }); +/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); + + +var NAME = "KHR_texture_transform"; +/** + * @internal + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_texture_transform = /** @class */ (function () { + function KHR_texture_transform() { + /** Name of this extension */ + this.name = NAME; + /** Defines whether this extension is enabled */ + this.enabled = true; + /** Defines whether this extension is required */ + this.required = false; + /** Reference to the glTF exporter */ + this._wasUsed = false; + } + KHR_texture_transform.prototype.dispose = function () { }; + Object.defineProperty(KHR_texture_transform.prototype, "wasUsed", { + /** @internal */ + get: function () { + return this._wasUsed; + }, + enumerable: false, + configurable: true + }); + KHR_texture_transform.prototype.postExportTexture = function (context, textureInfo, babylonTexture) { + var canUseExtension = babylonTexture && + ((babylonTexture.uAng === 0 && babylonTexture.wAng === 0 && babylonTexture.vAng === 0) || + (babylonTexture.uRotationCenter === 0 && babylonTexture.vRotationCenter === 0)); + if (canUseExtension) { + var textureTransform = {}; + var transformIsRequired = false; + if (babylonTexture.uOffset !== 0 || babylonTexture.vOffset !== 0) { + textureTransform.offset = [babylonTexture.uOffset, babylonTexture.vOffset]; + transformIsRequired = true; + } + if (babylonTexture.uScale !== 1 || babylonTexture.vScale !== 1) { + textureTransform.scale = [babylonTexture.uScale, babylonTexture.vScale]; + transformIsRequired = true; + } + if (babylonTexture.wAng !== 0) { + textureTransform.rotation = -babylonTexture.wAng; + transformIsRequired = true; + } + if (babylonTexture.coordinatesIndex !== 0) { + textureTransform.texCoord = babylonTexture.coordinatesIndex; + transformIsRequired = true; + } + if (!transformIsRequired) { + return; + } + this._wasUsed = true; + if (!textureInfo.extensions) { + textureInfo.extensions = {}; + } + textureInfo.extensions[NAME] = textureTransform; + } + }; + KHR_texture_transform.prototype.preExportTextureAsync = function (context, babylonTexture) { + return new Promise(function (resolve, reject) { + var scene = babylonTexture.getScene(); + if (!scene) { + reject("".concat(context, ": \"scene\" is not defined for Babylon texture ").concat(babylonTexture.name, "!")); + return; + } + /* + * The KHR_texture_transform schema only supports w rotation around the origin. + * See https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform#gltf-schema-updates. + */ + if (babylonTexture.uAng !== 0 || babylonTexture.vAng !== 0) { + babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("".concat(context, ": Texture ").concat(babylonTexture.name, " with rotation in the u or v axis is not supported in glTF.")); + resolve(null); + } + else if (babylonTexture.wAng !== 0 && (babylonTexture.uRotationCenter !== 0 || babylonTexture.vRotationCenter !== 0)) { + babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("".concat(context, ": Texture ").concat(babylonTexture.name, " with rotation not centered at the origin cannot be exported with ").concat(NAME)); + resolve(null); + } + else { + resolve(babylonTexture); + } + }); + }; + return KHR_texture_transform; +}()); + +_glTFExporter__WEBPACK_IMPORTED_MODULE_1__._Exporter.RegisterExtension(NAME, function () { return new KHR_texture_transform(); }); + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/Extensions/index.ts": +/*!*****************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/Extensions/index.ts ***! + \*****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_mesh_gpu_instancing: () => (/* reexport safe */ _EXT_mesh_gpu_instancing__WEBPACK_IMPORTED_MODULE_12__.EXT_mesh_gpu_instancing), +/* harmony export */ KHR_lights_punctual: () => (/* reexport safe */ _KHR_lights_punctual__WEBPACK_IMPORTED_MODULE_1__.KHR_lights_punctual), +/* harmony export */ KHR_materials_anisotropy: () => (/* reexport safe */ _KHR_materials_anisotropy__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_anisotropy), +/* harmony export */ KHR_materials_clearcoat: () => (/* reexport safe */ _KHR_materials_clearcoat__WEBPACK_IMPORTED_MODULE_2__.KHR_materials_clearcoat), +/* harmony export */ KHR_materials_diffuse_transmission: () => (/* reexport safe */ _KHR_materials_diffuse_transmission__WEBPACK_IMPORTED_MODULE_14__.KHR_materials_diffuse_transmission), +/* harmony export */ KHR_materials_dispersion: () => (/* reexport safe */ _KHR_materials_dispersion__WEBPACK_IMPORTED_MODULE_10__.KHR_materials_dispersion), +/* harmony export */ KHR_materials_emissive_strength: () => (/* reexport safe */ _KHR_materials_emissive_strength__WEBPACK_IMPORTED_MODULE_13__.KHR_materials_emissive_strength), +/* harmony export */ KHR_materials_ior: () => (/* reexport safe */ _KHR_materials_ior__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_ior), +/* harmony export */ KHR_materials_iridescence: () => (/* reexport safe */ _KHR_materials_iridescence__WEBPACK_IMPORTED_MODULE_3__.KHR_materials_iridescence), +/* harmony export */ KHR_materials_sheen: () => (/* reexport safe */ _KHR_materials_sheen__WEBPACK_IMPORTED_MODULE_5__.KHR_materials_sheen), +/* harmony export */ KHR_materials_specular: () => (/* reexport safe */ _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_8__.KHR_materials_specular), +/* harmony export */ KHR_materials_transmission: () => (/* reexport safe */ _KHR_materials_transmission__WEBPACK_IMPORTED_MODULE_11__.KHR_materials_transmission), +/* harmony export */ KHR_materials_unlit: () => (/* reexport safe */ _KHR_materials_unlit__WEBPACK_IMPORTED_MODULE_6__.KHR_materials_unlit), +/* harmony export */ KHR_materials_volume: () => (/* reexport safe */ _KHR_materials_volume__WEBPACK_IMPORTED_MODULE_9__.KHR_materials_volume), +/* harmony export */ KHR_texture_transform: () => (/* reexport safe */ _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_0__.KHR_texture_transform) +/* harmony export */ }); +/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./KHR_texture_transform */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_texture_transform.ts"); +/* harmony import */ var _KHR_lights_punctual__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./KHR_lights_punctual */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_lights_punctual.ts"); +/* harmony import */ var _KHR_materials_clearcoat__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./KHR_materials_clearcoat */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts"); +/* harmony import */ var _KHR_materials_iridescence__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./KHR_materials_iridescence */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_iridescence.ts"); +/* harmony import */ var _KHR_materials_anisotropy__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./KHR_materials_anisotropy */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts"); +/* harmony import */ var _KHR_materials_sheen__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./KHR_materials_sheen */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_sheen.ts"); +/* harmony import */ var _KHR_materials_unlit__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./KHR_materials_unlit */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_unlit.ts"); +/* harmony import */ var _KHR_materials_ior__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./KHR_materials_ior */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_ior.ts"); +/* harmony import */ var _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_materials_specular */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_specular.ts"); +/* harmony import */ var _KHR_materials_volume__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_materials_volume */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts"); +/* harmony import */ var _KHR_materials_dispersion__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./KHR_materials_dispersion */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts"); +/* harmony import */ var _KHR_materials_transmission__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./KHR_materials_transmission */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_transmission.ts"); +/* harmony import */ var _EXT_mesh_gpu_instancing__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./EXT_mesh_gpu_instancing */ "../../../dev/serializers/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts"); +/* harmony import */ var _KHR_materials_emissive_strength__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./KHR_materials_emissive_strength */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_emissive_strength.ts"); +/* harmony import */ var _KHR_materials_diffuse_transmission__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./KHR_materials_diffuse_transmission */ "../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts"); + + + + + + + + + + + + + + + + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/glTFAnimation.ts": +/*!**************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/glTFAnimation.ts ***! + \**************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ _GLTFAnimation: () => (/* binding */ _GLTFAnimation) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Lights/light */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./glTFUtilities */ "../../../dev/serializers/src/glTF/2.0/glTFUtilities.ts"); + + + + + + + + + +/** + * @internal + * Enum for handling in tangent and out tangent. + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var _TangentType; +(function (_TangentType) { + /** + * Specifies that input tangents are used. + */ + _TangentType[_TangentType["INTANGENT"] = 0] = "INTANGENT"; + /** + * Specifies that output tangents are used. + */ + _TangentType[_TangentType["OUTTANGENT"] = 1] = "OUTTANGENT"; +})(_TangentType || (_TangentType = {})); +/** + * @internal + * Utility class for generating glTF animation data from BabylonJS. + */ +var _GLTFAnimation = /** @class */ (function () { + function _GLTFAnimation() { + } + /** + * Determine if a node is transformable - ie has properties it should be part of animation of transformation. + * @param babylonNode the node to test + * @returns true if can be animated, false otherwise. False if the parameter is null or undefined. + */ + _GLTFAnimation._IsTransformable = function (babylonNode) { + return babylonNode && (babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TransformNode || babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Camera || babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Light); + }; + /** + * @ignore + * + * Creates glTF channel animation from BabylonJS animation. + * @param babylonTransformNode - BabylonJS mesh. + * @param animation - animation. + * @param animationChannelTargetPath - The target animation channel. + * @param useQuaternion - Specifies if quaternions are used. + * @returns nullable IAnimationData + */ + _GLTFAnimation._CreateNodeAnimation = function (babylonTransformNode, animation, animationChannelTargetPath, useQuaternion, animationSampleRate) { + if (this._IsTransformable(babylonTransformNode)) { + var inputs = []; + var outputs = []; + var keyFrames = animation.getKeys(); + var minMaxKeyFrames = _GLTFAnimation._CalculateMinMaxKeyFrames(keyFrames); + var interpolationOrBake = _GLTFAnimation._DeduceInterpolation(keyFrames, animationChannelTargetPath, useQuaternion); + var interpolation = interpolationOrBake.interpolationType; + var shouldBakeAnimation = interpolationOrBake.shouldBakeAnimation; + if (shouldBakeAnimation) { + _GLTFAnimation._CreateBakedAnimation(babylonTransformNode, animation, animationChannelTargetPath, minMaxKeyFrames.min, minMaxKeyFrames.max, animation.framePerSecond, animationSampleRate, inputs, outputs, minMaxKeyFrames, useQuaternion); + } + else { + if (interpolation === "LINEAR" /* AnimationSamplerInterpolation.LINEAR */ || interpolation === "STEP" /* AnimationSamplerInterpolation.STEP */) { + _GLTFAnimation._CreateLinearOrStepAnimation(babylonTransformNode, animation, animationChannelTargetPath, inputs, outputs, useQuaternion); + } + else if (interpolation === "CUBICSPLINE" /* AnimationSamplerInterpolation.CUBICSPLINE */) { + _GLTFAnimation._CreateCubicSplineAnimation(babylonTransformNode, animation, animationChannelTargetPath, inputs, outputs, useQuaternion); + } + else { + _GLTFAnimation._CreateBakedAnimation(babylonTransformNode, animation, animationChannelTargetPath, minMaxKeyFrames.min, minMaxKeyFrames.max, animation.framePerSecond, animationSampleRate, inputs, outputs, minMaxKeyFrames, useQuaternion); + } + } + if (inputs.length && outputs.length) { + var result = { + inputs: inputs, + outputs: outputs, + samplerInterpolation: interpolation, + inputsMin: shouldBakeAnimation ? minMaxKeyFrames.min : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.FloatRound(minMaxKeyFrames.min / animation.framePerSecond), + inputsMax: shouldBakeAnimation ? minMaxKeyFrames.max : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.FloatRound(minMaxKeyFrames.max / animation.framePerSecond), + }; + return result; + } + } + return null; + }; + _GLTFAnimation._DeduceAnimationInfo = function (animation) { + var animationChannelTargetPath = null; + var dataAccessorType = "VEC3" /* AccessorType.VEC3 */; + var useQuaternion = false; + var property = animation.targetProperty.split("."); + switch (property[0]) { + case "scaling": { + animationChannelTargetPath = "scale" /* AnimationChannelTargetPath.SCALE */; + break; + } + case "position": { + animationChannelTargetPath = "translation" /* AnimationChannelTargetPath.TRANSLATION */; + break; + } + case "rotation": { + dataAccessorType = "VEC4" /* AccessorType.VEC4 */; + animationChannelTargetPath = "rotation" /* AnimationChannelTargetPath.ROTATION */; + break; + } + case "rotationQuaternion": { + dataAccessorType = "VEC4" /* AccessorType.VEC4 */; + useQuaternion = true; + animationChannelTargetPath = "rotation" /* AnimationChannelTargetPath.ROTATION */; + break; + } + case "influence": { + dataAccessorType = "SCALAR" /* AccessorType.SCALAR */; + animationChannelTargetPath = "weights" /* AnimationChannelTargetPath.WEIGHTS */; + break; + } + default: { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("Unsupported animatable property ".concat(property[0])); + } + } + if (animationChannelTargetPath) { + return { animationChannelTargetPath: animationChannelTargetPath, dataAccessorType: dataAccessorType, useQuaternion: useQuaternion }; + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("animation channel target path and data accessor type could be deduced"); + } + return null; + }; + /** + * @ignore + * Create node animations from the transform node animations + * @param babylonNode + * @param runtimeGLTFAnimation + * @param idleGLTFAnimations + * @param nodeMap + * @param nodes + * @param binaryWriter + * @param bufferViews + * @param accessors + * @param animationSampleRate + */ + _GLTFAnimation._CreateNodeAnimationFromNodeAnimations = function (babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, animationSampleRate, shouldExportAnimation) { + var glTFAnimation; + if (_GLTFAnimation._IsTransformable(babylonNode)) { + if (babylonNode.animations) { + for (var _i = 0, _a = babylonNode.animations; _i < _a.length; _i++) { + var animation = _a[_i]; + if (shouldExportAnimation && !shouldExportAnimation(animation)) { + continue; + } + var animationInfo = _GLTFAnimation._DeduceAnimationInfo(animation); + if (animationInfo) { + glTFAnimation = { + name: animation.name, + samplers: [], + channels: [], + }; + _GLTFAnimation._AddAnimation("".concat(animation.name), animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation, babylonNode, animation, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, animationInfo.useQuaternion, animationSampleRate); + if (glTFAnimation.samplers.length && glTFAnimation.channels.length) { + idleGLTFAnimations.push(glTFAnimation); + } + } + } + } + } + }; + /** + * @ignore + * Create individual morph animations from the mesh's morph target animation tracks + * @param babylonNode + * @param runtimeGLTFAnimation + * @param idleGLTFAnimations + * @param nodeMap + * @param nodes + * @param binaryWriter + * @param bufferViews + * @param accessors + * @param animationSampleRate + */ + _GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations = function (babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, animationSampleRate, shouldExportAnimation) { + var glTFAnimation; + if (babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Mesh) { + var morphTargetManager = babylonNode.morphTargetManager; + if (morphTargetManager) { + for (var i = 0; i < morphTargetManager.numTargets; ++i) { + var morphTarget = morphTargetManager.getTarget(i); + for (var _i = 0, _a = morphTarget.animations; _i < _a.length; _i++) { + var animation = _a[_i]; + if (shouldExportAnimation && !shouldExportAnimation(animation)) { + continue; + } + var combinedAnimation = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Animation("".concat(animation.name), "influence", animation.framePerSecond, animation.dataType, animation.loopMode, animation.enableBlending); + var combinedAnimationKeys = []; + var animationKeys = animation.getKeys(); + for (var j = 0; j < animationKeys.length; ++j) { + var animationKey = animationKeys[j]; + for (var k = 0; k < morphTargetManager.numTargets; ++k) { + if (k == i) { + combinedAnimationKeys.push(animationKey); + } + else { + combinedAnimationKeys.push({ frame: animationKey.frame, value: 0 }); + } + } + } + combinedAnimation.setKeys(combinedAnimationKeys); + var animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimation); + if (animationInfo) { + glTFAnimation = { + name: combinedAnimation.name, + samplers: [], + channels: [], + }; + _GLTFAnimation._AddAnimation(animation.name, animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation, babylonNode, combinedAnimation, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, animationInfo.useQuaternion, animationSampleRate, morphTargetManager.numTargets); + if (glTFAnimation.samplers.length && glTFAnimation.channels.length) { + idleGLTFAnimations.push(glTFAnimation); + } + } + } + } + } + } + }; + /** + * @internal + * Create node and morph animations from the animation groups + * @param babylonScene + * @param glTFAnimations + * @param nodeMap + * @param nodes + * @param binaryWriter + * @param bufferViews + * @param accessors + * @param animationSampleRate + */ + _GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups = function (babylonScene, glTFAnimations, nodeMap, binaryWriter, bufferViews, accessors, animationSampleRate, shouldExportAnimation) { + var _a; + var glTFAnimation; + if (babylonScene.animationGroups) { + var animationGroups = babylonScene.animationGroups; + var _loop_1 = function (animationGroup) { + var morphAnimations = new Map(); + var sampleAnimations = new Map(); + var morphAnimationMeshes = new Set(); + var animationGroupFrameDiff = animationGroup.to - animationGroup.from; + glTFAnimation = { + name: animationGroup.name, + channels: [], + samplers: [], + }; + var _loop_2 = function (i) { + var targetAnimation = animationGroup.targetedAnimations[i]; + var target = targetAnimation.target; + var animation = targetAnimation.animation; + if (shouldExportAnimation && !shouldExportAnimation(animation)) { + return "continue"; + } + if (this_1._IsTransformable(target) || (target.length === 1 && this_1._IsTransformable(target[0]))) { + var animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation); + if (animationInfo) { + var babylonTransformNode = this_1._IsTransformable(target) ? target : this_1._IsTransformable(target[0]) ? target[0] : null; + if (babylonTransformNode) { + _GLTFAnimation._AddAnimation("".concat(animation.name), glTFAnimation, babylonTransformNode, animation, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, animationInfo.useQuaternion, animationSampleRate); + } + } + } + else if (target instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.MorphTarget || (target.length === 1 && target[0] instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.MorphTarget)) { + var animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation); + if (animationInfo) { + var babylonMorphTarget_1 = target instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.MorphTarget ? target : target[0]; + if (babylonMorphTarget_1) { + var babylonMorphTargetManager_1 = babylonScene.morphTargetManagers.find(function (morphTargetManager) { + for (var j = 0; j < morphTargetManager.numTargets; ++j) { + if (morphTargetManager.getTarget(j) === babylonMorphTarget_1) { + return true; + } + } + return false; + }); + if (babylonMorphTargetManager_1) { + var babylonMesh = babylonScene.meshes.find(function (mesh) { + return mesh.morphTargetManager === babylonMorphTargetManager_1; + }); + if (babylonMesh) { + if (!morphAnimations.has(babylonMesh)) { + morphAnimations.set(babylonMesh, new Map()); + } + (_a = morphAnimations.get(babylonMesh)) === null || _a === void 0 ? void 0 : _a.set(babylonMorphTarget_1, animation); + morphAnimationMeshes.add(babylonMesh); + sampleAnimations.set(babylonMesh, animation); + } + } + } + } + } + else { + // this is the place for the KHR_animation_pointer. + } + }; + for (var i = 0; i < animationGroup.targetedAnimations.length; ++i) { + _loop_2(i); + } + morphAnimationMeshes.forEach(function (mesh) { + var morphTargetManager = mesh.morphTargetManager; + var combinedAnimationGroup = null; + var animationKeys = []; + var sampleAnimation = sampleAnimations.get(mesh); + var sampleAnimationKeys = sampleAnimation.getKeys(); + var numAnimationKeys = sampleAnimationKeys.length; + /* + Due to how glTF expects morph target animation data to be formatted, we need to rearrange the individual morph target animation tracks, + such that we have a single animation, where a given keyframe input value has successive output values for each morph target belonging to the manager. + See: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations + + We do this via constructing a new Animation track, and interleaving the frames of each morph target animation track in the current Animation Group + We reuse the Babylon Animation data structure for ease of handling export of cubic spline animation keys, and to reuse the + existing _GLTFAnimation.AddAnimation codepath with minimal modification, however the constructed Babylon Animation is NOT intended for use in-engine. + */ + for (var i = 0; i < numAnimationKeys; ++i) { + for (var j = 0; j < morphTargetManager.numTargets; ++j) { + var morphTarget = morphTargetManager.getTarget(j); + var animationsByMorphTarget = morphAnimations.get(mesh); + if (animationsByMorphTarget) { + var morphTargetAnimation = animationsByMorphTarget.get(morphTarget); + if (morphTargetAnimation) { + if (!combinedAnimationGroup) { + combinedAnimationGroup = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Animation("".concat(animationGroup.name, "_").concat(mesh.name, "_MorphWeightAnimation"), "influence", morphTargetAnimation.framePerSecond, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, morphTargetAnimation.loopMode, morphTargetAnimation.enableBlending); + } + animationKeys.push(morphTargetAnimation.getKeys()[i]); + } + else { + animationKeys.push({ + frame: animationGroup.from + (animationGroupFrameDiff / numAnimationKeys) * i, + value: morphTarget.influence, + inTangent: sampleAnimationKeys[0].inTangent ? 0 : undefined, + outTangent: sampleAnimationKeys[0].outTangent ? 0 : undefined, + }); + } + } + } + } + combinedAnimationGroup.setKeys(animationKeys); + var animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimationGroup); + if (animationInfo) { + _GLTFAnimation._AddAnimation("".concat(animationGroup.name, "_").concat(mesh.name, "_MorphWeightAnimation"), glTFAnimation, mesh, combinedAnimationGroup, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, animationInfo.useQuaternion, animationSampleRate, morphTargetManager === null || morphTargetManager === void 0 ? void 0 : morphTargetManager.numTargets); + } + }); + if (glTFAnimation.channels.length && glTFAnimation.samplers.length) { + glTFAnimations.push(glTFAnimation); + } + }; + var this_1 = this; + for (var _i = 0, animationGroups_1 = animationGroups; _i < animationGroups_1.length; _i++) { + var animationGroup = animationGroups_1[_i]; + _loop_1(animationGroup); + } + } + }; + _GLTFAnimation._AddAnimation = function (name, glTFAnimation, babylonTransformNode, animation, dataAccessorType, animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, useQuaternion, animationSampleRate, morphAnimationChannels) { + var animationData = _GLTFAnimation._CreateNodeAnimation(babylonTransformNode, animation, animationChannelTargetPath, useQuaternion, animationSampleRate); + var bufferView; + var accessor; + var keyframeAccessorIndex; + var dataAccessorIndex; + var outputLength; + var animationSampler; + var animationChannel; + if (animationData) { + /* + * Now that we have the glTF converted morph target animation data, + * we can remove redundant input data so that we have n input frames, + * and morphAnimationChannels * n output frames + */ + if (morphAnimationChannels) { + var index = 0; + var currentInput = 0; + var newInputs = []; + while (animationData.inputs.length > 0) { + currentInput = animationData.inputs.shift(); + if (index % morphAnimationChannels == 0) { + newInputs.push(currentInput); + } + index++; + } + animationData.inputs = newInputs; + } + var nodeIndex = nodeMap[babylonTransformNode.uniqueId]; + // Creates buffer view and accessor for key frames. + var byteLength = animationData.inputs.length * 4; + bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__._GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, undefined, "".concat(name, " keyframe data view")); + bufferViews.push(bufferView); + animationData.inputs.forEach(function (input) { + binaryWriter.setFloat32(input); + }); + accessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__._GLTFUtilities._CreateAccessor(bufferViews.length - 1, "".concat(name, " keyframes"), "SCALAR" /* AccessorType.SCALAR */, 5126 /* AccessorComponentType.FLOAT */, animationData.inputs.length, null, [animationData.inputsMin], [animationData.inputsMax]); + accessors.push(accessor); + keyframeAccessorIndex = accessors.length - 1; + // create bufferview and accessor for keyed values. + outputLength = animationData.outputs.length; + byteLength = _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__._GLTFUtilities._GetDataAccessorElementCount(dataAccessorType) * 4 * animationData.outputs.length; + // check for in and out tangents + bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__._GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, undefined, "".concat(name, " data view")); + bufferViews.push(bufferView); + animationData.outputs.forEach(function (output) { + output.forEach(function (entry) { + binaryWriter.setFloat32(entry); + }); + }); + accessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__._GLTFUtilities._CreateAccessor(bufferViews.length - 1, "".concat(name, " data"), dataAccessorType, 5126 /* AccessorComponentType.FLOAT */, outputLength, null, null, null); + accessors.push(accessor); + dataAccessorIndex = accessors.length - 1; + // create sampler + animationSampler = { + interpolation: animationData.samplerInterpolation, + input: keyframeAccessorIndex, + output: dataAccessorIndex, + }; + glTFAnimation.samplers.push(animationSampler); + // create channel + animationChannel = { + sampler: glTFAnimation.samplers.length - 1, + target: { + node: nodeIndex, + path: animationChannelTargetPath, + }, + }; + glTFAnimation.channels.push(animationChannel); + } + }; + /** + * Create a baked animation + * @param babylonTransformNode BabylonJS mesh + * @param animation BabylonJS animation corresponding to the BabylonJS mesh + * @param animationChannelTargetPath animation target channel + * @param minFrame minimum animation frame + * @param maxFrame maximum animation frame + * @param fps frames per second of the animation + * @param sampleRate + * @param inputs input key frames of the animation + * @param outputs output key frame data of the animation + * @param minMaxFrames + * @param minMaxFrames.min + * @param minMaxFrames.max + * @param useQuaternion specifies if quaternions should be used + */ + _GLTFAnimation._CreateBakedAnimation = function (babylonTransformNode, animation, animationChannelTargetPath, minFrame, maxFrame, fps, sampleRate, inputs, outputs, minMaxFrames, useQuaternion) { + var value; + var quaternionCache = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity(); + var previousTime = null; + var time; + var maxUsedFrame = null; + var currKeyFrame = null; + var nextKeyFrame = null; + var prevKeyFrame = null; + var endFrame = null; + minMaxFrames.min = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.FloatRound(minFrame / fps); + var keyFrames = animation.getKeys(); + for (var i = 0, length_1 = keyFrames.length; i < length_1; ++i) { + endFrame = null; + currKeyFrame = keyFrames[i]; + if (i + 1 < length_1) { + nextKeyFrame = keyFrames[i + 1]; + if ((currKeyFrame.value.equals && currKeyFrame.value.equals(nextKeyFrame.value)) || currKeyFrame.value === nextKeyFrame.value) { + if (i === 0) { + // set the first frame to itself + endFrame = currKeyFrame.frame; + } + else { + continue; + } + } + else { + endFrame = nextKeyFrame.frame; + } + } + else { + // at the last key frame + prevKeyFrame = keyFrames[i - 1]; + if ((currKeyFrame.value.equals && currKeyFrame.value.equals(prevKeyFrame.value)) || currKeyFrame.value === prevKeyFrame.value) { + continue; + } + else { + endFrame = maxFrame; + } + } + if (endFrame) { + for (var f = currKeyFrame.frame; f <= endFrame; f += sampleRate) { + time = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.FloatRound(f / fps); + if (time === previousTime) { + continue; + } + previousTime = time; + maxUsedFrame = time; + var state = { + key: 0, + repeatCount: 0, + loopMode: animation.loopMode, + }; + value = animation._interpolate(f, state); + _GLTFAnimation._SetInterpolatedValue(babylonTransformNode, value, time, animation, animationChannelTargetPath, quaternionCache, inputs, outputs, useQuaternion); + } + } + } + if (maxUsedFrame) { + minMaxFrames.max = maxUsedFrame; + } + }; + _GLTFAnimation._ConvertFactorToVector3OrQuaternion = function (factor, babylonTransformNode, animation, animationChannelTargetPath, useQuaternion) { + var basePositionRotationOrScale = _GLTFAnimation._GetBasePositionRotationOrScale(babylonTransformNode, animationChannelTargetPath, useQuaternion); + // handles single component x, y, z or w component animation by using a base property and animating over a component. + var property = animation.targetProperty.split("."); + var componentName = property ? property[1] : ""; // x, y, z, or w component + var value = useQuaternion ? babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArray(basePositionRotationOrScale).normalize() : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(basePositionRotationOrScale); + switch (componentName) { + case "x": + case "y": + case "z": { + value[componentName] = factor; + break; + } + case "w": { + value.w = factor; + break; + } + default: { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("glTFAnimation: Unsupported component name \"".concat(componentName, "\"!")); + } + } + return value; + }; + _GLTFAnimation._SetInterpolatedValue = function (babylonTransformNode, value, time, animation, animationChannelTargetPath, quaternionCache, inputs, outputs, useQuaternion) { + var cacheValue; + inputs.push(time); + if (animationChannelTargetPath === "weights" /* AnimationChannelTargetPath.WEIGHTS */) { + outputs.push([value]); + return; + } + if (animation.dataType === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT) { + value = this._ConvertFactorToVector3OrQuaternion(value, babylonTransformNode, animation, animationChannelTargetPath, useQuaternion); + } + if (animationChannelTargetPath === "rotation" /* AnimationChannelTargetPath.ROTATION */) { + if (useQuaternion) { + quaternionCache = value; + } + else { + cacheValue = value; + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.RotationYawPitchRollToRef(cacheValue.y, cacheValue.x, cacheValue.z, quaternionCache); + } + outputs.push(quaternionCache.asArray()); + } + else { + // scaling and position animation + cacheValue = value; + outputs.push(cacheValue.asArray()); + } + }; + /** + * Creates linear animation from the animation key frames + * @param babylonTransformNode BabylonJS mesh + * @param animation BabylonJS animation + * @param animationChannelTargetPath The target animation channel + * @param inputs Array to store the key frame times + * @param outputs Array to store the key frame data + * @param useQuaternion Specifies if quaternions are used in the animation + */ + _GLTFAnimation._CreateLinearOrStepAnimation = function (babylonTransformNode, animation, animationChannelTargetPath, inputs, outputs, useQuaternion) { + for (var _i = 0, _a = animation.getKeys(); _i < _a.length; _i++) { + var keyFrame = _a[_i]; + inputs.push(keyFrame.frame / animation.framePerSecond); // keyframes in seconds. + _GLTFAnimation._AddKeyframeValue(keyFrame, animation, outputs, animationChannelTargetPath, babylonTransformNode, useQuaternion); + } + }; + /** + * Creates cubic spline animation from the animation key frames + * @param babylonTransformNode BabylonJS mesh + * @param animation BabylonJS animation + * @param animationChannelTargetPath The target animation channel + * @param inputs Array to store the key frame times + * @param outputs Array to store the key frame data + * @param useQuaternion Specifies if quaternions are used in the animation + */ + _GLTFAnimation._CreateCubicSplineAnimation = function (babylonTransformNode, animation, animationChannelTargetPath, inputs, outputs, useQuaternion) { + animation.getKeys().forEach(function (keyFrame) { + inputs.push(keyFrame.frame / animation.framePerSecond); // keyframes in seconds. + _GLTFAnimation._AddSplineTangent(_TangentType.INTANGENT, outputs, animationChannelTargetPath, "CUBICSPLINE" /* AnimationSamplerInterpolation.CUBICSPLINE */, keyFrame, useQuaternion); + _GLTFAnimation._AddKeyframeValue(keyFrame, animation, outputs, animationChannelTargetPath, babylonTransformNode, useQuaternion); + _GLTFAnimation._AddSplineTangent(_TangentType.OUTTANGENT, outputs, animationChannelTargetPath, "CUBICSPLINE" /* AnimationSamplerInterpolation.CUBICSPLINE */, keyFrame, useQuaternion); + }); + }; + _GLTFAnimation._GetBasePositionRotationOrScale = function (babylonTransformNode, animationChannelTargetPath, useQuaternion) { + var basePositionRotationOrScale; + if (animationChannelTargetPath === "rotation" /* AnimationChannelTargetPath.ROTATION */) { + if (useQuaternion) { + var q = babylonTransformNode.rotationQuaternion; + basePositionRotationOrScale = (q !== null && q !== void 0 ? q : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity()).asArray(); + } + else { + var r = babylonTransformNode.rotation; + basePositionRotationOrScale = (r !== null && r !== void 0 ? r : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero()).asArray(); + } + } + else if (animationChannelTargetPath === "translation" /* AnimationChannelTargetPath.TRANSLATION */) { + var p = babylonTransformNode.position; + basePositionRotationOrScale = (p !== null && p !== void 0 ? p : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero()).asArray(); + } + else { + // scale + var s = babylonTransformNode.scaling; + basePositionRotationOrScale = (s !== null && s !== void 0 ? s : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.One()).asArray(); + } + return basePositionRotationOrScale; + }; + /** + * Adds a key frame value + * @param keyFrame + * @param animation + * @param outputs + * @param animationChannelTargetPath + * @param babylonTransformNode + * @param useQuaternion + */ + _GLTFAnimation._AddKeyframeValue = function (keyFrame, animation, outputs, animationChannelTargetPath, babylonTransformNode, useQuaternion) { + var newPositionRotationOrScale; + var animationType = animation.dataType; + if (animationType === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_VECTOR3) { + var value = keyFrame.value.asArray(); + if (animationChannelTargetPath === "rotation" /* AnimationChannelTargetPath.ROTATION */) { + var array = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(value); + var rotationQuaternion = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.RotationYawPitchRoll(array.y, array.x, array.z); + value = rotationQuaternion.asArray(); + } + outputs.push(value); // scale vector. + } + else if (animationType === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT) { + if (animationChannelTargetPath === "weights" /* AnimationChannelTargetPath.WEIGHTS */) { + outputs.push([keyFrame.value]); + } + else { + // handles single component x, y, z or w component animation by using a base property and animating over a component. + newPositionRotationOrScale = this._ConvertFactorToVector3OrQuaternion(keyFrame.value, babylonTransformNode, animation, animationChannelTargetPath, useQuaternion); + if (newPositionRotationOrScale) { + if (animationChannelTargetPath === "rotation" /* AnimationChannelTargetPath.ROTATION */) { + var posRotScale = useQuaternion + ? newPositionRotationOrScale + : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.RotationYawPitchRoll(newPositionRotationOrScale.y, newPositionRotationOrScale.x, newPositionRotationOrScale.z).normalize(); + outputs.push(posRotScale.asArray()); + } + outputs.push(newPositionRotationOrScale.asArray()); + } + } + } + else if (animationType === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_QUATERNION) { + outputs.push(keyFrame.value.normalize().asArray()); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("glTFAnimation: Unsupported key frame values for animation!"); + } + }; + /** + * @internal + * Determine the interpolation based on the key frames + * @param keyFrames + * @param animationChannelTargetPath + * @param useQuaternion + */ + _GLTFAnimation._DeduceInterpolation = function (keyFrames, animationChannelTargetPath, useQuaternion) { + var interpolationType; + var shouldBakeAnimation = false; + var key; + if (animationChannelTargetPath === "rotation" /* AnimationChannelTargetPath.ROTATION */ && !useQuaternion) { + return { interpolationType: "LINEAR" /* AnimationSamplerInterpolation.LINEAR */, shouldBakeAnimation: true }; + } + for (var i = 0, length_2 = keyFrames.length; i < length_2; ++i) { + key = keyFrames[i]; + if (key.inTangent || key.outTangent) { + if (interpolationType) { + if (interpolationType !== "CUBICSPLINE" /* AnimationSamplerInterpolation.CUBICSPLINE */) { + interpolationType = "LINEAR" /* AnimationSamplerInterpolation.LINEAR */; + shouldBakeAnimation = true; + break; + } + } + else { + interpolationType = "CUBICSPLINE" /* AnimationSamplerInterpolation.CUBICSPLINE */; + } + } + else { + if (interpolationType) { + if (interpolationType === "CUBICSPLINE" /* AnimationSamplerInterpolation.CUBICSPLINE */ || + (key.interpolation && key.interpolation === 1 /* AnimationKeyInterpolation.STEP */ && interpolationType !== "STEP" /* AnimationSamplerInterpolation.STEP */)) { + interpolationType = "LINEAR" /* AnimationSamplerInterpolation.LINEAR */; + shouldBakeAnimation = true; + break; + } + } + else { + if (key.interpolation && key.interpolation === 1 /* AnimationKeyInterpolation.STEP */) { + interpolationType = "STEP" /* AnimationSamplerInterpolation.STEP */; + } + else { + interpolationType = "LINEAR" /* AnimationSamplerInterpolation.LINEAR */; + } + } + } + } + if (!interpolationType) { + interpolationType = "LINEAR" /* AnimationSamplerInterpolation.LINEAR */; + } + return { interpolationType: interpolationType, shouldBakeAnimation: shouldBakeAnimation }; + }; + /** + * Adds an input tangent or output tangent to the output data + * If an input tangent or output tangent is missing, it uses the zero vector or zero quaternion + * @param tangentType Specifies which type of tangent to handle (inTangent or outTangent) + * @param outputs The animation data by keyframe + * @param animationChannelTargetPath The target animation channel + * @param interpolation The interpolation type + * @param keyFrame The key frame with the animation data + * @param useQuaternion Specifies if quaternions are used + */ + _GLTFAnimation._AddSplineTangent = function (tangentType, outputs, animationChannelTargetPath, interpolation, keyFrame, useQuaternion) { + var tangent; + var tangentValue = tangentType === _TangentType.INTANGENT ? keyFrame.inTangent : keyFrame.outTangent; + if (interpolation === "CUBICSPLINE" /* AnimationSamplerInterpolation.CUBICSPLINE */) { + if (animationChannelTargetPath === "rotation" /* AnimationChannelTargetPath.ROTATION */) { + if (tangentValue) { + if (useQuaternion) { + tangent = tangentValue.asArray(); + } + else { + var array = tangentValue; + tangent = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.RotationYawPitchRoll(array.y, array.x, array.z).asArray(); + } + } + else { + tangent = [0, 0, 0, 0]; + } + } + else if (animationChannelTargetPath === "weights" /* AnimationChannelTargetPath.WEIGHTS */) { + if (tangentValue) { + tangent = [tangentValue]; + } + else { + tangent = [0]; + } + } + else { + if (tangentValue) { + tangent = tangentValue.asArray(); + } + else { + tangent = [0, 0, 0]; + } + } + outputs.push(tangent); + } + }; + /** + * Get the minimum and maximum key frames' frame values + * @param keyFrames animation key frames + * @returns the minimum and maximum key frame value + */ + _GLTFAnimation._CalculateMinMaxKeyFrames = function (keyFrames) { + var min = Infinity; + var max = -Infinity; + keyFrames.forEach(function (keyFrame) { + min = Math.min(min, keyFrame.frame); + max = Math.max(max, keyFrame.frame); + }); + return { min: min, max: max }; + }; + return _GLTFAnimation; +}()); + + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/glTFData.ts": +/*!*********************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/glTFData.ts ***! + \*********************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFData: () => (/* binding */ GLTFData) +/* harmony export */ }); +/** + * Class for holding and downloading glTF file data + */ +var GLTFData = /** @class */ (function () { + /** + * Initializes the glTF file object + */ + function GLTFData() { + this.glTFFiles = {}; + } + /** + * Downloads the glTF data as files based on their names and data + */ + GLTFData.prototype.downloadFiles = function () { + /** + * Checks for a matching suffix at the end of a string (for ES5 and lower) + * @param str Source string + * @param suffix Suffix to search for in the source string + * @returns Boolean indicating whether the suffix was found (true) or not (false) + */ + function endsWith(str, suffix) { + return str.indexOf(suffix, str.length - suffix.length) !== -1; + } + for (var key in this.glTFFiles) { + var link = document.createElement("a"); + document.body.appendChild(link); + link.setAttribute("type", "hidden"); + link.download = key; + var blob = this.glTFFiles[key]; + var mimeType = void 0; + if (endsWith(key, ".glb")) { + mimeType = { type: "model/gltf-binary" }; + } + else if (endsWith(key, ".bin")) { + mimeType = { type: "application/octet-stream" }; + } + else if (endsWith(key, ".gltf")) { + mimeType = { type: "model/gltf+json" }; + } + else if (endsWith(key, ".jpeg") || endsWith(key, ".jpg")) { + mimeType = { type: "image/jpeg" /* ImageMimeType.JPEG */ }; + } + else if (endsWith(key, ".png")) { + mimeType = { type: "image/png" /* ImageMimeType.PNG */ }; + } + link.href = window.URL.createObjectURL(new Blob([blob], mimeType)); + link.click(); + } + }; + return GLTFData; +}()); + + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts": +/*!*************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/glTFExporter.ts ***! + \*************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ _BinaryWriter: () => (/* binding */ _BinaryWriter), +/* harmony export */ _Exporter: () => (/* binding */ _Exporter) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/multiMaterial */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFMaterialExporter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./glTFMaterialExporter */ "../../../dev/serializers/src/glTF/2.0/glTFMaterialExporter.ts"); +/* harmony import */ var _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glTFUtilities */ "../../../dev/serializers/src/glTF/2.0/glTFUtilities.ts"); +/* harmony import */ var _glTFData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./glTFData */ "../../../dev/serializers/src/glTF/2.0/glTFData.ts"); +/* harmony import */ var _glTFAnimation__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./glTFAnimation */ "../../../dev/serializers/src/glTF/2.0/glTFAnimation.ts"); + + + + + + + + + + + + + + + + + + +// Matrix that converts handedness on the X-axis. +var convertHandednessMatrix = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Matrix.Compose(new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3(-1, 1, 1), babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity(), babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero()); +// 180 degrees rotation in Y. +var rotation180Y = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion(0, 1, 0, 0); +function isNoopNode(node, useRightHandedSystem) { + if (!(node instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TransformNode)) { + return false; + } + // Transform + if (useRightHandedSystem) { + var matrix = node.getWorldMatrix(); + if (!matrix.isIdentity()) { + return false; + } + } + else { + var matrix = node.getWorldMatrix().multiplyToRef(convertHandednessMatrix, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Matrix[0]); + if (!matrix.isIdentity()) { + return false; + } + } + // Geometry + if ((node instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Mesh && node.geometry) || (node instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.InstancedMesh && node.sourceMesh.geometry)) { + return false; + } + return true; +} +function convertNodeHandedness(node) { + var translation = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArrayToRef(node.translation || [0, 0, 0], 0, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[0]); + var rotation = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArrayToRef(node.rotation || [0, 0, 0, 1], 0, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Quaternion[0]); + var scale = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArrayToRef(node.scale || [1, 1, 1], 0, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[1]); + var matrix = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Matrix.ComposeToRef(scale, rotation, translation, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Matrix[0]).multiplyToRef(convertHandednessMatrix, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Matrix[0]); + matrix.decompose(scale, rotation, translation); + if (translation.equalsToFloats(0, 0, 0)) { + delete node.translation; + } + else { + node.translation = translation.asArray(); + } + if (babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.IsIdentity(rotation)) { + delete node.rotation; + } + else { + node.rotation = rotation.asArray(); + } + if (scale.equalsToFloats(1, 1, 1)) { + delete node.scale; + } + else { + node.scale = scale.asArray(); + } +} +function getBinaryWriterFunc(binaryWriter, attributeComponentKind) { + switch (attributeComponentKind) { + case 5121 /* AccessorComponentType.UNSIGNED_BYTE */: { + return binaryWriter.setUInt8.bind(binaryWriter); + } + case 5123 /* AccessorComponentType.UNSIGNED_SHORT */: { + return binaryWriter.setUInt16.bind(binaryWriter); + } + case 5125 /* AccessorComponentType.UNSIGNED_INT */: { + return binaryWriter.setUInt32.bind(binaryWriter); + } + case 5126 /* AccessorComponentType.FLOAT */: { + return binaryWriter.setFloat32.bind(binaryWriter); + } + default: { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("Unsupported Attribute Component kind: " + attributeComponentKind); + return null; + } + } +} +/** + * Converts Babylon Scene into glTF 2.0. + * @internal + */ +var _Exporter = /** @class */ (function () { + /** + * Creates a glTF Exporter instance, which can accept optional exporter options + * @param babylonScene Babylon scene object + * @param options Options to modify the behavior of the exporter + */ + function _Exporter(babylonScene, options) { + this._extensions = {}; + this._glTF = { + asset: { generator: "Babylon.js v".concat(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Engine.Version), version: "2.0" }, + }; + babylonScene = babylonScene || babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.EngineStore.LastCreatedScene; + if (!babylonScene) { + return; + } + this._babylonScene = babylonScene; + this._bufferViews = []; + this._accessors = []; + this._meshes = []; + this._scenes = []; + this._cameras = []; + this._nodes = []; + this._images = []; + this._materials = []; + this._materialMap = []; + this._textures = []; + this._samplers = []; + this._skins = []; + this._animations = []; + this._imageData = {}; + this._orderedImageData = []; + this._options = options || {}; + this._animationSampleRate = this._options.animationSampleRate || 1 / 60; + this._glTFMaterialExporter = new _glTFMaterialExporter__WEBPACK_IMPORTED_MODULE_1__._GLTFMaterialExporter(this); + this._loadExtensions(); + } + _Exporter.prototype._applyExtension = function (node, extensions, index, actionAsync) { + var _this = this; + if (index >= extensions.length) { + return Promise.resolve(node); + } + var currentPromise = actionAsync(extensions[index], node); + if (!currentPromise) { + return this._applyExtension(node, extensions, index + 1, actionAsync); + } + return currentPromise.then(function (newNode) { return _this._applyExtension(newNode, extensions, index + 1, actionAsync); }); + }; + _Exporter.prototype._applyExtensions = function (node, actionAsync) { + var extensions = []; + for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) { + var name_1 = _a[_i]; + extensions.push(this._extensions[name_1]); + } + return this._applyExtension(node, extensions, 0, actionAsync); + }; + _Exporter.prototype._extensionsPreExportTextureAsync = function (context, babylonTexture, mimeType) { + return this._applyExtensions(babylonTexture, function (extension, node) { return extension.preExportTextureAsync && extension.preExportTextureAsync(context, node, mimeType); }); + }; + _Exporter.prototype._extensionsPostExportMeshPrimitiveAsync = function (context, meshPrimitive, babylonSubMesh, binaryWriter) { + return this._applyExtensions(meshPrimitive, function (extension, node) { return extension.postExportMeshPrimitiveAsync && extension.postExportMeshPrimitiveAsync(context, node, babylonSubMesh, binaryWriter); }); + }; + _Exporter.prototype._extensionsPostExportNodeAsync = function (context, node, babylonNode, nodeMap, binaryWriter) { + return this._applyExtensions(node, function (extension, node) { return extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode, nodeMap, binaryWriter); }); + }; + _Exporter.prototype._extensionsPostExportMaterialAsync = function (context, material, babylonMaterial) { + return this._applyExtensions(material, function (extension, node) { return extension.postExportMaterialAsync && extension.postExportMaterialAsync(context, node, babylonMaterial); }); + }; + _Exporter.prototype._extensionsPostExportMaterialAdditionalTextures = function (context, material, babylonMaterial) { + var output = []; + for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) { + var name_2 = _a[_i]; + var extension = this._extensions[name_2]; + if (extension.postExportMaterialAdditionalTextures) { + output.push.apply(output, extension.postExportMaterialAdditionalTextures(context, material, babylonMaterial)); + } + } + return output; + }; + _Exporter.prototype._extensionsPostExportTextures = function (context, textureInfo, babylonTexture) { + for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) { + var name_3 = _a[_i]; + var extension = this._extensions[name_3]; + if (extension.postExportTexture) { + extension.postExportTexture(context, textureInfo, babylonTexture); + } + } + }; + _Exporter.prototype._forEachExtensions = function (action) { + for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) { + var name_4 = _a[_i]; + var extension = this._extensions[name_4]; + if (extension.enabled) { + action(extension); + } + } + }; + _Exporter.prototype._extensionsOnExporting = function () { + var _this = this; + this._forEachExtensions(function (extension) { + if (extension.wasUsed) { + if (_this._glTF.extensionsUsed == null) { + _this._glTF.extensionsUsed = []; + } + if (_this._glTF.extensionsUsed.indexOf(extension.name) === -1) { + _this._glTF.extensionsUsed.push(extension.name); + } + if (extension.required) { + if (_this._glTF.extensionsRequired == null) { + _this._glTF.extensionsRequired = []; + } + if (_this._glTF.extensionsRequired.indexOf(extension.name) === -1) { + _this._glTF.extensionsRequired.push(extension.name); + } + } + if (_this._glTF.extensions == null) { + _this._glTF.extensions = {}; + } + if (extension.onExporting) { + extension.onExporting(); + } + } + }); + }; + /** + * Load glTF serializer extensions + */ + _Exporter.prototype._loadExtensions = function () { + for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) { + var name_5 = _a[_i]; + var extension = _Exporter._ExtensionFactories[name_5](this); + this._extensions[name_5] = extension; + } + }; + _Exporter.prototype.dispose = function () { + for (var extensionKey in this._extensions) { + var extension = this._extensions[extensionKey]; + extension.dispose(); + } + }; + Object.defineProperty(_Exporter.prototype, "options", { + get: function () { + return this._options; + }, + enumerable: false, + configurable: true + }); + /** + * Registers a glTF exporter extension + * @param name Name of the extension to export + * @param factory The factory function that creates the exporter extension + */ + _Exporter.RegisterExtension = function (name, factory) { + if (_Exporter.UnregisterExtension(name)) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("Extension with the name ".concat(name, " already exists")); + } + _Exporter._ExtensionFactories[name] = factory; + _Exporter._ExtensionNames.push(name); + }; + /** + * Un-registers an exporter extension + * @param name The name fo the exporter extension + * @returns A boolean indicating whether the extension has been un-registered + */ + _Exporter.UnregisterExtension = function (name) { + if (!_Exporter._ExtensionFactories[name]) { + return false; + } + delete _Exporter._ExtensionFactories[name]; + var index = _Exporter._ExtensionNames.indexOf(name); + if (index !== -1) { + _Exporter._ExtensionNames.splice(index, 1); + } + return true; + }; + _Exporter.prototype._reorderIndicesBasedOnPrimitiveMode = function (submesh, primitiveMode, babylonIndices, byteOffset, binaryWriter) { + switch (primitiveMode) { + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleFillMode: { + if (!byteOffset) { + byteOffset = 0; + } + for (var i = submesh.indexStart, length_1 = submesh.indexStart + submesh.indexCount; i < length_1; i = i + 3) { + var index = byteOffset + i * 4; + // swap the second and third indices + var secondIndex = binaryWriter.getUInt32(index + 4); + var thirdIndex = binaryWriter.getUInt32(index + 8); + binaryWriter.setUInt32(thirdIndex, index + 4); + binaryWriter.setUInt32(secondIndex, index + 8); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleFanDrawMode: { + for (var i = submesh.indexStart + submesh.indexCount - 1, start = submesh.indexStart; i >= start; --i) { + binaryWriter.setUInt32(babylonIndices[i], byteOffset); + byteOffset += 4; + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleStripDrawMode: { + if (submesh.indexCount >= 3) { + binaryWriter.setUInt32(babylonIndices[submesh.indexStart + 2], byteOffset + 4); + binaryWriter.setUInt32(babylonIndices[submesh.indexStart + 1], byteOffset + 8); + } + break; + } + } + }; + /** + * Reorders the vertex attribute data based on the primitive mode. This is necessary when indices are not available and the winding order is + * clock-wise during export to glTF + * @param submesh BabylonJS submesh + * @param primitiveMode Primitive mode of the mesh + * @param vertexBufferKind The type of vertex attribute + * @param meshAttributeArray The vertex attribute data + * @param byteOffset The offset to the binary data + * @param binaryWriter The binary data for the glTF file + */ + _Exporter.prototype._reorderVertexAttributeDataBasedOnPrimitiveMode = function (submesh, primitiveMode, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) { + switch (primitiveMode) { + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleFillMode: { + this._reorderTriangleFillMode(submesh, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter); + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleStripDrawMode: { + this._reorderTriangleStripDrawMode(submesh, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter); + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleFanDrawMode: { + this._reorderTriangleFanMode(submesh, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter); + break; + } + } + }; + /** + * Reorders the vertex attributes in the correct triangle mode order . This is necessary when indices are not available and the winding order is + * clock-wise during export to glTF + * @param submesh BabylonJS submesh + * @param vertexBufferKind The type of vertex attribute + * @param meshAttributeArray The vertex attribute data + * @param byteOffset The offset to the binary data + * @param binaryWriter The binary data for the glTF file + */ + _Exporter.prototype._reorderTriangleFillMode = function (submesh, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) { + var vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh()); + if (vertexBuffer) { + var stride = vertexBuffer.byteStride / babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.GetTypeByteLength(vertexBuffer.type); + if (submesh.verticesCount % 3 !== 0) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("The submesh vertices for the triangle fill mode is not divisible by 3!"); + } + else { + var vertexData = []; + var index = 0; + switch (vertexBufferKind) { + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind: + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind: { + for (var x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) { + index = x * stride; + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(meshAttributeArray, index)); + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(meshAttributeArray, index + 2 * stride)); + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(meshAttributeArray, index + stride)); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind: { + for (var x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) { + index = x * stride; + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index)); + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index + 2 * stride)); + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index + stride)); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ColorKind: { + var size = vertexBuffer.getSize(); + for (var x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + size) { + index = x * stride; + if (size === 4) { + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index)); + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index + 2 * stride)); + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index + stride)); + } + else { + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(meshAttributeArray, index)); + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(meshAttributeArray, index + 2 * stride)); + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(meshAttributeArray, index + stride)); + } + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UVKind: + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV2Kind: { + for (var x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) { + index = x * stride; + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector2.FromArray(meshAttributeArray, index)); + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector2.FromArray(meshAttributeArray, index + 2 * stride)); + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector2.FromArray(meshAttributeArray, index + stride)); + } + break; + } + default: { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("Unsupported Vertex Buffer type: ".concat(vertexBufferKind)); + } + } + this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, binaryWriter); + } + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("reorderTriangleFillMode: Vertex Buffer Kind ".concat(vertexBufferKind, " not present!")); + } + }; + /** + * Reorders the vertex attributes in the correct triangle strip order. This is necessary when indices are not available and the winding order is + * clock-wise during export to glTF + * @param submesh BabylonJS submesh + * @param vertexBufferKind The type of vertex attribute + * @param meshAttributeArray The vertex attribute data + * @param byteOffset The offset to the binary data + * @param binaryWriter The binary data for the glTF file + */ + _Exporter.prototype._reorderTriangleStripDrawMode = function (submesh, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) { + var vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh()); + if (vertexBuffer) { + var stride = vertexBuffer.byteStride / babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.GetTypeByteLength(vertexBuffer.type); + var vertexData = []; + var index = 0; + switch (vertexBufferKind) { + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind: + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind: { + index = submesh.verticesStart; + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(meshAttributeArray, index + 2 * stride)); + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(meshAttributeArray, index + stride)); + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind: { + for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) { + index = x * stride; + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index)); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ColorKind: { + for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) { + index = x * stride; + vertexBuffer.getSize() === 4 + ? vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index)) + : vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(meshAttributeArray, index)); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UVKind: + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV2Kind: { + for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) { + index = x * stride; + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector2.FromArray(meshAttributeArray, index)); + } + break; + } + default: { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("Unsupported Vertex Buffer type: ".concat(vertexBufferKind)); + } + } + this._writeVertexAttributeData(vertexData, byteOffset + 12, vertexBufferKind, binaryWriter); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("reorderTriangleStripDrawMode: Vertex buffer kind ".concat(vertexBufferKind, " not present!")); + } + }; + /** + * Reorders the vertex attributes in the correct triangle fan order. This is necessary when indices are not available and the winding order is + * clock-wise during export to glTF + * @param submesh BabylonJS submesh + * @param vertexBufferKind The type of vertex attribute + * @param meshAttributeArray The vertex attribute data + * @param byteOffset The offset to the binary data + * @param binaryWriter The binary data for the glTF file + */ + _Exporter.prototype._reorderTriangleFanMode = function (submesh, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) { + var vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh()); + if (vertexBuffer) { + var stride = vertexBuffer.byteStride / babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.GetTypeByteLength(vertexBuffer.type); + var vertexData = []; + var index = 0; + switch (vertexBufferKind) { + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind: + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind: { + for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) { + index = x * stride; + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(meshAttributeArray, index)); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind: { + for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) { + index = x * stride; + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index)); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ColorKind: { + for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) { + index = x * stride; + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index)); + vertexBuffer.getSize() === 4 + ? vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index)) + : vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(meshAttributeArray, index)); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UVKind: + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV2Kind: { + for (var x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) { + index = x * stride; + vertexData.push(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector2.FromArray(meshAttributeArray, index)); + } + break; + } + default: { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("Unsupported Vertex Buffer type: ".concat(vertexBufferKind)); + } + } + this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, binaryWriter); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("reorderTriangleFanMode: Vertex buffer kind ".concat(vertexBufferKind, " not present!")); + } + }; + /** + * Writes the vertex attribute data to binary + * @param vertices The vertices to write to the binary writer + * @param byteOffset The offset into the binary writer to overwrite binary data + * @param vertexAttributeKind The vertex attribute type + * @param binaryWriter The writer containing the binary data + */ + _Exporter.prototype._writeVertexAttributeData = function (vertices, byteOffset, vertexAttributeKind, binaryWriter) { + for (var _i = 0, vertices_1 = vertices; _i < vertices_1.length; _i++) { + var vertex = vertices_1[_i]; + if (vertexAttributeKind === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind) { + vertex.normalize(); + } + else if (vertexAttributeKind === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind && vertex instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4) { + _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._NormalizeTangentFromRef(vertex); + } + for (var _a = 0, _b = vertex.asArray(); _a < _b.length; _a++) { + var component = _b[_a]; + binaryWriter.setFloat32(component, byteOffset); + byteOffset += 4; + } + } + }; + /** + * Writes mesh attribute data to a data buffer + * Returns the bytelength of the data + * @param vertexBufferKind Indicates what kind of vertex data is being passed in + * @param attributeComponentKind + * @param meshAttributeArray Array containing the attribute data + * @param stride Specifies the space between data + * @param binaryWriter The buffer to write the binary data to + * @param babylonTransformNode + */ + _Exporter.prototype._writeAttributeData = function (vertexBufferKind, attributeComponentKind, meshAttributeArray, stride, binaryWriter, babylonTransformNode) { + var vertexAttributes = []; + var index; + switch (vertexBufferKind) { + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind: { + for (var k = 0, length_2 = meshAttributeArray.length / stride; k < length_2; ++k) { + index = k * stride; + var vertexData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(meshAttributeArray, index); + vertexAttributes.push(vertexData.asArray()); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind: { + for (var k = 0, length_3 = meshAttributeArray.length / stride; k < length_3; ++k) { + index = k * stride; + var vertexData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(meshAttributeArray, index); + vertexAttributes.push(vertexData.normalize().asArray()); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind: { + for (var k = 0, length_4 = meshAttributeArray.length / stride; k < length_4; ++k) { + index = k * stride; + var vertexData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index); + _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._NormalizeTangentFromRef(vertexData); + vertexAttributes.push(vertexData.asArray()); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ColorKind: { + var meshMaterial = babylonTransformNode.material; + var convertToLinear = meshMaterial ? meshMaterial.getClassName() === "StandardMaterial" : true; + var vertexData = stride === 3 ? new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3() : new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color4(); + var useExactSrgbConversions = this._babylonScene.getEngine().useExactSrgbConversions; + for (var k = 0, length_5 = meshAttributeArray.length / stride; k < length_5; ++k) { + index = k * stride; + if (stride === 3) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArrayToRef(meshAttributeArray, index, vertexData); + if (convertToLinear) { + vertexData.toLinearSpaceToRef(vertexData, useExactSrgbConversions); + } + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color4.FromArrayToRef(meshAttributeArray, index, vertexData); + if (convertToLinear) { + vertexData.toLinearSpaceToRef(vertexData, useExactSrgbConversions); + } + } + vertexAttributes.push(vertexData.asArray()); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UVKind: + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV2Kind: { + for (var k = 0, length_6 = meshAttributeArray.length / stride; k < length_6; ++k) { + index = k * stride; + var vertexData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector2.FromArray(meshAttributeArray, index); + vertexAttributes.push(vertexData.asArray()); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesKind: + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesExtraKind: { + for (var k = 0, length_7 = meshAttributeArray.length / stride; k < length_7; ++k) { + index = k * stride; + var vertexData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index); + vertexAttributes.push(vertexData.asArray()); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesWeightsKind: + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesWeightsExtraKind: { + for (var k = 0, length_8 = meshAttributeArray.length / stride; k < length_8; ++k) { + index = k * stride; + var vertexData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector4.FromArray(meshAttributeArray, index); + vertexAttributes.push(vertexData.asArray()); + } + break; + } + default: { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("Unsupported Vertex Buffer Type: " + vertexBufferKind); + vertexAttributes = []; + } + } + var writeBinaryFunc = getBinaryWriterFunc(binaryWriter, attributeComponentKind); + if (writeBinaryFunc) { + for (var _i = 0, vertexAttributes_1 = vertexAttributes; _i < vertexAttributes_1.length; _i++) { + var vertexAttribute = vertexAttributes_1[_i]; + for (var _a = 0, vertexAttribute_1 = vertexAttribute; _a < vertexAttribute_1.length; _a++) { + var component = vertexAttribute_1[_a]; + writeBinaryFunc(component); + } + } + } + }; + _Exporter.prototype._createMorphTargetBufferViewKind = function (vertexBufferKind, accessorType, attributeComponentKind, mesh, morphTarget, binaryWriter, byteStride) { + var vertexCount; + var minMax; + var morphData = []; + var difference = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[0]; + switch (vertexBufferKind) { + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind: { + var morphPositions = morphTarget.getPositions(); + if (!morphPositions) { + return null; + } + var originalPositions = mesh.getVerticesData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind, undefined, undefined, true); + var vertexStart = 0; + var min = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3(Infinity, Infinity, Infinity); + var max = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3(-Infinity, -Infinity, -Infinity); + vertexCount = originalPositions.length / 3; + for (var i = vertexStart; i < vertexCount; ++i) { + var originalPosition = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(originalPositions, i * 3); + var morphPosition = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(morphPositions, i * 3); + morphPosition.subtractToRef(originalPosition, difference); + min.copyFromFloats(Math.min(difference.x, min.x), Math.min(difference.y, min.y), Math.min(difference.z, min.z)); + max.copyFromFloats(Math.max(difference.x, max.x), Math.max(difference.y, max.y), Math.max(difference.z, max.z)); + morphData.push(difference.x, difference.y, difference.z); + } + minMax = { min: min, max: max }; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind: { + var morphNormals = morphTarget.getNormals(); + if (!morphNormals) { + return null; + } + var originalNormals = mesh.getVerticesData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind, undefined, undefined, true); + var vertexStart = 0; + vertexCount = originalNormals.length / 3; + for (var i = vertexStart; i < vertexCount; ++i) { + var originalNormal = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(originalNormals, i * 3).normalize(); + var morphNormal = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(morphNormals, i * 3).normalize(); + morphNormal.subtractToRef(originalNormal, difference); + morphData.push(difference.x, difference.y, difference.z); + } + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind: { + var morphTangents = morphTarget.getTangents(); + if (!morphTangents) { + return null; + } + // Handedness cannot be displaced, so morph target tangents omit the w component + accessorType = "VEC3" /* AccessorType.VEC3 */; + byteStride = 12; // 3 components (x/y/z) * 4 bytes (float32) + var originalTangents = mesh.getVerticesData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind, undefined, undefined, true); + var vertexStart = 0; + vertexCount = originalTangents.length / 4; + for (var i = vertexStart; i < vertexCount; ++i) { + // Only read the x, y, z components and ignore w + var originalTangent = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(originalTangents, i * 4); + _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._NormalizeTangentFromRef(originalTangent); + // Morph target tangents omit the w component so it won't be present in the data + var morphTangent = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(morphTangents, i * 3); + _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._NormalizeTangentFromRef(morphTangent); + morphTangent.subtractToRef(originalTangent, difference); + morphData.push(difference.x, difference.y, difference.z); + } + break; + } + default: { + return null; + } + } + var binaryWriterFunc = getBinaryWriterFunc(binaryWriter, attributeComponentKind); + if (!binaryWriterFunc) { + return null; + } + var typeByteLength = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.GetTypeByteLength(attributeComponentKind); + var byteLength = morphData.length * typeByteLength; + var bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, "".concat(vertexBufferKind, " - ").concat(morphTarget.name, " (Morph Target)")); + this._bufferViews.push(bufferView); + var bufferViewIndex = this._bufferViews.length - 1; + for (var _i = 0, morphData_1 = morphData; _i < morphData_1.length; _i++) { + var value = morphData_1[_i]; + binaryWriterFunc(value); + } + return { bufferViewIndex: bufferViewIndex, vertexCount: vertexCount, accessorType: accessorType, minMax: minMax }; + }; + /** + * Generates glTF json data + * @param shouldUseGlb Indicates whether the json should be written for a glb file + * @param glTFPrefix Text to use when prefixing a glTF file + * @param prettyPrint Indicates whether the json file should be pretty printed (true) or not (false) + * @returns json data as string + */ + _Exporter.prototype._generateJSON = function (shouldUseGlb, glTFPrefix, prettyPrint) { + var _this = this; + var buffer = { byteLength: this._totalByteLength }; + var imageName; + var imageData; + var bufferView; + var byteOffset = this._totalByteLength; + if (buffer.byteLength) { + this._glTF.buffers = [buffer]; + } + if (this._nodes && this._nodes.length) { + this._glTF.nodes = this._nodes; + } + if (this._meshes && this._meshes.length) { + this._glTF.meshes = this._meshes; + } + if (this._scenes && this._scenes.length) { + this._glTF.scenes = this._scenes; + this._glTF.scene = 0; + } + if (this._cameras && this._cameras.length) { + this._glTF.cameras = this._cameras; + } + if (this._bufferViews && this._bufferViews.length) { + this._glTF.bufferViews = this._bufferViews; + } + if (this._accessors && this._accessors.length) { + this._glTF.accessors = this._accessors; + } + if (this._animations && this._animations.length) { + this._glTF.animations = this._animations; + } + if (this._materials && this._materials.length) { + this._glTF.materials = this._materials; + } + if (this._textures && this._textures.length) { + this._glTF.textures = this._textures; + } + if (this._samplers && this._samplers.length) { + this._glTF.samplers = this._samplers; + } + if (this._skins && this._skins.length) { + this._glTF.skins = this._skins; + } + if (this._images && this._images.length) { + if (!shouldUseGlb) { + this._glTF.images = this._images; + } + else { + this._glTF.images = []; + this._images.forEach(function (image) { + if (image.uri) { + imageData = _this._imageData[image.uri]; + _this._orderedImageData.push(imageData); + imageName = image.uri.split(".")[0] + " image"; + bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._CreateBufferView(0, byteOffset, imageData.data.byteLength, undefined, imageName); + byteOffset += imageData.data.byteLength; + _this._bufferViews.push(bufferView); + image.bufferView = _this._bufferViews.length - 1; + image.name = imageName; + image.mimeType = imageData.mimeType; + image.uri = undefined; + if (!_this._glTF.images) { + _this._glTF.images = []; + } + _this._glTF.images.push(image); + } + }); + // Replace uri with bufferview and mime type for glb + buffer.byteLength = byteOffset; + } + } + if (!shouldUseGlb) { + buffer.uri = glTFPrefix + ".bin"; + } + var jsonText = prettyPrint ? JSON.stringify(this._glTF, null, 2) : JSON.stringify(this._glTF); + return jsonText; + }; + /** + * Generates data for .gltf and .bin files based on the glTF prefix string + * @param glTFPrefix Text to use when prefixing a glTF file + * @param dispose Dispose the exporter + * @returns GLTFData with glTF file data + */ + _Exporter.prototype._generateGLTFAsync = function (glTFPrefix, dispose) { + var _this = this; + if (dispose === void 0) { dispose = true; } + return this._generateBinaryAsync().then(function (binaryBuffer) { + _this._extensionsOnExporting(); + var jsonText = _this._generateJSON(false, glTFPrefix, true); + var bin = new Blob([binaryBuffer], { type: "application/octet-stream" }); + var glTFFileName = glTFPrefix + ".gltf"; + var glTFBinFile = glTFPrefix + ".bin"; + var container = new _glTFData__WEBPACK_IMPORTED_MODULE_3__.GLTFData(); + container.glTFFiles[glTFFileName] = jsonText; + container.glTFFiles[glTFBinFile] = bin; + if (_this._imageData) { + for (var image in _this._imageData) { + container.glTFFiles[image] = new Blob([_this._imageData[image].data], { type: _this._imageData[image].mimeType }); + } + } + if (dispose) { + _this.dispose(); + } + return container; + }); + }; + /** + * Creates a binary buffer for glTF + * @returns array buffer for binary data + */ + _Exporter.prototype._generateBinaryAsync = function () { + var _this = this; + var binaryWriter = new _BinaryWriter(4); + return this._createSceneAsync(binaryWriter).then(function () { + if (_this._localEngine) { + _this._localEngine.dispose(); + } + return binaryWriter.getArrayBuffer(); + }); + }; + /** + * Pads the number to a multiple of 4 + * @param num number to pad + * @returns padded number + */ + _Exporter.prototype._getPadding = function (num) { + var remainder = num % 4; + var padding = remainder === 0 ? remainder : 4 - remainder; + return padding; + }; + /** + * @internal + */ + _Exporter.prototype._generateGLBAsync = function (glTFPrefix, dispose) { + var _this = this; + if (dispose === void 0) { dispose = true; } + return this._generateBinaryAsync().then(function (binaryBuffer) { + _this._extensionsOnExporting(); + var jsonText = _this._generateJSON(true); + var glbFileName = glTFPrefix + ".glb"; + var headerLength = 12; + var chunkLengthPrefix = 8; + var jsonLength = jsonText.length; + var encodedJsonText; + var imageByteLength = 0; + // make use of TextEncoder when available + if (typeof TextEncoder !== "undefined") { + var encoder = new TextEncoder(); + encodedJsonText = encoder.encode(jsonText); + jsonLength = encodedJsonText.length; + } + for (var i = 0; i < _this._orderedImageData.length; ++i) { + imageByteLength += _this._orderedImageData[i].data.byteLength; + } + var jsonPadding = _this._getPadding(jsonLength); + var binPadding = _this._getPadding(binaryBuffer.byteLength); + var imagePadding = _this._getPadding(imageByteLength); + var byteLength = headerLength + 2 * chunkLengthPrefix + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength + imagePadding; + //header + var headerBuffer = new ArrayBuffer(headerLength); + var headerBufferView = new DataView(headerBuffer); + headerBufferView.setUint32(0, 0x46546c67, true); //glTF + headerBufferView.setUint32(4, 2, true); // version + headerBufferView.setUint32(8, byteLength, true); // total bytes in file + //json chunk + var jsonChunkBuffer = new ArrayBuffer(chunkLengthPrefix + jsonLength + jsonPadding); + var jsonChunkBufferView = new DataView(jsonChunkBuffer); + jsonChunkBufferView.setUint32(0, jsonLength + jsonPadding, true); + jsonChunkBufferView.setUint32(4, 0x4e4f534a, true); + //json chunk bytes + var jsonData = new Uint8Array(jsonChunkBuffer, chunkLengthPrefix); + // if TextEncoder was available, we can simply copy the encoded array + if (encodedJsonText) { + jsonData.set(encodedJsonText); + } + else { + var blankCharCode = "_".charCodeAt(0); + for (var i = 0; i < jsonLength; ++i) { + var charCode = jsonText.charCodeAt(i); + // if the character doesn't fit into a single UTF-16 code unit, just put a blank character + if (charCode != jsonText.codePointAt(i)) { + jsonData[i] = blankCharCode; + } + else { + jsonData[i] = charCode; + } + } + } + //json padding + var jsonPaddingView = new Uint8Array(jsonChunkBuffer, chunkLengthPrefix + jsonLength); + for (var i = 0; i < jsonPadding; ++i) { + jsonPaddingView[i] = 0x20; + } + //binary chunk + var binaryChunkBuffer = new ArrayBuffer(chunkLengthPrefix); + var binaryChunkBufferView = new DataView(binaryChunkBuffer); + binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + imageByteLength + imagePadding, true); + binaryChunkBufferView.setUint32(4, 0x004e4942, true); + // binary padding + var binPaddingBuffer = new ArrayBuffer(binPadding); + var binPaddingView = new Uint8Array(binPaddingBuffer); + for (var i = 0; i < binPadding; ++i) { + binPaddingView[i] = 0; + } + var imagePaddingBuffer = new ArrayBuffer(imagePadding); + var imagePaddingView = new Uint8Array(imagePaddingBuffer); + for (var i = 0; i < imagePadding; ++i) { + imagePaddingView[i] = 0; + } + var glbData = [headerBuffer, jsonChunkBuffer, binaryChunkBuffer, binaryBuffer]; + // binary data + for (var i = 0; i < _this._orderedImageData.length; ++i) { + glbData.push(_this._orderedImageData[i].data); + } + glbData.push(binPaddingBuffer); + glbData.push(imagePaddingBuffer); + var glbFile = new Blob(glbData, { type: "application/octet-stream" }); + var container = new _glTFData__WEBPACK_IMPORTED_MODULE_3__.GLTFData(); + container.glTFFiles[glbFileName] = glbFile; + if (_this._localEngine != null) { + _this._localEngine.dispose(); + } + if (dispose) { + _this.dispose(); + } + return container; + }); + }; + /** + * Sets the TRS for each node + * @param node glTF Node for storing the transformation data + * @param babylonTransformNode Babylon mesh used as the source for the transformation data + */ + _Exporter.prototype._setNodeTransformation = function (node, babylonTransformNode) { + if (!babylonTransformNode.getPivotPoint().equalsToFloats(0, 0, 0)) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("Pivot points are not supported in the glTF serializer"); + } + if (!babylonTransformNode.position.equalsToFloats(0, 0, 0)) { + node.translation = babylonTransformNode.position.asArray(); + } + if (!babylonTransformNode.scaling.equalsToFloats(1, 1, 1)) { + node.scale = babylonTransformNode.scaling.asArray(); + } + var rotationQuaternion = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromEulerAngles(babylonTransformNode.rotation.x, babylonTransformNode.rotation.y, babylonTransformNode.rotation.z); + if (babylonTransformNode.rotationQuaternion) { + rotationQuaternion.multiplyInPlace(babylonTransformNode.rotationQuaternion); + } + if (!babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.IsIdentity(rotationQuaternion)) { + node.rotation = rotationQuaternion.normalize().asArray(); + } + }; + _Exporter.prototype._setCameraTransformation = function (node, babylonCamera) { + var translation = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[0]; + var rotation = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Quaternion[0]; + babylonCamera.getWorldMatrix().decompose(undefined, rotation, translation); + if (!translation.equalsToFloats(0, 0, 0)) { + node.translation = translation.asArray(); + } + // // Rotation by 180 as glTF has a different convention than Babylon. + rotation.multiplyInPlace(rotation180Y); + if (!babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.IsIdentity(rotation)) { + node.rotation = rotation.asArray(); + } + }; + _Exporter.prototype._getVertexBufferFromMesh = function (attributeKind, bufferMesh) { + if (bufferMesh.isVerticesDataPresent(attributeKind, true)) { + var vertexBuffer = bufferMesh.getVertexBuffer(attributeKind, true); + if (vertexBuffer) { + return vertexBuffer; + } + } + return null; + }; + /** + * Creates a bufferview based on the vertices type for the Babylon mesh + * @param kind Indicates the type of vertices data + * @param attributeComponentKind Indicates the numerical type used to store the data + * @param babylonTransformNode The Babylon mesh to get the vertices data from + * @param binaryWriter The buffer to write the bufferview data to + * @param byteStride + */ + _Exporter.prototype._createBufferViewKind = function (kind, attributeComponentKind, babylonTransformNode, binaryWriter, byteStride) { + var bufferMesh = babylonTransformNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Mesh + ? babylonTransformNode + : babylonTransformNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.InstancedMesh + ? babylonTransformNode.sourceMesh + : null; + if (bufferMesh) { + var vertexBuffer = bufferMesh.getVertexBuffer(kind, true); + var vertexData = bufferMesh.getVerticesData(kind, undefined, undefined, true); + if (vertexBuffer && vertexData) { + var typeByteLength = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.GetTypeByteLength(attributeComponentKind); + var byteLength = vertexData.length * typeByteLength; + var bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, kind + " - " + bufferMesh.name); + this._bufferViews.push(bufferView); + this._writeAttributeData(kind, attributeComponentKind, vertexData, byteStride / typeByteLength, binaryWriter, babylonTransformNode); + } + } + }; + /** + * The primitive mode of the Babylon mesh + * @param babylonMesh The BabylonJS mesh + * @returns Unsigned integer of the primitive mode or null + */ + _Exporter.prototype._getMeshPrimitiveMode = function (babylonMesh) { + if (babylonMesh instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.LinesMesh) { + return babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.LineListDrawMode; + } + if (babylonMesh instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.InstancedMesh || babylonMesh instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Mesh) { + var baseMesh = babylonMesh instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Mesh ? babylonMesh : babylonMesh.sourceMesh; + if (typeof baseMesh.overrideRenderingFillMode === "number") { + return baseMesh.overrideRenderingFillMode; + } + } + return babylonMesh.material ? babylonMesh.material.fillMode : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleFillMode; + }; + /** + * Sets the primitive mode of the glTF mesh primitive + * @param meshPrimitive glTF mesh primitive + * @param primitiveMode The primitive mode + */ + _Exporter.prototype._setPrimitiveMode = function (meshPrimitive, primitiveMode) { + switch (primitiveMode) { + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleFillMode: { + // glTF defaults to using Triangle Mode + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleStripDrawMode: { + meshPrimitive.mode = 5 /* MeshPrimitiveMode.TRIANGLE_STRIP */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleFanDrawMode: { + meshPrimitive.mode = 6 /* MeshPrimitiveMode.TRIANGLE_FAN */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.PointListDrawMode: { + meshPrimitive.mode = 0 /* MeshPrimitiveMode.POINTS */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.PointFillMode: { + meshPrimitive.mode = 0 /* MeshPrimitiveMode.POINTS */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.LineLoopDrawMode: { + meshPrimitive.mode = 2 /* MeshPrimitiveMode.LINE_LOOP */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.LineListDrawMode: { + meshPrimitive.mode = 1 /* MeshPrimitiveMode.LINES */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.LineStripDrawMode: { + meshPrimitive.mode = 3 /* MeshPrimitiveMode.LINE_STRIP */; + break; + } + } + }; + /** + * Sets the vertex attribute accessor based of the glTF mesh primitive + * @param meshPrimitive glTF mesh primitive + * @param attributeKind vertex attribute + */ + _Exporter.prototype._setAttributeKind = function (attributes, attributeKind) { + switch (attributeKind) { + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind: { + attributes.POSITION = this._accessors.length - 1; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind: { + attributes.NORMAL = this._accessors.length - 1; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ColorKind: { + attributes.COLOR_0 = this._accessors.length - 1; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind: { + attributes.TANGENT = this._accessors.length - 1; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UVKind: { + attributes.TEXCOORD_0 = this._accessors.length - 1; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV2Kind: { + attributes.TEXCOORD_1 = this._accessors.length - 1; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesKind: { + attributes.JOINTS_0 = this._accessors.length - 1; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesExtraKind: { + attributes.JOINTS_1 = this._accessors.length - 1; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesWeightsKind: { + attributes.WEIGHTS_0 = this._accessors.length - 1; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesWeightsExtraKind: { + attributes.WEIGHTS_1 = this._accessors.length - 1; + break; + } + default: { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind); + } + } + }; + /** + * Sets data for the primitive attributes of each submesh + * @param mesh glTF Mesh object to store the primitive attribute information + * @param babylonTransformNode Babylon mesh to get the primitive attribute data from + * @param binaryWriter Buffer to write the attribute data to + * @returns promise that resolves when done setting the primitive attributes + */ + _Exporter.prototype._setPrimitiveAttributesAsync = function (mesh, babylonTransformNode, binaryWriter) { + var _a, _b, _c, _d, _e, _f, _g; + var promises = []; + var bufferMesh = null; + var bufferView; + var minMax; + if (babylonTransformNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Mesh) { + bufferMesh = babylonTransformNode; + } + else if (babylonTransformNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.InstancedMesh) { + bufferMesh = babylonTransformNode.sourceMesh; + } + var attributeData = [ + { kind: babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind, accessorType: "VEC3" /* AccessorType.VEC3 */, accessorComponentType: 5126 /* AccessorComponentType.FLOAT */, byteStride: 12 }, + { kind: babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind, accessorType: "VEC3" /* AccessorType.VEC3 */, accessorComponentType: 5126 /* AccessorComponentType.FLOAT */, byteStride: 12 }, + { kind: babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ColorKind, accessorType: "VEC4" /* AccessorType.VEC4 */, accessorComponentType: 5126 /* AccessorComponentType.FLOAT */, byteStride: 16 }, + { kind: babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind, accessorType: "VEC4" /* AccessorType.VEC4 */, accessorComponentType: 5126 /* AccessorComponentType.FLOAT */, byteStride: 16 }, + { kind: babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UVKind, accessorType: "VEC2" /* AccessorType.VEC2 */, accessorComponentType: 5126 /* AccessorComponentType.FLOAT */, byteStride: 8 }, + { kind: babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV2Kind, accessorType: "VEC2" /* AccessorType.VEC2 */, accessorComponentType: 5126 /* AccessorComponentType.FLOAT */, byteStride: 8 }, + { kind: babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesKind, accessorType: "VEC4" /* AccessorType.VEC4 */, accessorComponentType: 5123 /* AccessorComponentType.UNSIGNED_SHORT */, byteStride: 8 }, + { kind: babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesExtraKind, accessorType: "VEC4" /* AccessorType.VEC4 */, accessorComponentType: 5123 /* AccessorComponentType.UNSIGNED_SHORT */, byteStride: 8 }, + { kind: babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesWeightsKind, accessorType: "VEC4" /* AccessorType.VEC4 */, accessorComponentType: 5126 /* AccessorComponentType.FLOAT */, byteStride: 16 }, + { kind: babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesWeightsExtraKind, accessorType: "VEC4" /* AccessorType.VEC4 */, accessorComponentType: 5126 /* AccessorComponentType.FLOAT */, byteStride: 16 }, + ]; + if (bufferMesh) { + var indexBufferViewIndex = null; + var primitiveMode = this._getMeshPrimitiveMode(bufferMesh); + var vertexAttributeBufferViews = {}; + var morphTargetManager = bufferMesh.morphTargetManager; + // For each BabylonMesh, create bufferviews for each 'kind' + for (var _i = 0, attributeData_1 = attributeData; _i < attributeData_1.length; _i++) { + var attribute = attributeData_1[_i]; + var attributeKind = attribute.kind; + var attributeComponentKind = attribute.accessorComponentType; + if (bufferMesh.isVerticesDataPresent(attributeKind, true)) { + var vertexBuffer = this._getVertexBufferFromMesh(attributeKind, bufferMesh); + attribute.byteStride = vertexBuffer + ? vertexBuffer.getSize() * babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.GetTypeByteLength(attribute.accessorComponentType) + : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.DeduceStride(attributeKind) * 4; + if (attribute.byteStride === 12) { + attribute.accessorType = "VEC3" /* AccessorType.VEC3 */; + } + this._createBufferViewKind(attributeKind, attributeComponentKind, babylonTransformNode, binaryWriter, attribute.byteStride); + attribute.bufferViewIndex = this._bufferViews.length - 1; + vertexAttributeBufferViews[attributeKind] = attribute.bufferViewIndex; + // Write any morph target data to the buffer and create an associated buffer view + if (morphTargetManager) { + for (var i = 0; i < morphTargetManager.numTargets; ++i) { + var morphTarget = morphTargetManager.getTarget(i); + var morphTargetInfo = this._createMorphTargetBufferViewKind(attributeKind, attribute.accessorType, attributeComponentKind, bufferMesh, morphTarget, binaryWriter, attribute.byteStride); + // Store info about the morph target that will be needed later when creating per-submesh accessors + if (morphTargetInfo) { + if (!attribute.morphTargetInfo) { + attribute.morphTargetInfo = []; + } + attribute.morphTargetInfo[i] = morphTargetInfo; + } + } + } + } + } + if (bufferMesh.getTotalIndices()) { + var indices = bufferMesh.getIndices(); + if (indices) { + var byteLength = indices.length * 4; + bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, undefined, "Indices - " + bufferMesh.name); + this._bufferViews.push(bufferView); + indexBufferViewIndex = this._bufferViews.length - 1; + for (var k = 0, length_9 = indices.length; k < length_9; ++k) { + binaryWriter.setUInt32(indices[k]); + } + } + } + if (bufferMesh.subMeshes) { + // go through all mesh primitives (submeshes) + for (var _h = 0, _j = bufferMesh.subMeshes; _h < _j.length; _h++) { + var submesh = _j[_h]; + var babylonMaterial = submesh.getMaterial() || bufferMesh.getScene().defaultMaterial; + var materialIndex = null; + if (babylonMaterial) { + if (bufferMesh instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.LinesMesh) { + // get the color from the lines mesh and set it in the material + var material = { + name: bufferMesh.name + " material", + }; + if (!bufferMesh.color.equals(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.White()) || bufferMesh.alpha < 1) { + material.pbrMetallicRoughness = { + baseColorFactor: bufferMesh.color.asArray().concat([bufferMesh.alpha]), + }; + } + this._materials.push(material); + materialIndex = this._materials.length - 1; + } + else if (babylonMaterial instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.MultiMaterial) { + var subMaterial = babylonMaterial.subMaterials[submesh.materialIndex]; + if (subMaterial) { + babylonMaterial = subMaterial; + materialIndex = this._materialMap[babylonMaterial.uniqueId]; + } + } + else { + materialIndex = this._materialMap[babylonMaterial.uniqueId]; + } + } + var glTFMaterial = materialIndex != null ? this._materials[materialIndex] : null; + var meshPrimitive = { attributes: {} }; + this._setPrimitiveMode(meshPrimitive, primitiveMode); + for (var _k = 0, attributeData_2 = attributeData; _k < attributeData_2.length; _k++) { + var attribute = attributeData_2[_k]; + var attributeKind = attribute.kind; + if ((attributeKind === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UVKind || attributeKind === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV2Kind) && !this._options.exportUnusedUVs) { + if (!glTFMaterial || !this._glTFMaterialExporter._hasTexturesPresent(glTFMaterial)) { + continue; + } + } + var vertexData = bufferMesh.getVerticesData(attributeKind, undefined, undefined, true); + if (vertexData) { + var vertexBuffer = this._getVertexBufferFromMesh(attributeKind, bufferMesh); + if (vertexBuffer) { + var stride = vertexBuffer.getSize(); + var bufferViewIndex = attribute.bufferViewIndex; + if (bufferViewIndex != undefined) { + // check to see if bufferviewindex has a numeric value assigned. + minMax = { min: null, max: null }; + if (attributeKind == babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind) { + minMax = _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._CalculateMinMaxPositions(vertexData, 0, vertexData.length / stride); + } + var accessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._CreateAccessor(bufferViewIndex, attributeKind + " - " + babylonTransformNode.name, attribute.accessorType, attribute.accessorComponentType, vertexData.length / stride, 0, minMax.min, minMax.max); + this._accessors.push(accessor); + this._setAttributeKind(meshPrimitive.attributes, attributeKind); + } + } + } + } + if (indexBufferViewIndex) { + // Create accessor + var accessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._CreateAccessor(indexBufferViewIndex, "indices - " + babylonTransformNode.name, "SCALAR" /* AccessorType.SCALAR */, 5125 /* AccessorComponentType.UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4, null, null); + this._accessors.push(accessor); + meshPrimitive.indices = this._accessors.length - 1; + } + if (Object.keys(meshPrimitive.attributes).length > 0) { + var sideOrientation = babylonMaterial._getEffectiveOrientation(bufferMesh); + if (sideOrientation === (this._babylonScene.useRightHandedSystem ? babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.ClockWiseSideOrientation : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Material.CounterClockWiseSideOrientation)) { + var byteOffset = indexBufferViewIndex != null ? this._bufferViews[indexBufferViewIndex].byteOffset : null; + if (byteOffset == null) { + byteOffset = 0; + } + var babylonIndices = null; + if (indexBufferViewIndex != null) { + babylonIndices = bufferMesh.getIndices(); + } + if (babylonIndices) { + this._reorderIndicesBasedOnPrimitiveMode(submesh, primitiveMode, babylonIndices, byteOffset, binaryWriter); + } + else { + for (var _l = 0, attributeData_3 = attributeData; _l < attributeData_3.length; _l++) { + var attribute = attributeData_3[_l]; + var vertexData = bufferMesh.getVerticesData(attribute.kind, undefined, undefined, true); + if (vertexData) { + var byteOffset_1 = this._bufferViews[vertexAttributeBufferViews[attribute.kind]].byteOffset || 0; + this._reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, attribute.kind, vertexData, byteOffset_1, binaryWriter); + } + } + } + } + if (materialIndex != null) { + meshPrimitive.material = materialIndex; + } + } + // If there are morph targets, write out targets and associated accessors + if (morphTargetManager) { + // By convention, morph target names are stored in the mesh extras. + if (!mesh.extras) { + mesh.extras = {}; + } + mesh.extras.targetNames = []; + for (var i = 0; i < morphTargetManager.numTargets; ++i) { + var morphTarget = morphTargetManager.getTarget(i); + mesh.extras.targetNames.push(morphTarget.name); + for (var _m = 0, attributeData_4 = attributeData; _m < attributeData_4.length; _m++) { + var attribute = attributeData_4[_m]; + var morphTargetInfo = (_a = attribute.morphTargetInfo) === null || _a === void 0 ? void 0 : _a[i]; + if (morphTargetInfo) { + // Write the accessor + var byteOffset = 0; + var accessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._CreateAccessor(morphTargetInfo.bufferViewIndex, "".concat(attribute.kind, " - ").concat(morphTarget.name, " (Morph Target)"), morphTargetInfo.accessorType, attribute.accessorComponentType, morphTargetInfo.vertexCount, byteOffset, (_d = (_c = (_b = morphTargetInfo.minMax) === null || _b === void 0 ? void 0 : _b.min) === null || _c === void 0 ? void 0 : _c.asArray()) !== null && _d !== void 0 ? _d : null, (_g = (_f = (_e = morphTargetInfo.minMax) === null || _e === void 0 ? void 0 : _e.max) === null || _f === void 0 ? void 0 : _f.asArray()) !== null && _g !== void 0 ? _g : null); + this._accessors.push(accessor); + // Create a target that references the new accessor + if (!meshPrimitive.targets) { + meshPrimitive.targets = []; + } + if (!meshPrimitive.targets[i]) { + meshPrimitive.targets[i] = {}; + } + this._setAttributeKind(meshPrimitive.targets[i], attribute.kind); + } + } + } + } + mesh.primitives.push(meshPrimitive); + this._extensionsPostExportMeshPrimitiveAsync("postExport", meshPrimitive, submesh, binaryWriter); + promises.push(); + } + } + } + return Promise.all(promises).then(function () { + /* do nothing */ + }); + }; + /** + * Creates a glTF scene based on the array of meshes + * Returns the total byte offset + * @param binaryWriter Buffer to write binary data to + * @returns a promise that resolves when done + */ + _Exporter.prototype._createSceneAsync = function (binaryWriter) { + var _this = this; + var _a; + var scene = { nodes: [] }; + var glTFNodeIndex; + var glTFNode; + var directDescendents; + var nodes = (0,tslib__WEBPACK_IMPORTED_MODULE_5__.__spreadArray)((0,tslib__WEBPACK_IMPORTED_MODULE_5__.__spreadArray)((0,tslib__WEBPACK_IMPORTED_MODULE_5__.__spreadArray)((0,tslib__WEBPACK_IMPORTED_MODULE_5__.__spreadArray)([], this._babylonScene.transformNodes, true), this._babylonScene.meshes, true), this._babylonScene.lights, true), this._babylonScene.cameras, true); + var removedRootNodes = new Set(); + // Scene metadata + if (this._babylonScene.metadata) { + if (this._options.metadataSelector) { + scene.extras = this._options.metadataSelector(this._babylonScene.metadata); + } + else if (this._babylonScene.metadata.gltf) { + scene.extras = this._babylonScene.metadata.gltf.extras; + } + } + // Remove no-op root nodes + if (((_a = this._options.removeNoopRootNodes) !== null && _a !== void 0 ? _a : true) && !this._options.includeCoordinateSystemConversionNodes) { + for (var _i = 0, _b = this._babylonScene.rootNodes; _i < _b.length; _i++) { + var rootNode = _b[_i]; + if (isNoopNode(rootNode, this._babylonScene.useRightHandedSystem)) { + removedRootNodes.add(rootNode); + // Exclude the node from list of nodes to export + nodes.splice(nodes.indexOf(rootNode), 1); + } + } + } + // Export babylon cameras to glTFCamera + var cameraMap = new Map(); + this._babylonScene.cameras.forEach(function (camera) { + if (_this._options.shouldExportNode && !_this._options.shouldExportNode(camera)) { + return; + } + var glTFCamera = { + type: camera.mode === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Camera.PERSPECTIVE_CAMERA ? "perspective" /* CameraType.PERSPECTIVE */ : "orthographic" /* CameraType.ORTHOGRAPHIC */, + }; + if (camera.name) { + glTFCamera.name = camera.name; + } + if (glTFCamera.type === "perspective" /* CameraType.PERSPECTIVE */) { + glTFCamera.perspective = { + aspectRatio: camera.getEngine().getAspectRatio(camera), + yfov: camera.fovMode === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Camera.FOVMODE_VERTICAL_FIXED ? camera.fov : camera.fov * camera.getEngine().getAspectRatio(camera), + znear: camera.minZ, + zfar: camera.maxZ, + }; + } + else if (glTFCamera.type === "orthographic" /* CameraType.ORTHOGRAPHIC */) { + var halfWidth = camera.orthoLeft && camera.orthoRight ? 0.5 * (camera.orthoRight - camera.orthoLeft) : camera.getEngine().getRenderWidth() * 0.5; + var halfHeight = camera.orthoBottom && camera.orthoTop ? 0.5 * (camera.orthoTop - camera.orthoBottom) : camera.getEngine().getRenderHeight() * 0.5; + glTFCamera.orthographic = { + xmag: halfWidth, + ymag: halfHeight, + znear: camera.minZ, + zfar: camera.maxZ, + }; + } + cameraMap.set(camera, _this._cameras.length); + _this._cameras.push(glTFCamera); + }); + var _c = this._getExportNodes(nodes), exportNodes = _c[0], exportMaterials = _c[1]; + return this._glTFMaterialExporter._convertMaterialsToGLTFAsync(exportMaterials, "image/png" /* ImageMimeType.PNG */, true).then(function () { + return _this._createNodeMapAndAnimationsAsync(exportNodes, binaryWriter).then(function (nodeMap) { + return _this._createSkinsAsync(nodeMap, binaryWriter).then(function (skinMap) { + _this._nodeMap = nodeMap; + _this._totalByteLength = binaryWriter.getByteOffset(); + if (_this._totalByteLength == undefined) { + throw new Error("undefined byte length!"); + } + // Build Hierarchy with the node map. + for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) { + var babylonNode = nodes_1[_i]; + glTFNodeIndex = _this._nodeMap[babylonNode.uniqueId]; + if (glTFNodeIndex !== undefined) { + glTFNode = _this._nodes[glTFNodeIndex]; + if (babylonNode.metadata) { + if (_this._options.metadataSelector) { + glTFNode.extras = _this._options.metadataSelector(babylonNode.metadata); + } + else if (babylonNode.metadata.gltf) { + glTFNode.extras = babylonNode.metadata.gltf.extras; + } + } + if (babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Camera) { + glTFNode.camera = cameraMap.get(babylonNode); + } + if (_this._options.shouldExportNode && !_this._options.shouldExportNode(babylonNode)) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Log("Omitting " + babylonNode.name + " from scene."); + } + else { + if (!babylonNode.parent && !_this._babylonScene.useRightHandedSystem) { + convertNodeHandedness(glTFNode); + } + if (!babylonNode.parent || removedRootNodes.has(babylonNode.parent)) { + scene.nodes.push(glTFNodeIndex); + } + } + if (babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Mesh) { + if (babylonNode.skeleton) { + glTFNode.skin = skinMap[babylonNode.skeleton.uniqueId]; + } + } + directDescendents = babylonNode.getDescendants(true); + if (!glTFNode.children && directDescendents && directDescendents.length) { + var children = []; + for (var _a = 0, directDescendents_1 = directDescendents; _a < directDescendents_1.length; _a++) { + var descendent = directDescendents_1[_a]; + if (_this._nodeMap[descendent.uniqueId] != null) { + children.push(_this._nodeMap[descendent.uniqueId]); + } + } + if (children.length) { + glTFNode.children = children; + } + } + } + } + if (scene.nodes.length) { + _this._scenes.push(scene); + } + }); + }); + }); + }; + /** + * Getting the nodes and materials that would be exported. + * @param nodes Babylon transform nodes + * @returns Set of materials which would be exported. + */ + _Exporter.prototype._getExportNodes = function (nodes) { + var exportNodes = []; + var exportMaterials = new Set(); + for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) { + var babylonNode = nodes_2[_i]; + if (!this._options.shouldExportNode || this._options.shouldExportNode(babylonNode)) { + exportNodes.push(babylonNode); + var babylonMesh = babylonNode; + if (babylonMesh.subMeshes && babylonMesh.subMeshes.length > 0) { + var material = babylonMesh.material || babylonMesh.getScene().defaultMaterial; + if (material instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.MultiMaterial) { + for (var _a = 0, _b = material.subMaterials; _a < _b.length; _a++) { + var subMaterial = _b[_a]; + if (subMaterial) { + exportMaterials.add(subMaterial); + } + } + } + else { + exportMaterials.add(material); + } + } + } + else { + "Excluding node ".concat(babylonNode.name); + } + } + return [exportNodes, exportMaterials]; + }; + /** + * Creates a mapping of Node unique id to node index and handles animations + * @param nodes Babylon transform nodes + * @param binaryWriter Buffer to write binary data to + * @returns Node mapping of unique id to index + */ + _Exporter.prototype._createNodeMapAndAnimationsAsync = function (nodes, binaryWriter) { + var _this = this; + var promiseChain = Promise.resolve(); + var nodeMap = {}; + var nodeIndex; + var runtimeGLTFAnimation = { + name: "runtime animations", + channels: [], + samplers: [], + }; + var idleGLTFAnimations = []; + var _loop_1 = function (babylonNode) { + promiseChain = promiseChain.then(function () { + return _this._createNodeAsync(babylonNode, binaryWriter).then(function (node) { + var promise = _this._extensionsPostExportNodeAsync("createNodeAsync", node, babylonNode, nodeMap, binaryWriter); + if (promise == null) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("Not exporting node ".concat(babylonNode.name)); + return Promise.resolve(); + } + else { + return promise.then(function (node) { + if (!node) { + return; + } + _this._nodes.push(node); + nodeIndex = _this._nodes.length - 1; + nodeMap[babylonNode.uniqueId] = nodeIndex; + if (!_this._babylonScene.animationGroups.length) { + _glTFAnimation__WEBPACK_IMPORTED_MODULE_4__._GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._animationSampleRate, _this._options.shouldExportAnimation); + if (babylonNode.animations.length) { + _glTFAnimation__WEBPACK_IMPORTED_MODULE_4__._GLTFAnimation._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._animationSampleRate, _this._options.shouldExportAnimation); + } + } + }); + } + }); + }); + }; + for (var _i = 0, nodes_3 = nodes; _i < nodes_3.length; _i++) { + var babylonNode = nodes_3[_i]; + _loop_1(babylonNode); + } + return promiseChain.then(function () { + if (runtimeGLTFAnimation.channels.length && runtimeGLTFAnimation.samplers.length) { + _this._animations.push(runtimeGLTFAnimation); + } + idleGLTFAnimations.forEach(function (idleGLTFAnimation) { + if (idleGLTFAnimation.channels.length && idleGLTFAnimation.samplers.length) { + _this._animations.push(idleGLTFAnimation); + } + }); + if (_this._babylonScene.animationGroups.length) { + _glTFAnimation__WEBPACK_IMPORTED_MODULE_4__._GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(_this._babylonScene, _this._animations, nodeMap, binaryWriter, _this._bufferViews, _this._accessors, _this._animationSampleRate, _this._options.shouldExportAnimation); + } + return nodeMap; + }); + }; + /** + * Creates a glTF node from a Babylon mesh + * @param babylonNode Source Babylon mesh + * @param binaryWriter Buffer for storing geometry data + * @returns glTF node + */ + _Exporter.prototype._createNodeAsync = function (babylonNode, binaryWriter) { + var _this = this; + return Promise.resolve().then(function () { + // create node to hold translation/rotation/scale and the mesh + var node = {}; + // create mesh + var mesh = { primitives: [] }; + if (babylonNode.name) { + node.name = babylonNode.name; + } + if (babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TransformNode) { + // Set transformation + _this._setNodeTransformation(node, babylonNode); + if (babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Mesh) { + var morphTargetManager = babylonNode.morphTargetManager; + if (morphTargetManager && morphTargetManager.numTargets > 0) { + mesh.weights = []; + for (var i = 0; i < morphTargetManager.numTargets; ++i) { + mesh.weights.push(morphTargetManager.getTarget(i).influence); + } + } + } + return _this._setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter).then(function () { + if (mesh.primitives.length) { + _this._meshes.push(mesh); + node.mesh = _this._meshes.length - 1; + } + return node; + }); + } + else if (babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Camera) { + _this._setCameraTransformation(node, babylonNode); + return node; + } + else { + return node; + } + }); + }; + /** + * Creates a glTF skin from a Babylon skeleton + * @param nodeMap Babylon transform nodes + * @param binaryWriter Buffer to write binary data to + * @returns Node mapping of unique id to index + */ + _Exporter.prototype._createSkinsAsync = function (nodeMap, binaryWriter) { + var _a; + var promiseChain = Promise.resolve(); + var skinMap = {}; + for (var _i = 0, _b = this._babylonScene.skeletons; _i < _b.length; _i++) { + var skeleton = _b[_i]; + if (skeleton.bones.length <= 0) { + continue; + } + // create skin + var skin = { joints: [] }; + var inverseBindMatrices = []; + var boneIndexMap = {}; + var maxBoneIndex = -1; + for (var i = 0; i < skeleton.bones.length; ++i) { + var bone = skeleton.bones[i]; + var boneIndex = (_a = bone.getIndex()) !== null && _a !== void 0 ? _a : i; + if (boneIndex !== -1) { + boneIndexMap[boneIndex] = bone; + if (boneIndex > maxBoneIndex) { + maxBoneIndex = boneIndex; + } + } + } + for (var boneIndex = 0; boneIndex <= maxBoneIndex; ++boneIndex) { + var bone = boneIndexMap[boneIndex]; + inverseBindMatrices.push(bone.getInvertedAbsoluteTransform()); + var transformNode = bone.getTransformNode(); + if (transformNode && nodeMap[transformNode.uniqueId] !== null && nodeMap[transformNode.uniqueId] !== undefined) { + skin.joints.push(nodeMap[transformNode.uniqueId]); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("Exporting a bone without a linked transform node is currently unsupported"); + } + } + if (skin.joints.length > 0) { + // create buffer view for inverse bind matrices + var byteStride = 64; // 4 x 4 matrix of 32 bit float + var byteLength = inverseBindMatrices.length * byteStride; + var bufferViewOffset = binaryWriter.getByteOffset(); + var bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._CreateBufferView(0, bufferViewOffset, byteLength, undefined, "InverseBindMatrices" + " - " + skeleton.name); + this._bufferViews.push(bufferView); + var bufferViewIndex = this._bufferViews.length - 1; + var bindMatrixAccessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__._GLTFUtilities._CreateAccessor(bufferViewIndex, "InverseBindMatrices" + " - " + skeleton.name, "MAT4" /* AccessorType.MAT4 */, 5126 /* AccessorComponentType.FLOAT */, inverseBindMatrices.length, null, null, null); + var inverseBindAccessorIndex = this._accessors.push(bindMatrixAccessor) - 1; + skin.inverseBindMatrices = inverseBindAccessorIndex; + this._skins.push(skin); + skinMap[skeleton.uniqueId] = this._skins.length - 1; + inverseBindMatrices.forEach(function (mat) { + mat.m.forEach(function (cell) { + binaryWriter.setFloat32(cell); + }); + }); + } + } + return promiseChain.then(function () { + return skinMap; + }); + }; + _Exporter._ExtensionNames = new Array(); + _Exporter._ExtensionFactories = {}; + return _Exporter; +}()); + +/** + * @internal + * + * Stores glTF binary data. If the array buffer byte length is exceeded, it doubles in size dynamically + */ +var _BinaryWriter = /** @class */ (function () { + /** + * Initialize binary writer with an initial byte length + * @param byteLength Initial byte length of the array buffer + */ + function _BinaryWriter(byteLength) { + this._arrayBuffer = new ArrayBuffer(byteLength); + this._dataView = new DataView(this._arrayBuffer); + this._byteOffset = 0; + } + /** + * Resize the array buffer to the specified byte length + * @param byteLength The new byte length + * @returns The resized array buffer + */ + _BinaryWriter.prototype._resizeBuffer = function (byteLength) { + var newBuffer = new ArrayBuffer(byteLength); + var copyOldBufferSize = Math.min(this._arrayBuffer.byteLength, byteLength); + var oldUint8Array = new Uint8Array(this._arrayBuffer, 0, copyOldBufferSize); + var newUint8Array = new Uint8Array(newBuffer); + newUint8Array.set(oldUint8Array, 0); + this._arrayBuffer = newBuffer; + this._dataView = new DataView(this._arrayBuffer); + return newBuffer; + }; + /** + * Get an array buffer with the length of the byte offset + * @returns ArrayBuffer resized to the byte offset + */ + _BinaryWriter.prototype.getArrayBuffer = function () { + return this._resizeBuffer(this.getByteOffset()); + }; + /** + * Get the byte offset of the array buffer + * @returns byte offset + */ + _BinaryWriter.prototype.getByteOffset = function () { + if (this._byteOffset == undefined) { + throw new Error("Byte offset is undefined!"); + } + return this._byteOffset; + }; + /** + * Stores an UInt8 in the array buffer + * @param entry + * @param byteOffset If defined, specifies where to set the value as an offset. + */ + _BinaryWriter.prototype.setUInt8 = function (entry, byteOffset) { + if (byteOffset != null) { + if (byteOffset < this._byteOffset) { + this._dataView.setUint8(byteOffset, entry); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"); + } + } + else { + if (this._byteOffset + 1 > this._arrayBuffer.byteLength) { + this._resizeBuffer(this._arrayBuffer.byteLength * 2); + } + this._dataView.setUint8(this._byteOffset, entry); + this._byteOffset += 1; + } + }; + /** + * Stores an UInt16 in the array buffer + * @param entry + * @param byteOffset If defined, specifies where to set the value as an offset. + */ + _BinaryWriter.prototype.setUInt16 = function (entry, byteOffset) { + if (byteOffset != null) { + if (byteOffset < this._byteOffset) { + this._dataView.setUint16(byteOffset, entry, true); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"); + } + } + else { + if (this._byteOffset + 2 > this._arrayBuffer.byteLength) { + this._resizeBuffer(this._arrayBuffer.byteLength * 2); + } + this._dataView.setUint16(this._byteOffset, entry, true); + this._byteOffset += 2; + } + }; + /** + * Gets an UInt32 in the array buffer + * @param byteOffset If defined, specifies where to set the value as an offset. + * @returns entry + */ + _BinaryWriter.prototype.getUInt32 = function (byteOffset) { + if (byteOffset < this._byteOffset) { + return this._dataView.getUint32(byteOffset, true); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"); + throw new Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"); + } + }; + _BinaryWriter.prototype.getVector3Float32FromRef = function (vector3, byteOffset) { + if (byteOffset + 8 > this._byteOffset) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"); + } + else { + vector3.x = this._dataView.getFloat32(byteOffset, true); + vector3.y = this._dataView.getFloat32(byteOffset + 4, true); + vector3.z = this._dataView.getFloat32(byteOffset + 8, true); + } + }; + _BinaryWriter.prototype.setVector3Float32FromRef = function (vector3, byteOffset) { + if (byteOffset + 8 > this._byteOffset) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"); + } + else { + this._dataView.setFloat32(byteOffset, vector3.x, true); + this._dataView.setFloat32(byteOffset + 4, vector3.y, true); + this._dataView.setFloat32(byteOffset + 8, vector3.z, true); + } + }; + _BinaryWriter.prototype.getVector4Float32FromRef = function (vector4, byteOffset) { + if (byteOffset + 12 > this._byteOffset) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"); + } + else { + vector4.x = this._dataView.getFloat32(byteOffset, true); + vector4.y = this._dataView.getFloat32(byteOffset + 4, true); + vector4.z = this._dataView.getFloat32(byteOffset + 8, true); + vector4.w = this._dataView.getFloat32(byteOffset + 12, true); + } + }; + _BinaryWriter.prototype.setVector4Float32FromRef = function (vector4, byteOffset) { + if (byteOffset + 12 > this._byteOffset) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"); + } + else { + this._dataView.setFloat32(byteOffset, vector4.x, true); + this._dataView.setFloat32(byteOffset + 4, vector4.y, true); + this._dataView.setFloat32(byteOffset + 8, vector4.z, true); + this._dataView.setFloat32(byteOffset + 12, vector4.w, true); + } + }; + /** + * Stores a Float32 in the array buffer + * @param entry + * @param byteOffset + */ + _BinaryWriter.prototype.setFloat32 = function (entry, byteOffset) { + if (isNaN(entry)) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("Invalid data being written!"); + } + if (byteOffset != null) { + if (byteOffset < this._byteOffset) { + this._dataView.setFloat32(byteOffset, entry, true); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("BinaryWriter: byteoffset is greater than the current binary length!"); + } + } + if (this._byteOffset + 4 > this._arrayBuffer.byteLength) { + this._resizeBuffer(this._arrayBuffer.byteLength * 2); + } + this._dataView.setFloat32(this._byteOffset, entry, true); + this._byteOffset += 4; + }; + /** + * Stores an UInt32 in the array buffer + * @param entry + * @param byteOffset If defined, specifies where to set the value as an offset. + */ + _BinaryWriter.prototype.setUInt32 = function (entry, byteOffset) { + if (byteOffset != null) { + if (byteOffset < this._byteOffset) { + this._dataView.setUint32(byteOffset, entry, true); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"); + } + } + else { + if (this._byteOffset + 4 > this._arrayBuffer.byteLength) { + this._resizeBuffer(this._arrayBuffer.byteLength * 2); + } + this._dataView.setUint32(this._byteOffset, entry, true); + this._byteOffset += 4; + } + }; + /** + * Stores an Int16 in the array buffer + * @param entry + * @param byteOffset If defined, specifies where to set the value as an offset. + */ + _BinaryWriter.prototype.setInt16 = function (entry, byteOffset) { + if (byteOffset != null) { + if (byteOffset < this._byteOffset) { + this._dataView.setInt16(byteOffset, entry, true); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"); + } + } + else { + if (this._byteOffset + 2 > this._arrayBuffer.byteLength) { + this._resizeBuffer(this._arrayBuffer.byteLength * 2); + } + this._dataView.setInt16(this._byteOffset, entry, true); + this._byteOffset += 2; + } + }; + /** + * Stores a byte in the array buffer + * @param entry + * @param byteOffset If defined, specifies where to set the value as an offset. + */ + _BinaryWriter.prototype.setByte = function (entry, byteOffset) { + if (byteOffset != null) { + if (byteOffset < this._byteOffset) { + this._dataView.setInt8(byteOffset, entry); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"); + } + } + else { + if (this._byteOffset + 1 > this._arrayBuffer.byteLength) { + this._resizeBuffer(this._arrayBuffer.byteLength * 2); + } + this._dataView.setInt8(this._byteOffset, entry); + this._byteOffset++; + } + }; + return _BinaryWriter; +}()); + + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/glTFExporterExtension.ts": +/*!**********************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/glTFExporterExtension.ts ***! + \**********************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ __IGLTFExporterExtensionV2: () => (/* binding */ __IGLTFExporterExtensionV2) +/* harmony export */ }); +/** @internal */ +// eslint-disable-next-line no-var, @typescript-eslint/naming-convention +var __IGLTFExporterExtensionV2 = 0; // I am here to allow dts to be created + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/glTFMaterialExporter.ts": +/*!*********************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/glTFMaterialExporter.ts ***! + \*********************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ _GLTFMaterialExporter: () => (/* binding */ _GLTFMaterialExporter) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/dumpTools */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__); + + + + + + + + + + +function getFileExtensionFromMimeType(mimeType) { + switch (mimeType) { + case "image/jpeg" /* ImageMimeType.JPEG */: + return ".jpg"; + case "image/png" /* ImageMimeType.PNG */: + return ".png"; + case "image/webp" /* ImageMimeType.WEBP */: + return ".webp"; + case "image/avif" /* ImageMimeType.AVIF */: + return ".avif"; + } +} +/** + * Utility methods for working with glTF material conversion properties. This class should only be used internally + * @internal + */ +var _GLTFMaterialExporter = /** @class */ (function () { + function _GLTFMaterialExporter(exporter) { + /** + * Mapping to store textures + */ + this._textureMap = {}; + // Mapping of internal textures to images to avoid exporting duplicate images. + this._internalTextureToImage = {}; + this._textureMap = {}; + this._exporter = exporter; + } + /** + * Specifies if two colors are approximately equal in value + * @param color1 first color to compare to + * @param color2 second color to compare to + * @param epsilon threshold value + * @returns boolean specifying if the colors are approximately equal in value + */ + _GLTFMaterialExporter._FuzzyEquals = function (color1, color2, epsilon) { + return babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Scalar.WithinEpsilon(color1.r, color2.r, epsilon) && babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Scalar.WithinEpsilon(color1.g, color2.g, epsilon) && babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Scalar.WithinEpsilon(color1.b, color2.b, epsilon); + }; + /** + * Gets the materials from a Babylon scene and converts them to glTF materials + * @param exportMaterials + * @param mimeType texture mime type + * @param hasTextureCoords specifies if texture coordinates are present on the material + * @returns promise that resolves after all materials have been converted + */ + _GLTFMaterialExporter.prototype._convertMaterialsToGLTFAsync = function (exportMaterials, mimeType, hasTextureCoords) { + var _this = this; + var promises = []; + exportMaterials.forEach(function (material) { + if (material.getClassName() === "StandardMaterial") { + promises.push(_this._convertStandardMaterialAsync(material, mimeType, hasTextureCoords)); + } + else if (material.getClassName().indexOf("PBR") !== -1) { + promises.push(_this._convertPBRMaterialAsync(material, mimeType, hasTextureCoords)); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("Unsupported material type: ".concat(material.name)); + } + }); + return Promise.all(promises).then(function () { + /* do nothing */ + }); + }; + /** + * Makes a copy of the glTF material without the texture parameters + * @param originalMaterial original glTF material + * @returns glTF material without texture parameters + */ + _GLTFMaterialExporter.prototype._stripTexturesFromMaterial = function (originalMaterial) { + var newMaterial = {}; + if (originalMaterial) { + newMaterial.name = originalMaterial.name; + newMaterial.doubleSided = originalMaterial.doubleSided; + newMaterial.alphaMode = originalMaterial.alphaMode; + newMaterial.alphaCutoff = originalMaterial.alphaCutoff; + newMaterial.emissiveFactor = originalMaterial.emissiveFactor; + var originalPBRMetallicRoughness = originalMaterial.pbrMetallicRoughness; + if (originalPBRMetallicRoughness) { + newMaterial.pbrMetallicRoughness = {}; + newMaterial.pbrMetallicRoughness.baseColorFactor = originalPBRMetallicRoughness.baseColorFactor; + newMaterial.pbrMetallicRoughness.metallicFactor = originalPBRMetallicRoughness.metallicFactor; + newMaterial.pbrMetallicRoughness.roughnessFactor = originalPBRMetallicRoughness.roughnessFactor; + } + } + return newMaterial; + }; + /** + * Specifies if the material has any texture parameters present + * @param material glTF Material + * @returns boolean specifying if texture parameters are present + */ + _GLTFMaterialExporter.prototype._hasTexturesPresent = function (material) { + var _a; + if (material.emissiveTexture || material.normalTexture || material.occlusionTexture) { + return true; + } + var pbrMat = material.pbrMetallicRoughness; + if (pbrMat) { + if (pbrMat.baseColorTexture || pbrMat.metallicRoughnessTexture) { + return true; + } + } + if (material.extensions) { + for (var extension in material.extensions) { + var extensionObject = material.extensions[extension]; + if (extensionObject) { + return (_a = extensionObject.hasTextures) === null || _a === void 0 ? void 0 : _a.call(extensionObject); + } + } + } + return false; + }; + _GLTFMaterialExporter.prototype._getTextureInfo = function (babylonTexture) { + if (babylonTexture) { + var textureUid = babylonTexture.uid; + if (textureUid in this._textureMap) { + return this._textureMap[textureUid]; + } + } + return null; + }; + /** + * Converts a Babylon StandardMaterial to a glTF Metallic Roughness Material + * @param babylonStandardMaterial + * @returns glTF Metallic Roughness Material representation + */ + _GLTFMaterialExporter.prototype._convertToGLTFPBRMetallicRoughness = function (babylonStandardMaterial) { + // Defines a cubic bezier curve where x is specular power and y is roughness + var P0 = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector2(0, 1); + var P1 = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector2(0, 0.1); + var P2 = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector2(0, 0.1); + var P3 = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector2(1300, 0.1); + /** + * Given the control points, solve for x based on a given t for a cubic bezier curve + * @param t a value between 0 and 1 + * @param p0 first control point + * @param p1 second control point + * @param p2 third control point + * @param p3 fourth control point + * @returns number result of cubic bezier curve at the specified t + */ + function cubicBezierCurve(t, p0, p1, p2, p3) { + return (1 - t) * (1 - t) * (1 - t) * p0 + 3 * (1 - t) * (1 - t) * t * p1 + 3 * (1 - t) * t * t * p2 + t * t * t * p3; + } + /** + * Evaluates a specified specular power value to determine the appropriate roughness value, + * based on a pre-defined cubic bezier curve with specular on the abscissa axis (x-axis) + * and roughness on the ordinant axis (y-axis) + * @param specularPower specular power of standard material + * @returns Number representing the roughness value + */ + function solveForRoughness(specularPower) { + // Given P0.x = 0, P1.x = 0, P2.x = 0 + // x = t * t * t * P3.x + // t = (x / P3.x)^(1/3) + var t = Math.pow(specularPower / P3.x, 0.333333); + return cubicBezierCurve(t, P0.y, P1.y, P2.y, P3.y); + } + var diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace(babylonStandardMaterial.getScene().getEngine().useExactSrgbConversions).scale(0.5); + var opacity = babylonStandardMaterial.alpha; + var specularPower = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Scalar.Clamp(babylonStandardMaterial.specularPower, 0, _GLTFMaterialExporter._MaxSpecularPower); + var roughness = solveForRoughness(specularPower); + var glTFPbrMetallicRoughness = { + baseColorFactor: [diffuse.r, diffuse.g, diffuse.b, opacity], + metallicFactor: 0, + roughnessFactor: roughness, + }; + return glTFPbrMetallicRoughness; + }; + /** + * Computes the metallic factor + * @param diffuse diffused value + * @param specular specular value + * @param oneMinusSpecularStrength one minus the specular strength + * @returns metallic value + */ + _GLTFMaterialExporter._SolveMetallic = function (diffuse, specular, oneMinusSpecularStrength) { + if (specular < this._DielectricSpecular.r) { + this._DielectricSpecular; + return 0; + } + var a = this._DielectricSpecular.r; + var b = (diffuse * oneMinusSpecularStrength) / (1.0 - this._DielectricSpecular.r) + specular - 2.0 * this._DielectricSpecular.r; + var c = this._DielectricSpecular.r - specular; + var D = b * b - 4.0 * a * c; + return babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Scalar.Clamp((-b + Math.sqrt(D)) / (2.0 * a), 0, 1); + }; + /** + * Sets the glTF alpha mode to a glTF material from the Babylon Material + * @param glTFMaterial glTF material + * @param babylonMaterial Babylon material + */ + _GLTFMaterialExporter._SetAlphaMode = function (glTFMaterial, babylonMaterial) { + if (babylonMaterial.needAlphaBlending()) { + glTFMaterial.alphaMode = "BLEND" /* MaterialAlphaMode.BLEND */; + } + else if (babylonMaterial.needAlphaTesting()) { + glTFMaterial.alphaMode = "MASK" /* MaterialAlphaMode.MASK */; + glTFMaterial.alphaCutoff = babylonMaterial.alphaCutOff; + } + }; + /** + * Converts a Babylon Standard Material to a glTF Material + * @param babylonStandardMaterial BJS Standard Material + * @param mimeType mime type to use for the textures + * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied + * @returns promise, resolved with the material + */ + _GLTFMaterialExporter.prototype._convertStandardMaterialAsync = function (babylonStandardMaterial, mimeType, hasTextureCoords) { + var materialMap = this._exporter._materialMap; + var materials = this._exporter._materials; + var promises = []; + var pbrMetallicRoughness = this._convertToGLTFPBRMetallicRoughness(babylonStandardMaterial); + var material = { name: babylonStandardMaterial.name }; + if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) { + if (!babylonStandardMaterial.twoSidedLighting) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn(babylonStandardMaterial.name + ": Back-face culling disabled and two-sided lighting disabled is not supported in glTF."); + } + material.doubleSided = true; + } + if (hasTextureCoords) { + if (babylonStandardMaterial.diffuseTexture) { + promises.push(this._exportTextureAsync(babylonStandardMaterial.diffuseTexture, mimeType).then(function (textureInfo) { + if (textureInfo) { + pbrMetallicRoughness.baseColorTexture = textureInfo; + } + })); + } + var bumpTexture_1 = babylonStandardMaterial.bumpTexture; + if (bumpTexture_1) { + promises.push(this._exportTextureAsync(bumpTexture_1, mimeType).then(function (textureInfo) { + if (textureInfo) { + material.normalTexture = textureInfo; + if (bumpTexture_1.level !== 1) { + material.normalTexture.scale = bumpTexture_1.level; + } + } + })); + } + if (babylonStandardMaterial.emissiveTexture) { + material.emissiveFactor = [1.0, 1.0, 1.0]; + promises.push(this._exportTextureAsync(babylonStandardMaterial.emissiveTexture, mimeType).then(function (textureInfo) { + if (textureInfo) { + material.emissiveTexture = textureInfo; + } + })); + } + if (babylonStandardMaterial.ambientTexture) { + promises.push(this._exportTextureAsync(babylonStandardMaterial.ambientTexture, mimeType).then(function (textureInfo) { + if (textureInfo) { + var occlusionTexture = { + index: textureInfo.index, + }; + material.occlusionTexture = occlusionTexture; + } + })); + } + } + if (babylonStandardMaterial.alpha < 1.0 || babylonStandardMaterial.opacityTexture) { + if (babylonStandardMaterial.alphaMode === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Constants.ALPHA_COMBINE) { + material.alphaMode = "BLEND" /* MaterialAlphaMode.BLEND */; + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn(babylonStandardMaterial.name + ": glTF 2.0 does not support alpha mode: " + babylonStandardMaterial.alphaMode.toString()); + } + } + if (babylonStandardMaterial.emissiveColor && !_GLTFMaterialExporter._FuzzyEquals(babylonStandardMaterial.emissiveColor, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.Black(), _GLTFMaterialExporter._Epsilon)) { + material.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray(); + } + material.pbrMetallicRoughness = pbrMetallicRoughness; + _GLTFMaterialExporter._SetAlphaMode(material, babylonStandardMaterial); + materials.push(material); + materialMap[babylonStandardMaterial.uniqueId] = materials.length - 1; + return this._finishMaterial(promises, material, babylonStandardMaterial, mimeType); + }; + _GLTFMaterialExporter.prototype._finishMaterial = function (promises, glTFMaterial, babylonMaterial, mimeType) { + var _this = this; + return Promise.all(promises).then(function () { + var textures = _this._exporter._extensionsPostExportMaterialAdditionalTextures("exportMaterial", glTFMaterial, babylonMaterial); + var tasks = null; + for (var _i = 0, textures_1 = textures; _i < textures_1.length; _i++) { + var texture = textures_1[_i]; + if (!tasks) { + tasks = []; + } + tasks.push(_this._exportTextureAsync(texture, mimeType)); + } + if (!tasks) { + tasks = [Promise.resolve(null)]; + } + return Promise.all(tasks).then(function () { + var extensionWork = _this._exporter._extensionsPostExportMaterialAsync("exportMaterial", glTFMaterial, babylonMaterial); + if (!extensionWork) { + return glTFMaterial; + } + return extensionWork.then(function () { return glTFMaterial; }); + }); + }); + }; + /** + * Converts an image typed array buffer to a base64 image + * @param buffer typed array buffer + * @param width width of the image + * @param height height of the image + * @param mimeType mimetype of the image + * @returns base64 image string + */ + _GLTFMaterialExporter.prototype._getImageDataAsync = function (buffer, width, height, mimeType) { + return (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__awaiter)(this, void 0, void 0, function () { + var textureType, hostingScene, engine, tempTexture, data; + return (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__generator)(this, function (_a) { + switch (_a.label) { + case 0: + textureType = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Constants.TEXTURETYPE_UNSIGNED_INT; + hostingScene = this._exporter._babylonScene; + engine = hostingScene.getEngine(); + tempTexture = engine.createRawTexture(buffer, width, height, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Constants.TEXTUREFORMAT_RGBA, false, true, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_SAMPLINGMODE, null, textureType); + return [4 /*yield*/, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TextureTools.ApplyPostProcess("pass", tempTexture, hostingScene, textureType, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Constants.TEXTURE_NEAREST_SAMPLINGMODE, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Constants.TEXTUREFORMAT_RGBA)]; + case 1: + _a.sent(); + return [4 /*yield*/, engine._readTexturePixels(tempTexture, width, height)]; + case 2: + data = _a.sent(); + return [4 /*yield*/, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.DumpTools.DumpDataAsync(width, height, data, mimeType, undefined, true, true)]; + case 3: return [2 /*return*/, (_a.sent())]; + } + }); + }); + }; + /** + * Generates a white texture based on the specified width and height + * @param width width of the texture in pixels + * @param height height of the texture in pixels + * @param scene babylonjs scene + * @returns white texture + */ + _GLTFMaterialExporter.prototype._createWhiteTexture = function (width, height, scene) { + var data = new Uint8Array(width * height * 4); + for (var i = 0; i < data.length; i = i + 4) { + data[i] = data[i + 1] = data[i + 2] = data[i + 3] = 0xff; + } + var rawTexture = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.RawTexture.CreateRGBATexture(data, width, height, scene); + return rawTexture; + }; + /** + * Resizes the two source textures to the same dimensions. If a texture is null, a default white texture is generated. If both textures are null, returns null + * @param texture1 first texture to resize + * @param texture2 second texture to resize + * @param scene babylonjs scene + * @returns resized textures or null + */ + _GLTFMaterialExporter.prototype._resizeTexturesToSameDimensions = function (texture1, texture2, scene) { + var texture1Size = texture1 ? texture1.getSize() : { width: 0, height: 0 }; + var texture2Size = texture2 ? texture2.getSize() : { width: 0, height: 0 }; + var resizedTexture1; + var resizedTexture2; + if (texture1Size.width < texture2Size.width) { + if (texture1 && texture1 instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture) { + resizedTexture1 = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TextureTools.CreateResizedCopy(texture1, texture2Size.width, texture2Size.height, true); + } + else { + resizedTexture1 = this._createWhiteTexture(texture2Size.width, texture2Size.height, scene); + } + resizedTexture2 = texture2; + } + else if (texture1Size.width > texture2Size.width) { + if (texture2 && texture2 instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture) { + resizedTexture2 = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TextureTools.CreateResizedCopy(texture2, texture1Size.width, texture1Size.height, true); + } + else { + resizedTexture2 = this._createWhiteTexture(texture1Size.width, texture1Size.height, scene); + } + resizedTexture1 = texture1; + } + else { + resizedTexture1 = texture1; + resizedTexture2 = texture2; + } + return { + texture1: resizedTexture1, + texture2: resizedTexture2, + }; + }; + /** + * Converts an array of pixels to a Float32Array + * Throws an error if the pixel format is not supported + * @param pixels - array buffer containing pixel values + * @returns Float32 of pixels + */ + _GLTFMaterialExporter.prototype._convertPixelArrayToFloat32 = function (pixels) { + if (pixels instanceof Uint8Array) { + var length_1 = pixels.length; + var buffer = new Float32Array(pixels.length); + for (var i = 0; i < length_1; ++i) { + buffer[i] = pixels[i] / 255; + } + return buffer; + } + else if (pixels instanceof Float32Array) { + return pixels; + } + else { + throw new Error("Unsupported pixel format!"); + } + }; + /** + * Convert Specular Glossiness Textures to Metallic Roughness + * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness + * @link https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js + * @param diffuseTexture texture used to store diffuse information + * @param specularGlossinessTexture texture used to store specular and glossiness information + * @param factors specular glossiness material factors + * @param mimeType the mime type to use for the texture + * @returns pbr metallic roughness interface or null + */ + _GLTFMaterialExporter.prototype._convertSpecularGlossinessTexturesToMetallicRoughnessAsync = function (diffuseTexture, specularGlossinessTexture, factors, mimeType) { + return (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__awaiter)(this, void 0, void 0, function () { + var promises, scene, resizedTextures, diffuseSize, diffuseBuffer, specularGlossinessBuffer, width, height, diffusePixels, specularPixels, byteLength, metallicRoughnessBuffer, baseColorBuffer, strideSize, maxBaseColor, maxMetallic, maxRoughness, h, w, offset, diffuseColor, specularColor, glossiness, specularGlossiness, metallicRoughness, metallicRoughnessFactors_1, writeOutMetallicRoughnessTexture, writeOutBaseColorTexture, h, w, destinationOffset, linearBaseColorPixel, sRGBBaseColorPixel, metallicRoughnessPixel; + var _a; + return (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__generator)(this, function (_b) { + switch (_b.label) { + case 0: + promises = new Array(); + if (!(diffuseTexture || specularGlossinessTexture)) { + return [2 /*return*/, Promise.reject("_ConvertSpecularGlosinessTexturesToMetallicRoughness: diffuse and specular glossiness textures are not defined!")]; + } + scene = diffuseTexture ? diffuseTexture.getScene() : specularGlossinessTexture ? specularGlossinessTexture.getScene() : null; + if (!scene) return [3 /*break*/, 3]; + resizedTextures = this._resizeTexturesToSameDimensions(diffuseTexture, specularGlossinessTexture, scene); + diffuseSize = (_a = resizedTextures.texture1) === null || _a === void 0 ? void 0 : _a.getSize(); + diffuseBuffer = void 0; + specularGlossinessBuffer = void 0; + width = diffuseSize.width; + height = diffuseSize.height; + return [4 /*yield*/, resizedTextures.texture1.readPixels()]; + case 1: + diffusePixels = _b.sent(); + return [4 /*yield*/, resizedTextures.texture2.readPixels()]; + case 2: + specularPixels = _b.sent(); + if (diffusePixels) { + diffuseBuffer = this._convertPixelArrayToFloat32(diffusePixels); + } + else { + return [2 /*return*/, Promise.reject("Failed to retrieve pixels from diffuse texture!")]; + } + if (specularPixels) { + specularGlossinessBuffer = this._convertPixelArrayToFloat32(specularPixels); + } + else { + return [2 /*return*/, Promise.reject("Failed to retrieve pixels from specular glossiness texture!")]; + } + byteLength = specularGlossinessBuffer.byteLength; + metallicRoughnessBuffer = new Uint8Array(byteLength); + baseColorBuffer = new Uint8Array(byteLength); + strideSize = 4; + maxBaseColor = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.Black(); + maxMetallic = 0; + maxRoughness = 0; + for (h = 0; h < height; ++h) { + for (w = 0; w < width; ++w) { + offset = (width * h + w) * strideSize; + diffuseColor = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3(diffuseBuffer[offset], diffuseBuffer[offset + 1], diffuseBuffer[offset + 2]) + .toLinearSpace(scene.getEngine().useExactSrgbConversions) + .multiply(factors.diffuseColor); + specularColor = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3(specularGlossinessBuffer[offset], specularGlossinessBuffer[offset + 1], specularGlossinessBuffer[offset + 2]) + .toLinearSpace(scene.getEngine().useExactSrgbConversions) + .multiply(factors.specularColor); + glossiness = specularGlossinessBuffer[offset + 3] * factors.glossiness; + specularGlossiness = { + diffuseColor: diffuseColor, + specularColor: specularColor, + glossiness: glossiness, + }; + metallicRoughness = this._convertSpecularGlossinessToMetallicRoughness(specularGlossiness); + maxBaseColor.r = Math.max(maxBaseColor.r, metallicRoughness.baseColor.r); + maxBaseColor.g = Math.max(maxBaseColor.g, metallicRoughness.baseColor.g); + maxBaseColor.b = Math.max(maxBaseColor.b, metallicRoughness.baseColor.b); + maxMetallic = Math.max(maxMetallic, metallicRoughness.metallic); + maxRoughness = Math.max(maxRoughness, metallicRoughness.roughness); + baseColorBuffer[offset] = metallicRoughness.baseColor.r * 255; + baseColorBuffer[offset + 1] = metallicRoughness.baseColor.g * 255; + baseColorBuffer[offset + 2] = metallicRoughness.baseColor.b * 255; + baseColorBuffer[offset + 3] = resizedTextures.texture1.hasAlpha ? diffuseBuffer[offset + 3] * 255 : 255; + metallicRoughnessBuffer[offset] = 0; + metallicRoughnessBuffer[offset + 1] = metallicRoughness.roughness * 255; + metallicRoughnessBuffer[offset + 2] = metallicRoughness.metallic * 255; + metallicRoughnessBuffer[offset + 3] = 255; + } + } + metallicRoughnessFactors_1 = { + baseColor: maxBaseColor, + metallic: maxMetallic, + roughness: maxRoughness, + }; + writeOutMetallicRoughnessTexture = false; + writeOutBaseColorTexture = false; + for (h = 0; h < height; ++h) { + for (w = 0; w < width; ++w) { + destinationOffset = (width * h + w) * strideSize; + baseColorBuffer[destinationOffset] /= metallicRoughnessFactors_1.baseColor.r > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.r : 1; + baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors_1.baseColor.g > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.g : 1; + baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors_1.baseColor.b > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.b : 1; + linearBaseColorPixel = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.FromInts(baseColorBuffer[destinationOffset], baseColorBuffer[destinationOffset + 1], baseColorBuffer[destinationOffset + 2]); + sRGBBaseColorPixel = linearBaseColorPixel.toGammaSpace(scene.getEngine().useExactSrgbConversions); + baseColorBuffer[destinationOffset] = sRGBBaseColorPixel.r * 255; + baseColorBuffer[destinationOffset + 1] = sRGBBaseColorPixel.g * 255; + baseColorBuffer[destinationOffset + 2] = sRGBBaseColorPixel.b * 255; + if (!_GLTFMaterialExporter._FuzzyEquals(sRGBBaseColorPixel, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.White(), _GLTFMaterialExporter._Epsilon)) { + writeOutBaseColorTexture = true; + } + metallicRoughnessBuffer[destinationOffset + 1] /= + metallicRoughnessFactors_1.roughness > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.roughness : 1; + metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors_1.metallic > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.metallic : 1; + metallicRoughnessPixel = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.FromInts(255, metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]); + if (!_GLTFMaterialExporter._FuzzyEquals(metallicRoughnessPixel, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.White(), _GLTFMaterialExporter._Epsilon)) { + writeOutMetallicRoughnessTexture = true; + } + } + } + if (writeOutMetallicRoughnessTexture) { + promises.push(this._getImageDataAsync(metallicRoughnessBuffer, width, height, mimeType).then(function (data) { + metallicRoughnessFactors_1.metallicRoughnessTextureData = data; + })); + } + if (writeOutBaseColorTexture) { + promises.push(this._getImageDataAsync(baseColorBuffer, width, height, mimeType).then(function (data) { + metallicRoughnessFactors_1.baseColorTextureData = data; + })); + } + return [2 /*return*/, Promise.all(promises).then(function () { + return metallicRoughnessFactors_1; + })]; + case 3: return [2 /*return*/, Promise.reject("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!")]; + } + }); + }); + }; + /** + * Converts specular glossiness material properties to metallic roughness + * @param specularGlossiness interface with specular glossiness material properties + * @returns interface with metallic roughness material properties + */ + _GLTFMaterialExporter.prototype._convertSpecularGlossinessToMetallicRoughness = function (specularGlossiness) { + var diffusePerceivedBrightness = this._getPerceivedBrightness(specularGlossiness.diffuseColor); + var specularPerceivedBrightness = this._getPerceivedBrightness(specularGlossiness.specularColor); + var oneMinusSpecularStrength = 1 - this._getMaxComponent(specularGlossiness.specularColor); + var metallic = _GLTFMaterialExporter._SolveMetallic(diffusePerceivedBrightness, specularPerceivedBrightness, oneMinusSpecularStrength); + var baseColorFromDiffuse = specularGlossiness.diffuseColor.scale(oneMinusSpecularStrength / (1.0 - _GLTFMaterialExporter._DielectricSpecular.r) / Math.max(1 - metallic, _GLTFMaterialExporter._Epsilon)); + var baseColorFromSpecular = specularGlossiness.specularColor + .subtract(_GLTFMaterialExporter._DielectricSpecular.scale(1 - metallic)) + .scale(1 / Math.max(metallic, _GLTFMaterialExporter._Epsilon)); + var baseColor = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.Lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic); + baseColor = baseColor.clampToRef(0, 1, baseColor); + var metallicRoughness = { + baseColor: baseColor, + metallic: metallic, + roughness: 1 - specularGlossiness.glossiness, + }; + return metallicRoughness; + }; + /** + * Calculates the surface reflectance, independent of lighting conditions + * @param color Color source to calculate brightness from + * @returns number representing the perceived brightness, or zero if color is undefined + */ + _GLTFMaterialExporter.prototype._getPerceivedBrightness = function (color) { + if (color) { + return Math.sqrt(0.299 * color.r * color.r + 0.587 * color.g * color.g + 0.114 * color.b * color.b); + } + return 0; + }; + /** + * Returns the maximum color component value + * @param color + * @returns maximum color component value, or zero if color is null or undefined + */ + _GLTFMaterialExporter.prototype._getMaxComponent = function (color) { + if (color) { + return Math.max(color.r, Math.max(color.g, color.b)); + } + return 0; + }; + /** + * Convert a PBRMaterial (Metallic/Roughness) to Metallic Roughness factors + * @param babylonPBRMaterial BJS PBR Metallic Roughness Material + * @param mimeType mime type to use for the textures + * @param glTFPbrMetallicRoughness glTF PBR Metallic Roughness interface + * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied + * @returns glTF PBR Metallic Roughness factors + */ + _GLTFMaterialExporter.prototype._convertMetalRoughFactorsToMetallicRoughnessAsync = function (babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasTextureCoords) { + var promises = []; + var baseColor = babylonPBRMaterial._albedoColor; + var metallic = babylonPBRMaterial._metallic; + var roughness = babylonPBRMaterial._roughness; + var metallicRoughness = { + baseColor: baseColor, + metallic: metallic, + roughness: roughness, + }; + if (hasTextureCoords) { + var albedoTexture = babylonPBRMaterial._albedoTexture; + if (albedoTexture) { + promises.push(this._exportTextureAsync(babylonPBRMaterial._albedoTexture, mimeType).then(function (glTFTexture) { + if (glTFTexture) { + glTFPbrMetallicRoughness.baseColorTexture = glTFTexture; + } + })); + } + var metallicTexture = babylonPBRMaterial._metallicTexture; + if (metallicTexture) { + promises.push(this._exportTextureAsync(metallicTexture, mimeType).then(function (glTFTexture) { + if (glTFTexture) { + glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture; + } + })); + } + } + return Promise.all(promises).then(function () { + return metallicRoughness; + }); + }; + _GLTFMaterialExporter.prototype._getTextureSampler = function (texture) { + var sampler = {}; + if (!texture || !(texture instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture)) { + return sampler; + } + var wrapS = this._getGLTFTextureWrapMode(texture.wrapU); + if (wrapS !== 10497 /* TextureWrapMode.REPEAT */) { + sampler.wrapS = wrapS; + } + var wrapT = this._getGLTFTextureWrapMode(texture.wrapV); + if (wrapT !== 10497 /* TextureWrapMode.REPEAT */) { + sampler.wrapT = wrapT; + } + switch (texture.samplingMode) { + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_LINEAR: { + sampler.magFilter = 9729 /* TextureMagFilter.LINEAR */; + sampler.minFilter = 9729 /* TextureMinFilter.LINEAR */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_NEAREST: { + sampler.magFilter = 9729 /* TextureMagFilter.LINEAR */; + sampler.minFilter = 9728 /* TextureMinFilter.NEAREST */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_LINEAR: { + sampler.magFilter = 9728 /* TextureMagFilter.NEAREST */; + sampler.minFilter = 9729 /* TextureMinFilter.LINEAR */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_LINEAR_MIPLINEAR: { + sampler.magFilter = 9728 /* TextureMagFilter.NEAREST */; + sampler.minFilter = 9987 /* TextureMinFilter.LINEAR_MIPMAP_LINEAR */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_NEAREST: { + sampler.magFilter = 9728 /* TextureMagFilter.NEAREST */; + sampler.minFilter = 9728 /* TextureMinFilter.NEAREST */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_LINEAR_MIPNEAREST: { + sampler.magFilter = 9728 /* TextureMagFilter.NEAREST */; + sampler.minFilter = 9985 /* TextureMinFilter.LINEAR_MIPMAP_NEAREST */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_NEAREST_MIPNEAREST: { + sampler.magFilter = 9729 /* TextureMagFilter.LINEAR */; + sampler.minFilter = 9984 /* TextureMinFilter.NEAREST_MIPMAP_NEAREST */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_NEAREST_MIPLINEAR: { + sampler.magFilter = 9729 /* TextureMagFilter.LINEAR */; + sampler.minFilter = 9986 /* TextureMinFilter.NEAREST_MIPMAP_LINEAR */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_NEAREST_MIPLINEAR: { + sampler.magFilter = 9728 /* TextureMagFilter.NEAREST */; + sampler.minFilter = 9986 /* TextureMinFilter.NEAREST_MIPMAP_LINEAR */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_LINEAR_MIPLINEAR: { + sampler.magFilter = 9729 /* TextureMagFilter.LINEAR */; + sampler.minFilter = 9987 /* TextureMinFilter.LINEAR_MIPMAP_LINEAR */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_LINEAR_MIPNEAREST: { + sampler.magFilter = 9729 /* TextureMagFilter.LINEAR */; + sampler.minFilter = 9985 /* TextureMinFilter.LINEAR_MIPMAP_NEAREST */; + break; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_NEAREST_MIPNEAREST: { + sampler.magFilter = 9728 /* TextureMagFilter.NEAREST */; + sampler.minFilter = 9984 /* TextureMinFilter.NEAREST_MIPMAP_NEAREST */; + break; + } + } + return sampler; + }; + _GLTFMaterialExporter.prototype._getGLTFTextureWrapMode = function (wrapMode) { + switch (wrapMode) { + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.WRAP_ADDRESSMODE: { + return 10497 /* TextureWrapMode.REPEAT */; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.CLAMP_ADDRESSMODE: { + return 33071 /* TextureWrapMode.CLAMP_TO_EDGE */; + } + case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Texture.MIRROR_ADDRESSMODE: { + return 33648 /* TextureWrapMode.MIRRORED_REPEAT */; + } + default: { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Error("Unsupported Texture Wrap Mode ".concat(wrapMode, "!")); + return 10497 /* TextureWrapMode.REPEAT */; + } + } + }; + /** + * Convert a PBRMaterial (Specular/Glossiness) to Metallic Roughness factors + * @param babylonPBRMaterial BJS PBR Metallic Roughness Material + * @param mimeType mime type to use for the textures + * @param pbrMetallicRoughness glTF PBR Metallic Roughness interface + * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied + * @returns glTF PBR Metallic Roughness factors + */ + _GLTFMaterialExporter.prototype._convertSpecGlossFactorsToMetallicRoughnessAsync = function (babylonPBRMaterial, mimeType, pbrMetallicRoughness, hasTextureCoords) { + var _this = this; + return Promise.resolve().then(function () { + var specGloss = { + diffuseColor: babylonPBRMaterial._albedoColor, + specularColor: babylonPBRMaterial._reflectivityColor, + glossiness: babylonPBRMaterial._microSurface, + }; + var albedoTexture = babylonPBRMaterial._albedoTexture; + var reflectivityTexture = babylonPBRMaterial._reflectivityTexture; + var useMicrosurfaceFromReflectivityMapAlpha = babylonPBRMaterial._useMicroSurfaceFromReflectivityMapAlpha; + if (reflectivityTexture && !useMicrosurfaceFromReflectivityMapAlpha) { + return Promise.reject("_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture are currently not supported"); + } + if ((albedoTexture || reflectivityTexture) && hasTextureCoords) { + var samplerIndex_1 = _this._exportTextureSampler(albedoTexture || reflectivityTexture); + return _this._convertSpecularGlossinessTexturesToMetallicRoughnessAsync(albedoTexture, reflectivityTexture, specGloss, mimeType).then(function (metallicRoughnessFactors) { + var textures = _this._exporter._textures; + if (metallicRoughnessFactors.baseColorTextureData) { + var imageIndex = _this._exportImage("baseColor".concat(textures.length), mimeType, metallicRoughnessFactors.baseColorTextureData); + pbrMetallicRoughness.baseColorTexture = _this._exportTextureInfo(imageIndex, samplerIndex_1, albedoTexture === null || albedoTexture === void 0 ? void 0 : albedoTexture.coordinatesIndex); + } + if (metallicRoughnessFactors.metallicRoughnessTextureData) { + var imageIndex = _this._exportImage("metallicRoughness".concat(textures.length), mimeType, metallicRoughnessFactors.metallicRoughnessTextureData); + pbrMetallicRoughness.metallicRoughnessTexture = _this._exportTextureInfo(imageIndex, samplerIndex_1, reflectivityTexture === null || reflectivityTexture === void 0 ? void 0 : reflectivityTexture.coordinatesIndex); + } + return metallicRoughnessFactors; + }); + } + else { + return _this._convertSpecularGlossinessToMetallicRoughness(specGloss); + } + }); + }; + /** + * Converts a Babylon PBR Base Material to a glTF Material + * @param babylonPBRMaterial BJS PBR Base Material + * @param mimeType mime type to use for the textures + * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied + * @returns async glTF Material representation + */ + _GLTFMaterialExporter.prototype._convertPBRMaterialAsync = function (babylonPBRMaterial, mimeType, hasTextureCoords) { + var _this = this; + var glTFPbrMetallicRoughness = {}; + var glTFMaterial = { + name: babylonPBRMaterial.name, + }; + var useMetallicRoughness = babylonPBRMaterial.isMetallicWorkflow(); + if (useMetallicRoughness) { + var albedoColor = babylonPBRMaterial._albedoColor; + var alpha = babylonPBRMaterial.alpha; + if (albedoColor) { + glTFPbrMetallicRoughness.baseColorFactor = [albedoColor.r, albedoColor.g, albedoColor.b, alpha]; + } + return this._convertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasTextureCoords).then(function (metallicRoughness) { + return _this._setMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, hasTextureCoords); + }); + } + else { + return this._convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasTextureCoords).then(function (metallicRoughness) { + return _this._setMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, hasTextureCoords); + }); + } + }; + _GLTFMaterialExporter.prototype._setMetallicRoughnessPbrMaterial = function (metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, hasTextureCoords) { + var materialMap = this._exporter._materialMap; + var materials = this._exporter._materials; + var promises = []; + if (metallicRoughness) { + _GLTFMaterialExporter._SetAlphaMode(glTFMaterial, babylonPBRMaterial); + if (!(_GLTFMaterialExporter._FuzzyEquals(metallicRoughness.baseColor, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.White(), _GLTFMaterialExporter._Epsilon) && + babylonPBRMaterial.alpha >= _GLTFMaterialExporter._Epsilon)) { + glTFPbrMetallicRoughness.baseColorFactor = [metallicRoughness.baseColor.r, metallicRoughness.baseColor.g, metallicRoughness.baseColor.b, babylonPBRMaterial.alpha]; + } + if (metallicRoughness.metallic != null && metallicRoughness.metallic !== 1) { + glTFPbrMetallicRoughness.metallicFactor = metallicRoughness.metallic; + } + if (metallicRoughness.roughness != null && metallicRoughness.roughness !== 1) { + glTFPbrMetallicRoughness.roughnessFactor = metallicRoughness.roughness; + } + if (babylonPBRMaterial.backFaceCulling != null && !babylonPBRMaterial.backFaceCulling) { + if (!babylonPBRMaterial._twoSidedLighting) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn(babylonPBRMaterial.name + ": Back-face culling disabled and two-sided lighting disabled is not supported in glTF."); + } + glTFMaterial.doubleSided = true; + } + if (hasTextureCoords) { + var bumpTexture_2 = babylonPBRMaterial._bumpTexture; + if (bumpTexture_2) { + var promise = this._exportTextureAsync(bumpTexture_2, mimeType).then(function (glTFTexture) { + if (glTFTexture) { + glTFMaterial.normalTexture = glTFTexture; + if (bumpTexture_2.level !== 1) { + glTFMaterial.normalTexture.scale = bumpTexture_2.level; + } + } + }); + promises.push(promise); + } + var ambientTexture = babylonPBRMaterial._ambientTexture; + if (ambientTexture) { + var promise = this._exportTextureAsync(ambientTexture, mimeType).then(function (glTFTexture) { + if (glTFTexture) { + var occlusionTexture = { + index: glTFTexture.index, + texCoord: glTFTexture.texCoord, + extensions: glTFTexture.extensions, + }; + glTFMaterial.occlusionTexture = occlusionTexture; + var ambientTextureStrength = babylonPBRMaterial._ambientTextureStrength; + if (ambientTextureStrength) { + occlusionTexture.strength = ambientTextureStrength; + } + } + }); + promises.push(promise); + } + var emissiveTexture = babylonPBRMaterial._emissiveTexture; + if (emissiveTexture) { + var promise = this._exportTextureAsync(emissiveTexture, mimeType).then(function (glTFTexture) { + if (glTFTexture) { + glTFMaterial.emissiveTexture = glTFTexture; + } + }); + promises.push(promise); + } + } + var emissiveColor = babylonPBRMaterial._emissiveColor; + if (!_GLTFMaterialExporter._FuzzyEquals(emissiveColor, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.Black(), _GLTFMaterialExporter._Epsilon)) { + glTFMaterial.emissiveFactor = emissiveColor.asArray(); + } + glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness; + materials.push(glTFMaterial); + materialMap[babylonPBRMaterial.uniqueId] = materials.length - 1; + } + return this._finishMaterial(promises, glTFMaterial, babylonPBRMaterial, mimeType); + }; + _GLTFMaterialExporter.prototype._getPixelsFromTexture = function (babylonTexture) { + var pixels = babylonTexture.textureType === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Constants.TEXTURETYPE_UNSIGNED_INT + ? babylonTexture.readPixels() + : babylonTexture.readPixels(); + return pixels; + }; + /** + * Extracts a texture from a Babylon texture into file data and glTF data + * @param babylonTexture Babylon texture to extract + * @param mimeType Mime Type of the babylonTexture + * @returns glTF texture info, or null if the texture format is not supported + */ + _GLTFMaterialExporter.prototype._exportTextureAsync = function (babylonTexture, mimeType) { + var _this = this; + var extensionPromise = this._exporter._extensionsPreExportTextureAsync("exporter", babylonTexture, mimeType); + if (!extensionPromise) { + return this._exportTextureInfoAsync(babylonTexture, mimeType); + } + return extensionPromise.then(function (texture) { + if (!texture) { + return _this._exportTextureInfoAsync(babylonTexture, mimeType); + } + return _this._exportTextureInfoAsync(texture, mimeType); + }); + }; + _GLTFMaterialExporter.prototype._exportTextureInfoAsync = function (babylonTexture, mimeType) { + return (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__awaiter)(this, void 0, void 0, function () { + var textureUid, pixels_1, samplerIndex, textureMimeType, internalTextureToImage, internalTextureUniqueId, imageIndexPromise, size_1, textureInfo, _a; + var _this = this; + return (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__generator)(this, function (_b) { + switch (_b.label) { + case 0: + textureUid = babylonTexture.uid; + if (!!(textureUid in this._textureMap)) return [3 /*break*/, 3]; + return [4 /*yield*/, this._getPixelsFromTexture(babylonTexture)]; + case 1: + pixels_1 = _b.sent(); + if (!pixels_1) { + return [2 /*return*/, null]; + } + samplerIndex = this._exportTextureSampler(babylonTexture); + textureMimeType = babylonTexture.mimeType; + if (textureMimeType) { + switch (textureMimeType) { + case "image/jpeg": + case "image/png": + case "image/webp": + mimeType = textureMimeType; + break; + default: + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("Unsupported media type: ".concat(textureMimeType)); + break; + } + } + internalTextureToImage = this._internalTextureToImage; + internalTextureUniqueId = babylonTexture.getInternalTexture().uniqueId; + internalTextureToImage[internalTextureUniqueId] || (internalTextureToImage[internalTextureUniqueId] = {}); + imageIndexPromise = internalTextureToImage[internalTextureUniqueId][mimeType]; + if (imageIndexPromise === undefined) { + size_1 = babylonTexture.getSize(); + imageIndexPromise = (function () { return (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__awaiter)(_this, void 0, void 0, function () { + var data; + return (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__generator)(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, this._getImageDataAsync(pixels_1, size_1.width, size_1.height, mimeType)]; + case 1: + data = _a.sent(); + return [2 /*return*/, this._exportImage(babylonTexture.name, mimeType, data)]; + } + }); + }); })(); + internalTextureToImage[internalTextureUniqueId][mimeType] = imageIndexPromise; + } + _a = this._exportTextureInfo; + return [4 /*yield*/, imageIndexPromise]; + case 2: + textureInfo = _a.apply(this, [_b.sent(), samplerIndex, babylonTexture.coordinatesIndex]); + this._textureMap[textureUid] = textureInfo; + this._exporter._extensionsPostExportTextures("exporter", this._textureMap[textureUid], babylonTexture); + _b.label = 3; + case 3: return [2 /*return*/, this._textureMap[textureUid]]; + } + }); + }); + }; + _GLTFMaterialExporter.prototype._exportImage = function (name, mimeType, data) { + var imageData = this._exporter._imageData; + var baseName = name.replace(/\.\/|\/|\.\\|\\/g, "_"); + var extension = getFileExtensionFromMimeType(mimeType); + var fileName = baseName + extension; + if (fileName in imageData) { + fileName = "".concat(baseName, "_").concat(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.RandomId()).concat(extension); + } + imageData[fileName] = { + data: data, + mimeType: mimeType, + }; + var images = this._exporter._images; + images.push({ + name: name, + uri: fileName, + }); + return images.length - 1; + }; + _GLTFMaterialExporter.prototype._exportTextureInfo = function (imageIndex, samplerIndex, coordinatesIndex) { + var textures = this._exporter._textures; + var textureIndex = textures.findIndex(function (t) { return t.sampler == samplerIndex && t.source === imageIndex; }); + if (textureIndex === -1) { + textureIndex = textures.length; + textures.push({ + source: imageIndex, + sampler: samplerIndex, + }); + } + var textureInfo = { index: textureIndex }; + if (coordinatesIndex) { + textureInfo.texCoord = coordinatesIndex; + } + return textureInfo; + }; + _GLTFMaterialExporter.prototype._exportTextureSampler = function (texture) { + var sampler = this._getTextureSampler(texture); + // if a pre-existing sampler with identical parameters exists, then reuse the previous sampler + var samplers = this._exporter._samplers; + var samplerIndex = samplers.findIndex(function (s) { return s.minFilter === sampler.minFilter && s.magFilter === sampler.magFilter && s.wrapS === sampler.wrapS && s.wrapT === sampler.wrapT; }); + if (samplerIndex !== -1) { + return samplerIndex; + } + samplers.push(sampler); + return samplers.length - 1; + }; + /** + * Represents the dielectric specular values for R, G and B + */ + _GLTFMaterialExporter._DielectricSpecular = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3(0.04, 0.04, 0.04); + /** + * Allows the maximum specular power to be defined for material calculations + */ + _GLTFMaterialExporter._MaxSpecularPower = 1024; + /** + * Numeric tolerance value + */ + _GLTFMaterialExporter._Epsilon = 1e-6; + return _GLTFMaterialExporter; +}()); + + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/glTFSerializer.ts": +/*!***************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/glTFSerializer.ts ***! + \***************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTF2Export: () => (/* binding */ GLTF2Export) +/* harmony export */ }); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); + +/** + * Class for generating glTF data from a Babylon scene. + */ +var GLTF2Export = /** @class */ (function () { + function GLTF2Export() { + } + /** + * Exports the geometry of the scene to .gltf file format asynchronously + * @param scene Babylon scene with scene hierarchy information + * @param filePrefix File prefix to use when generating the glTF file + * @param options Exporter options + * @returns Returns an object with a .gltf file and associates texture names + * as keys and their data and paths as values + */ + GLTF2Export.GLTFAsync = function (scene, filePrefix, options) { + return scene.whenReadyAsync().then(function () { + var glTFPrefix = filePrefix.replace(/\.[^/.]+$/, ""); + var gltfGenerator = new _glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter(scene, options); + return gltfGenerator._generateGLTFAsync(glTFPrefix); + }); + }; + GLTF2Export._PreExportAsync = function (scene, options) { + return Promise.resolve().then(function () { + if (options && options.exportWithoutWaitingForScene) { + return Promise.resolve(); + } + else { + return scene.whenReadyAsync(); + } + }); + }; + GLTF2Export._PostExportAsync = function (scene, glTFData, options) { + return Promise.resolve().then(function () { + if (options && options.exportWithoutWaitingForScene) { + return glTFData; + } + else { + return glTFData; + } + }); + }; + /** + * Exports the geometry of the scene to .glb file format asychronously + * @param scene Babylon scene with scene hierarchy information + * @param filePrefix File prefix to use when generating glb file + * @param options Exporter options + * @returns Returns an object with a .glb filename as key and data as value + */ + GLTF2Export.GLBAsync = function (scene, filePrefix, options) { + var _this = this; + return this._PreExportAsync(scene, options).then(function () { + var glTFPrefix = filePrefix.replace(/\.[^/.]+$/, ""); + var gltfGenerator = new _glTFExporter__WEBPACK_IMPORTED_MODULE_0__._Exporter(scene, options); + return gltfGenerator._generateGLBAsync(glTFPrefix).then(function (glTFData) { + return _this._PostExportAsync(scene, glTFData, options); + }); + }); + }; + return GLTF2Export; +}()); + + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/glTFUtilities.ts": +/*!**************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/glTFUtilities.ts ***! + \**************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ _GLTFUtilities: () => (/* binding */ _GLTFUtilities) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__); + +/** + * @internal + */ +var _GLTFUtilities = /** @class */ (function () { + function _GLTFUtilities() { + } + /** + * Creates a buffer view based on the supplied arguments + * @param bufferIndex index value of the specified buffer + * @param byteOffset byte offset value + * @param byteLength byte length of the bufferView + * @param byteStride byte distance between conequential elements + * @param name name of the buffer view + * @returns bufferView for glTF + */ + _GLTFUtilities._CreateBufferView = function (bufferIndex, byteOffset, byteLength, byteStride, name) { + var bufferview = { buffer: bufferIndex, byteLength: byteLength }; + if (byteOffset) { + bufferview.byteOffset = byteOffset; + } + if (name) { + bufferview.name = name; + } + if (byteStride) { + bufferview.byteStride = byteStride; + } + return bufferview; + }; + /** + * Creates an accessor based on the supplied arguments + * @param bufferviewIndex The index of the bufferview referenced by this accessor + * @param name The name of the accessor + * @param type The type of the accessor + * @param componentType The datatype of components in the attribute + * @param count The number of attributes referenced by this accessor + * @param byteOffset The offset relative to the start of the bufferView in bytes + * @param min Minimum value of each component in this attribute + * @param max Maximum value of each component in this attribute + * @returns accessor for glTF + */ + _GLTFUtilities._CreateAccessor = function (bufferviewIndex, name, type, componentType, count, byteOffset, min, max) { + var accessor = { name: name, bufferView: bufferviewIndex, componentType: componentType, count: count, type: type }; + if (min != null) { + accessor.min = min; + } + if (max != null) { + accessor.max = max; + } + if (byteOffset != null) { + accessor.byteOffset = byteOffset; + } + return accessor; + }; + /** + * Calculates the minimum and maximum values of an array of position floats + * @param positions Positions array of a mesh + * @param vertexStart Starting vertex offset to calculate min and max values + * @param vertexCount Number of vertices to check for min and max values + * @returns min number array and max number array + */ + _GLTFUtilities._CalculateMinMaxPositions = function (positions, vertexStart, vertexCount) { + var min = [Infinity, Infinity, Infinity]; + var max = [-Infinity, -Infinity, -Infinity]; + var positionStrideSize = 3; + var indexOffset; + var position; + var vector; + if (vertexCount) { + for (var i = vertexStart, length_1 = vertexStart + vertexCount; i < length_1; ++i) { + indexOffset = positionStrideSize * i; + position = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(positions, indexOffset); + vector = position.asArray(); + for (var j = 0; j < positionStrideSize; ++j) { + var num = vector[j]; + if (num < min[j]) { + min[j] = num; + } + if (num > max[j]) { + max[j] = num; + } + ++indexOffset; + } + } + } + return { min: min, max: max }; + }; + _GLTFUtilities._NormalizeTangentFromRef = function (tangent) { + var length = Math.sqrt(tangent.x * tangent.x + tangent.y * tangent.y + tangent.z * tangent.z); + if (length > 0) { + tangent.x /= length; + tangent.y /= length; + tangent.z /= length; + } + }; + _GLTFUtilities._GetDataAccessorElementCount = function (accessorType) { + switch (accessorType) { + case "MAT2" /* AccessorType.MAT2 */: + return 4; + case "MAT3" /* AccessorType.MAT3 */: + return 9; + case "MAT4" /* AccessorType.MAT4 */: + return 16; + case "SCALAR" /* AccessorType.SCALAR */: + return 1; + case "VEC2" /* AccessorType.VEC2 */: + return 2; + case "VEC3" /* AccessorType.VEC3 */: + return 3; + case "VEC4" /* AccessorType.VEC4 */: + return 4; + } + }; + return _GLTFUtilities; +}()); + + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/2.0/index.ts": +/*!******************************************************!*\ + !*** ../../../dev/serializers/src/glTF/2.0/index.ts ***! + \******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_mesh_gpu_instancing: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.EXT_mesh_gpu_instancing), +/* harmony export */ GLTF2Export: () => (/* reexport safe */ _glTFSerializer__WEBPACK_IMPORTED_MODULE_5__.GLTF2Export), +/* harmony export */ GLTFData: () => (/* reexport safe */ _glTFData__WEBPACK_IMPORTED_MODULE_1__.GLTFData), +/* harmony export */ KHR_lights_punctual: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_lights_punctual), +/* harmony export */ KHR_materials_anisotropy: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_anisotropy), +/* harmony export */ KHR_materials_clearcoat: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_clearcoat), +/* harmony export */ KHR_materials_diffuse_transmission: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_diffuse_transmission), +/* harmony export */ KHR_materials_dispersion: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_dispersion), +/* harmony export */ KHR_materials_emissive_strength: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_emissive_strength), +/* harmony export */ KHR_materials_ior: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_ior), +/* harmony export */ KHR_materials_iridescence: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_iridescence), +/* harmony export */ KHR_materials_sheen: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_sheen), +/* harmony export */ KHR_materials_specular: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_specular), +/* harmony export */ KHR_materials_transmission: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_transmission), +/* harmony export */ KHR_materials_unlit: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_unlit), +/* harmony export */ KHR_materials_volume: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_volume), +/* harmony export */ KHR_texture_transform: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_7__.KHR_texture_transform), +/* harmony export */ _BinaryWriter: () => (/* reexport safe */ _glTFExporter__WEBPACK_IMPORTED_MODULE_2__._BinaryWriter), +/* harmony export */ _Exporter: () => (/* reexport safe */ _glTFExporter__WEBPACK_IMPORTED_MODULE_2__._Exporter), +/* harmony export */ _GLTFAnimation: () => (/* reexport safe */ _glTFAnimation__WEBPACK_IMPORTED_MODULE_0__._GLTFAnimation), +/* harmony export */ _GLTFMaterialExporter: () => (/* reexport safe */ _glTFMaterialExporter__WEBPACK_IMPORTED_MODULE_4__._GLTFMaterialExporter), +/* harmony export */ _GLTFUtilities: () => (/* reexport safe */ _glTFUtilities__WEBPACK_IMPORTED_MODULE_6__._GLTFUtilities), +/* harmony export */ __IGLTFExporterExtensionV2: () => (/* reexport safe */ _glTFExporterExtension__WEBPACK_IMPORTED_MODULE_3__.__IGLTFExporterExtensionV2) +/* harmony export */ }); +/* harmony import */ var _glTFAnimation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./glTFAnimation */ "../../../dev/serializers/src/glTF/2.0/glTFAnimation.ts"); +/* harmony import */ var _glTFData__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./glTFData */ "../../../dev/serializers/src/glTF/2.0/glTFData.ts"); +/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glTFExporter */ "../../../dev/serializers/src/glTF/2.0/glTFExporter.ts"); +/* harmony import */ var _glTFExporterExtension__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./glTFExporterExtension */ "../../../dev/serializers/src/glTF/2.0/glTFExporterExtension.ts"); +/* harmony import */ var _glTFMaterialExporter__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./glTFMaterialExporter */ "../../../dev/serializers/src/glTF/2.0/glTFMaterialExporter.ts"); +/* harmony import */ var _glTFSerializer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./glTFSerializer */ "../../../dev/serializers/src/glTF/2.0/glTFSerializer.ts"); +/* harmony import */ var _glTFUtilities__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./glTFUtilities */ "../../../dev/serializers/src/glTF/2.0/glTFUtilities.ts"); +/* harmony import */ var _Extensions_index__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Extensions/index */ "../../../dev/serializers/src/glTF/2.0/Extensions/index.ts"); +/* eslint-disable import/no-internal-modules */ + + + + + + + + + + +/***/ }), + +/***/ "../../../dev/serializers/src/glTF/glTFFileExporter.ts": +/*!*************************************************************!*\ + !*** ../../../dev/serializers/src/glTF/glTFFileExporter.ts ***! + \*************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ __IGLTFExporterExtension: () => (/* binding */ __IGLTFExporterExtension) +/* harmony export */ }); +/** @internal */ +// eslint-disable-next-line no-var, @typescript-eslint/naming-convention +var __IGLTFExporterExtension = 0; // I am here to allow dts to be created + + +/***/ }), + +/***/ "../../../lts/serializers/src/legacy/legacy-glTF2Serializer.ts": +/*!*********************************************************************!*\ + !*** ../../../lts/serializers/src/legacy/legacy-glTF2Serializer.ts ***! + \*********************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_mesh_gpu_instancing: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.EXT_mesh_gpu_instancing), +/* harmony export */ GLTF2Export: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.GLTF2Export), +/* harmony export */ GLTFData: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.GLTFData), +/* harmony export */ KHR_lights_punctual: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_lights_punctual), +/* harmony export */ KHR_materials_anisotropy: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_anisotropy), +/* harmony export */ KHR_materials_clearcoat: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_clearcoat), +/* harmony export */ KHR_materials_diffuse_transmission: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_diffuse_transmission), +/* harmony export */ KHR_materials_dispersion: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_dispersion), +/* harmony export */ KHR_materials_emissive_strength: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_emissive_strength), +/* harmony export */ KHR_materials_ior: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_ior), +/* harmony export */ KHR_materials_iridescence: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_iridescence), +/* harmony export */ KHR_materials_sheen: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_sheen), +/* harmony export */ KHR_materials_specular: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_specular), +/* harmony export */ KHR_materials_transmission: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_transmission), +/* harmony export */ KHR_materials_unlit: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_unlit), +/* harmony export */ KHR_materials_volume: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_volume), +/* harmony export */ KHR_texture_transform: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.KHR_texture_transform), +/* harmony export */ _BinaryWriter: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__._BinaryWriter), +/* harmony export */ _Exporter: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__._Exporter), +/* harmony export */ _GLTFAnimation: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__._GLTFAnimation), +/* harmony export */ _GLTFMaterialExporter: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__._GLTFMaterialExporter), +/* harmony export */ _GLTFUtilities: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__._GLTFUtilities), +/* harmony export */ __IGLTFExporterExtension: () => (/* reexport safe */ serializers_glTF_glTFFileExporter__WEBPACK_IMPORTED_MODULE_0__.__IGLTFExporterExtension), +/* harmony export */ __IGLTFExporterExtensionV2: () => (/* reexport safe */ serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__.__IGLTFExporterExtensionV2) +/* harmony export */ }); +/* harmony import */ var serializers_glTF_glTFFileExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! serializers/glTF/glTFFileExporter */ "../../../dev/serializers/src/glTF/glTFFileExporter.ts"); +/* harmony import */ var serializers_glTF_2_0_glTFData__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! serializers/glTF/2.0/glTFData */ "../../../dev/serializers/src/glTF/2.0/glTFData.ts"); +/* harmony import */ var serializers_glTF_2_0_glTFSerializer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! serializers/glTF/2.0/glTFSerializer */ "../../../dev/serializers/src/glTF/2.0/glTFSerializer.ts"); +/* harmony import */ var serializers_glTF_2_0_Extensions_index__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! serializers/glTF/2.0/Extensions/index */ "../../../dev/serializers/src/glTF/2.0/Extensions/index.ts"); +/* harmony import */ var serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! serializers/glTF/2.0/index */ "../../../dev/serializers/src/glTF/2.0/index.ts"); +/* eslint-disable import/no-internal-modules */ + + + + + +/** + * This is the entry point for the UMD module. + * The entry point for a future ESM package should be index.ts + */ +var globalObject = typeof __webpack_require__.g !== "undefined" ? __webpack_require__.g : typeof window !== "undefined" ? window : undefined; +if (typeof globalObject !== "undefined") { + globalObject.BABYLON = globalObject.BABYLON || {}; + var BABYLON_1 = globalObject.BABYLON; + BABYLON_1.GLTF2 = BABYLON_1.GLTF2 || {}; + BABYLON_1.GLTF2.Exporter = BABYLON_1.GLTF2.Exporter || {}; + BABYLON_1.GLTF2.Exporter.Extensions = BABYLON_1.GLTF2.Exporter.Extensions || {}; + var keys = []; + for (var key in serializers_glTF_glTFFileExporter__WEBPACK_IMPORTED_MODULE_0__) { + BABYLON_1[key] = serializers_glTF_glTFFileExporter__WEBPACK_IMPORTED_MODULE_0__[key]; + keys.push(key); + } + for (var key in serializers_glTF_2_0_glTFData__WEBPACK_IMPORTED_MODULE_1__) { + BABYLON_1[key] = serializers_glTF_2_0_glTFData__WEBPACK_IMPORTED_MODULE_1__[key]; + keys.push(key); + } + for (var key in serializers_glTF_2_0_glTFSerializer__WEBPACK_IMPORTED_MODULE_2__) { + BABYLON_1[key] = serializers_glTF_2_0_glTFSerializer__WEBPACK_IMPORTED_MODULE_2__[key]; + keys.push(key); + } + for (var key in serializers_glTF_2_0_Extensions_index__WEBPACK_IMPORTED_MODULE_3__) { + BABYLON_1.GLTF2.Exporter.Extensions[key] = serializers_glTF_2_0_Extensions_index__WEBPACK_IMPORTED_MODULE_3__[key]; + keys.push(key); + } + for (var key in serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__) { + // Prevent Reassignment. + if (keys.indexOf(key) > -1) { + continue; + } + BABYLON_1.GLTF2.Exporter[key] = serializers_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_4__[key]; + } +} + + + + +/***/ }), + +/***/ "babylonjs/Maths/math.vector": +/*!****************************************************************************************************!*\ + !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***! + \****************************************************************************************************/ +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__; + +/***/ }), + +/***/ "../../../../node_modules/tslib/tslib.es6.mjs": +/*!****************************************************!*\ + !*** ../../../../node_modules/tslib/tslib.es6.mjs ***! + \****************************************************/ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ __addDisposableResource: () => (/* binding */ __addDisposableResource), +/* harmony export */ __assign: () => (/* binding */ __assign), +/* harmony export */ __asyncDelegator: () => (/* binding */ __asyncDelegator), +/* harmony export */ __asyncGenerator: () => (/* binding */ __asyncGenerator), +/* harmony export */ __asyncValues: () => (/* binding */ __asyncValues), +/* harmony export */ __await: () => (/* binding */ __await), +/* harmony export */ __awaiter: () => (/* binding */ __awaiter), +/* harmony export */ __classPrivateFieldGet: () => (/* binding */ __classPrivateFieldGet), +/* harmony export */ __classPrivateFieldIn: () => (/* binding */ __classPrivateFieldIn), +/* harmony export */ __classPrivateFieldSet: () => (/* binding */ __classPrivateFieldSet), +/* harmony export */ __createBinding: () => (/* binding */ __createBinding), +/* harmony export */ __decorate: () => (/* binding */ __decorate), +/* harmony export */ __disposeResources: () => (/* binding */ __disposeResources), +/* harmony export */ __esDecorate: () => (/* binding */ __esDecorate), +/* harmony export */ __exportStar: () => (/* binding */ __exportStar), +/* harmony export */ __extends: () => (/* binding */ __extends), +/* harmony export */ __generator: () => (/* binding */ __generator), +/* harmony export */ __importDefault: () => (/* binding */ __importDefault), +/* harmony export */ __importStar: () => (/* binding */ __importStar), +/* harmony export */ __makeTemplateObject: () => (/* binding */ __makeTemplateObject), +/* harmony export */ __metadata: () => (/* binding */ __metadata), +/* harmony export */ __param: () => (/* binding */ __param), +/* harmony export */ __propKey: () => (/* binding */ __propKey), +/* harmony export */ __read: () => (/* binding */ __read), +/* harmony export */ __rest: () => (/* binding */ __rest), +/* harmony export */ __rewriteRelativeImportExtension: () => (/* binding */ __rewriteRelativeImportExtension), +/* harmony export */ __runInitializers: () => (/* binding */ __runInitializers), +/* harmony export */ __setFunctionName: () => (/* binding */ __setFunctionName), +/* harmony export */ __spread: () => (/* binding */ __spread), +/* harmony export */ __spreadArray: () => (/* binding */ __spreadArray), +/* harmony export */ __spreadArrays: () => (/* binding */ __spreadArrays), +/* harmony export */ __values: () => (/* binding */ __values), +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +/* global Reflect, Promise, SuppressedError, Symbol, Iterator */ + +var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); +}; + +function __extends(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} + +var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + } + return __assign.apply(this, arguments); +} + +function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +} + +function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} + +function __param(paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } +} + +function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; + +function __runInitializers(thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; + +function __propKey(x) { + return typeof x === "symbol" ? x : "".concat(x); +}; + +function __setFunctionName(f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); +}; + +function __metadata(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); +} + +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); + return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +} + +var __createBinding = Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +}); + +function __exportStar(m, o) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); +} + +function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); +} + +function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +} + +/** @deprecated */ +function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; +} + +/** @deprecated */ +function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +} + +function __spreadArray(to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +} + +function __await(v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); +} + +function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; + function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } + function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } +} + +function __asyncDelegator(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; + function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } +} + +function __asyncValues(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +} + +function __makeTemplateObject(cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; +}; + +var __setModuleDefault = Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}; + +function __importStar(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +} + +function __importDefault(mod) { + return (mod && mod.__esModule) ? mod : { default: mod }; +} + +function __classPrivateFieldGet(receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +} + +function __classPrivateFieldSet(receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +} + +function __classPrivateFieldIn(state, receiver) { + if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); + return typeof state === "function" ? receiver === state : state.has(receiver); +} + +function __addDisposableResource(env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose, inner; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + if (async) inner = dispose; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } }; + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +} + +var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}; + +function __disposeResources(env) { + function fail(e) { + env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + var r, s = 0; + function next() { + while (r = env.stack.pop()) { + try { + if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); + if (r.dispose) { + var result = r.dispose.call(r.value); + if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + else s |= 1; + } + catch (e) { + fail(e); + } + } + if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); + if (env.hasError) throw env.error; + } + return next(); +} + +function __rewriteRelativeImportExtension(path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); + } + return path; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ + __extends, + __assign, + __rest, + __decorate, + __param, + __esDecorate, + __runInitializers, + __propKey, + __setFunctionName, + __metadata, + __awaiter, + __generator, + __createBinding, + __exportStar, + __values, + __read, + __spread, + __spreadArrays, + __spreadArray, + __await, + __asyncGenerator, + __asyncDelegator, + __asyncValues, + __makeTemplateObject, + __importStar, + __importDefault, + __classPrivateFieldGet, + __classPrivateFieldSet, + __classPrivateFieldIn, + __addDisposableResource, + __disposeResources, + __rewriteRelativeImportExtension, +}); + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/compat get default export */ +/******/ (() => { +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = (module) => { +/******/ var getter = module && module.__esModule ? +/******/ () => (module['default']) : +/******/ () => (module); +/******/ __webpack_require__.d(getter, { a: getter }); +/******/ return getter; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/global */ +/******/ (() => { +/******/ __webpack_require__.g = (function() { +/******/ if (typeof globalThis === 'object') return globalThis; +/******/ try { +/******/ return this || new Function('return this')(); +/******/ } catch (e) { +/******/ if (typeof window === 'object') return window; +/******/ } +/******/ })(); +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +/*!**********************!*\ + !*** ./src/glTF2.ts ***! + \**********************/ +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__), +/* harmony export */ serializers: () => (/* reexport module object */ _lts_serializers_legacy_legacy_glTF2Serializer__WEBPACK_IMPORTED_MODULE_0__) +/* harmony export */ }); +/* harmony import */ var _lts_serializers_legacy_legacy_glTF2Serializer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @lts/serializers/legacy/legacy-glTF2Serializer */ "../../../lts/serializers/src/legacy/legacy-glTF2Serializer.ts"); + + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_lts_serializers_legacy_legacy_glTF2Serializer__WEBPACK_IMPORTED_MODULE_0__); + +})(); + +__webpack_exports__ = __webpack_exports__["default"]; +/******/ return __webpack_exports__; +/******/ })() +; +}); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFieWxvbi5nbFRGMlNlcmlhbGl6ZXIuanMiLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNOQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFjQTtBQWJBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUlBO0FBR0E7QUFDQTtBQUVBO0FBR0E7QUFEQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFFQTs7Ozs7Ozs7QUFRQTtBQUNBO0FBQUE7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFPQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3RMQTtBQUNBO0FBQ0E7QUFFQTtBQUlBO0FBQ0E7QUFHQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQWVBOztBQUVBO0FBQ0E7QUFqQkE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBV0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFEQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FBT0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzNMQTtBQUVBO0FBR0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFjQTtBQWJBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUlBO0FBR0E7QUFDQTtBQUVBO0FBR0E7QUFEQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNoRkE7QUFFQTtBQUdBO0FBRUE7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFjQTtBQWJBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUlBO0FBR0E7QUFDQTtBQUVBO0FBR0E7QUFEQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzFHQTtBQUVBO0FBR0E7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBY0E7QUFiQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFJQTtBQUdBO0FBQ0E7QUFFQTtBQUdBO0FBREE7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBRUE7Ozs7OztBQU1BO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7O0FBTUE7QUFDQTtBQUFBO0FBQ0E7O0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN2SEE7QUFFQTtBQUVBO0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQVlBO0FBQ0E7QUFaQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUdBO0FBRUE7QUFDQTtBQUdBO0FBREE7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7OztBQU1BO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUMxRUE7QUFFQTtBQUdBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQTZDQTtBQTNDQTtBQUNBO0FBR0E7QUFEQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFFQTs7Ozs7O0FBTUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ25FQTtBQUVBO0FBRUE7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFZQTtBQVhBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBR0E7QUFEQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2hFQTtBQUVBO0FBR0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFjQTtBQWJBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUlBO0FBR0E7QUFDQTtBQUVBO0FBR0E7QUFEQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3hGQTtBQUVBO0FBR0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFjQTtBQWJBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBS0E7QUFDQTtBQUVBO0FBR0E7QUFEQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFBQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3BGQTtBQUVBO0FBR0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFjQTtBQWJBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUlBO0FBR0E7QUFDQTtBQUVBO0FBQ0E7QUFHQTtBQURBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQUE7QUFDQTs7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNsSEE7QUFFQTtBQUVBO0FBRUE7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFjQTtBQWJBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUlBO0FBR0E7QUFDQTtBQUVBO0FBQ0E7QUFHQTtBQURBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7O0FBTUE7QUFDQTs7Ozs7OztBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBOztBQUFBO0FBQ0E7QUFDQTtBQUNBOzs7QUFFQTs7O0FBSUE7QUFDQTs7QUFHQTs7OztBQUNBO0FBQ0E7QUFBQTs7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDbEhBO0FBRUE7QUFDQTtBQUVBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBWUE7QUFYQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBR0E7QUFEQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFFQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN6REE7QUFFQTtBQUVBO0FBRUE7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFjQTtBQWJBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUlBO0FBR0E7QUFDQTtBQUVBO0FBR0E7QUFEQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFFQTs7Ozs7O0FBTUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7O0FBTUE7QUFDQTtBQUFBO0FBQ0E7O0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNySEE7QUFJQTtBQUVBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBYUE7QUFaQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUdBO0FBREE7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDdEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBR0E7QUFJQTtBQUNBO0FBaURBOzs7QUFHQTtBQUNBO0FBQ0E7QUFBQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUFBO0FBbzhCQTtBQW44QkE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7Ozs7QUFTQTtBQUNBO0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFhQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQWFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7Ozs7Ozs7QUFZQTtBQUNBO0FBWUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFjQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7Ozs7Ozs7OztBQVlBO0FBQ0E7QUFZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFRQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQWVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7Ozs7OztBQVdBO0FBQ0E7O0FBVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBY0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTs7QUExREE7QUFBQTtBQTJEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFlQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUF6SUE7QUFBQTtBQUFBO0FBMElBO0FBQ0E7QUFDQTtBQUVBO0FBZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBVUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7Ozs7Ozs7Ozs7O0FBZUE7QUFDQTtBQWFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBV0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7Ozs7QUFRQTtBQUNBO0FBUUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7Ozs7O0FBUUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7OztBQVFBO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7O0FBTUE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7Ozs7Ozs7O0FBU0E7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7O0FDemhDQTs7QUFFQTtBQUNBO0FBTUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBR0E7QUFFQTtBQUNBO0FBSUE7QUFDQTtBQUlBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBdUNBOzs7QUFHQTtBQUNBO0FBdU9BOzs7O0FBSUE7QUFDQTtBQWpKQTtBQWtKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQXpLQTtBQUFBO0FBTUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFJQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBTUE7QUFJQTtBQUVBO0FBT0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBc0NBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBOzs7QUFBQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7Ozs7QUFTQTtBQUNBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7Ozs7O0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7Ozs7O0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7Ozs7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7O0FBTUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7Ozs7QUFTQTtBQUNBO0FBUUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBOzs7OztBQUtBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7QUFHQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7OztBQU9BO0FBQ0E7QUFPQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQVVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBVUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7OztBQUtBO0FBQ0E7QUFBQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7OztBQUtBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQVlBO0FBQ0E7QUFZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBL0NBO0FBQUE7QUFBQTtBQWdEQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFVQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7OztBQUtBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7O0FBS0E7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFVQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFsekRBO0FBQ0E7QUFrekRBO0FBQUE7QUFoNURBO0FBazVEQTs7OztBQUlBO0FBQ0E7QUFhQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7Ozs7Ozs7Ozs7Ozs7OztBQy94RUE7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFLQTtBQUNBO0FBdURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7QUFHQTtBQUNBO0FBNkJBO0FBbEJBOztBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBYUE7QUFDQTtBQUNBO0FBRUE7Ozs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7OztBQU1BO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7Ozs7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7OztBQU9BO0FBQ0E7Ozs7OztBQUNBO0FBRUE7QUFDQTtBQUdBO0FBRUE7O0FBQUE7QUFFQTs7QUFBQTtBQUVBO0FBQUE7Ozs7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTs7Ozs7O0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7Ozs7QUFTQTtBQUNBOzs7Ozs7O0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7O0FBQUE7QUFDQTs7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBRUE7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7OztBQU9BO0FBQ0E7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7Ozs7QUFPQTtBQUNBO0FBQUE7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7OztBQU1BO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFHQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7O0FBS0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7O0FBQ0E7QUFDQTtBQUNBOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBQ0E7O0FBQUE7QUFDQTs7O0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTs7QUFBQTtBQUNBO0FBQ0E7O0FBR0E7Ozs7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBemtDQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQVVBOztBQUVBO0FBQ0E7QUFxakNBO0FBQUE7QUEza0NBOzs7Ozs7Ozs7Ozs7Ozs7O0FDckZBO0FBc0RBOztBQUVBO0FBQ0E7QUFBQTtBQXFEQTtBQXBEQTs7Ozs7OztBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7OztBQU1BO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUM3R0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUE4SEE7QUE3SEE7Ozs7Ozs7O0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7Ozs7Ozs7OztBQVdBO0FBQ0E7QUFVQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7Ozs7O0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN4SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7QUNSQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7QUNqREE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDdllBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNQQTs7Ozs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ05BO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL1NFUklBTElaRVJTL3dlYnBhY2svdW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbiIsIndlYnBhY2s6Ly9TRVJJQUxJWkVSUy8uLi8uLi8uLi9kZXYvc2VyaWFsaXplcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvRVhUX21lc2hfZ3B1X2luc3RhbmNpbmcudHMiLCJ3ZWJwYWNrOi8vU0VSSUFMSVpFUlMvLi4vLi4vLi4vZGV2L3NlcmlhbGl6ZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9saWdodHNfcHVuY3R1YWwudHMiLCJ3ZWJwYWNrOi8vU0VSSUFMSVpFUlMvLi4vLi4vLi4vZGV2L3NlcmlhbGl6ZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfYW5pc290cm9weS50cyIsIndlYnBhY2s6Ly9TRVJJQUxJWkVSUy8uLi8uLi8uLi9kZXYvc2VyaWFsaXplcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc19jbGVhcmNvYXQudHMiLCJ3ZWJwYWNrOi8vU0VSSUFMSVpFUlMvLi4vLi4vLi4vZGV2L3NlcmlhbGl6ZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfZGlmZnVzZV90cmFuc21pc3Npb24udHMiLCJ3ZWJwYWNrOi8vU0VSSUFMSVpFUlMvLi4vLi4vLi4vZGV2L3NlcmlhbGl6ZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfZGlzcGVyc2lvbi50cyIsIndlYnBhY2s6Ly9TRVJJQUxJWkVSUy8uLi8uLi8uLi9kZXYvc2VyaWFsaXplcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc19lbWlzc2l2ZV9zdHJlbmd0aC50cyIsIndlYnBhY2s6Ly9TRVJJQUxJWkVSUy8uLi8uLi8uLi9kZXYvc2VyaWFsaXplcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc19pb3IudHMiLCJ3ZWJwYWNrOi8vU0VSSUFMSVpFUlMvLi4vLi4vLi4vZGV2L3NlcmlhbGl6ZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfaXJpZGVzY2VuY2UudHMiLCJ3ZWJwYWNrOi8vU0VSSUFMSVpFUlMvLi4vLi4vLi4vZGV2L3NlcmlhbGl6ZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfc2hlZW4udHMiLCJ3ZWJwYWNrOi8vU0VSSUFMSVpFUlMvLi4vLi4vLi4vZGV2L3NlcmlhbGl6ZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfc3BlY3VsYXIudHMiLCJ3ZWJwYWNrOi8vU0VSSUFMSVpFUlMvLi4vLi4vLi4vZGV2L3NlcmlhbGl6ZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfdHJhbnNtaXNzaW9uLnRzIiwid2VicGFjazovL1NFUklBTElaRVJTLy4uLy4uLy4uL2Rldi9zZXJpYWxpemVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfbWF0ZXJpYWxzX3VubGl0LnRzIiwid2VicGFjazovL1NFUklBTElaRVJTLy4uLy4uLy4uL2Rldi9zZXJpYWxpemVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfbWF0ZXJpYWxzX3ZvbHVtZS50cyIsIndlYnBhY2s6Ly9TRVJJQUxJWkVSUy8uLi8uLi8uLi9kZXYvc2VyaWFsaXplcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX3RleHR1cmVfdHJhbnNmb3JtLnRzIiwid2VicGFjazovL1NFUklBTElaRVJTLy4uLy4uLy4uL2Rldi9zZXJpYWxpemVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9pbmRleC50cyIsIndlYnBhY2s6Ly9TRVJJQUxJWkVSUy8uLi8uLi8uLi9kZXYvc2VyaWFsaXplcnMvc3JjL2dsVEYvMi4wL2dsVEZBbmltYXRpb24udHMiLCJ3ZWJwYWNrOi8vU0VSSUFMSVpFUlMvLi4vLi4vLi4vZGV2L3NlcmlhbGl6ZXJzL3NyYy9nbFRGLzIuMC9nbFRGRGF0YS50cyIsIndlYnBhY2s6Ly9TRVJJQUxJWkVSUy8uLi8uLi8uLi9kZXYvc2VyaWFsaXplcnMvc3JjL2dsVEYvMi4wL2dsVEZFeHBvcnRlci50cyIsIndlYnBhY2s6Ly9TRVJJQUxJWkVSUy8uLi8uLi8uLi9kZXYvc2VyaWFsaXplcnMvc3JjL2dsVEYvMi4wL2dsVEZFeHBvcnRlckV4dGVuc2lvbi50cyIsIndlYnBhY2s6Ly9TRVJJQUxJWkVSUy8uLi8uLi8uLi9kZXYvc2VyaWFsaXplcnMvc3JjL2dsVEYvMi4wL2dsVEZNYXRlcmlhbEV4cG9ydGVyLnRzIiwid2VicGFjazovL1NFUklBTElaRVJTLy4uLy4uLy4uL2Rldi9zZXJpYWxpemVycy9zcmMvZ2xURi8yLjAvZ2xURlNlcmlhbGl6ZXIudHMiLCJ3ZWJwYWNrOi8vU0VSSUFMSVpFUlMvLi4vLi4vLi4vZGV2L3NlcmlhbGl6ZXJzL3NyYy9nbFRGLzIuMC9nbFRGVXRpbGl0aWVzLnRzIiwid2VicGFjazovL1NFUklBTElaRVJTLy4uLy4uLy4uL2Rldi9zZXJpYWxpemVycy9zcmMvZ2xURi8yLjAvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vU0VSSUFMSVpFUlMvLi4vLi4vLi4vZGV2L3NlcmlhbGl6ZXJzL3NyYy9nbFRGL2dsVEZGaWxlRXhwb3J0ZXIudHMiLCJ3ZWJwYWNrOi8vU0VSSUFMSVpFUlMvLi4vLi4vLi4vbHRzL3NlcmlhbGl6ZXJzL3NyYy9sZWdhY3kvbGVnYWN5LWdsVEYyU2VyaWFsaXplci50cyIsIndlYnBhY2s6Ly9TRVJJQUxJWkVSUy9leHRlcm5hbCB1bWQge1wicm9vdFwiOlwiQkFCWUxPTlwiLFwiY29tbW9uanNcIjpcImJhYnlsb25qc1wiLFwiY29tbW9uanMyXCI6XCJiYWJ5bG9uanNcIixcImFtZFwiOlwiYmFieWxvbmpzXCJ9Iiwid2VicGFjazovL1NFUklBTElaRVJTLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5lczYubWpzIiwid2VicGFjazovL1NFUklBTElaRVJTL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL1NFUklBTElaRVJTL3dlYnBhY2svcnVudGltZS9jb21wYXQgZ2V0IGRlZmF1bHQgZXhwb3J0Iiwid2VicGFjazovL1NFUklBTElaRVJTL3dlYnBhY2svcnVudGltZS9kZWZpbmUgcHJvcGVydHkgZ2V0dGVycyIsIndlYnBhY2s6Ly9TRVJJQUxJWkVSUy93ZWJwYWNrL3J1bnRpbWUvZ2xvYmFsIiwid2VicGFjazovL1NFUklBTElaRVJTL3dlYnBhY2svcnVudGltZS9oYXNPd25Qcm9wZXJ0eSBzaG9ydGhhbmQiLCJ3ZWJwYWNrOi8vU0VSSUFMSVpFUlMvd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly9TRVJJQUxJWkVSUy8uL3NyYy9nbFRGMi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gd2VicGFja1VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24ocm9vdCwgZmFjdG9yeSkge1xuXHRpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcpXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCJiYWJ5bG9uanNcIikpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoXCJiYWJ5bG9uanMtc2VyaWFsaXplcnNcIiwgW1wiYmFieWxvbmpzXCJdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcImJhYnlsb25qcy1zZXJpYWxpemVyc1wiXSA9IGZhY3RvcnkocmVxdWlyZShcImJhYnlsb25qc1wiKSk7XG5cdGVsc2Vcblx0XHRyb290W1wiU0VSSUFMSVpFUlNcIl0gPSBmYWN0b3J5KHJvb3RbXCJCQUJZTE9OXCJdKTtcbn0pKCh0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdGhpcyksIChfX1dFQlBBQ0tfRVhURVJOQUxfTU9EVUxFX2JhYnlsb25qc19NYXRoc19tYXRoX3ZlY3Rvcl9fKSA9PiB7XG5yZXR1cm4gIiwiaW1wb3J0IHR5cGUgeyBJQnVmZmVyVmlldywgSUFjY2Vzc29yLCBJTm9kZSwgSUVYVE1lc2hHcHVJbnN0YW5jaW5nIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyBBY2Nlc3NvclR5cGUsIEFjY2Vzc29yQ29tcG9uZW50VHlwZSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIgfSBmcm9tIFwiLi4vZ2xURkV4cG9ydGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB0eXBlIHsgX0JpbmFyeVdyaXRlciB9IGZyb20gXCIuLi9nbFRGRXhwb3J0ZXJcIjtcclxuaW1wb3J0IHsgX0V4cG9ydGVyIH0gZnJvbSBcIi4uL2dsVEZFeHBvcnRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSBcImNvcmUvbm9kZVwiO1xyXG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcImNvcmUvTWVzaGVzL21lc2hcIjtcclxuaW1wb3J0IFwiY29yZS9NZXNoZXMvdGhpbkluc3RhbmNlTWVzaFwiO1xyXG5pbXBvcnQgeyBUbXBWZWN0b3JzLCBRdWF0ZXJuaW9uLCBWZWN0b3IzIH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC52ZWN0b3JcIjtcclxuaW1wb3J0IHsgVmVydGV4QnVmZmVyIH0gZnJvbSBcImNvcmUvQnVmZmVycy9idWZmZXJcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIkVYVF9tZXNoX2dwdV9pbnN0YW5jaW5nXCI7XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvVmVuZG9yL0VYVF9tZXNoX2dwdV9pbnN0YW5jaW5nL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEVYVF9tZXNoX2dwdV9pbnN0YW5jaW5nIGltcGxlbWVudHMgSUdMVEZFeHBvcnRlckV4dGVuc2lvblYyIHtcclxuICAgIC8qKiBOYW1lIG9mIHRoaXMgZXh0ZW5zaW9uICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZCA9IHRydWU7XHJcblxyXG4gICAgLyoqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyByZXF1aXJlZCAqL1xyXG4gICAgcHVibGljIHJlcXVpcmVkID0gZmFsc2U7XHJcblxyXG4gICAgcHJpdmF0ZSBfZXhwb3J0ZXI6IF9FeHBvcnRlcjtcclxuXHJcbiAgICBwcml2YXRlIF93YXNVc2VkID0gZmFsc2U7XHJcblxyXG4gICAgY29uc3RydWN0b3IoZXhwb3J0ZXI6IF9FeHBvcnRlcikge1xyXG4gICAgICAgIHRoaXMuX2V4cG9ydGVyID0gZXhwb3J0ZXI7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7fVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBnZXQgd2FzVXNlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fd2FzVXNlZDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFmdGVyIG5vZGUgaXMgZXhwb3J0ZWRcclxuICAgICAqIEBwYXJhbSBjb250ZXh0IHRoZSBHTFRGIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgZXhwb3J0ZWRcclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uTm9kZSB0aGUgY29ycmVzcG9uZGluZyBiYWJ5bG9uIG5vZGVcclxuICAgICAqIEBwYXJhbSBub2RlTWFwIG1hcCBmcm9tIGJhYnlsb24gbm9kZSBpZCB0byBub2RlIGluZGV4XHJcbiAgICAgKiBAcGFyYW0gYmluYXJ5V3JpdGVyIGJpbmFyeSB3cml0ZXJcclxuICAgICAqIEByZXR1cm5zIG51bGxhYmxlIHByb21pc2UsIHJlc29sdmVzIHdpdGggdGhlIG5vZGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIHBvc3RFeHBvcnROb2RlQXN5bmMoXHJcbiAgICAgICAgY29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIG5vZGU6IE51bGxhYmxlPElOb2RlPixcclxuICAgICAgICBiYWJ5bG9uTm9kZTogTm9kZSxcclxuICAgICAgICBub2RlTWFwOiB7IFtrZXk6IG51bWJlcl06IG51bWJlciB9LFxyXG4gICAgICAgIGJpbmFyeVdyaXRlcjogX0JpbmFyeVdyaXRlclxyXG4gICAgKTogUHJvbWlzZTxOdWxsYWJsZTxJTm9kZT4+IHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcclxuICAgICAgICAgICAgaWYgKG5vZGUgJiYgYmFieWxvbk5vZGUgaW5zdGFuY2VvZiBNZXNoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk5vZGUuaGFzVGhpbkluc3RhbmNlcyAmJiBiaW5hcnlXcml0ZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl93YXNVc2VkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9UcmFuc2xhdGlvbiA9IFZlY3RvcjMuWmVybygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vUm90YXRpb24gPSBRdWF0ZXJuaW9uLklkZW50aXR5KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9TY2FsZSA9IFZlY3RvcjMuT25lKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHJldHJpZXZlIGFsbCB0aGUgaW5zdGFuY2Ugd29ybGQgbWF0cml4XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0cml4ID0gYmFieWxvbk5vZGUudGhpbkluc3RhbmNlR2V0V29ybGRNYXRyaWNlcygpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpd3QgPSBUbXBWZWN0b3JzLlZlY3RvcjNbMl07XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaXdyID0gVG1wVmVjdG9ycy5RdWF0ZXJuaW9uWzFdO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGl3cyA9IFRtcFZlY3RvcnMuVmVjdG9yM1szXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGhhc0FueUluc3RhbmNlV29ybGRUcmFuc2xhdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBoYXNBbnlJbnN0YW5jZVdvcmxkUm90YXRpb24gPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgaGFzQW55SW5zdGFuY2VXb3JsZFNjYWxlID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHByZXBhcmUgdGVtcCBidWZmZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhbnNsYXRpb25CdWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGJhYnlsb25Ob2RlLnRoaW5JbnN0YW5jZUNvdW50ICogMyk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgcm90YXRpb25CdWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGJhYnlsb25Ob2RlLnRoaW5JbnN0YW5jZUNvdW50ICogNCk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2NhbGVCdWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGJhYnlsb25Ob2RlLnRoaW5JbnN0YW5jZUNvdW50ICogMyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG0gb2YgbWF0cml4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG0uZGVjb21wb3NlKGl3cywgaXdyLCBpd3QpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlsbCB0aGUgdGVtcCBidWZmZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRpb25CdWZmZXIuc2V0KGl3dC5hc0FycmF5KCksIGkgKiAzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcm90YXRpb25CdWZmZXIuc2V0KGl3ci5ub3JtYWxpemUoKS5hc0FycmF5KCksIGkgKiA0KTsgLy8gZW5zdXJlIHRoZSBxdWF0ZXJuaW9uIGlzIG5vcm1hbGl6ZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVCdWZmZXIuc2V0KGl3cy5hc0FycmF5KCksIGkgKiAzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgd2hlcmUgd2UgZGVjaWRlIGlmIHRoZXJlIGlzIGFueSB0cmFuc2Zvcm1hdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBoYXNBbnlJbnN0YW5jZVdvcmxkVHJhbnNsYXRpb24gPSBoYXNBbnlJbnN0YW5jZVdvcmxkVHJhbnNsYXRpb24gfHwgIWl3dC5lcXVhbHNXaXRoRXBzaWxvbihub1RyYW5zbGF0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzQW55SW5zdGFuY2VXb3JsZFJvdGF0aW9uID0gaGFzQW55SW5zdGFuY2VXb3JsZFJvdGF0aW9uIHx8ICFpd3IuZXF1YWxzV2l0aEVwc2lsb24obm9Sb3RhdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc0FueUluc3RhbmNlV29ybGRTY2FsZSA9IGhhc0FueUluc3RhbmNlV29ybGRTY2FsZSB8fCAhaXdzLmVxdWFsc1dpdGhFcHNpbG9uKG5vU2NhbGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaSsrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uOiBJRVhUTWVzaEdwdUluc3RhbmNpbmcgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHt9LFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGRvIHdlIG5lZWQgdG8gd3JpdGUgVFJBTlNMQVRJT04gP1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChoYXNBbnlJbnN0YW5jZVdvcmxkVHJhbnNsYXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmF0dHJpYnV0ZXNbXCJUUkFOU0xBVElPTlwiXSA9IHRoaXMuX2J1aWxkQWNjZXNzb3IoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGlvbkJ1ZmZlcixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjY2Vzc29yVHlwZS5WRUMzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbk5vZGUudGhpbkluc3RhbmNlQ291bnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5hcnlXcml0ZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBY2Nlc3NvckNvbXBvbmVudFR5cGUuRkxPQVRcclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZG8gd2UgbmVlZCB0byB3cml0ZSBST1RBVElPTiA/XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc0FueUluc3RhbmNlV29ybGRSb3RhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb21wb25lbnRUeXBlID0gQWNjZXNzb3JDb21wb25lbnRUeXBlLkZMT0FUOyAvLyB3ZSBkZWNpZGVkIHRvIHN0YXkgb24gRkxPQVQgZm9yIG5vdyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL0JhYnlsb25KUy9CYWJ5bG9uLmpzL3B1bGwvMTI0OTVcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmF0dHJpYnV0ZXNbXCJST1RBVElPTlwiXSA9IHRoaXMuX2J1aWxkQWNjZXNzb3Iocm90YXRpb25CdWZmZXIsIEFjY2Vzc29yVHlwZS5WRUM0LCBiYWJ5bG9uTm9kZS50aGluSW5zdGFuY2VDb3VudCwgYmluYXJ5V3JpdGVyLCBjb21wb25lbnRUeXBlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZG8gd2UgbmVlZCB0byB3cml0ZSBTQ0FMRSA/XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc0FueUluc3RhbmNlV29ybGRTY2FsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24uYXR0cmlidXRlc1tcIlNDQUxFXCJdID0gdGhpcy5fYnVpbGRBY2Nlc3NvcihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlQnVmZmVyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQWNjZXNzb3JUeXBlLlZFQzMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTm9kZS50aGluSW5zdGFuY2VDb3VudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmFyeVdyaXRlcixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjY2Vzc29yQ29tcG9uZW50VHlwZS5GTE9BVFxyXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLyogZXNsaW50LWVuYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24qL1xyXG4gICAgICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9ucyA9IG5vZGUuZXh0ZW5zaW9ucyB8fCB7fTtcclxuICAgICAgICAgICAgICAgICAgICBub2RlLmV4dGVuc2lvbnNbTkFNRV0gPSBleHRlbnNpb247XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmVzb2x2ZShub2RlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9idWlsZEFjY2Vzc29yKGJ1ZmZlcjogRmxvYXQzMkFycmF5LCB0eXBlOiBBY2Nlc3NvclR5cGUsIGNvdW50OiBudW1iZXIsIGJpbmFyeVdyaXRlcjogX0JpbmFyeVdyaXRlciwgY29tcG9uZW50VHlwZTogQWNjZXNzb3JDb21wb25lbnRUeXBlKTogbnVtYmVyIHtcclxuICAgICAgICAvLyB3cml0ZSB0aGUgYnVmZmVyXHJcbiAgICAgICAgY29uc3QgYnVmZmVyT2Zmc2V0ID0gYmluYXJ5V3JpdGVyLmdldEJ5dGVPZmZzZXQoKTtcclxuICAgICAgICBzd2l0Y2ggKGNvbXBvbmVudFR5cGUpIHtcclxuICAgICAgICAgICAgY2FzZSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuRkxPQVQ6IHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpICE9IGJ1ZmZlci5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGJpbmFyeVdyaXRlci5zZXRGbG9hdDMyKGJ1ZmZlcltpXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIEFjY2Vzc29yQ29tcG9uZW50VHlwZS5CWVRFOiB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSAhPSBidWZmZXIubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBiaW5hcnlXcml0ZXIuc2V0Qnl0ZShidWZmZXJbaV0gKiAxMjcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuU0hPUlQ6IHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpICE9IGJ1ZmZlci5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGJpbmFyeVdyaXRlci5zZXRJbnQxNihidWZmZXJbaV0gKiAzMjc2Nyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gYnVpbGQgdGhlIGJ1ZmZlciB2aWV3XHJcbiAgICAgICAgY29uc3QgYnY6IElCdWZmZXJWaWV3ID0geyBidWZmZXI6IDAsIGJ5dGVPZmZzZXQ6IGJ1ZmZlck9mZnNldCwgYnl0ZUxlbmd0aDogYnVmZmVyLmxlbmd0aCAqIFZlcnRleEJ1ZmZlci5HZXRUeXBlQnl0ZUxlbmd0aChjb21wb25lbnRUeXBlKSB9O1xyXG4gICAgICAgIGNvbnN0IGJ1ZmZlclZpZXdJbmRleCA9IHRoaXMuX2V4cG9ydGVyLl9idWZmZXJWaWV3cy5sZW5ndGg7XHJcbiAgICAgICAgdGhpcy5fZXhwb3J0ZXIuX2J1ZmZlclZpZXdzLnB1c2goYnYpO1xyXG5cclxuICAgICAgICAvLyBmaW5hbGx5IGJ1aWxkIHRoZSBhY2Nlc3NvclxyXG4gICAgICAgIGNvbnN0IGFjY2Vzc29ySW5kZXggPSB0aGlzLl9leHBvcnRlci5fYWNjZXNzb3JzLmxlbmd0aDtcclxuICAgICAgICBjb25zdCBhY2Nlc3NvcjogSUFjY2Vzc29yID0ge1xyXG4gICAgICAgICAgICBidWZmZXJWaWV3OiBidWZmZXJWaWV3SW5kZXgsXHJcbiAgICAgICAgICAgIGNvbXBvbmVudFR5cGU6IGNvbXBvbmVudFR5cGUsXHJcbiAgICAgICAgICAgIGNvdW50OiBjb3VudCxcclxuICAgICAgICAgICAgdHlwZTogdHlwZSxcclxuICAgICAgICAgICAgbm9ybWFsaXplZDogY29tcG9uZW50VHlwZSA9PSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuQllURSB8fCBjb21wb25lbnRUeXBlID09IEFjY2Vzc29yQ29tcG9uZW50VHlwZS5TSE9SVCxcclxuICAgICAgICB9O1xyXG4gICAgICAgIHRoaXMuX2V4cG9ydGVyLl9hY2Nlc3NvcnMucHVzaChhY2Nlc3Nvcik7XHJcbiAgICAgICAgcmV0dXJuIGFjY2Vzc29ySW5kZXg7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcclxuX0V4cG9ydGVyLlJlZ2lzdGVyRXh0ZW5zaW9uKE5BTUUsIChleHBvcnRlcikgPT4gbmV3IEVYVF9tZXNoX2dwdV9pbnN0YW5jaW5nKGV4cG9ydGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgU3BvdExpZ2h0IH0gZnJvbSBcImNvcmUvTGlnaHRzL3Nwb3RMaWdodFwiO1xyXG5pbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgVmVjdG9yMywgUXVhdGVybmlvbiwgVG1wVmVjdG9ycywgTWF0cml4IH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC52ZWN0b3JcIjtcclxuaW1wb3J0IHsgQ29sb3IzIH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC5jb2xvclwiO1xyXG5pbXBvcnQgeyBMaWdodCB9IGZyb20gXCJjb3JlL0xpZ2h0cy9saWdodFwiO1xyXG5pbXBvcnQgdHlwZSB7IE5vZGUgfSBmcm9tIFwiY29yZS9ub2RlXCI7XHJcbmltcG9ydCB7IFNoYWRvd0xpZ2h0IH0gZnJvbSBcImNvcmUvTGlnaHRzL3NoYWRvd0xpZ2h0XCI7XHJcbmltcG9ydCB0eXBlIHsgSU5vZGUsIElLSFJMaWdodHNQdW5jdHVhbF9MaWdodFJlZmVyZW5jZSwgSUtIUkxpZ2h0c1B1bmN0dWFsX0xpZ2h0LCBJS0hSTGlnaHRzUHVuY3R1YWwgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IEtIUkxpZ2h0c1B1bmN0dWFsX0xpZ2h0VHlwZSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIgfSBmcm9tIFwiLi4vZ2xURkV4cG9ydGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IF9FeHBvcnRlciB9IGZyb20gXCIuLi9nbFRGRXhwb3J0ZXJcIjtcclxuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcImNvcmUvTWlzYy9sb2dnZXJcIjtcclxuaW1wb3J0IHsgX0dMVEZVdGlsaXRpZXMgfSBmcm9tIFwiLi4vZ2xURlV0aWxpdGllc1wiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX2xpZ2h0c19wdW5jdHVhbFwiO1xyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYXN0ZXIvZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbGlnaHRzX3B1bmN0dWFsL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9saWdodHNfcHVuY3R1YWwgaW1wbGVtZW50cyBJR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIge1xyXG4gICAgLyoqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLiAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC4gKi9cclxuICAgIHB1YmxpYyBlbmFibGVkID0gdHJ1ZTtcclxuXHJcbiAgICAvKiogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIHJlcXVpcmVkICovXHJcbiAgICBwdWJsaWMgcmVxdWlyZWQgPSBmYWxzZTtcclxuXHJcbiAgICAvKiogUmVmZXJlbmNlIHRvIHRoZSBnbFRGIGV4cG9ydGVyICovXHJcbiAgICBwcml2YXRlIF9leHBvcnRlcjogX0V4cG9ydGVyO1xyXG5cclxuICAgIHByaXZhdGUgX2xpZ2h0czogSUtIUkxpZ2h0c1B1bmN0dWFsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGV4cG9ydGVyOiBfRXhwb3J0ZXIpIHtcclxuICAgICAgICB0aGlzLl9leHBvcnRlciA9IGV4cG9ydGVyO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9saWdodHMgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGdldCB3YXNVc2VkKCkge1xyXG4gICAgICAgIHJldHVybiAhIXRoaXMuX2xpZ2h0cztcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgb25FeHBvcnRpbmcoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fZXhwb3J0ZXIhLl9nbFRGLmV4dGVuc2lvbnMhW05BTUVdID0gdGhpcy5fbGlnaHRzO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmUgdGhpcyBtZXRob2QgdG8gbW9kaWZ5IHRoZSBkZWZhdWx0IGJlaGF2aW9yIHdoZW4gZXhwb3J0aW5nIGEgbm9kZVxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBleHBvcnRpbmcgdGhlIG5vZGVcclxuICAgICAqIEBwYXJhbSBub2RlIGdsVEYgbm9kZVxyXG4gICAgICogQHBhcmFtIGJhYnlsb25Ob2RlIEJhYnlsb25KUyBub2RlXHJcbiAgICAgKiBAcGFyYW0gbm9kZU1hcCBOb2RlIG1hcHBpbmcgb2YgdW5pcXVlIGlkIHRvIGdsVEYgbm9kZSBpbmRleFxyXG4gICAgICogQHJldHVybnMgbnVsbGFibGUgSU5vZGUgcHJvbWlzZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcG9zdEV4cG9ydE5vZGVBc3luYyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IE51bGxhYmxlPElOb2RlPiwgYmFieWxvbk5vZGU6IE5vZGUsIG5vZGVNYXA6IHsgW2tleTogbnVtYmVyXTogbnVtYmVyIH0pOiBQcm9taXNlPE51bGxhYmxlPElOb2RlPj4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAobm9kZSAmJiBiYWJ5bG9uTm9kZSBpbnN0YW5jZW9mIFNoYWRvd0xpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgbGlnaHQ6IElLSFJMaWdodHNQdW5jdHVhbF9MaWdodDtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBsaWdodFR5cGUgPVxyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25Ob2RlLmdldFR5cGVJRCgpID09IExpZ2h0LkxJR0hUVFlQRUlEX1BPSU5UTElHSFRcclxuICAgICAgICAgICAgICAgICAgICAgICAgPyBLSFJMaWdodHNQdW5jdHVhbF9MaWdodFR5cGUuUE9JTlRcclxuICAgICAgICAgICAgICAgICAgICAgICAgOiBiYWJ5bG9uTm9kZS5nZXRUeXBlSUQoKSA9PSBMaWdodC5MSUdIVFRZUEVJRF9ESVJFQ1RJT05BTExJR0hUXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPyBLSFJMaWdodHNQdW5jdHVhbF9MaWdodFR5cGUuRElSRUNUSU9OQUxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICA6IGJhYnlsb25Ob2RlLmdldFR5cGVJRCgpID09IExpZ2h0LkxJR0hUVFlQRUlEX1NQT1RMSUdIVFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBLSFJMaWdodHNQdW5jdHVhbF9MaWdodFR5cGUuU1BPVFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsO1xyXG4gICAgICAgICAgICAgICAgaWYgKGxpZ2h0VHlwZSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLldhcm4oYCR7Y29udGV4dH06IExpZ2h0ICR7YmFieWxvbk5vZGUubmFtZX0gaXMgbm90IHN1cHBvcnRlZCBpbiAke05BTUV9YCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghYmFieWxvbk5vZGUucG9zaXRpb24uZXF1YWxzVG9GbG9hdHMoMCwgMCwgMCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS50cmFuc2xhdGlvbiA9IGJhYnlsb25Ob2RlLnBvc2l0aW9uLmFzQXJyYXkoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpZ2h0VHlwZSAhPT0gS0hSTGlnaHRzUHVuY3R1YWxfTGlnaHRUeXBlLlBPSU5UKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvY2FsQXhpcyA9IGJhYnlsb25Ob2RlLmRpcmVjdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeWF3ID0gLU1hdGguYXRhbjIobG9jYWxBeGlzLnosIGxvY2FsQXhpcy54KSArIE1hdGguUEkgLyAyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsZW4gPSBNYXRoLnNxcnQobG9jYWxBeGlzLnggKiBsb2NhbEF4aXMueCArIGxvY2FsQXhpcy56ICogbG9jYWxBeGlzLnopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwaXRjaCA9IC1NYXRoLmF0YW4yKGxvY2FsQXhpcy55LCBsZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsaWdodFJvdGF0aW9uUXVhdGVybmlvbiA9IFF1YXRlcm5pb24uUm90YXRpb25ZYXdQaXRjaFJvbGwoeWF3ICsgTWF0aC5QSSwgcGl0Y2gsIDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIVF1YXRlcm5pb24uSXNJZGVudGl0eShsaWdodFJvdGF0aW9uUXVhdGVybmlvbikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUucm90YXRpb24gPSBsaWdodFJvdGF0aW9uUXVhdGVybmlvbi5hc0FycmF5KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTm9kZS5mYWxsb2ZmVHlwZSAhPT0gTGlnaHQuRkFMTE9GRl9HTFRGKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5XYXJuKGAke2NvbnRleHR9OiBMaWdodCBmYWxsb2ZmIGZvciAke2JhYnlsb25Ob2RlLm5hbWV9IGRvZXMgbm90IG1hdGNoIHRoZSAke05BTUV9IHNwZWNpZmljYXRpb24hYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGxpZ2h0ID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBsaWdodFR5cGUsXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWJhYnlsb25Ob2RlLmRpZmZ1c2UuZXF1YWxzKENvbG9yMy5XaGl0ZSgpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsaWdodC5jb2xvciA9IGJhYnlsb25Ob2RlLmRpZmZ1c2UuYXNBcnJheSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk5vZGUuaW50ZW5zaXR5ICE9PSAxLjApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGlnaHQuaW50ZW5zaXR5ID0gYmFieWxvbk5vZGUuaW50ZW5zaXR5O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk5vZGUucmFuZ2UgIT09IE51bWJlci5NQVhfVkFMVUUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGlnaHQucmFuZ2UgPSBiYWJ5bG9uTm9kZS5yYW5nZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChsaWdodFR5cGUgPT09IEtIUkxpZ2h0c1B1bmN0dWFsX0xpZ2h0VHlwZS5TUE9UKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJhYnlsb25TcG90TGlnaHQgPSBiYWJ5bG9uTm9kZSBhcyBTcG90TGlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uU3BvdExpZ2h0LmFuZ2xlICE9PSBNYXRoLlBJIC8gMi4wKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGlnaHQuc3BvdCA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlnaHQuc3BvdCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlnaHQuc3BvdC5vdXRlckNvbmVBbmdsZSA9IGJhYnlsb25TcG90TGlnaHQuYW5nbGUgLyAyLjA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJhYnlsb25TcG90TGlnaHQuaW5uZXJBbmdsZSAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpZ2h0LnNwb3QgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpZ2h0LnNwb3QgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpZ2h0LnNwb3QuaW5uZXJDb25lQW5nbGUgPSBiYWJ5bG9uU3BvdExpZ2h0LmlubmVyQW5nbGUgLyAyLjA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xpZ2h0cyB8fD0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsaWdodHM6IFtdLFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xpZ2h0cy5saWdodHMucHVzaChsaWdodCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxpZ2h0UmVmZXJlbmNlOiBJS0hSTGlnaHRzUHVuY3R1YWxfTGlnaHRSZWZlcmVuY2UgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpZ2h0OiB0aGlzLl9saWdodHMubGlnaHRzLmxlbmd0aCAtIDEsXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQXZvaWQgZHVwbGljYXRpbmcgdGhlIExpZ2h0J3MgcGFyZW50IG5vZGUgaWYgcG9zc2libGUuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFyZW50QmFieWxvbk5vZGUgPSBiYWJ5bG9uTm9kZS5wYXJlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudEJhYnlsb25Ob2RlICYmIHBhcmVudEJhYnlsb25Ob2RlLmdldENoaWxkcmVuKCkubGVuZ3RoID09IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFyZW50Tm9kZSA9IHRoaXMuX2V4cG9ydGVyLl9ub2Rlc1tub2RlTWFwW3BhcmVudEJhYnlsb25Ob2RlLnVuaXF1ZUlkXV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnROb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnRUcmFuc2xhdGlvbiA9IFZlY3RvcjMuRnJvbUFycmF5VG9SZWYocGFyZW50Tm9kZS50cmFuc2xhdGlvbiB8fCBbMCwgMCwgMF0sIDAsIFRtcFZlY3RvcnMuVmVjdG9yM1swXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnRSb3RhdGlvbiA9IFF1YXRlcm5pb24uRnJvbUFycmF5VG9SZWYocGFyZW50Tm9kZS5yb3RhdGlvbiB8fCBbMCwgMCwgMCwgMV0sIDAsIFRtcFZlY3RvcnMuUXVhdGVybmlvblswXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnRTY2FsZSA9IFZlY3RvcjMuRnJvbUFycmF5VG9SZWYocGFyZW50Tm9kZS5zY2FsZSB8fCBbMSwgMSwgMV0sIDAsIFRtcFZlY3RvcnMuVmVjdG9yM1sxXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnRNYXRyaXggPSBNYXRyaXguQ29tcG9zZVRvUmVmKHBhcmVudFNjYWxlLCBwYXJlbnRSb3RhdGlvbiwgcGFyZW50VHJhbnNsYXRpb24sIFRtcFZlY3RvcnMuTWF0cml4WzBdKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0cmFuc2xhdGlvbiA9IFZlY3RvcjMuRnJvbUFycmF5VG9SZWYobm9kZS50cmFuc2xhdGlvbiB8fCBbMCwgMCwgMF0sIDAsIFRtcFZlY3RvcnMuVmVjdG9yM1syXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByb3RhdGlvbiA9IFF1YXRlcm5pb24uRnJvbUFycmF5VG9SZWYobm9kZS5yb3RhdGlvbiB8fCBbMCwgMCwgMCwgMV0sIDAsIFRtcFZlY3RvcnMuUXVhdGVybmlvblsxXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXRyaXggPSBNYXRyaXguQ29tcG9zZVRvUmVmKFZlY3RvcjMuT25lUmVhZE9ubHksIHJvdGF0aW9uLCB0cmFuc2xhdGlvbiwgVG1wVmVjdG9ycy5NYXRyaXhbMV0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE1hdHJpeC5tdWx0aXBseVRvUmVmKG1hdHJpeCwgbWF0cml4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdHJpeC5kZWNvbXBvc2UocGFyZW50U2NhbGUsIHBhcmVudFJvdGF0aW9uLCBwYXJlbnRUcmFuc2xhdGlvbik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudFRyYW5zbGF0aW9uLmVxdWFsc1RvRmxvYXRzKDAsIDAsIDApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHBhcmVudE5vZGUudHJhbnNsYXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUudHJhbnNsYXRpb24gPSBwYXJlbnRUcmFuc2xhdGlvbi5hc0FycmF5KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFF1YXRlcm5pb24uSXNJZGVudGl0eShwYXJlbnRSb3RhdGlvbikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgcGFyZW50Tm9kZS5yb3RhdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5yb3RhdGlvbiA9IHBhcmVudFJvdGF0aW9uLmFzQXJyYXkoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50U2NhbGUuZXF1YWxzVG9GbG9hdHMoMSwgMSwgMSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgcGFyZW50Tm9kZS5zY2FsZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5zY2FsZSA9IHBhcmVudFNjYWxlLmFzQXJyYXkoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlLmV4dGVuc2lvbnMgfHw9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5leHRlbnNpb25zW05BTUVdID0gbGlnaHRSZWZlcmVuY2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90IGV4cG9ydCB0aGUgb3JpZ2luYWwgbm9kZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShudWxsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbm9kZS5leHRlbnNpb25zIHx8PSB7fTtcclxuICAgICAgICAgICAgICAgICAgICBub2RlLmV4dGVuc2lvbnNbTkFNRV0gPSBsaWdodFJlZmVyZW5jZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXNvbHZlKG5vZGUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcblxyXG5fRXhwb3J0ZXIuUmVnaXN0ZXJFeHRlbnNpb24oTkFNRSwgKGV4cG9ydGVyKSA9PiBuZXcgS0hSX2xpZ2h0c19wdW5jdHVhbChleHBvcnRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IElNYXRlcmlhbCwgSUtIUk1hdGVyaWFsc0FuaXNvdHJvcHkgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZFeHBvcnRlckV4dGVuc2lvblYyIH0gZnJvbSBcIi4uL2dsVEZFeHBvcnRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBfRXhwb3J0ZXIgfSBmcm9tIFwiLi4vZ2xURkV4cG9ydGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuaW1wb3J0IHsgUEJSQmFzZU1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJCYXNlTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBCYXNlVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy9iYXNlVGV4dHVyZVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc19hbmlzb3Ryb3B5XCI7XHJcblxyXG4vKipcclxuICogQGludGVybmFsXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfbWF0ZXJpYWxzX2FuaXNvdHJvcHkgaW1wbGVtZW50cyBJR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIge1xyXG4gICAgLyoqIE5hbWUgb2YgdGhpcyBleHRlbnNpb24gKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKiogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkID0gdHJ1ZTtcclxuXHJcbiAgICAvKiogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIHJlcXVpcmVkICovXHJcbiAgICBwdWJsaWMgcmVxdWlyZWQgPSBmYWxzZTtcclxuXHJcbiAgICBwcml2YXRlIF9leHBvcnRlcjogX0V4cG9ydGVyO1xyXG5cclxuICAgIHByaXZhdGUgX3dhc1VzZWQgPSBmYWxzZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihleHBvcnRlcjogX0V4cG9ydGVyKSB7XHJcbiAgICAgICAgdGhpcy5fZXhwb3J0ZXIgPSBleHBvcnRlcjtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHt9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGdldCB3YXNVc2VkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl93YXNVc2VkO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBwb3N0RXhwb3J0TWF0ZXJpYWxBZGRpdGlvbmFsVGV4dHVyZXM/KGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogQmFzZVRleHR1cmVbXSB7XHJcbiAgICAgICAgY29uc3QgYWRkaXRpb25hbFRleHR1cmVzOiBCYXNlVGV4dHVyZVtdID0gW107XHJcbiAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUkJhc2VNYXRlcmlhbCkge1xyXG4gICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsLmFuaXNvdHJvcHkuaXNFbmFibGVkICYmICFiYWJ5bG9uTWF0ZXJpYWwuYW5pc290cm9weS5sZWdhY3kpIHtcclxuICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwuYW5pc290cm9weS50ZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYWRkaXRpb25hbFRleHR1cmVzLnB1c2goYmFieWxvbk1hdGVyaWFsLmFuaXNvdHJvcHkudGV4dHVyZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYWRkaXRpb25hbFRleHR1cmVzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gW107XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHBvc3RFeHBvcnRNYXRlcmlhbEFzeW5jPyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IFByb21pc2U8SU1hdGVyaWFsPiB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJCYXNlTWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgICAgIGlmICghYmFieWxvbk1hdGVyaWFsLmFuaXNvdHJvcHkuaXNFbmFibGVkIHx8IGJhYnlsb25NYXRlcmlhbC5hbmlzb3Ryb3B5LmxlZ2FjeSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX3dhc1VzZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9ucyA9IG5vZGUuZXh0ZW5zaW9ucyB8fCB7fTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBhbmlzb3Ryb3B5VGV4dHVyZUluZm8gPSB0aGlzLl9leHBvcnRlci5fZ2xURk1hdGVyaWFsRXhwb3J0ZXIuX2dldFRleHR1cmVJbmZvKGJhYnlsb25NYXRlcmlhbC5hbmlzb3Ryb3B5LnRleHR1cmUpO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGFuaXNvdHJvcHlJbmZvOiBJS0hSTWF0ZXJpYWxzQW5pc290cm9weSA9IHtcclxuICAgICAgICAgICAgICAgICAgICBhbmlzb3Ryb3B5U3RyZW5ndGg6IGJhYnlsb25NYXRlcmlhbC5hbmlzb3Ryb3B5LmludGVuc2l0eSxcclxuICAgICAgICAgICAgICAgICAgICBhbmlzb3Ryb3B5Um90YXRpb246IGJhYnlsb25NYXRlcmlhbC5hbmlzb3Ryb3B5LmFuZ2xlLFxyXG4gICAgICAgICAgICAgICAgICAgIGFuaXNvdHJvcHlUZXh0dXJlOiBhbmlzb3Ryb3B5VGV4dHVyZUluZm8gPz8gdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgICAgIGhhc1RleHR1cmVzOiAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhbmlzb3Ryb3B5SW5mby5hbmlzb3Ryb3B5VGV4dHVyZSAhPT0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICBub2RlLmV4dGVuc2lvbnNbTkFNRV0gPSBhbmlzb3Ryb3B5SW5mbztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXNvbHZlKG5vZGUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcblxyXG5fRXhwb3J0ZXIuUmVnaXN0ZXJFeHRlbnNpb24oTkFNRSwgKGV4cG9ydGVyKSA9PiBuZXcgS0hSX21hdGVyaWFsc19hbmlzb3Ryb3B5KGV4cG9ydGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgSU1hdGVyaWFsLCBJS0hSTWF0ZXJpYWxzQ2xlYXJjb2F0IH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiB9IGZyb20gXCIuLi9nbFRGRXhwb3J0ZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgX0V4cG9ydGVyIH0gZnJvbSBcIi4uL2dsVEZFeHBvcnRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB7IFBCUkJhc2VNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9QQlIvcGJyQmFzZU1hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgQmFzZVRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvYmFzZVRleHR1cmVcIjtcclxuXHJcbmltcG9ydCB7IFRvb2xzIH0gZnJvbSBcImNvcmUvTWlzYy90b29sc1wiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc19jbGVhcmNvYXRcIjtcclxuXHJcbi8qKlxyXG4gKiBAaW50ZXJuYWxcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfY2xlYXJjb2F0IGltcGxlbWVudHMgSUdMVEZFeHBvcnRlckV4dGVuc2lvblYyIHtcclxuICAgIC8qKiBOYW1lIG9mIHRoaXMgZXh0ZW5zaW9uICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZCA9IHRydWU7XHJcblxyXG4gICAgLyoqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyByZXF1aXJlZCAqL1xyXG4gICAgcHVibGljIHJlcXVpcmVkID0gZmFsc2U7XHJcblxyXG4gICAgcHJpdmF0ZSBfZXhwb3J0ZXI6IF9FeHBvcnRlcjtcclxuXHJcbiAgICBwcml2YXRlIF93YXNVc2VkID0gZmFsc2U7XHJcblxyXG4gICAgY29uc3RydWN0b3IoZXhwb3J0ZXI6IF9FeHBvcnRlcikge1xyXG4gICAgICAgIHRoaXMuX2V4cG9ydGVyID0gZXhwb3J0ZXI7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7fVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBnZXQgd2FzVXNlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fd2FzVXNlZDtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcG9zdEV4cG9ydE1hdGVyaWFsQWRkaXRpb25hbFRleHR1cmVzPyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IEJhc2VUZXh0dXJlW10ge1xyXG4gICAgICAgIGNvbnN0IGFkZGl0aW9uYWxUZXh0dXJlczogQmFzZVRleHR1cmVbXSA9IFtdO1xyXG4gICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJCYXNlTWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbC5jbGVhckNvYXQuaXNFbmFibGVkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC50ZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYWRkaXRpb25hbFRleHR1cmVzLnB1c2goYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC50ZXh0dXJlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICghYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC51c2VSb3VnaG5lc3NGcm9tTWFpblRleHR1cmUgJiYgYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC50ZXh0dXJlUm91Z2huZXNzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYWRkaXRpb25hbFRleHR1cmVzLnB1c2goYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC50ZXh0dXJlUm91Z2huZXNzKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwuY2xlYXJDb2F0LmJ1bXBUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYWRkaXRpb25hbFRleHR1cmVzLnB1c2goYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC5idW1wVGV4dHVyZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYWRkaXRpb25hbFRleHR1cmVzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gW107XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHBvc3RFeHBvcnRNYXRlcmlhbEFzeW5jPyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IFByb21pc2U8SU1hdGVyaWFsPiB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJCYXNlTWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgICAgIGlmICghYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC5pc0VuYWJsZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl93YXNVc2VkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBub2RlLmV4dGVuc2lvbnMgPSBub2RlLmV4dGVuc2lvbnMgfHwge307XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgY2xlYXJDb2F0VGV4dHVyZUluZm8gPSB0aGlzLl9leHBvcnRlci5fZ2xURk1hdGVyaWFsRXhwb3J0ZXIuX2dldFRleHR1cmVJbmZvKGJhYnlsb25NYXRlcmlhbC5jbGVhckNvYXQudGV4dHVyZSk7XHJcbiAgICAgICAgICAgICAgICBsZXQgY2xlYXJDb2F0VGV4dHVyZVJvdWdobmVzc0luZm87XHJcbiAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC51c2VSb3VnaG5lc3NGcm9tTWFpblRleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBjbGVhckNvYXRUZXh0dXJlUm91Z2huZXNzSW5mbyA9IHRoaXMuX2V4cG9ydGVyLl9nbFRGTWF0ZXJpYWxFeHBvcnRlci5fZ2V0VGV4dHVyZUluZm8oYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC50ZXh0dXJlKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2xlYXJDb2F0VGV4dHVyZVJvdWdobmVzc0luZm8gPSB0aGlzLl9leHBvcnRlci5fZ2xURk1hdGVyaWFsRXhwb3J0ZXIuX2dldFRleHR1cmVJbmZvKGJhYnlsb25NYXRlcmlhbC5jbGVhckNvYXQudGV4dHVyZVJvdWdobmVzcyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbC5jbGVhckNvYXQuaXNUaW50RW5hYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIFRvb2xzLldhcm4oYENsZWFyIENvbG9yIHRpbnQgaXMgbm90IHN1cHBvcnRlZCBmb3IgZ2xURiBleHBvcnQuIElnbm9yaW5nIGZvcjogJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX1gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC5yZW1hcEYwT25JbnRlcmZhY2VDaGFuZ2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBUb29scy5XYXJuKGBDbGVhciBDb2xvciBGMCByZW1hcHBpbmcgaXMgbm90IHN1cHBvcnRlZCBmb3IgZ2xURiBleHBvcnQuIElnbm9yaW5nIGZvcjogJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX1gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBjbGVhckNvYXROb3JtYWxUZXh0dXJlSW5mbyA9IHRoaXMuX2V4cG9ydGVyLl9nbFRGTWF0ZXJpYWxFeHBvcnRlci5fZ2V0VGV4dHVyZUluZm8oYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC5idW1wVGV4dHVyZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgY2xlYXJDb2F0SW5mbzogSUtIUk1hdGVyaWFsc0NsZWFyY29hdCA9IHtcclxuICAgICAgICAgICAgICAgICAgICBjbGVhcmNvYXRGYWN0b3I6IGJhYnlsb25NYXRlcmlhbC5jbGVhckNvYXQuaW50ZW5zaXR5LFxyXG4gICAgICAgICAgICAgICAgICAgIGNsZWFyY29hdFRleHR1cmU6IGNsZWFyQ29hdFRleHR1cmVJbmZvID8/IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgICAgICAgICBjbGVhcmNvYXRSb3VnaG5lc3NGYWN0b3I6IGJhYnlsb25NYXRlcmlhbC5jbGVhckNvYXQucm91Z2huZXNzLFxyXG4gICAgICAgICAgICAgICAgICAgIGNsZWFyY29hdFJvdWdobmVzc1RleHR1cmU6IGNsZWFyQ29hdFRleHR1cmVSb3VnaG5lc3NJbmZvID8/IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgICAgICAgICBjbGVhcmNvYXROb3JtYWxUZXh0dXJlOiBjbGVhckNvYXROb3JtYWxUZXh0dXJlSW5mbyA/PyB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICAgICAgaGFzVGV4dHVyZXM6ICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNsZWFyQ29hdEluZm8uY2xlYXJjb2F0VGV4dHVyZSAhPT0gbnVsbCB8fCBjbGVhckNvYXRJbmZvLmNsZWFyY29hdFJvdWdobmVzc1RleHR1cmUgIT09IG51bGwgfHwgY2xlYXJDb2F0SW5mby5jbGVhcmNvYXRSb3VnaG5lc3NUZXh0dXJlICE9PSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9uc1tOQU1FXSA9IGNsZWFyQ29hdEluZm87XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmVzb2x2ZShub2RlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxuX0V4cG9ydGVyLlJlZ2lzdGVyRXh0ZW5zaW9uKE5BTUUsIChleHBvcnRlcikgPT4gbmV3IEtIUl9tYXRlcmlhbHNfY2xlYXJjb2F0KGV4cG9ydGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgSU1hdGVyaWFsLCBJS0hSTWF0ZXJpYWxzRGlmZnVzZVRyYW5zbWlzc2lvbiB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIgfSBmcm9tIFwiLi4vZ2xURkV4cG9ydGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IF9FeHBvcnRlciB9IGZyb20gXCIuLi9nbFRGRXhwb3J0ZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5pbXBvcnQgeyBQQlJNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9QQlIvcGJyTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBCYXNlVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy9iYXNlVGV4dHVyZVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc19kaWZmdXNlX3RyYW5zbWlzc2lvblwiO1xyXG5cclxuLyoqXHJcbiAqIFtQcm9wb3NlZCBTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvcHVsbC8xODI1KVxyXG4gKiAhISEgRXhwZXJpbWVudGFsIEV4dGVuc2lvbiBTdWJqZWN0IHRvIENoYW5nZXMgISEhXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfbWF0ZXJpYWxzX2RpZmZ1c2VfdHJhbnNtaXNzaW9uIGltcGxlbWVudHMgSUdMVEZFeHBvcnRlckV4dGVuc2lvblYyIHtcclxuICAgIC8qKiBOYW1lIG9mIHRoaXMgZXh0ZW5zaW9uICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZCA9IHRydWU7XHJcblxyXG4gICAgLyoqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyByZXF1aXJlZCAqL1xyXG4gICAgcHVibGljIHJlcXVpcmVkID0gZmFsc2U7XHJcblxyXG4gICAgcHJpdmF0ZSBfZXhwb3J0ZXI6IF9FeHBvcnRlcjtcclxuXHJcbiAgICBwcml2YXRlIF93YXNVc2VkID0gZmFsc2U7XHJcblxyXG4gICAgY29uc3RydWN0b3IoZXhwb3J0ZXI6IF9FeHBvcnRlcikge1xyXG4gICAgICAgIHRoaXMuX2V4cG9ydGVyID0gZXhwb3J0ZXI7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7fVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBnZXQgd2FzVXNlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fd2FzVXNlZDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFmdGVyIGV4cG9ydGluZyBhIG1hdGVyaWFsLCBkZWFsIHdpdGggYWRkaXRpb25hbCB0ZXh0dXJlc1xyXG4gICAgICogQHBhcmFtIGNvbnRleHQgR0xURiBjb250ZXh0IG9mIHRoZSBtYXRlcmlhbFxyXG4gICAgICogQHBhcmFtIG5vZGUgZXhwb3J0ZWQgR0xURiBub2RlXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk1hdGVyaWFsIGNvcnJlc3BvbmRpbmcgYmFieWxvbiBtYXRlcmlhbFxyXG4gICAgICogQHJldHVybnMgYXJyYXkgb2YgYWRkaXRpb25hbCB0ZXh0dXJlcyB0byBleHBvcnRcclxuICAgICAqL1xyXG4gICAgcHVibGljIHBvc3RFeHBvcnRNYXRlcmlhbEFkZGl0aW9uYWxUZXh0dXJlcz8oY29udGV4dDogc3RyaW5nLCBub2RlOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBCYXNlVGV4dHVyZVtdIHtcclxuICAgICAgICBjb25zdCBhZGRpdGlvbmFsVGV4dHVyZXM6IEJhc2VUZXh0dXJlW10gPSBbXTtcclxuXHJcbiAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0V4dGVuc2lvbkVuYWJsZWQoYmFieWxvbk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbC5zdWJTdXJmYWNlLnRoaWNrbmVzc1RleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBhZGRpdGlvbmFsVGV4dHVyZXMucHVzaChiYWJ5bG9uTWF0ZXJpYWwuc3ViU3VyZmFjZS50aGlja25lc3NUZXh0dXJlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBhZGRpdGlvbmFsVGV4dHVyZXM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBhZGRpdGlvbmFsVGV4dHVyZXM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfaXNFeHRlbnNpb25FbmFibGVkKG1hdDogUEJSTWF0ZXJpYWwpOiBib29sZWFuIHtcclxuICAgICAgICAvLyBUaGlzIGV4dGVuc2lvbiBtdXN0IG5vdCBiZSB1c2VkIG9uIGEgbWF0ZXJpYWwgdGhhdCBhbHNvIHVzZXMgS0hSX21hdGVyaWFsc191bmxpdFxyXG4gICAgICAgIGlmIChtYXQudW5saXQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBzdWJzID0gbWF0LnN1YlN1cmZhY2U7XHJcbiAgICAgICAgaWYgKCFzdWJzLmlzVHJhbnNsdWNlbmN5RW5hYmxlZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgICAhbWF0LnVubGl0ICYmXHJcbiAgICAgICAgICAgICFzdWJzLnVzZUFsYmVkb1RvVGludFRyYW5zbHVjZW5jeSAmJlxyXG4gICAgICAgICAgICBzdWJzLnVzZUdsdGZTdHlsZVRleHR1cmVzICYmXHJcbiAgICAgICAgICAgIHN1YnMudm9sdW1lSW5kZXhPZlJlZnJhY3Rpb24gPT09IDEgJiZcclxuICAgICAgICAgICAgc3Vicy5taW5pbXVtVGhpY2tuZXNzID09PSAwICYmXHJcbiAgICAgICAgICAgIHN1YnMubWF4aW11bVRoaWNrbmVzcyA9PT0gMFxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfaGFzVGV4dHVyZXNFeHRlbnNpb24obWF0OiBQQlJNYXRlcmlhbCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiBtYXQuc3ViU3VyZmFjZS50cmFuc2x1Y2VuY3lJbnRlbnNpdHlUZXh0dXJlICE9IG51bGwgfHwgbWF0LnN1YlN1cmZhY2UudHJhbnNsdWNlbmN5Q29sb3JUZXh0dXJlICE9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZnRlciBleHBvcnRpbmcgYSBtYXRlcmlhbFxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgR0xURiBjb250ZXh0IG9mIHRoZSBtYXRlcmlhbFxyXG4gICAgICogQHBhcmFtIG5vZGUgZXhwb3J0ZWQgR0xURiBub2RlXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk1hdGVyaWFsIGNvcnJlc3BvbmRpbmcgYmFieWxvbiBtYXRlcmlhbFxyXG4gICAgICogQHJldHVybnMgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHVwZGF0ZWQgbm9kZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcG9zdEV4cG9ydE1hdGVyaWFsQXN5bmM/KGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTxJTWF0ZXJpYWw+IHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcclxuICAgICAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsICYmIHRoaXMuX2lzRXh0ZW5zaW9uRW5hYmxlZChiYWJ5bG9uTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl93YXNVc2VkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBzdWJzID0gYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2U7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgZGlmZnVzZVRyYW5zbWlzc2lvbkZhY3RvciA9IHN1YnMudHJhbnNsdWNlbmN5SW50ZW5zaXR5ID09IDEgPyB1bmRlZmluZWQgOiBzdWJzLnRyYW5zbHVjZW5jeUludGVuc2l0eTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGRpZmZ1c2VUcmFuc21pc3Npb25UZXh0dXJlID0gdGhpcy5fZXhwb3J0ZXIuX2dsVEZNYXRlcmlhbEV4cG9ydGVyLl9nZXRUZXh0dXJlSW5mbyhzdWJzLnRyYW5zbHVjZW5jeUludGVuc2l0eVRleHR1cmUpID8/IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGRpZmZ1c2VUcmFuc21pc3Npb25Db2xvckZhY3RvciA9ICFzdWJzLnRyYW5zbHVjZW5jeUNvbG9yIHx8IHN1YnMudHJhbnNsdWNlbmN5Q29sb3IuZXF1YWxzRmxvYXRzKDEuMCwgMS4wLCAxLjApID8gdW5kZWZpbmVkIDogc3Vicy50cmFuc2x1Y2VuY3lDb2xvci5hc0FycmF5KCk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBkaWZmdXNlVHJhbnNtaXNzaW9uQ29sb3JUZXh0dXJlID0gdGhpcy5fZXhwb3J0ZXIuX2dsVEZNYXRlcmlhbEV4cG9ydGVyLl9nZXRUZXh0dXJlSW5mbyhzdWJzLnRyYW5zbHVjZW5jeUNvbG9yVGV4dHVyZSkgPz8gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGRpZmZ1c2VUcmFuc21pc3Npb25JbmZvOiBJS0hSTWF0ZXJpYWxzRGlmZnVzZVRyYW5zbWlzc2lvbiA9IHtcclxuICAgICAgICAgICAgICAgICAgICBkaWZmdXNlVHJhbnNtaXNzaW9uRmFjdG9yLFxyXG4gICAgICAgICAgICAgICAgICAgIGRpZmZ1c2VUcmFuc21pc3Npb25UZXh0dXJlLFxyXG4gICAgICAgICAgICAgICAgICAgIGRpZmZ1c2VUcmFuc21pc3Npb25Db2xvckZhY3RvcixcclxuICAgICAgICAgICAgICAgICAgICBkaWZmdXNlVHJhbnNtaXNzaW9uQ29sb3JUZXh0dXJlLFxyXG4gICAgICAgICAgICAgICAgICAgIGhhc1RleHR1cmVzOiAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYXNUZXh0dXJlc0V4dGVuc2lvbihiYWJ5bG9uTWF0ZXJpYWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgbm9kZS5leHRlbnNpb25zID0gbm9kZS5leHRlbnNpb25zIHx8IHt9O1xyXG4gICAgICAgICAgICAgICAgbm9kZS5leHRlbnNpb25zW05BTUVdID0gZGlmZnVzZVRyYW5zbWlzc2lvbkluZm87XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmVzb2x2ZShub2RlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxuX0V4cG9ydGVyLlJlZ2lzdGVyRXh0ZW5zaW9uKE5BTUUsIChleHBvcnRlcikgPT4gbmV3IEtIUl9tYXRlcmlhbHNfZGlmZnVzZV90cmFuc21pc3Npb24oZXhwb3J0ZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBJTWF0ZXJpYWwsIElLSFJNYXRlcmlhbHNEaXNwZXJzaW9uIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiB9IGZyb20gXCIuLi9nbFRGRXhwb3J0ZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgX0V4cG9ydGVyIH0gZnJvbSBcIi4uL2dsVEZFeHBvcnRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc19kaXNwZXJzaW9uXCI7XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iLzg3YmQ2NGE3ZjVlMjNjODRiNmFlZjJlNjA4MjA2OTU4M2VkMGRkYjQvZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbWF0ZXJpYWxzX2Rpc3BlcnNpb24vUkVBRE1FLm1kKVxyXG4gKiBAZXhwZXJpbWVudGFsXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfbWF0ZXJpYWxzX2Rpc3BlcnNpb24gaW1wbGVtZW50cyBJR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIge1xyXG4gICAgLyoqIE5hbWUgb2YgdGhpcyBleHRlbnNpb24gKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKiogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkID0gdHJ1ZTtcclxuXHJcbiAgICAvKiogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIHJlcXVpcmVkICovXHJcbiAgICBwdWJsaWMgcmVxdWlyZWQgPSBmYWxzZTtcclxuXHJcbiAgICBwcml2YXRlIF93YXNVc2VkID0gZmFsc2U7XHJcblxyXG4gICAgLyoqIENvbnN0cnVjdG9yICovXHJcbiAgICBjb25zdHJ1Y3RvcigpIHt9XHJcblxyXG4gICAgLyoqIERpc3Bvc2UgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge31cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZ2V0IHdhc1VzZWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3dhc1VzZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfaXNFeHRlbnNpb25FbmFibGVkKG1hdDogUEJSTWF0ZXJpYWwpOiBib29sZWFuIHtcclxuICAgICAgICAvLyBUaGlzIGV4dGVuc2lvbiBtdXN0IG5vdCBiZSB1c2VkIG9uIGEgbWF0ZXJpYWwgdGhhdCBhbHNvIHVzZXMgS0hSX21hdGVyaWFsc191bmxpdFxyXG4gICAgICAgIGlmIChtYXQudW5saXQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBzdWJzID0gbWF0LnN1YlN1cmZhY2U7XHJcbiAgICAgICAgLy8gdGhpcyBleHRlbnNpb24gcmVxdWlyZXMgcmVmcmFjdGlvbiB0byBiZSBlbmFibGVkLlxyXG4gICAgICAgIGlmICghc3Vicy5pc1JlZnJhY3Rpb25FbmFibGVkICYmICFzdWJzLmlzRGlzcGVyc2lvbkVuYWJsZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFmdGVyIGV4cG9ydGluZyBhIG1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBHTFRGIGNvbnRleHQgb2YgdGhlIG1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gbm9kZSBleHBvcnRlZCBHTFRGIG5vZGVcclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uTWF0ZXJpYWwgY29ycmVzcG9uZGluZyBiYWJ5bG9uIG1hdGVyaWFsXHJcbiAgICAgKiBAcmV0dXJucyBwcm9taXNlLCByZXNvbHZlcyB3aXRoIHRoZSBtYXRlcmlhbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcG9zdEV4cG9ydE1hdGVyaWFsQXN5bmM/KGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTxJTWF0ZXJpYWw+IHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcclxuICAgICAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsICYmIHRoaXMuX2lzRXh0ZW5zaW9uRW5hYmxlZChiYWJ5bG9uTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl93YXNVc2VkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBzdWJzID0gYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2U7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBkaXNwZXJzaW9uID0gc3Vicy5kaXNwZXJzaW9uO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGRpc3BlcnNpb25JbmZvOiBJS0hSTWF0ZXJpYWxzRGlzcGVyc2lvbiA9IHtcclxuICAgICAgICAgICAgICAgICAgICBkaXNwZXJzaW9uOiBkaXNwZXJzaW9uLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9ucyA9IG5vZGUuZXh0ZW5zaW9ucyB8fCB7fTtcclxuICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9uc1tOQU1FXSA9IGRpc3BlcnNpb25JbmZvO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJlc29sdmUobm9kZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbl9FeHBvcnRlci5SZWdpc3RlckV4dGVuc2lvbihOQU1FLCAoKSA9PiBuZXcgS0hSX21hdGVyaWFsc19kaXNwZXJzaW9uKCkpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiB9IGZyb20gXCIuLi9nbFRGRXhwb3J0ZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgX0V4cG9ydGVyIH0gZnJvbSBcIi4uL2dsVEZFeHBvcnRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IElNYXRlcmlhbCwgSUtIUk1hdGVyaWFsc0VtaXNzaXZlU3RyZW5ndGggfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWF0ZXJpYWxzX2VtaXNzaXZlX3N0cmVuZ3RoXCI7XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbWF0ZXJpYWxzX2VtaXNzaXZlX3N0cmVuZ3RoL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfZW1pc3NpdmVfc3RyZW5ndGggaW1wbGVtZW50cyBJR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIge1xyXG4gICAgLyoqIE5hbWUgb2YgdGhpcyBleHRlbnNpb24gKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKiogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkID0gdHJ1ZTtcclxuXHJcbiAgICAvKiogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIHJlcXVpcmVkICovXHJcbiAgICBwdWJsaWMgcmVxdWlyZWQgPSBmYWxzZTtcclxuXHJcbiAgICBwcml2YXRlIF93YXNVc2VkID0gZmFsc2U7XHJcblxyXG4gICAgLyoqIERpc3Bvc2UgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge31cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZ2V0IHdhc1VzZWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3dhc1VzZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZnRlciBleHBvcnRpbmcgYSBtYXRlcmlhbFxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgR0xURiBjb250ZXh0IG9mIHRoZSBtYXRlcmlhbFxyXG4gICAgICogQHBhcmFtIG5vZGUgZXhwb3J0ZWQgR0xURiBub2RlXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk1hdGVyaWFsIGNvcnJlc3BvbmRpbmcgYmFieWxvbiBtYXRlcmlhbFxyXG4gICAgICogQHJldHVybnMgcHJvbWlzZSwgcmVzb2x2ZXMgd2l0aCB0aGUgbWF0ZXJpYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIHBvc3RFeHBvcnRNYXRlcmlhbEFzeW5jKGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTxJTWF0ZXJpYWw+IHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcclxuICAgICAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShub2RlKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgZW1pc3NpdmVDb2xvciA9IGJhYnlsb25NYXRlcmlhbC5lbWlzc2l2ZUNvbG9yLmFzQXJyYXkoKTtcclxuICAgICAgICAgICAgY29uc3QgdGVtcEVtaXNzaXZlU3RyZW5ndGggPSBNYXRoLm1heCguLi5lbWlzc2l2ZUNvbG9yKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0ZW1wRW1pc3NpdmVTdHJlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3dhc1VzZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9ucyB8fD0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgZW1pc3NpdmVTdHJlbmd0aEluZm86IElLSFJNYXRlcmlhbHNFbWlzc2l2ZVN0cmVuZ3RoID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIGVtaXNzaXZlU3RyZW5ndGg6IHRlbXBFbWlzc2l2ZVN0cmVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBOb3JtYWxpemUgZWFjaCB2YWx1ZSBvZiB0aGUgZW1pc3NpdmUgZmFjdG9yIHRvIGhhdmUgYSBtYXggdmFsdWUgb2YgMVxyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3RW1pc3NpdmVGYWN0b3IgPSBiYWJ5bG9uTWF0ZXJpYWwuZW1pc3NpdmVDb2xvci5zY2FsZSgxIC8gZW1pc3NpdmVTdHJlbmd0aEluZm8uZW1pc3NpdmVTdHJlbmd0aCk7XHJcblxyXG4gICAgICAgICAgICAgICAgbm9kZS5lbWlzc2l2ZUZhY3RvciA9IG5ld0VtaXNzaXZlRmFjdG9yLmFzQXJyYXkoKTtcclxuICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9uc1tOQU1FXSA9IGVtaXNzaXZlU3RyZW5ndGhJbmZvO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShub2RlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxuX0V4cG9ydGVyLlJlZ2lzdGVyRXh0ZW5zaW9uKE5BTUUsIChleHBvcnRlcikgPT4gbmV3IEtIUl9tYXRlcmlhbHNfZW1pc3NpdmVfc3RyZW5ndGgoKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgSU1hdGVyaWFsLCBJS0hSTWF0ZXJpYWxzSW9yIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiB9IGZyb20gXCIuLi9nbFRGRXhwb3J0ZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgX0V4cG9ydGVyIH0gZnJvbSBcIi4uL2dsVEZFeHBvcnRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc19pb3JcIjtcclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl9tYXRlcmlhbHNfaW9yL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfaW9yIGltcGxlbWVudHMgSUdMVEZFeHBvcnRlckV4dGVuc2lvblYyIHtcclxuICAgIC8qKiBOYW1lIG9mIHRoaXMgZXh0ZW5zaW9uICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZCA9IHRydWU7XHJcblxyXG4gICAgLyoqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyByZXF1aXJlZCAqL1xyXG4gICAgcHVibGljIHJlcXVpcmVkID0gZmFsc2U7XHJcblxyXG4gICAgcHJpdmF0ZSBfd2FzVXNlZCA9IGZhbHNlO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKCkge31cclxuXHJcbiAgICAvKiogRGlzcG9zZSAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7fVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBnZXQgd2FzVXNlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fd2FzVXNlZDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9pc0V4dGVuc2lvbkVuYWJsZWQobWF0OiBQQlJNYXRlcmlhbCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIC8vIFRoaXMgZXh0ZW5zaW9uIG11c3Qgbm90IGJlIHVzZWQgb24gYSBtYXRlcmlhbCB0aGF0IGFsc28gdXNlcyBLSFJfbWF0ZXJpYWxzX3VubGl0XHJcbiAgICAgICAgaWYgKG1hdC51bmxpdCkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBtYXQuaW5kZXhPZlJlZnJhY3Rpb24gIT0gdW5kZWZpbmVkICYmIG1hdC5pbmRleE9mUmVmcmFjdGlvbiAhPSAxLjU7IC8vIDEuNSBpcyBub3JtYXRpdmUgZGVmYXVsdCB2YWx1ZS5cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFmdGVyIGV4cG9ydGluZyBhIG1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBHTFRGIGNvbnRleHQgb2YgdGhlIG1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gbm9kZSBleHBvcnRlZCBHTFRGIG5vZGVcclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uTWF0ZXJpYWwgY29ycmVzcG9uZGluZyBiYWJ5bG9uIG1hdGVyaWFsXHJcbiAgICAgKiBAcmV0dXJucyBwcm9taXNlLCByZXNvbHZlcyB3aXRoIHRoZSBtYXRlcmlhbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcG9zdEV4cG9ydE1hdGVyaWFsQXN5bmM/KGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTxJTWF0ZXJpYWw+IHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcclxuICAgICAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsICYmIHRoaXMuX2lzRXh0ZW5zaW9uRW5hYmxlZChiYWJ5bG9uTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl93YXNVc2VkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBpb3JJbmZvOiBJS0hSTWF0ZXJpYWxzSW9yID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlvcjogYmFieWxvbk1hdGVyaWFsLmluZGV4T2ZSZWZyYWN0aW9uLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9ucyA9IG5vZGUuZXh0ZW5zaW9ucyB8fCB7fTtcclxuICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9uc1tOQU1FXSA9IGlvckluZm87XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmVzb2x2ZShub2RlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xyXG5fRXhwb3J0ZXIuUmVnaXN0ZXJFeHRlbnNpb24oTkFNRSwgKGV4cG9ydGVyKSA9PiBuZXcgS0hSX21hdGVyaWFsc19pb3IoKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgSU1hdGVyaWFsLCBJS0hSTWF0ZXJpYWxzSXJpZGVzY2VuY2UgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZFeHBvcnRlckV4dGVuc2lvblYyIH0gZnJvbSBcIi4uL2dsVEZFeHBvcnRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBfRXhwb3J0ZXIgfSBmcm9tIFwiLi4vZ2xURkV4cG9ydGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuaW1wb3J0IHsgUEJSQmFzZU1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJCYXNlTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBCYXNlVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy9iYXNlVGV4dHVyZVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc19pcmlkZXNjZW5jZVwiO1xyXG5cclxuLyoqXHJcbiAqIEBpbnRlcm5hbFxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21hdGVyaWFsc19pcmlkZXNjZW5jZSBpbXBsZW1lbnRzIElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiB7XHJcbiAgICAvKiogTmFtZSBvZiB0aGlzIGV4dGVuc2lvbiAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZCAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQgPSB0cnVlO1xyXG5cclxuICAgIC8qKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgcmVxdWlyZWQgKi9cclxuICAgIHB1YmxpYyByZXF1aXJlZCA9IGZhbHNlO1xyXG5cclxuICAgIHByaXZhdGUgX2V4cG9ydGVyOiBfRXhwb3J0ZXI7XHJcblxyXG4gICAgcHJpdmF0ZSBfd2FzVXNlZCA9IGZhbHNlO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGV4cG9ydGVyOiBfRXhwb3J0ZXIpIHtcclxuICAgICAgICB0aGlzLl9leHBvcnRlciA9IGV4cG9ydGVyO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge31cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZ2V0IHdhc1VzZWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3dhc1VzZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHBvc3RFeHBvcnRNYXRlcmlhbEFkZGl0aW9uYWxUZXh0dXJlcz8oY29udGV4dDogc3RyaW5nLCBub2RlOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBCYXNlVGV4dHVyZVtdIHtcclxuICAgICAgICBjb25zdCBhZGRpdGlvbmFsVGV4dHVyZXM6IEJhc2VUZXh0dXJlW10gPSBbXTtcclxuICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSQmFzZU1hdGVyaWFsKSB7XHJcbiAgICAgICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwuaXJpZGVzY2VuY2UuaXNFbmFibGVkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsLmlyaWRlc2NlbmNlLnRleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBhZGRpdGlvbmFsVGV4dHVyZXMucHVzaChiYWJ5bG9uTWF0ZXJpYWwuaXJpZGVzY2VuY2UudGV4dHVyZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsLmlyaWRlc2NlbmNlLnRoaWNrbmVzc1RleHR1cmUgJiYgYmFieWxvbk1hdGVyaWFsLmlyaWRlc2NlbmNlLnRoaWNrbmVzc1RleHR1cmUgIT09IGJhYnlsb25NYXRlcmlhbC5pcmlkZXNjZW5jZS50ZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYWRkaXRpb25hbFRleHR1cmVzLnB1c2goYmFieWxvbk1hdGVyaWFsLmlyaWRlc2NlbmNlLnRoaWNrbmVzc1RleHR1cmUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGFkZGl0aW9uYWxUZXh0dXJlcztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBwb3N0RXhwb3J0TWF0ZXJpYWxBc3luYz8oY29udGV4dDogc3RyaW5nLCBub2RlOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBQcm9taXNlPElNYXRlcmlhbD4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSQmFzZU1hdGVyaWFsKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWJhYnlsb25NYXRlcmlhbC5pcmlkZXNjZW5jZS5pc0VuYWJsZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl93YXNVc2VkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBub2RlLmV4dGVuc2lvbnMgPSBub2RlLmV4dGVuc2lvbnMgfHwge307XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgaXJpZGVzY2VuY2VUZXh0dXJlSW5mbyA9IHRoaXMuX2V4cG9ydGVyLl9nbFRGTWF0ZXJpYWxFeHBvcnRlci5fZ2V0VGV4dHVyZUluZm8oYmFieWxvbk1hdGVyaWFsLmlyaWRlc2NlbmNlLnRleHR1cmUpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaXJpZGVzY2VuY2VUaGlja25lc3NUZXh0dXJlSW5mbyA9IHRoaXMuX2V4cG9ydGVyLl9nbFRGTWF0ZXJpYWxFeHBvcnRlci5fZ2V0VGV4dHVyZUluZm8oYmFieWxvbk1hdGVyaWFsLmlyaWRlc2NlbmNlLnRoaWNrbmVzc1RleHR1cmUpO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGlyaWRlc2NlbmNlSW5mbzogSUtIUk1hdGVyaWFsc0lyaWRlc2NlbmNlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlyaWRlc2NlbmNlRmFjdG9yOiBiYWJ5bG9uTWF0ZXJpYWwuaXJpZGVzY2VuY2UuaW50ZW5zaXR5LFxyXG4gICAgICAgICAgICAgICAgICAgIGlyaWRlc2NlbmNlSW9yOiBiYWJ5bG9uTWF0ZXJpYWwuaXJpZGVzY2VuY2UuaW5kZXhPZlJlZnJhY3Rpb24sXHJcbiAgICAgICAgICAgICAgICAgICAgaXJpZGVzY2VuY2VUaGlja25lc3NNaW5pbXVtOiBiYWJ5bG9uTWF0ZXJpYWwuaXJpZGVzY2VuY2UubWluaW11bVRoaWNrbmVzcyxcclxuICAgICAgICAgICAgICAgICAgICBpcmlkZXNjZW5jZVRoaWNrbmVzc01heGltdW06IGJhYnlsb25NYXRlcmlhbC5pcmlkZXNjZW5jZS5tYXhpbXVtVGhpY2tuZXNzLFxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpcmlkZXNjZW5jZVRleHR1cmU6IGlyaWRlc2NlbmNlVGV4dHVyZUluZm8gPz8gdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgICAgIGlyaWRlc2NlbmNlVGhpY2tuZXNzVGV4dHVyZTogaXJpZGVzY2VuY2VUaGlja25lc3NUZXh0dXJlSW5mbyA/PyB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICAgICAgaGFzVGV4dHVyZXM6ICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlyaWRlc2NlbmNlSW5mby5pcmlkZXNjZW5jZVRleHR1cmUgIT09IG51bGwgfHwgaXJpZGVzY2VuY2VJbmZvLmlyaWRlc2NlbmNlVGhpY2tuZXNzVGV4dHVyZSAhPT0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICBub2RlLmV4dGVuc2lvbnNbTkFNRV0gPSBpcmlkZXNjZW5jZUluZm87XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmVzb2x2ZShub2RlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxuX0V4cG9ydGVyLlJlZ2lzdGVyRXh0ZW5zaW9uKE5BTUUsIChleHBvcnRlcikgPT4gbmV3IEtIUl9tYXRlcmlhbHNfaXJpZGVzY2VuY2UoZXhwb3J0ZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBJTWF0ZXJpYWwsIElLSFJNYXRlcmlhbHNTaGVlbiB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIgfSBmcm9tIFwiLi4vZ2xURkV4cG9ydGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IF9FeHBvcnRlciB9IGZyb20gXCIuLi9nbFRGRXhwb3J0ZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5pbXBvcnQgeyBQQlJNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9QQlIvcGJyTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBCYXNlVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy9iYXNlVGV4dHVyZVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc19zaGVlblwiO1xyXG5cclxuLyoqXHJcbiAqIEBpbnRlcm5hbFxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21hdGVyaWFsc19zaGVlbiBpbXBsZW1lbnRzIElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiB7XHJcbiAgICAvKiogTmFtZSBvZiB0aGlzIGV4dGVuc2lvbiAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZCAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQgPSB0cnVlO1xyXG5cclxuICAgIC8qKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgcmVxdWlyZWQgKi9cclxuICAgIHB1YmxpYyByZXF1aXJlZCA9IGZhbHNlO1xyXG5cclxuICAgIHByaXZhdGUgX3dhc1VzZWQgPSBmYWxzZTtcclxuXHJcbiAgICBwcml2YXRlIF9leHBvcnRlcjogX0V4cG9ydGVyO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGV4cG9ydGVyOiBfRXhwb3J0ZXIpIHtcclxuICAgICAgICB0aGlzLl9leHBvcnRlciA9IGV4cG9ydGVyO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge31cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZ2V0IHdhc1VzZWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3dhc1VzZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHBvc3RFeHBvcnRNYXRlcmlhbEFkZGl0aW9uYWxUZXh0dXJlcyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IEJhc2VUZXh0dXJlW10ge1xyXG4gICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkge1xyXG4gICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsLnNoZWVuLmlzRW5hYmxlZCAmJiBiYWJ5bG9uTWF0ZXJpYWwuc2hlZW4udGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFtiYWJ5bG9uTWF0ZXJpYWwuc2hlZW4udGV4dHVyZV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBbXTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcG9zdEV4cG9ydE1hdGVyaWFsQXN5bmMoY29udGV4dDogc3RyaW5nLCBub2RlOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBQcm9taXNlPElNYXRlcmlhbD4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgICAgIGlmICghYmFieWxvbk1hdGVyaWFsLnNoZWVuLmlzRW5hYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX3dhc1VzZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChub2RlLmV4dGVuc2lvbnMgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9ucyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2hlZW5JbmZvOiBJS0hSTWF0ZXJpYWxzU2hlZW4gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2hlZW5Db2xvckZhY3RvcjogYmFieWxvbk1hdGVyaWFsLnNoZWVuLmNvbG9yLmFzQXJyYXkoKSxcclxuICAgICAgICAgICAgICAgICAgICBzaGVlblJvdWdobmVzc0ZhY3RvcjogYmFieWxvbk1hdGVyaWFsLnNoZWVuLnJvdWdobmVzcyA/PyAwLFxyXG4gICAgICAgICAgICAgICAgICAgIGhhc1RleHR1cmVzOiAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzaGVlbkluZm8uc2hlZW5Db2xvclRleHR1cmUgIT09IG51bGwgfHwgc2hlZW5JbmZvLnNoZWVuUm91Z2huZXNzVGV4dHVyZSAhPT0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsLnNoZWVuLnRleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBzaGVlbkluZm8uc2hlZW5Db2xvclRleHR1cmUgPSB0aGlzLl9leHBvcnRlci5fZ2xURk1hdGVyaWFsRXhwb3J0ZXIuX2dldFRleHR1cmVJbmZvKGJhYnlsb25NYXRlcmlhbC5zaGVlbi50ZXh0dXJlKSA/PyB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbC5zaGVlbi50ZXh0dXJlUm91Z2huZXNzICYmICFiYWJ5bG9uTWF0ZXJpYWwuc2hlZW4udXNlUm91Z2huZXNzRnJvbU1haW5UZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2hlZW5JbmZvLnNoZWVuUm91Z2huZXNzVGV4dHVyZSA9IHRoaXMuX2V4cG9ydGVyLl9nbFRGTWF0ZXJpYWxFeHBvcnRlci5fZ2V0VGV4dHVyZUluZm8oYmFieWxvbk1hdGVyaWFsLnNoZWVuLnRleHR1cmVSb3VnaG5lc3MpID8/IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYmFieWxvbk1hdGVyaWFsLnNoZWVuLnRleHR1cmUgJiYgYmFieWxvbk1hdGVyaWFsLnNoZWVuLnVzZVJvdWdobmVzc0Zyb21NYWluVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNoZWVuSW5mby5zaGVlblJvdWdobmVzc1RleHR1cmUgPSB0aGlzLl9leHBvcnRlci5fZ2xURk1hdGVyaWFsRXhwb3J0ZXIuX2dldFRleHR1cmVJbmZvKGJhYnlsb25NYXRlcmlhbC5zaGVlbi50ZXh0dXJlKSA/PyB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbm9kZS5leHRlbnNpb25zW05BTUVdID0gc2hlZW5JbmZvO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJlc29sdmUobm9kZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbl9FeHBvcnRlci5SZWdpc3RlckV4dGVuc2lvbihOQU1FLCAoZXhwb3J0ZXIpID0+IG5ldyBLSFJfbWF0ZXJpYWxzX3NoZWVuKGV4cG9ydGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgSU1hdGVyaWFsLCBJS0hSTWF0ZXJpYWxzU3BlY3VsYXIgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZFeHBvcnRlckV4dGVuc2lvblYyIH0gZnJvbSBcIi4uL2dsVEZFeHBvcnRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBfRXhwb3J0ZXIgfSBmcm9tIFwiLi4vZ2xURkV4cG9ydGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgQmFzZVRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvYmFzZVRleHR1cmVcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl9tYXRlcmlhbHNfc3BlY3VsYXJcIjtcclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl9tYXRlcmlhbHNfc3BlY3VsYXIvUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21hdGVyaWFsc19zcGVjdWxhciBpbXBsZW1lbnRzIElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiB7XHJcbiAgICAvKiogTmFtZSBvZiB0aGlzIGV4dGVuc2lvbiAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZCAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQgPSB0cnVlO1xyXG5cclxuICAgIC8qKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgcmVxdWlyZWQgKi9cclxuICAgIHB1YmxpYyByZXF1aXJlZCA9IGZhbHNlO1xyXG5cclxuICAgIHByaXZhdGUgX2V4cG9ydGVyOiBfRXhwb3J0ZXI7XHJcblxyXG4gICAgcHJpdmF0ZSBfd2FzVXNlZCA9IGZhbHNlO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGV4cG9ydGVyOiBfRXhwb3J0ZXIpIHtcclxuICAgICAgICB0aGlzLl9leHBvcnRlciA9IGV4cG9ydGVyO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBEaXNwb3NlICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHt9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGdldCB3YXNVc2VkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl93YXNVc2VkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWZ0ZXIgZXhwb3J0aW5nIGEgbWF0ZXJpYWwsIGRlYWwgd2l0aCB0aGUgYWRkaXRpb25hbCB0ZXh0dXJlc1xyXG4gICAgICogQHBhcmFtIGNvbnRleHQgR0xURiBjb250ZXh0IG9mIHRoZSBtYXRlcmlhbFxyXG4gICAgICogQHBhcmFtIG5vZGUgZXhwb3J0ZWQgR0xURiBub2RlXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk1hdGVyaWFsIGNvcnJlc3BvbmRpbmcgYmFieWxvbiBtYXRlcmlhbFxyXG4gICAgICogQHJldHVybnMgYXJyYXkgb2YgYWRkaXRpb25hbCB0ZXh0dXJlcyB0byBleHBvcnRcclxuICAgICAqL1xyXG4gICAgcHVibGljIHBvc3RFeHBvcnRNYXRlcmlhbEFkZGl0aW9uYWxUZXh0dXJlcz8oY29udGV4dDogc3RyaW5nLCBub2RlOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBCYXNlVGV4dHVyZVtdIHtcclxuICAgICAgICBjb25zdCBhZGRpdGlvbmFsVGV4dHVyZXM6IEJhc2VUZXh0dXJlW10gPSBbXTtcclxuXHJcbiAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0V4dGVuc2lvbkVuYWJsZWQoYmFieWxvbk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbC5tZXRhbGxpY1JlZmxlY3RhbmNlVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxUZXh0dXJlcy5wdXNoKGJhYnlsb25NYXRlcmlhbC5tZXRhbGxpY1JlZmxlY3RhbmNlVGV4dHVyZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsLnJlZmxlY3RhbmNlVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxUZXh0dXJlcy5wdXNoKGJhYnlsb25NYXRlcmlhbC5yZWZsZWN0YW5jZVRleHR1cmUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGFkZGl0aW9uYWxUZXh0dXJlcztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGFkZGl0aW9uYWxUZXh0dXJlcztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9pc0V4dGVuc2lvbkVuYWJsZWQobWF0OiBQQlJNYXRlcmlhbCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIC8vIFRoaXMgZXh0ZW5zaW9uIG11c3Qgbm90IGJlIHVzZWQgb24gYSBtYXRlcmlhbCB0aGF0IGFsc28gdXNlcyBLSFJfbWF0ZXJpYWxzX3VubGl0XHJcbiAgICAgICAgaWYgKG1hdC51bmxpdCkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAoXHJcbiAgICAgICAgICAgIChtYXQubWV0YWxsaWNGMEZhY3RvciAhPSB1bmRlZmluZWQgJiYgbWF0Lm1ldGFsbGljRjBGYWN0b3IgIT0gMS4wKSB8fFxyXG4gICAgICAgICAgICAobWF0Lm1ldGFsbGljUmVmbGVjdGFuY2VDb2xvciAhPSB1bmRlZmluZWQgJiYgIW1hdC5tZXRhbGxpY1JlZmxlY3RhbmNlQ29sb3IuZXF1YWxzRmxvYXRzKDEuMCwgMS4wLCAxLjApKSB8fFxyXG4gICAgICAgICAgICB0aGlzLl9oYXNUZXh0dXJlc0V4dGVuc2lvbihtYXQpXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9oYXNUZXh0dXJlc0V4dGVuc2lvbihtYXQ6IFBCUk1hdGVyaWFsKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIG1hdC5tZXRhbGxpY1JlZmxlY3RhbmNlVGV4dHVyZSAhPSBudWxsIHx8IG1hdC5yZWZsZWN0YW5jZVRleHR1cmUgIT0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFmdGVyIGV4cG9ydGluZyBhIG1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBHTFRGIGNvbnRleHQgb2YgdGhlIG1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gbm9kZSBleHBvcnRlZCBHTFRGIG5vZGVcclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uTWF0ZXJpYWwgY29ycmVzcG9uZGluZyBiYWJ5bG9uIG1hdGVyaWFsXHJcbiAgICAgKiBAcmV0dXJucyBwcm9taXNlLCByZXNvbHZlcyB3aXRoIHRoZSBtYXRlcmlhbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcG9zdEV4cG9ydE1hdGVyaWFsQXN5bmM/KGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTxJTWF0ZXJpYWw+IHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcclxuICAgICAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsICYmIHRoaXMuX2lzRXh0ZW5zaW9uRW5hYmxlZChiYWJ5bG9uTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl93YXNVc2VkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBub2RlLmV4dGVuc2lvbnMgPSBub2RlLmV4dGVuc2lvbnMgfHwge307XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgbWV0YWxsaWNSZWZsZWN0YW5jZVRleHR1cmUgPSB0aGlzLl9leHBvcnRlci5fZ2xURk1hdGVyaWFsRXhwb3J0ZXIuX2dldFRleHR1cmVJbmZvKGJhYnlsb25NYXRlcmlhbC5tZXRhbGxpY1JlZmxlY3RhbmNlVGV4dHVyZSkgPz8gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmVmbGVjdGFuY2VUZXh0dXJlID0gdGhpcy5fZXhwb3J0ZXIuX2dsVEZNYXRlcmlhbEV4cG9ydGVyLl9nZXRUZXh0dXJlSW5mbyhiYWJ5bG9uTWF0ZXJpYWwucmVmbGVjdGFuY2VUZXh0dXJlKSA/PyB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtZXRhbGxpY0YwRmFjdG9yID0gYmFieWxvbk1hdGVyaWFsLm1ldGFsbGljRjBGYWN0b3IgPT0gMS4wID8gdW5kZWZpbmVkIDogYmFieWxvbk1hdGVyaWFsLm1ldGFsbGljRjBGYWN0b3I7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtZXRhbGxpY1JlZmxlY3RhbmNlQ29sb3IgPSBiYWJ5bG9uTWF0ZXJpYWwubWV0YWxsaWNSZWZsZWN0YW5jZUNvbG9yLmVxdWFsc0Zsb2F0cygxLjAsIDEuMCwgMS4wKVxyXG4gICAgICAgICAgICAgICAgICAgID8gdW5kZWZpbmVkXHJcbiAgICAgICAgICAgICAgICAgICAgOiBiYWJ5bG9uTWF0ZXJpYWwubWV0YWxsaWNSZWZsZWN0YW5jZUNvbG9yLmFzQXJyYXkoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBzcGVjdWxhckluZm86IElLSFJNYXRlcmlhbHNTcGVjdWxhciA9IHtcclxuICAgICAgICAgICAgICAgICAgICBzcGVjdWxhckZhY3RvcjogbWV0YWxsaWNGMEZhY3RvcixcclxuICAgICAgICAgICAgICAgICAgICBzcGVjdWxhclRleHR1cmU6IG1ldGFsbGljUmVmbGVjdGFuY2VUZXh0dXJlLFxyXG4gICAgICAgICAgICAgICAgICAgIHNwZWN1bGFyQ29sb3JGYWN0b3I6IG1ldGFsbGljUmVmbGVjdGFuY2VDb2xvcixcclxuICAgICAgICAgICAgICAgICAgICBzcGVjdWxhckNvbG9yVGV4dHVyZTogcmVmbGVjdGFuY2VUZXh0dXJlLFxyXG4gICAgICAgICAgICAgICAgICAgIGhhc1RleHR1cmVzOiAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYXNUZXh0dXJlc0V4dGVuc2lvbihiYWJ5bG9uTWF0ZXJpYWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgbm9kZS5leHRlbnNpb25zW05BTUVdID0gc3BlY3VsYXJJbmZvO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJlc29sdmUobm9kZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbl9FeHBvcnRlci5SZWdpc3RlckV4dGVuc2lvbihOQU1FLCAoZXhwb3J0ZXIpID0+IG5ldyBLSFJfbWF0ZXJpYWxzX3NwZWN1bGFyKGV4cG9ydGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgSU1hdGVyaWFsLCBJS0hSTWF0ZXJpYWxzVHJhbnNtaXNzaW9uIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyBJbWFnZU1pbWVUeXBlIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiB9IGZyb20gXCIuLi9nbFRGRXhwb3J0ZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgX0V4cG9ydGVyIH0gZnJvbSBcIi4uL2dsVEZFeHBvcnRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IEJhc2VUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL2Jhc2VUZXh0dXJlXCI7XHJcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gXCJjb3JlL01pc2MvbG9nZ2VyXCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWF0ZXJpYWxzX3RyYW5zbWlzc2lvblwiO1xyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0tocm9ub3MvS0hSX21hdGVyaWFsc190cmFuc21pc3Npb24vUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21hdGVyaWFsc190cmFuc21pc3Npb24gaW1wbGVtZW50cyBJR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIge1xyXG4gICAgLyoqIE5hbWUgb2YgdGhpcyBleHRlbnNpb24gKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKiogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkID0gdHJ1ZTtcclxuXHJcbiAgICAvKiogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIHJlcXVpcmVkICovXHJcbiAgICBwdWJsaWMgcmVxdWlyZWQgPSBmYWxzZTtcclxuXHJcbiAgICBwcml2YXRlIF9leHBvcnRlcjogX0V4cG9ydGVyO1xyXG5cclxuICAgIHByaXZhdGUgX3dhc1VzZWQgPSBmYWxzZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihleHBvcnRlcjogX0V4cG9ydGVyKSB7XHJcbiAgICAgICAgdGhpcy5fZXhwb3J0ZXIgPSBleHBvcnRlcjtcclxuICAgIH1cclxuXHJcbiAgICAvKiogRGlzcG9zZSAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7fVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBnZXQgd2FzVXNlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fd2FzVXNlZDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFmdGVyIGV4cG9ydGluZyBhIG1hdGVyaWFsLCBkZWFsIHdpdGggYWRkaXRpb25hbCB0ZXh0dXJlc1xyXG4gICAgICogQHBhcmFtIGNvbnRleHQgR0xURiBjb250ZXh0IG9mIHRoZSBtYXRlcmlhbFxyXG4gICAgICogQHBhcmFtIG5vZGUgZXhwb3J0ZWQgR0xURiBub2RlXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk1hdGVyaWFsIGNvcnJlc3BvbmRpbmcgYmFieWxvbiBtYXRlcmlhbFxyXG4gICAgICogQHJldHVybnMgYXJyYXkgb2YgYWRkaXRpb25hbCB0ZXh0dXJlcyB0byBleHBvcnRcclxuICAgICAqL1xyXG4gICAgcHVibGljIHBvc3RFeHBvcnRNYXRlcmlhbEFkZGl0aW9uYWxUZXh0dXJlcz8oY29udGV4dDogc3RyaW5nLCBub2RlOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBCYXNlVGV4dHVyZVtdIHtcclxuICAgICAgICBjb25zdCBhZGRpdGlvbmFsVGV4dHVyZXM6IEJhc2VUZXh0dXJlW10gPSBbXTtcclxuXHJcbiAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0V4dGVuc2lvbkVuYWJsZWQoYmFieWxvbk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbC5zdWJTdXJmYWNlLnRoaWNrbmVzc1RleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBhZGRpdGlvbmFsVGV4dHVyZXMucHVzaChiYWJ5bG9uTWF0ZXJpYWwuc3ViU3VyZmFjZS50aGlja25lc3NUZXh0dXJlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBhZGRpdGlvbmFsVGV4dHVyZXM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBhZGRpdGlvbmFsVGV4dHVyZXM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfaXNFeHRlbnNpb25FbmFibGVkKG1hdDogUEJSTWF0ZXJpYWwpOiBib29sZWFuIHtcclxuICAgICAgICAvLyBUaGlzIGV4dGVuc2lvbiBtdXN0IG5vdCBiZSB1c2VkIG9uIGEgbWF0ZXJpYWwgdGhhdCBhbHNvIHVzZXMgS0hSX21hdGVyaWFsc191bmxpdFxyXG4gICAgICAgIGlmIChtYXQudW5saXQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBzdWJzID0gbWF0LnN1YlN1cmZhY2U7XHJcbiAgICAgICAgcmV0dXJuIChzdWJzLmlzUmVmcmFjdGlvbkVuYWJsZWQgJiYgc3Vicy5yZWZyYWN0aW9uSW50ZW5zaXR5ICE9IHVuZGVmaW5lZCAmJiBzdWJzLnJlZnJhY3Rpb25JbnRlbnNpdHkgIT0gMCkgfHwgdGhpcy5faGFzVGV4dHVyZXNFeHRlbnNpb24obWF0KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9oYXNUZXh0dXJlc0V4dGVuc2lvbihtYXQ6IFBCUk1hdGVyaWFsKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIG1hdC5zdWJTdXJmYWNlLnJlZnJhY3Rpb25JbnRlbnNpdHlUZXh0dXJlICE9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZnRlciBleHBvcnRpbmcgYSBtYXRlcmlhbFxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgR0xURiBjb250ZXh0IG9mIHRoZSBtYXRlcmlhbFxyXG4gICAgICogQHBhcmFtIG5vZGUgZXhwb3J0ZWQgR0xURiBub2RlXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk1hdGVyaWFsIGNvcnJlc3BvbmRpbmcgYmFieWxvbiBtYXRlcmlhbFxyXG4gICAgICogQHJldHVybnMgdHJ1ZSBpZiBzdWNjZXNzZnVsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhc3luYyBwb3N0RXhwb3J0TWF0ZXJpYWxBc3luYz8oY29udGV4dDogc3RyaW5nLCBub2RlOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBQcm9taXNlPElNYXRlcmlhbD4ge1xyXG4gICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCAmJiB0aGlzLl9pc0V4dGVuc2lvbkVuYWJsZWQoYmFieWxvbk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICB0aGlzLl93YXNVc2VkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHN1YlN1cmZhY2UgPSBiYWJ5bG9uTWF0ZXJpYWwuc3ViU3VyZmFjZTtcclxuICAgICAgICAgICAgY29uc3QgdHJhbnNtaXNzaW9uRmFjdG9yID0gc3ViU3VyZmFjZS5yZWZyYWN0aW9uSW50ZW5zaXR5ID09PSAwID8gdW5kZWZpbmVkIDogc3ViU3VyZmFjZS5yZWZyYWN0aW9uSW50ZW5zaXR5O1xyXG5cclxuICAgICAgICAgICAgY29uc3Qgdm9sdW1lSW5mbzogSUtIUk1hdGVyaWFsc1RyYW5zbWlzc2lvbiA9IHtcclxuICAgICAgICAgICAgICAgIHRyYW5zbWlzc2lvbkZhY3RvcjogdHJhbnNtaXNzaW9uRmFjdG9yLFxyXG4gICAgICAgICAgICAgICAgaGFzVGV4dHVyZXM6ICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5faGFzVGV4dHVyZXNFeHRlbnNpb24oYmFieWxvbk1hdGVyaWFsKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBpZiAoc3ViU3VyZmFjZS5yZWZyYWN0aW9uSW50ZW5zaXR5VGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHN1YlN1cmZhY2UudXNlR2x0ZlN0eWxlVGV4dHVyZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0cmFuc21pc3Npb25UZXh0dXJlID0gYXdhaXQgdGhpcy5fZXhwb3J0ZXIuX2dsVEZNYXRlcmlhbEV4cG9ydGVyLl9leHBvcnRUZXh0dXJlSW5mb0FzeW5jKHN1YlN1cmZhY2UucmVmcmFjdGlvbkludGVuc2l0eVRleHR1cmUsIEltYWdlTWltZVR5cGUuUE5HKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHJhbnNtaXNzaW9uVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2b2x1bWVJbmZvLnRyYW5zbWlzc2lvblRleHR1cmUgPSB0cmFuc21pc3Npb25UZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLldhcm4oYCR7Y29udGV4dH06IEV4cG9ydGluZyBhIHN1YnN1cmZhY2UgcmVmcmFjdGlvbiBpbnRlbnNpdHkgdGV4dHVyZSB3aXRob3V0IFxcYHVzZUdsdGZTdHlsZVRleHR1cmVzXFxgIGlzIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbm9kZS5leHRlbnNpb25zIHx8PSB7fTtcclxuICAgICAgICAgICAgbm9kZS5leHRlbnNpb25zW05BTUVdID0gdm9sdW1lSW5mbztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBub2RlO1xyXG4gICAgfVxyXG59XHJcblxyXG5fRXhwb3J0ZXIuUmVnaXN0ZXJFeHRlbnNpb24oTkFNRSwgKGV4cG9ydGVyKSA9PiBuZXcgS0hSX21hdGVyaWFsc190cmFuc21pc3Npb24oZXhwb3J0ZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBJTWF0ZXJpYWwgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZFeHBvcnRlckV4dGVuc2lvblYyIH0gZnJvbSBcIi4uL2dsVEZFeHBvcnRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBfRXhwb3J0ZXIgfSBmcm9tIFwiLi4vZ2xURkV4cG9ydGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcbmltcG9ydCB7IFN0YW5kYXJkTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvc3RhbmRhcmRNYXRlcmlhbFwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc191bmxpdFwiO1xyXG5cclxuLyoqXHJcbiAqIEBpbnRlcm5hbFxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21hdGVyaWFsc191bmxpdCBpbXBsZW1lbnRzIElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiB7XHJcbiAgICAvKiogTmFtZSBvZiB0aGlzIGV4dGVuc2lvbiAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZCAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQgPSB0cnVlO1xyXG5cclxuICAgIC8qKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgcmVxdWlyZWQgKi9cclxuICAgIHB1YmxpYyByZXF1aXJlZCA9IGZhbHNlO1xyXG5cclxuICAgIHByaXZhdGUgX3dhc1VzZWQgPSBmYWxzZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHt9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGdldCB3YXNVc2VkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl93YXNVc2VkO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge31cclxuXHJcbiAgICBwdWJsaWMgcG9zdEV4cG9ydE1hdGVyaWFsQXN5bmM/KGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTxJTWF0ZXJpYWw+IHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcclxuICAgICAgICAgICAgbGV0IHVubGl0TWF0ZXJpYWwgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkge1xyXG4gICAgICAgICAgICAgICAgdW5saXRNYXRlcmlhbCA9IGJhYnlsb25NYXRlcmlhbC51bmxpdDtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBTdGFuZGFyZE1hdGVyaWFsKSB7XHJcbiAgICAgICAgICAgICAgICB1bmxpdE1hdGVyaWFsID0gYmFieWxvbk1hdGVyaWFsLmRpc2FibGVMaWdodGluZztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHVubGl0TWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3dhc1VzZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChub2RlLmV4dGVuc2lvbnMgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9ucyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9uc1tOQU1FXSA9IHt9O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXNvbHZlKG5vZGUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcblxyXG5fRXhwb3J0ZXIuUmVnaXN0ZXJFeHRlbnNpb24oTkFNRSwgKCkgPT4gbmV3IEtIUl9tYXRlcmlhbHNfdW5saXQoKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgSU1hdGVyaWFsLCBJS0hSTWF0ZXJpYWxzVm9sdW1lIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiB9IGZyb20gXCIuLi9nbFRGRXhwb3J0ZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgX0V4cG9ydGVyIH0gZnJvbSBcIi4uL2dsVEZFeHBvcnRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IEJhc2VUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL2Jhc2VUZXh0dXJlXCI7XHJcbmltcG9ydCB7IENvbG9yMyB9IGZyb20gXCJjb3JlL01hdGhzL21hdGguY29sb3JcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl9tYXRlcmlhbHNfdm9sdW1lXCI7XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbWF0ZXJpYWxzX3ZvbHVtZS9SRUFETUUubWQpXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfbWF0ZXJpYWxzX3ZvbHVtZSBpbXBsZW1lbnRzIElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiB7XHJcbiAgICAvKiogTmFtZSBvZiB0aGlzIGV4dGVuc2lvbiAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZCAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQgPSB0cnVlO1xyXG5cclxuICAgIC8qKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgcmVxdWlyZWQgKi9cclxuICAgIHB1YmxpYyByZXF1aXJlZCA9IGZhbHNlO1xyXG5cclxuICAgIHByaXZhdGUgX2V4cG9ydGVyOiBfRXhwb3J0ZXI7XHJcblxyXG4gICAgcHJpdmF0ZSBfd2FzVXNlZCA9IGZhbHNlO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGV4cG9ydGVyOiBfRXhwb3J0ZXIpIHtcclxuICAgICAgICB0aGlzLl9leHBvcnRlciA9IGV4cG9ydGVyO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge31cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZ2V0IHdhc1VzZWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3dhc1VzZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZnRlciBleHBvcnRpbmcgYSBtYXRlcmlhbCwgZGVhbCB3aXRoIGFkZGl0aW9uYWwgdGV4dHVyZXNcclxuICAgICAqIEBwYXJhbSBjb250ZXh0IEdMVEYgY29udGV4dCBvZiB0aGUgbWF0ZXJpYWxcclxuICAgICAqIEBwYXJhbSBub2RlIGV4cG9ydGVkIEdMVEYgbm9kZVxyXG4gICAgICogQHBhcmFtIGJhYnlsb25NYXRlcmlhbCBjb3JyZXNwb25kaW5nIGJhYnlsb24gbWF0ZXJpYWxcclxuICAgICAqIEByZXR1cm5zIGFycmF5IG9mIGFkZGl0aW9uYWwgdGV4dHVyZXMgdG8gZXhwb3J0XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBwb3N0RXhwb3J0TWF0ZXJpYWxBZGRpdGlvbmFsVGV4dHVyZXM/KGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogQmFzZVRleHR1cmVbXSB7XHJcbiAgICAgICAgY29uc3QgYWRkaXRpb25hbFRleHR1cmVzOiBCYXNlVGV4dHVyZVtdID0gW107XHJcblxyXG4gICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5faXNFeHRlbnNpb25FbmFibGVkKGJhYnlsb25NYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwuc3ViU3VyZmFjZS50aGlja25lc3NUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYWRkaXRpb25hbFRleHR1cmVzLnB1c2goYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2UudGhpY2tuZXNzVGV4dHVyZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYWRkaXRpb25hbFRleHR1cmVzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYWRkaXRpb25hbFRleHR1cmVzO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2lzRXh0ZW5zaW9uRW5hYmxlZChtYXQ6IFBCUk1hdGVyaWFsKTogYm9vbGVhbiB7XHJcbiAgICAgICAgLy8gVGhpcyBleHRlbnNpb24gbXVzdCBub3QgYmUgdXNlZCBvbiBhIG1hdGVyaWFsIHRoYXQgYWxzbyB1c2VzIEtIUl9tYXRlcmlhbHNfdW5saXRcclxuICAgICAgICBpZiAobWF0LnVubGl0KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qgc3VicyA9IG1hdC5zdWJTdXJmYWNlO1xyXG4gICAgICAgIC8vIHRoaXMgZXh0ZW5zaW9uIHJlcXVpcmVzIGVpdGhlciB0aGUgS0hSX21hdGVyaWFsc190cmFuc21pc3Npb24gb3IgS0hSX21hdGVyaWFsc19kaWZmdXNlX3RyYW5zbWlzc2lvbiBleHRlbnNpb25zLlxyXG4gICAgICAgIGlmICghc3Vicy5pc1JlZnJhY3Rpb25FbmFibGVkICYmICFzdWJzLmlzVHJhbnNsdWNlbmN5RW5hYmxlZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAoXHJcbiAgICAgICAgICAgIChzdWJzLm1heGltdW1UaGlja25lc3MgIT0gdW5kZWZpbmVkICYmIHN1YnMubWF4aW11bVRoaWNrbmVzcyAhPSAwKSB8fFxyXG4gICAgICAgICAgICAoc3Vicy50aW50Q29sb3JBdERpc3RhbmNlICE9IHVuZGVmaW5lZCAmJiBzdWJzLnRpbnRDb2xvckF0RGlzdGFuY2UgIT0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZKSB8fFxyXG4gICAgICAgICAgICAoc3Vicy50aW50Q29sb3IgIT0gdW5kZWZpbmVkICYmIHN1YnMudGludENvbG9yICE9IENvbG9yMy5XaGl0ZSgpKSB8fFxyXG4gICAgICAgICAgICB0aGlzLl9oYXNUZXh0dXJlc0V4dGVuc2lvbihtYXQpXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9oYXNUZXh0dXJlc0V4dGVuc2lvbihtYXQ6IFBCUk1hdGVyaWFsKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIG1hdC5zdWJTdXJmYWNlLnRoaWNrbmVzc1RleHR1cmUgIT0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFmdGVyIGV4cG9ydGluZyBhIG1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBHTFRGIGNvbnRleHQgb2YgdGhlIG1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gbm9kZSBleHBvcnRlZCBHTFRGIG5vZGVcclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uTWF0ZXJpYWwgY29ycmVzcG9uZGluZyBiYWJ5bG9uIG1hdGVyaWFsXHJcbiAgICAgKiBAcmV0dXJucyBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgdXBkYXRlZCBub2RlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBwb3N0RXhwb3J0TWF0ZXJpYWxBc3luYz8oY29udGV4dDogc3RyaW5nLCBub2RlOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBQcm9taXNlPElNYXRlcmlhbD4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwgJiYgdGhpcy5faXNFeHRlbnNpb25FbmFibGVkKGJhYnlsb25NYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3dhc1VzZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHN1YnMgPSBiYWJ5bG9uTWF0ZXJpYWwuc3ViU3VyZmFjZTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHRoaWNrbmVzc0ZhY3RvciA9IHN1YnMubWF4aW11bVRoaWNrbmVzcyA9PSAwID8gdW5kZWZpbmVkIDogc3Vicy5tYXhpbXVtVGhpY2tuZXNzO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdGhpY2tuZXNzVGV4dHVyZSA9IHRoaXMuX2V4cG9ydGVyLl9nbFRGTWF0ZXJpYWxFeHBvcnRlci5fZ2V0VGV4dHVyZUluZm8oc3Vicy50aGlja25lc3NUZXh0dXJlKSA/PyB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhdHRlbnVhdGlvbkRpc3RhbmNlID0gc3Vicy50aW50Q29sb3JBdERpc3RhbmNlID09IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSA/IHVuZGVmaW5lZCA6IHN1YnMudGludENvbG9yQXREaXN0YW5jZTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGF0dGVudWF0aW9uQ29sb3IgPSBzdWJzLnRpbnRDb2xvci5lcXVhbHNGbG9hdHMoMS4wLCAxLjAsIDEuMCkgPyB1bmRlZmluZWQgOiBzdWJzLnRpbnRDb2xvci5hc0FycmF5KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3Qgdm9sdW1lSW5mbzogSUtIUk1hdGVyaWFsc1ZvbHVtZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlja25lc3NGYWN0b3I6IHRoaWNrbmVzc0ZhY3RvcixcclxuICAgICAgICAgICAgICAgICAgICB0aGlja25lc3NUZXh0dXJlOiB0aGlja25lc3NUZXh0dXJlLFxyXG4gICAgICAgICAgICAgICAgICAgIGF0dGVudWF0aW9uRGlzdGFuY2U6IGF0dGVudWF0aW9uRGlzdGFuY2UsXHJcbiAgICAgICAgICAgICAgICAgICAgYXR0ZW51YXRpb25Db2xvcjogYXR0ZW51YXRpb25Db2xvcixcclxuICAgICAgICAgICAgICAgICAgICBoYXNUZXh0dXJlczogKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5faGFzVGV4dHVyZXNFeHRlbnNpb24oYmFieWxvbk1hdGVyaWFsKTtcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9ucyA9IG5vZGUuZXh0ZW5zaW9ucyB8fCB7fTtcclxuICAgICAgICAgICAgICAgIG5vZGUuZXh0ZW5zaW9uc1tOQU1FXSA9IHZvbHVtZUluZm87XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmVzb2x2ZShub2RlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxuX0V4cG9ydGVyLlJlZ2lzdGVyRXh0ZW5zaW9uKE5BTUUsIChleHBvcnRlcikgPT4gbmV3IEtIUl9tYXRlcmlhbHNfdm9sdW1lKGV4cG9ydGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgSVRleHR1cmVJbmZvLCBJS0hSVGV4dHVyZVRyYW5zZm9ybSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgVG9vbHMgfSBmcm9tIFwiY29yZS9NaXNjL3Rvb2xzXCI7XHJcbmltcG9ydCB0eXBlIHsgVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy90ZXh0dXJlXCI7XHJcbmltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiB9IGZyb20gXCIuLi9nbFRGRXhwb3J0ZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgX0V4cG9ydGVyIH0gZnJvbSBcIi4uL2dsVEZFeHBvcnRlclwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX3RleHR1cmVfdHJhbnNmb3JtXCI7XHJcblxyXG4vKipcclxuICogQGludGVybmFsXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfdGV4dHVyZV90cmFuc2Zvcm0gaW1wbGVtZW50cyBJR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIge1xyXG4gICAgLyoqIE5hbWUgb2YgdGhpcyBleHRlbnNpb24gKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKiogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkID0gdHJ1ZTtcclxuXHJcbiAgICAvKiogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIHJlcXVpcmVkICovXHJcbiAgICBwdWJsaWMgcmVxdWlyZWQgPSBmYWxzZTtcclxuXHJcbiAgICAvKiogUmVmZXJlbmNlIHRvIHRoZSBnbFRGIGV4cG9ydGVyICovXHJcbiAgICBwcml2YXRlIF93YXNVc2VkID0gZmFsc2U7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7fVxyXG5cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge31cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZ2V0IHdhc1VzZWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3dhc1VzZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHBvc3RFeHBvcnRUZXh0dXJlPyhjb250ZXh0OiBzdHJpbmcsIHRleHR1cmVJbmZvOiBJVGV4dHVyZUluZm8sIGJhYnlsb25UZXh0dXJlOiBUZXh0dXJlKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgY2FuVXNlRXh0ZW5zaW9uID1cclxuICAgICAgICAgICAgYmFieWxvblRleHR1cmUgJiZcclxuICAgICAgICAgICAgKChiYWJ5bG9uVGV4dHVyZS51QW5nID09PSAwICYmIGJhYnlsb25UZXh0dXJlLndBbmcgPT09IDAgJiYgYmFieWxvblRleHR1cmUudkFuZyA9PT0gMCkgfHxcclxuICAgICAgICAgICAgICAgIChiYWJ5bG9uVGV4dHVyZS51Um90YXRpb25DZW50ZXIgPT09IDAgJiYgYmFieWxvblRleHR1cmUudlJvdGF0aW9uQ2VudGVyID09PSAwKSk7XHJcblxyXG4gICAgICAgIGlmIChjYW5Vc2VFeHRlbnNpb24pIHtcclxuICAgICAgICAgICAgY29uc3QgdGV4dHVyZVRyYW5zZm9ybTogSUtIUlRleHR1cmVUcmFuc2Zvcm0gPSB7fTtcclxuICAgICAgICAgICAgbGV0IHRyYW5zZm9ybUlzUmVxdWlyZWQgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChiYWJ5bG9uVGV4dHVyZS51T2Zmc2V0ICE9PSAwIHx8IGJhYnlsb25UZXh0dXJlLnZPZmZzZXQgIT09IDApIHtcclxuICAgICAgICAgICAgICAgIHRleHR1cmVUcmFuc2Zvcm0ub2Zmc2V0ID0gW2JhYnlsb25UZXh0dXJlLnVPZmZzZXQsIGJhYnlsb25UZXh0dXJlLnZPZmZzZXRdO1xyXG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtSXNSZXF1aXJlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChiYWJ5bG9uVGV4dHVyZS51U2NhbGUgIT09IDEgfHwgYmFieWxvblRleHR1cmUudlNjYWxlICE9PSAxKSB7XHJcbiAgICAgICAgICAgICAgICB0ZXh0dXJlVHJhbnNmb3JtLnNjYWxlID0gW2JhYnlsb25UZXh0dXJlLnVTY2FsZSwgYmFieWxvblRleHR1cmUudlNjYWxlXTtcclxuICAgICAgICAgICAgICAgIHRyYW5zZm9ybUlzUmVxdWlyZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoYmFieWxvblRleHR1cmUud0FuZyAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgdGV4dHVyZVRyYW5zZm9ybS5yb3RhdGlvbiA9IC1iYWJ5bG9uVGV4dHVyZS53QW5nO1xyXG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtSXNSZXF1aXJlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChiYWJ5bG9uVGV4dHVyZS5jb29yZGluYXRlc0luZGV4ICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICB0ZXh0dXJlVHJhbnNmb3JtLnRleENvb3JkID0gYmFieWxvblRleHR1cmUuY29vcmRpbmF0ZXNJbmRleDtcclxuICAgICAgICAgICAgICAgIHRyYW5zZm9ybUlzUmVxdWlyZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRyYW5zZm9ybUlzUmVxdWlyZWQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5fd2FzVXNlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmICghdGV4dHVyZUluZm8uZXh0ZW5zaW9ucykge1xyXG4gICAgICAgICAgICAgICAgdGV4dHVyZUluZm8uZXh0ZW5zaW9ucyA9IHt9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRleHR1cmVJbmZvLmV4dGVuc2lvbnNbTkFNRV0gPSB0ZXh0dXJlVHJhbnNmb3JtO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcHJlRXhwb3J0VGV4dHVyZUFzeW5jKGNvbnRleHQ6IHN0cmluZywgYmFieWxvblRleHR1cmU6IFRleHR1cmUpOiBQcm9taXNlPE51bGxhYmxlPFRleHR1cmU+PiB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgY29uc3Qgc2NlbmUgPSBiYWJ5bG9uVGV4dHVyZS5nZXRTY2VuZSgpO1xyXG4gICAgICAgICAgICBpZiAoIXNjZW5lKSB7XHJcbiAgICAgICAgICAgICAgICByZWplY3QoYCR7Y29udGV4dH06IFwic2NlbmVcIiBpcyBub3QgZGVmaW5lZCBmb3IgQmFieWxvbiB0ZXh0dXJlICR7YmFieWxvblRleHR1cmUubmFtZX0hYCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8qXHJcbiAgICAgICAgICAgICAqIFRoZSBLSFJfdGV4dHVyZV90cmFuc2Zvcm0gc2NoZW1hIG9ubHkgc3VwcG9ydHMgdyByb3RhdGlvbiBhcm91bmQgdGhlIG9yaWdpbi5cclxuICAgICAgICAgICAgICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi90cmVlL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfdGV4dHVyZV90cmFuc2Zvcm0jZ2x0Zi1zY2hlbWEtdXBkYXRlcy5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGlmIChiYWJ5bG9uVGV4dHVyZS51QW5nICE9PSAwIHx8IGJhYnlsb25UZXh0dXJlLnZBbmcgIT09IDApIHtcclxuICAgICAgICAgICAgICAgIFRvb2xzLldhcm4oYCR7Y29udGV4dH06IFRleHR1cmUgJHtiYWJ5bG9uVGV4dHVyZS5uYW1lfSB3aXRoIHJvdGF0aW9uIGluIHRoZSB1IG9yIHYgYXhpcyBpcyBub3Qgc3VwcG9ydGVkIGluIGdsVEYuYCk7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKG51bGwpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGJhYnlsb25UZXh0dXJlLndBbmcgIT09IDAgJiYgKGJhYnlsb25UZXh0dXJlLnVSb3RhdGlvbkNlbnRlciAhPT0gMCB8fCBiYWJ5bG9uVGV4dHVyZS52Um90YXRpb25DZW50ZXIgIT09IDApKSB7XHJcbiAgICAgICAgICAgICAgICBUb29scy5XYXJuKGAke2NvbnRleHR9OiBUZXh0dXJlICR7YmFieWxvblRleHR1cmUubmFtZX0gd2l0aCByb3RhdGlvbiBub3QgY2VudGVyZWQgYXQgdGhlIG9yaWdpbiBjYW5ub3QgYmUgZXhwb3J0ZWQgd2l0aCAke05BTUV9YCk7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKG51bGwpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShiYWJ5bG9uVGV4dHVyZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxuX0V4cG9ydGVyLlJlZ2lzdGVyRXh0ZW5zaW9uKE5BTUUsICgpID0+IG5ldyBLSFJfdGV4dHVyZV90cmFuc2Zvcm0oKSk7XHJcbiIsImV4cG9ydCAqIGZyb20gXCIuL0tIUl90ZXh0dXJlX3RyYW5zZm9ybVwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbGlnaHRzX3B1bmN0dWFsXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfY2xlYXJjb2F0XCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfaXJpZGVzY2VuY2VcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX21hdGVyaWFsc19hbmlzb3Ryb3B5XCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfc2hlZW5cIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX21hdGVyaWFsc191bmxpdFwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWF0ZXJpYWxzX2lvclwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWF0ZXJpYWxzX3NwZWN1bGFyXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfdm9sdW1lXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfZGlzcGVyc2lvblwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWF0ZXJpYWxzX3RyYW5zbWlzc2lvblwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9FWFRfbWVzaF9ncHVfaW5zdGFuY2luZ1wiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWF0ZXJpYWxzX2VtaXNzaXZlX3N0cmVuZ3RoXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfZGlmZnVzZV90cmFuc21pc3Npb25cIjtcclxuIiwiaW1wb3J0IHR5cGUgeyBJQW5pbWF0aW9uLCBJTm9kZSwgSUJ1ZmZlclZpZXcsIElBY2Nlc3NvciwgSUFuaW1hdGlvblNhbXBsZXIsIElBbmltYXRpb25DaGFubmVsIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyBBbmltYXRpb25TYW1wbGVySW50ZXJwb2xhdGlvbiwgQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgsIEFjY2Vzc29yVHlwZSwgQWNjZXNzb3JDb21wb25lbnRUeXBlIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IE5vZGUgfSBmcm9tIFwiY29yZS9ub2RlXCI7XHJcbmltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBWZWN0b3IzLCBRdWF0ZXJuaW9uIH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC52ZWN0b3JcIjtcclxuaW1wb3J0IHsgVG9vbHMgfSBmcm9tIFwiY29yZS9NaXNjL3Rvb2xzXCI7XHJcbmltcG9ydCB7IEFuaW1hdGlvbiB9IGZyb20gXCJjb3JlL0FuaW1hdGlvbnMvYW5pbWF0aW9uXCI7XHJcbmltcG9ydCB7IFRyYW5zZm9ybU5vZGUgfSBmcm9tIFwiY29yZS9NZXNoZXMvdHJhbnNmb3JtTm9kZVwiO1xyXG5pbXBvcnQgdHlwZSB7IFNjZW5lIH0gZnJvbSBcImNvcmUvc2NlbmVcIjtcclxuaW1wb3J0IHsgTW9ycGhUYXJnZXQgfSBmcm9tIFwiY29yZS9Nb3JwaC9tb3JwaFRhcmdldFwiO1xyXG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcImNvcmUvTWVzaGVzL21lc2hcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgX0JpbmFyeVdyaXRlciB9IGZyb20gXCIuL2dsVEZFeHBvcnRlclwiO1xyXG5pbXBvcnQgeyBfR0xURlV0aWxpdGllcyB9IGZyb20gXCIuL2dsVEZVdGlsaXRpZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJQW5pbWF0aW9uS2V5IH0gZnJvbSBcImNvcmUvQW5pbWF0aW9ucy9hbmltYXRpb25LZXlcIjtcclxuaW1wb3J0IHsgQW5pbWF0aW9uS2V5SW50ZXJwb2xhdGlvbiB9IGZyb20gXCJjb3JlL0FuaW1hdGlvbnMvYW5pbWF0aW9uS2V5XCI7XHJcblxyXG5pbXBvcnQgeyBDYW1lcmEgfSBmcm9tIFwiY29yZS9DYW1lcmFzL2NhbWVyYVwiO1xyXG5pbXBvcnQgeyBMaWdodCB9IGZyb20gXCJjb3JlL0xpZ2h0cy9saWdodFwiO1xyXG5cclxuLyoqXHJcbiAqIEBpbnRlcm5hbFxyXG4gKiBJbnRlcmZhY2UgdG8gc3RvcmUgYW5pbWF0aW9uIGRhdGEuXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBpbnRlcmZhY2UgX0lBbmltYXRpb25EYXRhIHtcclxuICAgIC8qKlxyXG4gICAgICogS2V5ZnJhbWUgZGF0YS5cclxuICAgICAqL1xyXG4gICAgaW5wdXRzOiBudW1iZXJbXTtcclxuICAgIC8qKlxyXG4gICAgICogVmFsdWUgZGF0YS5cclxuICAgICAqL1xyXG4gICAgb3V0cHV0czogbnVtYmVyW11bXTtcclxuICAgIC8qKlxyXG4gICAgICogQW5pbWF0aW9uIGludGVycG9sYXRpb24gZGF0YS5cclxuICAgICAqL1xyXG4gICAgc2FtcGxlckludGVycG9sYXRpb246IEFuaW1hdGlvblNhbXBsZXJJbnRlcnBvbGF0aW9uO1xyXG4gICAgLyoqXHJcbiAgICAgKiBNaW5pbXVtIGtleWZyYW1lIHZhbHVlLlxyXG4gICAgICovXHJcbiAgICBpbnB1dHNNaW46IG51bWJlcjtcclxuICAgIC8qKlxyXG4gICAgICogTWF4aW11bSBrZXlmcmFtZSB2YWx1ZS5cclxuICAgICAqL1xyXG4gICAgaW5wdXRzTWF4OiBudW1iZXI7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBAaW50ZXJuYWxcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGludGVyZmFjZSBfSUFuaW1hdGlvbkluZm8ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgdGFyZ2V0IGNoYW5uZWwgZm9yIHRoZSBhbmltYXRpb25cclxuICAgICAqL1xyXG4gICAgYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGg6IEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoO1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgZ2xURiBhY2Nlc3NvciB0eXBlIGZvciB0aGUgZGF0YS5cclxuICAgICAqL1xyXG4gICAgZGF0YUFjY2Vzc29yVHlwZTogQWNjZXNzb3JUeXBlLlZFQzMgfCBBY2Nlc3NvclR5cGUuVkVDNCB8IEFjY2Vzc29yVHlwZS5TQ0FMQVI7XHJcbiAgICAvKipcclxuICAgICAqIFNwZWNpZmllcyBpZiBxdWF0ZXJuaW9ucyBzaG91bGQgYmUgdXNlZC5cclxuICAgICAqL1xyXG4gICAgdXNlUXVhdGVybmlvbjogYm9vbGVhbjtcclxufVxyXG5cclxuLyoqXHJcbiAqIEBpbnRlcm5hbFxyXG4gKiBFbnVtIGZvciBoYW5kbGluZyBpbiB0YW5nZW50IGFuZCBvdXQgdGFuZ2VudC5cclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZW51bSBfVGFuZ2VudFR5cGUge1xyXG4gICAgLyoqXHJcbiAgICAgKiBTcGVjaWZpZXMgdGhhdCBpbnB1dCB0YW5nZW50cyBhcmUgdXNlZC5cclxuICAgICAqL1xyXG4gICAgSU5UQU5HRU5ULFxyXG4gICAgLyoqXHJcbiAgICAgKiBTcGVjaWZpZXMgdGhhdCBvdXRwdXQgdGFuZ2VudHMgYXJlIHVzZWQuXHJcbiAgICAgKi9cclxuICAgIE9VVFRBTkdFTlQsXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBAaW50ZXJuYWxcclxuICogVXRpbGl0eSBjbGFzcyBmb3IgZ2VuZXJhdGluZyBnbFRGIGFuaW1hdGlvbiBkYXRhIGZyb20gQmFieWxvbkpTLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIF9HTFRGQW5pbWF0aW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogRGV0ZXJtaW5lIGlmIGEgbm9kZSBpcyB0cmFuc2Zvcm1hYmxlIC0gaWUgaGFzIHByb3BlcnRpZXMgaXQgc2hvdWxkIGJlIHBhcnQgb2YgYW5pbWF0aW9uIG9mIHRyYW5zZm9ybWF0aW9uLlxyXG4gICAgICogQHBhcmFtIGJhYnlsb25Ob2RlIHRoZSBub2RlIHRvIHRlc3RcclxuICAgICAqIEByZXR1cm5zIHRydWUgaWYgY2FuIGJlIGFuaW1hdGVkLCBmYWxzZSBvdGhlcndpc2UuIEZhbHNlIGlmIHRoZSBwYXJhbWV0ZXIgaXMgbnVsbCBvciB1bmRlZmluZWQuXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIF9Jc1RyYW5zZm9ybWFibGUoYmFieWxvbk5vZGU6IE5vZGUpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gYmFieWxvbk5vZGUgJiYgKGJhYnlsb25Ob2RlIGluc3RhbmNlb2YgVHJhbnNmb3JtTm9kZSB8fCBiYWJ5bG9uTm9kZSBpbnN0YW5jZW9mIENhbWVyYSB8fCBiYWJ5bG9uTm9kZSBpbnN0YW5jZW9mIExpZ2h0KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqXHJcbiAgICAgKiBDcmVhdGVzIGdsVEYgY2hhbm5lbCBhbmltYXRpb24gZnJvbSBCYWJ5bG9uSlMgYW5pbWF0aW9uLlxyXG4gICAgICogQHBhcmFtIGJhYnlsb25UcmFuc2Zvcm1Ob2RlIC0gQmFieWxvbkpTIG1lc2guXHJcbiAgICAgKiBAcGFyYW0gYW5pbWF0aW9uIC0gYW5pbWF0aW9uLlxyXG4gICAgICogQHBhcmFtIGFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoIC0gVGhlIHRhcmdldCBhbmltYXRpb24gY2hhbm5lbC5cclxuICAgICAqIEBwYXJhbSB1c2VRdWF0ZXJuaW9uIC0gU3BlY2lmaWVzIGlmIHF1YXRlcm5pb25zIGFyZSB1c2VkLlxyXG4gICAgICogQHJldHVybnMgbnVsbGFibGUgSUFuaW1hdGlvbkRhdGFcclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBfQ3JlYXRlTm9kZUFuaW1hdGlvbihcclxuICAgICAgICBiYWJ5bG9uVHJhbnNmb3JtTm9kZTogTm9kZSxcclxuICAgICAgICBhbmltYXRpb246IEFuaW1hdGlvbixcclxuICAgICAgICBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aDogQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgsXHJcbiAgICAgICAgdXNlUXVhdGVybmlvbjogYm9vbGVhbixcclxuICAgICAgICBhbmltYXRpb25TYW1wbGVSYXRlOiBudW1iZXJcclxuICAgICk6IE51bGxhYmxlPF9JQW5pbWF0aW9uRGF0YT4ge1xyXG4gICAgICAgIGlmICh0aGlzLl9Jc1RyYW5zZm9ybWFibGUoYmFieWxvblRyYW5zZm9ybU5vZGUpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGlucHV0czogbnVtYmVyW10gPSBbXTtcclxuICAgICAgICAgICAgY29uc3Qgb3V0cHV0czogbnVtYmVyW11bXSA9IFtdO1xyXG4gICAgICAgICAgICBjb25zdCBrZXlGcmFtZXMgPSBhbmltYXRpb24uZ2V0S2V5cygpO1xyXG4gICAgICAgICAgICBjb25zdCBtaW5NYXhLZXlGcmFtZXMgPSBfR0xURkFuaW1hdGlvbi5fQ2FsY3VsYXRlTWluTWF4S2V5RnJhbWVzKGtleUZyYW1lcyk7XHJcbiAgICAgICAgICAgIGNvbnN0IGludGVycG9sYXRpb25PckJha2UgPSBfR0xURkFuaW1hdGlvbi5fRGVkdWNlSW50ZXJwb2xhdGlvbihrZXlGcmFtZXMsIGFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLCB1c2VRdWF0ZXJuaW9uKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGludGVycG9sYXRpb24gPSBpbnRlcnBvbGF0aW9uT3JCYWtlLmludGVycG9sYXRpb25UeXBlO1xyXG4gICAgICAgICAgICBjb25zdCBzaG91bGRCYWtlQW5pbWF0aW9uID0gaW50ZXJwb2xhdGlvbk9yQmFrZS5zaG91bGRCYWtlQW5pbWF0aW9uO1xyXG5cclxuICAgICAgICAgICAgaWYgKHNob3VsZEJha2VBbmltYXRpb24pIHtcclxuICAgICAgICAgICAgICAgIF9HTFRGQW5pbWF0aW9uLl9DcmVhdGVCYWtlZEFuaW1hdGlvbihcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uVHJhbnNmb3JtTm9kZSxcclxuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24sXHJcbiAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgbWluTWF4S2V5RnJhbWVzLm1pbixcclxuICAgICAgICAgICAgICAgICAgICBtaW5NYXhLZXlGcmFtZXMubWF4LFxyXG4gICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbi5mcmFtZVBlclNlY29uZCxcclxuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25TYW1wbGVSYXRlLFxyXG4gICAgICAgICAgICAgICAgICAgIGlucHV0cyxcclxuICAgICAgICAgICAgICAgICAgICBvdXRwdXRzLFxyXG4gICAgICAgICAgICAgICAgICAgIG1pbk1heEtleUZyYW1lcyxcclxuICAgICAgICAgICAgICAgICAgICB1c2VRdWF0ZXJuaW9uXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKGludGVycG9sYXRpb24gPT09IEFuaW1hdGlvblNhbXBsZXJJbnRlcnBvbGF0aW9uLkxJTkVBUiB8fCBpbnRlcnBvbGF0aW9uID09PSBBbmltYXRpb25TYW1wbGVySW50ZXJwb2xhdGlvbi5TVEVQKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX0dMVEZBbmltYXRpb24uX0NyZWF0ZUxpbmVhck9yU3RlcEFuaW1hdGlvbihiYWJ5bG9uVHJhbnNmb3JtTm9kZSwgYW5pbWF0aW9uLCBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCwgaW5wdXRzLCBvdXRwdXRzLCB1c2VRdWF0ZXJuaW9uKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaW50ZXJwb2xhdGlvbiA9PT0gQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uQ1VCSUNTUExJTkUpIHtcclxuICAgICAgICAgICAgICAgICAgICBfR0xURkFuaW1hdGlvbi5fQ3JlYXRlQ3ViaWNTcGxpbmVBbmltYXRpb24oYmFieWxvblRyYW5zZm9ybU5vZGUsIGFuaW1hdGlvbiwgYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgsIGlucHV0cywgb3V0cHV0cywgdXNlUXVhdGVybmlvbik7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIF9HTFRGQW5pbWF0aW9uLl9DcmVhdGVCYWtlZEFuaW1hdGlvbihcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvblRyYW5zZm9ybU5vZGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbk1heEtleUZyYW1lcy5taW4sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbk1heEtleUZyYW1lcy5tYXgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbi5mcmFtZVBlclNlY29uZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uU2FtcGxlUmF0ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW5NYXhLZXlGcmFtZXMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZVF1YXRlcm5pb25cclxuICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoaW5wdXRzLmxlbmd0aCAmJiBvdXRwdXRzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0OiBfSUFuaW1hdGlvbkRhdGEgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW5wdXRzOiBpbnB1dHMsXHJcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0czogb3V0cHV0cyxcclxuICAgICAgICAgICAgICAgICAgICBzYW1wbGVySW50ZXJwb2xhdGlvbjogaW50ZXJwb2xhdGlvbixcclxuICAgICAgICAgICAgICAgICAgICBpbnB1dHNNaW46IHNob3VsZEJha2VBbmltYXRpb24gPyBtaW5NYXhLZXlGcmFtZXMubWluIDogVG9vbHMuRmxvYXRSb3VuZChtaW5NYXhLZXlGcmFtZXMubWluIC8gYW5pbWF0aW9uLmZyYW1lUGVyU2Vjb25kKSxcclxuICAgICAgICAgICAgICAgICAgICBpbnB1dHNNYXg6IHNob3VsZEJha2VBbmltYXRpb24gPyBtaW5NYXhLZXlGcmFtZXMubWF4IDogVG9vbHMuRmxvYXRSb3VuZChtaW5NYXhLZXlGcmFtZXMubWF4IC8gYW5pbWF0aW9uLmZyYW1lUGVyU2Vjb25kKSxcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX0RlZHVjZUFuaW1hdGlvbkluZm8oYW5pbWF0aW9uOiBBbmltYXRpb24pOiBOdWxsYWJsZTxfSUFuaW1hdGlvbkluZm8+IHtcclxuICAgICAgICBsZXQgYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGg6IE51bGxhYmxlPEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoPiA9IG51bGw7XHJcbiAgICAgICAgbGV0IGRhdGFBY2Nlc3NvclR5cGUgPSBBY2Nlc3NvclR5cGUuVkVDMztcclxuICAgICAgICBsZXQgdXNlUXVhdGVybmlvbjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgICAgIGNvbnN0IHByb3BlcnR5ID0gYW5pbWF0aW9uLnRhcmdldFByb3BlcnR5LnNwbGl0KFwiLlwiKTtcclxuICAgICAgICBzd2l0Y2ggKHByb3BlcnR5WzBdKSB7XHJcbiAgICAgICAgICAgIGNhc2UgXCJzY2FsaW5nXCI6IHtcclxuICAgICAgICAgICAgICAgIGFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoID0gQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGguU0NBTEU7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFwicG9zaXRpb25cIjoge1xyXG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGggPSBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aC5UUkFOU0xBVElPTjtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgXCJyb3RhdGlvblwiOiB7XHJcbiAgICAgICAgICAgICAgICBkYXRhQWNjZXNzb3JUeXBlID0gQWNjZXNzb3JUeXBlLlZFQzQ7XHJcbiAgICAgICAgICAgICAgICBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCA9IEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLlJPVEFUSU9OO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBcInJvdGF0aW9uUXVhdGVybmlvblwiOiB7XHJcbiAgICAgICAgICAgICAgICBkYXRhQWNjZXNzb3JUeXBlID0gQWNjZXNzb3JUeXBlLlZFQzQ7XHJcbiAgICAgICAgICAgICAgICB1c2VRdWF0ZXJuaW9uID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoID0gQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGguUk9UQVRJT047XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFwiaW5mbHVlbmNlXCI6IHtcclxuICAgICAgICAgICAgICAgIGRhdGFBY2Nlc3NvclR5cGUgPSBBY2Nlc3NvclR5cGUuU0NBTEFSO1xyXG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGggPSBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aC5XRUlHSFRTO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZGVmYXVsdDoge1xyXG4gICAgICAgICAgICAgICAgVG9vbHMuRXJyb3IoYFVuc3VwcG9ydGVkIGFuaW1hdGFibGUgcHJvcGVydHkgJHtwcm9wZXJ0eVswXX1gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHsgYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGg6IGFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLCBkYXRhQWNjZXNzb3JUeXBlOiBkYXRhQWNjZXNzb3JUeXBlLCB1c2VRdWF0ZXJuaW9uOiB1c2VRdWF0ZXJuaW9uIH07XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgVG9vbHMuRXJyb3IoXCJhbmltYXRpb24gY2hhbm5lbCB0YXJnZXQgcGF0aCBhbmQgZGF0YSBhY2Nlc3NvciB0eXBlIGNvdWxkIGJlIGRlZHVjZWRcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICogQ3JlYXRlIG5vZGUgYW5pbWF0aW9ucyBmcm9tIHRoZSB0cmFuc2Zvcm0gbm9kZSBhbmltYXRpb25zXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk5vZGVcclxuICAgICAqIEBwYXJhbSBydW50aW1lR0xURkFuaW1hdGlvblxyXG4gICAgICogQHBhcmFtIGlkbGVHTFRGQW5pbWF0aW9uc1xyXG4gICAgICogQHBhcmFtIG5vZGVNYXBcclxuICAgICAqIEBwYXJhbSBub2Rlc1xyXG4gICAgICogQHBhcmFtIGJpbmFyeVdyaXRlclxyXG4gICAgICogQHBhcmFtIGJ1ZmZlclZpZXdzXHJcbiAgICAgKiBAcGFyYW0gYWNjZXNzb3JzXHJcbiAgICAgKiBAcGFyYW0gYW5pbWF0aW9uU2FtcGxlUmF0ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIF9DcmVhdGVOb2RlQW5pbWF0aW9uRnJvbU5vZGVBbmltYXRpb25zKFxyXG4gICAgICAgIGJhYnlsb25Ob2RlOiBOb2RlLFxyXG4gICAgICAgIHJ1bnRpbWVHTFRGQW5pbWF0aW9uOiBJQW5pbWF0aW9uLFxyXG4gICAgICAgIGlkbGVHTFRGQW5pbWF0aW9uczogSUFuaW1hdGlvbltdLFxyXG4gICAgICAgIG5vZGVNYXA6IHsgW2tleTogbnVtYmVyXTogbnVtYmVyIH0sXHJcbiAgICAgICAgbm9kZXM6IElOb2RlW10sXHJcbiAgICAgICAgYmluYXJ5V3JpdGVyOiBfQmluYXJ5V3JpdGVyLFxyXG4gICAgICAgIGJ1ZmZlclZpZXdzOiBJQnVmZmVyVmlld1tdLFxyXG4gICAgICAgIGFjY2Vzc29yczogSUFjY2Vzc29yW10sXHJcbiAgICAgICAgYW5pbWF0aW9uU2FtcGxlUmF0ZTogbnVtYmVyLFxyXG4gICAgICAgIHNob3VsZEV4cG9ydEFuaW1hdGlvbj86IChhbmltYXRpb246IEFuaW1hdGlvbikgPT4gYm9vbGVhblxyXG4gICAgKSB7XHJcbiAgICAgICAgbGV0IGdsVEZBbmltYXRpb246IElBbmltYXRpb247XHJcbiAgICAgICAgaWYgKF9HTFRGQW5pbWF0aW9uLl9Jc1RyYW5zZm9ybWFibGUoYmFieWxvbk5vZGUpKSB7XHJcbiAgICAgICAgICAgIGlmIChiYWJ5bG9uTm9kZS5hbmltYXRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGFuaW1hdGlvbiBvZiBiYWJ5bG9uTm9kZS5hbmltYXRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNob3VsZEV4cG9ydEFuaW1hdGlvbiAmJiAhc2hvdWxkRXhwb3J0QW5pbWF0aW9uKGFuaW1hdGlvbikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFuaW1hdGlvbkluZm8gPSBfR0xURkFuaW1hdGlvbi5fRGVkdWNlQW5pbWF0aW9uSW5mbyhhbmltYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhbmltYXRpb25JbmZvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGdsVEZBbmltYXRpb24gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBhbmltYXRpb24ubmFtZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZXJzOiBbXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzOiBbXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX0dMVEZBbmltYXRpb24uX0FkZEFuaW1hdGlvbihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAke2FuaW1hdGlvbi5uYW1lfWAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24uaGFzUnVubmluZ1J1bnRpbWVBbmltYXRpb25zID8gcnVudGltZUdMVEZBbmltYXRpb24gOiBnbFRGQW5pbWF0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbk5vZGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25JbmZvLmRhdGFBY2Nlc3NvclR5cGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25JbmZvLmFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZU1hcCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmFyeVdyaXRlcixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclZpZXdzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3JzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uSW5mby51c2VRdWF0ZXJuaW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uU2FtcGxlUmF0ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2xURkFuaW1hdGlvbi5zYW1wbGVycy5sZW5ndGggJiYgZ2xURkFuaW1hdGlvbi5jaGFubmVscy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkbGVHTFRGQW5pbWF0aW9ucy5wdXNoKGdsVEZBbmltYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICogQ3JlYXRlIGluZGl2aWR1YWwgbW9ycGggYW5pbWF0aW9ucyBmcm9tIHRoZSBtZXNoJ3MgbW9ycGggdGFyZ2V0IGFuaW1hdGlvbiB0cmFja3NcclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uTm9kZVxyXG4gICAgICogQHBhcmFtIHJ1bnRpbWVHTFRGQW5pbWF0aW9uXHJcbiAgICAgKiBAcGFyYW0gaWRsZUdMVEZBbmltYXRpb25zXHJcbiAgICAgKiBAcGFyYW0gbm9kZU1hcFxyXG4gICAgICogQHBhcmFtIG5vZGVzXHJcbiAgICAgKiBAcGFyYW0gYmluYXJ5V3JpdGVyXHJcbiAgICAgKiBAcGFyYW0gYnVmZmVyVmlld3NcclxuICAgICAqIEBwYXJhbSBhY2Nlc3NvcnNcclxuICAgICAqIEBwYXJhbSBhbmltYXRpb25TYW1wbGVSYXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgX0NyZWF0ZU1vcnBoVGFyZ2V0QW5pbWF0aW9uRnJvbU1vcnBoVGFyZ2V0QW5pbWF0aW9ucyhcclxuICAgICAgICBiYWJ5bG9uTm9kZTogTm9kZSxcclxuICAgICAgICBydW50aW1lR0xURkFuaW1hdGlvbjogSUFuaW1hdGlvbixcclxuICAgICAgICBpZGxlR0xURkFuaW1hdGlvbnM6IElBbmltYXRpb25bXSxcclxuICAgICAgICBub2RlTWFwOiB7IFtrZXk6IG51bWJlcl06IG51bWJlciB9LFxyXG4gICAgICAgIG5vZGVzOiBJTm9kZVtdLFxyXG4gICAgICAgIGJpbmFyeVdyaXRlcjogX0JpbmFyeVdyaXRlcixcclxuICAgICAgICBidWZmZXJWaWV3czogSUJ1ZmZlclZpZXdbXSxcclxuICAgICAgICBhY2Nlc3NvcnM6IElBY2Nlc3NvcltdLFxyXG4gICAgICAgIGFuaW1hdGlvblNhbXBsZVJhdGU6IG51bWJlcixcclxuICAgICAgICBzaG91bGRFeHBvcnRBbmltYXRpb24/OiAoYW5pbWF0aW9uOiBBbmltYXRpb24pID0+IGJvb2xlYW5cclxuICAgICkge1xyXG4gICAgICAgIGxldCBnbFRGQW5pbWF0aW9uOiBJQW5pbWF0aW9uO1xyXG4gICAgICAgIGlmIChiYWJ5bG9uTm9kZSBpbnN0YW5jZW9mIE1lc2gpIHtcclxuICAgICAgICAgICAgY29uc3QgbW9ycGhUYXJnZXRNYW5hZ2VyID0gYmFieWxvbk5vZGUubW9ycGhUYXJnZXRNYW5hZ2VyO1xyXG4gICAgICAgICAgICBpZiAobW9ycGhUYXJnZXRNYW5hZ2VyKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1vcnBoVGFyZ2V0TWFuYWdlci5udW1UYXJnZXRzOyArK2kpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBtb3JwaFRhcmdldCA9IG1vcnBoVGFyZ2V0TWFuYWdlci5nZXRUYXJnZXQoaSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBhbmltYXRpb24gb2YgbW9ycGhUYXJnZXQuYW5pbWF0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2hvdWxkRXhwb3J0QW5pbWF0aW9uICYmICFzaG91bGRFeHBvcnRBbmltYXRpb24oYW5pbWF0aW9uKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29tYmluZWRBbmltYXRpb24gPSBuZXcgQW5pbWF0aW9uKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYCR7YW5pbWF0aW9uLm5hbWV9YCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiaW5mbHVlbmNlXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24uZnJhbWVQZXJTZWNvbmQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24uZGF0YVR5cGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24ubG9vcE1vZGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24uZW5hYmxlQmxlbmRpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29tYmluZWRBbmltYXRpb25LZXlzOiBJQW5pbWF0aW9uS2V5W10gPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYW5pbWF0aW9uS2V5cyA9IGFuaW1hdGlvbi5nZXRLZXlzKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGFuaW1hdGlvbktleXMubGVuZ3RoOyArK2opIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFuaW1hdGlvbktleSA9IGFuaW1hdGlvbktleXNbal07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG1vcnBoVGFyZ2V0TWFuYWdlci5udW1UYXJnZXRzOyArK2spIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoayA9PSBpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbWJpbmVkQW5pbWF0aW9uS2V5cy5wdXNoKGFuaW1hdGlvbktleSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tYmluZWRBbmltYXRpb25LZXlzLnB1c2goeyBmcmFtZTogYW5pbWF0aW9uS2V5LmZyYW1lLCB2YWx1ZTogMCB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY29tYmluZWRBbmltYXRpb24uc2V0S2V5cyhjb21iaW5lZEFuaW1hdGlvbktleXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhbmltYXRpb25JbmZvID0gX0dMVEZBbmltYXRpb24uX0RlZHVjZUFuaW1hdGlvbkluZm8oY29tYmluZWRBbmltYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW5pbWF0aW9uSW5mbykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xURkFuaW1hdGlvbiA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBjb21iaW5lZEFuaW1hdGlvbi5uYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZXJzOiBbXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsczogW10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX0dMVEZBbmltYXRpb24uX0FkZEFuaW1hdGlvbihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24ubmFtZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24uaGFzUnVubmluZ1J1bnRpbWVBbmltYXRpb25zID8gcnVudGltZUdMVEZBbmltYXRpb24gOiBnbFRGQW5pbWF0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25Ob2RlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbWJpbmVkQW5pbWF0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbkluZm8uZGF0YUFjY2Vzc29yVHlwZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25JbmZvLmFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVNYXAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmluYXJ5V3JpdGVyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclZpZXdzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzc29ycyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25JbmZvLnVzZVF1YXRlcm5pb24sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uU2FtcGxlUmF0ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3JwaFRhcmdldE1hbmFnZXIubnVtVGFyZ2V0c1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnbFRGQW5pbWF0aW9uLnNhbXBsZXJzLmxlbmd0aCAmJiBnbFRGQW5pbWF0aW9uLmNoYW5uZWxzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkbGVHTFRGQW5pbWF0aW9ucy5wdXNoKGdsVEZBbmltYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKiBDcmVhdGUgbm9kZSBhbmQgbW9ycGggYW5pbWF0aW9ucyBmcm9tIHRoZSBhbmltYXRpb24gZ3JvdXBzXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvblNjZW5lXHJcbiAgICAgKiBAcGFyYW0gZ2xURkFuaW1hdGlvbnNcclxuICAgICAqIEBwYXJhbSBub2RlTWFwXHJcbiAgICAgKiBAcGFyYW0gbm9kZXNcclxuICAgICAqIEBwYXJhbSBiaW5hcnlXcml0ZXJcclxuICAgICAqIEBwYXJhbSBidWZmZXJWaWV3c1xyXG4gICAgICogQHBhcmFtIGFjY2Vzc29yc1xyXG4gICAgICogQHBhcmFtIGFuaW1hdGlvblNhbXBsZVJhdGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBfQ3JlYXRlTm9kZUFuZE1vcnBoQW5pbWF0aW9uRnJvbUFuaW1hdGlvbkdyb3VwcyhcclxuICAgICAgICBiYWJ5bG9uU2NlbmU6IFNjZW5lLFxyXG4gICAgICAgIGdsVEZBbmltYXRpb25zOiBJQW5pbWF0aW9uW10sXHJcbiAgICAgICAgbm9kZU1hcDogeyBba2V5OiBudW1iZXJdOiBudW1iZXIgfSxcclxuICAgICAgICBiaW5hcnlXcml0ZXI6IF9CaW5hcnlXcml0ZXIsXHJcbiAgICAgICAgYnVmZmVyVmlld3M6IElCdWZmZXJWaWV3W10sXHJcbiAgICAgICAgYWNjZXNzb3JzOiBJQWNjZXNzb3JbXSxcclxuICAgICAgICBhbmltYXRpb25TYW1wbGVSYXRlOiBudW1iZXIsXHJcbiAgICAgICAgc2hvdWxkRXhwb3J0QW5pbWF0aW9uPzogKGFuaW1hdGlvbjogQW5pbWF0aW9uKSA9PiBib29sZWFuXHJcbiAgICApIHtcclxuICAgICAgICBsZXQgZ2xURkFuaW1hdGlvbjogSUFuaW1hdGlvbjtcclxuICAgICAgICBpZiAoYmFieWxvblNjZW5lLmFuaW1hdGlvbkdyb3Vwcykge1xyXG4gICAgICAgICAgICBjb25zdCBhbmltYXRpb25Hcm91cHMgPSBiYWJ5bG9uU2NlbmUuYW5pbWF0aW9uR3JvdXBzO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGFuaW1hdGlvbkdyb3VwIG9mIGFuaW1hdGlvbkdyb3Vwcykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbW9ycGhBbmltYXRpb25zOiBNYXA8TWVzaCwgTWFwPE1vcnBoVGFyZ2V0LCBBbmltYXRpb24+PiA9IG5ldyBNYXAoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNhbXBsZUFuaW1hdGlvbnM6IE1hcDxNZXNoLCBBbmltYXRpb24+ID0gbmV3IE1hcCgpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbW9ycGhBbmltYXRpb25NZXNoZXM6IFNldDxNZXNoPiA9IG5ldyBTZXQoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGFuaW1hdGlvbkdyb3VwRnJhbWVEaWZmID0gYW5pbWF0aW9uR3JvdXAudG8gLSBhbmltYXRpb25Hcm91cC5mcm9tO1xyXG4gICAgICAgICAgICAgICAgZ2xURkFuaW1hdGlvbiA9IHtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBhbmltYXRpb25Hcm91cC5uYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzOiBbXSxcclxuICAgICAgICAgICAgICAgICAgICBzYW1wbGVyczogW10sXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhbmltYXRpb25Hcm91cC50YXJnZXRlZEFuaW1hdGlvbnMubGVuZ3RoOyArK2kpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXRBbmltYXRpb24gPSBhbmltYXRpb25Hcm91cC50YXJnZXRlZEFuaW1hdGlvbnNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gdGFyZ2V0QW5pbWF0aW9uLnRhcmdldDtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBhbmltYXRpb24gPSB0YXJnZXRBbmltYXRpb24uYW5pbWF0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzaG91bGRFeHBvcnRBbmltYXRpb24gJiYgIXNob3VsZEV4cG9ydEFuaW1hdGlvbihhbmltYXRpb24pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fSXNUcmFuc2Zvcm1hYmxlKHRhcmdldCkgfHwgKHRhcmdldC5sZW5ndGggPT09IDEgJiYgdGhpcy5fSXNUcmFuc2Zvcm1hYmxlKHRhcmdldFswXSkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFuaW1hdGlvbkluZm8gPSBfR0xURkFuaW1hdGlvbi5fRGVkdWNlQW5pbWF0aW9uSW5mbyh0YXJnZXRBbmltYXRpb24uYW5pbWF0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFuaW1hdGlvbkluZm8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJhYnlsb25UcmFuc2Zvcm1Ob2RlID0gdGhpcy5fSXNUcmFuc2Zvcm1hYmxlKHRhcmdldCkgPyB0YXJnZXQgOiB0aGlzLl9Jc1RyYW5zZm9ybWFibGUodGFyZ2V0WzBdKSA/IHRhcmdldFswXSA6IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmFieWxvblRyYW5zZm9ybU5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfR0xURkFuaW1hdGlvbi5fQWRkQW5pbWF0aW9uKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgJHthbmltYXRpb24ubmFtZX1gLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRGQW5pbWF0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uVHJhbnNmb3JtTm9kZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25JbmZvLmRhdGFBY2Nlc3NvclR5cGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbkluZm8uYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVNYXAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmFyeVdyaXRlcixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyVmlld3MsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzc29ycyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uSW5mby51c2VRdWF0ZXJuaW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25TYW1wbGVSYXRlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0IGluc3RhbmNlb2YgTW9ycGhUYXJnZXQgfHwgKHRhcmdldC5sZW5ndGggPT09IDEgJiYgdGFyZ2V0WzBdIGluc3RhbmNlb2YgTW9ycGhUYXJnZXQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFuaW1hdGlvbkluZm8gPSBfR0xURkFuaW1hdGlvbi5fRGVkdWNlQW5pbWF0aW9uSW5mbyh0YXJnZXRBbmltYXRpb24uYW5pbWF0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFuaW1hdGlvbkluZm8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJhYnlsb25Nb3JwaFRhcmdldCA9IHRhcmdldCBpbnN0YW5jZW9mIE1vcnBoVGFyZ2V0ID8gKHRhcmdldCBhcyBNb3JwaFRhcmdldCkgOiAodGFyZ2V0WzBdIGFzIE1vcnBoVGFyZ2V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTW9ycGhUYXJnZXQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uTW9ycGhUYXJnZXRNYW5hZ2VyID0gYmFieWxvblNjZW5lLm1vcnBoVGFyZ2V0TWFuYWdlcnMuZmluZCgobW9ycGhUYXJnZXRNYW5hZ2VyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbW9ycGhUYXJnZXRNYW5hZ2VyLm51bVRhcmdldHM7ICsraikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1vcnBoVGFyZ2V0TWFuYWdlci5nZXRUYXJnZXQoaikgPT09IGJhYnlsb25Nb3JwaFRhcmdldCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk1vcnBoVGFyZ2V0TWFuYWdlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uTWVzaCA9IGJhYnlsb25TY2VuZS5tZXNoZXMuZmluZCgobWVzaCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChtZXNoIGFzIE1lc2gpLm1vcnBoVGFyZ2V0TWFuYWdlciA9PT0gYmFieWxvbk1vcnBoVGFyZ2V0TWFuYWdlcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkgYXMgTWVzaDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJhYnlsb25NZXNoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1vcnBoQW5pbWF0aW9ucy5oYXMoYmFieWxvbk1lc2gpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9ycGhBbmltYXRpb25zLnNldChiYWJ5bG9uTWVzaCwgbmV3IE1hcCgpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vcnBoQW5pbWF0aW9ucy5nZXQoYmFieWxvbk1lc2gpPy5zZXQoYmFieWxvbk1vcnBoVGFyZ2V0LCBhbmltYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9ycGhBbmltYXRpb25NZXNoZXMuYWRkKGJhYnlsb25NZXNoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZUFuaW1hdGlvbnMuc2V0KGJhYnlsb25NZXNoLCBhbmltYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBpcyB0aGUgcGxhY2UgZm9yIHRoZSBLSFJfYW5pbWF0aW9uX3BvaW50ZXIuXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbW9ycGhBbmltYXRpb25NZXNoZXMuZm9yRWFjaCgobWVzaCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1vcnBoVGFyZ2V0TWFuYWdlciA9IG1lc2gubW9ycGhUYXJnZXRNYW5hZ2VyITtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgY29tYmluZWRBbmltYXRpb25Hcm91cDogTnVsbGFibGU8QW5pbWF0aW9uPiA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYW5pbWF0aW9uS2V5czogSUFuaW1hdGlvbktleVtdID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2FtcGxlQW5pbWF0aW9uID0gc2FtcGxlQW5pbWF0aW9ucy5nZXQobWVzaCkhO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNhbXBsZUFuaW1hdGlvbktleXMgPSBzYW1wbGVBbmltYXRpb24uZ2V0S2V5cygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bUFuaW1hdGlvbktleXMgPSBzYW1wbGVBbmltYXRpb25LZXlzLmxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAvKlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBEdWUgdG8gaG93IGdsVEYgZXhwZWN0cyBtb3JwaCB0YXJnZXQgYW5pbWF0aW9uIGRhdGEgdG8gYmUgZm9ybWF0dGVkLCB3ZSBuZWVkIHRvIHJlYXJyYW5nZSB0aGUgaW5kaXZpZHVhbCBtb3JwaCB0YXJnZXQgYW5pbWF0aW9uIHRyYWNrcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3VjaCB0aGF0IHdlIGhhdmUgYSBzaW5nbGUgYW5pbWF0aW9uLCB3aGVyZSBhIGdpdmVuIGtleWZyYW1lIGlucHV0IHZhbHVlIGhhcyBzdWNjZXNzaXZlIG91dHB1dCB2YWx1ZXMgZm9yIGVhY2ggbW9ycGggdGFyZ2V0IGJlbG9uZ2luZyB0byB0aGUgbWFuYWdlci5cclxuICAgICAgICAgICAgICAgICAgICAgICAgU2VlOiBodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvdHJlZS9tYXN0ZXIvc3BlY2lmaWNhdGlvbi8yLjAjYW5pbWF0aW9uc1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgV2UgZG8gdGhpcyB2aWEgY29uc3RydWN0aW5nIGEgbmV3IEFuaW1hdGlvbiB0cmFjaywgYW5kIGludGVybGVhdmluZyB0aGUgZnJhbWVzIG9mIGVhY2ggbW9ycGggdGFyZ2V0IGFuaW1hdGlvbiB0cmFjayBpbiB0aGUgY3VycmVudCBBbmltYXRpb24gR3JvdXBcclxuICAgICAgICAgICAgICAgICAgICAgICAgV2UgcmV1c2UgdGhlIEJhYnlsb24gQW5pbWF0aW9uIGRhdGEgc3RydWN0dXJlIGZvciBlYXNlIG9mIGhhbmRsaW5nIGV4cG9ydCBvZiBjdWJpYyBzcGxpbmUgYW5pbWF0aW9uIGtleXMsIGFuZCB0byByZXVzZSB0aGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcgX0dMVEZBbmltYXRpb24uQWRkQW5pbWF0aW9uIGNvZGVwYXRoIHdpdGggbWluaW1hbCBtb2RpZmljYXRpb24sIGhvd2V2ZXIgdGhlIGNvbnN0cnVjdGVkIEJhYnlsb24gQW5pbWF0aW9uIGlzIE5PVCBpbnRlbmRlZCBmb3IgdXNlIGluLWVuZ2luZS5cclxuICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtQW5pbWF0aW9uS2V5czsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbW9ycGhUYXJnZXRNYW5hZ2VyLm51bVRhcmdldHM7ICsraikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbW9ycGhUYXJnZXQgPSBtb3JwaFRhcmdldE1hbmFnZXIuZ2V0VGFyZ2V0KGopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYW5pbWF0aW9uc0J5TW9ycGhUYXJnZXQgPSBtb3JwaEFuaW1hdGlvbnMuZ2V0KG1lc2gpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFuaW1hdGlvbnNCeU1vcnBoVGFyZ2V0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbW9ycGhUYXJnZXRBbmltYXRpb24gPSBhbmltYXRpb25zQnlNb3JwaFRhcmdldC5nZXQobW9ycGhUYXJnZXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtb3JwaFRhcmdldEFuaW1hdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbWJpbmVkQW5pbWF0aW9uR3JvdXApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbWJpbmVkQW5pbWF0aW9uR3JvdXAgPSBuZXcgQW5pbWF0aW9uKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAke2FuaW1hdGlvbkdyb3VwLm5hbWV9XyR7bWVzaC5uYW1lfV9Nb3JwaFdlaWdodEFuaW1hdGlvbmAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJpbmZsdWVuY2VcIixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3JwaFRhcmdldEFuaW1hdGlvbi5mcmFtZVBlclNlY29uZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3JwaFRhcmdldEFuaW1hdGlvbi5sb29wTW9kZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3JwaFRhcmdldEFuaW1hdGlvbi5lbmFibGVCbGVuZGluZ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25LZXlzLnB1c2gobW9ycGhUYXJnZXRBbmltYXRpb24uZ2V0S2V5cygpW2ldKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25LZXlzLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWU6IGFuaW1hdGlvbkdyb3VwLmZyb20gKyAoYW5pbWF0aW9uR3JvdXBGcmFtZURpZmYgLyBudW1BbmltYXRpb25LZXlzKSAqIGksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogbW9ycGhUYXJnZXQuaW5mbHVlbmNlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5UYW5nZW50OiBzYW1wbGVBbmltYXRpb25LZXlzWzBdLmluVGFuZ2VudCA/IDAgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRUYW5nZW50OiBzYW1wbGVBbmltYXRpb25LZXlzWzBdLm91dFRhbmdlbnQgPyAwIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY29tYmluZWRBbmltYXRpb25Hcm91cCEuc2V0S2V5cyhhbmltYXRpb25LZXlzKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBhbmltYXRpb25JbmZvID0gX0dMVEZBbmltYXRpb24uX0RlZHVjZUFuaW1hdGlvbkluZm8oY29tYmluZWRBbmltYXRpb25Hcm91cCEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhbmltYXRpb25JbmZvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9HTFRGQW5pbWF0aW9uLl9BZGRBbmltYXRpb24oXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgJHthbmltYXRpb25Hcm91cC5uYW1lfV8ke21lc2gubmFtZX1fTW9ycGhXZWlnaHRBbmltYXRpb25gLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xURkFuaW1hdGlvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc2gsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21iaW5lZEFuaW1hdGlvbkdyb3VwISxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbkluZm8uZGF0YUFjY2Vzc29yVHlwZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbkluZm8uYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlTWFwLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYmluYXJ5V3JpdGVyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyVmlld3MsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3NvcnMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25JbmZvLnVzZVF1YXRlcm5pb24sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25TYW1wbGVSYXRlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9ycGhUYXJnZXRNYW5hZ2VyPy5udW1UYXJnZXRzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZ2xURkFuaW1hdGlvbi5jaGFubmVscy5sZW5ndGggJiYgZ2xURkFuaW1hdGlvbi5zYW1wbGVycy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICBnbFRGQW5pbWF0aW9ucy5wdXNoKGdsVEZBbmltYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIF9BZGRBbmltYXRpb24oXHJcbiAgICAgICAgbmFtZTogc3RyaW5nLFxyXG4gICAgICAgIGdsVEZBbmltYXRpb246IElBbmltYXRpb24sXHJcbiAgICAgICAgYmFieWxvblRyYW5zZm9ybU5vZGU6IE5vZGUsXHJcbiAgICAgICAgYW5pbWF0aW9uOiBBbmltYXRpb24sXHJcbiAgICAgICAgZGF0YUFjY2Vzc29yVHlwZTogQWNjZXNzb3JUeXBlLFxyXG4gICAgICAgIGFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoOiBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCxcclxuICAgICAgICBub2RlTWFwOiB7IFtrZXk6IG51bWJlcl06IG51bWJlciB9LFxyXG4gICAgICAgIGJpbmFyeVdyaXRlcjogX0JpbmFyeVdyaXRlcixcclxuICAgICAgICBidWZmZXJWaWV3czogSUJ1ZmZlclZpZXdbXSxcclxuICAgICAgICBhY2Nlc3NvcnM6IElBY2Nlc3NvcltdLFxyXG4gICAgICAgIHVzZVF1YXRlcm5pb246IGJvb2xlYW4sXHJcbiAgICAgICAgYW5pbWF0aW9uU2FtcGxlUmF0ZTogbnVtYmVyLFxyXG4gICAgICAgIG1vcnBoQW5pbWF0aW9uQ2hhbm5lbHM/OiBudW1iZXJcclxuICAgICkge1xyXG4gICAgICAgIGNvbnN0IGFuaW1hdGlvbkRhdGEgPSBfR0xURkFuaW1hdGlvbi5fQ3JlYXRlTm9kZUFuaW1hdGlvbihiYWJ5bG9uVHJhbnNmb3JtTm9kZSwgYW5pbWF0aW9uLCBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCwgdXNlUXVhdGVybmlvbiwgYW5pbWF0aW9uU2FtcGxlUmF0ZSk7XHJcbiAgICAgICAgbGV0IGJ1ZmZlclZpZXc6IElCdWZmZXJWaWV3O1xyXG4gICAgICAgIGxldCBhY2Nlc3NvcjogSUFjY2Vzc29yO1xyXG4gICAgICAgIGxldCBrZXlmcmFtZUFjY2Vzc29ySW5kZXg6IG51bWJlcjtcclxuICAgICAgICBsZXQgZGF0YUFjY2Vzc29ySW5kZXg6IG51bWJlcjtcclxuICAgICAgICBsZXQgb3V0cHV0TGVuZ3RoOiBudW1iZXI7XHJcbiAgICAgICAgbGV0IGFuaW1hdGlvblNhbXBsZXI6IElBbmltYXRpb25TYW1wbGVyO1xyXG4gICAgICAgIGxldCBhbmltYXRpb25DaGFubmVsOiBJQW5pbWF0aW9uQ2hhbm5lbDtcclxuXHJcbiAgICAgICAgaWYgKGFuaW1hdGlvbkRhdGEpIHtcclxuICAgICAgICAgICAgLypcclxuICAgICAgICAgICAgICogTm93IHRoYXQgd2UgaGF2ZSB0aGUgZ2xURiBjb252ZXJ0ZWQgbW9ycGggdGFyZ2V0IGFuaW1hdGlvbiBkYXRhLFxyXG4gICAgICAgICAgICAgKiB3ZSBjYW4gcmVtb3ZlIHJlZHVuZGFudCBpbnB1dCBkYXRhIHNvIHRoYXQgd2UgaGF2ZSBuIGlucHV0IGZyYW1lcyxcclxuICAgICAgICAgICAgICogYW5kIG1vcnBoQW5pbWF0aW9uQ2hhbm5lbHMgKiBuIG91dHB1dCBmcmFtZXNcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGlmIChtb3JwaEFuaW1hdGlvbkNoYW5uZWxzKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgaW5kZXggPSAwO1xyXG4gICAgICAgICAgICAgICAgbGV0IGN1cnJlbnRJbnB1dDogbnVtYmVyID0gMDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5ld0lucHV0czogbnVtYmVyW10gPSBbXTtcclxuICAgICAgICAgICAgICAgIHdoaWxlIChhbmltYXRpb25EYXRhLmlucHV0cy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudElucHV0ID0gYW5pbWF0aW9uRGF0YS5pbnB1dHMuc2hpZnQoKSE7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ICUgbW9ycGhBbmltYXRpb25DaGFubmVscyA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0lucHV0cy5wdXNoKGN1cnJlbnRJbnB1dCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGluZGV4Kys7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBhbmltYXRpb25EYXRhLmlucHV0cyA9IG5ld0lucHV0cztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3Qgbm9kZUluZGV4ID0gbm9kZU1hcFtiYWJ5bG9uVHJhbnNmb3JtTm9kZS51bmlxdWVJZF07XHJcblxyXG4gICAgICAgICAgICAvLyBDcmVhdGVzIGJ1ZmZlciB2aWV3IGFuZCBhY2Nlc3NvciBmb3Iga2V5IGZyYW1lcy5cclxuICAgICAgICAgICAgbGV0IGJ5dGVMZW5ndGggPSBhbmltYXRpb25EYXRhLmlucHV0cy5sZW5ndGggKiA0O1xyXG4gICAgICAgICAgICBidWZmZXJWaWV3ID0gX0dMVEZVdGlsaXRpZXMuX0NyZWF0ZUJ1ZmZlclZpZXcoMCwgYmluYXJ5V3JpdGVyLmdldEJ5dGVPZmZzZXQoKSwgYnl0ZUxlbmd0aCwgdW5kZWZpbmVkLCBgJHtuYW1lfSAga2V5ZnJhbWUgZGF0YSB2aWV3YCk7XHJcbiAgICAgICAgICAgIGJ1ZmZlclZpZXdzLnB1c2goYnVmZmVyVmlldyk7XHJcbiAgICAgICAgICAgIGFuaW1hdGlvbkRhdGEuaW5wdXRzLmZvckVhY2goZnVuY3Rpb24gKGlucHV0KSB7XHJcbiAgICAgICAgICAgICAgICBiaW5hcnlXcml0ZXIuc2V0RmxvYXQzMihpbnB1dCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgYWNjZXNzb3IgPSBfR0xURlV0aWxpdGllcy5fQ3JlYXRlQWNjZXNzb3IoXHJcbiAgICAgICAgICAgICAgICBidWZmZXJWaWV3cy5sZW5ndGggLSAxLFxyXG4gICAgICAgICAgICAgICAgYCR7bmFtZX0gIGtleWZyYW1lc2AsXHJcbiAgICAgICAgICAgICAgICBBY2Nlc3NvclR5cGUuU0NBTEFSLFxyXG4gICAgICAgICAgICAgICAgQWNjZXNzb3JDb21wb25lbnRUeXBlLkZMT0FULFxyXG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uRGF0YS5pbnB1dHMubGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgbnVsbCxcclxuICAgICAgICAgICAgICAgIFthbmltYXRpb25EYXRhLmlucHV0c01pbl0sXHJcbiAgICAgICAgICAgICAgICBbYW5pbWF0aW9uRGF0YS5pbnB1dHNNYXhdXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIGFjY2Vzc29ycy5wdXNoKGFjY2Vzc29yKTtcclxuICAgICAgICAgICAga2V5ZnJhbWVBY2Nlc3NvckluZGV4ID0gYWNjZXNzb3JzLmxlbmd0aCAtIDE7XHJcblxyXG4gICAgICAgICAgICAvLyBjcmVhdGUgYnVmZmVydmlldyBhbmQgYWNjZXNzb3IgZm9yIGtleWVkIHZhbHVlcy5cclxuICAgICAgICAgICAgb3V0cHV0TGVuZ3RoID0gYW5pbWF0aW9uRGF0YS5vdXRwdXRzLmxlbmd0aDtcclxuICAgICAgICAgICAgYnl0ZUxlbmd0aCA9IF9HTFRGVXRpbGl0aWVzLl9HZXREYXRhQWNjZXNzb3JFbGVtZW50Q291bnQoZGF0YUFjY2Vzc29yVHlwZSkgKiA0ICogYW5pbWF0aW9uRGF0YS5vdXRwdXRzLmxlbmd0aDtcclxuXHJcbiAgICAgICAgICAgIC8vIGNoZWNrIGZvciBpbiBhbmQgb3V0IHRhbmdlbnRzXHJcbiAgICAgICAgICAgIGJ1ZmZlclZpZXcgPSBfR0xURlV0aWxpdGllcy5fQ3JlYXRlQnVmZmVyVmlldygwLCBiaW5hcnlXcml0ZXIuZ2V0Qnl0ZU9mZnNldCgpLCBieXRlTGVuZ3RoLCB1bmRlZmluZWQsIGAke25hbWV9ICBkYXRhIHZpZXdgKTtcclxuICAgICAgICAgICAgYnVmZmVyVmlld3MucHVzaChidWZmZXJWaWV3KTtcclxuXHJcbiAgICAgICAgICAgIGFuaW1hdGlvbkRhdGEub3V0cHV0cy5mb3JFYWNoKGZ1bmN0aW9uIChvdXRwdXQpIHtcclxuICAgICAgICAgICAgICAgIG91dHB1dC5mb3JFYWNoKGZ1bmN0aW9uIChlbnRyeSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJpbmFyeVdyaXRlci5zZXRGbG9hdDMyKGVudHJ5KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGFjY2Vzc29yID0gX0dMVEZVdGlsaXRpZXMuX0NyZWF0ZUFjY2Vzc29yKGJ1ZmZlclZpZXdzLmxlbmd0aCAtIDEsIGAke25hbWV9ICBkYXRhYCwgZGF0YUFjY2Vzc29yVHlwZSwgQWNjZXNzb3JDb21wb25lbnRUeXBlLkZMT0FULCBvdXRwdXRMZW5ndGgsIG51bGwsIG51bGwsIG51bGwpO1xyXG4gICAgICAgICAgICBhY2Nlc3NvcnMucHVzaChhY2Nlc3Nvcik7XHJcbiAgICAgICAgICAgIGRhdGFBY2Nlc3NvckluZGV4ID0gYWNjZXNzb3JzLmxlbmd0aCAtIDE7XHJcblxyXG4gICAgICAgICAgICAvLyBjcmVhdGUgc2FtcGxlclxyXG4gICAgICAgICAgICBhbmltYXRpb25TYW1wbGVyID0ge1xyXG4gICAgICAgICAgICAgICAgaW50ZXJwb2xhdGlvbjogYW5pbWF0aW9uRGF0YS5zYW1wbGVySW50ZXJwb2xhdGlvbixcclxuICAgICAgICAgICAgICAgIGlucHV0OiBrZXlmcmFtZUFjY2Vzc29ySW5kZXgsXHJcbiAgICAgICAgICAgICAgICBvdXRwdXQ6IGRhdGFBY2Nlc3NvckluZGV4LFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBnbFRGQW5pbWF0aW9uLnNhbXBsZXJzLnB1c2goYW5pbWF0aW9uU2FtcGxlcik7XHJcblxyXG4gICAgICAgICAgICAvLyBjcmVhdGUgY2hhbm5lbFxyXG4gICAgICAgICAgICBhbmltYXRpb25DaGFubmVsID0ge1xyXG4gICAgICAgICAgICAgICAgc2FtcGxlcjogZ2xURkFuaW1hdGlvbi5zYW1wbGVycy5sZW5ndGggLSAxLFxyXG4gICAgICAgICAgICAgICAgdGFyZ2V0OiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbm9kZTogbm9kZUluZGV4LFxyXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgZ2xURkFuaW1hdGlvbi5jaGFubmVscy5wdXNoKGFuaW1hdGlvbkNoYW5uZWwpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZSBhIGJha2VkIGFuaW1hdGlvblxyXG4gICAgICogQHBhcmFtIGJhYnlsb25UcmFuc2Zvcm1Ob2RlIEJhYnlsb25KUyBtZXNoXHJcbiAgICAgKiBAcGFyYW0gYW5pbWF0aW9uIEJhYnlsb25KUyBhbmltYXRpb24gY29ycmVzcG9uZGluZyB0byB0aGUgQmFieWxvbkpTIG1lc2hcclxuICAgICAqIEBwYXJhbSBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCBhbmltYXRpb24gdGFyZ2V0IGNoYW5uZWxcclxuICAgICAqIEBwYXJhbSBtaW5GcmFtZSBtaW5pbXVtIGFuaW1hdGlvbiBmcmFtZVxyXG4gICAgICogQHBhcmFtIG1heEZyYW1lIG1heGltdW0gYW5pbWF0aW9uIGZyYW1lXHJcbiAgICAgKiBAcGFyYW0gZnBzIGZyYW1lcyBwZXIgc2Vjb25kIG9mIHRoZSBhbmltYXRpb25cclxuICAgICAqIEBwYXJhbSBzYW1wbGVSYXRlXHJcbiAgICAgKiBAcGFyYW0gaW5wdXRzIGlucHV0IGtleSBmcmFtZXMgb2YgdGhlIGFuaW1hdGlvblxyXG4gICAgICogQHBhcmFtIG91dHB1dHMgb3V0cHV0IGtleSBmcmFtZSBkYXRhIG9mIHRoZSBhbmltYXRpb25cclxuICAgICAqIEBwYXJhbSBtaW5NYXhGcmFtZXNcclxuICAgICAqIEBwYXJhbSBtaW5NYXhGcmFtZXMubWluXHJcbiAgICAgKiBAcGFyYW0gbWluTWF4RnJhbWVzLm1heFxyXG4gICAgICogQHBhcmFtIHVzZVF1YXRlcm5pb24gc3BlY2lmaWVzIGlmIHF1YXRlcm5pb25zIHNob3VsZCBiZSB1c2VkXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIF9DcmVhdGVCYWtlZEFuaW1hdGlvbihcclxuICAgICAgICBiYWJ5bG9uVHJhbnNmb3JtTm9kZTogTm9kZSxcclxuICAgICAgICBhbmltYXRpb246IEFuaW1hdGlvbixcclxuICAgICAgICBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aDogQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgsXHJcbiAgICAgICAgbWluRnJhbWU6IG51bWJlcixcclxuICAgICAgICBtYXhGcmFtZTogbnVtYmVyLFxyXG4gICAgICAgIGZwczogbnVtYmVyLFxyXG4gICAgICAgIHNhbXBsZVJhdGU6IG51bWJlcixcclxuICAgICAgICBpbnB1dHM6IG51bWJlcltdLFxyXG4gICAgICAgIG91dHB1dHM6IG51bWJlcltdW10sXHJcbiAgICAgICAgbWluTWF4RnJhbWVzOiB7IG1pbjogbnVtYmVyOyBtYXg6IG51bWJlciB9LFxyXG4gICAgICAgIHVzZVF1YXRlcm5pb246IGJvb2xlYW5cclxuICAgICkge1xyXG4gICAgICAgIGxldCB2YWx1ZTogbnVtYmVyIHwgVmVjdG9yMyB8IFF1YXRlcm5pb247XHJcbiAgICAgICAgY29uc3QgcXVhdGVybmlvbkNhY2hlOiBRdWF0ZXJuaW9uID0gUXVhdGVybmlvbi5JZGVudGl0eSgpO1xyXG4gICAgICAgIGxldCBwcmV2aW91c1RpbWU6IE51bGxhYmxlPG51bWJlcj4gPSBudWxsO1xyXG4gICAgICAgIGxldCB0aW1lOiBudW1iZXI7XHJcbiAgICAgICAgbGV0IG1heFVzZWRGcmFtZTogTnVsbGFibGU8bnVtYmVyPiA9IG51bGw7XHJcbiAgICAgICAgbGV0IGN1cnJLZXlGcmFtZTogTnVsbGFibGU8SUFuaW1hdGlvbktleT4gPSBudWxsO1xyXG4gICAgICAgIGxldCBuZXh0S2V5RnJhbWU6IE51bGxhYmxlPElBbmltYXRpb25LZXk+ID0gbnVsbDtcclxuICAgICAgICBsZXQgcHJldktleUZyYW1lOiBOdWxsYWJsZTxJQW5pbWF0aW9uS2V5PiA9IG51bGw7XHJcbiAgICAgICAgbGV0IGVuZEZyYW1lOiBOdWxsYWJsZTxudW1iZXI+ID0gbnVsbDtcclxuICAgICAgICBtaW5NYXhGcmFtZXMubWluID0gVG9vbHMuRmxvYXRSb3VuZChtaW5GcmFtZSAvIGZwcyk7XHJcblxyXG4gICAgICAgIGNvbnN0IGtleUZyYW1lcyA9IGFuaW1hdGlvbi5nZXRLZXlzKCk7XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW5ndGggPSBrZXlGcmFtZXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyArK2kpIHtcclxuICAgICAgICAgICAgZW5kRnJhbWUgPSBudWxsO1xyXG4gICAgICAgICAgICBjdXJyS2V5RnJhbWUgPSBrZXlGcmFtZXNbaV07XHJcblxyXG4gICAgICAgICAgICBpZiAoaSArIDEgPCBsZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIG5leHRLZXlGcmFtZSA9IGtleUZyYW1lc1tpICsgMV07XHJcbiAgICAgICAgICAgICAgICBpZiAoKGN1cnJLZXlGcmFtZS52YWx1ZS5lcXVhbHMgJiYgY3VycktleUZyYW1lLnZhbHVlLmVxdWFscyhuZXh0S2V5RnJhbWUudmFsdWUpKSB8fCBjdXJyS2V5RnJhbWUudmFsdWUgPT09IG5leHRLZXlGcmFtZS52YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNldCB0aGUgZmlyc3QgZnJhbWUgdG8gaXRzZWxmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuZEZyYW1lID0gY3VycktleUZyYW1lLmZyYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZW5kRnJhbWUgPSBuZXh0S2V5RnJhbWUuZnJhbWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBhdCB0aGUgbGFzdCBrZXkgZnJhbWVcclxuICAgICAgICAgICAgICAgIHByZXZLZXlGcmFtZSA9IGtleUZyYW1lc1tpIC0gMV07XHJcbiAgICAgICAgICAgICAgICBpZiAoKGN1cnJLZXlGcmFtZS52YWx1ZS5lcXVhbHMgJiYgY3VycktleUZyYW1lLnZhbHVlLmVxdWFscyhwcmV2S2V5RnJhbWUudmFsdWUpKSB8fCBjdXJyS2V5RnJhbWUudmFsdWUgPT09IHByZXZLZXlGcmFtZS52YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBlbmRGcmFtZSA9IG1heEZyYW1lO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlbmRGcmFtZSkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgZiA9IGN1cnJLZXlGcmFtZS5mcmFtZTsgZiA8PSBlbmRGcmFtZTsgZiArPSBzYW1wbGVSYXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGltZSA9IFRvb2xzLkZsb2F0Um91bmQoZiAvIGZwcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRpbWUgPT09IHByZXZpb3VzVGltZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNUaW1lID0gdGltZTtcclxuICAgICAgICAgICAgICAgICAgICBtYXhVc2VkRnJhbWUgPSB0aW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXRlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXk6IDAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdENvdW50OiAwLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsb29wTW9kZTogYW5pbWF0aW9uLmxvb3BNb2RlLFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBhbmltYXRpb24uX2ludGVycG9sYXRlKGYsIHN0YXRlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgX0dMVEZBbmltYXRpb24uX1NldEludGVycG9sYXRlZFZhbHVlKGJhYnlsb25UcmFuc2Zvcm1Ob2RlLCB2YWx1ZSwgdGltZSwgYW5pbWF0aW9uLCBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCwgcXVhdGVybmlvbkNhY2hlLCBpbnB1dHMsIG91dHB1dHMsIHVzZVF1YXRlcm5pb24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChtYXhVc2VkRnJhbWUpIHtcclxuICAgICAgICAgICAgbWluTWF4RnJhbWVzLm1heCA9IG1heFVzZWRGcmFtZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX0NvbnZlcnRGYWN0b3JUb1ZlY3RvcjNPclF1YXRlcm5pb24oXHJcbiAgICAgICAgZmFjdG9yOiBudW1iZXIsXHJcbiAgICAgICAgYmFieWxvblRyYW5zZm9ybU5vZGU6IE5vZGUsXHJcbiAgICAgICAgYW5pbWF0aW9uOiBBbmltYXRpb24sXHJcbiAgICAgICAgYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGg6IEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLFxyXG4gICAgICAgIHVzZVF1YXRlcm5pb246IGJvb2xlYW5cclxuICAgICk6IFZlY3RvcjMgfCBRdWF0ZXJuaW9uIHtcclxuICAgICAgICBjb25zdCBiYXNlUG9zaXRpb25Sb3RhdGlvbk9yU2NhbGUgPSBfR0xURkFuaW1hdGlvbi5fR2V0QmFzZVBvc2l0aW9uUm90YXRpb25PclNjYWxlKGJhYnlsb25UcmFuc2Zvcm1Ob2RlLCBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCwgdXNlUXVhdGVybmlvbik7XHJcbiAgICAgICAgLy8gaGFuZGxlcyBzaW5nbGUgY29tcG9uZW50IHgsIHksIHogb3IgdyBjb21wb25lbnQgYW5pbWF0aW9uIGJ5IHVzaW5nIGEgYmFzZSBwcm9wZXJ0eSBhbmQgYW5pbWF0aW5nIG92ZXIgYSBjb21wb25lbnQuXHJcbiAgICAgICAgY29uc3QgcHJvcGVydHkgPSBhbmltYXRpb24udGFyZ2V0UHJvcGVydHkuc3BsaXQoXCIuXCIpO1xyXG4gICAgICAgIGNvbnN0IGNvbXBvbmVudE5hbWUgPSBwcm9wZXJ0eSA/IHByb3BlcnR5WzFdIDogXCJcIjsgLy8geCwgeSwgeiwgb3IgdyBjb21wb25lbnRcclxuICAgICAgICBjb25zdCB2YWx1ZSA9IHVzZVF1YXRlcm5pb24gPyBRdWF0ZXJuaW9uLkZyb21BcnJheShiYXNlUG9zaXRpb25Sb3RhdGlvbk9yU2NhbGUpLm5vcm1hbGl6ZSgpIDogVmVjdG9yMy5Gcm9tQXJyYXkoYmFzZVBvc2l0aW9uUm90YXRpb25PclNjYWxlKTtcclxuXHJcbiAgICAgICAgc3dpdGNoIChjb21wb25lbnROYW1lKSB7XHJcbiAgICAgICAgICAgIGNhc2UgXCJ4XCI6XHJcbiAgICAgICAgICAgIGNhc2UgXCJ5XCI6XHJcbiAgICAgICAgICAgIGNhc2UgXCJ6XCI6IHtcclxuICAgICAgICAgICAgICAgIHZhbHVlW2NvbXBvbmVudE5hbWVdID0gZmFjdG9yO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBcIndcIjoge1xyXG4gICAgICAgICAgICAgICAgKHZhbHVlIGFzIFF1YXRlcm5pb24pLncgPSBmYWN0b3I7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBkZWZhdWx0OiB7XHJcbiAgICAgICAgICAgICAgICBUb29scy5FcnJvcihgZ2xURkFuaW1hdGlvbjogVW5zdXBwb3J0ZWQgY29tcG9uZW50IG5hbWUgXCIke2NvbXBvbmVudE5hbWV9XCIhYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfU2V0SW50ZXJwb2xhdGVkVmFsdWUoXHJcbiAgICAgICAgYmFieWxvblRyYW5zZm9ybU5vZGU6IE5vZGUsXHJcbiAgICAgICAgdmFsdWU6IG51bWJlciB8IFZlY3RvcjMgfCBRdWF0ZXJuaW9uLFxyXG4gICAgICAgIHRpbWU6IG51bWJlcixcclxuICAgICAgICBhbmltYXRpb246IEFuaW1hdGlvbixcclxuICAgICAgICBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aDogQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgsXHJcbiAgICAgICAgcXVhdGVybmlvbkNhY2hlOiBRdWF0ZXJuaW9uLFxyXG4gICAgICAgIGlucHV0czogbnVtYmVyW10sXHJcbiAgICAgICAgb3V0cHV0czogbnVtYmVyW11bXSxcclxuICAgICAgICB1c2VRdWF0ZXJuaW9uOiBib29sZWFuXHJcbiAgICApIHtcclxuICAgICAgICBsZXQgY2FjaGVWYWx1ZTogVmVjdG9yMyB8IFF1YXRlcm5pb24gfCBudW1iZXI7XHJcbiAgICAgICAgaW5wdXRzLnB1c2godGltZSk7XHJcblxyXG4gICAgICAgIGlmIChhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCA9PT0gQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGguV0VJR0hUUykge1xyXG4gICAgICAgICAgICBvdXRwdXRzLnB1c2goW3ZhbHVlIGFzIG51bWJlcl0pO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoYW5pbWF0aW9uLmRhdGFUeXBlID09PSBBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCkge1xyXG4gICAgICAgICAgICB2YWx1ZSA9IHRoaXMuX0NvbnZlcnRGYWN0b3JUb1ZlY3RvcjNPclF1YXRlcm5pb24odmFsdWUgYXMgbnVtYmVyLCBiYWJ5bG9uVHJhbnNmb3JtTm9kZSwgYW5pbWF0aW9uLCBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCwgdXNlUXVhdGVybmlvbik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGggPT09IEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLlJPVEFUSU9OKSB7XHJcbiAgICAgICAgICAgIGlmICh1c2VRdWF0ZXJuaW9uKSB7XHJcbiAgICAgICAgICAgICAgICBxdWF0ZXJuaW9uQ2FjaGUgPSB2YWx1ZSBhcyBRdWF0ZXJuaW9uO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY2FjaGVWYWx1ZSA9IHZhbHVlIGFzIFZlY3RvcjM7XHJcbiAgICAgICAgICAgICAgICBRdWF0ZXJuaW9uLlJvdGF0aW9uWWF3UGl0Y2hSb2xsVG9SZWYoY2FjaGVWYWx1ZS55LCBjYWNoZVZhbHVlLngsIGNhY2hlVmFsdWUueiwgcXVhdGVybmlvbkNhY2hlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvdXRwdXRzLnB1c2gocXVhdGVybmlvbkNhY2hlLmFzQXJyYXkoKSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gc2NhbGluZyBhbmQgcG9zaXRpb24gYW5pbWF0aW9uXHJcbiAgICAgICAgICAgIGNhY2hlVmFsdWUgPSB2YWx1ZSBhcyBWZWN0b3IzO1xyXG4gICAgICAgICAgICBvdXRwdXRzLnB1c2goY2FjaGVWYWx1ZS5hc0FycmF5KCkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgbGluZWFyIGFuaW1hdGlvbiBmcm9tIHRoZSBhbmltYXRpb24ga2V5IGZyYW1lc1xyXG4gICAgICogQHBhcmFtIGJhYnlsb25UcmFuc2Zvcm1Ob2RlIEJhYnlsb25KUyBtZXNoXHJcbiAgICAgKiBAcGFyYW0gYW5pbWF0aW9uIEJhYnlsb25KUyBhbmltYXRpb25cclxuICAgICAqIEBwYXJhbSBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCBUaGUgdGFyZ2V0IGFuaW1hdGlvbiBjaGFubmVsXHJcbiAgICAgKiBAcGFyYW0gaW5wdXRzIEFycmF5IHRvIHN0b3JlIHRoZSBrZXkgZnJhbWUgdGltZXNcclxuICAgICAqIEBwYXJhbSBvdXRwdXRzIEFycmF5IHRvIHN0b3JlIHRoZSBrZXkgZnJhbWUgZGF0YVxyXG4gICAgICogQHBhcmFtIHVzZVF1YXRlcm5pb24gU3BlY2lmaWVzIGlmIHF1YXRlcm5pb25zIGFyZSB1c2VkIGluIHRoZSBhbmltYXRpb25cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX0NyZWF0ZUxpbmVhck9yU3RlcEFuaW1hdGlvbihcclxuICAgICAgICBiYWJ5bG9uVHJhbnNmb3JtTm9kZTogTm9kZSxcclxuICAgICAgICBhbmltYXRpb246IEFuaW1hdGlvbixcclxuICAgICAgICBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aDogQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgsXHJcbiAgICAgICAgaW5wdXRzOiBudW1iZXJbXSxcclxuICAgICAgICBvdXRwdXRzOiBudW1iZXJbXVtdLFxyXG4gICAgICAgIHVzZVF1YXRlcm5pb246IGJvb2xlYW5cclxuICAgICkge1xyXG4gICAgICAgIGZvciAoY29uc3Qga2V5RnJhbWUgb2YgYW5pbWF0aW9uLmdldEtleXMoKSkge1xyXG4gICAgICAgICAgICBpbnB1dHMucHVzaChrZXlGcmFtZS5mcmFtZSAvIGFuaW1hdGlvbi5mcmFtZVBlclNlY29uZCk7IC8vIGtleWZyYW1lcyBpbiBzZWNvbmRzLlxyXG4gICAgICAgICAgICBfR0xURkFuaW1hdGlvbi5fQWRkS2V5ZnJhbWVWYWx1ZShrZXlGcmFtZSwgYW5pbWF0aW9uLCBvdXRwdXRzLCBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCwgYmFieWxvblRyYW5zZm9ybU5vZGUsIHVzZVF1YXRlcm5pb24pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgY3ViaWMgc3BsaW5lIGFuaW1hdGlvbiBmcm9tIHRoZSBhbmltYXRpb24ga2V5IGZyYW1lc1xyXG4gICAgICogQHBhcmFtIGJhYnlsb25UcmFuc2Zvcm1Ob2RlIEJhYnlsb25KUyBtZXNoXHJcbiAgICAgKiBAcGFyYW0gYW5pbWF0aW9uIEJhYnlsb25KUyBhbmltYXRpb25cclxuICAgICAqIEBwYXJhbSBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCBUaGUgdGFyZ2V0IGFuaW1hdGlvbiBjaGFubmVsXHJcbiAgICAgKiBAcGFyYW0gaW5wdXRzIEFycmF5IHRvIHN0b3JlIHRoZSBrZXkgZnJhbWUgdGltZXNcclxuICAgICAqIEBwYXJhbSBvdXRwdXRzIEFycmF5IHRvIHN0b3JlIHRoZSBrZXkgZnJhbWUgZGF0YVxyXG4gICAgICogQHBhcmFtIHVzZVF1YXRlcm5pb24gU3BlY2lmaWVzIGlmIHF1YXRlcm5pb25zIGFyZSB1c2VkIGluIHRoZSBhbmltYXRpb25cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX0NyZWF0ZUN1YmljU3BsaW5lQW5pbWF0aW9uKFxyXG4gICAgICAgIGJhYnlsb25UcmFuc2Zvcm1Ob2RlOiBOb2RlLFxyXG4gICAgICAgIGFuaW1hdGlvbjogQW5pbWF0aW9uLFxyXG4gICAgICAgIGFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoOiBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCxcclxuICAgICAgICBpbnB1dHM6IG51bWJlcltdLFxyXG4gICAgICAgIG91dHB1dHM6IG51bWJlcltdW10sXHJcbiAgICAgICAgdXNlUXVhdGVybmlvbjogYm9vbGVhblxyXG4gICAgKSB7XHJcbiAgICAgICAgYW5pbWF0aW9uLmdldEtleXMoKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXlGcmFtZSkge1xyXG4gICAgICAgICAgICBpbnB1dHMucHVzaChrZXlGcmFtZS5mcmFtZSAvIGFuaW1hdGlvbi5mcmFtZVBlclNlY29uZCk7IC8vIGtleWZyYW1lcyBpbiBzZWNvbmRzLlxyXG4gICAgICAgICAgICBfR0xURkFuaW1hdGlvbi5fQWRkU3BsaW5lVGFuZ2VudChfVGFuZ2VudFR5cGUuSU5UQU5HRU5ULCBvdXRwdXRzLCBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCwgQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uQ1VCSUNTUExJTkUsIGtleUZyYW1lLCB1c2VRdWF0ZXJuaW9uKTtcclxuICAgICAgICAgICAgX0dMVEZBbmltYXRpb24uX0FkZEtleWZyYW1lVmFsdWUoa2V5RnJhbWUsIGFuaW1hdGlvbiwgb3V0cHV0cywgYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgsIGJhYnlsb25UcmFuc2Zvcm1Ob2RlLCB1c2VRdWF0ZXJuaW9uKTtcclxuXHJcbiAgICAgICAgICAgIF9HTFRGQW5pbWF0aW9uLl9BZGRTcGxpbmVUYW5nZW50KF9UYW5nZW50VHlwZS5PVVRUQU5HRU5ULCBvdXRwdXRzLCBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCwgQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uQ1VCSUNTUExJTkUsIGtleUZyYW1lLCB1c2VRdWF0ZXJuaW9uKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfR2V0QmFzZVBvc2l0aW9uUm90YXRpb25PclNjYWxlKGJhYnlsb25UcmFuc2Zvcm1Ob2RlOiBOb2RlLCBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aDogQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgsIHVzZVF1YXRlcm5pb246IGJvb2xlYW4pIHtcclxuICAgICAgICBsZXQgYmFzZVBvc2l0aW9uUm90YXRpb25PclNjYWxlOiBudW1iZXJbXTtcclxuICAgICAgICBpZiAoYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGggPT09IEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLlJPVEFUSU9OKSB7XHJcbiAgICAgICAgICAgIGlmICh1c2VRdWF0ZXJuaW9uKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBxID0gKGJhYnlsb25UcmFuc2Zvcm1Ob2RlIGFzIFRyYW5zZm9ybU5vZGUpLnJvdGF0aW9uUXVhdGVybmlvbjtcclxuICAgICAgICAgICAgICAgIGJhc2VQb3NpdGlvblJvdGF0aW9uT3JTY2FsZSA9IChxID8/IFF1YXRlcm5pb24uSWRlbnRpdHkoKSkuYXNBcnJheSgpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcjogVmVjdG9yMyA9IChiYWJ5bG9uVHJhbnNmb3JtTm9kZSBhcyBUcmFuc2Zvcm1Ob2RlKS5yb3RhdGlvbjtcclxuICAgICAgICAgICAgICAgIGJhc2VQb3NpdGlvblJvdGF0aW9uT3JTY2FsZSA9IChyID8/IFZlY3RvcjMuWmVybygpKS5hc0FycmF5KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKGFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoID09PSBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aC5UUkFOU0xBVElPTikge1xyXG4gICAgICAgICAgICBjb25zdCBwOiBWZWN0b3IzID0gKGJhYnlsb25UcmFuc2Zvcm1Ob2RlIGFzIFRyYW5zZm9ybU5vZGUpLnBvc2l0aW9uO1xyXG4gICAgICAgICAgICBiYXNlUG9zaXRpb25Sb3RhdGlvbk9yU2NhbGUgPSAocCA/PyBWZWN0b3IzLlplcm8oKSkuYXNBcnJheSgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIHNjYWxlXHJcbiAgICAgICAgICAgIGNvbnN0IHM6IFZlY3RvcjMgPSAoYmFieWxvblRyYW5zZm9ybU5vZGUgYXMgVHJhbnNmb3JtTm9kZSkuc2NhbGluZztcclxuICAgICAgICAgICAgYmFzZVBvc2l0aW9uUm90YXRpb25PclNjYWxlID0gKHMgPz8gVmVjdG9yMy5PbmUoKSkuYXNBcnJheSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYmFzZVBvc2l0aW9uUm90YXRpb25PclNjYWxlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBhIGtleSBmcmFtZSB2YWx1ZVxyXG4gICAgICogQHBhcmFtIGtleUZyYW1lXHJcbiAgICAgKiBAcGFyYW0gYW5pbWF0aW9uXHJcbiAgICAgKiBAcGFyYW0gb3V0cHV0c1xyXG4gICAgICogQHBhcmFtIGFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvblRyYW5zZm9ybU5vZGVcclxuICAgICAqIEBwYXJhbSB1c2VRdWF0ZXJuaW9uXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIF9BZGRLZXlmcmFtZVZhbHVlKFxyXG4gICAgICAgIGtleUZyYW1lOiBJQW5pbWF0aW9uS2V5LFxyXG4gICAgICAgIGFuaW1hdGlvbjogQW5pbWF0aW9uLFxyXG4gICAgICAgIG91dHB1dHM6IG51bWJlcltdW10sXHJcbiAgICAgICAgYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGg6IEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLFxyXG4gICAgICAgIGJhYnlsb25UcmFuc2Zvcm1Ob2RlOiBOb2RlLFxyXG4gICAgICAgIHVzZVF1YXRlcm5pb246IGJvb2xlYW5cclxuICAgICkge1xyXG4gICAgICAgIGxldCBuZXdQb3NpdGlvblJvdGF0aW9uT3JTY2FsZTogTnVsbGFibGU8VmVjdG9yMyB8IFF1YXRlcm5pb24gfCBudW1iZXI+O1xyXG4gICAgICAgIGNvbnN0IGFuaW1hdGlvblR5cGUgPSBhbmltYXRpb24uZGF0YVR5cGU7XHJcbiAgICAgICAgaWYgKGFuaW1hdGlvblR5cGUgPT09IEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX1ZFQ1RPUjMpIHtcclxuICAgICAgICAgICAgbGV0IHZhbHVlID0ga2V5RnJhbWUudmFsdWUuYXNBcnJheSgpO1xyXG4gICAgICAgICAgICBpZiAoYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGggPT09IEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLlJPVEFUSU9OKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhcnJheSA9IFZlY3RvcjMuRnJvbUFycmF5KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJvdGF0aW9uUXVhdGVybmlvbiA9IFF1YXRlcm5pb24uUm90YXRpb25ZYXdQaXRjaFJvbGwoYXJyYXkueSwgYXJyYXkueCwgYXJyYXkueik7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHJvdGF0aW9uUXVhdGVybmlvbi5hc0FycmF5KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3V0cHV0cy5wdXNoKHZhbHVlKTsgLy8gc2NhbGUgIHZlY3Rvci5cclxuICAgICAgICB9IGVsc2UgaWYgKGFuaW1hdGlvblR5cGUgPT09IEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FUKSB7XHJcbiAgICAgICAgICAgIGlmIChhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCA9PT0gQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGguV0VJR0hUUykge1xyXG4gICAgICAgICAgICAgICAgb3V0cHV0cy5wdXNoKFtrZXlGcmFtZS52YWx1ZV0pO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gaGFuZGxlcyBzaW5nbGUgY29tcG9uZW50IHgsIHksIHogb3IgdyBjb21wb25lbnQgYW5pbWF0aW9uIGJ5IHVzaW5nIGEgYmFzZSBwcm9wZXJ0eSBhbmQgYW5pbWF0aW5nIG92ZXIgYSBjb21wb25lbnQuXHJcbiAgICAgICAgICAgICAgICBuZXdQb3NpdGlvblJvdGF0aW9uT3JTY2FsZSA9IHRoaXMuX0NvbnZlcnRGYWN0b3JUb1ZlY3RvcjNPclF1YXRlcm5pb24oXHJcbiAgICAgICAgICAgICAgICAgICAga2V5RnJhbWUudmFsdWUgYXMgbnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25UcmFuc2Zvcm1Ob2RlLFxyXG4gICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbixcclxuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCxcclxuICAgICAgICAgICAgICAgICAgICB1c2VRdWF0ZXJuaW9uXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgaWYgKG5ld1Bvc2l0aW9uUm90YXRpb25PclNjYWxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoID09PSBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aC5ST1RBVElPTikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3NSb3RTY2FsZSA9IHVzZVF1YXRlcm5pb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gKG5ld1Bvc2l0aW9uUm90YXRpb25PclNjYWxlIGFzIFF1YXRlcm5pb24pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFF1YXRlcm5pb24uUm90YXRpb25ZYXdQaXRjaFJvbGwobmV3UG9zaXRpb25Sb3RhdGlvbk9yU2NhbGUueSwgbmV3UG9zaXRpb25Sb3RhdGlvbk9yU2NhbGUueCwgbmV3UG9zaXRpb25Sb3RhdGlvbk9yU2NhbGUueikubm9ybWFsaXplKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dHMucHVzaChwb3NSb3RTY2FsZS5hc0FycmF5KCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBvdXRwdXRzLnB1c2gobmV3UG9zaXRpb25Sb3RhdGlvbk9yU2NhbGUuYXNBcnJheSgpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAoYW5pbWF0aW9uVHlwZSA9PT0gQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfUVVBVEVSTklPTikge1xyXG4gICAgICAgICAgICBvdXRwdXRzLnB1c2goKGtleUZyYW1lLnZhbHVlIGFzIFF1YXRlcm5pb24pLm5vcm1hbGl6ZSgpLmFzQXJyYXkoKSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgVG9vbHMuRXJyb3IoXCJnbFRGQW5pbWF0aW9uOiBVbnN1cHBvcnRlZCBrZXkgZnJhbWUgdmFsdWVzIGZvciBhbmltYXRpb24hXCIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICogRGV0ZXJtaW5lIHRoZSBpbnRlcnBvbGF0aW9uIGJhc2VkIG9uIHRoZSBrZXkgZnJhbWVzXHJcbiAgICAgKiBAcGFyYW0ga2V5RnJhbWVzXHJcbiAgICAgKiBAcGFyYW0gYW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGhcclxuICAgICAqIEBwYXJhbSB1c2VRdWF0ZXJuaW9uXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIF9EZWR1Y2VJbnRlcnBvbGF0aW9uKFxyXG4gICAgICAgIGtleUZyYW1lczogSUFuaW1hdGlvbktleVtdLFxyXG4gICAgICAgIGFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoOiBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCxcclxuICAgICAgICB1c2VRdWF0ZXJuaW9uOiBib29sZWFuXHJcbiAgICApOiB7IGludGVycG9sYXRpb25UeXBlOiBBbmltYXRpb25TYW1wbGVySW50ZXJwb2xhdGlvbjsgc2hvdWxkQmFrZUFuaW1hdGlvbjogYm9vbGVhbiB9IHtcclxuICAgICAgICBsZXQgaW50ZXJwb2xhdGlvblR5cGU6IEFuaW1hdGlvblNhbXBsZXJJbnRlcnBvbGF0aW9uIHwgdW5kZWZpbmVkO1xyXG4gICAgICAgIGxldCBzaG91bGRCYWtlQW5pbWF0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgbGV0IGtleTogSUFuaW1hdGlvbktleTtcclxuXHJcbiAgICAgICAgaWYgKGFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoID09PSBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aC5ST1RBVElPTiAmJiAhdXNlUXVhdGVybmlvbikge1xyXG4gICAgICAgICAgICByZXR1cm4geyBpbnRlcnBvbGF0aW9uVHlwZTogQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uTElORUFSLCBzaG91bGRCYWtlQW5pbWF0aW9uOiB0cnVlIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuZ3RoID0ga2V5RnJhbWVzLmxlbmd0aDsgaSA8IGxlbmd0aDsgKytpKSB7XHJcbiAgICAgICAgICAgIGtleSA9IGtleUZyYW1lc1tpXTtcclxuICAgICAgICAgICAgaWYgKGtleS5pblRhbmdlbnQgfHwga2V5Lm91dFRhbmdlbnQpIHtcclxuICAgICAgICAgICAgICAgIGlmIChpbnRlcnBvbGF0aW9uVHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnRlcnBvbGF0aW9uVHlwZSAhPT0gQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uQ1VCSUNTUExJTkUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJwb2xhdGlvblR5cGUgPSBBbmltYXRpb25TYW1wbGVySW50ZXJwb2xhdGlvbi5MSU5FQVI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNob3VsZEJha2VBbmltYXRpb24gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGludGVycG9sYXRpb25UeXBlID0gQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uQ1VCSUNTUExJTkU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaW50ZXJwb2xhdGlvblR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGludGVycG9sYXRpb25UeXBlID09PSBBbmltYXRpb25TYW1wbGVySW50ZXJwb2xhdGlvbi5DVUJJQ1NQTElORSB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoa2V5LmludGVycG9sYXRpb24gJiYga2V5LmludGVycG9sYXRpb24gPT09IEFuaW1hdGlvbktleUludGVycG9sYXRpb24uU1RFUCAmJiBpbnRlcnBvbGF0aW9uVHlwZSAhPT0gQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uU1RFUClcclxuICAgICAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJwb2xhdGlvblR5cGUgPSBBbmltYXRpb25TYW1wbGVySW50ZXJwb2xhdGlvbi5MSU5FQVI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNob3VsZEJha2VBbmltYXRpb24gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkuaW50ZXJwb2xhdGlvbiAmJiBrZXkuaW50ZXJwb2xhdGlvbiA9PT0gQW5pbWF0aW9uS2V5SW50ZXJwb2xhdGlvbi5TVEVQKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGludGVycG9sYXRpb25UeXBlID0gQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uU1RFUDtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnBvbGF0aW9uVHlwZSA9IEFuaW1hdGlvblNhbXBsZXJJbnRlcnBvbGF0aW9uLkxJTkVBUjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFpbnRlcnBvbGF0aW9uVHlwZSkge1xyXG4gICAgICAgICAgICBpbnRlcnBvbGF0aW9uVHlwZSA9IEFuaW1hdGlvblNhbXBsZXJJbnRlcnBvbGF0aW9uLkxJTkVBUjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB7IGludGVycG9sYXRpb25UeXBlOiBpbnRlcnBvbGF0aW9uVHlwZSwgc2hvdWxkQmFrZUFuaW1hdGlvbjogc2hvdWxkQmFrZUFuaW1hdGlvbiB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBhbiBpbnB1dCB0YW5nZW50IG9yIG91dHB1dCB0YW5nZW50IHRvIHRoZSBvdXRwdXQgZGF0YVxyXG4gICAgICogSWYgYW4gaW5wdXQgdGFuZ2VudCBvciBvdXRwdXQgdGFuZ2VudCBpcyBtaXNzaW5nLCBpdCB1c2VzIHRoZSB6ZXJvIHZlY3RvciBvciB6ZXJvIHF1YXRlcm5pb25cclxuICAgICAqIEBwYXJhbSB0YW5nZW50VHlwZSBTcGVjaWZpZXMgd2hpY2ggdHlwZSBvZiB0YW5nZW50IHRvIGhhbmRsZSAoaW5UYW5nZW50IG9yIG91dFRhbmdlbnQpXHJcbiAgICAgKiBAcGFyYW0gb3V0cHV0cyBUaGUgYW5pbWF0aW9uIGRhdGEgYnkga2V5ZnJhbWVcclxuICAgICAqIEBwYXJhbSBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCBUaGUgdGFyZ2V0IGFuaW1hdGlvbiBjaGFubmVsXHJcbiAgICAgKiBAcGFyYW0gaW50ZXJwb2xhdGlvbiBUaGUgaW50ZXJwb2xhdGlvbiB0eXBlXHJcbiAgICAgKiBAcGFyYW0ga2V5RnJhbWUgVGhlIGtleSBmcmFtZSB3aXRoIHRoZSBhbmltYXRpb24gZGF0YVxyXG4gICAgICogQHBhcmFtIHVzZVF1YXRlcm5pb24gU3BlY2lmaWVzIGlmIHF1YXRlcm5pb25zIGFyZSB1c2VkXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIF9BZGRTcGxpbmVUYW5nZW50KFxyXG4gICAgICAgIHRhbmdlbnRUeXBlOiBfVGFuZ2VudFR5cGUsXHJcbiAgICAgICAgb3V0cHV0czogbnVtYmVyW11bXSxcclxuICAgICAgICBhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aDogQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGgsXHJcbiAgICAgICAgaW50ZXJwb2xhdGlvbjogQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24sXHJcbiAgICAgICAga2V5RnJhbWU6IElBbmltYXRpb25LZXksXHJcbiAgICAgICAgdXNlUXVhdGVybmlvbjogYm9vbGVhblxyXG4gICAgKSB7XHJcbiAgICAgICAgbGV0IHRhbmdlbnQ6IG51bWJlcltdO1xyXG4gICAgICAgIGNvbnN0IHRhbmdlbnRWYWx1ZTogVmVjdG9yMyB8IFF1YXRlcm5pb24gfCBudW1iZXIgPSB0YW5nZW50VHlwZSA9PT0gX1RhbmdlbnRUeXBlLklOVEFOR0VOVCA/IGtleUZyYW1lLmluVGFuZ2VudCA6IGtleUZyYW1lLm91dFRhbmdlbnQ7XHJcbiAgICAgICAgaWYgKGludGVycG9sYXRpb24gPT09IEFuaW1hdGlvblNhbXBsZXJJbnRlcnBvbGF0aW9uLkNVQklDU1BMSU5FKSB7XHJcbiAgICAgICAgICAgIGlmIChhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCA9PT0gQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGguUk9UQVRJT04pIHtcclxuICAgICAgICAgICAgICAgIGlmICh0YW5nZW50VmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodXNlUXVhdGVybmlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YW5nZW50ID0gKHRhbmdlbnRWYWx1ZSBhcyBRdWF0ZXJuaW9uKS5hc0FycmF5KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXJyYXkgPSB0YW5nZW50VmFsdWUgYXMgVmVjdG9yMztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFuZ2VudCA9IFF1YXRlcm5pb24uUm90YXRpb25ZYXdQaXRjaFJvbGwoYXJyYXkueSwgYXJyYXkueCwgYXJyYXkueikuYXNBcnJheSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGFuZ2VudCA9IFswLCAwLCAwLCAwXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIGlmIChhbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCA9PT0gQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGguV0VJR0hUUykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRhbmdlbnRWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRhbmdlbnQgPSBbdGFuZ2VudFZhbHVlIGFzIG51bWJlcl07XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRhbmdlbnQgPSBbMF07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGFuZ2VudFZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGFuZ2VudCA9ICh0YW5nZW50VmFsdWUgYXMgVmVjdG9yMykuYXNBcnJheSgpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0YW5nZW50ID0gWzAsIDAsIDBdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBvdXRwdXRzLnB1c2godGFuZ2VudCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGtleSBmcmFtZXMnIGZyYW1lIHZhbHVlc1xyXG4gICAgICogQHBhcmFtIGtleUZyYW1lcyBhbmltYXRpb24ga2V5IGZyYW1lc1xyXG4gICAgICogQHJldHVybnMgdGhlIG1pbmltdW0gYW5kIG1heGltdW0ga2V5IGZyYW1lIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIF9DYWxjdWxhdGVNaW5NYXhLZXlGcmFtZXMoa2V5RnJhbWVzOiBJQW5pbWF0aW9uS2V5W10pOiB7IG1pbjogbnVtYmVyOyBtYXg6IG51bWJlciB9IHtcclxuICAgICAgICBsZXQgbWluOiBudW1iZXIgPSBJbmZpbml0eTtcclxuICAgICAgICBsZXQgbWF4OiBudW1iZXIgPSAtSW5maW5pdHk7XHJcbiAgICAgICAga2V5RnJhbWVzLmZvckVhY2goZnVuY3Rpb24gKGtleUZyYW1lKSB7XHJcbiAgICAgICAgICAgIG1pbiA9IE1hdGgubWluKG1pbiwga2V5RnJhbWUuZnJhbWUpO1xyXG4gICAgICAgICAgICBtYXggPSBNYXRoLm1heChtYXgsIGtleUZyYW1lLmZyYW1lKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHsgbWluOiBtaW4sIG1heDogbWF4IH07XHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IHsgSW1hZ2VNaW1lVHlwZSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuXHJcbi8qKlxyXG4gKiBDbGFzcyBmb3IgaG9sZGluZyBhbmQgZG93bmxvYWRpbmcgZ2xURiBmaWxlIGRhdGFcclxuICovXHJcbmV4cG9ydCBjbGFzcyBHTFRGRGF0YSB7XHJcbiAgICAvKipcclxuICAgICAqIE9iamVjdCB3aGljaCBjb250YWlucyB0aGUgZmlsZSBuYW1lIGFzIHRoZSBrZXkgYW5kIGl0cyBkYXRhIGFzIHRoZSB2YWx1ZVxyXG4gICAgICovXHJcbiAgICBnbFRGRmlsZXM6IHsgW2ZpbGVOYW1lOiBzdHJpbmddOiBzdHJpbmcgfCBCbG9iIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWFsaXplcyB0aGUgZ2xURiBmaWxlIG9iamVjdFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgdGhpcy5nbFRGRmlsZXMgPSB7fTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERvd25sb2FkcyB0aGUgZ2xURiBkYXRhIGFzIGZpbGVzIGJhc2VkIG9uIHRoZWlyIG5hbWVzIGFuZCBkYXRhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkb3dubG9hZEZpbGVzKCk6IHZvaWQge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENoZWNrcyBmb3IgYSBtYXRjaGluZyBzdWZmaXggYXQgdGhlIGVuZCBvZiBhIHN0cmluZyAoZm9yIEVTNSBhbmQgbG93ZXIpXHJcbiAgICAgICAgICogQHBhcmFtIHN0ciBTb3VyY2Ugc3RyaW5nXHJcbiAgICAgICAgICogQHBhcmFtIHN1ZmZpeCBTdWZmaXggdG8gc2VhcmNoIGZvciBpbiB0aGUgc291cmNlIHN0cmluZ1xyXG4gICAgICAgICAqIEByZXR1cm5zIEJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBzdWZmaXggd2FzIGZvdW5kICh0cnVlKSBvciBub3QgKGZhbHNlKVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIGVuZHNXaXRoKHN0cjogc3RyaW5nLCBzdWZmaXg6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgICAgICByZXR1cm4gc3RyLmluZGV4T2Yoc3VmZml4LCBzdHIubGVuZ3RoIC0gc3VmZml4Lmxlbmd0aCkgIT09IC0xO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy5nbFRGRmlsZXMpIHtcclxuICAgICAgICAgICAgY29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpO1xyXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGxpbmspO1xyXG4gICAgICAgICAgICBsaW5rLnNldEF0dHJpYnV0ZShcInR5cGVcIiwgXCJoaWRkZW5cIik7XHJcbiAgICAgICAgICAgIGxpbmsuZG93bmxvYWQgPSBrZXk7XHJcbiAgICAgICAgICAgIGNvbnN0IGJsb2IgPSB0aGlzLmdsVEZGaWxlc1trZXldO1xyXG4gICAgICAgICAgICBsZXQgbWltZVR5cGU7XHJcblxyXG4gICAgICAgICAgICBpZiAoZW5kc1dpdGgoa2V5LCBcIi5nbGJcIikpIHtcclxuICAgICAgICAgICAgICAgIG1pbWVUeXBlID0geyB0eXBlOiBcIm1vZGVsL2dsdGYtYmluYXJ5XCIgfTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChlbmRzV2l0aChrZXksIFwiLmJpblwiKSkge1xyXG4gICAgICAgICAgICAgICAgbWltZVR5cGUgPSB7IHR5cGU6IFwiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtXCIgfTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChlbmRzV2l0aChrZXksIFwiLmdsdGZcIikpIHtcclxuICAgICAgICAgICAgICAgIG1pbWVUeXBlID0geyB0eXBlOiBcIm1vZGVsL2dsdGYranNvblwiIH07XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZW5kc1dpdGgoa2V5LCBcIi5qcGVnXCIpIHx8IGVuZHNXaXRoKGtleSwgXCIuanBnXCIpKSB7XHJcbiAgICAgICAgICAgICAgICBtaW1lVHlwZSA9IHsgdHlwZTogSW1hZ2VNaW1lVHlwZS5KUEVHIH07XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZW5kc1dpdGgoa2V5LCBcIi5wbmdcIikpIHtcclxuICAgICAgICAgICAgICAgIG1pbWVUeXBlID0geyB0eXBlOiBJbWFnZU1pbWVUeXBlLlBORyB9O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsaW5rLmhyZWYgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihbYmxvYl0sIG1pbWVUeXBlKSk7XHJcbiAgICAgICAgICAgIGxpbmsuY2xpY2soKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IHR5cGUge1xyXG4gICAgSUJ1ZmZlclZpZXcsXHJcbiAgICBJQWNjZXNzb3IsXHJcbiAgICBJTm9kZSxcclxuICAgIElTY2VuZSxcclxuICAgIElNZXNoLFxyXG4gICAgSU1hdGVyaWFsLFxyXG4gICAgSVRleHR1cmUsXHJcbiAgICBJSW1hZ2UsXHJcbiAgICBJU2FtcGxlcixcclxuICAgIElBbmltYXRpb24sXHJcbiAgICBJTWVzaFByaW1pdGl2ZSxcclxuICAgIElCdWZmZXIsXHJcbiAgICBJR0xURixcclxuICAgIElUZXh0dXJlSW5mbyxcclxuICAgIElTa2luLFxyXG4gICAgSUNhbWVyYSxcclxufSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IEFjY2Vzc29yVHlwZSwgSW1hZ2VNaW1lVHlwZSwgTWVzaFByaW1pdGl2ZU1vZGUsIEFjY2Vzc29yQ29tcG9uZW50VHlwZSwgQ2FtZXJhVHlwZSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgRmxvYXRBcnJheSwgSW5kaWNlc0FycmF5LCBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IE1hdHJpeCwgVG1wVmVjdG9ycywgVmVjdG9yMiwgVmVjdG9yMywgVmVjdG9yNCwgUXVhdGVybmlvbiB9IGZyb20gXCJjb3JlL01hdGhzL21hdGgudmVjdG9yXCI7XHJcbmltcG9ydCB7IENvbG9yMywgQ29sb3I0IH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC5jb2xvclwiO1xyXG5pbXBvcnQgeyBUb29scyB9IGZyb20gXCJjb3JlL01pc2MvdG9vbHNcIjtcclxuaW1wb3J0IHsgVmVydGV4QnVmZmVyIH0gZnJvbSBcImNvcmUvQnVmZmVycy9idWZmZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSBcImNvcmUvbm9kZVwiO1xyXG5pbXBvcnQgeyBUcmFuc2Zvcm1Ob2RlIH0gZnJvbSBcImNvcmUvTWVzaGVzL3RyYW5zZm9ybU5vZGVcIjtcclxuaW1wb3J0IHR5cGUgeyBBYnN0cmFjdE1lc2ggfSBmcm9tIFwiY29yZS9NZXNoZXMvYWJzdHJhY3RNZXNoXCI7XHJcbmltcG9ydCB0eXBlIHsgU3ViTWVzaCB9IGZyb20gXCJjb3JlL01lc2hlcy9zdWJNZXNoXCI7XHJcbmltcG9ydCB7IE1lc2ggfSBmcm9tIFwiY29yZS9NZXNoZXMvbWVzaFwiO1xyXG5pbXBvcnQgdHlwZSB7IE1vcnBoVGFyZ2V0IH0gZnJvbSBcImNvcmUvTW9ycGgvbW9ycGhUYXJnZXRcIjtcclxuaW1wb3J0IHsgTGluZXNNZXNoIH0gZnJvbSBcImNvcmUvTWVzaGVzL2xpbmVzTWVzaFwiO1xyXG5pbXBvcnQgeyBJbnN0YW5jZWRNZXNoIH0gZnJvbSBcImNvcmUvTWVzaGVzL2luc3RhbmNlZE1lc2hcIjtcclxuaW1wb3J0IHR5cGUgeyBCb25lIH0gZnJvbSBcImNvcmUvQm9uZXMvYm9uZVwiO1xyXG5pbXBvcnQgdHlwZSB7IEJhc2VUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL2Jhc2VUZXh0dXJlXCI7XHJcbmltcG9ydCB0eXBlIHsgVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy90ZXh0dXJlXCI7XHJcbmltcG9ydCB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB7IEVuZ2luZSB9IGZyb20gXCJjb3JlL0VuZ2luZXMvZW5naW5lXCI7XHJcbmltcG9ydCB0eXBlIHsgU2NlbmUgfSBmcm9tIFwiY29yZS9zY2VuZVwiO1xyXG5cclxuaW1wb3J0IHR5cGUgeyBJR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIgfSBmcm9tIFwiLi9nbFRGRXhwb3J0ZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgX0dMVEZNYXRlcmlhbEV4cG9ydGVyIH0gZnJvbSBcIi4vZ2xURk1hdGVyaWFsRXhwb3J0ZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJRXhwb3J0T3B0aW9ucyB9IGZyb20gXCIuL2dsVEZTZXJpYWxpemVyXCI7XHJcbmltcG9ydCB7IF9HTFRGVXRpbGl0aWVzIH0gZnJvbSBcIi4vZ2xURlV0aWxpdGllc1wiO1xyXG5pbXBvcnQgeyBHTFRGRGF0YSB9IGZyb20gXCIuL2dsVEZEYXRhXCI7XHJcbmltcG9ydCB7IF9HTFRGQW5pbWF0aW9uIH0gZnJvbSBcIi4vZ2xURkFuaW1hdGlvblwiO1xyXG5pbXBvcnQgeyBDYW1lcmEgfSBmcm9tIFwiY29yZS9DYW1lcmFzL2NhbWVyYVwiO1xyXG5pbXBvcnQgeyBFbmdpbmVTdG9yZSB9IGZyb20gXCJjb3JlL0VuZ2luZXMvZW5naW5lU3RvcmVcIjtcclxuaW1wb3J0IHsgTXVsdGlNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tdWx0aU1hdGVyaWFsXCI7XHJcblxyXG4vLyBNYXRyaXggdGhhdCBjb252ZXJ0cyBoYW5kZWRuZXNzIG9uIHRoZSBYLWF4aXMuXHJcbmNvbnN0IGNvbnZlcnRIYW5kZWRuZXNzTWF0cml4ID0gTWF0cml4LkNvbXBvc2UobmV3IFZlY3RvcjMoLTEsIDEsIDEpLCBRdWF0ZXJuaW9uLklkZW50aXR5KCksIFZlY3RvcjMuWmVybygpKTtcclxuXHJcbi8vIDE4MCBkZWdyZWVzIHJvdGF0aW9uIGluIFkuXHJcbmNvbnN0IHJvdGF0aW9uMTgwWSA9IG5ldyBRdWF0ZXJuaW9uKDAsIDEsIDAsIDApO1xyXG5cclxuZnVuY3Rpb24gaXNOb29wTm9kZShub2RlOiBOb2RlLCB1c2VSaWdodEhhbmRlZFN5c3RlbTogYm9vbGVhbik6IGJvb2xlYW4ge1xyXG4gICAgaWYgKCEobm9kZSBpbnN0YW5jZW9mIFRyYW5zZm9ybU5vZGUpKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFRyYW5zZm9ybVxyXG4gICAgaWYgKHVzZVJpZ2h0SGFuZGVkU3lzdGVtKSB7XHJcbiAgICAgICAgY29uc3QgbWF0cml4ID0gbm9kZS5nZXRXb3JsZE1hdHJpeCgpO1xyXG4gICAgICAgIGlmICghbWF0cml4LmlzSWRlbnRpdHkoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBjb25zdCBtYXRyaXggPSBub2RlLmdldFdvcmxkTWF0cml4KCkubXVsdGlwbHlUb1JlZihjb252ZXJ0SGFuZGVkbmVzc01hdHJpeCwgVG1wVmVjdG9ycy5NYXRyaXhbMF0pO1xyXG4gICAgICAgIGlmICghbWF0cml4LmlzSWRlbnRpdHkoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIEdlb21ldHJ5XHJcbiAgICBpZiAoKG5vZGUgaW5zdGFuY2VvZiBNZXNoICYmIG5vZGUuZ2VvbWV0cnkpIHx8IChub2RlIGluc3RhbmNlb2YgSW5zdGFuY2VkTWVzaCAmJiBub2RlLnNvdXJjZU1lc2guZ2VvbWV0cnkpKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0cnVlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjb252ZXJ0Tm9kZUhhbmRlZG5lc3Mobm9kZTogSU5vZGUpOiB2b2lkIHtcclxuICAgIGNvbnN0IHRyYW5zbGF0aW9uID0gVmVjdG9yMy5Gcm9tQXJyYXlUb1JlZihub2RlLnRyYW5zbGF0aW9uIHx8IFswLCAwLCAwXSwgMCwgVG1wVmVjdG9ycy5WZWN0b3IzWzBdKTtcclxuICAgIGNvbnN0IHJvdGF0aW9uID0gUXVhdGVybmlvbi5Gcm9tQXJyYXlUb1JlZihub2RlLnJvdGF0aW9uIHx8IFswLCAwLCAwLCAxXSwgMCwgVG1wVmVjdG9ycy5RdWF0ZXJuaW9uWzBdKTtcclxuICAgIGNvbnN0IHNjYWxlID0gVmVjdG9yMy5Gcm9tQXJyYXlUb1JlZihub2RlLnNjYWxlIHx8IFsxLCAxLCAxXSwgMCwgVG1wVmVjdG9ycy5WZWN0b3IzWzFdKTtcclxuICAgIGNvbnN0IG1hdHJpeCA9IE1hdHJpeC5Db21wb3NlVG9SZWYoc2NhbGUsIHJvdGF0aW9uLCB0cmFuc2xhdGlvbiwgVG1wVmVjdG9ycy5NYXRyaXhbMF0pLm11bHRpcGx5VG9SZWYoY29udmVydEhhbmRlZG5lc3NNYXRyaXgsIFRtcFZlY3RvcnMuTWF0cml4WzBdKTtcclxuXHJcbiAgICBtYXRyaXguZGVjb21wb3NlKHNjYWxlLCByb3RhdGlvbiwgdHJhbnNsYXRpb24pO1xyXG5cclxuICAgIGlmICh0cmFuc2xhdGlvbi5lcXVhbHNUb0Zsb2F0cygwLCAwLCAwKSkge1xyXG4gICAgICAgIGRlbGV0ZSBub2RlLnRyYW5zbGF0aW9uO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBub2RlLnRyYW5zbGF0aW9uID0gdHJhbnNsYXRpb24uYXNBcnJheSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChRdWF0ZXJuaW9uLklzSWRlbnRpdHkocm90YXRpb24pKSB7XHJcbiAgICAgICAgZGVsZXRlIG5vZGUucm90YXRpb247XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIG5vZGUucm90YXRpb24gPSByb3RhdGlvbi5hc0FycmF5KCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHNjYWxlLmVxdWFsc1RvRmxvYXRzKDEsIDEsIDEpKSB7XHJcbiAgICAgICAgZGVsZXRlIG5vZGUuc2NhbGU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIG5vZGUuc2NhbGUgPSBzY2FsZS5hc0FycmF5KCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEJpbmFyeVdyaXRlckZ1bmMoYmluYXJ5V3JpdGVyOiBfQmluYXJ5V3JpdGVyLCBhdHRyaWJ1dGVDb21wb25lbnRLaW5kOiBBY2Nlc3NvckNvbXBvbmVudFR5cGUpOiBOdWxsYWJsZTwoZW50cnk6IG51bWJlciwgYnl0ZU9mZnNldD86IG51bWJlcikgPT4gdm9pZD4ge1xyXG4gICAgc3dpdGNoIChhdHRyaWJ1dGVDb21wb25lbnRLaW5kKSB7XHJcbiAgICAgICAgY2FzZSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuVU5TSUdORURfQllURToge1xyXG4gICAgICAgICAgICByZXR1cm4gYmluYXJ5V3JpdGVyLnNldFVJbnQ4LmJpbmQoYmluYXJ5V3JpdGVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2FzZSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuVU5TSUdORURfU0hPUlQ6IHtcclxuICAgICAgICAgICAgcmV0dXJuIGJpbmFyeVdyaXRlci5zZXRVSW50MTYuYmluZChiaW5hcnlXcml0ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXNlIEFjY2Vzc29yQ29tcG9uZW50VHlwZS5VTlNJR05FRF9JTlQ6IHtcclxuICAgICAgICAgICAgcmV0dXJuIGJpbmFyeVdyaXRlci5zZXRVSW50MzIuYmluZChiaW5hcnlXcml0ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXNlIEFjY2Vzc29yQ29tcG9uZW50VHlwZS5GTE9BVDoge1xyXG4gICAgICAgICAgICByZXR1cm4gYmluYXJ5V3JpdGVyLnNldEZsb2F0MzIuYmluZChiaW5hcnlXcml0ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBkZWZhdWx0OiB7XHJcbiAgICAgICAgICAgIFRvb2xzLldhcm4oXCJVbnN1cHBvcnRlZCBBdHRyaWJ1dGUgQ29tcG9uZW50IGtpbmQ6IFwiICsgYXR0cmlidXRlQ29tcG9uZW50S2luZCk7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFV0aWxpdHkgaW50ZXJmYWNlIGZvciBzdG9yaW5nIHZlcnRleCBhdHRyaWJ1dGUgZGF0YVxyXG4gKiBAaW50ZXJuYWxcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuaW50ZXJmYWNlIF9JVmVydGV4QXR0cmlidXRlRGF0YSB7XHJcbiAgICAvKipcclxuICAgICAqIFNwZWNpZmllcyB0aGUgQmFieWxvbiBWZXJ0ZXggQnVmZmVyIFR5cGUgKFBvc2l0aW9uLCBOb3JtYWwsIENvbG9yLCBldGMuKVxyXG4gICAgICovXHJcbiAgICBraW5kOiBzdHJpbmc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTcGVjaWZpZXMgdGhlIGdsVEYgQWNjZXNzb3IgVHlwZSAoVkVDMiwgVkVDMywgZXRjLilcclxuICAgICAqL1xyXG4gICAgYWNjZXNzb3JUeXBlOiBBY2Nlc3NvclR5cGU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTcGVjaWZpZXMgdGhlIGdsVEYgQWNjZXNzb3IgQ29tcG9uZW50IFR5cGUgKEJZVEUsIFVOU0lHTkVEX0JZVEUsIEZMT0FULCBTSE9SVCwgSU5ULCBldGMuLilcclxuICAgICAqL1xyXG4gICAgYWNjZXNzb3JDb21wb25lbnRUeXBlOiBBY2Nlc3NvckNvbXBvbmVudFR5cGU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTcGVjaWZpZXMgdGhlIEJ1ZmZlclZpZXcgaW5kZXggZm9yIHRoZSB2ZXJ0ZXggYXR0cmlidXRlIGRhdGFcclxuICAgICAqL1xyXG4gICAgYnVmZmVyVmlld0luZGV4PzogbnVtYmVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3BlY2lmaWVzIHRoZSBudW1iZXIgb2YgYnl0ZXMgcGVyIGF0dHJpYnV0ZSBlbGVtZW50IChlLmcuIHBvc2l0aW9uIHdvdWxkIGJlIDMgZmxvYXRzICh4L3kveikgd2hlcmUgZWFjaCBmbG9hdCBpcyA0IGJ5dGVzLCBzbyBhIDEyIGJ5dGUgc3RyaWRlKVxyXG4gICAgICovXHJcbiAgICBieXRlU3RyaWRlPzogbnVtYmVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3BlY2lmaWVzIGluZm9ybWF0aW9uIGFib3V0IGVhY2ggbW9ycGggdGFyZ2V0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGF0dHJpYnV0ZVxyXG4gICAgICovXHJcbiAgICBtb3JwaFRhcmdldEluZm8/OiBSZWFkb25seTx7IGJ1ZmZlclZpZXdJbmRleDogbnVtYmVyOyB2ZXJ0ZXhDb3VudDogbnVtYmVyOyBhY2Nlc3NvclR5cGU6IEFjY2Vzc29yVHlwZTsgbWluTWF4PzogeyBtaW46IFZlY3RvcjM7IG1heDogVmVjdG9yMyB9IH0+W107XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0cyBCYWJ5bG9uIFNjZW5lIGludG8gZ2xURiAyLjAuXHJcbiAqIEBpbnRlcm5hbFxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIF9FeHBvcnRlciB7XHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyB0aGUgZ2xURiB0byBleHBvcnRcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9nbFRGOiBJR0xURjtcclxuICAgIC8qKlxyXG4gICAgICogU3RvcmVzIGFsbCBnZW5lcmF0ZWQgYnVmZmVyIHZpZXdzLCB3aGljaCByZXByZXNlbnRzIHZpZXdzIGludG8gdGhlIG1haW4gZ2xURiBidWZmZXIgZGF0YVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2J1ZmZlclZpZXdzOiBJQnVmZmVyVmlld1tdO1xyXG4gICAgLyoqXHJcbiAgICAgKiBTdG9yZXMgYWxsIHRoZSBnZW5lcmF0ZWQgYWNjZXNzb3JzLCB3aGljaCBpcyB1c2VkIGZvciBhY2Nlc3NpbmcgdGhlIGRhdGEgd2l0aGluIHRoZSBidWZmZXIgdmlld3MgaW4gZ2xURlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2FjY2Vzc29yczogSUFjY2Vzc29yW107XHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyBhbGwgdGhlIGdlbmVyYXRlZCBub2Rlcywgd2hpY2ggY29udGFpbnMgdHJhbnNmb3JtIGFuZC9vciBtZXNoIGluZm9ybWF0aW9uIHBlciBub2RlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbm9kZXM6IElOb2RlW107XHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyBhbGwgdGhlIGdlbmVyYXRlZCBnbFRGIHNjZW5lcywgd2hpY2ggc3RvcmVzIG11bHRpcGxlIG5vZGUgaGllcmFyY2hpZXNcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfc2NlbmVzOiBJU2NlbmVbXTtcclxuICAgIC8qKlxyXG4gICAgICogU3RvcmVzIGFsbCB0aGUgZ2VuZXJhdGVkIGdsVEYgY2FtZXJhc1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9jYW1lcmFzOiBJQ2FtZXJhW107XHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyBhbGwgdGhlIGdlbmVyYXRlZCBtZXNoIGluZm9ybWF0aW9uLCBlYWNoIGNvbnRhaW5pbmcgYSBzZXQgb2YgcHJpbWl0aXZlcyB0byByZW5kZXIgaW4gZ2xURlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9tZXNoZXM6IElNZXNoW107XHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyBhbGwgdGhlIGdlbmVyYXRlZCBtYXRlcmlhbCBpbmZvcm1hdGlvbiwgd2hpY2ggcmVwcmVzZW50cyB0aGUgYXBwZWFyYW5jZSBvZiBlYWNoIHByaW1pdGl2ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX21hdGVyaWFsczogSU1hdGVyaWFsW107XHJcblxyXG4gICAgcHVibGljIF9tYXRlcmlhbE1hcDogeyBbbWF0ZXJpYWxJRDogbnVtYmVyXTogbnVtYmVyIH07XHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyBhbGwgdGhlIGdlbmVyYXRlZCB0ZXh0dXJlIGluZm9ybWF0aW9uLCB3aGljaCBpcyByZWZlcmVuY2VkIGJ5IGdsVEYgbWF0ZXJpYWxzXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfdGV4dHVyZXM6IElUZXh0dXJlW107XHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyBhbGwgdGhlIGdlbmVyYXRlZCBpbWFnZSBpbmZvcm1hdGlvbiwgd2hpY2ggaXMgcmVmZXJlbmNlZCBieSBnbFRGIHRleHR1cmVzXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfaW1hZ2VzOiBJSW1hZ2VbXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyBhbGwgdGhlIHRleHR1cmUgc2FtcGxlcnNcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9zYW1wbGVyczogSVNhbXBsZXJbXTtcclxuICAgIC8qKlxyXG4gICAgICogU3RvcmVzIGFsbCB0aGUgZ2VuZXJhdGVkIGdsVEYgc2tpbnNcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9za2luczogSVNraW5bXTtcclxuICAgIC8qKlxyXG4gICAgICogU3RvcmVzIGFsbCB0aGUgZ2VuZXJhdGVkIGFuaW1hdGlvbiBzYW1wbGVycywgd2hpY2ggaXMgcmVmZXJlbmNlZCBieSBnbFRGIGFuaW1hdGlvbnNcclxuICAgICAqL1xyXG4gICAgLyoqXHJcbiAgICAgKiBTdG9yZXMgdGhlIGFuaW1hdGlvbnMgZm9yIGdsVEYgbW9kZWxzXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX2FuaW1hdGlvbnM6IElBbmltYXRpb25bXTtcclxuICAgIC8qKlxyXG4gICAgICogU3RvcmVzIHRoZSB0b3RhbCBhbW91bnQgb2YgYnl0ZXMgc3RvcmVkIGluIHRoZSBnbFRGIGJ1ZmZlclxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF90b3RhbEJ5dGVMZW5ndGg6IG51bWJlcjtcclxuICAgIC8qKlxyXG4gICAgICogU3RvcmVzIGEgcmVmZXJlbmNlIHRvIHRoZSBCYWJ5bG9uIHNjZW5lIGNvbnRhaW5pbmcgdGhlIHNvdXJjZSBnZW9tZXRyeSBhbmQgbWF0ZXJpYWwgaW5mb3JtYXRpb25cclxuICAgICAqL1xyXG4gICAgcHVibGljIF9iYWJ5bG9uU2NlbmU6IFNjZW5lO1xyXG4gICAgLyoqXHJcbiAgICAgKiBTdG9yZXMgYSBtYXAgb2YgdGhlIGltYWdlIGRhdGEsIHdoZXJlIHRoZSBrZXkgaXMgdGhlIGZpbGUgbmFtZSBhbmQgdGhlIHZhbHVlXHJcbiAgICAgKiBpcyB0aGUgaW1hZ2UgZGF0YVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2ltYWdlRGF0YTogeyBbZmlsZU5hbWU6IHN0cmluZ106IHsgZGF0YTogQXJyYXlCdWZmZXI7IG1pbWVUeXBlOiBJbWFnZU1pbWVUeXBlIH0gfTtcclxuXHJcbiAgICBwcml2YXRlIF9vcmRlcmVkSW1hZ2VEYXRhOiBBcnJheTx7IGRhdGE6IEFycmF5QnVmZmVyOyBtaW1lVHlwZTogSW1hZ2VNaW1lVHlwZSB9PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyBhIG1hcCBvZiB0aGUgdW5pcXVlIGlkIG9mIGEgbm9kZSB0byBpdHMgaW5kZXggaW4gdGhlIG5vZGUgYXJyYXlcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfbm9kZU1hcDogeyBba2V5OiBudW1iZXJdOiBudW1iZXIgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEJha2VkIGFuaW1hdGlvbiBzYW1wbGUgcmF0ZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9hbmltYXRpb25TYW1wbGVSYXRlOiBudW1iZXI7XHJcblxyXG4gICAgcHJpdmF0ZSBfb3B0aW9uczogSUV4cG9ydE9wdGlvbnM7XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9jYWxFbmdpbmU6IEVuZ2luZTtcclxuXHJcbiAgICBwdWJsaWMgX2dsVEZNYXRlcmlhbEV4cG9ydGVyOiBfR0xURk1hdGVyaWFsRXhwb3J0ZXI7XHJcblxyXG4gICAgcHJpdmF0ZSBfZXh0ZW5zaW9uczogeyBbbmFtZTogc3RyaW5nXTogSUdMVEZFeHBvcnRlckV4dGVuc2lvblYyIH0gPSB7fTtcclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfRXh0ZW5zaW9uTmFtZXMgPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX0V4dGVuc2lvbkZhY3RvcmllczogeyBbbmFtZTogc3RyaW5nXTogKGV4cG9ydGVyOiBfRXhwb3J0ZXIpID0+IElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiB9ID0ge307XHJcblxyXG4gICAgcHJpdmF0ZSBfYXBwbHlFeHRlbnNpb248VD4oXHJcbiAgICAgICAgbm9kZTogTnVsbGFibGU8VD4sXHJcbiAgICAgICAgZXh0ZW5zaW9uczogSUdMVEZFeHBvcnRlckV4dGVuc2lvblYyW10sXHJcbiAgICAgICAgaW5kZXg6IG51bWJlcixcclxuICAgICAgICBhY3Rpb25Bc3luYzogKGV4dGVuc2lvbjogSUdMVEZFeHBvcnRlckV4dGVuc2lvblYyLCBub2RlOiBOdWxsYWJsZTxUPikgPT4gUHJvbWlzZTxOdWxsYWJsZTxUPj4gfCB1bmRlZmluZWRcclxuICAgICk6IFByb21pc2U8TnVsbGFibGU8VD4+IHtcclxuICAgICAgICBpZiAoaW5kZXggPj0gZXh0ZW5zaW9ucy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShub2RlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGN1cnJlbnRQcm9taXNlID0gYWN0aW9uQXN5bmMoZXh0ZW5zaW9uc1tpbmRleF0sIG5vZGUpO1xyXG5cclxuICAgICAgICBpZiAoIWN1cnJlbnRQcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hcHBseUV4dGVuc2lvbihub2RlLCBleHRlbnNpb25zLCBpbmRleCArIDEsIGFjdGlvbkFzeW5jKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBjdXJyZW50UHJvbWlzZS50aGVuKChuZXdOb2RlKSA9PiB0aGlzLl9hcHBseUV4dGVuc2lvbihuZXdOb2RlLCBleHRlbnNpb25zLCBpbmRleCArIDEsIGFjdGlvbkFzeW5jKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfYXBwbHlFeHRlbnNpb25zPFQ+KFxyXG4gICAgICAgIG5vZGU6IE51bGxhYmxlPFQ+LFxyXG4gICAgICAgIGFjdGlvbkFzeW5jOiAoZXh0ZW5zaW9uOiBJR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIsIG5vZGU6IE51bGxhYmxlPFQ+KSA9PiBQcm9taXNlPE51bGxhYmxlPFQ+PiB8IHVuZGVmaW5lZFxyXG4gICAgKTogUHJvbWlzZTxOdWxsYWJsZTxUPj4ge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbnM6IElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMltdID0gW107XHJcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIF9FeHBvcnRlci5fRXh0ZW5zaW9uTmFtZXMpIHtcclxuICAgICAgICAgICAgZXh0ZW5zaW9ucy5wdXNoKHRoaXMuX2V4dGVuc2lvbnNbbmFtZV0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5RXh0ZW5zaW9uKG5vZGUsIGV4dGVuc2lvbnMsIDAsIGFjdGlvbkFzeW5jKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgX2V4dGVuc2lvbnNQcmVFeHBvcnRUZXh0dXJlQXN5bmMoY29udGV4dDogc3RyaW5nLCBiYWJ5bG9uVGV4dHVyZTogTnVsbGFibGU8VGV4dHVyZT4sIG1pbWVUeXBlOiBJbWFnZU1pbWVUeXBlKTogUHJvbWlzZTxOdWxsYWJsZTxCYXNlVGV4dHVyZT4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlFeHRlbnNpb25zKGJhYnlsb25UZXh0dXJlLCAoZXh0ZW5zaW9uLCBub2RlKSA9PiBleHRlbnNpb24ucHJlRXhwb3J0VGV4dHVyZUFzeW5jICYmIGV4dGVuc2lvbi5wcmVFeHBvcnRUZXh0dXJlQXN5bmMoY29udGV4dCwgbm9kZSwgbWltZVR5cGUpKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgX2V4dGVuc2lvbnNQb3N0RXhwb3J0TWVzaFByaW1pdGl2ZUFzeW5jKFxyXG4gICAgICAgIGNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBtZXNoUHJpbWl0aXZlOiBJTWVzaFByaW1pdGl2ZSxcclxuICAgICAgICBiYWJ5bG9uU3ViTWVzaDogU3ViTWVzaCxcclxuICAgICAgICBiaW5hcnlXcml0ZXI6IF9CaW5hcnlXcml0ZXJcclxuICAgICk6IFByb21pc2U8TnVsbGFibGU8SU1lc2hQcmltaXRpdmU+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5RXh0ZW5zaW9ucyhcclxuICAgICAgICAgICAgbWVzaFByaW1pdGl2ZSxcclxuICAgICAgICAgICAgKGV4dGVuc2lvbiwgbm9kZSkgPT4gZXh0ZW5zaW9uLnBvc3RFeHBvcnRNZXNoUHJpbWl0aXZlQXN5bmMgJiYgZXh0ZW5zaW9uLnBvc3RFeHBvcnRNZXNoUHJpbWl0aXZlQXN5bmMoY29udGV4dCwgbm9kZSwgYmFieWxvblN1Yk1lc2gsIGJpbmFyeVdyaXRlcilcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBfZXh0ZW5zaW9uc1Bvc3RFeHBvcnROb2RlQXN5bmMoXHJcbiAgICAgICAgY29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIG5vZGU6IE51bGxhYmxlPElOb2RlPixcclxuICAgICAgICBiYWJ5bG9uTm9kZTogTm9kZSxcclxuICAgICAgICBub2RlTWFwOiB7IFtrZXk6IG51bWJlcl06IG51bWJlciB9LFxyXG4gICAgICAgIGJpbmFyeVdyaXRlcjogX0JpbmFyeVdyaXRlclxyXG4gICAgKTogUHJvbWlzZTxOdWxsYWJsZTxJTm9kZT4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlFeHRlbnNpb25zKG5vZGUsIChleHRlbnNpb24sIG5vZGUpID0+IGV4dGVuc2lvbi5wb3N0RXhwb3J0Tm9kZUFzeW5jICYmIGV4dGVuc2lvbi5wb3N0RXhwb3J0Tm9kZUFzeW5jKGNvbnRleHQsIG5vZGUsIGJhYnlsb25Ob2RlLCBub2RlTWFwLCBiaW5hcnlXcml0ZXIpKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgX2V4dGVuc2lvbnNQb3N0RXhwb3J0TWF0ZXJpYWxBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBOdWxsYWJsZTxJTWF0ZXJpYWw+LCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTxOdWxsYWJsZTxJTWF0ZXJpYWw+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5RXh0ZW5zaW9ucyhtYXRlcmlhbCwgKGV4dGVuc2lvbiwgbm9kZSkgPT4gZXh0ZW5zaW9uLnBvc3RFeHBvcnRNYXRlcmlhbEFzeW5jICYmIGV4dGVuc2lvbi5wb3N0RXhwb3J0TWF0ZXJpYWxBc3luYyhjb250ZXh0LCBub2RlLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgX2V4dGVuc2lvbnNQb3N0RXhwb3J0TWF0ZXJpYWxBZGRpdGlvbmFsVGV4dHVyZXMoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogQmFzZVRleHR1cmVbXSB7XHJcbiAgICAgICAgY29uc3Qgb3V0cHV0OiBCYXNlVGV4dHVyZVtdID0gW107XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBfRXhwb3J0ZXIuX0V4dGVuc2lvbk5hbWVzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IHRoaXMuX2V4dGVuc2lvbnNbbmFtZV07XHJcblxyXG4gICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLnBvc3RFeHBvcnRNYXRlcmlhbEFkZGl0aW9uYWxUZXh0dXJlcykge1xyXG4gICAgICAgICAgICAgICAgb3V0cHV0LnB1c2goLi4uZXh0ZW5zaW9uLnBvc3RFeHBvcnRNYXRlcmlhbEFkZGl0aW9uYWxUZXh0dXJlcyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBvdXRwdXQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIF9leHRlbnNpb25zUG9zdEV4cG9ydFRleHR1cmVzKGNvbnRleHQ6IHN0cmluZywgdGV4dHVyZUluZm86IElUZXh0dXJlSW5mbywgYmFieWxvblRleHR1cmU6IEJhc2VUZXh0dXJlKTogdm9pZCB7XHJcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIF9FeHBvcnRlci5fRXh0ZW5zaW9uTmFtZXMpIHtcclxuICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uID0gdGhpcy5fZXh0ZW5zaW9uc1tuYW1lXTtcclxuXHJcbiAgICAgICAgICAgIGlmIChleHRlbnNpb24ucG9zdEV4cG9ydFRleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgIGV4dGVuc2lvbi5wb3N0RXhwb3J0VGV4dHVyZShjb250ZXh0LCB0ZXh0dXJlSW5mbywgYmFieWxvblRleHR1cmUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2ZvckVhY2hFeHRlbnNpb25zKGFjdGlvbjogKGV4dGVuc2lvbjogSUdMVEZFeHBvcnRlckV4dGVuc2lvblYyKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIF9FeHBvcnRlci5fRXh0ZW5zaW9uTmFtZXMpIHtcclxuICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uID0gdGhpcy5fZXh0ZW5zaW9uc1tuYW1lXTtcclxuICAgICAgICAgICAgaWYgKGV4dGVuc2lvbi5lbmFibGVkKSB7XHJcbiAgICAgICAgICAgICAgICBhY3Rpb24oZXh0ZW5zaW9uKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9leHRlbnNpb25zT25FeHBvcnRpbmcoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fZm9yRWFjaEV4dGVuc2lvbnMoKGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLndhc1VzZWQpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9nbFRGLmV4dGVuc2lvbnNVc2VkID09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9nbFRGLmV4dGVuc2lvbnNVc2VkID0gW107XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2dsVEYuZXh0ZW5zaW9uc1VzZWQuaW5kZXhPZihleHRlbnNpb24ubmFtZSkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZ2xURi5leHRlbnNpb25zVXNlZC5wdXNoKGV4dGVuc2lvbi5uYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLnJlcXVpcmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2dsVEYuZXh0ZW5zaW9uc1JlcXVpcmVkID09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZ2xURi5leHRlbnNpb25zUmVxdWlyZWQgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2dsVEYuZXh0ZW5zaW9uc1JlcXVpcmVkLmluZGV4T2YoZXh0ZW5zaW9uLm5hbWUpID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9nbFRGLmV4dGVuc2lvbnNSZXF1aXJlZC5wdXNoKGV4dGVuc2lvbi5uYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2dsVEYuZXh0ZW5zaW9ucyA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZ2xURi5leHRlbnNpb25zID0ge307XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbi5vbkV4cG9ydGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbi5vbkV4cG9ydGluZygpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMb2FkIGdsVEYgc2VyaWFsaXplciBleHRlbnNpb25zXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX2xvYWRFeHRlbnNpb25zKCk6IHZvaWQge1xyXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBfRXhwb3J0ZXIuX0V4dGVuc2lvbk5hbWVzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IF9FeHBvcnRlci5fRXh0ZW5zaW9uRmFjdG9yaWVzW25hbWVdKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLl9leHRlbnNpb25zW25hbWVdID0gZXh0ZW5zaW9uO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBnbFRGIEV4cG9ydGVyIGluc3RhbmNlLCB3aGljaCBjYW4gYWNjZXB0IG9wdGlvbmFsIGV4cG9ydGVyIG9wdGlvbnNcclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uU2NlbmUgQmFieWxvbiBzY2VuZSBvYmplY3RcclxuICAgICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgdG8gbW9kaWZ5IHRoZSBiZWhhdmlvciBvZiB0aGUgZXhwb3J0ZXJcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKGJhYnlsb25TY2VuZT86IE51bGxhYmxlPFNjZW5lPiwgb3B0aW9ucz86IElFeHBvcnRPcHRpb25zKSB7XHJcbiAgICAgICAgdGhpcy5fZ2xURiA9IHtcclxuICAgICAgICAgICAgYXNzZXQ6IHsgZ2VuZXJhdG9yOiBgQmFieWxvbi5qcyB2JHtFbmdpbmUuVmVyc2lvbn1gLCB2ZXJzaW9uOiBcIjIuMFwiIH0sXHJcbiAgICAgICAgfTtcclxuICAgICAgICBiYWJ5bG9uU2NlbmUgPSBiYWJ5bG9uU2NlbmUgfHwgRW5naW5lU3RvcmUuTGFzdENyZWF0ZWRTY2VuZTtcclxuICAgICAgICBpZiAoIWJhYnlsb25TY2VuZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZSA9IGJhYnlsb25TY2VuZTtcclxuICAgICAgICB0aGlzLl9idWZmZXJWaWV3cyA9IFtdO1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc29ycyA9IFtdO1xyXG4gICAgICAgIHRoaXMuX21lc2hlcyA9IFtdO1xyXG4gICAgICAgIHRoaXMuX3NjZW5lcyA9IFtdO1xyXG4gICAgICAgIHRoaXMuX2NhbWVyYXMgPSBbXTtcclxuICAgICAgICB0aGlzLl9ub2RlcyA9IFtdO1xyXG4gICAgICAgIHRoaXMuX2ltYWdlcyA9IFtdO1xyXG4gICAgICAgIHRoaXMuX21hdGVyaWFscyA9IFtdO1xyXG4gICAgICAgIHRoaXMuX21hdGVyaWFsTWFwID0gW107XHJcbiAgICAgICAgdGhpcy5fdGV4dHVyZXMgPSBbXTtcclxuICAgICAgICB0aGlzLl9zYW1wbGVycyA9IFtdO1xyXG4gICAgICAgIHRoaXMuX3NraW5zID0gW107XHJcbiAgICAgICAgdGhpcy5fYW5pbWF0aW9ucyA9IFtdO1xyXG4gICAgICAgIHRoaXMuX2ltYWdlRGF0YSA9IHt9O1xyXG4gICAgICAgIHRoaXMuX29yZGVyZWRJbWFnZURhdGEgPSBbXTtcclxuICAgICAgICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuICAgICAgICB0aGlzLl9hbmltYXRpb25TYW1wbGVSYXRlID0gdGhpcy5fb3B0aW9ucy5hbmltYXRpb25TYW1wbGVSYXRlIHx8IDEgLyA2MDtcclxuXHJcbiAgICAgICAgdGhpcy5fZ2xURk1hdGVyaWFsRXhwb3J0ZXIgPSBuZXcgX0dMVEZNYXRlcmlhbEV4cG9ydGVyKHRoaXMpO1xyXG4gICAgICAgIHRoaXMuX2xvYWRFeHRlbnNpb25zKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgZm9yIChjb25zdCBleHRlbnNpb25LZXkgaW4gdGhpcy5fZXh0ZW5zaW9ucykge1xyXG4gICAgICAgICAgICBjb25zdCBleHRlbnNpb24gPSB0aGlzLl9leHRlbnNpb25zW2V4dGVuc2lvbktleV07XHJcblxyXG4gICAgICAgICAgICBleHRlbnNpb24uZGlzcG9zZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0IG9wdGlvbnMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX29wdGlvbnM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWdpc3RlcnMgYSBnbFRGIGV4cG9ydGVyIGV4dGVuc2lvblxyXG4gICAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHRvIGV4cG9ydFxyXG4gICAgICogQHBhcmFtIGZhY3RvcnkgVGhlIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIHRoZSBleHBvcnRlciBleHRlbnNpb25cclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBSZWdpc3RlckV4dGVuc2lvbihuYW1lOiBzdHJpbmcsIGZhY3Rvcnk6IChleHBvcnRlcjogX0V4cG9ydGVyKSA9PiBJR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIpOiB2b2lkIHtcclxuICAgICAgICBpZiAoX0V4cG9ydGVyLlVucmVnaXN0ZXJFeHRlbnNpb24obmFtZSkpIHtcclxuICAgICAgICAgICAgVG9vbHMuV2FybihgRXh0ZW5zaW9uIHdpdGggdGhlIG5hbWUgJHtuYW1lfSBhbHJlYWR5IGV4aXN0c2ApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgX0V4cG9ydGVyLl9FeHRlbnNpb25GYWN0b3JpZXNbbmFtZV0gPSBmYWN0b3J5O1xyXG4gICAgICAgIF9FeHBvcnRlci5fRXh0ZW5zaW9uTmFtZXMucHVzaChuYW1lKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFVuLXJlZ2lzdGVycyBhbiBleHBvcnRlciBleHRlbnNpb25cclxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIGZvIHRoZSBleHBvcnRlciBleHRlbnNpb25cclxuICAgICAqIEByZXR1cm5zIEEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGV4dGVuc2lvbiBoYXMgYmVlbiB1bi1yZWdpc3RlcmVkXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgVW5yZWdpc3RlckV4dGVuc2lvbihuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAoIV9FeHBvcnRlci5fRXh0ZW5zaW9uRmFjdG9yaWVzW25hbWVdKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZGVsZXRlIF9FeHBvcnRlci5fRXh0ZW5zaW9uRmFjdG9yaWVzW25hbWVdO1xyXG5cclxuICAgICAgICBjb25zdCBpbmRleCA9IF9FeHBvcnRlci5fRXh0ZW5zaW9uTmFtZXMuaW5kZXhPZihuYW1lKTtcclxuICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XHJcbiAgICAgICAgICAgIF9FeHBvcnRlci5fRXh0ZW5zaW9uTmFtZXMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3Jlb3JkZXJJbmRpY2VzQmFzZWRPblByaW1pdGl2ZU1vZGUoc3VibWVzaDogU3ViTWVzaCwgcHJpbWl0aXZlTW9kZTogbnVtYmVyLCBiYWJ5bG9uSW5kaWNlczogSW5kaWNlc0FycmF5LCBieXRlT2Zmc2V0OiBudW1iZXIsIGJpbmFyeVdyaXRlcjogX0JpbmFyeVdyaXRlcikge1xyXG4gICAgICAgIHN3aXRjaCAocHJpbWl0aXZlTW9kZSkge1xyXG4gICAgICAgICAgICBjYXNlIE1hdGVyaWFsLlRyaWFuZ2xlRmlsbE1vZGU6IHtcclxuICAgICAgICAgICAgICAgIGlmICghYnl0ZU9mZnNldCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJ5dGVPZmZzZXQgPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHN1Ym1lc2guaW5kZXhTdGFydCwgbGVuZ3RoID0gc3VibWVzaC5pbmRleFN0YXJ0ICsgc3VibWVzaC5pbmRleENvdW50OyBpIDwgbGVuZ3RoOyBpID0gaSArIDMpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IGJ5dGVPZmZzZXQgKyBpICogNDtcclxuICAgICAgICAgICAgICAgICAgICAvLyBzd2FwIHRoZSBzZWNvbmQgYW5kIHRoaXJkIGluZGljZXNcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzZWNvbmRJbmRleCA9IGJpbmFyeVdyaXRlci5nZXRVSW50MzIoaW5kZXggKyA0KTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0aGlyZEluZGV4ID0gYmluYXJ5V3JpdGVyLmdldFVJbnQzMihpbmRleCArIDgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJpbmFyeVdyaXRlci5zZXRVSW50MzIodGhpcmRJbmRleCwgaW5kZXggKyA0KTtcclxuICAgICAgICAgICAgICAgICAgICBiaW5hcnlXcml0ZXIuc2V0VUludDMyKHNlY29uZEluZGV4LCBpbmRleCArIDgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBNYXRlcmlhbC5UcmlhbmdsZUZhbkRyYXdNb2RlOiB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gc3VibWVzaC5pbmRleFN0YXJ0ICsgc3VibWVzaC5pbmRleENvdW50IC0gMSwgc3RhcnQgPSBzdWJtZXNoLmluZGV4U3RhcnQ7IGkgPj0gc3RhcnQ7IC0taSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJpbmFyeVdyaXRlci5zZXRVSW50MzIoYmFieWxvbkluZGljZXNbaV0sIGJ5dGVPZmZzZXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJ5dGVPZmZzZXQgKz0gNDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgTWF0ZXJpYWwuVHJpYW5nbGVTdHJpcERyYXdNb2RlOiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3VibWVzaC5pbmRleENvdW50ID49IDMpIHtcclxuICAgICAgICAgICAgICAgICAgICBiaW5hcnlXcml0ZXIuc2V0VUludDMyKGJhYnlsb25JbmRpY2VzW3N1Ym1lc2guaW5kZXhTdGFydCArIDJdLCBieXRlT2Zmc2V0ICsgNCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYmluYXJ5V3JpdGVyLnNldFVJbnQzMihiYWJ5bG9uSW5kaWNlc1tzdWJtZXNoLmluZGV4U3RhcnQgKyAxXSwgYnl0ZU9mZnNldCArIDgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZW9yZGVycyB0aGUgdmVydGV4IGF0dHJpYnV0ZSBkYXRhIGJhc2VkIG9uIHRoZSBwcmltaXRpdmUgbW9kZS4gIFRoaXMgaXMgbmVjZXNzYXJ5IHdoZW4gaW5kaWNlcyBhcmUgbm90IGF2YWlsYWJsZSBhbmQgdGhlIHdpbmRpbmcgb3JkZXIgaXNcclxuICAgICAqIGNsb2NrLXdpc2UgZHVyaW5nIGV4cG9ydCB0byBnbFRGXHJcbiAgICAgKiBAcGFyYW0gc3VibWVzaCBCYWJ5bG9uSlMgc3VibWVzaFxyXG4gICAgICogQHBhcmFtIHByaW1pdGl2ZU1vZGUgUHJpbWl0aXZlIG1vZGUgb2YgdGhlIG1lc2hcclxuICAgICAqIEBwYXJhbSB2ZXJ0ZXhCdWZmZXJLaW5kIFRoZSB0eXBlIG9mIHZlcnRleCBhdHRyaWJ1dGVcclxuICAgICAqIEBwYXJhbSBtZXNoQXR0cmlidXRlQXJyYXkgVGhlIHZlcnRleCBhdHRyaWJ1dGUgZGF0YVxyXG4gICAgICogQHBhcmFtIGJ5dGVPZmZzZXQgVGhlIG9mZnNldCB0byB0aGUgYmluYXJ5IGRhdGFcclxuICAgICAqIEBwYXJhbSBiaW5hcnlXcml0ZXIgVGhlIGJpbmFyeSBkYXRhIGZvciB0aGUgZ2xURiBmaWxlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX3Jlb3JkZXJWZXJ0ZXhBdHRyaWJ1dGVEYXRhQmFzZWRPblByaW1pdGl2ZU1vZGUoXHJcbiAgICAgICAgc3VibWVzaDogU3ViTWVzaCxcclxuICAgICAgICBwcmltaXRpdmVNb2RlOiBudW1iZXIsXHJcbiAgICAgICAgdmVydGV4QnVmZmVyS2luZDogc3RyaW5nLFxyXG4gICAgICAgIG1lc2hBdHRyaWJ1dGVBcnJheTogRmxvYXRBcnJheSxcclxuICAgICAgICBieXRlT2Zmc2V0OiBudW1iZXIsXHJcbiAgICAgICAgYmluYXJ5V3JpdGVyOiBfQmluYXJ5V3JpdGVyXHJcbiAgICApOiB2b2lkIHtcclxuICAgICAgICBzd2l0Y2ggKHByaW1pdGl2ZU1vZGUpIHtcclxuICAgICAgICAgICAgY2FzZSBNYXRlcmlhbC5UcmlhbmdsZUZpbGxNb2RlOiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9yZW9yZGVyVHJpYW5nbGVGaWxsTW9kZShzdWJtZXNoLCB2ZXJ0ZXhCdWZmZXJLaW5kLCBtZXNoQXR0cmlidXRlQXJyYXksIGJ5dGVPZmZzZXQsIGJpbmFyeVdyaXRlcik7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIE1hdGVyaWFsLlRyaWFuZ2xlU3RyaXBEcmF3TW9kZToge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fcmVvcmRlclRyaWFuZ2xlU3RyaXBEcmF3TW9kZShzdWJtZXNoLCB2ZXJ0ZXhCdWZmZXJLaW5kLCBtZXNoQXR0cmlidXRlQXJyYXksIGJ5dGVPZmZzZXQsIGJpbmFyeVdyaXRlcik7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIE1hdGVyaWFsLlRyaWFuZ2xlRmFuRHJhd01vZGU6IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3Jlb3JkZXJUcmlhbmdsZUZhbk1vZGUoc3VibWVzaCwgdmVydGV4QnVmZmVyS2luZCwgbWVzaEF0dHJpYnV0ZUFycmF5LCBieXRlT2Zmc2V0LCBiaW5hcnlXcml0ZXIpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZW9yZGVycyB0aGUgdmVydGV4IGF0dHJpYnV0ZXMgaW4gdGhlIGNvcnJlY3QgdHJpYW5nbGUgbW9kZSBvcmRlciAuICBUaGlzIGlzIG5lY2Vzc2FyeSB3aGVuIGluZGljZXMgYXJlIG5vdCBhdmFpbGFibGUgYW5kIHRoZSB3aW5kaW5nIG9yZGVyIGlzXHJcbiAgICAgKiBjbG9jay13aXNlIGR1cmluZyBleHBvcnQgdG8gZ2xURlxyXG4gICAgICogQHBhcmFtIHN1Ym1lc2ggQmFieWxvbkpTIHN1Ym1lc2hcclxuICAgICAqIEBwYXJhbSB2ZXJ0ZXhCdWZmZXJLaW5kIFRoZSB0eXBlIG9mIHZlcnRleCBhdHRyaWJ1dGVcclxuICAgICAqIEBwYXJhbSBtZXNoQXR0cmlidXRlQXJyYXkgVGhlIHZlcnRleCBhdHRyaWJ1dGUgZGF0YVxyXG4gICAgICogQHBhcmFtIGJ5dGVPZmZzZXQgVGhlIG9mZnNldCB0byB0aGUgYmluYXJ5IGRhdGFcclxuICAgICAqIEBwYXJhbSBiaW5hcnlXcml0ZXIgVGhlIGJpbmFyeSBkYXRhIGZvciB0aGUgZ2xURiBmaWxlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX3Jlb3JkZXJUcmlhbmdsZUZpbGxNb2RlKHN1Ym1lc2g6IFN1Yk1lc2gsIHZlcnRleEJ1ZmZlcktpbmQ6IHN0cmluZywgbWVzaEF0dHJpYnV0ZUFycmF5OiBGbG9hdEFycmF5LCBieXRlT2Zmc2V0OiBudW1iZXIsIGJpbmFyeVdyaXRlcjogX0JpbmFyeVdyaXRlcikge1xyXG4gICAgICAgIGNvbnN0IHZlcnRleEJ1ZmZlciA9IHRoaXMuX2dldFZlcnRleEJ1ZmZlckZyb21NZXNoKHZlcnRleEJ1ZmZlcktpbmQsIHN1Ym1lc2guZ2V0TWVzaCgpIGFzIE1lc2gpO1xyXG4gICAgICAgIGlmICh2ZXJ0ZXhCdWZmZXIpIHtcclxuICAgICAgICAgICAgY29uc3Qgc3RyaWRlID0gdmVydGV4QnVmZmVyLmJ5dGVTdHJpZGUgLyBWZXJ0ZXhCdWZmZXIuR2V0VHlwZUJ5dGVMZW5ndGgodmVydGV4QnVmZmVyLnR5cGUpO1xyXG4gICAgICAgICAgICBpZiAoc3VibWVzaC52ZXJ0aWNlc0NvdW50ICUgMyAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgVG9vbHMuRXJyb3IoXCJUaGUgc3VibWVzaCB2ZXJ0aWNlcyBmb3IgdGhlIHRyaWFuZ2xlIGZpbGwgbW9kZSBpcyBub3QgZGl2aXNpYmxlIGJ5IDMhXCIpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdmVydGV4RGF0YTogVmVjdG9yMltdIHwgVmVjdG9yM1tdIHwgVmVjdG9yNFtdID0gW107XHJcbiAgICAgICAgICAgICAgICBsZXQgaW5kZXggPSAwO1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoICh2ZXJ0ZXhCdWZmZXJLaW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBWZXJ0ZXhCdWZmZXIuUG9zaXRpb25LaW5kOlxyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLk5vcm1hbEtpbmQ6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgeCA9IHN1Ym1lc2gudmVydGljZXNTdGFydDsgeCA8IHN1Ym1lc2gudmVydGljZXNTdGFydCArIHN1Ym1lc2gudmVydGljZXNDb3VudDsgeCA9IHggKyAzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IHggKiBzdHJpZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodmVydGV4RGF0YSBhcyBWZWN0b3IzW10pLnB1c2goVmVjdG9yMy5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZlcnRleERhdGEgYXMgVmVjdG9yM1tdKS5wdXNoKFZlY3RvcjMuRnJvbUFycmF5KG1lc2hBdHRyaWJ1dGVBcnJheSwgaW5kZXggKyAyICogc3RyaWRlKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodmVydGV4RGF0YSBhcyBWZWN0b3IzW10pLnB1c2goVmVjdG9yMy5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCArIHN0cmlkZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjYXNlIFZlcnRleEJ1ZmZlci5UYW5nZW50S2luZDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCB4ID0gc3VibWVzaC52ZXJ0aWNlc1N0YXJ0OyB4IDwgc3VibWVzaC52ZXJ0aWNlc1N0YXJ0ICsgc3VibWVzaC52ZXJ0aWNlc0NvdW50OyB4ID0geCArIDMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0geCAqIHN0cmlkZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2ZXJ0ZXhEYXRhIGFzIFZlY3RvcjRbXSkucHVzaChWZWN0b3I0LkZyb21BcnJheShtZXNoQXR0cmlidXRlQXJyYXksIGluZGV4KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodmVydGV4RGF0YSBhcyBWZWN0b3I0W10pLnB1c2goVmVjdG9yNC5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCArIDIgKiBzdHJpZGUpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2ZXJ0ZXhEYXRhIGFzIFZlY3RvcjRbXSkucHVzaChWZWN0b3I0LkZyb21BcnJheShtZXNoQXR0cmlidXRlQXJyYXksIGluZGV4ICsgc3RyaWRlKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLkNvbG9yS2luZDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzaXplID0gdmVydGV4QnVmZmVyLmdldFNpemUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgeCA9IHN1Ym1lc2gudmVydGljZXNTdGFydDsgeCA8IHN1Ym1lc2gudmVydGljZXNTdGFydCArIHN1Ym1lc2gudmVydGljZXNDb3VudDsgeCA9IHggKyBzaXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IHggKiBzdHJpZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZSA9PT0gNCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2ZXJ0ZXhEYXRhIGFzIFZlY3RvcjRbXSkucHVzaChWZWN0b3I0LkZyb21BcnJheShtZXNoQXR0cmlidXRlQXJyYXksIGluZGV4KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZlcnRleERhdGEgYXMgVmVjdG9yNFtdKS5wdXNoKFZlY3RvcjQuRnJvbUFycmF5KG1lc2hBdHRyaWJ1dGVBcnJheSwgaW5kZXggKyAyICogc3RyaWRlKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZlcnRleERhdGEgYXMgVmVjdG9yNFtdKS5wdXNoKFZlY3RvcjQuRnJvbUFycmF5KG1lc2hBdHRyaWJ1dGVBcnJheSwgaW5kZXggKyBzdHJpZGUpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZlcnRleERhdGEgYXMgVmVjdG9yM1tdKS5wdXNoKFZlY3RvcjMuRnJvbUFycmF5KG1lc2hBdHRyaWJ1dGVBcnJheSwgaW5kZXgpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodmVydGV4RGF0YSBhcyBWZWN0b3IzW10pLnB1c2goVmVjdG9yMy5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCArIDIgKiBzdHJpZGUpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodmVydGV4RGF0YSBhcyBWZWN0b3IzW10pLnB1c2goVmVjdG9yMy5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCArIHN0cmlkZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjYXNlIFZlcnRleEJ1ZmZlci5VVktpbmQ6XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBWZXJ0ZXhCdWZmZXIuVVYyS2luZDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCB4ID0gc3VibWVzaC52ZXJ0aWNlc1N0YXJ0OyB4IDwgc3VibWVzaC52ZXJ0aWNlc1N0YXJ0ICsgc3VibWVzaC52ZXJ0aWNlc0NvdW50OyB4ID0geCArIDMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0geCAqIHN0cmlkZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2ZXJ0ZXhEYXRhIGFzIFZlY3RvcjJbXSkucHVzaChWZWN0b3IyLkZyb21BcnJheShtZXNoQXR0cmlidXRlQXJyYXksIGluZGV4KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodmVydGV4RGF0YSBhcyBWZWN0b3IyW10pLnB1c2goVmVjdG9yMi5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCArIDIgKiBzdHJpZGUpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2ZXJ0ZXhEYXRhIGFzIFZlY3RvcjJbXSkucHVzaChWZWN0b3IyLkZyb21BcnJheShtZXNoQXR0cmlidXRlQXJyYXksIGluZGV4ICsgc3RyaWRlKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgVG9vbHMuRXJyb3IoYFVuc3VwcG9ydGVkIFZlcnRleCBCdWZmZXIgdHlwZTogJHt2ZXJ0ZXhCdWZmZXJLaW5kfWApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMuX3dyaXRlVmVydGV4QXR0cmlidXRlRGF0YSh2ZXJ0ZXhEYXRhLCBieXRlT2Zmc2V0LCB2ZXJ0ZXhCdWZmZXJLaW5kLCBiaW5hcnlXcml0ZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgVG9vbHMuV2FybihgcmVvcmRlclRyaWFuZ2xlRmlsbE1vZGU6IFZlcnRleCBCdWZmZXIgS2luZCAke3ZlcnRleEJ1ZmZlcktpbmR9IG5vdCBwcmVzZW50IWApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlb3JkZXJzIHRoZSB2ZXJ0ZXggYXR0cmlidXRlcyBpbiB0aGUgY29ycmVjdCB0cmlhbmdsZSBzdHJpcCBvcmRlci4gIFRoaXMgaXMgbmVjZXNzYXJ5IHdoZW4gaW5kaWNlcyBhcmUgbm90IGF2YWlsYWJsZSBhbmQgdGhlIHdpbmRpbmcgb3JkZXIgaXNcclxuICAgICAqIGNsb2NrLXdpc2UgZHVyaW5nIGV4cG9ydCB0byBnbFRGXHJcbiAgICAgKiBAcGFyYW0gc3VibWVzaCBCYWJ5bG9uSlMgc3VibWVzaFxyXG4gICAgICogQHBhcmFtIHZlcnRleEJ1ZmZlcktpbmQgVGhlIHR5cGUgb2YgdmVydGV4IGF0dHJpYnV0ZVxyXG4gICAgICogQHBhcmFtIG1lc2hBdHRyaWJ1dGVBcnJheSBUaGUgdmVydGV4IGF0dHJpYnV0ZSBkYXRhXHJcbiAgICAgKiBAcGFyYW0gYnl0ZU9mZnNldCBUaGUgb2Zmc2V0IHRvIHRoZSBiaW5hcnkgZGF0YVxyXG4gICAgICogQHBhcmFtIGJpbmFyeVdyaXRlciBUaGUgYmluYXJ5IGRhdGEgZm9yIHRoZSBnbFRGIGZpbGVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfcmVvcmRlclRyaWFuZ2xlU3RyaXBEcmF3TW9kZShzdWJtZXNoOiBTdWJNZXNoLCB2ZXJ0ZXhCdWZmZXJLaW5kOiBzdHJpbmcsIG1lc2hBdHRyaWJ1dGVBcnJheTogRmxvYXRBcnJheSwgYnl0ZU9mZnNldDogbnVtYmVyLCBiaW5hcnlXcml0ZXI6IF9CaW5hcnlXcml0ZXIpIHtcclxuICAgICAgICBjb25zdCB2ZXJ0ZXhCdWZmZXIgPSB0aGlzLl9nZXRWZXJ0ZXhCdWZmZXJGcm9tTWVzaCh2ZXJ0ZXhCdWZmZXJLaW5kLCBzdWJtZXNoLmdldE1lc2goKSBhcyBNZXNoKTtcclxuICAgICAgICBpZiAodmVydGV4QnVmZmVyKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHN0cmlkZSA9IHZlcnRleEJ1ZmZlci5ieXRlU3RyaWRlIC8gVmVydGV4QnVmZmVyLkdldFR5cGVCeXRlTGVuZ3RoKHZlcnRleEJ1ZmZlci50eXBlKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHZlcnRleERhdGE6IFZlY3RvcjJbXSB8IFZlY3RvcjNbXSB8IFZlY3RvcjRbXSA9IFtdO1xyXG4gICAgICAgICAgICBsZXQgaW5kZXggPSAwO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKHZlcnRleEJ1ZmZlcktpbmQpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLlBvc2l0aW9uS2luZDpcclxuICAgICAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLk5vcm1hbEtpbmQ6IHtcclxuICAgICAgICAgICAgICAgICAgICBpbmRleCA9IHN1Ym1lc2gudmVydGljZXNTdGFydDtcclxuICAgICAgICAgICAgICAgICAgICAodmVydGV4RGF0YSBhcyBWZWN0b3IzW10pLnB1c2goVmVjdG9yMy5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCArIDIgKiBzdHJpZGUpKTtcclxuICAgICAgICAgICAgICAgICAgICAodmVydGV4RGF0YSBhcyBWZWN0b3IzW10pLnB1c2goVmVjdG9yMy5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCArIHN0cmlkZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY2FzZSBWZXJ0ZXhCdWZmZXIuVGFuZ2VudEtpbmQ6IHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCB4ID0gc3VibWVzaC52ZXJ0aWNlc1N0YXJ0ICsgc3VibWVzaC52ZXJ0aWNlc0NvdW50IC0gMTsgeCA+PSBzdWJtZXNoLnZlcnRpY2VzU3RhcnQ7IC0teCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IHggKiBzdHJpZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICh2ZXJ0ZXhEYXRhIGFzIFZlY3RvcjRbXSkucHVzaChWZWN0b3I0LkZyb21BcnJheShtZXNoQXR0cmlidXRlQXJyYXksIGluZGV4KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY2FzZSBWZXJ0ZXhCdWZmZXIuQ29sb3JLaW5kOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgeCA9IHN1Ym1lc2gudmVydGljZXNTdGFydCArIHN1Ym1lc2gudmVydGljZXNDb3VudCAtIDE7IHggPj0gc3VibWVzaC52ZXJ0aWNlc1N0YXJ0OyAtLXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSB4ICogc3RyaWRlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJ0ZXhCdWZmZXIuZ2V0U2l6ZSgpID09PSA0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICh2ZXJ0ZXhEYXRhIGFzIFZlY3RvcjRbXSkucHVzaChWZWN0b3I0LkZyb21BcnJheShtZXNoQXR0cmlidXRlQXJyYXksIGluZGV4KSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKHZlcnRleERhdGEgYXMgVmVjdG9yM1tdKS5wdXNoKFZlY3RvcjMuRnJvbUFycmF5KG1lc2hBdHRyaWJ1dGVBcnJheSwgaW5kZXgpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjYXNlIFZlcnRleEJ1ZmZlci5VVktpbmQ6XHJcbiAgICAgICAgICAgICAgICBjYXNlIFZlcnRleEJ1ZmZlci5VVjJLaW5kOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgeCA9IHN1Ym1lc2gudmVydGljZXNTdGFydCArIHN1Ym1lc2gudmVydGljZXNDb3VudCAtIDE7IHggPj0gc3VibWVzaC52ZXJ0aWNlc1N0YXJ0OyAtLXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSB4ICogc3RyaWRlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAodmVydGV4RGF0YSBhcyBWZWN0b3IyW10pLnB1c2goVmVjdG9yMi5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcclxuICAgICAgICAgICAgICAgICAgICBUb29scy5FcnJvcihgVW5zdXBwb3J0ZWQgVmVydGV4IEJ1ZmZlciB0eXBlOiAke3ZlcnRleEJ1ZmZlcktpbmR9YCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fd3JpdGVWZXJ0ZXhBdHRyaWJ1dGVEYXRhKHZlcnRleERhdGEsIGJ5dGVPZmZzZXQgKyAxMiwgdmVydGV4QnVmZmVyS2luZCwgYmluYXJ5V3JpdGVyKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBUb29scy5XYXJuKGByZW9yZGVyVHJpYW5nbGVTdHJpcERyYXdNb2RlOiBWZXJ0ZXggYnVmZmVyIGtpbmQgJHt2ZXJ0ZXhCdWZmZXJLaW5kfSBub3QgcHJlc2VudCFgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZW9yZGVycyB0aGUgdmVydGV4IGF0dHJpYnV0ZXMgaW4gdGhlIGNvcnJlY3QgdHJpYW5nbGUgZmFuIG9yZGVyLiAgVGhpcyBpcyBuZWNlc3Nhcnkgd2hlbiBpbmRpY2VzIGFyZSBub3QgYXZhaWxhYmxlIGFuZCB0aGUgd2luZGluZyBvcmRlciBpc1xyXG4gICAgICogY2xvY2std2lzZSBkdXJpbmcgZXhwb3J0IHRvIGdsVEZcclxuICAgICAqIEBwYXJhbSBzdWJtZXNoIEJhYnlsb25KUyBzdWJtZXNoXHJcbiAgICAgKiBAcGFyYW0gdmVydGV4QnVmZmVyS2luZCBUaGUgdHlwZSBvZiB2ZXJ0ZXggYXR0cmlidXRlXHJcbiAgICAgKiBAcGFyYW0gbWVzaEF0dHJpYnV0ZUFycmF5IFRoZSB2ZXJ0ZXggYXR0cmlidXRlIGRhdGFcclxuICAgICAqIEBwYXJhbSBieXRlT2Zmc2V0IFRoZSBvZmZzZXQgdG8gdGhlIGJpbmFyeSBkYXRhXHJcbiAgICAgKiBAcGFyYW0gYmluYXJ5V3JpdGVyIFRoZSBiaW5hcnkgZGF0YSBmb3IgdGhlIGdsVEYgZmlsZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9yZW9yZGVyVHJpYW5nbGVGYW5Nb2RlKHN1Ym1lc2g6IFN1Yk1lc2gsIHZlcnRleEJ1ZmZlcktpbmQ6IHN0cmluZywgbWVzaEF0dHJpYnV0ZUFycmF5OiBGbG9hdEFycmF5LCBieXRlT2Zmc2V0OiBudW1iZXIsIGJpbmFyeVdyaXRlcjogX0JpbmFyeVdyaXRlcikge1xyXG4gICAgICAgIGNvbnN0IHZlcnRleEJ1ZmZlciA9IHRoaXMuX2dldFZlcnRleEJ1ZmZlckZyb21NZXNoKHZlcnRleEJ1ZmZlcktpbmQsIHN1Ym1lc2guZ2V0TWVzaCgpIGFzIE1lc2gpO1xyXG4gICAgICAgIGlmICh2ZXJ0ZXhCdWZmZXIpIHtcclxuICAgICAgICAgICAgY29uc3Qgc3RyaWRlID0gdmVydGV4QnVmZmVyLmJ5dGVTdHJpZGUgLyBWZXJ0ZXhCdWZmZXIuR2V0VHlwZUJ5dGVMZW5ndGgodmVydGV4QnVmZmVyLnR5cGUpO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgdmVydGV4RGF0YTogVmVjdG9yMltdIHwgVmVjdG9yM1tdIHwgVmVjdG9yNFtdID0gW107XHJcbiAgICAgICAgICAgIGxldCBpbmRleCA9IDA7XHJcbiAgICAgICAgICAgIHN3aXRjaCAodmVydGV4QnVmZmVyS2luZCkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSBWZXJ0ZXhCdWZmZXIuUG9zaXRpb25LaW5kOlxyXG4gICAgICAgICAgICAgICAgY2FzZSBWZXJ0ZXhCdWZmZXIuTm9ybWFsS2luZDoge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHggPSBzdWJtZXNoLnZlcnRpY2VzU3RhcnQgKyBzdWJtZXNoLnZlcnRpY2VzQ291bnQgLSAxOyB4ID49IHN1Ym1lc2gudmVydGljZXNTdGFydDsgLS14KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0geCAqIHN0cmlkZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgKHZlcnRleERhdGEgYXMgVmVjdG9yM1tdKS5wdXNoKFZlY3RvcjMuRnJvbUFycmF5KG1lc2hBdHRyaWJ1dGVBcnJheSwgaW5kZXgpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjYXNlIFZlcnRleEJ1ZmZlci5UYW5nZW50S2luZDoge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHggPSBzdWJtZXNoLnZlcnRpY2VzU3RhcnQgKyBzdWJtZXNoLnZlcnRpY2VzQ291bnQgLSAxOyB4ID49IHN1Ym1lc2gudmVydGljZXNTdGFydDsgLS14KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0geCAqIHN0cmlkZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgKHZlcnRleERhdGEgYXMgVmVjdG9yNFtdKS5wdXNoKFZlY3RvcjQuRnJvbUFycmF5KG1lc2hBdHRyaWJ1dGVBcnJheSwgaW5kZXgpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjYXNlIFZlcnRleEJ1ZmZlci5Db2xvcktpbmQ6IHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCB4ID0gc3VibWVzaC52ZXJ0aWNlc1N0YXJ0ICsgc3VibWVzaC52ZXJ0aWNlc0NvdW50IC0gMTsgeCA+PSBzdWJtZXNoLnZlcnRpY2VzU3RhcnQ7IC0teCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IHggKiBzdHJpZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICh2ZXJ0ZXhEYXRhIGFzIFZlY3RvcjRbXSkucHVzaChWZWN0b3I0LkZyb21BcnJheShtZXNoQXR0cmlidXRlQXJyYXksIGluZGV4KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcnRleEJ1ZmZlci5nZXRTaXplKCkgPT09IDRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gKHZlcnRleERhdGEgYXMgVmVjdG9yNFtdKS5wdXNoKFZlY3RvcjQuRnJvbUFycmF5KG1lc2hBdHRyaWJ1dGVBcnJheSwgaW5kZXgpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAodmVydGV4RGF0YSBhcyBWZWN0b3IzW10pLnB1c2goVmVjdG9yMy5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLlVWS2luZDpcclxuICAgICAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLlVWMktpbmQ6IHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCB4ID0gc3VibWVzaC52ZXJ0aWNlc1N0YXJ0ICsgc3VibWVzaC52ZXJ0aWNlc0NvdW50IC0gMTsgeCA+PSBzdWJtZXNoLnZlcnRpY2VzU3RhcnQ7IC0teCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IHggKiBzdHJpZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICh2ZXJ0ZXhEYXRhIGFzIFZlY3RvcjJbXSkucHVzaChWZWN0b3IyLkZyb21BcnJheShtZXNoQXR0cmlidXRlQXJyYXksIGluZGV4KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDoge1xyXG4gICAgICAgICAgICAgICAgICAgIFRvb2xzLkVycm9yKGBVbnN1cHBvcnRlZCBWZXJ0ZXggQnVmZmVyIHR5cGU6ICR7dmVydGV4QnVmZmVyS2luZH1gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLl93cml0ZVZlcnRleEF0dHJpYnV0ZURhdGEodmVydGV4RGF0YSwgYnl0ZU9mZnNldCwgdmVydGV4QnVmZmVyS2luZCwgYmluYXJ5V3JpdGVyKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBUb29scy5XYXJuKGByZW9yZGVyVHJpYW5nbGVGYW5Nb2RlOiBWZXJ0ZXggYnVmZmVyIGtpbmQgJHt2ZXJ0ZXhCdWZmZXJLaW5kfSBub3QgcHJlc2VudCFgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgdGhlIHZlcnRleCBhdHRyaWJ1dGUgZGF0YSB0byBiaW5hcnlcclxuICAgICAqIEBwYXJhbSB2ZXJ0aWNlcyBUaGUgdmVydGljZXMgdG8gd3JpdGUgdG8gdGhlIGJpbmFyeSB3cml0ZXJcclxuICAgICAqIEBwYXJhbSBieXRlT2Zmc2V0IFRoZSBvZmZzZXQgaW50byB0aGUgYmluYXJ5IHdyaXRlciB0byBvdmVyd3JpdGUgYmluYXJ5IGRhdGFcclxuICAgICAqIEBwYXJhbSB2ZXJ0ZXhBdHRyaWJ1dGVLaW5kIFRoZSB2ZXJ0ZXggYXR0cmlidXRlIHR5cGVcclxuICAgICAqIEBwYXJhbSBiaW5hcnlXcml0ZXIgVGhlIHdyaXRlciBjb250YWluaW5nIHRoZSBiaW5hcnkgZGF0YVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF93cml0ZVZlcnRleEF0dHJpYnV0ZURhdGEodmVydGljZXM6IFZlY3RvcjJbXSB8IFZlY3RvcjNbXSB8IFZlY3RvcjRbXSwgYnl0ZU9mZnNldDogbnVtYmVyLCB2ZXJ0ZXhBdHRyaWJ1dGVLaW5kOiBzdHJpbmcsIGJpbmFyeVdyaXRlcjogX0JpbmFyeVdyaXRlcikge1xyXG4gICAgICAgIGZvciAoY29uc3QgdmVydGV4IG9mIHZlcnRpY2VzKSB7XHJcbiAgICAgICAgICAgIGlmICh2ZXJ0ZXhBdHRyaWJ1dGVLaW5kID09PSBWZXJ0ZXhCdWZmZXIuTm9ybWFsS2luZCkge1xyXG4gICAgICAgICAgICAgICAgdmVydGV4Lm5vcm1hbGl6ZSgpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZlcnRleEF0dHJpYnV0ZUtpbmQgPT09IFZlcnRleEJ1ZmZlci5UYW5nZW50S2luZCAmJiB2ZXJ0ZXggaW5zdGFuY2VvZiBWZWN0b3I0KSB7XHJcbiAgICAgICAgICAgICAgICBfR0xURlV0aWxpdGllcy5fTm9ybWFsaXplVGFuZ2VudEZyb21SZWYodmVydGV4KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgdmVydGV4LmFzQXJyYXkoKSkge1xyXG4gICAgICAgICAgICAgICAgYmluYXJ5V3JpdGVyLnNldEZsb2F0MzIoY29tcG9uZW50LCBieXRlT2Zmc2V0KTtcclxuICAgICAgICAgICAgICAgIGJ5dGVPZmZzZXQgKz0gNDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBtZXNoIGF0dHJpYnV0ZSBkYXRhIHRvIGEgZGF0YSBidWZmZXJcclxuICAgICAqIFJldHVybnMgdGhlIGJ5dGVsZW5ndGggb2YgdGhlIGRhdGFcclxuICAgICAqIEBwYXJhbSB2ZXJ0ZXhCdWZmZXJLaW5kIEluZGljYXRlcyB3aGF0IGtpbmQgb2YgdmVydGV4IGRhdGEgaXMgYmVpbmcgcGFzc2VkIGluXHJcbiAgICAgKiBAcGFyYW0gYXR0cmlidXRlQ29tcG9uZW50S2luZFxyXG4gICAgICogQHBhcmFtIG1lc2hBdHRyaWJ1dGVBcnJheSBBcnJheSBjb250YWluaW5nIHRoZSBhdHRyaWJ1dGUgZGF0YVxyXG4gICAgICogQHBhcmFtIHN0cmlkZSBTcGVjaWZpZXMgdGhlIHNwYWNlIGJldHdlZW4gZGF0YVxyXG4gICAgICogQHBhcmFtIGJpbmFyeVdyaXRlciBUaGUgYnVmZmVyIHRvIHdyaXRlIHRoZSBiaW5hcnkgZGF0YSB0b1xyXG4gICAgICogQHBhcmFtIGJhYnlsb25UcmFuc2Zvcm1Ob2RlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfd3JpdGVBdHRyaWJ1dGVEYXRhKFxyXG4gICAgICAgIHZlcnRleEJ1ZmZlcktpbmQ6IHN0cmluZyxcclxuICAgICAgICBhdHRyaWJ1dGVDb21wb25lbnRLaW5kOiBBY2Nlc3NvckNvbXBvbmVudFR5cGUsXHJcbiAgICAgICAgbWVzaEF0dHJpYnV0ZUFycmF5OiBGbG9hdEFycmF5LFxyXG4gICAgICAgIHN0cmlkZTogbnVtYmVyLFxyXG4gICAgICAgIGJpbmFyeVdyaXRlcjogX0JpbmFyeVdyaXRlcixcclxuICAgICAgICBiYWJ5bG9uVHJhbnNmb3JtTm9kZTogVHJhbnNmb3JtTm9kZVxyXG4gICAgKSB7XHJcbiAgICAgICAgbGV0IHZlcnRleEF0dHJpYnV0ZXM6IG51bWJlcltdW10gPSBbXTtcclxuICAgICAgICBsZXQgaW5kZXg6IG51bWJlcjtcclxuXHJcbiAgICAgICAgc3dpdGNoICh2ZXJ0ZXhCdWZmZXJLaW5kKSB7XHJcbiAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLlBvc2l0aW9uS2luZDoge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDAsIGxlbmd0aCA9IG1lc2hBdHRyaWJ1dGVBcnJheS5sZW5ndGggLyBzdHJpZGU7IGsgPCBsZW5ndGg7ICsraykge1xyXG4gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gayAqIHN0cmlkZTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZXJ0ZXhEYXRhID0gVmVjdG9yMy5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmVydGV4QXR0cmlidXRlcy5wdXNoKHZlcnRleERhdGEuYXNBcnJheSgpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLk5vcm1hbEtpbmQ6IHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwLCBsZW5ndGggPSBtZXNoQXR0cmlidXRlQXJyYXkubGVuZ3RoIC8gc3RyaWRlOyBrIDwgbGVuZ3RoOyArK2spIHtcclxuICAgICAgICAgICAgICAgICAgICBpbmRleCA9IGsgKiBzdHJpZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVydGV4RGF0YSA9IFZlY3RvcjMuRnJvbUFycmF5KG1lc2hBdHRyaWJ1dGVBcnJheSwgaW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZlcnRleEF0dHJpYnV0ZXMucHVzaCh2ZXJ0ZXhEYXRhLm5vcm1hbGl6ZSgpLmFzQXJyYXkoKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFZlcnRleEJ1ZmZlci5UYW5nZW50S2luZDoge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDAsIGxlbmd0aCA9IG1lc2hBdHRyaWJ1dGVBcnJheS5sZW5ndGggLyBzdHJpZGU7IGsgPCBsZW5ndGg7ICsraykge1xyXG4gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gayAqIHN0cmlkZTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZXJ0ZXhEYXRhID0gVmVjdG9yNC5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCk7XHJcbiAgICAgICAgICAgICAgICAgICAgX0dMVEZVdGlsaXRpZXMuX05vcm1hbGl6ZVRhbmdlbnRGcm9tUmVmKHZlcnRleERhdGEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZlcnRleEF0dHJpYnV0ZXMucHVzaCh2ZXJ0ZXhEYXRhLmFzQXJyYXkoKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFZlcnRleEJ1ZmZlci5Db2xvcktpbmQ6IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG1lc2hNYXRlcmlhbCA9IChiYWJ5bG9uVHJhbnNmb3JtTm9kZSBhcyBNZXNoKS5tYXRlcmlhbDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnZlcnRUb0xpbmVhciA9IG1lc2hNYXRlcmlhbCA/IG1lc2hNYXRlcmlhbC5nZXRDbGFzc05hbWUoKSA9PT0gXCJTdGFuZGFyZE1hdGVyaWFsXCIgOiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdmVydGV4RGF0YTogQ29sb3IzIHwgQ29sb3I0ID0gc3RyaWRlID09PSAzID8gbmV3IENvbG9yMygpIDogbmV3IENvbG9yNCgpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdXNlRXhhY3RTcmdiQ29udmVyc2lvbnMgPSB0aGlzLl9iYWJ5bG9uU2NlbmUuZ2V0RW5naW5lKCkudXNlRXhhY3RTcmdiQ29udmVyc2lvbnM7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMCwgbGVuZ3RoID0gbWVzaEF0dHJpYnV0ZUFycmF5Lmxlbmd0aCAvIHN0cmlkZTsgayA8IGxlbmd0aDsgKytrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBrICogc3RyaWRlO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHJpZGUgPT09IDMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ29sb3IzLkZyb21BcnJheVRvUmVmKG1lc2hBdHRyaWJ1dGVBcnJheSwgaW5kZXgsIHZlcnRleERhdGEgYXMgQ29sb3IzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnZlcnRUb0xpbmVhcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZlcnRleERhdGEgYXMgQ29sb3IzKS50b0xpbmVhclNwYWNlVG9SZWYodmVydGV4RGF0YSBhcyBDb2xvcjMsIHVzZUV4YWN0U3JnYkNvbnZlcnNpb25zKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENvbG9yNC5Gcm9tQXJyYXlUb1JlZihtZXNoQXR0cmlidXRlQXJyYXksIGluZGV4LCB2ZXJ0ZXhEYXRhIGFzIENvbG9yNCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb252ZXJ0VG9MaW5lYXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2ZXJ0ZXhEYXRhIGFzIENvbG9yNCkudG9MaW5lYXJTcGFjZVRvUmVmKHZlcnRleERhdGEgYXMgQ29sb3I0LCB1c2VFeGFjdFNyZ2JDb252ZXJzaW9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdmVydGV4QXR0cmlidXRlcy5wdXNoKHZlcnRleERhdGEuYXNBcnJheSgpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLlVWS2luZDpcclxuICAgICAgICAgICAgY2FzZSBWZXJ0ZXhCdWZmZXIuVVYyS2luZDoge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDAsIGxlbmd0aCA9IG1lc2hBdHRyaWJ1dGVBcnJheS5sZW5ndGggLyBzdHJpZGU7IGsgPCBsZW5ndGg7ICsraykge1xyXG4gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gayAqIHN0cmlkZTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZXJ0ZXhEYXRhID0gVmVjdG9yMi5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmVydGV4QXR0cmlidXRlcy5wdXNoKHZlcnRleERhdGEuYXNBcnJheSgpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLk1hdHJpY2VzSW5kaWNlc0tpbmQ6XHJcbiAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLk1hdHJpY2VzSW5kaWNlc0V4dHJhS2luZDoge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDAsIGxlbmd0aCA9IG1lc2hBdHRyaWJ1dGVBcnJheS5sZW5ndGggLyBzdHJpZGU7IGsgPCBsZW5ndGg7ICsraykge1xyXG4gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gayAqIHN0cmlkZTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZXJ0ZXhEYXRhID0gVmVjdG9yNC5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmVydGV4QXR0cmlidXRlcy5wdXNoKHZlcnRleERhdGEuYXNBcnJheSgpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLk1hdHJpY2VzV2VpZ2h0c0tpbmQ6XHJcbiAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLk1hdHJpY2VzV2VpZ2h0c0V4dHJhS2luZDoge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDAsIGxlbmd0aCA9IG1lc2hBdHRyaWJ1dGVBcnJheS5sZW5ndGggLyBzdHJpZGU7IGsgPCBsZW5ndGg7ICsraykge1xyXG4gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gayAqIHN0cmlkZTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZXJ0ZXhEYXRhID0gVmVjdG9yNC5Gcm9tQXJyYXkobWVzaEF0dHJpYnV0ZUFycmF5LCBpbmRleCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmVydGV4QXR0cmlidXRlcy5wdXNoKHZlcnRleERhdGEuYXNBcnJheSgpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcclxuICAgICAgICAgICAgICAgIFRvb2xzLldhcm4oXCJVbnN1cHBvcnRlZCBWZXJ0ZXggQnVmZmVyIFR5cGU6IFwiICsgdmVydGV4QnVmZmVyS2luZCk7XHJcbiAgICAgICAgICAgICAgICB2ZXJ0ZXhBdHRyaWJ1dGVzID0gW107XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHdyaXRlQmluYXJ5RnVuYyA9IGdldEJpbmFyeVdyaXRlckZ1bmMoYmluYXJ5V3JpdGVyLCBhdHRyaWJ1dGVDb21wb25lbnRLaW5kKTtcclxuXHJcbiAgICAgICAgaWYgKHdyaXRlQmluYXJ5RnVuYykge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHZlcnRleEF0dHJpYnV0ZSBvZiB2ZXJ0ZXhBdHRyaWJ1dGVzKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNvbXBvbmVudCBvZiB2ZXJ0ZXhBdHRyaWJ1dGUpIHtcclxuICAgICAgICAgICAgICAgICAgICB3cml0ZUJpbmFyeUZ1bmMoY29tcG9uZW50KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9jcmVhdGVNb3JwaFRhcmdldEJ1ZmZlclZpZXdLaW5kKFxyXG4gICAgICAgIHZlcnRleEJ1ZmZlcktpbmQ6IHN0cmluZyxcclxuICAgICAgICBhY2Nlc3NvclR5cGU6IEFjY2Vzc29yVHlwZSxcclxuICAgICAgICBhdHRyaWJ1dGVDb21wb25lbnRLaW5kOiBBY2Nlc3NvckNvbXBvbmVudFR5cGUsXHJcbiAgICAgICAgbWVzaDogTWVzaCxcclxuICAgICAgICBtb3JwaFRhcmdldDogTW9ycGhUYXJnZXQsXHJcbiAgICAgICAgYmluYXJ5V3JpdGVyOiBfQmluYXJ5V3JpdGVyLFxyXG4gICAgICAgIGJ5dGVTdHJpZGU6IG51bWJlclxyXG4gICAgKTogTnVsbGFibGU8eyBidWZmZXJWaWV3SW5kZXg6IG51bWJlcjsgdmVydGV4Q291bnQ6IG51bWJlcjsgYWNjZXNzb3JUeXBlOiBBY2Nlc3NvclR5cGU7IG1pbk1heD86IHsgbWluOiBWZWN0b3IzOyBtYXg6IFZlY3RvcjMgfSB9PiB7XHJcbiAgICAgICAgbGV0IHZlcnRleENvdW50OiBudW1iZXI7XHJcbiAgICAgICAgbGV0IG1pbk1heDogeyBtaW46IFZlY3RvcjM7IG1heDogVmVjdG9yMyB9IHwgdW5kZWZpbmVkO1xyXG4gICAgICAgIGNvbnN0IG1vcnBoRGF0YTogbnVtYmVyW10gPSBbXTtcclxuICAgICAgICBjb25zdCBkaWZmZXJlbmNlOiBWZWN0b3IzID0gVG1wVmVjdG9ycy5WZWN0b3IzWzBdO1xyXG5cclxuICAgICAgICBzd2l0Y2ggKHZlcnRleEJ1ZmZlcktpbmQpIHtcclxuICAgICAgICAgICAgY2FzZSBWZXJ0ZXhCdWZmZXIuUG9zaXRpb25LaW5kOiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtb3JwaFBvc2l0aW9ucyA9IG1vcnBoVGFyZ2V0LmdldFBvc2l0aW9ucygpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFtb3JwaFBvc2l0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsUG9zaXRpb25zID0gbWVzaC5nZXRWZXJ0aWNlc0RhdGEoVmVydGV4QnVmZmVyLlBvc2l0aW9uS2luZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHRydWUpITtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHZlcnRleFN0YXJ0ID0gMDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG1pbiA9IG5ldyBWZWN0b3IzKEluZmluaXR5LCBJbmZpbml0eSwgSW5maW5pdHkpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbWF4ID0gbmV3IFZlY3RvcjMoLUluZmluaXR5LCAtSW5maW5pdHksIC1JbmZpbml0eSk7XHJcbiAgICAgICAgICAgICAgICB2ZXJ0ZXhDb3VudCA9IG9yaWdpbmFsUG9zaXRpb25zLmxlbmd0aCAvIDM7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gdmVydGV4U3RhcnQ7IGkgPCB2ZXJ0ZXhDb3VudDsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxQb3NpdGlvbiA9IFZlY3RvcjMuRnJvbUFycmF5KG9yaWdpbmFsUG9zaXRpb25zLCBpICogMyk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbW9ycGhQb3NpdGlvbiA9IFZlY3RvcjMuRnJvbUFycmF5KG1vcnBoUG9zaXRpb25zLCBpICogMyk7XHJcbiAgICAgICAgICAgICAgICAgICAgbW9ycGhQb3NpdGlvbi5zdWJ0cmFjdFRvUmVmKG9yaWdpbmFsUG9zaXRpb24sIGRpZmZlcmVuY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIG1pbi5jb3B5RnJvbUZsb2F0cyhNYXRoLm1pbihkaWZmZXJlbmNlLngsIG1pbi54KSwgTWF0aC5taW4oZGlmZmVyZW5jZS55LCBtaW4ueSksIE1hdGgubWluKGRpZmZlcmVuY2UueiwgbWluLnopKTtcclxuICAgICAgICAgICAgICAgICAgICBtYXguY29weUZyb21GbG9hdHMoTWF0aC5tYXgoZGlmZmVyZW5jZS54LCBtYXgueCksIE1hdGgubWF4KGRpZmZlcmVuY2UueSwgbWF4LnkpLCBNYXRoLm1heChkaWZmZXJlbmNlLnosIG1heC56KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgbW9ycGhEYXRhLnB1c2goZGlmZmVyZW5jZS54LCBkaWZmZXJlbmNlLnksIGRpZmZlcmVuY2Uueik7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbWluTWF4ID0geyBtaW4sIG1heCB9O1xyXG5cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLk5vcm1hbEtpbmQ6IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG1vcnBoTm9ybWFscyA9IG1vcnBoVGFyZ2V0LmdldE5vcm1hbHMoKTtcclxuICAgICAgICAgICAgICAgIGlmICghbW9ycGhOb3JtYWxzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxOb3JtYWxzID0gbWVzaC5nZXRWZXJ0aWNlc0RhdGEoVmVydGV4QnVmZmVyLk5vcm1hbEtpbmQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0cnVlKSE7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB2ZXJ0ZXhTdGFydCA9IDA7XHJcbiAgICAgICAgICAgICAgICB2ZXJ0ZXhDb3VudCA9IG9yaWdpbmFsTm9ybWFscy5sZW5ndGggLyAzO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHZlcnRleFN0YXJ0OyBpIDwgdmVydGV4Q291bnQ7ICsraSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsTm9ybWFsID0gVmVjdG9yMy5Gcm9tQXJyYXkob3JpZ2luYWxOb3JtYWxzLCBpICogMykubm9ybWFsaXplKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbW9ycGhOb3JtYWwgPSBWZWN0b3IzLkZyb21BcnJheShtb3JwaE5vcm1hbHMsIGkgKiAzKS5ub3JtYWxpemUoKTtcclxuICAgICAgICAgICAgICAgICAgICBtb3JwaE5vcm1hbC5zdWJ0cmFjdFRvUmVmKG9yaWdpbmFsTm9ybWFsLCBkaWZmZXJlbmNlKTtcclxuICAgICAgICAgICAgICAgICAgICBtb3JwaERhdGEucHVzaChkaWZmZXJlbmNlLngsIGRpZmZlcmVuY2UueSwgZGlmZmVyZW5jZS56KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFZlcnRleEJ1ZmZlci5UYW5nZW50S2luZDoge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbW9ycGhUYW5nZW50cyA9IG1vcnBoVGFyZ2V0LmdldFRhbmdlbnRzKCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIW1vcnBoVGFuZ2VudHMpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBIYW5kZWRuZXNzIGNhbm5vdCBiZSBkaXNwbGFjZWQsIHNvIG1vcnBoIHRhcmdldCB0YW5nZW50cyBvbWl0IHRoZSB3IGNvbXBvbmVudFxyXG4gICAgICAgICAgICAgICAgYWNjZXNzb3JUeXBlID0gQWNjZXNzb3JUeXBlLlZFQzM7XHJcbiAgICAgICAgICAgICAgICBieXRlU3RyaWRlID0gMTI7IC8vIDMgY29tcG9uZW50cyAoeC95L3opICogNCBieXRlcyAoZmxvYXQzMilcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBvcmlnaW5hbFRhbmdlbnRzID0gbWVzaC5nZXRWZXJ0aWNlc0RhdGEoVmVydGV4QnVmZmVyLlRhbmdlbnRLaW5kLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdHJ1ZSkhO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdmVydGV4U3RhcnQgPSAwO1xyXG4gICAgICAgICAgICAgICAgdmVydGV4Q291bnQgPSBvcmlnaW5hbFRhbmdlbnRzLmxlbmd0aCAvIDQ7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gdmVydGV4U3RhcnQ7IGkgPCB2ZXJ0ZXhDb3VudDsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gT25seSByZWFkIHRoZSB4LCB5LCB6IGNvbXBvbmVudHMgYW5kIGlnbm9yZSB3XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxUYW5nZW50ID0gVmVjdG9yMy5Gcm9tQXJyYXkob3JpZ2luYWxUYW5nZW50cywgaSAqIDQpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9HTFRGVXRpbGl0aWVzLl9Ob3JtYWxpemVUYW5nZW50RnJvbVJlZihvcmlnaW5hbFRhbmdlbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBNb3JwaCB0YXJnZXQgdGFuZ2VudHMgb21pdCB0aGUgdyBjb21wb25lbnQgc28gaXQgd29uJ3QgYmUgcHJlc2VudCBpbiB0aGUgZGF0YVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1vcnBoVGFuZ2VudCA9IFZlY3RvcjMuRnJvbUFycmF5KG1vcnBoVGFuZ2VudHMsIGkgKiAzKTtcclxuICAgICAgICAgICAgICAgICAgICBfR0xURlV0aWxpdGllcy5fTm9ybWFsaXplVGFuZ2VudEZyb21SZWYobW9ycGhUYW5nZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbW9ycGhUYW5nZW50LnN1YnRyYWN0VG9SZWYob3JpZ2luYWxUYW5nZW50LCBkaWZmZXJlbmNlKTtcclxuICAgICAgICAgICAgICAgICAgICBtb3JwaERhdGEucHVzaChkaWZmZXJlbmNlLngsIGRpZmZlcmVuY2UueSwgZGlmZmVyZW5jZS56KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBkZWZhdWx0OiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgYmluYXJ5V3JpdGVyRnVuYyA9IGdldEJpbmFyeVdyaXRlckZ1bmMoYmluYXJ5V3JpdGVyLCBhdHRyaWJ1dGVDb21wb25lbnRLaW5kKTtcclxuICAgICAgICBpZiAoIWJpbmFyeVdyaXRlckZ1bmMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB0eXBlQnl0ZUxlbmd0aCA9IFZlcnRleEJ1ZmZlci5HZXRUeXBlQnl0ZUxlbmd0aChhdHRyaWJ1dGVDb21wb25lbnRLaW5kKTtcclxuICAgICAgICBjb25zdCBieXRlTGVuZ3RoID0gbW9ycGhEYXRhLmxlbmd0aCAqIHR5cGVCeXRlTGVuZ3RoO1xyXG4gICAgICAgIGNvbnN0IGJ1ZmZlclZpZXcgPSBfR0xURlV0aWxpdGllcy5fQ3JlYXRlQnVmZmVyVmlldygwLCBiaW5hcnlXcml0ZXIuZ2V0Qnl0ZU9mZnNldCgpLCBieXRlTGVuZ3RoLCBieXRlU3RyaWRlLCBgJHt2ZXJ0ZXhCdWZmZXJLaW5kfSAtICR7bW9ycGhUYXJnZXQubmFtZX0gKE1vcnBoIFRhcmdldClgKTtcclxuICAgICAgICB0aGlzLl9idWZmZXJWaWV3cy5wdXNoKGJ1ZmZlclZpZXcpO1xyXG4gICAgICAgIGNvbnN0IGJ1ZmZlclZpZXdJbmRleCA9IHRoaXMuX2J1ZmZlclZpZXdzLmxlbmd0aCAtIDE7XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgbW9ycGhEYXRhKSB7XHJcbiAgICAgICAgICAgIGJpbmFyeVdyaXRlckZ1bmModmFsdWUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHsgYnVmZmVyVmlld0luZGV4LCB2ZXJ0ZXhDb3VudCwgYWNjZXNzb3JUeXBlLCBtaW5NYXggfTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdlbmVyYXRlcyBnbFRGIGpzb24gZGF0YVxyXG4gICAgICogQHBhcmFtIHNob3VsZFVzZUdsYiBJbmRpY2F0ZXMgd2hldGhlciB0aGUganNvbiBzaG91bGQgYmUgd3JpdHRlbiBmb3IgYSBnbGIgZmlsZVxyXG4gICAgICogQHBhcmFtIGdsVEZQcmVmaXggVGV4dCB0byB1c2Ugd2hlbiBwcmVmaXhpbmcgYSBnbFRGIGZpbGVcclxuICAgICAqIEBwYXJhbSBwcmV0dHlQcmludCBJbmRpY2F0ZXMgd2hldGhlciB0aGUganNvbiBmaWxlIHNob3VsZCBiZSBwcmV0dHkgcHJpbnRlZCAodHJ1ZSkgb3Igbm90IChmYWxzZSlcclxuICAgICAqIEByZXR1cm5zIGpzb24gZGF0YSBhcyBzdHJpbmdcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfZ2VuZXJhdGVKU09OKHNob3VsZFVzZUdsYjogYm9vbGVhbiwgZ2xURlByZWZpeD86IHN0cmluZywgcHJldHR5UHJpbnQ/OiBib29sZWFuKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zdCBidWZmZXI6IElCdWZmZXIgPSB7IGJ5dGVMZW5ndGg6IHRoaXMuX3RvdGFsQnl0ZUxlbmd0aCB9O1xyXG4gICAgICAgIGxldCBpbWFnZU5hbWU6IHN0cmluZztcclxuICAgICAgICBsZXQgaW1hZ2VEYXRhOiB7IGRhdGE6IEFycmF5QnVmZmVyOyBtaW1lVHlwZTogSW1hZ2VNaW1lVHlwZSB9O1xyXG4gICAgICAgIGxldCBidWZmZXJWaWV3OiBJQnVmZmVyVmlldztcclxuICAgICAgICBsZXQgYnl0ZU9mZnNldDogbnVtYmVyID0gdGhpcy5fdG90YWxCeXRlTGVuZ3RoO1xyXG5cclxuICAgICAgICBpZiAoYnVmZmVyLmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhpcy5fZ2xURi5idWZmZXJzID0gW2J1ZmZlcl07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl9ub2RlcyAmJiB0aGlzLl9ub2Rlcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhpcy5fZ2xURi5ub2RlcyA9IHRoaXMuX25vZGVzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5fbWVzaGVzICYmIHRoaXMuX21lc2hlcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhpcy5fZ2xURi5tZXNoZXMgPSB0aGlzLl9tZXNoZXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl9zY2VuZXMgJiYgdGhpcy5fc2NlbmVzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aGlzLl9nbFRGLnNjZW5lcyA9IHRoaXMuX3NjZW5lcztcclxuICAgICAgICAgICAgdGhpcy5fZ2xURi5zY2VuZSA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl9jYW1lcmFzICYmIHRoaXMuX2NhbWVyYXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2dsVEYuY2FtZXJhcyA9IHRoaXMuX2NhbWVyYXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl9idWZmZXJWaWV3cyAmJiB0aGlzLl9idWZmZXJWaWV3cy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhpcy5fZ2xURi5idWZmZXJWaWV3cyA9IHRoaXMuX2J1ZmZlclZpZXdzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5fYWNjZXNzb3JzICYmIHRoaXMuX2FjY2Vzc29ycy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhpcy5fZ2xURi5hY2Nlc3NvcnMgPSB0aGlzLl9hY2Nlc3NvcnM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl9hbmltYXRpb25zICYmIHRoaXMuX2FuaW1hdGlvbnMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2dsVEYuYW5pbWF0aW9ucyA9IHRoaXMuX2FuaW1hdGlvbnM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl9tYXRlcmlhbHMgJiYgdGhpcy5fbWF0ZXJpYWxzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aGlzLl9nbFRGLm1hdGVyaWFscyA9IHRoaXMuX21hdGVyaWFscztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuX3RleHR1cmVzICYmIHRoaXMuX3RleHR1cmVzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aGlzLl9nbFRGLnRleHR1cmVzID0gdGhpcy5fdGV4dHVyZXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl9zYW1wbGVycyAmJiB0aGlzLl9zYW1wbGVycy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhpcy5fZ2xURi5zYW1wbGVycyA9IHRoaXMuX3NhbXBsZXJzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5fc2tpbnMgJiYgdGhpcy5fc2tpbnMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2dsVEYuc2tpbnMgPSB0aGlzLl9za2lucztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuX2ltYWdlcyAmJiB0aGlzLl9pbWFnZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIGlmICghc2hvdWxkVXNlR2xiKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9nbFRGLmltYWdlcyA9IHRoaXMuX2ltYWdlcztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2dsVEYuaW1hZ2VzID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5faW1hZ2VzLmZvckVhY2goKGltYWdlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGltYWdlLnVyaSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbWFnZURhdGEgPSB0aGlzLl9pbWFnZURhdGFbaW1hZ2UudXJpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fb3JkZXJlZEltYWdlRGF0YS5wdXNoKGltYWdlRGF0YSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlTmFtZSA9IGltYWdlLnVyaS5zcGxpdChcIi5cIilbMF0gKyBcIiBpbWFnZVwiO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBidWZmZXJWaWV3ID0gX0dMVEZVdGlsaXRpZXMuX0NyZWF0ZUJ1ZmZlclZpZXcoMCwgYnl0ZU9mZnNldCwgaW1hZ2VEYXRhLmRhdGEuYnl0ZUxlbmd0aCwgdW5kZWZpbmVkLCBpbWFnZU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBieXRlT2Zmc2V0ICs9IGltYWdlRGF0YS5kYXRhLmJ5dGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlclZpZXdzLnB1c2goYnVmZmVyVmlldyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlLmJ1ZmZlclZpZXcgPSB0aGlzLl9idWZmZXJWaWV3cy5sZW5ndGggLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbWFnZS5uYW1lID0gaW1hZ2VOYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbWFnZS5taW1lVHlwZSA9IGltYWdlRGF0YS5taW1lVHlwZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2UudXJpID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2dsVEYuaW1hZ2VzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9nbFRGLmltYWdlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2dsVEYuaW1hZ2VzLnB1c2goaW1hZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgLy8gUmVwbGFjZSB1cmkgd2l0aCBidWZmZXJ2aWV3IGFuZCBtaW1lIHR5cGUgZm9yIGdsYlxyXG4gICAgICAgICAgICAgICAgYnVmZmVyLmJ5dGVMZW5ndGggPSBieXRlT2Zmc2V0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXNob3VsZFVzZUdsYikge1xyXG4gICAgICAgICAgICBidWZmZXIudXJpID0gZ2xURlByZWZpeCArIFwiLmJpblwiO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QganNvblRleHQgPSBwcmV0dHlQcmludCA/IEpTT04uc3RyaW5naWZ5KHRoaXMuX2dsVEYsIG51bGwsIDIpIDogSlNPTi5zdHJpbmdpZnkodGhpcy5fZ2xURik7XHJcblxyXG4gICAgICAgIHJldHVybiBqc29uVGV4dDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdlbmVyYXRlcyBkYXRhIGZvciAuZ2x0ZiBhbmQgLmJpbiBmaWxlcyBiYXNlZCBvbiB0aGUgZ2xURiBwcmVmaXggc3RyaW5nXHJcbiAgICAgKiBAcGFyYW0gZ2xURlByZWZpeCBUZXh0IHRvIHVzZSB3aGVuIHByZWZpeGluZyBhIGdsVEYgZmlsZVxyXG4gICAgICogQHBhcmFtIGRpc3Bvc2UgRGlzcG9zZSB0aGUgZXhwb3J0ZXJcclxuICAgICAqIEByZXR1cm5zIEdMVEZEYXRhIHdpdGggZ2xURiBmaWxlIGRhdGFcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9nZW5lcmF0ZUdMVEZBc3luYyhnbFRGUHJlZml4OiBzdHJpbmcsIGRpc3Bvc2UgPSB0cnVlKTogUHJvbWlzZTxHTFRGRGF0YT4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZW5lcmF0ZUJpbmFyeUFzeW5jKCkudGhlbigoYmluYXJ5QnVmZmVyKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2V4dGVuc2lvbnNPbkV4cG9ydGluZygpO1xyXG4gICAgICAgICAgICBjb25zdCBqc29uVGV4dCA9IHRoaXMuX2dlbmVyYXRlSlNPTihmYWxzZSwgZ2xURlByZWZpeCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGNvbnN0IGJpbiA9IG5ldyBCbG9iKFtiaW5hcnlCdWZmZXJdLCB7IHR5cGU6IFwiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtXCIgfSk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBnbFRGRmlsZU5hbWUgPSBnbFRGUHJlZml4ICsgXCIuZ2x0ZlwiO1xyXG4gICAgICAgICAgICBjb25zdCBnbFRGQmluRmlsZSA9IGdsVEZQcmVmaXggKyBcIi5iaW5cIjtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IG5ldyBHTFRGRGF0YSgpO1xyXG5cclxuICAgICAgICAgICAgY29udGFpbmVyLmdsVEZGaWxlc1tnbFRGRmlsZU5hbWVdID0ganNvblRleHQ7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5nbFRGRmlsZXNbZ2xURkJpbkZpbGVdID0gYmluO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuX2ltYWdlRGF0YSkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBpbWFnZSBpbiB0aGlzLl9pbWFnZURhdGEpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb250YWluZXIuZ2xURkZpbGVzW2ltYWdlXSA9IG5ldyBCbG9iKFt0aGlzLl9pbWFnZURhdGFbaW1hZ2VdLmRhdGFdLCB7IHR5cGU6IHRoaXMuX2ltYWdlRGF0YVtpbWFnZV0ubWltZVR5cGUgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChkaXNwb3NlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGNvbnRhaW5lcjtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBiaW5hcnkgYnVmZmVyIGZvciBnbFRGXHJcbiAgICAgKiBAcmV0dXJucyBhcnJheSBidWZmZXIgZm9yIGJpbmFyeSBkYXRhXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX2dlbmVyYXRlQmluYXJ5QXN5bmMoKTogUHJvbWlzZTxBcnJheUJ1ZmZlcj4ge1xyXG4gICAgICAgIGNvbnN0IGJpbmFyeVdyaXRlciA9IG5ldyBfQmluYXJ5V3JpdGVyKDQpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9jcmVhdGVTY2VuZUFzeW5jKGJpbmFyeVdyaXRlcikudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9sb2NhbEVuZ2luZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9jYWxFbmdpbmUuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBiaW5hcnlXcml0ZXIuZ2V0QXJyYXlCdWZmZXIoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBhZHMgdGhlIG51bWJlciB0byBhIG11bHRpcGxlIG9mIDRcclxuICAgICAqIEBwYXJhbSBudW0gbnVtYmVyIHRvIHBhZFxyXG4gICAgICogQHJldHVybnMgcGFkZGVkIG51bWJlclxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9nZXRQYWRkaW5nKG51bTogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgICAgICBjb25zdCByZW1haW5kZXIgPSBudW0gJSA0O1xyXG4gICAgICAgIGNvbnN0IHBhZGRpbmcgPSByZW1haW5kZXIgPT09IDAgPyByZW1haW5kZXIgOiA0IC0gcmVtYWluZGVyO1xyXG5cclxuICAgICAgICByZXR1cm4gcGFkZGluZztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2dlbmVyYXRlR0xCQXN5bmMoZ2xURlByZWZpeDogc3RyaW5nLCBkaXNwb3NlID0gdHJ1ZSk6IFByb21pc2U8R0xURkRhdGE+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2VuZXJhdGVCaW5hcnlBc3luYygpLnRoZW4oKGJpbmFyeUJ1ZmZlcikgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9leHRlbnNpb25zT25FeHBvcnRpbmcoKTtcclxuICAgICAgICAgICAgY29uc3QganNvblRleHQgPSB0aGlzLl9nZW5lcmF0ZUpTT04odHJ1ZSk7XHJcbiAgICAgICAgICAgIGNvbnN0IGdsYkZpbGVOYW1lID0gZ2xURlByZWZpeCArIFwiLmdsYlwiO1xyXG4gICAgICAgICAgICBjb25zdCBoZWFkZXJMZW5ndGggPSAxMjtcclxuICAgICAgICAgICAgY29uc3QgY2h1bmtMZW5ndGhQcmVmaXggPSA4O1xyXG4gICAgICAgICAgICBsZXQganNvbkxlbmd0aCA9IGpzb25UZXh0Lmxlbmd0aDtcclxuICAgICAgICAgICAgbGV0IGVuY29kZWRKc29uVGV4dDtcclxuICAgICAgICAgICAgbGV0IGltYWdlQnl0ZUxlbmd0aCA9IDA7XHJcbiAgICAgICAgICAgIC8vIG1ha2UgdXNlIG9mIFRleHRFbmNvZGVyIHdoZW4gYXZhaWxhYmxlXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgVGV4dEVuY29kZXIgIT09IFwidW5kZWZpbmVkXCIpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcclxuICAgICAgICAgICAgICAgIGVuY29kZWRKc29uVGV4dCA9IGVuY29kZXIuZW5jb2RlKGpzb25UZXh0KTtcclxuICAgICAgICAgICAgICAgIGpzb25MZW5ndGggPSBlbmNvZGVkSnNvblRleHQubGVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fb3JkZXJlZEltYWdlRGF0YS5sZW5ndGg7ICsraSkge1xyXG4gICAgICAgICAgICAgICAgaW1hZ2VCeXRlTGVuZ3RoICs9IHRoaXMuX29yZGVyZWRJbWFnZURhdGFbaV0uZGF0YS5ieXRlTGVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGpzb25QYWRkaW5nID0gdGhpcy5fZ2V0UGFkZGluZyhqc29uTGVuZ3RoKTtcclxuICAgICAgICAgICAgY29uc3QgYmluUGFkZGluZyA9IHRoaXMuX2dldFBhZGRpbmcoYmluYXJ5QnVmZmVyLmJ5dGVMZW5ndGgpO1xyXG4gICAgICAgICAgICBjb25zdCBpbWFnZVBhZGRpbmcgPSB0aGlzLl9nZXRQYWRkaW5nKGltYWdlQnl0ZUxlbmd0aCk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBieXRlTGVuZ3RoID0gaGVhZGVyTGVuZ3RoICsgMiAqIGNodW5rTGVuZ3RoUHJlZml4ICsganNvbkxlbmd0aCArIGpzb25QYWRkaW5nICsgYmluYXJ5QnVmZmVyLmJ5dGVMZW5ndGggKyBiaW5QYWRkaW5nICsgaW1hZ2VCeXRlTGVuZ3RoICsgaW1hZ2VQYWRkaW5nO1xyXG5cclxuICAgICAgICAgICAgLy9oZWFkZXJcclxuICAgICAgICAgICAgY29uc3QgaGVhZGVyQnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKGhlYWRlckxlbmd0aCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGhlYWRlckJ1ZmZlclZpZXcgPSBuZXcgRGF0YVZpZXcoaGVhZGVyQnVmZmVyKTtcclxuICAgICAgICAgICAgaGVhZGVyQnVmZmVyVmlldy5zZXRVaW50MzIoMCwgMHg0NjU0NmM2NywgdHJ1ZSk7IC8vZ2xURlxyXG4gICAgICAgICAgICBoZWFkZXJCdWZmZXJWaWV3LnNldFVpbnQzMig0LCAyLCB0cnVlKTsgLy8gdmVyc2lvblxyXG4gICAgICAgICAgICBoZWFkZXJCdWZmZXJWaWV3LnNldFVpbnQzMig4LCBieXRlTGVuZ3RoLCB0cnVlKTsgLy8gdG90YWwgYnl0ZXMgaW4gZmlsZVxyXG5cclxuICAgICAgICAgICAgLy9qc29uIGNodW5rXHJcbiAgICAgICAgICAgIGNvbnN0IGpzb25DaHVua0J1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihjaHVua0xlbmd0aFByZWZpeCArIGpzb25MZW5ndGggKyBqc29uUGFkZGluZyk7XHJcbiAgICAgICAgICAgIGNvbnN0IGpzb25DaHVua0J1ZmZlclZpZXcgPSBuZXcgRGF0YVZpZXcoanNvbkNodW5rQnVmZmVyKTtcclxuICAgICAgICAgICAganNvbkNodW5rQnVmZmVyVmlldy5zZXRVaW50MzIoMCwganNvbkxlbmd0aCArIGpzb25QYWRkaW5nLCB0cnVlKTtcclxuICAgICAgICAgICAganNvbkNodW5rQnVmZmVyVmlldy5zZXRVaW50MzIoNCwgMHg0ZTRmNTM0YSwgdHJ1ZSk7XHJcblxyXG4gICAgICAgICAgICAvL2pzb24gY2h1bmsgYnl0ZXNcclxuICAgICAgICAgICAgY29uc3QganNvbkRhdGEgPSBuZXcgVWludDhBcnJheShqc29uQ2h1bmtCdWZmZXIsIGNodW5rTGVuZ3RoUHJlZml4KTtcclxuICAgICAgICAgICAgLy8gaWYgVGV4dEVuY29kZXIgd2FzIGF2YWlsYWJsZSwgd2UgY2FuIHNpbXBseSBjb3B5IHRoZSBlbmNvZGVkIGFycmF5XHJcbiAgICAgICAgICAgIGlmIChlbmNvZGVkSnNvblRleHQpIHtcclxuICAgICAgICAgICAgICAgIGpzb25EYXRhLnNldChlbmNvZGVkSnNvblRleHQpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYmxhbmtDaGFyQ29kZSA9IFwiX1wiLmNoYXJDb2RlQXQoMCk7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGpzb25MZW5ndGg7ICsraSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXJDb2RlID0ganNvblRleHQuY2hhckNvZGVBdChpKTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGUgY2hhcmFjdGVyIGRvZXNuJ3QgZml0IGludG8gYSBzaW5nbGUgVVRGLTE2IGNvZGUgdW5pdCwganVzdCBwdXQgYSBibGFuayBjaGFyYWN0ZXJcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgIT0ganNvblRleHQuY29kZVBvaW50QXQoaSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAganNvbkRhdGFbaV0gPSBibGFua0NoYXJDb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25EYXRhW2ldID0gY2hhckNvZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvL2pzb24gcGFkZGluZ1xyXG4gICAgICAgICAgICBjb25zdCBqc29uUGFkZGluZ1ZpZXcgPSBuZXcgVWludDhBcnJheShqc29uQ2h1bmtCdWZmZXIsIGNodW5rTGVuZ3RoUHJlZml4ICsganNvbkxlbmd0aCk7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwganNvblBhZGRpbmc7ICsraSkge1xyXG4gICAgICAgICAgICAgICAganNvblBhZGRpbmdWaWV3W2ldID0gMHgyMDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy9iaW5hcnkgY2h1bmtcclxuICAgICAgICAgICAgY29uc3QgYmluYXJ5Q2h1bmtCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoY2h1bmtMZW5ndGhQcmVmaXgpO1xyXG4gICAgICAgICAgICBjb25zdCBiaW5hcnlDaHVua0J1ZmZlclZpZXcgPSBuZXcgRGF0YVZpZXcoYmluYXJ5Q2h1bmtCdWZmZXIpO1xyXG4gICAgICAgICAgICBiaW5hcnlDaHVua0J1ZmZlclZpZXcuc2V0VWludDMyKDAsIGJpbmFyeUJ1ZmZlci5ieXRlTGVuZ3RoICsgaW1hZ2VCeXRlTGVuZ3RoICsgaW1hZ2VQYWRkaW5nLCB0cnVlKTtcclxuICAgICAgICAgICAgYmluYXJ5Q2h1bmtCdWZmZXJWaWV3LnNldFVpbnQzMig0LCAweDAwNGU0OTQyLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgIC8vIGJpbmFyeSBwYWRkaW5nXHJcbiAgICAgICAgICAgIGNvbnN0IGJpblBhZGRpbmdCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoYmluUGFkZGluZyk7XHJcbiAgICAgICAgICAgIGNvbnN0IGJpblBhZGRpbmdWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoYmluUGFkZGluZ0J1ZmZlcik7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYmluUGFkZGluZzsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICBiaW5QYWRkaW5nVmlld1tpXSA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGltYWdlUGFkZGluZ0J1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihpbWFnZVBhZGRpbmcpO1xyXG4gICAgICAgICAgICBjb25zdCBpbWFnZVBhZGRpbmdWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoaW1hZ2VQYWRkaW5nQnVmZmVyKTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbWFnZVBhZGRpbmc7ICsraSkge1xyXG4gICAgICAgICAgICAgICAgaW1hZ2VQYWRkaW5nVmlld1tpXSA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGdsYkRhdGEgPSBbaGVhZGVyQnVmZmVyLCBqc29uQ2h1bmtCdWZmZXIsIGJpbmFyeUNodW5rQnVmZmVyLCBiaW5hcnlCdWZmZXJdO1xyXG5cclxuICAgICAgICAgICAgLy8gYmluYXJ5IGRhdGFcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9vcmRlcmVkSW1hZ2VEYXRhLmxlbmd0aDsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICBnbGJEYXRhLnB1c2godGhpcy5fb3JkZXJlZEltYWdlRGF0YVtpXS5kYXRhKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZ2xiRGF0YS5wdXNoKGJpblBhZGRpbmdCdWZmZXIpO1xyXG5cclxuICAgICAgICAgICAgZ2xiRGF0YS5wdXNoKGltYWdlUGFkZGluZ0J1ZmZlcik7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBnbGJGaWxlID0gbmV3IEJsb2IoZ2xiRGF0YSwgeyB0eXBlOiBcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiIH0pO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgY29udGFpbmVyID0gbmV3IEdMVEZEYXRhKCk7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5nbFRGRmlsZXNbZ2xiRmlsZU5hbWVdID0gZ2xiRmlsZTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9sb2NhbEVuZ2luZSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2NhbEVuZ2luZS5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChkaXNwb3NlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGNvbnRhaW5lcjtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIFRSUyBmb3IgZWFjaCBub2RlXHJcbiAgICAgKiBAcGFyYW0gbm9kZSBnbFRGIE5vZGUgZm9yIHN0b3JpbmcgdGhlIHRyYW5zZm9ybWF0aW9uIGRhdGFcclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uVHJhbnNmb3JtTm9kZSBCYWJ5bG9uIG1lc2ggdXNlZCBhcyB0aGUgc291cmNlIGZvciB0aGUgdHJhbnNmb3JtYXRpb24gZGF0YVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9zZXROb2RlVHJhbnNmb3JtYXRpb24obm9kZTogSU5vZGUsIGJhYnlsb25UcmFuc2Zvcm1Ob2RlOiBUcmFuc2Zvcm1Ob2RlKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCFiYWJ5bG9uVHJhbnNmb3JtTm9kZS5nZXRQaXZvdFBvaW50KCkuZXF1YWxzVG9GbG9hdHMoMCwgMCwgMCkpIHtcclxuICAgICAgICAgICAgVG9vbHMuV2FybihcIlBpdm90IHBvaW50cyBhcmUgbm90IHN1cHBvcnRlZCBpbiB0aGUgZ2xURiBzZXJpYWxpemVyXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWJhYnlsb25UcmFuc2Zvcm1Ob2RlLnBvc2l0aW9uLmVxdWFsc1RvRmxvYXRzKDAsIDAsIDApKSB7XHJcbiAgICAgICAgICAgIG5vZGUudHJhbnNsYXRpb24gPSBiYWJ5bG9uVHJhbnNmb3JtTm9kZS5wb3NpdGlvbi5hc0FycmF5KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIWJhYnlsb25UcmFuc2Zvcm1Ob2RlLnNjYWxpbmcuZXF1YWxzVG9GbG9hdHMoMSwgMSwgMSkpIHtcclxuICAgICAgICAgICAgbm9kZS5zY2FsZSA9IGJhYnlsb25UcmFuc2Zvcm1Ob2RlLnNjYWxpbmcuYXNBcnJheSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3Qgcm90YXRpb25RdWF0ZXJuaW9uID0gUXVhdGVybmlvbi5Gcm9tRXVsZXJBbmdsZXMoYmFieWxvblRyYW5zZm9ybU5vZGUucm90YXRpb24ueCwgYmFieWxvblRyYW5zZm9ybU5vZGUucm90YXRpb24ueSwgYmFieWxvblRyYW5zZm9ybU5vZGUucm90YXRpb24ueik7XHJcbiAgICAgICAgaWYgKGJhYnlsb25UcmFuc2Zvcm1Ob2RlLnJvdGF0aW9uUXVhdGVybmlvbikge1xyXG4gICAgICAgICAgICByb3RhdGlvblF1YXRlcm5pb24ubXVsdGlwbHlJblBsYWNlKGJhYnlsb25UcmFuc2Zvcm1Ob2RlLnJvdGF0aW9uUXVhdGVybmlvbik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghUXVhdGVybmlvbi5Jc0lkZW50aXR5KHJvdGF0aW9uUXVhdGVybmlvbikpIHtcclxuICAgICAgICAgICAgbm9kZS5yb3RhdGlvbiA9IHJvdGF0aW9uUXVhdGVybmlvbi5ub3JtYWxpemUoKS5hc0FycmF5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3NldENhbWVyYVRyYW5zZm9ybWF0aW9uKG5vZGU6IElOb2RlLCBiYWJ5bG9uQ2FtZXJhOiBDYW1lcmEpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCB0cmFuc2xhdGlvbiA9IFRtcFZlY3RvcnMuVmVjdG9yM1swXTtcclxuICAgICAgICBjb25zdCByb3RhdGlvbiA9IFRtcFZlY3RvcnMuUXVhdGVybmlvblswXTtcclxuICAgICAgICBiYWJ5bG9uQ2FtZXJhLmdldFdvcmxkTWF0cml4KCkuZGVjb21wb3NlKHVuZGVmaW5lZCwgcm90YXRpb24sIHRyYW5zbGF0aW9uKTtcclxuXHJcbiAgICAgICAgaWYgKCF0cmFuc2xhdGlvbi5lcXVhbHNUb0Zsb2F0cygwLCAwLCAwKSkge1xyXG4gICAgICAgICAgICBub2RlLnRyYW5zbGF0aW9uID0gdHJhbnNsYXRpb24uYXNBcnJheSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gLy8gUm90YXRpb24gYnkgMTgwIGFzIGdsVEYgaGFzIGEgZGlmZmVyZW50IGNvbnZlbnRpb24gdGhhbiBCYWJ5bG9uLlxyXG4gICAgICAgIHJvdGF0aW9uLm11bHRpcGx5SW5QbGFjZShyb3RhdGlvbjE4MFkpO1xyXG5cclxuICAgICAgICBpZiAoIVF1YXRlcm5pb24uSXNJZGVudGl0eShyb3RhdGlvbikpIHtcclxuICAgICAgICAgICAgbm9kZS5yb3RhdGlvbiA9IHJvdGF0aW9uLmFzQXJyYXkoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZ2V0VmVydGV4QnVmZmVyRnJvbU1lc2goYXR0cmlidXRlS2luZDogc3RyaW5nLCBidWZmZXJNZXNoOiBNZXNoKTogTnVsbGFibGU8VmVydGV4QnVmZmVyPiB7XHJcbiAgICAgICAgaWYgKGJ1ZmZlck1lc2guaXNWZXJ0aWNlc0RhdGFQcmVzZW50KGF0dHJpYnV0ZUtpbmQsIHRydWUpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHZlcnRleEJ1ZmZlciA9IGJ1ZmZlck1lc2guZ2V0VmVydGV4QnVmZmVyKGF0dHJpYnV0ZUtpbmQsIHRydWUpO1xyXG4gICAgICAgICAgICBpZiAodmVydGV4QnVmZmVyKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdmVydGV4QnVmZmVyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIGJ1ZmZlcnZpZXcgYmFzZWQgb24gdGhlIHZlcnRpY2VzIHR5cGUgZm9yIHRoZSBCYWJ5bG9uIG1lc2hcclxuICAgICAqIEBwYXJhbSBraW5kIEluZGljYXRlcyB0aGUgdHlwZSBvZiB2ZXJ0aWNlcyBkYXRhXHJcbiAgICAgKiBAcGFyYW0gYXR0cmlidXRlQ29tcG9uZW50S2luZCBJbmRpY2F0ZXMgdGhlIG51bWVyaWNhbCB0eXBlIHVzZWQgdG8gc3RvcmUgdGhlIGRhdGFcclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uVHJhbnNmb3JtTm9kZSBUaGUgQmFieWxvbiBtZXNoIHRvIGdldCB0aGUgdmVydGljZXMgZGF0YSBmcm9tXHJcbiAgICAgKiBAcGFyYW0gYmluYXJ5V3JpdGVyIFRoZSBidWZmZXIgdG8gd3JpdGUgdGhlIGJ1ZmZlcnZpZXcgZGF0YSB0b1xyXG4gICAgICogQHBhcmFtIGJ5dGVTdHJpZGVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfY3JlYXRlQnVmZmVyVmlld0tpbmQoXHJcbiAgICAgICAga2luZDogc3RyaW5nLFxyXG4gICAgICAgIGF0dHJpYnV0ZUNvbXBvbmVudEtpbmQ6IEFjY2Vzc29yQ29tcG9uZW50VHlwZSxcclxuICAgICAgICBiYWJ5bG9uVHJhbnNmb3JtTm9kZTogVHJhbnNmb3JtTm9kZSxcclxuICAgICAgICBiaW5hcnlXcml0ZXI6IF9CaW5hcnlXcml0ZXIsXHJcbiAgICAgICAgYnl0ZVN0cmlkZTogbnVtYmVyXHJcbiAgICApIHtcclxuICAgICAgICBjb25zdCBidWZmZXJNZXNoID1cclxuICAgICAgICAgICAgYmFieWxvblRyYW5zZm9ybU5vZGUgaW5zdGFuY2VvZiBNZXNoXHJcbiAgICAgICAgICAgICAgICA/IChiYWJ5bG9uVHJhbnNmb3JtTm9kZSBhcyBNZXNoKVxyXG4gICAgICAgICAgICAgICAgOiBiYWJ5bG9uVHJhbnNmb3JtTm9kZSBpbnN0YW5jZW9mIEluc3RhbmNlZE1lc2hcclxuICAgICAgICAgICAgICAgICAgPyAoYmFieWxvblRyYW5zZm9ybU5vZGUgYXMgSW5zdGFuY2VkTWVzaCkuc291cmNlTWVzaFxyXG4gICAgICAgICAgICAgICAgICA6IG51bGw7XHJcblxyXG4gICAgICAgIGlmIChidWZmZXJNZXNoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHZlcnRleEJ1ZmZlciA9IGJ1ZmZlck1lc2guZ2V0VmVydGV4QnVmZmVyKGtpbmQsIHRydWUpO1xyXG4gICAgICAgICAgICBjb25zdCB2ZXJ0ZXhEYXRhID0gYnVmZmVyTWVzaC5nZXRWZXJ0aWNlc0RhdGEoa2luZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHZlcnRleEJ1ZmZlciAmJiB2ZXJ0ZXhEYXRhKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB0eXBlQnl0ZUxlbmd0aCA9IFZlcnRleEJ1ZmZlci5HZXRUeXBlQnl0ZUxlbmd0aChhdHRyaWJ1dGVDb21wb25lbnRLaW5kKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJ5dGVMZW5ndGggPSB2ZXJ0ZXhEYXRhLmxlbmd0aCAqIHR5cGVCeXRlTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYnVmZmVyVmlldyA9IF9HTFRGVXRpbGl0aWVzLl9DcmVhdGVCdWZmZXJWaWV3KDAsIGJpbmFyeVdyaXRlci5nZXRCeXRlT2Zmc2V0KCksIGJ5dGVMZW5ndGgsIGJ5dGVTdHJpZGUsIGtpbmQgKyBcIiAtIFwiICsgYnVmZmVyTWVzaC5uYW1lKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlclZpZXdzLnB1c2goYnVmZmVyVmlldyk7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5fd3JpdGVBdHRyaWJ1dGVEYXRhKGtpbmQsIGF0dHJpYnV0ZUNvbXBvbmVudEtpbmQsIHZlcnRleERhdGEsIGJ5dGVTdHJpZGUgLyB0eXBlQnl0ZUxlbmd0aCwgYmluYXJ5V3JpdGVyLCBiYWJ5bG9uVHJhbnNmb3JtTm9kZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgcHJpbWl0aXZlIG1vZGUgb2YgdGhlIEJhYnlsb24gbWVzaFxyXG4gICAgICogQHBhcmFtIGJhYnlsb25NZXNoIFRoZSBCYWJ5bG9uSlMgbWVzaFxyXG4gICAgICogQHJldHVybnMgVW5zaWduZWQgaW50ZWdlciBvZiB0aGUgcHJpbWl0aXZlIG1vZGUgb3IgbnVsbFxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9nZXRNZXNoUHJpbWl0aXZlTW9kZShiYWJ5bG9uTWVzaDogQWJzdHJhY3RNZXNoKTogbnVtYmVyIHtcclxuICAgICAgICBpZiAoYmFieWxvbk1lc2ggaW5zdGFuY2VvZiBMaW5lc01lc2gpIHtcclxuICAgICAgICAgICAgcmV0dXJuIE1hdGVyaWFsLkxpbmVMaXN0RHJhd01vZGU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChiYWJ5bG9uTWVzaCBpbnN0YW5jZW9mIEluc3RhbmNlZE1lc2ggfHwgYmFieWxvbk1lc2ggaW5zdGFuY2VvZiBNZXNoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJhc2VNZXNoID0gYmFieWxvbk1lc2ggaW5zdGFuY2VvZiBNZXNoID8gYmFieWxvbk1lc2ggOiBiYWJ5bG9uTWVzaC5zb3VyY2VNZXNoO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGJhc2VNZXNoLm92ZXJyaWRlUmVuZGVyaW5nRmlsbE1vZGUgPT09IFwibnVtYmVyXCIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBiYXNlTWVzaC5vdmVycmlkZVJlbmRlcmluZ0ZpbGxNb2RlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBiYWJ5bG9uTWVzaC5tYXRlcmlhbCA/IGJhYnlsb25NZXNoLm1hdGVyaWFsLmZpbGxNb2RlIDogTWF0ZXJpYWwuVHJpYW5nbGVGaWxsTW9kZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIHByaW1pdGl2ZSBtb2RlIG9mIHRoZSBnbFRGIG1lc2ggcHJpbWl0aXZlXHJcbiAgICAgKiBAcGFyYW0gbWVzaFByaW1pdGl2ZSBnbFRGIG1lc2ggcHJpbWl0aXZlXHJcbiAgICAgKiBAcGFyYW0gcHJpbWl0aXZlTW9kZSBUaGUgcHJpbWl0aXZlIG1vZGVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfc2V0UHJpbWl0aXZlTW9kZShtZXNoUHJpbWl0aXZlOiBJTWVzaFByaW1pdGl2ZSwgcHJpbWl0aXZlTW9kZTogbnVtYmVyKSB7XHJcbiAgICAgICAgc3dpdGNoIChwcmltaXRpdmVNb2RlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgTWF0ZXJpYWwuVHJpYW5nbGVGaWxsTW9kZToge1xyXG4gICAgICAgICAgICAgICAgLy8gZ2xURiBkZWZhdWx0cyB0byB1c2luZyBUcmlhbmdsZSBNb2RlXHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIE1hdGVyaWFsLlRyaWFuZ2xlU3RyaXBEcmF3TW9kZToge1xyXG4gICAgICAgICAgICAgICAgbWVzaFByaW1pdGl2ZS5tb2RlID0gTWVzaFByaW1pdGl2ZU1vZGUuVFJJQU5HTEVfU1RSSVA7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIE1hdGVyaWFsLlRyaWFuZ2xlRmFuRHJhd01vZGU6IHtcclxuICAgICAgICAgICAgICAgIG1lc2hQcmltaXRpdmUubW9kZSA9IE1lc2hQcmltaXRpdmVNb2RlLlRSSUFOR0xFX0ZBTjtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgTWF0ZXJpYWwuUG9pbnRMaXN0RHJhd01vZGU6IHtcclxuICAgICAgICAgICAgICAgIG1lc2hQcmltaXRpdmUubW9kZSA9IE1lc2hQcmltaXRpdmVNb2RlLlBPSU5UUztcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgTWF0ZXJpYWwuUG9pbnRGaWxsTW9kZToge1xyXG4gICAgICAgICAgICAgICAgbWVzaFByaW1pdGl2ZS5tb2RlID0gTWVzaFByaW1pdGl2ZU1vZGUuUE9JTlRTO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBNYXRlcmlhbC5MaW5lTG9vcERyYXdNb2RlOiB7XHJcbiAgICAgICAgICAgICAgICBtZXNoUHJpbWl0aXZlLm1vZGUgPSBNZXNoUHJpbWl0aXZlTW9kZS5MSU5FX0xPT1A7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIE1hdGVyaWFsLkxpbmVMaXN0RHJhd01vZGU6IHtcclxuICAgICAgICAgICAgICAgIG1lc2hQcmltaXRpdmUubW9kZSA9IE1lc2hQcmltaXRpdmVNb2RlLkxJTkVTO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBNYXRlcmlhbC5MaW5lU3RyaXBEcmF3TW9kZToge1xyXG4gICAgICAgICAgICAgICAgbWVzaFByaW1pdGl2ZS5tb2RlID0gTWVzaFByaW1pdGl2ZU1vZGUuTElORV9TVFJJUDtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgdmVydGV4IGF0dHJpYnV0ZSBhY2Nlc3NvciBiYXNlZCBvZiB0aGUgZ2xURiBtZXNoIHByaW1pdGl2ZVxyXG4gICAgICogQHBhcmFtIG1lc2hQcmltaXRpdmUgZ2xURiBtZXNoIHByaW1pdGl2ZVxyXG4gICAgICogQHBhcmFtIGF0dHJpYnV0ZUtpbmQgdmVydGV4IGF0dHJpYnV0ZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9zZXRBdHRyaWJ1dGVLaW5kKGF0dHJpYnV0ZXM6IHsgW25hbWU6IHN0cmluZ106IG51bWJlciB9LCBhdHRyaWJ1dGVLaW5kOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICBzd2l0Y2ggKGF0dHJpYnV0ZUtpbmQpIHtcclxuICAgICAgICAgICAgY2FzZSBWZXJ0ZXhCdWZmZXIuUG9zaXRpb25LaW5kOiB7XHJcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLlBPU0lUSU9OID0gdGhpcy5fYWNjZXNzb3JzLmxlbmd0aCAtIDE7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFZlcnRleEJ1ZmZlci5Ob3JtYWxLaW5kOiB7XHJcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLk5PUk1BTCA9IHRoaXMuX2FjY2Vzc29ycy5sZW5ndGggLSAxO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBWZXJ0ZXhCdWZmZXIuQ29sb3JLaW5kOiB7XHJcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLkNPTE9SXzAgPSB0aGlzLl9hY2Nlc3NvcnMubGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLlRhbmdlbnRLaW5kOiB7XHJcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLlRBTkdFTlQgPSB0aGlzLl9hY2Nlc3NvcnMubGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLlVWS2luZDoge1xyXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5URVhDT09SRF8wID0gdGhpcy5fYWNjZXNzb3JzLmxlbmd0aCAtIDE7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFZlcnRleEJ1ZmZlci5VVjJLaW5kOiB7XHJcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLlRFWENPT1JEXzEgPSB0aGlzLl9hY2Nlc3NvcnMubGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLk1hdHJpY2VzSW5kaWNlc0tpbmQ6IHtcclxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuSk9JTlRTXzAgPSB0aGlzLl9hY2Nlc3NvcnMubGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLk1hdHJpY2VzSW5kaWNlc0V4dHJhS2luZDoge1xyXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5KT0lOVFNfMSA9IHRoaXMuX2FjY2Vzc29ycy5sZW5ndGggLSAxO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBWZXJ0ZXhCdWZmZXIuTWF0cmljZXNXZWlnaHRzS2luZDoge1xyXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5XRUlHSFRTXzAgPSB0aGlzLl9hY2Nlc3NvcnMubGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgVmVydGV4QnVmZmVyLk1hdHJpY2VzV2VpZ2h0c0V4dHJhS2luZDoge1xyXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5XRUlHSFRTXzEgPSB0aGlzLl9hY2Nlc3NvcnMubGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcclxuICAgICAgICAgICAgICAgIFRvb2xzLldhcm4oXCJVbnN1cHBvcnRlZCBWZXJ0ZXggQnVmZmVyIFR5cGU6IFwiICsgYXR0cmlidXRlS2luZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIGRhdGEgZm9yIHRoZSBwcmltaXRpdmUgYXR0cmlidXRlcyBvZiBlYWNoIHN1Ym1lc2hcclxuICAgICAqIEBwYXJhbSBtZXNoIGdsVEYgTWVzaCBvYmplY3QgdG8gc3RvcmUgdGhlIHByaW1pdGl2ZSBhdHRyaWJ1dGUgaW5mb3JtYXRpb25cclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uVHJhbnNmb3JtTm9kZSBCYWJ5bG9uIG1lc2ggdG8gZ2V0IHRoZSBwcmltaXRpdmUgYXR0cmlidXRlIGRhdGEgZnJvbVxyXG4gICAgICogQHBhcmFtIGJpbmFyeVdyaXRlciBCdWZmZXIgdG8gd3JpdGUgdGhlIGF0dHJpYnV0ZSBkYXRhIHRvXHJcbiAgICAgKiBAcmV0dXJucyBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBkb25lIHNldHRpbmcgdGhlIHByaW1pdGl2ZSBhdHRyaWJ1dGVzXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX3NldFByaW1pdGl2ZUF0dHJpYnV0ZXNBc3luYyhtZXNoOiBJTWVzaCwgYmFieWxvblRyYW5zZm9ybU5vZGU6IFRyYW5zZm9ybU5vZGUsIGJpbmFyeVdyaXRlcjogX0JpbmFyeVdyaXRlcik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGNvbnN0IHByb21pc2VzOiBQcm9taXNlPElNZXNoUHJpbWl0aXZlPltdID0gW107XHJcbiAgICAgICAgbGV0IGJ1ZmZlck1lc2g6IE51bGxhYmxlPE1lc2g+ID0gbnVsbDtcclxuICAgICAgICBsZXQgYnVmZmVyVmlldzogSUJ1ZmZlclZpZXc7XHJcbiAgICAgICAgbGV0IG1pbk1heDogeyBtaW46IE51bGxhYmxlPG51bWJlcltdPjsgbWF4OiBOdWxsYWJsZTxudW1iZXJbXT4gfTtcclxuXHJcbiAgICAgICAgaWYgKGJhYnlsb25UcmFuc2Zvcm1Ob2RlIGluc3RhbmNlb2YgTWVzaCkge1xyXG4gICAgICAgICAgICBidWZmZXJNZXNoID0gYmFieWxvblRyYW5zZm9ybU5vZGUgYXMgTWVzaDtcclxuICAgICAgICB9IGVsc2UgaWYgKGJhYnlsb25UcmFuc2Zvcm1Ob2RlIGluc3RhbmNlb2YgSW5zdGFuY2VkTWVzaCkge1xyXG4gICAgICAgICAgICBidWZmZXJNZXNoID0gKGJhYnlsb25UcmFuc2Zvcm1Ob2RlIGFzIEluc3RhbmNlZE1lc2gpLnNvdXJjZU1lc2g7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGF0dHJpYnV0ZURhdGE6IF9JVmVydGV4QXR0cmlidXRlRGF0YVtdID0gW1xyXG4gICAgICAgICAgICB7IGtpbmQ6IFZlcnRleEJ1ZmZlci5Qb3NpdGlvbktpbmQsIGFjY2Vzc29yVHlwZTogQWNjZXNzb3JUeXBlLlZFQzMsIGFjY2Vzc29yQ29tcG9uZW50VHlwZTogQWNjZXNzb3JDb21wb25lbnRUeXBlLkZMT0FULCBieXRlU3RyaWRlOiAxMiB9LFxyXG4gICAgICAgICAgICB7IGtpbmQ6IFZlcnRleEJ1ZmZlci5Ob3JtYWxLaW5kLCBhY2Nlc3NvclR5cGU6IEFjY2Vzc29yVHlwZS5WRUMzLCBhY2Nlc3NvckNvbXBvbmVudFR5cGU6IEFjY2Vzc29yQ29tcG9uZW50VHlwZS5GTE9BVCwgYnl0ZVN0cmlkZTogMTIgfSxcclxuICAgICAgICAgICAgeyBraW5kOiBWZXJ0ZXhCdWZmZXIuQ29sb3JLaW5kLCBhY2Nlc3NvclR5cGU6IEFjY2Vzc29yVHlwZS5WRUM0LCBhY2Nlc3NvckNvbXBvbmVudFR5cGU6IEFjY2Vzc29yQ29tcG9uZW50VHlwZS5GTE9BVCwgYnl0ZVN0cmlkZTogMTYgfSxcclxuICAgICAgICAgICAgeyBraW5kOiBWZXJ0ZXhCdWZmZXIuVGFuZ2VudEtpbmQsIGFjY2Vzc29yVHlwZTogQWNjZXNzb3JUeXBlLlZFQzQsIGFjY2Vzc29yQ29tcG9uZW50VHlwZTogQWNjZXNzb3JDb21wb25lbnRUeXBlLkZMT0FULCBieXRlU3RyaWRlOiAxNiB9LFxyXG4gICAgICAgICAgICB7IGtpbmQ6IFZlcnRleEJ1ZmZlci5VVktpbmQsIGFjY2Vzc29yVHlwZTogQWNjZXNzb3JUeXBlLlZFQzIsIGFjY2Vzc29yQ29tcG9uZW50VHlwZTogQWNjZXNzb3JDb21wb25lbnRUeXBlLkZMT0FULCBieXRlU3RyaWRlOiA4IH0sXHJcbiAgICAgICAgICAgIHsga2luZDogVmVydGV4QnVmZmVyLlVWMktpbmQsIGFjY2Vzc29yVHlwZTogQWNjZXNzb3JUeXBlLlZFQzIsIGFjY2Vzc29yQ29tcG9uZW50VHlwZTogQWNjZXNzb3JDb21wb25lbnRUeXBlLkZMT0FULCBieXRlU3RyaWRlOiA4IH0sXHJcbiAgICAgICAgICAgIHsga2luZDogVmVydGV4QnVmZmVyLk1hdHJpY2VzSW5kaWNlc0tpbmQsIGFjY2Vzc29yVHlwZTogQWNjZXNzb3JUeXBlLlZFQzQsIGFjY2Vzc29yQ29tcG9uZW50VHlwZTogQWNjZXNzb3JDb21wb25lbnRUeXBlLlVOU0lHTkVEX1NIT1JULCBieXRlU3RyaWRlOiA4IH0sXHJcbiAgICAgICAgICAgIHsga2luZDogVmVydGV4QnVmZmVyLk1hdHJpY2VzSW5kaWNlc0V4dHJhS2luZCwgYWNjZXNzb3JUeXBlOiBBY2Nlc3NvclR5cGUuVkVDNCwgYWNjZXNzb3JDb21wb25lbnRUeXBlOiBBY2Nlc3NvckNvbXBvbmVudFR5cGUuVU5TSUdORURfU0hPUlQsIGJ5dGVTdHJpZGU6IDggfSxcclxuICAgICAgICAgICAgeyBraW5kOiBWZXJ0ZXhCdWZmZXIuTWF0cmljZXNXZWlnaHRzS2luZCwgYWNjZXNzb3JUeXBlOiBBY2Nlc3NvclR5cGUuVkVDNCwgYWNjZXNzb3JDb21wb25lbnRUeXBlOiBBY2Nlc3NvckNvbXBvbmVudFR5cGUuRkxPQVQsIGJ5dGVTdHJpZGU6IDE2IH0sXHJcbiAgICAgICAgICAgIHsga2luZDogVmVydGV4QnVmZmVyLk1hdHJpY2VzV2VpZ2h0c0V4dHJhS2luZCwgYWNjZXNzb3JUeXBlOiBBY2Nlc3NvclR5cGUuVkVDNCwgYWNjZXNzb3JDb21wb25lbnRUeXBlOiBBY2Nlc3NvckNvbXBvbmVudFR5cGUuRkxPQVQsIGJ5dGVTdHJpZGU6IDE2IH0sXHJcbiAgICAgICAgXTtcclxuXHJcbiAgICAgICAgaWYgKGJ1ZmZlck1lc2gpIHtcclxuICAgICAgICAgICAgbGV0IGluZGV4QnVmZmVyVmlld0luZGV4OiBOdWxsYWJsZTxudW1iZXI+ID0gbnVsbDtcclxuICAgICAgICAgICAgY29uc3QgcHJpbWl0aXZlTW9kZSA9IHRoaXMuX2dldE1lc2hQcmltaXRpdmVNb2RlKGJ1ZmZlck1lc2gpO1xyXG4gICAgICAgICAgICBjb25zdCB2ZXJ0ZXhBdHRyaWJ1dGVCdWZmZXJWaWV3czogeyBbYXR0cmlidXRlS2luZDogc3RyaW5nXTogbnVtYmVyIH0gPSB7fTtcclxuICAgICAgICAgICAgY29uc3QgbW9ycGhUYXJnZXRNYW5hZ2VyID0gYnVmZmVyTWVzaC5tb3JwaFRhcmdldE1hbmFnZXI7XHJcblxyXG4gICAgICAgICAgICAvLyBGb3IgZWFjaCBCYWJ5bG9uTWVzaCwgY3JlYXRlIGJ1ZmZlcnZpZXdzIGZvciBlYWNoICdraW5kJ1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZSBvZiBhdHRyaWJ1dGVEYXRhKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhdHRyaWJ1dGVLaW5kID0gYXR0cmlidXRlLmtpbmQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhdHRyaWJ1dGVDb21wb25lbnRLaW5kID0gYXR0cmlidXRlLmFjY2Vzc29yQ29tcG9uZW50VHlwZTtcclxuICAgICAgICAgICAgICAgIGlmIChidWZmZXJNZXNoLmlzVmVydGljZXNEYXRhUHJlc2VudChhdHRyaWJ1dGVLaW5kLCB0cnVlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlcnRleEJ1ZmZlciA9IHRoaXMuX2dldFZlcnRleEJ1ZmZlckZyb21NZXNoKGF0dHJpYnV0ZUtpbmQsIGJ1ZmZlck1lc2gpO1xyXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZS5ieXRlU3RyaWRlID0gdmVydGV4QnVmZmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gdmVydGV4QnVmZmVyLmdldFNpemUoKSAqIFZlcnRleEJ1ZmZlci5HZXRUeXBlQnl0ZUxlbmd0aChhdHRyaWJ1dGUuYWNjZXNzb3JDb21wb25lbnRUeXBlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6IFZlcnRleEJ1ZmZlci5EZWR1Y2VTdHJpZGUoYXR0cmlidXRlS2luZCkgKiA0O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGUuYnl0ZVN0cmlkZSA9PT0gMTIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlLmFjY2Vzc29yVHlwZSA9IEFjY2Vzc29yVHlwZS5WRUMzO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlQnVmZmVyVmlld0tpbmQoYXR0cmlidXRlS2luZCwgYXR0cmlidXRlQ29tcG9uZW50S2luZCwgYmFieWxvblRyYW5zZm9ybU5vZGUsIGJpbmFyeVdyaXRlciwgYXR0cmlidXRlLmJ5dGVTdHJpZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZS5idWZmZXJWaWV3SW5kZXggPSB0aGlzLl9idWZmZXJWaWV3cy5sZW5ndGggLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIHZlcnRleEF0dHJpYnV0ZUJ1ZmZlclZpZXdzW2F0dHJpYnV0ZUtpbmRdID0gYXR0cmlidXRlLmJ1ZmZlclZpZXdJbmRleDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gV3JpdGUgYW55IG1vcnBoIHRhcmdldCBkYXRhIHRvIHRoZSBidWZmZXIgYW5kIGNyZWF0ZSBhbiBhc3NvY2lhdGVkIGJ1ZmZlciB2aWV3XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1vcnBoVGFyZ2V0TWFuYWdlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1vcnBoVGFyZ2V0TWFuYWdlci5udW1UYXJnZXRzOyArK2kpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1vcnBoVGFyZ2V0ID0gbW9ycGhUYXJnZXRNYW5hZ2VyLmdldFRhcmdldChpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1vcnBoVGFyZ2V0SW5mbyA9IHRoaXMuX2NyZWF0ZU1vcnBoVGFyZ2V0QnVmZmVyVmlld0tpbmQoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlS2luZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGUuYWNjZXNzb3JUeXBlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUNvbXBvbmVudEtpbmQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyTWVzaCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3JwaFRhcmdldCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5hcnlXcml0ZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlLmJ5dGVTdHJpZGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RvcmUgaW5mbyBhYm91dCB0aGUgbW9ycGggdGFyZ2V0IHRoYXQgd2lsbCBiZSBuZWVkZWQgbGF0ZXIgd2hlbiBjcmVhdGluZyBwZXItc3VibWVzaCBhY2Nlc3NvcnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtb3JwaFRhcmdldEluZm8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZS5tb3JwaFRhcmdldEluZm8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlLm1vcnBoVGFyZ2V0SW5mbyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGUubW9ycGhUYXJnZXRJbmZvW2ldID0gbW9ycGhUYXJnZXRJbmZvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoYnVmZmVyTWVzaC5nZXRUb3RhbEluZGljZXMoKSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaW5kaWNlcyA9IGJ1ZmZlck1lc2guZ2V0SW5kaWNlcygpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGluZGljZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBieXRlTGVuZ3RoID0gaW5kaWNlcy5sZW5ndGggKiA0O1xyXG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlclZpZXcgPSBfR0xURlV0aWxpdGllcy5fQ3JlYXRlQnVmZmVyVmlldygwLCBiaW5hcnlXcml0ZXIuZ2V0Qnl0ZU9mZnNldCgpLCBieXRlTGVuZ3RoLCB1bmRlZmluZWQsIFwiSW5kaWNlcyAtIFwiICsgYnVmZmVyTWVzaC5uYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXJWaWV3cy5wdXNoKGJ1ZmZlclZpZXcpO1xyXG4gICAgICAgICAgICAgICAgICAgIGluZGV4QnVmZmVyVmlld0luZGV4ID0gdGhpcy5fYnVmZmVyVmlld3MubGVuZ3RoIC0gMTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDAsIGxlbmd0aCA9IGluZGljZXMubGVuZ3RoOyBrIDwgbGVuZ3RoOyArK2spIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmluYXJ5V3JpdGVyLnNldFVJbnQzMihpbmRpY2VzW2tdKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChidWZmZXJNZXNoLnN1Yk1lc2hlcykge1xyXG4gICAgICAgICAgICAgICAgLy8gZ28gdGhyb3VnaCBhbGwgbWVzaCBwcmltaXRpdmVzIChzdWJtZXNoZXMpXHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHN1Ym1lc2ggb2YgYnVmZmVyTWVzaC5zdWJNZXNoZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgYmFieWxvbk1hdGVyaWFsID0gc3VibWVzaC5nZXRNYXRlcmlhbCgpIHx8IGJ1ZmZlck1lc2guZ2V0U2NlbmUoKS5kZWZhdWx0TWF0ZXJpYWw7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBtYXRlcmlhbEluZGV4OiBOdWxsYWJsZTxudW1iZXI+ID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk1hdGVyaWFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChidWZmZXJNZXNoIGluc3RhbmNlb2YgTGluZXNNZXNoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIGNvbG9yIGZyb20gdGhlIGxpbmVzIG1lc2ggYW5kIHNldCBpdCBpbiB0aGUgbWF0ZXJpYWxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsOiBJTWF0ZXJpYWwgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogYnVmZmVyTWVzaC5uYW1lICsgXCIgbWF0ZXJpYWxcIixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWJ1ZmZlck1lc2guY29sb3IuZXF1YWxzKENvbG9yMy5XaGl0ZSgpKSB8fCBidWZmZXJNZXNoLmFscGhhIDwgMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGVyaWFsLnBick1ldGFsbGljUm91Z2huZXNzID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlQ29sb3JGYWN0b3I6IGJ1ZmZlck1lc2guY29sb3IuYXNBcnJheSgpLmNvbmNhdChbYnVmZmVyTWVzaC5hbHBoYV0pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYXRlcmlhbHMucHVzaChtYXRlcmlhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRlcmlhbEluZGV4ID0gdGhpcy5fbWF0ZXJpYWxzLmxlbmd0aCAtIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgTXVsdGlNYXRlcmlhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3ViTWF0ZXJpYWwgPSBiYWJ5bG9uTWF0ZXJpYWwuc3ViTWF0ZXJpYWxzW3N1Ym1lc2gubWF0ZXJpYWxJbmRleF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3ViTWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwgPSBzdWJNYXRlcmlhbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRlcmlhbEluZGV4ID0gdGhpcy5fbWF0ZXJpYWxNYXBbYmFieWxvbk1hdGVyaWFsLnVuaXF1ZUlkXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGVyaWFsSW5kZXggPSB0aGlzLl9tYXRlcmlhbE1hcFtiYWJ5bG9uTWF0ZXJpYWwudW5pcXVlSWRdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBnbFRGTWF0ZXJpYWw6IE51bGxhYmxlPElNYXRlcmlhbD4gPSBtYXRlcmlhbEluZGV4ICE9IG51bGwgPyB0aGlzLl9tYXRlcmlhbHNbbWF0ZXJpYWxJbmRleF0gOiBudWxsO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXNoUHJpbWl0aXZlOiBJTWVzaFByaW1pdGl2ZSA9IHsgYXR0cmlidXRlczoge30gfTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZXRQcmltaXRpdmVNb2RlKG1lc2hQcmltaXRpdmUsIHByaW1pdGl2ZU1vZGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZSBvZiBhdHRyaWJ1dGVEYXRhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGF0dHJpYnV0ZUtpbmQgPSBhdHRyaWJ1dGUua2luZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChhdHRyaWJ1dGVLaW5kID09PSBWZXJ0ZXhCdWZmZXIuVVZLaW5kIHx8IGF0dHJpYnV0ZUtpbmQgPT09IFZlcnRleEJ1ZmZlci5VVjJLaW5kKSAmJiAhdGhpcy5fb3B0aW9ucy5leHBvcnRVbnVzZWRVVnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZ2xURk1hdGVyaWFsIHx8ICF0aGlzLl9nbFRGTWF0ZXJpYWxFeHBvcnRlci5faGFzVGV4dHVyZXNQcmVzZW50KGdsVEZNYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZXJ0ZXhEYXRhID0gYnVmZmVyTWVzaC5nZXRWZXJ0aWNlc0RhdGEoYXR0cmlidXRlS2luZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmVydGV4RGF0YSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVydGV4QnVmZmVyID0gdGhpcy5fZ2V0VmVydGV4QnVmZmVyRnJvbU1lc2goYXR0cmlidXRlS2luZCwgYnVmZmVyTWVzaCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmVydGV4QnVmZmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaWRlID0gdmVydGV4QnVmZmVyLmdldFNpemUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBidWZmZXJWaWV3SW5kZXggPSBhdHRyaWJ1dGUuYnVmZmVyVmlld0luZGV4O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChidWZmZXJWaWV3SW5kZXggIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRvIHNlZSBpZiBidWZmZXJ2aWV3aW5kZXggaGFzIGEgbnVtZXJpYyB2YWx1ZSBhc3NpZ25lZC5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluTWF4ID0geyBtaW46IG51bGwsIG1heDogbnVsbCB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlS2luZCA9PSBWZXJ0ZXhCdWZmZXIuUG9zaXRpb25LaW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5NYXggPSBfR0xURlV0aWxpdGllcy5fQ2FsY3VsYXRlTWluTWF4UG9zaXRpb25zKHZlcnRleERhdGEsIDAsIHZlcnRleERhdGEubGVuZ3RoIC8gc3RyaWRlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhY2Nlc3NvciA9IF9HTFRGVXRpbGl0aWVzLl9DcmVhdGVBY2Nlc3NvcihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclZpZXdJbmRleCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUtpbmQgKyBcIiAtIFwiICsgYmFieWxvblRyYW5zZm9ybU5vZGUubmFtZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZS5hY2Nlc3NvclR5cGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGUuYWNjZXNzb3JDb21wb25lbnRUeXBlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVydGV4RGF0YS5sZW5ndGggLyBzdHJpZGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluTWF4Lm1pbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbk1heC5tYXhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYWNjZXNzb3JzLnB1c2goYWNjZXNzb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZXRBdHRyaWJ1dGVLaW5kKG1lc2hQcmltaXRpdmUuYXR0cmlidXRlcywgYXR0cmlidXRlS2luZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXhCdWZmZXJWaWV3SW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGFjY2Vzc29yXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFjY2Vzc29yID0gX0dMVEZVdGlsaXRpZXMuX0NyZWF0ZUFjY2Vzc29yKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXhCdWZmZXJWaWV3SW5kZXgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImluZGljZXMgLSBcIiArIGJhYnlsb25UcmFuc2Zvcm1Ob2RlLm5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBY2Nlc3NvclR5cGUuU0NBTEFSLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQWNjZXNzb3JDb21wb25lbnRUeXBlLlVOU0lHTkVEX0lOVCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Ym1lc2guaW5kZXhDb3VudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Ym1lc2guaW5kZXhTdGFydCAqIDQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9hY2Nlc3NvcnMucHVzaChhY2Nlc3Nvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc2hQcmltaXRpdmUuaW5kaWNlcyA9IHRoaXMuX2FjY2Vzc29ycy5sZW5ndGggLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKG1lc2hQcmltaXRpdmUuYXR0cmlidXRlcykubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzaWRlT3JpZW50YXRpb24gPSBiYWJ5bG9uTWF0ZXJpYWwuX2dldEVmZmVjdGl2ZU9yaWVudGF0aW9uKGJ1ZmZlck1lc2gpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNpZGVPcmllbnRhdGlvbiA9PT0gKHRoaXMuX2JhYnlsb25TY2VuZS51c2VSaWdodEhhbmRlZFN5c3RlbSA/IE1hdGVyaWFsLkNsb2NrV2lzZVNpZGVPcmllbnRhdGlvbiA6IE1hdGVyaWFsLkNvdW50ZXJDbG9ja1dpc2VTaWRlT3JpZW50YXRpb24pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgYnl0ZU9mZnNldCA9IGluZGV4QnVmZmVyVmlld0luZGV4ICE9IG51bGwgPyB0aGlzLl9idWZmZXJWaWV3c1tpbmRleEJ1ZmZlclZpZXdJbmRleF0uYnl0ZU9mZnNldCA6IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYnl0ZU9mZnNldCA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZU9mZnNldCA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgYmFieWxvbkluZGljZXM6IE51bGxhYmxlPEluZGljZXNBcnJheT4gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4QnVmZmVyVmlld0luZGV4ICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uSW5kaWNlcyA9IGJ1ZmZlck1lc2guZ2V0SW5kaWNlcygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJhYnlsb25JbmRpY2VzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVvcmRlckluZGljZXNCYXNlZE9uUHJpbWl0aXZlTW9kZShzdWJtZXNoLCBwcmltaXRpdmVNb2RlLCBiYWJ5bG9uSW5kaWNlcywgYnl0ZU9mZnNldCwgYmluYXJ5V3JpdGVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBhdHRyaWJ1dGUgb2YgYXR0cmlidXRlRGF0YSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZXJ0ZXhEYXRhID0gYnVmZmVyTWVzaC5nZXRWZXJ0aWNlc0RhdGEoYXR0cmlidXRlLmtpbmQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZlcnRleERhdGEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJ5dGVPZmZzZXQgPSB0aGlzLl9idWZmZXJWaWV3c1t2ZXJ0ZXhBdHRyaWJ1dGVCdWZmZXJWaWV3c1thdHRyaWJ1dGUua2luZF1dLmJ5dGVPZmZzZXQgfHwgMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Jlb3JkZXJWZXJ0ZXhBdHRyaWJ1dGVEYXRhQmFzZWRPblByaW1pdGl2ZU1vZGUoc3VibWVzaCwgcHJpbWl0aXZlTW9kZSwgYXR0cmlidXRlLmtpbmQsIHZlcnRleERhdGEsIGJ5dGVPZmZzZXQsIGJpbmFyeVdyaXRlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtYXRlcmlhbEluZGV4ICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc2hQcmltaXRpdmUubWF0ZXJpYWwgPSBtYXRlcmlhbEluZGV4O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbW9ycGggdGFyZ2V0cywgd3JpdGUgb3V0IHRhcmdldHMgYW5kIGFzc29jaWF0ZWQgYWNjZXNzb3JzXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1vcnBoVGFyZ2V0TWFuYWdlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBCeSBjb252ZW50aW9uLCBtb3JwaCB0YXJnZXQgbmFtZXMgYXJlIHN0b3JlZCBpbiB0aGUgbWVzaCBleHRyYXMuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbWVzaC5leHRyYXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc2guZXh0cmFzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzaC5leHRyYXMudGFyZ2V0TmFtZXMgPSBbXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbW9ycGhUYXJnZXRNYW5hZ2VyLm51bVRhcmdldHM7ICsraSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbW9ycGhUYXJnZXQgPSBtb3JwaFRhcmdldE1hbmFnZXIuZ2V0VGFyZ2V0KGkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzaC5leHRyYXMudGFyZ2V0TmFtZXMucHVzaChtb3JwaFRhcmdldC5uYW1lKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZSBvZiBhdHRyaWJ1dGVEYXRhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbW9ycGhUYXJnZXRJbmZvID0gYXR0cmlidXRlLm1vcnBoVGFyZ2V0SW5mbz8uW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtb3JwaFRhcmdldEluZm8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV3JpdGUgdGhlIGFjY2Vzc29yXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJ5dGVPZmZzZXQgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhY2Nlc3NvciA9IF9HTFRGVXRpbGl0aWVzLl9DcmVhdGVBY2Nlc3NvcihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vcnBoVGFyZ2V0SW5mby5idWZmZXJWaWV3SW5kZXgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgJHthdHRyaWJ1dGUua2luZH0gLSAke21vcnBoVGFyZ2V0Lm5hbWV9IChNb3JwaCBUYXJnZXQpYCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vcnBoVGFyZ2V0SW5mby5hY2Nlc3NvclR5cGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGUuYWNjZXNzb3JDb21wb25lbnRUeXBlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9ycGhUYXJnZXRJbmZvLnZlcnRleENvdW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZU9mZnNldCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vcnBoVGFyZ2V0SW5mby5taW5NYXg/Lm1pbj8uYXNBcnJheSgpID8/IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3JwaFRhcmdldEluZm8ubWluTWF4Py5tYXg/LmFzQXJyYXkoKSA/PyBudWxsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2FjY2Vzc29ycy5wdXNoKGFjY2Vzc29yKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBhIHRhcmdldCB0aGF0IHJlZmVyZW5jZXMgdGhlIG5ldyBhY2Nlc3NvclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1lc2hQcmltaXRpdmUudGFyZ2V0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzaFByaW1pdGl2ZS50YXJnZXRzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbWVzaFByaW1pdGl2ZS50YXJnZXRzW2ldKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNoUHJpbWl0aXZlLnRhcmdldHNbaV0gPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2V0QXR0cmlidXRlS2luZChtZXNoUHJpbWl0aXZlLnRhcmdldHNbaV0sIGF0dHJpYnV0ZS5raW5kKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIG1lc2gucHJpbWl0aXZlcy5wdXNoKG1lc2hQcmltaXRpdmUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9leHRlbnNpb25zUG9zdEV4cG9ydE1lc2hQcmltaXRpdmVBc3luYyhcInBvc3RFeHBvcnRcIiwgbWVzaFByaW1pdGl2ZSwgc3VibWVzaCwgYmluYXJ5V3JpdGVyKTtcclxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgLyogZG8gbm90aGluZyAqL1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIGdsVEYgc2NlbmUgYmFzZWQgb24gdGhlIGFycmF5IG9mIG1lc2hlc1xyXG4gICAgICogUmV0dXJucyB0aGUgdG90YWwgYnl0ZSBvZmZzZXRcclxuICAgICAqIEBwYXJhbSBiaW5hcnlXcml0ZXIgQnVmZmVyIHRvIHdyaXRlIGJpbmFyeSBkYXRhIHRvXHJcbiAgICAgKiBAcmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGRvbmVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfY3JlYXRlU2NlbmVBc3luYyhiaW5hcnlXcml0ZXI6IF9CaW5hcnlXcml0ZXIpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBjb25zdCBzY2VuZTogSVNjZW5lID0geyBub2RlczogW10gfTtcclxuICAgICAgICBsZXQgZ2xURk5vZGVJbmRleDogbnVtYmVyO1xyXG4gICAgICAgIGxldCBnbFRGTm9kZTogSU5vZGU7XHJcbiAgICAgICAgbGV0IGRpcmVjdERlc2NlbmRlbnRzOiBOb2RlW107XHJcbiAgICAgICAgY29uc3Qgbm9kZXM6IE5vZGVbXSA9IFsuLi50aGlzLl9iYWJ5bG9uU2NlbmUudHJhbnNmb3JtTm9kZXMsIC4uLnRoaXMuX2JhYnlsb25TY2VuZS5tZXNoZXMsIC4uLnRoaXMuX2JhYnlsb25TY2VuZS5saWdodHMsIC4uLnRoaXMuX2JhYnlsb25TY2VuZS5jYW1lcmFzXTtcclxuICAgICAgICBjb25zdCByZW1vdmVkUm9vdE5vZGVzID0gbmV3IFNldDxOb2RlPigpO1xyXG5cclxuICAgICAgICAvLyBTY2VuZSBtZXRhZGF0YVxyXG4gICAgICAgIGlmICh0aGlzLl9iYWJ5bG9uU2NlbmUubWV0YWRhdGEpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMubWV0YWRhdGFTZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgc2NlbmUuZXh0cmFzID0gdGhpcy5fb3B0aW9ucy5tZXRhZGF0YVNlbGVjdG9yKHRoaXMuX2JhYnlsb25TY2VuZS5tZXRhZGF0YSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fYmFieWxvblNjZW5lLm1ldGFkYXRhLmdsdGYpIHtcclxuICAgICAgICAgICAgICAgIHNjZW5lLmV4dHJhcyA9IHRoaXMuX2JhYnlsb25TY2VuZS5tZXRhZGF0YS5nbHRmLmV4dHJhcztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUmVtb3ZlIG5vLW9wIHJvb3Qgbm9kZXNcclxuICAgICAgICBpZiAoKHRoaXMuX29wdGlvbnMucmVtb3ZlTm9vcFJvb3ROb2RlcyA/PyB0cnVlKSAmJiAhdGhpcy5fb3B0aW9ucy5pbmNsdWRlQ29vcmRpbmF0ZVN5c3RlbUNvbnZlcnNpb25Ob2Rlcykge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJvb3ROb2RlIG9mIHRoaXMuX2JhYnlsb25TY2VuZS5yb290Tm9kZXMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChpc05vb3BOb2RlKHJvb3ROb2RlLCB0aGlzLl9iYWJ5bG9uU2NlbmUudXNlUmlnaHRIYW5kZWRTeXN0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlZFJvb3ROb2Rlcy5hZGQocm9vdE5vZGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBFeGNsdWRlIHRoZSBub2RlIGZyb20gbGlzdCBvZiBub2RlcyB0byBleHBvcnRcclxuICAgICAgICAgICAgICAgICAgICBub2Rlcy5zcGxpY2Uobm9kZXMuaW5kZXhPZihyb290Tm9kZSksIDEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBFeHBvcnQgYmFieWxvbiBjYW1lcmFzIHRvIGdsVEZDYW1lcmFcclxuICAgICAgICBjb25zdCBjYW1lcmFNYXAgPSBuZXcgTWFwPENhbWVyYSwgbnVtYmVyPigpO1xyXG4gICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5jYW1lcmFzLmZvckVhY2goKGNhbWVyYSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fb3B0aW9ucy5zaG91bGRFeHBvcnROb2RlICYmICF0aGlzLl9vcHRpb25zLnNob3VsZEV4cG9ydE5vZGUoY2FtZXJhKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBnbFRGQ2FtZXJhOiBJQ2FtZXJhID0ge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogY2FtZXJhLm1vZGUgPT09IENhbWVyYS5QRVJTUEVDVElWRV9DQU1FUkEgPyBDYW1lcmFUeXBlLlBFUlNQRUNUSVZFIDogQ2FtZXJhVHlwZS5PUlRIT0dSQVBISUMsXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBpZiAoY2FtZXJhLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgIGdsVEZDYW1lcmEubmFtZSA9IGNhbWVyYS5uYW1lO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoZ2xURkNhbWVyYS50eXBlID09PSBDYW1lcmFUeXBlLlBFUlNQRUNUSVZFKSB7XHJcbiAgICAgICAgICAgICAgICBnbFRGQ2FtZXJhLnBlcnNwZWN0aXZlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIGFzcGVjdFJhdGlvOiBjYW1lcmEuZ2V0RW5naW5lKCkuZ2V0QXNwZWN0UmF0aW8oY2FtZXJhKSxcclxuICAgICAgICAgICAgICAgICAgICB5Zm92OiBjYW1lcmEuZm92TW9kZSA9PT0gQ2FtZXJhLkZPVk1PREVfVkVSVElDQUxfRklYRUQgPyBjYW1lcmEuZm92IDogY2FtZXJhLmZvdiAqIGNhbWVyYS5nZXRFbmdpbmUoKS5nZXRBc3BlY3RSYXRpbyhjYW1lcmEpLFxyXG4gICAgICAgICAgICAgICAgICAgIHpuZWFyOiBjYW1lcmEubWluWixcclxuICAgICAgICAgICAgICAgICAgICB6ZmFyOiBjYW1lcmEubWF4WixcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZ2xURkNhbWVyYS50eXBlID09PSBDYW1lcmFUeXBlLk9SVEhPR1JBUEhJQykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaGFsZldpZHRoID0gY2FtZXJhLm9ydGhvTGVmdCAmJiBjYW1lcmEub3J0aG9SaWdodCA/IDAuNSAqIChjYW1lcmEub3J0aG9SaWdodCAtIGNhbWVyYS5vcnRob0xlZnQpIDogY2FtZXJhLmdldEVuZ2luZSgpLmdldFJlbmRlcldpZHRoKCkgKiAwLjU7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBoYWxmSGVpZ2h0ID0gY2FtZXJhLm9ydGhvQm90dG9tICYmIGNhbWVyYS5vcnRob1RvcCA/IDAuNSAqIChjYW1lcmEub3J0aG9Ub3AgLSBjYW1lcmEub3J0aG9Cb3R0b20pIDogY2FtZXJhLmdldEVuZ2luZSgpLmdldFJlbmRlckhlaWdodCgpICogMC41O1xyXG4gICAgICAgICAgICAgICAgZ2xURkNhbWVyYS5vcnRob2dyYXBoaWMgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgeG1hZzogaGFsZldpZHRoLFxyXG4gICAgICAgICAgICAgICAgICAgIHltYWc6IGhhbGZIZWlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgem5lYXI6IGNhbWVyYS5taW5aLFxyXG4gICAgICAgICAgICAgICAgICAgIHpmYXI6IGNhbWVyYS5tYXhaLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY2FtZXJhTWFwLnNldChjYW1lcmEsIHRoaXMuX2NhbWVyYXMubGVuZ3RoKTtcclxuICAgICAgICAgICAgdGhpcy5fY2FtZXJhcy5wdXNoKGdsVEZDYW1lcmEpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBjb25zdCBbZXhwb3J0Tm9kZXMsIGV4cG9ydE1hdGVyaWFsc10gPSB0aGlzLl9nZXRFeHBvcnROb2Rlcyhub2Rlcyk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dsVEZNYXRlcmlhbEV4cG9ydGVyLl9jb252ZXJ0TWF0ZXJpYWxzVG9HTFRGQXN5bmMoZXhwb3J0TWF0ZXJpYWxzLCBJbWFnZU1pbWVUeXBlLlBORywgdHJ1ZSkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jcmVhdGVOb2RlTWFwQW5kQW5pbWF0aW9uc0FzeW5jKGV4cG9ydE5vZGVzLCBiaW5hcnlXcml0ZXIpLnRoZW4oKG5vZGVNYXApID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9jcmVhdGVTa2luc0FzeW5jKG5vZGVNYXAsIGJpbmFyeVdyaXRlcikudGhlbigoc2tpbk1hcCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25vZGVNYXAgPSBub2RlTWFwO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl90b3RhbEJ5dGVMZW5ndGggPSBiaW5hcnlXcml0ZXIuZ2V0Qnl0ZU9mZnNldCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl90b3RhbEJ5dGVMZW5ndGggPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInVuZGVmaW5lZCBieXRlIGxlbmd0aCFcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBCdWlsZCBIaWVyYXJjaHkgd2l0aCB0aGUgbm9kZSBtYXAuXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBiYWJ5bG9uTm9kZSBvZiBub2Rlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBnbFRGTm9kZUluZGV4ID0gdGhpcy5fbm9kZU1hcFtiYWJ5bG9uTm9kZS51bmlxdWVJZF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnbFRGTm9kZUluZGV4ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsVEZOb2RlID0gdGhpcy5fbm9kZXNbZ2xURk5vZGVJbmRleF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJhYnlsb25Ob2RlLm1ldGFkYXRhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMubWV0YWRhdGFTZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRGTm9kZS5leHRyYXMgPSB0aGlzLl9vcHRpb25zLm1ldGFkYXRhU2VsZWN0b3IoYmFieWxvbk5vZGUubWV0YWRhdGEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYmFieWxvbk5vZGUubWV0YWRhdGEuZ2x0Zikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRGTm9kZS5leHRyYXMgPSBiYWJ5bG9uTm9kZS5tZXRhZGF0YS5nbHRmLmV4dHJhcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJhYnlsb25Ob2RlIGluc3RhbmNlb2YgQ2FtZXJhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xURk5vZGUuY2FtZXJhID0gY2FtZXJhTWFwLmdldChiYWJ5bG9uTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMuc2hvdWxkRXhwb3J0Tm9kZSAmJiAhdGhpcy5fb3B0aW9ucy5zaG91bGRFeHBvcnROb2RlKGJhYnlsb25Ob2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRvb2xzLkxvZyhcIk9taXR0aW5nIFwiICsgYmFieWxvbk5vZGUubmFtZSArIFwiIGZyb20gc2NlbmUuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWJhYnlsb25Ob2RlLnBhcmVudCAmJiAhdGhpcy5fYmFieWxvblNjZW5lLnVzZVJpZ2h0SGFuZGVkU3lzdGVtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnROb2RlSGFuZGVkbmVzcyhnbFRGTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWJhYnlsb25Ob2RlLnBhcmVudCB8fCByZW1vdmVkUm9vdE5vZGVzLmhhcyhiYWJ5bG9uTm9kZS5wYXJlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjZW5lLm5vZGVzLnB1c2goZ2xURk5vZGVJbmRleCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTm9kZSBpbnN0YW5jZW9mIE1lc2gpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk5vZGUuc2tlbGV0b24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xURk5vZGUuc2tpbiA9IHNraW5NYXBbYmFieWxvbk5vZGUuc2tlbGV0b24udW5pcXVlSWRdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3REZXNjZW5kZW50cyA9IGJhYnlsb25Ob2RlLmdldERlc2NlbmRhbnRzKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFnbFRGTm9kZS5jaGlsZHJlbiAmJiBkaXJlY3REZXNjZW5kZW50cyAmJiBkaXJlY3REZXNjZW5kZW50cy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGlsZHJlbjogbnVtYmVyW10gPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGRlc2NlbmRlbnQgb2YgZGlyZWN0RGVzY2VuZGVudHMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX25vZGVNYXBbZGVzY2VuZGVudC51bmlxdWVJZF0gIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4ucHVzaCh0aGlzLl9ub2RlTWFwW2Rlc2NlbmRlbnQudW5pcXVlSWRdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsVEZOb2RlLmNoaWxkcmVuID0gY2hpbGRyZW47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzY2VuZS5ub2Rlcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2NlbmVzLnB1c2goc2NlbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHRpbmcgdGhlIG5vZGVzIGFuZCBtYXRlcmlhbHMgdGhhdCB3b3VsZCBiZSBleHBvcnRlZC5cclxuICAgICAqIEBwYXJhbSBub2RlcyBCYWJ5bG9uIHRyYW5zZm9ybSBub2Rlc1xyXG4gICAgICogQHJldHVybnMgU2V0IG9mIG1hdGVyaWFscyB3aGljaCB3b3VsZCBiZSBleHBvcnRlZC5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfZ2V0RXhwb3J0Tm9kZXMobm9kZXM6IE5vZGVbXSk6IFtOb2RlW10sIFNldDxNYXRlcmlhbD5dIHtcclxuICAgICAgICBjb25zdCBleHBvcnROb2RlczogTm9kZVtdID0gW107XHJcbiAgICAgICAgY29uc3QgZXhwb3J0TWF0ZXJpYWxzOiBTZXQ8TWF0ZXJpYWw+ID0gbmV3IFNldDxNYXRlcmlhbD4oKTtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBiYWJ5bG9uTm9kZSBvZiBub2Rlcykge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuX29wdGlvbnMuc2hvdWxkRXhwb3J0Tm9kZSB8fCB0aGlzLl9vcHRpb25zLnNob3VsZEV4cG9ydE5vZGUoYmFieWxvbk5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnROb2Rlcy5wdXNoKGJhYnlsb25Ob2RlKTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uTWVzaCA9IGJhYnlsb25Ob2RlIGFzIEFic3RyYWN0TWVzaDtcclxuICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTWVzaC5zdWJNZXNoZXMgJiYgYmFieWxvbk1lc2guc3ViTWVzaGVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXRlcmlhbCA9IGJhYnlsb25NZXNoLm1hdGVyaWFsIHx8IGJhYnlsb25NZXNoLmdldFNjZW5lKCkuZGVmYXVsdE1hdGVyaWFsO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChtYXRlcmlhbCBpbnN0YW5jZW9mIE11bHRpTWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBzdWJNYXRlcmlhbCBvZiBtYXRlcmlhbC5zdWJNYXRlcmlhbHMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdWJNYXRlcmlhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9ydE1hdGVyaWFscy5hZGQoc3ViTWF0ZXJpYWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwb3J0TWF0ZXJpYWxzLmFkZChtYXRlcmlhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYEV4Y2x1ZGluZyBub2RlICR7YmFieWxvbk5vZGUubmFtZX1gO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gW2V4cG9ydE5vZGVzLCBleHBvcnRNYXRlcmlhbHNdO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIG1hcHBpbmcgb2YgTm9kZSB1bmlxdWUgaWQgdG8gbm9kZSBpbmRleCBhbmQgaGFuZGxlcyBhbmltYXRpb25zXHJcbiAgICAgKiBAcGFyYW0gbm9kZXMgQmFieWxvbiB0cmFuc2Zvcm0gbm9kZXNcclxuICAgICAqIEBwYXJhbSBiaW5hcnlXcml0ZXIgQnVmZmVyIHRvIHdyaXRlIGJpbmFyeSBkYXRhIHRvXHJcbiAgICAgKiBAcmV0dXJucyBOb2RlIG1hcHBpbmcgb2YgdW5pcXVlIGlkIHRvIGluZGV4XHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX2NyZWF0ZU5vZGVNYXBBbmRBbmltYXRpb25zQXN5bmMobm9kZXM6IE5vZGVbXSwgYmluYXJ5V3JpdGVyOiBfQmluYXJ5V3JpdGVyKTogUHJvbWlzZTx7IFtrZXk6IG51bWJlcl06IG51bWJlciB9PiB7XHJcbiAgICAgICAgbGV0IHByb21pc2VDaGFpbiA9IFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIGNvbnN0IG5vZGVNYXA6IHsgW2tleTogbnVtYmVyXTogbnVtYmVyIH0gPSB7fTtcclxuICAgICAgICBsZXQgbm9kZUluZGV4OiBudW1iZXI7XHJcbiAgICAgICAgY29uc3QgcnVudGltZUdMVEZBbmltYXRpb246IElBbmltYXRpb24gPSB7XHJcbiAgICAgICAgICAgIG5hbWU6IFwicnVudGltZSBhbmltYXRpb25zXCIsXHJcbiAgICAgICAgICAgIGNoYW5uZWxzOiBbXSxcclxuICAgICAgICAgICAgc2FtcGxlcnM6IFtdLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgY29uc3QgaWRsZUdMVEZBbmltYXRpb25zOiBJQW5pbWF0aW9uW10gPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBiYWJ5bG9uTm9kZSBvZiBub2Rlcykge1xyXG4gICAgICAgICAgICBwcm9taXNlQ2hhaW4gPSBwcm9taXNlQ2hhaW4udGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fY3JlYXRlTm9kZUFzeW5jKGJhYnlsb25Ob2RlLCBiaW5hcnlXcml0ZXIpLnRoZW4oKG5vZGUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlID0gdGhpcy5fZXh0ZW5zaW9uc1Bvc3RFeHBvcnROb2RlQXN5bmMoXCJjcmVhdGVOb2RlQXN5bmNcIiwgbm9kZSwgYmFieWxvbk5vZGUsIG5vZGVNYXAsIGJpbmFyeVdyaXRlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb21pc2UgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBUb29scy5XYXJuKGBOb3QgZXhwb3J0aW5nIG5vZGUgJHtiYWJ5bG9uTm9kZS5uYW1lfWApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbigobm9kZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFub2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbm9kZXMucHVzaChub2RlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVJbmRleCA9IHRoaXMuX25vZGVzLmxlbmd0aCAtIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlTWFwW2JhYnlsb25Ob2RlLnVuaXF1ZUlkXSA9IG5vZGVJbmRleDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2JhYnlsb25TY2VuZS5hbmltYXRpb25Hcm91cHMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX0dMVEZBbmltYXRpb24uX0NyZWF0ZU1vcnBoVGFyZ2V0QW5pbWF0aW9uRnJvbU1vcnBoVGFyZ2V0QW5pbWF0aW9ucyhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbk5vZGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bnRpbWVHTFRGQW5pbWF0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGxlR0xURkFuaW1hdGlvbnMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVNYXAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX25vZGVzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5hcnlXcml0ZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlclZpZXdzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9hY2Nlc3NvcnMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2FuaW1hdGlvblNhbXBsZVJhdGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX29wdGlvbnMuc2hvdWxkRXhwb3J0QW5pbWF0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmFieWxvbk5vZGUuYW5pbWF0aW9ucy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX0dMVEZBbmltYXRpb24uX0NyZWF0ZU5vZGVBbmltYXRpb25Gcm9tTm9kZUFuaW1hdGlvbnMoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTm9kZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bnRpbWVHTFRGQW5pbWF0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRsZUdMVEZBbmltYXRpb25zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZU1hcCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX25vZGVzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmluYXJ5V3JpdGVyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyVmlld3MsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9hY2Nlc3NvcnMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9hbmltYXRpb25TYW1wbGVSYXRlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fb3B0aW9ucy5zaG91bGRFeHBvcnRBbmltYXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBwcm9taXNlQ2hhaW4udGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChydW50aW1lR0xURkFuaW1hdGlvbi5jaGFubmVscy5sZW5ndGggJiYgcnVudGltZUdMVEZBbmltYXRpb24uc2FtcGxlcnMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hbmltYXRpb25zLnB1c2gocnVudGltZUdMVEZBbmltYXRpb24pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlkbGVHTFRGQW5pbWF0aW9ucy5mb3JFYWNoKChpZGxlR0xURkFuaW1hdGlvbikgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGlkbGVHTFRGQW5pbWF0aW9uLmNoYW5uZWxzLmxlbmd0aCAmJiBpZGxlR0xURkFuaW1hdGlvbi5zYW1wbGVycy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9hbmltYXRpb25zLnB1c2goaWRsZUdMVEZBbmltYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9iYWJ5bG9uU2NlbmUuYW5pbWF0aW9uR3JvdXBzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgX0dMVEZBbmltYXRpb24uX0NyZWF0ZU5vZGVBbmRNb3JwaEFuaW1hdGlvbkZyb21BbmltYXRpb25Hcm91cHMoXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2FuaW1hdGlvbnMsXHJcbiAgICAgICAgICAgICAgICAgICAgbm9kZU1hcCxcclxuICAgICAgICAgICAgICAgICAgICBiaW5hcnlXcml0ZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyVmlld3MsXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYWNjZXNzb3JzLFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2FuaW1hdGlvblNhbXBsZVJhdGUsXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb3B0aW9ucy5zaG91bGRFeHBvcnRBbmltYXRpb25cclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBub2RlTWFwO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIGdsVEYgbm9kZSBmcm9tIGEgQmFieWxvbiBtZXNoXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk5vZGUgU291cmNlIEJhYnlsb24gbWVzaFxyXG4gICAgICogQHBhcmFtIGJpbmFyeVdyaXRlciBCdWZmZXIgZm9yIHN0b3JpbmcgZ2VvbWV0cnkgZGF0YVxyXG4gICAgICogQHJldHVybnMgZ2xURiBub2RlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX2NyZWF0ZU5vZGVBc3luYyhiYWJ5bG9uTm9kZTogTm9kZSwgYmluYXJ5V3JpdGVyOiBfQmluYXJ5V3JpdGVyKTogUHJvbWlzZTxJTm9kZT4ge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgLy8gY3JlYXRlIG5vZGUgdG8gaG9sZCB0cmFuc2xhdGlvbi9yb3RhdGlvbi9zY2FsZSBhbmQgdGhlIG1lc2hcclxuICAgICAgICAgICAgY29uc3Qgbm9kZTogSU5vZGUgPSB7fTtcclxuICAgICAgICAgICAgLy8gY3JlYXRlIG1lc2hcclxuICAgICAgICAgICAgY29uc3QgbWVzaDogSU1lc2ggPSB7IHByaW1pdGl2ZXM6IFtdIH07XHJcblxyXG4gICAgICAgICAgICBpZiAoYmFieWxvbk5vZGUubmFtZSkge1xyXG4gICAgICAgICAgICAgICAgbm9kZS5uYW1lID0gYmFieWxvbk5vZGUubmFtZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGJhYnlsb25Ob2RlIGluc3RhbmNlb2YgVHJhbnNmb3JtTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgLy8gU2V0IHRyYW5zZm9ybWF0aW9uXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXROb2RlVHJhbnNmb3JtYXRpb24obm9kZSwgYmFieWxvbk5vZGUpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGJhYnlsb25Ob2RlIGluc3RhbmNlb2YgTWVzaCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1vcnBoVGFyZ2V0TWFuYWdlciA9IGJhYnlsb25Ob2RlLm1vcnBoVGFyZ2V0TWFuYWdlcjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobW9ycGhUYXJnZXRNYW5hZ2VyICYmIG1vcnBoVGFyZ2V0TWFuYWdlci5udW1UYXJnZXRzID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNoLndlaWdodHMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtb3JwaFRhcmdldE1hbmFnZXIubnVtVGFyZ2V0czsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNoLndlaWdodHMucHVzaChtb3JwaFRhcmdldE1hbmFnZXIuZ2V0VGFyZ2V0KGkpLmluZmx1ZW5jZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fc2V0UHJpbWl0aXZlQXR0cmlidXRlc0FzeW5jKG1lc2gsIGJhYnlsb25Ob2RlLCBiaW5hcnlXcml0ZXIpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChtZXNoLnByaW1pdGl2ZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21lc2hlcy5wdXNoKG1lc2gpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLm1lc2ggPSB0aGlzLl9tZXNoZXMubGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGU7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChiYWJ5bG9uTm9kZSBpbnN0YW5jZW9mIENhbWVyYSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0Q2FtZXJhVHJhbnNmb3JtYXRpb24obm9kZSwgYmFieWxvbk5vZGUpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5vZGU7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIGdsVEYgc2tpbiBmcm9tIGEgQmFieWxvbiBza2VsZXRvblxyXG4gICAgICogQHBhcmFtIG5vZGVNYXAgQmFieWxvbiB0cmFuc2Zvcm0gbm9kZXNcclxuICAgICAqIEBwYXJhbSBiaW5hcnlXcml0ZXIgQnVmZmVyIHRvIHdyaXRlIGJpbmFyeSBkYXRhIHRvXHJcbiAgICAgKiBAcmV0dXJucyBOb2RlIG1hcHBpbmcgb2YgdW5pcXVlIGlkIHRvIGluZGV4XHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX2NyZWF0ZVNraW5zQXN5bmMobm9kZU1hcDogeyBba2V5OiBudW1iZXJdOiBudW1iZXIgfSwgYmluYXJ5V3JpdGVyOiBfQmluYXJ5V3JpdGVyKTogUHJvbWlzZTx7IFtrZXk6IG51bWJlcl06IG51bWJlciB9PiB7XHJcbiAgICAgICAgY29uc3QgcHJvbWlzZUNoYWluID0gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgY29uc3Qgc2tpbk1hcDogeyBba2V5OiBudW1iZXJdOiBudW1iZXIgfSA9IHt9O1xyXG4gICAgICAgIGZvciAoY29uc3Qgc2tlbGV0b24gb2YgdGhpcy5fYmFieWxvblNjZW5lLnNrZWxldG9ucykge1xyXG4gICAgICAgICAgICBpZiAoc2tlbGV0b24uYm9uZXMubGVuZ3RoIDw9IDApIHtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBza2luXHJcbiAgICAgICAgICAgIGNvbnN0IHNraW46IElTa2luID0geyBqb2ludHM6IFtdIH07XHJcbiAgICAgICAgICAgIGNvbnN0IGludmVyc2VCaW5kTWF0cmljZXM6IE1hdHJpeFtdID0gW107XHJcblxyXG4gICAgICAgICAgICBjb25zdCBib25lSW5kZXhNYXA6IHsgW2luZGV4OiBudW1iZXJdOiBCb25lIH0gPSB7fTtcclxuICAgICAgICAgICAgbGV0IG1heEJvbmVJbmRleCA9IC0xO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNrZWxldG9uLmJvbmVzLmxlbmd0aDsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBib25lID0gc2tlbGV0b24uYm9uZXNbaV07XHJcbiAgICAgICAgICAgICAgICBjb25zdCBib25lSW5kZXggPSBib25lLmdldEluZGV4KCkgPz8gaTtcclxuICAgICAgICAgICAgICAgIGlmIChib25lSW5kZXggIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYm9uZUluZGV4TWFwW2JvbmVJbmRleF0gPSBib25lO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChib25lSW5kZXggPiBtYXhCb25lSW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4Qm9uZUluZGV4ID0gYm9uZUluZGV4O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZm9yIChsZXQgYm9uZUluZGV4ID0gMDsgYm9uZUluZGV4IDw9IG1heEJvbmVJbmRleDsgKytib25lSW5kZXgpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJvbmUgPSBib25lSW5kZXhNYXBbYm9uZUluZGV4XTtcclxuICAgICAgICAgICAgICAgIGludmVyc2VCaW5kTWF0cmljZXMucHVzaChib25lLmdldEludmVydGVkQWJzb2x1dGVUcmFuc2Zvcm0oKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgdHJhbnNmb3JtTm9kZSA9IGJvbmUuZ2V0VHJhbnNmb3JtTm9kZSgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRyYW5zZm9ybU5vZGUgJiYgbm9kZU1hcFt0cmFuc2Zvcm1Ob2RlLnVuaXF1ZUlkXSAhPT0gbnVsbCAmJiBub2RlTWFwW3RyYW5zZm9ybU5vZGUudW5pcXVlSWRdICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBza2luLmpvaW50cy5wdXNoKG5vZGVNYXBbdHJhbnNmb3JtTm9kZS51bmlxdWVJZF0pO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBUb29scy5XYXJuKFwiRXhwb3J0aW5nIGEgYm9uZSB3aXRob3V0IGEgbGlua2VkIHRyYW5zZm9ybSBub2RlIGlzIGN1cnJlbnRseSB1bnN1cHBvcnRlZFwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHNraW4uam9pbnRzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBidWZmZXIgdmlldyBmb3IgaW52ZXJzZSBiaW5kIG1hdHJpY2VzXHJcbiAgICAgICAgICAgICAgICBjb25zdCBieXRlU3RyaWRlID0gNjQ7IC8vIDQgeCA0IG1hdHJpeCBvZiAzMiBiaXQgZmxvYXRcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJ5dGVMZW5ndGggPSBpbnZlcnNlQmluZE1hdHJpY2VzLmxlbmd0aCAqIGJ5dGVTdHJpZGU7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBidWZmZXJWaWV3T2Zmc2V0ID0gYmluYXJ5V3JpdGVyLmdldEJ5dGVPZmZzZXQoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlclZpZXcgPSBfR0xURlV0aWxpdGllcy5fQ3JlYXRlQnVmZmVyVmlldygwLCBidWZmZXJWaWV3T2Zmc2V0LCBieXRlTGVuZ3RoLCB1bmRlZmluZWQsIFwiSW52ZXJzZUJpbmRNYXRyaWNlc1wiICsgXCIgLSBcIiArIHNrZWxldG9uLm5hbWUpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyVmlld3MucHVzaChidWZmZXJWaWV3KTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlclZpZXdJbmRleCA9IHRoaXMuX2J1ZmZlclZpZXdzLmxlbmd0aCAtIDE7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBiaW5kTWF0cml4QWNjZXNzb3IgPSBfR0xURlV0aWxpdGllcy5fQ3JlYXRlQWNjZXNzb3IoXHJcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyVmlld0luZGV4LFxyXG4gICAgICAgICAgICAgICAgICAgIFwiSW52ZXJzZUJpbmRNYXRyaWNlc1wiICsgXCIgLSBcIiArIHNrZWxldG9uLm5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgQWNjZXNzb3JUeXBlLk1BVDQsXHJcbiAgICAgICAgICAgICAgICAgICAgQWNjZXNzb3JDb21wb25lbnRUeXBlLkZMT0FULFxyXG4gICAgICAgICAgICAgICAgICAgIGludmVyc2VCaW5kTWF0cmljZXMubGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICBudWxsXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaW52ZXJzZUJpbmRBY2Nlc3NvckluZGV4ID0gdGhpcy5fYWNjZXNzb3JzLnB1c2goYmluZE1hdHJpeEFjY2Vzc29yKSAtIDE7XHJcbiAgICAgICAgICAgICAgICBza2luLmludmVyc2VCaW5kTWF0cmljZXMgPSBpbnZlcnNlQmluZEFjY2Vzc29ySW5kZXg7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9za2lucy5wdXNoKHNraW4pO1xyXG4gICAgICAgICAgICAgICAgc2tpbk1hcFtza2VsZXRvbi51bmlxdWVJZF0gPSB0aGlzLl9za2lucy5sZW5ndGggLSAxO1xyXG5cclxuICAgICAgICAgICAgICAgIGludmVyc2VCaW5kTWF0cmljZXMuZm9yRWFjaCgobWF0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbWF0Lm0uZm9yRWFjaCgoY2VsbDogbnVtYmVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJpbmFyeVdyaXRlci5zZXRGbG9hdDMyKGNlbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHByb21pc2VDaGFpbi50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHNraW5NYXA7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBAaW50ZXJuYWxcclxuICpcclxuICogU3RvcmVzIGdsVEYgYmluYXJ5IGRhdGEuICBJZiB0aGUgYXJyYXkgYnVmZmVyIGJ5dGUgbGVuZ3RoIGlzIGV4Y2VlZGVkLCBpdCBkb3VibGVzIGluIHNpemUgZHluYW1pY2FsbHlcclxuICovXHJcbmV4cG9ydCBjbGFzcyBfQmluYXJ5V3JpdGVyIHtcclxuICAgIC8qKlxyXG4gICAgICogQXJyYXkgYnVmZmVyIHdoaWNoIHN0b3JlcyBhbGwgYmluYXJ5IGRhdGFcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfYXJyYXlCdWZmZXI6IEFycmF5QnVmZmVyO1xyXG4gICAgLyoqXHJcbiAgICAgKiBWaWV3IG9mIHRoZSBhcnJheSBidWZmZXJcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfZGF0YVZpZXc6IERhdGFWaWV3O1xyXG4gICAgLyoqXHJcbiAgICAgKiBieXRlIG9mZnNldCBvZiBkYXRhIGluIGFycmF5IGJ1ZmZlclxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9ieXRlT2Zmc2V0OiBudW1iZXI7XHJcbiAgICAvKipcclxuICAgICAqIEluaXRpYWxpemUgYmluYXJ5IHdyaXRlciB3aXRoIGFuIGluaXRpYWwgYnl0ZSBsZW5ndGhcclxuICAgICAqIEBwYXJhbSBieXRlTGVuZ3RoIEluaXRpYWwgYnl0ZSBsZW5ndGggb2YgdGhlIGFycmF5IGJ1ZmZlclxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihieXRlTGVuZ3RoOiBudW1iZXIpIHtcclxuICAgICAgICB0aGlzLl9hcnJheUJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihieXRlTGVuZ3RoKTtcclxuICAgICAgICB0aGlzLl9kYXRhVmlldyA9IG5ldyBEYXRhVmlldyh0aGlzLl9hcnJheUJ1ZmZlcik7XHJcbiAgICAgICAgdGhpcy5fYnl0ZU9mZnNldCA9IDA7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFJlc2l6ZSB0aGUgYXJyYXkgYnVmZmVyIHRvIHRoZSBzcGVjaWZpZWQgYnl0ZSBsZW5ndGhcclxuICAgICAqIEBwYXJhbSBieXRlTGVuZ3RoIFRoZSBuZXcgYnl0ZSBsZW5ndGhcclxuICAgICAqIEByZXR1cm5zIFRoZSByZXNpemVkIGFycmF5IGJ1ZmZlclxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9yZXNpemVCdWZmZXIoYnl0ZUxlbmd0aDogbnVtYmVyKTogQXJyYXlCdWZmZXIge1xyXG4gICAgICAgIGNvbnN0IG5ld0J1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihieXRlTGVuZ3RoKTtcclxuICAgICAgICBjb25zdCBjb3B5T2xkQnVmZmVyU2l6ZSA9IE1hdGgubWluKHRoaXMuX2FycmF5QnVmZmVyLmJ5dGVMZW5ndGgsIGJ5dGVMZW5ndGgpO1xyXG4gICAgICAgIGNvbnN0IG9sZFVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheSh0aGlzLl9hcnJheUJ1ZmZlciwgMCwgY29weU9sZEJ1ZmZlclNpemUpO1xyXG4gICAgICAgIGNvbnN0IG5ld1VpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShuZXdCdWZmZXIpO1xyXG4gICAgICAgIG5ld1VpbnQ4QXJyYXkuc2V0KG9sZFVpbnQ4QXJyYXksIDApO1xyXG4gICAgICAgIHRoaXMuX2FycmF5QnVmZmVyID0gbmV3QnVmZmVyO1xyXG4gICAgICAgIHRoaXMuX2RhdGFWaWV3ID0gbmV3IERhdGFWaWV3KHRoaXMuX2FycmF5QnVmZmVyKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ld0J1ZmZlcjtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogR2V0IGFuIGFycmF5IGJ1ZmZlciB3aXRoIHRoZSBsZW5ndGggb2YgdGhlIGJ5dGUgb2Zmc2V0XHJcbiAgICAgKiBAcmV0dXJucyBBcnJheUJ1ZmZlciByZXNpemVkIHRvIHRoZSBieXRlIG9mZnNldFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0QXJyYXlCdWZmZXIoKTogQXJyYXlCdWZmZXIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yZXNpemVCdWZmZXIodGhpcy5nZXRCeXRlT2Zmc2V0KCkpO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgdGhlIGJ5dGUgb2Zmc2V0IG9mIHRoZSBhcnJheSBidWZmZXJcclxuICAgICAqIEByZXR1cm5zIGJ5dGUgb2Zmc2V0XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRCeXRlT2Zmc2V0KCk6IG51bWJlciB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2J5dGVPZmZzZXQgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkJ5dGUgb2Zmc2V0IGlzIHVuZGVmaW5lZCFcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLl9ieXRlT2Zmc2V0O1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBTdG9yZXMgYW4gVUludDggaW4gdGhlIGFycmF5IGJ1ZmZlclxyXG4gICAgICogQHBhcmFtIGVudHJ5XHJcbiAgICAgKiBAcGFyYW0gYnl0ZU9mZnNldCBJZiBkZWZpbmVkLCBzcGVjaWZpZXMgd2hlcmUgdG8gc2V0IHRoZSB2YWx1ZSBhcyBhbiBvZmZzZXQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXRVSW50OChlbnRyeTogbnVtYmVyLCBieXRlT2Zmc2V0PzogbnVtYmVyKSB7XHJcbiAgICAgICAgaWYgKGJ5dGVPZmZzZXQgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICBpZiAoYnl0ZU9mZnNldCA8IHRoaXMuX2J5dGVPZmZzZXQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2RhdGFWaWV3LnNldFVpbnQ4KGJ5dGVPZmZzZXQsIGVudHJ5KTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIFRvb2xzLkVycm9yKFwiQmluYXJ5V3JpdGVyOiBieXRlb2Zmc2V0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgY3VycmVudCBiaW5hcnkgYnVmZmVyIGxlbmd0aCFcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fYnl0ZU9mZnNldCArIDEgPiB0aGlzLl9hcnJheUJ1ZmZlci5ieXRlTGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9yZXNpemVCdWZmZXIodGhpcy5fYXJyYXlCdWZmZXIuYnl0ZUxlbmd0aCAqIDIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuX2RhdGFWaWV3LnNldFVpbnQ4KHRoaXMuX2J5dGVPZmZzZXQsIGVudHJ5KTtcclxuICAgICAgICAgICAgdGhpcy5fYnl0ZU9mZnNldCArPSAxO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyBhbiBVSW50MTYgaW4gdGhlIGFycmF5IGJ1ZmZlclxyXG4gICAgICogQHBhcmFtIGVudHJ5XHJcbiAgICAgKiBAcGFyYW0gYnl0ZU9mZnNldCBJZiBkZWZpbmVkLCBzcGVjaWZpZXMgd2hlcmUgdG8gc2V0IHRoZSB2YWx1ZSBhcyBhbiBvZmZzZXQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXRVSW50MTYoZW50cnk6IG51bWJlciwgYnl0ZU9mZnNldD86IG51bWJlcikge1xyXG4gICAgICAgIGlmIChieXRlT2Zmc2V0ICE9IG51bGwpIHtcclxuICAgICAgICAgICAgaWYgKGJ5dGVPZmZzZXQgPCB0aGlzLl9ieXRlT2Zmc2V0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9kYXRhVmlldy5zZXRVaW50MTYoYnl0ZU9mZnNldCwgZW50cnksIHRydWUpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgVG9vbHMuRXJyb3IoXCJCaW5hcnlXcml0ZXI6IGJ5dGVvZmZzZXQgaXMgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50IGJpbmFyeSBidWZmZXIgbGVuZ3RoIVwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9ieXRlT2Zmc2V0ICsgMiA+IHRoaXMuX2FycmF5QnVmZmVyLmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2l6ZUJ1ZmZlcih0aGlzLl9hcnJheUJ1ZmZlci5ieXRlTGVuZ3RoICogMik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fZGF0YVZpZXcuc2V0VWludDE2KHRoaXMuX2J5dGVPZmZzZXQsIGVudHJ5LCB0cnVlKTtcclxuICAgICAgICAgICAgdGhpcy5fYnl0ZU9mZnNldCArPSAyO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYW4gVUludDMyIGluIHRoZSBhcnJheSBidWZmZXJcclxuICAgICAqIEBwYXJhbSBieXRlT2Zmc2V0IElmIGRlZmluZWQsIHNwZWNpZmllcyB3aGVyZSB0byBzZXQgdGhlIHZhbHVlIGFzIGFuIG9mZnNldC5cclxuICAgICAqIEByZXR1cm5zIGVudHJ5XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRVSW50MzIoYnl0ZU9mZnNldDogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgICAgICBpZiAoYnl0ZU9mZnNldCA8IHRoaXMuX2J5dGVPZmZzZXQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGFWaWV3LmdldFVpbnQzMihieXRlT2Zmc2V0LCB0cnVlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBUb29scy5FcnJvcihcIkJpbmFyeVdyaXRlcjogYnl0ZW9mZnNldCBpcyBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQgYmluYXJ5IGJ1ZmZlciBsZW5ndGghXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJCaW5hcnlXcml0ZXI6IGJ5dGVvZmZzZXQgaXMgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50IGJpbmFyeSBidWZmZXIgbGVuZ3RoIVwiKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldFZlY3RvcjNGbG9hdDMyRnJvbVJlZih2ZWN0b3IzOiBWZWN0b3IzLCBieXRlT2Zmc2V0OiBudW1iZXIpOiB2b2lkIHtcclxuICAgICAgICBpZiAoYnl0ZU9mZnNldCArIDggPiB0aGlzLl9ieXRlT2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIFRvb2xzLkVycm9yKGBCaW5hcnlXcml0ZXI6IGJ5dGVvZmZzZXQgaXMgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50IGJpbmFyeSBidWZmZXIgbGVuZ3RoIWApO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHZlY3RvcjMueCA9IHRoaXMuX2RhdGFWaWV3LmdldEZsb2F0MzIoYnl0ZU9mZnNldCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIHZlY3RvcjMueSA9IHRoaXMuX2RhdGFWaWV3LmdldEZsb2F0MzIoYnl0ZU9mZnNldCArIDQsIHRydWUpO1xyXG4gICAgICAgICAgICB2ZWN0b3IzLnogPSB0aGlzLl9kYXRhVmlldy5nZXRGbG9hdDMyKGJ5dGVPZmZzZXQgKyA4LCB0cnVlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHNldFZlY3RvcjNGbG9hdDMyRnJvbVJlZih2ZWN0b3IzOiBWZWN0b3IzLCBieXRlT2Zmc2V0OiBudW1iZXIpOiB2b2lkIHtcclxuICAgICAgICBpZiAoYnl0ZU9mZnNldCArIDggPiB0aGlzLl9ieXRlT2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIFRvb2xzLkVycm9yKGBCaW5hcnlXcml0ZXI6IGJ5dGVvZmZzZXQgaXMgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50IGJpbmFyeSBidWZmZXIgbGVuZ3RoIWApO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2RhdGFWaWV3LnNldEZsb2F0MzIoYnl0ZU9mZnNldCwgdmVjdG9yMy54LCB0cnVlKTtcclxuICAgICAgICAgICAgdGhpcy5fZGF0YVZpZXcuc2V0RmxvYXQzMihieXRlT2Zmc2V0ICsgNCwgdmVjdG9yMy55LCB0cnVlKTtcclxuICAgICAgICAgICAgdGhpcy5fZGF0YVZpZXcuc2V0RmxvYXQzMihieXRlT2Zmc2V0ICsgOCwgdmVjdG9yMy56LCB0cnVlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldFZlY3RvcjRGbG9hdDMyRnJvbVJlZih2ZWN0b3I0OiBWZWN0b3I0LCBieXRlT2Zmc2V0OiBudW1iZXIpOiB2b2lkIHtcclxuICAgICAgICBpZiAoYnl0ZU9mZnNldCArIDEyID4gdGhpcy5fYnl0ZU9mZnNldCkge1xyXG4gICAgICAgICAgICBUb29scy5FcnJvcihgQmluYXJ5V3JpdGVyOiBieXRlb2Zmc2V0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgY3VycmVudCBiaW5hcnkgYnVmZmVyIGxlbmd0aCFgKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB2ZWN0b3I0LnggPSB0aGlzLl9kYXRhVmlldy5nZXRGbG9hdDMyKGJ5dGVPZmZzZXQsIHRydWUpO1xyXG4gICAgICAgICAgICB2ZWN0b3I0LnkgPSB0aGlzLl9kYXRhVmlldy5nZXRGbG9hdDMyKGJ5dGVPZmZzZXQgKyA0LCB0cnVlKTtcclxuICAgICAgICAgICAgdmVjdG9yNC56ID0gdGhpcy5fZGF0YVZpZXcuZ2V0RmxvYXQzMihieXRlT2Zmc2V0ICsgOCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIHZlY3RvcjQudyA9IHRoaXMuX2RhdGFWaWV3LmdldEZsb2F0MzIoYnl0ZU9mZnNldCArIDEyLCB0cnVlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHNldFZlY3RvcjRGbG9hdDMyRnJvbVJlZih2ZWN0b3I0OiBWZWN0b3I0LCBieXRlT2Zmc2V0OiBudW1iZXIpOiB2b2lkIHtcclxuICAgICAgICBpZiAoYnl0ZU9mZnNldCArIDEyID4gdGhpcy5fYnl0ZU9mZnNldCkge1xyXG4gICAgICAgICAgICBUb29scy5FcnJvcihgQmluYXJ5V3JpdGVyOiBieXRlb2Zmc2V0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgY3VycmVudCBiaW5hcnkgYnVmZmVyIGxlbmd0aCFgKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9kYXRhVmlldy5zZXRGbG9hdDMyKGJ5dGVPZmZzZXQsIHZlY3RvcjQueCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIHRoaXMuX2RhdGFWaWV3LnNldEZsb2F0MzIoYnl0ZU9mZnNldCArIDQsIHZlY3RvcjQueSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIHRoaXMuX2RhdGFWaWV3LnNldEZsb2F0MzIoYnl0ZU9mZnNldCArIDgsIHZlY3RvcjQueiwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIHRoaXMuX2RhdGFWaWV3LnNldEZsb2F0MzIoYnl0ZU9mZnNldCArIDEyLCB2ZWN0b3I0LncsIHRydWUpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogU3RvcmVzIGEgRmxvYXQzMiBpbiB0aGUgYXJyYXkgYnVmZmVyXHJcbiAgICAgKiBAcGFyYW0gZW50cnlcclxuICAgICAqIEBwYXJhbSBieXRlT2Zmc2V0XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXRGbG9hdDMyKGVudHJ5OiBudW1iZXIsIGJ5dGVPZmZzZXQ/OiBudW1iZXIpIHtcclxuICAgICAgICBpZiAoaXNOYU4oZW50cnkpKSB7XHJcbiAgICAgICAgICAgIFRvb2xzLkVycm9yKFwiSW52YWxpZCBkYXRhIGJlaW5nIHdyaXR0ZW4hXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYnl0ZU9mZnNldCAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgIGlmIChieXRlT2Zmc2V0IDwgdGhpcy5fYnl0ZU9mZnNldCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZGF0YVZpZXcuc2V0RmxvYXQzMihieXRlT2Zmc2V0LCBlbnRyeSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBUb29scy5FcnJvcihcIkJpbmFyeVdyaXRlcjogYnl0ZW9mZnNldCBpcyBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQgYmluYXJ5IGxlbmd0aCFcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuX2J5dGVPZmZzZXQgKyA0ID4gdGhpcy5fYXJyYXlCdWZmZXIuYnl0ZUxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aGlzLl9yZXNpemVCdWZmZXIodGhpcy5fYXJyYXlCdWZmZXIuYnl0ZUxlbmd0aCAqIDIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9kYXRhVmlldy5zZXRGbG9hdDMyKHRoaXMuX2J5dGVPZmZzZXQsIGVudHJ5LCB0cnVlKTtcclxuICAgICAgICB0aGlzLl9ieXRlT2Zmc2V0ICs9IDQ7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyBhbiBVSW50MzIgaW4gdGhlIGFycmF5IGJ1ZmZlclxyXG4gICAgICogQHBhcmFtIGVudHJ5XHJcbiAgICAgKiBAcGFyYW0gYnl0ZU9mZnNldCBJZiBkZWZpbmVkLCBzcGVjaWZpZXMgd2hlcmUgdG8gc2V0IHRoZSB2YWx1ZSBhcyBhbiBvZmZzZXQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXRVSW50MzIoZW50cnk6IG51bWJlciwgYnl0ZU9mZnNldD86IG51bWJlcikge1xyXG4gICAgICAgIGlmIChieXRlT2Zmc2V0ICE9IG51bGwpIHtcclxuICAgICAgICAgICAgaWYgKGJ5dGVPZmZzZXQgPCB0aGlzLl9ieXRlT2Zmc2V0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9kYXRhVmlldy5zZXRVaW50MzIoYnl0ZU9mZnNldCwgZW50cnksIHRydWUpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgVG9vbHMuRXJyb3IoXCJCaW5hcnlXcml0ZXI6IGJ5dGVvZmZzZXQgaXMgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50IGJpbmFyeSBidWZmZXIgbGVuZ3RoIVwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9ieXRlT2Zmc2V0ICsgNCA+IHRoaXMuX2FycmF5QnVmZmVyLmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2l6ZUJ1ZmZlcih0aGlzLl9hcnJheUJ1ZmZlci5ieXRlTGVuZ3RoICogMik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fZGF0YVZpZXcuc2V0VWludDMyKHRoaXMuX2J5dGVPZmZzZXQsIGVudHJ5LCB0cnVlKTtcclxuICAgICAgICAgICAgdGhpcy5fYnl0ZU9mZnNldCArPSA0O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogU3RvcmVzIGFuIEludDE2IGluIHRoZSBhcnJheSBidWZmZXJcclxuICAgICAqIEBwYXJhbSBlbnRyeVxyXG4gICAgICogQHBhcmFtIGJ5dGVPZmZzZXQgSWYgZGVmaW5lZCwgc3BlY2lmaWVzIHdoZXJlIHRvIHNldCB0aGUgdmFsdWUgYXMgYW4gb2Zmc2V0LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0SW50MTYoZW50cnk6IG51bWJlciwgYnl0ZU9mZnNldD86IG51bWJlcikge1xyXG4gICAgICAgIGlmIChieXRlT2Zmc2V0ICE9IG51bGwpIHtcclxuICAgICAgICAgICAgaWYgKGJ5dGVPZmZzZXQgPCB0aGlzLl9ieXRlT2Zmc2V0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9kYXRhVmlldy5zZXRJbnQxNihieXRlT2Zmc2V0LCBlbnRyeSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBUb29scy5FcnJvcihcIkJpbmFyeVdyaXRlcjogYnl0ZW9mZnNldCBpcyBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQgYmluYXJ5IGJ1ZmZlciBsZW5ndGghXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2J5dGVPZmZzZXQgKyAyID4gdGhpcy5fYXJyYXlCdWZmZXIuYnl0ZUxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fcmVzaXplQnVmZmVyKHRoaXMuX2FycmF5QnVmZmVyLmJ5dGVMZW5ndGggKiAyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLl9kYXRhVmlldy5zZXRJbnQxNih0aGlzLl9ieXRlT2Zmc2V0LCBlbnRyeSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIHRoaXMuX2J5dGVPZmZzZXQgKz0gMjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyBhIGJ5dGUgaW4gdGhlIGFycmF5IGJ1ZmZlclxyXG4gICAgICogQHBhcmFtIGVudHJ5XHJcbiAgICAgKiBAcGFyYW0gYnl0ZU9mZnNldCBJZiBkZWZpbmVkLCBzcGVjaWZpZXMgd2hlcmUgdG8gc2V0IHRoZSB2YWx1ZSBhcyBhbiBvZmZzZXQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXRCeXRlKGVudHJ5OiBudW1iZXIsIGJ5dGVPZmZzZXQ/OiBudW1iZXIpIHtcclxuICAgICAgICBpZiAoYnl0ZU9mZnNldCAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgIGlmIChieXRlT2Zmc2V0IDwgdGhpcy5fYnl0ZU9mZnNldCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZGF0YVZpZXcuc2V0SW50OChieXRlT2Zmc2V0LCBlbnRyeSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBUb29scy5FcnJvcihcIkJpbmFyeVdyaXRlcjogYnl0ZW9mZnNldCBpcyBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQgYmluYXJ5IGJ1ZmZlciBsZW5ndGghXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2J5dGVPZmZzZXQgKyAxID4gdGhpcy5fYXJyYXlCdWZmZXIuYnl0ZUxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fcmVzaXplQnVmZmVyKHRoaXMuX2FycmF5QnVmZmVyLmJ5dGVMZW5ndGggKiAyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLl9kYXRhVmlldy5zZXRJbnQ4KHRoaXMuX2J5dGVPZmZzZXQsIGVudHJ5KTtcclxuICAgICAgICAgICAgdGhpcy5fYnl0ZU9mZnNldCsrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCJpbXBvcnQgdHlwZSB7IEltYWdlTWltZVR5cGUsIElNZXNoUHJpbWl0aXZlLCBJTm9kZSwgSU1hdGVyaWFsLCBJVGV4dHVyZUluZm8gfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB0eXBlIHsgTm9kZSB9IGZyb20gXCJjb3JlL25vZGVcIjtcclxuaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IFRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvdGV4dHVyZVwiO1xyXG5pbXBvcnQgdHlwZSB7IFN1Yk1lc2ggfSBmcm9tIFwiY29yZS9NZXNoZXMvc3ViTWVzaFwiO1xyXG5pbXBvcnQgdHlwZSB7IElEaXNwb3NhYmxlIH0gZnJvbSBcImNvcmUvc2NlbmVcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgX0JpbmFyeVdyaXRlciB9IGZyb20gXCIuL2dsVEZFeHBvcnRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGRXhwb3J0ZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkZpbGVFeHBvcnRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgQmFzZVRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvYmFzZVRleHR1cmVcIjtcclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXZhciwgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCB2YXIgX19JR0xURkV4cG9ydGVyRXh0ZW5zaW9uVjIgPSAwOyAvLyBJIGFtIGhlcmUgdG8gYWxsb3cgZHRzIHRvIGJlIGNyZWF0ZWRcclxuXHJcbi8qKlxyXG4gKiBJbnRlcmZhY2UgZm9yIGEgZ2xURiBleHBvcnRlciBleHRlbnNpb25cclxuICogQGludGVybmFsXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGRXhwb3J0ZXJFeHRlbnNpb25WMiBleHRlbmRzIElHTFRGRXhwb3J0ZXJFeHRlbnNpb24sIElEaXNwb3NhYmxlIHtcclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lIHRoaXMgbWV0aG9kIHRvIG1vZGlmeSB0aGUgZGVmYXVsdCBiZWhhdmlvciBiZWZvcmUgZXhwb3J0aW5nIGEgdGV4dHVyZVxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIGJhYnlsb25UZXh0dXJlIFRoZSBCYWJ5bG9uLmpzIHRleHR1cmVcclxuICAgICAqIEBwYXJhbSBtaW1lVHlwZSBUaGUgbWltZS10eXBlIG9mIHRoZSBnZW5lcmF0ZWQgaW1hZ2VcclxuICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGV4cG9ydGVkIHRleHR1cmVcclxuICAgICAqL1xyXG4gICAgcHJlRXhwb3J0VGV4dHVyZUFzeW5jPyhjb250ZXh0OiBzdHJpbmcsIGJhYnlsb25UZXh0dXJlOiBOdWxsYWJsZTxUZXh0dXJlPiwgbWltZVR5cGU6IEltYWdlTWltZVR5cGUpOiBQcm9taXNlPE51bGxhYmxlPFRleHR1cmU+PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZSB0aGlzIG1ldGhvZCB0byBnZXQgbm90aWZpZWQgd2hlbiBhIHRleHR1cmUgaW5mbyBpcyBjcmVhdGVkXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gdGV4dHVyZUluZm8gVGhlIGdsVEYgdGV4dHVyZSBpbmZvXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvblRleHR1cmUgVGhlIEJhYnlsb24uanMgdGV4dHVyZVxyXG4gICAgICovXHJcbiAgICBwb3N0RXhwb3J0VGV4dHVyZT8oY29udGV4dDogc3RyaW5nLCB0ZXh0dXJlSW5mbzogSVRleHR1cmVJbmZvLCBiYWJ5bG9uVGV4dHVyZTogQmFzZVRleHR1cmUpOiB2b2lkO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lIHRoaXMgbWV0aG9kIHRvIG1vZGlmeSB0aGUgZGVmYXVsdCBiZWhhdmlvciB3aGVuIGV4cG9ydGluZyB0ZXh0dXJlIGluZm9cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBtZXNoUHJpbWl0aXZlIGdsVEYgbWVzaCBwcmltaXRpdmVcclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uU3ViTWVzaCBCYWJ5bG9uIHN1Ym1lc2hcclxuICAgICAqIEBwYXJhbSBiaW5hcnlXcml0ZXIgZ2xURiBzZXJpYWxpemVyIGJpbmFyeSB3cml0ZXIgaW5zdGFuY2VcclxuICAgICAqIEByZXR1cm5zIG51bGxhYmxlIElNZXNoUHJpbWl0aXZlIHByb21pc2VcclxuICAgICAqL1xyXG4gICAgcG9zdEV4cG9ydE1lc2hQcmltaXRpdmVBc3luYz8oY29udGV4dDogc3RyaW5nLCBtZXNoUHJpbWl0aXZlOiBOdWxsYWJsZTxJTWVzaFByaW1pdGl2ZT4sIGJhYnlsb25TdWJNZXNoOiBTdWJNZXNoLCBiaW5hcnlXcml0ZXI6IF9CaW5hcnlXcml0ZXIpOiBQcm9taXNlPElNZXNoUHJpbWl0aXZlPjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZSB0aGlzIG1ldGhvZCB0byBtb2RpZnkgdGhlIGRlZmF1bHQgYmVoYXZpb3Igd2hlbiBleHBvcnRpbmcgYSBub2RlXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCB3aGVuIGV4cG9ydGluZyB0aGUgbm9kZVxyXG4gICAgICogQHBhcmFtIG5vZGUgZ2xURiBub2RlXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk5vZGUgQmFieWxvbkpTIG5vZGVcclxuICAgICAqIEByZXR1cm5zIG51bGxhYmxlIElOb2RlIHByb21pc2VcclxuICAgICAqL1xyXG4gICAgcG9zdEV4cG9ydE5vZGVBc3luYz8oY29udGV4dDogc3RyaW5nLCBub2RlOiBOdWxsYWJsZTxJTm9kZT4sIGJhYnlsb25Ob2RlOiBOb2RlLCBub2RlTWFwOiB7IFtrZXk6IG51bWJlcl06IG51bWJlciB9LCBiaW5hcnlXcml0ZXI6IF9CaW5hcnlXcml0ZXIpOiBQcm9taXNlPE51bGxhYmxlPElOb2RlPj47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmUgdGhpcyBtZXRob2QgdG8gbW9kaWZ5IHRoZSBkZWZhdWx0IGJlaGF2aW9yIHdoZW4gZXhwb3J0aW5nIGEgbWF0ZXJpYWxcclxuICAgICAqIEBwYXJhbSBtYXRlcmlhbCBnbFRGIG1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk1hdGVyaWFsIEJhYnlsb25KUyBtYXRlcmlhbFxyXG4gICAgICogQHJldHVybnMgbnVsbGFibGUgSU1hdGVyaWFsIHByb21pc2VcclxuICAgICAqL1xyXG4gICAgcG9zdEV4cG9ydE1hdGVyaWFsQXN5bmM/KGNvbnRleHQ6IHN0cmluZywgbm9kZTogTnVsbGFibGU8SU1hdGVyaWFsPiwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IFByb21pc2U8SU1hdGVyaWFsPjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZSB0aGlzIG1ldGhvZCB0byByZXR1cm4gYWRkaXRpb25hbCB0ZXh0dXJlcyB0byBleHBvcnQgZnJvbSBhIG1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gbWF0ZXJpYWwgZ2xURiBtYXRlcmlhbFxyXG4gICAgICogQHBhcmFtIGJhYnlsb25NYXRlcmlhbCBCYWJ5bG9uSlMgbWF0ZXJpYWxcclxuICAgICAqIEByZXR1cm5zIExpc3Qgb2YgdGV4dHVyZXNcclxuICAgICAqL1xyXG4gICAgcG9zdEV4cG9ydE1hdGVyaWFsQWRkaXRpb25hbFRleHR1cmVzPyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IEJhc2VUZXh0dXJlW107XHJcblxyXG4gICAgLyoqIEdldHMgYSBib29sZWFuIGluZGljYXRpbmcgdGhhdCB0aGlzIGV4dGVuc2lvbiB3YXMgdXNlZCAqL1xyXG4gICAgd2FzVXNlZDogYm9vbGVhbjtcclxuXHJcbiAgICAvKiogR2V0cyBhIGJvb2xlYW4gaW5kaWNhdGluZyB0aGF0IHRoaXMgZXh0ZW5zaW9uIGlzIHJlcXVpcmVkIGZvciB0aGUgZmlsZSB0byB3b3JrICovXHJcbiAgICByZXF1aXJlZDogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGxlZCBhZnRlciB0aGUgZXhwb3J0ZXIgc3RhdGUgY2hhbmdlcyB0byBFWFBPUlRJTkdcclxuICAgICAqL1xyXG4gICAgb25FeHBvcnRpbmc/KCk6IHZvaWQ7XHJcbn1cclxuIiwiaW1wb3J0IHR5cGUgeyBJVGV4dHVyZUluZm8sIElNYXRlcmlhbCwgSU1hdGVyaWFsUGJyTWV0YWxsaWNSb3VnaG5lc3MsIElNYXRlcmlhbE9jY2x1c2lvblRleHR1cmVJbmZvLCBJU2FtcGxlciwgSU1hdGVyaWFsRXh0ZW5zaW9uIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyBJbWFnZU1pbWVUeXBlLCBNYXRlcmlhbEFscGhhTW9kZSwgVGV4dHVyZU1hZ0ZpbHRlciwgVGV4dHVyZU1pbkZpbHRlciwgVGV4dHVyZVdyYXBNb2RlIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5cclxuaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IFZlY3RvcjIgfSBmcm9tIFwiY29yZS9NYXRocy9tYXRoLnZlY3RvclwiO1xyXG5pbXBvcnQgeyBDb2xvcjMgfSBmcm9tIFwiY29yZS9NYXRocy9tYXRoLmNvbG9yXCI7XHJcbmltcG9ydCB7IFNjYWxhciB9IGZyb20gXCJjb3JlL01hdGhzL21hdGguc2NhbGFyXCI7XHJcbmltcG9ydCB7IFRvb2xzIH0gZnJvbSBcImNvcmUvTWlzYy90b29sc1wiO1xyXG5pbXBvcnQgeyBUZXh0dXJlVG9vbHMgfSBmcm9tIFwiY29yZS9NaXNjL3RleHR1cmVUb29sc1wiO1xyXG5pbXBvcnQgdHlwZSB7IEJhc2VUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL2Jhc2VUZXh0dXJlXCI7XHJcbmltcG9ydCB7IFRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvdGV4dHVyZVwiO1xyXG5pbXBvcnQgeyBSYXdUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL3Jhd1RleHR1cmVcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgU2NlbmUgfSBmcm9tIFwiY29yZS9zY2VuZVwiO1xyXG5cclxuaW1wb3J0IHR5cGUgeyBfRXhwb3J0ZXIgfSBmcm9tIFwiLi9nbFRGRXhwb3J0ZXJcIjtcclxuaW1wb3J0IHsgQ29uc3RhbnRzIH0gZnJvbSBcImNvcmUvRW5naW5lcy9jb25zdGFudHNcIjtcclxuaW1wb3J0IHsgRHVtcFRvb2xzIH0gZnJvbSBcImNvcmUvTWlzYy9kdW1wVG9vbHNcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBTdGFuZGFyZE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL3N0YW5kYXJkTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBQQlJCYXNlTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3BickJhc2VNYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5cclxuLyoqXHJcbiAqIEludGVyZmFjZSBmb3Igc3RvcmluZyBzcGVjdWxhciBnbG9zc2luZXNzIGZhY3RvcnNcclxuICogQGludGVybmFsXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmludGVyZmFjZSBfSVBCUlNwZWN1bGFyR2xvc3NpbmVzcyB7XHJcbiAgICAvKipcclxuICAgICAqIFJlcHJlc2VudHMgdGhlIGxpbmVhciBkaWZmdXNlIGZhY3RvcnMgb2YgdGhlIG1hdGVyaWFsXHJcbiAgICAgKi9cclxuICAgIGRpZmZ1c2VDb2xvcjogQ29sb3IzO1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXByZXNlbnRzIHRoZSBsaW5lYXIgc3BlY3VsYXIgZmFjdG9ycyBvZiB0aGUgbWF0ZXJpYWxcclxuICAgICAqL1xyXG4gICAgc3BlY3VsYXJDb2xvcjogQ29sb3IzO1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXByZXNlbnRzIHRoZSBzbW9vdGhuZXNzIG9mIHRoZSBtYXRlcmlhbFxyXG4gICAgICovXHJcbiAgICBnbG9zc2luZXNzOiBudW1iZXI7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBJbnRlcmZhY2UgZm9yIHN0b3JpbmcgbWV0YWxsaWMgcm91Z2huZXNzIGZhY3RvcnNcclxuICogQGludGVybmFsXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmludGVyZmFjZSBfSVBCUk1ldGFsbGljUm91Z2huZXNzIHtcclxuICAgIC8qKlxyXG4gICAgICogUmVwcmVzZW50cyB0aGUgYWxiZWRvIGNvbG9yIG9mIHRoZSBtYXRlcmlhbFxyXG4gICAgICovXHJcbiAgICBiYXNlQ29sb3I6IENvbG9yMztcclxuICAgIC8qKlxyXG4gICAgICogUmVwcmVzZW50cyB0aGUgbWV0YWxuZXNzIG9mIHRoZSBtYXRlcmlhbFxyXG4gICAgICovXHJcbiAgICBtZXRhbGxpYzogTnVsbGFibGU8bnVtYmVyPjtcclxuICAgIC8qKlxyXG4gICAgICogUmVwcmVzZW50cyB0aGUgcm91Z2huZXNzIG9mIHRoZSBtYXRlcmlhbFxyXG4gICAgICovXHJcbiAgICByb3VnaG5lc3M6IE51bGxhYmxlPG51bWJlcj47XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBtZXRhbGxpYyByb3VnaG5lc3MgdGV4dHVyZSBkYXRhXHJcbiAgICAgKi9cclxuICAgIG1ldGFsbGljUm91Z2huZXNzVGV4dHVyZURhdGE/OiBOdWxsYWJsZTxBcnJheUJ1ZmZlcj47XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBiYXNlIGNvbG9yIHRleHR1cmUgZGF0YVxyXG4gICAgICovXHJcbiAgICBiYXNlQ29sb3JUZXh0dXJlRGF0YT86IE51bGxhYmxlPEFycmF5QnVmZmVyPjtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0RmlsZUV4dGVuc2lvbkZyb21NaW1lVHlwZShtaW1lVHlwZTogSW1hZ2VNaW1lVHlwZSk6IHN0cmluZyB7XHJcbiAgICBzd2l0Y2ggKG1pbWVUeXBlKSB7XHJcbiAgICAgICAgY2FzZSBJbWFnZU1pbWVUeXBlLkpQRUc6XHJcbiAgICAgICAgICAgIHJldHVybiBcIi5qcGdcIjtcclxuICAgICAgICBjYXNlIEltYWdlTWltZVR5cGUuUE5HOlxyXG4gICAgICAgICAgICByZXR1cm4gXCIucG5nXCI7XHJcbiAgICAgICAgY2FzZSBJbWFnZU1pbWVUeXBlLldFQlA6XHJcbiAgICAgICAgICAgIHJldHVybiBcIi53ZWJwXCI7XHJcbiAgICAgICAgY2FzZSBJbWFnZU1pbWVUeXBlLkFWSUY6XHJcbiAgICAgICAgICAgIHJldHVybiBcIi5hdmlmXCI7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBVdGlsaXR5IG1ldGhvZHMgZm9yIHdvcmtpbmcgd2l0aCBnbFRGIG1hdGVyaWFsIGNvbnZlcnNpb24gcHJvcGVydGllcy4gIFRoaXMgY2xhc3Mgc2hvdWxkIG9ubHkgYmUgdXNlZCBpbnRlcm5hbGx5XHJcbiAqIEBpbnRlcm5hbFxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIF9HTFRGTWF0ZXJpYWxFeHBvcnRlciB7XHJcbiAgICAvKipcclxuICAgICAqIFJlcHJlc2VudHMgdGhlIGRpZWxlY3RyaWMgc3BlY3VsYXIgdmFsdWVzIGZvciBSLCBHIGFuZCBCXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IF9EaWVsZWN0cmljU3BlY3VsYXI6IENvbG9yMyA9IG5ldyBDb2xvcjMoMC4wNCwgMC4wNCwgMC4wNCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGxvd3MgdGhlIG1heGltdW0gc3BlY3VsYXIgcG93ZXIgdG8gYmUgZGVmaW5lZCBmb3IgbWF0ZXJpYWwgY2FsY3VsYXRpb25zXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IF9NYXhTcGVjdWxhclBvd2VyID0gMTAyNDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1hcHBpbmcgdG8gc3RvcmUgdGV4dHVyZXNcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfdGV4dHVyZU1hcDogeyBbdGV4dHVyZUlkOiBzdHJpbmddOiBJVGV4dHVyZUluZm8gfSA9IHt9O1xyXG5cclxuICAgIC8vIE1hcHBpbmcgb2YgaW50ZXJuYWwgdGV4dHVyZXMgdG8gaW1hZ2VzIHRvIGF2b2lkIGV4cG9ydGluZyBkdXBsaWNhdGUgaW1hZ2VzLlxyXG4gICAgcHJpdmF0ZSBfaW50ZXJuYWxUZXh0dXJlVG9JbWFnZTogeyBbdW5pcXVlSWQ6IG51bWJlcl06IHsgW21pbWVUeXBlOiBzdHJpbmddOiBQcm9taXNlPG51bWJlcj4gfSB9ID0ge307XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBOdW1lcmljIHRvbGVyYW5jZSB2YWx1ZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBfRXBzaWxvbiA9IDFlLTY7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZlcmVuY2UgdG8gdGhlIGdsVEYgRXhwb3J0ZXJcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfZXhwb3J0ZXI6IF9FeHBvcnRlcjtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihleHBvcnRlcjogX0V4cG9ydGVyKSB7XHJcbiAgICAgICAgdGhpcy5fdGV4dHVyZU1hcCA9IHt9O1xyXG4gICAgICAgIHRoaXMuX2V4cG9ydGVyID0gZXhwb3J0ZXI7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTcGVjaWZpZXMgaWYgdHdvIGNvbG9ycyBhcmUgYXBwcm94aW1hdGVseSBlcXVhbCBpbiB2YWx1ZVxyXG4gICAgICogQHBhcmFtIGNvbG9yMSBmaXJzdCBjb2xvciB0byBjb21wYXJlIHRvXHJcbiAgICAgKiBAcGFyYW0gY29sb3IyIHNlY29uZCBjb2xvciB0byBjb21wYXJlIHRvXHJcbiAgICAgKiBAcGFyYW0gZXBzaWxvbiB0aHJlc2hvbGQgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIGJvb2xlYW4gc3BlY2lmeWluZyBpZiB0aGUgY29sb3JzIGFyZSBhcHByb3hpbWF0ZWx5IGVxdWFsIGluIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIF9GdXp6eUVxdWFscyhjb2xvcjE6IENvbG9yMywgY29sb3IyOiBDb2xvcjMsIGVwc2lsb246IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiBTY2FsYXIuV2l0aGluRXBzaWxvbihjb2xvcjEuciwgY29sb3IyLnIsIGVwc2lsb24pICYmIFNjYWxhci5XaXRoaW5FcHNpbG9uKGNvbG9yMS5nLCBjb2xvcjIuZywgZXBzaWxvbikgJiYgU2NhbGFyLldpdGhpbkVwc2lsb24oY29sb3IxLmIsIGNvbG9yMi5iLCBlcHNpbG9uKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIG1hdGVyaWFscyBmcm9tIGEgQmFieWxvbiBzY2VuZSBhbmQgY29udmVydHMgdGhlbSB0byBnbFRGIG1hdGVyaWFsc1xyXG4gICAgICogQHBhcmFtIGV4cG9ydE1hdGVyaWFsc1xyXG4gICAgICogQHBhcmFtIG1pbWVUeXBlIHRleHR1cmUgbWltZSB0eXBlXHJcbiAgICAgKiBAcGFyYW0gaGFzVGV4dHVyZUNvb3JkcyBzcGVjaWZpZXMgaWYgdGV4dHVyZSBjb29yZGluYXRlcyBhcmUgcHJlc2VudCBvbiB0aGUgbWF0ZXJpYWxcclxuICAgICAqIEByZXR1cm5zIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciBhbGwgbWF0ZXJpYWxzIGhhdmUgYmVlbiBjb252ZXJ0ZWRcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9jb252ZXJ0TWF0ZXJpYWxzVG9HTFRGQXN5bmMoZXhwb3J0TWF0ZXJpYWxzOiBTZXQ8TWF0ZXJpYWw+LCBtaW1lVHlwZTogSW1hZ2VNaW1lVHlwZSwgaGFzVGV4dHVyZUNvb3JkczogYm9vbGVhbikge1xyXG4gICAgICAgIGNvbnN0IHByb21pc2VzOiBQcm9taXNlPElNYXRlcmlhbD5bXSA9IFtdO1xyXG4gICAgICAgIGV4cG9ydE1hdGVyaWFscy5mb3JFYWNoKChtYXRlcmlhbCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAobWF0ZXJpYWwuZ2V0Q2xhc3NOYW1lKCkgPT09IFwiU3RhbmRhcmRNYXRlcmlhbFwiKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2NvbnZlcnRTdGFuZGFyZE1hdGVyaWFsQXN5bmMobWF0ZXJpYWwgYXMgU3RhbmRhcmRNYXRlcmlhbCwgbWltZVR5cGUsIGhhc1RleHR1cmVDb29yZHMpKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChtYXRlcmlhbC5nZXRDbGFzc05hbWUoKS5pbmRleE9mKFwiUEJSXCIpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9jb252ZXJ0UEJSTWF0ZXJpYWxBc3luYyhtYXRlcmlhbCBhcyBQQlJNYXRlcmlhbCwgbWltZVR5cGUsIGhhc1RleHR1cmVDb29yZHMpKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIFRvb2xzLldhcm4oYFVuc3VwcG9ydGVkIG1hdGVyaWFsIHR5cGU6ICR7bWF0ZXJpYWwubmFtZX1gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAvKiBkbyBub3RoaW5nICovXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYWtlcyBhIGNvcHkgb2YgdGhlIGdsVEYgbWF0ZXJpYWwgd2l0aG91dCB0aGUgdGV4dHVyZSBwYXJhbWV0ZXJzXHJcbiAgICAgKiBAcGFyYW0gb3JpZ2luYWxNYXRlcmlhbCBvcmlnaW5hbCBnbFRGIG1hdGVyaWFsXHJcbiAgICAgKiBAcmV0dXJucyBnbFRGIG1hdGVyaWFsIHdpdGhvdXQgdGV4dHVyZSBwYXJhbWV0ZXJzXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfc3RyaXBUZXh0dXJlc0Zyb21NYXRlcmlhbChvcmlnaW5hbE1hdGVyaWFsOiBJTWF0ZXJpYWwpOiBJTWF0ZXJpYWwge1xyXG4gICAgICAgIGNvbnN0IG5ld01hdGVyaWFsOiBJTWF0ZXJpYWwgPSB7fTtcclxuICAgICAgICBpZiAob3JpZ2luYWxNYXRlcmlhbCkge1xyXG4gICAgICAgICAgICBuZXdNYXRlcmlhbC5uYW1lID0gb3JpZ2luYWxNYXRlcmlhbC5uYW1lO1xyXG4gICAgICAgICAgICBuZXdNYXRlcmlhbC5kb3VibGVTaWRlZCA9IG9yaWdpbmFsTWF0ZXJpYWwuZG91YmxlU2lkZWQ7XHJcbiAgICAgICAgICAgIG5ld01hdGVyaWFsLmFscGhhTW9kZSA9IG9yaWdpbmFsTWF0ZXJpYWwuYWxwaGFNb2RlO1xyXG4gICAgICAgICAgICBuZXdNYXRlcmlhbC5hbHBoYUN1dG9mZiA9IG9yaWdpbmFsTWF0ZXJpYWwuYWxwaGFDdXRvZmY7XHJcbiAgICAgICAgICAgIG5ld01hdGVyaWFsLmVtaXNzaXZlRmFjdG9yID0gb3JpZ2luYWxNYXRlcmlhbC5lbWlzc2l2ZUZhY3RvcjtcclxuICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxQQlJNZXRhbGxpY1JvdWdobmVzcyA9IG9yaWdpbmFsTWF0ZXJpYWwucGJyTWV0YWxsaWNSb3VnaG5lc3M7XHJcbiAgICAgICAgICAgIGlmIChvcmlnaW5hbFBCUk1ldGFsbGljUm91Z2huZXNzKSB7XHJcbiAgICAgICAgICAgICAgICBuZXdNYXRlcmlhbC5wYnJNZXRhbGxpY1JvdWdobmVzcyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgbmV3TWF0ZXJpYWwucGJyTWV0YWxsaWNSb3VnaG5lc3MuYmFzZUNvbG9yRmFjdG9yID0gb3JpZ2luYWxQQlJNZXRhbGxpY1JvdWdobmVzcy5iYXNlQ29sb3JGYWN0b3I7XHJcbiAgICAgICAgICAgICAgICBuZXdNYXRlcmlhbC5wYnJNZXRhbGxpY1JvdWdobmVzcy5tZXRhbGxpY0ZhY3RvciA9IG9yaWdpbmFsUEJSTWV0YWxsaWNSb3VnaG5lc3MubWV0YWxsaWNGYWN0b3I7XHJcbiAgICAgICAgICAgICAgICBuZXdNYXRlcmlhbC5wYnJNZXRhbGxpY1JvdWdobmVzcy5yb3VnaG5lc3NGYWN0b3IgPSBvcmlnaW5hbFBCUk1ldGFsbGljUm91Z2huZXNzLnJvdWdobmVzc0ZhY3RvcjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbmV3TWF0ZXJpYWw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTcGVjaWZpZXMgaWYgdGhlIG1hdGVyaWFsIGhhcyBhbnkgdGV4dHVyZSBwYXJhbWV0ZXJzIHByZXNlbnRcclxuICAgICAqIEBwYXJhbSBtYXRlcmlhbCBnbFRGIE1hdGVyaWFsXHJcbiAgICAgKiBAcmV0dXJucyBib29sZWFuIHNwZWNpZnlpbmcgaWYgdGV4dHVyZSBwYXJhbWV0ZXJzIGFyZSBwcmVzZW50XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfaGFzVGV4dHVyZXNQcmVzZW50KG1hdGVyaWFsOiBJTWF0ZXJpYWwpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAobWF0ZXJpYWwuZW1pc3NpdmVUZXh0dXJlIHx8IG1hdGVyaWFsLm5vcm1hbFRleHR1cmUgfHwgbWF0ZXJpYWwub2NjbHVzaW9uVGV4dHVyZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgcGJyTWF0ID0gbWF0ZXJpYWwucGJyTWV0YWxsaWNSb3VnaG5lc3M7XHJcbiAgICAgICAgaWYgKHBick1hdCkge1xyXG4gICAgICAgICAgICBpZiAocGJyTWF0LmJhc2VDb2xvclRleHR1cmUgfHwgcGJyTWF0Lm1ldGFsbGljUm91Z2huZXNzVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChtYXRlcmlhbC5leHRlbnNpb25zKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgZXh0ZW5zaW9uIGluIG1hdGVyaWFsLmV4dGVuc2lvbnMpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbk9iamVjdCA9IG1hdGVyaWFsLmV4dGVuc2lvbnNbZXh0ZW5zaW9uXTtcclxuICAgICAgICAgICAgICAgIGlmIChleHRlbnNpb25PYmplY3QgYXMgSU1hdGVyaWFsRXh0ZW5zaW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvbk9iamVjdC5oYXNUZXh0dXJlcz8uKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgX2dldFRleHR1cmVJbmZvKGJhYnlsb25UZXh0dXJlOiBOdWxsYWJsZTxCYXNlVGV4dHVyZT4pOiBOdWxsYWJsZTxJVGV4dHVyZUluZm8+IHtcclxuICAgICAgICBpZiAoYmFieWxvblRleHR1cmUpIHtcclxuICAgICAgICAgICAgY29uc3QgdGV4dHVyZVVpZCA9IGJhYnlsb25UZXh0dXJlLnVpZDtcclxuICAgICAgICAgICAgaWYgKHRleHR1cmVVaWQgaW4gdGhpcy5fdGV4dHVyZU1hcCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RleHR1cmVNYXBbdGV4dHVyZVVpZF07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0cyBhIEJhYnlsb24gU3RhbmRhcmRNYXRlcmlhbCB0byBhIGdsVEYgTWV0YWxsaWMgUm91Z2huZXNzIE1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvblN0YW5kYXJkTWF0ZXJpYWxcclxuICAgICAqIEByZXR1cm5zIGdsVEYgTWV0YWxsaWMgUm91Z2huZXNzIE1hdGVyaWFsIHJlcHJlc2VudGF0aW9uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfY29udmVydFRvR0xURlBCUk1ldGFsbGljUm91Z2huZXNzKGJhYnlsb25TdGFuZGFyZE1hdGVyaWFsOiBTdGFuZGFyZE1hdGVyaWFsKTogSU1hdGVyaWFsUGJyTWV0YWxsaWNSb3VnaG5lc3Mge1xyXG4gICAgICAgIC8vIERlZmluZXMgYSBjdWJpYyBiZXppZXIgY3VydmUgd2hlcmUgeCBpcyBzcGVjdWxhciBwb3dlciBhbmQgeSBpcyByb3VnaG5lc3NcclxuICAgICAgICBjb25zdCBQMCA9IG5ldyBWZWN0b3IyKDAsIDEpO1xyXG4gICAgICAgIGNvbnN0IFAxID0gbmV3IFZlY3RvcjIoMCwgMC4xKTtcclxuICAgICAgICBjb25zdCBQMiA9IG5ldyBWZWN0b3IyKDAsIDAuMSk7XHJcbiAgICAgICAgY29uc3QgUDMgPSBuZXcgVmVjdG9yMigxMzAwLCAwLjEpO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHaXZlbiB0aGUgY29udHJvbCBwb2ludHMsIHNvbHZlIGZvciB4IGJhc2VkIG9uIGEgZ2l2ZW4gdCBmb3IgYSBjdWJpYyBiZXppZXIgY3VydmVcclxuICAgICAgICAgKiBAcGFyYW0gdCBhIHZhbHVlIGJldHdlZW4gMCBhbmQgMVxyXG4gICAgICAgICAqIEBwYXJhbSBwMCBmaXJzdCBjb250cm9sIHBvaW50XHJcbiAgICAgICAgICogQHBhcmFtIHAxIHNlY29uZCBjb250cm9sIHBvaW50XHJcbiAgICAgICAgICogQHBhcmFtIHAyIHRoaXJkIGNvbnRyb2wgcG9pbnRcclxuICAgICAgICAgKiBAcGFyYW0gcDMgZm91cnRoIGNvbnRyb2wgcG9pbnRcclxuICAgICAgICAgKiBAcmV0dXJucyBudW1iZXIgcmVzdWx0IG9mIGN1YmljIGJlemllciBjdXJ2ZSBhdCB0aGUgc3BlY2lmaWVkIHRcclxuICAgICAgICAgKi9cclxuICAgICAgICBmdW5jdGlvbiBjdWJpY0JlemllckN1cnZlKHQ6IG51bWJlciwgcDA6IG51bWJlciwgcDE6IG51bWJlciwgcDI6IG51bWJlciwgcDM6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICAgICAgICAgIHJldHVybiAoMSAtIHQpICogKDEgLSB0KSAqICgxIC0gdCkgKiBwMCArIDMgKiAoMSAtIHQpICogKDEgLSB0KSAqIHQgKiBwMSArIDMgKiAoMSAtIHQpICogdCAqIHQgKiBwMiArIHQgKiB0ICogdCAqIHAzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRXZhbHVhdGVzIGEgc3BlY2lmaWVkIHNwZWN1bGFyIHBvd2VyIHZhbHVlIHRvIGRldGVybWluZSB0aGUgYXBwcm9wcmlhdGUgcm91Z2huZXNzIHZhbHVlLFxyXG4gICAgICAgICAqIGJhc2VkIG9uIGEgcHJlLWRlZmluZWQgY3ViaWMgYmV6aWVyIGN1cnZlIHdpdGggc3BlY3VsYXIgb24gdGhlIGFic2Npc3NhIGF4aXMgKHgtYXhpcylcclxuICAgICAgICAgKiBhbmQgcm91Z2huZXNzIG9uIHRoZSBvcmRpbmFudCBheGlzICh5LWF4aXMpXHJcbiAgICAgICAgICogQHBhcmFtIHNwZWN1bGFyUG93ZXIgc3BlY3VsYXIgcG93ZXIgb2Ygc3RhbmRhcmQgbWF0ZXJpYWxcclxuICAgICAgICAgKiBAcmV0dXJucyBOdW1iZXIgcmVwcmVzZW50aW5nIHRoZSByb3VnaG5lc3MgdmFsdWVcclxuICAgICAgICAgKi9cclxuICAgICAgICBmdW5jdGlvbiBzb2x2ZUZvclJvdWdobmVzcyhzcGVjdWxhclBvd2VyOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgICAgICAvLyBHaXZlbiBQMC54ID0gMCwgUDEueCA9IDAsIFAyLnggPSAwXHJcbiAgICAgICAgICAgIC8vICAgeCA9IHQgKiB0ICogdCAqIFAzLnhcclxuICAgICAgICAgICAgLy8gICB0ID0gKHggLyBQMy54KV4oMS8zKVxyXG4gICAgICAgICAgICBjb25zdCB0ID0gTWF0aC5wb3coc3BlY3VsYXJQb3dlciAvIFAzLngsIDAuMzMzMzMzKTtcclxuICAgICAgICAgICAgcmV0dXJuIGN1YmljQmV6aWVyQ3VydmUodCwgUDAueSwgUDEueSwgUDIueSwgUDMueSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBkaWZmdXNlID0gYmFieWxvblN0YW5kYXJkTWF0ZXJpYWwuZGlmZnVzZUNvbG9yLnRvTGluZWFyU3BhY2UoYmFieWxvblN0YW5kYXJkTWF0ZXJpYWwuZ2V0U2NlbmUoKS5nZXRFbmdpbmUoKS51c2VFeGFjdFNyZ2JDb252ZXJzaW9ucykuc2NhbGUoMC41KTtcclxuICAgICAgICBjb25zdCBvcGFjaXR5ID0gYmFieWxvblN0YW5kYXJkTWF0ZXJpYWwuYWxwaGE7XHJcbiAgICAgICAgY29uc3Qgc3BlY3VsYXJQb3dlciA9IFNjYWxhci5DbGFtcChiYWJ5bG9uU3RhbmRhcmRNYXRlcmlhbC5zcGVjdWxhclBvd2VyLCAwLCBfR0xURk1hdGVyaWFsRXhwb3J0ZXIuX01heFNwZWN1bGFyUG93ZXIpO1xyXG5cclxuICAgICAgICBjb25zdCByb3VnaG5lc3MgPSBzb2x2ZUZvclJvdWdobmVzcyhzcGVjdWxhclBvd2VyKTtcclxuXHJcbiAgICAgICAgY29uc3QgZ2xURlBick1ldGFsbGljUm91Z2huZXNzOiBJTWF0ZXJpYWxQYnJNZXRhbGxpY1JvdWdobmVzcyA9IHtcclxuICAgICAgICAgICAgYmFzZUNvbG9yRmFjdG9yOiBbZGlmZnVzZS5yLCBkaWZmdXNlLmcsIGRpZmZ1c2UuYiwgb3BhY2l0eV0sXHJcbiAgICAgICAgICAgIG1ldGFsbGljRmFjdG9yOiAwLFxyXG4gICAgICAgICAgICByb3VnaG5lc3NGYWN0b3I6IHJvdWdobmVzcyxcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gZ2xURlBick1ldGFsbGljUm91Z2huZXNzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29tcHV0ZXMgdGhlIG1ldGFsbGljIGZhY3RvclxyXG4gICAgICogQHBhcmFtIGRpZmZ1c2UgZGlmZnVzZWQgdmFsdWVcclxuICAgICAqIEBwYXJhbSBzcGVjdWxhciBzcGVjdWxhciB2YWx1ZVxyXG4gICAgICogQHBhcmFtIG9uZU1pbnVzU3BlY3VsYXJTdHJlbmd0aCBvbmUgbWludXMgdGhlIHNwZWN1bGFyIHN0cmVuZ3RoXHJcbiAgICAgKiBAcmV0dXJucyBtZXRhbGxpYyB2YWx1ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIF9Tb2x2ZU1ldGFsbGljKGRpZmZ1c2U6IG51bWJlciwgc3BlY3VsYXI6IG51bWJlciwgb25lTWludXNTcGVjdWxhclN0cmVuZ3RoOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIGlmIChzcGVjdWxhciA8IHRoaXMuX0RpZWxlY3RyaWNTcGVjdWxhci5yKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX0RpZWxlY3RyaWNTcGVjdWxhcjtcclxuICAgICAgICAgICAgcmV0dXJuIDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBhID0gdGhpcy5fRGllbGVjdHJpY1NwZWN1bGFyLnI7XHJcbiAgICAgICAgY29uc3QgYiA9IChkaWZmdXNlICogb25lTWludXNTcGVjdWxhclN0cmVuZ3RoKSAvICgxLjAgLSB0aGlzLl9EaWVsZWN0cmljU3BlY3VsYXIucikgKyBzcGVjdWxhciAtIDIuMCAqIHRoaXMuX0RpZWxlY3RyaWNTcGVjdWxhci5yO1xyXG4gICAgICAgIGNvbnN0IGMgPSB0aGlzLl9EaWVsZWN0cmljU3BlY3VsYXIuciAtIHNwZWN1bGFyO1xyXG4gICAgICAgIGNvbnN0IEQgPSBiICogYiAtIDQuMCAqIGEgKiBjO1xyXG4gICAgICAgIHJldHVybiBTY2FsYXIuQ2xhbXAoKC1iICsgTWF0aC5zcXJ0KEQpKSAvICgyLjAgKiBhKSwgMCwgMSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHRoZSBnbFRGIGFscGhhIG1vZGUgdG8gYSBnbFRGIG1hdGVyaWFsIGZyb20gdGhlIEJhYnlsb24gTWF0ZXJpYWxcclxuICAgICAqIEBwYXJhbSBnbFRGTWF0ZXJpYWwgZ2xURiBtYXRlcmlhbFxyXG4gICAgICogQHBhcmFtIGJhYnlsb25NYXRlcmlhbCBCYWJ5bG9uIG1hdGVyaWFsXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIF9TZXRBbHBoYU1vZGUoZ2xURk1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwgJiB7IGFscGhhQ3V0T2ZmOiBudW1iZXIgfSk6IHZvaWQge1xyXG4gICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwubmVlZEFscGhhQmxlbmRpbmcoKSkge1xyXG4gICAgICAgICAgICBnbFRGTWF0ZXJpYWwuYWxwaGFNb2RlID0gTWF0ZXJpYWxBbHBoYU1vZGUuQkxFTkQ7XHJcbiAgICAgICAgfSBlbHNlIGlmIChiYWJ5bG9uTWF0ZXJpYWwubmVlZEFscGhhVGVzdGluZygpKSB7XHJcbiAgICAgICAgICAgIGdsVEZNYXRlcmlhbC5hbHBoYU1vZGUgPSBNYXRlcmlhbEFscGhhTW9kZS5NQVNLO1xyXG4gICAgICAgICAgICBnbFRGTWF0ZXJpYWwuYWxwaGFDdXRvZmYgPSBiYWJ5bG9uTWF0ZXJpYWwuYWxwaGFDdXRPZmY7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgYSBCYWJ5bG9uIFN0YW5kYXJkIE1hdGVyaWFsIHRvIGEgZ2xURiBNYXRlcmlhbFxyXG4gICAgICogQHBhcmFtIGJhYnlsb25TdGFuZGFyZE1hdGVyaWFsIEJKUyBTdGFuZGFyZCBNYXRlcmlhbFxyXG4gICAgICogQHBhcmFtIG1pbWVUeXBlIG1pbWUgdHlwZSB0byB1c2UgZm9yIHRoZSB0ZXh0dXJlc1xyXG4gICAgICogQHBhcmFtIGhhc1RleHR1cmVDb29yZHMgc3BlY2lmaWVzIGlmIHRleHR1cmUgY29vcmRpbmF0ZXMgYXJlIHByZXNlbnQgb24gdGhlIHN1Ym1lc2ggdG8gZGV0ZXJtaW5lIGlmIHRleHR1cmVzIHNob3VsZCBiZSBhcHBsaWVkXHJcbiAgICAgKiBAcmV0dXJucyBwcm9taXNlLCByZXNvbHZlZCB3aXRoIHRoZSBtYXRlcmlhbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2NvbnZlcnRTdGFuZGFyZE1hdGVyaWFsQXN5bmMoYmFieWxvblN0YW5kYXJkTWF0ZXJpYWw6IFN0YW5kYXJkTWF0ZXJpYWwsIG1pbWVUeXBlOiBJbWFnZU1pbWVUeXBlLCBoYXNUZXh0dXJlQ29vcmRzOiBib29sZWFuKTogUHJvbWlzZTxJTWF0ZXJpYWw+IHtcclxuICAgICAgICBjb25zdCBtYXRlcmlhbE1hcCA9IHRoaXMuX2V4cG9ydGVyLl9tYXRlcmlhbE1hcDtcclxuICAgICAgICBjb25zdCBtYXRlcmlhbHMgPSB0aGlzLl9leHBvcnRlci5fbWF0ZXJpYWxzO1xyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gW107XHJcbiAgICAgICAgY29uc3QgcGJyTWV0YWxsaWNSb3VnaG5lc3MgPSB0aGlzLl9jb252ZXJ0VG9HTFRGUEJSTWV0YWxsaWNSb3VnaG5lc3MoYmFieWxvblN0YW5kYXJkTWF0ZXJpYWwpO1xyXG5cclxuICAgICAgICBjb25zdCBtYXRlcmlhbDogSU1hdGVyaWFsID0geyBuYW1lOiBiYWJ5bG9uU3RhbmRhcmRNYXRlcmlhbC5uYW1lIH07XHJcbiAgICAgICAgaWYgKGJhYnlsb25TdGFuZGFyZE1hdGVyaWFsLmJhY2tGYWNlQ3VsbGluZyAhPSBudWxsICYmICFiYWJ5bG9uU3RhbmRhcmRNYXRlcmlhbC5iYWNrRmFjZUN1bGxpbmcpIHtcclxuICAgICAgICAgICAgaWYgKCFiYWJ5bG9uU3RhbmRhcmRNYXRlcmlhbC50d29TaWRlZExpZ2h0aW5nKSB7XHJcbiAgICAgICAgICAgICAgICBUb29scy5XYXJuKGJhYnlsb25TdGFuZGFyZE1hdGVyaWFsLm5hbWUgKyBcIjogQmFjay1mYWNlIGN1bGxpbmcgZGlzYWJsZWQgYW5kIHR3by1zaWRlZCBsaWdodGluZyBkaXNhYmxlZCBpcyBub3Qgc3VwcG9ydGVkIGluIGdsVEYuXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG1hdGVyaWFsLmRvdWJsZVNpZGVkID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGhhc1RleHR1cmVDb29yZHMpIHtcclxuICAgICAgICAgICAgaWYgKGJhYnlsb25TdGFuZGFyZE1hdGVyaWFsLmRpZmZ1c2VUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V4cG9ydFRleHR1cmVBc3luYyhiYWJ5bG9uU3RhbmRhcmRNYXRlcmlhbC5kaWZmdXNlVGV4dHVyZSwgbWltZVR5cGUpLnRoZW4oKHRleHR1cmVJbmZvKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0dXJlSW5mbykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGJyTWV0YWxsaWNSb3VnaG5lc3MuYmFzZUNvbG9yVGV4dHVyZSA9IHRleHR1cmVJbmZvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgYnVtcFRleHR1cmUgPSBiYWJ5bG9uU3RhbmRhcmRNYXRlcmlhbC5idW1wVGV4dHVyZTtcclxuICAgICAgICAgICAgaWYgKGJ1bXBUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V4cG9ydFRleHR1cmVBc3luYyhidW1wVGV4dHVyZSwgbWltZVR5cGUpLnRoZW4oKHRleHR1cmVJbmZvKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0dXJlSW5mbykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0ZXJpYWwubm9ybWFsVGV4dHVyZSA9IHRleHR1cmVJbmZvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJ1bXBUZXh0dXJlLmxldmVsICE9PSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0ZXJpYWwubm9ybWFsVGV4dHVyZS5zY2FsZSA9IGJ1bXBUZXh0dXJlLmxldmVsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGJhYnlsb25TdGFuZGFyZE1hdGVyaWFsLmVtaXNzaXZlVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgbWF0ZXJpYWwuZW1pc3NpdmVGYWN0b3IgPSBbMS4wLCAxLjAsIDEuMF07XHJcblxyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9leHBvcnRUZXh0dXJlQXN5bmMoYmFieWxvblN0YW5kYXJkTWF0ZXJpYWwuZW1pc3NpdmVUZXh0dXJlLCBtaW1lVHlwZSkudGhlbigodGV4dHVyZUluZm8pID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRleHR1cmVJbmZvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRlcmlhbC5lbWlzc2l2ZVRleHR1cmUgPSB0ZXh0dXJlSW5mbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChiYWJ5bG9uU3RhbmRhcmRNYXRlcmlhbC5hbWJpZW50VGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9leHBvcnRUZXh0dXJlQXN5bmMoYmFieWxvblN0YW5kYXJkTWF0ZXJpYWwuYW1iaWVudFRleHR1cmUsIG1pbWVUeXBlKS50aGVuKCh0ZXh0dXJlSW5mbykgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGV4dHVyZUluZm8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9jY2x1c2lvblRleHR1cmU6IElNYXRlcmlhbE9jY2x1c2lvblRleHR1cmVJbmZvID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4OiB0ZXh0dXJlSW5mby5pbmRleCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRlcmlhbC5vY2NsdXNpb25UZXh0dXJlID0gb2NjbHVzaW9uVGV4dHVyZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoYmFieWxvblN0YW5kYXJkTWF0ZXJpYWwuYWxwaGEgPCAxLjAgfHwgYmFieWxvblN0YW5kYXJkTWF0ZXJpYWwub3BhY2l0eVRleHR1cmUpIHtcclxuICAgICAgICAgICAgaWYgKGJhYnlsb25TdGFuZGFyZE1hdGVyaWFsLmFscGhhTW9kZSA9PT0gQ29uc3RhbnRzLkFMUEhBX0NPTUJJTkUpIHtcclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsLmFscGhhTW9kZSA9IE1hdGVyaWFsQWxwaGFNb2RlLkJMRU5EO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgVG9vbHMuV2FybihiYWJ5bG9uU3RhbmRhcmRNYXRlcmlhbC5uYW1lICsgXCI6IGdsVEYgMi4wIGRvZXMgbm90IHN1cHBvcnQgYWxwaGEgbW9kZTogXCIgKyBiYWJ5bG9uU3RhbmRhcmRNYXRlcmlhbC5hbHBoYU1vZGUudG9TdHJpbmcoKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJhYnlsb25TdGFuZGFyZE1hdGVyaWFsLmVtaXNzaXZlQ29sb3IgJiYgIV9HTFRGTWF0ZXJpYWxFeHBvcnRlci5fRnV6enlFcXVhbHMoYmFieWxvblN0YW5kYXJkTWF0ZXJpYWwuZW1pc3NpdmVDb2xvciwgQ29sb3IzLkJsYWNrKCksIF9HTFRGTWF0ZXJpYWxFeHBvcnRlci5fRXBzaWxvbikpIHtcclxuICAgICAgICAgICAgbWF0ZXJpYWwuZW1pc3NpdmVGYWN0b3IgPSBiYWJ5bG9uU3RhbmRhcmRNYXRlcmlhbC5lbWlzc2l2ZUNvbG9yLmFzQXJyYXkoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG1hdGVyaWFsLnBick1ldGFsbGljUm91Z2huZXNzID0gcGJyTWV0YWxsaWNSb3VnaG5lc3M7XHJcbiAgICAgICAgX0dMVEZNYXRlcmlhbEV4cG9ydGVyLl9TZXRBbHBoYU1vZGUobWF0ZXJpYWwsIGJhYnlsb25TdGFuZGFyZE1hdGVyaWFsKTtcclxuXHJcbiAgICAgICAgbWF0ZXJpYWxzLnB1c2gobWF0ZXJpYWwpO1xyXG4gICAgICAgIG1hdGVyaWFsTWFwW2JhYnlsb25TdGFuZGFyZE1hdGVyaWFsLnVuaXF1ZUlkXSA9IG1hdGVyaWFscy5sZW5ndGggLSAxO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fZmluaXNoTWF0ZXJpYWwocHJvbWlzZXMsIG1hdGVyaWFsLCBiYWJ5bG9uU3RhbmRhcmRNYXRlcmlhbCwgbWltZVR5cGUpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2ZpbmlzaE1hdGVyaWFsPFQ+KHByb21pc2VzOiBQcm9taXNlPFQ+W10sIGdsVEZNYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsLCBtaW1lVHlwZTogSW1hZ2VNaW1lVHlwZSkge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRleHR1cmVzID0gdGhpcy5fZXhwb3J0ZXIuX2V4dGVuc2lvbnNQb3N0RXhwb3J0TWF0ZXJpYWxBZGRpdGlvbmFsVGV4dHVyZXMoXCJleHBvcnRNYXRlcmlhbFwiLCBnbFRGTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCk7XHJcbiAgICAgICAgICAgIGxldCB0YXNrczogTnVsbGFibGU8UHJvbWlzZTxOdWxsYWJsZTxJVGV4dHVyZUluZm8+PltdPiA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRleHR1cmUgb2YgdGV4dHVyZXMpIHtcclxuICAgICAgICAgICAgICAgIGlmICghdGFza3MpIHtcclxuICAgICAgICAgICAgICAgICAgICB0YXNrcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGFza3MucHVzaCh0aGlzLl9leHBvcnRUZXh0dXJlQXN5bmModGV4dHVyZSwgbWltZVR5cGUpKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCF0YXNrcykge1xyXG4gICAgICAgICAgICAgICAgdGFza3MgPSBbUHJvbWlzZS5yZXNvbHZlKG51bGwpXTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHRhc2tzKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbldvcmsgPSB0aGlzLl9leHBvcnRlci5fZXh0ZW5zaW9uc1Bvc3RFeHBvcnRNYXRlcmlhbEFzeW5jKFwiZXhwb3J0TWF0ZXJpYWxcIiwgZ2xURk1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFleHRlbnNpb25Xb3JrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdsVEZNYXRlcmlhbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBleHRlbnNpb25Xb3JrLnRoZW4oKCkgPT4gZ2xURk1hdGVyaWFsKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0cyBhbiBpbWFnZSB0eXBlZCBhcnJheSBidWZmZXIgdG8gYSBiYXNlNjQgaW1hZ2VcclxuICAgICAqIEBwYXJhbSBidWZmZXIgdHlwZWQgYXJyYXkgYnVmZmVyXHJcbiAgICAgKiBAcGFyYW0gd2lkdGggd2lkdGggb2YgdGhlIGltYWdlXHJcbiAgICAgKiBAcGFyYW0gaGVpZ2h0IGhlaWdodCBvZiB0aGUgaW1hZ2VcclxuICAgICAqIEBwYXJhbSBtaW1lVHlwZSBtaW1ldHlwZSBvZiB0aGUgaW1hZ2VcclxuICAgICAqIEByZXR1cm5zIGJhc2U2NCBpbWFnZSBzdHJpbmdcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBhc3luYyBfZ2V0SW1hZ2VEYXRhQXN5bmMoYnVmZmVyOiBVaW50OEFycmF5IHwgRmxvYXQzMkFycmF5LCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgbWltZVR5cGU6IEltYWdlTWltZVR5cGUpOiBQcm9taXNlPEFycmF5QnVmZmVyPiB7XHJcbiAgICAgICAgY29uc3QgdGV4dHVyZVR5cGUgPSBDb25zdGFudHMuVEVYVFVSRVRZUEVfVU5TSUdORURfSU5UO1xyXG5cclxuICAgICAgICBjb25zdCBob3N0aW5nU2NlbmUgPSB0aGlzLl9leHBvcnRlci5fYmFieWxvblNjZW5lO1xyXG4gICAgICAgIGNvbnN0IGVuZ2luZSA9IGhvc3RpbmdTY2VuZS5nZXRFbmdpbmUoKTtcclxuXHJcbiAgICAgICAgLy8gQ3JlYXRlIGEgdGVtcG9yYXJ5IHRleHR1cmUgd2l0aCB0aGUgdGV4dHVyZSBidWZmZXIgZGF0YVxyXG4gICAgICAgIGNvbnN0IHRlbXBUZXh0dXJlID0gZW5naW5lLmNyZWF0ZVJhd1RleHR1cmUoYnVmZmVyLCB3aWR0aCwgaGVpZ2h0LCBDb25zdGFudHMuVEVYVFVSRUZPUk1BVF9SR0JBLCBmYWxzZSwgdHJ1ZSwgVGV4dHVyZS5ORUFSRVNUX1NBTVBMSU5HTU9ERSwgbnVsbCwgdGV4dHVyZVR5cGUpO1xyXG5cclxuICAgICAgICBhd2FpdCBUZXh0dXJlVG9vbHMuQXBwbHlQb3N0UHJvY2VzcyhcInBhc3NcIiwgdGVtcFRleHR1cmUsIGhvc3RpbmdTY2VuZSwgdGV4dHVyZVR5cGUsIENvbnN0YW50cy5URVhUVVJFX05FQVJFU1RfU0FNUExJTkdNT0RFLCBDb25zdGFudHMuVEVYVFVSRUZPUk1BVF9SR0JBKTtcclxuXHJcbiAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IGVuZ2luZS5fcmVhZFRleHR1cmVQaXhlbHModGVtcFRleHR1cmUsIHdpZHRoLCBoZWlnaHQpO1xyXG5cclxuICAgICAgICByZXR1cm4gKGF3YWl0IER1bXBUb29scy5EdW1wRGF0YUFzeW5jKHdpZHRoLCBoZWlnaHQsIGRhdGEsIG1pbWVUeXBlLCB1bmRlZmluZWQsIHRydWUsIHRydWUpKSBhcyBBcnJheUJ1ZmZlcjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdlbmVyYXRlcyBhIHdoaXRlIHRleHR1cmUgYmFzZWQgb24gdGhlIHNwZWNpZmllZCB3aWR0aCBhbmQgaGVpZ2h0XHJcbiAgICAgKiBAcGFyYW0gd2lkdGggd2lkdGggb2YgdGhlIHRleHR1cmUgaW4gcGl4ZWxzXHJcbiAgICAgKiBAcGFyYW0gaGVpZ2h0IGhlaWdodCBvZiB0aGUgdGV4dHVyZSBpbiBwaXhlbHNcclxuICAgICAqIEBwYXJhbSBzY2VuZSBiYWJ5bG9uanMgc2NlbmVcclxuICAgICAqIEByZXR1cm5zIHdoaXRlIHRleHR1cmVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfY3JlYXRlV2hpdGVUZXh0dXJlKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBzY2VuZTogU2NlbmUpOiBUZXh0dXJlIHtcclxuICAgICAgICBjb25zdCBkYXRhID0gbmV3IFVpbnQ4QXJyYXkod2lkdGggKiBoZWlnaHQgKiA0KTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSA9IGkgKyA0KSB7XHJcbiAgICAgICAgICAgIGRhdGFbaV0gPSBkYXRhW2kgKyAxXSA9IGRhdGFbaSArIDJdID0gZGF0YVtpICsgM10gPSAweGZmO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcmF3VGV4dHVyZSA9IFJhd1RleHR1cmUuQ3JlYXRlUkdCQVRleHR1cmUoZGF0YSwgd2lkdGgsIGhlaWdodCwgc2NlbmUpO1xyXG5cclxuICAgICAgICByZXR1cm4gcmF3VGV4dHVyZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlc2l6ZXMgdGhlIHR3byBzb3VyY2UgdGV4dHVyZXMgdG8gdGhlIHNhbWUgZGltZW5zaW9ucy4gIElmIGEgdGV4dHVyZSBpcyBudWxsLCBhIGRlZmF1bHQgd2hpdGUgdGV4dHVyZSBpcyBnZW5lcmF0ZWQuICBJZiBib3RoIHRleHR1cmVzIGFyZSBudWxsLCByZXR1cm5zIG51bGxcclxuICAgICAqIEBwYXJhbSB0ZXh0dXJlMSBmaXJzdCB0ZXh0dXJlIHRvIHJlc2l6ZVxyXG4gICAgICogQHBhcmFtIHRleHR1cmUyIHNlY29uZCB0ZXh0dXJlIHRvIHJlc2l6ZVxyXG4gICAgICogQHBhcmFtIHNjZW5lIGJhYnlsb25qcyBzY2VuZVxyXG4gICAgICogQHJldHVybnMgcmVzaXplZCB0ZXh0dXJlcyBvciBudWxsXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX3Jlc2l6ZVRleHR1cmVzVG9TYW1lRGltZW5zaW9ucyh0ZXh0dXJlMTogTnVsbGFibGU8QmFzZVRleHR1cmU+LCB0ZXh0dXJlMjogTnVsbGFibGU8QmFzZVRleHR1cmU+LCBzY2VuZTogU2NlbmUpOiB7IHRleHR1cmUxOiBCYXNlVGV4dHVyZTsgdGV4dHVyZTI6IEJhc2VUZXh0dXJlIH0ge1xyXG4gICAgICAgIGNvbnN0IHRleHR1cmUxU2l6ZSA9IHRleHR1cmUxID8gdGV4dHVyZTEuZ2V0U2l6ZSgpIDogeyB3aWR0aDogMCwgaGVpZ2h0OiAwIH07XHJcbiAgICAgICAgY29uc3QgdGV4dHVyZTJTaXplID0gdGV4dHVyZTIgPyB0ZXh0dXJlMi5nZXRTaXplKCkgOiB7IHdpZHRoOiAwLCBoZWlnaHQ6IDAgfTtcclxuICAgICAgICBsZXQgcmVzaXplZFRleHR1cmUxOiBCYXNlVGV4dHVyZTtcclxuICAgICAgICBsZXQgcmVzaXplZFRleHR1cmUyOiBCYXNlVGV4dHVyZTtcclxuXHJcbiAgICAgICAgaWYgKHRleHR1cmUxU2l6ZS53aWR0aCA8IHRleHR1cmUyU2l6ZS53aWR0aCkge1xyXG4gICAgICAgICAgICBpZiAodGV4dHVyZTEgJiYgdGV4dHVyZTEgaW5zdGFuY2VvZiBUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICByZXNpemVkVGV4dHVyZTEgPSBUZXh0dXJlVG9vbHMuQ3JlYXRlUmVzaXplZENvcHkodGV4dHVyZTEsIHRleHR1cmUyU2l6ZS53aWR0aCwgdGV4dHVyZTJTaXplLmhlaWdodCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXNpemVkVGV4dHVyZTEgPSB0aGlzLl9jcmVhdGVXaGl0ZVRleHR1cmUodGV4dHVyZTJTaXplLndpZHRoLCB0ZXh0dXJlMlNpemUuaGVpZ2h0LCBzY2VuZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmVzaXplZFRleHR1cmUyID0gdGV4dHVyZTIhO1xyXG4gICAgICAgIH0gZWxzZSBpZiAodGV4dHVyZTFTaXplLndpZHRoID4gdGV4dHVyZTJTaXplLndpZHRoKSB7XHJcbiAgICAgICAgICAgIGlmICh0ZXh0dXJlMiAmJiB0ZXh0dXJlMiBpbnN0YW5jZW9mIFRleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgIHJlc2l6ZWRUZXh0dXJlMiA9IFRleHR1cmVUb29scy5DcmVhdGVSZXNpemVkQ29weSh0ZXh0dXJlMiwgdGV4dHVyZTFTaXplLndpZHRoLCB0ZXh0dXJlMVNpemUuaGVpZ2h0LCB0cnVlKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJlc2l6ZWRUZXh0dXJlMiA9IHRoaXMuX2NyZWF0ZVdoaXRlVGV4dHVyZSh0ZXh0dXJlMVNpemUud2lkdGgsIHRleHR1cmUxU2l6ZS5oZWlnaHQsIHNjZW5lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXNpemVkVGV4dHVyZTEgPSB0ZXh0dXJlMSE7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmVzaXplZFRleHR1cmUxID0gdGV4dHVyZTEhO1xyXG4gICAgICAgICAgICByZXNpemVkVGV4dHVyZTIgPSB0ZXh0dXJlMiE7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB0ZXh0dXJlMTogcmVzaXplZFRleHR1cmUxISxcclxuICAgICAgICAgICAgdGV4dHVyZTI6IHJlc2l6ZWRUZXh0dXJlMiEsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIGFuIGFycmF5IG9mIHBpeGVscyB0byBhIEZsb2F0MzJBcnJheVxyXG4gICAgICogVGhyb3dzIGFuIGVycm9yIGlmIHRoZSBwaXhlbCBmb3JtYXQgaXMgbm90IHN1cHBvcnRlZFxyXG4gICAgICogQHBhcmFtIHBpeGVscyAtIGFycmF5IGJ1ZmZlciBjb250YWluaW5nIHBpeGVsIHZhbHVlc1xyXG4gICAgICogQHJldHVybnMgRmxvYXQzMiBvZiBwaXhlbHNcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfY29udmVydFBpeGVsQXJyYXlUb0Zsb2F0MzIocGl4ZWxzOiBBcnJheUJ1ZmZlclZpZXcpOiBGbG9hdDMyQXJyYXkge1xyXG4gICAgICAgIGlmIChwaXhlbHMgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IHBpeGVscy5sZW5ndGg7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkocGl4ZWxzLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcclxuICAgICAgICAgICAgICAgIGJ1ZmZlcltpXSA9IHBpeGVsc1tpXSAvIDI1NTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gYnVmZmVyO1xyXG4gICAgICAgIH0gZWxzZSBpZiAocGl4ZWxzIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBwaXhlbHM7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgcGl4ZWwgZm9ybWF0IVwiKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0IFNwZWN1bGFyIEdsb3NzaW5lc3MgVGV4dHVyZXMgdG8gTWV0YWxsaWMgUm91Z2huZXNzXHJcbiAgICAgKiBTZWUgbGluayBiZWxvdyBmb3IgaW5mbyBvbiB0aGUgbWF0ZXJpYWwgY29udmVyc2lvbnMgZnJvbSBQQlIgTWV0YWxsaWMvUm91Z2huZXNzIGFuZCBTcGVjdWxhci9HbG9zc2luZXNzXHJcbiAgICAgKiBAbGluayBodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0FyY2hpdmVkL0tIUl9tYXRlcmlhbHNfcGJyU3BlY3VsYXJHbG9zc2luZXNzL2V4YW1wbGVzL2NvbnZlcnQtYmV0d2Vlbi13b3JrZmxvd3MtYmpzL2pzL2JhYnlsb24ucGJyVXRpbGl0aWVzLmpzXHJcbiAgICAgKiBAcGFyYW0gZGlmZnVzZVRleHR1cmUgdGV4dHVyZSB1c2VkIHRvIHN0b3JlIGRpZmZ1c2UgaW5mb3JtYXRpb25cclxuICAgICAqIEBwYXJhbSBzcGVjdWxhckdsb3NzaW5lc3NUZXh0dXJlIHRleHR1cmUgdXNlZCB0byBzdG9yZSBzcGVjdWxhciBhbmQgZ2xvc3NpbmVzcyBpbmZvcm1hdGlvblxyXG4gICAgICogQHBhcmFtIGZhY3RvcnMgc3BlY3VsYXIgZ2xvc3NpbmVzcyBtYXRlcmlhbCBmYWN0b3JzXHJcbiAgICAgKiBAcGFyYW0gbWltZVR5cGUgdGhlIG1pbWUgdHlwZSB0byB1c2UgZm9yIHRoZSB0ZXh0dXJlXHJcbiAgICAgKiBAcmV0dXJucyBwYnIgbWV0YWxsaWMgcm91Z2huZXNzIGludGVyZmFjZSBvciBudWxsXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgYXN5bmMgX2NvbnZlcnRTcGVjdWxhckdsb3NzaW5lc3NUZXh0dXJlc1RvTWV0YWxsaWNSb3VnaG5lc3NBc3luYyhcclxuICAgICAgICBkaWZmdXNlVGV4dHVyZTogTnVsbGFibGU8QmFzZVRleHR1cmU+LFxyXG4gICAgICAgIHNwZWN1bGFyR2xvc3NpbmVzc1RleHR1cmU6IE51bGxhYmxlPEJhc2VUZXh0dXJlPixcclxuICAgICAgICBmYWN0b3JzOiBfSVBCUlNwZWN1bGFyR2xvc3NpbmVzcyxcclxuICAgICAgICBtaW1lVHlwZTogSW1hZ2VNaW1lVHlwZVxyXG4gICAgKTogUHJvbWlzZTxfSVBCUk1ldGFsbGljUm91Z2huZXNzPiB7XHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTx2b2lkPj4oKTtcclxuICAgICAgICBpZiAoIShkaWZmdXNlVGV4dHVyZSB8fCBzcGVjdWxhckdsb3NzaW5lc3NUZXh0dXJlKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJfQ29udmVydFNwZWN1bGFyR2xvc2luZXNzVGV4dHVyZXNUb01ldGFsbGljUm91Z2huZXNzOiBkaWZmdXNlIGFuZCBzcGVjdWxhciBnbG9zc2luZXNzIHRleHR1cmVzIGFyZSBub3QgZGVmaW5lZCFcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBzY2VuZTogTnVsbGFibGU8U2NlbmU+ID0gZGlmZnVzZVRleHR1cmUgPyBkaWZmdXNlVGV4dHVyZS5nZXRTY2VuZSgpIDogc3BlY3VsYXJHbG9zc2luZXNzVGV4dHVyZSA/IHNwZWN1bGFyR2xvc3NpbmVzc1RleHR1cmUuZ2V0U2NlbmUoKSA6IG51bGw7XHJcbiAgICAgICAgaWYgKHNjZW5lKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlc2l6ZWRUZXh0dXJlcyA9IHRoaXMuX3Jlc2l6ZVRleHR1cmVzVG9TYW1lRGltZW5zaW9ucyhkaWZmdXNlVGV4dHVyZSwgc3BlY3VsYXJHbG9zc2luZXNzVGV4dHVyZSwgc2NlbmUpO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgZGlmZnVzZVNpemUgPSByZXNpemVkVGV4dHVyZXMudGV4dHVyZTE/LmdldFNpemUoKTtcclxuXHJcbiAgICAgICAgICAgIGxldCBkaWZmdXNlQnVmZmVyOiBGbG9hdDMyQXJyYXk7XHJcbiAgICAgICAgICAgIGxldCBzcGVjdWxhckdsb3NzaW5lc3NCdWZmZXI6IEZsb2F0MzJBcnJheTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHdpZHRoID0gZGlmZnVzZVNpemUud2lkdGg7XHJcbiAgICAgICAgICAgIGNvbnN0IGhlaWdodCA9IGRpZmZ1c2VTaXplLmhlaWdodDtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGRpZmZ1c2VQaXhlbHMgPSBhd2FpdCByZXNpemVkVGV4dHVyZXMudGV4dHVyZTEucmVhZFBpeGVscygpO1xyXG4gICAgICAgICAgICBjb25zdCBzcGVjdWxhclBpeGVscyA9IGF3YWl0IHJlc2l6ZWRUZXh0dXJlcy50ZXh0dXJlMi5yZWFkUGl4ZWxzKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoZGlmZnVzZVBpeGVscykge1xyXG4gICAgICAgICAgICAgICAgZGlmZnVzZUJ1ZmZlciA9IHRoaXMuX2NvbnZlcnRQaXhlbEFycmF5VG9GbG9hdDMyKGRpZmZ1c2VQaXhlbHMpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFwiRmFpbGVkIHRvIHJldHJpZXZlIHBpeGVscyBmcm9tIGRpZmZ1c2UgdGV4dHVyZSFcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHNwZWN1bGFyUGl4ZWxzKSB7XHJcbiAgICAgICAgICAgICAgICBzcGVjdWxhckdsb3NzaW5lc3NCdWZmZXIgPSB0aGlzLl9jb252ZXJ0UGl4ZWxBcnJheVRvRmxvYXQzMihzcGVjdWxhclBpeGVscyk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJGYWlsZWQgdG8gcmV0cmlldmUgcGl4ZWxzIGZyb20gc3BlY3VsYXIgZ2xvc3NpbmVzcyB0ZXh0dXJlIVwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgYnl0ZUxlbmd0aCA9IHNwZWN1bGFyR2xvc3NpbmVzc0J1ZmZlci5ieXRlTGVuZ3RoO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgbWV0YWxsaWNSb3VnaG5lc3NCdWZmZXIgPSBuZXcgVWludDhBcnJheShieXRlTGVuZ3RoKTtcclxuICAgICAgICAgICAgY29uc3QgYmFzZUNvbG9yQnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoYnl0ZUxlbmd0aCk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBzdHJpZGVTaXplID0gNDtcclxuICAgICAgICAgICAgY29uc3QgbWF4QmFzZUNvbG9yID0gQ29sb3IzLkJsYWNrKCk7XHJcbiAgICAgICAgICAgIGxldCBtYXhNZXRhbGxpYyA9IDA7XHJcbiAgICAgICAgICAgIGxldCBtYXhSb3VnaG5lc3MgPSAwO1xyXG5cclxuICAgICAgICAgICAgZm9yIChsZXQgaCA9IDA7IGggPCBoZWlnaHQ7ICsraCkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgdyA9IDA7IHcgPCB3aWR0aDsgKyt3KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gKHdpZHRoICogaCArIHcpICogc3RyaWRlU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGlmZnVzZUNvbG9yID0gbmV3IENvbG9yMyhkaWZmdXNlQnVmZmVyW29mZnNldF0sIGRpZmZ1c2VCdWZmZXJbb2Zmc2V0ICsgMV0sIGRpZmZ1c2VCdWZmZXJbb2Zmc2V0ICsgMl0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC50b0xpbmVhclNwYWNlKHNjZW5lLmdldEVuZ2luZSgpLnVzZUV4YWN0U3JnYkNvbnZlcnNpb25zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAubXVsdGlwbHkoZmFjdG9ycy5kaWZmdXNlQ29sb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwZWN1bGFyQ29sb3IgPSBuZXcgQ29sb3IzKHNwZWN1bGFyR2xvc3NpbmVzc0J1ZmZlcltvZmZzZXRdLCBzcGVjdWxhckdsb3NzaW5lc3NCdWZmZXJbb2Zmc2V0ICsgMV0sIHNwZWN1bGFyR2xvc3NpbmVzc0J1ZmZlcltvZmZzZXQgKyAyXSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgLnRvTGluZWFyU3BhY2Uoc2NlbmUuZ2V0RW5naW5lKCkudXNlRXhhY3RTcmdiQ29udmVyc2lvbnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5tdWx0aXBseShmYWN0b3JzLnNwZWN1bGFyQ29sb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGdsb3NzaW5lc3MgPSBzcGVjdWxhckdsb3NzaW5lc3NCdWZmZXJbb2Zmc2V0ICsgM10gKiBmYWN0b3JzLmdsb3NzaW5lc3M7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwZWN1bGFyR2xvc3NpbmVzczogX0lQQlJTcGVjdWxhckdsb3NzaW5lc3MgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZ1c2VDb2xvcjogZGlmZnVzZUNvbG9yLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzcGVjdWxhckNvbG9yOiBzcGVjdWxhckNvbG9yLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBnbG9zc2luZXNzOiBnbG9zc2luZXNzLFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1ldGFsbGljUm91Z2huZXNzID0gdGhpcy5fY29udmVydFNwZWN1bGFyR2xvc3NpbmVzc1RvTWV0YWxsaWNSb3VnaG5lc3Moc3BlY3VsYXJHbG9zc2luZXNzKTtcclxuICAgICAgICAgICAgICAgICAgICBtYXhCYXNlQ29sb3IuciA9IE1hdGgubWF4KG1heEJhc2VDb2xvci5yLCBtZXRhbGxpY1JvdWdobmVzcy5iYXNlQ29sb3Iucik7XHJcbiAgICAgICAgICAgICAgICAgICAgbWF4QmFzZUNvbG9yLmcgPSBNYXRoLm1heChtYXhCYXNlQ29sb3IuZywgbWV0YWxsaWNSb3VnaG5lc3MuYmFzZUNvbG9yLmcpO1xyXG4gICAgICAgICAgICAgICAgICAgIG1heEJhc2VDb2xvci5iID0gTWF0aC5tYXgobWF4QmFzZUNvbG9yLmIsIG1ldGFsbGljUm91Z2huZXNzLmJhc2VDb2xvci5iKTtcclxuICAgICAgICAgICAgICAgICAgICBtYXhNZXRhbGxpYyA9IE1hdGgubWF4KG1heE1ldGFsbGljLCBtZXRhbGxpY1JvdWdobmVzcy5tZXRhbGxpYyEpO1xyXG4gICAgICAgICAgICAgICAgICAgIG1heFJvdWdobmVzcyA9IE1hdGgubWF4KG1heFJvdWdobmVzcywgbWV0YWxsaWNSb3VnaG5lc3Mucm91Z2huZXNzISk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGJhc2VDb2xvckJ1ZmZlcltvZmZzZXRdID0gbWV0YWxsaWNSb3VnaG5lc3MuYmFzZUNvbG9yLnIgKiAyNTU7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFzZUNvbG9yQnVmZmVyW29mZnNldCArIDFdID0gbWV0YWxsaWNSb3VnaG5lc3MuYmFzZUNvbG9yLmcgKiAyNTU7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFzZUNvbG9yQnVmZmVyW29mZnNldCArIDJdID0gbWV0YWxsaWNSb3VnaG5lc3MuYmFzZUNvbG9yLmIgKiAyNTU7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFzZUNvbG9yQnVmZmVyW29mZnNldCArIDNdID0gcmVzaXplZFRleHR1cmVzLnRleHR1cmUxLmhhc0FscGhhID8gZGlmZnVzZUJ1ZmZlcltvZmZzZXQgKyAzXSAqIDI1NSA6IDI1NTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbWV0YWxsaWNSb3VnaG5lc3NCdWZmZXJbb2Zmc2V0XSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgbWV0YWxsaWNSb3VnaG5lc3NCdWZmZXJbb2Zmc2V0ICsgMV0gPSBtZXRhbGxpY1JvdWdobmVzcy5yb3VnaG5lc3MhICogMjU1O1xyXG4gICAgICAgICAgICAgICAgICAgIG1ldGFsbGljUm91Z2huZXNzQnVmZmVyW29mZnNldCArIDJdID0gbWV0YWxsaWNSb3VnaG5lc3MubWV0YWxsaWMhICogMjU1O1xyXG4gICAgICAgICAgICAgICAgICAgIG1ldGFsbGljUm91Z2huZXNzQnVmZmVyW29mZnNldCArIDNdID0gMjU1O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBSZXRyaWV2ZXMgdGhlIG1ldGFsbGljIHJvdWdobmVzcyBmYWN0b3JzIGZyb20gdGhlIG1heGltdW0gdGV4dHVyZSB2YWx1ZXMuXHJcbiAgICAgICAgICAgIGNvbnN0IG1ldGFsbGljUm91Z2huZXNzRmFjdG9yczogX0lQQlJNZXRhbGxpY1JvdWdobmVzcyA9IHtcclxuICAgICAgICAgICAgICAgIGJhc2VDb2xvcjogbWF4QmFzZUNvbG9yLFxyXG4gICAgICAgICAgICAgICAgbWV0YWxsaWM6IG1heE1ldGFsbGljLFxyXG4gICAgICAgICAgICAgICAgcm91Z2huZXNzOiBtYXhSb3VnaG5lc3MsXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBsZXQgd3JpdGVPdXRNZXRhbGxpY1JvdWdobmVzc1RleHR1cmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgbGV0IHdyaXRlT3V0QmFzZUNvbG9yVGV4dHVyZSA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgZm9yIChsZXQgaCA9IDA7IGggPCBoZWlnaHQ7ICsraCkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgdyA9IDA7IHcgPCB3aWR0aDsgKyt3KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVzdGluYXRpb25PZmZzZXQgPSAod2lkdGggKiBoICsgdykgKiBzdHJpZGVTaXplO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBiYXNlQ29sb3JCdWZmZXJbZGVzdGluYXRpb25PZmZzZXRdIC89IG1ldGFsbGljUm91Z2huZXNzRmFjdG9ycy5iYXNlQ29sb3IuciA+IF9HTFRGTWF0ZXJpYWxFeHBvcnRlci5fRXBzaWxvbiA/IG1ldGFsbGljUm91Z2huZXNzRmFjdG9ycy5iYXNlQ29sb3IuciA6IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFzZUNvbG9yQnVmZmVyW2Rlc3RpbmF0aW9uT2Zmc2V0ICsgMV0gLz0gbWV0YWxsaWNSb3VnaG5lc3NGYWN0b3JzLmJhc2VDb2xvci5nID4gX0dMVEZNYXRlcmlhbEV4cG9ydGVyLl9FcHNpbG9uID8gbWV0YWxsaWNSb3VnaG5lc3NGYWN0b3JzLmJhc2VDb2xvci5nIDogMTtcclxuICAgICAgICAgICAgICAgICAgICBiYXNlQ29sb3JCdWZmZXJbZGVzdGluYXRpb25PZmZzZXQgKyAyXSAvPSBtZXRhbGxpY1JvdWdobmVzc0ZhY3RvcnMuYmFzZUNvbG9yLmIgPiBfR0xURk1hdGVyaWFsRXhwb3J0ZXIuX0Vwc2lsb24gPyBtZXRhbGxpY1JvdWdobmVzc0ZhY3RvcnMuYmFzZUNvbG9yLmIgOiAxO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBsaW5lYXJCYXNlQ29sb3JQaXhlbCA9IENvbG9yMy5Gcm9tSW50cyhcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFzZUNvbG9yQnVmZmVyW2Rlc3RpbmF0aW9uT2Zmc2V0XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFzZUNvbG9yQnVmZmVyW2Rlc3RpbmF0aW9uT2Zmc2V0ICsgMV0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VDb2xvckJ1ZmZlcltkZXN0aW5hdGlvbk9mZnNldCArIDJdXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzUkdCQmFzZUNvbG9yUGl4ZWwgPSBsaW5lYXJCYXNlQ29sb3JQaXhlbC50b0dhbW1hU3BhY2Uoc2NlbmUuZ2V0RW5naW5lKCkudXNlRXhhY3RTcmdiQ29udmVyc2lvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhc2VDb2xvckJ1ZmZlcltkZXN0aW5hdGlvbk9mZnNldF0gPSBzUkdCQmFzZUNvbG9yUGl4ZWwuciAqIDI1NTtcclxuICAgICAgICAgICAgICAgICAgICBiYXNlQ29sb3JCdWZmZXJbZGVzdGluYXRpb25PZmZzZXQgKyAxXSA9IHNSR0JCYXNlQ29sb3JQaXhlbC5nICogMjU1O1xyXG4gICAgICAgICAgICAgICAgICAgIGJhc2VDb2xvckJ1ZmZlcltkZXN0aW5hdGlvbk9mZnNldCArIDJdID0gc1JHQkJhc2VDb2xvclBpeGVsLmIgKiAyNTU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghX0dMVEZNYXRlcmlhbEV4cG9ydGVyLl9GdXp6eUVxdWFscyhzUkdCQmFzZUNvbG9yUGl4ZWwsIENvbG9yMy5XaGl0ZSgpLCBfR0xURk1hdGVyaWFsRXhwb3J0ZXIuX0Vwc2lsb24pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlT3V0QmFzZUNvbG9yVGV4dHVyZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBtZXRhbGxpY1JvdWdobmVzc0J1ZmZlcltkZXN0aW5hdGlvbk9mZnNldCArIDFdIC89XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFsbGljUm91Z2huZXNzRmFjdG9ycy5yb3VnaG5lc3MhID4gX0dMVEZNYXRlcmlhbEV4cG9ydGVyLl9FcHNpbG9uID8gbWV0YWxsaWNSb3VnaG5lc3NGYWN0b3JzLnJvdWdobmVzcyEgOiAxO1xyXG4gICAgICAgICAgICAgICAgICAgIG1ldGFsbGljUm91Z2huZXNzQnVmZmVyW2Rlc3RpbmF0aW9uT2Zmc2V0ICsgMl0gLz0gbWV0YWxsaWNSb3VnaG5lc3NGYWN0b3JzLm1ldGFsbGljISA+IF9HTFRGTWF0ZXJpYWxFeHBvcnRlci5fRXBzaWxvbiA/IG1ldGFsbGljUm91Z2huZXNzRmFjdG9ycy5tZXRhbGxpYyEgOiAxO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXRhbGxpY1JvdWdobmVzc1BpeGVsID0gQ29sb3IzLkZyb21JbnRzKDI1NSwgbWV0YWxsaWNSb3VnaG5lc3NCdWZmZXJbZGVzdGluYXRpb25PZmZzZXQgKyAxXSwgbWV0YWxsaWNSb3VnaG5lc3NCdWZmZXJbZGVzdGluYXRpb25PZmZzZXQgKyAyXSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghX0dMVEZNYXRlcmlhbEV4cG9ydGVyLl9GdXp6eUVxdWFscyhtZXRhbGxpY1JvdWdobmVzc1BpeGVsLCBDb2xvcjMuV2hpdGUoKSwgX0dMVEZNYXRlcmlhbEV4cG9ydGVyLl9FcHNpbG9uKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3cml0ZU91dE1ldGFsbGljUm91Z2huZXNzVGV4dHVyZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAod3JpdGVPdXRNZXRhbGxpY1JvdWdobmVzc1RleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZ2V0SW1hZ2VEYXRhQXN5bmMobWV0YWxsaWNSb3VnaG5lc3NCdWZmZXIsIHdpZHRoLCBoZWlnaHQsIG1pbWVUeXBlKS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFsbGljUm91Z2huZXNzRmFjdG9ycy5tZXRhbGxpY1JvdWdobmVzc1RleHR1cmVEYXRhID0gZGF0YTtcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAod3JpdGVPdXRCYXNlQ29sb3JUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2dldEltYWdlRGF0YUFzeW5jKGJhc2VDb2xvckJ1ZmZlciwgd2lkdGgsIGhlaWdodCwgbWltZVR5cGUpLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWxsaWNSb3VnaG5lc3NGYWN0b3JzLmJhc2VDb2xvclRleHR1cmVEYXRhID0gZGF0YTtcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBtZXRhbGxpY1JvdWdobmVzc0ZhY3RvcnM7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcIl9Db252ZXJ0U3BlY3VsYXJHbG9zc2luZXNzVGV4dHVyZXNUb01ldGFsbGljUm91Z2huZXNzOiBTY2VuZSBmcm9tIHRleHR1cmVzIGlzIG1pc3NpbmchXCIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHNwZWN1bGFyIGdsb3NzaW5lc3MgbWF0ZXJpYWwgcHJvcGVydGllcyB0byBtZXRhbGxpYyByb3VnaG5lc3NcclxuICAgICAqIEBwYXJhbSBzcGVjdWxhckdsb3NzaW5lc3MgaW50ZXJmYWNlIHdpdGggc3BlY3VsYXIgZ2xvc3NpbmVzcyBtYXRlcmlhbCBwcm9wZXJ0aWVzXHJcbiAgICAgKiBAcmV0dXJucyBpbnRlcmZhY2Ugd2l0aCBtZXRhbGxpYyByb3VnaG5lc3MgbWF0ZXJpYWwgcHJvcGVydGllc1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9jb252ZXJ0U3BlY3VsYXJHbG9zc2luZXNzVG9NZXRhbGxpY1JvdWdobmVzcyhzcGVjdWxhckdsb3NzaW5lc3M6IF9JUEJSU3BlY3VsYXJHbG9zc2luZXNzKTogX0lQQlJNZXRhbGxpY1JvdWdobmVzcyB7XHJcbiAgICAgICAgY29uc3QgZGlmZnVzZVBlcmNlaXZlZEJyaWdodG5lc3MgPSB0aGlzLl9nZXRQZXJjZWl2ZWRCcmlnaHRuZXNzKHNwZWN1bGFyR2xvc3NpbmVzcy5kaWZmdXNlQ29sb3IpO1xyXG4gICAgICAgIGNvbnN0IHNwZWN1bGFyUGVyY2VpdmVkQnJpZ2h0bmVzcyA9IHRoaXMuX2dldFBlcmNlaXZlZEJyaWdodG5lc3Moc3BlY3VsYXJHbG9zc2luZXNzLnNwZWN1bGFyQ29sb3IpO1xyXG4gICAgICAgIGNvbnN0IG9uZU1pbnVzU3BlY3VsYXJTdHJlbmd0aCA9IDEgLSB0aGlzLl9nZXRNYXhDb21wb25lbnQoc3BlY3VsYXJHbG9zc2luZXNzLnNwZWN1bGFyQ29sb3IpO1xyXG4gICAgICAgIGNvbnN0IG1ldGFsbGljID0gX0dMVEZNYXRlcmlhbEV4cG9ydGVyLl9Tb2x2ZU1ldGFsbGljKGRpZmZ1c2VQZXJjZWl2ZWRCcmlnaHRuZXNzLCBzcGVjdWxhclBlcmNlaXZlZEJyaWdodG5lc3MsIG9uZU1pbnVzU3BlY3VsYXJTdHJlbmd0aCk7XHJcbiAgICAgICAgY29uc3QgYmFzZUNvbG9yRnJvbURpZmZ1c2UgPSBzcGVjdWxhckdsb3NzaW5lc3MuZGlmZnVzZUNvbG9yLnNjYWxlKFxyXG4gICAgICAgICAgICBvbmVNaW51c1NwZWN1bGFyU3RyZW5ndGggLyAoMS4wIC0gX0dMVEZNYXRlcmlhbEV4cG9ydGVyLl9EaWVsZWN0cmljU3BlY3VsYXIucikgLyBNYXRoLm1heCgxIC0gbWV0YWxsaWMsIF9HTFRGTWF0ZXJpYWxFeHBvcnRlci5fRXBzaWxvbilcclxuICAgICAgICApO1xyXG4gICAgICAgIGNvbnN0IGJhc2VDb2xvckZyb21TcGVjdWxhciA9IHNwZWN1bGFyR2xvc3NpbmVzcy5zcGVjdWxhckNvbG9yXHJcbiAgICAgICAgICAgIC5zdWJ0cmFjdChfR0xURk1hdGVyaWFsRXhwb3J0ZXIuX0RpZWxlY3RyaWNTcGVjdWxhci5zY2FsZSgxIC0gbWV0YWxsaWMpKVxyXG4gICAgICAgICAgICAuc2NhbGUoMSAvIE1hdGgubWF4KG1ldGFsbGljLCBfR0xURk1hdGVyaWFsRXhwb3J0ZXIuX0Vwc2lsb24pKTtcclxuICAgICAgICBsZXQgYmFzZUNvbG9yID0gQ29sb3IzLkxlcnAoYmFzZUNvbG9yRnJvbURpZmZ1c2UsIGJhc2VDb2xvckZyb21TcGVjdWxhciwgbWV0YWxsaWMgKiBtZXRhbGxpYyk7XHJcbiAgICAgICAgYmFzZUNvbG9yID0gYmFzZUNvbG9yLmNsYW1wVG9SZWYoMCwgMSwgYmFzZUNvbG9yKTtcclxuXHJcbiAgICAgICAgY29uc3QgbWV0YWxsaWNSb3VnaG5lc3M6IF9JUEJSTWV0YWxsaWNSb3VnaG5lc3MgPSB7XHJcbiAgICAgICAgICAgIGJhc2VDb2xvcjogYmFzZUNvbG9yLFxyXG4gICAgICAgICAgICBtZXRhbGxpYzogbWV0YWxsaWMsXHJcbiAgICAgICAgICAgIHJvdWdobmVzczogMSAtIHNwZWN1bGFyR2xvc3NpbmVzcy5nbG9zc2luZXNzLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHJldHVybiBtZXRhbGxpY1JvdWdobmVzcztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGN1bGF0ZXMgdGhlIHN1cmZhY2UgcmVmbGVjdGFuY2UsIGluZGVwZW5kZW50IG9mIGxpZ2h0aW5nIGNvbmRpdGlvbnNcclxuICAgICAqIEBwYXJhbSBjb2xvciBDb2xvciBzb3VyY2UgdG8gY2FsY3VsYXRlIGJyaWdodG5lc3MgZnJvbVxyXG4gICAgICogQHJldHVybnMgbnVtYmVyIHJlcHJlc2VudGluZyB0aGUgcGVyY2VpdmVkIGJyaWdodG5lc3MsIG9yIHplcm8gaWYgY29sb3IgaXMgdW5kZWZpbmVkXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX2dldFBlcmNlaXZlZEJyaWdodG5lc3MoY29sb3I6IENvbG9yMyk6IG51bWJlciB7XHJcbiAgICAgICAgaWYgKGNvbG9yKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBNYXRoLnNxcnQoMC4yOTkgKiBjb2xvci5yICogY29sb3IuciArIDAuNTg3ICogY29sb3IuZyAqIGNvbG9yLmcgKyAwLjExNCAqIGNvbG9yLmIgKiBjb2xvci5iKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIGNvbG9yIGNvbXBvbmVudCB2YWx1ZVxyXG4gICAgICogQHBhcmFtIGNvbG9yXHJcbiAgICAgKiBAcmV0dXJucyBtYXhpbXVtIGNvbG9yIGNvbXBvbmVudCB2YWx1ZSwgb3IgemVybyBpZiBjb2xvciBpcyBudWxsIG9yIHVuZGVmaW5lZFxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9nZXRNYXhDb21wb25lbnQoY29sb3I6IENvbG9yMyk6IG51bWJlciB7XHJcbiAgICAgICAgaWYgKGNvbG9yKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBNYXRoLm1heChjb2xvci5yLCBNYXRoLm1heChjb2xvci5nLCBjb2xvci5iKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydCBhIFBCUk1hdGVyaWFsIChNZXRhbGxpYy9Sb3VnaG5lc3MpIHRvIE1ldGFsbGljIFJvdWdobmVzcyBmYWN0b3JzXHJcbiAgICAgKiBAcGFyYW0gYmFieWxvblBCUk1hdGVyaWFsIEJKUyBQQlIgTWV0YWxsaWMgUm91Z2huZXNzIE1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gbWltZVR5cGUgbWltZSB0eXBlIHRvIHVzZSBmb3IgdGhlIHRleHR1cmVzXHJcbiAgICAgKiBAcGFyYW0gZ2xURlBick1ldGFsbGljUm91Z2huZXNzIGdsVEYgUEJSIE1ldGFsbGljIFJvdWdobmVzcyBpbnRlcmZhY2VcclxuICAgICAqIEBwYXJhbSBoYXNUZXh0dXJlQ29vcmRzIHNwZWNpZmllcyBpZiB0ZXh0dXJlIGNvb3JkaW5hdGVzIGFyZSBwcmVzZW50IG9uIHRoZSBzdWJtZXNoIHRvIGRldGVybWluZSBpZiB0ZXh0dXJlcyBzaG91bGQgYmUgYXBwbGllZFxyXG4gICAgICogQHJldHVybnMgZ2xURiBQQlIgTWV0YWxsaWMgUm91Z2huZXNzIGZhY3RvcnNcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfY29udmVydE1ldGFsUm91Z2hGYWN0b3JzVG9NZXRhbGxpY1JvdWdobmVzc0FzeW5jKFxyXG4gICAgICAgIGJhYnlsb25QQlJNYXRlcmlhbDogUEJSQmFzZU1hdGVyaWFsLFxyXG4gICAgICAgIG1pbWVUeXBlOiBJbWFnZU1pbWVUeXBlLFxyXG4gICAgICAgIGdsVEZQYnJNZXRhbGxpY1JvdWdobmVzczogSU1hdGVyaWFsUGJyTWV0YWxsaWNSb3VnaG5lc3MsXHJcbiAgICAgICAgaGFzVGV4dHVyZUNvb3JkczogYm9vbGVhblxyXG4gICAgKTogUHJvbWlzZTxfSVBCUk1ldGFsbGljUm91Z2huZXNzPiB7XHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcclxuICAgICAgICBjb25zdCBiYXNlQ29sb3IgPSBiYWJ5bG9uUEJSTWF0ZXJpYWwuX2FsYmVkb0NvbG9yO1xyXG4gICAgICAgIGNvbnN0IG1ldGFsbGljID0gYmFieWxvblBCUk1hdGVyaWFsLl9tZXRhbGxpYztcclxuICAgICAgICBjb25zdCByb3VnaG5lc3MgPSBiYWJ5bG9uUEJSTWF0ZXJpYWwuX3JvdWdobmVzcztcclxuICAgICAgICBjb25zdCBtZXRhbGxpY1JvdWdobmVzczogX0lQQlJNZXRhbGxpY1JvdWdobmVzcyA9IHtcclxuICAgICAgICAgICAgYmFzZUNvbG9yOiBiYXNlQ29sb3IsXHJcbiAgICAgICAgICAgIG1ldGFsbGljOiBtZXRhbGxpYyxcclxuICAgICAgICAgICAgcm91Z2huZXNzOiByb3VnaG5lc3MsXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgaWYgKGhhc1RleHR1cmVDb29yZHMpIHtcclxuICAgICAgICAgICAgY29uc3QgYWxiZWRvVGV4dHVyZSA9IGJhYnlsb25QQlJNYXRlcmlhbC5fYWxiZWRvVGV4dHVyZTtcclxuICAgICAgICAgICAgaWYgKGFsYmVkb1RleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXhwb3J0VGV4dHVyZUFzeW5jKGJhYnlsb25QQlJNYXRlcmlhbC5fYWxiZWRvVGV4dHVyZSEsIG1pbWVUeXBlKS50aGVuKChnbFRGVGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2xURlRleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsVEZQYnJNZXRhbGxpY1JvdWdobmVzcy5iYXNlQ29sb3JUZXh0dXJlID0gZ2xURlRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBtZXRhbGxpY1RleHR1cmUgPSBiYWJ5bG9uUEJSTWF0ZXJpYWwuX21ldGFsbGljVGV4dHVyZTtcclxuICAgICAgICAgICAgaWYgKG1ldGFsbGljVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9leHBvcnRUZXh0dXJlQXN5bmMobWV0YWxsaWNUZXh0dXJlLCBtaW1lVHlwZSkudGhlbigoZ2xURlRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdsVEZUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRGUGJyTWV0YWxsaWNSb3VnaG5lc3MubWV0YWxsaWNSb3VnaG5lc3NUZXh0dXJlID0gZ2xURlRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gbWV0YWxsaWNSb3VnaG5lc3M7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZ2V0VGV4dHVyZVNhbXBsZXIodGV4dHVyZTogTnVsbGFibGU8QmFzZVRleHR1cmU+KTogSVNhbXBsZXIge1xyXG4gICAgICAgIGNvbnN0IHNhbXBsZXI6IElTYW1wbGVyID0ge307XHJcbiAgICAgICAgaWYgKCF0ZXh0dXJlIHx8ICEodGV4dHVyZSBpbnN0YW5jZW9mIFRleHR1cmUpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3Qgd3JhcFMgPSB0aGlzLl9nZXRHTFRGVGV4dHVyZVdyYXBNb2RlKHRleHR1cmUud3JhcFUpO1xyXG4gICAgICAgIGlmICh3cmFwUyAhPT0gVGV4dHVyZVdyYXBNb2RlLlJFUEVBVCkge1xyXG4gICAgICAgICAgICBzYW1wbGVyLndyYXBTID0gd3JhcFM7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB3cmFwVCA9IHRoaXMuX2dldEdMVEZUZXh0dXJlV3JhcE1vZGUodGV4dHVyZS53cmFwVik7XHJcbiAgICAgICAgaWYgKHdyYXBUICE9PSBUZXh0dXJlV3JhcE1vZGUuUkVQRUFUKSB7XHJcbiAgICAgICAgICAgIHNhbXBsZXIud3JhcFQgPSB3cmFwVDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN3aXRjaCAodGV4dHVyZS5zYW1wbGluZ01vZGUpIHtcclxuICAgICAgICAgICAgY2FzZSBUZXh0dXJlLkxJTkVBUl9MSU5FQVI6IHtcclxuICAgICAgICAgICAgICAgIHNhbXBsZXIubWFnRmlsdGVyID0gVGV4dHVyZU1hZ0ZpbHRlci5MSU5FQVI7XHJcbiAgICAgICAgICAgICAgICBzYW1wbGVyLm1pbkZpbHRlciA9IFRleHR1cmVNaW5GaWx0ZXIuTElORUFSO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBUZXh0dXJlLkxJTkVBUl9ORUFSRVNUOiB7XHJcbiAgICAgICAgICAgICAgICBzYW1wbGVyLm1hZ0ZpbHRlciA9IFRleHR1cmVNYWdGaWx0ZXIuTElORUFSO1xyXG4gICAgICAgICAgICAgICAgc2FtcGxlci5taW5GaWx0ZXIgPSBUZXh0dXJlTWluRmlsdGVyLk5FQVJFU1Q7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFRleHR1cmUuTkVBUkVTVF9MSU5FQVI6IHtcclxuICAgICAgICAgICAgICAgIHNhbXBsZXIubWFnRmlsdGVyID0gVGV4dHVyZU1hZ0ZpbHRlci5ORUFSRVNUO1xyXG4gICAgICAgICAgICAgICAgc2FtcGxlci5taW5GaWx0ZXIgPSBUZXh0dXJlTWluRmlsdGVyLkxJTkVBUjtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgVGV4dHVyZS5ORUFSRVNUX0xJTkVBUl9NSVBMSU5FQVI6IHtcclxuICAgICAgICAgICAgICAgIHNhbXBsZXIubWFnRmlsdGVyID0gVGV4dHVyZU1hZ0ZpbHRlci5ORUFSRVNUO1xyXG4gICAgICAgICAgICAgICAgc2FtcGxlci5taW5GaWx0ZXIgPSBUZXh0dXJlTWluRmlsdGVyLkxJTkVBUl9NSVBNQVBfTElORUFSO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBUZXh0dXJlLk5FQVJFU1RfTkVBUkVTVDoge1xyXG4gICAgICAgICAgICAgICAgc2FtcGxlci5tYWdGaWx0ZXIgPSBUZXh0dXJlTWFnRmlsdGVyLk5FQVJFU1Q7XHJcbiAgICAgICAgICAgICAgICBzYW1wbGVyLm1pbkZpbHRlciA9IFRleHR1cmVNaW5GaWx0ZXIuTkVBUkVTVDtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgVGV4dHVyZS5ORUFSRVNUX0xJTkVBUl9NSVBORUFSRVNUOiB7XHJcbiAgICAgICAgICAgICAgICBzYW1wbGVyLm1hZ0ZpbHRlciA9IFRleHR1cmVNYWdGaWx0ZXIuTkVBUkVTVDtcclxuICAgICAgICAgICAgICAgIHNhbXBsZXIubWluRmlsdGVyID0gVGV4dHVyZU1pbkZpbHRlci5MSU5FQVJfTUlQTUFQX05FQVJFU1Q7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFRleHR1cmUuTElORUFSX05FQVJFU1RfTUlQTkVBUkVTVDoge1xyXG4gICAgICAgICAgICAgICAgc2FtcGxlci5tYWdGaWx0ZXIgPSBUZXh0dXJlTWFnRmlsdGVyLkxJTkVBUjtcclxuICAgICAgICAgICAgICAgIHNhbXBsZXIubWluRmlsdGVyID0gVGV4dHVyZU1pbkZpbHRlci5ORUFSRVNUX01JUE1BUF9ORUFSRVNUO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBUZXh0dXJlLkxJTkVBUl9ORUFSRVNUX01JUExJTkVBUjoge1xyXG4gICAgICAgICAgICAgICAgc2FtcGxlci5tYWdGaWx0ZXIgPSBUZXh0dXJlTWFnRmlsdGVyLkxJTkVBUjtcclxuICAgICAgICAgICAgICAgIHNhbXBsZXIubWluRmlsdGVyID0gVGV4dHVyZU1pbkZpbHRlci5ORUFSRVNUX01JUE1BUF9MSU5FQVI7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFRleHR1cmUuTkVBUkVTVF9ORUFSRVNUX01JUExJTkVBUjoge1xyXG4gICAgICAgICAgICAgICAgc2FtcGxlci5tYWdGaWx0ZXIgPSBUZXh0dXJlTWFnRmlsdGVyLk5FQVJFU1Q7XHJcbiAgICAgICAgICAgICAgICBzYW1wbGVyLm1pbkZpbHRlciA9IFRleHR1cmVNaW5GaWx0ZXIuTkVBUkVTVF9NSVBNQVBfTElORUFSO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBUZXh0dXJlLkxJTkVBUl9MSU5FQVJfTUlQTElORUFSOiB7XHJcbiAgICAgICAgICAgICAgICBzYW1wbGVyLm1hZ0ZpbHRlciA9IFRleHR1cmVNYWdGaWx0ZXIuTElORUFSO1xyXG4gICAgICAgICAgICAgICAgc2FtcGxlci5taW5GaWx0ZXIgPSBUZXh0dXJlTWluRmlsdGVyLkxJTkVBUl9NSVBNQVBfTElORUFSO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBUZXh0dXJlLkxJTkVBUl9MSU5FQVJfTUlQTkVBUkVTVDoge1xyXG4gICAgICAgICAgICAgICAgc2FtcGxlci5tYWdGaWx0ZXIgPSBUZXh0dXJlTWFnRmlsdGVyLkxJTkVBUjtcclxuICAgICAgICAgICAgICAgIHNhbXBsZXIubWluRmlsdGVyID0gVGV4dHVyZU1pbkZpbHRlci5MSU5FQVJfTUlQTUFQX05FQVJFU1Q7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFRleHR1cmUuTkVBUkVTVF9ORUFSRVNUX01JUE5FQVJFU1Q6IHtcclxuICAgICAgICAgICAgICAgIHNhbXBsZXIubWFnRmlsdGVyID0gVGV4dHVyZU1hZ0ZpbHRlci5ORUFSRVNUO1xyXG4gICAgICAgICAgICAgICAgc2FtcGxlci5taW5GaWx0ZXIgPSBUZXh0dXJlTWluRmlsdGVyLk5FQVJFU1RfTUlQTUFQX05FQVJFU1Q7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHNhbXBsZXI7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZ2V0R0xURlRleHR1cmVXcmFwTW9kZSh3cmFwTW9kZTogbnVtYmVyKTogVGV4dHVyZVdyYXBNb2RlIHtcclxuICAgICAgICBzd2l0Y2ggKHdyYXBNb2RlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgVGV4dHVyZS5XUkFQX0FERFJFU1NNT0RFOiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZVdyYXBNb2RlLlJFUEVBVDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFRleHR1cmUuQ0xBTVBfQUREUkVTU01PREU6IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBUZXh0dXJlV3JhcE1vZGUuQ0xBTVBfVE9fRURHRTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFRleHR1cmUuTUlSUk9SX0FERFJFU1NNT0RFOiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZVdyYXBNb2RlLk1JUlJPUkVEX1JFUEVBVDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBkZWZhdWx0OiB7XHJcbiAgICAgICAgICAgICAgICBUb29scy5FcnJvcihgVW5zdXBwb3J0ZWQgVGV4dHVyZSBXcmFwIE1vZGUgJHt3cmFwTW9kZX0hYCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZVdyYXBNb2RlLlJFUEVBVDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnQgYSBQQlJNYXRlcmlhbCAoU3BlY3VsYXIvR2xvc3NpbmVzcykgdG8gTWV0YWxsaWMgUm91Z2huZXNzIGZhY3RvcnNcclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uUEJSTWF0ZXJpYWwgQkpTIFBCUiBNZXRhbGxpYyBSb3VnaG5lc3MgTWF0ZXJpYWxcclxuICAgICAqIEBwYXJhbSBtaW1lVHlwZSBtaW1lIHR5cGUgdG8gdXNlIGZvciB0aGUgdGV4dHVyZXNcclxuICAgICAqIEBwYXJhbSBwYnJNZXRhbGxpY1JvdWdobmVzcyBnbFRGIFBCUiBNZXRhbGxpYyBSb3VnaG5lc3MgaW50ZXJmYWNlXHJcbiAgICAgKiBAcGFyYW0gaGFzVGV4dHVyZUNvb3JkcyBzcGVjaWZpZXMgaWYgdGV4dHVyZSBjb29yZGluYXRlcyBhcmUgcHJlc2VudCBvbiB0aGUgc3VibWVzaCB0byBkZXRlcm1pbmUgaWYgdGV4dHVyZXMgc2hvdWxkIGJlIGFwcGxpZWRcclxuICAgICAqIEByZXR1cm5zIGdsVEYgUEJSIE1ldGFsbGljIFJvdWdobmVzcyBmYWN0b3JzXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX2NvbnZlcnRTcGVjR2xvc3NGYWN0b3JzVG9NZXRhbGxpY1JvdWdobmVzc0FzeW5jKFxyXG4gICAgICAgIGJhYnlsb25QQlJNYXRlcmlhbDogUEJSQmFzZU1hdGVyaWFsLFxyXG4gICAgICAgIG1pbWVUeXBlOiBJbWFnZU1pbWVUeXBlLFxyXG4gICAgICAgIHBick1ldGFsbGljUm91Z2huZXNzOiBJTWF0ZXJpYWxQYnJNZXRhbGxpY1JvdWdobmVzcyxcclxuICAgICAgICBoYXNUZXh0dXJlQ29vcmRzOiBib29sZWFuXHJcbiAgICApOiBQcm9taXNlPF9JUEJSTWV0YWxsaWNSb3VnaG5lc3M+IHtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHNwZWNHbG9zczogX0lQQlJTcGVjdWxhckdsb3NzaW5lc3MgPSB7XHJcbiAgICAgICAgICAgICAgICBkaWZmdXNlQ29sb3I6IGJhYnlsb25QQlJNYXRlcmlhbC5fYWxiZWRvQ29sb3IsXHJcbiAgICAgICAgICAgICAgICBzcGVjdWxhckNvbG9yOiBiYWJ5bG9uUEJSTWF0ZXJpYWwuX3JlZmxlY3Rpdml0eUNvbG9yLFxyXG4gICAgICAgICAgICAgICAgZ2xvc3NpbmVzczogYmFieWxvblBCUk1hdGVyaWFsLl9taWNyb1N1cmZhY2UsXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGNvbnN0IGFsYmVkb1RleHR1cmUgPSBiYWJ5bG9uUEJSTWF0ZXJpYWwuX2FsYmVkb1RleHR1cmU7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlZmxlY3Rpdml0eVRleHR1cmUgPSBiYWJ5bG9uUEJSTWF0ZXJpYWwuX3JlZmxlY3Rpdml0eVRleHR1cmU7XHJcbiAgICAgICAgICAgIGNvbnN0IHVzZU1pY3Jvc3VyZmFjZUZyb21SZWZsZWN0aXZpdHlNYXBBbHBoYSA9IGJhYnlsb25QQlJNYXRlcmlhbC5fdXNlTWljcm9TdXJmYWNlRnJvbVJlZmxlY3Rpdml0eU1hcEFscGhhO1xyXG4gICAgICAgICAgICBpZiAocmVmbGVjdGl2aXR5VGV4dHVyZSAmJiAhdXNlTWljcm9zdXJmYWNlRnJvbVJlZmxlY3Rpdml0eU1hcEFscGhhKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJfQ29udmVydFBCUk1hdGVyaWFsOiBHbG9zc2luZXNzIHZhbHVlcyBub3QgaW5jbHVkZWQgaW4gdGhlIHJlZmxlY3Rpdml0eSB0ZXh0dXJlIGFyZSBjdXJyZW50bHkgbm90IHN1cHBvcnRlZFwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoKGFsYmVkb1RleHR1cmUgfHwgcmVmbGVjdGl2aXR5VGV4dHVyZSkgJiYgaGFzVGV4dHVyZUNvb3Jkcykge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2FtcGxlckluZGV4ID0gdGhpcy5fZXhwb3J0VGV4dHVyZVNhbXBsZXIoYWxiZWRvVGV4dHVyZSB8fCByZWZsZWN0aXZpdHlUZXh0dXJlKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9jb252ZXJ0U3BlY3VsYXJHbG9zc2luZXNzVGV4dHVyZXNUb01ldGFsbGljUm91Z2huZXNzQXN5bmMoYWxiZWRvVGV4dHVyZSwgcmVmbGVjdGl2aXR5VGV4dHVyZSwgc3BlY0dsb3NzLCBtaW1lVHlwZSkudGhlbigobWV0YWxsaWNSb3VnaG5lc3NGYWN0b3JzKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGV4dHVyZXMgPSB0aGlzLl9leHBvcnRlci5fdGV4dHVyZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1ldGFsbGljUm91Z2huZXNzRmFjdG9ycy5iYXNlQ29sb3JUZXh0dXJlRGF0YSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbWFnZUluZGV4ID0gdGhpcy5fZXhwb3J0SW1hZ2UoYGJhc2VDb2xvciR7dGV4dHVyZXMubGVuZ3RofWAsIG1pbWVUeXBlLCBtZXRhbGxpY1JvdWdobmVzc0ZhY3RvcnMuYmFzZUNvbG9yVGV4dHVyZURhdGEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYnJNZXRhbGxpY1JvdWdobmVzcy5iYXNlQ29sb3JUZXh0dXJlID0gdGhpcy5fZXhwb3J0VGV4dHVyZUluZm8oaW1hZ2VJbmRleCwgc2FtcGxlckluZGV4LCBhbGJlZG9UZXh0dXJlPy5jb29yZGluYXRlc0luZGV4KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1ldGFsbGljUm91Z2huZXNzRmFjdG9ycy5tZXRhbGxpY1JvdWdobmVzc1RleHR1cmVEYXRhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGltYWdlSW5kZXggPSB0aGlzLl9leHBvcnRJbWFnZShgbWV0YWxsaWNSb3VnaG5lc3Mke3RleHR1cmVzLmxlbmd0aH1gLCBtaW1lVHlwZSwgbWV0YWxsaWNSb3VnaG5lc3NGYWN0b3JzLm1ldGFsbGljUm91Z2huZXNzVGV4dHVyZURhdGEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYnJNZXRhbGxpY1JvdWdobmVzcy5tZXRhbGxpY1JvdWdobmVzc1RleHR1cmUgPSB0aGlzLl9leHBvcnRUZXh0dXJlSW5mbyhpbWFnZUluZGV4LCBzYW1wbGVySW5kZXgsIHJlZmxlY3Rpdml0eVRleHR1cmU/LmNvb3JkaW5hdGVzSW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1ldGFsbGljUm91Z2huZXNzRmFjdG9ycztcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnZlcnRTcGVjdWxhckdsb3NzaW5lc3NUb01ldGFsbGljUm91Z2huZXNzKHNwZWNHbG9zcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIGEgQmFieWxvbiBQQlIgQmFzZSBNYXRlcmlhbCB0byBhIGdsVEYgTWF0ZXJpYWxcclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uUEJSTWF0ZXJpYWwgQkpTIFBCUiBCYXNlIE1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gbWltZVR5cGUgbWltZSB0eXBlIHRvIHVzZSBmb3IgdGhlIHRleHR1cmVzXHJcbiAgICAgKiBAcGFyYW0gaGFzVGV4dHVyZUNvb3JkcyBzcGVjaWZpZXMgaWYgdGV4dHVyZSBjb29yZGluYXRlcyBhcmUgcHJlc2VudCBvbiB0aGUgc3VibWVzaCB0byBkZXRlcm1pbmUgaWYgdGV4dHVyZXMgc2hvdWxkIGJlIGFwcGxpZWRcclxuICAgICAqIEByZXR1cm5zIGFzeW5jIGdsVEYgTWF0ZXJpYWwgcmVwcmVzZW50YXRpb25cclxuICAgICAqL1xyXG4gICAgcHVibGljIF9jb252ZXJ0UEJSTWF0ZXJpYWxBc3luYyhiYWJ5bG9uUEJSTWF0ZXJpYWw6IFBCUkJhc2VNYXRlcmlhbCwgbWltZVR5cGU6IEltYWdlTWltZVR5cGUsIGhhc1RleHR1cmVDb29yZHM6IGJvb2xlYW4pOiBQcm9taXNlPElNYXRlcmlhbD4ge1xyXG4gICAgICAgIGNvbnN0IGdsVEZQYnJNZXRhbGxpY1JvdWdobmVzczogSU1hdGVyaWFsUGJyTWV0YWxsaWNSb3VnaG5lc3MgPSB7fTtcclxuICAgICAgICBjb25zdCBnbFRGTWF0ZXJpYWw6IElNYXRlcmlhbCA9IHtcclxuICAgICAgICAgICAgbmFtZTogYmFieWxvblBCUk1hdGVyaWFsLm5hbWUsXHJcbiAgICAgICAgfTtcclxuICAgICAgICBjb25zdCB1c2VNZXRhbGxpY1JvdWdobmVzcyA9IGJhYnlsb25QQlJNYXRlcmlhbC5pc01ldGFsbGljV29ya2Zsb3coKTtcclxuXHJcbiAgICAgICAgaWYgKHVzZU1ldGFsbGljUm91Z2huZXNzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGFsYmVkb0NvbG9yID0gYmFieWxvblBCUk1hdGVyaWFsLl9hbGJlZG9Db2xvcjtcclxuICAgICAgICAgICAgY29uc3QgYWxwaGEgPSBiYWJ5bG9uUEJSTWF0ZXJpYWwuYWxwaGE7XHJcbiAgICAgICAgICAgIGlmIChhbGJlZG9Db2xvcikge1xyXG4gICAgICAgICAgICAgICAgZ2xURlBick1ldGFsbGljUm91Z2huZXNzLmJhc2VDb2xvckZhY3RvciA9IFthbGJlZG9Db2xvci5yLCBhbGJlZG9Db2xvci5nLCBhbGJlZG9Db2xvci5iLCBhbHBoYV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnZlcnRNZXRhbFJvdWdoRmFjdG9yc1RvTWV0YWxsaWNSb3VnaG5lc3NBc3luYyhiYWJ5bG9uUEJSTWF0ZXJpYWwsIG1pbWVUeXBlLCBnbFRGUGJyTWV0YWxsaWNSb3VnaG5lc3MsIGhhc1RleHR1cmVDb29yZHMpLnRoZW4oKG1ldGFsbGljUm91Z2huZXNzKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fc2V0TWV0YWxsaWNSb3VnaG5lc3NQYnJNYXRlcmlhbChtZXRhbGxpY1JvdWdobmVzcywgYmFieWxvblBCUk1hdGVyaWFsLCBnbFRGTWF0ZXJpYWwsIGdsVEZQYnJNZXRhbGxpY1JvdWdobmVzcywgbWltZVR5cGUsIGhhc1RleHR1cmVDb29yZHMpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29udmVydFNwZWNHbG9zc0ZhY3RvcnNUb01ldGFsbGljUm91Z2huZXNzQXN5bmMoYmFieWxvblBCUk1hdGVyaWFsLCBtaW1lVHlwZSwgZ2xURlBick1ldGFsbGljUm91Z2huZXNzLCBoYXNUZXh0dXJlQ29vcmRzKS50aGVuKChtZXRhbGxpY1JvdWdobmVzcykgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NldE1ldGFsbGljUm91Z2huZXNzUGJyTWF0ZXJpYWwobWV0YWxsaWNSb3VnaG5lc3MsIGJhYnlsb25QQlJNYXRlcmlhbCwgZ2xURk1hdGVyaWFsLCBnbFRGUGJyTWV0YWxsaWNSb3VnaG5lc3MsIG1pbWVUeXBlLCBoYXNUZXh0dXJlQ29vcmRzKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3NldE1ldGFsbGljUm91Z2huZXNzUGJyTWF0ZXJpYWwoXHJcbiAgICAgICAgbWV0YWxsaWNSb3VnaG5lc3M6IE51bGxhYmxlPF9JUEJSTWV0YWxsaWNSb3VnaG5lc3M+LFxyXG4gICAgICAgIGJhYnlsb25QQlJNYXRlcmlhbDogUEJSQmFzZU1hdGVyaWFsLFxyXG4gICAgICAgIGdsVEZNYXRlcmlhbDogSU1hdGVyaWFsLFxyXG4gICAgICAgIGdsVEZQYnJNZXRhbGxpY1JvdWdobmVzczogSU1hdGVyaWFsUGJyTWV0YWxsaWNSb3VnaG5lc3MsXHJcbiAgICAgICAgbWltZVR5cGU6IEltYWdlTWltZVR5cGUsXHJcbiAgICAgICAgaGFzVGV4dHVyZUNvb3JkczogYm9vbGVhblxyXG4gICAgKTogUHJvbWlzZTxJTWF0ZXJpYWw+IHtcclxuICAgICAgICBjb25zdCBtYXRlcmlhbE1hcCA9IHRoaXMuX2V4cG9ydGVyLl9tYXRlcmlhbE1hcDtcclxuICAgICAgICBjb25zdCBtYXRlcmlhbHMgPSB0aGlzLl9leHBvcnRlci5fbWF0ZXJpYWxzO1xyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gW107XHJcbiAgICAgICAgaWYgKG1ldGFsbGljUm91Z2huZXNzKSB7XHJcbiAgICAgICAgICAgIF9HTFRGTWF0ZXJpYWxFeHBvcnRlci5fU2V0QWxwaGFNb2RlKGdsVEZNYXRlcmlhbCwgYmFieWxvblBCUk1hdGVyaWFsIGFzIFBCUk1hdGVyaWFsKTtcclxuICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgICAgIShcclxuICAgICAgICAgICAgICAgICAgICBfR0xURk1hdGVyaWFsRXhwb3J0ZXIuX0Z1enp5RXF1YWxzKG1ldGFsbGljUm91Z2huZXNzLmJhc2VDb2xvciwgQ29sb3IzLldoaXRlKCksIF9HTFRGTWF0ZXJpYWxFeHBvcnRlci5fRXBzaWxvbikgJiZcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uUEJSTWF0ZXJpYWwuYWxwaGEgPj0gX0dMVEZNYXRlcmlhbEV4cG9ydGVyLl9FcHNpbG9uXHJcbiAgICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgZ2xURlBick1ldGFsbGljUm91Z2huZXNzLmJhc2VDb2xvckZhY3RvciA9IFttZXRhbGxpY1JvdWdobmVzcy5iYXNlQ29sb3IuciwgbWV0YWxsaWNSb3VnaG5lc3MuYmFzZUNvbG9yLmcsIG1ldGFsbGljUm91Z2huZXNzLmJhc2VDb2xvci5iLCBiYWJ5bG9uUEJSTWF0ZXJpYWwuYWxwaGFdO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAobWV0YWxsaWNSb3VnaG5lc3MubWV0YWxsaWMgIT0gbnVsbCAmJiBtZXRhbGxpY1JvdWdobmVzcy5tZXRhbGxpYyAhPT0gMSkge1xyXG4gICAgICAgICAgICAgICAgZ2xURlBick1ldGFsbGljUm91Z2huZXNzLm1ldGFsbGljRmFjdG9yID0gbWV0YWxsaWNSb3VnaG5lc3MubWV0YWxsaWM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKG1ldGFsbGljUm91Z2huZXNzLnJvdWdobmVzcyAhPSBudWxsICYmIG1ldGFsbGljUm91Z2huZXNzLnJvdWdobmVzcyAhPT0gMSkge1xyXG4gICAgICAgICAgICAgICAgZ2xURlBick1ldGFsbGljUm91Z2huZXNzLnJvdWdobmVzc0ZhY3RvciA9IG1ldGFsbGljUm91Z2huZXNzLnJvdWdobmVzcztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGJhYnlsb25QQlJNYXRlcmlhbC5iYWNrRmFjZUN1bGxpbmcgIT0gbnVsbCAmJiAhYmFieWxvblBCUk1hdGVyaWFsLmJhY2tGYWNlQ3VsbGluZykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFiYWJ5bG9uUEJSTWF0ZXJpYWwuX3R3b1NpZGVkTGlnaHRpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICBUb29scy5XYXJuKGJhYnlsb25QQlJNYXRlcmlhbC5uYW1lICsgXCI6IEJhY2stZmFjZSBjdWxsaW5nIGRpc2FibGVkIGFuZCB0d28tc2lkZWQgbGlnaHRpbmcgZGlzYWJsZWQgaXMgbm90IHN1cHBvcnRlZCBpbiBnbFRGLlwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGdsVEZNYXRlcmlhbC5kb3VibGVTaWRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChoYXNUZXh0dXJlQ29vcmRzKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBidW1wVGV4dHVyZSA9IGJhYnlsb25QQlJNYXRlcmlhbC5fYnVtcFRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICBpZiAoYnVtcFRleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlID0gdGhpcy5fZXhwb3J0VGV4dHVyZUFzeW5jKGJ1bXBUZXh0dXJlLCBtaW1lVHlwZSkudGhlbigoZ2xURlRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdsVEZUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRGTWF0ZXJpYWwubm9ybWFsVGV4dHVyZSA9IGdsVEZUZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJ1bXBUZXh0dXJlLmxldmVsICE9PSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xURk1hdGVyaWFsLm5vcm1hbFRleHR1cmUuc2NhbGUgPSBidW1wVGV4dHVyZS5sZXZlbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2gocHJvbWlzZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhbWJpZW50VGV4dHVyZSA9IGJhYnlsb25QQlJNYXRlcmlhbC5fYW1iaWVudFRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICBpZiAoYW1iaWVudFRleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlID0gdGhpcy5fZXhwb3J0VGV4dHVyZUFzeW5jKGFtYmllbnRUZXh0dXJlLCBtaW1lVHlwZSkudGhlbigoZ2xURlRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdsVEZUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvY2NsdXNpb25UZXh0dXJlOiBJTWF0ZXJpYWxPY2NsdXNpb25UZXh0dXJlSW5mbyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleDogZ2xURlRleHR1cmUuaW5kZXgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4Q29vcmQ6IGdsVEZUZXh0dXJlLnRleENvb3JkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnM6IGdsVEZUZXh0dXJlLmV4dGVuc2lvbnMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsVEZNYXRlcmlhbC5vY2NsdXNpb25UZXh0dXJlID0gb2NjbHVzaW9uVGV4dHVyZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFtYmllbnRUZXh0dXJlU3RyZW5ndGggPSBiYWJ5bG9uUEJSTWF0ZXJpYWwuX2FtYmllbnRUZXh0dXJlU3RyZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW1iaWVudFRleHR1cmVTdHJlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jY2x1c2lvblRleHR1cmUuc3RyZW5ndGggPSBhbWJpZW50VGV4dHVyZVN0cmVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChwcm9taXNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbnN0IGVtaXNzaXZlVGV4dHVyZSA9IGJhYnlsb25QQlJNYXRlcmlhbC5fZW1pc3NpdmVUZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgaWYgKGVtaXNzaXZlVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLl9leHBvcnRUZXh0dXJlQXN5bmMoZW1pc3NpdmVUZXh0dXJlLCBtaW1lVHlwZSkudGhlbigoZ2xURlRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdsVEZUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRGTWF0ZXJpYWwuZW1pc3NpdmVUZXh0dXJlID0gZ2xURlRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKHByb21pc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGVtaXNzaXZlQ29sb3IgPSBiYWJ5bG9uUEJSTWF0ZXJpYWwuX2VtaXNzaXZlQ29sb3I7XHJcbiAgICAgICAgICAgIGlmICghX0dMVEZNYXRlcmlhbEV4cG9ydGVyLl9GdXp6eUVxdWFscyhlbWlzc2l2ZUNvbG9yLCBDb2xvcjMuQmxhY2soKSwgX0dMVEZNYXRlcmlhbEV4cG9ydGVyLl9FcHNpbG9uKSkge1xyXG4gICAgICAgICAgICAgICAgZ2xURk1hdGVyaWFsLmVtaXNzaXZlRmFjdG9yID0gZW1pc3NpdmVDb2xvci5hc0FycmF5KCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGdsVEZNYXRlcmlhbC5wYnJNZXRhbGxpY1JvdWdobmVzcyA9IGdsVEZQYnJNZXRhbGxpY1JvdWdobmVzcztcclxuICAgICAgICAgICAgbWF0ZXJpYWxzLnB1c2goZ2xURk1hdGVyaWFsKTtcclxuICAgICAgICAgICAgbWF0ZXJpYWxNYXBbYmFieWxvblBCUk1hdGVyaWFsLnVuaXF1ZUlkXSA9IG1hdGVyaWFscy5sZW5ndGggLSAxO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZpbmlzaE1hdGVyaWFsKHByb21pc2VzLCBnbFRGTWF0ZXJpYWwsIGJhYnlsb25QQlJNYXRlcmlhbCwgbWltZVR5cGUpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2dldFBpeGVsc0Zyb21UZXh0dXJlKGJhYnlsb25UZXh0dXJlOiBCYXNlVGV4dHVyZSk6IFByb21pc2U8TnVsbGFibGU8VWludDhBcnJheSB8IEZsb2F0MzJBcnJheT4+IHtcclxuICAgICAgICBjb25zdCBwaXhlbHMgPVxyXG4gICAgICAgICAgICBiYWJ5bG9uVGV4dHVyZS50ZXh0dXJlVHlwZSA9PT0gQ29uc3RhbnRzLlRFWFRVUkVUWVBFX1VOU0lHTkVEX0lOVFxyXG4gICAgICAgICAgICAgICAgPyAoYmFieWxvblRleHR1cmUucmVhZFBpeGVscygpIGFzIFByb21pc2U8VWludDhBcnJheT4pXHJcbiAgICAgICAgICAgICAgICA6IChiYWJ5bG9uVGV4dHVyZS5yZWFkUGl4ZWxzKCkgYXMgUHJvbWlzZTxGbG9hdDMyQXJyYXk+KTtcclxuICAgICAgICByZXR1cm4gcGl4ZWxzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXh0cmFjdHMgYSB0ZXh0dXJlIGZyb20gYSBCYWJ5bG9uIHRleHR1cmUgaW50byBmaWxlIGRhdGEgYW5kIGdsVEYgZGF0YVxyXG4gICAgICogQHBhcmFtIGJhYnlsb25UZXh0dXJlIEJhYnlsb24gdGV4dHVyZSB0byBleHRyYWN0XHJcbiAgICAgKiBAcGFyYW0gbWltZVR5cGUgTWltZSBUeXBlIG9mIHRoZSBiYWJ5bG9uVGV4dHVyZVxyXG4gICAgICogQHJldHVybnMgZ2xURiB0ZXh0dXJlIGluZm8sIG9yIG51bGwgaWYgdGhlIHRleHR1cmUgZm9ybWF0IGlzIG5vdCBzdXBwb3J0ZWRcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9leHBvcnRUZXh0dXJlQXN5bmMoYmFieWxvblRleHR1cmU6IEJhc2VUZXh0dXJlLCBtaW1lVHlwZTogSW1hZ2VNaW1lVHlwZSk6IFByb21pc2U8TnVsbGFibGU8SVRleHR1cmVJbmZvPj4ge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvblByb21pc2UgPSB0aGlzLl9leHBvcnRlci5fZXh0ZW5zaW9uc1ByZUV4cG9ydFRleHR1cmVBc3luYyhcImV4cG9ydGVyXCIsIGJhYnlsb25UZXh0dXJlIGFzIFRleHR1cmUsIG1pbWVUeXBlKTtcclxuICAgICAgICBpZiAoIWV4dGVuc2lvblByb21pc2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V4cG9ydFRleHR1cmVJbmZvQXN5bmMoYmFieWxvblRleHR1cmUsIG1pbWVUeXBlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBleHRlbnNpb25Qcm9taXNlLnRoZW4oKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgaWYgKCF0ZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXhwb3J0VGV4dHVyZUluZm9Bc3luYyhiYWJ5bG9uVGV4dHVyZSwgbWltZVR5cGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9leHBvcnRUZXh0dXJlSW5mb0FzeW5jKHRleHR1cmUsIG1pbWVUeXBlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgX2V4cG9ydFRleHR1cmVJbmZvQXN5bmMoYmFieWxvblRleHR1cmU6IEJhc2VUZXh0dXJlLCBtaW1lVHlwZTogSW1hZ2VNaW1lVHlwZSk6IFByb21pc2U8TnVsbGFibGU8SVRleHR1cmVJbmZvPj4ge1xyXG4gICAgICAgIGNvbnN0IHRleHR1cmVVaWQgPSBiYWJ5bG9uVGV4dHVyZS51aWQ7XHJcbiAgICAgICAgaWYgKCEodGV4dHVyZVVpZCBpbiB0aGlzLl90ZXh0dXJlTWFwKSkge1xyXG4gICAgICAgICAgICBjb25zdCBwaXhlbHMgPSBhd2FpdCB0aGlzLl9nZXRQaXhlbHNGcm9tVGV4dHVyZShiYWJ5bG9uVGV4dHVyZSk7XHJcbiAgICAgICAgICAgIGlmICghcGl4ZWxzKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3Qgc2FtcGxlckluZGV4ID0gdGhpcy5fZXhwb3J0VGV4dHVyZVNhbXBsZXIoYmFieWxvblRleHR1cmUpO1xyXG5cclxuICAgICAgICAgICAgLy8gUHJlc2VydmUgdGV4dHVyZSBtaW1lIHR5cGUgaWYgZGVmaW5lZFxyXG4gICAgICAgICAgICBjb25zdCB0ZXh0dXJlTWltZVR5cGUgPSAoYmFieWxvblRleHR1cmUgYXMgVGV4dHVyZSkubWltZVR5cGU7XHJcbiAgICAgICAgICAgIGlmICh0ZXh0dXJlTWltZVR5cGUpIHtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAodGV4dHVyZU1pbWVUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImltYWdlL2pwZWdcIjpcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiaW1hZ2UvcG5nXCI6XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImltYWdlL3dlYnBcIjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWltZVR5cGUgPSB0ZXh0dXJlTWltZVR5cGUgYXMgSW1hZ2VNaW1lVHlwZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgVG9vbHMuV2FybihgVW5zdXBwb3J0ZWQgbWVkaWEgdHlwZTogJHt0ZXh0dXJlTWltZVR5cGV9YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBpbnRlcm5hbFRleHR1cmVUb0ltYWdlID0gdGhpcy5faW50ZXJuYWxUZXh0dXJlVG9JbWFnZTtcclxuICAgICAgICAgICAgY29uc3QgaW50ZXJuYWxUZXh0dXJlVW5pcXVlSWQgPSBiYWJ5bG9uVGV4dHVyZS5nZXRJbnRlcm5hbFRleHR1cmUoKSEudW5pcXVlSWQ7XHJcbiAgICAgICAgICAgIGludGVybmFsVGV4dHVyZVRvSW1hZ2VbaW50ZXJuYWxUZXh0dXJlVW5pcXVlSWRdIHx8PSB7fTtcclxuICAgICAgICAgICAgbGV0IGltYWdlSW5kZXhQcm9taXNlID0gaW50ZXJuYWxUZXh0dXJlVG9JbWFnZVtpbnRlcm5hbFRleHR1cmVVbmlxdWVJZF1bbWltZVR5cGVdO1xyXG4gICAgICAgICAgICBpZiAoaW1hZ2VJbmRleFByb21pc2UgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2l6ZSA9IGJhYnlsb25UZXh0dXJlLmdldFNpemUoKTtcclxuICAgICAgICAgICAgICAgIGltYWdlSW5kZXhQcm9taXNlID0gKGFzeW5jICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhpcy5fZ2V0SW1hZ2VEYXRhQXN5bmMocGl4ZWxzLCBzaXplLndpZHRoLCBzaXplLmhlaWdodCwgbWltZVR5cGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9leHBvcnRJbWFnZShiYWJ5bG9uVGV4dHVyZS5uYW1lLCBtaW1lVHlwZSwgZGF0YSk7XHJcbiAgICAgICAgICAgICAgICB9KSgpO1xyXG4gICAgICAgICAgICAgICAgaW50ZXJuYWxUZXh0dXJlVG9JbWFnZVtpbnRlcm5hbFRleHR1cmVVbmlxdWVJZF1bbWltZVR5cGVdID0gaW1hZ2VJbmRleFByb21pc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHRleHR1cmVJbmZvID0gdGhpcy5fZXhwb3J0VGV4dHVyZUluZm8oYXdhaXQgaW1hZ2VJbmRleFByb21pc2UsIHNhbXBsZXJJbmRleCwgYmFieWxvblRleHR1cmUuY29vcmRpbmF0ZXNJbmRleCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3RleHR1cmVNYXBbdGV4dHVyZVVpZF0gPSB0ZXh0dXJlSW5mbztcclxuICAgICAgICAgICAgdGhpcy5fZXhwb3J0ZXIuX2V4dGVuc2lvbnNQb3N0RXhwb3J0VGV4dHVyZXMoXCJleHBvcnRlclwiLCB0aGlzLl90ZXh0dXJlTWFwW3RleHR1cmVVaWRdLCBiYWJ5bG9uVGV4dHVyZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fdGV4dHVyZU1hcFt0ZXh0dXJlVWlkXTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9leHBvcnRJbWFnZShuYW1lOiBzdHJpbmcsIG1pbWVUeXBlOiBJbWFnZU1pbWVUeXBlLCBkYXRhOiBBcnJheUJ1ZmZlcik6IG51bWJlciB7XHJcbiAgICAgICAgY29uc3QgaW1hZ2VEYXRhID0gdGhpcy5fZXhwb3J0ZXIuX2ltYWdlRGF0YTtcclxuXHJcbiAgICAgICAgY29uc3QgYmFzZU5hbWUgPSBuYW1lLnJlcGxhY2UoL1xcLlxcL3xcXC98XFwuXFxcXHxcXFxcL2csIFwiX1wiKTtcclxuICAgICAgICBjb25zdCBleHRlbnNpb24gPSBnZXRGaWxlRXh0ZW5zaW9uRnJvbU1pbWVUeXBlKG1pbWVUeXBlKTtcclxuICAgICAgICBsZXQgZmlsZU5hbWUgPSBiYXNlTmFtZSArIGV4dGVuc2lvbjtcclxuICAgICAgICBpZiAoZmlsZU5hbWUgaW4gaW1hZ2VEYXRhKSB7XHJcbiAgICAgICAgICAgIGZpbGVOYW1lID0gYCR7YmFzZU5hbWV9XyR7VG9vbHMuUmFuZG9tSWQoKX0ke2V4dGVuc2lvbn1gO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaW1hZ2VEYXRhW2ZpbGVOYW1lXSA9IHtcclxuICAgICAgICAgICAgZGF0YTogZGF0YSxcclxuICAgICAgICAgICAgbWltZVR5cGU6IG1pbWVUeXBlLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGNvbnN0IGltYWdlcyA9IHRoaXMuX2V4cG9ydGVyLl9pbWFnZXM7XHJcbiAgICAgICAgaW1hZ2VzLnB1c2goe1xyXG4gICAgICAgICAgICBuYW1lOiBuYW1lLFxyXG4gICAgICAgICAgICB1cmk6IGZpbGVOYW1lLFxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gaW1hZ2VzLmxlbmd0aCAtIDE7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXhwb3J0VGV4dHVyZUluZm8oaW1hZ2VJbmRleDogbnVtYmVyLCBzYW1wbGVySW5kZXg6IG51bWJlciwgY29vcmRpbmF0ZXNJbmRleD86IG51bWJlcik6IElUZXh0dXJlSW5mbyB7XHJcbiAgICAgICAgY29uc3QgdGV4dHVyZXMgPSB0aGlzLl9leHBvcnRlci5fdGV4dHVyZXM7XHJcbiAgICAgICAgbGV0IHRleHR1cmVJbmRleCA9IHRleHR1cmVzLmZpbmRJbmRleCgodCkgPT4gdC5zYW1wbGVyID09IHNhbXBsZXJJbmRleCAmJiB0LnNvdXJjZSA9PT0gaW1hZ2VJbmRleCk7XHJcbiAgICAgICAgaWYgKHRleHR1cmVJbmRleCA9PT0gLTEpIHtcclxuICAgICAgICAgICAgdGV4dHVyZUluZGV4ID0gdGV4dHVyZXMubGVuZ3RoO1xyXG4gICAgICAgICAgICB0ZXh0dXJlcy5wdXNoKHtcclxuICAgICAgICAgICAgICAgIHNvdXJjZTogaW1hZ2VJbmRleCxcclxuICAgICAgICAgICAgICAgIHNhbXBsZXI6IHNhbXBsZXJJbmRleCxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB0ZXh0dXJlSW5mbzogSVRleHR1cmVJbmZvID0geyBpbmRleDogdGV4dHVyZUluZGV4IH07XHJcbiAgICAgICAgaWYgKGNvb3JkaW5hdGVzSW5kZXgpIHtcclxuICAgICAgICAgICAgdGV4dHVyZUluZm8udGV4Q29vcmQgPSBjb29yZGluYXRlc0luZGV4O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGV4dHVyZUluZm87XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXhwb3J0VGV4dHVyZVNhbXBsZXIodGV4dHVyZTogTnVsbGFibGU8QmFzZVRleHR1cmU+KTogbnVtYmVyIHtcclxuICAgICAgICBjb25zdCBzYW1wbGVyID0gdGhpcy5fZ2V0VGV4dHVyZVNhbXBsZXIodGV4dHVyZSk7XHJcblxyXG4gICAgICAgIC8vIGlmIGEgcHJlLWV4aXN0aW5nIHNhbXBsZXIgd2l0aCBpZGVudGljYWwgcGFyYW1ldGVycyBleGlzdHMsIHRoZW4gcmV1c2UgdGhlIHByZXZpb3VzIHNhbXBsZXJcclxuICAgICAgICBjb25zdCBzYW1wbGVycyA9IHRoaXMuX2V4cG9ydGVyLl9zYW1wbGVycztcclxuICAgICAgICBjb25zdCBzYW1wbGVySW5kZXggPSBzYW1wbGVycy5maW5kSW5kZXgoXHJcbiAgICAgICAgICAgIChzKSA9PiBzLm1pbkZpbHRlciA9PT0gc2FtcGxlci5taW5GaWx0ZXIgJiYgcy5tYWdGaWx0ZXIgPT09IHNhbXBsZXIubWFnRmlsdGVyICYmIHMud3JhcFMgPT09IHNhbXBsZXIud3JhcFMgJiYgcy53cmFwVCA9PT0gc2FtcGxlci53cmFwVFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgaWYgKHNhbXBsZXJJbmRleCAhPT0gLTEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZXJJbmRleDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHNhbXBsZXJzLnB1c2goc2FtcGxlcik7XHJcbiAgICAgICAgcmV0dXJuIHNhbXBsZXJzLmxlbmd0aCAtIDE7XHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSBcImNvcmUvbm9kZVwiO1xyXG5pbXBvcnQgdHlwZSB7IFNjZW5lIH0gZnJvbSBcImNvcmUvc2NlbmVcIjtcclxuaW1wb3J0IHR5cGUgeyBBbmltYXRpb24gfSBmcm9tIFwiY29yZS9BbmltYXRpb25zL2FuaW1hdGlvblwiO1xyXG5pbXBvcnQgdHlwZSB7IEdMVEZEYXRhIH0gZnJvbSBcIi4vZ2xURkRhdGFcIjtcclxuaW1wb3J0IHsgX0V4cG9ydGVyIH0gZnJvbSBcIi4vZ2xURkV4cG9ydGVyXCI7XHJcblxyXG4vKipcclxuICogSG9sZHMgYSBjb2xsZWN0aW9uIG9mIGV4cG9ydGVyIG9wdGlvbnMgYW5kIHBhcmFtZXRlcnNcclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUV4cG9ydE9wdGlvbnMge1xyXG4gICAgLyoqXHJcbiAgICAgKiBGdW5jdGlvbiB3aGljaCBpbmRpY2F0ZXMgd2hldGhlciBhIGJhYnlsb24gbm9kZSBzaG91bGQgYmUgZXhwb3J0ZWQgb3Igbm90XHJcbiAgICAgKiBAcGFyYW0gbm9kZSBzb3VyY2UgQmFieWxvbiBub2RlLiBJdCBpcyB1c2VkIHRvIGNoZWNrIHdoZXRoZXIgaXQgc2hvdWxkIGJlIGV4cG9ydGVkIHRvIGdsVEYgb3Igbm90XHJcbiAgICAgKiBAcmV0dXJucyBib29sZWFuLCB3aGljaCBpbmRpY2F0ZXMgd2hldGhlciB0aGUgbm9kZSBzaG91bGQgYmUgZXhwb3J0ZWQgKHRydWUpIG9yIG5vdCAoZmFsc2UpXHJcbiAgICAgKi9cclxuICAgIHNob3VsZEV4cG9ydE5vZGU/KG5vZGU6IE5vZGUpOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRnVuY3Rpb24gd2hpY2ggaW5kaWNhdGVzIHdoZXRoZXIgYW4gYW5pbWF0aW9uIG9uIHRoZSBzY2VuZSBzaG91bGQgYmUgZXhwb3J0ZWQgb3Igbm90XHJcbiAgICAgKiBAcGFyYW0gYW5pbWF0aW9uIHNvdXJjZSBhbmltYXRpb25cclxuICAgICAqIEByZXR1cm5zIGJvb2xlYW4sIHdoaWNoIGluZGljYXRlcyB3aGV0aGVyIHRoZSBhbmltYXRpb24gc2hvdWxkIGJlIGV4cG9ydGVkICh0cnVlKSBvciBub3QgKGZhbHNlKVxyXG4gICAgICovXHJcbiAgICBzaG91bGRFeHBvcnRBbmltYXRpb24/KGFuaW1hdGlvbjogQW5pbWF0aW9uKTogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZ1bmN0aW9uIHVzZWQgdG8gZXh0cmFjdCB0aGUgcGFydCBvZiBub2RlJ3MgbWV0YWRhdGEgdGhhdCB3aWxsIGJlIGV4cG9ydGVkIGludG8gZ2xURiBub2RlIGV4dHJhc1xyXG4gICAgICogQHBhcmFtIG1ldGFkYXRhIHNvdXJjZSBtZXRhZGF0YSB0byByZWFkIGZyb21cclxuICAgICAqIEByZXR1cm5zIHRoZSBkYXRhIHRvIHN0b3JlIHRvIGdsVEYgbm9kZSBleHRyYXNcclxuICAgICAqL1xyXG4gICAgbWV0YWRhdGFTZWxlY3Rvcj8obWV0YWRhdGE6IGFueSk6IGFueTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBzYW1wbGUgcmF0ZSB0byBiYWtlIGFuaW1hdGlvbiBjdXJ2ZXMuIERlZmF1bHRzIHRvIDEgLyA2MC5cclxuICAgICAqL1xyXG4gICAgYW5pbWF0aW9uU2FtcGxlUmF0ZT86IG51bWJlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEJlZ2luIHNlcmlhbGl6YXRpb24gd2l0aG91dCB3YWl0aW5nIGZvciB0aGUgc2NlbmUgdG8gYmUgcmVhZHkuIERlZmF1bHRzIHRvIGZhbHNlLlxyXG4gICAgICovXHJcbiAgICBleHBvcnRXaXRob3V0V2FpdGluZ0ZvclNjZW5lPzogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZGljYXRlcyBpZiB1bnVzZWQgdmVydGV4IHV2IGF0dHJpYnV0ZXMgc2hvdWxkIGJlIGluY2x1ZGVkIGluIGV4cG9ydC4gRGVmYXVsdHMgdG8gZmFsc2UuXHJcbiAgICAgKi9cclxuICAgIGV4cG9ydFVudXNlZFVWcz86IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmUgbm8tb3Agcm9vdCBub2RlcyB3aGVuIHBvc3NpYmxlLiBEZWZhdWx0cyB0byB0cnVlLlxyXG4gICAgICovXHJcbiAgICByZW1vdmVOb29wUm9vdE5vZGVzPzogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZGljYXRlcyBpZiBjb29yZGluYXRlIHN5c3RlbSBzd2FwcGluZyByb290IG5vZGVzIHNob3VsZCBiZSBpbmNsdWRlZCBpbiBleHBvcnQuIERlZmF1bHRzIHRvIGZhbHNlLlxyXG4gICAgICogQGRlcHJlY2F0ZWQgUGxlYXNlIHVzZSByZW1vdmVOb29wUm9vdE5vZGVzIGluc3RlYWRcclxuICAgICAqL1xyXG4gICAgaW5jbHVkZUNvb3JkaW5hdGVTeXN0ZW1Db252ZXJzaW9uTm9kZXM/OiBib29sZWFuO1xyXG59XHJcblxyXG4vKipcclxuICogQ2xhc3MgZm9yIGdlbmVyYXRpbmcgZ2xURiBkYXRhIGZyb20gYSBCYWJ5bG9uIHNjZW5lLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEdMVEYyRXhwb3J0IHtcclxuICAgIC8qKlxyXG4gICAgICogRXhwb3J0cyB0aGUgZ2VvbWV0cnkgb2YgdGhlIHNjZW5lIHRvIC5nbHRmIGZpbGUgZm9ybWF0IGFzeW5jaHJvbm91c2x5XHJcbiAgICAgKiBAcGFyYW0gc2NlbmUgQmFieWxvbiBzY2VuZSB3aXRoIHNjZW5lIGhpZXJhcmNoeSBpbmZvcm1hdGlvblxyXG4gICAgICogQHBhcmFtIGZpbGVQcmVmaXggRmlsZSBwcmVmaXggdG8gdXNlIHdoZW4gZ2VuZXJhdGluZyB0aGUgZ2xURiBmaWxlXHJcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBFeHBvcnRlciBvcHRpb25zXHJcbiAgICAgKiBAcmV0dXJucyBSZXR1cm5zIGFuIG9iamVjdCB3aXRoIGEgLmdsdGYgZmlsZSBhbmQgYXNzb2NpYXRlcyB0ZXh0dXJlIG5hbWVzXHJcbiAgICAgKiBhcyBrZXlzIGFuZCB0aGVpciBkYXRhIGFuZCBwYXRocyBhcyB2YWx1ZXNcclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBHTFRGQXN5bmMoc2NlbmU6IFNjZW5lLCBmaWxlUHJlZml4OiBzdHJpbmcsIG9wdGlvbnM/OiBJRXhwb3J0T3B0aW9ucyk6IFByb21pc2U8R0xURkRhdGE+IHtcclxuICAgICAgICByZXR1cm4gc2NlbmUud2hlblJlYWR5QXN5bmMoKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgZ2xURlByZWZpeCA9IGZpbGVQcmVmaXgucmVwbGFjZSgvXFwuW14vLl0rJC8sIFwiXCIpO1xyXG4gICAgICAgICAgICBjb25zdCBnbHRmR2VuZXJhdG9yID0gbmV3IF9FeHBvcnRlcihzY2VuZSwgb3B0aW9ucyk7XHJcbiAgICAgICAgICAgIHJldHVybiBnbHRmR2VuZXJhdG9yLl9nZW5lcmF0ZUdMVEZBc3luYyhnbFRGUHJlZml4KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfUHJlRXhwb3J0QXN5bmMoc2NlbmU6IFNjZW5lLCBvcHRpb25zPzogSUV4cG9ydE9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuZXhwb3J0V2l0aG91dFdhaXRpbmdGb3JTY2VuZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjZW5lLndoZW5SZWFkeUFzeW5jKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfUG9zdEV4cG9ydEFzeW5jKHNjZW5lOiBTY2VuZSwgZ2xURkRhdGE6IEdMVEZEYXRhLCBvcHRpb25zPzogSUV4cG9ydE9wdGlvbnMpOiBQcm9taXNlPEdMVEZEYXRhPiB7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmV4cG9ydFdpdGhvdXRXYWl0aW5nRm9yU2NlbmUpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBnbFRGRGF0YTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBnbFRGRGF0YTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXhwb3J0cyB0aGUgZ2VvbWV0cnkgb2YgdGhlIHNjZW5lIHRvIC5nbGIgZmlsZSBmb3JtYXQgYXN5Y2hyb25vdXNseVxyXG4gICAgICogQHBhcmFtIHNjZW5lIEJhYnlsb24gc2NlbmUgd2l0aCBzY2VuZSBoaWVyYXJjaHkgaW5mb3JtYXRpb25cclxuICAgICAqIEBwYXJhbSBmaWxlUHJlZml4IEZpbGUgcHJlZml4IHRvIHVzZSB3aGVuIGdlbmVyYXRpbmcgZ2xiIGZpbGVcclxuICAgICAqIEBwYXJhbSBvcHRpb25zIEV4cG9ydGVyIG9wdGlvbnNcclxuICAgICAqIEByZXR1cm5zIFJldHVybnMgYW4gb2JqZWN0IHdpdGggYSAuZ2xiIGZpbGVuYW1lIGFzIGtleSBhbmQgZGF0YSBhcyB2YWx1ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIEdMQkFzeW5jKHNjZW5lOiBTY2VuZSwgZmlsZVByZWZpeDogc3RyaW5nLCBvcHRpb25zPzogSUV4cG9ydE9wdGlvbnMpOiBQcm9taXNlPEdMVEZEYXRhPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX1ByZUV4cG9ydEFzeW5jKHNjZW5lLCBvcHRpb25zKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgZ2xURlByZWZpeCA9IGZpbGVQcmVmaXgucmVwbGFjZSgvXFwuW14vLl0rJC8sIFwiXCIpO1xyXG4gICAgICAgICAgICBjb25zdCBnbHRmR2VuZXJhdG9yID0gbmV3IF9FeHBvcnRlcihzY2VuZSwgb3B0aW9ucyk7XHJcbiAgICAgICAgICAgIHJldHVybiBnbHRmR2VuZXJhdG9yLl9nZW5lcmF0ZUdMQkFzeW5jKGdsVEZQcmVmaXgpLnRoZW4oKGdsVEZEYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fUG9zdEV4cG9ydEFzeW5jKHNjZW5lLCBnbFRGRGF0YSwgb3B0aW9ucyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB0eXBlIHsgSUJ1ZmZlclZpZXcsIEFjY2Vzc29yQ29tcG9uZW50VHlwZSwgSUFjY2Vzc29yIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyBBY2Nlc3NvclR5cGUgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IEZsb2F0QXJyYXksIE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBWZWN0b3I0IH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC52ZWN0b3JcIjtcclxuaW1wb3J0IHsgVmVjdG9yMyB9IGZyb20gXCJjb3JlL01hdGhzL21hdGgudmVjdG9yXCI7XHJcblxyXG4vKipcclxuICogQGludGVybmFsXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgX0dMVEZVdGlsaXRpZXMge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgYnVmZmVyIHZpZXcgYmFzZWQgb24gdGhlIHN1cHBsaWVkIGFyZ3VtZW50c1xyXG4gICAgICogQHBhcmFtIGJ1ZmZlckluZGV4IGluZGV4IHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgYnVmZmVyXHJcbiAgICAgKiBAcGFyYW0gYnl0ZU9mZnNldCBieXRlIG9mZnNldCB2YWx1ZVxyXG4gICAgICogQHBhcmFtIGJ5dGVMZW5ndGggYnl0ZSBsZW5ndGggb2YgdGhlIGJ1ZmZlclZpZXdcclxuICAgICAqIEBwYXJhbSBieXRlU3RyaWRlIGJ5dGUgZGlzdGFuY2UgYmV0d2VlbiBjb25lcXVlbnRpYWwgZWxlbWVudHNcclxuICAgICAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgdGhlIGJ1ZmZlciB2aWV3XHJcbiAgICAgKiBAcmV0dXJucyBidWZmZXJWaWV3IGZvciBnbFRGXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgX0NyZWF0ZUJ1ZmZlclZpZXcoYnVmZmVySW5kZXg6IG51bWJlciwgYnl0ZU9mZnNldDogbnVtYmVyLCBieXRlTGVuZ3RoOiBudW1iZXIsIGJ5dGVTdHJpZGU/OiBudW1iZXIsIG5hbWU/OiBzdHJpbmcpOiBJQnVmZmVyVmlldyB7XHJcbiAgICAgICAgY29uc3QgYnVmZmVydmlldzogSUJ1ZmZlclZpZXcgPSB7IGJ1ZmZlcjogYnVmZmVySW5kZXgsIGJ5dGVMZW5ndGg6IGJ5dGVMZW5ndGggfTtcclxuICAgICAgICBpZiAoYnl0ZU9mZnNldCkge1xyXG4gICAgICAgICAgICBidWZmZXJ2aWV3LmJ5dGVPZmZzZXQgPSBieXRlT2Zmc2V0O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAobmFtZSkge1xyXG4gICAgICAgICAgICBidWZmZXJ2aWV3Lm5hbWUgPSBuYW1lO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYnl0ZVN0cmlkZSkge1xyXG4gICAgICAgICAgICBidWZmZXJ2aWV3LmJ5dGVTdHJpZGUgPSBieXRlU3RyaWRlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGJ1ZmZlcnZpZXc7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGFuIGFjY2Vzc29yIGJhc2VkIG9uIHRoZSBzdXBwbGllZCBhcmd1bWVudHNcclxuICAgICAqIEBwYXJhbSBidWZmZXJ2aWV3SW5kZXggVGhlIGluZGV4IG9mIHRoZSBidWZmZXJ2aWV3IHJlZmVyZW5jZWQgYnkgdGhpcyBhY2Nlc3NvclxyXG4gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGFjY2Vzc29yXHJcbiAgICAgKiBAcGFyYW0gdHlwZSBUaGUgdHlwZSBvZiB0aGUgYWNjZXNzb3JcclxuICAgICAqIEBwYXJhbSBjb21wb25lbnRUeXBlIFRoZSBkYXRhdHlwZSBvZiBjb21wb25lbnRzIGluIHRoZSBhdHRyaWJ1dGVcclxuICAgICAqIEBwYXJhbSBjb3VudCBUaGUgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgcmVmZXJlbmNlZCBieSB0aGlzIGFjY2Vzc29yXHJcbiAgICAgKiBAcGFyYW0gYnl0ZU9mZnNldCBUaGUgb2Zmc2V0IHJlbGF0aXZlIHRvIHRoZSBzdGFydCBvZiB0aGUgYnVmZmVyVmlldyBpbiBieXRlc1xyXG4gICAgICogQHBhcmFtIG1pbiBNaW5pbXVtIHZhbHVlIG9mIGVhY2ggY29tcG9uZW50IGluIHRoaXMgYXR0cmlidXRlXHJcbiAgICAgKiBAcGFyYW0gbWF4IE1heGltdW0gdmFsdWUgb2YgZWFjaCBjb21wb25lbnQgaW4gdGhpcyBhdHRyaWJ1dGVcclxuICAgICAqIEByZXR1cm5zIGFjY2Vzc29yIGZvciBnbFRGXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgX0NyZWF0ZUFjY2Vzc29yKFxyXG4gICAgICAgIGJ1ZmZlcnZpZXdJbmRleDogbnVtYmVyLFxyXG4gICAgICAgIG5hbWU6IHN0cmluZyxcclxuICAgICAgICB0eXBlOiBBY2Nlc3NvclR5cGUsXHJcbiAgICAgICAgY29tcG9uZW50VHlwZTogQWNjZXNzb3JDb21wb25lbnRUeXBlLFxyXG4gICAgICAgIGNvdW50OiBudW1iZXIsXHJcbiAgICAgICAgYnl0ZU9mZnNldDogTnVsbGFibGU8bnVtYmVyPixcclxuICAgICAgICBtaW46IE51bGxhYmxlPG51bWJlcltdPixcclxuICAgICAgICBtYXg6IE51bGxhYmxlPG51bWJlcltdPlxyXG4gICAgKTogSUFjY2Vzc29yIHtcclxuICAgICAgICBjb25zdCBhY2Nlc3NvcjogSUFjY2Vzc29yID0geyBuYW1lOiBuYW1lLCBidWZmZXJWaWV3OiBidWZmZXJ2aWV3SW5kZXgsIGNvbXBvbmVudFR5cGU6IGNvbXBvbmVudFR5cGUsIGNvdW50OiBjb3VudCwgdHlwZTogdHlwZSB9O1xyXG5cclxuICAgICAgICBpZiAobWluICE9IG51bGwpIHtcclxuICAgICAgICAgICAgYWNjZXNzb3IubWluID0gbWluO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAobWF4ICE9IG51bGwpIHtcclxuICAgICAgICAgICAgYWNjZXNzb3IubWF4ID0gbWF4O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYnl0ZU9mZnNldCAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgIGFjY2Vzc29yLmJ5dGVPZmZzZXQgPSBieXRlT2Zmc2V0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGFjY2Vzc29yO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgbWluaW11bSBhbmQgbWF4aW11bSB2YWx1ZXMgb2YgYW4gYXJyYXkgb2YgcG9zaXRpb24gZmxvYXRzXHJcbiAgICAgKiBAcGFyYW0gcG9zaXRpb25zIFBvc2l0aW9ucyBhcnJheSBvZiBhIG1lc2hcclxuICAgICAqIEBwYXJhbSB2ZXJ0ZXhTdGFydCBTdGFydGluZyB2ZXJ0ZXggb2Zmc2V0IHRvIGNhbGN1bGF0ZSBtaW4gYW5kIG1heCB2YWx1ZXNcclxuICAgICAqIEBwYXJhbSB2ZXJ0ZXhDb3VudCBOdW1iZXIgb2YgdmVydGljZXMgdG8gY2hlY2sgZm9yIG1pbiBhbmQgbWF4IHZhbHVlc1xyXG4gICAgICogQHJldHVybnMgbWluIG51bWJlciBhcnJheSBhbmQgbWF4IG51bWJlciBhcnJheVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIF9DYWxjdWxhdGVNaW5NYXhQb3NpdGlvbnMocG9zaXRpb25zOiBGbG9hdEFycmF5LCB2ZXJ0ZXhTdGFydDogbnVtYmVyLCB2ZXJ0ZXhDb3VudDogbnVtYmVyKTogeyBtaW46IG51bWJlcltdOyBtYXg6IG51bWJlcltdIH0ge1xyXG4gICAgICAgIGNvbnN0IG1pbiA9IFtJbmZpbml0eSwgSW5maW5pdHksIEluZmluaXR5XTtcclxuICAgICAgICBjb25zdCBtYXggPSBbLUluZmluaXR5LCAtSW5maW5pdHksIC1JbmZpbml0eV07XHJcbiAgICAgICAgY29uc3QgcG9zaXRpb25TdHJpZGVTaXplID0gMztcclxuICAgICAgICBsZXQgaW5kZXhPZmZzZXQ6IG51bWJlcjtcclxuICAgICAgICBsZXQgcG9zaXRpb246IFZlY3RvcjM7XHJcbiAgICAgICAgbGV0IHZlY3RvcjogbnVtYmVyW107XHJcblxyXG4gICAgICAgIGlmICh2ZXJ0ZXhDb3VudCkge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gdmVydGV4U3RhcnQsIGxlbmd0aCA9IHZlcnRleFN0YXJ0ICsgdmVydGV4Q291bnQ7IGkgPCBsZW5ndGg7ICsraSkge1xyXG4gICAgICAgICAgICAgICAgaW5kZXhPZmZzZXQgPSBwb3NpdGlvblN0cmlkZVNpemUgKiBpO1xyXG5cclxuICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gVmVjdG9yMy5Gcm9tQXJyYXkocG9zaXRpb25zLCBpbmRleE9mZnNldCk7XHJcbiAgICAgICAgICAgICAgICB2ZWN0b3IgPSBwb3NpdGlvbi5hc0FycmF5KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBwb3NpdGlvblN0cmlkZVNpemU7ICsraikge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bSA9IHZlY3RvcltqXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobnVtIDwgbWluW2pdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbltqXSA9IG51bTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG51bSA+IG1heFtqXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXhbal0gPSBudW07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICsraW5kZXhPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHsgbWluLCBtYXggfTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhdGljIF9Ob3JtYWxpemVUYW5nZW50RnJvbVJlZih0YW5nZW50OiBWZWN0b3I0IHwgVmVjdG9yMykge1xyXG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGguc3FydCh0YW5nZW50LnggKiB0YW5nZW50LnggKyB0YW5nZW50LnkgKiB0YW5nZW50LnkgKyB0YW5nZW50LnogKiB0YW5nZW50LnopO1xyXG4gICAgICAgIGlmIChsZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIHRhbmdlbnQueCAvPSBsZW5ndGg7XHJcbiAgICAgICAgICAgIHRhbmdlbnQueSAvPSBsZW5ndGg7XHJcbiAgICAgICAgICAgIHRhbmdlbnQueiAvPSBsZW5ndGg7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzdGF0aWMgX0dldERhdGFBY2Nlc3NvckVsZW1lbnRDb3VudChhY2Nlc3NvclR5cGU6IEFjY2Vzc29yVHlwZSkge1xyXG4gICAgICAgIHN3aXRjaCAoYWNjZXNzb3JUeXBlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgQWNjZXNzb3JUeXBlLk1BVDI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gNDtcclxuICAgICAgICAgICAgY2FzZSBBY2Nlc3NvclR5cGUuTUFUMzpcclxuICAgICAgICAgICAgICAgIHJldHVybiA5O1xyXG4gICAgICAgICAgICBjYXNlIEFjY2Vzc29yVHlwZS5NQVQ0OlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIDE2O1xyXG4gICAgICAgICAgICBjYXNlIEFjY2Vzc29yVHlwZS5TQ0FMQVI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gMTtcclxuICAgICAgICAgICAgY2FzZSBBY2Nlc3NvclR5cGUuVkVDMjpcclxuICAgICAgICAgICAgICAgIHJldHVybiAyO1xyXG4gICAgICAgICAgICBjYXNlIEFjY2Vzc29yVHlwZS5WRUMzOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIDM7XHJcbiAgICAgICAgICAgIGNhc2UgQWNjZXNzb3JUeXBlLlZFQzQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gNDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWludGVybmFsLW1vZHVsZXMgKi9cclxuZXhwb3J0ICogZnJvbSBcIi4vZ2xURkFuaW1hdGlvblwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9nbFRGRGF0YVwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9nbFRGRXhwb3J0ZXJcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vZ2xURkV4cG9ydGVyRXh0ZW5zaW9uXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL2dsVEZNYXRlcmlhbEV4cG9ydGVyXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL2dsVEZTZXJpYWxpemVyXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL2dsVEZVdGlsaXRpZXNcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vRXh0ZW5zaW9ucy9pbmRleFwiO1xyXG4iLCIvKiogQGludGVybmFsICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby12YXIsIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgdmFyIF9fSUdMVEZFeHBvcnRlckV4dGVuc2lvbiA9IDA7IC8vIEkgYW0gaGVyZSB0byBhbGxvdyBkdHMgdG8gYmUgY3JlYXRlZFxyXG5cclxuLyoqXHJcbiAqIEludGVyZmFjZSBmb3IgZXh0ZW5kaW5nIHRoZSBleHBvcnRlclxyXG4gKiBAaW50ZXJuYWxcclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZFeHBvcnRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uXHJcbiAgICAgKi9cclxuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWRcclxuICAgICAqL1xyXG4gICAgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyByZXF1aXJlZFxyXG4gICAgICovXHJcbiAgICByZXF1aXJlZDogYm9vbGVhbjtcclxufVxyXG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvbm8taW50ZXJuYWwtbW9kdWxlcyAqL1xyXG5pbXBvcnQgKiBhcyBFeHBvcnRlcnMgZnJvbSBcInNlcmlhbGl6ZXJzL2dsVEYvZ2xURkZpbGVFeHBvcnRlclwiO1xyXG5pbXBvcnQgKiBhcyBEYXRhcyBmcm9tIFwic2VyaWFsaXplcnMvZ2xURi8yLjAvZ2xURkRhdGFcIjtcclxuaW1wb3J0ICogYXMgU2VyaWFsaXplcnMgZnJvbSBcInNlcmlhbGl6ZXJzL2dsVEYvMi4wL2dsVEZTZXJpYWxpemVyXCI7XHJcbmltcG9ydCAqIGFzIEV4dGVuc2lvbnMgZnJvbSBcInNlcmlhbGl6ZXJzL2dsVEYvMi4wL0V4dGVuc2lvbnMvaW5kZXhcIjtcclxuaW1wb3J0ICogYXMgR0xURjIgZnJvbSBcInNlcmlhbGl6ZXJzL2dsVEYvMi4wL2luZGV4XCI7XHJcblxyXG4vKipcclxuICogVGhpcyBpcyB0aGUgZW50cnkgcG9pbnQgZm9yIHRoZSBVTUQgbW9kdWxlLlxyXG4gKiBUaGUgZW50cnkgcG9pbnQgZm9yIGEgZnV0dXJlIEVTTSBwYWNrYWdlIHNob3VsZCBiZSBpbmRleC50c1xyXG4gKi9cclxuY29uc3QgZ2xvYmFsT2JqZWN0ID0gdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB1bmRlZmluZWQ7XHJcbmlmICh0eXBlb2YgZ2xvYmFsT2JqZWN0ICE9PSBcInVuZGVmaW5lZFwiKSB7XHJcbiAgICAoPGFueT5nbG9iYWxPYmplY3QpLkJBQllMT04gPSAoPGFueT5nbG9iYWxPYmplY3QpLkJBQllMT04gfHwge307XHJcbiAgICBjb25zdCBCQUJZTE9OID0gKDxhbnk+Z2xvYmFsT2JqZWN0KS5CQUJZTE9OO1xyXG4gICAgQkFCWUxPTi5HTFRGMiA9IEJBQllMT04uR0xURjIgfHwge307XHJcbiAgICBCQUJZTE9OLkdMVEYyLkV4cG9ydGVyID0gQkFCWUxPTi5HTFRGMi5FeHBvcnRlciB8fCB7fTtcclxuICAgIEJBQllMT04uR0xURjIuRXhwb3J0ZXIuRXh0ZW5zaW9ucyA9IEJBQllMT04uR0xURjIuRXhwb3J0ZXIuRXh0ZW5zaW9ucyB8fCB7fTtcclxuXHJcbiAgICBjb25zdCBrZXlzID0gW107XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBFeHBvcnRlcnMpIHtcclxuICAgICAgICBCQUJZTE9OW2tleV0gPSAoPGFueT5FeHBvcnRlcnMpW2tleV07XHJcbiAgICAgICAga2V5cy5wdXNoKGtleSk7XHJcbiAgICB9XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBEYXRhcykge1xyXG4gICAgICAgIEJBQllMT05ba2V5XSA9ICg8YW55PkRhdGFzKVtrZXldO1xyXG4gICAgICAgIGtleXMucHVzaChrZXkpO1xyXG4gICAgfVxyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gU2VyaWFsaXplcnMpIHtcclxuICAgICAgICBCQUJZTE9OW2tleV0gPSAoPGFueT5TZXJpYWxpemVycylba2V5XTtcclxuICAgICAgICBrZXlzLnB1c2goa2V5KTtcclxuICAgIH1cclxuXHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBFeHRlbnNpb25zKSB7XHJcbiAgICAgICAgQkFCWUxPTi5HTFRGMi5FeHBvcnRlci5FeHRlbnNpb25zW2tleV0gPSAoPGFueT5FeHRlbnNpb25zKVtrZXldO1xyXG4gICAgICAgIGtleXMucHVzaChrZXkpO1xyXG4gICAgfVxyXG5cclxuICAgIGZvciAoY29uc3Qga2V5IGluIEdMVEYyKSB7XHJcbiAgICAgICAgLy8gUHJldmVudCBSZWFzc2lnbm1lbnQuXHJcbiAgICAgICAgaWYgKGtleXMuaW5kZXhPZihrZXkpID4gLTEpIHtcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBCQUJZTE9OLkdMVEYyLkV4cG9ydGVyW2tleV0gPSAoPGFueT5HTFRGMilba2V5XTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0ICogZnJvbSBcInNlcmlhbGl6ZXJzL2dsVEYvZ2xURkZpbGVFeHBvcnRlclwiO1xyXG5leHBvcnQgKiBmcm9tIFwic2VyaWFsaXplcnMvZ2xURi8yLjAvaW5kZXhcIjtcclxuIiwibW9kdWxlLmV4cG9ydHMgPSBfX1dFQlBBQ0tfRVhURVJOQUxfTU9EVUxFX2JhYnlsb25qc19NYXRoc19tYXRoX3ZlY3Rvcl9fOyIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxuXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cblxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlLCBTdXBwcmVzc2VkRXJyb3IsIFN5bWJvbCwgSXRlcmF0b3IgKi9cblxudmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbihkLCBiKSB7XG4gIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcbiAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcbiAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07IH07XG4gIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XG4gIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2xhc3MgZXh0ZW5kcyB2YWx1ZSBcIiArIFN0cmluZyhiKSArIFwiIGlzIG5vdCBhIGNvbnN0cnVjdG9yIG9yIG51bGxcIik7XG4gIGV4dGVuZFN0YXRpY3MoZCwgYik7XG4gIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxuICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG59XG5cbmV4cG9ydCB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcbiAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcbiAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xuICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XG4gICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0O1xuICB9XG4gIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcbiAgdmFyIHQgPSB7fTtcbiAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXG4gICAgICB0W3BdID0gc1twXTtcbiAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxuICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcbiAgICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XG4gICAgICB9XG4gIHJldHVybiB0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xuICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xuICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xuICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xuICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHIpLCByO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19wYXJhbShwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2VzRGVjb3JhdGUoY3RvciwgZGVzY3JpcHRvckluLCBkZWNvcmF0b3JzLCBjb250ZXh0SW4sIGluaXRpYWxpemVycywgZXh0cmFJbml0aWFsaXplcnMpIHtcbiAgZnVuY3Rpb24gYWNjZXB0KGYpIHsgaWYgKGYgIT09IHZvaWQgMCAmJiB0eXBlb2YgZiAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRnVuY3Rpb24gZXhwZWN0ZWRcIik7IHJldHVybiBmOyB9XG4gIHZhciBraW5kID0gY29udGV4dEluLmtpbmQsIGtleSA9IGtpbmQgPT09IFwiZ2V0dGVyXCIgPyBcImdldFwiIDoga2luZCA9PT0gXCJzZXR0ZXJcIiA/IFwic2V0XCIgOiBcInZhbHVlXCI7XG4gIHZhciB0YXJnZXQgPSAhZGVzY3JpcHRvckluICYmIGN0b3IgPyBjb250ZXh0SW5bXCJzdGF0aWNcIl0gPyBjdG9yIDogY3Rvci5wcm90b3R5cGUgOiBudWxsO1xuICB2YXIgZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JJbiB8fCAodGFyZ2V0ID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGNvbnRleHRJbi5uYW1lKSA6IHt9KTtcbiAgdmFyIF8sIGRvbmUgPSBmYWxzZTtcbiAgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciBjb250ZXh0ID0ge307XG4gICAgICBmb3IgKHZhciBwIGluIGNvbnRleHRJbikgY29udGV4dFtwXSA9IHAgPT09IFwiYWNjZXNzXCIgPyB7fSA6IGNvbnRleHRJbltwXTtcbiAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluLmFjY2VzcykgY29udGV4dC5hY2Nlc3NbcF0gPSBjb250ZXh0SW4uYWNjZXNzW3BdO1xuICAgICAgY29udGV4dC5hZGRJbml0aWFsaXplciA9IGZ1bmN0aW9uIChmKSB7IGlmIChkb25lKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGFkZCBpbml0aWFsaXplcnMgYWZ0ZXIgZGVjb3JhdGlvbiBoYXMgY29tcGxldGVkXCIpOyBleHRyYUluaXRpYWxpemVycy5wdXNoKGFjY2VwdChmIHx8IG51bGwpKTsgfTtcbiAgICAgIHZhciByZXN1bHQgPSAoMCwgZGVjb3JhdG9yc1tpXSkoa2luZCA9PT0gXCJhY2Nlc3NvclwiID8geyBnZXQ6IGRlc2NyaXB0b3IuZ2V0LCBzZXQ6IGRlc2NyaXB0b3Iuc2V0IH0gOiBkZXNjcmlwdG9yW2tleV0sIGNvbnRleHQpO1xuICAgICAgaWYgKGtpbmQgPT09IFwiYWNjZXNzb3JcIikge1xuICAgICAgICAgIGlmIChyZXN1bHQgPT09IHZvaWQgMCkgY29udGludWU7XG4gICAgICAgICAgaWYgKHJlc3VsdCA9PT0gbnVsbCB8fCB0eXBlb2YgcmVzdWx0ICE9PSBcIm9iamVjdFwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5nZXQpKSBkZXNjcmlwdG9yLmdldCA9IF87XG4gICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LnNldCkpIGRlc2NyaXB0b3Iuc2V0ID0gXztcbiAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuaW5pdCkpIGluaXRpYWxpemVycy51bnNoaWZ0KF8pO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoXyA9IGFjY2VwdChyZXN1bHQpKSB7XG4gICAgICAgICAgaWYgKGtpbmQgPT09IFwiZmllbGRcIikgaW5pdGlhbGl6ZXJzLnVuc2hpZnQoXyk7XG4gICAgICAgICAgZWxzZSBkZXNjcmlwdG9yW2tleV0gPSBfO1xuICAgICAgfVxuICB9XG4gIGlmICh0YXJnZXQpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGNvbnRleHRJbi5uYW1lLCBkZXNjcmlwdG9yKTtcbiAgZG9uZSA9IHRydWU7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gX19ydW5Jbml0aWFsaXplcnModGhpc0FyZywgaW5pdGlhbGl6ZXJzLCB2YWx1ZSkge1xuICB2YXIgdXNlVmFsdWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMjtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbml0aWFsaXplcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhbHVlID0gdXNlVmFsdWUgPyBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnLCB2YWx1ZSkgOiBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnKTtcbiAgfVxuICByZXR1cm4gdXNlVmFsdWUgPyB2YWx1ZSA6IHZvaWQgMDtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBfX3Byb3BLZXkoeCkge1xuICByZXR1cm4gdHlwZW9mIHggPT09IFwic3ltYm9sXCIgPyB4IDogXCJcIi5jb25jYXQoeCk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gX19zZXRGdW5jdGlvbk5hbWUoZiwgbmFtZSwgcHJlZml4KSB7XG4gIGlmICh0eXBlb2YgbmFtZSA9PT0gXCJzeW1ib2xcIikgbmFtZSA9IG5hbWUuZGVzY3JpcHRpb24gPyBcIltcIi5jb25jYXQobmFtZS5kZXNjcmlwdGlvbiwgXCJdXCIpIDogXCJcIjtcbiAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmLCBcIm5hbWVcIiwgeyBjb25maWd1cmFibGU6IHRydWUsIHZhbHVlOiBwcmVmaXggPyBcIlwiLmNvbmNhdChwcmVmaXgsIFwiIFwiLCBuYW1lKSA6IG5hbWUgfSk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xuICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xuICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH1cbiAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cbiAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XG4gICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xuICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnID0gT2JqZWN0LmNyZWF0ZSgodHlwZW9mIEl0ZXJhdG9yID09PSBcImZ1bmN0aW9uXCIgPyBJdGVyYXRvciA6IE9iamVjdCkucHJvdG90eXBlKTtcbiAgcmV0dXJuIGcubmV4dCA9IHZlcmIoMCksIGdbXCJ0aHJvd1wiXSA9IHZlcmIoMSksIGdbXCJyZXR1cm5cIl0gPSB2ZXJiKDIpLCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XG4gIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxuICBmdW5jdGlvbiBzdGVwKG9wKSB7XG4gICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XG4gICAgICB3aGlsZSAoZyAmJiAoZyA9IDAsIG9wWzBdICYmIChfID0gMCkpLCBfKSB0cnkge1xuICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcbiAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XG4gICAgICAgICAgc3dpdGNoIChvcFswXSkge1xuICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcbiAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xuICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cbiAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cbiAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cbiAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcbiAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xuICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxuICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XG4gIH1cbn1cblxuZXhwb3J0IHZhciBfX2NyZWF0ZUJpbmRpbmcgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG4gIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG4gIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcbiAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcbiAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG4gIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG4gIG9bazJdID0gbVtrXTtcbn0pO1xuXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIG8pIHtcbiAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBwKSkgX19jcmVhdGVCaW5kaW5nKG8sIG0sIHApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xuICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xuICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcbiAgaWYgKG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSByZXR1cm4ge1xuICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XG4gICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xuICAgICAgfVxuICB9O1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKHMgPyBcIk9iamVjdCBpcyBub3QgaXRlcmFibGUuXCIgOiBcIlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xuICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XG4gIGlmICghbSkgcmV0dXJuIG87XG4gIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xuICB0cnkge1xuICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XG4gIH1cbiAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XG4gIGZpbmFsbHkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcbiAgICAgIH1cbiAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxuICB9XG4gIHJldHVybiBhcjtcbn1cblxuLyoqIEBkZXByZWNhdGVkICovXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XG4gIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxuICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xuICByZXR1cm4gYXI7XG59XG5cbi8qKiBAZGVwcmVjYXRlZCAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXlzKCkge1xuICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcbiAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxuICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXG4gICAgICAgICAgcltrXSA9IGFbal07XG4gIHJldHVybiByO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheSh0bywgZnJvbSwgcGFjaykge1xuICBpZiAocGFjayB8fCBhcmd1bWVudHMubGVuZ3RoID09PSAyKSBmb3IgKHZhciBpID0gMCwgbCA9IGZyb20ubGVuZ3RoLCBhcjsgaSA8IGw7IGkrKykge1xuICAgICAgaWYgKGFyIHx8ICEoaSBpbiBmcm9tKSkge1xuICAgICAgICAgIGlmICghYXIpIGFyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSwgMCwgaSk7XG4gICAgICAgICAgYXJbaV0gPSBmcm9tW2ldO1xuICAgICAgfVxuICB9XG4gIHJldHVybiB0by5jb25jYXQoYXIgfHwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XG4gIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcbiAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcbiAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcbiAgcmV0dXJuIGkgPSBPYmplY3QuY3JlYXRlKCh0eXBlb2YgQXN5bmNJdGVyYXRvciA9PT0gXCJmdW5jdGlvblwiID8gQXN5bmNJdGVyYXRvciA6IE9iamVjdCkucHJvdG90eXBlKSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiLCBhd2FpdFJldHVybiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcbiAgZnVuY3Rpb24gYXdhaXRSZXR1cm4oZikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGYsIHJlamVjdCk7IH07IH1cbiAgZnVuY3Rpb24gdmVyYihuLCBmKSB7IGlmIChnW25dKSB7IGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IGlmIChmKSBpW25dID0gZihpW25dKTsgfSB9XG4gIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cbiAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XG4gIGZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHsgcmVzdW1lKFwibmV4dFwiLCB2YWx1ZSk7IH1cbiAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxuICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcbiAgdmFyIGksIHA7XG4gIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XG4gIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IGZhbHNlIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcbiAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcbiAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcbiAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xuICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XG4gIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XG4gIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XG4gIHJldHVybiBjb29rZWQ7XG59O1xuXG52YXIgX19zZXRNb2R1bGVEZWZhdWx0ID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBcImRlZmF1bHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdiB9KTtcbn0pIDogZnVuY3Rpb24obywgdikge1xuICBvW1wiZGVmYXVsdFwiXSA9IHY7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xuICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xuICB2YXIgcmVzdWx0ID0ge307XG4gIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChrICE9PSBcImRlZmF1bHRcIiAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgX19jcmVhdGVCaW5kaW5nKHJlc3VsdCwgbW9kLCBrKTtcbiAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcbiAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBkZWZhdWx0OiBtb2QgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRHZXQocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XG4gIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEluKHN0YXRlLCByZWNlaXZlcikge1xuICBpZiAocmVjZWl2ZXIgPT09IG51bGwgfHwgKHR5cGVvZiByZWNlaXZlciAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcmVjZWl2ZXIgIT09IFwiZnVuY3Rpb25cIikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgdXNlICdpbicgb3BlcmF0b3Igb24gbm9uLW9iamVjdFwiKTtcbiAgcmV0dXJuIHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgPT09IHN0YXRlIDogc3RhdGUuaGFzKHJlY2VpdmVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fYWRkRGlzcG9zYWJsZVJlc291cmNlKGVudiwgdmFsdWUsIGFzeW5jKSB7XG4gIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdm9pZCAwKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZC5cIik7XG4gICAgdmFyIGRpc3Bvc2UsIGlubmVyO1xuICAgIGlmIChhc3luYykge1xuICAgICAgaWYgKCFTeW1ib2wuYXN5bmNEaXNwb3NlKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jRGlzcG9zZSBpcyBub3QgZGVmaW5lZC5cIik7XG4gICAgICBkaXNwb3NlID0gdmFsdWVbU3ltYm9sLmFzeW5jRGlzcG9zZV07XG4gICAgfVxuICAgIGlmIChkaXNwb3NlID09PSB2b2lkIDApIHtcbiAgICAgIGlmICghU3ltYm9sLmRpc3Bvc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuZGlzcG9zZSBpcyBub3QgZGVmaW5lZC5cIik7XG4gICAgICBkaXNwb3NlID0gdmFsdWVbU3ltYm9sLmRpc3Bvc2VdO1xuICAgICAgaWYgKGFzeW5jKSBpbm5lciA9IGRpc3Bvc2U7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZGlzcG9zZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IG5vdCBkaXNwb3NhYmxlLlwiKTtcbiAgICBpZiAoaW5uZXIpIGRpc3Bvc2UgPSBmdW5jdGlvbigpIHsgdHJ5IHsgaW5uZXIuY2FsbCh0aGlzKTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7IH0gfTtcbiAgICBlbnYuc3RhY2sucHVzaCh7IHZhbHVlOiB2YWx1ZSwgZGlzcG9zZTogZGlzcG9zZSwgYXN5bmM6IGFzeW5jIH0pO1xuICB9XG4gIGVsc2UgaWYgKGFzeW5jKSB7XG4gICAgZW52LnN0YWNrLnB1c2goeyBhc3luYzogdHJ1ZSB9KTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbnZhciBfU3VwcHJlc3NlZEVycm9yID0gdHlwZW9mIFN1cHByZXNzZWRFcnJvciA9PT0gXCJmdW5jdGlvblwiID8gU3VwcHJlc3NlZEVycm9yIDogZnVuY3Rpb24gKGVycm9yLCBzdXBwcmVzc2VkLCBtZXNzYWdlKSB7XG4gIHZhciBlID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xuICByZXR1cm4gZS5uYW1lID0gXCJTdXBwcmVzc2VkRXJyb3JcIiwgZS5lcnJvciA9IGVycm9yLCBlLnN1cHByZXNzZWQgPSBzdXBwcmVzc2VkLCBlO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9fZGlzcG9zZVJlc291cmNlcyhlbnYpIHtcbiAgZnVuY3Rpb24gZmFpbChlKSB7XG4gICAgZW52LmVycm9yID0gZW52Lmhhc0Vycm9yID8gbmV3IF9TdXBwcmVzc2VkRXJyb3IoZSwgZW52LmVycm9yLCBcIkFuIGVycm9yIHdhcyBzdXBwcmVzc2VkIGR1cmluZyBkaXNwb3NhbC5cIikgOiBlO1xuICAgIGVudi5oYXNFcnJvciA9IHRydWU7XG4gIH1cbiAgdmFyIHIsIHMgPSAwO1xuICBmdW5jdGlvbiBuZXh0KCkge1xuICAgIHdoaWxlIChyID0gZW52LnN0YWNrLnBvcCgpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoIXIuYXN5bmMgJiYgcyA9PT0gMSkgcmV0dXJuIHMgPSAwLCBlbnYuc3RhY2sucHVzaChyKSwgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihuZXh0KTtcbiAgICAgICAgaWYgKHIuZGlzcG9zZSkge1xuICAgICAgICAgIHZhciByZXN1bHQgPSByLmRpc3Bvc2UuY2FsbChyLnZhbHVlKTtcbiAgICAgICAgICBpZiAoci5hc3luYykgcmV0dXJuIHMgfD0gMiwgUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCkudGhlbihuZXh0LCBmdW5jdGlvbihlKSB7IGZhaWwoZSk7IHJldHVybiBuZXh0KCk7IH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgcyB8PSAxO1xuICAgICAgfVxuICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgZmFpbChlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHMgPT09IDEpIHJldHVybiBlbnYuaGFzRXJyb3IgPyBQcm9taXNlLnJlamVjdChlbnYuZXJyb3IpIDogUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgaWYgKGVudi5oYXNFcnJvcikgdGhyb3cgZW52LmVycm9yO1xuICB9XG4gIHJldHVybiBuZXh0KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX3Jld3JpdGVSZWxhdGl2ZUltcG9ydEV4dGVuc2lvbihwYXRoLCBwcmVzZXJ2ZUpzeCkge1xuICBpZiAodHlwZW9mIHBhdGggPT09IFwic3RyaW5nXCIgJiYgL15cXC5cXC4/XFwvLy50ZXN0KHBhdGgpKSB7XG4gICAgICByZXR1cm4gcGF0aC5yZXBsYWNlKC9cXC4odHN4KSR8KCg/OlxcLmQpPykoKD86XFwuW14uL10rPyk/KVxcLihbY21dPyl0cyQvaSwgZnVuY3Rpb24gKG0sIHRzeCwgZCwgZXh0LCBjbSkge1xuICAgICAgICAgIHJldHVybiB0c3ggPyBwcmVzZXJ2ZUpzeCA/IFwiLmpzeFwiIDogXCIuanNcIiA6IGQgJiYgKCFleHQgfHwgIWNtKSA/IG0gOiAoZCArIGV4dCArIFwiLlwiICsgY20udG9Mb3dlckNhc2UoKSArIFwianNcIik7XG4gICAgICB9KTtcbiAgfVxuICByZXR1cm4gcGF0aDtcbn1cblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2V4dGVuZHMsXG4gIF9fYXNzaWduLFxuICBfX3Jlc3QsXG4gIF9fZGVjb3JhdGUsXG4gIF9fcGFyYW0sXG4gIF9fZXNEZWNvcmF0ZSxcbiAgX19ydW5Jbml0aWFsaXplcnMsXG4gIF9fcHJvcEtleSxcbiAgX19zZXRGdW5jdGlvbk5hbWUsXG4gIF9fbWV0YWRhdGEsXG4gIF9fYXdhaXRlcixcbiAgX19nZW5lcmF0b3IsXG4gIF9fY3JlYXRlQmluZGluZyxcbiAgX19leHBvcnRTdGFyLFxuICBfX3ZhbHVlcyxcbiAgX19yZWFkLFxuICBfX3NwcmVhZCxcbiAgX19zcHJlYWRBcnJheXMsXG4gIF9fc3ByZWFkQXJyYXksXG4gIF9fYXdhaXQsXG4gIF9fYXN5bmNHZW5lcmF0b3IsXG4gIF9fYXN5bmNEZWxlZ2F0b3IsXG4gIF9fYXN5bmNWYWx1ZXMsXG4gIF9fbWFrZVRlbXBsYXRlT2JqZWN0LFxuICBfX2ltcG9ydFN0YXIsXG4gIF9faW1wb3J0RGVmYXVsdCxcbiAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCxcbiAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCxcbiAgX19jbGFzc1ByaXZhdGVGaWVsZEluLFxuICBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZSxcbiAgX19kaXNwb3NlUmVzb3VyY2VzLFxuICBfX3Jld3JpdGVSZWxhdGl2ZUltcG9ydEV4dGVuc2lvbixcbn07XG4iLCIvLyBUaGUgbW9kdWxlIGNhY2hlXG52YXIgX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fID0ge307XG5cbi8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG5mdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuXHR2YXIgY2FjaGVkTW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXTtcblx0aWYgKGNhY2hlZE1vZHVsZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIGNhY2hlZE1vZHVsZS5leHBvcnRzO1xuXHR9XG5cdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG5cdHZhciBtb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdID0ge1xuXHRcdC8vIG5vIG1vZHVsZS5pZCBuZWVkZWRcblx0XHQvLyBubyBtb2R1bGUubG9hZGVkIG5lZWRlZFxuXHRcdGV4cG9ydHM6IHt9XG5cdH07XG5cblx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG5cdF9fd2VicGFja19tb2R1bGVzX19bbW9kdWxlSWRdKG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuIiwiLy8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbl9fd2VicGFja19yZXF1aXJlX18ubiA9IChtb2R1bGUpID0+IHtcblx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG5cdFx0KCkgPT4gKG1vZHVsZVsnZGVmYXVsdCddKSA6XG5cdFx0KCkgPT4gKG1vZHVsZSk7XG5cdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsIHsgYTogZ2V0dGVyIH0pO1xuXHRyZXR1cm4gZ2V0dGVyO1xufTsiLCIvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9ucyBmb3IgaGFybW9ueSBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSAoZXhwb3J0cywgZGVmaW5pdGlvbikgPT4ge1xuXHRmb3IodmFyIGtleSBpbiBkZWZpbml0aW9uKSB7XG5cdFx0aWYoX193ZWJwYWNrX3JlcXVpcmVfXy5vKGRlZmluaXRpb24sIGtleSkgJiYgIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBrZXkpKSB7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywga2V5LCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZGVmaW5pdGlvbltrZXldIH0pO1xuXHRcdH1cblx0fVxufTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLmcgPSAoZnVuY3Rpb24oKSB7XG5cdGlmICh0eXBlb2YgZ2xvYmFsVGhpcyA9PT0gJ29iamVjdCcpIHJldHVybiBnbG9iYWxUaGlzO1xuXHR0cnkge1xuXHRcdHJldHVybiB0aGlzIHx8IG5ldyBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0aWYgKHR5cGVvZiB3aW5kb3cgPT09ICdvYmplY3QnKSByZXR1cm4gd2luZG93O1xuXHR9XG59KSgpOyIsIl9fd2VicGFja19yZXF1aXJlX18ubyA9IChvYmosIHByb3ApID0+IChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKSkiLCIvLyBkZWZpbmUgX19lc01vZHVsZSBvbiBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSAoZXhwb3J0cykgPT4ge1xuXHRpZih0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcpIHtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcblx0fVxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xufTsiLCJpbXBvcnQgKiBhcyBzZXJpYWxpemVycyBmcm9tIFwiQGx0cy9zZXJpYWxpemVycy9sZWdhY3kvbGVnYWN5LWdsVEYyU2VyaWFsaXplclwiO1xyXG5leHBvcnQgeyBzZXJpYWxpemVycyB9O1xyXG5leHBvcnQgZGVmYXVsdCBzZXJpYWxpemVycztcclxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/libs/babylonjs/7.35.0/babylon.glTF2Serializer.min.js b/libs/babylonjs/7.35.0/babylon.glTF2Serializer.min.js new file mode 100644 index 00000000..20461dc1 --- /dev/null +++ b/libs/babylonjs/7.35.0/babylon.glTF2Serializer.min.js @@ -0,0 +1,2 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("babylonjs")):"function"==typeof define&&define.amd?define("babylonjs-serializers",["babylonjs"],t):"object"==typeof exports?exports["babylonjs-serializers"]=t(require("babylonjs")):e.SERIALIZERS=t(e.BABYLON)}("undefined"!=typeof self?self:"undefined"!=typeof global?global:this,(e=>(()=>{"use strict";var t={597:t=>{t.exports=e}},r={};function n(e){var i=r[e];if(void 0!==i)return i.exports;var o=r[e]={exports:{}};return t[e](o,o.exports,n),o.exports}n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var i={};n.d(i,{default:()=>le});var o={};n.r(o),n.d(o,{__IGLTFExporterExtension:()=>f});var a={};n.r(a),n.d(a,{GLTFData:()=>h});var s={};n.r(s),n.d(s,{GLTF2Export:()=>w});var u={};n.r(u),n.d(u,{EXT_mesh_gpu_instancing:()=>$,KHR_lights_punctual:()=>S,KHR_materials_anisotropy:()=>O,KHR_materials_clearcoat:()=>B,KHR_materials_diffuse_transmission:()=>ne,KHR_materials_dispersion:()=>Y,KHR_materials_emissive_strength:()=>te,KHR_materials_ior:()=>z,KHR_materials_iridescence:()=>N,KHR_materials_sheen:()=>k,KHR_materials_specular:()=>q,KHR_materials_transmission:()=>Z,KHR_materials_unlit:()=>D,KHR_materials_volume:()=>j,KHR_texture_transform:()=>C});var l={};n.r(l),n.d(l,{EXT_mesh_gpu_instancing:()=>$,GLTF2Export:()=>w,GLTFData:()=>h,KHR_lights_punctual:()=>S,KHR_materials_anisotropy:()=>O,KHR_materials_clearcoat:()=>B,KHR_materials_diffuse_transmission:()=>ne,KHR_materials_dispersion:()=>Y,KHR_materials_emissive_strength:()=>te,KHR_materials_ior:()=>z,KHR_materials_iridescence:()=>N,KHR_materials_sheen:()=>k,KHR_materials_specular:()=>q,KHR_materials_transmission:()=>Z,KHR_materials_unlit:()=>D,KHR_materials_volume:()=>j,KHR_texture_transform:()=>C,_BinaryWriter:()=>F,_Exporter:()=>M,_GLTFAnimation:()=>T,_GLTFMaterialExporter:()=>x,_GLTFUtilities:()=>y,__IGLTFExporterExtensionV2:()=>ie});var c={};n.r(c),n.d(c,{EXT_mesh_gpu_instancing:()=>$,GLTF2Export:()=>w,GLTFData:()=>h,KHR_lights_punctual:()=>S,KHR_materials_anisotropy:()=>O,KHR_materials_clearcoat:()=>B,KHR_materials_diffuse_transmission:()=>ne,KHR_materials_dispersion:()=>Y,KHR_materials_emissive_strength:()=>te,KHR_materials_ior:()=>z,KHR_materials_iridescence:()=>N,KHR_materials_sheen:()=>k,KHR_materials_specular:()=>q,KHR_materials_transmission:()=>Z,KHR_materials_unlit:()=>D,KHR_materials_volume:()=>j,KHR_texture_transform:()=>C,_BinaryWriter:()=>F,_Exporter:()=>M,_GLTFAnimation:()=>T,_GLTFMaterialExporter:()=>x,_GLTFUtilities:()=>y,__IGLTFExporterExtension:()=>f,__IGLTFExporterExtensionV2:()=>ie});var f=0,h=function(){function e(){this.glTFFiles={}}return e.prototype.downloadFiles=function(){function e(e,t){return-1!==e.indexOf(t,e.length-t.length)}for(var t in this.glTFFiles){var r=document.createElement("a");document.body.appendChild(r),r.setAttribute("type","hidden"),r.download=t;var n=this.glTFFiles[t],i=void 0;e(t,".glb")?i={type:"model/gltf-binary"}:e(t,".bin")?i={type:"application/octet-stream"}:e(t,".gltf")?i={type:"model/gltf+json"}:e(t,".jpeg")||e(t,".jpg")?i={type:"image/jpeg"}:e(t,".png")&&(i={type:"image/png"}),r.href=window.URL.createObjectURL(new Blob([n],i)),r.click()}},e}();function p(e,t,r,n){return new(r||(r=Promise))((function(i,o){function a(e){try{u(n.next(e))}catch(e){o(e)}}function s(e){try{u(n.throw(e))}catch(e){o(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(a,s)}u((n=n.apply(e,t||[])).next())}))}function d(e,t){var r,n,i,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]},a=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return a.next=s(0),a.throw=s(1),a.return=s(2),"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(u){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(o=0)),o;)try{if(r=1,n&&(i=2&s[0]?n.return:s[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,s[1])).done)return i;switch(n=0,i&&(s=[2&s[0],i.value]),s[0]){case 0:case 1:i=s;break;case 4:return o.label++,{value:s[1],done:!1};case 5:o.label++,n=s[1],s=[0];continue;case 7:s=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==s[0]&&2!==s[0])){o=0;continue}if(3===s[0]&&(!i||s[1]>i[0]&&s[1]a.width?(i=t&&t instanceof m.Texture?m.TextureTools.CreateResizedCopy(t,o.width,o.height,!0):this._createWhiteTexture(o.width,o.height,r),n=e):(n=e,i=t),{texture1:n,texture2:i}},e.prototype._convertPixelArrayToFloat32=function(e){if(e instanceof Uint8Array){for(var t=e.length,r=new Float32Array(e.length),n=0;ne._Epsilon?C.baseColor.r:1,y[P+1]/=C.baseColor.g>e._Epsilon?C.baseColor.g:1,y[P+2]/=C.baseColor.b>e._Epsilon?C.baseColor.b:1,N=m.Color3.FromInts(y[P],y[P+1],y[P+2]),L=N.toGammaSpace(a.getEngine().useExactSrgbConversions),y[P]=255*L.r,y[P+1]=255*L.g,y[P+2]=255*L.b,e._FuzzyEquals(L,m.Color3.White(),e._Epsilon)||(S=!0),x[P+1]/=C.roughness>e._Epsilon?C.roughness:1,x[P+2]/=C.metallic>e._Epsilon?C.metallic:1,O=m.Color3.FromInts(255,x[P+1],x[P+2]),e._FuzzyEquals(O,m.Color3.White(),e._Epsilon)||(V=!0);return V&&o.push(this._getImageDataAsync(x,f,h,i).then((function(e){C.metallicRoughnessTextureData=e}))),S&&o.push(this._getImageDataAsync(y,f,h,i).then((function(e){C.baseColorTextureData=e}))),[2,Promise.all(o).then((function(){return C}))];case 3:return[2,Promise.reject("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!")]}}))}))},e.prototype._convertSpecularGlossinessToMetallicRoughness=function(t){var r=this._getPerceivedBrightness(t.diffuseColor),n=this._getPerceivedBrightness(t.specularColor),i=1-this._getMaxComponent(t.specularColor),o=e._SolveMetallic(r,n,i),a=t.diffuseColor.scale(i/(1-e._DielectricSpecular.r)/Math.max(1-o,e._Epsilon)),s=t.specularColor.subtract(e._DielectricSpecular.scale(1-o)).scale(1/Math.max(o,e._Epsilon)),u=m.Color3.Lerp(a,s,o*o);return{baseColor:u=u.clampToRef(0,1,u),metallic:o,roughness:1-t.glossiness}},e.prototype._getPerceivedBrightness=function(e){return e?Math.sqrt(.299*e.r*e.r+.587*e.g*e.g+.114*e.b*e.b):0},e.prototype._getMaxComponent=function(e){return e?Math.max(e.r,Math.max(e.g,e.b)):0},e.prototype._convertMetalRoughFactorsToMetallicRoughnessAsync=function(e,t,r,n){var i=[],o={baseColor:e._albedoColor,metallic:e._metallic,roughness:e._roughness};if(n){e._albedoTexture&&i.push(this._exportTextureAsync(e._albedoTexture,t).then((function(e){e&&(r.baseColorTexture=e)})));var a=e._metallicTexture;a&&i.push(this._exportTextureAsync(a,t).then((function(e){e&&(r.metallicRoughnessTexture=e)})))}return Promise.all(i).then((function(){return o}))},e.prototype._getTextureSampler=function(e){var t={};if(!(e&&e instanceof m.Texture))return t;var r=this._getGLTFTextureWrapMode(e.wrapU);10497!==r&&(t.wrapS=r);var n=this._getGLTFTextureWrapMode(e.wrapV);switch(10497!==n&&(t.wrapT=n),e.samplingMode){case m.Texture.LINEAR_LINEAR:t.magFilter=9729,t.minFilter=9729;break;case m.Texture.LINEAR_NEAREST:t.magFilter=9729,t.minFilter=9728;break;case m.Texture.NEAREST_LINEAR:t.magFilter=9728,t.minFilter=9729;break;case m.Texture.NEAREST_LINEAR_MIPLINEAR:t.magFilter=9728,t.minFilter=9987;break;case m.Texture.NEAREST_NEAREST:t.magFilter=9728,t.minFilter=9728;break;case m.Texture.NEAREST_LINEAR_MIPNEAREST:t.magFilter=9728,t.minFilter=9985;break;case m.Texture.LINEAR_NEAREST_MIPNEAREST:t.magFilter=9729,t.minFilter=9984;break;case m.Texture.LINEAR_NEAREST_MIPLINEAR:t.magFilter=9729,t.minFilter=9986;break;case m.Texture.NEAREST_NEAREST_MIPLINEAR:t.magFilter=9728,t.minFilter=9986;break;case m.Texture.LINEAR_LINEAR_MIPLINEAR:t.magFilter=9729,t.minFilter=9987;break;case m.Texture.LINEAR_LINEAR_MIPNEAREST:t.magFilter=9729,t.minFilter=9985;break;case m.Texture.NEAREST_NEAREST_MIPNEAREST:t.magFilter=9728,t.minFilter=9984}return t},e.prototype._getGLTFTextureWrapMode=function(e){switch(e){case m.Texture.WRAP_ADDRESSMODE:return 10497;case m.Texture.CLAMP_ADDRESSMODE:return 33071;case m.Texture.MIRROR_ADDRESSMODE:return 33648;default:return m.Tools.Error("Unsupported Texture Wrap Mode ".concat(e,"!")),10497}},e.prototype._convertSpecGlossFactorsToMetallicRoughnessAsync=function(e,t,r,n){var i=this;return Promise.resolve().then((function(){var o={diffuseColor:e._albedoColor,specularColor:e._reflectivityColor,glossiness:e._microSurface},a=e._albedoTexture,s=e._reflectivityTexture,u=e._useMicroSurfaceFromReflectivityMapAlpha;if(s&&!u)return Promise.reject("_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture are currently not supported");if((a||s)&&n){var l=i._exportTextureSampler(a||s);return i._convertSpecularGlossinessTexturesToMetallicRoughnessAsync(a,s,o,t).then((function(e){var n=i._exporter._textures;if(e.baseColorTextureData){var o=i._exportImage("baseColor".concat(n.length),t,e.baseColorTextureData);r.baseColorTexture=i._exportTextureInfo(o,l,null==a?void 0:a.coordinatesIndex)}return e.metallicRoughnessTextureData&&(o=i._exportImage("metallicRoughness".concat(n.length),t,e.metallicRoughnessTextureData),r.metallicRoughnessTexture=i._exportTextureInfo(o,l,null==s?void 0:s.coordinatesIndex)),e}))}return i._convertSpecularGlossinessToMetallicRoughness(o)}))},e.prototype._convertPBRMaterialAsync=function(e,t,r){var n=this,i={},o={name:e.name};if(e.isMetallicWorkflow()){var a=e._albedoColor,s=e.alpha;return a&&(i.baseColorFactor=[a.r,a.g,a.b,s]),this._convertMetalRoughFactorsToMetallicRoughnessAsync(e,t,i,r).then((function(a){return n._setMetallicRoughnessPbrMaterial(a,e,o,i,t,r)}))}return this._convertSpecGlossFactorsToMetallicRoughnessAsync(e,t,i,r).then((function(a){return n._setMetallicRoughnessPbrMaterial(a,e,o,i,t,r)}))},e.prototype._setMetallicRoughnessPbrMaterial=function(t,r,n,i,o,a){var s=this._exporter._materialMap,u=this._exporter._materials,l=[];if(t){if(e._SetAlphaMode(n,r),e._FuzzyEquals(t.baseColor,m.Color3.White(),e._Epsilon)&&r.alpha>=e._Epsilon||(i.baseColorFactor=[t.baseColor.r,t.baseColor.g,t.baseColor.b,r.alpha]),null!=t.metallic&&1!==t.metallic&&(i.metallicFactor=t.metallic),null!=t.roughness&&1!==t.roughness&&(i.roughnessFactor=t.roughness),null==r.backFaceCulling||r.backFaceCulling||(r._twoSidedLighting||m.Tools.Warn(r.name+": Back-face culling disabled and two-sided lighting disabled is not supported in glTF."),n.doubleSided=!0),a){var c=r._bumpTexture;if(c){var f=this._exportTextureAsync(c,o).then((function(e){e&&(n.normalTexture=e,1!==c.level&&(n.normalTexture.scale=c.level))}));l.push(f)}var h=r._ambientTexture;h&&(f=this._exportTextureAsync(h,o).then((function(e){if(e){var t={index:e.index,texCoord:e.texCoord,extensions:e.extensions};n.occlusionTexture=t;var i=r._ambientTextureStrength;i&&(t.strength=i)}})),l.push(f));var p=r._emissiveTexture;p&&(f=this._exportTextureAsync(p,o).then((function(e){e&&(n.emissiveTexture=e)})),l.push(f))}var d=r._emissiveColor;e._FuzzyEquals(d,m.Color3.Black(),e._Epsilon)||(n.emissiveFactor=d.asArray()),n.pbrMetallicRoughness=i,u.push(n),s[r.uniqueId]=u.length-1}return this._finishMaterial(l,n,r,o)},e.prototype._getPixelsFromTexture=function(e){return e.textureType,m.Constants.TEXTURETYPE_UNSIGNED_INT,e.readPixels()},e.prototype._exportTextureAsync=function(e,t){var r=this,n=this._exporter._extensionsPreExportTextureAsync("exporter",e,t);return n?n.then((function(n){return n?r._exportTextureInfoAsync(n,t):r._exportTextureInfoAsync(e,t)})):this._exportTextureInfoAsync(e,t)},e.prototype._exportTextureInfoAsync=function(e,t){return p(this,void 0,void 0,(function(){var r,n,i,o,a,s,u,l,c,f,h=this;return d(this,(function(_){switch(_.label){case 0:return(r=e.uid)in this._textureMap?[3,3]:[4,this._getPixelsFromTexture(e)];case 1:if(!(n=_.sent()))return[2,null];if(i=this._exportTextureSampler(e),o=e.mimeType)switch(o){case"image/jpeg":case"image/png":case"image/webp":t=o;break;default:m.Tools.Warn("Unsupported media type: ".concat(o))}return a=this._internalTextureToImage,s=e.getInternalTexture().uniqueId,a[s]||(a[s]={}),void 0===(u=a[s][t])&&(l=e.getSize(),u=p(h,void 0,void 0,(function(){var r;return d(this,(function(i){switch(i.label){case 0:return[4,this._getImageDataAsync(n,l.width,l.height,t)];case 1:return r=i.sent(),[2,this._exportImage(e.name,t,r)]}}))})),a[s][t]=u),f=this._exportTextureInfo,[4,u];case 2:c=f.apply(this,[_.sent(),i,e.coordinatesIndex]),this._textureMap[r]=c,this._exporter._extensionsPostExportTextures("exporter",this._textureMap[r],e),_.label=3;case 3:return[2,this._textureMap[r]]}}))}))},e.prototype._exportImage=function(e,t,r){var n=this._exporter._imageData,i=e.replace(/\.\/|\/|\.\\|\\/g,"_"),o=function(e){switch(e){case"image/jpeg":return".jpg";case"image/png":return".png";case"image/webp":return".webp";case"image/avif":return".avif"}}(t),a=i+o;a in n&&(a="".concat(i,"_").concat(m.Tools.RandomId()).concat(o)),n[a]={data:r,mimeType:t};var s=this._exporter._images;return s.push({name:e,uri:a}),s.length-1},e.prototype._exportTextureInfo=function(e,t,r){var n=this._exporter._textures,i=n.findIndex((function(r){return r.sampler==t&&r.source===e}));-1===i&&(i=n.length,n.push({source:e,sampler:t}));var o={index:i};return r&&(o.texCoord=r),o},e.prototype._exportTextureSampler=function(e){var t=this._getTextureSampler(e),r=this._exporter._samplers,n=r.findIndex((function(e){return e.minFilter===t.minFilter&&e.magFilter===t.magFilter&&e.wrapS===t.wrapS&&e.wrapT===t.wrapT}));return-1!==n?n:(r.push(t),r.length-1)},e._DielectricSpecular=new m.Color3(.04,.04,.04),e._MaxSpecularPower=1024,e._Epsilon=1e-6,e}(),y=function(){function e(){}return e._CreateBufferView=function(e,t,r,n,i){var o={buffer:e,byteLength:r};return t&&(o.byteOffset=t),i&&(o.name=i),n&&(o.byteStride=n),o},e._CreateAccessor=function(e,t,r,n,i,o,a,s){var u={name:t,bufferView:e,componentType:n,count:i,type:r};return null!=a&&(u.min=a),null!=s&&(u.max=s),null!=o&&(u.byteOffset=o),u},e._CalculateMinMaxPositions=function(e,t,r){var n,i,o=[1/0,1/0,1/0],a=[-1/0,-1/0,-1/0];if(r)for(var s=t,u=t+r;sa[l]&&(a[l]=c),++n}}return{min:o,max:a}},e._NormalizeTangentFromRef=function(e){var t=Math.sqrt(e.x*e.x+e.y*e.y+e.z*e.z);t>0&&(e.x/=t,e.y/=t,e.z/=t)},e._GetDataAccessorElementCount=function(e){switch(e){case"MAT2":case"VEC4":return 4;case"MAT3":return 9;case"MAT4":return 16;case"SCALAR":return 1;case"VEC2":return 2;case"VEC3":return 3}},e}();!function(e){e[e.INTANGENT=0]="INTANGENT",e[e.OUTTANGENT=1]="OUTTANGENT"}(g||(g={}));var T=function(){function e(){}return e._IsTransformable=function(e){return e&&(e instanceof m.TransformNode||e instanceof m.Camera||e instanceof m.Light)},e._CreateNodeAnimation=function(t,r,n,i,o){if(this._IsTransformable(t)){var a=[],s=[],u=r.getKeys(),l=e._CalculateMinMaxKeyFrames(u),c=e._DeduceInterpolation(u,n,i),f=c.interpolationType,h=c.shouldBakeAnimation;if(h?e._CreateBakedAnimation(t,r,n,l.min,l.max,r.framePerSecond,o,a,s,l,i):"LINEAR"===f||"STEP"===f?e._CreateLinearOrStepAnimation(t,r,n,a,s,i):"CUBICSPLINE"===f?e._CreateCubicSplineAnimation(t,r,n,a,s,i):e._CreateBakedAnimation(t,r,n,l.min,l.max,r.framePerSecond,o,a,s,l,i),a.length&&s.length)return{inputs:a,outputs:s,samplerInterpolation:f,inputsMin:h?l.min:m.Tools.FloatRound(l.min/r.framePerSecond),inputsMax:h?l.max:m.Tools.FloatRound(l.max/r.framePerSecond)}}return null},e._DeduceAnimationInfo=function(e){var t=null,r="VEC3",n=!1,i=e.targetProperty.split(".");switch(i[0]){case"scaling":t="scale";break;case"position":t="translation";break;case"rotation":r="VEC4",t="rotation";break;case"rotationQuaternion":r="VEC4",n=!0,t="rotation";break;case"influence":r="SCALAR",t="weights";break;default:m.Tools.Error("Unsupported animatable property ".concat(i[0]))}return t?{animationChannelTargetPath:t,dataAccessorType:r,useQuaternion:n}:(m.Tools.Error("animation channel target path and data accessor type could be deduced"),null)},e._CreateNodeAnimationFromNodeAnimations=function(t,r,n,i,o,a,s,u,l,c){var f;if(e._IsTransformable(t)&&t.animations)for(var h=0,p=t.animations;h0;)E=b.inputs.shift(),A%p==0&&M.push(E),A++;b.inputs=M}var F=s[n.uniqueId],w=4*b.inputs.length;d=y._CreateBufferView(0,u.getByteOffset(),w,void 0,"".concat(t," keyframe data view")),l.push(d),b.inputs.forEach((function(e){u.setFloat32(e)})),_=y._CreateAccessor(l.length-1,"".concat(t," keyframes"),"SCALAR",5126,b.inputs.length,null,[b.inputsMin],[b.inputsMax]),c.push(_),g=c.length-1,x=b.outputs.length,w=4*y._GetDataAccessorElementCount(o)*b.outputs.length,d=y._CreateBufferView(0,u.getByteOffset(),w,void 0,"".concat(t," data view")),l.push(d),b.outputs.forEach((function(e){e.forEach((function(e){u.setFloat32(e)}))})),_=y._CreateAccessor(l.length-1,"".concat(t," data"),o,5126,x,null,null,null),c.push(_),m=c.length-1,T={interpolation:b.samplerInterpolation,input:g,output:m},r.samplers.push(T),v={sampler:r.samplers.length-1,target:{node:F,path:a}},r.channels.push(v)}},e._CreateBakedAnimation=function(t,r,n,i,o,a,s,u,l,c,f){var h,p,d=m.Quaternion.Identity(),_=null,g=null,x=null,y=null,T=null,v=null;c.min=m.Tools.FloatRound(i/a);for(var b=r.getKeys(),A=0,E=b.length;A=t.length)return Promise.resolve(e);var o=n(t[r],e);return o?o.then((function(e){return i._applyExtension(e,t,r+1,n)})):this._applyExtension(e,t,r+1,n)},e.prototype._applyExtensions=function(t,r){for(var n=[],i=0,o=e._ExtensionNames;i=c;--o)i.setUInt32(r[o],n),n+=4;break;case m.Material.TriangleStripDrawMode:e.indexCount>=3&&(i.setUInt32(r[e.indexStart+2],n+4),i.setUInt32(r[e.indexStart+1],n+8))}},e.prototype._reorderVertexAttributeDataBasedOnPrimitiveMode=function(e,t,r,n,i,o){switch(t){case m.Material.TriangleFillMode:this._reorderTriangleFillMode(e,r,n,i,o);break;case m.Material.TriangleStripDrawMode:this._reorderTriangleStripDrawMode(e,r,n,i,o);break;case m.Material.TriangleFanDrawMode:this._reorderTriangleFanMode(e,r,n,i,o)}},e.prototype._reorderTriangleFillMode=function(e,t,r,n,i){var o=this._getVertexBufferFromMesh(t,e.getMesh());if(o){var a=o.byteStride/m.VertexBuffer.GetTypeByteLength(o.type);if(e.verticesCount%3!=0)m.Tools.Error("The submesh vertices for the triangle fill mode is not divisible by 3!");else{var s=[],u=0;switch(t){case m.VertexBuffer.PositionKind:case m.VertexBuffer.NormalKind:for(var l=e.verticesStart;l=e.verticesStart;--l)u=l*a,s.push(m.Vector4.FromArray(r,u));break;case m.VertexBuffer.ColorKind:for(l=e.verticesStart+e.verticesCount-1;l>=e.verticesStart;--l)u=l*a,4===o.getSize()?s.push(m.Vector4.FromArray(r,u)):s.push(m.Vector3.FromArray(r,u));break;case m.VertexBuffer.UVKind:case m.VertexBuffer.UV2Kind:for(l=e.verticesStart+e.verticesCount-1;l>=e.verticesStart;--l)u=l*a,s.push(m.Vector2.FromArray(r,u));break;default:m.Tools.Error("Unsupported Vertex Buffer type: ".concat(t))}this._writeVertexAttributeData(s,n+12,t,i)}else m.Tools.Warn("reorderTriangleStripDrawMode: Vertex buffer kind ".concat(t," not present!"))},e.prototype._reorderTriangleFanMode=function(e,t,r,n,i){var o=this._getVertexBufferFromMesh(t,e.getMesh());if(o){var a=o.byteStride/m.VertexBuffer.GetTypeByteLength(o.type),s=[],u=0;switch(t){case m.VertexBuffer.PositionKind:case m.VertexBuffer.NormalKind:for(var l=e.verticesStart+e.verticesCount-1;l>=e.verticesStart;--l)u=l*a,s.push(m.Vector3.FromArray(r,u));break;case m.VertexBuffer.TangentKind:for(l=e.verticesStart+e.verticesCount-1;l>=e.verticesStart;--l)u=l*a,s.push(m.Vector4.FromArray(r,u));break;case m.VertexBuffer.ColorKind:for(l=e.verticesStart+e.verticesCount-1;l>=e.verticesStart;--l)u=l*a,s.push(m.Vector4.FromArray(r,u)),4===o.getSize()?s.push(m.Vector4.FromArray(r,u)):s.push(m.Vector3.FromArray(r,u));break;case m.VertexBuffer.UVKind:case m.VertexBuffer.UV2Kind:for(l=e.verticesStart+e.verticesCount-1;l>=e.verticesStart;--l)u=l*a,s.push(m.Vector2.FromArray(r,u));break;default:m.Tools.Error("Unsupported Vertex Buffer type: ".concat(t))}this._writeVertexAttributeData(s,n,t,i)}else m.Tools.Warn("reorderTriangleFanMode: Vertex buffer kind ".concat(t," not present!"))},e.prototype._writeVertexAttributeData=function(e,t,r,n){for(var i=0,o=e;i0){if(N._getEffectiveOrientation(p)===(this._babylonScene.useRightHandedSystem?m.Material.ClockWiseSideOrientation:m.Material.CounterClockWiseSideOrientation)){null==(te=null!=_?this._bufferViews[_].byteOffset:null)&&(te=0);var H=null;if(null!=_&&(H=p.getIndices()),H)this._reorderIndicesBasedOnPrimitiveMode(P,g,H,te,r);else for(var j=0,Q=d;j0){var s=a.material||a.getScene().defaultMaterial;if(s instanceof m.MultiMaterial)for(var u=0,l=s.subMaterials;u0){i.weights=[];for(var a=0;af&&(f=p));for(var p=0;p<=f;++p){var d=c[p];l.push(d.getInvertedAbsoluteTransform());var _=d.getTransformNode();_&&null!==e[_.uniqueId]&&void 0!==e[_.uniqueId]?u.joints.push(e[_.uniqueId]):m.Tools.Warn("Exporting a bone without a linked transform node is currently unsupported")}if(u.joints.length>0){var g=64*l.length,x=t.getByteOffset(),T=y._CreateBufferView(0,x,g,void 0,"InverseBindMatrices - "+s.name);this._bufferViews.push(T);var v=this._bufferViews.length-1,b=y._CreateAccessor(v,"InverseBindMatrices - "+s.name,"MAT4",5126,l.length,null,null,null),A=this._accessors.push(b)-1;u.inverseBindMatrices=A,this._skins.push(u),i[s.uniqueId]=this._skins.length-1,l.forEach((function(e){e.m.forEach((function(e){t.setFloat32(e)}))}))}}}return n.then((function(){return i}))},e._ExtensionNames=new Array,e._ExtensionFactories={},e}(),F=function(){function e(e){this._arrayBuffer=new ArrayBuffer(e),this._dataView=new DataView(this._arrayBuffer),this._byteOffset=0}return e.prototype._resizeBuffer=function(e){var t=new ArrayBuffer(e),r=Math.min(this._arrayBuffer.byteLength,e),n=new Uint8Array(this._arrayBuffer,0,r);return new Uint8Array(t).set(n,0),this._arrayBuffer=t,this._dataView=new DataView(this._arrayBuffer),t},e.prototype.getArrayBuffer=function(){return this._resizeBuffer(this.getByteOffset())},e.prototype.getByteOffset=function(){if(null==this._byteOffset)throw new Error("Byte offset is undefined!");return this._byteOffset},e.prototype.setUInt8=function(e,t){null!=t?tthis._arrayBuffer.byteLength&&this._resizeBuffer(2*this._arrayBuffer.byteLength),this._dataView.setUint8(this._byteOffset,e),this._byteOffset+=1)},e.prototype.setUInt16=function(e,t){null!=t?tthis._arrayBuffer.byteLength&&this._resizeBuffer(2*this._arrayBuffer.byteLength),this._dataView.setUint16(this._byteOffset,e,!0),this._byteOffset+=2)},e.prototype.getUInt32=function(e){if(ethis._byteOffset?m.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"):(e.x=this._dataView.getFloat32(t,!0),e.y=this._dataView.getFloat32(t+4,!0),e.z=this._dataView.getFloat32(t+8,!0))},e.prototype.setVector3Float32FromRef=function(e,t){t+8>this._byteOffset?m.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"):(this._dataView.setFloat32(t,e.x,!0),this._dataView.setFloat32(t+4,e.y,!0),this._dataView.setFloat32(t+8,e.z,!0))},e.prototype.getVector4Float32FromRef=function(e,t){t+12>this._byteOffset?m.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"):(e.x=this._dataView.getFloat32(t,!0),e.y=this._dataView.getFloat32(t+4,!0),e.z=this._dataView.getFloat32(t+8,!0),e.w=this._dataView.getFloat32(t+12,!0))},e.prototype.setVector4Float32FromRef=function(e,t){t+12>this._byteOffset?m.Tools.Error("BinaryWriter: byteoffset is greater than the current binary buffer length!"):(this._dataView.setFloat32(t,e.x,!0),this._dataView.setFloat32(t+4,e.y,!0),this._dataView.setFloat32(t+8,e.z,!0),this._dataView.setFloat32(t+12,e.w,!0))},e.prototype.setFloat32=function(e,t){isNaN(e)&&m.Tools.Error("Invalid data being written!"),null!=t&&(tthis._arrayBuffer.byteLength&&this._resizeBuffer(2*this._arrayBuffer.byteLength),this._dataView.setFloat32(this._byteOffset,e,!0),this._byteOffset+=4},e.prototype.setUInt32=function(e,t){null!=t?tthis._arrayBuffer.byteLength&&this._resizeBuffer(2*this._arrayBuffer.byteLength),this._dataView.setUint32(this._byteOffset,e,!0),this._byteOffset+=4)},e.prototype.setInt16=function(e,t){null!=t?tthis._arrayBuffer.byteLength&&this._resizeBuffer(2*this._arrayBuffer.byteLength),this._dataView.setInt16(this._byteOffset,e,!0),this._byteOffset+=2)},e.prototype.setByte=function(e,t){null!=t?tthis._arrayBuffer.byteLength&&this._resizeBuffer(2*this._arrayBuffer.byteLength),this._dataView.setInt8(this._byteOffset,e),this._byteOffset++)},e}(),w=function(){function e(){}return e.GLTFAsync=function(e,t,r){return e.whenReadyAsync().then((function(){var n=t.replace(/\.[^/.]+$/,"");return new M(e,r)._generateGLTFAsync(n)}))},e._PreExportAsync=function(e,t){return Promise.resolve().then((function(){return t&&t.exportWithoutWaitingForScene?Promise.resolve():e.whenReadyAsync()}))},e._PostExportAsync=function(e,t,r){return Promise.resolve().then((function(){return r&&r.exportWithoutWaitingForScene,t}))},e.GLBAsync=function(e,t,r){var n=this;return this._PreExportAsync(e,r).then((function(){var i=t.replace(/\.[^/.]+$/,"");return new M(e,r)._generateGLBAsync(i).then((function(t){return n._PostExportAsync(e,t,r)}))}))},e}(),R="KHR_texture_transform",C=function(){function e(){this.name=R,this.enabled=!0,this.required=!1,this._wasUsed=!1}return e.prototype.dispose=function(){},Object.defineProperty(e.prototype,"wasUsed",{get:function(){return this._wasUsed},enumerable:!1,configurable:!0}),e.prototype.postExportTexture=function(e,t,r){if(r&&(0===r.uAng&&0===r.wAng&&0===r.vAng||0===r.uRotationCenter&&0===r.vRotationCenter)){var n={},i=!1;if(0===r.uOffset&&0===r.vOffset||(n.offset=[r.uOffset,r.vOffset],i=!0),1===r.uScale&&1===r.vScale||(n.scale=[r.uScale,r.vScale],i=!0),0!==r.wAng&&(n.rotation=-r.wAng,i=!0),0!==r.coordinatesIndex&&(n.texCoord=r.coordinatesIndex,i=!0),!i)return;this._wasUsed=!0,t.extensions||(t.extensions={}),t.extensions[R]=n}},e.prototype.preExportTextureAsync=function(e,t){return new Promise((function(r,n){t.getScene()?0!==t.uAng||0!==t.vAng?(m.Tools.Warn("".concat(e,": Texture ").concat(t.name," with rotation in the u or v axis is not supported in glTF.")),r(null)):0===t.wAng||0===t.uRotationCenter&&0===t.vRotationCenter?r(t):(m.Tools.Warn("".concat(e,": Texture ").concat(t.name," with rotation not centered at the origin cannot be exported with ").concat(R)),r(null)):n("".concat(e,': "scene" is not defined for Babylon texture ').concat(t.name,"!"))}))},e}();M.RegisterExtension(R,(function(){return new C}));var V="KHR_lights_punctual",S=function(){function e(e){this.name=V,this.enabled=!0,this.required=!1,this._exporter=e}return e.prototype.dispose=function(){this._lights=null},Object.defineProperty(e.prototype,"wasUsed",{get:function(){return!!this._lights},enumerable:!1,configurable:!0}),e.prototype.onExporting=function(){this._exporter._glTF.extensions[V]=this._lights},e.prototype.postExportNodeAsync=function(e,t,r,n){var i=this;return new Promise((function(o){if(t&&r instanceof m.ShadowLight){var a=void 0,s=r.getTypeID()==m.Light.LIGHTTYPEID_POINTLIGHT?"point":r.getTypeID()==m.Light.LIGHTTYPEID_DIRECTIONALLIGHT?"directional":r.getTypeID()==m.Light.LIGHTTYPEID_SPOTLIGHT?"spot":null;if(null==s)m.Logger.Warn("".concat(e,": Light ").concat(r.name," is not supported in ").concat(V));else{if(r.position.equalsToFloats(0,0,0)||(t.translation=r.position.asArray()),"point"!==s){var u=r.direction,l=-Math.atan2(u.z,u.x)+Math.PI/2,c=Math.sqrt(u.x*u.x+u.z*u.z),f=-Math.atan2(u.y,c),h=m.Quaternion.RotationYawPitchRoll(l+Math.PI,f,0);m.Quaternion.IsIdentity(h)||(t.rotation=h.asArray())}if(r.falloffType!==m.Light.FALLOFF_GLTF&&m.Logger.Warn("".concat(e,": Light falloff for ").concat(r.name," does not match the ").concat(V," specification!")),a={type:s},r.diffuse.equals(m.Color3.White())||(a.color=r.diffuse.asArray()),1!==r.intensity&&(a.intensity=r.intensity),r.range!==Number.MAX_VALUE&&(a.range=r.range),"spot"===s){var p=r;p.angle!==Math.PI/2&&(null==a.spot&&(a.spot={}),a.spot.outerConeAngle=p.angle/2),0!==p.innerAngle&&(null==a.spot&&(a.spot={}),a.spot.innerConeAngle=p.innerAngle/2)}i._lights||(i._lights={lights:[]}),i._lights.lights.push(a);var d={light:i._lights.lights.length-1},_=r.parent;if(_&&1==_.getChildren().length){var g=i._exporter._nodes[n[_.uniqueId]];if(g){var x=m.Vector3.FromArrayToRef(g.translation||[0,0,0],0,m.TmpVectors.Vector3[0]),y=m.Quaternion.FromArrayToRef(g.rotation||[0,0,0,1],0,m.TmpVectors.Quaternion[0]),T=m.Vector3.FromArrayToRef(g.scale||[1,1,1],0,m.TmpVectors.Vector3[1]),v=m.Matrix.ComposeToRef(T,y,x,m.TmpVectors.Matrix[0]),b=m.Vector3.FromArrayToRef(t.translation||[0,0,0],0,m.TmpVectors.Vector3[2]),A=m.Quaternion.FromArrayToRef(t.rotation||[0,0,0,1],0,m.TmpVectors.Quaternion[1]),E=m.Matrix.ComposeToRef(m.Vector3.OneReadOnly,A,b,m.TmpVectors.Matrix[1]);return v.multiplyToRef(E,E),E.decompose(T,y,x),x.equalsToFloats(0,0,0)?delete g.translation:g.translation=x.asArray(),m.Quaternion.IsIdentity(y)?delete g.rotation:g.rotation=y.asArray(),T.equalsToFloats(1,1,1)?delete g.scale:g.scale=T.asArray(),g.extensions||(g.extensions={}),g.extensions[V]=d,void o(null)}}t.extensions||(t.extensions={}),t.extensions[V]=d}}o(t)}))},e}();M.RegisterExtension(V,(function(e){return new S(e)}));var I="KHR_materials_clearcoat",B=function(){function e(e){this.name=I,this.enabled=!0,this.required=!1,this._wasUsed=!1,this._exporter=e}return e.prototype.dispose=function(){},Object.defineProperty(e.prototype,"wasUsed",{get:function(){return this._wasUsed},enumerable:!1,configurable:!0}),e.prototype.postExportMaterialAdditionalTextures=function(e,t,r){var n=[];return r instanceof m.PBRBaseMaterial&&r.clearCoat.isEnabled?(r.clearCoat.texture&&n.push(r.clearCoat.texture),!r.clearCoat.useRoughnessFromMainTexture&&r.clearCoat.textureRoughness&&n.push(r.clearCoat.textureRoughness),r.clearCoat.bumpTexture&&n.push(r.clearCoat.bumpTexture),n):[]},e.prototype.postExportMaterialAsync=function(e,t,r){var n=this;return new Promise((function(e){if(r instanceof m.PBRBaseMaterial){if(!r.clearCoat.isEnabled)return void e(t);n._wasUsed=!0,t.extensions=t.extensions||{};var i,o=n._exporter._glTFMaterialExporter._getTextureInfo(r.clearCoat.texture);i=r.clearCoat.useRoughnessFromMainTexture?n._exporter._glTFMaterialExporter._getTextureInfo(r.clearCoat.texture):n._exporter._glTFMaterialExporter._getTextureInfo(r.clearCoat.textureRoughness),r.clearCoat.isTintEnabled&&m.Tools.Warn("Clear Color tint is not supported for glTF export. Ignoring for: ".concat(r.name)),r.clearCoat.remapF0OnInterfaceChange&&m.Tools.Warn("Clear Color F0 remapping is not supported for glTF export. Ignoring for: ".concat(r.name));var a=n._exporter._glTFMaterialExporter._getTextureInfo(r.clearCoat.bumpTexture),s={clearcoatFactor:r.clearCoat.intensity,clearcoatTexture:null!=o?o:void 0,clearcoatRoughnessFactor:r.clearCoat.roughness,clearcoatRoughnessTexture:null!=i?i:void 0,clearcoatNormalTexture:null!=a?a:void 0,hasTextures:function(){return null!==s.clearcoatTexture||null!==s.clearcoatRoughnessTexture||null!==s.clearcoatRoughnessTexture}};t.extensions[I]=s}e(t)}))},e}();M.RegisterExtension(I,(function(e){return new B(e)}));var P="KHR_materials_iridescence",N=function(){function e(e){this.name=P,this.enabled=!0,this.required=!1,this._wasUsed=!1,this._exporter=e}return e.prototype.dispose=function(){},Object.defineProperty(e.prototype,"wasUsed",{get:function(){return this._wasUsed},enumerable:!1,configurable:!0}),e.prototype.postExportMaterialAdditionalTextures=function(e,t,r){var n=[];return r instanceof m.PBRBaseMaterial&&r.iridescence.isEnabled?(r.iridescence.texture&&n.push(r.iridescence.texture),r.iridescence.thicknessTexture&&r.iridescence.thicknessTexture!==r.iridescence.texture&&n.push(r.iridescence.thicknessTexture),n):[]},e.prototype.postExportMaterialAsync=function(e,t,r){var n=this;return new Promise((function(e){if(r instanceof m.PBRBaseMaterial){if(!r.iridescence.isEnabled)return void e(t);n._wasUsed=!0,t.extensions=t.extensions||{};var i=n._exporter._glTFMaterialExporter._getTextureInfo(r.iridescence.texture),o=n._exporter._glTFMaterialExporter._getTextureInfo(r.iridescence.thicknessTexture),a={iridescenceFactor:r.iridescence.intensity,iridescenceIor:r.iridescence.indexOfRefraction,iridescenceThicknessMinimum:r.iridescence.minimumThickness,iridescenceThicknessMaximum:r.iridescence.maximumThickness,iridescenceTexture:null!=i?i:void 0,iridescenceThicknessTexture:null!=o?o:void 0,hasTextures:function(){return null!==a.iridescenceTexture||null!==a.iridescenceThicknessTexture}};t.extensions[P]=a}e(t)}))},e}();M.RegisterExtension(P,(function(e){return new N(e)}));var L="KHR_materials_anisotropy",O=function(){function e(e){this.name=L,this.enabled=!0,this.required=!1,this._wasUsed=!1,this._exporter=e}return e.prototype.dispose=function(){},Object.defineProperty(e.prototype,"wasUsed",{get:function(){return this._wasUsed},enumerable:!1,configurable:!0}),e.prototype.postExportMaterialAdditionalTextures=function(e,t,r){var n=[];return r instanceof m.PBRBaseMaterial&&r.anisotropy.isEnabled&&!r.anisotropy.legacy?(r.anisotropy.texture&&n.push(r.anisotropy.texture),n):[]},e.prototype.postExportMaterialAsync=function(e,t,r){var n=this;return new Promise((function(e){if(r instanceof m.PBRBaseMaterial){if(!r.anisotropy.isEnabled||r.anisotropy.legacy)return void e(t);n._wasUsed=!0,t.extensions=t.extensions||{};var i=n._exporter._glTFMaterialExporter._getTextureInfo(r.anisotropy.texture),o={anisotropyStrength:r.anisotropy.intensity,anisotropyRotation:r.anisotropy.angle,anisotropyTexture:null!=i?i:void 0,hasTextures:function(){return null!==o.anisotropyTexture}};t.extensions[L]=o}e(t)}))},e}();M.RegisterExtension(L,(function(e){return new O(e)}));var U="KHR_materials_sheen",k=function(){function e(e){this.name=U,this.enabled=!0,this.required=!1,this._wasUsed=!1,this._exporter=e}return e.prototype.dispose=function(){},Object.defineProperty(e.prototype,"wasUsed",{get:function(){return this._wasUsed},enumerable:!1,configurable:!0}),e.prototype.postExportMaterialAdditionalTextures=function(e,t,r){return r instanceof m.PBRMaterial&&r.sheen.isEnabled&&r.sheen.texture?[r.sheen.texture]:[]},e.prototype.postExportMaterialAsync=function(e,t,r){var n=this;return new Promise((function(e){var i,o,a,s;if(r instanceof m.PBRMaterial){if(!r.sheen.isEnabled)return void e(t);n._wasUsed=!0,null==t.extensions&&(t.extensions={});var u={sheenColorFactor:r.sheen.color.asArray(),sheenRoughnessFactor:null!==(i=r.sheen.roughness)&&void 0!==i?i:0,hasTextures:function(){return null!==u.sheenColorTexture||null!==u.sheenRoughnessTexture}};r.sheen.texture&&(u.sheenColorTexture=null!==(o=n._exporter._glTFMaterialExporter._getTextureInfo(r.sheen.texture))&&void 0!==o?o:void 0),r.sheen.textureRoughness&&!r.sheen.useRoughnessFromMainTexture?u.sheenRoughnessTexture=null!==(a=n._exporter._glTFMaterialExporter._getTextureInfo(r.sheen.textureRoughness))&&void 0!==a?a:void 0:r.sheen.texture&&r.sheen.useRoughnessFromMainTexture&&(u.sheenRoughnessTexture=null!==(s=n._exporter._glTFMaterialExporter._getTextureInfo(r.sheen.texture))&&void 0!==s?s:void 0),t.extensions[U]=u}e(t)}))},e}();M.RegisterExtension(U,(function(e){return new k(e)}));var K="KHR_materials_unlit",D=function(){function e(){this.name=K,this.enabled=!0,this.required=!1,this._wasUsed=!1}return Object.defineProperty(e.prototype,"wasUsed",{get:function(){return this._wasUsed},enumerable:!1,configurable:!0}),e.prototype.dispose=function(){},e.prototype.postExportMaterialAsync=function(e,t,r){var n=this;return new Promise((function(e){var i=!1;r instanceof m.PBRMaterial?i=r.unlit:r instanceof m.StandardMaterial&&(i=r.disableLighting),i&&(n._wasUsed=!0,null==t.extensions&&(t.extensions={}),t.extensions[K]={}),e(t)}))},e}();M.RegisterExtension(K,(function(){return new D}));var G="KHR_materials_ior",z=function(){function e(){this.name=G,this.enabled=!0,this.required=!1,this._wasUsed=!1}return e.prototype.dispose=function(){},Object.defineProperty(e.prototype,"wasUsed",{get:function(){return this._wasUsed},enumerable:!1,configurable:!0}),e.prototype._isExtensionEnabled=function(e){return!e.unlit&&null!=e.indexOfRefraction&&1.5!=e.indexOfRefraction},e.prototype.postExportMaterialAsync=function(e,t,r){var n=this;return new Promise((function(e){if(r instanceof m.PBRMaterial&&n._isExtensionEnabled(r)){n._wasUsed=!0;var i={ior:r.indexOfRefraction};t.extensions=t.extensions||{},t.extensions[G]=i}e(t)}))},e}();M.RegisterExtension(G,(function(e){return new z}));var W="KHR_materials_specular",q=function(){function e(e){this.name=W,this.enabled=!0,this.required=!1,this._wasUsed=!1,this._exporter=e}return e.prototype.dispose=function(){},Object.defineProperty(e.prototype,"wasUsed",{get:function(){return this._wasUsed},enumerable:!1,configurable:!0}),e.prototype.postExportMaterialAdditionalTextures=function(e,t,r){var n=[];return r instanceof m.PBRMaterial&&this._isExtensionEnabled(r)?(r.metallicReflectanceTexture&&n.push(r.metallicReflectanceTexture),r.reflectanceTexture&&n.push(r.reflectanceTexture),n):n},e.prototype._isExtensionEnabled=function(e){return!e.unlit&&(null!=e.metallicF0Factor&&1!=e.metallicF0Factor||null!=e.metallicReflectanceColor&&!e.metallicReflectanceColor.equalsFloats(1,1,1)||this._hasTexturesExtension(e))},e.prototype._hasTexturesExtension=function(e){return null!=e.metallicReflectanceTexture||null!=e.reflectanceTexture},e.prototype.postExportMaterialAsync=function(e,t,r){var n=this;return new Promise((function(e){var i,o;if(r instanceof m.PBRMaterial&&n._isExtensionEnabled(r)){n._wasUsed=!0,t.extensions=t.extensions||{};var a=null!==(i=n._exporter._glTFMaterialExporter._getTextureInfo(r.metallicReflectanceTexture))&&void 0!==i?i:void 0,s=null!==(o=n._exporter._glTFMaterialExporter._getTextureInfo(r.reflectanceTexture))&&void 0!==o?o:void 0,u={specularFactor:1==r.metallicF0Factor?void 0:r.metallicF0Factor,specularTexture:a,specularColorFactor:r.metallicReflectanceColor.equalsFloats(1,1,1)?void 0:r.metallicReflectanceColor.asArray(),specularColorTexture:s,hasTextures:function(){return n._hasTexturesExtension(r)}};t.extensions[W]=u}e(t)}))},e}();M.RegisterExtension(W,(function(e){return new q(e)}));var H="KHR_materials_volume",j=function(){function e(e){this.name=H,this.enabled=!0,this.required=!1,this._wasUsed=!1,this._exporter=e}return e.prototype.dispose=function(){},Object.defineProperty(e.prototype,"wasUsed",{get:function(){return this._wasUsed},enumerable:!1,configurable:!0}),e.prototype.postExportMaterialAdditionalTextures=function(e,t,r){var n=[];return r instanceof m.PBRMaterial&&this._isExtensionEnabled(r)?(r.subSurface.thicknessTexture&&n.push(r.subSurface.thicknessTexture),n):n},e.prototype._isExtensionEnabled=function(e){if(e.unlit)return!1;var t=e.subSurface;return!(!t.isRefractionEnabled&&!t.isTranslucencyEnabled)&&(null!=t.maximumThickness&&0!=t.maximumThickness||null!=t.tintColorAtDistance&&t.tintColorAtDistance!=Number.POSITIVE_INFINITY||null!=t.tintColor&&t.tintColor!=m.Color3.White()||this._hasTexturesExtension(e))},e.prototype._hasTexturesExtension=function(e){return null!=e.subSurface.thicknessTexture},e.prototype.postExportMaterialAsync=function(e,t,r){var n=this;return new Promise((function(e){var i;if(r instanceof m.PBRMaterial&&n._isExtensionEnabled(r)){n._wasUsed=!0;var o=r.subSurface,a={thicknessFactor:0==o.maximumThickness?void 0:o.maximumThickness,thicknessTexture:null!==(i=n._exporter._glTFMaterialExporter._getTextureInfo(o.thicknessTexture))&&void 0!==i?i:void 0,attenuationDistance:o.tintColorAtDistance==Number.POSITIVE_INFINITY?void 0:o.tintColorAtDistance,attenuationColor:o.tintColor.equalsFloats(1,1,1)?void 0:o.tintColor.asArray(),hasTextures:function(){return n._hasTexturesExtension(r)}};t.extensions=t.extensions||{},t.extensions[H]=a}e(t)}))},e}();M.RegisterExtension(H,(function(e){return new j(e)}));var Q="KHR_materials_dispersion",Y=function(){function e(){this.name=Q,this.enabled=!0,this.required=!1,this._wasUsed=!1}return e.prototype.dispose=function(){},Object.defineProperty(e.prototype,"wasUsed",{get:function(){return this._wasUsed},enumerable:!1,configurable:!0}),e.prototype._isExtensionEnabled=function(e){if(e.unlit)return!1;var t=e.subSurface;return!(!t.isRefractionEnabled&&!t.isDispersionEnabled)},e.prototype.postExportMaterialAsync=function(e,t,r){var n=this;return new Promise((function(e){if(r instanceof m.PBRMaterial&&n._isExtensionEnabled(r)){n._wasUsed=!0;var i={dispersion:r.subSurface.dispersion};t.extensions=t.extensions||{},t.extensions[Q]=i}e(t)}))},e}();M.RegisterExtension(Q,(function(){return new Y}));var X="KHR_materials_transmission",Z=function(){function e(e){this.name=X,this.enabled=!0,this.required=!1,this._wasUsed=!1,this._exporter=e}return e.prototype.dispose=function(){},Object.defineProperty(e.prototype,"wasUsed",{get:function(){return this._wasUsed},enumerable:!1,configurable:!0}),e.prototype.postExportMaterialAdditionalTextures=function(e,t,r){var n=[];return r instanceof m.PBRMaterial&&this._isExtensionEnabled(r)?(r.subSurface.thicknessTexture&&n.push(r.subSurface.thicknessTexture),n):n},e.prototype._isExtensionEnabled=function(e){if(e.unlit)return!1;var t=e.subSurface;return t.isRefractionEnabled&&null!=t.refractionIntensity&&0!=t.refractionIntensity||this._hasTexturesExtension(e)},e.prototype._hasTexturesExtension=function(e){return null!=e.subSurface.refractionIntensityTexture},e.prototype.postExportMaterialAsync=function(e,t,r){return p(this,void 0,void 0,(function(){var n,i,o,a,s=this;return d(this,(function(u){switch(u.label){case 0:return r instanceof m.PBRMaterial&&this._isExtensionEnabled(r)?(this._wasUsed=!0,n=r.subSurface,i=0===n.refractionIntensity?void 0:n.refractionIntensity,o={transmissionFactor:i,hasTextures:function(){return s._hasTexturesExtension(r)}},n.refractionIntensityTexture?n.useGltfStyleTextures?[4,this._exporter._glTFMaterialExporter._exportTextureInfoAsync(n.refractionIntensityTexture,"image/png")]:[3,2]:[3,3]):[3,4];case 1:return(a=u.sent())&&(o.transmissionTexture=a),[3,3];case 2:m.Logger.Warn("".concat(e,": Exporting a subsurface refraction intensity texture without `useGltfStyleTextures` is not supported")),u.label=3;case 3:t.extensions||(t.extensions={}),t.extensions[X]=o,u.label=4;case 4:return[2,t]}}))}))},e}();M.RegisterExtension(X,(function(e){return new Z(e)}));var J="EXT_mesh_gpu_instancing",$=function(){function e(e){this.name=J,this.enabled=!0,this.required=!1,this._wasUsed=!1,this._exporter=e}return e.prototype.dispose=function(){},Object.defineProperty(e.prototype,"wasUsed",{get:function(){return this._wasUsed},enumerable:!1,configurable:!0}),e.prototype.postExportNodeAsync=function(e,t,r,n,i){var o=this;return new Promise((function(e){if(t&&r instanceof m.Mesh&&r.hasThinInstances&&i){o._wasUsed=!0;for(var n=m.Vector3.Zero(),a=m.Quaternion.Identity(),s=m.Vector3.One(),u=r.thinInstanceGetWorldMatrices(),l=m.TmpVectors.Vector3[2],c=m.TmpVectors.Quaternion[1],f=m.TmpVectors.Vector3[3],h=!1,p=!1,d=!1,_=new Float32Array(3*r.thinInstanceCount),g=new Float32Array(4*r.thinInstanceCount),x=new Float32Array(3*r.thinInstanceCount),y=0,T=0,v=u;T1){n._wasUsed=!0,t.extensions||(t.extensions={});var a={emissiveStrength:o},s=r.emissiveColor.scale(1/a.emissiveStrength);t.emissiveFactor=s.asArray(),t.extensions[ee]=a}return e(t)}))},e}();M.RegisterExtension(ee,(function(e){return new te}));var re="KHR_materials_diffuse_transmission",ne=function(){function e(e){this.name=re,this.enabled=!0,this.required=!1,this._wasUsed=!1,this._exporter=e}return e.prototype.dispose=function(){},Object.defineProperty(e.prototype,"wasUsed",{get:function(){return this._wasUsed},enumerable:!1,configurable:!0}),e.prototype.postExportMaterialAdditionalTextures=function(e,t,r){var n=[];return r instanceof m.PBRMaterial&&this._isExtensionEnabled(r)?(r.subSurface.thicknessTexture&&n.push(r.subSurface.thicknessTexture),n):n},e.prototype._isExtensionEnabled=function(e){if(e.unlit)return!1;var t=e.subSurface;return!!t.isTranslucencyEnabled&&!e.unlit&&!t.useAlbedoToTintTranslucency&&t.useGltfStyleTextures&&1===t.volumeIndexOfRefraction&&0===t.minimumThickness&&0===t.maximumThickness},e.prototype._hasTexturesExtension=function(e){return null!=e.subSurface.translucencyIntensityTexture||null!=e.subSurface.translucencyColorTexture},e.prototype.postExportMaterialAsync=function(e,t,r){var n=this;return new Promise((function(e){var i,o;if(r instanceof m.PBRMaterial&&n._isExtensionEnabled(r)){n._wasUsed=!0;var a=r.subSurface,s={diffuseTransmissionFactor:1==a.translucencyIntensity?void 0:a.translucencyIntensity,diffuseTransmissionTexture:null!==(i=n._exporter._glTFMaterialExporter._getTextureInfo(a.translucencyIntensityTexture))&&void 0!==i?i:void 0,diffuseTransmissionColorFactor:!a.translucencyColor||a.translucencyColor.equalsFloats(1,1,1)?void 0:a.translucencyColor.asArray(),diffuseTransmissionColorTexture:null!==(o=n._exporter._glTFMaterialExporter._getTextureInfo(a.translucencyColorTexture))&&void 0!==o?o:void 0,hasTextures:function(){return n._hasTexturesExtension(r)}};t.extensions=t.extensions||{},t.extensions[re]=s}e(t)}))},e}();M.RegisterExtension(re,(function(e){return new ne(e)}));var ie=0,oe=void 0!==n.g?n.g:"undefined"!=typeof window?window:void 0;if(void 0!==oe){oe.BABYLON=oe.BABYLON||{};var ae=oe.BABYLON;ae.GLTF2=ae.GLTF2||{},ae.GLTF2.Exporter=ae.GLTF2.Exporter||{},ae.GLTF2.Exporter.Extensions=ae.GLTF2.Exporter.Extensions||{};var se=[];for(var ue in o)ae[ue]=o[ue],se.push(ue);for(var ue in a)ae[ue]=a[ue],se.push(ue);for(var ue in s)ae[ue]=s[ue],se.push(ue);for(var ue in u)ae.GLTF2.Exporter.Extensions[ue]=u[ue],se.push(ue);for(var ue in l)se.indexOf(ue)>-1||(ae.GLTF2.Exporter[ue]=l[ue])}const le=c;return i.default})())); +//# sourceMappingURL=babylon.glTF2Serializer.min.js.map \ No newline at end of file diff --git a/libs/babylonjs/7.35.0/babylon.glTFFileLoader.js b/libs/babylonjs/7.35.0/babylon.glTFFileLoader.js new file mode 100644 index 00000000..f7e90e41 --- /dev/null +++ b/libs/babylonjs/7.35.0/babylon.glTFFileLoader.js @@ -0,0 +1,11768 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("babylonjs")); + else if(typeof define === 'function' && define.amd) + define("babylonjs-loaders", ["babylonjs"], factory); + else if(typeof exports === 'object') + exports["babylonjs-loaders"] = factory(require("babylonjs")); + else + root["LOADERS"] = factory(root["BABYLON"]); +})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), (__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_tools__) => { +return /******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ + +/***/ "../../../dev/loaders/src/glTF/1.0/glTFBinaryExtension.ts": +/*!****************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/1.0/glTFBinaryExtension.ts ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFBinaryExtension: () => (/* binding */ GLTFBinaryExtension) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./glTFLoader */ "../../../dev/loaders/src/glTF/1.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./glTFLoaderUtils */ "../../../dev/loaders/src/glTF/1.0/glTFLoaderUtils.ts"); +/* harmony import */ var _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glTFLoaderInterfaces */ "../../../dev/loaders/src/glTF/1.0/glTFLoaderInterfaces.ts"); + + + + +var BinaryExtensionBufferName = "binary_glTF"; +/** + * @internal + * @deprecated + */ +var GLTFBinaryExtension = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_3__.__extends)(GLTFBinaryExtension, _super); + function GLTFBinaryExtension() { + return _super.call(this, "KHR_binary_glTF") || this; + } + GLTFBinaryExtension.prototype.loadRuntimeAsync = function (scene, data, rootUrl, onSuccess) { + var extensionsUsed = data.json.extensionsUsed; + if (!extensionsUsed || extensionsUsed.indexOf(this.name) === -1 || !data.bin) { + return false; + } + this._bin = data.bin; + onSuccess(_glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderBase.CreateRuntime(data.json, scene, rootUrl)); + return true; + }; + GLTFBinaryExtension.prototype.loadBufferAsync = function (gltfRuntime, id, onSuccess, onError) { + if (gltfRuntime.extensionsUsed.indexOf(this.name) === -1) { + return false; + } + if (id !== BinaryExtensionBufferName) { + return false; + } + this._bin.readAsync(0, this._bin.byteLength).then(onSuccess, function (error) { return onError(error.message); }); + return true; + }; + GLTFBinaryExtension.prototype.loadTextureBufferAsync = function (gltfRuntime, id, onSuccess) { + var texture = gltfRuntime.textures[id]; + var source = gltfRuntime.images[texture.source]; + if (!source.extensions || !(this.name in source.extensions)) { + return false; + } + var sourceExt = source.extensions[this.name]; + var bufferView = gltfRuntime.bufferViews[sourceExt.bufferView]; + var buffer = _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_1__.GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, 0, bufferView.byteLength, _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_2__.EComponentType.UNSIGNED_BYTE); + onSuccess(buffer); + return true; + }; + GLTFBinaryExtension.prototype.loadShaderStringAsync = function (gltfRuntime, id, onSuccess) { + var shader = gltfRuntime.shaders[id]; + if (!shader.extensions || !(this.name in shader.extensions)) { + return false; + } + var binaryExtensionShader = shader.extensions[this.name]; + var bufferView = gltfRuntime.bufferViews[binaryExtensionShader.bufferView]; + var shaderBytes = _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_1__.GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, 0, bufferView.byteLength, _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_2__.EComponentType.UNSIGNED_BYTE); + setTimeout(function () { + var shaderString = _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_1__.GLTFUtils.DecodeBufferToText(shaderBytes); + onSuccess(shaderString); + }); + return true; + }; + return GLTFBinaryExtension; +}(_glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderExtension)); + +_glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.RegisterExtension(new GLTFBinaryExtension()); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/1.0/glTFLoader.ts": +/*!*******************************************************!*\ + !*** ../../../dev/loaders/src/glTF/1.0/glTFLoader.ts ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFLoader: () => (/* binding */ GLTFLoader), +/* harmony export */ GLTFLoaderBase: () => (/* binding */ GLTFLoaderBase), +/* harmony export */ GLTFLoaderExtension: () => (/* binding */ GLTFLoaderExtension) +/* harmony export */ }); +/* harmony import */ var _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./glTFLoaderInterfaces */ "../../../dev/loaders/src/glTF/1.0/glTFLoaderInterfaces.ts"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Engines/constants */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glTFLoaderUtils */ "../../../dev/loaders/src/glTF/1.0/glTFLoaderUtils.ts"); +/* harmony import */ var _glTFFileLoader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../glTFFileLoader */ "../../../dev/loaders/src/glTF/glTFFileLoader.ts"); + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/** + * Tokenizer. Used for shaders compatibility + * Automatically map world, view, projection, worldViewProjection, attributes and so on + */ +var ETokenType; +(function (ETokenType) { + ETokenType[ETokenType["IDENTIFIER"] = 1] = "IDENTIFIER"; + ETokenType[ETokenType["UNKNOWN"] = 2] = "UNKNOWN"; + ETokenType[ETokenType["END_OF_INPUT"] = 3] = "END_OF_INPUT"; +})(ETokenType || (ETokenType = {})); +var Tokenizer = /** @class */ (function () { + function Tokenizer(toParse) { + this._pos = 0; + this.currentToken = ETokenType.UNKNOWN; + this.currentIdentifier = ""; + this.currentString = ""; + this.isLetterOrDigitPattern = /^[a-zA-Z0-9]+$/; + this._toParse = toParse; + this._maxPos = toParse.length; + } + Tokenizer.prototype.getNextToken = function () { + if (this.isEnd()) { + return ETokenType.END_OF_INPUT; + } + this.currentString = this.read(); + this.currentToken = ETokenType.UNKNOWN; + if (this.currentString === "_" || this.isLetterOrDigitPattern.test(this.currentString)) { + this.currentToken = ETokenType.IDENTIFIER; + this.currentIdentifier = this.currentString; + while (!this.isEnd() && (this.isLetterOrDigitPattern.test((this.currentString = this.peek())) || this.currentString === "_")) { + this.currentIdentifier += this.currentString; + this.forward(); + } + } + return this.currentToken; + }; + Tokenizer.prototype.peek = function () { + return this._toParse[this._pos]; + }; + Tokenizer.prototype.read = function () { + return this._toParse[this._pos++]; + }; + Tokenizer.prototype.forward = function () { + this._pos++; + }; + Tokenizer.prototype.isEnd = function () { + return this._pos >= this._maxPos; + }; + return Tokenizer; +}()); +/** + * Values + */ +var glTFTransforms = ["MODEL", "VIEW", "PROJECTION", "MODELVIEW", "MODELVIEWPROJECTION", "JOINTMATRIX"]; +var babylonTransforms = ["world", "view", "projection", "worldView", "worldViewProjection", "mBones"]; +var glTFAnimationPaths = ["translation", "rotation", "scale"]; +var babylonAnimationPaths = ["position", "rotationQuaternion", "scaling"]; +/** + * Parse + * @param parsedBuffers + * @param gltfRuntime + */ +var parseBuffers = function (parsedBuffers, gltfRuntime) { + for (var buf in parsedBuffers) { + var parsedBuffer = parsedBuffers[buf]; + gltfRuntime.buffers[buf] = parsedBuffer; + gltfRuntime.buffersCount++; + } +}; +var parseShaders = function (parsedShaders, gltfRuntime) { + for (var sha in parsedShaders) { + var parsedShader = parsedShaders[sha]; + gltfRuntime.shaders[sha] = parsedShader; + gltfRuntime.shaderscount++; + } +}; +var parseObject = function (parsedObjects, runtimeProperty, gltfRuntime) { + for (var object in parsedObjects) { + var parsedObject = parsedObjects[object]; + gltfRuntime[runtimeProperty][object] = parsedObject; + } +}; +/** + * Utils + * @param buffer + */ +var normalizeUVs = function (buffer) { + if (!buffer) { + return; + } + for (var i = 0; i < buffer.length / 2; i++) { + buffer[i * 2 + 1] = 1.0 - buffer[i * 2 + 1]; + } +}; +var getAttribute = function (attributeParameter) { + if (attributeParameter.semantic === "NORMAL") { + return "normal"; + } + else if (attributeParameter.semantic === "POSITION") { + return "position"; + } + else if (attributeParameter.semantic === "JOINT") { + return "matricesIndices"; + } + else if (attributeParameter.semantic === "WEIGHT") { + return "matricesWeights"; + } + else if (attributeParameter.semantic === "COLOR") { + return "color"; + } + else if (attributeParameter.semantic && attributeParameter.semantic.indexOf("TEXCOORD_") !== -1) { + var channel = Number(attributeParameter.semantic.split("_")[1]); + return "uv" + (channel === 0 ? "" : channel + 1); + } + return null; +}; +/** + * Loads and creates animations + * @param gltfRuntime + */ +var loadAnimations = function (gltfRuntime) { + for (var anim in gltfRuntime.animations) { + var animation = gltfRuntime.animations[anim]; + if (!animation.channels || !animation.samplers) { + continue; + } + var lastAnimation = null; + for (var i = 0; i < animation.channels.length; i++) { + // Get parameters and load buffers + var channel = animation.channels[i]; + var sampler = animation.samplers[channel.sampler]; + if (!sampler) { + continue; + } + var inputData = null; + var outputData = null; + if (animation.parameters) { + inputData = animation.parameters[sampler.input]; + outputData = animation.parameters[sampler.output]; + } + else { + inputData = sampler.input; + outputData = sampler.output; + } + var bufferInput = _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_2__.GLTFUtils.GetBufferFromAccessor(gltfRuntime, gltfRuntime.accessors[inputData]); + var bufferOutput = _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_2__.GLTFUtils.GetBufferFromAccessor(gltfRuntime, gltfRuntime.accessors[outputData]); + var targetId = channel.target.id; + var targetNode = gltfRuntime.scene.getNodeById(targetId); + if (targetNode === null) { + targetNode = gltfRuntime.scene.getNodeByName(targetId); + } + if (targetNode === null) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.Warn("Creating animation named " + anim + ". But cannot find node named " + targetId + " to attach to"); + continue; + } + var isBone = targetNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Bone; + // Get target path (position, rotation or scaling) + var targetPath = channel.target.path; + var targetPathIndex = glTFAnimationPaths.indexOf(targetPath); + if (targetPathIndex !== -1) { + targetPath = babylonAnimationPaths[targetPathIndex]; + } + // Determine animation type + var animationType = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Animation.ANIMATIONTYPE_MATRIX; + if (!isBone) { + if (targetPath === "rotationQuaternion") { + animationType = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Animation.ANIMATIONTYPE_QUATERNION; + targetNode.rotationQuaternion = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Quaternion(); + } + else { + animationType = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Animation.ANIMATIONTYPE_VECTOR3; + } + } + // Create animation and key frames + var babylonAnimation = null; + var keys = []; + var arrayOffset = 0; + var modifyKey = false; + if (isBone && lastAnimation && lastAnimation.getKeys().length === bufferInput.length) { + babylonAnimation = lastAnimation; + modifyKey = true; + } + if (!modifyKey) { + gltfRuntime.scene._blockEntityCollection = !!gltfRuntime.assetContainer; + babylonAnimation = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Animation(anim, isBone ? "_matrix" : targetPath, 1, animationType, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Animation.ANIMATIONLOOPMODE_CYCLE); + gltfRuntime.scene._blockEntityCollection = false; + } + // For each frame + for (var j = 0; j < bufferInput.length; j++) { + var value = null; + if (targetPath === "rotationQuaternion") { + // VEC4 + value = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Quaternion.FromArray([bufferOutput[arrayOffset], bufferOutput[arrayOffset + 1], bufferOutput[arrayOffset + 2], bufferOutput[arrayOffset + 3]]); + arrayOffset += 4; + } + else { + // Position and scaling are VEC3 + value = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.FromArray([bufferOutput[arrayOffset], bufferOutput[arrayOffset + 1], bufferOutput[arrayOffset + 2]]); + arrayOffset += 3; + } + if (isBone) { + var bone = targetNode; + var translation = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero(); + var rotationQuaternion = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Quaternion(); + var scaling = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero(); + // Warning on decompose + var mat = bone.getBaseMatrix(); + if (modifyKey && lastAnimation) { + mat = lastAnimation.getKeys()[j].value; + } + mat.decompose(scaling, rotationQuaternion, translation); + if (targetPath === "position") { + translation = value; + } + else if (targetPath === "rotationQuaternion") { + rotationQuaternion = value; + } + else { + scaling = value; + } + value = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Matrix.Compose(scaling, rotationQuaternion, translation); + } + if (!modifyKey) { + keys.push({ + frame: bufferInput[j], + value: value, + }); + } + else if (lastAnimation) { + lastAnimation.getKeys()[j].value = value; + } + } + // Finish + if (!modifyKey && babylonAnimation) { + babylonAnimation.setKeys(keys); + targetNode.animations.push(babylonAnimation); + } + lastAnimation = babylonAnimation; + gltfRuntime.scene.stopAnimation(targetNode); + gltfRuntime.scene.beginAnimation(targetNode, 0, bufferInput[bufferInput.length - 1], true, 1.0); + } + } +}; +/** + * @returns the bones transformation matrix + * @param node + */ +var configureBoneTransformation = function (node) { + var mat = null; + if (node.translation || node.rotation || node.scale) { + var scale = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.FromArray(node.scale || [1, 1, 1]); + var rotation = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Quaternion.FromArray(node.rotation || [0, 0, 0, 1]); + var position = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.FromArray(node.translation || [0, 0, 0]); + mat = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Matrix.Compose(scale, rotation, position); + } + else { + mat = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Matrix.FromArray(node.matrix); + } + return mat; +}; +/** + * Returns the parent bone + * @param gltfRuntime + * @param skins + * @param jointName + * @param newSkeleton + * @returns the parent bone + */ +var getParentBone = function (gltfRuntime, skins, jointName, newSkeleton) { + // Try to find + for (var i = 0; i < newSkeleton.bones.length; i++) { + if (newSkeleton.bones[i].name === jointName) { + return newSkeleton.bones[i]; + } + } + // Not found, search in gltf nodes + var nodes = gltfRuntime.nodes; + for (var nde in nodes) { + var node = nodes[nde]; + if (!node.jointName) { + continue; + } + var children = node.children; + for (var i = 0; i < children.length; i++) { + var child = gltfRuntime.nodes[children[i]]; + if (!child.jointName) { + continue; + } + if (child.jointName === jointName) { + var mat = configureBoneTransformation(node); + var bone = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Bone(node.name || "", newSkeleton, getParentBone(gltfRuntime, skins, node.jointName, newSkeleton), mat); + bone.id = nde; + return bone; + } + } + } + return null; +}; +/** + * Returns the appropriate root node + * @param nodesToRoot + * @param id + * @returns the root node + */ +var getNodeToRoot = function (nodesToRoot, id) { + for (var i = 0; i < nodesToRoot.length; i++) { + var nodeToRoot = nodesToRoot[i]; + for (var j = 0; j < nodeToRoot.node.children.length; j++) { + var child = nodeToRoot.node.children[j]; + if (child === id) { + return nodeToRoot.bone; + } + } + } + return null; +}; +/** + * Returns the node with the joint name + * @param gltfRuntime + * @param jointName + * @returns the node with the joint name + */ +var getJointNode = function (gltfRuntime, jointName) { + var nodes = gltfRuntime.nodes; + var node = nodes[jointName]; + if (node) { + return { + node: node, + id: jointName, + }; + } + for (var nde in nodes) { + node = nodes[nde]; + if (node.jointName === jointName) { + return { + node: node, + id: nde, + }; + } + } + return null; +}; +/** + * Checks if a nodes is in joints + * @param skins + * @param id + * @returns true if the node is in joints, else false + */ +var nodeIsInJoints = function (skins, id) { + for (var i = 0; i < skins.jointNames.length; i++) { + if (skins.jointNames[i] === id) { + return true; + } + } + return false; +}; +/** + * Fills the nodes to root for bones and builds hierarchy + * @param gltfRuntime + * @param newSkeleton + * @param skins + * @param nodesToRoot + */ +var getNodesToRoot = function (gltfRuntime, newSkeleton, skins, nodesToRoot) { + // Creates nodes for root + for (var nde in gltfRuntime.nodes) { + var node = gltfRuntime.nodes[nde]; + var id = nde; + if (!node.jointName || nodeIsInJoints(skins, node.jointName)) { + continue; + } + // Create node to root bone + var mat = configureBoneTransformation(node); + var bone = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Bone(node.name || "", newSkeleton, null, mat); + bone.id = id; + nodesToRoot.push({ bone: bone, node: node, id: id }); + } + // Parenting + for (var i = 0; i < nodesToRoot.length; i++) { + var nodeToRoot = nodesToRoot[i]; + var children = nodeToRoot.node.children; + for (var j = 0; j < children.length; j++) { + var child = null; + for (var k = 0; k < nodesToRoot.length; k++) { + if (nodesToRoot[k].id === children[j]) { + child = nodesToRoot[k]; + break; + } + } + if (child) { + child.bone._parent = nodeToRoot.bone; + nodeToRoot.bone.children.push(child.bone); + } + } + } +}; +/** + * Imports a skeleton + * @param gltfRuntime + * @param skins + * @param mesh + * @param newSkeleton + * @returns the bone name + */ +var importSkeleton = function (gltfRuntime, skins, mesh, newSkeleton) { + if (!newSkeleton) { + newSkeleton = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Skeleton(skins.name || "", "", gltfRuntime.scene); + } + if (!skins.babylonSkeleton) { + return newSkeleton; + } + // Find the root bones + var nodesToRoot = []; + var nodesToRootToAdd = []; + getNodesToRoot(gltfRuntime, newSkeleton, skins, nodesToRoot); + newSkeleton.bones = []; + // Joints + for (var i = 0; i < skins.jointNames.length; i++) { + var jointNode = getJointNode(gltfRuntime, skins.jointNames[i]); + if (!jointNode) { + continue; + } + var node = jointNode.node; + if (!node) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.Warn("Joint named " + skins.jointNames[i] + " does not exist"); + continue; + } + var id = jointNode.id; + // Optimize, if the bone already exists... + var existingBone = gltfRuntime.scene.getBoneById(id); + if (existingBone) { + newSkeleton.bones.push(existingBone); + continue; + } + // Search for parent bone + var foundBone = false; + var parentBone = null; + for (var j = 0; j < i; j++) { + var jointNode_1 = getJointNode(gltfRuntime, skins.jointNames[j]); + if (!jointNode_1) { + continue; + } + var joint = jointNode_1.node; + if (!joint) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.Warn("Joint named " + skins.jointNames[j] + " does not exist when looking for parent"); + continue; + } + var children = joint.children; + if (!children) { + continue; + } + foundBone = false; + for (var k = 0; k < children.length; k++) { + if (children[k] === id) { + parentBone = getParentBone(gltfRuntime, skins, skins.jointNames[j], newSkeleton); + foundBone = true; + break; + } + } + if (foundBone) { + break; + } + } + // Create bone + var mat = configureBoneTransformation(node); + if (!parentBone && nodesToRoot.length > 0) { + parentBone = getNodeToRoot(nodesToRoot, id); + if (parentBone) { + if (nodesToRootToAdd.indexOf(parentBone) === -1) { + nodesToRootToAdd.push(parentBone); + } + } + } + var bone = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Bone(node.jointName || "", newSkeleton, parentBone, mat); + bone.id = id; + } + // Polish + var bones = newSkeleton.bones; + newSkeleton.bones = []; + for (var i = 0; i < skins.jointNames.length; i++) { + var jointNode = getJointNode(gltfRuntime, skins.jointNames[i]); + if (!jointNode) { + continue; + } + for (var j = 0; j < bones.length; j++) { + if (bones[j].id === jointNode.id) { + newSkeleton.bones.push(bones[j]); + break; + } + } + } + newSkeleton.prepare(); + // Finish + for (var i = 0; i < nodesToRootToAdd.length; i++) { + newSkeleton.bones.push(nodesToRootToAdd[i]); + } + return newSkeleton; +}; +/** + * Imports a mesh and its geometries + * @param gltfRuntime + * @param node + * @param meshes + * @param id + * @param newMesh + * @returns the new mesh + */ +var importMesh = function (gltfRuntime, node, meshes, id, newMesh) { + if (!newMesh) { + gltfRuntime.scene._blockEntityCollection = !!gltfRuntime.assetContainer; + newMesh = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Mesh(node.name || "", gltfRuntime.scene); + newMesh._parentContainer = gltfRuntime.assetContainer; + gltfRuntime.scene._blockEntityCollection = false; + newMesh.id = id; + } + if (!node.babylonNode) { + return newMesh; + } + var subMaterials = []; + var vertexData = null; + var verticesStarts = []; + var verticesCounts = []; + var indexStarts = []; + var indexCounts = []; + for (var meshIndex = 0; meshIndex < meshes.length; meshIndex++) { + var meshId = meshes[meshIndex]; + var mesh = gltfRuntime.meshes[meshId]; + if (!mesh) { + continue; + } + // Positions, normals and UVs + for (var i = 0; i < mesh.primitives.length; i++) { + // Temporary vertex data + var tempVertexData = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.VertexData(); + var primitive = mesh.primitives[i]; + if (primitive.mode !== 4) { + // continue; + } + var attributes = primitive.attributes; + var accessor = null; + var buffer = null; + // Set positions, normal and uvs + for (var semantic in attributes) { + // Link accessor and buffer view + accessor = gltfRuntime.accessors[attributes[semantic]]; + buffer = _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_2__.GLTFUtils.GetBufferFromAccessor(gltfRuntime, accessor); + if (semantic === "NORMAL") { + tempVertexData.normals = new Float32Array(buffer.length); + tempVertexData.normals.set(buffer); + } + else if (semantic === "POSITION") { + if (_glTFFileLoader__WEBPACK_IMPORTED_MODULE_3__.GLTFFileLoader.HomogeneousCoordinates) { + tempVertexData.positions = new Float32Array(buffer.length - buffer.length / 4); + for (var j = 0; j < buffer.length; j += 4) { + tempVertexData.positions[j] = buffer[j]; + tempVertexData.positions[j + 1] = buffer[j + 1]; + tempVertexData.positions[j + 2] = buffer[j + 2]; + } + } + else { + tempVertexData.positions = new Float32Array(buffer.length); + tempVertexData.positions.set(buffer); + } + verticesCounts.push(tempVertexData.positions.length); + } + else if (semantic.indexOf("TEXCOORD_") !== -1) { + var channel = Number(semantic.split("_")[1]); + var uvKind = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.VertexBuffer.UVKind + (channel === 0 ? "" : channel + 1); + var uvs = new Float32Array(buffer.length); + uvs.set(buffer); + normalizeUVs(uvs); + tempVertexData.set(uvs, uvKind); + } + else if (semantic === "JOINT") { + tempVertexData.matricesIndices = new Float32Array(buffer.length); + tempVertexData.matricesIndices.set(buffer); + } + else if (semantic === "WEIGHT") { + tempVertexData.matricesWeights = new Float32Array(buffer.length); + tempVertexData.matricesWeights.set(buffer); + } + else if (semantic === "COLOR") { + tempVertexData.colors = new Float32Array(buffer.length); + tempVertexData.colors.set(buffer); + } + } + // Indices + accessor = gltfRuntime.accessors[primitive.indices]; + if (accessor) { + buffer = _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_2__.GLTFUtils.GetBufferFromAccessor(gltfRuntime, accessor); + tempVertexData.indices = new Int32Array(buffer.length); + tempVertexData.indices.set(buffer); + indexCounts.push(tempVertexData.indices.length); + } + else { + // Set indices on the fly + var indices = []; + for (var j = 0; j < tempVertexData.positions.length / 3; j++) { + indices.push(j); + } + tempVertexData.indices = new Int32Array(indices); + indexCounts.push(tempVertexData.indices.length); + } + if (!vertexData) { + vertexData = tempVertexData; + } + else { + vertexData.merge(tempVertexData); + } + // Sub material + var material_1 = gltfRuntime.scene.getMaterialById(primitive.material); + subMaterials.push(material_1 === null ? _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_2__.GLTFUtils.GetDefaultMaterial(gltfRuntime.scene) : material_1); + // Update vertices start and index start + verticesStarts.push(verticesStarts.length === 0 ? 0 : verticesStarts[verticesStarts.length - 1] + verticesCounts[verticesCounts.length - 2]); + indexStarts.push(indexStarts.length === 0 ? 0 : indexStarts[indexStarts.length - 1] + indexCounts[indexCounts.length - 2]); + } + } + var material; + gltfRuntime.scene._blockEntityCollection = !!gltfRuntime.assetContainer; + if (subMaterials.length > 1) { + material = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.MultiMaterial("multimat" + id, gltfRuntime.scene); + material.subMaterials = subMaterials; + } + else { + material = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.StandardMaterial("multimat" + id, gltfRuntime.scene); + } + if (subMaterials.length === 1) { + material = subMaterials[0]; + } + material._parentContainer = gltfRuntime.assetContainer; + if (!newMesh.material) { + newMesh.material = material; + } + // Apply geometry + new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Geometry(id, gltfRuntime.scene, vertexData, false, newMesh); + newMesh.computeWorldMatrix(true); + gltfRuntime.scene._blockEntityCollection = false; + // Apply submeshes + newMesh.subMeshes = []; + var index = 0; + for (var meshIndex = 0; meshIndex < meshes.length; meshIndex++) { + var meshId = meshes[meshIndex]; + var mesh = gltfRuntime.meshes[meshId]; + if (!mesh) { + continue; + } + for (var i = 0; i < mesh.primitives.length; i++) { + if (mesh.primitives[i].mode !== 4) { + //continue; + } + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.SubMesh.AddToMesh(index, verticesStarts[index], verticesCounts[index], indexStarts[index], indexCounts[index], newMesh, newMesh, true); + index++; + } + } + // Finish + return newMesh; +}; +/** + * Configure node transformation from position, rotation and scaling + * @param newNode + * @param position + * @param rotation + * @param scaling + */ +var configureNode = function (newNode, position, rotation, scaling) { + if (newNode.position) { + newNode.position = position; + } + if (newNode.rotationQuaternion || newNode.rotation) { + newNode.rotationQuaternion = rotation; + } + if (newNode.scaling) { + newNode.scaling = scaling; + } +}; +/** + * Configures node from transformation matrix + * @param newNode + * @param node + */ +var configureNodeFromMatrix = function (newNode, node) { + if (node.matrix) { + var position = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, 0, 0); + var rotation = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Quaternion(); + var scaling = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, 0, 0); + var mat = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Matrix.FromArray(node.matrix); + mat.decompose(scaling, rotation, position); + configureNode(newNode, position, rotation, scaling); + } + else if (node.translation && node.rotation && node.scale) { + configureNode(newNode, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.FromArray(node.translation), babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Quaternion.FromArray(node.rotation), babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.FromArray(node.scale)); + } + newNode.computeWorldMatrix(true); +}; +/** + * Imports a node + * @param gltfRuntime + * @param node + * @param id + * @returns the newly imported node + */ +var importNode = function (gltfRuntime, node, id) { + var lastNode = null; + if (gltfRuntime.importOnlyMeshes && (node.skin || node.meshes)) { + if (gltfRuntime.importMeshesNames && gltfRuntime.importMeshesNames.length > 0 && gltfRuntime.importMeshesNames.indexOf(node.name || "") === -1) { + return null; + } + } + // Meshes + if (node.skin) { + if (node.meshes) { + var skin = gltfRuntime.skins[node.skin]; + var newMesh = importMesh(gltfRuntime, node, node.meshes, id, node.babylonNode); + newMesh.skeleton = gltfRuntime.scene.getLastSkeletonById(node.skin); + if (newMesh.skeleton === null) { + newMesh.skeleton = importSkeleton(gltfRuntime, skin, newMesh, skin.babylonSkeleton); + if (!skin.babylonSkeleton) { + skin.babylonSkeleton = newMesh.skeleton; + } + } + lastNode = newMesh; + } + } + else if (node.meshes) { + /** + * Improve meshes property + */ + var newMesh = importMesh(gltfRuntime, node, node.mesh ? [node.mesh] : node.meshes, id, node.babylonNode); + lastNode = newMesh; + } + // Lights + else if (node.light && !node.babylonNode && !gltfRuntime.importOnlyMeshes) { + var light = gltfRuntime.lights[node.light]; + if (light) { + if (light.type === "ambient") { + var ambienLight = light[light.type]; + var hemiLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.HemisphericLight(node.light, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero(), gltfRuntime.scene); + hemiLight.name = node.name || ""; + if (ambienLight.color) { + hemiLight.diffuse = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color3.FromArray(ambienLight.color); + } + lastNode = hemiLight; + } + else if (light.type === "directional") { + var directionalLight = light[light.type]; + var dirLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.DirectionalLight(node.light, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero(), gltfRuntime.scene); + dirLight.name = node.name || ""; + if (directionalLight.color) { + dirLight.diffuse = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color3.FromArray(directionalLight.color); + } + lastNode = dirLight; + } + else if (light.type === "point") { + var pointLight = light[light.type]; + var ptLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.PointLight(node.light, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero(), gltfRuntime.scene); + ptLight.name = node.name || ""; + if (pointLight.color) { + ptLight.diffuse = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color3.FromArray(pointLight.color); + } + lastNode = ptLight; + } + else if (light.type === "spot") { + var spotLight = light[light.type]; + var spLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.SpotLight(node.light, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero(), babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero(), 0, 0, gltfRuntime.scene); + spLight.name = node.name || ""; + if (spotLight.color) { + spLight.diffuse = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color3.FromArray(spotLight.color); + } + if (spotLight.fallOfAngle) { + spLight.angle = spotLight.fallOfAngle; + } + if (spotLight.fallOffExponent) { + spLight.exponent = spotLight.fallOffExponent; + } + lastNode = spLight; + } + } + } + // Cameras + else if (node.camera && !node.babylonNode && !gltfRuntime.importOnlyMeshes) { + var camera = gltfRuntime.cameras[node.camera]; + if (camera) { + gltfRuntime.scene._blockEntityCollection = !!gltfRuntime.assetContainer; + if (camera.type === "orthographic") { + var orthoCamera = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.FreeCamera(node.camera, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero(), gltfRuntime.scene, false); + orthoCamera.name = node.name || ""; + orthoCamera.mode = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Camera.ORTHOGRAPHIC_CAMERA; + orthoCamera.attachControl(); + lastNode = orthoCamera; + orthoCamera._parentContainer = gltfRuntime.assetContainer; + } + else if (camera.type === "perspective") { + var perspectiveCamera = camera[camera.type]; + var persCamera = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.FreeCamera(node.camera, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.Zero(), gltfRuntime.scene, false); + persCamera.name = node.name || ""; + persCamera.attachControl(); + if (!perspectiveCamera.aspectRatio) { + perspectiveCamera.aspectRatio = gltfRuntime.scene.getEngine().getRenderWidth() / gltfRuntime.scene.getEngine().getRenderHeight(); + } + if (perspectiveCamera.znear && perspectiveCamera.zfar) { + persCamera.maxZ = perspectiveCamera.zfar; + persCamera.minZ = perspectiveCamera.znear; + } + lastNode = persCamera; + persCamera._parentContainer = gltfRuntime.assetContainer; + } + gltfRuntime.scene._blockEntityCollection = false; + } + } + // Empty node + if (!node.jointName) { + if (node.babylonNode) { + return node.babylonNode; + } + else if (lastNode === null) { + gltfRuntime.scene._blockEntityCollection = !!gltfRuntime.assetContainer; + var dummy = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Mesh(node.name || "", gltfRuntime.scene); + dummy._parentContainer = gltfRuntime.assetContainer; + gltfRuntime.scene._blockEntityCollection = false; + node.babylonNode = dummy; + lastNode = dummy; + } + } + if (lastNode !== null) { + if (node.matrix && lastNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Mesh) { + configureNodeFromMatrix(lastNode, node); + } + else { + var translation = node.translation || [0, 0, 0]; + var rotation = node.rotation || [0, 0, 0, 1]; + var scale = node.scale || [1, 1, 1]; + configureNode(lastNode, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.FromArray(translation), babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Quaternion.FromArray(rotation), babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.FromArray(scale)); + } + lastNode.updateCache(true); + node.babylonNode = lastNode; + } + return lastNode; +}; +/** + * Traverses nodes and creates them + * @param gltfRuntime + * @param id + * @param parent + * @param meshIncluded + */ +var traverseNodes = function (gltfRuntime, id, parent, meshIncluded) { + if (meshIncluded === void 0) { meshIncluded = false; } + var node = gltfRuntime.nodes[id]; + var newNode = null; + if (gltfRuntime.importOnlyMeshes && !meshIncluded && gltfRuntime.importMeshesNames) { + if (gltfRuntime.importMeshesNames.indexOf(node.name || "") !== -1 || gltfRuntime.importMeshesNames.length === 0) { + meshIncluded = true; + } + else { + meshIncluded = false; + } + } + else { + meshIncluded = true; + } + if (!node.jointName && meshIncluded) { + newNode = importNode(gltfRuntime, node, id); + if (newNode !== null) { + newNode.id = id; + newNode.parent = parent; + } + } + if (node.children) { + for (var i = 0; i < node.children.length; i++) { + traverseNodes(gltfRuntime, node.children[i], newNode, meshIncluded); + } + } +}; +/** + * do stuff after buffers, shaders are loaded (e.g. hook up materials, load animations, etc.) + * @param gltfRuntime + */ +var postLoad = function (gltfRuntime) { + // Nodes + var currentScene = gltfRuntime.currentScene; + if (currentScene) { + for (var i = 0; i < currentScene.nodes.length; i++) { + traverseNodes(gltfRuntime, currentScene.nodes[i], null); + } + } + else { + for (var thing in gltfRuntime.scenes) { + currentScene = gltfRuntime.scenes[thing]; + for (var i = 0; i < currentScene.nodes.length; i++) { + traverseNodes(gltfRuntime, currentScene.nodes[i], null); + } + } + } + // Set animations + loadAnimations(gltfRuntime); + for (var i = 0; i < gltfRuntime.scene.skeletons.length; i++) { + var skeleton = gltfRuntime.scene.skeletons[i]; + gltfRuntime.scene.beginAnimation(skeleton, 0, Number.MAX_VALUE, true, 1.0); + } +}; +/** + * onBind shaderrs callback to set uniforms and matrices + * @param mesh + * @param gltfRuntime + * @param unTreatedUniforms + * @param shaderMaterial + * @param technique + * @param material + * @param onSuccess + */ +var onBindShaderMaterial = function (mesh, gltfRuntime, unTreatedUniforms, shaderMaterial, technique, material, onSuccess) { + var materialValues = material.values || technique.parameters; + for (var unif in unTreatedUniforms) { + var uniform = unTreatedUniforms[unif]; + var type = uniform.type; + if (type === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EParameterType.FLOAT_MAT2 || type === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EParameterType.FLOAT_MAT3 || type === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EParameterType.FLOAT_MAT4) { + if (uniform.semantic && !uniform.source && !uniform.node) { + _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_2__.GLTFUtils.SetMatrix(gltfRuntime.scene, mesh, uniform, unif, shaderMaterial.getEffect()); + } + else if (uniform.semantic && (uniform.source || uniform.node)) { + var source = gltfRuntime.scene.getNodeByName(uniform.source || uniform.node || ""); + if (source === null) { + source = gltfRuntime.scene.getNodeById(uniform.source || uniform.node || ""); + } + if (source === null) { + continue; + } + _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_2__.GLTFUtils.SetMatrix(gltfRuntime.scene, source, uniform, unif, shaderMaterial.getEffect()); + } + } + else { + var value = materialValues[technique.uniforms[unif]]; + if (!value) { + continue; + } + if (type === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EParameterType.SAMPLER_2D) { + var texture = gltfRuntime.textures[material.values ? value : uniform.value].babylonTexture; + if (texture === null || texture === undefined) { + continue; + } + shaderMaterial.getEffect().setTexture(unif, texture); + } + else { + _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_2__.GLTFUtils.SetUniform(shaderMaterial.getEffect(), unif, value, type); + } + } + } + onSuccess(shaderMaterial); +}; +/** + * Prepare uniforms to send the only one time + * Loads the appropriate textures + * @param gltfRuntime + * @param shaderMaterial + * @param technique + * @param material + */ +var prepareShaderMaterialUniforms = function (gltfRuntime, shaderMaterial, technique, material, unTreatedUniforms) { + var materialValues = material.values || technique.parameters; + var techniqueUniforms = technique.uniforms; + var _loop_1 = function (unif) { + var uniform = unTreatedUniforms[unif]; + var type = uniform.type; + var value = materialValues[techniqueUniforms[unif]]; + if (value === undefined) { + // In case the value is the same for all materials + value = uniform.value; + } + if (!value) { + return "continue"; + } + var onLoadTexture = function (uniformName) { + return function (texture) { + if (uniform.value && uniformName) { + // Static uniform + shaderMaterial.setTexture(uniformName, texture); + delete unTreatedUniforms[uniformName]; + } + }; + }; + // Texture (sampler2D) + if (type === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EParameterType.SAMPLER_2D) { + GLTFLoaderExtension.LoadTextureAsync(gltfRuntime, material.values ? value : uniform.value, onLoadTexture(unif), function () { return onLoadTexture(null); }); + } + // Others + else { + if (uniform.value && _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_2__.GLTFUtils.SetUniform(shaderMaterial, unif, material.values ? value : uniform.value, type)) { + // Static uniform + delete unTreatedUniforms[unif]; + } + } + }; + /** + * Prepare values here (not matrices) + */ + for (var unif in unTreatedUniforms) { + _loop_1(unif); + } +}; +/** + * Shader compilation failed + * @param program + * @param shaderMaterial + * @param onError + * @returns callback when shader is compiled + */ +var onShaderCompileError = function (program, shaderMaterial, onError) { + return function (effect, error) { + shaderMaterial.dispose(true); + onError("Cannot compile program named " + program.name + ". Error: " + error + ". Default material will be applied"); + }; +}; +/** + * Shader compilation success + * @param gltfRuntime + * @param shaderMaterial + * @param technique + * @param material + * @param unTreatedUniforms + * @param onSuccess + * @returns callback when shader is compiled + */ +var onShaderCompileSuccess = function (gltfRuntime, shaderMaterial, technique, material, unTreatedUniforms, onSuccess) { + return function (_) { + prepareShaderMaterialUniforms(gltfRuntime, shaderMaterial, technique, material, unTreatedUniforms); + shaderMaterial.onBind = function (mesh) { + onBindShaderMaterial(mesh, gltfRuntime, unTreatedUniforms, shaderMaterial, technique, material, onSuccess); + }; + }; +}; +/** + * Returns the appropriate uniform if already handled by babylon + * @param tokenizer + * @param technique + * @param unTreatedUniforms + * @returns the name of the uniform handled by babylon + */ +var parseShaderUniforms = function (tokenizer, technique, unTreatedUniforms) { + for (var unif in technique.uniforms) { + var uniform = technique.uniforms[unif]; + var uniformParameter = technique.parameters[uniform]; + if (tokenizer.currentIdentifier === unif) { + if (uniformParameter.semantic && !uniformParameter.source && !uniformParameter.node) { + var transformIndex = glTFTransforms.indexOf(uniformParameter.semantic); + if (transformIndex !== -1) { + delete unTreatedUniforms[unif]; + return babylonTransforms[transformIndex]; + } + } + } + } + return tokenizer.currentIdentifier; +}; +/** + * All shaders loaded. Create materials one by one + * @param gltfRuntime + */ +var importMaterials = function (gltfRuntime) { + // Create materials + for (var mat in gltfRuntime.materials) { + GLTFLoaderExtension.LoadMaterialAsync(gltfRuntime, mat, function () { }, function () { }); + } +}; +/** + * Implementation of the base glTF spec + * @internal + */ +var GLTFLoaderBase = /** @class */ (function () { + function GLTFLoaderBase() { + } + GLTFLoaderBase.CreateRuntime = function (parsedData, scene, rootUrl) { + var gltfRuntime = { + extensions: {}, + accessors: {}, + buffers: {}, + bufferViews: {}, + meshes: {}, + lights: {}, + cameras: {}, + nodes: {}, + images: {}, + textures: {}, + shaders: {}, + programs: {}, + samplers: {}, + techniques: {}, + materials: {}, + animations: {}, + skins: {}, + extensionsUsed: [], + scenes: {}, + buffersCount: 0, + shaderscount: 0, + scene: scene, + rootUrl: rootUrl, + loadedBufferCount: 0, + loadedBufferViews: {}, + loadedShaderCount: 0, + importOnlyMeshes: false, + dummyNodes: [], + assetContainer: null, + }; + // Parse + if (parsedData.extensions) { + parseObject(parsedData.extensions, "extensions", gltfRuntime); + } + if (parsedData.extensionsUsed) { + parseObject(parsedData.extensionsUsed, "extensionsUsed", gltfRuntime); + } + if (parsedData.buffers) { + parseBuffers(parsedData.buffers, gltfRuntime); + } + if (parsedData.bufferViews) { + parseObject(parsedData.bufferViews, "bufferViews", gltfRuntime); + } + if (parsedData.accessors) { + parseObject(parsedData.accessors, "accessors", gltfRuntime); + } + if (parsedData.meshes) { + parseObject(parsedData.meshes, "meshes", gltfRuntime); + } + if (parsedData.lights) { + parseObject(parsedData.lights, "lights", gltfRuntime); + } + if (parsedData.cameras) { + parseObject(parsedData.cameras, "cameras", gltfRuntime); + } + if (parsedData.nodes) { + parseObject(parsedData.nodes, "nodes", gltfRuntime); + } + if (parsedData.images) { + parseObject(parsedData.images, "images", gltfRuntime); + } + if (parsedData.textures) { + parseObject(parsedData.textures, "textures", gltfRuntime); + } + if (parsedData.shaders) { + parseShaders(parsedData.shaders, gltfRuntime); + } + if (parsedData.programs) { + parseObject(parsedData.programs, "programs", gltfRuntime); + } + if (parsedData.samplers) { + parseObject(parsedData.samplers, "samplers", gltfRuntime); + } + if (parsedData.techniques) { + parseObject(parsedData.techniques, "techniques", gltfRuntime); + } + if (parsedData.materials) { + parseObject(parsedData.materials, "materials", gltfRuntime); + } + if (parsedData.animations) { + parseObject(parsedData.animations, "animations", gltfRuntime); + } + if (parsedData.skins) { + parseObject(parsedData.skins, "skins", gltfRuntime); + } + if (parsedData.scenes) { + gltfRuntime.scenes = parsedData.scenes; + } + if (parsedData.scene && parsedData.scenes) { + gltfRuntime.currentScene = parsedData.scenes[parsedData.scene]; + } + return gltfRuntime; + }; + GLTFLoaderBase.LoadBufferAsync = function (gltfRuntime, id, onSuccess, onError, onProgress) { + var buffer = gltfRuntime.buffers[id]; + if (babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.IsBase64(buffer.uri)) { + setTimeout(function () { return onSuccess(new Uint8Array(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.DecodeBase64(buffer.uri))); }); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.LoadFile(gltfRuntime.rootUrl + buffer.uri, function (data) { return onSuccess(new Uint8Array(data)); }, onProgress, undefined, true, function (request) { + if (request) { + onError(request.status + " " + request.statusText); + } + }); + } + }; + GLTFLoaderBase.LoadTextureBufferAsync = function (gltfRuntime, id, onSuccess, onError) { + var texture = gltfRuntime.textures[id]; + if (!texture || !texture.source) { + onError(""); + return; + } + if (texture.babylonTexture) { + onSuccess(null); + return; + } + var source = gltfRuntime.images[texture.source]; + if (babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.IsBase64(source.uri)) { + setTimeout(function () { return onSuccess(new Uint8Array(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.DecodeBase64(source.uri))); }); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.LoadFile(gltfRuntime.rootUrl + source.uri, function (data) { return onSuccess(new Uint8Array(data)); }, undefined, undefined, true, function (request) { + if (request) { + onError(request.status + " " + request.statusText); + } + }); + } + }; + GLTFLoaderBase.CreateTextureAsync = function (gltfRuntime, id, buffer, onSuccess) { + var texture = gltfRuntime.textures[id]; + if (texture.babylonTexture) { + onSuccess(texture.babylonTexture); + return; + } + var sampler = gltfRuntime.samplers[texture.sampler]; + var createMipMaps = sampler.minFilter === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.ETextureFilterType.NEAREST_MIPMAP_NEAREST || + sampler.minFilter === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.ETextureFilterType.NEAREST_MIPMAP_LINEAR || + sampler.minFilter === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.ETextureFilterType.LINEAR_MIPMAP_NEAREST || + sampler.minFilter === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.ETextureFilterType.LINEAR_MIPMAP_LINEAR; + var samplingMode = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Texture.BILINEAR_SAMPLINGMODE; + var blob = buffer == null ? new Blob() : new Blob([buffer]); + var blobURL = URL.createObjectURL(blob); + var revokeBlobURL = function () { return URL.revokeObjectURL(blobURL); }; + var newTexture = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Texture(blobURL, gltfRuntime.scene, !createMipMaps, true, samplingMode, revokeBlobURL, revokeBlobURL); + if (sampler.wrapS !== undefined) { + newTexture.wrapU = _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_2__.GLTFUtils.GetWrapMode(sampler.wrapS); + } + if (sampler.wrapT !== undefined) { + newTexture.wrapV = _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_2__.GLTFUtils.GetWrapMode(sampler.wrapT); + } + newTexture.name = id; + texture.babylonTexture = newTexture; + onSuccess(newTexture); + }; + GLTFLoaderBase.LoadShaderStringAsync = function (gltfRuntime, id, onSuccess, onError) { + var shader = gltfRuntime.shaders[id]; + if (babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.IsBase64(shader.uri)) { + var shaderString = atob(shader.uri.split(",")[1]); + if (onSuccess) { + onSuccess(shaderString); + } + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.LoadFile(gltfRuntime.rootUrl + shader.uri, onSuccess, undefined, undefined, false, function (request) { + if (request && onError) { + onError(request.status + " " + request.statusText); + } + }); + } + }; + GLTFLoaderBase.LoadMaterialAsync = function (gltfRuntime, id, onSuccess, onError) { + var material = gltfRuntime.materials[id]; + if (!material.technique) { + if (onError) { + onError("No technique found."); + } + return; + } + var technique = gltfRuntime.techniques[material.technique]; + if (!technique) { + gltfRuntime.scene._blockEntityCollection = !!gltfRuntime.assetContainer; + var defaultMaterial = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.StandardMaterial(id, gltfRuntime.scene); + defaultMaterial._parentContainer = gltfRuntime.assetContainer; + gltfRuntime.scene._blockEntityCollection = false; + defaultMaterial.diffuseColor = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color3(0.5, 0.5, 0.5); + defaultMaterial.sideOrientation = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Material.CounterClockWiseSideOrientation; + onSuccess(defaultMaterial); + return; + } + var program = gltfRuntime.programs[technique.program]; + var states = technique.states; + var vertexShader = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Effect.ShadersStore[program.vertexShader + "VertexShader"]; + var pixelShader = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Effect.ShadersStore[program.fragmentShader + "PixelShader"]; + var newVertexShader = ""; + var newPixelShader = ""; + var vertexTokenizer = new Tokenizer(vertexShader); + var pixelTokenizer = new Tokenizer(pixelShader); + var unTreatedUniforms = {}; + var uniforms = []; + var attributes = []; + var samplers = []; + // Fill uniform, sampler2D and attributes + for (var unif in technique.uniforms) { + var uniform = technique.uniforms[unif]; + var uniformParameter = technique.parameters[uniform]; + unTreatedUniforms[unif] = uniformParameter; + if (uniformParameter.semantic && !uniformParameter.node && !uniformParameter.source) { + var transformIndex = glTFTransforms.indexOf(uniformParameter.semantic); + if (transformIndex !== -1) { + uniforms.push(babylonTransforms[transformIndex]); + delete unTreatedUniforms[unif]; + } + else { + uniforms.push(unif); + } + } + else if (uniformParameter.type === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EParameterType.SAMPLER_2D) { + samplers.push(unif); + } + else { + uniforms.push(unif); + } + } + for (var attr in technique.attributes) { + var attribute = technique.attributes[attr]; + var attributeParameter = technique.parameters[attribute]; + if (attributeParameter.semantic) { + var name_1 = getAttribute(attributeParameter); + if (name_1) { + attributes.push(name_1); + } + } + } + // Configure vertex shader + while (!vertexTokenizer.isEnd() && vertexTokenizer.getNextToken()) { + var tokenType = vertexTokenizer.currentToken; + if (tokenType !== ETokenType.IDENTIFIER) { + newVertexShader += vertexTokenizer.currentString; + continue; + } + var foundAttribute = false; + for (var attr in technique.attributes) { + var attribute = technique.attributes[attr]; + var attributeParameter = technique.parameters[attribute]; + if (vertexTokenizer.currentIdentifier === attr && attributeParameter.semantic) { + newVertexShader += getAttribute(attributeParameter); + foundAttribute = true; + break; + } + } + if (foundAttribute) { + continue; + } + newVertexShader += parseShaderUniforms(vertexTokenizer, technique, unTreatedUniforms); + } + // Configure pixel shader + while (!pixelTokenizer.isEnd() && pixelTokenizer.getNextToken()) { + var tokenType = pixelTokenizer.currentToken; + if (tokenType !== ETokenType.IDENTIFIER) { + newPixelShader += pixelTokenizer.currentString; + continue; + } + newPixelShader += parseShaderUniforms(pixelTokenizer, technique, unTreatedUniforms); + } + // Create shader material + var shaderPath = { + vertex: program.vertexShader + id, + fragment: program.fragmentShader + id, + }; + var options = { + attributes: attributes, + uniforms: uniforms, + samplers: samplers, + needAlphaBlending: states && states.enable && states.enable.indexOf(3042) !== -1, + }; + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Effect.ShadersStore[program.vertexShader + id + "VertexShader"] = newVertexShader; + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Effect.ShadersStore[program.fragmentShader + id + "PixelShader"] = newPixelShader; + var shaderMaterial = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.ShaderMaterial(id, gltfRuntime.scene, shaderPath, options); + shaderMaterial.onError = onShaderCompileError(program, shaderMaterial, onError); + shaderMaterial.onCompiled = onShaderCompileSuccess(gltfRuntime, shaderMaterial, technique, material, unTreatedUniforms, onSuccess); + shaderMaterial.sideOrientation = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Material.CounterClockWiseSideOrientation; + if (states && states.functions) { + var functions = states.functions; + if (functions.cullFace && functions.cullFace[0] !== _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.ECullingType.BACK) { + shaderMaterial.backFaceCulling = false; + } + var blendFunc = functions.blendFuncSeparate; + if (blendFunc) { + if (blendFunc[0] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.SRC_ALPHA && + blendFunc[1] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE_MINUS_SRC_ALPHA && + blendFunc[2] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE && + blendFunc[3] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE) { + shaderMaterial.alphaMode = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Constants.ALPHA_COMBINE; + } + else if (blendFunc[0] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE && + blendFunc[1] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE && + blendFunc[2] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ZERO && + blendFunc[3] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE) { + shaderMaterial.alphaMode = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Constants.ALPHA_ONEONE; + } + else if (blendFunc[0] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.SRC_ALPHA && + blendFunc[1] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE && + blendFunc[2] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ZERO && + blendFunc[3] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE) { + shaderMaterial.alphaMode = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Constants.ALPHA_ADD; + } + else if (blendFunc[0] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ZERO && + blendFunc[1] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE_MINUS_SRC_COLOR && + blendFunc[2] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE && + blendFunc[3] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE) { + shaderMaterial.alphaMode = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Constants.ALPHA_SUBTRACT; + } + else if (blendFunc[0] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.DST_COLOR && + blendFunc[1] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ZERO && + blendFunc[2] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE && + blendFunc[3] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE) { + shaderMaterial.alphaMode = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Constants.ALPHA_MULTIPLY; + } + else if (blendFunc[0] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.SRC_ALPHA && + blendFunc[1] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE_MINUS_SRC_COLOR && + blendFunc[2] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE && + blendFunc[3] === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EBlendingFunction.ONE) { + shaderMaterial.alphaMode = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Constants.ALPHA_MAXIMIZED; + } + } + } + }; + return GLTFLoaderBase; +}()); + +/** + * glTF V1 Loader + * @internal + * @deprecated + */ +var GLTFLoader = /** @class */ (function () { + function GLTFLoader() { + } + GLTFLoader.RegisterExtension = function (extension) { + if (GLTFLoader.Extensions[extension.name]) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.Error('Tool with the same name "' + extension.name + '" already exists'); + return; + } + GLTFLoader.Extensions[extension.name] = extension; + }; + GLTFLoader.prototype.dispose = function () { + // do nothing + }; + GLTFLoader.prototype._importMeshAsync = function (meshesNames, scene, data, rootUrl, assetContainer, onSuccess, onProgress, onError) { + var _this = this; + scene.useRightHandedSystem = true; + GLTFLoaderExtension.LoadRuntimeAsync(scene, data, rootUrl, function (gltfRuntime) { + gltfRuntime.assetContainer = assetContainer; + gltfRuntime.importOnlyMeshes = true; + if (meshesNames === "") { + gltfRuntime.importMeshesNames = []; + } + else if (typeof meshesNames === "string") { + gltfRuntime.importMeshesNames = [meshesNames]; + } + else if (meshesNames && !(meshesNames instanceof Array)) { + gltfRuntime.importMeshesNames = [meshesNames]; + } + else { + gltfRuntime.importMeshesNames = []; + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.Warn("Argument meshesNames must be of type string or string[]"); + } + // Create nodes + _this._createNodes(gltfRuntime); + var meshes = []; + var skeletons = []; + // Fill arrays of meshes and skeletons + for (var nde in gltfRuntime.nodes) { + var node = gltfRuntime.nodes[nde]; + if (node.babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.AbstractMesh) { + meshes.push(node.babylonNode); + } + } + for (var skl in gltfRuntime.skins) { + var skin = gltfRuntime.skins[skl]; + if (skin.babylonSkeleton instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Skeleton) { + skeletons.push(skin.babylonSkeleton); + } + } + // Load buffers, shaders, materials, etc. + _this._loadBuffersAsync(gltfRuntime, function () { + _this._loadShadersAsync(gltfRuntime, function () { + importMaterials(gltfRuntime); + postLoad(gltfRuntime); + if (!_glTFFileLoader__WEBPACK_IMPORTED_MODULE_3__.GLTFFileLoader.IncrementalLoading && onSuccess) { + onSuccess(meshes, skeletons); + } + }); + }); + if (_glTFFileLoader__WEBPACK_IMPORTED_MODULE_3__.GLTFFileLoader.IncrementalLoading && onSuccess) { + onSuccess(meshes, skeletons); + } + }, onError); + return true; + }; + /** + * Imports one or more meshes from a loaded gltf file and adds them to the scene + * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file + * @param scene the scene the meshes should be added to + * @param assetContainer defines the asset container to use (can be null) + * @param data gltf data containing information of the meshes in a loaded file + * @param rootUrl root url to load from + * @param onProgress event that fires when loading progress has occured + * @returns a promise containg the loaded meshes, particles, skeletons and animations + */ + GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, assetContainer, data, rootUrl, onProgress) { + var _this = this; + return new Promise(function (resolve, reject) { + _this._importMeshAsync(meshesNames, scene, data, rootUrl, assetContainer, function (meshes, skeletons) { + resolve({ + meshes: meshes, + particleSystems: [], + skeletons: skeletons, + animationGroups: [], + lights: [], + transformNodes: [], + geometries: [], + spriteManagers: [], + }); + }, onProgress, function (message) { + reject(new Error(message)); + }); + }); + }; + GLTFLoader.prototype._loadAsync = function (scene, data, rootUrl, onSuccess, onProgress, onError) { + var _this = this; + scene.useRightHandedSystem = true; + GLTFLoaderExtension.LoadRuntimeAsync(scene, data, rootUrl, function (gltfRuntime) { + // Load runtime extensios + GLTFLoaderExtension.LoadRuntimeExtensionsAsync(gltfRuntime, function () { + // Create nodes + _this._createNodes(gltfRuntime); + // Load buffers, shaders, materials, etc. + _this._loadBuffersAsync(gltfRuntime, function () { + _this._loadShadersAsync(gltfRuntime, function () { + importMaterials(gltfRuntime); + postLoad(gltfRuntime); + if (!_glTFFileLoader__WEBPACK_IMPORTED_MODULE_3__.GLTFFileLoader.IncrementalLoading) { + onSuccess(); + } + }); + }); + if (_glTFFileLoader__WEBPACK_IMPORTED_MODULE_3__.GLTFFileLoader.IncrementalLoading) { + onSuccess(); + } + }, onError); + }, onError); + }; + /** + * Imports all objects from a loaded gltf file and adds them to the scene + * @param scene the scene the objects should be added to + * @param data gltf data containing information of the meshes in a loaded file + * @param rootUrl root url to load from + * @param onProgress event that fires when loading progress has occured + * @returns a promise which completes when objects have been loaded to the scene + */ + GLTFLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress) { + var _this = this; + return new Promise(function (resolve, reject) { + _this._loadAsync(scene, data, rootUrl, function () { + resolve(); + }, onProgress, function (message) { + reject(new Error(message)); + }); + }); + }; + GLTFLoader.prototype._loadShadersAsync = function (gltfRuntime, onload) { + var hasShaders = false; + var processShader = function (sha, shader) { + GLTFLoaderExtension.LoadShaderStringAsync(gltfRuntime, sha, function (shaderString) { + if (shaderString instanceof ArrayBuffer) { + return; + } + gltfRuntime.loadedShaderCount++; + if (shaderString) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Effect.ShadersStore[sha + (shader.type === _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EShaderType.VERTEX ? "VertexShader" : "PixelShader")] = shaderString; + } + if (gltfRuntime.loadedShaderCount === gltfRuntime.shaderscount) { + onload(); + } + }, function () { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.Error("Error when loading shader program named " + sha + " located at " + shader.uri); + }); + }; + for (var sha in gltfRuntime.shaders) { + hasShaders = true; + var shader = gltfRuntime.shaders[sha]; + if (shader) { + processShader.bind(this, sha, shader)(); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.Error("No shader named: " + sha); + } + } + if (!hasShaders) { + onload(); + } + }; + GLTFLoader.prototype._loadBuffersAsync = function (gltfRuntime, onLoad) { + var hasBuffers = false; + var processBuffer = function (buf, buffer) { + GLTFLoaderExtension.LoadBufferAsync(gltfRuntime, buf, function (bufferView) { + gltfRuntime.loadedBufferCount++; + if (bufferView) { + if (bufferView.byteLength != gltfRuntime.buffers[buf].byteLength) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.Error("Buffer named " + buf + " is length " + bufferView.byteLength + ". Expected: " + buffer.byteLength); // Improve error message + } + gltfRuntime.loadedBufferViews[buf] = bufferView; + } + if (gltfRuntime.loadedBufferCount === gltfRuntime.buffersCount) { + onLoad(); + } + }, function () { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.Error("Error when loading buffer named " + buf + " located at " + buffer.uri); + }); + }; + for (var buf in gltfRuntime.buffers) { + hasBuffers = true; + var buffer = gltfRuntime.buffers[buf]; + if (buffer) { + processBuffer.bind(this, buf, buffer)(); + } + else { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.Error("No buffer named: " + buf); + } + } + if (!hasBuffers) { + onLoad(); + } + }; + GLTFLoader.prototype._createNodes = function (gltfRuntime) { + var currentScene = gltfRuntime.currentScene; + if (currentScene) { + // Only one scene even if multiple scenes are defined + for (var i = 0; i < currentScene.nodes.length; i++) { + traverseNodes(gltfRuntime, currentScene.nodes[i], null); + } + } + else { + // Load all scenes + for (var thing in gltfRuntime.scenes) { + currentScene = gltfRuntime.scenes[thing]; + for (var i = 0; i < currentScene.nodes.length; i++) { + traverseNodes(gltfRuntime, currentScene.nodes[i], null); + } + } + } + }; + GLTFLoader.Extensions = {}; + return GLTFLoader; +}()); + +/** @internal */ +var GLTFLoaderExtension = /** @class */ (function () { + function GLTFLoaderExtension(name) { + this._name = name; + } + Object.defineProperty(GLTFLoaderExtension.prototype, "name", { + get: function () { + return this._name; + }, + enumerable: false, + configurable: true + }); + /** + * Defines an override for loading the runtime + * Return true to stop further extensions from loading the runtime + * @param scene + * @param data + * @param rootUrl + * @param onSuccess + * @param onError + * @returns true to stop further extensions from loading the runtime + */ + GLTFLoaderExtension.prototype.loadRuntimeAsync = function (scene, data, rootUrl, onSuccess, onError) { + return false; + }; + /** + * Defines an onverride for creating gltf runtime + * Return true to stop further extensions from creating the runtime + * @param gltfRuntime + * @param onSuccess + * @param onError + * @returns true to stop further extensions from creating the runtime + */ + GLTFLoaderExtension.prototype.loadRuntimeExtensionsAsync = function (gltfRuntime, onSuccess, onError) { + return false; + }; + /** + * Defines an override for loading buffers + * Return true to stop further extensions from loading this buffer + * @param gltfRuntime + * @param id + * @param onSuccess + * @param onError + * @param onProgress + * @returns true to stop further extensions from loading this buffer + */ + GLTFLoaderExtension.prototype.loadBufferAsync = function (gltfRuntime, id, onSuccess, onError, onProgress) { + return false; + }; + /** + * Defines an override for loading texture buffers + * Return true to stop further extensions from loading this texture data + * @param gltfRuntime + * @param id + * @param onSuccess + * @param onError + * @returns true to stop further extensions from loading this texture data + */ + GLTFLoaderExtension.prototype.loadTextureBufferAsync = function (gltfRuntime, id, onSuccess, onError) { + return false; + }; + /** + * Defines an override for creating textures + * Return true to stop further extensions from loading this texture + * @param gltfRuntime + * @param id + * @param buffer + * @param onSuccess + * @param onError + * @returns true to stop further extensions from loading this texture + */ + GLTFLoaderExtension.prototype.createTextureAsync = function (gltfRuntime, id, buffer, onSuccess, onError) { + return false; + }; + /** + * Defines an override for loading shader strings + * Return true to stop further extensions from loading this shader data + * @param gltfRuntime + * @param id + * @param onSuccess + * @param onError + * @returns true to stop further extensions from loading this shader data + */ + GLTFLoaderExtension.prototype.loadShaderStringAsync = function (gltfRuntime, id, onSuccess, onError) { + return false; + }; + /** + * Defines an override for loading materials + * Return true to stop further extensions from loading this material + * @param gltfRuntime + * @param id + * @param onSuccess + * @param onError + * @returns true to stop further extensions from loading this material + */ + GLTFLoaderExtension.prototype.loadMaterialAsync = function (gltfRuntime, id, onSuccess, onError) { + return false; + }; + // --------- + // Utilities + // --------- + GLTFLoaderExtension.LoadRuntimeAsync = function (scene, data, rootUrl, onSuccess, onError) { + GLTFLoaderExtension._ApplyExtensions(function (loaderExtension) { + return loaderExtension.loadRuntimeAsync(scene, data, rootUrl, onSuccess, onError); + }, function () { + setTimeout(function () { + if (!onSuccess) { + return; + } + onSuccess(GLTFLoaderBase.CreateRuntime(data.json, scene, rootUrl)); + }); + }); + }; + GLTFLoaderExtension.LoadRuntimeExtensionsAsync = function (gltfRuntime, onSuccess, onError) { + GLTFLoaderExtension._ApplyExtensions(function (loaderExtension) { + return loaderExtension.loadRuntimeExtensionsAsync(gltfRuntime, onSuccess, onError); + }, function () { + setTimeout(function () { + onSuccess(); + }); + }); + }; + GLTFLoaderExtension.LoadBufferAsync = function (gltfRuntime, id, onSuccess, onError, onProgress) { + GLTFLoaderExtension._ApplyExtensions(function (loaderExtension) { + return loaderExtension.loadBufferAsync(gltfRuntime, id, onSuccess, onError, onProgress); + }, function () { + GLTFLoaderBase.LoadBufferAsync(gltfRuntime, id, onSuccess, onError, onProgress); + }); + }; + GLTFLoaderExtension.LoadTextureAsync = function (gltfRuntime, id, onSuccess, onError) { + GLTFLoaderExtension._LoadTextureBufferAsync(gltfRuntime, id, function (buffer) { + if (buffer) { + GLTFLoaderExtension._CreateTextureAsync(gltfRuntime, id, buffer, onSuccess, onError); + } + }, onError); + }; + GLTFLoaderExtension.LoadShaderStringAsync = function (gltfRuntime, id, onSuccess, onError) { + GLTFLoaderExtension._ApplyExtensions(function (loaderExtension) { + return loaderExtension.loadShaderStringAsync(gltfRuntime, id, onSuccess, onError); + }, function () { + GLTFLoaderBase.LoadShaderStringAsync(gltfRuntime, id, onSuccess, onError); + }); + }; + GLTFLoaderExtension.LoadMaterialAsync = function (gltfRuntime, id, onSuccess, onError) { + GLTFLoaderExtension._ApplyExtensions(function (loaderExtension) { + return loaderExtension.loadMaterialAsync(gltfRuntime, id, onSuccess, onError); + }, function () { + GLTFLoaderBase.LoadMaterialAsync(gltfRuntime, id, onSuccess, onError); + }); + }; + GLTFLoaderExtension._LoadTextureBufferAsync = function (gltfRuntime, id, onSuccess, onError) { + GLTFLoaderExtension._ApplyExtensions(function (loaderExtension) { + return loaderExtension.loadTextureBufferAsync(gltfRuntime, id, onSuccess, onError); + }, function () { + GLTFLoaderBase.LoadTextureBufferAsync(gltfRuntime, id, onSuccess, onError); + }); + }; + GLTFLoaderExtension._CreateTextureAsync = function (gltfRuntime, id, buffer, onSuccess, onError) { + GLTFLoaderExtension._ApplyExtensions(function (loaderExtension) { + return loaderExtension.createTextureAsync(gltfRuntime, id, buffer, onSuccess, onError); + }, function () { + GLTFLoaderBase.CreateTextureAsync(gltfRuntime, id, buffer, onSuccess); + }); + }; + GLTFLoaderExtension._ApplyExtensions = function (func, defaultFunc) { + for (var extensionName in GLTFLoader.Extensions) { + var loaderExtension = GLTFLoader.Extensions[extensionName]; + if (func(loaderExtension)) { + return; + } + } + defaultFunc(); + }; + return GLTFLoaderExtension; +}()); + +_glTFFileLoader__WEBPACK_IMPORTED_MODULE_3__.GLTFFileLoader._CreateGLTF1Loader = function () { return new GLTFLoader(); }; + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/1.0/glTFLoaderInterfaces.ts": +/*!*****************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/1.0/glTFLoaderInterfaces.ts ***! + \*****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EBlendingFunction: () => (/* binding */ EBlendingFunction), +/* harmony export */ EComponentType: () => (/* binding */ EComponentType), +/* harmony export */ ECullingType: () => (/* binding */ ECullingType), +/* harmony export */ EParameterType: () => (/* binding */ EParameterType), +/* harmony export */ EShaderType: () => (/* binding */ EShaderType), +/* harmony export */ ETextureFilterType: () => (/* binding */ ETextureFilterType), +/* harmony export */ ETextureFormat: () => (/* binding */ ETextureFormat), +/* harmony export */ ETextureWrapMode: () => (/* binding */ ETextureWrapMode) +/* harmony export */ }); +/** + * Enums + * @internal + */ +var EComponentType; +(function (EComponentType) { + EComponentType[EComponentType["BYTE"] = 5120] = "BYTE"; + EComponentType[EComponentType["UNSIGNED_BYTE"] = 5121] = "UNSIGNED_BYTE"; + EComponentType[EComponentType["SHORT"] = 5122] = "SHORT"; + EComponentType[EComponentType["UNSIGNED_SHORT"] = 5123] = "UNSIGNED_SHORT"; + EComponentType[EComponentType["FLOAT"] = 5126] = "FLOAT"; +})(EComponentType || (EComponentType = {})); +/** @internal */ +var EShaderType; +(function (EShaderType) { + EShaderType[EShaderType["FRAGMENT"] = 35632] = "FRAGMENT"; + EShaderType[EShaderType["VERTEX"] = 35633] = "VERTEX"; +})(EShaderType || (EShaderType = {})); +/** @internal */ +var EParameterType; +(function (EParameterType) { + EParameterType[EParameterType["BYTE"] = 5120] = "BYTE"; + EParameterType[EParameterType["UNSIGNED_BYTE"] = 5121] = "UNSIGNED_BYTE"; + EParameterType[EParameterType["SHORT"] = 5122] = "SHORT"; + EParameterType[EParameterType["UNSIGNED_SHORT"] = 5123] = "UNSIGNED_SHORT"; + EParameterType[EParameterType["INT"] = 5124] = "INT"; + EParameterType[EParameterType["UNSIGNED_INT"] = 5125] = "UNSIGNED_INT"; + EParameterType[EParameterType["FLOAT"] = 5126] = "FLOAT"; + EParameterType[EParameterType["FLOAT_VEC2"] = 35664] = "FLOAT_VEC2"; + EParameterType[EParameterType["FLOAT_VEC3"] = 35665] = "FLOAT_VEC3"; + EParameterType[EParameterType["FLOAT_VEC4"] = 35666] = "FLOAT_VEC4"; + EParameterType[EParameterType["INT_VEC2"] = 35667] = "INT_VEC2"; + EParameterType[EParameterType["INT_VEC3"] = 35668] = "INT_VEC3"; + EParameterType[EParameterType["INT_VEC4"] = 35669] = "INT_VEC4"; + EParameterType[EParameterType["BOOL"] = 35670] = "BOOL"; + EParameterType[EParameterType["BOOL_VEC2"] = 35671] = "BOOL_VEC2"; + EParameterType[EParameterType["BOOL_VEC3"] = 35672] = "BOOL_VEC3"; + EParameterType[EParameterType["BOOL_VEC4"] = 35673] = "BOOL_VEC4"; + EParameterType[EParameterType["FLOAT_MAT2"] = 35674] = "FLOAT_MAT2"; + EParameterType[EParameterType["FLOAT_MAT3"] = 35675] = "FLOAT_MAT3"; + EParameterType[EParameterType["FLOAT_MAT4"] = 35676] = "FLOAT_MAT4"; + EParameterType[EParameterType["SAMPLER_2D"] = 35678] = "SAMPLER_2D"; +})(EParameterType || (EParameterType = {})); +/** @internal */ +var ETextureWrapMode; +(function (ETextureWrapMode) { + ETextureWrapMode[ETextureWrapMode["CLAMP_TO_EDGE"] = 33071] = "CLAMP_TO_EDGE"; + ETextureWrapMode[ETextureWrapMode["MIRRORED_REPEAT"] = 33648] = "MIRRORED_REPEAT"; + ETextureWrapMode[ETextureWrapMode["REPEAT"] = 10497] = "REPEAT"; +})(ETextureWrapMode || (ETextureWrapMode = {})); +/** @internal */ +var ETextureFilterType; +(function (ETextureFilterType) { + ETextureFilterType[ETextureFilterType["NEAREST"] = 9728] = "NEAREST"; + ETextureFilterType[ETextureFilterType["LINEAR"] = 9728] = "LINEAR"; + ETextureFilterType[ETextureFilterType["NEAREST_MIPMAP_NEAREST"] = 9984] = "NEAREST_MIPMAP_NEAREST"; + ETextureFilterType[ETextureFilterType["LINEAR_MIPMAP_NEAREST"] = 9985] = "LINEAR_MIPMAP_NEAREST"; + ETextureFilterType[ETextureFilterType["NEAREST_MIPMAP_LINEAR"] = 9986] = "NEAREST_MIPMAP_LINEAR"; + ETextureFilterType[ETextureFilterType["LINEAR_MIPMAP_LINEAR"] = 9987] = "LINEAR_MIPMAP_LINEAR"; +})(ETextureFilterType || (ETextureFilterType = {})); +/** @internal */ +var ETextureFormat; +(function (ETextureFormat) { + ETextureFormat[ETextureFormat["ALPHA"] = 6406] = "ALPHA"; + ETextureFormat[ETextureFormat["RGB"] = 6407] = "RGB"; + ETextureFormat[ETextureFormat["RGBA"] = 6408] = "RGBA"; + ETextureFormat[ETextureFormat["LUMINANCE"] = 6409] = "LUMINANCE"; + ETextureFormat[ETextureFormat["LUMINANCE_ALPHA"] = 6410] = "LUMINANCE_ALPHA"; +})(ETextureFormat || (ETextureFormat = {})); +/** @internal */ +var ECullingType; +(function (ECullingType) { + ECullingType[ECullingType["FRONT"] = 1028] = "FRONT"; + ECullingType[ECullingType["BACK"] = 1029] = "BACK"; + ECullingType[ECullingType["FRONT_AND_BACK"] = 1032] = "FRONT_AND_BACK"; +})(ECullingType || (ECullingType = {})); +/** @internal */ +var EBlendingFunction; +(function (EBlendingFunction) { + EBlendingFunction[EBlendingFunction["ZERO"] = 0] = "ZERO"; + EBlendingFunction[EBlendingFunction["ONE"] = 1] = "ONE"; + EBlendingFunction[EBlendingFunction["SRC_COLOR"] = 768] = "SRC_COLOR"; + EBlendingFunction[EBlendingFunction["ONE_MINUS_SRC_COLOR"] = 769] = "ONE_MINUS_SRC_COLOR"; + EBlendingFunction[EBlendingFunction["DST_COLOR"] = 774] = "DST_COLOR"; + EBlendingFunction[EBlendingFunction["ONE_MINUS_DST_COLOR"] = 775] = "ONE_MINUS_DST_COLOR"; + EBlendingFunction[EBlendingFunction["SRC_ALPHA"] = 770] = "SRC_ALPHA"; + EBlendingFunction[EBlendingFunction["ONE_MINUS_SRC_ALPHA"] = 771] = "ONE_MINUS_SRC_ALPHA"; + EBlendingFunction[EBlendingFunction["DST_ALPHA"] = 772] = "DST_ALPHA"; + EBlendingFunction[EBlendingFunction["ONE_MINUS_DST_ALPHA"] = 773] = "ONE_MINUS_DST_ALPHA"; + EBlendingFunction[EBlendingFunction["CONSTANT_COLOR"] = 32769] = "CONSTANT_COLOR"; + EBlendingFunction[EBlendingFunction["ONE_MINUS_CONSTANT_COLOR"] = 32770] = "ONE_MINUS_CONSTANT_COLOR"; + EBlendingFunction[EBlendingFunction["CONSTANT_ALPHA"] = 32771] = "CONSTANT_ALPHA"; + EBlendingFunction[EBlendingFunction["ONE_MINUS_CONSTANT_ALPHA"] = 32772] = "ONE_MINUS_CONSTANT_ALPHA"; + EBlendingFunction[EBlendingFunction["SRC_ALPHA_SATURATE"] = 776] = "SRC_ALPHA_SATURATE"; +})(EBlendingFunction || (EBlendingFunction = {})); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/1.0/glTFLoaderUtils.ts": +/*!************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/1.0/glTFLoaderUtils.ts ***! + \************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFUtils: () => (/* binding */ GLTFUtils) +/* harmony export */ }); +/* harmony import */ var _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./glTFLoaderInterfaces */ "../../../dev/loaders/src/glTF/1.0/glTFLoaderInterfaces.ts"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/Textures/texture */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__); + + + + + + +/** + * Utils functions for GLTF + * @internal + * @deprecated + */ +var GLTFUtils = /** @class */ (function () { + function GLTFUtils() { + } + /** + * Sets the given "parameter" matrix + * @param scene the Scene object + * @param source the source node where to pick the matrix + * @param parameter the GLTF technique parameter + * @param uniformName the name of the shader's uniform + * @param shaderMaterial the shader material + */ + GLTFUtils.SetMatrix = function (scene, source, parameter, uniformName, shaderMaterial) { + var mat = null; + if (parameter.semantic === "MODEL") { + mat = source.getWorldMatrix(); + } + else if (parameter.semantic === "PROJECTION") { + mat = scene.getProjectionMatrix(); + } + else if (parameter.semantic === "VIEW") { + mat = scene.getViewMatrix(); + } + else if (parameter.semantic === "MODELVIEWINVERSETRANSPOSE") { + mat = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Matrix.Transpose(source.getWorldMatrix().multiply(scene.getViewMatrix()).invert()); + } + else if (parameter.semantic === "MODELVIEW") { + mat = source.getWorldMatrix().multiply(scene.getViewMatrix()); + } + else if (parameter.semantic === "MODELVIEWPROJECTION") { + mat = source.getWorldMatrix().multiply(scene.getTransformMatrix()); + } + else if (parameter.semantic === "MODELINVERSE") { + mat = source.getWorldMatrix().invert(); + } + else if (parameter.semantic === "VIEWINVERSE") { + mat = scene.getViewMatrix().invert(); + } + else if (parameter.semantic === "PROJECTIONINVERSE") { + mat = scene.getProjectionMatrix().invert(); + } + else if (parameter.semantic === "MODELVIEWINVERSE") { + mat = source.getWorldMatrix().multiply(scene.getViewMatrix()).invert(); + } + else if (parameter.semantic === "MODELVIEWPROJECTIONINVERSE") { + mat = source.getWorldMatrix().multiply(scene.getTransformMatrix()).invert(); + } + else if (parameter.semantic === "MODELINVERSETRANSPOSE") { + mat = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Matrix.Transpose(source.getWorldMatrix().invert()); + } + if (mat) { + switch (parameter.type) { + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EParameterType.FLOAT_MAT2: + shaderMaterial.setMatrix2x2(uniformName, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Matrix.GetAsMatrix2x2(mat)); + break; + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EParameterType.FLOAT_MAT3: + shaderMaterial.setMatrix3x3(uniformName, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Matrix.GetAsMatrix3x3(mat)); + break; + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EParameterType.FLOAT_MAT4: + shaderMaterial.setMatrix(uniformName, mat); + break; + default: + break; + } + } + }; + /** + * Sets the given "parameter" matrix + * @param shaderMaterial the shader material + * @param uniform the name of the shader's uniform + * @param value the value of the uniform + * @param type the uniform's type (EParameterType FLOAT, VEC2, VEC3 or VEC4) + * @returns true if set, else false + */ + GLTFUtils.SetUniform = function (shaderMaterial, uniform, value, type) { + switch (type) { + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EParameterType.FLOAT: + shaderMaterial.setFloat(uniform, value); + return true; + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EParameterType.FLOAT_VEC2: + shaderMaterial.setVector2(uniform, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector2.FromArray(value)); + return true; + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EParameterType.FLOAT_VEC3: + shaderMaterial.setVector3(uniform, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3.FromArray(value)); + return true; + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EParameterType.FLOAT_VEC4: + shaderMaterial.setVector4(uniform, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector4.FromArray(value)); + return true; + default: + return false; + } + }; + /** + * Returns the wrap mode of the texture + * @param mode the mode value + * @returns the wrap mode (TEXTURE_WRAP_ADDRESSMODE, MIRROR_ADDRESSMODE or CLAMP_ADDRESSMODE) + */ + GLTFUtils.GetWrapMode = function (mode) { + switch (mode) { + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.ETextureWrapMode.CLAMP_TO_EDGE: + return babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Texture.CLAMP_ADDRESSMODE; + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.ETextureWrapMode.MIRRORED_REPEAT: + return babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Texture.MIRROR_ADDRESSMODE; + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.ETextureWrapMode.REPEAT: + return babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Texture.WRAP_ADDRESSMODE; + default: + return babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Texture.WRAP_ADDRESSMODE; + } + }; + /** + * Returns the byte stride giving an accessor + * @param accessor the GLTF accessor objet + * @returns the byte stride + */ + GLTFUtils.GetByteStrideFromType = function (accessor) { + // Needs this function since "byteStride" isn't requiered in glTF format + var type = accessor.type; + switch (type) { + case "VEC2": + return 2; + case "VEC3": + return 3; + case "VEC4": + return 4; + case "MAT2": + return 4; + case "MAT3": + return 9; + case "MAT4": + return 16; + default: + return 1; + } + }; + /** + * Returns the texture filter mode giving a mode value + * @param mode the filter mode value + * @returns the filter mode (TODO - needs to be a type?) + */ + GLTFUtils.GetTextureFilterMode = function (mode) { + switch (mode) { + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.ETextureFilterType.LINEAR: + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.ETextureFilterType.LINEAR_MIPMAP_NEAREST: + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.ETextureFilterType.LINEAR_MIPMAP_LINEAR: + return babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Texture.TRILINEAR_SAMPLINGMODE; + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.ETextureFilterType.NEAREST: + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.ETextureFilterType.NEAREST_MIPMAP_NEAREST: + return babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Texture.NEAREST_SAMPLINGMODE; + default: + return babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Texture.BILINEAR_SAMPLINGMODE; + } + }; + GLTFUtils.GetBufferFromBufferView = function (gltfRuntime, bufferView, byteOffset, byteLength, componentType) { + byteOffset = bufferView.byteOffset + byteOffset; + var loadedBufferView = gltfRuntime.loadedBufferViews[bufferView.buffer]; + if (byteOffset + byteLength > loadedBufferView.byteLength) { + throw new Error("Buffer access is out of range"); + } + var buffer = loadedBufferView.buffer; + byteOffset += loadedBufferView.byteOffset; + switch (componentType) { + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EComponentType.BYTE: + return new Int8Array(buffer, byteOffset, byteLength); + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EComponentType.UNSIGNED_BYTE: + return new Uint8Array(buffer, byteOffset, byteLength); + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EComponentType.SHORT: + return new Int16Array(buffer, byteOffset, byteLength); + case _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_0__.EComponentType.UNSIGNED_SHORT: + return new Uint16Array(buffer, byteOffset, byteLength); + default: + return new Float32Array(buffer, byteOffset, byteLength); + } + }; + /** + * Returns a buffer from its accessor + * @param gltfRuntime the GLTF runtime + * @param accessor the GLTF accessor + * @returns an array buffer view + */ + GLTFUtils.GetBufferFromAccessor = function (gltfRuntime, accessor) { + var bufferView = gltfRuntime.bufferViews[accessor.bufferView]; + var byteLength = accessor.count * GLTFUtils.GetByteStrideFromType(accessor); + return GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, accessor.byteOffset, byteLength, accessor.componentType); + }; + /** + * Decodes a buffer view into a string + * @param view the buffer view + * @returns a string + */ + GLTFUtils.DecodeBufferToText = function (view) { + var result = ""; + var length = view.byteLength; + for (var i = 0; i < length; ++i) { + result += String.fromCharCode(view[i]); + } + return result; + }; + /** + * Returns the default material of gltf. Related to + * https://github.com/KhronosGroup/glTF/tree/master/specification/1.0#appendix-a-default-material + * @param scene the Babylon.js scene + * @returns the default Babylon material + */ + GLTFUtils.GetDefaultMaterial = function (scene) { + if (!GLTFUtils._DefaultMaterial) { + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Effect.ShadersStore["GLTFDefaultMaterialVertexShader"] = [ + "precision highp float;", + "", + "uniform mat4 worldView;", + "uniform mat4 projection;", + "", + "attribute vec3 position;", + "", + "void main(void)", + "{", + " gl_Position = projection * worldView * vec4(position, 1.0);", + "}", + ].join("\n"); + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Effect.ShadersStore["GLTFDefaultMaterialPixelShader"] = [ + "precision highp float;", + "", + "uniform vec4 u_emission;", + "", + "void main(void)", + "{", + " gl_FragColor = u_emission;", + "}", + ].join("\n"); + var shaderPath = { + vertex: "GLTFDefaultMaterial", + fragment: "GLTFDefaultMaterial", + }; + var options = { + attributes: ["position"], + uniforms: ["worldView", "projection", "u_emission"], + samplers: new Array(), + needAlphaBlending: false, + }; + GLTFUtils._DefaultMaterial = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.ShaderMaterial("GLTFDefaultMaterial", scene, shaderPath, options); + GLTFUtils._DefaultMaterial.setColor4("u_emission", new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color4(0.5, 0.5, 0.5, 1.0)); + } + return GLTFUtils._DefaultMaterial; + }; + // The GLTF default material + GLTFUtils._DefaultMaterial = null; + return GLTFUtils; +}()); + + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/1.0/glTFMaterialsCommonExtension.ts": +/*!*************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/1.0/glTFMaterialsCommonExtension.ts ***! + \*************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFMaterialsCommonExtension: () => (/* binding */ GLTFMaterialsCommonExtension) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./glTFLoader */ "../../../dev/loaders/src/glTF/1.0/glTFLoader.ts"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Lights/spotLight */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__); + + + + + + + + + + + +/** + * @internal + * @deprecated + */ +var GLTFMaterialsCommonExtension = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__extends)(GLTFMaterialsCommonExtension, _super); + function GLTFMaterialsCommonExtension() { + return _super.call(this, "KHR_materials_common") || this; + } + GLTFMaterialsCommonExtension.prototype.loadRuntimeExtensionsAsync = function (gltfRuntime) { + if (!gltfRuntime.extensions) { + return false; + } + var extension = gltfRuntime.extensions[this.name]; + if (!extension) { + return false; + } + // Create lights + var lights = extension.lights; + if (lights) { + for (var thing in lights) { + var light = lights[thing]; + switch (light.type) { + case "ambient": { + var ambientLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.HemisphericLight(light.name, new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, 1, 0), gltfRuntime.scene); + var ambient = light.ambient; + if (ambient) { + ambientLight.diffuse = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color3.FromArray(ambient.color || [1, 1, 1]); + } + break; + } + case "point": { + var pointLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.PointLight(light.name, new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3(10, 10, 10), gltfRuntime.scene); + var point = light.point; + if (point) { + pointLight.diffuse = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color3.FromArray(point.color || [1, 1, 1]); + } + break; + } + case "directional": { + var dirLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.DirectionalLight(light.name, new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, -1, 0), gltfRuntime.scene); + var directional = light.directional; + if (directional) { + dirLight.diffuse = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color3.FromArray(directional.color || [1, 1, 1]); + } + break; + } + case "spot": { + var spot = light.spot; + if (spot) { + var spotLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.SpotLight(light.name, new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, 10, 0), new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Vector3(0, -1, 0), spot.fallOffAngle || Math.PI, spot.fallOffExponent || 0.0, gltfRuntime.scene); + spotLight.diffuse = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color3.FromArray(spot.color || [1, 1, 1]); + } + break; + } + default: + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Tools.Warn('GLTF Material Common extension: light type "' + light.type + "” not supported"); + break; + } + } + } + return false; + }; + GLTFMaterialsCommonExtension.prototype.loadMaterialAsync = function (gltfRuntime, id, onSuccess, onError) { + var material = gltfRuntime.materials[id]; + if (!material || !material.extensions) { + return false; + } + var extension = material.extensions[this.name]; + if (!extension) { + return false; + } + var standardMaterial = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.StandardMaterial(id, gltfRuntime.scene); + standardMaterial.sideOrientation = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Material.CounterClockWiseSideOrientation; + if (extension.technique === "CONSTANT") { + standardMaterial.disableLighting = true; + } + standardMaterial.backFaceCulling = extension.doubleSided === undefined ? false : !extension.doubleSided; + standardMaterial.alpha = extension.values.transparency === undefined ? 1.0 : extension.values.transparency; + standardMaterial.specularPower = extension.values.shininess === undefined ? 0.0 : extension.values.shininess; + // Ambient + if (typeof extension.values.ambient === "string") { + this._loadTexture(gltfRuntime, extension.values.ambient, standardMaterial, "ambientTexture", onError); + } + else { + standardMaterial.ambientColor = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color3.FromArray(extension.values.ambient || [0, 0, 0]); + } + // Diffuse + if (typeof extension.values.diffuse === "string") { + this._loadTexture(gltfRuntime, extension.values.diffuse, standardMaterial, "diffuseTexture", onError); + } + else { + standardMaterial.diffuseColor = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color3.FromArray(extension.values.diffuse || [0, 0, 0]); + } + // Emission + if (typeof extension.values.emission === "string") { + this._loadTexture(gltfRuntime, extension.values.emission, standardMaterial, "emissiveTexture", onError); + } + else { + standardMaterial.emissiveColor = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color3.FromArray(extension.values.emission || [0, 0, 0]); + } + // Specular + if (typeof extension.values.specular === "string") { + this._loadTexture(gltfRuntime, extension.values.specular, standardMaterial, "specularTexture", onError); + } + else { + standardMaterial.specularColor = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__.Color3.FromArray(extension.values.specular || [0, 0, 0]); + } + return true; + }; + GLTFMaterialsCommonExtension.prototype._loadTexture = function (gltfRuntime, id, material, propertyPath, onError) { + // Create buffer from texture url + _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderBase.LoadTextureBufferAsync(gltfRuntime, id, function (buffer) { + // Create texture from buffer + _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderBase.CreateTextureAsync(gltfRuntime, id, buffer, function (texture) { return (material[propertyPath] = texture); }); + }, onError); + }; + return GLTFMaterialsCommonExtension; +}(_glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderExtension)); + +_glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.RegisterExtension(new GLTFMaterialsCommonExtension()); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/1.0/index.ts": +/*!**************************************************!*\ + !*** ../../../dev/loaders/src/glTF/1.0/index.ts ***! + \**************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EBlendingFunction: () => (/* reexport safe */ _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_2__.EBlendingFunction), +/* harmony export */ EComponentType: () => (/* reexport safe */ _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_2__.EComponentType), +/* harmony export */ ECullingType: () => (/* reexport safe */ _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_2__.ECullingType), +/* harmony export */ EParameterType: () => (/* reexport safe */ _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_2__.EParameterType), +/* harmony export */ EShaderType: () => (/* reexport safe */ _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_2__.EShaderType), +/* harmony export */ ETextureFilterType: () => (/* reexport safe */ _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_2__.ETextureFilterType), +/* harmony export */ ETextureFormat: () => (/* reexport safe */ _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_2__.ETextureFormat), +/* harmony export */ ETextureWrapMode: () => (/* reexport safe */ _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_2__.ETextureWrapMode), +/* harmony export */ GLTFBinaryExtension: () => (/* reexport safe */ _glTFBinaryExtension__WEBPACK_IMPORTED_MODULE_0__.GLTFBinaryExtension), +/* harmony export */ GLTFLoader: () => (/* reexport safe */ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader), +/* harmony export */ GLTFLoaderBase: () => (/* reexport safe */ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderBase), +/* harmony export */ GLTFLoaderExtension: () => (/* reexport safe */ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderExtension), +/* harmony export */ GLTFMaterialsCommonExtension: () => (/* reexport safe */ _glTFMaterialsCommonExtension__WEBPACK_IMPORTED_MODULE_4__.GLTFMaterialsCommonExtension), +/* harmony export */ GLTFUtils: () => (/* reexport safe */ _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_3__.GLTFUtils) +/* harmony export */ }); +/* harmony import */ var _glTFBinaryExtension__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./glTFBinaryExtension */ "../../../dev/loaders/src/glTF/1.0/glTFBinaryExtension.ts"); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./glTFLoader */ "../../../dev/loaders/src/glTF/1.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glTFLoaderInterfaces */ "../../../dev/loaders/src/glTF/1.0/glTFLoaderInterfaces.ts"); +/* harmony import */ var _glTFLoaderUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./glTFLoaderUtils */ "../../../dev/loaders/src/glTF/1.0/glTFLoaderUtils.ts"); +/* harmony import */ var _glTFMaterialsCommonExtension__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./glTFMaterialsCommonExtension */ "../../../dev/loaders/src/glTF/1.0/glTFMaterialsCommonExtension.ts"); + + + + + + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_lights_image_based.ts": +/*!******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/EXT_lights_image_based.ts ***! + \******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_lights_image_based: () => (/* binding */ EXT_lights_image_based) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Textures/rawCubeTexture */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + +var NAME = "EXT_lights_image_based"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_lights_image_based/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var EXT_lights_image_based = /** @class */ (function () { + /** + * @internal + */ + function EXT_lights_image_based(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + EXT_lights_image_based.prototype.dispose = function () { + this._loader = null; + delete this._lights; + }; + /** @internal */ + EXT_lights_image_based.prototype.onLoading = function () { + var extensions = this._loader.gltf.extensions; + if (extensions && extensions[this.name]) { + var extension = extensions[this.name]; + this._lights = extension.lights; + } + }; + /** + * @internal + */ + EXT_lights_image_based.prototype.loadSceneAsync = function (context, scene) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, scene, this.name, function (extensionContext, extension) { + _this._loader._allMaterialsDirtyRequired = true; + var promises = new Array(); + promises.push(_this._loader.loadSceneAsync(context, scene)); + _this._loader.logOpen("".concat(extensionContext)); + var light = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("".concat(extensionContext, "/light"), _this._lights, extension.light); + promises.push(_this._loadLightAsync("/extensions/".concat(_this.name, "/lights/").concat(extension.light), light).then(function (texture) { + _this._loader.babylonScene.environmentTexture = texture; + })); + _this._loader.logClose(); + return Promise.all(promises).then(function () { }); + }); + }; + EXT_lights_image_based.prototype._loadLightAsync = function (context, light) { + var _this = this; + if (!light._loaded) { + var promises = new Array(); + this._loader.logOpen("".concat(context)); + var imageData_1 = new Array(light.specularImages.length); + var _loop_1 = function (mipmap) { + var faces = light.specularImages[mipmap]; + imageData_1[mipmap] = new Array(faces.length); + var _loop_2 = function (face) { + var specularImageContext = "".concat(context, "/specularImages/").concat(mipmap, "/").concat(face); + this_1._loader.logOpen("".concat(specularImageContext)); + var index = faces[face]; + var image = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get(specularImageContext, this_1._loader.gltf.images, index); + promises.push(this_1._loader.loadImageAsync("/images/".concat(index), image).then(function (data) { + imageData_1[mipmap][face] = data; + })); + this_1._loader.logClose(); + }; + for (var face = 0; face < faces.length; face++) { + _loop_2(face); + } + }; + var this_1 = this; + for (var mipmap = 0; mipmap < light.specularImages.length; mipmap++) { + _loop_1(mipmap); + } + this._loader.logClose(); + light._loaded = Promise.all(promises).then(function () { + var babylonTexture = new babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__.RawCubeTexture(_this._loader.babylonScene, null, light.specularImageSize); + babylonTexture.name = light.name || "environment"; + light._babylonTexture = babylonTexture; + if (light.intensity != undefined) { + babylonTexture.level = light.intensity; + } + if (light.rotation) { + var rotation = babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArray(light.rotation); + // Invert the rotation so that positive rotation is counter-clockwise. + if (!_this._loader.babylonScene.useRightHandedSystem) { + rotation = babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Inverse(rotation); + } + babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__.Matrix.FromQuaternionToRef(rotation, babylonTexture.getReflectionTextureMatrix()); + } + if (!light.irradianceCoefficients) { + throw new Error("".concat(context, ": Irradiance coefficients are missing")); + } + var sphericalHarmonics = babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__.SphericalHarmonics.FromArray(light.irradianceCoefficients); + sphericalHarmonics.scaleInPlace(light.intensity); + sphericalHarmonics.convertIrradianceToLambertianRadiance(); + var sphericalPolynomial = babylonjs_Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__.SphericalPolynomial.FromHarmonics(sphericalHarmonics); + // Compute the lod generation scale to fit exactly to the number of levels available. + var lodGenerationScale = (imageData_1.length - 1) / Math.log2(light.specularImageSize); + return babylonTexture.updateRGBDAsync(imageData_1, sphericalPolynomial, lodGenerationScale); + }); + } + return light._loaded.then(function () { + return light._babylonTexture; + }); + }; + return EXT_lights_image_based; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new EXT_lights_image_based(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts": +/*!*******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_mesh_gpu_instancing: () => (/* binding */ EXT_mesh_gpu_instancing) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Meshes/thinInstanceMesh */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "EXT_mesh_gpu_instancing"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_mesh_gpu_instancing/README.md) + * [Playground Sample](https://playground.babylonjs.com/#QFIGLW#9) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var EXT_mesh_gpu_instancing = /** @class */ (function () { + /** + * @internal + */ + function EXT_mesh_gpu_instancing(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + EXT_mesh_gpu_instancing.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + EXT_mesh_gpu_instancing.prototype.loadNodeAsync = function (context, node, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) { + _this._loader._disableInstancedMesh++; + var promise = _this._loader.loadNodeAsync("/nodes/".concat(node.index), node, assign); + _this._loader._disableInstancedMesh--; + if (!node._primitiveBabylonMeshes) { + return promise; + } + var promises = new Array(); + var instanceCount = 0; + var loadAttribute = function (attribute) { + if (extension.attributes[attribute] == undefined) { + promises.push(Promise.resolve(null)); + return; + } + var accessor = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("".concat(extensionContext, "/attributes/").concat(attribute), _this._loader.gltf.accessors, extension.attributes[attribute]); + promises.push(_this._loader._loadFloatAccessorAsync("/accessors/".concat(accessor.bufferView), accessor)); + if (instanceCount === 0) { + instanceCount = accessor.count; + } + else if (instanceCount !== accessor.count) { + throw new Error("".concat(extensionContext, "/attributes: Instance buffer accessors do not have the same count.")); + } + }; + loadAttribute("TRANSLATION"); + loadAttribute("ROTATION"); + loadAttribute("SCALE"); + return promise.then(function (babylonTransformNode) { + return Promise.all(promises).then(function (_a) { + var translationBuffer = _a[0], rotationBuffer = _a[1], scaleBuffer = _a[2]; + var matrices = new Float32Array(instanceCount * 16); + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[0].copyFromFloats(0, 0, 0); // translation + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Quaternion[0].copyFromFloats(0, 0, 0, 1); // rotation + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[1].copyFromFloats(1, 1, 1); // scale + for (var i = 0; i < instanceCount; ++i) { + translationBuffer && babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArrayToRef(translationBuffer, i * 3, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[0]); + rotationBuffer && babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArrayToRef(rotationBuffer, i * 4, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Quaternion[0]); + scaleBuffer && babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArrayToRef(scaleBuffer, i * 3, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[1]); + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Matrix.ComposeToRef(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[1], babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Quaternion[0], babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[0], babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Matrix[0]); + babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Matrix[0].copyToArray(matrices, i * 16); + } + for (var _i = 0, _b = node._primitiveBabylonMeshes; _i < _b.length; _i++) { + var babylonMesh = _b[_i]; + babylonMesh.thinInstanceSetBuffer("matrix", matrices, 16, true); + } + return babylonTransformNode; + }); + }); + }); + }; + return EXT_mesh_gpu_instancing; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new EXT_mesh_gpu_instancing(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_meshopt_compression.ts": +/*!*******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/EXT_meshopt_compression.ts ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_meshopt_compression: () => (/* binding */ EXT_meshopt_compression) +/* harmony export */ }); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var babylonjs_Meshes_Compression_meshoptCompression__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/Compression/meshoptCompression */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Meshes_Compression_meshoptCompression__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_Compression_meshoptCompression__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "EXT_meshopt_compression"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_meshopt_compression/README.md) + * + * This extension uses a WebAssembly decoder module from https://github.com/zeux/meshoptimizer/tree/master/js + * @since 5.0.0 + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var EXT_meshopt_compression = /** @class */ (function () { + /** + * @internal + */ + function EXT_meshopt_compression(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this.enabled = loader.isExtensionUsed(NAME); + this._loader = loader; + } + /** @internal */ + EXT_meshopt_compression.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + EXT_meshopt_compression.prototype.loadBufferViewAsync = function (context, bufferView) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.LoadExtensionAsync(context, bufferView, this.name, function (extensionContext, extension) { + var bufferViewMeshopt = bufferView; + if (bufferViewMeshopt._meshOptData) { + return bufferViewMeshopt._meshOptData; + } + var buffer = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(context, "/buffer"), _this._loader.gltf.buffers, extension.buffer); + bufferViewMeshopt._meshOptData = _this._loader.loadBufferAsync("/buffers/".concat(buffer.index), buffer, extension.byteOffset || 0, extension.byteLength).then(function (buffer) { + return babylonjs_Meshes_Compression_meshoptCompression__WEBPACK_IMPORTED_MODULE_1__.MeshoptCompression.Default.decodeGltfBufferAsync(buffer, extension.count, extension.byteStride, extension.mode, extension.filter); + }); + return bufferViewMeshopt._meshOptData; + }); + }; + return EXT_meshopt_compression; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new EXT_meshopt_compression(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_texture_avif.ts": +/*!************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/EXT_texture_avif.ts ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_texture_avif: () => (/* binding */ EXT_texture_avif) +/* harmony export */ }); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + +var NAME = "EXT_texture_avif"; +/** + * [glTF PR](https://github.com/KhronosGroup/glTF/pull/2235) + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_texture_avif/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var EXT_texture_avif = /** @class */ (function () { + /** + * @internal + */ + function EXT_texture_avif(loader) { + /** The name of this extension. */ + this.name = NAME; + this._loader = loader; + this.enabled = loader.isExtensionUsed(NAME); + } + /** @internal */ + EXT_texture_avif.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + EXT_texture_avif.prototype._loadTextureAsync = function (context, texture, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.LoadExtensionAsync(context, texture, this.name, function (extensionContext, extension) { + var sampler = texture.sampler == undefined ? _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.DefaultSampler : _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(context, "/sampler"), _this._loader.gltf.samplers, texture.sampler); + var image = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(extensionContext, "/source"), _this._loader.gltf.images, extension.source); + return _this._loader._createTextureAsync(context, sampler, image, function (babylonTexture) { + assign(babylonTexture); + }, undefined, !texture._textureInfo.nonColorData); + }); + }; + return EXT_texture_avif; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__.registerGLTFExtension)(NAME, true, function (loader) { return new EXT_texture_avif(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_texture_webp.ts": +/*!************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/EXT_texture_webp.ts ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_texture_webp: () => (/* binding */ EXT_texture_webp) +/* harmony export */ }); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + +var NAME = "EXT_texture_webp"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_texture_webp/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var EXT_texture_webp = /** @class */ (function () { + /** + * @internal + */ + function EXT_texture_webp(loader) { + /** The name of this extension. */ + this.name = NAME; + this._loader = loader; + this.enabled = loader.isExtensionUsed(NAME); + } + /** @internal */ + EXT_texture_webp.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + EXT_texture_webp.prototype._loadTextureAsync = function (context, texture, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.LoadExtensionAsync(context, texture, this.name, function (extensionContext, extension) { + var sampler = texture.sampler == undefined ? _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.DefaultSampler : _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(context, "/sampler"), _this._loader.gltf.samplers, texture.sampler); + var image = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(extensionContext, "/source"), _this._loader.gltf.images, extension.source); + return _this._loader._createTextureAsync(context, sampler, image, function (babylonTexture) { + assign(babylonTexture); + }, undefined, !texture._textureInfo.nonColorData); + }); + }; + return EXT_texture_webp; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__.registerGLTFExtension)(NAME, true, function (loader) { return new EXT_texture_webp(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/ExtrasAsMetadata.ts": +/*!************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/ExtrasAsMetadata.ts ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ ExtrasAsMetadata: () => (/* binding */ ExtrasAsMetadata) +/* harmony export */ }); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + +var NAME = "ExtrasAsMetadata"; +/** + * Store glTF extras (if present) in BJS objects' metadata + */ +var ExtrasAsMetadata = /** @class */ (function () { + /** + * @internal + */ + function ExtrasAsMetadata(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines whether this extension is enabled. + */ + this.enabled = true; + this._loader = loader; + } + ExtrasAsMetadata.prototype._assignExtras = function (babylonObject, gltfProp) { + if (gltfProp.extras && Object.keys(gltfProp.extras).length > 0) { + var metadata = (babylonObject.metadata = babylonObject.metadata || {}); + var gltf = (metadata.gltf = metadata.gltf || {}); + gltf.extras = gltfProp.extras; + } + }; + /** @internal */ + ExtrasAsMetadata.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + ExtrasAsMetadata.prototype.loadNodeAsync = function (context, node, assign) { + var _this = this; + return this._loader.loadNodeAsync(context, node, function (babylonTransformNode) { + _this._assignExtras(babylonTransformNode, node); + assign(babylonTransformNode); + }); + }; + /** + * @internal + */ + ExtrasAsMetadata.prototype.loadCameraAsync = function (context, camera, assign) { + var _this = this; + return this._loader.loadCameraAsync(context, camera, function (babylonCamera) { + _this._assignExtras(babylonCamera, camera); + assign(babylonCamera); + }); + }; + /** + * @internal + */ + ExtrasAsMetadata.prototype.createMaterial = function (context, material, babylonDrawMode) { + var babylonMaterial = this._loader.createMaterial(context, material, babylonDrawMode); + this._assignExtras(babylonMaterial, material); + return babylonMaterial; + }; + return ExtrasAsMetadata; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.registerGLTFExtension)(NAME, false, function (loader) { return new ExtrasAsMetadata(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_animation_pointer.data.ts": +/*!**********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_animation_pointer.data.ts ***! + \**********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ animationPointerTree: () => (/* binding */ animationPointerTree) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoaderAnimation */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderAnimation.ts"); +/* eslint-disable @typescript-eslint/naming-convention */ + + + + +function getColor3(_target, source, offset, scale) { + return babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(source, offset).scale(scale); +} +function getAlpha(_target, source, offset, scale) { + return source[offset + 3] * scale; +} +function getFloat(_target, source, offset, scale) { + return source[offset] * scale; +} +function getMinusFloat(_target, source, offset, scale) { + return -source[offset] * scale; +} +function getNextFloat(_target, source, offset, scale) { + return source[offset + 1] * scale; +} +function getFloatBy2(_target, source, offset, scale) { + return source[offset] * scale * 2; +} +function getTextureTransformTree(textureName) { + return { + scale: [ + new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "".concat(textureName, ".uScale"), getFloat, function () { return 2; }), + new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "".concat(textureName, ".vScale"), getNextFloat, function () { return 2; }), + ], + offset: [ + new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "".concat(textureName, ".uOffset"), getFloat, function () { return 2; }), + new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "".concat(textureName, ".vOffset"), getNextFloat, function () { return 2; }), + ], + rotation: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "".concat(textureName, ".wAng"), getMinusFloat, function () { return 1; })], + }; +} +var CameraAnimationPropertyInfo = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__extends)(CameraAnimationPropertyInfo, _super); + function CameraAnimationPropertyInfo() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** @internal */ + CameraAnimationPropertyInfo.prototype.buildAnimations = function (target, name, fps, keys, callback) { + callback(target._babylonCamera, this._buildAnimation(name, fps, keys)); + }; + return CameraAnimationPropertyInfo; +}(_glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_1__.AnimationPropertyInfo)); +var MaterialAnimationPropertyInfo = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__extends)(MaterialAnimationPropertyInfo, _super); + function MaterialAnimationPropertyInfo() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** @internal */ + MaterialAnimationPropertyInfo.prototype.buildAnimations = function (target, name, fps, keys, callback) { + for (var fillMode in target._data) { + callback(target._data[fillMode].babylonMaterial, this._buildAnimation(name, fps, keys)); + } + }; + return MaterialAnimationPropertyInfo; +}(_glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_1__.AnimationPropertyInfo)); +var LightAnimationPropertyInfo = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__extends)(LightAnimationPropertyInfo, _super); + function LightAnimationPropertyInfo() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** @internal */ + LightAnimationPropertyInfo.prototype.buildAnimations = function (target, name, fps, keys, callback) { + callback(target._babylonLight, this._buildAnimation(name, fps, keys)); + }; + return LightAnimationPropertyInfo; +}(_glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_1__.AnimationPropertyInfo)); +var nodesTree = { + __array__: (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__assign)({ __target__: true }, _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_1__.nodeAnimationData), +}; +var camerasTree = { + __array__: { + __target__: true, + orthographic: { + xmag: [ + new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "orthoLeft", getMinusFloat, function () { return 1; }), + new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "orthoRight", getNextFloat, function () { return 1; }), + ], + ymag: [ + new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "orthoBottom", getMinusFloat, function () { return 1; }), + new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "orthoTop", getNextFloat, function () { return 1; }), + ], + zfar: [new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "maxZ", getFloat, function () { return 1; })], + znear: [new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "minZ", getFloat, function () { return 1; })], + }, + perspective: { + yfov: [new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "fov", getFloat, function () { return 1; })], + zfar: [new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "maxZ", getFloat, function () { return 1; })], + znear: [new CameraAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "minZ", getFloat, function () { return 1; })], + }, + }, +}; +var materialsTree = { + __array__: { + __target__: true, + pbrMetallicRoughness: { + baseColorFactor: [ + new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "albedoColor", getColor3, function () { return 4; }), + new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "alpha", getAlpha, function () { return 4; }), + ], + metallicFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "metallic", getFloat, function () { return 1; })], + roughnessFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "roughness", getFloat, function () { return 1; })], + baseColorTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("albedoTexture"), + }, + }, + metallicRoughnessTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("metallicTexture"), + }, + }, + }, + emissiveFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "emissiveColor", getColor3, function () { return 3; })], + normalTexture: { + scale: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "bumpTexture.level", getFloat, function () { return 1; })], + extensions: { + KHR_texture_transform: getTextureTransformTree("bumpTexture"), + }, + }, + occlusionTexture: { + strength: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "ambientTextureStrength", getFloat, function () { return 1; })], + extensions: { + KHR_texture_transform: getTextureTransformTree("ambientTexture"), + }, + }, + emissiveTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("emissiveTexture"), + }, + }, + extensions: { + KHR_materials_anisotropy: { + anisotropyStrength: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "anisotropy.intensity", getFloat, function () { return 1; })], + anisotropyRotation: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "anisotropy.angle", getFloat, function () { return 1; })], + anisotropyTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("anisotropy.texture"), + }, + }, + }, + KHR_materials_clearcoat: { + clearcoatFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "clearCoat.intensity", getFloat, function () { return 1; })], + clearcoatRoughnessFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "clearCoat.roughness", getFloat, function () { return 1; })], + clearcoatTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("clearCoat.texture"), + }, + }, + clearcoatNormalTexture: { + scale: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "clearCoat.bumpTexture.level", getFloat, function () { return 1; })], + extensions: { + KHR_texture_transform: getTextureTransformTree("clearCoat.bumpTexture"), + }, + }, + clearcoatRoughnessTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("clearCoat.textureRoughness"), + }, + }, + }, + KHR_materials_dispersion: { + dispersion: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "subSurface.dispersion", getFloat, function () { return 1; })], + }, + KHR_materials_emissive_strength: { + emissiveStrength: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "emissiveIntensity", getFloat, function () { return 1; })], + }, + KHR_materials_ior: { + ior: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "indexOfRefraction", getFloat, function () { return 1; })], + }, + KHR_materials_iridescence: { + iridescenceFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "iridescence.intensity", getFloat, function () { return 1; })], + iridescenceIor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "iridescence.indexOfRefraction", getFloat, function () { return 1; })], + iridescenceThicknessMinimum: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "iridescence.minimumThickness", getFloat, function () { return 1; })], + iridescenceThicknessMaximum: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "iridescence.maximumThickness", getFloat, function () { return 1; })], + iridescenceTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("iridescence.texture"), + }, + }, + iridescenceThicknessTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("iridescence.thicknessTexture"), + }, + }, + }, + KHR_materials_sheen: { + sheenColorFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "sheen.color", getColor3, function () { return 3; })], + sheenRoughnessFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "sheen.roughness", getFloat, function () { return 1; })], + sheenColorTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("sheen.texture"), + }, + }, + sheenRoughnessTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("sheen.textureRoughness"), + }, + }, + }, + KHR_materials_specular: { + specularFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "metallicF0Factor", getFloat, function () { return 1; })], + specularColorFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "metallicReflectanceColor", getColor3, function () { return 3; })], + specularTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("metallicReflectanceTexture"), + }, + }, + specularColorTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("reflectanceTexture"), + }, + }, + }, + KHR_materials_transmission: { + transmissionFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "subSurface.refractionIntensity", getFloat, function () { return 1; })], + transmissionTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("subSurface.refractionIntensityTexture"), + }, + }, + }, + KHR_materials_volume: { + attenuationColor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "subSurface.tintColor", getColor3, function () { return 3; })], + attenuationDistance: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "subSurface.tintColorAtDistance", getFloat, function () { return 1; })], + thicknessFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "subSurface.maximumThickness", getFloat, function () { return 1; })], + thicknessTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("subSurface.thicknessTexture"), + }, + }, + }, + KHR_materials_diffuse_transmission: { + diffuseTransmissionFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "subSurface.translucencyIntensity", getFloat, function () { return 1; })], + diffuseTransmissionTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("subSurface.translucencyIntensityTexture"), + }, + }, + diffuseTransmissionColorFactor: [new MaterialAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "subSurface.translucencyColor", getColor3, function () { return 3; })], + diffuseTransmissionColorTexture: { + extensions: { + KHR_texture_transform: getTextureTransformTree("subSurface.translucencyColorTexture"), + }, + }, + }, + }, + }, +}; +var extensionsTree = { + KHR_lights_punctual: { + lights: { + __array__: { + __target__: true, + color: [new LightAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_COLOR3, "diffuse", getColor3, function () { return 3; })], + intensity: [new LightAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "intensity", getFloat, function () { return 1; })], + range: [new LightAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "range", getFloat, function () { return 1; })], + spot: { + innerConeAngle: [new LightAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "innerAngle", getFloatBy2, function () { return 1; })], + outerConeAngle: [new LightAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "angle", getFloatBy2, function () { return 1; })], + }, + }, + }, + }, +}; +/** @internal */ +var animationPointerTree = { + nodes: nodesTree, + materials: materialsTree, + cameras: camerasTree, + extensions: extensionsTree, +}; + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_animation_pointer.ts": +/*!*****************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_animation_pointer.ts ***! + \*****************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_animation_pointer: () => (/* binding */ KHR_animation_pointer) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _KHR_animation_pointer_data__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./KHR_animation_pointer.data */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_animation_pointer.data.ts"); +/* harmony import */ var _gltfPathToObjectConverter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./gltfPathToObjectConverter */ "../../../dev/loaders/src/glTF/2.0/Extensions/gltfPathToObjectConverter.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + +var NAME = "KHR_animation_pointer"; +/** + * Class to convert an animation pointer path to a smart object that + * gets data from the animation buffer and creates animations. + */ +var AnimationPointerPathToObjectConverter = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__extends)(AnimationPointerPathToObjectConverter, _super); + function AnimationPointerPathToObjectConverter(gltf) { + return _super.call(this, gltf, _KHR_animation_pointer_data__WEBPACK_IMPORTED_MODULE_1__.animationPointerTree) || this; + } + return AnimationPointerPathToObjectConverter; +}(_gltfPathToObjectConverter__WEBPACK_IMPORTED_MODULE_2__.GLTFPathToObjectConverter)); +/** + * [Specification PR](https://github.com/KhronosGroup/glTF/pull/2147) + * !!! Experimental Extension Subject to Changes !!! + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_animation_pointer = /** @class */ (function () { + /** + * @internal + */ + function KHR_animation_pointer(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this._pathToObjectConverter = new AnimationPointerPathToObjectConverter(this._loader.gltf); + } + Object.defineProperty(KHR_animation_pointer.prototype, "enabled", { + /** + * Defines whether this extension is enabled. + */ + get: function () { + return this._loader.isExtensionUsed(NAME); + }, + enumerable: false, + configurable: true + }); + /** @internal */ + KHR_animation_pointer.prototype.dispose = function () { + this._loader = null; + delete this._pathToObjectConverter; // GC + }; + /** + * Loads a glTF animation channel. + * @param context The context when loading the asset + * @param animationContext The context of the animation when loading the asset + * @param animation The glTF animation property + * @param channel The glTF animation channel property + * @param onLoad Called for each animation loaded + * @returns A void promise that resolves when the load is complete or null if not handled + */ + KHR_animation_pointer.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, onLoad) { + var _a; + var extension = (_a = channel.target.extensions) === null || _a === void 0 ? void 0 : _a.KHR_animation_pointer; + if (!extension || !this._pathToObjectConverter) { + return null; + } + if (channel.target.path !== "pointer" /* AnimationChannelTargetPath.POINTER */) { + babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, "/target/path: Value (").concat(channel.target.path, ") must be (").concat("pointer" /* AnimationChannelTargetPath.POINTER */, ") when using the ").concat(this.name, " extension")); + } + if (channel.target.node != undefined) { + babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, "/target/node: Value (").concat(channel.target.node, ") must not be present when using the ").concat(this.name, " extension")); + } + var extensionContext = "".concat(context, "/extensions/").concat(this.name); + var pointer = extension.pointer; + if (!pointer) { + throw new Error("".concat(extensionContext, ": Pointer is missing")); + } + try { + var targetInfo = this._pathToObjectConverter.convert(pointer); + return this._loader._loadAnimationChannelFromTargetInfoAsync(context, animationContext, animation, channel, targetInfo, onLoad); + } + catch (e) { + babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(extensionContext, "/pointer: Invalid pointer (").concat(pointer, ") skipped")); + return null; + } + }; + return KHR_animation_pointer; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_animation_pointer(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts": +/*!**********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts ***! + \**********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_draco_mesh_compression: () => (/* binding */ KHR_draco_mesh_compression) +/* harmony export */ }); +/* harmony import */ var babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Buffers/buffer */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "KHR_draco_mesh_compression"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_draco_mesh_compression = /** @class */ (function () { + /** + * @internal + */ + function KHR_draco_mesh_compression(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines whether to use the normalized flag from the glTF accessor instead of the Draco data. Defaults to true. + */ + this.useNormalizedFlagFromAccessor = true; + this._loader = loader; + this.enabled = babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.DracoCompression.DecoderAvailable && this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_draco_mesh_compression.prototype.dispose = function () { + delete this.dracoCompression; + this._loader = null; + }; + /** + * @internal + */ + KHR_draco_mesh_compression.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, primitive, this.name, function (extensionContext, extension) { + if (primitive.mode != undefined) { + if (primitive.mode !== 4 /* MeshPrimitiveMode.TRIANGLES */ && primitive.mode !== 5 /* MeshPrimitiveMode.TRIANGLE_STRIP */) { + throw new Error("".concat(context, ": Unsupported mode ").concat(primitive.mode)); + } + } + var attributes = {}; + var normalized = {}; + var loadAttribute = function (name, kind) { + var uniqueId = extension.attributes[name]; + if (uniqueId == undefined) { + return; + } + babylonMesh._delayInfo = babylonMesh._delayInfo || []; + if (babylonMesh._delayInfo.indexOf(kind) === -1) { + babylonMesh._delayInfo.push(kind); + } + attributes[kind] = uniqueId; + if (_this.useNormalizedFlagFromAccessor) { + var accessor = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.TryGet(_this._loader.gltf.accessors, primitive.attributes[name]); + if (accessor) { + normalized[kind] = accessor.normalized || false; + } + } + }; + loadAttribute("POSITION", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind); + loadAttribute("NORMAL", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind); + loadAttribute("TANGENT", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind); + loadAttribute("TEXCOORD_0", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UVKind); + loadAttribute("TEXCOORD_1", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV2Kind); + loadAttribute("TEXCOORD_2", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV3Kind); + loadAttribute("TEXCOORD_3", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV4Kind); + loadAttribute("TEXCOORD_4", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV5Kind); + loadAttribute("TEXCOORD_5", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV6Kind); + loadAttribute("JOINTS_0", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesKind); + loadAttribute("WEIGHTS_0", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesWeightsKind); + loadAttribute("COLOR_0", babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ColorKind); + var bufferView = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get(extensionContext, _this._loader.gltf.bufferViews, extension.bufferView); + if (!bufferView._dracoBabylonGeometry) { + bufferView._dracoBabylonGeometry = _this._loader.loadBufferViewAsync("/bufferViews/".concat(bufferView.index), bufferView).then(function (data) { + var dracoCompression = _this.dracoCompression || babylonjs_Meshes_Compression_dracoCompression__WEBPACK_IMPORTED_MODULE_0__.DracoCompression.Default; + return dracoCompression._decodeMeshToGeometryForGltfAsync(babylonMesh.name, _this._loader.babylonScene, data, attributes, normalized).catch(function (error) { + throw new Error("".concat(context, ": ").concat(error.message)); + }); + }); + } + return bufferView._dracoBabylonGeometry; + }); + }; + return KHR_draco_mesh_compression; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_draco_mesh_compression(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_interactivity.ts": +/*!*************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_interactivity.ts ***! + \*************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_interactivity: () => (/* binding */ KHR_interactivity) +/* harmony export */ }); +/* harmony import */ var babylonjs_FlowGraph_flowGraphCoordinator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/FlowGraph/flowGraph */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_FlowGraph_flowGraphCoordinator__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_FlowGraph_flowGraphCoordinator__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _interactivityFunctions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./interactivityFunctions */ "../../../dev/loaders/src/glTF/2.0/Extensions/interactivityFunctions.ts"); +/* harmony import */ var _interactivityPathToObjectConverter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./interactivityPathToObjectConverter */ "../../../dev/loaders/src/glTF/2.0/Extensions/interactivityPathToObjectConverter.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + +var NAME = "KHR_interactivity"; +/** + * Loader extension for KHR_interactivity + */ +var KHR_interactivity = /** @class */ (function () { + /** + * @internal + * @param _loader + */ + function KHR_interactivity(_loader) { + this._loader = _loader; + /** + * The name of this extension. + */ + this.name = NAME; + this.enabled = this._loader.isExtensionUsed(NAME); + this._pathConverter = new _interactivityPathToObjectConverter__WEBPACK_IMPORTED_MODULE_2__.InteractivityPathToObjectConverter(this._loader.gltf); + } + KHR_interactivity.prototype.dispose = function () { + this._loader = null; + delete this._pathConverter; + }; + KHR_interactivity.prototype.onReady = function () { + var _a; + if (!this._loader.babylonScene || !this._pathConverter) { + return; + } + var scene = this._loader.babylonScene; + var interactivityDefinition = (_a = this._loader.gltf.extensions) === null || _a === void 0 ? void 0 : _a.KHR_interactivity; + var json = (0,_interactivityFunctions__WEBPACK_IMPORTED_MODULE_1__.convertGLTFToSerializedFlowGraph)(interactivityDefinition); + var coordinator = new babylonjs_FlowGraph_flowGraphCoordinator__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCoordinator({ scene: scene }); + babylonjs_FlowGraph_flowGraphCoordinator__WEBPACK_IMPORTED_MODULE_0__.FlowGraph.Parse(json, { coordinator: coordinator, pathConverter: this._pathConverter }); + coordinator.start(); + }; + return KHR_interactivity; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_interactivity(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts": +/*!***************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_lights: () => (/* binding */ KHR_lights) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Lights/light */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + + + + +var NAME = "KHR_lights_punctual"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_lights_punctual/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_lights = /** @class */ (function () { + /** + * @internal + */ + function KHR_lights(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_lights.prototype.dispose = function () { + this._loader = null; + delete this._lights; + }; + /** @internal */ + KHR_lights.prototype.onLoading = function () { + var extensions = this._loader.gltf.extensions; + if (extensions && extensions[this.name]) { + var extension = extensions[this.name]; + this._lights = extension.lights; + _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Assign(this._lights); + } + }; + /** + * @internal + */ + KHR_lights.prototype.loadNodeAsync = function (context, node, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) { + _this._loader._allMaterialsDirtyRequired = true; + return _this._loader.loadNodeAsync(context, node, function (babylonMesh) { + var babylonLight; + var light = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get(extensionContext, _this._lights, extension.light); + var name = light.name || babylonMesh.name; + _this._loader.babylonScene._blockEntityCollection = !!_this._loader._assetContainer; + switch (light.type) { + case "directional" /* KHRLightsPunctual_LightType.DIRECTIONAL */: { + var babylonDirectionalLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.DirectionalLight(name, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.Backward(), _this._loader.babylonScene); + babylonDirectionalLight.position.setAll(0); + babylonLight = babylonDirectionalLight; + break; + } + case "point" /* KHRLightsPunctual_LightType.POINT */: { + babylonLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.PointLight(name, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero(), _this._loader.babylonScene); + break; + } + case "spot" /* KHRLightsPunctual_LightType.SPOT */: { + var babylonSpotLight = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.SpotLight(name, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero(), babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.Backward(), 0, 1, _this._loader.babylonScene); + babylonSpotLight.angle = ((light.spot && light.spot.outerConeAngle) || Math.PI / 4) * 2; + babylonSpotLight.innerAngle = ((light.spot && light.spot.innerConeAngle) || 0) * 2; + babylonLight = babylonSpotLight; + break; + } + default: { + _this._loader.babylonScene._blockEntityCollection = false; + throw new Error("".concat(extensionContext, ": Invalid light type (").concat(light.type, ")")); + } + } + babylonLight._parentContainer = _this._loader._assetContainer; + _this._loader.babylonScene._blockEntityCollection = false; + light._babylonLight = babylonLight; + babylonLight.falloffType = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Light.FALLOFF_GLTF; + babylonLight.diffuse = light.color ? babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(light.color) : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Color3.White(); + babylonLight.intensity = light.intensity == undefined ? 1 : light.intensity; + babylonLight.range = light.range == undefined ? Number.MAX_VALUE : light.range; + babylonLight.parent = babylonMesh; + _this._loader._babylonLights.push(babylonLight); + _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.AddPointerMetadata(babylonLight, extensionContext); + assign(babylonMesh); + }); + }); + }; + return KHR_lights; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_lights(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts": +/*!********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts ***! + \********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_anisotropy: () => (/* binding */ KHR_materials_anisotropy) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_anisotropy"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_anisotropy) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_anisotropy = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_anisotropy(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 195; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_anisotropy.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_anisotropy.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadIridescencePropertiesAsync(extensionContext, extension, babylonMaterial)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_anisotropy.prototype._loadIridescencePropertiesAsync = function (context, properties, babylonMaterial) { + var _a, _b; + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.anisotropy.isEnabled = true; + babylonMaterial.anisotropy.intensity = (_a = properties.anisotropyStrength) !== null && _a !== void 0 ? _a : 0; + babylonMaterial.anisotropy.angle = (_b = properties.anisotropyRotation) !== null && _b !== void 0 ? _b : 0; + if (properties.anisotropyTexture) { + properties.anisotropyTexture.nonColorData = true; + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/anisotropyTexture"), properties.anisotropyTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Anisotropy Intensity)"); + babylonMaterial.anisotropy.texture = texture; + })); + } + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_anisotropy; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_anisotropy(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts": +/*!*******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts ***! + \*******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_clearcoat: () => (/* binding */ KHR_materials_clearcoat) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_clearcoat"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md) + * [Playground Sample](https://www.babylonjs-playground.com/frame.html#7F7PN6#8) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_clearcoat = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_clearcoat(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 190; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_clearcoat.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_clearcoat.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadClearCoatPropertiesAsync(extensionContext, extension, babylonMaterial)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_clearcoat.prototype._loadClearCoatPropertiesAsync = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.clearCoat.isEnabled = true; + babylonMaterial.clearCoat.useRoughnessFromMainTexture = false; + babylonMaterial.clearCoat.remapF0OnInterfaceChange = false; + if (properties.clearcoatFactor != undefined) { + babylonMaterial.clearCoat.intensity = properties.clearcoatFactor; + } + else { + babylonMaterial.clearCoat.intensity = 0; + } + if (properties.clearcoatTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/clearcoatTexture"), properties.clearcoatTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (ClearCoat)"); + babylonMaterial.clearCoat.texture = texture; + })); + } + if (properties.clearcoatRoughnessFactor != undefined) { + babylonMaterial.clearCoat.roughness = properties.clearcoatRoughnessFactor; + } + else { + babylonMaterial.clearCoat.roughness = 0; + } + if (properties.clearcoatRoughnessTexture) { + properties.clearcoatRoughnessTexture.nonColorData = true; + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/clearcoatRoughnessTexture"), properties.clearcoatRoughnessTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (ClearCoat Roughness)"); + babylonMaterial.clearCoat.textureRoughness = texture; + })); + } + if (properties.clearcoatNormalTexture) { + properties.clearcoatNormalTexture.nonColorData = true; + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/clearcoatNormalTexture"), properties.clearcoatNormalTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (ClearCoat Normal)"); + babylonMaterial.clearCoat.bumpTexture = texture; + })); + babylonMaterial.invertNormalMapX = !babylonMaterial.getScene().useRightHandedSystem; + babylonMaterial.invertNormalMapY = babylonMaterial.getScene().useRightHandedSystem; + if (properties.clearcoatNormalTexture.scale != undefined) { + babylonMaterial.clearCoat.bumpTexture.level = properties.clearcoatNormalTexture.scale; + } + } + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_clearcoat; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_clearcoat(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts": +/*!******************************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts ***! + \******************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_diffuse_transmission: () => (/* binding */ KHR_materials_diffuse_transmission) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "KHR_materials_diffuse_transmission"; +/** + * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1825) + * !!! Experimental Extension Subject to Changes !!! + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_diffuse_transmission = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_diffuse_transmission(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 174; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + if (this.enabled) { + loader.parent.transparencyAsCoverage = true; + } + } + /** @internal */ + KHR_materials_diffuse_transmission.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_diffuse_transmission.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadTranslucentPropertiesAsync(extensionContext, material, babylonMaterial, extension)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_diffuse_transmission.prototype._loadTranslucentPropertiesAsync = function (context, material, babylonMaterial, extension) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var pbrMaterial = babylonMaterial; + // Enables "translucency" texture which represents diffusely-transmitted light. + pbrMaterial.subSurface.isTranslucencyEnabled = true; + // Since this extension models thin-surface transmission only, we must make the + // internal IOR == 1.0 and set the thickness to 0. + pbrMaterial.subSurface.volumeIndexOfRefraction = 1.0; + pbrMaterial.subSurface.minimumThickness = 0.0; + pbrMaterial.subSurface.maximumThickness = 0.0; + // Tint color will be used for transmission. + pbrMaterial.subSurface.useAlbedoToTintTranslucency = false; + if (extension.diffuseTransmissionFactor !== undefined) { + pbrMaterial.subSurface.translucencyIntensity = extension.diffuseTransmissionFactor; + } + else { + pbrMaterial.subSurface.translucencyIntensity = 0.0; + pbrMaterial.subSurface.isTranslucencyEnabled = false; + return Promise.resolve(); + } + var promises = new Array(); + pbrMaterial.subSurface.useGltfStyleTextures = true; + if (extension.diffuseTransmissionTexture) { + extension.diffuseTransmissionTexture.nonColorData = true; + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/diffuseTransmissionTexture"), extension.diffuseTransmissionTexture).then(function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Diffuse Transmission)"); + pbrMaterial.subSurface.translucencyIntensityTexture = texture; + })); + } + if (extension.diffuseTransmissionColorFactor !== undefined) { + pbrMaterial.subSurface.translucencyColor = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(extension.diffuseTransmissionColorFactor); + } + else { + pbrMaterial.subSurface.translucencyColor = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Color3.White(); + } + if (extension.diffuseTransmissionColorTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/diffuseTransmissionColorTexture"), extension.diffuseTransmissionColorTexture).then(function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Diffuse Transmission Color)"); + pbrMaterial.subSurface.translucencyColorTexture = texture; + })); + } + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_diffuse_transmission; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_diffuse_transmission(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts": +/*!********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts ***! + \********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_dispersion: () => (/* binding */ KHR_materials_dispersion) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_dispersion"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/87bd64a7f5e23c84b6aef2e6082069583ed0ddb4/extensions/2.0/Khronos/KHR_materials_dispersion/README.md) + * @experimental + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_dispersion = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_dispersion(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 174; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_dispersion.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_dispersion.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadDispersionPropertiesAsync(extensionContext, material, babylonMaterial, extension)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_dispersion.prototype._loadDispersionPropertiesAsync = function (context, material, babylonMaterial, extension) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + // If transparency isn't enabled already, this extension shouldn't do anything. + // i.e. it requires either the KHR_materials_transmission or KHR_materials_diffuse_transmission extensions. + if (!babylonMaterial.subSurface.isRefractionEnabled || !extension.dispersion) { + return Promise.resolve(); + } + babylonMaterial.subSurface.isDispersionEnabled = true; + babylonMaterial.subSurface.dispersion = extension.dispersion; + return Promise.resolve(); + }; + return KHR_materials_dispersion; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_dispersion(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_emissive_strength.ts": +/*!***************************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_emissive_strength.ts ***! + \***************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_emissive_strength: () => (/* binding */ KHR_materials_emissive_strength) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_emissive_strength"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_emissive_strength = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_emissive_strength(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 170; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_emissive_strength.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_emissive_strength.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + return _this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial).then(function () { + _this._loadEmissiveProperties(extensionContext, extension, babylonMaterial); + }); + }); + }; + KHR_materials_emissive_strength.prototype._loadEmissiveProperties = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + if (properties.emissiveStrength !== undefined) { + babylonMaterial.emissiveIntensity = properties.emissiveStrength; + } + }; + return KHR_materials_emissive_strength; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_emissive_strength(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_ior.ts": +/*!*************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_ior.ts ***! + \*************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_ior: () => (/* binding */ KHR_materials_ior) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_ior"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_ior/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_ior = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_ior(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 180; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_ior.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_ior.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadIorPropertiesAsync(extensionContext, extension, babylonMaterial)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_ior.prototype._loadIorPropertiesAsync = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + if (properties.ior !== undefined) { + babylonMaterial.indexOfRefraction = properties.ior; + } + else { + babylonMaterial.indexOfRefraction = KHR_materials_ior._DEFAULT_IOR; + } + return Promise.resolve(); + }; + /** + * Default ior Value from the spec. + */ + KHR_materials_ior._DEFAULT_IOR = 1.5; + return KHR_materials_ior; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_ior(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_iridescence.ts": +/*!*********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_iridescence.ts ***! + \*********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_iridescence: () => (/* binding */ KHR_materials_iridescence) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_iridescence"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_iridescence/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_iridescence = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_iridescence(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 195; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_iridescence.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_iridescence.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadIridescencePropertiesAsync(extensionContext, extension, babylonMaterial)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_iridescence.prototype._loadIridescencePropertiesAsync = function (context, properties, babylonMaterial) { + var _a, _b, _c, _d, _e; + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.iridescence.isEnabled = true; + babylonMaterial.iridescence.intensity = (_a = properties.iridescenceFactor) !== null && _a !== void 0 ? _a : 0; + babylonMaterial.iridescence.indexOfRefraction = (_c = (_b = properties.iridescenceIor) !== null && _b !== void 0 ? _b : properties.iridescenceIOR) !== null && _c !== void 0 ? _c : 1.3; + babylonMaterial.iridescence.minimumThickness = (_d = properties.iridescenceThicknessMinimum) !== null && _d !== void 0 ? _d : 100; + babylonMaterial.iridescence.maximumThickness = (_e = properties.iridescenceThicknessMaximum) !== null && _e !== void 0 ? _e : 400; + if (properties.iridescenceTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/iridescenceTexture"), properties.iridescenceTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Iridescence)"); + babylonMaterial.iridescence.texture = texture; + })); + } + if (properties.iridescenceThicknessTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/iridescenceThicknessTexture"), properties.iridescenceThicknessTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Iridescence Thickness)"); + babylonMaterial.iridescence.thicknessTexture = texture; + })); + } + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_iridescence; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_iridescence(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts": +/*!*******************************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts ***! + \*******************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_pbrSpecularGlossiness: () => (/* binding */ KHR_materials_pbrSpecularGlossiness) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "KHR_materials_pbrSpecularGlossiness"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_pbrSpecularGlossiness = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_pbrSpecularGlossiness(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 200; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_pbrSpecularGlossiness.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_pbrSpecularGlossiness.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialBasePropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadSpecularGlossinessPropertiesAsync(extensionContext, extension, babylonMaterial)); + _this._loader.loadMaterialAlphaProperties(context, material, babylonMaterial); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_pbrSpecularGlossiness.prototype._loadSpecularGlossinessPropertiesAsync = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.metallic = null; + babylonMaterial.roughness = null; + if (properties.diffuseFactor) { + babylonMaterial.albedoColor = babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(properties.diffuseFactor); + babylonMaterial.alpha = properties.diffuseFactor[3]; + } + else { + babylonMaterial.albedoColor = babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.Color3.White(); + } + babylonMaterial.reflectivityColor = properties.specularFactor ? babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(properties.specularFactor) : babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.Color3.White(); + babylonMaterial.microSurface = properties.glossinessFactor == undefined ? 1 : properties.glossinessFactor; + if (properties.diffuseTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/diffuseTexture"), properties.diffuseTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Diffuse)"); + babylonMaterial.albedoTexture = texture; + })); + } + if (properties.specularGlossinessTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/specularGlossinessTexture"), properties.specularGlossinessTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Specular Glossiness)"); + babylonMaterial.reflectivityTexture = texture; + babylonMaterial.reflectivityTexture.hasAlpha = true; + })); + babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true; + } + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_pbrSpecularGlossiness; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_pbrSpecularGlossiness(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_sheen.ts": +/*!***************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_sheen.ts ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_sheen: () => (/* binding */ KHR_materials_sheen) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "KHR_materials_sheen"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_sheen/README.md) + * [Playground Sample](https://www.babylonjs-playground.com/frame.html#BNIZX6#4) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_sheen = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_sheen(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 190; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_sheen.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_sheen.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadSheenPropertiesAsync(extensionContext, extension, babylonMaterial)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_sheen.prototype._loadSheenPropertiesAsync = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.sheen.isEnabled = true; + babylonMaterial.sheen.intensity = 1; + if (properties.sheenColorFactor != undefined) { + babylonMaterial.sheen.color = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(properties.sheenColorFactor); + } + else { + babylonMaterial.sheen.color = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Color3.Black(); + } + if (properties.sheenColorTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/sheenColorTexture"), properties.sheenColorTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Sheen Color)"); + babylonMaterial.sheen.texture = texture; + })); + } + if (properties.sheenRoughnessFactor !== undefined) { + babylonMaterial.sheen.roughness = properties.sheenRoughnessFactor; + } + else { + babylonMaterial.sheen.roughness = 0; + } + if (properties.sheenRoughnessTexture) { + properties.sheenRoughnessTexture.nonColorData = true; + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/sheenRoughnessTexture"), properties.sheenRoughnessTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Sheen Roughness)"); + babylonMaterial.sheen.textureRoughness = texture; + })); + } + babylonMaterial.sheen.albedoScaling = true; + babylonMaterial.sheen.useRoughnessFromMainTexture = false; + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_sheen; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_sheen(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_specular.ts": +/*!******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_specular.ts ***! + \******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_specular: () => (/* binding */ KHR_materials_specular) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "KHR_materials_specular"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_specular/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_specular = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_specular(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 190; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_specular.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_specular.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadSpecularPropertiesAsync(extensionContext, extension, babylonMaterial)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_specular.prototype._loadSpecularPropertiesAsync = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + if (properties.specularFactor !== undefined) { + babylonMaterial.metallicF0Factor = properties.specularFactor; + } + if (properties.specularColorFactor !== undefined) { + babylonMaterial.metallicReflectanceColor = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(properties.specularColorFactor); + } + if (properties.specularTexture) { + properties.specularTexture.nonColorData = true; + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/specularTexture"), properties.specularTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Specular)"); + babylonMaterial.metallicReflectanceTexture = texture; + babylonMaterial.useOnlyMetallicFromMetallicReflectanceTexture = true; + })); + } + if (properties.specularColorTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/specularColorTexture"), properties.specularColorTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Specular Color)"); + babylonMaterial.reflectanceTexture = texture; + })); + } + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_specular; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_specular(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_transmission.ts": +/*!**********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_transmission.ts ***! + \**********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_transmission: () => (/* binding */ KHR_materials_transmission) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + + + + +/** + * A class to handle setting up the rendering of opaque objects to be shown through transmissive objects. + */ +var TransmissionHelper = /** @class */ (function () { + /** + * constructor + * @param options Defines the options we want to customize the helper + * @param scene The scene to add the material to + */ + function TransmissionHelper(options, scene) { + var _this = this; + this._opaqueRenderTarget = null; + this._opaqueMeshesCache = []; + this._transparentMeshesCache = []; + this._materialObservers = {}; + this._options = (0,tslib__WEBPACK_IMPORTED_MODULE_3__.__assign)((0,tslib__WEBPACK_IMPORTED_MODULE_3__.__assign)({}, TransmissionHelper._GetDefaultOptions()), options); + this._scene = scene; + this._scene._transmissionHelper = this; + this.onErrorObservable = new babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Observable(); + this._scene.onDisposeObservable.addOnce(function () { + _this.dispose(); + }); + this._parseScene(); + this._setupRenderTargets(); + } + /** + * Creates the default options for the helper. + * @returns the default options + */ + TransmissionHelper._GetDefaultOptions = function () { + return { + renderSize: 1024, + samples: 4, + lodGenerationScale: 1, + lodGenerationOffset: -4, + renderTargetTextureType: babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Constants.TEXTURETYPE_HALF_FLOAT, + generateMipmaps: true, + }; + }; + /** + * Updates the background according to the new options + * @param options + */ + TransmissionHelper.prototype.updateOptions = function (options) { + var _this = this; + // First check if any options are actually being changed. If not, exit. + var newValues = Object.keys(options).filter(function (key) { return _this._options[key] !== options[key]; }); + if (!newValues.length) { + return; + } + var newOptions = (0,tslib__WEBPACK_IMPORTED_MODULE_3__.__assign)((0,tslib__WEBPACK_IMPORTED_MODULE_3__.__assign)({}, this._options), options); + var oldOptions = this._options; + this._options = newOptions; + // If size changes, recreate everything + if (newOptions.renderSize !== oldOptions.renderSize || + newOptions.renderTargetTextureType !== oldOptions.renderTargetTextureType || + newOptions.generateMipmaps !== oldOptions.generateMipmaps || + !this._opaqueRenderTarget) { + this._setupRenderTargets(); + } + else { + this._opaqueRenderTarget.samples = newOptions.samples; + this._opaqueRenderTarget.lodGenerationScale = newOptions.lodGenerationScale; + this._opaqueRenderTarget.lodGenerationOffset = newOptions.lodGenerationOffset; + } + }; + /** + * @returns the opaque render target texture or null if not available. + */ + TransmissionHelper.prototype.getOpaqueTarget = function () { + return this._opaqueRenderTarget; + }; + TransmissionHelper.prototype._shouldRenderAsTransmission = function (material) { + if (!material) { + return false; + } + if (material instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial && material.subSurface.isRefractionEnabled) { + return true; + } + return false; + }; + TransmissionHelper.prototype._addMesh = function (mesh) { + var _this = this; + this._materialObservers[mesh.uniqueId] = mesh.onMaterialChangedObservable.add(this._onMeshMaterialChanged.bind(this)); + // we need to defer the processing because _addMesh may be called as part as an instance mesh creation, in which case some + // internal properties are not setup yet, like _sourceMesh (needed when doing mesh.material below) + babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.Tools.SetImmediate(function () { + if (_this._shouldRenderAsTransmission(mesh.material)) { + mesh.material.refractionTexture = _this._opaqueRenderTarget; + if (_this._transparentMeshesCache.indexOf(mesh) === -1) { + _this._transparentMeshesCache.push(mesh); + } + } + else { + if (_this._opaqueMeshesCache.indexOf(mesh) === -1) { + _this._opaqueMeshesCache.push(mesh); + } + } + }); + }; + TransmissionHelper.prototype._removeMesh = function (mesh) { + mesh.onMaterialChangedObservable.remove(this._materialObservers[mesh.uniqueId]); + delete this._materialObservers[mesh.uniqueId]; + var idx = this._transparentMeshesCache.indexOf(mesh); + if (idx !== -1) { + this._transparentMeshesCache.splice(idx, 1); + } + idx = this._opaqueMeshesCache.indexOf(mesh); + if (idx !== -1) { + this._opaqueMeshesCache.splice(idx, 1); + } + }; + TransmissionHelper.prototype._parseScene = function () { + this._scene.meshes.forEach(this._addMesh.bind(this)); + // Listen for when a mesh is added to the scene and add it to our cache lists. + this._scene.onNewMeshAddedObservable.add(this._addMesh.bind(this)); + // Listen for when a mesh is removed from to the scene and remove it from our cache lists. + this._scene.onMeshRemovedObservable.add(this._removeMesh.bind(this)); + }; + // When one of the meshes in the scene has its material changed, make sure that it's in the correct cache list. + TransmissionHelper.prototype._onMeshMaterialChanged = function (mesh) { + var transparentIdx = this._transparentMeshesCache.indexOf(mesh); + var opaqueIdx = this._opaqueMeshesCache.indexOf(mesh); + // If the material is transparent, make sure that it's added to the transparent list and removed from the opaque list + var useTransmission = this._shouldRenderAsTransmission(mesh.material); + if (useTransmission) { + if (mesh.material instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial) { + mesh.material.subSurface.refractionTexture = this._opaqueRenderTarget; + } + if (opaqueIdx !== -1) { + this._opaqueMeshesCache.splice(opaqueIdx, 1); + this._transparentMeshesCache.push(mesh); + } + else if (transparentIdx === -1) { + this._transparentMeshesCache.push(mesh); + } + // If the material is opaque, make sure that it's added to the opaque list and removed from the transparent list + } + else { + if (transparentIdx !== -1) { + this._transparentMeshesCache.splice(transparentIdx, 1); + this._opaqueMeshesCache.push(mesh); + } + else if (opaqueIdx === -1) { + this._opaqueMeshesCache.push(mesh); + } + } + }; + /** + * @internal + * Check if the opaque render target has not been disposed and can still be used. + * @returns + */ + TransmissionHelper.prototype._isRenderTargetValid = function () { + var _a; + return ((_a = this._opaqueRenderTarget) === null || _a === void 0 ? void 0 : _a.getInternalTexture()) !== null; + }; + /** + * @internal + * Setup the render targets according to the specified options. + */ + TransmissionHelper.prototype._setupRenderTargets = function () { + var _this = this; + var _a, _b; + if (this._opaqueRenderTarget) { + this._opaqueRenderTarget.dispose(); + } + this._opaqueRenderTarget = new babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.RenderTargetTexture("opaqueSceneTexture", this._options.renderSize, this._scene, this._options.generateMipmaps, undefined, this._options.renderTargetTextureType); + this._opaqueRenderTarget.ignoreCameraViewport = true; + this._opaqueRenderTarget.renderList = this._opaqueMeshesCache; + this._opaqueRenderTarget.clearColor = (_b = (_a = this._options.clearColor) === null || _a === void 0 ? void 0 : _a.clone()) !== null && _b !== void 0 ? _b : this._scene.clearColor.clone(); + this._opaqueRenderTarget.gammaSpace = false; + this._opaqueRenderTarget.lodGenerationScale = this._options.lodGenerationScale; + this._opaqueRenderTarget.lodGenerationOffset = this._options.lodGenerationOffset; + this._opaqueRenderTarget.samples = this._options.samples; + this._opaqueRenderTarget.renderSprites = true; + this._opaqueRenderTarget.renderParticles = true; + var sceneImageProcessingapplyByPostProcess; + var saveSceneEnvIntensity; + this._opaqueRenderTarget.onBeforeBindObservable.add(function (opaqueRenderTarget) { + saveSceneEnvIntensity = _this._scene.environmentIntensity; + _this._scene.environmentIntensity = 1.0; + sceneImageProcessingapplyByPostProcess = _this._scene.imageProcessingConfiguration.applyByPostProcess; + if (!_this._options.clearColor) { + _this._scene.clearColor.toLinearSpaceToRef(opaqueRenderTarget.clearColor, _this._scene.getEngine().useExactSrgbConversions); + } + else { + opaqueRenderTarget.clearColor.copyFrom(_this._options.clearColor); + } + // we do not use the applyByPostProcess setter to avoid flagging all the materials as "image processing dirty"! + _this._scene.imageProcessingConfiguration._applyByPostProcess = true; + }); + this._opaqueRenderTarget.onAfterUnbindObservable.add(function () { + _this._scene.environmentIntensity = saveSceneEnvIntensity; + _this._scene.imageProcessingConfiguration._applyByPostProcess = sceneImageProcessingapplyByPostProcess; + }); + this._transparentMeshesCache.forEach(function (mesh) { + if (_this._shouldRenderAsTransmission(mesh.material)) { + mesh.material.refractionTexture = _this._opaqueRenderTarget; + } + }); + }; + /** + * Dispose all the elements created by the Helper. + */ + TransmissionHelper.prototype.dispose = function () { + this._scene._transmissionHelper = undefined; + if (this._opaqueRenderTarget) { + this._opaqueRenderTarget.dispose(); + this._opaqueRenderTarget = null; + } + this._transparentMeshesCache = []; + this._opaqueMeshesCache = []; + }; + return TransmissionHelper; +}()); +var NAME = "KHR_materials_transmission"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_transmission/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_transmission = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_transmission(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 175; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + if (this.enabled) { + loader.parent.transparencyAsCoverage = true; + } + } + /** @internal */ + KHR_materials_transmission.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_transmission.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadTransparentPropertiesAsync(extensionContext, material, babylonMaterial, extension)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_transmission.prototype._loadTransparentPropertiesAsync = function (context, material, babylonMaterial, extension) { + var _a, _b; + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var pbrMaterial = babylonMaterial; + // Enables "refraction" texture which represents transmitted light. + pbrMaterial.subSurface.isRefractionEnabled = true; + // Since this extension models thin-surface transmission only, we must make IOR = 1.0 + pbrMaterial.subSurface.volumeIndexOfRefraction = 1.0; + // Albedo colour will tint transmission. + pbrMaterial.subSurface.useAlbedoToTintRefraction = true; + if (extension.transmissionFactor !== undefined) { + pbrMaterial.subSurface.refractionIntensity = extension.transmissionFactor; + var scene = pbrMaterial.getScene(); + if (pbrMaterial.subSurface.refractionIntensity && !scene._transmissionHelper) { + new TransmissionHelper({}, pbrMaterial.getScene()); + } + else if (pbrMaterial.subSurface.refractionIntensity && !((_a = scene._transmissionHelper) === null || _a === void 0 ? void 0 : _a._isRenderTargetValid())) { + // If the render target is not valid, recreate it. + (_b = scene._transmissionHelper) === null || _b === void 0 ? void 0 : _b._setupRenderTargets(); + } + } + else { + pbrMaterial.subSurface.refractionIntensity = 0.0; + pbrMaterial.subSurface.isRefractionEnabled = false; + return Promise.resolve(); + } + pbrMaterial.subSurface.minimumThickness = 0.0; + pbrMaterial.subSurface.maximumThickness = 0.0; + if (extension.transmissionTexture) { + extension.transmissionTexture.nonColorData = true; + return this._loader.loadTextureInfoAsync("".concat(context, "/transmissionTexture"), extension.transmissionTexture, undefined).then(function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Transmission)"); + pbrMaterial.subSurface.refractionIntensityTexture = texture; + pbrMaterial.subSurface.useGltfStyleTextures = true; + }); + } + else { + return Promise.resolve(); + } + }; + return KHR_materials_transmission; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_transmission(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts": +/*!***************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_unlit: () => (/* binding */ KHR_materials_unlit) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "KHR_materials_unlit"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_unlit/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_unlit = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_unlit(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 210; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_unlit.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_unlit.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function () { + return _this._loadUnlitPropertiesAsync(context, material, babylonMaterial); + }); + }; + KHR_materials_unlit.prototype._loadUnlitPropertiesAsync = function (context, material, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.unlit = true; + var properties = material.pbrMetallicRoughness; + if (properties) { + if (properties.baseColorFactor) { + babylonMaterial.albedoColor = babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(properties.baseColorFactor); + babylonMaterial.alpha = properties.baseColorFactor[3]; + } + else { + babylonMaterial.albedoColor = babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_0__.Color3.White(); + } + if (properties.baseColorTexture) { + promises.push(this._loader.loadTextureInfoAsync("".concat(context, "/baseColorTexture"), properties.baseColorTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Base Color)"); + babylonMaterial.albedoTexture = texture; + })); + } + } + if (material.doubleSided) { + babylonMaterial.backFaceCulling = false; + babylonMaterial.twoSidedLighting = true; + } + this._loader.loadMaterialAlphaProperties(context, material, babylonMaterial); + return Promise.all(promises).then(function () { }); + }; + return KHR_materials_unlit; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_unlit(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_variants.ts": +/*!******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_variants.ts ***! + \******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_variants: () => (/* binding */ KHR_materials_variants) +/* harmony export */ }); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/mesh */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_variants"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_variants/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_variants = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_variants(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_materials_variants.prototype.dispose = function () { + this._loader = null; + }; + /** + * Gets the list of available variant names for this asset. + * @param rootMesh The glTF root mesh + * @returns the list of all the variant names for this model + */ + KHR_materials_variants.GetAvailableVariants = function (rootMesh) { + var extensionMetadata = this._GetExtensionMetadata(rootMesh); + if (!extensionMetadata) { + return []; + } + return Object.keys(extensionMetadata.variants); + }; + /** + * Gets the list of available variant names for this asset. + * @param rootMesh The glTF root mesh + * @returns the list of all the variant names for this model + */ + KHR_materials_variants.prototype.getAvailableVariants = function (rootMesh) { + return KHR_materials_variants.GetAvailableVariants(rootMesh); + }; + /** + * Select a variant given a variant name or a list of variant names. + * @param rootMesh The glTF root mesh + * @param variantName The variant name(s) to select. + */ + KHR_materials_variants.SelectVariant = function (rootMesh, variantName) { + var extensionMetadata = this._GetExtensionMetadata(rootMesh); + if (!extensionMetadata) { + throw new Error("Cannot select variant on a glTF mesh that does not have the ".concat(NAME, " extension")); + } + var select = function (variantName) { + var entries = extensionMetadata.variants[variantName]; + if (entries) { + for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { + var entry = entries_1[_i]; + entry.mesh.material = entry.material; + } + } + }; + if (variantName instanceof Array) { + for (var _i = 0, variantName_1 = variantName; _i < variantName_1.length; _i++) { + var name_1 = variantName_1[_i]; + select(name_1); + } + } + else { + select(variantName); + } + extensionMetadata.lastSelected = variantName; + }; + /** + * Select a variant given a variant name or a list of variant names. + * @param rootMesh The glTF root mesh + * @param variantName The variant name(s) to select. + */ + KHR_materials_variants.prototype.selectVariant = function (rootMesh, variantName) { + KHR_materials_variants.SelectVariant(rootMesh, variantName); + }; + /** + * Reset back to the original before selecting a variant. + * @param rootMesh The glTF root mesh + */ + KHR_materials_variants.Reset = function (rootMesh) { + var extensionMetadata = this._GetExtensionMetadata(rootMesh); + if (!extensionMetadata) { + throw new Error("Cannot reset on a glTF mesh that does not have the ".concat(NAME, " extension")); + } + for (var _i = 0, _a = extensionMetadata.original; _i < _a.length; _i++) { + var entry = _a[_i]; + entry.mesh.material = entry.material; + } + extensionMetadata.lastSelected = null; + }; + /** + * Reset back to the original before selecting a variant. + * @param rootMesh The glTF root mesh + */ + KHR_materials_variants.prototype.reset = function (rootMesh) { + KHR_materials_variants.Reset(rootMesh); + }; + /** + * Gets the last selected variant name(s) or null if original. + * @param rootMesh The glTF root mesh + * @returns The selected variant name(s). + */ + KHR_materials_variants.GetLastSelectedVariant = function (rootMesh) { + var extensionMetadata = this._GetExtensionMetadata(rootMesh); + if (!extensionMetadata) { + throw new Error("Cannot get the last selected variant on a glTF mesh that does not have the ".concat(NAME, " extension")); + } + return extensionMetadata.lastSelected; + }; + /** + * Gets the last selected variant name(s) or null if original. + * @param rootMesh The glTF root mesh + * @returns The selected variant name(s). + */ + KHR_materials_variants.prototype.getLastSelectedVariant = function (rootMesh) { + return KHR_materials_variants.GetLastSelectedVariant(rootMesh); + }; + KHR_materials_variants._GetExtensionMetadata = function (rootMesh) { + var _a, _b; + return ((_b = (_a = rootMesh === null || rootMesh === void 0 ? void 0 : rootMesh._internalMetadata) === null || _a === void 0 ? void 0 : _a.gltf) === null || _b === void 0 ? void 0 : _b[NAME]) || null; + }; + /** @internal */ + KHR_materials_variants.prototype.onLoading = function () { + var extensions = this._loader.gltf.extensions; + if (extensions && extensions[this.name]) { + var extension = extensions[this.name]; + this._variants = extension.variants; + } + }; + /** + * @internal + */ + KHR_materials_variants.prototype._loadMeshPrimitiveAsync = function (context, name, node, mesh, primitive, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.LoadExtensionAsync(context, primitive, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader._loadMeshPrimitiveAsync(context, name, node, mesh, primitive, function (babylonMesh) { + assign(babylonMesh); + if (babylonMesh instanceof babylonjs_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__.Mesh) { + var babylonDrawMode = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader._GetDrawMode(context, primitive.mode); + var root_1 = _this._loader.rootBabylonMesh; + var metadata = root_1 ? (root_1._internalMetadata = root_1._internalMetadata || {}) : {}; + var gltf = (metadata.gltf = metadata.gltf || {}); + var extensionMetadata_1 = (gltf[NAME] = gltf[NAME] || { lastSelected: null, original: [], variants: {} }); + // Store the original material. + extensionMetadata_1.original.push({ mesh: babylonMesh, material: babylonMesh.material }); + var _loop_1 = function (mappingIndex) { + var mapping = extension.mappings[mappingIndex]; + var material = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(extensionContext, "/mappings/").concat(mappingIndex, "/material"), _this._loader.gltf.materials, mapping.material); + promises.push(_this._loader._loadMaterialAsync("#/materials/".concat(mapping.material), material, babylonMesh, babylonDrawMode, function (babylonMaterial) { + var _loop_2 = function (mappingVariantIndex) { + var variantIndex = mapping.variants[mappingVariantIndex]; + var variant = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("/extensions/".concat(NAME, "/variants/").concat(variantIndex), _this._variants, variantIndex); + extensionMetadata_1.variants[variant.name] = extensionMetadata_1.variants[variant.name] || []; + extensionMetadata_1.variants[variant.name].push({ + mesh: babylonMesh, + material: babylonMaterial, + }); + // Replace the target when original mesh is cloned + babylonMesh.onClonedObservable.add(function (newOne) { + var newMesh = newOne; + var metadata = null; + var newRoot = newMesh; + // Find root to get medata + do { + newRoot = newRoot.parent; + if (!newRoot) { + return; + } + metadata = KHR_materials_variants._GetExtensionMetadata(newRoot); + } while (metadata === null); + // Need to clone the metadata on the root (first time only) + if (root_1 && metadata === KHR_materials_variants._GetExtensionMetadata(root_1)) { + // Copy main metadata + newRoot._internalMetadata = {}; + for (var key in root_1._internalMetadata) { + newRoot._internalMetadata[key] = root_1._internalMetadata[key]; + } + // Copy the gltf metadata + newRoot._internalMetadata.gltf = []; + for (var key in root_1._internalMetadata.gltf) { + newRoot._internalMetadata.gltf[key] = root_1._internalMetadata.gltf[key]; + } + // Duplicate the extension specific metadata + newRoot._internalMetadata.gltf[NAME] = { lastSelected: null, original: [], variants: {} }; + for (var _i = 0, _a = metadata.original; _i < _a.length; _i++) { + var original = _a[_i]; + newRoot._internalMetadata.gltf[NAME].original.push({ + mesh: original.mesh, + material: original.material, + }); + } + for (var key in metadata.variants) { + if (Object.prototype.hasOwnProperty.call(metadata.variants, key)) { + newRoot._internalMetadata.gltf[NAME].variants[key] = []; + for (var _b = 0, _c = metadata.variants[key]; _b < _c.length; _b++) { + var variantEntry = _c[_b]; + newRoot._internalMetadata.gltf[NAME].variants[key].push({ + mesh: variantEntry.mesh, + material: variantEntry.material, + }); + } + } + } + metadata = newRoot._internalMetadata.gltf[NAME]; + } + // Relocate + for (var _d = 0, _e = metadata.original; _d < _e.length; _d++) { + var target = _e[_d]; + if (target.mesh === babylonMesh) { + target.mesh = newMesh; + } + } + for (var _f = 0, _g = metadata.variants[variant.name]; _f < _g.length; _f++) { + var target = _g[_f]; + if (target.mesh === babylonMesh) { + target.mesh = newMesh; + } + } + }); + }; + for (var mappingVariantIndex = 0; mappingVariantIndex < mapping.variants.length; ++mappingVariantIndex) { + _loop_2(mappingVariantIndex); + } + })); + }; + // For each mapping, look at the variants and make a new entry for them. + for (var mappingIndex = 0; mappingIndex < extension.mappings.length; ++mappingIndex) { + _loop_1(mappingIndex); + } + } + })); + return Promise.all(promises).then(function (_a) { + var babylonMesh = _a[0]; + return babylonMesh; + }); + }); + }; + return KHR_materials_variants; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_variants(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts": +/*!****************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts ***! + \****************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_materials_volume: () => (/* binding */ KHR_materials_volume) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_materials_volume"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_volume/README.md) + * @since 5.0.0 + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_materials_volume = /** @class */ (function () { + /** + * @internal + */ + function KHR_materials_volume(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 173; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + if (this.enabled) { + // We need to disable instance usage because the attenuation factor depends on the node scale of each individual mesh + this._loader._disableInstancedMesh++; + } + } + /** @internal */ + KHR_materials_volume.prototype.dispose = function () { + if (this.enabled) { + this._loader._disableInstancedMesh--; + } + this._loader = null; + }; + /** + * @internal + */ + KHR_materials_volume.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial)); + promises.push(_this._loadVolumePropertiesAsync(extensionContext, material, babylonMaterial, extension)); + return Promise.all(promises).then(function () { }); + }); + }; + KHR_materials_volume.prototype._loadVolumePropertiesAsync = function (context, material, babylonMaterial, extension) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + // If transparency isn't enabled already, this extension shouldn't do anything. + // i.e. it requires either the KHR_materials_transmission or KHR_materials_diffuse_transmission extensions. + if ((!babylonMaterial.subSurface.isRefractionEnabled && !babylonMaterial.subSurface.isTranslucencyEnabled) || !extension.thicknessFactor) { + return Promise.resolve(); + } + // IOR in this extension only affects interior. + babylonMaterial.subSurface.volumeIndexOfRefraction = babylonMaterial.indexOfRefraction; + var attenuationDistance = extension.attenuationDistance !== undefined ? extension.attenuationDistance : Number.MAX_VALUE; + babylonMaterial.subSurface.tintColorAtDistance = attenuationDistance; + if (extension.attenuationColor !== undefined && extension.attenuationColor.length == 3) { + babylonMaterial.subSurface.tintColor.copyFromFloats(extension.attenuationColor[0], extension.attenuationColor[1], extension.attenuationColor[2]); + } + babylonMaterial.subSurface.minimumThickness = 0.0; + babylonMaterial.subSurface.maximumThickness = extension.thicknessFactor; + babylonMaterial.subSurface.useThicknessAsDepth = true; + if (extension.thicknessTexture) { + extension.thicknessTexture.nonColorData = true; + return this._loader.loadTextureInfoAsync("".concat(context, "/thicknessTexture"), extension.thicknessTexture).then(function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Thickness)"); + babylonMaterial.subSurface.thicknessTexture = texture; + babylonMaterial.subSurface.useGltfStyleTextures = true; + }); + } + else { + return Promise.resolve(); + } + }; + return KHR_materials_volume; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_materials_volume(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_mesh_quantization.ts": +/*!*****************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_mesh_quantization.ts ***! + \*****************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_mesh_quantization: () => (/* binding */ KHR_mesh_quantization) +/* harmony export */ }); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + +var NAME = "KHR_mesh_quantization"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_mesh_quantization/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_mesh_quantization = /** @class */ (function () { + /** + * @internal + */ + function KHR_mesh_quantization(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this.enabled = loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_mesh_quantization.prototype.dispose = function () { }; + return KHR_mesh_quantization; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_mesh_quantization(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_node_visibility.ts": +/*!***************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_node_visibility.ts ***! + \***************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_node_visibility: () => (/* binding */ KHR_node_visibility) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + +var NAME = "KHR_node_visibility"; +/** + * Loader extension for KHR_node_visibility + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_node_visibility = /** @class */ (function () { + /** + * @internal + */ + function KHR_node_visibility(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = loader.isExtensionUsed(NAME); + } + KHR_node_visibility.prototype.onReady = function () { + return (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__awaiter)(this, void 0, void 0, function () { + var _a; + return (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__generator)(this, function (_b) { + (_a = this._loader.gltf.nodes) === null || _a === void 0 ? void 0 : _a.forEach(function (node) { + var _a, _b, _c, _d; + (_a = node._primitiveBabylonMeshes) === null || _a === void 0 ? void 0 : _a.forEach(function (mesh) { + mesh.inheritVisibility = true; + }); + // When the JSON Pointer is used we need to change both the transform node and the primitive meshes to the new value. + if ((_b = node.extensions) === null || _b === void 0 ? void 0 : _b.KHR_node_visibility) { + if (((_c = node.extensions) === null || _c === void 0 ? void 0 : _c.KHR_node_visibility.visible) === false) { + if (node._babylonTransformNode) { + node._babylonTransformNode.isVisible = false; + } + (_d = node._primitiveBabylonMeshes) === null || _d === void 0 ? void 0 : _d.forEach(function (mesh) { + mesh.isVisible = false; + }); + } + } + }); + return [2 /*return*/]; + }); + }); + }; + KHR_node_visibility.prototype.dispose = function () { + this._loader = null; + }; + return KHR_node_visibility; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_node_visibility(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_texture_basisu.ts": +/*!**************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_texture_basisu.ts ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_texture_basisu: () => (/* binding */ KHR_texture_basisu) +/* harmony export */ }); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + +var NAME = "KHR_texture_basisu"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_texture_basisu/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_texture_basisu = /** @class */ (function () { + /** + * @internal + */ + function KHR_texture_basisu(loader) { + /** The name of this extension. */ + this.name = NAME; + this._loader = loader; + this.enabled = loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_texture_basisu.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_texture_basisu.prototype._loadTextureAsync = function (context, texture, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.LoadExtensionAsync(context, texture, this.name, function (extensionContext, extension) { + var sampler = texture.sampler == undefined ? _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader.DefaultSampler : _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(context, "/sampler"), _this._loader.gltf.samplers, texture.sampler); + var image = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem.Get("".concat(extensionContext, "/source"), _this._loader.gltf.images, extension.source); + return _this._loader._createTextureAsync(context, sampler, image, function (babylonTexture) { + assign(babylonTexture); + }, texture._textureInfo.nonColorData ? { useRGBAIfASTCBC7NotAvailableWhenUASTC: true } : undefined, !texture._textureInfo.nonColorData); + }); + }; + return KHR_texture_basisu; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_1__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_texture_basisu(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts": +/*!*****************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts ***! + \*****************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_texture_transform: () => (/* binding */ KHR_texture_transform) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Textures/texture */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "KHR_texture_transform"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_texture_transform/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_texture_transform = /** @class */ (function () { + /** + * @internal + */ + function KHR_texture_transform(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_texture_transform.prototype.dispose = function () { + this._loader = null; + }; + /** + * @internal + */ + KHR_texture_transform.prototype.loadTextureInfoAsync = function (context, textureInfo, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, textureInfo, this.name, function (extensionContext, extension) { + return _this._loader.loadTextureInfoAsync(context, textureInfo, function (babylonTexture) { + if (!(babylonTexture instanceof babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__.Texture)) { + throw new Error("".concat(extensionContext, ": Texture type not supported")); + } + if (extension.offset) { + babylonTexture.uOffset = extension.offset[0]; + babylonTexture.vOffset = extension.offset[1]; + } + // Always rotate around the origin. + babylonTexture.uRotationCenter = 0; + babylonTexture.vRotationCenter = 0; + if (extension.rotation) { + babylonTexture.wAng = -extension.rotation; + } + if (extension.scale) { + babylonTexture.uScale = extension.scale[0]; + babylonTexture.vScale = extension.scale[1]; + } + if (extension.texCoord != undefined) { + babylonTexture.coordinatesIndex = extension.texCoord; + } + assign(babylonTexture); + }); + }); + }; + return KHR_texture_transform; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_texture_transform(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_xmp_json_ld.ts": +/*!***********************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/KHR_xmp_json_ld.ts ***! + \***********************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ KHR_xmp_json_ld: () => (/* binding */ KHR_xmp_json_ld) +/* harmony export */ }); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + +var NAME = "KHR_xmp_json_ld"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_xmp_json_ld/README.md) + * @since 5.0.0 + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var KHR_xmp_json_ld = /** @class */ (function () { + /** + * @internal + */ + function KHR_xmp_json_ld(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 100; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + KHR_xmp_json_ld.prototype.dispose = function () { + this._loader = null; + }; + /** + * Called after the loader state changes to LOADING. + */ + KHR_xmp_json_ld.prototype.onLoading = function () { + var _a, _b, _c; + if (this._loader.rootBabylonMesh === null) { + return; + } + var xmp_gltf = (_a = this._loader.gltf.extensions) === null || _a === void 0 ? void 0 : _a.KHR_xmp_json_ld; + var xmp_node = (_c = (_b = this._loader.gltf.asset) === null || _b === void 0 ? void 0 : _b.extensions) === null || _c === void 0 ? void 0 : _c.KHR_xmp_json_ld; + if (xmp_gltf && xmp_node) { + var packet = +xmp_node.packet; + if (xmp_gltf.packets && packet < xmp_gltf.packets.length) { + this._loader.rootBabylonMesh.metadata = this._loader.rootBabylonMesh.metadata || {}; + this._loader.rootBabylonMesh.metadata.xmp = xmp_gltf.packets[packet]; + } + } + }; + return KHR_xmp_json_ld; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_0__.registerGLTFExtension)(NAME, true, function (loader) { return new KHR_xmp_json_ld(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts": +/*!**************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ MSFT_audio_emitter: () => (/* binding */ MSFT_audio_emitter) +/* harmony export */ }); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Audio/audioSceneComponent */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + + + + +var NAME = "MSFT_audio_emitter"; +/** + * [Specification](https://github.com/najadojo/glTF/blob/MSFT_audio_emitter/extensions/2.0/Vendor/MSFT_audio_emitter/README.md) + * !!! Experimental Extension Subject to Changes !!! + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var MSFT_audio_emitter = /** @class */ (function () { + /** + * @internal + */ + function MSFT_audio_emitter(loader) { + /** + * The name of this extension. + */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + MSFT_audio_emitter.prototype.dispose = function () { + this._loader = null; + this._clips = null; + this._emitters = null; + }; + /** @internal */ + MSFT_audio_emitter.prototype.onLoading = function () { + var extensions = this._loader.gltf.extensions; + if (extensions && extensions[this.name]) { + var extension = extensions[this.name]; + this._clips = extension.clips; + this._emitters = extension.emitters; + _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Assign(this._clips); + _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Assign(this._emitters); + } + }; + /** + * @internal + */ + MSFT_audio_emitter.prototype.loadSceneAsync = function (context, scene) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, scene, this.name, function (extensionContext, extension) { + var promises = new Array(); + promises.push(_this._loader.loadSceneAsync(context, scene)); + for (var _i = 0, _a = extension.emitters; _i < _a.length; _i++) { + var emitterIndex = _a[_i]; + var emitter = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("".concat(extensionContext, "/emitters"), _this._emitters, emitterIndex); + if (emitter.refDistance != undefined || + emitter.maxDistance != undefined || + emitter.rolloffFactor != undefined || + emitter.distanceModel != undefined || + emitter.innerAngle != undefined || + emitter.outerAngle != undefined) { + throw new Error("".concat(extensionContext, ": Direction or Distance properties are not allowed on emitters attached to a scene")); + } + promises.push(_this._loadEmitterAsync("".concat(extensionContext, "/emitters/").concat(emitter.index), emitter)); + } + return Promise.all(promises).then(function () { }); + }); + }; + /** + * @internal + */ + MSFT_audio_emitter.prototype.loadNodeAsync = function (context, node, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) { + var promises = new Array(); + return _this._loader + .loadNodeAsync(extensionContext, node, function (babylonMesh) { + var _loop_1 = function (emitterIndex) { + var emitter = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("".concat(extensionContext, "/emitters"), _this._emitters, emitterIndex); + promises.push(_this._loadEmitterAsync("".concat(extensionContext, "/emitters/").concat(emitter.index), emitter).then(function () { + for (var _i = 0, _a = emitter._babylonSounds; _i < _a.length; _i++) { + var sound = _a[_i]; + sound.attachToMesh(babylonMesh); + if (emitter.innerAngle != undefined || emitter.outerAngle != undefined) { + sound.setLocalDirectionToMesh(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Vector3.Forward()); + sound.setDirectionalCone(2 * babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.ToDegrees(emitter.innerAngle == undefined ? Math.PI : emitter.innerAngle), 2 * babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.ToDegrees(emitter.outerAngle == undefined ? Math.PI : emitter.outerAngle), 0); + } + } + })); + }; + for (var _i = 0, _a = extension.emitters; _i < _a.length; _i++) { + var emitterIndex = _a[_i]; + _loop_1(emitterIndex); + } + assign(babylonMesh); + }) + .then(function (babylonMesh) { + return Promise.all(promises).then(function () { + return babylonMesh; + }); + }); + }); + }; + /** + * @internal + */ + MSFT_audio_emitter.prototype.loadAnimationAsync = function (context, animation) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, animation, this.name, function (extensionContext, extension) { + return _this._loader.loadAnimationAsync(context, animation).then(function (babylonAnimationGroup) { + var promises = new Array(); + _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Assign(extension.events); + for (var _i = 0, _a = extension.events; _i < _a.length; _i++) { + var event_1 = _a[_i]; + promises.push(_this._loadAnimationEventAsync("".concat(extensionContext, "/events/").concat(event_1.index), context, animation, event_1, babylonAnimationGroup)); + } + return Promise.all(promises).then(function () { + return babylonAnimationGroup; + }); + }); + }); + }; + MSFT_audio_emitter.prototype._loadClipAsync = function (context, clip) { + if (clip._objectURL) { + return clip._objectURL; + } + var promise; + if (clip.uri) { + promise = this._loader.loadUriAsync(context, clip, clip.uri); + } + else { + var bufferView = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("".concat(context, "/bufferView"), this._loader.gltf.bufferViews, clip.bufferView); + promise = this._loader.loadBufferViewAsync("/bufferViews/".concat(bufferView.index), bufferView); + } + clip._objectURL = promise.then(function (data) { + return URL.createObjectURL(new Blob([data], { type: clip.mimeType })); + }); + return clip._objectURL; + }; + MSFT_audio_emitter.prototype._loadEmitterAsync = function (context, emitter) { + var _this = this; + emitter._babylonSounds = emitter._babylonSounds || []; + if (!emitter._babylonData) { + var clipPromises = new Array(); + var name_1 = emitter.name || "emitter".concat(emitter.index); + var options_1 = { + loop: false, + autoplay: false, + volume: emitter.volume == undefined ? 1 : emitter.volume, + }; + var _loop_2 = function (i) { + var clipContext = "/extensions/".concat(this_1.name, "/clips"); + var clip = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get(clipContext, this_1._clips, emitter.clips[i].clip); + clipPromises.push(this_1._loadClipAsync("".concat(clipContext, "/").concat(emitter.clips[i].clip), clip).then(function (objectURL) { + var sound = (emitter._babylonSounds[i] = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Sound(name_1, objectURL, _this._loader.babylonScene, null, options_1)); + sound.refDistance = emitter.refDistance || 1; + sound.maxDistance = emitter.maxDistance || 256; + sound.rolloffFactor = emitter.rolloffFactor || 1; + sound.distanceModel = emitter.distanceModel || "exponential"; + })); + }; + var this_1 = this; + for (var i = 0; i < emitter.clips.length; i++) { + _loop_2(i); + } + var promise = Promise.all(clipPromises).then(function () { + var weights = emitter.clips.map(function (clip) { + return clip.weight || 1; + }); + var weightedSound = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.WeightedSound(emitter.loop || false, emitter._babylonSounds, weights); + if (emitter.innerAngle) { + weightedSound.directionalConeInnerAngle = 2 * babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.ToDegrees(emitter.innerAngle); + } + if (emitter.outerAngle) { + weightedSound.directionalConeOuterAngle = 2 * babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.Tools.ToDegrees(emitter.outerAngle); + } + if (emitter.volume) { + weightedSound.volume = emitter.volume; + } + emitter._babylonData.sound = weightedSound; + }); + emitter._babylonData = { + loaded: promise, + }; + } + return emitter._babylonData.loaded; + }; + MSFT_audio_emitter.prototype._getEventAction = function (context, sound, action, time, startOffset) { + switch (action) { + case "play" /* IMSFTAudioEmitter_AnimationEventAction.play */: { + return function (currentFrame) { + var frameOffset = (startOffset || 0) + (currentFrame - time); + sound.play(frameOffset); + }; + } + case "stop" /* IMSFTAudioEmitter_AnimationEventAction.stop */: { + return function () { + sound.stop(); + }; + } + case "pause" /* IMSFTAudioEmitter_AnimationEventAction.pause */: { + return function () { + sound.pause(); + }; + } + default: { + throw new Error("".concat(context, ": Unsupported action ").concat(action)); + } + } + }; + MSFT_audio_emitter.prototype._loadAnimationEventAsync = function (context, animationContext, animation, event, babylonAnimationGroup) { + var _this = this; + if (babylonAnimationGroup.targetedAnimations.length == 0) { + return Promise.resolve(); + } + var babylonAnimation = babylonAnimationGroup.targetedAnimations[0]; + var emitterIndex = event.emitter; + var emitter = _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("/extensions/".concat(this.name, "/emitters"), this._emitters, emitterIndex); + return this._loadEmitterAsync(context, emitter).then(function () { + var sound = emitter._babylonData.sound; + if (sound) { + var babylonAnimationEvent = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__.AnimationEvent(event.time, _this._getEventAction(context, sound, event.action, event.time, event.startOffset)); + babylonAnimation.animation.addEvent(babylonAnimationEvent); + // Make sure all started audio stops when this animation is terminated. + babylonAnimationGroup.onAnimationGroupEndObservable.add(function () { + sound.stop(); + }); + babylonAnimationGroup.onAnimationGroupPauseObservable.add(function () { + sound.pause(); + }); + } + }); + }; + return MSFT_audio_emitter; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new MSFT_audio_emitter(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_lod.ts": +/*!****************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_lod.ts ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ MSFT_lod: () => (/* binding */ MSFT_lod) +/* harmony export */ }); +/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/deferred */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + +var NAME = "MSFT_lod"; +/** + * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/MSFT_lod/README.md) + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var MSFT_lod = /** @class */ (function () { + /** + * @internal + */ + function MSFT_lod(loader) { + var _a, _b; + /** + * The name of this extension. + */ + this.name = NAME; + /** + * Defines a number that determines the order the extensions are applied. + */ + this.order = 100; + /** + * Maximum number of LODs to load, starting from the lowest LOD. + */ + this.maxLODsToLoad = 10; + /** + * Observable raised when all node LODs of one level are loaded. + * The event data is the index of the loaded LOD starting from zero. + * Dispose the loader to cancel the loading of the next level of LODs. + */ + this.onNodeLODsLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when all material LODs of one level are loaded. + * The event data is the index of the loaded LOD starting from zero. + * Dispose the loader to cancel the loading of the next level of LODs. + */ + this.onMaterialLODsLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + this._bufferLODs = new Array(); + this._nodeIndexLOD = null; + this._nodeSignalLODs = new Array(); + this._nodePromiseLODs = new Array(); + this._nodeBufferLODs = new Array(); + this._materialIndexLOD = null; + this._materialSignalLODs = new Array(); + this._materialPromiseLODs = new Array(); + this._materialBufferLODs = new Array(); + this._loader = loader; + // Options takes precedence. The maxLODsToLoad extension property is retained for back compat. + // For new extensions, they should only use options. + this.maxLODsToLoad = (_b = (_a = this._loader.parent.extensionOptions[NAME]) === null || _a === void 0 ? void 0 : _a.maxLODsToLoad) !== null && _b !== void 0 ? _b : this.maxLODsToLoad; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + MSFT_lod.prototype.dispose = function () { + this._loader = null; + this._nodeIndexLOD = null; + this._nodeSignalLODs.length = 0; + this._nodePromiseLODs.length = 0; + this._nodeBufferLODs.length = 0; + this._materialIndexLOD = null; + this._materialSignalLODs.length = 0; + this._materialPromiseLODs.length = 0; + this._materialBufferLODs.length = 0; + this.onMaterialLODsLoadedObservable.clear(); + this.onNodeLODsLoadedObservable.clear(); + }; + /** @internal */ + MSFT_lod.prototype.onReady = function () { + var _this = this; + var _loop_1 = function (indexLOD) { + var promise = Promise.all(this_1._nodePromiseLODs[indexLOD]).then(function () { + if (indexLOD !== 0) { + _this._loader.endPerformanceCounter("Node LOD ".concat(indexLOD)); + _this._loader.log("Loaded node LOD ".concat(indexLOD)); + } + _this.onNodeLODsLoadedObservable.notifyObservers(indexLOD); + if (indexLOD !== _this._nodePromiseLODs.length - 1) { + _this._loader.startPerformanceCounter("Node LOD ".concat(indexLOD + 1)); + _this._loadBufferLOD(_this._nodeBufferLODs, indexLOD + 1); + if (_this._nodeSignalLODs[indexLOD]) { + _this._nodeSignalLODs[indexLOD].resolve(); + } + } + }); + this_1._loader._completePromises.push(promise); + }; + var this_1 = this; + for (var indexLOD = 0; indexLOD < this._nodePromiseLODs.length; indexLOD++) { + _loop_1(indexLOD); + } + var _loop_2 = function (indexLOD) { + var promise = Promise.all(this_2._materialPromiseLODs[indexLOD]).then(function () { + if (indexLOD !== 0) { + _this._loader.endPerformanceCounter("Material LOD ".concat(indexLOD)); + _this._loader.log("Loaded material LOD ".concat(indexLOD)); + } + _this.onMaterialLODsLoadedObservable.notifyObservers(indexLOD); + if (indexLOD !== _this._materialPromiseLODs.length - 1) { + _this._loader.startPerformanceCounter("Material LOD ".concat(indexLOD + 1)); + _this._loadBufferLOD(_this._materialBufferLODs, indexLOD + 1); + if (_this._materialSignalLODs[indexLOD]) { + _this._materialSignalLODs[indexLOD].resolve(); + } + } + }); + this_2._loader._completePromises.push(promise); + }; + var this_2 = this; + for (var indexLOD = 0; indexLOD < this._materialPromiseLODs.length; indexLOD++) { + _loop_2(indexLOD); + } + }; + /** + * @internal + */ + MSFT_lod.prototype.loadSceneAsync = function (context, scene) { + var promise = this._loader.loadSceneAsync(context, scene); + this._loadBufferLOD(this._bufferLODs, 0); + return promise; + }; + /** + * @internal + */ + MSFT_lod.prototype.loadNodeAsync = function (context, node, assign) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) { + var firstPromise; + var nodeLODs = _this._getLODs(extensionContext, node, _this._loader.gltf.nodes, extension.ids); + _this._loader.logOpen("".concat(extensionContext)); + var _loop_3 = function (indexLOD) { + var nodeLOD = nodeLODs[indexLOD]; + if (indexLOD !== 0) { + _this._nodeIndexLOD = indexLOD; + _this._nodeSignalLODs[indexLOD] = _this._nodeSignalLODs[indexLOD] || new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Deferred(); + } + var assignWrap = function (babylonTransformNode) { + assign(babylonTransformNode); + babylonTransformNode.setEnabled(false); + }; + var promise = _this._loader.loadNodeAsync("/nodes/".concat(nodeLOD.index), nodeLOD, assignWrap).then(function (babylonMesh) { + if (indexLOD !== 0) { + // TODO: should not rely on _babylonTransformNode + var previousNodeLOD = nodeLODs[indexLOD - 1]; + if (previousNodeLOD._babylonTransformNode) { + _this._disposeTransformNode(previousNodeLOD._babylonTransformNode); + delete previousNodeLOD._babylonTransformNode; + } + } + babylonMesh.setEnabled(true); + return babylonMesh; + }); + _this._nodePromiseLODs[indexLOD] = _this._nodePromiseLODs[indexLOD] || []; + if (indexLOD === 0) { + firstPromise = promise; + } + else { + _this._nodeIndexLOD = null; + _this._nodePromiseLODs[indexLOD].push(promise); + } + }; + for (var indexLOD = 0; indexLOD < nodeLODs.length; indexLOD++) { + _loop_3(indexLOD); + } + _this._loader.logClose(); + return firstPromise; + }); + }; + /** + * @internal + */ + MSFT_lod.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) { + var _this = this; + // Don't load material LODs if already loading a node LOD. + if (this._nodeIndexLOD) { + return null; + } + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtensionAsync(context, material, this.name, function (extensionContext, extension) { + var firstPromise; + var materialLODs = _this._getLODs(extensionContext, material, _this._loader.gltf.materials, extension.ids); + _this._loader.logOpen("".concat(extensionContext)); + var _loop_4 = function (indexLOD) { + var materialLOD = materialLODs[indexLOD]; + if (indexLOD !== 0) { + _this._materialIndexLOD = indexLOD; + } + var promise = _this._loader + ._loadMaterialAsync("/materials/".concat(materialLOD.index), materialLOD, babylonMesh, babylonDrawMode, function (babylonMaterial) { + if (indexLOD === 0) { + assign(babylonMaterial); + } + }) + .then(function (babylonMaterial) { + if (indexLOD !== 0) { + assign(babylonMaterial); + // TODO: should not rely on _data + var previousDataLOD = materialLODs[indexLOD - 1]._data; + if (previousDataLOD[babylonDrawMode]) { + _this._disposeMaterials([previousDataLOD[babylonDrawMode].babylonMaterial]); + delete previousDataLOD[babylonDrawMode]; + } + } + return babylonMaterial; + }); + _this._materialPromiseLODs[indexLOD] = _this._materialPromiseLODs[indexLOD] || []; + if (indexLOD === 0) { + firstPromise = promise; + } + else { + _this._materialIndexLOD = null; + _this._materialPromiseLODs[indexLOD].push(promise); + } + }; + for (var indexLOD = 0; indexLOD < materialLODs.length; indexLOD++) { + _loop_4(indexLOD); + } + _this._loader.logClose(); + return firstPromise; + }); + }; + /** + * @internal + */ + MSFT_lod.prototype._loadUriAsync = function (context, property, uri) { + var _this = this; + // Defer the loading of uris if loading a node or material LOD. + if (this._nodeIndexLOD !== null) { + this._loader.log("deferred"); + var previousIndexLOD = this._nodeIndexLOD - 1; + this._nodeSignalLODs[previousIndexLOD] = this._nodeSignalLODs[previousIndexLOD] || new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Deferred(); + return this._nodeSignalLODs[this._nodeIndexLOD - 1].promise.then(function () { + return _this._loader.loadUriAsync(context, property, uri); + }); + } + else if (this._materialIndexLOD !== null) { + this._loader.log("deferred"); + var previousIndexLOD = this._materialIndexLOD - 1; + this._materialSignalLODs[previousIndexLOD] = this._materialSignalLODs[previousIndexLOD] || new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Deferred(); + return this._materialSignalLODs[previousIndexLOD].promise.then(function () { + return _this._loader.loadUriAsync(context, property, uri); + }); + } + return null; + }; + /** + * @internal + */ + MSFT_lod.prototype.loadBufferAsync = function (context, buffer, byteOffset, byteLength) { + if (this._loader.parent.useRangeRequests && !buffer.uri) { + if (!this._loader.bin) { + throw new Error("".concat(context, ": Uri is missing or the binary glTF is missing its binary chunk")); + } + var loadAsync = function (bufferLODs, indexLOD) { + var start = byteOffset; + var end = start + byteLength - 1; + var bufferLOD = bufferLODs[indexLOD]; + if (bufferLOD) { + bufferLOD.start = Math.min(bufferLOD.start, start); + bufferLOD.end = Math.max(bufferLOD.end, end); + } + else { + bufferLOD = { start: start, end: end, loaded: new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Deferred() }; + bufferLODs[indexLOD] = bufferLOD; + } + return bufferLOD.loaded.promise.then(function (data) { + return new Uint8Array(data.buffer, data.byteOffset + byteOffset - bufferLOD.start, byteLength); + }); + }; + this._loader.log("deferred"); + if (this._nodeIndexLOD !== null) { + return loadAsync(this._nodeBufferLODs, this._nodeIndexLOD); + } + else if (this._materialIndexLOD !== null) { + return loadAsync(this._materialBufferLODs, this._materialIndexLOD); + } + else { + return loadAsync(this._bufferLODs, 0); + } + } + return null; + }; + MSFT_lod.prototype._loadBufferLOD = function (bufferLODs, indexLOD) { + var bufferLOD = bufferLODs[indexLOD]; + if (bufferLOD) { + this._loader.log("Loading buffer range [".concat(bufferLOD.start, "-").concat(bufferLOD.end, "]")); + this._loader.bin.readAsync(bufferLOD.start, bufferLOD.end - bufferLOD.start + 1).then(function (data) { + bufferLOD.loaded.resolve(data); + }, function (error) { + bufferLOD.loaded.reject(error); + }); + } + }; + /** + * @returns an array of LOD properties from lowest to highest. + * @param context + * @param property + * @param array + * @param ids + */ + MSFT_lod.prototype._getLODs = function (context, property, array, ids) { + if (this.maxLODsToLoad <= 0) { + throw new Error("maxLODsToLoad must be greater than zero"); + } + var properties = []; + for (var i = ids.length - 1; i >= 0; i--) { + properties.push(_glTFLoader__WEBPACK_IMPORTED_MODULE_1__.ArrayItem.Get("".concat(context, "/ids/").concat(ids[i]), array, ids[i])); + if (properties.length === this.maxLODsToLoad) { + return properties; + } + } + properties.push(property); + return properties; + }; + MSFT_lod.prototype._disposeTransformNode = function (babylonTransformNode) { + var _this = this; + var babylonMaterials = []; + var babylonMaterial = babylonTransformNode.material; + if (babylonMaterial) { + babylonMaterials.push(babylonMaterial); + } + for (var _i = 0, _a = babylonTransformNode.getChildMeshes(); _i < _a.length; _i++) { + var babylonMesh = _a[_i]; + if (babylonMesh.material) { + babylonMaterials.push(babylonMesh.material); + } + } + babylonTransformNode.dispose(); + var babylonMaterialsToDispose = babylonMaterials.filter(function (babylonMaterial) { return _this._loader.babylonScene.meshes.every(function (mesh) { return mesh.material != babylonMaterial; }); }); + this._disposeMaterials(babylonMaterialsToDispose); + }; + MSFT_lod.prototype._disposeMaterials = function (babylonMaterials) { + var babylonTextures = {}; + for (var _i = 0, babylonMaterials_1 = babylonMaterials; _i < babylonMaterials_1.length; _i++) { + var babylonMaterial = babylonMaterials_1[_i]; + for (var _a = 0, _b = babylonMaterial.getActiveTextures(); _a < _b.length; _a++) { + var babylonTexture = _b[_a]; + babylonTextures[babylonTexture.uniqueId] = babylonTexture; + } + babylonMaterial.dispose(); + } + for (var uniqueId in babylonTextures) { + for (var _c = 0, _d = this._loader.babylonScene.materials; _c < _d.length; _c++) { + var babylonMaterial = _d[_c]; + if (babylonMaterial.hasTexture(babylonTextures[uniqueId])) { + delete babylonTextures[uniqueId]; + } + } + } + for (var uniqueId in babylonTextures) { + babylonTextures[uniqueId].dispose(); + } + }; + return MSFT_lod; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new MSFT_lod(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_minecraftMesh.ts": +/*!**************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_minecraftMesh.ts ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ MSFT_minecraftMesh: () => (/* binding */ MSFT_minecraftMesh) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "MSFT_minecraftMesh"; +/** @internal */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var MSFT_minecraftMesh = /** @class */ (function () { + /** @internal */ + function MSFT_minecraftMesh(loader) { + /** @internal */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + MSFT_minecraftMesh.prototype.dispose = function () { + this._loader = null; + }; + /** @internal */ + MSFT_minecraftMesh.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtraAsync(context, material, this.name, function (extraContext, extra) { + if (extra) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(extraContext, ": Material type not supported")); + } + var promise = _this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial); + if (babylonMaterial.needAlphaBlending()) { + babylonMaterial.forceDepthWrite = true; + babylonMaterial.separateCullingPass = true; + } + babylonMaterial.backFaceCulling = babylonMaterial.forceDepthWrite; + babylonMaterial.twoSidedLighting = true; + return promise; + } + return null; + }); + }; + return MSFT_minecraftMesh; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new MSFT_minecraftMesh(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts": +/*!************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ MSFT_sRGBFactors: () => (/* binding */ MSFT_sRGBFactors) +/* harmony export */ }); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + +var NAME = "MSFT_sRGBFactors"; +/** @internal */ +// eslint-disable-next-line @typescript-eslint/naming-convention +var MSFT_sRGBFactors = /** @class */ (function () { + /** @internal */ + function MSFT_sRGBFactors(loader) { + /** @internal */ + this.name = NAME; + this._loader = loader; + this.enabled = this._loader.isExtensionUsed(NAME); + } + /** @internal */ + MSFT_sRGBFactors.prototype.dispose = function () { + this._loader = null; + }; + /** @internal */ + MSFT_sRGBFactors.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var _this = this; + return _glTFLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoader.LoadExtraAsync(context, material, this.name, function (extraContext, extra) { + if (extra) { + if (!(babylonMaterial instanceof babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(extraContext, ": Material type not supported")); + } + var promise = _this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial); + var useExactSrgbConversions = babylonMaterial.getScene().getEngine().useExactSrgbConversions; + if (!babylonMaterial.albedoTexture) { + babylonMaterial.albedoColor.toLinearSpaceToRef(babylonMaterial.albedoColor, useExactSrgbConversions); + } + if (!babylonMaterial.reflectivityTexture) { + babylonMaterial.reflectivityColor.toLinearSpaceToRef(babylonMaterial.reflectivityColor, useExactSrgbConversions); + } + return promise; + } + return null; + }); + }; + return MSFT_sRGBFactors; +}()); + +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension)(NAME); +(0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension)(NAME, true, function (loader) { return new MSFT_sRGBFactors(loader); }); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/gltfPathToObjectConverter.ts": +/*!*********************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/gltfPathToObjectConverter.ts ***! + \*********************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFPathToObjectConverter: () => (/* binding */ GLTFPathToObjectConverter) +/* harmony export */ }); +/** + * A converter that takes a glTF Object Model JSON Pointer + * and transforms it into an ObjectAccessorContainer, allowing + * objects referenced in the glTF to be associated with their + * respective Babylon.js objects. + */ +var GLTFPathToObjectConverter = /** @class */ (function () { + function GLTFPathToObjectConverter(_gltf, _infoTree) { + this._gltf = _gltf; + this._infoTree = _infoTree; + } + /** + * The pointer string is represented by a [JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901). + * := /// + * := "nodes" | "materials" | "meshes" | "cameras" | "extensions" + * := | + * := | + * := "extensions"// + * := | / + * := W+ + * := D+ + * + * Examples: + * - "/nodes/0/rotation" + * - "/materials/2/emissiveFactor" + * - "/materials/2/pbrMetallicRoughness/baseColorFactor" + * - "/materials/2/extensions/KHR_materials_emissive_strength/emissiveStrength" + * + * @param path The path to convert + * @returns The object and info associated with the path + */ + GLTFPathToObjectConverter.prototype.convert = function (path) { + var objectTree = this._gltf; + var infoTree = this._infoTree; + var target = undefined; + if (!path.startsWith("/")) { + throw new Error("Path must start with a /"); + } + var parts = path.split("/"); + parts.shift(); + for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) { + var part = parts_1[_i]; + if (infoTree.__array__) { + infoTree = infoTree.__array__; + } + else { + infoTree = infoTree[part]; + if (!infoTree) { + throw new Error("Path ".concat(path, " is invalid")); + } + } + if (objectTree === undefined) { + throw new Error("Path ".concat(path, " is invalid")); + } + objectTree = objectTree[part]; + if (infoTree.__target__) { + target = objectTree; + } + } + return { + object: target, + info: infoTree, + }; + }; + return GLTFPathToObjectConverter; +}()); + + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/index.ts": +/*!*************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/index.ts ***! + \*************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ EXT_lights_image_based: () => (/* reexport safe */ _EXT_lights_image_based__WEBPACK_IMPORTED_MODULE_0__.EXT_lights_image_based), +/* harmony export */ EXT_mesh_gpu_instancing: () => (/* reexport safe */ _EXT_mesh_gpu_instancing__WEBPACK_IMPORTED_MODULE_1__.EXT_mesh_gpu_instancing), +/* harmony export */ EXT_meshopt_compression: () => (/* reexport safe */ _EXT_meshopt_compression__WEBPACK_IMPORTED_MODULE_2__.EXT_meshopt_compression), +/* harmony export */ EXT_texture_avif: () => (/* reexport safe */ _EXT_texture_avif__WEBPACK_IMPORTED_MODULE_4__.EXT_texture_avif), +/* harmony export */ EXT_texture_webp: () => (/* reexport safe */ _EXT_texture_webp__WEBPACK_IMPORTED_MODULE_3__.EXT_texture_webp), +/* harmony export */ ExtrasAsMetadata: () => (/* reexport safe */ _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_32__.ExtrasAsMetadata), +/* harmony export */ KHR_animation_pointer: () => (/* reexport safe */ _KHR_animation_pointer__WEBPACK_IMPORTED_MODULE_25__.KHR_animation_pointer), +/* harmony export */ KHR_draco_mesh_compression: () => (/* reexport safe */ _KHR_draco_mesh_compression__WEBPACK_IMPORTED_MODULE_5__.KHR_draco_mesh_compression), +/* harmony export */ KHR_interactivity: () => (/* reexport safe */ _KHR_interactivity__WEBPACK_IMPORTED_MODULE_30__.KHR_interactivity), +/* harmony export */ KHR_lights: () => (/* reexport safe */ _KHR_lights_punctual__WEBPACK_IMPORTED_MODULE_6__.KHR_lights), +/* harmony export */ KHR_materials_anisotropy: () => (/* reexport safe */ _KHR_materials_anisotropy__WEBPACK_IMPORTED_MODULE_11__.KHR_materials_anisotropy), +/* harmony export */ KHR_materials_clearcoat: () => (/* reexport safe */ _KHR_materials_clearcoat__WEBPACK_IMPORTED_MODULE_9__.KHR_materials_clearcoat), +/* harmony export */ KHR_materials_diffuse_transmission: () => (/* reexport safe */ _KHR_materials_diffuse_transmission__WEBPACK_IMPORTED_MODULE_18__.KHR_materials_diffuse_transmission), +/* harmony export */ KHR_materials_dispersion: () => (/* reexport safe */ _KHR_materials_dispersion__WEBPACK_IMPORTED_MODULE_20__.KHR_materials_dispersion), +/* harmony export */ KHR_materials_emissive_strength: () => (/* reexport safe */ _KHR_materials_emissive_strength__WEBPACK_IMPORTED_MODULE_12__.KHR_materials_emissive_strength), +/* harmony export */ KHR_materials_ior: () => (/* reexport safe */ _KHR_materials_ior__WEBPACK_IMPORTED_MODULE_15__.KHR_materials_ior), +/* harmony export */ KHR_materials_iridescence: () => (/* reexport safe */ _KHR_materials_iridescence__WEBPACK_IMPORTED_MODULE_10__.KHR_materials_iridescence), +/* harmony export */ KHR_materials_pbrSpecularGlossiness: () => (/* reexport safe */ _KHR_materials_pbrSpecularGlossiness__WEBPACK_IMPORTED_MODULE_7__.KHR_materials_pbrSpecularGlossiness), +/* harmony export */ KHR_materials_sheen: () => (/* reexport safe */ _KHR_materials_sheen__WEBPACK_IMPORTED_MODULE_13__.KHR_materials_sheen), +/* harmony export */ KHR_materials_specular: () => (/* reexport safe */ _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_14__.KHR_materials_specular), +/* harmony export */ KHR_materials_transmission: () => (/* reexport safe */ _KHR_materials_transmission__WEBPACK_IMPORTED_MODULE_17__.KHR_materials_transmission), +/* harmony export */ KHR_materials_unlit: () => (/* reexport safe */ _KHR_materials_unlit__WEBPACK_IMPORTED_MODULE_8__.KHR_materials_unlit), +/* harmony export */ KHR_materials_variants: () => (/* reexport safe */ _KHR_materials_variants__WEBPACK_IMPORTED_MODULE_16__.KHR_materials_variants), +/* harmony export */ KHR_materials_volume: () => (/* reexport safe */ _KHR_materials_volume__WEBPACK_IMPORTED_MODULE_19__.KHR_materials_volume), +/* harmony export */ KHR_mesh_quantization: () => (/* reexport safe */ _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_21__.KHR_mesh_quantization), +/* harmony export */ KHR_node_visibility: () => (/* reexport safe */ _KHR_node_visibility__WEBPACK_IMPORTED_MODULE_31__.KHR_node_visibility), +/* harmony export */ KHR_texture_basisu: () => (/* reexport safe */ _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_22__.KHR_texture_basisu), +/* harmony export */ KHR_texture_transform: () => (/* reexport safe */ _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_23__.KHR_texture_transform), +/* harmony export */ KHR_xmp_json_ld: () => (/* reexport safe */ _KHR_xmp_json_ld__WEBPACK_IMPORTED_MODULE_24__.KHR_xmp_json_ld), +/* harmony export */ MSFT_audio_emitter: () => (/* reexport safe */ _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_26__.MSFT_audio_emitter), +/* harmony export */ MSFT_lod: () => (/* reexport safe */ _MSFT_lod__WEBPACK_IMPORTED_MODULE_27__.MSFT_lod), +/* harmony export */ MSFT_minecraftMesh: () => (/* reexport safe */ _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_28__.MSFT_minecraftMesh), +/* harmony export */ MSFT_sRGBFactors: () => (/* reexport safe */ _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_29__.MSFT_sRGBFactors) +/* harmony export */ }); +/* harmony import */ var _EXT_lights_image_based__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./EXT_lights_image_based */ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_lights_image_based.ts"); +/* harmony import */ var _EXT_mesh_gpu_instancing__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./EXT_mesh_gpu_instancing */ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts"); +/* harmony import */ var _EXT_meshopt_compression__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./EXT_meshopt_compression */ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_meshopt_compression.ts"); +/* harmony import */ var _EXT_texture_webp__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./EXT_texture_webp */ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_texture_webp.ts"); +/* harmony import */ var _EXT_texture_avif__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./EXT_texture_avif */ "../../../dev/loaders/src/glTF/2.0/Extensions/EXT_texture_avif.ts"); +/* harmony import */ var _KHR_draco_mesh_compression__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./KHR_draco_mesh_compression */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts"); +/* harmony import */ var _KHR_lights_punctual__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./KHR_lights_punctual */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts"); +/* harmony import */ var _KHR_materials_pbrSpecularGlossiness__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./KHR_materials_pbrSpecularGlossiness */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts"); +/* harmony import */ var _KHR_materials_unlit__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_materials_unlit */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts"); +/* harmony import */ var _KHR_materials_clearcoat__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_materials_clearcoat */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts"); +/* harmony import */ var _KHR_materials_iridescence__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./KHR_materials_iridescence */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_iridescence.ts"); +/* harmony import */ var _KHR_materials_anisotropy__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./KHR_materials_anisotropy */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts"); +/* harmony import */ var _KHR_materials_emissive_strength__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./KHR_materials_emissive_strength */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_emissive_strength.ts"); +/* harmony import */ var _KHR_materials_sheen__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./KHR_materials_sheen */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_sheen.ts"); +/* harmony import */ var _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./KHR_materials_specular */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_specular.ts"); +/* harmony import */ var _KHR_materials_ior__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./KHR_materials_ior */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_ior.ts"); +/* harmony import */ var _KHR_materials_variants__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./KHR_materials_variants */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_variants.ts"); +/* harmony import */ var _KHR_materials_transmission__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./KHR_materials_transmission */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_transmission.ts"); +/* harmony import */ var _KHR_materials_diffuse_transmission__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./KHR_materials_diffuse_transmission */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts"); +/* harmony import */ var _KHR_materials_volume__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./KHR_materials_volume */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_volume.ts"); +/* harmony import */ var _KHR_materials_dispersion__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./KHR_materials_dispersion */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts"); +/* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_mesh_quantization.ts"); +/* harmony import */ var _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./KHR_texture_basisu */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_texture_basisu.ts"); +/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./KHR_texture_transform */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts"); +/* harmony import */ var _KHR_xmp_json_ld__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./KHR_xmp_json_ld */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_xmp_json_ld.ts"); +/* harmony import */ var _KHR_animation_pointer__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./KHR_animation_pointer */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_animation_pointer.ts"); +/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts"); +/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./MSFT_lod */ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_lod.ts"); +/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_minecraftMesh.ts"); +/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "../../../dev/loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts"); +/* harmony import */ var _KHR_interactivity__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./KHR_interactivity */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_interactivity.ts"); +/* harmony import */ var _KHR_node_visibility__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./KHR_node_visibility */ "../../../dev/loaders/src/glTF/2.0/Extensions/KHR_node_visibility.ts"); +/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "../../../dev/loaders/src/glTF/2.0/Extensions/ExtrasAsMetadata.ts"); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/interactivityFunctions.ts": +/*!******************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/interactivityFunctions.ts ***! + \******************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ convertGLTFToSerializedFlowGraph: () => (/* binding */ convertGLTFToSerializedFlowGraph) +/* harmony export */ }); +/* harmony import */ var babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/guid */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _interactivityUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./interactivityUtils */ "../../../dev/loaders/src/glTF/2.0/Extensions/interactivityUtils.ts"); + + +function convertValueWithType(configObject, definition, context) { + if (configObject.type !== undefined) { + // get the type on the gltf definition + var type = definition.types && definition.types[configObject.type]; + if (!type) { + throw new Error("".concat(context, ": Unknown type: ").concat(configObject.type)); + } + var signature = type.signature; + if (!signature) { + throw new Error("".concat(context, ": Type ").concat(configObject.type, " has no signature")); + } + var convertedType = _interactivityUtils__WEBPACK_IMPORTED_MODULE_1__.gltfTypeToBabylonType[signature]; + return { + value: configObject.value, + className: convertedType, + }; + } + else { + return configObject.value; + } +} +function convertConfiguration(gltfBlock, definition, id) { + var _a; + var converted = {}; + var configurationList = (_a = gltfBlock.configuration) !== null && _a !== void 0 ? _a : []; + for (var _i = 0, configurationList_1 = configurationList; _i < configurationList_1.length; _i++) { + var configObject = configurationList_1[_i]; + if (configObject.id === "customEvent") { + var customEvent = definition.customEvents && definition.customEvents[configObject.value]; + if (!customEvent) { + throw new Error("/extensions/KHR_interactivity/nodes/".concat(id, ": Unknown custom event: ").concat(configObject.value)); + } + converted.eventId = customEvent.id; + converted.eventData = customEvent.values.map(function (v) { return v.id; }); + } + else if (configObject.id === "variable") { + var variable = definition.variables && definition.variables[configObject.value]; + if (!variable) { + throw new Error("/extensions/KHR_interactivity/nodes/".concat(id, ": Unknown variable: ").concat(configObject.value)); + } + converted.variableName = variable.id; + } + else if (configObject.id === "path") { + // Convert from a GLTF path to a reference to the Babylon.js object + var pathValue = configObject.value; + converted.path = pathValue; + } + else { + converted[configObject.id] = convertValueWithType(configObject, definition, "/extensions/KHR_interactivity/nodes/".concat(id)); + } + } + return converted; +} +function convertBlock(id, gltfBlock, definition) { + var className = _interactivityUtils__WEBPACK_IMPORTED_MODULE_1__.gltfToFlowGraphTypeMap[gltfBlock.type]; + if (!className) { + throw new Error("/extensions/KHR_interactivity/nodes/".concat(id, ": Unknown block type: ").concat(gltfBlock.type)); + } + var uniqueId = id.toString(); + var config = convertConfiguration(gltfBlock, definition, uniqueId); + var metadata = gltfBlock.metadata; + var dataInputs = []; + var dataOutputs = []; + var signalInputs = []; + var signalOutputs = []; + return { + className: className, + config: config, + uniqueId: uniqueId, + metadata: metadata, + dataInputs: dataInputs, + dataOutputs: dataOutputs, + signalInputs: signalInputs, + signalOutputs: signalOutputs, + }; +} +/** + * @internal + * Converts a glTF Interactivity Extension to a serialized flow graph. + * @param gltf the interactivity data + * @returns a serialized flow graph + */ +function convertGLTFToSerializedFlowGraph(gltf) { + var _a, _b, _c; + // create an empty serialized context to store the values of the connections + var context = { + uniqueId: (0,babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__.RandomGUID)(), + _userVariables: {}, + _connectionValues: {}, + }; + var executionContexts = [context]; + // Blocks converted to the flow graph json format + var flowGraphJsonBlocks = []; + for (var i = 0; i < gltf.nodes.length; i++) { + var gltfBlock = gltf.nodes[i]; + var flowGraphJsonBlock = convertBlock(i, gltfBlock, gltf); + flowGraphJsonBlocks.push(flowGraphJsonBlock); + } + // Parse the connections + for (var i = 0; i < gltf.nodes.length; i++) { + var gltfBlock = gltf.nodes[i]; + // get the block that was created in the previous step + var fgBlock = flowGraphJsonBlocks[i]; + var gltfFlows = (_a = gltfBlock.flows) !== null && _a !== void 0 ? _a : []; + var _loop_1 = function (flow) { + var socketOutName = flow.id; + // create an output connection for the flow graph block + var socketOut = { + uniqueId: (0,babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__.RandomGUID)(), + name: socketOutName, + _connectionType: 1 /* FlowGraphConnectionType.Output */, // Output + connectedPointIds: [], + }; + fgBlock.signalOutputs.push(socketOut); + // get the input node of this flow + var nodeInId = flow.node; + var nodeInSocketName = flow.socket; + // find the corresponding flow graph node + var nodeIn = flowGraphJsonBlocks[nodeInId]; + if (!nodeIn) { + throw new Error("/extensions/KHR_interactivity/nodes/".concat(i, ": Could not find node with id ").concat(nodeInId, " that connects its input with with node ").concat(i, "'s output ").concat(socketOutName)); + } + // in all of the flow graph input connections, find the one with the same name as the socket + var socketIn = nodeIn.signalInputs.find(function (s) { return s.name === nodeInSocketName; }); + // if the socket doesn't exist, create the input socket for the connection + if (!socketIn) { + socketIn = { + uniqueId: (0,babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__.RandomGUID)(), + name: nodeInSocketName, + _connectionType: 0 /* FlowGraphConnectionType.Input */, // Input + connectedPointIds: [], + }; + nodeIn.signalInputs.push(socketIn); + } + // connect the sockets + socketIn.connectedPointIds.push(socketOut.uniqueId); + socketOut.connectedPointIds.push(socketIn.uniqueId); + }; + // for each output flow of the gltf block + for (var _i = 0, gltfFlows_1 = gltfFlows; _i < gltfFlows_1.length; _i++) { + var flow = gltfFlows_1[_i]; + _loop_1(flow); + } + // for each input value of the gltf block + var gltfValues = (_b = gltfBlock.values) !== null && _b !== void 0 ? _b : []; + var _loop_2 = function (value) { + var socketInName = value.id; + // create an input data connection for the flow graph block + var socketIn = { + uniqueId: (0,babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__.RandomGUID)(), + name: socketInName, + _connectionType: 0 /* FlowGraphConnectionType.Input */, + connectedPointIds: [], + }; + fgBlock.dataInputs.push(socketIn); + if (value.value !== undefined) { + // if the value is set on the socket itself, store it in the context + var convertedValue = convertValueWithType(value, gltf, "/extensions/KHR_interactivity/nodes/".concat(i)); + // convertBlockInputType(gltfBlock, value, convertedValue, `/extensions/KHR_interactivity/nodes/${i}`); + context._connectionValues[socketIn.uniqueId] = convertedValue; + } + else if (value.node !== undefined && value.socket !== undefined) { + // if the value is connected with the output data of another socket, connect the two + var nodeOutId = value.node; + var nodeOutSocketName_1 = value.socket; + // find the flow graph node that owns that output socket + var nodeOut = flowGraphJsonBlocks[nodeOutId]; + if (!nodeOut) { + throw new Error("/extensions/KHR_interactivity/nodes/".concat(i, ": Could not find node with id ").concat(nodeOutId, " that connects its output with node").concat(i, "'s input ").concat(socketInName)); + } + var socketOut = nodeOut.dataOutputs.find(function (s) { return s.name === nodeOutSocketName_1; }); + // if the socket doesn't exist, create it + if (!socketOut) { + socketOut = { + uniqueId: (0,babylonjs_Misc_guid__WEBPACK_IMPORTED_MODULE_0__.RandomGUID)(), + name: nodeOutSocketName_1, + _connectionType: 1 /* FlowGraphConnectionType.Output */, + connectedPointIds: [], + }; + nodeOut.dataOutputs.push(socketOut); + } + // connect the sockets + socketIn.connectedPointIds.push(socketOut.uniqueId); + socketOut.connectedPointIds.push(socketIn.uniqueId); + } + else { + throw new Error("/extensions/KHR_interactivity/nodes/".concat(i, ": Invalid socket ").concat(socketInName, " in node ").concat(i)); + } + }; + for (var _d = 0, gltfValues_1 = gltfValues; _d < gltfValues_1.length; _d++) { + var value = gltfValues_1[_d]; + _loop_2(value); + } + } + var variables = (_c = gltf.variables) !== null && _c !== void 0 ? _c : []; + // Parse variables + for (var i = 0; i < variables.length; i++) { + var variable = variables[i]; + var variableName = variable.id; + context._userVariables[variableName] = convertValueWithType(variable, gltf, "/extensions/KHR_interactivity/variables/".concat(i)); + } + return { + allBlocks: flowGraphJsonBlocks, + executionContexts: executionContexts, + }; +} + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/interactivityPathToObjectConverter.ts": +/*!******************************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/interactivityPathToObjectConverter.ts ***! + \******************************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ InteractivityPathToObjectConverter: () => (/* binding */ InteractivityPathToObjectConverter) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var _gltfPathToObjectConverter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./gltfPathToObjectConverter */ "../../../dev/loaders/src/glTF/2.0/Extensions/gltfPathToObjectConverter.ts"); + + +/** + * Class to convert an interactivity pointer path to a smart object + */ +var InteractivityPathToObjectConverter = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__extends)(InteractivityPathToObjectConverter, _super); + function InteractivityPathToObjectConverter(gltf) { + return _super.call(this, gltf, gltfTree) || this; + } + return InteractivityPathToObjectConverter; +}(_gltfPathToObjectConverter__WEBPACK_IMPORTED_MODULE_0__.GLTFPathToObjectConverter)); + +var nodesTree = { + __array__: { + __target__: true, + translation: { + type: "Vector3", + get: function (node) { + var babylonObject = node._babylonTransformNode; + return babylonObject.position; + }, + set: function (value, node) { + var babylonObject = node._babylonTransformNode; + babylonObject.position = value; + }, + getObject: function (node) { + return node._babylonTransformNode; + }, + }, + }, +}; +var gltfTree = { + nodes: nodesTree, +}; + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/Extensions/interactivityUtils.ts": +/*!**************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/Extensions/interactivityUtils.ts ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ gltfToFlowGraphTypeMap: () => (/* binding */ gltfToFlowGraphTypeMap), +/* harmony export */ gltfTypeToBabylonType: () => (/* binding */ gltfTypeToBabylonType) +/* harmony export */ }); +/* harmony import */ var babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/FlowGraph/Blocks/Execution/ControlFlow/flowGraphWhileLoopBlock */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__); +/* eslint-disable @typescript-eslint/naming-convention */ + + + + + + + + + + + + + + +var gltfToFlowGraphTypeMap = { + "lifecycle/onStart": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSceneReadyEventBlock.ClassName, + "lifecycle/onTick": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSceneTickEventBlock.ClassName, + log: babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphConsoleLogBlock.ClassName, + "flow/delay": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphTimerBlock.ClassName, + "customEvent/send": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSendCustomEventBlock.ClassName, + "customEvent/receive": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphReceiveCustomEventBlock.ClassName, + "flow/sequence": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSequenceBlock.ClassName, + "world/get": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphGetPropertyBlock.ClassName, + "world/set": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSetPropertyBlock.ClassName, + "flow/doN": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphDoNBlock.ClassName, + "variable/get": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphGetVariableBlock.ClassName, + "variable/set": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSetVariableBlock.ClassName, + "flow/whileLoop": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphWhileLoopBlock.ClassName, + "math/random": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphRandomBlock.ClassName, + "math/e": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphEBlock.ClassName, + "math/pi": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphPiBlock.ClassName, + "math/inf": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphInfBlock.ClassName, + "math/nan": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphNaNBlock.ClassName, + "math/abs": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAbsBlock.ClassName, + "math/sign": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSignBlock.ClassName, + "math/trunc": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphTruncBlock.ClassName, + "math/floor": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphFloorBlock.ClassName, + "math/ceil": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCeilBlock.ClassName, + "math/fract": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphFractBlock.ClassName, + "math/neg": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphNegBlock.ClassName, + "math/add": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAddBlock.ClassName, + "math/sub": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSubtractBlock.ClassName, + "math/mul": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphMultiplyBlock.ClassName, + "math/div": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphDivideBlock.ClassName, + "math/rem": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphRemainderBlock.ClassName, + "math/min": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphMinBlock.ClassName, + "math/max": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphMaxBlock.ClassName, + "math/clamp": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphClampBlock.ClassName, + "math/saturate": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSaturateBlock.ClassName, + "math/mix": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphInterpolateBlock.ClassName, + "math/eq": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphEqBlock.ClassName, + "math/lt": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphLessThanBlock.ClassName, + "math/le": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphLessThanOrEqualBlock.ClassName, + "math/gt": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphGreaterThanBlock.ClassName, + "math/ge": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphGreaterThanOrEqualBlock.ClassName, + "math/isnan": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphIsNanBlock.ClassName, + "math/isinf": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphIsInfBlock.ClassName, + "math/rad": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphDegToRadBlock.ClassName, + "math/deg": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphRadToDegBlock.ClassName, + "math/sin": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSinBlock.ClassName, + "math/cos": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCosBlock.ClassName, + "math/tan": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphTanBlock.ClassName, + "math/asin": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAsinBlock.ClassName, + "math/acos": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAcosBlock.ClassName, + "math/atan": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAtanBlock.ClassName, + "math/atan2": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAtan2Block.ClassName, + "math/sinh": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSinhBlock.ClassName, + "math/cosh": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCoshBlock.ClassName, + "math/tanh": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphTanhBlock.ClassName, + "math/asinh": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAsinhBlock.ClassName, + "math/acosh": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAcoshBlock.ClassName, + "math/atanh": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphAtanhBlock.ClassName, + "math/exp": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphExpBlock.ClassName, + "math/log": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphLogBlock.ClassName, + "math/log2": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphLog2Block.ClassName, + "math/log10": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphLog10Block.ClassName, + "math/sqrt": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphSqrtBlock.ClassName, + "math/cbrt": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCubeRootBlock.ClassName, + "math/pow": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphPowBlock.ClassName, + "math/length": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphLengthBlock.ClassName, + "math/normalize": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphNormalizeBlock.ClassName, + "math/dot": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphDotBlock.ClassName, + "math/cross": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCrossBlock.ClassName, + "math/rotate2d": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphRotate2DBlock.ClassName, + "math/rotate3d": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphRotate3DBlock.ClassName, + "math/transpose": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphTransposeBlock.ClassName, + "math/determinant": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphDeterminantBlock.ClassName, + "math/inverse": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphInvertMatrixBlock.ClassName, + "math/matmul": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphMatMulBlock.ClassName, + "math/not": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphBitwiseNotBlock.ClassName, + "math/and": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphBitwiseAndBlock.ClassName, + "math/or": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphBitwiseOrBlock.ClassName, + "math/xor": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphBitwiseXorBlock.ClassName, + "math/asr": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphBitwiseRightShiftBlock.ClassName, + "math/lsl": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphBitwiseLeftShiftBlock.ClassName, + "math/clz": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCountLeadingZerosBlock.ClassName, + "math/ctz": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCountTrailingZerosBlock.ClassName, + "math/popcnt": babylonjs_FlowGraph_Blocks_Event_flowGraphSceneReadyEventBlock__WEBPACK_IMPORTED_MODULE_0__.FlowGraphCountOneBitsBlock.ClassName, +}; +var gltfTypeToBabylonType = { + float2: "Vector2", + float3: "Vector3", + float4: "Vector4", + float4x4: "Matrix", + int: "FlowGraphInteger", +}; + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts": +/*!*******************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/glTFLoader.ts ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ ArrayItem: () => (/* binding */ ArrayItem), +/* harmony export */ GLTFFileLoader: () => (/* reexport safe */ _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFFileLoader), +/* harmony export */ GLTFLoader: () => (/* binding */ GLTFLoader) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Culling/boundingInfo */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFFileLoader */ "../../../dev/loaders/src/glTF/glTFFileLoader.ts"); +/* harmony import */ var _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glTFLoaderAnimation */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderAnimation.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); + + + + + + + + + + + + + + + + + + + + + + + + + + +// https://stackoverflow.com/a/48218209 +function mergeDeep() { + var objects = []; + for (var _i = 0; _i < arguments.length; _i++) { + objects[_i] = arguments[_i]; + } + var isObject = function (obj) { return obj && typeof obj === "object"; }; + return objects.reduce(function (prev, obj) { + Object.keys(obj).forEach(function (key) { + var pVal = prev[key]; + var oVal = obj[key]; + if (Array.isArray(pVal) && Array.isArray(oVal)) { + prev[key] = pVal.concat.apply(pVal, oVal); + } + else if (isObject(pVal) && isObject(oVal)) { + prev[key] = mergeDeep(pVal, oVal); + } + else { + prev[key] = oVal; + } + }); + return prev; + }, {}); +} +/** + * Helper class for working with arrays when loading the glTF asset + */ +var ArrayItem = /** @class */ (function () { + function ArrayItem() { + } + /** + * Gets an item from the given array. + * @param context The context when loading the asset + * @param array The array to get the item from + * @param index The index to the array + * @returns The array item + */ + ArrayItem.Get = function (context, array, index) { + if (!array || index == undefined || !array[index]) { + throw new Error("".concat(context, ": Failed to find index (").concat(index, ")")); + } + return array[index]; + }; + /** + * Gets an item from the given array or returns null if not available. + * @param array The array to get the item from + * @param index The index to the array + * @returns The array item or null + */ + ArrayItem.TryGet = function (array, index) { + if (!array || index == undefined || !array[index]) { + return null; + } + return array[index]; + }; + /** + * Assign an `index` field to each item of the given array. + * @param array The array of items + */ + ArrayItem.Assign = function (array) { + if (array) { + for (var index = 0; index < array.length; index++) { + array[index].index = index; + } + } + }; + return ArrayItem; +}()); + +/** + * The glTF 2.0 loader + */ +var GLTFLoader = /** @class */ (function () { + /** + * @internal + */ + function GLTFLoader(parent) { + /** @internal */ + this._completePromises = new Array(); + /** @internal */ + this._assetContainer = null; + /** Storage */ + this._babylonLights = []; + /** @internal */ + this._disableInstancedMesh = 0; + /** @internal */ + this._allMaterialsDirtyRequired = false; + this._extensions = new Array(); + this._disposed = false; + this._rootUrl = null; + this._fileName = null; + this._uniqueRootUrl = null; + this._bin = null; + this._rootBabylonMesh = null; + this._defaultBabylonMaterialData = {}; + this._postSceneLoadActions = new Array(); + this._parent = parent; + } + /** + * Registers a loader extension. + * @param name The name of the loader extension. + * @param factory The factory function that creates the loader extension. + * @deprecated Please use registerGLTFExtension instead. + */ + GLTFLoader.RegisterExtension = function (name, factory) { + (0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.registerGLTFExtension)(name, false, factory); + }; + /** + * Unregisters a loader extension. + * @param name The name of the loader extension. + * @returns A boolean indicating whether the extension has been unregistered + * @deprecated Please use unregisterGLTFExtension instead. + */ + GLTFLoader.UnregisterExtension = function (name) { + return (0,_glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.unregisterGLTFExtension)(name); + }; + Object.defineProperty(GLTFLoader.prototype, "gltf", { + /** + * The object that represents the glTF JSON. + */ + get: function () { + if (!this._gltf) { + throw new Error("glTF JSON is not available"); + } + return this._gltf; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFLoader.prototype, "bin", { + /** + * The BIN chunk of a binary glTF. + */ + get: function () { + return this._bin; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFLoader.prototype, "parent", { + /** + * The parent file loader. + */ + get: function () { + return this._parent; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFLoader.prototype, "babylonScene", { + /** + * The Babylon scene when loading the asset. + */ + get: function () { + if (!this._babylonScene) { + throw new Error("Scene is not available"); + } + return this._babylonScene; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFLoader.prototype, "rootBabylonMesh", { + /** + * The root Babylon node when loading the asset. + */ + get: function () { + return this._rootBabylonMesh; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFLoader.prototype, "rootUrl", { + /** + * The root url when loading the asset. + */ + get: function () { + return this._rootUrl; + }, + enumerable: false, + configurable: true + }); + /** @internal */ + GLTFLoader.prototype.dispose = function () { + if (this._disposed) { + return; + } + this._disposed = true; + this._completePromises.length = 0; + this._extensions.forEach(function (extension) { return extension.dispose && extension.dispose(); }); + this._extensions.length = 0; + this._gltf = null; // TODO + this._bin = null; + this._babylonScene = null; // TODO + this._rootBabylonMesh = null; + this._defaultBabylonMaterialData = {}; + this._postSceneLoadActions.length = 0; + this._parent.dispose(); + }; + /** + * @internal + */ + GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, container, data, rootUrl, onProgress, fileName) { + var _this = this; + if (fileName === void 0) { fileName = ""; } + return Promise.resolve().then(function () { + _this._babylonScene = scene; + _this._assetContainer = container; + _this._loadData(data); + var nodes = null; + if (meshesNames) { + var nodeMap_1 = {}; + if (_this._gltf.nodes) { + for (var _i = 0, _a = _this._gltf.nodes; _i < _a.length; _i++) { + var node = _a[_i]; + if (node.name) { + nodeMap_1[node.name] = node.index; + } + } + } + var names = meshesNames instanceof Array ? meshesNames : [meshesNames]; + nodes = names.map(function (name) { + var node = nodeMap_1[name]; + if (node === undefined) { + throw new Error("Failed to find node '".concat(name, "'")); + } + return node; + }); + } + return _this._loadAsync(rootUrl, fileName, nodes, function () { + return { + meshes: _this._getMeshes(), + particleSystems: [], + skeletons: _this._getSkeletons(), + animationGroups: _this._getAnimationGroups(), + lights: _this._babylonLights, + transformNodes: _this._getTransformNodes(), + geometries: _this._getGeometries(), + spriteManagers: [], + }; + }); + }); + }; + /** + * @internal + */ + GLTFLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress, fileName) { + var _this = this; + if (fileName === void 0) { fileName = ""; } + return Promise.resolve().then(function () { + _this._babylonScene = scene; + _this._loadData(data); + return _this._loadAsync(rootUrl, fileName, null, function () { return undefined; }); + }); + }; + GLTFLoader.prototype._loadAsync = function (rootUrl, fileName, nodes, resultFunc) { + var _this = this; + return Promise.resolve() + .then(function () { return (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__awaiter)(_this, void 0, void 0, function () { + var loadingToReadyCounterName, loadingToCompleteCounterName, promises, oldBlockMaterialDirtyMechanism, scene, m, material, context_1, babylonDrawMode, resultPromise; + var _this = this; + return (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__generator)(this, function (_a) { + switch (_a.label) { + case 0: + this._rootUrl = rootUrl; + this._uniqueRootUrl = !rootUrl.startsWith("file:") && fileName ? rootUrl : "".concat(rootUrl).concat(Date.now(), "/"); + this._fileName = fileName; + this._allMaterialsDirtyRequired = false; + return [4 /*yield*/, this._loadExtensionsAsync()]; + case 1: + _a.sent(); + loadingToReadyCounterName = "".concat(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState[_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.LOADING], " => ").concat(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState[_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.READY]); + loadingToCompleteCounterName = "".concat(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState[_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.LOADING], " => ").concat(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState[_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.COMPLETE]); + this._parent._startPerformanceCounter(loadingToReadyCounterName); + this._parent._startPerformanceCounter(loadingToCompleteCounterName); + this._parent._setState(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.LOADING); + this._extensionsOnLoading(); + promises = new Array(); + oldBlockMaterialDirtyMechanism = this._babylonScene.blockMaterialDirtyMechanism; + this._babylonScene.blockMaterialDirtyMechanism = true; + if (!this.parent.loadOnlyMaterials) { + if (nodes) { + promises.push(this.loadSceneAsync("/nodes", { nodes: nodes, index: -1 })); + } + else if (this._gltf.scene != undefined || (this._gltf.scenes && this._gltf.scenes[0])) { + scene = ArrayItem.Get("/scene", this._gltf.scenes, this._gltf.scene || 0); + promises.push(this.loadSceneAsync("/scenes/".concat(scene.index), scene)); + } + } + if (!this.parent.skipMaterials && this.parent.loadAllMaterials && this._gltf.materials) { + for (m = 0; m < this._gltf.materials.length; ++m) { + material = this._gltf.materials[m]; + context_1 = "/materials/" + m; + babylonDrawMode = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleFillMode; + promises.push(this._loadMaterialAsync(context_1, material, null, babylonDrawMode, function () { })); + } + } + // Restore the blocking of material dirty. + if (this._allMaterialsDirtyRequired) { + // This can happen if we add a light for instance as it will impact the whole scene. + // This automatically resets everything if needed. + this._babylonScene.blockMaterialDirtyMechanism = oldBlockMaterialDirtyMechanism; + } + else { + // By default a newly created material is dirty so there is no need to flag the full scene as dirty. + // For perf reasons, we then bypass blockMaterialDirtyMechanism as this would "dirty" the entire scene. + this._babylonScene._forceBlockMaterialDirtyMechanism(oldBlockMaterialDirtyMechanism); + } + if (this._parent.compileMaterials) { + promises.push(this._compileMaterialsAsync()); + } + if (this._parent.compileShadowGenerators) { + promises.push(this._compileShadowGeneratorsAsync()); + } + resultPromise = Promise.all(promises).then(function () { + if (_this._rootBabylonMesh && _this._rootBabylonMesh !== _this._parent.customRootNode) { + _this._rootBabylonMesh.setEnabled(true); + } + _this._extensionsOnReady(); + _this._parent._setState(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.READY); + _this._startAnimations(); + return resultFunc(); + }); + return [2 /*return*/, resultPromise.then(function (result) { + _this._parent._endPerformanceCounter(loadingToReadyCounterName); + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Tools.SetImmediate(function () { + if (!_this._disposed) { + Promise.all(_this._completePromises).then(function () { + _this._parent._endPerformanceCounter(loadingToCompleteCounterName); + _this._parent._setState(_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderState.COMPLETE); + _this._parent.onCompleteObservable.notifyObservers(undefined); + _this._parent.onCompleteObservable.clear(); + _this.dispose(); + }, function (error) { + _this._parent.onErrorObservable.notifyObservers(error); + _this._parent.onErrorObservable.clear(); + _this.dispose(); + }); + } + }); + return result; + })]; + } + }); + }); }) + .catch(function (error) { + if (!_this._disposed) { + _this._parent.onErrorObservable.notifyObservers(error); + _this._parent.onErrorObservable.clear(); + _this.dispose(); + } + throw error; + }); + }; + GLTFLoader.prototype._loadData = function (data) { + this._gltf = data.json; + this._setupData(); + if (data.bin) { + var buffers = this._gltf.buffers; + if (buffers && buffers[0] && !buffers[0].uri) { + var binaryBuffer = buffers[0]; + if (binaryBuffer.byteLength < data.bin.byteLength - 3 || binaryBuffer.byteLength > data.bin.byteLength) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("Binary buffer length (".concat(binaryBuffer.byteLength, ") from JSON does not match chunk length (").concat(data.bin.byteLength, ")")); + } + this._bin = data.bin; + } + else { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("Unexpected BIN chunk"); + } + } + }; + GLTFLoader.prototype._setupData = function () { + ArrayItem.Assign(this._gltf.accessors); + ArrayItem.Assign(this._gltf.animations); + ArrayItem.Assign(this._gltf.buffers); + ArrayItem.Assign(this._gltf.bufferViews); + ArrayItem.Assign(this._gltf.cameras); + ArrayItem.Assign(this._gltf.images); + ArrayItem.Assign(this._gltf.materials); + ArrayItem.Assign(this._gltf.meshes); + ArrayItem.Assign(this._gltf.nodes); + ArrayItem.Assign(this._gltf.samplers); + ArrayItem.Assign(this._gltf.scenes); + ArrayItem.Assign(this._gltf.skins); + ArrayItem.Assign(this._gltf.textures); + if (this._gltf.nodes) { + var nodeParents = {}; + for (var _i = 0, _a = this._gltf.nodes; _i < _a.length; _i++) { + var node = _a[_i]; + if (node.children) { + for (var _b = 0, _c = node.children; _b < _c.length; _b++) { + var index = _c[_b]; + nodeParents[index] = node.index; + } + } + } + var rootNode = this._createRootNode(); + for (var _d = 0, _e = this._gltf.nodes; _d < _e.length; _d++) { + var node = _e[_d]; + var parentIndex = nodeParents[node.index]; + node.parent = parentIndex === undefined ? rootNode : this._gltf.nodes[parentIndex]; + } + } + }; + GLTFLoader.prototype._loadExtensionsAsync = function () { + return (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__awaiter)(this, void 0, void 0, function () { + var extensionPromises, _a, _b, _c, _loop_1, this_1, _i, _d, name_1; + var _e; + var _this = this; + var _f; + return (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__generator)(this, function (_g) { + switch (_g.label) { + case 0: + extensionPromises = []; + _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_3__.registeredGLTFExtensions.forEach(function (registeredExtension, name) { + var _a; + // Don't load explicitly disabled extensions. + if (((_a = _this.parent.extensionOptions[name]) === null || _a === void 0 ? void 0 : _a.enabled) === false) { + // But warn if the disabled extension is used by the model. + if (registeredExtension.isGLTFExtension && _this.isExtensionUsed(name)) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("Extension ".concat(name, " is used but has been explicitly disabled.")); + } + } + // Load loader extensions that are not a glTF extension, as well as extensions that are glTF extensions and are used by the model. + else if (!registeredExtension.isGLTFExtension || _this.isExtensionUsed(name)) { + extensionPromises.push((function () { return (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__awaiter)(_this, void 0, void 0, function () { + var extension; + return (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__generator)(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, registeredExtension.factory(this)]; + case 1: + extension = _a.sent(); + if (extension.name !== name) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("The name of the glTF loader extension instance does not match the registered name: ".concat(extension.name, " !== ").concat(name)); + } + this._parent.onExtensionLoadedObservable.notifyObservers(extension); + return [2 /*return*/, extension]; + } + }); + }); })()); + } + }); + _b = (_a = (_e = this._extensions).push).apply; + _c = [_e]; + return [4 /*yield*/, Promise.all(extensionPromises)]; + case 1: + _b.apply(_a, _c.concat([(_g.sent())])); + this._extensions.sort(function (a, b) { return (a.order || Number.MAX_VALUE) - (b.order || Number.MAX_VALUE); }); + this._parent.onExtensionLoadedObservable.clear(); + if (this._gltf.extensionsRequired) { + _loop_1 = function (name_1) { + var available = this_1._extensions.some(function (extension) { return extension.name === name_1 && extension.enabled; }); + if (!available) { + if (((_f = this_1.parent.extensionOptions[name_1]) === null || _f === void 0 ? void 0 : _f.enabled) === false) { + throw new Error("Required extension ".concat(name_1, " is disabled")); + } + throw new Error("Required extension ".concat(name_1, " is not available")); + } + }; + this_1 = this; + for (_i = 0, _d = this._gltf.extensionsRequired; _i < _d.length; _i++) { + name_1 = _d[_i]; + _loop_1(name_1); + } + } + return [2 /*return*/]; + } + }); + }); + }; + GLTFLoader.prototype._createRootNode = function () { + if (this._parent.customRootNode !== undefined) { + this._rootBabylonMesh = this._parent.customRootNode; + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + _babylonTransformNode: this._rootBabylonMesh === null ? undefined : this._rootBabylonMesh, + index: -1, + }; + } + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var rootMesh = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Mesh("__root__", this._babylonScene); + this._rootBabylonMesh = rootMesh; + this._rootBabylonMesh._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + this._rootBabylonMesh.setEnabled(false); + var rootNode = { + // eslint-disable-next-line @typescript-eslint/naming-convention + _babylonTransformNode: this._rootBabylonMesh, + index: -1, + }; + switch (this._parent.coordinateSystemMode) { + case _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderCoordinateSystemMode.AUTO: { + if (!this._babylonScene.useRightHandedSystem) { + rootNode.rotation = [0, 1, 0, 0]; + rootNode.scale = [1, 1, -1]; + GLTFLoader._LoadTransform(rootNode, this._rootBabylonMesh); + } + break; + } + case _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderCoordinateSystemMode.FORCE_RIGHT_HANDED: { + this._babylonScene.useRightHandedSystem = true; + break; + } + default: { + throw new Error("Invalid coordinate system mode (".concat(this._parent.coordinateSystemMode, ")")); + } + } + this._parent.onMeshLoadedObservable.notifyObservers(rootMesh); + return rootNode; + }; + /** + * Loads a glTF scene. + * @param context The context when loading the asset + * @param scene The glTF scene property + * @returns A promise that resolves when the load is complete + */ + GLTFLoader.prototype.loadSceneAsync = function (context, scene) { + var _this = this; + var extensionPromise = this._extensionsLoadSceneAsync(context, scene); + if (extensionPromise) { + return extensionPromise; + } + var promises = new Array(); + this.logOpen("".concat(context, " ").concat(scene.name || "")); + if (scene.nodes) { + for (var _i = 0, _a = scene.nodes; _i < _a.length; _i++) { + var index = _a[_i]; + var node = ArrayItem.Get("".concat(context, "/nodes/").concat(index), this._gltf.nodes, index); + promises.push(this.loadNodeAsync("/nodes/".concat(node.index), node, function (babylonMesh) { + babylonMesh.parent = _this._rootBabylonMesh; + })); + } + } + for (var _b = 0, _c = this._postSceneLoadActions; _b < _c.length; _b++) { + var action = _c[_b]; + action(); + } + promises.push(this._loadAnimationsAsync()); + this.logClose(); + return Promise.all(promises).then(function () { }); + }; + GLTFLoader.prototype._forEachPrimitive = function (node, callback) { + if (node._primitiveBabylonMeshes) { + for (var _i = 0, _a = node._primitiveBabylonMeshes; _i < _a.length; _i++) { + var babylonMesh = _a[_i]; + callback(babylonMesh); + } + } + }; + GLTFLoader.prototype._getGeometries = function () { + var geometries = []; + var nodes = this._gltf.nodes; + if (nodes) { + for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) { + var node = nodes_1[_i]; + this._forEachPrimitive(node, function (babylonMesh) { + var geometry = babylonMesh.geometry; + if (geometry && geometries.indexOf(geometry) === -1) { + geometries.push(geometry); + } + }); + } + } + return geometries; + }; + GLTFLoader.prototype._getMeshes = function () { + var meshes = []; + // Root mesh is always first, if available. + if (this._rootBabylonMesh instanceof babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.AbstractMesh) { + meshes.push(this._rootBabylonMesh); + } + var nodes = this._gltf.nodes; + if (nodes) { + for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) { + var node = nodes_2[_i]; + this._forEachPrimitive(node, function (babylonMesh) { + meshes.push(babylonMesh); + }); + } + } + return meshes; + }; + GLTFLoader.prototype._getTransformNodes = function () { + var transformNodes = []; + var nodes = this._gltf.nodes; + if (nodes) { + for (var _i = 0, nodes_3 = nodes; _i < nodes_3.length; _i++) { + var node = nodes_3[_i]; + if (node._babylonTransformNode && node._babylonTransformNode.getClassName() === "TransformNode") { + transformNodes.push(node._babylonTransformNode); + } + if (node._babylonTransformNodeForSkin) { + transformNodes.push(node._babylonTransformNodeForSkin); + } + } + } + return transformNodes; + }; + GLTFLoader.prototype._getSkeletons = function () { + var skeletons = []; + var skins = this._gltf.skins; + if (skins) { + for (var _i = 0, skins_1 = skins; _i < skins_1.length; _i++) { + var skin = skins_1[_i]; + if (skin._data) { + skeletons.push(skin._data.babylonSkeleton); + } + } + } + return skeletons; + }; + GLTFLoader.prototype._getAnimationGroups = function () { + var animationGroups = []; + var animations = this._gltf.animations; + if (animations) { + for (var _i = 0, animations_1 = animations; _i < animations_1.length; _i++) { + var animation = animations_1[_i]; + if (animation._babylonAnimationGroup) { + animationGroups.push(animation._babylonAnimationGroup); + } + } + } + return animationGroups; + }; + GLTFLoader.prototype._startAnimations = function () { + switch (this._parent.animationStartMode) { + case _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderAnimationStartMode.NONE: { + // do nothing + break; + } + case _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderAnimationStartMode.FIRST: { + var babylonAnimationGroups = this._getAnimationGroups(); + if (babylonAnimationGroups.length !== 0) { + babylonAnimationGroups[0].start(true); + } + break; + } + case _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFLoaderAnimationStartMode.ALL: { + var babylonAnimationGroups = this._getAnimationGroups(); + for (var _i = 0, babylonAnimationGroups_1 = babylonAnimationGroups; _i < babylonAnimationGroups_1.length; _i++) { + var babylonAnimationGroup = babylonAnimationGroups_1[_i]; + babylonAnimationGroup.start(true); + } + break; + } + default: { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Error("Invalid animation start mode (".concat(this._parent.animationStartMode, ")")); + return; + } + } + }; + /** + * Loads a glTF node. + * @param context The context when loading the asset + * @param node The glTF node property + * @param assign A function called synchronously after parsing the glTF properties + * @returns A promise that resolves with the loaded Babylon mesh when the load is complete + */ + GLTFLoader.prototype.loadNodeAsync = function (context, node, assign) { + var _this = this; + if (assign === void 0) { assign = function () { }; } + var extensionPromise = this._extensionsLoadNodeAsync(context, node, assign); + if (extensionPromise) { + return extensionPromise; + } + if (node._babylonTransformNode) { + throw new Error("".concat(context, ": Invalid recursive node hierarchy")); + } + var promises = new Array(); + this.logOpen("".concat(context, " ").concat(node.name || "")); + var loadNode = function (babylonTransformNode) { + GLTFLoader.AddPointerMetadata(babylonTransformNode, context); + GLTFLoader._LoadTransform(node, babylonTransformNode); + if (node.camera != undefined) { + var camera = ArrayItem.Get("".concat(context, "/camera"), _this._gltf.cameras, node.camera); + promises.push(_this.loadCameraAsync("/cameras/".concat(camera.index), camera, function (babylonCamera) { + babylonCamera.parent = babylonTransformNode; + })); + } + if (node.children) { + for (var _i = 0, _a = node.children; _i < _a.length; _i++) { + var index = _a[_i]; + var childNode = ArrayItem.Get("".concat(context, "/children/").concat(index), _this._gltf.nodes, index); + promises.push(_this.loadNodeAsync("/nodes/".concat(childNode.index), childNode, function (childBabylonMesh) { + childBabylonMesh.parent = babylonTransformNode; + })); + } + } + assign(babylonTransformNode); + }; + var hasMesh = node.mesh != undefined; + var hasSkin = this._parent.loadSkins && node.skin != undefined; + if (!hasMesh || hasSkin) { + var nodeName = node.name || "node".concat(node.index); + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var transformNode = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.TransformNode(nodeName, this._babylonScene); + transformNode._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + if (node.mesh == undefined) { + node._babylonTransformNode = transformNode; + } + else { + node._babylonTransformNodeForSkin = transformNode; + } + loadNode(transformNode); + } + if (hasMesh) { + if (hasSkin) { + // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note) + // This code path will place the skinned mesh as a sibling of the skeleton root node without loading the + // transform, which effectively ignores the transform of the skinned mesh, as per spec. + var mesh = ArrayItem.Get("".concat(context, "/mesh"), this._gltf.meshes, node.mesh); + promises.push(this._loadMeshAsync("/meshes/".concat(mesh.index), node, mesh, function (babylonTransformNode) { + var babylonTransformNodeForSkin = node._babylonTransformNodeForSkin; + // Merge the metadata from the skin node to the skinned mesh in case a loader extension added metadata. + babylonTransformNode.metadata = mergeDeep(babylonTransformNodeForSkin.metadata, babylonTransformNode.metadata || {}); + var skin = ArrayItem.Get("".concat(context, "/skin"), _this._gltf.skins, node.skin); + promises.push(_this._loadSkinAsync("/skins/".concat(skin.index), node, skin, function (babylonSkeleton) { + _this._forEachPrimitive(node, function (babylonMesh) { + babylonMesh.skeleton = babylonSkeleton; + }); + // Wait until all the nodes are parented before parenting the skinned mesh. + _this._postSceneLoadActions.push(function () { + if (skin.skeleton != undefined) { + // Place the skinned mesh node as a sibling of the skeleton root node. + // Handle special case when the parent of the skeleton root is the skinned mesh. + var parentNode = ArrayItem.Get("/skins/".concat(skin.index, "/skeleton"), _this._gltf.nodes, skin.skeleton).parent; + if (node.index === parentNode.index) { + babylonTransformNode.parent = babylonTransformNodeForSkin.parent; + } + else { + babylonTransformNode.parent = parentNode._babylonTransformNode; + } + } + else { + babylonTransformNode.parent = _this._rootBabylonMesh; + } + _this._parent.onSkinLoadedObservable.notifyObservers({ node: babylonTransformNodeForSkin, skinnedNode: babylonTransformNode }); + }); + })); + })); + } + else { + var mesh = ArrayItem.Get("".concat(context, "/mesh"), this._gltf.meshes, node.mesh); + promises.push(this._loadMeshAsync("/meshes/".concat(mesh.index), node, mesh, loadNode)); + } + } + this.logClose(); + return Promise.all(promises).then(function () { + _this._forEachPrimitive(node, function (babylonMesh) { + if (babylonMesh.geometry && babylonMesh.geometry.useBoundingInfoFromGeometry) { + // simply apply the world matrices to the bounding info - the extends are already ok + babylonMesh._updateBoundingInfo(); + } + else { + babylonMesh.refreshBoundingInfo(true, true); + } + }); + return node._babylonTransformNode; + }); + }; + GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh, assign) { + var primitives = mesh.primitives; + if (!primitives || !primitives.length) { + throw new Error("".concat(context, ": Primitives are missing")); + } + if (primitives[0].index == undefined) { + ArrayItem.Assign(primitives); + } + var promises = new Array(); + this.logOpen("".concat(context, " ").concat(mesh.name || "")); + var name = node.name || "node".concat(node.index); + if (primitives.length === 1) { + var primitive = mesh.primitives[0]; + promises.push(this._loadMeshPrimitiveAsync("".concat(context, "/primitives/").concat(primitive.index), name, node, mesh, primitive, function (babylonMesh) { + node._babylonTransformNode = babylonMesh; + node._primitiveBabylonMeshes = [babylonMesh]; + })); + } + else { + this._babylonScene._blockEntityCollection = !!this._assetContainer; + node._babylonTransformNode = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.TransformNode(name, this._babylonScene); + node._babylonTransformNode._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + node._primitiveBabylonMeshes = []; + for (var _i = 0, primitives_1 = primitives; _i < primitives_1.length; _i++) { + var primitive = primitives_1[_i]; + promises.push(this._loadMeshPrimitiveAsync("".concat(context, "/primitives/").concat(primitive.index), "".concat(name, "_primitive").concat(primitive.index), node, mesh, primitive, function (babylonMesh) { + babylonMesh.parent = node._babylonTransformNode; + node._primitiveBabylonMeshes.push(babylonMesh); + })); + } + } + assign(node._babylonTransformNode); + this.logClose(); + return Promise.all(promises).then(function () { + return node._babylonTransformNode; + }); + }; + /** + * @internal Define this method to modify the default behavior when loading data for mesh primitives. + * @param context The context when loading the asset + * @param name The mesh name when loading the asset + * @param node The glTF node when loading the asset + * @param mesh The glTF mesh when loading the asset + * @param primitive The glTF mesh primitive property + * @param assign A function called synchronously after parsing the glTF properties + * @returns A promise that resolves with the loaded mesh when the load is complete or null if not handled + */ + GLTFLoader.prototype._loadMeshPrimitiveAsync = function (context, name, node, mesh, primitive, assign) { + var _this = this; + var extensionPromise = this._extensionsLoadMeshPrimitiveAsync(context, name, node, mesh, primitive, assign); + if (extensionPromise) { + return extensionPromise; + } + this.logOpen("".concat(context)); + var shouldInstance = this._disableInstancedMesh === 0 && this._parent.createInstances && node.skin == undefined && !mesh.primitives[0].targets; + var babylonAbstractMesh; + var promise; + if (shouldInstance && primitive._instanceData) { + this._babylonScene._blockEntityCollection = !!this._assetContainer; + babylonAbstractMesh = primitive._instanceData.babylonSourceMesh.createInstance(name); + babylonAbstractMesh._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + promise = primitive._instanceData.promise; + } + else { + var promises = new Array(); + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var babylonMesh_1 = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Mesh(name, this._babylonScene); + babylonMesh_1._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + babylonMesh_1.sideOrientation = this._babylonScene.useRightHandedSystem ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.CounterClockWiseSideOrientation : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.ClockWiseSideOrientation; + this._createMorphTargets(context, node, mesh, primitive, babylonMesh_1); + promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh_1).then(function (babylonGeometry) { + return _this._loadMorphTargetsAsync(context, primitive, babylonMesh_1, babylonGeometry).then(function () { + if (_this._disposed) { + return; + } + _this._babylonScene._blockEntityCollection = !!_this._assetContainer; + babylonGeometry.applyToMesh(babylonMesh_1); + babylonGeometry._parentContainer = _this._assetContainer; + _this._babylonScene._blockEntityCollection = false; + }); + })); + var babylonDrawMode = GLTFLoader._GetDrawMode(context, primitive.mode); + if (primitive.material == undefined) { + var babylonMaterial = this._defaultBabylonMaterialData[babylonDrawMode]; + if (!babylonMaterial) { + babylonMaterial = this._createDefaultMaterial("__GLTFLoader._default", babylonDrawMode); + this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial); + this._defaultBabylonMaterialData[babylonDrawMode] = babylonMaterial; + } + babylonMesh_1.material = babylonMaterial; + } + else if (!this.parent.skipMaterials) { + var material = ArrayItem.Get("".concat(context, "/material"), this._gltf.materials, primitive.material); + promises.push(this._loadMaterialAsync("/materials/".concat(material.index), material, babylonMesh_1, babylonDrawMode, function (babylonMaterial) { + babylonMesh_1.material = babylonMaterial; + })); + } + promise = Promise.all(promises); + if (shouldInstance) { + primitive._instanceData = { + babylonSourceMesh: babylonMesh_1, + promise: promise, + }; + } + babylonAbstractMesh = babylonMesh_1; + } + GLTFLoader.AddPointerMetadata(babylonAbstractMesh, context); + this._parent.onMeshLoadedObservable.notifyObservers(babylonAbstractMesh); + assign(babylonAbstractMesh); + this.logClose(); + return promise.then(function () { + return babylonAbstractMesh; + }); + }; + GLTFLoader.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) { + var _this = this; + var extensionPromise = this._extensionsLoadVertexDataAsync(context, primitive, babylonMesh); + if (extensionPromise) { + return extensionPromise; + } + var attributes = primitive.attributes; + if (!attributes) { + throw new Error("".concat(context, ": Attributes are missing")); + } + var promises = new Array(); + var babylonGeometry = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Geometry(babylonMesh.name, this._babylonScene); + if (primitive.indices == undefined) { + babylonMesh.isUnIndexed = true; + } + else { + var accessor = ArrayItem.Get("".concat(context, "/indices"), this._gltf.accessors, primitive.indices); + promises.push(this._loadIndicesAccessorAsync("/accessors/".concat(accessor.index), accessor).then(function (data) { + babylonGeometry.setIndices(data); + })); + } + var loadAttribute = function (name, kind, callback) { + if (attributes[name] == undefined) { + return; + } + babylonMesh._delayInfo = babylonMesh._delayInfo || []; + if (babylonMesh._delayInfo.indexOf(kind) === -1) { + babylonMesh._delayInfo.push(kind); + } + var accessor = ArrayItem.Get("".concat(context, "/attributes/").concat(name), _this._gltf.accessors, attributes[name]); + promises.push(_this._loadVertexAccessorAsync("/accessors/".concat(accessor.index), accessor, kind).then(function (babylonVertexBuffer) { + var _a, _b; + if (babylonVertexBuffer.getKind() === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind && !_this.parent.alwaysComputeBoundingBox && !babylonMesh.skeleton) { + if (accessor.min && accessor.max) { + var min = (_a = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[0]).copyFromFloats.apply(_a, accessor.min); + var max = (_b = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.TmpVectors.Vector3[1]).copyFromFloats.apply(_b, accessor.max); + if (accessor.normalized && accessor.componentType !== 5126 /* AccessorComponentType.FLOAT */) { + var divider = 1; + switch (accessor.componentType) { + case 5120 /* AccessorComponentType.BYTE */: + divider = 127.0; + break; + case 5121 /* AccessorComponentType.UNSIGNED_BYTE */: + divider = 255.0; + break; + case 5122 /* AccessorComponentType.SHORT */: + divider = 32767.0; + break; + case 5123 /* AccessorComponentType.UNSIGNED_SHORT */: + divider = 65535.0; + break; + } + var oneOverDivider = 1 / divider; + min.scaleInPlace(oneOverDivider); + max.scaleInPlace(oneOverDivider); + } + babylonGeometry._boundingInfo = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.BoundingInfo(min, max); + babylonGeometry.useBoundingInfoFromGeometry = true; + } + } + babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count); + })); + if (kind == babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesExtraKind) { + babylonMesh.numBoneInfluencers = 8; + } + if (callback) { + callback(accessor); + } + }; + loadAttribute("POSITION", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind); + loadAttribute("NORMAL", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind); + loadAttribute("TANGENT", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind); + loadAttribute("TEXCOORD_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UVKind); + loadAttribute("TEXCOORD_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV2Kind); + loadAttribute("TEXCOORD_2", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV3Kind); + loadAttribute("TEXCOORD_3", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV4Kind); + loadAttribute("TEXCOORD_4", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV5Kind); + loadAttribute("TEXCOORD_5", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.UV6Kind); + loadAttribute("JOINTS_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesKind); + loadAttribute("WEIGHTS_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesWeightsKind); + loadAttribute("JOINTS_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesIndicesExtraKind); + loadAttribute("WEIGHTS_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.MatricesWeightsExtraKind); + loadAttribute("COLOR_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ColorKind, function (accessor) { + if (accessor.type === "VEC4" /* AccessorType.VEC4 */) { + babylonMesh.hasVertexAlpha = true; + } + }); + return Promise.all(promises).then(function () { + return babylonGeometry; + }); + }; + GLTFLoader.prototype._createMorphTargets = function (context, node, mesh, primitive, babylonMesh) { + if (!primitive.targets || !this._parent.loadMorphTargets) { + return; + } + if (node._numMorphTargets == undefined) { + node._numMorphTargets = primitive.targets.length; + } + else if (primitive.targets.length !== node._numMorphTargets) { + throw new Error("".concat(context, ": Primitives do not have the same number of targets")); + } + var targetNames = mesh.extras ? mesh.extras.targetNames : null; + this._babylonScene._blockEntityCollection = !!this._assetContainer; + babylonMesh.morphTargetManager = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.MorphTargetManager(this._babylonScene); + babylonMesh.morphTargetManager._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + babylonMesh.morphTargetManager.areUpdatesFrozen = true; + for (var index = 0; index < primitive.targets.length; index++) { + var weight = node.weights ? node.weights[index] : mesh.weights ? mesh.weights[index] : 0; + var name_2 = targetNames ? targetNames[index] : "morphTarget".concat(index); + babylonMesh.morphTargetManager.addTarget(new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.MorphTarget(name_2, weight, babylonMesh.getScene())); + // TODO: tell the target whether it has positions, normals, tangents + } + }; + GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonGeometry) { + if (!primitive.targets || !this._parent.loadMorphTargets) { + return Promise.resolve(); + } + var promises = new Array(); + var morphTargetManager = babylonMesh.morphTargetManager; + for (var index = 0; index < morphTargetManager.numTargets; index++) { + var babylonMorphTarget = morphTargetManager.getTarget(index); + promises.push(this._loadMorphTargetVertexDataAsync("".concat(context, "/targets/").concat(index), babylonGeometry, primitive.targets[index], babylonMorphTarget)); + } + return Promise.all(promises).then(function () { + morphTargetManager.areUpdatesFrozen = false; + }); + }; + GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonGeometry, attributes, babylonMorphTarget) { + var _this = this; + var promises = new Array(); + var loadAttribute = function (attribute, kind, setData) { + if (attributes[attribute] == undefined) { + return; + } + var babylonVertexBuffer = babylonGeometry.getVertexBuffer(kind); + if (!babylonVertexBuffer) { + return; + } + var accessor = ArrayItem.Get("".concat(context, "/").concat(attribute), _this._gltf.accessors, attributes[attribute]); + promises.push(_this._loadFloatAccessorAsync("/accessors/".concat(accessor.index), accessor).then(function (data) { + setData(babylonVertexBuffer, data); + })); + }; + loadAttribute("POSITION", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.PositionKind, function (babylonVertexBuffer, data) { + var positions = new Float32Array(data.length); + babylonVertexBuffer.forEach(data.length, function (value, index) { + positions[index] = data[index] + value; + }); + babylonMorphTarget.setPositions(positions); + }); + loadAttribute("NORMAL", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.NormalKind, function (babylonVertexBuffer, data) { + var normals = new Float32Array(data.length); + babylonVertexBuffer.forEach(normals.length, function (value, index) { + normals[index] = data[index] + value; + }); + babylonMorphTarget.setNormals(normals); + }); + loadAttribute("TANGENT", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.TangentKind, function (babylonVertexBuffer, data) { + var tangents = new Float32Array((data.length / 3) * 4); + var dataIndex = 0; + babylonVertexBuffer.forEach((data.length / 3) * 4, function (value, index) { + // Tangent data for morph targets is stored as xyz delta. + // The vertexData.tangent is stored as xyzw. + // So we need to skip every fourth vertexData.tangent. + if ((index + 1) % 4 !== 0) { + tangents[dataIndex] = data[dataIndex] + value; + dataIndex++; + } + }); + babylonMorphTarget.setTangents(tangents); + }); + return Promise.all(promises).then(function () { }); + }; + GLTFLoader._LoadTransform = function (node, babylonNode) { + // Ignore the TRS of skinned nodes. + // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note) + if (node.skin != undefined) { + return; + } + var position = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero(); + var rotation = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity(); + var scaling = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.One(); + if (node.matrix) { + var matrix = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Matrix.FromArray(node.matrix); + matrix.decompose(scaling, rotation, position); + } + else { + if (node.translation) { + position = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(node.translation); + } + if (node.rotation) { + rotation = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArray(node.rotation); + } + if (node.scale) { + scaling = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(node.scale); + } + } + babylonNode.position = position; + babylonNode.rotationQuaternion = rotation; + babylonNode.scaling = scaling; + }; + GLTFLoader.prototype._loadSkinAsync = function (context, node, skin, assign) { + var _this = this; + if (!this._parent.loadSkins) { + return Promise.resolve(); + } + var extensionPromise = this._extensionsLoadSkinAsync(context, node, skin); + if (extensionPromise) { + return extensionPromise; + } + if (skin._data) { + assign(skin._data.babylonSkeleton); + return skin._data.promise; + } + var skeletonId = "skeleton".concat(skin.index); + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var babylonSkeleton = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Skeleton(skin.name || skeletonId, skeletonId, this._babylonScene); + babylonSkeleton._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + this._loadBones(context, skin, babylonSkeleton); + var promise = this._loadSkinInverseBindMatricesDataAsync(context, skin).then(function (inverseBindMatricesData) { + _this._updateBoneMatrices(babylonSkeleton, inverseBindMatricesData); + }); + skin._data = { + babylonSkeleton: babylonSkeleton, + promise: promise, + }; + assign(babylonSkeleton); + return promise; + }; + GLTFLoader.prototype._loadBones = function (context, skin, babylonSkeleton) { + if (skin.skeleton == undefined || this._parent.alwaysComputeSkeletonRootNode) { + var rootNode = this._findSkeletonRootNode("".concat(context, "/joints"), skin.joints); + if (rootNode) { + if (skin.skeleton === undefined) { + skin.skeleton = rootNode.index; + } + else { + var isParent = function (a, b) { + for (; b.parent; b = b.parent) { + if (b.parent === a) { + return true; + } + } + return false; + }; + var skeletonNode = ArrayItem.Get("".concat(context, "/skeleton"), this._gltf.nodes, skin.skeleton); + if (skeletonNode !== rootNode && !isParent(skeletonNode, rootNode)) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, "/skeleton: Overriding with nearest common ancestor as skeleton node is not a common root")); + skin.skeleton = rootNode.index; + } + } + } + else { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, ": Failed to find common root")); + } + } + var babylonBones = {}; + for (var _i = 0, _a = skin.joints; _i < _a.length; _i++) { + var index = _a[_i]; + var node = ArrayItem.Get("".concat(context, "/joints/").concat(index), this._gltf.nodes, index); + this._loadBone(node, skin, babylonSkeleton, babylonBones); + } + }; + GLTFLoader.prototype._findSkeletonRootNode = function (context, joints) { + if (joints.length === 0) { + return null; + } + var paths = {}; + for (var _i = 0, joints_1 = joints; _i < joints_1.length; _i++) { + var index = joints_1[_i]; + var path = []; + var node = ArrayItem.Get("".concat(context, "/").concat(index), this._gltf.nodes, index); + while (node.index !== -1) { + path.unshift(node); + node = node.parent; + } + paths[index] = path; + } + var rootNode = null; + for (var i = 0;; ++i) { + var path = paths[joints[0]]; + if (i >= path.length) { + return rootNode; + } + var node = path[i]; + for (var j = 1; j < joints.length; ++j) { + path = paths[joints[j]]; + if (i >= path.length || node !== path[i]) { + return rootNode; + } + } + rootNode = node; + } + }; + GLTFLoader.prototype._loadBone = function (node, skin, babylonSkeleton, babylonBones) { + node._isJoint = true; + var babylonBone = babylonBones[node.index]; + if (babylonBone) { + return babylonBone; + } + var parentBabylonBone = null; + if (node.index !== skin.skeleton) { + if (node.parent && node.parent.index !== -1) { + parentBabylonBone = this._loadBone(node.parent, skin, babylonSkeleton, babylonBones); + } + else if (skin.skeleton !== undefined) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("/skins/".concat(skin.index, "/skeleton: Skeleton node is not a common root")); + } + } + var boneIndex = skin.joints.indexOf(node.index); + babylonBone = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Bone(node.name || "joint".concat(node.index), babylonSkeleton, parentBabylonBone, this._getNodeMatrix(node), null, null, boneIndex); + babylonBones[node.index] = babylonBone; + // Wait until the scene is loaded to ensure the transform nodes are loaded. + this._postSceneLoadActions.push(function () { + // Link the Babylon bone with the corresponding Babylon transform node. + // A glTF joint is a pointer to a glTF node in the glTF node hierarchy similar to Unity3D. + babylonBone.linkTransformNode(node._babylonTransformNode); + }); + return babylonBone; + }; + GLTFLoader.prototype._loadSkinInverseBindMatricesDataAsync = function (context, skin) { + if (skin.inverseBindMatrices == undefined) { + return Promise.resolve(null); + } + var accessor = ArrayItem.Get("".concat(context, "/inverseBindMatrices"), this._gltf.accessors, skin.inverseBindMatrices); + return this._loadFloatAccessorAsync("/accessors/".concat(accessor.index), accessor); + }; + GLTFLoader.prototype._updateBoneMatrices = function (babylonSkeleton, inverseBindMatricesData) { + for (var _i = 0, _a = babylonSkeleton.bones; _i < _a.length; _i++) { + var babylonBone = _a[_i]; + var baseMatrix = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Matrix.Identity(); + var boneIndex = babylonBone._index; + if (inverseBindMatricesData && boneIndex !== -1) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Matrix.FromArrayToRef(inverseBindMatricesData, boneIndex * 16, baseMatrix); + baseMatrix.invertToRef(baseMatrix); + } + var babylonParentBone = babylonBone.getParent(); + if (babylonParentBone) { + baseMatrix.multiplyToRef(babylonParentBone.getAbsoluteInverseBindMatrix(), baseMatrix); + } + babylonBone.updateMatrix(baseMatrix, false, false); + babylonBone._updateAbsoluteBindMatrices(undefined, false); + } + }; + GLTFLoader.prototype._getNodeMatrix = function (node) { + return node.matrix + ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Matrix.FromArray(node.matrix) + : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Matrix.Compose(node.scale ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(node.scale) : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.One(), node.rotation ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArray(node.rotation) : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Quaternion.Identity(), node.translation ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(node.translation) : babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero()); + }; + /** + * Loads a glTF camera. + * @param context The context when loading the asset + * @param camera The glTF camera property + * @param assign A function called synchronously after parsing the glTF properties + * @returns A promise that resolves with the loaded Babylon camera when the load is complete + */ + GLTFLoader.prototype.loadCameraAsync = function (context, camera, assign) { + if (assign === void 0) { assign = function () { }; } + var extensionPromise = this._extensionsLoadCameraAsync(context, camera, assign); + if (extensionPromise) { + return extensionPromise; + } + var promises = new Array(); + this.logOpen("".concat(context, " ").concat(camera.name || "")); + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var babylonCamera = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.FreeCamera(camera.name || "camera".concat(camera.index), babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Vector3.Zero(), this._babylonScene, false); + babylonCamera._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + babylonCamera.ignoreParentScaling = true; + camera._babylonCamera = babylonCamera; + // Rotation by 180 as glTF has a different convention than Babylon. + babylonCamera.rotation.set(0, Math.PI, 0); + switch (camera.type) { + case "perspective" /* CameraType.PERSPECTIVE */: { + var perspective = camera.perspective; + if (!perspective) { + throw new Error("".concat(context, ": Camera perspective properties are missing")); + } + babylonCamera.fov = perspective.yfov; + babylonCamera.minZ = perspective.znear; + babylonCamera.maxZ = perspective.zfar || 0; + break; + } + case "orthographic" /* CameraType.ORTHOGRAPHIC */: { + if (!camera.orthographic) { + throw new Error("".concat(context, ": Camera orthographic properties are missing")); + } + babylonCamera.mode = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Camera.ORTHOGRAPHIC_CAMERA; + babylonCamera.orthoLeft = -camera.orthographic.xmag; + babylonCamera.orthoRight = camera.orthographic.xmag; + babylonCamera.orthoBottom = -camera.orthographic.ymag; + babylonCamera.orthoTop = camera.orthographic.ymag; + babylonCamera.minZ = camera.orthographic.znear; + babylonCamera.maxZ = camera.orthographic.zfar; + break; + } + default: { + throw new Error("".concat(context, ": Invalid camera type (").concat(camera.type, ")")); + } + } + GLTFLoader.AddPointerMetadata(babylonCamera, context); + this._parent.onCameraLoadedObservable.notifyObservers(babylonCamera); + assign(babylonCamera); + this.logClose(); + return Promise.all(promises).then(function () { + return babylonCamera; + }); + }; + GLTFLoader.prototype._loadAnimationsAsync = function () { + var animations = this._gltf.animations; + if (!animations) { + return Promise.resolve(); + } + var promises = new Array(); + for (var index = 0; index < animations.length; index++) { + var animation = animations[index]; + promises.push(this.loadAnimationAsync("/animations/".concat(animation.index), animation).then(function (animationGroup) { + // Delete the animation group if it ended up not having any animations in it. + if (animationGroup.targetedAnimations.length === 0) { + animationGroup.dispose(); + } + })); + } + return Promise.all(promises).then(function () { }); + }; + /** + * Loads a glTF animation. + * @param context The context when loading the asset + * @param animation The glTF animation property + * @returns A promise that resolves with the loaded Babylon animation group when the load is complete + */ + GLTFLoader.prototype.loadAnimationAsync = function (context, animation) { + var _this = this; + var promise = this._extensionsLoadAnimationAsync(context, animation); + if (promise) { + return promise; + } + // eslint-disable-next-line @typescript-eslint/naming-convention + return Promise.resolve(/*! import() */).then(__webpack_require__.t.bind(__webpack_require__, /*! babylonjs/Animations/animationGroup */ "babylonjs/Misc/tools", 23)).then(function (_a) { + var AnimationGroup = _a.AnimationGroup; + _this._babylonScene._blockEntityCollection = !!_this._assetContainer; + var babylonAnimationGroup = new AnimationGroup(animation.name || "animation".concat(animation.index), _this._babylonScene); + babylonAnimationGroup._parentContainer = _this._assetContainer; + _this._babylonScene._blockEntityCollection = false; + animation._babylonAnimationGroup = babylonAnimationGroup; + var promises = new Array(); + ArrayItem.Assign(animation.channels); + ArrayItem.Assign(animation.samplers); + for (var _i = 0, _b = animation.channels; _i < _b.length; _i++) { + var channel = _b[_i]; + promises.push(_this._loadAnimationChannelAsync("".concat(context, "/channels/").concat(channel.index), context, animation, channel, function (babylonTarget, babylonAnimation) { + babylonTarget.animations = babylonTarget.animations || []; + babylonTarget.animations.push(babylonAnimation); + babylonAnimationGroup.addTargetedAnimation(babylonAnimation, babylonTarget); + })); + } + return Promise.all(promises).then(function () { + babylonAnimationGroup.normalize(0); + return babylonAnimationGroup; + }); + }); + }; + /** + * @hidden + * Loads a glTF animation channel. + * @param context The context when loading the asset + * @param animationContext The context of the animation when loading the asset + * @param animation The glTF animation property + * @param channel The glTF animation channel property + * @param onLoad Called for each animation loaded + * @returns A void promise that resolves when the load is complete + */ + GLTFLoader.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, onLoad) { + var promise = this._extensionsLoadAnimationChannelAsync(context, animationContext, animation, channel, onLoad); + if (promise) { + return promise; + } + if (channel.target.node == undefined) { + return Promise.resolve(); + } + var targetNode = ArrayItem.Get("".concat(context, "/target/node"), this._gltf.nodes, channel.target.node); + var channelTargetPath = channel.target.path; + var pathIsWeights = channelTargetPath === "weights" /* AnimationChannelTargetPath.WEIGHTS */; + // Ignore animations that have no animation targets. + if ((pathIsWeights && !targetNode._numMorphTargets) || (!pathIsWeights && !targetNode._babylonTransformNode)) { + return Promise.resolve(); + } + // Don't load node animations if disabled. + if (!this._parent.loadNodeAnimations && !pathIsWeights && !targetNode._isJoint) { + return Promise.resolve(); + } + var properties; + switch (channelTargetPath) { + case "translation" /* AnimationChannelTargetPath.TRANSLATION */: { + properties = _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_2__.nodeAnimationData.translation; + break; + } + case "rotation" /* AnimationChannelTargetPath.ROTATION */: { + properties = _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_2__.nodeAnimationData.rotation; + break; + } + case "scale" /* AnimationChannelTargetPath.SCALE */: { + properties = _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_2__.nodeAnimationData.scale; + break; + } + case "weights" /* AnimationChannelTargetPath.WEIGHTS */: { + properties = _glTFLoaderAnimation__WEBPACK_IMPORTED_MODULE_2__.nodeAnimationData.weights; + break; + } + default: { + throw new Error("".concat(context, "/target/path: Invalid value (").concat(channel.target.path, ")")); + } + } + var targetInfo = { + object: targetNode, + info: properties, + }; + return this._loadAnimationChannelFromTargetInfoAsync(context, animationContext, animation, channel, targetInfo, onLoad); + }; + /** + * @hidden + * Loads a glTF animation channel. + * @param context The context when loading the asset + * @param animationContext The context of the animation when loading the asset + * @param animation The glTF animation property + * @param channel The glTF animation channel property + * @param targetInfo The glTF target and properties + * @param onLoad Called for each animation loaded + * @returns A void promise that resolves when the load is complete + */ + GLTFLoader.prototype._loadAnimationChannelFromTargetInfoAsync = function (context, animationContext, animation, channel, targetInfo, onLoad) { + var fps = this.parent.targetFps; + var invfps = 1 / fps; + var sampler = ArrayItem.Get("".concat(context, "/sampler"), animation.samplers, channel.sampler); + return this._loadAnimationSamplerAsync("".concat(animationContext, "/samplers/").concat(channel.sampler), sampler).then(function (data) { + var numAnimations = 0; + var target = targetInfo.object; + var propertyInfos = targetInfo.info; + // Extract the corresponding values from the read value. + // GLTF values may be dispatched to several Babylon properties. + // For example, baseColorFactor [`r`, `g`, `b`, `a`] is dispatched to + // - albedoColor as Color3(`r`, `g`, `b`) + // - alpha as `a` + for (var _i = 0, propertyInfos_1 = propertyInfos; _i < propertyInfos_1.length; _i++) { + var propertyInfo = propertyInfos_1[_i]; + var stride = propertyInfo.getStride(target); + var input = data.input; + var output = data.output; + var keys = new Array(input.length); + var outputOffset = 0; + switch (data.interpolation) { + case "STEP" /* AnimationSamplerInterpolation.STEP */: { + for (var index = 0; index < input.length; index++) { + var value = propertyInfo.getValue(target, output, outputOffset, 1); + outputOffset += stride; + keys[index] = { + frame: input[index] * fps, + value: value, + interpolation: 1 /* AnimationKeyInterpolation.STEP */, + }; + } + break; + } + case "CUBICSPLINE" /* AnimationSamplerInterpolation.CUBICSPLINE */: { + for (var index = 0; index < input.length; index++) { + var inTangent = propertyInfo.getValue(target, output, outputOffset, invfps); + outputOffset += stride; + var value = propertyInfo.getValue(target, output, outputOffset, 1); + outputOffset += stride; + var outTangent = propertyInfo.getValue(target, output, outputOffset, invfps); + outputOffset += stride; + keys[index] = { + frame: input[index] * fps, + inTangent: inTangent, + value: value, + outTangent: outTangent, + }; + } + break; + } + case "LINEAR" /* AnimationSamplerInterpolation.LINEAR */: { + for (var index = 0; index < input.length; index++) { + var value = propertyInfo.getValue(target, output, outputOffset, 1); + outputOffset += stride; + keys[index] = { + frame: input[index] * fps, + value: value, + }; + } + break; + } + } + if (outputOffset > 0) { + var name_3 = "".concat(animation.name || "animation".concat(animation.index), "_channel").concat(channel.index, "_").concat(numAnimations); + propertyInfo.buildAnimations(target, name_3, fps, keys, function (babylonAnimatable, babylonAnimation) { + ++numAnimations; + onLoad(babylonAnimatable, babylonAnimation); + }); + } + } + }); + }; + GLTFLoader.prototype._loadAnimationSamplerAsync = function (context, sampler) { + if (sampler._data) { + return sampler._data; + } + var interpolation = sampler.interpolation || "LINEAR" /* AnimationSamplerInterpolation.LINEAR */; + switch (interpolation) { + case "STEP" /* AnimationSamplerInterpolation.STEP */: + case "LINEAR" /* AnimationSamplerInterpolation.LINEAR */: + case "CUBICSPLINE" /* AnimationSamplerInterpolation.CUBICSPLINE */: { + break; + } + default: { + throw new Error("".concat(context, "/interpolation: Invalid value (").concat(sampler.interpolation, ")")); + } + } + var inputAccessor = ArrayItem.Get("".concat(context, "/input"), this._gltf.accessors, sampler.input); + var outputAccessor = ArrayItem.Get("".concat(context, "/output"), this._gltf.accessors, sampler.output); + sampler._data = Promise.all([ + this._loadFloatAccessorAsync("/accessors/".concat(inputAccessor.index), inputAccessor), + this._loadFloatAccessorAsync("/accessors/".concat(outputAccessor.index), outputAccessor), + ]).then(function (_a) { + var inputData = _a[0], outputData = _a[1]; + return { + input: inputData, + interpolation: interpolation, + output: outputData, + }; + }); + return sampler._data; + }; + /** + * Loads a glTF buffer. + * @param context The context when loading the asset + * @param buffer The glTF buffer property + * @param byteOffset The byte offset to use + * @param byteLength The byte length to use + * @returns A promise that resolves with the loaded data when the load is complete + */ + GLTFLoader.prototype.loadBufferAsync = function (context, buffer, byteOffset, byteLength) { + var extensionPromise = this._extensionsLoadBufferAsync(context, buffer, byteOffset, byteLength); + if (extensionPromise) { + return extensionPromise; + } + if (!buffer._data) { + if (buffer.uri) { + buffer._data = this.loadUriAsync("".concat(context, "/uri"), buffer, buffer.uri); + } + else { + if (!this._bin) { + throw new Error("".concat(context, ": Uri is missing or the binary glTF is missing its binary chunk")); + } + buffer._data = this._bin.readAsync(0, buffer.byteLength); + } + } + return buffer._data.then(function (data) { + try { + return new Uint8Array(data.buffer, data.byteOffset + byteOffset, byteLength); + } + catch (e) { + throw new Error("".concat(context, ": ").concat(e.message)); + } + }); + }; + /** + * Loads a glTF buffer view. + * @param context The context when loading the asset + * @param bufferView The glTF buffer view property + * @returns A promise that resolves with the loaded data when the load is complete + */ + GLTFLoader.prototype.loadBufferViewAsync = function (context, bufferView) { + var extensionPromise = this._extensionsLoadBufferViewAsync(context, bufferView); + if (extensionPromise) { + return extensionPromise; + } + if (bufferView._data) { + return bufferView._data; + } + var buffer = ArrayItem.Get("".concat(context, "/buffer"), this._gltf.buffers, bufferView.buffer); + bufferView._data = this.loadBufferAsync("/buffers/".concat(buffer.index), buffer, bufferView.byteOffset || 0, bufferView.byteLength); + return bufferView._data; + }; + GLTFLoader.prototype._loadAccessorAsync = function (context, accessor, constructor) { + var _this = this; + if (accessor._data) { + return accessor._data; + } + var numComponents = GLTFLoader._GetNumComponents(context, accessor.type); + var byteStride = numComponents * babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.GetTypeByteLength(accessor.componentType); + var length = numComponents * accessor.count; + if (accessor.bufferView == undefined) { + accessor._data = Promise.resolve(new constructor(length)); + } + else { + var bufferView_1 = ArrayItem.Get("".concat(context, "/bufferView"), this._gltf.bufferViews, accessor.bufferView); + accessor._data = this.loadBufferViewAsync("/bufferViews/".concat(bufferView_1.index), bufferView_1).then(function (data) { + if (accessor.componentType === 5126 /* AccessorComponentType.FLOAT */ && !accessor.normalized && (!bufferView_1.byteStride || bufferView_1.byteStride === byteStride)) { + return GLTFLoader._GetTypedArray(context, accessor.componentType, data, accessor.byteOffset, length); + } + else { + var typedArray_1 = new constructor(length); + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ForEach(data, accessor.byteOffset || 0, bufferView_1.byteStride || byteStride, numComponents, accessor.componentType, typedArray_1.length, accessor.normalized || false, function (value, index) { + typedArray_1[index] = value; + }); + return typedArray_1; + } + }); + } + if (accessor.sparse) { + var sparse_1 = accessor.sparse; + accessor._data = accessor._data.then(function (data) { + var typedArray = data; + var indicesBufferView = ArrayItem.Get("".concat(context, "/sparse/indices/bufferView"), _this._gltf.bufferViews, sparse_1.indices.bufferView); + var valuesBufferView = ArrayItem.Get("".concat(context, "/sparse/values/bufferView"), _this._gltf.bufferViews, sparse_1.values.bufferView); + return Promise.all([ + _this.loadBufferViewAsync("/bufferViews/".concat(indicesBufferView.index), indicesBufferView), + _this.loadBufferViewAsync("/bufferViews/".concat(valuesBufferView.index), valuesBufferView), + ]).then(function (_a) { + var indicesData = _a[0], valuesData = _a[1]; + var indices = GLTFLoader._GetTypedArray("".concat(context, "/sparse/indices"), sparse_1.indices.componentType, indicesData, sparse_1.indices.byteOffset, sparse_1.count); + var sparseLength = numComponents * sparse_1.count; + var values; + if (accessor.componentType === 5126 /* AccessorComponentType.FLOAT */ && !accessor.normalized) { + values = GLTFLoader._GetTypedArray("".concat(context, "/sparse/values"), accessor.componentType, valuesData, sparse_1.values.byteOffset, sparseLength); + } + else { + var sparseData = GLTFLoader._GetTypedArray("".concat(context, "/sparse/values"), accessor.componentType, valuesData, sparse_1.values.byteOffset, sparseLength); + values = new constructor(sparseLength); + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.ForEach(sparseData, 0, byteStride, numComponents, accessor.componentType, values.length, accessor.normalized || false, function (value, index) { + values[index] = value; + }); + } + var valuesIndex = 0; + for (var indicesIndex = 0; indicesIndex < indices.length; indicesIndex++) { + var dataIndex = indices[indicesIndex] * numComponents; + for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) { + typedArray[dataIndex++] = values[valuesIndex++]; + } + } + return typedArray; + }); + }); + } + return accessor._data; + }; + /** + * @internal + */ + GLTFLoader.prototype._loadFloatAccessorAsync = function (context, accessor) { + return this._loadAccessorAsync(context, accessor, Float32Array); + }; + /** + * @internal + */ + GLTFLoader.prototype._loadIndicesAccessorAsync = function (context, accessor) { + if (accessor.type !== "SCALAR" /* AccessorType.SCALAR */) { + throw new Error("".concat(context, "/type: Invalid value ").concat(accessor.type)); + } + if (accessor.componentType !== 5121 /* AccessorComponentType.UNSIGNED_BYTE */ && + accessor.componentType !== 5123 /* AccessorComponentType.UNSIGNED_SHORT */ && + accessor.componentType !== 5125 /* AccessorComponentType.UNSIGNED_INT */) { + throw new Error("".concat(context, "/componentType: Invalid value ").concat(accessor.componentType)); + } + if (accessor._data) { + return accessor._data; + } + if (accessor.sparse) { + var constructor = GLTFLoader._GetTypedArrayConstructor("".concat(context, "/componentType"), accessor.componentType); + accessor._data = this._loadAccessorAsync(context, accessor, constructor); + } + else { + var bufferView = ArrayItem.Get("".concat(context, "/bufferView"), this._gltf.bufferViews, accessor.bufferView); + accessor._data = this.loadBufferViewAsync("/bufferViews/".concat(bufferView.index), bufferView).then(function (data) { + return GLTFLoader._GetTypedArray(context, accessor.componentType, data, accessor.byteOffset, accessor.count); + }); + } + return accessor._data; + }; + /** + * @internal + */ + GLTFLoader.prototype._loadVertexBufferViewAsync = function (bufferView) { + if (bufferView._babylonBuffer) { + return bufferView._babylonBuffer; + } + var engine = this._babylonScene.getEngine(); + bufferView._babylonBuffer = this.loadBufferViewAsync("/bufferViews/".concat(bufferView.index), bufferView).then(function (data) { + return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Buffer(engine, data, false); + }); + return bufferView._babylonBuffer; + }; + /** + * @internal + */ + GLTFLoader.prototype._loadVertexAccessorAsync = function (context, accessor, kind) { + var _a; + if ((_a = accessor._babylonVertexBuffer) === null || _a === void 0 ? void 0 : _a[kind]) { + return accessor._babylonVertexBuffer[kind]; + } + if (!accessor._babylonVertexBuffer) { + accessor._babylonVertexBuffer = {}; + } + var engine = this._babylonScene.getEngine(); + if (accessor.sparse || accessor.bufferView == undefined) { + accessor._babylonVertexBuffer[kind] = this._loadFloatAccessorAsync(context, accessor).then(function (data) { + return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer(engine, data, kind, false); + }); + } + else { + var bufferView_2 = ArrayItem.Get("".concat(context, "/bufferView"), this._gltf.bufferViews, accessor.bufferView); + accessor._babylonVertexBuffer[kind] = this._loadVertexBufferViewAsync(bufferView_2).then(function (babylonBuffer) { + var numComponents = GLTFLoader._GetNumComponents(context, accessor.type); + return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer(engine, babylonBuffer, kind, false, undefined, bufferView_2.byteStride, undefined, accessor.byteOffset, numComponents, accessor.componentType, accessor.normalized, true, undefined, true); + }); + } + return accessor._babylonVertexBuffer[kind]; + }; + GLTFLoader.prototype._loadMaterialMetallicRoughnessPropertiesAsync = function (context, properties, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + if (properties) { + if (properties.baseColorFactor) { + babylonMaterial.albedoColor = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(properties.baseColorFactor); + babylonMaterial.alpha = properties.baseColorFactor[3]; + } + else { + babylonMaterial.albedoColor = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Color3.White(); + } + babylonMaterial.metallic = properties.metallicFactor == undefined ? 1 : properties.metallicFactor; + babylonMaterial.roughness = properties.roughnessFactor == undefined ? 1 : properties.roughnessFactor; + if (properties.baseColorTexture) { + promises.push(this.loadTextureInfoAsync("".concat(context, "/baseColorTexture"), properties.baseColorTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Base Color)"); + babylonMaterial.albedoTexture = texture; + })); + } + if (properties.metallicRoughnessTexture) { + properties.metallicRoughnessTexture.nonColorData = true; + promises.push(this.loadTextureInfoAsync("".concat(context, "/metallicRoughnessTexture"), properties.metallicRoughnessTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Metallic Roughness)"); + babylonMaterial.metallicTexture = texture; + })); + babylonMaterial.useMetallnessFromMetallicTextureBlue = true; + babylonMaterial.useRoughnessFromMetallicTextureGreen = true; + babylonMaterial.useRoughnessFromMetallicTextureAlpha = false; + } + } + return Promise.all(promises).then(function () { }); + }; + /** + * @internal + */ + GLTFLoader.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) { + if (assign === void 0) { assign = function () { }; } + var extensionPromise = this._extensionsLoadMaterialAsync(context, material, babylonMesh, babylonDrawMode, assign); + if (extensionPromise) { + return extensionPromise; + } + material._data = material._data || {}; + var babylonData = material._data[babylonDrawMode]; + if (!babylonData) { + this.logOpen("".concat(context, " ").concat(material.name || "")); + var babylonMaterial = this.createMaterial(context, material, babylonDrawMode); + babylonData = { + babylonMaterial: babylonMaterial, + babylonMeshes: [], + promise: this.loadMaterialPropertiesAsync(context, material, babylonMaterial), + }; + material._data[babylonDrawMode] = babylonData; + GLTFLoader.AddPointerMetadata(babylonMaterial, context); + this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial); + this.logClose(); + } + if (babylonMesh) { + babylonData.babylonMeshes.push(babylonMesh); + babylonMesh.onDisposeObservable.addOnce(function () { + var index = babylonData.babylonMeshes.indexOf(babylonMesh); + if (index !== -1) { + babylonData.babylonMeshes.splice(index, 1); + } + }); + } + assign(babylonData.babylonMaterial); + return babylonData.promise.then(function () { + return babylonData.babylonMaterial; + }); + }; + GLTFLoader.prototype._createDefaultMaterial = function (name, babylonDrawMode) { + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var babylonMaterial = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial(name, this._babylonScene); + babylonMaterial._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + // Moved to mesh so user can change materials on gltf meshes: babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation; + babylonMaterial.fillMode = babylonDrawMode; + babylonMaterial.enableSpecularAntiAliasing = true; + babylonMaterial.useRadianceOverAlpha = !this._parent.transparencyAsCoverage; + babylonMaterial.useSpecularOverAlpha = !this._parent.transparencyAsCoverage; + babylonMaterial.transparencyMode = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial.PBRMATERIAL_OPAQUE; + babylonMaterial.metallic = 1; + babylonMaterial.roughness = 1; + return babylonMaterial; + }; + /** + * Creates a Babylon material from a glTF material. + * @param context The context when loading the asset + * @param material The glTF material property + * @param babylonDrawMode The draw mode for the Babylon material + * @returns The Babylon material + */ + GLTFLoader.prototype.createMaterial = function (context, material, babylonDrawMode) { + var extensionPromise = this._extensionsCreateMaterial(context, material, babylonDrawMode); + if (extensionPromise) { + return extensionPromise; + } + var name = material.name || "material".concat(material.index); + var babylonMaterial = this._createDefaultMaterial(name, babylonDrawMode); + return babylonMaterial; + }; + /** + * Loads properties from a glTF material into a Babylon material. + * @param context The context when loading the asset + * @param material The glTF material property + * @param babylonMaterial The Babylon material + * @returns A promise that resolves when the load is complete + */ + GLTFLoader.prototype.loadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + var extensionPromise = this._extensionsLoadMaterialPropertiesAsync(context, material, babylonMaterial); + if (extensionPromise) { + return extensionPromise; + } + var promises = new Array(); + promises.push(this.loadMaterialBasePropertiesAsync(context, material, babylonMaterial)); + if (material.pbrMetallicRoughness) { + promises.push(this._loadMaterialMetallicRoughnessPropertiesAsync("".concat(context, "/pbrMetallicRoughness"), material.pbrMetallicRoughness, babylonMaterial)); + } + this.loadMaterialAlphaProperties(context, material, babylonMaterial); + return Promise.all(promises).then(function () { }); + }; + /** + * Loads the normal, occlusion, and emissive properties from a glTF material into a Babylon material. + * @param context The context when loading the asset + * @param material The glTF material property + * @param babylonMaterial The Babylon material + * @returns A promise that resolves when the load is complete + */ + GLTFLoader.prototype.loadMaterialBasePropertiesAsync = function (context, material, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var promises = new Array(); + babylonMaterial.emissiveColor = material.emissiveFactor ? babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Color3.FromArray(material.emissiveFactor) : new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Color3(0, 0, 0); + if (material.doubleSided) { + babylonMaterial.backFaceCulling = false; + babylonMaterial.twoSidedLighting = true; + } + if (material.normalTexture) { + material.normalTexture.nonColorData = true; + promises.push(this.loadTextureInfoAsync("".concat(context, "/normalTexture"), material.normalTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Normal)"); + babylonMaterial.bumpTexture = texture; + })); + babylonMaterial.invertNormalMapX = !this._babylonScene.useRightHandedSystem; + babylonMaterial.invertNormalMapY = this._babylonScene.useRightHandedSystem; + if (material.normalTexture.scale != undefined && babylonMaterial.bumpTexture) { + babylonMaterial.bumpTexture.level = material.normalTexture.scale; + } + babylonMaterial.forceIrradianceInFragment = true; + } + if (material.occlusionTexture) { + material.occlusionTexture.nonColorData = true; + promises.push(this.loadTextureInfoAsync("".concat(context, "/occlusionTexture"), material.occlusionTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Occlusion)"); + babylonMaterial.ambientTexture = texture; + })); + babylonMaterial.useAmbientInGrayScale = true; + if (material.occlusionTexture.strength != undefined) { + babylonMaterial.ambientTextureStrength = material.occlusionTexture.strength; + } + } + if (material.emissiveTexture) { + promises.push(this.loadTextureInfoAsync("".concat(context, "/emissiveTexture"), material.emissiveTexture, function (texture) { + texture.name = "".concat(babylonMaterial.name, " (Emissive)"); + babylonMaterial.emissiveTexture = texture; + })); + } + return Promise.all(promises).then(function () { }); + }; + /** + * Loads the alpha properties from a glTF material into a Babylon material. + * Must be called after the setting the albedo texture of the Babylon material when the material has an albedo texture. + * @param context The context when loading the asset + * @param material The glTF material property + * @param babylonMaterial The Babylon material + */ + GLTFLoader.prototype.loadMaterialAlphaProperties = function (context, material, babylonMaterial) { + if (!(babylonMaterial instanceof babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial)) { + throw new Error("".concat(context, ": Material type not supported")); + } + var alphaMode = material.alphaMode || "OPAQUE" /* MaterialAlphaMode.OPAQUE */; + switch (alphaMode) { + case "OPAQUE" /* MaterialAlphaMode.OPAQUE */: { + babylonMaterial.transparencyMode = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial.PBRMATERIAL_OPAQUE; + babylonMaterial.alpha = 1.0; // Force alpha to 1.0 for opaque mode. + break; + } + case "MASK" /* MaterialAlphaMode.MASK */: { + babylonMaterial.transparencyMode = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial.PBRMATERIAL_ALPHATEST; + babylonMaterial.alphaCutOff = material.alphaCutoff == undefined ? 0.5 : material.alphaCutoff; + if (babylonMaterial.albedoTexture) { + babylonMaterial.albedoTexture.hasAlpha = true; + } + break; + } + case "BLEND" /* MaterialAlphaMode.BLEND */: { + babylonMaterial.transparencyMode = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.PBRMaterial.PBRMATERIAL_ALPHABLEND; + if (babylonMaterial.albedoTexture) { + babylonMaterial.albedoTexture.hasAlpha = true; + babylonMaterial.useAlphaFromAlbedoTexture = true; + } + break; + } + default: { + throw new Error("".concat(context, "/alphaMode: Invalid value (").concat(material.alphaMode, ")")); + } + } + }; + /** + * Loads a glTF texture info. + * @param context The context when loading the asset + * @param textureInfo The glTF texture info property + * @param assign A function called synchronously after parsing the glTF properties + * @returns A promise that resolves with the loaded Babylon texture when the load is complete + */ + GLTFLoader.prototype.loadTextureInfoAsync = function (context, textureInfo, assign) { + var _this = this; + if (assign === void 0) { assign = function () { }; } + var extensionPromise = this._extensionsLoadTextureInfoAsync(context, textureInfo, assign); + if (extensionPromise) { + return extensionPromise; + } + this.logOpen("".concat(context)); + if (textureInfo.texCoord >= 6) { + throw new Error("".concat(context, "/texCoord: Invalid value (").concat(textureInfo.texCoord, ")")); + } + var texture = ArrayItem.Get("".concat(context, "/index"), this._gltf.textures, textureInfo.index); + texture._textureInfo = textureInfo; + var promise = this._loadTextureAsync("/textures/".concat(textureInfo.index), texture, function (babylonTexture) { + babylonTexture.coordinatesIndex = textureInfo.texCoord || 0; + GLTFLoader.AddPointerMetadata(babylonTexture, context); + _this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture); + assign(babylonTexture); + }); + this.logClose(); + return promise; + }; + /** + * @internal + */ + GLTFLoader.prototype._loadTextureAsync = function (context, texture, assign) { + if (assign === void 0) { assign = function () { }; } + var extensionPromise = this._extensionsLoadTextureAsync(context, texture, assign); + if (extensionPromise) { + return extensionPromise; + } + this.logOpen("".concat(context, " ").concat(texture.name || "")); + var sampler = texture.sampler == undefined ? GLTFLoader.DefaultSampler : ArrayItem.Get("".concat(context, "/sampler"), this._gltf.samplers, texture.sampler); + var image = ArrayItem.Get("".concat(context, "/source"), this._gltf.images, texture.source); + var promise = this._createTextureAsync(context, sampler, image, assign, undefined, !texture._textureInfo.nonColorData); + this.logClose(); + return promise; + }; + /** + * @internal + */ + GLTFLoader.prototype._createTextureAsync = function (context, sampler, image, assign, textureLoaderOptions, useSRGBBuffer) { + var _this = this; + if (assign === void 0) { assign = function () { }; } + var samplerData = this._loadSampler("/samplers/".concat(sampler.index), sampler); + var promises = new Array(); + var deferred = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Deferred(); + this._babylonScene._blockEntityCollection = !!this._assetContainer; + var textureCreationOptions = { + noMipmap: samplerData.noMipMaps, + invertY: false, + samplingMode: samplerData.samplingMode, + onLoad: function () { + if (!_this._disposed) { + deferred.resolve(); + } + }, + onError: function (message, exception) { + if (!_this._disposed) { + deferred.reject(new Error("".concat(context, ": ").concat(exception && exception.message ? exception.message : message || "Failed to load texture"))); + } + }, + mimeType: image.mimeType, + loaderOptions: textureLoaderOptions, + useSRGBBuffer: !!useSRGBBuffer && this._parent.useSRGBBuffers, + }; + var babylonTexture = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture(null, this._babylonScene, textureCreationOptions); + babylonTexture._parentContainer = this._assetContainer; + this._babylonScene._blockEntityCollection = false; + promises.push(deferred.promise); + promises.push(this.loadImageAsync("/images/".concat(image.index), image).then(function (data) { + var name = image.uri || "".concat(_this._fileName, "#image").concat(image.index); + var dataUrl = "data:".concat(_this._uniqueRootUrl).concat(name); + babylonTexture.updateURL(dataUrl, data); + // Set the internal texture label. + var internalTexture = babylonTexture.getInternalTexture(); + if (internalTexture) { + internalTexture.label = image.name; + } + })); + babylonTexture.wrapU = samplerData.wrapU; + babylonTexture.wrapV = samplerData.wrapV; + assign(babylonTexture); + if (this._parent.useGltfTextureNames) { + babylonTexture.name = image.name || image.uri || "image".concat(image.index); + } + return Promise.all(promises).then(function () { + return babylonTexture; + }); + }; + GLTFLoader.prototype._loadSampler = function (context, sampler) { + if (!sampler._data) { + sampler._data = { + noMipMaps: sampler.minFilter === 9728 /* TextureMinFilter.NEAREST */ || sampler.minFilter === 9729 /* TextureMinFilter.LINEAR */, + samplingMode: GLTFLoader._GetTextureSamplingMode(context, sampler), + wrapU: GLTFLoader._GetTextureWrapMode("".concat(context, "/wrapS"), sampler.wrapS), + wrapV: GLTFLoader._GetTextureWrapMode("".concat(context, "/wrapT"), sampler.wrapT), + }; + } + return sampler._data; + }; + /** + * Loads a glTF image. + * @param context The context when loading the asset + * @param image The glTF image property + * @returns A promise that resolves with the loaded data when the load is complete + */ + GLTFLoader.prototype.loadImageAsync = function (context, image) { + if (!image._data) { + this.logOpen("".concat(context, " ").concat(image.name || "")); + if (image.uri) { + image._data = this.loadUriAsync("".concat(context, "/uri"), image, image.uri); + } + else { + var bufferView = ArrayItem.Get("".concat(context, "/bufferView"), this._gltf.bufferViews, image.bufferView); + image._data = this.loadBufferViewAsync("/bufferViews/".concat(bufferView.index), bufferView); + } + this.logClose(); + } + return image._data; + }; + /** + * Loads a glTF uri. + * @param context The context when loading the asset + * @param property The glTF property associated with the uri + * @param uri The base64 or relative uri + * @returns A promise that resolves with the loaded data when the load is complete + */ + GLTFLoader.prototype.loadUriAsync = function (context, property, uri) { + var _this = this; + var extensionPromise = this._extensionsLoadUriAsync(context, property, uri); + if (extensionPromise) { + return extensionPromise; + } + if (!GLTFLoader._ValidateUri(uri)) { + throw new Error("".concat(context, ": '").concat(uri, "' is invalid")); + } + if ((0,babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.IsBase64DataUrl)(uri)) { + var data = new Uint8Array((0,babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.DecodeBase64UrlToBinary)(uri)); + this.log("".concat(context, ": Decoded ").concat(uri.substring(0, 64), "... (").concat(data.length, " bytes)")); + return Promise.resolve(data); + } + this.log("".concat(context, ": Loading ").concat(uri)); + return this._parent.preprocessUrlAsync(this._rootUrl + uri).then(function (url) { + return new Promise(function (resolve, reject) { + _this._parent._loadFile(_this._babylonScene, url, function (data) { + if (!_this._disposed) { + _this.log("".concat(context, ": Loaded ").concat(uri, " (").concat(data.byteLength, " bytes)")); + resolve(new Uint8Array(data)); + } + }, true, function (request) { + reject(new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.LoadFileError("".concat(context, ": Failed to load '").concat(uri, "'").concat(request ? ": " + request.status + " " + request.statusText : ""), request)); + }); + }); + }); + }; + /** + * Adds a JSON pointer to the _internalMetadata of the Babylon object at `._internalMetadata.gltf.pointers`. + * @param babylonObject the Babylon object with _internalMetadata + * @param pointer the JSON pointer + */ + GLTFLoader.AddPointerMetadata = function (babylonObject, pointer) { + babylonObject.metadata = babylonObject.metadata || {}; + var metadata = (babylonObject._internalMetadata = babylonObject._internalMetadata || {}); + var gltf = (metadata.gltf = metadata.gltf || {}); + var pointers = (gltf.pointers = gltf.pointers || []); + pointers.push(pointer); + }; + GLTFLoader._GetTextureWrapMode = function (context, mode) { + // Set defaults if undefined + mode = mode == undefined ? 10497 /* TextureWrapMode.REPEAT */ : mode; + switch (mode) { + case 33071 /* TextureWrapMode.CLAMP_TO_EDGE */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.CLAMP_ADDRESSMODE; + case 33648 /* TextureWrapMode.MIRRORED_REPEAT */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.MIRROR_ADDRESSMODE; + case 10497 /* TextureWrapMode.REPEAT */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.WRAP_ADDRESSMODE; + default: + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, ": Invalid value (").concat(mode, ")")); + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.WRAP_ADDRESSMODE; + } + }; + GLTFLoader._GetTextureSamplingMode = function (context, sampler) { + // Set defaults if undefined + var magFilter = sampler.magFilter == undefined ? 9729 /* TextureMagFilter.LINEAR */ : sampler.magFilter; + var minFilter = sampler.minFilter == undefined ? 9987 /* TextureMinFilter.LINEAR_MIPMAP_LINEAR */ : sampler.minFilter; + if (magFilter === 9729 /* TextureMagFilter.LINEAR */) { + switch (minFilter) { + case 9728 /* TextureMinFilter.NEAREST */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_NEAREST; + case 9729 /* TextureMinFilter.LINEAR */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_LINEAR; + case 9984 /* TextureMinFilter.NEAREST_MIPMAP_NEAREST */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_NEAREST_MIPNEAREST; + case 9985 /* TextureMinFilter.LINEAR_MIPMAP_NEAREST */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_LINEAR_MIPNEAREST; + case 9986 /* TextureMinFilter.NEAREST_MIPMAP_LINEAR */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_NEAREST_MIPLINEAR; + case 9987 /* TextureMinFilter.LINEAR_MIPMAP_LINEAR */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_LINEAR_MIPLINEAR; + default: + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, "/minFilter: Invalid value (").concat(minFilter, ")")); + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.LINEAR_LINEAR_MIPLINEAR; + } + } + else { + if (magFilter !== 9728 /* TextureMagFilter.NEAREST */) { + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, "/magFilter: Invalid value (").concat(magFilter, ")")); + } + switch (minFilter) { + case 9728 /* TextureMinFilter.NEAREST */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_NEAREST; + case 9729 /* TextureMinFilter.LINEAR */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_LINEAR; + case 9984 /* TextureMinFilter.NEAREST_MIPMAP_NEAREST */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_NEAREST_MIPNEAREST; + case 9985 /* TextureMinFilter.LINEAR_MIPMAP_NEAREST */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_LINEAR_MIPNEAREST; + case 9986 /* TextureMinFilter.NEAREST_MIPMAP_LINEAR */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_NEAREST_MIPLINEAR; + case 9987 /* TextureMinFilter.LINEAR_MIPMAP_LINEAR */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_LINEAR_MIPLINEAR; + default: + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, "/minFilter: Invalid value (").concat(minFilter, ")")); + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Texture.NEAREST_NEAREST_MIPNEAREST; + } + } + }; + GLTFLoader._GetTypedArrayConstructor = function (context, componentType) { + switch (componentType) { + case 5120 /* AccessorComponentType.BYTE */: + return Int8Array; + case 5121 /* AccessorComponentType.UNSIGNED_BYTE */: + return Uint8Array; + case 5122 /* AccessorComponentType.SHORT */: + return Int16Array; + case 5123 /* AccessorComponentType.UNSIGNED_SHORT */: + return Uint16Array; + case 5125 /* AccessorComponentType.UNSIGNED_INT */: + return Uint32Array; + case 5126 /* AccessorComponentType.FLOAT */: + return Float32Array; + default: + throw new Error("".concat(context, ": Invalid component type ").concat(componentType)); + } + }; + GLTFLoader._GetTypedArray = function (context, componentType, bufferView, byteOffset, length) { + var buffer = bufferView.buffer; + byteOffset = bufferView.byteOffset + (byteOffset || 0); + var constructor = GLTFLoader._GetTypedArrayConstructor("".concat(context, "/componentType"), componentType); + var componentTypeLength = babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.VertexBuffer.GetTypeByteLength(componentType); + if (byteOffset % componentTypeLength !== 0) { + // HACK: Copy the buffer if byte offset is not a multiple of component type byte length. + babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("".concat(context, ": Copying buffer as byte offset (").concat(byteOffset, ") is not a multiple of component type byte length (").concat(componentTypeLength, ")")); + return new constructor(buffer.slice(byteOffset, byteOffset + length * componentTypeLength), 0); + } + return new constructor(buffer, byteOffset, length); + }; + GLTFLoader._GetNumComponents = function (context, type) { + switch (type) { + case "SCALAR": + return 1; + case "VEC2": + return 2; + case "VEC3": + return 3; + case "VEC4": + return 4; + case "MAT2": + return 4; + case "MAT3": + return 9; + case "MAT4": + return 16; + } + throw new Error("".concat(context, ": Invalid type (").concat(type, ")")); + }; + GLTFLoader._ValidateUri = function (uri) { + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Tools.IsBase64(uri) || uri.indexOf("..") === -1; + }; + /** + * @internal + */ + GLTFLoader._GetDrawMode = function (context, mode) { + if (mode == undefined) { + mode = 4 /* MeshPrimitiveMode.TRIANGLES */; + } + switch (mode) { + case 0 /* MeshPrimitiveMode.POINTS */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.PointListDrawMode; + case 1 /* MeshPrimitiveMode.LINES */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.LineListDrawMode; + case 2 /* MeshPrimitiveMode.LINE_LOOP */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.LineLoopDrawMode; + case 3 /* MeshPrimitiveMode.LINE_STRIP */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.LineStripDrawMode; + case 4 /* MeshPrimitiveMode.TRIANGLES */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleFillMode; + case 5 /* MeshPrimitiveMode.TRIANGLE_STRIP */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleStripDrawMode; + case 6 /* MeshPrimitiveMode.TRIANGLE_FAN */: + return babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__.Material.TriangleFanDrawMode; + } + throw new Error("".concat(context, ": Invalid mesh primitive mode (").concat(mode, ")")); + }; + GLTFLoader.prototype._compileMaterialsAsync = function () { + var _this = this; + this._parent._startPerformanceCounter("Compile materials"); + var promises = new Array(); + if (this._gltf.materials) { + for (var _i = 0, _a = this._gltf.materials; _i < _a.length; _i++) { + var material = _a[_i]; + if (material._data) { + for (var babylonDrawMode in material._data) { + var babylonData = material._data[babylonDrawMode]; + for (var _b = 0, _c = babylonData.babylonMeshes; _b < _c.length; _b++) { + var babylonMesh = _c[_b]; + // Ensure nonUniformScaling is set if necessary. + babylonMesh.computeWorldMatrix(true); + var babylonMaterial = babylonData.babylonMaterial; + promises.push(babylonMaterial.forceCompilationAsync(babylonMesh)); + promises.push(babylonMaterial.forceCompilationAsync(babylonMesh, { useInstances: true })); + if (this._parent.useClipPlane) { + promises.push(babylonMaterial.forceCompilationAsync(babylonMesh, { clipPlane: true })); + promises.push(babylonMaterial.forceCompilationAsync(babylonMesh, { clipPlane: true, useInstances: true })); + } + } + } + } + } + } + return Promise.all(promises).then(function () { + _this._parent._endPerformanceCounter("Compile materials"); + }); + }; + GLTFLoader.prototype._compileShadowGeneratorsAsync = function () { + var _this = this; + this._parent._startPerformanceCounter("Compile shadow generators"); + var promises = new Array(); + var lights = this._babylonScene.lights; + for (var _i = 0, lights_1 = lights; _i < lights_1.length; _i++) { + var light = lights_1[_i]; + var generator = light.getShadowGenerator(); + if (generator) { + promises.push(generator.forceCompilationAsync()); + } + } + return Promise.all(promises).then(function () { + _this._parent._endPerformanceCounter("Compile shadow generators"); + }); + }; + GLTFLoader.prototype._forEachExtensions = function (action) { + for (var _i = 0, _a = this._extensions; _i < _a.length; _i++) { + var extension = _a[_i]; + if (extension.enabled) { + action(extension); + } + } + }; + GLTFLoader.prototype._applyExtensions = function (property, functionName, actionAsync) { + for (var _i = 0, _a = this._extensions; _i < _a.length; _i++) { + var extension = _a[_i]; + if (extension.enabled) { + var id = "".concat(extension.name, ".").concat(functionName); + var loaderProperty = property; + loaderProperty._activeLoaderExtensionFunctions = loaderProperty._activeLoaderExtensionFunctions || {}; + var activeLoaderExtensionFunctions = loaderProperty._activeLoaderExtensionFunctions; + if (!activeLoaderExtensionFunctions[id]) { + activeLoaderExtensionFunctions[id] = true; + try { + var result = actionAsync(extension); + if (result) { + return result; + } + } + finally { + delete activeLoaderExtensionFunctions[id]; + } + } + } + } + return null; + }; + GLTFLoader.prototype._extensionsOnLoading = function () { + this._forEachExtensions(function (extension) { return extension.onLoading && extension.onLoading(); }); + }; + GLTFLoader.prototype._extensionsOnReady = function () { + this._forEachExtensions(function (extension) { return extension.onReady && extension.onReady(); }); + }; + GLTFLoader.prototype._extensionsLoadSceneAsync = function (context, scene) { + return this._applyExtensions(scene, "loadScene", function (extension) { return extension.loadSceneAsync && extension.loadSceneAsync(context, scene); }); + }; + GLTFLoader.prototype._extensionsLoadNodeAsync = function (context, node, assign) { + return this._applyExtensions(node, "loadNode", function (extension) { return extension.loadNodeAsync && extension.loadNodeAsync(context, node, assign); }); + }; + GLTFLoader.prototype._extensionsLoadCameraAsync = function (context, camera, assign) { + return this._applyExtensions(camera, "loadCamera", function (extension) { return extension.loadCameraAsync && extension.loadCameraAsync(context, camera, assign); }); + }; + GLTFLoader.prototype._extensionsLoadVertexDataAsync = function (context, primitive, babylonMesh) { + return this._applyExtensions(primitive, "loadVertexData", function (extension) { return extension._loadVertexDataAsync && extension._loadVertexDataAsync(context, primitive, babylonMesh); }); + }; + GLTFLoader.prototype._extensionsLoadMeshPrimitiveAsync = function (context, name, node, mesh, primitive, assign) { + return this._applyExtensions(primitive, "loadMeshPrimitive", function (extension) { return extension._loadMeshPrimitiveAsync && extension._loadMeshPrimitiveAsync(context, name, node, mesh, primitive, assign); }); + }; + GLTFLoader.prototype._extensionsLoadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) { + return this._applyExtensions(material, "loadMaterial", function (extension) { return extension._loadMaterialAsync && extension._loadMaterialAsync(context, material, babylonMesh, babylonDrawMode, assign); }); + }; + GLTFLoader.prototype._extensionsCreateMaterial = function (context, material, babylonDrawMode) { + return this._applyExtensions(material, "createMaterial", function (extension) { return extension.createMaterial && extension.createMaterial(context, material, babylonDrawMode); }); + }; + GLTFLoader.prototype._extensionsLoadMaterialPropertiesAsync = function (context, material, babylonMaterial) { + return this._applyExtensions(material, "loadMaterialProperties", function (extension) { return extension.loadMaterialPropertiesAsync && extension.loadMaterialPropertiesAsync(context, material, babylonMaterial); }); + }; + GLTFLoader.prototype._extensionsLoadTextureInfoAsync = function (context, textureInfo, assign) { + return this._applyExtensions(textureInfo, "loadTextureInfo", function (extension) { return extension.loadTextureInfoAsync && extension.loadTextureInfoAsync(context, textureInfo, assign); }); + }; + GLTFLoader.prototype._extensionsLoadTextureAsync = function (context, texture, assign) { + return this._applyExtensions(texture, "loadTexture", function (extension) { return extension._loadTextureAsync && extension._loadTextureAsync(context, texture, assign); }); + }; + GLTFLoader.prototype._extensionsLoadAnimationAsync = function (context, animation) { + return this._applyExtensions(animation, "loadAnimation", function (extension) { return extension.loadAnimationAsync && extension.loadAnimationAsync(context, animation); }); + }; + GLTFLoader.prototype._extensionsLoadAnimationChannelAsync = function (context, animationContext, animation, channel, onLoad) { + return this._applyExtensions(animation, "loadAnimationChannel", function (extension) { return extension._loadAnimationChannelAsync && extension._loadAnimationChannelAsync(context, animationContext, animation, channel, onLoad); }); + }; + GLTFLoader.prototype._extensionsLoadSkinAsync = function (context, node, skin) { + return this._applyExtensions(skin, "loadSkin", function (extension) { return extension._loadSkinAsync && extension._loadSkinAsync(context, node, skin); }); + }; + GLTFLoader.prototype._extensionsLoadUriAsync = function (context, property, uri) { + return this._applyExtensions(property, "loadUri", function (extension) { return extension._loadUriAsync && extension._loadUriAsync(context, property, uri); }); + }; + GLTFLoader.prototype._extensionsLoadBufferViewAsync = function (context, bufferView) { + return this._applyExtensions(bufferView, "loadBufferView", function (extension) { return extension.loadBufferViewAsync && extension.loadBufferViewAsync(context, bufferView); }); + }; + GLTFLoader.prototype._extensionsLoadBufferAsync = function (context, buffer, byteOffset, byteLength) { + return this._applyExtensions(buffer, "loadBuffer", function (extension) { return extension.loadBufferAsync && extension.loadBufferAsync(context, buffer, byteOffset, byteLength); }); + }; + /** + * Helper method called by a loader extension to load an glTF extension. + * @param context The context when loading the asset + * @param property The glTF property to load the extension from + * @param extensionName The name of the extension to load + * @param actionAsync The action to run + * @returns The promise returned by actionAsync or null if the extension does not exist + */ + GLTFLoader.LoadExtensionAsync = function (context, property, extensionName, actionAsync) { + if (!property.extensions) { + return null; + } + var extensions = property.extensions; + var extension = extensions[extensionName]; + if (!extension) { + return null; + } + return actionAsync("".concat(context, "/extensions/").concat(extensionName), extension); + }; + /** + * Helper method called by a loader extension to load a glTF extra. + * @param context The context when loading the asset + * @param property The glTF property to load the extra from + * @param extensionName The name of the extension to load + * @param actionAsync The action to run + * @returns The promise returned by actionAsync or null if the extra does not exist + */ + GLTFLoader.LoadExtraAsync = function (context, property, extensionName, actionAsync) { + if (!property.extras) { + return null; + } + var extras = property.extras; + var extra = extras[extensionName]; + if (!extra) { + return null; + } + return actionAsync("".concat(context, "/extras/").concat(extensionName), extra); + }; + /** + * Checks for presence of an extension. + * @param name The name of the extension to check + * @returns A boolean indicating the presence of the given extension name in `extensionsUsed` + */ + GLTFLoader.prototype.isExtensionUsed = function (name) { + return !!this._gltf.extensionsUsed && this._gltf.extensionsUsed.indexOf(name) !== -1; + }; + /** + * Increments the indentation level and logs a message. + * @param message The message to log + */ + GLTFLoader.prototype.logOpen = function (message) { + this._parent._logOpen(message); + }; + /** + * Decrements the indentation level. + */ + GLTFLoader.prototype.logClose = function () { + this._parent._logClose(); + }; + /** + * Logs a message + * @param message The message to log + */ + GLTFLoader.prototype.log = function (message) { + this._parent._log(message); + }; + /** + * Starts a performance counter. + * @param counterName The name of the performance counter + */ + GLTFLoader.prototype.startPerformanceCounter = function (counterName) { + this._parent._startPerformanceCounter(counterName); + }; + /** + * Ends a performance counter. + * @param counterName The name of the performance counter + */ + GLTFLoader.prototype.endPerformanceCounter = function (counterName) { + this._parent._endPerformanceCounter(counterName); + }; + /** + * The default glTF sampler. + */ + GLTFLoader.DefaultSampler = { index: -1 }; + return GLTFLoader; +}()); + +_glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__.GLTFFileLoader._CreateGLTF2Loader = function (parent) { return new GLTFLoader(parent); }; + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/glTFLoaderAnimation.ts": +/*!****************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/glTFLoaderAnimation.ts ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ AnimationPropertyInfo: () => (/* binding */ AnimationPropertyInfo), +/* harmony export */ TransformNodeAnimationPropertyInfo: () => (/* binding */ TransformNodeAnimationPropertyInfo), +/* harmony export */ WeightAnimationPropertyInfo: () => (/* binding */ WeightAnimationPropertyInfo), +/* harmony export */ getQuaternion: () => (/* binding */ getQuaternion), +/* harmony export */ getVector3: () => (/* binding */ getVector3), +/* harmony export */ getWeights: () => (/* binding */ getWeights), +/* harmony export */ nodeAnimationData: () => (/* binding */ nodeAnimationData) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__); + + + +/** @internal */ +function getVector3(_target, source, offset, scale) { + return babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Vector3.FromArray(source, offset).scaleInPlace(scale); +} +/** @internal */ +function getQuaternion(_target, source, offset, scale) { + return babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Quaternion.FromArray(source, offset).scaleInPlace(scale); +} +/** @internal */ +function getWeights(target, source, offset, scale) { + var value = new Array(target._numMorphTargets); + for (var i = 0; i < value.length; i++) { + value[i] = source[offset++] * scale; + } + return value; +} +/** @internal */ +var AnimationPropertyInfo = /** @class */ (function () { + /** @internal */ + function AnimationPropertyInfo(type, name, getValue, getStride) { + this.type = type; + this.name = name; + this.getValue = getValue; + this.getStride = getStride; + } + AnimationPropertyInfo.prototype._buildAnimation = function (name, fps, keys) { + var babylonAnimation = new babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation(name, this.name, fps, this.type); + babylonAnimation.setKeys(keys); + return babylonAnimation; + }; + return AnimationPropertyInfo; +}()); + +/** @internal */ +var TransformNodeAnimationPropertyInfo = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__extends)(TransformNodeAnimationPropertyInfo, _super); + function TransformNodeAnimationPropertyInfo() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** @internal */ + TransformNodeAnimationPropertyInfo.prototype.buildAnimations = function (target, name, fps, keys, callback) { + callback(target._babylonTransformNode, this._buildAnimation(name, fps, keys)); + }; + return TransformNodeAnimationPropertyInfo; +}(AnimationPropertyInfo)); + +/** @internal */ +var WeightAnimationPropertyInfo = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_1__.__extends)(WeightAnimationPropertyInfo, _super); + function WeightAnimationPropertyInfo() { + return _super !== null && _super.apply(this, arguments) || this; + } + WeightAnimationPropertyInfo.prototype.buildAnimations = function (target, name, fps, keys, callback) { + if (target._numMorphTargets) { + var _loop_1 = function (targetIndex) { + var babylonAnimation = new babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation("".concat(name, "_").concat(targetIndex), this_1.name, fps, this_1.type); + babylonAnimation.setKeys(keys.map(function (key) { return ({ + frame: key.frame, + inTangent: key.inTangent ? key.inTangent[targetIndex] : undefined, + value: key.value[targetIndex], + outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined, + interpolation: key.interpolation, + }); })); + if (target._primitiveBabylonMeshes) { + for (var _i = 0, _a = target._primitiveBabylonMeshes; _i < _a.length; _i++) { + var babylonMesh = _a[_i]; + if (babylonMesh.morphTargetManager) { + var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex); + var babylonAnimationClone = babylonAnimation.clone(); + morphTarget.animations.push(babylonAnimationClone); + callback(morphTarget, babylonAnimationClone); + } + } + } + }; + var this_1 = this; + for (var targetIndex = 0; targetIndex < target._numMorphTargets; targetIndex++) { + _loop_1(targetIndex); + } + } + }; + return WeightAnimationPropertyInfo; +}(AnimationPropertyInfo)); + +/** @internal */ +var nodeAnimationData = { + translation: [new TransformNodeAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_VECTOR3, "position", getVector3, function () { return 3; })], + rotation: [new TransformNodeAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_QUATERNION, "rotationQuaternion", getQuaternion, function () { return 4; })], + scale: [new TransformNodeAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_VECTOR3, "scaling", getVector3, function () { return 3; })], + weights: [new WeightAnimationPropertyInfo(babylonjs_Animations_animation__WEBPACK_IMPORTED_MODULE_0__.Animation.ANIMATIONTYPE_FLOAT, "influence", getWeights, function (target) { return target._numMorphTargets; })], +}; + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtension.ts": +/*!****************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/glTFLoaderExtension.ts ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); + + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts": +/*!************************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts ***! + \************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ registerGLTFExtension: () => (/* binding */ registerGLTFExtension), +/* harmony export */ registeredGLTFExtensions: () => (/* binding */ registeredGLTFExtensions), +/* harmony export */ unregisterGLTFExtension: () => (/* binding */ unregisterGLTFExtension) +/* harmony export */ }); +/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__); + +var _registeredGLTFExtensions = new Map(); +/** + * All currently registered glTF 2.0 loader extensions. + */ +var registeredGLTFExtensions = _registeredGLTFExtensions; +/** + * Registers a loader extension. + * @param name The name of the loader extension. + * @param isGLTFExtension If the loader extension is a glTF extension, then it will only be used for glTF files that use the corresponding glTF extension. Otherwise, it will be used for all loaded glTF files. + * @param factory The factory function that creates the loader extension. + */ +function registerGLTFExtension(name, isGLTFExtension, factory) { + if (unregisterGLTFExtension(name)) { + babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("Extension with the name '".concat(name, "' already exists")); + } + _registeredGLTFExtensions.set(name, { + isGLTFExtension: isGLTFExtension, + factory: factory, + }); +} +/** + * Unregisters a loader extension. + * @param name The name of the loader extension. + * @returns A boolean indicating whether the extension has been unregistered + */ +function unregisterGLTFExtension(name) { + return _registeredGLTFExtensions.delete(name); +} + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/glTFLoaderInterfaces.ts": +/*!*****************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/glTFLoaderInterfaces.ts ***! + \*****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); + + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/2.0/index.ts": +/*!**************************************************!*\ + !*** ../../../dev/loaders/src/glTF/2.0/index.ts ***! + \**************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ ArrayItem: () => (/* reexport safe */ _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.ArrayItem), +/* harmony export */ EXT_lights_image_based: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.EXT_lights_image_based), +/* harmony export */ EXT_mesh_gpu_instancing: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.EXT_mesh_gpu_instancing), +/* harmony export */ EXT_meshopt_compression: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.EXT_meshopt_compression), +/* harmony export */ EXT_texture_avif: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.EXT_texture_avif), +/* harmony export */ EXT_texture_webp: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.EXT_texture_webp), +/* harmony export */ ExtrasAsMetadata: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.ExtrasAsMetadata), +/* harmony export */ GLTFFileLoader: () => (/* reexport safe */ _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFFileLoader), +/* harmony export */ GLTFLoader: () => (/* reexport safe */ _glTFLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoader), +/* harmony export */ KHR_animation_pointer: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_animation_pointer), +/* harmony export */ KHR_draco_mesh_compression: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_draco_mesh_compression), +/* harmony export */ KHR_interactivity: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_interactivity), +/* harmony export */ KHR_lights: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_lights), +/* harmony export */ KHR_materials_anisotropy: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_anisotropy), +/* harmony export */ KHR_materials_clearcoat: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_clearcoat), +/* harmony export */ KHR_materials_diffuse_transmission: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_diffuse_transmission), +/* harmony export */ KHR_materials_dispersion: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_dispersion), +/* harmony export */ KHR_materials_emissive_strength: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_emissive_strength), +/* harmony export */ KHR_materials_ior: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_ior), +/* harmony export */ KHR_materials_iridescence: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_iridescence), +/* harmony export */ KHR_materials_pbrSpecularGlossiness: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_pbrSpecularGlossiness), +/* harmony export */ KHR_materials_sheen: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_sheen), +/* harmony export */ KHR_materials_specular: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_specular), +/* harmony export */ KHR_materials_transmission: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_transmission), +/* harmony export */ KHR_materials_unlit: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_unlit), +/* harmony export */ KHR_materials_variants: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_variants), +/* harmony export */ KHR_materials_volume: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_materials_volume), +/* harmony export */ KHR_mesh_quantization: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_mesh_quantization), +/* harmony export */ KHR_node_visibility: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_node_visibility), +/* harmony export */ KHR_texture_basisu: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_texture_basisu), +/* harmony export */ KHR_texture_transform: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_texture_transform), +/* harmony export */ KHR_xmp_json_ld: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.KHR_xmp_json_ld), +/* harmony export */ MSFT_audio_emitter: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.MSFT_audio_emitter), +/* harmony export */ MSFT_lod: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.MSFT_lod), +/* harmony export */ MSFT_minecraftMesh: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.MSFT_minecraftMesh), +/* harmony export */ MSFT_sRGBFactors: () => (/* reexport safe */ _Extensions_index__WEBPACK_IMPORTED_MODULE_4__.MSFT_sRGBFactors), +/* harmony export */ registerGLTFExtension: () => (/* reexport safe */ _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registerGLTFExtension), +/* harmony export */ registeredGLTFExtensions: () => (/* reexport safe */ _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.registeredGLTFExtensions), +/* harmony export */ unregisterGLTFExtension: () => (/* reexport safe */ _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__.unregisterGLTFExtension) +/* harmony export */ }); +/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./glTFLoader */ "../../../dev/loaders/src/glTF/2.0/glTFLoader.ts"); +/* harmony import */ var _glTFLoaderExtension__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./glTFLoaderExtension */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtension.ts"); +/* harmony import */ var _glTFLoaderExtensionRegistry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glTFLoaderExtensionRegistry */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderExtensionRegistry.ts"); +/* harmony import */ var _glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./glTFLoaderInterfaces */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderInterfaces.ts"); +/* harmony import */ var _Extensions_index__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Extensions/index */ "../../../dev/loaders/src/glTF/2.0/Extensions/index.ts"); +/* eslint-disable import/no-internal-modules */ + + + + + + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/glTFFileLoader.metadata.ts": +/*!****************************************************************!*\ + !*** ../../../dev/loaders/src/glTF/glTFFileLoader.metadata.ts ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFFileLoaderMetadata: () => (/* binding */ GLTFFileLoaderMetadata), +/* harmony export */ GLTFMagicBase64Encoded: () => (/* binding */ GLTFMagicBase64Encoded) +/* harmony export */ }); +var GLTFMagicBase64Encoded = "Z2xURg"; // "glTF" base64 encoded (without the quotes!) +var GLTFFileLoaderMetadata = { + name: "gltf", + extensions: { + // eslint-disable-next-line @typescript-eslint/naming-convention + ".gltf": { isBinary: false, mimeType: "model/gltf+json" }, + // eslint-disable-next-line @typescript-eslint/naming-convention + ".glb": { isBinary: true, mimeType: "model/gltf-binary" }, + }, + canDirectLoad: function (data) { + return ((data.indexOf("asset") !== -1 && data.indexOf("version") !== -1) || + data.startsWith("data:base64," + GLTFMagicBase64Encoded) || // this is technically incorrect, but will continue to support for backcompat. + data.startsWith("data:;base64," + GLTFMagicBase64Encoded) || + data.startsWith("data:application/octet-stream;base64," + GLTFMagicBase64Encoded) || + data.startsWith("data:model/gltf-binary;base64," + GLTFMagicBase64Encoded)); + }, +}; + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/glTFFileLoader.ts": +/*!*******************************************************!*\ + !*** ../../../dev/loaders/src/glTF/glTFFileLoader.ts ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFFileLoader: () => (/* binding */ GLTFFileLoader), +/* harmony export */ GLTFLoaderAnimationStartMode: () => (/* binding */ GLTFLoaderAnimationStartMode), +/* harmony export */ GLTFLoaderCoordinateSystemMode: () => (/* binding */ GLTFLoaderCoordinateSystemMode), +/* harmony export */ GLTFLoaderState: () => (/* binding */ GLTFLoaderState) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tslib */ "../../../../node_modules/tslib/tslib.es6.mjs"); +/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/error */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _glTFValidation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./glTFValidation */ "../../../dev/loaders/src/glTF/glTFValidation.ts"); +/* harmony import */ var _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glTFFileLoader.metadata */ "../../../dev/loaders/src/glTF/glTFFileLoader.metadata.ts"); + + + + + + + + + + + +function readAsync(arrayBuffer, byteOffset, byteLength) { + try { + return Promise.resolve(new Uint8Array(arrayBuffer, byteOffset, byteLength)); + } + catch (e) { + return Promise.reject(e); + } +} +function readViewAsync(arrayBufferView, byteOffset, byteLength) { + try { + if (byteOffset < 0 || byteOffset >= arrayBufferView.byteLength) { + throw new RangeError("Offset is out of range."); + } + if (byteOffset + byteLength > arrayBufferView.byteLength) { + throw new RangeError("Length is out of range."); + } + return Promise.resolve(new Uint8Array(arrayBufferView.buffer, arrayBufferView.byteOffset + byteOffset, byteLength)); + } + catch (e) { + return Promise.reject(e); + } +} +/** + * Mode that determines the coordinate system to use. + */ +var GLTFLoaderCoordinateSystemMode; +(function (GLTFLoaderCoordinateSystemMode) { + /** + * Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene. + */ + GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["AUTO"] = 0] = "AUTO"; + /** + * Sets the useRightHandedSystem flag on the scene. + */ + GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["FORCE_RIGHT_HANDED"] = 1] = "FORCE_RIGHT_HANDED"; +})(GLTFLoaderCoordinateSystemMode || (GLTFLoaderCoordinateSystemMode = {})); +/** + * Mode that determines what animations will start. + */ +var GLTFLoaderAnimationStartMode; +(function (GLTFLoaderAnimationStartMode) { + /** + * No animation will start. + */ + GLTFLoaderAnimationStartMode[GLTFLoaderAnimationStartMode["NONE"] = 0] = "NONE"; + /** + * The first animation will start. + */ + GLTFLoaderAnimationStartMode[GLTFLoaderAnimationStartMode["FIRST"] = 1] = "FIRST"; + /** + * All animations will start. + */ + GLTFLoaderAnimationStartMode[GLTFLoaderAnimationStartMode["ALL"] = 2] = "ALL"; +})(GLTFLoaderAnimationStartMode || (GLTFLoaderAnimationStartMode = {})); +/** + * Loader state. + */ +var GLTFLoaderState; +(function (GLTFLoaderState) { + /** + * The asset is loading. + */ + GLTFLoaderState[GLTFLoaderState["LOADING"] = 0] = "LOADING"; + /** + * The asset is ready for rendering. + */ + GLTFLoaderState[GLTFLoaderState["READY"] = 1] = "READY"; + /** + * The asset is completely loaded. + */ + GLTFLoaderState[GLTFLoaderState["COMPLETE"] = 2] = "COMPLETE"; +})(GLTFLoaderState || (GLTFLoaderState = {})); +var GLTFLoaderOptions = /** @class */ (function () { + function GLTFLoaderOptions() { + // ---------- + // V2 options + // ---------- + /** + * The coordinate system mode. Defaults to AUTO. + */ + this.coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO; + /** + * The animation start mode. Defaults to FIRST. + */ + this.animationStartMode = GLTFLoaderAnimationStartMode.FIRST; + /** + * Defines if the loader should load node animations. Defaults to true. + * NOTE: The animation of this node will still load if the node is also a joint of a skin and `loadSkins` is true. + */ + this.loadNodeAnimations = true; + /** + * Defines if the loader should load skins. Defaults to true. + */ + this.loadSkins = true; + /** + * Defines if the loader should load morph targets. Defaults to true. + */ + this.loadMorphTargets = true; + /** + * Defines if the loader should compile materials before raising the success callback. Defaults to false. + */ + this.compileMaterials = false; + /** + * Defines if the loader should also compile materials with clip planes. Defaults to false. + */ + this.useClipPlane = false; + /** + * Defines if the loader should compile shadow generators before raising the success callback. Defaults to false. + */ + this.compileShadowGenerators = false; + /** + * Defines if the Alpha blended materials are only applied as coverage. + * If false, (default) The luminance of each pixel will reduce its opacity to simulate the behaviour of most physical materials. + * If true, no extra effects are applied to transparent pixels. + */ + this.transparencyAsCoverage = false; + /** + * Defines if the loader should use range requests when load binary glTF files from HTTP. + * Enabling will disable offline support and glTF validator. + * Defaults to false. + */ + this.useRangeRequests = false; + /** + * Defines if the loader should create instances when multiple glTF nodes point to the same glTF mesh. Defaults to true. + */ + this.createInstances = true; + /** + * Defines if the loader should always compute the bounding boxes of meshes and not use the min/max values from the position accessor. Defaults to false. + */ + this.alwaysComputeBoundingBox = false; + /** + * If true, load all materials defined in the file, even if not used by any mesh. Defaults to false. + */ + this.loadAllMaterials = false; + /** + * If true, load only the materials defined in the file. Defaults to false. + */ + this.loadOnlyMaterials = false; + /** + * If true, do not load any materials defined in the file. Defaults to false. + */ + this.skipMaterials = false; + /** + * If true, load the color (gamma encoded) textures into sRGB buffers (if supported by the GPU), which will yield more accurate results when sampling the texture. Defaults to true. + */ + this.useSRGBBuffers = true; + /** + * When loading glTF animations, which are defined in seconds, target them to this FPS. Defaults to 60. + */ + this.targetFps = 60; + /** + * Defines if the loader should always compute the nearest common ancestor of the skeleton joints instead of using `skin.skeleton`. Defaults to false. + * Set this to true if loading assets with invalid `skin.skeleton` values. + */ + this.alwaysComputeSkeletonRootNode = false; + /** + * If true, the loader will derive the name for Babylon textures from the glTF texture name, image name, or image url. Defaults to false. + * Note that it is possible for multiple Babylon textures to share the same name when the Babylon textures load from the same glTF texture or image. + */ + this.useGltfTextureNames = false; + /** + * Function called before loading a url referenced by the asset. + * @param url url referenced by the asset + * @returns Async url to load + */ + this.preprocessUrlAsync = function (url) { return Promise.resolve(url); }; + /** + * Defines options for glTF extensions. + */ + this.extensionOptions = {}; + } + // eslint-disable-next-line babylonjs/available + GLTFLoaderOptions.prototype.copyFrom = function (options) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w; + if (options) { + this.onParsed = options.onParsed; + this.coordinateSystemMode = (_a = options.coordinateSystemMode) !== null && _a !== void 0 ? _a : this.coordinateSystemMode; + this.animationStartMode = (_b = options.animationStartMode) !== null && _b !== void 0 ? _b : this.animationStartMode; + this.loadNodeAnimations = (_c = options.loadNodeAnimations) !== null && _c !== void 0 ? _c : this.loadNodeAnimations; + this.loadSkins = (_d = options.loadSkins) !== null && _d !== void 0 ? _d : this.loadSkins; + this.loadMorphTargets = (_e = options.loadMorphTargets) !== null && _e !== void 0 ? _e : this.loadMorphTargets; + this.compileMaterials = (_f = options.compileMaterials) !== null && _f !== void 0 ? _f : this.compileMaterials; + this.useClipPlane = (_g = options.useClipPlane) !== null && _g !== void 0 ? _g : this.useClipPlane; + this.compileShadowGenerators = (_h = options.compileShadowGenerators) !== null && _h !== void 0 ? _h : this.compileShadowGenerators; + this.transparencyAsCoverage = (_j = options.transparencyAsCoverage) !== null && _j !== void 0 ? _j : this.transparencyAsCoverage; + this.useRangeRequests = (_k = options.useRangeRequests) !== null && _k !== void 0 ? _k : this.useRangeRequests; + this.createInstances = (_l = options.createInstances) !== null && _l !== void 0 ? _l : this.createInstances; + this.alwaysComputeBoundingBox = (_m = options.alwaysComputeBoundingBox) !== null && _m !== void 0 ? _m : this.alwaysComputeBoundingBox; + this.loadAllMaterials = (_o = options.loadAllMaterials) !== null && _o !== void 0 ? _o : this.loadAllMaterials; + this.loadOnlyMaterials = (_p = options.loadOnlyMaterials) !== null && _p !== void 0 ? _p : this.loadOnlyMaterials; + this.skipMaterials = (_q = options.skipMaterials) !== null && _q !== void 0 ? _q : this.skipMaterials; + this.useSRGBBuffers = (_r = options.useSRGBBuffers) !== null && _r !== void 0 ? _r : this.useSRGBBuffers; + this.targetFps = (_s = options.targetFps) !== null && _s !== void 0 ? _s : this.targetFps; + this.alwaysComputeSkeletonRootNode = (_t = options.alwaysComputeSkeletonRootNode) !== null && _t !== void 0 ? _t : this.alwaysComputeSkeletonRootNode; + this.useGltfTextureNames = (_u = options.useGltfTextureNames) !== null && _u !== void 0 ? _u : this.useGltfTextureNames; + this.preprocessUrlAsync = (_v = options.preprocessUrlAsync) !== null && _v !== void 0 ? _v : this.preprocessUrlAsync; + this.customRootNode = options.customRootNode; + this.onMeshLoaded = options.onMeshLoaded; + this.onSkinLoaded = options.onSkinLoaded; + this.onTextureLoaded = options.onTextureLoaded; + this.onMaterialLoaded = options.onMaterialLoaded; + this.onCameraLoaded = options.onCameraLoaded; + this.extensionOptions = (_w = options.extensionOptions) !== null && _w !== void 0 ? _w : this.extensionOptions; + } + }; + return GLTFLoaderOptions; +}()); +/** + * File loader for loading glTF files into a scene. + */ +var GLTFFileLoader = /** @class */ (function (_super) { + (0,tslib__WEBPACK_IMPORTED_MODULE_3__.__extends)(GLTFFileLoader, _super); + /** + * Creates a new glTF file loader. + * @param options The options for the loader + */ + function GLTFFileLoader(options) { + var _this = _super.call(this) || this; + // -------------------- + // Begin Common options + // -------------------- + /** + * Raised when the asset has been parsed + */ + _this.onParsedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + // -------------- + // End V1 options + // -------------- + /** + * Observable raised when the loader creates a mesh after parsing the glTF properties of the mesh. + * Note that the observable is raised as soon as the mesh object is created, meaning some data may not have been setup yet for this mesh (vertex data, morph targets, material, ...) + */ + _this.onMeshLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when the loader creates a skin after parsing the glTF properties of the skin node. + * @see https://doc.babylonjs.com/features/featuresDeepDive/importers/glTF/glTFSkinning#ignoring-the-transform-of-the-skinned-mesh + * @param node - the transform node that corresponds to the original glTF skin node used for animations + * @param skinnedNode - the transform node that is the skinned mesh itself or the parent of the skinned meshes + */ + _this.onSkinLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when the loader creates a texture after parsing the glTF properties of the texture. + */ + _this.onTextureLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when the loader creates a material after parsing the glTF properties of the material. + */ + _this.onMaterialLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when the loader creates a camera after parsing the glTF properties of the camera. + */ + _this.onCameraLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when the asset is completely loaded, immediately before the loader is disposed. + * For assets with LODs, raised when all of the LODs are complete. + * For assets without LODs, raised when the model is complete, immediately after the loader resolves the returned promise. + */ + _this.onCompleteObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised when an error occurs. + */ + _this.onErrorObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised after the loader is disposed. + */ + _this.onDisposeObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Observable raised after a loader extension is created. + * Set additional options for a loader extension in this event. + */ + _this.onExtensionLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + /** + * Defines if the loader should validate the asset. + */ + _this.validate = false; + /** + * Observable raised after validation when validate is set to true. The event data is the result of the validation. + */ + _this.onValidatedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + _this._loader = null; + _this._state = null; + _this._requests = new Array(); + /** + * Name of the loader ("gltf") + */ + _this.name = _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFFileLoaderMetadata.name; + /** @internal */ + _this.extensions = _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFFileLoaderMetadata.extensions; + /** + * Observable raised when the loader state changes. + */ + _this.onLoaderStateChangedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(); + _this._logIndentLevel = 0; + _this._loggingEnabled = false; + /** @internal */ + _this._log = _this._logDisabled; + _this._capturePerformanceCounters = false; + /** @internal */ + _this._startPerformanceCounter = _this._startPerformanceCounterDisabled; + /** @internal */ + _this._endPerformanceCounter = _this._endPerformanceCounterDisabled; + _this.copyFrom(options); + return _this; + } + Object.defineProperty(GLTFFileLoader.prototype, "onParsed", { + /** + * Raised when the asset has been parsed + */ + set: function (callback) { + if (this._onParsedObserver) { + this.onParsedObservable.remove(this._onParsedObserver); + } + if (callback) { + this._onParsedObserver = this.onParsedObservable.add(callback); + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onMeshLoaded", { + /** + * Callback raised when the loader creates a mesh after parsing the glTF properties of the mesh. + * Note that the callback is called as soon as the mesh object is created, meaning some data may not have been setup yet for this mesh (vertex data, morph targets, material, ...) + */ + set: function (callback) { + if (this._onMeshLoadedObserver) { + this.onMeshLoadedObservable.remove(this._onMeshLoadedObserver); + } + if (callback) { + this._onMeshLoadedObserver = this.onMeshLoadedObservable.add(callback); + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onSkinLoaded", { + /** + * Callback raised when the loader creates a skin after parsing the glTF properties of the skin node. + * @see https://doc.babylonjs.com/features/featuresDeepDive/importers/glTF/glTFSkinning#ignoring-the-transform-of-the-skinned-mesh + */ + set: function (callback) { + if (this._onSkinLoadedObserver) { + this.onSkinLoadedObservable.remove(this._onSkinLoadedObserver); + } + if (callback) { + this._onSkinLoadedObserver = this.onSkinLoadedObservable.add(function (data) { return callback(data.node, data.skinnedNode); }); + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onTextureLoaded", { + /** + * Callback raised when the loader creates a texture after parsing the glTF properties of the texture. + */ + set: function (callback) { + if (this._onTextureLoadedObserver) { + this.onTextureLoadedObservable.remove(this._onTextureLoadedObserver); + } + if (callback) { + this._onTextureLoadedObserver = this.onTextureLoadedObservable.add(callback); + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onMaterialLoaded", { + /** + * Callback raised when the loader creates a material after parsing the glTF properties of the material. + */ + set: function (callback) { + if (this._onMaterialLoadedObserver) { + this.onMaterialLoadedObservable.remove(this._onMaterialLoadedObserver); + } + if (callback) { + this._onMaterialLoadedObserver = this.onMaterialLoadedObservable.add(callback); + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onCameraLoaded", { + /** + * Callback raised when the loader creates a camera after parsing the glTF properties of the camera. + */ + set: function (callback) { + if (this._onCameraLoadedObserver) { + this.onCameraLoadedObservable.remove(this._onCameraLoadedObserver); + } + if (callback) { + this._onCameraLoadedObserver = this.onCameraLoadedObservable.add(callback); + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onComplete", { + /** + * Callback raised when the asset is completely loaded, immediately before the loader is disposed. + * For assets with LODs, raised when all of the LODs are complete. + * For assets without LODs, raised when the model is complete, immediately after the loader resolves the returned promise. + */ + set: function (callback) { + if (this._onCompleteObserver) { + this.onCompleteObservable.remove(this._onCompleteObserver); + } + this._onCompleteObserver = this.onCompleteObservable.add(callback); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onError", { + /** + * Callback raised when an error occurs. + */ + set: function (callback) { + if (this._onErrorObserver) { + this.onErrorObservable.remove(this._onErrorObserver); + } + this._onErrorObserver = this.onErrorObservable.add(callback); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onDispose", { + /** + * Callback raised after the loader is disposed. + */ + set: function (callback) { + if (this._onDisposeObserver) { + this.onDisposeObservable.remove(this._onDisposeObserver); + } + this._onDisposeObserver = this.onDisposeObservable.add(callback); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", { + /** + * Callback raised after a loader extension is created. + */ + set: function (callback) { + if (this._onExtensionLoadedObserver) { + this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver); + } + this._onExtensionLoadedObserver = this.onExtensionLoadedObservable.add(callback); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "loggingEnabled", { + /** + * Defines if the loader logging is enabled. + */ + get: function () { + return this._loggingEnabled; + }, + set: function (value) { + if (this._loggingEnabled === value) { + return; + } + this._loggingEnabled = value; + if (this._loggingEnabled) { + this._log = this._logEnabled; + } + else { + this._log = this._logDisabled; + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "capturePerformanceCounters", { + /** + * Defines if the loader should capture performance counters. + */ + get: function () { + return this._capturePerformanceCounters; + }, + set: function (value) { + if (this._capturePerformanceCounters === value) { + return; + } + this._capturePerformanceCounters = value; + if (this._capturePerformanceCounters) { + this._startPerformanceCounter = this._startPerformanceCounterEnabled; + this._endPerformanceCounter = this._endPerformanceCounterEnabled; + } + else { + this._startPerformanceCounter = this._startPerformanceCounterDisabled; + this._endPerformanceCounter = this._endPerformanceCounterDisabled; + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(GLTFFileLoader.prototype, "onValidated", { + /** + * Callback raised after a loader extension is created. + */ + set: function (callback) { + if (this._onValidatedObserver) { + this.onValidatedObservable.remove(this._onValidatedObserver); + } + this._onValidatedObserver = this.onValidatedObservable.add(callback); + }, + enumerable: false, + configurable: true + }); + /** + * Disposes the loader, releases resources during load, and cancels any outstanding requests. + */ + GLTFFileLoader.prototype.dispose = function () { + if (this._loader) { + this._loader.dispose(); + this._loader = null; + } + for (var _i = 0, _a = this._requests; _i < _a.length; _i++) { + var request = _a[_i]; + request.abort(); + } + this._requests.length = 0; + delete this._progressCallback; + this.preprocessUrlAsync = function (url) { return Promise.resolve(url); }; + this.onMeshLoadedObservable.clear(); + this.onSkinLoadedObservable.clear(); + this.onTextureLoadedObservable.clear(); + this.onMaterialLoadedObservable.clear(); + this.onCameraLoadedObservable.clear(); + this.onCompleteObservable.clear(); + this.onExtensionLoadedObservable.clear(); + this.onDisposeObservable.notifyObservers(undefined); + this.onDisposeObservable.clear(); + }; + /** + * @internal + */ + GLTFFileLoader.prototype.loadFile = function (scene, fileOrUrl, rootUrl, onSuccess, onProgress, useArrayBuffer, onError, name) { + var _this = this; + if (ArrayBuffer.isView(fileOrUrl)) { + this._loadBinary(scene, fileOrUrl, rootUrl, onSuccess, onError, name); + return null; + } + this._progressCallback = onProgress; + var fileName = fileOrUrl.name || babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Tools.GetFilename(fileOrUrl); + if (useArrayBuffer) { + if (this.useRangeRequests) { + if (this.validate) { + babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("glTF validation is not supported when range requests are enabled"); + } + var fileRequest_1 = { + abort: function () { }, + onCompleteObservable: new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Observable(), + }; + var dataBuffer = { + readAsync: function (byteOffset, byteLength) { + return new Promise(function (resolve, reject) { + _this._loadFile(scene, fileOrUrl, function (data) { + resolve(new Uint8Array(data)); + }, true, function (error) { + reject(error); + }, function (webRequest) { + webRequest.setRequestHeader("Range", "bytes=".concat(byteOffset, "-").concat(byteOffset + byteLength - 1)); + }); + }); + }, + byteLength: 0, + }; + this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.DataReader(dataBuffer)).then(function (loaderData) { + fileRequest_1.onCompleteObservable.notifyObservers(fileRequest_1); + onSuccess(loaderData); + }, onError ? function (error) { return onError(undefined, error); } : undefined); + return fileRequest_1; + } + return this._loadFile(scene, fileOrUrl, function (data) { + _this._validate(scene, new Uint8Array(data, 0, data.byteLength), rootUrl, fileName); + _this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.DataReader({ + readAsync: function (byteOffset, byteLength) { return readAsync(data, byteOffset, byteLength); }, + byteLength: data.byteLength, + })).then(function (loaderData) { + onSuccess(loaderData); + }, onError ? function (error) { return onError(undefined, error); } : undefined); + }, true, onError); + } + else { + return this._loadFile(scene, fileOrUrl, function (data) { + try { + _this._validate(scene, data, rootUrl, fileName); + onSuccess({ json: _this._parseJson(data) }); + } + catch (_a) { + if (onError) { + onError(); + } + } + }, false, onError); + } + }; + GLTFFileLoader.prototype._loadBinary = function (scene, data, rootUrl, onSuccess, onError, fileName) { + this._validate(scene, new Uint8Array(data.buffer, data.byteOffset, data.byteLength), rootUrl, fileName); + this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.DataReader({ + readAsync: function (byteOffset, byteLength) { return readViewAsync(data, byteOffset, byteLength); }, + byteLength: data.byteLength, + })).then(function (loaderData) { + onSuccess(loaderData); + }, onError ? function (error) { return onError(undefined, error); } : undefined); + }; + /** + * @internal + */ + GLTFFileLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress, fileName) { + var _this = this; + return Promise.resolve().then(function () { + _this.onParsedObservable.notifyObservers(data); + _this.onParsedObservable.clear(); + _this._log("Loading ".concat(fileName || "")); + _this._loader = _this._getLoader(data); + return _this._loader.importMeshAsync(meshesNames, scene, null, data, rootUrl, onProgress, fileName); + }); + }; + /** + * @internal + */ + GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress, fileName) { + var _this = this; + return Promise.resolve().then(function () { + _this.onParsedObservable.notifyObservers(data); + _this.onParsedObservable.clear(); + _this._log("Loading ".concat(fileName || "")); + _this._loader = _this._getLoader(data); + return _this._loader.loadAsync(scene, data, rootUrl, onProgress, fileName); + }); + }; + /** + * @internal + */ + GLTFFileLoader.prototype.loadAssetContainerAsync = function (scene, data, rootUrl, onProgress, fileName) { + var _this = this; + return Promise.resolve().then(function () { + _this.onParsedObservable.notifyObservers(data); + _this.onParsedObservable.clear(); + _this._log("Loading ".concat(fileName || "")); + _this._loader = _this._getLoader(data); + // Prepare the asset container. + var container = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.AssetContainer(scene); + // Get materials/textures when loading to add to container + var materials = []; + _this.onMaterialLoadedObservable.add(function (material) { + materials.push(material); + }); + var textures = []; + _this.onTextureLoadedObservable.add(function (texture) { + textures.push(texture); + }); + var cameras = []; + _this.onCameraLoadedObservable.add(function (camera) { + cameras.push(camera); + }); + var morphTargetManagers = []; + _this.onMeshLoadedObservable.add(function (mesh) { + if (mesh.morphTargetManager) { + morphTargetManagers.push(mesh.morphTargetManager); + } + }); + return _this._loader.importMeshAsync(null, scene, container, data, rootUrl, onProgress, fileName).then(function (result) { + Array.prototype.push.apply(container.geometries, result.geometries); + Array.prototype.push.apply(container.meshes, result.meshes); + Array.prototype.push.apply(container.particleSystems, result.particleSystems); + Array.prototype.push.apply(container.skeletons, result.skeletons); + Array.prototype.push.apply(container.animationGroups, result.animationGroups); + Array.prototype.push.apply(container.materials, materials); + Array.prototype.push.apply(container.textures, textures); + Array.prototype.push.apply(container.lights, result.lights); + Array.prototype.push.apply(container.transformNodes, result.transformNodes); + Array.prototype.push.apply(container.cameras, cameras); + Array.prototype.push.apply(container.morphTargetManagers, morphTargetManagers); + return container; + }); + }); + }; + /** + * @internal + */ + GLTFFileLoader.prototype.canDirectLoad = function (data) { + return _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFFileLoaderMetadata.canDirectLoad(data); + }; + /** + * @internal + */ + GLTFFileLoader.prototype.directLoad = function (scene, data) { + if (data.startsWith("base64," + _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFMagicBase64Encoded) || // this is technically incorrect, but will continue to support for backcompat. + data.startsWith(";base64," + _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFMagicBase64Encoded) || + data.startsWith("application/octet-stream;base64," + _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFMagicBase64Encoded) || + data.startsWith("model/gltf-binary;base64," + _glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFMagicBase64Encoded)) { + var arrayBuffer_1 = (0,babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.DecodeBase64UrlToBinary)(data); + this._validate(scene, new Uint8Array(arrayBuffer_1, 0, arrayBuffer_1.byteLength)); + return this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.DataReader({ + readAsync: function (byteOffset, byteLength) { return readAsync(arrayBuffer_1, byteOffset, byteLength); }, + byteLength: arrayBuffer_1.byteLength, + })); + } + this._validate(scene, data); + return Promise.resolve({ json: this._parseJson(data) }); + }; + /** @internal */ + GLTFFileLoader.prototype.createPlugin = function (options) { + return new GLTFFileLoader(options[_glTFFileLoader_metadata__WEBPACK_IMPORTED_MODULE_2__.GLTFFileLoaderMetadata.name]); + }; + Object.defineProperty(GLTFFileLoader.prototype, "loaderState", { + /** + * The loader state or null if the loader is not active. + */ + get: function () { + return this._state; + }, + enumerable: false, + configurable: true + }); + /** + * Returns a promise that resolves when the asset is completely loaded. + * @returns a promise that resolves when the asset is completely loaded. + */ + GLTFFileLoader.prototype.whenCompleteAsync = function () { + var _this = this; + return new Promise(function (resolve, reject) { + _this.onCompleteObservable.addOnce(function () { + resolve(); + }); + _this.onErrorObservable.addOnce(function (reason) { + reject(reason); + }); + }); + }; + /** + * @internal + */ + GLTFFileLoader.prototype._setState = function (state) { + if (this._state === state) { + return; + } + this._state = state; + this.onLoaderStateChangedObservable.notifyObservers(this._state); + this._log(GLTFLoaderState[this._state]); + }; + /** + * @internal + */ + GLTFFileLoader.prototype._loadFile = function (scene, fileOrUrl, onSuccess, useArrayBuffer, onError, onOpened) { + var _this = this; + var request = scene._loadFile(fileOrUrl, onSuccess, function (event) { + _this._onProgress(event, request); + }, true, useArrayBuffer, onError, onOpened); + request.onCompleteObservable.add(function () { + // Force the length computable to be true since we can guarantee the data is loaded. + request._lengthComputable = true; + request._total = request._loaded; + }); + this._requests.push(request); + return request; + }; + GLTFFileLoader.prototype._onProgress = function (event, request) { + if (!this._progressCallback) { + return; + } + request._lengthComputable = event.lengthComputable; + request._loaded = event.loaded; + request._total = event.total; + var lengthComputable = true; + var loaded = 0; + var total = 0; + for (var _i = 0, _a = this._requests; _i < _a.length; _i++) { + var request_1 = _a[_i]; + if (request_1._lengthComputable === undefined || request_1._loaded === undefined || request_1._total === undefined) { + return; + } + lengthComputable = lengthComputable && request_1._lengthComputable; + loaded += request_1._loaded; + total += request_1._total; + } + this._progressCallback({ + lengthComputable: lengthComputable, + loaded: loaded, + total: lengthComputable ? total : 0, + }); + }; + GLTFFileLoader.prototype._validate = function (scene, data, rootUrl, fileName) { + var _this = this; + if (rootUrl === void 0) { rootUrl = ""; } + if (fileName === void 0) { fileName = ""; } + if (!this.validate) { + return; + } + this._startPerformanceCounter("Validate JSON"); + _glTFValidation__WEBPACK_IMPORTED_MODULE_1__.GLTFValidation.ValidateAsync(data, rootUrl, fileName, function (uri) { + return _this.preprocessUrlAsync(rootUrl + uri).then(function (url) { + return scene._loadFileAsync(url, undefined, true, true).then(function (data) { + return new Uint8Array(data, 0, data.byteLength); + }); + }); + }).then(function (result) { + _this._endPerformanceCounter("Validate JSON"); + _this.onValidatedObservable.notifyObservers(result); + _this.onValidatedObservable.clear(); + }, function (reason) { + _this._endPerformanceCounter("Validate JSON"); + babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Tools.Warn("Failed to validate: ".concat(reason.message)); + _this.onValidatedObservable.clear(); + }); + }; + GLTFFileLoader.prototype._getLoader = function (loaderData) { + var asset = loaderData.json.asset || {}; + this._log("Asset version: ".concat(asset.version)); + asset.minVersion && this._log("Asset minimum version: ".concat(asset.minVersion)); + asset.generator && this._log("Asset generator: ".concat(asset.generator)); + var version = GLTFFileLoader._parseVersion(asset.version); + if (!version) { + throw new Error("Invalid version: " + asset.version); + } + if (asset.minVersion !== undefined) { + var minVersion = GLTFFileLoader._parseVersion(asset.minVersion); + if (!minVersion) { + throw new Error("Invalid minimum version: " + asset.minVersion); + } + if (GLTFFileLoader._compareVersion(minVersion, { major: 2, minor: 0 }) > 0) { + throw new Error("Incompatible minimum version: " + asset.minVersion); + } + } + var createLoaders = { + 1: GLTFFileLoader._CreateGLTF1Loader, + 2: GLTFFileLoader._CreateGLTF2Loader, + }; + var createLoader = createLoaders[version.major]; + if (!createLoader) { + throw new Error("Unsupported version: " + asset.version); + } + return createLoader(this); + }; + GLTFFileLoader.prototype._parseJson = function (json) { + this._startPerformanceCounter("Parse JSON"); + this._log("JSON length: ".concat(json.length)); + var parsed = JSON.parse(json); + this._endPerformanceCounter("Parse JSON"); + return parsed; + }; + GLTFFileLoader.prototype._unpackBinaryAsync = function (dataReader) { + var _this = this; + this._startPerformanceCounter("Unpack Binary"); + // Read magic + version + length + json length + json format + return dataReader.loadAsync(20).then(function () { + var Binary = { + Magic: 0x46546c67, + }; + var magic = dataReader.readUint32(); + if (magic !== Binary.Magic) { + throw new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.RuntimeError("Unexpected magic: " + magic, babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.ErrorCodes.GLTFLoaderUnexpectedMagicError); + } + var version = dataReader.readUint32(); + if (_this.loggingEnabled) { + _this._log("Binary version: ".concat(version)); + } + var length = dataReader.readUint32(); + if (!_this.useRangeRequests && length !== dataReader.buffer.byteLength) { + babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Logger.Warn("Length in header does not match actual data length: ".concat(length, " != ").concat(dataReader.buffer.byteLength)); + } + var unpacked; + switch (version) { + case 1: { + unpacked = _this._unpackBinaryV1Async(dataReader, length); + break; + } + case 2: { + unpacked = _this._unpackBinaryV2Async(dataReader, length); + break; + } + default: { + throw new Error("Unsupported version: " + version); + } + } + _this._endPerformanceCounter("Unpack Binary"); + return unpacked; + }); + }; + GLTFFileLoader.prototype._unpackBinaryV1Async = function (dataReader, length) { + var ContentFormat = { + JSON: 0, + }; + var contentLength = dataReader.readUint32(); + var contentFormat = dataReader.readUint32(); + if (contentFormat !== ContentFormat.JSON) { + throw new Error("Unexpected content format: ".concat(contentFormat)); + } + var bodyLength = length - dataReader.byteOffset; + var data = { json: this._parseJson(dataReader.readString(contentLength)), bin: null }; + if (bodyLength !== 0) { + var startByteOffset_1 = dataReader.byteOffset; + data.bin = { + readAsync: function (byteOffset, byteLength) { return dataReader.buffer.readAsync(startByteOffset_1 + byteOffset, byteLength); }, + byteLength: bodyLength, + }; + } + return Promise.resolve(data); + }; + GLTFFileLoader.prototype._unpackBinaryV2Async = function (dataReader, length) { + var _this = this; + var ChunkFormat = { + JSON: 0x4e4f534a, + BIN: 0x004e4942, + }; + // Read the JSON chunk header. + var chunkLength = dataReader.readUint32(); + var chunkFormat = dataReader.readUint32(); + if (chunkFormat !== ChunkFormat.JSON) { + throw new Error("First chunk format is not JSON"); + } + // Bail if there are no other chunks. + if (dataReader.byteOffset + chunkLength === length) { + return dataReader.loadAsync(chunkLength).then(function () { + return { json: _this._parseJson(dataReader.readString(chunkLength)), bin: null }; + }); + } + // Read the JSON chunk and the length and type of the next chunk. + return dataReader.loadAsync(chunkLength + 8).then(function () { + var data = { json: _this._parseJson(dataReader.readString(chunkLength)), bin: null }; + var readAsync = function () { + var chunkLength = dataReader.readUint32(); + var chunkFormat = dataReader.readUint32(); + switch (chunkFormat) { + case ChunkFormat.JSON: { + throw new Error("Unexpected JSON chunk"); + } + case ChunkFormat.BIN: { + var startByteOffset_2 = dataReader.byteOffset; + data.bin = { + readAsync: function (byteOffset, byteLength) { return dataReader.buffer.readAsync(startByteOffset_2 + byteOffset, byteLength); }, + byteLength: chunkLength, + }; + dataReader.skipBytes(chunkLength); + break; + } + default: { + // ignore unrecognized chunkFormat + dataReader.skipBytes(chunkLength); + break; + } + } + if (dataReader.byteOffset !== length) { + return dataReader.loadAsync(8).then(readAsync); + } + return Promise.resolve(data); + }; + return readAsync(); + }); + }; + GLTFFileLoader._parseVersion = function (version) { + if (version === "1.0" || version === "1.0.1") { + return { + major: 1, + minor: 0, + }; + } + var match = (version + "").match(/^(\d+)\.(\d+)/); + if (!match) { + return null; + } + return { + major: parseInt(match[1]), + minor: parseInt(match[2]), + }; + }; + GLTFFileLoader._compareVersion = function (a, b) { + if (a.major > b.major) { + return 1; + } + if (a.major < b.major) { + return -1; + } + if (a.minor > b.minor) { + return 1; + } + if (a.minor < b.minor) { + return -1; + } + return 0; + }; + /** + * @internal + */ + GLTFFileLoader.prototype._logOpen = function (message) { + this._log(message); + this._logIndentLevel++; + }; + /** @internal */ + GLTFFileLoader.prototype._logClose = function () { + --this._logIndentLevel; + }; + GLTFFileLoader.prototype._logEnabled = function (message) { + var spaces = GLTFFileLoader._logSpaces.substring(0, this._logIndentLevel * 2); + babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Logger.Log("".concat(spaces).concat(message)); + }; + GLTFFileLoader.prototype._logDisabled = function (message) { }; + GLTFFileLoader.prototype._startPerformanceCounterEnabled = function (counterName) { + babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Tools.StartPerformanceCounter(counterName); + }; + GLTFFileLoader.prototype._startPerformanceCounterDisabled = function (counterName) { }; + GLTFFileLoader.prototype._endPerformanceCounterEnabled = function (counterName) { + babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.Tools.EndPerformanceCounter(counterName); + }; + GLTFFileLoader.prototype._endPerformanceCounterDisabled = function (counterName) { }; + // ------------------ + // End Common options + // ------------------ + // ---------------- + // Begin V1 options + // ---------------- + /** + * Set this property to false to disable incremental loading which delays the loader from calling the success callback until after loading the meshes and shaders. + * Textures always loads asynchronously. For example, the success callback can compute the bounding information of the loaded meshes when incremental loading is disabled. + * Defaults to true. + * @internal + */ + GLTFFileLoader.IncrementalLoading = true; + /** + * Set this property to true in order to work with homogeneous coordinates, available with some converters and exporters. + * Defaults to false. See https://en.wikipedia.org/wiki/Homogeneous_coordinates. + * @internal + */ + GLTFFileLoader.HomogeneousCoordinates = false; + GLTFFileLoader._logSpaces = " "; + return GLTFFileLoader; +}(GLTFLoaderOptions)); + +(0,babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__.registerSceneLoaderPlugin)(new GLTFFileLoader()); + + +/***/ }), + +/***/ "../../../dev/loaders/src/glTF/glTFValidation.ts": +/*!*******************************************************!*\ + !*** ../../../dev/loaders/src/glTF/glTFValidation.ts ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFValidation: () => (/* binding */ GLTFValidation) +/* harmony export */ }); +/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/tools"); +/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__); + +function validateAsync(data, rootUrl, fileName, getExternalResource) { + var options = { + externalResourceFunction: getExternalResource, + }; + if (fileName) { + options.uri = rootUrl === "file:" ? fileName : rootUrl + fileName; + } + return ArrayBuffer.isView(data) ? GLTFValidator.validateBytes(data, options) : GLTFValidator.validateString(data, options); +} +/** + * The worker function that gets converted to a blob url to pass into a worker. + */ +function workerFunc() { + var pendingExternalResources = []; + onmessage = function (message) { + var data = message.data; + switch (data.id) { + case "init": { + importScripts(data.url); + break; + } + case "validate": { + validateAsync(data.data, data.rootUrl, data.fileName, function (uri) { + return new Promise(function (resolve, reject) { + var index = pendingExternalResources.length; + pendingExternalResources.push({ resolve: resolve, reject: reject }); + postMessage({ id: "getExternalResource", index: index, uri: uri }); + }); + }).then(function (value) { + postMessage({ id: "validate.resolve", value: value }); + }, function (reason) { + postMessage({ id: "validate.reject", reason: reason }); + }); + break; + } + case "getExternalResource.resolve": { + pendingExternalResources[data.index].resolve(data.value); + break; + } + case "getExternalResource.reject": { + pendingExternalResources[data.index].reject(data.reason); + break; + } + } + }; +} +/** + * glTF validation + */ +var GLTFValidation = /** @class */ (function () { + function GLTFValidation() { + } + /** + * Validate a glTF asset using the glTF-Validator. + * @param data The JSON of a glTF or the array buffer of a binary glTF + * @param rootUrl The root url for the glTF + * @param fileName The file name for the glTF + * @param getExternalResource The callback to get external resources for the glTF validator + * @returns A promise that resolves with the glTF validation results once complete + */ + GLTFValidation.ValidateAsync = function (data, rootUrl, fileName, getExternalResource) { + var _this = this; + if (typeof Worker === "function") { + return new Promise(function (resolve, reject) { + var workerContent = "".concat(validateAsync, "(").concat(workerFunc, ")()"); + var workerBlobUrl = URL.createObjectURL(new Blob([workerContent], { type: "application/javascript" })); + var worker = new Worker(workerBlobUrl); + var onError = function (error) { + worker.removeEventListener("error", onError); + worker.removeEventListener("message", onMessage); + reject(error); + }; + var onMessage = function (message) { + var data = message.data; + switch (data.id) { + case "getExternalResource": { + getExternalResource(data.uri).then(function (value) { + worker.postMessage({ id: "getExternalResource.resolve", index: data.index, value: value }, [value.buffer]); + }, function (reason) { + worker.postMessage({ id: "getExternalResource.reject", index: data.index, reason: reason }); + }); + break; + } + case "validate.resolve": { + worker.removeEventListener("error", onError); + worker.removeEventListener("message", onMessage); + resolve(data.value); + worker.terminate(); + break; + } + case "validate.reject": { + worker.removeEventListener("error", onError); + worker.removeEventListener("message", onMessage); + reject(data.reason); + worker.terminate(); + } + } + }; + worker.addEventListener("error", onError); + worker.addEventListener("message", onMessage); + worker.postMessage({ id: "init", url: babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__.Tools.GetBabylonScriptURL(_this.Configuration.url) }); + if (ArrayBuffer.isView(data)) { + // Slice the data to avoid copying the whole array buffer. + var slicedData = data.slice(); + worker.postMessage({ id: "validate", data: slicedData, rootUrl: rootUrl, fileName: fileName }, [slicedData.buffer]); + } + else { + worker.postMessage({ id: "validate", data: data, rootUrl: rootUrl, fileName: fileName }); + } + }); + } + else { + if (!this._LoadScriptPromise) { + this._LoadScriptPromise = babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__.Tools.LoadBabylonScriptAsync(this.Configuration.url); + } + return this._LoadScriptPromise.then(function () { + return validateAsync(data, rootUrl, fileName, getExternalResource); + }); + } + }; + /** + * The configuration. Defaults to `{ url: "https://cdn.babylonjs.com/gltf_validator.js" }`. + */ + GLTFValidation.Configuration = { + url: "".concat(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__.Tools._DefaultCdnUrl, "/gltf_validator.js"), + }; + return GLTFValidation; +}()); + + + +/***/ }), + +/***/ "../../../lts/loaders/src/legacy/legacy-glTF.ts": +/*!******************************************************!*\ + !*** ../../../lts/loaders/src/legacy/legacy-glTF.ts ***! + \******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTFFileLoader: () => (/* reexport safe */ loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFFileLoader), +/* harmony export */ GLTFLoaderAnimationStartMode: () => (/* reexport safe */ loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderAnimationStartMode), +/* harmony export */ GLTFLoaderCoordinateSystemMode: () => (/* reexport safe */ loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderCoordinateSystemMode), +/* harmony export */ GLTFLoaderState: () => (/* reexport safe */ loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderState), +/* harmony export */ GLTFValidation: () => (/* reexport safe */ loaders_glTF_glTFValidation__WEBPACK_IMPORTED_MODULE_1__.GLTFValidation) +/* harmony export */ }); +/* harmony import */ var loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! loaders/glTF/glTFFileLoader */ "../../../dev/loaders/src/glTF/glTFFileLoader.ts"); +/* harmony import */ var loaders_glTF_glTFValidation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! loaders/glTF/glTFValidation */ "../../../dev/loaders/src/glTF/glTFValidation.ts"); + + +/** + * This is the entry point for the UMD module. + * The entry point for a future ESM package should be index.ts + */ +var globalObject = typeof __webpack_require__.g !== "undefined" ? __webpack_require__.g : typeof window !== "undefined" ? window : undefined; +if (typeof globalObject !== "undefined") { + globalObject.BABYLON = globalObject.BABYLON || {}; + for (var key in loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__) { + globalObject.BABYLON[key] = loaders_glTF_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__[key]; + } + for (var key in loaders_glTF_glTFValidation__WEBPACK_IMPORTED_MODULE_1__) { + globalObject.BABYLON[key] = loaders_glTF_glTFValidation__WEBPACK_IMPORTED_MODULE_1__[key]; + } +} + + + + +/***/ }), + +/***/ "../../../lts/loaders/src/legacy/legacy-glTF1.ts": +/*!*******************************************************!*\ + !*** ../../../lts/loaders/src/legacy/legacy-glTF1.ts ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTF1: () => (/* reexport module object */ loaders_glTF_1_0_index__WEBPACK_IMPORTED_MODULE_0__) +/* harmony export */ }); +/* harmony import */ var loaders_glTF_1_0_index__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! loaders/glTF/1.0/index */ "../../../dev/loaders/src/glTF/1.0/index.ts"); +/* eslint-disable import/no-internal-modules */ + +/** + * This is the entry point for the UMD module. + * The entry point for a future ESM package should be index.ts + */ +var globalObject = typeof __webpack_require__.g !== "undefined" ? __webpack_require__.g : typeof window !== "undefined" ? window : undefined; +if (typeof globalObject !== "undefined") { + globalObject.BABYLON = globalObject.BABYLON || {}; + globalObject.BABYLON.GLTF1 = globalObject.BABYLON.GLTF1 || {}; + for (var key in loaders_glTF_1_0_index__WEBPACK_IMPORTED_MODULE_0__) { + globalObject.BABYLON.GLTF1[key] = loaders_glTF_1_0_index__WEBPACK_IMPORTED_MODULE_0__[key]; + } +} + + + +/***/ }), + +/***/ "../../../lts/loaders/src/legacy/legacy-glTF2.ts": +/*!*******************************************************!*\ + !*** ../../../lts/loaders/src/legacy/legacy-glTF2.ts ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTF2: () => (/* reexport module object */ loaders_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_2__) +/* harmony export */ }); +/* harmony import */ var loaders_glTF_2_0_Extensions_index__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! loaders/glTF/2.0/Extensions/index */ "../../../dev/loaders/src/glTF/2.0/Extensions/index.ts"); +/* harmony import */ var loaders_glTF_2_0_glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! loaders/glTF/2.0/glTFLoaderInterfaces */ "../../../dev/loaders/src/glTF/2.0/glTFLoaderInterfaces.ts"); +/* harmony import */ var loaders_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! loaders/glTF/2.0/index */ "../../../dev/loaders/src/glTF/2.0/index.ts"); +/* eslint-disable import/no-internal-modules */ + + + +/** + * This is the entry point for the UMD module. + * The entry point for a future ESM package should be index.ts + */ +var globalObject = typeof __webpack_require__.g !== "undefined" ? __webpack_require__.g : typeof window !== "undefined" ? window : undefined; +if (typeof globalObject !== "undefined") { + globalObject.BABYLON = globalObject.BABYLON || {}; + var BABYLON_1 = globalObject.BABYLON; + BABYLON_1.GLTF2 = BABYLON_1.GLTF2 || {}; + BABYLON_1.GLTF2.Loader = BABYLON_1.GLTF2.Loader || {}; + BABYLON_1.GLTF2.Loader.Extensions = BABYLON_1.GLTF2.Loader.Extensions || {}; + var keys = []; + for (var key in loaders_glTF_2_0_Extensions_index__WEBPACK_IMPORTED_MODULE_0__) { + BABYLON_1.GLTF2.Loader.Extensions[key] = loaders_glTF_2_0_Extensions_index__WEBPACK_IMPORTED_MODULE_0__[key]; + keys.push(key); + } + for (var key in loaders_glTF_2_0_glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_1__) { + BABYLON_1.GLTF2.Loader[key] = loaders_glTF_2_0_glTFLoaderInterfaces__WEBPACK_IMPORTED_MODULE_1__[key]; + keys.push(key); + } + for (var key in loaders_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_2__) { + // Prevent Reassignment. + if (keys.indexOf(key) > -1) { + continue; + } + BABYLON_1.GLTF2[key] = loaders_glTF_2_0_index__WEBPACK_IMPORTED_MODULE_2__[key]; + } +} + + + +/***/ }), + +/***/ "../../../lts/loaders/src/legacy/legacy-glTFFileLoader.ts": +/*!****************************************************************!*\ + !*** ../../../lts/loaders/src/legacy/legacy-glTFFileLoader.ts ***! + \****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GLTF1: () => (/* reexport safe */ _legacy_glTF1__WEBPACK_IMPORTED_MODULE_1__.GLTF1), +/* harmony export */ GLTF2: () => (/* reexport safe */ _legacy_glTF2__WEBPACK_IMPORTED_MODULE_2__.GLTF2), +/* harmony export */ GLTFFileLoader: () => (/* reexport safe */ _legacy_glTF__WEBPACK_IMPORTED_MODULE_0__.GLTFFileLoader), +/* harmony export */ GLTFLoaderAnimationStartMode: () => (/* reexport safe */ _legacy_glTF__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderAnimationStartMode), +/* harmony export */ GLTFLoaderCoordinateSystemMode: () => (/* reexport safe */ _legacy_glTF__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderCoordinateSystemMode), +/* harmony export */ GLTFLoaderState: () => (/* reexport safe */ _legacy_glTF__WEBPACK_IMPORTED_MODULE_0__.GLTFLoaderState), +/* harmony export */ GLTFValidation: () => (/* reexport safe */ _legacy_glTF__WEBPACK_IMPORTED_MODULE_0__.GLTFValidation) +/* harmony export */ }); +/* harmony import */ var _legacy_glTF__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./legacy-glTF */ "../../../lts/loaders/src/legacy/legacy-glTF.ts"); +/* harmony import */ var _legacy_glTF1__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./legacy-glTF1 */ "../../../lts/loaders/src/legacy/legacy-glTF1.ts"); +/* harmony import */ var _legacy_glTF2__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./legacy-glTF2 */ "../../../lts/loaders/src/legacy/legacy-glTF2.ts"); +// eslint-disable-next-line import/export + + + + + +/***/ }), + +/***/ "babylonjs/Misc/tools": +/*!****************************************************************************************************!*\ + !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***! + \****************************************************************************************************/ +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_tools__; + +/***/ }), + +/***/ "../../../../node_modules/tslib/tslib.es6.mjs": +/*!****************************************************!*\ + !*** ../../../../node_modules/tslib/tslib.es6.mjs ***! + \****************************************************/ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ __addDisposableResource: () => (/* binding */ __addDisposableResource), +/* harmony export */ __assign: () => (/* binding */ __assign), +/* harmony export */ __asyncDelegator: () => (/* binding */ __asyncDelegator), +/* harmony export */ __asyncGenerator: () => (/* binding */ __asyncGenerator), +/* harmony export */ __asyncValues: () => (/* binding */ __asyncValues), +/* harmony export */ __await: () => (/* binding */ __await), +/* harmony export */ __awaiter: () => (/* binding */ __awaiter), +/* harmony export */ __classPrivateFieldGet: () => (/* binding */ __classPrivateFieldGet), +/* harmony export */ __classPrivateFieldIn: () => (/* binding */ __classPrivateFieldIn), +/* harmony export */ __classPrivateFieldSet: () => (/* binding */ __classPrivateFieldSet), +/* harmony export */ __createBinding: () => (/* binding */ __createBinding), +/* harmony export */ __decorate: () => (/* binding */ __decorate), +/* harmony export */ __disposeResources: () => (/* binding */ __disposeResources), +/* harmony export */ __esDecorate: () => (/* binding */ __esDecorate), +/* harmony export */ __exportStar: () => (/* binding */ __exportStar), +/* harmony export */ __extends: () => (/* binding */ __extends), +/* harmony export */ __generator: () => (/* binding */ __generator), +/* harmony export */ __importDefault: () => (/* binding */ __importDefault), +/* harmony export */ __importStar: () => (/* binding */ __importStar), +/* harmony export */ __makeTemplateObject: () => (/* binding */ __makeTemplateObject), +/* harmony export */ __metadata: () => (/* binding */ __metadata), +/* harmony export */ __param: () => (/* binding */ __param), +/* harmony export */ __propKey: () => (/* binding */ __propKey), +/* harmony export */ __read: () => (/* binding */ __read), +/* harmony export */ __rest: () => (/* binding */ __rest), +/* harmony export */ __rewriteRelativeImportExtension: () => (/* binding */ __rewriteRelativeImportExtension), +/* harmony export */ __runInitializers: () => (/* binding */ __runInitializers), +/* harmony export */ __setFunctionName: () => (/* binding */ __setFunctionName), +/* harmony export */ __spread: () => (/* binding */ __spread), +/* harmony export */ __spreadArray: () => (/* binding */ __spreadArray), +/* harmony export */ __spreadArrays: () => (/* binding */ __spreadArrays), +/* harmony export */ __values: () => (/* binding */ __values), +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +/* global Reflect, Promise, SuppressedError, Symbol, Iterator */ + +var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); +}; + +function __extends(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} + +var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + } + return __assign.apply(this, arguments); +} + +function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +} + +function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} + +function __param(paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } +} + +function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; +}; + +function __runInitializers(thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; +}; + +function __propKey(x) { + return typeof x === "symbol" ? x : "".concat(x); +}; + +function __setFunctionName(f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); +}; + +function __metadata(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); +} + +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); + return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +} + +var __createBinding = Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +}); + +function __exportStar(m, o) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); +} + +function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); +} + +function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +} + +/** @deprecated */ +function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; +} + +/** @deprecated */ +function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +} + +function __spreadArray(to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +} + +function __await(v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); +} + +function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; + function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } + function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } +} + +function __asyncDelegator(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; + function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } +} + +function __asyncValues(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +} + +function __makeTemplateObject(cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; +}; + +var __setModuleDefault = Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}; + +function __importStar(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +} + +function __importDefault(mod) { + return (mod && mod.__esModule) ? mod : { default: mod }; +} + +function __classPrivateFieldGet(receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +} + +function __classPrivateFieldSet(receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +} + +function __classPrivateFieldIn(state, receiver) { + if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); + return typeof state === "function" ? receiver === state : state.has(receiver); +} + +function __addDisposableResource(env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose, inner; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + if (async) inner = dispose; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } }; + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; +} + +var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}; + +function __disposeResources(env) { + function fail(e) { + env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + var r, s = 0; + function next() { + while (r = env.stack.pop()) { + try { + if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); + if (r.dispose) { + var result = r.dispose.call(r.value); + if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + else s |= 1; + } + catch (e) { + fail(e); + } + } + if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); + if (env.hasError) throw env.error; + } + return next(); +} + +function __rewriteRelativeImportExtension(path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); + } + return path; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ + __extends, + __assign, + __rest, + __decorate, + __param, + __esDecorate, + __runInitializers, + __propKey, + __setFunctionName, + __metadata, + __awaiter, + __generator, + __createBinding, + __exportStar, + __values, + __read, + __spread, + __spreadArrays, + __spreadArray, + __await, + __asyncGenerator, + __asyncDelegator, + __asyncValues, + __makeTemplateObject, + __importStar, + __importDefault, + __classPrivateFieldGet, + __classPrivateFieldSet, + __classPrivateFieldIn, + __addDisposableResource, + __disposeResources, + __rewriteRelativeImportExtension, +}); + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/compat get default export */ +/******/ (() => { +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = (module) => { +/******/ var getter = module && module.__esModule ? +/******/ () => (module['default']) : +/******/ () => (module); +/******/ __webpack_require__.d(getter, { a: getter }); +/******/ return getter; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/create fake namespace object */ +/******/ (() => { +/******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__); +/******/ var leafPrototypes; +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 16: return value when it's Promise-like +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = this(value); +/******/ if(mode & 8) return value; +/******/ if(typeof value === 'object' && value) { +/******/ if((mode & 4) && value.__esModule) return value; +/******/ if((mode & 16) && typeof value.then === 'function') return value; +/******/ } +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ var def = {}; +/******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)]; +/******/ for(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) { +/******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key]))); +/******/ } +/******/ def['default'] = () => (value); +/******/ __webpack_require__.d(ns, def); +/******/ return ns; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/global */ +/******/ (() => { +/******/ __webpack_require__.g = (function() { +/******/ if (typeof globalThis === 'object') return globalThis; +/******/ try { +/******/ return this || new Function('return this')(); +/******/ } catch (e) { +/******/ if (typeof window === 'object') return window; +/******/ } +/******/ })(); +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +/*!*******************************!*\ + !*** ./src/glTFFileLoader.ts ***! + \*******************************/ +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__), +/* harmony export */ loaders: () => (/* reexport module object */ _lts_loaders_legacy_legacy_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__) +/* harmony export */ }); +/* harmony import */ var _lts_loaders_legacy_legacy_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @lts/loaders/legacy/legacy-glTFFileLoader */ "../../../lts/loaders/src/legacy/legacy-glTFFileLoader.ts"); + + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_lts_loaders_legacy_legacy_glTFFileLoader__WEBPACK_IMPORTED_MODULE_0__); + +})(); + +__webpack_exports__ = __webpack_exports__["default"]; +/******/ return __webpack_exports__; +/******/ })() +; +}); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFieWxvbi5nbFRGRmlsZUxvYWRlci5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDVkE7QUFDQTtBQUlBO0FBSUE7QUFhQTs7O0FBR0E7QUFDQTtBQUFBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzVEQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBRUE7QUFDQTtBQUdBOzs7QUFHQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBVUE7QUFSQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7Ozs7OztBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7Ozs7O0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7OztBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7Ozs7Ozs7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7Ozs7QUFTQTtBQUNBO0FBU0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7Ozs7O0FBT0E7QUFDQTtBQU9BO0FBQ0E7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQXJDQTs7QUFFQTtBQUNBO0FBQUE7QUFtQ0E7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7Ozs7QUFTQTtBQUNBO0FBUUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7O0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTUE7QUFDQTtBQUVBOzs7QUFHQTtBQUNBO0FBQUE7QUF3YUE7QUF2YUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBT0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7Ozs7QUFJQTtBQUNBO0FBQUE7QUEwVEE7QUF2VEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBVUE7QUFFQTtBQUtBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUVBOzs7Ozs7Ozs7QUFTQTtBQUNBO0FBQUE7QUFRQTtBQUNBO0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFBQTtBQVFBO0FBRUE7QUFLQTtBQUNBO0FBR0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUdBO0FBRUE7Ozs7Ozs7QUFPQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBS0E7QUFDQTtBQUdBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBSUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUF4VEE7QUF5VEE7QUFBQTtBQTFUQTtBQTRUQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7OztBQUFBO0FBRUE7Ozs7Ozs7OztBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7Ozs7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7Ozs7QUFTQTtBQUNBO0FBT0E7QUFDQTtBQUVBOzs7Ozs7OztBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7Ozs7OztBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7Ozs7O0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7Ozs7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBT0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBT0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFNQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQU9BO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN6d0VBOzs7QUFHQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNwR0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7Ozs7QUFJQTtBQUNBO0FBQUE7QUFtUUE7QUFsUUE7Ozs7Ozs7QUFPQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7O0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQU9BO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQW5RQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNqQkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUF3REE7OztBQUdBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQUE7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2xOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDSEE7QUFDQTtBQUVBO0FBS0E7QUFDQTtBQUVBO0FBc0JBOztBQUVBO0FBQ0E7QUFDQTtBQWNBOztBQUVBO0FBQ0E7QUFoQkE7O0FBRUE7QUFDQTtBQWNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBR0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBR0E7O0FBWkE7QUFBQTtBQWFBOzs7QUFoQkE7QUFBQTtBQWlCQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUM1S0E7QUFJQTtBQUlBO0FBRUE7QUFFQTtBQWFBOzs7QUFHQTtBQUNBO0FBQ0E7QUFhQTs7QUFFQTtBQUNBO0FBZkE7O0FBRUE7QUFDQTtBQWFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUMxSEE7QUFHQTtBQUNBO0FBRUE7QUFpQkE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBYUE7O0FBRUE7QUFDQTtBQWZBOztBQUVBO0FBQ0E7QUFhQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7QUM5RUE7QUFLQTtBQUVBO0FBYUE7OztBQUdBO0FBQ0E7QUFDQTtBQVNBOztBQUVBO0FBQ0E7QUFYQTtBQUNBO0FBV0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUtBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7OztBQ3JFQTtBQUtBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFTQTs7QUFFQTtBQUNBO0FBWEE7QUFDQTtBQVdBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFLQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQzVEQTtBQUVBO0FBaUJBOztBQUVBO0FBQ0E7QUFxQkE7O0FBRUE7QUFDQTtBQXZCQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQWdCQTtBQUNBO0FBYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFTQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDL0ZBOztBQUVBO0FBR0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUFBOztBQUtBO0FBSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFBQTtBQUFBOztBQU9BO0FBTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQUE7QUFBQTs7QUFXQTtBQVZBO0FBQ0E7QUFPQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFJQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDdFJBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFhQTs7O0FBR0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBOzs7QUFHQTtBQUNBO0FBQ0E7QUFTQTs7QUFFQTtBQUNBO0FBWEE7O0FBRUE7QUFDQTtBQVNBO0FBQ0E7QUFDQTtBQUtBO0FBSEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7OztBQVFBO0FBQ0E7O0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDdkhBO0FBRUE7QUFRQTtBQUNBO0FBRUE7QUFpQkE7O0FBRUE7QUFDQTtBQUNBO0FBdUJBOztBQUVBO0FBQ0E7QUF6QkE7O0FBRUE7QUFDQTtBQVlBOztBQUVBO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDbElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQWFBOztBQUVBO0FBQ0E7QUFZQTs7O0FBR0E7QUFDQTtBQUFBO0FBZkE7O0FBRUE7QUFDQTtBQWFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBT0E7QUFDQTtBQUVBO0FBYUE7O0FBRUE7QUFDQTtBQUNBO0FBZUE7O0FBRUE7QUFDQTtBQWpCQTs7QUFFQTtBQUNBO0FBZUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNwSUE7QUFLQTtBQUVBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2hHQTtBQUtBO0FBRUE7QUFFQTtBQWFBOzs7QUFHQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDcklBO0FBS0E7QUFFQTtBQUNBO0FBRUE7QUFhQTs7O0FBR0E7QUFDQTtBQUNBO0FBa0JBOztBQUVBO0FBQ0E7QUFwQkE7O0FBRUE7QUFDQTtBQU9BOztBQUVBO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDdElBO0FBSUE7QUFFQTtBQUVBO0FBYUE7OztBQUdBO0FBQ0E7QUFDQTtBQWtCQTs7QUFFQTtBQUNBO0FBcEJBOztBQUVBO0FBQ0E7QUFPQTs7QUFFQTtBQUNBO0FBUUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDdkZBO0FBS0E7QUFFQTtBQUVBO0FBYUE7O0FBRUE7QUFDQTtBQUNBO0FBa0JBOztBQUVBO0FBQ0E7QUFwQkE7O0FBRUE7QUFDQTtBQU9BOztBQUVBO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNoRkE7QUFLQTtBQUVBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUF1QkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUEzREE7O0FBRUE7QUFDQTtBQXlEQTtBQUFBO0FBN0RBO0FBK0RBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUMxRkE7QUFLQTtBQUVBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDMUdBO0FBQ0E7QUFLQTtBQUVBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNySEE7QUFLQTtBQUNBO0FBRUE7QUFFQTtBQWFBOzs7QUFHQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN4SEE7QUFLQTtBQUNBO0FBRUE7QUFFQTtBQWFBOztBQUVBO0FBQ0E7QUFDQTtBQWtCQTs7QUFFQTtBQUNBO0FBcEJBOztBQUVBO0FBQ0E7QUFPQTs7QUFFQTtBQUNBO0FBUUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDOUdBO0FBS0E7QUFLQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBK0NBOztBQUVBO0FBQ0E7QUFrQ0E7Ozs7QUFJQTtBQUNBO0FBQUE7QUFoQkE7QUFDQTtBQUNBO0FBQ0E7QUFjQTtBQUlBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQXJEQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQTBDQTs7O0FBR0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBS0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTs7QUFDQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFBQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzFhQTtBQUNBO0FBS0E7QUFDQTtBQUVBO0FBYUE7O0FBRUE7QUFDQTtBQUNBO0FBa0JBOztBQUVBO0FBQ0E7QUFwQkE7O0FBRUE7QUFDQTtBQU9BOztBQUVBO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3hHQTtBQUdBO0FBTUE7QUFFQTtBQXVCQTs7QUFFQTtBQUNBO0FBQ0E7QUFlQTs7QUFFQTtBQUNBO0FBakJBOztBQUVBO0FBQ0E7QUFlQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQVFBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBeEVBO0FBQUE7QUF5RUE7QUFDQTs7QUFoRkE7QUFDQTtBQUFBO0FBaUZBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3hUQTtBQUtBO0FBRUE7QUFFQTtBQWFBOzs7QUFHQTtBQUNBO0FBQ0E7QUFrQkE7O0FBRUE7QUFDQTtBQXBCQTs7QUFFQTtBQUNBO0FBT0E7O0FBRUE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7O0FDakhBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFXQTs7QUFFQTtBQUNBO0FBYkE7O0FBRUE7QUFDQTtBQVdBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN6Q0E7QUFFQTtBQWFBOztBQUVBO0FBQ0E7QUFDQTtBQVlBOztBQUVBO0FBQ0E7QUFkQTs7QUFFQTtBQUNBO0FBWUE7QUFDQTtBQUNBO0FBRUE7Ozs7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNsRUE7QUFLQTtBQUVBO0FBYUE7O0FBRUE7QUFDQTtBQUNBO0FBU0E7O0FBRUE7QUFDQTtBQVhBO0FBQ0E7QUFXQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBS0E7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNuRUE7QUFJQTtBQUVBO0FBRUE7QUFhQTs7QUFFQTtBQUNBO0FBQ0E7QUFhQTs7QUFFQTtBQUNBO0FBZkE7O0FBRUE7QUFDQTtBQWFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ3pGQTtBQUVBO0FBYUE7OztBQUdBO0FBQ0E7QUFDQTtBQWtCQTs7QUFFQTtBQUNBO0FBcEJBOztBQUVBO0FBQ0E7QUFPQTs7QUFFQTtBQUNBO0FBUUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDMUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFJQTtBQUdBO0FBRUE7QUFFQTtBQW9DQTs7O0FBR0E7QUFDQTtBQUNBO0FBZUE7O0FBRUE7QUFDQTtBQWpCQTs7QUFFQTtBQUNBO0FBZUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFLQTtBQUNBO0FBQ0E7O0FBZkE7QUFBQTtBQUFBO0FBaUJBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQVZBO0FBQUE7QUFZQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNoVUE7QUFDQTtBQU9BO0FBRUE7QUFFQTtBQXdCQTs7QUFFQTtBQUNBO0FBQ0E7QUFpREE7O0FBRUE7QUFDQTs7QUFuREE7O0FBRUE7QUFDQTtBQU9BOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7Ozs7QUFJQTtBQUNBO0FBRUE7Ozs7QUFJQTtBQUNBO0FBSUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7QUFsQkE7QUFBQTtBQW1CQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7QUFsQkE7QUFBQTtBQW1CQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7O0FBbENBO0FBQUE7QUFtQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7QUFuQ0E7QUFBQTtBQW9DQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNuYkE7QUFJQTtBQUNBO0FBRUE7QUFhQTtBQUNBO0FBQ0E7QUFTQTtBQUNBO0FBVEE7QUFDQTtBQVNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3JFQTtBQUlBO0FBQ0E7QUFFQTtBQWFBO0FBQ0E7QUFDQTtBQVNBO0FBQ0E7QUFUQTtBQUNBO0FBU0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7OztBQ3JFQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW1CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3RFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzVCQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7OztBQUtBO0FBQ0E7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFuQ0E7QUFDQTtBQUFBO0FBQUE7QUFtQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7O0FBMUNBO0FBQUE7QUFBQTtBQTJDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUM5TUE7QUFJQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQXdFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2xMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUEwQ0E7QUFFQTtBQUNBO0FBRUE7QUFHQTtBQUVBO0FBRUE7QUF1QkE7QUFDQTtBQUFBO0FBQUE7QUFBQTs7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUF5Q0E7QUF4Q0E7Ozs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBV0E7O0FBRUE7QUFDQTtBQXdHQTs7QUFFQTtBQUNBO0FBMUdBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBaUZBO0FBQ0E7QUEzRUE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUtBO0FBSEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7OztBQUFBO0FBS0E7QUFIQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFLQTtBQUhBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQUtBO0FBSEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7OztBQUFBO0FBS0E7QUFIQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFLQTtBQUhBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFPQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBOzs7Ozs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUFBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFHQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTs7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7Ozs7OztBQUNBO0FBRUE7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFFQTs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7OztBQUNBO0FBRUE7QUFDQTtBQUVBOztBQUFBOztBQUFBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBUEE7QUFBQTtBQUFBO0FBUUE7QUFDQTs7Ozs7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7Ozs7O0FBS0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7O0FBTUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7Ozs7O0FBU0E7QUFDQTtBQUFBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFLQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBOzs7OztBQUtBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7Ozs7O0FBU0E7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7Ozs7Ozs7QUFVQTtBQUNBO0FBUUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7Ozs7O0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQVNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQVFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFnQkE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFLQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7Ozs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7Ozs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7QUFNQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUlBO0FBSUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7OztBQU1BO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBT0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBUUE7QUFLQTtBQUVBO0FBT0E7QUFLQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFLQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBT0E7QUFLQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7O0FBT0E7QUFDQTtBQU1BO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7Ozs7Ozs7QUFPQTtBQUNBO0FBTUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFudUZBOztBQUVBO0FBQ0E7QUFpdUZBO0FBQUE7QUFqd0ZBO0FBbXdGQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzE3RkE7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQUE7O0FBRUE7QUFDQTtBQUFBO0FBQUE7O0FBS0E7QUFKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBRUE7QUFDQTtBQUFBO0FBQUE7O0FBNEJBO0FBM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFyQkE7QUFBQTtBQXNCQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDMUZBO0FBU0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ0ZBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ25CQTtBQUNBO0FBTUE7QUFDQTtBQUlBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQXlCQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUNBOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQXNDQTs7QUFFQTtBQUNBO0FBQUE7QUFDQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQTBCQTtBQUFBO0FBNENBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUVBOzs7O0FBSUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUVBOzs7QUFHQTtBQUNBO0FBRUE7Ozs7QUFJQTtBQUNBO0FBbUNBOztBQUVBO0FBQ0E7QUFRQTtBQXhNQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBd0tBO0FBQUE7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFPQTs7O0FBR0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQXVDQTtBQUNBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQWlCQTs7Ozs7QUFLQTtBQUNBO0FBaUJBOztBQUVBO0FBQ0E7QUFnQkE7O0FBRUE7QUFDQTtBQWdCQTs7QUFFQTtBQUNBO0FBZ0JBOzs7O0FBSUE7QUFDQTtBQWdCQTs7QUFFQTtBQUNBO0FBY0E7O0FBRUE7QUFDQTtBQWNBOzs7QUFHQTtBQUNBO0FBMERBOztBQUVBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBY0E7QUFDQTtBQUVBO0FBRUE7O0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFrVEE7O0FBRUE7QUFDQTtBQXVVQTtBQUNBO0FBRUE7QUFDQTtBQXNCQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBNThCQTs7QUFDQTtBQWdCQTtBQUhBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUF5Q0E7QUFKQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQWdCQTtBQUpBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBWUE7QUFIQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBWUE7QUFIQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBWUE7QUFIQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBZ0JBO0FBTEE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFZQTtBQUhBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQVlBO0FBSEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBYUE7QUFIQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQUE7QUFLQTtBQUhBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBOzs7QUFkQTtBQW1CQTtBQUhBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBaEJBO0FBaUNBO0FBSEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBZUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUdBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFFQTtBQUlBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBR0E7QUFJQTtBQUFBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFFQTtBQVFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBR0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFRQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQU9BO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFVQTtBQUNBO0FBQ0E7QUFDQTtBQUtBO0FBSEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBT0E7OztBQUdBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQVFBO0FBSUE7QUFDQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBU0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQVVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUE5N0JBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7OztBQUtBO0FBQ0E7QUFFQTs7OztBQUlBO0FBQ0E7QUE0M0JBO0FBOENBO0FBQUE7QUF0K0JBO0FBdytCQTs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNqM0NBO0FBU0E7QUFNQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBT0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVlBOztBQUVBO0FBQ0E7QUFBQTtBQXlGQTtBQS9FQTs7Ozs7OztBQU9BO0FBQ0E7QUFBQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBdkZBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBbUZBO0FBQUE7QUF6RkE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3RGQTtBQUNBO0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7O0FDbkJBO0FBQ0E7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7O0FDSEE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDdllBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNQQTs7Ozs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ05BO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL0xPQURFUlMvd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMS4wL2dsVEZCaW5hcnlFeHRlbnNpb24udHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8xLjAvZ2xURkxvYWRlci50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzEuMC9nbFRGTG9hZGVySW50ZXJmYWNlcy50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzEuMC9nbFRGTG9hZGVyVXRpbHMudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8xLjAvZ2xURk1hdGVyaWFsc0NvbW1vbkV4dGVuc2lvbi50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzEuMC9pbmRleC50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0VYVF9saWdodHNfaW1hZ2VfYmFzZWQudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9FWFRfbWVzaF9ncHVfaW5zdGFuY2luZy50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0VYVF9tZXNob3B0X2NvbXByZXNzaW9uLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvRVhUX3RleHR1cmVfYXZpZi50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0VYVF90ZXh0dXJlX3dlYnAudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9FeHRyYXNBc01ldGFkYXRhLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX2FuaW1hdGlvbl9wb2ludGVyLmRhdGEudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfYW5pbWF0aW9uX3BvaW50ZXIudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfZHJhY29fbWVzaF9jb21wcmVzc2lvbi50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9pbnRlcmFjdGl2aXR5LnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX2xpZ2h0c19wdW5jdHVhbC50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfYW5pc290cm9weS50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfY2xlYXJjb2F0LnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc19kaWZmdXNlX3RyYW5zbWlzc2lvbi50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfZGlzcGVyc2lvbi50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfZW1pc3NpdmVfc3RyZW5ndGgudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfbWF0ZXJpYWxzX2lvci50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfaXJpZGVzY2VuY2UudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfbWF0ZXJpYWxzX3BiclNwZWN1bGFyR2xvc3NpbmVzcy50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfc2hlZW4udHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfbWF0ZXJpYWxzX3NwZWN1bGFyLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc190cmFuc21pc3Npb24udHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9LSFJfbWF0ZXJpYWxzX3VubGl0LnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc192YXJpYW50cy50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl9tYXRlcmlhbHNfdm9sdW1lLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX21lc2hfcXVhbnRpemF0aW9uLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvS0hSX25vZGVfdmlzaWJpbGl0eS50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl90ZXh0dXJlX2Jhc2lzdS50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl90ZXh0dXJlX3RyYW5zZm9ybS50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL0tIUl94bXBfanNvbl9sZC50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL01TRlRfYXVkaW9fZW1pdHRlci50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL01TRlRfbG9kLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvTVNGVF9taW5lY3JhZnRNZXNoLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvTVNGVF9zUkdCRmFjdG9ycy50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL2dsdGZQYXRoVG9PYmplY3RDb252ZXJ0ZXIudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9pbmRleC50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9FeHRlbnNpb25zL2ludGVyYWN0aXZpdHlGdW5jdGlvbnMudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvRXh0ZW5zaW9ucy9pbnRlcmFjdGl2aXR5UGF0aFRvT2JqZWN0Q29udmVydGVyLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL0V4dGVuc2lvbnMvaW50ZXJhY3Rpdml0eVV0aWxzLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvMi4wL2dsVEZMb2FkZXIudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvZ2xURkxvYWRlckFuaW1hdGlvbi50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGLzIuMC9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnkudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi8yLjAvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9kZXYvbG9hZGVycy9zcmMvZ2xURi9nbFRGRmlsZUxvYWRlci5tZXRhZGF0YS50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2Rldi9sb2FkZXJzL3NyYy9nbFRGL2dsVEZGaWxlTG9hZGVyLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vZGV2L2xvYWRlcnMvc3JjL2dsVEYvZ2xURlZhbGlkYXRpb24udHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9sdHMvbG9hZGVycy9zcmMvbGVnYWN5L2xlZ2FjeS1nbFRGLnRzIiwid2VicGFjazovL0xPQURFUlMvLi4vLi4vLi4vbHRzL2xvYWRlcnMvc3JjL2xlZ2FjeS9sZWdhY3ktZ2xURjEudHMiLCJ3ZWJwYWNrOi8vTE9BREVSUy8uLi8uLi8uLi9sdHMvbG9hZGVycy9zcmMvbGVnYWN5L2xlZ2FjeS1nbFRGMi50cyIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uL2x0cy9sb2FkZXJzL3NyYy9sZWdhY3kvbGVnYWN5LWdsVEZGaWxlTG9hZGVyLnRzIiwid2VicGFjazovL0xPQURFUlMvZXh0ZXJuYWwgdW1kIHtcInJvb3RcIjpcIkJBQllMT05cIixcImNvbW1vbmpzXCI6XCJiYWJ5bG9uanNcIixcImNvbW1vbmpzMlwiOlwiYmFieWxvbmpzXCIsXCJhbWRcIjpcImJhYnlsb25qc1wifSIsIndlYnBhY2s6Ly9MT0FERVJTLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5lczYubWpzIiwid2VicGFjazovL0xPQURFUlMvd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vTE9BREVSUy93ZWJwYWNrL3J1bnRpbWUvY29tcGF0IGdldCBkZWZhdWx0IGV4cG9ydCIsIndlYnBhY2s6Ly9MT0FERVJTL3dlYnBhY2svcnVudGltZS9jcmVhdGUgZmFrZSBuYW1lc3BhY2Ugb2JqZWN0Iiwid2VicGFjazovL0xPQURFUlMvd2VicGFjay9ydW50aW1lL2RlZmluZSBwcm9wZXJ0eSBnZXR0ZXJzIiwid2VicGFjazovL0xPQURFUlMvd2VicGFjay9ydW50aW1lL2dsb2JhbCIsIndlYnBhY2s6Ly9MT0FERVJTL3dlYnBhY2svcnVudGltZS9oYXNPd25Qcm9wZXJ0eSBzaG9ydGhhbmQiLCJ3ZWJwYWNrOi8vTE9BREVSUy93ZWJwYWNrL3J1bnRpbWUvbWFrZSBuYW1lc3BhY2Ugb2JqZWN0Iiwid2VicGFjazovL0xPQURFUlMvLi9zcmMvZ2xURkZpbGVMb2FkZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiYmFieWxvbmpzXCIpKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFwiYmFieWxvbmpzLWxvYWRlcnNcIiwgW1wiYmFieWxvbmpzXCJdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcImJhYnlsb25qcy1sb2FkZXJzXCJdID0gZmFjdG9yeShyZXF1aXJlKFwiYmFieWxvbmpzXCIpKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJMT0FERVJTXCJdID0gZmFjdG9yeShyb290W1wiQkFCWUxPTlwiXSk7XG59KSgodHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHRoaXMpLCAoX19XRUJQQUNLX0VYVEVSTkFMX01PRFVMRV9iYWJ5bG9uanNfTWlzY190b29sc19fKSA9PiB7XG5yZXR1cm4gIiwiaW1wb3J0IHsgR0xURkxvYWRlckV4dGVuc2lvbiwgR0xURkxvYWRlciwgR0xURkxvYWRlckJhc2UgfSBmcm9tIFwiLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB7IEdMVEZVdGlscyB9IGZyb20gXCIuL2dsVEZMb2FkZXJVdGlsc1wiO1xyXG5pbXBvcnQgdHlwZSB7IFNjZW5lIH0gZnJvbSBcImNvcmUvc2NlbmVcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckRhdGEgfSBmcm9tIFwiLi4vZ2xURkZpbGVMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURlJ1bnRpbWUsIElHTFRGVGV4dHVyZSwgSUdMVEZJbWFnZSwgSUdMVEZCdWZmZXJWaWV3LCBJR0xURlNoYWRlciB9IGZyb20gXCIuL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB7IEVDb21wb25lbnRUeXBlIH0gZnJvbSBcIi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSURhdGFCdWZmZXIgfSBmcm9tIFwiY29yZS9NaXNjL2RhdGFSZWFkZXJcIjtcclxuXHJcbmNvbnN0IEJpbmFyeUV4dGVuc2lvbkJ1ZmZlck5hbWUgPSBcImJpbmFyeV9nbFRGXCI7XHJcblxyXG5pbnRlcmZhY2UgSUdMVEZCaW5hcnlFeHRlbnNpb25TaGFkZXIge1xyXG4gICAgYnVmZmVyVmlldzogc3RyaW5nO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgSUdMVEZCaW5hcnlFeHRlbnNpb25JbWFnZSB7XHJcbiAgICBidWZmZXJWaWV3OiBzdHJpbmc7XHJcbiAgICBtaW1lVHlwZTogc3RyaW5nO1xyXG4gICAgaGVpZ2h0OiBudW1iZXI7XHJcbiAgICB3aWR0aDogbnVtYmVyO1xyXG59XHJcblxyXG4vKipcclxuICogQGludGVybmFsXHJcbiAqIEBkZXByZWNhdGVkXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgR0xURkJpbmFyeUV4dGVuc2lvbiBleHRlbmRzIEdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgcHJpdmF0ZSBfYmluOiBJRGF0YUJ1ZmZlcjtcclxuXHJcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgc3VwZXIoXCJLSFJfYmluYXJ5X2dsVEZcIik7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIG92ZXJyaWRlIGxvYWRSdW50aW1lQXN5bmMoc2NlbmU6IFNjZW5lLCBkYXRhOiBJR0xURkxvYWRlckRhdGEsIHJvb3RVcmw6IHN0cmluZywgb25TdWNjZXNzOiAoZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSkgPT4gdm9pZCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbnNVc2VkID0gKDxhbnk+ZGF0YS5qc29uKS5leHRlbnNpb25zVXNlZDtcclxuICAgICAgICBpZiAoIWV4dGVuc2lvbnNVc2VkIHx8IGV4dGVuc2lvbnNVc2VkLmluZGV4T2YodGhpcy5uYW1lKSA9PT0gLTEgfHwgIWRhdGEuYmluKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2JpbiA9IGRhdGEuYmluO1xyXG4gICAgICAgIG9uU3VjY2VzcyhHTFRGTG9hZGVyQmFzZS5DcmVhdGVSdW50aW1lKGRhdGEuanNvbiwgc2NlbmUsIHJvb3RVcmwpKTtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgb3ZlcnJpZGUgbG9hZEJ1ZmZlckFzeW5jKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsIGlkOiBzdHJpbmcsIG9uU3VjY2VzczogKGJ1ZmZlcjogQXJyYXlCdWZmZXJWaWV3KSA9PiB2b2lkLCBvbkVycm9yOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkKTogYm9vbGVhbiB7XHJcbiAgICAgICAgaWYgKGdsdGZSdW50aW1lLmV4dGVuc2lvbnNVc2VkLmluZGV4T2YodGhpcy5uYW1lKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGlkICE9PSBCaW5hcnlFeHRlbnNpb25CdWZmZXJOYW1lKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2Jpbi5yZWFkQXN5bmMoMCwgdGhpcy5fYmluLmJ5dGVMZW5ndGgpLnRoZW4ob25TdWNjZXNzLCAoZXJyb3IpID0+IG9uRXJyb3IoZXJyb3IubWVzc2FnZSkpO1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBvdmVycmlkZSBsb2FkVGV4dHVyZUJ1ZmZlckFzeW5jKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsIGlkOiBzdHJpbmcsIG9uU3VjY2VzczogKGJ1ZmZlcjogQXJyYXlCdWZmZXJWaWV3KSA9PiB2b2lkKTogYm9vbGVhbiB7XHJcbiAgICAgICAgY29uc3QgdGV4dHVyZTogSUdMVEZUZXh0dXJlID0gZ2x0ZlJ1bnRpbWUudGV4dHVyZXNbaWRdO1xyXG4gICAgICAgIGNvbnN0IHNvdXJjZTogSUdMVEZJbWFnZSA9IGdsdGZSdW50aW1lLmltYWdlc1t0ZXh0dXJlLnNvdXJjZV07XHJcbiAgICAgICAgaWYgKCFzb3VyY2UuZXh0ZW5zaW9ucyB8fCAhKHRoaXMubmFtZSBpbiBzb3VyY2UuZXh0ZW5zaW9ucykpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3Qgc291cmNlRXh0OiBJR0xURkJpbmFyeUV4dGVuc2lvbkltYWdlID0gc291cmNlLmV4dGVuc2lvbnNbdGhpcy5uYW1lXTtcclxuICAgICAgICBjb25zdCBidWZmZXJWaWV3OiBJR0xURkJ1ZmZlclZpZXcgPSBnbHRmUnVudGltZS5idWZmZXJWaWV3c1tzb3VyY2VFeHQuYnVmZmVyVmlld107XHJcbiAgICAgICAgY29uc3QgYnVmZmVyID0gR0xURlV0aWxzLkdldEJ1ZmZlckZyb21CdWZmZXJWaWV3KGdsdGZSdW50aW1lLCBidWZmZXJWaWV3LCAwLCBidWZmZXJWaWV3LmJ5dGVMZW5ndGgsIEVDb21wb25lbnRUeXBlLlVOU0lHTkVEX0JZVEUpO1xyXG4gICAgICAgIG9uU3VjY2VzcyhidWZmZXIpO1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBvdmVycmlkZSBsb2FkU2hhZGVyU3RyaW5nQXN5bmMoZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSwgaWQ6IHN0cmluZywgb25TdWNjZXNzOiAoc2hhZGVyU3RyaW5nOiBzdHJpbmcpID0+IHZvaWQpOiBib29sZWFuIHtcclxuICAgICAgICBjb25zdCBzaGFkZXI6IElHTFRGU2hhZGVyID0gZ2x0ZlJ1bnRpbWUuc2hhZGVyc1tpZF07XHJcbiAgICAgICAgaWYgKCFzaGFkZXIuZXh0ZW5zaW9ucyB8fCAhKHRoaXMubmFtZSBpbiBzaGFkZXIuZXh0ZW5zaW9ucykpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgYmluYXJ5RXh0ZW5zaW9uU2hhZGVyOiBJR0xURkJpbmFyeUV4dGVuc2lvblNoYWRlciA9IHNoYWRlci5leHRlbnNpb25zW3RoaXMubmFtZV07XHJcbiAgICAgICAgY29uc3QgYnVmZmVyVmlldzogSUdMVEZCdWZmZXJWaWV3ID0gZ2x0ZlJ1bnRpbWUuYnVmZmVyVmlld3NbYmluYXJ5RXh0ZW5zaW9uU2hhZGVyLmJ1ZmZlclZpZXddO1xyXG4gICAgICAgIGNvbnN0IHNoYWRlckJ5dGVzID0gR0xURlV0aWxzLkdldEJ1ZmZlckZyb21CdWZmZXJWaWV3KGdsdGZSdW50aW1lLCBidWZmZXJWaWV3LCAwLCBidWZmZXJWaWV3LmJ5dGVMZW5ndGgsIEVDb21wb25lbnRUeXBlLlVOU0lHTkVEX0JZVEUpO1xyXG5cclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgY29uc3Qgc2hhZGVyU3RyaW5nID0gR0xURlV0aWxzLkRlY29kZUJ1ZmZlclRvVGV4dChzaGFkZXJCeXRlcyk7XHJcbiAgICAgICAgICAgIG9uU3VjY2VzcyhzaGFkZXJTdHJpbmcpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxufVxyXG5cclxuR0xURkxvYWRlci5SZWdpc3RlckV4dGVuc2lvbihuZXcgR0xURkJpbmFyeUV4dGVuc2lvbigpKTtcclxuIiwiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzICovXHJcbmltcG9ydCB0eXBlIHtcclxuICAgIElHTFRGUnVudGltZSxcclxuICAgIElHTFRGVGVjaG5pcXVlUGFyYW1ldGVyLFxyXG4gICAgSUdMVEZBbmltYXRpb24sXHJcbiAgICBJR0xURkFuaW1hdGlvblNhbXBsZXIsXHJcbiAgICBJR0xURk5vZGUsXHJcbiAgICBJR0xURlNraW5zLFxyXG4gICAgSU5vZGVUb1Jvb3QsXHJcbiAgICBJSm9pbnROb2RlLFxyXG4gICAgSUdMVEZNZXNoLFxyXG4gICAgSUdMVEZBY2Nlc3NvcixcclxuICAgIElHTFRGTGlnaHQsXHJcbiAgICBJR0xURkFtYmllbkxpZ2h0LFxyXG4gICAgSUdMVEZEaXJlY3Rpb25hbExpZ2h0LFxyXG4gICAgSUdMVEZQb2ludExpZ2h0LFxyXG4gICAgSUdMVEZTcG90TGlnaHQsXHJcbiAgICBJR0xURkNhbWVyYSxcclxuICAgIElHTFRGQ2FtZXJhUGVyc3BlY3RpdmUsXHJcbiAgICBJR0xURlNjZW5lLFxyXG4gICAgSUdMVEZUZWNobmlxdWUsXHJcbiAgICBJR0xURk1hdGVyaWFsLFxyXG4gICAgSUdMVEZQcm9ncmFtLFxyXG4gICAgSUdMVEZCdWZmZXIsXHJcbiAgICBJR0xURlRleHR1cmUsXHJcbiAgICBJR0xURkltYWdlLFxyXG4gICAgSUdMVEZTYW1wbGVyLFxyXG4gICAgSUdMVEZTaGFkZXIsXHJcbiAgICBJR0xURlRlY2huaXF1ZVN0YXRlcyxcclxufSBmcm9tIFwiLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgeyBFUGFyYW1ldGVyVHlwZSwgRVRleHR1cmVGaWx0ZXJUeXBlLCBFQ3VsbGluZ1R5cGUsIEVCbGVuZGluZ0Z1bmN0aW9uLCBFU2hhZGVyVHlwZSB9IGZyb20gXCIuL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IEZsb2F0QXJyYXksIE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgUXVhdGVybmlvbiwgVmVjdG9yMywgTWF0cml4IH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC52ZWN0b3JcIjtcclxuaW1wb3J0IHsgQ29sb3IzIH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC5jb2xvclwiO1xyXG5pbXBvcnQgeyBUb29scyB9IGZyb20gXCJjb3JlL01pc2MvdG9vbHNcIjtcclxuaW1wb3J0IHsgQ2FtZXJhIH0gZnJvbSBcImNvcmUvQ2FtZXJhcy9jYW1lcmFcIjtcclxuaW1wb3J0IHsgRnJlZUNhbWVyYSB9IGZyb20gXCJjb3JlL0NhbWVyYXMvZnJlZUNhbWVyYVwiO1xyXG5pbXBvcnQgeyBBbmltYXRpb24gfSBmcm9tIFwiY29yZS9BbmltYXRpb25zL2FuaW1hdGlvblwiO1xyXG5pbXBvcnQgeyBCb25lIH0gZnJvbSBcImNvcmUvQm9uZXMvYm9uZVwiO1xyXG5pbXBvcnQgeyBTa2VsZXRvbiB9IGZyb20gXCJjb3JlL0JvbmVzL3NrZWxldG9uXCI7XHJcbmltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9lZmZlY3RcIjtcclxuaW1wb3J0IHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuaW1wb3J0IHsgTXVsdGlNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tdWx0aU1hdGVyaWFsXCI7XHJcbmltcG9ydCB7IFN0YW5kYXJkTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvc3RhbmRhcmRNYXRlcmlhbFwiO1xyXG5pbXBvcnQgeyBTaGFkZXJNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9zaGFkZXJNYXRlcmlhbFwiO1xyXG5pbXBvcnQgeyBUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL3RleHR1cmVcIjtcclxuaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSBcImNvcmUvbm9kZVwiO1xyXG5pbXBvcnQgeyBWZXJ0ZXhEYXRhIH0gZnJvbSBcImNvcmUvTWVzaGVzL21lc2gudmVydGV4RGF0YVwiO1xyXG5pbXBvcnQgeyBWZXJ0ZXhCdWZmZXIgfSBmcm9tIFwiY29yZS9CdWZmZXJzL2J1ZmZlclwiO1xyXG5pbXBvcnQgeyBHZW9tZXRyeSB9IGZyb20gXCJjb3JlL01lc2hlcy9nZW9tZXRyeVwiO1xyXG5pbXBvcnQgeyBTdWJNZXNoIH0gZnJvbSBcImNvcmUvTWVzaGVzL3N1Yk1lc2hcIjtcclxuaW1wb3J0IHsgQWJzdHJhY3RNZXNoIH0gZnJvbSBcImNvcmUvTWVzaGVzL2Fic3RyYWN0TWVzaFwiO1xyXG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcImNvcmUvTWVzaGVzL21lc2hcIjtcclxuaW1wb3J0IHsgSGVtaXNwaGVyaWNMaWdodCB9IGZyb20gXCJjb3JlL0xpZ2h0cy9oZW1pc3BoZXJpY0xpZ2h0XCI7XHJcbmltcG9ydCB7IERpcmVjdGlvbmFsTGlnaHQgfSBmcm9tIFwiY29yZS9MaWdodHMvZGlyZWN0aW9uYWxMaWdodFwiO1xyXG5pbXBvcnQgeyBQb2ludExpZ2h0IH0gZnJvbSBcImNvcmUvTGlnaHRzL3BvaW50TGlnaHRcIjtcclxuaW1wb3J0IHsgU3BvdExpZ2h0IH0gZnJvbSBcImNvcmUvTGlnaHRzL3Nwb3RMaWdodFwiO1xyXG5pbXBvcnQgdHlwZSB7IElTY2VuZUxvYWRlckFzeW5jUmVzdWx0LCBJU2NlbmVMb2FkZXJQcm9ncmVzc0V2ZW50IH0gZnJvbSBcImNvcmUvTG9hZGluZy9zY2VuZUxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IFNjZW5lIH0gZnJvbSBcImNvcmUvc2NlbmVcIjtcclxuXHJcbmltcG9ydCB7IEdMVEZVdGlscyB9IGZyb20gXCIuL2dsVEZMb2FkZXJVdGlsc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyLCBJR0xURkxvYWRlckRhdGEgfSBmcm9tIFwiLi4vZ2xURkZpbGVMb2FkZXJcIjtcclxuaW1wb3J0IHsgR0xURkZpbGVMb2FkZXIgfSBmcm9tIFwiLi4vZ2xURkZpbGVMb2FkZXJcIjtcclxuaW1wb3J0IHsgQ29uc3RhbnRzIH0gZnJvbSBcImNvcmUvRW5naW5lcy9jb25zdGFudHNcIjtcclxuaW1wb3J0IHR5cGUgeyBBc3NldENvbnRhaW5lciB9IGZyb20gXCJjb3JlL2Fzc2V0Q29udGFpbmVyXCI7XHJcblxyXG4vKipcclxuICogVG9rZW5pemVyLiBVc2VkIGZvciBzaGFkZXJzIGNvbXBhdGliaWxpdHlcclxuICogQXV0b21hdGljYWxseSBtYXAgd29ybGQsIHZpZXcsIHByb2plY3Rpb24sIHdvcmxkVmlld1Byb2plY3Rpb24sIGF0dHJpYnV0ZXMgYW5kIHNvIG9uXHJcbiAqL1xyXG5lbnVtIEVUb2tlblR5cGUge1xyXG4gICAgSURFTlRJRklFUiA9IDEsXHJcblxyXG4gICAgVU5LTk9XTiA9IDIsXHJcbiAgICBFTkRfT0ZfSU5QVVQgPSAzLFxyXG59XHJcblxyXG5jbGFzcyBUb2tlbml6ZXIge1xyXG4gICAgcHJpdmF0ZSBfdG9QYXJzZTogc3RyaW5nO1xyXG4gICAgcHJpdmF0ZSBfcG9zOiBudW1iZXIgPSAwO1xyXG4gICAgcHJpdmF0ZSBfbWF4UG9zOiBudW1iZXI7XHJcblxyXG4gICAgcHVibGljIGN1cnJlbnRUb2tlbjogRVRva2VuVHlwZSA9IEVUb2tlblR5cGUuVU5LTk9XTjtcclxuICAgIHB1YmxpYyBjdXJyZW50SWRlbnRpZmllcjogc3RyaW5nID0gXCJcIjtcclxuICAgIHB1YmxpYyBjdXJyZW50U3RyaW5nOiBzdHJpbmcgPSBcIlwiO1xyXG4gICAgcHVibGljIGlzTGV0dGVyT3JEaWdpdFBhdHRlcm46IFJlZ0V4cCA9IC9eW2EtekEtWjAtOV0rJC87XHJcblxyXG4gICAgY29uc3RydWN0b3IodG9QYXJzZTogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5fdG9QYXJzZSA9IHRvUGFyc2U7XHJcbiAgICAgICAgdGhpcy5fbWF4UG9zID0gdG9QYXJzZS5sZW5ndGg7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldE5leHRUb2tlbigpOiBFVG9rZW5UeXBlIHtcclxuICAgICAgICBpZiAodGhpcy5pc0VuZCgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBFVG9rZW5UeXBlLkVORF9PRl9JTlBVVDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuY3VycmVudFN0cmluZyA9IHRoaXMucmVhZCgpO1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuID0gRVRva2VuVHlwZS5VTktOT1dOO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5jdXJyZW50U3RyaW5nID09PSBcIl9cIiB8fCB0aGlzLmlzTGV0dGVyT3JEaWdpdFBhdHRlcm4udGVzdCh0aGlzLmN1cnJlbnRTdHJpbmcpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFRva2VuID0gRVRva2VuVHlwZS5JREVOVElGSUVSO1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRJZGVudGlmaWVyID0gdGhpcy5jdXJyZW50U3RyaW5nO1xyXG4gICAgICAgICAgICB3aGlsZSAoIXRoaXMuaXNFbmQoKSAmJiAodGhpcy5pc0xldHRlck9yRGlnaXRQYXR0ZXJuLnRlc3QoKHRoaXMuY3VycmVudFN0cmluZyA9IHRoaXMucGVlaygpKSkgfHwgdGhpcy5jdXJyZW50U3RyaW5nID09PSBcIl9cIikpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudElkZW50aWZpZXIgKz0gdGhpcy5jdXJyZW50U3RyaW5nO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5mb3J3YXJkKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRUb2tlbjtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcGVlaygpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl90b1BhcnNlW3RoaXMuX3Bvc107XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJlYWQoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdG9QYXJzZVt0aGlzLl9wb3MrK107XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGZvcndhcmQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fcG9zKys7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGlzRW5kKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wb3MgPj0gdGhpcy5fbWF4UG9zO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogVmFsdWVzXHJcbiAqL1xyXG5jb25zdCBnbFRGVHJhbnNmb3JtcyA9IFtcIk1PREVMXCIsIFwiVklFV1wiLCBcIlBST0pFQ1RJT05cIiwgXCJNT0RFTFZJRVdcIiwgXCJNT0RFTFZJRVdQUk9KRUNUSU9OXCIsIFwiSk9JTlRNQVRSSVhcIl07XHJcbmNvbnN0IGJhYnlsb25UcmFuc2Zvcm1zID0gW1wid29ybGRcIiwgXCJ2aWV3XCIsIFwicHJvamVjdGlvblwiLCBcIndvcmxkVmlld1wiLCBcIndvcmxkVmlld1Byb2plY3Rpb25cIiwgXCJtQm9uZXNcIl07XHJcblxyXG5jb25zdCBnbFRGQW5pbWF0aW9uUGF0aHMgPSBbXCJ0cmFuc2xhdGlvblwiLCBcInJvdGF0aW9uXCIsIFwic2NhbGVcIl07XHJcbmNvbnN0IGJhYnlsb25BbmltYXRpb25QYXRocyA9IFtcInBvc2l0aW9uXCIsIFwicm90YXRpb25RdWF0ZXJuaW9uXCIsIFwic2NhbGluZ1wiXTtcclxuXHJcbi8qKlxyXG4gKiBQYXJzZVxyXG4gKiBAcGFyYW0gcGFyc2VkQnVmZmVyc1xyXG4gKiBAcGFyYW0gZ2x0ZlJ1bnRpbWVcclxuICovXHJcbmNvbnN0IHBhcnNlQnVmZmVycyA9IChwYXJzZWRCdWZmZXJzOiBhbnksIGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUpID0+IHtcclxuICAgIGZvciAoY29uc3QgYnVmIGluIHBhcnNlZEJ1ZmZlcnMpIHtcclxuICAgICAgICBjb25zdCBwYXJzZWRCdWZmZXIgPSBwYXJzZWRCdWZmZXJzW2J1Zl07XHJcbiAgICAgICAgZ2x0ZlJ1bnRpbWUuYnVmZmVyc1tidWZdID0gcGFyc2VkQnVmZmVyO1xyXG4gICAgICAgIGdsdGZSdW50aW1lLmJ1ZmZlcnNDb3VudCsrO1xyXG4gICAgfVxyXG59O1xyXG5cclxuY29uc3QgcGFyc2VTaGFkZXJzID0gKHBhcnNlZFNoYWRlcnM6IGFueSwgZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSkgPT4ge1xyXG4gICAgZm9yIChjb25zdCBzaGEgaW4gcGFyc2VkU2hhZGVycykge1xyXG4gICAgICAgIGNvbnN0IHBhcnNlZFNoYWRlciA9IHBhcnNlZFNoYWRlcnNbc2hhXTtcclxuICAgICAgICBnbHRmUnVudGltZS5zaGFkZXJzW3NoYV0gPSBwYXJzZWRTaGFkZXI7XHJcbiAgICAgICAgZ2x0ZlJ1bnRpbWUuc2hhZGVyc2NvdW50Kys7XHJcbiAgICB9XHJcbn07XHJcblxyXG5jb25zdCBwYXJzZU9iamVjdCA9IChwYXJzZWRPYmplY3RzOiBhbnksIHJ1bnRpbWVQcm9wZXJ0eTogc3RyaW5nLCBnbHRmUnVudGltZTogSUdMVEZSdW50aW1lKSA9PiB7XHJcbiAgICBmb3IgKGNvbnN0IG9iamVjdCBpbiBwYXJzZWRPYmplY3RzKSB7XHJcbiAgICAgICAgY29uc3QgcGFyc2VkT2JqZWN0ID0gcGFyc2VkT2JqZWN0c1tvYmplY3RdO1xyXG4gICAgICAgICg8YW55PmdsdGZSdW50aW1lKVtydW50aW1lUHJvcGVydHldW29iamVjdF0gPSBwYXJzZWRPYmplY3Q7XHJcbiAgICB9XHJcbn07XHJcblxyXG4vKipcclxuICogVXRpbHNcclxuICogQHBhcmFtIGJ1ZmZlclxyXG4gKi9cclxuY29uc3Qgbm9ybWFsaXplVVZzID0gKGJ1ZmZlcjogYW55KSA9PiB7XHJcbiAgICBpZiAoIWJ1ZmZlcikge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1ZmZlci5sZW5ndGggLyAyOyBpKyspIHtcclxuICAgICAgICBidWZmZXJbaSAqIDIgKyAxXSA9IDEuMCAtIGJ1ZmZlcltpICogMiArIDFdO1xyXG4gICAgfVxyXG59O1xyXG5cclxuY29uc3QgZ2V0QXR0cmlidXRlID0gKGF0dHJpYnV0ZVBhcmFtZXRlcjogSUdMVEZUZWNobmlxdWVQYXJhbWV0ZXIpOiBOdWxsYWJsZTxzdHJpbmc+ID0+IHtcclxuICAgIGlmIChhdHRyaWJ1dGVQYXJhbWV0ZXIuc2VtYW50aWMgPT09IFwiTk9STUFMXCIpIHtcclxuICAgICAgICByZXR1cm4gXCJub3JtYWxcIjtcclxuICAgIH0gZWxzZSBpZiAoYXR0cmlidXRlUGFyYW1ldGVyLnNlbWFudGljID09PSBcIlBPU0lUSU9OXCIpIHtcclxuICAgICAgICByZXR1cm4gXCJwb3NpdGlvblwiO1xyXG4gICAgfSBlbHNlIGlmIChhdHRyaWJ1dGVQYXJhbWV0ZXIuc2VtYW50aWMgPT09IFwiSk9JTlRcIikge1xyXG4gICAgICAgIHJldHVybiBcIm1hdHJpY2VzSW5kaWNlc1wiO1xyXG4gICAgfSBlbHNlIGlmIChhdHRyaWJ1dGVQYXJhbWV0ZXIuc2VtYW50aWMgPT09IFwiV0VJR0hUXCIpIHtcclxuICAgICAgICByZXR1cm4gXCJtYXRyaWNlc1dlaWdodHNcIjtcclxuICAgIH0gZWxzZSBpZiAoYXR0cmlidXRlUGFyYW1ldGVyLnNlbWFudGljID09PSBcIkNPTE9SXCIpIHtcclxuICAgICAgICByZXR1cm4gXCJjb2xvclwiO1xyXG4gICAgfSBlbHNlIGlmIChhdHRyaWJ1dGVQYXJhbWV0ZXIuc2VtYW50aWMgJiYgYXR0cmlidXRlUGFyYW1ldGVyLnNlbWFudGljLmluZGV4T2YoXCJURVhDT09SRF9cIikgIT09IC0xKSB7XHJcbiAgICAgICAgY29uc3QgY2hhbm5lbCA9IE51bWJlcihhdHRyaWJ1dGVQYXJhbWV0ZXIuc2VtYW50aWMuc3BsaXQoXCJfXCIpWzFdKTtcclxuICAgICAgICByZXR1cm4gXCJ1dlwiICsgKGNoYW5uZWwgPT09IDAgPyBcIlwiIDogY2hhbm5lbCArIDEpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBudWxsO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIExvYWRzIGFuZCBjcmVhdGVzIGFuaW1hdGlvbnNcclxuICogQHBhcmFtIGdsdGZSdW50aW1lXHJcbiAqL1xyXG5jb25zdCBsb2FkQW5pbWF0aW9ucyA9IChnbHRmUnVudGltZTogSUdMVEZSdW50aW1lKSA9PiB7XHJcbiAgICBmb3IgKGNvbnN0IGFuaW0gaW4gZ2x0ZlJ1bnRpbWUuYW5pbWF0aW9ucykge1xyXG4gICAgICAgIGNvbnN0IGFuaW1hdGlvbjogSUdMVEZBbmltYXRpb24gPSBnbHRmUnVudGltZS5hbmltYXRpb25zW2FuaW1dO1xyXG5cclxuICAgICAgICBpZiAoIWFuaW1hdGlvbi5jaGFubmVscyB8fCAhYW5pbWF0aW9uLnNhbXBsZXJzKSB7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGxhc3RBbmltYXRpb246IE51bGxhYmxlPEFuaW1hdGlvbj4gPSBudWxsO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFuaW1hdGlvbi5jaGFubmVscy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAvLyBHZXQgcGFyYW1ldGVycyBhbmQgbG9hZCBidWZmZXJzXHJcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWwgPSBhbmltYXRpb24uY2hhbm5lbHNbaV07XHJcbiAgICAgICAgICAgIGNvbnN0IHNhbXBsZXI6IElHTFRGQW5pbWF0aW9uU2FtcGxlciA9IGFuaW1hdGlvbi5zYW1wbGVyc1tjaGFubmVsLnNhbXBsZXJdO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFzYW1wbGVyKSB7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGV0IGlucHV0RGF0YTogTnVsbGFibGU8c3RyaW5nPiA9IG51bGw7XHJcbiAgICAgICAgICAgIGxldCBvdXRwdXREYXRhOiBOdWxsYWJsZTxzdHJpbmc+ID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgIGlmIChhbmltYXRpb24ucGFyYW1ldGVycykge1xyXG4gICAgICAgICAgICAgICAgaW5wdXREYXRhID0gYW5pbWF0aW9uLnBhcmFtZXRlcnNbc2FtcGxlci5pbnB1dF07XHJcbiAgICAgICAgICAgICAgICBvdXRwdXREYXRhID0gYW5pbWF0aW9uLnBhcmFtZXRlcnNbc2FtcGxlci5vdXRwdXRdO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaW5wdXREYXRhID0gc2FtcGxlci5pbnB1dDtcclxuICAgICAgICAgICAgICAgIG91dHB1dERhdGEgPSBzYW1wbGVyLm91dHB1dDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgYnVmZmVySW5wdXQgPSBHTFRGVXRpbHMuR2V0QnVmZmVyRnJvbUFjY2Vzc29yKGdsdGZSdW50aW1lLCBnbHRmUnVudGltZS5hY2Nlc3NvcnNbaW5wdXREYXRhXSk7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlck91dHB1dCA9IEdMVEZVdGlscy5HZXRCdWZmZXJGcm9tQWNjZXNzb3IoZ2x0ZlJ1bnRpbWUsIGdsdGZSdW50aW1lLmFjY2Vzc29yc1tvdXRwdXREYXRhXSk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCB0YXJnZXRJZCA9IGNoYW5uZWwudGFyZ2V0LmlkO1xyXG4gICAgICAgICAgICBsZXQgdGFyZ2V0Tm9kZTogYW55ID0gZ2x0ZlJ1bnRpbWUuc2NlbmUuZ2V0Tm9kZUJ5SWQodGFyZ2V0SWQpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRhcmdldE5vZGUgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHRhcmdldE5vZGUgPSBnbHRmUnVudGltZS5zY2VuZS5nZXROb2RlQnlOYW1lKHRhcmdldElkKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHRhcmdldE5vZGUgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIFRvb2xzLldhcm4oXCJDcmVhdGluZyBhbmltYXRpb24gbmFtZWQgXCIgKyBhbmltICsgXCIuIEJ1dCBjYW5ub3QgZmluZCBub2RlIG5hbWVkIFwiICsgdGFyZ2V0SWQgKyBcIiB0byBhdHRhY2ggdG9cIik7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgaXNCb25lID0gdGFyZ2V0Tm9kZSBpbnN0YW5jZW9mIEJvbmU7XHJcblxyXG4gICAgICAgICAgICAvLyBHZXQgdGFyZ2V0IHBhdGggKHBvc2l0aW9uLCByb3RhdGlvbiBvciBzY2FsaW5nKVxyXG4gICAgICAgICAgICBsZXQgdGFyZ2V0UGF0aCA9IGNoYW5uZWwudGFyZ2V0LnBhdGg7XHJcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldFBhdGhJbmRleCA9IGdsVEZBbmltYXRpb25QYXRocy5pbmRleE9mKHRhcmdldFBhdGgpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRhcmdldFBhdGhJbmRleCAhPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHRhcmdldFBhdGggPSBiYWJ5bG9uQW5pbWF0aW9uUGF0aHNbdGFyZ2V0UGF0aEluZGV4XTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIGFuaW1hdGlvbiB0eXBlXHJcbiAgICAgICAgICAgIGxldCBhbmltYXRpb25UeXBlID0gQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfTUFUUklYO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFpc0JvbmUpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0YXJnZXRQYXRoID09PSBcInJvdGF0aW9uUXVhdGVybmlvblwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uVHlwZSA9IEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX1FVQVRFUk5JT047XHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Tm9kZS5yb3RhdGlvblF1YXRlcm5pb24gPSBuZXcgUXVhdGVybmlvbigpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25UeXBlID0gQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfVkVDVE9SMztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gQ3JlYXRlIGFuaW1hdGlvbiBhbmQga2V5IGZyYW1lc1xyXG4gICAgICAgICAgICBsZXQgYmFieWxvbkFuaW1hdGlvbjogTnVsbGFibGU8QW5pbWF0aW9uPiA9IG51bGw7XHJcbiAgICAgICAgICAgIGNvbnN0IGtleXMgPSBbXTtcclxuICAgICAgICAgICAgbGV0IGFycmF5T2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgbGV0IG1vZGlmeUtleSA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgaWYgKGlzQm9uZSAmJiBsYXN0QW5pbWF0aW9uICYmIGxhc3RBbmltYXRpb24uZ2V0S2V5cygpLmxlbmd0aCA9PT0gYnVmZmVySW5wdXQubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uQW5pbWF0aW9uID0gbGFzdEFuaW1hdGlvbjtcclxuICAgICAgICAgICAgICAgIG1vZGlmeUtleSA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghbW9kaWZ5S2V5KSB7XHJcbiAgICAgICAgICAgICAgICBnbHRmUnVudGltZS5zY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gISFnbHRmUnVudGltZS5hc3NldENvbnRhaW5lcjtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25BbmltYXRpb24gPSBuZXcgQW5pbWF0aW9uKGFuaW0sIGlzQm9uZSA/IFwiX21hdHJpeFwiIDogdGFyZ2V0UGF0aCwgMSwgYW5pbWF0aW9uVHlwZSwgQW5pbWF0aW9uLkFOSU1BVElPTkxPT1BNT0RFX0NZQ0xFKTtcclxuICAgICAgICAgICAgICAgIGdsdGZSdW50aW1lLnNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gRm9yIGVhY2ggZnJhbWVcclxuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBidWZmZXJJbnB1dC5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IHZhbHVlOiBhbnkgPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0YXJnZXRQYXRoID09PSBcInJvdGF0aW9uUXVhdGVybmlvblwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVkVDNFxyXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gUXVhdGVybmlvbi5Gcm9tQXJyYXkoW2J1ZmZlck91dHB1dFthcnJheU9mZnNldF0sIGJ1ZmZlck91dHB1dFthcnJheU9mZnNldCArIDFdLCBidWZmZXJPdXRwdXRbYXJyYXlPZmZzZXQgKyAyXSwgYnVmZmVyT3V0cHV0W2FycmF5T2Zmc2V0ICsgM11dKTtcclxuICAgICAgICAgICAgICAgICAgICBhcnJheU9mZnNldCArPSA0O1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBQb3NpdGlvbiBhbmQgc2NhbGluZyBhcmUgVkVDM1xyXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gVmVjdG9yMy5Gcm9tQXJyYXkoW2J1ZmZlck91dHB1dFthcnJheU9mZnNldF0sIGJ1ZmZlck91dHB1dFthcnJheU9mZnNldCArIDFdLCBidWZmZXJPdXRwdXRbYXJyYXlPZmZzZXQgKyAyXV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGFycmF5T2Zmc2V0ICs9IDM7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGlzQm9uZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJvbmUgPSA8Qm9uZT50YXJnZXROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCB0cmFuc2xhdGlvbiA9IFZlY3RvcjMuWmVybygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCByb3RhdGlvblF1YXRlcm5pb24gPSBuZXcgUXVhdGVybmlvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBzY2FsaW5nID0gVmVjdG9yMy5aZXJvKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIFdhcm5pbmcgb24gZGVjb21wb3NlXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IG1hdCA9IGJvbmUuZ2V0QmFzZU1hdHJpeCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAobW9kaWZ5S2V5ICYmIGxhc3RBbmltYXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWF0ID0gbGFzdEFuaW1hdGlvbi5nZXRLZXlzKClbal0udmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBtYXQuZGVjb21wb3NlKHNjYWxpbmcsIHJvdGF0aW9uUXVhdGVybmlvbiwgdHJhbnNsYXRpb24pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0UGF0aCA9PT0gXCJwb3NpdGlvblwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0aW9uID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRQYXRoID09PSBcInJvdGF0aW9uUXVhdGVybmlvblwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJvdGF0aW9uUXVhdGVybmlvbiA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxpbmcgPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gTWF0cml4LkNvbXBvc2Uoc2NhbGluZywgcm90YXRpb25RdWF0ZXJuaW9uLCB0cmFuc2xhdGlvbik7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCFtb2RpZnlLZXkpIHtcclxuICAgICAgICAgICAgICAgICAgICBrZXlzLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmcmFtZTogYnVmZmVySW5wdXRbal0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobGFzdEFuaW1hdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGxhc3RBbmltYXRpb24uZ2V0S2V5cygpW2pdLnZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIEZpbmlzaFxyXG4gICAgICAgICAgICBpZiAoIW1vZGlmeUtleSAmJiBiYWJ5bG9uQW5pbWF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uQW5pbWF0aW9uLnNldEtleXMoa2V5cyk7XHJcbiAgICAgICAgICAgICAgICB0YXJnZXROb2RlLmFuaW1hdGlvbnMucHVzaChiYWJ5bG9uQW5pbWF0aW9uKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGFzdEFuaW1hdGlvbiA9IGJhYnlsb25BbmltYXRpb247XHJcblxyXG4gICAgICAgICAgICBnbHRmUnVudGltZS5zY2VuZS5zdG9wQW5pbWF0aW9uKHRhcmdldE5vZGUpO1xyXG4gICAgICAgICAgICBnbHRmUnVudGltZS5zY2VuZS5iZWdpbkFuaW1hdGlvbih0YXJnZXROb2RlLCAwLCBidWZmZXJJbnB1dFtidWZmZXJJbnB1dC5sZW5ndGggLSAxXSwgdHJ1ZSwgMS4wKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn07XHJcblxyXG4vKipcclxuICogQHJldHVybnMgdGhlIGJvbmVzIHRyYW5zZm9ybWF0aW9uIG1hdHJpeFxyXG4gKiBAcGFyYW0gbm9kZVxyXG4gKi9cclxuY29uc3QgY29uZmlndXJlQm9uZVRyYW5zZm9ybWF0aW9uID0gKG5vZGU6IElHTFRGTm9kZSk6IE1hdHJpeCA9PiB7XHJcbiAgICBsZXQgbWF0OiBOdWxsYWJsZTxNYXRyaXg+ID0gbnVsbDtcclxuXHJcbiAgICBpZiAobm9kZS50cmFuc2xhdGlvbiB8fCBub2RlLnJvdGF0aW9uIHx8IG5vZGUuc2NhbGUpIHtcclxuICAgICAgICBjb25zdCBzY2FsZSA9IFZlY3RvcjMuRnJvbUFycmF5KG5vZGUuc2NhbGUgfHwgWzEsIDEsIDFdKTtcclxuICAgICAgICBjb25zdCByb3RhdGlvbiA9IFF1YXRlcm5pb24uRnJvbUFycmF5KG5vZGUucm90YXRpb24gfHwgWzAsIDAsIDAsIDFdKTtcclxuICAgICAgICBjb25zdCBwb3NpdGlvbiA9IFZlY3RvcjMuRnJvbUFycmF5KG5vZGUudHJhbnNsYXRpb24gfHwgWzAsIDAsIDBdKTtcclxuXHJcbiAgICAgICAgbWF0ID0gTWF0cml4LkNvbXBvc2Uoc2NhbGUsIHJvdGF0aW9uLCBwb3NpdGlvbik7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIG1hdCA9IE1hdHJpeC5Gcm9tQXJyYXkobm9kZS5tYXRyaXgpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBtYXQ7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGUgcGFyZW50IGJvbmVcclxuICogQHBhcmFtIGdsdGZSdW50aW1lXHJcbiAqIEBwYXJhbSBza2luc1xyXG4gKiBAcGFyYW0gam9pbnROYW1lXHJcbiAqIEBwYXJhbSBuZXdTa2VsZXRvblxyXG4gKiBAcmV0dXJucyB0aGUgcGFyZW50IGJvbmVcclxuICovXHJcbmNvbnN0IGdldFBhcmVudEJvbmUgPSAoZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSwgc2tpbnM6IElHTFRGU2tpbnMsIGpvaW50TmFtZTogc3RyaW5nLCBuZXdTa2VsZXRvbjogU2tlbGV0b24pOiBOdWxsYWJsZTxCb25lPiA9PiB7XHJcbiAgICAvLyBUcnkgdG8gZmluZFxyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuZXdTa2VsZXRvbi5ib25lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGlmIChuZXdTa2VsZXRvbi5ib25lc1tpXS5uYW1lID09PSBqb2ludE5hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ld1NrZWxldG9uLmJvbmVzW2ldO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBOb3QgZm91bmQsIHNlYXJjaCBpbiBnbHRmIG5vZGVzXHJcbiAgICBjb25zdCBub2RlcyA9IGdsdGZSdW50aW1lLm5vZGVzO1xyXG4gICAgZm9yIChjb25zdCBuZGUgaW4gbm9kZXMpIHtcclxuICAgICAgICBjb25zdCBub2RlOiBJR0xURk5vZGUgPSBub2Rlc1tuZGVdO1xyXG5cclxuICAgICAgICBpZiAoIW5vZGUuam9pbnROYW1lKSB7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgY2hpbGQ6IElHTFRGTm9kZSA9IGdsdGZSdW50aW1lLm5vZGVzW2NoaWxkcmVuW2ldXTtcclxuICAgICAgICAgICAgaWYgKCFjaGlsZC5qb2ludE5hbWUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoY2hpbGQuam9pbnROYW1lID09PSBqb2ludE5hbWUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG1hdCA9IGNvbmZpZ3VyZUJvbmVUcmFuc2Zvcm1hdGlvbihub2RlKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJvbmUgPSBuZXcgQm9uZShub2RlLm5hbWUgfHwgXCJcIiwgbmV3U2tlbGV0b24sIGdldFBhcmVudEJvbmUoZ2x0ZlJ1bnRpbWUsIHNraW5zLCBub2RlLmpvaW50TmFtZSwgbmV3U2tlbGV0b24pLCBtYXQpO1xyXG4gICAgICAgICAgICAgICAgYm9uZS5pZCA9IG5kZTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBib25lO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBudWxsO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGFwcHJvcHJpYXRlIHJvb3Qgbm9kZVxyXG4gKiBAcGFyYW0gbm9kZXNUb1Jvb3RcclxuICogQHBhcmFtIGlkXHJcbiAqIEByZXR1cm5zIHRoZSByb290IG5vZGVcclxuICovXHJcbmNvbnN0IGdldE5vZGVUb1Jvb3QgPSAobm9kZXNUb1Jvb3Q6IElOb2RlVG9Sb290W10sIGlkOiBzdHJpbmcpOiBOdWxsYWJsZTxCb25lPiA9PiB7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzVG9Sb290Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgY29uc3Qgbm9kZVRvUm9vdCA9IG5vZGVzVG9Sb290W2ldO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG5vZGVUb1Jvb3Qubm9kZS5jaGlsZHJlbi5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgICBjb25zdCBjaGlsZCA9IG5vZGVUb1Jvb3Qubm9kZS5jaGlsZHJlbltqXTtcclxuICAgICAgICAgICAgaWYgKGNoaWxkID09PSBpZCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5vZGVUb1Jvb3QuYm9uZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBub2RlIHdpdGggdGhlIGpvaW50IG5hbWVcclxuICogQHBhcmFtIGdsdGZSdW50aW1lXHJcbiAqIEBwYXJhbSBqb2ludE5hbWVcclxuICogQHJldHVybnMgdGhlIG5vZGUgd2l0aCB0aGUgam9pbnQgbmFtZVxyXG4gKi9cclxuY29uc3QgZ2V0Sm9pbnROb2RlID0gKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsIGpvaW50TmFtZTogc3RyaW5nKTogTnVsbGFibGU8SUpvaW50Tm9kZT4gPT4ge1xyXG4gICAgY29uc3Qgbm9kZXMgPSBnbHRmUnVudGltZS5ub2RlcztcclxuICAgIGxldCBub2RlOiBJR0xURk5vZGUgPSBub2Rlc1tqb2ludE5hbWVdO1xyXG4gICAgaWYgKG5vZGUpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBub2RlOiBub2RlLFxyXG4gICAgICAgICAgICBpZDogam9pbnROYW1lLFxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgZm9yIChjb25zdCBuZGUgaW4gbm9kZXMpIHtcclxuICAgICAgICBub2RlID0gbm9kZXNbbmRlXTtcclxuICAgICAgICBpZiAobm9kZS5qb2ludE5hbWUgPT09IGpvaW50TmFtZSkge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgbm9kZTogbm9kZSxcclxuICAgICAgICAgICAgICAgIGlkOiBuZGUsXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBudWxsO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENoZWNrcyBpZiBhIG5vZGVzIGlzIGluIGpvaW50c1xyXG4gKiBAcGFyYW0gc2tpbnNcclxuICogQHBhcmFtIGlkXHJcbiAqIEByZXR1cm5zIHRydWUgaWYgdGhlIG5vZGUgaXMgaW4gam9pbnRzLCBlbHNlIGZhbHNlXHJcbiAqL1xyXG5jb25zdCBub2RlSXNJbkpvaW50cyA9IChza2luczogSUdMVEZTa2lucywgaWQ6IHN0cmluZyk6IGJvb2xlYW4gPT4ge1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBza2lucy5qb2ludE5hbWVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKHNraW5zLmpvaW50TmFtZXNbaV0gPT09IGlkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbn07XHJcblxyXG4vKipcclxuICogRmlsbHMgdGhlIG5vZGVzIHRvIHJvb3QgZm9yIGJvbmVzIGFuZCBidWlsZHMgaGllcmFyY2h5XHJcbiAqIEBwYXJhbSBnbHRmUnVudGltZVxyXG4gKiBAcGFyYW0gbmV3U2tlbGV0b25cclxuICogQHBhcmFtIHNraW5zXHJcbiAqIEBwYXJhbSBub2Rlc1RvUm9vdFxyXG4gKi9cclxuY29uc3QgZ2V0Tm9kZXNUb1Jvb3QgPSAoZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSwgbmV3U2tlbGV0b246IFNrZWxldG9uLCBza2luczogSUdMVEZTa2lucywgbm9kZXNUb1Jvb3Q6IElOb2RlVG9Sb290W10pID0+IHtcclxuICAgIC8vIENyZWF0ZXMgbm9kZXMgZm9yIHJvb3RcclxuICAgIGZvciAoY29uc3QgbmRlIGluIGdsdGZSdW50aW1lLm5vZGVzKSB7XHJcbiAgICAgICAgY29uc3Qgbm9kZTogSUdMVEZOb2RlID0gZ2x0ZlJ1bnRpbWUubm9kZXNbbmRlXTtcclxuICAgICAgICBjb25zdCBpZCA9IG5kZTtcclxuXHJcbiAgICAgICAgaWYgKCFub2RlLmpvaW50TmFtZSB8fCBub2RlSXNJbkpvaW50cyhza2lucywgbm9kZS5qb2ludE5hbWUpKSB7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQ3JlYXRlIG5vZGUgdG8gcm9vdCBib25lXHJcbiAgICAgICAgY29uc3QgbWF0ID0gY29uZmlndXJlQm9uZVRyYW5zZm9ybWF0aW9uKG5vZGUpO1xyXG4gICAgICAgIGNvbnN0IGJvbmUgPSBuZXcgQm9uZShub2RlLm5hbWUgfHwgXCJcIiwgbmV3U2tlbGV0b24sIG51bGwsIG1hdCk7XHJcbiAgICAgICAgYm9uZS5pZCA9IGlkO1xyXG4gICAgICAgIG5vZGVzVG9Sb290LnB1c2goeyBib25lOiBib25lLCBub2RlOiBub2RlLCBpZDogaWQgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUGFyZW50aW5nXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzVG9Sb290Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgY29uc3Qgbm9kZVRvUm9vdCA9IG5vZGVzVG9Sb290W2ldO1xyXG4gICAgICAgIGNvbnN0IGNoaWxkcmVuID0gbm9kZVRvUm9vdC5ub2RlLmNoaWxkcmVuO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNoaWxkcmVuLmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgICAgIGxldCBjaGlsZDogTnVsbGFibGU8SU5vZGVUb1Jvb3Q+ID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgbm9kZXNUb1Jvb3QubGVuZ3RoOyBrKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChub2Rlc1RvUm9vdFtrXS5pZCA9PT0gY2hpbGRyZW5bal0pIHtcclxuICAgICAgICAgICAgICAgICAgICBjaGlsZCA9IG5vZGVzVG9Sb290W2tdO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoY2hpbGQpIHtcclxuICAgICAgICAgICAgICAgICg8YW55PmNoaWxkLmJvbmUpLl9wYXJlbnQgPSBub2RlVG9Sb290LmJvbmU7XHJcbiAgICAgICAgICAgICAgICBub2RlVG9Sb290LmJvbmUuY2hpbGRyZW4ucHVzaChjaGlsZC5ib25lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufTtcclxuXHJcbi8qKlxyXG4gKiBJbXBvcnRzIGEgc2tlbGV0b25cclxuICogQHBhcmFtIGdsdGZSdW50aW1lXHJcbiAqIEBwYXJhbSBza2luc1xyXG4gKiBAcGFyYW0gbWVzaFxyXG4gKiBAcGFyYW0gbmV3U2tlbGV0b25cclxuICogQHJldHVybnMgdGhlIGJvbmUgbmFtZVxyXG4gKi9cclxuY29uc3QgaW1wb3J0U2tlbGV0b24gPSAoZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSwgc2tpbnM6IElHTFRGU2tpbnMsIG1lc2g6IE1lc2gsIG5ld1NrZWxldG9uOiBTa2VsZXRvbiB8IHVuZGVmaW5lZCk6IFNrZWxldG9uID0+IHtcclxuICAgIGlmICghbmV3U2tlbGV0b24pIHtcclxuICAgICAgICBuZXdTa2VsZXRvbiA9IG5ldyBTa2VsZXRvbihza2lucy5uYW1lIHx8IFwiXCIsIFwiXCIsIGdsdGZSdW50aW1lLnNjZW5lKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXNraW5zLmJhYnlsb25Ta2VsZXRvbikge1xyXG4gICAgICAgIHJldHVybiBuZXdTa2VsZXRvbjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBGaW5kIHRoZSByb290IGJvbmVzXHJcbiAgICBjb25zdCBub2Rlc1RvUm9vdDogSU5vZGVUb1Jvb3RbXSA9IFtdO1xyXG4gICAgY29uc3Qgbm9kZXNUb1Jvb3RUb0FkZDogQm9uZVtdID0gW107XHJcblxyXG4gICAgZ2V0Tm9kZXNUb1Jvb3QoZ2x0ZlJ1bnRpbWUsIG5ld1NrZWxldG9uLCBza2lucywgbm9kZXNUb1Jvb3QpO1xyXG4gICAgbmV3U2tlbGV0b24uYm9uZXMgPSBbXTtcclxuXHJcbiAgICAvLyBKb2ludHNcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2tpbnMuam9pbnROYW1lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IGpvaW50Tm9kZSA9IGdldEpvaW50Tm9kZShnbHRmUnVudGltZSwgc2tpbnMuam9pbnROYW1lc1tpXSk7XHJcblxyXG4gICAgICAgIGlmICgham9pbnROb2RlKSB7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3Qgbm9kZSA9IGpvaW50Tm9kZS5ub2RlO1xyXG5cclxuICAgICAgICBpZiAoIW5vZGUpIHtcclxuICAgICAgICAgICAgVG9vbHMuV2FybihcIkpvaW50IG5hbWVkIFwiICsgc2tpbnMuam9pbnROYW1lc1tpXSArIFwiIGRvZXMgbm90IGV4aXN0XCIpO1xyXG4gICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGlkID0gam9pbnROb2RlLmlkO1xyXG5cclxuICAgICAgICAvLyBPcHRpbWl6ZSwgaWYgdGhlIGJvbmUgYWxyZWFkeSBleGlzdHMuLi5cclxuICAgICAgICBjb25zdCBleGlzdGluZ0JvbmUgPSBnbHRmUnVudGltZS5zY2VuZS5nZXRCb25lQnlJZChpZCk7XHJcbiAgICAgICAgaWYgKGV4aXN0aW5nQm9uZSkge1xyXG4gICAgICAgICAgICBuZXdTa2VsZXRvbi5ib25lcy5wdXNoKGV4aXN0aW5nQm9uZSk7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU2VhcmNoIGZvciBwYXJlbnQgYm9uZVxyXG4gICAgICAgIGxldCBmb3VuZEJvbmUgPSBmYWxzZTtcclxuICAgICAgICBsZXQgcGFyZW50Qm9uZTogTnVsbGFibGU8Qm9uZT4gPSBudWxsO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGk7IGorKykge1xyXG4gICAgICAgICAgICBjb25zdCBqb2ludE5vZGUgPSBnZXRKb2ludE5vZGUoZ2x0ZlJ1bnRpbWUsIHNraW5zLmpvaW50TmFtZXNbal0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFqb2ludE5vZGUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBqb2ludDogSUdMVEZOb2RlID0gam9pbnROb2RlLm5vZGU7XHJcblxyXG4gICAgICAgICAgICBpZiAoIWpvaW50KSB7XHJcbiAgICAgICAgICAgICAgICBUb29scy5XYXJuKFwiSm9pbnQgbmFtZWQgXCIgKyBza2lucy5qb2ludE5hbWVzW2pdICsgXCIgZG9lcyBub3QgZXhpc3Qgd2hlbiBsb29raW5nIGZvciBwYXJlbnRcIik7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBqb2ludC5jaGlsZHJlbjtcclxuICAgICAgICAgICAgaWYgKCFjaGlsZHJlbikge1xyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZm91bmRCb25lID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IGNoaWxkcmVuLmxlbmd0aDsgaysrKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGRyZW5ba10gPT09IGlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50Qm9uZSA9IGdldFBhcmVudEJvbmUoZ2x0ZlJ1bnRpbWUsIHNraW5zLCBza2lucy5qb2ludE5hbWVzW2pdLCBuZXdTa2VsZXRvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgZm91bmRCb25lID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGZvdW5kQm9uZSkge1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSBib25lXHJcbiAgICAgICAgY29uc3QgbWF0ID0gY29uZmlndXJlQm9uZVRyYW5zZm9ybWF0aW9uKG5vZGUpO1xyXG5cclxuICAgICAgICBpZiAoIXBhcmVudEJvbmUgJiYgbm9kZXNUb1Jvb3QubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBwYXJlbnRCb25lID0gZ2V0Tm9kZVRvUm9vdChub2Rlc1RvUm9vdCwgaWQpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHBhcmVudEJvbmUpIHtcclxuICAgICAgICAgICAgICAgIGlmIChub2Rlc1RvUm9vdFRvQWRkLmluZGV4T2YocGFyZW50Qm9uZSkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbm9kZXNUb1Jvb3RUb0FkZC5wdXNoKHBhcmVudEJvbmUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBib25lID0gbmV3IEJvbmUobm9kZS5qb2ludE5hbWUgfHwgXCJcIiwgbmV3U2tlbGV0b24sIHBhcmVudEJvbmUsIG1hdCk7XHJcbiAgICAgICAgYm9uZS5pZCA9IGlkO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFBvbGlzaFxyXG4gICAgY29uc3QgYm9uZXMgPSBuZXdTa2VsZXRvbi5ib25lcztcclxuICAgIG5ld1NrZWxldG9uLmJvbmVzID0gW107XHJcblxyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBza2lucy5qb2ludE5hbWVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgY29uc3Qgam9pbnROb2RlID0gZ2V0Sm9pbnROb2RlKGdsdGZSdW50aW1lLCBza2lucy5qb2ludE5hbWVzW2ldKTtcclxuXHJcbiAgICAgICAgaWYgKCFqb2ludE5vZGUpIHtcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGJvbmVzLmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgICAgIGlmIChib25lc1tqXS5pZCA9PT0gam9pbnROb2RlLmlkKSB7XHJcbiAgICAgICAgICAgICAgICBuZXdTa2VsZXRvbi5ib25lcy5wdXNoKGJvbmVzW2pdKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG5ld1NrZWxldG9uLnByZXBhcmUoKTtcclxuXHJcbiAgICAvLyBGaW5pc2hcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXNUb1Jvb3RUb0FkZC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIG5ld1NrZWxldG9uLmJvbmVzLnB1c2gobm9kZXNUb1Jvb3RUb0FkZFtpXSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG5ld1NrZWxldG9uO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEltcG9ydHMgYSBtZXNoIGFuZCBpdHMgZ2VvbWV0cmllc1xyXG4gKiBAcGFyYW0gZ2x0ZlJ1bnRpbWVcclxuICogQHBhcmFtIG5vZGVcclxuICogQHBhcmFtIG1lc2hlc1xyXG4gKiBAcGFyYW0gaWRcclxuICogQHBhcmFtIG5ld01lc2hcclxuICogQHJldHVybnMgdGhlIG5ldyBtZXNoXHJcbiAqL1xyXG5jb25zdCBpbXBvcnRNZXNoID0gKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsIG5vZGU6IElHTFRGTm9kZSwgbWVzaGVzOiBzdHJpbmdbXSwgaWQ6IHN0cmluZywgbmV3TWVzaDogTWVzaCk6IE1lc2ggPT4ge1xyXG4gICAgaWYgKCFuZXdNZXNoKSB7XHJcbiAgICAgICAgZ2x0ZlJ1bnRpbWUuc2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9ICEhZ2x0ZlJ1bnRpbWUuYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgbmV3TWVzaCA9IG5ldyBNZXNoKG5vZGUubmFtZSB8fCBcIlwiLCBnbHRmUnVudGltZS5zY2VuZSk7XHJcbiAgICAgICAgbmV3TWVzaC5fcGFyZW50Q29udGFpbmVyID0gZ2x0ZlJ1bnRpbWUuYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgZ2x0ZlJ1bnRpbWUuc2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgIG5ld01lc2guaWQgPSBpZDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIW5vZGUuYmFieWxvbk5vZGUpIHtcclxuICAgICAgICByZXR1cm4gbmV3TWVzaDtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBzdWJNYXRlcmlhbHM6IE1hdGVyaWFsW10gPSBbXTtcclxuXHJcbiAgICBsZXQgdmVydGV4RGF0YTogTnVsbGFibGU8VmVydGV4RGF0YT4gPSBudWxsO1xyXG4gICAgY29uc3QgdmVydGljZXNTdGFydHM6IG51bWJlcltdID0gW107XHJcbiAgICBjb25zdCB2ZXJ0aWNlc0NvdW50czogbnVtYmVyW10gPSBbXTtcclxuICAgIGNvbnN0IGluZGV4U3RhcnRzOiBudW1iZXJbXSA9IFtdO1xyXG4gICAgY29uc3QgaW5kZXhDb3VudHM6IG51bWJlcltdID0gW107XHJcblxyXG4gICAgZm9yIChsZXQgbWVzaEluZGV4ID0gMDsgbWVzaEluZGV4IDwgbWVzaGVzLmxlbmd0aDsgbWVzaEluZGV4KyspIHtcclxuICAgICAgICBjb25zdCBtZXNoSWQgPSBtZXNoZXNbbWVzaEluZGV4XTtcclxuICAgICAgICBjb25zdCBtZXNoOiBJR0xURk1lc2ggPSBnbHRmUnVudGltZS5tZXNoZXNbbWVzaElkXTtcclxuXHJcbiAgICAgICAgaWYgKCFtZXNoKSB7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUG9zaXRpb25zLCBub3JtYWxzIGFuZCBVVnNcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1lc2gucHJpbWl0aXZlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAvLyBUZW1wb3JhcnkgdmVydGV4IGRhdGFcclxuICAgICAgICAgICAgY29uc3QgdGVtcFZlcnRleERhdGEgPSBuZXcgVmVydGV4RGF0YSgpO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgcHJpbWl0aXZlID0gbWVzaC5wcmltaXRpdmVzW2ldO1xyXG4gICAgICAgICAgICBpZiAocHJpbWl0aXZlLm1vZGUgIT09IDQpIHtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBhdHRyaWJ1dGVzID0gcHJpbWl0aXZlLmF0dHJpYnV0ZXM7XHJcbiAgICAgICAgICAgIGxldCBhY2Nlc3NvcjogTnVsbGFibGU8SUdMVEZBY2Nlc3Nvcj4gPSBudWxsO1xyXG4gICAgICAgICAgICBsZXQgYnVmZmVyOiBhbnkgPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgLy8gU2V0IHBvc2l0aW9ucywgbm9ybWFsIGFuZCB1dnNcclxuICAgICAgICAgICAgZm9yIChjb25zdCBzZW1hbnRpYyBpbiBhdHRyaWJ1dGVzKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBMaW5rIGFjY2Vzc29yIGFuZCBidWZmZXIgdmlld1xyXG4gICAgICAgICAgICAgICAgYWNjZXNzb3IgPSBnbHRmUnVudGltZS5hY2Nlc3NvcnNbYXR0cmlidXRlc1tzZW1hbnRpY11dO1xyXG4gICAgICAgICAgICAgICAgYnVmZmVyID0gR0xURlV0aWxzLkdldEJ1ZmZlckZyb21BY2Nlc3NvcihnbHRmUnVudGltZSwgYWNjZXNzb3IpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChzZW1hbnRpYyA9PT0gXCJOT1JNQUxcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRlbXBWZXJ0ZXhEYXRhLm5vcm1hbHMgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlci5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICg8RmxvYXQzMkFycmF5PnRlbXBWZXJ0ZXhEYXRhLm5vcm1hbHMpLnNldChidWZmZXIpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzZW1hbnRpYyA9PT0gXCJQT1NJVElPTlwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKEdMVEZGaWxlTG9hZGVyLkhvbW9nZW5lb3VzQ29vcmRpbmF0ZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGVtcFZlcnRleERhdGEucG9zaXRpb25zID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXIubGVuZ3RoIC0gYnVmZmVyLmxlbmd0aCAvIDQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBidWZmZXIubGVuZ3RoOyBqICs9IDQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBWZXJ0ZXhEYXRhLnBvc2l0aW9uc1tqXSA9IGJ1ZmZlcltqXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBWZXJ0ZXhEYXRhLnBvc2l0aW9uc1tqICsgMV0gPSBidWZmZXJbaiArIDFdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcFZlcnRleERhdGEucG9zaXRpb25zW2ogKyAyXSA9IGJ1ZmZlcltqICsgMl07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wVmVydGV4RGF0YS5wb3NpdGlvbnMgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlci5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAoPEZsb2F0MzJBcnJheT50ZW1wVmVydGV4RGF0YS5wb3NpdGlvbnMpLnNldChidWZmZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmVydGljZXNDb3VudHMucHVzaCh0ZW1wVmVydGV4RGF0YS5wb3NpdGlvbnMubGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc2VtYW50aWMuaW5kZXhPZihcIlRFWENPT1JEX1wiKSAhPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsID0gTnVtYmVyKHNlbWFudGljLnNwbGl0KFwiX1wiKVsxXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdXZLaW5kID0gVmVydGV4QnVmZmVyLlVWS2luZCArIChjaGFubmVsID09PSAwID8gXCJcIiA6IGNoYW5uZWwgKyAxKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB1dnMgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlci5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICg8RmxvYXQzMkFycmF5PnV2cykuc2V0KGJ1ZmZlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplVVZzKHV2cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGVtcFZlcnRleERhdGEuc2V0KHV2cywgdXZLaW5kKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc2VtYW50aWMgPT09IFwiSk9JTlRcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRlbXBWZXJ0ZXhEYXRhLm1hdHJpY2VzSW5kaWNlcyA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgKDxGbG9hdDMyQXJyYXk+dGVtcFZlcnRleERhdGEubWF0cmljZXNJbmRpY2VzKS5zZXQoYnVmZmVyKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc2VtYW50aWMgPT09IFwiV0VJR0hUXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICB0ZW1wVmVydGV4RGF0YS5tYXRyaWNlc1dlaWdodHMgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlci5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICg8RmxvYXQzMkFycmF5PnRlbXBWZXJ0ZXhEYXRhLm1hdHJpY2VzV2VpZ2h0cykuc2V0KGJ1ZmZlcik7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNlbWFudGljID09PSBcIkNPTE9SXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICB0ZW1wVmVydGV4RGF0YS5jb2xvcnMgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlci5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICg8RmxvYXQzMkFycmF5PnRlbXBWZXJ0ZXhEYXRhLmNvbG9ycykuc2V0KGJ1ZmZlcik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIEluZGljZXNcclxuICAgICAgICAgICAgYWNjZXNzb3IgPSBnbHRmUnVudGltZS5hY2Nlc3NvcnNbcHJpbWl0aXZlLmluZGljZXNdO1xyXG4gICAgICAgICAgICBpZiAoYWNjZXNzb3IpIHtcclxuICAgICAgICAgICAgICAgIGJ1ZmZlciA9IEdMVEZVdGlscy5HZXRCdWZmZXJGcm9tQWNjZXNzb3IoZ2x0ZlJ1bnRpbWUsIGFjY2Vzc29yKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0ZW1wVmVydGV4RGF0YS5pbmRpY2VzID0gbmV3IEludDMyQXJyYXkoYnVmZmVyLmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICB0ZW1wVmVydGV4RGF0YS5pbmRpY2VzLnNldChidWZmZXIpO1xyXG4gICAgICAgICAgICAgICAgaW5kZXhDb3VudHMucHVzaCh0ZW1wVmVydGV4RGF0YS5pbmRpY2VzLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBTZXQgaW5kaWNlcyBvbiB0aGUgZmx5XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpbmRpY2VzOiBudW1iZXJbXSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCAoPEZsb2F0QXJyYXk+dGVtcFZlcnRleERhdGEucG9zaXRpb25zKS5sZW5ndGggLyAzOyBqKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBpbmRpY2VzLnB1c2goaik7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgdGVtcFZlcnRleERhdGEuaW5kaWNlcyA9IG5ldyBJbnQzMkFycmF5KGluZGljZXMpO1xyXG4gICAgICAgICAgICAgICAgaW5kZXhDb3VudHMucHVzaCh0ZW1wVmVydGV4RGF0YS5pbmRpY2VzLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghdmVydGV4RGF0YSkge1xyXG4gICAgICAgICAgICAgICAgdmVydGV4RGF0YSA9IHRlbXBWZXJ0ZXhEYXRhO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdmVydGV4RGF0YS5tZXJnZSh0ZW1wVmVydGV4RGF0YSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIFN1YiBtYXRlcmlhbFxyXG4gICAgICAgICAgICBjb25zdCBtYXRlcmlhbCA9IGdsdGZSdW50aW1lLnNjZW5lLmdldE1hdGVyaWFsQnlJZChwcmltaXRpdmUubWF0ZXJpYWwpO1xyXG5cclxuICAgICAgICAgICAgc3ViTWF0ZXJpYWxzLnB1c2gobWF0ZXJpYWwgPT09IG51bGwgPyBHTFRGVXRpbHMuR2V0RGVmYXVsdE1hdGVyaWFsKGdsdGZSdW50aW1lLnNjZW5lKSA6IG1hdGVyaWFsKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFVwZGF0ZSB2ZXJ0aWNlcyBzdGFydCBhbmQgaW5kZXggc3RhcnRcclxuICAgICAgICAgICAgdmVydGljZXNTdGFydHMucHVzaCh2ZXJ0aWNlc1N0YXJ0cy5sZW5ndGggPT09IDAgPyAwIDogdmVydGljZXNTdGFydHNbdmVydGljZXNTdGFydHMubGVuZ3RoIC0gMV0gKyB2ZXJ0aWNlc0NvdW50c1t2ZXJ0aWNlc0NvdW50cy5sZW5ndGggLSAyXSk7XHJcbiAgICAgICAgICAgIGluZGV4U3RhcnRzLnB1c2goaW5kZXhTdGFydHMubGVuZ3RoID09PSAwID8gMCA6IGluZGV4U3RhcnRzW2luZGV4U3RhcnRzLmxlbmd0aCAtIDFdICsgaW5kZXhDb3VudHNbaW5kZXhDb3VudHMubGVuZ3RoIC0gMl0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGxldCBtYXRlcmlhbDogU3RhbmRhcmRNYXRlcmlhbCB8IE11bHRpTWF0ZXJpYWw7XHJcbiAgICBnbHRmUnVudGltZS5zY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gISFnbHRmUnVudGltZS5hc3NldENvbnRhaW5lcjtcclxuICAgIGlmIChzdWJNYXRlcmlhbHMubGVuZ3RoID4gMSkge1xyXG4gICAgICAgIG1hdGVyaWFsID0gbmV3IE11bHRpTWF0ZXJpYWwoXCJtdWx0aW1hdFwiICsgaWQsIGdsdGZSdW50aW1lLnNjZW5lKTtcclxuICAgICAgICAobWF0ZXJpYWwgYXMgTXVsdGlNYXRlcmlhbCkuc3ViTWF0ZXJpYWxzID0gc3ViTWF0ZXJpYWxzO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBtYXRlcmlhbCA9IG5ldyBTdGFuZGFyZE1hdGVyaWFsKFwibXVsdGltYXRcIiArIGlkLCBnbHRmUnVudGltZS5zY2VuZSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHN1Yk1hdGVyaWFscy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICBtYXRlcmlhbCA9IHN1Yk1hdGVyaWFsc1swXSBhcyBTdGFuZGFyZE1hdGVyaWFsO1xyXG4gICAgfVxyXG5cclxuICAgIG1hdGVyaWFsLl9wYXJlbnRDb250YWluZXIgPSBnbHRmUnVudGltZS5hc3NldENvbnRhaW5lcjtcclxuXHJcbiAgICBpZiAoIW5ld01lc2gubWF0ZXJpYWwpIHtcclxuICAgICAgICBuZXdNZXNoLm1hdGVyaWFsID0gbWF0ZXJpYWw7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQXBwbHkgZ2VvbWV0cnlcclxuICAgIG5ldyBHZW9tZXRyeShpZCwgZ2x0ZlJ1bnRpbWUuc2NlbmUsIHZlcnRleERhdGEhLCBmYWxzZSwgbmV3TWVzaCk7XHJcbiAgICBuZXdNZXNoLmNvbXB1dGVXb3JsZE1hdHJpeCh0cnVlKTtcclxuXHJcbiAgICBnbHRmUnVudGltZS5zY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gZmFsc2U7XHJcblxyXG4gICAgLy8gQXBwbHkgc3VibWVzaGVzXHJcbiAgICBuZXdNZXNoLnN1Yk1lc2hlcyA9IFtdO1xyXG4gICAgbGV0IGluZGV4ID0gMDtcclxuICAgIGZvciAobGV0IG1lc2hJbmRleCA9IDA7IG1lc2hJbmRleCA8IG1lc2hlcy5sZW5ndGg7IG1lc2hJbmRleCsrKSB7XHJcbiAgICAgICAgY29uc3QgbWVzaElkID0gbWVzaGVzW21lc2hJbmRleF07XHJcbiAgICAgICAgY29uc3QgbWVzaDogSUdMVEZNZXNoID0gZ2x0ZlJ1bnRpbWUubWVzaGVzW21lc2hJZF07XHJcblxyXG4gICAgICAgIGlmICghbWVzaCkge1xyXG4gICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWVzaC5wcmltaXRpdmVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChtZXNoLnByaW1pdGl2ZXNbaV0ubW9kZSAhPT0gNCkge1xyXG4gICAgICAgICAgICAgICAgLy9jb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgU3ViTWVzaC5BZGRUb01lc2goaW5kZXgsIHZlcnRpY2VzU3RhcnRzW2luZGV4XSwgdmVydGljZXNDb3VudHNbaW5kZXhdLCBpbmRleFN0YXJ0c1tpbmRleF0sIGluZGV4Q291bnRzW2luZGV4XSwgbmV3TWVzaCwgbmV3TWVzaCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGluZGV4Kys7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIEZpbmlzaFxyXG4gICAgcmV0dXJuIG5ld01lc2g7XHJcbn07XHJcblxyXG4vKipcclxuICogQ29uZmlndXJlIG5vZGUgdHJhbnNmb3JtYXRpb24gZnJvbSBwb3NpdGlvbiwgcm90YXRpb24gYW5kIHNjYWxpbmdcclxuICogQHBhcmFtIG5ld05vZGVcclxuICogQHBhcmFtIHBvc2l0aW9uXHJcbiAqIEBwYXJhbSByb3RhdGlvblxyXG4gKiBAcGFyYW0gc2NhbGluZ1xyXG4gKi9cclxuY29uc3QgY29uZmlndXJlTm9kZSA9IChuZXdOb2RlOiBhbnksIHBvc2l0aW9uOiBWZWN0b3IzLCByb3RhdGlvbjogUXVhdGVybmlvbiwgc2NhbGluZzogVmVjdG9yMykgPT4ge1xyXG4gICAgaWYgKG5ld05vZGUucG9zaXRpb24pIHtcclxuICAgICAgICBuZXdOb2RlLnBvc2l0aW9uID0gcG9zaXRpb247XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG5ld05vZGUucm90YXRpb25RdWF0ZXJuaW9uIHx8IG5ld05vZGUucm90YXRpb24pIHtcclxuICAgICAgICBuZXdOb2RlLnJvdGF0aW9uUXVhdGVybmlvbiA9IHJvdGF0aW9uO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChuZXdOb2RlLnNjYWxpbmcpIHtcclxuICAgICAgICBuZXdOb2RlLnNjYWxpbmcgPSBzY2FsaW5nO1xyXG4gICAgfVxyXG59O1xyXG5cclxuLyoqXHJcbiAqIENvbmZpZ3VyZXMgbm9kZSBmcm9tIHRyYW5zZm9ybWF0aW9uIG1hdHJpeFxyXG4gKiBAcGFyYW0gbmV3Tm9kZVxyXG4gKiBAcGFyYW0gbm9kZVxyXG4gKi9cclxuY29uc3QgY29uZmlndXJlTm9kZUZyb21NYXRyaXggPSAobmV3Tm9kZTogTWVzaCwgbm9kZTogSUdMVEZOb2RlKSA9PiB7XHJcbiAgICBpZiAobm9kZS5tYXRyaXgpIHtcclxuICAgICAgICBjb25zdCBwb3NpdGlvbiA9IG5ldyBWZWN0b3IzKDAsIDAsIDApO1xyXG4gICAgICAgIGNvbnN0IHJvdGF0aW9uID0gbmV3IFF1YXRlcm5pb24oKTtcclxuICAgICAgICBjb25zdCBzY2FsaW5nID0gbmV3IFZlY3RvcjMoMCwgMCwgMCk7XHJcbiAgICAgICAgY29uc3QgbWF0ID0gTWF0cml4LkZyb21BcnJheShub2RlLm1hdHJpeCk7XHJcbiAgICAgICAgbWF0LmRlY29tcG9zZShzY2FsaW5nLCByb3RhdGlvbiwgcG9zaXRpb24pO1xyXG5cclxuICAgICAgICBjb25maWd1cmVOb2RlKG5ld05vZGUsIHBvc2l0aW9uLCByb3RhdGlvbiwgc2NhbGluZyk7XHJcbiAgICB9IGVsc2UgaWYgKG5vZGUudHJhbnNsYXRpb24gJiYgbm9kZS5yb3RhdGlvbiAmJiBub2RlLnNjYWxlKSB7XHJcbiAgICAgICAgY29uZmlndXJlTm9kZShuZXdOb2RlLCBWZWN0b3IzLkZyb21BcnJheShub2RlLnRyYW5zbGF0aW9uKSwgUXVhdGVybmlvbi5Gcm9tQXJyYXkobm9kZS5yb3RhdGlvbiksIFZlY3RvcjMuRnJvbUFycmF5KG5vZGUuc2NhbGUpKTtcclxuICAgIH1cclxuXHJcbiAgICBuZXdOb2RlLmNvbXB1dGVXb3JsZE1hdHJpeCh0cnVlKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBJbXBvcnRzIGEgbm9kZVxyXG4gKiBAcGFyYW0gZ2x0ZlJ1bnRpbWVcclxuICogQHBhcmFtIG5vZGVcclxuICogQHBhcmFtIGlkXHJcbiAqIEByZXR1cm5zIHRoZSBuZXdseSBpbXBvcnRlZCBub2RlXHJcbiAqL1xyXG5jb25zdCBpbXBvcnROb2RlID0gKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsIG5vZGU6IElHTFRGTm9kZSwgaWQ6IHN0cmluZyk6IE51bGxhYmxlPE5vZGU+ID0+IHtcclxuICAgIGxldCBsYXN0Tm9kZTogTnVsbGFibGU8Tm9kZT4gPSBudWxsO1xyXG5cclxuICAgIGlmIChnbHRmUnVudGltZS5pbXBvcnRPbmx5TWVzaGVzICYmIChub2RlLnNraW4gfHwgbm9kZS5tZXNoZXMpKSB7XHJcbiAgICAgICAgaWYgKGdsdGZSdW50aW1lLmltcG9ydE1lc2hlc05hbWVzICYmIGdsdGZSdW50aW1lLmltcG9ydE1lc2hlc05hbWVzLmxlbmd0aCA+IDAgJiYgZ2x0ZlJ1bnRpbWUuaW1wb3J0TWVzaGVzTmFtZXMuaW5kZXhPZihub2RlLm5hbWUgfHwgXCJcIikgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBNZXNoZXNcclxuICAgIGlmIChub2RlLnNraW4pIHtcclxuICAgICAgICBpZiAobm9kZS5tZXNoZXMpIHtcclxuICAgICAgICAgICAgY29uc3Qgc2tpbjogSUdMVEZTa2lucyA9IGdsdGZSdW50aW1lLnNraW5zW25vZGUuc2tpbl07XHJcblxyXG4gICAgICAgICAgICBjb25zdCBuZXdNZXNoID0gaW1wb3J0TWVzaChnbHRmUnVudGltZSwgbm9kZSwgbm9kZS5tZXNoZXMsIGlkLCA8TWVzaD5ub2RlLmJhYnlsb25Ob2RlKTtcclxuICAgICAgICAgICAgbmV3TWVzaC5za2VsZXRvbiA9IGdsdGZSdW50aW1lLnNjZW5lLmdldExhc3RTa2VsZXRvbkJ5SWQobm9kZS5za2luKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChuZXdNZXNoLnNrZWxldG9uID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBuZXdNZXNoLnNrZWxldG9uID0gaW1wb3J0U2tlbGV0b24oZ2x0ZlJ1bnRpbWUsIHNraW4sIG5ld01lc2gsIHNraW4uYmFieWxvblNrZWxldG9uKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXNraW4uYmFieWxvblNrZWxldG9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2tpbi5iYWJ5bG9uU2tlbGV0b24gPSBuZXdNZXNoLnNrZWxldG9uO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsYXN0Tm9kZSA9IG5ld01lc2g7XHJcbiAgICAgICAgfVxyXG4gICAgfSBlbHNlIGlmIChub2RlLm1lc2hlcykge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEltcHJvdmUgbWVzaGVzIHByb3BlcnR5XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgY29uc3QgbmV3TWVzaCA9IGltcG9ydE1lc2goZ2x0ZlJ1bnRpbWUsIG5vZGUsIG5vZGUubWVzaCA/IFtub2RlLm1lc2hdIDogbm9kZS5tZXNoZXMsIGlkLCA8TWVzaD5ub2RlLmJhYnlsb25Ob2RlKTtcclxuICAgICAgICBsYXN0Tm9kZSA9IG5ld01lc2g7XHJcbiAgICB9XHJcbiAgICAvLyBMaWdodHNcclxuICAgIGVsc2UgaWYgKG5vZGUubGlnaHQgJiYgIW5vZGUuYmFieWxvbk5vZGUgJiYgIWdsdGZSdW50aW1lLmltcG9ydE9ubHlNZXNoZXMpIHtcclxuICAgICAgICBjb25zdCBsaWdodDogSUdMVEZMaWdodCA9IGdsdGZSdW50aW1lLmxpZ2h0c1tub2RlLmxpZ2h0XTtcclxuXHJcbiAgICAgICAgaWYgKGxpZ2h0KSB7XHJcbiAgICAgICAgICAgIGlmIChsaWdodC50eXBlID09PSBcImFtYmllbnRcIikge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYW1iaWVuTGlnaHQ6IElHTFRGQW1iaWVuTGlnaHQgPSAoPGFueT5saWdodClbbGlnaHQudHlwZV07XHJcbiAgICAgICAgICAgICAgICBjb25zdCBoZW1pTGlnaHQgPSBuZXcgSGVtaXNwaGVyaWNMaWdodChub2RlLmxpZ2h0LCBWZWN0b3IzLlplcm8oKSwgZ2x0ZlJ1bnRpbWUuc2NlbmUpO1xyXG4gICAgICAgICAgICAgICAgaGVtaUxpZ2h0Lm5hbWUgPSBub2RlLm5hbWUgfHwgXCJcIjtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoYW1iaWVuTGlnaHQuY29sb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICBoZW1pTGlnaHQuZGlmZnVzZSA9IENvbG9yMy5Gcm9tQXJyYXkoYW1iaWVuTGlnaHQuY29sb3IpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGxhc3ROb2RlID0gaGVtaUxpZ2h0O1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGxpZ2h0LnR5cGUgPT09IFwiZGlyZWN0aW9uYWxcIikge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGlyZWN0aW9uYWxMaWdodDogSUdMVEZEaXJlY3Rpb25hbExpZ2h0ID0gKDxhbnk+bGlnaHQpW2xpZ2h0LnR5cGVdO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGlyTGlnaHQgPSBuZXcgRGlyZWN0aW9uYWxMaWdodChub2RlLmxpZ2h0LCBWZWN0b3IzLlplcm8oKSwgZ2x0ZlJ1bnRpbWUuc2NlbmUpO1xyXG4gICAgICAgICAgICAgICAgZGlyTGlnaHQubmFtZSA9IG5vZGUubmFtZSB8fCBcIlwiO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChkaXJlY3Rpb25hbExpZ2h0LmNvbG9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGlyTGlnaHQuZGlmZnVzZSA9IENvbG9yMy5Gcm9tQXJyYXkoZGlyZWN0aW9uYWxMaWdodC5jb2xvcik7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbGFzdE5vZGUgPSBkaXJMaWdodDtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChsaWdodC50eXBlID09PSBcInBvaW50XCIpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHBvaW50TGlnaHQ6IElHTFRGUG9pbnRMaWdodCA9ICg8YW55PmxpZ2h0KVtsaWdodC50eXBlXTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHB0TGlnaHQgPSBuZXcgUG9pbnRMaWdodChub2RlLmxpZ2h0LCBWZWN0b3IzLlplcm8oKSwgZ2x0ZlJ1bnRpbWUuc2NlbmUpO1xyXG4gICAgICAgICAgICAgICAgcHRMaWdodC5uYW1lID0gbm9kZS5uYW1lIHx8IFwiXCI7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHBvaW50TGlnaHQuY29sb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICBwdExpZ2h0LmRpZmZ1c2UgPSBDb2xvcjMuRnJvbUFycmF5KHBvaW50TGlnaHQuY29sb3IpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGxhc3ROb2RlID0gcHRMaWdodDtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChsaWdodC50eXBlID09PSBcInNwb3RcIikge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc3BvdExpZ2h0OiBJR0xURlNwb3RMaWdodCA9ICg8YW55PmxpZ2h0KVtsaWdodC50eXBlXTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNwTGlnaHQgPSBuZXcgU3BvdExpZ2h0KG5vZGUubGlnaHQsIFZlY3RvcjMuWmVybygpLCBWZWN0b3IzLlplcm8oKSwgMCwgMCwgZ2x0ZlJ1bnRpbWUuc2NlbmUpO1xyXG4gICAgICAgICAgICAgICAgc3BMaWdodC5uYW1lID0gbm9kZS5uYW1lIHx8IFwiXCI7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHNwb3RMaWdodC5jb2xvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHNwTGlnaHQuZGlmZnVzZSA9IENvbG9yMy5Gcm9tQXJyYXkoc3BvdExpZ2h0LmNvbG9yKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoc3BvdExpZ2h0LmZhbGxPZkFuZ2xlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3BMaWdodC5hbmdsZSA9IHNwb3RMaWdodC5mYWxsT2ZBbmdsZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoc3BvdExpZ2h0LmZhbGxPZmZFeHBvbmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNwTGlnaHQuZXhwb25lbnQgPSBzcG90TGlnaHQuZmFsbE9mZkV4cG9uZW50O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGxhc3ROb2RlID0gc3BMaWdodDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIENhbWVyYXNcclxuICAgIGVsc2UgaWYgKG5vZGUuY2FtZXJhICYmICFub2RlLmJhYnlsb25Ob2RlICYmICFnbHRmUnVudGltZS5pbXBvcnRPbmx5TWVzaGVzKSB7XHJcbiAgICAgICAgY29uc3QgY2FtZXJhOiBJR0xURkNhbWVyYSA9IGdsdGZSdW50aW1lLmNhbWVyYXNbbm9kZS5jYW1lcmFdO1xyXG5cclxuICAgICAgICBpZiAoY2FtZXJhKSB7XHJcbiAgICAgICAgICAgIGdsdGZSdW50aW1lLnNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSAhIWdsdGZSdW50aW1lLmFzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICBpZiAoY2FtZXJhLnR5cGUgPT09IFwib3J0aG9ncmFwaGljXCIpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG9ydGhvQ2FtZXJhID0gbmV3IEZyZWVDYW1lcmEobm9kZS5jYW1lcmEsIFZlY3RvcjMuWmVybygpLCBnbHRmUnVudGltZS5zY2VuZSwgZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgICAgIG9ydGhvQ2FtZXJhLm5hbWUgPSBub2RlLm5hbWUgfHwgXCJcIjtcclxuICAgICAgICAgICAgICAgIG9ydGhvQ2FtZXJhLm1vZGUgPSBDYW1lcmEuT1JUSE9HUkFQSElDX0NBTUVSQTtcclxuICAgICAgICAgICAgICAgIG9ydGhvQ2FtZXJhLmF0dGFjaENvbnRyb2woKTtcclxuXHJcbiAgICAgICAgICAgICAgICBsYXN0Tm9kZSA9IG9ydGhvQ2FtZXJhO1xyXG5cclxuICAgICAgICAgICAgICAgIG9ydGhvQ2FtZXJhLl9wYXJlbnRDb250YWluZXIgPSBnbHRmUnVudGltZS5hc3NldENvbnRhaW5lcjtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChjYW1lcmEudHlwZSA9PT0gXCJwZXJzcGVjdGl2ZVwiKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwZXJzcGVjdGl2ZUNhbWVyYTogSUdMVEZDYW1lcmFQZXJzcGVjdGl2ZSA9ICg8YW55PmNhbWVyYSlbY2FtZXJhLnR5cGVdO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcGVyc0NhbWVyYSA9IG5ldyBGcmVlQ2FtZXJhKG5vZGUuY2FtZXJhLCBWZWN0b3IzLlplcm8oKSwgZ2x0ZlJ1bnRpbWUuc2NlbmUsIGZhbHNlKTtcclxuXHJcbiAgICAgICAgICAgICAgICBwZXJzQ2FtZXJhLm5hbWUgPSBub2RlLm5hbWUgfHwgXCJcIjtcclxuICAgICAgICAgICAgICAgIHBlcnNDYW1lcmEuYXR0YWNoQ29udHJvbCgpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICghcGVyc3BlY3RpdmVDYW1lcmEuYXNwZWN0UmF0aW8pIHtcclxuICAgICAgICAgICAgICAgICAgICBwZXJzcGVjdGl2ZUNhbWVyYS5hc3BlY3RSYXRpbyA9IGdsdGZSdW50aW1lLnNjZW5lLmdldEVuZ2luZSgpLmdldFJlbmRlcldpZHRoKCkgLyBnbHRmUnVudGltZS5zY2VuZS5nZXRFbmdpbmUoKS5nZXRSZW5kZXJIZWlnaHQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAocGVyc3BlY3RpdmVDYW1lcmEuem5lYXIgJiYgcGVyc3BlY3RpdmVDYW1lcmEuemZhcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHBlcnNDYW1lcmEubWF4WiA9IHBlcnNwZWN0aXZlQ2FtZXJhLnpmYXI7XHJcbiAgICAgICAgICAgICAgICAgICAgcGVyc0NhbWVyYS5taW5aID0gcGVyc3BlY3RpdmVDYW1lcmEuem5lYXI7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbGFzdE5vZGUgPSBwZXJzQ2FtZXJhO1xyXG4gICAgICAgICAgICAgICAgcGVyc0NhbWVyYS5fcGFyZW50Q29udGFpbmVyID0gZ2x0ZlJ1bnRpbWUuYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGdsdGZSdW50aW1lLnNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRW1wdHkgbm9kZVxyXG4gICAgaWYgKCFub2RlLmpvaW50TmFtZSkge1xyXG4gICAgICAgIGlmIChub2RlLmJhYnlsb25Ob2RlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBub2RlLmJhYnlsb25Ob2RlO1xyXG4gICAgICAgIH0gZWxzZSBpZiAobGFzdE5vZGUgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgZ2x0ZlJ1bnRpbWUuc2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9ICEhZ2x0ZlJ1bnRpbWUuYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgICAgIGNvbnN0IGR1bW15ID0gbmV3IE1lc2gobm9kZS5uYW1lIHx8IFwiXCIsIGdsdGZSdW50aW1lLnNjZW5lKTtcclxuICAgICAgICAgICAgZHVtbXkuX3BhcmVudENvbnRhaW5lciA9IGdsdGZSdW50aW1lLmFzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICBnbHRmUnVudGltZS5zY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgICAgIG5vZGUuYmFieWxvbk5vZGUgPSBkdW1teTtcclxuICAgICAgICAgICAgbGFzdE5vZGUgPSBkdW1teTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGxhc3ROb2RlICE9PSBudWxsKSB7XHJcbiAgICAgICAgaWYgKG5vZGUubWF0cml4ICYmIGxhc3ROb2RlIGluc3RhbmNlb2YgTWVzaCkge1xyXG4gICAgICAgICAgICBjb25maWd1cmVOb2RlRnJvbU1hdHJpeChsYXN0Tm9kZSwgbm9kZSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgdHJhbnNsYXRpb24gPSBub2RlLnRyYW5zbGF0aW9uIHx8IFswLCAwLCAwXTtcclxuICAgICAgICAgICAgY29uc3Qgcm90YXRpb24gPSBub2RlLnJvdGF0aW9uIHx8IFswLCAwLCAwLCAxXTtcclxuICAgICAgICAgICAgY29uc3Qgc2NhbGUgPSBub2RlLnNjYWxlIHx8IFsxLCAxLCAxXTtcclxuICAgICAgICAgICAgY29uZmlndXJlTm9kZShsYXN0Tm9kZSwgVmVjdG9yMy5Gcm9tQXJyYXkodHJhbnNsYXRpb24pLCBRdWF0ZXJuaW9uLkZyb21BcnJheShyb3RhdGlvbiksIFZlY3RvcjMuRnJvbUFycmF5KHNjYWxlKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsYXN0Tm9kZS51cGRhdGVDYWNoZSh0cnVlKTtcclxuICAgICAgICBub2RlLmJhYnlsb25Ob2RlID0gbGFzdE5vZGU7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGxhc3ROb2RlO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRyYXZlcnNlcyBub2RlcyBhbmQgY3JlYXRlcyB0aGVtXHJcbiAqIEBwYXJhbSBnbHRmUnVudGltZVxyXG4gKiBAcGFyYW0gaWRcclxuICogQHBhcmFtIHBhcmVudFxyXG4gKiBAcGFyYW0gbWVzaEluY2x1ZGVkXHJcbiAqL1xyXG5jb25zdCB0cmF2ZXJzZU5vZGVzID0gKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsIGlkOiBzdHJpbmcsIHBhcmVudDogTnVsbGFibGU8Tm9kZT4sIG1lc2hJbmNsdWRlZDogYm9vbGVhbiA9IGZhbHNlKSA9PiB7XHJcbiAgICBjb25zdCBub2RlOiBJR0xURk5vZGUgPSBnbHRmUnVudGltZS5ub2Rlc1tpZF07XHJcbiAgICBsZXQgbmV3Tm9kZTogTnVsbGFibGU8Tm9kZT4gPSBudWxsO1xyXG5cclxuICAgIGlmIChnbHRmUnVudGltZS5pbXBvcnRPbmx5TWVzaGVzICYmICFtZXNoSW5jbHVkZWQgJiYgZ2x0ZlJ1bnRpbWUuaW1wb3J0TWVzaGVzTmFtZXMpIHtcclxuICAgICAgICBpZiAoZ2x0ZlJ1bnRpbWUuaW1wb3J0TWVzaGVzTmFtZXMuaW5kZXhPZihub2RlLm5hbWUgfHwgXCJcIikgIT09IC0xIHx8IGdsdGZSdW50aW1lLmltcG9ydE1lc2hlc05hbWVzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICBtZXNoSW5jbHVkZWQgPSB0cnVlO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIG1lc2hJbmNsdWRlZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbWVzaEluY2x1ZGVkID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIW5vZGUuam9pbnROYW1lICYmIG1lc2hJbmNsdWRlZCkge1xyXG4gICAgICAgIG5ld05vZGUgPSBpbXBvcnROb2RlKGdsdGZSdW50aW1lLCBub2RlLCBpZCk7XHJcblxyXG4gICAgICAgIGlmIChuZXdOb2RlICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIG5ld05vZGUuaWQgPSBpZDtcclxuICAgICAgICAgICAgbmV3Tm9kZS5wYXJlbnQgPSBwYXJlbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChub2RlLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2RlLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHRyYXZlcnNlTm9kZXMoZ2x0ZlJ1bnRpbWUsIG5vZGUuY2hpbGRyZW5baV0sIG5ld05vZGUsIG1lc2hJbmNsdWRlZCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59O1xyXG5cclxuLyoqXHJcbiAqIGRvIHN0dWZmIGFmdGVyIGJ1ZmZlcnMsIHNoYWRlcnMgYXJlIGxvYWRlZCAoZS5nLiBob29rIHVwIG1hdGVyaWFscywgbG9hZCBhbmltYXRpb25zLCBldGMuKVxyXG4gKiBAcGFyYW0gZ2x0ZlJ1bnRpbWVcclxuICovXHJcbmNvbnN0IHBvc3RMb2FkID0gKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUpID0+IHtcclxuICAgIC8vIE5vZGVzXHJcbiAgICBsZXQgY3VycmVudFNjZW5lOiBJR0xURlNjZW5lID0gPElHTFRGU2NlbmU+Z2x0ZlJ1bnRpbWUuY3VycmVudFNjZW5lO1xyXG5cclxuICAgIGlmIChjdXJyZW50U2NlbmUpIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGN1cnJlbnRTY2VuZS5ub2Rlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB0cmF2ZXJzZU5vZGVzKGdsdGZSdW50aW1lLCBjdXJyZW50U2NlbmUubm9kZXNbaV0sIG51bGwpO1xyXG4gICAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZm9yIChjb25zdCB0aGluZyBpbiBnbHRmUnVudGltZS5zY2VuZXMpIHtcclxuICAgICAgICAgICAgY3VycmVudFNjZW5lID0gPElHTFRGU2NlbmU+Z2x0ZlJ1bnRpbWUuc2NlbmVzW3RoaW5nXTtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY3VycmVudFNjZW5lLm5vZGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB0cmF2ZXJzZU5vZGVzKGdsdGZSdW50aW1lLCBjdXJyZW50U2NlbmUubm9kZXNbaV0sIG51bGwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIFNldCBhbmltYXRpb25zXHJcbiAgICBsb2FkQW5pbWF0aW9ucyhnbHRmUnVudGltZSk7XHJcblxyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBnbHRmUnVudGltZS5zY2VuZS5za2VsZXRvbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBjb25zdCBza2VsZXRvbiA9IGdsdGZSdW50aW1lLnNjZW5lLnNrZWxldG9uc1tpXTtcclxuICAgICAgICBnbHRmUnVudGltZS5zY2VuZS5iZWdpbkFuaW1hdGlvbihza2VsZXRvbiwgMCwgTnVtYmVyLk1BWF9WQUxVRSwgdHJ1ZSwgMS4wKTtcclxuICAgIH1cclxufTtcclxuXHJcbi8qKlxyXG4gKiBvbkJpbmQgc2hhZGVycnMgY2FsbGJhY2sgdG8gc2V0IHVuaWZvcm1zIGFuZCBtYXRyaWNlc1xyXG4gKiBAcGFyYW0gbWVzaFxyXG4gKiBAcGFyYW0gZ2x0ZlJ1bnRpbWVcclxuICogQHBhcmFtIHVuVHJlYXRlZFVuaWZvcm1zXHJcbiAqIEBwYXJhbSBzaGFkZXJNYXRlcmlhbFxyXG4gKiBAcGFyYW0gdGVjaG5pcXVlXHJcbiAqIEBwYXJhbSBtYXRlcmlhbFxyXG4gKiBAcGFyYW0gb25TdWNjZXNzXHJcbiAqL1xyXG5jb25zdCBvbkJpbmRTaGFkZXJNYXRlcmlhbCA9IChcclxuICAgIG1lc2g6IEFic3RyYWN0TWVzaCxcclxuICAgIGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsXHJcbiAgICB1blRyZWF0ZWRVbmlmb3JtczogeyBba2V5OiBzdHJpbmddOiBJR0xURlRlY2huaXF1ZVBhcmFtZXRlciB9LFxyXG4gICAgc2hhZGVyTWF0ZXJpYWw6IFNoYWRlck1hdGVyaWFsLFxyXG4gICAgdGVjaG5pcXVlOiBJR0xURlRlY2huaXF1ZSxcclxuICAgIG1hdGVyaWFsOiBJR0xURk1hdGVyaWFsLFxyXG4gICAgb25TdWNjZXNzOiAoc2hhZGVyTWF0ZXJpYWw6IFNoYWRlck1hdGVyaWFsKSA9PiB2b2lkXHJcbikgPT4ge1xyXG4gICAgY29uc3QgbWF0ZXJpYWxWYWx1ZXMgPSBtYXRlcmlhbC52YWx1ZXMgfHwgdGVjaG5pcXVlLnBhcmFtZXRlcnM7XHJcblxyXG4gICAgZm9yIChjb25zdCB1bmlmIGluIHVuVHJlYXRlZFVuaWZvcm1zKSB7XHJcbiAgICAgICAgY29uc3QgdW5pZm9ybTogSUdMVEZUZWNobmlxdWVQYXJhbWV0ZXIgPSB1blRyZWF0ZWRVbmlmb3Jtc1t1bmlmXTtcclxuICAgICAgICBjb25zdCB0eXBlID0gdW5pZm9ybS50eXBlO1xyXG5cclxuICAgICAgICBpZiAodHlwZSA9PT0gRVBhcmFtZXRlclR5cGUuRkxPQVRfTUFUMiB8fCB0eXBlID09PSBFUGFyYW1ldGVyVHlwZS5GTE9BVF9NQVQzIHx8IHR5cGUgPT09IEVQYXJhbWV0ZXJUeXBlLkZMT0FUX01BVDQpIHtcclxuICAgICAgICAgICAgaWYgKHVuaWZvcm0uc2VtYW50aWMgJiYgIXVuaWZvcm0uc291cmNlICYmICF1bmlmb3JtLm5vZGUpIHtcclxuICAgICAgICAgICAgICAgIEdMVEZVdGlscy5TZXRNYXRyaXgoZ2x0ZlJ1bnRpbWUuc2NlbmUsIG1lc2gsIHVuaWZvcm0sIHVuaWYsIDxFZmZlY3Q+c2hhZGVyTWF0ZXJpYWwuZ2V0RWZmZWN0KCkpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHVuaWZvcm0uc2VtYW50aWMgJiYgKHVuaWZvcm0uc291cmNlIHx8IHVuaWZvcm0ubm9kZSkpIHtcclxuICAgICAgICAgICAgICAgIGxldCBzb3VyY2UgPSBnbHRmUnVudGltZS5zY2VuZS5nZXROb2RlQnlOYW1lKHVuaWZvcm0uc291cmNlIHx8IHVuaWZvcm0ubm9kZSB8fCBcIlwiKTtcclxuICAgICAgICAgICAgICAgIGlmIChzb3VyY2UgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBzb3VyY2UgPSBnbHRmUnVudGltZS5zY2VuZS5nZXROb2RlQnlJZCh1bmlmb3JtLnNvdXJjZSB8fCB1bmlmb3JtLm5vZGUgfHwgXCJcIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoc291cmNlID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgR0xURlV0aWxzLlNldE1hdHJpeChnbHRmUnVudGltZS5zY2VuZSwgc291cmNlLCB1bmlmb3JtLCB1bmlmLCA8RWZmZWN0PnNoYWRlck1hdGVyaWFsLmdldEVmZmVjdCgpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gKDxhbnk+bWF0ZXJpYWxWYWx1ZXMpW3RlY2huaXF1ZS51bmlmb3Jtc1t1bmlmXV07XHJcbiAgICAgICAgICAgIGlmICghdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gRVBhcmFtZXRlclR5cGUuU0FNUExFUl8yRCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdGV4dHVyZSA9IGdsdGZSdW50aW1lLnRleHR1cmVzW21hdGVyaWFsLnZhbHVlcyA/IHZhbHVlIDogdW5pZm9ybS52YWx1ZV0uYmFieWxvblRleHR1cmU7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRleHR1cmUgPT09IG51bGwgfHwgdGV4dHVyZSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgKDxFZmZlY3Q+c2hhZGVyTWF0ZXJpYWwuZ2V0RWZmZWN0KCkpLnNldFRleHR1cmUodW5pZiwgdGV4dHVyZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBHTFRGVXRpbHMuU2V0VW5pZm9ybSg8RWZmZWN0PnNoYWRlck1hdGVyaWFsLmdldEVmZmVjdCgpLCB1bmlmLCB2YWx1ZSwgdHlwZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgb25TdWNjZXNzKHNoYWRlck1hdGVyaWFsKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBQcmVwYXJlIHVuaWZvcm1zIHRvIHNlbmQgdGhlIG9ubHkgb25lIHRpbWVcclxuICogTG9hZHMgdGhlIGFwcHJvcHJpYXRlIHRleHR1cmVzXHJcbiAqIEBwYXJhbSBnbHRmUnVudGltZVxyXG4gKiBAcGFyYW0gc2hhZGVyTWF0ZXJpYWxcclxuICogQHBhcmFtIHRlY2huaXF1ZVxyXG4gKiBAcGFyYW0gbWF0ZXJpYWxcclxuICovXHJcbmNvbnN0IHByZXBhcmVTaGFkZXJNYXRlcmlhbFVuaWZvcm1zID0gKFxyXG4gICAgZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSxcclxuICAgIHNoYWRlck1hdGVyaWFsOiBTaGFkZXJNYXRlcmlhbCxcclxuICAgIHRlY2huaXF1ZTogSUdMVEZUZWNobmlxdWUsXHJcbiAgICBtYXRlcmlhbDogSUdMVEZNYXRlcmlhbCxcclxuICAgIHVuVHJlYXRlZFVuaWZvcm1zOiB7IFtrZXk6IHN0cmluZ106IElHTFRGVGVjaG5pcXVlUGFyYW1ldGVyIH1cclxuKSA9PiB7XHJcbiAgICBjb25zdCBtYXRlcmlhbFZhbHVlcyA9IG1hdGVyaWFsLnZhbHVlcyB8fCB0ZWNobmlxdWUucGFyYW1ldGVycztcclxuICAgIGNvbnN0IHRlY2huaXF1ZVVuaWZvcm1zID0gdGVjaG5pcXVlLnVuaWZvcm1zO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHJlcGFyZSB2YWx1ZXMgaGVyZSAobm90IG1hdHJpY2VzKVxyXG4gICAgICovXHJcbiAgICBmb3IgKGNvbnN0IHVuaWYgaW4gdW5UcmVhdGVkVW5pZm9ybXMpIHtcclxuICAgICAgICBjb25zdCB1bmlmb3JtOiBJR0xURlRlY2huaXF1ZVBhcmFtZXRlciA9IHVuVHJlYXRlZFVuaWZvcm1zW3VuaWZdO1xyXG4gICAgICAgIGNvbnN0IHR5cGUgPSB1bmlmb3JtLnR5cGU7XHJcbiAgICAgICAgbGV0IHZhbHVlID0gKDxhbnk+bWF0ZXJpYWxWYWx1ZXMpW3RlY2huaXF1ZVVuaWZvcm1zW3VuaWZdXTtcclxuXHJcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgLy8gSW4gY2FzZSB0aGUgdmFsdWUgaXMgdGhlIHNhbWUgZm9yIGFsbCBtYXRlcmlhbHNcclxuICAgICAgICAgICAgdmFsdWUgPSA8YW55PnVuaWZvcm0udmFsdWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXZhbHVlKSB7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3Qgb25Mb2FkVGV4dHVyZSA9ICh1bmlmb3JtTmFtZTogTnVsbGFibGU8c3RyaW5nPikgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gKHRleHR1cmU6IFRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh1bmlmb3JtLnZhbHVlICYmIHVuaWZvcm1OYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RhdGljIHVuaWZvcm1cclxuICAgICAgICAgICAgICAgICAgICBzaGFkZXJNYXRlcmlhbC5zZXRUZXh0dXJlKHVuaWZvcm1OYW1lLCB0ZXh0dXJlKTtcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdW5UcmVhdGVkVW5pZm9ybXNbdW5pZm9ybU5hbWVdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8vIFRleHR1cmUgKHNhbXBsZXIyRClcclxuICAgICAgICBpZiAodHlwZSA9PT0gRVBhcmFtZXRlclR5cGUuU0FNUExFUl8yRCkge1xyXG4gICAgICAgICAgICBHTFRGTG9hZGVyRXh0ZW5zaW9uLkxvYWRUZXh0dXJlQXN5bmMoZ2x0ZlJ1bnRpbWUsIG1hdGVyaWFsLnZhbHVlcyA/IHZhbHVlIDogdW5pZm9ybS52YWx1ZSwgb25Mb2FkVGV4dHVyZSh1bmlmKSwgKCkgPT4gb25Mb2FkVGV4dHVyZShudWxsKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIE90aGVyc1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAodW5pZm9ybS52YWx1ZSAmJiBHTFRGVXRpbHMuU2V0VW5pZm9ybShzaGFkZXJNYXRlcmlhbCwgdW5pZiwgbWF0ZXJpYWwudmFsdWVzID8gdmFsdWUgOiB1bmlmb3JtLnZhbHVlLCB0eXBlKSkge1xyXG4gICAgICAgICAgICAgICAgLy8gU3RhdGljIHVuaWZvcm1cclxuICAgICAgICAgICAgICAgIGRlbGV0ZSB1blRyZWF0ZWRVbmlmb3Jtc1t1bmlmXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufTtcclxuXHJcbi8qKlxyXG4gKiBTaGFkZXIgY29tcGlsYXRpb24gZmFpbGVkXHJcbiAqIEBwYXJhbSBwcm9ncmFtXHJcbiAqIEBwYXJhbSBzaGFkZXJNYXRlcmlhbFxyXG4gKiBAcGFyYW0gb25FcnJvclxyXG4gKiBAcmV0dXJucyBjYWxsYmFjayB3aGVuIHNoYWRlciBpcyBjb21waWxlZFxyXG4gKi9cclxuY29uc3Qgb25TaGFkZXJDb21waWxlRXJyb3IgPSAocHJvZ3JhbTogSUdMVEZQcm9ncmFtLCBzaGFkZXJNYXRlcmlhbDogU2hhZGVyTWF0ZXJpYWwsIG9uRXJyb3I6IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQpID0+IHtcclxuICAgIHJldHVybiAoZWZmZWN0OiBFZmZlY3QsIGVycm9yOiBzdHJpbmcpID0+IHtcclxuICAgICAgICBzaGFkZXJNYXRlcmlhbC5kaXNwb3NlKHRydWUpO1xyXG4gICAgICAgIG9uRXJyb3IoXCJDYW5ub3QgY29tcGlsZSBwcm9ncmFtIG5hbWVkIFwiICsgcHJvZ3JhbS5uYW1lICsgXCIuIEVycm9yOiBcIiArIGVycm9yICsgXCIuIERlZmF1bHQgbWF0ZXJpYWwgd2lsbCBiZSBhcHBsaWVkXCIpO1xyXG4gICAgfTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBTaGFkZXIgY29tcGlsYXRpb24gc3VjY2Vzc1xyXG4gKiBAcGFyYW0gZ2x0ZlJ1bnRpbWVcclxuICogQHBhcmFtIHNoYWRlck1hdGVyaWFsXHJcbiAqIEBwYXJhbSB0ZWNobmlxdWVcclxuICogQHBhcmFtIG1hdGVyaWFsXHJcbiAqIEBwYXJhbSB1blRyZWF0ZWRVbmlmb3Jtc1xyXG4gKiBAcGFyYW0gb25TdWNjZXNzXHJcbiAqIEByZXR1cm5zIGNhbGxiYWNrIHdoZW4gc2hhZGVyIGlzIGNvbXBpbGVkXHJcbiAqL1xyXG5jb25zdCBvblNoYWRlckNvbXBpbGVTdWNjZXNzID0gKFxyXG4gICAgZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSxcclxuICAgIHNoYWRlck1hdGVyaWFsOiBTaGFkZXJNYXRlcmlhbCxcclxuICAgIHRlY2huaXF1ZTogSUdMVEZUZWNobmlxdWUsXHJcbiAgICBtYXRlcmlhbDogSUdMVEZNYXRlcmlhbCxcclxuICAgIHVuVHJlYXRlZFVuaWZvcm1zOiB7IFtrZXk6IHN0cmluZ106IElHTFRGVGVjaG5pcXVlUGFyYW1ldGVyIH0sXHJcbiAgICBvblN1Y2Nlc3M6IChzaGFkZXJNYXRlcmlhbDogU2hhZGVyTWF0ZXJpYWwpID0+IHZvaWRcclxuKSA9PiB7XHJcbiAgICByZXR1cm4gKF86IEVmZmVjdCkgPT4ge1xyXG4gICAgICAgIHByZXBhcmVTaGFkZXJNYXRlcmlhbFVuaWZvcm1zKGdsdGZSdW50aW1lLCBzaGFkZXJNYXRlcmlhbCwgdGVjaG5pcXVlLCBtYXRlcmlhbCwgdW5UcmVhdGVkVW5pZm9ybXMpO1xyXG5cclxuICAgICAgICBzaGFkZXJNYXRlcmlhbC5vbkJpbmQgPSAobWVzaDogQWJzdHJhY3RNZXNoKSA9PiB7XHJcbiAgICAgICAgICAgIG9uQmluZFNoYWRlck1hdGVyaWFsKG1lc2gsIGdsdGZSdW50aW1lLCB1blRyZWF0ZWRVbmlmb3Jtcywgc2hhZGVyTWF0ZXJpYWwsIHRlY2huaXF1ZSwgbWF0ZXJpYWwsIG9uU3VjY2Vzcyk7XHJcbiAgICAgICAgfTtcclxuICAgIH07XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGUgYXBwcm9wcmlhdGUgdW5pZm9ybSBpZiBhbHJlYWR5IGhhbmRsZWQgYnkgYmFieWxvblxyXG4gKiBAcGFyYW0gdG9rZW5pemVyXHJcbiAqIEBwYXJhbSB0ZWNobmlxdWVcclxuICogQHBhcmFtIHVuVHJlYXRlZFVuaWZvcm1zXHJcbiAqIEByZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSB1bmlmb3JtIGhhbmRsZWQgYnkgYmFieWxvblxyXG4gKi9cclxuY29uc3QgcGFyc2VTaGFkZXJVbmlmb3JtcyA9ICh0b2tlbml6ZXI6IFRva2VuaXplciwgdGVjaG5pcXVlOiBJR0xURlRlY2huaXF1ZSwgdW5UcmVhdGVkVW5pZm9ybXM6IHsgW2tleTogc3RyaW5nXTogSUdMVEZUZWNobmlxdWVQYXJhbWV0ZXIgfSk6IHN0cmluZyA9PiB7XHJcbiAgICBmb3IgKGNvbnN0IHVuaWYgaW4gdGVjaG5pcXVlLnVuaWZvcm1zKSB7XHJcbiAgICAgICAgY29uc3QgdW5pZm9ybSA9IHRlY2huaXF1ZS51bmlmb3Jtc1t1bmlmXTtcclxuICAgICAgICBjb25zdCB1bmlmb3JtUGFyYW1ldGVyOiBJR0xURlRlY2huaXF1ZVBhcmFtZXRlciA9IHRlY2huaXF1ZS5wYXJhbWV0ZXJzW3VuaWZvcm1dO1xyXG5cclxuICAgICAgICBpZiAodG9rZW5pemVyLmN1cnJlbnRJZGVudGlmaWVyID09PSB1bmlmKSB7XHJcbiAgICAgICAgICAgIGlmICh1bmlmb3JtUGFyYW1ldGVyLnNlbWFudGljICYmICF1bmlmb3JtUGFyYW1ldGVyLnNvdXJjZSAmJiAhdW5pZm9ybVBhcmFtZXRlci5ub2RlKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1JbmRleCA9IGdsVEZUcmFuc2Zvcm1zLmluZGV4T2YodW5pZm9ybVBhcmFtZXRlci5zZW1hbnRpYyk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRyYW5zZm9ybUluZGV4ICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB1blRyZWF0ZWRVbmlmb3Jtc1t1bmlmXTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYmFieWxvblRyYW5zZm9ybXNbdHJhbnNmb3JtSW5kZXhdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0b2tlbml6ZXIuY3VycmVudElkZW50aWZpZXI7XHJcbn07XHJcblxyXG4vKipcclxuICogQWxsIHNoYWRlcnMgbG9hZGVkLiBDcmVhdGUgbWF0ZXJpYWxzIG9uZSBieSBvbmVcclxuICogQHBhcmFtIGdsdGZSdW50aW1lXHJcbiAqL1xyXG5jb25zdCBpbXBvcnRNYXRlcmlhbHMgPSAoZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSkgPT4ge1xyXG4gICAgLy8gQ3JlYXRlIG1hdGVyaWFsc1xyXG4gICAgZm9yIChjb25zdCBtYXQgaW4gZ2x0ZlJ1bnRpbWUubWF0ZXJpYWxzKSB7XHJcbiAgICAgICAgR0xURkxvYWRlckV4dGVuc2lvbi5Mb2FkTWF0ZXJpYWxBc3luYyhcclxuICAgICAgICAgICAgZ2x0ZlJ1bnRpbWUsXHJcbiAgICAgICAgICAgIG1hdCxcclxuICAgICAgICAgICAgKCkgPT4ge30sXHJcbiAgICAgICAgICAgICgpID0+IHt9XHJcbiAgICAgICAgKTtcclxuICAgIH1cclxufTtcclxuXHJcbi8qKlxyXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgYmFzZSBnbFRGIHNwZWNcclxuICogQGludGVybmFsXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgR0xURkxvYWRlckJhc2Uge1xyXG4gICAgcHVibGljIHN0YXRpYyBDcmVhdGVSdW50aW1lKHBhcnNlZERhdGE6IGFueSwgc2NlbmU6IFNjZW5lLCByb290VXJsOiBzdHJpbmcpOiBJR0xURlJ1bnRpbWUge1xyXG4gICAgICAgIGNvbnN0IGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUgPSB7XHJcbiAgICAgICAgICAgIGV4dGVuc2lvbnM6IHt9LFxyXG4gICAgICAgICAgICBhY2Nlc3NvcnM6IHt9LFxyXG4gICAgICAgICAgICBidWZmZXJzOiB7fSxcclxuICAgICAgICAgICAgYnVmZmVyVmlld3M6IHt9LFxyXG4gICAgICAgICAgICBtZXNoZXM6IHt9LFxyXG4gICAgICAgICAgICBsaWdodHM6IHt9LFxyXG4gICAgICAgICAgICBjYW1lcmFzOiB7fSxcclxuICAgICAgICAgICAgbm9kZXM6IHt9LFxyXG4gICAgICAgICAgICBpbWFnZXM6IHt9LFxyXG4gICAgICAgICAgICB0ZXh0dXJlczoge30sXHJcbiAgICAgICAgICAgIHNoYWRlcnM6IHt9LFxyXG4gICAgICAgICAgICBwcm9ncmFtczoge30sXHJcbiAgICAgICAgICAgIHNhbXBsZXJzOiB7fSxcclxuICAgICAgICAgICAgdGVjaG5pcXVlczoge30sXHJcbiAgICAgICAgICAgIG1hdGVyaWFsczoge30sXHJcbiAgICAgICAgICAgIGFuaW1hdGlvbnM6IHt9LFxyXG4gICAgICAgICAgICBza2luczoge30sXHJcbiAgICAgICAgICAgIGV4dGVuc2lvbnNVc2VkOiBbXSxcclxuXHJcbiAgICAgICAgICAgIHNjZW5lczoge30sXHJcblxyXG4gICAgICAgICAgICBidWZmZXJzQ291bnQ6IDAsXHJcbiAgICAgICAgICAgIHNoYWRlcnNjb3VudDogMCxcclxuXHJcbiAgICAgICAgICAgIHNjZW5lOiBzY2VuZSxcclxuICAgICAgICAgICAgcm9vdFVybDogcm9vdFVybCxcclxuXHJcbiAgICAgICAgICAgIGxvYWRlZEJ1ZmZlckNvdW50OiAwLFxyXG4gICAgICAgICAgICBsb2FkZWRCdWZmZXJWaWV3czoge30sXHJcblxyXG4gICAgICAgICAgICBsb2FkZWRTaGFkZXJDb3VudDogMCxcclxuXHJcbiAgICAgICAgICAgIGltcG9ydE9ubHlNZXNoZXM6IGZhbHNlLFxyXG5cclxuICAgICAgICAgICAgZHVtbXlOb2RlczogW10sXHJcblxyXG4gICAgICAgICAgICBhc3NldENvbnRhaW5lcjogbnVsbCxcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvLyBQYXJzZVxyXG4gICAgICAgIGlmIChwYXJzZWREYXRhLmV4dGVuc2lvbnMpIHtcclxuICAgICAgICAgICAgcGFyc2VPYmplY3QocGFyc2VkRGF0YS5leHRlbnNpb25zLCBcImV4dGVuc2lvbnNcIiwgZ2x0ZlJ1bnRpbWUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBhcnNlZERhdGEuZXh0ZW5zaW9uc1VzZWQpIHtcclxuICAgICAgICAgICAgcGFyc2VPYmplY3QocGFyc2VkRGF0YS5leHRlbnNpb25zVXNlZCwgXCJleHRlbnNpb25zVXNlZFwiLCBnbHRmUnVudGltZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGFyc2VkRGF0YS5idWZmZXJzKSB7XHJcbiAgICAgICAgICAgIHBhcnNlQnVmZmVycyhwYXJzZWREYXRhLmJ1ZmZlcnMsIGdsdGZSdW50aW1lKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwYXJzZWREYXRhLmJ1ZmZlclZpZXdzKSB7XHJcbiAgICAgICAgICAgIHBhcnNlT2JqZWN0KHBhcnNlZERhdGEuYnVmZmVyVmlld3MsIFwiYnVmZmVyVmlld3NcIiwgZ2x0ZlJ1bnRpbWUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBhcnNlZERhdGEuYWNjZXNzb3JzKSB7XHJcbiAgICAgICAgICAgIHBhcnNlT2JqZWN0KHBhcnNlZERhdGEuYWNjZXNzb3JzLCBcImFjY2Vzc29yc1wiLCBnbHRmUnVudGltZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGFyc2VkRGF0YS5tZXNoZXMpIHtcclxuICAgICAgICAgICAgcGFyc2VPYmplY3QocGFyc2VkRGF0YS5tZXNoZXMsIFwibWVzaGVzXCIsIGdsdGZSdW50aW1lKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwYXJzZWREYXRhLmxpZ2h0cykge1xyXG4gICAgICAgICAgICBwYXJzZU9iamVjdChwYXJzZWREYXRhLmxpZ2h0cywgXCJsaWdodHNcIiwgZ2x0ZlJ1bnRpbWUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBhcnNlZERhdGEuY2FtZXJhcykge1xyXG4gICAgICAgICAgICBwYXJzZU9iamVjdChwYXJzZWREYXRhLmNhbWVyYXMsIFwiY2FtZXJhc1wiLCBnbHRmUnVudGltZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGFyc2VkRGF0YS5ub2Rlcykge1xyXG4gICAgICAgICAgICBwYXJzZU9iamVjdChwYXJzZWREYXRhLm5vZGVzLCBcIm5vZGVzXCIsIGdsdGZSdW50aW1lKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwYXJzZWREYXRhLmltYWdlcykge1xyXG4gICAgICAgICAgICBwYXJzZU9iamVjdChwYXJzZWREYXRhLmltYWdlcywgXCJpbWFnZXNcIiwgZ2x0ZlJ1bnRpbWUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBhcnNlZERhdGEudGV4dHVyZXMpIHtcclxuICAgICAgICAgICAgcGFyc2VPYmplY3QocGFyc2VkRGF0YS50ZXh0dXJlcywgXCJ0ZXh0dXJlc1wiLCBnbHRmUnVudGltZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGFyc2VkRGF0YS5zaGFkZXJzKSB7XHJcbiAgICAgICAgICAgIHBhcnNlU2hhZGVycyhwYXJzZWREYXRhLnNoYWRlcnMsIGdsdGZSdW50aW1lKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwYXJzZWREYXRhLnByb2dyYW1zKSB7XHJcbiAgICAgICAgICAgIHBhcnNlT2JqZWN0KHBhcnNlZERhdGEucHJvZ3JhbXMsIFwicHJvZ3JhbXNcIiwgZ2x0ZlJ1bnRpbWUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBhcnNlZERhdGEuc2FtcGxlcnMpIHtcclxuICAgICAgICAgICAgcGFyc2VPYmplY3QocGFyc2VkRGF0YS5zYW1wbGVycywgXCJzYW1wbGVyc1wiLCBnbHRmUnVudGltZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGFyc2VkRGF0YS50ZWNobmlxdWVzKSB7XHJcbiAgICAgICAgICAgIHBhcnNlT2JqZWN0KHBhcnNlZERhdGEudGVjaG5pcXVlcywgXCJ0ZWNobmlxdWVzXCIsIGdsdGZSdW50aW1lKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwYXJzZWREYXRhLm1hdGVyaWFscykge1xyXG4gICAgICAgICAgICBwYXJzZU9iamVjdChwYXJzZWREYXRhLm1hdGVyaWFscywgXCJtYXRlcmlhbHNcIiwgZ2x0ZlJ1bnRpbWUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBhcnNlZERhdGEuYW5pbWF0aW9ucykge1xyXG4gICAgICAgICAgICBwYXJzZU9iamVjdChwYXJzZWREYXRhLmFuaW1hdGlvbnMsIFwiYW5pbWF0aW9uc1wiLCBnbHRmUnVudGltZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGFyc2VkRGF0YS5za2lucykge1xyXG4gICAgICAgICAgICBwYXJzZU9iamVjdChwYXJzZWREYXRhLnNraW5zLCBcInNraW5zXCIsIGdsdGZSdW50aW1lKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwYXJzZWREYXRhLnNjZW5lcykge1xyXG4gICAgICAgICAgICBnbHRmUnVudGltZS5zY2VuZXMgPSBwYXJzZWREYXRhLnNjZW5lcztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwYXJzZWREYXRhLnNjZW5lICYmIHBhcnNlZERhdGEuc2NlbmVzKSB7XHJcbiAgICAgICAgICAgIGdsdGZSdW50aW1lLmN1cnJlbnRTY2VuZSA9IHBhcnNlZERhdGEuc2NlbmVzW3BhcnNlZERhdGEuc2NlbmVdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGdsdGZSdW50aW1lO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzdGF0aWMgTG9hZEJ1ZmZlckFzeW5jKFxyXG4gICAgICAgIGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsXHJcbiAgICAgICAgaWQ6IHN0cmluZyxcclxuICAgICAgICBvblN1Y2Nlc3M6IChidWZmZXI6IEFycmF5QnVmZmVyVmlldykgPT4gdm9pZCxcclxuICAgICAgICBvbkVycm9yOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkLFxyXG4gICAgICAgIG9uUHJvZ3Jlc3M/OiAoKSA9PiB2b2lkXHJcbiAgICApOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBidWZmZXI6IElHTFRGQnVmZmVyID0gZ2x0ZlJ1bnRpbWUuYnVmZmVyc1tpZF07XHJcblxyXG4gICAgICAgIGlmIChUb29scy5Jc0Jhc2U2NChidWZmZXIudXJpKSkge1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IG9uU3VjY2VzcyhuZXcgVWludDhBcnJheShUb29scy5EZWNvZGVCYXNlNjQoYnVmZmVyLnVyaSkpKSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgVG9vbHMuTG9hZEZpbGUoXHJcbiAgICAgICAgICAgICAgICBnbHRmUnVudGltZS5yb290VXJsICsgYnVmZmVyLnVyaSxcclxuICAgICAgICAgICAgICAgIChkYXRhKSA9PiBvblN1Y2Nlc3MobmV3IFVpbnQ4QXJyYXkoZGF0YSBhcyBBcnJheUJ1ZmZlcikpLFxyXG4gICAgICAgICAgICAgICAgb25Qcm9ncmVzcyxcclxuICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgICAgIHRydWUsXHJcbiAgICAgICAgICAgICAgICAocmVxdWVzdCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uRXJyb3IocmVxdWVzdC5zdGF0dXMgKyBcIiBcIiArIHJlcXVlc3Quc3RhdHVzVGV4dCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhdGljIExvYWRUZXh0dXJlQnVmZmVyQXN5bmMoZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSwgaWQ6IHN0cmluZywgb25TdWNjZXNzOiAoYnVmZmVyOiBOdWxsYWJsZTxBcnJheUJ1ZmZlclZpZXc+KSA9PiB2b2lkLCBvbkVycm9yOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgdGV4dHVyZTogSUdMVEZUZXh0dXJlID0gZ2x0ZlJ1bnRpbWUudGV4dHVyZXNbaWRdO1xyXG5cclxuICAgICAgICBpZiAoIXRleHR1cmUgfHwgIXRleHR1cmUuc291cmNlKSB7XHJcbiAgICAgICAgICAgIG9uRXJyb3IoXCJcIik7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0ZXh0dXJlLmJhYnlsb25UZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIG9uU3VjY2VzcyhudWxsKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3Qgc291cmNlOiBJR0xURkltYWdlID0gZ2x0ZlJ1bnRpbWUuaW1hZ2VzW3RleHR1cmUuc291cmNlXTtcclxuXHJcbiAgICAgICAgaWYgKFRvb2xzLklzQmFzZTY0KHNvdXJjZS51cmkpKSB7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gb25TdWNjZXNzKG5ldyBVaW50OEFycmF5KFRvb2xzLkRlY29kZUJhc2U2NChzb3VyY2UudXJpKSkpKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBUb29scy5Mb2FkRmlsZShcclxuICAgICAgICAgICAgICAgIGdsdGZSdW50aW1lLnJvb3RVcmwgKyBzb3VyY2UudXJpLFxyXG4gICAgICAgICAgICAgICAgKGRhdGEpID0+IG9uU3VjY2VzcyhuZXcgVWludDhBcnJheShkYXRhIGFzIEFycmF5QnVmZmVyKSksXHJcbiAgICAgICAgICAgICAgICB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICB0cnVlLFxyXG4gICAgICAgICAgICAgICAgKHJlcXVlc3QpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocmVxdWVzdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkVycm9yKHJlcXVlc3Quc3RhdHVzICsgXCIgXCIgKyByZXF1ZXN0LnN0YXR1c1RleHQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHN0YXRpYyBDcmVhdGVUZXh0dXJlQXN5bmMoZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSwgaWQ6IHN0cmluZywgYnVmZmVyOiBOdWxsYWJsZTxBcnJheUJ1ZmZlclZpZXc+LCBvblN1Y2Nlc3M6ICh0ZXh0dXJlOiBUZXh0dXJlKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgdGV4dHVyZTogSUdMVEZUZXh0dXJlID0gZ2x0ZlJ1bnRpbWUudGV4dHVyZXNbaWRdO1xyXG5cclxuICAgICAgICBpZiAodGV4dHVyZS5iYWJ5bG9uVGV4dHVyZSkge1xyXG4gICAgICAgICAgICBvblN1Y2Nlc3ModGV4dHVyZS5iYWJ5bG9uVGV4dHVyZSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHNhbXBsZXI6IElHTFRGU2FtcGxlciA9IGdsdGZSdW50aW1lLnNhbXBsZXJzW3RleHR1cmUuc2FtcGxlcl07XHJcblxyXG4gICAgICAgIGNvbnN0IGNyZWF0ZU1pcE1hcHMgPVxyXG4gICAgICAgICAgICBzYW1wbGVyLm1pbkZpbHRlciA9PT0gRVRleHR1cmVGaWx0ZXJUeXBlLk5FQVJFU1RfTUlQTUFQX05FQVJFU1QgfHxcclxuICAgICAgICAgICAgc2FtcGxlci5taW5GaWx0ZXIgPT09IEVUZXh0dXJlRmlsdGVyVHlwZS5ORUFSRVNUX01JUE1BUF9MSU5FQVIgfHxcclxuICAgICAgICAgICAgc2FtcGxlci5taW5GaWx0ZXIgPT09IEVUZXh0dXJlRmlsdGVyVHlwZS5MSU5FQVJfTUlQTUFQX05FQVJFU1QgfHxcclxuICAgICAgICAgICAgc2FtcGxlci5taW5GaWx0ZXIgPT09IEVUZXh0dXJlRmlsdGVyVHlwZS5MSU5FQVJfTUlQTUFQX0xJTkVBUjtcclxuXHJcbiAgICAgICAgY29uc3Qgc2FtcGxpbmdNb2RlID0gVGV4dHVyZS5CSUxJTkVBUl9TQU1QTElOR01PREU7XHJcblxyXG4gICAgICAgIGNvbnN0IGJsb2IgPSBidWZmZXIgPT0gbnVsbCA/IG5ldyBCbG9iKCkgOiBuZXcgQmxvYihbYnVmZmVyXSk7XHJcbiAgICAgICAgY29uc3QgYmxvYlVSTCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XHJcbiAgICAgICAgY29uc3QgcmV2b2tlQmxvYlVSTCA9ICgpID0+IFVSTC5yZXZva2VPYmplY3RVUkwoYmxvYlVSTCk7XHJcbiAgICAgICAgY29uc3QgbmV3VGV4dHVyZSA9IG5ldyBUZXh0dXJlKGJsb2JVUkwsIGdsdGZSdW50aW1lLnNjZW5lLCAhY3JlYXRlTWlwTWFwcywgdHJ1ZSwgc2FtcGxpbmdNb2RlLCByZXZva2VCbG9iVVJMLCByZXZva2VCbG9iVVJMKTtcclxuICAgICAgICBpZiAoc2FtcGxlci53cmFwUyAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIG5ld1RleHR1cmUud3JhcFUgPSBHTFRGVXRpbHMuR2V0V3JhcE1vZGUoc2FtcGxlci53cmFwUyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzYW1wbGVyLndyYXBUICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgbmV3VGV4dHVyZS53cmFwViA9IEdMVEZVdGlscy5HZXRXcmFwTW9kZShzYW1wbGVyLndyYXBUKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbmV3VGV4dHVyZS5uYW1lID0gaWQ7XHJcblxyXG4gICAgICAgIHRleHR1cmUuYmFieWxvblRleHR1cmUgPSBuZXdUZXh0dXJlO1xyXG4gICAgICAgIG9uU3VjY2VzcyhuZXdUZXh0dXJlKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhdGljIExvYWRTaGFkZXJTdHJpbmdBc3luYyhnbHRmUnVudGltZTogSUdMVEZSdW50aW1lLCBpZDogc3RyaW5nLCBvblN1Y2Nlc3M6IChzaGFkZXJTdHJpbmc6IHN0cmluZyB8IEFycmF5QnVmZmVyKSA9PiB2b2lkLCBvbkVycm9yPzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHNoYWRlcjogSUdMVEZTaGFkZXIgPSBnbHRmUnVudGltZS5zaGFkZXJzW2lkXTtcclxuXHJcbiAgICAgICAgaWYgKFRvb2xzLklzQmFzZTY0KHNoYWRlci51cmkpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHNoYWRlclN0cmluZyA9IGF0b2Ioc2hhZGVyLnVyaS5zcGxpdChcIixcIilbMV0pO1xyXG4gICAgICAgICAgICBpZiAob25TdWNjZXNzKSB7XHJcbiAgICAgICAgICAgICAgICBvblN1Y2Nlc3Moc2hhZGVyU3RyaW5nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIFRvb2xzLkxvYWRGaWxlKGdsdGZSdW50aW1lLnJvb3RVcmwgKyBzaGFkZXIudXJpLCBvblN1Y2Nlc3MsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBmYWxzZSwgKHJlcXVlc3QpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0ICYmIG9uRXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICBvbkVycm9yKHJlcXVlc3Quc3RhdHVzICsgXCIgXCIgKyByZXF1ZXN0LnN0YXR1c1RleHQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHN0YXRpYyBMb2FkTWF0ZXJpYWxBc3luYyhnbHRmUnVudGltZTogSUdMVEZSdW50aW1lLCBpZDogc3RyaW5nLCBvblN1Y2Nlc3M6IChtYXRlcmlhbDogTWF0ZXJpYWwpID0+IHZvaWQsIG9uRXJyb3I6IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBtYXRlcmlhbDogSUdMVEZNYXRlcmlhbCA9IGdsdGZSdW50aW1lLm1hdGVyaWFsc1tpZF07XHJcbiAgICAgICAgaWYgKCFtYXRlcmlhbC50ZWNobmlxdWUpIHtcclxuICAgICAgICAgICAgaWYgKG9uRXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIG9uRXJyb3IoXCJObyB0ZWNobmlxdWUgZm91bmQuXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHRlY2huaXF1ZTogSUdMVEZUZWNobmlxdWUgPSBnbHRmUnVudGltZS50ZWNobmlxdWVzW21hdGVyaWFsLnRlY2huaXF1ZV07XHJcbiAgICAgICAgaWYgKCF0ZWNobmlxdWUpIHtcclxuICAgICAgICAgICAgZ2x0ZlJ1bnRpbWUuc2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9ICEhZ2x0ZlJ1bnRpbWUuYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRNYXRlcmlhbCA9IG5ldyBTdGFuZGFyZE1hdGVyaWFsKGlkLCBnbHRmUnVudGltZS5zY2VuZSk7XHJcbiAgICAgICAgICAgIGRlZmF1bHRNYXRlcmlhbC5fcGFyZW50Q29udGFpbmVyID0gZ2x0ZlJ1bnRpbWUuYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgICAgIGdsdGZSdW50aW1lLnNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSBmYWxzZTtcclxuICAgICAgICAgICAgZGVmYXVsdE1hdGVyaWFsLmRpZmZ1c2VDb2xvciA9IG5ldyBDb2xvcjMoMC41LCAwLjUsIDAuNSk7XHJcbiAgICAgICAgICAgIGRlZmF1bHRNYXRlcmlhbC5zaWRlT3JpZW50YXRpb24gPSBNYXRlcmlhbC5Db3VudGVyQ2xvY2tXaXNlU2lkZU9yaWVudGF0aW9uO1xyXG4gICAgICAgICAgICBvblN1Y2Nlc3MoZGVmYXVsdE1hdGVyaWFsKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcHJvZ3JhbTogSUdMVEZQcm9ncmFtID0gZ2x0ZlJ1bnRpbWUucHJvZ3JhbXNbdGVjaG5pcXVlLnByb2dyYW1dO1xyXG4gICAgICAgIGNvbnN0IHN0YXRlczogSUdMVEZUZWNobmlxdWVTdGF0ZXMgPSB0ZWNobmlxdWUuc3RhdGVzO1xyXG5cclxuICAgICAgICBjb25zdCB2ZXJ0ZXhTaGFkZXI6IHN0cmluZyA9IEVmZmVjdC5TaGFkZXJzU3RvcmVbcHJvZ3JhbS52ZXJ0ZXhTaGFkZXIgKyBcIlZlcnRleFNoYWRlclwiXTtcclxuICAgICAgICBjb25zdCBwaXhlbFNoYWRlcjogc3RyaW5nID0gRWZmZWN0LlNoYWRlcnNTdG9yZVtwcm9ncmFtLmZyYWdtZW50U2hhZGVyICsgXCJQaXhlbFNoYWRlclwiXTtcclxuICAgICAgICBsZXQgbmV3VmVydGV4U2hhZGVyID0gXCJcIjtcclxuICAgICAgICBsZXQgbmV3UGl4ZWxTaGFkZXIgPSBcIlwiO1xyXG5cclxuICAgICAgICBjb25zdCB2ZXJ0ZXhUb2tlbml6ZXIgPSBuZXcgVG9rZW5pemVyKHZlcnRleFNoYWRlcik7XHJcbiAgICAgICAgY29uc3QgcGl4ZWxUb2tlbml6ZXIgPSBuZXcgVG9rZW5pemVyKHBpeGVsU2hhZGVyKTtcclxuXHJcbiAgICAgICAgY29uc3QgdW5UcmVhdGVkVW5pZm9ybXM6IHsgW2tleTogc3RyaW5nXTogSUdMVEZUZWNobmlxdWVQYXJhbWV0ZXIgfSA9IHt9O1xyXG4gICAgICAgIGNvbnN0IHVuaWZvcm1zOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgICAgIGNvbnN0IGF0dHJpYnV0ZXM6IHN0cmluZ1tdID0gW107XHJcbiAgICAgICAgY29uc3Qgc2FtcGxlcnM6IHN0cmluZ1tdID0gW107XHJcblxyXG4gICAgICAgIC8vIEZpbGwgdW5pZm9ybSwgc2FtcGxlcjJEIGFuZCBhdHRyaWJ1dGVzXHJcbiAgICAgICAgZm9yIChjb25zdCB1bmlmIGluIHRlY2huaXF1ZS51bmlmb3Jtcykge1xyXG4gICAgICAgICAgICBjb25zdCB1bmlmb3JtID0gdGVjaG5pcXVlLnVuaWZvcm1zW3VuaWZdO1xyXG4gICAgICAgICAgICBjb25zdCB1bmlmb3JtUGFyYW1ldGVyOiBJR0xURlRlY2huaXF1ZVBhcmFtZXRlciA9IHRlY2huaXF1ZS5wYXJhbWV0ZXJzW3VuaWZvcm1dO1xyXG5cclxuICAgICAgICAgICAgdW5UcmVhdGVkVW5pZm9ybXNbdW5pZl0gPSB1bmlmb3JtUGFyYW1ldGVyO1xyXG5cclxuICAgICAgICAgICAgaWYgKHVuaWZvcm1QYXJhbWV0ZXIuc2VtYW50aWMgJiYgIXVuaWZvcm1QYXJhbWV0ZXIubm9kZSAmJiAhdW5pZm9ybVBhcmFtZXRlci5zb3VyY2UpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHRyYW5zZm9ybUluZGV4ID0gZ2xURlRyYW5zZm9ybXMuaW5kZXhPZih1bmlmb3JtUGFyYW1ldGVyLnNlbWFudGljKTtcclxuICAgICAgICAgICAgICAgIGlmICh0cmFuc2Zvcm1JbmRleCAhPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICB1bmlmb3Jtcy5wdXNoKGJhYnlsb25UcmFuc2Zvcm1zW3RyYW5zZm9ybUluZGV4XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHVuVHJlYXRlZFVuaWZvcm1zW3VuaWZdO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB1bmlmb3Jtcy5wdXNoKHVuaWYpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHVuaWZvcm1QYXJhbWV0ZXIudHlwZSA9PT0gRVBhcmFtZXRlclR5cGUuU0FNUExFUl8yRCkge1xyXG4gICAgICAgICAgICAgICAgc2FtcGxlcnMucHVzaCh1bmlmKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHVuaWZvcm1zLnB1c2godW5pZik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgYXR0ciBpbiB0ZWNobmlxdWUuYXR0cmlidXRlcykge1xyXG4gICAgICAgICAgICBjb25zdCBhdHRyaWJ1dGUgPSB0ZWNobmlxdWUuYXR0cmlidXRlc1thdHRyXTtcclxuICAgICAgICAgICAgY29uc3QgYXR0cmlidXRlUGFyYW1ldGVyOiBJR0xURlRlY2huaXF1ZVBhcmFtZXRlciA9IHRlY2huaXF1ZS5wYXJhbWV0ZXJzW2F0dHJpYnV0ZV07XHJcblxyXG4gICAgICAgICAgICBpZiAoYXR0cmlidXRlUGFyYW1ldGVyLnNlbWFudGljKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBuYW1lID0gZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZVBhcmFtZXRlcik7XHJcbiAgICAgICAgICAgICAgICBpZiAobmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMucHVzaChuYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQ29uZmlndXJlIHZlcnRleCBzaGFkZXJcclxuICAgICAgICB3aGlsZSAoIXZlcnRleFRva2VuaXplci5pc0VuZCgpICYmIHZlcnRleFRva2VuaXplci5nZXROZXh0VG9rZW4oKSkge1xyXG4gICAgICAgICAgICBjb25zdCB0b2tlblR5cGUgPSB2ZXJ0ZXhUb2tlbml6ZXIuY3VycmVudFRva2VuO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRva2VuVHlwZSAhPT0gRVRva2VuVHlwZS5JREVOVElGSUVSKSB7XHJcbiAgICAgICAgICAgICAgICBuZXdWZXJ0ZXhTaGFkZXIgKz0gdmVydGV4VG9rZW5pemVyLmN1cnJlbnRTdHJpbmc7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGV0IGZvdW5kQXR0cmlidXRlID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGF0dHIgaW4gdGVjaG5pcXVlLmF0dHJpYnV0ZXMpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGF0dHJpYnV0ZSA9IHRlY2huaXF1ZS5hdHRyaWJ1dGVzW2F0dHJdO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYXR0cmlidXRlUGFyYW1ldGVyOiBJR0xURlRlY2huaXF1ZVBhcmFtZXRlciA9IHRlY2huaXF1ZS5wYXJhbWV0ZXJzW2F0dHJpYnV0ZV07XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHZlcnRleFRva2VuaXplci5jdXJyZW50SWRlbnRpZmllciA9PT0gYXR0ciAmJiBhdHRyaWJ1dGVQYXJhbWV0ZXIuc2VtYW50aWMpIHtcclxuICAgICAgICAgICAgICAgICAgICBuZXdWZXJ0ZXhTaGFkZXIgKz0gZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZVBhcmFtZXRlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgZm91bmRBdHRyaWJ1dGUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoZm91bmRBdHRyaWJ1dGUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBuZXdWZXJ0ZXhTaGFkZXIgKz0gcGFyc2VTaGFkZXJVbmlmb3Jtcyh2ZXJ0ZXhUb2tlbml6ZXIsIHRlY2huaXF1ZSwgdW5UcmVhdGVkVW5pZm9ybXMpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQ29uZmlndXJlIHBpeGVsIHNoYWRlclxyXG4gICAgICAgIHdoaWxlICghcGl4ZWxUb2tlbml6ZXIuaXNFbmQoKSAmJiBwaXhlbFRva2VuaXplci5nZXROZXh0VG9rZW4oKSkge1xyXG4gICAgICAgICAgICBjb25zdCB0b2tlblR5cGUgPSBwaXhlbFRva2VuaXplci5jdXJyZW50VG9rZW47XHJcblxyXG4gICAgICAgICAgICBpZiAodG9rZW5UeXBlICE9PSBFVG9rZW5UeXBlLklERU5USUZJRVIpIHtcclxuICAgICAgICAgICAgICAgIG5ld1BpeGVsU2hhZGVyICs9IHBpeGVsVG9rZW5pemVyLmN1cnJlbnRTdHJpbmc7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbmV3UGl4ZWxTaGFkZXIgKz0gcGFyc2VTaGFkZXJVbmlmb3JtcyhwaXhlbFRva2VuaXplciwgdGVjaG5pcXVlLCB1blRyZWF0ZWRVbmlmb3Jtcyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBDcmVhdGUgc2hhZGVyIG1hdGVyaWFsXHJcbiAgICAgICAgY29uc3Qgc2hhZGVyUGF0aCA9IHtcclxuICAgICAgICAgICAgdmVydGV4OiBwcm9ncmFtLnZlcnRleFNoYWRlciArIGlkLFxyXG4gICAgICAgICAgICBmcmFnbWVudDogcHJvZ3JhbS5mcmFnbWVudFNoYWRlciArIGlkLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XHJcbiAgICAgICAgICAgIGF0dHJpYnV0ZXM6IGF0dHJpYnV0ZXMsXHJcbiAgICAgICAgICAgIHVuaWZvcm1zOiB1bmlmb3JtcyxcclxuICAgICAgICAgICAgc2FtcGxlcnM6IHNhbXBsZXJzLFxyXG4gICAgICAgICAgICBuZWVkQWxwaGFCbGVuZGluZzogc3RhdGVzICYmIHN0YXRlcy5lbmFibGUgJiYgc3RhdGVzLmVuYWJsZS5pbmRleE9mKDMwNDIpICE9PSAtMSxcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBFZmZlY3QuU2hhZGVyc1N0b3JlW3Byb2dyYW0udmVydGV4U2hhZGVyICsgaWQgKyBcIlZlcnRleFNoYWRlclwiXSA9IG5ld1ZlcnRleFNoYWRlcjtcclxuICAgICAgICBFZmZlY3QuU2hhZGVyc1N0b3JlW3Byb2dyYW0uZnJhZ21lbnRTaGFkZXIgKyBpZCArIFwiUGl4ZWxTaGFkZXJcIl0gPSBuZXdQaXhlbFNoYWRlcjtcclxuXHJcbiAgICAgICAgY29uc3Qgc2hhZGVyTWF0ZXJpYWwgPSBuZXcgU2hhZGVyTWF0ZXJpYWwoaWQsIGdsdGZSdW50aW1lLnNjZW5lLCBzaGFkZXJQYXRoLCBvcHRpb25zKTtcclxuICAgICAgICBzaGFkZXJNYXRlcmlhbC5vbkVycm9yID0gb25TaGFkZXJDb21waWxlRXJyb3IocHJvZ3JhbSwgc2hhZGVyTWF0ZXJpYWwsIG9uRXJyb3IpO1xyXG4gICAgICAgIHNoYWRlck1hdGVyaWFsLm9uQ29tcGlsZWQgPSBvblNoYWRlckNvbXBpbGVTdWNjZXNzKGdsdGZSdW50aW1lLCBzaGFkZXJNYXRlcmlhbCwgdGVjaG5pcXVlLCBtYXRlcmlhbCwgdW5UcmVhdGVkVW5pZm9ybXMsIG9uU3VjY2Vzcyk7XHJcbiAgICAgICAgc2hhZGVyTWF0ZXJpYWwuc2lkZU9yaWVudGF0aW9uID0gTWF0ZXJpYWwuQ291bnRlckNsb2NrV2lzZVNpZGVPcmllbnRhdGlvbjtcclxuXHJcbiAgICAgICAgaWYgKHN0YXRlcyAmJiBzdGF0ZXMuZnVuY3Rpb25zKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGZ1bmN0aW9ucyA9IHN0YXRlcy5mdW5jdGlvbnM7XHJcbiAgICAgICAgICAgIGlmIChmdW5jdGlvbnMuY3VsbEZhY2UgJiYgZnVuY3Rpb25zLmN1bGxGYWNlWzBdICE9PSBFQ3VsbGluZ1R5cGUuQkFDSykge1xyXG4gICAgICAgICAgICAgICAgc2hhZGVyTWF0ZXJpYWwuYmFja0ZhY2VDdWxsaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGJsZW5kRnVuYyA9IGZ1bmN0aW9ucy5ibGVuZEZ1bmNTZXBhcmF0ZTtcclxuICAgICAgICAgICAgaWYgKGJsZW5kRnVuYykge1xyXG4gICAgICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgICAgICAgIGJsZW5kRnVuY1swXSA9PT0gRUJsZW5kaW5nRnVuY3Rpb24uU1JDX0FMUEhBICYmXHJcbiAgICAgICAgICAgICAgICAgICAgYmxlbmRGdW5jWzFdID09PSBFQmxlbmRpbmdGdW5jdGlvbi5PTkVfTUlOVVNfU1JDX0FMUEhBICYmXHJcbiAgICAgICAgICAgICAgICAgICAgYmxlbmRGdW5jWzJdID09PSBFQmxlbmRpbmdGdW5jdGlvbi5PTkUgJiZcclxuICAgICAgICAgICAgICAgICAgICBibGVuZEZ1bmNbM10gPT09IEVCbGVuZGluZ0Z1bmN0aW9uLk9ORVxyXG4gICAgICAgICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2hhZGVyTWF0ZXJpYWwuYWxwaGFNb2RlID0gQ29uc3RhbnRzLkFMUEhBX0NPTUJJTkU7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAgICAgICAgICAgICAgIGJsZW5kRnVuY1swXSA9PT0gRUJsZW5kaW5nRnVuY3Rpb24uT05FICYmXHJcbiAgICAgICAgICAgICAgICAgICAgYmxlbmRGdW5jWzFdID09PSBFQmxlbmRpbmdGdW5jdGlvbi5PTkUgJiZcclxuICAgICAgICAgICAgICAgICAgICBibGVuZEZ1bmNbMl0gPT09IEVCbGVuZGluZ0Z1bmN0aW9uLlpFUk8gJiZcclxuICAgICAgICAgICAgICAgICAgICBibGVuZEZ1bmNbM10gPT09IEVCbGVuZGluZ0Z1bmN0aW9uLk9ORVxyXG4gICAgICAgICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2hhZGVyTWF0ZXJpYWwuYWxwaGFNb2RlID0gQ29uc3RhbnRzLkFMUEhBX09ORU9ORTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgICAgICAgICAgICAgICAgYmxlbmRGdW5jWzBdID09PSBFQmxlbmRpbmdGdW5jdGlvbi5TUkNfQUxQSEEgJiZcclxuICAgICAgICAgICAgICAgICAgICBibGVuZEZ1bmNbMV0gPT09IEVCbGVuZGluZ0Z1bmN0aW9uLk9ORSAmJlxyXG4gICAgICAgICAgICAgICAgICAgIGJsZW5kRnVuY1syXSA9PT0gRUJsZW5kaW5nRnVuY3Rpb24uWkVSTyAmJlxyXG4gICAgICAgICAgICAgICAgICAgIGJsZW5kRnVuY1szXSA9PT0gRUJsZW5kaW5nRnVuY3Rpb24uT05FXHJcbiAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgICBzaGFkZXJNYXRlcmlhbC5hbHBoYU1vZGUgPSBDb25zdGFudHMuQUxQSEFfQUREO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICAgICAgICAgICAgICBibGVuZEZ1bmNbMF0gPT09IEVCbGVuZGluZ0Z1bmN0aW9uLlpFUk8gJiZcclxuICAgICAgICAgICAgICAgICAgICBibGVuZEZ1bmNbMV0gPT09IEVCbGVuZGluZ0Z1bmN0aW9uLk9ORV9NSU5VU19TUkNfQ09MT1IgJiZcclxuICAgICAgICAgICAgICAgICAgICBibGVuZEZ1bmNbMl0gPT09IEVCbGVuZGluZ0Z1bmN0aW9uLk9ORSAmJlxyXG4gICAgICAgICAgICAgICAgICAgIGJsZW5kRnVuY1szXSA9PT0gRUJsZW5kaW5nRnVuY3Rpb24uT05FXHJcbiAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgICBzaGFkZXJNYXRlcmlhbC5hbHBoYU1vZGUgPSBDb25zdGFudHMuQUxQSEFfU1VCVFJBQ1Q7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAgICAgICAgICAgICAgIGJsZW5kRnVuY1swXSA9PT0gRUJsZW5kaW5nRnVuY3Rpb24uRFNUX0NPTE9SICYmXHJcbiAgICAgICAgICAgICAgICAgICAgYmxlbmRGdW5jWzFdID09PSBFQmxlbmRpbmdGdW5jdGlvbi5aRVJPICYmXHJcbiAgICAgICAgICAgICAgICAgICAgYmxlbmRGdW5jWzJdID09PSBFQmxlbmRpbmdGdW5jdGlvbi5PTkUgJiZcclxuICAgICAgICAgICAgICAgICAgICBibGVuZEZ1bmNbM10gPT09IEVCbGVuZGluZ0Z1bmN0aW9uLk9ORVxyXG4gICAgICAgICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2hhZGVyTWF0ZXJpYWwuYWxwaGFNb2RlID0gQ29uc3RhbnRzLkFMUEhBX01VTFRJUExZO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICAgICAgICAgICAgICBibGVuZEZ1bmNbMF0gPT09IEVCbGVuZGluZ0Z1bmN0aW9uLlNSQ19BTFBIQSAmJlxyXG4gICAgICAgICAgICAgICAgICAgIGJsZW5kRnVuY1sxXSA9PT0gRUJsZW5kaW5nRnVuY3Rpb24uT05FX01JTlVTX1NSQ19DT0xPUiAmJlxyXG4gICAgICAgICAgICAgICAgICAgIGJsZW5kRnVuY1syXSA9PT0gRUJsZW5kaW5nRnVuY3Rpb24uT05FICYmXHJcbiAgICAgICAgICAgICAgICAgICAgYmxlbmRGdW5jWzNdID09PSBFQmxlbmRpbmdGdW5jdGlvbi5PTkVcclxuICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNoYWRlck1hdGVyaWFsLmFscGhhTW9kZSA9IENvbnN0YW50cy5BTFBIQV9NQVhJTUlaRUQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBnbFRGIFYxIExvYWRlclxyXG4gKiBAaW50ZXJuYWxcclxuICogQGRlcHJlY2F0ZWRcclxuICovXHJcbmV4cG9ydCBjbGFzcyBHTFRGTG9hZGVyIGltcGxlbWVudHMgSUdMVEZMb2FkZXIge1xyXG4gICAgcHVibGljIHN0YXRpYyBFeHRlbnNpb25zOiB7IFtuYW1lOiBzdHJpbmddOiBHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gPSB7fTtcclxuXHJcbiAgICBwdWJsaWMgc3RhdGljIFJlZ2lzdGVyRXh0ZW5zaW9uKGV4dGVuc2lvbjogR0xURkxvYWRlckV4dGVuc2lvbik6IHZvaWQge1xyXG4gICAgICAgIGlmIChHTFRGTG9hZGVyLkV4dGVuc2lvbnNbZXh0ZW5zaW9uLm5hbWVdKSB7XHJcbiAgICAgICAgICAgIFRvb2xzLkVycm9yKCdUb29sIHdpdGggdGhlIHNhbWUgbmFtZSBcIicgKyBleHRlbnNpb24ubmFtZSArICdcIiBhbHJlYWR5IGV4aXN0cycpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBHTFRGTG9hZGVyLkV4dGVuc2lvbnNbZXh0ZW5zaW9uLm5hbWVdID0gZXh0ZW5zaW9uO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBkaXNwb3NlKCk6IHZvaWQge1xyXG4gICAgICAgIC8vIGRvIG5vdGhpbmdcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9pbXBvcnRNZXNoQXN5bmMoXHJcbiAgICAgICAgbWVzaGVzTmFtZXM6IGFueSxcclxuICAgICAgICBzY2VuZTogU2NlbmUsXHJcbiAgICAgICAgZGF0YTogSUdMVEZMb2FkZXJEYXRhLFxyXG4gICAgICAgIHJvb3RVcmw6IHN0cmluZyxcclxuICAgICAgICBhc3NldENvbnRhaW5lcjogTnVsbGFibGU8QXNzZXRDb250YWluZXI+LFxyXG4gICAgICAgIG9uU3VjY2VzczogKG1lc2hlczogQWJzdHJhY3RNZXNoW10sIHNrZWxldG9uczogU2tlbGV0b25bXSkgPT4gdm9pZCxcclxuICAgICAgICBvblByb2dyZXNzPzogKGV2ZW50OiBJU2NlbmVMb2FkZXJQcm9ncmVzc0V2ZW50KSA9PiB2b2lkLFxyXG4gICAgICAgIG9uRXJyb3I/OiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkXHJcbiAgICApOiBib29sZWFuIHtcclxuICAgICAgICBzY2VuZS51c2VSaWdodEhhbmRlZFN5c3RlbSA9IHRydWU7XHJcblxyXG4gICAgICAgIEdMVEZMb2FkZXJFeHRlbnNpb24uTG9hZFJ1bnRpbWVBc3luYyhcclxuICAgICAgICAgICAgc2NlbmUsXHJcbiAgICAgICAgICAgIGRhdGEsXHJcbiAgICAgICAgICAgIHJvb3RVcmwsXHJcbiAgICAgICAgICAgIChnbHRmUnVudGltZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgZ2x0ZlJ1bnRpbWUuYXNzZXRDb250YWluZXIgPSBhc3NldENvbnRhaW5lcjtcclxuICAgICAgICAgICAgICAgIGdsdGZSdW50aW1lLmltcG9ydE9ubHlNZXNoZXMgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChtZXNoZXNOYW1lcyA9PT0gXCJcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIGdsdGZSdW50aW1lLmltcG9ydE1lc2hlc05hbWVzID0gW107XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBtZXNoZXNOYW1lcyA9PT0gXCJzdHJpbmdcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIGdsdGZSdW50aW1lLmltcG9ydE1lc2hlc05hbWVzID0gW21lc2hlc05hbWVzXTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWVzaGVzTmFtZXMgJiYgIShtZXNoZXNOYW1lcyBpbnN0YW5jZW9mIEFycmF5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGdsdGZSdW50aW1lLmltcG9ydE1lc2hlc05hbWVzID0gW21lc2hlc05hbWVzXTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZ2x0ZlJ1bnRpbWUuaW1wb3J0TWVzaGVzTmFtZXMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICBUb29scy5XYXJuKFwiQXJndW1lbnQgbWVzaGVzTmFtZXMgbXVzdCBiZSBvZiB0eXBlIHN0cmluZyBvciBzdHJpbmdbXVwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgbm9kZXNcclxuICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5vZGVzKGdsdGZSdW50aW1lKTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBtZXNoZXM6IEFic3RyYWN0TWVzaFtdID0gW107XHJcbiAgICAgICAgICAgICAgICBjb25zdCBza2VsZXRvbnM6IFNrZWxldG9uW10gPSBbXTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBGaWxsIGFycmF5cyBvZiBtZXNoZXMgYW5kIHNrZWxldG9uc1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBuZGUgaW4gZ2x0ZlJ1bnRpbWUubm9kZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBub2RlOiBJR0xURk5vZGUgPSBnbHRmUnVudGltZS5ub2Rlc1tuZGVdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAobm9kZS5iYWJ5bG9uTm9kZSBpbnN0YW5jZW9mIEFic3RyYWN0TWVzaCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNoZXMucHVzaCg8QWJzdHJhY3RNZXNoPm5vZGUuYmFieWxvbk5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNrbCBpbiBnbHRmUnVudGltZS5za2lucykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNraW46IElHTFRGU2tpbnMgPSBnbHRmUnVudGltZS5za2luc1tza2xdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2tpbi5iYWJ5bG9uU2tlbGV0b24gaW5zdGFuY2VvZiBTa2VsZXRvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBza2VsZXRvbnMucHVzaChza2luLmJhYnlsb25Ta2VsZXRvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIExvYWQgYnVmZmVycywgc2hhZGVycywgbWF0ZXJpYWxzLCBldGMuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkQnVmZmVyc0FzeW5jKGdsdGZSdW50aW1lLCAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZFNoYWRlcnNBc3luYyhnbHRmUnVudGltZSwgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbXBvcnRNYXRlcmlhbHMoZ2x0ZlJ1bnRpbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3N0TG9hZChnbHRmUnVudGltZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUdMVEZGaWxlTG9hZGVyLkluY3JlbWVudGFsTG9hZGluZyAmJiBvblN1Y2Nlc3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uU3VjY2VzcyhtZXNoZXMsIHNrZWxldG9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChHTFRGRmlsZUxvYWRlci5JbmNyZW1lbnRhbExvYWRpbmcgJiYgb25TdWNjZXNzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb25TdWNjZXNzKG1lc2hlcywgc2tlbGV0b25zKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgb25FcnJvclxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW1wb3J0cyBvbmUgb3IgbW9yZSBtZXNoZXMgZnJvbSBhIGxvYWRlZCBnbHRmIGZpbGUgYW5kIGFkZHMgdGhlbSB0byB0aGUgc2NlbmVcclxuICAgICAqIEBwYXJhbSBtZXNoZXNOYW1lcyBhIHN0cmluZyBvciBhcnJheSBvZiBzdHJpbmdzIG9mIHRoZSBtZXNoIG5hbWVzIHRoYXQgc2hvdWxkIGJlIGxvYWRlZCBmcm9tIHRoZSBmaWxlXHJcbiAgICAgKiBAcGFyYW0gc2NlbmUgdGhlIHNjZW5lIHRoZSBtZXNoZXMgc2hvdWxkIGJlIGFkZGVkIHRvXHJcbiAgICAgKiBAcGFyYW0gYXNzZXRDb250YWluZXIgZGVmaW5lcyB0aGUgYXNzZXQgY29udGFpbmVyIHRvIHVzZSAoY2FuIGJlIG51bGwpXHJcbiAgICAgKiBAcGFyYW0gZGF0YSBnbHRmIGRhdGEgY29udGFpbmluZyBpbmZvcm1hdGlvbiBvZiB0aGUgbWVzaGVzIGluIGEgbG9hZGVkIGZpbGVcclxuICAgICAqIEBwYXJhbSByb290VXJsIHJvb3QgdXJsIHRvIGxvYWQgZnJvbVxyXG4gICAgICogQHBhcmFtIG9uUHJvZ3Jlc3MgZXZlbnQgdGhhdCBmaXJlcyB3aGVuIGxvYWRpbmcgcHJvZ3Jlc3MgaGFzIG9jY3VyZWRcclxuICAgICAqIEByZXR1cm5zIGEgcHJvbWlzZSBjb250YWluZyB0aGUgbG9hZGVkIG1lc2hlcywgcGFydGljbGVzLCBza2VsZXRvbnMgYW5kIGFuaW1hdGlvbnNcclxuICAgICAqL1xyXG4gICAgcHVibGljIGltcG9ydE1lc2hBc3luYyhcclxuICAgICAgICBtZXNoZXNOYW1lczogYW55LFxyXG4gICAgICAgIHNjZW5lOiBTY2VuZSxcclxuICAgICAgICBhc3NldENvbnRhaW5lcjogTnVsbGFibGU8QXNzZXRDb250YWluZXI+LFxyXG4gICAgICAgIGRhdGE6IElHTFRGTG9hZGVyRGF0YSxcclxuICAgICAgICByb290VXJsOiBzdHJpbmcsXHJcbiAgICAgICAgb25Qcm9ncmVzcz86IChldmVudDogSVNjZW5lTG9hZGVyUHJvZ3Jlc3NFdmVudCkgPT4gdm9pZFxyXG4gICAgKTogUHJvbWlzZTxJU2NlbmVMb2FkZXJBc3luY1Jlc3VsdD4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2ltcG9ydE1lc2hBc3luYyhcclxuICAgICAgICAgICAgICAgIG1lc2hlc05hbWVzLFxyXG4gICAgICAgICAgICAgICAgc2NlbmUsXHJcbiAgICAgICAgICAgICAgICBkYXRhLFxyXG4gICAgICAgICAgICAgICAgcm9vdFVybCxcclxuICAgICAgICAgICAgICAgIGFzc2V0Q29udGFpbmVyLFxyXG4gICAgICAgICAgICAgICAgKG1lc2hlcywgc2tlbGV0b25zKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc2hlczogbWVzaGVzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJ0aWNsZVN5c3RlbXM6IFtdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBza2VsZXRvbnM6IHNrZWxldG9ucyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uR3JvdXBzOiBbXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGlnaHRzOiBbXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtTm9kZXM6IFtdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBnZW9tZXRyaWVzOiBbXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3ByaXRlTWFuYWdlcnM6IFtdLFxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIG9uUHJvZ3Jlc3MsXHJcbiAgICAgICAgICAgICAgICAobWVzc2FnZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IobWVzc2FnZSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRBc3luYyhcclxuICAgICAgICBzY2VuZTogU2NlbmUsXHJcbiAgICAgICAgZGF0YTogSUdMVEZMb2FkZXJEYXRhLFxyXG4gICAgICAgIHJvb3RVcmw6IHN0cmluZyxcclxuICAgICAgICBvblN1Y2Nlc3M6ICgpID0+IHZvaWQsXHJcbiAgICAgICAgb25Qcm9ncmVzcz86IChldmVudDogSVNjZW5lTG9hZGVyUHJvZ3Jlc3NFdmVudCkgPT4gdm9pZCxcclxuICAgICAgICBvbkVycm9yPzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZFxyXG4gICAgKTogdm9pZCB7XHJcbiAgICAgICAgc2NlbmUudXNlUmlnaHRIYW5kZWRTeXN0ZW0gPSB0cnVlO1xyXG5cclxuICAgICAgICBHTFRGTG9hZGVyRXh0ZW5zaW9uLkxvYWRSdW50aW1lQXN5bmMoXHJcbiAgICAgICAgICAgIHNjZW5lLFxyXG4gICAgICAgICAgICBkYXRhLFxyXG4gICAgICAgICAgICByb290VXJsLFxyXG4gICAgICAgICAgICAoZ2x0ZlJ1bnRpbWUpID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIExvYWQgcnVudGltZSBleHRlbnNpb3NcclxuICAgICAgICAgICAgICAgIEdMVEZMb2FkZXJFeHRlbnNpb24uTG9hZFJ1bnRpbWVFeHRlbnNpb25zQXN5bmMoXHJcbiAgICAgICAgICAgICAgICAgICAgZ2x0ZlJ1bnRpbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDcmVhdGUgbm9kZXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlTm9kZXMoZ2x0ZlJ1bnRpbWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTG9hZCBidWZmZXJzLCBzaGFkZXJzLCBtYXRlcmlhbHMsIGV0Yy5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZEJ1ZmZlcnNBc3luYyhnbHRmUnVudGltZSwgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZFNoYWRlcnNBc3luYyhnbHRmUnVudGltZSwgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltcG9ydE1hdGVyaWFscyhnbHRmUnVudGltZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zdExvYWQoZ2x0ZlJ1bnRpbWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUdMVEZGaWxlTG9hZGVyLkluY3JlbWVudGFsTG9hZGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvblN1Y2Nlc3MoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoR0xURkZpbGVMb2FkZXIuSW5jcmVtZW50YWxMb2FkaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvblN1Y2Nlc3MoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgb25FcnJvclxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgb25FcnJvclxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbXBvcnRzIGFsbCBvYmplY3RzIGZyb20gYSBsb2FkZWQgZ2x0ZiBmaWxlIGFuZCBhZGRzIHRoZW0gdG8gdGhlIHNjZW5lXHJcbiAgICAgKiBAcGFyYW0gc2NlbmUgdGhlIHNjZW5lIHRoZSBvYmplY3RzIHNob3VsZCBiZSBhZGRlZCB0b1xyXG4gICAgICogQHBhcmFtIGRhdGEgZ2x0ZiBkYXRhIGNvbnRhaW5pbmcgaW5mb3JtYXRpb24gb2YgdGhlIG1lc2hlcyBpbiBhIGxvYWRlZCBmaWxlXHJcbiAgICAgKiBAcGFyYW0gcm9vdFVybCByb290IHVybCB0byBsb2FkIGZyb21cclxuICAgICAqIEBwYXJhbSBvblByb2dyZXNzIGV2ZW50IHRoYXQgZmlyZXMgd2hlbiBsb2FkaW5nIHByb2dyZXNzIGhhcyBvY2N1cmVkXHJcbiAgICAgKiBAcmV0dXJucyBhIHByb21pc2Ugd2hpY2ggY29tcGxldGVzIHdoZW4gb2JqZWN0cyBoYXZlIGJlZW4gbG9hZGVkIHRvIHRoZSBzY2VuZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZEFzeW5jKHNjZW5lOiBTY2VuZSwgZGF0YTogSUdMVEZMb2FkZXJEYXRhLCByb290VXJsOiBzdHJpbmcsIG9uUHJvZ3Jlc3M/OiAoZXZlbnQ6IElTY2VuZUxvYWRlclByb2dyZXNzRXZlbnQpID0+IHZvaWQpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9sb2FkQXN5bmMoXHJcbiAgICAgICAgICAgICAgICBzY2VuZSxcclxuICAgICAgICAgICAgICAgIGRhdGEsXHJcbiAgICAgICAgICAgICAgICByb290VXJsLFxyXG4gICAgICAgICAgICAgICAgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBvblByb2dyZXNzLFxyXG4gICAgICAgICAgICAgICAgKG1lc3NhZ2UpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKG1lc3NhZ2UpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkU2hhZGVyc0FzeW5jKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsIG9ubG9hZDogKCkgPT4gdm9pZCk6IHZvaWQge1xyXG4gICAgICAgIGxldCBoYXNTaGFkZXJzID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGNvbnN0IHByb2Nlc3NTaGFkZXIgPSAoc2hhOiBzdHJpbmcsIHNoYWRlcjogSUdMVEZTaGFkZXIpID0+IHtcclxuICAgICAgICAgICAgR0xURkxvYWRlckV4dGVuc2lvbi5Mb2FkU2hhZGVyU3RyaW5nQXN5bmMoXHJcbiAgICAgICAgICAgICAgICBnbHRmUnVudGltZSxcclxuICAgICAgICAgICAgICAgIHNoYSxcclxuICAgICAgICAgICAgICAgIChzaGFkZXJTdHJpbmcpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2hhZGVyU3RyaW5nIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZ2x0ZlJ1bnRpbWUubG9hZGVkU2hhZGVyQ291bnQrKztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNoYWRlclN0cmluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBFZmZlY3QuU2hhZGVyc1N0b3JlW3NoYSArIChzaGFkZXIudHlwZSA9PT0gRVNoYWRlclR5cGUuVkVSVEVYID8gXCJWZXJ0ZXhTaGFkZXJcIiA6IFwiUGl4ZWxTaGFkZXJcIildID0gc2hhZGVyU3RyaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGdsdGZSdW50aW1lLmxvYWRlZFNoYWRlckNvdW50ID09PSBnbHRmUnVudGltZS5zaGFkZXJzY291bnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb25sb2FkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBUb29scy5FcnJvcihcIkVycm9yIHdoZW4gbG9hZGluZyBzaGFkZXIgcHJvZ3JhbSBuYW1lZCBcIiArIHNoYSArIFwiIGxvY2F0ZWQgYXQgXCIgKyBzaGFkZXIudXJpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IHNoYSBpbiBnbHRmUnVudGltZS5zaGFkZXJzKSB7XHJcbiAgICAgICAgICAgIGhhc1NoYWRlcnMgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgY29uc3Qgc2hhZGVyOiBJR0xURlNoYWRlciA9IGdsdGZSdW50aW1lLnNoYWRlcnNbc2hhXTtcclxuICAgICAgICAgICAgaWYgKHNoYWRlcikge1xyXG4gICAgICAgICAgICAgICAgcHJvY2Vzc1NoYWRlci5iaW5kKHRoaXMsIHNoYSwgc2hhZGVyKSgpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgVG9vbHMuRXJyb3IoXCJObyBzaGFkZXIgbmFtZWQ6IFwiICsgc2hhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFoYXNTaGFkZXJzKSB7XHJcbiAgICAgICAgICAgIG9ubG9hZCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkQnVmZmVyc0FzeW5jKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsIG9uTG9hZDogKCkgPT4gdm9pZCk6IHZvaWQge1xyXG4gICAgICAgIGxldCBoYXNCdWZmZXJzID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGNvbnN0IHByb2Nlc3NCdWZmZXIgPSAoYnVmOiBzdHJpbmcsIGJ1ZmZlcjogSUdMVEZCdWZmZXIpID0+IHtcclxuICAgICAgICAgICAgR0xURkxvYWRlckV4dGVuc2lvbi5Mb2FkQnVmZmVyQXN5bmMoXHJcbiAgICAgICAgICAgICAgICBnbHRmUnVudGltZSxcclxuICAgICAgICAgICAgICAgIGJ1ZixcclxuICAgICAgICAgICAgICAgIChidWZmZXJWaWV3KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZ2x0ZlJ1bnRpbWUubG9hZGVkQnVmZmVyQ291bnQrKztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJ1ZmZlclZpZXcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJ1ZmZlclZpZXcuYnl0ZUxlbmd0aCAhPSBnbHRmUnVudGltZS5idWZmZXJzW2J1Zl0uYnl0ZUxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgVG9vbHMuRXJyb3IoXCJCdWZmZXIgbmFtZWQgXCIgKyBidWYgKyBcIiBpcyBsZW5ndGggXCIgKyBidWZmZXJWaWV3LmJ5dGVMZW5ndGggKyBcIi4gRXhwZWN0ZWQ6IFwiICsgYnVmZmVyLmJ5dGVMZW5ndGgpOyAvLyBJbXByb3ZlIGVycm9yIG1lc3NhZ2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgZ2x0ZlJ1bnRpbWUubG9hZGVkQnVmZmVyVmlld3NbYnVmXSA9IGJ1ZmZlclZpZXc7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZ2x0ZlJ1bnRpbWUubG9hZGVkQnVmZmVyQ291bnQgPT09IGdsdGZSdW50aW1lLmJ1ZmZlcnNDb3VudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkxvYWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIFRvb2xzLkVycm9yKFwiRXJyb3Igd2hlbiBsb2FkaW5nIGJ1ZmZlciBuYW1lZCBcIiArIGJ1ZiArIFwiIGxvY2F0ZWQgYXQgXCIgKyBidWZmZXIudXJpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IGJ1ZiBpbiBnbHRmUnVudGltZS5idWZmZXJzKSB7XHJcbiAgICAgICAgICAgIGhhc0J1ZmZlcnMgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgYnVmZmVyOiBJR0xURkJ1ZmZlciA9IGdsdGZSdW50aW1lLmJ1ZmZlcnNbYnVmXTtcclxuICAgICAgICAgICAgaWYgKGJ1ZmZlcikge1xyXG4gICAgICAgICAgICAgICAgcHJvY2Vzc0J1ZmZlci5iaW5kKHRoaXMsIGJ1ZiwgYnVmZmVyKSgpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgVG9vbHMuRXJyb3IoXCJObyBidWZmZXIgbmFtZWQ6IFwiICsgYnVmKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFoYXNCdWZmZXJzKSB7XHJcbiAgICAgICAgICAgIG9uTG9hZCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9jcmVhdGVOb2RlcyhnbHRmUnVudGltZTogSUdMVEZSdW50aW1lKTogdm9pZCB7XHJcbiAgICAgICAgbGV0IGN1cnJlbnRTY2VuZSA9IDxJR0xURlNjZW5lPmdsdGZSdW50aW1lLmN1cnJlbnRTY2VuZTtcclxuXHJcbiAgICAgICAgaWYgKGN1cnJlbnRTY2VuZSkge1xyXG4gICAgICAgICAgICAvLyBPbmx5IG9uZSBzY2VuZSBldmVuIGlmIG11bHRpcGxlIHNjZW5lcyBhcmUgZGVmaW5lZFxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGN1cnJlbnRTY2VuZS5ub2Rlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgdHJhdmVyc2VOb2RlcyhnbHRmUnVudGltZSwgY3VycmVudFNjZW5lLm5vZGVzW2ldLCBudWxsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIExvYWQgYWxsIHNjZW5lc1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRoaW5nIGluIGdsdGZSdW50aW1lLnNjZW5lcykge1xyXG4gICAgICAgICAgICAgICAgY3VycmVudFNjZW5lID0gPElHTFRGU2NlbmU+Z2x0ZlJ1bnRpbWUuc2NlbmVzW3RoaW5nXTtcclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGN1cnJlbnRTY2VuZS5ub2Rlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRyYXZlcnNlTm9kZXMoZ2x0ZlJ1bnRpbWUsIGN1cnJlbnRTY2VuZS5ub2Rlc1tpXSwgbnVsbCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgcHJpdmF0ZSBfbmFtZTogc3RyaW5nO1xyXG5cclxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihuYW1lOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLl9uYW1lID0gbmFtZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0IG5hbWUoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbmFtZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgYW4gb3ZlcnJpZGUgZm9yIGxvYWRpbmcgdGhlIHJ1bnRpbWVcclxuICAgICAqIFJldHVybiB0cnVlIHRvIHN0b3AgZnVydGhlciBleHRlbnNpb25zIGZyb20gbG9hZGluZyB0aGUgcnVudGltZVxyXG4gICAgICogQHBhcmFtIHNjZW5lXHJcbiAgICAgKiBAcGFyYW0gZGF0YVxyXG4gICAgICogQHBhcmFtIHJvb3RVcmxcclxuICAgICAqIEBwYXJhbSBvblN1Y2Nlc3NcclxuICAgICAqIEBwYXJhbSBvbkVycm9yXHJcbiAgICAgKiBAcmV0dXJucyB0cnVlIHRvIHN0b3AgZnVydGhlciBleHRlbnNpb25zIGZyb20gbG9hZGluZyB0aGUgcnVudGltZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZFJ1bnRpbWVBc3luYyhzY2VuZTogU2NlbmUsIGRhdGE6IElHTFRGTG9hZGVyRGF0YSwgcm9vdFVybDogc3RyaW5nLCBvblN1Y2Nlc3M/OiAoZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSkgPT4gdm9pZCwgb25FcnJvcj86IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGFuIG9udmVycmlkZSBmb3IgY3JlYXRpbmcgZ2x0ZiBydW50aW1lXHJcbiAgICAgKiBSZXR1cm4gdHJ1ZSB0byBzdG9wIGZ1cnRoZXIgZXh0ZW5zaW9ucyBmcm9tIGNyZWF0aW5nIHRoZSBydW50aW1lXHJcbiAgICAgKiBAcGFyYW0gZ2x0ZlJ1bnRpbWVcclxuICAgICAqIEBwYXJhbSBvblN1Y2Nlc3NcclxuICAgICAqIEBwYXJhbSBvbkVycm9yXHJcbiAgICAgKiBAcmV0dXJucyB0cnVlIHRvIHN0b3AgZnVydGhlciBleHRlbnNpb25zIGZyb20gY3JlYXRpbmcgdGhlIHJ1bnRpbWVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRSdW50aW1lRXh0ZW5zaW9uc0FzeW5jKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsIG9uU3VjY2VzczogKCkgPT4gdm9pZCwgb25FcnJvcj86IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGFuIG92ZXJyaWRlIGZvciBsb2FkaW5nIGJ1ZmZlcnNcclxuICAgICAqIFJldHVybiB0cnVlIHRvIHN0b3AgZnVydGhlciBleHRlbnNpb25zIGZyb20gbG9hZGluZyB0aGlzIGJ1ZmZlclxyXG4gICAgICogQHBhcmFtIGdsdGZSdW50aW1lXHJcbiAgICAgKiBAcGFyYW0gaWRcclxuICAgICAqIEBwYXJhbSBvblN1Y2Nlc3NcclxuICAgICAqIEBwYXJhbSBvbkVycm9yXHJcbiAgICAgKiBAcGFyYW0gb25Qcm9ncmVzc1xyXG4gICAgICogQHJldHVybnMgdHJ1ZSB0byBzdG9wIGZ1cnRoZXIgZXh0ZW5zaW9ucyBmcm9tIGxvYWRpbmcgdGhpcyBidWZmZXJcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRCdWZmZXJBc3luYyhcclxuICAgICAgICBnbHRmUnVudGltZTogSUdMVEZSdW50aW1lLFxyXG4gICAgICAgIGlkOiBzdHJpbmcsXHJcbiAgICAgICAgb25TdWNjZXNzOiAoYnVmZmVyOiBBcnJheUJ1ZmZlclZpZXcpID0+IHZvaWQsXHJcbiAgICAgICAgb25FcnJvcjogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZCxcclxuICAgICAgICBvblByb2dyZXNzPzogKCkgPT4gdm9pZFxyXG4gICAgKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBhbiBvdmVycmlkZSBmb3IgbG9hZGluZyB0ZXh0dXJlIGJ1ZmZlcnNcclxuICAgICAqIFJldHVybiB0cnVlIHRvIHN0b3AgZnVydGhlciBleHRlbnNpb25zIGZyb20gbG9hZGluZyB0aGlzIHRleHR1cmUgZGF0YVxyXG4gICAgICogQHBhcmFtIGdsdGZSdW50aW1lXHJcbiAgICAgKiBAcGFyYW0gaWRcclxuICAgICAqIEBwYXJhbSBvblN1Y2Nlc3NcclxuICAgICAqIEBwYXJhbSBvbkVycm9yXHJcbiAgICAgKiBAcmV0dXJucyB0cnVlIHRvIHN0b3AgZnVydGhlciBleHRlbnNpb25zIGZyb20gbG9hZGluZyB0aGlzIHRleHR1cmUgZGF0YVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZFRleHR1cmVCdWZmZXJBc3luYyhnbHRmUnVudGltZTogSUdMVEZSdW50aW1lLCBpZDogc3RyaW5nLCBvblN1Y2Nlc3M6IChidWZmZXI6IEFycmF5QnVmZmVyVmlldykgPT4gdm9pZCwgb25FcnJvcjogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgYW4gb3ZlcnJpZGUgZm9yIGNyZWF0aW5nIHRleHR1cmVzXHJcbiAgICAgKiBSZXR1cm4gdHJ1ZSB0byBzdG9wIGZ1cnRoZXIgZXh0ZW5zaW9ucyBmcm9tIGxvYWRpbmcgdGhpcyB0ZXh0dXJlXHJcbiAgICAgKiBAcGFyYW0gZ2x0ZlJ1bnRpbWVcclxuICAgICAqIEBwYXJhbSBpZFxyXG4gICAgICogQHBhcmFtIGJ1ZmZlclxyXG4gICAgICogQHBhcmFtIG9uU3VjY2Vzc1xyXG4gICAgICogQHBhcmFtIG9uRXJyb3JcclxuICAgICAqIEByZXR1cm5zIHRydWUgdG8gc3RvcCBmdXJ0aGVyIGV4dGVuc2lvbnMgZnJvbSBsb2FkaW5nIHRoaXMgdGV4dHVyZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY3JlYXRlVGV4dHVyZUFzeW5jKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsIGlkOiBzdHJpbmcsIGJ1ZmZlcjogQXJyYXlCdWZmZXJWaWV3LCBvblN1Y2Nlc3M6ICh0ZXh0dXJlOiBUZXh0dXJlKSA9PiB2b2lkLCBvbkVycm9yOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBhbiBvdmVycmlkZSBmb3IgbG9hZGluZyBzaGFkZXIgc3RyaW5nc1xyXG4gICAgICogUmV0dXJuIHRydWUgdG8gc3RvcCBmdXJ0aGVyIGV4dGVuc2lvbnMgZnJvbSBsb2FkaW5nIHRoaXMgc2hhZGVyIGRhdGFcclxuICAgICAqIEBwYXJhbSBnbHRmUnVudGltZVxyXG4gICAgICogQHBhcmFtIGlkXHJcbiAgICAgKiBAcGFyYW0gb25TdWNjZXNzXHJcbiAgICAgKiBAcGFyYW0gb25FcnJvclxyXG4gICAgICogQHJldHVybnMgdHJ1ZSB0byBzdG9wIGZ1cnRoZXIgZXh0ZW5zaW9ucyBmcm9tIGxvYWRpbmcgdGhpcyBzaGFkZXIgZGF0YVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZFNoYWRlclN0cmluZ0FzeW5jKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsIGlkOiBzdHJpbmcsIG9uU3VjY2VzczogKHNoYWRlclN0cmluZzogc3RyaW5nKSA9PiB2b2lkLCBvbkVycm9yOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBhbiBvdmVycmlkZSBmb3IgbG9hZGluZyBtYXRlcmlhbHNcclxuICAgICAqIFJldHVybiB0cnVlIHRvIHN0b3AgZnVydGhlciBleHRlbnNpb25zIGZyb20gbG9hZGluZyB0aGlzIG1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gZ2x0ZlJ1bnRpbWVcclxuICAgICAqIEBwYXJhbSBpZFxyXG4gICAgICogQHBhcmFtIG9uU3VjY2Vzc1xyXG4gICAgICogQHBhcmFtIG9uRXJyb3JcclxuICAgICAqIEByZXR1cm5zIHRydWUgdG8gc3RvcCBmdXJ0aGVyIGV4dGVuc2lvbnMgZnJvbSBsb2FkaW5nIHRoaXMgbWF0ZXJpYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRNYXRlcmlhbEFzeW5jKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsIGlkOiBzdHJpbmcsIG9uU3VjY2VzczogKG1hdGVyaWFsOiBNYXRlcmlhbCkgPT4gdm9pZCwgb25FcnJvcjogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICAvLyAtLS0tLS0tLS1cclxuICAgIC8vIFV0aWxpdGllc1xyXG4gICAgLy8gLS0tLS0tLS0tXHJcblxyXG4gICAgcHVibGljIHN0YXRpYyBMb2FkUnVudGltZUFzeW5jKFxyXG4gICAgICAgIHNjZW5lOiBTY2VuZSxcclxuICAgICAgICBkYXRhOiBJR0xURkxvYWRlckRhdGEsXHJcbiAgICAgICAgcm9vdFVybDogc3RyaW5nLFxyXG4gICAgICAgIG9uU3VjY2Vzcz86IChnbHRmUnVudGltZTogSUdMVEZSdW50aW1lKSA9PiB2b2lkLFxyXG4gICAgICAgIG9uRXJyb3I/OiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkXHJcbiAgICApOiB2b2lkIHtcclxuICAgICAgICBHTFRGTG9hZGVyRXh0ZW5zaW9uLl9BcHBseUV4dGVuc2lvbnMoXHJcbiAgICAgICAgICAgIChsb2FkZXJFeHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBsb2FkZXJFeHRlbnNpb24ubG9hZFJ1bnRpbWVBc3luYyhzY2VuZSwgZGF0YSwgcm9vdFVybCwgb25TdWNjZXNzLCBvbkVycm9yKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFvblN1Y2Nlc3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBvblN1Y2Nlc3MoR0xURkxvYWRlckJhc2UuQ3JlYXRlUnVudGltZShkYXRhLmpzb24sIHNjZW5lLCByb290VXJsKSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHN0YXRpYyBMb2FkUnVudGltZUV4dGVuc2lvbnNBc3luYyhnbHRmUnVudGltZTogSUdMVEZSdW50aW1lLCBvblN1Y2Nlc3M6ICgpID0+IHZvaWQsIG9uRXJyb3I/OiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICAgICAgR0xURkxvYWRlckV4dGVuc2lvbi5fQXBwbHlFeHRlbnNpb25zKFxyXG4gICAgICAgICAgICAobG9hZGVyRXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbG9hZGVyRXh0ZW5zaW9uLmxvYWRSdW50aW1lRXh0ZW5zaW9uc0FzeW5jKGdsdGZSdW50aW1lLCBvblN1Y2Nlc3MsIG9uRXJyb3IpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBvblN1Y2Nlc3MoKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhdGljIExvYWRCdWZmZXJBc3luYyhcclxuICAgICAgICBnbHRmUnVudGltZTogSUdMVEZSdW50aW1lLFxyXG4gICAgICAgIGlkOiBzdHJpbmcsXHJcbiAgICAgICAgb25TdWNjZXNzOiAoYnVmZmVyVmlldzogQXJyYXlCdWZmZXJWaWV3KSA9PiB2b2lkLFxyXG4gICAgICAgIG9uRXJyb3I6IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQsXHJcbiAgICAgICAgb25Qcm9ncmVzcz86ICgpID0+IHZvaWRcclxuICAgICk6IHZvaWQge1xyXG4gICAgICAgIEdMVEZMb2FkZXJFeHRlbnNpb24uX0FwcGx5RXh0ZW5zaW9ucyhcclxuICAgICAgICAgICAgKGxvYWRlckV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGxvYWRlckV4dGVuc2lvbi5sb2FkQnVmZmVyQXN5bmMoZ2x0ZlJ1bnRpbWUsIGlkLCBvblN1Y2Nlc3MsIG9uRXJyb3IsIG9uUHJvZ3Jlc3MpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBHTFRGTG9hZGVyQmFzZS5Mb2FkQnVmZmVyQXN5bmMoZ2x0ZlJ1bnRpbWUsIGlkLCBvblN1Y2Nlc3MsIG9uRXJyb3IsIG9uUHJvZ3Jlc3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhdGljIExvYWRUZXh0dXJlQXN5bmMoZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSwgaWQ6IHN0cmluZywgb25TdWNjZXNzOiAodGV4dHVyZTogVGV4dHVyZSkgPT4gdm9pZCwgb25FcnJvcjogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZCk6IHZvaWQge1xyXG4gICAgICAgIEdMVEZMb2FkZXJFeHRlbnNpb24uX0xvYWRUZXh0dXJlQnVmZmVyQXN5bmMoXHJcbiAgICAgICAgICAgIGdsdGZSdW50aW1lLFxyXG4gICAgICAgICAgICBpZCxcclxuICAgICAgICAgICAgKGJ1ZmZlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGJ1ZmZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgIEdMVEZMb2FkZXJFeHRlbnNpb24uX0NyZWF0ZVRleHR1cmVBc3luYyhnbHRmUnVudGltZSwgaWQsIGJ1ZmZlciwgb25TdWNjZXNzLCBvbkVycm9yKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgb25FcnJvclxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHN0YXRpYyBMb2FkU2hhZGVyU3RyaW5nQXN5bmMoZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSwgaWQ6IHN0cmluZywgb25TdWNjZXNzOiAoc2hhZGVyRGF0YTogc3RyaW5nIHwgQXJyYXlCdWZmZXIpID0+IHZvaWQsIG9uRXJyb3I6IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQpOiB2b2lkIHtcclxuICAgICAgICBHTFRGTG9hZGVyRXh0ZW5zaW9uLl9BcHBseUV4dGVuc2lvbnMoXHJcbiAgICAgICAgICAgIChsb2FkZXJFeHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBsb2FkZXJFeHRlbnNpb24ubG9hZFNoYWRlclN0cmluZ0FzeW5jKGdsdGZSdW50aW1lLCBpZCwgb25TdWNjZXNzLCBvbkVycm9yKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgR0xURkxvYWRlckJhc2UuTG9hZFNoYWRlclN0cmluZ0FzeW5jKGdsdGZSdW50aW1lLCBpZCwgb25TdWNjZXNzLCBvbkVycm9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHN0YXRpYyBMb2FkTWF0ZXJpYWxBc3luYyhnbHRmUnVudGltZTogSUdMVEZSdW50aW1lLCBpZDogc3RyaW5nLCBvblN1Y2Nlc3M6IChtYXRlcmlhbDogTWF0ZXJpYWwpID0+IHZvaWQsIG9uRXJyb3I6IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQpOiB2b2lkIHtcclxuICAgICAgICBHTFRGTG9hZGVyRXh0ZW5zaW9uLl9BcHBseUV4dGVuc2lvbnMoXHJcbiAgICAgICAgICAgIChsb2FkZXJFeHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBsb2FkZXJFeHRlbnNpb24ubG9hZE1hdGVyaWFsQXN5bmMoZ2x0ZlJ1bnRpbWUsIGlkLCBvblN1Y2Nlc3MsIG9uRXJyb3IpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBHTFRGTG9hZGVyQmFzZS5Mb2FkTWF0ZXJpYWxBc3luYyhnbHRmUnVudGltZSwgaWQsIG9uU3VjY2Vzcywgb25FcnJvcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIF9Mb2FkVGV4dHVyZUJ1ZmZlckFzeW5jKFxyXG4gICAgICAgIGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsXHJcbiAgICAgICAgaWQ6IHN0cmluZyxcclxuICAgICAgICBvblN1Y2Nlc3M6IChidWZmZXI6IE51bGxhYmxlPEFycmF5QnVmZmVyVmlldz4pID0+IHZvaWQsXHJcbiAgICAgICAgb25FcnJvcjogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZFxyXG4gICAgKTogdm9pZCB7XHJcbiAgICAgICAgR0xURkxvYWRlckV4dGVuc2lvbi5fQXBwbHlFeHRlbnNpb25zKFxyXG4gICAgICAgICAgICAobG9hZGVyRXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbG9hZGVyRXh0ZW5zaW9uLmxvYWRUZXh0dXJlQnVmZmVyQXN5bmMoZ2x0ZlJ1bnRpbWUsIGlkLCBvblN1Y2Nlc3MsIG9uRXJyb3IpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBHTFRGTG9hZGVyQmFzZS5Mb2FkVGV4dHVyZUJ1ZmZlckFzeW5jKGdsdGZSdW50aW1lLCBpZCwgb25TdWNjZXNzLCBvbkVycm9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX0NyZWF0ZVRleHR1cmVBc3luYyhcclxuICAgICAgICBnbHRmUnVudGltZTogSUdMVEZSdW50aW1lLFxyXG4gICAgICAgIGlkOiBzdHJpbmcsXHJcbiAgICAgICAgYnVmZmVyOiBBcnJheUJ1ZmZlclZpZXcsXHJcbiAgICAgICAgb25TdWNjZXNzOiAodGV4dHVyZTogVGV4dHVyZSkgPT4gdm9pZCxcclxuICAgICAgICBvbkVycm9yOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkXHJcbiAgICApOiB2b2lkIHtcclxuICAgICAgICBHTFRGTG9hZGVyRXh0ZW5zaW9uLl9BcHBseUV4dGVuc2lvbnMoXHJcbiAgICAgICAgICAgIChsb2FkZXJFeHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBsb2FkZXJFeHRlbnNpb24uY3JlYXRlVGV4dHVyZUFzeW5jKGdsdGZSdW50aW1lLCBpZCwgYnVmZmVyLCBvblN1Y2Nlc3MsIG9uRXJyb3IpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBHTFRGTG9hZGVyQmFzZS5DcmVhdGVUZXh0dXJlQXN5bmMoZ2x0ZlJ1bnRpbWUsIGlkLCBidWZmZXIsIG9uU3VjY2Vzcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIF9BcHBseUV4dGVuc2lvbnMoZnVuYzogKGxvYWRlckV4dGVuc2lvbjogR0xURkxvYWRlckV4dGVuc2lvbikgPT4gYm9vbGVhbiwgZGVmYXVsdEZ1bmM6ICgpID0+IHZvaWQpOiB2b2lkIHtcclxuICAgICAgICBmb3IgKGNvbnN0IGV4dGVuc2lvbk5hbWUgaW4gR0xURkxvYWRlci5FeHRlbnNpb25zKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGxvYWRlckV4dGVuc2lvbiA9IEdMVEZMb2FkZXIuRXh0ZW5zaW9uc1tleHRlbnNpb25OYW1lXTtcclxuICAgICAgICAgICAgaWYgKGZ1bmMobG9hZGVyRXh0ZW5zaW9uKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBkZWZhdWx0RnVuYygpO1xyXG4gICAgfVxyXG59XHJcblxyXG5HTFRGRmlsZUxvYWRlci5fQ3JlYXRlR0xURjFMb2FkZXIgPSAoKSA9PiBuZXcgR0xURkxvYWRlcigpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IEFzc2V0Q29udGFpbmVyIH0gZnJvbSBcImNvcmUvYXNzZXRDb250YWluZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBCb25lIH0gZnJvbSBcImNvcmUvQm9uZXMvYm9uZVwiO1xyXG5pbXBvcnQgdHlwZSB7IFNrZWxldG9uIH0gZnJvbSBcImNvcmUvQm9uZXMvc2tlbGV0b25cIjtcclxuaW1wb3J0IHR5cGUgeyBUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL3RleHR1cmVcIjtcclxuaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSBcImNvcmUvbm9kZVwiO1xyXG5pbXBvcnQgdHlwZSB7IFNjZW5lIH0gZnJvbSBcImNvcmUvc2NlbmVcIjtcclxuaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcblxyXG4vKipcclxuICogRW51bXNcclxuICogQGludGVybmFsXHJcbiAqL1xyXG5leHBvcnQgZW51bSBFQ29tcG9uZW50VHlwZSB7XHJcbiAgICBCWVRFID0gNTEyMCxcclxuICAgIFVOU0lHTkVEX0JZVEUgPSA1MTIxLFxyXG4gICAgU0hPUlQgPSA1MTIyLFxyXG4gICAgVU5TSUdORURfU0hPUlQgPSA1MTIzLFxyXG4gICAgRkxPQVQgPSA1MTI2LFxyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBlbnVtIEVTaGFkZXJUeXBlIHtcclxuICAgIEZSQUdNRU5UID0gMzU2MzIsXHJcbiAgICBWRVJURVggPSAzNTYzMyxcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgZW51bSBFUGFyYW1ldGVyVHlwZSB7XHJcbiAgICBCWVRFID0gNTEyMCxcclxuICAgIFVOU0lHTkVEX0JZVEUgPSA1MTIxLFxyXG4gICAgU0hPUlQgPSA1MTIyLFxyXG4gICAgVU5TSUdORURfU0hPUlQgPSA1MTIzLFxyXG4gICAgSU5UID0gNTEyNCxcclxuICAgIFVOU0lHTkVEX0lOVCA9IDUxMjUsXHJcbiAgICBGTE9BVCA9IDUxMjYsXHJcbiAgICBGTE9BVF9WRUMyID0gMzU2NjQsXHJcbiAgICBGTE9BVF9WRUMzID0gMzU2NjUsXHJcbiAgICBGTE9BVF9WRUM0ID0gMzU2NjYsXHJcbiAgICBJTlRfVkVDMiA9IDM1NjY3LFxyXG4gICAgSU5UX1ZFQzMgPSAzNTY2OCxcclxuICAgIElOVF9WRUM0ID0gMzU2NjksXHJcbiAgICBCT09MID0gMzU2NzAsXHJcbiAgICBCT09MX1ZFQzIgPSAzNTY3MSxcclxuICAgIEJPT0xfVkVDMyA9IDM1NjcyLFxyXG4gICAgQk9PTF9WRUM0ID0gMzU2NzMsXHJcbiAgICBGTE9BVF9NQVQyID0gMzU2NzQsXHJcbiAgICBGTE9BVF9NQVQzID0gMzU2NzUsXHJcbiAgICBGTE9BVF9NQVQ0ID0gMzU2NzYsXHJcbiAgICBTQU1QTEVSXzJEID0gMzU2NzgsXHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGVudW0gRVRleHR1cmVXcmFwTW9kZSB7XHJcbiAgICBDTEFNUF9UT19FREdFID0gMzMwNzEsXHJcbiAgICBNSVJST1JFRF9SRVBFQVQgPSAzMzY0OCxcclxuICAgIFJFUEVBVCA9IDEwNDk3LFxyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBlbnVtIEVUZXh0dXJlRmlsdGVyVHlwZSB7XHJcbiAgICBORUFSRVNUID0gOTcyOCxcclxuICAgIExJTkVBUiA9IDk3MjgsXHJcbiAgICBORUFSRVNUX01JUE1BUF9ORUFSRVNUID0gOTk4NCxcclxuICAgIExJTkVBUl9NSVBNQVBfTkVBUkVTVCA9IDk5ODUsXHJcbiAgICBORUFSRVNUX01JUE1BUF9MSU5FQVIgPSA5OTg2LFxyXG4gICAgTElORUFSX01JUE1BUF9MSU5FQVIgPSA5OTg3LFxyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBlbnVtIEVUZXh0dXJlRm9ybWF0IHtcclxuICAgIEFMUEhBID0gNjQwNixcclxuICAgIFJHQiA9IDY0MDcsXHJcbiAgICBSR0JBID0gNjQwOCxcclxuICAgIExVTUlOQU5DRSA9IDY0MDksXHJcbiAgICBMVU1JTkFOQ0VfQUxQSEEgPSA2NDEwLFxyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBlbnVtIEVDdWxsaW5nVHlwZSB7XHJcbiAgICBGUk9OVCA9IDEwMjgsXHJcbiAgICBCQUNLID0gMTAyOSxcclxuICAgIEZST05UX0FORF9CQUNLID0gMTAzMixcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgZW51bSBFQmxlbmRpbmdGdW5jdGlvbiB7XHJcbiAgICBaRVJPID0gMCxcclxuICAgIE9ORSA9IDEsXHJcbiAgICBTUkNfQ09MT1IgPSA3NjgsXHJcbiAgICBPTkVfTUlOVVNfU1JDX0NPTE9SID0gNzY5LFxyXG4gICAgRFNUX0NPTE9SID0gNzc0LFxyXG4gICAgT05FX01JTlVTX0RTVF9DT0xPUiA9IDc3NSxcclxuICAgIFNSQ19BTFBIQSA9IDc3MCxcclxuICAgIE9ORV9NSU5VU19TUkNfQUxQSEEgPSA3NzEsXHJcbiAgICBEU1RfQUxQSEEgPSA3NzIsXHJcbiAgICBPTkVfTUlOVVNfRFNUX0FMUEhBID0gNzczLFxyXG4gICAgQ09OU1RBTlRfQ09MT1IgPSAzMjc2OSxcclxuICAgIE9ORV9NSU5VU19DT05TVEFOVF9DT0xPUiA9IDMyNzcwLFxyXG4gICAgQ09OU1RBTlRfQUxQSEEgPSAzMjc3MSxcclxuICAgIE9ORV9NSU5VU19DT05TVEFOVF9BTFBIQSA9IDMyNzcyLFxyXG4gICAgU1JDX0FMUEhBX1NBVFVSQVRFID0gNzc2LFxyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZQcm9wZXJ0eSB7XHJcbiAgICBleHRlbnNpb25zPzogeyBba2V5OiBzdHJpbmddOiBhbnkgfTtcclxuICAgIGV4dHJhcz86IE9iamVjdDtcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGQ2hpbGRSb290UHJvcGVydHkgZXh0ZW5kcyBJR0xURlByb3BlcnR5IHtcclxuICAgIG5hbWU/OiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGludGVyZmFjZSBJR0xURkFjY2Vzc29yIGV4dGVuZHMgSUdMVEZDaGlsZFJvb3RQcm9wZXJ0eSB7XHJcbiAgICBidWZmZXJWaWV3OiBzdHJpbmc7XHJcbiAgICBieXRlT2Zmc2V0OiBudW1iZXI7XHJcbiAgICBieXRlU3RyaWRlOiBudW1iZXI7XHJcbiAgICBjb3VudDogbnVtYmVyO1xyXG4gICAgdHlwZTogc3RyaW5nO1xyXG4gICAgY29tcG9uZW50VHlwZTogRUNvbXBvbmVudFR5cGU7XHJcblxyXG4gICAgbWF4PzogbnVtYmVyW107XHJcbiAgICBtaW4/OiBudW1iZXJbXTtcclxuICAgIG5hbWU/OiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGludGVyZmFjZSBJR0xURkJ1ZmZlclZpZXcgZXh0ZW5kcyBJR0xURkNoaWxkUm9vdFByb3BlcnR5IHtcclxuICAgIGJ1ZmZlcjogc3RyaW5nO1xyXG4gICAgYnl0ZU9mZnNldDogbnVtYmVyO1xyXG4gICAgYnl0ZUxlbmd0aDogbnVtYmVyO1xyXG4gICAgYnl0ZVN0cmlkZTogbnVtYmVyO1xyXG5cclxuICAgIHRhcmdldD86IG51bWJlcjtcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGQnVmZmVyIGV4dGVuZHMgSUdMVEZDaGlsZFJvb3RQcm9wZXJ0eSB7XHJcbiAgICB1cmk6IHN0cmluZztcclxuXHJcbiAgICBieXRlTGVuZ3RoPzogbnVtYmVyO1xyXG4gICAgdHlwZT86IHN0cmluZztcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGU2hhZGVyIGV4dGVuZHMgSUdMVEZDaGlsZFJvb3RQcm9wZXJ0eSB7XHJcbiAgICB1cmk6IHN0cmluZztcclxuICAgIHR5cGU6IEVTaGFkZXJUeXBlO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZQcm9ncmFtIGV4dGVuZHMgSUdMVEZDaGlsZFJvb3RQcm9wZXJ0eSB7XHJcbiAgICBhdHRyaWJ1dGVzOiBzdHJpbmdbXTtcclxuICAgIGZyYWdtZW50U2hhZGVyOiBzdHJpbmc7XHJcbiAgICB2ZXJ0ZXhTaGFkZXI6IHN0cmluZztcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGVGVjaG5pcXVlUGFyYW1ldGVyIHtcclxuICAgIHR5cGU6IG51bWJlcjtcclxuXHJcbiAgICBjb3VudD86IG51bWJlcjtcclxuICAgIHNlbWFudGljPzogc3RyaW5nO1xyXG4gICAgbm9kZT86IHN0cmluZztcclxuICAgIHZhbHVlPzogbnVtYmVyIHwgYm9vbGVhbiB8IHN0cmluZyB8IEFycmF5PGFueT47XHJcbiAgICBzb3VyY2U/OiBzdHJpbmc7XHJcblxyXG4gICAgYmFieWxvblZhbHVlPzogYW55O1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZUZWNobmlxdWVDb21tb25Qcm9maWxlIHtcclxuICAgIGxpZ2h0aW5nTW9kZWw6IHN0cmluZztcclxuICAgIHRleGNvb3JkQmluZGluZ3M6IE9iamVjdDtcclxuXHJcbiAgICBwYXJhbWV0ZXJzPzogQXJyYXk8YW55PjtcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGVGVjaG5pcXVlU3RhdGVzRnVuY3Rpb25zIHtcclxuICAgIGJsZW5kQ29sb3I/OiBudW1iZXJbXTtcclxuICAgIGJsZW5kRXF1YXRpb25TZXBhcmF0ZT86IG51bWJlcltdO1xyXG4gICAgYmxlbmRGdW5jU2VwYXJhdGU/OiBudW1iZXJbXTtcclxuICAgIGNvbG9yTWFzazogYm9vbGVhbltdO1xyXG4gICAgY3VsbEZhY2U6IG51bWJlcltdO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZUZWNobmlxdWVTdGF0ZXMge1xyXG4gICAgZW5hYmxlOiBudW1iZXJbXTtcclxuICAgIGZ1bmN0aW9uczogSUdMVEZUZWNobmlxdWVTdGF0ZXNGdW5jdGlvbnM7XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGludGVyZmFjZSBJR0xURlRlY2huaXF1ZSBleHRlbmRzIElHTFRGQ2hpbGRSb290UHJvcGVydHkge1xyXG4gICAgcGFyYW1ldGVyczogeyBba2V5OiBzdHJpbmddOiBJR0xURlRlY2huaXF1ZVBhcmFtZXRlciB9O1xyXG4gICAgcHJvZ3JhbTogc3RyaW5nO1xyXG5cclxuICAgIGF0dHJpYnV0ZXM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XHJcbiAgICB1bmlmb3JtczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfTtcclxuICAgIHN0YXRlczogSUdMVEZUZWNobmlxdWVTdGF0ZXM7XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGludGVyZmFjZSBJR0xURk1hdGVyaWFsIGV4dGVuZHMgSUdMVEZDaGlsZFJvb3RQcm9wZXJ0eSB7XHJcbiAgICB0ZWNobmlxdWU/OiBzdHJpbmc7XHJcbiAgICB2YWx1ZXM6IHN0cmluZ1tdO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZNZXNoUHJpbWl0aXZlIGV4dGVuZHMgSUdMVEZQcm9wZXJ0eSB7XHJcbiAgICBhdHRyaWJ1dGVzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xyXG4gICAgaW5kaWNlczogc3RyaW5nO1xyXG4gICAgbWF0ZXJpYWw6IHN0cmluZztcclxuXHJcbiAgICBtb2RlPzogbnVtYmVyO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZNZXNoIGV4dGVuZHMgSUdMVEZDaGlsZFJvb3RQcm9wZXJ0eSB7XHJcbiAgICBwcmltaXRpdmVzOiBJR0xURk1lc2hQcmltaXRpdmVbXTtcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGSW1hZ2UgZXh0ZW5kcyBJR0xURkNoaWxkUm9vdFByb3BlcnR5IHtcclxuICAgIHVyaTogc3RyaW5nO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZTYW1wbGVyIGV4dGVuZHMgSUdMVEZDaGlsZFJvb3RQcm9wZXJ0eSB7XHJcbiAgICBtYWdGaWx0ZXI/OiBudW1iZXI7XHJcbiAgICBtaW5GaWx0ZXI/OiBudW1iZXI7XHJcbiAgICB3cmFwUz86IG51bWJlcjtcclxuICAgIHdyYXBUPzogbnVtYmVyO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZUZXh0dXJlIGV4dGVuZHMgSUdMVEZDaGlsZFJvb3RQcm9wZXJ0eSB7XHJcbiAgICBzYW1wbGVyOiBzdHJpbmc7XHJcbiAgICBzb3VyY2U6IHN0cmluZztcclxuXHJcbiAgICBmb3JtYXQ/OiBFVGV4dHVyZUZvcm1hdDtcclxuICAgIGludGVybmFsRm9ybWF0PzogRVRleHR1cmVGb3JtYXQ7XHJcbiAgICB0YXJnZXQ/OiBudW1iZXI7XHJcbiAgICB0eXBlPzogbnVtYmVyO1xyXG5cclxuICAgIC8vIEJhYnlsb24uanMgdmFsdWVzIChvcHRpbWl6ZSlcclxuICAgIGJhYnlsb25UZXh0dXJlPzogVGV4dHVyZTtcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGQW1iaWVuTGlnaHQge1xyXG4gICAgY29sb3I/OiBudW1iZXJbXTtcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGRGlyZWN0aW9uYWxMaWdodCB7XHJcbiAgICBjb2xvcj86IG51bWJlcltdO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZQb2ludExpZ2h0IHtcclxuICAgIGNvbG9yPzogbnVtYmVyW107XHJcbiAgICBjb25zdGFudEF0dGVudWF0aW9uPzogbnVtYmVyO1xyXG4gICAgbGluZWFyQXR0ZW51YXRpb24/OiBudW1iZXI7XHJcbiAgICBxdWFkcmF0aWNBdHRlbnVhdGlvbj86IG51bWJlcjtcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGU3BvdExpZ2h0IHtcclxuICAgIGNvbG9yPzogbnVtYmVyW107XHJcbiAgICBjb25zdGFudEF0dGVudWF0aW9uPzogbnVtYmVyO1xyXG4gICAgZmFsbE9mQW5nbGU/OiBudW1iZXI7XHJcbiAgICBmYWxsT2ZmRXhwb25lbnQ/OiBudW1iZXI7XHJcbiAgICBsaW5lYXJBdHRlbnVhdGlvbj86IG51bWJlcjtcclxuICAgIHF1YWRyYXRpY0F0dGVudWF0aW9uPzogbnVtYmVyO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZMaWdodCBleHRlbmRzIElHTFRGQ2hpbGRSb290UHJvcGVydHkge1xyXG4gICAgdHlwZTogc3RyaW5nO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZDYW1lcmFPcnRob2dyYXBoaWMge1xyXG4gICAgeG1hZzogbnVtYmVyO1xyXG4gICAgeW1hZzogbnVtYmVyO1xyXG4gICAgemZhcjogbnVtYmVyO1xyXG4gICAgem5lYXI6IG51bWJlcjtcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGQ2FtZXJhUGVyc3BlY3RpdmUge1xyXG4gICAgYXNwZWN0UmF0aW86IG51bWJlcjtcclxuICAgIHlmb3Y6IG51bWJlcjtcclxuICAgIHpmYXI6IG51bWJlcjtcclxuICAgIHpuZWFyOiBudW1iZXI7XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGludGVyZmFjZSBJR0xURkNhbWVyYSBleHRlbmRzIElHTFRGQ2hpbGRSb290UHJvcGVydHkge1xyXG4gICAgdHlwZTogc3RyaW5nO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZBbmltYXRpb25DaGFubmVsVGFyZ2V0IHtcclxuICAgIGlkOiBzdHJpbmc7XHJcbiAgICBwYXRoOiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGludGVyZmFjZSBJR0xURkFuaW1hdGlvbkNoYW5uZWwge1xyXG4gICAgc2FtcGxlcjogc3RyaW5nO1xyXG4gICAgdGFyZ2V0OiBJR0xURkFuaW1hdGlvbkNoYW5uZWxUYXJnZXQ7XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGludGVyZmFjZSBJR0xURkFuaW1hdGlvblNhbXBsZXIge1xyXG4gICAgaW5wdXQ6IHN0cmluZztcclxuICAgIG91dHB1dDogc3RyaW5nO1xyXG5cclxuICAgIGludGVycG9sYXRpb24/OiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGludGVyZmFjZSBJR0xURkFuaW1hdGlvbiBleHRlbmRzIElHTFRGQ2hpbGRSb290UHJvcGVydHkge1xyXG4gICAgY2hhbm5lbHM/OiBJR0xURkFuaW1hdGlvbkNoYW5uZWxbXTtcclxuICAgIHBhcmFtZXRlcnM/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xyXG4gICAgc2FtcGxlcnM/OiB7IFtrZXk6IHN0cmluZ106IElHTFRGQW5pbWF0aW9uU2FtcGxlciB9O1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZOb2RlSW5zdGFuY2VTa2luIHtcclxuICAgIHNrZWxldG9uczogc3RyaW5nW107XHJcbiAgICBza2luOiBzdHJpbmc7XHJcbiAgICBtZXNoZXM6IHN0cmluZ1tdO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZTa2lucyBleHRlbmRzIElHTFRGQ2hpbGRSb290UHJvcGVydHkge1xyXG4gICAgYmluZFNoYXBlTWF0cml4OiBudW1iZXJbXTtcclxuICAgIGludmVyc2VCaW5kTWF0cmljZXM6IHN0cmluZztcclxuICAgIGpvaW50TmFtZXM6IHN0cmluZ1tdO1xyXG5cclxuICAgIGJhYnlsb25Ta2VsZXRvbj86IFNrZWxldG9uO1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZOb2RlIGV4dGVuZHMgSUdMVEZDaGlsZFJvb3RQcm9wZXJ0eSB7XHJcbiAgICBjYW1lcmE/OiBzdHJpbmc7XHJcbiAgICBjaGlsZHJlbjogc3RyaW5nW107XHJcbiAgICBza2luPzogc3RyaW5nO1xyXG4gICAgam9pbnROYW1lPzogc3RyaW5nO1xyXG4gICAgbGlnaHQ/OiBzdHJpbmc7XHJcbiAgICBtYXRyaXg6IG51bWJlcltdO1xyXG4gICAgbWVzaD86IHN0cmluZztcclxuICAgIG1lc2hlcz86IHN0cmluZ1tdO1xyXG4gICAgcm90YXRpb24/OiBudW1iZXJbXTtcclxuICAgIHNjYWxlPzogbnVtYmVyW107XHJcbiAgICB0cmFuc2xhdGlvbj86IG51bWJlcltdO1xyXG5cclxuICAgIC8vIEJhYnlsb24uanMgdmFsdWVzIChvcHRpbWl6ZSlcclxuICAgIGJhYnlsb25Ob2RlPzogTm9kZTtcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGU2NlbmUgZXh0ZW5kcyBJR0xURkNoaWxkUm9vdFByb3BlcnR5IHtcclxuICAgIG5vZGVzOiBzdHJpbmdbXTtcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGUnVudGltZSB7XHJcbiAgICBleHRlbnNpb25zOiB7IFtrZXk6IHN0cmluZ106IGFueSB9O1xyXG4gICAgYWNjZXNzb3JzOiB7IFtrZXk6IHN0cmluZ106IElHTFRGQWNjZXNzb3IgfTtcclxuICAgIGJ1ZmZlcnM6IHsgW2tleTogc3RyaW5nXTogSUdMVEZCdWZmZXIgfTtcclxuICAgIGJ1ZmZlclZpZXdzOiB7IFtrZXk6IHN0cmluZ106IElHTFRGQnVmZmVyVmlldyB9O1xyXG4gICAgbWVzaGVzOiB7IFtrZXk6IHN0cmluZ106IElHTFRGTWVzaCB9O1xyXG4gICAgbGlnaHRzOiB7IFtrZXk6IHN0cmluZ106IElHTFRGTGlnaHQgfTtcclxuICAgIGNhbWVyYXM6IHsgW2tleTogc3RyaW5nXTogSUdMVEZDYW1lcmEgfTtcclxuICAgIG5vZGVzOiB7IFtrZXk6IHN0cmluZ106IElHTFRGTm9kZSB9O1xyXG4gICAgaW1hZ2VzOiB7IFtrZXk6IHN0cmluZ106IElHTFRGSW1hZ2UgfTtcclxuICAgIHRleHR1cmVzOiB7IFtrZXk6IHN0cmluZ106IElHTFRGVGV4dHVyZSB9O1xyXG4gICAgc2hhZGVyczogeyBba2V5OiBzdHJpbmddOiBJR0xURlNoYWRlciB9O1xyXG4gICAgcHJvZ3JhbXM6IHsgW2tleTogc3RyaW5nXTogSUdMVEZQcm9ncmFtIH07XHJcbiAgICBzYW1wbGVyczogeyBba2V5OiBzdHJpbmddOiBJR0xURlNhbXBsZXIgfTtcclxuICAgIHRlY2huaXF1ZXM6IHsgW2tleTogc3RyaW5nXTogSUdMVEZUZWNobmlxdWUgfTtcclxuICAgIG1hdGVyaWFsczogeyBba2V5OiBzdHJpbmddOiBJR0xURk1hdGVyaWFsIH07XHJcbiAgICBhbmltYXRpb25zOiB7IFtrZXk6IHN0cmluZ106IElHTFRGQW5pbWF0aW9uIH07XHJcbiAgICBza2luczogeyBba2V5OiBzdHJpbmddOiBJR0xURlNraW5zIH07XHJcblxyXG4gICAgY3VycmVudFNjZW5lPzogT2JqZWN0O1xyXG4gICAgc2NlbmVzOiB7IFtrZXk6IHN0cmluZ106IElHTFRGU2NlbmUgfTsgLy8gdjEuMVxyXG5cclxuICAgIGV4dGVuc2lvbnNVc2VkOiBzdHJpbmdbXTtcclxuICAgIGV4dGVuc2lvbnNSZXF1aXJlZD86IHN0cmluZ1tdOyAvLyB2MS4xXHJcblxyXG4gICAgYnVmZmVyc0NvdW50OiBudW1iZXI7XHJcbiAgICBzaGFkZXJzY291bnQ6IG51bWJlcjtcclxuXHJcbiAgICBzY2VuZTogU2NlbmU7XHJcbiAgICByb290VXJsOiBzdHJpbmc7XHJcblxyXG4gICAgbG9hZGVkQnVmZmVyQ291bnQ6IG51bWJlcjtcclxuICAgIGxvYWRlZEJ1ZmZlclZpZXdzOiB7IFtuYW1lOiBzdHJpbmddOiBBcnJheUJ1ZmZlclZpZXcgfTtcclxuXHJcbiAgICBsb2FkZWRTaGFkZXJDb3VudDogbnVtYmVyO1xyXG5cclxuICAgIGltcG9ydE9ubHlNZXNoZXM6IGJvb2xlYW47XHJcbiAgICBpbXBvcnRNZXNoZXNOYW1lcz86IHN0cmluZ1tdO1xyXG5cclxuICAgIGR1bW15Tm9kZXM6IE5vZGVbXTtcclxuXHJcbiAgICBhc3NldENvbnRhaW5lcjogTnVsbGFibGU8QXNzZXRDb250YWluZXI+O1xyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSU5vZGVUb1Jvb3Qge1xyXG4gICAgYm9uZTogQm9uZTtcclxuICAgIG5vZGU6IElHTFRGTm9kZTtcclxuICAgIGlkOiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGludGVyZmFjZSBJSm9pbnROb2RlIHtcclxuICAgIG5vZGU6IElHTFRGTm9kZTtcclxuICAgIGlkOiBzdHJpbmc7XHJcbn1cclxuIiwiaW1wb3J0IHR5cGUgeyBJR0xURlRlY2huaXF1ZVBhcmFtZXRlciwgSUdMVEZBY2Nlc3NvciwgSUdMVEZSdW50aW1lLCBJR0xURkJ1ZmZlclZpZXcgfSBmcm9tIFwiLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgeyBFUGFyYW1ldGVyVHlwZSwgRVRleHR1cmVXcmFwTW9kZSwgRVRleHR1cmVGaWx0ZXJUeXBlLCBFQ29tcG9uZW50VHlwZSB9IGZyb20gXCIuL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgVmVjdG9yMiwgVmVjdG9yMywgVmVjdG9yNCwgTWF0cml4IH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC52ZWN0b3JcIjtcclxuaW1wb3J0IHsgQ29sb3I0IH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC5jb2xvclwiO1xyXG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvZWZmZWN0XCI7XHJcbmltcG9ydCB7IFNoYWRlck1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL3NoYWRlck1hdGVyaWFsXCI7XHJcbmltcG9ydCB7IFRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvdGV4dHVyZVwiO1xyXG5pbXBvcnQgdHlwZSB7IE5vZGUgfSBmcm9tIFwiY29yZS9ub2RlXCI7XHJcbmltcG9ydCB0eXBlIHsgU2NlbmUgfSBmcm9tIFwiY29yZS9zY2VuZVwiO1xyXG5cclxuLyoqXHJcbiAqIFV0aWxzIGZ1bmN0aW9ucyBmb3IgR0xURlxyXG4gKiBAaW50ZXJuYWxcclxuICogQGRlcHJlY2F0ZWRcclxuICovXHJcbmV4cG9ydCBjbGFzcyBHTFRGVXRpbHMge1xyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHRoZSBnaXZlbiBcInBhcmFtZXRlclwiIG1hdHJpeFxyXG4gICAgICogQHBhcmFtIHNjZW5lIHRoZSBTY2VuZSBvYmplY3RcclxuICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBub2RlIHdoZXJlIHRvIHBpY2sgdGhlIG1hdHJpeFxyXG4gICAgICogQHBhcmFtIHBhcmFtZXRlciB0aGUgR0xURiB0ZWNobmlxdWUgcGFyYW1ldGVyXHJcbiAgICAgKiBAcGFyYW0gdW5pZm9ybU5hbWUgdGhlIG5hbWUgb2YgdGhlIHNoYWRlcidzIHVuaWZvcm1cclxuICAgICAqIEBwYXJhbSBzaGFkZXJNYXRlcmlhbCB0aGUgc2hhZGVyIG1hdGVyaWFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgU2V0TWF0cml4KHNjZW5lOiBTY2VuZSwgc291cmNlOiBOb2RlLCBwYXJhbWV0ZXI6IElHTFRGVGVjaG5pcXVlUGFyYW1ldGVyLCB1bmlmb3JtTmFtZTogc3RyaW5nLCBzaGFkZXJNYXRlcmlhbDogU2hhZGVyTWF0ZXJpYWwgfCBFZmZlY3QpOiB2b2lkIHtcclxuICAgICAgICBsZXQgbWF0OiBOdWxsYWJsZTxNYXRyaXg+ID0gbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKHBhcmFtZXRlci5zZW1hbnRpYyA9PT0gXCJNT0RFTFwiKSB7XHJcbiAgICAgICAgICAgIG1hdCA9IHNvdXJjZS5nZXRXb3JsZE1hdHJpeCgpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAocGFyYW1ldGVyLnNlbWFudGljID09PSBcIlBST0pFQ1RJT05cIikge1xyXG4gICAgICAgICAgICBtYXQgPSBzY2VuZS5nZXRQcm9qZWN0aW9uTWF0cml4KCk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChwYXJhbWV0ZXIuc2VtYW50aWMgPT09IFwiVklFV1wiKSB7XHJcbiAgICAgICAgICAgIG1hdCA9IHNjZW5lLmdldFZpZXdNYXRyaXgoKTtcclxuICAgICAgICB9IGVsc2UgaWYgKHBhcmFtZXRlci5zZW1hbnRpYyA9PT0gXCJNT0RFTFZJRVdJTlZFUlNFVFJBTlNQT1NFXCIpIHtcclxuICAgICAgICAgICAgbWF0ID0gTWF0cml4LlRyYW5zcG9zZShzb3VyY2UuZ2V0V29ybGRNYXRyaXgoKS5tdWx0aXBseShzY2VuZS5nZXRWaWV3TWF0cml4KCkpLmludmVydCgpKTtcclxuICAgICAgICB9IGVsc2UgaWYgKHBhcmFtZXRlci5zZW1hbnRpYyA9PT0gXCJNT0RFTFZJRVdcIikge1xyXG4gICAgICAgICAgICBtYXQgPSBzb3VyY2UuZ2V0V29ybGRNYXRyaXgoKS5tdWx0aXBseShzY2VuZS5nZXRWaWV3TWF0cml4KCkpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAocGFyYW1ldGVyLnNlbWFudGljID09PSBcIk1PREVMVklFV1BST0pFQ1RJT05cIikge1xyXG4gICAgICAgICAgICBtYXQgPSBzb3VyY2UuZ2V0V29ybGRNYXRyaXgoKS5tdWx0aXBseShzY2VuZS5nZXRUcmFuc2Zvcm1NYXRyaXgoKSk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChwYXJhbWV0ZXIuc2VtYW50aWMgPT09IFwiTU9ERUxJTlZFUlNFXCIpIHtcclxuICAgICAgICAgICAgbWF0ID0gc291cmNlLmdldFdvcmxkTWF0cml4KCkuaW52ZXJ0KCk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChwYXJhbWV0ZXIuc2VtYW50aWMgPT09IFwiVklFV0lOVkVSU0VcIikge1xyXG4gICAgICAgICAgICBtYXQgPSBzY2VuZS5nZXRWaWV3TWF0cml4KCkuaW52ZXJ0KCk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChwYXJhbWV0ZXIuc2VtYW50aWMgPT09IFwiUFJPSkVDVElPTklOVkVSU0VcIikge1xyXG4gICAgICAgICAgICBtYXQgPSBzY2VuZS5nZXRQcm9qZWN0aW9uTWF0cml4KCkuaW52ZXJ0KCk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChwYXJhbWV0ZXIuc2VtYW50aWMgPT09IFwiTU9ERUxWSUVXSU5WRVJTRVwiKSB7XHJcbiAgICAgICAgICAgIG1hdCA9IHNvdXJjZS5nZXRXb3JsZE1hdHJpeCgpLm11bHRpcGx5KHNjZW5lLmdldFZpZXdNYXRyaXgoKSkuaW52ZXJ0KCk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChwYXJhbWV0ZXIuc2VtYW50aWMgPT09IFwiTU9ERUxWSUVXUFJPSkVDVElPTklOVkVSU0VcIikge1xyXG4gICAgICAgICAgICBtYXQgPSBzb3VyY2UuZ2V0V29ybGRNYXRyaXgoKS5tdWx0aXBseShzY2VuZS5nZXRUcmFuc2Zvcm1NYXRyaXgoKSkuaW52ZXJ0KCk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChwYXJhbWV0ZXIuc2VtYW50aWMgPT09IFwiTU9ERUxJTlZFUlNFVFJBTlNQT1NFXCIpIHtcclxuICAgICAgICAgICAgbWF0ID0gTWF0cml4LlRyYW5zcG9zZShzb3VyY2UuZ2V0V29ybGRNYXRyaXgoKS5pbnZlcnQoKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAobWF0KSB7XHJcbiAgICAgICAgICAgIHN3aXRjaCAocGFyYW1ldGVyLnR5cGUpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgRVBhcmFtZXRlclR5cGUuRkxPQVRfTUFUMjpcclxuICAgICAgICAgICAgICAgICAgICBzaGFkZXJNYXRlcmlhbC5zZXRNYXRyaXgyeDIodW5pZm9ybU5hbWUsIE1hdHJpeC5HZXRBc01hdHJpeDJ4MihtYXQpKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgRVBhcmFtZXRlclR5cGUuRkxPQVRfTUFUMzpcclxuICAgICAgICAgICAgICAgICAgICBzaGFkZXJNYXRlcmlhbC5zZXRNYXRyaXgzeDModW5pZm9ybU5hbWUsIE1hdHJpeC5HZXRBc01hdHJpeDN4MyhtYXQpKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgRVBhcmFtZXRlclR5cGUuRkxPQVRfTUFUNDpcclxuICAgICAgICAgICAgICAgICAgICBzaGFkZXJNYXRlcmlhbC5zZXRNYXRyaXgodW5pZm9ybU5hbWUsIG1hdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgZ2l2ZW4gXCJwYXJhbWV0ZXJcIiBtYXRyaXhcclxuICAgICAqIEBwYXJhbSBzaGFkZXJNYXRlcmlhbCB0aGUgc2hhZGVyIG1hdGVyaWFsXHJcbiAgICAgKiBAcGFyYW0gdW5pZm9ybSB0aGUgbmFtZSBvZiB0aGUgc2hhZGVyJ3MgdW5pZm9ybVxyXG4gICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgdW5pZm9ybVxyXG4gICAgICogQHBhcmFtIHR5cGUgdGhlIHVuaWZvcm0ncyB0eXBlIChFUGFyYW1ldGVyVHlwZSBGTE9BVCwgVkVDMiwgVkVDMyBvciBWRUM0KVxyXG4gICAgICogQHJldHVybnMgdHJ1ZSBpZiBzZXQsIGVsc2UgZmFsc2VcclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBTZXRVbmlmb3JtKHNoYWRlck1hdGVyaWFsOiBTaGFkZXJNYXRlcmlhbCB8IEVmZmVjdCwgdW5pZm9ybTogc3RyaW5nLCB2YWx1ZTogYW55LCB0eXBlOiBudW1iZXIpOiBib29sZWFuIHtcclxuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcclxuICAgICAgICAgICAgY2FzZSBFUGFyYW1ldGVyVHlwZS5GTE9BVDpcclxuICAgICAgICAgICAgICAgIHNoYWRlck1hdGVyaWFsLnNldEZsb2F0KHVuaWZvcm0sIHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICBjYXNlIEVQYXJhbWV0ZXJUeXBlLkZMT0FUX1ZFQzI6XHJcbiAgICAgICAgICAgICAgICBzaGFkZXJNYXRlcmlhbC5zZXRWZWN0b3IyKHVuaWZvcm0sIFZlY3RvcjIuRnJvbUFycmF5KHZhbHVlKSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgY2FzZSBFUGFyYW1ldGVyVHlwZS5GTE9BVF9WRUMzOlxyXG4gICAgICAgICAgICAgICAgc2hhZGVyTWF0ZXJpYWwuc2V0VmVjdG9yMyh1bmlmb3JtLCBWZWN0b3IzLkZyb21BcnJheSh2YWx1ZSkpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIGNhc2UgRVBhcmFtZXRlclR5cGUuRkxPQVRfVkVDNDpcclxuICAgICAgICAgICAgICAgIHNoYWRlck1hdGVyaWFsLnNldFZlY3RvcjQodW5pZm9ybSwgVmVjdG9yNC5Gcm9tQXJyYXkodmFsdWUpKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIHdyYXAgbW9kZSBvZiB0aGUgdGV4dHVyZVxyXG4gICAgICogQHBhcmFtIG1vZGUgdGhlIG1vZGUgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHRoZSB3cmFwIG1vZGUgKFRFWFRVUkVfV1JBUF9BRERSRVNTTU9ERSwgTUlSUk9SX0FERFJFU1NNT0RFIG9yIENMQU1QX0FERFJFU1NNT0RFKVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIEdldFdyYXBNb2RlKG1vZGU6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICAgICAgc3dpdGNoIChtb2RlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgRVRleHR1cmVXcmFwTW9kZS5DTEFNUF9UT19FREdFOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuQ0xBTVBfQUREUkVTU01PREU7XHJcbiAgICAgICAgICAgIGNhc2UgRVRleHR1cmVXcmFwTW9kZS5NSVJST1JFRF9SRVBFQVQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5NSVJST1JfQUREUkVTU01PREU7XHJcbiAgICAgICAgICAgIGNhc2UgRVRleHR1cmVXcmFwTW9kZS5SRVBFQVQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5XUkFQX0FERFJFU1NNT0RFO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuV1JBUF9BRERSRVNTTU9ERTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBieXRlIHN0cmlkZSBnaXZpbmcgYW4gYWNjZXNzb3JcclxuICAgICAqIEBwYXJhbSBhY2Nlc3NvciB0aGUgR0xURiBhY2Nlc3NvciBvYmpldFxyXG4gICAgICogQHJldHVybnMgdGhlIGJ5dGUgc3RyaWRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgR2V0Qnl0ZVN0cmlkZUZyb21UeXBlKGFjY2Vzc29yOiBJR0xURkFjY2Vzc29yKTogbnVtYmVyIHtcclxuICAgICAgICAvLyBOZWVkcyB0aGlzIGZ1bmN0aW9uIHNpbmNlIFwiYnl0ZVN0cmlkZVwiIGlzbid0IHJlcXVpZXJlZCBpbiBnbFRGIGZvcm1hdFxyXG4gICAgICAgIGNvbnN0IHR5cGUgPSBhY2Nlc3Nvci50eXBlO1xyXG5cclxuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcclxuICAgICAgICAgICAgY2FzZSBcIlZFQzJcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiAyO1xyXG4gICAgICAgICAgICBjYXNlIFwiVkVDM1wiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIDM7XHJcbiAgICAgICAgICAgIGNhc2UgXCJWRUM0XCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gNDtcclxuICAgICAgICAgICAgY2FzZSBcIk1BVDJcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiA0O1xyXG4gICAgICAgICAgICBjYXNlIFwiTUFUM1wiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIDk7XHJcbiAgICAgICAgICAgIGNhc2UgXCJNQVQ0XCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gMTY7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gMTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSB0ZXh0dXJlIGZpbHRlciBtb2RlIGdpdmluZyBhIG1vZGUgdmFsdWVcclxuICAgICAqIEBwYXJhbSBtb2RlIHRoZSBmaWx0ZXIgbW9kZSB2YWx1ZVxyXG4gICAgICogQHJldHVybnMgdGhlIGZpbHRlciBtb2RlIChUT0RPIC0gbmVlZHMgdG8gYmUgYSB0eXBlPylcclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBHZXRUZXh0dXJlRmlsdGVyTW9kZShtb2RlOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIHN3aXRjaCAobW9kZSkge1xyXG4gICAgICAgICAgICBjYXNlIEVUZXh0dXJlRmlsdGVyVHlwZS5MSU5FQVI6XHJcbiAgICAgICAgICAgIGNhc2UgRVRleHR1cmVGaWx0ZXJUeXBlLkxJTkVBUl9NSVBNQVBfTkVBUkVTVDpcclxuICAgICAgICAgICAgY2FzZSBFVGV4dHVyZUZpbHRlclR5cGUuTElORUFSX01JUE1BUF9MSU5FQVI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5UUklMSU5FQVJfU0FNUExJTkdNT0RFO1xyXG4gICAgICAgICAgICBjYXNlIEVUZXh0dXJlRmlsdGVyVHlwZS5ORUFSRVNUOlxyXG4gICAgICAgICAgICBjYXNlIEVUZXh0dXJlRmlsdGVyVHlwZS5ORUFSRVNUX01JUE1BUF9ORUFSRVNUOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuTkVBUkVTVF9TQU1QTElOR01PREU7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5CSUxJTkVBUl9TQU1QTElOR01PREU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzdGF0aWMgR2V0QnVmZmVyRnJvbUJ1ZmZlclZpZXcoXHJcbiAgICAgICAgZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSxcclxuICAgICAgICBidWZmZXJWaWV3OiBJR0xURkJ1ZmZlclZpZXcsXHJcbiAgICAgICAgYnl0ZU9mZnNldDogbnVtYmVyLFxyXG4gICAgICAgIGJ5dGVMZW5ndGg6IG51bWJlcixcclxuICAgICAgICBjb21wb25lbnRUeXBlOiBFQ29tcG9uZW50VHlwZVxyXG4gICAgKTogQXJyYXlCdWZmZXJWaWV3IHtcclxuICAgICAgICBieXRlT2Zmc2V0ID0gYnVmZmVyVmlldy5ieXRlT2Zmc2V0ICsgYnl0ZU9mZnNldDtcclxuXHJcbiAgICAgICAgY29uc3QgbG9hZGVkQnVmZmVyVmlldyA9IGdsdGZSdW50aW1lLmxvYWRlZEJ1ZmZlclZpZXdzW2J1ZmZlclZpZXcuYnVmZmVyXTtcclxuICAgICAgICBpZiAoYnl0ZU9mZnNldCArIGJ5dGVMZW5ndGggPiBsb2FkZWRCdWZmZXJWaWV3LmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQnVmZmVyIGFjY2VzcyBpcyBvdXQgb2YgcmFuZ2VcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBidWZmZXIgPSBsb2FkZWRCdWZmZXJWaWV3LmJ1ZmZlcjtcclxuICAgICAgICBieXRlT2Zmc2V0ICs9IGxvYWRlZEJ1ZmZlclZpZXcuYnl0ZU9mZnNldDtcclxuXHJcbiAgICAgICAgc3dpdGNoIChjb21wb25lbnRUeXBlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgRUNvbXBvbmVudFR5cGUuQllURTpcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSW50OEFycmF5KGJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XHJcbiAgICAgICAgICAgIGNhc2UgRUNvbXBvbmVudFR5cGUuVU5TSUdORURfQllURTpcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpO1xyXG4gICAgICAgICAgICBjYXNlIEVDb21wb25lbnRUeXBlLlNIT1JUOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBJbnQxNkFycmF5KGJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XHJcbiAgICAgICAgICAgIGNhc2UgRUNvbXBvbmVudFR5cGUuVU5TSUdORURfU0hPUlQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVpbnQxNkFycmF5KGJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgYSBidWZmZXIgZnJvbSBpdHMgYWNjZXNzb3JcclxuICAgICAqIEBwYXJhbSBnbHRmUnVudGltZSB0aGUgR0xURiBydW50aW1lXHJcbiAgICAgKiBAcGFyYW0gYWNjZXNzb3IgdGhlIEdMVEYgYWNjZXNzb3JcclxuICAgICAqIEByZXR1cm5zIGFuIGFycmF5IGJ1ZmZlciB2aWV3XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgR2V0QnVmZmVyRnJvbUFjY2Vzc29yKGdsdGZSdW50aW1lOiBJR0xURlJ1bnRpbWUsIGFjY2Vzc29yOiBJR0xURkFjY2Vzc29yKTogYW55IHtcclxuICAgICAgICBjb25zdCBidWZmZXJWaWV3OiBJR0xURkJ1ZmZlclZpZXcgPSBnbHRmUnVudGltZS5idWZmZXJWaWV3c1thY2Nlc3Nvci5idWZmZXJWaWV3XTtcclxuICAgICAgICBjb25zdCBieXRlTGVuZ3RoID0gYWNjZXNzb3IuY291bnQgKiBHTFRGVXRpbHMuR2V0Qnl0ZVN0cmlkZUZyb21UeXBlKGFjY2Vzc29yKTtcclxuICAgICAgICByZXR1cm4gR0xURlV0aWxzLkdldEJ1ZmZlckZyb21CdWZmZXJWaWV3KGdsdGZSdW50aW1lLCBidWZmZXJWaWV3LCBhY2Nlc3Nvci5ieXRlT2Zmc2V0LCBieXRlTGVuZ3RoLCBhY2Nlc3Nvci5jb21wb25lbnRUeXBlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERlY29kZXMgYSBidWZmZXIgdmlldyBpbnRvIGEgc3RyaW5nXHJcbiAgICAgKiBAcGFyYW0gdmlldyB0aGUgYnVmZmVyIHZpZXdcclxuICAgICAqIEByZXR1cm5zIGEgc3RyaW5nXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgRGVjb2RlQnVmZmVyVG9UZXh0KHZpZXc6IEFycmF5QnVmZmVyVmlldyk6IHN0cmluZyB7XHJcbiAgICAgICAgbGV0IHJlc3VsdCA9IFwiXCI7XHJcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gdmlldy5ieXRlTGVuZ3RoO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XHJcbiAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKCg8YW55PnZpZXcpW2ldKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IG1hdGVyaWFsIG9mIGdsdGYuIFJlbGF0ZWQgdG9cclxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi90cmVlL21hc3Rlci9zcGVjaWZpY2F0aW9uLzEuMCNhcHBlbmRpeC1hLWRlZmF1bHQtbWF0ZXJpYWxcclxuICAgICAqIEBwYXJhbSBzY2VuZSB0aGUgQmFieWxvbi5qcyBzY2VuZVxyXG4gICAgICogQHJldHVybnMgdGhlIGRlZmF1bHQgQmFieWxvbiBtYXRlcmlhbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIEdldERlZmF1bHRNYXRlcmlhbChzY2VuZTogU2NlbmUpOiBTaGFkZXJNYXRlcmlhbCB7XHJcbiAgICAgICAgaWYgKCFHTFRGVXRpbHMuX0RlZmF1bHRNYXRlcmlhbCkge1xyXG4gICAgICAgICAgICBFZmZlY3QuU2hhZGVyc1N0b3JlW1wiR0xURkRlZmF1bHRNYXRlcmlhbFZlcnRleFNoYWRlclwiXSA9IFtcclxuICAgICAgICAgICAgICAgIFwicHJlY2lzaW9uIGhpZ2hwIGZsb2F0O1wiLFxyXG4gICAgICAgICAgICAgICAgXCJcIixcclxuICAgICAgICAgICAgICAgIFwidW5pZm9ybSBtYXQ0IHdvcmxkVmlldztcIixcclxuICAgICAgICAgICAgICAgIFwidW5pZm9ybSBtYXQ0IHByb2plY3Rpb247XCIsXHJcbiAgICAgICAgICAgICAgICBcIlwiLFxyXG4gICAgICAgICAgICAgICAgXCJhdHRyaWJ1dGUgdmVjMyBwb3NpdGlvbjtcIixcclxuICAgICAgICAgICAgICAgIFwiXCIsXHJcbiAgICAgICAgICAgICAgICBcInZvaWQgbWFpbih2b2lkKVwiLFxyXG4gICAgICAgICAgICAgICAgXCJ7XCIsXHJcbiAgICAgICAgICAgICAgICBcIiAgICBnbF9Qb3NpdGlvbiA9IHByb2plY3Rpb24gKiB3b3JsZFZpZXcgKiB2ZWM0KHBvc2l0aW9uLCAxLjApO1wiLFxyXG4gICAgICAgICAgICAgICAgXCJ9XCIsXHJcbiAgICAgICAgICAgIF0uam9pbihcIlxcblwiKTtcclxuXHJcbiAgICAgICAgICAgIEVmZmVjdC5TaGFkZXJzU3RvcmVbXCJHTFRGRGVmYXVsdE1hdGVyaWFsUGl4ZWxTaGFkZXJcIl0gPSBbXHJcbiAgICAgICAgICAgICAgICBcInByZWNpc2lvbiBoaWdocCBmbG9hdDtcIixcclxuICAgICAgICAgICAgICAgIFwiXCIsXHJcbiAgICAgICAgICAgICAgICBcInVuaWZvcm0gdmVjNCB1X2VtaXNzaW9uO1wiLFxyXG4gICAgICAgICAgICAgICAgXCJcIixcclxuICAgICAgICAgICAgICAgIFwidm9pZCBtYWluKHZvaWQpXCIsXHJcbiAgICAgICAgICAgICAgICBcIntcIixcclxuICAgICAgICAgICAgICAgIFwiICAgIGdsX0ZyYWdDb2xvciA9IHVfZW1pc3Npb247XCIsXHJcbiAgICAgICAgICAgICAgICBcIn1cIixcclxuICAgICAgICAgICAgXS5qb2luKFwiXFxuXCIpO1xyXG5cclxuICAgICAgICAgICAgY29uc3Qgc2hhZGVyUGF0aCA9IHtcclxuICAgICAgICAgICAgICAgIHZlcnRleDogXCJHTFRGRGVmYXVsdE1hdGVyaWFsXCIsXHJcbiAgICAgICAgICAgICAgICBmcmFnbWVudDogXCJHTFRGRGVmYXVsdE1hdGVyaWFsXCIsXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xyXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczogW1wicG9zaXRpb25cIl0sXHJcbiAgICAgICAgICAgICAgICB1bmlmb3JtczogW1wid29ybGRWaWV3XCIsIFwicHJvamVjdGlvblwiLCBcInVfZW1pc3Npb25cIl0sXHJcbiAgICAgICAgICAgICAgICBzYW1wbGVyczogbmV3IEFycmF5PHN0cmluZz4oKSxcclxuICAgICAgICAgICAgICAgIG5lZWRBbHBoYUJsZW5kaW5nOiBmYWxzZSxcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIEdMVEZVdGlscy5fRGVmYXVsdE1hdGVyaWFsID0gbmV3IFNoYWRlck1hdGVyaWFsKFwiR0xURkRlZmF1bHRNYXRlcmlhbFwiLCBzY2VuZSwgc2hhZGVyUGF0aCwgb3B0aW9ucyk7XHJcbiAgICAgICAgICAgIEdMVEZVdGlscy5fRGVmYXVsdE1hdGVyaWFsLnNldENvbG9yNChcInVfZW1pc3Npb25cIiwgbmV3IENvbG9yNCgwLjUsIDAuNSwgMC41LCAxLjApKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBHTFRGVXRpbHMuX0RlZmF1bHRNYXRlcmlhbDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBUaGUgR0xURiBkZWZhdWx0IG1hdGVyaWFsXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfRGVmYXVsdE1hdGVyaWFsOiBOdWxsYWJsZTxTaGFkZXJNYXRlcmlhbD4gPSBudWxsO1xyXG59XHJcbiIsImltcG9ydCB7IEdMVEZMb2FkZXJFeHRlbnNpb24sIEdMVEZMb2FkZXJCYXNlLCBHTFRGTG9hZGVyIH0gZnJvbSBcIi4vZ2xURkxvYWRlclwiO1xyXG5cclxuaW1wb3J0IHR5cGUgeyBJR0xURlJ1bnRpbWUsIElHTFRGTWF0ZXJpYWwgfSBmcm9tIFwiLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5cclxuaW1wb3J0IHsgVmVjdG9yMyB9IGZyb20gXCJjb3JlL01hdGhzL21hdGgudmVjdG9yXCI7XHJcbmltcG9ydCB7IENvbG9yMyB9IGZyb20gXCJjb3JlL01hdGhzL21hdGguY29sb3JcIjtcclxuaW1wb3J0IHsgVG9vbHMgfSBmcm9tIFwiY29yZS9NaXNjL3Rvb2xzXCI7XHJcbmltcG9ydCB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB7IFN0YW5kYXJkTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvc3RhbmRhcmRNYXRlcmlhbFwiO1xyXG5pbXBvcnQgeyBIZW1pc3BoZXJpY0xpZ2h0IH0gZnJvbSBcImNvcmUvTGlnaHRzL2hlbWlzcGhlcmljTGlnaHRcIjtcclxuaW1wb3J0IHsgRGlyZWN0aW9uYWxMaWdodCB9IGZyb20gXCJjb3JlL0xpZ2h0cy9kaXJlY3Rpb25hbExpZ2h0XCI7XHJcbmltcG9ydCB7IFBvaW50TGlnaHQgfSBmcm9tIFwiY29yZS9MaWdodHMvcG9pbnRMaWdodFwiO1xyXG5pbXBvcnQgeyBTcG90TGlnaHQgfSBmcm9tIFwiY29yZS9MaWdodHMvc3BvdExpZ2h0XCI7XHJcblxyXG5pbnRlcmZhY2UgSUdMVEZNYXRlcmlhbHNDb21tb25FeHRlbnNpb25WYWx1ZXMge1xyXG4gICAgYW1iaWVudD86IG51bWJlcltdIHwgc3RyaW5nO1xyXG4gICAgZGlmZnVzZT86IG51bWJlcltdIHwgc3RyaW5nO1xyXG4gICAgZW1pc3Npb24/OiBudW1iZXJbXSB8IHN0cmluZztcclxuICAgIHNwZWN1bGFyPzogbnVtYmVyW10gfCBzdHJpbmc7XHJcbiAgICBzaGluaW5lc3M/OiBudW1iZXI7XHJcbiAgICB0cmFuc3BhcmVuY3k/OiBudW1iZXI7XHJcbn1cclxuXHJcbmludGVyZmFjZSBJR0xURk1hdGVyaWFsc0NvbW1vbkV4dGVuc2lvbiB7XHJcbiAgICB0ZWNobmlxdWU6IHN0cmluZztcclxuICAgIHRyYW5zcGFyZW50PzogbnVtYmVyO1xyXG4gICAgZG91YmxlU2lkZWQ/OiBib29sZWFuO1xyXG4gICAgdmFsdWVzOiBJR0xURk1hdGVyaWFsc0NvbW1vbkV4dGVuc2lvblZhbHVlcztcclxufVxyXG5cclxuaW50ZXJmYWNlIElHTFRGUnVudGltZUNvbW1vbkV4dGVuc2lvbiB7XHJcbiAgICBsaWdodHM6IHsgW2tleTogc3RyaW5nXTogSUdMVEZMaWdodENvbW1vbkV4dGVuc2lvbiB9O1xyXG59XHJcblxyXG5pbnRlcmZhY2UgSUdMVEZMaWdodENvbW1vbkV4dGVuc2lvbiB7XHJcbiAgICBuYW1lOiBzdHJpbmc7XHJcbiAgICB0eXBlOiBzdHJpbmc7XHJcblxyXG4gICAgYW1iaWVudD86IElHTFRGQW1iaWVudExpZ2h0Q29tbW9uRXh0ZW5zaW9uO1xyXG4gICAgcG9pbnQ/OiBJR0xURlBvaW50TGlnaHRDb21tb25FeHRlbnNpb247XHJcbiAgICBkaXJlY3Rpb25hbD86IElHTFRGRGlyZWN0aW9uYWxMaWdodENvbW1vbkV4dGVuc2lvbjtcclxuICAgIHNwb3Q/OiBJR0xURlNwb3RMaWdodENvbW1vbkV4dGVuc2lvbjtcclxufVxyXG5cclxuaW50ZXJmYWNlIElHTFRGUG9pbnRMaWdodENvbW1vbkV4dGVuc2lvbiB7XHJcbiAgICBjb2xvcjogbnVtYmVyW107XHJcbiAgICBjb25zdGFudEF0dGVudWF0aW9uOiBudW1iZXI7XHJcbiAgICBsaW5lYXJBdHRlbnVhdGlvbjogbnVtYmVyO1xyXG4gICAgcXVhZHJhdGljQXR0ZW51YXRpb246IG51bWJlcjtcclxufVxyXG5cclxuaW50ZXJmYWNlIElHTFRGQW1iaWVudExpZ2h0Q29tbW9uRXh0ZW5zaW9uIHtcclxuICAgIGNvbG9yOiBudW1iZXJbXTtcclxufVxyXG5cclxuaW50ZXJmYWNlIElHTFRGRGlyZWN0aW9uYWxMaWdodENvbW1vbkV4dGVuc2lvbiB7XHJcbiAgICBjb2xvcjogbnVtYmVyW107XHJcbn1cclxuXHJcbmludGVyZmFjZSBJR0xURlNwb3RMaWdodENvbW1vbkV4dGVuc2lvbiB7XHJcbiAgICBjb2xvcjogbnVtYmVyW107XHJcbiAgICBjb25zdGFudEF0dGVudWF0aW9uOiBudW1iZXI7XHJcbiAgICBmYWxsT2ZmQW5nbGU6IG51bWJlcjtcclxuICAgIGZhbGxPZmZFeHBvbmVudDogbnVtYmVyO1xyXG4gICAgbGluZWFyQXR0ZW51YXRpb246IG51bWJlcjtcclxuICAgIHF1YWRyYXRpY0F0dGVudWF0aW9uOiBudW1iZXI7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBAaW50ZXJuYWxcclxuICogQGRlcHJlY2F0ZWRcclxuICovXHJcbmV4cG9ydCBjbGFzcyBHTFRGTWF0ZXJpYWxzQ29tbW9uRXh0ZW5zaW9uIGV4dGVuZHMgR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICBzdXBlcihcIktIUl9tYXRlcmlhbHNfY29tbW9uXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBvdmVycmlkZSBsb2FkUnVudGltZUV4dGVuc2lvbnNBc3luYyhnbHRmUnVudGltZTogSUdMVEZSdW50aW1lKTogYm9vbGVhbiB7XHJcbiAgICAgICAgaWYgKCFnbHRmUnVudGltZS5leHRlbnNpb25zKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbjogSUdMVEZSdW50aW1lQ29tbW9uRXh0ZW5zaW9uID0gZ2x0ZlJ1bnRpbWUuZXh0ZW5zaW9uc1t0aGlzLm5hbWVdO1xyXG4gICAgICAgIGlmICghZXh0ZW5zaW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSBsaWdodHNcclxuICAgICAgICBjb25zdCBsaWdodHMgPSBleHRlbnNpb24ubGlnaHRzO1xyXG4gICAgICAgIGlmIChsaWdodHMpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCB0aGluZyBpbiBsaWdodHMpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGxpZ2h0OiBJR0xURkxpZ2h0Q29tbW9uRXh0ZW5zaW9uID0gbGlnaHRzW3RoaW5nXTtcclxuXHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGxpZ2h0LnR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiYW1iaWVudFwiOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFtYmllbnRMaWdodCA9IG5ldyBIZW1pc3BoZXJpY0xpZ2h0KGxpZ2h0Lm5hbWUsIG5ldyBWZWN0b3IzKDAsIDEsIDApLCBnbHRmUnVudGltZS5zY2VuZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFtYmllbnQgPSBsaWdodC5hbWJpZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW1iaWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW1iaWVudExpZ2h0LmRpZmZ1c2UgPSBDb2xvcjMuRnJvbUFycmF5KGFtYmllbnQuY29sb3IgfHwgWzEsIDEsIDFdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInBvaW50XCI6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9pbnRMaWdodCA9IG5ldyBQb2ludExpZ2h0KGxpZ2h0Lm5hbWUsIG5ldyBWZWN0b3IzKDEwLCAxMCwgMTApLCBnbHRmUnVudGltZS5zY2VuZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvaW50ID0gbGlnaHQucG9pbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwb2ludCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRMaWdodC5kaWZmdXNlID0gQ29sb3IzLkZyb21BcnJheShwb2ludC5jb2xvciB8fCBbMSwgMSwgMV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZGlyZWN0aW9uYWxcIjoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkaXJMaWdodCA9IG5ldyBEaXJlY3Rpb25hbExpZ2h0KGxpZ2h0Lm5hbWUsIG5ldyBWZWN0b3IzKDAsIC0xLCAwKSwgZ2x0ZlJ1bnRpbWUuc2NlbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkaXJlY3Rpb25hbCA9IGxpZ2h0LmRpcmVjdGlvbmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlyZWN0aW9uYWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpckxpZ2h0LmRpZmZ1c2UgPSBDb2xvcjMuRnJvbUFycmF5KGRpcmVjdGlvbmFsLmNvbG9yIHx8IFsxLCAxLCAxXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJzcG90XCI6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3BvdCA9IGxpZ2h0LnNwb3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzcG90KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzcG90TGlnaHQgPSBuZXcgU3BvdExpZ2h0KFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpZ2h0Lm5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFZlY3RvcjMoMCwgMTAsIDApLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBWZWN0b3IzKDAsIC0xLCAwKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcG90LmZhbGxPZmZBbmdsZSB8fCBNYXRoLlBJLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwb3QuZmFsbE9mZkV4cG9uZW50IHx8IDAuMCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbHRmUnVudGltZS5zY2VuZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwb3RMaWdodC5kaWZmdXNlID0gQ29sb3IzLkZyb21BcnJheShzcG90LmNvbG9yIHx8IFsxLCAxLCAxXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFRvb2xzLldhcm4oJ0dMVEYgTWF0ZXJpYWwgQ29tbW9uIGV4dGVuc2lvbjogbGlnaHQgdHlwZSBcIicgKyBsaWdodC50eXBlICsgXCLigJ0gbm90IHN1cHBvcnRlZFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgb3ZlcnJpZGUgbG9hZE1hdGVyaWFsQXN5bmMoZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSwgaWQ6IHN0cmluZywgb25TdWNjZXNzOiAobWF0ZXJpYWw6IE1hdGVyaWFsKSA9PiB2b2lkLCBvbkVycm9yOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkKTogYm9vbGVhbiB7XHJcbiAgICAgICAgY29uc3QgbWF0ZXJpYWw6IElHTFRGTWF0ZXJpYWwgPSBnbHRmUnVudGltZS5tYXRlcmlhbHNbaWRdO1xyXG4gICAgICAgIGlmICghbWF0ZXJpYWwgfHwgIW1hdGVyaWFsLmV4dGVuc2lvbnMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uOiBJR0xURk1hdGVyaWFsc0NvbW1vbkV4dGVuc2lvbiA9IG1hdGVyaWFsLmV4dGVuc2lvbnNbdGhpcy5uYW1lXTtcclxuICAgICAgICBpZiAoIWV4dGVuc2lvbikge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBzdGFuZGFyZE1hdGVyaWFsID0gbmV3IFN0YW5kYXJkTWF0ZXJpYWwoaWQsIGdsdGZSdW50aW1lLnNjZW5lKTtcclxuICAgICAgICBzdGFuZGFyZE1hdGVyaWFsLnNpZGVPcmllbnRhdGlvbiA9IE1hdGVyaWFsLkNvdW50ZXJDbG9ja1dpc2VTaWRlT3JpZW50YXRpb247XHJcblxyXG4gICAgICAgIGlmIChleHRlbnNpb24udGVjaG5pcXVlID09PSBcIkNPTlNUQU5UXCIpIHtcclxuICAgICAgICAgICAgc3RhbmRhcmRNYXRlcmlhbC5kaXNhYmxlTGlnaHRpbmcgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc3RhbmRhcmRNYXRlcmlhbC5iYWNrRmFjZUN1bGxpbmcgPSBleHRlbnNpb24uZG91YmxlU2lkZWQgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogIWV4dGVuc2lvbi5kb3VibGVTaWRlZDtcclxuICAgICAgICBzdGFuZGFyZE1hdGVyaWFsLmFscGhhID0gZXh0ZW5zaW9uLnZhbHVlcy50cmFuc3BhcmVuY3kgPT09IHVuZGVmaW5lZCA/IDEuMCA6IGV4dGVuc2lvbi52YWx1ZXMudHJhbnNwYXJlbmN5O1xyXG4gICAgICAgIHN0YW5kYXJkTWF0ZXJpYWwuc3BlY3VsYXJQb3dlciA9IGV4dGVuc2lvbi52YWx1ZXMuc2hpbmluZXNzID09PSB1bmRlZmluZWQgPyAwLjAgOiBleHRlbnNpb24udmFsdWVzLnNoaW5pbmVzcztcclxuXHJcbiAgICAgICAgLy8gQW1iaWVudFxyXG4gICAgICAgIGlmICh0eXBlb2YgZXh0ZW5zaW9uLnZhbHVlcy5hbWJpZW50ID09PSBcInN0cmluZ1wiKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRUZXh0dXJlKGdsdGZSdW50aW1lLCBleHRlbnNpb24udmFsdWVzLmFtYmllbnQsIHN0YW5kYXJkTWF0ZXJpYWwsIFwiYW1iaWVudFRleHR1cmVcIiwgb25FcnJvcik7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgc3RhbmRhcmRNYXRlcmlhbC5hbWJpZW50Q29sb3IgPSBDb2xvcjMuRnJvbUFycmF5KGV4dGVuc2lvbi52YWx1ZXMuYW1iaWVudCB8fCBbMCwgMCwgMF0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRGlmZnVzZVxyXG4gICAgICAgIGlmICh0eXBlb2YgZXh0ZW5zaW9uLnZhbHVlcy5kaWZmdXNlID09PSBcInN0cmluZ1wiKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRUZXh0dXJlKGdsdGZSdW50aW1lLCBleHRlbnNpb24udmFsdWVzLmRpZmZ1c2UsIHN0YW5kYXJkTWF0ZXJpYWwsIFwiZGlmZnVzZVRleHR1cmVcIiwgb25FcnJvcik7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgc3RhbmRhcmRNYXRlcmlhbC5kaWZmdXNlQ29sb3IgPSBDb2xvcjMuRnJvbUFycmF5KGV4dGVuc2lvbi52YWx1ZXMuZGlmZnVzZSB8fCBbMCwgMCwgMF0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRW1pc3Npb25cclxuICAgICAgICBpZiAodHlwZW9mIGV4dGVuc2lvbi52YWx1ZXMuZW1pc3Npb24gPT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZFRleHR1cmUoZ2x0ZlJ1bnRpbWUsIGV4dGVuc2lvbi52YWx1ZXMuZW1pc3Npb24sIHN0YW5kYXJkTWF0ZXJpYWwsIFwiZW1pc3NpdmVUZXh0dXJlXCIsIG9uRXJyb3IpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHN0YW5kYXJkTWF0ZXJpYWwuZW1pc3NpdmVDb2xvciA9IENvbG9yMy5Gcm9tQXJyYXkoZXh0ZW5zaW9uLnZhbHVlcy5lbWlzc2lvbiB8fCBbMCwgMCwgMF0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU3BlY3VsYXJcclxuICAgICAgICBpZiAodHlwZW9mIGV4dGVuc2lvbi52YWx1ZXMuc3BlY3VsYXIgPT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZFRleHR1cmUoZ2x0ZlJ1bnRpbWUsIGV4dGVuc2lvbi52YWx1ZXMuc3BlY3VsYXIsIHN0YW5kYXJkTWF0ZXJpYWwsIFwic3BlY3VsYXJUZXh0dXJlXCIsIG9uRXJyb3IpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHN0YW5kYXJkTWF0ZXJpYWwuc3BlY3VsYXJDb2xvciA9IENvbG9yMy5Gcm9tQXJyYXkoZXh0ZW5zaW9uLnZhbHVlcy5zcGVjdWxhciB8fCBbMCwgMCwgMF0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZFRleHR1cmUoZ2x0ZlJ1bnRpbWU6IElHTFRGUnVudGltZSwgaWQ6IHN0cmluZywgbWF0ZXJpYWw6IFN0YW5kYXJkTWF0ZXJpYWwsIHByb3BlcnR5UGF0aDogc3RyaW5nLCBvbkVycm9yOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICAgICAgLy8gQ3JlYXRlIGJ1ZmZlciBmcm9tIHRleHR1cmUgdXJsXHJcbiAgICAgICAgR0xURkxvYWRlckJhc2UuTG9hZFRleHR1cmVCdWZmZXJBc3luYyhcclxuICAgICAgICAgICAgZ2x0ZlJ1bnRpbWUsXHJcbiAgICAgICAgICAgIGlkLFxyXG4gICAgICAgICAgICAoYnVmZmVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgdGV4dHVyZSBmcm9tIGJ1ZmZlclxyXG4gICAgICAgICAgICAgICAgR0xURkxvYWRlckJhc2UuQ3JlYXRlVGV4dHVyZUFzeW5jKGdsdGZSdW50aW1lLCBpZCwgYnVmZmVyLCAodGV4dHVyZSkgPT4gKCg8YW55Pm1hdGVyaWFsKVtwcm9wZXJ0eVBhdGhdID0gdGV4dHVyZSkpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBvbkVycm9yXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxufVxyXG5cclxuR0xURkxvYWRlci5SZWdpc3RlckV4dGVuc2lvbihuZXcgR0xURk1hdGVyaWFsc0NvbW1vbkV4dGVuc2lvbigpKTtcclxuIiwiZXhwb3J0ICogZnJvbSBcIi4vZ2xURkJpbmFyeUV4dGVuc2lvblwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9nbFRGTG9hZGVyXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL2dsVEZMb2FkZXJVdGlsc1wiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9nbFRGTWF0ZXJpYWxzQ29tbW9uRXh0ZW5zaW9uXCI7XHJcbiIsImltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBTcGhlcmljYWxIYXJtb25pY3MsIFNwaGVyaWNhbFBvbHlub21pYWwgfSBmcm9tIFwiY29yZS9NYXRocy9zcGhlcmljYWxQb2x5bm9taWFsXCI7XHJcbmltcG9ydCB7IFF1YXRlcm5pb24sIE1hdHJpeCB9IGZyb20gXCJjb3JlL01hdGhzL21hdGgudmVjdG9yXCI7XHJcbmltcG9ydCB0eXBlIHsgQmFzZVRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvYmFzZVRleHR1cmVcIjtcclxuaW1wb3J0IHsgUmF3Q3ViZVRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvcmF3Q3ViZVRleHR1cmVcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSUVYVExpZ2h0c0ltYWdlQmFzZWRfTGlnaHRSZWZlcmVuY2VJbWFnZUJhc2VkLCBJRVhUTGlnaHRzSW1hZ2VCYXNlZF9MaWdodEltYWdlQmFzZWQsIElFWFRMaWdodHNJbWFnZUJhc2VkIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElTY2VuZSB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciwgQXJyYXlJdGVtIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIkVYVF9saWdodHNfaW1hZ2VfYmFzZWRcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgRVhUX2xpZ2h0c19pbWFnZV9iYXNlZCBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiRVhUX2xpZ2h0c19pbWFnZV9iYXNlZFwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCIge1xyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG4gICAgaW50ZXJmYWNlIElFWFRMaWdodHNJbWFnZUJhc2VkX0xpZ2h0SW1hZ2VCYXNlZCB7XHJcbiAgICAgICAgX2JhYnlsb25UZXh0dXJlPzogQmFzZVRleHR1cmU7XHJcbiAgICAgICAgX2xvYWRlZD86IFByb21pc2U8dm9pZD47XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9WZW5kb3IvRVhUX2xpZ2h0c19pbWFnZV9iYXNlZC9SRUFETUUubWQpXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBFWFRfbGlnaHRzX2ltYWdlX2Jhc2VkIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuICAgIHByaXZhdGUgX2xpZ2h0cz86IElFWFRMaWdodHNJbWFnZUJhc2VkX0xpZ2h0SW1hZ2VCYXNlZFtdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICAgICAgZGVsZXRlIHRoaXMuX2xpZ2h0cztcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgb25Mb2FkaW5nKCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbnMgPSB0aGlzLl9sb2FkZXIuZ2x0Zi5leHRlbnNpb25zO1xyXG4gICAgICAgIGlmIChleHRlbnNpb25zICYmIGV4dGVuc2lvbnNbdGhpcy5uYW1lXSkge1xyXG4gICAgICAgICAgICBjb25zdCBleHRlbnNpb24gPSBleHRlbnNpb25zW3RoaXMubmFtZV0gYXMgSUVYVExpZ2h0c0ltYWdlQmFzZWQ7XHJcbiAgICAgICAgICAgIHRoaXMuX2xpZ2h0cyA9IGV4dGVuc2lvbi5saWdodHM7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkU2NlbmVBc3luYyhjb250ZXh0OiBzdHJpbmcsIHNjZW5lOiBJU2NlbmUpOiBOdWxsYWJsZTxQcm9taXNlPHZvaWQ+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElFWFRMaWdodHNJbWFnZUJhc2VkX0xpZ2h0UmVmZXJlbmNlSW1hZ2VCYXNlZD4oY29udGV4dCwgc2NlbmUsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9sb2FkZXIuX2FsbE1hdGVyaWFsc0RpcnR5UmVxdWlyZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG5cclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkZXIubG9hZFNjZW5lQXN5bmMoY29udGV4dCwgc2NlbmUpKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2dPcGVuKGAke2V4dGVuc2lvbkNvbnRleHR9YCk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBsaWdodCA9IEFycmF5SXRlbS5HZXQoYCR7ZXh0ZW5zaW9uQ29udGV4dH0vbGlnaHRgLCB0aGlzLl9saWdodHMsIGV4dGVuc2lvbi5saWdodCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkTGlnaHRBc3luYyhgL2V4dGVuc2lvbnMvJHt0aGlzLm5hbWV9L2xpZ2h0cy8ke2V4dGVuc2lvbi5saWdodH1gLCBsaWdodCkudGhlbigodGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmUuZW52aXJvbm1lbnRUZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9nQ2xvc2UoKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZExpZ2h0QXN5bmMoY29udGV4dDogc3RyaW5nLCBsaWdodDogSUVYVExpZ2h0c0ltYWdlQmFzZWRfTGlnaHRJbWFnZUJhc2VkKTogUHJvbWlzZTxCYXNlVGV4dHVyZT4ge1xyXG4gICAgICAgIGlmICghbGlnaHQuX2xvYWRlZCkge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9nT3BlbihgJHtjb250ZXh0fWApO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgaW1hZ2VEYXRhID0gbmV3IEFycmF5PEFycmF5PEFycmF5QnVmZmVyVmlldz4+KGxpZ2h0LnNwZWN1bGFySW1hZ2VzLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIGZvciAobGV0IG1pcG1hcCA9IDA7IG1pcG1hcCA8IGxpZ2h0LnNwZWN1bGFySW1hZ2VzLmxlbmd0aDsgbWlwbWFwKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGZhY2VzID0gbGlnaHQuc3BlY3VsYXJJbWFnZXNbbWlwbWFwXTtcclxuICAgICAgICAgICAgICAgIGltYWdlRGF0YVttaXBtYXBdID0gbmV3IEFycmF5PEFycmF5QnVmZmVyVmlldz4oZmFjZXMubGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGZhY2UgPSAwOyBmYWNlIDwgZmFjZXMubGVuZ3RoOyBmYWNlKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzcGVjdWxhckltYWdlQ29udGV4dCA9IGAke2NvbnRleHR9L3NwZWN1bGFySW1hZ2VzLyR7bWlwbWFwfS8ke2ZhY2V9YDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9nT3BlbihgJHtzcGVjdWxhckltYWdlQ29udGV4dH1gKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBmYWNlc1tmYWNlXTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbWFnZSA9IEFycmF5SXRlbS5HZXQoc3BlY3VsYXJJbWFnZUNvbnRleHQsIHRoaXMuX2xvYWRlci5nbHRmLmltYWdlcywgaW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2FkSW1hZ2VBc3luYyhgL2ltYWdlcy8ke2luZGV4fWAsIGltYWdlKS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZURhdGFbbWlwbWFwXVtmYWNlXSA9IGRhdGE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvZ0Nsb3NlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2dDbG9zZSgpO1xyXG5cclxuICAgICAgICAgICAgbGlnaHQuX2xvYWRlZCA9IFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJhYnlsb25UZXh0dXJlID0gbmV3IFJhd0N1YmVUZXh0dXJlKHRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmUsIG51bGwsIGxpZ2h0LnNwZWN1bGFySW1hZ2VTaXplKTtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25UZXh0dXJlLm5hbWUgPSBsaWdodC5uYW1lIHx8IFwiZW52aXJvbm1lbnRcIjtcclxuICAgICAgICAgICAgICAgIGxpZ2h0Ll9iYWJ5bG9uVGV4dHVyZSA9IGJhYnlsb25UZXh0dXJlO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChsaWdodC5pbnRlbnNpdHkgIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvblRleHR1cmUubGV2ZWwgPSBsaWdodC5pbnRlbnNpdHk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGxpZ2h0LnJvdGF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJvdGF0aW9uID0gUXVhdGVybmlvbi5Gcm9tQXJyYXkobGlnaHQucm90YXRpb24pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBJbnZlcnQgdGhlIHJvdGF0aW9uIHNvIHRoYXQgcG9zaXRpdmUgcm90YXRpb24gaXMgY291bnRlci1jbG9ja3dpc2UuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9sb2FkZXIuYmFieWxvblNjZW5lLnVzZVJpZ2h0SGFuZGVkU3lzdGVtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJvdGF0aW9uID0gUXVhdGVybmlvbi5JbnZlcnNlKHJvdGF0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIE1hdHJpeC5Gcm9tUXVhdGVybmlvblRvUmVmKHJvdGF0aW9uLCBiYWJ5bG9uVGV4dHVyZS5nZXRSZWZsZWN0aW9uVGV4dHVyZU1hdHJpeCgpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWxpZ2h0LmlycmFkaWFuY2VDb2VmZmljaWVudHMpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IElycmFkaWFuY2UgY29lZmZpY2llbnRzIGFyZSBtaXNzaW5nYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3Qgc3BoZXJpY2FsSGFybW9uaWNzID0gU3BoZXJpY2FsSGFybW9uaWNzLkZyb21BcnJheShsaWdodC5pcnJhZGlhbmNlQ29lZmZpY2llbnRzKTtcclxuICAgICAgICAgICAgICAgIHNwaGVyaWNhbEhhcm1vbmljcy5zY2FsZUluUGxhY2UobGlnaHQuaW50ZW5zaXR5KTtcclxuXHJcbiAgICAgICAgICAgICAgICBzcGhlcmljYWxIYXJtb25pY3MuY29udmVydElycmFkaWFuY2VUb0xhbWJlcnRpYW5SYWRpYW5jZSgpO1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc3BoZXJpY2FsUG9seW5vbWlhbCA9IFNwaGVyaWNhbFBvbHlub21pYWwuRnJvbUhhcm1vbmljcyhzcGhlcmljYWxIYXJtb25pY3MpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIENvbXB1dGUgdGhlIGxvZCBnZW5lcmF0aW9uIHNjYWxlIHRvIGZpdCBleGFjdGx5IHRvIHRoZSBudW1iZXIgb2YgbGV2ZWxzIGF2YWlsYWJsZS5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGxvZEdlbmVyYXRpb25TY2FsZSA9IChpbWFnZURhdGEubGVuZ3RoIC0gMSkgLyBNYXRoLmxvZzIobGlnaHQuc3BlY3VsYXJJbWFnZVNpemUpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJhYnlsb25UZXh0dXJlLnVwZGF0ZVJHQkRBc3luYyhpbWFnZURhdGEsIHNwaGVyaWNhbFBvbHlub21pYWwsIGxvZEdlbmVyYXRpb25TY2FsZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGxpZ2h0Ll9sb2FkZWQudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBsaWdodC5fYmFieWxvblRleHR1cmUhO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBFWFRfbGlnaHRzX2ltYWdlX2Jhc2VkKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgeyBWZWN0b3IzLCBRdWF0ZXJuaW9uLCBNYXRyaXgsIFRtcFZlY3RvcnMgfSBmcm9tIFwiY29yZS9NYXRocy9tYXRoLnZlY3RvclwiO1xyXG5pbXBvcnQgdHlwZSB7IE1lc2ggfSBmcm9tIFwiY29yZS9NZXNoZXMvbWVzaFwiO1xyXG5pbXBvcnQgdHlwZSB7IFRyYW5zZm9ybU5vZGUgfSBmcm9tIFwiY29yZS9NZXNoZXMvdHJhbnNmb3JtTm9kZVwiO1xyXG5pbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciwgQXJyYXlJdGVtIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB0eXBlIHsgSU5vZGUgfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJRVhUTWVzaEdwdUluc3RhbmNpbmcgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5pbXBvcnQgXCJjb3JlL01lc2hlcy90aGluSW5zdGFuY2VNZXNoXCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJFWFRfbWVzaF9ncHVfaW5zdGFuY2luZ1wiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBFWFRfbWVzaF9ncHVfaW5zdGFuY2luZyBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiRVhUX21lc2hfZ3B1X2luc3RhbmNpbmdcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvVmVuZG9yL0VYVF9tZXNoX2dwdV9pbnN0YW5jaW5nL1JFQURNRS5tZClcclxuICogW1BsYXlncm91bmQgU2FtcGxlXShodHRwczovL3BsYXlncm91bmQuYmFieWxvbmpzLmNvbS8jUUZJR0xXIzkpXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBFWFRfbWVzaF9ncHVfaW5zdGFuY2luZyBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE5vZGVBc3luYyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IElOb2RlLCBhc3NpZ246IChiYWJ5bG9uVHJhbnNmb3JtTm9kZTogVHJhbnNmb3JtTm9kZSkgPT4gdm9pZCk6IE51bGxhYmxlPFByb21pc2U8VHJhbnNmb3JtTm9kZT4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUVYVE1lc2hHcHVJbnN0YW5jaW5nLCBUcmFuc2Zvcm1Ob2RlPihjb250ZXh0LCBub2RlLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLl9kaXNhYmxlSW5zdGFuY2VkTWVzaCsrO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRoaXMuX2xvYWRlci5sb2FkTm9kZUFzeW5jKGAvbm9kZXMvJHtub2RlLmluZGV4fWAsIG5vZGUsIGFzc2lnbik7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9sb2FkZXIuX2Rpc2FibGVJbnN0YW5jZWRNZXNoLS07XHJcblxyXG4gICAgICAgICAgICBpZiAoIW5vZGUuX3ByaW1pdGl2ZUJhYnlsb25NZXNoZXMpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPE51bGxhYmxlPEZsb2F0MzJBcnJheT4+PigpO1xyXG4gICAgICAgICAgICBsZXQgaW5zdGFuY2VDb3VudCA9IDA7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBsb2FkQXR0cmlidXRlID0gKGF0dHJpYnV0ZTogc3RyaW5nKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLmF0dHJpYnV0ZXNbYXR0cmlidXRlXSA9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFByb21pc2UucmVzb2x2ZShudWxsKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGFjY2Vzc29yID0gQXJyYXlJdGVtLkdldChgJHtleHRlbnNpb25Db250ZXh0fS9hdHRyaWJ1dGVzLyR7YXR0cmlidXRlfWAsIHRoaXMuX2xvYWRlci5nbHRmLmFjY2Vzc29ycywgZXh0ZW5zaW9uLmF0dHJpYnV0ZXNbYXR0cmlidXRlXSk7XHJcbiAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRlci5fbG9hZEZsb2F0QWNjZXNzb3JBc3luYyhgL2FjY2Vzc29ycy8ke2FjY2Vzc29yLmJ1ZmZlclZpZXd9YCwgYWNjZXNzb3IpKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2VDb3VudCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQ291bnQgPSBhY2Nlc3Nvci5jb3VudDtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaW5zdGFuY2VDb3VudCAhPT0gYWNjZXNzb3IuY291bnQpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXh0ZW5zaW9uQ29udGV4dH0vYXR0cmlidXRlczogSW5zdGFuY2UgYnVmZmVyIGFjY2Vzc29ycyBkbyBub3QgaGF2ZSB0aGUgc2FtZSBjb3VudC5gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJUUkFOU0xBVElPTlwiKTtcclxuICAgICAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlJPVEFUSU9OXCIpO1xyXG4gICAgICAgICAgICBsb2FkQXR0cmlidXRlKFwiU0NBTEVcIik7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZS50aGVuKChiYWJ5bG9uVHJhbnNmb3JtTm9kZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKChbdHJhbnNsYXRpb25CdWZmZXIsIHJvdGF0aW9uQnVmZmVyLCBzY2FsZUJ1ZmZlcl0pID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXRyaWNlcyA9IG5ldyBGbG9hdDMyQXJyYXkoaW5zdGFuY2VDb3VudCAqIDE2KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgVG1wVmVjdG9ycy5WZWN0b3IzWzBdLmNvcHlGcm9tRmxvYXRzKDAsIDAsIDApOyAvLyB0cmFuc2xhdGlvblxyXG4gICAgICAgICAgICAgICAgICAgIFRtcFZlY3RvcnMuUXVhdGVybmlvblswXS5jb3B5RnJvbUZsb2F0cygwLCAwLCAwLCAxKTsgLy8gcm90YXRpb25cclxuICAgICAgICAgICAgICAgICAgICBUbXBWZWN0b3JzLlZlY3RvcjNbMV0uY29weUZyb21GbG9hdHMoMSwgMSwgMSk7IC8vIHNjYWxlXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5zdGFuY2VDb3VudDsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0aW9uQnVmZmVyICYmIFZlY3RvcjMuRnJvbUFycmF5VG9SZWYodHJhbnNsYXRpb25CdWZmZXIsIGkgKiAzLCBUbXBWZWN0b3JzLlZlY3RvcjNbMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByb3RhdGlvbkJ1ZmZlciAmJiBRdWF0ZXJuaW9uLkZyb21BcnJheVRvUmVmKHJvdGF0aW9uQnVmZmVyLCBpICogNCwgVG1wVmVjdG9ycy5RdWF0ZXJuaW9uWzBdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVCdWZmZXIgJiYgVmVjdG9yMy5Gcm9tQXJyYXlUb1JlZihzY2FsZUJ1ZmZlciwgaSAqIDMsIFRtcFZlY3RvcnMuVmVjdG9yM1sxXSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBNYXRyaXguQ29tcG9zZVRvUmVmKFRtcFZlY3RvcnMuVmVjdG9yM1sxXSwgVG1wVmVjdG9ycy5RdWF0ZXJuaW9uWzBdLCBUbXBWZWN0b3JzLlZlY3RvcjNbMF0sIFRtcFZlY3RvcnMuTWF0cml4WzBdKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFRtcFZlY3RvcnMuTWF0cml4WzBdLmNvcHlUb0FycmF5KG1hdHJpY2VzLCBpICogMTYpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBiYWJ5bG9uTWVzaCBvZiBub2RlLl9wcmltaXRpdmVCYWJ5bG9uTWVzaGVzISkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAoYmFieWxvbk1lc2ggYXMgTWVzaCkudGhpbkluc3RhbmNlU2V0QnVmZmVyKFwibWF0cml4XCIsIG1hdHJpY2VzLCAxNiwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYmFieWxvblRyYW5zZm9ybU5vZGU7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEVYVF9tZXNoX2dwdV9pbnN0YW5jaW5nKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IEFycmF5SXRlbSwgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSUJ1ZmZlclZpZXcgfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJRVhUTWVzaG9wdENvbXByZXNzaW9uIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyBNZXNob3B0Q29tcHJlc3Npb24gfSBmcm9tIFwiY29yZS9NZXNoZXMvQ29tcHJlc3Npb24vbWVzaG9wdENvbXByZXNzaW9uXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJFWFRfbWVzaG9wdF9jb21wcmVzc2lvblwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBFWFRfbWVzaG9wdF9jb21wcmVzc2lvbiBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiRVhUX21lc2hvcHRfY29tcHJlc3Npb25cIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG5pbnRlcmZhY2UgSUJ1ZmZlclZpZXdNZXNob3B0IGV4dGVuZHMgSUJ1ZmZlclZpZXcge1xyXG4gICAgX21lc2hPcHREYXRhPzogUHJvbWlzZTxBcnJheUJ1ZmZlclZpZXc+O1xyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvVmVuZG9yL0VYVF9tZXNob3B0X2NvbXByZXNzaW9uL1JFQURNRS5tZClcclxuICpcclxuICogVGhpcyBleHRlbnNpb24gdXNlcyBhIFdlYkFzc2VtYmx5IGRlY29kZXIgbW9kdWxlIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL3pldXgvbWVzaG9wdGltaXplci90cmVlL21hc3Rlci9qc1xyXG4gKiBAc2luY2UgNS4wLjBcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEVYVF9tZXNob3B0X2NvbXByZXNzaW9uIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSBsb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkQnVmZmVyVmlld0FzeW5jKGNvbnRleHQ6IHN0cmluZywgYnVmZmVyVmlldzogSUJ1ZmZlclZpZXcpOiBOdWxsYWJsZTxQcm9taXNlPEFycmF5QnVmZmVyVmlldz4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUVYVE1lc2hvcHRDb21wcmVzc2lvbiwgQXJyYXlCdWZmZXJWaWV3Pihjb250ZXh0LCBidWZmZXJWaWV3LCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgYnVmZmVyVmlld01lc2hvcHQgPSBidWZmZXJWaWV3IGFzIElCdWZmZXJWaWV3TWVzaG9wdDtcclxuICAgICAgICAgICAgaWYgKGJ1ZmZlclZpZXdNZXNob3B0Ll9tZXNoT3B0RGF0YSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlclZpZXdNZXNob3B0Ll9tZXNoT3B0RGF0YTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9idWZmZXJgLCB0aGlzLl9sb2FkZXIuZ2x0Zi5idWZmZXJzLCBleHRlbnNpb24uYnVmZmVyKTtcclxuICAgICAgICAgICAgYnVmZmVyVmlld01lc2hvcHQuX21lc2hPcHREYXRhID0gdGhpcy5fbG9hZGVyLmxvYWRCdWZmZXJBc3luYyhgL2J1ZmZlcnMvJHtidWZmZXIuaW5kZXh9YCwgYnVmZmVyLCBleHRlbnNpb24uYnl0ZU9mZnNldCB8fCAwLCBleHRlbnNpb24uYnl0ZUxlbmd0aCkudGhlbigoYnVmZmVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gTWVzaG9wdENvbXByZXNzaW9uLkRlZmF1bHQuZGVjb2RlR2x0ZkJ1ZmZlckFzeW5jKGJ1ZmZlciBhcyBVaW50OEFycmF5LCBleHRlbnNpb24uY291bnQsIGV4dGVuc2lvbi5ieXRlU3RyaWRlLCBleHRlbnNpb24ubW9kZSwgZXh0ZW5zaW9uLmZpbHRlcik7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlclZpZXdNZXNob3B0Ll9tZXNoT3B0RGF0YTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgRVhUX21lc2hvcHRfY29tcHJlc3Npb24obG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyLCBBcnJheUl0ZW0gfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IElUZXh0dXJlIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgQmFzZVRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvYmFzZVRleHR1cmVcIjtcclxuaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUVYVFRleHR1cmVBVklGIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiRVhUX3RleHR1cmVfYXZpZlwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBFWFRfdGV4dHVyZV9hdmlmIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJFWFRfdGV4dHVyZV9hdmlmXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFtnbFRGIFBSXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvcHVsbC8yMjM1KVxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9WZW5kb3IvRVhUX3RleHR1cmVfYXZpZi9SRUFETUUubWQpXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBFWFRfdGV4dHVyZV9hdmlmIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLiAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC4gKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbG9hZFRleHR1cmVBc3luYyhjb250ZXh0OiBzdHJpbmcsIHRleHR1cmU6IElUZXh0dXJlLCBhc3NpZ246IChiYWJ5bG9uVGV4dHVyZTogQmFzZVRleHR1cmUpID0+IHZvaWQpOiBOdWxsYWJsZTxQcm9taXNlPEJhc2VUZXh0dXJlPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRlbnNpb25Bc3luYzxJRVhUVGV4dHVyZUFWSUYsIEJhc2VUZXh0dXJlPihjb250ZXh0LCB0ZXh0dXJlLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3Qgc2FtcGxlciA9IHRleHR1cmUuc2FtcGxlciA9PSB1bmRlZmluZWQgPyBHTFRGTG9hZGVyLkRlZmF1bHRTYW1wbGVyIDogQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9zYW1wbGVyYCwgdGhpcy5fbG9hZGVyLmdsdGYuc2FtcGxlcnMsIHRleHR1cmUuc2FtcGxlcik7XHJcbiAgICAgICAgICAgIGNvbnN0IGltYWdlID0gQXJyYXlJdGVtLkdldChgJHtleHRlbnNpb25Db250ZXh0fS9zb3VyY2VgLCB0aGlzLl9sb2FkZXIuZ2x0Zi5pbWFnZXMsIGV4dGVuc2lvbi5zb3VyY2UpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGVyLl9jcmVhdGVUZXh0dXJlQXN5bmMoXHJcbiAgICAgICAgICAgICAgICBjb250ZXh0LFxyXG4gICAgICAgICAgICAgICAgc2FtcGxlcixcclxuICAgICAgICAgICAgICAgIGltYWdlLFxyXG4gICAgICAgICAgICAgICAgKGJhYnlsb25UZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXNzaWduKGJhYnlsb25UZXh0dXJlKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICAhdGV4dHVyZS5fdGV4dHVyZUluZm8ubm9uQ29sb3JEYXRhXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEVYVF90ZXh0dXJlX2F2aWYobG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyLCBBcnJheUl0ZW0gfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IElUZXh0dXJlIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgQmFzZVRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvYmFzZVRleHR1cmVcIjtcclxuaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUVYVFRleHR1cmVXZWJQIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiRVhUX3RleHR1cmVfd2VicFwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBFWFRfdGV4dHVyZV93ZWJwIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJFWFRfdGV4dHVyZV93ZWJwXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL1ZlbmRvci9FWFRfdGV4dHVyZV93ZWJwL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEVYVF90ZXh0dXJlX3dlYnAgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKiogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLiAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSBsb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9sb2FkVGV4dHVyZUFzeW5jKGNvbnRleHQ6IHN0cmluZywgdGV4dHVyZTogSVRleHR1cmUsIGFzc2lnbjogKGJhYnlsb25UZXh0dXJlOiBCYXNlVGV4dHVyZSkgPT4gdm9pZCk6IE51bGxhYmxlPFByb21pc2U8QmFzZVRleHR1cmU+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElFWFRUZXh0dXJlV2ViUCwgQmFzZVRleHR1cmU+KGNvbnRleHQsIHRleHR1cmUsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBzYW1wbGVyID0gdGV4dHVyZS5zYW1wbGVyID09IHVuZGVmaW5lZCA/IEdMVEZMb2FkZXIuRGVmYXVsdFNhbXBsZXIgOiBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L3NhbXBsZXJgLCB0aGlzLl9sb2FkZXIuZ2x0Zi5zYW1wbGVycywgdGV4dHVyZS5zYW1wbGVyKTtcclxuICAgICAgICAgICAgY29uc3QgaW1hZ2UgPSBBcnJheUl0ZW0uR2V0KGAke2V4dGVuc2lvbkNvbnRleHR9L3NvdXJjZWAsIHRoaXMuX2xvYWRlci5nbHRmLmltYWdlcywgZXh0ZW5zaW9uLnNvdXJjZSk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIuX2NyZWF0ZVRleHR1cmVBc3luYyhcclxuICAgICAgICAgICAgICAgIGNvbnRleHQsXHJcbiAgICAgICAgICAgICAgICBzYW1wbGVyLFxyXG4gICAgICAgICAgICAgICAgaW1hZ2UsXHJcbiAgICAgICAgICAgICAgICAoYmFieWxvblRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBhc3NpZ24oYmFieWxvblRleHR1cmUpO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgICAgICF0ZXh0dXJlLl90ZXh0dXJlSW5mby5ub25Db2xvckRhdGFcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgRVhUX3RleHR1cmVfd2VicChsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB0eXBlIHsgVHJhbnNmb3JtTm9kZSB9IGZyb20gXCJjb3JlL01lc2hlcy90cmFuc2Zvcm1Ob2RlXCI7XHJcbmltcG9ydCB0eXBlIHsgQ2FtZXJhIH0gZnJvbSBcImNvcmUvQ2FtZXJhcy9jYW1lcmFcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSVByb3BlcnR5IH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElOb2RlLCBJQ2FtZXJhLCBJTWF0ZXJpYWwgfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB0eXBlIHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIkV4dHJhc0FzTWV0YWRhdGFcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgRXh0cmFzQXNNZXRhZGF0YSBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiRXh0cmFzQXNNZXRhZGF0YVwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbmludGVyZmFjZSBPYmplY3RXaXRoTWV0YWRhdGEge1xyXG4gICAgbWV0YWRhdGE6IGFueTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFN0b3JlIGdsVEYgZXh0cmFzIChpZiBwcmVzZW50KSBpbiBCSlMgb2JqZWN0cycgbWV0YWRhdGFcclxuICovXHJcbmV4cG9ydCBjbGFzcyBFeHRyYXNBc01ldGFkYXRhIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkID0gdHJ1ZTtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgcHJpdmF0ZSBfYXNzaWduRXh0cmFzKGJhYnlsb25PYmplY3Q6IE9iamVjdFdpdGhNZXRhZGF0YSwgZ2x0ZlByb3A6IElQcm9wZXJ0eSk6IHZvaWQge1xyXG4gICAgICAgIGlmIChnbHRmUHJvcC5leHRyYXMgJiYgT2JqZWN0LmtleXMoZ2x0ZlByb3AuZXh0cmFzKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG1ldGFkYXRhID0gKGJhYnlsb25PYmplY3QubWV0YWRhdGEgPSBiYWJ5bG9uT2JqZWN0Lm1ldGFkYXRhIHx8IHt9KTtcclxuICAgICAgICAgICAgY29uc3QgZ2x0ZiA9IChtZXRhZGF0YS5nbHRmID0gbWV0YWRhdGEuZ2x0ZiB8fCB7fSk7XHJcbiAgICAgICAgICAgIGdsdGYuZXh0cmFzID0gZ2x0ZlByb3AuZXh0cmFzO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCk6IHZvaWQge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWROb2RlQXN5bmMoY29udGV4dDogc3RyaW5nLCBub2RlOiBJTm9kZSwgYXNzaWduOiAoYmFieWxvblRyYW5zZm9ybU5vZGU6IFRyYW5zZm9ybU5vZGUpID0+IHZvaWQpOiBOdWxsYWJsZTxQcm9taXNlPFRyYW5zZm9ybU5vZGU+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRlci5sb2FkTm9kZUFzeW5jKGNvbnRleHQsIG5vZGUsIChiYWJ5bG9uVHJhbnNmb3JtTm9kZSk6IHZvaWQgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9hc3NpZ25FeHRyYXMoYmFieWxvblRyYW5zZm9ybU5vZGUsIG5vZGUpO1xyXG4gICAgICAgICAgICBhc3NpZ24oYmFieWxvblRyYW5zZm9ybU5vZGUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkQ2FtZXJhQXN5bmMoY29udGV4dDogc3RyaW5nLCBjYW1lcmE6IElDYW1lcmEsIGFzc2lnbjogKGJhYnlsb25DYW1lcmE6IENhbWVyYSkgPT4gdm9pZCk6IE51bGxhYmxlPFByb21pc2U8Q2FtZXJhPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIubG9hZENhbWVyYUFzeW5jKGNvbnRleHQsIGNhbWVyYSwgKGJhYnlsb25DYW1lcmEpOiB2b2lkID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fYXNzaWduRXh0cmFzKGJhYnlsb25DYW1lcmEsIGNhbWVyYSk7XHJcbiAgICAgICAgICAgIGFzc2lnbihiYWJ5bG9uQ2FtZXJhKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY3JlYXRlTWF0ZXJpYWwoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uRHJhd01vZGU6IG51bWJlcik6IE51bGxhYmxlPE1hdGVyaWFsPiB7XHJcbiAgICAgICAgY29uc3QgYmFieWxvbk1hdGVyaWFsID0gdGhpcy5fbG9hZGVyLmNyZWF0ZU1hdGVyaWFsKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uRHJhd01vZGUpO1xyXG4gICAgICAgIHRoaXMuX2Fzc2lnbkV4dHJhcyhiYWJ5bG9uTWF0ZXJpYWwsIG1hdGVyaWFsKTtcclxuICAgICAgICByZXR1cm4gYmFieWxvbk1hdGVyaWFsO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIGZhbHNlLCAobG9hZGVyKSA9PiBuZXcgRXh0cmFzQXNNZXRhZGF0YShsb2FkZXIpKTtcclxuIiwiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXHJcblxyXG5pbXBvcnQgeyBBbmltYXRpb24gfSBmcm9tIFwiY29yZS9BbmltYXRpb25zL2FuaW1hdGlvblwiO1xyXG5pbXBvcnQgdHlwZSB7IElDYW1lcmEsIElLSFJMaWdodHNQdW5jdHVhbF9MaWdodCwgSU1hdGVyaWFsIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUFuaW1hdGFibGUgfSBmcm9tIFwiY29yZS9BbmltYXRpb25zL2FuaW1hdGFibGUuaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IEFuaW1hdGlvblByb3BlcnR5SW5mbywgbm9kZUFuaW1hdGlvbkRhdGEgfSBmcm9tIFwiLi4vZ2xURkxvYWRlckFuaW1hdGlvblwiO1xyXG5pbXBvcnQgeyBDb2xvcjMgfSBmcm9tIFwiY29yZS9NYXRocy9tYXRoLmNvbG9yXCI7XHJcblxyXG5mdW5jdGlvbiBnZXRDb2xvcjMoX3RhcmdldDogYW55LCBzb3VyY2U6IEZsb2F0MzJBcnJheSwgb2Zmc2V0OiBudW1iZXIsIHNjYWxlOiBudW1iZXIpOiBDb2xvcjMge1xyXG4gICAgcmV0dXJuIENvbG9yMy5Gcm9tQXJyYXkoc291cmNlLCBvZmZzZXQpLnNjYWxlKHNjYWxlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0QWxwaGEoX3RhcmdldDogYW55LCBzb3VyY2U6IEZsb2F0MzJBcnJheSwgb2Zmc2V0OiBudW1iZXIsIHNjYWxlOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHNvdXJjZVtvZmZzZXQgKyAzXSAqIHNjYWxlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRGbG9hdChfdGFyZ2V0OiBhbnksIHNvdXJjZTogRmxvYXQzMkFycmF5LCBvZmZzZXQ6IG51bWJlciwgc2NhbGU6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICByZXR1cm4gc291cmNlW29mZnNldF0gKiBzY2FsZTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0TWludXNGbG9hdChfdGFyZ2V0OiBhbnksIHNvdXJjZTogRmxvYXQzMkFycmF5LCBvZmZzZXQ6IG51bWJlciwgc2NhbGU6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICByZXR1cm4gLXNvdXJjZVtvZmZzZXRdICogc2NhbGU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldE5leHRGbG9hdChfdGFyZ2V0OiBhbnksIHNvdXJjZTogRmxvYXQzMkFycmF5LCBvZmZzZXQ6IG51bWJlciwgc2NhbGU6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICByZXR1cm4gc291cmNlW29mZnNldCArIDFdICogc2NhbGU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEZsb2F0QnkyKF90YXJnZXQ6IGFueSwgc291cmNlOiBGbG9hdDMyQXJyYXksIG9mZnNldDogbnVtYmVyLCBzY2FsZTogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgIHJldHVybiBzb3VyY2Vbb2Zmc2V0XSAqIHNjYWxlICogMjtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0VGV4dHVyZVRyYW5zZm9ybVRyZWUodGV4dHVyZU5hbWU6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBzY2FsZTogW1xyXG4gICAgICAgICAgICBuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIGAke3RleHR1cmVOYW1lfS51U2NhbGVgLCBnZXRGbG9hdCwgKCkgPT4gMiksXHJcbiAgICAgICAgICAgIG5ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgYCR7dGV4dHVyZU5hbWV9LnZTY2FsZWAsIGdldE5leHRGbG9hdCwgKCkgPT4gMiksXHJcbiAgICAgICAgXSxcclxuICAgICAgICBvZmZzZXQ6IFtcclxuICAgICAgICAgICAgbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBgJHt0ZXh0dXJlTmFtZX0udU9mZnNldGAsIGdldEZsb2F0LCAoKSA9PiAyKSxcclxuICAgICAgICAgICAgbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBgJHt0ZXh0dXJlTmFtZX0udk9mZnNldGAsIGdldE5leHRGbG9hdCwgKCkgPT4gMiksXHJcbiAgICAgICAgXSxcclxuICAgICAgICByb3RhdGlvbjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgYCR7dGV4dHVyZU5hbWV9LndBbmdgLCBnZXRNaW51c0Zsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICB9O1xyXG59XHJcblxyXG5jbGFzcyBDYW1lcmFBbmltYXRpb25Qcm9wZXJ0eUluZm8gZXh0ZW5kcyBBbmltYXRpb25Qcm9wZXJ0eUluZm8ge1xyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGJ1aWxkQW5pbWF0aW9ucyh0YXJnZXQ6IElDYW1lcmEsIG5hbWU6IHN0cmluZywgZnBzOiBudW1iZXIsIGtleXM6IGFueVtdLCBjYWxsYmFjazogKGJhYnlsb25BbmltYXRhYmxlOiBJQW5pbWF0YWJsZSwgYmFieWxvbkFuaW1hdGlvbjogQW5pbWF0aW9uKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICAgICAgY2FsbGJhY2sodGFyZ2V0Ll9iYWJ5bG9uQ2FtZXJhISwgdGhpcy5fYnVpbGRBbmltYXRpb24obmFtZSwgZnBzLCBrZXlzKSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmNsYXNzIE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvIGV4dGVuZHMgQW5pbWF0aW9uUHJvcGVydHlJbmZvIHtcclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBidWlsZEFuaW1hdGlvbnModGFyZ2V0OiBJTWF0ZXJpYWwsIG5hbWU6IHN0cmluZywgZnBzOiBudW1iZXIsIGtleXM6IGFueVtdLCBjYWxsYmFjazogKGJhYnlsb25BbmltYXRhYmxlOiBJQW5pbWF0YWJsZSwgYmFieWxvbkFuaW1hdGlvbjogQW5pbWF0aW9uKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICAgICAgZm9yIChjb25zdCBmaWxsTW9kZSBpbiB0YXJnZXQuX2RhdGEhKSB7XHJcbiAgICAgICAgICAgIGNhbGxiYWNrKHRhcmdldC5fZGF0YSFbZmlsbE1vZGVdLmJhYnlsb25NYXRlcmlhbCwgdGhpcy5fYnVpbGRBbmltYXRpb24obmFtZSwgZnBzLCBrZXlzKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG5jbGFzcyBMaWdodEFuaW1hdGlvblByb3BlcnR5SW5mbyBleHRlbmRzIEFuaW1hdGlvblByb3BlcnR5SW5mbyB7XHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgYnVpbGRBbmltYXRpb25zKFxyXG4gICAgICAgIHRhcmdldDogSUtIUkxpZ2h0c1B1bmN0dWFsX0xpZ2h0LFxyXG4gICAgICAgIG5hbWU6IHN0cmluZyxcclxuICAgICAgICBmcHM6IG51bWJlcixcclxuICAgICAgICBrZXlzOiBhbnlbXSxcclxuICAgICAgICBjYWxsYmFjazogKGJhYnlsb25BbmltYXRhYmxlOiBJQW5pbWF0YWJsZSwgYmFieWxvbkFuaW1hdGlvbjogQW5pbWF0aW9uKSA9PiB2b2lkXHJcbiAgICApOiB2b2lkIHtcclxuICAgICAgICBjYWxsYmFjayh0YXJnZXQuX2JhYnlsb25MaWdodCEsIHRoaXMuX2J1aWxkQW5pbWF0aW9uKG5hbWUsIGZwcywga2V5cykpO1xyXG4gICAgfVxyXG59XHJcblxyXG5jb25zdCBub2Rlc1RyZWUgPSB7XHJcbiAgICBfX2FycmF5X186IHtcclxuICAgICAgICBfX3RhcmdldF9fOiB0cnVlLFxyXG4gICAgICAgIC4uLm5vZGVBbmltYXRpb25EYXRhLFxyXG4gICAgfSxcclxufTtcclxuXHJcbmNvbnN0IGNhbWVyYXNUcmVlID0ge1xyXG4gICAgX19hcnJheV9fOiB7XHJcbiAgICAgICAgX190YXJnZXRfXzogdHJ1ZSxcclxuICAgICAgICBvcnRob2dyYXBoaWM6IHtcclxuICAgICAgICAgICAgeG1hZzogW1xyXG4gICAgICAgICAgICAgICAgbmV3IENhbWVyYUFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJvcnRob0xlZnRcIiwgZ2V0TWludXNGbG9hdCwgKCkgPT4gMSksXHJcbiAgICAgICAgICAgICAgICBuZXcgQ2FtZXJhQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcIm9ydGhvUmlnaHRcIiwgZ2V0TmV4dEZsb2F0LCAoKSA9PiAxKSxcclxuICAgICAgICAgICAgXSxcclxuICAgICAgICAgICAgeW1hZzogW1xyXG4gICAgICAgICAgICAgICAgbmV3IENhbWVyYUFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJvcnRob0JvdHRvbVwiLCBnZXRNaW51c0Zsb2F0LCAoKSA9PiAxKSxcclxuICAgICAgICAgICAgICAgIG5ldyBDYW1lcmFBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwib3J0aG9Ub3BcIiwgZ2V0TmV4dEZsb2F0LCAoKSA9PiAxKSxcclxuICAgICAgICAgICAgXSxcclxuICAgICAgICAgICAgemZhcjogW25ldyBDYW1lcmFBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwibWF4WlwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICB6bmVhcjogW25ldyBDYW1lcmFBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwibWluWlwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgcGVyc3BlY3RpdmU6IHtcclxuICAgICAgICAgICAgeWZvdjogW25ldyBDYW1lcmFBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwiZm92XCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgIHpmYXI6IFtuZXcgQ2FtZXJhQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcIm1heFpcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgem5lYXI6IFtuZXcgQ2FtZXJhQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcIm1pblpcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICB9LFxyXG4gICAgfSxcclxufTtcclxuXHJcbmNvbnN0IG1hdGVyaWFsc1RyZWUgPSB7XHJcbiAgICBfX2FycmF5X186IHtcclxuICAgICAgICBfX3RhcmdldF9fOiB0cnVlLFxyXG4gICAgICAgIHBick1ldGFsbGljUm91Z2huZXNzOiB7XHJcbiAgICAgICAgICAgIGJhc2VDb2xvckZhY3RvcjogW1xyXG4gICAgICAgICAgICAgICAgbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0NPTE9SMywgXCJhbGJlZG9Db2xvclwiLCBnZXRDb2xvcjMsICgpID0+IDQpLFxyXG4gICAgICAgICAgICAgICAgbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcImFscGhhXCIsIGdldEFscGhhLCAoKSA9PiA0KSxcclxuICAgICAgICAgICAgXSxcclxuICAgICAgICAgICAgbWV0YWxsaWNGYWN0b3I6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwibWV0YWxsaWNcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgcm91Z2huZXNzRmFjdG9yOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcInJvdWdobmVzc1wiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICBiYXNlQ29sb3JUZXh0dXJlOiB7XHJcbiAgICAgICAgICAgICAgICBleHRlbnNpb25zOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcImFsYmVkb1RleHR1cmVcIiksXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBtZXRhbGxpY1JvdWdobmVzc1RleHR1cmU6IHtcclxuICAgICAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgICAgICAgICBLSFJfdGV4dHVyZV90cmFuc2Zvcm06IGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKFwibWV0YWxsaWNUZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVtaXNzaXZlRmFjdG9yOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0NPTE9SMywgXCJlbWlzc2l2ZUNvbG9yXCIsIGdldENvbG9yMywgKCkgPT4gMyldLFxyXG4gICAgICAgIG5vcm1hbFRleHR1cmU6IHtcclxuICAgICAgICAgICAgc2NhbGU6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwiYnVtcFRleHR1cmUubGV2ZWxcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcImJ1bXBUZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgb2NjbHVzaW9uVGV4dHVyZToge1xyXG4gICAgICAgICAgICBzdHJlbmd0aDogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJhbWJpZW50VGV4dHVyZVN0cmVuZ3RoXCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgICAgIEtIUl90ZXh0dXJlX3RyYW5zZm9ybTogZ2V0VGV4dHVyZVRyYW5zZm9ybVRyZWUoXCJhbWJpZW50VGV4dHVyZVwiKSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVtaXNzaXZlVGV4dHVyZToge1xyXG4gICAgICAgICAgICBleHRlbnNpb25zOiB7XHJcbiAgICAgICAgICAgICAgICBLSFJfdGV4dHVyZV90cmFuc2Zvcm06IGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKFwiZW1pc3NpdmVUZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICBLSFJfbWF0ZXJpYWxzX2FuaXNvdHJvcHk6IHtcclxuICAgICAgICAgICAgICAgIGFuaXNvdHJvcHlTdHJlbmd0aDogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJhbmlzb3Ryb3B5LmludGVuc2l0eVwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICAgICAgYW5pc290cm9weVJvdGF0aW9uOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcImFuaXNvdHJvcHkuYW5nbGVcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIGFuaXNvdHJvcHlUZXh0dXJlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBLSFJfdGV4dHVyZV90cmFuc2Zvcm06IGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKFwiYW5pc290cm9weS50ZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBLSFJfbWF0ZXJpYWxzX2NsZWFyY29hdDoge1xyXG4gICAgICAgICAgICAgICAgY2xlYXJjb2F0RmFjdG9yOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcImNsZWFyQ29hdC5pbnRlbnNpdHlcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIGNsZWFyY29hdFJvdWdobmVzc0ZhY3RvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJjbGVhckNvYXQucm91Z2huZXNzXCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgICAgICBjbGVhcmNvYXRUZXh0dXJlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBLSFJfdGV4dHVyZV90cmFuc2Zvcm06IGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKFwiY2xlYXJDb2F0LnRleHR1cmVcIiksXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBjbGVhcmNvYXROb3JtYWxUZXh0dXJlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2NhbGU6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwiY2xlYXJDb2F0LmJ1bXBUZXh0dXJlLmxldmVsXCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBLSFJfdGV4dHVyZV90cmFuc2Zvcm06IGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKFwiY2xlYXJDb2F0LmJ1bXBUZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgY2xlYXJjb2F0Um91Z2huZXNzVGV4dHVyZToge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcImNsZWFyQ29hdC50ZXh0dXJlUm91Z2huZXNzXCIpLFxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBLSFJfbWF0ZXJpYWxzX2Rpc3BlcnNpb246IHtcclxuICAgICAgICAgICAgICAgIGRpc3BlcnNpb246IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwic3ViU3VyZmFjZS5kaXNwZXJzaW9uXCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIEtIUl9tYXRlcmlhbHNfZW1pc3NpdmVfc3RyZW5ndGg6IHtcclxuICAgICAgICAgICAgICAgIGVtaXNzaXZlU3RyZW5ndGg6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwiZW1pc3NpdmVJbnRlbnNpdHlcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgS0hSX21hdGVyaWFsc19pb3I6IHtcclxuICAgICAgICAgICAgICAgIGlvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJpbmRleE9mUmVmcmFjdGlvblwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBLSFJfbWF0ZXJpYWxzX2lyaWRlc2NlbmNlOiB7XHJcbiAgICAgICAgICAgICAgICBpcmlkZXNjZW5jZUZhY3RvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJpcmlkZXNjZW5jZS5pbnRlbnNpdHlcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIGlyaWRlc2NlbmNlSW9yOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcImlyaWRlc2NlbmNlLmluZGV4T2ZSZWZyYWN0aW9uXCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgICAgICBpcmlkZXNjZW5jZVRoaWNrbmVzc01pbmltdW06IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwiaXJpZGVzY2VuY2UubWluaW11bVRoaWNrbmVzc1wiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICAgICAgaXJpZGVzY2VuY2VUaGlja25lc3NNYXhpbXVtOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcImlyaWRlc2NlbmNlLm1heGltdW1UaGlja25lc3NcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIGlyaWRlc2NlbmNlVGV4dHVyZToge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcImlyaWRlc2NlbmNlLnRleHR1cmVcIiksXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBpcmlkZXNjZW5jZVRoaWNrbmVzc1RleHR1cmU6IHtcclxuICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEtIUl90ZXh0dXJlX3RyYW5zZm9ybTogZ2V0VGV4dHVyZVRyYW5zZm9ybVRyZWUoXCJpcmlkZXNjZW5jZS50aGlja25lc3NUZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBLSFJfbWF0ZXJpYWxzX3NoZWVuOiB7XHJcbiAgICAgICAgICAgICAgICBzaGVlbkNvbG9yRmFjdG9yOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0NPTE9SMywgXCJzaGVlbi5jb2xvclwiLCBnZXRDb2xvcjMsICgpID0+IDMpXSxcclxuICAgICAgICAgICAgICAgIHNoZWVuUm91Z2huZXNzRmFjdG9yOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcInNoZWVuLnJvdWdobmVzc1wiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICAgICAgc2hlZW5Db2xvclRleHR1cmU6IHtcclxuICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEtIUl90ZXh0dXJlX3RyYW5zZm9ybTogZ2V0VGV4dHVyZVRyYW5zZm9ybVRyZWUoXCJzaGVlbi50ZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgc2hlZW5Sb3VnaG5lc3NUZXh0dXJlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBLSFJfdGV4dHVyZV90cmFuc2Zvcm06IGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKFwic2hlZW4udGV4dHVyZVJvdWdobmVzc1wiKSxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgS0hSX21hdGVyaWFsc19zcGVjdWxhcjoge1xyXG4gICAgICAgICAgICAgICAgc3BlY3VsYXJGYWN0b3I6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwibWV0YWxsaWNGMEZhY3RvclwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICAgICAgc3BlY3VsYXJDb2xvckZhY3RvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9DT0xPUjMsIFwibWV0YWxsaWNSZWZsZWN0YW5jZUNvbG9yXCIsIGdldENvbG9yMywgKCkgPT4gMyldLFxyXG4gICAgICAgICAgICAgICAgc3BlY3VsYXJUZXh0dXJlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBLSFJfdGV4dHVyZV90cmFuc2Zvcm06IGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKFwibWV0YWxsaWNSZWZsZWN0YW5jZVRleHR1cmVcIiksXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBzcGVjdWxhckNvbG9yVGV4dHVyZToge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcInJlZmxlY3RhbmNlVGV4dHVyZVwiKSxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgS0hSX21hdGVyaWFsc190cmFuc21pc3Npb246IHtcclxuICAgICAgICAgICAgICAgIHRyYW5zbWlzc2lvbkZhY3RvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJzdWJTdXJmYWNlLnJlZnJhY3Rpb25JbnRlbnNpdHlcIiwgZ2V0RmxvYXQsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgIHRyYW5zbWlzc2lvblRleHR1cmU6IHtcclxuICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEtIUl90ZXh0dXJlX3RyYW5zZm9ybTogZ2V0VGV4dHVyZVRyYW5zZm9ybVRyZWUoXCJzdWJTdXJmYWNlLnJlZnJhY3Rpb25JbnRlbnNpdHlUZXh0dXJlXCIpLFxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBLSFJfbWF0ZXJpYWxzX3ZvbHVtZToge1xyXG4gICAgICAgICAgICAgICAgYXR0ZW51YXRpb25Db2xvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9DT0xPUjMsIFwic3ViU3VyZmFjZS50aW50Q29sb3JcIiwgZ2V0Q29sb3IzLCAoKSA9PiAzKV0sXHJcbiAgICAgICAgICAgICAgICBhdHRlbnVhdGlvbkRpc3RhbmNlOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcInN1YlN1cmZhY2UudGludENvbG9yQXREaXN0YW5jZVwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICAgICAgdGhpY2tuZXNzRmFjdG9yOiBbbmV3IE1hdGVyaWFsQW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcInN1YlN1cmZhY2UubWF4aW11bVRoaWNrbmVzc1wiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICAgICAgdGhpY2tuZXNzVGV4dHVyZToge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgS0hSX3RleHR1cmVfdHJhbnNmb3JtOiBnZXRUZXh0dXJlVHJhbnNmb3JtVHJlZShcInN1YlN1cmZhY2UudGhpY2tuZXNzVGV4dHVyZVwiKSxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgS0hSX21hdGVyaWFsc19kaWZmdXNlX3RyYW5zbWlzc2lvbjoge1xyXG4gICAgICAgICAgICAgICAgZGlmZnVzZVRyYW5zbWlzc2lvbkZhY3RvcjogW25ldyBNYXRlcmlhbEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJzdWJTdXJmYWNlLnRyYW5zbHVjZW5jeUludGVuc2l0eVwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICAgICAgZGlmZnVzZVRyYW5zbWlzc2lvblRleHR1cmU6IHtcclxuICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEtIUl90ZXh0dXJlX3RyYW5zZm9ybTogZ2V0VGV4dHVyZVRyYW5zZm9ybVRyZWUoXCJzdWJTdXJmYWNlLnRyYW5zbHVjZW5jeUludGVuc2l0eVRleHR1cmVcIiksXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBkaWZmdXNlVHJhbnNtaXNzaW9uQ29sb3JGYWN0b3I6IFtuZXcgTWF0ZXJpYWxBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfQ09MT1IzLCBcInN1YlN1cmZhY2UudHJhbnNsdWNlbmN5Q29sb3JcIiwgZ2V0Q29sb3IzLCAoKSA9PiAzKV0sXHJcbiAgICAgICAgICAgICAgICBkaWZmdXNlVHJhbnNtaXNzaW9uQ29sb3JUZXh0dXJlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBLSFJfdGV4dHVyZV90cmFuc2Zvcm06IGdldFRleHR1cmVUcmFuc2Zvcm1UcmVlKFwic3ViU3VyZmFjZS50cmFuc2x1Y2VuY3lDb2xvclRleHR1cmVcIiksXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgfSxcclxuICAgIH0sXHJcbn07XHJcblxyXG5jb25zdCBleHRlbnNpb25zVHJlZSA9IHtcclxuICAgIEtIUl9saWdodHNfcHVuY3R1YWw6IHtcclxuICAgICAgICBsaWdodHM6IHtcclxuICAgICAgICAgICAgX19hcnJheV9fOiB7XHJcbiAgICAgICAgICAgICAgICBfX3RhcmdldF9fOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgY29sb3I6IFtuZXcgTGlnaHRBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfQ09MT1IzLCBcImRpZmZ1c2VcIiwgZ2V0Q29sb3IzLCAoKSA9PiAzKV0sXHJcbiAgICAgICAgICAgICAgICBpbnRlbnNpdHk6IFtuZXcgTGlnaHRBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwiaW50ZW5zaXR5XCIsIGdldEZsb2F0LCAoKSA9PiAxKV0sXHJcbiAgICAgICAgICAgICAgICByYW5nZTogW25ldyBMaWdodEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJyYW5nZVwiLCBnZXRGbG9hdCwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICAgICAgc3BvdDoge1xyXG4gICAgICAgICAgICAgICAgICAgIGlubmVyQ29uZUFuZ2xlOiBbbmV3IExpZ2h0QW5pbWF0aW9uUHJvcGVydHlJbmZvKEFuaW1hdGlvbi5BTklNQVRJT05UWVBFX0ZMT0FULCBcImlubmVyQW5nbGVcIiwgZ2V0RmxvYXRCeTIsICgpID0+IDEpXSxcclxuICAgICAgICAgICAgICAgICAgICBvdXRlckNvbmVBbmdsZTogW25ldyBMaWdodEFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9GTE9BVCwgXCJhbmdsZVwiLCBnZXRGbG9hdEJ5MiwgKCkgPT4gMSldLFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgfSxcclxufTtcclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGNvbnN0IGFuaW1hdGlvblBvaW50ZXJUcmVlID0ge1xyXG4gICAgbm9kZXM6IG5vZGVzVHJlZSxcclxuICAgIG1hdGVyaWFsczogbWF0ZXJpYWxzVHJlZSxcclxuICAgIGNhbWVyYXM6IGNhbWVyYXNUcmVlLFxyXG4gICAgZXh0ZW5zaW9uczogZXh0ZW5zaW9uc1RyZWUsXHJcbn07XHJcbiIsImltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgdHlwZSB7IEdMVEZMb2FkZXIgfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBBbmltYXRpb24gfSBmcm9tIFwiY29yZS9BbmltYXRpb25zL2FuaW1hdGlvblwiO1xyXG5pbXBvcnQgdHlwZSB7IElBbmltYXRhYmxlIH0gZnJvbSBcImNvcmUvQW5pbWF0aW9ucy9hbmltYXRhYmxlLmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElBbmltYXRpb24sIElBbmltYXRpb25DaGFubmVsLCBJR0xURiB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElLSFJBbmltYXRpb25Qb2ludGVyIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyBBbmltYXRpb25DaGFubmVsVGFyZ2V0UGF0aCB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcImNvcmUvTWlzYy9sb2dnZXJcIjtcclxuaW1wb3J0IHsgYW5pbWF0aW9uUG9pbnRlclRyZWUgfSBmcm9tIFwiLi9LSFJfYW5pbWF0aW9uX3BvaW50ZXIuZGF0YVwiO1xyXG5pbXBvcnQgeyBHTFRGUGF0aFRvT2JqZWN0Q29udmVydGVyIH0gZnJvbSBcIi4vZ2x0ZlBhdGhUb09iamVjdENvbnZlcnRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IEFuaW1hdGlvblByb3BlcnR5SW5mbyB9IGZyb20gXCIuLi9nbFRGTG9hZGVyQW5pbWF0aW9uXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfYW5pbWF0aW9uX3BvaW50ZXJcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX2FuaW1hdGlvbl9wb2ludGVyIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJLSFJfYW5pbWF0aW9uX3BvaW50ZXJcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogQ2xhc3MgdG8gY29udmVydCBhbiBhbmltYXRpb24gcG9pbnRlciBwYXRoIHRvIGEgc21hcnQgb2JqZWN0IHRoYXRcclxuICogZ2V0cyBkYXRhIGZyb20gdGhlIGFuaW1hdGlvbiBidWZmZXIgYW5kIGNyZWF0ZXMgYW5pbWF0aW9ucy5cclxuICovXHJcbmNsYXNzIEFuaW1hdGlvblBvaW50ZXJQYXRoVG9PYmplY3RDb252ZXJ0ZXIgZXh0ZW5kcyBHTFRGUGF0aFRvT2JqZWN0Q29udmVydGVyPEFuaW1hdGlvblByb3BlcnR5SW5mb1tdPiB7XHJcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoZ2x0ZjogSUdMVEYpIHtcclxuICAgICAgICBzdXBlcihnbHRmLCBhbmltYXRpb25Qb2ludGVyVHJlZSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbiBQUl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL3B1bGwvMjE0NylcclxuICogISEhIEV4cGVyaW1lbnRhbCBFeHRlbnNpb24gU3ViamVjdCB0byBDaGFuZ2VzICEhIVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX2FuaW1hdGlvbl9wb2ludGVyIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuICAgIHByaXZhdGUgX3BhdGhUb09iamVjdENvbnZlcnRlcj86IEFuaW1hdGlvblBvaW50ZXJQYXRoVG9PYmplY3RDb252ZXJ0ZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuX3BhdGhUb09iamVjdENvbnZlcnRlciA9IG5ldyBBbmltYXRpb25Qb2ludGVyUGF0aFRvT2JqZWN0Q29udmVydGVyKHRoaXMuX2xvYWRlci5nbHRmKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IGVuYWJsZWQoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgICAgICBkZWxldGUgdGhpcy5fcGF0aFRvT2JqZWN0Q29udmVydGVyOyAvLyBHQ1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9hZHMgYSBnbFRGIGFuaW1hdGlvbiBjaGFubmVsLlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIGFuaW1hdGlvbkNvbnRleHQgVGhlIGNvbnRleHQgb2YgdGhlIGFuaW1hdGlvbiB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gYW5pbWF0aW9uIFRoZSBnbFRGIGFuaW1hdGlvbiBwcm9wZXJ0eVxyXG4gICAgICogQHBhcmFtIGNoYW5uZWwgVGhlIGdsVEYgYW5pbWF0aW9uIGNoYW5uZWwgcHJvcGVydHlcclxuICAgICAqIEBwYXJhbSBvbkxvYWQgQ2FsbGVkIGZvciBlYWNoIGFuaW1hdGlvbiBsb2FkZWRcclxuICAgICAqIEByZXR1cm5zIEEgdm9pZCBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgbG9hZCBpcyBjb21wbGV0ZSBvciBudWxsIGlmIG5vdCBoYW5kbGVkXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbG9hZEFuaW1hdGlvbkNoYW5uZWxBc3luYyhcclxuICAgICAgICBjb250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgYW5pbWF0aW9uQ29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIGFuaW1hdGlvbjogSUFuaW1hdGlvbixcclxuICAgICAgICBjaGFubmVsOiBJQW5pbWF0aW9uQ2hhbm5lbCxcclxuICAgICAgICBvbkxvYWQ6IChiYWJ5bG9uQW5pbWF0YWJsZTogSUFuaW1hdGFibGUsIGJhYnlsb25BbmltYXRpb246IEFuaW1hdGlvbikgPT4gdm9pZFxyXG4gICAgKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IGNoYW5uZWwudGFyZ2V0LmV4dGVuc2lvbnM/LktIUl9hbmltYXRpb25fcG9pbnRlciBhcyBJS0hSQW5pbWF0aW9uUG9pbnRlcjtcclxuICAgICAgICBpZiAoIWV4dGVuc2lvbiB8fCAhdGhpcy5fcGF0aFRvT2JqZWN0Q29udmVydGVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGNoYW5uZWwudGFyZ2V0LnBhdGggIT09IEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLlBPSU5URVIpIHtcclxuICAgICAgICAgICAgTG9nZ2VyLldhcm4oYCR7Y29udGV4dH0vdGFyZ2V0L3BhdGg6IFZhbHVlICgke2NoYW5uZWwudGFyZ2V0LnBhdGh9KSBtdXN0IGJlICgke0FuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLlBPSU5URVJ9KSB3aGVuIHVzaW5nIHRoZSAke3RoaXMubmFtZX0gZXh0ZW5zaW9uYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoY2hhbm5lbC50YXJnZXQubm9kZSAhPSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgTG9nZ2VyLldhcm4oYCR7Y29udGV4dH0vdGFyZ2V0L25vZGU6IFZhbHVlICgke2NoYW5uZWwudGFyZ2V0Lm5vZGV9KSBtdXN0IG5vdCBiZSBwcmVzZW50IHdoZW4gdXNpbmcgdGhlICR7dGhpcy5uYW1lfSBleHRlbnNpb25gKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbkNvbnRleHQgPSBgJHtjb250ZXh0fS9leHRlbnNpb25zLyR7dGhpcy5uYW1lfWA7XHJcblxyXG4gICAgICAgIGNvbnN0IHBvaW50ZXIgPSBleHRlbnNpb24ucG9pbnRlcjtcclxuICAgICAgICBpZiAoIXBvaW50ZXIpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2V4dGVuc2lvbkNvbnRleHR9OiBQb2ludGVyIGlzIG1pc3NpbmdgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldEluZm8gPSB0aGlzLl9wYXRoVG9PYmplY3RDb252ZXJ0ZXIuY29udmVydChwb2ludGVyKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRlci5fbG9hZEFuaW1hdGlvbkNoYW5uZWxGcm9tVGFyZ2V0SW5mb0FzeW5jKGNvbnRleHQsIGFuaW1hdGlvbkNvbnRleHQsIGFuaW1hdGlvbiwgY2hhbm5lbCwgdGFyZ2V0SW5mbywgb25Mb2FkKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIExvZ2dlci5XYXJuKGAke2V4dGVuc2lvbkNvbnRleHR9L3BvaW50ZXI6IEludmFsaWQgcG9pbnRlciAoJHtwb2ludGVyfSkgc2tpcHBlZGApO1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl9hbmltYXRpb25fcG9pbnRlcihsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHsgRHJhY29Db21wcmVzc2lvbiB9IGZyb20gXCJjb3JlL01lc2hlcy9Db21wcmVzc2lvbi9kcmFjb0NvbXByZXNzaW9uXCI7XHJcbmltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBWZXJ0ZXhCdWZmZXIgfSBmcm9tIFwiY29yZS9CdWZmZXJzL2J1ZmZlclwiO1xyXG5pbXBvcnQgdHlwZSB7IEdlb21ldHJ5IH0gZnJvbSBcImNvcmUvTWVzaGVzL2dlb21ldHJ5XCI7XHJcbmltcG9ydCB0eXBlIHsgTWVzaCB9IGZyb20gXCJjb3JlL01lc2hlcy9tZXNoXCI7XHJcblxyXG5pbXBvcnQgeyBNZXNoUHJpbWl0aXZlTW9kZSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSRHJhY29NZXNoQ29tcHJlc3Npb24gfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB0eXBlIHsgSU1lc2hQcmltaXRpdmUsIElCdWZmZXJWaWV3IH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyLCBBcnJheUl0ZW0gfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX2RyYWNvX21lc2hfY29tcHJlc3Npb25cIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX2RyYWNvX21lc2hfY29tcHJlc3Npb24gZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9kcmFjb19tZXNoX2NvbXByZXNzaW9uXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuaW50ZXJmYWNlIElCdWZmZXJWaWV3RHJhY28gZXh0ZW5kcyBJQnVmZmVyVmlldyB7XHJcbiAgICBfZHJhY29CYWJ5bG9uR2VvbWV0cnk/OiBQcm9taXNlPEdlb21ldHJ5PjtcclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0tocm9ub3MvS0hSX2RyYWNvX21lc2hfY29tcHJlc3Npb24vUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX2RyYWNvX21lc2hfY29tcHJlc3Npb24gaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgZHJhY28gY29tcHJlc3Npb24gdXNlZCB0byBkZWNvZGUgdmVydGV4IGRhdGEgb3IgRHJhY29Db21wcmVzc2lvbi5EZWZhdWx0IGlmIG5vdCBkZWZpbmVkXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkcmFjb0NvbXByZXNzaW9uPzogRHJhY29Db21wcmVzc2lvbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0byB1c2UgdGhlIG5vcm1hbGl6ZWQgZmxhZyBmcm9tIHRoZSBnbFRGIGFjY2Vzc29yIGluc3RlYWQgb2YgdGhlIERyYWNvIGRhdGEuIERlZmF1bHRzIHRvIHRydWUuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB1c2VOb3JtYWxpemVkRmxhZ0Zyb21BY2Nlc3NvciA9IHRydWU7XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSBEcmFjb0NvbXByZXNzaW9uLkRlY29kZXJBdmFpbGFibGUgJiYgdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpOiB2b2lkIHtcclxuICAgICAgICBkZWxldGUgdGhpcy5kcmFjb0NvbXByZXNzaW9uO1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9sb2FkVmVydGV4RGF0YUFzeW5jKGNvbnRleHQ6IHN0cmluZywgcHJpbWl0aXZlOiBJTWVzaFByaW1pdGl2ZSwgYmFieWxvbk1lc2g6IE1lc2gpOiBOdWxsYWJsZTxQcm9taXNlPEdlb21ldHJ5Pj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRlbnNpb25Bc3luYzxJS0hSRHJhY29NZXNoQ29tcHJlc3Npb24sIEdlb21ldHJ5Pihjb250ZXh0LCBwcmltaXRpdmUsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBpZiAocHJpbWl0aXZlLm1vZGUgIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocHJpbWl0aXZlLm1vZGUgIT09IE1lc2hQcmltaXRpdmVNb2RlLlRSSUFOR0xFUyAmJiBwcmltaXRpdmUubW9kZSAhPT0gTWVzaFByaW1pdGl2ZU1vZGUuVFJJQU5HTEVfU1RSSVApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IFVuc3VwcG9ydGVkIG1vZGUgJHtwcmltaXRpdmUubW9kZX1gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgYXR0cmlidXRlczogeyBba2luZDogc3RyaW5nXTogbnVtYmVyIH0gPSB7fTtcclxuICAgICAgICAgICAgY29uc3Qgbm9ybWFsaXplZDogeyBba2luZDogc3RyaW5nXTogYm9vbGVhbiB9ID0ge307XHJcbiAgICAgICAgICAgIGNvbnN0IGxvYWRBdHRyaWJ1dGUgPSAobmFtZTogc3RyaW5nLCBraW5kOiBzdHJpbmcpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHVuaXF1ZUlkID0gZXh0ZW5zaW9uLmF0dHJpYnV0ZXNbbmFtZV07XHJcbiAgICAgICAgICAgICAgICBpZiAodW5pcXVlSWQgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGJhYnlsb25NZXNoLl9kZWxheUluZm8gPSBiYWJ5bG9uTWVzaC5fZGVsYXlJbmZvIHx8IFtdO1xyXG4gICAgICAgICAgICAgICAgaWYgKGJhYnlsb25NZXNoLl9kZWxheUluZm8uaW5kZXhPZihraW5kKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWVzaC5fZGVsYXlJbmZvLnB1c2goa2luZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlc1traW5kXSA9IHVuaXF1ZUlkO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnVzZU5vcm1hbGl6ZWRGbGFnRnJvbUFjY2Vzc29yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWNjZXNzb3IgPSBBcnJheUl0ZW0uVHJ5R2V0KHRoaXMuX2xvYWRlci5nbHRmLmFjY2Vzc29ycywgcHJpbWl0aXZlLmF0dHJpYnV0ZXNbbmFtZV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhY2Nlc3Nvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkW2tpbmRdID0gYWNjZXNzb3Iubm9ybWFsaXplZCB8fCBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBsb2FkQXR0cmlidXRlKFwiUE9TSVRJT05cIiwgVmVydGV4QnVmZmVyLlBvc2l0aW9uS2luZCk7XHJcbiAgICAgICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJOT1JNQUxcIiwgVmVydGV4QnVmZmVyLk5vcm1hbEtpbmQpO1xyXG4gICAgICAgICAgICBsb2FkQXR0cmlidXRlKFwiVEFOR0VOVFwiLCBWZXJ0ZXhCdWZmZXIuVGFuZ2VudEtpbmQpO1xyXG4gICAgICAgICAgICBsb2FkQXR0cmlidXRlKFwiVEVYQ09PUkRfMFwiLCBWZXJ0ZXhCdWZmZXIuVVZLaW5kKTtcclxuICAgICAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlRFWENPT1JEXzFcIiwgVmVydGV4QnVmZmVyLlVWMktpbmQpO1xyXG4gICAgICAgICAgICBsb2FkQXR0cmlidXRlKFwiVEVYQ09PUkRfMlwiLCBWZXJ0ZXhCdWZmZXIuVVYzS2luZCk7XHJcbiAgICAgICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJURVhDT09SRF8zXCIsIFZlcnRleEJ1ZmZlci5VVjRLaW5kKTtcclxuICAgICAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlRFWENPT1JEXzRcIiwgVmVydGV4QnVmZmVyLlVWNUtpbmQpO1xyXG4gICAgICAgICAgICBsb2FkQXR0cmlidXRlKFwiVEVYQ09PUkRfNVwiLCBWZXJ0ZXhCdWZmZXIuVVY2S2luZCk7XHJcbiAgICAgICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJKT0lOVFNfMFwiLCBWZXJ0ZXhCdWZmZXIuTWF0cmljZXNJbmRpY2VzS2luZCk7XHJcbiAgICAgICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJXRUlHSFRTXzBcIiwgVmVydGV4QnVmZmVyLk1hdHJpY2VzV2VpZ2h0c0tpbmQpO1xyXG4gICAgICAgICAgICBsb2FkQXR0cmlidXRlKFwiQ09MT1JfMFwiLCBWZXJ0ZXhCdWZmZXIuQ29sb3JLaW5kKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlclZpZXcgPSBBcnJheUl0ZW0uR2V0KGV4dGVuc2lvbkNvbnRleHQsIHRoaXMuX2xvYWRlci5nbHRmLmJ1ZmZlclZpZXdzLCBleHRlbnNpb24uYnVmZmVyVmlldykgYXMgSUJ1ZmZlclZpZXdEcmFjbztcclxuICAgICAgICAgICAgaWYgKCFidWZmZXJWaWV3Ll9kcmFjb0JhYnlsb25HZW9tZXRyeSkge1xyXG4gICAgICAgICAgICAgICAgYnVmZmVyVmlldy5fZHJhY29CYWJ5bG9uR2VvbWV0cnkgPSB0aGlzLl9sb2FkZXIubG9hZEJ1ZmZlclZpZXdBc3luYyhgL2J1ZmZlclZpZXdzLyR7YnVmZmVyVmlldy5pbmRleH1gLCBidWZmZXJWaWV3KS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZHJhY29Db21wcmVzc2lvbiA9IHRoaXMuZHJhY29Db21wcmVzc2lvbiB8fCBEcmFjb0NvbXByZXNzaW9uLkRlZmF1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRyYWNvQ29tcHJlc3Npb24uX2RlY29kZU1lc2hUb0dlb21ldHJ5Rm9yR2x0ZkFzeW5jKGJhYnlsb25NZXNoLm5hbWUsIHRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmUsIGRhdGEsIGF0dHJpYnV0ZXMsIG5vcm1hbGl6ZWQpLmNhdGNoKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06ICR7ZXJyb3IubWVzc2FnZX1gKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gYnVmZmVyVmlldy5fZHJhY29CYWJ5bG9uR2VvbWV0cnk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl9kcmFjb19tZXNoX2NvbXByZXNzaW9uKGxvYWRlcikpO1xyXG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24gKi9cclxuaW1wb3J0IHR5cGUgeyBJS0hSSW50ZXJhY3Rpdml0eSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHR5cGUgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaENvb3JkaW5hdG9yIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL2Zsb3dHcmFwaENvb3JkaW5hdG9yXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaCB9IGZyb20gXCJjb3JlL0Zsb3dHcmFwaC9mbG93R3JhcGhcIjtcclxuaW1wb3J0IHsgY29udmVydEdMVEZUb1NlcmlhbGl6ZWRGbG93R3JhcGggfSBmcm9tIFwiLi9pbnRlcmFjdGl2aXR5RnVuY3Rpb25zXCI7XHJcbmltcG9ydCB7IEludGVyYWN0aXZpdHlQYXRoVG9PYmplY3RDb252ZXJ0ZXIgfSBmcm9tIFwiLi9pbnRlcmFjdGl2aXR5UGF0aFRvT2JqZWN0Q29udmVydGVyXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfaW50ZXJhY3Rpdml0eVwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfaW50ZXJhY3Rpdml0eSBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiS0hSX2ludGVyYWN0aXZpdHlcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogTG9hZGVyIGV4dGVuc2lvbiBmb3IgS0hSX2ludGVyYWN0aXZpdHlcclxuICovXHJcbmV4cG9ydCBjbGFzcyBLSFJfaW50ZXJhY3Rpdml0eSBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIHByaXZhdGUgX3BhdGhDb252ZXJ0ZXI/OiBJbnRlcmFjdGl2aXR5UGF0aFRvT2JqZWN0Q29udmVydGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKiBAcGFyYW0gX2xvYWRlclxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgICAgIHRoaXMuX3BhdGhDb252ZXJ0ZXIgPSBuZXcgSW50ZXJhY3Rpdml0eVBhdGhUb09iamVjdENvbnZlcnRlcih0aGlzLl9sb2FkZXIuZ2x0Zik7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgICAgICBkZWxldGUgdGhpcy5fcGF0aENvbnZlcnRlcjtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgb25SZWFkeSgpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmUgfHwgIXRoaXMuX3BhdGhDb252ZXJ0ZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBzY2VuZSA9IHRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmU7XHJcbiAgICAgICAgY29uc3QgaW50ZXJhY3Rpdml0eURlZmluaXRpb24gPSB0aGlzLl9sb2FkZXIuZ2x0Zi5leHRlbnNpb25zPy5LSFJfaW50ZXJhY3Rpdml0eSBhcyBJS0hSSW50ZXJhY3Rpdml0eTtcclxuXHJcbiAgICAgICAgY29uc3QganNvbiA9IGNvbnZlcnRHTFRGVG9TZXJpYWxpemVkRmxvd0dyYXBoKGludGVyYWN0aXZpdHlEZWZpbml0aW9uKTtcclxuICAgICAgICBjb25zdCBjb29yZGluYXRvciA9IG5ldyBGbG93R3JhcGhDb29yZGluYXRvcih7IHNjZW5lIH0pO1xyXG4gICAgICAgIEZsb3dHcmFwaC5QYXJzZShqc29uLCB7IGNvb3JkaW5hdG9yLCBwYXRoQ29udmVydGVyOiB0aGlzLl9wYXRoQ29udmVydGVyIH0pO1xyXG5cclxuICAgICAgICBjb29yZGluYXRvci5zdGFydCgpO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfaW50ZXJhY3Rpdml0eShsb2FkZXIpKTtcclxuIiwiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXHJcbmltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBWZWN0b3IzIH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC52ZWN0b3JcIjtcclxuaW1wb3J0IHsgQ29sb3IzIH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC5jb2xvclwiO1xyXG5pbXBvcnQgeyBEaXJlY3Rpb25hbExpZ2h0IH0gZnJvbSBcImNvcmUvTGlnaHRzL2RpcmVjdGlvbmFsTGlnaHRcIjtcclxuaW1wb3J0IHsgUG9pbnRMaWdodCB9IGZyb20gXCJjb3JlL0xpZ2h0cy9wb2ludExpZ2h0XCI7XHJcbmltcG9ydCB7IFNwb3RMaWdodCB9IGZyb20gXCJjb3JlL0xpZ2h0cy9zcG90TGlnaHRcIjtcclxuaW1wb3J0IHsgTGlnaHQgfSBmcm9tIFwiY29yZS9MaWdodHMvbGlnaHRcIjtcclxuaW1wb3J0IHR5cGUgeyBUcmFuc2Zvcm1Ob2RlIH0gZnJvbSBcImNvcmUvTWVzaGVzL3RyYW5zZm9ybU5vZGVcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSUtIUkxpZ2h0c1B1bmN0dWFsX0xpZ2h0UmVmZXJlbmNlIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyBLSFJMaWdodHNQdW5jdHVhbF9MaWdodFR5cGUgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB0eXBlIHsgSU5vZGUsIElLSFJMaWdodHNQdW5jdHVhbF9MaWdodCB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciwgQXJyYXlJdGVtIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl9saWdodHNfcHVuY3R1YWxcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX2xpZ2h0c19wdW5jdHVhbCBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiS0hSX2xpZ2h0c19wdW5jdHVhbFwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl9saWdodHNfcHVuY3R1YWwvUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX2xpZ2h0cyBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICAvKiogaGlkZGVuICovXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcbiAgICBwcml2YXRlIF9saWdodHM/OiBJS0hSTGlnaHRzUHVuY3R1YWxfTGlnaHRbXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgICAgIGRlbGV0ZSB0aGlzLl9saWdodHM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIG9uTG9hZGluZygpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25zID0gdGhpcy5fbG9hZGVyLmdsdGYuZXh0ZW5zaW9ucztcclxuICAgICAgICBpZiAoZXh0ZW5zaW9ucyAmJiBleHRlbnNpb25zW3RoaXMubmFtZV0pIHtcclxuICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uc1t0aGlzLm5hbWVdIGFzIGFueTtcclxuICAgICAgICAgICAgdGhpcy5fbGlnaHRzID0gZXh0ZW5zaW9uLmxpZ2h0cztcclxuICAgICAgICAgICAgQXJyYXlJdGVtLkFzc2lnbih0aGlzLl9saWdodHMpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE5vZGVBc3luYyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IElOb2RlLCBhc3NpZ246IChiYWJ5bG9uVHJhbnNmb3JtTm9kZTogVHJhbnNmb3JtTm9kZSkgPT4gdm9pZCk6IE51bGxhYmxlPFByb21pc2U8VHJhbnNmb3JtTm9kZT4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUkxpZ2h0c1B1bmN0dWFsX0xpZ2h0UmVmZXJlbmNlLCBUcmFuc2Zvcm1Ob2RlPihjb250ZXh0LCBub2RlLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLl9hbGxNYXRlcmlhbHNEaXJ0eVJlcXVpcmVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIubG9hZE5vZGVBc3luYyhjb250ZXh0LCBub2RlLCAoYmFieWxvbk1lc2gpID0+IHtcclxuICAgICAgICAgICAgICAgIGxldCBiYWJ5bG9uTGlnaHQ6IExpZ2h0O1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGxpZ2h0ID0gQXJyYXlJdGVtLkdldChleHRlbnNpb25Db250ZXh0LCB0aGlzLl9saWdodHMsIGV4dGVuc2lvbi5saWdodCk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBuYW1lID0gbGlnaHQubmFtZSB8fCBiYWJ5bG9uTWVzaC5uYW1lO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9ICEhdGhpcy5fbG9hZGVyLl9hc3NldENvbnRhaW5lcjtcclxuXHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGxpZ2h0LnR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIEtIUkxpZ2h0c1B1bmN0dWFsX0xpZ2h0VHlwZS5ESVJFQ1RJT05BTDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uRGlyZWN0aW9uYWxMaWdodCA9IG5ldyBEaXJlY3Rpb25hbExpZ2h0KG5hbWUsIFZlY3RvcjMuQmFja3dhcmQoKSwgdGhpcy5fbG9hZGVyLmJhYnlsb25TY2VuZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25EaXJlY3Rpb25hbExpZ2h0LnBvc2l0aW9uLnNldEFsbCgwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbkxpZ2h0ID0gYmFieWxvbkRpcmVjdGlvbmFsTGlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjYXNlIEtIUkxpZ2h0c1B1bmN0dWFsX0xpZ2h0VHlwZS5QT0lOVDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTGlnaHQgPSBuZXcgUG9pbnRMaWdodChuYW1lLCBWZWN0b3IzLlplcm8oKSwgdGhpcy5fbG9hZGVyLmJhYnlsb25TY2VuZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjYXNlIEtIUkxpZ2h0c1B1bmN0dWFsX0xpZ2h0VHlwZS5TUE9UOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJhYnlsb25TcG90TGlnaHQgPSBuZXcgU3BvdExpZ2h0KG5hbWUsIFZlY3RvcjMuWmVybygpLCBWZWN0b3IzLkJhY2t3YXJkKCksIDAsIDEsIHRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uU3BvdExpZ2h0LmFuZ2xlID0gKChsaWdodC5zcG90ICYmIGxpZ2h0LnNwb3Qub3V0ZXJDb25lQW5nbGUpIHx8IE1hdGguUEkgLyA0KSAqIDI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25TcG90TGlnaHQuaW5uZXJBbmdsZSA9ICgobGlnaHQuc3BvdCAmJiBsaWdodC5zcG90LmlubmVyQ29uZUFuZ2xlKSB8fCAwKSAqIDI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25MaWdodCA9IGJhYnlsb25TcG90TGlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXh0ZW5zaW9uQ29udGV4dH06IEludmFsaWQgbGlnaHQgdHlwZSAoJHtsaWdodC50eXBlfSlgKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgYmFieWxvbkxpZ2h0Ll9wYXJlbnRDb250YWluZXIgPSB0aGlzLl9sb2FkZXIuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmJhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBsaWdodC5fYmFieWxvbkxpZ2h0ID0gYmFieWxvbkxpZ2h0O1xyXG5cclxuICAgICAgICAgICAgICAgIGJhYnlsb25MaWdodC5mYWxsb2ZmVHlwZSA9IExpZ2h0LkZBTExPRkZfR0xURjtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25MaWdodC5kaWZmdXNlID0gbGlnaHQuY29sb3IgPyBDb2xvcjMuRnJvbUFycmF5KGxpZ2h0LmNvbG9yKSA6IENvbG9yMy5XaGl0ZSgpO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbkxpZ2h0LmludGVuc2l0eSA9IGxpZ2h0LmludGVuc2l0eSA9PSB1bmRlZmluZWQgPyAxIDogbGlnaHQuaW50ZW5zaXR5O1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbkxpZ2h0LnJhbmdlID0gbGlnaHQucmFuZ2UgPT0gdW5kZWZpbmVkID8gTnVtYmVyLk1BWF9WQUxVRSA6IGxpZ2h0LnJhbmdlO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbkxpZ2h0LnBhcmVudCA9IGJhYnlsb25NZXNoO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5fYmFieWxvbkxpZ2h0cy5wdXNoKGJhYnlsb25MaWdodCk7XHJcblxyXG4gICAgICAgICAgICAgICAgR0xURkxvYWRlci5BZGRQb2ludGVyTWV0YWRhdGEoYmFieWxvbkxpZ2h0LCBleHRlbnNpb25Db250ZXh0KTtcclxuXHJcbiAgICAgICAgICAgICAgICBhc3NpZ24oYmFieWxvbk1lc2gpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX2xpZ2h0cyhsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IElNYXRlcmlhbCwgSVRleHR1cmVJbmZvIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSTWF0ZXJpYWxzQW5pc290cm9weSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl9tYXRlcmlhbHNfYW5pc290cm9weVwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfbWF0ZXJpYWxzX2FuaXNvdHJvcHkgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfYW5pc290cm9weVwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL3RyZWUvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl9tYXRlcmlhbHNfYW5pc290cm9weSlcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfYW5pc290cm9weSBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgYSBudW1iZXIgdGhhdCBkZXRlcm1pbmVzIHRoZSBvcmRlciB0aGUgZXh0ZW5zaW9ucyBhcmUgYXBwbGllZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9yZGVyID0gMTk1O1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRlbnNpb25Bc3luYzxJS0hSTWF0ZXJpYWxzQW5pc290cm9weT4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZElyaWRlc2NlbmNlUHJvcGVydGllc0FzeW5jKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbiwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZElyaWRlc2NlbmNlUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgcHJvcGVydGllczogSUtIUk1hdGVyaWFsc0FuaXNvdHJvcHksIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAoIShiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBNYXRlcmlhbCB0eXBlIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuXHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLmFuaXNvdHJvcHkuaXNFbmFibGVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLmFuaXNvdHJvcHkuaW50ZW5zaXR5ID0gcHJvcGVydGllcy5hbmlzb3Ryb3B5U3RyZW5ndGggPz8gMDtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYW5pc290cm9weS5hbmdsZSA9IHByb3BlcnRpZXMuYW5pc290cm9weVJvdGF0aW9uID8/IDA7XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmFuaXNvdHJvcHlUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIChwcm9wZXJ0aWVzLmFuaXNvdHJvcHlUZXh0dXJlIGFzIElUZXh0dXJlSW5mbykubm9uQ29sb3JEYXRhID0gdHJ1ZTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2FkVGV4dHVyZUluZm9Bc3luYyhgJHtjb250ZXh0fS9hbmlzb3Ryb3B5VGV4dHVyZWAsIHByb3BlcnRpZXMuYW5pc290cm9weVRleHR1cmUsICh0ZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dHVyZS5uYW1lID0gYCR7YmFieWxvbk1hdGVyaWFsLm5hbWV9IChBbmlzb3Ryb3B5IEludGVuc2l0eSlgO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbmlzb3Ryb3B5LnRleHR1cmUgPSB0ZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl9tYXRlcmlhbHNfYW5pc290cm9weShsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IElNYXRlcmlhbCwgSVRleHR1cmVJbmZvIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSTWF0ZXJpYWxzQ2xlYXJjb2F0IH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc19jbGVhcmNvYXRcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX21hdGVyaWFsc19jbGVhcmNvYXQgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfY2xlYXJjb2F0XCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0tocm9ub3MvS0hSX21hdGVyaWFsc19jbGVhcmNvYXQvUkVBRE1FLm1kKVxyXG4gKiBbUGxheWdyb3VuZCBTYW1wbGVdKGh0dHBzOi8vd3d3LmJhYnlsb25qcy1wbGF5Z3JvdW5kLmNvbS9mcmFtZS5odG1sIzdGN1BONiM4KVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21hdGVyaWFsc19jbGVhcmNvYXQgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDE5MDtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUk1hdGVyaWFsc0NsZWFyY29hdD4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZENsZWFyQ29hdFByb3BlcnRpZXNBc3luYyhleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24sIGJhYnlsb25NYXRlcmlhbCkpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRDbGVhckNvYXRQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBwcm9wZXJ0aWVzOiBJS0hSTWF0ZXJpYWxzQ2xlYXJjb2F0LCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogTWF0ZXJpYWwgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcblxyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5jbGVhckNvYXQuaXNFbmFibGVkID0gdHJ1ZTtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuY2xlYXJDb2F0LnVzZVJvdWdobmVzc0Zyb21NYWluVGV4dHVyZSA9IGZhbHNlO1xyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5jbGVhckNvYXQucmVtYXBGME9uSW50ZXJmYWNlQ2hhbmdlID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmNsZWFyY29hdEZhY3RvciAhPSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmNsZWFyQ29hdC5pbnRlbnNpdHkgPSBwcm9wZXJ0aWVzLmNsZWFyY29hdEZhY3RvcjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuY2xlYXJDb2F0LmludGVuc2l0eSA9IDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5jbGVhcmNvYXRUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vY2xlYXJjb2F0VGV4dHVyZWAsIHByb3BlcnRpZXMuY2xlYXJjb2F0VGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKENsZWFyQ29hdClgO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5jbGVhckNvYXQudGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuY2xlYXJjb2F0Um91Z2huZXNzRmFjdG9yICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuY2xlYXJDb2F0LnJvdWdobmVzcyA9IHByb3BlcnRpZXMuY2xlYXJjb2F0Um91Z2huZXNzRmFjdG9yO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5jbGVhckNvYXQucm91Z2huZXNzID0gMDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmNsZWFyY29hdFJvdWdobmVzc1RleHR1cmUpIHtcclxuICAgICAgICAgICAgKHByb3BlcnRpZXMuY2xlYXJjb2F0Um91Z2huZXNzVGV4dHVyZSBhcyBJVGV4dHVyZUluZm8pLm5vbkNvbG9yRGF0YSA9IHRydWU7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vY2xlYXJjb2F0Um91Z2huZXNzVGV4dHVyZWAsIHByb3BlcnRpZXMuY2xlYXJjb2F0Um91Z2huZXNzVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKENsZWFyQ29hdCBSb3VnaG5lc3MpYDtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuY2xlYXJDb2F0LnRleHR1cmVSb3VnaG5lc3MgPSB0ZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmNsZWFyY29hdE5vcm1hbFRleHR1cmUpIHtcclxuICAgICAgICAgICAgKHByb3BlcnRpZXMuY2xlYXJjb2F0Tm9ybWFsVGV4dHVyZSBhcyBJVGV4dHVyZUluZm8pLm5vbkNvbG9yRGF0YSA9IHRydWU7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vY2xlYXJjb2F0Tm9ybWFsVGV4dHVyZWAsIHByb3BlcnRpZXMuY2xlYXJjb2F0Tm9ybWFsVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKENsZWFyQ29hdCBOb3JtYWwpYDtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuY2xlYXJDb2F0LmJ1bXBUZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuaW52ZXJ0Tm9ybWFsTWFwWCA9ICFiYWJ5bG9uTWF0ZXJpYWwuZ2V0U2NlbmUoKS51c2VSaWdodEhhbmRlZFN5c3RlbTtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmludmVydE5vcm1hbE1hcFkgPSBiYWJ5bG9uTWF0ZXJpYWwuZ2V0U2NlbmUoKS51c2VSaWdodEhhbmRlZFN5c3RlbTtcclxuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMuY2xlYXJjb2F0Tm9ybWFsVGV4dHVyZS5zY2FsZSAhPSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5jbGVhckNvYXQuYnVtcFRleHR1cmUhLmxldmVsID0gcHJvcGVydGllcy5jbGVhcmNvYXROb3JtYWxUZXh0dXJlLnNjYWxlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfbWF0ZXJpYWxzX2NsZWFyY29hdChsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgQmFzZVRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvYmFzZVRleHR1cmVcIjtcclxuaW1wb3J0IHR5cGUgeyBJTWF0ZXJpYWwsIElUZXh0dXJlSW5mbyB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSUtIUk1hdGVyaWFsc0RpZmZ1c2VUcmFuc21pc3Npb24gfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IENvbG9yMyB9IGZyb20gXCJjb3JlL01hdGhzL21hdGguY29sb3JcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl9tYXRlcmlhbHNfZGlmZnVzZV90cmFuc21pc3Npb25cIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX21hdGVyaWFsc19kaWZmdXNlX3RyYW5zbWlzc2lvbiBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiS0hSX21hdGVyaWFsc19kaWZmdXNlX3RyYW5zbWlzc2lvblwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbUHJvcG9zZWQgU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL3B1bGwvMTgyNSlcclxuICogISEhIEV4cGVyaW1lbnRhbCBFeHRlbnNpb24gU3ViamVjdCB0byBDaGFuZ2VzICEhIVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21hdGVyaWFsc19kaWZmdXNlX3RyYW5zbWlzc2lvbiBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgYSBudW1iZXIgdGhhdCBkZXRlcm1pbmVzIHRoZSBvcmRlciB0aGUgZXh0ZW5zaW9ucyBhcmUgYXBwbGllZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9yZGVyID0gMTc0O1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgICAgICBpZiAodGhpcy5lbmFibGVkKSB7XHJcbiAgICAgICAgICAgIGxvYWRlci5wYXJlbnQudHJhbnNwYXJlbmN5QXNDb3ZlcmFnZSA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBOdWxsYWJsZTxQcm9taXNlPHZvaWQ+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElLSFJNYXRlcmlhbHNEaWZmdXNlVHJhbnNtaXNzaW9uPihjb250ZXh0LCBtYXRlcmlhbCwgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkZXIubG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkVHJhbnNsdWNlbnRQcm9wZXJ0aWVzQXN5bmMoZXh0ZW5zaW9uQ29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCwgZXh0ZW5zaW9uKSk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZFRyYW5zbHVjZW50UHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCwgZXh0ZW5zaW9uOiBJS0hSTWF0ZXJpYWxzRGlmZnVzZVRyYW5zbWlzc2lvbik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IE1hdGVyaWFsIHR5cGUgbm90IHN1cHBvcnRlZGApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcGJyTWF0ZXJpYWwgPSBiYWJ5bG9uTWF0ZXJpYWwgYXMgUEJSTWF0ZXJpYWw7XHJcblxyXG4gICAgICAgIC8vIEVuYWJsZXMgXCJ0cmFuc2x1Y2VuY3lcIiB0ZXh0dXJlIHdoaWNoIHJlcHJlc2VudHMgZGlmZnVzZWx5LXRyYW5zbWl0dGVkIGxpZ2h0LlxyXG4gICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UuaXNUcmFuc2x1Y2VuY3lFbmFibGVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgLy8gU2luY2UgdGhpcyBleHRlbnNpb24gbW9kZWxzIHRoaW4tc3VyZmFjZSB0cmFuc21pc3Npb24gb25seSwgd2UgbXVzdCBtYWtlIHRoZVxyXG4gICAgICAgIC8vIGludGVybmFsIElPUiA9PSAxLjAgYW5kIHNldCB0aGUgdGhpY2tuZXNzIHRvIDAuXHJcbiAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS52b2x1bWVJbmRleE9mUmVmcmFjdGlvbiA9IDEuMDtcclxuICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLm1pbmltdW1UaGlja25lc3MgPSAwLjA7XHJcbiAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS5tYXhpbXVtVGhpY2tuZXNzID0gMC4wO1xyXG5cclxuICAgICAgICAvLyBUaW50IGNvbG9yIHdpbGwgYmUgdXNlZCBmb3IgdHJhbnNtaXNzaW9uLlxyXG4gICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UudXNlQWxiZWRvVG9UaW50VHJhbnNsdWNlbmN5ID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGlmIChleHRlbnNpb24uZGlmZnVzZVRyYW5zbWlzc2lvbkZhY3RvciAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UudHJhbnNsdWNlbmN5SW50ZW5zaXR5ID0gZXh0ZW5zaW9uLmRpZmZ1c2VUcmFuc21pc3Npb25GYWN0b3I7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS50cmFuc2x1Y2VuY3lJbnRlbnNpdHkgPSAwLjA7XHJcbiAgICAgICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UuaXNUcmFuc2x1Y2VuY3lFbmFibGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuXHJcbiAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS51c2VHbHRmU3R5bGVUZXh0dXJlcyA9IHRydWU7XHJcblxyXG4gICAgICAgIGlmIChleHRlbnNpb24uZGlmZnVzZVRyYW5zbWlzc2lvblRleHR1cmUpIHtcclxuICAgICAgICAgICAgKGV4dGVuc2lvbi5kaWZmdXNlVHJhbnNtaXNzaW9uVGV4dHVyZSBhcyBJVGV4dHVyZUluZm8pLm5vbkNvbG9yRGF0YSA9IHRydWU7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vZGlmZnVzZVRyYW5zbWlzc2lvblRleHR1cmVgLCBleHRlbnNpb24uZGlmZnVzZVRyYW5zbWlzc2lvblRleHR1cmUpLnRoZW4oKHRleHR1cmU6IEJhc2VUZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dHVyZS5uYW1lID0gYCR7YmFieWxvbk1hdGVyaWFsLm5hbWV9IChEaWZmdXNlIFRyYW5zbWlzc2lvbilgO1xyXG4gICAgICAgICAgICAgICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UudHJhbnNsdWNlbmN5SW50ZW5zaXR5VGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGV4dGVuc2lvbi5kaWZmdXNlVHJhbnNtaXNzaW9uQ29sb3JGYWN0b3IgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLnRyYW5zbHVjZW5jeUNvbG9yID0gQ29sb3IzLkZyb21BcnJheShleHRlbnNpb24uZGlmZnVzZVRyYW5zbWlzc2lvbkNvbG9yRmFjdG9yKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLnRyYW5zbHVjZW5jeUNvbG9yID0gQ29sb3IzLldoaXRlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoZXh0ZW5zaW9uLmRpZmZ1c2VUcmFuc21pc3Npb25Db2xvclRleHR1cmUpIHtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2FkVGV4dHVyZUluZm9Bc3luYyhgJHtjb250ZXh0fS9kaWZmdXNlVHJhbnNtaXNzaW9uQ29sb3JUZXh0dXJlYCwgZXh0ZW5zaW9uLmRpZmZ1c2VUcmFuc21pc3Npb25Db2xvclRleHR1cmUpLnRoZW4oKHRleHR1cmU6IEJhc2VUZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dHVyZS5uYW1lID0gYCR7YmFieWxvbk1hdGVyaWFsLm5hbWV9IChEaWZmdXNlIFRyYW5zbWlzc2lvbiBDb2xvcilgO1xyXG4gICAgICAgICAgICAgICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UudHJhbnNsdWNlbmN5Q29sb3JUZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfbWF0ZXJpYWxzX2RpZmZ1c2VfdHJhbnNtaXNzaW9uKGxvYWRlcikpO1xyXG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24gKi9cclxuaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IFBCUk1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1BCUi9wYnJNYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgSU1hdGVyaWFsIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSTWF0ZXJpYWxzRGlzcGVyc2lvbiB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl9tYXRlcmlhbHNfZGlzcGVyc2lvblwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfbWF0ZXJpYWxzX2Rpc3BlcnNpb24gZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfZGlzcGVyc2lvblwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvODdiZDY0YTdmNWUyM2M4NGI2YWVmMmU2MDgyMDY5NTgzZWQwZGRiNC9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl9tYXRlcmlhbHNfZGlzcGVyc2lvbi9SRUFETUUubWQpXHJcbiAqIEBleHBlcmltZW50YWxcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfZGlzcGVyc2lvbiBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgYSBudW1iZXIgdGhhdCBkZXRlcm1pbmVzIHRoZSBvcmRlciB0aGUgZXh0ZW5zaW9ucyBhcmUgYXBwbGllZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9yZGVyID0gMTc0O1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRlbnNpb25Bc3luYzxJS0hSTWF0ZXJpYWxzRGlzcGVyc2lvbj4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZERpc3BlcnNpb25Qcm9wZXJ0aWVzQXN5bmMoZXh0ZW5zaW9uQ29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCwgZXh0ZW5zaW9uKSk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZERpc3BlcnNpb25Qcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsLCBleHRlbnNpb246IElLSFJNYXRlcmlhbHNEaXNwZXJzaW9uKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogTWF0ZXJpYWwgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJZiB0cmFuc3BhcmVuY3kgaXNuJ3QgZW5hYmxlZCBhbHJlYWR5LCB0aGlzIGV4dGVuc2lvbiBzaG91bGRuJ3QgZG8gYW55dGhpbmcuXHJcbiAgICAgICAgLy8gaS5lLiBpdCByZXF1aXJlcyBlaXRoZXIgdGhlIEtIUl9tYXRlcmlhbHNfdHJhbnNtaXNzaW9uIG9yIEtIUl9tYXRlcmlhbHNfZGlmZnVzZV90cmFuc21pc3Npb24gZXh0ZW5zaW9ucy5cclxuICAgICAgICBpZiAoIWJhYnlsb25NYXRlcmlhbC5zdWJTdXJmYWNlLmlzUmVmcmFjdGlvbkVuYWJsZWQgfHwgIWV4dGVuc2lvbi5kaXNwZXJzaW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2UuaXNEaXNwZXJzaW9uRW5hYmxlZCA9IHRydWU7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2UuZGlzcGVyc2lvbiA9IGV4dGVuc2lvbi5kaXNwZXJzaW9uO1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX21hdGVyaWFsc19kaXNwZXJzaW9uKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSU1hdGVyaWFsIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSTWF0ZXJpYWxzRW1pc3NpdmVTdHJlbmd0aCB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl9tYXRlcmlhbHNfZW1pc3NpdmVfc3RyZW5ndGhcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX21hdGVyaWFsc19lbWlzc2l2ZV9zdHJlbmd0aCBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiS0hSX21hdGVyaWFsc19lbWlzc2l2ZV9zdHJlbmd0aFwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl9tYXRlcmlhbHNfZW1pc3NpdmVfc3RyZW5ndGgvUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21hdGVyaWFsc19lbWlzc2l2ZV9zdHJlbmd0aCBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgYSBudW1iZXIgdGhhdCBkZXRlcm1pbmVzIHRoZSBvcmRlciB0aGUgZXh0ZW5zaW9ucyBhcmUgYXBwbGllZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9yZGVyID0gMTcwO1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRlbnNpb25Bc3luYzxJS0hSTWF0ZXJpYWxzRW1pc3NpdmVTdHJlbmd0aD4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRFbWlzc2l2ZVByb3BlcnRpZXMoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uLCBiYWJ5bG9uTWF0ZXJpYWwpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkRW1pc3NpdmVQcm9wZXJ0aWVzKGNvbnRleHQ6IHN0cmluZywgcHJvcGVydGllczogSUtIUk1hdGVyaWFsc0VtaXNzaXZlU3RyZW5ndGgsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIShiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBNYXRlcmlhbCB0eXBlIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmVtaXNzaXZlU3RyZW5ndGggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuZW1pc3NpdmVJbnRlbnNpdHkgPSBwcm9wZXJ0aWVzLmVtaXNzaXZlU3RyZW5ndGg7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfbWF0ZXJpYWxzX2VtaXNzaXZlX3N0cmVuZ3RoKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSU1hdGVyaWFsIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSTWF0ZXJpYWxzSW9yIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc19pb3JcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX21hdGVyaWFsc19pb3IgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfaW9yXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0tocm9ub3MvS0hSX21hdGVyaWFsc19pb3IvUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21hdGVyaWFsc19pb3IgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIERlZmF1bHQgaW9yIFZhbHVlIGZyb20gdGhlIHNwZWMuXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IF9ERUZBVUxUX0lPUiA9IDEuNTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDE4MDtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUk1hdGVyaWFsc0lvcj4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZElvclByb3BlcnRpZXNBc3luYyhleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24sIGJhYnlsb25NYXRlcmlhbCkpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRJb3JQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBwcm9wZXJ0aWVzOiBJS0hSTWF0ZXJpYWxzSW9yLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogTWF0ZXJpYWwgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5pb3IgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuaW5kZXhPZlJlZnJhY3Rpb24gPSBwcm9wZXJ0aWVzLmlvcjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuaW5kZXhPZlJlZnJhY3Rpb24gPSBLSFJfbWF0ZXJpYWxzX2lvci5fREVGQVVMVF9JT1I7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl9tYXRlcmlhbHNfaW9yKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSU1hdGVyaWFsIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSTWF0ZXJpYWxzSXJpZGVzY2VuY2UgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWF0ZXJpYWxzX2lyaWRlc2NlbmNlXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9tYXRlcmlhbHNfaXJpZGVzY2VuY2UgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfaXJpZGVzY2VuY2VcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbWF0ZXJpYWxzX2lyaWRlc2NlbmNlL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfaXJpZGVzY2VuY2UgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDE5NTtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUk1hdGVyaWFsc0lyaWRlc2NlbmNlPihjb250ZXh0LCBtYXRlcmlhbCwgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkZXIubG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkSXJpZGVzY2VuY2VQcm9wZXJ0aWVzQXN5bmMoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkSXJpZGVzY2VuY2VQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBwcm9wZXJ0aWVzOiBJS0hSTWF0ZXJpYWxzSXJpZGVzY2VuY2UsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAoIShiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBNYXRlcmlhbCB0eXBlIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuXHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLmlyaWRlc2NlbmNlLmlzRW5hYmxlZCA9IHRydWU7XHJcblxyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5pcmlkZXNjZW5jZS5pbnRlbnNpdHkgPSBwcm9wZXJ0aWVzLmlyaWRlc2NlbmNlRmFjdG9yID8/IDA7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLmlyaWRlc2NlbmNlLmluZGV4T2ZSZWZyYWN0aW9uID0gcHJvcGVydGllcy5pcmlkZXNjZW5jZUlvciA/PyAocHJvcGVydGllcyBhcyBhbnkpLmlyaWRlc2NlbmNlSU9SID8/IDEuMztcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuaXJpZGVzY2VuY2UubWluaW11bVRoaWNrbmVzcyA9IHByb3BlcnRpZXMuaXJpZGVzY2VuY2VUaGlja25lc3NNaW5pbXVtID8/IDEwMDtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuaXJpZGVzY2VuY2UubWF4aW11bVRoaWNrbmVzcyA9IHByb3BlcnRpZXMuaXJpZGVzY2VuY2VUaGlja25lc3NNYXhpbXVtID8/IDQwMDtcclxuXHJcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuaXJpZGVzY2VuY2VUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vaXJpZGVzY2VuY2VUZXh0dXJlYCwgcHJvcGVydGllcy5pcmlkZXNjZW5jZVRleHR1cmUsICh0ZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dHVyZS5uYW1lID0gYCR7YmFieWxvbk1hdGVyaWFsLm5hbWV9IChJcmlkZXNjZW5jZSlgO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5pcmlkZXNjZW5jZS50ZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5pcmlkZXNjZW5jZVRoaWNrbmVzc1RleHR1cmUpIHtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2FkVGV4dHVyZUluZm9Bc3luYyhgJHtjb250ZXh0fS9pcmlkZXNjZW5jZVRoaWNrbmVzc1RleHR1cmVgLCBwcm9wZXJ0aWVzLmlyaWRlc2NlbmNlVGhpY2tuZXNzVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKElyaWRlc2NlbmNlIFRoaWNrbmVzcylgO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5pcmlkZXNjZW5jZS50aGlja25lc3NUZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfbWF0ZXJpYWxzX2lyaWRlc2NlbmNlKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgQ29sb3IzIH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC5jb2xvclwiO1xyXG5pbXBvcnQgeyBQQlJNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9QQlIvcGJyTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5cclxuaW1wb3J0IHR5cGUgeyBJTWF0ZXJpYWwgfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IEdMVEZMb2FkZXIgfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IElLSFJNYXRlcmlhbHNQYnJTcGVjdWxhckdsb3NzaW5lc3MgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWF0ZXJpYWxzX3BiclNwZWN1bGFyR2xvc3NpbmVzc1wiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfbWF0ZXJpYWxzX3BiclNwZWN1bGFyR2xvc3NpbmVzcyBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiS0hSX21hdGVyaWFsc19wYnJTcGVjdWxhckdsb3NzaW5lc3NcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvQXJjaGl2ZWQvS0hSX21hdGVyaWFsc19wYnJTcGVjdWxhckdsb3NzaW5lc3MvUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21hdGVyaWFsc19wYnJTcGVjdWxhckdsb3NzaW5lc3MgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDIwMDtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUk1hdGVyaWFsc1BiclNwZWN1bGFyR2xvc3NpbmVzcz4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbEJhc2VQcm9wZXJ0aWVzQXN5bmMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCkpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRTcGVjdWxhckdsb3NzaW5lc3NQcm9wZXJ0aWVzQXN5bmMoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbEFscGhhUHJvcGVydGllcyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkU3BlY3VsYXJHbG9zc2luZXNzUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgcHJvcGVydGllczogSUtIUk1hdGVyaWFsc1BiclNwZWN1bGFyR2xvc3NpbmVzcywgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IE1hdGVyaWFsIHR5cGUgbm90IHN1cHBvcnRlZGApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG5cclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwubWV0YWxsaWMgPSBudWxsO1xyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5yb3VnaG5lc3MgPSBudWxsO1xyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5kaWZmdXNlRmFjdG9yKSB7XHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbGJlZG9Db2xvciA9IENvbG9yMy5Gcm9tQXJyYXkocHJvcGVydGllcy5kaWZmdXNlRmFjdG9yKTtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmFscGhhID0gcHJvcGVydGllcy5kaWZmdXNlRmFjdG9yWzNdO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbGJlZG9Db2xvciA9IENvbG9yMy5XaGl0ZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnJlZmxlY3Rpdml0eUNvbG9yID0gcHJvcGVydGllcy5zcGVjdWxhckZhY3RvciA/IENvbG9yMy5Gcm9tQXJyYXkocHJvcGVydGllcy5zcGVjdWxhckZhY3RvcikgOiBDb2xvcjMuV2hpdGUoKTtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwubWljcm9TdXJmYWNlID0gcHJvcGVydGllcy5nbG9zc2luZXNzRmFjdG9yID09IHVuZGVmaW5lZCA/IDEgOiBwcm9wZXJ0aWVzLmdsb3NzaW5lc3NGYWN0b3I7XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmRpZmZ1c2VUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vZGlmZnVzZVRleHR1cmVgLCBwcm9wZXJ0aWVzLmRpZmZ1c2VUZXh0dXJlLCAodGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoRGlmZnVzZSlgO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbGJlZG9UZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5zcGVjdWxhckdsb3NzaW5lc3NUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vc3BlY3VsYXJHbG9zc2luZXNzVGV4dHVyZWAsIHByb3BlcnRpZXMuc3BlY3VsYXJHbG9zc2luZXNzVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKFNwZWN1bGFyIEdsb3NzaW5lc3MpYDtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwucmVmbGVjdGl2aXR5VGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnJlZmxlY3Rpdml0eVRleHR1cmUuaGFzQWxwaGEgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC51c2VNaWNyb1N1cmZhY2VGcm9tUmVmbGVjdGl2aXR5TWFwQWxwaGEgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX21hdGVyaWFsc19wYnJTcGVjdWxhckdsb3NzaW5lc3MobG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBQQlJNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9QQlIvcGJyTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5cclxuaW1wb3J0IHR5cGUgeyBJTWF0ZXJpYWwsIElUZXh0dXJlSW5mbyB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB7IENvbG9yMyB9IGZyb20gXCJjb3JlL01hdGhzL21hdGguY29sb3JcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSTWF0ZXJpYWxzU2hlZW4gfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWF0ZXJpYWxzX3NoZWVuXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9tYXRlcmlhbHNfc2hlZW4gZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfc2hlZW5cIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbWF0ZXJpYWxzX3NoZWVuL1JFQURNRS5tZClcclxuICogW1BsYXlncm91bmQgU2FtcGxlXShodHRwczovL3d3dy5iYWJ5bG9uanMtcGxheWdyb3VuZC5jb20vZnJhbWUuaHRtbCNCTklaWDYjNClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfc2hlZW4gaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDE5MDtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUk1hdGVyaWFsc1NoZWVuPihjb250ZXh0LCBtYXRlcmlhbCwgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkZXIubG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkU2hlZW5Qcm9wZXJ0aWVzQXN5bmMoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkU2hlZW5Qcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBwcm9wZXJ0aWVzOiBJS0hSTWF0ZXJpYWxzU2hlZW4sIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAoIShiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBNYXRlcmlhbCB0eXBlIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuXHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnNoZWVuLmlzRW5hYmxlZCA9IHRydWU7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnNoZWVuLmludGVuc2l0eSA9IDE7XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLnNoZWVuQ29sb3JGYWN0b3IgIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5zaGVlbi5jb2xvciA9IENvbG9yMy5Gcm9tQXJyYXkocHJvcGVydGllcy5zaGVlbkNvbG9yRmFjdG9yKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuc2hlZW4uY29sb3IgPSBDb2xvcjMuQmxhY2soKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLnNoZWVuQ29sb3JUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vc2hlZW5Db2xvclRleHR1cmVgLCBwcm9wZXJ0aWVzLnNoZWVuQ29sb3JUZXh0dXJlLCAodGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoU2hlZW4gQ29sb3IpYDtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuc2hlZW4udGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuc2hlZW5Sb3VnaG5lc3NGYWN0b3IgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuc2hlZW4ucm91Z2huZXNzID0gcHJvcGVydGllcy5zaGVlblJvdWdobmVzc0ZhY3RvcjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuc2hlZW4ucm91Z2huZXNzID0gMDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLnNoZWVuUm91Z2huZXNzVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAocHJvcGVydGllcy5zaGVlblJvdWdobmVzc1RleHR1cmUgYXMgSVRleHR1cmVJbmZvKS5ub25Db2xvckRhdGEgPSB0cnVlO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L3NoZWVuUm91Z2huZXNzVGV4dHVyZWAsIHByb3BlcnRpZXMuc2hlZW5Sb3VnaG5lc3NUZXh0dXJlLCAodGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoU2hlZW4gUm91Z2huZXNzKWA7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnNoZWVuLnRleHR1cmVSb3VnaG5lc3MgPSB0ZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5zaGVlbi5hbGJlZG9TY2FsaW5nID0gdHJ1ZTtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuc2hlZW4udXNlUm91Z2huZXNzRnJvbU1haW5UZXh0dXJlID0gZmFsc2U7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl9tYXRlcmlhbHNfc2hlZW4obG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBQQlJNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9QQlIvcGJyTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5cclxuaW1wb3J0IHR5cGUgeyBJTWF0ZXJpYWwsIElUZXh0dXJlSW5mbyB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB7IENvbG9yMyB9IGZyb20gXCJjb3JlL01hdGhzL21hdGguY29sb3JcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSTWF0ZXJpYWxzU3BlY3VsYXIgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWF0ZXJpYWxzX3NwZWN1bGFyXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9tYXRlcmlhbHNfc3BlY3VsYXIgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfc3BlY3VsYXJcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbWF0ZXJpYWxzX3NwZWN1bGFyL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfc3BlY3VsYXIgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDE5MDtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUk1hdGVyaWFsc1NwZWN1bGFyPihjb250ZXh0LCBtYXRlcmlhbCwgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkZXIubG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkU3BlY3VsYXJQcm9wZXJ0aWVzQXN5bmMoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkU3BlY3VsYXJQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBwcm9wZXJ0aWVzOiBJS0hSTWF0ZXJpYWxzU3BlY3VsYXIsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAoIShiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBNYXRlcmlhbCB0eXBlIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuXHJcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuc3BlY3VsYXJGYWN0b3IgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwubWV0YWxsaWNGMEZhY3RvciA9IHByb3BlcnRpZXMuc3BlY3VsYXJGYWN0b3I7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJvcGVydGllcy5zcGVjdWxhckNvbG9yRmFjdG9yICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLm1ldGFsbGljUmVmbGVjdGFuY2VDb2xvciA9IENvbG9yMy5Gcm9tQXJyYXkocHJvcGVydGllcy5zcGVjdWxhckNvbG9yRmFjdG9yKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLnNwZWN1bGFyVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAocHJvcGVydGllcy5zcGVjdWxhclRleHR1cmUgYXMgSVRleHR1cmVJbmZvKS5ub25Db2xvckRhdGEgPSB0cnVlO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L3NwZWN1bGFyVGV4dHVyZWAsIHByb3BlcnRpZXMuc3BlY3VsYXJUZXh0dXJlLCAodGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoU3BlY3VsYXIpYDtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwubWV0YWxsaWNSZWZsZWN0YW5jZVRleHR1cmUgPSB0ZXh0dXJlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC51c2VPbmx5TWV0YWxsaWNGcm9tTWV0YWxsaWNSZWZsZWN0YW5jZVRleHR1cmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLnNwZWN1bGFyQ29sb3JUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vc3BlY3VsYXJDb2xvclRleHR1cmVgLCBwcm9wZXJ0aWVzLnNwZWN1bGFyQ29sb3JUZXh0dXJlLCAodGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoU3BlY3VsYXIgQ29sb3IpYDtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwucmVmbGVjdGFuY2VUZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfbWF0ZXJpYWxzX3NwZWN1bGFyKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBCYXNlVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy9iYXNlVGV4dHVyZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElNYXRlcmlhbCwgSVRleHR1cmVJbmZvIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSTWF0ZXJpYWxzVHJhbnNtaXNzaW9uIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IFNjZW5lIH0gZnJvbSBcImNvcmUvc2NlbmVcIjtcclxuaW1wb3J0IHR5cGUgeyBBYnN0cmFjdE1lc2ggfSBmcm9tIFwiY29yZS9NZXNoZXMvYWJzdHJhY3RNZXNoXCI7XHJcbmltcG9ydCB0eXBlIHsgVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy90ZXh0dXJlXCI7XHJcbmltcG9ydCB7IFJlbmRlclRhcmdldFRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvcmVuZGVyVGFyZ2V0VGV4dHVyZVwiO1xyXG5pbXBvcnQgdHlwZSB7IE9ic2VydmVyIH0gZnJvbSBcImNvcmUvTWlzYy9vYnNlcnZhYmxlXCI7XHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tIFwiY29yZS9NaXNjL29ic2VydmFibGVcIjtcclxuaW1wb3J0IHsgQ29uc3RhbnRzIH0gZnJvbSBcImNvcmUvRW5naW5lcy9jb25zdGFudHNcIjtcclxuaW1wb3J0IHsgVG9vbHMgfSBmcm9tIFwiY29yZS9NaXNjL3Rvb2xzXCI7XHJcbmltcG9ydCB0eXBlIHsgQ29sb3I0IH0gZnJvbSBcImNvcmUvTWF0aHMvbWF0aC5jb2xvclwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuaW50ZXJmYWNlIElUcmFuc21pc3Npb25IZWxwZXJIb2xkZXIge1xyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgX3RyYW5zbWlzc2lvbkhlbHBlcjogVHJhbnNtaXNzaW9uSGVscGVyIHwgdW5kZWZpbmVkO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgSVRyYW5zbWlzc2lvbkhlbHBlck9wdGlvbnMge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgc2l6ZSBvZiB0aGUgcmVuZGVyIGJ1ZmZlcnMgKGRlZmF1bHQ6IDEwMjQpXHJcbiAgICAgKi9cclxuICAgIHJlbmRlclNpemU6IG51bWJlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBudW1iZXIgb2Ygc2FtcGxlcyB0byB1c2Ugd2hlbiBnZW5lcmF0aW5nIHRoZSByZW5kZXIgdGFyZ2V0IHRleHR1cmUgZm9yIG9wYXF1ZSBtZXNoZXMgKGRlZmF1bHQ6IDQpXHJcbiAgICAgKi9cclxuICAgIHNhbXBsZXM6IG51bWJlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNjYWxlIHRvIGFwcGx5IHdoZW4gc2VsZWN0aW5nIHRoZSBMT0QgbGV2ZWwgdG8gc2FtcGxlIHRoZSByZWZyYWN0aW9uIHRleHR1cmUgKGRlZmF1bHQ6IDEpXHJcbiAgICAgKi9cclxuICAgIGxvZEdlbmVyYXRpb25TY2FsZTogbnVtYmVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2Zmc2V0IHRvIGFwcGx5IHdoZW4gc2VsZWN0aW5nIHRoZSBMT0QgbGV2ZWwgdG8gc2FtcGxlIHRoZSByZWZyYWN0aW9uIHRleHR1cmUgKGRlZmF1bHQ6IC00KVxyXG4gICAgICovXHJcbiAgICBsb2RHZW5lcmF0aW9uT2Zmc2V0OiBudW1iZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUeXBlIG9mIHRoZSByZWZyYWN0aW9uIHJlbmRlciB0YXJnZXQgdGV4dHVyZSAoZGVmYXVsdDogVEVYVFVSRVRZUEVfSEFMRl9GTE9BVClcclxuICAgICAqL1xyXG4gICAgcmVuZGVyVGFyZ2V0VGV4dHVyZVR5cGU6IG51bWJlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgaWYgdGhlIG1pcG1hcHMgZm9yIHRoZSByZWZyYWN0aW9uIHJlbmRlciB0YXJnZXQgdGV4dHVyZSBtdXN0IGJlIGdlbmVyYXRlZCAoZGVmYXVsdDogdHJ1ZSlcclxuICAgICAqL1xyXG4gICAgZ2VuZXJhdGVNaXBtYXBzOiBib29sZWFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2xlYXIgY29sb3Igb2YgdGhlIG9wYXF1ZSB0ZXh0dXJlLiBJZiBub3QgcHJvdmlkZWQsIHVzZSB0aGUgc2NlbmUgY2xlYXIgY29sb3IgKHdoaWNoIHdpbGwgYmUgY29udmVydGVkIHRvIGxpbmVhciBzcGFjZSkuXHJcbiAgICAgKiBJZiBwcm92aWRlZCwgc2hvdWxkIGJlIGluIGxpbmVhciBzcGFjZVxyXG4gICAgICovXHJcbiAgICBjbGVhckNvbG9yPzogQ29sb3I0O1xyXG59XHJcblxyXG4vKipcclxuICogQSBjbGFzcyB0byBoYW5kbGUgc2V0dGluZyB1cCB0aGUgcmVuZGVyaW5nIG9mIG9wYXF1ZSBvYmplY3RzIHRvIGJlIHNob3duIHRocm91Z2ggdHJhbnNtaXNzaXZlIG9iamVjdHMuXHJcbiAqL1xyXG5jbGFzcyBUcmFuc21pc3Npb25IZWxwZXIge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIHRoZSBkZWZhdWx0IG9wdGlvbnMgZm9yIHRoZSBoZWxwZXIuXHJcbiAgICAgKiBAcmV0dXJucyB0aGUgZGVmYXVsdCBvcHRpb25zXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIF9HZXREZWZhdWx0T3B0aW9ucygpOiBJVHJhbnNtaXNzaW9uSGVscGVyT3B0aW9ucyB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgcmVuZGVyU2l6ZTogMTAyNCxcclxuICAgICAgICAgICAgc2FtcGxlczogNCxcclxuICAgICAgICAgICAgbG9kR2VuZXJhdGlvblNjYWxlOiAxLFxyXG4gICAgICAgICAgICBsb2RHZW5lcmF0aW9uT2Zmc2V0OiAtNCxcclxuICAgICAgICAgICAgcmVuZGVyVGFyZ2V0VGV4dHVyZVR5cGU6IENvbnN0YW50cy5URVhUVVJFVFlQRV9IQUxGX0ZMT0FULFxyXG4gICAgICAgICAgICBnZW5lcmF0ZU1pcG1hcHM6IHRydWUsXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyB0aGUgY3JlYXRpb24gb3B0aW9ucy5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBfc2NlbmU6IFNjZW5lICYgSVRyYW5zbWlzc2lvbkhlbHBlckhvbGRlcjtcclxuXHJcbiAgICBwcml2YXRlIF9vcHRpb25zOiBJVHJhbnNtaXNzaW9uSGVscGVyT3B0aW9ucztcclxuXHJcbiAgICBwcml2YXRlIF9vcGFxdWVSZW5kZXJUYXJnZXQ6IE51bGxhYmxlPFJlbmRlclRhcmdldFRleHR1cmU+ID0gbnVsbDtcclxuICAgIHByaXZhdGUgX29wYXF1ZU1lc2hlc0NhY2hlOiBBYnN0cmFjdE1lc2hbXSA9IFtdO1xyXG4gICAgcHJpdmF0ZSBfdHJhbnNwYXJlbnRNZXNoZXNDYWNoZTogQWJzdHJhY3RNZXNoW10gPSBbXTtcclxuICAgIHByaXZhdGUgX21hdGVyaWFsT2JzZXJ2ZXJzOiB7IFtpZDogc3RyaW5nXTogTnVsbGFibGU8T2JzZXJ2ZXI8QWJzdHJhY3RNZXNoPj4gfSA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhpcyBvYnNlcnZhYmxlIHdpbGwgYmUgbm90aWZpZWQgd2l0aCBhbnkgZXJyb3IgZHVyaW5nIHRoZSBjcmVhdGlvbiBvZiB0aGUgZW52aXJvbm1lbnQsXHJcbiAgICAgKiBtYWlubHkgdGV4dHVyZSBjcmVhdGlvbiBlcnJvcnMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkVycm9yT2JzZXJ2YWJsZTogT2JzZXJ2YWJsZTx7IG1lc3NhZ2U/OiBzdHJpbmc7IGV4Y2VwdGlvbj86IGFueSB9PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBEZWZpbmVzIHRoZSBvcHRpb25zIHdlIHdhbnQgdG8gY3VzdG9taXplIHRoZSBoZWxwZXJcclxuICAgICAqIEBwYXJhbSBzY2VuZSBUaGUgc2NlbmUgdG8gYWRkIHRoZSBtYXRlcmlhbCB0b1xyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zOiBQYXJ0aWFsPElUcmFuc21pc3Npb25IZWxwZXJPcHRpb25zPiwgc2NlbmU6IFNjZW5lKSB7XHJcbiAgICAgICAgdGhpcy5fb3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgLi4uVHJhbnNtaXNzaW9uSGVscGVyLl9HZXREZWZhdWx0T3B0aW9ucygpLFxyXG4gICAgICAgICAgICAuLi5vcHRpb25zLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdGhpcy5fc2NlbmUgPSBzY2VuZSBhcyBhbnk7XHJcbiAgICAgICAgdGhpcy5fc2NlbmUuX3RyYW5zbWlzc2lvbkhlbHBlciA9IHRoaXM7XHJcblxyXG4gICAgICAgIHRoaXMub25FcnJvck9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZSgpO1xyXG4gICAgICAgIHRoaXMuX3NjZW5lLm9uRGlzcG9zZU9ic2VydmFibGUuYWRkT25jZSgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuZGlzcG9zZSgpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLl9wYXJzZVNjZW5lKCk7XHJcbiAgICAgICAgdGhpcy5fc2V0dXBSZW5kZXJUYXJnZXRzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBVcGRhdGVzIHRoZSBiYWNrZ3JvdW5kIGFjY29yZGluZyB0byB0aGUgbmV3IG9wdGlvbnNcclxuICAgICAqIEBwYXJhbSBvcHRpb25zXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB1cGRhdGVPcHRpb25zKG9wdGlvbnM6IFBhcnRpYWw8SVRyYW5zbWlzc2lvbkhlbHBlck9wdGlvbnM+KSB7XHJcbiAgICAgICAgLy8gRmlyc3QgY2hlY2sgaWYgYW55IG9wdGlvbnMgYXJlIGFjdHVhbGx5IGJlaW5nIGNoYW5nZWQuIElmIG5vdCwgZXhpdC5cclxuICAgICAgICBjb25zdCBuZXdWYWx1ZXMgPSBPYmplY3Qua2V5cyhvcHRpb25zKS5maWx0ZXIoKGtleTogc3RyaW5nKSA9PiAodGhpcy5fb3B0aW9ucyBhcyBhbnkpW2tleV0gIT09IChvcHRpb25zIGFzIGFueSlba2V5XSk7XHJcbiAgICAgICAgaWYgKCFuZXdWYWx1ZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IG5ld09wdGlvbnMgPSB7XHJcbiAgICAgICAgICAgIC4uLnRoaXMuX29wdGlvbnMsXHJcbiAgICAgICAgICAgIC4uLm9wdGlvbnMsXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgY29uc3Qgb2xkT3B0aW9ucyA9IHRoaXMuX29wdGlvbnM7XHJcbiAgICAgICAgdGhpcy5fb3B0aW9ucyA9IG5ld09wdGlvbnM7XHJcblxyXG4gICAgICAgIC8vIElmIHNpemUgY2hhbmdlcywgcmVjcmVhdGUgZXZlcnl0aGluZ1xyXG4gICAgICAgIGlmIChcclxuICAgICAgICAgICAgbmV3T3B0aW9ucy5yZW5kZXJTaXplICE9PSBvbGRPcHRpb25zLnJlbmRlclNpemUgfHxcclxuICAgICAgICAgICAgbmV3T3B0aW9ucy5yZW5kZXJUYXJnZXRUZXh0dXJlVHlwZSAhPT0gb2xkT3B0aW9ucy5yZW5kZXJUYXJnZXRUZXh0dXJlVHlwZSB8fFxyXG4gICAgICAgICAgICBuZXdPcHRpb25zLmdlbmVyYXRlTWlwbWFwcyAhPT0gb2xkT3B0aW9ucy5nZW5lcmF0ZU1pcG1hcHMgfHxcclxuICAgICAgICAgICAgIXRoaXMuX29wYXF1ZVJlbmRlclRhcmdldFxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgICB0aGlzLl9zZXR1cFJlbmRlclRhcmdldHMoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQuc2FtcGxlcyA9IG5ld09wdGlvbnMuc2FtcGxlcztcclxuICAgICAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0LmxvZEdlbmVyYXRpb25TY2FsZSA9IG5ld09wdGlvbnMubG9kR2VuZXJhdGlvblNjYWxlO1xyXG4gICAgICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQubG9kR2VuZXJhdGlvbk9mZnNldCA9IG5ld09wdGlvbnMubG9kR2VuZXJhdGlvbk9mZnNldDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcmV0dXJucyB0aGUgb3BhcXVlIHJlbmRlciB0YXJnZXQgdGV4dHVyZSBvciBudWxsIGlmIG5vdCBhdmFpbGFibGUuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRPcGFxdWVUYXJnZXQoKTogTnVsbGFibGU8VGV4dHVyZT4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfc2hvdWxkUmVuZGVyQXNUcmFuc21pc3Npb24obWF0ZXJpYWw6IE51bGxhYmxlPE1hdGVyaWFsPik6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICghbWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAobWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCAmJiBtYXRlcmlhbC5zdWJTdXJmYWNlLmlzUmVmcmFjdGlvbkVuYWJsZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9hZGRNZXNoKG1lc2g6IEFic3RyYWN0TWVzaCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX21hdGVyaWFsT2JzZXJ2ZXJzW21lc2gudW5pcXVlSWRdID0gbWVzaC5vbk1hdGVyaWFsQ2hhbmdlZE9ic2VydmFibGUuYWRkKHRoaXMuX29uTWVzaE1hdGVyaWFsQ2hhbmdlZC5iaW5kKHRoaXMpKTtcclxuXHJcbiAgICAgICAgLy8gd2UgbmVlZCB0byBkZWZlciB0aGUgcHJvY2Vzc2luZyBiZWNhdXNlIF9hZGRNZXNoIG1heSBiZSBjYWxsZWQgYXMgcGFydCBhcyBhbiBpbnN0YW5jZSBtZXNoIGNyZWF0aW9uLCBpbiB3aGljaCBjYXNlIHNvbWVcclxuICAgICAgICAvLyBpbnRlcm5hbCBwcm9wZXJ0aWVzIGFyZSBub3Qgc2V0dXAgeWV0LCBsaWtlIF9zb3VyY2VNZXNoIChuZWVkZWQgd2hlbiBkb2luZyBtZXNoLm1hdGVyaWFsIGJlbG93KVxyXG4gICAgICAgIFRvb2xzLlNldEltbWVkaWF0ZSgoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9zaG91bGRSZW5kZXJBc1RyYW5zbWlzc2lvbihtZXNoLm1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICAgICAgKG1lc2gubWF0ZXJpYWwgYXMgUEJSTWF0ZXJpYWwpLnJlZnJhY3Rpb25UZXh0dXJlID0gdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0O1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3RyYW5zcGFyZW50TWVzaGVzQ2FjaGUuaW5kZXhPZihtZXNoKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmFuc3BhcmVudE1lc2hlc0NhY2hlLnB1c2gobWVzaCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fb3BhcXVlTWVzaGVzQ2FjaGUuaW5kZXhPZihtZXNoKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9vcGFxdWVNZXNoZXNDYWNoZS5wdXNoKG1lc2gpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfcmVtb3ZlTWVzaChtZXNoOiBBYnN0cmFjdE1lc2gpOiB2b2lkIHtcclxuICAgICAgICBtZXNoLm9uTWF0ZXJpYWxDaGFuZ2VkT2JzZXJ2YWJsZS5yZW1vdmUodGhpcy5fbWF0ZXJpYWxPYnNlcnZlcnNbbWVzaC51bmlxdWVJZF0pO1xyXG4gICAgICAgIGRlbGV0ZSB0aGlzLl9tYXRlcmlhbE9ic2VydmVyc1ttZXNoLnVuaXF1ZUlkXTtcclxuICAgICAgICBsZXQgaWR4ID0gdGhpcy5fdHJhbnNwYXJlbnRNZXNoZXNDYWNoZS5pbmRleE9mKG1lc2gpO1xyXG4gICAgICAgIGlmIChpZHggIT09IC0xKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3RyYW5zcGFyZW50TWVzaGVzQ2FjaGUuc3BsaWNlKGlkeCwgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlkeCA9IHRoaXMuX29wYXF1ZU1lc2hlc0NhY2hlLmluZGV4T2YobWVzaCk7XHJcbiAgICAgICAgaWYgKGlkeCAhPT0gLTEpIHtcclxuICAgICAgICAgICAgdGhpcy5fb3BhcXVlTWVzaGVzQ2FjaGUuc3BsaWNlKGlkeCwgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3BhcnNlU2NlbmUoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fc2NlbmUubWVzaGVzLmZvckVhY2godGhpcy5fYWRkTWVzaC5iaW5kKHRoaXMpKTtcclxuICAgICAgICAvLyBMaXN0ZW4gZm9yIHdoZW4gYSBtZXNoIGlzIGFkZGVkIHRvIHRoZSBzY2VuZSBhbmQgYWRkIGl0IHRvIG91ciBjYWNoZSBsaXN0cy5cclxuICAgICAgICB0aGlzLl9zY2VuZS5vbk5ld01lc2hBZGRlZE9ic2VydmFibGUuYWRkKHRoaXMuX2FkZE1lc2guYmluZCh0aGlzKSk7XHJcbiAgICAgICAgLy8gTGlzdGVuIGZvciB3aGVuIGEgbWVzaCBpcyByZW1vdmVkIGZyb20gdG8gdGhlIHNjZW5lIGFuZCByZW1vdmUgaXQgZnJvbSBvdXIgY2FjaGUgbGlzdHMuXHJcbiAgICAgICAgdGhpcy5fc2NlbmUub25NZXNoUmVtb3ZlZE9ic2VydmFibGUuYWRkKHRoaXMuX3JlbW92ZU1lc2guYmluZCh0aGlzKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gV2hlbiBvbmUgb2YgdGhlIG1lc2hlcyBpbiB0aGUgc2NlbmUgaGFzIGl0cyBtYXRlcmlhbCBjaGFuZ2VkLCBtYWtlIHN1cmUgdGhhdCBpdCdzIGluIHRoZSBjb3JyZWN0IGNhY2hlIGxpc3QuXHJcbiAgICBwcml2YXRlIF9vbk1lc2hNYXRlcmlhbENoYW5nZWQobWVzaDogQWJzdHJhY3RNZXNoKSB7XHJcbiAgICAgICAgY29uc3QgdHJhbnNwYXJlbnRJZHggPSB0aGlzLl90cmFuc3BhcmVudE1lc2hlc0NhY2hlLmluZGV4T2YobWVzaCk7XHJcbiAgICAgICAgY29uc3Qgb3BhcXVlSWR4ID0gdGhpcy5fb3BhcXVlTWVzaGVzQ2FjaGUuaW5kZXhPZihtZXNoKTtcclxuXHJcbiAgICAgICAgLy8gSWYgdGhlIG1hdGVyaWFsIGlzIHRyYW5zcGFyZW50LCBtYWtlIHN1cmUgdGhhdCBpdCdzIGFkZGVkIHRvIHRoZSB0cmFuc3BhcmVudCBsaXN0IGFuZCByZW1vdmVkIGZyb20gdGhlIG9wYXF1ZSBsaXN0XHJcbiAgICAgICAgY29uc3QgdXNlVHJhbnNtaXNzaW9uID0gdGhpcy5fc2hvdWxkUmVuZGVyQXNUcmFuc21pc3Npb24obWVzaC5tYXRlcmlhbCk7XHJcbiAgICAgICAgaWYgKHVzZVRyYW5zbWlzc2lvbikge1xyXG4gICAgICAgICAgICBpZiAobWVzaC5tYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSB7XHJcbiAgICAgICAgICAgICAgICBtZXNoLm1hdGVyaWFsLnN1YlN1cmZhY2UucmVmcmFjdGlvblRleHR1cmUgPSB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKG9wYXF1ZUlkeCAhPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX29wYXF1ZU1lc2hlc0NhY2hlLnNwbGljZShvcGFxdWVJZHgsIDEpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdHJhbnNwYXJlbnRNZXNoZXNDYWNoZS5wdXNoKG1lc2gpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRyYW5zcGFyZW50SWR4ID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdHJhbnNwYXJlbnRNZXNoZXNDYWNoZS5wdXNoKG1lc2gpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIElmIHRoZSBtYXRlcmlhbCBpcyBvcGFxdWUsIG1ha2Ugc3VyZSB0aGF0IGl0J3MgYWRkZWQgdG8gdGhlIG9wYXF1ZSBsaXN0IGFuZCByZW1vdmVkIGZyb20gdGhlIHRyYW5zcGFyZW50IGxpc3RcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAodHJhbnNwYXJlbnRJZHggIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl90cmFuc3BhcmVudE1lc2hlc0NhY2hlLnNwbGljZSh0cmFuc3BhcmVudElkeCwgMSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9vcGFxdWVNZXNoZXNDYWNoZS5wdXNoKG1lc2gpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKG9wYXF1ZUlkeCA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX29wYXF1ZU1lc2hlc0NhY2hlLnB1c2gobWVzaCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqIENoZWNrIGlmIHRoZSBvcGFxdWUgcmVuZGVyIHRhcmdldCBoYXMgbm90IGJlZW4gZGlzcG9zZWQgYW5kIGNhbiBzdGlsbCBiZSB1c2VkLlxyXG4gICAgICogQHJldHVybnNcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9pc1JlbmRlclRhcmdldFZhbGlkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQ/LmdldEludGVybmFsVGV4dHVyZSgpICE9PSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKiBTZXR1cCB0aGUgcmVuZGVyIHRhcmdldHMgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgb3B0aW9ucy5cclxuICAgICAqL1xyXG4gICAgcHVibGljIF9zZXR1cFJlbmRlclRhcmdldHMoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuX29wYXF1ZVJlbmRlclRhcmdldCkge1xyXG4gICAgICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQuZGlzcG9zZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQgPSBuZXcgUmVuZGVyVGFyZ2V0VGV4dHVyZShcclxuICAgICAgICAgICAgXCJvcGFxdWVTY2VuZVRleHR1cmVcIixcclxuICAgICAgICAgICAgdGhpcy5fb3B0aW9ucy5yZW5kZXJTaXplLFxyXG4gICAgICAgICAgICB0aGlzLl9zY2VuZSxcclxuICAgICAgICAgICAgdGhpcy5fb3B0aW9ucy5nZW5lcmF0ZU1pcG1hcHMsXHJcbiAgICAgICAgICAgIHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgdGhpcy5fb3B0aW9ucy5yZW5kZXJUYXJnZXRUZXh0dXJlVHlwZVxyXG4gICAgICAgICk7XHJcbiAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0Lmlnbm9yZUNhbWVyYVZpZXdwb3J0ID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQucmVuZGVyTGlzdCA9IHRoaXMuX29wYXF1ZU1lc2hlc0NhY2hlO1xyXG4gICAgICAgIHRoaXMuX29wYXF1ZVJlbmRlclRhcmdldC5jbGVhckNvbG9yID0gdGhpcy5fb3B0aW9ucy5jbGVhckNvbG9yPy5jbG9uZSgpID8/IHRoaXMuX3NjZW5lLmNsZWFyQ29sb3IuY2xvbmUoKTtcclxuICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQuZ2FtbWFTcGFjZSA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuX29wYXF1ZVJlbmRlclRhcmdldC5sb2RHZW5lcmF0aW9uU2NhbGUgPSB0aGlzLl9vcHRpb25zLmxvZEdlbmVyYXRpb25TY2FsZTtcclxuICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQubG9kR2VuZXJhdGlvbk9mZnNldCA9IHRoaXMuX29wdGlvbnMubG9kR2VuZXJhdGlvbk9mZnNldDtcclxuICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQuc2FtcGxlcyA9IHRoaXMuX29wdGlvbnMuc2FtcGxlcztcclxuICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQucmVuZGVyU3ByaXRlcyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0LnJlbmRlclBhcnRpY2xlcyA9IHRydWU7XHJcblxyXG4gICAgICAgIGxldCBzY2VuZUltYWdlUHJvY2Vzc2luZ2FwcGx5QnlQb3N0UHJvY2VzczogYm9vbGVhbjtcclxuXHJcbiAgICAgICAgbGV0IHNhdmVTY2VuZUVudkludGVuc2l0eTogbnVtYmVyO1xyXG4gICAgICAgIHRoaXMuX29wYXF1ZVJlbmRlclRhcmdldC5vbkJlZm9yZUJpbmRPYnNlcnZhYmxlLmFkZCgob3BhcXVlUmVuZGVyVGFyZ2V0KSA9PiB7XHJcbiAgICAgICAgICAgIHNhdmVTY2VuZUVudkludGVuc2l0eSA9IHRoaXMuX3NjZW5lLmVudmlyb25tZW50SW50ZW5zaXR5O1xyXG4gICAgICAgICAgICB0aGlzLl9zY2VuZS5lbnZpcm9ubWVudEludGVuc2l0eSA9IDEuMDtcclxuICAgICAgICAgICAgc2NlbmVJbWFnZVByb2Nlc3NpbmdhcHBseUJ5UG9zdFByb2Nlc3MgPSB0aGlzLl9zY2VuZS5pbWFnZVByb2Nlc3NpbmdDb25maWd1cmF0aW9uLmFwcGx5QnlQb3N0UHJvY2VzcztcclxuICAgICAgICAgICAgaWYgKCF0aGlzLl9vcHRpb25zLmNsZWFyQ29sb3IpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3NjZW5lLmNsZWFyQ29sb3IudG9MaW5lYXJTcGFjZVRvUmVmKG9wYXF1ZVJlbmRlclRhcmdldC5jbGVhckNvbG9yLCB0aGlzLl9zY2VuZS5nZXRFbmdpbmUoKS51c2VFeGFjdFNyZ2JDb252ZXJzaW9ucyk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBvcGFxdWVSZW5kZXJUYXJnZXQuY2xlYXJDb2xvci5jb3B5RnJvbSh0aGlzLl9vcHRpb25zLmNsZWFyQ29sb3IpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB1c2UgdGhlIGFwcGx5QnlQb3N0UHJvY2VzcyBzZXR0ZXIgdG8gYXZvaWQgZmxhZ2dpbmcgYWxsIHRoZSBtYXRlcmlhbHMgYXMgXCJpbWFnZSBwcm9jZXNzaW5nIGRpcnR5XCIhXHJcbiAgICAgICAgICAgIHRoaXMuX3NjZW5lLmltYWdlUHJvY2Vzc2luZ0NvbmZpZ3VyYXRpb24uX2FwcGx5QnlQb3N0UHJvY2VzcyA9IHRydWU7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5fb3BhcXVlUmVuZGVyVGFyZ2V0Lm9uQWZ0ZXJVbmJpbmRPYnNlcnZhYmxlLmFkZCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX3NjZW5lLmVudmlyb25tZW50SW50ZW5zaXR5ID0gc2F2ZVNjZW5lRW52SW50ZW5zaXR5O1xyXG4gICAgICAgICAgICB0aGlzLl9zY2VuZS5pbWFnZVByb2Nlc3NpbmdDb25maWd1cmF0aW9uLl9hcHBseUJ5UG9zdFByb2Nlc3MgPSBzY2VuZUltYWdlUHJvY2Vzc2luZ2FwcGx5QnlQb3N0UHJvY2VzcztcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5fdHJhbnNwYXJlbnRNZXNoZXNDYWNoZS5mb3JFYWNoKChtZXNoOiBBYnN0cmFjdE1lc2gpID0+IHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX3Nob3VsZFJlbmRlckFzVHJhbnNtaXNzaW9uKG1lc2gubWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgICAgICAobWVzaC5tYXRlcmlhbCBhcyBQQlJNYXRlcmlhbCkucmVmcmFjdGlvblRleHR1cmUgPSB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERpc3Bvc2UgYWxsIHRoZSBlbGVtZW50cyBjcmVhdGVkIGJ5IHRoZSBIZWxwZXIuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX3NjZW5lLl90cmFuc21pc3Npb25IZWxwZXIgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgaWYgKHRoaXMuX29wYXF1ZVJlbmRlclRhcmdldCkge1xyXG4gICAgICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICB0aGlzLl9vcGFxdWVSZW5kZXJUYXJnZXQgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl90cmFuc3BhcmVudE1lc2hlc0NhY2hlID0gW107XHJcbiAgICAgICAgdGhpcy5fb3BhcXVlTWVzaGVzQ2FjaGUgPSBbXTtcclxuICAgIH1cclxufVxyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX21hdGVyaWFsc190cmFuc21pc3Npb25cIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX21hdGVyaWFsc190cmFuc21pc3Npb24gZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfdHJhbnNtaXNzaW9uXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0tocm9ub3MvS0hSX21hdGVyaWFsc190cmFuc21pc3Npb24vUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21hdGVyaWFsc190cmFuc21pc3Npb24gaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDE3NTtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICAgICAgaWYgKHRoaXMuZW5hYmxlZCkge1xyXG4gICAgICAgICAgICBsb2FkZXIucGFyZW50LnRyYW5zcGFyZW5jeUFzQ292ZXJhZ2UgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRlbnNpb25Bc3luYzxJS0hSTWF0ZXJpYWxzVHJhbnNtaXNzaW9uPihjb250ZXh0LCBtYXRlcmlhbCwgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8YW55Pj4oKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkZXIubG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkVHJhbnNwYXJlbnRQcm9wZXJ0aWVzQXN5bmMoZXh0ZW5zaW9uQ29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCwgZXh0ZW5zaW9uKSk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZFRyYW5zcGFyZW50UHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCwgZXh0ZW5zaW9uOiBJS0hSTWF0ZXJpYWxzVHJhbnNtaXNzaW9uKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogTWF0ZXJpYWwgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHBick1hdGVyaWFsID0gYmFieWxvbk1hdGVyaWFsIGFzIFBCUk1hdGVyaWFsO1xyXG5cclxuICAgICAgICAvLyBFbmFibGVzIFwicmVmcmFjdGlvblwiIHRleHR1cmUgd2hpY2ggcmVwcmVzZW50cyB0cmFuc21pdHRlZCBsaWdodC5cclxuICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLmlzUmVmcmFjdGlvbkVuYWJsZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICAvLyBTaW5jZSB0aGlzIGV4dGVuc2lvbiBtb2RlbHMgdGhpbi1zdXJmYWNlIHRyYW5zbWlzc2lvbiBvbmx5LCB3ZSBtdXN0IG1ha2UgSU9SID0gMS4wXHJcbiAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS52b2x1bWVJbmRleE9mUmVmcmFjdGlvbiA9IDEuMDtcclxuXHJcbiAgICAgICAgLy8gQWxiZWRvIGNvbG91ciB3aWxsIHRpbnQgdHJhbnNtaXNzaW9uLlxyXG4gICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UudXNlQWxiZWRvVG9UaW50UmVmcmFjdGlvbiA9IHRydWU7XHJcblxyXG4gICAgICAgIGlmIChleHRlbnNpb24udHJhbnNtaXNzaW9uRmFjdG9yICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS5yZWZyYWN0aW9uSW50ZW5zaXR5ID0gZXh0ZW5zaW9uLnRyYW5zbWlzc2lvbkZhY3RvcjtcclxuICAgICAgICAgICAgY29uc3Qgc2NlbmUgPSBwYnJNYXRlcmlhbC5nZXRTY2VuZSgpIGFzIHVua25vd24gYXMgSVRyYW5zbWlzc2lvbkhlbHBlckhvbGRlcjtcclxuICAgICAgICAgICAgaWYgKHBick1hdGVyaWFsLnN1YlN1cmZhY2UucmVmcmFjdGlvbkludGVuc2l0eSAmJiAhc2NlbmUuX3RyYW5zbWlzc2lvbkhlbHBlcikge1xyXG4gICAgICAgICAgICAgICAgbmV3IFRyYW5zbWlzc2lvbkhlbHBlcih7fSwgcGJyTWF0ZXJpYWwuZ2V0U2NlbmUoKSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS5yZWZyYWN0aW9uSW50ZW5zaXR5ICYmICFzY2VuZS5fdHJhbnNtaXNzaW9uSGVscGVyPy5faXNSZW5kZXJUYXJnZXRWYWxpZCgpKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgcmVuZGVyIHRhcmdldCBpcyBub3QgdmFsaWQsIHJlY3JlYXRlIGl0LlxyXG4gICAgICAgICAgICAgICAgc2NlbmUuX3RyYW5zbWlzc2lvbkhlbHBlcj8uX3NldHVwUmVuZGVyVGFyZ2V0cygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS5yZWZyYWN0aW9uSW50ZW5zaXR5ID0gMC4wO1xyXG4gICAgICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLmlzUmVmcmFjdGlvbkVuYWJsZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcGJyTWF0ZXJpYWwuc3ViU3VyZmFjZS5taW5pbXVtVGhpY2tuZXNzID0gMC4wO1xyXG4gICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UubWF4aW11bVRoaWNrbmVzcyA9IDAuMDtcclxuICAgICAgICBpZiAoZXh0ZW5zaW9uLnRyYW5zbWlzc2lvblRleHR1cmUpIHtcclxuICAgICAgICAgICAgKGV4dGVuc2lvbi50cmFuc21pc3Npb25UZXh0dXJlIGFzIElUZXh0dXJlSW5mbykubm9uQ29sb3JEYXRhID0gdHJ1ZTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRlci5sb2FkVGV4dHVyZUluZm9Bc3luYyhgJHtjb250ZXh0fS90cmFuc21pc3Npb25UZXh0dXJlYCwgZXh0ZW5zaW9uLnRyYW5zbWlzc2lvblRleHR1cmUsIHVuZGVmaW5lZCkudGhlbigodGV4dHVyZTogQmFzZVRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoVHJhbnNtaXNzaW9uKWA7XHJcbiAgICAgICAgICAgICAgICBwYnJNYXRlcmlhbC5zdWJTdXJmYWNlLnJlZnJhY3Rpb25JbnRlbnNpdHlUZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIHBick1hdGVyaWFsLnN1YlN1cmZhY2UudXNlR2x0ZlN0eWxlVGV4dHVyZXMgPSB0cnVlO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfbWF0ZXJpYWxzX3RyYW5zbWlzc2lvbihsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IENvbG9yMyB9IGZyb20gXCJjb3JlL01hdGhzL21hdGguY29sb3JcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSU1hdGVyaWFsIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl9tYXRlcmlhbHNfdW5saXRcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgS0hSX21hdGVyaWFsc191bmxpdCBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiS0hSX21hdGVyaWFsc191bmxpdFwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl9tYXRlcmlhbHNfdW5saXQvUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21hdGVyaWFsc191bmxpdCBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgYSBudW1iZXIgdGhhdCBkZXRlcm1pbmVzIHRoZSBvcmRlciB0aGUgZXh0ZW5zaW9ucyBhcmUgYXBwbGllZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9yZGVyID0gMjEwO1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRlbnNpb25Bc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgdGhpcy5uYW1lLCAoKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkVW5saXRQcm9wZXJ0aWVzQXN5bmMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZFVubGl0UHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IE1hdGVyaWFsIHR5cGUgbm90IHN1cHBvcnRlZGApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC51bmxpdCA9IHRydWU7XHJcblxyXG4gICAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSBtYXRlcmlhbC5wYnJNZXRhbGxpY1JvdWdobmVzcztcclxuICAgICAgICBpZiAocHJvcGVydGllcykge1xyXG4gICAgICAgICAgICBpZiAocHJvcGVydGllcy5iYXNlQ29sb3JGYWN0b3IpIHtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbGJlZG9Db2xvciA9IENvbG9yMy5Gcm9tQXJyYXkocHJvcGVydGllcy5iYXNlQ29sb3JGYWN0b3IpO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmFscGhhID0gcHJvcGVydGllcy5iYXNlQ29sb3JGYWN0b3JbM107XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvQ29sb3IgPSBDb2xvcjMuV2hpdGUoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMuYmFzZUNvbG9yVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vYmFzZUNvbG9yVGV4dHVyZWAsIHByb3BlcnRpZXMuYmFzZUNvbG9yVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dHVyZS5uYW1lID0gYCR7YmFieWxvbk1hdGVyaWFsLm5hbWV9IChCYXNlIENvbG9yKWA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbGJlZG9UZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKG1hdGVyaWFsLmRvdWJsZVNpZGVkKSB7XHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5iYWNrRmFjZUN1bGxpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnR3b1NpZGVkTGlnaHRpbmcgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbEFscGhhUHJvcGVydGllcyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX21hdGVyaWFsc191bmxpdChsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyLCBBcnJheUl0ZW0gfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5cclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcImNvcmUvTWVzaGVzL21lc2hcIjtcclxuaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSBcImNvcmUvbm9kZVwiO1xyXG5pbXBvcnQgdHlwZSB7IEFic3RyYWN0TWVzaCB9IGZyb20gXCJjb3JlL01lc2hlcy9hYnN0cmFjdE1lc2hcIjtcclxuaW1wb3J0IHR5cGUgeyBJTm9kZSwgSU1lc2hQcmltaXRpdmUsIElNZXNoIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUtIUk1hdGVyaWFsVmFyaWFudHNfTWFwcGluZywgSUtIUk1hdGVyaWFsVmFyaWFudHNfVmFyaWFudCwgSUtIUk1hdGVyaWFsVmFyaWFudHNfVmFyaWFudHMgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB0eXBlIHsgVHJhbnNmb3JtTm9kZSB9IGZyb20gXCJjb3JlL01lc2hlcy90cmFuc2Zvcm1Ob2RlXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWF0ZXJpYWxzX3ZhcmlhbnRzXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9tYXRlcmlhbHNfdmFyaWFudHMgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tYXRlcmlhbHNfdmFyaWFudHNcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG5pbnRlcmZhY2UgSVZhcmlhbnRzTWFwIHtcclxuICAgIFtrZXk6IHN0cmluZ106IEFycmF5PHsgbWVzaDogQWJzdHJhY3RNZXNoOyBtYXRlcmlhbDogTnVsbGFibGU8TWF0ZXJpYWw+IH0+O1xyXG59XHJcblxyXG5pbnRlcmZhY2UgSUV4dGVuc2lvbk1ldGFkYXRhIHtcclxuICAgIGxhc3RTZWxlY3RlZDogTnVsbGFibGU8c3RyaW5nIHwgQXJyYXk8c3RyaW5nPj47XHJcbiAgICBvcmlnaW5hbDogQXJyYXk8eyBtZXNoOiBBYnN0cmFjdE1lc2g7IG1hdGVyaWFsOiBOdWxsYWJsZTxNYXRlcmlhbD4gfT47XHJcbiAgICB2YXJpYW50czogSVZhcmlhbnRzTWFwO1xyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbWF0ZXJpYWxzX3ZhcmlhbnRzL1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl9tYXRlcmlhbHNfdmFyaWFudHMgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIHByaXZhdGUgX3ZhcmlhbnRzPzogQXJyYXk8SUtIUk1hdGVyaWFsVmFyaWFudHNfVmFyaWFudD47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGxpc3Qgb2YgYXZhaWxhYmxlIHZhcmlhbnQgbmFtZXMgZm9yIHRoaXMgYXNzZXQuXHJcbiAgICAgKiBAcGFyYW0gcm9vdE1lc2ggVGhlIGdsVEYgcm9vdCBtZXNoXHJcbiAgICAgKiBAcmV0dXJucyB0aGUgbGlzdCBvZiBhbGwgdGhlIHZhcmlhbnQgbmFtZXMgZm9yIHRoaXMgbW9kZWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBHZXRBdmFpbGFibGVWYXJpYW50cyhyb290TWVzaDogTWVzaCk6IHN0cmluZ1tdIHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25NZXRhZGF0YSA9IHRoaXMuX0dldEV4dGVuc2lvbk1ldGFkYXRhKHJvb3RNZXNoKTtcclxuICAgICAgICBpZiAoIWV4dGVuc2lvbk1ldGFkYXRhKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhleHRlbnNpb25NZXRhZGF0YS52YXJpYW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBsaXN0IG9mIGF2YWlsYWJsZSB2YXJpYW50IG5hbWVzIGZvciB0aGlzIGFzc2V0LlxyXG4gICAgICogQHBhcmFtIHJvb3RNZXNoIFRoZSBnbFRGIHJvb3QgbWVzaFxyXG4gICAgICogQHJldHVybnMgdGhlIGxpc3Qgb2YgYWxsIHRoZSB2YXJpYW50IG5hbWVzIGZvciB0aGlzIG1vZGVsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRBdmFpbGFibGVWYXJpYW50cyhyb290TWVzaDogTWVzaCk6IHN0cmluZ1tdIHtcclxuICAgICAgICByZXR1cm4gS0hSX21hdGVyaWFsc192YXJpYW50cy5HZXRBdmFpbGFibGVWYXJpYW50cyhyb290TWVzaCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZWxlY3QgYSB2YXJpYW50IGdpdmVuIGEgdmFyaWFudCBuYW1lIG9yIGEgbGlzdCBvZiB2YXJpYW50IG5hbWVzLlxyXG4gICAgICogQHBhcmFtIHJvb3RNZXNoIFRoZSBnbFRGIHJvb3QgbWVzaFxyXG4gICAgICogQHBhcmFtIHZhcmlhbnROYW1lIFRoZSB2YXJpYW50IG5hbWUocykgdG8gc2VsZWN0LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIFNlbGVjdFZhcmlhbnQocm9vdE1lc2g6IE1lc2gsIHZhcmlhbnROYW1lOiBzdHJpbmcgfCBzdHJpbmdbXSk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbk1ldGFkYXRhID0gdGhpcy5fR2V0RXh0ZW5zaW9uTWV0YWRhdGEocm9vdE1lc2gpO1xyXG4gICAgICAgIGlmICghZXh0ZW5zaW9uTWV0YWRhdGEpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3Qgc2VsZWN0IHZhcmlhbnQgb24gYSBnbFRGIG1lc2ggdGhhdCBkb2VzIG5vdCBoYXZlIHRoZSAke05BTUV9IGV4dGVuc2lvbmApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3Qgc2VsZWN0ID0gKHZhcmlhbnROYW1lOiBzdHJpbmcpOiB2b2lkID0+IHtcclxuICAgICAgICAgICAgY29uc3QgZW50cmllcyA9IGV4dGVuc2lvbk1ldGFkYXRhLnZhcmlhbnRzW3ZhcmlhbnROYW1lXTtcclxuICAgICAgICAgICAgaWYgKGVudHJpZXMpIHtcclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xyXG4gICAgICAgICAgICAgICAgICAgIGVudHJ5Lm1lc2gubWF0ZXJpYWwgPSBlbnRyeS5tYXRlcmlhbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGlmICh2YXJpYW50TmFtZSBpbnN0YW5jZW9mIEFycmF5KSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiB2YXJpYW50TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgc2VsZWN0KG5hbWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgc2VsZWN0KHZhcmlhbnROYW1lKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGV4dGVuc2lvbk1ldGFkYXRhLmxhc3RTZWxlY3RlZCA9IHZhcmlhbnROYW1lO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2VsZWN0IGEgdmFyaWFudCBnaXZlbiBhIHZhcmlhbnQgbmFtZSBvciBhIGxpc3Qgb2YgdmFyaWFudCBuYW1lcy5cclxuICAgICAqIEBwYXJhbSByb290TWVzaCBUaGUgZ2xURiByb290IG1lc2hcclxuICAgICAqIEBwYXJhbSB2YXJpYW50TmFtZSBUaGUgdmFyaWFudCBuYW1lKHMpIHRvIHNlbGVjdC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHNlbGVjdFZhcmlhbnQocm9vdE1lc2g6IE1lc2gsIHZhcmlhbnROYW1lOiBzdHJpbmcgfCBzdHJpbmdbXSk6IHZvaWQge1xyXG4gICAgICAgIEtIUl9tYXRlcmlhbHNfdmFyaWFudHMuU2VsZWN0VmFyaWFudChyb290TWVzaCwgdmFyaWFudE5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVzZXQgYmFjayB0byB0aGUgb3JpZ2luYWwgYmVmb3JlIHNlbGVjdGluZyBhIHZhcmlhbnQuXHJcbiAgICAgKiBAcGFyYW0gcm9vdE1lc2ggVGhlIGdsVEYgcm9vdCBtZXNoXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgUmVzZXQocm9vdE1lc2g6IE1lc2gpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25NZXRhZGF0YSA9IHRoaXMuX0dldEV4dGVuc2lvbk1ldGFkYXRhKHJvb3RNZXNoKTtcclxuICAgICAgICBpZiAoIWV4dGVuc2lvbk1ldGFkYXRhKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHJlc2V0IG9uIGEgZ2xURiBtZXNoIHRoYXQgZG9lcyBub3QgaGF2ZSB0aGUgJHtOQU1FfSBleHRlbnNpb25gKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgZXh0ZW5zaW9uTWV0YWRhdGEub3JpZ2luYWwpIHtcclxuICAgICAgICAgICAgZW50cnkubWVzaC5tYXRlcmlhbCA9IGVudHJ5Lm1hdGVyaWFsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZXh0ZW5zaW9uTWV0YWRhdGEubGFzdFNlbGVjdGVkID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlc2V0IGJhY2sgdG8gdGhlIG9yaWdpbmFsIGJlZm9yZSBzZWxlY3RpbmcgYSB2YXJpYW50LlxyXG4gICAgICogQHBhcmFtIHJvb3RNZXNoIFRoZSBnbFRGIHJvb3QgbWVzaFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVzZXQocm9vdE1lc2g6IE1lc2gpOiB2b2lkIHtcclxuICAgICAgICBLSFJfbWF0ZXJpYWxzX3ZhcmlhbnRzLlJlc2V0KHJvb3RNZXNoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGxhc3Qgc2VsZWN0ZWQgdmFyaWFudCBuYW1lKHMpIG9yIG51bGwgaWYgb3JpZ2luYWwuXHJcbiAgICAgKiBAcGFyYW0gcm9vdE1lc2ggVGhlIGdsVEYgcm9vdCBtZXNoXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgc2VsZWN0ZWQgdmFyaWFudCBuYW1lKHMpLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIEdldExhc3RTZWxlY3RlZFZhcmlhbnQocm9vdE1lc2g6IE1lc2gpOiBOdWxsYWJsZTxzdHJpbmcgfCBzdHJpbmdbXT4ge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbk1ldGFkYXRhID0gdGhpcy5fR2V0RXh0ZW5zaW9uTWV0YWRhdGEocm9vdE1lc2gpO1xyXG4gICAgICAgIGlmICghZXh0ZW5zaW9uTWV0YWRhdGEpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZ2V0IHRoZSBsYXN0IHNlbGVjdGVkIHZhcmlhbnQgb24gYSBnbFRGIG1lc2ggdGhhdCBkb2VzIG5vdCBoYXZlIHRoZSAke05BTUV9IGV4dGVuc2lvbmApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGV4dGVuc2lvbk1ldGFkYXRhLmxhc3RTZWxlY3RlZDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGxhc3Qgc2VsZWN0ZWQgdmFyaWFudCBuYW1lKHMpIG9yIG51bGwgaWYgb3JpZ2luYWwuXHJcbiAgICAgKiBAcGFyYW0gcm9vdE1lc2ggVGhlIGdsVEYgcm9vdCBtZXNoXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgc2VsZWN0ZWQgdmFyaWFudCBuYW1lKHMpLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0TGFzdFNlbGVjdGVkVmFyaWFudChyb290TWVzaDogTWVzaCk6IE51bGxhYmxlPHN0cmluZyB8IHN0cmluZ1tdPiB7XHJcbiAgICAgICAgcmV0dXJuIEtIUl9tYXRlcmlhbHNfdmFyaWFudHMuR2V0TGFzdFNlbGVjdGVkVmFyaWFudChyb290TWVzaCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX0dldEV4dGVuc2lvbk1ldGFkYXRhKHJvb3RNZXNoOiBOdWxsYWJsZTxUcmFuc2Zvcm1Ob2RlPik6IE51bGxhYmxlPElFeHRlbnNpb25NZXRhZGF0YT4ge1xyXG4gICAgICAgIHJldHVybiByb290TWVzaD8uX2ludGVybmFsTWV0YWRhdGE/LmdsdGY/LltOQU1FXSB8fCBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBvbkxvYWRpbmcoKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9ucyA9IHRoaXMuX2xvYWRlci5nbHRmLmV4dGVuc2lvbnM7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvbnMgJiYgZXh0ZW5zaW9uc1t0aGlzLm5hbWVdKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IGV4dGVuc2lvbnNbdGhpcy5uYW1lXSBhcyBJS0hSTWF0ZXJpYWxWYXJpYW50c19WYXJpYW50cztcclxuICAgICAgICAgICAgdGhpcy5fdmFyaWFudHMgPSBleHRlbnNpb24udmFyaWFudHM7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbG9hZE1lc2hQcmltaXRpdmVBc3luYyhcclxuICAgICAgICBjb250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgbmFtZTogc3RyaW5nLFxyXG4gICAgICAgIG5vZGU6IElOb2RlLFxyXG4gICAgICAgIG1lc2g6IElNZXNoLFxyXG4gICAgICAgIHByaW1pdGl2ZTogSU1lc2hQcmltaXRpdmUsXHJcbiAgICAgICAgYXNzaWduOiAoYmFieWxvbk1lc2g6IEFic3RyYWN0TWVzaCkgPT4gdm9pZFxyXG4gICAgKTogTnVsbGFibGU8UHJvbWlzZTxBYnN0cmFjdE1lc2g+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElLSFJNYXRlcmlhbFZhcmlhbnRzX01hcHBpbmcsIEFic3RyYWN0TWVzaD4oY29udGV4dCwgcHJpbWl0aXZlLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLl9sb2FkTWVzaFByaW1pdGl2ZUFzeW5jKGNvbnRleHQsIG5hbWUsIG5vZGUsIG1lc2gsIHByaW1pdGl2ZSwgKGJhYnlsb25NZXNoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXNzaWduKGJhYnlsb25NZXNoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJhYnlsb25NZXNoIGluc3RhbmNlb2YgTWVzaCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uRHJhd01vZGUgPSBHTFRGTG9hZGVyLl9HZXREcmF3TW9kZShjb250ZXh0LCBwcmltaXRpdmUubW9kZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByb290ID0gdGhpcy5fbG9hZGVyLnJvb3RCYWJ5bG9uTWVzaDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWV0YWRhdGEgPSByb290ID8gKHJvb3QuX2ludGVybmFsTWV0YWRhdGEgPSByb290Ll9pbnRlcm5hbE1ldGFkYXRhIHx8IHt9KSA6IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnbHRmID0gKG1ldGFkYXRhLmdsdGYgPSBtZXRhZGF0YS5nbHRmIHx8IHt9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uTWV0YWRhdGE6IElFeHRlbnNpb25NZXRhZGF0YSA9IChnbHRmW05BTUVdID0gZ2x0ZltOQU1FXSB8fCB7IGxhc3RTZWxlY3RlZDogbnVsbCwgb3JpZ2luYWw6IFtdLCB2YXJpYW50czoge30gfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBTdG9yZSB0aGUgb3JpZ2luYWwgbWF0ZXJpYWwuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbk1ldGFkYXRhLm9yaWdpbmFsLnB1c2goeyBtZXNoOiBiYWJ5bG9uTWVzaCwgbWF0ZXJpYWw6IGJhYnlsb25NZXNoLm1hdGVyaWFsIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yIGVhY2ggbWFwcGluZywgbG9vayBhdCB0aGUgdmFyaWFudHMgYW5kIG1ha2UgYSBuZXcgZW50cnkgZm9yIHRoZW0uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IG1hcHBpbmdJbmRleCA9IDA7IG1hcHBpbmdJbmRleCA8IGV4dGVuc2lvbi5tYXBwaW5ncy5sZW5ndGg7ICsrbWFwcGluZ0luZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXBwaW5nID0gZXh0ZW5zaW9uLm1hcHBpbmdzW21hcHBpbmdJbmRleF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXRlcmlhbCA9IEFycmF5SXRlbS5HZXQoYCR7ZXh0ZW5zaW9uQ29udGV4dH0vbWFwcGluZ3MvJHttYXBwaW5nSW5kZXh9L21hdGVyaWFsYCwgdGhpcy5fbG9hZGVyLmdsdGYubWF0ZXJpYWxzLCBtYXBwaW5nLm1hdGVyaWFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLl9sb2FkTWF0ZXJpYWxBc3luYyhgIy9tYXRlcmlhbHMvJHttYXBwaW5nLm1hdGVyaWFsfWAsIG1hdGVyaWFsLCBiYWJ5bG9uTWVzaCwgYmFieWxvbkRyYXdNb2RlLCAoYmFieWxvbk1hdGVyaWFsKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IG1hcHBpbmdWYXJpYW50SW5kZXggPSAwOyBtYXBwaW5nVmFyaWFudEluZGV4IDwgbWFwcGluZy52YXJpYW50cy5sZW5ndGg7ICsrbWFwcGluZ1ZhcmlhbnRJbmRleCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFyaWFudEluZGV4ID0gbWFwcGluZy52YXJpYW50c1ttYXBwaW5nVmFyaWFudEluZGV4XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhcmlhbnQgPSBBcnJheUl0ZW0uR2V0KGAvZXh0ZW5zaW9ucy8ke05BTUV9L3ZhcmlhbnRzLyR7dmFyaWFudEluZGV4fWAsIHRoaXMuX3ZhcmlhbnRzLCB2YXJpYW50SW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uTWV0YWRhdGEudmFyaWFudHNbdmFyaWFudC5uYW1lXSA9IGV4dGVuc2lvbk1ldGFkYXRhLnZhcmlhbnRzW3ZhcmlhbnQubmFtZV0gfHwgW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25NZXRhZGF0YS52YXJpYW50c1t2YXJpYW50Lm5hbWVdLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc2g6IGJhYnlsb25NZXNoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGVyaWFsOiBiYWJ5bG9uTWF0ZXJpYWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXBsYWNlIHRoZSB0YXJnZXQgd2hlbiBvcmlnaW5hbCBtZXNoIGlzIGNsb25lZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1lc2gub25DbG9uZWRPYnNlcnZhYmxlLmFkZCgobmV3T25lOiBOb2RlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3TWVzaCA9IG5ld09uZSBhcyBNZXNoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBtZXRhZGF0YTogTnVsbGFibGU8SUV4dGVuc2lvbk1ldGFkYXRhPiA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG5ld1Jvb3Q6IE51bGxhYmxlPE5vZGU+ID0gbmV3TWVzaDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmluZCByb290IHRvIGdldCBtZWRhdGFcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkbyB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Jvb3QgPSBuZXdSb290IS5wYXJlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbmV3Um9vdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhID0gS0hSX21hdGVyaWFsc192YXJpYW50cy5fR2V0RXh0ZW5zaW9uTWV0YWRhdGEobmV3Um9vdCBhcyBNZXNoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IHdoaWxlIChtZXRhZGF0YSA9PT0gbnVsbCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5lZWQgdG8gY2xvbmUgdGhlIG1ldGFkYXRhIG9uIHRoZSByb290IChmaXJzdCB0aW1lIG9ubHkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJvb3QgJiYgbWV0YWRhdGEgPT09IEtIUl9tYXRlcmlhbHNfdmFyaWFudHMuX0dldEV4dGVuc2lvbk1ldGFkYXRhKHJvb3QpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvcHkgbWFpbiBtZXRhZGF0YVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdSb290Ll9pbnRlcm5hbE1ldGFkYXRhID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHJvb3QuX2ludGVybmFsTWV0YWRhdGEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Jvb3QuX2ludGVybmFsTWV0YWRhdGFba2V5XSA9IHJvb3QuX2ludGVybmFsTWV0YWRhdGFba2V5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29weSB0aGUgZ2x0ZiBtZXRhZGF0YVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdSb290Ll9pbnRlcm5hbE1ldGFkYXRhLmdsdGYgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gcm9vdC5faW50ZXJuYWxNZXRhZGF0YS5nbHRmKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdSb290Ll9pbnRlcm5hbE1ldGFkYXRhLmdsdGZba2V5XSA9IHJvb3QuX2ludGVybmFsTWV0YWRhdGEuZ2x0ZltrZXldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEdXBsaWNhdGUgdGhlIGV4dGVuc2lvbiBzcGVjaWZpYyBtZXRhZGF0YVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdSb290Ll9pbnRlcm5hbE1ldGFkYXRhLmdsdGZbTkFNRV0gPSB7IGxhc3RTZWxlY3RlZDogbnVsbCwgb3JpZ2luYWw6IFtdLCB2YXJpYW50czoge30gfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBvcmlnaW5hbCBvZiBtZXRhZGF0YS5vcmlnaW5hbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Um9vdC5faW50ZXJuYWxNZXRhZGF0YS5nbHRmW05BTUVdLm9yaWdpbmFsLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc2g6IG9yaWdpbmFsLm1lc2gsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0ZXJpYWw6IG9yaWdpbmFsLm1hdGVyaWFsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gbWV0YWRhdGEudmFyaWFudHMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobWV0YWRhdGEudmFyaWFudHMsIGtleSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdSb290Ll9pbnRlcm5hbE1ldGFkYXRhLmdsdGZbTkFNRV0udmFyaWFudHNba2V5XSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdmFyaWFudEVudHJ5IG9mIG1ldGFkYXRhLnZhcmlhbnRzW2tleV0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Um9vdC5faW50ZXJuYWxNZXRhZGF0YS5nbHRmW05BTUVdLnZhcmlhbnRzW2tleV0ucHVzaCh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNoOiB2YXJpYW50RW50cnkubWVzaCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGVyaWFsOiB2YXJpYW50RW50cnkubWF0ZXJpYWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGEgPSBuZXdSb290Ll9pbnRlcm5hbE1ldGFkYXRhLmdsdGZbTkFNRV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZWxvY2F0ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdGFyZ2V0IG9mIG1ldGFkYXRhIS5vcmlnaW5hbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0Lm1lc2ggPT09IGJhYnlsb25NZXNoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQubWVzaCA9IG5ld01lc2g7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCB0YXJnZXQgb2YgbWV0YWRhdGEhLnZhcmlhbnRzW3ZhcmlhbnQubmFtZV0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldC5tZXNoID09PSBiYWJ5bG9uTWVzaCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Lm1lc2ggPSBuZXdNZXNoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoW2JhYnlsb25NZXNoXSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJhYnlsb25NZXNoO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX21hdGVyaWFsc192YXJpYW50cyhsb2FkZXIpKTtcclxuIiwiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXHJcbmltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBQQlJNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9QQlIvcGJyTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5pbXBvcnQgdHlwZSB7IEJhc2VUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL2Jhc2VUZXh0dXJlXCI7XHJcbmltcG9ydCB0eXBlIHsgSU1hdGVyaWFsLCBJVGV4dHVyZUluZm8gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IEdMVEZMb2FkZXIgfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IElLSFJNYXRlcmlhbHNWb2x1bWUgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJLSFJfbWF0ZXJpYWxzX3ZvbHVtZVwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfbWF0ZXJpYWxzX3ZvbHVtZSBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiS0hSX21hdGVyaWFsc192b2x1bWVcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogW1NwZWNpZmljYXRpb25dKGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi9ibG9iL21haW4vZXh0ZW5zaW9ucy8yLjAvS2hyb25vcy9LSFJfbWF0ZXJpYWxzX3ZvbHVtZS9SRUFETUUubWQpXHJcbiAqIEBzaW5jZSA1LjAuMFxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgS0hSX21hdGVyaWFsc192b2x1bWUgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDE3MztcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICAgICAgaWYgKHRoaXMuZW5hYmxlZCkge1xyXG4gICAgICAgICAgICAvLyBXZSBuZWVkIHRvIGRpc2FibGUgaW5zdGFuY2UgdXNhZ2UgYmVjYXVzZSB0aGUgYXR0ZW51YXRpb24gZmFjdG9yIGRlcGVuZHMgb24gdGhlIG5vZGUgc2NhbGUgb2YgZWFjaCBpbmRpdmlkdWFsIG1lc2hcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLl9kaXNhYmxlSW5zdGFuY2VkTWVzaCsrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICBpZiAodGhpcy5lbmFibGVkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5fZGlzYWJsZUluc3RhbmNlZE1lc2gtLTtcclxuICAgICAgICB9XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUk1hdGVyaWFsc1ZvbHVtZT4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZGVyLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZFZvbHVtZVByb3BlcnRpZXNBc3luYyhleHRlbnNpb25Db250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsLCBleHRlbnNpb24pKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkVm9sdW1lUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCwgZXh0ZW5zaW9uOiBJS0hSTWF0ZXJpYWxzVm9sdW1lKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogTWF0ZXJpYWwgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJZiB0cmFuc3BhcmVuY3kgaXNuJ3QgZW5hYmxlZCBhbHJlYWR5LCB0aGlzIGV4dGVuc2lvbiBzaG91bGRuJ3QgZG8gYW55dGhpbmcuXHJcbiAgICAgICAgLy8gaS5lLiBpdCByZXF1aXJlcyBlaXRoZXIgdGhlIEtIUl9tYXRlcmlhbHNfdHJhbnNtaXNzaW9uIG9yIEtIUl9tYXRlcmlhbHNfZGlmZnVzZV90cmFuc21pc3Npb24gZXh0ZW5zaW9ucy5cclxuICAgICAgICBpZiAoKCFiYWJ5bG9uTWF0ZXJpYWwuc3ViU3VyZmFjZS5pc1JlZnJhY3Rpb25FbmFibGVkICYmICFiYWJ5bG9uTWF0ZXJpYWwuc3ViU3VyZmFjZS5pc1RyYW5zbHVjZW5jeUVuYWJsZWQpIHx8ICFleHRlbnNpb24udGhpY2tuZXNzRmFjdG9yKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIElPUiBpbiB0aGlzIGV4dGVuc2lvbiBvbmx5IGFmZmVjdHMgaW50ZXJpb3IuXHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2Uudm9sdW1lSW5kZXhPZlJlZnJhY3Rpb24gPSBiYWJ5bG9uTWF0ZXJpYWwuaW5kZXhPZlJlZnJhY3Rpb247XHJcbiAgICAgICAgY29uc3QgYXR0ZW51YXRpb25EaXN0YW5jZSA9IGV4dGVuc2lvbi5hdHRlbnVhdGlvbkRpc3RhbmNlICE9PSB1bmRlZmluZWQgPyBleHRlbnNpb24uYXR0ZW51YXRpb25EaXN0YW5jZSA6IE51bWJlci5NQVhfVkFMVUU7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2UudGludENvbG9yQXREaXN0YW5jZSA9IGF0dGVudWF0aW9uRGlzdGFuY2U7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvbi5hdHRlbnVhdGlvbkNvbG9yICE9PSB1bmRlZmluZWQgJiYgZXh0ZW5zaW9uLmF0dGVudWF0aW9uQ29sb3IubGVuZ3RoID09IDMpIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2UudGludENvbG9yLmNvcHlGcm9tRmxvYXRzKGV4dGVuc2lvbi5hdHRlbnVhdGlvbkNvbG9yWzBdLCBleHRlbnNpb24uYXR0ZW51YXRpb25Db2xvclsxXSwgZXh0ZW5zaW9uLmF0dGVudWF0aW9uQ29sb3JbMl0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2UubWluaW11bVRoaWNrbmVzcyA9IDAuMDtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuc3ViU3VyZmFjZS5tYXhpbXVtVGhpY2tuZXNzID0gZXh0ZW5zaW9uLnRoaWNrbmVzc0ZhY3RvcjtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuc3ViU3VyZmFjZS51c2VUaGlja25lc3NBc0RlcHRoID0gdHJ1ZTtcclxuICAgICAgICBpZiAoZXh0ZW5zaW9uLnRoaWNrbmVzc1RleHR1cmUpIHtcclxuICAgICAgICAgICAgKGV4dGVuc2lvbi50aGlja25lc3NUZXh0dXJlIGFzIElUZXh0dXJlSW5mbykubm9uQ29sb3JEYXRhID0gdHJ1ZTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRlci5sb2FkVGV4dHVyZUluZm9Bc3luYyhgJHtjb250ZXh0fS90aGlja25lc3NUZXh0dXJlYCwgZXh0ZW5zaW9uLnRoaWNrbmVzc1RleHR1cmUpLnRoZW4oKHRleHR1cmU6IEJhc2VUZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0ZXh0dXJlLm5hbWUgPSBgJHtiYWJ5bG9uTWF0ZXJpYWwubmFtZX0gKFRoaWNrbmVzcylgO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnN1YlN1cmZhY2UudGhpY2tuZXNzVGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuc3ViU3VyZmFjZS51c2VHbHRmU3R5bGVUZXh0dXJlcyA9IHRydWU7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl9tYXRlcmlhbHNfdm9sdW1lKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHR5cGUgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl9tZXNoX3F1YW50aXphdGlvblwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfbWVzaF9xdWFudGl6YXRpb24gZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl9tZXNoX3F1YW50aXphdGlvblwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl9tZXNoX3F1YW50aXphdGlvbi9SRUFETUUubWQpXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfbWVzaF9xdWFudGl6YXRpb24gaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHt9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl9tZXNoX3F1YW50aXphdGlvbihsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBBYnN0cmFjdE1lc2ggfSBmcm9tIFwiY29yZS9NZXNoZXMvYWJzdHJhY3RNZXNoXCI7XG5pbXBvcnQgdHlwZSB7IEdMVEZMb2FkZXIgfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xuXG5jb25zdCBOQU1FID0gXCJLSFJfbm9kZV92aXNpYmlsaXR5XCI7XG5cbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl9ub2RlX3Zpc2liaWxpdHkgZXh0ZW5zaW9uLlxuICAgICAgICAgKi9cbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXG4gICAgICAgIFtcIktIUl9ub2RlX3Zpc2liaWxpdHlcIl06IHt9O1xuICAgIH1cbn1cblxuLyoqXG4gKiBMb2FkZXIgZXh0ZW5zaW9uIGZvciBLSFJfbm9kZV92aXNpYmlsaXR5XG4gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbmV4cG9ydCBjbGFzcyBLSFJfbm9kZV92aXNpYmlsaXR5IGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cbiAgICAgKi9cbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcblxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcblxuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IGxvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIG9uUmVhZHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuX2xvYWRlci5nbHRmLm5vZGVzPy5mb3JFYWNoKChub2RlKSA9PiB7XG4gICAgICAgICAgICBub2RlLl9wcmltaXRpdmVCYWJ5bG9uTWVzaGVzPy5mb3JFYWNoKChtZXNoKSA9PiB7XG4gICAgICAgICAgICAgICAgbWVzaC5pbmhlcml0VmlzaWJpbGl0eSA9IHRydWU7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIFdoZW4gdGhlIEpTT04gUG9pbnRlciBpcyB1c2VkIHdlIG5lZWQgdG8gY2hhbmdlIGJvdGggdGhlIHRyYW5zZm9ybSBub2RlIGFuZCB0aGUgcHJpbWl0aXZlIG1lc2hlcyB0byB0aGUgbmV3IHZhbHVlLlxuICAgICAgICAgICAgaWYgKG5vZGUuZXh0ZW5zaW9ucz8uS0hSX25vZGVfdmlzaWJpbGl0eSkge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmV4dGVuc2lvbnM/LktIUl9ub2RlX3Zpc2liaWxpdHkudmlzaWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAobm9kZS5fYmFieWxvblRyYW5zZm9ybU5vZGUgYXMgQWJzdHJhY3RNZXNoKS5pc1Zpc2libGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBub2RlLl9wcmltaXRpdmVCYWJ5bG9uTWVzaGVzPy5mb3JFYWNoKChtZXNoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNoLmlzVmlzaWJsZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xuICAgIH1cbn1cblxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl9ub2RlX3Zpc2liaWxpdHkobG9hZGVyKSk7XG4iLCJpbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciwgQXJyYXlJdGVtIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJVGV4dHVyZSB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IEJhc2VUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL2Jhc2VUZXh0dXJlXCI7XHJcbmltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElLSFJUZXh0dXJlQmFzaXNVIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX3RleHR1cmVfYmFzaXN1XCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl90ZXh0dXJlX2Jhc2lzdSBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiS0hSX3RleHR1cmVfYmFzaXN1XCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0tocm9ub3MvS0hSX3RleHR1cmVfYmFzaXN1L1JFQURNRS5tZClcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIEtIUl90ZXh0dXJlX2Jhc2lzdSBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKiBUaGUgbmFtZSBvZiB0aGlzIGV4dGVuc2lvbi4gKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKiogRGVmaW5lcyB3aGV0aGVyIHRoaXMgZXh0ZW5zaW9uIGlzIGVuYWJsZWQuICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IGxvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvYWRUZXh0dXJlQXN5bmMoY29udGV4dDogc3RyaW5nLCB0ZXh0dXJlOiBJVGV4dHVyZSwgYXNzaWduOiAoYmFieWxvblRleHR1cmU6IEJhc2VUZXh0dXJlKSA9PiB2b2lkKTogTnVsbGFibGU8UHJvbWlzZTxCYXNlVGV4dHVyZT4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUlRleHR1cmVCYXNpc1UsIEJhc2VUZXh0dXJlPihjb250ZXh0LCB0ZXh0dXJlLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3Qgc2FtcGxlciA9IHRleHR1cmUuc2FtcGxlciA9PSB1bmRlZmluZWQgPyBHTFRGTG9hZGVyLkRlZmF1bHRTYW1wbGVyIDogQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9zYW1wbGVyYCwgdGhpcy5fbG9hZGVyLmdsdGYuc2FtcGxlcnMsIHRleHR1cmUuc2FtcGxlcik7XHJcbiAgICAgICAgICAgIGNvbnN0IGltYWdlID0gQXJyYXlJdGVtLkdldChgJHtleHRlbnNpb25Db250ZXh0fS9zb3VyY2VgLCB0aGlzLl9sb2FkZXIuZ2x0Zi5pbWFnZXMsIGV4dGVuc2lvbi5zb3VyY2UpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGVyLl9jcmVhdGVUZXh0dXJlQXN5bmMoXHJcbiAgICAgICAgICAgICAgICBjb250ZXh0LFxyXG4gICAgICAgICAgICAgICAgc2FtcGxlcixcclxuICAgICAgICAgICAgICAgIGltYWdlLFxyXG4gICAgICAgICAgICAgICAgKGJhYnlsb25UZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXNzaWduKGJhYnlsb25UZXh0dXJlKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB0ZXh0dXJlLl90ZXh0dXJlSW5mby5ub25Db2xvckRhdGEgPyB7IHVzZVJHQkFJZkFTVENCQzdOb3RBdmFpbGFibGVXaGVuVUFTVEM6IHRydWUgfSA6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgICAgICF0ZXh0dXJlLl90ZXh0dXJlSW5mby5ub25Db2xvckRhdGFcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgS0hSX3RleHR1cmVfYmFzaXN1KGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBCYXNlVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy9iYXNlVGV4dHVyZVwiO1xyXG5pbXBvcnQgeyBUZXh0dXJlIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL3RleHR1cmVcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSVRleHR1cmVJbmZvIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJS0hSVGV4dHVyZVRyYW5zZm9ybSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIktIUl90ZXh0dXJlX3RyYW5zZm9ybVwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBLSFJfdGV4dHVyZV90cmFuc2Zvcm0gZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIktIUl90ZXh0dXJlX3RyYW5zZm9ybVwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9LaHJvbm9zL0tIUl90ZXh0dXJlX3RyYW5zZm9ybS9SRUFETUUubWQpXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfdGV4dHVyZV90cmFuc2Zvcm0gaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRUZXh0dXJlSW5mb0FzeW5jKGNvbnRleHQ6IHN0cmluZywgdGV4dHVyZUluZm86IElUZXh0dXJlSW5mbywgYXNzaWduOiAoYmFieWxvblRleHR1cmU6IEJhc2VUZXh0dXJlKSA9PiB2b2lkKTogTnVsbGFibGU8UHJvbWlzZTxCYXNlVGV4dHVyZT4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUtIUlRleHR1cmVUcmFuc2Zvcm0sIEJhc2VUZXh0dXJlPihjb250ZXh0LCB0ZXh0dXJlSW5mbywgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIubG9hZFRleHR1cmVJbmZvQXN5bmMoY29udGV4dCwgdGV4dHVyZUluZm8sIChiYWJ5bG9uVGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKCEoYmFieWxvblRleHR1cmUgaW5zdGFuY2VvZiBUZXh0dXJlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtleHRlbnNpb25Db250ZXh0fTogVGV4dHVyZSB0eXBlIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLm9mZnNldCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25UZXh0dXJlLnVPZmZzZXQgPSBleHRlbnNpb24ub2Zmc2V0WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25UZXh0dXJlLnZPZmZzZXQgPSBleHRlbnNpb24ub2Zmc2V0WzFdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIEFsd2F5cyByb3RhdGUgYXJvdW5kIHRoZSBvcmlnaW4uXHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uVGV4dHVyZS51Um90YXRpb25DZW50ZXIgPSAwO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvblRleHR1cmUudlJvdGF0aW9uQ2VudGVyID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLnJvdGF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvblRleHR1cmUud0FuZyA9IC1leHRlbnNpb24ucm90YXRpb247XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbi5zY2FsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25UZXh0dXJlLnVTY2FsZSA9IGV4dGVuc2lvbi5zY2FsZVswXTtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uVGV4dHVyZS52U2NhbGUgPSBleHRlbnNpb24uc2NhbGVbMV07XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbi50ZXhDb29yZCAhPSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uVGV4dHVyZS5jb29yZGluYXRlc0luZGV4ID0gZXh0ZW5zaW9uLnRleENvb3JkO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGFzc2lnbihiYWJ5bG9uVGV4dHVyZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBLSFJfdGV4dHVyZV90cmFuc2Zvcm0obG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgdHlwZSB7IEdMVEZMb2FkZXIgfSBmcm9tIFwiLi4vZ2xURkxvYWRlclwiO1xyXG5pbXBvcnQgdHlwZSB7IElLSFJYbXBKc29uTGRfR2x0ZiwgSUtIUlhtcEpzb25MZF9Ob2RlIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuY29uc3QgTkFNRSA9IFwiS0hSX3htcF9qc29uX2xkXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIEtIUl94bXBfanNvbl9sZCBleHRlbnNpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gTk9URTogRG9uJ3QgdXNlIE5BTUUgaGVyZSBhcyBpdCB3aWxsIGJyZWFrIHRoZSBVTUQgdHlwZSBkZWNsYXJhdGlvbnMuXHJcbiAgICAgICAgW1wiS0hSX3htcF9qc29uX2xkXCJdOiB7fTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFtTcGVjaWZpY2F0aW9uXShodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvYmxvYi9tYWluL2V4dGVuc2lvbnMvMi4wL0tocm9ub3MvS0hSX3htcF9qc29uX2xkL1JFQURNRS5tZClcclxuICogQHNpbmNlIDUuMC4wXHJcbiAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbmV4cG9ydCBjbGFzcyBLSFJfeG1wX2pzb25fbGQgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDEwMDtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9IHRoaXMuX2xvYWRlci5pc0V4dGVuc2lvblVzZWQoTkFNRSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGRpc3Bvc2UoKSB7XHJcbiAgICAgICAgKHRoaXMuX2xvYWRlciBhcyBhbnkpID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGxlZCBhZnRlciB0aGUgbG9hZGVyIHN0YXRlIGNoYW5nZXMgdG8gTE9BRElORy5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uTG9hZGluZygpOiB2b2lkIHtcclxuICAgICAgICBpZiAodGhpcy5fbG9hZGVyLnJvb3RCYWJ5bG9uTWVzaCA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB4bXBfZ2x0ZiA9IHRoaXMuX2xvYWRlci5nbHRmLmV4dGVuc2lvbnM/LktIUl94bXBfanNvbl9sZCBhcyBJS0hSWG1wSnNvbkxkX0dsdGY7XHJcbiAgICAgICAgY29uc3QgeG1wX25vZGUgPSB0aGlzLl9sb2FkZXIuZ2x0Zi5hc3NldD8uZXh0ZW5zaW9ucz8uS0hSX3htcF9qc29uX2xkIGFzIElLSFJYbXBKc29uTGRfTm9kZTtcclxuICAgICAgICBpZiAoeG1wX2dsdGYgJiYgeG1wX25vZGUpIHtcclxuICAgICAgICAgICAgY29uc3QgcGFja2V0ID0gK3htcF9ub2RlLnBhY2tldDtcclxuICAgICAgICAgICAgaWYgKHhtcF9nbHRmLnBhY2tldHMgJiYgcGFja2V0IDwgeG1wX2dsdGYucGFja2V0cy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5yb290QmFieWxvbk1lc2gubWV0YWRhdGEgPSB0aGlzLl9sb2FkZXIucm9vdEJhYnlsb25NZXNoLm1ldGFkYXRhIHx8IHt9O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLnJvb3RCYWJ5bG9uTWVzaC5tZXRhZGF0YS54bXAgPSB4bXBfZ2x0Zi5wYWNrZXRzW3BhY2tldF07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IEtIUl94bXBfanNvbl9sZChsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB7IFZlY3RvcjMgfSBmcm9tIFwiY29yZS9NYXRocy9tYXRoLnZlY3RvclwiO1xyXG5pbXBvcnQgeyBUb29scyB9IGZyb20gXCJjb3JlL01pc2MvdG9vbHNcIjtcclxuaW1wb3J0IHR5cGUgeyBBbmltYXRpb25Hcm91cCB9IGZyb20gXCJjb3JlL0FuaW1hdGlvbnMvYW5pbWF0aW9uR3JvdXBcIjtcclxuaW1wb3J0IHsgQW5pbWF0aW9uRXZlbnQgfSBmcm9tIFwiY29yZS9BbmltYXRpb25zL2FuaW1hdGlvbkV2ZW50XCI7XHJcbmltcG9ydCB0eXBlIHsgVHJhbnNmb3JtTm9kZSB9IGZyb20gXCJjb3JlL01lc2hlcy90cmFuc2Zvcm1Ob2RlXCI7XHJcbmltcG9ydCB7IFNvdW5kIH0gZnJvbSBcImNvcmUvQXVkaW8vc291bmRcIjtcclxuaW1wb3J0IHsgV2VpZ2h0ZWRTb3VuZCB9IGZyb20gXCJjb3JlL0F1ZGlvL3dlaWdodGVkc291bmRcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSUFycmF5SXRlbSwgSVNjZW5lLCBJTm9kZSwgSUFuaW1hdGlvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciwgQXJyYXlJdGVtIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHR5cGUgeyBJTVNGVEF1ZGlvRW1pdHRlcl9DbGlwLCBJTVNGVEF1ZGlvRW1pdHRlcl9FbWl0dGVyLCBJTVNGVEF1ZGlvRW1pdHRlcl9FbWl0dGVyc1JlZmVyZW5jZSwgSU1TRlRBdWRpb0VtaXR0ZXJfQW5pbWF0aW9uRXZlbnQgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IElNU0ZUQXVkaW9FbWl0dGVyX0FuaW1hdGlvbkV2ZW50QWN0aW9uIH0gZnJvbSBcImJhYnlsb25qcy1nbHRmMmludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyByZWdpc3RlckdMVEZFeHRlbnNpb24sIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5cclxuaW1wb3J0IFwiY29yZS9BdWRpby9hdWRpb1NjZW5lQ29tcG9uZW50XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJNU0ZUX2F1ZGlvX2VtaXR0ZXJcIjtcclxuXHJcbmRlY2xhcmUgbW9kdWxlIFwiLi4vLi4vZ2xURkZpbGVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVmaW5lcyBvcHRpb25zIGZvciB0aGUgTVNGVF9hdWRpb19lbWl0dGVyIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJNU0ZUX2F1ZGlvX2VtaXR0ZXJcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG5pbnRlcmZhY2UgSUxvYWRlckNsaXAgZXh0ZW5kcyBJTVNGVEF1ZGlvRW1pdHRlcl9DbGlwLCBJQXJyYXlJdGVtIHtcclxuICAgIF9vYmplY3RVUkw/OiBQcm9taXNlPHN0cmluZz47XHJcbn1cclxuXHJcbmludGVyZmFjZSBJTG9hZGVyRW1pdHRlciBleHRlbmRzIElNU0ZUQXVkaW9FbWl0dGVyX0VtaXR0ZXIsIElBcnJheUl0ZW0ge1xyXG4gICAgX2JhYnlsb25EYXRhPzoge1xyXG4gICAgICAgIHNvdW5kPzogV2VpZ2h0ZWRTb3VuZDtcclxuICAgICAgICBsb2FkZWQ6IFByb21pc2U8dm9pZD47XHJcbiAgICB9O1xyXG4gICAgX2JhYnlsb25Tb3VuZHM6IFNvdW5kW107XHJcbn1cclxuXHJcbmludGVyZmFjZSBJTVNGVEF1ZGlvRW1pdHRlciB7XHJcbiAgICBjbGlwczogSUxvYWRlckNsaXBbXTtcclxuICAgIGVtaXR0ZXJzOiBJTG9hZGVyRW1pdHRlcltdO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgSUxvYWRlckFuaW1hdGlvbkV2ZW50IGV4dGVuZHMgSU1TRlRBdWRpb0VtaXR0ZXJfQW5pbWF0aW9uRXZlbnQsIElBcnJheUl0ZW0ge31cclxuXHJcbmludGVyZmFjZSBJTG9hZGVyQW5pbWF0aW9uRXZlbnRzIHtcclxuICAgIGV2ZW50czogSUxvYWRlckFuaW1hdGlvbkV2ZW50W107XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL25hamFkb2pvL2dsVEYvYmxvYi9NU0ZUX2F1ZGlvX2VtaXR0ZXIvZXh0ZW5zaW9ucy8yLjAvVmVuZG9yL01TRlRfYXVkaW9fZW1pdHRlci9SRUFETUUubWQpXHJcbiAqICEhISBFeHBlcmltZW50YWwgRXh0ZW5zaW9uIFN1YmplY3QgdG8gQ2hhbmdlcyAhISFcclxuICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIE1TRlRfYXVkaW9fZW1pdHRlciBpbXBsZW1lbnRzIElHTFRGTG9hZGVyRXh0ZW5zaW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hbWUgb2YgdGhpcyBleHRlbnNpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gTkFNRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgd2hldGhlciB0aGlzIGV4dGVuc2lvbiBpcyBlbmFibGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IEdMVEZMb2FkZXI7XHJcbiAgICBwcml2YXRlIF9jbGlwczogQXJyYXk8SUxvYWRlckNsaXA+O1xyXG4gICAgcHJpdmF0ZSBfZW1pdHRlcnM6IEFycmF5PElMb2FkZXJFbWl0dGVyPjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgICAgICh0aGlzLl9jbGlwcyBhcyBhbnkpID0gbnVsbDtcclxuICAgICAgICAodGhpcy5fZW1pdHRlcnMgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIG9uTG9hZGluZygpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25zID0gdGhpcy5fbG9hZGVyLmdsdGYuZXh0ZW5zaW9ucztcclxuICAgICAgICBpZiAoZXh0ZW5zaW9ucyAmJiBleHRlbnNpb25zW3RoaXMubmFtZV0pIHtcclxuICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uc1t0aGlzLm5hbWVdIGFzIElNU0ZUQXVkaW9FbWl0dGVyO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fY2xpcHMgPSBleHRlbnNpb24uY2xpcHM7XHJcbiAgICAgICAgICAgIHRoaXMuX2VtaXR0ZXJzID0gZXh0ZW5zaW9uLmVtaXR0ZXJzO1xyXG5cclxuICAgICAgICAgICAgQXJyYXlJdGVtLkFzc2lnbih0aGlzLl9jbGlwcyk7XHJcbiAgICAgICAgICAgIEFycmF5SXRlbS5Bc3NpZ24odGhpcy5fZW1pdHRlcnMpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZFNjZW5lQXN5bmMoY29udGV4dDogc3RyaW5nLCBzY2VuZTogSVNjZW5lKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRlbnNpb25Bc3luYzxJTVNGVEF1ZGlvRW1pdHRlcl9FbWl0dGVyc1JlZmVyZW5jZT4oY29udGV4dCwgc2NlbmUsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcblxyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRlci5sb2FkU2NlbmVBc3luYyhjb250ZXh0LCBzY2VuZSkpO1xyXG5cclxuICAgICAgICAgICAgZm9yIChjb25zdCBlbWl0dGVySW5kZXggb2YgZXh0ZW5zaW9uLmVtaXR0ZXJzKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBlbWl0dGVyID0gQXJyYXlJdGVtLkdldChgJHtleHRlbnNpb25Db250ZXh0fS9lbWl0dGVyc2AsIHRoaXMuX2VtaXR0ZXJzLCBlbWl0dGVySW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgICAgICAgIGVtaXR0ZXIucmVmRGlzdGFuY2UgIT0gdW5kZWZpbmVkIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgZW1pdHRlci5tYXhEaXN0YW5jZSAhPSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgICAgICAgICAgICBlbWl0dGVyLnJvbGxvZmZGYWN0b3IgIT0gdW5kZWZpbmVkIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgZW1pdHRlci5kaXN0YW5jZU1vZGVsICE9IHVuZGVmaW5lZCB8fFxyXG4gICAgICAgICAgICAgICAgICAgIGVtaXR0ZXIuaW5uZXJBbmdsZSAhPSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgICAgICAgICAgICBlbWl0dGVyLm91dGVyQW5nbGUgIT0gdW5kZWZpbmVkXHJcbiAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXh0ZW5zaW9uQ29udGV4dH06IERpcmVjdGlvbiBvciBEaXN0YW5jZSBwcm9wZXJ0aWVzIGFyZSBub3QgYWxsb3dlZCBvbiBlbWl0dGVycyBhdHRhY2hlZCB0byBhIHNjZW5lYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkRW1pdHRlckFzeW5jKGAke2V4dGVuc2lvbkNvbnRleHR9L2VtaXR0ZXJzLyR7ZW1pdHRlci5pbmRleH1gLCBlbWl0dGVyKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWROb2RlQXN5bmMoY29udGV4dDogc3RyaW5nLCBub2RlOiBJTm9kZSwgYXNzaWduOiAoYmFieWxvblRyYW5zZm9ybU5vZGU6IFRyYW5zZm9ybU5vZGUpID0+IHZvaWQpOiBOdWxsYWJsZTxQcm9taXNlPFRyYW5zZm9ybU5vZGU+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dGVuc2lvbkFzeW5jPElNU0ZUQXVkaW9FbWl0dGVyX0VtaXR0ZXJzUmVmZXJlbmNlLCBUcmFuc2Zvcm1Ob2RlPihjb250ZXh0LCBub2RlLCB0aGlzLm5hbWUsIChleHRlbnNpb25Db250ZXh0LCBleHRlbnNpb24pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTxhbnk+PigpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRlclxyXG4gICAgICAgICAgICAgICAgLmxvYWROb2RlQXN5bmMoZXh0ZW5zaW9uQ29udGV4dCwgbm9kZSwgKGJhYnlsb25NZXNoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBlbWl0dGVySW5kZXggb2YgZXh0ZW5zaW9uLmVtaXR0ZXJzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVtaXR0ZXIgPSBBcnJheUl0ZW0uR2V0KGAke2V4dGVuc2lvbkNvbnRleHR9L2VtaXR0ZXJzYCwgdGhpcy5fZW1pdHRlcnMsIGVtaXR0ZXJJbmRleCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkRW1pdHRlckFzeW5jKGAke2V4dGVuc2lvbkNvbnRleHR9L2VtaXR0ZXJzLyR7ZW1pdHRlci5pbmRleH1gLCBlbWl0dGVyKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNvdW5kIG9mIGVtaXR0ZXIuX2JhYnlsb25Tb3VuZHMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291bmQuYXR0YWNoVG9NZXNoKGJhYnlsb25NZXNoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVtaXR0ZXIuaW5uZXJBbmdsZSAhPSB1bmRlZmluZWQgfHwgZW1pdHRlci5vdXRlckFuZ2xlICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291bmQuc2V0TG9jYWxEaXJlY3Rpb25Ub01lc2goVmVjdG9yMy5Gb3J3YXJkKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291bmQuc2V0RGlyZWN0aW9uYWxDb25lKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIgKiBUb29scy5Ub0RlZ3JlZXMoZW1pdHRlci5pbm5lckFuZ2xlID09IHVuZGVmaW5lZCA/IE1hdGguUEkgOiBlbWl0dGVyLmlubmVyQW5nbGUpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIgKiBUb29scy5Ub0RlZ3JlZXMoZW1pdHRlci5vdXRlckFuZ2xlID09IHVuZGVmaW5lZCA/IE1hdGguUEkgOiBlbWl0dGVyLm91dGVyQW5nbGUpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYXNzaWduKGJhYnlsb25NZXNoKTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAudGhlbigoYmFieWxvbk1lc2gpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYmFieWxvbk1lc2g7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZEFuaW1hdGlvbkFzeW5jKGNvbnRleHQ6IHN0cmluZywgYW5pbWF0aW9uOiBJQW5pbWF0aW9uKTogTnVsbGFibGU8UHJvbWlzZTxBbmltYXRpb25Hcm91cD4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SUxvYWRlckFuaW1hdGlvbkV2ZW50cywgQW5pbWF0aW9uR3JvdXA+KGNvbnRleHQsIGFuaW1hdGlvbiwgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIubG9hZEFuaW1hdGlvbkFzeW5jKGNvbnRleHQsIGFuaW1hdGlvbikudGhlbigoYmFieWxvbkFuaW1hdGlvbkdyb3VwKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgQXJyYXlJdGVtLkFzc2lnbihleHRlbnNpb24uZXZlbnRzKTtcclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXh0ZW5zaW9uLmV2ZW50cykge1xyXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZEFuaW1hdGlvbkV2ZW50QXN5bmMoYCR7ZXh0ZW5zaW9uQ29udGV4dH0vZXZlbnRzLyR7ZXZlbnQuaW5kZXh9YCwgY29udGV4dCwgYW5pbWF0aW9uLCBldmVudCwgYmFieWxvbkFuaW1hdGlvbkdyb3VwKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYmFieWxvbkFuaW1hdGlvbkdyb3VwO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRDbGlwQXN5bmMoY29udGV4dDogc3RyaW5nLCBjbGlwOiBJTG9hZGVyQ2xpcCk6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICAgICAgaWYgKGNsaXAuX29iamVjdFVSTCkge1xyXG4gICAgICAgICAgICByZXR1cm4gY2xpcC5fb2JqZWN0VVJMO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IHByb21pc2U6IFByb21pc2U8QXJyYXlCdWZmZXJWaWV3PjtcclxuICAgICAgICBpZiAoY2xpcC51cmkpIHtcclxuICAgICAgICAgICAgcHJvbWlzZSA9IHRoaXMuX2xvYWRlci5sb2FkVXJpQXN5bmMoY29udGV4dCwgY2xpcCwgY2xpcC51cmkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlclZpZXcgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L2J1ZmZlclZpZXdgLCB0aGlzLl9sb2FkZXIuZ2x0Zi5idWZmZXJWaWV3cywgY2xpcC5idWZmZXJWaWV3KTtcclxuICAgICAgICAgICAgcHJvbWlzZSA9IHRoaXMuX2xvYWRlci5sb2FkQnVmZmVyVmlld0FzeW5jKGAvYnVmZmVyVmlld3MvJHtidWZmZXJWaWV3LmluZGV4fWAsIGJ1ZmZlclZpZXcpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY2xpcC5fb2JqZWN0VVJMID0gcHJvbWlzZS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBVUkwuY3JlYXRlT2JqZWN0VVJMKG5ldyBCbG9iKFtkYXRhXSwgeyB0eXBlOiBjbGlwLm1pbWVUeXBlIH0pKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGNsaXAuX29iamVjdFVSTDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkRW1pdHRlckFzeW5jKGNvbnRleHQ6IHN0cmluZywgZW1pdHRlcjogSUxvYWRlckVtaXR0ZXIpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBlbWl0dGVyLl9iYWJ5bG9uU291bmRzID0gZW1pdHRlci5fYmFieWxvblNvdW5kcyB8fCBbXTtcclxuICAgICAgICBpZiAoIWVtaXR0ZXIuX2JhYnlsb25EYXRhKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNsaXBQcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPGFueT4+KCk7XHJcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBlbWl0dGVyLm5hbWUgfHwgYGVtaXR0ZXIke2VtaXR0ZXIuaW5kZXh9YDtcclxuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgYXV0b3BsYXk6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgdm9sdW1lOiBlbWl0dGVyLnZvbHVtZSA9PSB1bmRlZmluZWQgPyAxIDogZW1pdHRlci52b2x1bWUsXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVtaXR0ZXIuY2xpcHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNsaXBDb250ZXh0ID0gYC9leHRlbnNpb25zLyR7dGhpcy5uYW1lfS9jbGlwc2A7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjbGlwID0gQXJyYXlJdGVtLkdldChjbGlwQ29udGV4dCwgdGhpcy5fY2xpcHMsIGVtaXR0ZXIuY2xpcHNbaV0uY2xpcCk7XHJcbiAgICAgICAgICAgICAgICBjbGlwUHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkQ2xpcEFzeW5jKGAke2NsaXBDb250ZXh0fS8ke2VtaXR0ZXIuY2xpcHNbaV0uY2xpcH1gLCBjbGlwKS50aGVuKChvYmplY3RVUkw6IHN0cmluZykgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VuZCA9IChlbWl0dGVyLl9iYWJ5bG9uU291bmRzW2ldID0gbmV3IFNvdW5kKG5hbWUsIG9iamVjdFVSTCwgdGhpcy5fbG9hZGVyLmJhYnlsb25TY2VuZSwgbnVsbCwgb3B0aW9ucykpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzb3VuZC5yZWZEaXN0YW5jZSA9IGVtaXR0ZXIucmVmRGlzdGFuY2UgfHwgMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc291bmQubWF4RGlzdGFuY2UgPSBlbWl0dGVyLm1heERpc3RhbmNlIHx8IDI1NjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc291bmQucm9sbG9mZkZhY3RvciA9IGVtaXR0ZXIucm9sbG9mZkZhY3RvciB8fCAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzb3VuZC5kaXN0YW5jZU1vZGVsID0gZW1pdHRlci5kaXN0YW5jZU1vZGVsIHx8IFwiZXhwb25lbnRpYWxcIjtcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZSA9IFByb21pc2UuYWxsKGNsaXBQcm9taXNlcykudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB3ZWlnaHRzID0gZW1pdHRlci5jbGlwcy5tYXAoKGNsaXApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2xpcC53ZWlnaHQgfHwgMTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgd2VpZ2h0ZWRTb3VuZCA9IG5ldyBXZWlnaHRlZFNvdW5kKGVtaXR0ZXIubG9vcCB8fCBmYWxzZSwgZW1pdHRlci5fYmFieWxvblNvdW5kcywgd2VpZ2h0cyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZW1pdHRlci5pbm5lckFuZ2xlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2VpZ2h0ZWRTb3VuZC5kaXJlY3Rpb25hbENvbmVJbm5lckFuZ2xlID0gMiAqIFRvb2xzLlRvRGVncmVlcyhlbWl0dGVyLmlubmVyQW5nbGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGVtaXR0ZXIub3V0ZXJBbmdsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdlaWdodGVkU291bmQuZGlyZWN0aW9uYWxDb25lT3V0ZXJBbmdsZSA9IDIgKiBUb29scy5Ub0RlZ3JlZXMoZW1pdHRlci5vdXRlckFuZ2xlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChlbWl0dGVyLnZvbHVtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdlaWdodGVkU291bmQudm9sdW1lID0gZW1pdHRlci52b2x1bWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbWl0dGVyLl9iYWJ5bG9uRGF0YSEuc291bmQgPSB3ZWlnaHRlZFNvdW5kO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGVtaXR0ZXIuX2JhYnlsb25EYXRhID0ge1xyXG4gICAgICAgICAgICAgICAgbG9hZGVkOiBwcm9taXNlLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGVtaXR0ZXIuX2JhYnlsb25EYXRhLmxvYWRlZDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9nZXRFdmVudEFjdGlvbihcclxuICAgICAgICBjb250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgc291bmQ6IFdlaWdodGVkU291bmQsXHJcbiAgICAgICAgYWN0aW9uOiBJTVNGVEF1ZGlvRW1pdHRlcl9BbmltYXRpb25FdmVudEFjdGlvbixcclxuICAgICAgICB0aW1lOiBudW1iZXIsXHJcbiAgICAgICAgc3RhcnRPZmZzZXQ/OiBudW1iZXJcclxuICAgICk6IChjdXJyZW50RnJhbWU6IG51bWJlcikgPT4gdm9pZCB7XHJcbiAgICAgICAgc3dpdGNoIChhY3Rpb24pIHtcclxuICAgICAgICAgICAgY2FzZSBJTVNGVEF1ZGlvRW1pdHRlcl9BbmltYXRpb25FdmVudEFjdGlvbi5wbGF5OiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKGN1cnJlbnRGcmFtZTogbnVtYmVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZnJhbWVPZmZzZXQgPSAoc3RhcnRPZmZzZXQgfHwgMCkgKyAoY3VycmVudEZyYW1lIC0gdGltZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgc291bmQucGxheShmcmFtZU9mZnNldCk7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgSU1TRlRBdWRpb0VtaXR0ZXJfQW5pbWF0aW9uRXZlbnRBY3Rpb24uc3RvcDoge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBzb3VuZC5zdG9wKCk7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgSU1TRlRBdWRpb0VtaXR0ZXJfQW5pbWF0aW9uRXZlbnRBY3Rpb24ucGF1c2U6IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgc291bmQucGF1c2UoKTtcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZGVmYXVsdDoge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBVbnN1cHBvcnRlZCBhY3Rpb24gJHthY3Rpb259YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZEFuaW1hdGlvbkV2ZW50QXN5bmMoXHJcbiAgICAgICAgY29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIGFuaW1hdGlvbkNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBhbmltYXRpb246IElBbmltYXRpb24sXHJcbiAgICAgICAgZXZlbnQ6IElMb2FkZXJBbmltYXRpb25FdmVudCxcclxuICAgICAgICBiYWJ5bG9uQW5pbWF0aW9uR3JvdXA6IEFuaW1hdGlvbkdyb3VwXHJcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAoYmFieWxvbkFuaW1hdGlvbkdyb3VwLnRhcmdldGVkQW5pbWF0aW9ucy5sZW5ndGggPT0gMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGJhYnlsb25BbmltYXRpb24gPSBiYWJ5bG9uQW5pbWF0aW9uR3JvdXAudGFyZ2V0ZWRBbmltYXRpb25zWzBdO1xyXG4gICAgICAgIGNvbnN0IGVtaXR0ZXJJbmRleCA9IGV2ZW50LmVtaXR0ZXI7XHJcbiAgICAgICAgY29uc3QgZW1pdHRlciA9IEFycmF5SXRlbS5HZXQoYC9leHRlbnNpb25zLyR7dGhpcy5uYW1lfS9lbWl0dGVyc2AsIHRoaXMuX2VtaXR0ZXJzLCBlbWl0dGVySW5kZXgpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkRW1pdHRlckFzeW5jKGNvbnRleHQsIGVtaXR0ZXIpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBzb3VuZCA9IGVtaXR0ZXIuX2JhYnlsb25EYXRhIS5zb3VuZDtcclxuICAgICAgICAgICAgaWYgKHNvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uQW5pbWF0aW9uRXZlbnQgPSBuZXcgQW5pbWF0aW9uRXZlbnQoZXZlbnQudGltZSwgdGhpcy5fZ2V0RXZlbnRBY3Rpb24oY29udGV4dCwgc291bmQsIGV2ZW50LmFjdGlvbiwgZXZlbnQudGltZSwgZXZlbnQuc3RhcnRPZmZzZXQpKTtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25BbmltYXRpb24uYW5pbWF0aW9uLmFkZEV2ZW50KGJhYnlsb25BbmltYXRpb25FdmVudCk7XHJcbiAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgYWxsIHN0YXJ0ZWQgYXVkaW8gc3RvcHMgd2hlbiB0aGlzIGFuaW1hdGlvbiBpcyB0ZXJtaW5hdGVkLlxyXG4gICAgICAgICAgICAgICAgYmFieWxvbkFuaW1hdGlvbkdyb3VwLm9uQW5pbWF0aW9uR3JvdXBFbmRPYnNlcnZhYmxlLmFkZCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgc291bmQuc3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uQW5pbWF0aW9uR3JvdXAub25BbmltYXRpb25Hcm91cFBhdXNlT2JzZXJ2YWJsZS5hZGQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHNvdW5kLnBhdXNlKCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcblxyXG51bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FKTtcclxucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUsIHRydWUsIChsb2FkZXIpID0+IG5ldyBNU0ZUX2F1ZGlvX2VtaXR0ZXIobG9hZGVyKSk7XHJcbiIsImltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSBcImNvcmUvTWlzYy9vYnNlcnZhYmxlXCI7XHJcbmltcG9ydCB7IERlZmVycmVkIH0gZnJvbSBcImNvcmUvTWlzYy9kZWZlcnJlZFwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgVHJhbnNmb3JtTm9kZSB9IGZyb20gXCJjb3JlL01lc2hlcy90cmFuc2Zvcm1Ob2RlXCI7XHJcbmltcG9ydCB0eXBlIHsgTWVzaCB9IGZyb20gXCJjb3JlL01lc2hlcy9tZXNoXCI7XHJcbmltcG9ydCB0eXBlIHsgQmFzZVRleHR1cmUgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvVGV4dHVyZXMvYmFzZVRleHR1cmVcIjtcclxuaW1wb3J0IHR5cGUgeyBJTm9kZSwgSU1hdGVyaWFsLCBJQnVmZmVyLCBJU2NlbmUgfSBmcm9tIFwiLi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJR0xURkxvYWRlckV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcbmltcG9ydCB7IEdMVEZMb2FkZXIsIEFycmF5SXRlbSB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSVByb3BlcnR5LCBJTVNGVExPRCB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIk1TRlRfbG9kXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIE1TRlRfbG9kIGV4dGVuc2lvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICAvLyBOT1RFOiBEb24ndCB1c2UgTkFNRSBoZXJlIGFzIGl0IHdpbGwgYnJlYWsgdGhlIFVNRCB0eXBlIGRlY2xhcmF0aW9ucy5cclxuICAgICAgICBbXCJNU0ZUX2xvZFwiXTogUGFydGlhbDx7XHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBNYXhpbXVtIG51bWJlciBvZiBMT0RzIHRvIGxvYWQsIHN0YXJ0aW5nIGZyb20gdGhlIGxvd2VzdCBMT0QuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBtYXhMT0RzVG9Mb2FkOiBudW1iZXI7XHJcbiAgICAgICAgfT47XHJcbiAgICB9XHJcbn1cclxuXHJcbmludGVyZmFjZSBJQnVmZmVySW5mbyB7XHJcbiAgICBzdGFydDogbnVtYmVyO1xyXG4gICAgZW5kOiBudW1iZXI7XHJcbiAgICBsb2FkZWQ6IERlZmVycmVkPEFycmF5QnVmZmVyVmlldz47XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBbU3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGL2Jsb2IvbWFpbi9leHRlbnNpb25zLzIuMC9WZW5kb3IvTVNGVF9sb2QvUkVBRE1FLm1kKVxyXG4gKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgTVNGVF9sb2QgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgb3JkZXIgdGhlIGV4dGVuc2lvbnMgYXJlIGFwcGxpZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvcmRlciA9IDEwMDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1heGltdW0gbnVtYmVyIG9mIExPRHMgdG8gbG9hZCwgc3RhcnRpbmcgZnJvbSB0aGUgbG93ZXN0IExPRC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG1heExPRHNUb0xvYWQgPSAxMDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmFpc2VkIHdoZW4gYWxsIG5vZGUgTE9EcyBvZiBvbmUgbGV2ZWwgYXJlIGxvYWRlZC5cclxuICAgICAqIFRoZSBldmVudCBkYXRhIGlzIHRoZSBpbmRleCBvZiB0aGUgbG9hZGVkIExPRCBzdGFydGluZyBmcm9tIHplcm8uXHJcbiAgICAgKiBEaXNwb3NlIHRoZSBsb2FkZXIgdG8gY2FuY2VsIHRoZSBsb2FkaW5nIG9mIHRoZSBuZXh0IGxldmVsIG9mIExPRHMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbk5vZGVMT0RzTG9hZGVkT2JzZXJ2YWJsZSA9IG5ldyBPYnNlcnZhYmxlPG51bWJlcj4oKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmFpc2VkIHdoZW4gYWxsIG1hdGVyaWFsIExPRHMgb2Ygb25lIGxldmVsIGFyZSBsb2FkZWQuXHJcbiAgICAgKiBUaGUgZXZlbnQgZGF0YSBpcyB0aGUgaW5kZXggb2YgdGhlIGxvYWRlZCBMT0Qgc3RhcnRpbmcgZnJvbSB6ZXJvLlxyXG4gICAgICogRGlzcG9zZSB0aGUgbG9hZGVyIHRvIGNhbmNlbCB0aGUgbG9hZGluZyBvZiB0aGUgbmV4dCBsZXZlbCBvZiBMT0RzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25NYXRlcmlhbExPRHNMb2FkZWRPYnNlcnZhYmxlID0gbmV3IE9ic2VydmFibGU8bnVtYmVyPigpO1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICBwcml2YXRlIF9idWZmZXJMT0RzID0gbmV3IEFycmF5PElCdWZmZXJJbmZvPigpO1xyXG5cclxuICAgIHByaXZhdGUgX25vZGVJbmRleExPRDogTnVsbGFibGU8bnVtYmVyPiA9IG51bGw7XHJcbiAgICBwcml2YXRlIF9ub2RlU2lnbmFsTE9EcyA9IG5ldyBBcnJheTxEZWZlcnJlZDx2b2lkPj4oKTtcclxuICAgIHByaXZhdGUgX25vZGVQcm9taXNlTE9EcyA9IG5ldyBBcnJheTxBcnJheTxQcm9taXNlPGFueT4+PigpO1xyXG4gICAgcHJpdmF0ZSBfbm9kZUJ1ZmZlckxPRHMgPSBuZXcgQXJyYXk8SUJ1ZmZlckluZm8+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfbWF0ZXJpYWxJbmRleExPRDogTnVsbGFibGU8bnVtYmVyPiA9IG51bGw7XHJcbiAgICBwcml2YXRlIF9tYXRlcmlhbFNpZ25hbExPRHMgPSBuZXcgQXJyYXk8RGVmZXJyZWQ8dm9pZD4+KCk7XHJcbiAgICBwcml2YXRlIF9tYXRlcmlhbFByb21pc2VMT0RzID0gbmV3IEFycmF5PEFycmF5PFByb21pc2U8YW55Pj4+KCk7XHJcbiAgICBwcml2YXRlIF9tYXRlcmlhbEJ1ZmZlckxPRHMgPSBuZXcgQXJyYXk8SUJ1ZmZlckluZm8+KCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobG9hZGVyOiBHTFRGTG9hZGVyKSB7XHJcbiAgICAgICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyO1xyXG4gICAgICAgIC8vIE9wdGlvbnMgdGFrZXMgcHJlY2VkZW5jZS4gVGhlIG1heExPRHNUb0xvYWQgZXh0ZW5zaW9uIHByb3BlcnR5IGlzIHJldGFpbmVkIGZvciBiYWNrIGNvbXBhdC5cclxuICAgICAgICAvLyBGb3IgbmV3IGV4dGVuc2lvbnMsIHRoZXkgc2hvdWxkIG9ubHkgdXNlIG9wdGlvbnMuXHJcbiAgICAgICAgdGhpcy5tYXhMT0RzVG9Mb2FkID0gdGhpcy5fbG9hZGVyLnBhcmVudC5leHRlbnNpb25PcHRpb25zW05BTUVdPy5tYXhMT0RzVG9Mb2FkID8/IHRoaXMubWF4TE9Ec1RvTG9hZDtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcblxyXG4gICAgICAgIHRoaXMuX25vZGVJbmRleExPRCA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5fbm9kZVNpZ25hbExPRHMubGVuZ3RoID0gMDtcclxuICAgICAgICB0aGlzLl9ub2RlUHJvbWlzZUxPRHMubGVuZ3RoID0gMDtcclxuICAgICAgICB0aGlzLl9ub2RlQnVmZmVyTE9Ecy5sZW5ndGggPSAwO1xyXG5cclxuICAgICAgICB0aGlzLl9tYXRlcmlhbEluZGV4TE9EID0gbnVsbDtcclxuICAgICAgICB0aGlzLl9tYXRlcmlhbFNpZ25hbExPRHMubGVuZ3RoID0gMDtcclxuICAgICAgICB0aGlzLl9tYXRlcmlhbFByb21pc2VMT0RzLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgdGhpcy5fbWF0ZXJpYWxCdWZmZXJMT0RzLmxlbmd0aCA9IDA7XHJcblxyXG4gICAgICAgIHRoaXMub25NYXRlcmlhbExPRHNMb2FkZWRPYnNlcnZhYmxlLmNsZWFyKCk7XHJcbiAgICAgICAgdGhpcy5vbk5vZGVMT0RzTG9hZGVkT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBvblJlYWR5KCk6IHZvaWQge1xyXG4gICAgICAgIGZvciAobGV0IGluZGV4TE9EID0gMDsgaW5kZXhMT0QgPCB0aGlzLl9ub2RlUHJvbWlzZUxPRHMubGVuZ3RoOyBpbmRleExPRCsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSBQcm9taXNlLmFsbCh0aGlzLl9ub2RlUHJvbWlzZUxPRHNbaW5kZXhMT0RdKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChpbmRleExPRCAhPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRlci5lbmRQZXJmb3JtYW5jZUNvdW50ZXIoYE5vZGUgTE9EICR7aW5kZXhMT0R9YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvZyhgTG9hZGVkIG5vZGUgTE9EICR7aW5kZXhMT0R9YCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5vbk5vZGVMT0RzTG9hZGVkT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMoaW5kZXhMT0QpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChpbmRleExPRCAhPT0gdGhpcy5fbm9kZVByb21pc2VMT0RzLmxlbmd0aCAtIDEpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIuc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXIoYE5vZGUgTE9EICR7aW5kZXhMT0QgKyAxfWApO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRCdWZmZXJMT0QodGhpcy5fbm9kZUJ1ZmZlckxPRHMsIGluZGV4TE9EICsgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX25vZGVTaWduYWxMT0RzW2luZGV4TE9EXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9ub2RlU2lnbmFsTE9Ec1tpbmRleExPRF0ucmVzb2x2ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9sb2FkZXIuX2NvbXBsZXRlUHJvbWlzZXMucHVzaChwcm9taXNlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAobGV0IGluZGV4TE9EID0gMDsgaW5kZXhMT0QgPCB0aGlzLl9tYXRlcmlhbFByb21pc2VMT0RzLmxlbmd0aDsgaW5kZXhMT0QrKykge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlID0gUHJvbWlzZS5hbGwodGhpcy5fbWF0ZXJpYWxQcm9taXNlTE9Ec1tpbmRleExPRF0pLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4TE9EICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmVuZFBlcmZvcm1hbmNlQ291bnRlcihgTWF0ZXJpYWwgTE9EICR7aW5kZXhMT0R9YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvZyhgTG9hZGVkIG1hdGVyaWFsIExPRCAke2luZGV4TE9EfWApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMub25NYXRlcmlhbExPRHNMb2FkZWRPYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyhpbmRleExPRCk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4TE9EICE9PSB0aGlzLl9tYXRlcmlhbFByb21pc2VMT0RzLmxlbmd0aCAtIDEpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkZXIuc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXIoYE1hdGVyaWFsIExPRCAke2luZGV4TE9EICsgMX1gKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkQnVmZmVyTE9EKHRoaXMuX21hdGVyaWFsQnVmZmVyTE9EcywgaW5kZXhMT0QgKyAxKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbWF0ZXJpYWxTaWduYWxMT0RzW2luZGV4TE9EXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYXRlcmlhbFNpZ25hbExPRHNbaW5kZXhMT0RdLnJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLl9jb21wbGV0ZVByb21pc2VzLnB1c2gocHJvbWlzZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkU2NlbmVBc3luYyhjb250ZXh0OiBzdHJpbmcsIHNjZW5lOiBJU2NlbmUpOiBOdWxsYWJsZTxQcm9taXNlPHZvaWQ+PiB7XHJcbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRoaXMuX2xvYWRlci5sb2FkU2NlbmVBc3luYyhjb250ZXh0LCBzY2VuZSk7XHJcbiAgICAgICAgdGhpcy5fbG9hZEJ1ZmZlckxPRCh0aGlzLl9idWZmZXJMT0RzLCAwKTtcclxuICAgICAgICByZXR1cm4gcHJvbWlzZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZE5vZGVBc3luYyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IElOb2RlLCBhc3NpZ246IChiYWJ5bG9uVHJhbnNmb3JtTm9kZTogVHJhbnNmb3JtTm9kZSkgPT4gdm9pZCk6IE51bGxhYmxlPFByb21pc2U8VHJhbnNmb3JtTm9kZT4+IHtcclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SU1TRlRMT0QsIFRyYW5zZm9ybU5vZGU+KGNvbnRleHQsIG5vZGUsIHRoaXMubmFtZSwgKGV4dGVuc2lvbkNvbnRleHQsIGV4dGVuc2lvbikgPT4ge1xyXG4gICAgICAgICAgICBsZXQgZmlyc3RQcm9taXNlOiBQcm9taXNlPFRyYW5zZm9ybU5vZGU+O1xyXG5cclxuICAgICAgICAgICAgY29uc3Qgbm9kZUxPRHMgPSB0aGlzLl9nZXRMT0RzKGV4dGVuc2lvbkNvbnRleHQsIG5vZGUsIHRoaXMuX2xvYWRlci5nbHRmLm5vZGVzLCBleHRlbnNpb24uaWRzKTtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvZ09wZW4oYCR7ZXh0ZW5zaW9uQ29udGV4dH1gKTtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGluZGV4TE9EID0gMDsgaW5kZXhMT0QgPCBub2RlTE9Ecy5sZW5ndGg7IGluZGV4TE9EKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5vZGVMT0QgPSBub2RlTE9Ec1tpbmRleExPRF07XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4TE9EICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbm9kZUluZGV4TE9EID0gaW5kZXhMT0Q7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbm9kZVNpZ25hbExPRHNbaW5kZXhMT0RdID0gdGhpcy5fbm9kZVNpZ25hbExPRHNbaW5kZXhMT0RdIHx8IG5ldyBEZWZlcnJlZCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGFzc2lnbldyYXAgPSAoYmFieWxvblRyYW5zZm9ybU5vZGU6IFRyYW5zZm9ybU5vZGUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBhc3NpZ24oYmFieWxvblRyYW5zZm9ybU5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25UcmFuc2Zvcm1Ob2RlLnNldEVuYWJsZWQoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlID0gdGhpcy5fbG9hZGVyLmxvYWROb2RlQXN5bmMoYC9ub2Rlcy8ke25vZGVMT0QuaW5kZXh9YCwgbm9kZUxPRCwgYXNzaWduV3JhcCkudGhlbigoYmFieWxvbk1lc2gpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXhMT0QgIT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogc2hvdWxkIG5vdCByZWx5IG9uIF9iYWJ5bG9uVHJhbnNmb3JtTm9kZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmV2aW91c05vZGVMT0QgPSBub2RlTE9Ec1tpbmRleExPRCAtIDFdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJldmlvdXNOb2RlTE9ELl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGlzcG9zZVRyYW5zZm9ybU5vZGUocHJldmlvdXNOb2RlTE9ELl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgcHJldmlvdXNOb2RlTE9ELl9iYWJ5bG9uVHJhbnNmb3JtTm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1lc2guc2V0RW5hYmxlZCh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYmFieWxvbk1lc2g7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9ub2RlUHJvbWlzZUxPRHNbaW5kZXhMT0RdID0gdGhpcy5fbm9kZVByb21pc2VMT0RzW2luZGV4TE9EXSB8fCBbXTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXhMT0QgPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBmaXJzdFByb21pc2UgPSBwcm9taXNlO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ub2RlSW5kZXhMT0QgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25vZGVQcm9taXNlTE9Ec1tpbmRleExPRF0ucHVzaChwcm9taXNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvZ0Nsb3NlKCk7XHJcbiAgICAgICAgICAgIHJldHVybiBmaXJzdFByb21pc2UhO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbG9hZE1hdGVyaWFsQXN5bmMoXHJcbiAgICAgICAgY29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIG1hdGVyaWFsOiBJTWF0ZXJpYWwsXHJcbiAgICAgICAgYmFieWxvbk1lc2g6IE51bGxhYmxlPE1lc2g+LFxyXG4gICAgICAgIGJhYnlsb25EcmF3TW9kZTogbnVtYmVyLFxyXG4gICAgICAgIGFzc2lnbjogKGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpID0+IHZvaWRcclxuICAgICk6IE51bGxhYmxlPFByb21pc2U8TWF0ZXJpYWw+PiB7XHJcbiAgICAgICAgLy8gRG9uJ3QgbG9hZCBtYXRlcmlhbCBMT0RzIGlmIGFscmVhZHkgbG9hZGluZyBhIG5vZGUgTE9ELlxyXG4gICAgICAgIGlmICh0aGlzLl9ub2RlSW5kZXhMT0QpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gR0xURkxvYWRlci5Mb2FkRXh0ZW5zaW9uQXN5bmM8SU1TRlRMT0QsIE1hdGVyaWFsPihjb250ZXh0LCBtYXRlcmlhbCwgdGhpcy5uYW1lLCAoZXh0ZW5zaW9uQ29udGV4dCwgZXh0ZW5zaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIGxldCBmaXJzdFByb21pc2U6IFByb21pc2U8TWF0ZXJpYWw+O1xyXG5cclxuICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxMT0RzID0gdGhpcy5fZ2V0TE9EcyhleHRlbnNpb25Db250ZXh0LCBtYXRlcmlhbCwgdGhpcy5fbG9hZGVyLmdsdGYubWF0ZXJpYWxzLCBleHRlbnNpb24uaWRzKTtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvZ09wZW4oYCR7ZXh0ZW5zaW9uQ29udGV4dH1gKTtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGluZGV4TE9EID0gMDsgaW5kZXhMT0QgPCBtYXRlcmlhbExPRHMubGVuZ3RoOyBpbmRleExPRCsrKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtYXRlcmlhbExPRCA9IG1hdGVyaWFsTE9Ec1tpbmRleExPRF07XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4TE9EICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWF0ZXJpYWxJbmRleExPRCA9IGluZGV4TE9EO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLl9sb2FkZXJcclxuICAgICAgICAgICAgICAgICAgICAuX2xvYWRNYXRlcmlhbEFzeW5jKGAvbWF0ZXJpYWxzLyR7bWF0ZXJpYWxMT0QuaW5kZXh9YCwgbWF0ZXJpYWxMT0QsIGJhYnlsb25NZXNoLCBiYWJ5bG9uRHJhd01vZGUsIChiYWJ5bG9uTWF0ZXJpYWwpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4TE9EID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NpZ24oYmFieWxvbk1hdGVyaWFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKGJhYnlsb25NYXRlcmlhbCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXhMT0QgIT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2lnbihiYWJ5bG9uTWF0ZXJpYWwpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IHNob3VsZCBub3QgcmVseSBvbiBfZGF0YVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJldmlvdXNEYXRhTE9EID0gbWF0ZXJpYWxMT0RzW2luZGV4TE9EIC0gMV0uX2RhdGEhO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzRGF0YUxPRFtiYWJ5bG9uRHJhd01vZGVdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGlzcG9zZU1hdGVyaWFscyhbcHJldmlvdXNEYXRhTE9EW2JhYnlsb25EcmF3TW9kZV0uYmFieWxvbk1hdGVyaWFsXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHByZXZpb3VzRGF0YUxPRFtiYWJ5bG9uRHJhd01vZGVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYmFieWxvbk1hdGVyaWFsO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX21hdGVyaWFsUHJvbWlzZUxPRHNbaW5kZXhMT0RdID0gdGhpcy5fbWF0ZXJpYWxQcm9taXNlTE9Ec1tpbmRleExPRF0gfHwgW107XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4TE9EID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmlyc3RQcm9taXNlID0gcHJvbWlzZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWF0ZXJpYWxJbmRleExPRCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWF0ZXJpYWxQcm9taXNlTE9Ec1tpbmRleExPRF0ucHVzaChwcm9taXNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvZ0Nsb3NlKCk7XHJcbiAgICAgICAgICAgIHJldHVybiBmaXJzdFByb21pc2UhO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbG9hZFVyaUFzeW5jKGNvbnRleHQ6IHN0cmluZywgcHJvcGVydHk6IElQcm9wZXJ0eSwgdXJpOiBzdHJpbmcpOiBOdWxsYWJsZTxQcm9taXNlPEFycmF5QnVmZmVyVmlldz4+IHtcclxuICAgICAgICAvLyBEZWZlciB0aGUgbG9hZGluZyBvZiB1cmlzIGlmIGxvYWRpbmcgYSBub2RlIG9yIG1hdGVyaWFsIExPRC5cclxuICAgICAgICBpZiAodGhpcy5fbm9kZUluZGV4TE9EICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlci5sb2coYGRlZmVycmVkYCk7XHJcbiAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzSW5kZXhMT0QgPSB0aGlzLl9ub2RlSW5kZXhMT0QgLSAxO1xyXG4gICAgICAgICAgICB0aGlzLl9ub2RlU2lnbmFsTE9Ec1twcmV2aW91c0luZGV4TE9EXSA9IHRoaXMuX25vZGVTaWduYWxMT0RzW3ByZXZpb3VzSW5kZXhMT0RdIHx8IG5ldyBEZWZlcnJlZDx2b2lkPigpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbm9kZVNpZ25hbExPRHNbdGhpcy5fbm9kZUluZGV4TE9EIC0gMV0ucHJvbWlzZS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIubG9hZFVyaUFzeW5jKGNvbnRleHQsIHByb3BlcnR5LCB1cmkpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX21hdGVyaWFsSW5kZXhMT0QgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvZyhgZGVmZXJyZWRgKTtcclxuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNJbmRleExPRCA9IHRoaXMuX21hdGVyaWFsSW5kZXhMT0QgLSAxO1xyXG4gICAgICAgICAgICB0aGlzLl9tYXRlcmlhbFNpZ25hbExPRHNbcHJldmlvdXNJbmRleExPRF0gPSB0aGlzLl9tYXRlcmlhbFNpZ25hbExPRHNbcHJldmlvdXNJbmRleExPRF0gfHwgbmV3IERlZmVycmVkPHZvaWQ+KCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9tYXRlcmlhbFNpZ25hbExPRHNbcHJldmlvdXNJbmRleExPRF0ucHJvbWlzZS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIubG9hZFVyaUFzeW5jKGNvbnRleHQsIHByb3BlcnR5LCB1cmkpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkQnVmZmVyQXN5bmMoY29udGV4dDogc3RyaW5nLCBidWZmZXI6IElCdWZmZXIsIGJ5dGVPZmZzZXQ6IG51bWJlciwgYnl0ZUxlbmd0aDogbnVtYmVyKTogTnVsbGFibGU8UHJvbWlzZTxBcnJheUJ1ZmZlclZpZXc+PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2xvYWRlci5wYXJlbnQudXNlUmFuZ2VSZXF1ZXN0cyAmJiAhYnVmZmVyLnVyaSkge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuX2xvYWRlci5iaW4pIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogVXJpIGlzIG1pc3Npbmcgb3IgdGhlIGJpbmFyeSBnbFRGIGlzIG1pc3NpbmcgaXRzIGJpbmFyeSBjaHVua2ApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBsb2FkQXN5bmMgPSAoYnVmZmVyTE9EczogQXJyYXk8SUJ1ZmZlckluZm8+LCBpbmRleExPRDogbnVtYmVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzdGFydCA9IGJ5dGVPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBlbmQgPSBzdGFydCArIGJ5dGVMZW5ndGggLSAxO1xyXG4gICAgICAgICAgICAgICAgbGV0IGJ1ZmZlckxPRCA9IGJ1ZmZlckxPRHNbaW5kZXhMT0RdO1xyXG4gICAgICAgICAgICAgICAgaWYgKGJ1ZmZlckxPRCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlckxPRC5zdGFydCA9IE1hdGgubWluKGJ1ZmZlckxPRC5zdGFydCwgc3RhcnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlckxPRC5lbmQgPSBNYXRoLm1heChidWZmZXJMT0QuZW5kLCBlbmQpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBidWZmZXJMT0QgPSB7IHN0YXJ0OiBzdGFydCwgZW5kOiBlbmQsIGxvYWRlZDogbmV3IERlZmVycmVkKCkgfTtcclxuICAgICAgICAgICAgICAgICAgICBidWZmZXJMT0RzW2luZGV4TE9EXSA9IGJ1ZmZlckxPRDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYnVmZmVyTE9ELmxvYWRlZC5wcm9taXNlLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoZGF0YS5idWZmZXIsIGRhdGEuYnl0ZU9mZnNldCArIGJ5dGVPZmZzZXQgLSBidWZmZXJMT0Quc3RhcnQsIGJ5dGVMZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9sb2FkZXIubG9nKGBkZWZlcnJlZGApO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuX25vZGVJbmRleExPRCAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGxvYWRBc3luYyh0aGlzLl9ub2RlQnVmZmVyTE9EcywgdGhpcy5fbm9kZUluZGV4TE9EKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9tYXRlcmlhbEluZGV4TE9EICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbG9hZEFzeW5jKHRoaXMuX21hdGVyaWFsQnVmZmVyTE9EcywgdGhpcy5fbWF0ZXJpYWxJbmRleExPRCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbG9hZEFzeW5jKHRoaXMuX2J1ZmZlckxPRHMsIDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkQnVmZmVyTE9EKGJ1ZmZlckxPRHM6IEFycmF5PElCdWZmZXJJbmZvPiwgaW5kZXhMT0Q6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGJ1ZmZlckxPRCA9IGJ1ZmZlckxPRHNbaW5kZXhMT0RdO1xyXG4gICAgICAgIGlmIChidWZmZXJMT0QpIHtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmxvZyhgTG9hZGluZyBidWZmZXIgcmFuZ2UgWyR7YnVmZmVyTE9ELnN0YXJ0fS0ke2J1ZmZlckxPRC5lbmR9XWApO1xyXG4gICAgICAgICAgICB0aGlzLl9sb2FkZXIuYmluIS5yZWFkQXN5bmMoYnVmZmVyTE9ELnN0YXJ0LCBidWZmZXJMT0QuZW5kIC0gYnVmZmVyTE9ELnN0YXJ0ICsgMSkudGhlbihcclxuICAgICAgICAgICAgICAgIChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyTE9ELmxvYWRlZC5yZXNvbHZlKGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlckxPRC5sb2FkZWQucmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcmV0dXJucyBhbiBhcnJheSBvZiBMT0QgcHJvcGVydGllcyBmcm9tIGxvd2VzdCB0byBoaWdoZXN0LlxyXG4gICAgICogQHBhcmFtIGNvbnRleHRcclxuICAgICAqIEBwYXJhbSBwcm9wZXJ0eVxyXG4gICAgICogQHBhcmFtIGFycmF5XHJcbiAgICAgKiBAcGFyYW0gaWRzXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgX2dldExPRHM8VD4oY29udGV4dDogc3RyaW5nLCBwcm9wZXJ0eTogVCwgYXJyYXk6IEFycmF5TGlrZTxUPiB8IHVuZGVmaW5lZCwgaWRzOiBudW1iZXJbXSk6IFRbXSB7XHJcbiAgICAgICAgaWYgKHRoaXMubWF4TE9Ec1RvTG9hZCA8PSAwKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm1heExPRHNUb0xvYWQgbXVzdCBiZSBncmVhdGVyIHRoYW4gemVyb1wiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb3BlcnRpZXM6IFRbXSA9IFtdO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gaWRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgICAgIHByb3BlcnRpZXMucHVzaChBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L2lkcy8ke2lkc1tpXX1gLCBhcnJheSwgaWRzW2ldKSk7XHJcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLmxlbmd0aCA9PT0gdGhpcy5tYXhMT0RzVG9Mb2FkKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvcGVydGllcztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcHJvcGVydGllcy5wdXNoKHByb3BlcnR5KTtcclxuICAgICAgICByZXR1cm4gcHJvcGVydGllcztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9kaXNwb3NlVHJhbnNmb3JtTm9kZShiYWJ5bG9uVHJhbnNmb3JtTm9kZTogVHJhbnNmb3JtTm9kZSk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGJhYnlsb25NYXRlcmlhbHM6IE1hdGVyaWFsW10gPSBbXTtcclxuICAgICAgICBjb25zdCBiYWJ5bG9uTWF0ZXJpYWwgPSAoYmFieWxvblRyYW5zZm9ybU5vZGUgYXMgTWVzaCkubWF0ZXJpYWw7XHJcbiAgICAgICAgaWYgKGJhYnlsb25NYXRlcmlhbCkge1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWxzLnB1c2goYmFieWxvbk1hdGVyaWFsKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm9yIChjb25zdCBiYWJ5bG9uTWVzaCBvZiBiYWJ5bG9uVHJhbnNmb3JtTm9kZS5nZXRDaGlsZE1lc2hlcygpKSB7XHJcbiAgICAgICAgICAgIGlmIChiYWJ5bG9uTWVzaC5tYXRlcmlhbCkge1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFscy5wdXNoKGJhYnlsb25NZXNoLm1hdGVyaWFsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYmFieWxvblRyYW5zZm9ybU5vZGUuZGlzcG9zZSgpO1xyXG5cclxuICAgICAgICBjb25zdCBiYWJ5bG9uTWF0ZXJpYWxzVG9EaXNwb3NlID0gYmFieWxvbk1hdGVyaWFscy5maWx0ZXIoKGJhYnlsb25NYXRlcmlhbCkgPT4gdGhpcy5fbG9hZGVyLmJhYnlsb25TY2VuZS5tZXNoZXMuZXZlcnkoKG1lc2gpID0+IG1lc2gubWF0ZXJpYWwgIT0gYmFieWxvbk1hdGVyaWFsKSk7XHJcbiAgICAgICAgdGhpcy5fZGlzcG9zZU1hdGVyaWFscyhiYWJ5bG9uTWF0ZXJpYWxzVG9EaXNwb3NlKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9kaXNwb3NlTWF0ZXJpYWxzKGJhYnlsb25NYXRlcmlhbHM6IE1hdGVyaWFsW10pOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBiYWJ5bG9uVGV4dHVyZXM6IHsgW3VuaXF1ZUlkOiBudW1iZXJdOiBCYXNlVGV4dHVyZSB9ID0ge307XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgYmFieWxvbk1hdGVyaWFsIG9mIGJhYnlsb25NYXRlcmlhbHMpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBiYWJ5bG9uVGV4dHVyZSBvZiBiYWJ5bG9uTWF0ZXJpYWwuZ2V0QWN0aXZlVGV4dHVyZXMoKSkge1xyXG4gICAgICAgICAgICAgICAgYmFieWxvblRleHR1cmVzW2JhYnlsb25UZXh0dXJlLnVuaXF1ZUlkXSA9IGJhYnlsb25UZXh0dXJlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuZGlzcG9zZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yIChjb25zdCB1bmlxdWVJZCBpbiBiYWJ5bG9uVGV4dHVyZXMpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBiYWJ5bG9uTWF0ZXJpYWwgb2YgdGhpcy5fbG9hZGVyLmJhYnlsb25TY2VuZS5tYXRlcmlhbHMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwuaGFzVGV4dHVyZShiYWJ5bG9uVGV4dHVyZXNbdW5pcXVlSWRdKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBiYWJ5bG9uVGV4dHVyZXNbdW5pcXVlSWRdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IHVuaXF1ZUlkIGluIGJhYnlsb25UZXh0dXJlcykge1xyXG4gICAgICAgICAgICBiYWJ5bG9uVGV4dHVyZXNbdW5pcXVlSWRdLmRpc3Bvc2UoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IE1TRlRfbG9kKGxvYWRlcikpO1xyXG4iLCJpbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5pbXBvcnQgeyBQQlJNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9QQlIvcGJyTWF0ZXJpYWxcIjtcclxuXHJcbmltcG9ydCB0eXBlIHsgSU1hdGVyaWFsIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgeyBHTFRGTG9hZGVyIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJcIjtcclxuaW1wb3J0IHsgcmVnaXN0ZXJHTFRGRXh0ZW5zaW9uLCB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbiB9IGZyb20gXCIuLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuXHJcbmNvbnN0IE5BTUUgPSBcIk1TRlRfbWluZWNyYWZ0TWVzaFwiO1xyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCIuLi8uLi9nbFRGRmlsZUxvYWRlclwiIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBqc2RvYy9yZXF1aXJlLWpzZG9jXHJcbiAgICBleHBvcnQgaW50ZXJmYWNlIEdMVEZMb2FkZXJFeHRlbnNpb25PcHRpb25zIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWZpbmVzIG9wdGlvbnMgZm9yIHRoZSBNU0ZUX21pbmVjcmFmdE1lc2ggZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIk1TRlRfbWluZWNyYWZ0TWVzaFwiXToge307XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgY2xhc3MgTVNGVF9taW5lY3JhZnRNZXNoIGltcGxlbWVudHMgSUdMVEZMb2FkZXJFeHRlbnNpb24ge1xyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSBOQU1FO1xyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBlbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAgIHByaXZhdGUgX2xvYWRlcjogR0xURkxvYWRlcjtcclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBjb25zdHJ1Y3Rvcihsb2FkZXI6IEdMVEZMb2FkZXIpIHtcclxuICAgICAgICB0aGlzLl9sb2FkZXIgPSBsb2FkZXI7XHJcbiAgICAgICAgdGhpcy5lbmFibGVkID0gdGhpcy5fbG9hZGVyLmlzRXh0ZW5zaW9uVXNlZChOQU1FKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpIHtcclxuICAgICAgICAodGhpcy5fbG9hZGVyIGFzIGFueSkgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBsb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIHJldHVybiBHTFRGTG9hZGVyLkxvYWRFeHRyYUFzeW5jPGJvb2xlYW4+KGNvbnRleHQsIG1hdGVyaWFsLCB0aGlzLm5hbWUsIChleHRyYUNvbnRleHQsIGV4dHJhKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChleHRyYSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2V4dHJhQ29udGV4dH06IE1hdGVyaWFsIHR5cGUgbm90IHN1cHBvcnRlZGApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLl9sb2FkZXIubG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwubmVlZEFscGhhQmxlbmRpbmcoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5mb3JjZURlcHRoV3JpdGUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5zZXBhcmF0ZUN1bGxpbmdQYXNzID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYmFja0ZhY2VDdWxsaW5nID0gYmFieWxvbk1hdGVyaWFsLmZvcmNlRGVwdGhXcml0ZTtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC50d29TaWRlZExpZ2h0aW5nID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbnVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uKE5BTUUpO1xyXG5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSwgdHJ1ZSwgKGxvYWRlcikgPT4gbmV3IE1TRlRfbWluZWNyYWZ0TWVzaChsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gXCJjb3JlL3R5cGVzXCI7XHJcbmltcG9ydCB0eXBlIHsgTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvbWF0ZXJpYWxcIjtcclxuaW1wb3J0IHsgUEJSTWF0ZXJpYWwgfSBmcm9tIFwiY29yZS9NYXRlcmlhbHMvUEJSL3Bick1hdGVyaWFsXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IElNYXRlcmlhbCB9IGZyb20gXCIuLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuaW1wb3J0IHsgR0xURkxvYWRlciB9IGZyb20gXCIuLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB7IHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcblxyXG5jb25zdCBOQU1FID0gXCJNU0ZUX3NSR0JGYWN0b3JzXCI7XHJcblxyXG5kZWNsYXJlIG1vZHVsZSBcIi4uLy4uL2dsVEZGaWxlTG9hZGVyXCIge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2NcclxuICAgIGV4cG9ydCBpbnRlcmZhY2UgR0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIE1TRlRfc1JHQkZhY3RvcnMgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE5PVEU6IERvbid0IHVzZSBOQU1FIGhlcmUgYXMgaXQgd2lsbCBicmVhayB0aGUgVU1EIHR5cGUgZGVjbGFyYXRpb25zLlxyXG4gICAgICAgIFtcIk1TRlRfc1JHQkZhY3RvcnNcIl06IHt9O1xyXG4gICAgfVxyXG59XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuZXhwb3J0IGNsYXNzIE1TRlRfc1JHQkZhY3RvcnMgaW1wbGVtZW50cyBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZSA9IE5BTUU7XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGVuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZGVyOiBHTFRGTG9hZGVyO1xyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIGNvbnN0cnVjdG9yKGxvYWRlcjogR0xURkxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcjtcclxuICAgICAgICB0aGlzLmVuYWJsZWQgPSB0aGlzLl9sb2FkZXIuaXNFeHRlbnNpb25Vc2VkKE5BTUUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgICAgICh0aGlzLl9sb2FkZXIgYXMgYW55KSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyhjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBOdWxsYWJsZTxQcm9taXNlPHZvaWQ+PiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuTG9hZEV4dHJhQXN5bmM8Ym9vbGVhbj4oY29udGV4dCwgbWF0ZXJpYWwsIHRoaXMubmFtZSwgKGV4dHJhQ29udGV4dCwgZXh0cmEpID0+IHtcclxuICAgICAgICAgICAgaWYgKGV4dHJhKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIShiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXh0cmFDb250ZXh0fTogTWF0ZXJpYWwgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRoaXMuX2xvYWRlci5sb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgdXNlRXhhY3RTcmdiQ29udmVyc2lvbnMgPSBiYWJ5bG9uTWF0ZXJpYWwuZ2V0U2NlbmUoKS5nZXRFbmdpbmUoKS51c2VFeGFjdFNyZ2JDb252ZXJzaW9ucztcclxuICAgICAgICAgICAgICAgIGlmICghYmFieWxvbk1hdGVyaWFsLmFsYmVkb1RleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvQ29sb3IudG9MaW5lYXJTcGFjZVRvUmVmKGJhYnlsb25NYXRlcmlhbC5hbGJlZG9Db2xvciwgdXNlRXhhY3RTcmdiQ29udmVyc2lvbnMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICghYmFieWxvbk1hdGVyaWFsLnJlZmxlY3Rpdml0eVRleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwucmVmbGVjdGl2aXR5Q29sb3IudG9MaW5lYXJTcGFjZVRvUmVmKGJhYnlsb25NYXRlcmlhbC5yZWZsZWN0aXZpdHlDb2xvciwgdXNlRXhhY3RTcmdiQ29udmVyc2lvbnMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxudW5yZWdpc3RlckdMVEZFeHRlbnNpb24oTkFNRSk7XHJcbnJlZ2lzdGVyR0xURkV4dGVuc2lvbihOQU1FLCB0cnVlLCAobG9hZGVyKSA9PiBuZXcgTVNGVF9zUkdCRmFjdG9ycyhsb2FkZXIpKTtcclxuIiwiaW1wb3J0IHR5cGUgeyBJT2JqZWN0SW5mbywgSVBhdGhUb09iamVjdENvbnZlcnRlciB9IGZyb20gXCJjb3JlL09iamVjdE1vZGVsL29iamVjdE1vZGVsSW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcblxyXG4vKipcclxuICogQSBjb252ZXJ0ZXIgdGhhdCB0YWtlcyBhIGdsVEYgT2JqZWN0IE1vZGVsIEpTT04gUG9pbnRlclxyXG4gKiBhbmQgdHJhbnNmb3JtcyBpdCBpbnRvIGFuIE9iamVjdEFjY2Vzc29yQ29udGFpbmVyLCBhbGxvd2luZ1xyXG4gKiBvYmplY3RzIHJlZmVyZW5jZWQgaW4gdGhlIGdsVEYgdG8gYmUgYXNzb2NpYXRlZCB3aXRoIHRoZWlyXHJcbiAqIHJlc3BlY3RpdmUgQmFieWxvbi5qcyBvYmplY3RzLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEdMVEZQYXRoVG9PYmplY3RDb252ZXJ0ZXI8VD4gaW1wbGVtZW50cyBJUGF0aFRvT2JqZWN0Q29udmVydGVyPFQ+IHtcclxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwcml2YXRlIF9nbHRmOiBJR0xURixcclxuICAgICAgICBwcml2YXRlIF9pbmZvVHJlZTogYW55XHJcbiAgICApIHt9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgcG9pbnRlciBzdHJpbmcgaXMgcmVwcmVzZW50ZWQgYnkgYSBbSlNPTiBwb2ludGVyXShodHRwczovL2RhdGF0cmFja2VyLmlldGYub3JnL2RvYy9odG1sL3JmYzY5MDEpLlxyXG4gICAgICogPGFuaW1hdGlvblBvaW50ZXI+IDo9IC88cm9vdE5vZGU+Lzxhc3NldEluZGV4Pi88cHJvcGVydHlQYXRoPlxyXG4gICAgICogPHJvb3ROb2RlPiA6PSBcIm5vZGVzXCIgfCBcIm1hdGVyaWFsc1wiIHwgXCJtZXNoZXNcIiB8IFwiY2FtZXJhc1wiIHwgXCJleHRlbnNpb25zXCJcclxuICAgICAqIDxhc3NldEluZGV4PiA6PSA8ZGlnaXQ+IHwgPG5hbWU+XHJcbiAgICAgKiA8cHJvcGVydHlQYXRoPiA6PSA8ZXh0ZW5zaW9uUGF0aD4gfCA8c3RhbmRhcmRQYXRoPlxyXG4gICAgICogPGV4dGVuc2lvblBhdGg+IDo9IFwiZXh0ZW5zaW9uc1wiLzxuYW1lPi88c3RhbmRhcmRQYXRoPlxyXG4gICAgICogPHN0YW5kYXJkUGF0aD4gOj0gPG5hbWU+IHwgPG5hbWU+LzxzdGFuZGFyZFBhdGg+XHJcbiAgICAgKiA8bmFtZT4gOj0gVytcclxuICAgICAqIDxkaWdpdD4gOj0gRCtcclxuICAgICAqXHJcbiAgICAgKiBFeGFtcGxlczpcclxuICAgICAqICAtIFwiL25vZGVzLzAvcm90YXRpb25cIlxyXG4gICAgICogIC0gXCIvbWF0ZXJpYWxzLzIvZW1pc3NpdmVGYWN0b3JcIlxyXG4gICAgICogIC0gXCIvbWF0ZXJpYWxzLzIvcGJyTWV0YWxsaWNSb3VnaG5lc3MvYmFzZUNvbG9yRmFjdG9yXCJcclxuICAgICAqICAtIFwiL21hdGVyaWFscy8yL2V4dGVuc2lvbnMvS0hSX21hdGVyaWFsc19lbWlzc2l2ZV9zdHJlbmd0aC9lbWlzc2l2ZVN0cmVuZ3RoXCJcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gcGF0aCBUaGUgcGF0aCB0byBjb252ZXJ0XHJcbiAgICAgKiBAcmV0dXJucyBUaGUgb2JqZWN0IGFuZCBpbmZvIGFzc29jaWF0ZWQgd2l0aCB0aGUgcGF0aFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY29udmVydChwYXRoOiBzdHJpbmcpOiBJT2JqZWN0SW5mbzxUPiB7XHJcbiAgICAgICAgbGV0IG9iamVjdFRyZWU6IGFueSA9IHRoaXMuX2dsdGY7XHJcbiAgICAgICAgbGV0IGluZm9UcmVlOiBhbnkgPSB0aGlzLl9pbmZvVHJlZTtcclxuICAgICAgICBsZXQgdGFyZ2V0OiBhbnkgPSB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgIGlmICghcGF0aC5zdGFydHNXaXRoKFwiL1wiKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQYXRoIG11c3Qgc3RhcnQgd2l0aCBhIC9cIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHBhcnRzID0gcGF0aC5zcGxpdChcIi9cIik7XHJcbiAgICAgICAgcGFydHMuc2hpZnQoKTtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XHJcbiAgICAgICAgICAgIGlmIChpbmZvVHJlZS5fX2FycmF5X18pIHtcclxuICAgICAgICAgICAgICAgIGluZm9UcmVlID0gaW5mb1RyZWUuX19hcnJheV9fO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaW5mb1RyZWUgPSBpbmZvVHJlZVtwYXJ0XTtcclxuICAgICAgICAgICAgICAgIGlmICghaW5mb1RyZWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFBhdGggJHtwYXRofSBpcyBpbnZhbGlkYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKG9iamVjdFRyZWUgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQYXRoICR7cGF0aH0gaXMgaW52YWxpZGApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9iamVjdFRyZWUgPSBvYmplY3RUcmVlW3BhcnRdO1xyXG5cclxuICAgICAgICAgICAgaWYgKGluZm9UcmVlLl9fdGFyZ2V0X18pIHtcclxuICAgICAgICAgICAgICAgIHRhcmdldCA9IG9iamVjdFRyZWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIG9iamVjdDogdGFyZ2V0LFxyXG4gICAgICAgICAgICBpbmZvOiBpbmZvVHJlZSxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59XHJcbiIsImV4cG9ydCAqIGZyb20gXCIuL0VYVF9saWdodHNfaW1hZ2VfYmFzZWRcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vRVhUX21lc2hfZ3B1X2luc3RhbmNpbmdcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vRVhUX21lc2hvcHRfY29tcHJlc3Npb25cIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vRVhUX3RleHR1cmVfd2VicFwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9FWFRfdGV4dHVyZV9hdmlmXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9kcmFjb19tZXNoX2NvbXByZXNzaW9uXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9saWdodHNfcHVuY3R1YWxcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX21hdGVyaWFsc19wYnJTcGVjdWxhckdsb3NzaW5lc3NcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX21hdGVyaWFsc191bmxpdFwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWF0ZXJpYWxzX2NsZWFyY29hdFwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWF0ZXJpYWxzX2lyaWRlc2NlbmNlXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfYW5pc290cm9weVwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWF0ZXJpYWxzX2VtaXNzaXZlX3N0cmVuZ3RoXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfc2hlZW5cIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX21hdGVyaWFsc19zcGVjdWxhclwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWF0ZXJpYWxzX2lvclwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfbWF0ZXJpYWxzX3ZhcmlhbnRzXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfdHJhbnNtaXNzaW9uXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tYXRlcmlhbHNfZGlmZnVzZV90cmFuc21pc3Npb25cIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX21hdGVyaWFsc192b2x1bWVcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX21hdGVyaWFsc19kaXNwZXJzaW9uXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9tZXNoX3F1YW50aXphdGlvblwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfdGV4dHVyZV9iYXNpc3VcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vS0hSX3RleHR1cmVfdHJhbnNmb3JtXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl94bXBfanNvbl9sZFwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9LSFJfYW5pbWF0aW9uX3BvaW50ZXJcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vTVNGVF9hdWRpb19lbWl0dGVyXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL01TRlRfbG9kXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL01TRlRfbWluZWNyYWZ0TWVzaFwiO1xyXG5leHBvcnQgKiBmcm9tIFwiLi9NU0ZUX3NSR0JGYWN0b3JzXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9pbnRlcmFjdGl2aXR5XCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0tIUl9ub2RlX3Zpc2liaWxpdHlcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vRXh0cmFzQXNNZXRhZGF0YVwiO1xyXG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24gKi9cclxuaW1wb3J0IHR5cGUgeyBJS0hSSW50ZXJhY3Rpdml0eSwgSUtIUkludGVyYWN0aXZpdHlfQ29uZmlndXJhdGlvbiwgSUtIUkludGVyYWN0aXZpdHlfTm9kZSwgSUtIUkludGVyYWN0aXZpdHlfVmFyaWFibGUgfSBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB0eXBlIHsgSUZsb3dHcmFwaEJsb2NrQ29uZmlndXJhdGlvbiB9IGZyb20gXCJjb3JlL0Zsb3dHcmFwaC9mbG93R3JhcGhCbG9ja1wiO1xyXG5pbXBvcnQgdHlwZSB7IElTZXJpYWxpemVkRmxvd0dyYXBoLCBJU2VyaWFsaXplZEZsb3dHcmFwaEJsb2NrLCBJU2VyaWFsaXplZEZsb3dHcmFwaENvbm5lY3Rpb24sIElTZXJpYWxpemVkRmxvd0dyYXBoQ29udGV4dCB9IGZyb20gXCJjb3JlL0Zsb3dHcmFwaC90eXBlRGVmaW5pdGlvbnNcIjtcclxuaW1wb3J0IHsgUmFuZG9tR1VJRCB9IGZyb20gXCJjb3JlL01pc2MvZ3VpZFwiO1xyXG5pbXBvcnQgeyBnbHRmVG9GbG93R3JhcGhUeXBlTWFwLCBnbHRmVHlwZVRvQmFieWxvblR5cGUgfSBmcm9tIFwiLi9pbnRlcmFjdGl2aXR5VXRpbHNcIjtcclxuaW1wb3J0IHsgRmxvd0dyYXBoQ29ubmVjdGlvblR5cGUgfSBmcm9tIFwiY29yZS9GbG93R3JhcGgvZmxvd0dyYXBoQ29ubmVjdGlvblwiO1xyXG5cclxuZnVuY3Rpb24gY29udmVydFZhbHVlV2l0aFR5cGUoY29uZmlnT2JqZWN0OiBJS0hSSW50ZXJhY3Rpdml0eV9Db25maWd1cmF0aW9uLCBkZWZpbml0aW9uOiBJS0hSSW50ZXJhY3Rpdml0eSwgY29udGV4dDogc3RyaW5nKSB7XHJcbiAgICBpZiAoY29uZmlnT2JqZWN0LnR5cGUgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIC8vIGdldCB0aGUgdHlwZSBvbiB0aGUgZ2x0ZiBkZWZpbml0aW9uXHJcbiAgICAgICAgY29uc3QgdHlwZSA9IGRlZmluaXRpb24udHlwZXMgJiYgZGVmaW5pdGlvbi50eXBlc1tjb25maWdPYmplY3QudHlwZV07XHJcbiAgICAgICAgaWYgKCF0eXBlKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogVW5rbm93biB0eXBlOiAke2NvbmZpZ09iamVjdC50eXBlfWApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBzaWduYXR1cmUgPSB0eXBlLnNpZ25hdHVyZTtcclxuICAgICAgICBpZiAoIXNpZ25hdHVyZSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IFR5cGUgJHtjb25maWdPYmplY3QudHlwZX0gaGFzIG5vIHNpZ25hdHVyZWApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBjb252ZXJ0ZWRUeXBlID0gZ2x0ZlR5cGVUb0JhYnlsb25UeXBlW3NpZ25hdHVyZV07XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmFsdWU6IGNvbmZpZ09iamVjdC52YWx1ZSxcclxuICAgICAgICAgICAgY2xhc3NOYW1lOiBjb252ZXJ0ZWRUeXBlLFxyXG4gICAgICAgIH07XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiBjb25maWdPYmplY3QudmFsdWU7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNvbnZlcnRDb25maWd1cmF0aW9uKGdsdGZCbG9jazogSUtIUkludGVyYWN0aXZpdHlfTm9kZSwgZGVmaW5pdGlvbjogSUtIUkludGVyYWN0aXZpdHksIGlkOiBzdHJpbmcpOiBJRmxvd0dyYXBoQmxvY2tDb25maWd1cmF0aW9uIHtcclxuICAgIGNvbnN0IGNvbnZlcnRlZDogSUZsb3dHcmFwaEJsb2NrQ29uZmlndXJhdGlvbiA9IHt9O1xyXG4gICAgY29uc3QgY29uZmlndXJhdGlvbkxpc3Q6IElLSFJJbnRlcmFjdGl2aXR5X0NvbmZpZ3VyYXRpb25bXSA9IGdsdGZCbG9jay5jb25maWd1cmF0aW9uID8/IFtdO1xyXG4gICAgZm9yIChjb25zdCBjb25maWdPYmplY3Qgb2YgY29uZmlndXJhdGlvbkxpc3QpIHtcclxuICAgICAgICBpZiAoY29uZmlnT2JqZWN0LmlkID09PSBcImN1c3RvbUV2ZW50XCIpIHtcclxuICAgICAgICAgICAgY29uc3QgY3VzdG9tRXZlbnQgPSBkZWZpbml0aW9uLmN1c3RvbUV2ZW50cyAmJiBkZWZpbml0aW9uLmN1c3RvbUV2ZW50c1tjb25maWdPYmplY3QudmFsdWVdO1xyXG4gICAgICAgICAgICBpZiAoIWN1c3RvbUV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYC9leHRlbnNpb25zL0tIUl9pbnRlcmFjdGl2aXR5L25vZGVzLyR7aWR9OiBVbmtub3duIGN1c3RvbSBldmVudDogJHtjb25maWdPYmplY3QudmFsdWV9YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29udmVydGVkLmV2ZW50SWQgPSBjdXN0b21FdmVudC5pZDtcclxuICAgICAgICAgICAgY29udmVydGVkLmV2ZW50RGF0YSA9IGN1c3RvbUV2ZW50LnZhbHVlcy5tYXAoKHYpID0+IHYuaWQpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoY29uZmlnT2JqZWN0LmlkID09PSBcInZhcmlhYmxlXCIpIHtcclxuICAgICAgICAgICAgY29uc3QgdmFyaWFibGUgPSBkZWZpbml0aW9uLnZhcmlhYmxlcyAmJiBkZWZpbml0aW9uLnZhcmlhYmxlc1tjb25maWdPYmplY3QudmFsdWVdO1xyXG4gICAgICAgICAgICBpZiAoIXZhcmlhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYC9leHRlbnNpb25zL0tIUl9pbnRlcmFjdGl2aXR5L25vZGVzLyR7aWR9OiBVbmtub3duIHZhcmlhYmxlOiAke2NvbmZpZ09iamVjdC52YWx1ZX1gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb252ZXJ0ZWQudmFyaWFibGVOYW1lID0gdmFyaWFibGUuaWQ7XHJcbiAgICAgICAgfSBlbHNlIGlmIChjb25maWdPYmplY3QuaWQgPT09IFwicGF0aFwiKSB7XHJcbiAgICAgICAgICAgIC8vIENvbnZlcnQgZnJvbSBhIEdMVEYgcGF0aCB0byBhIHJlZmVyZW5jZSB0byB0aGUgQmFieWxvbi5qcyBvYmplY3RcclxuICAgICAgICAgICAgY29uc3QgcGF0aFZhbHVlID0gY29uZmlnT2JqZWN0LnZhbHVlIGFzIHN0cmluZztcclxuICAgICAgICAgICAgY29udmVydGVkLnBhdGggPSBwYXRoVmFsdWU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29udmVydGVkW2NvbmZpZ09iamVjdC5pZF0gPSBjb252ZXJ0VmFsdWVXaXRoVHlwZShjb25maWdPYmplY3QsIGRlZmluaXRpb24sIGAvZXh0ZW5zaW9ucy9LSFJfaW50ZXJhY3Rpdml0eS9ub2Rlcy8ke2lkfWApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBjb252ZXJ0ZWQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNvbnZlcnRCbG9jayhpZDogbnVtYmVyLCBnbHRmQmxvY2s6IElLSFJJbnRlcmFjdGl2aXR5X05vZGUsIGRlZmluaXRpb246IElLSFJJbnRlcmFjdGl2aXR5KTogSVNlcmlhbGl6ZWRGbG93R3JhcGhCbG9jayB7XHJcbiAgICBjb25zdCBjbGFzc05hbWUgPSBnbHRmVG9GbG93R3JhcGhUeXBlTWFwW2dsdGZCbG9jay50eXBlXTtcclxuICAgIGlmICghY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAvZXh0ZW5zaW9ucy9LSFJfaW50ZXJhY3Rpdml0eS9ub2Rlcy8ke2lkfTogVW5rbm93biBibG9jayB0eXBlOiAke2dsdGZCbG9jay50eXBlfWApO1xyXG4gICAgfVxyXG4gICAgY29uc3QgdW5pcXVlSWQgPSBpZC50b1N0cmluZygpO1xyXG4gICAgY29uc3QgY29uZmlnID0gY29udmVydENvbmZpZ3VyYXRpb24oZ2x0ZkJsb2NrLCBkZWZpbml0aW9uLCB1bmlxdWVJZCk7XHJcbiAgICBjb25zdCBtZXRhZGF0YSA9IGdsdGZCbG9jay5tZXRhZGF0YTtcclxuICAgIGNvbnN0IGRhdGFJbnB1dHM6IElTZXJpYWxpemVkRmxvd0dyYXBoQ29ubmVjdGlvbltdID0gW107XHJcbiAgICBjb25zdCBkYXRhT3V0cHV0czogSVNlcmlhbGl6ZWRGbG93R3JhcGhDb25uZWN0aW9uW10gPSBbXTtcclxuICAgIGNvbnN0IHNpZ25hbElucHV0czogSVNlcmlhbGl6ZWRGbG93R3JhcGhDb25uZWN0aW9uW10gPSBbXTtcclxuICAgIGNvbnN0IHNpZ25hbE91dHB1dHM6IElTZXJpYWxpemVkRmxvd0dyYXBoQ29ubmVjdGlvbltdID0gW107XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGNsYXNzTmFtZSxcclxuICAgICAgICBjb25maWcsXHJcbiAgICAgICAgdW5pcXVlSWQsXHJcbiAgICAgICAgbWV0YWRhdGEsXHJcbiAgICAgICAgZGF0YUlucHV0cyxcclxuICAgICAgICBkYXRhT3V0cHV0cyxcclxuICAgICAgICBzaWduYWxJbnB1dHMsXHJcbiAgICAgICAgc2lnbmFsT3V0cHV0cyxcclxuICAgIH07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBAaW50ZXJuYWxcclxuICogQ29udmVydHMgYSBnbFRGIEludGVyYWN0aXZpdHkgRXh0ZW5zaW9uIHRvIGEgc2VyaWFsaXplZCBmbG93IGdyYXBoLlxyXG4gKiBAcGFyYW0gZ2x0ZiB0aGUgaW50ZXJhY3Rpdml0eSBkYXRhXHJcbiAqIEByZXR1cm5zIGEgc2VyaWFsaXplZCBmbG93IGdyYXBoXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY29udmVydEdMVEZUb1NlcmlhbGl6ZWRGbG93R3JhcGgoZ2x0ZjogSUtIUkludGVyYWN0aXZpdHkpOiBJU2VyaWFsaXplZEZsb3dHcmFwaCB7XHJcbiAgICAvLyBjcmVhdGUgYW4gZW1wdHkgc2VyaWFsaXplZCBjb250ZXh0IHRvIHN0b3JlIHRoZSB2YWx1ZXMgb2YgdGhlIGNvbm5lY3Rpb25zXHJcbiAgICBjb25zdCBjb250ZXh0OiBJU2VyaWFsaXplZEZsb3dHcmFwaENvbnRleHQgPSB7XHJcbiAgICAgICAgdW5pcXVlSWQ6IFJhbmRvbUdVSUQoKSxcclxuICAgICAgICBfdXNlclZhcmlhYmxlczoge30sXHJcbiAgICAgICAgX2Nvbm5lY3Rpb25WYWx1ZXM6IHt9LFxyXG4gICAgfTtcclxuICAgIGNvbnN0IGV4ZWN1dGlvbkNvbnRleHRzID0gW2NvbnRleHRdO1xyXG5cclxuICAgIC8vIEJsb2NrcyBjb252ZXJ0ZWQgdG8gdGhlIGZsb3cgZ3JhcGgganNvbiBmb3JtYXRcclxuICAgIGNvbnN0IGZsb3dHcmFwaEpzb25CbG9ja3M6IElTZXJpYWxpemVkRmxvd0dyYXBoQmxvY2tbXSA9IFtdO1xyXG5cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ2x0Zi5ub2Rlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IGdsdGZCbG9jayA9IGdsdGYubm9kZXNbaV07XHJcbiAgICAgICAgY29uc3QgZmxvd0dyYXBoSnNvbkJsb2NrID0gY29udmVydEJsb2NrKGksIGdsdGZCbG9jaywgZ2x0Zik7XHJcbiAgICAgICAgZmxvd0dyYXBoSnNvbkJsb2Nrcy5wdXNoKGZsb3dHcmFwaEpzb25CbG9jayk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUGFyc2UgdGhlIGNvbm5lY3Rpb25zXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdsdGYubm9kZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBjb25zdCBnbHRmQmxvY2sgPSBnbHRmLm5vZGVzW2ldO1xyXG4gICAgICAgIC8vIGdldCB0aGUgYmxvY2sgdGhhdCB3YXMgY3JlYXRlZCBpbiB0aGUgcHJldmlvdXMgc3RlcFxyXG4gICAgICAgIGNvbnN0IGZnQmxvY2sgPSBmbG93R3JhcGhKc29uQmxvY2tzW2ldO1xyXG4gICAgICAgIGNvbnN0IGdsdGZGbG93cyA9IGdsdGZCbG9jay5mbG93cyA/PyBbXTtcclxuICAgICAgICAvLyBmb3IgZWFjaCBvdXRwdXQgZmxvdyBvZiB0aGUgZ2x0ZiBibG9ja1xyXG4gICAgICAgIGZvciAoY29uc3QgZmxvdyBvZiBnbHRmRmxvd3MpIHtcclxuICAgICAgICAgICAgY29uc3Qgc29ja2V0T3V0TmFtZSA9IGZsb3cuaWQ7XHJcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhbiBvdXRwdXQgY29ubmVjdGlvbiBmb3IgdGhlIGZsb3cgZ3JhcGggYmxvY2tcclxuICAgICAgICAgICAgY29uc3Qgc29ja2V0T3V0OiBJU2VyaWFsaXplZEZsb3dHcmFwaENvbm5lY3Rpb24gPSB7XHJcbiAgICAgICAgICAgICAgICB1bmlxdWVJZDogUmFuZG9tR1VJRCgpLFxyXG4gICAgICAgICAgICAgICAgbmFtZTogc29ja2V0T3V0TmFtZSxcclxuICAgICAgICAgICAgICAgIF9jb25uZWN0aW9uVHlwZTogRmxvd0dyYXBoQ29ubmVjdGlvblR5cGUuT3V0cHV0LCAvLyBPdXRwdXRcclxuICAgICAgICAgICAgICAgIGNvbm5lY3RlZFBvaW50SWRzOiBbXSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgZmdCbG9jay5zaWduYWxPdXRwdXRzLnB1c2goc29ja2V0T3V0KTtcclxuICAgICAgICAgICAgLy8gZ2V0IHRoZSBpbnB1dCBub2RlIG9mIHRoaXMgZmxvd1xyXG4gICAgICAgICAgICBjb25zdCBub2RlSW5JZCA9IGZsb3cubm9kZTtcclxuICAgICAgICAgICAgY29uc3Qgbm9kZUluU29ja2V0TmFtZSA9IGZsb3cuc29ja2V0O1xyXG4gICAgICAgICAgICAvLyBmaW5kIHRoZSBjb3JyZXNwb25kaW5nIGZsb3cgZ3JhcGggbm9kZVxyXG4gICAgICAgICAgICBjb25zdCBub2RlSW4gPSBmbG93R3JhcGhKc29uQmxvY2tzW25vZGVJbklkXTtcclxuICAgICAgICAgICAgaWYgKCFub2RlSW4pIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcclxuICAgICAgICAgICAgICAgICAgICBgL2V4dGVuc2lvbnMvS0hSX2ludGVyYWN0aXZpdHkvbm9kZXMvJHtpfTogQ291bGQgbm90IGZpbmQgbm9kZSB3aXRoIGlkICR7bm9kZUluSWR9IHRoYXQgY29ubmVjdHMgaXRzIGlucHV0IHdpdGggd2l0aCBub2RlICR7aX0ncyBvdXRwdXQgJHtzb2NrZXRPdXROYW1lfWBcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gaW4gYWxsIG9mIHRoZSBmbG93IGdyYXBoIGlucHV0IGNvbm5lY3Rpb25zLCBmaW5kIHRoZSBvbmUgd2l0aCB0aGUgc2FtZSBuYW1lIGFzIHRoZSBzb2NrZXRcclxuICAgICAgICAgICAgbGV0IHNvY2tldEluID0gbm9kZUluLnNpZ25hbElucHV0cy5maW5kKChzKSA9PiBzLm5hbWUgPT09IG5vZGVJblNvY2tldE5hbWUpO1xyXG4gICAgICAgICAgICAvLyBpZiB0aGUgc29ja2V0IGRvZXNuJ3QgZXhpc3QsIGNyZWF0ZSB0aGUgaW5wdXQgc29ja2V0IGZvciB0aGUgY29ubmVjdGlvblxyXG4gICAgICAgICAgICBpZiAoIXNvY2tldEluKSB7XHJcbiAgICAgICAgICAgICAgICBzb2NrZXRJbiA9IHtcclxuICAgICAgICAgICAgICAgICAgICB1bmlxdWVJZDogUmFuZG9tR1VJRCgpLFxyXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IG5vZGVJblNvY2tldE5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgX2Nvbm5lY3Rpb25UeXBlOiBGbG93R3JhcGhDb25uZWN0aW9uVHlwZS5JbnB1dCwgLy8gSW5wdXRcclxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0ZWRQb2ludElkczogW10sXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgbm9kZUluLnNpZ25hbElucHV0cy5wdXNoKHNvY2tldEluKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBjb25uZWN0IHRoZSBzb2NrZXRzXHJcbiAgICAgICAgICAgIHNvY2tldEluLmNvbm5lY3RlZFBvaW50SWRzLnB1c2goc29ja2V0T3V0LnVuaXF1ZUlkKTtcclxuICAgICAgICAgICAgc29ja2V0T3V0LmNvbm5lY3RlZFBvaW50SWRzLnB1c2goc29ja2V0SW4udW5pcXVlSWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBmb3IgZWFjaCBpbnB1dCB2YWx1ZSBvZiB0aGUgZ2x0ZiBibG9ja1xyXG4gICAgICAgIGNvbnN0IGdsdGZWYWx1ZXMgPSBnbHRmQmxvY2sudmFsdWVzID8/IFtdO1xyXG4gICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgZ2x0ZlZhbHVlcykge1xyXG4gICAgICAgICAgICBjb25zdCBzb2NrZXRJbk5hbWUgPSB2YWx1ZS5pZDtcclxuICAgICAgICAgICAgLy8gY3JlYXRlIGFuIGlucHV0IGRhdGEgY29ubmVjdGlvbiBmb3IgdGhlIGZsb3cgZ3JhcGggYmxvY2tcclxuICAgICAgICAgICAgY29uc3Qgc29ja2V0SW46IElTZXJpYWxpemVkRmxvd0dyYXBoQ29ubmVjdGlvbiA9IHtcclxuICAgICAgICAgICAgICAgIHVuaXF1ZUlkOiBSYW5kb21HVUlEKCksXHJcbiAgICAgICAgICAgICAgICBuYW1lOiBzb2NrZXRJbk5hbWUsXHJcbiAgICAgICAgICAgICAgICBfY29ubmVjdGlvblR5cGU6IEZsb3dHcmFwaENvbm5lY3Rpb25UeXBlLklucHV0LFxyXG4gICAgICAgICAgICAgICAgY29ubmVjdGVkUG9pbnRJZHM6IFtdLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBmZ0Jsb2NrLmRhdGFJbnB1dHMucHVzaChzb2NrZXRJbik7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZS52YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgdmFsdWUgaXMgc2V0IG9uIHRoZSBzb2NrZXQgaXRzZWxmLCBzdG9yZSBpdCBpbiB0aGUgY29udGV4dFxyXG4gICAgICAgICAgICAgICAgY29uc3QgY29udmVydGVkVmFsdWUgPSBjb252ZXJ0VmFsdWVXaXRoVHlwZSh2YWx1ZSBhcyBJS0hSSW50ZXJhY3Rpdml0eV9Db25maWd1cmF0aW9uLCBnbHRmLCBgL2V4dGVuc2lvbnMvS0hSX2ludGVyYWN0aXZpdHkvbm9kZXMvJHtpfWApO1xyXG4gICAgICAgICAgICAgICAgLy8gY29udmVydEJsb2NrSW5wdXRUeXBlKGdsdGZCbG9jaywgdmFsdWUsIGNvbnZlcnRlZFZhbHVlLCBgL2V4dGVuc2lvbnMvS0hSX2ludGVyYWN0aXZpdHkvbm9kZXMvJHtpfWApO1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5fY29ubmVjdGlvblZhbHVlc1tzb2NrZXRJbi51bmlxdWVJZF0gPSBjb252ZXJ0ZWRWYWx1ZTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZS5ub2RlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUuc29ja2V0ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIC8vIGlmIHRoZSB2YWx1ZSBpcyBjb25uZWN0ZWQgd2l0aCB0aGUgb3V0cHV0IGRhdGEgb2YgYW5vdGhlciBzb2NrZXQsIGNvbm5lY3QgdGhlIHR3b1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgbm9kZU91dElkID0gdmFsdWUubm9kZTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5vZGVPdXRTb2NrZXROYW1lID0gdmFsdWUuc29ja2V0O1xyXG4gICAgICAgICAgICAgICAgLy8gZmluZCB0aGUgZmxvdyBncmFwaCBub2RlIHRoYXQgb3ducyB0aGF0IG91dHB1dCBzb2NrZXRcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5vZGVPdXQgPSBmbG93R3JhcGhKc29uQmxvY2tzW25vZGVPdXRJZF07XHJcbiAgICAgICAgICAgICAgICBpZiAoIW5vZGVPdXQpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGAvZXh0ZW5zaW9ucy9LSFJfaW50ZXJhY3Rpdml0eS9ub2Rlcy8ke2l9OiBDb3VsZCBub3QgZmluZCBub2RlIHdpdGggaWQgJHtub2RlT3V0SWR9IHRoYXQgY29ubmVjdHMgaXRzIG91dHB1dCB3aXRoIG5vZGUke2l9J3MgaW5wdXQgJHtzb2NrZXRJbk5hbWV9YFxyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBsZXQgc29ja2V0T3V0ID0gbm9kZU91dC5kYXRhT3V0cHV0cy5maW5kKChzKSA9PiBzLm5hbWUgPT09IG5vZGVPdXRTb2NrZXROYW1lKTtcclxuICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBzb2NrZXQgZG9lc24ndCBleGlzdCwgY3JlYXRlIGl0XHJcbiAgICAgICAgICAgICAgICBpZiAoIXNvY2tldE91dCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNvY2tldE91dCA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdW5pcXVlSWQ6IFJhbmRvbUdVSUQoKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogbm9kZU91dFNvY2tldE5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb25uZWN0aW9uVHlwZTogRmxvd0dyYXBoQ29ubmVjdGlvblR5cGUuT3V0cHV0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0ZWRQb2ludElkczogW10sXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBub2RlT3V0LmRhdGFPdXRwdXRzLnB1c2goc29ja2V0T3V0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIGNvbm5lY3QgdGhlIHNvY2tldHNcclxuICAgICAgICAgICAgICAgIHNvY2tldEluLmNvbm5lY3RlZFBvaW50SWRzLnB1c2goc29ja2V0T3V0LnVuaXF1ZUlkKTtcclxuICAgICAgICAgICAgICAgIHNvY2tldE91dC5jb25uZWN0ZWRQb2ludElkcy5wdXNoKHNvY2tldEluLnVuaXF1ZUlkKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgL2V4dGVuc2lvbnMvS0hSX2ludGVyYWN0aXZpdHkvbm9kZXMvJHtpfTogSW52YWxpZCBzb2NrZXQgJHtzb2NrZXRJbk5hbWV9IGluIG5vZGUgJHtpfWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHZhcmlhYmxlcyA9IGdsdGYudmFyaWFibGVzID8/IFtdO1xyXG4gICAgLy8gUGFyc2UgdmFyaWFibGVzXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhcmlhYmxlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IHZhcmlhYmxlOiBJS0hSSW50ZXJhY3Rpdml0eV9WYXJpYWJsZSA9IHZhcmlhYmxlc1tpXTtcclxuICAgICAgICBjb25zdCB2YXJpYWJsZU5hbWUgPSB2YXJpYWJsZS5pZDtcclxuICAgICAgICBjb250ZXh0Ll91c2VyVmFyaWFibGVzW3ZhcmlhYmxlTmFtZV0gPSBjb252ZXJ0VmFsdWVXaXRoVHlwZSh2YXJpYWJsZSBhcyBJS0hSSW50ZXJhY3Rpdml0eV9Db25maWd1cmF0aW9uLCBnbHRmLCBgL2V4dGVuc2lvbnMvS0hSX2ludGVyYWN0aXZpdHkvdmFyaWFibGVzLyR7aX1gKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGFsbEJsb2NrczogZmxvd0dyYXBoSnNvbkJsb2NrcyxcclxuICAgICAgICBleGVjdXRpb25Db250ZXh0cyxcclxuICAgIH07XHJcbn1cclxuIiwiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXHJcbmltcG9ydCB0eXBlIHsgSUdMVEYsIElOb2RlIH0gZnJvbSBcIi4uL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB7IEdMVEZQYXRoVG9PYmplY3RDb252ZXJ0ZXIgfSBmcm9tIFwiLi9nbHRmUGF0aFRvT2JqZWN0Q29udmVydGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgVHJhbnNmb3JtTm9kZSB9IGZyb20gXCJjb3JlL01lc2hlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElPYmplY3RBY2Nlc3NvciB9IGZyb20gXCJjb3JlL0Zsb3dHcmFwaC90eXBlRGVmaW5pdGlvbnNcIjtcclxuXHJcbi8qKlxyXG4gKiBDbGFzcyB0byBjb252ZXJ0IGFuIGludGVyYWN0aXZpdHkgcG9pbnRlciBwYXRoIHRvIGEgc21hcnQgb2JqZWN0XHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgSW50ZXJhY3Rpdml0eVBhdGhUb09iamVjdENvbnZlcnRlciBleHRlbmRzIEdMVEZQYXRoVG9PYmplY3RDb252ZXJ0ZXI8SU9iamVjdEFjY2Vzc29yPiB7XHJcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoZ2x0ZjogSUdMVEYpIHtcclxuICAgICAgICBzdXBlcihnbHRmLCBnbHRmVHJlZSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmNvbnN0IG5vZGVzVHJlZSA9IHtcclxuICAgIF9fYXJyYXlfXzoge1xyXG4gICAgICAgIF9fdGFyZ2V0X186IHRydWUsXHJcbiAgICAgICAgdHJhbnNsYXRpb246IHtcclxuICAgICAgICAgICAgdHlwZTogXCJWZWN0b3IzXCIsXHJcbiAgICAgICAgICAgIGdldDogKG5vZGU6IElOb2RlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uT2JqZWN0ID0gbm9kZS5fYmFieWxvblRyYW5zZm9ybU5vZGUgYXMgVHJhbnNmb3JtTm9kZTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBiYWJ5bG9uT2JqZWN0LnBvc2l0aW9uO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBzZXQ6ICh2YWx1ZTogYW55LCBub2RlOiBJTm9kZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYmFieWxvbk9iamVjdCA9IG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlIGFzIFRyYW5zZm9ybU5vZGU7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uT2JqZWN0LnBvc2l0aW9uID0gdmFsdWU7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGdldE9iamVjdChub2RlOiBJTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICB9LFxyXG59O1xyXG5cclxuY29uc3QgZ2x0ZlRyZWUgPSB7XHJcbiAgICBub2Rlczogbm9kZXNUcmVlLFxyXG59O1xyXG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24gKi9cclxuaW1wb3J0IHsgRmxvd0dyYXBoU2NlbmVSZWFkeUV2ZW50QmxvY2sgfSBmcm9tIFwiY29yZS9GbG93R3JhcGgvQmxvY2tzL0V2ZW50L2Zsb3dHcmFwaFNjZW5lUmVhZHlFdmVudEJsb2NrXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaFNjZW5lVGlja0V2ZW50QmxvY2sgfSBmcm9tIFwiY29yZS9GbG93R3JhcGgvQmxvY2tzL0V2ZW50L2Zsb3dHcmFwaFNjZW5lVGlja0V2ZW50QmxvY2tcIjtcclxuaW1wb3J0IHsgRmxvd0dyYXBoQ29uc29sZUxvZ0Jsb2NrIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL0Jsb2Nrcy9FeGVjdXRpb24vZmxvd0dyYXBoQ29uc29sZUxvZ0Jsb2NrXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaFRpbWVyQmxvY2sgfSBmcm9tIFwiY29yZS9GbG93R3JhcGgvQmxvY2tzL0V4ZWN1dGlvbi9Db250cm9sRmxvdy9mbG93R3JhcGhUaW1lckJsb2NrXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaFNlbmRDdXN0b21FdmVudEJsb2NrIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL0Jsb2Nrcy9FeGVjdXRpb24vZmxvd0dyYXBoU2VuZEN1c3RvbUV2ZW50QmxvY2tcIjtcclxuaW1wb3J0IHsgRmxvd0dyYXBoUmVjZWl2ZUN1c3RvbUV2ZW50QmxvY2sgfSBmcm9tIFwiY29yZS9GbG93R3JhcGgvQmxvY2tzL0V2ZW50L2Zsb3dHcmFwaFJlY2VpdmVDdXN0b21FdmVudEJsb2NrXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaFNlcXVlbmNlQmxvY2sgfSBmcm9tIFwiY29yZS9GbG93R3JhcGgvQmxvY2tzL0V4ZWN1dGlvbi9Db250cm9sRmxvdy9mbG93R3JhcGhTZXF1ZW5jZUJsb2NrXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaEdldFByb3BlcnR5QmxvY2sgfSBmcm9tIFwiY29yZS9GbG93R3JhcGgvQmxvY2tzL0RhdGEvZmxvd0dyYXBoR2V0UHJvcGVydHlCbG9ja1wiO1xyXG5pbXBvcnQgeyBGbG93R3JhcGhTZXRQcm9wZXJ0eUJsb2NrIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL0Jsb2Nrcy9FeGVjdXRpb24vZmxvd0dyYXBoU2V0UHJvcGVydHlCbG9ja1wiO1xyXG5pbXBvcnQge1xyXG4gICAgRmxvd0dyYXBoQWRkQmxvY2ssXHJcbiAgICBGbG93R3JhcGhSYW5kb21CbG9jayxcclxuICAgIEZsb3dHcmFwaExlc3NUaGFuQmxvY2ssXHJcbiAgICBGbG93R3JhcGhNdWx0aXBseUJsb2NrLFxyXG4gICAgRmxvd0dyYXBoU3VidHJhY3RCbG9jayxcclxuICAgIEZsb3dHcmFwaERvdEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoRUJsb2NrLFxyXG4gICAgRmxvd0dyYXBoUGlCbG9jayxcclxuICAgIEZsb3dHcmFwaEluZkJsb2NrLFxyXG4gICAgRmxvd0dyYXBoTmFOQmxvY2ssXHJcbiAgICBGbG93R3JhcGhBYnNCbG9jayxcclxuICAgIEZsb3dHcmFwaFNpZ25CbG9jayxcclxuICAgIEZsb3dHcmFwaFRydW5jQmxvY2ssXHJcbiAgICBGbG93R3JhcGhGbG9vckJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQ2VpbEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoRnJhY3RCbG9jayxcclxuICAgIEZsb3dHcmFwaE5lZ0Jsb2NrLFxyXG4gICAgRmxvd0dyYXBoRGl2aWRlQmxvY2ssXHJcbiAgICBGbG93R3JhcGhSZW1haW5kZXJCbG9jayxcclxuICAgIEZsb3dHcmFwaE1pbkJsb2NrLFxyXG4gICAgRmxvd0dyYXBoTWF4QmxvY2ssXHJcbiAgICBGbG93R3JhcGhDbGFtcEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoU2F0dXJhdGVCbG9jayxcclxuICAgIEZsb3dHcmFwaEludGVycG9sYXRlQmxvY2ssXHJcbiAgICBGbG93R3JhcGhFcUJsb2NrLFxyXG4gICAgRmxvd0dyYXBoTGVzc1RoYW5PckVxdWFsQmxvY2ssXHJcbiAgICBGbG93R3JhcGhHcmVhdGVyVGhhbkJsb2NrLFxyXG4gICAgRmxvd0dyYXBoR3JlYXRlclRoYW5PckVxdWFsQmxvY2ssXHJcbiAgICBGbG93R3JhcGhJc05hbkJsb2NrLFxyXG4gICAgRmxvd0dyYXBoSXNJbmZCbG9jayxcclxuICAgIEZsb3dHcmFwaERlZ1RvUmFkQmxvY2ssXHJcbiAgICBGbG93R3JhcGhSYWRUb0RlZ0Jsb2NrLFxyXG4gICAgRmxvd0dyYXBoU2luQmxvY2ssXHJcbiAgICBGbG93R3JhcGhDb3NCbG9jayxcclxuICAgIEZsb3dHcmFwaFRhbkJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQXNpbkJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQWNvc0Jsb2NrLFxyXG4gICAgRmxvd0dyYXBoQXRhbkJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQXRhbjJCbG9jayxcclxuICAgIEZsb3dHcmFwaFNpbmhCbG9jayxcclxuICAgIEZsb3dHcmFwaENvc2hCbG9jayxcclxuICAgIEZsb3dHcmFwaFRhbmhCbG9jayxcclxuICAgIEZsb3dHcmFwaEFzaW5oQmxvY2ssXHJcbiAgICBGbG93R3JhcGhBY29zaEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQXRhbmhCbG9jayxcclxuICAgIEZsb3dHcmFwaEV4cEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoTG9nMkJsb2NrLFxyXG4gICAgRmxvd0dyYXBoTG9nQmxvY2ssXHJcbiAgICBGbG93R3JhcGhMb2cxMEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoU3FydEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoQ3ViZVJvb3RCbG9jayxcclxuICAgIEZsb3dHcmFwaFBvd0Jsb2NrLFxyXG4gICAgRmxvd0dyYXBoTGVuZ3RoQmxvY2ssXHJcbiAgICBGbG93R3JhcGhOb3JtYWxpemVCbG9jayxcclxuICAgIEZsb3dHcmFwaENyb3NzQmxvY2ssXHJcbiAgICBGbG93R3JhcGhSb3RhdGUyREJsb2NrLFxyXG4gICAgRmxvd0dyYXBoUm90YXRlM0RCbG9jayxcclxuICAgIEZsb3dHcmFwaFRyYW5zcG9zZUJsb2NrLFxyXG4gICAgRmxvd0dyYXBoRGV0ZXJtaW5hbnRCbG9jayxcclxuICAgIEZsb3dHcmFwaEludmVydE1hdHJpeEJsb2NrLFxyXG4gICAgRmxvd0dyYXBoTWF0TXVsQmxvY2ssXHJcbiAgICBGbG93R3JhcGhCaXR3aXNlTm90QmxvY2ssXHJcbiAgICBGbG93R3JhcGhCaXR3aXNlQW5kQmxvY2ssXHJcbiAgICBGbG93R3JhcGhCaXR3aXNlT3JCbG9jayxcclxuICAgIEZsb3dHcmFwaEJpdHdpc2VYb3JCbG9jayxcclxuICAgIEZsb3dHcmFwaEJpdHdpc2VSaWdodFNoaWZ0QmxvY2ssXHJcbiAgICBGbG93R3JhcGhCaXR3aXNlTGVmdFNoaWZ0QmxvY2ssXHJcbiAgICBGbG93R3JhcGhDb3VudExlYWRpbmdaZXJvc0Jsb2NrLFxyXG4gICAgRmxvd0dyYXBoQ291bnRUcmFpbGluZ1plcm9zQmxvY2ssXHJcbiAgICBGbG93R3JhcGhDb3VudE9uZUJpdHNCbG9jayxcclxufSBmcm9tIFwiY29yZS9GbG93R3JhcGgvQmxvY2tzL0RhdGEvTWF0aC9mbG93R3JhcGhNYXRoQmxvY2tzXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaERvTkJsb2NrIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL0Jsb2Nrcy9FeGVjdXRpb24vQ29udHJvbEZsb3cvZmxvd0dyYXBoRG9OQmxvY2tcIjtcclxuaW1wb3J0IHsgRmxvd0dyYXBoR2V0VmFyaWFibGVCbG9jayB9IGZyb20gXCJjb3JlL0Zsb3dHcmFwaC9CbG9ja3MvRGF0YS9mbG93R3JhcGhHZXRWYXJpYWJsZUJsb2NrXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaFNldFZhcmlhYmxlQmxvY2sgfSBmcm9tIFwiY29yZS9GbG93R3JhcGgvQmxvY2tzL0V4ZWN1dGlvbi9mbG93R3JhcGhTZXRWYXJpYWJsZUJsb2NrXCI7XHJcbmltcG9ydCB7IEZsb3dHcmFwaFdoaWxlTG9vcEJsb2NrIH0gZnJvbSBcImNvcmUvRmxvd0dyYXBoL0Jsb2Nrcy9FeGVjdXRpb24vQ29udHJvbEZsb3cvZmxvd0dyYXBoV2hpbGVMb29wQmxvY2tcIjtcclxuXHJcbmV4cG9ydCBjb25zdCBnbHRmVG9GbG93R3JhcGhUeXBlTWFwOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge1xyXG4gICAgXCJsaWZlY3ljbGUvb25TdGFydFwiOiBGbG93R3JhcGhTY2VuZVJlYWR5RXZlbnRCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcImxpZmVjeWNsZS9vblRpY2tcIjogRmxvd0dyYXBoU2NlbmVUaWNrRXZlbnRCbG9jay5DbGFzc05hbWUsXHJcbiAgICBsb2c6IEZsb3dHcmFwaENvbnNvbGVMb2dCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcImZsb3cvZGVsYXlcIjogRmxvd0dyYXBoVGltZXJCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcImN1c3RvbUV2ZW50L3NlbmRcIjogRmxvd0dyYXBoU2VuZEN1c3RvbUV2ZW50QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJjdXN0b21FdmVudC9yZWNlaXZlXCI6IEZsb3dHcmFwaFJlY2VpdmVDdXN0b21FdmVudEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwiZmxvdy9zZXF1ZW5jZVwiOiBGbG93R3JhcGhTZXF1ZW5jZUJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwid29ybGQvZ2V0XCI6IEZsb3dHcmFwaEdldFByb3BlcnR5QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJ3b3JsZC9zZXRcIjogRmxvd0dyYXBoU2V0UHJvcGVydHlCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcImZsb3cvZG9OXCI6IEZsb3dHcmFwaERvTkJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwidmFyaWFibGUvZ2V0XCI6IEZsb3dHcmFwaEdldFZhcmlhYmxlQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJ2YXJpYWJsZS9zZXRcIjogRmxvd0dyYXBoU2V0VmFyaWFibGVCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcImZsb3cvd2hpbGVMb29wXCI6IEZsb3dHcmFwaFdoaWxlTG9vcEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9yYW5kb21cIjogRmxvd0dyYXBoUmFuZG9tQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2VcIjogRmxvd0dyYXBoRUJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9waVwiOiBGbG93R3JhcGhQaUJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9pbmZcIjogRmxvd0dyYXBoSW5mQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL25hblwiOiBGbG93R3JhcGhOYU5CbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvYWJzXCI6IEZsb3dHcmFwaEFic0Jsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9zaWduXCI6IEZsb3dHcmFwaFNpZ25CbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvdHJ1bmNcIjogRmxvd0dyYXBoVHJ1bmNCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvZmxvb3JcIjogRmxvd0dyYXBoRmxvb3JCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvY2VpbFwiOiBGbG93R3JhcGhDZWlsQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2ZyYWN0XCI6IEZsb3dHcmFwaEZyYWN0QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL25lZ1wiOiBGbG93R3JhcGhOZWdCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvYWRkXCI6IEZsb3dHcmFwaEFkZEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9zdWJcIjogRmxvd0dyYXBoU3VidHJhY3RCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvbXVsXCI6IEZsb3dHcmFwaE11bHRpcGx5QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2RpdlwiOiBGbG93R3JhcGhEaXZpZGVCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvcmVtXCI6IEZsb3dHcmFwaFJlbWFpbmRlckJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9taW5cIjogRmxvd0dyYXBoTWluQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL21heFwiOiBGbG93R3JhcGhNYXhCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvY2xhbXBcIjogRmxvd0dyYXBoQ2xhbXBCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvc2F0dXJhdGVcIjogRmxvd0dyYXBoU2F0dXJhdGVCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvbWl4XCI6IEZsb3dHcmFwaEludGVycG9sYXRlQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2VxXCI6IEZsb3dHcmFwaEVxQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2x0XCI6IEZsb3dHcmFwaExlc3NUaGFuQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2xlXCI6IEZsb3dHcmFwaExlc3NUaGFuT3JFcXVhbEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9ndFwiOiBGbG93R3JhcGhHcmVhdGVyVGhhbkJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9nZVwiOiBGbG93R3JhcGhHcmVhdGVyVGhhbk9yRXF1YWxCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvaXNuYW5cIjogRmxvd0dyYXBoSXNOYW5CbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvaXNpbmZcIjogRmxvd0dyYXBoSXNJbmZCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvcmFkXCI6IEZsb3dHcmFwaERlZ1RvUmFkQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2RlZ1wiOiBGbG93R3JhcGhSYWRUb0RlZ0Jsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9zaW5cIjogRmxvd0dyYXBoU2luQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2Nvc1wiOiBGbG93R3JhcGhDb3NCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvdGFuXCI6IEZsb3dHcmFwaFRhbkJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9hc2luXCI6IEZsb3dHcmFwaEFzaW5CbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvYWNvc1wiOiBGbG93R3JhcGhBY29zQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2F0YW5cIjogRmxvd0dyYXBoQXRhbkJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9hdGFuMlwiOiBGbG93R3JhcGhBdGFuMkJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9zaW5oXCI6IEZsb3dHcmFwaFNpbmhCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvY29zaFwiOiBGbG93R3JhcGhDb3NoQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL3RhbmhcIjogRmxvd0dyYXBoVGFuaEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9hc2luaFwiOiBGbG93R3JhcGhBc2luaEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9hY29zaFwiOiBGbG93R3JhcGhBY29zaEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9hdGFuaFwiOiBGbG93R3JhcGhBdGFuaEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9leHBcIjogRmxvd0dyYXBoRXhwQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2xvZ1wiOiBGbG93R3JhcGhMb2dCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvbG9nMlwiOiBGbG93R3JhcGhMb2cyQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2xvZzEwXCI6IEZsb3dHcmFwaExvZzEwQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL3NxcnRcIjogRmxvd0dyYXBoU3FydEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9jYnJ0XCI6IEZsb3dHcmFwaEN1YmVSb290QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL3Bvd1wiOiBGbG93R3JhcGhQb3dCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvbGVuZ3RoXCI6IEZsb3dHcmFwaExlbmd0aEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9ub3JtYWxpemVcIjogRmxvd0dyYXBoTm9ybWFsaXplQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2RvdFwiOiBGbG93R3JhcGhEb3RCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvY3Jvc3NcIjogRmxvd0dyYXBoQ3Jvc3NCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvcm90YXRlMmRcIjogRmxvd0dyYXBoUm90YXRlMkRCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvcm90YXRlM2RcIjogRmxvd0dyYXBoUm90YXRlM0RCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvdHJhbnNwb3NlXCI6IEZsb3dHcmFwaFRyYW5zcG9zZUJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9kZXRlcm1pbmFudFwiOiBGbG93R3JhcGhEZXRlcm1pbmFudEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9pbnZlcnNlXCI6IEZsb3dHcmFwaEludmVydE1hdHJpeEJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9tYXRtdWxcIjogRmxvd0dyYXBoTWF0TXVsQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL25vdFwiOiBGbG93R3JhcGhCaXR3aXNlTm90QmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2FuZFwiOiBGbG93R3JhcGhCaXR3aXNlQW5kQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL29yXCI6IEZsb3dHcmFwaEJpdHdpc2VPckJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC94b3JcIjogRmxvd0dyYXBoQml0d2lzZVhvckJsb2NrLkNsYXNzTmFtZSxcclxuICAgIFwibWF0aC9hc3JcIjogRmxvd0dyYXBoQml0d2lzZVJpZ2h0U2hpZnRCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvbHNsXCI6IEZsb3dHcmFwaEJpdHdpc2VMZWZ0U2hpZnRCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvY2x6XCI6IEZsb3dHcmFwaENvdW50TGVhZGluZ1plcm9zQmxvY2suQ2xhc3NOYW1lLFxyXG4gICAgXCJtYXRoL2N0elwiOiBGbG93R3JhcGhDb3VudFRyYWlsaW5nWmVyb3NCbG9jay5DbGFzc05hbWUsXHJcbiAgICBcIm1hdGgvcG9wY250XCI6IEZsb3dHcmFwaENvdW50T25lQml0c0Jsb2NrLkNsYXNzTmFtZSxcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBnbHRmVHlwZVRvQmFieWxvblR5cGU6IGFueSA9IHtcclxuICAgIGZsb2F0MjogXCJWZWN0b3IyXCIsXHJcbiAgICBmbG9hdDM6IFwiVmVjdG9yM1wiLFxyXG4gICAgZmxvYXQ0OiBcIlZlY3RvcjRcIixcclxuICAgIGZsb2F0NHg0OiBcIk1hdHJpeFwiLFxyXG4gICAgaW50OiBcIkZsb3dHcmFwaEludGVnZXJcIixcclxufTtcclxuIiwiaW1wb3J0IHR5cGUgeyBJbmRpY2VzQXJyYXksIE51bGxhYmxlIH0gZnJvbSBcImNvcmUvdHlwZXNcIjtcclxuaW1wb3J0IHsgRGVmZXJyZWQgfSBmcm9tIFwiY29yZS9NaXNjL2RlZmVycmVkXCI7XHJcbmltcG9ydCB7IFF1YXRlcm5pb24sIFZlY3RvcjMsIE1hdHJpeCwgVG1wVmVjdG9ycyB9IGZyb20gXCJjb3JlL01hdGhzL21hdGgudmVjdG9yXCI7XHJcbmltcG9ydCB7IENvbG9yMyB9IGZyb20gXCJjb3JlL01hdGhzL21hdGguY29sb3JcIjtcclxuaW1wb3J0IHsgVG9vbHMgfSBmcm9tIFwiY29yZS9NaXNjL3Rvb2xzXCI7XHJcbmltcG9ydCB7IENhbWVyYSB9IGZyb20gXCJjb3JlL0NhbWVyYXMvY2FtZXJhXCI7XHJcbmltcG9ydCB7IEZyZWVDYW1lcmEgfSBmcm9tIFwiY29yZS9DYW1lcmFzL2ZyZWVDYW1lcmFcIjtcclxuaW1wb3J0IHR5cGUgeyBBbmltYXRpb24gfSBmcm9tIFwiY29yZS9BbmltYXRpb25zL2FuaW1hdGlvblwiO1xyXG5pbXBvcnQgdHlwZSB7IElBbmltYXRhYmxlIH0gZnJvbSBcImNvcmUvQW5pbWF0aW9ucy9hbmltYXRhYmxlLmludGVyZmFjZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElBbmltYXRpb25LZXkgfSBmcm9tIFwiY29yZS9BbmltYXRpb25zL2FuaW1hdGlvbktleVwiO1xyXG5pbXBvcnQgeyBBbmltYXRpb25LZXlJbnRlcnBvbGF0aW9uIH0gZnJvbSBcImNvcmUvQW5pbWF0aW9ucy9hbmltYXRpb25LZXlcIjtcclxuaW1wb3J0IHR5cGUgeyBBbmltYXRpb25Hcm91cCB9IGZyb20gXCJjb3JlL0FuaW1hdGlvbnMvYW5pbWF0aW9uR3JvdXBcIjtcclxuaW1wb3J0IHsgQm9uZSB9IGZyb20gXCJjb3JlL0JvbmVzL2JvbmVcIjtcclxuaW1wb3J0IHsgU2tlbGV0b24gfSBmcm9tIFwiY29yZS9Cb25lcy9za2VsZXRvblwiO1xyXG5pbXBvcnQgeyBNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9tYXRlcmlhbFwiO1xyXG5pbXBvcnQgeyBQQlJNYXRlcmlhbCB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9QQlIvcGJyTWF0ZXJpYWxcIjtcclxuaW1wb3J0IHR5cGUgeyBCYXNlVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy9iYXNlVGV4dHVyZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElUZXh0dXJlQ3JlYXRpb25PcHRpb25zIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL1RleHR1cmVzL3RleHR1cmVcIjtcclxuaW1wb3J0IHsgVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy90ZXh0dXJlXCI7XHJcbmltcG9ydCB7IFRyYW5zZm9ybU5vZGUgfSBmcm9tIFwiY29yZS9NZXNoZXMvdHJhbnNmb3JtTm9kZVwiO1xyXG5pbXBvcnQgeyBCdWZmZXIsIFZlcnRleEJ1ZmZlciB9IGZyb20gXCJjb3JlL0J1ZmZlcnMvYnVmZmVyXCI7XHJcbmltcG9ydCB7IEdlb21ldHJ5IH0gZnJvbSBcImNvcmUvTWVzaGVzL2dlb21ldHJ5XCI7XHJcbmltcG9ydCB7IEFic3RyYWN0TWVzaCB9IGZyb20gXCJjb3JlL01lc2hlcy9hYnN0cmFjdE1lc2hcIjtcclxuaW1wb3J0IHR5cGUgeyBJbnN0YW5jZWRNZXNoIH0gZnJvbSBcImNvcmUvTWVzaGVzL2luc3RhbmNlZE1lc2hcIjtcclxuaW1wb3J0IHsgTWVzaCB9IGZyb20gXCJjb3JlL01lc2hlcy9tZXNoXCI7XHJcbmltcG9ydCB7IE1vcnBoVGFyZ2V0IH0gZnJvbSBcImNvcmUvTW9ycGgvbW9ycGhUYXJnZXRcIjtcclxuaW1wb3J0IHsgTW9ycGhUYXJnZXRNYW5hZ2VyIH0gZnJvbSBcImNvcmUvTW9ycGgvbW9ycGhUYXJnZXRNYW5hZ2VyXCI7XHJcbmltcG9ydCB0eXBlIHsgSVNjZW5lTG9hZGVyQXN5bmNSZXN1bHQsIElTY2VuZUxvYWRlclByb2dyZXNzRXZlbnQgfSBmcm9tIFwiY29yZS9Mb2FkaW5nL3NjZW5lTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgU2NlbmUgfSBmcm9tIFwiY29yZS9zY2VuZVwiO1xyXG5pbXBvcnQgdHlwZSB7IElQcm9wZXJ0eSB9IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHtcclxuICAgIEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLFxyXG4gICAgQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24sXHJcbiAgICBBY2Nlc3NvclR5cGUsXHJcbiAgICBDYW1lcmFUeXBlLFxyXG4gICAgQWNjZXNzb3JDb21wb25lbnRUeXBlLFxyXG4gICAgTWF0ZXJpYWxBbHBoYU1vZGUsXHJcbiAgICBUZXh0dXJlTWluRmlsdGVyLFxyXG4gICAgVGV4dHVyZVdyYXBNb2RlLFxyXG4gICAgVGV4dHVyZU1hZ0ZpbHRlcixcclxuICAgIE1lc2hQcmltaXRpdmVNb2RlLFxyXG59IGZyb20gXCJiYWJ5bG9uanMtZ2x0ZjJpbnRlcmZhY2VcIjtcclxuaW1wb3J0IHR5cGUge1xyXG4gICAgSUdMVEYsXHJcbiAgICBJU2FtcGxlcixcclxuICAgIElOb2RlLFxyXG4gICAgSVNjZW5lLFxyXG4gICAgSU1lc2gsXHJcbiAgICBJQWNjZXNzb3IsXHJcbiAgICBJU2tpbixcclxuICAgIElDYW1lcmEsXHJcbiAgICBJQW5pbWF0aW9uLFxyXG4gICAgSUJ1ZmZlcixcclxuICAgIElCdWZmZXJWaWV3LFxyXG4gICAgSU1hdGVyaWFsUGJyTWV0YWxsaWNSb3VnaG5lc3MsXHJcbiAgICBJTWF0ZXJpYWwsXHJcbiAgICBJVGV4dHVyZUluZm8sXHJcbiAgICBJVGV4dHVyZSxcclxuICAgIElJbWFnZSxcclxuICAgIElNZXNoUHJpbWl0aXZlLFxyXG4gICAgSUFycmF5SXRlbSxcclxuICAgIF9JU2FtcGxlckRhdGEsXHJcbiAgICBJQW5pbWF0aW9uQ2hhbm5lbCxcclxuICAgIElBbmltYXRpb25TYW1wbGVyLFxyXG4gICAgX0lBbmltYXRpb25TYW1wbGVyRGF0YSxcclxufSBmcm9tIFwiLi9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyRXh0ZW5zaW9uIH0gZnJvbSBcIi4vZ2xURkxvYWRlckV4dGVuc2lvblwiO1xyXG5pbXBvcnQgdHlwZSB7IElHTFRGTG9hZGVyLCBJR0xURkxvYWRlckRhdGEgfSBmcm9tIFwiLi4vZ2xURkZpbGVMb2FkZXJcIjtcclxuaW1wb3J0IHsgR0xURkZpbGVMb2FkZXIsIEdMVEZMb2FkZXJTdGF0ZSwgR0xURkxvYWRlckNvb3JkaW5hdGVTeXN0ZW1Nb2RlLCBHTFRGTG9hZGVyQW5pbWF0aW9uU3RhcnRNb2RlIH0gZnJvbSBcIi4uL2dsVEZGaWxlTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSURhdGFCdWZmZXIgfSBmcm9tIFwiY29yZS9NaXNjL2RhdGFSZWFkZXJcIjtcclxuaW1wb3J0IHsgRGVjb2RlQmFzZTY0VXJsVG9CaW5hcnksIElzQmFzZTY0RGF0YVVybCwgTG9hZEZpbGVFcnJvciB9IGZyb20gXCJjb3JlL01pc2MvZmlsZVRvb2xzXCI7XHJcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gXCJjb3JlL01pc2MvbG9nZ2VyXCI7XHJcbmltcG9ydCB0eXBlIHsgTGlnaHQgfSBmcm9tIFwiY29yZS9MaWdodHMvbGlnaHRcIjtcclxuaW1wb3J0IHsgQm91bmRpbmdJbmZvIH0gZnJvbSBcImNvcmUvQ3VsbGluZy9ib3VuZGluZ0luZm9cIjtcclxuaW1wb3J0IHR5cGUgeyBBc3NldENvbnRhaW5lciB9IGZyb20gXCJjb3JlL2Fzc2V0Q29udGFpbmVyXCI7XHJcbmltcG9ydCB0eXBlIHsgQW5pbWF0aW9uUHJvcGVydHlJbmZvIH0gZnJvbSBcIi4vZ2xURkxvYWRlckFuaW1hdGlvblwiO1xyXG5pbXBvcnQgeyBub2RlQW5pbWF0aW9uRGF0YSB9IGZyb20gXCIuL2dsVEZMb2FkZXJBbmltYXRpb25cIjtcclxuaW1wb3J0IHR5cGUgeyBJT2JqZWN0SW5mbyB9IGZyb20gXCJjb3JlL09iamVjdE1vZGVsL29iamVjdE1vZGVsSW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgeyByZWdpc3RlcmVkR0xURkV4dGVuc2lvbnMsIHJlZ2lzdGVyR0xURkV4dGVuc2lvbiwgdW5yZWdpc3RlckdMVEZFeHRlbnNpb24gfSBmcm9tIFwiLi9nbFRGTG9hZGVyRXh0ZW5zaW9uUmVnaXN0cnlcIjtcclxuaW1wb3J0IHR5cGUgeyBHTFRGRXh0ZW5zaW9uRmFjdG9yeSB9IGZyb20gXCIuL2dsVEZMb2FkZXJFeHRlbnNpb25SZWdpc3RyeVwiO1xyXG5leHBvcnQgeyBHTFRGRmlsZUxvYWRlciB9O1xyXG5cclxuaW50ZXJmYWNlIFR5cGVkQXJyYXlMaWtlIGV4dGVuZHMgQXJyYXlCdWZmZXJWaWV3IHtcclxuICAgIHJlYWRvbmx5IGxlbmd0aDogbnVtYmVyO1xyXG4gICAgW246IG51bWJlcl06IG51bWJlcjtcclxufVxyXG5cclxuaW50ZXJmYWNlIFR5cGVkQXJyYXlDb25zdHJ1Y3RvciB7XHJcbiAgICBuZXcgKGxlbmd0aDogbnVtYmVyKTogVHlwZWRBcnJheUxpa2U7XHJcbiAgICBuZXcgKGJ1ZmZlcjogQXJyYXlCdWZmZXJMaWtlLCBieXRlT2Zmc2V0OiBudW1iZXIsIGxlbmd0aD86IG51bWJlcik6IFR5cGVkQXJyYXlMaWtlO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgSUxvYWRlclByb3BlcnR5IGV4dGVuZHMgSVByb3BlcnR5IHtcclxuICAgIF9hY3RpdmVMb2FkZXJFeHRlbnNpb25GdW5jdGlvbnM6IHtcclxuICAgICAgICBbaWQ6IHN0cmluZ106IGJvb2xlYW47XHJcbiAgICB9O1xyXG59XHJcblxyXG5pbnRlcmZhY2UgSVdpdGhNZXRhZGF0YSB7XHJcbiAgICBtZXRhZGF0YTogYW55O1xyXG4gICAgX2ludGVybmFsTWV0YWRhdGE6IGFueTtcclxufVxyXG5cclxuLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzQ4MjE4MjA5XHJcbmZ1bmN0aW9uIG1lcmdlRGVlcCguLi5vYmplY3RzOiBhbnlbXSk6IGFueSB7XHJcbiAgICBjb25zdCBpc09iamVjdCA9IChvYmo6IGFueSkgPT4gb2JqICYmIHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCI7XHJcblxyXG4gICAgcmV0dXJuIG9iamVjdHMucmVkdWNlKChwcmV2LCBvYmopID0+IHtcclxuICAgICAgICBPYmplY3Qua2V5cyhvYmopLmZvckVhY2goKGtleSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwVmFsID0gcHJldltrZXldO1xyXG4gICAgICAgICAgICBjb25zdCBvVmFsID0gb2JqW2tleV07XHJcblxyXG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwVmFsKSAmJiBBcnJheS5pc0FycmF5KG9WYWwpKSB7XHJcbiAgICAgICAgICAgICAgICBwcmV2W2tleV0gPSBwVmFsLmNvbmNhdCguLi5vVmFsKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc09iamVjdChwVmFsKSAmJiBpc09iamVjdChvVmFsKSkge1xyXG4gICAgICAgICAgICAgICAgcHJldltrZXldID0gbWVyZ2VEZWVwKHBWYWwsIG9WYWwpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcHJldltrZXldID0gb1ZhbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gcHJldjtcclxuICAgIH0sIHt9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEhlbHBlciBjbGFzcyBmb3Igd29ya2luZyB3aXRoIGFycmF5cyB3aGVuIGxvYWRpbmcgdGhlIGdsVEYgYXNzZXRcclxuICovXHJcbmV4cG9ydCBjbGFzcyBBcnJheUl0ZW0ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIGFuIGl0ZW0gZnJvbSB0aGUgZ2l2ZW4gYXJyYXkuXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gYXJyYXkgVGhlIGFycmF5IHRvIGdldCB0aGUgaXRlbSBmcm9tXHJcbiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHRoZSBhcnJheVxyXG4gICAgICogQHJldHVybnMgVGhlIGFycmF5IGl0ZW1cclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBHZXQ8VD4oY29udGV4dDogc3RyaW5nLCBhcnJheTogQXJyYXlMaWtlPFQ+IHwgdW5kZWZpbmVkLCBpbmRleDogbnVtYmVyIHwgdW5kZWZpbmVkKTogVCB7XHJcbiAgICAgICAgaWYgKCFhcnJheSB8fCBpbmRleCA9PSB1bmRlZmluZWQgfHwgIWFycmF5W2luZGV4XSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IEZhaWxlZCB0byBmaW5kIGluZGV4ICgke2luZGV4fSlgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBhcnJheVtpbmRleF07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIGFuIGl0ZW0gZnJvbSB0aGUgZ2l2ZW4gYXJyYXkgb3IgcmV0dXJucyBudWxsIGlmIG5vdCBhdmFpbGFibGUuXHJcbiAgICAgKiBAcGFyYW0gYXJyYXkgVGhlIGFycmF5IHRvIGdldCB0aGUgaXRlbSBmcm9tXHJcbiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHRoZSBhcnJheVxyXG4gICAgICogQHJldHVybnMgVGhlIGFycmF5IGl0ZW0gb3IgbnVsbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIFRyeUdldDxUPihhcnJheTogQXJyYXlMaWtlPFQ+IHwgdW5kZWZpbmVkLCBpbmRleDogbnVtYmVyIHwgdW5kZWZpbmVkKTogTnVsbGFibGU8VD4ge1xyXG4gICAgICAgIGlmICghYXJyYXkgfHwgaW5kZXggPT0gdW5kZWZpbmVkIHx8ICFhcnJheVtpbmRleF0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYXJyYXlbaW5kZXhdO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQXNzaWduIGFuIGBpbmRleGAgZmllbGQgdG8gZWFjaCBpdGVtIG9mIHRoZSBnaXZlbiBhcnJheS5cclxuICAgICAqIEBwYXJhbSBhcnJheSBUaGUgYXJyYXkgb2YgaXRlbXNcclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBBc3NpZ24oYXJyYXk/OiBJQXJyYXlJdGVtW10pOiB2b2lkIHtcclxuICAgICAgICBpZiAoYXJyYXkpIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGFycmF5Lmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICAgICAgICAgICAgYXJyYXlbaW5kZXhdLmluZGV4ID0gaW5kZXg7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGludGVyZmFjZSBJQW5pbWF0aW9uVGFyZ2V0SW5mbyB7XHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICB0YXJnZXQ6IHVua25vd247XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHJvcGVydGllczogQXJyYXk8QW5pbWF0aW9uUHJvcGVydHlJbmZvPjtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRoZSBnbFRGIDIuMCBsb2FkZXJcclxuICovXHJcbmV4cG9ydCBjbGFzcyBHTFRGTG9hZGVyIGltcGxlbWVudHMgSUdMVEZMb2FkZXIge1xyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IF9jb21wbGV0ZVByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dW5rbm93bj4+KCk7XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIF9hc3NldENvbnRhaW5lcjogTnVsbGFibGU8QXNzZXRDb250YWluZXI+ID0gbnVsbDtcclxuXHJcbiAgICAvKiogU3RvcmFnZSAqL1xyXG4gICAgcHVibGljIF9iYWJ5bG9uTGlnaHRzOiBMaWdodFtdID0gW107XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIF9kaXNhYmxlSW5zdGFuY2VkTWVzaCA9IDA7XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIF9hbGxNYXRlcmlhbHNEaXJ0eVJlcXVpcmVkID0gZmFsc2U7XHJcblxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBfcGFyZW50OiBHTFRGRmlsZUxvYWRlcjtcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2V4dGVuc2lvbnMgPSBuZXcgQXJyYXk8SUdMVEZMb2FkZXJFeHRlbnNpb24+KCk7XHJcbiAgICBwcml2YXRlIF9kaXNwb3NlZCA9IGZhbHNlO1xyXG4gICAgcHJpdmF0ZSBfcm9vdFVybDogTnVsbGFibGU8c3RyaW5nPiA9IG51bGw7XHJcbiAgICBwcml2YXRlIF9maWxlTmFtZTogTnVsbGFibGU8c3RyaW5nPiA9IG51bGw7XHJcbiAgICBwcml2YXRlIF91bmlxdWVSb290VXJsOiBOdWxsYWJsZTxzdHJpbmc+ID0gbnVsbDtcclxuICAgIHByaXZhdGUgX2dsdGY6IElHTFRGO1xyXG4gICAgcHJpdmF0ZSBfYmluOiBOdWxsYWJsZTxJRGF0YUJ1ZmZlcj4gPSBudWxsO1xyXG4gICAgcHJpdmF0ZSBfYmFieWxvblNjZW5lOiBTY2VuZTtcclxuICAgIHByaXZhdGUgX3Jvb3RCYWJ5bG9uTWVzaDogTnVsbGFibGU8VHJhbnNmb3JtTm9kZT4gPSBudWxsO1xyXG4gICAgcHJpdmF0ZSBfZGVmYXVsdEJhYnlsb25NYXRlcmlhbERhdGE6IHsgW2RyYXdNb2RlOiBudW1iZXJdOiBNYXRlcmlhbCB9ID0ge307XHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9wb3N0U2NlbmVMb2FkQWN0aW9ucyA9IG5ldyBBcnJheTwoKSA9PiB2b2lkPigpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGRlZmF1bHQgZ2xURiBzYW1wbGVyLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERlZmF1bHRTYW1wbGVyOiBJU2FtcGxlciA9IHsgaW5kZXg6IC0xIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWdpc3RlcnMgYSBsb2FkZXIgZXh0ZW5zaW9uLlxyXG4gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGxvYWRlciBleHRlbnNpb24uXHJcbiAgICAgKiBAcGFyYW0gZmFjdG9yeSBUaGUgZmFjdG9yeSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgdGhlIGxvYWRlciBleHRlbnNpb24uXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBQbGVhc2UgdXNlIHJlZ2lzdGVyR0xURkV4dGVuc2lvbiBpbnN0ZWFkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIFJlZ2lzdGVyRXh0ZW5zaW9uKG5hbWU6IHN0cmluZywgZmFjdG9yeTogR0xURkV4dGVuc2lvbkZhY3RvcnkpOiB2b2lkIHtcclxuICAgICAgICByZWdpc3RlckdMVEZFeHRlbnNpb24obmFtZSwgZmFsc2UsIGZhY3RvcnkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVW5yZWdpc3RlcnMgYSBsb2FkZXIgZXh0ZW5zaW9uLlxyXG4gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGxvYWRlciBleHRlbnNpb24uXHJcbiAgICAgKiBAcmV0dXJucyBBIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBleHRlbnNpb24gaGFzIGJlZW4gdW5yZWdpc3RlcmVkXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBQbGVhc2UgdXNlIHVucmVnaXN0ZXJHTFRGRXh0ZW5zaW9uIGluc3RlYWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgVW5yZWdpc3RlckV4dGVuc2lvbihuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdW5yZWdpc3RlckdMVEZFeHRlbnNpb24obmFtZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgZ2xURiBKU09OLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IGdsdGYoKTogSUdMVEYge1xyXG4gICAgICAgIGlmICghdGhpcy5fZ2x0Zikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJnbFRGIEpTT04gaXMgbm90IGF2YWlsYWJsZVwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9nbHRmO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIEJJTiBjaHVuayBvZiBhIGJpbmFyeSBnbFRGLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IGJpbigpOiBOdWxsYWJsZTxJRGF0YUJ1ZmZlcj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9iaW47XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgcGFyZW50IGZpbGUgbG9hZGVyLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IHBhcmVudCgpOiBHTFRGRmlsZUxvYWRlciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmVudDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBCYWJ5bG9uIHNjZW5lIHdoZW4gbG9hZGluZyB0aGUgYXNzZXQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXQgYmFieWxvblNjZW5lKCk6IFNjZW5lIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2JhYnlsb25TY2VuZSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTY2VuZSBpcyBub3QgYXZhaWxhYmxlXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JhYnlsb25TY2VuZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSByb290IEJhYnlsb24gbm9kZSB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IHJvb3RCYWJ5bG9uTWVzaCgpOiBOdWxsYWJsZTxUcmFuc2Zvcm1Ob2RlPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvb3RCYWJ5bG9uTWVzaDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSByb290IHVybCB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IHJvb3RVcmwoKTogTnVsbGFibGU8c3RyaW5nPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvb3RVcmw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IocGFyZW50OiBHTFRGRmlsZUxvYWRlcikge1xyXG4gICAgICAgIHRoaXMuX3BhcmVudCA9IHBhcmVudDtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpOiB2b2lkIHtcclxuICAgICAgICBpZiAodGhpcy5fZGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fZGlzcG9zZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICB0aGlzLl9jb21wbGV0ZVByb21pc2VzLmxlbmd0aCA9IDA7XHJcblxyXG4gICAgICAgIHRoaXMuX2V4dGVuc2lvbnMuZm9yRWFjaCgoZXh0ZW5zaW9uKSA9PiBleHRlbnNpb24uZGlzcG9zZSAmJiBleHRlbnNpb24uZGlzcG9zZSgpKTtcclxuICAgICAgICB0aGlzLl9leHRlbnNpb25zLmxlbmd0aCA9IDA7XHJcblxyXG4gICAgICAgICh0aGlzLl9nbHRmIGFzIE51bGxhYmxlPElHTFRGPikgPSBudWxsOyAvLyBUT0RPXHJcbiAgICAgICAgdGhpcy5fYmluID0gbnVsbDtcclxuICAgICAgICAodGhpcy5fYmFieWxvblNjZW5lIGFzIE51bGxhYmxlPFNjZW5lPikgPSBudWxsOyAvLyBUT0RPXHJcbiAgICAgICAgdGhpcy5fcm9vdEJhYnlsb25NZXNoID0gbnVsbDtcclxuICAgICAgICB0aGlzLl9kZWZhdWx0QmFieWxvbk1hdGVyaWFsRGF0YSA9IHt9O1xyXG4gICAgICAgIHRoaXMuX3Bvc3RTY2VuZUxvYWRBY3Rpb25zLmxlbmd0aCA9IDA7XHJcblxyXG4gICAgICAgIHRoaXMuX3BhcmVudC5kaXNwb3NlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGltcG9ydE1lc2hBc3luYyhcclxuICAgICAgICBtZXNoZXNOYW1lczogc3RyaW5nIHwgcmVhZG9ubHkgc3RyaW5nW10gfCBudWxsIHwgdW5kZWZpbmVkLFxyXG4gICAgICAgIHNjZW5lOiBTY2VuZSxcclxuICAgICAgICBjb250YWluZXI6IE51bGxhYmxlPEFzc2V0Q29udGFpbmVyPixcclxuICAgICAgICBkYXRhOiBJR0xURkxvYWRlckRhdGEsXHJcbiAgICAgICAgcm9vdFVybDogc3RyaW5nLFxyXG4gICAgICAgIG9uUHJvZ3Jlc3M/OiAoZXZlbnQ6IElTY2VuZUxvYWRlclByb2dyZXNzRXZlbnQpID0+IHZvaWQsXHJcbiAgICAgICAgZmlsZU5hbWUgPSBcIlwiXHJcbiAgICApOiBQcm9taXNlPElTY2VuZUxvYWRlckFzeW5jUmVzdWx0PiB7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUgPSBzY2VuZTtcclxuICAgICAgICAgICAgdGhpcy5fYXNzZXRDb250YWluZXIgPSBjb250YWluZXI7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWREYXRhKGRhdGEpO1xyXG5cclxuICAgICAgICAgICAgbGV0IG5vZGVzOiBOdWxsYWJsZTxBcnJheTxudW1iZXI+PiA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICBpZiAobWVzaGVzTmFtZXMpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5vZGVNYXA6IHsgW25hbWU6IHN0cmluZ106IG51bWJlciB9ID0ge307XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fZ2x0Zi5ub2Rlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9nbHRmLm5vZGVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVNYXBbbm9kZS5uYW1lXSA9IG5vZGUuaW5kZXg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgbmFtZXMgPSBtZXNoZXNOYW1lcyBpbnN0YW5jZW9mIEFycmF5ID8gbWVzaGVzTmFtZXMgOiBbbWVzaGVzTmFtZXNdO1xyXG4gICAgICAgICAgICAgICAgbm9kZXMgPSBuYW1lcy5tYXAoKG5hbWUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBub2RlID0gbm9kZU1hcFtuYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGZpbmQgbm9kZSAnJHtuYW1lfSdgKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkQXN5bmMocm9vdFVybCwgZmlsZU5hbWUsIG5vZGVzLCAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIG1lc2hlczogdGhpcy5fZ2V0TWVzaGVzKCksXHJcbiAgICAgICAgICAgICAgICAgICAgcGFydGljbGVTeXN0ZW1zOiBbXSxcclxuICAgICAgICAgICAgICAgICAgICBza2VsZXRvbnM6IHRoaXMuX2dldFNrZWxldG9ucygpLFxyXG4gICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbkdyb3VwczogdGhpcy5fZ2V0QW5pbWF0aW9uR3JvdXBzKCksXHJcbiAgICAgICAgICAgICAgICAgICAgbGlnaHRzOiB0aGlzLl9iYWJ5bG9uTGlnaHRzLFxyXG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybU5vZGVzOiB0aGlzLl9nZXRUcmFuc2Zvcm1Ob2RlcygpLFxyXG4gICAgICAgICAgICAgICAgICAgIGdlb21ldHJpZXM6IHRoaXMuX2dldEdlb21ldHJpZXMoKSxcclxuICAgICAgICAgICAgICAgICAgICBzcHJpdGVNYW5hZ2VyczogW10sXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZEFzeW5jKHNjZW5lOiBTY2VuZSwgZGF0YTogSUdMVEZMb2FkZXJEYXRhLCByb290VXJsOiBzdHJpbmcsIG9uUHJvZ3Jlc3M/OiAoZXZlbnQ6IElTY2VuZUxvYWRlclByb2dyZXNzRXZlbnQpID0+IHZvaWQsIGZpbGVOYW1lID0gXCJcIik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lID0gc2NlbmU7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWREYXRhKGRhdGEpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZEFzeW5jKHJvb3RVcmwsIGZpbGVOYW1lLCBudWxsLCAoKSA9PiB1bmRlZmluZWQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRBc3luYzxUPihyb290VXJsOiBzdHJpbmcsIGZpbGVOYW1lOiBzdHJpbmcsIG5vZGVzOiBOdWxsYWJsZTxBcnJheTxudW1iZXI+PiwgcmVzdWx0RnVuYzogKCkgPT4gVCk6IFByb21pc2U8VD4ge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxyXG4gICAgICAgICAgICAudGhlbihhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9yb290VXJsID0gcm9vdFVybDtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3VuaXF1ZVJvb3RVcmwgPSAhcm9vdFVybC5zdGFydHNXaXRoKFwiZmlsZTpcIikgJiYgZmlsZU5hbWUgPyByb290VXJsIDogYCR7cm9vdFVybH0ke0RhdGUubm93KCl9L2A7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9maWxlTmFtZSA9IGZpbGVOYW1lO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYWxsTWF0ZXJpYWxzRGlydHlSZXF1aXJlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuX2xvYWRFeHRlbnNpb25zQXN5bmMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBsb2FkaW5nVG9SZWFkeUNvdW50ZXJOYW1lID0gYCR7R0xURkxvYWRlclN0YXRlW0dMVEZMb2FkZXJTdGF0ZS5MT0FESU5HXX0gPT4gJHtHTFRGTG9hZGVyU3RhdGVbR0xURkxvYWRlclN0YXRlLlJFQURZXX1gO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbG9hZGluZ1RvQ29tcGxldGVDb3VudGVyTmFtZSA9IGAke0dMVEZMb2FkZXJTdGF0ZVtHTFRGTG9hZGVyU3RhdGUuTE9BRElOR119ID0+ICR7R0xURkxvYWRlclN0YXRlW0dMVEZMb2FkZXJTdGF0ZS5DT01QTEVURV19YDtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJlbnQuX3N0YXJ0UGVyZm9ybWFuY2VDb3VudGVyKGxvYWRpbmdUb1JlYWR5Q291bnRlck5hbWUpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fcGFyZW50Ll9zdGFydFBlcmZvcm1hbmNlQ291bnRlcihsb2FkaW5nVG9Db21wbGV0ZUNvdW50ZXJOYW1lKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJlbnQuX3NldFN0YXRlKEdMVEZMb2FkZXJTdGF0ZS5MT0FESU5HKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2V4dGVuc2lvbnNPbkxvYWRpbmcoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHVua25vd24+PigpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIEJsb2NrIHRoZSBtYXJraW5nIG9mIG1hdGVyaWFscyBkaXJ0eSB1bnRpbCB0aGUgc2NlbmUgaXMgbG9hZGVkLlxyXG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkQmxvY2tNYXRlcmlhbERpcnR5TWVjaGFuaXNtID0gdGhpcy5fYmFieWxvblNjZW5lLmJsb2NrTWF0ZXJpYWxEaXJ0eU1lY2hhbmlzbTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5ibG9ja01hdGVyaWFsRGlydHlNZWNoYW5pc20gPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5wYXJlbnQubG9hZE9ubHlNYXRlcmlhbHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobm9kZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLmxvYWRTY2VuZUFzeW5jKFwiL25vZGVzXCIsIHsgbm9kZXM6IG5vZGVzLCBpbmRleDogLTEgfSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fZ2x0Zi5zY2VuZSAhPSB1bmRlZmluZWQgfHwgKHRoaXMuX2dsdGYuc2NlbmVzICYmIHRoaXMuX2dsdGYuc2NlbmVzWzBdKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzY2VuZSA9IEFycmF5SXRlbS5HZXQoYC9zY2VuZWAsIHRoaXMuX2dsdGYuc2NlbmVzLCB0aGlzLl9nbHRmLnNjZW5lIHx8IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMubG9hZFNjZW5lQXN5bmMoYC9zY2VuZXMvJHtzY2VuZS5pbmRleH1gLCBzY2VuZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMucGFyZW50LnNraXBNYXRlcmlhbHMgJiYgdGhpcy5wYXJlbnQubG9hZEFsbE1hdGVyaWFscyAmJiB0aGlzLl9nbHRmLm1hdGVyaWFscykge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IG0gPSAwOyBtIDwgdGhpcy5fZ2x0Zi5tYXRlcmlhbHMubGVuZ3RoOyArK20pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSB0aGlzLl9nbHRmLm1hdGVyaWFsc1ttXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29udGV4dCA9IFwiL21hdGVyaWFscy9cIiArIG07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJhYnlsb25EcmF3TW9kZSA9IE1hdGVyaWFsLlRyaWFuZ2xlRmlsbE1vZGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRNYXRlcmlhbEFzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBudWxsLCBiYWJ5bG9uRHJhd01vZGUsICgpID0+IHt9KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIFJlc3RvcmUgdGhlIGJsb2NraW5nIG9mIG1hdGVyaWFsIGRpcnR5LlxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2FsbE1hdGVyaWFsc0RpcnR5UmVxdWlyZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGNhbiBoYXBwZW4gaWYgd2UgYWRkIGEgbGlnaHQgZm9yIGluc3RhbmNlIGFzIGl0IHdpbGwgaW1wYWN0IHRoZSB3aG9sZSBzY2VuZS5cclxuICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGF1dG9tYXRpY2FsbHkgcmVzZXRzIGV2ZXJ5dGhpbmcgaWYgbmVlZGVkLlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5ibG9ja01hdGVyaWFsRGlydHlNZWNoYW5pc20gPSBvbGRCbG9ja01hdGVyaWFsRGlydHlNZWNoYW5pc207XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIEJ5IGRlZmF1bHQgYSBuZXdseSBjcmVhdGVkIG1hdGVyaWFsIGlzIGRpcnR5IHNvIHRoZXJlIGlzIG5vIG5lZWQgdG8gZmxhZyB0aGUgZnVsbCBzY2VuZSBhcyBkaXJ0eS5cclxuICAgICAgICAgICAgICAgICAgICAvLyBGb3IgcGVyZiByZWFzb25zLCB3ZSB0aGVuIGJ5cGFzcyBibG9ja01hdGVyaWFsRGlydHlNZWNoYW5pc20gYXMgdGhpcyB3b3VsZCBcImRpcnR5XCIgdGhlIGVudGlyZSBzY2VuZS5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2ZvcmNlQmxvY2tNYXRlcmlhbERpcnR5TWVjaGFuaXNtKG9sZEJsb2NrTWF0ZXJpYWxEaXJ0eU1lY2hhbmlzbSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3BhcmVudC5jb21waWxlTWF0ZXJpYWxzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9jb21waWxlTWF0ZXJpYWxzQXN5bmMoKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3BhcmVudC5jb21waWxlU2hhZG93R2VuZXJhdG9ycykge1xyXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fY29tcGlsZVNoYWRvd0dlbmVyYXRvcnNBc3luYygpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHRQcm9taXNlID0gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9yb290QmFieWxvbk1lc2ggJiYgdGhpcy5fcm9vdEJhYnlsb25NZXNoICE9PSB0aGlzLl9wYXJlbnQuY3VzdG9tUm9vdE5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcm9vdEJhYnlsb25NZXNoLnNldEVuYWJsZWQodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9leHRlbnNpb25zT25SZWFkeSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcmVudC5fc2V0U3RhdGUoR0xURkxvYWRlclN0YXRlLlJFQURZKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnRBbmltYXRpb25zKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRGdW5jKCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0UHJvbWlzZS50aGVuKChyZXN1bHQpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJlbnQuX2VuZFBlcmZvcm1hbmNlQ291bnRlcihsb2FkaW5nVG9SZWFkeUNvdW50ZXJOYW1lKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgVG9vbHMuU2V0SW1tZWRpYXRlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9kaXNwb3NlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvbWlzZS5hbGwodGhpcy5fY29tcGxldGVQcm9taXNlcykudGhlbihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcmVudC5fZW5kUGVyZm9ybWFuY2VDb3VudGVyKGxvYWRpbmdUb0NvbXBsZXRlQ291bnRlck5hbWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFyZW50Ll9zZXRTdGF0ZShHTFRGTG9hZGVyU3RhdGUuQ09NUExFVEUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFyZW50Lm9uQ29tcGxldGVPYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyh1bmRlZmluZWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJlbnQub25Db21wbGV0ZU9ic2VydmFibGUuY2xlYXIoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcmVudC5vbkVycm9yT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJlbnQub25FcnJvck9ic2VydmFibGUuY2xlYXIoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2Rpc3Bvc2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFyZW50Lm9uRXJyb3JPYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyhlcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFyZW50Lm9uRXJyb3JPYnNlcnZhYmxlLmNsZWFyKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkRGF0YShkYXRhOiBJR0xURkxvYWRlckRhdGEpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9nbHRmID0gZGF0YS5qc29uIGFzIElHTFRGO1xyXG4gICAgICAgIHRoaXMuX3NldHVwRGF0YSgpO1xyXG5cclxuICAgICAgICBpZiAoZGF0YS5iaW4pIHtcclxuICAgICAgICAgICAgY29uc3QgYnVmZmVycyA9IHRoaXMuX2dsdGYuYnVmZmVycztcclxuICAgICAgICAgICAgaWYgKGJ1ZmZlcnMgJiYgYnVmZmVyc1swXSAmJiAhYnVmZmVyc1swXS51cmkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJpbmFyeUJ1ZmZlciA9IGJ1ZmZlcnNbMF07XHJcbiAgICAgICAgICAgICAgICBpZiAoYmluYXJ5QnVmZmVyLmJ5dGVMZW5ndGggPCBkYXRhLmJpbi5ieXRlTGVuZ3RoIC0gMyB8fCBiaW5hcnlCdWZmZXIuYnl0ZUxlbmd0aCA+IGRhdGEuYmluLmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuV2FybihgQmluYXJ5IGJ1ZmZlciBsZW5ndGggKCR7YmluYXJ5QnVmZmVyLmJ5dGVMZW5ndGh9KSBmcm9tIEpTT04gZG9lcyBub3QgbWF0Y2ggY2h1bmsgbGVuZ3RoICgke2RhdGEuYmluLmJ5dGVMZW5ndGh9KWApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX2JpbiA9IGRhdGEuYmluO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgTG9nZ2VyLldhcm4oXCJVbmV4cGVjdGVkIEJJTiBjaHVua1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9zZXR1cERhdGEoKTogdm9pZCB7XHJcbiAgICAgICAgQXJyYXlJdGVtLkFzc2lnbih0aGlzLl9nbHRmLmFjY2Vzc29ycyk7XHJcbiAgICAgICAgQXJyYXlJdGVtLkFzc2lnbih0aGlzLl9nbHRmLmFuaW1hdGlvbnMpO1xyXG4gICAgICAgIEFycmF5SXRlbS5Bc3NpZ24odGhpcy5fZ2x0Zi5idWZmZXJzKTtcclxuICAgICAgICBBcnJheUl0ZW0uQXNzaWduKHRoaXMuX2dsdGYuYnVmZmVyVmlld3MpO1xyXG4gICAgICAgIEFycmF5SXRlbS5Bc3NpZ24odGhpcy5fZ2x0Zi5jYW1lcmFzKTtcclxuICAgICAgICBBcnJheUl0ZW0uQXNzaWduKHRoaXMuX2dsdGYuaW1hZ2VzKTtcclxuICAgICAgICBBcnJheUl0ZW0uQXNzaWduKHRoaXMuX2dsdGYubWF0ZXJpYWxzKTtcclxuICAgICAgICBBcnJheUl0ZW0uQXNzaWduKHRoaXMuX2dsdGYubWVzaGVzKTtcclxuICAgICAgICBBcnJheUl0ZW0uQXNzaWduKHRoaXMuX2dsdGYubm9kZXMpO1xyXG4gICAgICAgIEFycmF5SXRlbS5Bc3NpZ24odGhpcy5fZ2x0Zi5zYW1wbGVycyk7XHJcbiAgICAgICAgQXJyYXlJdGVtLkFzc2lnbih0aGlzLl9nbHRmLnNjZW5lcyk7XHJcbiAgICAgICAgQXJyYXlJdGVtLkFzc2lnbih0aGlzLl9nbHRmLnNraW5zKTtcclxuICAgICAgICBBcnJheUl0ZW0uQXNzaWduKHRoaXMuX2dsdGYudGV4dHVyZXMpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5fZ2x0Zi5ub2Rlcykge1xyXG4gICAgICAgICAgICBjb25zdCBub2RlUGFyZW50czogeyBbaW5kZXg6IG51bWJlcl06IG51bWJlciB9ID0ge307XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9nbHRmLm5vZGVzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5jaGlsZHJlbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgaW5kZXggb2Ygbm9kZS5jaGlsZHJlbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlUGFyZW50c1tpbmRleF0gPSBub2RlLmluZGV4O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3Qgcm9vdE5vZGUgPSB0aGlzLl9jcmVhdGVSb290Tm9kZSgpO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5fZ2x0Zi5ub2Rlcykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcGFyZW50SW5kZXggPSBub2RlUGFyZW50c1tub2RlLmluZGV4XTtcclxuICAgICAgICAgICAgICAgIG5vZGUucGFyZW50ID0gcGFyZW50SW5kZXggPT09IHVuZGVmaW5lZCA/IHJvb3ROb2RlIDogdGhpcy5fZ2x0Zi5ub2Rlc1twYXJlbnRJbmRleF07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhc3luYyBfbG9hZEV4dGVuc2lvbnNBc3luYygpIHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25Qcm9taXNlczogUHJvbWlzZTxJR0xURkxvYWRlckV4dGVuc2lvbj5bXSA9IFtdO1xyXG5cclxuICAgICAgICByZWdpc3RlcmVkR0xURkV4dGVuc2lvbnMuZm9yRWFjaCgocmVnaXN0ZXJlZEV4dGVuc2lvbiwgbmFtZSkgPT4ge1xyXG4gICAgICAgICAgICAvLyBEb24ndCBsb2FkIGV4cGxpY2l0bHkgZGlzYWJsZWQgZXh0ZW5zaW9ucy5cclxuICAgICAgICAgICAgaWYgKHRoaXMucGFyZW50LmV4dGVuc2lvbk9wdGlvbnNbbmFtZV0/LmVuYWJsZWQgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBCdXQgd2FybiBpZiB0aGUgZGlzYWJsZWQgZXh0ZW5zaW9uIGlzIHVzZWQgYnkgdGhlIG1vZGVsLlxyXG4gICAgICAgICAgICAgICAgaWYgKHJlZ2lzdGVyZWRFeHRlbnNpb24uaXNHTFRGRXh0ZW5zaW9uICYmIHRoaXMuaXNFeHRlbnNpb25Vc2VkKG5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLldhcm4oYEV4dGVuc2lvbiAke25hbWV9IGlzIHVzZWQgYnV0IGhhcyBiZWVuIGV4cGxpY2l0bHkgZGlzYWJsZWQuYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gTG9hZCBsb2FkZXIgZXh0ZW5zaW9ucyB0aGF0IGFyZSBub3QgYSBnbFRGIGV4dGVuc2lvbiwgYXMgd2VsbCBhcyBleHRlbnNpb25zIHRoYXQgYXJlIGdsVEYgZXh0ZW5zaW9ucyBhbmQgYXJlIHVzZWQgYnkgdGhlIG1vZGVsLlxyXG4gICAgICAgICAgICBlbHNlIGlmICghcmVnaXN0ZXJlZEV4dGVuc2lvbi5pc0dMVEZFeHRlbnNpb24gfHwgdGhpcy5pc0V4dGVuc2lvblVzZWQobmFtZSkpIHtcclxuICAgICAgICAgICAgICAgIGV4dGVuc2lvblByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgKGFzeW5jICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uID0gYXdhaXQgcmVnaXN0ZXJlZEV4dGVuc2lvbi5mYWN0b3J5KHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLm5hbWUgIT09IG5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5XYXJuKGBUaGUgbmFtZSBvZiB0aGUgZ2xURiBsb2FkZXIgZXh0ZW5zaW9uIGluc3RhbmNlIGRvZXMgbm90IG1hdGNoIHRoZSByZWdpc3RlcmVkIG5hbWU6ICR7ZXh0ZW5zaW9uLm5hbWV9ICE9PSAke25hbWV9YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcmVudC5vbkV4dGVuc2lvbkxvYWRlZE9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKGV4dGVuc2lvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBleHRlbnNpb247XHJcbiAgICAgICAgICAgICAgICAgICAgfSkoKVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLl9leHRlbnNpb25zLnB1c2goLi4uKGF3YWl0IFByb21pc2UuYWxsKGV4dGVuc2lvblByb21pc2VzKSkpO1xyXG5cclxuICAgICAgICB0aGlzLl9leHRlbnNpb25zLnNvcnQoKGEsIGIpID0+IChhLm9yZGVyIHx8IE51bWJlci5NQVhfVkFMVUUpIC0gKGIub3JkZXIgfHwgTnVtYmVyLk1BWF9WQUxVRSkpO1xyXG4gICAgICAgIHRoaXMuX3BhcmVudC5vbkV4dGVuc2lvbkxvYWRlZE9ic2VydmFibGUuY2xlYXIoKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX2dsdGYuZXh0ZW5zaW9uc1JlcXVpcmVkKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLl9nbHRmLmV4dGVuc2lvbnNSZXF1aXJlZCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYXZhaWxhYmxlID0gdGhpcy5fZXh0ZW5zaW9ucy5zb21lKChleHRlbnNpb24pID0+IGV4dGVuc2lvbi5uYW1lID09PSBuYW1lICYmIGV4dGVuc2lvbi5lbmFibGVkKTtcclxuICAgICAgICAgICAgICAgIGlmICghYXZhaWxhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucGFyZW50LmV4dGVuc2lvbk9wdGlvbnNbbmFtZV0/LmVuYWJsZWQgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUmVxdWlyZWQgZXh0ZW5zaW9uICR7bmFtZX0gaXMgZGlzYWJsZWRgKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXF1aXJlZCBleHRlbnNpb24gJHtuYW1lfSBpcyBub3QgYXZhaWxhYmxlYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfY3JlYXRlUm9vdE5vZGUoKTogSU5vZGUge1xyXG4gICAgICAgIGlmICh0aGlzLl9wYXJlbnQuY3VzdG9tUm9vdE5vZGUgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICB0aGlzLl9yb290QmFieWxvbk1lc2ggPSB0aGlzLl9wYXJlbnQuY3VzdG9tUm9vdE5vZGU7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbiAgICAgICAgICAgICAgICBfYmFieWxvblRyYW5zZm9ybU5vZGU6IHRoaXMuX3Jvb3RCYWJ5bG9uTWVzaCA9PT0gbnVsbCA/IHVuZGVmaW5lZCA6IHRoaXMuX3Jvb3RCYWJ5bG9uTWVzaCxcclxuICAgICAgICAgICAgICAgIGluZGV4OiAtMSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSAhIXRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgIGNvbnN0IHJvb3RNZXNoID0gbmV3IE1lc2goXCJfX3Jvb3RfX1wiLCB0aGlzLl9iYWJ5bG9uU2NlbmUpO1xyXG4gICAgICAgIHRoaXMuX3Jvb3RCYWJ5bG9uTWVzaCA9IHJvb3RNZXNoO1xyXG4gICAgICAgIHRoaXMuX3Jvb3RCYWJ5bG9uTWVzaC5fcGFyZW50Q29udGFpbmVyID0gdGhpcy5fYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSBmYWxzZTtcclxuICAgICAgICB0aGlzLl9yb290QmFieWxvbk1lc2guc2V0RW5hYmxlZChmYWxzZSk7XHJcblxyXG4gICAgICAgIGNvbnN0IHJvb3ROb2RlOiBJTm9kZSA9IHtcclxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG4gICAgICAgICAgICBfYmFieWxvblRyYW5zZm9ybU5vZGU6IHRoaXMuX3Jvb3RCYWJ5bG9uTWVzaCxcclxuICAgICAgICAgICAgaW5kZXg6IC0xLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHN3aXRjaCAodGhpcy5fcGFyZW50LmNvb3JkaW5hdGVTeXN0ZW1Nb2RlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgR0xURkxvYWRlckNvb3JkaW5hdGVTeXN0ZW1Nb2RlLkFVVE86IHtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5fYmFieWxvblNjZW5lLnVzZVJpZ2h0SGFuZGVkU3lzdGVtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcm9vdE5vZGUucm90YXRpb24gPSBbMCwgMSwgMCwgMF07XHJcbiAgICAgICAgICAgICAgICAgICAgcm9vdE5vZGUuc2NhbGUgPSBbMSwgMSwgLTFdO1xyXG4gICAgICAgICAgICAgICAgICAgIEdMVEZMb2FkZXIuX0xvYWRUcmFuc2Zvcm0ocm9vdE5vZGUsIHRoaXMuX3Jvb3RCYWJ5bG9uTWVzaCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIEdMVEZMb2FkZXJDb29yZGluYXRlU3lzdGVtTW9kZS5GT1JDRV9SSUdIVF9IQU5ERUQ6IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS51c2VSaWdodEhhbmRlZFN5c3RlbSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBkZWZhdWx0OiB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgY29vcmRpbmF0ZSBzeXN0ZW0gbW9kZSAoJHt0aGlzLl9wYXJlbnQuY29vcmRpbmF0ZVN5c3RlbU1vZGV9KWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9wYXJlbnQub25NZXNoTG9hZGVkT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMocm9vdE1lc2gpO1xyXG4gICAgICAgIHJldHVybiByb290Tm9kZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIExvYWRzIGEgZ2xURiBzY2VuZS5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBzY2VuZSBUaGUgZ2xURiBzY2VuZSBwcm9wZXJ0eVxyXG4gICAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgbG9hZCBpcyBjb21wbGV0ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZFNjZW5lQXN5bmMoY29udGV4dDogc3RyaW5nLCBzY2VuZTogSVNjZW5lKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uUHJvbWlzZSA9IHRoaXMuX2V4dGVuc2lvbnNMb2FkU2NlbmVBc3luYyhjb250ZXh0LCBzY2VuZSk7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvblByb21pc2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvblByb21pc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHVua25vd24+PigpO1xyXG5cclxuICAgICAgICB0aGlzLmxvZ09wZW4oYCR7Y29udGV4dH0gJHtzY2VuZS5uYW1lIHx8IFwiXCJ9YCk7XHJcblxyXG4gICAgICAgIGlmIChzY2VuZS5ub2Rlcykge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGluZGV4IG9mIHNjZW5lLm5vZGVzKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBub2RlID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9ub2Rlcy8ke2luZGV4fWAsIHRoaXMuX2dsdGYubm9kZXMsIGluZGV4KTtcclxuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkTm9kZUFzeW5jKGAvbm9kZXMvJHtub2RlLmluZGV4fWAsIG5vZGUsIChiYWJ5bG9uTWVzaCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWVzaC5wYXJlbnQgPSB0aGlzLl9yb290QmFieWxvbk1lc2g7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgYWN0aW9uIG9mIHRoaXMuX3Bvc3RTY2VuZUxvYWRBY3Rpb25zKSB7XHJcbiAgICAgICAgICAgIGFjdGlvbigpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkQW5pbWF0aW9uc0FzeW5jKCkpO1xyXG5cclxuICAgICAgICB0aGlzLmxvZ0Nsb3NlKCk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZm9yRWFjaFByaW1pdGl2ZShub2RlOiBJTm9kZSwgY2FsbGJhY2s6IChiYWJ5bG9uTWVzaDogQWJzdHJhY3RNZXNoKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKG5vZGUuX3ByaW1pdGl2ZUJhYnlsb25NZXNoZXMpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBiYWJ5bG9uTWVzaCBvZiBub2RlLl9wcmltaXRpdmVCYWJ5bG9uTWVzaGVzKSB7XHJcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhiYWJ5bG9uTWVzaCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZ2V0R2VvbWV0cmllcygpOiBHZW9tZXRyeVtdIHtcclxuICAgICAgICBjb25zdCBnZW9tZXRyaWVzOiBHZW9tZXRyeVtdID0gW107XHJcblxyXG4gICAgICAgIGNvbnN0IG5vZGVzID0gdGhpcy5fZ2x0Zi5ub2RlcztcclxuICAgICAgICBpZiAobm9kZXMpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBub2RlIG9mIG5vZGVzKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9mb3JFYWNoUHJpbWl0aXZlKG5vZGUsIChiYWJ5bG9uTWVzaCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGdlb21ldHJ5ID0gKGJhYnlsb25NZXNoIGFzIE1lc2gpLmdlb21ldHJ5O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChnZW9tZXRyeSAmJiBnZW9tZXRyaWVzLmluZGV4T2YoZ2VvbWV0cnkpID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBnZW9tZXRyaWVzLnB1c2goZ2VvbWV0cnkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZ2VvbWV0cmllcztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9nZXRNZXNoZXMoKTogQWJzdHJhY3RNZXNoW10ge1xyXG4gICAgICAgIGNvbnN0IG1lc2hlczogQWJzdHJhY3RNZXNoW10gPSBbXTtcclxuXHJcbiAgICAgICAgLy8gUm9vdCBtZXNoIGlzIGFsd2F5cyBmaXJzdCwgaWYgYXZhaWxhYmxlLlxyXG4gICAgICAgIGlmICh0aGlzLl9yb290QmFieWxvbk1lc2ggaW5zdGFuY2VvZiBBYnN0cmFjdE1lc2gpIHtcclxuICAgICAgICAgICAgbWVzaGVzLnB1c2godGhpcy5fcm9vdEJhYnlsb25NZXNoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IG5vZGVzID0gdGhpcy5fZ2x0Zi5ub2RlcztcclxuICAgICAgICBpZiAobm9kZXMpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBub2RlIG9mIG5vZGVzKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9mb3JFYWNoUHJpbWl0aXZlKG5vZGUsIChiYWJ5bG9uTWVzaCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIG1lc2hlcy5wdXNoKGJhYnlsb25NZXNoKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbWVzaGVzO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2dldFRyYW5zZm9ybU5vZGVzKCk6IFRyYW5zZm9ybU5vZGVbXSB7XHJcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtTm9kZXM6IFRyYW5zZm9ybU5vZGVbXSA9IFtdO1xyXG5cclxuICAgICAgICBjb25zdCBub2RlcyA9IHRoaXMuX2dsdGYubm9kZXM7XHJcbiAgICAgICAgaWYgKG5vZGVzKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBub2Rlcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlICYmIG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlLmdldENsYXNzTmFtZSgpID09PSBcIlRyYW5zZm9ybU5vZGVcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybU5vZGVzLnB1c2gobm9kZS5fYmFieWxvblRyYW5zZm9ybU5vZGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlRm9yU2tpbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybU5vZGVzLnB1c2gobm9kZS5fYmFieWxvblRyYW5zZm9ybU5vZGVGb3JTa2luKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRyYW5zZm9ybU5vZGVzO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2dldFNrZWxldG9ucygpOiBTa2VsZXRvbltdIHtcclxuICAgICAgICBjb25zdCBza2VsZXRvbnM6IFNrZWxldG9uW10gPSBbXTtcclxuXHJcbiAgICAgICAgY29uc3Qgc2tpbnMgPSB0aGlzLl9nbHRmLnNraW5zO1xyXG4gICAgICAgIGlmIChza2lucykge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNraW4gb2Ygc2tpbnMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChza2luLl9kYXRhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2tlbGV0b25zLnB1c2goc2tpbi5fZGF0YS5iYWJ5bG9uU2tlbGV0b24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gc2tlbGV0b25zO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2dldEFuaW1hdGlvbkdyb3VwcygpOiBBbmltYXRpb25Hcm91cFtdIHtcclxuICAgICAgICBjb25zdCBhbmltYXRpb25Hcm91cHM6IEFuaW1hdGlvbkdyb3VwW10gPSBbXTtcclxuXHJcbiAgICAgICAgY29uc3QgYW5pbWF0aW9ucyA9IHRoaXMuX2dsdGYuYW5pbWF0aW9ucztcclxuICAgICAgICBpZiAoYW5pbWF0aW9ucykge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGFuaW1hdGlvbiBvZiBhbmltYXRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYW5pbWF0aW9uLl9iYWJ5bG9uQW5pbWF0aW9uR3JvdXApIHtcclxuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25Hcm91cHMucHVzaChhbmltYXRpb24uX2JhYnlsb25BbmltYXRpb25Hcm91cCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBhbmltYXRpb25Hcm91cHM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfc3RhcnRBbmltYXRpb25zKCk6IHZvaWQge1xyXG4gICAgICAgIHN3aXRjaCAodGhpcy5fcGFyZW50LmFuaW1hdGlvblN0YXJ0TW9kZSkge1xyXG4gICAgICAgICAgICBjYXNlIEdMVEZMb2FkZXJBbmltYXRpb25TdGFydE1vZGUuTk9ORToge1xyXG4gICAgICAgICAgICAgICAgLy8gZG8gbm90aGluZ1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBHTFRGTG9hZGVyQW5pbWF0aW9uU3RhcnRNb2RlLkZJUlNUOiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uQW5pbWF0aW9uR3JvdXBzID0gdGhpcy5fZ2V0QW5pbWF0aW9uR3JvdXBzKCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoYmFieWxvbkFuaW1hdGlvbkdyb3Vwcy5sZW5ndGggIT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uQW5pbWF0aW9uR3JvdXBzWzBdLnN0YXJ0KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBHTFRGTG9hZGVyQW5pbWF0aW9uU3RhcnRNb2RlLkFMTDoge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYmFieWxvbkFuaW1hdGlvbkdyb3VwcyA9IHRoaXMuX2dldEFuaW1hdGlvbkdyb3VwcygpO1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBiYWJ5bG9uQW5pbWF0aW9uR3JvdXAgb2YgYmFieWxvbkFuaW1hdGlvbkdyb3Vwcykge1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25BbmltYXRpb25Hcm91cC5zdGFydCh0cnVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcclxuICAgICAgICAgICAgICAgIExvZ2dlci5FcnJvcihgSW52YWxpZCBhbmltYXRpb24gc3RhcnQgbW9kZSAoJHt0aGlzLl9wYXJlbnQuYW5pbWF0aW9uU3RhcnRNb2RlfSlgKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIExvYWRzIGEgZ2xURiBub2RlLlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIG5vZGUgVGhlIGdsVEYgbm9kZSBwcm9wZXJ0eVxyXG4gICAgICogQHBhcmFtIGFzc2lnbiBBIGZ1bmN0aW9uIGNhbGxlZCBzeW5jaHJvbm91c2x5IGFmdGVyIHBhcnNpbmcgdGhlIGdsVEYgcHJvcGVydGllc1xyXG4gICAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgbG9hZGVkIEJhYnlsb24gbWVzaCB3aGVuIHRoZSBsb2FkIGlzIGNvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTm9kZUFzeW5jKGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU5vZGUsIGFzc2lnbjogKGJhYnlsb25UcmFuc2Zvcm1Ob2RlOiBUcmFuc2Zvcm1Ob2RlKSA9PiB2b2lkID0gKCkgPT4ge30pOiBQcm9taXNlPFRyYW5zZm9ybU5vZGU+IHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25Qcm9taXNlID0gdGhpcy5fZXh0ZW5zaW9uc0xvYWROb2RlQXN5bmMoY29udGV4dCwgbm9kZSwgYXNzaWduKTtcclxuICAgICAgICBpZiAoZXh0ZW5zaW9uUHJvbWlzZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZXh0ZW5zaW9uUHJvbWlzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IEludmFsaWQgcmVjdXJzaXZlIG5vZGUgaGllcmFyY2h5YCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHVua25vd24+PigpO1xyXG5cclxuICAgICAgICB0aGlzLmxvZ09wZW4oYCR7Y29udGV4dH0gJHtub2RlLm5hbWUgfHwgXCJcIn1gKTtcclxuXHJcbiAgICAgICAgY29uc3QgbG9hZE5vZGUgPSAoYmFieWxvblRyYW5zZm9ybU5vZGU6IFRyYW5zZm9ybU5vZGUpID0+IHtcclxuICAgICAgICAgICAgR0xURkxvYWRlci5BZGRQb2ludGVyTWV0YWRhdGEoYmFieWxvblRyYW5zZm9ybU5vZGUsIGNvbnRleHQpO1xyXG4gICAgICAgICAgICBHTFRGTG9hZGVyLl9Mb2FkVHJhbnNmb3JtKG5vZGUsIGJhYnlsb25UcmFuc2Zvcm1Ob2RlKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChub2RlLmNhbWVyYSAhPSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNhbWVyYSA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vY2FtZXJhYCwgdGhpcy5fZ2x0Zi5jYW1lcmFzLCBub2RlLmNhbWVyYSk7XHJcbiAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZENhbWVyYUFzeW5jKGAvY2FtZXJhcy8ke2NhbWVyYS5pbmRleH1gLCBjYW1lcmEsIChiYWJ5bG9uQ2FtZXJhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25DYW1lcmEucGFyZW50ID0gYmFieWxvblRyYW5zZm9ybU5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChub2RlLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGluZGV4IG9mIG5vZGUuY2hpbGRyZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGlsZE5vZGUgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L2NoaWxkcmVuLyR7aW5kZXh9YCwgdGhpcy5fZ2x0Zi5ub2RlcywgaW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZE5vZGVBc3luYyhgL25vZGVzLyR7Y2hpbGROb2RlLmluZGV4fWAsIGNoaWxkTm9kZSwgKGNoaWxkQmFieWxvbk1lc2gpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkQmFieWxvbk1lc2gucGFyZW50ID0gYmFieWxvblRyYW5zZm9ybU5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgYXNzaWduKGJhYnlsb25UcmFuc2Zvcm1Ob2RlKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBjb25zdCBoYXNNZXNoID0gbm9kZS5tZXNoICE9IHVuZGVmaW5lZDtcclxuICAgICAgICBjb25zdCBoYXNTa2luID0gdGhpcy5fcGFyZW50LmxvYWRTa2lucyAmJiBub2RlLnNraW4gIT0gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICBpZiAoIWhhc01lc2ggfHwgaGFzU2tpbikge1xyXG4gICAgICAgICAgICBjb25zdCBub2RlTmFtZSA9IG5vZGUubmFtZSB8fCBgbm9kZSR7bm9kZS5pbmRleH1gO1xyXG4gICAgICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9ICEhdGhpcy5fYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zZm9ybU5vZGUgPSBuZXcgVHJhbnNmb3JtTm9kZShub2RlTmFtZSwgdGhpcy5fYmFieWxvblNjZW5lKTtcclxuICAgICAgICAgICAgdHJhbnNmb3JtTm9kZS5fcGFyZW50Q29udGFpbmVyID0gdGhpcy5fYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGlmIChub2RlLm1lc2ggPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICBub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSA9IHRyYW5zZm9ybU5vZGU7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZUZvclNraW4gPSB0cmFuc2Zvcm1Ob2RlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGxvYWROb2RlKHRyYW5zZm9ybU5vZGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGhhc01lc2gpIHtcclxuICAgICAgICAgICAgaWYgKGhhc1NraW4pIHtcclxuICAgICAgICAgICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvdHJlZS9tYXN0ZXIvc3BlY2lmaWNhdGlvbi8yLjAjc2tpbnMgKHNlY29uZCBpbXBsZW1lbnRhdGlvbiBub3RlKVxyXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBjb2RlIHBhdGggd2lsbCBwbGFjZSB0aGUgc2tpbm5lZCBtZXNoIGFzIGEgc2libGluZyBvZiB0aGUgc2tlbGV0b24gcm9vdCBub2RlIHdpdGhvdXQgbG9hZGluZyB0aGVcclxuICAgICAgICAgICAgICAgIC8vIHRyYW5zZm9ybSwgd2hpY2ggZWZmZWN0aXZlbHkgaWdub3JlcyB0aGUgdHJhbnNmb3JtIG9mIHRoZSBza2lubmVkIG1lc2gsIGFzIHBlciBzcGVjLlxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IG1lc2ggPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L21lc2hgLCB0aGlzLl9nbHRmLm1lc2hlcywgbm9kZS5tZXNoKTtcclxuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZE1lc2hBc3luYyhgL21lc2hlcy8ke21lc2guaW5kZXh9YCwgbm9kZSwgbWVzaCwgKGJhYnlsb25UcmFuc2Zvcm1Ob2RlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJhYnlsb25UcmFuc2Zvcm1Ob2RlRm9yU2tpbiA9IG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlRm9yU2tpbiE7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBNZXJnZSB0aGUgbWV0YWRhdGEgZnJvbSB0aGUgc2tpbiBub2RlIHRvIHRoZSBza2lubmVkIG1lc2ggaW4gY2FzZSBhIGxvYWRlciBleHRlbnNpb24gYWRkZWQgbWV0YWRhdGEuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25UcmFuc2Zvcm1Ob2RlLm1ldGFkYXRhID0gbWVyZ2VEZWVwKGJhYnlsb25UcmFuc2Zvcm1Ob2RlRm9yU2tpbi5tZXRhZGF0YSwgYmFieWxvblRyYW5zZm9ybU5vZGUubWV0YWRhdGEgfHwge30pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2tpbiA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vc2tpbmAsIHRoaXMuX2dsdGYuc2tpbnMsIG5vZGUuc2tpbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkU2tpbkFzeW5jKGAvc2tpbnMvJHtza2luLmluZGV4fWAsIG5vZGUsIHNraW4sIChiYWJ5bG9uU2tlbGV0b24pID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9mb3JFYWNoUHJpbWl0aXZlKG5vZGUsIChiYWJ5bG9uTWVzaCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWVzaC5za2VsZXRvbiA9IGJhYnlsb25Ta2VsZXRvbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2FpdCB1bnRpbCBhbGwgdGhlIG5vZGVzIGFyZSBwYXJlbnRlZCBiZWZvcmUgcGFyZW50aW5nIHRoZSBza2lubmVkIG1lc2guXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcG9zdFNjZW5lTG9hZEFjdGlvbnMucHVzaCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChza2luLnNrZWxldG9uICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGxhY2UgdGhlIHNraW5uZWQgbWVzaCBub2RlIGFzIGEgc2libGluZyBvZiB0aGUgc2tlbGV0b24gcm9vdCBub2RlLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSGFuZGxlIHNwZWNpYWwgY2FzZSB3aGVuIHRoZSBwYXJlbnQgb2YgdGhlIHNrZWxldG9uIHJvb3QgaXMgdGhlIHNraW5uZWQgbWVzaC5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcmVudE5vZGUgPSBBcnJheUl0ZW0uR2V0KGAvc2tpbnMvJHtza2luLmluZGV4fS9za2VsZXRvbmAsIHRoaXMuX2dsdGYubm9kZXMsIHNraW4uc2tlbGV0b24pLnBhcmVudCE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZS5pbmRleCA9PT0gcGFyZW50Tm9kZS5pbmRleCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25UcmFuc2Zvcm1Ob2RlLnBhcmVudCA9IGJhYnlsb25UcmFuc2Zvcm1Ob2RlRm9yU2tpbi5wYXJlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25UcmFuc2Zvcm1Ob2RlLnBhcmVudCA9IHBhcmVudE5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlITtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25UcmFuc2Zvcm1Ob2RlLnBhcmVudCA9IHRoaXMuX3Jvb3RCYWJ5bG9uTWVzaDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFyZW50Lm9uU2tpbkxvYWRlZE9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKHsgbm9kZTogYmFieWxvblRyYW5zZm9ybU5vZGVGb3JTa2luLCBza2lubmVkTm9kZTogYmFieWxvblRyYW5zZm9ybU5vZGUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbWVzaCA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vbWVzaGAsIHRoaXMuX2dsdGYubWVzaGVzLCBub2RlLm1lc2gpO1xyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLl9sb2FkTWVzaEFzeW5jKGAvbWVzaGVzLyR7bWVzaC5pbmRleH1gLCBub2RlLCBtZXNoLCBsb2FkTm9kZSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmxvZ0Nsb3NlKCk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2hQcmltaXRpdmUobm9kZSwgKGJhYnlsb25NZXNoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoKGJhYnlsb25NZXNoIGFzIE1lc2gpLmdlb21ldHJ5ICYmIChiYWJ5bG9uTWVzaCBhcyBNZXNoKS5nZW9tZXRyeSEudXNlQm91bmRpbmdJbmZvRnJvbUdlb21ldHJ5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gc2ltcGx5IGFwcGx5IHRoZSB3b3JsZCBtYXRyaWNlcyB0byB0aGUgYm91bmRpbmcgaW5mbyAtIHRoZSBleHRlbmRzIGFyZSBhbHJlYWR5IG9rXHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1lc2guX3VwZGF0ZUJvdW5kaW5nSW5mbygpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWVzaC5yZWZyZXNoQm91bmRpbmdJbmZvKHRydWUsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSE7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZE1lc2hBc3luYyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IElOb2RlLCBtZXNoOiBJTWVzaCwgYXNzaWduOiAoYmFieWxvblRyYW5zZm9ybU5vZGU6IFRyYW5zZm9ybU5vZGUpID0+IHZvaWQpOiBQcm9taXNlPFRyYW5zZm9ybU5vZGU+IHtcclxuICAgICAgICBjb25zdCBwcmltaXRpdmVzID0gbWVzaC5wcmltaXRpdmVzO1xyXG4gICAgICAgIGlmICghcHJpbWl0aXZlcyB8fCAhcHJpbWl0aXZlcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBQcmltaXRpdmVzIGFyZSBtaXNzaW5nYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocHJpbWl0aXZlc1swXS5pbmRleCA9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgQXJyYXlJdGVtLkFzc2lnbihwcmltaXRpdmVzKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dW5rbm93bj4+KCk7XHJcblxyXG4gICAgICAgIHRoaXMubG9nT3BlbihgJHtjb250ZXh0fSAke21lc2gubmFtZSB8fCBcIlwifWApO1xyXG5cclxuICAgICAgICBjb25zdCBuYW1lID0gbm9kZS5uYW1lIHx8IGBub2RlJHtub2RlLmluZGV4fWA7XHJcblxyXG4gICAgICAgIGlmIChwcmltaXRpdmVzLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgICAgICBjb25zdCBwcmltaXRpdmUgPSBtZXNoLnByaW1pdGl2ZXNbMF07XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkTWVzaFByaW1pdGl2ZUFzeW5jKGAke2NvbnRleHR9L3ByaW1pdGl2ZXMvJHtwcmltaXRpdmUuaW5kZXh9YCwgbmFtZSwgbm9kZSwgbWVzaCwgcHJpbWl0aXZlLCAoYmFieWxvbk1lc2gpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSA9IGJhYnlsb25NZXNoO1xyXG4gICAgICAgICAgICAgICAgICAgIG5vZGUuX3ByaW1pdGl2ZUJhYnlsb25NZXNoZXMgPSBbYmFieWxvbk1lc2hdO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9ICEhdGhpcy5fYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgICAgIG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlID0gbmV3IFRyYW5zZm9ybU5vZGUobmFtZSwgdGhpcy5fYmFieWxvblNjZW5lKTtcclxuICAgICAgICAgICAgbm9kZS5fYmFieWxvblRyYW5zZm9ybU5vZGUuX3BhcmVudENvbnRhaW5lciA9IHRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICBub2RlLl9wcmltaXRpdmVCYWJ5bG9uTWVzaGVzID0gW107XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgcHJpbWl0aXZlIG9mIHByaW1pdGl2ZXMpIHtcclxuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZE1lc2hQcmltaXRpdmVBc3luYyhgJHtjb250ZXh0fS9wcmltaXRpdmVzLyR7cHJpbWl0aXZlLmluZGV4fWAsIGAke25hbWV9X3ByaW1pdGl2ZSR7cHJpbWl0aXZlLmluZGV4fWAsIG5vZGUsIG1lc2gsIHByaW1pdGl2ZSwgKGJhYnlsb25NZXNoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25NZXNoLnBhcmVudCA9IG5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlITtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5fcHJpbWl0aXZlQmFieWxvbk1lc2hlcyEucHVzaChiYWJ5bG9uTWVzaCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGFzc2lnbihub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSEpO1xyXG5cclxuICAgICAgICB0aGlzLmxvZ0Nsb3NlKCk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBub2RlLl9iYWJ5bG9uVHJhbnNmb3JtTm9kZSE7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWwgRGVmaW5lIHRoaXMgbWV0aG9kIHRvIG1vZGlmeSB0aGUgZGVmYXVsdCBiZWhhdmlvciB3aGVuIGxvYWRpbmcgZGF0YSBmb3IgbWVzaCBwcmltaXRpdmVzLlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIG5hbWUgVGhlIG1lc2ggbmFtZSB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gbm9kZSBUaGUgZ2xURiBub2RlIHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBtZXNoIFRoZSBnbFRGIG1lc2ggd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIHByaW1pdGl2ZSBUaGUgZ2xURiBtZXNoIHByaW1pdGl2ZSBwcm9wZXJ0eVxyXG4gICAgICogQHBhcmFtIGFzc2lnbiBBIGZ1bmN0aW9uIGNhbGxlZCBzeW5jaHJvbm91c2x5IGFmdGVyIHBhcnNpbmcgdGhlIGdsVEYgcHJvcGVydGllc1xyXG4gICAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgbG9hZGVkIG1lc2ggd2hlbiB0aGUgbG9hZCBpcyBjb21wbGV0ZSBvciBudWxsIGlmIG5vdCBoYW5kbGVkXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbG9hZE1lc2hQcmltaXRpdmVBc3luYyhcclxuICAgICAgICBjb250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgbmFtZTogc3RyaW5nLFxyXG4gICAgICAgIG5vZGU6IElOb2RlLFxyXG4gICAgICAgIG1lc2g6IElNZXNoLFxyXG4gICAgICAgIHByaW1pdGl2ZTogSU1lc2hQcmltaXRpdmUsXHJcbiAgICAgICAgYXNzaWduOiAoYmFieWxvbk1lc2g6IEFic3RyYWN0TWVzaCkgPT4gdm9pZFxyXG4gICAgKTogUHJvbWlzZTxBYnN0cmFjdE1lc2g+IHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25Qcm9taXNlID0gdGhpcy5fZXh0ZW5zaW9uc0xvYWRNZXNoUHJpbWl0aXZlQXN5bmMoY29udGV4dCwgbmFtZSwgbm9kZSwgbWVzaCwgcHJpbWl0aXZlLCBhc3NpZ24pO1xyXG4gICAgICAgIGlmIChleHRlbnNpb25Qcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHRlbnNpb25Qcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5sb2dPcGVuKGAke2NvbnRleHR9YCk7XHJcblxyXG4gICAgICAgIGNvbnN0IHNob3VsZEluc3RhbmNlID0gdGhpcy5fZGlzYWJsZUluc3RhbmNlZE1lc2ggPT09IDAgJiYgdGhpcy5fcGFyZW50LmNyZWF0ZUluc3RhbmNlcyAmJiBub2RlLnNraW4gPT0gdW5kZWZpbmVkICYmICFtZXNoLnByaW1pdGl2ZXNbMF0udGFyZ2V0cztcclxuXHJcbiAgICAgICAgbGV0IGJhYnlsb25BYnN0cmFjdE1lc2g6IEFic3RyYWN0TWVzaDtcclxuICAgICAgICBsZXQgcHJvbWlzZTogUHJvbWlzZTx1bmtub3duPjtcclxuXHJcbiAgICAgICAgaWYgKHNob3VsZEluc3RhbmNlICYmIHByaW1pdGl2ZS5faW5zdGFuY2VEYXRhKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gISF0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICAgICAgYmFieWxvbkFic3RyYWN0TWVzaCA9IHByaW1pdGl2ZS5faW5zdGFuY2VEYXRhLmJhYnlsb25Tb3VyY2VNZXNoLmNyZWF0ZUluc3RhbmNlKG5hbWUpIGFzIEluc3RhbmNlZE1lc2g7XHJcbiAgICAgICAgICAgIGJhYnlsb25BYnN0cmFjdE1lc2guX3BhcmVudENvbnRhaW5lciA9IHRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICBwcm9taXNlID0gcHJpbWl0aXZlLl9pbnN0YW5jZURhdGEucHJvbWlzZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHVua25vd24+PigpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSAhIXRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICBjb25zdCBiYWJ5bG9uTWVzaCA9IG5ldyBNZXNoKG5hbWUsIHRoaXMuX2JhYnlsb25TY2VuZSk7XHJcbiAgICAgICAgICAgIGJhYnlsb25NZXNoLl9wYXJlbnRDb250YWluZXIgPSB0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSBmYWxzZTtcclxuICAgICAgICAgICAgYmFieWxvbk1lc2guc2lkZU9yaWVudGF0aW9uID0gdGhpcy5fYmFieWxvblNjZW5lLnVzZVJpZ2h0SGFuZGVkU3lzdGVtID8gTWF0ZXJpYWwuQ291bnRlckNsb2NrV2lzZVNpZGVPcmllbnRhdGlvbiA6IE1hdGVyaWFsLkNsb2NrV2lzZVNpZGVPcmllbnRhdGlvbjtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU1vcnBoVGFyZ2V0cyhjb250ZXh0LCBub2RlLCBtZXNoLCBwcmltaXRpdmUsIGJhYnlsb25NZXNoKTtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRWZXJ0ZXhEYXRhQXN5bmMoY29udGV4dCwgcHJpbWl0aXZlLCBiYWJ5bG9uTWVzaCkudGhlbigoYmFieWxvbkdlb21ldHJ5KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRNb3JwaFRhcmdldHNBc3luYyhjb250ZXh0LCBwcmltaXRpdmUsIGJhYnlsb25NZXNoLCBiYWJ5bG9uR2VvbWV0cnkpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fZGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSAhIXRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uR2VvbWV0cnkuYXBwbHlUb01lc2goYmFieWxvbk1lc2gpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uR2VvbWV0cnkuX3BhcmVudENvbnRhaW5lciA9IHRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGJhYnlsb25EcmF3TW9kZSA9IEdMVEZMb2FkZXIuX0dldERyYXdNb2RlKGNvbnRleHQsIHByaW1pdGl2ZS5tb2RlKTtcclxuICAgICAgICAgICAgaWYgKHByaW1pdGl2ZS5tYXRlcmlhbCA9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIGxldCBiYWJ5bG9uTWF0ZXJpYWwgPSB0aGlzLl9kZWZhdWx0QmFieWxvbk1hdGVyaWFsRGF0YVtiYWJ5bG9uRHJhd01vZGVdO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFiYWJ5bG9uTWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwgPSB0aGlzLl9jcmVhdGVEZWZhdWx0TWF0ZXJpYWwoXCJfX0dMVEZMb2FkZXIuX2RlZmF1bHRcIiwgYmFieWxvbkRyYXdNb2RlKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJlbnQub25NYXRlcmlhbExvYWRlZE9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKGJhYnlsb25NYXRlcmlhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGVmYXVsdEJhYnlsb25NYXRlcmlhbERhdGFbYmFieWxvbkRyYXdNb2RlXSA9IGJhYnlsb25NYXRlcmlhbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJhYnlsb25NZXNoLm1hdGVyaWFsID0gYmFieWxvbk1hdGVyaWFsO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLnBhcmVudC5za2lwTWF0ZXJpYWxzKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtYXRlcmlhbCA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vbWF0ZXJpYWxgLCB0aGlzLl9nbHRmLm1hdGVyaWFscywgcHJpbWl0aXZlLm1hdGVyaWFsKTtcclxuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9hZE1hdGVyaWFsQXN5bmMoYC9tYXRlcmlhbHMvJHttYXRlcmlhbC5pbmRleH1gLCBtYXRlcmlhbCwgYmFieWxvbk1lc2gsIGJhYnlsb25EcmF3TW9kZSwgKGJhYnlsb25NYXRlcmlhbCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWVzaC5tYXRlcmlhbCA9IGJhYnlsb25NYXRlcmlhbDtcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcHJvbWlzZSA9IFByb21pc2UuYWxsKHByb21pc2VzKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzaG91bGRJbnN0YW5jZSkge1xyXG4gICAgICAgICAgICAgICAgcHJpbWl0aXZlLl9pbnN0YW5jZURhdGEgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvblNvdXJjZU1lc2g6IGJhYnlsb25NZXNoLFxyXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2U6IHByb21pc2UsXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBiYWJ5bG9uQWJzdHJhY3RNZXNoID0gYmFieWxvbk1lc2g7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBHTFRGTG9hZGVyLkFkZFBvaW50ZXJNZXRhZGF0YShiYWJ5bG9uQWJzdHJhY3RNZXNoLCBjb250ZXh0KTtcclxuICAgICAgICB0aGlzLl9wYXJlbnQub25NZXNoTG9hZGVkT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMoYmFieWxvbkFic3RyYWN0TWVzaCk7XHJcbiAgICAgICAgYXNzaWduKGJhYnlsb25BYnN0cmFjdE1lc2gpO1xyXG5cclxuICAgICAgICB0aGlzLmxvZ0Nsb3NlKCk7XHJcblxyXG4gICAgICAgIHJldHVybiBwcm9taXNlLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gYmFieWxvbkFic3RyYWN0TWVzaDtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkVmVydGV4RGF0YUFzeW5jKGNvbnRleHQ6IHN0cmluZywgcHJpbWl0aXZlOiBJTWVzaFByaW1pdGl2ZSwgYmFieWxvbk1lc2g6IE1lc2gpOiBQcm9taXNlPEdlb21ldHJ5PiB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uUHJvbWlzZSA9IHRoaXMuX2V4dGVuc2lvbnNMb2FkVmVydGV4RGF0YUFzeW5jKGNvbnRleHQsIHByaW1pdGl2ZSwgYmFieWxvbk1lc2gpO1xyXG4gICAgICAgIGlmIChleHRlbnNpb25Qcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHRlbnNpb25Qcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgYXR0cmlidXRlcyA9IHByaW1pdGl2ZS5hdHRyaWJ1dGVzO1xyXG4gICAgICAgIGlmICghYXR0cmlidXRlcykge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IEF0dHJpYnV0ZXMgYXJlIG1pc3NpbmdgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dW5rbm93bj4+KCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGJhYnlsb25HZW9tZXRyeSA9IG5ldyBHZW9tZXRyeShiYWJ5bG9uTWVzaC5uYW1lLCB0aGlzLl9iYWJ5bG9uU2NlbmUpO1xyXG5cclxuICAgICAgICBpZiAocHJpbWl0aXZlLmluZGljZXMgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGJhYnlsb25NZXNoLmlzVW5JbmRleGVkID0gdHJ1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBhY2Nlc3NvciA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vaW5kaWNlc2AsIHRoaXMuX2dsdGYuYWNjZXNzb3JzLCBwcmltaXRpdmUuaW5kaWNlcyk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkSW5kaWNlc0FjY2Vzc29yQXN5bmMoYC9hY2Nlc3NvcnMvJHthY2Nlc3Nvci5pbmRleH1gLCBhY2Nlc3NvcikudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25HZW9tZXRyeS5zZXRJbmRpY2VzKGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGxvYWRBdHRyaWJ1dGUgPSAobmFtZTogc3RyaW5nLCBraW5kOiBzdHJpbmcsIGNhbGxiYWNrPzogKGFjY2Vzc29yOiBJQWNjZXNzb3IpID0+IHZvaWQpID0+IHtcclxuICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXNbbmFtZV0gPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGJhYnlsb25NZXNoLl9kZWxheUluZm8gPSBiYWJ5bG9uTWVzaC5fZGVsYXlJbmZvIHx8IFtdO1xyXG4gICAgICAgICAgICBpZiAoYmFieWxvbk1lc2guX2RlbGF5SW5mby5pbmRleE9mKGtpbmQpID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1lc2guX2RlbGF5SW5mby5wdXNoKGtpbmQpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBhY2Nlc3NvciA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vYXR0cmlidXRlcy8ke25hbWV9YCwgdGhpcy5fZ2x0Zi5hY2Nlc3NvcnMsIGF0dHJpYnV0ZXNbbmFtZV0pO1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbG9hZFZlcnRleEFjY2Vzc29yQXN5bmMoYC9hY2Nlc3NvcnMvJHthY2Nlc3Nvci5pbmRleH1gLCBhY2Nlc3Nvciwga2luZCkudGhlbigoYmFieWxvblZlcnRleEJ1ZmZlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uVmVydGV4QnVmZmVyLmdldEtpbmQoKSA9PT0gVmVydGV4QnVmZmVyLlBvc2l0aW9uS2luZCAmJiAhdGhpcy5wYXJlbnQuYWx3YXlzQ29tcHV0ZUJvdW5kaW5nQm94ICYmICFiYWJ5bG9uTWVzaC5za2VsZXRvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWNjZXNzb3IubWluICYmIGFjY2Vzc29yLm1heCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWluID0gVG1wVmVjdG9ycy5WZWN0b3IzWzBdLmNvcHlGcm9tRmxvYXRzKC4uLihhY2Nlc3Nvci5taW4gYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXJdKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXggPSBUbXBWZWN0b3JzLlZlY3RvcjNbMV0uY29weUZyb21GbG9hdHMoLi4uKGFjY2Vzc29yLm1heCBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0pKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhY2Nlc3Nvci5ub3JtYWxpemVkICYmIGFjY2Vzc29yLmNvbXBvbmVudFR5cGUgIT09IEFjY2Vzc29yQ29tcG9uZW50VHlwZS5GTE9BVCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkaXZpZGVyID0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGFjY2Vzc29yLmNvbXBvbmVudFR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuQllURTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpdmlkZXIgPSAxMjcuMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEFjY2Vzc29yQ29tcG9uZW50VHlwZS5VTlNJR05FRF9CWVRFOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGl2aWRlciA9IDI1NS4wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQWNjZXNzb3JDb21wb25lbnRUeXBlLlNIT1JUOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGl2aWRlciA9IDMyNzY3LjA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuVU5TSUdORURfU0hPUlQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXZpZGVyID0gNjU1MzUuMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbmVPdmVyRGl2aWRlciA9IDEgLyBkaXZpZGVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5zY2FsZUluUGxhY2Uob25lT3ZlckRpdmlkZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heC5zY2FsZUluUGxhY2Uob25lT3ZlckRpdmlkZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbkdlb21ldHJ5Ll9ib3VuZGluZ0luZm8gPSBuZXcgQm91bmRpbmdJbmZvKG1pbiwgbWF4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25HZW9tZXRyeS51c2VCb3VuZGluZ0luZm9Gcm9tR2VvbWV0cnkgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25HZW9tZXRyeS5zZXRWZXJ0aWNlc0J1ZmZlcihiYWJ5bG9uVmVydGV4QnVmZmVyLCBhY2Nlc3Nvci5jb3VudCk7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgaWYgKGtpbmQgPT0gVmVydGV4QnVmZmVyLk1hdHJpY2VzSW5kaWNlc0V4dHJhS2luZCkge1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1lc2gubnVtQm9uZUluZmx1ZW5jZXJzID0gODtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhhY2Nlc3Nvcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBsb2FkQXR0cmlidXRlKFwiUE9TSVRJT05cIiwgVmVydGV4QnVmZmVyLlBvc2l0aW9uS2luZCk7XHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIk5PUk1BTFwiLCBWZXJ0ZXhCdWZmZXIuTm9ybWFsS2luZCk7XHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlRBTkdFTlRcIiwgVmVydGV4QnVmZmVyLlRhbmdlbnRLaW5kKTtcclxuICAgICAgICBsb2FkQXR0cmlidXRlKFwiVEVYQ09PUkRfMFwiLCBWZXJ0ZXhCdWZmZXIuVVZLaW5kKTtcclxuICAgICAgICBsb2FkQXR0cmlidXRlKFwiVEVYQ09PUkRfMVwiLCBWZXJ0ZXhCdWZmZXIuVVYyS2luZCk7XHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlRFWENPT1JEXzJcIiwgVmVydGV4QnVmZmVyLlVWM0tpbmQpO1xyXG4gICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJURVhDT09SRF8zXCIsIFZlcnRleEJ1ZmZlci5VVjRLaW5kKTtcclxuICAgICAgICBsb2FkQXR0cmlidXRlKFwiVEVYQ09PUkRfNFwiLCBWZXJ0ZXhCdWZmZXIuVVY1S2luZCk7XHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIlRFWENPT1JEXzVcIiwgVmVydGV4QnVmZmVyLlVWNktpbmQpO1xyXG4gICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJKT0lOVFNfMFwiLCBWZXJ0ZXhCdWZmZXIuTWF0cmljZXNJbmRpY2VzS2luZCk7XHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIldFSUdIVFNfMFwiLCBWZXJ0ZXhCdWZmZXIuTWF0cmljZXNXZWlnaHRzS2luZCk7XHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIkpPSU5UU18xXCIsIFZlcnRleEJ1ZmZlci5NYXRyaWNlc0luZGljZXNFeHRyYUtpbmQpO1xyXG4gICAgICAgIGxvYWRBdHRyaWJ1dGUoXCJXRUlHSFRTXzFcIiwgVmVydGV4QnVmZmVyLk1hdHJpY2VzV2VpZ2h0c0V4dHJhS2luZCk7XHJcbiAgICAgICAgbG9hZEF0dHJpYnV0ZShcIkNPTE9SXzBcIiwgVmVydGV4QnVmZmVyLkNvbG9yS2luZCwgKGFjY2Vzc29yKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChhY2Nlc3Nvci50eXBlID09PSBBY2Nlc3NvclR5cGUuVkVDNCkge1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1lc2guaGFzVmVydGV4QWxwaGEgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBiYWJ5bG9uR2VvbWV0cnk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfY3JlYXRlTW9ycGhUYXJnZXRzKGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU5vZGUsIG1lc2g6IElNZXNoLCBwcmltaXRpdmU6IElNZXNoUHJpbWl0aXZlLCBiYWJ5bG9uTWVzaDogTWVzaCk6IHZvaWQge1xyXG4gICAgICAgIGlmICghcHJpbWl0aXZlLnRhcmdldHMgfHwgIXRoaXMuX3BhcmVudC5sb2FkTW9ycGhUYXJnZXRzKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChub2RlLl9udW1Nb3JwaFRhcmdldHMgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIG5vZGUuX251bU1vcnBoVGFyZ2V0cyA9IHByaW1pdGl2ZS50YXJnZXRzLmxlbmd0aDtcclxuICAgICAgICB9IGVsc2UgaWYgKHByaW1pdGl2ZS50YXJnZXRzLmxlbmd0aCAhPT0gbm9kZS5fbnVtTW9ycGhUYXJnZXRzKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogUHJpbWl0aXZlcyBkbyBub3QgaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgdGFyZ2V0c2ApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgdGFyZ2V0TmFtZXMgPSBtZXNoLmV4dHJhcyA/IG1lc2guZXh0cmFzLnRhcmdldE5hbWVzIDogbnVsbDtcclxuXHJcbiAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSAhIXRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgIGJhYnlsb25NZXNoLm1vcnBoVGFyZ2V0TWFuYWdlciA9IG5ldyBNb3JwaFRhcmdldE1hbmFnZXIodGhpcy5fYmFieWxvblNjZW5lKTtcclxuICAgICAgICBiYWJ5bG9uTWVzaC5tb3JwaFRhcmdldE1hbmFnZXIuX3BhcmVudENvbnRhaW5lciA9IHRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGJhYnlsb25NZXNoLm1vcnBoVGFyZ2V0TWFuYWdlci5hcmVVcGRhdGVzRnJvemVuID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHByaW1pdGl2ZS50YXJnZXRzLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICAgICAgICBjb25zdCB3ZWlnaHQgPSBub2RlLndlaWdodHMgPyBub2RlLndlaWdodHNbaW5kZXhdIDogbWVzaC53ZWlnaHRzID8gbWVzaC53ZWlnaHRzW2luZGV4XSA6IDA7XHJcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSB0YXJnZXROYW1lcyA/IHRhcmdldE5hbWVzW2luZGV4XSA6IGBtb3JwaFRhcmdldCR7aW5kZXh9YDtcclxuICAgICAgICAgICAgYmFieWxvbk1lc2gubW9ycGhUYXJnZXRNYW5hZ2VyLmFkZFRhcmdldChuZXcgTW9ycGhUYXJnZXQobmFtZSwgd2VpZ2h0LCBiYWJ5bG9uTWVzaC5nZXRTY2VuZSgpKSk7XHJcbiAgICAgICAgICAgIC8vIFRPRE86IHRlbGwgdGhlIHRhcmdldCB3aGV0aGVyIGl0IGhhcyBwb3NpdGlvbnMsIG5vcm1hbHMsIHRhbmdlbnRzXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRNb3JwaFRhcmdldHNBc3luYyhjb250ZXh0OiBzdHJpbmcsIHByaW1pdGl2ZTogSU1lc2hQcmltaXRpdmUsIGJhYnlsb25NZXNoOiBNZXNoLCBiYWJ5bG9uR2VvbWV0cnk6IEdlb21ldHJ5KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKCFwcmltaXRpdmUudGFyZ2V0cyB8fCAhdGhpcy5fcGFyZW50LmxvYWRNb3JwaFRhcmdldHMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTx1bmtub3duPj4oKTtcclxuXHJcbiAgICAgICAgY29uc3QgbW9ycGhUYXJnZXRNYW5hZ2VyID0gYmFieWxvbk1lc2gubW9ycGhUYXJnZXRNYW5hZ2VyITtcclxuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbW9ycGhUYXJnZXRNYW5hZ2VyLm51bVRhcmdldHM7IGluZGV4KyspIHtcclxuICAgICAgICAgICAgY29uc3QgYmFieWxvbk1vcnBoVGFyZ2V0ID0gbW9ycGhUYXJnZXRNYW5hZ2VyLmdldFRhcmdldChpbmRleCk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5fbG9hZE1vcnBoVGFyZ2V0VmVydGV4RGF0YUFzeW5jKGAke2NvbnRleHR9L3RhcmdldHMvJHtpbmRleH1gLCBiYWJ5bG9uR2VvbWV0cnksIHByaW1pdGl2ZS50YXJnZXRzW2luZGV4XSwgYmFieWxvbk1vcnBoVGFyZ2V0KSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICBtb3JwaFRhcmdldE1hbmFnZXIuYXJlVXBkYXRlc0Zyb3plbiA9IGZhbHNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRNb3JwaFRhcmdldFZlcnRleERhdGFBc3luYyhjb250ZXh0OiBzdHJpbmcsIGJhYnlsb25HZW9tZXRyeTogR2VvbWV0cnksIGF0dHJpYnV0ZXM6IHsgW25hbWU6IHN0cmluZ106IG51bWJlciB9LCBiYWJ5bG9uTW9ycGhUYXJnZXQ6IE1vcnBoVGFyZ2V0KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTx1bmtub3duPj4oKTtcclxuXHJcbiAgICAgICAgY29uc3QgbG9hZEF0dHJpYnV0ZSA9IChhdHRyaWJ1dGU6IHN0cmluZywga2luZDogc3RyaW5nLCBzZXREYXRhOiAoYmFieWxvblZlcnRleEJ1ZmZlcjogVmVydGV4QnVmZmVyLCBkYXRhOiBGbG9hdDMyQXJyYXkpID0+IHZvaWQpID0+IHtcclxuICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXNbYXR0cmlidXRlXSA9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgYmFieWxvblZlcnRleEJ1ZmZlciA9IGJhYnlsb25HZW9tZXRyeS5nZXRWZXJ0ZXhCdWZmZXIoa2luZCk7XHJcbiAgICAgICAgICAgIGlmICghYmFieWxvblZlcnRleEJ1ZmZlcikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBhY2Nlc3NvciA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vJHthdHRyaWJ1dGV9YCwgdGhpcy5fZ2x0Zi5hY2Nlc3NvcnMsIGF0dHJpYnV0ZXNbYXR0cmlidXRlXSk7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkRmxvYXRBY2Nlc3NvckFzeW5jKGAvYWNjZXNzb3JzLyR7YWNjZXNzb3IuaW5kZXh9YCwgYWNjZXNzb3IpLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBzZXREYXRhKGJhYnlsb25WZXJ0ZXhCdWZmZXIsIGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBsb2FkQXR0cmlidXRlKFwiUE9TSVRJT05cIiwgVmVydGV4QnVmZmVyLlBvc2l0aW9uS2luZCwgKGJhYnlsb25WZXJ0ZXhCdWZmZXIsIGRhdGEpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcG9zaXRpb25zID0gbmV3IEZsb2F0MzJBcnJheShkYXRhLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIGJhYnlsb25WZXJ0ZXhCdWZmZXIuZm9yRWFjaChkYXRhLmxlbmd0aCwgKHZhbHVlLCBpbmRleCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcG9zaXRpb25zW2luZGV4XSA9IGRhdGFbaW5kZXhdICsgdmFsdWU7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgYmFieWxvbk1vcnBoVGFyZ2V0LnNldFBvc2l0aW9ucyhwb3NpdGlvbnMpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBsb2FkQXR0cmlidXRlKFwiTk9STUFMXCIsIFZlcnRleEJ1ZmZlci5Ob3JtYWxLaW5kLCAoYmFieWxvblZlcnRleEJ1ZmZlciwgZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBub3JtYWxzID0gbmV3IEZsb2F0MzJBcnJheShkYXRhLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIGJhYnlsb25WZXJ0ZXhCdWZmZXIuZm9yRWFjaChub3JtYWxzLmxlbmd0aCwgKHZhbHVlLCBpbmRleCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgbm9ybWFsc1tpbmRleF0gPSBkYXRhW2luZGV4XSArIHZhbHVlO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGJhYnlsb25Nb3JwaFRhcmdldC5zZXROb3JtYWxzKG5vcm1hbHMpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBsb2FkQXR0cmlidXRlKFwiVEFOR0VOVFwiLCBWZXJ0ZXhCdWZmZXIuVGFuZ2VudEtpbmQsIChiYWJ5bG9uVmVydGV4QnVmZmVyLCBkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRhbmdlbnRzID0gbmV3IEZsb2F0MzJBcnJheSgoZGF0YS5sZW5ndGggLyAzKSAqIDQpO1xyXG4gICAgICAgICAgICBsZXQgZGF0YUluZGV4ID0gMDtcclxuICAgICAgICAgICAgYmFieWxvblZlcnRleEJ1ZmZlci5mb3JFYWNoKChkYXRhLmxlbmd0aCAvIDMpICogNCwgKHZhbHVlLCBpbmRleCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gVGFuZ2VudCBkYXRhIGZvciBtb3JwaCB0YXJnZXRzIGlzIHN0b3JlZCBhcyB4eXogZGVsdGEuXHJcbiAgICAgICAgICAgICAgICAvLyBUaGUgdmVydGV4RGF0YS50YW5nZW50IGlzIHN0b3JlZCBhcyB4eXp3LlxyXG4gICAgICAgICAgICAgICAgLy8gU28gd2UgbmVlZCB0byBza2lwIGV2ZXJ5IGZvdXJ0aCB2ZXJ0ZXhEYXRhLnRhbmdlbnQuXHJcbiAgICAgICAgICAgICAgICBpZiAoKGluZGV4ICsgMSkgJSA0ICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGFuZ2VudHNbZGF0YUluZGV4XSA9IGRhdGFbZGF0YUluZGV4XSArIHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGRhdGFJbmRleCsrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgYmFieWxvbk1vcnBoVGFyZ2V0LnNldFRhbmdlbnRzKHRhbmdlbnRzKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfTG9hZFRyYW5zZm9ybShub2RlOiBJTm9kZSwgYmFieWxvbk5vZGU6IFRyYW5zZm9ybU5vZGUpOiB2b2lkIHtcclxuICAgICAgICAvLyBJZ25vcmUgdGhlIFRSUyBvZiBza2lubmVkIG5vZGVzLlxyXG4gICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vS2hyb25vc0dyb3VwL2dsVEYvdHJlZS9tYXN0ZXIvc3BlY2lmaWNhdGlvbi8yLjAjc2tpbnMgKHNlY29uZCBpbXBsZW1lbnRhdGlvbiBub3RlKVxyXG4gICAgICAgIGlmIChub2RlLnNraW4gIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBwb3NpdGlvbiA9IFZlY3RvcjMuWmVybygpO1xyXG4gICAgICAgIGxldCByb3RhdGlvbiA9IFF1YXRlcm5pb24uSWRlbnRpdHkoKTtcclxuICAgICAgICBsZXQgc2NhbGluZyA9IFZlY3RvcjMuT25lKCk7XHJcblxyXG4gICAgICAgIGlmIChub2RlLm1hdHJpeCkge1xyXG4gICAgICAgICAgICBjb25zdCBtYXRyaXggPSBNYXRyaXguRnJvbUFycmF5KG5vZGUubWF0cml4KTtcclxuICAgICAgICAgICAgbWF0cml4LmRlY29tcG9zZShzY2FsaW5nLCByb3RhdGlvbiwgcG9zaXRpb24pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChub2RlLnRyYW5zbGF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICBwb3NpdGlvbiA9IFZlY3RvcjMuRnJvbUFycmF5KG5vZGUudHJhbnNsYXRpb24pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChub2RlLnJvdGF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICByb3RhdGlvbiA9IFF1YXRlcm5pb24uRnJvbUFycmF5KG5vZGUucm90YXRpb24pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChub2RlLnNjYWxlKSB7XHJcbiAgICAgICAgICAgICAgICBzY2FsaW5nID0gVmVjdG9yMy5Gcm9tQXJyYXkobm9kZS5zY2FsZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGJhYnlsb25Ob2RlLnBvc2l0aW9uID0gcG9zaXRpb247XHJcbiAgICAgICAgYmFieWxvbk5vZGUucm90YXRpb25RdWF0ZXJuaW9uID0gcm90YXRpb247XHJcbiAgICAgICAgYmFieWxvbk5vZGUuc2NhbGluZyA9IHNjYWxpbmc7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZFNraW5Bc3luYyhjb250ZXh0OiBzdHJpbmcsIG5vZGU6IElOb2RlLCBza2luOiBJU2tpbiwgYXNzaWduOiAoYmFieWxvblNrZWxldG9uOiBTa2VsZXRvbikgPT4gdm9pZCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghdGhpcy5fcGFyZW50LmxvYWRTa2lucykge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBleHRlbnNpb25Qcm9taXNlID0gdGhpcy5fZXh0ZW5zaW9uc0xvYWRTa2luQXN5bmMoY29udGV4dCwgbm9kZSwgc2tpbik7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvblByb21pc2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvblByb21pc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc2tpbi5fZGF0YSkge1xyXG4gICAgICAgICAgICBhc3NpZ24oc2tpbi5fZGF0YS5iYWJ5bG9uU2tlbGV0b24pO1xyXG4gICAgICAgICAgICByZXR1cm4gc2tpbi5fZGF0YS5wcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3Qgc2tlbGV0b25JZCA9IGBza2VsZXRvbiR7c2tpbi5pbmRleH1gO1xyXG4gICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gISF0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICBjb25zdCBiYWJ5bG9uU2tlbGV0b24gPSBuZXcgU2tlbGV0b24oc2tpbi5uYW1lIHx8IHNrZWxldG9uSWQsIHNrZWxldG9uSWQsIHRoaXMuX2JhYnlsb25TY2VuZSk7XHJcbiAgICAgICAgYmFieWxvblNrZWxldG9uLl9wYXJlbnRDb250YWluZXIgPSB0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9IGZhbHNlO1xyXG5cclxuICAgICAgICB0aGlzLl9sb2FkQm9uZXMoY29udGV4dCwgc2tpbiwgYmFieWxvblNrZWxldG9uKTtcclxuICAgICAgICBjb25zdCBwcm9taXNlID0gdGhpcy5fbG9hZFNraW5JbnZlcnNlQmluZE1hdHJpY2VzRGF0YUFzeW5jKGNvbnRleHQsIHNraW4pLnRoZW4oKGludmVyc2VCaW5kTWF0cmljZXNEYXRhKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUJvbmVNYXRyaWNlcyhiYWJ5bG9uU2tlbGV0b24sIGludmVyc2VCaW5kTWF0cmljZXNEYXRhKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgc2tpbi5fZGF0YSA9IHtcclxuICAgICAgICAgICAgYmFieWxvblNrZWxldG9uOiBiYWJ5bG9uU2tlbGV0b24sXHJcbiAgICAgICAgICAgIHByb21pc2U6IHByb21pc2UsXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgYXNzaWduKGJhYnlsb25Ta2VsZXRvbik7XHJcblxyXG4gICAgICAgIHJldHVybiBwcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRCb25lcyhjb250ZXh0OiBzdHJpbmcsIHNraW46IElTa2luLCBiYWJ5bG9uU2tlbGV0b246IFNrZWxldG9uKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHNraW4uc2tlbGV0b24gPT0gdW5kZWZpbmVkIHx8IHRoaXMuX3BhcmVudC5hbHdheXNDb21wdXRlU2tlbGV0b25Sb290Tm9kZSkge1xyXG4gICAgICAgICAgICBjb25zdCByb290Tm9kZSA9IHRoaXMuX2ZpbmRTa2VsZXRvblJvb3ROb2RlKGAke2NvbnRleHR9L2pvaW50c2AsIHNraW4uam9pbnRzKTtcclxuICAgICAgICAgICAgaWYgKHJvb3ROb2RlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2tpbi5za2VsZXRvbiA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2tpbi5za2VsZXRvbiA9IHJvb3ROb2RlLmluZGV4O1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpc1BhcmVudCA9IChhOiBJTm9kZSwgYjogSU5vZGUpOiBib29sZWFuID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IGIucGFyZW50OyBiID0gYi5wYXJlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiLnBhcmVudCA9PT0gYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2tlbGV0b25Ob2RlID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9za2VsZXRvbmAsIHRoaXMuX2dsdGYubm9kZXMsIHNraW4uc2tlbGV0b24pO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChza2VsZXRvbk5vZGUgIT09IHJvb3ROb2RlICYmICFpc1BhcmVudChza2VsZXRvbk5vZGUsIHJvb3ROb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuV2FybihgJHtjb250ZXh0fS9za2VsZXRvbjogT3ZlcnJpZGluZyB3aXRoIG5lYXJlc3QgY29tbW9uIGFuY2VzdG9yIGFzIHNrZWxldG9uIG5vZGUgaXMgbm90IGEgY29tbW9uIHJvb3RgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2tpbi5za2VsZXRvbiA9IHJvb3ROb2RlLmluZGV4O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIExvZ2dlci5XYXJuKGAke2NvbnRleHR9OiBGYWlsZWQgdG8gZmluZCBjb21tb24gcm9vdGApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBiYWJ5bG9uQm9uZXM6IHsgW2luZGV4OiBudW1iZXJdOiBCb25lIH0gPSB7fTtcclxuICAgICAgICBmb3IgKGNvbnN0IGluZGV4IG9mIHNraW4uam9pbnRzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG5vZGUgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L2pvaW50cy8ke2luZGV4fWAsIHRoaXMuX2dsdGYubm9kZXMsIGluZGV4KTtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZEJvbmUobm9kZSwgc2tpbiwgYmFieWxvblNrZWxldG9uLCBiYWJ5bG9uQm9uZXMpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9maW5kU2tlbGV0b25Sb290Tm9kZShjb250ZXh0OiBzdHJpbmcsIGpvaW50czogQXJyYXk8bnVtYmVyPik6IE51bGxhYmxlPElOb2RlPiB7XHJcbiAgICAgICAgaWYgKGpvaW50cy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwYXRoczogeyBbam9pbnQ6IG51bWJlcl06IEFycmF5PElOb2RlPiB9ID0ge307XHJcbiAgICAgICAgZm9yIChjb25zdCBpbmRleCBvZiBqb2ludHMpIHtcclxuICAgICAgICAgICAgY29uc3QgcGF0aDogSU5vZGVbXSA9IFtdO1xyXG4gICAgICAgICAgICBsZXQgbm9kZSA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vJHtpbmRleH1gLCB0aGlzLl9nbHRmLm5vZGVzLCBpbmRleCk7XHJcbiAgICAgICAgICAgIHdoaWxlIChub2RlLmluZGV4ICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgcGF0aC51bnNoaWZ0KG5vZGUpO1xyXG4gICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50ITtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBwYXRoc1tpbmRleF0gPSBwYXRoO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IHJvb3ROb2RlOiBOdWxsYWJsZTxJTm9kZT4gPSBudWxsO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyA7ICsraSkge1xyXG4gICAgICAgICAgICBsZXQgcGF0aCA9IHBhdGhzW2pvaW50c1swXV07XHJcbiAgICAgICAgICAgIGlmIChpID49IHBhdGgubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcm9vdE5vZGU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IG5vZGUgPSBwYXRoW2ldO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMTsgaiA8IGpvaW50cy5sZW5ndGg7ICsraikge1xyXG4gICAgICAgICAgICAgICAgcGF0aCA9IHBhdGhzW2pvaW50c1tqXV07XHJcbiAgICAgICAgICAgICAgICBpZiAoaSA+PSBwYXRoLmxlbmd0aCB8fCBub2RlICE9PSBwYXRoW2ldKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJvb3ROb2RlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByb290Tm9kZSA9IG5vZGU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRCb25lKG5vZGU6IElOb2RlLCBza2luOiBJU2tpbiwgYmFieWxvblNrZWxldG9uOiBTa2VsZXRvbiwgYmFieWxvbkJvbmVzOiB7IFtpbmRleDogbnVtYmVyXTogQm9uZSB9KTogQm9uZSB7XHJcbiAgICAgICAgbm9kZS5faXNKb2ludCA9IHRydWU7XHJcblxyXG4gICAgICAgIGxldCBiYWJ5bG9uQm9uZSA9IGJhYnlsb25Cb25lc1tub2RlLmluZGV4XTtcclxuICAgICAgICBpZiAoYmFieWxvbkJvbmUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGJhYnlsb25Cb25lO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IHBhcmVudEJhYnlsb25Cb25lOiBOdWxsYWJsZTxCb25lPiA9IG51bGw7XHJcbiAgICAgICAgaWYgKG5vZGUuaW5kZXggIT09IHNraW4uc2tlbGV0b24pIHtcclxuICAgICAgICAgICAgaWYgKG5vZGUucGFyZW50ICYmIG5vZGUucGFyZW50LmluZGV4ICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgcGFyZW50QmFieWxvbkJvbmUgPSB0aGlzLl9sb2FkQm9uZShub2RlLnBhcmVudCwgc2tpbiwgYmFieWxvblNrZWxldG9uLCBiYWJ5bG9uQm9uZXMpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHNraW4uc2tlbGV0b24gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgTG9nZ2VyLldhcm4oYC9za2lucy8ke3NraW4uaW5kZXh9L3NrZWxldG9uOiBTa2VsZXRvbiBub2RlIGlzIG5vdCBhIGNvbW1vbiByb290YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGJvbmVJbmRleCA9IHNraW4uam9pbnRzLmluZGV4T2Yobm9kZS5pbmRleCk7XHJcbiAgICAgICAgYmFieWxvbkJvbmUgPSBuZXcgQm9uZShub2RlLm5hbWUgfHwgYGpvaW50JHtub2RlLmluZGV4fWAsIGJhYnlsb25Ta2VsZXRvbiwgcGFyZW50QmFieWxvbkJvbmUsIHRoaXMuX2dldE5vZGVNYXRyaXgobm9kZSksIG51bGwsIG51bGwsIGJvbmVJbmRleCk7XHJcbiAgICAgICAgYmFieWxvbkJvbmVzW25vZGUuaW5kZXhdID0gYmFieWxvbkJvbmU7XHJcblxyXG4gICAgICAgIC8vIFdhaXQgdW50aWwgdGhlIHNjZW5lIGlzIGxvYWRlZCB0byBlbnN1cmUgdGhlIHRyYW5zZm9ybSBub2RlcyBhcmUgbG9hZGVkLlxyXG4gICAgICAgIHRoaXMuX3Bvc3RTY2VuZUxvYWRBY3Rpb25zLnB1c2goKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyBMaW5rIHRoZSBCYWJ5bG9uIGJvbmUgd2l0aCB0aGUgY29ycmVzcG9uZGluZyBCYWJ5bG9uIHRyYW5zZm9ybSBub2RlLlxyXG4gICAgICAgICAgICAvLyBBIGdsVEYgam9pbnQgaXMgYSBwb2ludGVyIHRvIGEgZ2xURiBub2RlIGluIHRoZSBnbFRGIG5vZGUgaGllcmFyY2h5IHNpbWlsYXIgdG8gVW5pdHkzRC5cclxuICAgICAgICAgICAgYmFieWxvbkJvbmUubGlua1RyYW5zZm9ybU5vZGUobm9kZS5fYmFieWxvblRyYW5zZm9ybU5vZGUhKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGJhYnlsb25Cb25lO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRTa2luSW52ZXJzZUJpbmRNYXRyaWNlc0RhdGFBc3luYyhjb250ZXh0OiBzdHJpbmcsIHNraW46IElTa2luKTogUHJvbWlzZTxOdWxsYWJsZTxGbG9hdDMyQXJyYXk+PiB7XHJcbiAgICAgICAgaWYgKHNraW4uaW52ZXJzZUJpbmRNYXRyaWNlcyA9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGFjY2Vzc29yID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9pbnZlcnNlQmluZE1hdHJpY2VzYCwgdGhpcy5fZ2x0Zi5hY2Nlc3NvcnMsIHNraW4uaW52ZXJzZUJpbmRNYXRyaWNlcyk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRGbG9hdEFjY2Vzc29yQXN5bmMoYC9hY2Nlc3NvcnMvJHthY2Nlc3Nvci5pbmRleH1gLCBhY2Nlc3Nvcik7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfdXBkYXRlQm9uZU1hdHJpY2VzKGJhYnlsb25Ta2VsZXRvbjogU2tlbGV0b24sIGludmVyc2VCaW5kTWF0cmljZXNEYXRhOiBOdWxsYWJsZTxGbG9hdDMyQXJyYXk+KTogdm9pZCB7XHJcbiAgICAgICAgZm9yIChjb25zdCBiYWJ5bG9uQm9uZSBvZiBiYWJ5bG9uU2tlbGV0b24uYm9uZXMpIHtcclxuICAgICAgICAgICAgY29uc3QgYmFzZU1hdHJpeCA9IE1hdHJpeC5JZGVudGl0eSgpO1xyXG4gICAgICAgICAgICBjb25zdCBib25lSW5kZXggPSBiYWJ5bG9uQm9uZS5faW5kZXghO1xyXG4gICAgICAgICAgICBpZiAoaW52ZXJzZUJpbmRNYXRyaWNlc0RhdGEgJiYgYm9uZUluZGV4ICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgTWF0cml4LkZyb21BcnJheVRvUmVmKGludmVyc2VCaW5kTWF0cmljZXNEYXRhLCBib25lSW5kZXggKiAxNiwgYmFzZU1hdHJpeCk7XHJcbiAgICAgICAgICAgICAgICBiYXNlTWF0cml4LmludmVydFRvUmVmKGJhc2VNYXRyaXgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBiYWJ5bG9uUGFyZW50Qm9uZSA9IGJhYnlsb25Cb25lLmdldFBhcmVudCgpO1xyXG4gICAgICAgICAgICBpZiAoYmFieWxvblBhcmVudEJvbmUpIHtcclxuICAgICAgICAgICAgICAgIGJhc2VNYXRyaXgubXVsdGlwbHlUb1JlZihiYWJ5bG9uUGFyZW50Qm9uZS5nZXRBYnNvbHV0ZUludmVyc2VCaW5kTWF0cml4KCksIGJhc2VNYXRyaXgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBiYWJ5bG9uQm9uZS51cGRhdGVNYXRyaXgoYmFzZU1hdHJpeCwgZmFsc2UsIGZhbHNlKTtcclxuICAgICAgICAgICAgYmFieWxvbkJvbmUuX3VwZGF0ZUFic29sdXRlQmluZE1hdHJpY2VzKHVuZGVmaW5lZCwgZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9nZXROb2RlTWF0cml4KG5vZGU6IElOb2RlKTogTWF0cml4IHtcclxuICAgICAgICByZXR1cm4gbm9kZS5tYXRyaXhcclxuICAgICAgICAgICAgPyBNYXRyaXguRnJvbUFycmF5KG5vZGUubWF0cml4KVxyXG4gICAgICAgICAgICA6IE1hdHJpeC5Db21wb3NlKFxyXG4gICAgICAgICAgICAgICAgICBub2RlLnNjYWxlID8gVmVjdG9yMy5Gcm9tQXJyYXkobm9kZS5zY2FsZSkgOiBWZWN0b3IzLk9uZSgpLFxyXG4gICAgICAgICAgICAgICAgICBub2RlLnJvdGF0aW9uID8gUXVhdGVybmlvbi5Gcm9tQXJyYXkobm9kZS5yb3RhdGlvbikgOiBRdWF0ZXJuaW9uLklkZW50aXR5KCksXHJcbiAgICAgICAgICAgICAgICAgIG5vZGUudHJhbnNsYXRpb24gPyBWZWN0b3IzLkZyb21BcnJheShub2RlLnRyYW5zbGF0aW9uKSA6IFZlY3RvcjMuWmVybygpXHJcbiAgICAgICAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIExvYWRzIGEgZ2xURiBjYW1lcmEuXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gY2FtZXJhIFRoZSBnbFRGIGNhbWVyYSBwcm9wZXJ0eVxyXG4gICAgICogQHBhcmFtIGFzc2lnbiBBIGZ1bmN0aW9uIGNhbGxlZCBzeW5jaHJvbm91c2x5IGFmdGVyIHBhcnNpbmcgdGhlIGdsVEYgcHJvcGVydGllc1xyXG4gICAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgbG9hZGVkIEJhYnlsb24gY2FtZXJhIHdoZW4gdGhlIGxvYWQgaXMgY29tcGxldGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRDYW1lcmFBc3luYyhjb250ZXh0OiBzdHJpbmcsIGNhbWVyYTogSUNhbWVyYSwgYXNzaWduOiAoYmFieWxvbkNhbWVyYTogQ2FtZXJhKSA9PiB2b2lkID0gKCkgPT4ge30pOiBQcm9taXNlPENhbWVyYT4ge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvblByb21pc2UgPSB0aGlzLl9leHRlbnNpb25zTG9hZENhbWVyYUFzeW5jKGNvbnRleHQsIGNhbWVyYSwgYXNzaWduKTtcclxuICAgICAgICBpZiAoZXh0ZW5zaW9uUHJvbWlzZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZXh0ZW5zaW9uUHJvbWlzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dW5rbm93bj4+KCk7XHJcblxyXG4gICAgICAgIHRoaXMubG9nT3BlbihgJHtjb250ZXh0fSAke2NhbWVyYS5uYW1lIHx8IFwiXCJ9YCk7XHJcblxyXG4gICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gISF0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICBjb25zdCBiYWJ5bG9uQ2FtZXJhID0gbmV3IEZyZWVDYW1lcmEoY2FtZXJhLm5hbWUgfHwgYGNhbWVyYSR7Y2FtZXJhLmluZGV4fWAsIFZlY3RvcjMuWmVybygpLCB0aGlzLl9iYWJ5bG9uU2NlbmUsIGZhbHNlKTtcclxuICAgICAgICBiYWJ5bG9uQ2FtZXJhLl9wYXJlbnRDb250YWluZXIgPSB0aGlzLl9hc3NldENvbnRhaW5lcjtcclxuICAgICAgICB0aGlzLl9iYWJ5bG9uU2NlbmUuX2Jsb2NrRW50aXR5Q29sbGVjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgIGJhYnlsb25DYW1lcmEuaWdub3JlUGFyZW50U2NhbGluZyA9IHRydWU7XHJcbiAgICAgICAgY2FtZXJhLl9iYWJ5bG9uQ2FtZXJhID0gYmFieWxvbkNhbWVyYTtcclxuXHJcbiAgICAgICAgLy8gUm90YXRpb24gYnkgMTgwIGFzIGdsVEYgaGFzIGEgZGlmZmVyZW50IGNvbnZlbnRpb24gdGhhbiBCYWJ5bG9uLlxyXG4gICAgICAgIGJhYnlsb25DYW1lcmEucm90YXRpb24uc2V0KDAsIE1hdGguUEksIDApO1xyXG5cclxuICAgICAgICBzd2l0Y2ggKGNhbWVyYS50eXBlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgQ2FtZXJhVHlwZS5QRVJTUEVDVElWRToge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcGVyc3BlY3RpdmUgPSBjYW1lcmEucGVyc3BlY3RpdmU7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXBlcnNwZWN0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBDYW1lcmEgcGVyc3BlY3RpdmUgcHJvcGVydGllcyBhcmUgbWlzc2luZ2ApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGJhYnlsb25DYW1lcmEuZm92ID0gcGVyc3BlY3RpdmUueWZvdjtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25DYW1lcmEubWluWiA9IHBlcnNwZWN0aXZlLnpuZWFyO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbkNhbWVyYS5tYXhaID0gcGVyc3BlY3RpdmUuemZhciB8fCAwO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBDYW1lcmFUeXBlLk9SVEhPR1JBUEhJQzoge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFjYW1lcmEub3J0aG9ncmFwaGljKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBDYW1lcmEgb3J0aG9ncmFwaGljIHByb3BlcnRpZXMgYXJlIG1pc3NpbmdgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uQ2FtZXJhLm1vZGUgPSBDYW1lcmEuT1JUSE9HUkFQSElDX0NBTUVSQTtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25DYW1lcmEub3J0aG9MZWZ0ID0gLWNhbWVyYS5vcnRob2dyYXBoaWMueG1hZztcclxuICAgICAgICAgICAgICAgIGJhYnlsb25DYW1lcmEub3J0aG9SaWdodCA9IGNhbWVyYS5vcnRob2dyYXBoaWMueG1hZztcclxuICAgICAgICAgICAgICAgIGJhYnlsb25DYW1lcmEub3J0aG9Cb3R0b20gPSAtY2FtZXJhLm9ydGhvZ3JhcGhpYy55bWFnO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbkNhbWVyYS5vcnRob1RvcCA9IGNhbWVyYS5vcnRob2dyYXBoaWMueW1hZztcclxuICAgICAgICAgICAgICAgIGJhYnlsb25DYW1lcmEubWluWiA9IGNhbWVyYS5vcnRob2dyYXBoaWMuem5lYXI7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uQ2FtZXJhLm1heFogPSBjYW1lcmEub3J0aG9ncmFwaGljLnpmYXI7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBkZWZhdWx0OiB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IEludmFsaWQgY2FtZXJhIHR5cGUgKCR7Y2FtZXJhLnR5cGV9KWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBHTFRGTG9hZGVyLkFkZFBvaW50ZXJNZXRhZGF0YShiYWJ5bG9uQ2FtZXJhLCBjb250ZXh0KTtcclxuICAgICAgICB0aGlzLl9wYXJlbnQub25DYW1lcmFMb2FkZWRPYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyhiYWJ5bG9uQ2FtZXJhKTtcclxuICAgICAgICBhc3NpZ24oYmFieWxvbkNhbWVyYSk7XHJcblxyXG4gICAgICAgIHRoaXMubG9nQ2xvc2UoKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIGJhYnlsb25DYW1lcmE7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZEFuaW1hdGlvbnNBc3luYygpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBjb25zdCBhbmltYXRpb25zID0gdGhpcy5fZ2x0Zi5hbmltYXRpb25zO1xyXG4gICAgICAgIGlmICghYW5pbWF0aW9ucykge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHZvaWQ+PigpO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgYW5pbWF0aW9ucy5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICAgICAgY29uc3QgYW5pbWF0aW9uID0gYW5pbWF0aW9uc1tpbmRleF07XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRBbmltYXRpb25Bc3luYyhgL2FuaW1hdGlvbnMvJHthbmltYXRpb24uaW5kZXh9YCwgYW5pbWF0aW9uKS50aGVuKChhbmltYXRpb25Hcm91cCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIERlbGV0ZSB0aGUgYW5pbWF0aW9uIGdyb3VwIGlmIGl0IGVuZGVkIHVwIG5vdCBoYXZpbmcgYW55IGFuaW1hdGlvbnMgaW4gaXQuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFuaW1hdGlvbkdyb3VwLnRhcmdldGVkQW5pbWF0aW9ucy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uR3JvdXAuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9hZHMgYSBnbFRGIGFuaW1hdGlvbi5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBhbmltYXRpb24gVGhlIGdsVEYgYW5pbWF0aW9uIHByb3BlcnR5XHJcbiAgICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBsb2FkZWQgQmFieWxvbiBhbmltYXRpb24gZ3JvdXAgd2hlbiB0aGUgbG9hZCBpcyBjb21wbGV0ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZEFuaW1hdGlvbkFzeW5jKGNvbnRleHQ6IHN0cmluZywgYW5pbWF0aW9uOiBJQW5pbWF0aW9uKTogUHJvbWlzZTxBbmltYXRpb25Hcm91cD4ge1xyXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLl9leHRlbnNpb25zTG9hZEFuaW1hdGlvbkFzeW5jKGNvbnRleHQsIGFuaW1hdGlvbik7XHJcbiAgICAgICAgaWYgKHByb21pc2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXHJcbiAgICAgICAgcmV0dXJuIGltcG9ydChcImNvcmUvQW5pbWF0aW9ucy9hbmltYXRpb25Hcm91cFwiKS50aGVuKCh7IEFuaW1hdGlvbkdyb3VwIH0pID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSAhIXRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgICAgICBjb25zdCBiYWJ5bG9uQW5pbWF0aW9uR3JvdXAgPSBuZXcgQW5pbWF0aW9uR3JvdXAoYW5pbWF0aW9uLm5hbWUgfHwgYGFuaW1hdGlvbiR7YW5pbWF0aW9uLmluZGV4fWAsIHRoaXMuX2JhYnlsb25TY2VuZSk7XHJcbiAgICAgICAgICAgIGJhYnlsb25BbmltYXRpb25Hcm91cC5fcGFyZW50Q29udGFpbmVyID0gdGhpcy5fYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgICAgIHRoaXMuX2JhYnlsb25TY2VuZS5fYmxvY2tFbnRpdHlDb2xsZWN0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGFuaW1hdGlvbi5fYmFieWxvbkFuaW1hdGlvbkdyb3VwID0gYmFieWxvbkFuaW1hdGlvbkdyb3VwO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTx1bmtub3duPj4oKTtcclxuXHJcbiAgICAgICAgICAgIEFycmF5SXRlbS5Bc3NpZ24oYW5pbWF0aW9uLmNoYW5uZWxzKTtcclxuICAgICAgICAgICAgQXJyYXlJdGVtLkFzc2lnbihhbmltYXRpb24uc2FtcGxlcnMpO1xyXG5cclxuICAgICAgICAgICAgZm9yIChjb25zdCBjaGFubmVsIG9mIGFuaW1hdGlvbi5jaGFubmVscykge1xyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sb2FkQW5pbWF0aW9uQ2hhbm5lbEFzeW5jKGAke2NvbnRleHR9L2NoYW5uZWxzLyR7Y2hhbm5lbC5pbmRleH1gLCBjb250ZXh0LCBhbmltYXRpb24sIGNoYW5uZWwsIChiYWJ5bG9uVGFyZ2V0LCBiYWJ5bG9uQW5pbWF0aW9uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25UYXJnZXQuYW5pbWF0aW9ucyA9IGJhYnlsb25UYXJnZXQuYW5pbWF0aW9ucyB8fCBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvblRhcmdldC5hbmltYXRpb25zLnB1c2goYmFieWxvbkFuaW1hdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25BbmltYXRpb25Hcm91cC5hZGRUYXJnZXRlZEFuaW1hdGlvbihiYWJ5bG9uQW5pbWF0aW9uLCBiYWJ5bG9uVGFyZ2V0KTtcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25BbmltYXRpb25Hcm91cC5ub3JtYWxpemUoMCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYmFieWxvbkFuaW1hdGlvbkdyb3VwO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBoaWRkZW5cclxuICAgICAqIExvYWRzIGEgZ2xURiBhbmltYXRpb24gY2hhbm5lbC5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBhbmltYXRpb25Db250ZXh0IFRoZSBjb250ZXh0IG9mIHRoZSBhbmltYXRpb24gd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIGFuaW1hdGlvbiBUaGUgZ2xURiBhbmltYXRpb24gcHJvcGVydHlcclxuICAgICAqIEBwYXJhbSBjaGFubmVsIFRoZSBnbFRGIGFuaW1hdGlvbiBjaGFubmVsIHByb3BlcnR5XHJcbiAgICAgKiBAcGFyYW0gb25Mb2FkIENhbGxlZCBmb3IgZWFjaCBhbmltYXRpb24gbG9hZGVkXHJcbiAgICAgKiBAcmV0dXJucyBBIHZvaWQgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGxvYWQgaXMgY29tcGxldGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9sb2FkQW5pbWF0aW9uQ2hhbm5lbEFzeW5jKFxyXG4gICAgICAgIGNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBhbmltYXRpb25Db250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgYW5pbWF0aW9uOiBJQW5pbWF0aW9uLFxyXG4gICAgICAgIGNoYW5uZWw6IElBbmltYXRpb25DaGFubmVsLFxyXG4gICAgICAgIG9uTG9hZDogKGJhYnlsb25BbmltYXRhYmxlOiBJQW5pbWF0YWJsZSwgYmFieWxvbkFuaW1hdGlvbjogQW5pbWF0aW9uKSA9PiB2b2lkXHJcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBjb25zdCBwcm9taXNlID0gdGhpcy5fZXh0ZW5zaW9uc0xvYWRBbmltYXRpb25DaGFubmVsQXN5bmMoY29udGV4dCwgYW5pbWF0aW9uQ29udGV4dCwgYW5pbWF0aW9uLCBjaGFubmVsLCBvbkxvYWQpO1xyXG4gICAgICAgIGlmIChwcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGNoYW5uZWwudGFyZ2V0Lm5vZGUgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHRhcmdldE5vZGUgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L3RhcmdldC9ub2RlYCwgdGhpcy5fZ2x0Zi5ub2RlcywgY2hhbm5lbC50YXJnZXQubm9kZSk7XHJcbiAgICAgICAgY29uc3QgY2hhbm5lbFRhcmdldFBhdGggPSBjaGFubmVsLnRhcmdldC5wYXRoO1xyXG4gICAgICAgIGNvbnN0IHBhdGhJc1dlaWdodHMgPSBjaGFubmVsVGFyZ2V0UGF0aCA9PT0gQW5pbWF0aW9uQ2hhbm5lbFRhcmdldFBhdGguV0VJR0hUUztcclxuXHJcbiAgICAgICAgLy8gSWdub3JlIGFuaW1hdGlvbnMgdGhhdCBoYXZlIG5vIGFuaW1hdGlvbiB0YXJnZXRzLlxyXG4gICAgICAgIGlmICgocGF0aElzV2VpZ2h0cyAmJiAhdGFyZ2V0Tm9kZS5fbnVtTW9ycGhUYXJnZXRzKSB8fCAoIXBhdGhJc1dlaWdodHMgJiYgIXRhcmdldE5vZGUuX2JhYnlsb25UcmFuc2Zvcm1Ob2RlKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBEb24ndCBsb2FkIG5vZGUgYW5pbWF0aW9ucyBpZiBkaXNhYmxlZC5cclxuICAgICAgICBpZiAoIXRoaXMuX3BhcmVudC5sb2FkTm9kZUFuaW1hdGlvbnMgJiYgIXBhdGhJc1dlaWdodHMgJiYgIXRhcmdldE5vZGUuX2lzSm9pbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IHByb3BlcnRpZXM6IEFycmF5PEFuaW1hdGlvblByb3BlcnR5SW5mbz47XHJcbiAgICAgICAgc3dpdGNoIChjaGFubmVsVGFyZ2V0UGF0aCkge1xyXG4gICAgICAgICAgICBjYXNlIEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLlRSQU5TTEFUSU9OOiB7XHJcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzID0gbm9kZUFuaW1hdGlvbkRhdGEudHJhbnNsYXRpb247XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLlJPVEFUSU9OOiB7XHJcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzID0gbm9kZUFuaW1hdGlvbkRhdGEucm90YXRpb247XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLlNDQUxFOiB7XHJcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzID0gbm9kZUFuaW1hdGlvbkRhdGEuc2NhbGU7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIEFuaW1hdGlvbkNoYW5uZWxUYXJnZXRQYXRoLldFSUdIVFM6IHtcclxuICAgICAgICAgICAgICAgIHByb3BlcnRpZXMgPSBub2RlQW5pbWF0aW9uRGF0YS53ZWlnaHRzO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZGVmYXVsdDoge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9L3RhcmdldC9wYXRoOiBJbnZhbGlkIHZhbHVlICgke2NoYW5uZWwudGFyZ2V0LnBhdGh9KWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB0YXJnZXRJbmZvOiBJT2JqZWN0SW5mbzxBbmltYXRpb25Qcm9wZXJ0eUluZm9bXT4gPSB7XHJcbiAgICAgICAgICAgIG9iamVjdDogdGFyZ2V0Tm9kZSxcclxuICAgICAgICAgICAgaW5mbzogcHJvcGVydGllcyxcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fbG9hZEFuaW1hdGlvbkNoYW5uZWxGcm9tVGFyZ2V0SW5mb0FzeW5jKGNvbnRleHQsIGFuaW1hdGlvbkNvbnRleHQsIGFuaW1hdGlvbiwgY2hhbm5lbCwgdGFyZ2V0SW5mbywgb25Mb2FkKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBoaWRkZW5cclxuICAgICAqIExvYWRzIGEgZ2xURiBhbmltYXRpb24gY2hhbm5lbC5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBhbmltYXRpb25Db250ZXh0IFRoZSBjb250ZXh0IG9mIHRoZSBhbmltYXRpb24gd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIGFuaW1hdGlvbiBUaGUgZ2xURiBhbmltYXRpb24gcHJvcGVydHlcclxuICAgICAqIEBwYXJhbSBjaGFubmVsIFRoZSBnbFRGIGFuaW1hdGlvbiBjaGFubmVsIHByb3BlcnR5XHJcbiAgICAgKiBAcGFyYW0gdGFyZ2V0SW5mbyBUaGUgZ2xURiB0YXJnZXQgYW5kIHByb3BlcnRpZXNcclxuICAgICAqIEBwYXJhbSBvbkxvYWQgQ2FsbGVkIGZvciBlYWNoIGFuaW1hdGlvbiBsb2FkZWRcclxuICAgICAqIEByZXR1cm5zIEEgdm9pZCBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgbG9hZCBpcyBjb21wbGV0ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvYWRBbmltYXRpb25DaGFubmVsRnJvbVRhcmdldEluZm9Bc3luYyhcclxuICAgICAgICBjb250ZXh0OiBzdHJpbmcsXHJcbiAgICAgICAgYW5pbWF0aW9uQ29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIGFuaW1hdGlvbjogSUFuaW1hdGlvbixcclxuICAgICAgICBjaGFubmVsOiBJQW5pbWF0aW9uQ2hhbm5lbCxcclxuICAgICAgICB0YXJnZXRJbmZvOiBJT2JqZWN0SW5mbzxBbmltYXRpb25Qcm9wZXJ0eUluZm9bXT4sXHJcbiAgICAgICAgb25Mb2FkOiAoYmFieWxvbkFuaW1hdGFibGU6IElBbmltYXRhYmxlLCBiYWJ5bG9uQW5pbWF0aW9uOiBBbmltYXRpb24pID0+IHZvaWRcclxuICAgICk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGNvbnN0IGZwcyA9IHRoaXMucGFyZW50LnRhcmdldEZwcztcclxuICAgICAgICBjb25zdCBpbnZmcHMgPSAxIC8gZnBzO1xyXG5cclxuICAgICAgICBjb25zdCBzYW1wbGVyID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9zYW1wbGVyYCwgYW5pbWF0aW9uLnNhbXBsZXJzLCBjaGFubmVsLnNhbXBsZXIpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkQW5pbWF0aW9uU2FtcGxlckFzeW5jKGAke2FuaW1hdGlvbkNvbnRleHR9L3NhbXBsZXJzLyR7Y2hhbm5lbC5zYW1wbGVyfWAsIHNhbXBsZXIpLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgbGV0IG51bUFuaW1hdGlvbnMgPSAwO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gdGFyZ2V0SW5mby5vYmplY3Q7XHJcbiAgICAgICAgICAgIGNvbnN0IHByb3BlcnR5SW5mb3MgPSB0YXJnZXRJbmZvLmluZm87XHJcbiAgICAgICAgICAgIC8vIEV4dHJhY3QgdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWVzIGZyb20gdGhlIHJlYWQgdmFsdWUuXHJcbiAgICAgICAgICAgIC8vIEdMVEYgdmFsdWVzIG1heSBiZSBkaXNwYXRjaGVkIHRvIHNldmVyYWwgQmFieWxvbiBwcm9wZXJ0aWVzLlxyXG4gICAgICAgICAgICAvLyBGb3IgZXhhbXBsZSwgYmFzZUNvbG9yRmFjdG9yIFtgcmAsIGBnYCwgYGJgLCBgYWBdIGlzIGRpc3BhdGNoZWQgdG9cclxuICAgICAgICAgICAgLy8gLSBhbGJlZG9Db2xvciBhcyBDb2xvcjMoYHJgLCBgZ2AsIGBiYClcclxuICAgICAgICAgICAgLy8gLSBhbHBoYSBhcyBgYWBcclxuICAgICAgICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eUluZm8gb2YgcHJvcGVydHlJbmZvcykge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyaWRlID0gcHJvcGVydHlJbmZvLmdldFN0cmlkZSh0YXJnZXQpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaW5wdXQgPSBkYXRhLmlucHV0O1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0ID0gZGF0YS5vdXRwdXQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBrZXlzID0gbmV3IEFycmF5PElBbmltYXRpb25LZXk+KGlucHV0Lmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICBsZXQgb3V0cHV0T2Zmc2V0ID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGRhdGEuaW50ZXJwb2xhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uU1RFUDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaW5wdXQubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHByb3BlcnR5SW5mby5nZXRWYWx1ZSh0YXJnZXQsIG91dHB1dCwgb3V0cHV0T2Zmc2V0LCAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dE9mZnNldCArPSBzdHJpZGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5c1tpbmRleF0gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWU6IGlucHV0W2luZGV4XSAqIGZwcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJwb2xhdGlvbjogQW5pbWF0aW9uS2V5SW50ZXJwb2xhdGlvbi5TVEVQLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBBbmltYXRpb25TYW1wbGVySW50ZXJwb2xhdGlvbi5DVUJJQ1NQTElORToge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaW5wdXQubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpblRhbmdlbnQgPSBwcm9wZXJ0eUluZm8uZ2V0VmFsdWUodGFyZ2V0LCBvdXRwdXQsIG91dHB1dE9mZnNldCwgaW52ZnBzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dE9mZnNldCArPSBzdHJpZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHByb3BlcnR5SW5mby5nZXRWYWx1ZSh0YXJnZXQsIG91dHB1dCwgb3V0cHV0T2Zmc2V0LCAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dE9mZnNldCArPSBzdHJpZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvdXRUYW5nZW50ID0gcHJvcGVydHlJbmZvLmdldFZhbHVlKHRhcmdldCwgb3V0cHV0LCBvdXRwdXRPZmZzZXQsIGludmZwcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRPZmZzZXQgKz0gc3RyaWRlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleXNbaW5kZXhdID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lOiBpbnB1dFtpbmRleF0gKiBmcHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5UYW5nZW50OiBpblRhbmdlbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dFRhbmdlbnQ6IG91dFRhbmdlbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjYXNlIEFuaW1hdGlvblNhbXBsZXJJbnRlcnBvbGF0aW9uLkxJTkVBUjoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaW5wdXQubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHByb3BlcnR5SW5mby5nZXRWYWx1ZSh0YXJnZXQsIG91dHB1dCwgb3V0cHV0T2Zmc2V0LCAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dE9mZnNldCArPSBzdHJpZGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5c1tpbmRleF0gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWU6IGlucHV0W2luZGV4XSAqIGZwcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAob3V0cHV0T2Zmc2V0ID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBgJHthbmltYXRpb24ubmFtZSB8fCBgYW5pbWF0aW9uJHthbmltYXRpb24uaW5kZXh9YH1fY2hhbm5lbCR7Y2hhbm5lbC5pbmRleH1fJHtudW1BbmltYXRpb25zfWA7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvcGVydHlJbmZvLmJ1aWxkQW5pbWF0aW9ucyh0YXJnZXQsIG5hbWUsIGZwcywga2V5cywgKGJhYnlsb25BbmltYXRhYmxlLCBiYWJ5bG9uQW5pbWF0aW9uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICsrbnVtQW5pbWF0aW9ucztcclxuICAgICAgICAgICAgICAgICAgICAgICAgb25Mb2FkKGJhYnlsb25BbmltYXRhYmxlLCBiYWJ5bG9uQW5pbWF0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRBbmltYXRpb25TYW1wbGVyQXN5bmMoY29udGV4dDogc3RyaW5nLCBzYW1wbGVyOiBJQW5pbWF0aW9uU2FtcGxlcik6IFByb21pc2U8X0lBbmltYXRpb25TYW1wbGVyRGF0YT4ge1xyXG4gICAgICAgIGlmIChzYW1wbGVyLl9kYXRhKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVyLl9kYXRhO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgaW50ZXJwb2xhdGlvbiA9IHNhbXBsZXIuaW50ZXJwb2xhdGlvbiB8fCBBbmltYXRpb25TYW1wbGVySW50ZXJwb2xhdGlvbi5MSU5FQVI7XHJcbiAgICAgICAgc3dpdGNoIChpbnRlcnBvbGF0aW9uKSB7XHJcbiAgICAgICAgICAgIGNhc2UgQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uU1RFUDpcclxuICAgICAgICAgICAgY2FzZSBBbmltYXRpb25TYW1wbGVySW50ZXJwb2xhdGlvbi5MSU5FQVI6XHJcbiAgICAgICAgICAgIGNhc2UgQW5pbWF0aW9uU2FtcGxlckludGVycG9sYXRpb24uQ1VCSUNTUExJTkU6IHtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fS9pbnRlcnBvbGF0aW9uOiBJbnZhbGlkIHZhbHVlICgke3NhbXBsZXIuaW50ZXJwb2xhdGlvbn0pYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGlucHV0QWNjZXNzb3IgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L2lucHV0YCwgdGhpcy5fZ2x0Zi5hY2Nlc3NvcnMsIHNhbXBsZXIuaW5wdXQpO1xyXG4gICAgICAgIGNvbnN0IG91dHB1dEFjY2Vzc29yID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9vdXRwdXRgLCB0aGlzLl9nbHRmLmFjY2Vzc29ycywgc2FtcGxlci5vdXRwdXQpO1xyXG4gICAgICAgIHNhbXBsZXIuX2RhdGEgPSBQcm9taXNlLmFsbChbXHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRGbG9hdEFjY2Vzc29yQXN5bmMoYC9hY2Nlc3NvcnMvJHtpbnB1dEFjY2Vzc29yLmluZGV4fWAsIGlucHV0QWNjZXNzb3IpLFxyXG4gICAgICAgICAgICB0aGlzLl9sb2FkRmxvYXRBY2Nlc3NvckFzeW5jKGAvYWNjZXNzb3JzLyR7b3V0cHV0QWNjZXNzb3IuaW5kZXh9YCwgb3V0cHV0QWNjZXNzb3IpLFxyXG4gICAgICAgIF0pLnRoZW4oKFtpbnB1dERhdGEsIG91dHB1dERhdGFdKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBpbnB1dDogaW5wdXREYXRhLFxyXG4gICAgICAgICAgICAgICAgaW50ZXJwb2xhdGlvbjogaW50ZXJwb2xhdGlvbixcclxuICAgICAgICAgICAgICAgIG91dHB1dDogb3V0cHV0RGF0YSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHNhbXBsZXIuX2RhdGE7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMb2FkcyBhIGdsVEYgYnVmZmVyLlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIGJ1ZmZlciBUaGUgZ2xURiBidWZmZXIgcHJvcGVydHlcclxuICAgICAqIEBwYXJhbSBieXRlT2Zmc2V0IFRoZSBieXRlIG9mZnNldCB0byB1c2VcclxuICAgICAqIEBwYXJhbSBieXRlTGVuZ3RoIFRoZSBieXRlIGxlbmd0aCB0byB1c2VcclxuICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGxvYWRlZCBkYXRhIHdoZW4gdGhlIGxvYWQgaXMgY29tcGxldGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRCdWZmZXJBc3luYyhjb250ZXh0OiBzdHJpbmcsIGJ1ZmZlcjogSUJ1ZmZlciwgYnl0ZU9mZnNldDogbnVtYmVyLCBieXRlTGVuZ3RoOiBudW1iZXIpOiBQcm9taXNlPEFycmF5QnVmZmVyVmlldz4ge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvblByb21pc2UgPSB0aGlzLl9leHRlbnNpb25zTG9hZEJ1ZmZlckFzeW5jKGNvbnRleHQsIGJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvblByb21pc2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvblByb21pc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIWJ1ZmZlci5fZGF0YSkge1xyXG4gICAgICAgICAgICBpZiAoYnVmZmVyLnVyaSkge1xyXG4gICAgICAgICAgICAgICAgYnVmZmVyLl9kYXRhID0gdGhpcy5sb2FkVXJpQXN5bmMoYCR7Y29udGV4dH0vdXJpYCwgYnVmZmVyLCBidWZmZXIudXJpKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5fYmluKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBVcmkgaXMgbWlzc2luZyBvciB0aGUgYmluYXJ5IGdsVEYgaXMgbWlzc2luZyBpdHMgYmluYXJ5IGNodW5rYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgYnVmZmVyLl9kYXRhID0gdGhpcy5fYmluLnJlYWRBc3luYygwLCBidWZmZXIuYnl0ZUxlbmd0aCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBidWZmZXIuX2RhdGEudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGRhdGEuYnVmZmVyLCBkYXRhLmJ5dGVPZmZzZXQgKyBieXRlT2Zmc2V0LCBieXRlTGVuZ3RoKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiAke2UubWVzc2FnZX1gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9hZHMgYSBnbFRGIGJ1ZmZlciB2aWV3LlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIGJ1ZmZlclZpZXcgVGhlIGdsVEYgYnVmZmVyIHZpZXcgcHJvcGVydHlcclxuICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGxvYWRlZCBkYXRhIHdoZW4gdGhlIGxvYWQgaXMgY29tcGxldGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRCdWZmZXJWaWV3QXN5bmMoY29udGV4dDogc3RyaW5nLCBidWZmZXJWaWV3OiBJQnVmZmVyVmlldyk6IFByb21pc2U8QXJyYXlCdWZmZXJWaWV3PiB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uUHJvbWlzZSA9IHRoaXMuX2V4dGVuc2lvbnNMb2FkQnVmZmVyVmlld0FzeW5jKGNvbnRleHQsIGJ1ZmZlclZpZXcpO1xyXG4gICAgICAgIGlmIChleHRlbnNpb25Qcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHRlbnNpb25Qcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGJ1ZmZlclZpZXcuX2RhdGEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlclZpZXcuX2RhdGE7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBidWZmZXIgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L2J1ZmZlcmAsIHRoaXMuX2dsdGYuYnVmZmVycywgYnVmZmVyVmlldy5idWZmZXIpO1xyXG4gICAgICAgIGJ1ZmZlclZpZXcuX2RhdGEgPSB0aGlzLmxvYWRCdWZmZXJBc3luYyhgL2J1ZmZlcnMvJHtidWZmZXIuaW5kZXh9YCwgYnVmZmVyLCBidWZmZXJWaWV3LmJ5dGVPZmZzZXQgfHwgMCwgYnVmZmVyVmlldy5ieXRlTGVuZ3RoKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGJ1ZmZlclZpZXcuX2RhdGE7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZEFjY2Vzc29yQXN5bmMoY29udGV4dDogc3RyaW5nLCBhY2Nlc3NvcjogSUFjY2Vzc29yLCBjb25zdHJ1Y3RvcjogVHlwZWRBcnJheUNvbnN0cnVjdG9yKTogUHJvbWlzZTxBcnJheUJ1ZmZlclZpZXc+IHtcclxuICAgICAgICBpZiAoYWNjZXNzb3IuX2RhdGEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFjY2Vzc29yLl9kYXRhO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgbnVtQ29tcG9uZW50cyA9IEdMVEZMb2FkZXIuX0dldE51bUNvbXBvbmVudHMoY29udGV4dCwgYWNjZXNzb3IudHlwZSk7XHJcbiAgICAgICAgY29uc3QgYnl0ZVN0cmlkZSA9IG51bUNvbXBvbmVudHMgKiBWZXJ0ZXhCdWZmZXIuR2V0VHlwZUJ5dGVMZW5ndGgoYWNjZXNzb3IuY29tcG9uZW50VHlwZSk7XHJcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gbnVtQ29tcG9uZW50cyAqIGFjY2Vzc29yLmNvdW50O1xyXG5cclxuICAgICAgICBpZiAoYWNjZXNzb3IuYnVmZmVyVmlldyA9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgYWNjZXNzb3IuX2RhdGEgPSBQcm9taXNlLnJlc29sdmUobmV3IGNvbnN0cnVjdG9yKGxlbmd0aCkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlclZpZXcgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L2J1ZmZlclZpZXdgLCB0aGlzLl9nbHRmLmJ1ZmZlclZpZXdzLCBhY2Nlc3Nvci5idWZmZXJWaWV3KTtcclxuICAgICAgICAgICAgYWNjZXNzb3IuX2RhdGEgPSB0aGlzLmxvYWRCdWZmZXJWaWV3QXN5bmMoYC9idWZmZXJWaWV3cy8ke2J1ZmZlclZpZXcuaW5kZXh9YCwgYnVmZmVyVmlldykudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFjY2Vzc29yLmNvbXBvbmVudFR5cGUgPT09IEFjY2Vzc29yQ29tcG9uZW50VHlwZS5GTE9BVCAmJiAhYWNjZXNzb3Iubm9ybWFsaXplZCAmJiAoIWJ1ZmZlclZpZXcuYnl0ZVN0cmlkZSB8fCBidWZmZXJWaWV3LmJ5dGVTdHJpZGUgPT09IGJ5dGVTdHJpZGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEdMVEZMb2FkZXIuX0dldFR5cGVkQXJyYXkoY29udGV4dCwgYWNjZXNzb3IuY29tcG9uZW50VHlwZSwgZGF0YSwgYWNjZXNzb3IuYnl0ZU9mZnNldCwgbGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZWRBcnJheSA9IG5ldyBjb25zdHJ1Y3RvcihsZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIFZlcnRleEJ1ZmZlci5Gb3JFYWNoKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3Nvci5ieXRlT2Zmc2V0IHx8IDAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclZpZXcuYnl0ZVN0cmlkZSB8fCBieXRlU3RyaWRlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBudW1Db21wb25lbnRzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3Nvci5jb21wb25lbnRUeXBlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlZEFycmF5Lmxlbmd0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3Iubm9ybWFsaXplZCB8fCBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgKHZhbHVlLCBpbmRleCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZWRBcnJheVtpbmRleF0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVkQXJyYXk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGFjY2Vzc29yLnNwYXJzZSkge1xyXG4gICAgICAgICAgICBjb25zdCBzcGFyc2UgPSBhY2Nlc3Nvci5zcGFyc2U7XHJcbiAgICAgICAgICAgIGFjY2Vzc29yLl9kYXRhID0gYWNjZXNzb3IuX2RhdGEudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdHlwZWRBcnJheSA9IGRhdGEgYXMgVHlwZWRBcnJheUxpa2U7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpbmRpY2VzQnVmZmVyVmlldyA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vc3BhcnNlL2luZGljZXMvYnVmZmVyVmlld2AsIHRoaXMuX2dsdGYuYnVmZmVyVmlld3MsIHNwYXJzZS5pbmRpY2VzLmJ1ZmZlclZpZXcpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWVzQnVmZmVyVmlldyA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vc3BhcnNlL3ZhbHVlcy9idWZmZXJWaWV3YCwgdGhpcy5fZ2x0Zi5idWZmZXJWaWV3cywgc3BhcnNlLnZhbHVlcy5idWZmZXJWaWV3KTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkQnVmZmVyVmlld0FzeW5jKGAvYnVmZmVyVmlld3MvJHtpbmRpY2VzQnVmZmVyVmlldy5pbmRleH1gLCBpbmRpY2VzQnVmZmVyVmlldyksXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkQnVmZmVyVmlld0FzeW5jKGAvYnVmZmVyVmlld3MvJHt2YWx1ZXNCdWZmZXJWaWV3LmluZGV4fWAsIHZhbHVlc0J1ZmZlclZpZXcpLFxyXG4gICAgICAgICAgICAgICAgXSkudGhlbigoW2luZGljZXNEYXRhLCB2YWx1ZXNEYXRhXSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGljZXMgPSBHTFRGTG9hZGVyLl9HZXRUeXBlZEFycmF5KFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBgJHtjb250ZXh0fS9zcGFyc2UvaW5kaWNlc2AsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNwYXJzZS5pbmRpY2VzLmNvbXBvbmVudFR5cGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZGljZXNEYXRhLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzcGFyc2UuaW5kaWNlcy5ieXRlT2Zmc2V0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzcGFyc2UuY291bnRcclxuICAgICAgICAgICAgICAgICAgICApIGFzIEluZGljZXNBcnJheTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3BhcnNlTGVuZ3RoID0gbnVtQ29tcG9uZW50cyAqIHNwYXJzZS5jb3VudDtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgdmFsdWVzOiBUeXBlZEFycmF5TGlrZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFjY2Vzc29yLmNvbXBvbmVudFR5cGUgPT09IEFjY2Vzc29yQ29tcG9uZW50VHlwZS5GTE9BVCAmJiAhYWNjZXNzb3Iubm9ybWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBHTFRGTG9hZGVyLl9HZXRUeXBlZEFycmF5KGAke2NvbnRleHR9L3NwYXJzZS92YWx1ZXNgLCBhY2Nlc3Nvci5jb21wb25lbnRUeXBlLCB2YWx1ZXNEYXRhLCBzcGFyc2UudmFsdWVzLmJ5dGVPZmZzZXQsIHNwYXJzZUxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3BhcnNlRGF0YSA9IEdMVEZMb2FkZXIuX0dldFR5cGVkQXJyYXkoYCR7Y29udGV4dH0vc3BhcnNlL3ZhbHVlc2AsIGFjY2Vzc29yLmNvbXBvbmVudFR5cGUsIHZhbHVlc0RhdGEsIHNwYXJzZS52YWx1ZXMuYnl0ZU9mZnNldCwgc3BhcnNlTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gbmV3IGNvbnN0cnVjdG9yKHNwYXJzZUxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFZlcnRleEJ1ZmZlci5Gb3JFYWNoKHNwYXJzZURhdGEsIDAsIGJ5dGVTdHJpZGUsIG51bUNvbXBvbmVudHMsIGFjY2Vzc29yLmNvbXBvbmVudFR5cGUsIHZhbHVlcy5sZW5ndGgsIGFjY2Vzc29yLm5vcm1hbGl6ZWQgfHwgZmFsc2UsICh2YWx1ZSwgaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlc1tpbmRleF0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBsZXQgdmFsdWVzSW5kZXggPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGluZGljZXNJbmRleCA9IDA7IGluZGljZXNJbmRleCA8IGluZGljZXMubGVuZ3RoOyBpbmRpY2VzSW5kZXgrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZGF0YUluZGV4ID0gaW5kaWNlc1tpbmRpY2VzSW5kZXhdICogbnVtQ29tcG9uZW50cztcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgY29tcG9uZW50SW5kZXggPSAwOyBjb21wb25lbnRJbmRleCA8IG51bUNvbXBvbmVudHM7IGNvbXBvbmVudEluZGV4KyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVkQXJyYXlbZGF0YUluZGV4KytdID0gdmFsdWVzW3ZhbHVlc0luZGV4KytdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHlwZWRBcnJheTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBhY2Nlc3Nvci5fZGF0YTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvYWRGbG9hdEFjY2Vzc29yQXN5bmMoY29udGV4dDogc3RyaW5nLCBhY2Nlc3NvcjogSUFjY2Vzc29yKTogUHJvbWlzZTxGbG9hdDMyQXJyYXk+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbG9hZEFjY2Vzc29yQXN5bmMoY29udGV4dCwgYWNjZXNzb3IsIEZsb2F0MzJBcnJheSkgYXMgUHJvbWlzZTxGbG9hdDMyQXJyYXk+O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbG9hZEluZGljZXNBY2Nlc3NvckFzeW5jKGNvbnRleHQ6IHN0cmluZywgYWNjZXNzb3I6IElBY2Nlc3Nvcik6IFByb21pc2U8SW5kaWNlc0FycmF5PiB7XHJcbiAgICAgICAgaWYgKGFjY2Vzc29yLnR5cGUgIT09IEFjY2Vzc29yVHlwZS5TQ0FMQVIpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9L3R5cGU6IEludmFsaWQgdmFsdWUgJHthY2Nlc3Nvci50eXBlfWApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICBhY2Nlc3Nvci5jb21wb25lbnRUeXBlICE9PSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuVU5TSUdORURfQllURSAmJlxyXG4gICAgICAgICAgICBhY2Nlc3Nvci5jb21wb25lbnRUeXBlICE9PSBBY2Nlc3NvckNvbXBvbmVudFR5cGUuVU5TSUdORURfU0hPUlQgJiZcclxuICAgICAgICAgICAgYWNjZXNzb3IuY29tcG9uZW50VHlwZSAhPT0gQWNjZXNzb3JDb21wb25lbnRUeXBlLlVOU0lHTkVEX0lOVFxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH0vY29tcG9uZW50VHlwZTogSW52YWxpZCB2YWx1ZSAke2FjY2Vzc29yLmNvbXBvbmVudFR5cGV9YCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoYWNjZXNzb3IuX2RhdGEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFjY2Vzc29yLl9kYXRhIGFzIFByb21pc2U8SW5kaWNlc0FycmF5PjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChhY2Nlc3Nvci5zcGFyc2UpIHtcclxuICAgICAgICAgICAgY29uc3QgY29uc3RydWN0b3IgPSBHTFRGTG9hZGVyLl9HZXRUeXBlZEFycmF5Q29uc3RydWN0b3IoYCR7Y29udGV4dH0vY29tcG9uZW50VHlwZWAsIGFjY2Vzc29yLmNvbXBvbmVudFR5cGUpO1xyXG4gICAgICAgICAgICBhY2Nlc3Nvci5fZGF0YSA9IHRoaXMuX2xvYWRBY2Nlc3NvckFzeW5jKGNvbnRleHQsIGFjY2Vzc29yLCBjb25zdHJ1Y3Rvcik7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgYnVmZmVyVmlldyA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vYnVmZmVyVmlld2AsIHRoaXMuX2dsdGYuYnVmZmVyVmlld3MsIGFjY2Vzc29yLmJ1ZmZlclZpZXcpO1xyXG4gICAgICAgICAgICBhY2Nlc3Nvci5fZGF0YSA9IHRoaXMubG9hZEJ1ZmZlclZpZXdBc3luYyhgL2J1ZmZlclZpZXdzLyR7YnVmZmVyVmlldy5pbmRleH1gLCBidWZmZXJWaWV3KS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gR0xURkxvYWRlci5fR2V0VHlwZWRBcnJheShjb250ZXh0LCBhY2Nlc3Nvci5jb21wb25lbnRUeXBlLCBkYXRhLCBhY2Nlc3Nvci5ieXRlT2Zmc2V0LCBhY2Nlc3Nvci5jb3VudCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGFjY2Vzc29yLl9kYXRhIGFzIFByb21pc2U8SW5kaWNlc0FycmF5PjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvYWRWZXJ0ZXhCdWZmZXJWaWV3QXN5bmMoYnVmZmVyVmlldzogSUJ1ZmZlclZpZXcpOiBQcm9taXNlPEJ1ZmZlcj4ge1xyXG4gICAgICAgIGlmIChidWZmZXJWaWV3Ll9iYWJ5bG9uQnVmZmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBidWZmZXJWaWV3Ll9iYWJ5bG9uQnVmZmVyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZW5naW5lID0gdGhpcy5fYmFieWxvblNjZW5lLmdldEVuZ2luZSgpO1xyXG4gICAgICAgIGJ1ZmZlclZpZXcuX2JhYnlsb25CdWZmZXIgPSB0aGlzLmxvYWRCdWZmZXJWaWV3QXN5bmMoYC9idWZmZXJWaWV3cy8ke2J1ZmZlclZpZXcuaW5kZXh9YCwgYnVmZmVyVmlldykudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcihlbmdpbmUsIGRhdGEsIGZhbHNlKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGJ1ZmZlclZpZXcuX2JhYnlsb25CdWZmZXI7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9sb2FkVmVydGV4QWNjZXNzb3JBc3luYyhjb250ZXh0OiBzdHJpbmcsIGFjY2Vzc29yOiBJQWNjZXNzb3IsIGtpbmQ6IHN0cmluZyk6IFByb21pc2U8VmVydGV4QnVmZmVyPiB7XHJcbiAgICAgICAgaWYgKGFjY2Vzc29yLl9iYWJ5bG9uVmVydGV4QnVmZmVyPy5ba2luZF0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFjY2Vzc29yLl9iYWJ5bG9uVmVydGV4QnVmZmVyW2tpbmRdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFhY2Nlc3Nvci5fYmFieWxvblZlcnRleEJ1ZmZlcikge1xyXG4gICAgICAgICAgICBhY2Nlc3Nvci5fYmFieWxvblZlcnRleEJ1ZmZlciA9IHt9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZW5naW5lID0gdGhpcy5fYmFieWxvblNjZW5lLmdldEVuZ2luZSgpO1xyXG5cclxuICAgICAgICBpZiAoYWNjZXNzb3Iuc3BhcnNlIHx8IGFjY2Vzc29yLmJ1ZmZlclZpZXcgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGFjY2Vzc29yLl9iYWJ5bG9uVmVydGV4QnVmZmVyW2tpbmRdID0gdGhpcy5fbG9hZEZsb2F0QWNjZXNzb3JBc3luYyhjb250ZXh0LCBhY2Nlc3NvcikudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBWZXJ0ZXhCdWZmZXIoZW5naW5lLCBkYXRhLCBraW5kLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlclZpZXcgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L2J1ZmZlclZpZXdgLCB0aGlzLl9nbHRmLmJ1ZmZlclZpZXdzLCBhY2Nlc3Nvci5idWZmZXJWaWV3KTtcclxuICAgICAgICAgICAgYWNjZXNzb3IuX2JhYnlsb25WZXJ0ZXhCdWZmZXJba2luZF0gPSB0aGlzLl9sb2FkVmVydGV4QnVmZmVyVmlld0FzeW5jKGJ1ZmZlclZpZXcpLnRoZW4oKGJhYnlsb25CdWZmZXIpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG51bUNvbXBvbmVudHMgPSBHTFRGTG9hZGVyLl9HZXROdW1Db21wb25lbnRzKGNvbnRleHQsIGFjY2Vzc29yLnR5cGUpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBWZXJ0ZXhCdWZmZXIoXHJcbiAgICAgICAgICAgICAgICAgICAgZW5naW5lLFxyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25CdWZmZXIsXHJcbiAgICAgICAgICAgICAgICAgICAga2luZCxcclxuICAgICAgICAgICAgICAgICAgICBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyVmlldy5ieXRlU3RyaWRlLFxyXG4gICAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgICAgICAgICBhY2Nlc3Nvci5ieXRlT2Zmc2V0LFxyXG4gICAgICAgICAgICAgICAgICAgIG51bUNvbXBvbmVudHMsXHJcbiAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3IuY29tcG9uZW50VHlwZSxcclxuICAgICAgICAgICAgICAgICAgICBhY2Nlc3Nvci5ub3JtYWxpemVkLFxyXG4gICAgICAgICAgICAgICAgICAgIHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgICAgIHRydWVcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGFjY2Vzc29yLl9iYWJ5bG9uVmVydGV4QnVmZmVyW2tpbmRdO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvYWRNYXRlcmlhbE1ldGFsbGljUm91Z2huZXNzUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgcHJvcGVydGllczogSU1hdGVyaWFsUGJyTWV0YWxsaWNSb3VnaG5lc3MsIGJhYnlsb25NYXRlcmlhbDogTWF0ZXJpYWwpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAoIShiYWJ5bG9uTWF0ZXJpYWwgaW5zdGFuY2VvZiBQQlJNYXRlcmlhbCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBNYXRlcmlhbCB0eXBlIG5vdCBzdXBwb3J0ZWRgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dW5rbm93bj4+KCk7XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzKSB7XHJcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLmJhc2VDb2xvckZhY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmFsYmVkb0NvbG9yID0gQ29sb3IzLkZyb21BcnJheShwcm9wZXJ0aWVzLmJhc2VDb2xvckZhY3Rvcik7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxwaGEgPSBwcm9wZXJ0aWVzLmJhc2VDb2xvckZhY3RvclszXTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbGJlZG9Db2xvciA9IENvbG9yMy5XaGl0ZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwubWV0YWxsaWMgPSBwcm9wZXJ0aWVzLm1ldGFsbGljRmFjdG9yID09IHVuZGVmaW5lZCA/IDEgOiBwcm9wZXJ0aWVzLm1ldGFsbGljRmFjdG9yO1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwucm91Z2huZXNzID0gcHJvcGVydGllcy5yb3VnaG5lc3NGYWN0b3IgPT0gdW5kZWZpbmVkID8gMSA6IHByb3BlcnRpZXMucm91Z2huZXNzRmFjdG9yO1xyXG5cclxuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMuYmFzZUNvbG9yVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L2Jhc2VDb2xvclRleHR1cmVgLCBwcm9wZXJ0aWVzLmJhc2VDb2xvclRleHR1cmUsICh0ZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoQmFzZSBDb2xvcilgO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvVGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLm1ldGFsbGljUm91Z2huZXNzVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgcHJvcGVydGllcy5tZXRhbGxpY1JvdWdobmVzc1RleHR1cmUubm9uQ29sb3JEYXRhID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkVGV4dHVyZUluZm9Bc3luYyhgJHtjb250ZXh0fS9tZXRhbGxpY1JvdWdobmVzc1RleHR1cmVgLCBwcm9wZXJ0aWVzLm1ldGFsbGljUm91Z2huZXNzVGV4dHVyZSwgKHRleHR1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dHVyZS5uYW1lID0gYCR7YmFieWxvbk1hdGVyaWFsLm5hbWV9IChNZXRhbGxpYyBSb3VnaG5lc3MpYDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLm1ldGFsbGljVGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnVzZU1ldGFsbG5lc3NGcm9tTWV0YWxsaWNUZXh0dXJlQmx1ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwudXNlUm91Z2huZXNzRnJvbU1ldGFsbGljVGV4dHVyZUdyZWVuID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC51c2VSb3VnaG5lc3NGcm9tTWV0YWxsaWNUZXh0dXJlQWxwaGEgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHt9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvYWRNYXRlcmlhbEFzeW5jKFxyXG4gICAgICAgIGNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBtYXRlcmlhbDogSU1hdGVyaWFsLFxyXG4gICAgICAgIGJhYnlsb25NZXNoOiBOdWxsYWJsZTxNZXNoPixcclxuICAgICAgICBiYWJ5bG9uRHJhd01vZGU6IG51bWJlcixcclxuICAgICAgICBhc3NpZ246IChiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKSA9PiB2b2lkID0gKCkgPT4ge31cclxuICAgICk6IFByb21pc2U8TWF0ZXJpYWw+IHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25Qcm9taXNlID0gdGhpcy5fZXh0ZW5zaW9uc0xvYWRNYXRlcmlhbEFzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWVzaCwgYmFieWxvbkRyYXdNb2RlLCBhc3NpZ24pO1xyXG4gICAgICAgIGlmIChleHRlbnNpb25Qcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHRlbnNpb25Qcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbWF0ZXJpYWwuX2RhdGEgPSBtYXRlcmlhbC5fZGF0YSB8fCB7fTtcclxuICAgICAgICBsZXQgYmFieWxvbkRhdGEgPSBtYXRlcmlhbC5fZGF0YVtiYWJ5bG9uRHJhd01vZGVdO1xyXG4gICAgICAgIGlmICghYmFieWxvbkRhdGEpIHtcclxuICAgICAgICAgICAgdGhpcy5sb2dPcGVuKGAke2NvbnRleHR9ICR7bWF0ZXJpYWwubmFtZSB8fCBcIlwifWApO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgYmFieWxvbk1hdGVyaWFsID0gdGhpcy5jcmVhdGVNYXRlcmlhbChjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbkRyYXdNb2RlKTtcclxuXHJcbiAgICAgICAgICAgIGJhYnlsb25EYXRhID0ge1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsOiBiYWJ5bG9uTWF0ZXJpYWwsXHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWVzaGVzOiBbXSxcclxuICAgICAgICAgICAgICAgIHByb21pc2U6IHRoaXMubG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpLFxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgbWF0ZXJpYWwuX2RhdGFbYmFieWxvbkRyYXdNb2RlXSA9IGJhYnlsb25EYXRhO1xyXG5cclxuICAgICAgICAgICAgR0xURkxvYWRlci5BZGRQb2ludGVyTWV0YWRhdGEoYmFieWxvbk1hdGVyaWFsLCBjb250ZXh0KTtcclxuICAgICAgICAgICAgdGhpcy5fcGFyZW50Lm9uTWF0ZXJpYWxMb2FkZWRPYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyhiYWJ5bG9uTWF0ZXJpYWwpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5sb2dDbG9zZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGJhYnlsb25NZXNoKSB7XHJcbiAgICAgICAgICAgIGJhYnlsb25EYXRhLmJhYnlsb25NZXNoZXMucHVzaChiYWJ5bG9uTWVzaCk7XHJcblxyXG4gICAgICAgICAgICBiYWJ5bG9uTWVzaC5vbkRpc3Bvc2VPYnNlcnZhYmxlLmFkZE9uY2UoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBiYWJ5bG9uRGF0YS5iYWJ5bG9uTWVzaGVzLmluZGV4T2YoYmFieWxvbk1lc2gpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25EYXRhLmJhYnlsb25NZXNoZXMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBhc3NpZ24oYmFieWxvbkRhdGEuYmFieWxvbk1hdGVyaWFsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGJhYnlsb25EYXRhLnByb21pc2UudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBiYWJ5bG9uRGF0YS5iYWJ5bG9uTWF0ZXJpYWw7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfY3JlYXRlRGVmYXVsdE1hdGVyaWFsKG5hbWU6IHN0cmluZywgYmFieWxvbkRyYXdNb2RlOiBudW1iZXIpOiBNYXRlcmlhbCB7XHJcbiAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSAhIXRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgIGNvbnN0IGJhYnlsb25NYXRlcmlhbCA9IG5ldyBQQlJNYXRlcmlhbChuYW1lLCB0aGlzLl9iYWJ5bG9uU2NlbmUpO1xyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5fcGFyZW50Q29udGFpbmVyID0gdGhpcy5fYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSBmYWxzZTtcclxuICAgICAgICAvLyBNb3ZlZCB0byBtZXNoIHNvIHVzZXIgY2FuIGNoYW5nZSBtYXRlcmlhbHMgb24gZ2x0ZiBtZXNoZXM6IGJhYnlsb25NYXRlcmlhbC5zaWRlT3JpZW50YXRpb24gPSB0aGlzLl9iYWJ5bG9uU2NlbmUudXNlUmlnaHRIYW5kZWRTeXN0ZW0gPyBNYXRlcmlhbC5Db3VudGVyQ2xvY2tXaXNlU2lkZU9yaWVudGF0aW9uIDogTWF0ZXJpYWwuQ2xvY2tXaXNlU2lkZU9yaWVudGF0aW9uO1xyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC5maWxsTW9kZSA9IGJhYnlsb25EcmF3TW9kZTtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuZW5hYmxlU3BlY3VsYXJBbnRpQWxpYXNpbmcgPSB0cnVlO1xyXG4gICAgICAgIGJhYnlsb25NYXRlcmlhbC51c2VSYWRpYW5jZU92ZXJBbHBoYSA9ICF0aGlzLl9wYXJlbnQudHJhbnNwYXJlbmN5QXNDb3ZlcmFnZTtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwudXNlU3BlY3VsYXJPdmVyQWxwaGEgPSAhdGhpcy5fcGFyZW50LnRyYW5zcGFyZW5jeUFzQ292ZXJhZ2U7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLnRyYW5zcGFyZW5jeU1vZGUgPSBQQlJNYXRlcmlhbC5QQlJNQVRFUklBTF9PUEFRVUU7XHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLm1ldGFsbGljID0gMTtcclxuICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwucm91Z2huZXNzID0gMTtcclxuICAgICAgICByZXR1cm4gYmFieWxvbk1hdGVyaWFsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIEJhYnlsb24gbWF0ZXJpYWwgZnJvbSBhIGdsVEYgbWF0ZXJpYWwuXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gbWF0ZXJpYWwgVGhlIGdsVEYgbWF0ZXJpYWwgcHJvcGVydHlcclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uRHJhd01vZGUgVGhlIGRyYXcgbW9kZSBmb3IgdGhlIEJhYnlsb24gbWF0ZXJpYWxcclxuICAgICAqIEByZXR1cm5zIFRoZSBCYWJ5bG9uIG1hdGVyaWFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjcmVhdGVNYXRlcmlhbChjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25EcmF3TW9kZTogbnVtYmVyKTogTWF0ZXJpYWwge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvblByb21pc2UgPSB0aGlzLl9leHRlbnNpb25zQ3JlYXRlTWF0ZXJpYWwoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25EcmF3TW9kZSk7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvblByb21pc2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvblByb21pc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBuYW1lID0gbWF0ZXJpYWwubmFtZSB8fCBgbWF0ZXJpYWwke21hdGVyaWFsLmluZGV4fWA7XHJcbiAgICAgICAgY29uc3QgYmFieWxvbk1hdGVyaWFsID0gdGhpcy5fY3JlYXRlRGVmYXVsdE1hdGVyaWFsKG5hbWUsIGJhYnlsb25EcmF3TW9kZSk7XHJcblxyXG4gICAgICAgIHJldHVybiBiYWJ5bG9uTWF0ZXJpYWw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMb2FkcyBwcm9wZXJ0aWVzIGZyb20gYSBnbFRGIG1hdGVyaWFsIGludG8gYSBCYWJ5bG9uIG1hdGVyaWFsLlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIG1hdGVyaWFsIFRoZSBnbFRGIG1hdGVyaWFsIHByb3BlcnR5XHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk1hdGVyaWFsIFRoZSBCYWJ5bG9uIG1hdGVyaWFsXHJcbiAgICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBsb2FkIGlzIGNvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uUHJvbWlzZSA9IHRoaXMuX2V4dGVuc2lvbnNMb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCk7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvblByb21pc2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvblByb21pc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHVua25vd24+PigpO1xyXG5cclxuICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMubG9hZE1hdGVyaWFsQmFzZVByb3BlcnRpZXNBc3luYyhjb250ZXh0LCBtYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsKSk7XHJcblxyXG4gICAgICAgIGlmIChtYXRlcmlhbC5wYnJNZXRhbGxpY1JvdWdobmVzcykge1xyXG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKHRoaXMuX2xvYWRNYXRlcmlhbE1ldGFsbGljUm91Z2huZXNzUHJvcGVydGllc0FzeW5jKGAke2NvbnRleHR9L3Bick1ldGFsbGljUm91Z2huZXNzYCwgbWF0ZXJpYWwucGJyTWV0YWxsaWNSb3VnaG5lc3MsIGJhYnlsb25NYXRlcmlhbCkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5sb2FkTWF0ZXJpYWxBbHBoYVByb3BlcnRpZXMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NYXRlcmlhbCk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7fSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMb2FkcyB0aGUgbm9ybWFsLCBvY2NsdXNpb24sIGFuZCBlbWlzc2l2ZSBwcm9wZXJ0aWVzIGZyb20gYSBnbFRGIG1hdGVyaWFsIGludG8gYSBCYWJ5bG9uIG1hdGVyaWFsLlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIG1hdGVyaWFsIFRoZSBnbFRGIG1hdGVyaWFsIHByb3BlcnR5XHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk1hdGVyaWFsIFRoZSBCYWJ5bG9uIG1hdGVyaWFsXHJcbiAgICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBsb2FkIGlzIGNvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTWF0ZXJpYWxCYXNlUHJvcGVydGllc0FzeW5jKGNvbnRleHQ6IHN0cmluZywgbWF0ZXJpYWw6IElNYXRlcmlhbCwgYmFieWxvbk1hdGVyaWFsOiBNYXRlcmlhbCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGlmICghKGJhYnlsb25NYXRlcmlhbCBpbnN0YW5jZW9mIFBCUk1hdGVyaWFsKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06IE1hdGVyaWFsIHR5cGUgbm90IHN1cHBvcnRlZGApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTx1bmtub3duPj4oKTtcclxuXHJcbiAgICAgICAgYmFieWxvbk1hdGVyaWFsLmVtaXNzaXZlQ29sb3IgPSBtYXRlcmlhbC5lbWlzc2l2ZUZhY3RvciA/IENvbG9yMy5Gcm9tQXJyYXkobWF0ZXJpYWwuZW1pc3NpdmVGYWN0b3IpIDogbmV3IENvbG9yMygwLCAwLCAwKTtcclxuICAgICAgICBpZiAobWF0ZXJpYWwuZG91YmxlU2lkZWQpIHtcclxuICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmJhY2tGYWNlQ3VsbGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwudHdvU2lkZWRMaWdodGluZyA9IHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAobWF0ZXJpYWwubm9ybWFsVGV4dHVyZSkge1xyXG4gICAgICAgICAgICBtYXRlcmlhbC5ub3JtYWxUZXh0dXJlLm5vbkNvbG9yRGF0YSA9IHRydWU7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L25vcm1hbFRleHR1cmVgLCBtYXRlcmlhbC5ub3JtYWxUZXh0dXJlLCAodGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoTm9ybWFsKWA7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmJ1bXBUZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuaW52ZXJ0Tm9ybWFsTWFwWCA9ICF0aGlzLl9iYWJ5bG9uU2NlbmUudXNlUmlnaHRIYW5kZWRTeXN0ZW07XHJcbiAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5pbnZlcnROb3JtYWxNYXBZID0gdGhpcy5fYmFieWxvblNjZW5lLnVzZVJpZ2h0SGFuZGVkU3lzdGVtO1xyXG4gICAgICAgICAgICBpZiAobWF0ZXJpYWwubm9ybWFsVGV4dHVyZS5zY2FsZSAhPSB1bmRlZmluZWQgJiYgYmFieWxvbk1hdGVyaWFsLmJ1bXBUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYnVtcFRleHR1cmUubGV2ZWwgPSBtYXRlcmlhbC5ub3JtYWxUZXh0dXJlLnNjYWxlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuZm9yY2VJcnJhZGlhbmNlSW5GcmFnbWVudCA9IHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAobWF0ZXJpYWwub2NjbHVzaW9uVGV4dHVyZSkge1xyXG4gICAgICAgICAgICBtYXRlcmlhbC5vY2NsdXNpb25UZXh0dXJlLm5vbkNvbG9yRGF0YSA9IHRydWU7XHJcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRUZXh0dXJlSW5mb0FzeW5jKGAke2NvbnRleHR9L29jY2x1c2lvblRleHR1cmVgLCBtYXRlcmlhbC5vY2NsdXNpb25UZXh0dXJlLCAodGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoT2NjbHVzaW9uKWA7XHJcbiAgICAgICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLmFtYmllbnRUZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwudXNlQW1iaWVudEluR3JheVNjYWxlID0gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKG1hdGVyaWFsLm9jY2x1c2lvblRleHR1cmUuc3RyZW5ndGggIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYW1iaWVudFRleHR1cmVTdHJlbmd0aCA9IG1hdGVyaWFsLm9jY2x1c2lvblRleHR1cmUuc3RyZW5ndGg7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChtYXRlcmlhbC5lbWlzc2l2ZVRleHR1cmUpIHtcclxuICAgICAgICAgICAgcHJvbWlzZXMucHVzaChcclxuICAgICAgICAgICAgICAgIHRoaXMubG9hZFRleHR1cmVJbmZvQXN5bmMoYCR7Y29udGV4dH0vZW1pc3NpdmVUZXh0dXJlYCwgbWF0ZXJpYWwuZW1pc3NpdmVUZXh0dXJlLCAodGV4dHVyZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmUubmFtZSA9IGAke2JhYnlsb25NYXRlcmlhbC5uYW1lfSAoRW1pc3NpdmUpYDtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuZW1pc3NpdmVUZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge30pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9hZHMgdGhlIGFscGhhIHByb3BlcnRpZXMgZnJvbSBhIGdsVEYgbWF0ZXJpYWwgaW50byBhIEJhYnlsb24gbWF0ZXJpYWwuXHJcbiAgICAgKiBNdXN0IGJlIGNhbGxlZCBhZnRlciB0aGUgc2V0dGluZyB0aGUgYWxiZWRvIHRleHR1cmUgb2YgdGhlIEJhYnlsb24gbWF0ZXJpYWwgd2hlbiB0aGUgbWF0ZXJpYWwgaGFzIGFuIGFsYmVkbyB0ZXh0dXJlLlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIG1hdGVyaWFsIFRoZSBnbFRGIG1hdGVyaWFsIHByb3BlcnR5XHJcbiAgICAgKiBAcGFyYW0gYmFieWxvbk1hdGVyaWFsIFRoZSBCYWJ5bG9uIG1hdGVyaWFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTWF0ZXJpYWxBbHBoYVByb3BlcnRpZXMoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCEoYmFieWxvbk1hdGVyaWFsIGluc3RhbmNlb2YgUEJSTWF0ZXJpYWwpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogTWF0ZXJpYWwgdHlwZSBub3Qgc3VwcG9ydGVkYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBhbHBoYU1vZGUgPSBtYXRlcmlhbC5hbHBoYU1vZGUgfHwgTWF0ZXJpYWxBbHBoYU1vZGUuT1BBUVVFO1xyXG4gICAgICAgIHN3aXRjaCAoYWxwaGFNb2RlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgTWF0ZXJpYWxBbHBoYU1vZGUuT1BBUVVFOiB7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwudHJhbnNwYXJlbmN5TW9kZSA9IFBCUk1hdGVyaWFsLlBCUk1BVEVSSUFMX09QQVFVRTtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbHBoYSA9IDEuMDsgLy8gRm9yY2UgYWxwaGEgdG8gMS4wIGZvciBvcGFxdWUgbW9kZS5cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgTWF0ZXJpYWxBbHBoYU1vZGUuTUFTSzoge1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbk1hdGVyaWFsLnRyYW5zcGFyZW5jeU1vZGUgPSBQQlJNYXRlcmlhbC5QQlJNQVRFUklBTF9BTFBIQVRFU1Q7XHJcbiAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwuYWxwaGFDdXRPZmYgPSBtYXRlcmlhbC5hbHBoYUN1dG9mZiA9PSB1bmRlZmluZWQgPyAwLjUgOiBtYXRlcmlhbC5hbHBoYUN1dG9mZjtcclxuICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbGJlZG9UZXh0dXJlLmhhc0FscGhhID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgTWF0ZXJpYWxBbHBoYU1vZGUuQkxFTkQ6IHtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC50cmFuc3BhcmVuY3lNb2RlID0gUEJSTWF0ZXJpYWwuUEJSTUFURVJJQUxfQUxQSEFCTEVORDtcclxuICAgICAgICAgICAgICAgIGlmIChiYWJ5bG9uTWF0ZXJpYWwuYWxiZWRvVGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJhYnlsb25NYXRlcmlhbC5hbGJlZG9UZXh0dXJlLmhhc0FscGhhID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBiYWJ5bG9uTWF0ZXJpYWwudXNlQWxwaGFGcm9tQWxiZWRvVGV4dHVyZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBkZWZhdWx0OiB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH0vYWxwaGFNb2RlOiBJbnZhbGlkIHZhbHVlICgke21hdGVyaWFsLmFscGhhTW9kZX0pYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMb2FkcyBhIGdsVEYgdGV4dHVyZSBpbmZvLlxyXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgd2hlbiBsb2FkaW5nIHRoZSBhc3NldFxyXG4gICAgICogQHBhcmFtIHRleHR1cmVJbmZvIFRoZSBnbFRGIHRleHR1cmUgaW5mbyBwcm9wZXJ0eVxyXG4gICAgICogQHBhcmFtIGFzc2lnbiBBIGZ1bmN0aW9uIGNhbGxlZCBzeW5jaHJvbm91c2x5IGFmdGVyIHBhcnNpbmcgdGhlIGdsVEYgcHJvcGVydGllc1xyXG4gICAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgbG9hZGVkIEJhYnlsb24gdGV4dHVyZSB3aGVuIHRoZSBsb2FkIGlzIGNvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkVGV4dHVyZUluZm9Bc3luYyhjb250ZXh0OiBzdHJpbmcsIHRleHR1cmVJbmZvOiBJVGV4dHVyZUluZm8sIGFzc2lnbjogKGJhYnlsb25UZXh0dXJlOiBCYXNlVGV4dHVyZSkgPT4gdm9pZCA9ICgpID0+IHt9KTogUHJvbWlzZTxCYXNlVGV4dHVyZT4ge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvblByb21pc2UgPSB0aGlzLl9leHRlbnNpb25zTG9hZFRleHR1cmVJbmZvQXN5bmMoY29udGV4dCwgdGV4dHVyZUluZm8sIGFzc2lnbik7XHJcbiAgICAgICAgaWYgKGV4dGVuc2lvblByb21pc2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvblByb21pc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmxvZ09wZW4oYCR7Y29udGV4dH1gKTtcclxuXHJcbiAgICAgICAgaWYgKHRleHR1cmVJbmZvLnRleENvb3JkISA+PSA2KSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fS90ZXhDb29yZDogSW52YWxpZCB2YWx1ZSAoJHt0ZXh0dXJlSW5mby50ZXhDb29yZH0pYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB0ZXh0dXJlID0gQXJyYXlJdGVtLkdldChgJHtjb250ZXh0fS9pbmRleGAsIHRoaXMuX2dsdGYudGV4dHVyZXMsIHRleHR1cmVJbmZvLmluZGV4KTtcclxuICAgICAgICB0ZXh0dXJlLl90ZXh0dXJlSW5mbyA9IHRleHR1cmVJbmZvO1xyXG5cclxuICAgICAgICBjb25zdCBwcm9taXNlID0gdGhpcy5fbG9hZFRleHR1cmVBc3luYyhgL3RleHR1cmVzLyR7dGV4dHVyZUluZm8uaW5kZXh9YCwgdGV4dHVyZSwgKGJhYnlsb25UZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgIGJhYnlsb25UZXh0dXJlLmNvb3JkaW5hdGVzSW5kZXggPSB0ZXh0dXJlSW5mby50ZXhDb29yZCB8fCAwO1xyXG4gICAgICAgICAgICBHTFRGTG9hZGVyLkFkZFBvaW50ZXJNZXRhZGF0YShiYWJ5bG9uVGV4dHVyZSwgY29udGV4dCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3BhcmVudC5vblRleHR1cmVMb2FkZWRPYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyhiYWJ5bG9uVGV4dHVyZSk7XHJcbiAgICAgICAgICAgIGFzc2lnbihiYWJ5bG9uVGV4dHVyZSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMubG9nQ2xvc2UoKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9sb2FkVGV4dHVyZUFzeW5jKGNvbnRleHQ6IHN0cmluZywgdGV4dHVyZTogSVRleHR1cmUsIGFzc2lnbjogKGJhYnlsb25UZXh0dXJlOiBCYXNlVGV4dHVyZSkgPT4gdm9pZCA9ICgpID0+IHt9KTogUHJvbWlzZTxCYXNlVGV4dHVyZT4ge1xyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvblByb21pc2UgPSB0aGlzLl9leHRlbnNpb25zTG9hZFRleHR1cmVBc3luYyhjb250ZXh0LCB0ZXh0dXJlLCBhc3NpZ24pO1xyXG4gICAgICAgIGlmIChleHRlbnNpb25Qcm9taXNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHRlbnNpb25Qcm9taXNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5sb2dPcGVuKGAke2NvbnRleHR9ICR7dGV4dHVyZS5uYW1lIHx8IFwiXCJ9YCk7XHJcblxyXG4gICAgICAgIGNvbnN0IHNhbXBsZXIgPSB0ZXh0dXJlLnNhbXBsZXIgPT0gdW5kZWZpbmVkID8gR0xURkxvYWRlci5EZWZhdWx0U2FtcGxlciA6IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vc2FtcGxlcmAsIHRoaXMuX2dsdGYuc2FtcGxlcnMsIHRleHR1cmUuc2FtcGxlcik7XHJcbiAgICAgICAgY29uc3QgaW1hZ2UgPSBBcnJheUl0ZW0uR2V0KGAke2NvbnRleHR9L3NvdXJjZWAsIHRoaXMuX2dsdGYuaW1hZ2VzLCB0ZXh0dXJlLnNvdXJjZSk7XHJcbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRoaXMuX2NyZWF0ZVRleHR1cmVBc3luYyhjb250ZXh0LCBzYW1wbGVyLCBpbWFnZSwgYXNzaWduLCB1bmRlZmluZWQsICF0ZXh0dXJlLl90ZXh0dXJlSW5mby5ub25Db2xvckRhdGEpO1xyXG5cclxuICAgICAgICB0aGlzLmxvZ0Nsb3NlKCk7XHJcblxyXG4gICAgICAgIHJldHVybiBwcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfY3JlYXRlVGV4dHVyZUFzeW5jKFxyXG4gICAgICAgIGNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBzYW1wbGVyOiBJU2FtcGxlcixcclxuICAgICAgICBpbWFnZTogSUltYWdlLFxyXG4gICAgICAgIGFzc2lnbjogKGJhYnlsb25UZXh0dXJlOiBCYXNlVGV4dHVyZSkgPT4gdm9pZCA9ICgpID0+IHt9LFxyXG4gICAgICAgIHRleHR1cmVMb2FkZXJPcHRpb25zPzogdW5rbm93bixcclxuICAgICAgICB1c2VTUkdCQnVmZmVyPzogYm9vbGVhblxyXG4gICAgKTogUHJvbWlzZTxCYXNlVGV4dHVyZT4ge1xyXG4gICAgICAgIGNvbnN0IHNhbXBsZXJEYXRhID0gdGhpcy5fbG9hZFNhbXBsZXIoYC9zYW1wbGVycy8ke3NhbXBsZXIuaW5kZXh9YCwgc2FtcGxlcik7XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dW5rbm93bj4+KCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGRlZmVycmVkID0gbmV3IERlZmVycmVkPHZvaWQ+KCk7XHJcbiAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSAhIXRoaXMuX2Fzc2V0Q29udGFpbmVyO1xyXG4gICAgICAgIGNvbnN0IHRleHR1cmVDcmVhdGlvbk9wdGlvbnM6IElUZXh0dXJlQ3JlYXRpb25PcHRpb25zID0ge1xyXG4gICAgICAgICAgICBub01pcG1hcDogc2FtcGxlckRhdGEubm9NaXBNYXBzLFxyXG4gICAgICAgICAgICBpbnZlcnRZOiBmYWxzZSxcclxuICAgICAgICAgICAgc2FtcGxpbmdNb2RlOiBzYW1wbGVyRGF0YS5zYW1wbGluZ01vZGUsXHJcbiAgICAgICAgICAgIG9uTG9hZDogKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9kaXNwb3NlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgb25FcnJvcjogKG1lc3NhZ2U/OiBzdHJpbmcsIGV4Y2VwdGlvbj86IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9kaXNwb3NlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChuZXcgRXJyb3IoYCR7Y29udGV4dH06ICR7ZXhjZXB0aW9uICYmIGV4Y2VwdGlvbi5tZXNzYWdlID8gZXhjZXB0aW9uLm1lc3NhZ2UgOiBtZXNzYWdlIHx8IFwiRmFpbGVkIHRvIGxvYWQgdGV4dHVyZVwifWApKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbWltZVR5cGU6IGltYWdlLm1pbWVUeXBlLFxyXG4gICAgICAgICAgICBsb2FkZXJPcHRpb25zOiB0ZXh0dXJlTG9hZGVyT3B0aW9ucyxcclxuICAgICAgICAgICAgdXNlU1JHQkJ1ZmZlcjogISF1c2VTUkdCQnVmZmVyICYmIHRoaXMuX3BhcmVudC51c2VTUkdCQnVmZmVycyxcclxuICAgICAgICB9O1xyXG4gICAgICAgIGNvbnN0IGJhYnlsb25UZXh0dXJlID0gbmV3IFRleHR1cmUobnVsbCwgdGhpcy5fYmFieWxvblNjZW5lLCB0ZXh0dXJlQ3JlYXRpb25PcHRpb25zKTtcclxuICAgICAgICBiYWJ5bG9uVGV4dHVyZS5fcGFyZW50Q29udGFpbmVyID0gdGhpcy5fYXNzZXRDb250YWluZXI7XHJcbiAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLl9ibG9ja0VudGl0eUNvbGxlY3Rpb24gPSBmYWxzZTtcclxuICAgICAgICBwcm9taXNlcy5wdXNoKGRlZmVycmVkLnByb21pc2UpO1xyXG5cclxuICAgICAgICBwcm9taXNlcy5wdXNoKFxyXG4gICAgICAgICAgICB0aGlzLmxvYWRJbWFnZUFzeW5jKGAvaW1hZ2VzLyR7aW1hZ2UuaW5kZXh9YCwgaW1hZ2UpLnRoZW4oKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBpbWFnZS51cmkgfHwgYCR7dGhpcy5fZmlsZU5hbWV9I2ltYWdlJHtpbWFnZS5pbmRleH1gO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YVVybCA9IGBkYXRhOiR7dGhpcy5fdW5pcXVlUm9vdFVybH0ke25hbWV9YDtcclxuICAgICAgICAgICAgICAgIGJhYnlsb25UZXh0dXJlLnVwZGF0ZVVSTChkYXRhVXJsLCBkYXRhKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIGludGVybmFsIHRleHR1cmUgbGFiZWwuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBpbnRlcm5hbFRleHR1cmUgPSBiYWJ5bG9uVGV4dHVyZS5nZXRJbnRlcm5hbFRleHR1cmUoKTtcclxuICAgICAgICAgICAgICAgIGlmIChpbnRlcm5hbFRleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpbnRlcm5hbFRleHR1cmUubGFiZWwgPSBpbWFnZS5uYW1lO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIGJhYnlsb25UZXh0dXJlLndyYXBVID0gc2FtcGxlckRhdGEud3JhcFU7XHJcbiAgICAgICAgYmFieWxvblRleHR1cmUud3JhcFYgPSBzYW1wbGVyRGF0YS53cmFwVjtcclxuICAgICAgICBhc3NpZ24oYmFieWxvblRleHR1cmUpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5fcGFyZW50LnVzZUdsdGZUZXh0dXJlTmFtZXMpIHtcclxuICAgICAgICAgICAgYmFieWxvblRleHR1cmUubmFtZSA9IGltYWdlLm5hbWUgfHwgaW1hZ2UudXJpIHx8IGBpbWFnZSR7aW1hZ2UuaW5kZXh9YDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBiYWJ5bG9uVGV4dHVyZTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkU2FtcGxlcihjb250ZXh0OiBzdHJpbmcsIHNhbXBsZXI6IElTYW1wbGVyKTogX0lTYW1wbGVyRGF0YSB7XHJcbiAgICAgICAgaWYgKCFzYW1wbGVyLl9kYXRhKSB7XHJcbiAgICAgICAgICAgIHNhbXBsZXIuX2RhdGEgPSB7XHJcbiAgICAgICAgICAgICAgICBub01pcE1hcHM6IHNhbXBsZXIubWluRmlsdGVyID09PSBUZXh0dXJlTWluRmlsdGVyLk5FQVJFU1QgfHwgc2FtcGxlci5taW5GaWx0ZXIgPT09IFRleHR1cmVNaW5GaWx0ZXIuTElORUFSLFxyXG4gICAgICAgICAgICAgICAgc2FtcGxpbmdNb2RlOiBHTFRGTG9hZGVyLl9HZXRUZXh0dXJlU2FtcGxpbmdNb2RlKGNvbnRleHQsIHNhbXBsZXIpLFxyXG4gICAgICAgICAgICAgICAgd3JhcFU6IEdMVEZMb2FkZXIuX0dldFRleHR1cmVXcmFwTW9kZShgJHtjb250ZXh0fS93cmFwU2AsIHNhbXBsZXIud3JhcFMpLFxyXG4gICAgICAgICAgICAgICAgd3JhcFY6IEdMVEZMb2FkZXIuX0dldFRleHR1cmVXcmFwTW9kZShgJHtjb250ZXh0fS93cmFwVGAsIHNhbXBsZXIud3JhcFQpLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHNhbXBsZXIuX2RhdGE7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMb2FkcyBhIGdsVEYgaW1hZ2UuXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gaW1hZ2UgVGhlIGdsVEYgaW1hZ2UgcHJvcGVydHlcclxuICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGxvYWRlZCBkYXRhIHdoZW4gdGhlIGxvYWQgaXMgY29tcGxldGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRJbWFnZUFzeW5jKGNvbnRleHQ6IHN0cmluZywgaW1hZ2U6IElJbWFnZSk6IFByb21pc2U8QXJyYXlCdWZmZXJWaWV3PiB7XHJcbiAgICAgICAgaWYgKCFpbWFnZS5fZGF0YSkge1xyXG4gICAgICAgICAgICB0aGlzLmxvZ09wZW4oYCR7Y29udGV4dH0gJHtpbWFnZS5uYW1lIHx8IFwiXCJ9YCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoaW1hZ2UudXJpKSB7XHJcbiAgICAgICAgICAgICAgICBpbWFnZS5fZGF0YSA9IHRoaXMubG9hZFVyaUFzeW5jKGAke2NvbnRleHR9L3VyaWAsIGltYWdlLCBpbWFnZS51cmkpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYnVmZmVyVmlldyA9IEFycmF5SXRlbS5HZXQoYCR7Y29udGV4dH0vYnVmZmVyVmlld2AsIHRoaXMuX2dsdGYuYnVmZmVyVmlld3MsIGltYWdlLmJ1ZmZlclZpZXcpO1xyXG4gICAgICAgICAgICAgICAgaW1hZ2UuX2RhdGEgPSB0aGlzLmxvYWRCdWZmZXJWaWV3QXN5bmMoYC9idWZmZXJWaWV3cy8ke2J1ZmZlclZpZXcuaW5kZXh9YCwgYnVmZmVyVmlldyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMubG9nQ2xvc2UoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBpbWFnZS5fZGF0YTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIExvYWRzIGEgZ2xURiB1cmkuXHJcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCB3aGVuIGxvYWRpbmcgdGhlIGFzc2V0XHJcbiAgICAgKiBAcGFyYW0gcHJvcGVydHkgVGhlIGdsVEYgcHJvcGVydHkgYXNzb2NpYXRlZCB3aXRoIHRoZSB1cmlcclxuICAgICAqIEBwYXJhbSB1cmkgVGhlIGJhc2U2NCBvciByZWxhdGl2ZSB1cmlcclxuICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGxvYWRlZCBkYXRhIHdoZW4gdGhlIGxvYWQgaXMgY29tcGxldGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRVcmlBc3luYyhjb250ZXh0OiBzdHJpbmcsIHByb3BlcnR5OiBJUHJvcGVydHksIHVyaTogc3RyaW5nKTogUHJvbWlzZTxBcnJheUJ1ZmZlclZpZXc+IHtcclxuICAgICAgICBjb25zdCBleHRlbnNpb25Qcm9taXNlID0gdGhpcy5fZXh0ZW5zaW9uc0xvYWRVcmlBc3luYyhjb250ZXh0LCBwcm9wZXJ0eSwgdXJpKTtcclxuICAgICAgICBpZiAoZXh0ZW5zaW9uUHJvbWlzZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZXh0ZW5zaW9uUHJvbWlzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghR0xURkxvYWRlci5fVmFsaWRhdGVVcmkodXJpKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7Y29udGV4dH06ICcke3VyaX0nIGlzIGludmFsaWRgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChJc0Jhc2U2NERhdGFVcmwodXJpKSkge1xyXG4gICAgICAgICAgICBjb25zdCBkYXRhID0gbmV3IFVpbnQ4QXJyYXkoRGVjb2RlQmFzZTY0VXJsVG9CaW5hcnkodXJpKSk7XHJcbiAgICAgICAgICAgIHRoaXMubG9nKGAke2NvbnRleHR9OiBEZWNvZGVkICR7dXJpLnN1YnN0cmluZygwLCA2NCl9Li4uICgke2RhdGEubGVuZ3RofSBieXRlcylgKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShkYXRhKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMubG9nKGAke2NvbnRleHR9OiBMb2FkaW5nICR7dXJpfWApO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fcGFyZW50LnByZXByb2Nlc3NVcmxBc3luYyh0aGlzLl9yb290VXJsICsgdXJpKS50aGVuKCh1cmwpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3BhcmVudC5fbG9hZEZpbGUoXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYmFieWxvblNjZW5lLFxyXG4gICAgICAgICAgICAgICAgICAgIHVybCxcclxuICAgICAgICAgICAgICAgICAgICAoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2Rpc3Bvc2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZyhgJHtjb250ZXh0fTogTG9hZGVkICR7dXJpfSAoJHsoZGF0YSBhcyBBcnJheUJ1ZmZlcikuYnl0ZUxlbmd0aH0gYnl0ZXMpYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBVaW50OEFycmF5KGRhdGEgYXMgQXJyYXlCdWZmZXIpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAocmVxdWVzdCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IExvYWRGaWxlRXJyb3IoYCR7Y29udGV4dH06IEZhaWxlZCB0byBsb2FkICcke3VyaX0nJHtyZXF1ZXN0ID8gXCI6IFwiICsgcmVxdWVzdC5zdGF0dXMgKyBcIiBcIiArIHJlcXVlc3Quc3RhdHVzVGV4dCA6IFwiXCJ9YCwgcmVxdWVzdCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBhIEpTT04gcG9pbnRlciB0byB0aGUgX2ludGVybmFsTWV0YWRhdGEgb2YgdGhlIEJhYnlsb24gb2JqZWN0IGF0IGA8b2JqZWN0Pi5faW50ZXJuYWxNZXRhZGF0YS5nbHRmLnBvaW50ZXJzYC5cclxuICAgICAqIEBwYXJhbSBiYWJ5bG9uT2JqZWN0IHRoZSBCYWJ5bG9uIG9iamVjdCB3aXRoIF9pbnRlcm5hbE1ldGFkYXRhXHJcbiAgICAgKiBAcGFyYW0gcG9pbnRlciB0aGUgSlNPTiBwb2ludGVyXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgQWRkUG9pbnRlck1ldGFkYXRhKGJhYnlsb25PYmplY3Q6IElXaXRoTWV0YWRhdGEsIHBvaW50ZXI6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGJhYnlsb25PYmplY3QubWV0YWRhdGEgPSBiYWJ5bG9uT2JqZWN0Lm1ldGFkYXRhIHx8IHt9O1xyXG4gICAgICAgIGNvbnN0IG1ldGFkYXRhID0gKGJhYnlsb25PYmplY3QuX2ludGVybmFsTWV0YWRhdGEgPSBiYWJ5bG9uT2JqZWN0Ll9pbnRlcm5hbE1ldGFkYXRhIHx8IHt9KTtcclxuICAgICAgICBjb25zdCBnbHRmID0gKG1ldGFkYXRhLmdsdGYgPSBtZXRhZGF0YS5nbHRmIHx8IHt9KTtcclxuICAgICAgICBjb25zdCBwb2ludGVycyA9IChnbHRmLnBvaW50ZXJzID0gZ2x0Zi5wb2ludGVycyB8fCBbXSk7XHJcbiAgICAgICAgcG9pbnRlcnMucHVzaChwb2ludGVyKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfR2V0VGV4dHVyZVdyYXBNb2RlKGNvbnRleHQ6IHN0cmluZywgbW9kZTogVGV4dHVyZVdyYXBNb2RlIHwgdW5kZWZpbmVkKTogbnVtYmVyIHtcclxuICAgICAgICAvLyBTZXQgZGVmYXVsdHMgaWYgdW5kZWZpbmVkXHJcbiAgICAgICAgbW9kZSA9IG1vZGUgPT0gdW5kZWZpbmVkID8gVGV4dHVyZVdyYXBNb2RlLlJFUEVBVCA6IG1vZGU7XHJcblxyXG4gICAgICAgIHN3aXRjaCAobW9kZSkge1xyXG4gICAgICAgICAgICBjYXNlIFRleHR1cmVXcmFwTW9kZS5DTEFNUF9UT19FREdFOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuQ0xBTVBfQUREUkVTU01PREU7XHJcbiAgICAgICAgICAgIGNhc2UgVGV4dHVyZVdyYXBNb2RlLk1JUlJPUkVEX1JFUEVBVDpcclxuICAgICAgICAgICAgICAgIHJldHVybiBUZXh0dXJlLk1JUlJPUl9BRERSRVNTTU9ERTtcclxuICAgICAgICAgICAgY2FzZSBUZXh0dXJlV3JhcE1vZGUuUkVQRUFUOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuV1JBUF9BRERSRVNTTU9ERTtcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIExvZ2dlci5XYXJuKGAke2NvbnRleHR9OiBJbnZhbGlkIHZhbHVlICgke21vZGV9KWApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuV1JBUF9BRERSRVNTTU9ERTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX0dldFRleHR1cmVTYW1wbGluZ01vZGUoY29udGV4dDogc3RyaW5nLCBzYW1wbGVyOiBJU2FtcGxlcik6IG51bWJlciB7XHJcbiAgICAgICAgLy8gU2V0IGRlZmF1bHRzIGlmIHVuZGVmaW5lZFxyXG4gICAgICAgIGNvbnN0IG1hZ0ZpbHRlciA9IHNhbXBsZXIubWFnRmlsdGVyID09IHVuZGVmaW5lZCA/IFRleHR1cmVNYWdGaWx0ZXIuTElORUFSIDogc2FtcGxlci5tYWdGaWx0ZXI7XHJcbiAgICAgICAgY29uc3QgbWluRmlsdGVyID0gc2FtcGxlci5taW5GaWx0ZXIgPT0gdW5kZWZpbmVkID8gVGV4dHVyZU1pbkZpbHRlci5MSU5FQVJfTUlQTUFQX0xJTkVBUiA6IHNhbXBsZXIubWluRmlsdGVyO1xyXG5cclxuICAgICAgICBpZiAobWFnRmlsdGVyID09PSBUZXh0dXJlTWFnRmlsdGVyLkxJTkVBUikge1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG1pbkZpbHRlcikge1xyXG4gICAgICAgICAgICAgICAgY2FzZSBUZXh0dXJlTWluRmlsdGVyLk5FQVJFU1Q6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuTElORUFSX05FQVJFU1Q7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFRleHR1cmVNaW5GaWx0ZXIuTElORUFSOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBUZXh0dXJlLkxJTkVBUl9MSU5FQVI7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFRleHR1cmVNaW5GaWx0ZXIuTkVBUkVTVF9NSVBNQVBfTkVBUkVTVDpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5MSU5FQVJfTkVBUkVTVF9NSVBORUFSRVNUO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBUZXh0dXJlTWluRmlsdGVyLkxJTkVBUl9NSVBNQVBfTkVBUkVTVDpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5MSU5FQVJfTElORUFSX01JUE5FQVJFU1Q7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFRleHR1cmVNaW5GaWx0ZXIuTkVBUkVTVF9NSVBNQVBfTElORUFSOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBUZXh0dXJlLkxJTkVBUl9ORUFSRVNUX01JUExJTkVBUjtcclxuICAgICAgICAgICAgICAgIGNhc2UgVGV4dHVyZU1pbkZpbHRlci5MSU5FQVJfTUlQTUFQX0xJTkVBUjpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5MSU5FQVJfTElORUFSX01JUExJTkVBUjtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLldhcm4oYCR7Y29udGV4dH0vbWluRmlsdGVyOiBJbnZhbGlkIHZhbHVlICgke21pbkZpbHRlcn0pYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuTElORUFSX0xJTkVBUl9NSVBMSU5FQVI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAobWFnRmlsdGVyICE9PSBUZXh0dXJlTWFnRmlsdGVyLk5FQVJFU1QpIHtcclxuICAgICAgICAgICAgICAgIExvZ2dlci5XYXJuKGAke2NvbnRleHR9L21hZ0ZpbHRlcjogSW52YWxpZCB2YWx1ZSAoJHttYWdGaWx0ZXJ9KWApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBzd2l0Y2ggKG1pbkZpbHRlcikge1xyXG4gICAgICAgICAgICAgICAgY2FzZSBUZXh0dXJlTWluRmlsdGVyLk5FQVJFU1Q6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuTkVBUkVTVF9ORUFSRVNUO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBUZXh0dXJlTWluRmlsdGVyLkxJTkVBUjpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5ORUFSRVNUX0xJTkVBUjtcclxuICAgICAgICAgICAgICAgIGNhc2UgVGV4dHVyZU1pbkZpbHRlci5ORUFSRVNUX01JUE1BUF9ORUFSRVNUOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBUZXh0dXJlLk5FQVJFU1RfTkVBUkVTVF9NSVBORUFSRVNUO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBUZXh0dXJlTWluRmlsdGVyLkxJTkVBUl9NSVBNQVBfTkVBUkVTVDpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5ORUFSRVNUX0xJTkVBUl9NSVBORUFSRVNUO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBUZXh0dXJlTWluRmlsdGVyLk5FQVJFU1RfTUlQTUFQX0xJTkVBUjpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVGV4dHVyZS5ORUFSRVNUX05FQVJFU1RfTUlQTElORUFSO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBUZXh0dXJlTWluRmlsdGVyLkxJTkVBUl9NSVBNQVBfTElORUFSOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBUZXh0dXJlLk5FQVJFU1RfTElORUFSX01JUExJTkVBUjtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLldhcm4oYCR7Y29udGV4dH0vbWluRmlsdGVyOiBJbnZhbGlkIHZhbHVlICgke21pbkZpbHRlcn0pYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRleHR1cmUuTkVBUkVTVF9ORUFSRVNUX01JUE5FQVJFU1Q7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX0dldFR5cGVkQXJyYXlDb25zdHJ1Y3Rvcihjb250ZXh0OiBzdHJpbmcsIGNvbXBvbmVudFR5cGU6IEFjY2Vzc29yQ29tcG9uZW50VHlwZSk6IFR5cGVkQXJyYXlDb25zdHJ1Y3RvciB7XHJcbiAgICAgICAgc3dpdGNoIChjb21wb25lbnRUeXBlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgQWNjZXNzb3JDb21wb25lbnRUeXBlLkJZVEU6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gSW50OEFycmF5O1xyXG4gICAgICAgICAgICBjYXNlIEFjY2Vzc29yQ29tcG9uZW50VHlwZS5VTlNJR05FRF9CWVRFOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXk7XHJcbiAgICAgICAgICAgIGNhc2UgQWNjZXNzb3JDb21wb25lbnRUeXBlLlNIT1JUOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIEludDE2QXJyYXk7XHJcbiAgICAgICAgICAgIGNhc2UgQWNjZXNzb3JDb21wb25lbnRUeXBlLlVOU0lHTkVEX1NIT1JUOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFVpbnQxNkFycmF5O1xyXG4gICAgICAgICAgICBjYXNlIEFjY2Vzc29yQ29tcG9uZW50VHlwZS5VTlNJR05FRF9JTlQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVWludDMyQXJyYXk7XHJcbiAgICAgICAgICAgIGNhc2UgQWNjZXNzb3JDb21wb25lbnRUeXBlLkZMT0FUOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIEZsb2F0MzJBcnJheTtcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogSW52YWxpZCBjb21wb25lbnQgdHlwZSAke2NvbXBvbmVudFR5cGV9YCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIF9HZXRUeXBlZEFycmF5KFxyXG4gICAgICAgIGNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBjb21wb25lbnRUeXBlOiBBY2Nlc3NvckNvbXBvbmVudFR5cGUsXHJcbiAgICAgICAgYnVmZmVyVmlldzogQXJyYXlCdWZmZXJWaWV3LFxyXG4gICAgICAgIGJ5dGVPZmZzZXQ6IG51bWJlciB8IHVuZGVmaW5lZCxcclxuICAgICAgICBsZW5ndGg6IG51bWJlclxyXG4gICAgKTogVHlwZWRBcnJheUxpa2Uge1xyXG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IGJ1ZmZlclZpZXcuYnVmZmVyO1xyXG4gICAgICAgIGJ5dGVPZmZzZXQgPSBidWZmZXJWaWV3LmJ5dGVPZmZzZXQgKyAoYnl0ZU9mZnNldCB8fCAwKTtcclxuXHJcbiAgICAgICAgY29uc3QgY29uc3RydWN0b3IgPSBHTFRGTG9hZGVyLl9HZXRUeXBlZEFycmF5Q29uc3RydWN0b3IoYCR7Y29udGV4dH0vY29tcG9uZW50VHlwZWAsIGNvbXBvbmVudFR5cGUpO1xyXG5cclxuICAgICAgICBjb25zdCBjb21wb25lbnRUeXBlTGVuZ3RoID0gVmVydGV4QnVmZmVyLkdldFR5cGVCeXRlTGVuZ3RoKGNvbXBvbmVudFR5cGUpO1xyXG4gICAgICAgIGlmIChieXRlT2Zmc2V0ICUgY29tcG9uZW50VHlwZUxlbmd0aCAhPT0gMCkge1xyXG4gICAgICAgICAgICAvLyBIQUNLOiBDb3B5IHRoZSBidWZmZXIgaWYgYnl0ZSBvZmZzZXQgaXMgbm90IGEgbXVsdGlwbGUgb2YgY29tcG9uZW50IHR5cGUgYnl0ZSBsZW5ndGguXHJcbiAgICAgICAgICAgIExvZ2dlci5XYXJuKGAke2NvbnRleHR9OiBDb3B5aW5nIGJ1ZmZlciBhcyBieXRlIG9mZnNldCAoJHtieXRlT2Zmc2V0fSkgaXMgbm90IGEgbXVsdGlwbGUgb2YgY29tcG9uZW50IHR5cGUgYnl0ZSBsZW5ndGggKCR7Y29tcG9uZW50VHlwZUxlbmd0aH0pYCk7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgY29uc3RydWN0b3IoYnVmZmVyLnNsaWNlKGJ5dGVPZmZzZXQsIGJ5dGVPZmZzZXQgKyBsZW5ndGggKiBjb21wb25lbnRUeXBlTGVuZ3RoKSwgMCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbmV3IGNvbnN0cnVjdG9yKGJ1ZmZlciwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfR2V0TnVtQ29tcG9uZW50cyhjb250ZXh0OiBzdHJpbmcsIHR5cGU6IHN0cmluZyk6IG51bWJlciB7XHJcbiAgICAgICAgc3dpdGNoICh0eXBlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgXCJTQ0FMQVJcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiAxO1xyXG4gICAgICAgICAgICBjYXNlIFwiVkVDMlwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIDI7XHJcbiAgICAgICAgICAgIGNhc2UgXCJWRUMzXCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gMztcclxuICAgICAgICAgICAgY2FzZSBcIlZFQzRcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiA0O1xyXG4gICAgICAgICAgICBjYXNlIFwiTUFUMlwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIDQ7XHJcbiAgICAgICAgICAgIGNhc2UgXCJNQVQzXCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gOTtcclxuICAgICAgICAgICAgY2FzZSBcIk1BVDRcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiAxNjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb250ZXh0fTogSW52YWxpZCB0eXBlICgke3R5cGV9KWApO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIF9WYWxpZGF0ZVVyaSh1cmk6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiBUb29scy5Jc0Jhc2U2NCh1cmkpIHx8IHVyaS5pbmRleE9mKFwiLi5cIikgPT09IC0xO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgX0dldERyYXdNb2RlKGNvbnRleHQ6IHN0cmluZywgbW9kZTogbnVtYmVyIHwgdW5kZWZpbmVkKTogbnVtYmVyIHtcclxuICAgICAgICBpZiAobW9kZSA9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgbW9kZSA9IE1lc2hQcmltaXRpdmVNb2RlLlRSSUFOR0xFUztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN3aXRjaCAobW9kZSkge1xyXG4gICAgICAgICAgICBjYXNlIE1lc2hQcmltaXRpdmVNb2RlLlBPSU5UUzpcclxuICAgICAgICAgICAgICAgIHJldHVybiBNYXRlcmlhbC5Qb2ludExpc3REcmF3TW9kZTtcclxuICAgICAgICAgICAgY2FzZSBNZXNoUHJpbWl0aXZlTW9kZS5MSU5FUzpcclxuICAgICAgICAgICAgICAgIHJldHVybiBNYXRlcmlhbC5MaW5lTGlzdERyYXdNb2RlO1xyXG4gICAgICAgICAgICBjYXNlIE1lc2hQcmltaXRpdmVNb2RlLkxJTkVfTE9PUDpcclxuICAgICAgICAgICAgICAgIHJldHVybiBNYXRlcmlhbC5MaW5lTG9vcERyYXdNb2RlO1xyXG4gICAgICAgICAgICBjYXNlIE1lc2hQcmltaXRpdmVNb2RlLkxJTkVfU1RSSVA6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gTWF0ZXJpYWwuTGluZVN0cmlwRHJhd01vZGU7XHJcbiAgICAgICAgICAgIGNhc2UgTWVzaFByaW1pdGl2ZU1vZGUuVFJJQU5HTEVTOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE1hdGVyaWFsLlRyaWFuZ2xlRmlsbE1vZGU7XHJcbiAgICAgICAgICAgIGNhc2UgTWVzaFByaW1pdGl2ZU1vZGUuVFJJQU5HTEVfU1RSSVA6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gTWF0ZXJpYWwuVHJpYW5nbGVTdHJpcERyYXdNb2RlO1xyXG4gICAgICAgICAgICBjYXNlIE1lc2hQcmltaXRpdmVNb2RlLlRSSUFOR0xFX0ZBTjpcclxuICAgICAgICAgICAgICAgIHJldHVybiBNYXRlcmlhbC5UcmlhbmdsZUZhbkRyYXdNb2RlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2NvbnRleHR9OiBJbnZhbGlkIG1lc2ggcHJpbWl0aXZlIG1vZGUgKCR7bW9kZX0pYCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfY29tcGlsZU1hdGVyaWFsc0FzeW5jKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHRoaXMuX3BhcmVudC5fc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXIoXCJDb21waWxlIG1hdGVyaWFsc1wiKTtcclxuXHJcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBuZXcgQXJyYXk8UHJvbWlzZTx1bmtub3duPj4oKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX2dsdGYubWF0ZXJpYWxzKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgbWF0ZXJpYWwgb2YgdGhpcy5fZ2x0Zi5tYXRlcmlhbHMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChtYXRlcmlhbC5fZGF0YSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYmFieWxvbkRyYXdNb2RlIGluIG1hdGVyaWFsLl9kYXRhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJhYnlsb25EYXRhID0gbWF0ZXJpYWwuX2RhdGFbYmFieWxvbkRyYXdNb2RlXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBiYWJ5bG9uTWVzaCBvZiBiYWJ5bG9uRGF0YS5iYWJ5bG9uTWVzaGVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBFbnN1cmUgbm9uVW5pZm9ybVNjYWxpbmcgaXMgc2V0IGlmIG5lY2Vzc2FyeS5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhYnlsb25NZXNoLmNvbXB1dGVXb3JsZE1hdHJpeCh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uTWF0ZXJpYWwgPSBiYWJ5bG9uRGF0YS5iYWJ5bG9uTWF0ZXJpYWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKGJhYnlsb25NYXRlcmlhbC5mb3JjZUNvbXBpbGF0aW9uQXN5bmMoYmFieWxvbk1lc2gpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goYmFieWxvbk1hdGVyaWFsLmZvcmNlQ29tcGlsYXRpb25Bc3luYyhiYWJ5bG9uTWVzaCwgeyB1c2VJbnN0YW5jZXM6IHRydWUgfSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3BhcmVudC51c2VDbGlwUGxhbmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKGJhYnlsb25NYXRlcmlhbC5mb3JjZUNvbXBpbGF0aW9uQXN5bmMoYmFieWxvbk1lc2gsIHsgY2xpcFBsYW5lOiB0cnVlIH0pKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKGJhYnlsb25NYXRlcmlhbC5mb3JjZUNvbXBpbGF0aW9uQXN5bmMoYmFieWxvbk1lc2gsIHsgY2xpcFBsYW5lOiB0cnVlLCB1c2VJbnN0YW5jZXM6IHRydWUgfSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9wYXJlbnQuX2VuZFBlcmZvcm1hbmNlQ291bnRlcihcIkNvbXBpbGUgbWF0ZXJpYWxzXCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2NvbXBpbGVTaGFkb3dHZW5lcmF0b3JzQXN5bmMoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgdGhpcy5fcGFyZW50Ll9zdGFydFBlcmZvcm1hbmNlQ291bnRlcihcIkNvbXBpbGUgc2hhZG93IGdlbmVyYXRvcnNcIik7XHJcblxyXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dW5rbm93bj4+KCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGxpZ2h0cyA9IHRoaXMuX2JhYnlsb25TY2VuZS5saWdodHM7XHJcbiAgICAgICAgZm9yIChjb25zdCBsaWdodCBvZiBsaWdodHMpIHtcclxuICAgICAgICAgICAgY29uc3QgZ2VuZXJhdG9yID0gbGlnaHQuZ2V0U2hhZG93R2VuZXJhdG9yKCk7XHJcbiAgICAgICAgICAgIGlmIChnZW5lcmF0b3IpIHtcclxuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goZ2VuZXJhdG9yLmZvcmNlQ29tcGlsYXRpb25Bc3luYygpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fcGFyZW50Ll9lbmRQZXJmb3JtYW5jZUNvdW50ZXIoXCJDb21waWxlIHNoYWRvdyBnZW5lcmF0b3JzXCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2ZvckVhY2hFeHRlbnNpb25zKGFjdGlvbjogKGV4dGVuc2lvbjogSUdMVEZMb2FkZXJFeHRlbnNpb24pID0+IHZvaWQpOiB2b2lkIHtcclxuICAgICAgICBmb3IgKGNvbnN0IGV4dGVuc2lvbiBvZiB0aGlzLl9leHRlbnNpb25zKSB7XHJcbiAgICAgICAgICAgIGlmIChleHRlbnNpb24uZW5hYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgYWN0aW9uKGV4dGVuc2lvbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfYXBwbHlFeHRlbnNpb25zPFQ+KHByb3BlcnR5OiBJUHJvcGVydHksIGZ1bmN0aW9uTmFtZTogc3RyaW5nLCBhY3Rpb25Bc3luYzogKGV4dGVuc2lvbjogSUdMVEZMb2FkZXJFeHRlbnNpb24pID0+IE51bGxhYmxlPFQ+IHwgdW5kZWZpbmVkKTogTnVsbGFibGU8VD4ge1xyXG4gICAgICAgIGZvciAoY29uc3QgZXh0ZW5zaW9uIG9mIHRoaXMuX2V4dGVuc2lvbnMpIHtcclxuICAgICAgICAgICAgaWYgKGV4dGVuc2lvbi5lbmFibGVkKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpZCA9IGAke2V4dGVuc2lvbi5uYW1lfS4ke2Z1bmN0aW9uTmFtZX1gO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbG9hZGVyUHJvcGVydHkgPSBwcm9wZXJ0eSBhcyBJTG9hZGVyUHJvcGVydHk7XHJcbiAgICAgICAgICAgICAgICBsb2FkZXJQcm9wZXJ0eS5fYWN0aXZlTG9hZGVyRXh0ZW5zaW9uRnVuY3Rpb25zID0gbG9hZGVyUHJvcGVydHkuX2FjdGl2ZUxvYWRlckV4dGVuc2lvbkZ1bmN0aW9ucyB8fCB7fTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGFjdGl2ZUxvYWRlckV4dGVuc2lvbkZ1bmN0aW9ucyA9IGxvYWRlclByb3BlcnR5Ll9hY3RpdmVMb2FkZXJFeHRlbnNpb25GdW5jdGlvbnM7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWFjdGl2ZUxvYWRlckV4dGVuc2lvbkZ1bmN0aW9uc1tpZF0pIHtcclxuICAgICAgICAgICAgICAgICAgICBhY3RpdmVMb2FkZXJFeHRlbnNpb25GdW5jdGlvbnNbaWRdID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYWN0aW9uQXN5bmMoZXh0ZW5zaW9uKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBhY3RpdmVMb2FkZXJFeHRlbnNpb25GdW5jdGlvbnNbaWRdO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXh0ZW5zaW9uc09uTG9hZGluZygpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9mb3JFYWNoRXh0ZW5zaW9ucygoZXh0ZW5zaW9uKSA9PiBleHRlbnNpb24ub25Mb2FkaW5nICYmIGV4dGVuc2lvbi5vbkxvYWRpbmcoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXh0ZW5zaW9uc09uUmVhZHkoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fZm9yRWFjaEV4dGVuc2lvbnMoKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLm9uUmVhZHkgJiYgZXh0ZW5zaW9uLm9uUmVhZHkoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXh0ZW5zaW9uc0xvYWRTY2VuZUFzeW5jKGNvbnRleHQ6IHN0cmluZywgc2NlbmU6IElTY2VuZSk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlFeHRlbnNpb25zKHNjZW5lLCBcImxvYWRTY2VuZVwiLCAoZXh0ZW5zaW9uKSA9PiBleHRlbnNpb24ubG9hZFNjZW5lQXN5bmMgJiYgZXh0ZW5zaW9uLmxvYWRTY2VuZUFzeW5jKGNvbnRleHQsIHNjZW5lKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXh0ZW5zaW9uc0xvYWROb2RlQXN5bmMoY29udGV4dDogc3RyaW5nLCBub2RlOiBJTm9kZSwgYXNzaWduOiAoYmFieWxvblRyYW5zZm9ybU5vZGU6IFRyYW5zZm9ybU5vZGUpID0+IHZvaWQpOiBOdWxsYWJsZTxQcm9taXNlPFRyYW5zZm9ybU5vZGU+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5RXh0ZW5zaW9ucyhub2RlLCBcImxvYWROb2RlXCIsIChleHRlbnNpb24pID0+IGV4dGVuc2lvbi5sb2FkTm9kZUFzeW5jICYmIGV4dGVuc2lvbi5sb2FkTm9kZUFzeW5jKGNvbnRleHQsIG5vZGUsIGFzc2lnbikpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNMb2FkQ2FtZXJhQXN5bmMoY29udGV4dDogc3RyaW5nLCBjYW1lcmE6IElDYW1lcmEsIGFzc2lnbjogKGJhYnlsb25DYW1lcmE6IENhbWVyYSkgPT4gdm9pZCk6IE51bGxhYmxlPFByb21pc2U8Q2FtZXJhPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUV4dGVuc2lvbnMoY2FtZXJhLCBcImxvYWRDYW1lcmFcIiwgKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLmxvYWRDYW1lcmFBc3luYyAmJiBleHRlbnNpb24ubG9hZENhbWVyYUFzeW5jKGNvbnRleHQsIGNhbWVyYSwgYXNzaWduKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXh0ZW5zaW9uc0xvYWRWZXJ0ZXhEYXRhQXN5bmMoY29udGV4dDogc3RyaW5nLCBwcmltaXRpdmU6IElNZXNoUHJpbWl0aXZlLCBiYWJ5bG9uTWVzaDogTWVzaCk6IE51bGxhYmxlPFByb21pc2U8R2VvbWV0cnk+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5RXh0ZW5zaW9ucyhwcmltaXRpdmUsIFwibG9hZFZlcnRleERhdGFcIiwgKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLl9sb2FkVmVydGV4RGF0YUFzeW5jICYmIGV4dGVuc2lvbi5fbG9hZFZlcnRleERhdGFBc3luYyhjb250ZXh0LCBwcmltaXRpdmUsIGJhYnlsb25NZXNoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXh0ZW5zaW9uc0xvYWRNZXNoUHJpbWl0aXZlQXN5bmMoXHJcbiAgICAgICAgY29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIG5hbWU6IHN0cmluZyxcclxuICAgICAgICBub2RlOiBJTm9kZSxcclxuICAgICAgICBtZXNoOiBJTWVzaCxcclxuICAgICAgICBwcmltaXRpdmU6IElNZXNoUHJpbWl0aXZlLFxyXG4gICAgICAgIGFzc2lnbjogKGJhYnlsb25NZXNoOiBBYnN0cmFjdE1lc2gpID0+IHZvaWRcclxuICAgICk6IE51bGxhYmxlPFByb21pc2U8QWJzdHJhY3RNZXNoPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUV4dGVuc2lvbnMoXHJcbiAgICAgICAgICAgIHByaW1pdGl2ZSxcclxuICAgICAgICAgICAgXCJsb2FkTWVzaFByaW1pdGl2ZVwiLFxyXG4gICAgICAgICAgICAoZXh0ZW5zaW9uKSA9PiBleHRlbnNpb24uX2xvYWRNZXNoUHJpbWl0aXZlQXN5bmMgJiYgZXh0ZW5zaW9uLl9sb2FkTWVzaFByaW1pdGl2ZUFzeW5jKGNvbnRleHQsIG5hbWUsIG5vZGUsIG1lc2gsIHByaW1pdGl2ZSwgYXNzaWduKVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXh0ZW5zaW9uc0xvYWRNYXRlcmlhbEFzeW5jKFxyXG4gICAgICAgIGNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBtYXRlcmlhbDogSU1hdGVyaWFsLFxyXG4gICAgICAgIGJhYnlsb25NZXNoOiBOdWxsYWJsZTxNZXNoPixcclxuICAgICAgICBiYWJ5bG9uRHJhd01vZGU6IG51bWJlcixcclxuICAgICAgICBhc3NpZ246IChiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKSA9PiB2b2lkXHJcbiAgICApOiBOdWxsYWJsZTxQcm9taXNlPE1hdGVyaWFsPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUV4dGVuc2lvbnMoXHJcbiAgICAgICAgICAgIG1hdGVyaWFsLFxyXG4gICAgICAgICAgICBcImxvYWRNYXRlcmlhbFwiLFxyXG4gICAgICAgICAgICAoZXh0ZW5zaW9uKSA9PiBleHRlbnNpb24uX2xvYWRNYXRlcmlhbEFzeW5jICYmIGV4dGVuc2lvbi5fbG9hZE1hdGVyaWFsQXN5bmMoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25NZXNoLCBiYWJ5bG9uRHJhd01vZGUsIGFzc2lnbilcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNDcmVhdGVNYXRlcmlhbChjb250ZXh0OiBzdHJpbmcsIG1hdGVyaWFsOiBJTWF0ZXJpYWwsIGJhYnlsb25EcmF3TW9kZTogbnVtYmVyKTogTnVsbGFibGU8TWF0ZXJpYWw+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlFeHRlbnNpb25zKG1hdGVyaWFsLCBcImNyZWF0ZU1hdGVyaWFsXCIsIChleHRlbnNpb24pID0+IGV4dGVuc2lvbi5jcmVhdGVNYXRlcmlhbCAmJiBleHRlbnNpb24uY3JlYXRlTWF0ZXJpYWwoY29udGV4dCwgbWF0ZXJpYWwsIGJhYnlsb25EcmF3TW9kZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNMb2FkTWF0ZXJpYWxQcm9wZXJ0aWVzQXN5bmMoY29udGV4dDogc3RyaW5nLCBtYXRlcmlhbDogSU1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWw6IE1hdGVyaWFsKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUV4dGVuc2lvbnMoXHJcbiAgICAgICAgICAgIG1hdGVyaWFsLFxyXG4gICAgICAgICAgICBcImxvYWRNYXRlcmlhbFByb3BlcnRpZXNcIixcclxuICAgICAgICAgICAgKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLmxvYWRNYXRlcmlhbFByb3BlcnRpZXNBc3luYyAmJiBleHRlbnNpb24ubG9hZE1hdGVyaWFsUHJvcGVydGllc0FzeW5jKGNvbnRleHQsIG1hdGVyaWFsLCBiYWJ5bG9uTWF0ZXJpYWwpXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9leHRlbnNpb25zTG9hZFRleHR1cmVJbmZvQXN5bmMoY29udGV4dDogc3RyaW5nLCB0ZXh0dXJlSW5mbzogSVRleHR1cmVJbmZvLCBhc3NpZ246IChiYWJ5bG9uVGV4dHVyZTogQmFzZVRleHR1cmUpID0+IHZvaWQpOiBOdWxsYWJsZTxQcm9taXNlPEJhc2VUZXh0dXJlPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUV4dGVuc2lvbnModGV4dHVyZUluZm8sIFwibG9hZFRleHR1cmVJbmZvXCIsIChleHRlbnNpb24pID0+IGV4dGVuc2lvbi5sb2FkVGV4dHVyZUluZm9Bc3luYyAmJiBleHRlbnNpb24ubG9hZFRleHR1cmVJbmZvQXN5bmMoY29udGV4dCwgdGV4dHVyZUluZm8sIGFzc2lnbikpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNMb2FkVGV4dHVyZUFzeW5jKGNvbnRleHQ6IHN0cmluZywgdGV4dHVyZTogSVRleHR1cmUsIGFzc2lnbjogKGJhYnlsb25UZXh0dXJlOiBCYXNlVGV4dHVyZSkgPT4gdm9pZCk6IE51bGxhYmxlPFByb21pc2U8QmFzZVRleHR1cmU+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5RXh0ZW5zaW9ucyh0ZXh0dXJlLCBcImxvYWRUZXh0dXJlXCIsIChleHRlbnNpb24pID0+IGV4dGVuc2lvbi5fbG9hZFRleHR1cmVBc3luYyAmJiBleHRlbnNpb24uX2xvYWRUZXh0dXJlQXN5bmMoY29udGV4dCwgdGV4dHVyZSwgYXNzaWduKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXh0ZW5zaW9uc0xvYWRBbmltYXRpb25Bc3luYyhjb250ZXh0OiBzdHJpbmcsIGFuaW1hdGlvbjogSUFuaW1hdGlvbik6IE51bGxhYmxlPFByb21pc2U8QW5pbWF0aW9uR3JvdXA+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5RXh0ZW5zaW9ucyhhbmltYXRpb24sIFwibG9hZEFuaW1hdGlvblwiLCAoZXh0ZW5zaW9uKSA9PiBleHRlbnNpb24ubG9hZEFuaW1hdGlvbkFzeW5jICYmIGV4dGVuc2lvbi5sb2FkQW5pbWF0aW9uQXN5bmMoY29udGV4dCwgYW5pbWF0aW9uKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZXh0ZW5zaW9uc0xvYWRBbmltYXRpb25DaGFubmVsQXN5bmMoXHJcbiAgICAgICAgY29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIGFuaW1hdGlvbkNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBhbmltYXRpb246IElBbmltYXRpb24sXHJcbiAgICAgICAgY2hhbm5lbDogSUFuaW1hdGlvbkNoYW5uZWwsXHJcbiAgICAgICAgb25Mb2FkOiAoYmFieWxvbkFuaW1hdGFibGU6IElBbmltYXRhYmxlLCBiYWJ5bG9uQW5pbWF0aW9uOiBBbmltYXRpb24pID0+IHZvaWRcclxuICAgICk6IE51bGxhYmxlPFByb21pc2U8dm9pZD4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlFeHRlbnNpb25zKFxyXG4gICAgICAgICAgICBhbmltYXRpb24sXHJcbiAgICAgICAgICAgIFwibG9hZEFuaW1hdGlvbkNoYW5uZWxcIixcclxuICAgICAgICAgICAgKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLl9sb2FkQW5pbWF0aW9uQ2hhbm5lbEFzeW5jICYmIGV4dGVuc2lvbi5fbG9hZEFuaW1hdGlvbkNoYW5uZWxBc3luYyhjb250ZXh0LCBhbmltYXRpb25Db250ZXh0LCBhbmltYXRpb24sIGNoYW5uZWwsIG9uTG9hZClcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNMb2FkU2tpbkFzeW5jKGNvbnRleHQ6IHN0cmluZywgbm9kZTogSU5vZGUsIHNraW46IElTa2luKTogTnVsbGFibGU8UHJvbWlzZTx2b2lkPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hcHBseUV4dGVuc2lvbnMoc2tpbiwgXCJsb2FkU2tpblwiLCAoZXh0ZW5zaW9uKSA9PiBleHRlbnNpb24uX2xvYWRTa2luQXN5bmMgJiYgZXh0ZW5zaW9uLl9sb2FkU2tpbkFzeW5jKGNvbnRleHQsIG5vZGUsIHNraW4pKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9leHRlbnNpb25zTG9hZFVyaUFzeW5jKGNvbnRleHQ6IHN0cmluZywgcHJvcGVydHk6IElQcm9wZXJ0eSwgdXJpOiBzdHJpbmcpOiBOdWxsYWJsZTxQcm9taXNlPEFycmF5QnVmZmVyVmlldz4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlFeHRlbnNpb25zKHByb3BlcnR5LCBcImxvYWRVcmlcIiwgKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLl9sb2FkVXJpQXN5bmMgJiYgZXh0ZW5zaW9uLl9sb2FkVXJpQXN5bmMoY29udGV4dCwgcHJvcGVydHksIHVyaSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNMb2FkQnVmZmVyVmlld0FzeW5jKGNvbnRleHQ6IHN0cmluZywgYnVmZmVyVmlldzogSUJ1ZmZlclZpZXcpOiBOdWxsYWJsZTxQcm9taXNlPEFycmF5QnVmZmVyVmlldz4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYXBwbHlFeHRlbnNpb25zKGJ1ZmZlclZpZXcsIFwibG9hZEJ1ZmZlclZpZXdcIiwgKGV4dGVuc2lvbikgPT4gZXh0ZW5zaW9uLmxvYWRCdWZmZXJWaWV3QXN5bmMgJiYgZXh0ZW5zaW9uLmxvYWRCdWZmZXJWaWV3QXN5bmMoY29udGV4dCwgYnVmZmVyVmlldykpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2V4dGVuc2lvbnNMb2FkQnVmZmVyQXN5bmMoY29udGV4dDogc3RyaW5nLCBidWZmZXI6IElCdWZmZXIsIGJ5dGVPZmZzZXQ6IG51bWJlciwgYnl0ZUxlbmd0aDogbnVtYmVyKTogTnVsbGFibGU8UHJvbWlzZTxBcnJheUJ1ZmZlclZpZXc+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FwcGx5RXh0ZW5zaW9ucyhidWZmZXIsIFwibG9hZEJ1ZmZlclwiLCAoZXh0ZW5zaW9uKSA9PiBleHRlbnNpb24ubG9hZEJ1ZmZlckFzeW5jICYmIGV4dGVuc2lvbi5sb2FkQnVmZmVyQXN5bmMoY29udGV4dCwgYnVmZmVyLCBieXRlT2Zmc2V0LCBieXRlTGVuZ3RoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIZWxwZXIgbWV0aG9kIGNhbGxlZCBieSBhIGxvYWRlciBleHRlbnNpb24gdG8gbG9hZCBhbiBnbFRGIGV4dGVuc2lvbi5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBwcm9wZXJ0eSBUaGUgZ2xURiBwcm9wZXJ0eSB0byBsb2FkIHRoZSBleHRlbnNpb24gZnJvbVxyXG4gICAgICogQHBhcmFtIGV4dGVuc2lvbk5hbWUgVGhlIG5hbWUgb2YgdGhlIGV4dGVuc2lvbiB0byBsb2FkXHJcbiAgICAgKiBAcGFyYW0gYWN0aW9uQXN5bmMgVGhlIGFjdGlvbiB0byBydW5cclxuICAgICAqIEByZXR1cm5zIFRoZSBwcm9taXNlIHJldHVybmVkIGJ5IGFjdGlvbkFzeW5jIG9yIG51bGwgaWYgdGhlIGV4dGVuc2lvbiBkb2VzIG5vdCBleGlzdFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIExvYWRFeHRlbnNpb25Bc3luYzxURXh0ZW5zaW9uID0gdW5rbm93biwgVFJlc3VsdCA9IHZvaWQ+KFxyXG4gICAgICAgIGNvbnRleHQ6IHN0cmluZyxcclxuICAgICAgICBwcm9wZXJ0eTogSVByb3BlcnR5LFxyXG4gICAgICAgIGV4dGVuc2lvbk5hbWU6IHN0cmluZyxcclxuICAgICAgICBhY3Rpb25Bc3luYzogKGV4dGVuc2lvbkNvbnRleHQ6IHN0cmluZywgZXh0ZW5zaW9uOiBURXh0ZW5zaW9uKSA9PiBOdWxsYWJsZTxQcm9taXNlPFRSZXN1bHQ+PlxyXG4gICAgKTogTnVsbGFibGU8UHJvbWlzZTxUUmVzdWx0Pj4ge1xyXG4gICAgICAgIGlmICghcHJvcGVydHkuZXh0ZW5zaW9ucykge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbnMgPSBwcm9wZXJ0eS5leHRlbnNpb25zO1xyXG5cclxuICAgICAgICBjb25zdCBleHRlbnNpb24gPSBleHRlbnNpb25zW2V4dGVuc2lvbk5hbWVdIGFzIFRFeHRlbnNpb247XHJcbiAgICAgICAgaWYgKCFleHRlbnNpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYWN0aW9uQXN5bmMoYCR7Y29udGV4dH0vZXh0ZW5zaW9ucy8ke2V4dGVuc2lvbk5hbWV9YCwgZXh0ZW5zaW9uKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhlbHBlciBtZXRob2QgY2FsbGVkIGJ5IGEgbG9hZGVyIGV4dGVuc2lvbiB0byBsb2FkIGEgZ2xURiBleHRyYS5cclxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IHdoZW4gbG9hZGluZyB0aGUgYXNzZXRcclxuICAgICAqIEBwYXJhbSBwcm9wZXJ0eSBUaGUgZ2xURiBwcm9wZXJ0eSB0byBsb2FkIHRoZSBleHRyYSBmcm9tXHJcbiAgICAgKiBAcGFyYW0gZXh0ZW5zaW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHRvIGxvYWRcclxuICAgICAqIEBwYXJhbSBhY3Rpb25Bc3luYyBUaGUgYWN0aW9uIHRvIHJ1blxyXG4gICAgICogQHJldHVybnMgVGhlIHByb21pc2UgcmV0dXJuZWQgYnkgYWN0aW9uQXN5bmMgb3IgbnVsbCBpZiB0aGUgZXh0cmEgZG9lcyBub3QgZXhpc3RcclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBMb2FkRXh0cmFBc3luYzxURXh0cmEgPSB1bmtub3duLCBUUmVzdWx0ID0gdm9pZD4oXHJcbiAgICAgICAgY29udGV4dDogc3RyaW5nLFxyXG4gICAgICAgIHByb3BlcnR5OiBJUHJvcGVydHksXHJcbiAgICAgICAgZXh0ZW5zaW9uTmFtZTogc3RyaW5nLFxyXG4gICAgICAgIGFjdGlvbkFzeW5jOiAoZXh0cmFDb250ZXh0OiBzdHJpbmcsIGV4dHJhOiBURXh0cmEpID0+IE51bGxhYmxlPFByb21pc2U8VFJlc3VsdD4+XHJcbiAgICApOiBOdWxsYWJsZTxQcm9taXNlPFRSZXN1bHQ+PiB7XHJcbiAgICAgICAgaWYgKCFwcm9wZXJ0eS5leHRyYXMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBleHRyYXMgPSBwcm9wZXJ0eS5leHRyYXM7XHJcblxyXG4gICAgICAgIGNvbnN0IGV4dHJhID0gZXh0cmFzW2V4dGVuc2lvbk5hbWVdIGFzIFRFeHRyYTtcclxuICAgICAgICBpZiAoIWV4dHJhKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGFjdGlvbkFzeW5jKGAke2NvbnRleHR9L2V4dHJhcy8ke2V4dGVuc2lvbk5hbWV9YCwgZXh0cmEpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2hlY2tzIGZvciBwcmVzZW5jZSBvZiBhbiBleHRlbnNpb24uXHJcbiAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHRvIGNoZWNrXHJcbiAgICAgKiBAcmV0dXJucyBBIGJvb2xlYW4gaW5kaWNhdGluZyB0aGUgcHJlc2VuY2Ugb2YgdGhlIGdpdmVuIGV4dGVuc2lvbiBuYW1lIGluIGBleHRlbnNpb25zVXNlZGBcclxuICAgICAqL1xyXG4gICAgcHVibGljIGlzRXh0ZW5zaW9uVXNlZChuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gISF0aGlzLl9nbHRmLmV4dGVuc2lvbnNVc2VkICYmIHRoaXMuX2dsdGYuZXh0ZW5zaW9uc1VzZWQuaW5kZXhPZihuYW1lKSAhPT0gLTE7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbmNyZW1lbnRzIHRoZSBpbmRlbnRhdGlvbiBsZXZlbCBhbmQgbG9ncyBhIG1lc3NhZ2UuXHJcbiAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBsb2dcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvZ09wZW4obWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fcGFyZW50Ll9sb2dPcGVuKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVjcmVtZW50cyB0aGUgaW5kZW50YXRpb24gbGV2ZWwuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2dDbG9zZSgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9wYXJlbnQuX2xvZ0Nsb3NlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMb2dzIGEgbWVzc2FnZVxyXG4gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gbG9nXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2cobWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fcGFyZW50Ll9sb2cobWVzc2FnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTdGFydHMgYSBwZXJmb3JtYW5jZSBjb3VudGVyLlxyXG4gICAgICogQHBhcmFtIGNvdW50ZXJOYW1lIFRoZSBuYW1lIG9mIHRoZSBwZXJmb3JtYW5jZSBjb3VudGVyXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGFydFBlcmZvcm1hbmNlQ291bnRlcihjb3VudGVyTmFtZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fcGFyZW50Ll9zdGFydFBlcmZvcm1hbmNlQ291bnRlcihjb3VudGVyTmFtZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmRzIGEgcGVyZm9ybWFuY2UgY291bnRlci5cclxuICAgICAqIEBwYXJhbSBjb3VudGVyTmFtZSBUaGUgbmFtZSBvZiB0aGUgcGVyZm9ybWFuY2UgY291bnRlclxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZW5kUGVyZm9ybWFuY2VDb3VudGVyKGNvdW50ZXJOYW1lOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9wYXJlbnQuX2VuZFBlcmZvcm1hbmNlQ291bnRlcihjb3VudGVyTmFtZSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbkdMVEZGaWxlTG9hZGVyLl9DcmVhdGVHTFRGMkxvYWRlciA9IChwYXJlbnQpID0+IG5ldyBHTFRGTG9hZGVyKHBhcmVudCk7XHJcbiIsImltcG9ydCB7IEFuaW1hdGlvbiB9IGZyb20gXCJjb3JlL0FuaW1hdGlvbnMvYW5pbWF0aW9uXCI7XHJcbmltcG9ydCB7IFF1YXRlcm5pb24sIFZlY3RvcjMgfSBmcm9tIFwiY29yZS9NYXRocy9tYXRoLnZlY3RvclwiO1xyXG5pbXBvcnQgdHlwZSB7IElOb2RlIH0gZnJvbSBcIi4vZ2xURkxvYWRlckludGVyZmFjZXNcIjtcclxuaW1wb3J0IHR5cGUgeyBJQW5pbWF0YWJsZSB9IGZyb20gXCJjb3JlL0FuaW1hdGlvbnMvYW5pbWF0YWJsZS5pbnRlcmZhY2VcIjtcclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IHR5cGUgR2V0VmFsdWVGbiA9ICh0YXJnZXQ6IGFueSwgc291cmNlOiBGbG9hdDMyQXJyYXksIG9mZnNldDogbnVtYmVyLCBzY2FsZTogbnVtYmVyKSA9PiBhbnk7XHJcblxyXG4vKiogQGludGVybmFsICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRWZWN0b3IzKF90YXJnZXQ6IGFueSwgc291cmNlOiBGbG9hdDMyQXJyYXksIG9mZnNldDogbnVtYmVyLCBzY2FsZTogbnVtYmVyKTogVmVjdG9yMyB7XHJcbiAgICByZXR1cm4gVmVjdG9yMy5Gcm9tQXJyYXkoc291cmNlLCBvZmZzZXQpLnNjYWxlSW5QbGFjZShzY2FsZSk7XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldFF1YXRlcm5pb24oX3RhcmdldDogYW55LCBzb3VyY2U6IEZsb2F0MzJBcnJheSwgb2Zmc2V0OiBudW1iZXIsIHNjYWxlOiBudW1iZXIpOiBRdWF0ZXJuaW9uIHtcclxuICAgIHJldHVybiBRdWF0ZXJuaW9uLkZyb21BcnJheShzb3VyY2UsIG9mZnNldCkuc2NhbGVJblBsYWNlKHNjYWxlKTtcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0V2VpZ2h0cyh0YXJnZXQ6IElOb2RlLCBzb3VyY2U6IEZsb2F0MzJBcnJheSwgb2Zmc2V0OiBudW1iZXIsIHNjYWxlOiBudW1iZXIpOiBBcnJheTxudW1iZXI+IHtcclxuICAgIGNvbnN0IHZhbHVlID0gbmV3IEFycmF5PG51bWJlcj4odGFyZ2V0Ll9udW1Nb3JwaFRhcmdldHMhKTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICB2YWx1ZVtpXSA9IHNvdXJjZVtvZmZzZXQrK10gKiBzY2FsZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFuaW1hdGlvblByb3BlcnR5SW5mbyB7XHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHVibGljIHJlYWRvbmx5IHR5cGU6IG51bWJlcixcclxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogc3RyaW5nLFxyXG4gICAgICAgIHB1YmxpYyByZWFkb25seSBnZXRWYWx1ZTogR2V0VmFsdWVGbixcclxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgZ2V0U3RyaWRlOiAodGFyZ2V0OiBhbnkpID0+IG51bWJlclxyXG4gICAgKSB7fVxyXG5cclxuICAgIHByb3RlY3RlZCBfYnVpbGRBbmltYXRpb24obmFtZTogc3RyaW5nLCBmcHM6IG51bWJlciwga2V5czogYW55W10pOiBBbmltYXRpb24ge1xyXG4gICAgICAgIGNvbnN0IGJhYnlsb25BbmltYXRpb24gPSBuZXcgQW5pbWF0aW9uKG5hbWUsIHRoaXMubmFtZSwgZnBzLCB0aGlzLnR5cGUpO1xyXG4gICAgICAgIGJhYnlsb25BbmltYXRpb24uc2V0S2V5cyhrZXlzKTtcclxuICAgICAgICByZXR1cm4gYmFieWxvbkFuaW1hdGlvbjtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGludGVybmFsICovXHJcbiAgICBwdWJsaWMgYWJzdHJhY3QgYnVpbGRBbmltYXRpb25zKHRhcmdldDogYW55LCBuYW1lOiBzdHJpbmcsIGZwczogbnVtYmVyLCBrZXlzOiBhbnlbXSwgY2FsbGJhY2s6IChiYWJ5bG9uQW5pbWF0YWJsZTogSUFuaW1hdGFibGUsIGJhYnlsb25BbmltYXRpb246IEFuaW1hdGlvbikgPT4gdm9pZCk6IHZvaWQ7XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGNsYXNzIFRyYW5zZm9ybU5vZGVBbmltYXRpb25Qcm9wZXJ0eUluZm8gZXh0ZW5kcyBBbmltYXRpb25Qcm9wZXJ0eUluZm8ge1xyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIGJ1aWxkQW5pbWF0aW9ucyh0YXJnZXQ6IElOb2RlLCBuYW1lOiBzdHJpbmcsIGZwczogbnVtYmVyLCBrZXlzOiBhbnlbXSwgY2FsbGJhY2s6IChiYWJ5bG9uQW5pbWF0YWJsZTogSUFuaW1hdGFibGUsIGJhYnlsb25BbmltYXRpb246IEFuaW1hdGlvbikgPT4gdm9pZCk6IHZvaWQge1xyXG4gICAgICAgIGNhbGxiYWNrKHRhcmdldC5fYmFieWxvblRyYW5zZm9ybU5vZGUhLCB0aGlzLl9idWlsZEFuaW1hdGlvbihuYW1lLCBmcHMsIGtleXMpKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgY2xhc3MgV2VpZ2h0QW5pbWF0aW9uUHJvcGVydHlJbmZvIGV4dGVuZHMgQW5pbWF0aW9uUHJvcGVydHlJbmZvIHtcclxuICAgIHB1YmxpYyBidWlsZEFuaW1hdGlvbnModGFyZ2V0OiBJTm9kZSwgbmFtZTogc3RyaW5nLCBmcHM6IG51bWJlciwga2V5czogYW55W10sIGNhbGxiYWNrOiAoYmFieWxvbkFuaW1hdGFibGU6IElBbmltYXRhYmxlLCBiYWJ5bG9uQW5pbWF0aW9uOiBBbmltYXRpb24pID0+IHZvaWQpOiB2b2lkIHtcclxuICAgICAgICBpZiAodGFyZ2V0Ll9udW1Nb3JwaFRhcmdldHMpIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgdGFyZ2V0SW5kZXggPSAwOyB0YXJnZXRJbmRleCA8IHRhcmdldC5fbnVtTW9ycGhUYXJnZXRzOyB0YXJnZXRJbmRleCsrKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBiYWJ5bG9uQW5pbWF0aW9uID0gbmV3IEFuaW1hdGlvbihgJHtuYW1lfV8ke3RhcmdldEluZGV4fWAsIHRoaXMubmFtZSwgZnBzLCB0aGlzLnR5cGUpO1xyXG4gICAgICAgICAgICAgICAgYmFieWxvbkFuaW1hdGlvbi5zZXRLZXlzKFxyXG4gICAgICAgICAgICAgICAgICAgIGtleXMubWFwKChrZXkpID0+ICh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lOiBrZXkuZnJhbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluVGFuZ2VudDoga2V5LmluVGFuZ2VudCA/IGtleS5pblRhbmdlbnRbdGFyZ2V0SW5kZXhdIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZToga2V5LnZhbHVlW3RhcmdldEluZGV4XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3V0VGFuZ2VudDoga2V5Lm91dFRhbmdlbnQgPyBrZXkub3V0VGFuZ2VudFt0YXJnZXRJbmRleF0gOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGludGVycG9sYXRpb246IGtleS5pbnRlcnBvbGF0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgIH0pKVxyXG4gICAgICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodGFyZ2V0Ll9wcmltaXRpdmVCYWJ5bG9uTWVzaGVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBiYWJ5bG9uTWVzaCBvZiB0YXJnZXQuX3ByaW1pdGl2ZUJhYnlsb25NZXNoZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJhYnlsb25NZXNoLm1vcnBoVGFyZ2V0TWFuYWdlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbW9ycGhUYXJnZXQgPSBiYWJ5bG9uTWVzaC5tb3JwaFRhcmdldE1hbmFnZXIuZ2V0VGFyZ2V0KHRhcmdldEluZGV4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJhYnlsb25BbmltYXRpb25DbG9uZSA9IGJhYnlsb25BbmltYXRpb24uY2xvbmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vcnBoVGFyZ2V0LmFuaW1hdGlvbnMucHVzaChiYWJ5bG9uQW5pbWF0aW9uQ2xvbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobW9ycGhUYXJnZXQsIGJhYnlsb25BbmltYXRpb25DbG9uZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGNvbnN0IG5vZGVBbmltYXRpb25EYXRhID0ge1xyXG4gICAgdHJhbnNsYXRpb246IFtuZXcgVHJhbnNmb3JtTm9kZUFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9WRUNUT1IzLCBcInBvc2l0aW9uXCIsIGdldFZlY3RvcjMsICgpID0+IDMpXSxcclxuICAgIHJvdGF0aW9uOiBbbmV3IFRyYW5zZm9ybU5vZGVBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfUVVBVEVSTklPTiwgXCJyb3RhdGlvblF1YXRlcm5pb25cIiwgZ2V0UXVhdGVybmlvbiwgKCkgPT4gNCldLFxyXG4gICAgc2NhbGU6IFtuZXcgVHJhbnNmb3JtTm9kZUFuaW1hdGlvblByb3BlcnR5SW5mbyhBbmltYXRpb24uQU5JTUFUSU9OVFlQRV9WRUNUT1IzLCBcInNjYWxpbmdcIiwgZ2V0VmVjdG9yMywgKCkgPT4gMyldLFxyXG4gICAgd2VpZ2h0czogW25ldyBXZWlnaHRBbmltYXRpb25Qcm9wZXJ0eUluZm8oQW5pbWF0aW9uLkFOSU1BVElPTlRZUEVfRkxPQVQsIFwiaW5mbHVlbmNlXCIsIGdldFdlaWdodHMsICh0YXJnZXQpID0+IHRhcmdldC5fbnVtTW9ycGhUYXJnZXRzISldLFxyXG59O1xyXG4iLCJpbXBvcnQgdHlwZSB7IEdMVEZMb2FkZXIgfSBmcm9tIFwiLi9nbFRGTG9hZGVyXCI7XHJcbmltcG9ydCB0eXBlIHsgSUdMVEZMb2FkZXJFeHRlbnNpb24gfSBmcm9tIFwiLi9nbFRGTG9hZGVyRXh0ZW5zaW9uXCI7XHJcblxyXG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tIFwiY29yZS9NaXNjL2xvZ2dlclwiO1xyXG5cclxuaW50ZXJmYWNlIElSZWdpc3RlcmVkR0xURkV4dGVuc2lvbiB7XHJcbiAgICBpc0dMVEZFeHRlbnNpb246IGJvb2xlYW47XHJcbiAgICBmYWN0b3J5OiBHTFRGRXh0ZW5zaW9uRmFjdG9yeTtcclxufVxyXG5cclxuZXhwb3J0IHR5cGUgR0xURkV4dGVuc2lvbkZhY3RvcnkgPSAobG9hZGVyOiBHTFRGTG9hZGVyKSA9PiBJR0xURkxvYWRlckV4dGVuc2lvbiB8IFByb21pc2U8SUdMVEZMb2FkZXJFeHRlbnNpb24+O1xyXG5cclxuY29uc3QgX3JlZ2lzdGVyZWRHTFRGRXh0ZW5zaW9ucyA9IG5ldyBNYXA8c3RyaW5nLCBJUmVnaXN0ZXJlZEdMVEZFeHRlbnNpb24+KCk7XHJcblxyXG4vKipcclxuICogQWxsIGN1cnJlbnRseSByZWdpc3RlcmVkIGdsVEYgMi4wIGxvYWRlciBleHRlbnNpb25zLlxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IHJlZ2lzdGVyZWRHTFRGRXh0ZW5zaW9uczogUmVhZG9ubHlNYXA8c3RyaW5nLCBSZWFkb25seTxJUmVnaXN0ZXJlZEdMVEZFeHRlbnNpb24+PiA9IF9yZWdpc3RlcmVkR0xURkV4dGVuc2lvbnM7XHJcblxyXG4vKipcclxuICogUmVnaXN0ZXJzIGEgbG9hZGVyIGV4dGVuc2lvbi5cclxuICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGxvYWRlciBleHRlbnNpb24uXHJcbiAqIEBwYXJhbSBpc0dMVEZFeHRlbnNpb24gSWYgdGhlIGxvYWRlciBleHRlbnNpb24gaXMgYSBnbFRGIGV4dGVuc2lvbiwgdGhlbiBpdCB3aWxsIG9ubHkgYmUgdXNlZCBmb3IgZ2xURiBmaWxlcyB0aGF0IHVzZSB0aGUgY29ycmVzcG9uZGluZyBnbFRGIGV4dGVuc2lvbi4gT3RoZXJ3aXNlLCBpdCB3aWxsIGJlIHVzZWQgZm9yIGFsbCBsb2FkZWQgZ2xURiBmaWxlcy5cclxuICogQHBhcmFtIGZhY3RvcnkgVGhlIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIHRoZSBsb2FkZXIgZXh0ZW5zaW9uLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyR0xURkV4dGVuc2lvbihuYW1lOiBzdHJpbmcsIGlzR0xURkV4dGVuc2lvbjogYm9vbGVhbiwgZmFjdG9yeTogR0xURkV4dGVuc2lvbkZhY3RvcnkpOiB2b2lkIHtcclxuICAgIGlmICh1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihuYW1lKSkge1xyXG4gICAgICAgIExvZ2dlci5XYXJuKGBFeHRlbnNpb24gd2l0aCB0aGUgbmFtZSAnJHtuYW1lfScgYWxyZWFkeSBleGlzdHNgKTtcclxuICAgIH1cclxuXHJcbiAgICBfcmVnaXN0ZXJlZEdMVEZFeHRlbnNpb25zLnNldChuYW1lLCB7XHJcbiAgICAgICAgaXNHTFRGRXh0ZW5zaW9uLFxyXG4gICAgICAgIGZhY3RvcnksXHJcbiAgICB9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFVucmVnaXN0ZXJzIGEgbG9hZGVyIGV4dGVuc2lvbi5cclxuICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGxvYWRlciBleHRlbnNpb24uXHJcbiAqIEByZXR1cm5zIEEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGV4dGVuc2lvbiBoYXMgYmVlbiB1bnJlZ2lzdGVyZWRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiB1bnJlZ2lzdGVyR0xURkV4dGVuc2lvbihuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIHJldHVybiBfcmVnaXN0ZXJlZEdMVEZFeHRlbnNpb25zLmRlbGV0ZShuYW1lKTtcclxufVxyXG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvbm8taW50ZXJuYWwtbW9kdWxlcyAqL1xyXG5leHBvcnQgKiBmcm9tIFwiLi9nbFRGTG9hZGVyXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL2dsVEZMb2FkZXJFeHRlbnNpb25cIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vZ2xURkxvYWRlckV4dGVuc2lvblJlZ2lzdHJ5XCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL2dsVEZMb2FkZXJJbnRlcmZhY2VzXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL0V4dGVuc2lvbnMvaW5kZXhcIjtcclxuIiwiLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1pbnRlcm5hbC1tb2R1bGVzXHJcbmltcG9ydCB0eXBlIHsgSVNjZW5lTG9hZGVyUGx1Z2luRXh0ZW5zaW9ucywgSVNjZW5lTG9hZGVyUGx1Z2luTWV0YWRhdGEgfSBmcm9tIFwiY29yZS9pbmRleFwiO1xyXG5cclxuZXhwb3J0IGNvbnN0IEdMVEZNYWdpY0Jhc2U2NEVuY29kZWQgPSBcIloyeFVSZ1wiOyAvLyBcImdsVEZcIiBiYXNlNjQgZW5jb2RlZCAod2l0aG91dCB0aGUgcXVvdGVzISlcclxuXHJcbmV4cG9ydCBjb25zdCBHTFRGRmlsZUxvYWRlck1ldGFkYXRhID0ge1xyXG4gICAgbmFtZTogXCJnbHRmXCIsXHJcblxyXG4gICAgZXh0ZW5zaW9uczoge1xyXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuICAgICAgICBcIi5nbHRmXCI6IHsgaXNCaW5hcnk6IGZhbHNlLCBtaW1lVHlwZTogXCJtb2RlbC9nbHRmK2pzb25cIiB9LFxyXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cclxuICAgICAgICBcIi5nbGJcIjogeyBpc0JpbmFyeTogdHJ1ZSwgbWltZVR5cGU6IFwibW9kZWwvZ2x0Zi1iaW5hcnlcIiB9LFxyXG4gICAgfSBhcyBjb25zdCBzYXRpc2ZpZXMgSVNjZW5lTG9hZGVyUGx1Z2luRXh0ZW5zaW9ucyxcclxuXHJcbiAgICBjYW5EaXJlY3RMb2FkKGRhdGE6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiAoXHJcbiAgICAgICAgICAgIChkYXRhLmluZGV4T2YoXCJhc3NldFwiKSAhPT0gLTEgJiYgZGF0YS5pbmRleE9mKFwidmVyc2lvblwiKSAhPT0gLTEpIHx8XHJcbiAgICAgICAgICAgIGRhdGEuc3RhcnRzV2l0aChcImRhdGE6YmFzZTY0LFwiICsgR0xURk1hZ2ljQmFzZTY0RW5jb2RlZCkgfHwgLy8gdGhpcyBpcyB0ZWNobmljYWxseSBpbmNvcnJlY3QsIGJ1dCB3aWxsIGNvbnRpbnVlIHRvIHN1cHBvcnQgZm9yIGJhY2tjb21wYXQuXHJcbiAgICAgICAgICAgIGRhdGEuc3RhcnRzV2l0aChcImRhdGE6O2Jhc2U2NCxcIiArIEdMVEZNYWdpY0Jhc2U2NEVuY29kZWQpIHx8XHJcbiAgICAgICAgICAgIGRhdGEuc3RhcnRzV2l0aChcImRhdGE6YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtO2Jhc2U2NCxcIiArIEdMVEZNYWdpY0Jhc2U2NEVuY29kZWQpIHx8XHJcbiAgICAgICAgICAgIGRhdGEuc3RhcnRzV2l0aChcImRhdGE6bW9kZWwvZ2x0Zi1iaW5hcnk7YmFzZTY0LFwiICsgR0xURk1hZ2ljQmFzZTY0RW5jb2RlZClcclxuICAgICAgICApO1xyXG4gICAgfSxcclxufSBhcyBjb25zdCBzYXRpc2ZpZXMgSVNjZW5lTG9hZGVyUGx1Z2luTWV0YWRhdGE7XHJcbiIsIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycyAqL1xyXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24gKi9cclxuaW1wb3J0IHR5cGUgKiBhcyBHTFRGMiBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiY29yZS90eXBlc1wiO1xyXG5pbXBvcnQgdHlwZSB7IE9ic2VydmVyIH0gZnJvbSBcImNvcmUvTWlzYy9vYnNlcnZhYmxlXCI7XHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tIFwiY29yZS9NaXNjL29ic2VydmFibGVcIjtcclxuaW1wb3J0IHsgVG9vbHMgfSBmcm9tIFwiY29yZS9NaXNjL3Rvb2xzXCI7XHJcbmltcG9ydCB0eXBlIHsgQ2FtZXJhIH0gZnJvbSBcImNvcmUvQ2FtZXJhcy9jYW1lcmFcIjtcclxuaW1wb3J0IHR5cGUgeyBCYXNlVGV4dHVyZSB9IGZyb20gXCJjb3JlL01hdGVyaWFscy9UZXh0dXJlcy9iYXNlVGV4dHVyZVwiO1xyXG5pbXBvcnQgdHlwZSB7IE1hdGVyaWFsIH0gZnJvbSBcImNvcmUvTWF0ZXJpYWxzL21hdGVyaWFsXCI7XHJcbmltcG9ydCB0eXBlIHsgQWJzdHJhY3RNZXNoIH0gZnJvbSBcImNvcmUvTWVzaGVzL2Fic3RyYWN0TWVzaFwiO1xyXG5pbXBvcnQgdHlwZSB7IElTY2VuZUxvYWRlclBsdWdpbkZhY3RvcnksIElTY2VuZUxvYWRlclBsdWdpbkFzeW5jLCBJU2NlbmVMb2FkZXJQcm9ncmVzc0V2ZW50LCBJU2NlbmVMb2FkZXJBc3luY1Jlc3VsdCwgU2NlbmVMb2FkZXJQbHVnaW5PcHRpb25zIH0gZnJvbSBcImNvcmUvTG9hZGluZy9zY2VuZUxvYWRlclwiO1xyXG5pbXBvcnQgeyByZWdpc3RlclNjZW5lTG9hZGVyUGx1Z2luIH0gZnJvbSBcImNvcmUvTG9hZGluZy9zY2VuZUxvYWRlclwiO1xyXG5pbXBvcnQgeyBBc3NldENvbnRhaW5lciB9IGZyb20gXCJjb3JlL2Fzc2V0Q29udGFpbmVyXCI7XHJcbmltcG9ydCB0eXBlIHsgU2NlbmUsIElEaXNwb3NhYmxlIH0gZnJvbSBcImNvcmUvc2NlbmVcIjtcclxuaW1wb3J0IHR5cGUgeyBXZWJSZXF1ZXN0IH0gZnJvbSBcImNvcmUvTWlzYy93ZWJSZXF1ZXN0XCI7XHJcbmltcG9ydCB0eXBlIHsgSUZpbGVSZXF1ZXN0IH0gZnJvbSBcImNvcmUvTWlzYy9maWxlUmVxdWVzdFwiO1xyXG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tIFwiY29yZS9NaXNjL2xvZ2dlclwiO1xyXG5pbXBvcnQgdHlwZSB7IElEYXRhQnVmZmVyIH0gZnJvbSBcImNvcmUvTWlzYy9kYXRhUmVhZGVyXCI7XHJcbmltcG9ydCB7IERhdGFSZWFkZXIgfSBmcm9tIFwiY29yZS9NaXNjL2RhdGFSZWFkZXJcIjtcclxuaW1wb3J0IHsgR0xURlZhbGlkYXRpb24gfSBmcm9tIFwiLi9nbFRGVmFsaWRhdGlvblwiO1xyXG5pbXBvcnQgeyBHTFRGRmlsZUxvYWRlck1ldGFkYXRhLCBHTFRGTWFnaWNCYXNlNjRFbmNvZGVkIH0gZnJvbSBcIi4vZ2xURkZpbGVMb2FkZXIubWV0YWRhdGFcIjtcclxuaW1wb3J0IHR5cGUgeyBMb2FkRmlsZUVycm9yIH0gZnJvbSBcImNvcmUvTWlzYy9maWxlVG9vbHNcIjtcclxuaW1wb3J0IHsgRGVjb2RlQmFzZTY0VXJsVG9CaW5hcnkgfSBmcm9tIFwiY29yZS9NaXNjL2ZpbGVUb29sc1wiO1xyXG5pbXBvcnQgeyBSdW50aW1lRXJyb3IsIEVycm9yQ29kZXMgfSBmcm9tIFwiY29yZS9NaXNjL2Vycm9yXCI7XHJcbmltcG9ydCB0eXBlIHsgVHJhbnNmb3JtTm9kZSB9IGZyb20gXCJjb3JlL01lc2hlcy90cmFuc2Zvcm1Ob2RlXCI7XHJcbmltcG9ydCB0eXBlIHsgTW9ycGhUYXJnZXRNYW5hZ2VyIH0gZnJvbSBcImNvcmUvTW9ycGgvbW9ycGhUYXJnZXRNYW5hZ2VyXCI7XHJcblxyXG4vKipcclxuICogRGVmaW5lcyBvcHRpb25zIGZvciBnbFRGIGxvYWRlciBleHRlbnNpb25zLiBUaGlzIGludGVyZmFjZSBpcyBleHRlbmRlZCBieSBzcGVjaWZpYyBleHRlbnNpb25zLlxyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9ucyBleHRlbmRzIFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkPiB7fVxyXG5cclxuZGVjbGFyZSBtb2R1bGUgXCJjb3JlL0xvYWRpbmcvc2NlbmVMb2FkZXJcIiB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xyXG4gICAgZXhwb3J0IGludGVyZmFjZSBTY2VuZUxvYWRlclBsdWdpbk9wdGlvbnMge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlZmluZXMgb3B0aW9ucyBmb3IgdGhlIGdsVEYgbG9hZGVyLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFtHTFRGRmlsZUxvYWRlck1ldGFkYXRhLm5hbWVdOiBQYXJ0aWFsPEdMVEZMb2FkZXJPcHRpb25zPjtcclxuICAgIH1cclxufVxyXG5cclxuaW50ZXJmYWNlIElGaWxlUmVxdWVzdEluZm8gZXh0ZW5kcyBJRmlsZVJlcXVlc3Qge1xyXG4gICAgX2xlbmd0aENvbXB1dGFibGU/OiBib29sZWFuO1xyXG4gICAgX2xvYWRlZD86IG51bWJlcjtcclxuICAgIF90b3RhbD86IG51bWJlcjtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVhZEFzeW5jKGFycmF5QnVmZmVyOiBBcnJheUJ1ZmZlciwgYnl0ZU9mZnNldDogbnVtYmVyLCBieXRlTGVuZ3RoOiBudW1iZXIpOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCkpO1xyXG4gICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlKTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gcmVhZFZpZXdBc3luYyhhcnJheUJ1ZmZlclZpZXc6IEFycmF5QnVmZmVyVmlldywgYnl0ZU9mZnNldDogbnVtYmVyLCBieXRlTGVuZ3RoOiBudW1iZXIpOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgaWYgKGJ5dGVPZmZzZXQgPCAwIHx8IGJ5dGVPZmZzZXQgPj0gYXJyYXlCdWZmZXJWaWV3LmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJPZmZzZXQgaXMgb3V0IG9mIHJhbmdlLlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChieXRlT2Zmc2V0ICsgYnl0ZUxlbmd0aCA+IGFycmF5QnVmZmVyVmlldy5ieXRlTGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiTGVuZ3RoIGlzIG91dCBvZiByYW5nZS5cIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBVaW50OEFycmF5KGFycmF5QnVmZmVyVmlldy5idWZmZXIsIGFycmF5QnVmZmVyVmlldy5ieXRlT2Zmc2V0ICsgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCkpO1xyXG4gICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIE1vZGUgdGhhdCBkZXRlcm1pbmVzIHRoZSBjb29yZGluYXRlIHN5c3RlbSB0byB1c2UuXHJcbiAqL1xyXG5leHBvcnQgZW51bSBHTFRGTG9hZGVyQ29vcmRpbmF0ZVN5c3RlbU1vZGUge1xyXG4gICAgLyoqXHJcbiAgICAgKiBBdXRvbWF0aWNhbGx5IGNvbnZlcnQgdGhlIGdsVEYgcmlnaHQtaGFuZGVkIGRhdGEgdG8gdGhlIGFwcHJvcHJpYXRlIHN5c3RlbSBiYXNlZCBvbiB0aGUgY3VycmVudCBjb29yZGluYXRlIHN5c3RlbSBtb2RlIG9mIHRoZSBzY2VuZS5cclxuICAgICAqL1xyXG4gICAgQVVUTyxcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIHVzZVJpZ2h0SGFuZGVkU3lzdGVtIGZsYWcgb24gdGhlIHNjZW5lLlxyXG4gICAgICovXHJcbiAgICBGT1JDRV9SSUdIVF9IQU5ERUQsXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBNb2RlIHRoYXQgZGV0ZXJtaW5lcyB3aGF0IGFuaW1hdGlvbnMgd2lsbCBzdGFydC5cclxuICovXHJcbmV4cG9ydCBlbnVtIEdMVEZMb2FkZXJBbmltYXRpb25TdGFydE1vZGUge1xyXG4gICAgLyoqXHJcbiAgICAgKiBObyBhbmltYXRpb24gd2lsbCBzdGFydC5cclxuICAgICAqL1xyXG4gICAgTk9ORSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBmaXJzdCBhbmltYXRpb24gd2lsbCBzdGFydC5cclxuICAgICAqL1xyXG4gICAgRklSU1QsXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGwgYW5pbWF0aW9ucyB3aWxsIHN0YXJ0LlxyXG4gICAgICovXHJcbiAgICBBTEwsXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBJbnRlcmZhY2UgdGhhdCBjb250YWlucyB0aGUgZGF0YSBmb3IgdGhlIGdsVEYgYXNzZXQuXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGTG9hZGVyRGF0YSB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBnbFRGIEpTT04uXHJcbiAgICAgKi9cclxuICAgIGpzb246IE9iamVjdDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBCSU4gY2h1bmsgb2YgYSBiaW5hcnkgZ2xURi5cclxuICAgICAqL1xyXG4gICAgYmluOiBOdWxsYWJsZTxJRGF0YUJ1ZmZlcj47XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBJbnRlcmZhY2UgZm9yIGV4dGVuZGluZyB0aGUgbG9hZGVyLlxyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBJR0xURkxvYWRlckV4dGVuc2lvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICovXHJcbiAgICByZWFkb25seSBuYW1lOiBzdHJpbmc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIHdoZXRoZXIgdGhpcyBleHRlbnNpb24gaXMgZW5hYmxlZC5cclxuICAgICAqL1xyXG4gICAgZW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgdGhlIG9yZGVyIG9mIHRoaXMgZXh0ZW5zaW9uLlxyXG4gICAgICogVGhlIGxvYWRlciBzb3J0cyB0aGUgZXh0ZW5zaW9ucyB1c2luZyB0aGVzZSB2YWx1ZXMgd2hlbiBsb2FkaW5nLlxyXG4gICAgICovXHJcbiAgICBvcmRlcj86IG51bWJlcjtcclxufVxyXG5cclxuLyoqXHJcbiAqIExvYWRlciBzdGF0ZS5cclxuICovXHJcbmV4cG9ydCBlbnVtIEdMVEZMb2FkZXJTdGF0ZSB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSBhc3NldCBpcyBsb2FkaW5nLlxyXG4gICAgICovXHJcbiAgICBMT0FESU5HLFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGFzc2V0IGlzIHJlYWR5IGZvciByZW5kZXJpbmcuXHJcbiAgICAgKi9cclxuICAgIFJFQURZLFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGFzc2V0IGlzIGNvbXBsZXRlbHkgbG9hZGVkLlxyXG4gICAgICovXHJcbiAgICBDT01QTEVURSxcclxufVxyXG5cclxuLyoqIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHTFRGTG9hZGVyIGV4dGVuZHMgSURpc3Bvc2FibGUge1xyXG4gICAgaW1wb3J0TWVzaEFzeW5jOiAoXHJcbiAgICAgICAgbWVzaGVzTmFtZXM6IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdIHwgbnVsbCB8IHVuZGVmaW5lZCxcclxuICAgICAgICBzY2VuZTogU2NlbmUsXHJcbiAgICAgICAgY29udGFpbmVyOiBOdWxsYWJsZTxBc3NldENvbnRhaW5lcj4sXHJcbiAgICAgICAgZGF0YTogSUdMVEZMb2FkZXJEYXRhLFxyXG4gICAgICAgIHJvb3RVcmw6IHN0cmluZyxcclxuICAgICAgICBvblByb2dyZXNzPzogKGV2ZW50OiBJU2NlbmVMb2FkZXJQcm9ncmVzc0V2ZW50KSA9PiB2b2lkLFxyXG4gICAgICAgIGZpbGVOYW1lPzogc3RyaW5nXHJcbiAgICApID0+IFByb21pc2U8SVNjZW5lTG9hZGVyQXN5bmNSZXN1bHQ+O1xyXG4gICAgbG9hZEFzeW5jOiAoc2NlbmU6IFNjZW5lLCBkYXRhOiBJR0xURkxvYWRlckRhdGEsIHJvb3RVcmw6IHN0cmluZywgb25Qcm9ncmVzcz86IChldmVudDogSVNjZW5lTG9hZGVyUHJvZ3Jlc3NFdmVudCkgPT4gdm9pZCwgZmlsZU5hbWU/OiBzdHJpbmcpID0+IFByb21pc2U8dm9pZD47XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBZGRzIGRlZmF1bHQvaW1wbGljaXQgb3B0aW9ucyB0byBleHRlbnNpb24gc3BlY2lmaWMgb3B0aW9ucy5cclxuICovXHJcbnR5cGUgRGVmYXVsdEV4dGVuc2lvbk9wdGlvbnM8QmFzZUV4dGVuc2lvbk9wdGlvbnM+ID0ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGlmIHRoZSBleHRlbnNpb24gaXMgZW5hYmxlZFxyXG4gICAgICovXHJcbiAgICBlbmFibGVkPzogYm9vbGVhbjtcclxufSAmIEJhc2VFeHRlbnNpb25PcHRpb25zO1xyXG5cclxuYWJzdHJhY3QgY2xhc3MgR0xURkxvYWRlck9wdGlvbnMge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGJhYnlsb25qcy9hdmFpbGFibGVcclxuICAgIHByb3RlY3RlZCBjb3B5RnJvbShvcHRpb25zPzogUGFydGlhbDxSZWFkb25seTxHTFRGTG9hZGVyT3B0aW9ucz4+KSB7XHJcbiAgICAgICAgaWYgKG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgdGhpcy5vblBhcnNlZCA9IG9wdGlvbnMub25QYXJzZWQ7XHJcbiAgICAgICAgICAgIHRoaXMuY29vcmRpbmF0ZVN5c3RlbU1vZGUgPSBvcHRpb25zLmNvb3JkaW5hdGVTeXN0ZW1Nb2RlID8/IHRoaXMuY29vcmRpbmF0ZVN5c3RlbU1vZGU7XHJcbiAgICAgICAgICAgIHRoaXMuYW5pbWF0aW9uU3RhcnRNb2RlID0gb3B0aW9ucy5hbmltYXRpb25TdGFydE1vZGUgPz8gdGhpcy5hbmltYXRpb25TdGFydE1vZGU7XHJcbiAgICAgICAgICAgIHRoaXMubG9hZE5vZGVBbmltYXRpb25zID0gb3B0aW9ucy5sb2FkTm9kZUFuaW1hdGlvbnMgPz8gdGhpcy5sb2FkTm9kZUFuaW1hdGlvbnM7XHJcbiAgICAgICAgICAgIHRoaXMubG9hZFNraW5zID0gb3B0aW9ucy5sb2FkU2tpbnMgPz8gdGhpcy5sb2FkU2tpbnM7XHJcbiAgICAgICAgICAgIHRoaXMubG9hZE1vcnBoVGFyZ2V0cyA9IG9wdGlvbnMubG9hZE1vcnBoVGFyZ2V0cyA/PyB0aGlzLmxvYWRNb3JwaFRhcmdldHM7XHJcbiAgICAgICAgICAgIHRoaXMuY29tcGlsZU1hdGVyaWFscyA9IG9wdGlvbnMuY29tcGlsZU1hdGVyaWFscyA/PyB0aGlzLmNvbXBpbGVNYXRlcmlhbHM7XHJcbiAgICAgICAgICAgIHRoaXMudXNlQ2xpcFBsYW5lID0gb3B0aW9ucy51c2VDbGlwUGxhbmUgPz8gdGhpcy51c2VDbGlwUGxhbmU7XHJcbiAgICAgICAgICAgIHRoaXMuY29tcGlsZVNoYWRvd0dlbmVyYXRvcnMgPSBvcHRpb25zLmNvbXBpbGVTaGFkb3dHZW5lcmF0b3JzID8/IHRoaXMuY29tcGlsZVNoYWRvd0dlbmVyYXRvcnM7XHJcbiAgICAgICAgICAgIHRoaXMudHJhbnNwYXJlbmN5QXNDb3ZlcmFnZSA9IG9wdGlvbnMudHJhbnNwYXJlbmN5QXNDb3ZlcmFnZSA/PyB0aGlzLnRyYW5zcGFyZW5jeUFzQ292ZXJhZ2U7XHJcbiAgICAgICAgICAgIHRoaXMudXNlUmFuZ2VSZXF1ZXN0cyA9IG9wdGlvbnMudXNlUmFuZ2VSZXF1ZXN0cyA/PyB0aGlzLnVzZVJhbmdlUmVxdWVzdHM7XHJcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlSW5zdGFuY2VzID0gb3B0aW9ucy5jcmVhdGVJbnN0YW5jZXMgPz8gdGhpcy5jcmVhdGVJbnN0YW5jZXM7XHJcbiAgICAgICAgICAgIHRoaXMuYWx3YXlzQ29tcHV0ZUJvdW5kaW5nQm94ID0gb3B0aW9ucy5hbHdheXNDb21wdXRlQm91bmRpbmdCb3ggPz8gdGhpcy5hbHdheXNDb21wdXRlQm91bmRpbmdCb3g7XHJcbiAgICAgICAgICAgIHRoaXMubG9hZEFsbE1hdGVyaWFscyA9IG9wdGlvbnMubG9hZEFsbE1hdGVyaWFscyA/PyB0aGlzLmxvYWRBbGxNYXRlcmlhbHM7XHJcbiAgICAgICAgICAgIHRoaXMubG9hZE9ubHlNYXRlcmlhbHMgPSBvcHRpb25zLmxvYWRPbmx5TWF0ZXJpYWxzID8/IHRoaXMubG9hZE9ubHlNYXRlcmlhbHM7XHJcbiAgICAgICAgICAgIHRoaXMuc2tpcE1hdGVyaWFscyA9IG9wdGlvbnMuc2tpcE1hdGVyaWFscyA/PyB0aGlzLnNraXBNYXRlcmlhbHM7XHJcbiAgICAgICAgICAgIHRoaXMudXNlU1JHQkJ1ZmZlcnMgPSBvcHRpb25zLnVzZVNSR0JCdWZmZXJzID8/IHRoaXMudXNlU1JHQkJ1ZmZlcnM7XHJcbiAgICAgICAgICAgIHRoaXMudGFyZ2V0RnBzID0gb3B0aW9ucy50YXJnZXRGcHMgPz8gdGhpcy50YXJnZXRGcHM7XHJcbiAgICAgICAgICAgIHRoaXMuYWx3YXlzQ29tcHV0ZVNrZWxldG9uUm9vdE5vZGUgPSBvcHRpb25zLmFsd2F5c0NvbXB1dGVTa2VsZXRvblJvb3ROb2RlID8/IHRoaXMuYWx3YXlzQ29tcHV0ZVNrZWxldG9uUm9vdE5vZGU7XHJcbiAgICAgICAgICAgIHRoaXMudXNlR2x0ZlRleHR1cmVOYW1lcyA9IG9wdGlvbnMudXNlR2x0ZlRleHR1cmVOYW1lcyA/PyB0aGlzLnVzZUdsdGZUZXh0dXJlTmFtZXM7XHJcbiAgICAgICAgICAgIHRoaXMucHJlcHJvY2Vzc1VybEFzeW5jID0gb3B0aW9ucy5wcmVwcm9jZXNzVXJsQXN5bmMgPz8gdGhpcy5wcmVwcm9jZXNzVXJsQXN5bmM7XHJcbiAgICAgICAgICAgIHRoaXMuY3VzdG9tUm9vdE5vZGUgPSBvcHRpb25zLmN1c3RvbVJvb3ROb2RlO1xyXG4gICAgICAgICAgICB0aGlzLm9uTWVzaExvYWRlZCA9IG9wdGlvbnMub25NZXNoTG9hZGVkO1xyXG4gICAgICAgICAgICB0aGlzLm9uU2tpbkxvYWRlZCA9IG9wdGlvbnMub25Ta2luTG9hZGVkO1xyXG4gICAgICAgICAgICB0aGlzLm9uVGV4dHVyZUxvYWRlZCA9IG9wdGlvbnMub25UZXh0dXJlTG9hZGVkO1xyXG4gICAgICAgICAgICB0aGlzLm9uTWF0ZXJpYWxMb2FkZWQgPSBvcHRpb25zLm9uTWF0ZXJpYWxMb2FkZWQ7XHJcbiAgICAgICAgICAgIHRoaXMub25DYW1lcmFMb2FkZWQgPSBvcHRpb25zLm9uQ2FtZXJhTG9hZGVkO1xyXG4gICAgICAgICAgICB0aGlzLmV4dGVuc2lvbk9wdGlvbnMgPSBvcHRpb25zLmV4dGVuc2lvbk9wdGlvbnMgPz8gdGhpcy5leHRlbnNpb25PcHRpb25zO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLVxyXG4gICAgLy8gQ29tbW9uIG9wdGlvbnNcclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSYWlzZWQgd2hlbiB0aGUgYXNzZXQgaGFzIGJlZW4gcGFyc2VkXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhYnN0cmFjdCBvblBhcnNlZD86ICgobG9hZGVyRGF0YTogSUdMVEZMb2FkZXJEYXRhKSA9PiB2b2lkKSB8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAvLyAtLS0tLS0tLS0tXHJcbiAgICAvLyBWMiBvcHRpb25zXHJcbiAgICAvLyAtLS0tLS0tLS0tXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgY29vcmRpbmF0ZSBzeXN0ZW0gbW9kZS4gRGVmYXVsdHMgdG8gQVVUTy5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvb3JkaW5hdGVTeXN0ZW1Nb2RlID0gR0xURkxvYWRlckNvb3JkaW5hdGVTeXN0ZW1Nb2RlLkFVVE87XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgYW5pbWF0aW9uIHN0YXJ0IG1vZGUuIERlZmF1bHRzIHRvIEZJUlNULlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYW5pbWF0aW9uU3RhcnRNb2RlID0gR0xURkxvYWRlckFuaW1hdGlvblN0YXJ0TW9kZS5GSVJTVDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgaWYgdGhlIGxvYWRlciBzaG91bGQgbG9hZCBub2RlIGFuaW1hdGlvbnMuIERlZmF1bHRzIHRvIHRydWUuXHJcbiAgICAgKiBOT1RFOiBUaGUgYW5pbWF0aW9uIG9mIHRoaXMgbm9kZSB3aWxsIHN0aWxsIGxvYWQgaWYgdGhlIG5vZGUgaXMgYWxzbyBhIGpvaW50IG9mIGEgc2tpbiBhbmQgYGxvYWRTa2luc2AgaXMgdHJ1ZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWROb2RlQW5pbWF0aW9ucyA9IHRydWU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGlmIHRoZSBsb2FkZXIgc2hvdWxkIGxvYWQgc2tpbnMuIERlZmF1bHRzIHRvIHRydWUuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkU2tpbnMgPSB0cnVlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBpZiB0aGUgbG9hZGVyIHNob3VsZCBsb2FkIG1vcnBoIHRhcmdldHMuIERlZmF1bHRzIHRvIHRydWUuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkTW9ycGhUYXJnZXRzID0gdHJ1ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgaWYgdGhlIGxvYWRlciBzaG91bGQgY29tcGlsZSBtYXRlcmlhbHMgYmVmb3JlIHJhaXNpbmcgdGhlIHN1Y2Nlc3MgY2FsbGJhY2suIERlZmF1bHRzIHRvIGZhbHNlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY29tcGlsZU1hdGVyaWFscyA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBpZiB0aGUgbG9hZGVyIHNob3VsZCBhbHNvIGNvbXBpbGUgbWF0ZXJpYWxzIHdpdGggY2xpcCBwbGFuZXMuIERlZmF1bHRzIHRvIGZhbHNlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdXNlQ2xpcFBsYW5lID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGlmIHRoZSBsb2FkZXIgc2hvdWxkIGNvbXBpbGUgc2hhZG93IGdlbmVyYXRvcnMgYmVmb3JlIHJhaXNpbmcgdGhlIHN1Y2Nlc3MgY2FsbGJhY2suIERlZmF1bHRzIHRvIGZhbHNlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY29tcGlsZVNoYWRvd0dlbmVyYXRvcnMgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgaWYgdGhlIEFscGhhIGJsZW5kZWQgbWF0ZXJpYWxzIGFyZSBvbmx5IGFwcGxpZWQgYXMgY292ZXJhZ2UuXHJcbiAgICAgKiBJZiBmYWxzZSwgKGRlZmF1bHQpIFRoZSBsdW1pbmFuY2Ugb2YgZWFjaCBwaXhlbCB3aWxsIHJlZHVjZSBpdHMgb3BhY2l0eSB0byBzaW11bGF0ZSB0aGUgYmVoYXZpb3VyIG9mIG1vc3QgcGh5c2ljYWwgbWF0ZXJpYWxzLlxyXG4gICAgICogSWYgdHJ1ZSwgbm8gZXh0cmEgZWZmZWN0cyBhcmUgYXBwbGllZCB0byB0cmFuc3BhcmVudCBwaXhlbHMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB0cmFuc3BhcmVuY3lBc0NvdmVyYWdlID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZpbmVzIGlmIHRoZSBsb2FkZXIgc2hvdWxkIHVzZSByYW5nZSByZXF1ZXN0cyB3aGVuIGxvYWQgYmluYXJ5IGdsVEYgZmlsZXMgZnJvbSBIVFRQLlxyXG4gICAgICogRW5hYmxpbmcgd2lsbCBkaXNhYmxlIG9mZmxpbmUgc3VwcG9ydCBhbmQgZ2xURiB2YWxpZGF0b3IuXHJcbiAgICAgKiBEZWZhdWx0cyB0byBmYWxzZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHVzZVJhbmdlUmVxdWVzdHMgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgaWYgdGhlIGxvYWRlciBzaG91bGQgY3JlYXRlIGluc3RhbmNlcyB3aGVuIG11bHRpcGxlIGdsVEYgbm9kZXMgcG9pbnQgdG8gdGhlIHNhbWUgZ2xURiBtZXNoLiBEZWZhdWx0cyB0byB0cnVlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY3JlYXRlSW5zdGFuY2VzID0gdHJ1ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgaWYgdGhlIGxvYWRlciBzaG91bGQgYWx3YXlzIGNvbXB1dGUgdGhlIGJvdW5kaW5nIGJveGVzIG9mIG1lc2hlcyBhbmQgbm90IHVzZSB0aGUgbWluL21heCB2YWx1ZXMgZnJvbSB0aGUgcG9zaXRpb24gYWNjZXNzb3IuIERlZmF1bHRzIHRvIGZhbHNlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWx3YXlzQ29tcHV0ZUJvdW5kaW5nQm94ID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJZiB0cnVlLCBsb2FkIGFsbCBtYXRlcmlhbHMgZGVmaW5lZCBpbiB0aGUgZmlsZSwgZXZlbiBpZiBub3QgdXNlZCBieSBhbnkgbWVzaC4gRGVmYXVsdHMgdG8gZmFsc2UuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkQWxsTWF0ZXJpYWxzID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJZiB0cnVlLCBsb2FkIG9ubHkgdGhlIG1hdGVyaWFscyBkZWZpbmVkIGluIHRoZSBmaWxlLiBEZWZhdWx0cyB0byBmYWxzZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRPbmx5TWF0ZXJpYWxzID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJZiB0cnVlLCBkbyBub3QgbG9hZCBhbnkgbWF0ZXJpYWxzIGRlZmluZWQgaW4gdGhlIGZpbGUuIERlZmF1bHRzIHRvIGZhbHNlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2tpcE1hdGVyaWFscyA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSWYgdHJ1ZSwgbG9hZCB0aGUgY29sb3IgKGdhbW1hIGVuY29kZWQpIHRleHR1cmVzIGludG8gc1JHQiBidWZmZXJzIChpZiBzdXBwb3J0ZWQgYnkgdGhlIEdQVSksIHdoaWNoIHdpbGwgeWllbGQgbW9yZSBhY2N1cmF0ZSByZXN1bHRzIHdoZW4gc2FtcGxpbmcgdGhlIHRleHR1cmUuIERlZmF1bHRzIHRvIHRydWUuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB1c2VTUkdCQnVmZmVycyA9IHRydWU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXaGVuIGxvYWRpbmcgZ2xURiBhbmltYXRpb25zLCB3aGljaCBhcmUgZGVmaW5lZCBpbiBzZWNvbmRzLCB0YXJnZXQgdGhlbSB0byB0aGlzIEZQUy4gRGVmYXVsdHMgdG8gNjAuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB0YXJnZXRGcHMgPSA2MDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgaWYgdGhlIGxvYWRlciBzaG91bGQgYWx3YXlzIGNvbXB1dGUgdGhlIG5lYXJlc3QgY29tbW9uIGFuY2VzdG9yIG9mIHRoZSBza2VsZXRvbiBqb2ludHMgaW5zdGVhZCBvZiB1c2luZyBgc2tpbi5za2VsZXRvbmAuIERlZmF1bHRzIHRvIGZhbHNlLlxyXG4gICAgICogU2V0IHRoaXMgdG8gdHJ1ZSBpZiBsb2FkaW5nIGFzc2V0cyB3aXRoIGludmFsaWQgYHNraW4uc2tlbGV0b25gIHZhbHVlcy5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGFsd2F5c0NvbXB1dGVTa2VsZXRvblJvb3ROb2RlID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJZiB0cnVlLCB0aGUgbG9hZGVyIHdpbGwgZGVyaXZlIHRoZSBuYW1lIGZvciBCYWJ5bG9uIHRleHR1cmVzIGZyb20gdGhlIGdsVEYgdGV4dHVyZSBuYW1lLCBpbWFnZSBuYW1lLCBvciBpbWFnZSB1cmwuIERlZmF1bHRzIHRvIGZhbHNlLlxyXG4gICAgICogTm90ZSB0aGF0IGl0IGlzIHBvc3NpYmxlIGZvciBtdWx0aXBsZSBCYWJ5bG9uIHRleHR1cmVzIHRvIHNoYXJlIHRoZSBzYW1lIG5hbWUgd2hlbiB0aGUgQmFieWxvbiB0ZXh0dXJlcyBsb2FkIGZyb20gdGhlIHNhbWUgZ2xURiB0ZXh0dXJlIG9yIGltYWdlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdXNlR2x0ZlRleHR1cmVOYW1lcyA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRnVuY3Rpb24gY2FsbGVkIGJlZm9yZSBsb2FkaW5nIGEgdXJsIHJlZmVyZW5jZWQgYnkgdGhlIGFzc2V0LlxyXG4gICAgICogQHBhcmFtIHVybCB1cmwgcmVmZXJlbmNlZCBieSB0aGUgYXNzZXRcclxuICAgICAqIEByZXR1cm5zIEFzeW5jIHVybCB0byBsb2FkXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBwcmVwcm9jZXNzVXJsQXN5bmMgPSAodXJsOiBzdHJpbmcpID0+IFByb21pc2UucmVzb2x2ZSh1cmwpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyB0aGUgbm9kZSB0byB1c2UgYXMgdGhlIHJvb3Qgb2YgdGhlIGhpZXJhcmNoeSB3aGVuIGxvYWRpbmcgdGhlIHNjZW5lIChkZWZhdWx0OiB1bmRlZmluZWQpLiBJZiBub3QgZGVmaW5lZCwgYSByb290IG5vZGUgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGNyZWF0ZWQuXHJcbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBudWxsIGlmIHlvdSBkb24ndCB3YW50IGEgcm9vdCBub2RlIHRvIGJlIGNyZWF0ZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjdXN0b21Sb290Tm9kZT86IE51bGxhYmxlPFRyYW5zZm9ybU5vZGU+O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgcmFpc2VkIHdoZW4gdGhlIGxvYWRlciBjcmVhdGVzIGEgbWVzaCBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXMgb2YgdGhlIG1lc2guXHJcbiAgICAgKiBOb3RlIHRoYXQgdGhlIGNhbGxiYWNrIGlzIGNhbGxlZCBhcyBzb29uIGFzIHRoZSBtZXNoIG9iamVjdCBpcyBjcmVhdGVkLCBtZWFuaW5nIHNvbWUgZGF0YSBtYXkgbm90IGhhdmUgYmVlbiBzZXR1cCB5ZXQgZm9yIHRoaXMgbWVzaCAodmVydGV4IGRhdGEsIG1vcnBoIHRhcmdldHMsIG1hdGVyaWFsLCAuLi4pXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhYnN0cmFjdCBvbk1lc2hMb2FkZWQ/OiAoKG1lc2g6IEFic3RyYWN0TWVzaCkgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayByYWlzZWQgd2hlbiB0aGUgbG9hZGVyIGNyZWF0ZXMgYSBza2luIGFmdGVyIHBhcnNpbmcgdGhlIGdsVEYgcHJvcGVydGllcyBvZiB0aGUgc2tpbiBub2RlLlxyXG4gICAgICogQHNlZSBodHRwczovL2RvYy5iYWJ5bG9uanMuY29tL2ZlYXR1cmVzL2ZlYXR1cmVzRGVlcERpdmUvaW1wb3J0ZXJzL2dsVEYvZ2xURlNraW5uaW5nI2lnbm9yaW5nLXRoZS10cmFuc2Zvcm0tb2YtdGhlLXNraW5uZWQtbWVzaFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWJzdHJhY3Qgb25Ta2luTG9hZGVkPzogKChub2RlOiBUcmFuc2Zvcm1Ob2RlLCBza2lubmVkTm9kZTogVHJhbnNmb3JtTm9kZSkgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayByYWlzZWQgd2hlbiB0aGUgbG9hZGVyIGNyZWF0ZXMgYSB0ZXh0dXJlIGFmdGVyIHBhcnNpbmcgdGhlIGdsVEYgcHJvcGVydGllcyBvZiB0aGUgdGV4dHVyZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGFic3RyYWN0IG9uVGV4dHVyZUxvYWRlZD86ICgodGV4dHVyZTogQmFzZVRleHR1cmUpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgcmFpc2VkIHdoZW4gdGhlIGxvYWRlciBjcmVhdGVzIGEgbWF0ZXJpYWwgYWZ0ZXIgcGFyc2luZyB0aGUgZ2xURiBwcm9wZXJ0aWVzIG9mIHRoZSBtYXRlcmlhbC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGFic3RyYWN0IG9uTWF0ZXJpYWxMb2FkZWQ/OiAoKG1hdGVyaWFsOiBNYXRlcmlhbCkgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayByYWlzZWQgd2hlbiB0aGUgbG9hZGVyIGNyZWF0ZXMgYSBjYW1lcmEgYWZ0ZXIgcGFyc2luZyB0aGUgZ2xURiBwcm9wZXJ0aWVzIG9mIHRoZSBjYW1lcmEuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhYnN0cmFjdCBvbkNhbWVyYUxvYWRlZD86ICgoY2FtZXJhOiBDYW1lcmEpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBvcHRpb25zIGZvciBnbFRGIGV4dGVuc2lvbnMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBleHRlbnNpb25PcHRpb25zOiB7XHJcbiAgICAgICAgLy8gTk9URTogVGhpcyB0eXBlIGlzIGRvaW5nIHR3byB0aGluZ3M6XHJcbiAgICAgICAgLy8gMS4gQWRkaW5nIGFuIGltcGxpY2l0ICdlbmFibGVkJyBwcm9wZXJ0eSB0byB0aGUgb3B0aW9ucyBmb3IgZWFjaCBleHRlbnNpb24uXHJcbiAgICAgICAgLy8gMi4gQ3JlYXRpbmcgYSBtYXBwZWQgdHlwZSBvZiBhbGwgdGhlIG9wdGlvbnMgb2YgYWxsIHRoZSBleHRlbnNpb25zIHRvIG1ha2UgaXQganVzdCBsb29rIGxpa2UgYSBjb25zb2xpZGF0ZWQgcGxhaW4gb2JqZWN0IGluIGludGVsbGlzZW5zZSBmb3IgdGhlIHVzZXIuXHJcbiAgICAgICAgW0V4dGVuc2lvbiBpbiBrZXlvZiBHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9uc10/OiB7XHJcbiAgICAgICAgICAgIFtPcHRpb24gaW4ga2V5b2YgRGVmYXVsdEV4dGVuc2lvbk9wdGlvbnM8R0xURkxvYWRlckV4dGVuc2lvbk9wdGlvbnNbRXh0ZW5zaW9uXT5dOiBEZWZhdWx0RXh0ZW5zaW9uT3B0aW9uczxHTFRGTG9hZGVyRXh0ZW5zaW9uT3B0aW9uc1tFeHRlbnNpb25dPltPcHRpb25dO1xyXG4gICAgICAgIH07XHJcbiAgICB9ID0ge307XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGaWxlIGxvYWRlciBmb3IgbG9hZGluZyBnbFRGIGZpbGVzIGludG8gYSBzY2VuZS5cclxuICovXHJcbmV4cG9ydCBjbGFzcyBHTFRGRmlsZUxvYWRlciBleHRlbmRzIEdMVEZMb2FkZXJPcHRpb25zIGltcGxlbWVudHMgSURpc3Bvc2FibGUsIElTY2VuZUxvYWRlclBsdWdpbkFzeW5jLCBJU2NlbmVMb2FkZXJQbHVnaW5GYWN0b3J5IHtcclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgX0NyZWF0ZUdMVEYxTG9hZGVyOiAocGFyZW50OiBHTFRGRmlsZUxvYWRlcikgPT4gSUdMVEZMb2FkZXI7XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBfQ3JlYXRlR0xURjJMb2FkZXI6IChwYXJlbnQ6IEdMVEZGaWxlTG9hZGVyKSA9PiBJR0xURkxvYWRlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgZ2xURiBmaWxlIGxvYWRlci5cclxuICAgICAqIEBwYXJhbSBvcHRpb25zIFRoZSBvcHRpb25zIGZvciB0aGUgbG9hZGVyXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihvcHRpb25zPzogUGFydGlhbDxSZWFkb25seTxHTFRGTG9hZGVyT3B0aW9ucz4+KSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICB0aGlzLmNvcHlGcm9tKG9wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICAvLyBCZWdpbiBDb21tb24gb3B0aW9uc1xyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJhaXNlZCB3aGVuIHRoZSBhc3NldCBoYXMgYmVlbiBwYXJzZWRcclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uUGFyc2VkT2JzZXJ2YWJsZSA9IG5ldyBPYnNlcnZhYmxlPElHTFRGTG9hZGVyRGF0YT4oKTtcclxuXHJcbiAgICBwcml2YXRlIF9vblBhcnNlZE9ic2VydmVyOiBOdWxsYWJsZTxPYnNlcnZlcjxJR0xURkxvYWRlckRhdGE+PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJhaXNlZCB3aGVuIHRoZSBhc3NldCBoYXMgYmVlbiBwYXJzZWRcclxuICAgICAqL1xyXG4gICAgcHVibGljIHNldCBvblBhcnNlZChjYWxsYmFjazogKChsb2FkZXJEYXRhOiBJR0xURkxvYWRlckRhdGEpID0+IHZvaWQpIHwgdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX29uUGFyc2VkT2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5vblBhcnNlZE9ic2VydmFibGUucmVtb3ZlKHRoaXMuX29uUGFyc2VkT2JzZXJ2ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgdGhpcy5fb25QYXJzZWRPYnNlcnZlciA9IHRoaXMub25QYXJzZWRPYnNlcnZhYmxlLmFkZChjYWxsYmFjayk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgLy8gRW5kIENvbW1vbiBvcHRpb25zXHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tXHJcbiAgICAvLyBCZWdpbiBWMSBvcHRpb25zXHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXQgdGhpcyBwcm9wZXJ0eSB0byBmYWxzZSB0byBkaXNhYmxlIGluY3JlbWVudGFsIGxvYWRpbmcgd2hpY2ggZGVsYXlzIHRoZSBsb2FkZXIgZnJvbSBjYWxsaW5nIHRoZSBzdWNjZXNzIGNhbGxiYWNrIHVudGlsIGFmdGVyIGxvYWRpbmcgdGhlIG1lc2hlcyBhbmQgc2hhZGVycy5cclxuICAgICAqIFRleHR1cmVzIGFsd2F5cyBsb2FkcyBhc3luY2hyb25vdXNseS4gRm9yIGV4YW1wbGUsIHRoZSBzdWNjZXNzIGNhbGxiYWNrIGNhbiBjb21wdXRlIHRoZSBib3VuZGluZyBpbmZvcm1hdGlvbiBvZiB0aGUgbG9hZGVkIG1lc2hlcyB3aGVuIGluY3JlbWVudGFsIGxvYWRpbmcgaXMgZGlzYWJsZWQuXHJcbiAgICAgKiBEZWZhdWx0cyB0byB0cnVlLlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgSW5jcmVtZW50YWxMb2FkaW5nID0gdHJ1ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldCB0aGlzIHByb3BlcnR5IHRvIHRydWUgaW4gb3JkZXIgdG8gd29yayB3aXRoIGhvbW9nZW5lb3VzIGNvb3JkaW5hdGVzLCBhdmFpbGFibGUgd2l0aCBzb21lIGNvbnZlcnRlcnMgYW5kIGV4cG9ydGVycy5cclxuICAgICAqIERlZmF1bHRzIHRvIGZhbHNlLiBTZWUgaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSG9tb2dlbmVvdXNfY29vcmRpbmF0ZXMuXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBIb21vZ2VuZW91c0Nvb3JkaW5hdGVzID0gZmFsc2U7XHJcblxyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS1cclxuICAgIC8vIEVuZCBWMSBvcHRpb25zXHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2JzZXJ2YWJsZSByYWlzZWQgd2hlbiB0aGUgbG9hZGVyIGNyZWF0ZXMgYSBtZXNoIGFmdGVyIHBhcnNpbmcgdGhlIGdsVEYgcHJvcGVydGllcyBvZiB0aGUgbWVzaC5cclxuICAgICAqIE5vdGUgdGhhdCB0aGUgb2JzZXJ2YWJsZSBpcyByYWlzZWQgYXMgc29vbiBhcyB0aGUgbWVzaCBvYmplY3QgaXMgY3JlYXRlZCwgbWVhbmluZyBzb21lIGRhdGEgbWF5IG5vdCBoYXZlIGJlZW4gc2V0dXAgeWV0IGZvciB0aGlzIG1lc2ggKHZlcnRleCBkYXRhLCBtb3JwaCB0YXJnZXRzLCBtYXRlcmlhbCwgLi4uKVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgb25NZXNoTG9hZGVkT2JzZXJ2YWJsZSA9IG5ldyBPYnNlcnZhYmxlPEFic3RyYWN0TWVzaD4oKTtcclxuXHJcbiAgICBwcml2YXRlIF9vbk1lc2hMb2FkZWRPYnNlcnZlcjogTnVsbGFibGU8T2JzZXJ2ZXI8QWJzdHJhY3RNZXNoPj47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayByYWlzZWQgd2hlbiB0aGUgbG9hZGVyIGNyZWF0ZXMgYSBtZXNoIGFmdGVyIHBhcnNpbmcgdGhlIGdsVEYgcHJvcGVydGllcyBvZiB0aGUgbWVzaC5cclxuICAgICAqIE5vdGUgdGhhdCB0aGUgY2FsbGJhY2sgaXMgY2FsbGVkIGFzIHNvb24gYXMgdGhlIG1lc2ggb2JqZWN0IGlzIGNyZWF0ZWQsIG1lYW5pbmcgc29tZSBkYXRhIG1heSBub3QgaGF2ZSBiZWVuIHNldHVwIHlldCBmb3IgdGhpcyBtZXNoICh2ZXJ0ZXggZGF0YSwgbW9ycGggdGFyZ2V0cywgbWF0ZXJpYWwsIC4uLilcclxuICAgICAqL1xyXG4gICAgcHVibGljIHNldCBvbk1lc2hMb2FkZWQoY2FsbGJhY2s6ICgobWVzaDogQWJzdHJhY3RNZXNoKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9vbk1lc2hMb2FkZWRPYnNlcnZlcikge1xyXG4gICAgICAgICAgICB0aGlzLm9uTWVzaExvYWRlZE9ic2VydmFibGUucmVtb3ZlKHRoaXMuX29uTWVzaExvYWRlZE9ic2VydmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX29uTWVzaExvYWRlZE9ic2VydmVyID0gdGhpcy5vbk1lc2hMb2FkZWRPYnNlcnZhYmxlLmFkZChjYWxsYmFjayk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2JzZXJ2YWJsZSByYWlzZWQgd2hlbiB0aGUgbG9hZGVyIGNyZWF0ZXMgYSBza2luIGFmdGVyIHBhcnNpbmcgdGhlIGdsVEYgcHJvcGVydGllcyBvZiB0aGUgc2tpbiBub2RlLlxyXG4gICAgICogQHNlZSBodHRwczovL2RvYy5iYWJ5bG9uanMuY29tL2ZlYXR1cmVzL2ZlYXR1cmVzRGVlcERpdmUvaW1wb3J0ZXJzL2dsVEYvZ2xURlNraW5uaW5nI2lnbm9yaW5nLXRoZS10cmFuc2Zvcm0tb2YtdGhlLXNraW5uZWQtbWVzaFxyXG4gICAgICogQHBhcmFtIG5vZGUgLSB0aGUgdHJhbnNmb3JtIG5vZGUgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgb3JpZ2luYWwgZ2xURiBza2luIG5vZGUgdXNlZCBmb3IgYW5pbWF0aW9uc1xyXG4gICAgICogQHBhcmFtIHNraW5uZWROb2RlIC0gdGhlIHRyYW5zZm9ybSBub2RlIHRoYXQgaXMgdGhlIHNraW5uZWQgbWVzaCBpdHNlbGYgb3IgdGhlIHBhcmVudCBvZiB0aGUgc2tpbm5lZCBtZXNoZXNcclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG9uU2tpbkxvYWRlZE9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZTx7IG5vZGU6IFRyYW5zZm9ybU5vZGU7IHNraW5uZWROb2RlOiBUcmFuc2Zvcm1Ob2RlIH0+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfb25Ta2luTG9hZGVkT2JzZXJ2ZXI6IE51bGxhYmxlPE9ic2VydmVyPHsgbm9kZTogVHJhbnNmb3JtTm9kZTsgc2tpbm5lZE5vZGU6IFRyYW5zZm9ybU5vZGUgfT4+O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgcmFpc2VkIHdoZW4gdGhlIGxvYWRlciBjcmVhdGVzIGEgc2tpbiBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXMgb2YgdGhlIHNraW4gbm9kZS5cclxuICAgICAqIEBzZWUgaHR0cHM6Ly9kb2MuYmFieWxvbmpzLmNvbS9mZWF0dXJlcy9mZWF0dXJlc0RlZXBEaXZlL2ltcG9ydGVycy9nbFRGL2dsVEZTa2lubmluZyNpZ25vcmluZy10aGUtdHJhbnNmb3JtLW9mLXRoZS1za2lubmVkLW1lc2hcclxuICAgICAqL1xyXG4gICAgcHVibGljIHNldCBvblNraW5Mb2FkZWQoY2FsbGJhY2s6ICgobm9kZTogVHJhbnNmb3JtTm9kZSwgc2tpbm5lZE5vZGU6IFRyYW5zZm9ybU5vZGUpID0+IHZvaWQpIHwgdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX29uU2tpbkxvYWRlZE9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25Ta2luTG9hZGVkT2JzZXJ2YWJsZS5yZW1vdmUodGhpcy5fb25Ta2luTG9hZGVkT2JzZXJ2ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgdGhpcy5fb25Ta2luTG9hZGVkT2JzZXJ2ZXIgPSB0aGlzLm9uU2tpbkxvYWRlZE9ic2VydmFibGUuYWRkKChkYXRhKSA9PiBjYWxsYmFjayhkYXRhLm5vZGUsIGRhdGEuc2tpbm5lZE5vZGUpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPYnNlcnZhYmxlIHJhaXNlZCB3aGVuIHRoZSBsb2FkZXIgY3JlYXRlcyBhIHRleHR1cmUgYWZ0ZXIgcGFyc2luZyB0aGUgZ2xURiBwcm9wZXJ0aWVzIG9mIHRoZSB0ZXh0dXJlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgb25UZXh0dXJlTG9hZGVkT2JzZXJ2YWJsZSA9IG5ldyBPYnNlcnZhYmxlPEJhc2VUZXh0dXJlPigpO1xyXG5cclxuICAgIHByaXZhdGUgX29uVGV4dHVyZUxvYWRlZE9ic2VydmVyOiBOdWxsYWJsZTxPYnNlcnZlcjxCYXNlVGV4dHVyZT4+O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgcmFpc2VkIHdoZW4gdGhlIGxvYWRlciBjcmVhdGVzIGEgdGV4dHVyZSBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXMgb2YgdGhlIHRleHR1cmUuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgb25UZXh0dXJlTG9hZGVkKGNhbGxiYWNrOiAoKHRleHR1cmU6IEJhc2VUZXh0dXJlKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9vblRleHR1cmVMb2FkZWRPYnNlcnZlcikge1xyXG4gICAgICAgICAgICB0aGlzLm9uVGV4dHVyZUxvYWRlZE9ic2VydmFibGUucmVtb3ZlKHRoaXMuX29uVGV4dHVyZUxvYWRlZE9ic2VydmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX29uVGV4dHVyZUxvYWRlZE9ic2VydmVyID0gdGhpcy5vblRleHR1cmVMb2FkZWRPYnNlcnZhYmxlLmFkZChjYWxsYmFjayk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2JzZXJ2YWJsZSByYWlzZWQgd2hlbiB0aGUgbG9hZGVyIGNyZWF0ZXMgYSBtYXRlcmlhbCBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXMgb2YgdGhlIG1hdGVyaWFsLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgb25NYXRlcmlhbExvYWRlZE9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZTxNYXRlcmlhbD4oKTtcclxuXHJcbiAgICBwcml2YXRlIF9vbk1hdGVyaWFsTG9hZGVkT2JzZXJ2ZXI6IE51bGxhYmxlPE9ic2VydmVyPE1hdGVyaWFsPj47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayByYWlzZWQgd2hlbiB0aGUgbG9hZGVyIGNyZWF0ZXMgYSBtYXRlcmlhbCBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXMgb2YgdGhlIG1hdGVyaWFsLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0IG9uTWF0ZXJpYWxMb2FkZWQoY2FsbGJhY2s6ICgobWF0ZXJpYWw6IE1hdGVyaWFsKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9vbk1hdGVyaWFsTG9hZGVkT2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5vbk1hdGVyaWFsTG9hZGVkT2JzZXJ2YWJsZS5yZW1vdmUodGhpcy5fb25NYXRlcmlhbExvYWRlZE9ic2VydmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX29uTWF0ZXJpYWxMb2FkZWRPYnNlcnZlciA9IHRoaXMub25NYXRlcmlhbExvYWRlZE9ic2VydmFibGUuYWRkKGNhbGxiYWNrKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPYnNlcnZhYmxlIHJhaXNlZCB3aGVuIHRoZSBsb2FkZXIgY3JlYXRlcyBhIGNhbWVyYSBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXMgb2YgdGhlIGNhbWVyYS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG9uQ2FtZXJhTG9hZGVkT2JzZXJ2YWJsZSA9IG5ldyBPYnNlcnZhYmxlPENhbWVyYT4oKTtcclxuXHJcbiAgICBwcml2YXRlIF9vbkNhbWVyYUxvYWRlZE9ic2VydmVyOiBOdWxsYWJsZTxPYnNlcnZlcjxDYW1lcmE+PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGxiYWNrIHJhaXNlZCB3aGVuIHRoZSBsb2FkZXIgY3JlYXRlcyBhIGNhbWVyYSBhZnRlciBwYXJzaW5nIHRoZSBnbFRGIHByb3BlcnRpZXMgb2YgdGhlIGNhbWVyYS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHNldCBvbkNhbWVyYUxvYWRlZChjYWxsYmFjazogKChjYW1lcmE6IENhbWVyYSkgPT4gdm9pZCkgfCB1bmRlZmluZWQpIHtcclxuICAgICAgICBpZiAodGhpcy5fb25DYW1lcmFMb2FkZWRPYnNlcnZlcikge1xyXG4gICAgICAgICAgICB0aGlzLm9uQ2FtZXJhTG9hZGVkT2JzZXJ2YWJsZS5yZW1vdmUodGhpcy5fb25DYW1lcmFMb2FkZWRPYnNlcnZlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjYWxsYmFjaykge1xyXG4gICAgICAgICAgICB0aGlzLl9vbkNhbWVyYUxvYWRlZE9ic2VydmVyID0gdGhpcy5vbkNhbWVyYUxvYWRlZE9ic2VydmFibGUuYWRkKGNhbGxiYWNrKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPYnNlcnZhYmxlIHJhaXNlZCB3aGVuIHRoZSBhc3NldCBpcyBjb21wbGV0ZWx5IGxvYWRlZCwgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBsb2FkZXIgaXMgZGlzcG9zZWQuXHJcbiAgICAgKiBGb3IgYXNzZXRzIHdpdGggTE9EcywgcmFpc2VkIHdoZW4gYWxsIG9mIHRoZSBMT0RzIGFyZSBjb21wbGV0ZS5cclxuICAgICAqIEZvciBhc3NldHMgd2l0aG91dCBMT0RzLCByYWlzZWQgd2hlbiB0aGUgbW9kZWwgaXMgY29tcGxldGUsIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBsb2FkZXIgcmVzb2x2ZXMgdGhlIHJldHVybmVkIHByb21pc2UuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBvbkNvbXBsZXRlT2JzZXJ2YWJsZSA9IG5ldyBPYnNlcnZhYmxlPHZvaWQ+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfb25Db21wbGV0ZU9ic2VydmVyOiBOdWxsYWJsZTxPYnNlcnZlcjx2b2lkPj47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayByYWlzZWQgd2hlbiB0aGUgYXNzZXQgaXMgY29tcGxldGVseSBsb2FkZWQsIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgbG9hZGVyIGlzIGRpc3Bvc2VkLlxyXG4gICAgICogRm9yIGFzc2V0cyB3aXRoIExPRHMsIHJhaXNlZCB3aGVuIGFsbCBvZiB0aGUgTE9EcyBhcmUgY29tcGxldGUuXHJcbiAgICAgKiBGb3IgYXNzZXRzIHdpdGhvdXQgTE9EcywgcmFpc2VkIHdoZW4gdGhlIG1vZGVsIGlzIGNvbXBsZXRlLCBpbW1lZGlhdGVseSBhZnRlciB0aGUgbG9hZGVyIHJlc29sdmVzIHRoZSByZXR1cm5lZCBwcm9taXNlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0IG9uQ29tcGxldGUoY2FsbGJhY2s6ICgpID0+IHZvaWQpIHtcclxuICAgICAgICBpZiAodGhpcy5fb25Db21wbGV0ZU9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25Db21wbGV0ZU9ic2VydmFibGUucmVtb3ZlKHRoaXMuX29uQ29tcGxldGVPYnNlcnZlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX29uQ29tcGxldGVPYnNlcnZlciA9IHRoaXMub25Db21wbGV0ZU9ic2VydmFibGUuYWRkKGNhbGxiYWNrKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmFpc2VkIHdoZW4gYW4gZXJyb3Igb2NjdXJzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgb25FcnJvck9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZTxhbnk+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfb25FcnJvck9ic2VydmVyOiBOdWxsYWJsZTxPYnNlcnZlcjxhbnk+PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGxiYWNrIHJhaXNlZCB3aGVuIGFuIGVycm9yIG9jY3Vycy5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHNldCBvbkVycm9yKGNhbGxiYWNrOiAocmVhc29uOiBhbnkpID0+IHZvaWQpIHtcclxuICAgICAgICBpZiAodGhpcy5fb25FcnJvck9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25FcnJvck9ic2VydmFibGUucmVtb3ZlKHRoaXMuX29uRXJyb3JPYnNlcnZlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX29uRXJyb3JPYnNlcnZlciA9IHRoaXMub25FcnJvck9ic2VydmFibGUuYWRkKGNhbGxiYWNrKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9ic2VydmFibGUgcmFpc2VkIGFmdGVyIHRoZSBsb2FkZXIgaXMgZGlzcG9zZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBvbkRpc3Bvc2VPYnNlcnZhYmxlID0gbmV3IE9ic2VydmFibGU8dm9pZD4oKTtcclxuXHJcbiAgICBwcml2YXRlIF9vbkRpc3Bvc2VPYnNlcnZlcjogTnVsbGFibGU8T2JzZXJ2ZXI8dm9pZD4+O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgcmFpc2VkIGFmdGVyIHRoZSBsb2FkZXIgaXMgZGlzcG9zZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgb25EaXNwb3NlKGNhbGxiYWNrOiAoKSA9PiB2b2lkKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX29uRGlzcG9zZU9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25EaXNwb3NlT2JzZXJ2YWJsZS5yZW1vdmUodGhpcy5fb25EaXNwb3NlT2JzZXJ2ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9vbkRpc3Bvc2VPYnNlcnZlciA9IHRoaXMub25EaXNwb3NlT2JzZXJ2YWJsZS5hZGQoY2FsbGJhY2spO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2JzZXJ2YWJsZSByYWlzZWQgYWZ0ZXIgYSBsb2FkZXIgZXh0ZW5zaW9uIGlzIGNyZWF0ZWQuXHJcbiAgICAgKiBTZXQgYWRkaXRpb25hbCBvcHRpb25zIGZvciBhIGxvYWRlciBleHRlbnNpb24gaW4gdGhpcyBldmVudC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlYWRvbmx5IG9uRXh0ZW5zaW9uTG9hZGVkT2JzZXJ2YWJsZSA9IG5ldyBPYnNlcnZhYmxlPElHTFRGTG9hZGVyRXh0ZW5zaW9uPigpO1xyXG5cclxuICAgIHByaXZhdGUgX29uRXh0ZW5zaW9uTG9hZGVkT2JzZXJ2ZXI6IE51bGxhYmxlPE9ic2VydmVyPElHTFRGTG9hZGVyRXh0ZW5zaW9uPj47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayByYWlzZWQgYWZ0ZXIgYSBsb2FkZXIgZXh0ZW5zaW9uIGlzIGNyZWF0ZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgb25FeHRlbnNpb25Mb2FkZWQoY2FsbGJhY2s6IChleHRlbnNpb246IElHTFRGTG9hZGVyRXh0ZW5zaW9uKSA9PiB2b2lkKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX29uRXh0ZW5zaW9uTG9hZGVkT2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5vbkV4dGVuc2lvbkxvYWRlZE9ic2VydmFibGUucmVtb3ZlKHRoaXMuX29uRXh0ZW5zaW9uTG9hZGVkT2JzZXJ2ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9vbkV4dGVuc2lvbkxvYWRlZE9ic2VydmVyID0gdGhpcy5vbkV4dGVuc2lvbkxvYWRlZE9ic2VydmFibGUuYWRkKGNhbGxiYWNrKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgaWYgdGhlIGxvYWRlciBsb2dnaW5nIGlzIGVuYWJsZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXQgbG9nZ2luZ0VuYWJsZWQoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvZ2dpbmdFbmFibGVkO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzZXQgbG9nZ2luZ0VuYWJsZWQodmFsdWU6IGJvb2xlYW4pIHtcclxuICAgICAgICBpZiAodGhpcy5fbG9nZ2luZ0VuYWJsZWQgPT09IHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2xvZ2dpbmdFbmFibGVkID0gdmFsdWU7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9sb2dnaW5nRW5hYmxlZCkge1xyXG4gICAgICAgICAgICB0aGlzLl9sb2cgPSB0aGlzLl9sb2dFbmFibGVkO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvZyA9IHRoaXMuX2xvZ0Rpc2FibGVkO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmluZXMgaWYgdGhlIGxvYWRlciBzaG91bGQgY2FwdHVyZSBwZXJmb3JtYW5jZSBjb3VudGVycy5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldCBjYXB0dXJlUGVyZm9ybWFuY2VDb3VudGVycygpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fY2FwdHVyZVBlcmZvcm1hbmNlQ291bnRlcnM7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHNldCBjYXB0dXJlUGVyZm9ybWFuY2VDb3VudGVycyh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgICAgIGlmICh0aGlzLl9jYXB0dXJlUGVyZm9ybWFuY2VDb3VudGVycyA9PT0gdmFsdWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fY2FwdHVyZVBlcmZvcm1hbmNlQ291bnRlcnMgPSB2YWx1ZTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX2NhcHR1cmVQZXJmb3JtYW5jZUNvdW50ZXJzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0UGVyZm9ybWFuY2VDb3VudGVyID0gdGhpcy5fc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXJFbmFibGVkO1xyXG4gICAgICAgICAgICB0aGlzLl9lbmRQZXJmb3JtYW5jZUNvdW50ZXIgPSB0aGlzLl9lbmRQZXJmb3JtYW5jZUNvdW50ZXJFbmFibGVkO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0UGVyZm9ybWFuY2VDb3VudGVyID0gdGhpcy5fc3RhcnRQZXJmb3JtYW5jZUNvdW50ZXJEaXNhYmxlZDtcclxuICAgICAgICAgICAgdGhpcy5fZW5kUGVyZm9ybWFuY2VDb3VudGVyID0gdGhpcy5fZW5kUGVyZm9ybWFuY2VDb3VudGVyRGlzYWJsZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmaW5lcyBpZiB0aGUgbG9hZGVyIHNob3VsZCB2YWxpZGF0ZSB0aGUgYXNzZXQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB2YWxpZGF0ZSA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2JzZXJ2YWJsZSByYWlzZWQgYWZ0ZXIgdmFsaWRhdGlvbiB3aGVuIHZhbGlkYXRlIGlzIHNldCB0byB0cnVlLiBUaGUgZXZlbnQgZGF0YSBpcyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgb25WYWxpZGF0ZWRPYnNlcnZhYmxlID0gbmV3IE9ic2VydmFibGU8R0xURjIuSUdMVEZWYWxpZGF0aW9uUmVzdWx0cz4oKTtcclxuXHJcbiAgICBwcml2YXRlIF9vblZhbGlkYXRlZE9ic2VydmVyOiBOdWxsYWJsZTxPYnNlcnZlcjxHTFRGMi5JR0xURlZhbGlkYXRpb25SZXN1bHRzPj47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayByYWlzZWQgYWZ0ZXIgYSBsb2FkZXIgZXh0ZW5zaW9uIGlzIGNyZWF0ZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgb25WYWxpZGF0ZWQoY2FsbGJhY2s6IChyZXN1bHRzOiBHTFRGMi5JR0xURlZhbGlkYXRpb25SZXN1bHRzKSA9PiB2b2lkKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX29uVmFsaWRhdGVkT2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5vblZhbGlkYXRlZE9ic2VydmFibGUucmVtb3ZlKHRoaXMuX29uVmFsaWRhdGVkT2JzZXJ2ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9vblZhbGlkYXRlZE9ic2VydmVyID0gdGhpcy5vblZhbGlkYXRlZE9ic2VydmFibGUuYWRkKGNhbGxiYWNrKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9sb2FkZXI6IE51bGxhYmxlPElHTFRGTG9hZGVyPiA9IG51bGw7XHJcbiAgICBwcml2YXRlIF9zdGF0ZTogTnVsbGFibGU8R0xURkxvYWRlclN0YXRlPiA9IG51bGw7XHJcbiAgICBwcml2YXRlIF9wcm9ncmVzc0NhbGxiYWNrPzogKGV2ZW50OiBJU2NlbmVMb2FkZXJQcm9ncmVzc0V2ZW50KSA9PiB2b2lkO1xyXG4gICAgcHJpdmF0ZSBfcmVxdWVzdHMgPSBuZXcgQXJyYXk8SUZpbGVSZXF1ZXN0SW5mbz4oKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE5hbWUgb2YgdGhlIGxvYWRlciAoXCJnbHRmXCIpXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gR0xURkZpbGVMb2FkZXJNZXRhZGF0YS5uYW1lO1xyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyByZWFkb25seSBleHRlbnNpb25zID0gR0xURkZpbGVMb2FkZXJNZXRhZGF0YS5leHRlbnNpb25zO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGlzcG9zZXMgdGhlIGxvYWRlciwgcmVsZWFzZXMgcmVzb3VyY2VzIGR1cmluZyBsb2FkLCBhbmQgY2FuY2VscyBhbnkgb3V0c3RhbmRpbmcgcmVxdWVzdHMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkaXNwb3NlKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLl9sb2FkZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyID0gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgcmVxdWVzdCBvZiB0aGlzLl9yZXF1ZXN0cykge1xyXG4gICAgICAgICAgICByZXF1ZXN0LmFib3J0KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9yZXF1ZXN0cy5sZW5ndGggPSAwO1xyXG5cclxuICAgICAgICBkZWxldGUgdGhpcy5fcHJvZ3Jlc3NDYWxsYmFjaztcclxuXHJcbiAgICAgICAgdGhpcy5wcmVwcm9jZXNzVXJsQXN5bmMgPSAodXJsKSA9PiBQcm9taXNlLnJlc29sdmUodXJsKTtcclxuXHJcbiAgICAgICAgdGhpcy5vbk1lc2hMb2FkZWRPYnNlcnZhYmxlLmNsZWFyKCk7XHJcbiAgICAgICAgdGhpcy5vblNraW5Mb2FkZWRPYnNlcnZhYmxlLmNsZWFyKCk7XHJcbiAgICAgICAgdGhpcy5vblRleHR1cmVMb2FkZWRPYnNlcnZhYmxlLmNsZWFyKCk7XHJcbiAgICAgICAgdGhpcy5vbk1hdGVyaWFsTG9hZGVkT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG4gICAgICAgIHRoaXMub25DYW1lcmFMb2FkZWRPYnNlcnZhYmxlLmNsZWFyKCk7XHJcbiAgICAgICAgdGhpcy5vbkNvbXBsZXRlT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG4gICAgICAgIHRoaXMub25FeHRlbnNpb25Mb2FkZWRPYnNlcnZhYmxlLmNsZWFyKCk7XHJcblxyXG4gICAgICAgIHRoaXMub25EaXNwb3NlT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnModW5kZWZpbmVkKTtcclxuICAgICAgICB0aGlzLm9uRGlzcG9zZU9ic2VydmFibGUuY2xlYXIoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbG9hZEZpbGUoXHJcbiAgICAgICAgc2NlbmU6IFNjZW5lLFxyXG4gICAgICAgIGZpbGVPclVybDogRmlsZSB8IHN0cmluZyB8IEFycmF5QnVmZmVyVmlldyxcclxuICAgICAgICByb290VXJsOiBzdHJpbmcsXHJcbiAgICAgICAgb25TdWNjZXNzOiAoZGF0YTogdW5rbm93biwgcmVzcG9uc2VVUkw/OiBzdHJpbmcpID0+IHZvaWQsXHJcbiAgICAgICAgb25Qcm9ncmVzcz86IChldjogSVNjZW5lTG9hZGVyUHJvZ3Jlc3NFdmVudCkgPT4gdm9pZCxcclxuICAgICAgICB1c2VBcnJheUJ1ZmZlcj86IGJvb2xlYW4sXHJcbiAgICAgICAgb25FcnJvcj86IChyZXF1ZXN0PzogV2ViUmVxdWVzdCwgZXhjZXB0aW9uPzogTG9hZEZpbGVFcnJvcikgPT4gdm9pZCxcclxuICAgICAgICBuYW1lPzogc3RyaW5nXHJcbiAgICApOiBOdWxsYWJsZTxJRmlsZVJlcXVlc3Q+IHtcclxuICAgICAgICBpZiAoQXJyYXlCdWZmZXIuaXNWaWV3KGZpbGVPclVybCkpIHtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZEJpbmFyeShzY2VuZSwgZmlsZU9yVXJsIGFzIEFycmF5QnVmZmVyVmlldywgcm9vdFVybCwgb25TdWNjZXNzLCBvbkVycm9yLCBuYW1lKTtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9wcm9ncmVzc0NhbGxiYWNrID0gb25Qcm9ncmVzcztcclxuXHJcbiAgICAgICAgY29uc3QgZmlsZU5hbWUgPSAoZmlsZU9yVXJsIGFzIEZpbGUpLm5hbWUgfHwgVG9vbHMuR2V0RmlsZW5hbWUoZmlsZU9yVXJsIGFzIHN0cmluZyk7XHJcblxyXG4gICAgICAgIGlmICh1c2VBcnJheUJ1ZmZlcikge1xyXG4gICAgICAgICAgICBpZiAodGhpcy51c2VSYW5nZVJlcXVlc3RzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy52YWxpZGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5XYXJuKFwiZ2xURiB2YWxpZGF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgd2hlbiByYW5nZSByZXF1ZXN0cyBhcmUgZW5hYmxlZFwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBmaWxlUmVxdWVzdDogSUZpbGVSZXF1ZXN0ID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIGFib3J0OiAoKSA9PiB7fSxcclxuICAgICAgICAgICAgICAgICAgICBvbkNvbXBsZXRlT2JzZXJ2YWJsZTogbmV3IE9ic2VydmFibGU8SUZpbGVSZXF1ZXN0PigpLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhQnVmZmVyID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlYWRBc3luYzogKGJ5dGVPZmZzZXQ6IG51bWJlciwgYnl0ZUxlbmd0aDogbnVtYmVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxBcnJheUJ1ZmZlclZpZXc+KChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvYWRGaWxlKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjZW5lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVPclVybCBhcyBGaWxlIHwgc3RyaW5nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IFVpbnQ4QXJyYXkoZGF0YSBhcyBBcnJheUJ1ZmZlcikpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh3ZWJSZXF1ZXN0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlYlJlcXVlc3Quc2V0UmVxdWVzdEhlYWRlcihcIlJhbmdlXCIsIGBieXRlcz0ke2J5dGVPZmZzZXR9LSR7Ynl0ZU9mZnNldCArIGJ5dGVMZW5ndGggLSAxfWApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgYnl0ZUxlbmd0aDogMCxcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5fdW5wYWNrQmluYXJ5QXN5bmMobmV3IERhdGFSZWFkZXIoZGF0YUJ1ZmZlcikpLnRoZW4oXHJcbiAgICAgICAgICAgICAgICAgICAgKGxvYWRlckRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVJlcXVlc3Qub25Db21wbGV0ZU9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKGZpbGVSZXF1ZXN0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb25TdWNjZXNzKGxvYWRlckRhdGEpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgb25FcnJvciA/IChlcnJvcikgPT4gb25FcnJvcih1bmRlZmluZWQsIGVycm9yKSA6IHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmlsZVJlcXVlc3Q7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkRmlsZShcclxuICAgICAgICAgICAgICAgIHNjZW5lLFxyXG4gICAgICAgICAgICAgICAgZmlsZU9yVXJsIGFzIEZpbGUgfCBzdHJpbmcsXHJcbiAgICAgICAgICAgICAgICAoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRlKHNjZW5lLCBuZXcgVWludDhBcnJheShkYXRhIGFzIEFycmF5QnVmZmVyLCAwLCAoZGF0YSBhcyBBcnJheUJ1ZmZlcikuYnl0ZUxlbmd0aCksIHJvb3RVcmwsIGZpbGVOYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl91bnBhY2tCaW5hcnlBc3luYyhcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IERhdGFSZWFkZXIoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZEFzeW5jOiAoYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCkgPT4gcmVhZEFzeW5jKGRhdGEgYXMgQXJyYXlCdWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZUxlbmd0aDogKGRhdGEgYXMgQXJyYXlCdWZmZXIpLmJ5dGVMZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgKS50aGVuKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAobG9hZGVyRGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25TdWNjZXNzKGxvYWRlckRhdGEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkVycm9yID8gKGVycm9yKSA9PiBvbkVycm9yKHVuZGVmaW5lZCwgZXJyb3IpIDogdW5kZWZpbmVkXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB0cnVlLFxyXG4gICAgICAgICAgICAgICAgb25FcnJvclxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkRmlsZShcclxuICAgICAgICAgICAgICAgIHNjZW5lLFxyXG4gICAgICAgICAgICAgICAgZmlsZU9yVXJsLFxyXG4gICAgICAgICAgICAgICAgKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWxpZGF0ZShzY2VuZSwgZGF0YSBhcyBzdHJpbmcsIHJvb3RVcmwsIGZpbGVOYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb25TdWNjZXNzKHsganNvbjogdGhpcy5fcGFyc2VKc29uKGRhdGEgYXMgc3RyaW5nKSB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9uRXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uRXJyb3IoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBmYWxzZSxcclxuICAgICAgICAgICAgICAgIG9uRXJyb3JcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9hZEJpbmFyeShcclxuICAgICAgICBzY2VuZTogU2NlbmUsXHJcbiAgICAgICAgZGF0YTogQXJyYXlCdWZmZXJWaWV3LFxyXG4gICAgICAgIHJvb3RVcmw6IHN0cmluZyxcclxuICAgICAgICBvblN1Y2Nlc3M6IChkYXRhOiB1bmtub3duLCByZXNwb25zZVVSTD86IHN0cmluZykgPT4gdm9pZCxcclxuICAgICAgICBvbkVycm9yPzogKHJlcXVlc3Q/OiBXZWJSZXF1ZXN0LCBleGNlcHRpb24/OiBMb2FkRmlsZUVycm9yKSA9PiB2b2lkLFxyXG4gICAgICAgIGZpbGVOYW1lPzogc3RyaW5nXHJcbiAgICApOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl92YWxpZGF0ZShzY2VuZSwgbmV3IFVpbnQ4QXJyYXkoZGF0YS5idWZmZXIsIGRhdGEuYnl0ZU9mZnNldCwgZGF0YS5ieXRlTGVuZ3RoKSwgcm9vdFVybCwgZmlsZU5hbWUpO1xyXG4gICAgICAgIHRoaXMuX3VucGFja0JpbmFyeUFzeW5jKFxyXG4gICAgICAgICAgICBuZXcgRGF0YVJlYWRlcih7XHJcbiAgICAgICAgICAgICAgICByZWFkQXN5bmM6IChieXRlT2Zmc2V0LCBieXRlTGVuZ3RoKSA9PiByZWFkVmlld0FzeW5jKGRhdGEsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpLFxyXG4gICAgICAgICAgICAgICAgYnl0ZUxlbmd0aDogZGF0YS5ieXRlTGVuZ3RoLFxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICkudGhlbihcclxuICAgICAgICAgICAgKGxvYWRlckRhdGEpID0+IHtcclxuICAgICAgICAgICAgICAgIG9uU3VjY2Vzcyhsb2FkZXJEYXRhKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgb25FcnJvciA/IChlcnJvcikgPT4gb25FcnJvcih1bmRlZmluZWQsIGVycm9yKSA6IHVuZGVmaW5lZFxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGltcG9ydE1lc2hBc3luYyhcclxuICAgICAgICBtZXNoZXNOYW1lczogc3RyaW5nIHwgcmVhZG9ubHkgc3RyaW5nW10gfCBudWxsIHwgdW5kZWZpbmVkLFxyXG4gICAgICAgIHNjZW5lOiBTY2VuZSxcclxuICAgICAgICBkYXRhOiBJR0xURkxvYWRlckRhdGEsXHJcbiAgICAgICAgcm9vdFVybDogc3RyaW5nLFxyXG4gICAgICAgIG9uUHJvZ3Jlc3M/OiAoZXZlbnQ6IElTY2VuZUxvYWRlclByb2dyZXNzRXZlbnQpID0+IHZvaWQsXHJcbiAgICAgICAgZmlsZU5hbWU/OiBzdHJpbmdcclxuICAgICk6IFByb21pc2U8SVNjZW5lTG9hZGVyQXN5bmNSZXN1bHQ+IHtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMub25QYXJzZWRPYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyhkYXRhKTtcclxuICAgICAgICAgICAgdGhpcy5vblBhcnNlZE9ic2VydmFibGUuY2xlYXIoKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2xvZyhgTG9hZGluZyAke2ZpbGVOYW1lIHx8IFwiXCJ9YCk7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRlciA9IHRoaXMuX2dldExvYWRlcihkYXRhKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRlci5pbXBvcnRNZXNoQXN5bmMobWVzaGVzTmFtZXMsIHNjZW5lLCBudWxsLCBkYXRhLCByb290VXJsLCBvblByb2dyZXNzLCBmaWxlTmFtZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGxvYWRBc3luYyhzY2VuZTogU2NlbmUsIGRhdGE6IElHTFRGTG9hZGVyRGF0YSwgcm9vdFVybDogc3RyaW5nLCBvblByb2dyZXNzPzogKGV2ZW50OiBJU2NlbmVMb2FkZXJQcm9ncmVzc0V2ZW50KSA9PiB2b2lkLCBmaWxlTmFtZT86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5vblBhcnNlZE9ic2VydmFibGUubm90aWZ5T2JzZXJ2ZXJzKGRhdGEpO1xyXG4gICAgICAgICAgICB0aGlzLm9uUGFyc2VkT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fbG9nKGBMb2FkaW5nICR7ZmlsZU5hbWUgfHwgXCJcIn1gKTtcclxuICAgICAgICAgICAgdGhpcy5fbG9hZGVyID0gdGhpcy5fZ2V0TG9hZGVyKGRhdGEpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9hZGVyLmxvYWRBc3luYyhzY2VuZSwgZGF0YSwgcm9vdFVybCwgb25Qcm9ncmVzcywgZmlsZU5hbWUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBsb2FkQXNzZXRDb250YWluZXJBc3luYyhcclxuICAgICAgICBzY2VuZTogU2NlbmUsXHJcbiAgICAgICAgZGF0YTogSUdMVEZMb2FkZXJEYXRhLFxyXG4gICAgICAgIHJvb3RVcmw6IHN0cmluZyxcclxuICAgICAgICBvblByb2dyZXNzPzogKGV2ZW50OiBJU2NlbmVMb2FkZXJQcm9ncmVzc0V2ZW50KSA9PiB2b2lkLFxyXG4gICAgICAgIGZpbGVOYW1lPzogc3RyaW5nXHJcbiAgICApOiBQcm9taXNlPEFzc2V0Q29udGFpbmVyPiB7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLm9uUGFyc2VkT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMoZGF0YSk7XHJcbiAgICAgICAgICAgIHRoaXMub25QYXJzZWRPYnNlcnZhYmxlLmNsZWFyKCk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9sb2coYExvYWRpbmcgJHtmaWxlTmFtZSB8fCBcIlwifWApO1xyXG4gICAgICAgICAgICB0aGlzLl9sb2FkZXIgPSB0aGlzLl9nZXRMb2FkZXIoZGF0YSk7XHJcblxyXG4gICAgICAgICAgICAvLyBQcmVwYXJlIHRoZSBhc3NldCBjb250YWluZXIuXHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IG5ldyBBc3NldENvbnRhaW5lcihzY2VuZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBHZXQgbWF0ZXJpYWxzL3RleHR1cmVzIHdoZW4gbG9hZGluZyB0byBhZGQgdG8gY29udGFpbmVyXHJcbiAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsczogQXJyYXk8TWF0ZXJpYWw+ID0gW107XHJcbiAgICAgICAgICAgIHRoaXMub25NYXRlcmlhbExvYWRlZE9ic2VydmFibGUuYWRkKChtYXRlcmlhbCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgbWF0ZXJpYWxzLnB1c2gobWF0ZXJpYWwpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgY29uc3QgdGV4dHVyZXM6IEFycmF5PEJhc2VUZXh0dXJlPiA9IFtdO1xyXG4gICAgICAgICAgICB0aGlzLm9uVGV4dHVyZUxvYWRlZE9ic2VydmFibGUuYWRkKCh0ZXh0dXJlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0ZXh0dXJlcy5wdXNoKHRleHR1cmUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgY29uc3QgY2FtZXJhczogQXJyYXk8Q2FtZXJhPiA9IFtdO1xyXG4gICAgICAgICAgICB0aGlzLm9uQ2FtZXJhTG9hZGVkT2JzZXJ2YWJsZS5hZGQoKGNhbWVyYSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY2FtZXJhcy5wdXNoKGNhbWVyYSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgbW9ycGhUYXJnZXRNYW5hZ2VyczogQXJyYXk8TW9ycGhUYXJnZXRNYW5hZ2VyPiA9IFtdO1xyXG4gICAgICAgICAgICB0aGlzLm9uTWVzaExvYWRlZE9ic2VydmFibGUuYWRkKChtZXNoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAobWVzaC5tb3JwaFRhcmdldE1hbmFnZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICBtb3JwaFRhcmdldE1hbmFnZXJzLnB1c2gobWVzaC5tb3JwaFRhcmdldE1hbmFnZXIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkZXIuaW1wb3J0TWVzaEFzeW5jKG51bGwsIHNjZW5lLCBjb250YWluZXIsIGRhdGEsIHJvb3RVcmwsIG9uUHJvZ3Jlc3MsIGZpbGVOYW1lKS50aGVuKChyZXN1bHQpID0+IHtcclxuICAgICAgICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGNvbnRhaW5lci5nZW9tZXRyaWVzLCByZXN1bHQuZ2VvbWV0cmllcyk7XHJcbiAgICAgICAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShjb250YWluZXIubWVzaGVzLCByZXN1bHQubWVzaGVzKTtcclxuICAgICAgICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGNvbnRhaW5lci5wYXJ0aWNsZVN5c3RlbXMsIHJlc3VsdC5wYXJ0aWNsZVN5c3RlbXMpO1xyXG4gICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoY29udGFpbmVyLnNrZWxldG9ucywgcmVzdWx0LnNrZWxldG9ucyk7XHJcbiAgICAgICAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShjb250YWluZXIuYW5pbWF0aW9uR3JvdXBzLCByZXN1bHQuYW5pbWF0aW9uR3JvdXBzKTtcclxuICAgICAgICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGNvbnRhaW5lci5tYXRlcmlhbHMsIG1hdGVyaWFscyk7XHJcbiAgICAgICAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShjb250YWluZXIudGV4dHVyZXMsIHRleHR1cmVzKTtcclxuICAgICAgICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGNvbnRhaW5lci5saWdodHMsIHJlc3VsdC5saWdodHMpO1xyXG4gICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoY29udGFpbmVyLnRyYW5zZm9ybU5vZGVzLCByZXN1bHQudHJhbnNmb3JtTm9kZXMpO1xyXG4gICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoY29udGFpbmVyLmNhbWVyYXMsIGNhbWVyYXMpO1xyXG4gICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoY29udGFpbmVyLm1vcnBoVGFyZ2V0TWFuYWdlcnMsIG1vcnBoVGFyZ2V0TWFuYWdlcnMpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRhaW5lcjtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNhbkRpcmVjdExvYWQoZGF0YTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIEdMVEZGaWxlTG9hZGVyTWV0YWRhdGEuY2FuRGlyZWN0TG9hZChkYXRhKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZGlyZWN0TG9hZChzY2VuZTogU2NlbmUsIGRhdGE6IHN0cmluZyk6IFByb21pc2U8T2JqZWN0PiB7XHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICBkYXRhLnN0YXJ0c1dpdGgoXCJiYXNlNjQsXCIgKyBHTFRGTWFnaWNCYXNlNjRFbmNvZGVkKSB8fCAvLyB0aGlzIGlzIHRlY2huaWNhbGx5IGluY29ycmVjdCwgYnV0IHdpbGwgY29udGludWUgdG8gc3VwcG9ydCBmb3IgYmFja2NvbXBhdC5cclxuICAgICAgICAgICAgZGF0YS5zdGFydHNXaXRoKFwiO2Jhc2U2NCxcIiArIEdMVEZNYWdpY0Jhc2U2NEVuY29kZWQpIHx8XHJcbiAgICAgICAgICAgIGRhdGEuc3RhcnRzV2l0aChcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTtiYXNlNjQsXCIgKyBHTFRGTWFnaWNCYXNlNjRFbmNvZGVkKSB8fFxyXG4gICAgICAgICAgICBkYXRhLnN0YXJ0c1dpdGgoXCJtb2RlbC9nbHRmLWJpbmFyeTtiYXNlNjQsXCIgKyBHTFRGTWFnaWNCYXNlNjRFbmNvZGVkKVxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgICBjb25zdCBhcnJheUJ1ZmZlciA9IERlY29kZUJhc2U2NFVybFRvQmluYXJ5KGRhdGEpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fdmFsaWRhdGUoc2NlbmUsIG5ldyBVaW50OEFycmF5KGFycmF5QnVmZmVyLCAwLCBhcnJheUJ1ZmZlci5ieXRlTGVuZ3RoKSk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl91bnBhY2tCaW5hcnlBc3luYyhcclxuICAgICAgICAgICAgICAgIG5ldyBEYXRhUmVhZGVyKHtcclxuICAgICAgICAgICAgICAgICAgICByZWFkQXN5bmM6IChieXRlT2Zmc2V0LCBieXRlTGVuZ3RoKSA9PiByZWFkQXN5bmMoYXJyYXlCdWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpLFxyXG4gICAgICAgICAgICAgICAgICAgIGJ5dGVMZW5ndGg6IGFycmF5QnVmZmVyLmJ5dGVMZW5ndGgsXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fdmFsaWRhdGUoc2NlbmUsIGRhdGEpO1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoeyBqc29uOiB0aGlzLl9wYXJzZUpzb24oZGF0YSkgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgY2FsbGJhY2sgdGhhdCBhbGxvd3MgY3VzdG9tIGhhbmRsaW5nIG9mIHRoZSByb290IHVybCBiYXNlZCBvbiB0aGUgcmVzcG9uc2UgdXJsLlxyXG4gICAgICogQHBhcmFtIHJvb3RVcmwgdGhlIG9yaWdpbmFsIHJvb3QgdXJsXHJcbiAgICAgKiBAcGFyYW0gcmVzcG9uc2VVUkwgdGhlIHJlc3BvbnNlIHVybCBpZiBhdmFpbGFibGVcclxuICAgICAqIEByZXR1cm5zIHRoZSBuZXcgcm9vdCB1cmxcclxuICAgICAqL1xyXG4gICAgcHVibGljIHJld3JpdGVSb290VVJMPyhyb290VXJsOiBzdHJpbmcsIHJlc3BvbnNlVVJMPzogc3RyaW5nKTogc3RyaW5nO1xyXG5cclxuICAgIC8qKiBAaW50ZXJuYWwgKi9cclxuICAgIHB1YmxpYyBjcmVhdGVQbHVnaW4ob3B0aW9uczogU2NlbmVMb2FkZXJQbHVnaW5PcHRpb25zKTogSVNjZW5lTG9hZGVyUGx1Z2luQXN5bmMge1xyXG4gICAgICAgIHJldHVybiBuZXcgR0xURkZpbGVMb2FkZXIob3B0aW9uc1tHTFRGRmlsZUxvYWRlck1ldGFkYXRhLm5hbWVdKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBsb2FkZXIgc3RhdGUgb3IgbnVsbCBpZiB0aGUgbG9hZGVyIGlzIG5vdCBhY3RpdmUuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXQgbG9hZGVyU3RhdGUoKTogTnVsbGFibGU8R0xURkxvYWRlclN0YXRlPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2JzZXJ2YWJsZSByYWlzZWQgd2hlbiB0aGUgbG9hZGVyIHN0YXRlIGNoYW5nZXMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkxvYWRlclN0YXRlQ2hhbmdlZE9ic2VydmFibGUgPSBuZXcgT2JzZXJ2YWJsZTxOdWxsYWJsZTxHTFRGTG9hZGVyU3RhdGU+PigpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBhc3NldCBpcyBjb21wbGV0ZWx5IGxvYWRlZC5cclxuICAgICAqIEByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGFzc2V0IGlzIGNvbXBsZXRlbHkgbG9hZGVkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgd2hlbkNvbXBsZXRlQXN5bmMoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5vbkNvbXBsZXRlT2JzZXJ2YWJsZS5hZGRPbmNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHRoaXMub25FcnJvck9ic2VydmFibGUuYWRkT25jZSgocmVhc29uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZWplY3QocmVhc29uKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAaW50ZXJuYWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9zZXRTdGF0ZShzdGF0ZTogR0xURkxvYWRlclN0YXRlKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSBzdGF0ZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9zdGF0ZSA9IHN0YXRlO1xyXG4gICAgICAgIHRoaXMub25Mb2FkZXJTdGF0ZUNoYW5nZWRPYnNlcnZhYmxlLm5vdGlmeU9ic2VydmVycyh0aGlzLl9zdGF0ZSk7XHJcbiAgICAgICAgdGhpcy5fbG9nKEdMVEZMb2FkZXJTdGF0ZVt0aGlzLl9zdGF0ZV0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGludGVybmFsXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBfbG9hZEZpbGUoXHJcbiAgICAgICAgc2NlbmU6IFNjZW5lLFxyXG4gICAgICAgIGZpbGVPclVybDogRmlsZSB8IHN0cmluZyxcclxuICAgICAgICBvblN1Y2Nlc3M6IChkYXRhOiBzdHJpbmcgfCBBcnJheUJ1ZmZlcikgPT4gdm9pZCxcclxuICAgICAgICB1c2VBcnJheUJ1ZmZlcj86IGJvb2xlYW4sXHJcbiAgICAgICAgb25FcnJvcj86IChyZXF1ZXN0PzogV2ViUmVxdWVzdCkgPT4gdm9pZCxcclxuICAgICAgICBvbk9wZW5lZD86IChyZXF1ZXN0OiBXZWJSZXF1ZXN0KSA9PiB2b2lkXHJcbiAgICApOiBJRmlsZVJlcXVlc3Qge1xyXG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSBzY2VuZS5fbG9hZEZpbGUoXHJcbiAgICAgICAgICAgIGZpbGVPclVybCxcclxuICAgICAgICAgICAgb25TdWNjZXNzLFxyXG4gICAgICAgICAgICAoZXZlbnQpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX29uUHJvZ3Jlc3MoZXZlbnQsIHJlcXVlc3QpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB0cnVlLFxyXG4gICAgICAgICAgICB1c2VBcnJheUJ1ZmZlcixcclxuICAgICAgICAgICAgb25FcnJvcixcclxuICAgICAgICAgICAgb25PcGVuZWRcclxuICAgICAgICApIGFzIElGaWxlUmVxdWVzdEluZm87XHJcbiAgICAgICAgcmVxdWVzdC5vbkNvbXBsZXRlT2JzZXJ2YWJsZS5hZGQoKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyBGb3JjZSB0aGUgbGVuZ3RoIGNvbXB1dGFibGUgdG8gYmUgdHJ1ZSBzaW5jZSB3ZSBjYW4gZ3VhcmFudGVlIHRoZSBkYXRhIGlzIGxvYWRlZC5cclxuICAgICAgICAgICAgcmVxdWVzdC5fbGVuZ3RoQ29tcHV0YWJsZSA9IHRydWU7XHJcbiAgICAgICAgICAgIHJlcXVlc3QuX3RvdGFsID0gcmVxdWVzdC5fbG9hZGVkO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuX3JlcXVlc3RzLnB1c2gocmVxdWVzdCk7XHJcbiAgICAgICAgcmV0dXJuIHJlcXVlc3Q7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfb25Qcm9ncmVzcyhldmVudDogUHJvZ3Jlc3NFdmVudCwgcmVxdWVzdDogSUZpbGVSZXF1ZXN0SW5mbyk6IHZvaWQge1xyXG4gICAgICAgIGlmICghdGhpcy5fcHJvZ3Jlc3NDYWxsYmFjaykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXF1ZXN0Ll9sZW5ndGhDb21wdXRhYmxlID0gZXZlbnQubGVuZ3RoQ29tcHV0YWJsZTtcclxuICAgICAgICByZXF1ZXN0Ll9sb2FkZWQgPSBldmVudC5sb2FkZWQ7XHJcbiAgICAgICAgcmVxdWVzdC5fdG90YWwgPSBldmVudC50b3RhbDtcclxuXHJcbiAgICAgICAgbGV0IGxlbmd0aENvbXB1dGFibGUgPSB0cnVlO1xyXG4gICAgICAgIGxldCBsb2FkZWQgPSAwO1xyXG4gICAgICAgIGxldCB0b3RhbCA9IDA7XHJcbiAgICAgICAgZm9yIChjb25zdCByZXF1ZXN0IG9mIHRoaXMuX3JlcXVlc3RzKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0Ll9sZW5ndGhDb21wdXRhYmxlID09PSB1bmRlZmluZWQgfHwgcmVxdWVzdC5fbG9hZGVkID09PSB1bmRlZmluZWQgfHwgcmVxdWVzdC5fdG90YWwgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZW5ndGhDb21wdXRhYmxlID0gbGVuZ3RoQ29tcHV0YWJsZSAmJiByZXF1ZXN0Ll9sZW5ndGhDb21wdXRhYmxlO1xyXG4gICAgICAgICAgICBsb2FkZWQgKz0gcmVxdWVzdC5fbG9hZGVkO1xyXG4gICAgICAgICAgICB0b3RhbCArPSByZXF1ZXN0Ll90b3RhbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3Byb2dyZXNzQ2FsbGJhY2soe1xyXG4gICAgICAgICAgICBsZW5ndGhDb21wdXRhYmxlOiBsZW5ndGhDb21wdXRhYmxlLFxyXG4gICAgICAgICAgICBsb2FkZWQ6IGxvYWRlZCxcclxuICAgICAgICAgICAgdG90YWw6IGxlbmd0aENvbXB1dGFibGUgPyB0b3RhbCA6IDAsXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfdmFsaWRhdGUoc2NlbmU6IFNjZW5lLCBkYXRhOiBzdHJpbmcgfCBVaW50OEFycmF5LCByb290VXJsID0gXCJcIiwgZmlsZU5hbWUgPSBcIlwiKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnZhbGlkYXRlKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3N0YXJ0UGVyZm9ybWFuY2VDb3VudGVyKFwiVmFsaWRhdGUgSlNPTlwiKTtcclxuICAgICAgICBHTFRGVmFsaWRhdGlvbi5WYWxpZGF0ZUFzeW5jKGRhdGEsIHJvb3RVcmwsIGZpbGVOYW1lLCAodXJpKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByZXByb2Nlc3NVcmxBc3luYyhyb290VXJsICsgdXJpKS50aGVuKCh1cmwpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzY2VuZS5fbG9hZEZpbGVBc3luYyh1cmwsIHVuZGVmaW5lZCwgdHJ1ZSwgdHJ1ZSkudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShkYXRhLCAwLCBkYXRhLmJ5dGVMZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pLnRoZW4oXHJcbiAgICAgICAgICAgIChyZXN1bHQpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2VuZFBlcmZvcm1hbmNlQ291bnRlcihcIlZhbGlkYXRlIEpTT05cIik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uVmFsaWRhdGVkT2JzZXJ2YWJsZS5ub3RpZnlPYnNlcnZlcnMocmVzdWx0KTtcclxuICAgICAgICAgICAgICAgIHRoaXMub25WYWxpZGF0ZWRPYnNlcnZhYmxlLmNsZWFyKCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIChyZWFzb24pID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2VuZFBlcmZvcm1hbmNlQ291bnRlcihcIlZhbGlkYXRlIEpTT05cIik7XHJcbiAgICAgICAgICAgICAgICBUb29scy5XYXJuKGBGYWlsZWQgdG8gdmFsaWRhdGU6ICR7cmVhc29uLm1lc3NhZ2V9YCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uVmFsaWRhdGVkT2JzZXJ2YWJsZS5jbGVhcigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9nZXRMb2FkZXIobG9hZGVyRGF0YTogSUdMVEZMb2FkZXJEYXRhKTogSUdMVEZMb2FkZXIge1xyXG4gICAgICAgIGNvbnN0IGFzc2V0ID0gKDxhbnk+bG9hZGVyRGF0YS5qc29uKS5hc3NldCB8fCB7fTtcclxuXHJcbiAgICAgICAgdGhpcy5fbG9nKGBBc3NldCB2ZXJzaW9uOiAke2Fzc2V0LnZlcnNpb259YCk7XHJcbiAgICAgICAgYXNzZXQubWluVmVyc2lvbiAmJiB0aGlzLl9sb2coYEFzc2V0IG1pbmltdW0gdmVyc2lvbjogJHthc3NldC5taW5WZXJzaW9ufWApO1xyXG4gICAgICAgIGFzc2V0LmdlbmVyYXRvciAmJiB0aGlzLl9sb2coYEFzc2V0IGdlbmVyYXRvcjogJHthc3NldC5nZW5lcmF0b3J9YCk7XHJcblxyXG4gICAgICAgIGNvbnN0IHZlcnNpb24gPSBHTFRGRmlsZUxvYWRlci5fcGFyc2VWZXJzaW9uKGFzc2V0LnZlcnNpb24pO1xyXG4gICAgICAgIGlmICghdmVyc2lvbikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHZlcnNpb246IFwiICsgYXNzZXQudmVyc2lvbik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoYXNzZXQubWluVmVyc2lvbiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG1pblZlcnNpb24gPSBHTFRGRmlsZUxvYWRlci5fcGFyc2VWZXJzaW9uKGFzc2V0Lm1pblZlcnNpb24pO1xyXG4gICAgICAgICAgICBpZiAoIW1pblZlcnNpb24pIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgbWluaW11bSB2ZXJzaW9uOiBcIiArIGFzc2V0Lm1pblZlcnNpb24pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoR0xURkZpbGVMb2FkZXIuX2NvbXBhcmVWZXJzaW9uKG1pblZlcnNpb24sIHsgbWFqb3I6IDIsIG1pbm9yOiAwIH0pID4gMCkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW5jb21wYXRpYmxlIG1pbmltdW0gdmVyc2lvbjogXCIgKyBhc3NldC5taW5WZXJzaW9uKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgY3JlYXRlTG9hZGVyczogeyBba2V5OiBudW1iZXJdOiAocGFyZW50OiBHTFRGRmlsZUxvYWRlcikgPT4gSUdMVEZMb2FkZXIgfSA9IHtcclxuICAgICAgICAgICAgMTogR0xURkZpbGVMb2FkZXIuX0NyZWF0ZUdMVEYxTG9hZGVyLFxyXG4gICAgICAgICAgICAyOiBHTFRGRmlsZUxvYWRlci5fQ3JlYXRlR0xURjJMb2FkZXIsXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgY29uc3QgY3JlYXRlTG9hZGVyID0gY3JlYXRlTG9hZGVyc1t2ZXJzaW9uLm1ham9yXTtcclxuICAgICAgICBpZiAoIWNyZWF0ZUxvYWRlcikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCB2ZXJzaW9uOiBcIiArIGFzc2V0LnZlcnNpb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUxvYWRlcih0aGlzKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9wYXJzZUpzb24oanNvbjogc3RyaW5nKTogT2JqZWN0IHtcclxuICAgICAgICB0aGlzLl9zdGFydFBlcmZvcm1hbmNlQ291bnRlcihcIlBhcnNlIEpTT05cIik7XHJcbiAgICAgICAgdGhpcy5fbG9nKGBKU09OIGxlbmd0aDogJHtqc29uLmxlbmd0aH1gKTtcclxuICAgICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGpzb24pO1xyXG4gICAgICAgIHRoaXMuX2VuZFBlcmZvcm1hbmNlQ291bnRlcihcIlBhcnNlIEpTT05cIik7XHJcbiAgICAgICAgcmV0dXJuIHBhcnNlZDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF91bnBhY2tCaW5hcnlBc3luYyhkYXRhUmVhZGVyOiBEYXRhUmVhZGVyKTogUHJvbWlzZTxJR0xURkxvYWRlckRhdGE+IHtcclxuICAgICAgICB0aGlzLl9zdGFydFBlcmZvcm1hbmNlQ291bnRlcihcIlVucGFjayBCaW5hcnlcIik7XHJcblxyXG4gICAgICAgIC8vIFJlYWQgbWFnaWMgKyB2ZXJzaW9uICsgbGVuZ3RoICsganNvbiBsZW5ndGggKyBqc29uIGZvcm1hdFxyXG4gICAgICAgIHJldHVybiBkYXRhUmVhZGVyLmxvYWRBc3luYygyMCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IEJpbmFyeSA9IHtcclxuICAgICAgICAgICAgICAgIE1hZ2ljOiAweDQ2NTQ2YzY3LFxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgY29uc3QgbWFnaWMgPSBkYXRhUmVhZGVyLnJlYWRVaW50MzIoKTtcclxuICAgICAgICAgICAgaWYgKG1hZ2ljICE9PSBCaW5hcnkuTWFnaWMpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoXCJVbmV4cGVjdGVkIG1hZ2ljOiBcIiArIG1hZ2ljLCBFcnJvckNvZGVzLkdMVEZMb2FkZXJVbmV4cGVjdGVkTWFnaWNFcnJvcik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHZlcnNpb24gPSBkYXRhUmVhZGVyLnJlYWRVaW50MzIoKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxvZ2dpbmdFbmFibGVkKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2coYEJpbmFyeSB2ZXJzaW9uOiAke3ZlcnNpb259YCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IGRhdGFSZWFkZXIucmVhZFVpbnQzMigpO1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMudXNlUmFuZ2VSZXF1ZXN0cyAmJiBsZW5ndGggIT09IGRhdGFSZWFkZXIuYnVmZmVyLmJ5dGVMZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIExvZ2dlci5XYXJuKGBMZW5ndGggaW4gaGVhZGVyIGRvZXMgbm90IG1hdGNoIGFjdHVhbCBkYXRhIGxlbmd0aDogJHtsZW5ndGh9ICE9ICR7ZGF0YVJlYWRlci5idWZmZXIuYnl0ZUxlbmd0aH1gKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGV0IHVucGFja2VkOiBQcm9taXNlPElHTFRGTG9hZGVyRGF0YT47XHJcbiAgICAgICAgICAgIHN3aXRjaCAodmVyc2lvbikge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAxOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQgPSB0aGlzLl91bnBhY2tCaW5hcnlWMUFzeW5jKGRhdGFSZWFkZXIsIGxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjYXNlIDI6IHtcclxuICAgICAgICAgICAgICAgICAgICB1bnBhY2tlZCA9IHRoaXMuX3VucGFja0JpbmFyeVYyQXN5bmMoZGF0YVJlYWRlciwgbGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCB2ZXJzaW9uOiBcIiArIHZlcnNpb24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9lbmRQZXJmb3JtYW5jZUNvdW50ZXIoXCJVbnBhY2sgQmluYXJ5XCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHVucGFja2VkO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3VucGFja0JpbmFyeVYxQXN5bmMoZGF0YVJlYWRlcjogRGF0YVJlYWRlciwgbGVuZ3RoOiBudW1iZXIpOiBQcm9taXNlPElHTFRGTG9hZGVyRGF0YT4ge1xyXG4gICAgICAgIGNvbnN0IENvbnRlbnRGb3JtYXQgPSB7XHJcbiAgICAgICAgICAgIEpTT046IDAsXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgY29uc3QgY29udGVudExlbmd0aCA9IGRhdGFSZWFkZXIucmVhZFVpbnQzMigpO1xyXG4gICAgICAgIGNvbnN0IGNvbnRlbnRGb3JtYXQgPSBkYXRhUmVhZGVyLnJlYWRVaW50MzIoKTtcclxuXHJcbiAgICAgICAgaWYgKGNvbnRlbnRGb3JtYXQgIT09IENvbnRlbnRGb3JtYXQuSlNPTikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgY29udGVudCBmb3JtYXQ6ICR7Y29udGVudEZvcm1hdH1gKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGJvZHlMZW5ndGggPSBsZW5ndGggLSBkYXRhUmVhZGVyLmJ5dGVPZmZzZXQ7XHJcblxyXG4gICAgICAgIGNvbnN0IGRhdGE6IElHTFRGTG9hZGVyRGF0YSA9IHsganNvbjogdGhpcy5fcGFyc2VKc29uKGRhdGFSZWFkZXIucmVhZFN0cmluZyhjb250ZW50TGVuZ3RoKSksIGJpbjogbnVsbCB9O1xyXG4gICAgICAgIGlmIChib2R5TGVuZ3RoICE9PSAwKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0Qnl0ZU9mZnNldCA9IGRhdGFSZWFkZXIuYnl0ZU9mZnNldDtcclxuICAgICAgICAgICAgZGF0YS5iaW4gPSB7XHJcbiAgICAgICAgICAgICAgICByZWFkQXN5bmM6IChieXRlT2Zmc2V0LCBieXRlTGVuZ3RoKSA9PiBkYXRhUmVhZGVyLmJ1ZmZlci5yZWFkQXN5bmMoc3RhcnRCeXRlT2Zmc2V0ICsgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCksXHJcbiAgICAgICAgICAgICAgICBieXRlTGVuZ3RoOiBib2R5TGVuZ3RoLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShkYXRhKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF91bnBhY2tCaW5hcnlWMkFzeW5jKGRhdGFSZWFkZXI6IERhdGFSZWFkZXIsIGxlbmd0aDogbnVtYmVyKTogUHJvbWlzZTxJR0xURkxvYWRlckRhdGE+IHtcclxuICAgICAgICBjb25zdCBDaHVua0Zvcm1hdCA9IHtcclxuICAgICAgICAgICAgSlNPTjogMHg0ZTRmNTM0YSxcclxuICAgICAgICAgICAgQklOOiAweDAwNGU0OTQyLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8vIFJlYWQgdGhlIEpTT04gY2h1bmsgaGVhZGVyLlxyXG4gICAgICAgIGNvbnN0IGNodW5rTGVuZ3RoID0gZGF0YVJlYWRlci5yZWFkVWludDMyKCk7XHJcbiAgICAgICAgY29uc3QgY2h1bmtGb3JtYXQgPSBkYXRhUmVhZGVyLnJlYWRVaW50MzIoKTtcclxuICAgICAgICBpZiAoY2h1bmtGb3JtYXQgIT09IENodW5rRm9ybWF0LkpTT04pIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRmlyc3QgY2h1bmsgZm9ybWF0IGlzIG5vdCBKU09OXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQmFpbCBpZiB0aGVyZSBhcmUgbm8gb3RoZXIgY2h1bmtzLlxyXG4gICAgICAgIGlmIChkYXRhUmVhZGVyLmJ5dGVPZmZzZXQgKyBjaHVua0xlbmd0aCA9PT0gbGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBkYXRhUmVhZGVyLmxvYWRBc3luYyhjaHVua0xlbmd0aCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4geyBqc29uOiB0aGlzLl9wYXJzZUpzb24oZGF0YVJlYWRlci5yZWFkU3RyaW5nKGNodW5rTGVuZ3RoKSksIGJpbjogbnVsbCB9O1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFJlYWQgdGhlIEpTT04gY2h1bmsgYW5kIHRoZSBsZW5ndGggYW5kIHR5cGUgb2YgdGhlIG5leHQgY2h1bmsuXHJcbiAgICAgICAgcmV0dXJuIGRhdGFSZWFkZXIubG9hZEFzeW5jKGNodW5rTGVuZ3RoICsgOCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGRhdGE6IElHTFRGTG9hZGVyRGF0YSA9IHsganNvbjogdGhpcy5fcGFyc2VKc29uKGRhdGFSZWFkZXIucmVhZFN0cmluZyhjaHVua0xlbmd0aCkpLCBiaW46IG51bGwgfTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHJlYWRBc3luYyA9ICgpOiBQcm9taXNlPElHTFRGTG9hZGVyRGF0YT4gPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2h1bmtMZW5ndGggPSBkYXRhUmVhZGVyLnJlYWRVaW50MzIoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNodW5rRm9ybWF0ID0gZGF0YVJlYWRlci5yZWFkVWludDMyKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChjaHVua0Zvcm1hdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgQ2h1bmtGb3JtYXQuSlNPTjoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIEpTT04gY2h1bmtcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgQ2h1bmtGb3JtYXQuQklOOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0Qnl0ZU9mZnNldCA9IGRhdGFSZWFkZXIuYnl0ZU9mZnNldDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5iaW4gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkQXN5bmM6IChieXRlT2Zmc2V0LCBieXRlTGVuZ3RoKSA9PiBkYXRhUmVhZGVyLmJ1ZmZlci5yZWFkQXN5bmMoc3RhcnRCeXRlT2Zmc2V0ICsgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlTGVuZ3RoOiBjaHVua0xlbmd0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVJlYWRlci5za2lwQnl0ZXMoY2h1bmtMZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgdW5yZWNvZ25pemVkIGNodW5rRm9ybWF0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFSZWFkZXIuc2tpcEJ5dGVzKGNodW5rTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChkYXRhUmVhZGVyLmJ5dGVPZmZzZXQgIT09IGxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhUmVhZGVyLmxvYWRBc3luYyg4KS50aGVuKHJlYWRBc3luYyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShkYXRhKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiByZWFkQXN5bmMoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfcGFyc2VWZXJzaW9uKHZlcnNpb246IHN0cmluZyk6IE51bGxhYmxlPHsgbWFqb3I6IG51bWJlcjsgbWlub3I6IG51bWJlciB9PiB7XHJcbiAgICAgICAgaWYgKHZlcnNpb24gPT09IFwiMS4wXCIgfHwgdmVyc2lvbiA9PT0gXCIxLjAuMVwiKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBtYWpvcjogMSxcclxuICAgICAgICAgICAgICAgIG1pbm9yOiAwLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgbWF0Y2ggPSAodmVyc2lvbiArIFwiXCIpLm1hdGNoKC9eKFxcZCspXFwuKFxcZCspLyk7XHJcbiAgICAgICAgaWYgKCFtYXRjaCkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIG1ham9yOiBwYXJzZUludChtYXRjaFsxXSksXHJcbiAgICAgICAgICAgIG1pbm9yOiBwYXJzZUludChtYXRjaFsyXSksXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXRpYyBfY29tcGFyZVZlcnNpb24oYTogeyBtYWpvcjogbnVtYmVyOyBtaW5vcjogbnVtYmVyIH0sIGI6IHsgbWFqb3I6IG51bWJlcjsgbWlub3I6IG51bWJlciB9KTogbnVtYmVyIHtcclxuICAgICAgICBpZiAoYS5tYWpvciA+IGIubWFqb3IpIHtcclxuICAgICAgICAgICAgcmV0dXJuIDE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChhLm1ham9yIDwgYi5tYWpvcikge1xyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChhLm1pbm9yID4gYi5taW5vcikge1xyXG4gICAgICAgICAgICByZXR1cm4gMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGEubWlub3IgPCBiLm1pbm9yKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgX2xvZ1NwYWNlcyA9IFwiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIjtcclxuICAgIHByaXZhdGUgX2xvZ0luZGVudExldmVsID0gMDtcclxuICAgIHByaXZhdGUgX2xvZ2dpbmdFbmFibGVkID0gZmFsc2U7XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIF9sb2cgPSB0aGlzLl9sb2dEaXNhYmxlZDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBpbnRlcm5hbFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgX2xvZ09wZW4obWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fbG9nKG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuX2xvZ0luZGVudExldmVsKys7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIF9sb2dDbG9zZSgpOiB2b2lkIHtcclxuICAgICAgICAtLXRoaXMuX2xvZ0luZGVudExldmVsO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2xvZ0VuYWJsZWQobWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3Qgc3BhY2VzID0gR0xURkZpbGVMb2FkZXIuX2xvZ1NwYWNlcy5zdWJzdHJpbmcoMCwgdGhpcy5fbG9nSW5kZW50TGV2ZWwgKiAyKTtcclxuICAgICAgICBMb2dnZXIuTG9nKGAke3NwYWNlc30ke21lc3NhZ2V9YCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbG9nRGlzYWJsZWQobWVzc2FnZTogc3RyaW5nKTogdm9pZCB7fVxyXG5cclxuICAgIHByaXZhdGUgX2NhcHR1cmVQZXJmb3JtYW5jZUNvdW50ZXJzID0gZmFsc2U7XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIF9zdGFydFBlcmZvcm1hbmNlQ291bnRlciA9IHRoaXMuX3N0YXJ0UGVyZm9ybWFuY2VDb3VudGVyRGlzYWJsZWQ7XHJcblxyXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gICAgcHVibGljIF9lbmRQZXJmb3JtYW5jZUNvdW50ZXIgPSB0aGlzLl9lbmRQZXJmb3JtYW5jZUNvdW50ZXJEaXNhYmxlZDtcclxuXHJcbiAgICBwcml2YXRlIF9zdGFydFBlcmZvcm1hbmNlQ291bnRlckVuYWJsZWQoY291bnRlck5hbWU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIFRvb2xzLlN0YXJ0UGVyZm9ybWFuY2VDb3VudGVyKGNvdW50ZXJOYW1lKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9zdGFydFBlcmZvcm1hbmNlQ291bnRlckRpc2FibGVkKGNvdW50ZXJOYW1lOiBzdHJpbmcpOiB2b2lkIHt9XHJcblxyXG4gICAgcHJpdmF0ZSBfZW5kUGVyZm9ybWFuY2VDb3VudGVyRW5hYmxlZChjb3VudGVyTmFtZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgVG9vbHMuRW5kUGVyZm9ybWFuY2VDb3VudGVyKGNvdW50ZXJOYW1lKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9lbmRQZXJmb3JtYW5jZUNvdW50ZXJEaXNhYmxlZChjb3VudGVyTmFtZTogc3RyaW5nKTogdm9pZCB7fVxyXG59XHJcblxyXG5yZWdpc3RlclNjZW5lTG9hZGVyUGx1Z2luKG5ldyBHTFRGRmlsZUxvYWRlcigpKTtcclxuIiwiaW1wb3J0IHR5cGUgKiBhcyBHTFRGMiBmcm9tIFwiYmFieWxvbmpzLWdsdGYyaW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7IFRvb2xzIH0gZnJvbSBcImNvcmUvTWlzYy90b29sc1wiO1xyXG5cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5kZWNsYXJlIGxldCBHTFRGVmFsaWRhdG9yOiBHTFRGMi5JR0xURlZhbGlkYXRvcjtcclxuXHJcbi8vIFdvcmtlckdsb2JhbFNjb3BlXHJcbmRlY2xhcmUgZnVuY3Rpb24gaW1wb3J0U2NyaXB0cyguLi51cmxzOiBzdHJpbmdbXSk6IHZvaWQ7XHJcbmRlY2xhcmUgZnVuY3Rpb24gcG9zdE1lc3NhZ2UobWVzc2FnZTogYW55LCB0cmFuc2Zlcj86IGFueVtdKTogdm9pZDtcclxuXHJcbmZ1bmN0aW9uIHZhbGlkYXRlQXN5bmMoXHJcbiAgICBkYXRhOiBzdHJpbmcgfCBVaW50OEFycmF5LFxyXG4gICAgcm9vdFVybDogc3RyaW5nLFxyXG4gICAgZmlsZU5hbWU6IHN0cmluZyxcclxuICAgIGdldEV4dGVybmFsUmVzb3VyY2U6ICh1cmk6IHN0cmluZykgPT4gUHJvbWlzZTxVaW50OEFycmF5PlxyXG4pOiBQcm9taXNlPEdMVEYyLklHTFRGVmFsaWRhdGlvblJlc3VsdHM+IHtcclxuICAgIGNvbnN0IG9wdGlvbnM6IEdMVEYyLklHTFRGVmFsaWRhdGlvbk9wdGlvbnMgPSB7XHJcbiAgICAgICAgZXh0ZXJuYWxSZXNvdXJjZUZ1bmN0aW9uOiBnZXRFeHRlcm5hbFJlc291cmNlLFxyXG4gICAgfTtcclxuXHJcbiAgICBpZiAoZmlsZU5hbWUpIHtcclxuICAgICAgICBvcHRpb25zLnVyaSA9IHJvb3RVcmwgPT09IFwiZmlsZTpcIiA/IGZpbGVOYW1lIDogcm9vdFVybCArIGZpbGVOYW1lO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBBcnJheUJ1ZmZlci5pc1ZpZXcoZGF0YSkgPyBHTFRGVmFsaWRhdG9yLnZhbGlkYXRlQnl0ZXMoZGF0YSwgb3B0aW9ucykgOiBHTFRGVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nKGRhdGEsIG9wdGlvbnMpO1xyXG59XHJcblxyXG4vKipcclxuICogVGhlIHdvcmtlciBmdW5jdGlvbiB0aGF0IGdldHMgY29udmVydGVkIHRvIGEgYmxvYiB1cmwgdG8gcGFzcyBpbnRvIGEgd29ya2VyLlxyXG4gKi9cclxuZnVuY3Rpb24gd29ya2VyRnVuYygpOiB2b2lkIHtcclxuICAgIGNvbnN0IHBlbmRpbmdFeHRlcm5hbFJlc291cmNlczogQXJyYXk8eyByZXNvbHZlOiAoZGF0YTogYW55KSA9PiB2b2lkOyByZWplY3Q6IChyZWFzb246IGFueSkgPT4gdm9pZCB9PiA9IFtdO1xyXG5cclxuICAgIG9ubWVzc2FnZSA9IChtZXNzYWdlKSA9PiB7XHJcbiAgICAgICAgY29uc3QgZGF0YSA9IG1lc3NhZ2UuZGF0YTtcclxuICAgICAgICBzd2l0Y2ggKGRhdGEuaWQpIHtcclxuICAgICAgICAgICAgY2FzZSBcImluaXRcIjoge1xyXG4gICAgICAgICAgICAgICAgaW1wb3J0U2NyaXB0cyhkYXRhLnVybCk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFwidmFsaWRhdGVcIjoge1xyXG4gICAgICAgICAgICAgICAgdmFsaWRhdGVBc3luYyhcclxuICAgICAgICAgICAgICAgICAgICBkYXRhLmRhdGEsXHJcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5yb290VXJsLFxyXG4gICAgICAgICAgICAgICAgICAgIGRhdGEuZmlsZU5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgKHVyaSkgPT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBwZW5kaW5nRXh0ZXJuYWxSZXNvdXJjZXMubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVuZGluZ0V4dGVybmFsUmVzb3VyY2VzLnB1c2goeyByZXNvbHZlLCByZWplY3QgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZSh7IGlkOiBcImdldEV4dGVybmFsUmVzb3VyY2VcIiwgaW5kZXg6IGluZGV4LCB1cmk6IHVyaSB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICkudGhlbihcclxuICAgICAgICAgICAgICAgICAgICAodmFsdWUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcG9zdE1lc3NhZ2UoeyBpZDogXCJ2YWxpZGF0ZS5yZXNvbHZlXCIsIHZhbHVlOiB2YWx1ZSB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIChyZWFzb24pID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcG9zdE1lc3NhZ2UoeyBpZDogXCJ2YWxpZGF0ZS5yZWplY3RcIiwgcmVhc29uOiByZWFzb24gfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgXCJnZXRFeHRlcm5hbFJlc291cmNlLnJlc29sdmVcIjoge1xyXG4gICAgICAgICAgICAgICAgcGVuZGluZ0V4dGVybmFsUmVzb3VyY2VzW2RhdGEuaW5kZXhdLnJlc29sdmUoZGF0YS52YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFwiZ2V0RXh0ZXJuYWxSZXNvdXJjZS5yZWplY3RcIjoge1xyXG4gICAgICAgICAgICAgICAgcGVuZGluZ0V4dGVybmFsUmVzb3VyY2VzW2RhdGEuaW5kZXhdLnJlamVjdChkYXRhLnJlYXNvbik7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDb25maWd1cmF0aW9uIGZvciBnbFRGIHZhbGlkYXRpb25cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdMVEZWYWxpZGF0aW9uQ29uZmlndXJhdGlvbiB7XHJcbiAgICAvKipcclxuICAgICAqIFRoZSB1cmwgb2YgdGhlIGdsVEYgdmFsaWRhdG9yLlxyXG4gICAgICovXHJcbiAgICB1cmw6IHN0cmluZztcclxufVxyXG5cclxuLyoqXHJcbiAqIGdsVEYgdmFsaWRhdGlvblxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEdMVEZWYWxpZGF0aW9uIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIGNvbmZpZ3VyYXRpb24uIERlZmF1bHRzIHRvIGB7IHVybDogXCJodHRwczovL2Nkbi5iYWJ5bG9uanMuY29tL2dsdGZfdmFsaWRhdG9yLmpzXCIgfWAuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgQ29uZmlndXJhdGlvbjogSUdMVEZWYWxpZGF0aW9uQ29uZmlndXJhdGlvbiA9IHtcclxuICAgICAgICB1cmw6IGAke1Rvb2xzLl9EZWZhdWx0Q2RuVXJsfS9nbHRmX3ZhbGlkYXRvci5qc2AsXHJcbiAgICB9O1xyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIF9Mb2FkU2NyaXB0UHJvbWlzZTogUHJvbWlzZTx2b2lkPjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFZhbGlkYXRlIGEgZ2xURiBhc3NldCB1c2luZyB0aGUgZ2xURi1WYWxpZGF0b3IuXHJcbiAgICAgKiBAcGFyYW0gZGF0YSBUaGUgSlNPTiBvZiBhIGdsVEYgb3IgdGhlIGFycmF5IGJ1ZmZlciBvZiBhIGJpbmFyeSBnbFRGXHJcbiAgICAgKiBAcGFyYW0gcm9vdFVybCBUaGUgcm9vdCB1cmwgZm9yIHRoZSBnbFRGXHJcbiAgICAgKiBAcGFyYW0gZmlsZU5hbWUgVGhlIGZpbGUgbmFtZSBmb3IgdGhlIGdsVEZcclxuICAgICAqIEBwYXJhbSBnZXRFeHRlcm5hbFJlc291cmNlIFRoZSBjYWxsYmFjayB0byBnZXQgZXh0ZXJuYWwgcmVzb3VyY2VzIGZvciB0aGUgZ2xURiB2YWxpZGF0b3JcclxuICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGdsVEYgdmFsaWRhdGlvbiByZXN1bHRzIG9uY2UgY29tcGxldGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBWYWxpZGF0ZUFzeW5jKFxyXG4gICAgICAgIGRhdGE6IHN0cmluZyB8IFVpbnQ4QXJyYXksXHJcbiAgICAgICAgcm9vdFVybDogc3RyaW5nLFxyXG4gICAgICAgIGZpbGVOYW1lOiBzdHJpbmcsXHJcbiAgICAgICAgZ2V0RXh0ZXJuYWxSZXNvdXJjZTogKHVyaTogc3RyaW5nKSA9PiBQcm9taXNlPFVpbnQ4QXJyYXk+XHJcbiAgICApOiBQcm9taXNlPEdMVEYyLklHTFRGVmFsaWRhdGlvblJlc3VsdHM+IHtcclxuICAgICAgICBpZiAodHlwZW9mIFdvcmtlciA9PT0gXCJmdW5jdGlvblwiKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB3b3JrZXJDb250ZW50ID0gYCR7dmFsaWRhdGVBc3luY30oJHt3b3JrZXJGdW5jfSkoKWA7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB3b3JrZXJCbG9iVXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihbd29ya2VyQ29udGVudF0sIHsgdHlwZTogXCJhcHBsaWNhdGlvbi9qYXZhc2NyaXB0XCIgfSkpO1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgd29ya2VyID0gbmV3IFdvcmtlcih3b3JrZXJCbG9iVXJsKTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBvbkVycm9yID0gKGVycm9yOiBFcnJvckV2ZW50KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgd29ya2VyLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLCBvbkVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICB3b3JrZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgb25NZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBvbk1lc3NhZ2UgPSAobWVzc2FnZTogTWVzc2FnZUV2ZW50KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IG1lc3NhZ2UuZGF0YTtcclxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGRhdGEuaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcImdldEV4dGVybmFsUmVzb3VyY2VcIjoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0RXh0ZXJuYWxSZXNvdXJjZShkYXRhLnVyaSkudGhlbihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodmFsdWUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd29ya2VyLnBvc3RNZXNzYWdlKHsgaWQ6IFwiZ2V0RXh0ZXJuYWxSZXNvdXJjZS5yZXNvbHZlXCIsIGluZGV4OiBkYXRhLmluZGV4LCB2YWx1ZTogdmFsdWUgfSwgW3ZhbHVlLmJ1ZmZlcl0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlYXNvbikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JrZXIucG9zdE1lc3NhZ2UoeyBpZDogXCJnZXRFeHRlcm5hbFJlc291cmNlLnJlamVjdFwiLCBpbmRleDogZGF0YS5pbmRleCwgcmVhc29uOiByZWFzb24gfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJ2YWxpZGF0ZS5yZXNvbHZlXCI6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvcmtlci5yZW1vdmVFdmVudExpc3RlbmVyKFwiZXJyb3JcIiwgb25FcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JrZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgb25NZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoZGF0YS52YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JrZXIudGVybWluYXRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwidmFsaWRhdGUucmVqZWN0XCI6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvcmtlci5yZW1vdmVFdmVudExpc3RlbmVyKFwiZXJyb3JcIiwgb25FcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JrZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgb25NZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChkYXRhLnJlYXNvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JrZXIudGVybWluYXRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIHdvcmtlci5hZGRFdmVudExpc3RlbmVyKFwiZXJyb3JcIiwgb25FcnJvcik7XHJcbiAgICAgICAgICAgICAgICB3b3JrZXIuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgb25NZXNzYWdlKTtcclxuXHJcbiAgICAgICAgICAgICAgICB3b3JrZXIucG9zdE1lc3NhZ2UoeyBpZDogXCJpbml0XCIsIHVybDogVG9vbHMuR2V0QmFieWxvblNjcmlwdFVSTCh0aGlzLkNvbmZpZ3VyYXRpb24udXJsKSB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXlCdWZmZXIuaXNWaWV3KGRhdGEpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gU2xpY2UgdGhlIGRhdGEgdG8gYXZvaWQgY29weWluZyB0aGUgd2hvbGUgYXJyYXkgYnVmZmVyLlxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNsaWNlZERhdGEgPSBkYXRhLnNsaWNlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgd29ya2VyLnBvc3RNZXNzYWdlKHsgaWQ6IFwidmFsaWRhdGVcIiwgZGF0YTogc2xpY2VkRGF0YSwgcm9vdFVybDogcm9vdFVybCwgZmlsZU5hbWU6IGZpbGVOYW1lIH0sIFtzbGljZWREYXRhLmJ1ZmZlcl0pO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB3b3JrZXIucG9zdE1lc3NhZ2UoeyBpZDogXCJ2YWxpZGF0ZVwiLCBkYXRhOiBkYXRhLCByb290VXJsOiByb290VXJsLCBmaWxlTmFtZTogZmlsZU5hbWUgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5fTG9hZFNjcmlwdFByb21pc2UpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX0xvYWRTY3JpcHRQcm9taXNlID0gVG9vbHMuTG9hZEJhYnlsb25TY3JpcHRBc3luYyh0aGlzLkNvbmZpZ3VyYXRpb24udXJsKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX0xvYWRTY3JpcHRQcm9taXNlLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbGlkYXRlQXN5bmMoZGF0YSwgcm9vdFVybCwgZmlsZU5hbWUsIGdldEV4dGVybmFsUmVzb3VyY2UpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0ICogYXMgRmlsZUxvYWRlciBmcm9tIFwibG9hZGVycy9nbFRGL2dsVEZGaWxlTG9hZGVyXCI7XHJcbmltcG9ydCAqIGFzIFZhbGlkYXRpb24gZnJvbSBcImxvYWRlcnMvZ2xURi9nbFRGVmFsaWRhdGlvblwiO1xyXG5cclxuLyoqXHJcbiAqIFRoaXMgaXMgdGhlIGVudHJ5IHBvaW50IGZvciB0aGUgVU1EIG1vZHVsZS5cclxuICogVGhlIGVudHJ5IHBvaW50IGZvciBhIGZ1dHVyZSBFU00gcGFja2FnZSBzaG91bGQgYmUgaW5kZXgudHNcclxuICovXHJcbmNvbnN0IGdsb2JhbE9iamVjdCA9IHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogdW5kZWZpbmVkO1xyXG5pZiAodHlwZW9mIGdsb2JhbE9iamVjdCAhPT0gXCJ1bmRlZmluZWRcIikge1xyXG4gICAgKDxhbnk+Z2xvYmFsT2JqZWN0KS5CQUJZTE9OID0gKDxhbnk+Z2xvYmFsT2JqZWN0KS5CQUJZTE9OIHx8IHt9O1xyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gRmlsZUxvYWRlcikge1xyXG4gICAgICAgICg8YW55Pmdsb2JhbE9iamVjdCkuQkFCWUxPTltrZXldID0gKDxhbnk+RmlsZUxvYWRlcilba2V5XTtcclxuICAgIH1cclxuICAgIGZvciAoY29uc3Qga2V5IGluIFZhbGlkYXRpb24pIHtcclxuICAgICAgICAoPGFueT5nbG9iYWxPYmplY3QpLkJBQllMT05ba2V5XSA9ICg8YW55PlZhbGlkYXRpb24pW2tleV07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCAqIGZyb20gXCJsb2FkZXJzL2dsVEYvZ2xURkZpbGVMb2FkZXJcIjtcclxuZXhwb3J0ICogZnJvbSBcImxvYWRlcnMvZ2xURi9nbFRGVmFsaWRhdGlvblwiO1xyXG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvbm8taW50ZXJuYWwtbW9kdWxlcyAqL1xyXG5pbXBvcnQgKiBhcyBHTFRGMSBmcm9tIFwibG9hZGVycy9nbFRGLzEuMC9pbmRleFwiO1xyXG5cclxuLyoqXHJcbiAqIFRoaXMgaXMgdGhlIGVudHJ5IHBvaW50IGZvciB0aGUgVU1EIG1vZHVsZS5cclxuICogVGhlIGVudHJ5IHBvaW50IGZvciBhIGZ1dHVyZSBFU00gcGFja2FnZSBzaG91bGQgYmUgaW5kZXgudHNcclxuICovXHJcbmNvbnN0IGdsb2JhbE9iamVjdCA9IHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogdW5kZWZpbmVkO1xyXG5pZiAodHlwZW9mIGdsb2JhbE9iamVjdCAhPT0gXCJ1bmRlZmluZWRcIikge1xyXG4gICAgKDxhbnk+Z2xvYmFsT2JqZWN0KS5CQUJZTE9OID0gKDxhbnk+Z2xvYmFsT2JqZWN0KS5CQUJZTE9OIHx8IHt9O1xyXG4gICAgKDxhbnk+Z2xvYmFsT2JqZWN0KS5CQUJZTE9OLkdMVEYxID0gKDxhbnk+Z2xvYmFsT2JqZWN0KS5CQUJZTE9OLkdMVEYxIHx8IHt9O1xyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gR0xURjEpIHtcclxuICAgICAgICAoPGFueT5nbG9iYWxPYmplY3QpLkJBQllMT04uR0xURjFba2V5XSA9ICg8YW55PkdMVEYxKVtrZXldO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgeyBHTFRGMSB9O1xyXG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvbm8taW50ZXJuYWwtbW9kdWxlcyAqL1xyXG5pbXBvcnQgKiBhcyBFeHRlbnNpb25zIGZyb20gXCJsb2FkZXJzL2dsVEYvMi4wL0V4dGVuc2lvbnMvaW5kZXhcIjtcclxuaW1wb3J0ICogYXMgSW50ZXJmYWNlcyBmcm9tIFwibG9hZGVycy9nbFRGLzIuMC9nbFRGTG9hZGVySW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgKiBhcyBHTFRGMiBmcm9tIFwibG9hZGVycy9nbFRGLzIuMC9pbmRleFwiO1xyXG5cclxuLyoqXHJcbiAqIFRoaXMgaXMgdGhlIGVudHJ5IHBvaW50IGZvciB0aGUgVU1EIG1vZHVsZS5cclxuICogVGhlIGVudHJ5IHBvaW50IGZvciBhIGZ1dHVyZSBFU00gcGFja2FnZSBzaG91bGQgYmUgaW5kZXgudHNcclxuICovXHJcbmNvbnN0IGdsb2JhbE9iamVjdCA9IHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogdW5kZWZpbmVkO1xyXG5pZiAodHlwZW9mIGdsb2JhbE9iamVjdCAhPT0gXCJ1bmRlZmluZWRcIikge1xyXG4gICAgKDxhbnk+Z2xvYmFsT2JqZWN0KS5CQUJZTE9OID0gKDxhbnk+Z2xvYmFsT2JqZWN0KS5CQUJZTE9OIHx8IHt9O1xyXG4gICAgY29uc3QgQkFCWUxPTiA9ICg8YW55Pmdsb2JhbE9iamVjdCkuQkFCWUxPTjtcclxuICAgIEJBQllMT04uR0xURjIgPSBCQUJZTE9OLkdMVEYyIHx8IHt9O1xyXG4gICAgQkFCWUxPTi5HTFRGMi5Mb2FkZXIgPSBCQUJZTE9OLkdMVEYyLkxvYWRlciB8fCB7fTtcclxuICAgIEJBQllMT04uR0xURjIuTG9hZGVyLkV4dGVuc2lvbnMgPSBCQUJZTE9OLkdMVEYyLkxvYWRlci5FeHRlbnNpb25zIHx8IHt9O1xyXG5cclxuICAgIGNvbnN0IGtleXMgPSBbXTtcclxuICAgIGZvciAoY29uc3Qga2V5IGluIEV4dGVuc2lvbnMpIHtcclxuICAgICAgICBCQUJZTE9OLkdMVEYyLkxvYWRlci5FeHRlbnNpb25zW2tleV0gPSAoPGFueT5FeHRlbnNpb25zKVtrZXldO1xyXG4gICAgICAgIGtleXMucHVzaChrZXkpO1xyXG4gICAgfVxyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gSW50ZXJmYWNlcykge1xyXG4gICAgICAgIEJBQllMT04uR0xURjIuTG9hZGVyW2tleV0gPSAoPGFueT5JbnRlcmZhY2VzKVtrZXldO1xyXG4gICAgICAgIGtleXMucHVzaChrZXkpO1xyXG4gICAgfVxyXG5cclxuICAgIGZvciAoY29uc3Qga2V5IGluIEdMVEYyKSB7XHJcbiAgICAgICAgLy8gUHJldmVudCBSZWFzc2lnbm1lbnQuXHJcbiAgICAgICAgaWYgKGtleXMuaW5kZXhPZihrZXkpID4gLTEpIHtcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBCQUJZTE9OLkdMVEYyW2tleV0gPSAoPGFueT5HTFRGMilba2V5XTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IHsgR0xURjIgfTtcclxuIiwiLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9leHBvcnRcclxuZXhwb3J0ICogZnJvbSBcIi4vbGVnYWN5LWdsVEZcIjtcclxuZXhwb3J0ICogZnJvbSBcIi4vbGVnYWN5LWdsVEYxXCI7XHJcbmV4cG9ydCAqIGZyb20gXCIuL2xlZ2FjeS1nbFRGMlwiO1xyXG4iLCJtb2R1bGUuZXhwb3J0cyA9IF9fV0VCUEFDS19FWFRFUk5BTF9NT0RVTEVfYmFieWxvbmpzX01pc2NfdG9vbHNfXzsiLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cblxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXG5cblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSwgU3VwcHJlc3NlZEVycm9yLCBTeW1ib2wsIEl0ZXJhdG9yICovXG5cbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xuICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XG4gICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XG4gICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xuICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xuICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xuICBleHRlbmRTdGF0aWNzKGQsIGIpO1xuICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cbiAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xufVxuXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XG4gIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XG4gICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xuICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XG4gICAgICB9XG4gICAgICByZXR1cm4gdDtcbiAgfVxuICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XG4gIHZhciB0ID0ge307XG4gIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxuICAgICAgdFtwXSA9IHNbcF07XG4gIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcbiAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXG4gICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xuICAgICAgfVxuICByZXR1cm4gdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcbiAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcbiAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcbiAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcbiAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XG4gIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gX19lc0RlY29yYXRlKGN0b3IsIGRlc2NyaXB0b3JJbiwgZGVjb3JhdG9ycywgY29udGV4dEluLCBpbml0aWFsaXplcnMsIGV4dHJhSW5pdGlhbGl6ZXJzKSB7XG4gIGZ1bmN0aW9uIGFjY2VwdChmKSB7IGlmIChmICE9PSB2b2lkIDAgJiYgdHlwZW9mIGYgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZ1bmN0aW9uIGV4cGVjdGVkXCIpOyByZXR1cm4gZjsgfVxuICB2YXIga2luZCA9IGNvbnRleHRJbi5raW5kLCBrZXkgPSBraW5kID09PSBcImdldHRlclwiID8gXCJnZXRcIiA6IGtpbmQgPT09IFwic2V0dGVyXCIgPyBcInNldFwiIDogXCJ2YWx1ZVwiO1xuICB2YXIgdGFyZ2V0ID0gIWRlc2NyaXB0b3JJbiAmJiBjdG9yID8gY29udGV4dEluW1wic3RhdGljXCJdID8gY3RvciA6IGN0b3IucHJvdG90eXBlIDogbnVsbDtcbiAgdmFyIGRlc2NyaXB0b3IgPSBkZXNjcmlwdG9ySW4gfHwgKHRhcmdldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSkgOiB7fSk7XG4gIHZhciBfLCBkb25lID0gZmFsc2U7XG4gIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgY29udGV4dCA9IHt9O1xuICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4pIGNvbnRleHRbcF0gPSBwID09PSBcImFjY2Vzc1wiID8ge30gOiBjb250ZXh0SW5bcF07XG4gICAgICBmb3IgKHZhciBwIGluIGNvbnRleHRJbi5hY2Nlc3MpIGNvbnRleHQuYWNjZXNzW3BdID0gY29udGV4dEluLmFjY2Vzc1twXTtcbiAgICAgIGNvbnRleHQuYWRkSW5pdGlhbGl6ZXIgPSBmdW5jdGlvbiAoZikgeyBpZiAoZG9uZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBhZGQgaW5pdGlhbGl6ZXJzIGFmdGVyIGRlY29yYXRpb24gaGFzIGNvbXBsZXRlZFwiKTsgZXh0cmFJbml0aWFsaXplcnMucHVzaChhY2NlcHQoZiB8fCBudWxsKSk7IH07XG4gICAgICB2YXIgcmVzdWx0ID0gKDAsIGRlY29yYXRvcnNbaV0pKGtpbmQgPT09IFwiYWNjZXNzb3JcIiA/IHsgZ2V0OiBkZXNjcmlwdG9yLmdldCwgc2V0OiBkZXNjcmlwdG9yLnNldCB9IDogZGVzY3JpcHRvcltrZXldLCBjb250ZXh0KTtcbiAgICAgIGlmIChraW5kID09PSBcImFjY2Vzc29yXCIpIHtcbiAgICAgICAgICBpZiAocmVzdWx0ID09PSB2b2lkIDApIGNvbnRpbnVlO1xuICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuZ2V0KSkgZGVzY3JpcHRvci5nZXQgPSBfO1xuICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5zZXQpKSBkZXNjcmlwdG9yLnNldCA9IF87XG4gICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmluaXQpKSBpbml0aWFsaXplcnMudW5zaGlmdChfKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKF8gPSBhY2NlcHQocmVzdWx0KSkge1xuICAgICAgICAgIGlmIChraW5kID09PSBcImZpZWxkXCIpIGluaXRpYWxpemVycy51bnNoaWZ0KF8pO1xuICAgICAgICAgIGVsc2UgZGVzY3JpcHRvcltrZXldID0gXztcbiAgICAgIH1cbiAgfVxuICBpZiAodGFyZ2V0KSBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSwgZGVzY3JpcHRvcik7XG4gIGRvbmUgPSB0cnVlO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9fcnVuSW5pdGlhbGl6ZXJzKHRoaXNBcmcsIGluaXRpYWxpemVycywgdmFsdWUpIHtcbiAgdmFyIHVzZVZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaW5pdGlhbGl6ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YWx1ZSA9IHVzZVZhbHVlID8gaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZywgdmFsdWUpIDogaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZyk7XG4gIH1cbiAgcmV0dXJuIHVzZVZhbHVlID8gdmFsdWUgOiB2b2lkIDA7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gX19wcm9wS2V5KHgpIHtcbiAgcmV0dXJuIHR5cGVvZiB4ID09PSBcInN5bWJvbFwiID8geCA6IFwiXCIuY29uY2F0KHgpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9fc2V0RnVuY3Rpb25OYW1lKGYsIG5hbWUsIHByZWZpeCkge1xuICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3ltYm9sXCIpIG5hbWUgPSBuYW1lLmRlc2NyaXB0aW9uID8gXCJbXCIuY29uY2F0KG5hbWUuZGVzY3JpcHRpb24sIFwiXVwiKSA6IFwiXCI7XG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoZiwgXCJuYW1lXCIsIHsgY29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogcHJlZml4ID8gXCJcIi5jb25jYXQocHJlZml4LCBcIiBcIiwgbmFtZSkgOiBuYW1lIH0pO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcbiAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcbiAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XG4gIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxuICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxuICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcbiAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZyA9IE9iamVjdC5jcmVhdGUoKHR5cGVvZiBJdGVyYXRvciA9PT0gXCJmdW5jdGlvblwiID8gSXRlcmF0b3IgOiBPYmplY3QpLnByb3RvdHlwZSk7XG4gIHJldHVybiBnLm5leHQgPSB2ZXJiKDApLCBnW1widGhyb3dcIl0gPSB2ZXJiKDEpLCBnW1wicmV0dXJuXCJdID0gdmVyYigyKSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xuICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cbiAgZnVuY3Rpb24gc3RlcChvcCkge1xuICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xuICAgICAgd2hpbGUgKGcgJiYgKGcgPSAwLCBvcFswXSAmJiAoXyA9IDApKSwgXykgdHJ5IHtcbiAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XG4gICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xuICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcbiAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XG4gICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcbiAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XG4gICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxuICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XG4gICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cbiAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xuICB9XG59XG5cbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG4gIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XG4gICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuICB9XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG59KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICBvW2syXSA9IG1ba107XG59KTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XG4gIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobywgcCkpIF9fY3JlYXRlQmluZGluZyhvLCBtLCBwKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcbiAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcbiAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XG4gIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcbiAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xuICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcbiAgICAgIH1cbiAgfTtcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcbiAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xuICBpZiAoIW0pIHJldHVybiBvO1xuICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcbiAgdHJ5IHtcbiAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xuICB9XG4gIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxuICBmaW5hbGx5IHtcbiAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XG4gICAgICB9XG4gICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cbiAgfVxuICByZXR1cm4gYXI7XG59XG5cbi8qKiBAZGVwcmVjYXRlZCAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xuICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcbiAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcbiAgcmV0dXJuIGFyO1xufVxuXG4vKiogQGRlcHJlY2F0ZWQgKi9cbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcbiAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XG4gIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcbiAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxuICAgICAgICAgIHJba10gPSBhW2pdO1xuICByZXR1cm4gcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20sIHBhY2spIHtcbiAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcbiAgICAgIGlmIChhciB8fCAhKGkgaW4gZnJvbSkpIHtcbiAgICAgICAgICBpZiAoIWFyKSBhciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20sIDAsIGkpO1xuICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcbiAgICAgIH1cbiAgfVxuICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xuICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XG4gIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XG4gIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XG4gIHJldHVybiBpID0gT2JqZWN0LmNyZWF0ZSgodHlwZW9mIEFzeW5jSXRlcmF0b3IgPT09IFwiZnVuY3Rpb25cIiA/IEFzeW5jSXRlcmF0b3IgOiBPYmplY3QpLnByb3RvdHlwZSksIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiwgYXdhaXRSZXR1cm4pLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XG4gIGZ1bmN0aW9uIGF3YWl0UmV0dXJuKGYpIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBQcm9taXNlLnJlc29sdmUodikudGhlbihmLCByZWplY3QpOyB9OyB9XG4gIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpZiAoZ1tuXSkgeyBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyBpZiAoZikgaVtuXSA9IGYoaVtuXSk7IH0gfVxuICBmdW5jdGlvbiByZXN1bWUobiwgdikgeyB0cnkgeyBzdGVwKGdbbl0odikpOyB9IGNhdGNoIChlKSB7IHNldHRsZShxWzBdWzNdLCBlKTsgfSB9XG4gIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxuICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XG4gIGZ1bmN0aW9uIHJlamVjdCh2YWx1ZSkgeyByZXN1bWUoXCJ0aHJvd1wiLCB2YWx1ZSk7IH1cbiAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XG4gIHZhciBpLCBwO1xuICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIsIGZ1bmN0aW9uIChlKSB7IHRocm93IGU7IH0pLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xuICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBmYWxzZSB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XG4gIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XG4gIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XG4gIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcbiAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxuICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xuICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxuICByZXR1cm4gY29va2VkO1xufTtcblxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgXCJkZWZhdWx0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHYgfSk7XG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcbiAgb1tcImRlZmF1bHRcIl0gPSB2O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcbiAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcbiAgdmFyIHJlc3VsdCA9IHt9O1xuICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoayAhPT0gXCJkZWZhdWx0XCIgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwgayk7XG4gIF9fc2V0TW9kdWxlRGVmYXVsdChyZXN1bHQsIG1vZCk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XG4gIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcbiAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRJbihzdGF0ZSwgcmVjZWl2ZXIpIHtcbiAgaWYgKHJlY2VpdmVyID09PSBudWxsIHx8ICh0eXBlb2YgcmVjZWl2ZXIgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlY2VpdmVyICE9PSBcImZ1bmN0aW9uXCIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHVzZSAnaW4nIG9wZXJhdG9yIG9uIG5vbi1vYmplY3RcIik7XG4gIHJldHVybiB0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyID09PSBzdGF0ZSA6IHN0YXRlLmhhcyhyZWNlaXZlcik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZShlbnYsIHZhbHVlLCBhc3luYykge1xuICBpZiAodmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09IHZvaWQgMCkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHZhbHVlICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3QgZXhwZWN0ZWQuXCIpO1xuICAgIHZhciBkaXNwb3NlLCBpbm5lcjtcbiAgICBpZiAoYXN5bmMpIHtcbiAgICAgIGlmICghU3ltYm9sLmFzeW5jRGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0Rpc3Bvc2UgaXMgbm90IGRlZmluZWQuXCIpO1xuICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5hc3luY0Rpc3Bvc2VdO1xuICAgIH1cbiAgICBpZiAoZGlzcG9zZSA9PT0gdm9pZCAwKSB7XG4gICAgICBpZiAoIVN5bWJvbC5kaXNwb3NlKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmRpc3Bvc2UgaXMgbm90IGRlZmluZWQuXCIpO1xuICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5kaXNwb3NlXTtcbiAgICAgIGlmIChhc3luYykgaW5uZXIgPSBkaXNwb3NlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGRpc3Bvc2UgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBub3QgZGlzcG9zYWJsZS5cIik7XG4gICAgaWYgKGlubmVyKSBkaXNwb3NlID0gZnVuY3Rpb24oKSB7IHRyeSB7IGlubmVyLmNhbGwodGhpcyk7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIFByb21pc2UucmVqZWN0KGUpOyB9IH07XG4gICAgZW52LnN0YWNrLnB1c2goeyB2YWx1ZTogdmFsdWUsIGRpc3Bvc2U6IGRpc3Bvc2UsIGFzeW5jOiBhc3luYyB9KTtcbiAgfVxuICBlbHNlIGlmIChhc3luYykge1xuICAgIGVudi5zdGFjay5wdXNoKHsgYXN5bmM6IHRydWUgfSk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG52YXIgX1N1cHByZXNzZWRFcnJvciA9IHR5cGVvZiBTdXBwcmVzc2VkRXJyb3IgPT09IFwiZnVuY3Rpb25cIiA/IFN1cHByZXNzZWRFcnJvciA6IGZ1bmN0aW9uIChlcnJvciwgc3VwcHJlc3NlZCwgbWVzc2FnZSkge1xuICB2YXIgZSA9IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgcmV0dXJuIGUubmFtZSA9IFwiU3VwcHJlc3NlZEVycm9yXCIsIGUuZXJyb3IgPSBlcnJvciwgZS5zdXBwcmVzc2VkID0gc3VwcHJlc3NlZCwgZTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBfX2Rpc3Bvc2VSZXNvdXJjZXMoZW52KSB7XG4gIGZ1bmN0aW9uIGZhaWwoZSkge1xuICAgIGVudi5lcnJvciA9IGVudi5oYXNFcnJvciA/IG5ldyBfU3VwcHJlc3NlZEVycm9yKGUsIGVudi5lcnJvciwgXCJBbiBlcnJvciB3YXMgc3VwcHJlc3NlZCBkdXJpbmcgZGlzcG9zYWwuXCIpIDogZTtcbiAgICBlbnYuaGFzRXJyb3IgPSB0cnVlO1xuICB9XG4gIHZhciByLCBzID0gMDtcbiAgZnVuY3Rpb24gbmV4dCgpIHtcbiAgICB3aGlsZSAociA9IGVudi5zdGFjay5wb3AoKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCFyLmFzeW5jICYmIHMgPT09IDEpIHJldHVybiBzID0gMCwgZW52LnN0YWNrLnB1c2gociksIFByb21pc2UucmVzb2x2ZSgpLnRoZW4obmV4dCk7XG4gICAgICAgIGlmIChyLmRpc3Bvc2UpIHtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gci5kaXNwb3NlLmNhbGwoci52YWx1ZSk7XG4gICAgICAgICAgaWYgKHIuYXN5bmMpIHJldHVybiBzIHw9IDIsIFByb21pc2UucmVzb2x2ZShyZXN1bHQpLnRoZW4obmV4dCwgZnVuY3Rpb24oZSkgeyBmYWlsKGUpOyByZXR1cm4gbmV4dCgpOyB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHMgfD0gMTtcbiAgICAgIH1cbiAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgIGZhaWwoZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChzID09PSAxKSByZXR1cm4gZW52Lmhhc0Vycm9yID8gUHJvbWlzZS5yZWplY3QoZW52LmVycm9yKSA6IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIGlmIChlbnYuaGFzRXJyb3IpIHRocm93IGVudi5lcnJvcjtcbiAgfVxuICByZXR1cm4gbmV4dCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX19yZXdyaXRlUmVsYXRpdmVJbXBvcnRFeHRlbnNpb24ocGF0aCwgcHJlc2VydmVKc3gpIHtcbiAgaWYgKHR5cGVvZiBwYXRoID09PSBcInN0cmluZ1wiICYmIC9eXFwuXFwuP1xcLy8udGVzdChwYXRoKSkge1xuICAgICAgcmV0dXJuIHBhdGgucmVwbGFjZSgvXFwuKHRzeCkkfCgoPzpcXC5kKT8pKCg/OlxcLlteLi9dKz8pPylcXC4oW2NtXT8pdHMkL2ksIGZ1bmN0aW9uIChtLCB0c3gsIGQsIGV4dCwgY20pIHtcbiAgICAgICAgICByZXR1cm4gdHN4ID8gcHJlc2VydmVKc3ggPyBcIi5qc3hcIiA6IFwiLmpzXCIgOiBkICYmICghZXh0IHx8ICFjbSkgPyBtIDogKGQgKyBleHQgKyBcIi5cIiArIGNtLnRvTG93ZXJDYXNlKCkgKyBcImpzXCIpO1xuICAgICAgfSk7XG4gIH1cbiAgcmV0dXJuIHBhdGg7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19leHRlbmRzLFxuICBfX2Fzc2lnbixcbiAgX19yZXN0LFxuICBfX2RlY29yYXRlLFxuICBfX3BhcmFtLFxuICBfX2VzRGVjb3JhdGUsXG4gIF9fcnVuSW5pdGlhbGl6ZXJzLFxuICBfX3Byb3BLZXksXG4gIF9fc2V0RnVuY3Rpb25OYW1lLFxuICBfX21ldGFkYXRhLFxuICBfX2F3YWl0ZXIsXG4gIF9fZ2VuZXJhdG9yLFxuICBfX2NyZWF0ZUJpbmRpbmcsXG4gIF9fZXhwb3J0U3RhcixcbiAgX192YWx1ZXMsXG4gIF9fcmVhZCxcbiAgX19zcHJlYWQsXG4gIF9fc3ByZWFkQXJyYXlzLFxuICBfX3NwcmVhZEFycmF5LFxuICBfX2F3YWl0LFxuICBfX2FzeW5jR2VuZXJhdG9yLFxuICBfX2FzeW5jRGVsZWdhdG9yLFxuICBfX2FzeW5jVmFsdWVzLFxuICBfX21ha2VUZW1wbGF0ZU9iamVjdCxcbiAgX19pbXBvcnRTdGFyLFxuICBfX2ltcG9ydERlZmF1bHQsXG4gIF9fY2xhc3NQcml2YXRlRmllbGRHZXQsXG4gIF9fY2xhc3NQcml2YXRlRmllbGRTZXQsXG4gIF9fY2xhc3NQcml2YXRlRmllbGRJbixcbiAgX19hZGREaXNwb3NhYmxlUmVzb3VyY2UsXG4gIF9fZGlzcG9zZVJlc291cmNlcyxcbiAgX19yZXdyaXRlUmVsYXRpdmVJbXBvcnRFeHRlbnNpb24sXG59O1xuIiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHQvLyBubyBtb2R1bGUuaWQgbmVlZGVkXG5cdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXShtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIi8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSAobW9kdWxlKSA9PiB7XG5cdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuXHRcdCgpID0+IChtb2R1bGVbJ2RlZmF1bHQnXSkgOlxuXHRcdCgpID0+IChtb2R1bGUpO1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCB7IGE6IGdldHRlciB9KTtcblx0cmV0dXJuIGdldHRlcjtcbn07IiwidmFyIGdldFByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mID8gKG9iaikgPT4gKE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopKSA6IChvYmopID0+IChvYmouX19wcm90b19fKTtcbnZhciBsZWFmUHJvdG90eXBlcztcbi8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuLy8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4vLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbi8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuLy8gbW9kZSAmIDE2OiByZXR1cm4gdmFsdWUgd2hlbiBpdCdzIFByb21pc2UtbGlrZVxuLy8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuX193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcblx0aWYobW9kZSAmIDEpIHZhbHVlID0gdGhpcyh2YWx1ZSk7XG5cdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG5cdGlmKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUpIHtcblx0XHRpZigobW9kZSAmIDQpICYmIHZhbHVlLl9fZXNNb2R1bGUpIHJldHVybiB2YWx1ZTtcblx0XHRpZigobW9kZSAmIDE2KSAmJiB0eXBlb2YgdmFsdWUudGhlbiA9PT0gJ2Z1bmN0aW9uJykgcmV0dXJuIHZhbHVlO1xuXHR9XG5cdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG5cdHZhciBkZWYgPSB7fTtcblx0bGVhZlByb3RvdHlwZXMgPSBsZWFmUHJvdG90eXBlcyB8fCBbbnVsbCwgZ2V0UHJvdG8oe30pLCBnZXRQcm90byhbXSksIGdldFByb3RvKGdldFByb3RvKV07XG5cdGZvcih2YXIgY3VycmVudCA9IG1vZGUgJiAyICYmIHZhbHVlOyB0eXBlb2YgY3VycmVudCA9PSAnb2JqZWN0JyAmJiAhfmxlYWZQcm90b3R5cGVzLmluZGV4T2YoY3VycmVudCk7IGN1cnJlbnQgPSBnZXRQcm90byhjdXJyZW50KSkge1xuXHRcdE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGN1cnJlbnQpLmZvckVhY2goKGtleSkgPT4gKGRlZltrZXldID0gKCkgPT4gKHZhbHVlW2tleV0pKSk7XG5cdH1cblx0ZGVmWydkZWZhdWx0J10gPSAoKSA9PiAodmFsdWUpO1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQobnMsIGRlZik7XG5cdHJldHVybiBucztcbn07IiwiLy8gZGVmaW5lIGdldHRlciBmdW5jdGlvbnMgZm9yIGhhcm1vbnkgZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5kID0gKGV4cG9ydHMsIGRlZmluaXRpb24pID0+IHtcblx0Zm9yKHZhciBrZXkgaW4gZGVmaW5pdGlvbikge1xuXHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhkZWZpbml0aW9uLCBrZXkpICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywga2V5KSkge1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIGtleSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGRlZmluaXRpb25ba2V5XSB9KTtcblx0XHR9XG5cdH1cbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5nID0gKGZ1bmN0aW9uKCkge1xuXHRpZiAodHlwZW9mIGdsb2JhbFRoaXMgPT09ICdvYmplY3QnKSByZXR1cm4gZ2xvYmFsVGhpcztcblx0dHJ5IHtcblx0XHRyZXR1cm4gdGhpcyB8fCBuZXcgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JykgcmV0dXJuIHdpbmRvdztcblx0fVxufSkoKTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gKGV4cG9ydHMpID0+IHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiaW1wb3J0ICogYXMgbG9hZGVycyBmcm9tIFwiQGx0cy9sb2FkZXJzL2xlZ2FjeS9sZWdhY3ktZ2xURkZpbGVMb2FkZXJcIjtcclxuZXhwb3J0IHsgbG9hZGVycyB9O1xyXG5leHBvcnQgZGVmYXVsdCBsb2FkZXJzO1xyXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0= \ No newline at end of file diff --git a/libs/babylonjs/7.35.0/babylon.glTFFileLoader.min.js b/libs/babylonjs/7.35.0/babylon.glTFFileLoader.min.js new file mode 100644 index 00000000..5005aaed --- /dev/null +++ b/libs/babylonjs/7.35.0/babylon.glTFFileLoader.min.js @@ -0,0 +1,2 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("babylonjs")):"function"==typeof define&&define.amd?define("babylonjs-loaders",["babylonjs"],t):"object"==typeof exports?exports["babylonjs-loaders"]=t(require("babylonjs")):e.LOADERS=t(e.BABYLON)}("undefined"!=typeof self?self:"undefined"!=typeof global?global:this,(e=>(()=>{"use strict";var t,n,r={597:t=>{t.exports=e}},o={};function a(e){var t=o[e];if(void 0!==t)return t.exports;var n=o[e]={exports:{}};return r[e](n,n.exports,a),n.exports}n=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,a.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var o=Object.create(null);a.r(o);var i={};t=t||[null,n({}),n([]),n(n)];for(var s=2&r&&e;"object"==typeof s&&!~t.indexOf(s);s=n(s))Object.getOwnPropertyNames(s).forEach((t=>i[t]=()=>e[t]));return i.default=()=>e,a.d(o,i),o},a.d=(e,t)=>{for(var n in t)a.o(t,n)&&!a.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var i={};a.d(i,{default:()=>fn});var s={};a.r(s),a.d(s,{GLTFValidation:()=>O});var l={};a.r(l),a.d(l,{GLTFFileLoader:()=>N,GLTFLoaderAnimationStartMode:()=>x,GLTFLoaderCoordinateSystemMode:()=>T,GLTFLoaderState:()=>E});var c={};a.r(c),a.d(c,{EBlendingFunction:()=>k,EComponentType:()=>S,ECullingType:()=>D,EParameterType:()=>I,EShaderType:()=>R,ETextureFilterType:()=>F,ETextureFormat:()=>B,ETextureWrapMode:()=>P,GLTFBinaryExtension:()=>fe,GLTFLoader:()=>ue,GLTFLoaderBase:()=>ce,GLTFLoaderExtension:()=>de,GLTFMaterialsCommonExtension:()=>he,GLTFUtils:()=>H});var u={};a.r(u),a.d(u,{EXT_lights_image_based:()=>Le,EXT_mesh_gpu_instancing:()=>Se,EXT_meshopt_compression:()=>Ie,EXT_texture_avif:()=>De,EXT_texture_webp:()=>Fe,ExtrasAsMetadata:()=>sn,KHR_animation_pointer:()=>Vt,KHR_draco_mesh_compression:()=>Ge,KHR_interactivity:()=>nn,KHR_lights:()=>Ue,KHR_materials_anisotropy:()=>Qe,KHR_materials_clearcoat:()=>Ye,KHR_materials_diffuse_transmission:()=>ft,KHR_materials_dispersion:()=>_t,KHR_materials_emissive_strength:()=>$e,KHR_materials_ior:()=>at,KHR_materials_iridescence:()=>ze,KHR_materials_pbrSpecularGlossiness:()=>Ke,KHR_materials_sheen:()=>tt,KHR_materials_specular:()=>rt,KHR_materials_transmission:()=>ut,KHR_materials_unlit:()=>qe,KHR_materials_variants:()=>st,KHR_materials_volume:()=>pt,KHR_mesh_quantization:()=>vt,KHR_node_visibility:()=>on,KHR_texture_basisu:()=>At,KHR_texture_transform:()=>Tt,KHR_xmp_json_ld:()=>Et,MSFT_audio_emitter:()=>Ht,MSFT_lod:()=>jt,MSFT_minecraftMesh:()=>Wt,MSFT_sRGBFactors:()=>Xt});var d={};a.r(d);var f={};a.r(f),a.d(f,{ArrayItem:()=>Me,EXT_lights_image_based:()=>Le,EXT_mesh_gpu_instancing:()=>Se,EXT_meshopt_compression:()=>Ie,EXT_texture_avif:()=>De,EXT_texture_webp:()=>Fe,ExtrasAsMetadata:()=>sn,GLTFFileLoader:()=>N,GLTFLoader:()=>Ce,KHR_animation_pointer:()=>Vt,KHR_draco_mesh_compression:()=>Ge,KHR_interactivity:()=>nn,KHR_lights:()=>Ue,KHR_materials_anisotropy:()=>Qe,KHR_materials_clearcoat:()=>Ye,KHR_materials_diffuse_transmission:()=>ft,KHR_materials_dispersion:()=>_t,KHR_materials_emissive_strength:()=>$e,KHR_materials_ior:()=>at,KHR_materials_iridescence:()=>ze,KHR_materials_pbrSpecularGlossiness:()=>Ke,KHR_materials_sheen:()=>tt,KHR_materials_specular:()=>rt,KHR_materials_transmission:()=>ut,KHR_materials_unlit:()=>qe,KHR_materials_variants:()=>st,KHR_materials_volume:()=>pt,KHR_mesh_quantization:()=>vt,KHR_node_visibility:()=>on,KHR_texture_basisu:()=>At,KHR_texture_transform:()=>Tt,KHR_xmp_json_ld:()=>Et,MSFT_audio_emitter:()=>Ht,MSFT_lod:()=>jt,MSFT_minecraftMesh:()=>Wt,MSFT_sRGBFactors:()=>Xt,registerGLTFExtension:()=>xe,registeredGLTFExtensions:()=>Te,unregisterGLTFExtension:()=>Ee});var h={};a.r(h),a.d(h,{GLTF1:()=>c,GLTF2:()=>f,GLTFFileLoader:()=>N,GLTFLoaderAnimationStartMode:()=>x,GLTFLoaderCoordinateSystemMode:()=>T,GLTFLoaderState:()=>E,GLTFValidation:()=>O});var p=function(e,t){return p=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},p(e,t)};function m(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}p(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var _=function(){return _=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])||6!==s[0]&&2!==s[0])){a=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]=e.byteLength)throw new RangeError("Offset is out of range.");if(t+n>e.byteLength)throw new RangeError("Length is out of range.");return Promise.resolve(new Uint8Array(e.buffer,e.byteOffset+t,n))}catch(e){return Promise.reject(e)}}(t,e,n)},byteLength:t.byteLength})).then((function(e){r(e)}),o?function(e){return o(void 0,e)}:void 0)},t.prototype.importMeshAsync=function(e,t,n,r,o,a){var i=this;return Promise.resolve().then((function(){return i.onParsedObservable.notifyObservers(n),i.onParsedObservable.clear(),i._log("Loading ".concat(a||"")),i._loader=i._getLoader(n),i._loader.importMeshAsync(e,t,null,n,r,o,a)}))},t.prototype.loadAsync=function(e,t,n,r,o){var a=this;return Promise.resolve().then((function(){return a.onParsedObservable.notifyObservers(t),a.onParsedObservable.clear(),a._log("Loading ".concat(o||"")),a._loader=a._getLoader(t),a._loader.loadAsync(e,t,n,r,o)}))},t.prototype.loadAssetContainerAsync=function(e,t,n,r,o){var a=this;return Promise.resolve().then((function(){a.onParsedObservable.notifyObservers(t),a.onParsedObservable.clear(),a._log("Loading ".concat(o||"")),a._loader=a._getLoader(t);var i=new b.AssetContainer(e),s=[];a.onMaterialLoadedObservable.add((function(e){s.push(e)}));var l=[];a.onTextureLoadedObservable.add((function(e){l.push(e)}));var c=[];a.onCameraLoadedObservable.add((function(e){c.push(e)}));var u=[];return a.onMeshLoadedObservable.add((function(e){e.morphTargetManager&&u.push(e.morphTargetManager)})),a._loader.importMeshAsync(null,e,i,t,n,r,o).then((function(e){return Array.prototype.push.apply(i.geometries,e.geometries),Array.prototype.push.apply(i.meshes,e.meshes),Array.prototype.push.apply(i.particleSystems,e.particleSystems),Array.prototype.push.apply(i.skeletons,e.skeletons),Array.prototype.push.apply(i.animationGroups,e.animationGroups),Array.prototype.push.apply(i.materials,s),Array.prototype.push.apply(i.textures,l),Array.prototype.push.apply(i.lights,e.lights),Array.prototype.push.apply(i.transformNodes,e.transformNodes),Array.prototype.push.apply(i.cameras,c),Array.prototype.push.apply(i.morphTargetManagers,u),i}))}))},t.prototype.canDirectLoad=function(e){return function(e){return-1!==e.indexOf("asset")&&-1!==e.indexOf("version")||e.startsWith("data:base64,"+M)||e.startsWith("data:;base64,"+M)||e.startsWith("data:application/octet-stream;base64,"+M)||e.startsWith("data:model/gltf-binary;base64,"+M)}(e)},t.prototype.directLoad=function(e,t){if(t.startsWith("base64,"+M)||t.startsWith(";base64,"+M)||t.startsWith("application/octet-stream;base64,"+M)||t.startsWith("model/gltf-binary;base64,"+M)){var n=(0,b.DecodeBase64UrlToBinary)(t);return this._validate(e,new Uint8Array(n,0,n.byteLength)),this._unpackBinaryAsync(new b.DataReader({readAsync:function(e,t){return L(n,e,t)},byteLength:n.byteLength}))}return this._validate(e,t),Promise.resolve({json:this._parseJson(t)})},t.prototype.createPlugin=function(e){return new t(e[C])},Object.defineProperty(t.prototype,"loaderState",{get:function(){return this._state},enumerable:!1,configurable:!0}),t.prototype.whenCompleteAsync=function(){var e=this;return new Promise((function(t,n){e.onCompleteObservable.addOnce((function(){t()})),e.onErrorObservable.addOnce((function(e){n(e)}))}))},t.prototype._setState=function(e){this._state!==e&&(this._state=e,this.onLoaderStateChangedObservable.notifyObservers(this._state),this._log(E[this._state]))},t.prototype._loadFile=function(e,t,n,r,o,a){var i=this,s=e._loadFile(t,n,(function(e){i._onProgress(e,s)}),!0,r,o,a);return s.onCompleteObservable.add((function(){s._lengthComputable=!0,s._total=s._loaded})),this._requests.push(s),s},t.prototype._onProgress=function(e,t){if(this._progressCallback){t._lengthComputable=e.lengthComputable,t._loaded=e.loaded,t._total=e.total;for(var n=!0,r=0,o=0,a=0,i=this._requests;a0)throw new Error("Incompatible minimum version: "+n.minVersion)}var a={1:t._CreateGLTF1Loader,2:t._CreateGLTF2Loader}[r.major];if(!a)throw new Error("Unsupported version: "+n.version);return a(this)},t.prototype._parseJson=function(e){this._startPerformanceCounter("Parse JSON"),this._log("JSON length: ".concat(e.length));var t=JSON.parse(e);return this._endPerformanceCounter("Parse JSON"),t},t.prototype._unpackBinaryAsync=function(e){var t=this;return this._startPerformanceCounter("Unpack Binary"),e.loadAsync(20).then((function(){var n=e.readUint32();if(1179937895!==n)throw new b.RuntimeError("Unexpected magic: "+n,b.ErrorCodes.GLTFLoaderUnexpectedMagicError);var r=e.readUint32();t.loggingEnabled&&t._log("Binary version: ".concat(r));var o,a=e.readUint32();switch(t.useRangeRequests||a===e.buffer.byteLength||b.Logger.Warn("Length in header does not match actual data length: ".concat(a," != ").concat(e.buffer.byteLength)),r){case 1:o=t._unpackBinaryV1Async(e,a);break;case 2:o=t._unpackBinaryV2Async(e,a);break;default:throw new Error("Unsupported version: "+r)}return t._endPerformanceCounter("Unpack Binary"),o}))},t.prototype._unpackBinaryV1Async=function(e,t){var n=e.readUint32(),r=e.readUint32();if(0!==r)throw new Error("Unexpected content format: ".concat(r));var o=t-e.byteOffset,a={json:this._parseJson(e.readString(n)),bin:null};if(0!==o){var i=e.byteOffset;a.bin={readAsync:function(t,n){return e.buffer.readAsync(i+t,n)},byteLength:o}}return Promise.resolve(a)},t.prototype._unpackBinaryV2Async=function(e,t){var n=this,r=1313821514,o=e.readUint32();if(e.readUint32()!==r)throw new Error("First chunk format is not JSON");return e.byteOffset+o===t?e.loadAsync(o).then((function(){return{json:n._parseJson(e.readString(o)),bin:null}})):e.loadAsync(o+8).then((function(){var a={json:n._parseJson(e.readString(o)),bin:null},i=function(){var n=e.readUint32();switch(e.readUint32()){case r:throw new Error("Unexpected JSON chunk");case 5130562:var o=e.byteOffset;a.bin={readAsync:function(t,n){return e.buffer.readAsync(o+t,n)},byteLength:n},e.skipBytes(n);break;default:e.skipBytes(n)}return e.byteOffset!==t?e.loadAsync(8).then(i):Promise.resolve(a)};return i()}))},t._parseVersion=function(e){if("1.0"===e||"1.0.1"===e)return{major:1,minor:0};var t=(e+"").match(/^(\d+)\.(\d+)/);return t?{major:parseInt(t[1]),minor:parseInt(t[2])}:null},t._compareVersion=function(e,t){return e.major>t.major?1:e.majort.minor?1:e.minora.byteLength)throw new Error("Buffer access is out of range");var i=a.buffer;switch(n+=a.byteOffset,o){case S.BYTE:return new Int8Array(i,n,r);case S.UNSIGNED_BYTE:return new Uint8Array(i,n,r);case S.SHORT:return new Int16Array(i,n,r);case S.UNSIGNED_SHORT:return new Uint16Array(i,n,r);default:return new Float32Array(i,n,r)}},e.GetBufferFromAccessor=function(t,n){var r=t.bufferViews[n.bufferView],o=n.count*e.GetByteStrideFromType(n);return e.GetBufferFromBufferView(t,r,n.byteOffset,o,n.componentType)},e.DecodeBufferToText=function(e){for(var t="",n=e.byteLength,r=0;r=this._maxPos},e}(),j=["MODEL","VIEW","PROJECTION","MODELVIEW","MODELVIEWPROJECTION","JOINTMATRIX"],q=["world","view","projection","worldView","worldViewProjection","mBones"],W=["translation","rotation","scale"],Y=["position","rotationQuaternion","scaling"],X=function(e,t,n){for(var r in e){var o=e[r];n[t][r]=o}},z=function(e){if(e)for(var t=0;t1?(a=new b.MultiMaterial("multimat"+r,e.scene)).subMaterials=i:a=new b.StandardMaterial("multimat"+r,e.scene),1===i.length&&(a=i[0]),a._parentContainer=e.assetContainer,o.material||(o.material=a),new b.Geometry(r,e.scene,s,!1,o),o.computeWorldMatrix(!0),e.scene._blockEntityCollection=!1,o.subMeshes=[];var w=0;for(f=0;f0&&-1===e.importMeshesNames.indexOf(t.name||""))return null;if(t.skin){if(t.meshes){var o=e.skins[t.skin];(a=ne(e,t,t.meshes,n,t.babylonNode)).skeleton=e.scene.getLastSkeletonById(t.skin),null===a.skeleton&&(a.skeleton=function(e,t,n,r){if(r||(r=new b.Skeleton(t.name||"","",e.scene)),!t.babylonSkeleton)return r;var o=[],a=[];!function(e,t,n,r){for(var o in e.nodes){var a=e.nodes[o],i=o;if(a.jointName&&!te(n,a.jointName)){var s=Q(a),l=new b.Bone(a.name||"",t,null,s);l.id=i,r.push({bone:l,node:a,id:i})}}for(var c=0;c0&&(d=$(o,l))&&-1===a.indexOf(d)&&a.push(d),new b.Bone(s.jointName||"",r,d,y).id=l}}else b.Tools.Warn("Joint named "+t.jointNames[i]+" does not exist")}var v=r.bones;for(r.bones=[],i=0;i ").concat(E[E.READY]),a="".concat(E[E.LOADING]," => ").concat(E[E.COMPLETE]),this._parent._startPerformanceCounter(o),this._parent._startPerformanceCounter(a),this._parent._setState(E.LOADING),this._extensionsOnLoading(),i=new Array,s=this._babylonScene.blockMaterialDirtyMechanism,this._babylonScene.blockMaterialDirtyMechanism=!0,this.parent.loadOnlyMaterials||(n?i.push(this.loadSceneAsync("/nodes",{nodes:n,index:-1})):(null!=this._gltf.scene||this._gltf.scenes&&this._gltf.scenes[0])&&(l=Me.Get("/scene",this._gltf.scenes,this._gltf.scene||0),i.push(this.loadSceneAsync("/scenes/".concat(l.index),l)))),!this.parent.skipMaterials&&this.parent.loadAllMaterials&&this._gltf.materials)for(c=0;ce.bin.byteLength)&&b.Logger.Warn("Binary buffer length (".concat(n.byteLength,") from JSON does not match chunk length (").concat(e.bin.byteLength,")")),this._bin=e.bin}else b.Logger.Warn("Unexpected BIN chunk")}},e.prototype._setupData=function(){if(Me.Assign(this._gltf.accessors),Me.Assign(this._gltf.animations),Me.Assign(this._gltf.buffers),Me.Assign(this._gltf.bufferViews),Me.Assign(this._gltf.cameras),Me.Assign(this._gltf.images),Me.Assign(this._gltf.materials),Me.Assign(this._gltf.meshes),Me.Assign(this._gltf.nodes),Me.Assign(this._gltf.samplers),Me.Assign(this._gltf.scenes),Me.Assign(this._gltf.skins),Me.Assign(this._gltf.textures),this._gltf.nodes){for(var e={},t=0,n=this._gltf.nodes;t=(i=n[t[0]]).length)return l;s=i[c];for(var u=1;u=(i=n[t[u]]).length||s!==i[c])return l;l=s}},e.prototype._loadBone=function(e,t,n,r){e._isJoint=!0;var o=r[e.index];if(o)return o;var a=null;e.index!==t.skeleton&&(e.parent&&-1!==e.parent.index?a=this._loadBone(e.parent,t,n,r):void 0!==t.skeleton&&b.Logger.Warn("/skins/".concat(t.index,"/skeleton: Skeleton node is not a common root")));var i=t.joints.indexOf(e.index);return o=new b.Bone(e.name||"joint".concat(e.index),n,a,this._getNodeMatrix(e),null,null,i),r[e.index]=o,this._postSceneLoadActions.push((function(){o.linkTransformNode(e._babylonTransformNode)})),o},e.prototype._loadSkinInverseBindMatricesDataAsync=function(e,t){if(null==t.inverseBindMatrices)return Promise.resolve(null);var n=Me.Get("".concat(e,"/inverseBindMatrices"),this._gltf.accessors,t.inverseBindMatrices);return this._loadFloatAccessorAsync("/accessors/".concat(n.index),n)},e.prototype._updateBoneMatrices=function(e,t){for(var n=0,r=e.bones;n0){var g="".concat(n.name||"animation".concat(n.index),"_channel").concat(r.index,"_").concat(t);d.buildAnimations(l,g,i,m,(function(e,n){++t,a(e,n)}))}}}))},e.prototype._loadAnimationSamplerAsync=function(e,t){if(t._data)return t._data;var n=t.interpolation||"LINEAR";switch(n){case"STEP":case"LINEAR":case"CUBICSPLINE":break;default:throw new Error("".concat(e,"/interpolation: Invalid value (").concat(t.interpolation,")"))}var r=Me.Get("".concat(e,"/input"),this._gltf.accessors,t.input),o=Me.Get("".concat(e,"/output"),this._gltf.accessors,t.output);return t._data=Promise.all([this._loadFloatAccessorAsync("/accessors/".concat(r.index),r),this._loadFloatAccessorAsync("/accessors/".concat(o.index),o)]).then((function(e){var t=e[0],r=e[1];return{input:t,interpolation:n,output:r}})),t._data},e.prototype.loadBufferAsync=function(e,t,n,r){var o=this._extensionsLoadBufferAsync(e,t,n,r);if(o)return o;if(!t._data)if(t.uri)t._data=this.loadUriAsync("".concat(e,"/uri"),t,t.uri);else{if(!this._bin)throw new Error("".concat(e,": Uri is missing or the binary glTF is missing its binary chunk"));t._data=this._bin.readAsync(0,t.byteLength)}return t._data.then((function(t){try{return new Uint8Array(t.buffer,t.byteOffset+n,r)}catch(t){throw new Error("".concat(e,": ").concat(t.message))}}))},e.prototype.loadBufferViewAsync=function(e,t){var n=this._extensionsLoadBufferViewAsync(e,t);if(n)return n;if(t._data)return t._data;var r=Me.Get("".concat(e,"/buffer"),this._gltf.buffers,t.buffer);return t._data=this.loadBufferAsync("/buffers/".concat(r.index),r,t.byteOffset||0,t.byteLength),t._data},e.prototype._loadAccessorAsync=function(t,n,r){var o=this;if(n._data)return n._data;var a=e._GetNumComponents(t,n.type),i=a*b.VertexBuffer.GetTypeByteLength(n.componentType),s=a*n.count;if(null==n.bufferView)n._data=Promise.resolve(new r(s));else{var l=Me.Get("".concat(t,"/bufferView"),this._gltf.bufferViews,n.bufferView);n._data=this.loadBufferViewAsync("/bufferViews/".concat(l.index),l).then((function(o){if(5126!==n.componentType||n.normalized||l.byteStride&&l.byteStride!==i){var c=new r(s);return b.VertexBuffer.ForEach(o,n.byteOffset||0,l.byteStride||i,a,n.componentType,c.length,n.normalized||!1,(function(e,t){c[t]=e})),c}return e._GetTypedArray(t,n.componentType,o,n.byteOffset,s)}))}if(n.sparse){var c=n.sparse;n._data=n._data.then((function(s){var l=s,u=Me.Get("".concat(t,"/sparse/indices/bufferView"),o._gltf.bufferViews,c.indices.bufferView),d=Me.Get("".concat(t,"/sparse/values/bufferView"),o._gltf.bufferViews,c.values.bufferView);return Promise.all([o.loadBufferViewAsync("/bufferViews/".concat(u.index),u),o.loadBufferViewAsync("/bufferViews/".concat(d.index),d)]).then((function(o){var s,u=o[0],d=o[1],f=e._GetTypedArray("".concat(t,"/sparse/indices"),c.indices.componentType,u,c.indices.byteOffset,c.count),h=a*c.count;if(5126!==n.componentType||n.normalized){var p=e._GetTypedArray("".concat(t,"/sparse/values"),n.componentType,d,c.values.byteOffset,h);s=new r(h),b.VertexBuffer.ForEach(p,0,i,a,n.componentType,s.length,n.normalized||!1,(function(e,t){s[t]=e}))}else s=e._GetTypedArray("".concat(t,"/sparse/values"),n.componentType,d,c.values.byteOffset,h);for(var m=0,_=0;_=6)throw new Error("".concat(t,"/texCoord: Invalid value (").concat(n.texCoord,")"));var i=Me.Get("".concat(t,"/index"),this._gltf.textures,n.index);i._textureInfo=n;var s=this._loadTextureAsync("/textures/".concat(n.index),i,(function(a){a.coordinatesIndex=n.texCoord||0,e.AddPointerMetadata(a,t),o._parent.onTextureLoadedObservable.notifyObservers(a),r(a)}));return this.logClose(),s},e.prototype._loadTextureAsync=function(t,n,r){void 0===r&&(r=function(){});var o=this._extensionsLoadTextureAsync(t,n,r);if(o)return o;this.logOpen("".concat(t," ").concat(n.name||""));var a=null==n.sampler?e.DefaultSampler:Me.Get("".concat(t,"/sampler"),this._gltf.samplers,n.sampler),i=Me.Get("".concat(t,"/source"),this._gltf.images,n.source),s=this._createTextureAsync(t,a,i,r,void 0,!n._textureInfo.nonColorData);return this.logClose(),s},e.prototype._createTextureAsync=function(e,t,n,r,o,a){var i=this;void 0===r&&(r=function(){});var s=this._loadSampler("/samplers/".concat(t.index),t),l=new Array,c=new b.Deferred;this._babylonScene._blockEntityCollection=!!this._assetContainer;var u={noMipmap:s.noMipMaps,invertY:!1,samplingMode:s.samplingMode,onLoad:function(){i._disposed||c.resolve()},onError:function(t,n){i._disposed||c.reject(new Error("".concat(e,": ").concat(n&&n.message?n.message:t||"Failed to load texture")))},mimeType:n.mimeType,loaderOptions:o,useSRGBBuffer:!!a&&this._parent.useSRGBBuffers},d=new b.Texture(null,this._babylonScene,u);return d._parentContainer=this._assetContainer,this._babylonScene._blockEntityCollection=!1,l.push(c.promise),l.push(this.loadImageAsync("/images/".concat(n.index),n).then((function(e){var t=n.uri||"".concat(i._fileName,"#image").concat(n.index),r="data:".concat(i._uniqueRootUrl).concat(t);d.updateURL(r,e);var o=d.getInternalTexture();o&&(o.label=n.name)}))),d.wrapU=s.wrapU,d.wrapV=s.wrapV,r(d),this._parent.useGltfTextureNames&&(d.name=n.name||n.uri||"image".concat(n.index)),Promise.all(l).then((function(){return d}))},e.prototype._loadSampler=function(t,n){return n._data||(n._data={noMipMaps:9728===n.minFilter||9729===n.minFilter,samplingMode:e._GetTextureSamplingMode(t,n),wrapU:e._GetTextureWrapMode("".concat(t,"/wrapS"),n.wrapS),wrapV:e._GetTextureWrapMode("".concat(t,"/wrapT"),n.wrapT)}),n._data},e.prototype.loadImageAsync=function(e,t){if(!t._data){if(this.logOpen("".concat(e," ").concat(t.name||"")),t.uri)t._data=this.loadUriAsync("".concat(e,"/uri"),t,t.uri);else{var n=Me.Get("".concat(e,"/bufferView"),this._gltf.bufferViews,t.bufferView);t._data=this.loadBufferViewAsync("/bufferViews/".concat(n.index),n)}this.logClose()}return t._data},e.prototype.loadUriAsync=function(t,n,r){var o=this,a=this._extensionsLoadUriAsync(t,n,r);if(a)return a;if(!e._ValidateUri(r))throw new Error("".concat(t,": '").concat(r,"' is invalid"));if((0,b.IsBase64DataUrl)(r)){var i=new Uint8Array((0,b.DecodeBase64UrlToBinary)(r));return this.log("".concat(t,": Decoded ").concat(r.substring(0,64),"... (").concat(i.length," bytes)")),Promise.resolve(i)}return this.log("".concat(t,": Loading ").concat(r)),this._parent.preprocessUrlAsync(this._rootUrl+r).then((function(e){return new Promise((function(n,a){o._parent._loadFile(o._babylonScene,e,(function(e){o._disposed||(o.log("".concat(t,": Loaded ").concat(r," (").concat(e.byteLength," bytes)")),n(new Uint8Array(e)))}),!0,(function(e){a(new b.LoadFileError("".concat(t,": Failed to load '").concat(r,"'").concat(e?": "+e.status+" "+e.statusText:""),e))}))}))}))},e.AddPointerMetadata=function(e,t){e.metadata=e.metadata||{};var n=e._internalMetadata=e._internalMetadata||{},r=n.gltf=n.gltf||{};(r.pointers=r.pointers||[]).push(t)},e._GetTextureWrapMode=function(e,t){switch(t=null==t?10497:t){case 33071:return b.Texture.CLAMP_ADDRESSMODE;case 33648:return b.Texture.MIRROR_ADDRESSMODE;case 10497:return b.Texture.WRAP_ADDRESSMODE;default:return b.Logger.Warn("".concat(e,": Invalid value (").concat(t,")")),b.Texture.WRAP_ADDRESSMODE}},e._GetTextureSamplingMode=function(e,t){var n=null==t.magFilter?9729:t.magFilter,r=null==t.minFilter?9987:t.minFilter;if(9729===n)switch(r){case 9728:return b.Texture.LINEAR_NEAREST;case 9729:return b.Texture.LINEAR_LINEAR;case 9984:return b.Texture.LINEAR_NEAREST_MIPNEAREST;case 9985:return b.Texture.LINEAR_LINEAR_MIPNEAREST;case 9986:return b.Texture.LINEAR_NEAREST_MIPLINEAR;case 9987:return b.Texture.LINEAR_LINEAR_MIPLINEAR;default:return b.Logger.Warn("".concat(e,"/minFilter: Invalid value (").concat(r,")")),b.Texture.LINEAR_LINEAR_MIPLINEAR}else switch(9728!==n&&b.Logger.Warn("".concat(e,"/magFilter: Invalid value (").concat(n,")")),r){case 9728:return b.Texture.NEAREST_NEAREST;case 9729:return b.Texture.NEAREST_LINEAR;case 9984:return b.Texture.NEAREST_NEAREST_MIPNEAREST;case 9985:return b.Texture.NEAREST_LINEAR_MIPNEAREST;case 9986:return b.Texture.NEAREST_NEAREST_MIPLINEAR;case 9987:return b.Texture.NEAREST_LINEAR_MIPLINEAR;default:return b.Logger.Warn("".concat(e,"/minFilter: Invalid value (").concat(r,")")),b.Texture.NEAREST_NEAREST_MIPNEAREST}},e._GetTypedArrayConstructor=function(e,t){switch(t){case 5120:return Int8Array;case 5121:return Uint8Array;case 5122:return Int16Array;case 5123:return Uint16Array;case 5125:return Uint32Array;case 5126:return Float32Array;default:throw new Error("".concat(e,": Invalid component type ").concat(t))}},e._GetTypedArray=function(t,n,r,o,a){var i=r.buffer;o=r.byteOffset+(o||0);var s=e._GetTypedArrayConstructor("".concat(t,"/componentType"),n),l=b.VertexBuffer.GetTypeByteLength(n);return o%l!=0?(b.Logger.Warn("".concat(t,": Copying buffer as byte offset (").concat(o,") is not a multiple of component type byte length (").concat(l,")")),new s(i.slice(o,o+a*l),0)):new s(i,o,a)},e._GetNumComponents=function(e,t){switch(t){case"SCALAR":return 1;case"VEC2":return 2;case"VEC3":return 3;case"VEC4":case"MAT2":return 4;case"MAT3":return 9;case"MAT4":return 16}throw new Error("".concat(e,": Invalid type (").concat(t,")"))},e._ValidateUri=function(e){return b.Tools.IsBase64(e)||-1===e.indexOf("..")},e._GetDrawMode=function(e,t){switch(null==t&&(t=4),t){case 0:return b.Material.PointListDrawMode;case 1:return b.Material.LineListDrawMode;case 2:return b.Material.LineLoopDrawMode;case 3:return b.Material.LineStripDrawMode;case 4:return b.Material.TriangleFillMode;case 5:return b.Material.TriangleStripDrawMode;case 6:return b.Material.TriangleFanDrawMode}throw new Error("".concat(e,": Invalid mesh primitive mode (").concat(t,")"))},e.prototype._compileMaterialsAsync=function(){var e=this;this._parent._startPerformanceCounter("Compile materials");var t=new Array;if(this._gltf.materials)for(var n=0,r=this._gltf.materials;n=0;a--)if(o.push(Me.Get("".concat(e,"/ids/").concat(r[a]),n,r[a])),o.length===this.maxLODsToLoad)return o;return o.push(t),o},e.prototype._disposeTransformNode=function(e){var t=this,n=[],r=e.material;r&&n.push(r);for(var o=0,a=e.getChildMeshes();o0){var n=e.metadata=e.metadata||{};(n.gltf=n.gltf||{}).extras=t.extras}},e.prototype.dispose=function(){this._loader=null},e.prototype.loadNodeAsync=function(e,t,n){var r=this;return this._loader.loadNodeAsync(e,t,(function(e){r._assignExtras(e,t),n(e)}))},e.prototype.loadCameraAsync=function(e,t,n){var r=this;return this._loader.loadCameraAsync(e,t,(function(e){r._assignExtras(e,t),n(e)}))},e.prototype.createMaterial=function(e,t,n){var r=this._loader.createMaterial(e,t,n);return this._assignExtras(r,t),r},e}();Ee(an),xe(an,!1,(function(e){return new sn(e)}));var ln=void 0!==a.g?a.g:"undefined"!=typeof window?window:void 0;if(void 0!==ln){ln.BABYLON=ln.BABYLON||{};var cn=ln.BABYLON;cn.GLTF2=cn.GLTF2||{},cn.GLTF2.Loader=cn.GLTF2.Loader||{},cn.GLTF2.Loader.Extensions=cn.GLTF2.Loader.Extensions||{};var un=[];for(var dn in u)cn.GLTF2.Loader.Extensions[dn]=u[dn],un.push(dn);for(var dn in d)cn.GLTF2.Loader[dn]=d[dn],un.push(dn);for(var dn in f)un.indexOf(dn)>-1||(cn.GLTF2[dn]=f[dn])}const fn=h;return i.default})())); +//# sourceMappingURL=babylon.glTFFileLoader.min.js.map \ No newline at end of file diff --git a/libs/babylonjs/7.35.0/babylon.inspector.bundle.js b/libs/babylonjs/7.35.0/babylon.inspector.bundle.js new file mode 100644 index 00000000..68b2533b --- /dev/null +++ b/libs/babylonjs/7.35.0/babylon.inspector.bundle.js @@ -0,0 +1,3 @@ +/*! For license information please see babylon.inspector.bundle.js.LICENSE.txt */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("babylonjs"),require("babylonjs-materials"),require("babylonjs"),require("babylonjs-gui"),require("babylonjs-gui-editor"),require("babylonjs-loaders"),require("babylonjs-serializers")):"function"==typeof define&&define.amd?define("babylonjs-inspector",["babylonjs","babylonjs-materials","babylonjs","babylonjs-gui","babylonjs-gui-editor","babylonjs-loaders","babylonjs-serializers"],t):"object"==typeof exports?exports["babylonjs-inspector"]=t(require("babylonjs"),require("babylonjs-materials"),require("babylonjs"),require("babylonjs-gui"),require("babylonjs-gui-editor"),require("babylonjs-loaders"),require("babylonjs-serializers")):e.INSPECTOR=t(e.BABYLON,e.BABYLON,e.BABYLON.Debug,e.BABYLON.GUI,e.BABYLON,e.BABYLON,e.BABYLON)}("undefined"!=typeof self?self:"undefined"!=typeof global?global:this,((e,t,s,r,n,o,a)=>(()=>{var i={729:(e,t,s)=>{"use strict";s.d(t,{A:()=>h});var r=s(3234),n=s.n(r),o=s(7474),a=s.n(o),i=s(1721),l=s.n(i),p=new URL(s(4149),s.b),c=a()(n()),d=l()(p);c.push([e.id,`#inspector-host{position:absolute;right:0px;top:0px;bottom:0px}#__resizable_base__{display:none}#actionTabs{background:#333;height:100%;margin:0;padding:0;display:grid;grid-template-rows:auto 1fr;font:14px "Arial";overflow:hidden}#actionTabs .hoverIcon:hover{opacity:.8}#actionTabs #header{height:30px;font-size:16px;color:#fff;background:#222;grid-row:1;text-align:center;display:grid;grid-template-columns:30px 1fr 50px;user-select:none}#actionTabs #header #logo{grid-column:1;width:24px;height:24px;display:flex;align-self:center;justify-self:center}#actionTabs #header #back{grid-column:1;display:grid;align-self:center;justify-self:center;cursor:pointer}#actionTabs #header #title{grid-column:2;display:grid;align-items:center;text-align:center}#actionTabs #header #commands{grid-column:3;display:grid;align-items:center;grid-template-columns:1fr 1fr}#actionTabs #header #commands .expand{grid-column:1;display:grid;align-items:center;justify-items:center;cursor:pointer}#actionTabs #header #commands .close{grid-column:2;display:grid;align-items:center;justify-items:center;cursor:pointer}#actionTabs .tabsMenu{display:grid;grid-row:2;grid-template-rows:40px 1fr;font:14px "Arial";overflow:hidden}#actionTabs .tabsMenu .labels{grid-row:1;display:flex;align-items:center;justify-items:center;border-bottom:1px solid #fff;margin:0;padding:0}#actionTabs .tabsMenu .labels .label{font-size:24px;color:#fff;width:40px;display:flex;align-content:center;justify-content:center;border:1px solid rgba(0,0,0,0);border-bottom:none;background:#333;padding:5px;height:28px;cursor:pointer}#actionTabs .tabsMenu .labels .label.active{border-color:#fff;border-bottom:2px solid rgba(0,0,0,0);margin-bottom:-2px}#actionTabs .tabsMenu .panes{grid-row:2;display:grid;grid-template-rows:100%;overflow:hidden}#actionTabs .tabsMenu .panes .infoMessage{opacity:.5;color:#fff;margin:15px 5px 0px 5px}#actionTabs .tabsMenu .panes .gradient-step{display:grid;grid-template-rows:100%;grid-template-columns:20px 30px 40px auto 20px 30px;padding-top:5px;padding-left:5px;padding-bottom:5px;align-items:center}#actionTabs .tabsMenu .panes .gradient-step .step{grid-row:1;grid-column:1}#actionTabs .tabsMenu .panes .gradient-step .color1{height:100%}#actionTabs .tabsMenu .panes .gradient-step .color2{height:100%;padding-left:5px}#actionTabs .tabsMenu .panes .gradient-step .factor1{grid-row:1;grid-column:2;cursor:pointer}#actionTabs .tabsMenu .panes .gradient-step .factor2{padding-left:5px;grid-row:1;grid-column:3;cursor:pointer}#actionTabs .tabsMenu .panes .gradient-step .factor2 .grayed{background:gray;border-color:gray}#actionTabs .tabsMenu .panes .gradient-step .numeric-input{width:calc(100% - 5px)}#actionTabs .tabsMenu .panes .gradient-step .icon{cursor:pointer}#actionTabs .tabsMenu .panes .gradient-step .step-value{margin-left:5px;grid-row:1;grid-column:3;text-align:right;margin-right:5px}#actionTabs .tabsMenu .panes .gradient-step .step-slider{grid-row:1;grid-column:4;display:grid;justify-content:stretch;align-content:center;margin-right:12px}#actionTabs .tabsMenu .panes .gradient-step .step-slider input{width:100%}#actionTabs .tabsMenu .panes .gradient-step .step-slider .range:hover{opacity:1}#actionTabs .tabsMenu .panes .gradient-step .step-slider .range{-webkit-appearance:none;height:6px;background:#d3d3d3;border-radius:5px;outline:none;opacity:.7;transition:opacity .2s}#actionTabs .tabsMenu .panes .gradient-step .step-slider .range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:14px;height:14px;border-radius:50%;background:#337ab7;cursor:pointer}#actionTabs .tabsMenu .panes .gradient-step .step-slider .range::-moz-range-thumb{width:14px;height:14px;border-radius:50%;background:#337ab7;cursor:pointer}#actionTabs .tabsMenu .panes .gradient-step .gradient-copy{grid-row:1;grid-column:5;display:grid;align-content:center;justify-content:center}#actionTabs .tabsMenu .panes .gradient-step .gradient-copy .img{height:20px;width:20px}#actionTabs .tabsMenu .panes .gradient-step .gradient-copy .img:hover{cursor:pointer}#actionTabs .tabsMenu .panes .gradient-step .gradient-delete{grid-row:1;grid-column:6;display:grid;align-content:center;justify-content:center}#actionTabs .tabsMenu .panes .gradient-step .gradient-delete .img{height:20px;width:20px}#actionTabs .tabsMenu .panes .gradient-step .gradient-delete .img:hover{cursor:pointer}#actionTabs .tabsMenu .panes .pane{color:#fff;overflow-x:hidden;overflow-y:auto;height:100%;user-select:none}#actionTabs .tabsMenu .panes .pane .animation-info{border-left:#adff2f 3px solid;margin-left:5px;padding-left:5px !important}#actionTabs .tabsMenu .panes .pane .tagContainer{display:flex;min-height:20px;padding:4px;width:calc(100% - 8px);flex-wrap:wrap}#actionTabs .tabsMenu .panes .pane .tagContainer .tag{border:1px solid #fff;border-radius:6px;padding:1px 4px;margin:2px}#actionTabs .tabsMenu .panes .pane .underline{border-bottom:.5px solid hsla(0,0%,100%,.5)}#actionTabs .tabsMenu .panes .pane .textureLinkLine{display:grid;grid-template-columns:auto 1fr}#actionTabs .tabsMenu .panes .pane .textureLinkLine .debug{grid-column:1;margin-left:5px;margin-right:5px;display:block;align-items:center;justify-items:center;cursor:pointer;opacity:.5}#actionTabs .tabsMenu .panes .pane .textureLinkLine .debug.selected{opacity:1}#actionTabs .tabsMenu .panes .pane .textureLinkLine .textLine{grid-column:2}#actionTabs .tabsMenu .panes .pane .textureLinkLine .actionIcon{display:inline-block;margin-top:6px;margin-right:4px}#actionTabs .tabsMenu .panes .pane .messageLine{text-align:center;font-size:12px;font-style:italic;opacity:.6}#actionTabs .tabsMenu .panes .pane .iconMessageLine{padding-left:2px;height:30px;display:grid;grid-template-columns:30px 1fr}#actionTabs .tabsMenu .panes .pane .iconMessageLine .icon{grid-column:1;display:grid;align-items:center;justify-items:center}#actionTabs .tabsMenu .panes .pane .iconMessageLine .value{grid-column:2;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .color-picker{height:calc(100% - 8px);margin:4px;width:100%}#actionTabs .tabsMenu .panes .pane .color-picker .color-rect{height:calc(100% - 4px);border:2px #fff solid;cursor:pointer;min-height:18px}#actionTabs .tabsMenu .panes .pane .color-picker .color-picker-cover{position:fixed;top:0px;right:0px;bottom:0px;left:0px;z-index:100}#actionTabs .tabsMenu .panes .pane .color-picker .color-picker-float{position:absolute}#actionTabs .tabsMenu .panes .pane .linkButtonLine{padding-left:2px;height:30px;display:grid;grid-template-columns:1fr auto 20px}#actionTabs .tabsMenu .panes .pane .linkButtonLine .link{grid-column:1;display:flex;align-items:center;text-decoration:underline;cursor:pointer}#actionTabs .tabsMenu .panes .pane .linkButtonLine .link-button{grid-column:2}#actionTabs .tabsMenu .panes .pane .linkButtonLine .link-button button{background:#222;border:1px solid #337ab7;margin:5px 10px 5px 10px;color:#fff;padding:4px 5px;opacity:.9;cursor:pointer}#actionTabs .tabsMenu .panes .pane .linkButtonLine .link-button button:hover{opacity:1}#actionTabs .tabsMenu .panes .pane .linkButtonLine .link-button button:active{background:#282828}#actionTabs .tabsMenu .panes .pane .linkButtonLine .link-button button:focus{border:1px solid #337ab7;outline:0px}#actionTabs .tabsMenu .panes .pane .linkButtonLine .link-icon{grid-column:3;display:grid;align-content:center}#actionTabs .tabsMenu .panes .pane .textLine{padding-left:2px;height:30px;display:grid;grid-template-columns:1fr auto}#actionTabs .tabsMenu .panes .pane .textLine.indented{grid-template-columns:100%}#actionTabs .tabsMenu .panes .pane .textLine.indented .link-value{grid-column:1;text-align:start;margin-left:20px;opacity:.6;max-width:unset}#actionTabs .tabsMenu .panes .pane .textLine.indented .value{grid-column:1;text-align:start;margin-left:20px;opacity:.6;max-width:unset}#actionTabs .tabsMenu .panes .pane .textLine.reduced-opacity{opacity:.6;padding-left:25px}#actionTabs .tabsMenu .panes .pane .textLine .label{grid-column:1;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .textLine .link-value{grid-column:2;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-align:end;opacity:.8;margin:5px;margin-top:7px;max-width:140px;text-decoration:underline;cursor:pointer}#actionTabs .tabsMenu .panes .pane .textLine .value{grid-column:2;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-align:end;opacity:.8;margin:5px;margin-top:7px;max-width:200px;user-select:text}#actionTabs .tabsMenu .panes .pane .textLine .value.check{color:green}#actionTabs .tabsMenu .panes .pane .textLine .value.uncheck{color:red}#actionTabs .tabsMenu .panes .pane .gradient-container{margin-top:3px}#actionTabs .tabsMenu .panes .pane .gradient-container .gradient-label{height:30px;display:grid;align-content:center}#actionTabs .tabsMenu .panes .pane .gradient-container .gradient-step{display:grid;grid-template-rows:100%;grid-template-columns:25px 50px 55px 40px auto 20px 5px;padding-top:5px;padding-left:5px;padding-bottom:5px;align-items:center;border-left:orange 3px solid}#actionTabs .tabsMenu .panes .pane .gradient-container .gradient-step .step{grid-row:1;grid-column:1}#actionTabs .tabsMenu .panes .pane .gradient-container .gradient-step .color1{height:100%}#actionTabs .tabsMenu .panes .pane .gradient-container .gradient-step .color2{height:100%;padding-left:5px}#actionTabs .tabsMenu .panes .pane .gradient-container .gradient-step .factor1{grid-row:1;grid-column:2;cursor:pointer}#actionTabs .tabsMenu .panes .pane .gradient-container .gradient-step .factor2{padding-left:5px;grid-row:1;grid-column:3;cursor:pointer}#actionTabs .tabsMenu .panes .pane .gradient-container .gradient-step .factor2 .grayed{background:gray;border-color:gray}#actionTabs .tabsMenu .panes .pane .gradient-container .gradient-step .numeric-input{width:calc(100% - 5px)}#actionTabs .tabsMenu .panes .pane .gradient-container .gradient-step .step-value{margin-left:5px;grid-row:1;grid-column:4;text-align:right;margin-right:5px}#actionTabs .tabsMenu .panes .pane .gradient-container .gradient-step .step-slider{grid-row:1;grid-column:5;display:grid;justify-content:stretch;align-content:center;margin-right:5px}#actionTabs .tabsMenu .panes .pane .gradient-container .gradient-step .step-slider input{width:100%}#actionTabs .tabsMenu .panes .pane .gradient-container .gradient-step .gradient-delete{grid-row:1;grid-column:6;display:grid;align-content:center;justify-content:center}#actionTabs .tabsMenu .panes .pane .textInputLine{padding-left:2px;height:30px;display:grid;grid-template-columns:1fr 120px}#actionTabs .tabsMenu .panes .pane .textInputLine .label{grid-column:1;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .textInputLine .value{display:flex;align-items:center;grid-column:2}#actionTabs .tabsMenu .panes .pane .textInputLine .value input{width:110px}#actionTabs .tabsMenu .panes .pane .buttonLine{height:30px;display:grid;align-items:center;justify-items:stretch}#actionTabs .tabsMenu .panes .pane .buttonLine input[type=file]{display:none}#actionTabs .tabsMenu .panes .pane .buttonLine .file-upload{background:#222;border:1px solid #337ab7;margin:5px 10px 5px 10px;color:#fff;padding:4px 5px;font-size:13px;opacity:.9;cursor:pointer;text-align:center}#actionTabs .tabsMenu .panes .pane .buttonLine .file-upload:hover{opacity:1}#actionTabs .tabsMenu .panes .pane .buttonLine .file-upload:active{transform:scale(0.98);transform-origin:.5 .5}#actionTabs .tabsMenu .panes .pane .buttonLine button{background:#222;border:1px solid #337ab7;margin:5px 10px 5px 10px;color:#fff;padding:4px 5px;opacity:.9;cursor:pointer}#actionTabs .tabsMenu .panes .pane .buttonLine button:hover{opacity:1}#actionTabs .tabsMenu .panes .pane .buttonLine button:active{background:#282828}#actionTabs .tabsMenu .panes .pane .buttonLine button:focus{border:1px solid #337ab7;outline:0px}#actionTabs .tabsMenu .panes .pane .radioLine{padding-left:2px;height:30px;display:grid;grid-template-columns:1fr 24px}#actionTabs .tabsMenu .panes .pane .radioLine .label{grid-column:1;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .radioLine .radioContainer{grid-column:2;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .radioLine .radioContainer .radio{display:none}#actionTabs .tabsMenu .panes .pane .radioLine .radioContainer .radio:checked+label:before{border-color:#337ab7}#actionTabs .tabsMenu .panes .pane .radioLine .radioContainer .radio:checked+label:after{transform:scale(1)}#actionTabs .tabsMenu .panes .pane .radioLine .radioContainer .labelForRadio{display:inline-block;height:14px;position:relative;padding:0 24px;margin-bottom:0;cursor:pointer;vertical-align:bottom}#actionTabs .tabsMenu .panes .pane .radioLine .radioContainer .labelForRadio:before,#actionTabs .tabsMenu .panes .pane .radioLine .radioContainer .labelForRadio:after{position:absolute;content:"";border-radius:50%;transition:all .3s ease;transition-property:transform,border-color}#actionTabs .tabsMenu .panes .pane .radioLine .radioContainer .labelForRadio:before{left:0px;top:0;width:16px;height:16px;border:2px solid #fff}#actionTabs .tabsMenu .panes .pane .radioLine .radioContainer .labelForRadio:after{top:6px;left:6px;width:8px;height:8px;transform:scale(0);background:#337ab7}#actionTabs .tabsMenu .panes .pane .radioLine .copy{grid-column:3;display:grid;align-items:center;justify-items:center;cursor:pointer}#actionTabs .tabsMenu .panes .pane .radioLine .copy img{height:100%}#actionTabs .tabsMenu .panes .pane .vector3Line{padding-left:2px;display:grid}#actionTabs .tabsMenu .panes .pane .vector3Line .firstLine{display:grid;grid-template-columns:1fr auto 20px;height:30px}#actionTabs .tabsMenu .panes .pane .vector3Line .firstLine .label{grid-column:1;display:flex;align-items:center;white-space:nowrap;overflow:hidden}#actionTabs .tabsMenu .panes .pane .vector3Line .firstLine .vector{grid-column:2;display:flex;align-items:center;text-align:right;opacity:.8;padding-left:5px}#actionTabs .tabsMenu .panes .pane .vector3Line .firstLine .expand{grid-column:3;display:grid;align-items:center;justify-items:center;cursor:pointer}#actionTabs .tabsMenu .panes .pane .vector3Line .firstLine .copy{grid-column:4;display:grid;align-items:center;justify-items:center;cursor:pointer}#actionTabs .tabsMenu .panes .pane .vector3Line .firstLine .copy img{height:100%}#actionTabs .tabsMenu .panes .pane .vector3Line .secondLine{display:grid;padding-right:5px;border-left:1px solid #337ab7}#actionTabs .tabsMenu .panes .pane .vector3Line .secondLine .numeric{display:grid;grid-template-columns:1fr auto}#actionTabs .tabsMenu .panes .pane .vector3Line .secondLine .numeric-label{text-align:right;grid-column:1;display:flex;align-items:center;justify-self:right;margin-right:10px}#actionTabs .tabsMenu .panes .pane .vector3Line .secondLine .numeric-value{width:120px;grid-column:2;display:flex;align-items:center;border:1px solid #337ab7}#actionTabs .tabsMenu .panes .pane .checkBoxLine{padding-left:2px;height:30px;display:grid;grid-template-columns:1fr auto 20px 10px}#actionTabs .tabsMenu .panes .pane .checkBoxLine .label{grid-column:1;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .checkBoxLine .checkBox{grid-column:2;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .checkBoxLine .checkBox .lbl{position:relative;display:block;height:14px;width:34px;margin-right:5px;background:#898989;border-radius:100px;cursor:pointer;transition:all .3s ease}#actionTabs .tabsMenu .panes .pane .checkBoxLine .checkBox .lbl.checked{background:#337ab7}#actionTabs .tabsMenu .panes .pane .checkBoxLine .checkBox .lbl:after{position:absolute;left:3px;top:2px;display:block;width:10px;height:10px;border-radius:100px;background:#fff;box-shadow:0px 3px 3px rgba(0,0,0,.05);content:"";transition:all .15s ease}#actionTabs .tabsMenu .panes .pane .checkBoxLine .checkBox .lbl:after.checked{left:20px;background:#164975}#actionTabs .tabsMenu .panes .pane .checkBoxLine .checkBox .lbl.checked:after{position:absolute;top:2px;display:block;width:10px;height:10px;border-radius:100px;background:#fff;box-shadow:0px 3px 3px rgba(0,0,0,.05);content:"";transition:all .15s ease;left:20px;background:#164975}#actionTabs .tabsMenu .panes .pane .checkBoxLine .checkBox .lbl:active:after{transform:scale(1.15, 0.85)}#actionTabs .tabsMenu .panes .pane .checkBoxLine .checkBox .hidden{display:none}#actionTabs .tabsMenu .panes .pane .checkBoxLine .checkBox .icon{display:none}#actionTabs .tabsMenu .panes .pane .checkBoxLine .copy{grid-column:3;display:grid;align-items:center;justify-items:center;cursor:pointer}#actionTabs .tabsMenu .panes .pane .checkBoxLine .copy img{height:100%}#actionTabs .tabsMenu .panes .pane .textureLine{display:grid;grid-template-rows:30px auto}#actionTabs .tabsMenu .panes .pane .textureLine .control{margin-top:2px;grid-row:1;display:grid;grid-template-columns:1fr 40px 40px 40px 40px 40px 1fr}#actionTabs .tabsMenu .panes .pane .textureLine .control .red{grid-column:2}#actionTabs .tabsMenu .panes .pane .textureLine .control .green{grid-column:3}#actionTabs .tabsMenu .panes .pane .textureLine .control .blue{grid-column:4}#actionTabs .tabsMenu .panes .pane .textureLine .control .alpha{grid-column:5}#actionTabs .tabsMenu .panes .pane .textureLine .control .all{grid-column:6}#actionTabs .tabsMenu .panes .pane .textureLine .control3D{margin-top:2px;grid-row:1;display:grid;grid-template-columns:1fr 40px 40px 40px 40px 40px 40px 1fr}#actionTabs .tabsMenu .panes .pane .textureLine .control3D .px{grid-column:2}#actionTabs .tabsMenu .panes .pane .textureLine .control3D .nx{grid-column:3}#actionTabs .tabsMenu .panes .pane .textureLine .control3D .py{grid-column:4}#actionTabs .tabsMenu .panes .pane .textureLine .control3D .ny{grid-column:5}#actionTabs .tabsMenu .panes .pane .textureLine .control3D .pz{grid-column:6}#actionTabs .tabsMenu .panes .pane .textureLine .control3D .nz{grid-column:7}#actionTabs .tabsMenu .panes .pane .textureLine .command{border:1px solid rgba(0,0,0,0);background:rgba(0,0,0,0);color:#fff}#actionTabs .tabsMenu .panes .pane .textureLine .selected{border:1px solid #337ab7}#actionTabs .tabsMenu .panes .pane .textureLine .preview{grid-row:2;display:grid;align-self:center;justify-self:center;height:256px;width:256px;margin-top:5px;margin-bottom:5px;border:1px solid #fff;background-size:32px 32px;background-color:#fff;background-image:url(${d})}#actionTabs .tabsMenu .panes .pane .gltf-extension-property{margin-left:30px;border-left:1px solid #337ab7}#actionTabs .tabsMenu .panes .pane .floatLine{padding-left:2px;height:30px;display:grid;grid-template-columns:1fr 120px}#actionTabs .tabsMenu .panes .pane .floatLine .label{grid-column:1;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .floatLine .value{grid-column:2;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .floatLine .value input{width:110px}#actionTabs .tabsMenu .panes .pane .floatLine .copy{grid-column:3;display:grid;align-items:center;justify-items:center;cursor:pointer}#actionTabs .tabsMenu .panes .pane .floatLine .copy img{height:100%}#actionTabs .tabsMenu .panes .pane .sliderLine{padding-left:2px;height:30px;display:grid;grid-template-rows:100%;grid-template-columns:1fr 50px auto}#actionTabs .tabsMenu .panes .pane .sliderLine .label{grid-column:1;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .sliderLine .withMargins{margin-left:5px}#actionTabs .tabsMenu .panes .pane .sliderLine .floatLine{padding-left:2px}#actionTabs .tabsMenu .panes .pane .sliderLine .floatLine .short{grid-column:1;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .sliderLine .floatLine .short input{width:35px}#actionTabs .tabsMenu .panes .pane .sliderLine .floatLine .short input::-webkit-outer-spin-button,#actionTabs .tabsMenu .panes .pane .sliderLine .floatLine .short input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}#actionTabs .tabsMenu .panes .pane .sliderLine .floatLine .short input[type=number]{-moz-appearance:textfield}#actionTabs .tabsMenu .panes .pane .sliderLine .slider{grid-column:3;grid-row:1;margin-right:5px;width:90%;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .sliderLine .slider .range{-webkit-appearance:none;width:100%;height:6px;background:#d3d3d3;border-radius:5px;outline:none;opacity:.7;transition:opacity .2s}#actionTabs .tabsMenu .panes .pane .sliderLine .slider .range.overflow{background-color:red}#actionTabs .tabsMenu .panes .pane .sliderLine .slider .range:hover{opacity:1}#actionTabs .tabsMenu .panes .pane .sliderLine .slider .range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:14px;height:14px;border-radius:50%;background:#337ab7;cursor:pointer}#actionTabs .tabsMenu .panes .pane .sliderLine .slider .range::-moz-range-thumb{width:14px;height:14px;border-radius:50%;background:#337ab7;cursor:pointer}#actionTabs .tabsMenu .panes .pane .sliderLine .floatLine .copy{display:none}#actionTabs .tabsMenu .panes .pane .sliderLine .copy{grid-column:4;display:grid;align-items:center;justify-items:center;cursor:pointer}#actionTabs .tabsMenu .panes .pane .sliderLine .copy img{height:100%}#actionTabs .tabsMenu .panes .pane .color3Line{padding-left:2px;display:grid}#actionTabs .tabsMenu .panes .pane .color3Line .firstLine{height:30px;display:grid;grid-template-columns:1fr auto 20px}#actionTabs .tabsMenu .panes .pane .color3Line .firstLine .label{grid-column:1;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .color3Line .firstLine .color3{grid-column:2;width:50px;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .color3Line .firstLine .color3 input[type=color]{-webkit-appearance:none;border:1px solid hsla(0,0%,100%,.5);padding:0;width:30px;height:20px}#actionTabs .tabsMenu .panes .pane .color3Line .firstLine .color3 input[type=color]::-webkit-color-swatch-wrapper{padding:0}#actionTabs .tabsMenu .panes .pane .color3Line .firstLine .color3 input[type=color]::-webkit-color-swatch{border:none}#actionTabs .tabsMenu .panes .pane .color3Line .firstLine .color3 input{margin-right:5px}#actionTabs .tabsMenu .panes .pane .color3Line .firstLine .expand{grid-column:3;display:grid;align-items:center;justify-items:center;cursor:pointer}#actionTabs .tabsMenu .panes .pane .color3Line .firstLine .copy{grid-column:4;display:grid;align-items:center;justify-items:center;cursor:pointer}#actionTabs .tabsMenu .panes .pane .color3Line .firstLine .copy img{height:100%}#actionTabs .tabsMenu .panes .pane .color3Line .secondLine{display:grid;padding-right:5px;border-left:1px solid #337ab7}#actionTabs .tabsMenu .panes .pane .color3Line .secondLine .numeric{display:grid;grid-template-columns:1fr auto}#actionTabs .tabsMenu .panes .pane .color3Line .secondLine .numeric-label{text-align:right;grid-column:1;display:flex;align-items:center;justify-self:right;margin-right:10px}#actionTabs .tabsMenu .panes .pane .color3Line .secondLine .numeric-value{width:120px;grid-column:2;display:flex;align-items:center;border:1px solid #337ab7}#actionTabs .tabsMenu .panes .pane .listLine{padding-left:2px;height:30px;display:grid;grid-template-columns:1fr auto 20px 10px}#actionTabs .tabsMenu .panes .pane .listLine .label{grid-column:1;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .listLine .options{grid-column:2;display:flex;align-items:center;margin-right:5px}#actionTabs .tabsMenu .panes .pane .listLine .options select{width:115px}#actionTabs .tabsMenu .panes .pane .listLine .copy{grid-column:3;display:grid;align-items:center;justify-items:center;cursor:pointer}#actionTabs .tabsMenu .panes .pane .listLine .copy img{height:100%}#actionTabs .tabsMenu .panes .pane .paneContainer{margin-top:3px;display:grid;grid-template-rows:100%;grid-template-columns:100%}#actionTabs .tabsMenu .panes .pane .paneContainer .paneList{border-left:3px solid rgba(0,0,0,0)}#actionTabs .tabsMenu .panes .pane .paneContainer:hover .paneList{border-left:3px solid rgba(51,122,183,.8)}#actionTabs .tabsMenu .panes .pane .paneContainer:hover .paneContainer-content .header .title{border-left:3px solid #337ab7}#actionTabs .tabsMenu .panes .pane .paneContainer .paneContainer-highlight-border{grid-row:1;grid-column:1;opacity:1;border:3px solid red;margin-bottom:-5px;z-index:100;transition:opacity 250ms;pointer-events:none}#actionTabs .tabsMenu .panes .pane .paneContainer .paneContainer-highlight-border.transparent{opacity:0}#actionTabs .tabsMenu .panes .pane .paneContainer .paneContainer-content{grid-row:1;grid-column:1}#actionTabs .tabsMenu .panes .pane .paneContainer .paneContainer-content .header{display:grid;grid-template-columns:1fr auto;background:#555;height:30px;padding-right:5px;cursor:pointer}#actionTabs .tabsMenu .panes .pane .paneContainer .paneContainer-content .header .title{border-left:3px solid rgba(0,0,0,0);padding-left:5px;grid-column:1;display:flex;align-items:center}#actionTabs .tabsMenu .panes .pane .paneContainer .paneContainer-content .header .collapse{grid-column:2;display:flex;align-items:center;justify-items:center;transform-origin:center}#actionTabs .tabsMenu .panes .pane .paneContainer .paneContainer-content .header .collapse.closed{transform:rotate(180deg)}#actionTabs .tabsMenu .panes .pane .paneContainer .paneContainer-content .paneList>div:not(:last-child){border-bottom:.5px solid hsla(0,0%,100%,.1)}#actionTabs .tabsMenu .panes .pane .paneContainer .paneContainer-content .fragment>div:not(:last-child){border-bottom:.5px solid hsla(0,0%,100%,.1)}`,"",{version:3,sources:["webpack://./../../../dev/inspector/dist/components/actionTabs/actionTabs.scss"],names:[],mappings:"AAEA,gBACI,iBAAA,CACA,SAAA,CACA,OAAA,CACA,UAAA,CAGJ,oBACI,YAAA,CAGJ,YACI,eAAA,CACA,WAAA,CACA,QAAA,CACA,SAAA,CACA,YAAA,CACA,2BAAA,CACA,iBAAA,CACA,eAAA,CAEA,6BACI,UAAA,CAGJ,oBACI,WAAA,CACA,cAAA,CACA,UAAA,CACA,eAAA,CACA,UAAA,CACA,iBAAA,CACA,YAAA,CACA,mCAAA,CACA,gBAAA,CAEA,0BACI,aAAA,CACA,UAAA,CACA,WAAA,CACA,YAAA,CACA,iBAAA,CACA,mBAAA,CAGJ,0BACI,aAAA,CACA,YAAA,CACA,iBAAA,CACA,mBAAA,CACA,cAAA,CAGJ,2BACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,iBAAA,CAGJ,8BACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,6BAAA,CAEA,sCACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CAGJ,qCACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CAKZ,sBACI,YAAA,CACA,UAAA,CACA,2BAAA,CACA,iBAAA,CACA,eAAA,CAEA,8BACI,UAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,4BAAA,CACA,QAAA,CACA,SAAA,CAEA,qCACI,cAAA,CACA,UAAA,CACA,UAAA,CACA,YAAA,CACA,oBAAA,CACA,sBAAA,CACA,8BAAA,CACA,kBAAA,CACA,eAAA,CACA,WAAA,CACA,WAAA,CACA,cAAA,CAEA,4CACI,iBAAA,CACA,qCAAA,CACA,kBAAA,CAKZ,6BACI,UAAA,CACA,YAAA,CACA,uBAAA,CAEA,eAAA,CAEA,0CACI,UAAA,CACA,UAAA,CACA,uBAAA,CAGJ,4CACI,YAAA,CACA,uBAAA,CACA,mDAAA,CACA,eAAA,CACA,gBAAA,CACA,kBAAA,CACA,kBAAA,CAEA,kDACI,UAAA,CACA,aAAA,CAGJ,oDACI,WAAA,CAGJ,oDACI,WAAA,CACA,gBAAA,CAGJ,qDACI,UAAA,CACA,aAAA,CACA,cAAA,CAGJ,qDACI,gBAAA,CACA,UAAA,CACA,aAAA,CACA,cAAA,CAEA,6DACI,eAAA,CACA,iBAAA,CAIR,2DACI,sBAAA,CAGJ,kDACI,cAAA,CAGJ,wDACI,eAAA,CACA,UAAA,CACA,aAAA,CACA,gBAAA,CACA,gBAAA,CAGJ,yDACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,uBAAA,CACA,oBAAA,CACA,iBAAA,CAEA,+DACI,UAAA,CAEJ,sEACI,SAAA,CAGJ,gEACI,uBAAA,CACA,UAAA,CACA,kBAAA,CACA,iBAAA,CACA,YAAA,CACA,UAAA,CACA,sBAAA,CAGJ,sFACI,uBAAA,CACA,eAAA,CACA,UAAA,CACA,WAAA,CACA,iBAAA,CACA,kBAAA,CACA,cAAA,CAGJ,kFACI,UAAA,CACA,WAAA,CACA,iBAAA,CACA,kBAAA,CACA,cAAA,CAIR,2DACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,oBAAA,CACA,sBAAA,CAEA,gEACI,WAAA,CACA,UAAA,CAEJ,sEACI,cAAA,CAGR,6DACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,oBAAA,CACA,sBAAA,CACA,kEACI,WAAA,CACA,UAAA,CAEJ,wEACI,cAAA,CAKZ,mCACI,UAAA,CAEA,iBAAA,CACA,eAAA,CACA,WAAA,CAEA,gBAAA,CAEA,mDACI,6BAAA,CACA,eAAA,CACA,2BAAA,CAGJ,iDACI,YAAA,CACA,eAAA,CACA,WAAA,CACA,sBAAA,CACA,cAAA,CAEA,sDACI,qBAAA,CACA,iBAAA,CACA,eAAA,CACA,UAAA,CAIR,8CACI,2CAAA,CAGJ,oDACI,YAAA,CACA,8BAAA,CAEA,2DACI,aAAA,CACA,eAAA,CACA,gBAAA,CACA,aAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CACA,UAAA,CAEA,oEACI,SAAA,CAIR,8DACI,aAAA,CAGJ,gEACI,oBAAA,CACA,cAAA,CACA,gBAAA,CAIR,gDACI,iBAAA,CACA,cAAA,CACA,iBAAA,CACA,UAAA,CAGJ,oDACI,gBArVA,CAsVA,WAAA,CACA,YAAA,CACA,8BAAA,CAEA,0DACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CAGJ,2DACI,aAAA,CACA,YAAA,CACA,kBAAA,CAIR,iDACI,uBAAA,CACA,UAAA,CACA,UAAA,CAEA,6DACI,uBAAA,CACA,qBAAA,CACA,cAAA,CACA,eAAA,CAGJ,qEACI,cAAA,CACA,OAAA,CACA,SAAA,CACA,UAAA,CACA,QAAA,CACA,WAAA,CAGJ,qEACI,iBAAA,CAIR,mDACI,gBAnYA,CAoYA,WAAA,CACA,YAAA,CACA,mCAAA,CAEA,yDACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,yBAAA,CACA,cAAA,CAGJ,gEACI,aAAA,CAEA,uEACI,eAAA,CACA,wBAAA,CACA,wBAAA,CACA,UAAA,CACA,eAAA,CACA,UAAA,CACA,cAAA,CAGJ,6EACI,SAAA,CAGJ,8EACI,kBAAA,CAGJ,6EACI,wBAAA,CACA,WAAA,CAIR,8DACI,aAAA,CACA,YAAA,CACA,oBAAA,CAIR,6CACI,gBAnbA,CAobA,WAAA,CACA,YAAA,CACA,8BAAA,CAEA,sDACI,0BAAA,CAEA,kEACI,aAAA,CACA,gBAAA,CACA,gBAAA,CACA,UAAA,CACA,eAAA,CAGJ,6DACI,aAAA,CACA,gBAAA,CACA,gBAAA,CACA,UAAA,CACA,eAAA,CAIR,6DACI,UAAA,CACA,iBAAA,CAGJ,oDACI,aAAA,CACA,YAAA,CACA,kBAAA,CAGJ,yDACI,aAAA,CACA,kBAAA,CACA,sBAAA,CACA,eAAA,CACA,cAAA,CACA,UAAA,CACA,UAAA,CACA,cAAA,CACA,eAAA,CACA,yBAAA,CACA,cAAA,CAGJ,oDACI,aAAA,CACA,kBAAA,CACA,sBAAA,CACA,eAAA,CACA,cAAA,CACA,UAAA,CACA,UAAA,CACA,cAAA,CACA,eAAA,CACA,gBAAA,CAEA,0DACI,WAAA,CAGJ,4DACI,SAAA,CAKZ,uDACI,cAAA,CAEA,uEACI,WAAA,CACA,YAAA,CACA,oBAAA,CAGJ,sEACI,YAAA,CACA,uBAAA,CACA,uDAAA,CACA,eAAA,CACA,gBAAA,CACA,kBAAA,CACA,kBAAA,CACA,4BAAA,CAEA,4EACI,UAAA,CACA,aAAA,CAGJ,8EACI,WAAA,CAGJ,8EACI,WAAA,CACA,gBAAA,CAGJ,+EACI,UAAA,CACA,aAAA,CACA,cAAA,CAGJ,+EACI,gBAAA,CACA,UAAA,CACA,aAAA,CACA,cAAA,CAEA,uFACI,eAAA,CACA,iBAAA,CAIR,qFACI,sBAAA,CAGJ,kFACI,eAAA,CACA,UAAA,CACA,aAAA,CACA,gBAAA,CACA,gBAAA,CAGJ,mFACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,uBAAA,CACA,oBAAA,CACA,gBAAA,CAEA,yFACI,UAAA,CAIR,uFACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,oBAAA,CACA,sBAAA,CAKZ,kDACI,gBAllBA,CAmlBA,WAAA,CACA,YAAA,CACA,+BAAA,CAEA,yDACI,aAAA,CACA,YAAA,CACA,kBAAA,CAGJ,yDACI,YAAA,CACA,kBAAA,CACA,aAAA,CAEA,+DACI,WAAA,CAKZ,+CACI,WAAA,CACA,YAAA,CACA,kBAAA,CACA,qBAAA,CAEA,gEACI,YAAA,CAGJ,4DACI,eAAA,CACA,wBAAA,CACA,wBAAA,CACA,UAAA,CACA,eAAA,CACA,cAAA,CACA,UAAA,CACA,cAAA,CACA,iBAAA,CAGJ,kEACI,SAAA,CAGJ,mEACI,qBAAA,CACA,sBAAA,CAGJ,sDACI,eAAA,CACA,wBAAA,CACA,wBAAA,CACA,UAAA,CACA,eAAA,CACA,UAAA,CACA,cAAA,CAGJ,4DACI,SAAA,CAGJ,6DACI,kBAAA,CAGJ,4DACI,wBAAA,CACA,WAAA,CAIR,8CACI,gBAhqBA,CAiqBA,WAAA,CACA,YAAA,CACA,8BAAA,CAEA,qDACI,aAAA,CACA,YAAA,CACA,kBAAA,CAGJ,8DACI,aAAA,CACA,YAAA,CACA,kBAAA,CAEA,qEACI,YAAA,CAEA,0FACI,oBAAA,CAEJ,yFACI,kBAAA,CAIR,6EACI,oBAAA,CACA,WAAA,CACA,iBAAA,CACA,cAAA,CACA,eAAA,CACA,cAAA,CACA,qBAAA,CACA,uKAEI,iBAAA,CACA,UAAA,CACA,iBAAA,CACA,uBAAA,CACA,0CAAA,CAEJ,oFACI,QAAA,CACA,KAAA,CACA,UAAA,CACA,WAAA,CACA,qBAAA,CAEJ,mFACI,OAAA,CACA,QAAA,CACA,SAAA,CACA,UAAA,CACA,kBAAA,CACA,kBAAA,CAKZ,oDACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CACA,wDACI,WAAA,CAKZ,gDACI,gBA1uBA,CA2uBA,YAAA,CAEA,2DACI,YAAA,CACA,mCAAA,CACA,WAAA,CAEA,kEACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,kBAAA,CACA,eAAA,CAGJ,mEACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,gBAAA,CACA,UAAA,CACA,gBAAA,CAGJ,mEACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CAGJ,iEACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CACA,qEACI,WAAA,CAKZ,4DACI,YAAA,CACA,iBAAA,CACA,6BAAA,CAEA,qEACI,YAAA,CACA,8BAAA,CAGJ,2EACI,gBAAA,CACA,aAAA,CACA,YAAA,CACA,kBAAA,CACA,kBAAA,CACA,iBAAA,CAGJ,2EACI,WAAA,CACA,aAAA,CACA,YAAA,CACA,kBAAA,CACA,wBAAA,CAKZ,iDACI,gBArzBA,CAszBA,WAAA,CACA,YAAA,CACA,wCAAA,CAEA,wDACI,aAAA,CACA,YAAA,CACA,kBAAA,CAGJ,2DACI,aAAA,CAEA,YAAA,CACA,kBAAA,CAEA,gEACI,iBAAA,CACA,aAAA,CACA,WAAA,CACA,UAAA,CACA,gBAAA,CACA,kBAAA,CACA,mBAAA,CACA,cAAA,CACA,uBAAA,CAEA,wEACI,kBAAA,CAIR,sEACI,iBAAA,CACA,QAAA,CACA,OAAA,CACA,aAAA,CACA,UAAA,CACA,WAAA,CACA,mBAAA,CACA,eAAA,CACA,sCAAA,CACA,UAAA,CACA,wBAAA,CAEA,8EACI,SAAA,CACA,kBAAA,CAIR,8EACI,iBAAA,CACA,OAAA,CACA,aAAA,CACA,UAAA,CACA,WAAA,CACA,mBAAA,CACA,eAAA,CACA,sCAAA,CACA,UAAA,CACA,wBAAA,CACA,SAAA,CACA,kBAAA,CAGJ,6EACI,2BAAA,CAGJ,mEACI,YAAA,CAGJ,iEACI,YAAA,CAIR,uDACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CACA,2DACI,WAAA,CAKZ,gDACI,YAAA,CACA,4BAAA,CAEA,yDACI,cAAA,CACA,UAAA,CACA,YAAA,CACA,sDAAA,CAEA,8DACI,aAAA,CAGJ,gEACI,aAAA,CAGJ,+DACI,aAAA,CAGJ,gEACI,aAAA,CAGJ,8DACI,aAAA,CAIR,2DACI,cAAA,CACA,UAAA,CACA,YAAA,CACA,2DAAA,CAEA,+DACI,aAAA,CAGJ,+DACI,aAAA,CAGJ,+DACI,aAAA,CAGJ,+DACI,aAAA,CAGJ,+DACI,aAAA,CAGJ,+DACI,aAAA,CAIR,yDACI,8BAAA,CACA,wBAAA,CACA,UAAA,CAGJ,0DACI,wBAAA,CAGJ,yDACI,UAAA,CACA,YAAA,CACA,iBAAA,CACA,mBAAA,CACA,YAAA,CACA,WAAA,CACA,cAAA,CACA,iBAAA,CACA,qBAAA,CACA,yBAAA,CACA,qBAAA,CACA,wDAAA,CAIR,4DACI,gBAAA,CACA,6BAAA,CAGJ,8CACI,gBA/+BA,CAg/BA,WAAA,CACA,YAAA,CACA,+BAAA,CAEA,qDACI,aAAA,CACA,YAAA,CACA,kBAAA,CAGJ,qDACI,aAAA,CAEA,YAAA,CACA,kBAAA,CAEA,2DACI,WAAA,CAIR,oDACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CACA,wDACI,WAAA,CAKZ,+CACI,gBAlhCA,CAmhCA,WAAA,CACA,YAAA,CACA,uBAAA,CACA,mCAAA,CAEA,sDACI,aAAA,CACA,YAAA,CACA,kBAAA,CAGJ,4DACI,eAAA,CAGJ,0DACI,gBAniCJ,CAqiCI,iEACI,aAAA,CACA,YAAA,CACA,kBAAA,CAEA,uEACI,UAAA,CAGJ,oMAEI,uBAAA,CACA,QAAA,CAGJ,oFACI,yBAAA,CAKZ,uDACI,aAAA,CACA,UAAA,CACA,gBAAA,CACA,SAAA,CACA,YAAA,CACA,kBAAA,CAEA,8DACI,uBAAA,CACA,UAAA,CACA,UAAA,CACA,kBAAA,CACA,iBAAA,CACA,YAAA,CACA,UAAA,CACA,sBAAA,CAEA,uEACI,oBAAA,CAIR,oEACI,SAAA,CAGJ,oFACI,uBAAA,CACA,eAAA,CACA,UAAA,CACA,WAAA,CACA,iBAAA,CACA,kBAAA,CACA,cAAA,CAGJ,gFACI,UAAA,CACA,WAAA,CACA,iBAAA,CACA,kBAAA,CACA,cAAA,CAKJ,gEACI,YAAA,CAIR,qDACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CACA,yDACI,WAAA,CAKZ,+CACI,gBA3nCA,CA4nCA,YAAA,CAEA,0DACI,WAAA,CACA,YAAA,CACA,mCAAA,CAEA,iEACI,aAAA,CACA,YAAA,CACA,kBAAA,CAGJ,kEACI,aAAA,CACA,UAAA,CAEA,YAAA,CACA,kBAAA,CAEA,oFACI,uBAAA,CACA,mCAAA,CACA,SAAA,CACA,UAAA,CACA,WAAA,CAEJ,kHACI,SAAA,CAEJ,0GACI,WAAA,CAGJ,wEACI,gBAAA,CAIR,kEACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CAGJ,gEACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CACA,oEACI,WAAA,CAKZ,2DACI,YAAA,CACA,iBAAA,CACA,6BAAA,CAEA,oEACI,YAAA,CACA,8BAAA,CAGJ,0EACI,gBAAA,CACA,aAAA,CACA,YAAA,CACA,kBAAA,CACA,kBAAA,CACA,iBAAA,CAGJ,0EACI,WAAA,CACA,aAAA,CACA,YAAA,CACA,kBAAA,CACA,wBAAA,CAKZ,6CACI,gBArtCA,CAstCA,WAAA,CACA,YAAA,CACA,wCAAA,CAEA,oDACI,aAAA,CACA,YAAA,CACA,kBAAA,CAGJ,sDACI,aAAA,CAEA,YAAA,CACA,kBAAA,CACA,gBAAA,CAEA,6DACI,WAAA,CAIR,mDACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CACA,uDACI,WAAA,CAKZ,kDACI,cAAA,CACA,YAAA,CACA,uBAAA,CACA,0BAAA,CAEA,4DACI,mCAAA,CAIA,kEACI,yCAAA,CAKI,8FACI,6BAAA,CAMhB,kFACI,UAAA,CACA,aAAA,CACA,SAAA,CACA,oBAAA,CACA,kBAAA,CACA,WAAA,CACA,wBAAA,CACA,mBAAA,CAEA,8FACI,SAAA,CAIR,yEACI,UAAA,CACA,aAAA,CAEA,iFACI,YAAA,CACA,8BAAA,CACA,eAAA,CACA,WAAA,CACA,iBAAA,CACA,cAAA,CAEA,wFACI,mCAAA,CACA,gBAAA,CACA,aAAA,CACA,YAAA,CACA,kBAAA,CAGJ,2FACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,uBAAA,CAEA,kGACI,wBAAA,CAKZ,wGACI,2CAAA,CAGJ,wGACI,2CAAA",sourceRoot:""}]),c.locals={};const h=c},5030:(e,t,s)=>{"use strict";s.d(t,{A:()=>i});var r=s(3234),n=s.n(r),o=s(7474),a=s.n(o)()(n());a.push([e.id,'#performance-viewer{display:grid;height:100%;width:100%;grid-template-columns:300px 1fr;font-family:"acumin-pro"}#performance-viewer .performancePlayheadButton{grid-area:liveButton;height:30px;width:100px;justify-self:right;background-color:#dcdfe1;color:#2e3f47;outline:2px #2e3f47;margin:5px;position:absolute;top:10px;right:10px}#performance-viewer #performance-viewer-sidebar{display:flex;flex-direction:column;overflow-y:scroll;border:2px solid gray}#performance-viewer #performance-viewer-sidebar .sidebar-item{display:grid;width:100%;height:30px;font-size:14px;padding:2.5px 0px;align-items:center}#performance-viewer #performance-viewer-sidebar .header{color:#fff;grid-template-columns:10px 9fr 1fr 10px}#performance-viewer #performance-viewer-sidebar .header .category{grid-column:2}#performance-viewer #performance-viewer-sidebar .header .value{grid-column:3}#performance-viewer #performance-viewer-sidebar .version-header{background-color:#2e3f47;color:#fff;grid-template-columns:10px 1fr 1fr 10px;font-size:14px;height:35px}#performance-viewer #performance-viewer-sidebar .version-header .category{grid-column:2}#performance-viewer #performance-viewer-sidebar .version-header .value{grid-column:3;display:flex;justify-content:end}#performance-viewer #performance-viewer-sidebar .category-header{background-color:#4a5960;text-transform:uppercase;font-size:14px;height:30px}#performance-viewer #performance-viewer-sidebar .category-header .checkBoxLine{color:#dcdfe1}#performance-viewer #performance-viewer-sidebar .measure{color:#000;grid-template-columns:18px 6fr 1fr;font-family:"acumin-pro-condensed"}#performance-viewer #performance-viewer-sidebar .measure .category{display:grid;grid-template-columns:18px 7px 18px 10px 1fr;grid-column:2;align-items:center}#performance-viewer #performance-viewer-sidebar .measure .category .color-picker{grid-column:3}#performance-viewer #performance-viewer-sidebar .measure .category .sidebar-item-label{grid-column:5}#performance-viewer #performance-viewer-sidebar .measure .value{grid-column:3}#performance-viewer #performance-viewer-sidebar .measure:nth-child(odd){background-color:#dcdfe1}#performance-viewer #performance-viewer-sidebar .measure:nth-child(even){background-color:#ebedee}#performance-viewer #performance-viewer-sidebar .checkBoxLine{color:#4a5960;width:100%;height:100%;display:flex;justify-content:center;align-items:center}#performance-viewer #performance-viewer-sidebar .checkBoxLine .disabled{color:#d3d3d3}#performance-viewer #performance-viewer-sidebar .color-picker{width:100%}#performance-viewer #performance-viewer-sidebar .color-picker .color-rect{height:18px;width:18px;cursor:pointer}#performance-viewer #performance-viewer-sidebar .color-picker .color-picker-cover{position:fixed;top:0px;right:0px;bottom:0px;left:0px;z-index:100}#performance-viewer #performance-viewer-sidebar .color-picker .color-picker-float{position:absolute}#performance-viewer #performance-viewer-sidebar .color-picker .color-picker-float .color-picker-container{width:200px}',"",{version:3,sources:["webpack://./../../../dev/inspector/dist/components/actionTabs/tabs/performanceViewer/scss/performanceViewer.scss"],names:[],mappings:"AAGA,oBACI,YAAA,CACA,WAAA,CACA,UAAA,CACA,+BAAA,CACA,wBAAA,CAEA,+CACI,oBAAA,CACA,WAZO,CAaP,WAAA,CACA,kBAAA,CACA,wBAAA,CACA,aAAA,CACA,mBAAA,CACA,UAAA,CACA,iBAAA,CACA,QAAA,CACA,UAAA,CAGJ,gDACI,YAAA,CACA,qBAAA,CACA,iBAAA,CAEA,qBAAA,CAEA,8DACI,YAAA,CACA,UAAA,CACA,WAAA,CACA,cAAA,CACA,iBAAA,CACA,kBAAA,CAGJ,wDACI,UAAA,CACA,uCAAA,CAEA,kEACI,aAAA,CAGJ,+DACI,aAAA,CAIR,gEACI,wBAAA,CACA,UAAA,CACA,uCAAA,CACA,cAAA,CACA,WAAA,CAEA,0EACI,aAAA,CAGJ,uEACI,aAAA,CACA,YAAA,CACA,mBAAA,CAKR,iEACI,wBAAA,CACA,wBAAA,CACA,cAAA,CACA,WAAA,CAEA,+EACI,aAAA,CAIR,yDACI,UAAA,CACA,kCAAA,CACA,kCAAA,CAEA,mEACI,YAAA,CACA,4CAAA,CACA,aAAA,CACA,kBAAA,CAEA,iFACI,aAAA,CAGJ,uFACI,aAAA,CAIR,gEACI,aAAA,CAKR,wEACI,wBAAA,CAIJ,yEACI,wBAAA,CAGJ,8DACI,aAAA,CACA,UAAA,CACA,WAAA,CACA,YAAA,CACA,sBAAA,CACA,kBAAA,CACA,wEACI,aAAA,CAIR,8DACI,UAAA,CAEA,0EACI,WArIH,CAsIG,UAtIH,CAuIG,cAAA,CAGJ,kFACI,cAAA,CACA,OAAA,CACA,SAAA,CACA,UAAA,CACA,QAAA,CACA,WAAA,CAGJ,kFACI,iBAAA,CAEA,0GACI,WAAA",sourceRoot:""}]),a.locals={};const i=a},2685:(e,t,s)=>{"use strict";s.d(t,{A:()=>i});var r=s(3234),n=s.n(r),o=s(7474),a=s.n(o)()(n());a.push([e.id,'#bottom-bar{display:grid;grid-template-rows:100%;grid-template-columns:10px 210px 10px 1fr 10px 61px 10px}#bottom-bar #bottom-bar-total{grid-row:1;grid-column:6;color:#fff;background:#222;height:25px;align-self:center;font-size:12pt}#bottom-bar #bottom-bar-total #clip-range{width:100%}#bottom-bar .control-button .control-button-image{display:unset}#bottom-bar .control-button .control-button-hover-image{display:none}#bottom-bar .control-button:hover{cursor:pointer}#bottom-bar .control-button:hover .control-button-image{display:none}#bottom-bar .control-button:hover .control-button-hover-image{display:unset}#bottom-bar .control-button:active{transform-origin:50% 50%;transform:scale(0.96)}#bottom-bar #media-player{grid-row:1;grid-column:2;display:grid;align-self:center;justify-self:center;grid-template-rows:100%;grid-template-columns:23px 23px 23px 23px 23px 23px 23px}#bottom-bar #media-player #start-key{grid-row:1;grid-column:1}#bottom-bar #media-player #prev-frame{grid-row:1;grid-column:2}#bottom-bar #media-player #first-key{grid-row:1;grid-column:3}#bottom-bar #media-player #rev-key{grid-row:1;grid-column:4}#bottom-bar #media-player #fwd-key{grid-row:1;grid-column:5}#bottom-bar #media-player #next-key{grid-row:1;grid-column:6}#bottom-bar #media-player #next-frame{grid-row:1;grid-column:7}#bottom-bar #media-player #end-key{grid-row:1;grid-column:8}#bottom-bar #range-selector{grid-row:1;grid-column:4;background:#222;width:100%;height:calc(100% - 20px);margin:10px 0;position:relative}#bottom-bar #range-selector #range-scrollbar{position:absolute;left:2px;top:2px;right:2px;bottom:2px;background:#666;display:grid;grid-template-rows:100%;grid-template-columns:20px auto 1fr auto 20px;color:#222;font-family:"acumin-pro-condensed";font-size:14px;min-width:70px}#bottom-bar #range-selector #range-scrollbar #left-handle{grid-row:1;grid-column:1}#bottom-bar #range-selector #range-scrollbar #right-handle{grid-row:1;grid-column:5}#bottom-bar #range-selector #range-scrollbar #from-key{grid-row:1;grid-column:2;align-self:center;justify-self:center;user-select:none;pointer-events:none}#bottom-bar #range-selector #range-scrollbar #to-key{grid-row:1;grid-column:4;align-self:center;justify-self:center;user-select:none;pointer-events:none}#bottom-bar #range-selector #range-scrollbar .handle{width:20px;align-self:center;justify-self:center;cursor:pointer;user-select:none}#bottom-bar #range-selector #range-scrollbar .handle img{pointer-events:none}',"",{version:3,sources:["webpack://./../../../dev/inspector/dist/components/actionTabs/tabs/propertyGrids/animations/curveEditor/scss/bottomBar.scss"],names:[],mappings:"AAAA,YACI,YAAA,CACA,uBAAA,CACA,wDAAA,CAEA,8BACI,UAAA,CACA,aAAA,CACA,UAAA,CACA,eAAA,CACA,WAAA,CACA,iBAAA,CACA,cAAA,CAEA,0CACI,UAAA,CAKJ,kDACI,aAAA,CAGJ,wDACI,YAAA,CAGJ,kCACI,cAAA,CAEA,wDACI,YAAA,CAGJ,8DACI,aAAA,CAIR,mCACI,wBAAA,CACA,qBAAA,CAIR,0BACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,iBAAA,CACA,mBAAA,CACA,uBAAA,CACA,wDAAA,CAEA,qCACI,UAAA,CACA,aAAA,CAGJ,sCACI,UAAA,CACA,aAAA,CAGJ,qCACI,UAAA,CACA,aAAA,CAGJ,mCACI,UAAA,CACA,aAAA,CAGJ,mCACI,UAAA,CACA,aAAA,CAGJ,oCACI,UAAA,CACA,aAAA,CAGJ,sCACI,UAAA,CACA,aAAA,CAGJ,mCACI,UAAA,CACA,aAAA,CAIR,4BACI,UAAA,CACA,aAAA,CACA,eAAA,CACA,UAAA,CACA,wBAAA,CACA,aAAA,CACA,iBAAA,CAEA,6CACI,iBAAA,CACA,QAAA,CACA,OAAA,CACA,SAAA,CACA,UAAA,CACA,eAAA,CACA,YAAA,CACA,uBAAA,CACA,6CAAA,CACA,UAAA,CACA,kCAAA,CACA,cAAA,CACA,cAAA,CAEA,0DACI,UAAA,CACA,aAAA,CAGJ,2DACI,UAAA,CACA,aAAA,CAGJ,uDACI,UAAA,CACA,aAAA,CACA,iBAAA,CACA,mBAAA,CACA,gBAAA,CACA,mBAAA,CAGJ,qDACI,UAAA,CACA,aAAA,CACA,iBAAA,CACA,mBAAA,CACA,gBAAA,CACA,mBAAA,CAGJ,qDACI,UAAA,CACA,iBAAA,CACA,mBAAA,CACA,cAAA,CACA,gBAAA,CAEA,yDACI,mBAAA",sourceRoot:""}]),a.locals={};const i=a},7159:(e,t,s)=>{"use strict";s.d(t,{A:()=>i});var r=s(3234),n=s.n(r),o=s(7474),a=s.n(o)()(n());a.push([e.id,'#canvas-zone{display:grid;grid-template-columns:100%;grid-template-rows:30px 1fr 10px 40px;overflow:hidden;position:relative}#canvas-zone #graph{grid-column:1;grid-row:2;width:100%;height:100%;background:#222;display:grid;grid-template-columns:100%;grid-template-rows:100%;overflow:hidden;position:relative}#canvas-zone #graph #svg-graph-grid{grid-column:1;grid-row:1;width:100%;height:100%;pointer-events:none;z-index:1}#canvas-zone #graph #svg-graph-grid:focus{outline:none}#canvas-zone #graph #svg-graph-horizontal{grid-column:1;grid-row:1;margin-left:40px;width:calc(100% - 40px);height:100%;pointer-events:none;z-index:1}#canvas-zone #graph #svg-graph-horizontal:focus{outline:none}#canvas-zone #graph #dark-rectangle{grid-column:1;grid-row:1;margin-left:40px;width:calc(100% - 40px);height:100%;background:#111;opacity:.2;pointer-events:none;position:absolute}#canvas-zone #graph #block-rectangle{grid-column:1;grid-row:1;width:40px;height:100%;background:#222;z-index:1}#canvas-zone #graph #svg-graph-curves{grid-column:1;grid-row:1;margin-left:40px;width:calc(100% - 40px);height:100%;z-index:2}#canvas-zone #graph #svg-graph-curves:focus{outline:none}#canvas-zone #graph #selection-rectangle{grid-column:1;grid-row:1;width:calc(100% - 40px);height:100%;pointer-events:none;position:absolute;left:40px;visibility:hidden;border:1px dashed #fff}#canvas-zone #range-frame-bar{grid-column:1;grid-row:4;width:100%;height:100%;background:#222;pointer-events:none;display:grid;grid-template-rows:100%;grid-template-columns:100%;pointer-events:none;user-select:none}#canvas-zone #range-frame-bar #svg-range-frames{grid-column:1;grid-row:1;width:100%;height:100%}#canvas-zone #frame-bar{grid-column:1;grid-row:1;width:100%;height:100%;background:#222;pointer-events:none;display:grid;grid-template-rows:100%;grid-template-columns:40px 1fr}#canvas-zone #frame-bar #angle-unit{grid-column:1;grid-row:1;background:#111}#canvas-zone #frame-bar #frames{grid-column:1/3;grid-row:1;width:100%;height:100%;display:grid;grid-template-rows:100%;grid-template-columns:100%}#canvas-zone #frame-bar #frames #svg-frames{margin-left:40px;grid-column:1;grid-row:1;width:calc(100% - 40px);height:100%}#canvas-zone #play-head-control{grid-column:1;grid-row:1;position:absolute;height:30px;left:40px;width:calc(100% - 40px)}#canvas-zone #play-head-control-2{grid-column:1;grid-row:4;position:absolute;height:30px;left:0px;width:100%}#canvas-zone #play-head{grid-column:1;grid-row:1/3;position:absolute;top:0;height:calc(100% - 5px);width:22px;margin-left:40px;display:grid;grid-template-columns:100%;grid-template-rows:22px 1fr;transform:translateX(-50%);pointer-events:none;z-index:3}#canvas-zone #play-head #play-head-bar{grid-row:2;grid-column:1;justify-self:center;width:1.5px;background:#fff;height:100%;pointer-events:none}#canvas-zone #play-head #play-head-circle{grid-row:1;grid-column:1;width:22px;height:22px;border-radius:50%;background:#fff;font-family:"acumin-pro-condensed";font-size:8pt;display:grid;align-content:center;justify-content:center;color:#555;cursor:pointer}#canvas-zone #angle-mode{grid-column:1;grid-row:1;width:40px;height:100%;z-index:1;background:#222}',"",{version:3,sources:["webpack://./../../../dev/inspector/dist/components/actionTabs/tabs/propertyGrids/animations/curveEditor/scss/canvas.scss"],names:[],mappings:"AAAA,aACI,YAAA,CACA,0BAAA,CACA,qCAAA,CACA,eAAA,CACA,iBAAA,CAEA,oBACI,aAAA,CACA,UAAA,CACA,UAAA,CACA,WAAA,CACA,eAAA,CACA,YAAA,CACA,0BAAA,CACA,uBAAA,CACA,eAAA,CACA,iBAAA,CAEA,oCACI,aAAA,CACA,UAAA,CACA,UAAA,CACA,WAAA,CACA,mBAAA,CACA,SAAA,CAEA,0CACI,YAAA,CAIR,0CACI,aAAA,CACA,UAAA,CACA,gBAAA,CACA,uBAAA,CACA,WAAA,CACA,mBAAA,CACA,SAAA,CAEA,gDACI,YAAA,CAIR,oCACI,aAAA,CACA,UAAA,CACA,gBAAA,CACA,uBAAA,CACA,WAAA,CACA,eAAA,CACA,UAAA,CACA,mBAAA,CACA,iBAAA,CAGJ,qCACI,aAAA,CACA,UAAA,CACA,UAAA,CACA,WAAA,CACA,eAAA,CACA,SAAA,CAGJ,sCACI,aAAA,CACA,UAAA,CACA,gBAAA,CACA,uBAAA,CACA,WAAA,CACA,SAAA,CAEA,4CACI,YAAA,CAIR,yCACI,aAAA,CACA,UAAA,CACA,uBAAA,CACA,WAAA,CACA,mBAAA,CACA,iBAAA,CACA,SAAA,CACA,iBAAA,CAEA,sBAAA,CAIR,8BACI,aAAA,CACA,UAAA,CACA,UAAA,CACA,WAAA,CACA,eAAA,CACA,mBAAA,CACA,YAAA,CACA,uBAAA,CACA,0BAAA,CACA,mBAAA,CACA,gBAAA,CAEA,gDACI,aAAA,CACA,UAAA,CACA,UAAA,CACA,WAAA,CAIR,wBACI,aAAA,CACA,UAAA,CACA,UAAA,CACA,WAAA,CACA,eAAA,CACA,mBAAA,CAEA,YAAA,CACA,uBAAA,CACA,8BAAA,CAEA,oCACI,aAAA,CACA,UAAA,CACA,eAAA,CAGJ,gCACI,eAAA,CAEA,UAAA,CACA,UAAA,CACA,WAAA,CACA,YAAA,CACA,uBAAA,CACA,0BAAA,CAEA,4CACI,gBAAA,CACA,aAAA,CACA,UAAA,CACA,uBAAA,CACA,WAAA,CAKZ,gCACI,aAAA,CACA,UAAA,CACA,iBAAA,CACA,WAAA,CACA,SAAA,CACA,uBAAA,CAGJ,kCACI,aAAA,CACA,UAAA,CACA,iBAAA,CACA,WAAA,CACA,QAAA,CACA,UAAA,CAGJ,wBACI,aAAA,CACA,YAAA,CACA,iBAAA,CACA,KAAA,CACA,uBAAA,CACA,UAAA,CACA,gBAAA,CACA,YAAA,CACA,0BAAA,CACA,2BAAA,CACA,0BAAA,CACA,mBAAA,CACA,SAAA,CAEA,uCACI,UAAA,CACA,aAAA,CACA,mBAAA,CACA,WAAA,CACA,eAAA,CACA,WAAA,CACA,mBAAA,CAGJ,0CACI,UAAA,CACA,aAAA,CACA,UAAA,CACA,WAAA,CACA,iBAAA,CACA,eAAA,CACA,kCAAA,CACA,aAAA,CACA,YAAA,CACA,oBAAA,CACA,sBAAA,CACA,UAAA,CACA,cAAA,CAIR,yBACI,aAAA,CACA,UAAA,CACA,UAAA,CACA,WAAA,CACA,SAAA,CACA,eAAA",sourceRoot:""}]),a.locals={};const i=a},2667:(e,t,s)=>{"use strict";s.d(t,{A:()=>i});var r=s(3234),n=s.n(r),o=s(7474),a=s.n(o)()(n());a.push([e.id,'#curve-editor{background:#333;width:100%;height:100%;display:grid;grid-template-rows:40px calc(100% - 85px) 45px;grid-template-columns:10px 210px 10px 1fr 10px}#curve-editor #top-bar{background:#333;grid-row:1;grid-column:1/6;width:100%;height:100%}#curve-editor #bottom-bar{background:#333;grid-row:3;grid-column:1/6;width:100%;height:100%}#curve-editor #canvas-zone{grid-row:2;grid-column:4;width:100%;height:100%;background:#333}#curve-editor #sidebar{grid-row:2;grid-column:2;width:100%;height:100%;background:#111}#curve-editor .action-button:hover{background:#666;color:#fff;cursor:pointer}#curve-editor .action-button.active{background:#111}#curve-editor .action-button:active{transform-origin:50% 50%;transform:scale(0.96)}#curve-editor .push-button{cursor:pointer}#curve-editor .push-button.active{background:#666}#curve-editor .text-input{color:#fff;background:#000;font-family:"acumin-pro-condensed";font-size:11pt;border:0;margin:3px 1px;text-align:end;padding-right:4px}#curve-editor .text-input:focus{outline:none}#curve-editor .text-input:disabled{background:#444;border:#555 solid 1px}',"",{version:3,sources:["webpack://./../../../dev/inspector/dist/components/actionTabs/tabs/propertyGrids/animations/curveEditor/scss/curveEditor.scss"],names:[],mappings:"AAAA,cACI,eAAA,CACA,UAAA,CACA,WAAA,CACA,YAAA,CACA,8CAAA,CACA,8CAAA,CAEA,uBACI,eAAA,CACA,UAAA,CACA,eAAA,CACA,UAAA,CACA,WAAA,CAGJ,0BACI,eAAA,CACA,UAAA,CACA,eAAA,CACA,UAAA,CACA,WAAA,CAGJ,2BACI,UAAA,CACA,aAAA,CACA,UAAA,CACA,WAAA,CACA,eAAA,CAGJ,uBACI,UAAA,CACA,aAAA,CACA,UAAA,CACA,WAAA,CACA,eAAA,CAIA,mCACI,eAAA,CACA,UAAA,CACA,cAAA,CAGJ,oCACI,eAAA,CAGJ,oCACI,wBAAA,CACA,qBAAA,CAIR,2BACI,cAAA,CACA,kCACI,eAAA,CAIR,0BACI,UAAA,CACA,eAAA,CACA,kCAAA,CACA,cAAA,CACA,QAAA,CACA,cAAA,CACA,cAAA,CACA,iBAAA,CAEA,gCACI,YAAA,CAGJ,mCACI,eAAA,CACA,qBAAA",sourceRoot:""}]),a.locals={};const i=a},9465:(e,t,s)=>{"use strict";s.d(t,{A:()=>i});var r=s(3234),n=s.n(r),o=s(7474),a=s.n(o)()(n());a.push([e.id,'#sideBar{display:grid;grid-template-columns:100%;grid-template-rows:30px 1fr}#sideBar #menu-bar{background:#252525;grid-row:1;grid-column:1;width:100%;height:100%;display:grid;grid-template-rows:100%;grid-template-columns:30px 30px 30px 30px 1fr 52px 3px}#sideBar #menu-bar.small{grid-template-columns:0px 0px 30px 30px 1fr 52px 3px}#sideBar #menu-bar #add-animation{grid-row:1;grid-column:1}#sideBar #menu-bar #load-animation{grid-row:1;grid-column:2}#sideBar #menu-bar #save-animation{grid-row:1;grid-column:3}#sideBar #menu-bar #edit-animation{grid-row:1;grid-column:4}#sideBar #menu-bar #framerate-animation{grid-row:1;grid-column:6}#sideBar .simple-button{width:80px;height:20px;color:#fff;font-family:"acumin-pro-condensed";font-size:10pt;background:#444;border:0;line-height:12px;cursor:pointer;align-self:center;justify-self:center;border-radius:0}#sideBar .simple-button:active{transform-origin:center;transform:scale(0.95)}#sideBar #save-animation-pane{width:100%;height:100%;display:grid;grid-template-columns:100%;grid-template-rows:1fr 40px auto}#sideBar #save-animation-pane #save-animation-list{grid-row:1;grid-column:1;width:100%;height:100%;display:flex;flex-direction:column;padding-top:5px}#sideBar #save-animation-pane #save-animation-list .save-animation-list-entry{height:20px;margin-left:10px;display:flex;align-content:center;color:#fff;font-family:"acumin-pro-condensed";font-size:10pt;line-height:15px}#sideBar #save-animation-pane #save-animation-buttons{grid-row:2;grid-column:1;width:100%;height:100%;display:grid;grid-template-rows:100%;grid-template-columns:10px 1fr 10px 1fr 10px;align-items:center}#sideBar #save-animation-pane #save-animation-buttons #save-snippet{grid-row:1;grid-column:2}#sideBar #save-animation-pane #save-animation-buttons #save-file{grid-row:1;grid-column:4}#sideBar #save-animation-pane #save-animation-snippet{grid-row:3;grid-column:1;width:calc(100% - 31px);height:20px;align-content:center;color:#fff;font-family:"acumin-pro-condensed";font-size:10pt;padding-left:31px;background:#252525}#sideBar #load-animation-pane{width:100%;height:100%;display:grid;grid-template-columns:75px 1fr;grid-template-rows:10px 20px 10px 20px 10px 20px 1fr auto;color:#fff;font-family:"acumin-pro-condensed";font-size:10pt}#sideBar #load-animation-pane #load-animation-snippet-id-label{grid-row:2;grid-column:1;justify-self:end;margin-right:10px}#sideBar #load-animation-pane #load-animation-local-file-label{grid-row:6;grid-column:1;justify-self:end;margin-right:10px}#sideBar #load-animation-pane #load-snippet-id{grid-row:2;grid-column:2;margin-right:10px;border:0;background:#252525;width:127px;color:#fff;font-family:"acumin-pro-condensed";font-size:10pt}#sideBar #load-animation-pane #load-snippet{grid-row:4;grid-column:2;width:60px;justify-self:left}#sideBar #load-animation-pane input[type=file]{display:none}#sideBar #load-animation-pane #file-snippet-label{grid-row:6;grid-column:2;width:60px;justify-self:left;text-align:center;line-height:18px}#sideBar #load-animation-pane #load-animation-snippet{grid-row:8;grid-column:1/3;width:calc(100% - 31px);height:20px;align-content:center;color:#fff;font-family:"acumin-pro-condensed";font-size:10pt;padding-left:31px;background:#252525}#sideBar #add-animation-pane{grid-column:1;grid-row:2;width:100%;height:100%;display:grid;grid-template-columns:75px 1fr;grid-template-rows:10px 20px 10px 20px 10px 20px 10px 20px 10px 20px 10px 20px 1fr;color:#fff;font-family:"acumin-pro-condensed";font-size:10pt}#sideBar #add-animation-pane .input-text{border:0;background:#252525;width:127px;color:#fff;font-family:"acumin-pro-condensed";font-size:10pt}#sideBar #add-animation-pane .option{background:#252525;color:#fff;border:0}#sideBar #add-animation-pane #add-animation-display-name-label{grid-row:2;grid-column:1;justify-self:end;margin-right:10px}#sideBar #add-animation-pane #add-animation-mode-label{grid-row:4;grid-column:1;justify-self:end;margin-right:10px}#sideBar #add-animation-pane #add-animation-property-label{grid-row:6;grid-column:1;justify-self:end;margin-right:10px}#sideBar #add-animation-pane #add-animation-type-label{grid-row:8;grid-column:1;justify-self:end;margin-right:10px}#sideBar #add-animation-pane #add-animation-loop-mode-label{grid-row:10;grid-column:1;justify-self:end;margin-right:10px}#sideBar #add-animation-pane #add-animation-name{grid-row:2;grid-column:2;margin-right:10px}#sideBar #add-animation-pane #add-animation-mode{grid-row:4;grid-column:2;margin-right:10px;width:calc(100% - 10px)}#sideBar #add-animation-pane #add-animation-property{grid-row:6;grid-column:2;margin-right:10px;width:calc(100% - 10px)}#sideBar #add-animation-pane #add-animation-type{grid-row:8;grid-column:2;margin-right:10px}#sideBar #add-animation-pane #add-animation-loop-mode{grid-row:10;grid-column:2;margin-right:10px}#sideBar #add-animation-pane #add-animation{grid-row:12;grid-column:2;justify-self:left}#sideBar #edit-animation-pane{grid-column:1;grid-row:2;width:100%;height:100%;display:grid;grid-template-columns:75px 1fr;grid-template-rows:10px 20px 10px 20px 10px 20px 10px 20px 1fr;color:#fff;font-family:"acumin-pro-condensed";font-size:10pt;background:#111}#sideBar #edit-animation-pane .input-text{border:0;background:#252525;width:127px;color:#fff;font-family:"acumin-pro-condensed";font-size:10pt}#sideBar #edit-animation-pane .option{background:#252525;color:#fff;border:0}#sideBar #edit-animation-pane #edit-animation-display-name-label{grid-row:2;grid-column:1;justify-self:end;margin-right:10px}#sideBar #edit-animation-pane #edit-animation-property-label{grid-row:4;grid-column:1;justify-self:end;margin-right:10px}#sideBar #edit-animation-pane #edit-animation-loop-mode-label{grid-row:6;grid-column:1;justify-self:end;margin-right:10px}#sideBar #edit-animation-pane #edit-animation-name{grid-row:2;grid-column:2;margin-right:10px}#sideBar #edit-animation-pane #edit-animation-property{grid-row:4;grid-column:2;margin-right:10px}#sideBar #edit-animation-pane #edit-animation-loop-mode{grid-row:6;grid-column:2;margin-right:10px}#sideBar #edit-animation-pane #edit-animation{grid-row:8;grid-column:1/3;display:grid;grid-template-columns:50% 50%;grid-template-rows:100%}#sideBar #edit-animation-pane #edit-animation #edit-animation-ok{grid-row:1;grid-column:1}#sideBar #edit-animation-pane #edit-animation #edit-animation-cancel{grid-row:1;grid-column:2}#sideBar #animation-list{background:#111;grid-row:2;grid-column:1;width:100%;height:100%}#sideBar #animation-list .animation-entry{height:20px;display:grid;grid-template-columns:20px 10px 1fr 20px 20px;grid-template-rows:100%}#sideBar #animation-list .animation-entry.isActive{background:#444}#sideBar #animation-list .animation-entry .animation-active-indicator{grid-row:1;grid-column:1;display:grid;margin:5px;padding-top:2px}#sideBar #animation-list .animation-entry .animation-chevron{grid-row:1;grid-column:2;display:grid;align-content:center;padding-top:5px;cursor:pointer}#sideBar #animation-list .animation-entry .animation-chevron .animation-chevron-image.collapsed{transform-origin:50% 50%;transform:rotateZ(-90deg)}#sideBar #animation-list .animation-entry .animation-name{cursor:pointer;grid-row:1;grid-column:3;font-family:"acumin-pro-condensed";font-size:10.5pt;color:#fff;display:grid;align-self:center;margin-left:5px;user-select:none}#sideBar #animation-list .animation-entry .animation-options{grid-row:1;grid-column:4}#sideBar #animation-list .animation-entry .animation-delete{grid-row:1;grid-column:5}',"",{version:3,sources:["webpack://./../../../dev/inspector/dist/components/actionTabs/tabs/propertyGrids/animations/curveEditor/scss/sideBar.scss"],names:[],mappings:"AAAA,SACI,YAAA,CACA,0BAAA,CACA,2BAAA,CAEA,mBACI,kBAAA,CACA,UAAA,CACA,aAAA,CACA,UAAA,CACA,WAAA,CACA,YAAA,CACA,uBAAA,CACA,sDAAA,CAEA,yBACI,oDAAA,CAGJ,kCACI,UAAA,CACA,aAAA,CAGJ,mCACI,UAAA,CACA,aAAA,CAGJ,mCACI,UAAA,CACA,aAAA,CAGJ,mCACI,UAAA,CACA,aAAA,CAGJ,wCACI,UAAA,CACA,aAAA,CAIR,wBACI,UAAA,CACA,WAAA,CACA,UAAA,CACA,kCAAA,CACA,cAAA,CACA,eAAA,CACA,QAAA,CACA,gBAAA,CACA,cAAA,CACA,iBAAA,CACA,mBAAA,CACA,eAAA,CAEA,+BACI,uBAAA,CACA,qBAAA,CAIR,8BACI,UAAA,CACA,WAAA,CACA,YAAA,CACA,0BAAA,CACA,gCAAA,CAEA,mDACI,UAAA,CACA,aAAA,CACA,UAAA,CACA,WAAA,CACA,YAAA,CACA,qBAAA,CACA,eAAA,CAEA,8EACI,WAAA,CACA,gBAAA,CACA,YAAA,CACA,oBAAA,CACA,UAAA,CAEA,kCAAA,CACA,cAAA,CACA,gBAAA,CAIR,sDACI,UAAA,CACA,aAAA,CACA,UAAA,CACA,WAAA,CACA,YAAA,CACA,uBAAA,CACA,4CAAA,CACA,kBAAA,CAEA,oEACI,UAAA,CACA,aAAA,CAGJ,iEACI,UAAA,CACA,aAAA,CAIR,sDACI,UAAA,CACA,aAAA,CACA,uBAAA,CACA,WAAA,CACA,oBAAA,CACA,UAAA,CACA,kCAAA,CACA,cAAA,CACA,iBAAA,CACA,kBAAA,CAIR,8BACI,UAAA,CACA,WAAA,CACA,YAAA,CACA,8BAAA,CACA,yDAAA,CACA,UAAA,CACA,kCAAA,CACA,cAAA,CAEA,+DACI,UAAA,CACA,aAAA,CACA,gBAAA,CACA,iBAAA,CAGJ,+DACI,UAAA,CACA,aAAA,CACA,gBAAA,CACA,iBAAA,CAGJ,+CACI,UAAA,CACA,aAAA,CACA,iBAAA,CACA,QAAA,CACA,kBAAA,CACA,WAAA,CACA,UAAA,CACA,kCAAA,CACA,cAAA,CAGJ,4CACI,UAAA,CACA,aAAA,CACA,UAAA,CACA,iBAAA,CAGJ,+CACI,YAAA,CAGJ,kDACI,UAAA,CACA,aAAA,CACA,UAAA,CACA,iBAAA,CACA,iBAAA,CACA,gBAAA,CAGJ,sDACI,UAAA,CACA,eAAA,CACA,uBAAA,CACA,WAAA,CACA,oBAAA,CACA,UAAA,CACA,kCAAA,CACA,cAAA,CACA,iBAAA,CACA,kBAAA,CAIR,6BACI,aAAA,CACA,UAAA,CACA,UAAA,CACA,WAAA,CACA,YAAA,CACA,8BAAA,CACA,kFAAA,CACA,UAAA,CACA,kCAAA,CACA,cAAA,CAEA,yCACI,QAAA,CACA,kBAAA,CACA,WAAA,CACA,UAAA,CACA,kCAAA,CACA,cAAA,CAGJ,qCACI,kBAAA,CACA,UAAA,CACA,QAAA,CAGJ,+DACI,UAAA,CACA,aAAA,CACA,gBAAA,CACA,iBAAA,CAGJ,uDACI,UAAA,CACA,aAAA,CACA,gBAAA,CACA,iBAAA,CAGJ,2DACI,UAAA,CACA,aAAA,CACA,gBAAA,CACA,iBAAA,CAGJ,uDACI,UAAA,CACA,aAAA,CACA,gBAAA,CACA,iBAAA,CAGJ,4DACI,WAAA,CACA,aAAA,CACA,gBAAA,CACA,iBAAA,CAGJ,iDACI,UAAA,CACA,aAAA,CACA,iBAAA,CAGJ,iDACI,UAAA,CACA,aAAA,CACA,iBAAA,CACA,uBAAA,CAGJ,qDACI,UAAA,CACA,aAAA,CACA,iBAAA,CACA,uBAAA,CAGJ,iDACI,UAAA,CACA,aAAA,CACA,iBAAA,CAGJ,sDACI,WAAA,CACA,aAAA,CACA,iBAAA,CAGJ,4CACI,WAAA,CACA,aAAA,CACA,iBAAA,CAIR,8BACI,aAAA,CACA,UAAA,CAEA,UAAA,CACA,WAAA,CACA,YAAA,CACA,8BAAA,CACA,8DAAA,CACA,UAAA,CACA,kCAAA,CACA,cAAA,CACA,eAAA,CAEA,0CACI,QAAA,CACA,kBAAA,CACA,WAAA,CACA,UAAA,CACA,kCAAA,CACA,cAAA,CAGJ,sCACI,kBAAA,CACA,UAAA,CACA,QAAA,CAGJ,iEACI,UAAA,CACA,aAAA,CACA,gBAAA,CACA,iBAAA,CAGJ,6DACI,UAAA,CACA,aAAA,CACA,gBAAA,CACA,iBAAA,CAGJ,8DACI,UAAA,CACA,aAAA,CACA,gBAAA,CACA,iBAAA,CAGJ,mDACI,UAAA,CACA,aAAA,CACA,iBAAA,CAGJ,uDACI,UAAA,CACA,aAAA,CACA,iBAAA,CAGJ,wDACI,UAAA,CACA,aAAA,CACA,iBAAA,CAGJ,8CACI,UAAA,CACA,eAAA,CACA,YAAA,CACA,6BAAA,CACA,uBAAA,CAEA,iEACI,UAAA,CACA,aAAA,CAGJ,qEACI,UAAA,CACA,aAAA,CAKZ,yBACI,eAAA,CACA,UAAA,CACA,aAAA,CACA,UAAA,CACA,WAAA,CAEA,0CACI,WAAA,CACA,YAAA,CACA,6CAAA,CACA,uBAAA,CAEA,mDACI,eAAA,CAGJ,sEACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,UAAA,CACA,eAAA,CAGJ,6DACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,oBAAA,CACA,eAAA,CACA,cAAA,CAGI,gGACI,wBAAA,CACA,yBAAA,CAKZ,0DACI,cAAA,CACA,UAAA,CACA,aAAA,CACA,kCAAA,CACA,gBAAA,CACA,UAAA,CACA,YAAA,CACA,iBAAA,CACA,eAAA,CACA,gBAAA,CAGJ,6DACI,UAAA,CACA,aAAA,CAGJ,4DACI,UAAA,CACA,aAAA",sourceRoot:""}]),a.locals={};const i=a},2063:(e,t,s)=>{"use strict";s.d(t,{A:()=>i});var r=s(3234),n=s.n(r),o=s(7474),a=s.n(o)()(n());a.push([e.id,'#top-bar{display:grid;grid-template-columns:40px 200px 75px 8px 75px 8px 40px 40px 40px 40px 40px 40px 40px 40px 1fr 40px;grid-template-rows:100%}#top-bar .disabled{opacity:20%;pointer-events:none}#top-bar #top-bar-logo{grid-row:1;grid-column:1}#top-bar #top-bar-parent-name{grid-row:1;grid-column:2;font-family:"acumin-pro-condensed";font-size:15pt;color:#fff;display:grid;align-content:center;padding-bottom:5px}#top-bar #key-frame{grid-row:1;grid-column:3;height:24px;display:grid;align-self:center}#top-bar #key-value{grid-row:1;grid-column:5;height:24px;display:grid;align-self:center}#top-bar #new-key{grid-row:1;grid-column:7}#top-bar #frame-canvas{grid-row:1;grid-column:8}#top-bar #flatten-tangent{grid-row:1;grid-column:9}#top-bar #linear-tangent{grid-row:1;grid-column:10}#top-bar #break-tangent{grid-row:1;grid-column:11}#top-bar #unify-tangent{grid-row:1;grid-column:12}#top-bar #step-tangent{grid-row:1;grid-column:13}',"",{version:3,sources:["webpack://./../../../dev/inspector/dist/components/actionTabs/tabs/propertyGrids/animations/curveEditor/scss/topBar.scss"],names:[],mappings:"AAAA,SACI,YAAA,CACA,mGAAA,CACA,uBAAA,CAEA,mBACI,WAAA,CACA,mBAAA,CAGJ,uBACI,UAAA,CACA,aAAA,CAGJ,8BACI,UAAA,CACA,aAAA,CACA,kCAAA,CACA,cAAA,CACA,UAAA,CACA,YAAA,CACA,oBAAA,CACA,kBAAA,CAGJ,oBACI,UAAA,CACA,aAAA,CACA,WAAA,CACA,YAAA,CACA,iBAAA,CAGJ,oBACI,UAAA,CACA,aAAA,CACA,WAAA,CACA,YAAA,CACA,iBAAA,CAGJ,kBACI,UAAA,CACA,aAAA,CAGJ,uBACI,UAAA,CACA,aAAA,CAGJ,0BACI,UAAA,CACA,aAAA,CAGJ,yBACI,UAAA,CACA,cAAA,CAGJ,wBACI,UAAA,CACA,cAAA,CAGJ,wBACI,UAAA,CACA,cAAA,CAGJ,uBACI,UAAA,CACA,cAAA",sourceRoot:""}]),a.locals={};const i=a},2181:(e,t,s)=>{"use strict";s.d(t,{A:()=>i});var r=s(3234),n=s.n(r),o=s(7474),a=s.n(o)()(n());a.push([e.id,'#texture-editor{height:100%;width:100%;color:#fff;background-color:#1e1e1e;font-family:"acumin-pro-condensed"}#texture-editor .icon{width:40px;height:40px}#texture-editor .icon.button{background-color:#333}#texture-editor .icon.button:hover{background-color:#4a4a4a;cursor:pointer}#texture-editor .icon.button.active{background-color:#666}#texture-editor .icon.button:active{background-color:#837c7c}#texture-editor .has-tooltip{display:inline-block}#texture-editor .has-tooltip .tooltip{visibility:hidden;background-color:#fff;z-index:1;position:absolute;opacity:0;transition:opacity .5s;line-height:normal;font-size:14px;padding:0px 5px;color:#000}#texture-editor .has-tooltip:hover .tooltip{visibility:visible;opacity:1}#texture-editor #properties{width:100%;height:40px;display:flex;align-items:center;font-size:12px;color:#fff;user-select:none;background-color:#333}#texture-editor #properties .tab{display:inline-flex;line-height:40px;height:40px;flex-shrink:0;flex-grow:0;border-right:2px solid #1e1e1e;background-color:#333}#texture-editor #properties #left{overflow:hidden;height:40px;flex-grow:1;flex-shrink:1;display:flex;flex-wrap:wrap}#texture-editor #properties #left #dimensions-tab form{display:flex}#texture-editor #properties #left #dimensions-tab label{margin-left:15px;font-size:15px;color:#afafaf}#texture-editor #properties #left #dimensions-tab label input{width:40px;height:24px;background-color:#000;color:#fff;border:0;font-size:12px;text-align:"left";font-family:"acumin-pro-condensed";font-size:15px;padding-left:8px}#texture-editor #properties #left #dimensions-tab label:last-of-type{margin-right:8px}#texture-editor #properties #right-tab{margin-right:0;flex-grow:0;flex-shrink:0}#texture-editor #properties #right-tab input[type=file]{display:none}#texture-editor #properties .pixel-data{width:45px;color:#afafaf;display:flex;justify-content:space-between;font-size:15px}#texture-editor #properties .pixel-data:first-of-type{margin-left:15px}#texture-editor #properties .pixel-data:last-of-type{padding-right:15px}#texture-editor #properties .pixel-data .value{display:inline-block;width:30px;color:#fff}#texture-editor #toolbar{position:absolute;top:60px;left:0;width:40px;display:flex;flex-direction:column;justify-content:left}#texture-editor #toolbar #tools{display:flex;flex-direction:column}#texture-editor #toolbar #add-tool{position:relative}#texture-editor #toolbar #add-tool #add-tool-popup{background-color:#333;width:348px;margin-left:40px;position:absolute;top:0px;height:40px;padding-left:4px;line-height:40px;user-select:none}#texture-editor #toolbar #add-tool #add-tool-popup button{background:#222;border:1px solid #337ab7;margin:5px 10px 5px 10px;color:#fff;padding:4px 5px;opacity:.9;cursor:pointer}#texture-editor #toolbar #color{margin-top:8px}#texture-editor #toolbar #color #active-color-bg{border-radius:50%;width:20px;height:20px;margin:10px;position:relative;background-image:linear-gradient(45deg, #808080 25%, transparent 25%),linear-gradient(-45deg, #808080 25%, transparent 25%),linear-gradient(45deg, transparent 75%, #808080 75%),linear-gradient(-45deg, transparent 75%, #808080 75%);background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px}#texture-editor #toolbar #color #active-color{width:20px;height:20px;position:absolute;top:0;left:0;border-radius:50%}#texture-editor #toolbar #color-picker{position:absolute;margin-left:40px}#texture-editor #channels-bar{position:absolute;top:60px;right:0;width:80px;background:#666;user-select:none}#texture-editor #channels-bar .channel{color:#fff;border-bottom:2px solid #232323;width:80px;height:40px;font-size:16px;display:flex;align-items:center}#texture-editor #channels-bar .channel.uneditable{background:#333}#texture-editor #channels-bar .channel:hover{cursor:pointer}#texture-editor #channels-bar .channel:last-of-type{border-bottom:none}#texture-editor #canvas-ui{width:100%;height:calc(100% - 70px);outline:none}#texture-editor #tool-ui{background-color:#333;position:absolute;right:0;bottom:30px}#texture-editor #tool-ui label{display:flex;flex-direction:column;align-items:center}#texture-editor #tool-ui input[type=range]{background:#d3d3d3}#texture-editor #bottom-bar{height:30px;width:100%;background-color:#333;font-size:14px;user-select:none;line-height:30px;position:relative}#texture-editor #bottom-bar #file-url{left:30px;position:absolute}#texture-editor #bottom-bar #mip-level{right:30px;position:absolute}',"",{version:3,sources:["webpack://./../../../dev/inspector/dist/components/actionTabs/tabs/propertyGrids/materials/textures/textureEditor.scss"],names:[],mappings:"AAAA,gBACI,WAAA,CACA,UAAA,CACA,UAAA,CACA,wBAAA,CACA,kCAAA,CAEA,sBACI,UAAA,CACA,WAAA,CACA,6BACI,qBAAA,CACA,mCACI,wBAAA,CACA,cAAA,CAGJ,oCACI,qBAAA,CAGJ,oCACI,wBAAA,CAKZ,6BACI,oBAAA,CACA,sCACI,iBAAA,CACA,qBAAA,CACA,SAAA,CACA,iBAAA,CACA,SAAA,CACA,sBAAA,CACA,kBAAA,CACA,cAAA,CACA,eAAA,CACA,UAAA,CAGJ,4CACI,kBAAA,CACA,SAAA,CAIR,4BACI,UAAA,CACA,WAAA,CAEA,YAAA,CACA,kBAAA,CACA,cAAA,CACA,UAAA,CACA,gBAAA,CACA,qBAAA,CAEA,iCACI,mBAAA,CACA,gBAAA,CACA,WAAA,CACA,aAAA,CACA,WAAA,CACA,8BAAA,CACA,qBAAA,CAEJ,kCACI,eAAA,CACA,WAAA,CACA,WAAA,CACA,aAAA,CACA,YAAA,CACA,cAAA,CAEI,uDACI,YAAA,CAEJ,wDACI,gBAAA,CACA,cAAA,CACA,aAAA,CACA,8DACI,UAAA,CACA,WAAA,CACA,qBAAA,CACA,UAAA,CACA,QAAA,CACA,cAAA,CACA,iBAAA,CACA,kCAAA,CACA,cAAA,CACA,gBAAA,CAGJ,qEACI,gBAAA,CAKhB,uCACI,cAAA,CACA,WAAA,CACA,aAAA,CAEA,wDACI,YAAA,CAIR,wCACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,6BAAA,CACA,cAAA,CACA,sDACI,gBAAA,CAEJ,qDACI,kBAAA,CAEJ,+CACI,oBAAA,CACA,UAAA,CACA,UAAA,CAKZ,yBACI,iBAAA,CACA,QAAA,CACA,MAAA,CACA,UAAA,CACA,YAAA,CACA,qBAAA,CACA,oBAAA,CAEA,gCACI,YAAA,CACA,qBAAA,CAGJ,mCACI,iBAAA,CACA,mDACI,qBAAA,CACA,WAAA,CACA,gBAAA,CACA,iBAAA,CACA,OAAA,CACA,WAAA,CACA,gBAAA,CACA,gBAAA,CACA,gBAAA,CACA,0DACI,eAAA,CACA,wBAAA,CACA,wBAAA,CACA,UAAA,CACA,eAAA,CACA,UAAA,CACA,cAAA,CAKZ,gCACI,cAAA,CACA,iDACI,iBAAA,CACA,UAAA,CACA,WAAA,CACA,WAAA,CACA,iBAAA,CACA,sOAAA,CAEA,yBAAA,CACA,mDACI,CAKR,8CACI,UAAA,CACA,WAAA,CACA,iBAAA,CACA,KAAA,CACA,MAAA,CACA,iBAAA,CAGR,uCACI,iBAAA,CACA,gBAAA,CAIR,8BACI,iBAAA,CACA,QAAA,CACA,OAAA,CACA,UAAA,CACA,eAAA,CACA,gBAAA,CACA,uCACI,UAAA,CACA,+BAAA,CACA,UAAA,CACA,WAAA,CACA,cAAA,CACA,YAAA,CACA,kBAAA,CAEA,kDACI,eAAA,CAGJ,6CACI,cAAA,CAGJ,oDACI,kBAAA,CAKZ,2BACI,UAAA,CACA,wBAAA,CACA,YAAA,CAGJ,yBACI,qBAAA,CACA,iBAAA,CACA,OAAA,CACA,WAAA,CAEA,+BACI,YAAA,CACA,qBAAA,CACA,kBAAA,CAGJ,2CACI,kBAAA,CAIR,4BACI,WAAA,CACA,UAAA,CACA,qBAAA,CACA,cAAA,CACA,gBAAA,CACA,gBAAA,CACA,iBAAA,CACA,sCACI,SAAA,CACA,iBAAA,CAEJ,uCACI,UAAA,CACA,iBAAA",sourceRoot:""}]),a.locals={};const i=a},8335:(e,t,s)=>{"use strict";s.d(t,{A:()=>i});var r=s(3234),n=s.n(r),o=s(7474),a=s.n(o)()(n());a.push([e.id,"#metadata-container textarea{display:block;margin:4px;width:calc(100% - 14px);min-height:100px;max-height:500px;resize:vertical}.meta-string textarea{background:#fe9}.meta-json textarea{background:#9df}.meta-object textarea{background:#d9f}.meta-object-protect textarea{background:#b0b0b0}.buttonLine.disabled{opacity:20%;pointer-events:none}.copy-root{display:grid;justify-content:end;height:30px}.copy-container{height:30px;width:30px;cursor:pointer}.hoverIcon:hover{opacity:.8}.type-status{padding:5px 15px}","",{version:3,sources:["webpack://./../../../dev/inspector/dist/components/actionTabs/tabs/propertyGrids/metadata/metadataPropertyGrid.scss"],names:[],mappings:"AACI,6BACI,aAAA,CACA,UAAA,CACA,uBAAA,CACA,gBAAA,CACA,gBAAA,CACA,eAAA,CAKJ,sBACI,eAAA,CAKJ,oBACI,eAAA,CAKJ,sBACI,eAAA,CAKJ,8BACI,kBAAA,CAKJ,qBACI,WAAA,CACA,mBAAA,CAIR,WACI,YAAA,CACA,mBAAA,CACA,WAAA,CAGJ,gBACI,WAAA,CACA,UAAA,CACA,cAAA,CAGJ,iBACI,UAAA,CAGJ,aACI,gBAAA",sourceRoot:""}]),a.locals={};const i=a},8555:(e,t,s)=>{"use strict";s.d(t,{A:()=>i});var r=s(3234),n=s.n(r),o=s(7474),a=s.n(o)()(n());a.push([e.id,'#embed-host{position:absolute;right:0px;top:0px;bottom:0px;z-index:10}#__resizable_base__{display:none}#embed{background:#333;height:100%;margin:0;padding:0;display:grid;grid-template-rows:30px 1fr;font:14px "Arial";overflow:hidden}#embed #header{font-size:16px;color:#fff;background:#222;grid-row:1;text-align:center;display:grid;grid-template-columns:30px 1fr 50px;user-select:none}#embed #header #logo{grid-column:1;width:24px;height:24px;display:flex;align-self:center;justify-self:center}#embed #header #back{grid-column:1;display:grid;align-self:center;justify-self:center;cursor:pointer}#embed #header #title{grid-column:2;display:grid;align-items:center;text-align:center}#embed #header #commands{grid-column:3;display:grid;align-items:center;grid-template-columns:1fr 1fr}#embed #header #commands .expand{grid-column:1;display:grid;align-items:center;justify-items:center;cursor:pointer}#embed #header #commands .close{grid-column:2;display:grid;align-items:center;justify-items:center;cursor:pointer}#embed #split{grid-row:2;overflow:hidden}#embed #split.splitPopup{display:grid;grid-template-rows:300px 2px 1fr}#embed #split.splitPopup .panes{margin-bottom:1px}#embed #split #topPart{grid-row:1;overflow:hidden;display:grid;grid-auto-rows:100%}#embed #split #separator{grid-row:2;background:#fff;opacity:.1}#embed #split #bottomPart{overflow:hidden;grid-row:3;display:grid;grid-auto-rows:100%}#embed #split .gutter.gutter-vertical{background-image:none;background:#444;cursor:row-resize}',"",{version:3,sources:["webpack://./../../../dev/inspector/dist/components/embedHost/embedHost.scss"],names:[],mappings:"AAAA,YACI,iBAAA,CACA,SAAA,CACA,OAAA,CACA,UAAA,CACA,UAAA,CAGJ,oBACI,YAAA,CAGJ,OACI,eAAA,CACA,WAAA,CACA,QAAA,CACA,SAAA,CACA,YAAA,CACA,2BAAA,CACA,iBAAA,CACA,eAAA,CAEA,eACI,cAAA,CACA,UAAA,CACA,eAAA,CACA,UAAA,CACA,iBAAA,CACA,YAAA,CACA,mCAAA,CACA,gBAAA,CAEA,qBACI,aAAA,CACA,UAAA,CACA,WAAA,CACA,YAAA,CACA,iBAAA,CACA,mBAAA,CAGJ,qBACI,aAAA,CACA,YAAA,CACA,iBAAA,CACA,mBAAA,CACA,cAAA,CAGJ,sBACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,iBAAA,CAGJ,yBACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,6BAAA,CAEA,iCACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CAGJ,gCACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CAKZ,cACI,UAAA,CACA,eAAA,CAEA,yBACI,YAAA,CACA,gCAAA,CAEA,gCACI,iBAAA,CAIR,uBACI,UAAA,CACA,eAAA,CACA,YAAA,CACA,mBAAA,CAGJ,yBACI,UAAA,CACA,eAAA,CACA,UAAA,CAGJ,0BACI,eAAA,CACA,UAAA,CACA,YAAA,CACA,mBAAA,CAGJ,sCACI,qBAAA,CACA,eAAA,CACA,iBAAA",sourceRoot:""}]),a.locals={};const i=a},6771:(e,t,s)=>{"use strict";s.d(t,{A:()=>i});var r=s(3234),n=s.n(r),o=s(7474),a=s.n(o)()(n());a.push([e.id,'#scene-explorer-host{position:absolute;left:0px;top:0px;bottom:0px}#scene-explorer-host:focus{outline:none}#__resizable_base__{display:none}.context-menu{background:#222}.context-menu .react-contextmenu-item{padding:10px;cursor:pointer}.context-menu .react-contextmenu-item:hover{background:#555}.react-contextmenu.context-menu.react-contextmenu--visible{z-index:99;transform:scale(1)}#sceneExplorer{background:#333;height:100%;margin:0;padding:0;display:grid;grid-template-rows:auto 1fr;font:14px "Arial"}#sceneExplorer:focus{outline:none}#sceneExplorer #header{height:30px;font-size:16px;color:#fff;background:#222;grid-row:1;text-align:center;display:grid;grid-template-columns:30px 1fr 50px;user-select:none}#sceneExplorer #header #logo{position:relative;grid-column:1;width:24px;height:24px;left:0;display:flex;align-self:center;justify-self:center}#sceneExplorer #header #title{grid-column:2;display:grid;align-items:center;text-align:center}#sceneExplorer #header #commands{grid-column:3;display:grid;align-items:center;grid-template-columns:1fr 1fr}#sceneExplorer #header #commands .expand{grid-column:1;display:grid;align-items:center;justify-items:center;cursor:pointer}#sceneExplorer #header #commands .close{grid-column:2;display:grid;align-items:center;justify-items:center;cursor:pointer}#sceneExplorer #tree{grid-row:2;overflow-x:hidden;overflow-y:auto}#sceneExplorer .filter{display:flex;align-items:stretch}#sceneExplorer .filter input{width:100%;margin:10px 40px 5px 40px;display:block;border:none;padding:0;border-bottom:solid 1px #337ab7;background:linear-gradient(to bottom, rgba(255, 255, 255, 0) 96%, rgb(51, 122, 183) 4%);background-position:-1000px 0;background-size:1000px 100%;background-repeat:no-repeat;color:#fff}#sceneExplorer .filter input::placeholder{color:#d3d3d3}#sceneExplorer .filter input:focus{box-shadow:none;outline:none;background-position:0 0}#sceneExplorer .groupContainer{margin-left:0px;color:#fff;margin-top:0px;margin-bottom:0px;height:24px;user-select:none;align-self:center;display:grid;align-items:center}#sceneExplorer .groupContainer:hover{background:#444}#sceneExplorer .groupContainer .expandableHeader{display:grid;grid-template-columns:1fr 20px}#sceneExplorer .groupContainer .expandableHeader .text{grid-column:1;display:grid;grid-template-columns:20px 1fr}#sceneExplorer .groupContainer .expandableHeader .text .arrow{grid-column:1;margin-left:0px;color:#fff;cursor:pointer;display:inline-block;margin-right:6px;opacity:.5}#sceneExplorer .groupContainer .expandableHeader .text .text-value{grid-column:2;display:flex;align-items:center}#sceneExplorer .groupContainer .expandableHeader .expandAll{opacity:.5;grid-column:2;margin-right:10px}#sceneExplorer .icon{display:grid;align-items:center;justify-items:center;cursor:pointer}#sceneExplorer .itemContainer{margin-left:0px;color:#fff;margin-top:0px;margin-bottom:0px;height:24px;user-select:none;display:grid;grid-template-columns:20px 1fr}#sceneExplorer .itemContainer:hover{background:#444}#sceneExplorer .itemContainer.selected{background:#bbb;color:#000}#sceneExplorer .itemContainer .isNotActive{opacity:.3}#sceneExplorer .itemContainer .arrow{grid-column:1;color:#fff;opacity:.6}#sceneExplorer .itemContainer .popup{width:200px;visibility:hidden;background-color:#444;color:#fff;border:1px solid hsla(0,0%,100%,.5);position:absolute;z-index:1;margin-left:-180px;box-sizing:border-box}#sceneExplorer .itemContainer .popup.show{visibility:visible}#sceneExplorer .itemContainer .popup:focus{outline:none}#sceneExplorer .itemContainer .popup .popupMenu{padding:6px 5px 5px 10px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;height:18px}#sceneExplorer .itemContainer .popup .popupMenu:hover{background:#fff;color:#333}#sceneExplorer .itemContainer .sceneNode{grid-column:2;margin-left:-10px;display:grid;grid-template-columns:1fr 20px 20px 20px 20px 10px 20px 20px auto 5px;align-items:center;cursor:pointer}#sceneExplorer .itemContainer .sceneNode .sceneTitle{grid-column:1;margin-right:5px;display:flex;align-items:center;height:24px}#sceneExplorer .itemContainer .sceneNode .translation{grid-column:2;opacity:.6}#sceneExplorer .itemContainer .sceneNode .translation.selected{opacity:1}#sceneExplorer .itemContainer .sceneNode .rotation{grid-column:3;opacity:.6}#sceneExplorer .itemContainer .sceneNode .rotation.selected{opacity:1}#sceneExplorer .itemContainer .sceneNode .scaling{grid-column:4;opacity:.6}#sceneExplorer .itemContainer .sceneNode .scaling.selected{opacity:1}#sceneExplorer .itemContainer .sceneNode .bounding{grid-column:5;opacity:.6}#sceneExplorer .itemContainer .sceneNode .bounding.selected{opacity:1}#sceneExplorer .itemContainer .sceneNode .separator{grid-column:6;margin-left:5px;width:5px;display:flex;align-items:center;height:18px;border-left:solid 1px #337ab7}#sceneExplorer .itemContainer .sceneNode .pickingMode{grid-column:7;opacity:.6}#sceneExplorer .itemContainer .sceneNode .pickingMode.selected{opacity:1}#sceneExplorer .itemContainer .sceneNode .coordinates{grid-column:8;opacity:.6}#sceneExplorer .itemContainer .sceneNode .coordinates.selected{opacity:1}#sceneExplorer .itemContainer .sceneNode .refresh{grid-column:9}#sceneExplorer .itemContainer .sceneNode .extensions{width:20px;grid-column:10}#sceneExplorer .itemContainer .targetedAnimationTools{grid-column:2;width:100%;display:grid;grid-template-columns:1fr auto 5px;align-items:center;min-width:0}#sceneExplorer .itemContainer .targetedAnimationTools .extensions{width:20px;grid-column:2}#sceneExplorer .itemContainer .animationGroupTools{grid-column:2;width:100%;display:grid;grid-template-columns:1fr auto 5px;align-items:center;min-width:0}#sceneExplorer .itemContainer .animationGroupTools .extensions{width:20px;grid-column:2}#sceneExplorer .itemContainer .soundTools{grid-column:2;width:100%;display:grid;grid-template-columns:1fr auto 5px;align-items:center;min-width:0}#sceneExplorer .itemContainer .soundTools .extensions{width:20px;grid-column:2}#sceneExplorer .itemContainer .meshTools{grid-column:2;width:100%;display:grid;grid-template-columns:1fr auto 20px 20px auto 5px;align-items:center;min-width:0}#sceneExplorer .itemContainer .meshTools .edit{width:20px;grid-column:2}#sceneExplorer .itemContainer .meshTools .bounding-box{grid-column:3;opacity:.5}#sceneExplorer .itemContainer .meshTools .bounding-box.selected{opacity:1}#sceneExplorer .itemContainer .meshTools .visibility{grid-column:4}#sceneExplorer .itemContainer .meshTools .extensions{width:20px;grid-column:5}#sceneExplorer .itemContainer .cameraTools{grid-column:2;display:grid;grid-template-columns:1fr 20px 20px auto 5px;align-items:center}#sceneExplorer .itemContainer .cameraTools .activeCamera{grid-column:2}#sceneExplorer .itemContainer .cameraTools .enableGizmo{grid-column:3}#sceneExplorer .itemContainer .cameraTools .extensions{width:20px;grid-column:4}#sceneExplorer .itemContainer .lightTools{grid-column:2;display:grid;grid-template-columns:1fr 20px 20px auto 5px;align-items:center}#sceneExplorer .itemContainer .lightTools .visibility{grid-column:2}#sceneExplorer .itemContainer .lightTools .enableGizmo{grid-column:3}#sceneExplorer .itemContainer .lightTools .extensions{width:20px;grid-column:4}#sceneExplorer .itemContainer .spriteTools{grid-column:2;display:grid;grid-template-columns:1fr auto 5px;align-items:center}#sceneExplorer .itemContainer .spriteTools .extensions{width:20px;grid-column:2}#sceneExplorer .itemContainer .spriteManagerTools{grid-column:2;display:grid;grid-template-columns:1fr auto 5px;align-items:center}#sceneExplorer .itemContainer .spriteManagerTools .extensions{width:20px;grid-column:2}#sceneExplorer .itemContainer .materialTools{grid-column:2;display:grid;grid-template-columns:1fr auto 5px;align-items:center}#sceneExplorer .itemContainer .materialTools .extensions{width:20px;grid-column:2}#sceneExplorer .itemContainer .materialTools .icon{display:grid;align-items:center;justify-items:center;cursor:pointer}#sceneExplorer .itemContainer .particleSystemTools{grid-column:2;display:grid;grid-template-columns:1fr auto 5px;align-items:center}#sceneExplorer .itemContainer .particleSystemTools .extensions{width:20px;grid-column:2}#sceneExplorer .itemContainer .effectLayerTools{grid-column:2;display:grid;grid-template-columns:1fr auto 5px;align-items:center}#sceneExplorer .itemContainer .effectLayerTools .extensions{width:20px;grid-column:2}#sceneExplorer .itemContainer .postProcessTools{grid-column:2;display:grid;grid-template-columns:1fr auto 5px;align-items:center}#sceneExplorer .itemContainer .postProcessTools .extensions{width:20px;grid-column:2}#sceneExplorer .itemContainer .renderingPipelineTools{grid-column:2;display:grid;grid-template-columns:1fr auto 5px;align-items:center}#sceneExplorer .itemContainer .renderingPipelineTools .extensions{width:20px;grid-column:2}#sceneExplorer .itemContainer .textureTools{grid-column:2;display:grid;grid-template-columns:1fr auto 5px;align-items:center}#sceneExplorer .itemContainer .textureTools .extensions{width:20px;grid-column:2}#sceneExplorer .itemContainer .adtextureTools{grid-column:2;display:grid;grid-template-columns:1fr 20px 20px auto 5px;align-items:center}#sceneExplorer .itemContainer .adtextureTools .edit{grid-column:2}#sceneExplorer .itemContainer .adtextureTools .pickingMode{grid-column:3;opacity:.6}#sceneExplorer .itemContainer .adtextureTools .pickingMode.selected{opacity:1}#sceneExplorer .itemContainer .adtextureTools .extensions{width:20px;grid-column:3}#sceneExplorer .itemContainer .controlTools{grid-column:2;display:grid;grid-template-columns:1fr 20px 20px auto 5px;align-items:center}#sceneExplorer .itemContainer .controlTools .highlight{grid-column:2}#sceneExplorer .itemContainer .controlTools .visibility{grid-column:3}#sceneExplorer .itemContainer .controlTools .extensions{width:20px;grid-column:4}#sceneExplorer .itemContainer .transformNodeTools{grid-column:2;display:grid;grid-template-columns:1fr auto 5px;align-items:center}#sceneExplorer .itemContainer .transformNodeTools .extensions{width:20px;grid-column:2}#sceneExplorer .itemContainer .skeletonTools{grid-column:2;display:grid;grid-template-columns:1fr auto 5px;align-items:center}#sceneExplorer .itemContainer .skeletonTools .extensions{width:20px;grid-column:2}#sceneExplorer .itemContainer .title{grid-column:1;background:rgba(0,0,0,0);white-space:nowrap;overflow:hidden;min-width:0;margin-right:5px;display:grid;align-items:center;grid-template-columns:25px 1fr;height:24px;cursor:pointer}#sceneExplorer .itemContainer .title .titleIcon{grid-column:1;display:grid;align-items:center;justify-items:center}#sceneExplorer .itemContainer .title .titleText{grid-column:2;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}',"",{version:3,sources:["webpack://./../../../dev/inspector/dist/components/sceneExplorer/sceneExplorer.scss"],names:[],mappings:"AAAA,qBACI,iBAAA,CACA,QAAA,CACA,OAAA,CACA,UAAA,CAEA,2BACI,YAAA,CAIR,oBACI,YAAA,CAGJ,cACI,eAAA,CAEA,sCACI,YAAA,CACA,cAAA,CAEA,4CACI,eAAA,CAKZ,2DACI,UAAA,CACA,kBAAA,CAGJ,eACI,eAAA,CACA,WAAA,CACA,QAAA,CACA,SAAA,CACA,YAAA,CACA,2BAAA,CACA,iBAAA,CAEA,qBACI,YAAA,CAGJ,uBACI,WAAA,CACA,cAAA,CACA,UAAA,CACA,eAAA,CACA,UAAA,CACA,iBAAA,CACA,YAAA,CACA,mCAAA,CACA,gBAAA,CAEA,6BACI,iBAAA,CACA,aAAA,CACA,UAAA,CACA,WAAA,CACA,MAAA,CACA,YAAA,CACA,iBAAA,CACA,mBAAA,CAGJ,8BACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,iBAAA,CAGJ,iCACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,6BAAA,CAEA,yCACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CAGJ,wCACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CAKZ,qBACI,UAAA,CAEA,iBAAA,CACA,eAAA,CAGJ,uBACI,YAAA,CACA,mBAAA,CAEA,6BACI,UAAA,CACA,yBAAA,CACA,aAAA,CACA,WAAA,CACA,SAAA,CACA,+BAAA,CACA,uFAAA,CACA,6BAAA,CACA,2BAAA,CACA,2BAAA,CACA,UAAA,CAGJ,0CACI,aAAA,CAGJ,mCACI,eAAA,CACA,YAAA,CACA,uBAAA,CAIR,+BACI,eAAA,CACA,UAAA,CACA,cAAA,CACA,iBAAA,CACA,WAAA,CAEA,gBAAA,CAEA,iBAAA,CACA,YAAA,CACA,kBAAA,CAEA,qCACI,eAAA,CAGJ,iDACI,YAAA,CACA,8BAAA,CAEA,uDACI,aAAA,CACA,YAAA,CACA,8BAAA,CAEA,8DACI,aAAA,CACA,eAAA,CACA,UAAA,CACA,cAAA,CACA,oBAAA,CACA,gBAAA,CACA,UAAA,CAGJ,mEACI,aAAA,CACA,YAAA,CACA,kBAAA,CAIR,4DACI,UAAA,CACA,aAAA,CACA,iBAAA,CAKZ,qBACI,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CAGJ,8BACI,eAAA,CACA,UAAA,CACA,cAAA,CACA,iBAAA,CACA,WAAA,CACA,gBAAA,CACA,YAAA,CACA,8BAAA,CAEA,oCACI,eAAA,CAGJ,uCACI,eAAA,CACA,UAAA,CAGJ,2CACI,UAAA,CAGJ,qCACI,aAAA,CACA,UAAA,CACA,UAAA,CAGJ,qCACI,WAAA,CACA,iBAAA,CACA,qBAAA,CACA,UAAA,CACA,mCAAA,CACA,iBAAA,CACA,SAAA,CACA,kBAAA,CACA,qBAAA,CAEA,0CACI,kBAAA,CAGJ,2CACI,YAAA,CAGJ,gDACI,wBAAA,CACA,eAAA,CACA,kBAAA,CACA,sBAAA,CACA,WAAA,CAEA,sDACI,eAAA,CACA,UAAA,CAKZ,yCACI,aAAA,CACA,iBAAA,CACA,YAAA,CACA,qEAAA,CACA,kBAAA,CACA,cAAA,CAEA,qDACI,aAAA,CACA,gBAAA,CACA,YAAA,CACA,kBAAA,CACA,WAAA,CAGJ,sDACI,aAAA,CACA,UAAA,CAEA,+DACI,SAAA,CAIR,mDACI,aAAA,CACA,UAAA,CAEA,4DACI,SAAA,CAIR,kDACI,aAAA,CACA,UAAA,CACA,2DACI,SAAA,CAIR,mDACI,aAAA,CACA,UAAA,CACA,4DACI,SAAA,CAIR,oDACI,aAAA,CACA,eAAA,CACA,SAAA,CACA,YAAA,CACA,kBAAA,CACA,WAAA,CACA,6BAAA,CAGJ,sDACI,aAAA,CACA,UAAA,CAEA,+DACI,SAAA,CAIR,sDACI,aAAA,CACA,UAAA,CAEA,+DACI,SAAA,CAIR,kDACI,aAAA,CAGJ,qDACI,UAAA,CACA,cAAA,CAIR,sDACI,aAAA,CACA,UAAA,CACA,YAAA,CACA,kCAAA,CACA,kBAAA,CACA,WAAA,CAEA,kEACI,UAAA,CACA,aAAA,CAIR,mDACI,aAAA,CACA,UAAA,CACA,YAAA,CACA,kCAAA,CACA,kBAAA,CACA,WAAA,CAEA,+DACI,UAAA,CACA,aAAA,CAIR,0CACI,aAAA,CACA,UAAA,CACA,YAAA,CACA,kCAAA,CACA,kBAAA,CACA,WAAA,CAEA,sDACI,UAAA,CACA,aAAA,CAIR,yCACI,aAAA,CACA,UAAA,CACA,YAAA,CACA,iDAAA,CACA,kBAAA,CACA,WAAA,CAEA,+CACI,UAAA,CACA,aAAA,CAGJ,uDACI,aAAA,CACA,UAAA,CAEA,gEACI,SAAA,CAIR,qDACI,aAAA,CAGJ,qDACI,UAAA,CACA,aAAA,CAIR,2CACI,aAAA,CACA,YAAA,CACA,4CAAA,CACA,kBAAA,CAEA,yDACI,aAAA,CAGJ,wDACI,aAAA,CAGJ,uDACI,UAAA,CACA,aAAA,CAIR,0CACI,aAAA,CACA,YAAA,CACA,4CAAA,CACA,kBAAA,CAEA,sDACI,aAAA,CAGJ,uDACI,aAAA,CAGJ,sDACI,UAAA,CACA,aAAA,CAIR,2CACI,aAAA,CACA,YAAA,CACA,kCAAA,CACA,kBAAA,CAEA,uDACI,UAAA,CACA,aAAA,CAIR,kDACI,aAAA,CACA,YAAA,CACA,kCAAA,CACA,kBAAA,CAEA,8DACI,UAAA,CACA,aAAA,CAIR,6CACI,aAAA,CACA,YAAA,CACA,kCAAA,CACA,kBAAA,CAEA,yDACI,UAAA,CACA,aAAA,CAGJ,mDACI,YAAA,CACA,kBAAA,CACA,oBAAA,CACA,cAAA,CAIR,mDACI,aAAA,CACA,YAAA,CACA,kCAAA,CACA,kBAAA,CAEA,+DACI,UAAA,CACA,aAAA,CAIR,gDACI,aAAA,CACA,YAAA,CACA,kCAAA,CACA,kBAAA,CAEA,4DACI,UAAA,CACA,aAAA,CAIR,gDACI,aAAA,CACA,YAAA,CACA,kCAAA,CACA,kBAAA,CAEA,4DACI,UAAA,CACA,aAAA,CAIR,sDACI,aAAA,CACA,YAAA,CACA,kCAAA,CACA,kBAAA,CAEA,kEACI,UAAA,CACA,aAAA,CAIR,4CACI,aAAA,CACA,YAAA,CACA,kCAAA,CACA,kBAAA,CAEA,wDACI,UAAA,CACA,aAAA,CAIR,8CACI,aAAA,CACA,YAAA,CACA,4CAAA,CACA,kBAAA,CAEA,oDACI,aAAA,CAGJ,2DACI,aAAA,CACA,UAAA,CAEA,oEACI,SAAA,CAIR,0DACI,UAAA,CACA,aAAA,CAIR,4CACI,aAAA,CACA,YAAA,CACA,4CAAA,CACA,kBAAA,CAEA,uDACI,aAAA,CAGJ,wDACI,aAAA,CAGJ,wDACI,UAAA,CACA,aAAA,CAIR,kDACI,aAAA,CACA,YAAA,CACA,kCAAA,CACA,kBAAA,CAEA,8DACI,UAAA,CACA,aAAA,CAIR,6CACI,aAAA,CACA,YAAA,CACA,kCAAA,CACA,kBAAA,CAEA,yDACI,UAAA,CACA,aAAA,CAIR,qCACI,aAAA,CACA,wBAAA,CACA,kBAAA,CACA,eAAA,CACA,WAAA,CACA,gBAAA,CACA,YAAA,CACA,kBAAA,CACA,8BAAA,CACA,WAAA,CACA,cAAA,CAEA,gDACI,aAAA,CACA,YAAA,CACA,kBAAA,CACA,oBAAA,CAGJ,gDACI,aAAA,CACA,kBAAA,CACA,sBAAA,CACA,eAAA",sourceRoot:""}]),a.locals={};const i=a},5228:(e,t,s)=>{"use strict";s.d(t,{A:()=>i});var r=s(3234),n=s.n(r),o=s(7474),a=s.n(o)()(n());a.push([e.id,'.color-picker-container{width:320px;height:300px;background-color:#fff;display:grid;grid-template-columns:100%;grid-template-rows:50% 50px 60px 40px 1fr auto;font-family:"acumin-pro-condensed";font-weight:normal;font-size:14px}.color-picker-container.with-hints{height:380px}.color-picker-container .color-picker-saturation{grid-row:1;grid-column:1;display:grid;grid-template-columns:100%;grid-template-rows:100%;position:relative;cursor:pointer}.color-picker-container .color-picker-saturation .color-picker-saturation-white{grid-row:1;grid-column:1;background:linear-gradient(to right, #fff, rgba(255, 255, 255, 0))}.color-picker-container .color-picker-saturation .color-picker-saturation-black{grid-row:1;grid-column:1;background:linear-gradient(to top, #000, rgba(0, 0, 0, 0))}.color-picker-container .color-picker-saturation .color-picker-saturation-cursor{pointer-events:none;width:4px;height:4px;box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px rgba(0,0,0,.3),0 0 1px 2px rgba(0,0,0,.4);border-radius:50%;transform:translate(-2px, -2px);position:absolute}.color-picker-container .color-picker-hue{grid-row:2;grid-column:1;display:grid;margin:10px;grid-template-columns:24% 76%;grid-template-rows:100%}.color-picker-container .color-picker-hue .color-picker-hue-color{grid-row:1;grid-column:1;align-self:center;justify-self:center;width:30px;height:30px;border-radius:15px;border:1px solid #000}.color-picker-container .color-picker-hue .color-picker-hue-slider{grid-row:1;grid-column:2;align-self:center;height:16px;position:relative;cursor:pointer;background:linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)}.color-picker-container .color-picker-hue .color-picker-hue-slider .color-picker-hue-cursor{pointer-events:none;width:8px;height:18px;transform:translate(-4px, -2px);background-color:#f8f8f8;box-shadow:0 1px 4px 0 rgba(0,0,0,.37);position:absolute}.color-picker-container .color-picker-component{display:grid;margin:5px;grid-template-columns:100%;grid-template-rows:50% 50%}.color-picker-container .color-picker-component .color-picker-component-value{justify-self:center;align-self:center;grid-row:1;grid-column:1;margin-bottom:4px}.color-picker-container .color-picker-component .color-picker-component-value input{width:50px}.color-picker-container .color-picker-component .color-picker-component-label{justify-self:center;align-self:center;grid-row:2;grid-column:1;color:#000}.color-picker-container .color-picker-rgb{grid-row:3;grid-column:1;display:grid;margin:10px;grid-template-columns:20% 6.66% 20% 6.66% 20% 6.66% 20%;grid-template-rows:100%}.color-picker-container .red{grid-row:1;grid-column:1}.color-picker-container .green{grid-row:1;grid-column:3}.color-picker-container .blue{grid-row:1;grid-column:5}.color-picker-container .alpha{grid-row:1;grid-column:7}.color-picker-container .alpha.grayed{opacity:.5}.color-picker-container .color-picker-hex{grid-row:4;grid-column:1;display:grid;grid-template-columns:20% 80%;grid-template-rows:100%}.color-picker-container .color-picker-hex .color-picker-hex-label{justify-self:center;align-self:center;grid-row:1;grid-column:1;margin-left:10px;color:#000}.color-picker-container .color-picker-hex .color-picker-hex-value{justify-self:left;align-self:center;grid-row:1;grid-column:2;margin-left:10px;margin-right:10px}.color-picker-container .color-picker-hex .color-picker-hex-value input{width:70px}.color-picker-container .color-picker-warning{color:#000;font-size:11px;padding:4px;justify-self:left;align-self:center;grid-row:6;grid-column:1}',"",{version:3,sources:["webpack://./../../../dev/sharedUiComponents/dist/colorPicker/colorPicker.scss"],names:[],mappings:"AAAA,wBACI,WAAA,CACA,YAAA,CACA,qBAAA,CACA,YAAA,CACA,0BAAA,CACA,8CAAA,CACA,kCAAA,CACA,kBAAA,CACA,cAAA,CAEA,mCACI,YAAA,CAGJ,iDACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,0BAAA,CACA,uBAAA,CACA,iBAAA,CACA,cAAA,CAEA,gFACI,UAAA,CACA,aAAA,CAEA,kEAAA,CAGJ,gFACI,UAAA,CACA,aAAA,CAEA,0DAAA,CAGJ,iFACI,mBAAA,CACA,SAAA,CACA,UAAA,CACA,uFACI,CAGJ,iBAAA,CACA,+BAAA,CACA,iBAAA,CAIR,0CACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,WAAA,CACA,6BAAA,CACA,uBAAA,CAEA,kEACI,UAAA,CACA,aAAA,CACA,iBAAA,CACA,mBAAA,CACA,UAAA,CACA,WAAA,CACA,kBAAA,CACA,qBAAA,CAGJ,mEACI,UAAA,CACA,aAAA,CACA,iBAAA,CACA,WAAA,CACA,iBAAA,CACA,cAAA,CAEA,0GAAA,CAEA,4FACI,mBAAA,CACA,SAAA,CACA,WAAA,CACA,+BAAA,CACA,wBAAA,CACA,sCAAA,CACA,iBAAA,CAKZ,gDACI,YAAA,CACA,UAAA,CACA,0BAAA,CACA,0BAAA,CAEA,8EACI,mBAAA,CACA,iBAAA,CACA,UAAA,CACA,aAAA,CACA,iBAAA,CAEA,oFACI,UAAA,CAIR,8EACI,mBAAA,CACA,iBAAA,CACA,UAAA,CACA,aAAA,CACA,UAAA,CAIR,0CACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,WAAA,CACA,uDAAA,CACA,uBAAA,CAGJ,6BACI,UAAA,CACA,aAAA,CAGJ,+BACI,UAAA,CACA,aAAA,CAGJ,8BACI,UAAA,CACA,aAAA,CAGJ,+BACI,UAAA,CACA,aAAA,CAEA,sCACI,UAAA,CAIR,0CACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,6BAAA,CACA,uBAAA,CAEA,kEACI,mBAAA,CACA,iBAAA,CACA,UAAA,CACA,aAAA,CACA,gBAAA,CACA,UAAA,CAGJ,kEACI,iBAAA,CACA,iBAAA,CACA,UAAA,CACA,aAAA,CACA,gBAAA,CACA,iBAAA,CAEA,wEACI,UAAA,CAKZ,8CACI,UAAA,CACA,cAAA,CACA,WAAA,CACA,iBAAA,CACA,iBAAA,CACA,UAAA,CACA,aAAA",sourceRoot:""}]),a.locals={};const i=a},7474:e=>{"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var s="",r=void 0!==t[5];return t[4]&&(s+="@supports (".concat(t[4],") {")),t[2]&&(s+="@media ".concat(t[2]," {")),r&&(s+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),s+=e(t),r&&(s+="}"),t[2]&&(s+="}"),t[4]&&(s+="}"),s})).join("")},t.i=function(e,s,r,n,o){"string"==typeof e&&(e=[[null,e,void 0]]);var a={};if(r)for(var i=0;i0?" ".concat(c[5]):""," {").concat(c[1],"}")),c[5]=o),s&&(c[2]?(c[1]="@media ".concat(c[2]," {").concat(c[1],"}"),c[2]=s):c[2]=s),n&&(c[4]?(c[1]="@supports (".concat(c[4],") {").concat(c[1],"}"),c[4]=n):c[4]="".concat(n)),t.push(c))}},t}},1721:e=>{"use strict";e.exports=function(e,t){return t||(t={}),e?(e=String(e.__esModule?e.default:e),/^['"].*['"]$/.test(e)&&(e=e.slice(1,-1)),t.hash&&(e+=t.hash),/["'() \t\n]|(%20)/.test(e)||t.needQuotes?'"'.concat(e.replace(/"/g,'\\"').replace(/\n/g,"\\n"),'"'):e):e}},3234:e=>{"use strict";e.exports=function(e){var t=e[1],s=e[3];if(!s)return t;if("function"==typeof btoa){var r=btoa(unescape(encodeURIComponent(JSON.stringify(s)))),n="sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(r),o="/*# ".concat(n," */");return[t].concat([o]).join("\n")}return[t].join("\n")}},1684:function(e){e.exports=function(e){function t(r){if(s[r])return s[r].exports;var n=s[r]={exports:{},id:r,loaded:!1};return e[r].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var s={};return t.m=e,t.c=s,t.p="",t(0)}([function(e,t,s){var r,n,o={}.hasOwnProperty,a=[].indexOf||function(e){for(var t=0,s=this.length;t0&&s.data&&(this.groups.has(s.data)?this.groups.get(s.data).push(n):this.groups.set(s.data,[n])),this.frames.push(s)},t.prototype.render=function(){var e,t,s;if(this.running)throw new Error("Already running");if(null==this.options.width||null==this.options.height)throw new Error("Width and height must be set prior to rendering");if(this.running=!0,this.nextFrame=0,this.finishedFrames=0,this.imageParts=function(){var e,t,s;for(s=[],e=0,t=this.frames.length;0<=t?et;0<=t?++e:--e)s.push(null);return s}.call(this),t=this.spawnWorkers(),!0===this.options.globalPalette)this.renderNextFrame();else for(e=0,s=t;0<=s?es;0<=s?++e:--e)this.renderNextFrame();return this.emit("start"),this.emit("progress",0)},t.prototype.abort=function(){for(var e;null!=(e=this.activeWorkers.shift());)this.log("killing active worker"),e.terminate();return this.running=!1,this.emit("abort")},t.prototype.spawnWorkers=function(){var e,t,s;return e=Math.min(this.options.workers,this.frames.length),function(){s=[];for(var r=t=this.freeWorkers.length;t<=e?re;t<=e?r++:r--)s.push(r);return s}.apply(this).forEach(function(e){return function(t){var s;return e.log("spawning worker "+t),(s=new Worker(e.options.workerScript)).onmessage=function(t){return e.activeWorkers.splice(e.activeWorkers.indexOf(s),1),e.freeWorkers.push(s),e.frameFinished(t.data,!1)},e.freeWorkers.push(s)}}(this)),e},t.prototype.frameFinished=function(e,t){var s,r,n,o;if(this.finishedFrames++,t?(s=this.frames.indexOf(e),r=this.groups.get(e.data)[0],this.log("frame "+(s+1)+" is duplicate of "+r+" - "+this.activeWorkers.length+" active"),this.imageParts[s]={indexOfFirstInGroup:r}):(this.log("frame "+(e.index+1)+" finished - "+this.activeWorkers.length+" active"),this.emit("progress",this.finishedFrames/this.frames.length),this.imageParts[e.index]=e),!0===this.options.globalPalette&&!t&&(this.options.globalPalette=e.globalPalette,this.log("global palette analyzed"),this.frames.length>2))for(n=1,o=this.freeWorkers.length;1<=o?no;1<=o?++n:--n)this.renderNextFrame();return a.call(this.imageParts,null)>=0?this.renderNextFrame():this.finishRendering()},t.prototype.finishRendering=function(){var e,t,s,r,n,o,a,i,l,p,c,d,h,u,b,A,m,g,C,f;for(n=o=0,p=(m=this.imageParts).length;o=this.frames.length))return e=this.frames[this.nextFrame++],(t=this.frames.indexOf(e))>0&&this.groups.has(e.data)&&this.groups.get(e.data)[0]!==t?void setTimeout(function(t){return function(){return t.frameFinished(e,!0)}}(this),0):(r=this.freeWorkers.shift(),s=this.getTask(e),this.log("starting frame "+(s.index+1)+" of "+this.frames.length),this.activeWorkers.push(r),r.postMessage(s))},t.prototype.getContextData=function(e){return e.getImageData(0,0,this.options.width,this.options.height).data},t.prototype.getImageData=function(e){var t;return null==this._canvas&&(this._canvas=document.createElement("canvas"),this._canvas.width=this.options.width,this._canvas.height=this.options.height),(t=this._canvas.getContext("2d")).setFill=this.options.background,t.fillRect(0,0,this.options.width,this.options.height),t.drawImage(e,0,0),this.getContextData(t)},t.prototype.getTask=function(e){var t,s;if(s={index:t=this.frames.indexOf(e),last:t===this.frames.length-1,delay:e.delay,transparent:e.transparent,width:this.options.width,height:this.options.height,quality:this.options.quality,dither:this.options.dither,globalPalette:this.options.globalPalette,repeat:this.options.repeat,canTransfer:!0},null!=e.data)s.data=e.data;else if(null!=e.context)s.data=this.getContextData(e.context);else{if(null==e.image)throw new Error("Invalid frame");s.data=this.getImageData(e.image)}return s},t.prototype.log=function(e){if(this.options.debug)return console.log(e)},t}(r),e.exports=n},function(e,t){function s(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function r(e){return"function"==typeof e}function n(e){return"object"==typeof e&&null!==e}function o(e){return void 0===e}e.exports=s,s.EventEmitter=s,s.prototype._events=void 0,s.prototype._maxListeners=void 0,s.defaultMaxListeners=10,s.prototype.setMaxListeners=function(e){if(!function(e){return"number"==typeof e}(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},s.prototype.emit=function(e){var t,s,a,i,l,p;if(this._events||(this._events={}),"error"===e&&(!this._events.error||n(this._events.error)&&!this._events.error.length)){if((t=arguments[1])instanceof Error)throw t;var c=new Error('Uncaught, unspecified "error" event. ('+t+")");throw c.context=t,c}if(o(s=this._events[e]))return!1;if(r(s))switch(arguments.length){case 1:s.call(this);break;case 2:s.call(this,arguments[1]);break;case 3:s.call(this,arguments[1],arguments[2]);break;default:i=Array.prototype.slice.call(arguments,1),s.apply(this,i)}else if(n(s))for(i=Array.prototype.slice.call(arguments,1),a=(p=s.slice()).length,l=0;l0&&this._events[e].length>a&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},s.prototype.on=s.prototype.addListener,s.prototype.once=function(e,t){function s(){this.removeListener(e,s),n||(n=!0,t.apply(this,arguments))}if(!r(t))throw TypeError("listener must be a function");var n=!1;return s.listener=t,this.on(e,s),this},s.prototype.removeListener=function(e,t){var s,o,a,i;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(a=(s=this._events[e]).length,o=-1,s===t||r(s.listener)&&s.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(n(s)){for(i=a;i-- >0;)if(s[i]===t||s[i].listener&&s[i].listener===t){o=i;break}if(o<0)return this;1===s.length?(s.length=0,delete this._events[e]):s.splice(o,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},s.prototype.removeAllListeners=function(e){var t,s;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(r(s=this._events[e]))this.removeListener(e,s);else if(s)for(;s.length;)this.removeListener(e,s[s.length-1]);return delete this._events[e],this},s.prototype.listeners=function(e){return this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},s.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(r(t))return 1;if(t)return t.length}return 0},s.listenerCount=function(e,t){return e.listenerCount(t)}},function(e,t){var s,r,n,o,a;a=navigator.userAgent.toLowerCase(),o=navigator.platform.toLowerCase(),n="ie"===(s=a.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/)||[null,"unknown",0])[1]&&document.documentMode,(r={name:"version"===s[1]?s[3]:s[1],version:n||parseFloat("opera"===s[1]&&s[4]?s[4]:s[2]),platform:{name:a.match(/ip(?:ad|od|hone)/)?"ios":(a.match(/(?:webos|android)/)||o.match(/mac|win|linux/)||["other"])[0]}})[r.name]=!0,r[r.name+parseInt(r.version,10)]=!0,r.platform[r.platform.name]=!0,e.exports=r}])},772:e=>{"use strict";var t=Object.getOwnPropertySymbols,s=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},s=0;s<10;s++)t["_"+String.fromCharCode(s)]=s;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,n){for(var o,a,i=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),l=1;l{"use strict";var r=s(8565);function n(){}function o(){}o.resetWarningCache=n,e.exports=function(){function e(e,t,s,n,o,a){if(a!==r){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function t(){return e}e.isRequired=e;var s={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:n};return s.PropTypes=s,s}},764:(e,t,s)=>{e.exports=s(878)()},8565:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},315:(e,t,s)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=function(e,t){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var s=l(t);if(s&&s.has(e))return s.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&Object.prototype.hasOwnProperty.call(e,a)){var i=o?Object.getOwnPropertyDescriptor(e,a):null;i&&(i.get||i.set)?Object.defineProperty(n,a,i):n[a]=e[a]}return n.default=e,s&&s.set(e,n),n}(s(7460)),o=i(s(764)),a=i(s(1122));function i(e){return e&&e.__esModule?e:{default:e}}function l(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,s=new WeakMap;return(l=function(e){return e?s:t})(e)}function p(e,t){return p=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},p(e,t)}function c(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function d(e){return d=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},d(e)}function h(e,t,s){return t in e?Object.defineProperty(e,t,{value:s,enumerable:!0,configurable:!0,writable:!0}):e[t]=s,e}var u=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&p(e,t)}(l,e);var t,s,o,i=(s=l,o=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=d(s);if(o){var n=d(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return function(e,t){if(t&&("object"===r(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return c(e)}(this,e)});function l(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,l),h(c(t=i.call(this,e)),"handleKeyNavigation",(function(e){if(!1!==t.state.isVisible)switch(e.keyCode){case 37:case 27:e.preventDefault(),t.hideMenu(e);break;case 38:e.preventDefault(),t.selectChildren(!0);break;case 40:e.preventDefault(),t.selectChildren(!1);break;case 39:t.tryToOpenSubMenu(e);break;case 13:e.preventDefault(),t.tryToOpenSubMenu(e);var s=t.seletedItemRef&&t.seletedItemRef.props&&t.seletedItemRef.props.disabled;t.seletedItemRef&&t.seletedItemRef.ref instanceof HTMLElement&&!s?t.seletedItemRef.ref.click():t.hideMenu(e)}})),h(c(t),"handleForceClose",(function(){t.setState({forceSubMenuOpen:!1})})),h(c(t),"tryToOpenSubMenu",(function(e){t.state.selectedItem&&t.state.selectedItem.type===t.getSubMenuType()&&(e.preventDefault(),t.setState({forceSubMenuOpen:!0}))})),h(c(t),"selectChildren",(function(e){var s=t.state.selectedItem,r=[],o=0,i={};if(n.default.Children.forEach(t.props.children,(function e(s,l){s&&([a.default,t.getSubMenuType()].indexOf(s.type)<0?n.default.Children.forEach(s.props.children,e):s.props.divider||(s.props.disabled&&(++o,i[l]=!0),r.push(s)))})),o!==r.length){var l=function(t){var s=t;do{e?--s:++s,s<0?s=r.length-1:s>=r.length&&(s=0)}while(s!==t&&i[s]);return s===t?null:s}(r.indexOf(s));null!==l&&t.setState({selectedItem:r[l],forceSubMenuOpen:!1})}})),h(c(t),"onChildMouseMove",(function(e){t.state.selectedItem!==e&&t.setState({selectedItem:e,forceSubMenuOpen:!1})})),h(c(t),"onChildMouseLeave",(function(){t.setState({selectedItem:null,forceSubMenuOpen:!1})})),h(c(t),"renderChildren",(function(e){return n.default.Children.map(e,(function(e){var s={};return n.default.isValidElement(e)?[a.default,t.getSubMenuType()].indexOf(e.type)<0?(s.children=t.renderChildren(e.props.children),n.default.cloneElement(e,s)):(s.onMouseLeave=t.onChildMouseLeave.bind(c(t)),e.type===t.getSubMenuType()&&(s.forceOpen=t.state.forceSubMenuOpen&&t.state.selectedItem===e,s.forceClose=t.handleForceClose,s.parentKeyNavigationHandler=t.handleKeyNavigation),e.props.divider||t.state.selectedItem!==e?(s.onMouseMove=function(){return t.onChildMouseMove(e)},n.default.cloneElement(e,s)):(s.selected=!0,s.ref=function(e){t.seletedItemRef=e},n.default.cloneElement(e,s))):e}))})),t.seletedItemRef=null,t.state={selectedItem:null,forceSubMenuOpen:!1},t}return t=l,Object.defineProperty(t,"prototype",{writable:!1}),t}(n.Component);t.default=u,h(u,"propTypes",{children:o.default.node.isRequired})},6824:(e,t,s)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=u(s(7460)),o=u(s(764)),a=u(s(3368)),i=u(s(772)),l=u(s(9225)),p=u(s(315)),c=u(s(2349)),d=s(5451),h=s(3645);function u(e){return e&&e.__esModule?e:{default:e}}function b(e,t){for(var s=0;s0&&void 0!==arguments[0]?arguments[0]:0,s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r={top:s,left:e};if(!t.menu)return r;var n=window,o=n.innerWidth,a=n.innerHeight,i=t.menu.getBoundingClientRect();return s+i.height>a&&(r.top-=i.height),e+i.width>o&&(r.left-=i.width),r.top<0&&(r.top=i.height0&&void 0!==arguments[0]?arguments[0]:0,s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r={top:s,left:e};if(!t.menu)return r;var n=window,o=n.innerWidth,a=n.innerHeight,i=t.menu.getBoundingClientRect();return r.left=e-i.width,s+i.height>a&&(r.top-=i.height),r.left<0&&(r.left+=i.width),r.top<0&&(r.top=i.heighto&&(r.left=i.width{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=function(e,t){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var s=d(t);if(s&&s.has(e))return s.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&Object.prototype.hasOwnProperty.call(e,a)){var i=o?Object.getOwnPropertyDescriptor(e,a):null;i&&(i.get||i.set)?Object.defineProperty(n,a,i):n[a]=e[a]}return n.default=e,s&&s.set(e,n),n}(s(7460)),o=c(s(764)),a=c(s(3368)),i=c(s(772)),l=s(5451),p=s(3645);function c(e){return e&&e.__esModule?e:{default:e}}function d(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,s=new WeakMap;return(d=function(e){return e?s:t})(e)}function h(e,t){for(var s=0;s=0&&0===t.button&&(t.persist(),t.stopPropagation(),e.mouseDownTimeoutId=setTimeout((function(){return e.handleContextClick(t)}),e.props.holdToDisplay)),(0,p.callIfExists)(e.props.attributes.onMouseDown,t)})),m(b(e),"handleMouseUp",(function(t){0===t.button&&clearTimeout(e.mouseDownTimeoutId),(0,p.callIfExists)(e.props.attributes.onMouseUp,t)})),m(b(e),"handleMouseOut",(function(t){0===t.button&&clearTimeout(e.mouseDownTimeoutId),(0,p.callIfExists)(e.props.attributes.onMouseOut,t)})),m(b(e),"handleTouchstart",(function(t){e.touchHandled=!1,e.props.holdToDisplay>=0&&(t.persist(),t.stopPropagation(),e.touchstartTimeoutId=setTimeout((function(){e.handleContextClick(t),e.touchHandled=!0}),e.props.holdToDisplay)),(0,p.callIfExists)(e.props.attributes.onTouchStart,t)})),m(b(e),"handleTouchEnd",(function(t){e.touchHandled&&t.preventDefault(),clearTimeout(e.touchstartTimeoutId),(0,p.callIfExists)(e.props.attributes.onTouchEnd,t)})),m(b(e),"handleContextMenu",(function(t){t.button===e.props.mouseButton&&e.handleContextClick(t),(0,p.callIfExists)(e.props.attributes.onContextMenu,t)})),m(b(e),"handleMouseClick",(function(t){t.button===e.props.mouseButton&&e.handleContextClick(t),(0,p.callIfExists)(e.props.attributes.onClick,t)})),m(b(e),"handleContextClick",(function(t){if(!(e.props.disable||e.props.disableIfShiftIsPressed&&t.shiftKey)){t.preventDefault(),t.stopPropagation();var s=t.clientX||t.touches&&t.touches[0].pageX,r=t.clientY||t.touches&&t.touches[0].pageY;e.props.posX&&(s-=e.props.posX),e.props.posY&&(r-=e.props.posY),(0,l.hideMenu)();var n=(0,p.callIfExists)(e.props.collect,e.props),o={position:{x:s,y:r},target:e.elem,id:e.props.id};n&&"function"==typeof n.then?n.then((function(e){o.data=(0,i.default)({},e,{target:t.target}),(0,l.showMenu)(o)})):(o.data=(0,i.default)({},n,{target:t.target}),(0,l.showMenu)(o))}})),m(b(e),"elemRef",(function(t){e.elem=t})),e}return t=g,(s=[{key:"render",value:function(){var e=this.props,t=e.renderTag,s=e.attributes,r=e.children,o=(0,i.default)({},s,{className:(0,a.default)(p.cssClasses.menuWrapper,s.className),onContextMenu:this.handleContextMenu,onClick:this.handleMouseClick,onMouseDown:this.handleMouseDown,onMouseUp:this.handleMouseUp,onTouchStart:this.handleTouchstart,onTouchEnd:this.handleTouchEnd,onMouseOut:this.handleMouseOut,ref:this.elemRef});return n.default.createElement(t,o,r)}}])&&h(t.prototype,s),Object.defineProperty(t,"prototype",{writable:!1}),g}(n.Component);t.default=g,m(g,"propTypes",{id:o.default.string.isRequired,children:o.default.node.isRequired,attributes:o.default.object,collect:o.default.func,disable:o.default.bool,holdToDisplay:o.default.number,posX:o.default.number,posY:o.default.number,renderTag:o.default.elementType,mouseButton:o.default.number,disableIfShiftIsPressed:o.default.bool}),m(g,"defaultProps",{attributes:{},collect:function(){return null},disable:!1,holdToDisplay:1e3,renderTag:"div",posX:0,posY:0,mouseButton:2,disableIfShiftIsPressed:!1})},1122:(e,t,s)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=function(e,t){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var s=d(t);if(s&&s.has(e))return s.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&Object.prototype.hasOwnProperty.call(e,a)){var i=o?Object.getOwnPropertyDescriptor(e,a):null;i&&(i.get||i.set)?Object.defineProperty(n,a,i):n[a]=e[a]}return n.default=e,s&&s.set(e,n),n}(s(7460)),o=c(s(764)),a=c(s(3368)),i=c(s(772)),l=s(5451),p=s(3645);function c(e){return e&&e.__esModule?e:{default:e}}function d(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,s=new WeakMap;return(d=function(e){return e?s:t})(e)}function h(){return h=Object.assign||function(e){for(var t=1;t{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=h(s(7460)),o=h(s(764)),a=h(s(3368)),i=h(s(772)),l=s(5451),p=h(s(315)),c=s(3645),d=h(s(9225));function h(e){return e&&e.__esModule?e:{default:e}}function u(){return u=Object.assign||function(e){for(var t=1;tr?o.bottom=0:o.top=0,n.righte?r.bottom=0:r.top=0,s.left<0?r.left="100%":r.right="100%",r})),C(m(t),"hideMenu",(function(e){e.preventDefault(),t.hideSubMenu(e)})),C(m(t),"hideSubMenu",(function(e){e.detail&&e.detail.id&&t.menu&&e.detail.id!==t.menu.id||(t.props.forceOpen&&t.props.forceClose(),t.setState({visible:!1,selectedItem:null}),t.unregisterHandlers())})),C(m(t),"handleClick",(function(e){e.preventDefault(),t.props.disabled||((0,c.callIfExists)(t.props.onClick,e,(0,i.default)({},t.props.data,c.store.data),c.store.target),t.props.onClick&&!t.props.preventCloseOnClick&&(0,l.hideMenu)())})),C(m(t),"handleMouseEnter",(function(){t.closetimer&&clearTimeout(t.closetimer),t.props.disabled||t.state.visible||(t.opentimer=setTimeout((function(){return t.setState({visible:!0,selectedItem:null})}),t.props.hoverDelay))})),C(m(t),"handleMouseLeave",(function(){t.opentimer&&clearTimeout(t.opentimer),t.state.visible&&(t.closetimer=setTimeout((function(){return t.setState({visible:!1,selectedItem:null})}),t.props.hoverDelay))})),C(m(t),"menuRef",(function(e){t.menu=e})),C(m(t),"subMenuRef",(function(e){t.subMenu=e})),C(m(t),"registerHandlers",(function(){document.removeEventListener("keydown",t.props.parentKeyNavigationHandler),document.addEventListener("keydown",t.handleKeyNavigation)})),C(m(t),"unregisterHandlers",(function(e){document.removeEventListener("keydown",t.handleKeyNavigation),e||document.addEventListener("keydown",t.props.parentKeyNavigationHandler)})),t.state=(0,i.default)({},t.state,{visible:!1}),t}return t=f,(s=[{key:"componentDidMount",value:function(){this.listenId=d.default.register((function(){}),this.hideSubMenu)}},{key:"getSubMenuType",value:function(){return f}},{key:"shouldComponentUpdate",value:function(e,t){return this.isVisibilityChange=!(this.state.visible===t.visible&&this.props.forceOpen===e.forceOpen||this.state.visible&&e.forceOpen||this.props.forceOpen&&t.visible),!0}},{key:"componentDidUpdate",value:function(){var e=this;this.isVisibilityChange&&(this.props.forceOpen||this.state.visible?(window.requestAnimationFrame||setTimeout)((function(){var t=e.props.rtl?e.getRTLMenuPosition():e.getMenuPosition();e.subMenu.style.removeProperty("top"),e.subMenu.style.removeProperty("bottom"),e.subMenu.style.removeProperty("left"),e.subMenu.style.removeProperty("right"),(0,c.hasOwnProp)(t,"top")&&(e.subMenu.style.top=t.top),(0,c.hasOwnProp)(t,"left")&&(e.subMenu.style.left=t.left),(0,c.hasOwnProp)(t,"bottom")&&(e.subMenu.style.bottom=t.bottom),(0,c.hasOwnProp)(t,"right")&&(e.subMenu.style.right=t.right),e.subMenu.classList.add(c.cssClasses.menuVisible),e.registerHandlers(),e.setState({selectedItem:null})})):(this.subMenu.addEventListener("transitionend",(function t(){e.subMenu.removeEventListener("transitionend",t),e.subMenu.style.removeProperty("bottom"),e.subMenu.style.removeProperty("right"),e.subMenu.style.top=0,e.subMenu.style.left="100%",e.unregisterHandlers()})),this.subMenu.classList.remove(c.cssClasses.menuVisible)))}},{key:"componentWillUnmount",value:function(){this.listenId&&d.default.unregister(this.listenId),this.opentimer&&clearTimeout(this.opentimer),this.closetimer&&clearTimeout(this.closetimer),this.unregisterHandlers(!0)}},{key:"render",value:function(){var e,t=this.props,s=t.children,r=t.attributes,o=t.disabled,i=t.title,l=t.selected,p=this.state.visible,d={ref:this.menuRef,onMouseEnter:this.handleMouseEnter,onMouseLeave:this.handleMouseLeave,className:(0,a.default)(c.cssClasses.menuItem,c.cssClasses.subMenu,r.listClassName),style:{position:"relative"}},h={className:(0,a.default)(c.cssClasses.menuItem,r.className,(e={},C(e,(0,a.default)(c.cssClasses.menuItemDisabled,r.disabledClassName),o),C(e,(0,a.default)(c.cssClasses.menuItemActive,r.visibleClassName),p),C(e,(0,a.default)(c.cssClasses.menuItemSelected,r.selectedClassName),l),e)),onMouseMove:this.props.onMouseMove,onMouseOut:this.props.onMouseOut,onClick:this.handleClick},b={ref:this.subMenuRef,style:{position:"absolute",transition:"opacity 1ms",top:0,left:"100%"},className:(0,a.default)(c.cssClasses.menu,this.props.className)};return n.default.createElement("nav",u({},d,{role:"menuitem",tabIndex:"-1","aria-haspopup":"true"}),n.default.createElement("div",u({},r,h),i),n.default.createElement("nav",u({},b,{role:"menu",tabIndex:"-1"}),this.renderChildren(s)))}}])&&b(t.prototype,s),Object.defineProperty(t,"prototype",{writable:!1}),f}(p.default);t.default=f,C(f,"propTypes",{children:o.default.node.isRequired,attributes:o.default.object,title:o.default.node.isRequired,className:o.default.string,disabled:o.default.bool,hoverDelay:o.default.number,rtl:o.default.bool,selected:o.default.bool,onMouseMove:o.default.func,onMouseOut:o.default.func,forceOpen:o.default.bool,forceClose:o.default.func,parentKeyNavigationHandler:o.default.func}),C(f,"defaultProps",{disabled:!1,hoverDelay:500,attributes:{},className:"",rtl:!1,selected:!1,onMouseMove:function(){return null},onMouseOut:function(){return null},forceOpen:!1,forceClose:function(){return null},parentKeyNavigationHandler:function(){return null}})},5451:(e,t,s)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.MENU_SHOW=t.MENU_HIDE=void 0,t.dispatchGlobalEvent=l,t.hideMenu=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0;l(i,(0,n.default)({},e,{type:i}),t)},t.showMenu=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0;l(a,(0,n.default)({},e,{type:a}),t)};var r,n=(r=s(772))&&r.__esModule?r:{default:r},o=s(3645),a="REACT_CONTEXTMENU_SHOW";t.MENU_SHOW=a;var i="REACT_CONTEXTMENU_HIDE";function l(e,t){var s,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:window;"function"==typeof window.CustomEvent?s=new window.CustomEvent(e,{detail:t}):(s=document.createEvent("CustomEvent")).initCustomEvent(e,!1,!0,t),r&&(r.dispatchEvent(s),(0,n.default)(o.store,t))}t.MENU_HIDE=i},857:(e,t,s)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return function(t){return function(s){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&d(e,t)}(C,s);var o,i,l,A,m=(o=C,i=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=u(o);if(i){var s=u(this).constructor;e=Reflect.construct(t,arguments,s)}else e=t.apply(this,arguments);return function(e,t){if(t&&("object"===r(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return h(e)}(this,e)});function C(t){var s;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,C),b(h(s=m.call(this,t)),"handleShow",(function(t){if(t.detail.id===e){var r=t.detail.data,n={};for(var o in r)g.includes(o)||(n[o]=r[o]);s.setState({trigger:n})}})),b(h(s),"handleHide",(function(){s.setState({trigger:null})})),s.state={trigger:null},s}return l=C,(A=[{key:"componentDidMount",value:function(){this.listenId=a.default.register(this.handleShow,this.handleHide)}},{key:"componentWillUnmount",value:function(){this.listenId&&a.default.unregister(this.listenId)}},{key:"render",value:function(){return n.default.createElement(t,p({},this.props,{id:e,trigger:this.state.trigger}))}}])&&c(l.prototype,A),Object.defineProperty(l,"prototype",{writable:!1}),C}(n.Component)}};var n=function(e,t){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var s=l(t);if(s&&s.has(e))return s.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&Object.prototype.hasOwnProperty.call(e,a)){var i=o?Object.getOwnPropertyDescriptor(e,a):null;i&&(i.get||i.set)?Object.defineProperty(n,a,i):n[a]=e[a]}return n.default=e,s&&s.set(e,n),n}(s(7460)),o=i(s(774)),a=i(s(9225));function i(e){return e&&e.__esModule?e:{default:e}}function l(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,s=new WeakMap;return(l=function(e){return e?s:t})(e)}function p(){return p=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var s=0,r=new Array(t);s{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=s(5451),n=s(3645);function o(e,t){for(var s=0;s{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.callIfExists=function(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),r=1;r{"use strict";Object.defineProperty(t,"tz",{enumerable:!0,get:function(){return r.default}}),Object.defineProperty(t,"Rc",{enumerable:!0,get:function(){return n.default}}),Object.defineProperty(t,"Dr",{enumerable:!0,get:function(){return o.default}});var r=a(s(6824)),n=a(s(774)),o=a(s(1122));a(s(2349)),a(s(857)),s(5451);function a(e){return e&&e.__esModule?e:{default:e}}},3903:(e,t,s)=>{"use strict";var r=s(7460),n=s(772),o=s(9798);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,s=1;s