/****************************************************************************** * Spine Runtimes License Agreement * Last updated April 5, 2025. Replaces all prior versions. * * Copyright (c) 2013-2025, 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. * * THE SPINE RUNTIMES ARE 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 * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ import { TextureAtlas } from "./TextureAtlas.js"; export class AssetManagerBase { textureLoader; pathPrefix; downloader; cache; errors = {}; toLoad = 0; loaded = 0; texturePmaInfo = {}; constructor(textureLoader, pathPrefix = "", downloader = new Downloader(), cache = new AssetCache()) { this.textureLoader = textureLoader; this.pathPrefix = pathPrefix; this.downloader = downloader; this.cache = cache; } start(path) { this.toLoad++; return this.pathPrefix + path; } success(callback, path, asset) { this.toLoad--; this.loaded++; this.cache.assets[path] = asset; this.cache.assetsRefCount[path] = (this.cache.assetsRefCount[path] || 0) + 1; if (callback) callback(path, asset); } error(callback, path, message) { this.toLoad--; this.loaded++; this.errors[path] = message; if (callback) callback(path, message); } loadAll() { const promise = new Promise((resolve, reject) => { const check = () => { if (this.isLoadingComplete()) { if (this.hasErrors()) reject(this.errors); else resolve(this); return; } requestAnimationFrame(check); }; requestAnimationFrame(check); }); return promise; } setRawDataURI(path, data) { this.downloader.rawDataUris[this.pathPrefix + path] = data; } loadBinary(path, success = () => { }, error = () => { }) { path = this.start(path); if (this.reuseAssets(path, success, error)) return; this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { this.downloader.downloadBinary(path, (data) => { this.success(success, path, data); resolve(data); }, (status, responseText) => { const errorMsg = `Couldn't load binary ${path}: status ${status}, ${responseText}`; this.error(error, path, errorMsg); reject(errorMsg); }); }); } loadText(path, success = () => { }, error = () => { }) { path = this.start(path); this.downloader.downloadText(path, (data) => { this.success(success, path, data); }, (status, responseText) => { this.error(error, path, `Couldn't load text ${path}: status ${status}, ${responseText}`); }); } loadJson(path, success = () => { }, error = () => { }) { path = this.start(path); if (this.reuseAssets(path, success, error)) return; this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { this.downloader.downloadJson(path, (data) => { this.success(success, path, data); resolve(data); }, (status, responseText) => { const errorMsg = `Couldn't load JSON ${path}: status ${status}, ${responseText}`; this.error(error, path, errorMsg); reject(errorMsg); }); }); } reuseAssets(path, success = () => { }, error = () => { }) { const loadedStatus = this.cache.getAsset(path); const alreadyExistsOrLoading = loadedStatus !== undefined; if (alreadyExistsOrLoading) { this.cache.assetsLoaded[path] = loadedStatus .then(data => { // necessary when user preloads an image into the cache. // texture loader is not avaiable in the cache, so we transform in GLTexture at first use data = (data instanceof Image || data instanceof ImageBitmap) ? this.textureLoader(data) : data; this.success(success, path, data); return data; }) .catch(errorMsg => { this.error(error, path, errorMsg); return undefined; }); } return alreadyExistsOrLoading; } loadTexture(path, success = () => { }, error = () => { }) { path = this.start(path); if (this.reuseAssets(path, success, error)) return; const pma = this.texturePmaInfo[path]; this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { const isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document); const isWebWorker = !isBrowser; // && typeof importScripts !== 'undefined'; if (isWebWorker) { fetch(path, { mode: "cors" }).then((response) => { if (response.ok) return response.blob(); const errorMsg = `Couldn't load image: ${path}`; this.error(error, path, `Couldn't load image: ${path}`); reject(errorMsg); }).then((blob) => { return blob ? createImageBitmap(blob, { premultiplyAlpha: "none", colorSpaceConversion: "none" }) : null; }).then((bitmap) => { if (bitmap) { const texture = this.createTexture(path, pma, bitmap); this.success(success, path, texture); resolve(texture); } ; }); } else { const image = new Image(); image.crossOrigin = "anonymous"; image.onload = () => { const texture = this.createTexture(path, pma, image); this.success(success, path, texture); resolve(texture); }; image.onerror = () => { const errorMsg = `Couldn't load image: ${path}`; this.error(error, path, errorMsg); reject(errorMsg); }; if (this.downloader.rawDataUris[path]) path = this.downloader.rawDataUris[path]; image.src = path; } }); } loadTextureAtlas(path, success = () => { }, error = () => { }, fileAlias) { const index = path.lastIndexOf("/"); const parent = index >= 0 ? path.substring(0, index + 1) : ""; path = this.start(path); if (this.reuseAssets(path, success, error)) return; this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { this.downloader.downloadText(path, (atlasText) => { try { const atlas = this.createTextureAtlas(atlasText, parent, path, fileAlias); let toLoad = atlas.pages.length, abort = false; if (toLoad === 0) { this.success(success, path, atlas); resolve(atlas); return; } for (const page of atlas.pages) { this.loadTexture(this.texturePath(parent, page.name, fileAlias), (imagePath, texture) => { if (!abort) { page.setTexture(texture); if (--toLoad === 0) { this.success(success, path, atlas); resolve(atlas); } } }, (imagePath, message) => { if (!abort) { const errorMsg = `Couldn't load texture ${path} page image: ${imagePath}`; this.error(error, path, errorMsg); reject(errorMsg); } abort = true; }); } } catch (e) { const errorMsg = `Couldn't parse texture atlas ${path}: ${e.message}`; this.error(error, path, errorMsg); reject(errorMsg); } }, (status, responseText) => { const errorMsg = `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`; this.error(error, path, errorMsg); reject(errorMsg); }); }); } loadTextureAtlasButNoTextures(path, success = () => { }, error = () => { }) { const index = path.lastIndexOf("/"); const parent = index >= 0 ? path.substring(0, index + 1) : ""; path = this.start(path); if (this.reuseAssets(path, success, error)) return; this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { this.downloader.downloadText(path, (atlasText) => { try { const atlas = this.createTextureAtlas(atlasText, parent, path); this.success(success, path, atlas); resolve(atlas); } catch (e) { const errorMsg = `Couldn't parse texture atlas ${path}: ${e.message}`; this.error(error, path, errorMsg); reject(errorMsg); } }, (status, responseText) => { const errorMsg = `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`; this.error(error, path, errorMsg); reject(errorMsg); }); }); } async loadBinaryAsync(path) { return new Promise((resolve, reject) => { this.loadBinary(path, (_, binary) => resolve(binary), (_, message) => reject(message)); }); } async loadJsonAsync(path) { return new Promise((resolve, reject) => { this.loadJson(path, (_, object) => resolve(object), (_, message) => reject(message)); }); } async loadTextureAsync(path) { return new Promise((resolve, reject) => { this.loadTexture(path, (_, texture) => resolve(texture), (_, message) => reject(message)); }); } async loadTextureAtlasAsync(path) { return new Promise((resolve, reject) => { this.loadTextureAtlas(path, (_, atlas) => resolve(atlas), (_, message) => reject(message)); }); } async loadTextureAtlasButNoTexturesAsync(path) { return new Promise((resolve, reject) => { this.loadTextureAtlasButNoTextures(path, (_, atlas) => resolve(atlas), (_, message) => reject(message)); }); } setCache(cache) { this.cache = cache; } get(path) { return this.cache.assets[this.pathPrefix + path]; } require(path) { path = this.pathPrefix + path; const asset = this.cache.assets[path]; if (asset) return asset; const error = this.errors[path]; throw Error(`Asset not found: ${path}${error ? `\n${error}` : ""}`); } remove(path) { path = this.pathPrefix + path; const asset = this.cache.assets[path]; if (asset.dispose) asset.dispose(); delete this.cache.assets[path]; delete this.cache.assetsRefCount[path]; delete this.cache.assetsLoaded[path]; return asset; } removeAll() { for (const path in this.cache.assets) { const asset = this.cache.assets[path]; if (asset.dispose) asset.dispose(); } this.cache.assets = {}; this.cache.assetsLoaded = {}; this.cache.assetsRefCount = {}; } isLoadingComplete() { return this.toLoad === 0; } getToLoad() { return this.toLoad; } getLoaded() { return this.loaded; } dispose() { this.removeAll(); } // dispose asset only if it's not used by others disposeAsset(path) { const asset = this.cache.assets[path]; if (asset instanceof TextureAtlas) { asset.dispose(); return; } this.disposeAssetInternal(path); } hasErrors() { return Object.keys(this.errors).length > 0; } getErrors() { return this.errors; } disposeAssetInternal(path) { if (this.cache.assetsRefCount[path] > 0 && --this.cache.assetsRefCount[path] === 0) { return this.remove(path); } } createTextureAtlas(atlasText, parentPath, path, fileAlias) { const atlas = new TextureAtlas(atlasText); atlas.dispose = () => { if (this.cache.assetsRefCount[path] <= 0) return; this.disposeAssetInternal(path); for (const page of atlas.pages) { page.texture?.dispose(); } }; for (const page of atlas.pages) { const texturePath = this.texturePath(parentPath, page.name, fileAlias); this.texturePmaInfo[this.pathPrefix + texturePath] = page.pma; } return atlas; } createTexture(path, pma, image) { const texture = this.textureLoader(image, pma); const textureDispose = texture.dispose.bind(texture); texture.dispose = () => { if (this.disposeAssetInternal(path)) textureDispose(); }; return texture; } texturePath(parentPath, pageName, fileAlias) { if (!fileAlias) return parentPath + pageName; return fileAlias[pageName]; } } export class AssetCache { assets = {}; assetsRefCount = {}; assetsLoaded = {}; static AVAILABLE_CACHES = new Map(); static getCache(id) { const cache = AssetCache.AVAILABLE_CACHES.get(id); if (cache) return cache; const newCache = new AssetCache(); AssetCache.AVAILABLE_CACHES.set(id, newCache); return newCache; } async addAsset(path, asset) { this.assetsLoaded[path] = Promise.resolve(asset); this.assets[path] = asset; return asset; } getAsset(path) { return this.assetsLoaded[path]; } } export class Downloader { callbacks = {}; rawDataUris = {}; dataUriToString(dataUri) { if (!dataUri.startsWith("data:")) { throw new Error("Not a data URI."); } let base64Idx = dataUri.indexOf("base64,"); if (base64Idx !== -1) { base64Idx += "base64,".length; return atob(dataUri.substr(base64Idx)); } else { return dataUri.substr(dataUri.indexOf(",") + 1); } } base64ToUint8Array(base64) { var binary_string = window.atob(base64); var len = binary_string.length; var bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i); } return bytes; } dataUriToUint8Array(dataUri) { if (!dataUri.startsWith("data:")) { throw new Error("Not a data URI."); } let base64Idx = dataUri.indexOf("base64,"); if (base64Idx === -1) throw new Error("Not a binary data URI."); base64Idx += "base64,".length; return this.base64ToUint8Array(dataUri.substr(base64Idx)); } downloadText(url, success, error) { if (this.start(url, success, error)) return; const rawDataUri = this.rawDataUris[url]; // we assume if a "." is included in a raw data uri, it is used to rewrite an asset URL if (rawDataUri && !rawDataUri.includes(".")) { try { this.finish(url, 200, this.dataUriToString(rawDataUri)); } catch (e) { this.finish(url, 400, JSON.stringify(e)); } return; } const request = new XMLHttpRequest(); request.overrideMimeType("text/html"); request.open("GET", rawDataUri ? rawDataUri : url, true); const done = () => { this.finish(url, request.status, request.responseText); }; request.onload = done; request.onerror = done; request.send(); } downloadJson(url, success, error) { this.downloadText(url, (data) => { success(JSON.parse(data)); }, error); } downloadBinary(url, success, error) { if (this.start(url, success, error)) return; const rawDataUri = this.rawDataUris[url]; // we assume if a "." is included in a raw data uri, it is used to rewrite an asset URL if (rawDataUri && !rawDataUri.includes(".")) { try { this.finish(url, 200, this.dataUriToUint8Array(rawDataUri)); } catch (e) { this.finish(url, 400, JSON.stringify(e)); } return; } const request = new XMLHttpRequest(); request.open("GET", rawDataUri ? rawDataUri : url, true); request.responseType = "arraybuffer"; const onerror = () => { this.finish(url, request.status, request.response); }; request.onload = () => { if (request.status === 200 || request.status === 0) this.finish(url, 200, new Uint8Array(request.response)); else onerror(); }; request.onerror = onerror; request.send(); } start(url, success, error) { let callbacks = this.callbacks[url]; try { if (callbacks) return true; this.callbacks[url] = callbacks = []; } finally { callbacks.push(success, error); } } finish(url, status, data) { const callbacks = this.callbacks[url]; delete this.callbacks[url]; if (status === 200 || status === 0) { for (let i = 0, n = callbacks.length; i < n; i += 2) callbacks[i](data); } else { for (let i = 1, n = callbacks.length; i < n; i += 2) callbacks[i](status, data); } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXNzZXRNYW5hZ2VyQmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Bc3NldE1hbmFnZXJCYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUcvRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFTakQsTUFBTSxPQUFPLGdCQUFnQjtJQU9uQjtJQUNBO0lBQ0E7SUFDQTtJQVRELE1BQU0sR0FBc0IsRUFBRSxDQUFDO0lBQy9CLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDWCxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ1gsY0FBYyxHQUE0QixFQUFFLENBQUM7SUFFckQsWUFDUyxhQUE0QixFQUM1QixhQUFxQixFQUFFLEVBQ3ZCLGFBQWEsSUFBSSxVQUFVLEVBQUUsRUFDN0IsUUFBUSxJQUFJLFVBQVUsRUFBRTtRQUh4QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUM1QixlQUFVLEdBQVYsVUFBVSxDQUFhO1FBQ3ZCLGVBQVUsR0FBVixVQUFVLENBQW1CO1FBQzdCLFVBQUssR0FBTCxLQUFLLENBQW1CO0lBQ2pDLENBQUM7SUFFTyxLQUFLLENBQUUsSUFBWTtRQUMxQixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZCxPQUFPLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO0lBQy9CLENBQUM7SUFFTyxPQUFPLENBQXVCLFFBQTBCLEVBQUUsSUFBWSxFQUFFLEtBQVE7UUFDdkYsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2QsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFj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QUFDLENBQUM7UUFDM0IsSUFBSSxNQUFNLEtBQUssR0FBRyxJQUFJLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNwQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDO2dCQUNqRCxTQUFTLENBQUMsQ0FBQyxDQUErQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BELENBQUM7YUFBTSxDQUFDO1lBQ1AsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQztnQkFDakQsU0FBUyxDQUFDLENBQUMsQ0FBNkIsQ0FBQyxNQUFNLEVBQUUsSUFBYyxDQUFDLENBQUM7UUFDcEUsQ0FBQztJQUNGLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBUZXh0dXJlIH0gZnJvbSBcIi4vVGV4dHVyZS5qc1wiO1xuaW1wb3J0IHsgVGV4dHVyZUF0bGFzIH0gZnJvbSBcIi4vVGV4dHVyZUF0bGFzLmpzXCI7XG5pbXBvcnQgdHlwZSB7IERpc3Bvc2FibGUsIFN0cmluZ01hcCB9IGZyb20gXCIuL1V0aWxzLmpzXCI7XG5cbnR5cGUgQXNzZXREYXRhID0gKFVpbnQ4QXJyYXkgfCBzdHJpbmcgfCBUZXh0dXJlIHwgVGV4dHVyZUF0bGFzIHwgb2JqZWN0KSAmIFBhcnRpYWw8RGlzcG9zYWJsZT47XG50eXBlIEFzc2V0Q2FsbGJhY2s8VCBleHRlbmRzIEFzc2V0RGF0YT4gPSAocGF0aDogc3RyaW5nLCBkYXRhOiBUKSA9PiB2b2lkO1xudHlwZSBFcnJvckNhbGxiYWNrID0gKHBhdGg6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkO1xuXG5leHBvcnQgdHlwZSBUZXh0dXJlTG9hZGVyID0gKGltYWdlOiBIVE1MSW1hZ2VFbGVtZW50IHwgSW1hZ2VCaXRtYXAsIHBtYT86IGJvb2xlYW4pID0+IFRleHR1cmU7XG5cbmV4cG9ydCBjbGFzcyBBc3NldE1hbmFnZXJCYXNlIGltcGxlbWVudHMgRGlzcG9zYWJsZSB7XG5cdHByaXZhdGUgZXJyb3JzOiBTdHJpbmdNYXA8c3RyaW5nPiA9IHt9O1xuXHRwcml2YXRlIHRvTG9hZCA9IDA7XG5cdHByaXZhdGUgbG9hZGVkID0gMDtcblx0cHJpdmF0ZSB0ZXh0dXJlUG1hSW5mbzogUmVjb3JkPHN0cmluZywgYm9vbGVhbj4gPSB7fTtcblxuXHRjb25zdHJ1Y3RvciAoXG5cdFx0cHJpdmF0ZSB0ZXh0dXJlTG9hZGVyOiBUZXh0dXJlTG9hZGVyLFxuXHRcdHByaXZhdGUgcGF0aFByZWZpeDogc3RyaW5nID0gXCJcIixcblx0XHRwcml2YXRlIGRvd25sb2FkZXIgPSBuZXcgRG93bmxvYWRlcigpLFxuXHRcdHByaXZhdGUgY2FjaGUgPSBuZXcgQXNzZXRDYWNoZSgpKSB7XG5cdH1cblxuXHRwcml2YXRlIHN0YXJ0IChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuXHRcdHRoaXMudG9Mb2FkKys7XG5cdFx0cmV0dXJuIHRoaXMucGF0aFByZWZpeCArIHBhdGg7XG5cdH1cblxuXHRwcml2YXRlIHN1Y2Nlc3M8VCBleHRlbmRzIEFzc2V0RGF0YT4gKGNhbGxiYWNrOiBBc3NldENhbGxiYWNrPFQ+LCBwYXRoOiBzdHJpbmcsIGFzc2V0OiBUKSB7XG5cdFx0dGhpcy50b0xvYWQtLTtcblx0XHR0aGlzLmxvYWRlZCsrO1xuXHRcdHRoaXMuY2FjaGUuYXNzZXRzW3BhdGhdID0gYXNzZXQ7XG5cdFx0dGhpcy5jYWNoZS5hc3NldHNSZWZDb3VudFtwYXRoXSA9ICh0aGlzLmNhY2hlLmFzc2V0c1JlZkNvdW50W3BhdGhdIHx8IDApICsgMTtcblx0XHRpZiAoY2FsbGJhY2spIGNhbGxiYWNrKHBhdGgsIGFzc2V0KTtcblx0fVxuXG5cdHByaXZhdGUgZXJyb3IgKGNhbGxiYWNrOiAocGF0aDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQsIHBhdGg6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKSB7XG5cdFx0dGhpcy50b0xvYWQtLTtcblx0XHR0aGlzLmxvYWRlZCsrO1xuXHRcdHRoaXMuZXJyb3JzW3BhdGhdID0gbWVzc2FnZTtcblx0XHRpZiAoY2FsbGJhY2spIGNhbGxiYWNrKHBhdGgsIG1lc3NhZ2UpO1xuXHR9XG5cblx0bG9hZEFsbCAoKSB7XG5cdFx0Y29uc3QgcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlOiAoYXNzZXRNYW5hZ2VyOiBBc3NldE1hbmFnZXJCYXNlKSA9PiB2b2lkLCByZWplY3Q6IChlcnJvcnM6IFN0cmluZ01hcDxzdHJpbmc+KSA9PiB2b2lkKSA9PiB7XG5cdFx0XHRjb25zdCBjaGVjayA9ICgpID0+IHtcblx0XHRcdFx0aWYgKHRoaXMuaXNMb2FkaW5nQ29tcGxldGUoKSkge1xuXHRcdFx0XHRcdGlmICh0aGlzLmhhc0Vycm9ycygpKSByZWplY3QodGhpcy5lcnJvcnMpO1xuXHRcdFx0XHRcdGVsc2UgcmVzb2x2ZSh0aGlzKTtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0cmVxdWVzdEFuaW1hdGlvbkZyYW1lKGNoZWNrKTtcblx0XHRcdH1cblx0XHRcdHJlcXVlc3RBbmltYXRpb25GcmFtZShjaGVjayk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHByb21pc2U7XG5cdH1cblxuXHRzZXRSYXdEYXRhVVJJIChwYXRoOiBzdHJpbmcsIGRhdGE6IHN0cmluZykge1xuXHRcdHRoaXMuZG93bmxvYWRlci5yYXdEYXRhVXJpc1t0aGlzLnBhdGhQcmVmaXggKyBwYXRoXSA9IGRhdGE7XG5cdH1cblxuXHRsb2FkQmluYXJ5IChwYXRoOiBzdHJpbmcsXG5cdFx0c3VjY2VzczogKHBhdGg6IHN0cmluZywgYmluYXJ5OiBVaW50OEFycmF5KSA9PiB2b2lkID0gKCkgPT4geyB9LFxuXHRcdGVycm9yOiAocGF0aDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQgPSAoKSA9PiB7IH0pIHtcblx0XHRwYXRoID0gdGhpcy5zdGFydChwYXRoKTtcblxuXHRcdGlmICh0aGlzLnJldXNlQXNzZXRzKHBhdGgsIHN1Y2Nlc3MsIGVycm9yKSkgcmV0dXJuO1xuXG5cdFx0dGhpcy5jYWNoZS5hc3NldHNMb2FkZWRbcGF0aF0gPSBuZXcgUHJvbWlzZTxVaW50OEFycmF5PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cdFx0XHR0aGlzLmRvd25sb2FkZXIuZG93bmxvYWRCaW5hcnkocGF0aCwgKGRhdGE6IFVpbnQ4QXJyYXkpOiB2b2lkID0+IHtcblx0XHRcdFx0dGhpcy5zdWNjZXNzKHN1Y2Nlc3MsIHBhdGgsIGRhdGEpO1xuXHRcdFx0XHRyZXNvbHZlKGRhdGEpO1xuXHRcdFx0fSwgKHN0YXR1czogbnVtYmVyLCByZXNwb25zZVRleHQ6IHN0cmluZyk6IHZvaWQgPT4ge1xuXHRcdFx0XHRjb25zdCBlcnJvck1zZyA9IGBDb3VsZG4ndCBsb2FkIGJpbmFyeSAke3BhdGh9OiBzdGF0dXMgJHtzdGF0dXN9LCAke3Jlc3BvbnNlVGV4dH1gO1xuXHRcdFx0XHR0aGlzLmVycm9yKGVycm9yLCBwYXRoLCBlcnJvck1zZyk7XG5cdFx0XHRcdHJlamVjdChlcnJvck1zZyk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdGxvYWRUZXh0IChwYXRoOiBzdHJpbmcsXG5cdFx0c3VjY2VzczogKHBhdGg6IHN0cmluZywgdGV4dDogc3RyaW5nKSA9PiB2b2lkID0gKCkgPT4geyB9LFxuXHRcdGVycm9yOiAocGF0aDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQgPSAoKSA9PiB7IH0pIHtcblx0XHRwYXRoID0gdGhpcy5zdGFydChwYXRoKTtcblxuXHRcdHRoaXMuZG93bmxvYWRlci5kb3dubG9hZFRleHQocGF0aCwgKGRhdGE6IHN0cmluZyk6IHZvaWQgPT4ge1xuXHRcdFx0dGhpcy5zdWNjZXNzKHN1Y2Nlc3MsIHBhdGgsIGRhdGEpO1xuXHRcdH0sIChzdGF0dXM6IG51bWJlciwgcmVzcG9uc2VUZXh0OiBzdHJpbmcpOiB2b2lkID0+IHtcblx0XHRcdHRoaXMuZXJyb3IoZXJyb3IsIHBhdGgsIGBDb3VsZG4ndCBsb2FkIHRleHQgJHtwYXRofTogc3RhdHVzICR7c3RhdHVzfSwgJHtyZXNwb25zZVRleHR9YCk7XG5cdFx0fSk7XG5cdH1cblxuXHRsb2FkSnNvbiAocGF0aDogc3RyaW5nLFxuXHRcdHN1Y2Nlc3M6IChwYXRoOiBzdHJpbmcsIG9iamVjdDogb2JqZWN0KSA9PiB2b2lkID0gKCkgPT4geyB9LFxuXHRcdGVycm9yOiAocGF0aDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQgPSAoKSA9PiB7IH0pIHtcblx0XHRwYXRoID0gdGhpcy5zdGFydChwYXRoKTtcblxuXHRcdGlmICh0aGlzLnJldXNlQXNzZXRzKHBhdGgsIHN1Y2Nlc3MsIGVycm9yKSkgcmV0dXJuO1xuXG5cdFx0dGhpcy5jYWNoZS5hc3NldHNMb2FkZWRbcGF0aF0gPSBuZXcgUHJvbWlzZTxvYmplY3Q+KChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHRcdHRoaXMuZG93bmxvYWRlci5kb3dubG9hZEpzb24ocGF0aCwgKGRhdGE6IG9iamVjdCk6IHZvaWQgPT4ge1xuXHRcdFx0XHR0aGlzLnN1Y2Nlc3Moc3VjY2VzcywgcGF0aCwgZGF0YSk7XG5cdFx0XHRcdHJlc29sdmUoZGF0YSk7XG5cdFx0XHR9LCAoc3RhdHVzOiBudW1iZXIsIHJlc3BvbnNlVGV4dDogc3RyaW5nKTogdm9pZCA9PiB7XG5cdFx0XHRcdGNvbnN0IGVycm9yTXNnID0gYENvdWxkbid0IGxvYWQgSlNPTiAke3BhdGh9OiBzdGF0dXMgJHtzdGF0dXN9LCAke3Jlc3BvbnNlVGV4dH1gO1xuXHRcdFx0XHR0aGlzLmVycm9yKGVycm9yLCBwYXRoLCBlcnJvck1zZyk7XG5cdFx0XHRcdHJlamVjdChlcnJvck1zZyk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cblx0cmV1c2VBc3NldHM8VCBleHRlbmRzIEFzc2V0RGF0YT4gKFxuXHRcdHBhdGg6IHN0cmluZyxcblx0XHRzdWNjZXNzOiBBc3NldENhbGxiYWNrPFQ+ID0gKCkgPT4geyB9LFxuXHRcdGVycm9yOiBFcnJvckNhbGxiYWNrID0gKCkgPT4geyB9XG5cdCkge1xuXHRcdGNvbnN0IGxvYWRlZFN0YXR1cyA9IHRoaXMuY2FjaGUuZ2V0QXNzZXQocGF0aCk7XG5cdFx0Y29uc3QgYWxyZWFkeUV4aXN0c09yTG9hZGluZyA9IGxvYWRlZFN0YXR1cyAhPT0gdW5kZWZpbmVkO1xuXHRcdGlmIChhbHJlYWR5RXhpc3RzT3JMb2FkaW5nKSB7XG5cdFx0XHR0aGlzLmNhY2hlLmFzc2V0c0xvYWRlZFtwYXRoXSA9IGxvYWRlZFN0YXR1c1xuXHRcdFx0XHQudGhlbihkYXRhID0+IHtcblx0XHRcdFx0XHQvLyBuZWNlc3Nhcnkgd2hlbiB1c2VyIHByZWxvYWRzIGFuIGltYWdlIGludG8gdGhlIGNhY2hlLlxuXHRcdFx0XHRcdC8vIHRleHR1cmUgbG9hZGVyIGlzIG5vdCBhdmFpYWJsZSBpbiB0aGUgY2FjaGUsIHNvIHdlIHRyYW5zZm9ybSBpbiBHTFRleHR1cmUgYXQgZmlyc3QgdXNlXG5cdFx0XHRcdFx0ZGF0YSA9IChkYXRhIGluc3RhbmNlb2YgSW1hZ2UgfHwgZGF0YSBpbnN0YW5jZW9mIEltYWdlQml0bWFwKSA/IHRoaXMudGV4dHVyZUxvYWRlcihkYXRhKSBhcyBUIDogZGF0YTtcblx0XHRcdFx0XHR0aGlzLnN1Y2Nlc3Moc3VjY2VzcywgcGF0aCwgZGF0YSBhcyBUKTtcblx0XHRcdFx0XHRyZXR1cm4gZGF0YTtcblx0XHRcdFx0fSlcblx0XHRcdFx0LmNhdGNoKGVycm9yTXNnID0+IHtcblx0XHRcdFx0XHR0aGlzLmVycm9yKGVycm9yLCBwYXRoLCBlcnJvck1zZyk7XG5cdFx0XHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHRcdFx0fSk7XG5cdFx0fVxuXHRcdHJldHVybiBhbHJlYWR5RXhpc3RzT3JMb2FkaW5nO1xuXHR9XG5cblx0bG9hZFRleHR1cmUgKFxuXHRcdHBhdGg6IHN0cmluZyxcblx0XHRzdWNjZXNzOiBBc3NldENhbGxiYWNrPFRleHR1cmU+ID0gKCkgPT4geyB9LFxuXHRcdGVycm9yOiBFcnJvckNhbGxiYWNrID0gKCkgPT4geyB9XG5cdCkge1xuXG5cdFx0cGF0aCA9IHRoaXMuc3RhcnQocGF0aCk7XG5cblx0XHRpZiAodGhpcy5yZXVzZUFzc2V0cyhwYXRoLCBzdWNjZXNzLCBlcnJvcikpIHJldHVybjtcblxuXHRcdGNvbnN0IHBtYSA9IHRoaXMudGV4dHVyZVBtYUluZm9bcGF0aF07XG5cdFx0dGhpcy5jYWNoZS5hc3NldHNMb2FkZWRbcGF0aF0gPSBuZXcgUHJvbWlzZTxUZXh0dXJlPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cdFx0XHRjb25zdCBpc0Jyb3dzZXIgPSAhISh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuZG9jdW1lbnQpO1xuXHRcdFx0Y29uc3QgaXNXZWJXb3JrZXIgPSAhaXNCcm93c2VyOyAvLyAmJiB0eXBlb2YgaW1wb3J0U2NyaXB0cyAhPT0gJ3VuZGVmaW5lZCc7XG5cdFx0XHRpZiAoaXNXZWJXb3JrZXIpIHtcblx0XHRcdFx0ZmV0Y2gocGF0aCwgeyBtb2RlOiA8UmVxdWVzdE1vZGU+XCJjb3JzXCIgfSkudGhlbigocmVzcG9uc2UpID0+IHtcblx0XHRcdFx0XHRpZiAocmVzcG9uc2Uub2spIHJldHVybiByZXNwb25zZS5ibG9iKCk7XG5cdFx0XHRcdFx0Y29uc3QgZXJyb3JNc2cgPSBgQ291bGRuJ3QgbG9hZCBpbWFnZTogJHtwYXRofWA7XG5cdFx0XHRcdFx0dGhpcy5lcnJvcihlcnJvciwgcGF0aCwgYENvdWxkbid0IGxvYWQgaW1hZ2U6ICR7cGF0aH1gKTtcblx0XHRcdFx0XHRyZWplY3QoZXJyb3JNc2cpO1xuXHRcdFx0XHR9KS50aGVuKChibG9iKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIGJsb2IgPyBjcmVhdGVJbWFnZUJpdG1hcChibG9iLCB7IHByZW11bHRpcGx5QWxwaGE6IFwibm9uZVwiLCBjb2xvclNwYWNlQ29udmVyc2lvbjogXCJub25lXCIgfSkgOiBudWxsO1xuXHRcdFx0XHR9KS50aGVuKChiaXRtYXApID0+IHtcblx0XHRcdFx0XHRpZiAoYml0bWFwKSB7XG5cdFx0XHRcdFx0XHRjb25zdCB0ZXh0dXJlID0gdGhpcy5jcmVhdGVUZXh0dXJlKHBhdGgsIHBtYSwgYml0bWFwKTtcblx0XHRcdFx0XHRcdHRoaXMuc3VjY2VzcyhzdWNjZXNzLCBwYXRoLCB0ZXh0dXJlKTtcblx0XHRcdFx0XHRcdHJlc29sdmUodGV4dHVyZSk7XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjb25zdCBpbWFnZSA9IG5ldyBJbWFnZSgpO1xuXHRcdFx0XHRpbWFnZS5jcm9zc09yaWdpbiA9IFwiYW5vbnltb3VzXCI7XG5cdFx0XHRcdGltYWdlLm9ubG9hZCA9ICgpID0+IHtcblx0XHRcdFx0XHRjb25zdCB0ZXh0dXJlID0gdGhpcy5jcmVhdGVUZXh0dXJlKHBhdGgsIHBtYSwgaW1hZ2UpO1xuXHRcdFx0XHRcdHRoaXMuc3VjY2VzcyhzdWNjZXNzLCBwYXRoLCB0ZXh0dXJlKTtcblx0XHRcdFx0XHRyZXNvbHZlKHRleHR1cmUpO1xuXHRcdFx0XHR9O1xuXHRcdFx0XHRpbWFnZS5vbmVycm9yID0gKCkgPT4ge1xuXHRcdFx0XHRcdGNvbnN0IGVycm9yTXNnID0gYENvdWxkbid0IGxvYWQgaW1hZ2U6ICR7cGF0aH1gO1xuXHRcdFx0XHRcdHRoaXMuZXJyb3IoZXJyb3IsIHBhdGgsIGVycm9yTXNnKTtcblx0XHRcdFx0XHRyZWplY3QoZXJyb3JNc2cpO1xuXHRcdFx0XHR9O1xuXHRcdFx0XHRpZiAodGhpcy5kb3dubG9hZGVyLnJhd0RhdGFVcmlzW3BhdGhdKSBwYXRoID0gdGhpcy5kb3dubG9hZGVyLnJhd0RhdGFVcmlzW3BhdGhdO1xuXHRcdFx0XHRpbWFnZS5zcmMgPSBwYXRoO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cblx0bG9hZFRleHR1cmVBdGxhcyAoXG5cdFx0cGF0aDogc3RyaW5nLFxuXHRcdHN1Y2Nlc3M6IEFzc2V0Q2FsbGJhY2s8VGV4dHVyZUF0bGFzPiA9ICgpID0+IHsgfSxcblx0XHRlcnJvcjogRXJyb3JDYWxsYmFjayA9ICgpID0+IHsgfSxcblx0XHRmaWxlQWxpYXM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+XG5cdCkge1xuXHRcdGNvbnN0IGluZGV4ID0gcGF0aC5sYXN0SW5kZXhPZihcIi9cIik7XG5cdFx0Y29uc3QgcGFyZW50ID0gaW5kZXggPj0gMCA/IHBhdGguc3Vic3RyaW5nKDAsIGluZGV4ICsgMSkgOiBcIlwiO1xuXHRcdHBhdGggPSB0aGlzLnN0YXJ0KHBhdGgpO1xuXG5cdFx0aWYgKHRoaXMucmV1c2VBc3NldHMocGF0aCwgc3VjY2VzcywgZXJyb3IpKSByZXR1cm47XG5cblx0XHR0aGlzLmNhY2hlLmFzc2V0c0xvYWRlZFtwYXRoXSA9IG5ldyBQcm9taXNlPFRleHR1cmVBdGxhcz4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdFx0dGhpcy5kb3dubG9hZGVyLmRvd25sb2FkVGV4dChwYXRoLCAoYXRsYXNUZXh0OiBzdHJpbmcpOiB2b2lkID0+IHtcblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRjb25zdCBhdGxhcyA9IHRoaXMuY3JlYXRlVGV4dHVyZUF0bGFzKGF0bGFzVGV4dCwgcGFyZW50LCBwYXRoLCBmaWxlQWxpYXMpO1xuXHRcdFx0XHRcdGxldCB0b0xvYWQgPSBhdGxhcy5wYWdlcy5sZW5ndGgsIGFib3J0ID0gZmFsc2U7XG5cblx0XHRcdFx0XHRpZiAodG9Mb2FkID09PSAwKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnN1Y2Nlc3Moc3VjY2VzcywgcGF0aCwgYXRsYXMpO1xuXHRcdFx0XHRcdFx0cmVzb2x2ZShhdGxhcyk7XG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Zm9yIChjb25zdCBwYWdlIG9mIGF0bGFzLnBhZ2VzKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmxvYWRUZXh0dXJlKFxuXHRcdFx0XHRcdFx0XHR0aGlzLnRleHR1cmVQYXRoKHBhcmVudCwgcGFnZS5uYW1lLCBmaWxlQWxpYXMpLFxuXHRcdFx0XHRcdFx0XHQoaW1hZ2VQYXRoOiBzdHJpbmcsIHRleHR1cmU6IFRleHR1cmUpID0+IHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIWFib3J0KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRwYWdlLnNldFRleHR1cmUodGV4dHVyZSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoLS10b0xvYWQgPT09IDApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5zdWNjZXNzKHN1Y2Nlc3MsIHBhdGgsIGF0bGFzKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZShhdGxhcyk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHQoaW1hZ2VQYXRoOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdGlmICghYWJvcnQpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGNvbnN0IGVycm9yTXNnID0gYENvdWxkbid0IGxvYWQgdGV4dHVyZSAke3BhdGh9IHBhZ2UgaW1hZ2U6ICR7aW1hZ2VQYXRofWA7XG5cdFx0XHRcdFx0XHRcdFx0XHR0aGlzLmVycm9yKGVycm9yLCBwYXRoLCBlcnJvck1zZyk7XG5cdFx0XHRcdFx0XHRcdFx0XHRyZWplY3QoZXJyb3JNc2cpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRhYm9ydCA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGNhdGNoIChlOiB1bmtub3duKSB7XG5cdFx0XHRcdFx0Y29uc3QgZXJyb3JNc2cgPSBgQ291bGRuJ3QgcGFyc2UgdGV4dHVyZSBhdGxhcyAke3BhdGh9OiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWA7XG5cdFx0XHRcdFx0dGhpcy5lcnJvcihlcnJvciwgcGF0aCwgZXJyb3JNc2cpO1xuXHRcdFx0XHRcdHJlamVjdChlcnJvck1zZyk7XG5cdFx0XHRcdH1cblx0XHRcdH0sIChzdGF0dXM6IG51bWJlciwgcmVzcG9uc2VUZXh0OiBzdHJpbmcpOiB2b2lkID0+IHtcblx0XHRcdFx0Y29uc3QgZXJyb3JNc2cgPSBgQ291bGRuJ3QgbG9hZCB0ZXh0dXJlIGF0bGFzICR7cGF0aH06IHN0YXR1cyAke3N0YXR1c30sICR7cmVzcG9uc2VUZXh0fWA7XG5cdFx0XHRcdHRoaXMuZXJyb3IoZXJyb3IsIHBhdGgsIGVycm9yTXNnKTtcblx0XHRcdFx0cmVqZWN0KGVycm9yTXNnKTtcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG5cblx0bG9hZFRleHR1cmVBdGxhc0J1dE5vVGV4dHVyZXMgKFxuXHRcdHBhdGg6IHN0cmluZyxcblx0XHRzdWNjZXNzOiBBc3NldENhbGxiYWNrPFRleHR1cmVBdGxhcz4gPSAoKSA9PiB7IH0sXG5cdFx0ZXJyb3I6IEVycm9yQ2FsbGJhY2sgPSAoKSA9PiB7IH0sXG5cdCkge1xuXHRcdGNvbnN0IGluZGV4ID0gcGF0aC5sYXN0SW5kZXhPZihcIi9cIik7XG5cdFx0Y29uc3QgcGFyZW50ID0gaW5kZXggPj0gMCA/IHBhdGguc3Vic3RyaW5nKDAsIGluZGV4ICsgMSkgOiBcIlwiO1xuXHRcdHBhdGggPSB0aGlzLnN0YXJ0KHBhdGgpO1xuXG5cdFx0aWYgKHRoaXMucmV1c2VBc3NldHMocGF0aCwgc3VjY2VzcywgZXJyb3IpKSByZXR1cm47XG5cblx0XHR0aGlzLmNhY2hlLmFzc2V0c0xvYWRlZFtwYXRoXSA9IG5ldyBQcm9taXNlPFRleHR1cmVBdGxhcz4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdFx0dGhpcy5kb3dubG9hZGVyLmRvd25sb2FkVGV4dChwYXRoLCAoYXRsYXNUZXh0OiBzdHJpbmcpOiB2b2lkID0+IHtcblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRjb25zdCBhdGxhcyA9IHRoaXMuY3JlYXRlVGV4dHVyZUF0bGFzKGF0bGFzVGV4dCwgcGFyZW50LCBwYXRoKTtcblx0XHRcdFx0XHR0aGlzLnN1Y2Nlc3Moc3VjY2VzcywgcGF0aCwgYXRsYXMpO1xuXHRcdFx0XHRcdHJlc29sdmUoYXRsYXMpO1xuXHRcdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdFx0Y29uc3QgZXJyb3JNc2cgPSBgQ291bGRuJ3QgcGFyc2UgdGV4dHVyZSBhdGxhcyAke3BhdGh9OiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWA7XG5cdFx0XHRcdFx0dGhpcy5lcnJvcihlcnJvciwgcGF0aCwgZXJyb3JNc2cpO1xuXHRcdFx0XHRcdHJlamVjdChlcnJvck1zZyk7XG5cdFx0XHRcdH1cblx0XHRcdH0sIChzdGF0dXM6IG51bWJlciwgcmVzcG9uc2VUZXh0OiBzdHJpbmcpOiB2b2lkID0+IHtcblx0XHRcdFx0Y29uc3QgZXJyb3JNc2cgPSBgQ291bGRuJ3QgbG9hZCB0ZXh0dXJlIGF0bGFzICR7cGF0aH06IHN0YXR1cyAke3N0YXR1c30sICR7cmVzcG9uc2VUZXh0fWA7XG5cdFx0XHRcdHRoaXMuZXJyb3IoZXJyb3IsIHBhdGgsIGVycm9yTXNnKTtcblx0XHRcdFx0cmVqZWN0KGVycm9yTXNnKTtcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG5cblx0YXN5bmMgbG9hZEJpbmFyeUFzeW5jIChwYXRoOiBzdHJpbmcpIHtcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdFx0dGhpcy5sb2FkQmluYXJ5KHBhdGgsXG5cdFx0XHRcdChfLCBiaW5hcnkpID0+IHJlc29sdmUoYmluYXJ5KSxcblx0XHRcdFx0KF8sIG1lc3NhZ2UpID0+IHJlamVjdChtZXNzYWdlKSxcblx0XHRcdCk7XG5cdFx0fSk7XG5cdH1cblxuXHRhc3luYyBsb2FkSnNvbkFzeW5jIChwYXRoOiBzdHJpbmcpIHtcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdFx0dGhpcy5sb2FkSnNvbihwYXRoLFxuXHRcdFx0XHQoXywgb2JqZWN0KSA9PiByZXNvbHZlKG9iamVjdCksXG5cdFx0XHRcdChfLCBtZXNzYWdlKSA9PiByZWplY3QobWVzc2FnZSksXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0YXN5bmMgbG9hZFRleHR1cmVBc3luYyAocGF0aDogc3RyaW5nKSB7XG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlPFRleHR1cmU+KChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHRcdHRoaXMubG9hZFRleHR1cmUocGF0aCxcblx0XHRcdFx0KF8sIHRleHR1cmUpID0+IHJlc29sdmUodGV4dHVyZSksXG5cdFx0XHRcdChfLCBtZXNzYWdlKSA9PiByZWplY3QobWVzc2FnZSksXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0YXN5bmMgbG9hZFRleHR1cmVBdGxhc0FzeW5jIChwYXRoOiBzdHJpbmcpIHtcblx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdFx0dGhpcy5sb2FkVGV4dHVyZUF0bGFzKHBhdGgsXG5cdFx0XHRcdChfLCBhdGxhcykgPT4gcmVzb2x2ZShhdGxhcyksXG5cdFx0XHRcdChfLCBtZXNzYWdlKSA9PiByZWplY3QobWVzc2FnZSksXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0YXN5bmMgbG9hZFRleHR1cmVBdGxhc0J1dE5vVGV4dHVyZXNBc3luYyAocGF0aDogc3RyaW5nKSB7XG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlPFRleHR1cmVBdGxhcz4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdFx0dGhpcy5sb2FkVGV4dHVyZUF0bGFzQnV0Tm9UZXh0dXJlcyhwYXRoLFxuXHRcdFx0XHQoXywgYXRsYXMpID0+IHJlc29sdmUoYXRsYXMpLFxuXHRcdFx0XHQoXywgbWVzc2FnZSkgPT4gcmVqZWN0KG1lc3NhZ2UpLFxuXHRcdFx0KTtcblx0XHR9KTtcblx0fVxuXG5cdHNldENhY2hlIChjYWNoZTogQXNzZXRDYWNoZSkge1xuXHRcdHRoaXMuY2FjaGUgPSBjYWNoZTtcblx0fVxuXG5cdGdldCAocGF0aDogc3RyaW5nKSB7XG5cdFx0cmV0dXJuIHRoaXMuY2FjaGUuYXNzZXRzW3RoaXMucGF0aFByZWZpeCArIHBhdGhdO1xuXHR9XG5cblx0cmVxdWlyZSAocGF0aDogc3RyaW5nKSB7XG5cdFx0cGF0aCA9IHRoaXMucGF0aFByZWZpeCArIHBhdGg7XG5cdFx0Y29uc3QgYXNzZXQgPSB0aGlzLmNhY2hlLmFzc2V0c1twYXRoXTtcblx0XHRpZiAoYXNzZXQpIHJldHVybiBhc3NldDtcblx0XHRjb25zdCBlcnJvciA9IHRoaXMuZXJyb3JzW3BhdGhdO1xuXHRcdHRocm93IEVycm9yKGBBc3NldCBub3QgZm91bmQ6ICR7cGF0aH0ke2Vycm9yID8gYFxcbiR7ZXJyb3J9YCA6IFwiXCJ9YCk7XG5cdH1cblxuXHRyZW1vdmUgKHBhdGg6IHN0cmluZykge1xuXHRcdHBhdGggPSB0aGlzLnBhdGhQcmVmaXggKyBwYXRoO1xuXHRcdGNvbnN0IGFzc2V0ID0gdGhpcy5jYWNoZS5hc3NldHNbcGF0aF07XG5cdFx0aWYgKGFzc2V0LmRpc3Bvc2UpIGFzc2V0LmRpc3Bvc2UoKTtcblx0XHRkZWxldGUgdGhpcy5jYWNoZS5hc3NldHNbcGF0aF07XG5cdFx0ZGVsZXRlIHRoaXMuY2FjaGUuYXNzZXRzUmVmQ291bnRbcGF0aF07XG5cdFx0ZGVsZXRlIHRoaXMuY2FjaGUuYXNzZXRzTG9hZGVkW3BhdGhdO1xuXHRcdHJldHVybiBhc3NldDtcblx0fVxuXG5cdHJlbW92ZUFsbCAoKSB7XG5cdFx0Zm9yIChjb25zdCBwYXRoIGluIHRoaXMuY2FjaGUuYXNzZXRzKSB7XG5cdFx0XHRjb25zdCBhc3NldCA9IHRoaXMuY2FjaGUuYXNzZXRzW3BhdGhdO1xuXHRcdFx0aWYgKGFzc2V0LmRpc3Bvc2UpIGFzc2V0LmRpc3Bvc2UoKTtcblx0XHR9XG5cdFx0dGhpcy5jYWNoZS5hc3NldHMgPSB7fTtcblx0XHR0aGlzLmNhY2hlLmFzc2V0c0xvYWRlZCA9IHt9O1xuXHRcdHRoaXMuY2FjaGUuYXNzZXRzUmVmQ291bnQgPSB7fTtcblx0fVxuXG5cdGlzTG9hZGluZ0NvbXBsZXRlICgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy50b0xvYWQgPT09IDA7XG5cdH1cblxuXHRnZXRUb0xvYWQgKCk6IG51bWJlciB7XG5cdFx0cmV0dXJuIHRoaXMudG9Mb2FkO1xuXHR9XG5cblx0Z2V0TG9hZGVkICgpOiBudW1iZXIge1xuXHRcdHJldHVybiB0aGlzLmxvYWRlZDtcblx0fVxuXG5cdGRpc3Bvc2UgKCkge1xuXHRcdHRoaXMucmVtb3ZlQWxsKCk7XG5cdH1cblxuXHQvLyBkaXNwb3NlIGFzc2V0IG9ubHkgaWYgaXQncyBub3QgdXNlZCBieSBvdGhlcnNcblx0ZGlzcG9zZUFzc2V0IChwYXRoOiBzdHJpbmcpIHtcblx0XHRjb25zdCBhc3NldCA9IHRoaXMuY2FjaGUuYXNzZXRzW3BhdGhdO1xuXHRcdGlmIChhc3NldCBpbnN0YW5jZW9mIFRleHR1cmVBdGxhcykge1xuXHRcdFx0YXNzZXQuZGlzcG9zZSgpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR0aGlzLmRpc3Bvc2VBc3NldEludGVybmFsKHBhdGgpO1xuXHR9XG5cblx0aGFzRXJyb3JzICgpIHtcblx0XHRyZXR1cm4gT2JqZWN0LmtleXModGhpcy5lcnJvcnMpLmxlbmd0aCA+IDA7XG5cdH1cblxuXHRnZXRFcnJvcnMgKCkge1xuXHRcdHJldHVybiB0aGlzLmVycm9ycztcblx0fVxuXG5cdHByaXZhdGUgZGlzcG9zZUFzc2V0SW50ZXJuYWwgKHBhdGg6IHN0cmluZykge1xuXHRcdGlmICh0aGlzLmNhY2hlLmFzc2V0c1JlZkNvdW50W3BhdGhdID4gMCAmJiAtLXRoaXMuY2FjaGUuYXNzZXRzUmVmQ291bnRbcGF0aF0gPT09IDApIHtcblx0XHRcdHJldHVybiB0aGlzLnJlbW92ZShwYXRoKTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGNyZWF0ZVRleHR1cmVBdGxhcyAoYXRsYXNUZXh0OiBzdHJpbmcsIHBhcmVudFBhdGg6IHN0cmluZywgcGF0aDogc3RyaW5nLCBmaWxlQWxpYXM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KTogVGV4dHVyZUF0bGFzIHtcblx0XHRjb25zdCBhdGxhcyA9IG5ldyBUZXh0dXJlQXRsYXMoYXRsYXNUZXh0KTtcblx0XHRhdGxhcy5kaXNwb3NlID0gKCkgPT4ge1xuXHRcdFx0aWYgKHRoaXMuY2FjaGUuYXNzZXRzUmVmQ291bnRbcGF0aF0gPD0gMCkgcmV0dXJuO1xuXHRcdFx0dGhpcy5kaXNwb3NlQXNzZXRJbnRlcm5hbChwYXRoKTtcblx0XHRcdGZvciAoY29uc3QgcGFnZSBvZiBhdGxhcy5wYWdlcykge1xuXHRcdFx0XHRwYWdlLnRleHR1cmU/LmRpc3Bvc2UoKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Zm9yIChjb25zdCBwYWdlIG9mIGF0bGFzLnBhZ2VzKSB7XG5cdFx0XHRjb25zdCB0ZXh0dXJlUGF0aCA9IHRoaXMudGV4dHVyZVBhdGgocGFyZW50UGF0aCwgcGFnZS5uYW1lLCBmaWxlQWxpYXMpO1xuXHRcdFx0dGhpcy50ZXh0dXJlUG1hSW5mb1t0aGlzLnBhdGhQcmVmaXggKyB0ZXh0dXJlUGF0aF0gPSBwYWdlLnBtYTtcblx0XHR9XG5cdFx0cmV0dXJuIGF0bGFzO1xuXHR9XG5cblx0cHJpdmF0ZSBjcmVhdGVUZXh0dXJlIChwYXRoOiBzdHJpbmcsIHBtYTogYm9vbGVhbiwgaW1hZ2U6IEhUTUxJbWFnZUVsZW1lbnQgfCBJbWFnZUJpdG1hcCk6IFRleHR1cmUge1xuXHRcdGNvbnN0IHRleHR1cmUgPSB0aGlzLnRleHR1cmVMb2FkZXIoaW1hZ2UsIHBtYSk7XG5cdFx0Y29uc3QgdGV4dHVyZURpc3Bvc2UgPSB0ZXh0dXJlLmRpc3Bvc2UuYmluZCh0ZXh0dXJlKTtcblx0XHR0ZXh0dXJlLmRpc3Bvc2UgPSAoKSA9PiB7XG5cdFx0XHRpZiAodGhpcy5kaXNwb3NlQXNzZXRJbnRlcm5hbChwYXRoKSkgdGV4dHVyZURpc3Bvc2UoKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRleHR1cmU7XG5cdH1cblxuXHRwcml2YXRlIHRleHR1cmVQYXRoIChwYXJlbnRQYXRoOiBzdHJpbmcsIHBhZ2VOYW1lOiBzdHJpbmcsIGZpbGVBbGlhcz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pIHtcblx0XHRpZiAoIWZpbGVBbGlhcykgcmV0dXJuIHBhcmVudFBhdGggKyBwYWdlTmFtZTtcblx0XHRyZXR1cm4gZmlsZUFsaWFzW3BhZ2VOYW1lXTtcblx0fVxufVxuXG5leHBvcnQgY2xhc3MgQXNzZXRDYWNoZSB7XG5cdHB1YmxpYyBhc3NldHM6IFN0cmluZ01hcDxBc3NldERhdGE+ID0ge307XG5cdHB1YmxpYyBhc3NldHNSZWZDb3VudDogU3RyaW5nTWFwPG51bWJlcj4gPSB7fTtcblx0cHVibGljIGFzc2V0c0xvYWRlZDogU3RyaW5nTWFwPFByb21pc2U8QXNzZXREYXRhIHwgdW5kZWZpbmVkPj4gPSB7fTtcblxuXHRzdGF0aWMgQVZBSUxBQkxFX0NBQ0hFUyA9IG5ldyBNYXA8c3RyaW5nLCBBc3NldENhY2hlPigpO1xuXHRzdGF0aWMgZ2V0Q2FjaGUgKGlkOiBzdHJpbmcpIHtcblx0XHRjb25zdCBjYWNoZSA9IEFzc2V0Q2FjaGUuQVZBSUxBQkxFX0NBQ0hFUy5nZXQoaWQpO1xuXHRcdGlmIChjYWNoZSkgcmV0dXJuIGNhY2hlO1xuXG5cdFx0Y29uc3QgbmV3Q2FjaGUgPSBuZXcgQXNzZXRDYWNoZSgpO1xuXHRcdEFzc2V0Q2FjaGUuQVZBSUxBQkxFX0NBQ0hFUy5zZXQoaWQsIG5ld0NhY2hlKTtcblx0XHRyZXR1cm4gbmV3Q2FjaGU7XG5cdH1cblxuXHRhc3luYyBhZGRBc3NldDxUIGV4dGVuZHMgQXNzZXREYXRhPiAocGF0aDogc3RyaW5nLCBhc3NldDogVCk6IFByb21pc2U8VD4ge1xuXHRcdHRoaXMuYXNzZXRzTG9hZGVkW3BhdGhdID0gUHJvbWlzZS5yZXNvbHZlKGFzc2V0KTtcblx0XHR0aGlzLmFzc2V0c1twYXRoXSA9IGFzc2V0O1xuXHRcdHJldHVybiBhc3NldDtcblx0fVxuXG5cdGdldEFzc2V0PFQgZXh0ZW5kcyBBc3NldERhdGE+IChwYXRoOiBzdHJpbmcpOiBQcm9taXNlPFQ+IHwgdW5kZWZpbmVkIHtcblx0XHRyZXR1cm4gdGhpcy5hc3NldHNMb2FkZWRbcGF0aF0gYXMgUHJvbWlzZTxUPiB8IHVuZGVmaW5lZDtcblx0fVxufVxuXG50eXBlIERvd25sb2FkZXJTdWNjZXNzQ2FsbGJhY2s8VCBleHRlbmRzIEFzc2V0RGF0YSA9IEFzc2V0RGF0YT4gPSAoZGF0YTogVCkgPT4gdm9pZDtcbnR5cGUgRG93bmxvYWRlckVycm9yQ2FsbGJhY2sgPSAoc3RhdHVzOiBudW1iZXIsIHJlc3BvbnNlVGV4dDogc3RyaW5nKSA9PiB2b2lkO1xuXG5leHBvcnQgY2xhc3MgRG93bmxvYWRlciB7XG5cdHByaXZhdGUgY2FsbGJhY2tzOiBTdHJpbmdNYXA8QXJyYXk8RG93bmxvYWRlclN1Y2Nlc3NDYWxsYmFjayB8IERvd25sb2FkZXJFcnJvckNhbGxiYWNrPj4gPSB7fTtcblx0cmF3RGF0YVVyaXM6IFN0cmluZ01hcDxzdHJpbmc+ID0ge307XG5cblx0ZGF0YVVyaVRvU3RyaW5nIChkYXRhVXJpOiBzdHJpbmcpIHtcblx0XHRpZiAoIWRhdGFVcmkuc3RhcnRzV2l0aChcImRhdGE6XCIpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJOb3QgYSBkYXRhIFVSSS5cIik7XG5cdFx0fVxuXG5cdFx0bGV0IGJhc2U2NElkeCA9IGRhdGFVcmkuaW5kZXhPZihcImJhc2U2NCxcIik7XG5cdFx0aWYgKGJhc2U2NElkeCAhPT0gLTEpIHtcblx0XHRcdGJhc2U2NElkeCArPSBcImJhc2U2NCxcIi5sZW5ndGg7XG5cdFx0XHRyZXR1cm4gYXRvYihkYXRhVXJpLnN1YnN0cihiYXNlNjRJZHgpKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIGRhdGFVcmkuc3Vic3RyKGRhdGFVcmkuaW5kZXhPZihcIixcIikgKyAxKTtcblx0XHR9XG5cdH1cblxuXHRiYXNlNjRUb1VpbnQ4QXJyYXkgKGJhc2U2NDogc3RyaW5nKTogVWludDhBcnJheSB7XG5cdFx0dmFyIGJpbmFyeV9zdHJpbmcgPSB3aW5kb3cuYXRvYihiYXNlNjQpO1xuXHRcdHZhciBsZW4gPSBiaW5hcnlfc3RyaW5nLmxlbmd0aDtcblx0XHR2YXIgYnl0ZXMgPSBuZXcgVWludDhBcnJheShsZW4pO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdGJ5dGVzW2ldID0gYmluYXJ5X3N0cmluZy5jaGFyQ29kZUF0KGkpO1xuXHRcdH1cblx0XHRyZXR1cm4gYnl0ZXM7XG5cdH1cblxuXHRkYXRhVXJpVG9VaW50OEFycmF5IChkYXRhVXJpOiBzdHJpbmcpOiBVaW50OEFycmF5IHtcblx0XHRpZiAoIWRhdGFVcmkuc3RhcnRzV2l0aChcImRhdGE6XCIpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJOb3QgYSBkYXRhIFVSSS5cIik7XG5cdFx0fVxuXG5cdFx0bGV0IGJhc2U2NElkeCA9IGRhdGFVcmkuaW5kZXhPZihcImJhc2U2NCxcIik7XG5cdFx0aWYgKGJhc2U2NElkeCA9PT0gLTEpIHRocm93IG5ldyBFcnJvcihcIk5vdCBhIGJpbmFyeSBkYXRhIFVSSS5cIik7XG5cdFx0YmFzZTY0SWR4ICs9IFwiYmFzZTY0LFwiLmxlbmd0aDtcblx0XHRyZXR1cm4gdGhpcy5iYXNlNjRUb1VpbnQ4QXJyYXkoZGF0YVVyaS5zdWJzdHIoYmFzZTY0SWR4KSk7XG5cdH1cblxuXHRkb3dubG9hZFRleHQgKHVybDogc3RyaW5nLCBzdWNjZXNzOiBEb3dubG9hZGVyU3VjY2Vzc0NhbGxiYWNrPHN0cmluZz4sIGVycm9yOiBEb3dubG9hZGVyRXJyb3JDYWxsYmFjaykge1xuXHRcdGlmICh0aGlzLnN0YXJ0KHVybCwgc3VjY2VzcywgZXJyb3IpKSByZXR1cm47XG5cblx0XHRjb25zdCByYXdEYXRhVXJpID0gdGhpcy5yYXdEYXRhVXJpc1t1cmxdO1xuXHRcdC8vIHdlIGFzc3VtZSBpZiBhIFwiLlwiIGlzIGluY2x1ZGVkIGluIGEgcmF3IGRhdGEgdXJpLCBpdCBpcyB1c2VkIHRvIHJld3JpdGUgYW4gYXNzZXQgVVJMXG5cdFx0aWYgKHJhd0RhdGFVcmkgJiYgIXJhd0RhdGFVcmkuaW5jbHVkZXMoXCIuXCIpKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHR0aGlzLmZpbmlzaCh1cmwsIDIwMCwgdGhpcy5kYXRhVXJpVG9TdHJpbmcocmF3RGF0YVVyaSkpO1xuXHRcdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0XHR0aGlzLmZpbmlzaCh1cmwsIDQwMCwgSlNPTi5zdHJpbmdpZnkoZSkpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IHJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcblx0XHRyZXF1ZXN0Lm92ZXJyaWRlTWltZVR5cGUoXCJ0ZXh0L2h0bWxcIik7XG5cdFx0cmVxdWVzdC5vcGVuKFwiR0VUXCIsIHJhd0RhdGFVcmkgPyByYXdEYXRhVXJpIDogdXJsLCB0cnVlKTtcblx0XHRjb25zdCBkb25lID0gKCkgPT4ge1xuXHRcdFx0dGhpcy5maW5pc2godXJsLCByZXF1ZXN0LnN0YXR1cywgcmVxdWVzdC5yZXNwb25zZVRleHQpO1xuXHRcdH07XG5cdFx0cmVxdWVzdC5vbmxvYWQgPSBkb25lO1xuXHRcdHJlcXVlc3Qub25lcnJvciA9IGRvbmU7XG5cdFx0cmVxdWVzdC5zZW5kKCk7XG5cdH1cblxuXHRkb3dubG9hZEpzb24gKHVybDogc3RyaW5nLCBzdWNjZXNzOiBEb3dubG9hZGVyU3VjY2Vzc0NhbGxiYWNrPG9iamVjdD4sIGVycm9yOiBEb3dubG9hZGVyRXJyb3JDYWxsYmFjaykge1xuXHRcdHRoaXMuZG93bmxvYWRUZXh0KHVybCwgKGRhdGE6IHN0cmluZyk6IHZvaWQgPT4ge1xuXHRcdFx0c3VjY2VzcyhKU09OLnBhcnNlKGRhdGEpKTtcblx0XHR9LCBlcnJvcik7XG5cdH1cblxuXHRkb3dubG9hZEJpbmFyeSAodXJsOiBzdHJpbmcsIHN1Y2Nlc3M6IChkYXRhOiBVaW50OEFycmF5KSA9PiB2b2lkLCBlcnJvcjogRG93bmxvYWRlckVycm9yQ2FsbGJhY2spIHtcblx0XHRpZiAodGhpcy5zdGFydCh1cmwsIHN1Y2Nlc3MsIGVycm9yKSkgcmV0dXJuO1xuXG5cdFx0Y29uc3QgcmF3RGF0YVVyaSA9IHRoaXMucmF3RGF0YVVyaXNbdXJsXTtcblx0XHQvLyB3ZSBhc3N1bWUgaWYgYSBcIi5cIiBpcyBpbmNsdWRlZCBpbiBhIHJhdyBkYXRhIHVyaSwgaXQgaXMgdXNlZCB0byByZXdyaXRlIGFuIGFzc2V0IFVSTFxuXHRcdGlmIChyYXdEYXRhVXJpICYmICFyYXdEYXRhVXJpLmluY2x1ZGVzKFwiLlwiKSkge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0dGhpcy5maW5pc2godXJsLCAyMDAsIHRoaXMuZGF0YVVyaVRvVWludDhBcnJheShyYXdEYXRhVXJpKSk7XG5cdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdHRoaXMuZmluaXNoKHVybCwgNDAwLCBKU09OLnN0cmluZ2lmeShlKSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgcmVxdWVzdCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuXHRcdHJlcXVlc3Qub3BlbihcIkdFVFwiLCByYXdEYXRhVXJpID8gcmF3RGF0YVVyaSA6IHVybCwgdHJ1ZSk7XG5cdFx0cmVxdWVzdC5yZXNwb25zZVR5cGUgPSBcImFycmF5YnVmZmVyXCI7XG5cdFx0Y29uc3Qgb25lcnJvciA9ICgpID0+IHtcblx0XHRcdHRoaXMuZmluaXNoKHVybCwgcmVxdWVzdC5zdGF0dXMsIHJlcXVlc3QucmVzcG9uc2UpO1xuXHRcdH07XG5cdFx0cmVxdWVzdC5vbmxvYWQgPSAoKSA9PiB7XG5cdFx0XHRpZiAocmVxdWVzdC5zdGF0dXMgPT09IDIwMCB8fCByZXF1ZXN0LnN0YXR1cyA9PT0gMClcblx0XHRcdFx0dGhpcy5maW5pc2godXJsLCAyMDAsIG5ldyBVaW50OEFycmF5KHJlcXVlc3QucmVzcG9uc2UgYXMgQXJyYXlCdWZmZXIpKTtcblx0XHRcdGVsc2Vcblx0XHRcdFx0b25lcnJvcigpO1xuXHRcdH07XG5cdFx0cmVxdWVzdC5vbmVycm9yID0gb25lcnJvcjtcblx0XHRyZXF1ZXN0LnNlbmQoKTtcblx0fVxuXG5cdHByaXZhdGUgc3RhcnQ8VCBleHRlbmRzIEFzc2V0RGF0YT4gKHVybDogc3RyaW5nLCBzdWNjZXNzOiBEb3dubG9hZGVyU3VjY2Vzc0NhbGxiYWNrPFQ+LCBlcnJvcjogRG93bmxvYWRlckVycm9yQ2FsbGJhY2spIHtcblx0XHRsZXQgY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3NbdXJsXTtcblx0XHR0cnkge1xuXHRcdFx0aWYgKGNhbGxiYWNrcykgcmV0dXJuIHRydWU7XG5cdFx0XHR0aGlzLmNhbGxiYWNrc1t1cmxdID0gY2FsbGJhY2tzID0gW107XG5cdFx0fSBmaW5hbGx5IHtcblx0XHRcdGNhbGxiYWNrcy5wdXNoKHN1Y2Nlc3MgYXMgRG93bmxvYWRlclN1Y2Nlc3NDYWxsYmFjazxBc3NldERhdGE+LCBlcnJvcik7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBmaW5pc2ggKHVybDogc3RyaW5nLCBzdGF0dXM6IG51bWJlciwgZGF0YTogQXNzZXREYXRhKSB7XG5cdFx0Y29uc3QgY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3NbdXJsXTtcblx0XHRkZWxldGUgdGhpcy5jYWxsYmFja3NbdXJsXTtcblx0XHRpZiAoc3RhdHVzID09PSAyMDAgfHwgc3RhdHVzID09PSAwKSB7XG5cdFx0XHRmb3IgKGxldCBpID0gMCwgbiA9IGNhbGxiYWNrcy5sZW5ndGg7IGkgPCBuOyBpICs9IDIpXG5cdFx0XHRcdChjYWxsYmFja3NbaV0gYXMgRG93bmxvYWRlclN1Y2Nlc3NDYWxsYmFjaykoZGF0YSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGZvciAobGV0IGkgPSAxLCBuID0gY2FsbGJhY2tzLmxlbmd0aDsgaSA8IG47IGkgKz0gMilcblx0XHRcdFx0KGNhbGxiYWNrc1tpXSBhcyBEb3dubG9hZGVyRXJyb3JDYWxsYmFjaykoc3RhdHVzLCBkYXRhIGFzIHN0cmluZyk7XG5cdFx0fVxuXHR9XG59XG4iXX0=