ngx-spine
Version:
[](https://travis-ci.org/PoiScript/ngx-spine)
472 lines • 42.3 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { FakeTexture } from "./Texture";
import { TextureAtlas } from "./TextureAtlas";
export class AssetManager {
/**
* @param {?} textureLoader
* @param {?=} pathPrefix
*/
constructor(textureLoader, pathPrefix = "") {
this.assets = {};
this.errors = {};
this.toLoad = 0;
this.loaded = 0;
this.textureLoader = textureLoader;
this.pathPrefix = pathPrefix;
}
/**
* @private
* @param {?} url
* @param {?} success
* @param {?} error
* @return {?}
*/
static downloadText(url, success, error) {
/** @type {?} */
let request = new XMLHttpRequest();
request.open("GET", url, true);
request.onload = (/**
* @return {?}
*/
() => {
if (request.status == 200) {
success(request.responseText);
}
else {
error(request.status, request.responseText);
}
});
request.onerror = (/**
* @return {?}
*/
() => {
error(request.status, request.responseText);
});
request.send();
}
/**
* @private
* @param {?} url
* @param {?} success
* @param {?} error
* @return {?}
*/
static downloadBinary(url, success, error) {
/** @type {?} */
let request = new XMLHttpRequest();
request.open("GET", url, true);
request.responseType = "arraybuffer";
request.onload = (/**
* @return {?}
*/
() => {
if (request.status == 200) {
success(new Uint8Array((/** @type {?} */ (request.response))));
}
else {
error(request.status, request.responseText);
}
});
request.onerror = (/**
* @return {?}
*/
() => {
error(request.status, request.responseText);
});
request.send();
}
/**
* @param {?} path
* @param {?=} success
* @param {?=} error
* @return {?}
*/
loadBinary(path, success = null, error = null) {
path = this.pathPrefix + path;
this.toLoad++;
AssetManager.downloadBinary(path, (/**
* @param {?} data
* @return {?}
*/
(data) => {
this.assets[path] = data;
if (success)
success(path, data);
this.toLoad--;
this.loaded++;
}), (/**
* @param {?} state
* @param {?} responseText
* @return {?}
*/
(state, responseText) => {
this.errors[path] = `Couldn't load binary ${path}: status ${status}, ${responseText}`;
if (error)
error(path, `Couldn't load binary ${path}: status ${status}, ${responseText}`);
this.toLoad--;
this.loaded++;
}));
}
/**
* @param {?} path
* @param {?=} success
* @param {?=} error
* @return {?}
*/
loadText(path, success = null, error = null) {
path = this.pathPrefix + path;
this.toLoad++;
AssetManager.downloadText(path, (/**
* @param {?} data
* @return {?}
*/
(data) => {
this.assets[path] = data;
if (success)
success(path, data);
this.toLoad--;
this.loaded++;
}), (/**
* @param {?} state
* @param {?} responseText
* @return {?}
*/
(state, responseText) => {
this.errors[path] = `Couldn't load text ${path}: status ${status}, ${responseText}`;
if (error)
error(path, `Couldn't load text ${path}: status ${status}, ${responseText}`);
this.toLoad--;
this.loaded++;
}));
}
/**
* @param {?} path
* @param {?=} success
* @param {?=} error
* @return {?}
*/
loadTexture(path, success = null, error = null) {
path = this.pathPrefix + path;
this.toLoad++;
/** @type {?} */
let img = new Image();
img.crossOrigin = "anonymous";
img.onload = (/**
* @param {?} ev
* @return {?}
*/
ev => {
/** @type {?} */
let texture = this.textureLoader(img);
this.assets[path] = texture;
this.toLoad--;
this.loaded++;
if (success)
success(path, img);
});
img.onerror = (/**
* @param {?} ev
* @return {?}
*/
ev => {
this.errors[path] = `Couldn't load image ${path}`;
this.toLoad--;
this.loaded++;
if (error)
error(path, `Couldn't load image ${path}`);
});
img.src = path;
}
/**
* @param {?} path
* @param {?} data
* @param {?=} success
* @param {?=} error
* @return {?}
*/
loadTextureData(path, data, success = null, error = null) {
path = this.pathPrefix + path;
this.toLoad++;
/** @type {?} */
let img = new Image();
img.onload = (/**
* @param {?} ev
* @return {?}
*/
ev => {
/** @type {?} */
let texture = this.textureLoader(img);
this.assets[path] = texture;
this.toLoad--;
this.loaded++;
if (success)
success(path, img);
});
img.onerror = (/**
* @param {?} ev
* @return {?}
*/
ev => {
this.errors[path] = `Couldn't load image ${path}`;
this.toLoad--;
this.loaded++;
if (error)
error(path, `Couldn't load image ${path}`);
});
img.src = data;
}
/**
* @param {?} path
* @param {?=} success
* @param {?=} error
* @return {?}
*/
loadTextureAtlas(path, success = null, error = null) {
/** @type {?} */
let parent = path.lastIndexOf("/") >= 0
? path.substring(0, path.lastIndexOf("/"))
: "";
path = this.pathPrefix + path;
this.toLoad++;
AssetManager.downloadText(path, (/**
* @param {?} atlasData
* @return {?}
*/
(atlasData) => {
/** @type {?} */
let pagesLoaded = { count: 0 };
/** @type {?} */
let atlasPages = new Array();
try {
/** @type {?} */
let atlas = new TextureAtlas(atlasData, (/**
* @param {?} path
* @return {?}
*/
(path) => {
atlasPages.push(parent + "/" + path);
/** @type {?} */
let image = (/** @type {?} */ (document.createElement("img")));
image.width = 16;
image.height = 16;
return new FakeTexture(image);
}));
}
catch (e) {
/** @type {?} */
let ex = (/** @type {?} */ (e));
this.errors[path] = `Couldn't load texture atlas ${path}: ${ex.message}`;
if (error)
error(path, `Couldn't load texture atlas ${path}: ${ex.message}`);
this.toLoad--;
this.loaded++;
return;
}
for (let atlasPage of atlasPages) {
/** @type {?} */
let pageLoadError = false;
this.loadTexture(atlasPage, (/**
* @param {?} imagePath
* @param {?} image
* @return {?}
*/
(imagePath, image) => {
pagesLoaded.count++;
if (pagesLoaded.count == atlasPages.length) {
if (!pageLoadError) {
try {
/** @type {?} */
let atlas = new TextureAtlas(atlasData, (/**
* @param {?} path
* @return {?}
*/
(path) => {
return this.get(parent + "/" + path);
}));
this.assets[path] = atlas;
if (success)
success(path, atlas);
this.toLoad--;
this.loaded++;
}
catch (e) {
/** @type {?} */
let ex = (/** @type {?} */ (e));
this.errors[path] = `Couldn't load texture atlas ${path}: ${ex.message}`;
if (error)
error(path, `Couldn't load texture atlas ${path}: ${ex.message}`);
this.toLoad--;
this.loaded++;
}
}
else {
this.errors[path] = `Couldn't load texture atlas page ${imagePath}} of atlas ${path}`;
if (error)
error(path, `Couldn't load texture atlas page ${imagePath} of atlas ${path}`);
this.toLoad--;
this.loaded++;
}
}
}), (/**
* @param {?} imagePath
* @param {?} errorMessage
* @return {?}
*/
(imagePath, errorMessage) => {
pageLoadError = true;
pagesLoaded.count++;
if (pagesLoaded.count == atlasPages.length) {
this.errors[path] = `Couldn't load texture atlas page ${imagePath}} of atlas ${path}`;
if (error)
error(path, `Couldn't load texture atlas page ${imagePath} of atlas ${path}`);
this.toLoad--;
this.loaded++;
}
}));
}
}), (/**
* @param {?} state
* @param {?} responseText
* @return {?}
*/
(state, responseText) => {
this.errors[path] = `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`;
if (error)
error(path, `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`);
this.toLoad--;
this.loaded++;
}));
}
/**
* @param {?} path
* @return {?}
*/
get(path) {
path = this.pathPrefix + path;
return this.assets[path];
}
/**
* @param {?} path
* @return {?}
*/
remove(path) {
path = this.pathPrefix + path;
/** @type {?} */
let asset = this.assets[path];
if (((/** @type {?} */ (asset))).dispose)
((/** @type {?} */ (asset))).dispose();
this.assets[path] = null;
}
/**
* @return {?}
*/
removeAll() {
for (let key in this.assets) {
/** @type {?} */
let asset = this.assets[key];
if (((/** @type {?} */ (asset))).dispose)
((/** @type {?} */ (asset))).dispose();
}
this.assets = {};
}
/**
* @return {?}
*/
isLoadingComplete() {
return this.toLoad == 0;
}
/**
* @return {?}
*/
getToLoad() {
return this.toLoad;
}
/**
* @return {?}
*/
getLoaded() {
return this.loaded;
}
/**
* @return {?}
*/
dispose() {
this.removeAll();
}
/**
* @return {?}
*/
hasErrors() {
return Object.keys(this.errors).length > 0;
}
/**
* @return {?}
*/
getErrors() {
return this.errors;
}
}
if (false) {
/**
* @type {?}
* @private
*/
AssetManager.prototype.pathPrefix;
/**
* @type {?}
* @private
*/
AssetManager.prototype.textureLoader;
/**
* @type {?}
* @private
*/
AssetManager.prototype.assets;
/**
* @type {?}
* @private
*/
AssetManager.prototype.errors;
/**
* @type {?}
* @private
*/
AssetManager.prototype.toLoad;
/**
* @type {?}
* @private
*/
AssetManager.prototype.loaded;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXNzZXRNYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LXNwaW5lLyIsInNvdXJjZXMiOlsibGliL3NwaW5lLXRzL2NvcmUvQXNzZXRNYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBOEJBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDeEMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTlDLE1BQU0sT0FBTyxZQUFZOzs7OztJQU92QixZQUNFLGFBQStDLEVBQy9DLGFBQXFCLEVBQUU7UUFOakIsV0FBTSxHQUFhLEVBQUUsQ0FBQztRQUN0QixXQUFNLEdBQWdCLEVBQUUsQ0FBQztRQUN6QixXQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsV0FBTSxHQUFHLENBQUMsQ0FBQztRQUtqQixJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztRQUNuQyxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztJQUMvQixDQUFDOzs7Ozs7OztJQUNPLE1BQU0sQ0FBQyxZQUFZLENBQ3pCLEdBQVcsRUFDWCxPQUErQixFQUMvQixLQUFxRDs7WUFFakQsT0FBTyxHQUFHLElBQUksY0FBYyxFQUFFO1FBQ2xDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMvQixPQUFPLENBQUMsTUFBTTs7O1FBQUcsR0FBRyxFQUFFO1lBQ3BCLElBQUksT0FBTyxDQUFDLE1BQU0sSUFBSSxHQUFHLEVBQUU7Z0JBQ3pCLE9BQU8sQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7YUFDL0I7aUJBQU07Z0JBQ0wsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDO2FBQzdDO1FBQ0gsQ0FBQyxDQUFBLENBQUM7UUFDRixPQUFPLENBQUMsT0FBTzs7O1FBQUcsR0FBRyxFQUFFO1lBQ3JCLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM5QyxDQUFDLENBQUEsQ0FBQztRQUNGLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNqQixDQUFDOzs7Ozs7OztJQUNPLE1BQU0sQ0FBQyxjQUFjLENBQzNCLEdBQVcsRUFDWCxPQUFtQyxFQUNuQyxLQUFxRDs7WUFFakQsT0FBTyxHQUFHLElBQUksY0FBYyxFQUFFO1FBQ2xDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMvQixPQUFPLENBQUMsWUFBWSxHQUFHLGFBQWEsQ0FBQztRQUNyQyxPQUFPLENBQUMsTUFBTTs7O1FBQUcsR0FBRyxFQUFFO1lBQ3BCLElBQUksT0FBTyxDQUFDLE1BQU0sSUFBSSxHQUFHLEVBQUU7Z0JBQ3pCLE9BQU8sQ0FBQyxJQUFJLFVBQVUsQ0FBQyxtQkFBQSxPQUFPLENBQUMsUUFBUSxFQUFlLENBQUMsQ0FBQyxDQUFDO2FBQzFEO2lCQUFNO2dCQUNMLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQzthQUM3QztRQUNILENBQUMsQ0FBQSxDQUFDO1FBQ0YsT0FBTyxDQUFDLE9BQU87OztRQUFHLEdBQUcsRUFBRTtZQUNyQixLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDOUMsQ0FBQyxDQUFBLENBQUM7UUFDRixPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDakIsQ0FBQzs7Ozs7OztJQUNELFVBQVUsQ0FDUixJQUFZLEVBQ1osVUFBc0QsSUFBSSxFQUMxRCxRQUErQyxJQUFJO1FBRW5ELElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUM5QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZCxZQUFZLENBQUMsY0FBYyxDQUN6QixJQUFJOzs7O1FBQ0osQ0FBQyxJQUFnQixFQUFRLEVBQUU7WUFDekIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDekIsSUFBSSxPQUFPO2dCQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDakMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2hCLENBQUM7Ozs7O1FBQ0QsQ0FBQyxLQUFhLEVBQUUsWUFBb0IsRUFBUSxFQUFFO1lBQzVDLElBQUksQ0FBQyxNQUFNLENBQ1QsSUFBSSxDQUNMLEdBQUcsd0JBQXdCLElBQUksWUFBWSxNQUFNLEtBQUssWUFBWSxFQUFFLENBQUM7WUFDdEUsSUFBSSxLQUFLO2dCQUNQLEtBQUssQ0FDSCxJQUFJLEVBQ0osd0JBQXdCLElBQUksWUFBWSxNQUFNLEtBQUssWUFBWSxFQUFFLENBQ2xFLENBQUM7WUFDSixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDZCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDaEIsQ0FBQyxFQUNGLENBQUM7SUFDSixDQUFDOzs7Ozs7O0lBQ0QsUUFBUSxDQUNOLElBQVksRUFDWixVQUFnRCxJQUFJLEVBQ3BELFFBQStDLElBQUk7UUFFbkQsSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQzlCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNkLFlBQVksQ0FBQyxZQUFZLENBQ3ZCLElBQUk7Ozs7UUFDSixDQUFDLElBQVksRUFBUSxFQUFFO1lBQ3JCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQ3pCLElBQUksT0FBTztnQkFBRSxPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2pDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNoQixDQUFDOzs7OztRQUNELENBQUMsS0FBYSxFQUFFLFlBQW9CLEVBQVEsRUFBRTtZQUM1QyxJQUFJLENBQUMsTUFBTSxDQUNULElBQUksQ0FDTCxHQUFHLHNCQUFzQixJQUFJLFlBQVksTUFBTSxLQUFLLFlBQVksRUFBRSxDQUFDO1lBQ3BFLElBQUksS0FBSztnQkFDUCxLQUFLLENBQ0gsSUFBSSxFQUNKLHNCQUFzQixJQUFJLFlBQVksTUFBTSxLQUFLLFlBQVksRUFBRSxDQUNoRSxDQUFDO1lBQ0osSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2hCLENBQUMsRUFDRixDQUFDO0lBQ0osQ0FBQzs7Ozs7OztJQUNELFdBQVcsQ0FDVCxJQUFZLEVBQ1osVUFBMkQsSUFBSSxFQUMvRCxRQUErQyxJQUFJO1FBRW5ELElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUM5QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7O1lBQ1YsR0FBRyxHQUFHLElBQUksS0FBSyxFQUFFO1FBQ3JCLEdBQUcsQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO1FBQzlCLEdBQUcsQ0FBQyxNQUFNOzs7O1FBQUcsRUFBRSxDQUFDLEVBQUU7O2dCQUNaLE9BQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQztZQUNyQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLE9BQU8sQ0FBQztZQUM1QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDZCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDZCxJQUFJLE9BQU87Z0JBQUUsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNsQyxDQUFDLENBQUEsQ0FBQztRQUNGLEdBQUcsQ0FBQyxPQUFPOzs7O1FBQUcsRUFBRSxDQUFDLEVBQUU7WUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyx1QkFBdUIsSUFBSSxFQUFFLENBQUM7WUFDbEQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2QsSUFBSSxLQUFLO2dCQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsdUJBQXVCLElBQUksRUFBRSxDQUFDLENBQUM7UUFDeEQsQ0FBQyxDQUFBLENBQUM7UUFDRixHQUFHLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQztJQUNqQixDQUFDOzs7Ozs7OztJQUNELGVBQWUsQ0FDYixJQUFZLEVBQ1osSUFBWSxFQUNaLFVBQTJELElBQUksRUFDL0QsUUFBK0MsSUFBSTtRQUVuRCxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFDOUIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDOztZQUNWLEdBQUcsR0FBRyxJQUFJLEtBQUssRUFBRTtRQUNyQixHQUFHLENBQUMsTUFBTTs7OztRQUFHLEVBQUUsQ0FBQyxFQUFFOztnQkFDWixPQUFPLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxPQUFPLENBQUM7WUFDNUIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2QsSUFBSSxPQUFPO2dCQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDbEMsQ0FBQyxDQUFBLENBQUM7UUFDRixHQUFHLENBQUMsT0FBTzs7OztRQUFHLEVBQUUsQ0FBQyxFQUFFO1lBQ2pCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsdUJBQXVCLElBQUksRUFBRSxDQUFDO1lBQ2xELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNkLElBQUksS0FBSztnQkFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLHVCQUF1QixJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3hELENBQUMsQ0FBQSxDQUFDO1FBQ0YsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUM7SUFDakIsQ0FBQzs7Ozs7OztJQUNELGdCQUFnQixDQUNkLElBQVksRUFDWixVQUF1RCxJQUFJLEVBQzNELFFBQStDLElBQUk7O1lBRS9DLE1BQU0sR0FDUixJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFDeEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDMUMsQ0FBQyxDQUFDLEVBQUU7UUFDUixJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFDOUIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2QsWUFBWSxDQUFDLFlBQVksQ0FDdkIsSUFBSTs7OztRQUNKLENBQUMsU0FBaUIsRUFBUSxFQUFFOztnQkFDdEIsV0FBVyxHQUFRLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRTs7Z0JBQy9CLFVBQVUsR0FBRyxJQUFJLEtBQUssRUFBVTtZQUNwQyxJQUFJOztvQkFDRSxLQUFLLEdBQUcsSUFBSSxZQUFZLENBQUMsU0FBUzs7OztnQkFBRSxDQUFDLElBQVksRUFBRSxFQUFFO29CQUN2RCxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUM7O3dCQUNqQyxLQUFLLEdBQUcsbUJBQUEsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsRUFBb0I7b0JBQzdELEtBQUssQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO29CQUNqQixLQUFLLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztvQkFDbEIsT0FBTyxJQUFJLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDaEMsQ0FBQyxFQUFDO2FBQ0g7WUFBQyxPQUFPLENBQUMsRUFBRTs7b0JBQ04sRUFBRSxHQUFHLG1CQUFBLENBQUMsRUFBUztnQkFDbkIsSUFBSSxDQUFDLE1BQU0sQ0FDVCxJQUFJLENBQ0wsR0FBRywrQkFBK0IsSUFBSSxLQUFLLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDekQsSUFBSSxLQUFLO29CQUNQLEtBQUssQ0FBQyxJQUFJLEVBQUUsK0JBQStCLElBQUksS0FBSyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztnQkFDcEUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNkLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDZCxPQUFPO2FBQ1I7WUFDRCxLQUFLLElBQUksU0FBUyxJQUFJLFVBQVUsRUFBRTs7b0JBQzVCLGFBQWEsR0FBRyxLQUFLO2dCQUN6QixJQUFJLENBQUMsV0FBVyxDQUNkLFNBQVM7Ozs7O2dCQUNULENBQUMsU0FBaUIsRUFBRSxLQUF1QixFQUFFLEVBQUU7b0JBQzdDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDcEIsSUFBSSxXQUFXLENBQUMsS0FBSyxJQUFJLFVBQVUsQ0FBQyxNQUFNLEVBQUU7d0JBQzFDLElBQUksQ0FBQyxhQUFhLEVBQUU7NEJBQ2xCLElBQUk7O29DQUNFLEtBQUssR0FBRyxJQUFJLFlBQVksQ0FBQyxTQUFTOzs7O2dDQUFFLENBQUMsSUFBWSxFQUFFLEVBQUU7b0NBQ3ZELE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDO2dDQUN2QyxDQUFDLEVBQUM7Z0NBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUM7Z0NBQzFCLElBQUksT0FBTztvQ0FBRSxPQUFPLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO2dDQUNsQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7Z0NBQ2QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDOzZCQUNmOzRCQUFDLE9BQU8sQ0FBQyxFQUFFOztvQ0FDTixFQUFFLEdBQUcsbUJBQUEsQ0FBQyxFQUFTO2dDQUNuQixJQUFJLENBQUMsTUFBTSxDQUNULElBQUksQ0FDTCxHQUFHLCtCQUErQixJQUFJLEtBQUssRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dDQUN6RCxJQUFJLEtBQUs7b0NBQ1AsS0FBSyxDQUNILElBQUksRUFDSiwrQkFBK0IsSUFBSSxLQUFLLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FDckQsQ0FBQztnQ0FDSixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7Z0NBQ2QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDOzZCQUNmO3lCQUNGOzZCQUFNOzRCQUNMLElBQUksQ0FBQyxNQUFNLENBQ1QsSUFBSSxDQUNMLEdBQUcsb0NBQW9DLFNBQVMsY0FBYyxJQUFJLEVBQUUsQ0FBQzs0QkFDdEUsSUFBSSxLQUFLO2dDQUNQLEtBQUssQ0FDSCxJQUFJLEVBQ0osb0NBQW9DLFNBQVMsYUFBYSxJQUFJLEVBQUUsQ0FDakUsQ0FBQzs0QkFDSixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7NEJBQ2QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO3lCQUNmO3FCQUNGO2dCQUNILENBQUM7Ozs7O2dCQUNELENBQUMsU0FBaUIsRUFBRSxZQUFvQixFQUFFLEVBQUU7b0JBQzFDLGFBQWEsR0FBRyxJQUFJLENBQUM7b0JBQ3JCLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDcEIsSUFBSSxXQUFXLENBQUMsS0FBSyxJQUFJLFVBQVUsQ0FBQyxNQUFNLEVBQUU7d0JBQzFDLElBQUksQ0FBQyxNQUFNLENBQ1QsSUFBSSxDQUNMLEdBQUcsb0NBQW9DLFNBQVMsY0FBYyxJQUFJLEVBQUUsQ0FBQzt3QkFDdEUsSUFBSSxLQUFLOzRCQUNQLEtBQUssQ0FDSCxJQUFJLEVBQ0osb0NBQW9DLFNBQVMsYUFBYSxJQUFJLEVBQUUsQ0FDakUsQ0FBQzt3QkFDSixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7d0JBQ2QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO3FCQUNmO2dCQUNILENBQUMsRUFDRixDQUFDO2FBQ0g7UUFDSCxDQUFDOzs7OztRQUNELENBQUMsS0FBYSxFQUFFLFlBQW9CLEVBQVEsRUFBRTtZQUM1QyxJQUFJLENBQUMsTUFBTSxDQUNULElBQUksQ0FDTCxHQUFHLCtCQUErQixJQUFJLFlBQVksTUFBTSxLQUFLLFlBQVksRUFBRSxDQUFDO1lBQzdFLElBQUksS0FBSztnQkFDUCxLQUFLLENBQ0gsSUFBSSxFQUNKLCtCQUErQixJQUFJLFlBQVksTUFBTSxLQUFLLFlBQVksRUFBRSxDQUN6RSxDQUFDO1lBQ0osSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2hCLENBQUMsRUFDRixDQUFDO0lBQ0osQ0FBQzs7Ozs7SUFDRCxHQUFHLENBQUMsSUFBWTtRQUNkLElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUM5QixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDM0IsQ0FBQzs7Ozs7SUFDRCxNQUFNLENBQUMsSUFBWTtRQUNqQixJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7O1lBQzFCLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztRQUM3QixJQUFJLENBQUMsbUJBQUssS0FBSyxFQUFBLENBQUMsQ0FBQyxPQUFPO1lBQUUsQ0FBQyxtQkFBSyxLQUFLLEVBQUEsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDO0lBQzNCLENBQUM7Ozs7SUFDRCxTQUFTO1FBQ1AsS0FBSyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFOztnQkFDdkIsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO1lBQzVCLElBQUksQ0FBQyxtQkFBSyxLQUFLLEVBQUEsQ0FBQyxDQUFDLE9BQU87Z0JBQUUsQ0FBQyxtQkFBSyxLQUFLLEVBQUEsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1NBQ2xEO1FBQ0QsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7SUFDbkIsQ0FBQzs7OztJQUNELGlCQUFpQjtRQUNmLE9BQU8sSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUM7SUFDMUIsQ0FBQzs7OztJQUNELFNBQVM7UUFDUCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQzs7OztJQUNELFNBQVM7UUFDUCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQzs7OztJQUNELE9BQU87UUFDTCxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDbkIsQ0FBQzs7OztJQUNELFNBQVM7UUFDUCxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDN0MsQ0FBQzs7OztJQUNELFNBQVM7UUFDUCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQztDQUNGOzs7Ozs7SUFoVEMsa0NBQTJCOzs7OztJQUMzQixxQ0FBd0Q7Ozs7O0lBQ3hELDhCQUE4Qjs7Ozs7SUFDOUIsOEJBQWlDOzs7OztJQUNqQyw4QkFBbUI7Ozs7O0lBQ25CLDhCQUFtQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuICogU3BpbmUgUnVudGltZXMgTGljZW5zZSBBZ3JlZW1lbnRcclxuICogTGFzdCB1cGRhdGVkIE1heSAxLCAyMDE5LiBSZXBsYWNlcyBhbGwgcHJpb3IgdmVyc2lvbnMuXHJcbiAqXHJcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDE5LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcclxuICpcclxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXHJcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXHJcbiAqIGNvbmRpdGlvbnMgb2YgU2VjdGlvbiAyIG9mIHRoZSBTcGluZSBFZGl0b3IgTGljZW5zZSBBZ3JlZW1lbnQ6XHJcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxyXG4gKlxyXG4gKiBPdGhlcndpc2UsIGl0IGlzIHBlcm1pdHRlZCB0byBpbnRlZ3JhdGUgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmVcclxuICogb3Igb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxyXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXHJcbiAqIFNwaW5lIEVkaXRvciBsaWNlbnNlIGFuZCByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZHVjdHMgaW4gYW55IGZvcm0gbXVzdFxyXG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cclxuICpcclxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBFU09URVJJQyBTT0ZUV0FSRSBMTEMgXCJBUyBJU1wiIEFORCBBTlkgRVhQUkVTU1xyXG4gKiBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTXHJcbiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOXHJcbiAqIE5PIEVWRU5UIFNIQUxMIEVTT1RFUklDIFNPRlRXQVJFIExMQyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULFxyXG4gKiBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLFxyXG4gKiBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsIEJVU0lORVNTXHJcbiAqIElOVEVSUlVQVElPTiwgT1IgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFMpIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTllcclxuICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HXHJcbiAqIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSxcclxuICogRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cclxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG5cclxuaW1wb3J0IHsgTWFwLCBEaXNwb3NhYmxlIH0gZnJvbSBcIi4vVXRpbHNcIjtcclxuaW1wb3J0IHsgRmFrZVRleHR1cmUgfSBmcm9tIFwiLi9UZXh0dXJlXCI7XHJcbmltcG9ydCB7IFRleHR1cmVBdGxhcyB9IGZyb20gXCIuL1RleHR1cmVBdGxhc1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIEFzc2V0TWFuYWdlciBpbXBsZW1lbnRzIERpc3Bvc2FibGUge1xyXG4gIHByaXZhdGUgcGF0aFByZWZpeDogc3RyaW5nO1xyXG4gIHByaXZhdGUgdGV4dHVyZUxvYWRlcjogKGltYWdlOiBIVE1MSW1hZ2VFbGVtZW50KSA9PiBhbnk7XHJcbiAgcHJpdmF0ZSBhc3NldHM6IE1hcDxhbnk+ID0ge307XHJcbiAgcHJpdmF0ZSBlcnJvcnM6IE1hcDxzdHJpbmc+ID0ge307XHJcbiAgcHJpdmF0ZSB0b0xvYWQgPSAwO1xyXG4gIHByaXZhdGUgbG9hZGVkID0gMDtcclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHRleHR1cmVMb2FkZXI6IChpbWFnZTogSFRNTEltYWdlRWxlbWVudCkgPT4gYW55LFxyXG4gICAgcGF0aFByZWZpeDogc3RyaW5nID0gXCJcIlxyXG4gICkge1xyXG4gICAgdGhpcy50ZXh0dXJlTG9hZGVyID0gdGV4dHVyZUxvYWRlcjtcclxuICAgIHRoaXMucGF0aFByZWZpeCA9IHBhdGhQcmVmaXg7XHJcbiAgfVxyXG4gIHByaXZhdGUgc3RhdGljIGRvd25sb2FkVGV4dChcclxuICAgIHVybDogc3RyaW5nLFxyXG4gICAgc3VjY2VzczogKGRhdGE6IHN0cmluZykgPT4gdm9pZCxcclxuICAgIGVycm9yOiAoc3RhdHVzOiBudW1iZXIsIHJlc3BvbnNlVGV4dDogc3RyaW5nKSA9PiB2b2lkXHJcbiAgKSB7XHJcbiAgICBsZXQgcmVxdWVzdCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xyXG4gICAgcmVxdWVzdC5vcGVuKFwiR0VUXCIsIHVybCwgdHJ1ZSk7XHJcbiAgICByZXF1ZXN0Lm9ubG9hZCA9ICgpID0+IHtcclxuICAgICAgaWYgKHJlcXVlc3Quc3RhdHVzID09IDIwMCkge1xyXG4gICAgICAgIHN1Y2Nlc3MocmVxdWVzdC5yZXNwb25zZVRleHQpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGVycm9yKHJlcXVlc3Quc3RhdHVzLCByZXF1ZXN0LnJlc3BvbnNlVGV4dCk7XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgICByZXF1ZXN0Lm9uZXJyb3IgPSAoKSA9PiB7XHJcbiAgICAgIGVycm9yKHJlcXVlc3Quc3RhdHVzLCByZXF1ZXN0LnJlc3BvbnNlVGV4dCk7XHJcbiAgICB9O1xyXG4gICAgcmVxdWVzdC5zZW5kKCk7XHJcbiAgfVxyXG4gIHByaXZhdGUgc3RhdGljIGRvd25sb2FkQmluYXJ5KFxyXG4gICAgdXJsOiBzdHJpbmcsXHJcbiAgICBzdWNjZXNzOiAoZGF0YTogVWludDhBcnJheSkgPT4gdm9pZCxcclxuICAgIGVycm9yOiAoc3RhdHVzOiBudW1iZXIsIHJlc3BvbnNlVGV4dDogc3RyaW5nKSA9PiB2b2lkXHJcbiAgKSB7XHJcbiAgICBsZXQgcmVxdWVzdCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xyXG4gICAgcmVxdWVzdC5vcGVuKFwiR0VUXCIsIHVybCwgdHJ1ZSk7XHJcbiAgICByZXF1ZXN0LnJlc3BvbnNlVHlwZSA9IFwiYXJyYXlidWZmZXJcIjtcclxuICAgIHJlcXVlc3Qub25sb2FkID0gKCkgPT4ge1xyXG4gICAgICBpZiAocmVxdWVzdC5zdGF0dXMgPT0gMjAwKSB7XHJcbiAgICAgICAgc3VjY2VzcyhuZXcgVWludDhBcnJheShyZXF1ZXN0LnJlc3BvbnNlIGFzIEFycmF5QnVmZmVyKSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZXJyb3IocmVxdWVzdC5zdGF0dXMsIHJlcXVlc3QucmVzcG9uc2VUZXh0KTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcclxuICAgICAgZXJyb3IocmVxdWVzdC5zdGF0dXMsIHJlcXVlc3QucmVzcG9uc2VUZXh0KTtcclxuICAgIH07XHJcbiAgICByZXF1ZXN0LnNlbmQoKTtcclxuICB9XHJcbiAgbG9hZEJpbmFyeShcclxuICAgIHBhdGg6IHN0cmluZyxcclxuICAgIHN1Y2Nlc3M6IChwYXRoOiBzdHJpbmcsIGJpbmFyeTogVWludDhBcnJheSkgPT4gdm9pZCA9IG51bGwsXHJcbiAgICBlcnJvcjogKHBhdGg6IHN0cmluZywgZXJyb3I6IHN0cmluZykgPT4gdm9pZCA9IG51bGxcclxuICApIHtcclxuICAgIHBhdGggPSB0aGlzLnBhdGhQcmVmaXggKyBwYXRoO1xyXG4gICAgdGhpcy50b0xvYWQrKztcclxuICAgIEFzc2V0TWFuYWdlci5kb3dubG9hZEJpbmFyeShcclxuICAgICAgcGF0aCxcclxuICAgICAgKGRhdGE6IFVpbnQ4QXJyYXkpOiB2b2lkID0+IHtcclxuICAgICAgICB0aGlzLmFzc2V0c1twYXRoXSA9IGRhdGE7XHJcbiAgICAgICAgaWYgKHN1Y2Nlc3MpIHN1Y2Nlc3MocGF0aCwgZGF0YSk7XHJcbiAgICAgICAgdGhpcy50b0xvYWQtLTtcclxuICAgICAgICB0aGlzLmxvYWRlZCsrO1xyXG4gICAgICB9LFxyXG4gICAgICAoc3RhdGU6IG51bWJlciwgcmVzcG9uc2VUZXh0OiBzdHJpbmcpOiB2b2lkID0+IHtcclxuICAgICAgICB0aGlzLmVycm9yc1tcclxuICAgICAgICAgIHBhdGhcclxuICAgICAgICBdID0gYENvdWxkbid0IGxvYWQgYmluYXJ5ICR7cGF0aH06IHN0YXR1cyAke3N0YXR1c30sICR7cmVzcG9uc2VUZXh0fWA7XHJcbiAgICAgICAgaWYgKGVycm9yKVxyXG4gICAgICAgICAgZXJyb3IoXHJcbiAgICAgICAgICAgIHBhdGgsXHJcbiAgICAgICAgICAgIGBDb3VsZG4ndCBsb2FkIGJpbmFyeSAke3BhdGh9OiBzdGF0dXMgJHtzdGF0dXN9LCAke3Jlc3BvbnNlVGV4dH1gXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgIHRoaXMudG9Mb2FkLS07XHJcbiAgICAgICAgdGhpcy5sb2FkZWQrKztcclxuICAgICAgfVxyXG4gICAgKTtcclxuICB9XHJcbiAgbG9hZFRleHQoXHJcbiAgICBwYXRoOiBzdHJpbmcsXHJcbiAgICBzdWNjZXNzOiAocGF0aDogc3RyaW5nLCB0ZXh0OiBzdHJpbmcpID0+IHZvaWQgPSBudWxsLFxyXG4gICAgZXJyb3I6IChwYXRoOiBzdHJpbmcsIGVycm9yOiBzdHJpbmcpID0+IHZvaWQgPSBudWxsXHJcbiAgKSB7XHJcbiAgICBwYXRoID0gdGhpcy5wYXRoUHJlZml4ICsgcGF0aDtcclxuICAgIHRoaXMudG9Mb2FkKys7XHJcbiAgICBBc3NldE1hbmFnZXIuZG93bmxvYWRUZXh0KFxyXG4gICAgICBwYXRoLFxyXG4gICAgICAoZGF0YTogc3RyaW5nKTogdm9pZCA9PiB7XHJcbiAgICAgICAgdGhpcy5hc3NldHNbcGF0aF0gPSBkYXRhO1xyXG4gICAgICAgIGlmIChzdWNjZXNzKSBzdWNjZXNzKHBhdGgsIGRhdGEpO1xyXG4gICAgICAgIHRoaXMudG9Mb2FkLS07XHJcbiAgICAgICAgdGhpcy5sb2FkZWQrKztcclxuICAgICAgfSxcclxuICAgICAgKHN0YXRlOiBudW1iZXIsIHJlc3BvbnNlVGV4dDogc3RyaW5nKTogdm9pZCA9PiB7XHJcbiAgICAgICAgdGhpcy5lcnJvcnNbXHJcbiAgICAgICAgICBwYXRoXHJcbiAgICAgICAgXSA9IGBDb3VsZG4ndCBsb2FkIHRleHQgJHtwYXRofTogc3RhdHVzICR7c3RhdHVzfSwgJHtyZXNwb25zZVRleHR9YDtcclxuICAgICAgICBpZiAoZXJyb3IpXHJcbiAgICAgICAgICBlcnJvcihcclxuICAgICAgICAgICAgcGF0aCxcclxuICAgICAgICAgICAgYENvdWxkbid0IGxvYWQgdGV4dCAke3BhdGh9OiBzdGF0dXMgJHtzdGF0dXN9LCAke3Jlc3BvbnNlVGV4dH1gXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgIHRoaXMudG9Mb2FkLS07XHJcbiAgICAgICAgdGhpcy5sb2FkZWQrKztcclxuICAgICAgfVxyXG4gICAgKTtcclxuICB9XHJcbiAgbG9hZFRleHR1cmUoXHJcbiAgICBwYXRoOiBzdHJpbmcsXHJcbiAgICBzdWNjZXNzOiAocGF0aDogc3RyaW5nLCBpbWFnZTogSFRNTEltYWdlRWxlbWVudCkgPT4gdm9pZCA9IG51bGwsXHJcbiAgICBlcnJvcjogKHBhdGg6IHN0cmluZywgZXJyb3I6IHN0cmluZykgPT4gdm9pZCA9IG51bGxcclxuICApIHtcclxuICAgIHBhdGggPSB0aGlzLnBhdGhQcmVmaXggKyBwYXRoO1xyXG4gICAgdGhpcy50b0xvYWQrKztcclxuICAgIGxldCBpbWcgPSBuZXcgSW1hZ2UoKTtcclxuICAgIGltZy5jcm9zc09yaWdpbiA9IFwiYW5vbnltb3VzXCI7XHJcbiAgICBpbWcub25sb2FkID0gZXYgPT4ge1xyXG4gICAgICBsZXQgdGV4dHVyZSA9IHRoaXMudGV4dHVyZUxvYWRlcihpbWcpO1xyXG4gICAgICB0aGlzLmFzc2V0c1twYXRoXSA9IHRleHR1cmU7XHJcbiAgICAgIHRoaXMudG9Mb2FkLS07XHJcbiAgICAgIHRoaXMubG9hZGVkKys7XHJcbiAgICAgIGlmIChzdWNjZXNzKSBzdWNjZXNzKHBhdGgsIGltZyk7XHJcbiAgICB9O1xyXG4gICAgaW1nLm9uZXJyb3IgPSBldiA9PiB7XHJcbiAgICAgIHRoaXMuZXJyb3JzW3BhdGhdID0gYENvdWxkbid0IGxvYWQgaW1hZ2UgJHtwYXRofWA7XHJcbiAgICAgIHRoaXMudG9Mb2FkLS07XHJcbiAgICAgIHRoaXMubG9hZGVkKys7XHJcbiAgICAgIGlmIChlcnJvcikgZXJyb3IocGF0aCwgYENvdWxkbid0IGxvYWQgaW1hZ2UgJHtwYXRofWApO1xyXG4gICAgfTtcclxuICAgIGltZy5zcmMgPSBwYXRoO1xyXG4gIH1cclxuICBsb2FkVGV4dHVyZURhdGEoXHJcbiAgICBwYXRoOiBzdHJpbmcsXHJcbiAgICBkYXRhOiBzdHJpbmcsXHJcbiAgICBzdWNjZXNzOiAocGF0aDogc3RyaW5nLCBpbWFnZTogSFRNTEltYWdlRWxlbWVudCkgPT4gdm9pZCA9IG51bGwsXHJcbiAgICBlcnJvcjogKHBhdGg6IHN0cmluZywgZXJyb3I6IHN0cmluZykgPT4gdm9pZCA9IG51bGxcclxuICApIHtcclxuICAgIHBhdGggPSB0aGlzLnBhdGhQcmVmaXggKyBwYXRoO1xyXG4gICAgdGhpcy50b0xvYWQrKztcclxuICAgIGxldCBpbWcgPSBuZXcgSW1hZ2UoKTtcclxuICAgIGltZy5vbmxvYWQgPSBldiA9PiB7XHJcbiAgICAgIGxldCB0ZXh0dXJlID0gdGhpcy50ZXh0dXJlTG9hZGVyKGltZyk7XHJcbiAgICAgIHRoaXMuYXNzZXRzW3BhdGhdID0gdGV4dHVyZTtcclxuICAgICAgdGhpcy50b0xvYWQtLTtcclxuICAgICAgdGhpcy5sb2FkZWQrKztcclxuICAgICAgaWYgKHN1Y2Nlc3MpIHN1Y2Nlc3MocGF0aCwgaW1nKTtcclxuICAgIH07XHJcbiAgICBpbWcub25lcnJvciA9IGV2ID0+IHtcclxuICAgICAgdGhpcy5lcnJvcnNbcGF0aF0gPSBgQ291bGRuJ3QgbG9hZCBpbWFnZSAke3BhdGh9YDtcclxuICAgICAgdGhpcy50b0xvYWQtLTtcclxuICAgICAgdGhpcy5sb2FkZWQrKztcclxuICAgICAgaWYgKGVycm9yKSBlcnJvcihwYXRoLCBgQ291bGRuJ3QgbG9hZCBpbWFnZSAke3BhdGh9YCk7XHJcbiAgICB9O1xyXG4gICAgaW1nLnNyYyA9IGRhdGE7XHJcbiAgfVxyXG4gIGxvYWRUZXh0dXJlQXRsYXMoXHJcbiAgICBwYXRoOiBzdHJpbmcsXHJcbiAgICBzdWNjZXNzOiAocGF0aDogc3RyaW5nLCBhdGxhczogVGV4dHVyZUF0bGFzKSA9PiB2b2lkID0gbnVsbCxcclxuICAgIGVycm9yOiAocGF0aDogc3RyaW5nLCBlcnJvcjogc3RyaW5nKSA9PiB2b2lkID0gbnVsbFxyXG4gICkge1xyXG4gICAgbGV0IHBhcmVudCA9XHJcbiAgICAgIHBhdGgubGFzdEluZGV4T2YoXCIvXCIpID49IDBcclxuICAgICAgICA/IHBhdGguc3Vic3RyaW5nKDAsIHBhdGgubGFzdEluZGV4T2YoXCIvXCIpKVxyXG4gICAgICAgIDogXCJcIjtcclxuICAgIHBhdGggPSB0aGlzLnBhdGhQcmVmaXggKyBwYXRoO1xyXG4gICAgdGhpcy50b0xvYWQrKztcclxuICAgIEFzc2V0TWFuYWdlci5kb3dubG9hZFRleHQoXHJcbiAgICAgIHBhdGgsXHJcbiAgICAgIChhdGxhc0RhdGE6IHN0cmluZyk6IHZvaWQgPT4ge1xyXG4gICAgICAgIGxldCBwYWdlc0xvYWRlZDogYW55ID0geyBjb3VudDogMCB9O1xyXG4gICAgICAgIGxldCBhdGxhc1BhZ2VzID0gbmV3IEFycmF5PHN0cmluZz4oKTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgbGV0IGF0bGFzID0gbmV3IFRleHR1cmVBdGxhcyhhdGxhc0RhdGEsIChwYXRoOiBzdHJpbmcpID0+IHtcclxuICAgICAgICAgICAgYXRsYXNQYWdlcy5wdXNoKHBhcmVudCArIFwiL1wiICsgcGF0aCk7XHJcbiAgICAgICAgICAgIGxldCBpbWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIikgYXMgSFRNTEltYWdlRWxlbWVudDtcclxuICAgICAgICAgICAgaW1hZ2Uud2lkdGggPSAxNjtcclxuICAgICAgICAgICAgaW1hZ2UuaGVpZ2h0ID0gMTY7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgRmFrZVRleHR1cmUoaW1hZ2UpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgbGV0IGV4ID0gZSBhcyBFcnJvcjtcclxuICAgICAgICAgIHRoaXMuZXJyb3JzW1xyXG4gICAgICAgICAgICBwYXRoXHJcbiAgICAgICAgICBdID0gYENvdWxkbid0IGxvYWQgdGV4dHVyZSBhdGxhcyAke3BhdGh9OiAke2V4Lm1lc3NhZ2V9YDtcclxuICAgICAgICAgIGlmIChlcnJvcilcclxuICAgICAgICAgICAgZXJyb3IocGF0aCwgYENvdWxkbid0IGxvYWQgdGV4dHVyZSBhdGxhcyAke3BhdGh9OiAke2V4Lm1lc3NhZ2V9YCk7XHJcbiAgICAgICAgICB0aGlzLnRvTG9hZC0tO1xyXG4gICAgICAgICAgdGhpcy5sb2FkZWQrKztcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm9yIChsZXQgYXRsYXNQYWdlIG9mIGF0bGFzUGFnZXMpIHtcclxuICAgICAgICAgIGxldCBwYWdlTG9hZEVycm9yID0gZmFsc2U7XHJcbiAgICAgICAgICB0aGlzLmxvYWRUZXh0dXJlKFxyXG4gICAgICAgICAgICBhdGxhc1BhZ2UsXHJcbiAgICAgICAgICAgIChpbWFnZVBhdGg6IHN0cmluZywgaW1hZ2U6IEhUTUxJbWFnZUVsZW1lbnQpID0+IHtcclxuICAgICAgICAgICAgICBwYWdlc0xvYWRlZC5jb3VudCsrO1xyXG4gICAgICAgICAgICAgIGlmIChwYWdlc0xvYWRlZC5jb3VudCA9PSBhdGxhc1BhZ2VzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFwYWdlTG9hZEVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGF0bGFzID0gbmV3IFRleHR1cmVBdGxhcyhhdGxhc0RhdGEsIChwYXRoOiBzdHJpbmcpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldChwYXJlbnQgKyBcIi9cIiArIHBhdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYXNzZXRzW3BhdGhdID0gYXRsYXM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN1Y2Nlc3MpIHN1Y2Nlc3MocGF0aCwgYXRsYXMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudG9Mb2FkLS07XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkZWQrKztcclxuICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBleCA9IGUgYXMgRXJyb3I7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvcnNbXHJcbiAgICAgICAgICAgICAgICAgICAgICBwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgXSA9IGBDb3VsZG4ndCBsb2FkIHRleHR1cmUgYXRsYXMgJHtwYXRofTogJHtleC5tZXNzYWdlfWA7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxyXG4gICAgICAgICAgICAgICAgICAgICAgZXJyb3IoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGBDb3VsZG4ndCBsb2FkIHRleHR1cmUgYXRsYXMgJHtwYXRofTogJHtleC5tZXNzYWdlfWBcclxuICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b0xvYWQtLTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRlZCsrO1xyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLmVycm9yc1tcclxuICAgICAgICAgICAgICAgICAgICBwYXRoXHJcbiAgICAgICAgICAgICAgICAgIF0gPSBgQ291bGRuJ3QgbG9hZCB0ZXh0dXJlIGF0bGFzIHBhZ2UgJHtpbWFnZVBhdGh9fSBvZiBhdGxhcyAke3BhdGh9YDtcclxuICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxyXG4gICAgICAgICAgICAgICAgICAgIGVycm9yKFxyXG4gICAgICAgICAgICAgICAgICAgICAgcGF0aCxcclxuICAgICAgICAgICAgICAgICAgICAgIGBDb3VsZG4ndCBsb2FkIHRleHR1cmUgYXRsYXMgcGFnZSAke2ltYWdlUGF0aH0gb2YgYXRsYXMgJHtwYXRofWBcclxuICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLnRvTG9hZC0tO1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLmxvYWRlZCsrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgKGltYWdlUGF0aDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZykgPT4ge1xyXG4gICAgICAgICAgICAgIHBhZ2VMb2FkRXJyb3IgPSB0cnVlO1xyXG4gICAgICAgICAgICAgIHBhZ2VzTG9hZGVkLmNvdW50Kys7XHJcbiAgICAgICAgICAgICAgaWYgKHBhZ2VzTG9hZGVkLmNvdW50ID09IGF0bGFzUGFnZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yc1tcclxuICAgICAgICAgICAgICAgICAgcGF0aFxyXG4gICAgICAgICAgICAgICAgXSA9IGBDb3VsZG4ndCBsb2FkIHRleHR1cmUgYXRsYXMgcGFnZSAke2ltYWdlUGF0aH19IG9mIGF0bGFzICR7cGF0aH1gO1xyXG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKVxyXG4gICAgICAgICAgICAgICAgICBlcnJvcihcclxuICAgICAgICAgICAgICAgICAgICBwYXRoLFxyXG4gICAgICAgICAgICAgICAgICAgIGBDb3VsZG4ndCBsb2FkIHRleHR1cmUgYXRsYXMgcGFnZSAke2ltYWdlUGF0aH0gb2YgYXRsYXMgJHtwYXRofWBcclxuICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIHRoaXMudG9Mb2FkLS07XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRlZCsrO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sXHJcbiAgICAgIChzdGF0ZTogbnVtYmVyLCByZXNwb25zZVRleHQ6IHN0cmluZyk6IHZvaWQgPT4ge1xyXG4gICAgICAgIHRoaXMuZXJyb3JzW1xyXG4gICAgICAgICAgcGF0aFxyXG4gICAgICAgIF0gPSBgQ291bGRuJ3QgbG9hZCB0ZXh0dXJlIGF0bGFzICR7cGF0aH06IHN0YXR1cyAke3N0YXR1c30sICR7cmVzcG9uc2VUZXh0fWA7XHJcbiAgICAgICAgaWYgKGVycm9yKVxyXG4gICAgICAgICAgZXJyb3IoXHJcbiAgICAgICAgICAgIHBhdGgsXHJcbiAgICAgICAgICAgIGBDb3VsZG4ndCBsb2FkIHRleHR1cmUgYXRsYXMgJHtwYXRofTogc3RhdHVzICR7c3RhdHVzfSwgJHtyZXNwb25zZVRleHR9YFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICB0aGlzLnRvTG9hZC0tO1xyXG4gICAgICAgIHRoaXMubG9hZGVkKys7XHJcbiAgICAgIH1cclxuICAgICk7XHJcbiAgfVxyXG4gIGdldChwYXRoOiBzdHJpbmcpIHtcclxuICAgIHBhdGggPSB0aGlzLnBhdGhQcmVmaXggKyBwYXRoO1xyXG4gICAgcmV0dXJuIHRoaXMuYXNzZXRzW3BhdGhdO1xyXG4gIH1cclxuICByZW1vdmUocGF0aDogc3RyaW5nKSB7XHJcbiAgICBwYXRoID0gdGhpcy5wYXRoUHJlZml4ICsgcGF0aDtcclxuICAgIGxldCBhc3NldCA9IHRoaXMuYXNzZXRzW3BhdGhdO1xyXG4gICAgaWYgKCg8YW55PmFzc2V0KS5kaXNwb3NlKSAoPGFueT5hc3NldCkuZGlzcG9zZSgpO1xyXG4gICAgdGhpcy5hc3NldHNbcGF0aF0gPSBudWxsO1xyXG4gIH1cclxuICByZW1vdmVBbGwoKSB7XHJcbiAgICBmb3IgKGxldCBrZXkgaW4gdGhpcy5hc3NldHMpIHtcclxuICAgICAgbGV0IGFzc2V0ID0gdGhpcy5hc3NldHNba2V5XTtcclxuICAgICAgaWYgKCg8YW55PmFzc2V0KS5kaXNwb3NlKSAoPGFueT5hc3NldCkuZGlzcG9zZSgpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5hc3NldHMgPSB7fTtcclxuICB9XHJcbiAgaXNMb2FkaW5nQ29tcGxldGUoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy50b0xvYWQgPT0gMDtcclxuICB9XHJcbiAgZ2V0VG9Mb2FkKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy50b0xvYWQ7XHJcbiAgfVxyXG4gIGdldExvYWRlZCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMubG9hZGVkO1xyXG4gIH1cclxuICBkaXNwb3NlKCkge1xyXG4gICAgdGhpcy5yZW1vdmVBbGwoKTtcclxuICB9XHJcbiAgaGFzRXJyb3JzKCkge1xyXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZXJyb3JzKS5sZW5ndGggPiAwO1xyXG4gIH1cclxuICBnZXRFcnJvcnMoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5lcnJvcnM7XHJcbiAgfVxyXG59XHJcbiJdfQ==