/*! * ONNX Runtime Web v1.26.0 * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __commonJS = (cb, mod2) => function __require() { return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports; }; var __export = (target, all) => { for (var name2 in all) __defProp(target, name2, { get: all[name2], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod2 || !mod2.__esModule ? __defProp(target, "default", { value: mod2, enumerable: true }) : target, mod2 )); var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2); // common/dist/esm/backend-impl.js var backends, backendsSortedByPriority, registerBackend, tryResolveAndInitializeBackend, resolveBackendAndExecutionProviders; var init_backend_impl = __esm({ "common/dist/esm/backend-impl.js"() { "use strict"; backends = /* @__PURE__ */ new Map(); backendsSortedByPriority = []; registerBackend = (name2, backend2, priority) => { if (backend2 && typeof backend2.init === "function" && typeof backend2.createInferenceSessionHandler === "function") { const currentBackend = backends.get(name2); if (currentBackend === void 0) { backends.set(name2, { backend: backend2, priority }); } else if (currentBackend.priority > priority) { return; } else if (currentBackend.priority === priority) { if (currentBackend.backend !== backend2) { throw new Error(`cannot register backend "${name2}" using priority ${priority}`); } } if (priority >= 0) { const i = backendsSortedByPriority.indexOf(name2); if (i !== -1) { backendsSortedByPriority.splice(i, 1); } for (let i2 = 0; i2 < backendsSortedByPriority.length; i2++) { if (backends.get(backendsSortedByPriority[i2]).priority <= priority) { backendsSortedByPriority.splice(i2, 0, name2); return; } } backendsSortedByPriority.push(name2); } return; } throw new TypeError("not a valid backend"); }; tryResolveAndInitializeBackend = async (backendName) => { const backendInfo = backends.get(backendName); if (!backendInfo) { return "backend not found."; } if (backendInfo.initialized) { return backendInfo.backend; } else if (backendInfo.aborted) { return backendInfo.error; } else { const isInitializing = !!backendInfo.initPromise; try { if (!isInitializing) { backendInfo.initPromise = backendInfo.backend.init(backendName); } await backendInfo.initPromise; backendInfo.initialized = true; return backendInfo.backend; } catch (e) { if (!isInitializing) { backendInfo.error = `${e}`; backendInfo.aborted = true; } return backendInfo.error; } finally { delete backendInfo.initPromise; } } }; resolveBackendAndExecutionProviders = async (options) => { const eps = options.executionProviders || []; const backendHints = eps.map((i) => typeof i === "string" ? i : i.name); const backendNames = backendHints.length === 0 ? backendsSortedByPriority : backendHints; let backend2; const errors = []; const availableBackendNames = /* @__PURE__ */ new Set(); for (const backendName of backendNames) { const resolveResult = await tryResolveAndInitializeBackend(backendName); if (typeof resolveResult === "string") { errors.push({ name: backendName, err: resolveResult }); } else { if (!backend2) { backend2 = resolveResult; } if (backend2 === resolveResult) { availableBackendNames.add(backendName); } } } if (!backend2) { throw new Error(`no available backend found. ERR: ${errors.map((e) => `[${e.name}] ${e.err}`).join(", ")}`); } for (const { name: name2, err } of errors) { if (backendHints.includes(name2)) { console.warn(`removing requested execution provider "${name2}" from session options because it is not available: ${err}`); } } const filteredEps = eps.filter((i) => availableBackendNames.has(typeof i === "string" ? i : i.name)); return [ backend2, new Proxy(options, { get: (target, prop) => { if (prop === "executionProviders") { return filteredEps; } return Reflect.get(target, prop); } }) ]; }; } }); // common/dist/esm/backend.js var init_backend = __esm({ "common/dist/esm/backend.js"() { "use strict"; init_backend_impl(); } }); // common/dist/esm/version.js var version; var init_version = __esm({ "common/dist/esm/version.js"() { "use strict"; version = "1.26.0"; } }); // common/dist/esm/env-impl.js var logLevelValue, env; var init_env_impl = __esm({ "common/dist/esm/env-impl.js"() { "use strict"; init_version(); logLevelValue = "warning"; env = { wasm: {}, webgl: {}, webgpu: {}, versions: { common: version }, set logLevel(value) { if (value === void 0) { return; } if (typeof value !== "string" || ["verbose", "info", "warning", "error", "fatal"].indexOf(value) === -1) { throw new Error(`Unsupported logging level: ${value}`); } logLevelValue = value; }, get logLevel() { return logLevelValue; } }; Object.defineProperty(env, "logLevel", { enumerable: true }); } }); // common/dist/esm/env.js var env2; var init_env = __esm({ "common/dist/esm/env.js"() { "use strict"; init_env_impl(); env2 = env; } }); // common/dist/esm/tensor-conversion-impl.js var tensorToDataURL, tensorToImageData; var init_tensor_conversion_impl = __esm({ "common/dist/esm/tensor-conversion-impl.js"() { "use strict"; tensorToDataURL = (tensor, options) => { const canvas = typeof document !== "undefined" ? document.createElement("canvas") : new OffscreenCanvas(1, 1); canvas.width = tensor.dims[3]; canvas.height = tensor.dims[2]; const pixels2DContext = canvas.getContext("2d"); if (pixels2DContext != null) { let width; let height; if (options?.tensorLayout !== void 0 && options.tensorLayout === "NHWC") { width = tensor.dims[2]; height = tensor.dims[3]; } else { width = tensor.dims[3]; height = tensor.dims[2]; } const inputformat = options?.format !== void 0 ? options.format : "RGB"; const norm = options?.norm; let normMean; let normBias; if (norm === void 0 || norm.mean === void 0) { normMean = [255, 255, 255, 255]; } else { if (typeof norm.mean === "number") { normMean = [norm.mean, norm.mean, norm.mean, norm.mean]; } else { normMean = [norm.mean[0], norm.mean[1], norm.mean[2], 0]; if (norm.mean[3] !== void 0) { normMean[3] = norm.mean[3]; } } } if (norm === void 0 || norm.bias === void 0) { normBias = [0, 0, 0, 0]; } else { if (typeof norm.bias === "number") { normBias = [norm.bias, norm.bias, norm.bias, norm.bias]; } else { normBias = [norm.bias[0], norm.bias[1], norm.bias[2], 0]; if (norm.bias[3] !== void 0) { normBias[3] = norm.bias[3]; } } } const stride = height * width; let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1; if (inputformat === "RGBA") { rTensorPointer = 0; gTensorPointer = stride; bTensorPointer = stride * 2; aTensorPointer = stride * 3; } else if (inputformat === "RGB") { rTensorPointer = 0; gTensorPointer = stride; bTensorPointer = stride * 2; } else if (inputformat === "RBG") { rTensorPointer = 0; bTensorPointer = stride; gTensorPointer = stride * 2; } for (let i = 0; i < height; i++) { for (let j = 0; j < width; j++) { const R = (tensor.data[rTensorPointer++] - normBias[0]) * normMean[0]; const G = (tensor.data[gTensorPointer++] - normBias[1]) * normMean[1]; const B = (tensor.data[bTensorPointer++] - normBias[2]) * normMean[2]; const A = aTensorPointer === -1 ? 255 : (tensor.data[aTensorPointer++] - normBias[3]) * normMean[3]; pixels2DContext.fillStyle = "rgba(" + R + "," + G + "," + B + "," + A + ")"; pixels2DContext.fillRect(j, i, 1, 1); } } if ("toDataURL" in canvas) { return canvas.toDataURL(); } else { throw new Error("toDataURL is not supported"); } } else { throw new Error("Can not access image data"); } }; tensorToImageData = (tensor, options) => { const pixels2DContext = typeof document !== "undefined" ? document.createElement("canvas").getContext("2d") : new OffscreenCanvas(1, 1).getContext("2d"); let image; if (pixels2DContext != null) { let width; let height; let channels; if (options?.tensorLayout !== void 0 && options.tensorLayout === "NHWC") { width = tensor.dims[2]; height = tensor.dims[1]; channels = tensor.dims[3]; } else { width = tensor.dims[3]; height = tensor.dims[2]; channels = tensor.dims[1]; } const inputformat = options !== void 0 ? options.format !== void 0 ? options.format : "RGB" : "RGB"; const norm = options?.norm; let normMean; let normBias; if (norm === void 0 || norm.mean === void 0) { normMean = [255, 255, 255, 255]; } else { if (typeof norm.mean === "number") { normMean = [norm.mean, norm.mean, norm.mean, norm.mean]; } else { normMean = [norm.mean[0], norm.mean[1], norm.mean[2], 255]; if (norm.mean[3] !== void 0) { normMean[3] = norm.mean[3]; } } } if (norm === void 0 || norm.bias === void 0) { normBias = [0, 0, 0, 0]; } else { if (typeof norm.bias === "number") { normBias = [norm.bias, norm.bias, norm.bias, norm.bias]; } else { normBias = [norm.bias[0], norm.bias[1], norm.bias[2], 0]; if (norm.bias[3] !== void 0) { normBias[3] = norm.bias[3]; } } } const stride = height * width; if (options !== void 0) { if (options.format !== void 0 && channels === 4 && options.format !== "RGBA" || channels === 3 && options.format !== "RGB" && options.format !== "BGR") { throw new Error("Tensor format doesn't match input tensor dims"); } } const step = 4; let rImagePointer = 0, gImagePointer = 1, bImagePointer = 2, aImagePointer = 3; let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1; if (inputformat === "RGBA") { rTensorPointer = 0; gTensorPointer = stride; bTensorPointer = stride * 2; aTensorPointer = stride * 3; } else if (inputformat === "RGB") { rTensorPointer = 0; gTensorPointer = stride; bTensorPointer = stride * 2; } else if (inputformat === "RBG") { rTensorPointer = 0; bTensorPointer = stride; gTensorPointer = stride * 2; } image = pixels2DContext.createImageData(width, height); for (let i = 0; i < height * width; rImagePointer += step, gImagePointer += step, bImagePointer += step, aImagePointer += step, i++) { image.data[rImagePointer] = (tensor.data[rTensorPointer++] - normBias[0]) * normMean[0]; image.data[gImagePointer] = (tensor.data[gTensorPointer++] - normBias[1]) * normMean[1]; image.data[bImagePointer] = (tensor.data[bTensorPointer++] - normBias[2]) * normMean[2]; image.data[aImagePointer] = aTensorPointer === -1 ? 255 : (tensor.data[aTensorPointer++] - normBias[3]) * normMean[3]; } } else { throw new Error("Can not access image data"); } return image; }; } }); // common/dist/esm/tensor-factory-impl.js var bufferToTensor, tensorFromImage, tensorFromTexture, tensorFromGpuBuffer, tensorFromMLTensor, tensorFromPinnedBuffer; var init_tensor_factory_impl = __esm({ "common/dist/esm/tensor-factory-impl.js"() { "use strict"; init_tensor_impl(); bufferToTensor = (buffer, options) => { if (buffer === void 0) { throw new Error("Image buffer must be defined"); } if (options.height === void 0 || options.width === void 0) { throw new Error("Image height and width must be defined"); } if (options.tensorLayout === "NHWC") { throw new Error("NHWC Tensor layout is not supported yet"); } const { height, width } = options; const norm = options.norm ?? { mean: 255, bias: 0 }; let normMean; let normBias; if (typeof norm.mean === "number") { normMean = [norm.mean, norm.mean, norm.mean, norm.mean]; } else { normMean = [norm.mean[0], norm.mean[1], norm.mean[2], norm.mean[3] ?? 255]; } if (typeof norm.bias === "number") { normBias = [norm.bias, norm.bias, norm.bias, norm.bias]; } else { normBias = [norm.bias[0], norm.bias[1], norm.bias[2], norm.bias[3] ?? 0]; } const inputformat = options.format !== void 0 ? options.format : "RGBA"; const outputformat = options.tensorFormat !== void 0 ? options.tensorFormat !== void 0 ? options.tensorFormat : "RGB" : "RGB"; const stride = height * width; const float32Data = outputformat === "RGBA" ? new Float32Array(stride * 4) : new Float32Array(stride * 3); let step = 4, rImagePointer = 0, gImagePointer = 1, bImagePointer = 2, aImagePointer = 3; let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1; if (inputformat === "RGB") { step = 3; rImagePointer = 0; gImagePointer = 1; bImagePointer = 2; aImagePointer = -1; } if (outputformat === "RGBA") { aTensorPointer = stride * 3; } else if (outputformat === "RBG") { rTensorPointer = 0; bTensorPointer = stride; gTensorPointer = stride * 2; } else if (outputformat === "BGR") { bTensorPointer = 0; gTensorPointer = stride; rTensorPointer = stride * 2; } for (let i = 0; i < stride; i++, rImagePointer += step, bImagePointer += step, gImagePointer += step, aImagePointer += step) { float32Data[rTensorPointer++] = (buffer[rImagePointer] + normBias[0]) / normMean[0]; float32Data[gTensorPointer++] = (buffer[gImagePointer] + normBias[1]) / normMean[1]; float32Data[bTensorPointer++] = (buffer[bImagePointer] + normBias[2]) / normMean[2]; if (aTensorPointer !== -1 && aImagePointer !== -1) { float32Data[aTensorPointer++] = (buffer[aImagePointer] + normBias[3]) / normMean[3]; } } const outputTensor = outputformat === "RGBA" ? new Tensor("float32", float32Data, [1, 4, height, width]) : new Tensor("float32", float32Data, [1, 3, height, width]); return outputTensor; }; tensorFromImage = async (image, options) => { const isHTMLImageEle = typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement; const isImageDataEle = typeof ImageData !== "undefined" && image instanceof ImageData; const isImageBitmap = typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap; const isString = typeof image === "string"; let data; let bufferToTensorOptions = options ?? {}; const createCanvas2 = () => { if (typeof document !== "undefined") { return document.createElement("canvas"); } else if (typeof OffscreenCanvas !== "undefined") { return new OffscreenCanvas(1, 1); } else { throw new Error("Canvas is not supported"); } }; const createCanvasContext = (canvas) => { if (typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement) { return canvas.getContext("2d"); } else if (canvas instanceof OffscreenCanvas) { return canvas.getContext("2d"); } else { return null; } }; if (isHTMLImageEle) { const canvas = createCanvas2(); canvas.width = image.width; canvas.height = image.height; const pixels2DContext = createCanvasContext(canvas); if (pixels2DContext != null) { let height = image.height; let width = image.width; if (options !== void 0 && options.resizedHeight !== void 0 && options.resizedWidth !== void 0) { height = options.resizedHeight; width = options.resizedWidth; } if (options !== void 0) { bufferToTensorOptions = options; if (options.tensorFormat !== void 0) { throw new Error("Image input config format must be RGBA for HTMLImageElement"); } else { bufferToTensorOptions.tensorFormat = "RGBA"; } bufferToTensorOptions.height = height; bufferToTensorOptions.width = width; } else { bufferToTensorOptions.tensorFormat = "RGBA"; bufferToTensorOptions.height = height; bufferToTensorOptions.width = width; } pixels2DContext.drawImage(image, 0, 0); data = pixels2DContext.getImageData(0, 0, width, height).data; } else { throw new Error("Can not access image data"); } } else if (isImageDataEle) { let height; let width; if (options !== void 0 && options.resizedWidth !== void 0 && options.resizedHeight !== void 0) { height = options.resizedHeight; width = options.resizedWidth; } else { height = image.height; width = image.width; } if (options !== void 0) { bufferToTensorOptions = options; } bufferToTensorOptions.format = "RGBA"; bufferToTensorOptions.height = height; bufferToTensorOptions.width = width; if (options !== void 0) { const tempCanvas = createCanvas2(); tempCanvas.width = width; tempCanvas.height = height; const pixels2DContext = createCanvasContext(tempCanvas); if (pixels2DContext != null) { pixels2DContext.putImageData(image, 0, 0); data = pixels2DContext.getImageData(0, 0, width, height).data; } else { throw new Error("Can not access image data"); } } else { data = image.data; } } else if (isImageBitmap) { if (options === void 0) { throw new Error("Please provide image config with format for Imagebitmap"); } const canvas = createCanvas2(); canvas.width = image.width; canvas.height = image.height; const pixels2DContext = createCanvasContext(canvas); if (pixels2DContext != null) { const height = image.height; const width = image.width; pixels2DContext.drawImage(image, 0, 0, width, height); data = pixels2DContext.getImageData(0, 0, width, height).data; bufferToTensorOptions.height = height; bufferToTensorOptions.width = width; return bufferToTensor(data, bufferToTensorOptions); } else { throw new Error("Can not access image data"); } } else if (isString) { return new Promise((resolve, reject) => { const canvas = createCanvas2(); const context = createCanvasContext(canvas); if (!image || !context) { return reject(); } const newImage = new Image(); newImage.crossOrigin = "Anonymous"; newImage.src = image; newImage.onload = () => { canvas.width = newImage.width; canvas.height = newImage.height; context.drawImage(newImage, 0, 0, canvas.width, canvas.height); const img = context.getImageData(0, 0, canvas.width, canvas.height); bufferToTensorOptions.height = canvas.height; bufferToTensorOptions.width = canvas.width; resolve(bufferToTensor(img.data, bufferToTensorOptions)); }; }); } else { throw new Error("Input data provided is not supported - aborted tensor creation"); } if (data !== void 0) { return bufferToTensor(data, bufferToTensorOptions); } else { throw new Error("Input data provided is not supported - aborted tensor creation"); } }; tensorFromTexture = (texture, options) => { const { width, height, download, dispose } = options; const dims = [1, height, width, 4]; return new Tensor({ location: "texture", type: "float32", texture, dims, download, dispose }); }; tensorFromGpuBuffer = (gpuBuffer, options) => { const { dataType, dims, download, dispose } = options; return new Tensor({ location: "gpu-buffer", type: dataType ?? "float32", gpuBuffer, dims, download, dispose }); }; tensorFromMLTensor = (mlTensor, options) => { const { dataType, dims, download, dispose } = options; return new Tensor({ location: "ml-tensor", type: dataType ?? "float32", mlTensor, dims, download, dispose }); }; tensorFromPinnedBuffer = (type, buffer, dims) => new Tensor({ location: "cpu-pinned", type, data: buffer, dims: dims ?? [buffer.length] }); } }); // common/dist/esm/tensor-impl-type-mapping.js var NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP, NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP, isTypedArrayChecked, checkTypedArray; var init_tensor_impl_type_mapping = __esm({ "common/dist/esm/tensor-impl-type-mapping.js"() { "use strict"; NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP = /* @__PURE__ */ new Map([ ["float32", Float32Array], ["uint8", Uint8Array], ["int8", Int8Array], ["uint16", Uint16Array], ["int16", Int16Array], ["int32", Int32Array], ["bool", Uint8Array], ["float64", Float64Array], ["uint32", Uint32Array], ["int4", Uint8Array], ["uint4", Uint8Array] ]); NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP = /* @__PURE__ */ new Map([ [Float32Array, "float32"], [Uint8Array, "uint8"], [Int8Array, "int8"], [Uint16Array, "uint16"], [Int16Array, "int16"], [Int32Array, "int32"], [Float64Array, "float64"], [Uint32Array, "uint32"] ]); isTypedArrayChecked = false; checkTypedArray = () => { if (!isTypedArrayChecked) { isTypedArrayChecked = true; const isBigInt64ArrayAvailable = typeof BigInt64Array !== "undefined" && BigInt64Array.from; const isBigUint64ArrayAvailable = typeof BigUint64Array !== "undefined" && BigUint64Array.from; const Float16Array = globalThis.Float16Array; const isFloat16ArrayAvailable = typeof Float16Array !== "undefined" && Float16Array.from; if (isBigInt64ArrayAvailable) { NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.set("int64", BigInt64Array); NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.set(BigInt64Array, "int64"); } if (isBigUint64ArrayAvailable) { NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.set("uint64", BigUint64Array); NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.set(BigUint64Array, "uint64"); } if (isFloat16ArrayAvailable) { NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.set("float16", Float16Array); NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.set(Float16Array, "float16"); } else { NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.set("float16", Uint16Array); } } }; } }); // common/dist/esm/tensor-utils-impl.js var calculateSize, tensorReshape; var init_tensor_utils_impl = __esm({ "common/dist/esm/tensor-utils-impl.js"() { "use strict"; init_tensor_impl(); calculateSize = (dims) => { let size = 1; for (let i = 0; i < dims.length; i++) { const dim = dims[i]; if (typeof dim !== "number" || !Number.isSafeInteger(dim)) { throw new TypeError(`dims[${i}] must be an integer, got: ${dim}`); } if (dim < 0) { throw new RangeError(`dims[${i}] must be a non-negative integer, got: ${dim}`); } size *= dim; } return size; }; tensorReshape = (tensor, dims) => { switch (tensor.location) { case "cpu": return new Tensor(tensor.type, tensor.data, dims); case "cpu-pinned": return new Tensor({ location: "cpu-pinned", data: tensor.data, type: tensor.type, dims }); case "texture": return new Tensor({ location: "texture", texture: tensor.texture, type: tensor.type, dims }); case "gpu-buffer": return new Tensor({ location: "gpu-buffer", gpuBuffer: tensor.gpuBuffer, type: tensor.type, dims }); case "ml-tensor": return new Tensor({ location: "ml-tensor", mlTensor: tensor.mlTensor, type: tensor.type, dims }); default: throw new Error(`tensorReshape: tensor location ${tensor.location} is not supported`); } }; } }); // common/dist/esm/tensor-impl.js var Tensor; var init_tensor_impl = __esm({ "common/dist/esm/tensor-impl.js"() { "use strict"; init_tensor_conversion_impl(); init_tensor_factory_impl(); init_tensor_impl_type_mapping(); init_tensor_utils_impl(); Tensor = class { /** * implementation. */ constructor(arg0, arg1, arg2) { checkTypedArray(); let type; let dims; if (typeof arg0 === "object" && "location" in arg0) { this.dataLocation = arg0.location; type = arg0.type; dims = arg0.dims; switch (arg0.location) { case "cpu-pinned": { const expectedTypedArrayConstructor = NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.get(type); if (!expectedTypedArrayConstructor) { throw new TypeError(`unsupported type "${type}" to create tensor from pinned buffer`); } if (!(arg0.data instanceof expectedTypedArrayConstructor)) { throw new TypeError(`buffer should be of type ${expectedTypedArrayConstructor.name}`); } this.cpuData = arg0.data; break; } case "texture": { if (type !== "float32") { throw new TypeError(`unsupported type "${type}" to create tensor from texture`); } this.gpuTextureData = arg0.texture; this.downloader = arg0.download; this.disposer = arg0.dispose; break; } case "gpu-buffer": { if (type !== "float32" && type !== "float16" && type !== "int32" && type !== "int64" && type !== "uint32" && type !== "uint8" && type !== "bool" && type !== "uint4" && type !== "int4") { throw new TypeError(`unsupported type "${type}" to create tensor from gpu buffer`); } this.gpuBufferData = arg0.gpuBuffer; this.downloader = arg0.download; this.disposer = arg0.dispose; break; } case "ml-tensor": { if (type !== "float32" && type !== "float16" && type !== "int32" && type !== "int64" && type !== "uint32" && type !== "uint64" && type !== "int8" && type !== "uint8" && type !== "bool" && type !== "uint4" && type !== "int4") { throw new TypeError(`unsupported type "${type}" to create tensor from MLTensor`); } this.mlTensorData = arg0.mlTensor; this.downloader = arg0.download; this.disposer = arg0.dispose; break; } default: throw new Error(`Tensor constructor: unsupported location '${this.dataLocation}'`); } } else { let data; let maybeDims; if (typeof arg0 === "string") { type = arg0; maybeDims = arg2; if (arg0 === "string") { if (!Array.isArray(arg1)) { throw new TypeError("A string tensor's data must be a string array."); } data = arg1; } else { const typedArrayConstructor = NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.get(arg0); if (typedArrayConstructor === void 0) { throw new TypeError(`Unsupported tensor type: ${arg0}.`); } if (Array.isArray(arg1)) { if (arg0 === "float16" && typedArrayConstructor === Uint16Array || arg0 === "uint4" || arg0 === "int4") { throw new TypeError(`Creating a ${arg0} tensor from number array is not supported. Please use ${typedArrayConstructor.name} as data.`); } else if (arg0 === "uint64" || arg0 === "int64") { data = typedArrayConstructor.from(arg1, BigInt); } else { data = typedArrayConstructor.from(arg1); } } else if (arg1 instanceof typedArrayConstructor) { data = arg1; } else if (arg1 instanceof Uint8ClampedArray) { if (arg0 === "uint8") { data = Uint8Array.from(arg1); } else { throw new TypeError(`A Uint8ClampedArray tensor's data must be type of uint8`); } } else if (arg0 === "float16" && arg1 instanceof Uint16Array && typedArrayConstructor !== Uint16Array) { data = new globalThis.Float16Array(arg1.buffer, arg1.byteOffset, arg1.length); } else { throw new TypeError(`A ${type} tensor's data must be type of ${typedArrayConstructor}`); } } } else { maybeDims = arg1; if (Array.isArray(arg0)) { if (arg0.length === 0) { throw new TypeError("Tensor type cannot be inferred from an empty array."); } const firstElementType = typeof arg0[0]; if (firstElementType === "string") { type = "string"; data = arg0; } else if (firstElementType === "boolean") { type = "bool"; data = Uint8Array.from(arg0); } else { throw new TypeError(`Invalid element type of data array: ${firstElementType}.`); } } else if (arg0 instanceof Uint8ClampedArray) { type = "uint8"; data = Uint8Array.from(arg0); } else { const mappedType = NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.get(arg0.constructor); if (mappedType === void 0) { throw new TypeError(`Unsupported type for tensor data: ${arg0.constructor}.`); } type = mappedType; data = arg0; } } if (maybeDims === void 0) { maybeDims = [data.length]; } else if (!Array.isArray(maybeDims)) { throw new TypeError("A tensor's dims must be a number array"); } dims = maybeDims; this.cpuData = data; this.dataLocation = "cpu"; } const size = calculateSize(dims); if (this.cpuData && size !== this.cpuData.length) { if ((type === "uint4" || type === "int4") && Math.ceil(size / 2) === this.cpuData.length) { } else { throw new Error(`Tensor's size(${size}) does not match data length(${this.cpuData.length}).`); } } this.type = type; this.dims = dims; this.size = size; } // #endregion // #region factory static async fromImage(image, options) { return tensorFromImage(image, options); } static fromTexture(texture, options) { return tensorFromTexture(texture, options); } static fromGpuBuffer(gpuBuffer, options) { return tensorFromGpuBuffer(gpuBuffer, options); } static fromMLTensor(mlTensor, options) { return tensorFromMLTensor(mlTensor, options); } static fromPinnedBuffer(type, buffer, dims) { return tensorFromPinnedBuffer(type, buffer, dims); } // #endregion // #region conversions toDataURL(options) { return tensorToDataURL(this, options); } toImageData(options) { return tensorToImageData(this, options); } // #endregion // #region properties get data() { this.ensureValid(); if (!this.cpuData) { throw new Error("The data is not on CPU. Use `getData()` to download GPU data to CPU, or use `texture` or `gpuBuffer` property to access the GPU data directly."); } return this.cpuData; } get location() { return this.dataLocation; } get texture() { this.ensureValid(); if (!this.gpuTextureData) { throw new Error("The data is not stored as a WebGL texture."); } return this.gpuTextureData; } get gpuBuffer() { this.ensureValid(); if (!this.gpuBufferData) { throw new Error("The data is not stored as a WebGPU buffer."); } return this.gpuBufferData; } get mlTensor() { this.ensureValid(); if (!this.mlTensorData) { throw new Error("The data is not stored as a WebNN MLTensor."); } return this.mlTensorData; } // #endregion // #region methods async getData(releaseData) { this.ensureValid(); switch (this.dataLocation) { case "cpu": case "cpu-pinned": return this.data; case "texture": case "gpu-buffer": case "ml-tensor": { if (!this.downloader) { throw new Error("The current tensor is not created with a specified data downloader."); } if (this.isDownloading) { throw new Error("The current tensor is being downloaded."); } try { this.isDownloading = true; const data = await this.downloader(); this.downloader = void 0; this.dataLocation = "cpu"; this.cpuData = data; if (releaseData && this.disposer) { this.disposer(); this.disposer = void 0; } return data; } finally { this.isDownloading = false; } } default: throw new Error(`cannot get data from location: ${this.dataLocation}`); } } dispose() { if (this.isDownloading) { throw new Error("The current tensor is being downloaded."); } if (this.disposer) { this.disposer(); this.disposer = void 0; } this.cpuData = void 0; this.gpuTextureData = void 0; this.gpuBufferData = void 0; this.mlTensorData = void 0; this.downloader = void 0; this.isDownloading = void 0; this.dataLocation = "none"; } // #endregion // #region tensor utilities ensureValid() { if (this.dataLocation === "none") { throw new Error("The tensor is disposed."); } } reshape(dims) { this.ensureValid(); if (this.downloader || this.disposer) { throw new Error("Cannot reshape a tensor that owns GPU resource."); } return tensorReshape(this, dims); } }; } }); // common/dist/esm/tensor.js var Tensor2; var init_tensor = __esm({ "common/dist/esm/tensor.js"() { "use strict"; init_tensor_impl(); Tensor2 = Tensor; } }); // common/dist/esm/trace.js var TRACE, TRACE_FUNC, TRACE_FUNC_BEGIN, TRACE_FUNC_END, TRACE_EVENT_BEGIN, TRACE_EVENT_END; var init_trace = __esm({ "common/dist/esm/trace.js"() { "use strict"; init_env_impl(); TRACE = (deviceType, label) => { if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { return; } console.timeStamp(`${deviceType}::ORT::${label}`); }; TRACE_FUNC = (msg, extraMsg) => { const stack = new Error().stack?.split(/\r\n|\r|\n/g) || []; let hasTraceFunc = false; for (let i = 0; i < stack.length; i++) { if (hasTraceFunc && !stack[i].includes("TRACE_FUNC")) { let label = `FUNC_${msg}::${stack[i].trim().split(" ")[1]}`; if (extraMsg) { label += `::${extraMsg}`; } TRACE("CPU", label); return; } if (stack[i].includes("TRACE_FUNC")) { hasTraceFunc = true; } } }; TRACE_FUNC_BEGIN = (extraMsg) => { if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { return; } TRACE_FUNC("BEGIN", extraMsg); }; TRACE_FUNC_END = (extraMsg) => { if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { return; } TRACE_FUNC("END", extraMsg); }; TRACE_EVENT_BEGIN = (extraMsg) => { if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { return; } console.time(`ORT::${extraMsg}`); }; TRACE_EVENT_END = (extraMsg) => { if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { return; } console.timeEnd(`ORT::${extraMsg}`); }; } }); // common/dist/esm/inference-session-impl.js var InferenceSession; var init_inference_session_impl = __esm({ "common/dist/esm/inference-session-impl.js"() { "use strict"; init_backend_impl(); init_tensor(); init_trace(); InferenceSession = class _InferenceSession { constructor(handler) { this.handler = handler; } async run(feeds, arg1, arg2) { TRACE_FUNC_BEGIN(); TRACE_EVENT_BEGIN("InferenceSession.run"); const fetches = {}; let options = {}; if (typeof feeds !== "object" || feeds === null || feeds instanceof Tensor2 || Array.isArray(feeds)) { throw new TypeError("'feeds' must be an object that use input names as keys and OnnxValue as corresponding values."); } let isFetchesEmpty = true; if (typeof arg1 === "object") { if (arg1 === null) { throw new TypeError("Unexpected argument[1]: cannot be null."); } if (arg1 instanceof Tensor2) { throw new TypeError("'fetches' cannot be a Tensor"); } if (Array.isArray(arg1)) { if (arg1.length === 0) { throw new TypeError("'fetches' cannot be an empty array."); } isFetchesEmpty = false; for (const name2 of arg1) { if (typeof name2 !== "string") { throw new TypeError("'fetches' must be a string array or an object."); } if (this.outputNames.indexOf(name2) === -1) { throw new RangeError(`'fetches' contains invalid output name: ${name2}.`); } fetches[name2] = null; } if (typeof arg2 === "object" && arg2 !== null) { options = arg2; } else if (typeof arg2 !== "undefined") { throw new TypeError("'options' must be an object."); } } else { let isFetches = false; const arg1Keys = Object.getOwnPropertyNames(arg1); for (const name2 of this.outputNames) { if (arg1Keys.indexOf(name2) !== -1) { const v = arg1[name2]; if (v === null || v instanceof Tensor2) { isFetches = true; isFetchesEmpty = false; fetches[name2] = v; } } } if (isFetches) { if (typeof arg2 === "object" && arg2 !== null) { options = arg2; } else if (typeof arg2 !== "undefined") { throw new TypeError("'options' must be an object."); } } else { options = arg1; } } } else if (typeof arg1 !== "undefined") { throw new TypeError("Unexpected argument[1]: must be 'fetches' or 'options'."); } for (const name2 of this.inputNames) { if (typeof feeds[name2] === "undefined") { throw new Error(`input '${name2}' is missing in 'feeds'.`); } } if (isFetchesEmpty) { for (const name2 of this.outputNames) { fetches[name2] = null; } } const results = await this.handler.run(feeds, fetches, options); const returnValue = {}; for (const key in results) { if (Object.hasOwnProperty.call(results, key)) { const result = results[key]; if (result instanceof Tensor2) { returnValue[key] = result; } else { returnValue[key] = new Tensor2(result.type, result.data, result.dims); } } } TRACE_EVENT_END("InferenceSession.run"); TRACE_FUNC_END(); return returnValue; } async release() { return this.handler.dispose(); } static async create(arg0, arg1, arg2, arg3) { TRACE_FUNC_BEGIN(); TRACE_EVENT_BEGIN("InferenceSession.create"); let filePathOrUint8Array; let options = {}; if (typeof arg0 === "string") { filePathOrUint8Array = arg0; if (typeof arg1 === "object" && arg1 !== null) { options = arg1; } else if (typeof arg1 !== "undefined") { throw new TypeError("'options' must be an object."); } } else if (arg0 instanceof Uint8Array) { filePathOrUint8Array = arg0; if (typeof arg1 === "object" && arg1 !== null) { options = arg1; } else if (typeof arg1 !== "undefined") { throw new TypeError("'options' must be an object."); } } else if (arg0 instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && arg0 instanceof SharedArrayBuffer) { const buffer = arg0; let byteOffset = 0; let byteLength = arg0.byteLength; if (typeof arg1 === "object" && arg1 !== null) { options = arg1; } else if (typeof arg1 === "number") { byteOffset = arg1; if (!Number.isSafeInteger(byteOffset)) { throw new RangeError("'byteOffset' must be an integer."); } if (byteOffset < 0 || byteOffset >= buffer.byteLength) { throw new RangeError(`'byteOffset' is out of range [0, ${buffer.byteLength}).`); } byteLength = arg0.byteLength - byteOffset; if (typeof arg2 === "number") { byteLength = arg2; if (!Number.isSafeInteger(byteLength)) { throw new RangeError("'byteLength' must be an integer."); } if (byteLength <= 0 || byteOffset + byteLength > buffer.byteLength) { throw new RangeError(`'byteLength' is out of range (0, ${buffer.byteLength - byteOffset}].`); } if (typeof arg3 === "object" && arg3 !== null) { options = arg3; } else if (typeof arg3 !== "undefined") { throw new TypeError("'options' must be an object."); } } else if (typeof arg2 !== "undefined") { throw new TypeError("'byteLength' must be a number."); } } else if (typeof arg1 !== "undefined") { throw new TypeError("'options' must be an object."); } filePathOrUint8Array = new Uint8Array(buffer, byteOffset, byteLength); } else { throw new TypeError("Unexpected argument[0]: must be 'path' or 'buffer'."); } const [backend2, optionsWithValidatedEPs] = await resolveBackendAndExecutionProviders(options); const handler = await backend2.createInferenceSessionHandler(filePathOrUint8Array, optionsWithValidatedEPs); TRACE_EVENT_END("InferenceSession.create"); TRACE_FUNC_END(); return new _InferenceSession(handler); } startProfiling() { this.handler.startProfiling(); } endProfiling() { this.handler.endProfiling(); } get inputNames() { return this.handler.inputNames; } get outputNames() { return this.handler.outputNames; } get inputMetadata() { return this.handler.inputMetadata; } get outputMetadata() { return this.handler.outputMetadata; } }; } }); // common/dist/esm/inference-session.js var InferenceSession2; var init_inference_session = __esm({ "common/dist/esm/inference-session.js"() { "use strict"; init_inference_session_impl(); InferenceSession2 = InferenceSession; } }); // common/dist/esm/tensor-conversion.js var init_tensor_conversion = __esm({ "common/dist/esm/tensor-conversion.js"() { "use strict"; } }); // common/dist/esm/tensor-factory.js var init_tensor_factory = __esm({ "common/dist/esm/tensor-factory.js"() { "use strict"; } }); // common/dist/esm/onnx-model.js var init_onnx_model = __esm({ "common/dist/esm/onnx-model.js"() { "use strict"; } }); // common/dist/esm/onnx-value.js var init_onnx_value = __esm({ "common/dist/esm/onnx-value.js"() { "use strict"; } }); // common/dist/esm/index.js var esm_exports = {}; __export(esm_exports, { InferenceSession: () => InferenceSession2, TRACE: () => TRACE, TRACE_EVENT_BEGIN: () => TRACE_EVENT_BEGIN, TRACE_EVENT_END: () => TRACE_EVENT_END, TRACE_FUNC_BEGIN: () => TRACE_FUNC_BEGIN, TRACE_FUNC_END: () => TRACE_FUNC_END, Tensor: () => Tensor2, env: () => env2, registerBackend: () => registerBackend }); var init_esm = __esm({ "common/dist/esm/index.js"() { "use strict"; init_backend(); init_env(); init_inference_session(); init_tensor(); init_tensor_conversion(); init_tensor_factory(); init_trace(); init_onnx_model(); init_onnx_value(); } }); // web/lib/onnxjs/instrument.ts function log(arg0, arg1, arg2, arg3) { if (arg1 === void 0) { return createCategorizedLogger(arg0); } else if (arg2 === void 0) { logInternal(arg0, arg1, 1); } else if (typeof arg2 === "number" && arg3 === void 0) { logInternal(arg0, arg1, arg2); } else if (typeof arg2 === "string" && arg3 === void 0) { logInternal(arg0, arg2, 1, arg1); } else if (typeof arg2 === "string" && typeof arg3 === "number") { logInternal(arg0, arg2, arg3, arg1); } else { throw new TypeError("input is valid"); } } function createCategorizedLogger(category) { return { verbose: log.verbose.bind(null, category), info: log.info.bind(null, category), warning: log.warning.bind(null, category), error: log.error.bind(null, category), fatal: log.fatal.bind(null, category) }; } function logInternal(severity, content, _stack, category) { const config = LOGGER_CONFIG_MAP[category || ""] || LOGGER_CONFIG_MAP[""]; if (SEVERITY_VALUE[severity] < SEVERITY_VALUE[config.minimalSeverity]) { return; } if (config.logDateTime) { content = `${(/* @__PURE__ */ new Date()).toISOString()}|${content}`; } if (config.logSourceLocation) { } LOGGER_PROVIDER_MAP[config.provider].log(severity, content, category); } var NoOpLoggerProvider, ConsoleLoggerProvider, SEVERITY_VALUE, LOGGER_PROVIDER_MAP, LOGGER_DEFAULT_CONFIG, LOGGER_CONFIG_MAP, Logger, Event, EventRecord, Profiler, now; var init_instrument = __esm({ "web/lib/onnxjs/instrument.ts"() { "use strict"; NoOpLoggerProvider = class { log(_severity, _content, _category) { } }; ConsoleLoggerProvider = class { log(severity, content, category) { console.log(`${this.color(severity)} ${category ? "\x1B[35m" + category + "\x1B[0m " : ""}${content}`); } color(severity) { switch (severity) { case "verbose": return "\x1B[34;40mv\x1B[0m"; case "info": return "\x1B[32mi\x1B[0m"; case "warning": return "\x1B[30;43mw\x1B[0m"; case "error": return "\x1B[31;40me\x1B[0m"; case "fatal": return "\x1B[101mf\x1B[0m"; default: throw new Error(`unsupported severity: ${severity}`); } } }; SEVERITY_VALUE = { verbose: 1e3, info: 2e3, warning: 4e3, error: 5e3, fatal: 6e3 }; LOGGER_PROVIDER_MAP = { ["none"]: new NoOpLoggerProvider(), ["console"]: new ConsoleLoggerProvider() }; LOGGER_DEFAULT_CONFIG = { provider: "console", minimalSeverity: "warning", logDateTime: true, logSourceLocation: false }; LOGGER_CONFIG_MAP = { [""]: LOGGER_DEFAULT_CONFIG }; ((log3) => { function verbose(arg0, arg1) { log3("verbose", arg0, arg1); } log3.verbose = verbose; function info(arg0, arg1) { log3("info", arg0, arg1); } log3.info = info; function warning(arg0, arg1) { log3("warning", arg0, arg1); } log3.warning = warning; function error(arg0, arg1) { log3("error", arg0, arg1); } log3.error = error; function fatal(arg0, arg1) { log3("fatal", arg0, arg1); } log3.fatal = fatal; function reset(config) { LOGGER_CONFIG_MAP = {}; set("", config || {}); } log3.reset = reset; function set(category, config) { if (category === "*") { reset(config); } else { const previousConfig = LOGGER_CONFIG_MAP[category] || LOGGER_DEFAULT_CONFIG; LOGGER_CONFIG_MAP[category] = { provider: config.provider || previousConfig.provider, minimalSeverity: config.minimalSeverity || previousConfig.minimalSeverity, logDateTime: config.logDateTime === void 0 ? previousConfig.logDateTime : config.logDateTime, logSourceLocation: config.logSourceLocation === void 0 ? previousConfig.logSourceLocation : config.logSourceLocation }; } } log3.set = set; function setWithEnv(env3) { const config = {}; if (env3.logLevel) { config.minimalSeverity = env3.logLevel; } set("", config); } log3.setWithEnv = setWithEnv; })(log || (log = {})); Logger = log; Event = class { constructor(category, name2, startTime, endCallback, timer, ctx) { this.category = category; this.name = name2; this.startTime = startTime; this.endCallback = endCallback; this.timer = timer; this.ctx = ctx; } async end() { return this.endCallback(this); } async checkTimer() { if (this.ctx === void 0 || this.timer === void 0) { throw new Error("No webgl timer found"); } else { this.ctx.endTimer(); return this.ctx.waitForQueryAndGetTime(this.timer); } } }; EventRecord = class { constructor(category, name2, startTime, endTime) { this.category = category; this.name = name2; this.startTime = startTime; this.endTime = endTime; } }; Profiler = class { constructor(maxNumberEvents, flushBatchSize, flushIntervalInMilliseconds) { this._started = false; this._flushPointer = 0; this._started = false; this._maxNumberEvents = maxNumberEvents === void 0 ? 1e4 : maxNumberEvents; this._flushBatchSize = flushBatchSize === void 0 ? 10 : flushBatchSize; this._flushIntervalInMilliseconds = flushIntervalInMilliseconds === void 0 ? 5e3 : flushIntervalInMilliseconds; } static create(config) { if (config === void 0) { return new this(); } return new this(config.maxNumberEvents, config.flushBatchSize, config.flushIntervalInMilliseconds); } // start profiling start() { this._started = true; this._timingEvents = []; this._flushTime = now(); this._flushPointer = 0; } // stop profiling stop() { this._started = false; for (; this._flushPointer < this._timingEvents.length; this._flushPointer++) { this.logOneEvent(this._timingEvents[this._flushPointer]); } } event(category, name2, func, ctx) { const event = this._started ? this.begin(category, name2, ctx) : void 0; let isPromise = false; const res = func(); if (res && typeof res.then === "function") { isPromise = true; return new Promise((resolve, reject) => { res.then( async (value) => { if (event) { await event.end(); } resolve(value); }, async (reason) => { if (event) { await event.end(); } reject(reason); } ); }); } if (!isPromise && event) { const eventRes = event.end(); if (eventRes && typeof eventRes.then === "function") { return new Promise((resolve, reject) => { eventRes.then( () => { resolve(res); }, (reason) => { reject(reason); } ); }); } } return res; } // begin an event begin(category, name2, ctx) { if (!this._started) { throw new Error("profiler is not started yet"); } if (ctx === void 0) { const startTime = now(); this.flush(startTime); return new Event(category, name2, startTime, (e) => this.endSync(e)); } else { const timer = ctx.beginTimer(); return new Event(category, name2, 0, async (e) => this.end(e), timer, ctx); } } // end the specific event async end(event) { const endTime = await event.checkTimer(); if (this._timingEvents.length < this._maxNumberEvents) { this._timingEvents.push(new EventRecord(event.category, event.name, event.startTime, endTime)); this.flush(endTime); } } endSync(event) { const endTime = now(); if (this._timingEvents.length < this._maxNumberEvents) { this._timingEvents.push(new EventRecord(event.category, event.name, event.startTime, endTime)); this.flush(endTime); } } logOneEvent(event) { Logger.verbose( `Profiler.${event.category}`, `${(event.endTime - event.startTime).toFixed(2)}ms on event '${event.name}' at ${event.endTime.toFixed(2)}` ); } flush(currentTime) { if (this._timingEvents.length - this._flushPointer >= this._flushBatchSize || currentTime - this._flushTime >= this._flushIntervalInMilliseconds) { for (const previousPointer = this._flushPointer; this._flushPointer < previousPointer + this._flushBatchSize && this._flushPointer < this._timingEvents.length; this._flushPointer++) { this.logOneEvent(this._timingEvents[this._flushPointer]); } this._flushTime = now(); } } get started() { return this._started; } }; now = typeof performance !== "undefined" && performance.now ? () => performance.now() : Date.now; } }); // web/lib/onnxjs/opset.ts function resolveOperator(node, opsets, rules) { for (const rule of rules) { const opType = rule[0]; const domain = rule[1]; const versionSelector = rule[2]; const opImpl = rule[3]; const opInit = rule[4]; if (node.opType === opType) { for (const opset of opsets) { if (opset.domain === domain || opset.domain === "ai.onnx" && domain === "") { if (matchSelector(opset.version, versionSelector)) { return { opImpl, opInit }; } } } } } throw new TypeError( `cannot resolve operator '${node.opType}' with opsets: ${opsets.map((set) => `${set.domain || "ai.onnx"} v${set.version}`).join(", ")}` ); } function matchSelector(version3, selector) { if (selector.endsWith("+")) { const rangeStart = Number.parseInt(selector.substring(0, selector.length - 1), 10); return !isNaN(rangeStart) && rangeStart <= version3; } else if (selector.split("-").length === 2) { const pair = selector.split("-"); const rangeStart = Number.parseInt(pair[0], 10); const rangeEnd = Number.parseInt(pair[1], 10); return !isNaN(rangeStart) && !isNaN(rangeEnd) && rangeStart <= version3 && version3 <= rangeEnd; } else { return Number.parseInt(selector, 10) === version3; } } var init_opset = __esm({ "web/lib/onnxjs/opset.ts"() { "use strict"; } }); // web/node_modules/guid-typescript/dist/guid.js var require_guid = __commonJS({ "web/node_modules/guid-typescript/dist/guid.js"(exports2) { "use strict"; exports2.__esModule = true; var Guid2 = ( /** @class */ function() { function Guid3(guid) { if (!guid) { throw new TypeError("Invalid argument; `value` has no value."); } this.value = Guid3.EMPTY; if (guid && Guid3.isGuid(guid)) { this.value = guid; } } Guid3.isGuid = function(guid) { var value = guid.toString(); return guid && (guid instanceof Guid3 || Guid3.validator.test(value)); }; Guid3.create = function() { return new Guid3([Guid3.gen(2), Guid3.gen(1), Guid3.gen(1), Guid3.gen(1), Guid3.gen(3)].join("-")); }; Guid3.createEmpty = function() { return new Guid3("emptyguid"); }; Guid3.parse = function(guid) { return new Guid3(guid); }; Guid3.raw = function() { return [Guid3.gen(2), Guid3.gen(1), Guid3.gen(1), Guid3.gen(1), Guid3.gen(3)].join("-"); }; Guid3.gen = function(count) { var out = ""; for (var i = 0; i < count; i++) { out += ((1 + Math.random()) * 65536 | 0).toString(16).substring(1); } return out; }; Guid3.prototype.equals = function(other) { return Guid3.isGuid(other) && this.value === other.toString(); }; Guid3.prototype.isEmpty = function() { return this.value === Guid3.EMPTY; }; Guid3.prototype.toString = function() { return this.value; }; Guid3.prototype.toJSON = function() { return { value: this.value }; }; Guid3.validator = new RegExp("^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$", "i"); Guid3.EMPTY = "00000000-0000-0000-0000-000000000000"; return Guid3; }() ); exports2.Guid = Guid2; } }); // web/node_modules/long/index.js function Long(low, high, unsigned) { this.low = low | 0; this.high = high | 0; this.unsigned = !!unsigned; } function isLong(obj) { return (obj && obj["__isLong__"]) === true; } function ctz32(value) { var c = Math.clz32(value & -value); return value ? 31 - c : c; } function fromInt(value, unsigned) { var obj, cachedObj, cache2; if (unsigned) { value >>>= 0; if (cache2 = 0 <= value && value < 256) { cachedObj = UINT_CACHE[value]; if (cachedObj) return cachedObj; } obj = fromBits(value, 0, true); if (cache2) UINT_CACHE[value] = obj; return obj; } else { value |= 0; if (cache2 = -128 <= value && value < 128) { cachedObj = INT_CACHE[value]; if (cachedObj) return cachedObj; } obj = fromBits(value, value < 0 ? -1 : 0, false); if (cache2) INT_CACHE[value] = obj; return obj; } } function fromNumber(value, unsigned) { if (isNaN(value)) return unsigned ? UZERO : ZERO; if (unsigned) { if (value < 0) return UZERO; if (value >= TWO_PWR_64_DBL) return MAX_UNSIGNED_VALUE; } else { if (value <= -TWO_PWR_63_DBL) return MIN_VALUE; if (value + 1 >= TWO_PWR_63_DBL) return MAX_VALUE; } if (value < 0) return fromNumber(-value, unsigned).neg(); return fromBits(value % TWO_PWR_32_DBL | 0, value / TWO_PWR_32_DBL | 0, unsigned); } function fromBits(lowBits, highBits, unsigned) { return new Long(lowBits, highBits, unsigned); } function fromString(str, unsigned, radix) { if (str.length === 0) throw Error("empty string"); if (typeof unsigned === "number") { radix = unsigned; unsigned = false; } else { unsigned = !!unsigned; } if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity") return unsigned ? UZERO : ZERO; radix = radix || 10; if (radix < 2 || 36 < radix) throw RangeError("radix"); var p; if ((p = str.indexOf("-")) > 0) throw Error("interior hyphen"); else if (p === 0) { return fromString(str.substring(1), unsigned, radix).neg(); } var radixToPower = fromNumber(pow_dbl(radix, 8)); var result = ZERO; for (var i = 0; i < str.length; i += 8) { var size = Math.min(8, str.length - i), value = parseInt(str.substring(i, i + size), radix); if (size < 8) { var power = fromNumber(pow_dbl(radix, size)); result = result.mul(power).add(fromNumber(value)); } else { result = result.mul(radixToPower); result = result.add(fromNumber(value)); } } result.unsigned = unsigned; return result; } function fromValue(val, unsigned) { if (typeof val === "number") return fromNumber(val, unsigned); if (typeof val === "string") return fromString(val, unsigned); return fromBits(val.low, val.high, typeof unsigned === "boolean" ? unsigned : val.unsigned); } var wasm, INT_CACHE, UINT_CACHE, pow_dbl, TWO_PWR_16_DBL, TWO_PWR_24_DBL, TWO_PWR_32_DBL, TWO_PWR_64_DBL, TWO_PWR_63_DBL, TWO_PWR_24, ZERO, UZERO, ONE, UONE, NEG_ONE, MAX_VALUE, MAX_UNSIGNED_VALUE, MIN_VALUE, LongPrototype, long_default; var init_long = __esm({ "web/node_modules/long/index.js"() { wasm = null; try { wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([ 0, 97, 115, 109, 1, 0, 0, 0, 1, 13, 2, 96, 0, 1, 127, 96, 4, 127, 127, 127, 127, 1, 127, 3, 7, 6, 0, 1, 1, 1, 1, 1, 6, 6, 1, 127, 1, 65, 0, 11, 7, 50, 6, 3, 109, 117, 108, 0, 1, 5, 100, 105, 118, 95, 115, 0, 2, 5, 100, 105, 118, 95, 117, 0, 3, 5, 114, 101, 109, 95, 115, 0, 4, 5, 114, 101, 109, 95, 117, 0, 5, 8, 103, 101, 116, 95, 104, 105, 103, 104, 0, 0, 10, 191, 1, 6, 4, 0, 35, 0, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 126, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 127, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 128, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 129, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 130, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11 ])), {}).exports; } catch (e) { } Long.prototype.__isLong__; Object.defineProperty(Long.prototype, "__isLong__", { value: true }); Long.isLong = isLong; INT_CACHE = {}; UINT_CACHE = {}; Long.fromInt = fromInt; Long.fromNumber = fromNumber; Long.fromBits = fromBits; pow_dbl = Math.pow; Long.fromString = fromString; Long.fromValue = fromValue; TWO_PWR_16_DBL = 1 << 16; TWO_PWR_24_DBL = 1 << 24; TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL; TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL; TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2; TWO_PWR_24 = fromInt(TWO_PWR_24_DBL); ZERO = fromInt(0); Long.ZERO = ZERO; UZERO = fromInt(0, true); Long.UZERO = UZERO; ONE = fromInt(1); Long.ONE = ONE; UONE = fromInt(1, true); Long.UONE = UONE; NEG_ONE = fromInt(-1); Long.NEG_ONE = NEG_ONE; MAX_VALUE = fromBits(4294967295 | 0, 2147483647 | 0, false); Long.MAX_VALUE = MAX_VALUE; MAX_UNSIGNED_VALUE = fromBits(4294967295 | 0, 4294967295 | 0, true); Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE; MIN_VALUE = fromBits(0, 2147483648 | 0, false); Long.MIN_VALUE = MIN_VALUE; LongPrototype = Long.prototype; LongPrototype.toInt = function toInt() { return this.unsigned ? this.low >>> 0 : this.low; }; LongPrototype.toNumber = function toNumber() { if (this.unsigned) return (this.high >>> 0) * TWO_PWR_32_DBL + (this.low >>> 0); return this.high * TWO_PWR_32_DBL + (this.low >>> 0); }; LongPrototype.toString = function toString(radix) { radix = radix || 10; if (radix < 2 || 36 < radix) throw RangeError("radix"); if (this.isZero()) return "0"; if (this.isNegative()) { if (this.eq(MIN_VALUE)) { var radixLong = fromNumber(radix), div2 = this.div(radixLong), rem1 = div2.mul(radixLong).sub(this); return div2.toString(radix) + rem1.toInt().toString(radix); } else return "-" + this.neg().toString(radix); } var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned), rem = this; var result = ""; while (true) { var remDiv = rem.div(radixToPower), intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0, digits = intval.toString(radix); rem = remDiv; if (rem.isZero()) return digits + result; else { while (digits.length < 6) digits = "0" + digits; result = "" + digits + result; } } }; LongPrototype.getHighBits = function getHighBits() { return this.high; }; LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() { return this.high >>> 0; }; LongPrototype.getLowBits = function getLowBits() { return this.low; }; LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() { return this.low >>> 0; }; LongPrototype.getNumBitsAbs = function getNumBitsAbs() { if (this.isNegative()) return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs(); var val = this.high != 0 ? this.high : this.low; for (var bit = 31; bit > 0; bit--) if ((val & 1 << bit) != 0) break; return this.high != 0 ? bit + 33 : bit + 1; }; LongPrototype.isZero = function isZero() { return this.high === 0 && this.low === 0; }; LongPrototype.eqz = LongPrototype.isZero; LongPrototype.isNegative = function isNegative() { return !this.unsigned && this.high < 0; }; LongPrototype.isPositive = function isPositive() { return this.unsigned || this.high >= 0; }; LongPrototype.isOdd = function isOdd() { return (this.low & 1) === 1; }; LongPrototype.isEven = function isEven() { return (this.low & 1) === 0; }; LongPrototype.equals = function equals(other) { if (!isLong(other)) other = fromValue(other); if (this.unsigned !== other.unsigned && this.high >>> 31 === 1 && other.high >>> 31 === 1) return false; return this.high === other.high && this.low === other.low; }; LongPrototype.eq = LongPrototype.equals; LongPrototype.notEquals = function notEquals(other) { return !this.eq( /* validates */ other ); }; LongPrototype.neq = LongPrototype.notEquals; LongPrototype.ne = LongPrototype.notEquals; LongPrototype.lessThan = function lessThan(other) { return this.comp( /* validates */ other ) < 0; }; LongPrototype.lt = LongPrototype.lessThan; LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) { return this.comp( /* validates */ other ) <= 0; }; LongPrototype.lte = LongPrototype.lessThanOrEqual; LongPrototype.le = LongPrototype.lessThanOrEqual; LongPrototype.greaterThan = function greaterThan(other) { return this.comp( /* validates */ other ) > 0; }; LongPrototype.gt = LongPrototype.greaterThan; LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) { return this.comp( /* validates */ other ) >= 0; }; LongPrototype.gte = LongPrototype.greaterThanOrEqual; LongPrototype.ge = LongPrototype.greaterThanOrEqual; LongPrototype.compare = function compare(other) { if (!isLong(other)) other = fromValue(other); if (this.eq(other)) return 0; var thisNeg = this.isNegative(), otherNeg = other.isNegative(); if (thisNeg && !otherNeg) return -1; if (!thisNeg && otherNeg) return 1; if (!this.unsigned) return this.sub(other).isNegative() ? -1 : 1; return other.high >>> 0 > this.high >>> 0 || other.high === this.high && other.low >>> 0 > this.low >>> 0 ? -1 : 1; }; LongPrototype.comp = LongPrototype.compare; LongPrototype.negate = function negate() { if (!this.unsigned && this.eq(MIN_VALUE)) return MIN_VALUE; return this.not().add(ONE); }; LongPrototype.neg = LongPrototype.negate; LongPrototype.add = function add(addend) { if (!isLong(addend)) addend = fromValue(addend); var a48 = this.high >>> 16; var a32 = this.high & 65535; var a16 = this.low >>> 16; var a00 = this.low & 65535; var b48 = addend.high >>> 16; var b32 = addend.high & 65535; var b16 = addend.low >>> 16; var b00 = addend.low & 65535; var c48 = 0, c32 = 0, c16 = 0, c00 = 0; c00 += a00 + b00; c16 += c00 >>> 16; c00 &= 65535; c16 += a16 + b16; c32 += c16 >>> 16; c16 &= 65535; c32 += a32 + b32; c48 += c32 >>> 16; c32 &= 65535; c48 += a48 + b48; c48 &= 65535; return fromBits(c16 << 16 | c00, c48 << 16 | c32, this.unsigned); }; LongPrototype.subtract = function subtract(subtrahend) { if (!isLong(subtrahend)) subtrahend = fromValue(subtrahend); return this.add(subtrahend.neg()); }; LongPrototype.sub = LongPrototype.subtract; LongPrototype.multiply = function multiply(multiplier) { if (this.isZero()) return this; if (!isLong(multiplier)) multiplier = fromValue(multiplier); if (wasm) { var low = wasm["mul"]( this.low, this.high, multiplier.low, multiplier.high ); return fromBits(low, wasm["get_high"](), this.unsigned); } if (multiplier.isZero()) return this.unsigned ? UZERO : ZERO; if (this.eq(MIN_VALUE)) return multiplier.isOdd() ? MIN_VALUE : ZERO; if (multiplier.eq(MIN_VALUE)) return this.isOdd() ? MIN_VALUE : ZERO; if (this.isNegative()) { if (multiplier.isNegative()) return this.neg().mul(multiplier.neg()); else return this.neg().mul(multiplier).neg(); } else if (multiplier.isNegative()) return this.mul(multiplier.neg()).neg(); if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24)) return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned); var a48 = this.high >>> 16; var a32 = this.high & 65535; var a16 = this.low >>> 16; var a00 = this.low & 65535; var b48 = multiplier.high >>> 16; var b32 = multiplier.high & 65535; var b16 = multiplier.low >>> 16; var b00 = multiplier.low & 65535; var c48 = 0, c32 = 0, c16 = 0, c00 = 0; c00 += a00 * b00; c16 += c00 >>> 16; c00 &= 65535; c16 += a16 * b00; c32 += c16 >>> 16; c16 &= 65535; c16 += a00 * b16; c32 += c16 >>> 16; c16 &= 65535; c32 += a32 * b00; c48 += c32 >>> 16; c32 &= 65535; c32 += a16 * b16; c48 += c32 >>> 16; c32 &= 65535; c32 += a00 * b32; c48 += c32 >>> 16; c32 &= 65535; c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; c48 &= 65535; return fromBits(c16 << 16 | c00, c48 << 16 | c32, this.unsigned); }; LongPrototype.mul = LongPrototype.multiply; LongPrototype.divide = function divide(divisor) { if (!isLong(divisor)) divisor = fromValue(divisor); if (divisor.isZero()) throw Error("division by zero"); if (wasm) { if (!this.unsigned && this.high === -2147483648 && divisor.low === -1 && divisor.high === -1) { return this; } var low = (this.unsigned ? wasm["div_u"] : wasm["div_s"])( this.low, this.high, divisor.low, divisor.high ); return fromBits(low, wasm["get_high"](), this.unsigned); } if (this.isZero()) return this.unsigned ? UZERO : ZERO; var approx, rem, res; if (!this.unsigned) { if (this.eq(MIN_VALUE)) { if (divisor.eq(ONE) || divisor.eq(NEG_ONE)) return MIN_VALUE; else if (divisor.eq(MIN_VALUE)) return ONE; else { var halfThis = this.shr(1); approx = halfThis.div(divisor).shl(1); if (approx.eq(ZERO)) { return divisor.isNegative() ? ONE : NEG_ONE; } else { rem = this.sub(divisor.mul(approx)); res = approx.add(rem.div(divisor)); return res; } } } else if (divisor.eq(MIN_VALUE)) return this.unsigned ? UZERO : ZERO; if (this.isNegative()) { if (divisor.isNegative()) return this.neg().div(divisor.neg()); return this.neg().div(divisor).neg(); } else if (divisor.isNegative()) return this.div(divisor.neg()).neg(); res = ZERO; } else { if (!divisor.unsigned) divisor = divisor.toUnsigned(); if (divisor.gt(this)) return UZERO; if (divisor.gt(this.shru(1))) return UONE; res = UZERO; } rem = this; while (rem.gte(divisor)) { approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber())); var log22 = Math.ceil(Math.log(approx) / Math.LN2), delta = log22 <= 48 ? 1 : pow_dbl(2, log22 - 48), approxRes = fromNumber(approx), approxRem = approxRes.mul(divisor); while (approxRem.isNegative() || approxRem.gt(rem)) { approx -= delta; approxRes = fromNumber(approx, this.unsigned); approxRem = approxRes.mul(divisor); } if (approxRes.isZero()) approxRes = ONE; res = res.add(approxRes); rem = rem.sub(approxRem); } return res; }; LongPrototype.div = LongPrototype.divide; LongPrototype.modulo = function modulo(divisor) { if (!isLong(divisor)) divisor = fromValue(divisor); if (wasm) { var low = (this.unsigned ? wasm["rem_u"] : wasm["rem_s"])( this.low, this.high, divisor.low, divisor.high ); return fromBits(low, wasm["get_high"](), this.unsigned); } return this.sub(this.div(divisor).mul(divisor)); }; LongPrototype.mod = LongPrototype.modulo; LongPrototype.rem = LongPrototype.modulo; LongPrototype.not = function not() { return fromBits(~this.low, ~this.high, this.unsigned); }; LongPrototype.countLeadingZeros = function countLeadingZeros() { return this.high ? Math.clz32(this.high) : Math.clz32(this.low) + 32; }; LongPrototype.clz = LongPrototype.countLeadingZeros; LongPrototype.countTrailingZeros = function countTrailingZeros() { return this.low ? ctz32(this.low) : ctz32(this.high) + 32; }; LongPrototype.ctz = LongPrototype.countTrailingZeros; LongPrototype.and = function and(other) { if (!isLong(other)) other = fromValue(other); return fromBits(this.low & other.low, this.high & other.high, this.unsigned); }; LongPrototype.or = function or(other) { if (!isLong(other)) other = fromValue(other); return fromBits(this.low | other.low, this.high | other.high, this.unsigned); }; LongPrototype.xor = function xor(other) { if (!isLong(other)) other = fromValue(other); return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned); }; LongPrototype.shiftLeft = function shiftLeft(numBits) { if (isLong(numBits)) numBits = numBits.toInt(); if ((numBits &= 63) === 0) return this; else if (numBits < 32) return fromBits(this.low << numBits, this.high << numBits | this.low >>> 32 - numBits, this.unsigned); else return fromBits(0, this.low << numBits - 32, this.unsigned); }; LongPrototype.shl = LongPrototype.shiftLeft; LongPrototype.shiftRight = function shiftRight(numBits) { if (isLong(numBits)) numBits = numBits.toInt(); if ((numBits &= 63) === 0) return this; else if (numBits < 32) return fromBits(this.low >>> numBits | this.high << 32 - numBits, this.high >> numBits, this.unsigned); else return fromBits(this.high >> numBits - 32, this.high >= 0 ? 0 : -1, this.unsigned); }; LongPrototype.shr = LongPrototype.shiftRight; LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) { if (isLong(numBits)) numBits = numBits.toInt(); if ((numBits &= 63) === 0) return this; if (numBits < 32) return fromBits(this.low >>> numBits | this.high << 32 - numBits, this.high >>> numBits, this.unsigned); if (numBits === 32) return fromBits(this.high, 0, this.unsigned); return fromBits(this.high >>> numBits - 32, 0, this.unsigned); }; LongPrototype.shru = LongPrototype.shiftRightUnsigned; LongPrototype.shr_u = LongPrototype.shiftRightUnsigned; LongPrototype.rotateLeft = function rotateLeft(numBits) { var b; if (isLong(numBits)) numBits = numBits.toInt(); if ((numBits &= 63) === 0) return this; if (numBits === 32) return fromBits(this.high, this.low, this.unsigned); if (numBits < 32) { b = 32 - numBits; return fromBits(this.low << numBits | this.high >>> b, this.high << numBits | this.low >>> b, this.unsigned); } numBits -= 32; b = 32 - numBits; return fromBits(this.high << numBits | this.low >>> b, this.low << numBits | this.high >>> b, this.unsigned); }; LongPrototype.rotl = LongPrototype.rotateLeft; LongPrototype.rotateRight = function rotateRight(numBits) { var b; if (isLong(numBits)) numBits = numBits.toInt(); if ((numBits &= 63) === 0) return this; if (numBits === 32) return fromBits(this.high, this.low, this.unsigned); if (numBits < 32) { b = 32 - numBits; return fromBits(this.high << b | this.low >>> numBits, this.low << b | this.high >>> numBits, this.unsigned); } numBits -= 32; b = 32 - numBits; return fromBits(this.low << b | this.high >>> numBits, this.high << b | this.low >>> numBits, this.unsigned); }; LongPrototype.rotr = LongPrototype.rotateRight; LongPrototype.toSigned = function toSigned() { if (!this.unsigned) return this; return fromBits(this.low, this.high, false); }; LongPrototype.toUnsigned = function toUnsigned() { if (this.unsigned) return this; return fromBits(this.low, this.high, true); }; LongPrototype.toBytes = function toBytes(le) { return le ? this.toBytesLE() : this.toBytesBE(); }; LongPrototype.toBytesLE = function toBytesLE() { var hi = this.high, lo = this.low; return [ lo & 255, lo >>> 8 & 255, lo >>> 16 & 255, lo >>> 24, hi & 255, hi >>> 8 & 255, hi >>> 16 & 255, hi >>> 24 ]; }; LongPrototype.toBytesBE = function toBytesBE() { var hi = this.high, lo = this.low; return [ hi >>> 24, hi >>> 16 & 255, hi >>> 8 & 255, hi & 255, lo >>> 24, lo >>> 16 & 255, lo >>> 8 & 255, lo & 255 ]; }; Long.fromBytes = function fromBytes(bytes, unsigned, le) { return le ? Long.fromBytesLE(bytes, unsigned) : Long.fromBytesBE(bytes, unsigned); }; Long.fromBytesLE = function fromBytesLE(bytes, unsigned) { return new Long( bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24, bytes[4] | bytes[5] << 8 | bytes[6] << 16 | bytes[7] << 24, unsigned ); }; Long.fromBytesBE = function fromBytesBE(bytes, unsigned) { return new Long( bytes[4] << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7], bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], unsigned ); }; long_default = Long; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/arg-type.js var require_arg_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/arg-type.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.ArgType = void 0; var ArgType2; (function(ArgType3) { ArgType3[ArgType3["INPUT"] = 0] = "INPUT"; ArgType3[ArgType3["OUTPUT"] = 1] = "OUTPUT"; })(ArgType2 || (exports2.ArgType = ArgType2 = {})); } }); // web/node_modules/flatbuffers/js/constants.js var require_constants = __commonJS({ "web/node_modules/flatbuffers/js/constants.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.SIZE_PREFIX_LENGTH = exports2.FILE_IDENTIFIER_LENGTH = exports2.SIZEOF_INT = exports2.SIZEOF_SHORT = void 0; exports2.SIZEOF_SHORT = 2; exports2.SIZEOF_INT = 4; exports2.FILE_IDENTIFIER_LENGTH = 4; exports2.SIZE_PREFIX_LENGTH = 4; } }); // web/node_modules/flatbuffers/js/utils.js var require_utils = __commonJS({ "web/node_modules/flatbuffers/js/utils.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.isLittleEndian = exports2.float64 = exports2.float32 = exports2.int32 = void 0; exports2.int32 = new Int32Array(2); exports2.float32 = new Float32Array(exports2.int32.buffer); exports2.float64 = new Float64Array(exports2.int32.buffer); exports2.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1; } }); // web/node_modules/flatbuffers/js/encoding.js var require_encoding = __commonJS({ "web/node_modules/flatbuffers/js/encoding.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Encoding = void 0; var Encoding; (function(Encoding2) { Encoding2[Encoding2["UTF8_BYTES"] = 1] = "UTF8_BYTES"; Encoding2[Encoding2["UTF16_STRING"] = 2] = "UTF16_STRING"; })(Encoding || (exports2.Encoding = Encoding = {})); } }); // web/node_modules/flatbuffers/js/byte-buffer.js var require_byte_buffer = __commonJS({ "web/node_modules/flatbuffers/js/byte-buffer.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.ByteBuffer = void 0; var constants_js_1 = require_constants(); var utils_js_1 = require_utils(); var encoding_js_1 = require_encoding(); var ByteBuffer2 = class _ByteBuffer { /** * Create a new ByteBuffer with a given array of bytes (`Uint8Array`) */ constructor(bytes_) { this.bytes_ = bytes_; this.position_ = 0; this.text_decoder_ = new TextDecoder(); } /** * Create and allocate a new ByteBuffer with a given size. */ static allocate(byte_size) { return new _ByteBuffer(new Uint8Array(byte_size)); } clear() { this.position_ = 0; } /** * Get the underlying `Uint8Array`. */ bytes() { return this.bytes_; } /** * Get the buffer's position. */ position() { return this.position_; } /** * Set the buffer's position. */ setPosition(position) { this.position_ = position; } /** * Get the buffer's capacity. */ capacity() { return this.bytes_.length; } readInt8(offset) { return this.readUint8(offset) << 24 >> 24; } readUint8(offset) { return this.bytes_[offset]; } readInt16(offset) { return this.readUint16(offset) << 16 >> 16; } readUint16(offset) { return this.bytes_[offset] | this.bytes_[offset + 1] << 8; } readInt32(offset) { return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24; } readUint32(offset) { return this.readInt32(offset) >>> 0; } readInt64(offset) { return BigInt.asIntN(64, BigInt(this.readUint32(offset)) + (BigInt(this.readUint32(offset + 4)) << BigInt(32))); } readUint64(offset) { return BigInt.asUintN(64, BigInt(this.readUint32(offset)) + (BigInt(this.readUint32(offset + 4)) << BigInt(32))); } readFloat32(offset) { utils_js_1.int32[0] = this.readInt32(offset); return utils_js_1.float32[0]; } readFloat64(offset) { utils_js_1.int32[utils_js_1.isLittleEndian ? 0 : 1] = this.readInt32(offset); utils_js_1.int32[utils_js_1.isLittleEndian ? 1 : 0] = this.readInt32(offset + 4); return utils_js_1.float64[0]; } writeInt8(offset, value) { this.bytes_[offset] = value; } writeUint8(offset, value) { this.bytes_[offset] = value; } writeInt16(offset, value) { this.bytes_[offset] = value; this.bytes_[offset + 1] = value >> 8; } writeUint16(offset, value) { this.bytes_[offset] = value; this.bytes_[offset + 1] = value >> 8; } writeInt32(offset, value) { this.bytes_[offset] = value; this.bytes_[offset + 1] = value >> 8; this.bytes_[offset + 2] = value >> 16; this.bytes_[offset + 3] = value >> 24; } writeUint32(offset, value) { this.bytes_[offset] = value; this.bytes_[offset + 1] = value >> 8; this.bytes_[offset + 2] = value >> 16; this.bytes_[offset + 3] = value >> 24; } writeInt64(offset, value) { this.writeInt32(offset, Number(BigInt.asIntN(32, value))); this.writeInt32(offset + 4, Number(BigInt.asIntN(32, value >> BigInt(32)))); } writeUint64(offset, value) { this.writeUint32(offset, Number(BigInt.asUintN(32, value))); this.writeUint32(offset + 4, Number(BigInt.asUintN(32, value >> BigInt(32)))); } writeFloat32(offset, value) { utils_js_1.float32[0] = value; this.writeInt32(offset, utils_js_1.int32[0]); } writeFloat64(offset, value) { utils_js_1.float64[0] = value; this.writeInt32(offset, utils_js_1.int32[utils_js_1.isLittleEndian ? 0 : 1]); this.writeInt32(offset + 4, utils_js_1.int32[utils_js_1.isLittleEndian ? 1 : 0]); } /** * Return the file identifier. Behavior is undefined for FlatBuffers whose * schema does not include a file_identifier (likely points at padding or the * start of a the root vtable). */ getBufferIdentifier() { if (this.bytes_.length < this.position_ + constants_js_1.SIZEOF_INT + constants_js_1.FILE_IDENTIFIER_LENGTH) { throw new Error("FlatBuffers: ByteBuffer is too short to contain an identifier."); } let result = ""; for (let i = 0; i < constants_js_1.FILE_IDENTIFIER_LENGTH; i++) { result += String.fromCharCode(this.readInt8(this.position_ + constants_js_1.SIZEOF_INT + i)); } return result; } /** * Look up a field in the vtable, return an offset into the object, or 0 if the * field is not present. */ __offset(bb_pos, vtable_offset) { const vtable = bb_pos - this.readInt32(bb_pos); return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0; } /** * Initialize any Table-derived type to point to the union at the given offset. */ __union(t, offset) { t.bb_pos = offset + this.readInt32(offset); t.bb = this; return t; } /** * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer. * This allocates a new string and converts to wide chars upon each access. * * To avoid the conversion to string, pass Encoding.UTF8_BYTES as the * "optionalEncoding" argument. This is useful for avoiding conversion when * the data will just be packaged back up in another FlatBuffer later on. * * @param offset * @param opt_encoding Defaults to UTF16_STRING */ __string(offset, opt_encoding) { offset += this.readInt32(offset); const length = this.readInt32(offset); offset += constants_js_1.SIZEOF_INT; const utf8bytes = this.bytes_.subarray(offset, offset + length); if (opt_encoding === encoding_js_1.Encoding.UTF8_BYTES) return utf8bytes; else return this.text_decoder_.decode(utf8bytes); } /** * Handle unions that can contain string as its member, if a Table-derived type then initialize it, * if a string then return a new one * * WARNING: strings are immutable in JS so we can't change the string that the user gave us, this * makes the behaviour of __union_with_string different compared to __union */ __union_with_string(o, offset) { if (typeof o === "string") { return this.__string(offset); } return this.__union(o, offset); } /** * Retrieve the relative offset stored at "offset" */ __indirect(offset) { return offset + this.readInt32(offset); } /** * Get the start of data of a vector whose offset is stored at "offset" in this object. */ __vector(offset) { return offset + this.readInt32(offset) + constants_js_1.SIZEOF_INT; } /** * Get the length of a vector whose offset is stored at "offset" in this object. */ __vector_len(offset) { return this.readInt32(offset + this.readInt32(offset)); } __has_identifier(ident) { if (ident.length != constants_js_1.FILE_IDENTIFIER_LENGTH) { throw new Error("FlatBuffers: file identifier must be length " + constants_js_1.FILE_IDENTIFIER_LENGTH); } for (let i = 0; i < constants_js_1.FILE_IDENTIFIER_LENGTH; i++) { if (ident.charCodeAt(i) != this.readInt8(this.position() + constants_js_1.SIZEOF_INT + i)) { return false; } } return true; } /** * A helper function for generating list for obj api */ createScalarList(listAccessor, listLength) { const ret = []; for (let i = 0; i < listLength; ++i) { const val = listAccessor(i); if (val !== null) { ret.push(val); } } return ret; } /** * A helper function for generating list for obj api * @param listAccessor function that accepts an index and return data at that index * @param listLength listLength * @param res result list */ createObjList(listAccessor, listLength) { const ret = []; for (let i = 0; i < listLength; ++i) { const val = listAccessor(i); if (val !== null) { ret.push(val.unpack()); } } return ret; } }; exports2.ByteBuffer = ByteBuffer2; } }); // web/node_modules/flatbuffers/js/builder.js var require_builder = __commonJS({ "web/node_modules/flatbuffers/js/builder.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Builder = void 0; var byte_buffer_js_1 = require_byte_buffer(); var constants_js_1 = require_constants(); var Builder = class _Builder { /** * Create a FlatBufferBuilder. */ constructor(opt_initial_size) { this.minalign = 1; this.vtable = null; this.vtable_in_use = 0; this.isNested = false; this.object_start = 0; this.vtables = []; this.vector_num_elems = 0; this.force_defaults = false; this.string_maps = null; this.text_encoder = new TextEncoder(); let initial_size; if (!opt_initial_size) { initial_size = 1024; } else { initial_size = opt_initial_size; } this.bb = byte_buffer_js_1.ByteBuffer.allocate(initial_size); this.space = initial_size; } clear() { this.bb.clear(); this.space = this.bb.capacity(); this.minalign = 1; this.vtable = null; this.vtable_in_use = 0; this.isNested = false; this.object_start = 0; this.vtables = []; this.vector_num_elems = 0; this.force_defaults = false; this.string_maps = null; } /** * In order to save space, fields that are set to their default value * don't get serialized into the buffer. Forcing defaults provides a * way to manually disable this optimization. * * @param forceDefaults true always serializes default values */ forceDefaults(forceDefaults) { this.force_defaults = forceDefaults; } /** * Get the ByteBuffer representing the FlatBuffer. Only call this after you've * called finish(). The actual data starts at the ByteBuffer's current position, * not necessarily at 0. */ dataBuffer() { return this.bb; } /** * Get the bytes representing the FlatBuffer. Only call this after you've * called finish(). */ asUint8Array() { return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset()); } /** * Prepare to write an element of `size` after `additional_bytes` have been * written, e.g. if you write a string, you need to align such the int length * field is aligned to 4 bytes, and the string data follows it directly. If all * you need to do is alignment, `additional_bytes` will be 0. * * @param size This is the of the new element to write * @param additional_bytes The padding size */ prep(size, additional_bytes) { if (size > this.minalign) { this.minalign = size; } const align_size = ~(this.bb.capacity() - this.space + additional_bytes) + 1 & size - 1; while (this.space < align_size + size + additional_bytes) { const old_buf_size = this.bb.capacity(); this.bb = _Builder.growByteBuffer(this.bb); this.space += this.bb.capacity() - old_buf_size; } this.pad(align_size); } pad(byte_size) { for (let i = 0; i < byte_size; i++) { this.bb.writeInt8(--this.space, 0); } } writeInt8(value) { this.bb.writeInt8(this.space -= 1, value); } writeInt16(value) { this.bb.writeInt16(this.space -= 2, value); } writeInt32(value) { this.bb.writeInt32(this.space -= 4, value); } writeInt64(value) { this.bb.writeInt64(this.space -= 8, value); } writeFloat32(value) { this.bb.writeFloat32(this.space -= 4, value); } writeFloat64(value) { this.bb.writeFloat64(this.space -= 8, value); } /** * Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary). * @param value The `int8` to add the buffer. */ addInt8(value) { this.prep(1, 0); this.writeInt8(value); } /** * Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary). * @param value The `int16` to add the buffer. */ addInt16(value) { this.prep(2, 0); this.writeInt16(value); } /** * Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary). * @param value The `int32` to add the buffer. */ addInt32(value) { this.prep(4, 0); this.writeInt32(value); } /** * Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary). * @param value The `int64` to add the buffer. */ addInt64(value) { this.prep(8, 0); this.writeInt64(value); } /** * Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary). * @param value The `float32` to add the buffer. */ addFloat32(value) { this.prep(4, 0); this.writeFloat32(value); } /** * Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary). * @param value The `float64` to add the buffer. */ addFloat64(value) { this.prep(8, 0); this.writeFloat64(value); } addFieldInt8(voffset, value, defaultValue) { if (this.force_defaults || value != defaultValue) { this.addInt8(value); this.slot(voffset); } } addFieldInt16(voffset, value, defaultValue) { if (this.force_defaults || value != defaultValue) { this.addInt16(value); this.slot(voffset); } } addFieldInt32(voffset, value, defaultValue) { if (this.force_defaults || value != defaultValue) { this.addInt32(value); this.slot(voffset); } } addFieldInt64(voffset, value, defaultValue) { if (this.force_defaults || value !== defaultValue) { this.addInt64(value); this.slot(voffset); } } addFieldFloat32(voffset, value, defaultValue) { if (this.force_defaults || value != defaultValue) { this.addFloat32(value); this.slot(voffset); } } addFieldFloat64(voffset, value, defaultValue) { if (this.force_defaults || value != defaultValue) { this.addFloat64(value); this.slot(voffset); } } addFieldOffset(voffset, value, defaultValue) { if (this.force_defaults || value != defaultValue) { this.addOffset(value); this.slot(voffset); } } /** * Structs are stored inline, so nothing additional is being added. `d` is always 0. */ addFieldStruct(voffset, value, defaultValue) { if (value != defaultValue) { this.nested(value); this.slot(voffset); } } /** * Structures are always stored inline, they need to be created right * where they're used. You'll get this assertion failure if you * created it elsewhere. */ nested(obj) { if (obj != this.offset()) { throw new TypeError("FlatBuffers: struct must be serialized inline."); } } /** * Should not be creating any other object, string or vector * while an object is being constructed */ notNested() { if (this.isNested) { throw new TypeError("FlatBuffers: object serialization must not be nested."); } } /** * Set the current vtable at `voffset` to the current location in the buffer. */ slot(voffset) { if (this.vtable !== null) this.vtable[voffset] = this.offset(); } /** * @returns Offset relative to the end of the buffer. */ offset() { return this.bb.capacity() - this.space; } /** * Doubles the size of the backing ByteBuffer and copies the old data towards * the end of the new buffer (since we build the buffer backwards). * * @param bb The current buffer with the existing data * @returns A new byte buffer with the old data copied * to it. The data is located at the end of the buffer. * * uint8Array.set() formally takes {Array|ArrayBufferView}, so to pass * it a uint8Array we need to suppress the type check: * @suppress {checkTypes} */ static growByteBuffer(bb) { const old_buf_size = bb.capacity(); if (old_buf_size & 3221225472) { throw new Error("FlatBuffers: cannot grow buffer beyond 2 gigabytes."); } const new_buf_size = old_buf_size << 1; const nbb = byte_buffer_js_1.ByteBuffer.allocate(new_buf_size); nbb.setPosition(new_buf_size - old_buf_size); nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size); return nbb; } /** * Adds on offset, relative to where it will be written. * * @param offset The offset to add. */ addOffset(offset) { this.prep(constants_js_1.SIZEOF_INT, 0); this.writeInt32(this.offset() - offset + constants_js_1.SIZEOF_INT); } /** * Start encoding a new object in the buffer. Users will not usually need to * call this directly. The FlatBuffers compiler will generate helper methods * that call this method internally. */ startObject(numfields) { this.notNested(); if (this.vtable == null) { this.vtable = []; } this.vtable_in_use = numfields; for (let i = 0; i < numfields; i++) { this.vtable[i] = 0; } this.isNested = true; this.object_start = this.offset(); } /** * Finish off writing the object that is under construction. * * @returns The offset to the object inside `dataBuffer` */ endObject() { if (this.vtable == null || !this.isNested) { throw new Error("FlatBuffers: endObject called without startObject"); } this.addInt32(0); const vtableloc = this.offset(); let i = this.vtable_in_use - 1; for (; i >= 0 && this.vtable[i] == 0; i--) { } const trimmed_size = i + 1; for (; i >= 0; i--) { this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0); } const standard_fields = 2; this.addInt16(vtableloc - this.object_start); const len = (trimmed_size + standard_fields) * constants_js_1.SIZEOF_SHORT; this.addInt16(len); let existing_vtable = 0; const vt1 = this.space; outer_loop: for (i = 0; i < this.vtables.length; i++) { const vt2 = this.bb.capacity() - this.vtables[i]; if (len == this.bb.readInt16(vt2)) { for (let j = constants_js_1.SIZEOF_SHORT; j < len; j += constants_js_1.SIZEOF_SHORT) { if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) { continue outer_loop; } } existing_vtable = this.vtables[i]; break; } } if (existing_vtable) { this.space = this.bb.capacity() - vtableloc; this.bb.writeInt32(this.space, existing_vtable - vtableloc); } else { this.vtables.push(this.offset()); this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc); } this.isNested = false; return vtableloc; } /** * Finalize a buffer, poiting to the given `root_table`. */ finish(root_table, opt_file_identifier, opt_size_prefix) { const size_prefix = opt_size_prefix ? constants_js_1.SIZE_PREFIX_LENGTH : 0; if (opt_file_identifier) { const file_identifier = opt_file_identifier; this.prep(this.minalign, constants_js_1.SIZEOF_INT + constants_js_1.FILE_IDENTIFIER_LENGTH + size_prefix); if (file_identifier.length != constants_js_1.FILE_IDENTIFIER_LENGTH) { throw new TypeError("FlatBuffers: file identifier must be length " + constants_js_1.FILE_IDENTIFIER_LENGTH); } for (let i = constants_js_1.FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) { this.writeInt8(file_identifier.charCodeAt(i)); } } this.prep(this.minalign, constants_js_1.SIZEOF_INT + size_prefix); this.addOffset(root_table); if (size_prefix) { this.addInt32(this.bb.capacity() - this.space); } this.bb.setPosition(this.space); } /** * Finalize a size prefixed buffer, pointing to the given `root_table`. */ finishSizePrefixed(root_table, opt_file_identifier) { this.finish(root_table, opt_file_identifier, true); } /** * This checks a required field has been set in a given table that has * just been constructed. */ requiredField(table, field) { const table_start = this.bb.capacity() - table; const vtable_start = table_start - this.bb.readInt32(table_start); const ok = field < this.bb.readInt16(vtable_start) && this.bb.readInt16(vtable_start + field) != 0; if (!ok) { throw new TypeError("FlatBuffers: field " + field + " must be set"); } } /** * Start a new array/vector of objects. Users usually will not call * this directly. The FlatBuffers compiler will create a start/end * method for vector types in generated code. * * @param elem_size The size of each element in the array * @param num_elems The number of elements in the array * @param alignment The alignment of the array */ startVector(elem_size, num_elems, alignment) { this.notNested(); this.vector_num_elems = num_elems; this.prep(constants_js_1.SIZEOF_INT, elem_size * num_elems); this.prep(alignment, elem_size * num_elems); } /** * Finish off the creation of an array and all its elements. The array must be * created with `startVector`. * * @returns The offset at which the newly created array * starts. */ endVector() { this.writeInt32(this.vector_num_elems); return this.offset(); } /** * Encode the string `s` in the buffer using UTF-8. If the string passed has * already been seen, we return the offset of the already written string * * @param s The string to encode * @return The offset in the buffer where the encoded string starts */ createSharedString(s) { if (!s) { return 0; } if (!this.string_maps) { this.string_maps = /* @__PURE__ */ new Map(); } if (this.string_maps.has(s)) { return this.string_maps.get(s); } const offset = this.createString(s); this.string_maps.set(s, offset); return offset; } /** * Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed * instead of a string, it is assumed to contain valid UTF-8 encoded data. * * @param s The string to encode * @return The offset in the buffer where the encoded string starts */ createString(s) { if (s === null || s === void 0) { return 0; } let utf8; if (s instanceof Uint8Array) { utf8 = s; } else { utf8 = this.text_encoder.encode(s); } this.addInt8(0); this.startVector(1, utf8.length, 1); this.bb.setPosition(this.space -= utf8.length); this.bb.bytes().set(utf8, this.space); return this.endVector(); } /** * Create a byte vector. * * @param v The bytes to add * @returns The offset in the buffer where the byte vector starts */ createByteVector(v) { if (v === null || v === void 0) { return 0; } this.startVector(1, v.length, 1); this.bb.setPosition(this.space -= v.length); this.bb.bytes().set(v, this.space); return this.endVector(); } /** * A helper function to pack an object * * @returns offset of obj */ createObjectOffset(obj) { if (obj === null) { return 0; } if (typeof obj === "string") { return this.createString(obj); } else { return obj.pack(this); } } /** * A helper function to pack a list of object * * @returns list of offsets of each non null object */ createObjectOffsetList(list) { const ret = []; for (let i = 0; i < list.length; ++i) { const val = list[i]; if (val !== null) { ret.push(this.createObjectOffset(val)); } else { throw new TypeError("FlatBuffers: Argument for createObjectOffsetList cannot contain null."); } } return ret; } createStructOffsetList(list, startFunc) { startFunc(this, list.length); this.createObjectOffsetList(list.slice().reverse()); return this.endVector(); } }; exports2.Builder = Builder; } }); // web/node_modules/flatbuffers/js/flatbuffers.js var require_flatbuffers = __commonJS({ "web/node_modules/flatbuffers/js/flatbuffers.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.ByteBuffer = exports2.Builder = exports2.Encoding = exports2.isLittleEndian = exports2.float64 = exports2.float32 = exports2.int32 = exports2.SIZE_PREFIX_LENGTH = exports2.FILE_IDENTIFIER_LENGTH = exports2.SIZEOF_INT = exports2.SIZEOF_SHORT = void 0; var constants_js_1 = require_constants(); Object.defineProperty(exports2, "SIZEOF_SHORT", { enumerable: true, get: function() { return constants_js_1.SIZEOF_SHORT; } }); var constants_js_2 = require_constants(); Object.defineProperty(exports2, "SIZEOF_INT", { enumerable: true, get: function() { return constants_js_2.SIZEOF_INT; } }); var constants_js_3 = require_constants(); Object.defineProperty(exports2, "FILE_IDENTIFIER_LENGTH", { enumerable: true, get: function() { return constants_js_3.FILE_IDENTIFIER_LENGTH; } }); var constants_js_4 = require_constants(); Object.defineProperty(exports2, "SIZE_PREFIX_LENGTH", { enumerable: true, get: function() { return constants_js_4.SIZE_PREFIX_LENGTH; } }); var utils_js_1 = require_utils(); Object.defineProperty(exports2, "int32", { enumerable: true, get: function() { return utils_js_1.int32; } }); Object.defineProperty(exports2, "float32", { enumerable: true, get: function() { return utils_js_1.float32; } }); Object.defineProperty(exports2, "float64", { enumerable: true, get: function() { return utils_js_1.float64; } }); Object.defineProperty(exports2, "isLittleEndian", { enumerable: true, get: function() { return utils_js_1.isLittleEndian; } }); var encoding_js_1 = require_encoding(); Object.defineProperty(exports2, "Encoding", { enumerable: true, get: function() { return encoding_js_1.Encoding; } }); var builder_js_1 = require_builder(); Object.defineProperty(exports2, "Builder", { enumerable: true, get: function() { return builder_js_1.Builder; } }); var byte_buffer_js_1 = require_byte_buffer(); Object.defineProperty(exports2, "ByteBuffer", { enumerable: true, get: function() { return byte_buffer_js_1.ByteBuffer; } }); } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/arg-type-and-index.js var require_arg_type_and_index = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/arg-type-and-index.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.ArgTypeAndIndex = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var arg_type_js_1 = require_arg_type(); var ArgTypeAndIndex2 = class _ArgTypeAndIndex { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsArgTypeAndIndex(bb, obj) { return (obj || new _ArgTypeAndIndex()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsArgTypeAndIndex(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _ArgTypeAndIndex()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } argType() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readInt8(this.bb_pos + offset) : arg_type_js_1.ArgType.INPUT; } index() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } static startArgTypeAndIndex(builder) { builder.startObject(2); } static addArgType(builder, argType) { builder.addFieldInt8(0, argType, arg_type_js_1.ArgType.INPUT); } static addIndex(builder, index) { builder.addFieldInt32(1, index, 0); } static endArgTypeAndIndex(builder) { const offset = builder.endObject(); return offset; } static createArgTypeAndIndex(builder, argType, index) { _ArgTypeAndIndex.startArgTypeAndIndex(builder); _ArgTypeAndIndex.addArgType(builder, argType); _ArgTypeAndIndex.addIndex(builder, index); return _ArgTypeAndIndex.endArgTypeAndIndex(builder); } }; exports2.ArgTypeAndIndex = ArgTypeAndIndex2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/attribute-type.js var require_attribute_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/attribute-type.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.AttributeType = void 0; var AttributeType2; (function(AttributeType3) { AttributeType3[AttributeType3["UNDEFINED"] = 0] = "UNDEFINED"; AttributeType3[AttributeType3["FLOAT"] = 1] = "FLOAT"; AttributeType3[AttributeType3["INT"] = 2] = "INT"; AttributeType3[AttributeType3["STRING"] = 3] = "STRING"; AttributeType3[AttributeType3["TENSOR"] = 4] = "TENSOR"; AttributeType3[AttributeType3["GRAPH"] = 5] = "GRAPH"; AttributeType3[AttributeType3["FLOATS"] = 6] = "FLOATS"; AttributeType3[AttributeType3["INTS"] = 7] = "INTS"; AttributeType3[AttributeType3["STRINGS"] = 8] = "STRINGS"; AttributeType3[AttributeType3["TENSORS"] = 9] = "TENSORS"; AttributeType3[AttributeType3["GRAPHS"] = 10] = "GRAPHS"; AttributeType3[AttributeType3["SPARSE_TENSOR"] = 11] = "SPARSE_TENSOR"; AttributeType3[AttributeType3["SPARSE_TENSORS"] = 12] = "SPARSE_TENSORS"; })(AttributeType2 || (exports2.AttributeType = AttributeType2 = {})); } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node-type.js var require_node_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node-type.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.NodeType = void 0; var NodeType2; (function(NodeType3) { NodeType3[NodeType3["Primitive"] = 0] = "Primitive"; NodeType3[NodeType3["Fused"] = 1] = "Fused"; })(NodeType2 || (exports2.NodeType = NodeType2 = {})); } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node.js var require_node = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Node = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var attribute_js_1 = require_attribute(); var node_type_js_1 = require_node_type(); var Node3 = class _Node { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsNode(bb, obj) { return (obj || new _Node()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsNode(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Node()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } name(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } docString(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } domain(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } sinceVersion() { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.readInt32(this.bb_pos + offset) : 0; } index() { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } opType(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } type() { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? this.bb.readInt32(this.bb_pos + offset) : node_type_js_1.NodeType.Primitive; } executionProviderType(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 18); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } inputs(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 20); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } inputsLength() { const offset = this.bb.__offset(this.bb_pos, 20); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } outputs(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 22); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } outputsLength() { const offset = this.bb.__offset(this.bb_pos, 22); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } attributes(index, obj) { const offset = this.bb.__offset(this.bb_pos, 24); return offset ? (obj || new attribute_js_1.Attribute()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } attributesLength() { const offset = this.bb.__offset(this.bb_pos, 24); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } inputArgCounts(index) { const offset = this.bb.__offset(this.bb_pos, 26); return offset ? this.bb.readInt32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; } inputArgCountsLength() { const offset = this.bb.__offset(this.bb_pos, 26); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } inputArgCountsArray() { const offset = this.bb.__offset(this.bb_pos, 26); return offset ? new Int32Array( this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset) ) : null; } implicitInputs(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 28); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } implicitInputsLength() { const offset = this.bb.__offset(this.bb_pos, 28); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startNode(builder) { builder.startObject(13); } static addName(builder, nameOffset) { builder.addFieldOffset(0, nameOffset, 0); } static addDocString(builder, docStringOffset) { builder.addFieldOffset(1, docStringOffset, 0); } static addDomain(builder, domainOffset) { builder.addFieldOffset(2, domainOffset, 0); } static addSinceVersion(builder, sinceVersion) { builder.addFieldInt32(3, sinceVersion, 0); } static addIndex(builder, index) { builder.addFieldInt32(4, index, 0); } static addOpType(builder, opTypeOffset) { builder.addFieldOffset(5, opTypeOffset, 0); } static addType(builder, type) { builder.addFieldInt32(6, type, node_type_js_1.NodeType.Primitive); } static addExecutionProviderType(builder, executionProviderTypeOffset) { builder.addFieldOffset(7, executionProviderTypeOffset, 0); } static addInputs(builder, inputsOffset) { builder.addFieldOffset(8, inputsOffset, 0); } static createInputsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startInputsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addOutputs(builder, outputsOffset) { builder.addFieldOffset(9, outputsOffset, 0); } static createOutputsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startOutputsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addAttributes(builder, attributesOffset) { builder.addFieldOffset(10, attributesOffset, 0); } static createAttributesVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startAttributesVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addInputArgCounts(builder, inputArgCountsOffset) { builder.addFieldOffset(11, inputArgCountsOffset, 0); } static createInputArgCountsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); } return builder.endVector(); } static startInputArgCountsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addImplicitInputs(builder, implicitInputsOffset) { builder.addFieldOffset(12, implicitInputsOffset, 0); } static createImplicitInputsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startImplicitInputsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endNode(builder) { const offset = builder.endObject(); return offset; } static createNode(builder, nameOffset, docStringOffset, domainOffset, sinceVersion, index, opTypeOffset, type, executionProviderTypeOffset, inputsOffset, outputsOffset, attributesOffset, inputArgCountsOffset, implicitInputsOffset) { _Node.startNode(builder); _Node.addName(builder, nameOffset); _Node.addDocString(builder, docStringOffset); _Node.addDomain(builder, domainOffset); _Node.addSinceVersion(builder, sinceVersion); _Node.addIndex(builder, index); _Node.addOpType(builder, opTypeOffset); _Node.addType(builder, type); _Node.addExecutionProviderType(builder, executionProviderTypeOffset); _Node.addInputs(builder, inputsOffset); _Node.addOutputs(builder, outputsOffset); _Node.addAttributes(builder, attributesOffset); _Node.addInputArgCounts(builder, inputArgCountsOffset); _Node.addImplicitInputs(builder, implicitInputsOffset); return _Node.endNode(builder); } }; exports2.Node = Node3; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/edge-end.js var require_edge_end = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/edge-end.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.EdgeEnd = void 0; var EdgeEnd2 = class { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } nodeIndex() { return this.bb.readUint32(this.bb_pos); } srcArgIndex() { return this.bb.readInt32(this.bb_pos + 4); } dstArgIndex() { return this.bb.readInt32(this.bb_pos + 8); } static sizeOf() { return 12; } static createEdgeEnd(builder, node_index, src_arg_index, dst_arg_index) { builder.prep(4, 12); builder.writeInt32(dst_arg_index); builder.writeInt32(src_arg_index); builder.writeInt32(node_index); return builder.offset(); } }; exports2.EdgeEnd = EdgeEnd2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node-edge.js var require_node_edge = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node-edge.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.NodeEdge = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var edge_end_js_1 = require_edge_end(); var NodeEdge2 = class _NodeEdge { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsNodeEdge(bb, obj) { return (obj || new _NodeEdge()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsNodeEdge(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _NodeEdge()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } nodeIndex() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } inputEdges(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new edge_end_js_1.EdgeEnd()).__init(this.bb.__vector(this.bb_pos + offset) + index * 12, this.bb) : null; } inputEdgesLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } outputEdges(index, obj) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? (obj || new edge_end_js_1.EdgeEnd()).__init(this.bb.__vector(this.bb_pos + offset) + index * 12, this.bb) : null; } outputEdgesLength() { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startNodeEdge(builder) { builder.startObject(3); } static addNodeIndex(builder, nodeIndex) { builder.addFieldInt32(0, nodeIndex, 0); } static addInputEdges(builder, inputEdgesOffset) { builder.addFieldOffset(1, inputEdgesOffset, 0); } static startInputEdgesVector(builder, numElems) { builder.startVector(12, numElems, 4); } static addOutputEdges(builder, outputEdgesOffset) { builder.addFieldOffset(2, outputEdgesOffset, 0); } static startOutputEdgesVector(builder, numElems) { builder.startVector(12, numElems, 4); } static endNodeEdge(builder) { const offset = builder.endObject(); return offset; } static createNodeEdge(builder, nodeIndex, inputEdgesOffset, outputEdgesOffset) { _NodeEdge.startNodeEdge(builder); _NodeEdge.addNodeIndex(builder, nodeIndex); _NodeEdge.addInputEdges(builder, inputEdgesOffset); _NodeEdge.addOutputEdges(builder, outputEdgesOffset); return _NodeEdge.endNodeEdge(builder); } }; exports2.NodeEdge = NodeEdge2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/nodes-to-optimize-indices.js var require_nodes_to_optimize_indices = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/nodes-to-optimize-indices.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.NodesToOptimizeIndices = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var NodesToOptimizeIndices2 = class _NodesToOptimizeIndices { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsNodesToOptimizeIndices(bb, obj) { return (obj || new _NodesToOptimizeIndices()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsNodesToOptimizeIndices(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _NodesToOptimizeIndices()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } nodeIndices(index) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readUint32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; } nodeIndicesLength() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } nodeIndicesArray() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? new Uint32Array( this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset) ) : null; } numInputs() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } numOutputs() { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } hasVariadicInput() { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false; } hasVariadicOutput() { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false; } numVariadicInputs() { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } numVariadicOutputs() { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } static startNodesToOptimizeIndices(builder) { builder.startObject(7); } static addNodeIndices(builder, nodeIndicesOffset) { builder.addFieldOffset(0, nodeIndicesOffset, 0); } static createNodeIndicesVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); } return builder.endVector(); } static startNodeIndicesVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addNumInputs(builder, numInputs) { builder.addFieldInt32(1, numInputs, 0); } static addNumOutputs(builder, numOutputs) { builder.addFieldInt32(2, numOutputs, 0); } static addHasVariadicInput(builder, hasVariadicInput) { builder.addFieldInt8(3, +hasVariadicInput, 0); } static addHasVariadicOutput(builder, hasVariadicOutput) { builder.addFieldInt8(4, +hasVariadicOutput, 0); } static addNumVariadicInputs(builder, numVariadicInputs) { builder.addFieldInt32(5, numVariadicInputs, 0); } static addNumVariadicOutputs(builder, numVariadicOutputs) { builder.addFieldInt32(6, numVariadicOutputs, 0); } static endNodesToOptimizeIndices(builder) { const offset = builder.endObject(); return offset; } static createNodesToOptimizeIndices(builder, nodeIndicesOffset, numInputs, numOutputs, hasVariadicInput, hasVariadicOutput, numVariadicInputs, numVariadicOutputs) { _NodesToOptimizeIndices.startNodesToOptimizeIndices(builder); _NodesToOptimizeIndices.addNodeIndices(builder, nodeIndicesOffset); _NodesToOptimizeIndices.addNumInputs(builder, numInputs); _NodesToOptimizeIndices.addNumOutputs(builder, numOutputs); _NodesToOptimizeIndices.addHasVariadicInput(builder, hasVariadicInput); _NodesToOptimizeIndices.addHasVariadicOutput(builder, hasVariadicOutput); _NodesToOptimizeIndices.addNumVariadicInputs(builder, numVariadicInputs); _NodesToOptimizeIndices.addNumVariadicOutputs(builder, numVariadicOutputs); return _NodesToOptimizeIndices.endNodesToOptimizeIndices(builder); } }; exports2.NodesToOptimizeIndices = NodesToOptimizeIndices2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimization-record.js var require_runtime_optimization_record = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimization-record.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.RuntimeOptimizationRecord = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var nodes_to_optimize_indices_js_1 = require_nodes_to_optimize_indices(); var RuntimeOptimizationRecord2 = class _RuntimeOptimizationRecord { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsRuntimeOptimizationRecord(bb, obj) { return (obj || new _RuntimeOptimizationRecord()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsRuntimeOptimizationRecord(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _RuntimeOptimizationRecord()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } actionId(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } nodesToOptimizeIndices(obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new nodes_to_optimize_indices_js_1.NodesToOptimizeIndices()).__init( this.bb.__indirect(this.bb_pos + offset), this.bb ) : null; } producedOpIds(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } producedOpIdsLength() { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startRuntimeOptimizationRecord(builder) { builder.startObject(4); } static addActionId(builder, actionIdOffset) { builder.addFieldOffset(0, actionIdOffset, 0); } static addNodesToOptimizeIndices(builder, nodesToOptimizeIndicesOffset) { builder.addFieldOffset(1, nodesToOptimizeIndicesOffset, 0); } static addProducedOpIds(builder, producedOpIdsOffset) { builder.addFieldOffset(3, producedOpIdsOffset, 0); } static createProducedOpIdsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startProducedOpIdsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endRuntimeOptimizationRecord(builder) { const offset = builder.endObject(); return offset; } }; exports2.RuntimeOptimizationRecord = RuntimeOptimizationRecord2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimization-record-container-entry.js var require_runtime_optimization_record_container_entry = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimization-record-container-entry.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.RuntimeOptimizationRecordContainerEntry = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var runtime_optimization_record_js_1 = require_runtime_optimization_record(); var RuntimeOptimizationRecordContainerEntry2 = class _RuntimeOptimizationRecordContainerEntry { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsRuntimeOptimizationRecordContainerEntry(bb, obj) { return (obj || new _RuntimeOptimizationRecordContainerEntry()).__init( bb.readInt32(bb.position()) + bb.position(), bb ); } static getSizePrefixedRootAsRuntimeOptimizationRecordContainerEntry(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _RuntimeOptimizationRecordContainerEntry()).__init( bb.readInt32(bb.position()) + bb.position(), bb ); } optimizerName(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } runtimeOptimizationRecords(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new runtime_optimization_record_js_1.RuntimeOptimizationRecord()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } runtimeOptimizationRecordsLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startRuntimeOptimizationRecordContainerEntry(builder) { builder.startObject(2); } static addOptimizerName(builder, optimizerNameOffset) { builder.addFieldOffset(0, optimizerNameOffset, 0); } static addRuntimeOptimizationRecords(builder, runtimeOptimizationRecordsOffset) { builder.addFieldOffset(1, runtimeOptimizationRecordsOffset, 0); } static createRuntimeOptimizationRecordsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startRuntimeOptimizationRecordsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endRuntimeOptimizationRecordContainerEntry(builder) { const offset = builder.endObject(); builder.requiredField(offset, 4); return offset; } static createRuntimeOptimizationRecordContainerEntry(builder, optimizerNameOffset, runtimeOptimizationRecordsOffset) { _RuntimeOptimizationRecordContainerEntry.startRuntimeOptimizationRecordContainerEntry(builder); _RuntimeOptimizationRecordContainerEntry.addOptimizerName(builder, optimizerNameOffset); _RuntimeOptimizationRecordContainerEntry.addRuntimeOptimizationRecords(builder, runtimeOptimizationRecordsOffset); return _RuntimeOptimizationRecordContainerEntry.endRuntimeOptimizationRecordContainerEntry(builder); } }; exports2.RuntimeOptimizationRecordContainerEntry = RuntimeOptimizationRecordContainerEntry2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimizations.js var require_runtime_optimizations = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimizations.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.RuntimeOptimizations = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var runtime_optimization_record_container_entry_js_1 = require_runtime_optimization_record_container_entry(); var RuntimeOptimizations2 = class _RuntimeOptimizations { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsRuntimeOptimizations(bb, obj) { return (obj || new _RuntimeOptimizations()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsRuntimeOptimizations(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _RuntimeOptimizations()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } /** * mapping from optimizer name to [RuntimeOptimizationRecord] */ records(index, obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new runtime_optimization_record_container_entry_js_1.RuntimeOptimizationRecordContainerEntry()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } recordsLength() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startRuntimeOptimizations(builder) { builder.startObject(1); } static addRecords(builder, recordsOffset) { builder.addFieldOffset(0, recordsOffset, 0); } static createRecordsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startRecordsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endRuntimeOptimizations(builder) { const offset = builder.endObject(); return offset; } static createRuntimeOptimizations(builder, recordsOffset) { _RuntimeOptimizations.startRuntimeOptimizations(builder); _RuntimeOptimizations.addRecords(builder, recordsOffset); return _RuntimeOptimizations.endRuntimeOptimizations(builder); } }; exports2.RuntimeOptimizations = RuntimeOptimizations2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor-data-type.js var require_tensor_data_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor-data-type.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.TensorDataType = void 0; var TensorDataType2; (function(TensorDataType3) { TensorDataType3[TensorDataType3["UNDEFINED"] = 0] = "UNDEFINED"; TensorDataType3[TensorDataType3["FLOAT"] = 1] = "FLOAT"; TensorDataType3[TensorDataType3["UINT8"] = 2] = "UINT8"; TensorDataType3[TensorDataType3["INT8"] = 3] = "INT8"; TensorDataType3[TensorDataType3["UINT16"] = 4] = "UINT16"; TensorDataType3[TensorDataType3["INT16"] = 5] = "INT16"; TensorDataType3[TensorDataType3["INT32"] = 6] = "INT32"; TensorDataType3[TensorDataType3["INT64"] = 7] = "INT64"; TensorDataType3[TensorDataType3["STRING"] = 8] = "STRING"; TensorDataType3[TensorDataType3["BOOL"] = 9] = "BOOL"; TensorDataType3[TensorDataType3["FLOAT16"] = 10] = "FLOAT16"; TensorDataType3[TensorDataType3["DOUBLE"] = 11] = "DOUBLE"; TensorDataType3[TensorDataType3["UINT32"] = 12] = "UINT32"; TensorDataType3[TensorDataType3["UINT64"] = 13] = "UINT64"; TensorDataType3[TensorDataType3["COMPLEX64"] = 14] = "COMPLEX64"; TensorDataType3[TensorDataType3["COMPLEX128"] = 15] = "COMPLEX128"; TensorDataType3[TensorDataType3["BFLOAT16"] = 16] = "BFLOAT16"; TensorDataType3[TensorDataType3["FLOAT8E4M3FN"] = 17] = "FLOAT8E4M3FN"; TensorDataType3[TensorDataType3["FLOAT8E4M3FNUZ"] = 18] = "FLOAT8E4M3FNUZ"; TensorDataType3[TensorDataType3["FLOAT8E5M2"] = 19] = "FLOAT8E5M2"; TensorDataType3[TensorDataType3["FLOAT8E5M2FNUZ"] = 20] = "FLOAT8E5M2FNUZ"; })(TensorDataType2 || (exports2.TensorDataType = TensorDataType2 = {})); } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor.js var require_tensor = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Tensor = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var tensor_data_type_js_1 = require_tensor_data_type(); var Tensor5 = class _Tensor { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsTensor(bb, obj) { return (obj || new _Tensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsTensor(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Tensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } name(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } docString(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } dims(index) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : BigInt(0); } dimsLength() { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } dataType() { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.readInt32(this.bb_pos + offset) : tensor_data_type_js_1.TensorDataType.UNDEFINED; } rawData(index) { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) : 0; } rawDataLength() { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } rawDataArray() { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? new Uint8Array( this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset) ) : null; } stringData(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } stringDataLength() { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } externalDataOffset() { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("-1"); } static startTensor(builder) { builder.startObject(7); } static addName(builder, nameOffset) { builder.addFieldOffset(0, nameOffset, 0); } static addDocString(builder, docStringOffset) { builder.addFieldOffset(1, docStringOffset, 0); } static addDims(builder, dimsOffset) { builder.addFieldOffset(2, dimsOffset, 0); } static createDimsVector(builder, data) { builder.startVector(8, data.length, 8); for (let i = data.length - 1; i >= 0; i--) { builder.addInt64(data[i]); } return builder.endVector(); } static startDimsVector(builder, numElems) { builder.startVector(8, numElems, 8); } static addDataType(builder, dataType) { builder.addFieldInt32(3, dataType, tensor_data_type_js_1.TensorDataType.UNDEFINED); } static addRawData(builder, rawDataOffset) { builder.addFieldOffset(4, rawDataOffset, 0); } static createRawDataVector(builder, data) { builder.startVector(1, data.length, 1); for (let i = data.length - 1; i >= 0; i--) { builder.addInt8(data[i]); } return builder.endVector(); } static startRawDataVector(builder, numElems) { builder.startVector(1, numElems, 1); } static addStringData(builder, stringDataOffset) { builder.addFieldOffset(5, stringDataOffset, 0); } static createStringDataVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startStringDataVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addExternalDataOffset(builder, externalDataOffset) { builder.addFieldInt64(6, externalDataOffset, BigInt("-1")); } static endTensor(builder) { const offset = builder.endObject(); return offset; } static createTensor(builder, nameOffset, docStringOffset, dimsOffset, dataType, rawDataOffset, stringDataOffset, externalDataOffset) { _Tensor.startTensor(builder); _Tensor.addName(builder, nameOffset); _Tensor.addDocString(builder, docStringOffset); _Tensor.addDims(builder, dimsOffset); _Tensor.addDataType(builder, dataType); _Tensor.addRawData(builder, rawDataOffset); _Tensor.addStringData(builder, stringDataOffset); _Tensor.addExternalDataOffset(builder, externalDataOffset); return _Tensor.endTensor(builder); } }; exports2.Tensor = Tensor5; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/sparse-tensor.js var require_sparse_tensor = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/sparse-tensor.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.SparseTensor = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var tensor_js_1 = require_tensor(); var SparseTensor2 = class _SparseTensor { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsSparseTensor(bb, obj) { return (obj || new _SparseTensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsSparseTensor(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _SparseTensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } values(obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new tensor_js_1.Tensor()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } indices(obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new tensor_js_1.Tensor()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } dims(index) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : BigInt(0); } dimsLength() { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startSparseTensor(builder) { builder.startObject(3); } static addValues(builder, valuesOffset) { builder.addFieldOffset(0, valuesOffset, 0); } static addIndices(builder, indicesOffset) { builder.addFieldOffset(1, indicesOffset, 0); } static addDims(builder, dimsOffset) { builder.addFieldOffset(2, dimsOffset, 0); } static createDimsVector(builder, data) { builder.startVector(8, data.length, 8); for (let i = data.length - 1; i >= 0; i--) { builder.addInt64(data[i]); } return builder.endVector(); } static startDimsVector(builder, numElems) { builder.startVector(8, numElems, 8); } static endSparseTensor(builder) { const offset = builder.endObject(); return offset; } }; exports2.SparseTensor = SparseTensor2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/map-type.js var require_map_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/map-type.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.MapType = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var tensor_data_type_js_1 = require_tensor_data_type(); var type_info_js_1 = require_type_info(); var MapType2 = class _MapType { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsMapType(bb, obj) { return (obj || new _MapType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsMapType(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _MapType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } keyType() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readInt32(this.bb_pos + offset) : tensor_data_type_js_1.TensorDataType.UNDEFINED; } valueType(obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new type_info_js_1.TypeInfo()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } static startMapType(builder) { builder.startObject(2); } static addKeyType(builder, keyType) { builder.addFieldInt32(0, keyType, tensor_data_type_js_1.TensorDataType.UNDEFINED); } static addValueType(builder, valueTypeOffset) { builder.addFieldOffset(1, valueTypeOffset, 0); } static endMapType(builder) { const offset = builder.endObject(); return offset; } }; exports2.MapType = MapType2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/sequence-type.js var require_sequence_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/sequence-type.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.SequenceType = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var type_info_js_1 = require_type_info(); var SequenceType2 = class _SequenceType { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsSequenceType(bb, obj) { return (obj || new _SequenceType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsSequenceType(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _SequenceType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } elemType(obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new type_info_js_1.TypeInfo()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } static startSequenceType(builder) { builder.startObject(1); } static addElemType(builder, elemTypeOffset) { builder.addFieldOffset(0, elemTypeOffset, 0); } static endSequenceType(builder) { const offset = builder.endObject(); return offset; } static createSequenceType(builder, elemTypeOffset) { _SequenceType.startSequenceType(builder); _SequenceType.addElemType(builder, elemTypeOffset); return _SequenceType.endSequenceType(builder); } }; exports2.SequenceType = SequenceType2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension-value-type.js var require_dimension_value_type = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension-value-type.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DimensionValueType = void 0; var DimensionValueType2; (function(DimensionValueType3) { DimensionValueType3[DimensionValueType3["UNKNOWN"] = 0] = "UNKNOWN"; DimensionValueType3[DimensionValueType3["VALUE"] = 1] = "VALUE"; DimensionValueType3[DimensionValueType3["PARAM"] = 2] = "PARAM"; })(DimensionValueType2 || (exports2.DimensionValueType = DimensionValueType2 = {})); } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension-value.js var require_dimension_value = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension-value.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DimensionValue = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var dimension_value_type_js_1 = require_dimension_value_type(); var DimensionValue2 = class _DimensionValue { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsDimensionValue(bb, obj) { return (obj || new _DimensionValue()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsDimensionValue(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _DimensionValue()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } dimType() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readInt8(this.bb_pos + offset) : dimension_value_type_js_1.DimensionValueType.UNKNOWN; } dimValue() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); } dimParam(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } static startDimensionValue(builder) { builder.startObject(3); } static addDimType(builder, dimType) { builder.addFieldInt8(0, dimType, dimension_value_type_js_1.DimensionValueType.UNKNOWN); } static addDimValue(builder, dimValue) { builder.addFieldInt64(1, dimValue, BigInt("0")); } static addDimParam(builder, dimParamOffset) { builder.addFieldOffset(2, dimParamOffset, 0); } static endDimensionValue(builder) { const offset = builder.endObject(); return offset; } static createDimensionValue(builder, dimType, dimValue, dimParamOffset) { _DimensionValue.startDimensionValue(builder); _DimensionValue.addDimType(builder, dimType); _DimensionValue.addDimValue(builder, dimValue); _DimensionValue.addDimParam(builder, dimParamOffset); return _DimensionValue.endDimensionValue(builder); } }; exports2.DimensionValue = DimensionValue2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension.js var require_dimension = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Dimension = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var dimension_value_js_1 = require_dimension_value(); var Dimension2 = class _Dimension { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsDimension(bb, obj) { return (obj || new _Dimension()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsDimension(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Dimension()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } value(obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new dimension_value_js_1.DimensionValue()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } denotation(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } static startDimension(builder) { builder.startObject(2); } static addValue(builder, valueOffset) { builder.addFieldOffset(0, valueOffset, 0); } static addDenotation(builder, denotationOffset) { builder.addFieldOffset(1, denotationOffset, 0); } static endDimension(builder) { const offset = builder.endObject(); return offset; } static createDimension(builder, valueOffset, denotationOffset) { _Dimension.startDimension(builder); _Dimension.addValue(builder, valueOffset); _Dimension.addDenotation(builder, denotationOffset); return _Dimension.endDimension(builder); } }; exports2.Dimension = Dimension2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/shape.js var require_shape = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/shape.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Shape = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var dimension_js_1 = require_dimension(); var Shape2 = class _Shape { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsShape(bb, obj) { return (obj || new _Shape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsShape(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Shape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } dim(index, obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new dimension_js_1.Dimension()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } dimLength() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startShape(builder) { builder.startObject(1); } static addDim(builder, dimOffset) { builder.addFieldOffset(0, dimOffset, 0); } static createDimVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startDimVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endShape(builder) { const offset = builder.endObject(); return offset; } static createShape(builder, dimOffset) { _Shape.startShape(builder); _Shape.addDim(builder, dimOffset); return _Shape.endShape(builder); } }; exports2.Shape = Shape2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor-type-and-shape.js var require_tensor_type_and_shape = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor-type-and-shape.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.TensorTypeAndShape = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var shape_js_1 = require_shape(); var tensor_data_type_js_1 = require_tensor_data_type(); var TensorTypeAndShape2 = class _TensorTypeAndShape { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsTensorTypeAndShape(bb, obj) { return (obj || new _TensorTypeAndShape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsTensorTypeAndShape(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _TensorTypeAndShape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } elemType() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readInt32(this.bb_pos + offset) : tensor_data_type_js_1.TensorDataType.UNDEFINED; } shape(obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new shape_js_1.Shape()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } static startTensorTypeAndShape(builder) { builder.startObject(2); } static addElemType(builder, elemType) { builder.addFieldInt32(0, elemType, tensor_data_type_js_1.TensorDataType.UNDEFINED); } static addShape(builder, shapeOffset) { builder.addFieldOffset(1, shapeOffset, 0); } static endTensorTypeAndShape(builder) { const offset = builder.endObject(); return offset; } }; exports2.TensorTypeAndShape = TensorTypeAndShape2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/type-info-value.js var require_type_info_value = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/type-info-value.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.unionListToTypeInfoValue = exports2.unionToTypeInfoValue = exports2.TypeInfoValue = void 0; var map_type_js_1 = require_map_type(); var sequence_type_js_1 = require_sequence_type(); var tensor_type_and_shape_js_1 = require_tensor_type_and_shape(); var TypeInfoValue2; (function(TypeInfoValue3) { TypeInfoValue3[TypeInfoValue3["NONE"] = 0] = "NONE"; TypeInfoValue3[TypeInfoValue3["tensor_type"] = 1] = "tensor_type"; TypeInfoValue3[TypeInfoValue3["sequence_type"] = 2] = "sequence_type"; TypeInfoValue3[TypeInfoValue3["map_type"] = 3] = "map_type"; })(TypeInfoValue2 || (exports2.TypeInfoValue = TypeInfoValue2 = {})); function unionToTypeInfoValue(type, accessor) { switch (TypeInfoValue2[type]) { case "NONE": return null; case "tensor_type": return accessor(new tensor_type_and_shape_js_1.TensorTypeAndShape()); case "sequence_type": return accessor(new sequence_type_js_1.SequenceType()); case "map_type": return accessor(new map_type_js_1.MapType()); default: return null; } } exports2.unionToTypeInfoValue = unionToTypeInfoValue; function unionListToTypeInfoValue(type, accessor, index) { switch (TypeInfoValue2[type]) { case "NONE": return null; case "tensor_type": return accessor(index, new tensor_type_and_shape_js_1.TensorTypeAndShape()); case "sequence_type": return accessor(index, new sequence_type_js_1.SequenceType()); case "map_type": return accessor(index, new map_type_js_1.MapType()); default: return null; } } exports2.unionListToTypeInfoValue = unionListToTypeInfoValue; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/type-info.js var require_type_info = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/type-info.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.TypeInfo = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var type_info_value_js_1 = require_type_info_value(); var TypeInfo2 = class _TypeInfo { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsTypeInfo(bb, obj) { return (obj || new _TypeInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsTypeInfo(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _TypeInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } denotation(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } valueType() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readUint8(this.bb_pos + offset) : type_info_value_js_1.TypeInfoValue.NONE; } value(obj) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__union(obj, this.bb_pos + offset) : null; } static startTypeInfo(builder) { builder.startObject(3); } static addDenotation(builder, denotationOffset) { builder.addFieldOffset(0, denotationOffset, 0); } static addValueType(builder, valueType) { builder.addFieldInt8(1, valueType, type_info_value_js_1.TypeInfoValue.NONE); } static addValue(builder, valueOffset) { builder.addFieldOffset(2, valueOffset, 0); } static endTypeInfo(builder) { const offset = builder.endObject(); return offset; } static createTypeInfo(builder, denotationOffset, valueType, valueOffset) { _TypeInfo.startTypeInfo(builder); _TypeInfo.addDenotation(builder, denotationOffset); _TypeInfo.addValueType(builder, valueType); _TypeInfo.addValue(builder, valueOffset); return _TypeInfo.endTypeInfo(builder); } }; exports2.TypeInfo = TypeInfo2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/value-info.js var require_value_info = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/value-info.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.ValueInfo = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var type_info_js_1 = require_type_info(); var ValueInfo2 = class _ValueInfo { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsValueInfo(bb, obj) { return (obj || new _ValueInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsValueInfo(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _ValueInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } name(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } docString(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } type(obj) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? (obj || new type_info_js_1.TypeInfo()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } static startValueInfo(builder) { builder.startObject(3); } static addName(builder, nameOffset) { builder.addFieldOffset(0, nameOffset, 0); } static addDocString(builder, docStringOffset) { builder.addFieldOffset(1, docStringOffset, 0); } static addType(builder, typeOffset) { builder.addFieldOffset(2, typeOffset, 0); } static endValueInfo(builder) { const offset = builder.endObject(); return offset; } }; exports2.ValueInfo = ValueInfo2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/graph.js var require_graph = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/graph.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Graph = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var node_js_1 = require_node(); var node_edge_js_1 = require_node_edge(); var runtime_optimizations_js_1 = require_runtime_optimizations(); var sparse_tensor_js_1 = require_sparse_tensor(); var tensor_js_1 = require_tensor(); var value_info_js_1 = require_value_info(); var Graph3 = class _Graph { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsGraph(bb, obj) { return (obj || new _Graph()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsGraph(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Graph()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } initializers(index, obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new tensor_js_1.Tensor()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } initializersLength() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } nodeArgs(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new value_info_js_1.ValueInfo()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } nodeArgsLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } nodes(index, obj) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? (obj || new node_js_1.Node()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } nodesLength() { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } maxNodeIndex() { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } nodeEdges(index, obj) { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? (obj || new node_edge_js_1.NodeEdge()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } nodeEdgesLength() { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } inputs(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } inputsLength() { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } outputs(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } outputsLength() { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } sparseInitializers(index, obj) { const offset = this.bb.__offset(this.bb_pos, 18); return offset ? (obj || new sparse_tensor_js_1.SparseTensor()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } sparseInitializersLength() { const offset = this.bb.__offset(this.bb_pos, 18); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } runtimeOptimizations(obj) { const offset = this.bb.__offset(this.bb_pos, 20); return offset ? (obj || new runtime_optimizations_js_1.RuntimeOptimizations()).__init( this.bb.__indirect(this.bb_pos + offset), this.bb ) : null; } static startGraph(builder) { builder.startObject(9); } static addInitializers(builder, initializersOffset) { builder.addFieldOffset(0, initializersOffset, 0); } static createInitializersVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startInitializersVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addNodeArgs(builder, nodeArgsOffset) { builder.addFieldOffset(1, nodeArgsOffset, 0); } static createNodeArgsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startNodeArgsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addNodes(builder, nodesOffset) { builder.addFieldOffset(2, nodesOffset, 0); } static createNodesVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startNodesVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addMaxNodeIndex(builder, maxNodeIndex) { builder.addFieldInt32(3, maxNodeIndex, 0); } static addNodeEdges(builder, nodeEdgesOffset) { builder.addFieldOffset(4, nodeEdgesOffset, 0); } static createNodeEdgesVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startNodeEdgesVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addInputs(builder, inputsOffset) { builder.addFieldOffset(5, inputsOffset, 0); } static createInputsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startInputsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addOutputs(builder, outputsOffset) { builder.addFieldOffset(6, outputsOffset, 0); } static createOutputsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startOutputsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addSparseInitializers(builder, sparseInitializersOffset) { builder.addFieldOffset(7, sparseInitializersOffset, 0); } static createSparseInitializersVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startSparseInitializersVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addRuntimeOptimizations(builder, runtimeOptimizationsOffset) { builder.addFieldOffset(8, runtimeOptimizationsOffset, 0); } static endGraph(builder) { const offset = builder.endObject(); return offset; } }; exports2.Graph = Graph3; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/attribute.js var require_attribute = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/attribute.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Attribute = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var attribute_type_js_1 = require_attribute_type(); var graph_js_1 = require_graph(); var tensor_js_1 = require_tensor(); var Attribute3 = class _Attribute { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsAttribute(bb, obj) { return (obj || new _Attribute()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsAttribute(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Attribute()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } name(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } docString(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } type() { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.readInt32(this.bb_pos + offset) : attribute_type_js_1.AttributeType.UNDEFINED; } f() { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.readFloat32(this.bb_pos + offset) : 0; } i() { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); } s(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } t(obj) { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? (obj || new tensor_js_1.Tensor()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } g(obj) { const offset = this.bb.__offset(this.bb_pos, 18); return offset ? (obj || new graph_js_1.Graph()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } floats(index) { const offset = this.bb.__offset(this.bb_pos, 20); return offset ? this.bb.readFloat32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; } floatsLength() { const offset = this.bb.__offset(this.bb_pos, 20); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } floatsArray() { const offset = this.bb.__offset(this.bb_pos, 20); return offset ? new Float32Array( this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset) ) : null; } ints(index) { const offset = this.bb.__offset(this.bb_pos, 22); return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : BigInt(0); } intsLength() { const offset = this.bb.__offset(this.bb_pos, 22); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } strings(index, optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 24); return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; } stringsLength() { const offset = this.bb.__offset(this.bb_pos, 24); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } tensors(index, obj) { const offset = this.bb.__offset(this.bb_pos, 26); return offset ? (obj || new tensor_js_1.Tensor()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } tensorsLength() { const offset = this.bb.__offset(this.bb_pos, 26); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } graphs(index, obj) { const offset = this.bb.__offset(this.bb_pos, 28); return offset ? (obj || new graph_js_1.Graph()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } graphsLength() { const offset = this.bb.__offset(this.bb_pos, 28); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startAttribute(builder) { builder.startObject(13); } static addName(builder, nameOffset) { builder.addFieldOffset(0, nameOffset, 0); } static addDocString(builder, docStringOffset) { builder.addFieldOffset(1, docStringOffset, 0); } static addType(builder, type) { builder.addFieldInt32(2, type, attribute_type_js_1.AttributeType.UNDEFINED); } static addF(builder, f) { builder.addFieldFloat32(3, f, 0); } static addI(builder, i) { builder.addFieldInt64(4, i, BigInt("0")); } static addS(builder, sOffset) { builder.addFieldOffset(5, sOffset, 0); } static addT(builder, tOffset) { builder.addFieldOffset(6, tOffset, 0); } static addG(builder, gOffset) { builder.addFieldOffset(7, gOffset, 0); } static addFloats(builder, floatsOffset) { builder.addFieldOffset(8, floatsOffset, 0); } static createFloatsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addFloat32(data[i]); } return builder.endVector(); } static startFloatsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addInts(builder, intsOffset) { builder.addFieldOffset(9, intsOffset, 0); } static createIntsVector(builder, data) { builder.startVector(8, data.length, 8); for (let i = data.length - 1; i >= 0; i--) { builder.addInt64(data[i]); } return builder.endVector(); } static startIntsVector(builder, numElems) { builder.startVector(8, numElems, 8); } static addStrings(builder, stringsOffset) { builder.addFieldOffset(10, stringsOffset, 0); } static createStringsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startStringsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addTensors(builder, tensorsOffset) { builder.addFieldOffset(11, tensorsOffset, 0); } static createTensorsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startTensorsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addGraphs(builder, graphsOffset) { builder.addFieldOffset(12, graphsOffset, 0); } static createGraphsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startGraphsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endAttribute(builder) { const offset = builder.endObject(); return offset; } }; exports2.Attribute = Attribute3; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-kernel-create-infos.js var require_deprecated_kernel_create_infos = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-kernel-create-infos.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DeprecatedKernelCreateInfos = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var DeprecatedKernelCreateInfos2 = class _DeprecatedKernelCreateInfos { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsDeprecatedKernelCreateInfos(bb, obj) { return (obj || new _DeprecatedKernelCreateInfos()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsDeprecatedKernelCreateInfos(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _DeprecatedKernelCreateInfos()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } nodeIndices(index) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readUint32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; } nodeIndicesLength() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } nodeIndicesArray() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? new Uint32Array( this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset) ) : null; } kernelDefHashes(index) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readUint64(this.bb.__vector(this.bb_pos + offset) + index * 8) : BigInt(0); } kernelDefHashesLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startDeprecatedKernelCreateInfos(builder) { builder.startObject(2); } static addNodeIndices(builder, nodeIndicesOffset) { builder.addFieldOffset(0, nodeIndicesOffset, 0); } static createNodeIndicesVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addInt32(data[i]); } return builder.endVector(); } static startNodeIndicesVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addKernelDefHashes(builder, kernelDefHashesOffset) { builder.addFieldOffset(1, kernelDefHashesOffset, 0); } static createKernelDefHashesVector(builder, data) { builder.startVector(8, data.length, 8); for (let i = data.length - 1; i >= 0; i--) { builder.addInt64(data[i]); } return builder.endVector(); } static startKernelDefHashesVector(builder, numElems) { builder.startVector(8, numElems, 8); } static endDeprecatedKernelCreateInfos(builder) { const offset = builder.endObject(); return offset; } static createDeprecatedKernelCreateInfos(builder, nodeIndicesOffset, kernelDefHashesOffset) { _DeprecatedKernelCreateInfos.startDeprecatedKernelCreateInfos(builder); _DeprecatedKernelCreateInfos.addNodeIndices(builder, nodeIndicesOffset); _DeprecatedKernelCreateInfos.addKernelDefHashes(builder, kernelDefHashesOffset); return _DeprecatedKernelCreateInfos.endDeprecatedKernelCreateInfos(builder); } }; exports2.DeprecatedKernelCreateInfos = DeprecatedKernelCreateInfos2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-node-index-and-kernel-def-hash.js var require_deprecated_node_index_and_kernel_def_hash = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-node-index-and-kernel-def-hash.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DeprecatedNodeIndexAndKernelDefHash = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var DeprecatedNodeIndexAndKernelDefHash2 = class _DeprecatedNodeIndexAndKernelDefHash { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsDeprecatedNodeIndexAndKernelDefHash(bb, obj) { return (obj || new _DeprecatedNodeIndexAndKernelDefHash()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsDeprecatedNodeIndexAndKernelDefHash(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _DeprecatedNodeIndexAndKernelDefHash()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } nodeIndex() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; } kernelDefHash() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readUint64(this.bb_pos + offset) : BigInt("0"); } static startDeprecatedNodeIndexAndKernelDefHash(builder) { builder.startObject(2); } static addNodeIndex(builder, nodeIndex) { builder.addFieldInt32(0, nodeIndex, 0); } static addKernelDefHash(builder, kernelDefHash) { builder.addFieldInt64(1, kernelDefHash, BigInt("0")); } static endDeprecatedNodeIndexAndKernelDefHash(builder) { const offset = builder.endObject(); return offset; } static createDeprecatedNodeIndexAndKernelDefHash(builder, nodeIndex, kernelDefHash) { _DeprecatedNodeIndexAndKernelDefHash.startDeprecatedNodeIndexAndKernelDefHash(builder); _DeprecatedNodeIndexAndKernelDefHash.addNodeIndex(builder, nodeIndex); _DeprecatedNodeIndexAndKernelDefHash.addKernelDefHash(builder, kernelDefHash); return _DeprecatedNodeIndexAndKernelDefHash.endDeprecatedNodeIndexAndKernelDefHash(builder); } }; exports2.DeprecatedNodeIndexAndKernelDefHash = DeprecatedNodeIndexAndKernelDefHash2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-sub-graph-session-state.js var require_deprecated_sub_graph_session_state = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-sub-graph-session-state.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DeprecatedSubGraphSessionState = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var deprecated_session_state_js_1 = require_deprecated_session_state(); var DeprecatedSubGraphSessionState2 = class _DeprecatedSubGraphSessionState { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsDeprecatedSubGraphSessionState(bb, obj) { return (obj || new _DeprecatedSubGraphSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsDeprecatedSubGraphSessionState(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _DeprecatedSubGraphSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } graphId(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } sessionState(obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new deprecated_session_state_js_1.DeprecatedSessionState()).__init( this.bb.__indirect(this.bb_pos + offset), this.bb ) : null; } static startDeprecatedSubGraphSessionState(builder) { builder.startObject(2); } static addGraphId(builder, graphIdOffset) { builder.addFieldOffset(0, graphIdOffset, 0); } static addSessionState(builder, sessionStateOffset) { builder.addFieldOffset(1, sessionStateOffset, 0); } static endDeprecatedSubGraphSessionState(builder) { const offset = builder.endObject(); builder.requiredField(offset, 4); return offset; } }; exports2.DeprecatedSubGraphSessionState = DeprecatedSubGraphSessionState2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-session-state.js var require_deprecated_session_state = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-session-state.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.DeprecatedSessionState = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var deprecated_kernel_create_infos_js_1 = require_deprecated_kernel_create_infos(); var deprecated_sub_graph_session_state_js_1 = require_deprecated_sub_graph_session_state(); var DeprecatedSessionState2 = class _DeprecatedSessionState { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsDeprecatedSessionState(bb, obj) { return (obj || new _DeprecatedSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsDeprecatedSessionState(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _DeprecatedSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } kernels(obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new deprecated_kernel_create_infos_js_1.DeprecatedKernelCreateInfos()).__init( this.bb.__indirect(this.bb_pos + offset), this.bb ) : null; } subGraphSessionStates(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new deprecated_sub_graph_session_state_js_1.DeprecatedSubGraphSessionState()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } subGraphSessionStatesLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startDeprecatedSessionState(builder) { builder.startObject(2); } static addKernels(builder, kernelsOffset) { builder.addFieldOffset(0, kernelsOffset, 0); } static addSubGraphSessionStates(builder, subGraphSessionStatesOffset) { builder.addFieldOffset(1, subGraphSessionStatesOffset, 0); } static createSubGraphSessionStatesVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startSubGraphSessionStatesVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endDeprecatedSessionState(builder) { const offset = builder.endObject(); return offset; } static createDeprecatedSessionState(builder, kernelsOffset, subGraphSessionStatesOffset) { _DeprecatedSessionState.startDeprecatedSessionState(builder); _DeprecatedSessionState.addKernels(builder, kernelsOffset); _DeprecatedSessionState.addSubGraphSessionStates(builder, subGraphSessionStatesOffset); return _DeprecatedSessionState.endDeprecatedSessionState(builder); } }; exports2.DeprecatedSessionState = DeprecatedSessionState2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/kernel-type-str-args-entry.js var require_kernel_type_str_args_entry = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/kernel-type-str-args-entry.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.KernelTypeStrArgsEntry = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var arg_type_and_index_js_1 = require_arg_type_and_index(); var KernelTypeStrArgsEntry2 = class _KernelTypeStrArgsEntry { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsKernelTypeStrArgsEntry(bb, obj) { return (obj || new _KernelTypeStrArgsEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsKernelTypeStrArgsEntry(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _KernelTypeStrArgsEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } kernelTypeStr(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } args(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new arg_type_and_index_js_1.ArgTypeAndIndex()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } argsLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startKernelTypeStrArgsEntry(builder) { builder.startObject(2); } static addKernelTypeStr(builder, kernelTypeStrOffset) { builder.addFieldOffset(0, kernelTypeStrOffset, 0); } static addArgs(builder, argsOffset) { builder.addFieldOffset(1, argsOffset, 0); } static createArgsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startArgsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endKernelTypeStrArgsEntry(builder) { const offset = builder.endObject(); builder.requiredField(offset, 4); return offset; } static createKernelTypeStrArgsEntry(builder, kernelTypeStrOffset, argsOffset) { _KernelTypeStrArgsEntry.startKernelTypeStrArgsEntry(builder); _KernelTypeStrArgsEntry.addKernelTypeStr(builder, kernelTypeStrOffset); _KernelTypeStrArgsEntry.addArgs(builder, argsOffset); return _KernelTypeStrArgsEntry.endKernelTypeStrArgsEntry(builder); } }; exports2.KernelTypeStrArgsEntry = KernelTypeStrArgsEntry2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/op-id-kernel-type-str-args-entry.js var require_op_id_kernel_type_str_args_entry = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/op-id-kernel-type-str-args-entry.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.OpIdKernelTypeStrArgsEntry = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var kernel_type_str_args_entry_js_1 = require_kernel_type_str_args_entry(); var OpIdKernelTypeStrArgsEntry2 = class _OpIdKernelTypeStrArgsEntry { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsOpIdKernelTypeStrArgsEntry(bb, obj) { return (obj || new _OpIdKernelTypeStrArgsEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsOpIdKernelTypeStrArgsEntry(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _OpIdKernelTypeStrArgsEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } opId(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } kernelTypeStrArgs(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new kernel_type_str_args_entry_js_1.KernelTypeStrArgsEntry()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } kernelTypeStrArgsLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startOpIdKernelTypeStrArgsEntry(builder) { builder.startObject(2); } static addOpId(builder, opIdOffset) { builder.addFieldOffset(0, opIdOffset, 0); } static addKernelTypeStrArgs(builder, kernelTypeStrArgsOffset) { builder.addFieldOffset(1, kernelTypeStrArgsOffset, 0); } static createKernelTypeStrArgsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startKernelTypeStrArgsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endOpIdKernelTypeStrArgsEntry(builder) { const offset = builder.endObject(); builder.requiredField(offset, 4); return offset; } static createOpIdKernelTypeStrArgsEntry(builder, opIdOffset, kernelTypeStrArgsOffset) { _OpIdKernelTypeStrArgsEntry.startOpIdKernelTypeStrArgsEntry(builder); _OpIdKernelTypeStrArgsEntry.addOpId(builder, opIdOffset); _OpIdKernelTypeStrArgsEntry.addKernelTypeStrArgs(builder, kernelTypeStrArgsOffset); return _OpIdKernelTypeStrArgsEntry.endOpIdKernelTypeStrArgsEntry(builder); } }; exports2.OpIdKernelTypeStrArgsEntry = OpIdKernelTypeStrArgsEntry2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/kernel-type-str-resolver.js var require_kernel_type_str_resolver = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/kernel-type-str-resolver.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.KernelTypeStrResolver = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var op_id_kernel_type_str_args_entry_js_1 = require_op_id_kernel_type_str_args_entry(); var KernelTypeStrResolver2 = class _KernelTypeStrResolver { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsKernelTypeStrResolver(bb, obj) { return (obj || new _KernelTypeStrResolver()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsKernelTypeStrResolver(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _KernelTypeStrResolver()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } opKernelTypeStrArgs(index, obj) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? (obj || new op_id_kernel_type_str_args_entry_js_1.OpIdKernelTypeStrArgsEntry()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } opKernelTypeStrArgsLength() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startKernelTypeStrResolver(builder) { builder.startObject(1); } static addOpKernelTypeStrArgs(builder, opKernelTypeStrArgsOffset) { builder.addFieldOffset(0, opKernelTypeStrArgsOffset, 0); } static createOpKernelTypeStrArgsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startOpKernelTypeStrArgsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endKernelTypeStrResolver(builder) { const offset = builder.endObject(); return offset; } static createKernelTypeStrResolver(builder, opKernelTypeStrArgsOffset) { _KernelTypeStrResolver.startKernelTypeStrResolver(builder); _KernelTypeStrResolver.addOpKernelTypeStrArgs(builder, opKernelTypeStrArgsOffset); return _KernelTypeStrResolver.endKernelTypeStrResolver(builder); } }; exports2.KernelTypeStrResolver = KernelTypeStrResolver2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/operator-set-id.js var require_operator_set_id = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/operator-set-id.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.OperatorSetId = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var OperatorSetId2 = class _OperatorSetId { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsOperatorSetId(bb, obj) { return (obj || new _OperatorSetId()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsOperatorSetId(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _OperatorSetId()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } domain(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } version() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); } static startOperatorSetId(builder) { builder.startObject(2); } static addDomain(builder, domainOffset) { builder.addFieldOffset(0, domainOffset, 0); } static addVersion(builder, version3) { builder.addFieldInt64(1, version3, BigInt("0")); } static endOperatorSetId(builder) { const offset = builder.endObject(); return offset; } static createOperatorSetId(builder, domainOffset, version3) { _OperatorSetId.startOperatorSetId(builder); _OperatorSetId.addDomain(builder, domainOffset); _OperatorSetId.addVersion(builder, version3); return _OperatorSetId.endOperatorSetId(builder); } }; exports2.OperatorSetId = OperatorSetId2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/string-string-entry.js var require_string_string_entry = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/string-string-entry.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.StringStringEntry = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var StringStringEntry2 = class _StringStringEntry { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsStringStringEntry(bb, obj) { return (obj || new _StringStringEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsStringStringEntry(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _StringStringEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } key(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } value(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } static startStringStringEntry(builder) { builder.startObject(2); } static addKey(builder, keyOffset) { builder.addFieldOffset(0, keyOffset, 0); } static addValue(builder, valueOffset) { builder.addFieldOffset(1, valueOffset, 0); } static endStringStringEntry(builder) { const offset = builder.endObject(); return offset; } static createStringStringEntry(builder, keyOffset, valueOffset) { _StringStringEntry.startStringStringEntry(builder); _StringStringEntry.addKey(builder, keyOffset); _StringStringEntry.addValue(builder, valueOffset); return _StringStringEntry.endStringStringEntry(builder); } }; exports2.StringStringEntry = StringStringEntry2; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/model.js var require_model = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/model.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Model = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var graph_js_1 = require_graph(); var operator_set_id_js_1 = require_operator_set_id(); var string_string_entry_js_1 = require_string_string_entry(); var Model3 = class _Model { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsModel(bb, obj) { return (obj || new _Model()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsModel(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _Model()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } irVersion() { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); } opsetImport(index, obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new operator_set_id_js_1.OperatorSetId()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } opsetImportLength() { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } producerName(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 8); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } producerVersion(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } domain(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 12); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } modelVersion() { const offset = this.bb.__offset(this.bb_pos, 14); return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); } docString(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 16); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } graph(obj) { const offset = this.bb.__offset(this.bb_pos, 18); return offset ? (obj || new graph_js_1.Graph()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } graphDocString(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 20); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } metadataProps(index, obj) { const offset = this.bb.__offset(this.bb_pos, 22); return offset ? (obj || new string_string_entry_js_1.StringStringEntry()).__init( this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb ) : null; } metadataPropsLength() { const offset = this.bb.__offset(this.bb_pos, 22); return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; } static startModel(builder) { builder.startObject(10); } static addIrVersion(builder, irVersion) { builder.addFieldInt64(0, irVersion, BigInt("0")); } static addOpsetImport(builder, opsetImportOffset) { builder.addFieldOffset(1, opsetImportOffset, 0); } static createOpsetImportVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startOpsetImportVector(builder, numElems) { builder.startVector(4, numElems, 4); } static addProducerName(builder, producerNameOffset) { builder.addFieldOffset(2, producerNameOffset, 0); } static addProducerVersion(builder, producerVersionOffset) { builder.addFieldOffset(3, producerVersionOffset, 0); } static addDomain(builder, domainOffset) { builder.addFieldOffset(4, domainOffset, 0); } static addModelVersion(builder, modelVersion) { builder.addFieldInt64(5, modelVersion, BigInt("0")); } static addDocString(builder, docStringOffset) { builder.addFieldOffset(6, docStringOffset, 0); } static addGraph(builder, graphOffset) { builder.addFieldOffset(7, graphOffset, 0); } static addGraphDocString(builder, graphDocStringOffset) { builder.addFieldOffset(8, graphDocStringOffset, 0); } static addMetadataProps(builder, metadataPropsOffset) { builder.addFieldOffset(9, metadataPropsOffset, 0); } static createMetadataPropsVector(builder, data) { builder.startVector(4, data.length, 4); for (let i = data.length - 1; i >= 0; i--) { builder.addOffset(data[i]); } return builder.endVector(); } static startMetadataPropsVector(builder, numElems) { builder.startVector(4, numElems, 4); } static endModel(builder) { const offset = builder.endObject(); return offset; } }; exports2.Model = Model3; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/inference-session.js var require_inference_session = __commonJS({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/inference-session.js"(exports2) { "use strict"; var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { if (k2 === void 0) 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 === void 0) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function(o, v) { o["default"] = v; }); var __importStar = exports2 && exports2.__importStar || function(mod2) { if (mod2 && mod2.__esModule) return mod2; var result = {}; if (mod2 != null) { for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); } __setModuleDefault(result, mod2); return result; }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.InferenceSession = void 0; var flatbuffers2 = __importStar(require_flatbuffers()); var kernel_type_str_resolver_js_1 = require_kernel_type_str_resolver(); var model_js_1 = require_model(); var InferenceSession5 = class _InferenceSession { constructor() { this.bb = null; this.bb_pos = 0; } __init(i, bb) { this.bb_pos = i; this.bb = bb; return this; } static getRootAsInferenceSession(bb, obj) { return (obj || new _InferenceSession()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static getSizePrefixedRootAsInferenceSession(bb, obj) { bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); return (obj || new _InferenceSession()).__init(bb.readInt32(bb.position()) + bb.position(), bb); } static bufferHasIdentifier(bb) { return bb.__has_identifier("ORTM"); } ortVersion(optionalEncoding) { const offset = this.bb.__offset(this.bb_pos, 4); return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; } model(obj) { const offset = this.bb.__offset(this.bb_pos, 6); return offset ? (obj || new model_js_1.Model()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; } kernelTypeStrResolver(obj) { const offset = this.bb.__offset(this.bb_pos, 10); return offset ? (obj || new kernel_type_str_resolver_js_1.KernelTypeStrResolver()).__init( this.bb.__indirect(this.bb_pos + offset), this.bb ) : null; } static startInferenceSession(builder) { builder.startObject(4); } static addOrtVersion(builder, ortVersionOffset) { builder.addFieldOffset(0, ortVersionOffset, 0); } static addModel(builder, modelOffset) { builder.addFieldOffset(1, modelOffset, 0); } static addKernelTypeStrResolver(builder, kernelTypeStrResolverOffset) { builder.addFieldOffset(3, kernelTypeStrResolverOffset, 0); } static endInferenceSession(builder) { const offset = builder.endObject(); return offset; } static finishInferenceSessionBuffer(builder, offset) { builder.finish(offset, "ORTM"); } static finishSizePrefixedInferenceSessionBuffer(builder, offset) { builder.finish(offset, "ORTM", true); } }; exports2.InferenceSession = InferenceSession5; } }); // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs.ts var import_arg_type, import_arg_type_and_index, import_attribute, import_attribute_type, import_deprecated_kernel_create_infos, import_deprecated_node_index_and_kernel_def_hash, import_deprecated_session_state, import_deprecated_sub_graph_session_state, import_dimension, import_dimension_value, import_dimension_value_type, import_edge_end, import_graph, import_inference_session, import_kernel_type_str_args_entry, import_kernel_type_str_resolver, import_map_type, import_model, import_node, import_node_edge, import_node_type, import_nodes_to_optimize_indices, import_op_id_kernel_type_str_args_entry, import_operator_set_id, import_runtime_optimization_record, import_runtime_optimization_record_container_entry, import_runtime_optimizations, import_sequence_type, import_shape, import_sparse_tensor, import_string_string_entry, import_tensor2, import_tensor_data_type, import_tensor_type_and_shape, import_type_info, import_type_info_value, import_value_info; var init_fbs = __esm({ "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs.ts"() { "use strict"; import_arg_type = __toESM(require_arg_type()); import_arg_type_and_index = __toESM(require_arg_type_and_index()); import_attribute = __toESM(require_attribute()); import_attribute_type = __toESM(require_attribute_type()); import_deprecated_kernel_create_infos = __toESM(require_deprecated_kernel_create_infos()); import_deprecated_node_index_and_kernel_def_hash = __toESM(require_deprecated_node_index_and_kernel_def_hash()); import_deprecated_session_state = __toESM(require_deprecated_session_state()); import_deprecated_sub_graph_session_state = __toESM(require_deprecated_sub_graph_session_state()); import_dimension = __toESM(require_dimension()); import_dimension_value = __toESM(require_dimension_value()); import_dimension_value_type = __toESM(require_dimension_value_type()); import_edge_end = __toESM(require_edge_end()); import_graph = __toESM(require_graph()); import_inference_session = __toESM(require_inference_session()); import_kernel_type_str_args_entry = __toESM(require_kernel_type_str_args_entry()); import_kernel_type_str_resolver = __toESM(require_kernel_type_str_resolver()); import_map_type = __toESM(require_map_type()); import_model = __toESM(require_model()); import_node = __toESM(require_node()); import_node_edge = __toESM(require_node_edge()); import_node_type = __toESM(require_node_type()); import_nodes_to_optimize_indices = __toESM(require_nodes_to_optimize_indices()); import_op_id_kernel_type_str_args_entry = __toESM(require_op_id_kernel_type_str_args_entry()); import_operator_set_id = __toESM(require_operator_set_id()); import_runtime_optimization_record = __toESM(require_runtime_optimization_record()); import_runtime_optimization_record_container_entry = __toESM(require_runtime_optimization_record_container_entry()); import_runtime_optimizations = __toESM(require_runtime_optimizations()); import_sequence_type = __toESM(require_sequence_type()); import_shape = __toESM(require_shape()); import_sparse_tensor = __toESM(require_sparse_tensor()); import_string_string_entry = __toESM(require_string_string_entry()); import_tensor2 = __toESM(require_tensor()); import_tensor_data_type = __toESM(require_tensor_data_type()); import_tensor_type_and_shape = __toESM(require_tensor_type_and_shape()); import_type_info = __toESM(require_type_info()); import_type_info_value = __toESM(require_type_info_value()); import_value_info = __toESM(require_value_info()); } }); // web/lib/onnxjs/ort-schema/flatbuffers/ort-generated.ts var init_ort_generated = __esm({ "web/lib/onnxjs/ort-schema/flatbuffers/ort-generated.ts"() { "use strict"; init_fbs(); } }); // web/node_modules/@protobufjs/aspromise/index.js var require_aspromise = __commonJS({ "web/node_modules/@protobufjs/aspromise/index.js"(exports2, module2) { "use strict"; module2.exports = asPromise; function asPromise(fn, ctx) { var params = new Array(arguments.length - 1), offset = 0, index = 2, pending = true; while (index < arguments.length) params[offset++] = arguments[index++]; return new Promise(function executor(resolve, reject) { params[offset] = function callback(err) { if (pending) { pending = false; if (err) reject(err); else { var params2 = new Array(arguments.length - 1), offset2 = 0; while (offset2 < params2.length) params2[offset2++] = arguments[offset2]; resolve.apply(null, params2); } } }; try { fn.apply(ctx || null, params); } catch (err) { if (pending) { pending = false; reject(err); } } }); } } }); // web/node_modules/@protobufjs/base64/index.js var require_base64 = __commonJS({ "web/node_modules/@protobufjs/base64/index.js"(exports2) { "use strict"; var base64 = exports2; base64.length = function length(string) { var p = string.length; if (!p) return 0; var n = 0; while (--p % 4 > 1 && string.charAt(p) === "=") ++n; return Math.ceil(string.length * 3) / 4 - n; }; var b64 = new Array(64); var s64 = new Array(123); for (i = 0; i < 64; ) s64[b64[i] = i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++; var i; base64.encode = function encode(buffer, start, end) { var parts = null, chunk = []; var i2 = 0, j = 0, t; while (start < end) { var b = buffer[start++]; switch (j) { case 0: chunk[i2++] = b64[b >> 2]; t = (b & 3) << 4; j = 1; break; case 1: chunk[i2++] = b64[t | b >> 4]; t = (b & 15) << 2; j = 2; break; case 2: chunk[i2++] = b64[t | b >> 6]; chunk[i2++] = b64[b & 63]; j = 0; break; } if (i2 > 8191) { (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk)); i2 = 0; } } if (j) { chunk[i2++] = b64[t]; chunk[i2++] = 61; if (j === 1) chunk[i2++] = 61; } if (parts) { if (i2) parts.push(String.fromCharCode.apply(String, chunk.slice(0, i2))); return parts.join(""); } return String.fromCharCode.apply(String, chunk.slice(0, i2)); }; var invalidEncoding = "invalid encoding"; base64.decode = function decode(string, buffer, offset) { var start = offset; var j = 0, t; for (var i2 = 0; i2 < string.length; ) { var c = string.charCodeAt(i2++); if (c === 61 && j > 1) break; if ((c = s64[c]) === void 0) throw Error(invalidEncoding); switch (j) { case 0: t = c; j = 1; break; case 1: buffer[offset++] = t << 2 | (c & 48) >> 4; t = c; j = 2; break; case 2: buffer[offset++] = (t & 15) << 4 | (c & 60) >> 2; t = c; j = 3; break; case 3: buffer[offset++] = (t & 3) << 6 | c; j = 0; break; } } if (j === 1) throw Error(invalidEncoding); return offset - start; }; base64.test = function test(string) { return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(string); }; } }); // web/node_modules/@protobufjs/eventemitter/index.js var require_eventemitter = __commonJS({ "web/node_modules/@protobufjs/eventemitter/index.js"(exports2, module2) { "use strict"; module2.exports = EventEmitter; function EventEmitter() { this._listeners = {}; } EventEmitter.prototype.on = function on(evt, fn, ctx) { (this._listeners[evt] || (this._listeners[evt] = [])).push({ fn, ctx: ctx || this }); return this; }; EventEmitter.prototype.off = function off(evt, fn) { if (evt === void 0) this._listeners = {}; else { if (fn === void 0) this._listeners[evt] = []; else { var listeners = this._listeners[evt]; for (var i = 0; i < listeners.length; ) if (listeners[i].fn === fn) listeners.splice(i, 1); else ++i; } } return this; }; EventEmitter.prototype.emit = function emit(evt) { var listeners = this._listeners[evt]; if (listeners) { var args = [], i = 1; for (; i < arguments.length; ) args.push(arguments[i++]); for (i = 0; i < listeners.length; ) listeners[i].fn.apply(listeners[i++].ctx, args); } return this; }; } }); // web/node_modules/@protobufjs/float/index.js var require_float = __commonJS({ "web/node_modules/@protobufjs/float/index.js"(exports2, module2) { "use strict"; module2.exports = factory(factory); function factory(exports3) { if (typeof Float32Array !== "undefined") (function() { var f32 = new Float32Array([-0]), f8b = new Uint8Array(f32.buffer), le = f8b[3] === 128; function writeFloat_f32_cpy(val, buf, pos) { f32[0] = val; buf[pos] = f8b[0]; buf[pos + 1] = f8b[1]; buf[pos + 2] = f8b[2]; buf[pos + 3] = f8b[3]; } function writeFloat_f32_rev(val, buf, pos) { f32[0] = val; buf[pos] = f8b[3]; buf[pos + 1] = f8b[2]; buf[pos + 2] = f8b[1]; buf[pos + 3] = f8b[0]; } exports3.writeFloatLE = le ? writeFloat_f32_cpy : writeFloat_f32_rev; exports3.writeFloatBE = le ? writeFloat_f32_rev : writeFloat_f32_cpy; function readFloat_f32_cpy(buf, pos) { f8b[0] = buf[pos]; f8b[1] = buf[pos + 1]; f8b[2] = buf[pos + 2]; f8b[3] = buf[pos + 3]; return f32[0]; } function readFloat_f32_rev(buf, pos) { f8b[3] = buf[pos]; f8b[2] = buf[pos + 1]; f8b[1] = buf[pos + 2]; f8b[0] = buf[pos + 3]; return f32[0]; } exports3.readFloatLE = le ? readFloat_f32_cpy : readFloat_f32_rev; exports3.readFloatBE = le ? readFloat_f32_rev : readFloat_f32_cpy; })(); else (function() { function writeFloat_ieee754(writeUint, val, buf, pos) { var sign = val < 0 ? 1 : 0; if (sign) val = -val; if (val === 0) writeUint(1 / val > 0 ? ( /* positive */ 0 ) : ( /* negative 0 */ 2147483648 ), buf, pos); else if (isNaN(val)) writeUint(2143289344, buf, pos); else if (val > 34028234663852886e22) writeUint((sign << 31 | 2139095040) >>> 0, buf, pos); else if (val < 11754943508222875e-54) writeUint((sign << 31 | Math.round(val / 1401298464324817e-60)) >>> 0, buf, pos); else { var exponent = Math.floor(Math.log(val) / Math.LN2), mantissa = Math.round(val * Math.pow(2, -exponent) * 8388608) & 8388607; writeUint((sign << 31 | exponent + 127 << 23 | mantissa) >>> 0, buf, pos); } } exports3.writeFloatLE = writeFloat_ieee754.bind(null, writeUintLE); exports3.writeFloatBE = writeFloat_ieee754.bind(null, writeUintBE); function readFloat_ieee754(readUint, buf, pos) { var uint = readUint(buf, pos), sign = (uint >> 31) * 2 + 1, exponent = uint >>> 23 & 255, mantissa = uint & 8388607; return exponent === 255 ? mantissa ? NaN : sign * Infinity : exponent === 0 ? sign * 1401298464324817e-60 * mantissa : sign * Math.pow(2, exponent - 150) * (mantissa + 8388608); } exports3.readFloatLE = readFloat_ieee754.bind(null, readUintLE); exports3.readFloatBE = readFloat_ieee754.bind(null, readUintBE); })(); if (typeof Float64Array !== "undefined") (function() { var f64 = new Float64Array([-0]), f8b = new Uint8Array(f64.buffer), le = f8b[7] === 128; function writeDouble_f64_cpy(val, buf, pos) { f64[0] = val; buf[pos] = f8b[0]; buf[pos + 1] = f8b[1]; buf[pos + 2] = f8b[2]; buf[pos + 3] = f8b[3]; buf[pos + 4] = f8b[4]; buf[pos + 5] = f8b[5]; buf[pos + 6] = f8b[6]; buf[pos + 7] = f8b[7]; } function writeDouble_f64_rev(val, buf, pos) { f64[0] = val; buf[pos] = f8b[7]; buf[pos + 1] = f8b[6]; buf[pos + 2] = f8b[5]; buf[pos + 3] = f8b[4]; buf[pos + 4] = f8b[3]; buf[pos + 5] = f8b[2]; buf[pos + 6] = f8b[1]; buf[pos + 7] = f8b[0]; } exports3.writeDoubleLE = le ? writeDouble_f64_cpy : writeDouble_f64_rev; exports3.writeDoubleBE = le ? writeDouble_f64_rev : writeDouble_f64_cpy; function readDouble_f64_cpy(buf, pos) { f8b[0] = buf[pos]; f8b[1] = buf[pos + 1]; f8b[2] = buf[pos + 2]; f8b[3] = buf[pos + 3]; f8b[4] = buf[pos + 4]; f8b[5] = buf[pos + 5]; f8b[6] = buf[pos + 6]; f8b[7] = buf[pos + 7]; return f64[0]; } function readDouble_f64_rev(buf, pos) { f8b[7] = buf[pos]; f8b[6] = buf[pos + 1]; f8b[5] = buf[pos + 2]; f8b[4] = buf[pos + 3]; f8b[3] = buf[pos + 4]; f8b[2] = buf[pos + 5]; f8b[1] = buf[pos + 6]; f8b[0] = buf[pos + 7]; return f64[0]; } exports3.readDoubleLE = le ? readDouble_f64_cpy : readDouble_f64_rev; exports3.readDoubleBE = le ? readDouble_f64_rev : readDouble_f64_cpy; })(); else (function() { function writeDouble_ieee754(writeUint, off0, off1, val, buf, pos) { var sign = val < 0 ? 1 : 0; if (sign) val = -val; if (val === 0) { writeUint(0, buf, pos + off0); writeUint(1 / val > 0 ? ( /* positive */ 0 ) : ( /* negative 0 */ 2147483648 ), buf, pos + off1); } else if (isNaN(val)) { writeUint(0, buf, pos + off0); writeUint(2146959360, buf, pos + off1); } else if (val > 17976931348623157e292) { writeUint(0, buf, pos + off0); writeUint((sign << 31 | 2146435072) >>> 0, buf, pos + off1); } else { var mantissa; if (val < 22250738585072014e-324) { mantissa = val / 5e-324; writeUint(mantissa >>> 0, buf, pos + off0); writeUint((sign << 31 | mantissa / 4294967296) >>> 0, buf, pos + off1); } else { var exponent = Math.floor(Math.log(val) / Math.LN2); if (exponent === 1024) exponent = 1023; mantissa = val * Math.pow(2, -exponent); writeUint(mantissa * 4503599627370496 >>> 0, buf, pos + off0); writeUint((sign << 31 | exponent + 1023 << 20 | mantissa * 1048576 & 1048575) >>> 0, buf, pos + off1); } } } exports3.writeDoubleLE = writeDouble_ieee754.bind(null, writeUintLE, 0, 4); exports3.writeDoubleBE = writeDouble_ieee754.bind(null, writeUintBE, 4, 0); function readDouble_ieee754(readUint, off0, off1, buf, pos) { var lo = readUint(buf, pos + off0), hi = readUint(buf, pos + off1); var sign = (hi >> 31) * 2 + 1, exponent = hi >>> 20 & 2047, mantissa = 4294967296 * (hi & 1048575) + lo; return exponent === 2047 ? mantissa ? NaN : sign * Infinity : exponent === 0 ? sign * 5e-324 * mantissa : sign * Math.pow(2, exponent - 1075) * (mantissa + 4503599627370496); } exports3.readDoubleLE = readDouble_ieee754.bind(null, readUintLE, 0, 4); exports3.readDoubleBE = readDouble_ieee754.bind(null, readUintBE, 4, 0); })(); return exports3; } function writeUintLE(val, buf, pos) { buf[pos] = val & 255; buf[pos + 1] = val >>> 8 & 255; buf[pos + 2] = val >>> 16 & 255; buf[pos + 3] = val >>> 24; } function writeUintBE(val, buf, pos) { buf[pos] = val >>> 24; buf[pos + 1] = val >>> 16 & 255; buf[pos + 2] = val >>> 8 & 255; buf[pos + 3] = val & 255; } function readUintLE(buf, pos) { return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16 | buf[pos + 3] << 24) >>> 0; } function readUintBE(buf, pos) { return (buf[pos] << 24 | buf[pos + 1] << 16 | buf[pos + 2] << 8 | buf[pos + 3]) >>> 0; } } }); // web/node_modules/@protobufjs/inquire/index.js var require_inquire = __commonJS({ "web/node_modules/@protobufjs/inquire/index.js"(exports, module) { "use strict"; module.exports = inquire; function inquire(moduleName) { try { var mod = eval("quire".replace(/^/, "re"))(moduleName); if (mod && (mod.length || Object.keys(mod).length)) return mod; } catch (e) { } return null; } } }); // web/node_modules/@protobufjs/utf8/index.js var require_utf8 = __commonJS({ "web/node_modules/@protobufjs/utf8/index.js"(exports2) { "use strict"; var utf8 = exports2; utf8.length = function utf8_length(string) { var len = 0, c = 0; for (var i = 0; i < string.length; ++i) { c = string.charCodeAt(i); if (c < 128) len += 1; else if (c < 2048) len += 2; else if ((c & 64512) === 55296 && (string.charCodeAt(i + 1) & 64512) === 56320) { ++i; len += 4; } else len += 3; } return len; }; utf8.read = function utf8_read(buffer, start, end) { var len = end - start; if (len < 1) return ""; var parts = null, chunk = [], i = 0, t; while (start < end) { t = buffer[start++]; if (t < 128) chunk[i++] = t; else if (t > 191 && t < 224) chunk[i++] = (t & 31) << 6 | buffer[start++] & 63; else if (t > 239 && t < 365) { t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 65536; chunk[i++] = 55296 + (t >> 10); chunk[i++] = 56320 + (t & 1023); } else chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63; if (i > 8191) { (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk)); i = 0; } } if (parts) { if (i) parts.push(String.fromCharCode.apply(String, chunk.slice(0, i))); return parts.join(""); } return String.fromCharCode.apply(String, chunk.slice(0, i)); }; utf8.write = function utf8_write(string, buffer, offset) { var start = offset, c1, c2; for (var i = 0; i < string.length; ++i) { c1 = string.charCodeAt(i); if (c1 < 128) { buffer[offset++] = c1; } else if (c1 < 2048) { buffer[offset++] = c1 >> 6 | 192; buffer[offset++] = c1 & 63 | 128; } else if ((c1 & 64512) === 55296 && ((c2 = string.charCodeAt(i + 1)) & 64512) === 56320) { c1 = 65536 + ((c1 & 1023) << 10) + (c2 & 1023); ++i; buffer[offset++] = c1 >> 18 | 240; buffer[offset++] = c1 >> 12 & 63 | 128; buffer[offset++] = c1 >> 6 & 63 | 128; buffer[offset++] = c1 & 63 | 128; } else { buffer[offset++] = c1 >> 12 | 224; buffer[offset++] = c1 >> 6 & 63 | 128; buffer[offset++] = c1 & 63 | 128; } } return offset - start; }; } }); // web/node_modules/@protobufjs/pool/index.js var require_pool = __commonJS({ "web/node_modules/@protobufjs/pool/index.js"(exports2, module2) { "use strict"; module2.exports = pool; function pool(alloc, slice2, size) { var SIZE = size || 8192; var MAX = SIZE >>> 1; var slab = null; var offset = SIZE; return function pool_alloc(size2) { if (size2 < 1 || size2 > MAX) return alloc(size2); if (offset + size2 > SIZE) { slab = alloc(SIZE); offset = 0; } var buf = slice2.call(slab, offset, offset += size2); if (offset & 7) offset = (offset | 7) + 1; return buf; }; } } }); // web/node_modules/protobufjs/src/util/longbits.js var require_longbits = __commonJS({ "web/node_modules/protobufjs/src/util/longbits.js"(exports2, module2) { "use strict"; module2.exports = LongBits; var util = require_minimal(); function LongBits(lo, hi) { this.lo = lo >>> 0; this.hi = hi >>> 0; } var zero = LongBits.zero = new LongBits(0, 0); zero.toNumber = function() { return 0; }; zero.zzEncode = zero.zzDecode = function() { return this; }; zero.length = function() { return 1; }; var zeroHash = LongBits.zeroHash = "\0\0\0\0\0\0\0\0"; LongBits.fromNumber = function fromNumber2(value) { if (value === 0) return zero; var sign = value < 0; if (sign) value = -value; var lo = value >>> 0, hi = (value - lo) / 4294967296 >>> 0; if (sign) { hi = ~hi >>> 0; lo = ~lo >>> 0; if (++lo > 4294967295) { lo = 0; if (++hi > 4294967295) hi = 0; } } return new LongBits(lo, hi); }; LongBits.from = function from(value) { if (typeof value === "number") return LongBits.fromNumber(value); if (util.isString(value)) { if (util.Long) value = util.Long.fromString(value); else return LongBits.fromNumber(parseInt(value, 10)); } return value.low || value.high ? new LongBits(value.low >>> 0, value.high >>> 0) : zero; }; LongBits.prototype.toNumber = function toNumber2(unsigned) { if (!unsigned && this.hi >>> 31) { var lo = ~this.lo + 1 >>> 0, hi = ~this.hi >>> 0; if (!lo) hi = hi + 1 >>> 0; return -(lo + hi * 4294967296); } return this.lo + this.hi * 4294967296; }; LongBits.prototype.toLong = function toLong(unsigned) { return util.Long ? new util.Long(this.lo | 0, this.hi | 0, Boolean(unsigned)) : { low: this.lo | 0, high: this.hi | 0, unsigned: Boolean(unsigned) }; }; var charCodeAt = String.prototype.charCodeAt; LongBits.fromHash = function fromHash(hash) { if (hash === zeroHash) return zero; return new LongBits( (charCodeAt.call(hash, 0) | charCodeAt.call(hash, 1) << 8 | charCodeAt.call(hash, 2) << 16 | charCodeAt.call(hash, 3) << 24) >>> 0, (charCodeAt.call(hash, 4) | charCodeAt.call(hash, 5) << 8 | charCodeAt.call(hash, 6) << 16 | charCodeAt.call(hash, 7) << 24) >>> 0 ); }; LongBits.prototype.toHash = function toHash() { return String.fromCharCode( this.lo & 255, this.lo >>> 8 & 255, this.lo >>> 16 & 255, this.lo >>> 24, this.hi & 255, this.hi >>> 8 & 255, this.hi >>> 16 & 255, this.hi >>> 24 ); }; LongBits.prototype.zzEncode = function zzEncode() { var mask = this.hi >> 31; this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0; this.lo = (this.lo << 1 ^ mask) >>> 0; return this; }; LongBits.prototype.zzDecode = function zzDecode() { var mask = -(this.lo & 1); this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0; this.hi = (this.hi >>> 1 ^ mask) >>> 0; return this; }; LongBits.prototype.length = function length() { var part0 = this.lo, part1 = (this.lo >>> 28 | this.hi << 4) >>> 0, part2 = this.hi >>> 24; return part2 === 0 ? part1 === 0 ? part0 < 16384 ? part0 < 128 ? 1 : 2 : part0 < 2097152 ? 3 : 4 : part1 < 16384 ? part1 < 128 ? 5 : 6 : part1 < 2097152 ? 7 : 8 : part2 < 128 ? 9 : 10; }; } }); // web/node_modules/protobufjs/src/util/minimal.js var require_minimal = __commonJS({ "web/node_modules/protobufjs/src/util/minimal.js"(exports2) { "use strict"; var util = exports2; util.asPromise = require_aspromise(); util.base64 = require_base64(); util.EventEmitter = require_eventemitter(); util.float = require_float(); util.inquire = require_inquire(); util.utf8 = require_utf8(); util.pool = require_pool(); util.LongBits = require_longbits(); util.isNode = Boolean(typeof global !== "undefined" && global && global.process && global.process.versions && global.process.versions.node); util.global = util.isNode && global || typeof window !== "undefined" && window || typeof self !== "undefined" && self || exports2; util.emptyArray = Object.freeze ? Object.freeze([]) : ( /* istanbul ignore next */ [] ); util.emptyObject = Object.freeze ? Object.freeze({}) : ( /* istanbul ignore next */ {} ); util.isInteger = Number.isInteger || /* istanbul ignore next */ function isInteger(value) { return typeof value === "number" && isFinite(value) && Math.floor(value) === value; }; util.isString = function isString(value) { return typeof value === "string" || value instanceof String; }; util.isObject = function isObject(value) { return value && typeof value === "object"; }; util.isset = /** * Checks if a property on a message is considered to be present. * @param {Object} obj Plain object or message instance * @param {string} prop Property name * @returns {boolean} `true` if considered to be present, otherwise `false` */ util.isSet = function isSet(obj, prop) { var value = obj[prop]; if (value != null && obj.hasOwnProperty(prop)) return typeof value !== "object" || (Array.isArray(value) ? value.length : Object.keys(value).length) > 0; return false; }; util.Buffer = function() { try { var Buffer2 = util.inquire("buffer").Buffer; return Buffer2.prototype.utf8Write ? Buffer2 : ( /* istanbul ignore next */ null ); } catch (e) { return null; } }(); util._Buffer_from = null; util._Buffer_allocUnsafe = null; util.newBuffer = function newBuffer(sizeOrArray) { return typeof sizeOrArray === "number" ? util.Buffer ? util._Buffer_allocUnsafe(sizeOrArray) : new util.Array(sizeOrArray) : util.Buffer ? util._Buffer_from(sizeOrArray) : typeof Uint8Array === "undefined" ? sizeOrArray : new Uint8Array(sizeOrArray); }; util.Array = typeof Uint8Array !== "undefined" ? Uint8Array : Array; util.Long = /* istanbul ignore next */ util.global.dcodeIO && /* istanbul ignore next */ util.global.dcodeIO.Long || /* istanbul ignore next */ util.global.Long || util.inquire("long"); util.key2Re = /^true|false|0|1$/; util.key32Re = /^-?(?:0|[1-9][0-9]*)$/; util.key64Re = /^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/; util.longToHash = function longToHash(value) { return value ? util.LongBits.from(value).toHash() : util.LongBits.zeroHash; }; util.longFromHash = function longFromHash(hash, unsigned) { var bits = util.LongBits.fromHash(hash); if (util.Long) return util.Long.fromBits(bits.lo, bits.hi, unsigned); return bits.toNumber(Boolean(unsigned)); }; function merge(dst, src, ifNotSet) { for (var keys = Object.keys(src), i = 0; i < keys.length; ++i) if (dst[keys[i]] === void 0 || !ifNotSet) dst[keys[i]] = src[keys[i]]; return dst; } util.merge = merge; util.lcFirst = function lcFirst(str) { return str.charAt(0).toLowerCase() + str.substring(1); }; function newError(name2) { function CustomError(message, properties) { if (!(this instanceof CustomError)) return new CustomError(message, properties); Object.defineProperty(this, "message", { get: function() { return message; } }); if (Error.captureStackTrace) Error.captureStackTrace(this, CustomError); else Object.defineProperty(this, "stack", { value: new Error().stack || "" }); if (properties) merge(this, properties); } CustomError.prototype = Object.create(Error.prototype, { constructor: { value: CustomError, writable: true, enumerable: false, configurable: true }, name: { get: function get() { return name2; }, set: void 0, enumerable: false, // configurable: false would accurately preserve the behavior of // the original, but I'm guessing that was not intentional. // For an actual error subclass, this property would // be configurable. configurable: true }, toString: { value: function value() { return this.name + ": " + this.message; }, writable: true, enumerable: false, configurable: true } }); return CustomError; } util.newError = newError; util.ProtocolError = newError("ProtocolError"); util.oneOfGetter = function getOneOf(fieldNames) { var fieldMap = {}; for (var i = 0; i < fieldNames.length; ++i) fieldMap[fieldNames[i]] = 1; return function() { for (var keys = Object.keys(this), i2 = keys.length - 1; i2 > -1; --i2) if (fieldMap[keys[i2]] === 1 && this[keys[i2]] !== void 0 && this[keys[i2]] !== null) return keys[i2]; }; }; util.oneOfSetter = function setOneOf(fieldNames) { return function(name2) { for (var i = 0; i < fieldNames.length; ++i) if (fieldNames[i] !== name2) delete this[fieldNames[i]]; }; }; util.toJSONOptions = { longs: String, enums: String, bytes: String, json: true }; util._configure = function() { var Buffer2 = util.Buffer; if (!Buffer2) { util._Buffer_from = util._Buffer_allocUnsafe = null; return; } util._Buffer_from = Buffer2.from !== Uint8Array.from && Buffer2.from || /* istanbul ignore next */ function Buffer_from(value, encoding) { return new Buffer2(value, encoding); }; util._Buffer_allocUnsafe = Buffer2.allocUnsafe || /* istanbul ignore next */ function Buffer_allocUnsafe(size) { return new Buffer2(size); }; }; } }); // web/node_modules/protobufjs/src/writer.js var require_writer = __commonJS({ "web/node_modules/protobufjs/src/writer.js"(exports2, module2) { "use strict"; module2.exports = Writer; var util = require_minimal(); var BufferWriter; var LongBits = util.LongBits; var base64 = util.base64; var utf8 = util.utf8; function Op(fn, len, val) { this.fn = fn; this.len = len; this.next = void 0; this.val = val; } function noop() { } function State(writer) { this.head = writer.head; this.tail = writer.tail; this.len = writer.len; this.next = writer.states; } function Writer() { this.len = 0; this.head = new Op(noop, 0, 0); this.tail = this.head; this.states = null; } var create = function create2() { return util.Buffer ? function create_buffer_setup() { return (Writer.create = function create_buffer() { return new BufferWriter(); })(); } : function create_array() { return new Writer(); }; }; Writer.create = create(); Writer.alloc = function alloc(size) { return new util.Array(size); }; if (util.Array !== Array) Writer.alloc = util.pool(Writer.alloc, util.Array.prototype.subarray); Writer.prototype._push = function push(fn, len, val) { this.tail = this.tail.next = new Op(fn, len, val); this.len += len; return this; }; function writeByte(val, buf, pos) { buf[pos] = val & 255; } function writeVarint32(val, buf, pos) { while (val > 127) { buf[pos++] = val & 127 | 128; val >>>= 7; } buf[pos] = val; } function VarintOp(len, val) { this.len = len; this.next = void 0; this.val = val; } VarintOp.prototype = Object.create(Op.prototype); VarintOp.prototype.fn = writeVarint32; Writer.prototype.uint32 = function write_uint32(value) { this.len += (this.tail = this.tail.next = new VarintOp( (value = value >>> 0) < 128 ? 1 : value < 16384 ? 2 : value < 2097152 ? 3 : value < 268435456 ? 4 : 5, value )).len; return this; }; Writer.prototype.int32 = function write_int32(value) { return value < 0 ? this._push(writeVarint64, 10, LongBits.fromNumber(value)) : this.uint32(value); }; Writer.prototype.sint32 = function write_sint32(value) { return this.uint32((value << 1 ^ value >> 31) >>> 0); }; function writeVarint64(val, buf, pos) { while (val.hi) { buf[pos++] = val.lo & 127 | 128; val.lo = (val.lo >>> 7 | val.hi << 25) >>> 0; val.hi >>>= 7; } while (val.lo > 127) { buf[pos++] = val.lo & 127 | 128; val.lo = val.lo >>> 7; } buf[pos++] = val.lo; } Writer.prototype.uint64 = function write_uint64(value) { var bits = LongBits.from(value); return this._push(writeVarint64, bits.length(), bits); }; Writer.prototype.int64 = Writer.prototype.uint64; Writer.prototype.sint64 = function write_sint64(value) { var bits = LongBits.from(value).zzEncode(); return this._push(writeVarint64, bits.length(), bits); }; Writer.prototype.bool = function write_bool(value) { return this._push(writeByte, 1, value ? 1 : 0); }; function writeFixed32(val, buf, pos) { buf[pos] = val & 255; buf[pos + 1] = val >>> 8 & 255; buf[pos + 2] = val >>> 16 & 255; buf[pos + 3] = val >>> 24; } Writer.prototype.fixed32 = function write_fixed32(value) { return this._push(writeFixed32, 4, value >>> 0); }; Writer.prototype.sfixed32 = Writer.prototype.fixed32; Writer.prototype.fixed64 = function write_fixed64(value) { var bits = LongBits.from(value); return this._push(writeFixed32, 4, bits.lo)._push(writeFixed32, 4, bits.hi); }; Writer.prototype.sfixed64 = Writer.prototype.fixed64; Writer.prototype.float = function write_float(value) { return this._push(util.float.writeFloatLE, 4, value); }; Writer.prototype.double = function write_double(value) { return this._push(util.float.writeDoubleLE, 8, value); }; var writeBytes = util.Array.prototype.set ? function writeBytes_set(val, buf, pos) { buf.set(val, pos); } : function writeBytes_for(val, buf, pos) { for (var i = 0; i < val.length; ++i) buf[pos + i] = val[i]; }; Writer.prototype.bytes = function write_bytes(value) { var len = value.length >>> 0; if (!len) return this._push(writeByte, 1, 0); if (util.isString(value)) { var buf = Writer.alloc(len = base64.length(value)); base64.decode(value, buf, 0); value = buf; } return this.uint32(len)._push(writeBytes, len, value); }; Writer.prototype.string = function write_string(value) { var len = utf8.length(value); return len ? this.uint32(len)._push(utf8.write, len, value) : this._push(writeByte, 1, 0); }; Writer.prototype.fork = function fork() { this.states = new State(this); this.head = this.tail = new Op(noop, 0, 0); this.len = 0; return this; }; Writer.prototype.reset = function reset() { if (this.states) { this.head = this.states.head; this.tail = this.states.tail; this.len = this.states.len; this.states = this.states.next; } else { this.head = this.tail = new Op(noop, 0, 0); this.len = 0; } return this; }; Writer.prototype.ldelim = function ldelim() { var head = this.head, tail = this.tail, len = this.len; this.reset().uint32(len); if (len) { this.tail.next = head.next; this.tail = tail; this.len += len; } return this; }; Writer.prototype.finish = function finish() { var head = this.head.next, buf = this.constructor.alloc(this.len), pos = 0; while (head) { head.fn(head.val, buf, pos); pos += head.len; head = head.next; } return buf; }; Writer._configure = function(BufferWriter_) { BufferWriter = BufferWriter_; Writer.create = create(); BufferWriter._configure(); }; } }); // web/node_modules/protobufjs/src/writer_buffer.js var require_writer_buffer = __commonJS({ "web/node_modules/protobufjs/src/writer_buffer.js"(exports2, module2) { "use strict"; module2.exports = BufferWriter; var Writer = require_writer(); (BufferWriter.prototype = Object.create(Writer.prototype)).constructor = BufferWriter; var util = require_minimal(); function BufferWriter() { Writer.call(this); } BufferWriter._configure = function() { BufferWriter.alloc = util._Buffer_allocUnsafe; BufferWriter.writeBytesBuffer = util.Buffer && util.Buffer.prototype instanceof Uint8Array && util.Buffer.prototype.set.name === "set" ? function writeBytesBuffer_set(val, buf, pos) { buf.set(val, pos); } : function writeBytesBuffer_copy(val, buf, pos) { if (val.copy) val.copy(buf, pos, 0, val.length); else for (var i = 0; i < val.length; ) buf[pos++] = val[i++]; }; }; BufferWriter.prototype.bytes = function write_bytes_buffer(value) { if (util.isString(value)) value = util._Buffer_from(value, "base64"); var len = value.length >>> 0; this.uint32(len); if (len) this._push(BufferWriter.writeBytesBuffer, len, value); return this; }; function writeStringBuffer(val, buf, pos) { if (val.length < 40) util.utf8.write(val, buf, pos); else if (buf.utf8Write) buf.utf8Write(val, pos); else buf.write(val, pos); } BufferWriter.prototype.string = function write_string_buffer(value) { var len = util.Buffer.byteLength(value); this.uint32(len); if (len) this._push(writeStringBuffer, len, value); return this; }; BufferWriter._configure(); } }); // web/node_modules/protobufjs/src/reader.js var require_reader = __commonJS({ "web/node_modules/protobufjs/src/reader.js"(exports2, module2) { "use strict"; module2.exports = Reader; var util = require_minimal(); var BufferReader; var LongBits = util.LongBits; var utf8 = util.utf8; function indexOutOfRange(reader, writeLength) { return RangeError("index out of range: " + reader.pos + " + " + (writeLength || 1) + " > " + reader.len); } function Reader(buffer) { this.buf = buffer; this.pos = 0; this.len = buffer.length; } var create_array = typeof Uint8Array !== "undefined" ? function create_typed_array(buffer) { if (buffer instanceof Uint8Array || Array.isArray(buffer)) return new Reader(buffer); throw Error("illegal buffer"); } : function create_array2(buffer) { if (Array.isArray(buffer)) return new Reader(buffer); throw Error("illegal buffer"); }; var create = function create2() { return util.Buffer ? function create_buffer_setup(buffer) { return (Reader.create = function create_buffer(buffer2) { return util.Buffer.isBuffer(buffer2) ? new BufferReader(buffer2) : create_array(buffer2); })(buffer); } : create_array; }; Reader.create = create(); Reader.prototype._slice = util.Array.prototype.subarray || /* istanbul ignore next */ util.Array.prototype.slice; Reader.prototype.uint32 = /* @__PURE__ */ function read_uint32_setup() { var value = 4294967295; return function read_uint32() { value = (this.buf[this.pos] & 127) >>> 0; if (this.buf[this.pos++] < 128) return value; value = (value | (this.buf[this.pos] & 127) << 7) >>> 0; if (this.buf[this.pos++] < 128) return value; value = (value | (this.buf[this.pos] & 127) << 14) >>> 0; if (this.buf[this.pos++] < 128) return value; value = (value | (this.buf[this.pos] & 127) << 21) >>> 0; if (this.buf[this.pos++] < 128) return value; value = (value | (this.buf[this.pos] & 15) << 28) >>> 0; if (this.buf[this.pos++] < 128) return value; if ((this.pos += 5) > this.len) { this.pos = this.len; throw indexOutOfRange(this, 10); } return value; }; }(); Reader.prototype.int32 = function read_int32() { return this.uint32() | 0; }; Reader.prototype.sint32 = function read_sint32() { var value = this.uint32(); return value >>> 1 ^ -(value & 1) | 0; }; function readLongVarint() { var bits = new LongBits(0, 0); var i = 0; if (this.len - this.pos > 4) { for (; i < 4; ++i) { bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0; if (this.buf[this.pos++] < 128) return bits; } bits.lo = (bits.lo | (this.buf[this.pos] & 127) << 28) >>> 0; bits.hi = (bits.hi | (this.buf[this.pos] & 127) >> 4) >>> 0; if (this.buf[this.pos++] < 128) return bits; i = 0; } else { for (; i < 3; ++i) { if (this.pos >= this.len) throw indexOutOfRange(this); bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0; if (this.buf[this.pos++] < 128) return bits; } bits.lo = (bits.lo | (this.buf[this.pos++] & 127) << i * 7) >>> 0; return bits; } if (this.len - this.pos > 4) { for (; i < 5; ++i) { bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0; if (this.buf[this.pos++] < 128) return bits; } } else { for (; i < 5; ++i) { if (this.pos >= this.len) throw indexOutOfRange(this); bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0; if (this.buf[this.pos++] < 128) return bits; } } throw Error("invalid varint encoding"); } Reader.prototype.bool = function read_bool() { return this.uint32() !== 0; }; function readFixed32_end(buf, end) { return (buf[end - 4] | buf[end - 3] << 8 | buf[end - 2] << 16 | buf[end - 1] << 24) >>> 0; } Reader.prototype.fixed32 = function read_fixed32() { if (this.pos + 4 > this.len) throw indexOutOfRange(this, 4); return readFixed32_end(this.buf, this.pos += 4); }; Reader.prototype.sfixed32 = function read_sfixed32() { if (this.pos + 4 > this.len) throw indexOutOfRange(this, 4); return readFixed32_end(this.buf, this.pos += 4) | 0; }; function readFixed64() { if (this.pos + 8 > this.len) throw indexOutOfRange(this, 8); return new LongBits(readFixed32_end(this.buf, this.pos += 4), readFixed32_end(this.buf, this.pos += 4)); } Reader.prototype.float = function read_float() { if (this.pos + 4 > this.len) throw indexOutOfRange(this, 4); var value = util.float.readFloatLE(this.buf, this.pos); this.pos += 4; return value; }; Reader.prototype.double = function read_double() { if (this.pos + 8 > this.len) throw indexOutOfRange(this, 4); var value = util.float.readDoubleLE(this.buf, this.pos); this.pos += 8; return value; }; Reader.prototype.bytes = function read_bytes() { var length = this.uint32(), start = this.pos, end = this.pos + length; if (end > this.len) throw indexOutOfRange(this, length); this.pos += length; if (Array.isArray(this.buf)) return this.buf.slice(start, end); if (start === end) { var nativeBuffer = util.Buffer; return nativeBuffer ? nativeBuffer.alloc(0) : new this.buf.constructor(0); } return this._slice.call(this.buf, start, end); }; Reader.prototype.string = function read_string() { var bytes = this.bytes(); return utf8.read(bytes, 0, bytes.length); }; Reader.prototype.skip = function skip(length) { if (typeof length === "number") { if (this.pos + length > this.len) throw indexOutOfRange(this, length); this.pos += length; } else { do { if (this.pos >= this.len) throw indexOutOfRange(this); } while (this.buf[this.pos++] & 128); } return this; }; Reader.prototype.skipType = function(wireType) { switch (wireType) { case 0: this.skip(); break; case 1: this.skip(8); break; case 2: this.skip(this.uint32()); break; case 3: while ((wireType = this.uint32() & 7) !== 4) { this.skipType(wireType); } break; case 5: this.skip(4); break; /* istanbul ignore next */ default: throw Error("invalid wire type " + wireType + " at offset " + this.pos); } return this; }; Reader._configure = function(BufferReader_) { BufferReader = BufferReader_; Reader.create = create(); BufferReader._configure(); var fn = util.Long ? "toLong" : ( /* istanbul ignore next */ "toNumber" ); util.merge(Reader.prototype, { int64: function read_int64() { return readLongVarint.call(this)[fn](false); }, uint64: function read_uint64() { return readLongVarint.call(this)[fn](true); }, sint64: function read_sint64() { return readLongVarint.call(this).zzDecode()[fn](false); }, fixed64: function read_fixed64() { return readFixed64.call(this)[fn](true); }, sfixed64: function read_sfixed64() { return readFixed64.call(this)[fn](false); } }); }; } }); // web/node_modules/protobufjs/src/reader_buffer.js var require_reader_buffer = __commonJS({ "web/node_modules/protobufjs/src/reader_buffer.js"(exports2, module2) { "use strict"; module2.exports = BufferReader; var Reader = require_reader(); (BufferReader.prototype = Object.create(Reader.prototype)).constructor = BufferReader; var util = require_minimal(); function BufferReader(buffer) { Reader.call(this, buffer); } BufferReader._configure = function() { if (util.Buffer) BufferReader.prototype._slice = util.Buffer.prototype.slice; }; BufferReader.prototype.string = function read_string_buffer() { var len = this.uint32(); return this.buf.utf8Slice ? this.buf.utf8Slice(this.pos, this.pos = Math.min(this.pos + len, this.len)) : this.buf.toString("utf-8", this.pos, this.pos = Math.min(this.pos + len, this.len)); }; BufferReader._configure(); } }); // web/node_modules/protobufjs/src/rpc/service.js var require_service = __commonJS({ "web/node_modules/protobufjs/src/rpc/service.js"(exports2, module2) { "use strict"; module2.exports = Service; var util = require_minimal(); (Service.prototype = Object.create(util.EventEmitter.prototype)).constructor = Service; function Service(rpcImpl, requestDelimited, responseDelimited) { if (typeof rpcImpl !== "function") throw TypeError("rpcImpl must be a function"); util.EventEmitter.call(this); this.rpcImpl = rpcImpl; this.requestDelimited = Boolean(requestDelimited); this.responseDelimited = Boolean(responseDelimited); } Service.prototype.rpcCall = function rpcCall(method, requestCtor, responseCtor, request, callback) { if (!request) throw TypeError("request must be specified"); var self2 = this; if (!callback) return util.asPromise(rpcCall, self2, method, requestCtor, responseCtor, request); if (!self2.rpcImpl) { setTimeout(function() { callback(Error("already ended")); }, 0); return void 0; } try { return self2.rpcImpl( method, requestCtor[self2.requestDelimited ? "encodeDelimited" : "encode"](request).finish(), function rpcCallback(err, response) { if (err) { self2.emit("error", err, method); return callback(err); } if (response === null) { self2.end( /* endedByRPC */ true ); return void 0; } if (!(response instanceof responseCtor)) { try { response = responseCtor[self2.responseDelimited ? "decodeDelimited" : "decode"](response); } catch (err2) { self2.emit("error", err2, method); return callback(err2); } } self2.emit("data", response, method); return callback(null, response); } ); } catch (err) { self2.emit("error", err, method); setTimeout(function() { callback(err); }, 0); return void 0; } }; Service.prototype.end = function end(endedByRPC) { if (this.rpcImpl) { if (!endedByRPC) this.rpcImpl(null, null, null); this.rpcImpl = null; this.emit("end").off(); } return this; }; } }); // web/node_modules/protobufjs/src/rpc.js var require_rpc = __commonJS({ "web/node_modules/protobufjs/src/rpc.js"(exports2) { "use strict"; var rpc = exports2; rpc.Service = require_service(); } }); // web/node_modules/protobufjs/src/roots.js var require_roots = __commonJS({ "web/node_modules/protobufjs/src/roots.js"(exports2, module2) { "use strict"; module2.exports = {}; } }); // web/node_modules/protobufjs/src/index-minimal.js var require_index_minimal = __commonJS({ "web/node_modules/protobufjs/src/index-minimal.js"(exports2) { "use strict"; var protobuf = exports2; protobuf.build = "minimal"; protobuf.Writer = require_writer(); protobuf.BufferWriter = require_writer_buffer(); protobuf.Reader = require_reader(); protobuf.BufferReader = require_reader_buffer(); protobuf.util = require_minimal(); protobuf.rpc = require_rpc(); protobuf.roots = require_roots(); protobuf.configure = configure; function configure() { protobuf.util._configure(); protobuf.Writer._configure(protobuf.BufferWriter); protobuf.Reader._configure(protobuf.BufferReader); } configure(); } }); // web/node_modules/protobufjs/minimal.js var require_minimal2 = __commonJS({ "web/node_modules/protobufjs/minimal.js"(exports2, module2) { "use strict"; module2.exports = require_index_minimal(); } }); // web/lib/onnxjs/ort-schema/protobuf/onnx.js var require_onnx = __commonJS({ "web/lib/onnxjs/ort-schema/protobuf/onnx.js"(exports2, module2) { "use strict"; var $protobuf = require_minimal2(); var $Reader = $protobuf.Reader; var $Writer = $protobuf.Writer; var $util = $protobuf.util; var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {}); $root.onnx = function() { var onnx6 = {}; onnx6.Version = function() { var valuesById = {}, values = Object.create(valuesById); values[valuesById[0] = "_START_VERSION"] = 0; values[valuesById[1] = "IR_VERSION_2017_10_10"] = 1; values[valuesById[2] = "IR_VERSION_2017_10_30"] = 2; values[valuesById[3] = "IR_VERSION_2017_11_3"] = 3; values[valuesById[4] = "IR_VERSION_2019_1_22"] = 4; values[valuesById[5] = "IR_VERSION_2019_3_18"] = 5; values[valuesById[6] = "IR_VERSION_2019_9_19"] = 6; values[valuesById[7] = "IR_VERSION_2020_5_8"] = 7; values[valuesById[8] = "IR_VERSION_2021_7_30"] = 8; values[valuesById[9] = "IR_VERSION"] = 9; return values; }(); onnx6.AttributeProto = function() { function AttributeProto(properties) { this.floats = []; this.ints = []; this.strings = []; this.tensors = []; this.graphs = []; this.sparseTensors = []; this.typeProtos = []; if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } AttributeProto.prototype.name = ""; AttributeProto.prototype.refAttrName = ""; AttributeProto.prototype.docString = ""; AttributeProto.prototype.type = 0; AttributeProto.prototype.f = 0; AttributeProto.prototype.i = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; AttributeProto.prototype.s = $util.newBuffer([]); AttributeProto.prototype.t = null; AttributeProto.prototype.g = null; AttributeProto.prototype.sparseTensor = null; AttributeProto.prototype.tp = null; AttributeProto.prototype.floats = $util.emptyArray; AttributeProto.prototype.ints = $util.emptyArray; AttributeProto.prototype.strings = $util.emptyArray; AttributeProto.prototype.tensors = $util.emptyArray; AttributeProto.prototype.graphs = $util.emptyArray; AttributeProto.prototype.sparseTensors = $util.emptyArray; AttributeProto.prototype.typeProtos = $util.emptyArray; AttributeProto.create = function create(properties) { return new AttributeProto(properties); }; AttributeProto.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.name != null && Object.hasOwnProperty.call(message, "name")) writer.uint32( /* id 1, wireType 2 =*/ 10 ).string(message.name); if (message.f != null && Object.hasOwnProperty.call(message, "f")) writer.uint32( /* id 2, wireType 5 =*/ 21 ).float(message.f); if (message.i != null && Object.hasOwnProperty.call(message, "i")) writer.uint32( /* id 3, wireType 0 =*/ 24 ).int64(message.i); if (message.s != null && Object.hasOwnProperty.call(message, "s")) writer.uint32( /* id 4, wireType 2 =*/ 34 ).bytes(message.s); if (message.t != null && Object.hasOwnProperty.call(message, "t")) $root.onnx.TensorProto.encode(message.t, writer.uint32( /* id 5, wireType 2 =*/ 42 ).fork()).ldelim(); if (message.g != null && Object.hasOwnProperty.call(message, "g")) $root.onnx.GraphProto.encode(message.g, writer.uint32( /* id 6, wireType 2 =*/ 50 ).fork()).ldelim(); if (message.floats != null && message.floats.length) { writer.uint32( /* id 7, wireType 2 =*/ 58 ).fork(); for (var i = 0; i < message.floats.length; ++i) writer.float(message.floats[i]); writer.ldelim(); } if (message.ints != null && message.ints.length) { writer.uint32( /* id 8, wireType 2 =*/ 66 ).fork(); for (var i = 0; i < message.ints.length; ++i) writer.int64(message.ints[i]); writer.ldelim(); } if (message.strings != null && message.strings.length) for (var i = 0; i < message.strings.length; ++i) writer.uint32( /* id 9, wireType 2 =*/ 74 ).bytes(message.strings[i]); if (message.tensors != null && message.tensors.length) for (var i = 0; i < message.tensors.length; ++i) $root.onnx.TensorProto.encode(message.tensors[i], writer.uint32( /* id 10, wireType 2 =*/ 82 ).fork()).ldelim(); if (message.graphs != null && message.graphs.length) for (var i = 0; i < message.graphs.length; ++i) $root.onnx.GraphProto.encode(message.graphs[i], writer.uint32( /* id 11, wireType 2 =*/ 90 ).fork()).ldelim(); if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) writer.uint32( /* id 13, wireType 2 =*/ 106 ).string(message.docString); if (message.tp != null && Object.hasOwnProperty.call(message, "tp")) $root.onnx.TypeProto.encode(message.tp, writer.uint32( /* id 14, wireType 2 =*/ 114 ).fork()).ldelim(); if (message.typeProtos != null && message.typeProtos.length) for (var i = 0; i < message.typeProtos.length; ++i) $root.onnx.TypeProto.encode( message.typeProtos[i], writer.uint32( /* id 15, wireType 2 =*/ 122 ).fork() ).ldelim(); if (message.type != null && Object.hasOwnProperty.call(message, "type")) writer.uint32( /* id 20, wireType 0 =*/ 160 ).int32(message.type); if (message.refAttrName != null && Object.hasOwnProperty.call(message, "refAttrName")) writer.uint32( /* id 21, wireType 2 =*/ 170 ).string(message.refAttrName); if (message.sparseTensor != null && Object.hasOwnProperty.call(message, "sparseTensor")) $root.onnx.SparseTensorProto.encode( message.sparseTensor, writer.uint32( /* id 22, wireType 2 =*/ 178 ).fork() ).ldelim(); if (message.sparseTensors != null && message.sparseTensors.length) for (var i = 0; i < message.sparseTensors.length; ++i) $root.onnx.SparseTensorProto.encode( message.sparseTensors[i], writer.uint32( /* id 23, wireType 2 =*/ 186 ).fork() ).ldelim(); return writer; }; AttributeProto.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; AttributeProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.AttributeProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.name = reader.string(); break; } case 21: { message.refAttrName = reader.string(); break; } case 13: { message.docString = reader.string(); break; } case 20: { message.type = reader.int32(); break; } case 2: { message.f = reader.float(); break; } case 3: { message.i = reader.int64(); break; } case 4: { message.s = reader.bytes(); break; } case 5: { message.t = $root.onnx.TensorProto.decode(reader, reader.uint32()); break; } case 6: { message.g = $root.onnx.GraphProto.decode(reader, reader.uint32()); break; } case 22: { message.sparseTensor = $root.onnx.SparseTensorProto.decode(reader, reader.uint32()); break; } case 14: { message.tp = $root.onnx.TypeProto.decode(reader, reader.uint32()); break; } case 7: { if (!(message.floats && message.floats.length)) message.floats = []; if ((tag & 7) === 2) { var end2 = reader.uint32() + reader.pos; while (reader.pos < end2) message.floats.push(reader.float()); } else message.floats.push(reader.float()); break; } case 8: { if (!(message.ints && message.ints.length)) message.ints = []; if ((tag & 7) === 2) { var end2 = reader.uint32() + reader.pos; while (reader.pos < end2) message.ints.push(reader.int64()); } else message.ints.push(reader.int64()); break; } case 9: { if (!(message.strings && message.strings.length)) message.strings = []; message.strings.push(reader.bytes()); break; } case 10: { if (!(message.tensors && message.tensors.length)) message.tensors = []; message.tensors.push($root.onnx.TensorProto.decode(reader, reader.uint32())); break; } case 11: { if (!(message.graphs && message.graphs.length)) message.graphs = []; message.graphs.push($root.onnx.GraphProto.decode(reader, reader.uint32())); break; } case 23: { if (!(message.sparseTensors && message.sparseTensors.length)) message.sparseTensors = []; message.sparseTensors.push($root.onnx.SparseTensorProto.decode(reader, reader.uint32())); break; } case 15: { if (!(message.typeProtos && message.typeProtos.length)) message.typeProtos = []; message.typeProtos.push($root.onnx.TypeProto.decode(reader, reader.uint32())); break; } default: reader.skipType(tag & 7); break; } } return message; }; AttributeProto.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; AttributeProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.name != null && message.hasOwnProperty("name")) { if (!$util.isString(message.name)) return "name: string expected"; } if (message.refAttrName != null && message.hasOwnProperty("refAttrName")) { if (!$util.isString(message.refAttrName)) return "refAttrName: string expected"; } if (message.docString != null && message.hasOwnProperty("docString")) { if (!$util.isString(message.docString)) return "docString: string expected"; } if (message.type != null && message.hasOwnProperty("type")) switch (message.type) { default: return "type: enum value expected"; case 0: case 1: case 2: case 3: case 4: case 5: case 11: case 13: case 6: case 7: case 8: case 9: case 10: case 12: case 14: break; } if (message.f != null && message.hasOwnProperty("f")) { if (typeof message.f !== "number") return "f: number expected"; } if (message.i != null && message.hasOwnProperty("i")) { if (!$util.isInteger(message.i) && !(message.i && $util.isInteger(message.i.low) && $util.isInteger(message.i.high))) return "i: integer|Long expected"; } if (message.s != null && message.hasOwnProperty("s")) { if (!(message.s && typeof message.s.length === "number" || $util.isString(message.s))) return "s: buffer expected"; } if (message.t != null && message.hasOwnProperty("t")) { var error = $root.onnx.TensorProto.verify(message.t); if (error) return "t." + error; } if (message.g != null && message.hasOwnProperty("g")) { var error = $root.onnx.GraphProto.verify(message.g); if (error) return "g." + error; } if (message.sparseTensor != null && message.hasOwnProperty("sparseTensor")) { var error = $root.onnx.SparseTensorProto.verify(message.sparseTensor); if (error) return "sparseTensor." + error; } if (message.tp != null && message.hasOwnProperty("tp")) { var error = $root.onnx.TypeProto.verify(message.tp); if (error) return "tp." + error; } if (message.floats != null && message.hasOwnProperty("floats")) { if (!Array.isArray(message.floats)) return "floats: array expected"; for (var i = 0; i < message.floats.length; ++i) if (typeof message.floats[i] !== "number") return "floats: number[] expected"; } if (message.ints != null && message.hasOwnProperty("ints")) { if (!Array.isArray(message.ints)) return "ints: array expected"; for (var i = 0; i < message.ints.length; ++i) if (!$util.isInteger(message.ints[i]) && !(message.ints[i] && $util.isInteger(message.ints[i].low) && $util.isInteger(message.ints[i].high))) return "ints: integer|Long[] expected"; } if (message.strings != null && message.hasOwnProperty("strings")) { if (!Array.isArray(message.strings)) return "strings: array expected"; for (var i = 0; i < message.strings.length; ++i) if (!(message.strings[i] && typeof message.strings[i].length === "number" || $util.isString(message.strings[i]))) return "strings: buffer[] expected"; } if (message.tensors != null && message.hasOwnProperty("tensors")) { if (!Array.isArray(message.tensors)) return "tensors: array expected"; for (var i = 0; i < message.tensors.length; ++i) { var error = $root.onnx.TensorProto.verify(message.tensors[i]); if (error) return "tensors." + error; } } if (message.graphs != null && message.hasOwnProperty("graphs")) { if (!Array.isArray(message.graphs)) return "graphs: array expected"; for (var i = 0; i < message.graphs.length; ++i) { var error = $root.onnx.GraphProto.verify(message.graphs[i]); if (error) return "graphs." + error; } } if (message.sparseTensors != null && message.hasOwnProperty("sparseTensors")) { if (!Array.isArray(message.sparseTensors)) return "sparseTensors: array expected"; for (var i = 0; i < message.sparseTensors.length; ++i) { var error = $root.onnx.SparseTensorProto.verify(message.sparseTensors[i]); if (error) return "sparseTensors." + error; } } if (message.typeProtos != null && message.hasOwnProperty("typeProtos")) { if (!Array.isArray(message.typeProtos)) return "typeProtos: array expected"; for (var i = 0; i < message.typeProtos.length; ++i) { var error = $root.onnx.TypeProto.verify(message.typeProtos[i]); if (error) return "typeProtos." + error; } } return null; }; AttributeProto.fromObject = function fromObject(object) { if (object instanceof $root.onnx.AttributeProto) return object; var message = new $root.onnx.AttributeProto(); if (object.name != null) message.name = String(object.name); if (object.refAttrName != null) message.refAttrName = String(object.refAttrName); if (object.docString != null) message.docString = String(object.docString); switch (object.type) { default: if (typeof object.type === "number") { message.type = object.type; break; } break; case "UNDEFINED": case 0: message.type = 0; break; case "FLOAT": case 1: message.type = 1; break; case "INT": case 2: message.type = 2; break; case "STRING": case 3: message.type = 3; break; case "TENSOR": case 4: message.type = 4; break; case "GRAPH": case 5: message.type = 5; break; case "SPARSE_TENSOR": case 11: message.type = 11; break; case "TYPE_PROTO": case 13: message.type = 13; break; case "FLOATS": case 6: message.type = 6; break; case "INTS": case 7: message.type = 7; break; case "STRINGS": case 8: message.type = 8; break; case "TENSORS": case 9: message.type = 9; break; case "GRAPHS": case 10: message.type = 10; break; case "SPARSE_TENSORS": case 12: message.type = 12; break; case "TYPE_PROTOS": case 14: message.type = 14; break; } if (object.f != null) message.f = Number(object.f); if (object.i != null) { if ($util.Long) (message.i = $util.Long.fromValue(object.i)).unsigned = false; else if (typeof object.i === "string") message.i = parseInt(object.i, 10); else if (typeof object.i === "number") message.i = object.i; else if (typeof object.i === "object") message.i = new $util.LongBits(object.i.low >>> 0, object.i.high >>> 0).toNumber(); } if (object.s != null) { if (typeof object.s === "string") $util.base64.decode(object.s, message.s = $util.newBuffer($util.base64.length(object.s)), 0); else if (object.s.length >= 0) message.s = object.s; } if (object.t != null) { if (typeof object.t !== "object") throw TypeError(".onnx.AttributeProto.t: object expected"); message.t = $root.onnx.TensorProto.fromObject(object.t); } if (object.g != null) { if (typeof object.g !== "object") throw TypeError(".onnx.AttributeProto.g: object expected"); message.g = $root.onnx.GraphProto.fromObject(object.g); } if (object.sparseTensor != null) { if (typeof object.sparseTensor !== "object") throw TypeError(".onnx.AttributeProto.sparseTensor: object expected"); message.sparseTensor = $root.onnx.SparseTensorProto.fromObject(object.sparseTensor); } if (object.tp != null) { if (typeof object.tp !== "object") throw TypeError(".onnx.AttributeProto.tp: object expected"); message.tp = $root.onnx.TypeProto.fromObject(object.tp); } if (object.floats) { if (!Array.isArray(object.floats)) throw TypeError(".onnx.AttributeProto.floats: array expected"); message.floats = []; for (var i = 0; i < object.floats.length; ++i) message.floats[i] = Number(object.floats[i]); } if (object.ints) { if (!Array.isArray(object.ints)) throw TypeError(".onnx.AttributeProto.ints: array expected"); message.ints = []; for (var i = 0; i < object.ints.length; ++i) if ($util.Long) (message.ints[i] = $util.Long.fromValue(object.ints[i])).unsigned = false; else if (typeof object.ints[i] === "string") message.ints[i] = parseInt(object.ints[i], 10); else if (typeof object.ints[i] === "number") message.ints[i] = object.ints[i]; else if (typeof object.ints[i] === "object") message.ints[i] = new $util.LongBits(object.ints[i].low >>> 0, object.ints[i].high >>> 0).toNumber(); } if (object.strings) { if (!Array.isArray(object.strings)) throw TypeError(".onnx.AttributeProto.strings: array expected"); message.strings = []; for (var i = 0; i < object.strings.length; ++i) if (typeof object.strings[i] === "string") $util.base64.decode( object.strings[i], message.strings[i] = $util.newBuffer($util.base64.length(object.strings[i])), 0 ); else if (object.strings[i].length >= 0) message.strings[i] = object.strings[i]; } if (object.tensors) { if (!Array.isArray(object.tensors)) throw TypeError(".onnx.AttributeProto.tensors: array expected"); message.tensors = []; for (var i = 0; i < object.tensors.length; ++i) { if (typeof object.tensors[i] !== "object") throw TypeError(".onnx.AttributeProto.tensors: object expected"); message.tensors[i] = $root.onnx.TensorProto.fromObject(object.tensors[i]); } } if (object.graphs) { if (!Array.isArray(object.graphs)) throw TypeError(".onnx.AttributeProto.graphs: array expected"); message.graphs = []; for (var i = 0; i < object.graphs.length; ++i) { if (typeof object.graphs[i] !== "object") throw TypeError(".onnx.AttributeProto.graphs: object expected"); message.graphs[i] = $root.onnx.GraphProto.fromObject(object.graphs[i]); } } if (object.sparseTensors) { if (!Array.isArray(object.sparseTensors)) throw TypeError(".onnx.AttributeProto.sparseTensors: array expected"); message.sparseTensors = []; for (var i = 0; i < object.sparseTensors.length; ++i) { if (typeof object.sparseTensors[i] !== "object") throw TypeError(".onnx.AttributeProto.sparseTensors: object expected"); message.sparseTensors[i] = $root.onnx.SparseTensorProto.fromObject(object.sparseTensors[i]); } } if (object.typeProtos) { if (!Array.isArray(object.typeProtos)) throw TypeError(".onnx.AttributeProto.typeProtos: array expected"); message.typeProtos = []; for (var i = 0; i < object.typeProtos.length; ++i) { if (typeof object.typeProtos[i] !== "object") throw TypeError(".onnx.AttributeProto.typeProtos: object expected"); message.typeProtos[i] = $root.onnx.TypeProto.fromObject(object.typeProtos[i]); } } return message; }; AttributeProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.arrays || options.defaults) { object.floats = []; object.ints = []; object.strings = []; object.tensors = []; object.graphs = []; object.typeProtos = []; object.sparseTensors = []; } if (options.defaults) { object.name = ""; object.f = 0; if ($util.Long) { var long = new $util.Long(0, 0, false); object.i = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; } else object.i = options.longs === String ? "0" : 0; if (options.bytes === String) object.s = ""; else { object.s = []; if (options.bytes !== Array) object.s = $util.newBuffer(object.s); } object.t = null; object.g = null; object.docString = ""; object.tp = null; object.type = options.enums === String ? "UNDEFINED" : 0; object.refAttrName = ""; object.sparseTensor = null; } if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; if (message.f != null && message.hasOwnProperty("f")) object.f = options.json && !isFinite(message.f) ? String(message.f) : message.f; if (message.i != null && message.hasOwnProperty("i")) if (typeof message.i === "number") object.i = options.longs === String ? String(message.i) : message.i; else object.i = options.longs === String ? $util.Long.prototype.toString.call(message.i) : options.longs === Number ? new $util.LongBits(message.i.low >>> 0, message.i.high >>> 0).toNumber() : message.i; if (message.s != null && message.hasOwnProperty("s")) object.s = options.bytes === String ? $util.base64.encode(message.s, 0, message.s.length) : options.bytes === Array ? Array.prototype.slice.call(message.s) : message.s; if (message.t != null && message.hasOwnProperty("t")) object.t = $root.onnx.TensorProto.toObject(message.t, options); if (message.g != null && message.hasOwnProperty("g")) object.g = $root.onnx.GraphProto.toObject(message.g, options); if (message.floats && message.floats.length) { object.floats = []; for (var j = 0; j < message.floats.length; ++j) object.floats[j] = options.json && !isFinite(message.floats[j]) ? String(message.floats[j]) : message.floats[j]; } if (message.ints && message.ints.length) { object.ints = []; for (var j = 0; j < message.ints.length; ++j) if (typeof message.ints[j] === "number") object.ints[j] = options.longs === String ? String(message.ints[j]) : message.ints[j]; else object.ints[j] = options.longs === String ? $util.Long.prototype.toString.call(message.ints[j]) : options.longs === Number ? new $util.LongBits(message.ints[j].low >>> 0, message.ints[j].high >>> 0).toNumber() : message.ints[j]; } if (message.strings && message.strings.length) { object.strings = []; for (var j = 0; j < message.strings.length; ++j) object.strings[j] = options.bytes === String ? $util.base64.encode(message.strings[j], 0, message.strings[j].length) : options.bytes === Array ? Array.prototype.slice.call(message.strings[j]) : message.strings[j]; } if (message.tensors && message.tensors.length) { object.tensors = []; for (var j = 0; j < message.tensors.length; ++j) object.tensors[j] = $root.onnx.TensorProto.toObject(message.tensors[j], options); } if (message.graphs && message.graphs.length) { object.graphs = []; for (var j = 0; j < message.graphs.length; ++j) object.graphs[j] = $root.onnx.GraphProto.toObject(message.graphs[j], options); } if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; if (message.tp != null && message.hasOwnProperty("tp")) object.tp = $root.onnx.TypeProto.toObject(message.tp, options); if (message.typeProtos && message.typeProtos.length) { object.typeProtos = []; for (var j = 0; j < message.typeProtos.length; ++j) object.typeProtos[j] = $root.onnx.TypeProto.toObject(message.typeProtos[j], options); } if (message.type != null && message.hasOwnProperty("type")) object.type = options.enums === String ? $root.onnx.AttributeProto.AttributeType[message.type] === void 0 ? message.type : $root.onnx.AttributeProto.AttributeType[message.type] : message.type; if (message.refAttrName != null && message.hasOwnProperty("refAttrName")) object.refAttrName = message.refAttrName; if (message.sparseTensor != null && message.hasOwnProperty("sparseTensor")) object.sparseTensor = $root.onnx.SparseTensorProto.toObject(message.sparseTensor, options); if (message.sparseTensors && message.sparseTensors.length) { object.sparseTensors = []; for (var j = 0; j < message.sparseTensors.length; ++j) object.sparseTensors[j] = $root.onnx.SparseTensorProto.toObject(message.sparseTensors[j], options); } return object; }; AttributeProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; AttributeProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.AttributeProto"; }; AttributeProto.AttributeType = function() { var valuesById = {}, values = Object.create(valuesById); values[valuesById[0] = "UNDEFINED"] = 0; values[valuesById[1] = "FLOAT"] = 1; values[valuesById[2] = "INT"] = 2; values[valuesById[3] = "STRING"] = 3; values[valuesById[4] = "TENSOR"] = 4; values[valuesById[5] = "GRAPH"] = 5; values[valuesById[11] = "SPARSE_TENSOR"] = 11; values[valuesById[13] = "TYPE_PROTO"] = 13; values[valuesById[6] = "FLOATS"] = 6; values[valuesById[7] = "INTS"] = 7; values[valuesById[8] = "STRINGS"] = 8; values[valuesById[9] = "TENSORS"] = 9; values[valuesById[10] = "GRAPHS"] = 10; values[valuesById[12] = "SPARSE_TENSORS"] = 12; values[valuesById[14] = "TYPE_PROTOS"] = 14; return values; }(); return AttributeProto; }(); onnx6.ValueInfoProto = function() { function ValueInfoProto(properties) { if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } ValueInfoProto.prototype.name = ""; ValueInfoProto.prototype.type = null; ValueInfoProto.prototype.docString = ""; ValueInfoProto.create = function create(properties) { return new ValueInfoProto(properties); }; ValueInfoProto.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.name != null && Object.hasOwnProperty.call(message, "name")) writer.uint32( /* id 1, wireType 2 =*/ 10 ).string(message.name); if (message.type != null && Object.hasOwnProperty.call(message, "type")) $root.onnx.TypeProto.encode(message.type, writer.uint32( /* id 2, wireType 2 =*/ 18 ).fork()).ldelim(); if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) writer.uint32( /* id 3, wireType 2 =*/ 26 ).string(message.docString); return writer; }; ValueInfoProto.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; ValueInfoProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.ValueInfoProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.name = reader.string(); break; } case 2: { message.type = $root.onnx.TypeProto.decode(reader, reader.uint32()); break; } case 3: { message.docString = reader.string(); break; } default: reader.skipType(tag & 7); break; } } return message; }; ValueInfoProto.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; ValueInfoProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.name != null && message.hasOwnProperty("name")) { if (!$util.isString(message.name)) return "name: string expected"; } if (message.type != null && message.hasOwnProperty("type")) { var error = $root.onnx.TypeProto.verify(message.type); if (error) return "type." + error; } if (message.docString != null && message.hasOwnProperty("docString")) { if (!$util.isString(message.docString)) return "docString: string expected"; } return null; }; ValueInfoProto.fromObject = function fromObject(object) { if (object instanceof $root.onnx.ValueInfoProto) return object; var message = new $root.onnx.ValueInfoProto(); if (object.name != null) message.name = String(object.name); if (object.type != null) { if (typeof object.type !== "object") throw TypeError(".onnx.ValueInfoProto.type: object expected"); message.type = $root.onnx.TypeProto.fromObject(object.type); } if (object.docString != null) message.docString = String(object.docString); return message; }; ValueInfoProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { object.name = ""; object.type = null; object.docString = ""; } if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; if (message.type != null && message.hasOwnProperty("type")) object.type = $root.onnx.TypeProto.toObject(message.type, options); if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; return object; }; ValueInfoProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; ValueInfoProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.ValueInfoProto"; }; return ValueInfoProto; }(); onnx6.NodeProto = function() { function NodeProto(properties) { this.input = []; this.output = []; this.attribute = []; if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } NodeProto.prototype.input = $util.emptyArray; NodeProto.prototype.output = $util.emptyArray; NodeProto.prototype.name = ""; NodeProto.prototype.opType = ""; NodeProto.prototype.domain = ""; NodeProto.prototype.attribute = $util.emptyArray; NodeProto.prototype.docString = ""; NodeProto.create = function create(properties) { return new NodeProto(properties); }; NodeProto.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.input != null && message.input.length) for (var i = 0; i < message.input.length; ++i) writer.uint32( /* id 1, wireType 2 =*/ 10 ).string(message.input[i]); if (message.output != null && message.output.length) for (var i = 0; i < message.output.length; ++i) writer.uint32( /* id 2, wireType 2 =*/ 18 ).string(message.output[i]); if (message.name != null && Object.hasOwnProperty.call(message, "name")) writer.uint32( /* id 3, wireType 2 =*/ 26 ).string(message.name); if (message.opType != null && Object.hasOwnProperty.call(message, "opType")) writer.uint32( /* id 4, wireType 2 =*/ 34 ).string(message.opType); if (message.attribute != null && message.attribute.length) for (var i = 0; i < message.attribute.length; ++i) $root.onnx.AttributeProto.encode( message.attribute[i], writer.uint32( /* id 5, wireType 2 =*/ 42 ).fork() ).ldelim(); if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) writer.uint32( /* id 6, wireType 2 =*/ 50 ).string(message.docString); if (message.domain != null && Object.hasOwnProperty.call(message, "domain")) writer.uint32( /* id 7, wireType 2 =*/ 58 ).string(message.domain); return writer; }; NodeProto.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; NodeProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.NodeProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { if (!(message.input && message.input.length)) message.input = []; message.input.push(reader.string()); break; } case 2: { if (!(message.output && message.output.length)) message.output = []; message.output.push(reader.string()); break; } case 3: { message.name = reader.string(); break; } case 4: { message.opType = reader.string(); break; } case 7: { message.domain = reader.string(); break; } case 5: { if (!(message.attribute && message.attribute.length)) message.attribute = []; message.attribute.push($root.onnx.AttributeProto.decode(reader, reader.uint32())); break; } case 6: { message.docString = reader.string(); break; } default: reader.skipType(tag & 7); break; } } return message; }; NodeProto.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; NodeProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.input != null && message.hasOwnProperty("input")) { if (!Array.isArray(message.input)) return "input: array expected"; for (var i = 0; i < message.input.length; ++i) if (!$util.isString(message.input[i])) return "input: string[] expected"; } if (message.output != null && message.hasOwnProperty("output")) { if (!Array.isArray(message.output)) return "output: array expected"; for (var i = 0; i < message.output.length; ++i) if (!$util.isString(message.output[i])) return "output: string[] expected"; } if (message.name != null && message.hasOwnProperty("name")) { if (!$util.isString(message.name)) return "name: string expected"; } if (message.opType != null && message.hasOwnProperty("opType")) { if (!$util.isString(message.opType)) return "opType: string expected"; } if (message.domain != null && message.hasOwnProperty("domain")) { if (!$util.isString(message.domain)) return "domain: string expected"; } if (message.attribute != null && message.hasOwnProperty("attribute")) { if (!Array.isArray(message.attribute)) return "attribute: array expected"; for (var i = 0; i < message.attribute.length; ++i) { var error = $root.onnx.AttributeProto.verify(message.attribute[i]); if (error) return "attribute." + error; } } if (message.docString != null && message.hasOwnProperty("docString")) { if (!$util.isString(message.docString)) return "docString: string expected"; } return null; }; NodeProto.fromObject = function fromObject(object) { if (object instanceof $root.onnx.NodeProto) return object; var message = new $root.onnx.NodeProto(); if (object.input) { if (!Array.isArray(object.input)) throw TypeError(".onnx.NodeProto.input: array expected"); message.input = []; for (var i = 0; i < object.input.length; ++i) message.input[i] = String(object.input[i]); } if (object.output) { if (!Array.isArray(object.output)) throw TypeError(".onnx.NodeProto.output: array expected"); message.output = []; for (var i = 0; i < object.output.length; ++i) message.output[i] = String(object.output[i]); } if (object.name != null) message.name = String(object.name); if (object.opType != null) message.opType = String(object.opType); if (object.domain != null) message.domain = String(object.domain); if (object.attribute) { if (!Array.isArray(object.attribute)) throw TypeError(".onnx.NodeProto.attribute: array expected"); message.attribute = []; for (var i = 0; i < object.attribute.length; ++i) { if (typeof object.attribute[i] !== "object") throw TypeError(".onnx.NodeProto.attribute: object expected"); message.attribute[i] = $root.onnx.AttributeProto.fromObject(object.attribute[i]); } } if (object.docString != null) message.docString = String(object.docString); return message; }; NodeProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.arrays || options.defaults) { object.input = []; object.output = []; object.attribute = []; } if (options.defaults) { object.name = ""; object.opType = ""; object.docString = ""; object.domain = ""; } if (message.input && message.input.length) { object.input = []; for (var j = 0; j < message.input.length; ++j) object.input[j] = message.input[j]; } if (message.output && message.output.length) { object.output = []; for (var j = 0; j < message.output.length; ++j) object.output[j] = message.output[j]; } if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; if (message.opType != null && message.hasOwnProperty("opType")) object.opType = message.opType; if (message.attribute && message.attribute.length) { object.attribute = []; for (var j = 0; j < message.attribute.length; ++j) object.attribute[j] = $root.onnx.AttributeProto.toObject(message.attribute[j], options); } if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; if (message.domain != null && message.hasOwnProperty("domain")) object.domain = message.domain; return object; }; NodeProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; NodeProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.NodeProto"; }; return NodeProto; }(); onnx6.TrainingInfoProto = function() { function TrainingInfoProto(properties) { this.initializationBinding = []; this.updateBinding = []; if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } TrainingInfoProto.prototype.initialization = null; TrainingInfoProto.prototype.algorithm = null; TrainingInfoProto.prototype.initializationBinding = $util.emptyArray; TrainingInfoProto.prototype.updateBinding = $util.emptyArray; TrainingInfoProto.create = function create(properties) { return new TrainingInfoProto(properties); }; TrainingInfoProto.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.initialization != null && Object.hasOwnProperty.call(message, "initialization")) $root.onnx.GraphProto.encode(message.initialization, writer.uint32( /* id 1, wireType 2 =*/ 10 ).fork()).ldelim(); if (message.algorithm != null && Object.hasOwnProperty.call(message, "algorithm")) $root.onnx.GraphProto.encode(message.algorithm, writer.uint32( /* id 2, wireType 2 =*/ 18 ).fork()).ldelim(); if (message.initializationBinding != null && message.initializationBinding.length) for (var i = 0; i < message.initializationBinding.length; ++i) $root.onnx.StringStringEntryProto.encode( message.initializationBinding[i], writer.uint32( /* id 3, wireType 2 =*/ 26 ).fork() ).ldelim(); if (message.updateBinding != null && message.updateBinding.length) for (var i = 0; i < message.updateBinding.length; ++i) $root.onnx.StringStringEntryProto.encode( message.updateBinding[i], writer.uint32( /* id 4, wireType 2 =*/ 34 ).fork() ).ldelim(); return writer; }; TrainingInfoProto.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; TrainingInfoProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TrainingInfoProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.initialization = $root.onnx.GraphProto.decode(reader, reader.uint32()); break; } case 2: { message.algorithm = $root.onnx.GraphProto.decode(reader, reader.uint32()); break; } case 3: { if (!(message.initializationBinding && message.initializationBinding.length)) message.initializationBinding = []; message.initializationBinding.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); break; } case 4: { if (!(message.updateBinding && message.updateBinding.length)) message.updateBinding = []; message.updateBinding.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); break; } default: reader.skipType(tag & 7); break; } } return message; }; TrainingInfoProto.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; TrainingInfoProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.initialization != null && message.hasOwnProperty("initialization")) { var error = $root.onnx.GraphProto.verify(message.initialization); if (error) return "initialization." + error; } if (message.algorithm != null && message.hasOwnProperty("algorithm")) { var error = $root.onnx.GraphProto.verify(message.algorithm); if (error) return "algorithm." + error; } if (message.initializationBinding != null && message.hasOwnProperty("initializationBinding")) { if (!Array.isArray(message.initializationBinding)) return "initializationBinding: array expected"; for (var i = 0; i < message.initializationBinding.length; ++i) { var error = $root.onnx.StringStringEntryProto.verify(message.initializationBinding[i]); if (error) return "initializationBinding." + error; } } if (message.updateBinding != null && message.hasOwnProperty("updateBinding")) { if (!Array.isArray(message.updateBinding)) return "updateBinding: array expected"; for (var i = 0; i < message.updateBinding.length; ++i) { var error = $root.onnx.StringStringEntryProto.verify(message.updateBinding[i]); if (error) return "updateBinding." + error; } } return null; }; TrainingInfoProto.fromObject = function fromObject(object) { if (object instanceof $root.onnx.TrainingInfoProto) return object; var message = new $root.onnx.TrainingInfoProto(); if (object.initialization != null) { if (typeof object.initialization !== "object") throw TypeError(".onnx.TrainingInfoProto.initialization: object expected"); message.initialization = $root.onnx.GraphProto.fromObject(object.initialization); } if (object.algorithm != null) { if (typeof object.algorithm !== "object") throw TypeError(".onnx.TrainingInfoProto.algorithm: object expected"); message.algorithm = $root.onnx.GraphProto.fromObject(object.algorithm); } if (object.initializationBinding) { if (!Array.isArray(object.initializationBinding)) throw TypeError(".onnx.TrainingInfoProto.initializationBinding: array expected"); message.initializationBinding = []; for (var i = 0; i < object.initializationBinding.length; ++i) { if (typeof object.initializationBinding[i] !== "object") throw TypeError(".onnx.TrainingInfoProto.initializationBinding: object expected"); message.initializationBinding[i] = $root.onnx.StringStringEntryProto.fromObject( object.initializationBinding[i] ); } } if (object.updateBinding) { if (!Array.isArray(object.updateBinding)) throw TypeError(".onnx.TrainingInfoProto.updateBinding: array expected"); message.updateBinding = []; for (var i = 0; i < object.updateBinding.length; ++i) { if (typeof object.updateBinding[i] !== "object") throw TypeError(".onnx.TrainingInfoProto.updateBinding: object expected"); message.updateBinding[i] = $root.onnx.StringStringEntryProto.fromObject(object.updateBinding[i]); } } return message; }; TrainingInfoProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.arrays || options.defaults) { object.initializationBinding = []; object.updateBinding = []; } if (options.defaults) { object.initialization = null; object.algorithm = null; } if (message.initialization != null && message.hasOwnProperty("initialization")) object.initialization = $root.onnx.GraphProto.toObject(message.initialization, options); if (message.algorithm != null && message.hasOwnProperty("algorithm")) object.algorithm = $root.onnx.GraphProto.toObject(message.algorithm, options); if (message.initializationBinding && message.initializationBinding.length) { object.initializationBinding = []; for (var j = 0; j < message.initializationBinding.length; ++j) object.initializationBinding[j] = $root.onnx.StringStringEntryProto.toObject( message.initializationBinding[j], options ); } if (message.updateBinding && message.updateBinding.length) { object.updateBinding = []; for (var j = 0; j < message.updateBinding.length; ++j) object.updateBinding[j] = $root.onnx.StringStringEntryProto.toObject(message.updateBinding[j], options); } return object; }; TrainingInfoProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; TrainingInfoProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TrainingInfoProto"; }; return TrainingInfoProto; }(); onnx6.ModelProto = function() { function ModelProto(properties) { this.opsetImport = []; this.metadataProps = []; this.trainingInfo = []; this.functions = []; if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } ModelProto.prototype.irVersion = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; ModelProto.prototype.opsetImport = $util.emptyArray; ModelProto.prototype.producerName = ""; ModelProto.prototype.producerVersion = ""; ModelProto.prototype.domain = ""; ModelProto.prototype.modelVersion = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; ModelProto.prototype.docString = ""; ModelProto.prototype.graph = null; ModelProto.prototype.metadataProps = $util.emptyArray; ModelProto.prototype.trainingInfo = $util.emptyArray; ModelProto.prototype.functions = $util.emptyArray; ModelProto.create = function create(properties) { return new ModelProto(properties); }; ModelProto.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.irVersion != null && Object.hasOwnProperty.call(message, "irVersion")) writer.uint32( /* id 1, wireType 0 =*/ 8 ).int64(message.irVersion); if (message.producerName != null && Object.hasOwnProperty.call(message, "producerName")) writer.uint32( /* id 2, wireType 2 =*/ 18 ).string(message.producerName); if (message.producerVersion != null && Object.hasOwnProperty.call(message, "producerVersion")) writer.uint32( /* id 3, wireType 2 =*/ 26 ).string(message.producerVersion); if (message.domain != null && Object.hasOwnProperty.call(message, "domain")) writer.uint32( /* id 4, wireType 2 =*/ 34 ).string(message.domain); if (message.modelVersion != null && Object.hasOwnProperty.call(message, "modelVersion")) writer.uint32( /* id 5, wireType 0 =*/ 40 ).int64(message.modelVersion); if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) writer.uint32( /* id 6, wireType 2 =*/ 50 ).string(message.docString); if (message.graph != null && Object.hasOwnProperty.call(message, "graph")) $root.onnx.GraphProto.encode(message.graph, writer.uint32( /* id 7, wireType 2 =*/ 58 ).fork()).ldelim(); if (message.opsetImport != null && message.opsetImport.length) for (var i = 0; i < message.opsetImport.length; ++i) $root.onnx.OperatorSetIdProto.encode( message.opsetImport[i], writer.uint32( /* id 8, wireType 2 =*/ 66 ).fork() ).ldelim(); if (message.metadataProps != null && message.metadataProps.length) for (var i = 0; i < message.metadataProps.length; ++i) $root.onnx.StringStringEntryProto.encode( message.metadataProps[i], writer.uint32( /* id 14, wireType 2 =*/ 114 ).fork() ).ldelim(); if (message.trainingInfo != null && message.trainingInfo.length) for (var i = 0; i < message.trainingInfo.length; ++i) $root.onnx.TrainingInfoProto.encode( message.trainingInfo[i], writer.uint32( /* id 20, wireType 2 =*/ 162 ).fork() ).ldelim(); if (message.functions != null && message.functions.length) for (var i = 0; i < message.functions.length; ++i) $root.onnx.FunctionProto.encode( message.functions[i], writer.uint32( /* id 25, wireType 2 =*/ 202 ).fork() ).ldelim(); return writer; }; ModelProto.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; ModelProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.ModelProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.irVersion = reader.int64(); break; } case 8: { if (!(message.opsetImport && message.opsetImport.length)) message.opsetImport = []; message.opsetImport.push($root.onnx.OperatorSetIdProto.decode(reader, reader.uint32())); break; } case 2: { message.producerName = reader.string(); break; } case 3: { message.producerVersion = reader.string(); break; } case 4: { message.domain = reader.string(); break; } case 5: { message.modelVersion = reader.int64(); break; } case 6: { message.docString = reader.string(); break; } case 7: { message.graph = $root.onnx.GraphProto.decode(reader, reader.uint32()); break; } case 14: { if (!(message.metadataProps && message.metadataProps.length)) message.metadataProps = []; message.metadataProps.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); break; } case 20: { if (!(message.trainingInfo && message.trainingInfo.length)) message.trainingInfo = []; message.trainingInfo.push($root.onnx.TrainingInfoProto.decode(reader, reader.uint32())); break; } case 25: { if (!(message.functions && message.functions.length)) message.functions = []; message.functions.push($root.onnx.FunctionProto.decode(reader, reader.uint32())); break; } default: reader.skipType(tag & 7); break; } } return message; }; ModelProto.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; ModelProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.irVersion != null && message.hasOwnProperty("irVersion")) { if (!$util.isInteger(message.irVersion) && !(message.irVersion && $util.isInteger(message.irVersion.low) && $util.isInteger(message.irVersion.high))) return "irVersion: integer|Long expected"; } if (message.opsetImport != null && message.hasOwnProperty("opsetImport")) { if (!Array.isArray(message.opsetImport)) return "opsetImport: array expected"; for (var i = 0; i < message.opsetImport.length; ++i) { var error = $root.onnx.OperatorSetIdProto.verify(message.opsetImport[i]); if (error) return "opsetImport." + error; } } if (message.producerName != null && message.hasOwnProperty("producerName")) { if (!$util.isString(message.producerName)) return "producerName: string expected"; } if (message.producerVersion != null && message.hasOwnProperty("producerVersion")) { if (!$util.isString(message.producerVersion)) return "producerVersion: string expected"; } if (message.domain != null && message.hasOwnProperty("domain")) { if (!$util.isString(message.domain)) return "domain: string expected"; } if (message.modelVersion != null && message.hasOwnProperty("modelVersion")) { if (!$util.isInteger(message.modelVersion) && !(message.modelVersion && $util.isInteger(message.modelVersion.low) && $util.isInteger(message.modelVersion.high))) return "modelVersion: integer|Long expected"; } if (message.docString != null && message.hasOwnProperty("docString")) { if (!$util.isString(message.docString)) return "docString: string expected"; } if (message.graph != null && message.hasOwnProperty("graph")) { var error = $root.onnx.GraphProto.verify(message.graph); if (error) return "graph." + error; } if (message.metadataProps != null && message.hasOwnProperty("metadataProps")) { if (!Array.isArray(message.metadataProps)) return "metadataProps: array expected"; for (var i = 0; i < message.metadataProps.length; ++i) { var error = $root.onnx.StringStringEntryProto.verify(message.metadataProps[i]); if (error) return "metadataProps." + error; } } if (message.trainingInfo != null && message.hasOwnProperty("trainingInfo")) { if (!Array.isArray(message.trainingInfo)) return "trainingInfo: array expected"; for (var i = 0; i < message.trainingInfo.length; ++i) { var error = $root.onnx.TrainingInfoProto.verify(message.trainingInfo[i]); if (error) return "trainingInfo." + error; } } if (message.functions != null && message.hasOwnProperty("functions")) { if (!Array.isArray(message.functions)) return "functions: array expected"; for (var i = 0; i < message.functions.length; ++i) { var error = $root.onnx.FunctionProto.verify(message.functions[i]); if (error) return "functions." + error; } } return null; }; ModelProto.fromObject = function fromObject(object) { if (object instanceof $root.onnx.ModelProto) return object; var message = new $root.onnx.ModelProto(); if (object.irVersion != null) { if ($util.Long) (message.irVersion = $util.Long.fromValue(object.irVersion)).unsigned = false; else if (typeof object.irVersion === "string") message.irVersion = parseInt(object.irVersion, 10); else if (typeof object.irVersion === "number") message.irVersion = object.irVersion; else if (typeof object.irVersion === "object") message.irVersion = new $util.LongBits(object.irVersion.low >>> 0, object.irVersion.high >>> 0).toNumber(); } if (object.opsetImport) { if (!Array.isArray(object.opsetImport)) throw TypeError(".onnx.ModelProto.opsetImport: array expected"); message.opsetImport = []; for (var i = 0; i < object.opsetImport.length; ++i) { if (typeof object.opsetImport[i] !== "object") throw TypeError(".onnx.ModelProto.opsetImport: object expected"); message.opsetImport[i] = $root.onnx.OperatorSetIdProto.fromObject(object.opsetImport[i]); } } if (object.producerName != null) message.producerName = String(object.producerName); if (object.producerVersion != null) message.producerVersion = String(object.producerVersion); if (object.domain != null) message.domain = String(object.domain); if (object.modelVersion != null) { if ($util.Long) (message.modelVersion = $util.Long.fromValue(object.modelVersion)).unsigned = false; else if (typeof object.modelVersion === "string") message.modelVersion = parseInt(object.modelVersion, 10); else if (typeof object.modelVersion === "number") message.modelVersion = object.modelVersion; else if (typeof object.modelVersion === "object") message.modelVersion = new $util.LongBits( object.modelVersion.low >>> 0, object.modelVersion.high >>> 0 ).toNumber(); } if (object.docString != null) message.docString = String(object.docString); if (object.graph != null) { if (typeof object.graph !== "object") throw TypeError(".onnx.ModelProto.graph: object expected"); message.graph = $root.onnx.GraphProto.fromObject(object.graph); } if (object.metadataProps) { if (!Array.isArray(object.metadataProps)) throw TypeError(".onnx.ModelProto.metadataProps: array expected"); message.metadataProps = []; for (var i = 0; i < object.metadataProps.length; ++i) { if (typeof object.metadataProps[i] !== "object") throw TypeError(".onnx.ModelProto.metadataProps: object expected"); message.metadataProps[i] = $root.onnx.StringStringEntryProto.fromObject(object.metadataProps[i]); } } if (object.trainingInfo) { if (!Array.isArray(object.trainingInfo)) throw TypeError(".onnx.ModelProto.trainingInfo: array expected"); message.trainingInfo = []; for (var i = 0; i < object.trainingInfo.length; ++i) { if (typeof object.trainingInfo[i] !== "object") throw TypeError(".onnx.ModelProto.trainingInfo: object expected"); message.trainingInfo[i] = $root.onnx.TrainingInfoProto.fromObject(object.trainingInfo[i]); } } if (object.functions) { if (!Array.isArray(object.functions)) throw TypeError(".onnx.ModelProto.functions: array expected"); message.functions = []; for (var i = 0; i < object.functions.length; ++i) { if (typeof object.functions[i] !== "object") throw TypeError(".onnx.ModelProto.functions: object expected"); message.functions[i] = $root.onnx.FunctionProto.fromObject(object.functions[i]); } } return message; }; ModelProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.arrays || options.defaults) { object.opsetImport = []; object.metadataProps = []; object.trainingInfo = []; object.functions = []; } if (options.defaults) { if ($util.Long) { var long = new $util.Long(0, 0, false); object.irVersion = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; } else object.irVersion = options.longs === String ? "0" : 0; object.producerName = ""; object.producerVersion = ""; object.domain = ""; if ($util.Long) { var long = new $util.Long(0, 0, false); object.modelVersion = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; } else object.modelVersion = options.longs === String ? "0" : 0; object.docString = ""; object.graph = null; } if (message.irVersion != null && message.hasOwnProperty("irVersion")) if (typeof message.irVersion === "number") object.irVersion = options.longs === String ? String(message.irVersion) : message.irVersion; else object.irVersion = options.longs === String ? $util.Long.prototype.toString.call(message.irVersion) : options.longs === Number ? new $util.LongBits(message.irVersion.low >>> 0, message.irVersion.high >>> 0).toNumber() : message.irVersion; if (message.producerName != null && message.hasOwnProperty("producerName")) object.producerName = message.producerName; if (message.producerVersion != null && message.hasOwnProperty("producerVersion")) object.producerVersion = message.producerVersion; if (message.domain != null && message.hasOwnProperty("domain")) object.domain = message.domain; if (message.modelVersion != null && message.hasOwnProperty("modelVersion")) if (typeof message.modelVersion === "number") object.modelVersion = options.longs === String ? String(message.modelVersion) : message.modelVersion; else object.modelVersion = options.longs === String ? $util.Long.prototype.toString.call(message.modelVersion) : options.longs === Number ? new $util.LongBits(message.modelVersion.low >>> 0, message.modelVersion.high >>> 0).toNumber() : message.modelVersion; if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; if (message.graph != null && message.hasOwnProperty("graph")) object.graph = $root.onnx.GraphProto.toObject(message.graph, options); if (message.opsetImport && message.opsetImport.length) { object.opsetImport = []; for (var j = 0; j < message.opsetImport.length; ++j) object.opsetImport[j] = $root.onnx.OperatorSetIdProto.toObject(message.opsetImport[j], options); } if (message.metadataProps && message.metadataProps.length) { object.metadataProps = []; for (var j = 0; j < message.metadataProps.length; ++j) object.metadataProps[j] = $root.onnx.StringStringEntryProto.toObject(message.metadataProps[j], options); } if (message.trainingInfo && message.trainingInfo.length) { object.trainingInfo = []; for (var j = 0; j < message.trainingInfo.length; ++j) object.trainingInfo[j] = $root.onnx.TrainingInfoProto.toObject(message.trainingInfo[j], options); } if (message.functions && message.functions.length) { object.functions = []; for (var j = 0; j < message.functions.length; ++j) object.functions[j] = $root.onnx.FunctionProto.toObject(message.functions[j], options); } return object; }; ModelProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; ModelProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.ModelProto"; }; return ModelProto; }(); onnx6.StringStringEntryProto = function() { function StringStringEntryProto(properties) { if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } StringStringEntryProto.prototype.key = ""; StringStringEntryProto.prototype.value = ""; StringStringEntryProto.create = function create(properties) { return new StringStringEntryProto(properties); }; StringStringEntryProto.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.key != null && Object.hasOwnProperty.call(message, "key")) writer.uint32( /* id 1, wireType 2 =*/ 10 ).string(message.key); if (message.value != null && Object.hasOwnProperty.call(message, "value")) writer.uint32( /* id 2, wireType 2 =*/ 18 ).string(message.value); return writer; }; StringStringEntryProto.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; StringStringEntryProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.StringStringEntryProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.key = reader.string(); break; } case 2: { message.value = reader.string(); break; } default: reader.skipType(tag & 7); break; } } return message; }; StringStringEntryProto.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; StringStringEntryProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.key != null && message.hasOwnProperty("key")) { if (!$util.isString(message.key)) return "key: string expected"; } if (message.value != null && message.hasOwnProperty("value")) { if (!$util.isString(message.value)) return "value: string expected"; } return null; }; StringStringEntryProto.fromObject = function fromObject(object) { if (object instanceof $root.onnx.StringStringEntryProto) return object; var message = new $root.onnx.StringStringEntryProto(); if (object.key != null) message.key = String(object.key); if (object.value != null) message.value = String(object.value); return message; }; StringStringEntryProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { object.key = ""; object.value = ""; } if (message.key != null && message.hasOwnProperty("key")) object.key = message.key; if (message.value != null && message.hasOwnProperty("value")) object.value = message.value; return object; }; StringStringEntryProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; StringStringEntryProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.StringStringEntryProto"; }; return StringStringEntryProto; }(); onnx6.TensorAnnotation = function() { function TensorAnnotation(properties) { this.quantParameterTensorNames = []; if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } TensorAnnotation.prototype.tensorName = ""; TensorAnnotation.prototype.quantParameterTensorNames = $util.emptyArray; TensorAnnotation.create = function create(properties) { return new TensorAnnotation(properties); }; TensorAnnotation.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.tensorName != null && Object.hasOwnProperty.call(message, "tensorName")) writer.uint32( /* id 1, wireType 2 =*/ 10 ).string(message.tensorName); if (message.quantParameterTensorNames != null && message.quantParameterTensorNames.length) for (var i = 0; i < message.quantParameterTensorNames.length; ++i) $root.onnx.StringStringEntryProto.encode( message.quantParameterTensorNames[i], writer.uint32( /* id 2, wireType 2 =*/ 18 ).fork() ).ldelim(); return writer; }; TensorAnnotation.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; TensorAnnotation.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorAnnotation(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.tensorName = reader.string(); break; } case 2: { if (!(message.quantParameterTensorNames && message.quantParameterTensorNames.length)) message.quantParameterTensorNames = []; message.quantParameterTensorNames.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); break; } default: reader.skipType(tag & 7); break; } } return message; }; TensorAnnotation.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; TensorAnnotation.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.tensorName != null && message.hasOwnProperty("tensorName")) { if (!$util.isString(message.tensorName)) return "tensorName: string expected"; } if (message.quantParameterTensorNames != null && message.hasOwnProperty("quantParameterTensorNames")) { if (!Array.isArray(message.quantParameterTensorNames)) return "quantParameterTensorNames: array expected"; for (var i = 0; i < message.quantParameterTensorNames.length; ++i) { var error = $root.onnx.StringStringEntryProto.verify(message.quantParameterTensorNames[i]); if (error) return "quantParameterTensorNames." + error; } } return null; }; TensorAnnotation.fromObject = function fromObject(object) { if (object instanceof $root.onnx.TensorAnnotation) return object; var message = new $root.onnx.TensorAnnotation(); if (object.tensorName != null) message.tensorName = String(object.tensorName); if (object.quantParameterTensorNames) { if (!Array.isArray(object.quantParameterTensorNames)) throw TypeError(".onnx.TensorAnnotation.quantParameterTensorNames: array expected"); message.quantParameterTensorNames = []; for (var i = 0; i < object.quantParameterTensorNames.length; ++i) { if (typeof object.quantParameterTensorNames[i] !== "object") throw TypeError(".onnx.TensorAnnotation.quantParameterTensorNames: object expected"); message.quantParameterTensorNames[i] = $root.onnx.StringStringEntryProto.fromObject( object.quantParameterTensorNames[i] ); } } return message; }; TensorAnnotation.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.arrays || options.defaults) object.quantParameterTensorNames = []; if (options.defaults) object.tensorName = ""; if (message.tensorName != null && message.hasOwnProperty("tensorName")) object.tensorName = message.tensorName; if (message.quantParameterTensorNames && message.quantParameterTensorNames.length) { object.quantParameterTensorNames = []; for (var j = 0; j < message.quantParameterTensorNames.length; ++j) object.quantParameterTensorNames[j] = $root.onnx.StringStringEntryProto.toObject( message.quantParameterTensorNames[j], options ); } return object; }; TensorAnnotation.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; TensorAnnotation.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TensorAnnotation"; }; return TensorAnnotation; }(); onnx6.GraphProto = function() { function GraphProto(properties) { this.node = []; this.initializer = []; this.sparseInitializer = []; this.input = []; this.output = []; this.valueInfo = []; this.quantizationAnnotation = []; if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } GraphProto.prototype.node = $util.emptyArray; GraphProto.prototype.name = ""; GraphProto.prototype.initializer = $util.emptyArray; GraphProto.prototype.sparseInitializer = $util.emptyArray; GraphProto.prototype.docString = ""; GraphProto.prototype.input = $util.emptyArray; GraphProto.prototype.output = $util.emptyArray; GraphProto.prototype.valueInfo = $util.emptyArray; GraphProto.prototype.quantizationAnnotation = $util.emptyArray; GraphProto.create = function create(properties) { return new GraphProto(properties); }; GraphProto.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.node != null && message.node.length) for (var i = 0; i < message.node.length; ++i) $root.onnx.NodeProto.encode(message.node[i], writer.uint32( /* id 1, wireType 2 =*/ 10 ).fork()).ldelim(); if (message.name != null && Object.hasOwnProperty.call(message, "name")) writer.uint32( /* id 2, wireType 2 =*/ 18 ).string(message.name); if (message.initializer != null && message.initializer.length) for (var i = 0; i < message.initializer.length; ++i) $root.onnx.TensorProto.encode( message.initializer[i], writer.uint32( /* id 5, wireType 2 =*/ 42 ).fork() ).ldelim(); if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) writer.uint32( /* id 10, wireType 2 =*/ 82 ).string(message.docString); if (message.input != null && message.input.length) for (var i = 0; i < message.input.length; ++i) $root.onnx.ValueInfoProto.encode( message.input[i], writer.uint32( /* id 11, wireType 2 =*/ 90 ).fork() ).ldelim(); if (message.output != null && message.output.length) for (var i = 0; i < message.output.length; ++i) $root.onnx.ValueInfoProto.encode( message.output[i], writer.uint32( /* id 12, wireType 2 =*/ 98 ).fork() ).ldelim(); if (message.valueInfo != null && message.valueInfo.length) for (var i = 0; i < message.valueInfo.length; ++i) $root.onnx.ValueInfoProto.encode( message.valueInfo[i], writer.uint32( /* id 13, wireType 2 =*/ 106 ).fork() ).ldelim(); if (message.quantizationAnnotation != null && message.quantizationAnnotation.length) for (var i = 0; i < message.quantizationAnnotation.length; ++i) $root.onnx.TensorAnnotation.encode( message.quantizationAnnotation[i], writer.uint32( /* id 14, wireType 2 =*/ 114 ).fork() ).ldelim(); if (message.sparseInitializer != null && message.sparseInitializer.length) for (var i = 0; i < message.sparseInitializer.length; ++i) $root.onnx.SparseTensorProto.encode( message.sparseInitializer[i], writer.uint32( /* id 15, wireType 2 =*/ 122 ).fork() ).ldelim(); return writer; }; GraphProto.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; GraphProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.GraphProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { if (!(message.node && message.node.length)) message.node = []; message.node.push($root.onnx.NodeProto.decode(reader, reader.uint32())); break; } case 2: { message.name = reader.string(); break; } case 5: { if (!(message.initializer && message.initializer.length)) message.initializer = []; message.initializer.push($root.onnx.TensorProto.decode(reader, reader.uint32())); break; } case 15: { if (!(message.sparseInitializer && message.sparseInitializer.length)) message.sparseInitializer = []; message.sparseInitializer.push($root.onnx.SparseTensorProto.decode(reader, reader.uint32())); break; } case 10: { message.docString = reader.string(); break; } case 11: { if (!(message.input && message.input.length)) message.input = []; message.input.push($root.onnx.ValueInfoProto.decode(reader, reader.uint32())); break; } case 12: { if (!(message.output && message.output.length)) message.output = []; message.output.push($root.onnx.ValueInfoProto.decode(reader, reader.uint32())); break; } case 13: { if (!(message.valueInfo && message.valueInfo.length)) message.valueInfo = []; message.valueInfo.push($root.onnx.ValueInfoProto.decode(reader, reader.uint32())); break; } case 14: { if (!(message.quantizationAnnotation && message.quantizationAnnotation.length)) message.quantizationAnnotation = []; message.quantizationAnnotation.push($root.onnx.TensorAnnotation.decode(reader, reader.uint32())); break; } default: reader.skipType(tag & 7); break; } } return message; }; GraphProto.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; GraphProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.node != null && message.hasOwnProperty("node")) { if (!Array.isArray(message.node)) return "node: array expected"; for (var i = 0; i < message.node.length; ++i) { var error = $root.onnx.NodeProto.verify(message.node[i]); if (error) return "node." + error; } } if (message.name != null && message.hasOwnProperty("name")) { if (!$util.isString(message.name)) return "name: string expected"; } if (message.initializer != null && message.hasOwnProperty("initializer")) { if (!Array.isArray(message.initializer)) return "initializer: array expected"; for (var i = 0; i < message.initializer.length; ++i) { var error = $root.onnx.TensorProto.verify(message.initializer[i]); if (error) return "initializer." + error; } } if (message.sparseInitializer != null && message.hasOwnProperty("sparseInitializer")) { if (!Array.isArray(message.sparseInitializer)) return "sparseInitializer: array expected"; for (var i = 0; i < message.sparseInitializer.length; ++i) { var error = $root.onnx.SparseTensorProto.verify(message.sparseInitializer[i]); if (error) return "sparseInitializer." + error; } } if (message.docString != null && message.hasOwnProperty("docString")) { if (!$util.isString(message.docString)) return "docString: string expected"; } if (message.input != null && message.hasOwnProperty("input")) { if (!Array.isArray(message.input)) return "input: array expected"; for (var i = 0; i < message.input.length; ++i) { var error = $root.onnx.ValueInfoProto.verify(message.input[i]); if (error) return "input." + error; } } if (message.output != null && message.hasOwnProperty("output")) { if (!Array.isArray(message.output)) return "output: array expected"; for (var i = 0; i < message.output.length; ++i) { var error = $root.onnx.ValueInfoProto.verify(message.output[i]); if (error) return "output." + error; } } if (message.valueInfo != null && message.hasOwnProperty("valueInfo")) { if (!Array.isArray(message.valueInfo)) return "valueInfo: array expected"; for (var i = 0; i < message.valueInfo.length; ++i) { var error = $root.onnx.ValueInfoProto.verify(message.valueInfo[i]); if (error) return "valueInfo." + error; } } if (message.quantizationAnnotation != null && message.hasOwnProperty("quantizationAnnotation")) { if (!Array.isArray(message.quantizationAnnotation)) return "quantizationAnnotation: array expected"; for (var i = 0; i < message.quantizationAnnotation.length; ++i) { var error = $root.onnx.TensorAnnotation.verify(message.quantizationAnnotation[i]); if (error) return "quantizationAnnotation." + error; } } return null; }; GraphProto.fromObject = function fromObject(object) { if (object instanceof $root.onnx.GraphProto) return object; var message = new $root.onnx.GraphProto(); if (object.node) { if (!Array.isArray(object.node)) throw TypeError(".onnx.GraphProto.node: array expected"); message.node = []; for (var i = 0; i < object.node.length; ++i) { if (typeof object.node[i] !== "object") throw TypeError(".onnx.GraphProto.node: object expected"); message.node[i] = $root.onnx.NodeProto.fromObject(object.node[i]); } } if (object.name != null) message.name = String(object.name); if (object.initializer) { if (!Array.isArray(object.initializer)) throw TypeError(".onnx.GraphProto.initializer: array expected"); message.initializer = []; for (var i = 0; i < object.initializer.length; ++i) { if (typeof object.initializer[i] !== "object") throw TypeError(".onnx.GraphProto.initializer: object expected"); message.initializer[i] = $root.onnx.TensorProto.fromObject(object.initializer[i]); } } if (object.sparseInitializer) { if (!Array.isArray(object.sparseInitializer)) throw TypeError(".onnx.GraphProto.sparseInitializer: array expected"); message.sparseInitializer = []; for (var i = 0; i < object.sparseInitializer.length; ++i) { if (typeof object.sparseInitializer[i] !== "object") throw TypeError(".onnx.GraphProto.sparseInitializer: object expected"); message.sparseInitializer[i] = $root.onnx.SparseTensorProto.fromObject(object.sparseInitializer[i]); } } if (object.docString != null) message.docString = String(object.docString); if (object.input) { if (!Array.isArray(object.input)) throw TypeError(".onnx.GraphProto.input: array expected"); message.input = []; for (var i = 0; i < object.input.length; ++i) { if (typeof object.input[i] !== "object") throw TypeError(".onnx.GraphProto.input: object expected"); message.input[i] = $root.onnx.ValueInfoProto.fromObject(object.input[i]); } } if (object.output) { if (!Array.isArray(object.output)) throw TypeError(".onnx.GraphProto.output: array expected"); message.output = []; for (var i = 0; i < object.output.length; ++i) { if (typeof object.output[i] !== "object") throw TypeError(".onnx.GraphProto.output: object expected"); message.output[i] = $root.onnx.ValueInfoProto.fromObject(object.output[i]); } } if (object.valueInfo) { if (!Array.isArray(object.valueInfo)) throw TypeError(".onnx.GraphProto.valueInfo: array expected"); message.valueInfo = []; for (var i = 0; i < object.valueInfo.length; ++i) { if (typeof object.valueInfo[i] !== "object") throw TypeError(".onnx.GraphProto.valueInfo: object expected"); message.valueInfo[i] = $root.onnx.ValueInfoProto.fromObject(object.valueInfo[i]); } } if (object.quantizationAnnotation) { if (!Array.isArray(object.quantizationAnnotation)) throw TypeError(".onnx.GraphProto.quantizationAnnotation: array expected"); message.quantizationAnnotation = []; for (var i = 0; i < object.quantizationAnnotation.length; ++i) { if (typeof object.quantizationAnnotation[i] !== "object") throw TypeError(".onnx.GraphProto.quantizationAnnotation: object expected"); message.quantizationAnnotation[i] = $root.onnx.TensorAnnotation.fromObject(object.quantizationAnnotation[i]); } } return message; }; GraphProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.arrays || options.defaults) { object.node = []; object.initializer = []; object.input = []; object.output = []; object.valueInfo = []; object.quantizationAnnotation = []; object.sparseInitializer = []; } if (options.defaults) { object.name = ""; object.docString = ""; } if (message.node && message.node.length) { object.node = []; for (var j = 0; j < message.node.length; ++j) object.node[j] = $root.onnx.NodeProto.toObject(message.node[j], options); } if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; if (message.initializer && message.initializer.length) { object.initializer = []; for (var j = 0; j < message.initializer.length; ++j) object.initializer[j] = $root.onnx.TensorProto.toObject(message.initializer[j], options); } if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; if (message.input && message.input.length) { object.input = []; for (var j = 0; j < message.input.length; ++j) object.input[j] = $root.onnx.ValueInfoProto.toObject(message.input[j], options); } if (message.output && message.output.length) { object.output = []; for (var j = 0; j < message.output.length; ++j) object.output[j] = $root.onnx.ValueInfoProto.toObject(message.output[j], options); } if (message.valueInfo && message.valueInfo.length) { object.valueInfo = []; for (var j = 0; j < message.valueInfo.length; ++j) object.valueInfo[j] = $root.onnx.ValueInfoProto.toObject(message.valueInfo[j], options); } if (message.quantizationAnnotation && message.quantizationAnnotation.length) { object.quantizationAnnotation = []; for (var j = 0; j < message.quantizationAnnotation.length; ++j) object.quantizationAnnotation[j] = $root.onnx.TensorAnnotation.toObject( message.quantizationAnnotation[j], options ); } if (message.sparseInitializer && message.sparseInitializer.length) { object.sparseInitializer = []; for (var j = 0; j < message.sparseInitializer.length; ++j) object.sparseInitializer[j] = $root.onnx.SparseTensorProto.toObject(message.sparseInitializer[j], options); } return object; }; GraphProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; GraphProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.GraphProto"; }; return GraphProto; }(); onnx6.TensorProto = function() { function TensorProto(properties) { this.dims = []; this.floatData = []; this.int32Data = []; this.stringData = []; this.int64Data = []; this.externalData = []; this.doubleData = []; this.uint64Data = []; if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } TensorProto.prototype.dims = $util.emptyArray; TensorProto.prototype.dataType = 0; TensorProto.prototype.segment = null; TensorProto.prototype.floatData = $util.emptyArray; TensorProto.prototype.int32Data = $util.emptyArray; TensorProto.prototype.stringData = $util.emptyArray; TensorProto.prototype.int64Data = $util.emptyArray; TensorProto.prototype.name = ""; TensorProto.prototype.docString = ""; TensorProto.prototype.rawData = $util.newBuffer([]); TensorProto.prototype.externalData = $util.emptyArray; TensorProto.prototype.dataLocation = 0; TensorProto.prototype.doubleData = $util.emptyArray; TensorProto.prototype.uint64Data = $util.emptyArray; TensorProto.create = function create(properties) { return new TensorProto(properties); }; TensorProto.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.dims != null && message.dims.length) { writer.uint32( /* id 1, wireType 2 =*/ 10 ).fork(); for (var i = 0; i < message.dims.length; ++i) writer.int64(message.dims[i]); writer.ldelim(); } if (message.dataType != null && Object.hasOwnProperty.call(message, "dataType")) writer.uint32( /* id 2, wireType 0 =*/ 16 ).int32(message.dataType); if (message.segment != null && Object.hasOwnProperty.call(message, "segment")) $root.onnx.TensorProto.Segment.encode( message.segment, writer.uint32( /* id 3, wireType 2 =*/ 26 ).fork() ).ldelim(); if (message.floatData != null && message.floatData.length) { writer.uint32( /* id 4, wireType 2 =*/ 34 ).fork(); for (var i = 0; i < message.floatData.length; ++i) writer.float(message.floatData[i]); writer.ldelim(); } if (message.int32Data != null && message.int32Data.length) { writer.uint32( /* id 5, wireType 2 =*/ 42 ).fork(); for (var i = 0; i < message.int32Data.length; ++i) writer.int32(message.int32Data[i]); writer.ldelim(); } if (message.stringData != null && message.stringData.length) for (var i = 0; i < message.stringData.length; ++i) writer.uint32( /* id 6, wireType 2 =*/ 50 ).bytes(message.stringData[i]); if (message.int64Data != null && message.int64Data.length) { writer.uint32( /* id 7, wireType 2 =*/ 58 ).fork(); for (var i = 0; i < message.int64Data.length; ++i) writer.int64(message.int64Data[i]); writer.ldelim(); } if (message.name != null && Object.hasOwnProperty.call(message, "name")) writer.uint32( /* id 8, wireType 2 =*/ 66 ).string(message.name); if (message.rawData != null && Object.hasOwnProperty.call(message, "rawData")) writer.uint32( /* id 9, wireType 2 =*/ 74 ).bytes(message.rawData); if (message.doubleData != null && message.doubleData.length) { writer.uint32( /* id 10, wireType 2 =*/ 82 ).fork(); for (var i = 0; i < message.doubleData.length; ++i) writer.double(message.doubleData[i]); writer.ldelim(); } if (message.uint64Data != null && message.uint64Data.length) { writer.uint32( /* id 11, wireType 2 =*/ 90 ).fork(); for (var i = 0; i < message.uint64Data.length; ++i) writer.uint64(message.uint64Data[i]); writer.ldelim(); } if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) writer.uint32( /* id 12, wireType 2 =*/ 98 ).string(message.docString); if (message.externalData != null && message.externalData.length) for (var i = 0; i < message.externalData.length; ++i) $root.onnx.StringStringEntryProto.encode( message.externalData[i], writer.uint32( /* id 13, wireType 2 =*/ 106 ).fork() ).ldelim(); if (message.dataLocation != null && Object.hasOwnProperty.call(message, "dataLocation")) writer.uint32( /* id 14, wireType 0 =*/ 112 ).int32(message.dataLocation); return writer; }; TensorProto.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; TensorProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { if (!(message.dims && message.dims.length)) message.dims = []; if ((tag & 7) === 2) { var end2 = reader.uint32() + reader.pos; while (reader.pos < end2) message.dims.push(reader.int64()); } else message.dims.push(reader.int64()); break; } case 2: { message.dataType = reader.int32(); break; } case 3: { message.segment = $root.onnx.TensorProto.Segment.decode(reader, reader.uint32()); break; } case 4: { if (!(message.floatData && message.floatData.length)) message.floatData = []; if ((tag & 7) === 2) { var end2 = reader.uint32() + reader.pos; while (reader.pos < end2) message.floatData.push(reader.float()); } else message.floatData.push(reader.float()); break; } case 5: { if (!(message.int32Data && message.int32Data.length)) message.int32Data = []; if ((tag & 7) === 2) { var end2 = reader.uint32() + reader.pos; while (reader.pos < end2) message.int32Data.push(reader.int32()); } else message.int32Data.push(reader.int32()); break; } case 6: { if (!(message.stringData && message.stringData.length)) message.stringData = []; message.stringData.push(reader.bytes()); break; } case 7: { if (!(message.int64Data && message.int64Data.length)) message.int64Data = []; if ((tag & 7) === 2) { var end2 = reader.uint32() + reader.pos; while (reader.pos < end2) message.int64Data.push(reader.int64()); } else message.int64Data.push(reader.int64()); break; } case 8: { message.name = reader.string(); break; } case 12: { message.docString = reader.string(); break; } case 9: { message.rawData = reader.bytes(); break; } case 13: { if (!(message.externalData && message.externalData.length)) message.externalData = []; message.externalData.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); break; } case 14: { message.dataLocation = reader.int32(); break; } case 10: { if (!(message.doubleData && message.doubleData.length)) message.doubleData = []; if ((tag & 7) === 2) { var end2 = reader.uint32() + reader.pos; while (reader.pos < end2) message.doubleData.push(reader.double()); } else message.doubleData.push(reader.double()); break; } case 11: { if (!(message.uint64Data && message.uint64Data.length)) message.uint64Data = []; if ((tag & 7) === 2) { var end2 = reader.uint32() + reader.pos; while (reader.pos < end2) message.uint64Data.push(reader.uint64()); } else message.uint64Data.push(reader.uint64()); break; } default: reader.skipType(tag & 7); break; } } return message; }; TensorProto.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; TensorProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.dims != null && message.hasOwnProperty("dims")) { if (!Array.isArray(message.dims)) return "dims: array expected"; for (var i = 0; i < message.dims.length; ++i) if (!$util.isInteger(message.dims[i]) && !(message.dims[i] && $util.isInteger(message.dims[i].low) && $util.isInteger(message.dims[i].high))) return "dims: integer|Long[] expected"; } if (message.dataType != null && message.hasOwnProperty("dataType")) { if (!$util.isInteger(message.dataType)) return "dataType: integer expected"; } if (message.segment != null && message.hasOwnProperty("segment")) { var error = $root.onnx.TensorProto.Segment.verify(message.segment); if (error) return "segment." + error; } if (message.floatData != null && message.hasOwnProperty("floatData")) { if (!Array.isArray(message.floatData)) return "floatData: array expected"; for (var i = 0; i < message.floatData.length; ++i) if (typeof message.floatData[i] !== "number") return "floatData: number[] expected"; } if (message.int32Data != null && message.hasOwnProperty("int32Data")) { if (!Array.isArray(message.int32Data)) return "int32Data: array expected"; for (var i = 0; i < message.int32Data.length; ++i) if (!$util.isInteger(message.int32Data[i])) return "int32Data: integer[] expected"; } if (message.stringData != null && message.hasOwnProperty("stringData")) { if (!Array.isArray(message.stringData)) return "stringData: array expected"; for (var i = 0; i < message.stringData.length; ++i) if (!(message.stringData[i] && typeof message.stringData[i].length === "number" || $util.isString(message.stringData[i]))) return "stringData: buffer[] expected"; } if (message.int64Data != null && message.hasOwnProperty("int64Data")) { if (!Array.isArray(message.int64Data)) return "int64Data: array expected"; for (var i = 0; i < message.int64Data.length; ++i) if (!$util.isInteger(message.int64Data[i]) && !(message.int64Data[i] && $util.isInteger(message.int64Data[i].low) && $util.isInteger(message.int64Data[i].high))) return "int64Data: integer|Long[] expected"; } if (message.name != null && message.hasOwnProperty("name")) { if (!$util.isString(message.name)) return "name: string expected"; } if (message.docString != null && message.hasOwnProperty("docString")) { if (!$util.isString(message.docString)) return "docString: string expected"; } if (message.rawData != null && message.hasOwnProperty("rawData")) { if (!(message.rawData && typeof message.rawData.length === "number" || $util.isString(message.rawData))) return "rawData: buffer expected"; } if (message.externalData != null && message.hasOwnProperty("externalData")) { if (!Array.isArray(message.externalData)) return "externalData: array expected"; for (var i = 0; i < message.externalData.length; ++i) { var error = $root.onnx.StringStringEntryProto.verify(message.externalData[i]); if (error) return "externalData." + error; } } if (message.dataLocation != null && message.hasOwnProperty("dataLocation")) switch (message.dataLocation) { default: return "dataLocation: enum value expected"; case 0: case 1: break; } if (message.doubleData != null && message.hasOwnProperty("doubleData")) { if (!Array.isArray(message.doubleData)) return "doubleData: array expected"; for (var i = 0; i < message.doubleData.length; ++i) if (typeof message.doubleData[i] !== "number") return "doubleData: number[] expected"; } if (message.uint64Data != null && message.hasOwnProperty("uint64Data")) { if (!Array.isArray(message.uint64Data)) return "uint64Data: array expected"; for (var i = 0; i < message.uint64Data.length; ++i) if (!$util.isInteger(message.uint64Data[i]) && !(message.uint64Data[i] && $util.isInteger(message.uint64Data[i].low) && $util.isInteger(message.uint64Data[i].high))) return "uint64Data: integer|Long[] expected"; } return null; }; TensorProto.fromObject = function fromObject(object) { if (object instanceof $root.onnx.TensorProto) return object; var message = new $root.onnx.TensorProto(); if (object.dims) { if (!Array.isArray(object.dims)) throw TypeError(".onnx.TensorProto.dims: array expected"); message.dims = []; for (var i = 0; i < object.dims.length; ++i) if ($util.Long) (message.dims[i] = $util.Long.fromValue(object.dims[i])).unsigned = false; else if (typeof object.dims[i] === "string") message.dims[i] = parseInt(object.dims[i], 10); else if (typeof object.dims[i] === "number") message.dims[i] = object.dims[i]; else if (typeof object.dims[i] === "object") message.dims[i] = new $util.LongBits(object.dims[i].low >>> 0, object.dims[i].high >>> 0).toNumber(); } if (object.dataType != null) message.dataType = object.dataType | 0; if (object.segment != null) { if (typeof object.segment !== "object") throw TypeError(".onnx.TensorProto.segment: object expected"); message.segment = $root.onnx.TensorProto.Segment.fromObject(object.segment); } if (object.floatData) { if (!Array.isArray(object.floatData)) throw TypeError(".onnx.TensorProto.floatData: array expected"); message.floatData = []; for (var i = 0; i < object.floatData.length; ++i) message.floatData[i] = Number(object.floatData[i]); } if (object.int32Data) { if (!Array.isArray(object.int32Data)) throw TypeError(".onnx.TensorProto.int32Data: array expected"); message.int32Data = []; for (var i = 0; i < object.int32Data.length; ++i) message.int32Data[i] = object.int32Data[i] | 0; } if (object.stringData) { if (!Array.isArray(object.stringData)) throw TypeError(".onnx.TensorProto.stringData: array expected"); message.stringData = []; for (var i = 0; i < object.stringData.length; ++i) if (typeof object.stringData[i] === "string") $util.base64.decode( object.stringData[i], message.stringData[i] = $util.newBuffer($util.base64.length(object.stringData[i])), 0 ); else if (object.stringData[i].length >= 0) message.stringData[i] = object.stringData[i]; } if (object.int64Data) { if (!Array.isArray(object.int64Data)) throw TypeError(".onnx.TensorProto.int64Data: array expected"); message.int64Data = []; for (var i = 0; i < object.int64Data.length; ++i) if ($util.Long) (message.int64Data[i] = $util.Long.fromValue(object.int64Data[i])).unsigned = false; else if (typeof object.int64Data[i] === "string") message.int64Data[i] = parseInt(object.int64Data[i], 10); else if (typeof object.int64Data[i] === "number") message.int64Data[i] = object.int64Data[i]; else if (typeof object.int64Data[i] === "object") message.int64Data[i] = new $util.LongBits( object.int64Data[i].low >>> 0, object.int64Data[i].high >>> 0 ).toNumber(); } if (object.name != null) message.name = String(object.name); if (object.docString != null) message.docString = String(object.docString); if (object.rawData != null) { if (typeof object.rawData === "string") $util.base64.decode( object.rawData, message.rawData = $util.newBuffer($util.base64.length(object.rawData)), 0 ); else if (object.rawData.length >= 0) message.rawData = object.rawData; } if (object.externalData) { if (!Array.isArray(object.externalData)) throw TypeError(".onnx.TensorProto.externalData: array expected"); message.externalData = []; for (var i = 0; i < object.externalData.length; ++i) { if (typeof object.externalData[i] !== "object") throw TypeError(".onnx.TensorProto.externalData: object expected"); message.externalData[i] = $root.onnx.StringStringEntryProto.fromObject(object.externalData[i]); } } switch (object.dataLocation) { default: if (typeof object.dataLocation === "number") { message.dataLocation = object.dataLocation; break; } break; case "DEFAULT": case 0: message.dataLocation = 0; break; case "EXTERNAL": case 1: message.dataLocation = 1; break; } if (object.doubleData) { if (!Array.isArray(object.doubleData)) throw TypeError(".onnx.TensorProto.doubleData: array expected"); message.doubleData = []; for (var i = 0; i < object.doubleData.length; ++i) message.doubleData[i] = Number(object.doubleData[i]); } if (object.uint64Data) { if (!Array.isArray(object.uint64Data)) throw TypeError(".onnx.TensorProto.uint64Data: array expected"); message.uint64Data = []; for (var i = 0; i < object.uint64Data.length; ++i) if ($util.Long) (message.uint64Data[i] = $util.Long.fromValue(object.uint64Data[i])).unsigned = true; else if (typeof object.uint64Data[i] === "string") message.uint64Data[i] = parseInt(object.uint64Data[i], 10); else if (typeof object.uint64Data[i] === "number") message.uint64Data[i] = object.uint64Data[i]; else if (typeof object.uint64Data[i] === "object") message.uint64Data[i] = new $util.LongBits( object.uint64Data[i].low >>> 0, object.uint64Data[i].high >>> 0 ).toNumber(true); } return message; }; TensorProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.arrays || options.defaults) { object.dims = []; object.floatData = []; object.int32Data = []; object.stringData = []; object.int64Data = []; object.doubleData = []; object.uint64Data = []; object.externalData = []; } if (options.defaults) { object.dataType = 0; object.segment = null; object.name = ""; if (options.bytes === String) object.rawData = ""; else { object.rawData = []; if (options.bytes !== Array) object.rawData = $util.newBuffer(object.rawData); } object.docString = ""; object.dataLocation = options.enums === String ? "DEFAULT" : 0; } if (message.dims && message.dims.length) { object.dims = []; for (var j = 0; j < message.dims.length; ++j) if (typeof message.dims[j] === "number") object.dims[j] = options.longs === String ? String(message.dims[j]) : message.dims[j]; else object.dims[j] = options.longs === String ? $util.Long.prototype.toString.call(message.dims[j]) : options.longs === Number ? new $util.LongBits(message.dims[j].low >>> 0, message.dims[j].high >>> 0).toNumber() : message.dims[j]; } if (message.dataType != null && message.hasOwnProperty("dataType")) object.dataType = message.dataType; if (message.segment != null && message.hasOwnProperty("segment")) object.segment = $root.onnx.TensorProto.Segment.toObject(message.segment, options); if (message.floatData && message.floatData.length) { object.floatData = []; for (var j = 0; j < message.floatData.length; ++j) object.floatData[j] = options.json && !isFinite(message.floatData[j]) ? String(message.floatData[j]) : message.floatData[j]; } if (message.int32Data && message.int32Data.length) { object.int32Data = []; for (var j = 0; j < message.int32Data.length; ++j) object.int32Data[j] = message.int32Data[j]; } if (message.stringData && message.stringData.length) { object.stringData = []; for (var j = 0; j < message.stringData.length; ++j) object.stringData[j] = options.bytes === String ? $util.base64.encode(message.stringData[j], 0, message.stringData[j].length) : options.bytes === Array ? Array.prototype.slice.call(message.stringData[j]) : message.stringData[j]; } if (message.int64Data && message.int64Data.length) { object.int64Data = []; for (var j = 0; j < message.int64Data.length; ++j) if (typeof message.int64Data[j] === "number") object.int64Data[j] = options.longs === String ? String(message.int64Data[j]) : message.int64Data[j]; else object.int64Data[j] = options.longs === String ? $util.Long.prototype.toString.call(message.int64Data[j]) : options.longs === Number ? new $util.LongBits(message.int64Data[j].low >>> 0, message.int64Data[j].high >>> 0).toNumber() : message.int64Data[j]; } if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; if (message.rawData != null && message.hasOwnProperty("rawData")) object.rawData = options.bytes === String ? $util.base64.encode(message.rawData, 0, message.rawData.length) : options.bytes === Array ? Array.prototype.slice.call(message.rawData) : message.rawData; if (message.doubleData && message.doubleData.length) { object.doubleData = []; for (var j = 0; j < message.doubleData.length; ++j) object.doubleData[j] = options.json && !isFinite(message.doubleData[j]) ? String(message.doubleData[j]) : message.doubleData[j]; } if (message.uint64Data && message.uint64Data.length) { object.uint64Data = []; for (var j = 0; j < message.uint64Data.length; ++j) if (typeof message.uint64Data[j] === "number") object.uint64Data[j] = options.longs === String ? String(message.uint64Data[j]) : message.uint64Data[j]; else object.uint64Data[j] = options.longs === String ? $util.Long.prototype.toString.call(message.uint64Data[j]) : options.longs === Number ? new $util.LongBits(message.uint64Data[j].low >>> 0, message.uint64Data[j].high >>> 0).toNumber(true) : message.uint64Data[j]; } if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; if (message.externalData && message.externalData.length) { object.externalData = []; for (var j = 0; j < message.externalData.length; ++j) object.externalData[j] = $root.onnx.StringStringEntryProto.toObject(message.externalData[j], options); } if (message.dataLocation != null && message.hasOwnProperty("dataLocation")) object.dataLocation = options.enums === String ? $root.onnx.TensorProto.DataLocation[message.dataLocation] === void 0 ? message.dataLocation : $root.onnx.TensorProto.DataLocation[message.dataLocation] : message.dataLocation; return object; }; TensorProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; TensorProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TensorProto"; }; TensorProto.DataType = function() { var valuesById = {}, values = Object.create(valuesById); values[valuesById[0] = "UNDEFINED"] = 0; values[valuesById[1] = "FLOAT"] = 1; values[valuesById[2] = "UINT8"] = 2; values[valuesById[3] = "INT8"] = 3; values[valuesById[4] = "UINT16"] = 4; values[valuesById[5] = "INT16"] = 5; values[valuesById[6] = "INT32"] = 6; values[valuesById[7] = "INT64"] = 7; values[valuesById[8] = "STRING"] = 8; values[valuesById[9] = "BOOL"] = 9; values[valuesById[10] = "FLOAT16"] = 10; values[valuesById[11] = "DOUBLE"] = 11; values[valuesById[12] = "UINT32"] = 12; values[valuesById[13] = "UINT64"] = 13; values[valuesById[14] = "COMPLEX64"] = 14; values[valuesById[15] = "COMPLEX128"] = 15; values[valuesById[16] = "BFLOAT16"] = 16; values[valuesById[17] = "FLOAT8E4M3FN"] = 17; values[valuesById[18] = "FLOAT8E4M3FNUZ"] = 18; values[valuesById[19] = "FLOAT8E5M2"] = 19; values[valuesById[20] = "FLOAT8E5M2FNUZ"] = 20; return values; }(); TensorProto.Segment = function() { function Segment(properties) { if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } Segment.prototype.begin = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; Segment.prototype.end = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; Segment.create = function create(properties) { return new Segment(properties); }; Segment.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.begin != null && Object.hasOwnProperty.call(message, "begin")) writer.uint32( /* id 1, wireType 0 =*/ 8 ).int64(message.begin); if (message.end != null && Object.hasOwnProperty.call(message, "end")) writer.uint32( /* id 2, wireType 0 =*/ 16 ).int64(message.end); return writer; }; Segment.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; Segment.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorProto.Segment(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.begin = reader.int64(); break; } case 2: { message.end = reader.int64(); break; } default: reader.skipType(tag & 7); break; } } return message; }; Segment.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; Segment.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.begin != null && message.hasOwnProperty("begin")) { if (!$util.isInteger(message.begin) && !(message.begin && $util.isInteger(message.begin.low) && $util.isInteger(message.begin.high))) return "begin: integer|Long expected"; } if (message.end != null && message.hasOwnProperty("end")) { if (!$util.isInteger(message.end) && !(message.end && $util.isInteger(message.end.low) && $util.isInteger(message.end.high))) return "end: integer|Long expected"; } return null; }; Segment.fromObject = function fromObject(object) { if (object instanceof $root.onnx.TensorProto.Segment) return object; var message = new $root.onnx.TensorProto.Segment(); if (object.begin != null) { if ($util.Long) (message.begin = $util.Long.fromValue(object.begin)).unsigned = false; else if (typeof object.begin === "string") message.begin = parseInt(object.begin, 10); else if (typeof object.begin === "number") message.begin = object.begin; else if (typeof object.begin === "object") message.begin = new $util.LongBits(object.begin.low >>> 0, object.begin.high >>> 0).toNumber(); } if (object.end != null) { if ($util.Long) (message.end = $util.Long.fromValue(object.end)).unsigned = false; else if (typeof object.end === "string") message.end = parseInt(object.end, 10); else if (typeof object.end === "number") message.end = object.end; else if (typeof object.end === "object") message.end = new $util.LongBits(object.end.low >>> 0, object.end.high >>> 0).toNumber(); } return message; }; Segment.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { if ($util.Long) { var long = new $util.Long(0, 0, false); object.begin = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; } else object.begin = options.longs === String ? "0" : 0; if ($util.Long) { var long = new $util.Long(0, 0, false); object.end = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; } else object.end = options.longs === String ? "0" : 0; } if (message.begin != null && message.hasOwnProperty("begin")) if (typeof message.begin === "number") object.begin = options.longs === String ? String(message.begin) : message.begin; else object.begin = options.longs === String ? $util.Long.prototype.toString.call(message.begin) : options.longs === Number ? new $util.LongBits(message.begin.low >>> 0, message.begin.high >>> 0).toNumber() : message.begin; if (message.end != null && message.hasOwnProperty("end")) if (typeof message.end === "number") object.end = options.longs === String ? String(message.end) : message.end; else object.end = options.longs === String ? $util.Long.prototype.toString.call(message.end) : options.longs === Number ? new $util.LongBits(message.end.low >>> 0, message.end.high >>> 0).toNumber() : message.end; return object; }; Segment.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; Segment.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TensorProto.Segment"; }; return Segment; }(); TensorProto.DataLocation = function() { var valuesById = {}, values = Object.create(valuesById); values[valuesById[0] = "DEFAULT"] = 0; values[valuesById[1] = "EXTERNAL"] = 1; return values; }(); return TensorProto; }(); onnx6.SparseTensorProto = function() { function SparseTensorProto(properties) { this.dims = []; if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } SparseTensorProto.prototype.values = null; SparseTensorProto.prototype.indices = null; SparseTensorProto.prototype.dims = $util.emptyArray; SparseTensorProto.create = function create(properties) { return new SparseTensorProto(properties); }; SparseTensorProto.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.values != null && Object.hasOwnProperty.call(message, "values")) $root.onnx.TensorProto.encode(message.values, writer.uint32( /* id 1, wireType 2 =*/ 10 ).fork()).ldelim(); if (message.indices != null && Object.hasOwnProperty.call(message, "indices")) $root.onnx.TensorProto.encode(message.indices, writer.uint32( /* id 2, wireType 2 =*/ 18 ).fork()).ldelim(); if (message.dims != null && message.dims.length) { writer.uint32( /* id 3, wireType 2 =*/ 26 ).fork(); for (var i = 0; i < message.dims.length; ++i) writer.int64(message.dims[i]); writer.ldelim(); } return writer; }; SparseTensorProto.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; SparseTensorProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.SparseTensorProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.values = $root.onnx.TensorProto.decode(reader, reader.uint32()); break; } case 2: { message.indices = $root.onnx.TensorProto.decode(reader, reader.uint32()); break; } case 3: { if (!(message.dims && message.dims.length)) message.dims = []; if ((tag & 7) === 2) { var end2 = reader.uint32() + reader.pos; while (reader.pos < end2) message.dims.push(reader.int64()); } else message.dims.push(reader.int64()); break; } default: reader.skipType(tag & 7); break; } } return message; }; SparseTensorProto.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; SparseTensorProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.values != null && message.hasOwnProperty("values")) { var error = $root.onnx.TensorProto.verify(message.values); if (error) return "values." + error; } if (message.indices != null && message.hasOwnProperty("indices")) { var error = $root.onnx.TensorProto.verify(message.indices); if (error) return "indices." + error; } if (message.dims != null && message.hasOwnProperty("dims")) { if (!Array.isArray(message.dims)) return "dims: array expected"; for (var i = 0; i < message.dims.length; ++i) if (!$util.isInteger(message.dims[i]) && !(message.dims[i] && $util.isInteger(message.dims[i].low) && $util.isInteger(message.dims[i].high))) return "dims: integer|Long[] expected"; } return null; }; SparseTensorProto.fromObject = function fromObject(object) { if (object instanceof $root.onnx.SparseTensorProto) return object; var message = new $root.onnx.SparseTensorProto(); if (object.values != null) { if (typeof object.values !== "object") throw TypeError(".onnx.SparseTensorProto.values: object expected"); message.values = $root.onnx.TensorProto.fromObject(object.values); } if (object.indices != null) { if (typeof object.indices !== "object") throw TypeError(".onnx.SparseTensorProto.indices: object expected"); message.indices = $root.onnx.TensorProto.fromObject(object.indices); } if (object.dims) { if (!Array.isArray(object.dims)) throw TypeError(".onnx.SparseTensorProto.dims: array expected"); message.dims = []; for (var i = 0; i < object.dims.length; ++i) if ($util.Long) (message.dims[i] = $util.Long.fromValue(object.dims[i])).unsigned = false; else if (typeof object.dims[i] === "string") message.dims[i] = parseInt(object.dims[i], 10); else if (typeof object.dims[i] === "number") message.dims[i] = object.dims[i]; else if (typeof object.dims[i] === "object") message.dims[i] = new $util.LongBits(object.dims[i].low >>> 0, object.dims[i].high >>> 0).toNumber(); } return message; }; SparseTensorProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.arrays || options.defaults) object.dims = []; if (options.defaults) { object.values = null; object.indices = null; } if (message.values != null && message.hasOwnProperty("values")) object.values = $root.onnx.TensorProto.toObject(message.values, options); if (message.indices != null && message.hasOwnProperty("indices")) object.indices = $root.onnx.TensorProto.toObject(message.indices, options); if (message.dims && message.dims.length) { object.dims = []; for (var j = 0; j < message.dims.length; ++j) if (typeof message.dims[j] === "number") object.dims[j] = options.longs === String ? String(message.dims[j]) : message.dims[j]; else object.dims[j] = options.longs === String ? $util.Long.prototype.toString.call(message.dims[j]) : options.longs === Number ? new $util.LongBits(message.dims[j].low >>> 0, message.dims[j].high >>> 0).toNumber() : message.dims[j]; } return object; }; SparseTensorProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; SparseTensorProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.SparseTensorProto"; }; return SparseTensorProto; }(); onnx6.TensorShapeProto = function() { function TensorShapeProto(properties) { this.dim = []; if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } TensorShapeProto.prototype.dim = $util.emptyArray; TensorShapeProto.create = function create(properties) { return new TensorShapeProto(properties); }; TensorShapeProto.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.dim != null && message.dim.length) for (var i = 0; i < message.dim.length; ++i) $root.onnx.TensorShapeProto.Dimension.encode( message.dim[i], writer.uint32( /* id 1, wireType 2 =*/ 10 ).fork() ).ldelim(); return writer; }; TensorShapeProto.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; TensorShapeProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorShapeProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { if (!(message.dim && message.dim.length)) message.dim = []; message.dim.push($root.onnx.TensorShapeProto.Dimension.decode(reader, reader.uint32())); break; } default: reader.skipType(tag & 7); break; } } return message; }; TensorShapeProto.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; TensorShapeProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.dim != null && message.hasOwnProperty("dim")) { if (!Array.isArray(message.dim)) return "dim: array expected"; for (var i = 0; i < message.dim.length; ++i) { var error = $root.onnx.TensorShapeProto.Dimension.verify(message.dim[i]); if (error) return "dim." + error; } } return null; }; TensorShapeProto.fromObject = function fromObject(object) { if (object instanceof $root.onnx.TensorShapeProto) return object; var message = new $root.onnx.TensorShapeProto(); if (object.dim) { if (!Array.isArray(object.dim)) throw TypeError(".onnx.TensorShapeProto.dim: array expected"); message.dim = []; for (var i = 0; i < object.dim.length; ++i) { if (typeof object.dim[i] !== "object") throw TypeError(".onnx.TensorShapeProto.dim: object expected"); message.dim[i] = $root.onnx.TensorShapeProto.Dimension.fromObject(object.dim[i]); } } return message; }; TensorShapeProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.arrays || options.defaults) object.dim = []; if (message.dim && message.dim.length) { object.dim = []; for (var j = 0; j < message.dim.length; ++j) object.dim[j] = $root.onnx.TensorShapeProto.Dimension.toObject(message.dim[j], options); } return object; }; TensorShapeProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; TensorShapeProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TensorShapeProto"; }; TensorShapeProto.Dimension = function() { function Dimension2(properties) { if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } Dimension2.prototype.dimValue = null; Dimension2.prototype.dimParam = null; Dimension2.prototype.denotation = ""; var $oneOfFields; Object.defineProperty(Dimension2.prototype, "value", { get: $util.oneOfGetter($oneOfFields = ["dimValue", "dimParam"]), set: $util.oneOfSetter($oneOfFields) }); Dimension2.create = function create(properties) { return new Dimension2(properties); }; Dimension2.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.dimValue != null && Object.hasOwnProperty.call(message, "dimValue")) writer.uint32( /* id 1, wireType 0 =*/ 8 ).int64(message.dimValue); if (message.dimParam != null && Object.hasOwnProperty.call(message, "dimParam")) writer.uint32( /* id 2, wireType 2 =*/ 18 ).string(message.dimParam); if (message.denotation != null && Object.hasOwnProperty.call(message, "denotation")) writer.uint32( /* id 3, wireType 2 =*/ 26 ).string(message.denotation); return writer; }; Dimension2.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; Dimension2.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorShapeProto.Dimension(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.dimValue = reader.int64(); break; } case 2: { message.dimParam = reader.string(); break; } case 3: { message.denotation = reader.string(); break; } default: reader.skipType(tag & 7); break; } } return message; }; Dimension2.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; Dimension2.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; var properties = {}; if (message.dimValue != null && message.hasOwnProperty("dimValue")) { properties.value = 1; if (!$util.isInteger(message.dimValue) && !(message.dimValue && $util.isInteger(message.dimValue.low) && $util.isInteger(message.dimValue.high))) return "dimValue: integer|Long expected"; } if (message.dimParam != null && message.hasOwnProperty("dimParam")) { if (properties.value === 1) return "value: multiple values"; properties.value = 1; if (!$util.isString(message.dimParam)) return "dimParam: string expected"; } if (message.denotation != null && message.hasOwnProperty("denotation")) { if (!$util.isString(message.denotation)) return "denotation: string expected"; } return null; }; Dimension2.fromObject = function fromObject(object) { if (object instanceof $root.onnx.TensorShapeProto.Dimension) return object; var message = new $root.onnx.TensorShapeProto.Dimension(); if (object.dimValue != null) { if ($util.Long) (message.dimValue = $util.Long.fromValue(object.dimValue)).unsigned = false; else if (typeof object.dimValue === "string") message.dimValue = parseInt(object.dimValue, 10); else if (typeof object.dimValue === "number") message.dimValue = object.dimValue; else if (typeof object.dimValue === "object") message.dimValue = new $util.LongBits(object.dimValue.low >>> 0, object.dimValue.high >>> 0).toNumber(); } if (object.dimParam != null) message.dimParam = String(object.dimParam); if (object.denotation != null) message.denotation = String(object.denotation); return message; }; Dimension2.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) object.denotation = ""; if (message.dimValue != null && message.hasOwnProperty("dimValue")) { if (typeof message.dimValue === "number") object.dimValue = options.longs === String ? String(message.dimValue) : message.dimValue; else object.dimValue = options.longs === String ? $util.Long.prototype.toString.call(message.dimValue) : options.longs === Number ? new $util.LongBits(message.dimValue.low >>> 0, message.dimValue.high >>> 0).toNumber() : message.dimValue; if (options.oneofs) object.value = "dimValue"; } if (message.dimParam != null && message.hasOwnProperty("dimParam")) { object.dimParam = message.dimParam; if (options.oneofs) object.value = "dimParam"; } if (message.denotation != null && message.hasOwnProperty("denotation")) object.denotation = message.denotation; return object; }; Dimension2.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; Dimension2.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TensorShapeProto.Dimension"; }; return Dimension2; }(); return TensorShapeProto; }(); onnx6.TypeProto = function() { function TypeProto(properties) { if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } TypeProto.prototype.tensorType = null; TypeProto.prototype.sequenceType = null; TypeProto.prototype.mapType = null; TypeProto.prototype.optionalType = null; TypeProto.prototype.sparseTensorType = null; TypeProto.prototype.denotation = ""; var $oneOfFields; Object.defineProperty(TypeProto.prototype, "value", { get: $util.oneOfGetter( $oneOfFields = ["tensorType", "sequenceType", "mapType", "optionalType", "sparseTensorType"] ), set: $util.oneOfSetter($oneOfFields) }); TypeProto.create = function create(properties) { return new TypeProto(properties); }; TypeProto.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.tensorType != null && Object.hasOwnProperty.call(message, "tensorType")) $root.onnx.TypeProto.Tensor.encode( message.tensorType, writer.uint32( /* id 1, wireType 2 =*/ 10 ).fork() ).ldelim(); if (message.sequenceType != null && Object.hasOwnProperty.call(message, "sequenceType")) $root.onnx.TypeProto.Sequence.encode( message.sequenceType, writer.uint32( /* id 4, wireType 2 =*/ 34 ).fork() ).ldelim(); if (message.mapType != null && Object.hasOwnProperty.call(message, "mapType")) $root.onnx.TypeProto.Map.encode(message.mapType, writer.uint32( /* id 5, wireType 2 =*/ 42 ).fork()).ldelim(); if (message.denotation != null && Object.hasOwnProperty.call(message, "denotation")) writer.uint32( /* id 6, wireType 2 =*/ 50 ).string(message.denotation); if (message.sparseTensorType != null && Object.hasOwnProperty.call(message, "sparseTensorType")) $root.onnx.TypeProto.SparseTensor.encode( message.sparseTensorType, writer.uint32( /* id 8, wireType 2 =*/ 66 ).fork() ).ldelim(); if (message.optionalType != null && Object.hasOwnProperty.call(message, "optionalType")) $root.onnx.TypeProto.Optional.encode( message.optionalType, writer.uint32( /* id 9, wireType 2 =*/ 74 ).fork() ).ldelim(); return writer; }; TypeProto.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; TypeProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.tensorType = $root.onnx.TypeProto.Tensor.decode(reader, reader.uint32()); break; } case 4: { message.sequenceType = $root.onnx.TypeProto.Sequence.decode(reader, reader.uint32()); break; } case 5: { message.mapType = $root.onnx.TypeProto.Map.decode(reader, reader.uint32()); break; } case 9: { message.optionalType = $root.onnx.TypeProto.Optional.decode(reader, reader.uint32()); break; } case 8: { message.sparseTensorType = $root.onnx.TypeProto.SparseTensor.decode(reader, reader.uint32()); break; } case 6: { message.denotation = reader.string(); break; } default: reader.skipType(tag & 7); break; } } return message; }; TypeProto.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; TypeProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; var properties = {}; if (message.tensorType != null && message.hasOwnProperty("tensorType")) { properties.value = 1; { var error = $root.onnx.TypeProto.Tensor.verify(message.tensorType); if (error) return "tensorType." + error; } } if (message.sequenceType != null && message.hasOwnProperty("sequenceType")) { if (properties.value === 1) return "value: multiple values"; properties.value = 1; { var error = $root.onnx.TypeProto.Sequence.verify(message.sequenceType); if (error) return "sequenceType." + error; } } if (message.mapType != null && message.hasOwnProperty("mapType")) { if (properties.value === 1) return "value: multiple values"; properties.value = 1; { var error = $root.onnx.TypeProto.Map.verify(message.mapType); if (error) return "mapType." + error; } } if (message.optionalType != null && message.hasOwnProperty("optionalType")) { if (properties.value === 1) return "value: multiple values"; properties.value = 1; { var error = $root.onnx.TypeProto.Optional.verify(message.optionalType); if (error) return "optionalType." + error; } } if (message.sparseTensorType != null && message.hasOwnProperty("sparseTensorType")) { if (properties.value === 1) return "value: multiple values"; properties.value = 1; { var error = $root.onnx.TypeProto.SparseTensor.verify(message.sparseTensorType); if (error) return "sparseTensorType." + error; } } if (message.denotation != null && message.hasOwnProperty("denotation")) { if (!$util.isString(message.denotation)) return "denotation: string expected"; } return null; }; TypeProto.fromObject = function fromObject(object) { if (object instanceof $root.onnx.TypeProto) return object; var message = new $root.onnx.TypeProto(); if (object.tensorType != null) { if (typeof object.tensorType !== "object") throw TypeError(".onnx.TypeProto.tensorType: object expected"); message.tensorType = $root.onnx.TypeProto.Tensor.fromObject(object.tensorType); } if (object.sequenceType != null) { if (typeof object.sequenceType !== "object") throw TypeError(".onnx.TypeProto.sequenceType: object expected"); message.sequenceType = $root.onnx.TypeProto.Sequence.fromObject(object.sequenceType); } if (object.mapType != null) { if (typeof object.mapType !== "object") throw TypeError(".onnx.TypeProto.mapType: object expected"); message.mapType = $root.onnx.TypeProto.Map.fromObject(object.mapType); } if (object.optionalType != null) { if (typeof object.optionalType !== "object") throw TypeError(".onnx.TypeProto.optionalType: object expected"); message.optionalType = $root.onnx.TypeProto.Optional.fromObject(object.optionalType); } if (object.sparseTensorType != null) { if (typeof object.sparseTensorType !== "object") throw TypeError(".onnx.TypeProto.sparseTensorType: object expected"); message.sparseTensorType = $root.onnx.TypeProto.SparseTensor.fromObject(object.sparseTensorType); } if (object.denotation != null) message.denotation = String(object.denotation); return message; }; TypeProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) object.denotation = ""; if (message.tensorType != null && message.hasOwnProperty("tensorType")) { object.tensorType = $root.onnx.TypeProto.Tensor.toObject(message.tensorType, options); if (options.oneofs) object.value = "tensorType"; } if (message.sequenceType != null && message.hasOwnProperty("sequenceType")) { object.sequenceType = $root.onnx.TypeProto.Sequence.toObject(message.sequenceType, options); if (options.oneofs) object.value = "sequenceType"; } if (message.mapType != null && message.hasOwnProperty("mapType")) { object.mapType = $root.onnx.TypeProto.Map.toObject(message.mapType, options); if (options.oneofs) object.value = "mapType"; } if (message.denotation != null && message.hasOwnProperty("denotation")) object.denotation = message.denotation; if (message.sparseTensorType != null && message.hasOwnProperty("sparseTensorType")) { object.sparseTensorType = $root.onnx.TypeProto.SparseTensor.toObject(message.sparseTensorType, options); if (options.oneofs) object.value = "sparseTensorType"; } if (message.optionalType != null && message.hasOwnProperty("optionalType")) { object.optionalType = $root.onnx.TypeProto.Optional.toObject(message.optionalType, options); if (options.oneofs) object.value = "optionalType"; } return object; }; TypeProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; TypeProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TypeProto"; }; TypeProto.Tensor = function() { function Tensor5(properties) { if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } Tensor5.prototype.elemType = 0; Tensor5.prototype.shape = null; Tensor5.create = function create(properties) { return new Tensor5(properties); }; Tensor5.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.elemType != null && Object.hasOwnProperty.call(message, "elemType")) writer.uint32( /* id 1, wireType 0 =*/ 8 ).int32(message.elemType); if (message.shape != null && Object.hasOwnProperty.call(message, "shape")) $root.onnx.TensorShapeProto.encode(message.shape, writer.uint32( /* id 2, wireType 2 =*/ 18 ).fork()).ldelim(); return writer; }; Tensor5.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; Tensor5.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.Tensor(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.elemType = reader.int32(); break; } case 2: { message.shape = $root.onnx.TensorShapeProto.decode(reader, reader.uint32()); break; } default: reader.skipType(tag & 7); break; } } return message; }; Tensor5.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; Tensor5.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.elemType != null && message.hasOwnProperty("elemType")) { if (!$util.isInteger(message.elemType)) return "elemType: integer expected"; } if (message.shape != null && message.hasOwnProperty("shape")) { var error = $root.onnx.TensorShapeProto.verify(message.shape); if (error) return "shape." + error; } return null; }; Tensor5.fromObject = function fromObject(object) { if (object instanceof $root.onnx.TypeProto.Tensor) return object; var message = new $root.onnx.TypeProto.Tensor(); if (object.elemType != null) message.elemType = object.elemType | 0; if (object.shape != null) { if (typeof object.shape !== "object") throw TypeError(".onnx.TypeProto.Tensor.shape: object expected"); message.shape = $root.onnx.TensorShapeProto.fromObject(object.shape); } return message; }; Tensor5.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { object.elemType = 0; object.shape = null; } if (message.elemType != null && message.hasOwnProperty("elemType")) object.elemType = message.elemType; if (message.shape != null && message.hasOwnProperty("shape")) object.shape = $root.onnx.TensorShapeProto.toObject(message.shape, options); return object; }; Tensor5.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; Tensor5.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TypeProto.Tensor"; }; return Tensor5; }(); TypeProto.Sequence = function() { function Sequence(properties) { if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } Sequence.prototype.elemType = null; Sequence.create = function create(properties) { return new Sequence(properties); }; Sequence.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.elemType != null && Object.hasOwnProperty.call(message, "elemType")) $root.onnx.TypeProto.encode(message.elemType, writer.uint32( /* id 1, wireType 2 =*/ 10 ).fork()).ldelim(); return writer; }; Sequence.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; Sequence.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.Sequence(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.elemType = $root.onnx.TypeProto.decode(reader, reader.uint32()); break; } default: reader.skipType(tag & 7); break; } } return message; }; Sequence.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; Sequence.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.elemType != null && message.hasOwnProperty("elemType")) { var error = $root.onnx.TypeProto.verify(message.elemType); if (error) return "elemType." + error; } return null; }; Sequence.fromObject = function fromObject(object) { if (object instanceof $root.onnx.TypeProto.Sequence) return object; var message = new $root.onnx.TypeProto.Sequence(); if (object.elemType != null) { if (typeof object.elemType !== "object") throw TypeError(".onnx.TypeProto.Sequence.elemType: object expected"); message.elemType = $root.onnx.TypeProto.fromObject(object.elemType); } return message; }; Sequence.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) object.elemType = null; if (message.elemType != null && message.hasOwnProperty("elemType")) object.elemType = $root.onnx.TypeProto.toObject(message.elemType, options); return object; }; Sequence.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; Sequence.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TypeProto.Sequence"; }; return Sequence; }(); TypeProto.Map = function() { function Map2(properties) { if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } Map2.prototype.keyType = 0; Map2.prototype.valueType = null; Map2.create = function create(properties) { return new Map2(properties); }; Map2.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.keyType != null && Object.hasOwnProperty.call(message, "keyType")) writer.uint32( /* id 1, wireType 0 =*/ 8 ).int32(message.keyType); if (message.valueType != null && Object.hasOwnProperty.call(message, "valueType")) $root.onnx.TypeProto.encode(message.valueType, writer.uint32( /* id 2, wireType 2 =*/ 18 ).fork()).ldelim(); return writer; }; Map2.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; Map2.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.Map(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.keyType = reader.int32(); break; } case 2: { message.valueType = $root.onnx.TypeProto.decode(reader, reader.uint32()); break; } default: reader.skipType(tag & 7); break; } } return message; }; Map2.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; Map2.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.keyType != null && message.hasOwnProperty("keyType")) { if (!$util.isInteger(message.keyType)) return "keyType: integer expected"; } if (message.valueType != null && message.hasOwnProperty("valueType")) { var error = $root.onnx.TypeProto.verify(message.valueType); if (error) return "valueType." + error; } return null; }; Map2.fromObject = function fromObject(object) { if (object instanceof $root.onnx.TypeProto.Map) return object; var message = new $root.onnx.TypeProto.Map(); if (object.keyType != null) message.keyType = object.keyType | 0; if (object.valueType != null) { if (typeof object.valueType !== "object") throw TypeError(".onnx.TypeProto.Map.valueType: object expected"); message.valueType = $root.onnx.TypeProto.fromObject(object.valueType); } return message; }; Map2.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { object.keyType = 0; object.valueType = null; } if (message.keyType != null && message.hasOwnProperty("keyType")) object.keyType = message.keyType; if (message.valueType != null && message.hasOwnProperty("valueType")) object.valueType = $root.onnx.TypeProto.toObject(message.valueType, options); return object; }; Map2.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; Map2.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TypeProto.Map"; }; return Map2; }(); TypeProto.Optional = function() { function Optional(properties) { if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } Optional.prototype.elemType = null; Optional.create = function create(properties) { return new Optional(properties); }; Optional.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.elemType != null && Object.hasOwnProperty.call(message, "elemType")) $root.onnx.TypeProto.encode(message.elemType, writer.uint32( /* id 1, wireType 2 =*/ 10 ).fork()).ldelim(); return writer; }; Optional.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; Optional.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.Optional(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.elemType = $root.onnx.TypeProto.decode(reader, reader.uint32()); break; } default: reader.skipType(tag & 7); break; } } return message; }; Optional.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; Optional.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.elemType != null && message.hasOwnProperty("elemType")) { var error = $root.onnx.TypeProto.verify(message.elemType); if (error) return "elemType." + error; } return null; }; Optional.fromObject = function fromObject(object) { if (object instanceof $root.onnx.TypeProto.Optional) return object; var message = new $root.onnx.TypeProto.Optional(); if (object.elemType != null) { if (typeof object.elemType !== "object") throw TypeError(".onnx.TypeProto.Optional.elemType: object expected"); message.elemType = $root.onnx.TypeProto.fromObject(object.elemType); } return message; }; Optional.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) object.elemType = null; if (message.elemType != null && message.hasOwnProperty("elemType")) object.elemType = $root.onnx.TypeProto.toObject(message.elemType, options); return object; }; Optional.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; Optional.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TypeProto.Optional"; }; return Optional; }(); TypeProto.SparseTensor = function() { function SparseTensor2(properties) { if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } SparseTensor2.prototype.elemType = 0; SparseTensor2.prototype.shape = null; SparseTensor2.create = function create(properties) { return new SparseTensor2(properties); }; SparseTensor2.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.elemType != null && Object.hasOwnProperty.call(message, "elemType")) writer.uint32( /* id 1, wireType 0 =*/ 8 ).int32(message.elemType); if (message.shape != null && Object.hasOwnProperty.call(message, "shape")) $root.onnx.TensorShapeProto.encode(message.shape, writer.uint32( /* id 2, wireType 2 =*/ 18 ).fork()).ldelim(); return writer; }; SparseTensor2.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; SparseTensor2.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.SparseTensor(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.elemType = reader.int32(); break; } case 2: { message.shape = $root.onnx.TensorShapeProto.decode(reader, reader.uint32()); break; } default: reader.skipType(tag & 7); break; } } return message; }; SparseTensor2.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; SparseTensor2.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.elemType != null && message.hasOwnProperty("elemType")) { if (!$util.isInteger(message.elemType)) return "elemType: integer expected"; } if (message.shape != null && message.hasOwnProperty("shape")) { var error = $root.onnx.TensorShapeProto.verify(message.shape); if (error) return "shape." + error; } return null; }; SparseTensor2.fromObject = function fromObject(object) { if (object instanceof $root.onnx.TypeProto.SparseTensor) return object; var message = new $root.onnx.TypeProto.SparseTensor(); if (object.elemType != null) message.elemType = object.elemType | 0; if (object.shape != null) { if (typeof object.shape !== "object") throw TypeError(".onnx.TypeProto.SparseTensor.shape: object expected"); message.shape = $root.onnx.TensorShapeProto.fromObject(object.shape); } return message; }; SparseTensor2.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { object.elemType = 0; object.shape = null; } if (message.elemType != null && message.hasOwnProperty("elemType")) object.elemType = message.elemType; if (message.shape != null && message.hasOwnProperty("shape")) object.shape = $root.onnx.TensorShapeProto.toObject(message.shape, options); return object; }; SparseTensor2.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; SparseTensor2.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.TypeProto.SparseTensor"; }; return SparseTensor2; }(); return TypeProto; }(); onnx6.OperatorSetIdProto = function() { function OperatorSetIdProto(properties) { if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } OperatorSetIdProto.prototype.domain = ""; OperatorSetIdProto.prototype.version = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; OperatorSetIdProto.create = function create(properties) { return new OperatorSetIdProto(properties); }; OperatorSetIdProto.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.domain != null && Object.hasOwnProperty.call(message, "domain")) writer.uint32( /* id 1, wireType 2 =*/ 10 ).string(message.domain); if (message.version != null && Object.hasOwnProperty.call(message, "version")) writer.uint32( /* id 2, wireType 0 =*/ 16 ).int64(message.version); return writer; }; OperatorSetIdProto.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; OperatorSetIdProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.OperatorSetIdProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.domain = reader.string(); break; } case 2: { message.version = reader.int64(); break; } default: reader.skipType(tag & 7); break; } } return message; }; OperatorSetIdProto.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; OperatorSetIdProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.domain != null && message.hasOwnProperty("domain")) { if (!$util.isString(message.domain)) return "domain: string expected"; } if (message.version != null && message.hasOwnProperty("version")) { if (!$util.isInteger(message.version) && !(message.version && $util.isInteger(message.version.low) && $util.isInteger(message.version.high))) return "version: integer|Long expected"; } return null; }; OperatorSetIdProto.fromObject = function fromObject(object) { if (object instanceof $root.onnx.OperatorSetIdProto) return object; var message = new $root.onnx.OperatorSetIdProto(); if (object.domain != null) message.domain = String(object.domain); if (object.version != null) { if ($util.Long) (message.version = $util.Long.fromValue(object.version)).unsigned = false; else if (typeof object.version === "string") message.version = parseInt(object.version, 10); else if (typeof object.version === "number") message.version = object.version; else if (typeof object.version === "object") message.version = new $util.LongBits(object.version.low >>> 0, object.version.high >>> 0).toNumber(); } return message; }; OperatorSetIdProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { object.domain = ""; if ($util.Long) { var long = new $util.Long(0, 0, false); object.version = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; } else object.version = options.longs === String ? "0" : 0; } if (message.domain != null && message.hasOwnProperty("domain")) object.domain = message.domain; if (message.version != null && message.hasOwnProperty("version")) if (typeof message.version === "number") object.version = options.longs === String ? String(message.version) : message.version; else object.version = options.longs === String ? $util.Long.prototype.toString.call(message.version) : options.longs === Number ? new $util.LongBits(message.version.low >>> 0, message.version.high >>> 0).toNumber() : message.version; return object; }; OperatorSetIdProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; OperatorSetIdProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.OperatorSetIdProto"; }; return OperatorSetIdProto; }(); onnx6.OperatorStatus = function() { var valuesById = {}, values = Object.create(valuesById); values[valuesById[0] = "EXPERIMENTAL"] = 0; values[valuesById[1] = "STABLE"] = 1; return values; }(); onnx6.FunctionProto = function() { function FunctionProto(properties) { this.input = []; this.output = []; this.attribute = []; this.attributeProto = []; this.node = []; this.opsetImport = []; if (properties) { for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; } } FunctionProto.prototype.name = ""; FunctionProto.prototype.input = $util.emptyArray; FunctionProto.prototype.output = $util.emptyArray; FunctionProto.prototype.attribute = $util.emptyArray; FunctionProto.prototype.attributeProto = $util.emptyArray; FunctionProto.prototype.node = $util.emptyArray; FunctionProto.prototype.docString = ""; FunctionProto.prototype.opsetImport = $util.emptyArray; FunctionProto.prototype.domain = ""; FunctionProto.create = function create(properties) { return new FunctionProto(properties); }; FunctionProto.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); if (message.name != null && Object.hasOwnProperty.call(message, "name")) writer.uint32( /* id 1, wireType 2 =*/ 10 ).string(message.name); if (message.input != null && message.input.length) for (var i = 0; i < message.input.length; ++i) writer.uint32( /* id 4, wireType 2 =*/ 34 ).string(message.input[i]); if (message.output != null && message.output.length) for (var i = 0; i < message.output.length; ++i) writer.uint32( /* id 5, wireType 2 =*/ 42 ).string(message.output[i]); if (message.attribute != null && message.attribute.length) for (var i = 0; i < message.attribute.length; ++i) writer.uint32( /* id 6, wireType 2 =*/ 50 ).string(message.attribute[i]); if (message.node != null && message.node.length) for (var i = 0; i < message.node.length; ++i) $root.onnx.NodeProto.encode(message.node[i], writer.uint32( /* id 7, wireType 2 =*/ 58 ).fork()).ldelim(); if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) writer.uint32( /* id 8, wireType 2 =*/ 66 ).string(message.docString); if (message.opsetImport != null && message.opsetImport.length) for (var i = 0; i < message.opsetImport.length; ++i) $root.onnx.OperatorSetIdProto.encode( message.opsetImport[i], writer.uint32( /* id 9, wireType 2 =*/ 74 ).fork() ).ldelim(); if (message.domain != null && Object.hasOwnProperty.call(message, "domain")) writer.uint32( /* id 10, wireType 2 =*/ 82 ).string(message.domain); if (message.attributeProto != null && message.attributeProto.length) for (var i = 0; i < message.attributeProto.length; ++i) $root.onnx.AttributeProto.encode( message.attributeProto[i], writer.uint32( /* id 11, wireType 2 =*/ 90 ).fork() ).ldelim(); return writer; }; FunctionProto.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; FunctionProto.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.FunctionProto(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: { message.name = reader.string(); break; } case 4: { if (!(message.input && message.input.length)) message.input = []; message.input.push(reader.string()); break; } case 5: { if (!(message.output && message.output.length)) message.output = []; message.output.push(reader.string()); break; } case 6: { if (!(message.attribute && message.attribute.length)) message.attribute = []; message.attribute.push(reader.string()); break; } case 11: { if (!(message.attributeProto && message.attributeProto.length)) message.attributeProto = []; message.attributeProto.push($root.onnx.AttributeProto.decode(reader, reader.uint32())); break; } case 7: { if (!(message.node && message.node.length)) message.node = []; message.node.push($root.onnx.NodeProto.decode(reader, reader.uint32())); break; } case 8: { message.docString = reader.string(); break; } case 9: { if (!(message.opsetImport && message.opsetImport.length)) message.opsetImport = []; message.opsetImport.push($root.onnx.OperatorSetIdProto.decode(reader, reader.uint32())); break; } case 10: { message.domain = reader.string(); break; } default: reader.skipType(tag & 7); break; } } return message; }; FunctionProto.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; FunctionProto.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; if (message.name != null && message.hasOwnProperty("name")) { if (!$util.isString(message.name)) return "name: string expected"; } if (message.input != null && message.hasOwnProperty("input")) { if (!Array.isArray(message.input)) return "input: array expected"; for (var i = 0; i < message.input.length; ++i) if (!$util.isString(message.input[i])) return "input: string[] expected"; } if (message.output != null && message.hasOwnProperty("output")) { if (!Array.isArray(message.output)) return "output: array expected"; for (var i = 0; i < message.output.length; ++i) if (!$util.isString(message.output[i])) return "output: string[] expected"; } if (message.attribute != null && message.hasOwnProperty("attribute")) { if (!Array.isArray(message.attribute)) return "attribute: array expected"; for (var i = 0; i < message.attribute.length; ++i) if (!$util.isString(message.attribute[i])) return "attribute: string[] expected"; } if (message.attributeProto != null && message.hasOwnProperty("attributeProto")) { if (!Array.isArray(message.attributeProto)) return "attributeProto: array expected"; for (var i = 0; i < message.attributeProto.length; ++i) { var error = $root.onnx.AttributeProto.verify(message.attributeProto[i]); if (error) return "attributeProto." + error; } } if (message.node != null && message.hasOwnProperty("node")) { if (!Array.isArray(message.node)) return "node: array expected"; for (var i = 0; i < message.node.length; ++i) { var error = $root.onnx.NodeProto.verify(message.node[i]); if (error) return "node." + error; } } if (message.docString != null && message.hasOwnProperty("docString")) { if (!$util.isString(message.docString)) return "docString: string expected"; } if (message.opsetImport != null && message.hasOwnProperty("opsetImport")) { if (!Array.isArray(message.opsetImport)) return "opsetImport: array expected"; for (var i = 0; i < message.opsetImport.length; ++i) { var error = $root.onnx.OperatorSetIdProto.verify(message.opsetImport[i]); if (error) return "opsetImport." + error; } } if (message.domain != null && message.hasOwnProperty("domain")) { if (!$util.isString(message.domain)) return "domain: string expected"; } return null; }; FunctionProto.fromObject = function fromObject(object) { if (object instanceof $root.onnx.FunctionProto) return object; var message = new $root.onnx.FunctionProto(); if (object.name != null) message.name = String(object.name); if (object.input) { if (!Array.isArray(object.input)) throw TypeError(".onnx.FunctionProto.input: array expected"); message.input = []; for (var i = 0; i < object.input.length; ++i) message.input[i] = String(object.input[i]); } if (object.output) { if (!Array.isArray(object.output)) throw TypeError(".onnx.FunctionProto.output: array expected"); message.output = []; for (var i = 0; i < object.output.length; ++i) message.output[i] = String(object.output[i]); } if (object.attribute) { if (!Array.isArray(object.attribute)) throw TypeError(".onnx.FunctionProto.attribute: array expected"); message.attribute = []; for (var i = 0; i < object.attribute.length; ++i) message.attribute[i] = String(object.attribute[i]); } if (object.attributeProto) { if (!Array.isArray(object.attributeProto)) throw TypeError(".onnx.FunctionProto.attributeProto: array expected"); message.attributeProto = []; for (var i = 0; i < object.attributeProto.length; ++i) { if (typeof object.attributeProto[i] !== "object") throw TypeError(".onnx.FunctionProto.attributeProto: object expected"); message.attributeProto[i] = $root.onnx.AttributeProto.fromObject(object.attributeProto[i]); } } if (object.node) { if (!Array.isArray(object.node)) throw TypeError(".onnx.FunctionProto.node: array expected"); message.node = []; for (var i = 0; i < object.node.length; ++i) { if (typeof object.node[i] !== "object") throw TypeError(".onnx.FunctionProto.node: object expected"); message.node[i] = $root.onnx.NodeProto.fromObject(object.node[i]); } } if (object.docString != null) message.docString = String(object.docString); if (object.opsetImport) { if (!Array.isArray(object.opsetImport)) throw TypeError(".onnx.FunctionProto.opsetImport: array expected"); message.opsetImport = []; for (var i = 0; i < object.opsetImport.length; ++i) { if (typeof object.opsetImport[i] !== "object") throw TypeError(".onnx.FunctionProto.opsetImport: object expected"); message.opsetImport[i] = $root.onnx.OperatorSetIdProto.fromObject(object.opsetImport[i]); } } if (object.domain != null) message.domain = String(object.domain); return message; }; FunctionProto.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.arrays || options.defaults) { object.input = []; object.output = []; object.attribute = []; object.node = []; object.opsetImport = []; object.attributeProto = []; } if (options.defaults) { object.name = ""; object.docString = ""; object.domain = ""; } if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; if (message.input && message.input.length) { object.input = []; for (var j = 0; j < message.input.length; ++j) object.input[j] = message.input[j]; } if (message.output && message.output.length) { object.output = []; for (var j = 0; j < message.output.length; ++j) object.output[j] = message.output[j]; } if (message.attribute && message.attribute.length) { object.attribute = []; for (var j = 0; j < message.attribute.length; ++j) object.attribute[j] = message.attribute[j]; } if (message.node && message.node.length) { object.node = []; for (var j = 0; j < message.node.length; ++j) object.node[j] = $root.onnx.NodeProto.toObject(message.node[j], options); } if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; if (message.opsetImport && message.opsetImport.length) { object.opsetImport = []; for (var j = 0; j < message.opsetImport.length; ++j) object.opsetImport[j] = $root.onnx.OperatorSetIdProto.toObject(message.opsetImport[j], options); } if (message.domain != null && message.hasOwnProperty("domain")) object.domain = message.domain; if (message.attributeProto && message.attributeProto.length) { object.attributeProto = []; for (var j = 0; j < message.attributeProto.length; ++j) object.attributeProto[j] = $root.onnx.AttributeProto.toObject(message.attributeProto[j], options); } return object; }; FunctionProto.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; FunctionProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { if (typeUrlPrefix === void 0) { typeUrlPrefix = "type.googleapis.com"; } return typeUrlPrefix + "/onnx.FunctionProto"; }; return FunctionProto; }(); return onnx6; }(); module2.exports = $root; } }); // web/lib/onnxjs/util.ts function assert(expr, msg) { if (!expr) { throw new Error(typeof msg === "string" ? msg : msg()); } } function decodeUtf8String(buffer) { return new TextDecoder().decode(buffer); } var import_onnx, ArrayUtil, MatMulUtil, BroadcastUtil, GemmUtil, ProtoUtil, LongUtil, ShapeUtil, SplitUtil, PoolConvUtil, MIN_CLIP, MAX_CLIP; var init_util = __esm({ "web/lib/onnxjs/util.ts"() { "use strict"; init_long(); import_onnx = __toESM(require_onnx()); init_tensor2(); ArrayUtil = class { /** * Verifies if 2 input arrays contain the same elements. * @param n1 Array 1 * @param n2 Array 2 * @returns Whether these 2 are equal */ static arraysEqual(n1, n2) { if (n1.length !== n2.length) { return false; } for (let i = 0; i < n1.length; i++) { if (n1[i] !== n2[i]) { return false; } } return true; } }; MatMulUtil = class { /** * Fix the input shapes for MatMul operation if they need fixing * @param dimsA The shape of tensor A. Should be an array of positive integers * @param dimsB The shape of tensor B. Should be an array of positive integers * @returns A tuple containing the preprocessed input shapes as required by ONNX specifications */ static preprocessInputShapes(dimsA, dimsB) { const a = dimsA.length === 1 ? [1, dimsA[0]] : dimsA; const b = dimsB.length === 1 ? [dimsB[0], 1] : dimsB; return [a, b]; } /** * Fix the output shape computed for MatMul operation if it needs fixing * @param outputShape The computed outputShape. Should be an array (at least of length 2) of positive integers. * This will be mutated. * @param aRank The rank of tensor A. * @param bRank The rank of tensor B. */ static postprocessOutputShape(outputShape, aRank, bRank) { if (aRank === 1) { outputShape.splice(outputShape.length - 2, 1); } if (bRank === 1) { outputShape.pop(); } } /** * Calculate the expected shape when matrix multiplication * @param a The shape of tensor A. Should be a tuple of 2 positive integers * @param b The shape of tensor B. Should be a tuple of 2 positive integers * @returns The expected shape of the result, or undefined if N/A */ static calcMatMulShape(a, b) { return a[1] !== b[0] ? void 0 : [a[0], b[1]]; } }; BroadcastUtil = class _BroadcastUtil { /** * Calculate the expected shape when broadcasting 2 tensors * @param a The shape of tensor A. Should be an array of positive integers * @param b The shape of tensor B. Should be an array of positive integers * @param isMatMul Whether the operation is MatMul * @returns The expected shape of the result, or undefined if N/A */ static calcShape(adims, bdims, isMatMul = false) { const arank = adims.length; const brank = bdims.length; if (arank === 0) { return bdims; } if (brank === 0) { return adims; } const crank = Math.max(adims.length, bdims.length); const cdims = new Array(crank); if (isMatMul) { if (arank < 2 || brank < 2) { return void 0; } const cShapeMatMul = MatMulUtil.calcMatMulShape( [adims[arank - 2], adims[arank - 1]], [bdims[brank - 2], bdims[brank - 1]] ); if (cShapeMatMul === void 0) { return void 0; } [cdims[crank - 2], cdims[crank - 1]] = cShapeMatMul; } for (let i = isMatMul ? 3 : 1; i <= crank; i++) { const aLen = arank - i < 0 ? 1 : adims[arank - i]; const bLen = brank - i < 0 ? 1 : bdims[brank - i]; if (aLen !== bLen && aLen > 1 && bLen > 1) { return void 0; } cdims[crank - i] = Math.max(aLen, bLen); } return cdims; } /** * Given the indices of a broadcasted tensor, calculate the original indices * @param broadcastedIndices The given indices of the broadcasted tensor. * @param originalShape The original shape of the tensor before broadcast * @returns The calculated indices that maps to the original tensor. */ static index(broadcastedIndices, originalShape) { const originalIndices = new Array(originalShape.length); _BroadcastUtil.fillIndex(broadcastedIndices, originalShape, originalIndices); return originalIndices; } /** * Given the indices of a broadcasted tensor, calculate the original indices * @param broadcastedIndices The given indices of the broadcasted tensor. * @param originalShape The original shape of the tensor before broadcast * @param originalIndices The mapping of broadcastedIndices to the originalIndices (output parameter - will be * mutated). */ static fillIndex(broadcastedIndices, originalShape, originalIndices) { const dimOffset = broadcastedIndices.length - originalShape.length; for (let i = 0; i < originalShape.length; i++) { originalIndices[i] = broadcastedIndices[dimOffset + i] % originalShape[i]; } } /** * Perform the broadcasting operation on the specific operator * @param a The input tensor A * @param b The input tensor B * @param op The operator lambda function * @param inplace Whether to write the result back to A. * @returns The result tensor, or undefined if input not broadcastable. */ static calc(a, b, op, inplace, resultType) { const outputShape = _BroadcastUtil.calcShape(a.dims, b.dims); if (outputShape) { if (inplace && !ShapeUtil.areEqual(outputShape, a.dims)) { return void 0; } const size = ShapeUtil.size(outputShape); const c = inplace ? a : new Tensor4(outputShape, resultType || a.type); if (outputShape.length === 0) { c.set([], op(a.get([]), b.get([]))); } else { const outputIndices = new Array(outputShape.length); const originalIndicesA = new Array(a.dims.length); const originalIndicesB = new Array(b.dims.length); let valA = 0; let valB = 0; let isAScalar = false; let isBScalar = false; if (a.dims.length === 0) { valA = a.get([]); isAScalar = true; } if (b.dims.length === 0) { valB = b.get([]); isBScalar = true; } let rest; for (let i = 0; i < size; i++) { rest = i; for (let j = outputShape.length - 1; j >= 0; j--) { outputIndices[j] = rest % outputShape[j]; rest = Math.floor(rest / outputShape[j]); } if (!isAScalar) { _BroadcastUtil.fillIndex(outputIndices, a.dims, originalIndicesA); valA = a.get(originalIndicesA); } if (!isBScalar) { _BroadcastUtil.fillIndex(outputIndices, b.dims, originalIndicesB); valB = b.get(originalIndicesB); } c.set(outputIndices, op(valA, valB)); } } return c; } return void 0; } /** * Determine if a shape is unidirectional broadcastable to another shape * @param shape The input shape * @param finalShape The desired shape after broadcasting */ static isValidBroadcast(shape2, finalShape) { const inputRank = shape2.length; const finalRank = finalShape.length; if (inputRank > finalRank) { return false; } for (let i = 1; i <= inputRank; i++) { if (shape2[inputRank - i] !== 1 && shape2[inputRank - i] !== finalShape[finalRank - i]) { return false; } } return true; } /** * Determine the broadcasted dims in input shape based on the given output shape. * Note that this function only returns the broadcasted dims. * @param inputShape The input shape * @param outputShape The output shape * @returns The broadcasted dims in input shape. */ static getBroadcastDims(inputShape, outputShape) { const inRank = inputShape.length; const dims = []; for (let i = 0; i < inRank; i++) { const dim = inRank - 1 - i; const a = inputShape[dim] || 1; const b = outputShape[outputShape.length - 1 - i] || 1; if (b > 1 && a === 1) { dims.unshift(dim); } } return dims; } }; GemmUtil = class { // will make sure input shapes are compatible for this op // and return back the shape of the output in the form of a tuple // will throw exception if the input shapes are not compatible static getShapeOfGemmResult(leftShape, transLeft, rightShape, transRight, biasShape) { if (leftShape.length !== 2 || rightShape.length !== 2) { throw new Error("shape need to be of size 2"); } let M; let K; let N; if (transLeft) { M = leftShape[1]; K = leftShape[0]; } else { M = leftShape[0]; K = leftShape[1]; } let kDim = -1; if (transRight) { N = rightShape[0]; kDim = 1; } else { N = rightShape[1]; kDim = 0; } if (rightShape[kDim] !== K) { throw new Error("dimension mismatch"); } if (M <= 0 || N <= 0 || K <= 0) { throw new Error("invalid shape specified"); } if (biasShape && !BroadcastUtil.isValidBroadcast(biasShape, [M, N])) { throw new Error("gemm: invalid bias shape for broadcast"); } return [M, N, K]; } }; ProtoUtil = class _ProtoUtil { static tensorDataTypeFromProto(typeProto) { switch (typeProto) { case import_onnx.onnx.TensorProto.DataType.INT8: return "int8"; case import_onnx.onnx.TensorProto.DataType.UINT8: return "uint8"; case import_onnx.onnx.TensorProto.DataType.BOOL: return "bool"; case import_onnx.onnx.TensorProto.DataType.INT16: return "int16"; case import_onnx.onnx.TensorProto.DataType.UINT16: return "uint16"; case import_onnx.onnx.TensorProto.DataType.INT32: return "int32"; case import_onnx.onnx.TensorProto.DataType.UINT32: return "uint32"; case import_onnx.onnx.TensorProto.DataType.FLOAT: return "float32"; case import_onnx.onnx.TensorProto.DataType.DOUBLE: return "float64"; case import_onnx.onnx.TensorProto.DataType.STRING: return "string"; // For INT64/UINT64, reduce their value to 32-bits. // Should throw exception when overflow case import_onnx.onnx.TensorProto.DataType.INT64: return "int32"; case import_onnx.onnx.TensorProto.DataType.UINT64: return "uint32"; default: throw new Error(`unsupported data type: ${import_onnx.onnx.TensorProto.DataType[typeProto]}`); } } static tensorDataTypeStringToEnum(type) { switch (type) { case "int8": return import_onnx.onnx.TensorProto.DataType.INT8; case "uint8": return import_onnx.onnx.TensorProto.DataType.UINT8; case "bool": return import_onnx.onnx.TensorProto.DataType.BOOL; case "int16": return import_onnx.onnx.TensorProto.DataType.INT16; case "uint16": return import_onnx.onnx.TensorProto.DataType.UINT16; case "int32": return import_onnx.onnx.TensorProto.DataType.INT32; case "uint32": return import_onnx.onnx.TensorProto.DataType.UINT32; case "float32": return import_onnx.onnx.TensorProto.DataType.FLOAT; case "float64": return import_onnx.onnx.TensorProto.DataType.DOUBLE; case "string": return import_onnx.onnx.TensorProto.DataType.STRING; case "int64": return import_onnx.onnx.TensorProto.DataType.INT64; case "uint64": return import_onnx.onnx.TensorProto.DataType.UINT64; default: throw new Error(`unsupported data type: ${type}`); } } static tensorDimsFromProto(dims) { return dims.map((d) => long_default.isLong(d) ? d.toNumber() : d); } static tensorValueTypeFromProto(valueType) { return { tensorType: _ProtoUtil.tensorDataTypeFromProto(valueType.elemType), shape: { dims: _ProtoUtil.tensorDimsFromProto(valueType.shape.dim.map((d) => d.dimValue)) } }; } static tensorDimsFromORTFormat(tensor) { const dims = []; for (let i = 0; i < tensor.dimsLength(); i++) { dims.push(LongUtil.longToNumber(tensor.dims(i))); } return dims; } static tensorAttributesFromORTFormat(node) { const attributes = []; for (let i = 0; i < node.attributesLength(); i++) { attributes.push(node.attributes(i)); } return attributes; } }; LongUtil = class { // This function is called to get a number from long type of data for attribute, dim, and ir version, // which values are signed integers. // To make it more generic, add an optional parameter to convert to a unsigned number. static longToNumber(n) { if (long_default.isLong(n)) { return n.toNumber(); } else if (typeof n === "bigint") { return Number(n); } return n; } static isLong(n) { return long_default.isLong(n) || typeof n === "bigint"; } }; ShapeUtil = class _ShapeUtil { static size(dims) { return _ShapeUtil.getSizeFromDimensionRange(dims, 0, dims.length); } // `axis` inclusive static sizeFromDimension(dims, axis) { if (axis < 0 || axis > dims.length) { throw new Error(`invalid dimension of ${axis} for sizeFromDimension as Tensor has ${dims.length} dimensions.`); } return _ShapeUtil.getSizeFromDimensionRange(dims, axis, dims.length); } // `axis` exclusive static sizeToDimension(dims, axis) { if (axis < 0 || axis > dims.length) { throw new Error(`invalid dimension of ${axis} for sizeToDimension as Tensor has ${dims.length} dimensions.`); } return _ShapeUtil.getSizeFromDimensionRange(dims, 0, axis); } static getSizeFromDimensionRange(dims, start, end) { let size = 1; for (let i = start; i < end; i++) { if (dims[i] <= 0) { throw new Error( "cannot get valid size from specified dimension range. Most likely the range contains 0 or negative values in them." ); } size *= dims[i]; } return size; } static computeStrides(dims) { const rank = dims.length; if (rank === 0) { return []; } else if (rank === 1) { return [1]; } const strides = new Array(rank); strides[rank - 1] = 1; strides[rank - 2] = dims[rank - 1]; for (let i = rank - 3; i >= 0; --i) { strides[i] = strides[i + 1] * dims[i + 1]; } return strides; } static transpose(dims) { const copy = dims.slice(); return copy.reverse(); } static indicesToOffset(indices, strides, axis) { if (axis === void 0) { axis = indices.length; } let offset = 0; for (let i = 0; i < axis; ++i) { offset += strides[i] * indices[i]; } return offset; } static offsetToIndices(offset, strides) { const rank = strides.length; if (rank === 0) { return []; } else if (rank === 1) { return [offset * strides[0]]; } const indices = new Array(strides.length); for (let i = 0; i < indices.length - 1; ++i) { indices[i] = Math.floor(offset / strides[i]); offset -= indices[i] * strides[i]; } indices[indices.length - 1] = offset; return indices; } /** * normalize axis of range [-r, r) into [0, r). */ static normalizeAxis(axis, tensorRank) { if (axis < -tensorRank && axis >= tensorRank) { throw new Error("unsupported axis for this operation."); } return axis < 0 ? axis + tensorRank : axis; } static normalizeAxes(axes, tensorRank) { return axes.map((x) => this.normalizeAxis(x, tensorRank)); } // Increment an index into a tensor (in lexicographic // ordering), wrapping around the specified upper_bound. /** * Increment an index into a tensor (in lexicographic ordering), wrapping around the specified upper_bound. * @param index Given index to increment (Will be mutated) * @param dims The dimensions of the tensor for which the given index corresponds to * @param axisToIncrementOn The 1-indexed axis to increment on. If undefined, axisToIncrementOn == rank */ static incrementIndex(index, dims, axisToIncrementOn) { if (dims.length === 0 || index.length === 0) { throw new Error("Index incrementing unsupported for scalar Tensor"); } if (axisToIncrementOn === void 0) { axisToIncrementOn = dims.length; } else { if (axisToIncrementOn <= 0 || axisToIncrementOn > dims.length) { throw new Error("Incorrect axis to increment on"); } } for (let k = axisToIncrementOn - 1; k >= 0; --k) { index[k]++; if (index[k] < dims[k]) { break; } index[k] = 0; } } /** * Produces a new dimensions array based on the values in the 'originalDimensions' and 'shape' array * Used in Reshape * @param originalDims Original Shape array * @param shapeHints array containing values to compute the new dimensions * For example: * originalDims = [2,2] and shapeHints = [0,-1] will return [2,2] * originalDims = [2,2] and shapeHints = [4] will return [4] * originalDims = [2,2] and shapeHints = [5] will throw an exception * https://github.com/onnx/onnx/blob/main/docs/Operators.md#Reshape */ static calculateReshapedDims(originalDims, shapeHints) { if (shapeHints.length === 0) { if (originalDims.length === 0 || _ShapeUtil.size(originalDims) === 1) { return []; } else { throw new Error("cannot reshape to a scalar Tensor"); } } const nDims = shapeHints.length; const reshapedDims = new Array(nDims); let unknownDimension = -1; let newTensorSize = 1; for (let i = 0; i < nDims; i++) { if (shapeHints[i] < -1) { throw new Error("a dimension in shape hints cannot be less than -1"); } if (shapeHints[i] === -1) { if (unknownDimension !== -1) { throw new Error("at most one dimension in shape hints can be -1"); } unknownDimension = i; } else { if (shapeHints[i] === 0) { if (i >= originalDims.length) { throw new Error("the dimension with value zero exceeds the dimension size of the input tensor"); } reshapedDims[i] = originalDims[i]; } else { reshapedDims[i] = shapeHints[i]; } newTensorSize *= reshapedDims[i]; } } const oldTensorSize = _ShapeUtil.size(originalDims); if (unknownDimension !== -1) { if (oldTensorSize % newTensorSize !== 0) { throw new Error( `the input tensor cannot be reshaped to the requested shape. Input shape: [${originalDims}] Output shape: [${shapeHints}]` ); } reshapedDims[unknownDimension] = oldTensorSize / newTensorSize; } else { if (newTensorSize !== oldTensorSize) { throw new Error("reshapedDims and originalDims don't have matching sizes"); } } return reshapedDims; } /** * Sorts a given array based on the indices in the Perm array * Used in Transpose * @param a Array to be sorted such as dims or strides * @param perm Perm given; if null a will be reversed */ static sortBasedOnPerm(a, perm) { if (perm) { return perm.map((v) => a[v]); } else { return a.slice().reverse(); } } /** * Pads a given shape according to the padding values * @param dims shape of the Tensor to be padded * @param pad pad values */ static padShape(dims, pad) { const rank = dims.length; return dims.map((v, i) => v + pad[i] + pad[i + rank]); } /** * Determines if the two shapes are identical * @param shape1 * @param shape2 */ static areEqual(shape1, shape2) { if (shape1.length !== shape2.length) { return false; } return shape1.every((v, i) => v === shape2[i]); } /** * Validates if the given `dims` or `shape` is valid in ONNX.js context and returns data size * @param dims - input `dims` that needs to be checked */ static validateDimsAndCalcSize(dims) { if (dims.length > 6) { throw new TypeError("Only rank 0 to 6 is supported for tensor shape."); } let size = 1; for (const n of dims) { if (!Number.isInteger(n)) { throw new TypeError(`Invalid shape: ${n} is not an integer`); } if (n < 0 || n > 2147483647) { throw new TypeError(`Invalid shape: length ${n} is not allowed`); } size *= n; } return size; } /** * Determines the shape of output tensor y = flatten(x, axis) * @param dims - shape of input tensor * @param axis - flatten axis, in the range [-r, r] */ static flattenShape(dims, axis) { if (axis < 0) { axis += dims.length; } const total = dims.reduce((x, y) => x * y, 1); const right = dims.slice(axis).reduce((x, y) => x * y, 1); const outputDims = [total / right, right]; return outputDims; } /** * Determines the shape of output tensor y = squeeze(x, axes) * @param dims - shape of input tensor * @param axes - squeeze axes */ static squeezeShape(dims, axes) { const outputDims = new Array(); axes = _ShapeUtil.normalizeAxes(axes, dims.length); for (let i = 0; i < dims.length; i++) { const inSqueezeList = axes.indexOf(i) >= 0; if (inSqueezeList && dims[i] !== 1) { throw new Error("squeeze an axis of size different than 1"); } if (axes.length === 0 && dims[i] > 1 || axes.length > 0 && !inSqueezeList) { outputDims.push(dims[i]); } } return outputDims; } /** * Determines the shape of output tensor y = unsqueeze(x, axes) * @param dims - shape of input tensor * @param axes - unsqueeze axes */ static unsqueezeShape(dims, axes) { const outputDims = new Array(dims.length + axes.length); outputDims.fill(0); for (let i = 0; i < axes.length; i++) { const axis = _ShapeUtil.normalizeAxis(axes[i], outputDims.length); if (axis >= outputDims.length) { throw new Error("'axes' has an out of range axis"); } if (outputDims[axis] !== 0) { throw new Error("'axes' has a duplicate axis"); } outputDims[axis] = 1; } let inputDimsIterator = 0; for (let i = 0; i < outputDims.length; i++) { if (outputDims[i] === 0) { outputDims[i] = dims[inputDimsIterator++]; } } if (inputDimsIterator !== dims.length) { throw new Error("the unsqueezed dimension could not be established"); } return outputDims; } }; SplitUtil = class _SplitUtil { /** * Calculates new Shapes from existing one and the splits given along the axis provides * @param dims Shape of the Tensor to be splitted into two or more Shapes * @param axis The dimension along which the Tensor will be split * @param splits Offsets for the start of each split */ static splitShape(dims, axis, split2, numOutputs) { if (split2.length === 0) { if (!numOutputs) { throw new Error("need to know number of outputs when the 'split' attribute is not specified"); } _SplitUtil.determineSplit(dims[axis], numOutputs, split2); } const shapes = []; const offsets = [0]; for (let i = 0; i < split2.length; ++i) { if (i !== 0) { offsets.push(offsets[i - 1] + split2[i - 1]); } const shape2 = dims.slice(); shape2[axis] = split2[i]; shapes.push(shape2); } return [shapes, offsets]; } static determineSplit(numElementsAlongAxis, numOutputs, split2) { if (numElementsAlongAxis % numOutputs !== 0) { throw new Error("cannot split tensor to equal sized parts"); } for (let i = 0; i < numOutputs; ++i) { split2.push(numElementsAlongAxis / numOutputs); } } }; PoolConvUtil = class _PoolConvUtil { /** * Adjust the kernel, strides, pads to correct rank. Set to default value if not present * @param isGlobalOperator If true, perform global pooling. * @param inputDims The input tensor dimension. * @param kernelShape The size of the kernel along each axis. * @param strides Stride along each axis. * @param dilations Dilation along each axis. * @param pads Padding for the beginning and ending along each axis. */ static adjustPoolAttributes(isGlobalOperator, inputDims, kernelShape, strides, dilations, pads) { if (!isGlobalOperator && kernelShape.length !== inputDims.length - 2) { throw new Error("length of specified kernel shapes should be 2 less than length of input dimensions"); } if (isGlobalOperator) { for (let dim = 0; dim < inputDims.length - 2; dim++) { if (dim >= kernelShape.length) { kernelShape.push(inputDims[dim + 2]); } else { kernelShape[dim] = inputDims[dim + 2]; } } } for (let dim = 0; dim < kernelShape.length; dim++) { if (dim < strides.length) { if (strides[dim] < 0) { throw new Error("strides should be greater than or equal to 1"); } } else { strides.push(1); } } for (let dim = 0; dim < kernelShape.length; dim++) { if (dim < dilations.length) { if (dilations[dim] < 0) { throw new Error("dilations should be greater than or equal to 1"); } } else { dilations.push(1); } } for (let dim = 0; dim < kernelShape.length * 2; dim++) { if (dim < pads.length) { if (pads[dim] < 0) { throw new Error("pad should be greater than or equal to 1"); } } else { pads.push(0); } } for (let dim = 0; dim < kernelShape.length; dim++) { if (kernelShape[dim] <= 0) { throw new Error("kernel shapes need to be greater than 0"); } if (pads[dim] >= kernelShape[dim] || pads[dim + kernelShape.length] >= kernelShape[dim]) { throw new Error("pads should be smaller than kernel"); } } } // adjust pad values based on 'autoPad' attribute static adjustPadsBasedOnAutoPad(inputDims, strides, dilations, kernelShape, pads, autoPad) { if (!autoPad) { return; } if (pads.length !== 2 * (inputDims.length - 2)) { throw new Error("length of pads should be twice the length of data dimensions"); } if (strides.length !== inputDims.length - 2) { throw new Error("length of strides should be the length of data dimensions"); } if (kernelShape.length !== inputDims.length - 2) { throw new Error("length of kernel shapes should be the length of data dimensions"); } for (let dim = 0; dim < inputDims.length - 2; dim++) { _PoolConvUtil.adjustPadAndReturnShape( inputDims[dim + 2], strides[dim], dilations[dim], kernelShape[dim], pads, dim, dim + inputDims.length - 2, autoPad ); } } /** * Calculate the output shape for Pool ops based on input attributes. (Should be used only for Pool ops) * @param isGlobalOperator If true, perform global pooling. * @param inputDims The input tensor dimension. (inputs[0].dims) * @param strides Stride along each axis. * @param dilations Dilation along each axis. * @param kernelShape The size of the kernel along each axis. * @param pads Padding for the beginning and ending along each axis. * @param autoPad DEPRECATED attribute supported for legacy models. Specifies how to implicitly calculate pads in each * dimension. Can take values NOTSET, SAME_UPPER, SAME_LOWER, or VALID. */ static computePoolOutputShape(isGlobalOperator, inputDims, strides, dilations, kernelShape, pads, autoPad) { if (inputDims.length <= 0) { throw new Error("input shape must be of size greater than 0"); } const outputDims = [inputDims[0], inputDims[1]]; _PoolConvUtil.computeShapeHelper( isGlobalOperator, inputDims, outputDims, strides, dilations, kernelShape, pads, autoPad ); return outputDims; } /** * Calculate the output shape for Conv op based on input attributes. (Should be used only for Conv op) * @param inputDims The input tensor dimension. (inputs[0].dims) * @param filterDims The filter tensor dimension. (inputs[1].dims) * @param strides Stride along each axis. * @param kernelShape The size of the kernel along each axis. * @param pads Padding for the beginning and ending along each axis. * @param autoPad DEPRECATED attribute supported for legacy models. Specifies how to implicitly calculate pads in each * dimension. Can take values NOTSET, SAME_UPPER, SAME_LOWER, or VALID. */ static computeConvOutputShape(inputDims, filterDims, strides, dilations, kernelShape, pads, autoPad) { if (inputDims.length <= 0 || filterDims.length <= 0) { throw new Error("invalid input tensor dims or invalid filter tensor dims"); } const outputDims = [inputDims[0], filterDims[0]]; _PoolConvUtil.computeShapeHelper(false, inputDims, outputDims, strides, dilations, kernelShape, pads, autoPad); return outputDims; } // will compute output shapes for data dimensions ONLY (i.e.) no batch size and channels // called by computePoolOutputShape() and computeConvOutputShape() // adjust pads based on 'autoPad' attribute prior to shape computation static computeShapeHelper(isGlobalOperator, inputDims, outputDims, strides, dilations, kernelShape, pads, autoPad) { if (isGlobalOperator) { for (let dim = 0; dim < inputDims.length - 2; dim++) { outputDims.push(1); } } else { for (let dim = 0; dim < inputDims.length - 2; dim++) { outputDims.push( _PoolConvUtil.adjustPadAndReturnShape( inputDims[dim + 2], strides[dim], dilations[dim], kernelShape[dim], pads, dim, dim + inputDims.length - 2, autoPad ) ); } } } // helper for computeShapeHelper() and adjustPadsBasedOnAutoPad() // adjusts pad value for given 'autoPad' string and computes output shape along a particular dimension static adjustPadAndReturnShape(inSize, stride, dilation, kernel, pads, padHeadIndex, padTailIndex, autoPad) { const dkernel = dilation * (kernel - 1) + 1; if (autoPad && autoPad !== "NOTSET") { switch (autoPad) { case "VALID": pads[padHeadIndex] = 0; pads[padTailIndex] = 0; return Math.floor((inSize - dkernel) / stride + 1); case "SAME_LOWER": case "SAME_UPPER": if (dilation !== 1) { throw new Error("Dilation not supported for SAME_UPPER or SAME_LOWER"); } else { const legacyTargetSize = (inSize + stride - 1) / stride; const padNeeded = (legacyTargetSize - 1) * stride + kernel - inSize; pads[padHeadIndex] = autoPad === "SAME_LOWER" ? Math.floor((padNeeded + 1) / 2) : Math.floor(padNeeded / 2); pads[padTailIndex] = padNeeded - pads[padHeadIndex]; return Math.floor((inSize + padNeeded - kernel) / stride + 1); } default: throw new Error("Unsupported AutoPad type"); } } else { return Math.floor((inSize + pads[padHeadIndex] + pads[padTailIndex] - dkernel) / stride + 1); } } }; MIN_CLIP = -34028234663852886e22; MAX_CLIP = 34028234663852886e22; } }); // web/lib/onnxjs/tensor.ts function sizeof(type) { switch (type) { case "bool": case "int8": case "uint8": return 1; case "int16": case "uint16": return 2; case "int32": case "uint32": case "float32": return 4; case "float64": return 8; default: throw new Error(`cannot calculate sizeof() on type ${type}`); } } function sizeofProto(type) { switch (type) { case import_onnx2.onnx.TensorProto.DataType.UINT8: case import_onnx2.onnx.TensorProto.DataType.INT8: case import_onnx2.onnx.TensorProto.DataType.BOOL: return 1; case import_onnx2.onnx.TensorProto.DataType.UINT16: case import_onnx2.onnx.TensorProto.DataType.INT16: return 2; case import_onnx2.onnx.TensorProto.DataType.FLOAT: case import_onnx2.onnx.TensorProto.DataType.INT32: case import_onnx2.onnx.TensorProto.DataType.UINT32: return 4; case import_onnx2.onnx.TensorProto.DataType.INT64: case import_onnx2.onnx.TensorProto.DataType.DOUBLE: case import_onnx2.onnx.TensorProto.DataType.UINT64: return 8; default: throw new Error(`cannot calculate sizeof() on type ${import_onnx2.onnx.TensorProto.DataType[type]}`); } } function createView(dataBuffer, type) { return new (dataviewConstructor(type))(dataBuffer); } function dataviewConstructor(type) { switch (type) { case "bool": case "uint8": return Uint8Array; case "int8": return Int8Array; case "int16": return Int16Array; case "uint16": return Uint16Array; case "int32": return Int32Array; case "uint32": return Uint32Array; case "int64": return BigInt64Array; case "float32": return Float32Array; case "float64": return Float64Array; default: throw new Error("unspecified error"); } } function longToNumber(i, type) { if (type === import_onnx2.onnx.TensorProto.DataType.INT64 || type === import_tensor_data_type.TensorDataType.INT64) { if (i.greaterThanOrEqual(2147483648) || i.lessThan(-2147483648)) { throw new TypeError("int64 is not supported"); } } else if (type === import_onnx2.onnx.TensorProto.DataType.UINT32 || type === import_tensor_data_type.TensorDataType.UINT32 || type === import_onnx2.onnx.TensorProto.DataType.UINT64 || type === import_tensor_data_type.TensorDataType.UINT64) { if (i.greaterThanOrEqual(4294967296) || i.lessThan(0)) { throw new TypeError("uint64 is not supported"); } } else { throw new TypeError(`not a LONG type: ${import_onnx2.onnx.TensorProto.DataType[type]}`); } return i.toNumber(); } function readProto(view, type, byteOffset) { switch (type) { case import_onnx2.onnx.TensorProto.DataType.BOOL: case import_onnx2.onnx.TensorProto.DataType.UINT8: return view.getUint8(byteOffset); case import_onnx2.onnx.TensorProto.DataType.INT8: return view.getInt8(byteOffset); case import_onnx2.onnx.TensorProto.DataType.UINT16: return view.getUint16(byteOffset, true); case import_onnx2.onnx.TensorProto.DataType.INT16: return view.getInt16(byteOffset, true); case import_onnx2.onnx.TensorProto.DataType.FLOAT: return view.getFloat32(byteOffset, true); case import_onnx2.onnx.TensorProto.DataType.INT32: return view.getInt32(byteOffset, true); case import_onnx2.onnx.TensorProto.DataType.UINT32: return view.getUint32(byteOffset, true); case import_onnx2.onnx.TensorProto.DataType.INT64: return longToNumber( long_default.fromBits(view.getUint32(byteOffset, true), view.getUint32(byteOffset + 4, true), false), type ); case import_onnx2.onnx.TensorProto.DataType.DOUBLE: return view.getFloat64(byteOffset, true); case import_onnx2.onnx.TensorProto.DataType.UINT64: return longToNumber( long_default.fromBits(view.getUint32(byteOffset, true), view.getUint32(byteOffset + 4, true), true), type ); default: throw new Error(`cannot read from DataView for type ${import_onnx2.onnx.TensorProto.DataType[type]}`); } } var import_guid_typescript, import_onnx2, Tensor4; var init_tensor2 = __esm({ "web/lib/onnxjs/tensor.ts"() { "use strict"; import_guid_typescript = __toESM(require_guid()); init_long(); init_ort_generated(); import_onnx2 = __toESM(require_onnx()); init_util(); Tensor4 = class _Tensor { constructor(dims, type, dataProvider, asyncDataProvider, cache2, dataId = import_guid_typescript.Guid.create()) { this.dims = dims; this.type = type; this.dataProvider = dataProvider; this.asyncDataProvider = asyncDataProvider; this.cache = cache2; this.dataId = dataId; this.size = ShapeUtil.validateDimsAndCalcSize(dims); const size = this.size; const empty = dataProvider === void 0 && asyncDataProvider === void 0 && cache2 === void 0; if (cache2 !== void 0) { if (cache2.length !== size) { throw new RangeError("Input dims doesn't match data length."); } } if (type === "string") { if (cache2 !== void 0 && (!Array.isArray(cache2) || !cache2.every((i) => typeof i === "string"))) { throw new TypeError("cache should be a string array"); } if (empty) { this.cache = new Array(size); } } else { if (cache2 !== void 0) { const constructor = dataviewConstructor(type); if (!(cache2 instanceof constructor)) { throw new TypeError(`cache should be type ${constructor.name}`); } } if (empty) { const buf = new ArrayBuffer(size * sizeof(type)); this.cache = createView(buf, type); } } } /** * get the underlying tensor data */ get data() { if (this.cache === void 0) { const data = this.dataProvider(this.dataId); if (data.length !== this.size) { throw new Error("Length of data provided by the Data Provider is inconsistent with the dims of this Tensor."); } this.cache = data; } return this.cache; } /** * get the underlying string tensor data. Should only use when type is STRING */ get stringData() { if (this.type !== "string") { throw new TypeError("data type is not string"); } return this.data; } /** * get the underlying integer tensor data. Should only use when type is one of the following: (UINT8, INT8, UINT16, * INT16, INT32, UINT32, BOOL) */ get integerData() { switch (this.type) { case "uint8": case "int8": case "uint16": case "int16": case "int32": case "uint32": case "bool": return this.data; default: throw new TypeError("data type is not integer (uint8, int8, uint16, int16, int32, uint32, bool)"); } } /** * get the underlying float tensor data. Should only use when type is one of the following: (FLOAT, DOUBLE) */ get floatData() { switch (this.type) { case "float32": case "float64": return this.data; default: throw new TypeError("data type is not float (float32, float64)"); } } /** * get the underlying number tensor data. Should only use when type is one of the following: (UINT8, INT8, UINT16, * INT16, INT32, UINT32, BOOL, FLOAT, DOUBLE) */ get numberData() { if (this.type !== "string") { return this.data; } throw new TypeError("type cannot be non-number (string)"); } /** * get value of an element at the given indices */ get(indices) { return this.data[ShapeUtil.indicesToOffset(indices, this.strides)]; } /** * set value of an element at the given indices */ set(indices, value) { this.data[ShapeUtil.indicesToOffset(indices, this.strides)] = value; } /** * get the underlying tensor data asynchronously */ async getData() { if (this.cache === void 0) { this.cache = await this.asyncDataProvider(this.dataId); } return this.cache; } /** * get the strides for each dimension */ get strides() { if (!this._strides) { this._strides = ShapeUtil.computeStrides(this.dims); } return this._strides; } /** * Construct new Tensor from a ONNX Tensor object * @param tensorProto the ONNX Tensor */ static fromProto(tensorProto) { if (!tensorProto) { throw new Error("cannot construct Value from an empty tensor"); } const type = ProtoUtil.tensorDataTypeFromProto(tensorProto.dataType); const dims = ProtoUtil.tensorDimsFromProto(tensorProto.dims); const value = new _Tensor(dims, type); if (type === "string") { tensorProto.stringData.forEach((str, i) => { value.data[i] = decodeUtf8String(str); }); } else if (tensorProto.rawData && typeof tensorProto.rawData.byteLength === "number" && tensorProto.rawData.byteLength > 0) { const dataDest = value.data; const dataSource = new DataView( tensorProto.rawData.buffer, tensorProto.rawData.byteOffset, tensorProto.rawData.byteLength ); const elementSize = sizeofProto(tensorProto.dataType); const length = tensorProto.rawData.byteLength / elementSize; if (tensorProto.rawData.byteLength % elementSize !== 0) { throw new Error("invalid buffer length"); } if (dataDest.length !== length) { throw new Error("buffer length mismatch"); } for (let i = 0; i < length; i++) { const n = readProto(dataSource, tensorProto.dataType, i * elementSize); dataDest[i] = n; } } else { let array; switch (tensorProto.dataType) { case import_onnx2.onnx.TensorProto.DataType.FLOAT: array = tensorProto.floatData; break; case import_onnx2.onnx.TensorProto.DataType.INT32: case import_onnx2.onnx.TensorProto.DataType.INT16: case import_onnx2.onnx.TensorProto.DataType.UINT16: case import_onnx2.onnx.TensorProto.DataType.INT8: case import_onnx2.onnx.TensorProto.DataType.UINT8: case import_onnx2.onnx.TensorProto.DataType.BOOL: array = tensorProto.int32Data; break; case import_onnx2.onnx.TensorProto.DataType.INT64: array = tensorProto.int64Data; break; case import_onnx2.onnx.TensorProto.DataType.DOUBLE: array = tensorProto.doubleData; break; case import_onnx2.onnx.TensorProto.DataType.UINT32: case import_onnx2.onnx.TensorProto.DataType.UINT64: array = tensorProto.uint64Data; break; default: throw new Error("unspecific error"); } if (array === null || array === void 0) { throw new Error("failed to populate data from a tensorproto value"); } const data = value.data; if (data.length !== array.length) { throw new Error("array length mismatch"); } for (let i = 0; i < array.length; i++) { const element = array[i]; if (long_default.isLong(element)) { data[i] = longToNumber(element, tensorProto.dataType); } else { data[i] = element; } } } return value; } /** * Construct new Tensor from raw data * @param data the raw data object. Should be a string array for 'string' tensor, and the corresponding typed array * for other types of tensor. * @param dims the dimensions of the tensor * @param type the type of the tensor */ static fromData(data, dims, type) { return new _Tensor(dims, type, void 0, void 0, data); } static fromOrtTensor(ortTensor) { if (!ortTensor) { throw new Error("cannot construct Value from an empty tensor"); } const dims = ProtoUtil.tensorDimsFromORTFormat(ortTensor); const type = ProtoUtil.tensorDataTypeFromProto(ortTensor.dataType()); const value = new _Tensor(dims, type); if (type === "string") { for (let i = 0; i < ortTensor.stringDataLength(); i++) { value.data[i] = ortTensor.stringData(i); } } else if (ortTensor.rawDataArray() && typeof ortTensor.rawDataLength() === "number" && ortTensor.rawDataLength() > 0) { const dataDest = value.data; const dataSource = new DataView( ortTensor.rawDataArray().buffer, ortTensor.rawDataArray().byteOffset, ortTensor.rawDataLength() ); const elementSize = sizeofProto(ortTensor.dataType()); const length = ortTensor.rawDataLength() / elementSize; if (ortTensor.rawDataLength() % elementSize !== 0) { throw new Error("invalid buffer length"); } if (dataDest.length !== length) { throw new Error("buffer length mismatch"); } for (let i = 0; i < length; i++) { const n = readProto(dataSource, ortTensor.dataType(), i * elementSize); dataDest[i] = n; } } return value; } }; } }); // web/lib/onnxjs/backends/webgl/glsl-source.ts function getGlsl(version3) { return version3 === 1 ? GLSL_ES_2_0 : GLSL_ES_3_0; } function getVertexShaderSource(version3) { const glsl = getGlsl(version3); return `${glsl.version} precision highp float; ${glsl.attribute} vec3 position; ${glsl.attribute} vec2 textureCoord; ${glsl.varyingVertex} vec2 TexCoords; void main() { gl_Position = vec4(position, 1.0); TexCoords = textureCoord; }`; } function getFragShaderPreamble(version3) { const glsl = getGlsl(version3); return `${glsl.version} precision highp float; precision highp int; precision highp sampler2D; ${glsl.varyingFrag} vec2 TexCoords; ${glsl.outputDeclaration} const vec2 halfCR = vec2(0.5, 0.5); // Custom vector types to handle higher dimenalities. struct ivec5 { int x; int y; int z; int w; int u; }; struct ivec6 { int x; int y; int z; int w; int u; int v; }; int imod(int x, int y) { return x - y * (x / y); } `; } function getDefaultFragShaderMain(version3, outputShapeLength) { const glsl = getGlsl(version3); return ` void main() { int indices[${outputShapeLength}]; toVec(TexCoords, indices); vec4 result = vec4(process(indices)); ${glsl.output} = result; } `; } var GLSL_ES_2_0, GLSL_ES_3_0; var init_glsl_source = __esm({ "web/lib/onnxjs/backends/webgl/glsl-source.ts"() { "use strict"; GLSL_ES_2_0 = { version: "", attribute: "attribute", varyingVertex: "varying", varyingFrag: "varying", texture2D: "texture2D", output: "gl_FragColor", outputDeclaration: "" }; GLSL_ES_3_0 = { version: "#version 300 es", attribute: "in", varyingVertex: "out", varyingFrag: "in", texture2D: "texture", output: "outputColor", outputDeclaration: "out vec4 outputColor;" }; } }); // web/lib/onnxjs/backends/webgl/types.ts var init_types = __esm({ "web/lib/onnxjs/backends/webgl/types.ts"() { "use strict"; } }); // web/lib/onnxjs/backends/webgl/utils.ts async function repeatedTry(checkFn, delayFn = (_counter) => 0, maxCounter) { return new Promise((resolve, reject) => { let tryCount = 0; const tryFn = () => { if (checkFn()) { resolve(); return; } tryCount++; const nextBackoff = delayFn(tryCount); if (maxCounter != null && tryCount >= maxCounter) { reject(); return; } setTimeout(tryFn, nextBackoff); }; tryFn(); }); } function generateShaderFuncNameFromInputSamplerName(samplerName) { assert(typeof samplerName !== "undefined" && samplerName.length !== 0, () => "empty string found for sampler name"); return "get" + samplerName.charAt(0).toUpperCase() + samplerName.slice(1); } function generateShaderFuncNameFromInputSamplerNameAtOutCoords(samplerName) { assert(typeof samplerName !== "undefined" && samplerName.length !== 0, () => "empty string found for sampler name"); return "get" + samplerName.charAt(0).toUpperCase() + samplerName.slice(1) + "AtOutCoords"; } function squeezeInputShape(inputShape, squeezedShape) { let newInputShape = JSON.parse(JSON.stringify(inputShape)); newInputShape = squeezedShape; return newInputShape; } function getSqueezedParams(params, keptDims) { return keptDims.map((d) => params[d]).join(", "); } function getCoordsDataType(rank) { if (rank <= 1) { return "int"; } else if (rank === 2) { return "ivec2"; } else if (rank === 3) { return "ivec3"; } else if (rank === 4) { return "ivec4"; } else if (rank === 5) { return "ivec5"; } else if (rank === 6) { return "ivec6"; } else { throw Error(`GPU for rank ${rank} is not yet supported`); } } function getGlChannels(rank = 6) { return ["x", "y", "z", "w", "u", "v"].slice(0, rank); } var init_utils = __esm({ "web/lib/onnxjs/backends/webgl/utils.ts"() { "use strict"; init_util(); } }); // web/lib/onnxjs/backends/webgl/ops/packing-utils.ts function getVecChannels(name2, rank) { return getGlChannels(rank).map((d) => `${name2}.${d}`); } function getChannels(name2, rank) { if (rank === 1) { return [name2]; } return getVecChannels(name2, rank); } function unpackFromChannel() { return ` float getChannel(vec4 frag, int dim) { int modCoord = imod(dim, 2); return modCoord == 0 ? frag.r : frag.g; } float getChannel(vec4 frag, vec2 innerDims) { vec2 modCoord = mod(innerDims, 2.); return modCoord.x == 0. ? (modCoord.y == 0. ? frag.r : frag.g) : (modCoord.y == 0. ? frag.b : frag.a); } `; } var init_packing_utils = __esm({ "web/lib/onnxjs/backends/webgl/ops/packing-utils.ts"() { "use strict"; init_utils(); } }); // web/lib/onnxjs/backends/webgl/ops/pack.ts function getOutOfBoundsCondition(rank, shape2, dims) { if (rank === 0) { return "false"; } if (rank === 1) { return `rc > ${shape2[0]}`; } let cond = ""; for (let i = rank - 2; i < rank; i++) { cond += `${dims[i]} >= ${shape2[i - rank + 2]}`; if (i < rank - 1) { cond += "||"; } } return cond; } function getOutput(shape2, dims) { const rank = shape2.length; if (rank === 0) { return "getA(), 0, 0, 0"; } if (rank === 1) { return `getA(rc), rc + 1 >= ${shape2[0]} ? 0. : getA(rc + 1), 0, 0`; } const coord00 = "r, c"; const coord01 = "r, cp1"; const coord10 = "rp1, c"; const coord11 = "rp1, cp1"; let D = ""; if (rank > 2) { for (let i = 0; i < rank - 2; ++i) { D = D + `${dims[i]},`; } } return `getA(${D}${coord00}), rEdge ? 0. : getA(${D}${coord10}), cEdge ? 0. : getA(${D}${coord01}), rEdge || cEdge ? 0. : getA(${D}${coord11})`; } function getSetup(rank, dims, rows, cols) { if (rank === 0 || rank === 1) { return ""; } else { const setup = ` int r = ${dims[rank - 2]}; int c = ${dims[rank - 1]}; int rp1 = ${dims[rank - 2]} + 1; int cp1 = ${dims[rank - 1]} + 1; bool rEdge = rp1 >= ${cols}; bool cEdge = cp1 >= ${rows}; `; return setup; } } var packProgramMetadata, createPackProgramInfo, createPackProgramInfoLoader; var init_pack = __esm({ "web/lib/onnxjs/backends/webgl/ops/pack.ts"() { "use strict"; init_glsl_source(); init_types(); init_utils(); init_packing_utils(); packProgramMetadata = { name: "pack", inputNames: ["A"], inputTypes: [1 /* unpackedReversed */] }; createPackProgramInfo = (handler, input) => { const glsl = getGlsl(handler.session.backend.glContext.version); const inputShape = input.dims; const inputRank = inputShape.length; const outputRank = input.dims.length; const coordsDataType = getCoordsDataType(outputRank); const channels = getChannels("rc", outputRank); const setup = getSetup(outputRank, channels, inputShape[inputShape.length - 2], inputShape[inputShape.length - 1]); let reversedInputWH; if (inputRank === 0) { reversedInputWH = [1, 1]; } else if (inputRank === 1) { reversedInputWH = [inputShape[0], 1]; } else { reversedInputWH = [inputShape[outputRank - 1], inputShape[outputRank - 2]]; } const outOfBoundsCondition = getOutOfBoundsCondition(outputRank, reversedInputWH, channels); const output = getOutput(inputShape, channels); const shaderSource = ` void main() { ${coordsDataType} rc = getOutputCoords(); if(${outOfBoundsCondition}) { ${glsl.output} = vec4(0); } else { ${setup} ${glsl.output} = vec4(${output}); } } `; return { ...packProgramMetadata, hasMain: true, output: { dims: input.dims, type: input.type, textureType: 2 /* packed */ }, shaderSource }; }; createPackProgramInfoLoader = (handler, input) => ({ ...packProgramMetadata, get: () => createPackProgramInfo(handler, input) }); } }); // web/lib/onnxjs/backends/webgl/ops/reshape-packed.ts function processDims3D(shape2) { if (shape2.length === 0) { return [1, 1, 1]; } let batch = 1; for (let i = 0; i < shape2.length - 2; ++i) { batch *= shape2[i]; } return [batch, shape2.length > 1 ? shape2[shape2.length - 2] : 1, shape2[shape2.length - 1]]; } function isReshapeCheap(dims, reshapedDims) { let isCheapReshape = false; if (dims.length === 0 || reshapedDims.length === 0) { isCheapReshape = true; } else if (dims.length < 2 || reshapedDims.length < 2) { isCheapReshape = dims[dims.length - 1] === reshapedDims[reshapedDims.length - 1]; } else { isCheapReshape = dims[dims.length - 1] === reshapedDims[reshapedDims.length - 1] && dims[dims.length - 2] === reshapedDims[reshapedDims.length - 2]; } return isCheapReshape; } function getReshapedInputCoords(shape2) { const strides = ShapeUtil.computeStrides(shape2); const coords = ["b", "r", "c"]; const index = "index"; const coordsFromIndexSnippet = strides.map((stride, i) => { const line1 = `int ${coords[i]} = ${index} / ${stride}`; const line2 = i === strides.length - 1 ? `int ${coords[i + 1]} = ${index} - ${coords[i]} * ${stride}` : `index -= ${coords[i]} * ${stride}`; return `${line1}; ${line2};`; }).join(""); return ` ivec3 inputCoordsFromReshapedOutCoords(int index) { ${coordsFromIndexSnippet} return ivec3(b, r, c); } `; } function getFlattenedIndexFrom3D(shape2) { const strides = ShapeUtil.computeStrides(shape2); return ` int getFlattenedIndex(ivec3 coords) { // reverse y, z order return coords.x * ${strides[0]} + coords.z * ${strides[1]} + coords.y; } `; } var createPackedReshape3DProgramMetadata, createPackedReshape3DProgramInfo, createPackedReshape3DProgramInfoLoader; var init_reshape_packed = __esm({ "web/lib/onnxjs/backends/webgl/ops/reshape-packed.ts"() { "use strict"; init_util(); init_glsl_source(); init_types(); init_packing_utils(); createPackedReshape3DProgramMetadata = (outputShape3D) => ({ name: "Reshape (packed)", inputTypes: [2 /* packed */], inputNames: ["A"], cacheHint: `${outputShape3D}` }); createPackedReshape3DProgramInfo = (handler, input3D, metadata, outputShape3D) => { const inputShape3D = input3D.dims; const squeezedOutputShape = outputShape3D; let mainLoop = ""; for (let i = 0; i < 4; i++) { let outputCoords = ""; switch (i) { case 0: outputCoords = "outputCoords = rc;"; break; case 1: outputCoords = "outputCoords = ivec3(rc.x, rc.y+1, rc.z);"; break; case 2: outputCoords = "outputCoords = ivec3(rc.x, rc.y, rc.z+1);"; break; case 3: outputCoords = "outputCoords = ivec3(rc.x, rc.y+1, rc.z+1);"; break; default: throw new Error(); } mainLoop += ` ${outputCoords} ${i > 0 ? "if(outputCoords.y < rows && outputCoords.z < cols){" : ""} int flattenedIndex = getFlattenedIndex(outputCoords); ivec3 inputRC = inputCoordsFromReshapedOutCoords(flattenedIndex); vec2 innerDims = vec2(float(inputRC.y),float(inputRC.z)); result[${i}] = getChannel(getA(inputRC.x, inputRC.y, inputRC.z), innerDims); ${i > 0 ? "}" : ""} `; } const glsl = getGlsl(handler.session.backend.glContext.version); const shaderSource = ` ${getReshapedInputCoords(inputShape3D)} ${getFlattenedIndexFrom3D(squeezedOutputShape)} ${unpackFromChannel()} void main() { ivec3 rc = getOutputCoords(); vec4 result = vec4(0.0); ivec3 outputCoords; int rows = ${squeezedOutputShape[2]}; int cols = ${squeezedOutputShape[1]}; ${mainLoop} ${glsl.output} = result; } `; return { ...metadata, output: { dims: squeezedOutputShape, type: input3D.type, textureType: 2 /* packed */ }, shaderSource, hasMain: true }; }; createPackedReshape3DProgramInfoLoader = (handler, input3D, outputShape3D) => { const metadata = createPackedReshape3DProgramMetadata(outputShape3D); return { ...metadata, get: () => createPackedReshape3DProgramInfo(handler, input3D, metadata, outputShape3D) }; }; } }); // web/lib/onnxjs/backends/webgl/ops/uint8-encode.ts var encodeAsUint8; var init_uint8_encode = __esm({ "web/lib/onnxjs/backends/webgl/ops/uint8-encode.ts"() { "use strict"; init_glsl_source(); init_types(); encodeAsUint8 = (inferenceHandler, input) => { const outputShape = input.shape; const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); const shaderSource = ` const float FLOAT_MAX = 1.70141184e38; const float FLOAT_MIN = 1.17549435e-38; bool isNaN(float val) { return (val < 1.0 || 0.0 < val || val == 0.0) ? false : true; } highp vec4 encodeAsUint8(highp float v) { if (isNaN(v)) { return vec4(255, 255, 255, 255); } highp float av = abs(v); if(av < FLOAT_MIN) { return vec4(0.0, 0.0, 0.0, 0.0); } else if(v > FLOAT_MAX) { return vec4(0.0, 0.0, 128.0, 127.0) / 255.0; } else if(v < -FLOAT_MAX) { return vec4(0.0, 0.0, 128.0, 255.0) / 255.0; } highp vec4 c = vec4(0,0,0,0); highp float e = floor(log2(av)); highp float m = exp2(fract(log2(av))) - 1.0; c[2] = floor(128.0 * m); m -= c[2] / 128.0; c[1] = floor(32768.0 * m); m -= c[1] / 32768.0; c[0] = floor(8388608.0 * m); highp float ebias = e + 127.0; c[3] = floor(ebias / 2.0); ebias -= c[3] * 2.0; c[2] += floor(ebias) * 128.0; c[3] += 128.0 * step(0.0, -v); return c / 255.0; } void main() { float value = ${glsl.texture2D}(X,TexCoords).r; ${glsl.output} = encodeAsUint8(value); }`; const programInfo = { name: "Uint8Encode", inputTypes: [0 /* unpacked */], inputNames: ["X"], output: { dims: outputShape, type: input.tensor.type, textureType: 3 /* downloadUint8AsFloat */ }, shaderSource, hasMain: true }; return inferenceHandler.executeProgram(programInfo, [input.tensor]); }; } }); // web/lib/onnxjs/backends/webgl/ops/unpack.ts function getSourceCoords(rank, dims) { if (rank === 1) { return "rc"; } let coords = ""; for (let i = 0; i < rank; i++) { coords += dims[i]; if (i < rank - 1) { coords += ","; } } return coords; } var unpackProgramMetadata, createUnpackProgramInfo, createUnpackProgramInfoLoader; var init_unpack = __esm({ "web/lib/onnxjs/backends/webgl/ops/unpack.ts"() { "use strict"; init_glsl_source(); init_types(); init_utils(); init_packing_utils(); unpackProgramMetadata = { name: "unpack", inputNames: ["A"], inputTypes: [2 /* packed */] }; createUnpackProgramInfo = (handler, input) => { const rank = input.dims.length; const channels = getChannels("rc", rank); const innerDims = channels.slice(-2); const coordsDataType = getCoordsDataType(rank); const unpackChannel = unpackFromChannel(); const isScalar = input.dims.length === 0; const sourceCoords = isScalar ? "" : getSourceCoords(rank, channels); const coords = rank <= 1 ? "rc" : `vec2(${innerDims.join(",")})`; const glsl = getGlsl(handler.session.backend.glContext.version); const shaderSource = ` ${unpackChannel} void main() { ${coordsDataType} rc = getOutputCoords(); // Sample the texture with the coords to get the rgba channel value. vec4 packedInput = getA(${sourceCoords}); ${glsl.output} = vec4(getChannel(packedInput, ${coords}), 0, 0, 0); } `; return { ...unpackProgramMetadata, hasMain: true, output: { dims: input.dims, type: input.type, textureType: 0 /* unpacked */ }, shaderSource }; }; createUnpackProgramInfoLoader = (handler, input) => ({ ...unpackProgramMetadata, get: () => createUnpackProgramInfo(handler, input) }); } }); // web/lib/onnxjs/backends/webgl/texture-data-encoder.ts var RedFloat32DataEncoder, RGBAFloatDataEncoder, Uint8DataEncoder; var init_texture_data_encoder = __esm({ "web/lib/onnxjs/backends/webgl/texture-data-encoder.ts"() { "use strict"; init_instrument(); RedFloat32DataEncoder = class { constructor(gl, channels = 1) { if (channels === 1) { this.internalFormat = gl.R32F; this.format = gl.RED; this.textureType = gl.FLOAT; this.channelSize = channels; } else if (channels === 4) { this.internalFormat = gl.RGBA32F; this.format = gl.RGBA; this.textureType = gl.FLOAT; this.channelSize = channels; } else { throw new Error(`Invalid number of channels: ${channels}`); } } encode(src, textureSize) { let result; let source; if (src.constructor !== Float32Array) { Logger.warning("Encoder", "data was not of type Float32; creating new Float32Array"); source = new Float32Array(src); } if (textureSize * this.channelSize > src.length) { Logger.warning("Encoder", "Source data too small. Allocating larger array"); source = src; result = this.allocate(textureSize * this.channelSize); source.forEach((v, i) => result[i] = v); } else { source = src; result = source; } return result; } allocate(size) { return new Float32Array(size * 4); } decode(buffer, dataSize) { if (this.channelSize === 1) { const filteredData = buffer.filter((_value, index) => index % 4 === 0).subarray(0, dataSize); return filteredData; } return buffer.subarray(0, dataSize); } }; RGBAFloatDataEncoder = class { constructor(gl, channels = 1, textureType) { if (channels !== 1 && channels !== 4) { throw new Error(`Invalid number of channels: ${channels}`); } this.internalFormat = gl.RGBA; this.format = gl.RGBA; this.channelSize = channels; this.textureType = textureType || gl.FLOAT; } encode(src, textureSize) { let dest = src; if (this.channelSize === 1) { Logger.verbose("Encoder", "Exploding into a larger array"); dest = this.allocate(textureSize); src.forEach((v, i) => dest[i * 4] = v); } return dest; } allocate(size) { return new Float32Array(size * 4); } decode(buffer, dataSize) { if (this.channelSize === 1) { const filteredData = buffer.filter((_value, index) => index % 4 === 0).subarray(0, dataSize); return filteredData; } return buffer.subarray(0, dataSize); } }; Uint8DataEncoder = class { constructor(gl, channels = 1) { this.channelSize = 4; if (channels === 1) { this.internalFormat = gl.ALPHA; this.format = gl.ALPHA; this.textureType = gl.UNSIGNED_BYTE; this.channelSize = channels; } else if (channels === 4) { this.internalFormat = gl.RGBA; this.format = gl.RGBA; this.textureType = gl.UNSIGNED_BYTE; this.channelSize = channels; } else { throw new Error(`Invalid number of channels: ${channels}`); } } encode(src, _textureSize) { return new Uint8Array(src.buffer, src.byteOffset, src.byteLength); } allocate(size) { return new Uint8Array(size * this.channelSize); } decode(buffer, dataSize) { if (buffer instanceof Uint8Array) { return buffer.subarray(0, dataSize); } throw new Error(`Invalid array type: ${buffer.constructor}`); } }; } }); // web/lib/onnxjs/backends/webgl/texture-layout.ts var createTextureLayoutFromTextureType, calculateTextureWidthAndHeight, createTextureLayoutFromShape; var init_texture_layout = __esm({ "web/lib/onnxjs/backends/webgl/texture-layout.ts"() { "use strict"; init_util(); init_types(); createTextureLayoutFromTextureType = (textureLayoutStrategy, shape2, textureType) => { const channel = textureType === 0 /* unpacked */ || textureType === 1 /* unpackedReversed */ ? 1 : 4; const isPacked = textureType === 2 /* packed */; const reverseWH = textureType === 1 /* unpackedReversed */ || textureType === 2 /* packed */; const breakAxis = textureType === 4 /* packedLastDimension */ ? shape2.length - 1 : void 0; const unpackedShape = textureType === 4 /* packedLastDimension */ ? shape2.map((d, i) => i === shape2.length - 1 ? d * 4 : d) : void 0; return createTextureLayoutFromShape(textureLayoutStrategy, shape2, channel, unpackedShape, { isPacked, reverseWH, breakAxis }); }; calculateTextureWidthAndHeight = (textureLayoutStrategy, shape2, textureType) => { const layout = createTextureLayoutFromTextureType(textureLayoutStrategy, shape2, textureType); return [layout.width, layout.height]; }; createTextureLayoutFromShape = (textureLayoutStrategy, shape2, channels = 1, unpackedShape, prefs) => { const isPacked = !!(prefs && prefs.isPacked); const [width, height] = textureLayoutStrategy.computeTextureWH(isPacked ? unpackedShape || shape2 : shape2, prefs); const rank = shape2.length; let inferredDims = shape2.slice(0); if (rank === 0) { inferredDims = [1]; } if (channels === 1) { unpackedShape = shape2; } else if (isPacked) { if (channels !== 4) { throw new Error("a packed texture must be 4-channel"); } unpackedShape = shape2; if (rank > 0) { inferredDims[rank - 1] = Math.ceil(inferredDims[rank - 1] / 2); } if (rank > 1) { inferredDims[rank - 2] = Math.ceil(inferredDims[rank - 2] / 2); } } else if (!unpackedShape) { throw new Error("Unpacked shape is needed when using channels > 1"); } return { width, height, channels, isPacked, shape: inferredDims, strides: ShapeUtil.computeStrides(inferredDims), unpackedShape, reversedWH: prefs && prefs.reverseWH }; }; } }); // web/lib/onnxjs/backends/webgl/inference-handler.ts var getProgramInfoUniqueKey, WebGLInferenceHandler; var init_inference_handler = __esm({ "web/lib/onnxjs/backends/webgl/inference-handler.ts"() { "use strict"; init_instrument(); init_tensor2(); init_util(); init_pack(); init_reshape_packed(); init_uint8_encode(); init_unpack(); init_texture_data_encoder(); init_texture_layout(); init_types(); getProgramInfoUniqueKey = (programInfo, inputTextureDatas) => { const inputs = inputTextureDatas.map((texture) => `${texture.unpackedShape.join(",")};${texture.width}x${texture.height}`).join("_"); let key = programInfo.name; if (programInfo.cacheHint) { key += "[" + programInfo.cacheHint + "]"; } key += ":" + inputs; return key; }; WebGLInferenceHandler = class { constructor(session) { this.session = session; this.packedTextureDataCache = /* @__PURE__ */ new Map(); this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); } /** * @returns [width, height] */ calculateTextureWidthAndHeight(shape2, textureType) { return calculateTextureWidthAndHeight(this.session.layoutStrategy, shape2, textureType); } executeProgram(program, inputs) { if (inputs.length < program.inputNames.length) { throw new Error(`Input size mustn't be less than ${program.inputNames.length}.`); } if (program.inputNames.length !== program.inputTypes.length) { throw new Error("input names size does not match input types"); } const inputTextureDatas = []; for (let i = 0; i < program.inputNames.length; ++i) { inputTextureDatas[i] = this.getOrCreateTextureData(inputs[i], program.inputTypes[i]); } const key = getProgramInfoUniqueKey(program, inputTextureDatas); let artifact = this.session.programManager.getArtifact(key); const programInfo = artifact ? artifact.programInfo : typeof program.get === "function" ? program.get() : program; const outputTextureLayout = createTextureLayoutFromTextureType( this.session.layoutStrategy, programInfo.output.dims, programInfo.output.textureType ); const outputTextureData = this.createTextureData(outputTextureLayout, programInfo.output.type); if (!artifact) { artifact = this.session.programManager.build(programInfo, inputTextureDatas, outputTextureData); this.session.programManager.setArtifact(key, artifact); } this.runProgram(artifact, inputTextureDatas, outputTextureData); return outputTextureData; } run(program, inputs) { const outputTextureData = this.executeProgram(program, inputs); return outputTextureData.tensor; } runProgram(artifact, inputs, output) { for (let i = 0; i < inputs.length; ++i) { if (!!inputs[i].isPacked !== (artifact.programInfo.inputTypes[i] === 2 /* packed */)) { throw new Error(`input[${i}] property packed inconsistent`); } } if (!!output.isPacked !== (artifact.programInfo.output.textureType === 2 /* packed */)) { throw new Error("output property packed inconsistent"); } this.session.programManager.run(artifact, inputs, output); } /** * Create a TextureData object from a tensor. * Usage = EncoderUsage.UploadOnly. * If a related texture data is found in cache, returns it; * Otherwise: * Creates a new texture layout if not provided; * Creates WebGLTexture with the layout; * Upload tensor data to the texture; * Creates a texture data object associated with the given tensor. * @param tensor the tensor with data to upload */ getOrCreateTextureData(tensor, textureType) { let td = this.getTextureData(tensor.dataId, textureType === 2 /* packed */); if (!td) { td = this.getTextureData(tensor.dataId, textureType !== 2 /* packed */); if (td) { if (textureType === 2 /* packed */) { return this.pack(td); } else { return this.unpack(td); } } } if (!td) { const layout = createTextureLayoutFromTextureType(this.session.layoutStrategy, tensor.dims, textureType); if (textureType === 4 /* packedLastDimension */) { const group = 1; const channels = 4; const shape2 = tensor.dims; if (shape2.length === 4) { const adjustedKernelShape = [shape2[0], Math.ceil(shape2[1] * shape2[2] * shape2[3] / channels)]; const adjustedLayout = createTextureLayoutFromTextureType( this.session.layoutStrategy, adjustedKernelShape, textureType ); let buffer = tensor.numberData; if (shape2[1] * shape2[2] * shape2[3] % channels !== 0) { const numFeatureMaps = shape2[0]; const oldRowSize = shape2[1] * shape2[2] * shape2[3]; const newRowSize = Math.ceil(oldRowSize * group / channels) * channels; const newSize = numFeatureMaps * newRowSize; buffer = new Float32Array(newSize); for (let f = 0; f < numFeatureMaps; ++f) { const oldOffset = f * oldRowSize; const newOffset = f * newRowSize + f % group * oldRowSize; buffer.set(tensor.numberData.subarray(oldOffset, oldOffset + oldRowSize), newOffset); } } return this.createTextureData(adjustedLayout, tensor.type, buffer, tensor, 1 /* UploadOnly */); } } if (textureType === 2 /* packed */) { const unpackedTextureLayout = createTextureLayoutFromShape(this.session.layoutStrategy, tensor.dims, 1, [], { reverseWH: true }); const unpackedTextureData = this.createTextureData( unpackedTextureLayout, tensor.type, tensor.numberData, tensor, 1 /* UploadOnly */ ); td = this.pack(unpackedTextureData); } else { td = this.createTextureData(layout, tensor.type, tensor.numberData, tensor, 1 /* UploadOnly */); } } return td; } /** * Create a TextureData object using the given data and bind to the given tensor. * Usage = EncoderUsage.UploadOnly. * NOTE: this function is a hack for Conv implementation. should remove this function, after rewriting Conv * implementation by Graph.Transformer * @param dataType the tensor data type * @param data the actual data to upload * @param tensor the tensor to bind. tensor's data is ignored. */ createTextureDataFromLayoutBindTensor(layout, dataType, data, tensor) { return this.createTextureData(layout, dataType, data, tensor, 1 /* UploadOnly */); } createTextureData(layout, dataType, data, tensor, usage) { Logger.verbose("InferenceHandler", `Creating TextureData: layout:[${JSON.stringify(layout)}]`); const texture = this.session.textureManager.createTextureFromLayout(dataType, layout, data, usage); return this.createTextureDataFromTexture(layout, dataType, texture, tensor); } reshapeUnpacked(input, reshapedDims) { const inputTD = this.getOrCreateTextureData(input, 0 /* unpacked */); const newTextureLayout = { channels: inputTD.channels, height: inputTD.height, width: inputTD.width, // handle reshaping into scalar Tensors shape: reshapedDims.length !== 0 ? reshapedDims : [1], strides: ShapeUtil.computeStrides(reshapedDims), unpackedShape: reshapedDims }; const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture); return newTextureData.tensor; } reshapePacked(input, reshapedDims) { const inputTD = this.getOrCreateTextureData(input, 2 /* packed */); if (isReshapeCheap(input.dims, reshapedDims)) { const newTextureLayout = { channels: inputTD.channels, height: inputTD.height, width: inputTD.width, // handle reshaping into scalar Tensors shape: reshapedDims.length !== 0 ? reshapedDims : [1], strides: ShapeUtil.computeStrides(reshapedDims), unpackedShape: reshapedDims, isPacked: true }; const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture); return newTextureData.tensor; } const squeezedInputShape = processDims3D(input.dims); const squeezedOutputShape = processDims3D(reshapedDims); const squeezedInputTensor = this.reshapePacked(input, squeezedInputShape); const squeezedOutputTensor = this.run( createPackedReshape3DProgramInfoLoader(this, squeezedInputTensor, squeezedOutputShape), [squeezedInputTensor] ); const outputTensor = this.reshapePacked(squeezedOutputTensor, reshapedDims); return outputTensor; } cast(input, type) { const inputTD = this.getOrCreateTextureData(input, 0 /* unpacked */); const newTextureData = this.createTextureDataFromTexture(inputTD, type, inputTD.texture); return newTextureData.tensor; } createTextureDataFromTexture(layout, dataType, texture, tensor, tensorId) { const textureData = { ...layout, tensor: tensor || new Tensor4( layout.unpackedShape, dataType, (_id) => this.readTexture(textureData), async (_id) => this.readTextureAsync(textureData), void 0, tensorId ), texture }; this.setTextureData(textureData.tensor.dataId, textureData, layout.isPacked); return textureData; } getTextureData(tensorId, isPacked = false) { return this.session.isInitializer(tensorId) ? this.session.getTextureData(tensorId, isPacked) : isPacked ? this.packedTextureDataCache.get(tensorId) : this.unpackedTextureDataCache.get(tensorId); } setTextureData(tensorId, td, isPacked = false) { if (this.session.isInitializer(tensorId)) { this.session.setTextureData(tensorId, td, isPacked); } else { (isPacked ? this.packedTextureDataCache : this.unpackedTextureDataCache).set(tensorId, td); } } isTextureLayoutCached(tensor, isPacked = false) { return !!this.getTextureData(tensor.dataId, isPacked); } dispose() { this.session.textureManager.clearActiveTextures(); this.packedTextureDataCache.forEach((td) => this.session.textureManager.releaseTexture(td)); this.packedTextureDataCache = /* @__PURE__ */ new Map(); this.unpackedTextureDataCache.forEach((td) => this.session.textureManager.releaseTexture(td)); this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); } readTexture(textureData) { if (textureData.isPacked) { return this.readTexture(this.unpack(textureData)); } if (!this.session.backend.glContext.isFloat32DownloadSupported) { return this.session.textureManager.readUint8TextureAsFloat(encodeAsUint8(this, textureData)); } return this.session.textureManager.readTexture(textureData, textureData.tensor.type, textureData.channels); } async readTextureAsync(textureData) { if (textureData.isPacked) { return this.readTextureAsync(this.unpack(textureData)); } if (!this.session.backend.glContext.isFloat32DownloadSupported) { return this.session.textureManager.readUint8TextureAsFloat(encodeAsUint8(this, textureData)); } return this.session.textureManager.readTextureAsync(textureData, textureData.tensor.type, textureData.channels); } pack(input) { const outputTextureData = this.executeProgram(createPackProgramInfoLoader(this, input.tensor), [input.tensor]); return outputTextureData; } unpack(input) { const outputTextureData = this.executeProgram(createUnpackProgramInfoLoader(this, input.tensor), [input.tensor]); return outputTextureData; } }; } }); // web/lib/onnxjs/attribute-with-cache-key.ts var AttributeWithCacheKeyImpl, createAttributeWithCacheKey; var init_attribute_with_cache_key = __esm({ "web/lib/onnxjs/attribute-with-cache-key.ts"() { "use strict"; AttributeWithCacheKeyImpl = class { constructor(attribute) { Object.assign(this, attribute); } get cacheKey() { if (!this.key) { this.key = Object.getOwnPropertyNames(this).sort().map((name2) => `${this[name2]}`).join(";"); } return this.key; } }; createAttributeWithCacheKey = (attribute) => new AttributeWithCacheKeyImpl(attribute); } }); // web/lib/onnxjs/backends/webgl/ops/batch-normalization.ts var batchNormalizationProgramMetadata, batchNormalization, parseBatchNormalizationAttributes, createBatchNormalizationProgramInfo, validateInputs; var init_batch_normalization = __esm({ "web/lib/onnxjs/backends/webgl/ops/batch-normalization.ts"() { "use strict"; init_attribute_with_cache_key(); init_glsl_source(); init_types(); batchNormalizationProgramMetadata = { name: "BatchNormalization", inputNames: ["A", "Scale", "B", "Mean", "Variance"], inputTypes: [ 0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */ ] }; batchNormalization = (inferenceHandler, inputs, attributes) => { validateInputs(inputs); const output = inferenceHandler.run( { ...batchNormalizationProgramMetadata, cacheHint: attributes.cacheKey, get: () => createBatchNormalizationProgramInfo(inferenceHandler, inputs, attributes) }, inputs ); return [output]; }; parseBatchNormalizationAttributes = (node) => { const epsilon = node.attributes.getFloat("epsilon", 1e-5); const momentum = node.attributes.getFloat("momentum", 0.9); const spatial = node.attributes.getInt("spatial", 1); return createAttributeWithCacheKey({ epsilon, momentum, spatial }); }; createBatchNormalizationProgramInfo = (inferenceHandler, inputs, attributes) => { const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); const rank = inputs[0].dims.length; const [scaleWidth, scaleHeight] = inferenceHandler.calculateTextureWidthAndHeight( inputs[1].dims, 0 /* unpacked */ ); const shaderSource = ` float process(int[${rank}] indices) { vec2 position = offsetToCoords(indices[1], ${scaleWidth}, ${scaleHeight}); float scale = getColorAsFloat(${glsl.texture2D}(Scale, position)); float mean = getColorAsFloat(${glsl.texture2D}(Mean, position)); float variance = getColorAsFloat(${glsl.texture2D}(Variance, position)); float b = getColorAsFloat(${glsl.texture2D}(B, position)); return scale * ( (_A(indices) - mean) / sqrt(variance + float(${attributes.epsilon})) ) + b; }`; return { ...batchNormalizationProgramMetadata, output: { dims: inputs[0].dims, type: inputs[0].type, textureType: 0 /* unpacked */ }, shaderSource }; }; validateInputs = (inputs) => { if (!inputs || inputs.length !== 5) { throw new Error("BatchNormalization requires 5 inputs."); } const X = inputs[0]; const scale = inputs[1]; const B = inputs[2]; const mean = inputs[3]; const var_ = inputs[4]; if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1 || mean.dims.length !== 1 || var_.dims.length !== 1) { throw new Error("invalid input shape."); } if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1] || mean.dims[0] !== X.dims[1] || var_.dims[0] !== X.dims[1]) { throw new Error("invalid input shape."); } if (X.type !== "float32" && X.type !== "float64" || scale.type !== "float32" && scale.type !== "float64" || B.type !== "float32" && B.type !== "float64" || mean.type !== "float32" && mean.type !== "float64" || var_.type !== "float32" && var_.type !== "float64") { throw new Error("invalid input tensor types."); } }; } }); // web/lib/onnxjs/backends/webgl/glsl-definitions.ts var GlslContext, GlslLib, GlslLibRoutine, GlslLibRoutineNode, TopologicalSortGlslRoutines; var init_glsl_definitions = __esm({ "web/lib/onnxjs/backends/webgl/glsl-definitions.ts"() { "use strict"; GlslContext = class { constructor(glContext, programInfo, inputTextureLayouts, outputTextureLayout) { this.glContext = glContext; this.programInfo = programInfo; this.inputTextureLayouts = inputTextureLayouts; this.outputTextureLayout = outputTextureLayout; } }; GlslLib = class { constructor(context) { this.context = context; } }; GlslLibRoutine = class { constructor(routineBody, dependencies) { this.routineBody = routineBody; this.dependencies = dependencies; } }; GlslLibRoutineNode = class { constructor(name2, routineBody, dependencies) { this.name = name2; if (dependencies) { this.dependencies = dependencies; } else { this.dependencies = []; } if (routineBody) { this.routineBody = routineBody; } } addDependency(node) { if (node) { this.dependencies.push(node); } } }; TopologicalSortGlslRoutines = class { static returnOrderedNodes(nodes) { if (!nodes || nodes.length === 0) { return []; } if (nodes.length === 1) { return nodes; } const cycleCheck = /* @__PURE__ */ new Set(); const alreadyTraversed = /* @__PURE__ */ new Set(); const result = new Array(); this.createOrderedNodes(nodes, cycleCheck, alreadyTraversed, result); return result; } static createOrderedNodes(graphNodes, cycleCheck, alreadyTraversed, result) { for (let i = 0; i < graphNodes.length; ++i) { this.dfsTraverse(graphNodes[i], cycleCheck, alreadyTraversed, result); } } static dfsTraverse(root, cycleCheck, alreadyTraversed, result) { if (!root || alreadyTraversed.has(root.name)) { return; } if (cycleCheck.has(root.name)) { throw new Error("Cyclic dependency detected. Can't topologically sort routines needed for shader."); } cycleCheck.add(root.name); const dependencies = root.dependencies; if (dependencies && dependencies.length > 0) { for (let i = 0; i < dependencies.length; ++i) { this.dfsTraverse(dependencies[i], cycleCheck, alreadyTraversed, result); } } result.push(root); alreadyTraversed.add(root.name); cycleCheck.delete(root.name); } }; } }); // web/lib/onnxjs/backends/webgl/ops/binary-op.ts function glslAdd() { const name2 = "add_"; const body = ` float ${name2}(float a, float b) { return a + b; } vec4 ${name2}(vec4 v1, vec4 v2) { return v1 + v2; } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslDiv() { const name2 = "div_"; const body = ` float ${name2}(float a, float b) { return a / b; } vec4 ${name2}(vec4 v1, vec4 v2) { return v1 / v2; } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslMul() { const name2 = "mul_"; const body = ` float ${name2}(float a, float b) { return a * b; } vec4 ${name2}(vec4 v1, vec4 v2) { return v1 * v2; } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslSub() { const name2 = "sub_"; const body = ` float ${name2}(float a, float b) { return a - b; } vec4 ${name2}(vec4 v1, vec4 v2) { return v1 - v2; } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslEqual() { const name2 = "equal_"; const body = ` float ${name2}(float a, float b) { return float(a == b); } vec4 ${name2}(vec4 v1, vec4 v2) { return vec4(equal(v1, v2)); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslGreater() { const name2 = "greater_"; const body = ` float ${name2}(float a, float b) { return float(a > b); } vec4 ${name2}(vec4 v1, vec4 v2) { return vec4( v1.r > v2.r , v1.g > v2.g, v1.b > v2.b, v1.a > v2.a ); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslLess() { const name2 = "less_"; const body = ` float ${name2}(float a, float b) { return float(a < b); } vec4 ${name2}(vec4 v1, vec4 v2) { return vec4( v1.r < v2.r , v1.g < v2.g, v1.b < v2.b, v1.a < v2.a ); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslAnd() { const name2 = "and_"; const body = ` float ${name2}(float a, float b) { return float( bool(a) && bool(b) ); } vec4 ${name2}(vec4 v1, vec4 v2) { bvec4 b1 = bvec4(v1); bvec4 b2 = bvec4(v2); return vec4( b1.r && b2.r , b1.g && b2.g, b1.b && b2.b, b1.a && b2.a ); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslOr() { const name2 = "or_"; const body = ` float ${name2}(float a, float b) { return float( bool(a) || bool(b) ); } vec4 ${name2}(vec4 v1, vec4 v2) { bvec4 b1 = bvec4(v1); bvec4 b2 = bvec4(v2); return vec4( b1.r || b2.r , b1.g || b2.g, b1.b || b2.b, b1.a || b2.a ); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslXor() { const name2 = "xor_"; const body = ` float ${name2}(float a, float b) { return float( bool(a) ^^ bool(b) ); } vec4 ${name2}(vec4 v1, vec4 v2) { bvec4 b1 = bvec4(v1); bvec4 b2 = bvec4(v2); return vec4( b1.r ^^ b2.r , b1.g ^^ b2.g, b1.b ^^ b2.b, b1.a ^^ b2.a ); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslPow() { return glslBuiltinBinary("pow"); } function glslPRelu() { const name2 = "prelu_"; const body = ` float ${name2}(float a, float b) { return a < 0.0 ? a * b: a; } vec4 ${name2}(vec4 v1, vec4 v2) { return vec4( v1.r < 0.0 ? v1.r * v2.r: v1.r, v1.g < 0.0 ? v1.g * v2.g: v1.g, v1.b < 0.0 ? v1.b * v2.b: v1.b, v1.a < 0.0 ? v1.a * v2.a: v1.a ); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslBuiltinBinary(fname) { const name2 = `${fname}_`; const body = ` float ${name2}(float a, float b) { return ${fname}(a, b); } vec4 ${name2}(vec4 v1, vec4 v2) { return ${fname}(v1, v2); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } var createBinaryProgramInfoLoader, createBinaryProgramInfo, add2, and2, div, equal, greater, less, mul, or2, pow, pRelu, sub, xor2; var init_binary_op = __esm({ "web/lib/onnxjs/backends/webgl/ops/binary-op.ts"() { "use strict"; init_util(); init_glsl_definitions(); init_glsl_source(); init_types(); createBinaryProgramInfoLoader = (handler, inputs, glslFunc, outputTensorType = inputs[0].type, cacheKey) => { const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; return { name: glslFunc.name, inputNames: ["A", "B"], inputTypes: [textureType, textureType], cacheHint: cacheKey, get: () => createBinaryProgramInfo(handler, inputs, glslFunc, outputTensorType) }; }; createBinaryProgramInfo = (handler, inputs, glslFunc, outputTensorType = inputs[0].type) => { const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; const isBroadcast = !ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims); let outputShape = inputs[0].dims; const usePackedTexture = handler.session.pack; if (isBroadcast) { const calculatedShape = BroadcastUtil.calcShape(inputs[0].dims, inputs[1].dims, false); if (!calculatedShape) { throw new Error("Can't perform binary op on the given tensors"); } outputShape = calculatedShape; const outputRank = outputShape.length; const aRank = inputs[0].dims.length !== 0 ? inputs[0].dims.length : 1; const bRank = inputs[1].dims.length !== 0 ? inputs[1].dims.length : 1; const aBcast = inputs[0].dims.length !== 0 ? "bcastIndices_A(indices, aindices);" : "aindices[0] = 0;"; const bBcast = inputs[1].dims.length !== 0 ? "bcastIndices_B(indices, bindices);" : "bindices[0] = 0;"; const glsl2 = getGlsl(handler.session.backend.glContext.version); const shaderSource2 = usePackedTexture ? ` ${glslFunc.body} void main() { vec4 a = getAAtOutCoords(); vec4 b = getBAtOutCoords(); vec4 result = ${glslFunc.name}(a, b); ${glsl2.output} = result; }` : ` ${glslFunc.body} float process(int indices[${outputRank}]) { int aindices[${aRank}]; int bindices[${bRank}]; ${aBcast} ${bBcast} return ${glslFunc.name}(_A(aindices), _B(bindices)); }`; return { name: glslFunc.name, inputNames: ["A", "B"], inputTypes: [textureType, textureType], output: { dims: outputShape, type: outputTensorType, textureType }, shaderSource: shaderSource2, hasMain: usePackedTexture }; } const glsl = getGlsl(handler.session.backend.glContext.version); const shaderSource = ` ${glslFunc.body} void main() { vec4 v1 = ${glsl.texture2D}(A, TexCoords); vec4 v2 = ${glsl.texture2D}(B, TexCoords); vec4 result = ${glslFunc.name}(v1, v2); ${glsl.output} = result; } `; return { name: glslFunc.name, inputNames: ["A", "B"], inputTypes: [textureType, textureType], output: { dims: inputs[0].dims, type: outputTensorType, textureType }, shaderSource, hasMain: true }; }; add2 = (handler, inputs) => [ handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAdd()), inputs) ]; and2 = (handler, inputs) => [ handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAnd(), "bool"), inputs) ]; div = (handler, inputs) => [ handler.run(createBinaryProgramInfoLoader(handler, inputs, glslDiv()), inputs) ]; equal = (handler, inputs) => [ handler.run(createBinaryProgramInfoLoader(handler, inputs, glslEqual(), "bool"), inputs) ]; greater = (handler, inputs) => [ handler.run(createBinaryProgramInfoLoader(handler, inputs, glslGreater(), "bool"), inputs) ]; less = (handler, inputs) => [ handler.run(createBinaryProgramInfoLoader(handler, inputs, glslLess(), "bool"), inputs) ]; mul = (handler, inputs) => [ handler.run(createBinaryProgramInfoLoader(handler, inputs, glslMul()), inputs) ]; or2 = (handler, inputs) => [ handler.run(createBinaryProgramInfoLoader(handler, inputs, glslOr(), "bool"), inputs) ]; pow = (handler, inputs) => [ handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPow()), inputs) ]; pRelu = (handler, inputs) => [ handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPRelu()), inputs) ]; sub = (handler, inputs) => [ handler.run(createBinaryProgramInfoLoader(handler, inputs, glslSub()), inputs) ]; xor2 = (handler, inputs) => [ handler.run(createBinaryProgramInfoLoader(handler, inputs, glslXor(), "bool"), inputs) ]; } }); // web/lib/onnxjs/backends/webgl/ops/cast.ts var cast, parseCastAttributes, validateInputs2; var init_cast = __esm({ "web/lib/onnxjs/backends/webgl/ops/cast.ts"() { "use strict"; init_util(); cast = (handler, inputs, to) => { validateInputs2(inputs); return [handler.cast(inputs[0], to)]; }; parseCastAttributes = (node) => ProtoUtil.tensorDataTypeFromProto(node.attributes.getInt("to")); validateInputs2 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("Cast requires 1 input."); } if (inputs[0].type === "string") { throw new Error("Invalid input type."); } }; } }); // web/lib/onnxjs/backends/webgl/ops/concat-packed.ts var createPackedConcatProgramMetadata, createPackedConcatProgramInfo, createPackedConcatProgramInfoLoader, getShiftedChannelsSnippet; var init_concat_packed = __esm({ "web/lib/onnxjs/backends/webgl/ops/concat-packed.ts"() { "use strict"; init_glsl_source(); init_types(); init_utils(); init_packing_utils(); createPackedConcatProgramMetadata = (inputCount, cacheHint) => ({ name: "Concat (packed)", inputNames: Array.from({ length: inputCount }, (_v, i) => `X${i}`), inputTypes: Array(inputCount).fill(2 /* packed */), cacheHint }); createPackedConcatProgramInfo = (handler, metadata, inputs, axis) => { const inputShape = inputs[0].dims.slice(); if (axis >= inputShape.length || axis < -1 * inputShape.length) { throw new Error("axis specified for concat doesn't match input dimensionality"); } if (axis < 0) { axis = inputShape.length + axis; } const outputShape = inputShape.slice(0); for (let i = 1; i < inputs.length; i++) { const dataNShape = inputs[i].dims.slice(); for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) { if (axisIndex === axis) { outputShape[axis] += dataNShape[axisIndex]; } else if (inputShape[axisIndex] !== dataNShape[axisIndex]) { throw new Error("non concat dimensions must match"); } } } const rank = outputShape.length; const coords = getChannels("coords", rank); const dtype = getCoordsDataType(rank); const unpackChannel = unpackFromChannel(); const shapes = inputs.map((i) => i.dims); const channels = getGlChannels(rank); const offsets = new Array(shapes.length - 1); offsets[0] = shapes[0][axis]; for (let i = 1; i < offsets.length; i++) { offsets[i] = offsets[i - 1] + shapes[i][axis]; } const channel = channels[axis]; const lastChannels = channels.slice(-2); const allChannels = channels.join(); let getValueSnippet = `if (${channel} < ${offsets[0]}) { return getChannel( getX0(${allChannels}), vec2(${lastChannels.join()})); }`; for (let i = 1; i < offsets.length; i++) { const shift2 = offsets[i - 1]; getValueSnippet += ` if (${channel} < ${offsets[i]} && ${channel} >= ${offsets[i - 1]}) { return getChannel( getX${i}(${getShiftedChannelsSnippet(channels, channel, shift2)}), vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift2)})); }`; } const lastIndex = offsets.length; const shift = offsets[offsets.length - 1]; getValueSnippet += ` return getChannel( getX${lastIndex}(${getShiftedChannelsSnippet(channels, channel, shift)}), vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift)}));`; const glsl = getGlsl(handler.session.backend.glContext.version); const shaderSource = ` ${unpackChannel} float getValue(${channels.map((x) => "int " + x)}) { ${getValueSnippet} } void main() { ${dtype} coords = getOutputCoords(); int lastDim = coords.${channels[rank - 1]}; coords.${channels[rank - 1]} = coords.${channels[rank - 2]}; coords.${channels[rank - 2]} = lastDim; vec4 result = vec4(getValue(${coords}), 0., 0., 0.); ${coords[rank - 1]} = ${coords[rank - 1]} + 1; if (${coords[rank - 1]} < ${outputShape[rank - 1]}) { result.g = getValue(${coords}); } ${coords[rank - 2]} = ${coords[rank - 2]} + 1; if (${coords[rank - 2]} < ${outputShape[rank - 2]}) { result.a = getValue(${coords}); } ${coords[rank - 1]} = ${coords[rank - 1]} - 1; if (${coords[rank - 2]} < ${outputShape[rank - 2]} && ${coords[rank - 1]} < ${outputShape[rank - 1]}) { result.b = getValue(${coords}); } ${glsl.output} = result; } `; return { ...metadata, output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, shaderSource, hasMain: true }; }; createPackedConcatProgramInfoLoader = (handler, inputs, attributes) => { const metadata = createPackedConcatProgramMetadata(inputs.length, attributes.cacheKey); return { ...metadata, get: () => createPackedConcatProgramInfo(handler, metadata, inputs, attributes.axis) }; }; getShiftedChannelsSnippet = (channels, channel, shift) => { const channelIdx = channels.indexOf(channel); const res = channels.map((c, idx) => { if (idx === channelIdx) { return `${c} - ${shift}`; } else { return c; } }); return res.join(); }; } }); // web/lib/onnxjs/backends/webgl/ops/concat.ts var concat, createUnpackedConcatProgramMetadata, createUnpackedConcatProgramInfo, createUnpackedConcatProgramInfoLoader, getTextureIndexWhereDataResidesLinearSearch, getTextureIndexWhereDataResidesBinarySearch, getFetchDataFromCorrectTextureMethod, getGetSizeInConcatAxisValueFromIndexMethod, parseConcatAttributes, validateInputs3; var init_concat = __esm({ "web/lib/onnxjs/backends/webgl/ops/concat.ts"() { "use strict"; init_attribute_with_cache_key(); init_types(); init_concat_packed(); concat = (inferenceHandler, inputs, attributes) => { validateInputs3(inputs); if (inferenceHandler.session.pack && inputs[0].dims.length > 1) { const output = inferenceHandler.run( createPackedConcatProgramInfoLoader(inferenceHandler, inputs, attributes), inputs ); return [output]; } else { const output = inferenceHandler.run( createUnpackedConcatProgramInfoLoader(inferenceHandler, inputs, attributes), inputs ); return [output]; } }; createUnpackedConcatProgramMetadata = (inputCount, cacheHint) => ({ name: "Concat", inputNames: Array.from({ length: inputCount }, (_v, i) => `X${i}`), inputTypes: Array(inputCount).fill(0 /* unpacked */), cacheHint }); createUnpackedConcatProgramInfo = (_handler, metadata, inputs, axis) => { const inputShape = inputs[0].dims.slice(); if (axis >= inputShape.length || axis < -1 * inputShape.length) { throw new Error("axis specified for concat doesn't match input dimensionality"); } if (axis < 0) { axis = inputShape.length + axis; } const outputShape = inputShape.slice(0); for (let i = 1; i < inputs.length; i++) { const dataNShape = inputs[i].dims.slice(); for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) { if (axisIndex === axis) { outputShape[axis] += dataNShape[axisIndex]; } else if (inputShape[axisIndex] !== dataNShape[axisIndex]) { throw new Error("non concat dimensions must match"); } } } const rank = outputShape.length; const sizeInConcatAxis = new Array(inputs.length); let previousSum = 0; for (let i = 0; i < sizeInConcatAxis.length; ++i) { previousSum += inputs[i].dims[axis]; sizeInConcatAxis[i] = previousSum; } let getTextureIndexWhereDataResidesMethod = ""; if (inputs.length < 5) { getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis); } else { getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesBinarySearch(sizeInConcatAxis); } const fetchDataFromCorrectTextureMethod = getFetchDataFromCorrectTextureMethod(inputs.length, rank); const getSizeInConcatAxisValueFromIndexMethod = getGetSizeInConcatAxisValueFromIndexMethod(sizeInConcatAxis); const shaderSource = ` ${fetchDataFromCorrectTextureMethod} ${getSizeInConcatAxisValueFromIndexMethod} ${getTextureIndexWhereDataResidesMethod} float process(int indices[${rank}]) { int textureIndex = getTextureWhereDataResides (indices[${axis}]); if(textureIndex != 0) { indices[${axis}] = indices[${axis}] - int(getSizeInConcatAxisValueFromIndex(textureIndex-int(1))); } return fetchDataFromCorrectTexture(textureIndex, indices); }`; return { ...metadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, shaderSource }; }; createUnpackedConcatProgramInfoLoader = (handler, inputs, attributes) => { const metadata = createUnpackedConcatProgramMetadata(inputs.length, attributes.cacheKey); return { ...metadata, get: () => createUnpackedConcatProgramInfo(handler, metadata, inputs, attributes.axis) }; }; getTextureIndexWhereDataResidesLinearSearch = (sizeInConcatAxis) => { const searchAxis = sizeInConcatAxis.map( (size, i) => `if(index<${size}) {return ${i};} ` ); return `int getTextureWhereDataResides(int index) { ${searchAxis.join("")} }`; }; getTextureIndexWhereDataResidesBinarySearch = (sizeInConcatAxis) => getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis); getFetchDataFromCorrectTextureMethod = (numberOfTensors, tensorRank) => { const codeLines = [`float fetchDataFromCorrectTexture(int textureIndex, int indices[${tensorRank}]) {`]; for (let i = 0; i < numberOfTensors; ++i) { if (i === 0) { codeLines.push(` if (textureIndex == ${i}) { return _X${i}(indices); }`); } else if (i === numberOfTensors - 1) { codeLines.push(` else { return _X${i}(indices); }`); } else { codeLines.push(` else if (textureIndex == ${i}) { return _X${i}(indices); }`); } } codeLines.push(" }"); return codeLines.join("\n"); }; getGetSizeInConcatAxisValueFromIndexMethod = (sizeInConcatAxis) => { const codeLines = ["int getSizeInConcatAxisValueFromIndex(int index) {"]; for (let i = 0; i < sizeInConcatAxis.length; ++i) { if (i === 0) { codeLines.push(` if (index == ${i}) { return ${sizeInConcatAxis[i]}; }`); } else if (i === sizeInConcatAxis.length - 1) { codeLines.push(` else { return ${sizeInConcatAxis[i]}; }`); } else { codeLines.push(` else if (index == ${i}) { return ${sizeInConcatAxis[i]}; }`); } } codeLines.push(" }"); return codeLines.join("\n"); }; parseConcatAttributes = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis") }); validateInputs3 = (inputs) => { if (!inputs || inputs.length < 1) { throw new Error("too few inputs"); } const inputType = inputs[0].type; const inputDimensionality = inputs[0].dims.length; if (inputType === "string") { throw new Error("string tensor is not supported yet"); } for (const input of inputs) { if (input.type !== inputType) { throw new Error("input tensors should be one type"); } if (input.dims.length !== inputDimensionality) { throw new Error("input tensors should have the same shape"); } } }; } }); // web/lib/onnxjs/backends/webgl/ops/unary-op.ts function glslAbs() { return glslBuiltinUnary("abs"); } function glslAcos() { return glslBuiltinUnary("acos"); } function glslAsin() { return glslBuiltinUnary("asin"); } function glslAtan() { return glslBuiltinUnary("atan"); } function glslCeil() { return glslBuiltinUnary("ceil"); } function glslCos() { return glslBuiltinUnary("cos"); } function glslElu(alpha) { const name2 = "elu"; const body = ` const float alpha = float(${alpha}); float ${name2}_(float a) { return a >= 0.0 ? a: (exp(a) - 1.0) * alpha; } vec4 ${name2}_(vec4 v) { return vec4(${name2}_(v.x), ${name2}_(v.y), ${name2}_(v.z), ${name2}_(v.w)); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslExp() { return glslBuiltinUnary("exp"); } function glslFloor() { return glslBuiltinUnary("floor"); } function glslClip(min, max) { const name2 = "clip"; const body = ` const float min = float(${min}); const float max = float(${max}); float ${name2}_(float a) { return clamp(a, min, max); } vec4 ${name2}_(vec4 v) { return clamp(v, min, max); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslIdentity() { const name2 = "indentity"; const body = ` float ${name2}_(float a) { return a; } vec4 ${name2}_(vec4 v) { return v; } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslLeakyRelu(alpha) { const name2 = "leakyRelu"; const body = ` const float alpha = float(${alpha}); float ${name2}_(float a) { return a < 0.0 ? a * alpha : a; } vec4 ${name2}_(vec4 v) { return vec4(${name2}_(v.x), ${name2}_(v.y), ${name2}_(v.z), ${name2}_(v.w)); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslLog() { return glslBuiltinUnary("log"); } function glslNeg() { const name2 = "neg"; const body = ` float ${name2}_(float a) { return -a; } vec4 ${name2}_(vec4 v) { return -v; } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslNot() { const name2 = "not"; const body = ` float ${name2}_(float a) { return float( ! bool(a) ); } bool ${name2}_(bool a) { return !a; } vec4 ${name2}_(vec4 v) { return vec4(!bool(v.x), !bool(v.y), !bool(v.z), !bool(v.w)); } bvec4 ${name2}_(bvec4 v) { return bvec4(!v.x, !v.y, !v.z, !v.w); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslSin() { return glslBuiltinUnary("sin"); } function glslRelu() { const name2 = "relu"; const body = ` float ${name2}_(float a) { return max( a, 0.0 ); } vec4 ${name2}_(vec4 v) { return max( v, 0.0 ); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslSigmoid() { const name2 = "sigmoid"; const body = ` float ${name2}_(float a) { return 1.0 / (1.0 + exp(-a)); } vec4 ${name2}_(vec4 v) { return 1.0 / (1.0 + exp(-v)); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslSqrt() { return glslBuiltinUnary("sqrt"); } function glslTan() { return glslBuiltinUnary("tan"); } function glslTanh() { const name2 = "tanh"; const body = ` float ${name2}_(float a) { a = clamp(a, -10., 10.); a = exp(2.*a); return (a - 1.) / (a + 1.); } vec4 ${name2}_(vec4 v) { v = clamp(v, -10., 10.); v = exp(2.*v); return (v - 1.) / (v + 1.); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } function glslBuiltinUnary(name2) { const body = ` float ${name2}_(float a) { return ${name2}(a); } vec4 ${name2}_(vec4 v) { return ${name2}(v); } `; return { body, name: name2, type: 0 /* ValueBased */ }; } var createElementwiseProgramInfo, createElementwiseProgramInfoLoader, abs, acos, asin, atan, clip, parseClipAttributes, clipV11, generateClipAttributesFromInputs, ceil, cos, elu, parseEluAttributes, exp, floor, identity, leakyRelu, parseLeakyReluAttributes, log2, neg, not2, relu, sigmoid, sin, sqrt, tan, tanh; var init_unary_op = __esm({ "web/lib/onnxjs/backends/webgl/ops/unary-op.ts"() { "use strict"; init_attribute_with_cache_key(); init_util(); init_glsl_definitions(); init_glsl_source(); init_types(); createElementwiseProgramInfo = (handler, metadata, input, glslFunc) => { const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; const glsl = getGlsl(handler.session.backend.glContext.version); return { ...metadata, output: { dims: input.dims, type: input.type, textureType }, shaderSource: ` ${glslFunc.body} void main() { vec4 v = ${glsl.texture2D}(A, TexCoords); v = ${glslFunc.name}_(v); ${glsl.output} = v; } `, hasMain: true }; }; createElementwiseProgramInfoLoader = (handler, input, glslFunc, cacheKey) => { const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; const metadata = { name: glslFunc.name, inputTypes: [textureType], inputNames: ["A"], cacheHint: cacheKey }; return { ...metadata, get: () => createElementwiseProgramInfo(handler, metadata, input, glslFunc) }; }; abs = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAbs()), inputs) ]; acos = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAcos()), inputs) ]; asin = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAsin()), inputs) ]; atan = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAtan()), inputs) ]; clip = (handler, inputs, attributes) => [ handler.run( createElementwiseProgramInfoLoader( handler, inputs[0], glslClip(attributes.min, attributes.max), attributes.cacheKey ), inputs ) ]; parseClipAttributes = (node) => createAttributeWithCacheKey({ min: node.attributes.getFloat("min", MIN_CLIP), max: node.attributes.getFloat("max", MAX_CLIP) }); clipV11 = (handler, inputs) => { const attributes = generateClipAttributesFromInputs(handler, inputs); return clip(handler, [inputs[0]], attributes); }; generateClipAttributesFromInputs = (handler, inputs) => { if (inputs.length >= 3 && (!handler.session.isInitializer(inputs[1].dataId) || !handler.session.isInitializer(inputs[2].dataId))) { throw new Error("dynamic clip attributes are not allowed"); } const min = inputs.length >= 3 ? inputs[1].numberData[0] : MIN_CLIP; const max = inputs.length >= 3 ? inputs[2].numberData[0] : MAX_CLIP; return createAttributeWithCacheKey({ min, max }); }; ceil = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslCeil()), inputs) ]; cos = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslCos()), inputs) ]; elu = (handler, inputs, attributes) => [ handler.run( createElementwiseProgramInfoLoader(handler, inputs[0], glslElu(attributes.alpha), attributes.cacheKey), inputs ) ]; parseEluAttributes = (node) => createAttributeWithCacheKey({ alpha: node.attributes.getFloat("alpha", 1) }); exp = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslExp()), inputs) ]; floor = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslFloor()), inputs) ]; identity = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslIdentity()), inputs) ]; leakyRelu = (handler, inputs, attributes) => [ handler.run( createElementwiseProgramInfoLoader(handler, inputs[0], glslLeakyRelu(attributes.alpha), attributes.cacheKey), inputs ) ]; parseLeakyReluAttributes = (node) => createAttributeWithCacheKey({ alpha: node.attributes.getFloat("alpha", 0.01) }); log2 = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslLog()), inputs) ]; neg = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslNeg()), inputs) ]; not2 = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslNot()), inputs) ]; relu = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslRelu()), inputs) ]; sigmoid = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSigmoid()), inputs) ]; sin = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSin()), inputs) ]; sqrt = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSqrt()), inputs) ]; tan = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslTan()), inputs) ]; tanh = (handler, inputs) => [ handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslTanh()), inputs) ]; } }); // web/lib/onnxjs/backends/webgl/ops/fuse-utils.ts function getActivationSnippet(attributes) { let func; switch (attributes.activation) { case "Relu": func = glslRelu(); break; case "Sigmoid": func = glslSigmoid(); break; case "Clip": func = glslClip(attributes.clipMin, attributes.clipMax); break; // TODO: adding other activations that can be fused. default: return { activationFunction: "", applyActivation: "" }; } const activationName = func.name; const activationFunction = func.body; const applyActivation = `value = ${activationName}_(value);`; return { activationFunction, applyActivation }; } var parseInternalActivationAttributes; var init_fuse_utils = __esm({ "web/lib/onnxjs/backends/webgl/ops/fuse-utils.ts"() { "use strict"; init_util(); init_unary_op(); parseInternalActivationAttributes = (attributes) => { const activation = attributes.getString("activation", ""); if (activation === "Clip") { const [clipMin, clipMax] = attributes.getFloats("activation_params", [MIN_CLIP, MAX_CLIP]); return { activation, clipMax, clipMin, activationCacheKey: `${activation}:${clipMin},${clipMax}` }; } return { activation, activationCacheKey: activation }; }; } }); // web/lib/onnxjs/backends/webgl/ops/conv-grouped.ts var createUnpackedGroupedConvProgramMetadata, createUnpackedGroupedConvProgramInfo, createUnpackedGroupedConvProgramInfoLoader; var init_conv_grouped = __esm({ "web/lib/onnxjs/backends/webgl/ops/conv-grouped.ts"() { "use strict"; init_instrument(); init_glsl_source(); init_types(); init_conv(); init_fuse_utils(); createUnpackedGroupedConvProgramMetadata = (hasBias, cacheHint) => ({ name: "GroupedConv", inputNames: hasBias ? ["X", "W", "Bias"] : ["X", "W"], inputTypes: hasBias ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], cacheHint }); createUnpackedGroupedConvProgramInfo = (inferenceHandler, inputs, metadata, attributes) => { const hasBias = inputs.length > 2; const processBias = hasBias ? "value += getBias(output_channel);" : ""; const xShape = inputs[0].dims.slice(); const wShape = inputs[1].dims.slice(); const outputChannelsPerGroup = wShape[0] / attributes.group; Logger.verbose( "GroupedConv", `autpPad:${attributes.autoPad}, dilations:${attributes.dilations}, group:${attributes.group}, kernelShape:${attributes.kernelShape}, pads:${attributes.pads}, strides:${attributes.strides}` ); const outputShape = calculateOutputShape(xShape, wShape, attributes.dilations, attributes.pads, attributes.strides); const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); const { activationFunction, applyActivation } = getActivationSnippet(attributes); const shaderSource = ` const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]}); const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]}); ${activationFunction} void main() { ivec4 coords = getOutputCoords(); int batch = coords.x; int output_channel = coords.y; ivec2 xRCCorner = coords.zw * strides - pads; int group_id = output_channel / ${outputChannelsPerGroup}; float value = 0.0; for (int wInChannel = 0; wInChannel < ${wShape[1]}; wInChannel++) { int input_channel = group_id * ${wShape[1]} + wInChannel; for (int wHeight = 0; wHeight < ${wShape[2]}; wHeight++) { int xHeight = xRCCorner.x + wHeight * ${attributes.dilations[0]}; if (xHeight < 0 || xHeight >= ${xShape[2]}) { continue; } for (int wWidth = 0; wWidth < ${wShape[3]}; wWidth++) { int xWidth = xRCCorner.y + wWidth * ${attributes.dilations[1]}; if (xWidth < 0 || xWidth >= ${xShape[3]}) { continue; } float xVal = getX(batch, input_channel, xWidth, xHeight); float wVal = getW(output_channel, wInChannel, wWidth, wHeight); value += xVal*wVal; } } } ${processBias} ${applyActivation} ${glsl.output} = vec4(value, .0, .0, .0); } `; return { ...metadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, shaderSource, hasMain: true }; }; createUnpackedGroupedConvProgramInfoLoader = (inferenceHandler, inputs, attributes) => { const metadata = createUnpackedGroupedConvProgramMetadata(inputs.length > 2, attributes.cacheKey); return { ...metadata, get: () => createUnpackedGroupedConvProgramInfo(inferenceHandler, inputs, metadata, attributes) }; }; } }); // web/lib/onnxjs/backends/webgl/ops/im2col-pack.ts var createPackedIm2ColProgramMetadata, createPackedIm2ColProgramInfo, createPackedIm2ColProgramInfoLoader; var init_im2col_pack = __esm({ "web/lib/onnxjs/backends/webgl/ops/im2col-pack.ts"() { "use strict"; init_glsl_source(); init_types(); init_packing_utils(); createPackedIm2ColProgramMetadata = (cacheHint) => ({ name: "Im2Col (packed)", inputNames: ["A"], inputTypes: [2 /* packed */], cacheHint }); createPackedIm2ColProgramInfo = (inferenceHandler, metadata, x, w, outputShape, attributes) => { const xshape = x.dims; const wshape = w.dims; const rowDim = 2; const colDim = 3; const rank = outputShape.length; const im2colShape = [wshape[1] * wshape[2] * wshape[3], outputShape[2] * outputShape[3]]; const kernelSize = wshape[2] * wshape[3]; const unpackChannel = unpackFromChannel(); const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); let unrolled = ""; for (let row = 0; row <= 1; row++) { for (let col = 0; col <= 1; col++) { unrolled += ` blockIndex = rc.x + ${col}; pos = rc.y + ${row}; if(blockIndex < ${im2colShape[1]} && pos < ${im2colShape[0]}) { offsetY = int(blockIndex / (${outputShape[rank - 1]})) * ${attributes.strides[0]} - ${attributes.pads[0]}; d0 = offsetY + ${attributes.dilations[0]} * (imod(pos, ${kernelSize}) / ${wshape[2]}); if(d0 < ${xshape[rowDim]} && d0 >= 0) { offsetX = imod(blockIndex, ${outputShape[rank - 1]}) * ${attributes.strides[1]} - ${attributes.pads[1]}; d1 = offsetX + ${attributes.dilations[1]} * imod(imod(pos, ${kernelSize}), ${wshape[2]}); if(d1 < ${xshape[colDim]} && d1 >= 0) { ch = int(float(pos)/ ${kernelSize}.); innerDims = vec2(d0, d1); result[${row * 2 + col}] = getChannel( getA(0, ch, int(innerDims.x), int(innerDims.y)), innerDims); } } } `; } } const shaderSource = ` ${unpackChannel} void main() { ivec2 rc = getOutputCoords(); vec4 result = vec4(0.0); int blockIndex, pos, offsetY, d0, offsetX, d1, ch; vec2 innerDims; ${unrolled} ${glsl.output} = result; } `; return { ...metadata, output: { dims: im2colShape, type: x.type, textureType: 2 /* packed */ }, shaderSource, hasMain: true }; }; createPackedIm2ColProgramInfoLoader = (inferenceHandler, x, w, outputShape, attributes) => { const metadata = createPackedIm2ColProgramMetadata(attributes.cacheKey); return { ...metadata, get: () => createPackedIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes) }; }; } }); // web/lib/onnxjs/backends/webgl/ops/matmul.ts function createMatmulProgramInfo(metadata, inputs, activationAttributes) { const aShape = inputs[0].dims; const bShape = inputs[1].dims; const outputShape = BroadcastUtil.calcShape(aShape, bShape, true); if (!outputShape) { throw new Error("Can't use matmul on the given tensors"); } const coordsDataType = getCoordsDataType(outputShape.length); const allGlChannels = getGlChannels(); const { activationFunction, applyActivation } = getActivationSnippet(activationAttributes); const hasBias = inputs.length > 2; const processBias = hasBias ? "value += getBiasForMatmul();" : ""; const getBiasForMatmulSnippet = hasBias ? `${getBiasForMatmul(coordsDataType, allGlChannels, inputs[2].dims, outputShape, false)}` : ""; const rank = outputShape.length; const arank = aShape.length; const brank = bShape.length; const sharedDim = aShape[aShape.length - 1]; const shaderSource = ` ${activationFunction} ${getBiasForMatmulSnippet} float process(int indices[${rank}]) { int a[${arank}]; int b[${brank}]; bcastMatmulIndices_A(indices, a); bcastMatmulIndices_B(indices, b); float value; for (int k=0; k<${sharedDim}; ++k) { a[${arank - 1}] = k; b[${brank - 2}] = k; value += _A(a) * _B(b); } ${processBias} ${applyActivation} return value; }`; return { ...metadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, shaderSource }; } function createMatmulProgramInfoLoader(inputs, activationAttributes) { const metadata = createMatmulProgramMetadata(inputs.length > 2, activationAttributes.activationCacheKey); return { ...metadata, get: () => createMatmulProgramInfo(metadata, inputs, activationAttributes) }; } function getBiasForMatmul(coordsDataType, allGlChannels, inShape, outShape, isPacked) { let unpackedCoordsSnippet = ""; const inRank = inShape.length; const outRank = outShape.length; const rankDiff = outRank - inRank; if (outRank < 2 && inRank > 0) { unpackedCoordsSnippet = "coords"; } else { unpackedCoordsSnippet = inShape.map((_s, i) => `coords.${allGlChannels[i + rankDiff]}`).join(", "); } const broadcastDims = BroadcastUtil.getBroadcastDims(inShape, outShape); const coordsSnippet = broadcastDims.map((d) => `coords.${allGlChannels[d + rankDiff]} = 0;`).join("\n"); const inSize = ShapeUtil.size(inShape); const isInputScalar = inSize === 1; let output = "vec4(outputValue.xx, outputValue.yy)"; if (isInputScalar) { output = "vec4(outputValue.x)"; } const getBiasForMatmulSource = isPacked ? ` vec4 getBiasForMatmul() { ${coordsDataType} coords = getOutputCoords(); ${coordsSnippet} vec4 outputValue = getBias(${unpackedCoordsSnippet}); return ${output}; }` : ` float getBiasForMatmul() { ${coordsDataType} coords = getOutputCoords(); ${coordsSnippet} return getBias(coords.x); }`; return getBiasForMatmulSource; } var matMul, parseMatMulAttributes, createMatmulProgramMetadata, validateInputs4; var init_matmul = __esm({ "web/lib/onnxjs/backends/webgl/ops/matmul.ts"() { "use strict"; init_util(); init_types(); init_utils(); init_fuse_utils(); init_matmul_pack(); matMul = (inferenceHandler, inputs, attributes) => { validateInputs4(inputs); if (inferenceHandler.session.pack) { return [inferenceHandler.run(createPackedMatmulProgramInfoLoader(inferenceHandler, inputs, attributes), inputs)]; } else { return [inferenceHandler.run(createMatmulProgramInfoLoader(inputs, attributes), inputs)]; } }; parseMatMulAttributes = (node) => parseInternalActivationAttributes(node.attributes); createMatmulProgramMetadata = (hasBias, cacheHint) => ({ name: "MatMul", inputNames: hasBias ? ["A", "B", "Bias"] : ["A", "B"], inputTypes: hasBias ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], cacheHint }); validateInputs4 = (inputs) => { if (!inputs || inputs.length !== 2) { throw new Error("MatMul requires 2 inputs."); } if (inputs[0].dims[inputs[0].dims.length - 1] !== inputs[1].dims[inputs[1].dims.length - 2]) { throw new Error("shared dimension does not match."); } if (inputs[0].type !== "float32" && inputs[0].type !== "float64" || inputs[1].type !== "float32" && inputs[1].type !== "float64") { throw new Error("inputs should be float type"); } if (inputs[0].type !== inputs[1].type) { throw new Error("inputs types should match"); } }; } }); // web/lib/onnxjs/backends/webgl/ops/matmul-pack.ts function getBcastSamplerForMatmul(coordsDataType, allGlChannels, inputs, outShape) { let unpackedACoordsSnippet = []; let unpackedBCoordsSnippet = []; const inAShape = inputs[0].dims; const inBShape = inputs[1].dims; const inARank = inAShape.length; const inBRank = inBShape.length; const outRank = outShape.length; const rankADiff = outRank - inARank; const rankBDiff = outRank - inBRank; unpackedACoordsSnippet = inAShape.map((_s, i) => `coords.${allGlChannels[i + rankADiff]}`); unpackedACoordsSnippet[inARank - 1] = "i*2"; unpackedACoordsSnippet.join(", "); unpackedBCoordsSnippet = inBShape.map((_s, i) => `coords.${allGlChannels[i + rankBDiff]}`); unpackedBCoordsSnippet[inBRank - 2] = "i*2"; unpackedBCoordsSnippet.join(", "); const broadcastADims = BroadcastUtil.getBroadcastDims(inAShape, outShape); const broadcastBDims = BroadcastUtil.getBroadcastDims(inBShape, outShape); const coordsASnippet = broadcastADims.map((d) => `coords.${allGlChannels[d + rankADiff]} = 0;`).join("\n"); const coordsBSnippet = broadcastBDims.map((d) => `coords.${allGlChannels[d + rankBDiff]} = 0;`).join("\n"); const swapDimSnippet = `int lastDim = coords.${allGlChannels[outRank - 1]}; coords.${allGlChannels[outRank - 1]} = coords.${allGlChannels[outRank - 2]}; coords.${allGlChannels[outRank - 2]} = lastDim;`; const getBcastSamplerMatmulSource = ` vec4 getAAtOutCoordsMatmul(int i) { ${coordsDataType} coords = getOutputCoords(); ${swapDimSnippet} ${coordsASnippet} vec4 outputValue = getA(${unpackedACoordsSnippet}); return outputValue; } vec4 getBAtOutCoordsMatmul(int i) { ${coordsDataType} coords = getOutputCoords(); ${swapDimSnippet} ${coordsBSnippet} vec4 outputValue = getB(${unpackedBCoordsSnippet}); return outputValue; }`; return getBcastSamplerMatmulSource; } function getA(allGlChannels, rank) { let res = ""; for (let i = 0; i < rank - 2; i++) { res += `rc.${allGlChannels[i]}, `; } res += `rc.${allGlChannels[rank - 2]}, i*2`; return res; } function getB(allGlChannels, rank) { let res = ""; for (let i = 0; i < rank - 2; i++) { res += `rc.${allGlChannels[i]}, `; } res += `i*2, rc.${allGlChannels[rank - 1]}`; return res; } var createPackedMatmulProgramMetadata, createPackedMatmulProgramInfo, createPackedMatmulProgramInfoLoader; var init_matmul_pack = __esm({ "web/lib/onnxjs/backends/webgl/ops/matmul-pack.ts"() { "use strict"; init_util(); init_glsl_source(); init_types(); init_utils(); init_fuse_utils(); init_matmul(); createPackedMatmulProgramMetadata = (hasBias, cacheHint) => ({ name: "MatMul (packed)", inputNames: hasBias ? ["A", "B", "Bias"] : ["A", "B"], inputTypes: hasBias ? [2 /* packed */, 2 /* packed */, 2 /* packed */] : [2 /* packed */, 2 /* packed */], cacheHint }); createPackedMatmulProgramInfo = (inferenceHandler, metadata, inputs, activationAttributes) => { const hasBias = inputs.length > 2; const processBias = hasBias ? "value += getBiasForMatmul();" : ""; const aShape = inputs[0].dims; const bShape = inputs[1].dims; const outputShape = BroadcastUtil.calcShape(aShape, bShape, true); const isBroadcast = !ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims); if (!outputShape) { throw new Error("Can't use matmul on the given tensors"); } const sharedDim = aShape[aShape.length - 1]; const sharedDimIndex = Math.ceil(sharedDim / 2); const aRank = aShape.length; const bRank = bShape.length; const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); const coordsDataType = getCoordsDataType(outputShape.length); const outRank = outputShape.length; const allGlChannels = getGlChannels(); const { activationFunction, applyActivation } = getActivationSnippet(activationAttributes); const getBiasForMatmulSnippet = hasBias ? `${getBiasForMatmul(coordsDataType, allGlChannels, inputs[2].dims, outputShape, true)}` : ""; const getBcastedSamplerForMatmulSnippet = isBroadcast ? `${getBcastSamplerForMatmul(coordsDataType, allGlChannels, inputs, outputShape)}` : ""; const getSamplerAInLoopSnippet = isBroadcast ? "getAAtOutCoordsMatmul(i)" : `getA(${getA(allGlChannels, aRank)})`; const getSamplerBInLoopSnippet = isBroadcast ? "getBAtOutCoordsMatmul(i)" : `getB(${getB(allGlChannels, bRank)})`; const getOutputCoordsSnippet = isBroadcast ? "" : `${coordsDataType} rc = getOutputCoords(); int lastDim = rc.${allGlChannels[outRank - 1]}; rc.${allGlChannels[outRank - 1]} = rc.${allGlChannels[outRank - 2]}; rc.${allGlChannels[outRank - 2]} = lastDim; `; const shaderSource = ` ${getBcastedSamplerForMatmulSnippet} ${getBiasForMatmulSnippet} ${activationFunction} void main() { ${getOutputCoordsSnippet} vec4 value = vec4(0); for (int i = 0; i < ${sharedDimIndex}; i++) { vec4 a = ${getSamplerAInLoopSnippet}; vec4 b = ${getSamplerBInLoopSnippet}; value += (a.rrbb * b.rgrg); value += (a.ggaa * b.baba); } ${processBias} ${applyActivation} ${glsl.output} = value; }`; return { ...metadata, output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, shaderSource, hasMain: true }; }; createPackedMatmulProgramInfoLoader = (inferenceHandler, inputs, activationAttributes) => { const metadata = createPackedMatmulProgramMetadata(inputs.length > 2, activationAttributes.activationCacheKey); return { ...metadata, get: () => createPackedMatmulProgramInfo(inferenceHandler, metadata, inputs, activationAttributes) }; }; } }); // web/lib/onnxjs/backends/webgl/ops/conv-pack.ts var conv2DPacked; var init_conv_pack = __esm({ "web/lib/onnxjs/backends/webgl/ops/conv-pack.ts"() { "use strict"; init_conv(); init_im2col_pack(); init_matmul_pack(); conv2DPacked = (inferenceHandler, inputs, attributes) => { const xshape = inputs[0].dims; const kshape = inputs[1].dims; const outputShape = calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides); const im2colOutput = inferenceHandler.run( createPackedIm2ColProgramInfoLoader(inferenceHandler, inputs[0], inputs[1], outputShape, attributes), [inputs[0]] ); const kernelReshaped = inferenceHandler.reshapePacked(inputs[1], [kshape[0], kshape[1] * kshape[2] * kshape[3]]); const matmulInputs = inputs.length === 3 ? [kernelReshaped, im2colOutput, inputs[2]] : [kernelReshaped, im2colOutput]; const matmulOutput = inferenceHandler.run( createPackedMatmulProgramInfoLoader(inferenceHandler, matmulInputs, attributes), matmulInputs ); const outputReshaped = inferenceHandler.reshapePacked(matmulOutput, outputShape); return outputReshaped; }; } }); // web/lib/onnxjs/backends/webgl/ops/im2col.ts var createIm2ColProgramMetadata, createIm2ColProgramInfo, createIm2ColProgramInfoLoader, calculateIm2ColDims; var init_im2col = __esm({ "web/lib/onnxjs/backends/webgl/ops/im2col.ts"() { "use strict"; init_types(); createIm2ColProgramMetadata = (cacheHint) => ({ name: "Im2Col", inputNames: ["X"], inputTypes: [0 /* unpacked */], cacheHint }); createIm2ColProgramInfo = (_inferenceHandler, metadata, x, w, outputShape, attributes) => { const xshape = x.dims; const wshape = w.dims; const rank = outputShape.length; const im2colDims = calculateIm2ColDims(xshape, wshape, outputShape, 4); const shaderSource = ` const int XC = ${xshape[1]}; const int XH = ${xshape[2]}; const int XW = ${xshape[3]}; const int KH = ${attributes.kernelShape[0]}; const int KW = ${attributes.kernelShape[1]}; const int dilationH = ${attributes.dilations[0]}; const int dilationW = ${attributes.dilations[1]}; const int strideH = ${attributes.strides[0]}; const int strideW = ${attributes.strides[1]}; const int padH = ${attributes.pads[0]}; const int padW = ${attributes.pads[1]}; const int KHKW = KH*KW; const int XCKHKW = XC * KHKW; const int outputChannels = 4; vec4 process(int indices[${rank}]) { int b = indices[0]; // batch size int oh = indices[1] * strideH - padH; //output height int ow = indices[2] * strideW - padW; //output width int p = indices[3] * outputChannels; //patch vec4 value = vec4(0.0); for(int i=0; i < outputChannels; ++i) { if(p < XCKHKW) { int patchC = p / KHKW; int patchH = (p - patchC*KHKW) / KW; int patchW = (p - patchC*KHKW) - patchH * KW; int xh2 = oh + patchH * dilationH; int xw2 = ow + patchW * dilationW; int x[${xshape.length}]; x[0] = b; x[1] = patchC; x[2] = xh2; x[3] = xw2; if(xh2 >= 0 && xh2 < XH && xw2 >= 0 && xw2 < XW) { value[i] = _X(x); } } ++p; } return value; } `; return { ...metadata, output: { dims: im2colDims, type: x.type, textureType: 4 /* packedLastDimension */ }, shaderSource }; }; createIm2ColProgramInfoLoader = (inferenceHandler, x, w, outputShape, attributes) => { const metadata = createIm2ColProgramMetadata(attributes.cacheKey); return { ...metadata, get: () => createIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes) }; }; calculateIm2ColDims = (inputShape, kernelShape, outputShape, channels = 4) => [ outputShape[0], outputShape[2], outputShape[3], Math.ceil(inputShape[1] * kernelShape[2] * kernelShape[3] / channels) ]; } }); // web/lib/onnxjs/backends/webgl/ops/dot-product.ts var createDotProductProgramMetadata, createDotProductProgramInfo, createDotProductProgramInfoLoader; var init_dot_product = __esm({ "web/lib/onnxjs/backends/webgl/ops/dot-product.ts"() { "use strict"; init_util(); init_glsl_source(); init_types(); init_fuse_utils(); init_im2col(); createDotProductProgramMetadata = (hasBias, attributes) => ({ name: "ConvDotProduct", inputNames: hasBias ? ["Im2Col", "K", "B"] : ["Im2Col", "K"], inputTypes: hasBias ? [0 /* unpacked */, 4 /* packedLastDimension */, 0 /* unpacked */] : [0 /* unpacked */, 4 /* packedLastDimension */], cacheKey: attributes.activationCacheKey }); createDotProductProgramInfo = (inferenceHandler, metadata, inputs, outputShape, attributes) => { const xshape = inputs[0].dims; const kshape = inputs[1].dims; const adjustedKernelShape = [kshape[0], Math.ceil(xshape[1] * kshape[2] * kshape[3] / 4)]; const im2colShape = calculateIm2ColDims(xshape, kshape, outputShape); const [kWidth, kHeight] = inferenceHandler.calculateTextureWidthAndHeight( adjustedKernelShape, 4 /* packedLastDimension */ ); const im2colStrides = ShapeUtil.computeStrides(im2colShape); const [im2colWidth, im2colHeight] = inferenceHandler.calculateTextureWidthAndHeight( im2colShape, 4 /* packedLastDimension */ ); const rank = outputShape.length; const initValue = inputs.length < 3 ? "0.0" : "_B(b)"; const sharedDim = Math.ceil(xshape[1] * kshape[2] * kshape[3] / 4); const { activationFunction, applyActivation } = getActivationSnippet(attributes); const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); const shaderSource = ` ${activationFunction} float process(int indices[${rank}]) { int b[1]; b[0] = indices[1]; int im2col[4]; im2col[0] = indices[0]; im2col[1] = indices[2]; im2col[2] = indices[3]; int im2colOffset = im2col[0] * ${im2colStrides[0]} + im2col[1] * ${im2colStrides[1]} + im2col[2] * ${im2colStrides[2]}; int kernelOffset = indices[1] * ${adjustedKernelShape[1]}; float value = ${initValue}; for (int i = 0; i < ${sharedDim}; ++i) { vec2 im2colCoords = offsetToCoords(im2colOffset, ${im2colWidth}, ${im2colHeight}); vec2 kernelCoords = offsetToCoords(kernelOffset, ${kWidth}, ${kHeight}); value += dot(${glsl.texture2D}(Im2Col, im2colCoords), ${glsl.texture2D}(K, kernelCoords)); ++im2colOffset; ++kernelOffset; } ${applyActivation} return value; }`; return { ...metadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, shaderSource }; }; createDotProductProgramInfoLoader = (inferenceHandler, inputs, outputShape, attributes) => { const metadata = createDotProductProgramMetadata(inputs.length > 2, attributes); return { ...metadata, get: () => createDotProductProgramInfo(inferenceHandler, metadata, inputs, outputShape, attributes) }; }; } }); // web/lib/onnxjs/backends/webgl/ops/conv.ts var calculateOutputShape, conv, conv2d, conv2DUnpackedPointwise, conv2DUnpacked, getAdjustedConvAttributes, parseConvAttributes, validateInputs5; var init_conv = __esm({ "web/lib/onnxjs/backends/webgl/ops/conv.ts"() { "use strict"; init_attribute_with_cache_key(); init_util(); init_conv_grouped(); init_conv_pack(); init_dot_product(); init_fuse_utils(); init_im2col(); init_matmul(); calculateOutputShape = (inputShape, kernelShape, dilations, adjustPads, strides) => { const batchSize = inputShape[0]; const inputSpatialShape = inputShape.slice(2); const spatialRank = inputSpatialShape.length; const outChannels = kernelShape[0]; const kernelSpatialShape = kernelShape.slice(2); const dilatedKernelShape = kernelSpatialShape.map((v, i) => v + (v - 1) * (dilations[i] - 1)); const inputSpatialShapeWithPad = inputSpatialShape.map((v, i) => v + adjustPads[i] + adjustPads[i + spatialRank]); const outputSpatialShape = inputSpatialShapeWithPad.map( (v, i) => Math.floor((v - dilatedKernelShape[i] + strides[i]) / strides[i]) ); const outputShape = [batchSize, outChannels].concat(...outputSpatialShape); return outputShape; }; conv = (inferenceHandler, inputs, attributes) => { validateInputs5(inputs, attributes); return conv2d(inferenceHandler, inputs, attributes); }; conv2d = (inferenceHandler, inputs, attributes) => { const adjustedAttributes = getAdjustedConvAttributes(attributes, inputs); const packMode = inferenceHandler.session.pack; const isPointwise = adjustedAttributes.kernelShape[0] === 1 && adjustedAttributes.kernelShape[1] === 1; if (adjustedAttributes.group > 1) { const result = inferenceHandler.run( createUnpackedGroupedConvProgramInfoLoader(inferenceHandler, inputs, adjustedAttributes), inputs ); return [result]; } else if (isPointwise && packMode) { return [conv2DUnpackedPointwise(inferenceHandler, inputs, adjustedAttributes)]; } else if (packMode && inputs[0].dims.length === 4 && inputs[0].dims[0] === 1 && !isPointwise) { return [conv2DPacked(inferenceHandler, inputs, adjustedAttributes)]; } else { return [conv2DUnpacked(inferenceHandler, inputs, adjustedAttributes)]; } }; conv2DUnpackedPointwise = (inferenceHandler, inputs, attributes) => { const xshape = inputs[0].dims; const kshape = inputs[1].dims; const outputShape = calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides); const reshapedX = inferenceHandler.reshapeUnpacked(inputs[0], [xshape[1], xshape[2] * xshape[3]]); const reshapedK = inferenceHandler.reshapeUnpacked(inputs[1], [kshape[0], kshape[1]]); const matmulInputs = inputs.length > 2 ? [reshapedK, reshapedX, inputs[2]] : [reshapedK, reshapedX]; const matmulOutput = inferenceHandler.run(createMatmulProgramInfoLoader(matmulInputs, attributes), matmulInputs); return inferenceHandler.reshapeUnpacked(matmulOutput, outputShape); }; conv2DUnpacked = (inferenceHandler, inputs, attributes) => { const xshape = inputs[0].dims; const kshape = inputs[1].dims; const outputShape = calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides); const xIm2Col = inferenceHandler.run( createIm2ColProgramInfoLoader(inferenceHandler, inputs[0], inputs[1], outputShape, attributes), [inputs[0]] ); const dotProductInputs = inputs.length === 3 ? [xIm2Col, inputs[1], inputs[2]] : [xIm2Col, inputs[1]]; const output = inferenceHandler.run( createDotProductProgramInfoLoader(inferenceHandler, inputs, outputShape, attributes), dotProductInputs ); return output; }; getAdjustedConvAttributes = (attributes, inputs) => { const kernelShape = attributes.kernelShape.slice(); if (attributes.kernelShape.length === 0) { for (let i = 2; i < inputs[1].dims.length; ++i) { kernelShape.push(inputs[1].dims[i]); } } const pads = attributes.pads.slice(); PoolConvUtil.adjustPadsBasedOnAutoPad( inputs[0].dims, attributes.strides, attributes.dilations, kernelShape, pads, attributes.autoPad ); const newAttributes = Object.assign({}, attributes); Object.assign(newAttributes, { kernelShape, pads, cacheKey: attributes.cacheKey }); return newAttributes; }; parseConvAttributes = (node) => { const attributes = node.attributes; const activationAttributes = parseInternalActivationAttributes(attributes); const autoPad = attributes.getString("auto_pad", "NOTSET"); const dilations = attributes.getInts("dilations", [1, 1]); const group = attributes.getInt("group", 1); const kernelShape = attributes.getInts("kernel_shape", []); const pads = attributes.getInts("pads", [0, 0, 0, 0]); const strides = attributes.getInts("strides", [1, 1]); return createAttributeWithCacheKey({ autoPad, dilations, group, kernelShape, pads, strides, ...activationAttributes }); }; validateInputs5 = (inputs, attributes) => { if (!inputs || inputs.length !== 2 && inputs.length !== 3) { throw new Error("Conv requires 2 or 3 inputs"); } if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) { throw new Error("currently only support 2-dimensional conv"); } const dataChannel = inputs[0].dims[1]; const filterInChannel = inputs[1].dims[1] * attributes.group; if (dataChannel !== filterInChannel) { throw new Error("FILTER_IN_CHANNEL should be equal to DATA_CHANNEL"); } if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[1].dims[0] !== inputs[2].dims[0])) { throw new Error("invalid bias"); } const spatialRank = inputs[0].dims.length - 2; if (attributes.dilations.length !== spatialRank) { throw new Error(`dilations should be ${spatialRank}D`); } if (attributes.strides.length !== spatialRank) { throw new Error(`strides should be ${spatialRank}D`); } if (attributes.pads.length !== spatialRank * 2) { throw new Error(`pads should be ${spatialRank * 2}D`); } if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) { throw new Error("invalid kernel shape"); } if (inputs[0].type !== "float32" || inputs[1].type !== "float32") { throw new Error("Conv input(X,W) should be float tensor"); } if (inputs.length === 3 && inputs[2].type !== "float32") { throw new Error("Conv input(bias) should be float tensor"); } }; } }); // web/lib/onnxjs/backends/webgl/ops/conv-transpose.ts var computeTotalPad, distributePadding, calculateOutputShapeAndPads, convTranspose, convTranspose2d, createConvTransposeProgramMetadata, createUnpackedConvTransposeProgramInfo, createUnpackedConvTransposeProgramInfoLoader, convTranspose2DUnpacked, getAdjustedConvTransposeAttributes, parseConvTransposeAttributes, validateInputs6; var init_conv_transpose = __esm({ "web/lib/onnxjs/backends/webgl/ops/conv-transpose.ts"() { "use strict"; init_attribute_with_cache_key(); init_glsl_source(); init_types(); init_fuse_utils(); computeTotalPad = (inDim, stride, adj, kernel, dilation, outSize) => (inDim - 1) * stride + adj + (kernel - 1) * dilation + 1 - outSize; distributePadding = (totalPad, autoPad, pads, head, tail) => { const smallPad = Math.floor(totalPad / 2); if (autoPad === "SAME_UPPER") { pads[head] = smallPad; pads[tail] = totalPad - smallPad; } else if (autoPad === "SAME_LOWER") { pads[head] = totalPad - smallPad; pads[tail] = smallPad; } }; calculateOutputShapeAndPads = (inputShape, kernelShape, dilations, autoPad, pads, strides, outputPadding, outputShape) => { const spatialRank = inputShape.length - 2; const updateShape = outputShape.length === 0; for (let i = 0; i < spatialRank; ++i) { const outSize = updateShape ? inputShape[i + 2] * strides[i] : outputShape[i]; const totalPad = computeTotalPad(inputShape[i + 2], strides[i], pads[i], kernelShape[i], dilations[i], outSize); distributePadding(totalPad, autoPad, pads, i, i + spatialRank); if (updateShape) { outputShape.push( strides[i] * (inputShape[i + 2] - 1) + outputPadding[i] + (kernelShape[i] - 1) * dilations[i] + 1 - pads[i] - pads[i + spatialRank] ); } } }; convTranspose = (inferenceHandler, inputs, attributes) => { validateInputs6(inputs, attributes); return convTranspose2d(inferenceHandler, inputs, attributes); }; convTranspose2d = (inferenceHandler, inputs, attributes) => { const adjustedAttributes = getAdjustedConvTransposeAttributes(attributes, inputs); return [convTranspose2DUnpacked(inferenceHandler, inputs, adjustedAttributes)]; }; createConvTransposeProgramMetadata = (hasBias, cacheHint) => ({ name: "ConvTranspose", inputNames: hasBias ? ["X", "W", "B"] : ["X", "W"], inputTypes: hasBias ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], cacheHint }); createUnpackedConvTransposeProgramInfo = (inferenceHandler, inputs, metadata, attributes) => { const hasBias = inputs.length > 2; const valueInit = hasBias ? "getB(output_channel)" : "0.0"; const xShape = inputs[0].dims; const wShape = inputs[1].dims; const outputChannelsPerGroup = wShape[1]; const inputChannelsPerGroup = wShape[0] / attributes.group; const outputShape = [inputs[0].dims[0], inputs[1].dims[1] * attributes.group, ...attributes.outputShape]; const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); const { activationFunction, applyActivation } = getActivationSnippet(attributes); const shaderSource = ` const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]}); const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]}); ${activationFunction} void main() { ivec4 coords = getOutputCoords(); int batch = coords.x; int output_channel = coords.y; ivec2 loc = coords.zw + pads; int group_id = output_channel / ${outputChannelsPerGroup}; int wOutChannel = output_channel - group_id * ${outputChannelsPerGroup}; float value = ${valueInit}; for (int inChannelOffset = 0; inChannelOffset < ${inputChannelsPerGroup}; inChannelOffset++) { int input_channel = group_id * ${inputChannelsPerGroup} + inChannelOffset; for (int wWOff = 0; wWOff < ${wShape[2]}; wWOff++) { for (int wHOff = 0; wHOff < ${wShape[3]}; wHOff++) { ivec2 wOff = ivec2(wWOff * ${attributes.dilations[0]}, wHOff * ${attributes.dilations[1]}); ivec2 wLoc = loc - wOff; ivec2 wLocIn = wLoc / strides; if ( wLocIn * strides == wLoc && wLocIn.x >= 0 && wLocIn.x < ${xShape[2]} && wLocIn.y >= 0 && wLocIn.y < ${xShape[3]} ) { float xVal = getX(batch, input_channel, wLocIn.y, wLocIn.x); float wVal = getW(input_channel, wOutChannel, wHOff, wWOff); value += xVal * wVal; } } } } ${applyActivation} ${glsl.output} = vec4(value, .0, .0, .0); } `; return { ...metadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, shaderSource, hasMain: true }; }; createUnpackedConvTransposeProgramInfoLoader = (inferenceHandler, inputs, attributes) => { const metadata = createConvTransposeProgramMetadata(inputs.length > 2, attributes.cacheKey); return { ...metadata, get: () => createUnpackedConvTransposeProgramInfo(inferenceHandler, inputs, metadata, attributes) }; }; convTranspose2DUnpacked = (inferenceHandler, inputs, attributes) => { const result = inferenceHandler.run( createUnpackedConvTransposeProgramInfoLoader(inferenceHandler, inputs, attributes), inputs ); return result; }; getAdjustedConvTransposeAttributes = (attributes, inputs) => { const kernelShape = attributes.kernelShape.slice(); if (attributes.kernelShape.length === 0) { for (let i = 2; i < inputs[1].dims.length; ++i) { kernelShape.push(inputs[1].dims[i]); } } const pads = attributes.pads.slice(); const outputShape = attributes.outputShape.slice(); const inputShape = inputs[0].dims; calculateOutputShapeAndPads( inputShape, kernelShape, attributes.dilations, attributes.autoPad, pads, attributes.strides, attributes.outputPadding, outputShape ); const newAttributes = Object.assign({}, attributes); Object.assign(newAttributes, { kernelShape, pads, outputShape, cacheKey: attributes.cacheKey }); return newAttributes; }; parseConvTransposeAttributes = (node) => { const attributes = node.attributes; const activationAttributes = parseInternalActivationAttributes(attributes); const autoPad = attributes.getString("auto_pad", "NOTSET"); const dilations = attributes.getInts("dilations", [1, 1]); const group = attributes.getInt("group", 1); const kernelShape = attributes.getInts("kernel_shape", []); const outputPadding = attributes.getInts("output_padding", [0, 0]); const outputShape = attributes.getInts("output_shape", []); const pads = attributes.getInts("pads", [0, 0, 0, 0]); const strides = attributes.getInts("strides", [1, 1]); return createAttributeWithCacheKey({ autoPad, dilations, group, kernelShape, outputPadding, outputShape, pads, strides, ...activationAttributes }); }; validateInputs6 = (inputs, attributes) => { if (!inputs || inputs.length !== 2 && inputs.length !== 3) { throw new Error("Conv requires 2 or 3 inputs"); } if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) { throw new Error("currently only support 2-dimensional conv"); } const dataChannel = inputs[0].dims[1]; const filterInChannel = inputs[1].dims[0]; if (dataChannel !== filterInChannel) { throw new Error("FILTER_IN_CHANNEL should be equal to DATA_CHANNEL"); } const featureMaps = inputs[1].dims[1] * attributes.group; if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[2].dims[0] !== featureMaps)) { throw new Error("invalid bias"); } const spatialRank = inputs[0].dims.length - 2; if (attributes.dilations.length !== spatialRank) { throw new Error(`dilations should be ${spatialRank}D`); } if (attributes.strides.length !== spatialRank) { throw new Error(`strides should be ${spatialRank}D`); } if (attributes.pads.length !== spatialRank * 2) { throw new Error(`pads should be ${spatialRank * 2}D`); } if (attributes.outputPadding.length !== spatialRank) { throw new Error(`output_padding should be ${spatialRank}D`); } if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) { throw new Error("invalid kernel shape"); } if (attributes.outputShape.length !== 0 && attributes.outputShape.length !== inputs[0].dims.length - 2) { throw new Error("invalid output shape"); } if (inputs[0].type !== "float32" || inputs[1].type !== "float32") { throw new Error("ConvTranspose input(X,W) should be float tensor"); } if (inputs.length === 3 && inputs[2].type !== "float32") { throw new Error("ConvTranspose input(bias) should be float tensor"); } }; } }); // web/lib/onnxjs/backends/webgl/ops/transpose.ts var transposeProgramMetadata, transpose, parseTransposeAttributes, createTransposeProgramInfo, getAdjustedPerm, getOutputShape, getPermFunctionBody, validateInputs7; var init_transpose = __esm({ "web/lib/onnxjs/backends/webgl/ops/transpose.ts"() { "use strict"; init_attribute_with_cache_key(); init_util(); init_types(); transposeProgramMetadata = { name: "Transpose", inputNames: ["A"], inputTypes: [0 /* unpacked */] }; transpose = (inferenceHandler, inputs, attributes) => { validateInputs7(inputs); const output = inferenceHandler.run( { ...transposeProgramMetadata, cacheHint: attributes.cacheKey, get: () => createTransposeProgramInfo(inferenceHandler, inputs[0], attributes.perm) }, inputs ); return [output]; }; parseTransposeAttributes = (node) => createAttributeWithCacheKey({ perm: node.attributes.getInts("perm", []) }); createTransposeProgramInfo = (_inferenceHandler, input, perm) => { const inputShape = input.dims; perm = getAdjustedPerm(inputShape, perm); const unpackedOutputShape = getOutputShape(inputShape, perm); const rank = inputShape.length; const shaderSource = ` ${getPermFunctionBody("perm", perm, rank)} float process(int indices[${rank}]) { int a[${rank}]; perm(a, indices); return _A(a); }`; return { ...transposeProgramMetadata, output: { dims: unpackedOutputShape, type: input.type, textureType: 0 /* unpacked */ }, shaderSource }; }; getAdjustedPerm = (inputShape, perm) => { if (perm && perm.length !== inputShape.length) { perm = [...inputShape.keys()].reverse(); } return perm; }; getOutputShape = (inputShape, perm) => { perm = getAdjustedPerm(inputShape, perm); return ShapeUtil.sortBasedOnPerm(inputShape, perm); }; getPermFunctionBody = (name2, perm, rank) => { const reverseFunc = []; reverseFunc.push(`void ${name2}(out int a[${rank}], int src[${rank}]) {`); for (let i = 0; i < rank; ++i) { reverseFunc.push(` a[${perm[i]}]=src[${i}];`); } reverseFunc.push(" }"); return reverseFunc.join("\n"); }; validateInputs7 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("Transpose requires 1 input."); } if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { throw new Error("input should be float tensor"); } }; } }); // web/lib/onnxjs/backends/webgl/ops/depth-to-space.ts var depthToSpace, parseDepthToSpaceAttributes, validateInputs8; var init_depth_to_space = __esm({ "web/lib/onnxjs/backends/webgl/ops/depth-to-space.ts"() { "use strict"; init_transpose(); depthToSpace = (inferenceHandler, inputs, attributes) => { validateInputs8(inputs); const blocksize = attributes.blocksize; const blocksizeSqr = blocksize * blocksize; const transposePerm = attributes.mode === "DCR" ? [0, 3, 4, 1, 5, 2] : [0, 1, 4, 2, 5, 3]; const firstReshapeShape = attributes.mode === "DCR" ? [ inputs[0].dims[0], blocksize, blocksize, inputs[0].dims[1] / blocksizeSqr, inputs[0].dims[2], inputs[0].dims[3] ] : [ inputs[0].dims[0], inputs[0].dims[1] / blocksizeSqr, blocksize, blocksize, inputs[0].dims[2], inputs[0].dims[3] ]; const firstReshapedTensor = inferenceHandler.reshapeUnpacked(inputs[0], firstReshapeShape); const transposeAttributes = { perm: transposePerm, cacheKey: `${transposePerm}` }; const [transposeOutput] = transpose(inferenceHandler, [firstReshapedTensor], transposeAttributes); const secondReshapeShape = [ inputs[0].dims[0], inputs[0].dims[1] / blocksizeSqr, inputs[0].dims[2] * blocksize, inputs[0].dims[3] * blocksize ]; const result = inferenceHandler.reshapeUnpacked(transposeOutput, secondReshapeShape); return [result]; }; parseDepthToSpaceAttributes = (node) => { const blocksize = node.attributes.getInt("blocksize"); if (blocksize < 1) { throw new Error(`blocksize must be >= 1, but got : ${blocksize} for DepthToSpace`); } const mode = node.attributes.getString("mode", "DCR"); if (mode !== "DCR" && mode !== "CRD") { throw new Error(`unrecognized mode: ${mode} for DepthToSpace`); } return { mode, blocksize }; }; validateInputs8 = (inputs) => { if (inputs.length !== 1) { throw new Error(`DepthToSpace expect 1 inputs, but got ${inputs.length}`); } if (inputs[0].type === "string" || inputs[0].dims.length !== 4) { throw new TypeError("DepthToSpace input should be a 4-D numeric tensor"); } }; } }); // web/lib/onnxjs/backends/webgl/ops/flatten.ts var flatten, parseFlattenAttributes, validateInputs9; var init_flatten = __esm({ "web/lib/onnxjs/backends/webgl/ops/flatten.ts"() { "use strict"; init_util(); flatten = (inferenceHandler, inputs, axis) => { validateInputs9(inputs, axis); const outputDims = ShapeUtil.flattenShape(inputs[0].dims, axis); return [inferenceHandler.reshapeUnpacked(inputs[0], outputDims)]; }; parseFlattenAttributes = (node) => node.attributes.getInt("axis", 1); validateInputs9 = (inputs, axis) => { if (!inputs || inputs.length !== 1) { throw new Error("Flatten requires 1 input."); } const r = inputs[0].dims.length; if (r === 0) { throw new Error("scalar tensor is not supported."); } if (axis < -r || axis > r) { throw new Error("Invalid axis"); } if (inputs[0].type === "string") { throw new Error("string tensor is not supported."); } }; } }); // web/lib/onnxjs/operators.ts var NUMBER_TYPES; var init_operators = __esm({ "web/lib/onnxjs/operators.ts"() { "use strict"; NUMBER_TYPES = [ "float32", "float64", "int32", "int16", "int8", "uint16", "uint32", "uint8" ]; } }); // web/lib/onnxjs/backends/webgl/ops/gather.ts var gather, parseGatherAttributes, gatherProgramMetadata, createGatherProgramInfo, createGatherProgramInfoLoader, validateInputs10; var init_gather = __esm({ "web/lib/onnxjs/backends/webgl/ops/gather.ts"() { "use strict"; init_attribute_with_cache_key(); init_operators(); init_util(); init_types(); gather = (inferenceHandler, inputs, attributes) => { validateInputs10(inputs, attributes.axis); const output = inferenceHandler.run(createGatherProgramInfoLoader(inferenceHandler, inputs, attributes), inputs); return [output]; }; parseGatherAttributes = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis", 0) }); gatherProgramMetadata = { name: "Gather", inputNames: ["A", "B"], inputTypes: [0 /* unpacked */, 0 /* unpacked */] }; createGatherProgramInfo = (_handler, metadata, inputs, axis) => { const inputShape = inputs[0].dims.slice(); const indexDataShape = inputs[1].dims.slice(); const outputShape = new Array(inputShape.length + indexDataShape.length - 1); axis = ShapeUtil.normalizeAxis(axis, inputShape.length); const indexCopyOps = []; for (let i = 0; i < outputShape.length; i++) { if (i < axis) { outputShape[i] = inputShape[i]; indexCopyOps.push(`inputIdx[${i}] = outputIdx[${i}];`); } else { if (i < axis + indexDataShape.length) { outputShape[i] = indexDataShape[i - axis]; indexCopyOps.push(`indexDataIdx[${i - axis}] = outputIdx[${i}];`); } else { outputShape[i] = inputShape[i - indexDataShape.length + 1]; indexCopyOps.push(`inputIdx[${i - indexDataShape.length + 1}] = outputIdx[${i}];`); } } } const orank = outputShape.length || 1; const irank = inputShape.length; const iDrank = indexDataShape.length || 1; const shaderSource = ` float process(int outputIdx[${orank}]) { int inputIdx[${irank}]; int indexDataIdx[${iDrank}]; indexDataIdx[0] = 0; ${indexCopyOps.join("\n ")} int idx = int(_B(indexDataIdx)); inputIdx[${axis}] = idx < 0 ? idx + ${inputShape[axis]} : idx; return _A(inputIdx); }`; return { ...metadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, shaderSource }; }; createGatherProgramInfoLoader = (handler, inputs, attributes) => { const metadata = { ...gatherProgramMetadata, cacheHint: attributes.cacheKey }; return { ...metadata, get: () => createGatherProgramInfo(handler, metadata, inputs, attributes.axis) }; }; validateInputs10 = (inputs, axis) => { if (!inputs || inputs.length !== 2) { throw new Error("Gather requires 2 inputs."); } const tensorRank = inputs[0].dims.length; if (tensorRank < 1) { throw new Error("Invalid input shape."); } if (axis < -tensorRank || axis > tensorRank - 1) { throw new Error("Invalid axis."); } if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) { throw new Error("Invaid input type."); } if (inputs[1].type !== "int32" && inputs[1].type !== "int16") { throw new Error("Invaid input type."); } }; } }); // web/lib/onnxjs/backends/webgl/ops/gemm.ts var gemm, parseGemmAttributes, parseGemmAttributesV7, parseGemmAttributesV11, createGemmProgramInfoLoader, createGemmProgramInfo, validateInputs11; var init_gemm = __esm({ "web/lib/onnxjs/backends/webgl/ops/gemm.ts"() { "use strict"; init_attribute_with_cache_key(); init_util(); init_types(); gemm = (inferenceHandler, inputs, attributes) => { validateInputs11(inputs, attributes); const output = inferenceHandler.run(createGemmProgramInfoLoader(inputs, attributes), inputs); return [output]; }; parseGemmAttributes = (node, isOptionalC) => { const transA = node.attributes.getInt("transA", 0) !== 0; const transB = node.attributes.getInt("transB", 0) !== 0; const alpha = node.attributes.getFloat("alpha", 1); const beta = node.attributes.getFloat("beta", 1); return createAttributeWithCacheKey({ transA, transB, alpha, beta, isOptionalC }); }; parseGemmAttributesV7 = (node) => parseGemmAttributes(node, false); parseGemmAttributesV11 = (node) => parseGemmAttributes(node, true); createGemmProgramInfoLoader = (inputs, attributes) => { const metadata = { name: "Gemm", inputNames: inputs.length === 3 ? ["A", "B", "C"] : ["A", "B"], inputTypes: inputs.length === 3 ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], key: attributes.cacheKey }; return { ...metadata, get: () => createGemmProgramInfo(metadata, inputs, attributes) }; }; createGemmProgramInfo = (metadata, inputs, attributes) => { const aShape = inputs[0].dims.slice(); const bShape = inputs[1].dims.slice(); const [M, N] = GemmUtil.getShapeOfGemmResult( aShape, attributes.transA, bShape, attributes.transB, inputs.length === 3 ? inputs[2].dims : void 0 ); const outputShape = [M, N]; if (!outputShape) { throw new Error("Can't use gemm on the given tensors"); } let sharedDim = aShape[aShape.length - 1]; let line = ""; if (attributes.transA) { sharedDim = aShape[0]; } if (attributes.transA && attributes.transB) { line = "value += _A_T(a) * _B_T(b);"; } else if (attributes.transA && !attributes.transB) { line = "value += _A_T(a) * _B(b);"; } else if (!attributes.transA && attributes.transB) { line = "value += _A(a) * _B_T(b);"; } else if (!attributes.transA && !attributes.transB) { line = "value += _A(a) * _B(b);"; } const rank = outputShape.length; const declareC = inputs.length === 3 ? `int c[${inputs[2].dims.length}];` : ""; const broadcastC = inputs.length === 3 ? "bcastIndices_C(indices, c);" : ""; const calculateC = inputs.length === 3 ? "value += beta * _C(c);" : ""; const shaderSource = ` float process(int indices[${rank}]) { int a[${rank}]; int b[${rank}]; ${declareC} copyVec(indices, a); copyVec(indices, b); ${broadcastC} float value = 0.0; for (int k=0; k<${sharedDim}; ++k) { a[${rank - 1}] = k; b[${rank - 2}] = k; ${line} } value = value * alpha; ${calculateC} return value; }`; return { ...metadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, variables: [ { name: "alpha", type: "float", data: attributes.alpha }, { name: "beta", type: "float", data: attributes.beta } ], shaderSource }; }; validateInputs11 = (inputs, attributes) => { if (!inputs) { throw new Error("Input is missing"); } if (attributes.isOptionalC && (inputs.length < 2 || inputs.length > 3)) { throw new Error("Invaid input shape."); } if (!attributes.isOptionalC && inputs.length !== 3) { throw new Error("Gemm requires 3 inputs"); } if (inputs.length === 3 && inputs[2].dims.length !== 1 && inputs[2].dims.length !== 2) { throw new Error("Invalid input shape of C"); } if (inputs[0].type !== "float32" && inputs[0].type !== "float64" || inputs[1].type !== "float32" && inputs[1].type !== "float64" || inputs.length === 3 && inputs[2].type !== "float32" && inputs[2].type !== "float64") { throw new Error("Invalid input type."); } if (inputs[0].type !== inputs[1].type || inputs.length === 3 && inputs[0].type !== inputs[2].type) { throw new Error("Input types are mismatched"); } }; } }); // web/lib/onnxjs/backends/webgl/ops/image-scaler.ts var imageScaler, parseImageScalerAttributes, imageScalerProgramMetadata, createImageScalerProgramInfo, createImageScalerProgramInfoLoader, createGetBiasMethod, validateInputs12; var init_image_scaler = __esm({ "web/lib/onnxjs/backends/webgl/ops/image-scaler.ts"() { "use strict"; init_attribute_with_cache_key(); init_types(); imageScaler = (inferenceHandler, inputs, attributes) => { validateInputs12(inputs); const output = inferenceHandler.run(createImageScalerProgramInfoLoader(inferenceHandler, inputs, attributes), inputs); return [output]; }; parseImageScalerAttributes = (node) => { const scale = node.attributes.getFloat("scale"); const bias = node.attributes.getFloats("bias"); return createAttributeWithCacheKey({ scale, bias }); }; imageScalerProgramMetadata = { name: "ImageScaler", inputNames: ["X"], inputTypes: [0 /* unpacked */] }; createImageScalerProgramInfo = (_handler, metadata, inputs, attributes) => { const outputShape = inputs[0].dims.slice(); const rank = outputShape.length; const getBiasMethod = createGetBiasMethod(attributes.bias.length); const shaderSource = ` ${getBiasMethod} float process(int indices[${rank}]) { return _X(indices) * scale + getBias(bias, indices[1]); }`; return { ...metadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, variables: [ { name: "bias", type: "float", arrayLength: attributes.bias.length, data: attributes.bias }, { name: "scale", type: "float", data: attributes.scale } ], shaderSource }; }; createImageScalerProgramInfoLoader = (handler, inputs, attributes) => { const metadata = { ...imageScalerProgramMetadata, cacheHint: attributes.cacheKey }; return { ...metadata, get: () => createImageScalerProgramInfo(handler, metadata, inputs, attributes) }; }; createGetBiasMethod = (numChannels) => { const codeLines = [`float getBias(float bias[${numChannels}], int channel) {`]; for (let i = 0; i < numChannels; ++i) { if (i === 0) { codeLines.push(` if (channel == ${i}) { return bias[${i}]; }`); } else if (i === numChannels - 1) { codeLines.push(` else { return bias[${i}]; }`); } else { codeLines.push(` else if (channel == ${i}) { return bias[${i}]; }`); } } codeLines.push(" }"); return codeLines.join("\n"); }; validateInputs12 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("ImageScaler requires 1 input."); } if (inputs[0].dims.length !== 4) { throw new Error("Invalid input shape."); } if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { throw new Error("Invalid input type."); } }; } }); // web/lib/onnxjs/backends/webgl/ops/instance-normalization.ts var instanceNormalization, parseInstanceNormalizationAttributes, meanAndVarianceProgramMetadata, createMeanAndVarianceProgramInfo, createMeanAndVarianceProgramInfoLoader, computeOutputProgramMetadata, createComputeOutputProgramInfo, createComputeOutputProgramInfoLoader, validateInputs13; var init_instance_normalization = __esm({ "web/lib/onnxjs/backends/webgl/ops/instance-normalization.ts"() { "use strict"; init_glsl_source(); init_types(); instanceNormalization = (inferenceHandler, inputs, epsilon) => { validateInputs13(inputs); const meanAndVariance = inferenceHandler.run(createMeanAndVarianceProgramInfoLoader(inputs[0]), inputs); const output = inferenceHandler.run( createComputeOutputProgramInfoLoader(inferenceHandler, inputs[0], epsilon, meanAndVariance.dims), [inputs[0], meanAndVariance, inputs[1], inputs[2]] ); return [output]; }; parseInstanceNormalizationAttributes = (node) => node.attributes.getFloat("epsilon", 1e-5); meanAndVarianceProgramMetadata = { name: "InstanceNormalization_MeanAndVariance", inputNames: ["X"], inputTypes: [0 /* unpacked */] }; createMeanAndVarianceProgramInfo = (metadata, input) => { const xDims = input.dims.slice(); const channel = xDims[1]; const channelSize = xDims[2] * xDims[3]; const outputShape = [xDims[0], channel]; const shaderSource = ` vec4 process(int[2] indices) { vec4 v = vec4(0.0); int a[4]; a[0] = indices[0]; a[1] = indices[1]; float temp = 0.0; for(int a2=0; a2<${xDims[2]}; a2++) { a[2] = a2; for(int a3=0; a3<${xDims[3]}; a3++) { a[3] = a3; float x = _X(a); temp += x; } } float mean = temp / float(${channelSize}); temp = 0.0; for(int a2=0; a2<${xDims[2]}; a2++) { a[2] = a2; for(int a3=0; a3<${xDims[3]}; a3++) { a[3] = a3; float x = _X(a); temp += (x - mean) * (x - mean); } } v.r = mean; v.g = temp / float(${channelSize}); return v; }`; return { ...metadata, output: { dims: outputShape, type: input.type, textureType: 4 /* packedLastDimension */ }, shaderSource }; }; createMeanAndVarianceProgramInfoLoader = (input) => ({ ...meanAndVarianceProgramMetadata, get: () => createMeanAndVarianceProgramInfo(meanAndVarianceProgramMetadata, input) }); computeOutputProgramMetadata = { name: "InstanceNormalization_ComputeOutput", inputNames: ["X", "MeanAndVariance", "Scale", "B"], inputTypes: [0 /* unpacked */, 4 /* packedLastDimension */, 0 /* unpacked */, 0 /* unpacked */] }; createComputeOutputProgramInfo = (inferenceHandler, metadata, input, epsilon, meanAndVarianceShape) => { const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight( meanAndVarianceShape, 4 /* packedLastDimension */ ); const [meanAndVarianceWidth, meanAndVarianceHeight] = [textureWidth / 4, textureHeight]; const shaderSource = ` vec4 get_MeanAndVariance(int[2] mv) { int offset = indicesToOffset_MeanAndVariance(mv); vec2 coords = offsetToCoords(offset, ${meanAndVarianceWidth}, ${meanAndVarianceHeight}); return ${glsl.texture2D}(MeanAndVariance, coords); } float process(int[4] indices) { int mv[2]; mv[0] = indices[0]; mv[1] = indices[1]; vec4 mean_and_variance = get_MeanAndVariance(mv); float mean = mean_and_variance.r; float variance = mean_and_variance.g; int sb[1]; sb[0] = indices[1]; float scale = _Scale(sb); float b = _B(sb); return scale * (_X(indices) - mean) / sqrt(variance + epsilon) + b; }`; return { ...metadata, output: { dims: input.dims, type: input.type, textureType: 0 /* unpacked */ }, variables: [{ name: "epsilon", type: "float", data: epsilon }], shaderSource }; }; createComputeOutputProgramInfoLoader = (inferenceHandler, input, epsilon, meanAndVarianceShape) => { const metadata = { ...computeOutputProgramMetadata, cacheHint: `${epsilon}` }; return { ...metadata, get: () => createComputeOutputProgramInfo(inferenceHandler, metadata, input, epsilon, meanAndVarianceShape) }; }; validateInputs13 = (inputs) => { if (!inputs || inputs.length !== 3) { throw new Error("InstanceNormalization requires 3 inputs."); } const X = inputs[0]; const scale = inputs[1]; const B = inputs[2]; if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1) { throw new Error("Invalid input shape."); } if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1]) { throw new Error("Input shapes are mismatched."); } if (X.type !== "float32" && X.type !== "float64" || scale.type !== "float32" && scale.type !== "float64" || B.type !== "float32" && B.type !== "float64") { throw new Error("Invalid input type."); } if (inputs[0].dims.length !== 4) { throw new Error("Only support 4-D input shape."); } }; } }); // web/lib/onnxjs/backends/webgl/ops/lrn.ts function createLrnProgramInfo(inputs, attributes) { const C = inputs[0].dims[1]; const rank = inputs[0].dims.length; const from = -Math.floor((attributes.size - 1) / 2); const to = Math.ceil((attributes.size - 1) / 2); const alpha = `float(${attributes.alpha}) / float(${attributes.size})`; const bias = `float(${attributes.bias})`; const beta = `float(${attributes.beta})`; const shaderSource = ` float process(int indices[${rank}]) { int c = indices[1]; float x = _X(indices); float square_sum = 0.0; for (int i = ${from}; i <= ${to}; i++) { int idx = c + i; if (c >= 0 && c < ${C}) { indices[1] = idx; float j = _X(indices); square_sum += j * j; } } return x / pow(${bias} + ${alpha} * square_sum, ${beta}); }`; return { ...lrnProgramMetadata, cacheHint: attributes.cacheKey, output: { dims: inputs[0].dims, type: inputs[0].type, textureType: 0 /* unpacked */ }, shaderSource }; } function createLrnProgramInfoLoader(inputs, attributes) { return { ...lrnProgramMetadata, cacheHint: attributes.cacheKey, get: () => createLrnProgramInfo(inputs, attributes) }; } var lrn, parseLrnAttributes, lrnProgramMetadata, validateInputs14; var init_lrn = __esm({ "web/lib/onnxjs/backends/webgl/ops/lrn.ts"() { "use strict"; init_attribute_with_cache_key(); init_types(); lrn = (inferenceHandler, inputs, attributes) => { validateInputs14(inputs); return [inferenceHandler.run(createLrnProgramInfoLoader(inputs, attributes), inputs)]; }; parseLrnAttributes = (node) => { const alpha = node.attributes.getFloat("alpha", 1e-4); const beta = node.attributes.getFloat("beta", 0.75); const bias = node.attributes.getFloat("bias", 1); const size = node.attributes.getInt("size"); return createAttributeWithCacheKey({ alpha, beta, bias, size }); }; lrnProgramMetadata = { name: "LRN", inputNames: ["X"], inputTypes: [0 /* unpacked */] }; validateInputs14 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("LRN requires 1 input."); } if (inputs[0].dims.length !== 4) { throw new Error('currently only support LRN for input with "NCHW" format'); } if (inputs[0].type !== "float32") { throw new Error("input should be float type"); } }; } }); // web/lib/onnxjs/backends/webgl/ops/pad.ts var padProgramMetadata, padV2, parsePadAttributesV2, padV11, parsePadAttributesV11, generatePadAttributesFromInputs, createPadProgramInfo, validateInputsV2, validateInputsV11, getPadFunction, getPadConstant, getPadReflect, getPadEdge; var init_pad = __esm({ "web/lib/onnxjs/backends/webgl/ops/pad.ts"() { "use strict"; init_attribute_with_cache_key(); init_util(); init_glsl_source(); init_types(); padProgramMetadata = { name: "Pad", inputNames: ["A"], inputTypes: [0 /* unpacked */] }; padV2 = (inferenceHandler, inputs, attributes) => { validateInputsV2(inputs); const output = inferenceHandler.run( { ...padProgramMetadata, cacheHint: attributes.cacheKey, get: () => createPadProgramInfo(inferenceHandler, inputs[0], attributes) }, inputs ); return [output]; }; parsePadAttributesV2 = (node) => { const mode = node.attributes.getString("mode", "constant"); const value = node.attributes.getFloat("value", 0); const pads = node.attributes.getInts("pads"); return createAttributeWithCacheKey({ mode, value, pads }); }; padV11 = (inferenceHandler, inputs, mode) => { validateInputsV11(inputs); const attrubutes = generatePadAttributesFromInputs(inferenceHandler, inputs, mode); return padV2(inferenceHandler, [inputs[0]], attrubutes); }; parsePadAttributesV11 = (node) => node.attributes.getString("mode", "constant"); generatePadAttributesFromInputs = (inferenceHandler, inputs, mode) => { if (!inferenceHandler.session.isInitializer(inputs[1].dataId) || inputs.length >= 3 && !inferenceHandler.session.isInitializer(inputs[2].dataId)) { throw new Error("dynamic pad attributes are not allowed"); } const pads = Array.from(inputs[1].integerData); const value = inputs.length >= 3 ? inputs[2].floatData[0] : 0; return createAttributeWithCacheKey({ mode, pads, value }); }; createPadProgramInfo = (inferenceHandler, input, attributes) => { const outputShape = ShapeUtil.padShape(input.dims.slice(), attributes.pads); const rank = outputShape.length; const padFunction = getPadFunction(inferenceHandler, input, attributes); const shaderSource = ` ${padFunction} float process(int[${rank}] indices) { return padA(indices); }`; return { name: "Pad", inputNames: ["A"], inputTypes: [0 /* unpacked */], output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, shaderSource }; }; validateInputsV2 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("Pad requires 1 input"); } if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { throw new Error("Invalid input type."); } }; validateInputsV11 = (inputs) => { if (!inputs || inputs.length !== 2 && inputs.length !== 3) { throw new Error("Pad requires 2 or 3 inputs"); } if (inputs[1].type !== "int32") { throw new Error("Invalid input type."); } if (inputs.length >= 3 && inputs[2].type === "string") { throw new Error("Invalid input type."); } }; getPadFunction = (inferenceHandler, input, attributes) => { const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); const [width, height] = inferenceHandler.calculateTextureWidthAndHeight(input.dims, 0 /* unpacked */); const strides = ShapeUtil.computeStrides(input.dims); switch (attributes.mode) { case "constant": return getPadConstant(glsl, input.dims, strides, width, height, attributes.pads, attributes.value); case "reflect": return getPadReflect(glsl, input.dims, strides, width, height, attributes.pads); case "edge": return getPadEdge(glsl, input.dims, strides, width, height, attributes.pads); default: throw new Error("Invalid mode"); } }; getPadConstant = (glsl, shape2, strides, width, height, pads, value) => { const rank = shape2.length; let block = ""; for (let i = rank - 1; i >= 0; --i) { block += ` k = m[${i}] - ${pads[i]}; if (k < 0) return constant; if (k >= ${shape2[i]}) return constant; offset += k * ${strides[i]}; `; } return ` float padA(int m[${rank}]) { const float constant = float(${value}); int offset = 0; int k = 0; ${block} vec2 coords = offsetToCoords(offset, ${width}, ${height}); float value = getColorAsFloat(${glsl.texture2D}(A, coords)); return value; } `; }; getPadReflect = (glsl, shape2, strides, width, height, pads) => { const rank = shape2.length; let block = ""; for (let i = rank - 1; i >= 0; --i) { block += ` k = m[${i}] - ${pads[i]}; if (k < 0) { k = -k; } { const int _2n_1 = ${2 * (shape2[i] - 1)}; k = int( mod( float(k), float(_2n_1) ) ) ; if(k >= ${shape2[i]}) { k = _2n_1 - k; } } offset += k * ${strides[i]}; `; } return ` float padA(int m[${rank}]) { int offset = 0; int k = 0; ${block} vec2 coords = offsetToCoords(offset, ${width}, ${height}); float value = getColorAsFloat(${glsl.texture2D}(A, coords)); return value; } `; }; getPadEdge = (glsl, shape2, strides, width, height, pads) => { const rank = shape2.length; let block = ""; for (let i = rank - 1; i >= 0; --i) { block += ` k = m[${i}] - ${pads[i]}; if (k < 0) k = 0; if (k >= ${shape2[i]}) k = ${shape2[i] - 1}; offset += k * ${strides[i]}; `; } return ` float padA(int m[${rank}]) { int offset = 0; int k = 0; ${block} vec2 coords = offsetToCoords(offset, ${width}, ${height}); float value = getColorAsFloat(${glsl.texture2D}(A, coords)); return value; } `; }; } }); // web/lib/onnxjs/backends/webgl/ops/pool.ts var averagePool, parseAveragePoolAttributes, createAveragePoolProgramInfo, globalAveragePool, parseGlobalAveragePoolAttributes, maxPool, parseMaxPoolAttributes, createMaxPoolProgramInfo, getAdjustedPoolAttributesAndOutputShape, globalMaxPoolAttributes, globalMaxPoolMetadata, globalMaxPool, validateInputs15, generatePoolingCode, copyArray, offsetToIndices; var init_pool = __esm({ "web/lib/onnxjs/backends/webgl/ops/pool.ts"() { "use strict"; init_attribute_with_cache_key(); init_util(); init_types(); averagePool = (inferenceHandler, inputs, attributes) => { validateInputs15(inputs); const metadata = { name: "AveragePool", inputNames: ["X"], inputTypes: [0 /* unpacked */], cacheHint: attributes.cacheKey }; const output = inferenceHandler.run( { ...metadata, get: () => createAveragePoolProgramInfo(inputs, metadata, false, attributes) }, inputs ); return [output]; }; parseAveragePoolAttributes = (node) => { const autoPad = node.attributes.getString("auto_pad", "NOTSET"); const ceilMode = node.attributes.getInt("ceil_mode", 0); const countIncludePad = node.attributes.getInt("count_include_pad", 0) === 0 ? false : true; const kernelShape = node.attributes.getInts("kernel_shape"); const strides = node.attributes.getInts("strides", []); const pads = node.attributes.getInts("pads", []); if (ceilMode !== 0) { throw new Error("using ceil() in shape computation is not yet supported for AveragePool"); } return createAttributeWithCacheKey({ autoPad, ceilMode, countIncludePad, kernelShape, strides, pads }); }; createAveragePoolProgramInfo = (inputs, metadata, isGlobalOperator, attributes) => { const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape( inputs, attributes, isGlobalOperator ); const kernelSize = ShapeUtil.size(adjustedAttributes.kernelShape); const op1 = "value += _X(x);"; let op2 = ""; if (adjustedAttributes.countIncludePad) { op2 += `value /= float(${kernelSize});`; } else { op2 += `value /= float(${kernelSize} - pad);`; } const poolingCode = generatePoolingCode(inputs[0].dims, adjustedAttributes, op1, op2, "0.0"); const shaderSource = ` ${poolingCode} `; return { ...metadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, shaderSource }; }; globalAveragePool = (inferenceHandler, inputs, attributes) => { validateInputs15(inputs); const metadata = { name: "GlobalAveragePool", inputNames: ["X"], inputTypes: [0 /* unpacked */], cacheHint: `${attributes.countIncludePad}` }; const output = inferenceHandler.run( { ...metadata, get: () => createAveragePoolProgramInfo(inputs, metadata, true, attributes) }, inputs ); return [output]; }; parseGlobalAveragePoolAttributes = (node) => { const countIncludePad = node.attributes.getInt("count_include_pad", 0) === 0 ? false : true; return createAttributeWithCacheKey({ autoPad: "", ceilMode: 0, countIncludePad, kernelShape: [], strides: [], pads: [] }); }; maxPool = (inferenceHandler, inputs, attributes) => { validateInputs15(inputs); const metadata = { name: "MaxPool", inputNames: ["X"], inputTypes: [0 /* unpacked */], cacheHint: attributes.cacheKey }; const output = inferenceHandler.run( { ...metadata, get: () => createMaxPoolProgramInfo(inputs, metadata, false, attributes) }, inputs ); return [output]; }; parseMaxPoolAttributes = (node) => { const autoPad = node.attributes.getString("auto_pad", "NOTSET"); const ceilMode = node.attributes.getInt("ceil_mode", 0); const kernelShape = node.attributes.getInts("kernel_shape"); const strides = node.attributes.getInts("strides", []); const pads = node.attributes.getInts("pads", []); const storageOrder = node.attributes.getInt("storage_order", 0); const dilations = node.attributes.getInts("dilations", []); if (storageOrder !== 0) { throw new Error("column major storage order is not yet supported for MaxPool"); } if (ceilMode !== 0) { throw new Error("using ceil() in shape computation is not yet supported for MaxPool"); } return createAttributeWithCacheKey({ autoPad, ceilMode, countIncludePad: false, kernelShape, strides, pads, storageOrder, dilations }); }; createMaxPoolProgramInfo = (inputs, metadata, isGlobalOperator, attributes) => { const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape( inputs, attributes, isGlobalOperator ); const op1 = ` value = max(_X(x), value); `; const op2 = ""; const poolingCode = generatePoolingCode(inputs[0].dims, adjustedAttributes, op1, op2, "-1e5"); const shaderSource = ` ${poolingCode} `; return { ...metadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, shaderSource }; }; getAdjustedPoolAttributesAndOutputShape = (inputs, attributes, isGlobalOperator) => { const inputShape = inputs[0].dims.slice(); const hasDilations = Object.hasOwnProperty.call(attributes, "dilations"); const kernelShape = attributes.kernelShape.slice(); const strides = attributes.strides.slice(); const dilations = hasDilations ? attributes.dilations.slice() : []; const pads = attributes.pads.slice(); PoolConvUtil.adjustPoolAttributes(isGlobalOperator, inputShape, kernelShape, strides, dilations, pads); const outputShape = PoolConvUtil.computePoolOutputShape( isGlobalOperator, inputShape, strides, dilations, kernelShape, pads, attributes.autoPad ); const newAttributes = Object.assign({}, attributes); if (hasDilations) { Object.assign(newAttributes, { kernelShape, strides, pads, dilations, cacheKey: attributes.cacheKey }); } else { Object.assign(newAttributes, { kernelShape, strides, pads, cacheKey: attributes.cacheKey }); } return [newAttributes, outputShape]; }; globalMaxPoolAttributes = { autoPad: "", ceilMode: 0, countIncludePad: false, kernelShape: [], strides: [], pads: [], storageOrder: 0, dilations: [], cacheKey: "" }; globalMaxPoolMetadata = { name: "GlobalMaxPool", inputNames: ["X"], inputTypes: [0 /* unpacked */] }; globalMaxPool = (inferenceHandler, inputs) => { validateInputs15(inputs); const output = inferenceHandler.run( { ...globalMaxPoolMetadata, get: () => createMaxPoolProgramInfo(inputs, globalMaxPoolMetadata, true, globalMaxPoolAttributes) }, inputs ); return [output]; }; validateInputs15 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("Pool ops requires 1 input."); } if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { throw new Error("Invalid input type."); } }; generatePoolingCode = (inputDims, attributes, op1, op2, start) => { const rank = inputDims.length; if (attributes.kernelShape.length <= 2) { const kw = attributes.kernelShape[attributes.kernelShape.length - 1]; const sw = attributes.strides[attributes.strides.length - 1]; const pwStart = attributes.pads[attributes.pads.length / 2 - 1]; const pwEnd = attributes.pads[attributes.pads.length - 1]; const dimW = inputDims[rank - 1]; let codeW = ""; let codeH = ""; let codeHEnd = ""; if (pwStart + pwEnd !== 0) { codeW = ` for (int i = 0; i < ${kw}; i++) { x[${rank} - 1] = indices[${rank} - 1] * ${sw} - ${pwStart} + i; if (x[${rank} - 1] < 0 || x[${rank} - 1] >= ${dimW}) { pad++; continue; } ${op1} }`; } else { codeW = ` for (int i = 0; i < ${kw}; i++) { x[${rank} - 1] = indices[${rank} - 1] * ${sw} - ${pwStart} + i; ${op1} }`; } if (attributes.kernelShape.length === 2) { const kh = attributes.kernelShape[attributes.kernelShape.length - 2]; const sh = attributes.strides[attributes.strides.length - 2]; const phStart = attributes.pads[attributes.pads.length / 2 - 2]; const phEnd = attributes.pads[attributes.pads.length - 2]; const dimH = inputDims[rank - 2]; if (phStart + phEnd !== 0) { codeH = ` for (int j = 0; j < ${kh}; j++) { x[${rank} - 2] = indices[${rank} - 2] * ${sh} - ${phStart} + j; if (x[${rank} - 2] < 0 || x[${rank} - 2] >= ${dimH}) { pad+= ${kw}; continue; } `; } else { codeH = ` for (int j = 0; j < ${kh}; j++) { x[${rank} - 2] = indices[${rank} - 2] * ${sh} - ${phStart} + j; `; } codeHEnd = ` } `; } const poolingCode = ` float process(int indices[${rank}]) { int x[${rank}]; copyVec(indices, x); float value = ${start}; int pad = 0; ${codeH} ${codeW} ${codeHEnd} ${op2} return value; } `; return poolingCode; } else { const kernelSize = ShapeUtil.size(attributes.kernelShape); const kernelStrides = ShapeUtil.computeStrides(attributes.kernelShape); const stridesRank = kernelStrides.length; const padsRank = attributes.pads.length; const offsetToIndicesFunction = offsetToIndices(stridesRank); const copyInputDims = copyArray(inputDims, "inputDims"); const copyPads = copyArray(attributes.pads, "pads"); const copyKernelStrides = copyArray(kernelStrides, "kernelStrides"); const copyStrides = copyArray(attributes.strides, "strides"); const hasPads = attributes.pads.reduce((sum2, cur) => sum2 + cur); let padCode = ""; if (hasPads) { padCode = ` if (x[j] >= inputDims[j] || x[j] < 0) { pad++; isPad = true; break; } } if (!isPad) { ${op1} }`; } else { padCode = ` } ${op1} `; } const poolingCode = ` ${offsetToIndicesFunction} float process(int indices[${rank}]) { int x[${rank}]; copyVec(indices, x); int offset[${stridesRank}]; int pads[${padsRank}]; int inputDims[${rank}]; int kernelStrides[${stridesRank}]; int strides[${stridesRank}]; ${copyPads} ${copyInputDims} ${copyStrides} ${copyKernelStrides} float value = ${start}; int pad = 0; bool isPad = false; for (int i = 0; i < ${kernelSize}; i++) { offsetToIndices(i, kernelStrides, offset); isPad = false; for (int j = ${rank} - ${stridesRank}; j < ${rank}; j++) { x[j] = indices[j] * strides[j - ${rank} + ${stridesRank}] + offset[j - ${rank} + ${stridesRank}] - pads[j - 2]; ${padCode} } ${op2} return value; } `; return poolingCode; } }; copyArray = (array, arrayName) => { let block = ""; for (let i = 0; i < array.length; i++) { block += ` ${arrayName}[${i}] = ${array[i]}; `; } return block; }; offsetToIndices = (rank) => ` void offsetToIndices(int offset, int[${rank}] strides, out int[${rank}] indices) { if (${rank} == 0) { return; } for (int i = 0; i < ${rank} - 1; ++i) { indices[i] = offset / strides[i]; offset -= indices[i] * strides[i]; } indices[${rank} - 1] = offset; }`; } }); // web/lib/onnxjs/backends/webgl/ops/reduce.ts var reduce, parseReduceAttributes, createReduceProgramInfo, validateInputs16, reduceSum, reduceMean, reduceMax, reduceMin, reduceProd, reduceLogSum, reduceLogSumSquare; var init_reduce = __esm({ "web/lib/onnxjs/backends/webgl/ops/reduce.ts"() { "use strict"; init_attribute_with_cache_key(); init_operators(); init_util(); init_types(); reduce = (inferenceHandler, inputs, attributes, name2, reduceOp) => { validateInputs16(inputs); const reduceProgramMetadata = { name: name2, inputNames: ["A"], inputTypes: [0 /* unpacked */] }; const output = inferenceHandler.run( { ...reduceProgramMetadata, cacheHint: attributes.cacheKey, get: () => createReduceProgramInfo(inferenceHandler, inputs, attributes, name2, reduceOp, reduceProgramMetadata) }, inputs ); return [output]; }; parseReduceAttributes = (node) => { const axes = node.attributes.getInts("axes", []); const keepDims = node.attributes.getInt("keepdims", 1) === 1; return createAttributeWithCacheKey({ axes, keepDims }); }; createReduceProgramInfo = (_handler, inputs, attributes, _name, reduceOp, reduceProgramMetadata) => { const outputShape = []; const iRank = inputs[0].dims.length || 1; const idxCopy = []; const axes = ShapeUtil.normalizeAxes(attributes.axes, inputs[0].dims.length); const ops = reduceOp(inputs, axes); let reduceOps = ops[1]; for (let k = 0; k < inputs[0].dims.length; k++) { if (axes.indexOf(k) >= 0 || axes.length === 0) { if (attributes.keepDims) { outputShape.push(1); } reduceOps = ` for(int j${k} = 0; j${k} < ${inputs[0].dims[k]}; j${k}++) { inputIdx[${k}] = j${k}; ${reduceOps} }`; } else { idxCopy.push(`inputIdx[${k}] = outputIdx[${outputShape.length}];`); outputShape.push(inputs[0].dims[k]); } } const oRank = outputShape.length || 1; const shaderSource = ` float process(int outputIdx[${oRank}]) { float value; // final result int inputIdx[${iRank}]; // addressing input data ${idxCopy.join("\n")} ${ops[0]} // init ops for reduce max/min ${reduceOps} ${ops[2]} // final computation for reduce mean return value; }`; return { ...reduceProgramMetadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, shaderSource }; }; validateInputs16 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("Reduce op requires 1 input."); } if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) { throw new Error("Invalid input type."); } }; reduceSum = (inferenceHandler, inputs, attributes) => { const reduceOp = () => ["value = 0.0;", "value += _A(inputIdx);", ""]; return reduce(inferenceHandler, inputs, attributes, "ReduceSum", reduceOp); }; reduceMean = (inferenceHandler, inputs, attributes) => { const reduceOp = (inputs2, axes) => { let size = 1; for (let k = 0; k < inputs2[0].dims.length; k++) { if (axes.indexOf(k) >= 0 || axes.length === 0) { size *= inputs2[0].dims[k]; } } return ["value = 0.0;", "value += _A(inputIdx);", `value /= ${size}.;`]; }; return reduce(inferenceHandler, inputs, attributes, "ReduceMean", reduceOp); }; reduceMax = (inferenceHandler, inputs, attributes) => { const reduceOp = (inputs2, axes) => { const idxZero = []; for (let k = 0; k < inputs2[0].dims.length; k++) { if (axes.indexOf(k) >= 0 || axes.length === 0) { idxZero.push(`inputIdx[${k}] = 0;`); } } return [`${idxZero.join("\n")} value = _A(inputIdx);`, "value = max(value, _A(inputIdx));", ""]; }; return reduce(inferenceHandler, inputs, attributes, "ReduceMax", reduceOp); }; reduceMin = (inferenceHandler, inputs, attributes) => { const reduceOp = (inputs2, axes) => { const idxZero = []; for (let k = 0; k < inputs2[0].dims.length; k++) { if (axes.indexOf(k) >= 0 || axes.length === 0) { idxZero.push(`inputIdx[${k}] = 0;`); } } return [`${idxZero.join("\n")} value = _A(inputIdx);`, "value = min(value, _A(inputIdx));", ""]; }; return reduce(inferenceHandler, inputs, attributes, "ReduceMin", reduceOp); }; reduceProd = (inferenceHandler, inputs, attributes) => { const reduceOp = () => ["value = 1.0;", "value *= _A(inputIdx);", ""]; return reduce(inferenceHandler, inputs, attributes, "ReduceProd", reduceOp); }; reduceLogSum = (inferenceHandler, inputs, attributes) => { const reduceOp = () => ["value = 0.0;", "value += _A(inputIdx);", "value = log(value);"]; return reduce(inferenceHandler, inputs, attributes, "ReduceLogSum", reduceOp); }; reduceLogSumSquare = (inferenceHandler, inputs, attributes) => { const reduceOp = () => ["float t; value = 0.0;", "t = _A(inputIdx); value += t * t;", ""]; return reduce(inferenceHandler, inputs, attributes, "ReduceLogSumSquare", reduceOp); }; } }); // web/lib/onnxjs/backends/webgl/ops/reshape.ts var reshape; var init_reshape = __esm({ "web/lib/onnxjs/backends/webgl/ops/reshape.ts"() { "use strict"; init_util(); reshape = (handler, inputs) => { const reshapedDims = ShapeUtil.calculateReshapedDims(inputs[0].dims, inputs[1].integerData); if (handler.session.pack) { return [handler.reshapePacked(inputs[0], reshapedDims)]; } else { return [handler.reshapeUnpacked(inputs[0], reshapedDims)]; } }; } }); // web/lib/onnxjs/backends/webgl/ops/upsample.ts var upsampleProgramMetadata, upsample, parseUpsampleAttributesV7, parseUpsampleAttributesV9, parseUpsampleAttributes, createUpsampleProgramInfo, validateInputs17, scalesValidation; var init_upsample = __esm({ "web/lib/onnxjs/backends/webgl/ops/upsample.ts"() { "use strict"; init_attribute_with_cache_key(); init_glsl_source(); init_types(); upsampleProgramMetadata = { name: "Upsample", inputNames: ["X"], inputTypes: [0 /* unpacked */] }; upsample = (inferenceHandler, inputs, attributes) => { validateInputs17(inputs, attributes); const output = inferenceHandler.run( { ...upsampleProgramMetadata, cacheHint: attributes.cacheKey, get: () => createUpsampleProgramInfo(inferenceHandler, inputs, attributes) }, inputs ); return [output]; }; parseUpsampleAttributesV7 = (node) => parseUpsampleAttributes(node, 7); parseUpsampleAttributesV9 = (node) => parseUpsampleAttributes(node, 9); parseUpsampleAttributes = (node, opset) => { const isResize = opset >= 10; const mode = node.attributes.getString("mode", "nearest"); if (mode !== "nearest" && mode !== "linear" && (opset < 11 || mode !== "cubic")) { throw new Error(`unrecognized mode: ${mode}`); } let scales = []; if (opset < 9) { scales = node.attributes.getFloats("scales"); scalesValidation(scales, mode, isResize); } const extrapolationValue = node.attributes.getFloat("extrapolation_value", 0); const coordinateTransformMode = opset > 10 ? node.attributes.getString("coordinate_transformation_mode", "half_pixel") : "asymmetric"; if ([ "asymmetric", "pytorch_half_pixel", "tf_half_pixel_for_nn", "align_corners", "tf_crop_and_resize", "half_pixel" ].indexOf(coordinateTransformMode) === -1) { throw new Error(`coordinate_transform_mode '${coordinateTransformMode}' is not supported`); } const needRoiInput = coordinateTransformMode === "tf_crop_and_resize"; const useExtrapolation = needRoiInput; const nearestMode = mode === "nearest" && opset >= 11 ? node.attributes.getString("nearest_mode", "round_prefer_floor") : ""; if (["round_prefer_floor", "round_prefer_ceil", "floor", "ceil", ""].indexOf(nearestMode) === -1) { throw new Error(`nearest_mode '${nearestMode}' is not supported`); } const cubicCoefficientA = node.attributes.getFloat("cubic_coeff_a", -0.75); const excludeOutside = node.attributes.getInt("exclude_outside", 0) !== 0; if (excludeOutside && mode !== "cubic") { throw new Error("exclude_outside can be set to 1 only when mode is CUBIC."); } const useNearest2xOptimization = opset < 11 ? true : mode === "nearest" && coordinateTransformMode === "asymmetric" && nearestMode === "floor"; let roiInputIdx = 0; let scalesInputIdx = 0; let sizesInputIdx = 0; if (opset > 10) { if (node.inputs.length > 2) { roiInputIdx = 1; scalesInputIdx = 2; sizesInputIdx = 3; } else { scalesInputIdx = 1; sizesInputIdx = 2; } } else if (opset === 9) { scalesInputIdx = 1; } return createAttributeWithCacheKey({ opset, isResize, mode, scales, extrapolationValue, coordinateTransformMode, useExtrapolation, needRoiInput, nearestMode, cubicCoefficientA, excludeOutside, useNearest2xOptimization, roiInputIdx, scalesInputIdx, sizesInputIdx }); }; createUpsampleProgramInfo = (inferenceHandler, inputs, attributes) => { const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); const [inputWidth, inputHeight] = inferenceHandler.calculateTextureWidthAndHeight( inputs[0].dims, 0 /* unpacked */ ); const outputShape = inputs[0].dims.map((dim2, i) => Math.floor(dim2 * attributes.scales[i])); const [outputWidth, outputHeight] = inferenceHandler.calculateTextureWidthAndHeight( outputShape, 0 /* unpacked */ ); const dim = outputShape.length; const outputPitches = new Array(dim); const inputPitches = new Array(dim); let precalculatedPitches = ` int output_pitches[${dim}]; int input_pitches[${dim}]; `; for (let d = dim - 1; d >= 0; d--) { outputPitches[d] = d === dim - 1 ? 1 : outputPitches[d + 1] * outputShape[d + 1]; inputPitches[d] = d === dim - 1 ? 1 : inputPitches[d + 1] * inputs[0].dims[d + 1]; precalculatedPitches += ` output_pitches[${d}] = ${outputPitches[d]}; input_pitches[${d}] = ${inputPitches[d]}; `; } const getInputFloatFunction = ` float getInputFloat(int index) { vec2 coords = offsetToCoords(index, ${inputWidth}, ${inputHeight}); float value = getColorAsFloat(${glsl.texture2D}(X, coords)); return value; } `; const shaderSource = attributes.mode === "nearest" ? ( // nearest ` ${getInputFloatFunction} float process(int indices[${dim}]) { int input_index = 0; int output_index = coordsToOffset(TexCoords, ${outputWidth}, ${outputHeight}); ${precalculatedPitches} int d, m; for (int dim = 0; dim < ${dim}; ++dim) { d = output_index / output_pitches[dim]; m = output_index - d * output_pitches[dim]; output_index = m; if (scales[dim] != 1 && d > 0) { int d2 = d / scales[dim]; m = d - d2 * scales[dim]; d = d2; } input_index += input_pitches[dim] * d; } return getInputFloat(input_index); }` ) : dim === 4 ? ( // bilinear 4D ` ${getInputFloatFunction} float process(int indices[4]) { int input_index = 0; int output_index = coordsToOffset(TexCoords, ${outputWidth}, ${outputHeight}); ${precalculatedPitches} int m; int index_of_dim0, index_of_dim1, index_of_dim2, index_of_dim3; index_of_dim0 = output_index / output_pitches[0]; m = output_index - index_of_dim0 * output_pitches[0]; index_of_dim1 = m / output_pitches[1]; m = m - index_of_dim1 * output_pitches[1]; index_of_dim2 = m / output_pitches[2]; m = m - index_of_dim2 * output_pitches[2]; index_of_dim3 = m; int index_of_input_dim2, index_of_input_dim3, x_offset, y_offset; index_of_input_dim2 = index_of_dim2 / scales[2]; y_offset = index_of_dim2 - index_of_input_dim2 * scales[2]; index_of_input_dim3 = index_of_dim3 / scales[3]; x_offset = index_of_dim3 - index_of_input_dim3 * scales[3]; input_index = index_of_dim0 * input_pitches[0] + index_of_dim1 * input_pitches[1] + index_of_input_dim2 * input_pitches[2] + index_of_input_dim3; float x00 = getInputFloat(input_index); float x10, x01, x11; bool end_of_dim2 = false; if (index_of_input_dim2 == (${inputs[0].dims[2]} - 1)) { // It's the end in dimension 2 x01 = x00; end_of_dim2 = true; } else { x01 = getInputFloat(input_index + input_pitches[2]); } if (index_of_input_dim3 == (input_pitches[2] - 1)) { // It's the end in dimension 3 x10 = x00; x11 = x01; } else { x10 = getInputFloat(input_index + 1); x11 = end_of_dim2 ? x10 : getInputFloat(input_index + input_pitches[2] + 1); } float y0 = x00 + float(y_offset) * (x01 - x00) / float(scales[2]); float y1 = x10 + float(y_offset) * (x11 - x10) / float(scales[2]); return y0 + float(x_offset) * (y1 - y0) / float(scales[3]); }` ) : ( // bilinear 2D ` ${getInputFloatFunction} float process(int indices[2]) { int input_index = 0; int output_index = coordsToOffset(TexCoords, ${outputWidth}, ${outputHeight}); ${precalculatedPitches} int m; int index_of_dim0, index_of_dim1; index_of_dim0 = output_index / output_pitches[0]; m = output_index - index_of_dim0 * output_pitches[0]; index_of_dim1 = m; int index_of_input_dim0, index_of_input_dim1, x_offset, y_offset; index_of_input_dim0 = index_of_dim0 / scales[0]; y_offset = index_of_dim0 - index_of_input_dim0 * scales[0]; index_of_input_dim1 = index_of_dim1 / scales[1]; x_offset = index_of_dim1 - index_of_input_dim1 * scales[1]; input_index = index_of_input_dim0 * input_pitches[0] + index_of_input_dim1; float x00 = getInputFloat(input_index); float x10, x01, x11; bool end_of_dim0 = false; if (index_of_input_dim0 == (${inputs[0].dims[0]} - 1)) { // It's the end in dimension 0 x01 = x00; end_of_dim0 = true; } else { x01 = getInputFloat(input_index + input_pitches[0]); } if (index_of_input_dim1 == (input_pitches[0] - 1)) { // It's the end in dimension 1 x10 = x00; x11 = x01; } else { x10 = getInputFloat(input_index + 1); x11 = end_of_dim0 ? x10 : getInputFloat(input_index + input_pitches[0] + 1); } float y0 = x00 + float(y_offset) * (x01 - x00) / float(scales[0]); float y1 = x10 + float(y_offset) * (x11 - x10) / float(scales[0]); return y0 + float(x_offset) * (y1 - y0) / float(scales[1]); }` ); return { ...upsampleProgramMetadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, shaderSource, variables: [ { name: "scales", type: "int", arrayLength: attributes.scales.length, data: attributes.scales.map((x) => Math.ceil(x)) } ] }; }; validateInputs17 = (inputs, attribute) => { if (!inputs || attribute.opset < 9 && inputs.length !== 1 || attribute.opset >= 9 && attribute.opset < 11 && inputs.length !== 2 || attribute.opset >= 11 && inputs.length < 2) { throw new Error("invalid inputs."); } if (attribute.scales.length > 0 && inputs[0].dims.length !== attribute.scales.length) { throw new Error("Invalid input shape."); } if (inputs[0].type === "string") { throw new Error("Invalid input tensor types."); } }; scalesValidation = (scales, mode, isResize) => { if (!isResize) { for (const scale of scales) { if (scale < 1) { throw new Error("Scale value should be greater than or equal to 1."); } } } else { for (const scale of scales) { if (scale <= 0) { throw new Error("Scale value should be greater than 0."); } } } if (mode === "linear" || mode === "cubic") { if (scales.length !== 2 && (scales.length !== 4 || scales[0] !== 1 || scales[1] !== 1)) { throw new Error(`'Linear' mode and 'Cubic' mode only support 2-D inputs ('Bilinear', 'Bicubic') or 4-D inputs with the corresponding outermost 2 scale values being 1 in the ${isResize ? "Resize" : "Upsample"} opeartor.`); } } }; } }); // web/lib/onnxjs/backends/webgl/ops/resize-packed.ts var resizeProgramMetadata, resize, parseResizeAttributesV10, parseResizeAttributesV11, createPackedResizeProgramInfo, prepareInputs, parseScalesData, parseScalesDataFromOutputSize; var init_resize_packed = __esm({ "web/lib/onnxjs/backends/webgl/ops/resize-packed.ts"() { "use strict"; init_glsl_source(); init_types(); init_utils(); init_packing_utils(); init_upsample(); resizeProgramMetadata = { name: "Resize", inputNames: ["A"], inputTypes: [2 /* packed */] }; resize = (inferenceHandler, inputs, attributes) => { validateInputs17(inputs, attributes); const output = inferenceHandler.run( { ...resizeProgramMetadata, cacheHint: attributes.cacheKey, get: () => createPackedResizeProgramInfo(inferenceHandler, inputs, attributes) }, inputs ); return [output]; }; parseResizeAttributesV10 = (node) => parseUpsampleAttributes(node, 10); parseResizeAttributesV11 = (node) => parseUpsampleAttributes(node, 11); createPackedResizeProgramInfo = (inferenceHandler, inputs, attributes) => { const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); const [scales, outputShape] = prepareInputs(inputs, attributes); const isSame = scales.every((s) => s === 1) && attributes.coordinateTransformMode !== "tf_crop_and_resize"; if (isSame) { return { ...resizeProgramMetadata, output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, hasMain: true, shaderSource: `void main() { vec4 v = ${glsl.texture2D}(X, TexCoords); ${glsl.output} = v; }` }; } const dim = outputShape.length; if (dim < 2) { throw new Error(`output dimension should be at least 2, but got ${dim}`); } const outputHeight = outputShape[dim - 2]; const outputWidth = outputShape[dim - 1]; const inputShape = inputs[0].dims; if (dim !== inputShape.length) { throw new Error(`output dimension should match input ${inputShape.length}, but got ${dim}`); } const inputHeight = inputShape[dim - 2]; const inputWidth = inputShape[dim - 1]; const scalesHeight = scales[dim - 2]; const scalesWidth = scales[dim - 1]; let getSourceFracIndex = ""; if (attributes.mode !== "linear") { throw new Error(`resize (packed) does not support mode: '${attributes.mode}'`); } switch (attributes.coordinateTransformMode) { case "asymmetric": getSourceFracIndex = ` vec4 getSourceFracIndex(ivec4 coords) { return vec4(coords) / scaleWHWH; } `; break; case "half_pixel": getSourceFracIndex = ` vec4 getSourceFracIndex(ivec4 coords) { return (vec4(coords) + 0.5) / scaleWHWH - 0.5; } `; break; case "pytorch_half_pixel": getSourceFracIndex = ` vec4 getSourceFracIndex(ivec4 coords) { vec4 fcoords = vec4(coords); return vec4( ${outputWidth}.0 > 1.0 ? (fcoords.x + 0.5) / scaleWHWH.x - 0.5 : 0.0, ${outputHeight}.0 > 1.0 ? (fcoords.y + 0.5) / scaleWHWH.y - 0.5 : 0.0, ${outputWidth}.0 > 1.0 ? (fcoords.z + 0.5) / scaleWHWH.z - 0.5 : 0.0, ${outputHeight}.0 > 1.0 ? (fcoords.w + 0.5) / scaleWHWH.w - 0.5 : 0.0 ); } `; break; case "align_corners": getSourceFracIndex = ` vec4 getSourceFracIndex(ivec4 coords) { vec4 resized = vec4(${outputWidth}.0 - 1.0, ${outputHeight}.0 - 1.0, ${outputWidth}.0 - 1.0, ${outputHeight}.0 - 1.0); vec4 original = vec4(${inputWidth}.0 - 1.0, ${inputHeight}.0 - 1.0, ${inputWidth}.0 - 1.0, ${inputHeight}.0 - 1.0); vec4 new_scale = original / resized; return vec4(coords) * new_scale; } `; break; default: throw new Error(`resize (packed) does not support coordinateTransformMode: '${attributes.coordinateTransformMode}'`); } const coordsDataType = getCoordsDataType(dim); const unpackChannel = unpackFromChannel(); const shaderSource = ` const vec2 inputWH = vec2(${inputHeight}.0, ${inputWidth}.0); const vec4 scaleWHWH = vec4(float(${scalesHeight}), float(${scalesWidth}), float(${scalesHeight}), float(${scalesWidth})); ${unpackChannel} ${getSourceFracIndex} float getAValue(int x10, int r, int c, int d) { return getChannel(getA(x10, r, c, d), vec2(c, d)); } void main() { ${coordsDataType} rc = getOutputCoords(); int batch = rc[0]; int depth = rc[1]; // retrieve the 4 coordinates that is used in the 4 packed output values. ivec4 coords = ivec4(rc.wz, rc.w + 1, rc.z + 1); // calculate the source index in fraction vec4 sourceFrac = getSourceFracIndex(coords); // get the lower and upper bound of the 4 values that will be packed into one texel. ivec4 x00 = ivec4(max(sourceFrac.xy, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.xy))); ivec4 x01 = ivec4(max(sourceFrac.xw, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.xw))); ivec4 x10 = ivec4(max(sourceFrac.zy, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.zy))); ivec4 x11 = ivec4(max(sourceFrac.zw, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.zw))); bool hasNextRow = rc.w < ${outputHeight - 1}; bool hasNextCol = rc.z < ${outputWidth - 1}; // pack x00, x01, x10, x11's top-left corner into one vec4 structure vec4 topLeft = vec4( getAValue(batch, depth, x00.x, x00.y), hasNextCol ? getAValue(batch, depth, x01.x, x01.y) : 0.0, hasNextRow ? getAValue(batch, depth, x10.x, x10.y) : 0.0, (hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.x, x11.y) : 0.0); // pack x00, x01, x10, x11's top-right corner into one vec4 structure vec4 topRight = vec4( getAValue(batch, depth, x00.x, x00.w), hasNextCol ? getAValue(batch, depth, x01.x, x01.w) : 0.0, hasNextRow ? getAValue(batch, depth, x10.x, x10.w) : 0.0, (hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.x, x11.w) : 0.0); // pack x00, x01, x10, x11's bottom-left corner into one vec4 structure vec4 bottomLeft = vec4( getAValue(batch, depth, x00.z, x00.y), hasNextCol ? getAValue(batch, depth, x01.z, x01.y) : 0.0, hasNextRow ? getAValue(batch, depth, x10.z, x10.y) : 0.0, (hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.z, x11.y) : 0.0); // pack x00, x01, x10, x11's bottom-right corner into one vec4 structure vec4 bottomRight = vec4( getAValue(batch, depth, x00.z, x00.w), hasNextCol ? getAValue(batch, depth, x01.z, x01.w) : 0.0, hasNextRow ? getAValue(batch, depth, x10.z, x10.w) : 0.0, (hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.z, x11.w) : 0.0); // calculate the interpolation fraction on u and v direction vec4 frac = vec4(sourceFrac) - floor(sourceFrac); vec4 clampFrac = clamp(frac, vec4(0.0), vec4(1.0)); vec4 top = mix(topLeft, topRight, clampFrac.ywyw); vec4 bottom = mix(bottomLeft, bottomRight, clampFrac.ywyw); vec4 newValue = mix(top, bottom, clampFrac.xxzz); ${glsl.output} = vec4(newValue); } `; return { ...resizeProgramMetadata, output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, hasMain: true, shaderSource }; }; prepareInputs = (inputs, attributes) => { const x = inputs[0]; const xDims = x.dims; let scales = attributes.scales; let outputSizes; if (scales.length === 0) { const scalesTensor = inputs[attributes.scalesInputIdx]; if (scalesTensor && scalesTensor.size !== 0) { if (inputs[attributes.sizesInputIdx]) { throw new Error("Only one of scales or sizes must be provided as input."); } scales = parseScalesData(scalesTensor, attributes.mode, attributes.isResize); } else { const sizesTensor = inputs[attributes.sizesInputIdx]; if (!sizesTensor || sizesTensor.size === 0) { throw new Error("Either scales or sizes MUST be provided as input."); } outputSizes = Array.from(sizesTensor.integerData); scales = parseScalesDataFromOutputSize(outputSizes, xDims, attributes.mode, attributes.isResize); } } else { if (inputs[attributes.sizesInputIdx]) { throw new Error("Only one of scales or sizes must be provided as input."); } } const yDims = outputSizes || xDims.map((dim, i) => Math.floor(dim * scales[i])); return [scales, yDims]; }; parseScalesData = (scale, mode, isResize) => { const scales = Array.from(scale.floatData); scalesValidation(scales, mode, isResize); return scales; }; parseScalesDataFromOutputSize = (yDims, xDims, mode, isResize) => { const length = xDims.length; const scales = new Array(length); for (let i = 0, end = length; i < end; i++) { if (xDims[i] === 0) { if (yDims[i] !== 0) { throw new Error("Input dim is zero but required output dim is non-zero."); } scales[i] = 1; } else { scales[i] = yDims[i] / xDims[i]; } } scalesValidation(scales, mode, isResize); return scales; }; } }); // web/lib/onnxjs/backends/webgl/ops/shape.ts var shape, validateInputs18; var init_shape = __esm({ "web/lib/onnxjs/backends/webgl/ops/shape.ts"() { "use strict"; init_tensor2(); shape = (_inferenceHandler, inputs) => { validateInputs18(inputs); return [new Tensor4([inputs[0].dims.length], "int32", void 0, void 0, new Int32Array(inputs[0].dims))]; }; validateInputs18 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("Shape requires 1 input."); } }; } }); // web/lib/onnxjs/backends/webgl/ops/slice.ts var sliceProgramMetadata, slice, parseSliceAttributes, createSliceProgramInfo, validateInputs19, sliceV10, generateSliceAttributesFromInputs, validateInputsV10; var init_slice = __esm({ "web/lib/onnxjs/backends/webgl/ops/slice.ts"() { "use strict"; init_attribute_with_cache_key(); init_operators(); init_util(); init_types(); sliceProgramMetadata = { name: "Slice", inputNames: ["A"], inputTypes: [0 /* unpacked */] }; slice = (inferenceHandler, inputs, attributes) => { validateInputs19(inputs); const output = inferenceHandler.run( { ...sliceProgramMetadata, cacheHint: attributes.cacheKey, get: () => createSliceProgramInfo(inferenceHandler, inputs[0], attributes) }, inputs ); return [output]; }; parseSliceAttributes = (node) => { const starts = node.attributes.getInts("starts"); const ends = node.attributes.getInts("ends"); const axes = node.attributes.getInts("axes", []); return createAttributeWithCacheKey({ starts, ends, axes }); }; createSliceProgramInfo = (_inferenceHandler, input, attributes) => { const axes = attributes.axes.length === 0 ? input.dims.slice(0).map((_val, i) => i) : attributes.axes; const normalizedAxes = ShapeUtil.normalizeAxes(axes, input.dims.length); const starts = attributes.starts.map((start, i) => { if (start > input.dims[normalizedAxes[i]] - 1) { return input.dims[normalizedAxes[i]]; } return ShapeUtil.normalizeAxis(start, input.dims[normalizedAxes[i]]); }); const ends = attributes.ends.map((end, i) => { if (end > input.dims[normalizedAxes[i]] - 1) { return input.dims[normalizedAxes[i]]; } return ShapeUtil.normalizeAxis(end, input.dims[normalizedAxes[i]]); }); const outputShape = input.dims.slice(); const sliceOps = []; for (let i = 0; i < normalizedAxes.length; i++) { outputShape[normalizedAxes[i]] = ends[i] - starts[i]; if (starts[i] > 0) { sliceOps.push(`outputIdx[${normalizedAxes[i]}] += ${starts[i]};`); } } const rank = outputShape.length; const shaderSource = ` float process(int outputIdx[${rank}]) { ${sliceOps.join("\n ")} return _A(outputIdx); }`; return { ...sliceProgramMetadata, output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, shaderSource }; }; validateInputs19 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("Slice requires 1 input."); } if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) { throw new Error("Invalid input type."); } }; sliceV10 = (inferenceHandler, inputs) => { validateInputsV10(inputs); const attributes = generateSliceAttributesFromInputs(inferenceHandler, inputs); const output = inferenceHandler.run( { ...sliceProgramMetadata, cacheHint: attributes.cacheKey, get: () => createSliceProgramInfo(inferenceHandler, inputs[0], attributes) }, [inputs[0]] ); return [output]; }; generateSliceAttributesFromInputs = (inferenceHandler, inputs) => { if (!inferenceHandler.session.isInitializer(inputs[1].dataId) || !inferenceHandler.session.isInitializer(inputs[2].dataId) || inputs.length >= 4 && !inferenceHandler.session.isInitializer(inputs[3].dataId) || inputs.length >= 5 && !inferenceHandler.session.isInitializer(inputs[4].dataId)) { throw new Error("dynamic slice attributes are not allowed"); } if (inputs.length >= 5 && inputs[4].integerData.some((i) => i !== 1)) { throw new Error("currently non-1 steps is not supported for Slice"); } const starts = Array.from(inputs[1].integerData); const ends = Array.from(inputs[2].integerData); const axes = inputs.length >= 4 ? Array.from(inputs[3].integerData) : []; const cacheKey = `${axes};${starts};${ends}`; return { starts, ends, axes, cacheKey }; }; validateInputsV10 = (inputs) => { if (!inputs || inputs.length < 3 || inputs.length > 5) { throw new Error("Invalid input number."); } if (inputs[1].type !== "int32" || inputs[1].dims.length !== 1) { throw new Error("Invalid input type."); } if (inputs[2].type !== "int32" || inputs[2].dims.length !== 1) { throw new Error("Invalid input type."); } if (inputs.length >= 4 && (inputs[3].type !== "int32" || inputs[3].dims.length !== 1)) { throw new Error("Invalid input type."); } if (inputs.length >= 5 && (inputs[4].type !== "int32" || inputs[4].dims.length !== 1)) { throw new Error("Invalid input type."); } }; } }); // web/lib/onnxjs/backends/webgl/ops/softmax.ts var softmaxComputeMaxProgramMetadata, softmaxComputeScaleProgramMetadata, softmaxProgramMetadata, softmax, parseSoftmaxAttributes, parseSoftmaxAttributesV13, softmaxV13, computeSoftmax, createComputeMaxProgramInfo, createComputScaleProgramInfo, createSoftMaxProgramInfo, validateInputs20; var init_softmax = __esm({ "web/lib/onnxjs/backends/webgl/ops/softmax.ts"() { "use strict"; init_attribute_with_cache_key(); init_util(); init_glsl_source(); init_types(); init_transpose(); softmaxComputeMaxProgramMetadata = { name: "SoftmaxComputeMax", inputNames: ["A"], inputTypes: [0 /* unpacked */] }; softmaxComputeScaleProgramMetadata = { name: "SoftmaxComputeScale", inputNames: ["A", "Max"], inputTypes: [0 /* unpacked */, 0 /* unpacked */] }; softmaxProgramMetadata = { name: "SoftMax", inputNames: ["A", "Max", "Norm"], inputTypes: [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] }; softmax = (inferenceHandler, inputs, attributes) => { validateInputs20(inputs); const inputShape = inputs[0].dims.slice(); const axis = ShapeUtil.normalizeAxis(attributes.axis, inputShape.length); const logicalRowCount = ShapeUtil.sizeToDimension(inputShape, axis); const featureCount = ShapeUtil.sizeFromDimension(inputShape, axis); const output = computeSoftmax(inferenceHandler, inputs, attributes, logicalRowCount, featureCount); return output; }; parseSoftmaxAttributes = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis", 1) }); parseSoftmaxAttributesV13 = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis", -1) }); softmaxV13 = (inferenceHandler, inputs, attributes) => { validateInputs20(inputs); const inputShape = inputs[0].dims.slice(); const axis = ShapeUtil.normalizeAxis(attributes.axis, inputShape.length); const rank = inputShape.length; const isTransposeRequired = axis !== rank - 1 ? true : false; const transposedInputShape = []; let perm = []; let transposedInputs = []; let transposeAttribute; if (isTransposeRequired) { perm = Array.from({ length: rank }).map((_, i) => i); perm[axis] = rank - 1; perm[rank - 1] = axis; perm.map((p) => transposedInputShape.push(inputShape[p])); transposeAttribute = createAttributeWithCacheKey({ perm }); transposedInputs = transpose(inferenceHandler, inputs, transposeAttribute); } const logicalRowCount = isTransposeRequired ? ShapeUtil.sizeToDimension(transposedInputShape, rank - 1) : ShapeUtil.sizeToDimension(inputShape, rank - 1); const featureCount = isTransposeRequired ? ShapeUtil.sizeFromDimension(transposedInputShape, rank - 1) : ShapeUtil.sizeFromDimension(inputShape, rank - 1); const output = computeSoftmax( inferenceHandler, isTransposeRequired ? transposedInputs : inputs, attributes, logicalRowCount, featureCount ); if (isTransposeRequired) { const reversedOutput = transpose(inferenceHandler, output, transposeAttribute); return reversedOutput; } else { return output; } }; computeSoftmax = (inferenceHandler, inputs, attributes, logicalRowCount, featureCount) => { const computeMaxProgramInfo = createComputeMaxProgramInfo( inferenceHandler, inputs[0], logicalRowCount, featureCount, [logicalRowCount] ); const max = inferenceHandler.run( { ...softmaxComputeMaxProgramMetadata, cacheHint: attributes.cacheKey, get: () => computeMaxProgramInfo }, inputs ); const computeScaleProgramInfo = createComputScaleProgramInfo( inferenceHandler, inputs[0], logicalRowCount, featureCount, computeMaxProgramInfo.output.dims, [logicalRowCount] ); const scale = inferenceHandler.run( { ...softmaxComputeScaleProgramMetadata, cacheHint: attributes.cacheKey, get: () => computeScaleProgramInfo }, [inputs[0], max] ); const softMaxProgramInfo = createSoftMaxProgramInfo( inferenceHandler, inputs[0], logicalRowCount, featureCount, computeMaxProgramInfo.output.dims, computeScaleProgramInfo.output.dims ); const output = inferenceHandler.run( { ...softmaxProgramMetadata, cacheHint: attributes.cacheKey, get: () => softMaxProgramInfo }, [inputs[0], max, scale] ); return [output]; }; createComputeMaxProgramInfo = (inferenceHandler, input, logicalRowCount, featureCount, outputShape) => { const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight( input.dims, 0 /* unpacked */ ); const rank = outputShape.length; if (logicalRowCount < 1 || featureCount < 1) { throw new Error("Logical row count N and feature count D must be greater than or equal to 1"); } if (outputShape.length !== 1) { throw new Error("Dimensionality of the output should be 1"); } if (outputShape[0] !== logicalRowCount) { throw new Error("Shape of the output should be equal to logical row count"); } const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); const shaderSource = ` float process(int[${rank}] indices) { int logical_row_start_offset = indices[0] * ${featureCount}; float max = getColorAsFloat(${glsl.texture2D}(A, offsetToCoords(logical_row_start_offset, ${textureWidth}, ${textureHeight} ))); for(int i=1; i<${featureCount}; ++i) { float current = getColorAsFloat(${glsl.texture2D}(A, offsetToCoords(logical_row_start_offset + i, ${textureWidth}, ${textureHeight}))); if(current > max) max = current; } return max; }`; return { ...softmaxComputeMaxProgramMetadata, output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, shaderSource }; }; createComputScaleProgramInfo = (inferenceHandler, input, logicalRowCount, featureCount, maxElementPerLogicalRow, outputShape) => { const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight( input.dims, 0 /* unpacked */ ); const rank = outputShape.length; if (logicalRowCount < 1 || featureCount < 1) { throw new Error("Logical row count N and feature count D must be greater than or equal to 1"); } if (outputShape.length !== 1) { throw new Error("Dimensionality of the output should be 1"); } if (outputShape[0] !== logicalRowCount) { throw new Error("Shape of the output should be equal to logical row count"); } if (maxElementPerLogicalRow.length !== 1) { throw new Error("Dimensionality of the intermediate results should be 1"); } if (maxElementPerLogicalRow[0] !== logicalRowCount) { throw new Error("Shape of the intermediate results should be equal to logical row count"); } const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); const shaderSource = ` float process(int[${rank}] indices) { int logical_row_start_offset = indices[0] * ${featureCount}; float norm_factor = 0.0; float max = _Max(indices); for(int i=0; i<${featureCount}; ++i) { norm_factor += exp(getColorAsFloat(${glsl.texture2D}(A, offsetToCoords(logical_row_start_offset + i, ${textureWidth}, ${textureHeight}))) - max); } return norm_factor; }`; return { ...softmaxComputeScaleProgramMetadata, output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, shaderSource }; }; createSoftMaxProgramInfo = (inferenceHandler, input, logicalRowCount, featureCount, maxElementPerLogicalRow, normalizationPerLogicalRow) => { const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight( input.dims, 0 /* unpacked */ ); const rank = input.dims.length; if (logicalRowCount < 1 || featureCount < 1) { throw new Error("Logical row count N and feature count D must be greater than or equal to 1"); } if (maxElementPerLogicalRow.length !== 1 || normalizationPerLogicalRow.length !== 1) { throw new Error("Dimensionality of the intermediate results should be 1"); } if (maxElementPerLogicalRow[0] !== logicalRowCount || normalizationPerLogicalRow[0] !== logicalRowCount) { throw new Error("Shape of the intermediate results should be equal to logical row count"); } const shaderSource = ` float process(int[${rank}] indices) { // get offset of current logical tensor index from the 2-D texture coordinates (TexCoords) int offset = coordsToOffset(TexCoords, ${textureWidth}, ${textureHeight}); //determine the logical row for this index int logical_row_index[1]; logical_row_index[0] = offset / ${featureCount}; float norm_factor = _Norm(logical_row_index); // avoid possible division by 0 // if norm_facor is 0, all elements are zero // if so, return 0 if(norm_factor == 0.0) return 0.0; return exp(_A(indices) - _Max(logical_row_index)) / norm_factor; }`; return { ...softmaxProgramMetadata, output: { dims: input.dims, type: input.type, textureType: 0 /* unpacked */ }, shaderSource }; }; validateInputs20 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("Softmax requires 1 input."); } if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { throw new Error("Invalid input type"); } }; } }); // web/lib/onnxjs/backends/webgl/ops/split.ts var splitProgramMetadata, split, parseSplitAttributes, getProgramCount, createSplitProgramInfo, validateInputs21; var init_split = __esm({ "web/lib/onnxjs/backends/webgl/ops/split.ts"() { "use strict"; init_attribute_with_cache_key(); init_util(); init_types(); splitProgramMetadata = { name: "Split", inputNames: ["A"], inputTypes: [0 /* unpacked */] }; split = (inferenceHandler, inputs, attributes) => { validateInputs21(inputs); const axis = ShapeUtil.normalizeAxis(attributes.axis, inputs[0].dims.length); const count = getProgramCount(inferenceHandler, inputs, axis, attributes); const output = []; for (let i = 0; i < count; ++i) { output.push( inferenceHandler.run( { ...splitProgramMetadata, cacheHint: `${attributes.cacheKey};${i}`, get: () => createSplitProgramInfo(inferenceHandler, inputs[0], attributes, axis, i) }, inputs ) ); } return output; }; parseSplitAttributes = (node) => { const axis = node.attributes.getInt("axis", 0); const split2 = node.attributes.getInts("split", []); const numOutputs = node.outputs.length; return createAttributeWithCacheKey({ axis, split: split2, numOutputs }); }; getProgramCount = (_inferenceHandler, inputs, axis, attributes) => { const [, offsets] = SplitUtil.splitShape(inputs[0].dims, axis, attributes.split, attributes.numOutputs); return offsets.length; }; createSplitProgramInfo = (_inferenceHandler, input, attributes, axis, index) => { const [shapes, offsets] = SplitUtil.splitShape(input.dims, axis, attributes.split, attributes.numOutputs); const offset = offsets[index]; const outputShape = shapes[index]; const rank = outputShape.length; const shaderSource = ` float process(int indices[${rank}]) { indices[${axis}] += ${offset}; return _A(indices); } `; return { ...splitProgramMetadata, cacheHint: `${attributes.cacheKey}:${index}`, output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, shaderSource }; }; validateInputs21 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("Split requires one input."); } if (inputs[0].type !== "int8" && inputs[0].type !== "uint8" && inputs[0].type !== "int16" && inputs[0].type !== "uint16" && inputs[0].type !== "int32" && inputs[0].type !== "uint32" && inputs[0].type !== "float32" && inputs[0].type !== "float64" && inputs[0].type !== "bool") { throw new Error("Invalid input type."); } }; } }); // web/lib/onnxjs/backends/webgl/ops/squeeze.ts var squeeze, squeezeV13, parseSqueezeAttributes, validateInputs22, validateInputsV13; var init_squeeze = __esm({ "web/lib/onnxjs/backends/webgl/ops/squeeze.ts"() { "use strict"; init_util(); squeeze = (inferenceHandler, inputs, axes) => { validateInputs22(inputs); const outputShape = ShapeUtil.squeezeShape(inputs[0].dims, axes); const output = inferenceHandler.reshapeUnpacked(inputs[0], outputShape); return [output]; }; squeezeV13 = (inferenceHandler, inputs) => { validateInputsV13(inputs); return squeeze(inferenceHandler, [inputs[0]], Array.from(inputs[1].integerData)); }; parseSqueezeAttributes = (node) => node.attributes.getInts("axes"); validateInputs22 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("Squeeze requires 1 input."); } if (inputs[0].type === "string") { throw new Error("invalid input tensor types."); } }; validateInputsV13 = (inputs) => { if (!inputs || inputs.length !== 2) { throw new Error("Squeeze requires 2 inputs."); } if (inputs[1].type !== "int32") { throw new Error("Invalid input type."); } }; } }); // web/lib/onnxjs/backends/webgl/ops/sum.ts var sum, createSumProgramInfo, validateInputs23; var init_sum = __esm({ "web/lib/onnxjs/backends/webgl/ops/sum.ts"() { "use strict"; init_glsl_source(); init_types(); sum = (inferenceHandler, inputs) => { validateInputs23(inputs); const sumProgramMetadata = { name: "Sum", inputNames: inputs.map((_v, i) => `X${i}`), inputTypes: new Array(inputs.length).fill(0 /* unpacked */) }; const output = inferenceHandler.run( { ...sumProgramMetadata, get: () => createSumProgramInfo(inferenceHandler, inputs, sumProgramMetadata) }, inputs ); return [output]; }; createSumProgramInfo = (inferenceHandler, inputs, sumProgramMetadata) => { const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); const outputShape = inputs[0].dims.slice(); const sumLine = inputs.map((_v, i) => `${glsl.texture2D}(X${i},TexCoords)`).join(" + "); const shaderSource = ` void main() { vec4 result = ${sumLine}; ${glsl.output} = result; } `; return { ...sumProgramMetadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, hasMain: true, shaderSource }; }; validateInputs23 = (inputs) => { if (!inputs || inputs.length === 0) { throw new Error("Sum requires inputs."); } const length = inputs[0].dims.length; for (let i = 1; i < inputs.length; i++) { if (length !== inputs[i].dims.length) { throw new Error("Input shapes are mismatched."); } for (let j = 0; j < length; j++) { if (inputs[0].dims[j] !== inputs[i].dims[j]) { throw new Error("Input shapes are not matched."); } } } if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { throw new Error("Invalid input type."); } for (let i = 1; i < inputs.length; i++) { if (inputs[0].type !== inputs[i].type) { throw new Error("Input types are not matched."); } } }; } }); // web/lib/onnxjs/backends/webgl/ops/tile.ts var tile, createTileProgramInfo, validateInputs24; var init_tile = __esm({ "web/lib/onnxjs/backends/webgl/ops/tile.ts"() { "use strict"; init_operators(); init_types(); tile = (inferenceHandler, inputs) => { validateInputs24(inputs); const tileProgramMetadata = { name: "Tile", inputNames: ["A"], inputTypes: [0 /* unpacked */] }; const output = inferenceHandler.run( { ...tileProgramMetadata, get: () => createTileProgramInfo(inferenceHandler, inputs, tileProgramMetadata) }, inputs ); return [output]; }; createTileProgramInfo = (_handler, inputs, tileProgramMetadata) => { const inputShape = inputs[0].dims.slice(); const outputShape = new Array(inputShape.length); const tileOps = []; for (let i = 0; i < inputShape.length; i++) { outputShape[i] = inputShape[i] * inputs[1].numberData[i]; tileOps.push(`inputIdx[${i}] = int(mod(float(outputIdx[${i}]), ${inputShape[i]}.));`); } const rank = outputShape.length; const shaderSource = ` float process(int outputIdx[${rank}]) { int inputIdx[${rank}]; ${tileOps.join("\n")} return _A(inputIdx); } `; return { ...tileProgramMetadata, output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, shaderSource }; }; validateInputs24 = (inputs) => { if (!inputs || inputs.length !== 2) { throw new Error("Tile requires 2 input."); } if (inputs[1].dims.length !== 1) { throw new Error("The second input shape must 1 dimension."); } if (inputs[1].dims[0] !== inputs[0].dims.length) { throw new Error("Invalid input shape."); } if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) { throw new Error("Invalid input type."); } if (inputs[1].type !== "int32" && inputs[1].type !== "int16") { throw new Error("Invalid repeat type."); } }; } }); // web/lib/onnxjs/backends/webgl/ops/unsqueeze.ts var unsqueeze, unsqueezeV13, parseUnsqueezeAttributes, validateInputs25, validateInputsV132; var init_unsqueeze = __esm({ "web/lib/onnxjs/backends/webgl/ops/unsqueeze.ts"() { "use strict"; init_util(); unsqueeze = (inferenceHandler, inputs, axes) => { validateInputs25(inputs); const outputShape = ShapeUtil.unsqueezeShape(inputs[0].dims, axes); const output = inferenceHandler.reshapeUnpacked(inputs[0], outputShape); return [output]; }; unsqueezeV13 = (inferenceHandler, inputs) => { validateInputsV132(inputs); return unsqueeze(inferenceHandler, [inputs[0]], Array.from(inputs[1].integerData)); }; parseUnsqueezeAttributes = (node) => node.attributes.getInts("axes"); validateInputs25 = (inputs) => { if (!inputs || inputs.length !== 1) { throw new Error("Unsqueeze requires 1 input."); } if (inputs[0].type === "string") { throw new Error("invalid input tensor types."); } }; validateInputsV132 = (inputs) => { if (!inputs || inputs.length !== 2) { throw new Error("Unsqueeze requires 2 inputs."); } if (inputs[1].type !== "int32") { throw new Error("Invalid input type."); } }; } }); // web/lib/onnxjs/backends/webgl/op-resolve-rules.ts var WEBGL_OP_RESOLVE_RULES; var init_op_resolve_rules = __esm({ "web/lib/onnxjs/backends/webgl/op-resolve-rules.ts"() { "use strict"; init_batch_normalization(); init_binary_op(); init_cast(); init_concat(); init_conv(); init_conv_transpose(); init_depth_to_space(); init_flatten(); init_gather(); init_gemm(); init_image_scaler(); init_instance_normalization(); init_lrn(); init_matmul(); init_pad(); init_pool(); init_reduce(); init_reshape(); init_resize_packed(); init_shape(); init_slice(); init_softmax(); init_split(); init_squeeze(); init_sum(); init_tile(); init_transpose(); init_unary_op(); init_unsqueeze(); init_upsample(); WEBGL_OP_RESOLVE_RULES = [ ["Abs", "", "6+", abs], ["Acos", "", "7+", acos], ["Add", "", "7+", add2], ["And", "", "7+", and2], ["Asin", "", "7+", asin], ["Atan", "", "7+", atan], // TODO: support new attributes for AveragePool-10 ["AveragePool", "", "7+", averagePool, parseAveragePoolAttributes], ["BatchNormalization", "", "7+", batchNormalization, parseBatchNormalizationAttributes], ["Cast", "", "6+", cast, parseCastAttributes], ["Ceil", "", "6+", ceil], ["Clip", "", "6-10", clip, parseClipAttributes], ["Clip", "", "11+", clipV11], ["Concat", "", "4+", concat, parseConcatAttributes], ["Conv", "", "1+", conv, parseConvAttributes], ["ConvTranspose", "", "1+", convTranspose, parseConvTransposeAttributes], ["Cos", "", "7+", cos], ["Div", "", "7+", div], ["Dropout", "", "7+", identity], ["DepthToSpace", "", "1+", depthToSpace, parseDepthToSpaceAttributes], ["Equal", "", "7+", equal], ["Elu", "", "6+", elu, parseEluAttributes], ["Exp", "", "6+", exp], ["Flatten", "", "1+", flatten, parseFlattenAttributes], ["Floor", "", "6+", floor], ["FusedConv", "com.microsoft", "1+", conv, parseConvAttributes], ["Gather", "", "1+", gather, parseGatherAttributes], ["Gemm", "", "7-10", gemm, parseGemmAttributesV7], ["Gemm", "", "11+", gemm, parseGemmAttributesV11], ["GlobalAveragePool", "", "1+", globalAveragePool, parseGlobalAveragePoolAttributes], ["GlobalMaxPool", "", "1+", globalMaxPool], ["Greater", "", "7+", greater], ["Identity", "", "1+", identity], ["ImageScaler", "", "1+", imageScaler, parseImageScalerAttributes], ["InstanceNormalization", "", "6+", instanceNormalization, parseInstanceNormalizationAttributes], ["LeakyRelu", "", "6+", leakyRelu, parseLeakyReluAttributes], ["Less", "", "7+", less], ["LRN", "", "1+", lrn, parseLrnAttributes], ["Log", "", "6+", log2], ["MatMul", "", "1+", matMul, parseMatMulAttributes], // TODO: support new attributes for MaxPool-8 and MaxPool-10 ["MaxPool", "", "1+", maxPool, parseMaxPoolAttributes], ["Mul", "", "7+", mul], ["Neg", "", "6+", neg], ["Not", "", "1+", not2], ["Or", "", "7+", or2], ["Pad", "", "2-10", padV2, parsePadAttributesV2], ["Pad", "", "11+", padV11, parsePadAttributesV11], ["Pow", "", "7+", pow], ["PRelu", "", "7+", pRelu], ["ReduceLogSum", "", "1+", reduceLogSum, parseReduceAttributes], ["ReduceMax", "", "1+", reduceMax, parseReduceAttributes], ["ReduceMean", "", "1+", reduceMean, parseReduceAttributes], ["ReduceMin", "", "1+", reduceMin, parseReduceAttributes], ["ReduceProd", "", "1+", reduceProd, parseReduceAttributes], ["ReduceSum", "", "1-12", reduceSum, parseReduceAttributes], ["ReduceSumSquare", "", "1+", reduceLogSumSquare, parseReduceAttributes], ["Relu", "", "6+", relu], ["Reshape", "", "5+", reshape], ["Resize", "", "10", resize, parseResizeAttributesV10], ["Resize", "", "11+", resize, parseResizeAttributesV11], ["Shape", "", "1+", shape], ["Sigmoid", "", "6+", sigmoid], ["Sin", "", "7+", sin], ["Slice", "", "10+", sliceV10], // TODO: support 'steps' for Slice-10 ["Slice", "", "1-9", slice, parseSliceAttributes], // The "semantic" meaning of axis has changed in opset-13. ["Softmax", "", "1-12", softmax, parseSoftmaxAttributes], ["Softmax", "", "13+", softmaxV13, parseSoftmaxAttributesV13], // 'Split' operator has an optional attribute 'split' // this attribute determines how the specified axis of input data is split. // When the attribute is missing, we need the count of number of outputs // so that we can determine the 'split' attribute from the runtime input to the Operator ["Split", "", "2-12", split, parseSplitAttributes], ["Sqrt", "", "6+", sqrt], ["Squeeze", "", "1-12", squeeze, parseSqueezeAttributes], ["Squeeze", "", "13+", squeezeV13], ["Sub", "", "7+", sub], ["Sum", "", "6+", sum], ["Tan", "", "7+", tan], ["Tanh", "", "6+", tanh], ["Tile", "", "6+", tile], ["Transpose", "", "1+", transpose, parseTransposeAttributes], ["Upsample", "", "7-8", upsample, parseUpsampleAttributesV7], ["Upsample", "", "9", upsample, parseUpsampleAttributesV9], ["Unsqueeze", "", "1-12", unsqueeze, parseUnsqueezeAttributes], ["Unsqueeze", "", "13+", unsqueezeV13], ["Xor", "", "7+", xor2] ]; } }); // web/lib/onnxjs/backends/webgl/glsl-function-inliner.ts function replaceInlines(script) { const inlineDefs = {}; let match; while ((match = INLINE_FUNC_DEF_REGEX.exec(script)) !== null) { const params = match[3].split(",").map((s) => { const tokens = s.trim().split(" "); if (tokens && tokens.length === 2) { return { type: tokens[0], name: tokens[1] }; } return null; }).filter((v) => v !== null); inlineDefs[match[2]] = { params, body: match[4] }; } for (const name2 in inlineDefs) { const regexString = FUNC_CALL_REGEX.replace("__FUNC__", name2); const regex = new RegExp(regexString, "gm"); while ((match = regex.exec(script)) !== null) { const type = match[1]; const variable = match[2]; const params = match[3].split(","); const declLine = type ? `${type} ${variable};` : ""; let newBody = inlineDefs[name2].body; let paramRedecLine = ""; inlineDefs[name2].params.forEach((v, i) => { if (v) { paramRedecLine += `${v.type} ${v.name} = ${params[i]}; `; } }); newBody = `${paramRedecLine} ${newBody}`; newBody = newBody.replace("return", `${variable} = `); const replacement = ` ${declLine} { ${newBody} } `; script = script.replace(match[0], replacement); } } script = script.replace(INLINE_FUNC_DEF_REGEX, ""); return script; } var INLINE_FUNC_DEF_REGEX, FUNC_CALL_REGEX; var init_glsl_function_inliner = __esm({ "web/lib/onnxjs/backends/webgl/glsl-function-inliner.ts"() { "use strict"; INLINE_FUNC_DEF_REGEX = /@inline[\s\n\r]+(\w+)[\s\n\r]+([0-9a-zA-Z_]+)\s*\(([^)]*)\)\s*{(([^}]|[\n\r])*)}/gm; FUNC_CALL_REGEX = "(\\w+)?\\s+([_0-9a-zA-Z]+)\\s+=\\s+__FUNC__\\((.*)\\)\\s*;"; } }); // web/lib/onnxjs/backends/webgl/texture-layout-strategy.ts function squeezeShape(shape2, axis) { const newShape = []; const keptDims = []; const isEmptyArray = axis != null && Array.isArray(axis) && axis.length === 0; const axes = axis == null || isEmptyArray ? null : parseAxisParam(axis, shape2).sort(); let j = 0; for (let i = 0; i < shape2.length; ++i) { if (axes != null) { if (axes[j] === i && shape2[i] !== 1) { throw new Error(`Can't squeeze axis ${i} since its dim '${shape2[i]}' is not 1`); } if ((axes[j] == null || axes[j] > i) && shape2[i] === 1) { newShape.push(shape2[i]); keptDims.push(i); } if (axes[j] <= i) { j++; } } if (shape2[i] !== 1) { newShape.push(shape2[i]); keptDims.push(i); } } return { newShape, keptDims }; } function parseAxisParam(axis, shape2) { const rank = shape2.length; axis = axis == null ? shape2.map((_s, i) => i) : [].concat(axis); assert( axis.every((ax) => ax >= -rank && ax < rank), () => `All values in axis param must be in range [-${rank}, ${rank}) but got axis ${axis}` ); assert(axis.every(isInt), () => `All values in axis param must be integers but got axis ${axis}`); return axis.map((a) => a < 0 ? rank + a : a); } function isInt(a) { return a % 1 === 0; } function sizeFromShape(shape2) { if (shape2.length === 0) { return 1; } let size = shape2[0]; for (let i = 1; i < shape2.length; i++) { size *= shape2[i]; } return size; } function sizeToSquarishShape(size) { const width = Math.ceil(Math.sqrt(size)); return [width, Math.ceil(size / width)]; } var PreferLogicalStrategy; var init_texture_layout_strategy = __esm({ "web/lib/onnxjs/backends/webgl/texture-layout-strategy.ts"() { "use strict"; init_instrument(); init_util(); PreferLogicalStrategy = class { constructor(maxTextureSize) { this.maxTextureSize = maxTextureSize; } computeTextureWH(shape2, prefs) { const wh = this.computeTexture(shape2, prefs); if (prefs && prefs.isPacked) { wh[0] /= 2; wh[1] /= 2; } if (prefs && prefs.reverseWH) { return [wh[1], wh[0]]; } return wh; } computeTexture(shape2, prefs) { const isPacked = prefs && prefs.isPacked; if (shape2.length === 0) { return isPacked ? [2, 2] : [1, 1]; } let maxTextureSize = this.maxTextureSize; if (prefs && prefs.breakAxis !== void 0) { const wsize = prefs.breakAxis >= shape2.length ? 1 : shape2.slice(prefs.breakAxis).reduce((a, b) => a * b); const hsize = prefs.breakAxis <= 0 ? 1 : shape2.slice(0, prefs.breakAxis).reduce((a, b) => a * b); if (wsize > maxTextureSize || hsize > maxTextureSize) { Logger.verbose( "TextureLayout", `Given width/height preferences were unattainable: shape:${shape2}, breakAxis:${prefs.breakAxis}` ); } else { return [wsize, hsize]; } } let logShape = shape2.slice(0); if (isPacked) { maxTextureSize = maxTextureSize * 2; logShape = logShape.map( (_d, i) => i >= logShape.length - 2 ? logShape[i] % 2 === 0 ? logShape[i] : logShape[i] + 1 : logShape[i] ); if (logShape.length === 1) { logShape = [2, logShape[0]]; } } if (logShape.length !== 2) { const squeezeResult = squeezeShape(logShape); logShape = squeezeResult.newShape; } const size = sizeFromShape(logShape); if (logShape.length <= 1 && size <= maxTextureSize) { return [1, size]; } else if (logShape.length === 2 && logShape[0] <= maxTextureSize && logShape[1] <= maxTextureSize) { return logShape; } else if (logShape.length === 3 && logShape[0] * logShape[1] <= maxTextureSize && logShape[2] <= maxTextureSize) { return [logShape[0] * logShape[1], logShape[2]]; } else if (logShape.length === 3 && logShape[0] <= maxTextureSize && logShape[1] * logShape[2] <= maxTextureSize) { return [logShape[0], logShape[1] * logShape[2]]; } else if (logShape.length === 4 && logShape[0] * logShape[1] * logShape[2] <= maxTextureSize && logShape[3] <= maxTextureSize) { return [logShape[0] * logShape[1] * logShape[2], logShape[3]]; } else if (logShape.length === 4 && logShape[0] <= maxTextureSize && logShape[1] * logShape[2] * logShape[3] <= maxTextureSize) { return [logShape[0], logShape[1] * logShape[2] * logShape[3]]; } else { if (isPacked) { return sizeToSquarishShape(size / 4).map((d) => d * 2); } return sizeToSquarishShape(size); } } }; } }); // web/lib/onnxjs/backends/webgl/glsl-coordinate-lib.ts var CoordsGlslLib; var init_glsl_coordinate_lib = __esm({ "web/lib/onnxjs/backends/webgl/glsl-coordinate-lib.ts"() { "use strict"; init_util(); init_glsl_definitions(); init_glsl_source(); init_texture_layout_strategy(); init_utils(); CoordsGlslLib = class extends GlslLib { constructor(context) { super(context); } getFunctions() { return { ...this.offsetToCoords(), ...this.coordsToOffset(), ...this.toVec(), ...this.valueFrom(), // TODO return these only when packing is enabled. ...this.getCommonUtilFuncs(), ...this.getInputsSamplingSnippets(), ...this.getOutputSamplingSnippet() }; } getCustomTypes() { return {}; } /** * Produces a function that can map from * 2D normalzied coordinates (s,t) to a flat offset */ offsetToCoords() { const funcName = "offsetToCoords"; return { offsetToCoords: new GlslLibRoutine(` vec2 ${funcName}(int offset, int width, int height) { int t = offset / width; int s = offset - t*width; vec2 coords = (vec2(s,t) + vec2(0.5,0.5)) / vec2(width, height); return coords; } `) }; } /** * Produces a function that can map from * 2D normalzied coordinates (s,t) to a flat offset */ coordsToOffset() { const funcName = "coordsToOffset"; return { coordsToOffset: new GlslLibRoutine(` int ${funcName}(vec2 coords, int width, int height) { float s = coords.s * float(width); float t = coords.t * float(height); int offset = int(t) * width + int(s); return offset; } `) }; } /** * Generates code for output sampler. */ getOutputSamplingSnippet() { const outputLayout = this.context.outputTextureLayout; if (outputLayout.isPacked) { return this.getPackedOutputSamplingSnippet(outputLayout); } else { return this.getUnpackedOutputSamplingSnippet(outputLayout); } } /** * Generates code for packed output sampler. */ getPackedOutputSamplingSnippet(outputLayout) { const outShape = outputLayout.unpackedShape; const outTexShape = [outputLayout.width, outputLayout.height]; const result = {}; const funcName = "getOutputCoords"; switch (outShape.length) { case 0: result[funcName] = this.getOutputScalarCoords(); break; case 1: result[funcName] = this.getOutputPacked1DCoords(outShape, outTexShape); break; case 2: result[funcName] = this.getOutputPacked2DCoords(outShape, outTexShape); break; case 3: result[funcName] = this.getOutputPacked3DCoords( outShape, outTexShape ); break; default: result[funcName] = this.getOutputPackedNDCoords(outShape, outTexShape); } const glsl = getGlsl(this.context.glContext.version); const floatTextureSetRGBASource = ` void setOutput(vec4 val) { ${glsl.output} = val; } `; const floatTextureSetRGBAFuncName = "floatTextureSetRGBA"; result[floatTextureSetRGBAFuncName] = new GlslLibRoutine(floatTextureSetRGBASource); return result; } /** * Generates code for unpacked output sampler. */ getUnpackedOutputSamplingSnippet(outputLayout) { const outShape = outputLayout.unpackedShape; const outTexShape = [outputLayout.width, outputLayout.height]; const result = {}; const funcName = "getOutputCoords"; switch (outShape.length) { case 0: result[funcName] = this.getOutputScalarCoords(); break; case 1: result[funcName] = this.getOutputUnpacked1DCoords(outShape, outTexShape); break; case 2: result[funcName] = this.getOutputUnpacked2DCoords( outShape, outTexShape ); break; case 3: result[funcName] = this.getOutputUnpacked3DCoords( outShape, outTexShape ); break; case 4: result[funcName] = this.getOutputUnpacked4DCoords( outShape, outTexShape ); break; case 5: result[funcName] = this.getOutputUnpacked5DCoords( outShape, outTexShape ); break; case 6: result[funcName] = this.getOutputUnpacked6DCoords( outShape, outTexShape ); break; default: throw new Error(`Unsupported output dimensionality: ${outShape.length}`); } const glsl = getGlsl(this.context.glContext.version); const floatTextureSetRSource = ` void setOutput(float val) { ${glsl.output} = vec4(val, 0, 0, 0); } `; const floatTextureSetRFuncName = "floatTextureSetR"; result[floatTextureSetRFuncName] = new GlslLibRoutine(floatTextureSetRSource); return result; } /** * Scalar output coordinates. */ getOutputScalarCoords() { return new GlslLibRoutine(` int getOutputCoords() { return 0; } `); } /** * 1D packed output coordinates. */ getOutputPacked1DCoords(_shape, texShape) { const packedTexShape = texShape; let source = ""; if (packedTexShape[0] === 1) { source = ` int getOutputCoords() { return 2 * int(TexCoords.y * ${packedTexShape[1]}.0); } `; return new GlslLibRoutine(source); } if (packedTexShape[1] === 1) { source = ` int getOutputCoords() { return 2 * int(TexCoords.x * ${packedTexShape[0]}.0); } `; return new GlslLibRoutine(source); } source = ` int getOutputCoords() { ivec2 resTexRC = ivec2(TexCoords.xy * vec2(${packedTexShape[0]}, ${packedTexShape[1]})); return 2 * (resTexRC.y * ${packedTexShape[0]} + resTexRC.x); } `; return new GlslLibRoutine(source); } /** * 2D packed output coordinates. */ getOutputPacked2DCoords(shape2, texShape) { let source = ""; if (ArrayUtil.arraysEqual(shape2, texShape)) { source = ` ivec2 getOutputCoords() { return 2 * ivec2(TexCoords.xy * vec2(${texShape[0]}, ${texShape[1]})); } `; return new GlslLibRoutine(source); } const packedTexShape = texShape; const texelsInLogicalRow = Math.ceil(shape2[1] / 2); source = ` ivec2 getOutputCoords() { ivec2 resTexRC = ivec2(TexCoords.xy * vec2(${packedTexShape[0]}, ${packedTexShape[1]})); int index = resTexRC.y * ${packedTexShape[0]} + resTexRC.x; // reverse r and c order for packed texture int r = imod(index, ${texelsInLogicalRow}) * 2; int c = 2 * (index / ${texelsInLogicalRow}); return ivec2(r, c); } `; return new GlslLibRoutine(source); } /** * 3D packed output coordinates. */ getOutputPacked3DCoords(shape2, texShape) { const packedTexShape = [texShape[0], texShape[1]]; const texelsInLogicalRow = Math.ceil(shape2[2] / 2); const texelsInBatch = texelsInLogicalRow * Math.ceil(shape2[1] / 2); const source = ` ivec3 getOutputCoords() { ivec2 resTexRC = ivec2(TexCoords.xy * vec2(${packedTexShape[0]}, ${packedTexShape[1]})); int index = resTexRC.y * ${packedTexShape[0]} + resTexRC.x; int b = index / ${texelsInBatch}; index -= b * ${texelsInBatch}; // reverse r and c order for packed texture int r = imod(index, ${texelsInLogicalRow}) * 2; int c = 2 * (index / ${texelsInLogicalRow}); return ivec3(b, r, c); } `; return new GlslLibRoutine(source); } /** * ND packed output coordinates. */ getOutputPackedNDCoords(shape2, texShape) { const packedTexShape = [texShape[0], texShape[1]]; const texelsInLogicalRow = Math.ceil(shape2[shape2.length - 1] / 2); const texelsInBatch = texelsInLogicalRow * Math.ceil(shape2[shape2.length - 2] / 2); let texelsInBatchN = texelsInBatch; let batches = ""; let coords = "b, r, c"; for (let b = 2; b < shape2.length - 1; b++) { texelsInBatchN *= shape2[shape2.length - b - 1]; batches = ` int b${b} = index / ${texelsInBatchN}; index -= b${b} * ${texelsInBatchN}; ` + batches; coords = `b${b}, ` + coords; } const source = ` ivec${shape2.length} getOutputCoords() { ivec2 resTexRC = ivec2(TexCoords.xy * vec2(${packedTexShape[0]}, ${packedTexShape[1]})); int index = resTexRC.y * ${packedTexShape[0]} + resTexRC.x; ${batches} int b = index / ${texelsInBatch}; index -= b * ${texelsInBatch}; // reverse r and c order for packed texture int r = imod(index, ${texelsInLogicalRow}) * 2; int c = 2 * (index / ${texelsInLogicalRow}); return ivec${shape2.length}(${coords}); } `; return new GlslLibRoutine(source); } /** * Unpacked 1D output coordinates. */ getOutputUnpacked1DCoords(_shape, texShape) { const source = ` int getOutputCoords() { ivec2 resTexRC = ivec2(TexCoords.xy * vec2(${texShape[0]}, ${texShape[1]})); return resTexRC.y * ${texShape[0]} + resTexRC.x; } `; return new GlslLibRoutine(source); } /** * Unpacked 2D output coordinates. */ getOutputUnpacked2DCoords(shape2, texShape) { const source = ` ivec2 getOutputCoords() { ivec2 resTexRC = ivec2(TexCoords.xy * vec2(${texShape[0]}, ${texShape[1]})); int index = resTexRC.y * ${texShape[0]} + resTexRC.x; int r = index / ${shape2[1]}; int c = index - r * ${shape2[1]}; return ivec2(r, c); } `; return new GlslLibRoutine(source); } /** * Unpacked 3D output coordinates. */ getOutputUnpacked3DCoords(shape2, texShape) { let source = ""; const rank = shape2.length; let strides = null; if (rank < 2) { strides = []; } strides = new Array(rank - 1); strides[rank - 2] = shape2[rank - 1]; for (let i = rank - 3; i >= 0; --i) { strides[i] = strides[i + 1] * shape2[i + 1]; } const coordsToCompute = ["r", "c", "d"]; const coordsFromIndexSnippet = strides.map((stride, i) => { const line1 = `int ${coordsToCompute[i]} = index / ${stride}`; const line2 = i === strides.length - 1 ? `int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` : `index -= ${coordsToCompute[i]} * ${stride}`; return `${line1}; ${line2};`; }).join(""); source = ` ivec3 getOutputCoords() { ivec2 resTexRC = ivec2(TexCoords.xy * vec2(${texShape[0]}, ${texShape[1]})); int index = resTexRC.y * ${texShape[0]} + resTexRC.x; ${coordsFromIndexSnippet} return ivec3(r, c, d); } `; return new GlslLibRoutine(source); } /** * Unpacked 4D output coordinates. */ getOutputUnpacked4DCoords(shape2, texShape) { let source = ""; const rank = shape2.length; let strides = null; if (rank < 2) { strides = []; } strides = new Array(rank - 1); strides[rank - 2] = shape2[rank - 1]; for (let i = rank - 3; i >= 0; --i) { strides[i] = strides[i + 1] * shape2[i + 1]; } const coordsToCompute = ["r", "c", "d", "d2"]; const coordsFromIndexSnippet = strides.map((stride, i) => { const line1 = `int ${coordsToCompute[i]} = index / ${stride}`; const line2 = i === strides.length - 1 ? `int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` : `index -= ${coordsToCompute[i]} * ${stride}`; return `${line1}; ${line2};`; }).join(""); source = ` ivec4 getOutputCoords() { ivec2 resTexRC = ivec2(TexCoords.xy * vec2(${texShape[0]}, ${texShape[1]})); int index = resTexRC.y * ${texShape[0]} + resTexRC.x; ${coordsFromIndexSnippet} return ivec4(r, c, d, d2); } `; return new GlslLibRoutine(source); } /** * Unpacked 5D output coordinates. */ getOutputUnpacked5DCoords(shape2, texShape) { let source = ""; const rank = shape2.length; let strides = null; if (rank < 2) { strides = []; } strides = new Array(rank - 1); strides[rank - 2] = shape2[rank - 1]; for (let i = rank - 3; i >= 0; --i) { strides[i] = strides[i + 1] * shape2[i + 1]; } const coordsToCompute = ["r", "c", "d", "d2", "d3"]; const coordsFromIndexSnippet = strides.map((stride, i) => { const line1 = `int ${coordsToCompute[i]} = index / ${stride}`; const line2 = i === strides.length - 1 ? `int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` : `index -= ${coordsToCompute[i]} * ${stride}`; return `${line1}; ${line2};`; }).join(""); source = ` ivec5 getOutputCoords() { ivec2 resTexRC = ivec2(TexCoords.xy * vec2(${texShape[0]}, ${texShape[1]})); int index = resTexRC.y * ${texShape[0]} + resTexRC.x; ${coordsFromIndexSnippet} return ivec5(r, c, d, d2, d3); } `; return new GlslLibRoutine(source); } /** * Unpacked 6D output coordinates. */ getOutputUnpacked6DCoords(shape2, texShape) { let source = ""; const rank = shape2.length; let strides = null; if (rank < 2) { strides = []; } strides = new Array(rank - 1); strides[rank - 2] = shape2[rank - 1]; for (let i = rank - 3; i >= 0; --i) { strides[i] = strides[i + 1] * shape2[i + 1]; } const coordsToCompute = ["r", "c", "d", "d2", "d3", "d4"]; const coordsFromIndexSnippet = strides.map((stride, i) => { const line1 = `int ${coordsToCompute[i]} = index / ${stride}`; const line2 = i === strides.length - 1 ? `int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` : `index -= ${coordsToCompute[i]} * ${stride}`; return `${line1}; ${line2};`; }).join(""); source = ` ivec6 getOutputCoords() { ivec2 resTexRC = ivec2(TexCoords.xy * vec2(${texShape[0]}, ${texShape[1]})); int index = resTexRC.y * ${texShape[0]} + resTexRC.x; ${coordsFromIndexSnippet} return ivec6(r, c, d, d2, d3, d4); } `; return new GlslLibRoutine(source); } /** * Generates code for common UV coords computation utility functions. */ getCommonUtilFuncs() { const result = {}; let funcName = "uvFromFlat"; result[funcName] = new GlslLibRoutine(` vec2 uvFromFlat(int texNumR, int texNumC, int index) { int texC = index / texNumR; int texR = index - texC * texNumR; // TODO: swap texR, texC order in following function so row is corresponding to u and column is corresponding to // v. return (vec2(texR, texC) + halfCR) / vec2(texNumR, texNumC); } `); funcName = "packedUVfrom1D"; result[funcName] = new GlslLibRoutine(` vec2 packedUVfrom1D(int texNumR, int texNumC, int index) { int texelIndex = index / 2; int texR = texelIndex / texNumC; int texC = texelIndex - texR * texNumC; return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR); } `); funcName = "packedUVfrom2D"; result[funcName] = new GlslLibRoutine(` vec2 packedUVfrom2D(int texNumR, int texNumC, int texelsInLogicalRow, int row, int col) { int texelIndex = (row / 2) * texelsInLogicalRow + (col / 2); int texR = texelIndex / texNumC; int texC = texelIndex - texR * texNumC; return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR); } `); funcName = "packedUVfrom3D"; result[funcName] = new GlslLibRoutine(` vec2 packedUVfrom3D(int texNumR, int texNumC, int texelsInBatch, int texelsInLogicalRow, int b, int row, int col) { int index = b * texelsInBatch + (row / 2) * texelsInLogicalRow + (col / 2); int texR = index / texNumC; int texC = index - texR * texNumC; return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR); } `); funcName = "sampleTexture"; const glsl = getGlsl(this.context.glContext.version); result[funcName] = new GlslLibRoutine(` float sampleTexture(sampler2D textureSampler, vec2 uv) { return ${glsl.texture2D}(textureSampler, uv).r; }`); return result; } /** * Constructing snippets for inputs */ getInputsSamplingSnippets() { const result = {}; const outputLayout = this.context.outputTextureLayout; this.context.programInfo.inputNames.forEach((samplerName, i) => { const inputLayout = this.context.inputTextureLayouts[i]; const funcName = generateShaderFuncNameFromInputSamplerName(samplerName); if (inputLayout.isPacked) { result[funcName] = this.getPackedSamplerFromInput(funcName, samplerName, inputLayout); } else { result[funcName] = this.getUnpackedSamplerFromInput(funcName, samplerName, inputLayout); } const outCoordFuncName = generateShaderFuncNameFromInputSamplerNameAtOutCoords(samplerName); if (inputLayout.unpackedShape.length <= outputLayout.unpackedShape.length) { if (inputLayout.isPacked) { result[outCoordFuncName] = this.getPackedSamplerAtOutputCoords( outCoordFuncName, inputLayout, outputLayout, samplerName ); } else { result[outCoordFuncName] = this.getUnpackedSamplerAtOutputCoords( outCoordFuncName, inputLayout, outputLayout, samplerName ); } } }); return result; } /** * Constructing snippets for output coordinates of samplers */ getPackedSamplerAtOutputCoords(funcName, inputLayout, outputLayout, name2) { const inShape = inputLayout.unpackedShape; const outShape = outputLayout.unpackedShape; const texName = name2; const texFuncSnippet = generateShaderFuncNameFromInputSamplerName(texName); const inRank = inShape.length; const outRank = outShape.length; const broadcastDims = BroadcastUtil.getBroadcastDims(inShape, outShape); const type = getCoordsDataType(outRank); const rankDiff = outRank - inRank; let coordsSnippet; const fields = getGlChannels(); if (inRank === 0) { coordsSnippet = ""; } else if (outRank < 2 && broadcastDims.length >= 1) { coordsSnippet = "coords = 0;"; } else { coordsSnippet = broadcastDims.map((d) => `coords.${fields[d + rankDiff]} = 0;`).join("\n"); } let unpackedCoordsSnippet = ""; if (outRank < 2 && inRank > 0) { unpackedCoordsSnippet = "coords"; } else { unpackedCoordsSnippet = inShape.map((_s, i) => `coords.${fields[i + rankDiff]}`).join(", "); } let output = "return outputValue;"; const inSize = ShapeUtil.size(inShape); const isInputScalar = inSize === 1; const outSize = ShapeUtil.size(outShape); const isOutputScalar = outSize === 1; if (inRank === 1 && !isInputScalar && !isOutputScalar) { output = ` return vec4(outputValue.xy, outputValue.xy); `; } else if (isInputScalar && !isOutputScalar) { if (outRank === 1) { output = ` return vec4(outputValue.x, outputValue.x, 0., 0.); `; } else { output = ` return vec4(outputValue.x); `; } } else if (broadcastDims.length) { const rows = inRank - 2; const cols = inRank - 1; if (broadcastDims.indexOf(rows) > -1 && broadcastDims.indexOf(cols) > -1) { output = "return vec4(outputValue.x);"; } else if (broadcastDims.indexOf(rows) > -1) { output = "return vec4(outputValue.x, outputValue.y, outputValue.x, outputValue.y);"; } else if (broadcastDims.indexOf(cols) > -1) { output = "return vec4(outputValue.xx, outputValue.zz);"; } } const swapLastDimsSnippet = ` int lastDim = coords.${fields[outRank - 1]}; coords.${fields[outRank - 1]} = coords.${fields[outRank - 2]}; coords.${fields[outRank - 2]} = lastDim; `; const source = ` vec4 ${funcName}() { ${type} coords = getOutputCoords(); ${swapLastDimsSnippet} ${coordsSnippet} vec4 outputValue = ${texFuncSnippet}(${unpackedCoordsSnippet}); ${output} } `; return new GlslLibRoutine(source, ["coordinates.getOutputCoords"]); } /** * Constructing snippets for unpacked output coordinates of samplers */ getUnpackedSamplerAtOutputCoords(funcName, inputLayout, outputLayout, name2) { const outTexShape = [outputLayout.width, outputLayout.height]; const inTexShape = [inputLayout.width, inputLayout.height]; const inRank = inputLayout.unpackedShape.length; const outRank = outputLayout.unpackedShape.length; const inShape = inputLayout.unpackedShape; const outShape = outputLayout.unpackedShape; const texFuncSnippet = generateShaderFuncNameFromInputSamplerName(name2); if (inRank === outRank && ArrayUtil.arraysEqual(inTexShape, outTexShape)) { const source2 = ` float ${funcName}() { return sampleTexture(${name2}, TexCoords); } `; return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); } const type = getCoordsDataType(outRank); const broadcastDims = BroadcastUtil.getBroadcastDims(inShape, outShape); const rankDiff = outRank - inRank; let coordsSnippet; const fields = getGlChannels(); if (inRank === 0) { coordsSnippet = ""; } else if (outRank < 2 && broadcastDims.length >= 1) { coordsSnippet = "coords = 0;"; } else { coordsSnippet = broadcastDims.map((d) => `coords.${fields[d + rankDiff]} = 0;`).join("\n"); } let unpackedCoordsSnippet = ""; if (outRank < 2 && inRank > 0) { unpackedCoordsSnippet = "coords"; } else { unpackedCoordsSnippet = inputLayout.unpackedShape.map((_s, i) => `coords.${fields[i + rankDiff]}`).join(", "); } const source = ` float ${funcName}() { ${type} coords = getOutputCoords(); ${coordsSnippet} return ${texFuncSnippet}(${unpackedCoordsSnippet}); } `; return new GlslLibRoutine(source, ["coordinates.getOutputCoords"]); } /** * Constructing snippets for packed operations. */ getPackedSamplerFromInput(funcName, name2, inputLayout) { switch (inputLayout.unpackedShape.length) { case 0: return this.getPackedSamplerScalar(funcName, name2); case 1: return this.getPackedSampler1D(funcName, name2, inputLayout); case 2: return this.getPackedSampler2D(funcName, name2, inputLayout); case 3: return this.getPackedSampler3D(funcName, name2, inputLayout); default: return this.getPackedSamplerND(funcName, name2, inputLayout); } } /** * Constructing snippets for unpacked operations. */ getUnpackedSamplerFromInput(funcName, name2, inputLayout) { const shape2 = inputLayout.unpackedShape; switch (shape2.length) { case 0: return this.getUnpackedSamplerScalar(funcName, name2, inputLayout); case 1: return this.getUnpackedSampler1D(funcName, name2, inputLayout); case 2: return this.getUnpackedSampler2D(funcName, name2, inputLayout); case 3: return this.getUnpackedSampler3D(funcName, name2, inputLayout); case 4: return this.getUnpackedSampler4D(funcName, name2, inputLayout); case 5: return this.getUnpackedSampler5D(funcName, name2, inputLayout); case 6: return this.getUnpackedSampler6D(funcName, name2, inputLayout); default: throw new Error(`Unsupported dimension ${shape2.length}-D`); } } /** * Packed scalar snippet. */ getPackedSamplerScalar(funcName, name2) { const glsl = getGlsl(this.context.glContext.version); const source = ` vec4 ${funcName}() { return ${glsl.texture2D}(${name2}, halfCR); } `; return new GlslLibRoutine(source); } /** * Packed 1D snippet. */ getPackedSampler1D(funcName, name2, inputLayout) { const texShape = [inputLayout.width, inputLayout.height]; const packedTexShape = [texShape[1], texShape[0]]; const glsl = getGlsl(this.context.glContext.version); const packedSampler = `vec4 ${funcName}(int index) { vec2 uv = packedUVfrom1D( ${packedTexShape[0]}, ${packedTexShape[1]}, index); return ${glsl.texture2D}(${name2}, uv); }`; const source = packedSampler; return new GlslLibRoutine(source, ["coordinates.packedUVfrom1D"]); } /** * Packed 2D snippet. */ getPackedSampler2D(funcName, name2, inputLayout) { const shape2 = inputLayout.unpackedShape; const texShape = [inputLayout.width, inputLayout.height]; const glsl = getGlsl(this.context.glContext.version); const texNumR = texShape[0]; const texNumC = texShape[1]; if (texShape != null && ArrayUtil.arraysEqual(shape2, texShape)) { const packedSampler2 = `vec4 ${funcName}(int row, int col) { vec2 uv = (vec2(col, row) + halfCR) / vec2(${texNumC}.0, ${texNumR}.0); return ${glsl.texture2D}(${name2}, uv); }`; return new GlslLibRoutine(packedSampler2); } const packedTexShape = texShape; const valuesPerRow = Math.ceil(shape2[1] / 2); const packedSampler = `vec4 ${funcName}(int row, int col) { vec2 uv = packedUVfrom2D(${packedTexShape[1]}, ${packedTexShape[0]}, ${valuesPerRow}, row, col); return ${glsl.texture2D}(${name2}, uv); }`; const source = packedSampler; return new GlslLibRoutine(source, ["coordinates.packedUVfrom2D"]); } /** * Packed 3D snippet. */ getPackedSampler3D(funcName, name2, inputLayout) { const shape2 = inputLayout.unpackedShape; const texShape = [inputLayout.width, inputLayout.height]; const packedTexShape = [texShape[0], texShape[1]]; const glsl = getGlsl(this.context.glContext.version); if (shape2[0] === 1) { const squeezedShape = shape2.slice(1); const keptDims = [1, 2]; const newInputShape = squeezeInputShape(shape2, squeezedShape); const params = ["b", "row", "col"]; const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); newInputLayout.unpackedShape = newInputShape; const samplerRoutine = this.getPackedSamplerFromInput(funcName, name2, newInputLayout); const packedSampler2 = `${samplerRoutine.routineBody} vec4 ${funcName}(int b, int row, int col) { return ${funcName}(${getSqueezedParams(params, keptDims)}); } `; const source2 = packedSampler2; return new GlslLibRoutine(source2, samplerRoutine.dependencies); } const texNumR = packedTexShape[0]; const texNumC = packedTexShape[1]; const valuesPerRow = Math.ceil(shape2[2] / 2); const texelsInBatch = valuesPerRow * Math.ceil(shape2[1] / 2); const packedSampler = `vec4 ${funcName}(int b, int row, int col) { vec2 uv = packedUVfrom3D( ${texNumC}, ${texNumR}, ${texelsInBatch}, ${valuesPerRow}, b, row, col); return ${glsl.texture2D}(${name2}, uv);}`; const source = packedSampler; return new GlslLibRoutine(source, ["coordinates.packedUVfrom3D"]); } /* * Packed ND snippet. */ getPackedSamplerND(funcName, name2, inputLayout) { const shape2 = inputLayout.unpackedShape; const rank = shape2.length; const texShape = [inputLayout.width, inputLayout.height]; const glsl = getGlsl(this.context.glContext.version); const packedTexShape = [texShape[0], texShape[1]]; const texNumR = packedTexShape[1]; const texNumC = packedTexShape[0]; const valuesPerRow = Math.ceil(shape2[rank - 1] / 2); let texelsInBatch = valuesPerRow * Math.ceil(shape2[rank - 2] / 2); let params = "int b, int row, int col"; let index = `b * ${texelsInBatch} + (row / 2) * ${valuesPerRow} + (col / 2)`; for (let b = 2; b < rank - 1; b++) { params = `int b${b}, ` + params; texelsInBatch *= shape2[rank - b - 1]; index = `b${b} * ${texelsInBatch} + ` + index; } const packedSampler = `vec4 ${funcName}(${params}) { int index = ${index}; int texR = index / ${texNumC}; int texC = index - texR * ${texNumC}; vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${texNumC}, ${texNumR}); return ${glsl.texture2D}(${name2}, uv); }`; const source = packedSampler; return new GlslLibRoutine(source); } /** * Unpacked scalar snippet. */ getUnpackedSamplerScalar(funcName, name2, inputLayout) { const [texNumR, texNumC] = [inputLayout.width, inputLayout.height]; if (texNumR === 1 && texNumC === 1) { const source2 = ` float ${funcName}() { return sampleTexture(${name2}, halfCR); } `; return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); } const source = ` float ${funcName}() { int offset_${name2} = coordsToOffset(TexCoords, ${texNumR}, ${texNumC}); vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, offset_${name2}); return sampleTexture(${name2}, uv); } `; return new GlslLibRoutine(source, [ "coordinates.uvFromFlat", "coordinates.sampleTexture", "coordinates.coordsToOffset" ]); } /** * Unpacked 1D snippet. */ getUnpackedSampler1D(funcName, name2, inputLayout) { const tNumR = inputLayout.width; const tNumC = inputLayout.height; if (tNumC === 1 && tNumR === 1) { const source2 = ` float ${funcName}(int index) { return sampleTexture(${name2}, halfCR); } `; return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); } if (tNumC === 1) { const source2 = ` float ${funcName}(int index) { vec2 uv = vec2((float(index) + 0.5) / ${tNumR}.0, 0.5); return sampleTexture(${name2}, uv); } `; return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); } if (tNumR === 1) { const source2 = ` float ${funcName}(int index) { vec2 uv = vec2(0.5, (float(index) + 0.5) / ${tNumC}.0); return sampleTexture(${name2}, uv); } `; return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); } const source = ` float ${funcName}(int index) { vec2 uv = uvFromFlat(${tNumR}, ${tNumC}, index); return sampleTexture(${name2}, uv); } `; return new GlslLibRoutine(source, ["coordinates.uvFromFlat", "coordinates.sampleTexture"]); } /** * Unpacked 2D snippet. */ getUnpackedSampler2D(funcName, name2, inputLayout) { const shape2 = inputLayout.unpackedShape; const texShape = [inputLayout.height, inputLayout.width]; if (texShape != null && ArrayUtil.arraysEqual(shape2, texShape)) { const texNumR2 = texShape[1]; const texNumC2 = texShape[0]; const source2 = ` float ${funcName}(int row, int col) { vec2 uv = (vec2(row, col) + halfCR) / vec2(${texNumR2}.0, ${texNumC2}.0); return sampleTexture(${name2}, uv); } `; return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); } const { newShape, keptDims } = squeezeShape(shape2); const squeezedShape = newShape; if (squeezedShape.length < shape2.length) { const newInputShape = squeezeInputShape(shape2, squeezedShape); const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); newInputLayout.unpackedShape = newInputShape; const params = ["col", "row"]; const source2 = ` ${this.getUnpackedSamplerFromInput(funcName, name2, newInputLayout).routineBody} float ${funcName}(int row, int col) { return ${funcName}(${getSqueezedParams(params, keptDims)}); } `; return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); } const texNumR = texShape[1]; const texNumC = texShape[0]; if (texNumC === 1) { const source2 = ` float ${funcName}(int row, int col) { int offset_${name2} = coordsToOffset(TexCoords, ${texNumR}, ${texNumC}); float index = dot(vec3(row, col, offset_${name2}), vec3(${shape2[1]}, 1, 1)); vec2 uv = vec2(0.5, (index + 0.5) / ${texNumR}.0); return sampleTexture(${name2}, uv); } `; return new GlslLibRoutine(source2, ["coordinates.sampleTexture", "coordinates.coordsToOffset"]); } if (texNumR === 1) { const source2 = ` float ${funcName}(int row, int col) { int offset_${name2} = coordsToOffset(TexCoords, ${texNumR}, ${texNumC}); float index = dot(vec3(row, col, offset_${name2}), vec3(${shape2[1]}, 1, 1)); vec2 uv = vec2((index + 0.5) / ${texNumC}.0, 0.5); return sampleTexture(${name2}, uv); } `; return new GlslLibRoutine(source2, ["coordinates.sampleTexture", "coordinates.coordsToOffset"]); } const source = ` float ${funcName}(int row, int col) { int index = col * ${shape2[1]} + row; vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); return sampleTexture(${name2}, uv); } `; return new GlslLibRoutine(source, [ "coordinates.uvFromFlat", "coordinates.sampleTexture", "coordinates.coordsToOffset" ]); } /** * Unpacked 3D snippet. */ getUnpackedSampler3D(funcName, name2, inputLayout) { const shape2 = inputLayout.unpackedShape; const stride0 = shape2[1] * shape2[2]; const stride1 = shape2[2]; const { newShape, keptDims } = squeezeShape(shape2); const squeezedShape = newShape; if (squeezedShape.length < shape2.length) { const newInputShape = squeezeInputShape(shape2, squeezedShape); const params = ["batch", "col", "row"]; const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); newInputLayout.unpackedShape = newInputShape; const routine = this.getUnpackedSamplerFromInput(funcName, name2, newInputLayout); const revDims = keptDims.reverse(); const source2 = ` ${routine.routineBody} float ${funcName}(int batch, int row, int col) { return ${funcName}(${getSqueezedParams(params, revDims)}); } `; return new GlslLibRoutine(source2, routine.dependencies); } const texNumR = inputLayout.width; const texNumC = inputLayout.height; const source = ` float ${funcName}(int depth, int row, int col) { // Explicitly use integer operations as dot() only works on floats. int index = depth * ${stride0} + col * ${stride1} + row; vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); return sampleTexture(${name2}, uv); } `; return new GlslLibRoutine(source, [ "coordinates.uvFromFlat", "coordinates.sampleTexture", "coordinates.coordsToOffset" ]); } /** * Unpacked 4D snippet. */ getUnpackedSampler4D(funcName, name2, inputLayout) { const shape2 = inputLayout.unpackedShape; const stride2 = shape2[3]; const stride1 = shape2[2] * stride2; const stride0 = shape2[1] * stride1; const texNumR = inputLayout.width; const texNumC = inputLayout.height; const source = ` float ${funcName}(int row, int col, int depth, int depth2) { int index = row * ${stride0} + col * ${stride1} + depth2 * ${stride2} + depth; vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); return sampleTexture(${name2}, uv); } `; return new GlslLibRoutine(source, ["coordinates.uvFromFlat", "coordinates.sampleTexture"]); } /** * Unpacked 5D snippet. */ getUnpackedSampler5D(funcName, name2, inputLayout) { const shape2 = inputLayout.unpackedShape; const stride3 = shape2[4]; const stride2 = shape2[3] * stride3; const stride1 = shape2[2] * stride2; const stride0 = shape2[1] * stride1; const { newShape, keptDims } = squeezeShape(shape2); if (newShape.length < shape2.length) { const newInputShape = squeezeInputShape(shape2, newShape); const params = ["row", "col", "depth", "depth2", "depth3"]; const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); newInputLayout.unpackedShape = newInputShape; const source2 = ` ${this.getUnpackedSamplerFromInput(funcName, name2, newInputLayout).routineBody} float ${funcName}(int row, int col, int depth, int depth2, int depth3) { return ${funcName}(${getSqueezedParams(params, keptDims)}); } `; return new GlslLibRoutine(source2, ["coordinates.sampleTexture", "coordinates.uvFromFlat"]); } const texNumR = inputLayout.width; const texNumC = inputLayout.height; const source = ` float ${funcName}(int row, int col, int depth, int depth2, int depth3) { int index = row * ${stride0} + col * ${stride1} + depth * ${stride2} + depth3 * ${stride3} + depth2; vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); return sampleTexture(${name2}, uv); } `; return new GlslLibRoutine(source, ["coordinates.sampleTexture", "coordinates.uvFromFlat"]); } /** * Unpacked 6D snippet. */ getUnpackedSampler6D(funcName, name2, inputLayout) { const shape2 = inputLayout.unpackedShape; const stride4 = shape2[5]; const stride3 = shape2[4] * stride4; const stride2 = shape2[3] * stride3; const stride1 = shape2[2] * stride2; const stride0 = shape2[1] * stride1; const { newShape, keptDims } = squeezeShape(shape2); if (newShape.length < shape2.length) { const newInputShape = squeezeInputShape(shape2, newShape); const params = ["row", "col", "depth", "depth2", "depth3", "depth4"]; const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); newInputLayout.unpackedShape = newInputShape; const source2 = ` ${this.getUnpackedSamplerFromInput(funcName, name2, newInputLayout).routineBody} float ${funcName}(int row, int col, int depth, int depth2, int depth3, int depth4) { return ${funcName}(${getSqueezedParams(params, keptDims)}); } `; return new GlslLibRoutine(source2, ["coordinates.sampleTexture", "coordinates.uvFromFlat"]); } const texNumR = inputLayout.width; const texNumC = inputLayout.height; const source = ` float ${funcName}(int row, int col, int depth, int depth2, int depth3, int depth4) { int index = row * ${stride0} + col * ${stride1} + depth * ${stride2} + depth2 * ${stride3} + depth3 * ${stride4} + depth4; vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); return sampleTexture(${name2}, uv); } `; return new GlslLibRoutine(source, [ "coordinates.uvFromFlat", "coordinates.sampleTexture", "coordinates.coordsToOffset" ]); } /** * This is the main function to map from the given texture coordinates (s,t) * to logical indices for the output * There will only be one single variation of this * Also see coordsToOffset and offsetToIndices for input-specific versions */ toVec() { const output = this.context.outputTextureLayout; const rank = output.shape.length; const strides = output.strides; const xScale = output.width; const yScale = output.height; const stridesBlock = []; for (let i = 0; i < rank - 1; ++i) { stridesBlock.push(` c[${i}] = offset / ${strides[i]};`); stridesBlock.push(` offset -= c[${i}] * ${strides[i]};`); } stridesBlock.push(` c[${rank - 1}] = offset;`); const body = ` void toVec(vec2 texCoords, out int c[${rank}]) { int offset = coordsToOffset(texCoords, ${xScale}, ${yScale}); ${stridesBlock.join("")} } void toVec(int offset, out int c[${rank}]) { ${stridesBlock.join("")} } `; return { toVec: new GlslLibRoutine(body, ["coordinates.coordsToOffset"]) }; } /** * These are value getter functions generated for each input * Each function is hardwired to the name and dimensions of the input * An '_T' variation is also produced which accesses values as if the * input was transposed */ valueFrom() { const result = {}; this.context.programInfo.inputNames.forEach((name2, i) => { const layout = this.context.inputTextureLayouts[i]; const shape2 = layout.unpackedShape.length > 0 ? layout.unpackedShape : layout.shape; const rank = shape2.length; let funcName = `_${name2}`; result[funcName] = new GlslLibRoutine(this.getValueFromSingle(name2, rank, layout.width, layout.height, false), [ `shapeUtils.indicesToOffset${funcName}`, "coordinates.offsetToCoords", "fragcolor.getColorAsFloat" ]); funcName = funcName + "_T"; result[funcName] = new GlslLibRoutine(this.getValueFromSingle(name2, rank, layout.width, layout.height, true), [ `shapeUtils.indicesToOffset${funcName}`, "coordinates.offsetToCoords", "fragcolor.getColorAsFloat" ]); }); return result; } /** * Produces one value getter function for the name and rank given * If a transpose is set proper offsetToCoords mapping will be used * @param name name of the function * @param rank rank of the input * @param transpose whether or not should generate a transpose variation */ getValueFromSingle(varName, rank, width, height, transpose2) { let name2 = `_${varName}`; if (transpose2) { name2 = name2 + "_T"; } const glsl = getGlsl(this.context.glContext.version); return ` float ${name2}(int m[${rank}]) { int offset = indicesToOffset${name2}(m); vec2 coords = offsetToCoords(offset, ${width}, ${height}); float value = getColorAsFloat(${glsl.texture2D}(${varName}, coords)); return value; } `; } /** * Produces a packed value getter function for the name and rank given * If a transpose is set proper offsetToCoords mapping will be used * @param name name of the function * @param rank rank of the input * @param transpose whether or not should generate a transpose variation */ getPackedValueFrom(varName, rank, width, height, transpose2) { let name2 = `_${varName}_Pack`; if (transpose2) { name2 = name2 + "_T"; } const glsl = getGlsl(this.context.glContext.version); return ` vec4 ${name2}(int m[${rank}]) { int offset = indicesToOffset_${varName}(m); vec2 coords = offsetToCoords(offset, ${width}, ${height}); return ${glsl.texture2D}(${varName}, coords); } `; } }; } }); // web/lib/onnxjs/backends/webgl/glsl-encoding-lib.ts var EncodingGlslLib; var init_glsl_encoding_lib = __esm({ "web/lib/onnxjs/backends/webgl/glsl-encoding-lib.ts"() { "use strict"; init_glsl_definitions(); EncodingGlslLib = class _EncodingGlslLib extends GlslLib { constructor(context) { super(context); } getFunctions() { return { ...this.encodeFloat32(), ...this.decodeFloat32() }; } getCustomTypes() { return {}; } encodeFloat32() { return { encode: new GlslLibRoutine(`highp vec4 encode(highp float f) { return vec4(f, 0.0, 0.0, 0.0); } `) }; } decodeFloat32() { return { decode: new GlslLibRoutine(`highp float decode(highp vec4 rgba) { return rgba.r; } `) }; } /** * returns the routine to encode encode a 32bit float to a vec4 (of unsigned bytes) * @credit: https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float */ encodeUint8() { const endianness = _EncodingGlslLib.isLittleEndian() ? "rgba.rgba=rgba.abgr;" : ""; return { encode: new GlslLibRoutine(` highp vec4 encode(highp float f) { highp float F = abs(f); highp float Sign = step(0.0,-f); highp float Exponent = floor(log2(F)); highp float Mantissa = (exp2(- Exponent) * F); Exponent = floor(log2(F) + 127.0) + floor(log2(Mantissa)); highp vec4 rgba; rgba[0] = 128.0 * Sign + floor(Exponent*exp2(-1.0)); rgba[1] = 128.0 * mod(Exponent,2.0) + mod(floor(Mantissa*128.0),128.0); rgba[2] = floor(mod(floor(Mantissa*exp2(23.0 -8.0)),exp2(8.0))); rgba[3] = floor(exp2(23.0)*mod(Mantissa,exp2(-15.0))); ${endianness} rgba = rgba / 255.0; // values need to be normalized to [0,1] return rgba; } `) }; } /** * returns the routine to encode a vec4 of unsigned bytes to float32 * @credit: https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float */ decodeUint8() { const endianness = _EncodingGlslLib.isLittleEndian() ? "rgba.rgba=rgba.abgr;" : ""; return { decode: new GlslLibRoutine(` highp float decode(highp vec4 rgba) { rgba = rgba * 255.0; // values need to be de-normalized from [0,1] to [0,255] ${endianness} highp float Sign = 1.0 - step(128.0,rgba[0])*2.0; highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0; highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000); highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 )); return Result; } `) }; } /** * Determines if the machine is little endian or not * @credit: https://gist.github.com/TooTallNate/4750953 */ static isLittleEndian() { const b = new ArrayBuffer(4); const a = new Uint32Array(b); const c = new Uint8Array(b); a[0] = 3735928559; if (c[0] === 239) { return true; } if (c[0] === 222) { return false; } throw new Error("unknown endianness"); } }; } }); // web/lib/onnxjs/backends/webgl/glsl-fragcolor-lib.ts var FragColorGlslLib; var init_glsl_fragcolor_lib = __esm({ "web/lib/onnxjs/backends/webgl/glsl-fragcolor-lib.ts"() { "use strict"; init_glsl_definitions(); init_glsl_source(); FragColorGlslLib = class extends GlslLib { constructor(context) { super(context); } getFunctions() { return { ...this.setFragColor(), ...this.getColorAsFloat() }; } getCustomTypes() { return {}; } setFragColor() { const glsl = getGlsl(this.context.glContext.version); return { setFragColor: new GlslLibRoutine( ` void setFragColor(float value) { ${glsl.output} = encode(value); } `, ["encoding.encode"] ) }; } getColorAsFloat() { return { getColorAsFloat: new GlslLibRoutine( ` float getColorAsFloat(vec4 color) { return decode(color); } `, ["encoding.decode"] ) }; } }; } }); // web/lib/onnxjs/backends/webgl/glsl-shape-utils-lib.ts var ShapeUtilsGlslLib; var init_glsl_shape_utils_lib = __esm({ "web/lib/onnxjs/backends/webgl/glsl-shape-utils-lib.ts"() { "use strict"; init_glsl_definitions(); ShapeUtilsGlslLib = class _ShapeUtilsGlslLib extends GlslLib { constructor(context) { super(context); } getFunctions() { return { ...this.bcastIndex(), ...this.bcastMatmulIndex(), ...this.offsetToIndices(), ...this.indicesToOffset(), ...this.incrementIndices() }; } getCustomTypes() { return {}; } bcastIndex() { const outputRank = this.context.outputTextureLayout.shape.length; const result = {}; this.context.programInfo.inputNames.forEach((name2, i) => { const shape2 = this.context.inputTextureLayouts[i].unpackedShape; if (shape2.length <= outputRank) { const rank = shape2.length; const dimOffset = outputRank - rank; const funcName = `bcastIndices_${name2}`; let block = ""; for (let i2 = 0; i2 < rank; ++i2) { block += ` realIndices[${i2}] = int( mod(float(bcastedIndices[${dimOffset + i2}]), ${shape2[i2]}.0) ); `; } const body = ` void ${funcName} (int bcastedIndices[${outputRank}], out int realIndices[${rank}]) { ${block} } `; result[funcName] = new GlslLibRoutine(body); } }); return result; } bcastMatmulIndex() { const outputRank = this.context.outputTextureLayout.shape.length; const result = {}; this.context.programInfo.inputNames.forEach((name2, i) => { const shape2 = this.context.inputTextureLayouts[i].shape; if (!(shape2.length < 2 || shape2.length > outputRank)) { const rank = shape2.length; const dimOffset = outputRank - rank; const funcName = `bcastMatmulIndices_${name2}`; let block = ""; for (let i2 = 0; i2 < rank - 2; ++i2) { block += ` realIndices[${i2}] = int( mod(float(bcastedIndices[${dimOffset + i2}]), ${shape2[i2]}.0) ); `; } const body = ` void ${funcName}(int bcastedIndices[${outputRank}], out int realIndices[${rank}]) { ${block} realIndices[${rank - 1}] = bcastedIndices[${outputRank - 1}]; realIndices[${rank - 2}] = bcastedIndices[${outputRank - 2}]; } `; result[funcName] = new GlslLibRoutine(body); } }); return result; } indicesToOffset() { const result = {}; this.context.programInfo.inputNames.forEach((name2, i) => { const shape2 = this.context.inputTextureLayouts[i].shape; const strides = this.context.inputTextureLayouts[i].strides; const rank = shape2.length; let funcName = `indicesToOffset_${name2}`; result[funcName] = new GlslLibRoutine(_ShapeUtilsGlslLib.indexToOffsetSingle(funcName, rank, strides)); funcName = `indicesToOffset_${name2}_T`; result[funcName] = new GlslLibRoutine( _ShapeUtilsGlslLib.indexToOffsetSingle(funcName, rank, strides.slice().reverse()) ); }); return result; } static indexToOffsetSingle(name2, rank, strides) { let block = ""; for (let i = rank - 1; i >= 0; --i) { block += ` offset += indices[${i}] * ${strides[i]}; `; } return ` int ${name2}(int indices[${rank}]) { int offset = 0; ${block} return offset; } `; } offsetToIndices() { const result = {}; this.context.programInfo.inputNames.forEach((name2, i) => { const shape2 = this.context.inputTextureLayouts[i].shape; const strides = this.context.inputTextureLayouts[i].strides; const rank = shape2.length; let funcName = `offsetToIndices_${name2}`; result[funcName] = new GlslLibRoutine(_ShapeUtilsGlslLib.offsetToIndicesSingle(funcName, rank, strides)); funcName = `offsetToIndices_${name2}_T`; result[funcName] = new GlslLibRoutine( _ShapeUtilsGlslLib.offsetToIndicesSingle(funcName, rank, strides.slice().reverse()) ); }); return result; } static offsetToIndicesSingle(name2, rank, strides) { const stridesBlock = []; for (let i = 0; i < rank - 1; ++i) { stridesBlock.push(` indices[${i}] = offset / ${strides[i]};`); stridesBlock.push(` offset -= indices[${i}] * ${strides[i]};`); } stridesBlock.push(` indices[${rank - 1}] = offset;`); return ` void ${name2}(int offset, out int indices[${rank}]) { ${stridesBlock.join("")} } `; } incrementIndices() { const result = {}; this.context.programInfo.inputNames.forEach((name2, i) => { const shape2 = this.context.inputTextureLayouts[i].shape; const rank = shape2.length; const funcName = `incrementIndices_${name2}`; let shapeInit = ""; for (let i2 = 0; i2 < rank; ++i2) { shapeInit += ` shape[${i2}] = ${shape2[i2]};`; } const body = ` void ${funcName}(int axis, out int indices[${rank}]) { int shape[${rank}]; ${shapeInit}; for(int i = ${rank} -1 ; i >= 0; --i) { if(i > axis) continue; indices[i] += 1; if(indices[i] < shape[i]) { break; } indices[i] = 0; } } `; result[funcName] = new GlslLibRoutine(body); }); return result; } }; } }); // web/lib/onnxjs/backends/webgl/glsl-vec-lib.ts var VecGlslLib; var init_glsl_vec_lib = __esm({ "web/lib/onnxjs/backends/webgl/glsl-vec-lib.ts"() { "use strict"; init_glsl_definitions(); VecGlslLib = class extends GlslLib { constructor(context) { super(context); } getCustomTypes() { return {}; } getFunctions() { return { ...this.binaryVecFunctions(), ...this.copyVec(), ...this.setVecItem(), ...this.getVecItem() }; } binaryVecFunctions() { const outputLayout = this.context.outputTextureLayout; const rank = outputLayout.shape.length; const nameOp = { add: "+=", sub: "-=", mul: "*=", div: "/=" }; const result = {}; for (const name2 in nameOp) { const fname = `${name2}Vec`; let assignmentBlock = ""; for (let i = 0; i < rank; ++i) { assignmentBlock += ` dest[${i}] ${nameOp[name2]} src[${i}]; `; } const body = ` void ${fname}(int src[${rank}], out int dest[${rank}]) { ${assignmentBlock} } `; result[fname] = new GlslLibRoutine(body); } return result; } copyVec() { const outputLayout = this.context.outputTextureLayout; const rank = outputLayout.shape.length; let assignmentBlock = ""; for (let i = 0; i < rank; ++i) { assignmentBlock += ` dest[${i}] = src[${i}]; `; } const body = ` void copyVec(int src[${rank}], out int dest[${rank}]) { ${assignmentBlock} } `; return { copyVec: new GlslLibRoutine(body) }; } setVecItem() { const outputLayout = this.context.outputTextureLayout; const rank = outputLayout.shape.length; let block = ` if(index < 0) index =${rank} + index; if (index == 0) m[0] = value; `; for (let i = 1; i < rank - 1; ++i) { block += ` else if (index == ${i}) m[${i}] = value; `; } block += ` else m[${rank - 1}] = value; `; const body = ` void setVecItem(out int m[${rank}], int index, int value) { ${block} } `; return { setVecItem: new GlslLibRoutine(body) }; } getVecItem() { const outputLayout = this.context.outputTextureLayout; const rank = outputLayout.shape.length; let block = ` if(index < 0) index = ${rank} + index; if (index == 0) return m[0]; `; for (let i = 1; i < rank - 1; ++i) { block += ` else if (index == ${i}) return m[${i}]; `; } block += ` else return m[${rank - 1}]; `; const body = ` int getVecItem(int m[${rank}], int index) { ${block} } `; return { getVecItem: new GlslLibRoutine(body) }; } }; } }); // web/lib/onnxjs/backends/webgl/glsl-registered-libs.ts var glslRegistry; var init_glsl_registered_libs = __esm({ "web/lib/onnxjs/backends/webgl/glsl-registered-libs.ts"() { "use strict"; init_glsl_coordinate_lib(); init_glsl_encoding_lib(); init_glsl_fragcolor_lib(); init_glsl_shape_utils_lib(); init_glsl_vec_lib(); glslRegistry = { encoding: EncodingGlslLib, fragcolor: FragColorGlslLib, vec: VecGlslLib, shapeUtils: ShapeUtilsGlslLib, coordinates: CoordsGlslLib // 'arrays': ArrayGlslSLib }; } }); // web/lib/onnxjs/backends/webgl/glsl-preprocessor.ts var GlslPreprocessor; var init_glsl_preprocessor = __esm({ "web/lib/onnxjs/backends/webgl/glsl-preprocessor.ts"() { "use strict"; init_glsl_definitions(); init_glsl_function_inliner(); init_glsl_registered_libs(); init_glsl_source(); GlslPreprocessor = class { constructor(glContext, programInfo, inputTextureLayouts, outputTextureLayout) { this.libs = {}; this.glslLibRoutineDependencyGraph = {}; this.context = new GlslContext(glContext, programInfo, inputTextureLayouts, outputTextureLayout); Object.keys(glslRegistry).forEach((name2) => { const lib = new glslRegistry[name2](this.context); this.libs[name2] = lib; }); const map = this.glslLibRoutineDependencyGraph; for (const libName in this.libs) { const lib = this.libs[libName]; const routinesInLib = lib.getFunctions(); for (const routine in routinesInLib) { const key = libName + "." + routine; let currentNode; if (map[key]) { currentNode = map[key]; currentNode.routineBody = routinesInLib[routine].routineBody; } else { currentNode = new GlslLibRoutineNode(key, routinesInLib[routine].routineBody); map[key] = currentNode; } const dependencies = routinesInLib[routine].dependencies; if (dependencies) { for (let i = 0; i < dependencies.length; ++i) { if (!map[dependencies[i]]) { const node = new GlslLibRoutineNode(dependencies[i]); map[dependencies[i]] = node; currentNode.addDependency(node); } else { currentNode.addDependency(map[dependencies[i]]); } } } } } } preprocess() { const programInfo = this.context.programInfo; let source = programInfo.shaderSource; if (!this.context.programInfo.hasMain) { source = `${source} ${getDefaultFragShaderMain(this.context.glContext.version, this.context.outputTextureLayout.shape.length)}`; } source = replaceInlines(source); return `${getFragShaderPreamble(this.context.glContext.version)} ${this.getUniforms(programInfo.inputNames, programInfo.variables)} ${this.getImports(source)} ${source}`; } getImports(script) { const routinesIncluded = this.selectGlslLibRoutinesToBeIncluded(script); if (routinesIncluded.length === 0) { return ""; } let routines = ""; for (let i = 0; i < routinesIncluded.length; ++i) { if (routinesIncluded[i].routineBody) { routines += routinesIncluded[i].routineBody + "\n"; } else { throw new Error(`Missing body for the Glsl Library routine: ${routinesIncluded[i].name}`); } } return routines; } selectGlslLibRoutinesToBeIncluded(script) { const nodes = []; Object.keys(this.glslLibRoutineDependencyGraph).forEach((classAndRoutine) => { const routine = classAndRoutine.split(".")[1]; if (script.indexOf(routine) !== -1) { nodes.push(this.glslLibRoutineDependencyGraph[classAndRoutine]); } }); return TopologicalSortGlslRoutines.returnOrderedNodes(nodes); } getUniforms(samplers, variables) { const uniformLines = []; if (samplers) { for (const sampler of samplers) { uniformLines.push(`uniform sampler2D ${sampler};`); } } if (variables) { for (const variable of variables) { uniformLines.push( `uniform ${variable.type} ${variable.name}${variable.arrayLength ? `[${variable.arrayLength}]` : ""};` ); } } return uniformLines.join("\n"); } }; } }); // web/lib/onnxjs/backends/webgl/program-manager.ts var ProgramManager; var init_program_manager = __esm({ "web/lib/onnxjs/backends/webgl/program-manager.ts"() { "use strict"; init_esm(); init_instrument(); init_glsl_preprocessor(); init_glsl_source(); ProgramManager = class { constructor(profiler, glContext, textureLayoutStrategy) { this.profiler = profiler; this.glContext = glContext; this.textureLayoutStrategy = textureLayoutStrategy; this.repo = /* @__PURE__ */ new Map(); this.attributesBound = false; } getArtifact(key) { return this.repo.get(key); } setArtifact(key, artifact) { this.repo.set(key, artifact); } run(buildArtifact, inputs, output) { this.profiler.event( "op", `ProgramManager.run ${buildArtifact.programInfo.name ?? "unknown kernel"}`, () => { const gl = this.glContext.gl; const program = buildArtifact.program; gl.useProgram(program); try { this.bindOutput(output); if (!this.attributesBound) { this.bindAttributes(buildArtifact.attribLocations); } this.bindUniforms(buildArtifact.uniformLocations, buildArtifact.programInfo.variables ?? [], inputs); } catch (err) { Logger.error("ProgramManager", buildArtifact.programInfo.shaderSource); throw err; } this.profiler.event("backend", "GlContext.draw()", () => { this.glContext.draw(); }); }, this.glContext ); } dispose() { if (this.vertexShader) { this.glContext.deleteShader(this.vertexShader); } this.repo.forEach((a) => this.glContext.deleteProgram(a.program)); } build(programInfo, inputTextureLayouts, outputTextureLayout) { return this.profiler.event("backend", "ProgramManager.build", () => { const preprocessor = new GlslPreprocessor(this.glContext, programInfo, inputTextureLayouts, outputTextureLayout); const fragScript = preprocessor.preprocess(); const program = this.compile(fragScript); const artifact = { programInfo, program, uniformLocations: this.getUniformLocations( program, preprocessor.context.programInfo.inputNames, preprocessor.context.programInfo.variables ), attribLocations: this.getAttribLocations(program) }; return artifact; }); } compile(fragShaderScript) { if (!this.vertexShader) { Logger.verbose("ProrgramManager", "Compiling and caching Vertex shader for the first time"); const vertexShaderScript = getVertexShaderSource(this.glContext.version); this.vertexShader = this.glContext.compileShader(vertexShaderScript, this.glContext.gl.VERTEX_SHADER); } if (env2.debug) { Logger.verbose( "ProrgramManager", `FragShader: ${fragShaderScript} ` ); } const fragShader = this.glContext.compileShader(fragShaderScript, this.glContext.gl.FRAGMENT_SHADER); const program = this.glContext.createProgram(this.vertexShader, fragShader); this.glContext.deleteShader(fragShader); return program; } bindOutput(td) { const width = td.width; const height = td.height; Logger.verbose( "ProrgramManager", `Binding output texture to Framebuffer: w/h=${width}/${height}, shape=${td.shape}, type=${td.tensor.type}` ); this.glContext.attachFramebuffer(td.texture, width, height); } bindAttributes(attribLocations) { const positionHandle = attribLocations.position; const textureCoordHandle = attribLocations.textureCoord; this.glContext.setVertexAttributes(positionHandle, textureCoordHandle); this.attributesBound = true; } bindUniforms(uniformLocations, variables, textures) { const gl = this.glContext.gl; let texturePosition = 0; for (const { name: name2, type, location, arrayLength } of uniformLocations) { const value = variables.find((v) => v.name === name2)?.data; if (type !== "sampler2D" && !value) { throw new Error(`variable '${name2}' does not have data defined in program info`); } switch (type) { case "sampler2D": this.bindTexture(textures[texturePosition], location, texturePosition); texturePosition++; break; case "float": if (arrayLength) { gl.uniform1fv(location, value); } else { gl.uniform1f(location, value); } break; case "int": if (arrayLength) { gl.uniform1iv(location, value); } else { gl.uniform1i(location, value); } break; default: throw new Error(`Uniform not implemented: ${type}`); } } } bindTexture(td, uniformHandle, position) { this.glContext.bindTextureToUniform(td.texture, position, uniformHandle); } getAttribLocations(program) { return { position: this.getAttribLocation(program, "position"), textureCoord: this.getAttribLocation(program, "textureCoord") }; } getUniformLocations(program, samplers, variables) { const uniformLocations = []; if (samplers) { for (const sampler of samplers) { uniformLocations.push({ name: sampler, type: "sampler2D", location: this.getUniformLocation(program, sampler) }); } } if (variables) { for (const variable of variables) { uniformLocations.push({ ...variable, location: this.getUniformLocation(program, variable.name) }); } } return uniformLocations; } getUniformLocation(program, name2) { const gl = this.glContext.gl; const reference = gl.getUniformLocation(program, name2); if (reference === null) { throw new Error(`Uniform ${name2} not found.`); } return reference; } getAttribLocation(program, name2) { const gl = this.glContext.gl; const attributeLocation = gl.getAttribLocation(program, name2); return attributeLocation; } }; } }); // web/lib/onnxjs/backends/webgl/texture-manager.ts var TextureManager; var init_texture_manager = __esm({ "web/lib/onnxjs/backends/webgl/texture-manager.ts"() { "use strict"; init_instrument(); init_texture_data_encoder(); TextureManager = class { constructor(glContext, layoutStrategy, profiler, config) { this.glContext = glContext; this.layoutStrategy = layoutStrategy; this.profiler = profiler; this.config = config; this.pendingRead = /* @__PURE__ */ new Map(); if (config.reuseTextures) { this.inUseTextures = /* @__PURE__ */ new Map(); this.idleTextures = /* @__PURE__ */ new Map(); this.textureLookup = /* @__PURE__ */ new Map(); } } createTextureFromLayout(dataType, layout, data, usage) { const textureDataType = this.toEncoderType(dataType); const encoder = this.glContext.getEncoder(textureDataType, layout.channels || 1, usage); if (layout.isPacked && usage === 1 /* UploadOnly */) { throw new Error("not implemented"); } const width = layout.width; const height = layout.height; let key; let inUseTextures; if (this.config.reuseTextures) { key = `${width}x${height}_${encoder.format}_${encoder.internalFormat}_${encoder.textureType}`; inUseTextures = this.inUseTextures.get(key); if (!inUseTextures) { inUseTextures = []; this.inUseTextures.set(key, inUseTextures); } const idleTextures = this.idleTextures.get(key); if (idleTextures && idleTextures.length > 0) { const texture2 = idleTextures.pop(); inUseTextures.push(texture2); if (usage === 1 /* UploadOnly */) { this.glContext.updateTexture(texture2, width, height, encoder, this.toTextureData(dataType, data)); } return texture2; } } Logger.verbose("TextureManager", `Creating new texture of size ${layout.width}x${layout.height}`); const texture = this.glContext.allocateTexture(width, height, encoder, this.toTextureData(dataType, data)); if (this.config.reuseTextures) { inUseTextures.push(texture); this.textureLookup.set(texture, key); } return texture; } readTexture(td, dataType, channels) { if (!channels) { channels = 1; } return this.profiler.event("backend", "TextureManager.readTexture", () => { const dataSize = td.shape.reduce((a, b) => a * b) * channels; const data = this.glContext.readTexture( td.texture, td.width, td.height, dataSize, this.toEncoderType(dataType), channels ); return this.toTensorData(dataType, data); }); } async readTextureAsync(td, dataType, channels) { const dataId = td.tensor.dataId; if (!channels) { channels = 1; } if (this.pendingRead.has(dataId)) { const subscribers = this.pendingRead.get(dataId); return new Promise((resolve) => subscribers?.push(resolve)); } return this.profiler.event("backend", "TextureManager.readTextureAsync", async () => { this.pendingRead.set(dataId, []); const dataSize = td.shape.reduce((a, b) => a * b) * channels; await this.glContext.createAndWaitForFence(); const data = this.glContext.readTexture( td.texture, td.width, td.height, dataSize, this.toEncoderType(dataType), channels ); const tensorData = this.toTensorData(dataType, data); const subscribers = this.pendingRead.get(dataId); this.pendingRead.delete(dataId); subscribers?.forEach((resolve) => resolve(tensorData)); return tensorData; }); } readUint8TextureAsFloat(td) { return this.profiler.event("backend", "TextureManager.readUint8TextureAsFloat", () => { const dataSize = td.shape.reduce((a, b) => a * b); const data = this.glContext.readTexture(td.texture, td.width, td.height, dataSize * 4, "byte", 4); return new Float32Array(data.buffer, data.byteOffset, dataSize); }); } releaseTexture(textureData, deleteTexture) { let key; if (this.config.reuseTextures) { key = this.textureLookup.get(textureData.texture); if (key) { if (deleteTexture) { this.textureLookup.delete(key); } const inUseTextures = this.inUseTextures.get(key); if (inUseTextures) { const index = inUseTextures.indexOf(textureData.texture); if (index !== -1) { inUseTextures.splice(index, 1); let idleTextures = this.idleTextures.get(key); if (!idleTextures) { idleTextures = []; this.idleTextures.set(key, idleTextures); } idleTextures.push(textureData.texture); } } } } if (!key || deleteTexture) { Logger.verbose("TextureManager", `Deleting texture of size ${textureData.width}x${textureData.height}`); this.glContext.deleteTexture(textureData.texture); } } toTensorData(dataType, data) { switch (dataType) { case "int16": return data instanceof Int16Array ? data : Int16Array.from(data); case "int32": return data instanceof Int32Array ? data : Int32Array.from(data); case "int8": return data instanceof Int8Array ? data : Int8Array.from(data); case "uint16": return data instanceof Uint16Array ? data : Uint16Array.from(data); case "uint32": return data instanceof Uint32Array ? data : Uint32Array.from(data); case "uint8": case "bool": return data instanceof Uint8Array ? data : Uint8Array.from(data); case "float32": return data instanceof Float32Array ? data : Float32Array.from(data); case "float64": return data instanceof Float64Array ? data : Float64Array.from(data); default: throw new Error(`TensorData type ${dataType} is not supported`); } } toTextureData(_dataType, data) { if (!data) { return void 0; } return data instanceof Float32Array ? data : new Float32Array(data); } toEncoderType(_dataType) { return "float"; } clearActiveTextures() { this.glContext.clearActiveTextures(); } }; } }); // web/lib/onnxjs/backends/webgl/session-handler.ts var WebGLSessionHandler; var init_session_handler = __esm({ "web/lib/onnxjs/backends/webgl/session-handler.ts"() { "use strict"; init_instrument(); init_opset(); init_inference_handler(); init_op_resolve_rules(); init_program_manager(); init_texture_layout_strategy(); init_texture_manager(); WebGLSessionHandler = class { constructor(backend2, context) { this.backend = backend2; this.context = context; this.layoutStrategy = new PreferLogicalStrategy(backend2.glContext.maxTextureSize); this.programManager = new ProgramManager(this.context.profiler, backend2.glContext, this.layoutStrategy); this.textureManager = new TextureManager(backend2.glContext, this.layoutStrategy, this.context.profiler, { reuseTextures: backend2.textureCacheMode === "full" }); this.packedTextureDataCache = /* @__PURE__ */ new Map(); this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); this.pack = backend2.pack; this.pack2unpackMap = /* @__PURE__ */ new Map(); this.unpack2packMap = /* @__PURE__ */ new Map(); } createInferenceHandler() { return new WebGLInferenceHandler(this); } onGraphInitialized(graph) { const initializers = graph.getValues().filter((v) => v.from === -1 && v.tensor).map((v) => v.tensor.dataId); this.initializers = new Set(initializers); } isInitializer(tensorId) { return this.initializers ? this.initializers.has(tensorId) : false; } addInitializer(tensorId) { this.initializers.add(tensorId); } getTextureData(tensorId, isPacked) { if (isPacked) { return this.packedTextureDataCache.get(tensorId); } else { return this.unpackedTextureDataCache.get(tensorId); } } setTextureData(tensorId, textureData, isPacked = false) { Logger.verbose("WebGLSessionHandler", "Storing Texture data in cache"); if (isPacked) { this.packedTextureDataCache.set(tensorId, textureData); } else { this.unpackedTextureDataCache.set(tensorId, textureData); } } dispose() { this.programManager.dispose(); this.textureManager.clearActiveTextures(); this.packedTextureDataCache.forEach((td) => this.textureManager.releaseTexture(td, true)); this.packedTextureDataCache = /* @__PURE__ */ new Map(); this.unpackedTextureDataCache.forEach((td) => this.textureManager.releaseTexture(td, true)); this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); } resolve(node, opsets, graph) { const op = resolveOperator(node, opsets, WEBGL_OP_RESOLVE_RULES); return { impl: op.opImpl, context: op.opInit ? op.opInit(node, graph) : node }; } }; } }); // web/lib/onnxjs/backends/webgl/webgl-context.ts function linearSearchLastTrue(arr) { let i = 0; for (; i < arr.length; ++i) { const isDone = arr[i](); if (!isDone) { break; } } return i - 1; } var WebGLContext; var init_webgl_context = __esm({ "web/lib/onnxjs/backends/webgl/webgl-context.ts"() { "use strict"; init_esm(); init_texture_data_encoder(); init_texture_data_encoder(); init_utils(); WebGLContext = class { constructor(gl, version3) { this.frameBufferBound = false; this.itemsToPoll = []; this.gl = gl; this.version = version3; this.getExtensions(); this.vertexbuffer = this.createVertexbuffer(); this.framebuffer = this.createFramebuffer(); this.queryVitalParameters(); } allocateTexture(width, height, encoder, data) { const gl = this.gl; const texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); const buffer = data ? encoder.encode(data, width * height) : null; gl.texImage2D( gl.TEXTURE_2D, 0, // Level of detail. encoder.internalFormat, width, height, 0, // Always 0 in OpenGL ES. encoder.format, encoder.textureType, buffer ); this.checkError(); return texture; } updateTexture(texture, width, height, encoder, data) { const gl = this.gl; gl.bindTexture(gl.TEXTURE_2D, texture); const buffer = encoder.encode(data, width * height); gl.texSubImage2D( gl.TEXTURE_2D, 0, // level 0, // xoffset 0, // yoffset width, height, encoder.format, encoder.textureType, buffer ); this.checkError(); } attachFramebuffer(texture, width, height) { const gl = this.gl; gl.bindTexture(gl.TEXTURE_2D, texture); gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); this.checkError(); gl.viewport(0, 0, width, height); gl.scissor(0, 0, width, height); } readTexture(texture, width, height, dataSize, dataType, channels) { const gl = this.gl; if (!channels) { channels = 1; } if (!this.frameBufferBound) { this.attachFramebuffer(texture, width, height); } const encoder = this.getEncoder(dataType, channels); const buffer = encoder.allocate(width * height); gl.bindTexture(gl.TEXTURE_2D, texture); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); gl.readPixels(0, 0, width, height, gl.RGBA, encoder.textureType, buffer); this.checkError(); return encoder.decode(buffer, dataSize); } isFramebufferReady() { return true; } getActiveTexture() { const gl = this.gl; const n = gl.getParameter(this.gl.ACTIVE_TEXTURE); return `TEXTURE${n - gl.TEXTURE0}`; } getTextureBinding() { return this.gl.getParameter(this.gl.TEXTURE_BINDING_2D); } getFramebufferBinding() { return this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING); } setVertexAttributes(positionHandle, textureCoordHandle) { const gl = this.gl; gl.vertexAttribPointer(positionHandle, 3, gl.FLOAT, false, 20, 0); gl.enableVertexAttribArray(positionHandle); if (textureCoordHandle !== -1) { gl.vertexAttribPointer(textureCoordHandle, 2, gl.FLOAT, false, 20, 12); gl.enableVertexAttribArray(textureCoordHandle); } this.checkError(); } createProgram(vertexShader, fragShader) { const gl = this.gl; const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragShader); gl.linkProgram(program); return program; } compileShader(shaderSource, shaderType) { const gl = this.gl; const shader = gl.createShader(shaderType); if (!shader) { throw new Error(`createShader() returned null with type ${shaderType}`); } gl.shaderSource(shader, shaderSource); gl.compileShader(shader); if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) === false) { throw new Error(`Failed to compile shader: ${gl.getShaderInfoLog(shader)} Shader source: ${shaderSource}`); } return shader; } deleteShader(shader) { this.gl.deleteShader(shader); } bindTextureToUniform(texture, position, uniformHandle) { const gl = this.gl; gl.activeTexture(gl.TEXTURE0 + position); this.checkError(); gl.bindTexture(gl.TEXTURE_2D, texture); this.checkError(); gl.uniform1i(uniformHandle, position); this.checkError(); } draw() { this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); this.checkError(); } checkError() { if (env2.debug) { const gl = this.gl; const error = gl.getError(); let label = ""; switch (error) { case gl.NO_ERROR: return; case gl.INVALID_ENUM: label = "INVALID_ENUM"; break; case gl.INVALID_VALUE: label = "INVALID_VALUE"; break; case gl.INVALID_OPERATION: label = "INVALID_OPERATION"; break; case gl.INVALID_FRAMEBUFFER_OPERATION: label = "INVALID_FRAMEBUFFER_OPERATION"; break; case gl.OUT_OF_MEMORY: label = "OUT_OF_MEMORY"; break; case gl.CONTEXT_LOST_WEBGL: label = "CONTEXT_LOST_WEBGL"; break; default: label = `Unknown WebGL Error: ${error.toString(16)}`; } throw new Error(label); } } deleteTexture(texture) { this.gl.deleteTexture(texture); } deleteProgram(program) { this.gl.deleteProgram(program); } getEncoder(dataType, channels, usage = 0 /* Default */) { if (this.version === 2) { return new RedFloat32DataEncoder(this.gl, channels); } switch (dataType) { case "float": if (usage === 1 /* UploadOnly */ || this.isRenderFloat32Supported) { return new RGBAFloatDataEncoder(this.gl, channels); } else { return new RGBAFloatDataEncoder( this.gl, channels, this.textureHalfFloatExtension.HALF_FLOAT_OES ); } case "int": throw new Error("not implemented"); case "byte": return new Uint8DataEncoder(this.gl, channels); default: throw new Error(`Invalid dataType: ${dataType}`); } } clearActiveTextures() { const gl = this.gl; for (let unit = 0; unit < this.maxTextureImageUnits; ++unit) { gl.activeTexture(gl.TEXTURE0 + unit); gl.bindTexture(gl.TEXTURE_2D, null); } } dispose() { if (this.disposed) { return; } const gl = this.gl; gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.deleteFramebuffer(this.framebuffer); gl.bindBuffer(gl.ARRAY_BUFFER, null); gl.deleteBuffer(this.vertexbuffer); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); gl.finish(); this.disposed = true; } createDefaultGeometry() { return new Float32Array([ -1, 1, 0, 0, 1, // upper left -1, -1, 0, 0, 0, // lower left 1, 1, 0, 1, 1, // upper right 1, -1, 0, 1, 0 // lower right ]); } createVertexbuffer() { const gl = this.gl; const buffer = gl.createBuffer(); if (!buffer) { throw new Error("createBuffer() returned null"); } const geometry = this.createDefaultGeometry(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.bufferData(gl.ARRAY_BUFFER, geometry, gl.STATIC_DRAW); this.checkError(); return buffer; } createFramebuffer() { const fb = this.gl.createFramebuffer(); if (!fb) { throw new Error("createFramebuffer returned null"); } return fb; } queryVitalParameters() { const gl = this.gl; this.isFloatTextureAttachableToFrameBuffer = this.checkFloatTextureAttachableToFrameBuffer(); this.isRenderFloat32Supported = this.checkRenderFloat32(); this.isFloat32DownloadSupported = this.checkFloat32Download(); if (this.version === 1 && !this.textureHalfFloatExtension && !this.isRenderFloat32Supported) { throw new Error("both float32 and float16 TextureType are not supported"); } this.isBlendSupported = !this.isRenderFloat32Supported || this.checkFloat32Blend(); this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); this.maxTextureImageUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); if (this.version === 2) { } } getExtensions() { if (this.version === 2) { this.colorBufferFloatExtension = this.gl.getExtension("EXT_color_buffer_float"); this.disjointTimerQueryWebgl2Extension = this.gl.getExtension("EXT_disjoint_timer_query_webgl2"); } else { this.textureFloatExtension = this.gl.getExtension("OES_texture_float"); this.textureHalfFloatExtension = this.gl.getExtension("OES_texture_half_float"); } } checkFloatTextureAttachableToFrameBuffer() { const gl = this.gl; const texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); const internalFormat = this.version === 2 ? gl.RGBA32F : gl.RGBA; gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null); const frameBuffer = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); const isComplete = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE; gl.bindTexture(gl.TEXTURE_2D, null); gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.deleteTexture(texture); gl.deleteFramebuffer(frameBuffer); return isComplete; } checkRenderFloat32() { if (this.version === 2) { if (!this.colorBufferFloatExtension) { return false; } } else { if (!this.textureFloatExtension) { return false; } } return this.isFloatTextureAttachableToFrameBuffer; } checkFloat32Download() { if (this.version === 2) { if (!this.colorBufferFloatExtension) { return false; } } else { if (!this.textureFloatExtension) { return false; } if (!this.gl.getExtension("WEBGL_color_buffer_float")) { return false; } } return this.isFloatTextureAttachableToFrameBuffer; } /** * Check whether GL_BLEND is supported */ checkFloat32Blend() { const gl = this.gl; let texture; let frameBuffer; let vertexShader; let fragmentShader; let program; try { texture = gl.createTexture(); frameBuffer = gl.createFramebuffer(); gl.bindTexture(gl.TEXTURE_2D, texture); const internalFormat = this.version === 2 ? gl.RGBA32F : gl.RGBA; gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null); gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); gl.enable(gl.BLEND); vertexShader = gl.createShader(gl.VERTEX_SHADER); if (!vertexShader) { return false; } gl.shaderSource(vertexShader, "void main(){}"); gl.compileShader(vertexShader); fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); if (!fragmentShader) { return false; } gl.shaderSource(fragmentShader, "precision highp float;void main(){gl_FragColor=vec4(0.5);}"); gl.compileShader(fragmentShader); program = gl.createProgram(); if (!program) { return false; } gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); gl.useProgram(program); gl.drawArrays(gl.POINTS, 0, 1); return gl.getError() === gl.NO_ERROR; } finally { gl.disable(gl.BLEND); if (program) { gl.deleteProgram(program); } if (vertexShader) { gl.deleteShader(vertexShader); } if (fragmentShader) { gl.deleteShader(fragmentShader); } if (frameBuffer) { gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.deleteFramebuffer(frameBuffer); } if (texture) { gl.bindTexture(gl.TEXTURE_2D, null); gl.deleteTexture(texture); } } } beginTimer() { if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) { const gl2 = this.gl; const ext = this.disjointTimerQueryWebgl2Extension; const query = gl2.createQuery(); gl2.beginQuery(ext.TIME_ELAPSED_EXT, query); return query; } else { throw new Error("WebGL1 profiling currently not supported."); } } endTimer() { if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) { const gl2 = this.gl; const ext = this.disjointTimerQueryWebgl2Extension; gl2.endQuery(ext.TIME_ELAPSED_EXT); return; } else { throw new Error("WebGL1 profiling currently not supported"); } } isTimerResultAvailable(query) { let available = false, disjoint = false; if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) { const gl2 = this.gl; const ext = this.disjointTimerQueryWebgl2Extension; available = gl2.getQueryParameter(query, gl2.QUERY_RESULT_AVAILABLE); disjoint = gl2.getParameter(ext.GPU_DISJOINT_EXT); } else { throw new Error("WebGL1 profiling currently not supported"); } return available && !disjoint; } getTimerResult(query) { let timeElapsed = 0; if (this.version === 2) { const gl2 = this.gl; timeElapsed = gl2.getQueryParameter(query, gl2.QUERY_RESULT); gl2.deleteQuery(query); } else { throw new Error("WebGL1 profiling currently not supported"); } return timeElapsed / 1e6; } async waitForQueryAndGetTime(query) { await repeatedTry(() => this.isTimerResultAvailable(query)); return this.getTimerResult(query); } async createAndWaitForFence() { const fenceContext = this.createFence(this.gl); return this.pollFence(fenceContext); } createFence(gl) { let isFencePassed; const gl2 = gl; const query = gl2.fenceSync(gl2.SYNC_GPU_COMMANDS_COMPLETE, 0); gl.flush(); if (query === null) { isFencePassed = () => true; } else { isFencePassed = () => { const status = gl2.clientWaitSync(query, 0, 0); return status === gl2.ALREADY_SIGNALED || status === gl2.CONDITION_SATISFIED; }; } return { query, isFencePassed }; } async pollFence(fenceContext) { return new Promise((resolve) => { void this.addItemToPoll( () => fenceContext.isFencePassed(), () => resolve() ); }); } pollItems() { const index = linearSearchLastTrue(this.itemsToPoll.map((x) => x.isDoneFn)); for (let i = 0; i <= index; ++i) { const { resolveFn } = this.itemsToPoll[i]; resolveFn(); } this.itemsToPoll = this.itemsToPoll.slice(index + 1); } async addItemToPoll(isDoneFn, resolveFn) { this.itemsToPoll.push({ isDoneFn, resolveFn }); if (this.itemsToPoll.length > 1) { return; } await repeatedTry(() => { this.pollItems(); return this.itemsToPoll.length === 0; }); } }; } }); // web/lib/onnxjs/backends/webgl/webgl-context-factory.ts function createWebGLContext(contextId) { let context; if ((!contextId || contextId === "webgl2") && "webgl2" in cache) { context = cache.webgl2; } else if ((!contextId || contextId === "webgl") && "webgl" in cache) { context = cache.webgl; } if (!context) { try { const offscreenCanvas = createOffscreenCanvas(); context = createNewWebGLContext(offscreenCanvas, contextId); } catch { const canvas = createCanvas(); context = createNewWebGLContext(canvas, contextId); } } contextId = contextId || context.version === 1 ? "webgl" : "webgl2"; const gl = context.gl; cache[contextId] = context; if (gl.isContextLost()) { delete cache[contextId]; return createWebGLContext(contextId); } gl.disable(gl.DEPTH_TEST); gl.disable(gl.STENCIL_TEST); gl.disable(gl.BLEND); gl.disable(gl.DITHER); gl.disable(gl.POLYGON_OFFSET_FILL); gl.disable(gl.SAMPLE_COVERAGE); gl.enable(gl.SCISSOR_TEST); gl.enable(gl.CULL_FACE); gl.cullFace(gl.BACK); return context; } function createNewWebGLContext(canvas, contextId) { const contextAttributes = { alpha: false, depth: false, antialias: false, stencil: false, preserveDrawingBuffer: false, premultipliedAlpha: false, failIfMajorPerformanceCaveat: false }; let gl; const ca = contextAttributes; if (!contextId || contextId === "webgl2") { gl = canvas.getContext("webgl2", ca); if (gl) { try { return new WebGLContext(gl, 2); } catch (err) { Logger.warning("GlContextFactory", `failed to create WebGLContext using contextId 'webgl2'. Error: ${err}`); } } } if (!contextId || contextId === "webgl") { gl = canvas.getContext("webgl", ca) || canvas.getContext("experimental-webgl", ca); if (gl) { try { return new WebGLContext(gl, 1); } catch (err) { Logger.warning( "GlContextFactory", `failed to create WebGLContext using contextId 'webgl' or 'experimental-webgl'. Error: ${err}` ); } } } throw new Error("WebGL is not supported"); } function createCanvas() { if (typeof document === "undefined") { throw new TypeError("failed to create canvas: document is not supported"); } const canvas = document.createElement("canvas"); canvas.width = 1; canvas.height = 1; return canvas; } function createOffscreenCanvas() { if (typeof OffscreenCanvas === "undefined") { throw new TypeError("failed to create offscreen canvas: OffscreenCanvas is not supported"); } return new OffscreenCanvas(1, 1); } var cache; var init_webgl_context_factory = __esm({ "web/lib/onnxjs/backends/webgl/webgl-context-factory.ts"() { "use strict"; init_instrument(); init_webgl_context(); cache = {}; } }); // web/lib/onnxjs/backends/backend-webgl.ts var WebGLBackend; var init_backend_webgl = __esm({ "web/lib/onnxjs/backends/backend-webgl.ts"() { "use strict"; init_esm(); init_instrument(); init_session_handler(); init_webgl_context_factory(); WebGLBackend = class { get contextId() { return env2.webgl.contextId; } set contextId(value) { env2.webgl.contextId = value; } get matmulMaxBatchSize() { return env2.webgl.matmulMaxBatchSize; } set matmulMaxBatchSize(value) { env2.webgl.matmulMaxBatchSize = value; } get textureCacheMode() { return env2.webgl.textureCacheMode; } set textureCacheMode(value) { env2.webgl.textureCacheMode = value; } get pack() { return env2.webgl.pack; } set pack(value) { env2.webgl.pack = value; } get async() { return env2.webgl.async; } set async(value) { env2.webgl.async = value; } initialize() { try { this.glContext = createWebGLContext(this.contextId); if (typeof this.matmulMaxBatchSize !== "number") { this.matmulMaxBatchSize = 16; } if (typeof this.textureCacheMode !== "string") { this.textureCacheMode = "full"; } if (typeof this.pack !== "boolean") { this.pack = false; } if (typeof this.async !== "boolean") { this.async = false; } Logger.setWithEnv(env2); if (!env2.webgl.context) { Object.defineProperty(env2.webgl, "context", { value: this.glContext.gl }); } Logger.verbose( "WebGLBackend", `Created WebGLContext: ${typeof this.glContext} with matmulMaxBatchSize: ${this.matmulMaxBatchSize}; textureCacheMode: ${this.textureCacheMode}; pack: ${this.pack}; async: ${this.async}.` ); return true; } catch (e) { Logger.warning("WebGLBackend", `Unable to initialize WebGLBackend. ${e}`); return false; } } createSessionHandler(context) { return new WebGLSessionHandler(this, context); } dispose() { this.glContext.dispose(); } }; } }); // web/lib/onnxjs/backend.ts async function resolveBackend(hint) { if (!hint) { return resolveBackend(["webgl"]); } else { const hints = typeof hint === "string" ? [hint] : hint; for (const backendHint of hints) { const cache2 = backendsCache.get(backendHint); if (cache2) { return cache2; } const backend2 = await tryLoadBackend(backendHint); if (backend2) { return backend2; } } } throw new Error("no available backend to use"); } async function tryLoadBackend(backendHint) { const backendObj = backend; if (typeof backendObj[backendHint] !== "undefined" && isBackend(backendObj[backendHint])) { const backend2 = backendObj[backendHint]; let init = backend2.initialize(); if (typeof init === "object" && "then" in init) { init = await init; } if (init) { backendsCache.set(backendHint, backend2); return backend2; } } return void 0; } function isBackend(obj) { const o = obj; if ("initialize" in o && typeof o.initialize === "function" && // initialize() "createSessionHandler" in o && typeof o.createSessionHandler === "function" && // createSessionHandler() "dispose" in o && typeof o.dispose === "function") { return true; } return false; } var backendsCache, backend; var init_backend2 = __esm({ "web/lib/onnxjs/backend.ts"() { "use strict"; init_backend_webgl(); backendsCache = /* @__PURE__ */ new Map(); backend = { webgl: new WebGLBackend() }; } }); // web/lib/onnxjs/execution-plan.ts var KernelOp, ExecutionPlan; var init_execution_plan = __esm({ "web/lib/onnxjs/execution-plan.ts"() { "use strict"; init_instrument(); KernelOp = class { constructor(op, node) { this.op = op; this.node = node; } }; ExecutionPlan = class { constructor(graph, ops, profiler) { this.graph = graph; this.profiler = profiler; this.initialize(ops); } initialize(ops) { this.profiler.event("session", "ExecutionPlan.initialize", () => { const graphNodes = this.graph.getNodes(); if (graphNodes.length !== ops.length) { throw new Error("The size of nodes and OPs do not match."); } this._ops = ops.map((op, i) => new KernelOp(op, graphNodes[i])); this.reset(); this._starter = []; this._ops.forEach((op, i) => { let resolved = true; for (const input of op.node.inputs) { if (!this._values[input] && // not an initialized input this.graph.getInputIndices().indexOf(input) === -1) { resolved = false; break; } } if (resolved) { this._starter.push(i); } }); }); } reset() { this._values = this.graph.getValues().map((i) => i.tensor); } async execute(sessionHandler, modelInputs) { return this.profiler.event("session", "ExecutionPlan.execute", async () => { this.reset(); const inferenceHandler = sessionHandler.createInferenceHandler(); const graphInputs = this.graph.getInputIndices(); if (modelInputs.length !== graphInputs.length) { throw new Error( `number of input tensors don't match the number of inputs to the model: actual: ${modelInputs.length} expected: ${graphInputs.length}` ); } modelInputs.forEach((input, i) => { const index = graphInputs[i]; this._values[index] = input; }); const sequence = this._starter.slice(0); const graphValues = this.graph.getValues(); const graphNodes = this.graph.getNodes(); let rear = 0; while (rear < sequence.length) { const thisOpIndex = sequence[rear++]; const thisOp = this._ops[thisOpIndex]; const inputList = thisOp.node.inputs.map((i) => this._values[i]); if (inputList.indexOf(void 0) !== -1) { throw new Error(`unresolved input detected: op: ${thisOp.node}`); } const inputTensors = inputList; Logger.verbose( "ExecPlan", `Running op:${thisOp.node.name} (${inputTensors.map((t, i) => `'${thisOp.node.inputs[i]}': ${t.type}[${t.dims.join(",")}]`).join(", ")})` ); const outputList = await this.profiler.event( "node", thisOp.node.name, async () => thisOp.op.impl(inferenceHandler, inputTensors, thisOp.op.context) ); if (outputList.length !== thisOp.node.outputs.length) { throw new Error("the size of output does not match model definition."); } outputList.forEach((output2, i) => { const j = thisOp.node.outputs[i]; if (this._values[j]) { throw new Error(`output [${j}] already has value: op:${thisOp.node.name}`); } this._values[j] = output2; }); const downstreamNodes = /* @__PURE__ */ new Set(); outputList.forEach((_output, i) => { const j = thisOp.node.outputs[i]; for (const currentDownstreamNodeIndex of graphValues[j].to) { const currentDownstreamNode = graphNodes[currentDownstreamNodeIndex]; let resolved = true; for (const k of currentDownstreamNode.inputs) { if (!this._values[k]) { resolved = false; break; } } if (resolved) { downstreamNodes.add(currentDownstreamNodeIndex); } } }); sequence.push(...downstreamNodes); } const output = []; for (let i = 0; i < this.graph.getOutputIndices().length; i++) { const outputIndex = this.graph.getOutputIndices()[i]; const outputTensor = this._values[outputIndex]; if (outputTensor === void 0) { throw new Error(`required output [${outputIndex}] does not have value`); } if (outputIndex === 0) { await outputTensor.getData(); } else { void outputTensor.data; } output.push(outputTensor); } Logger.verbose("ExecPlan", "disposing of inferenceHandler"); inferenceHandler.dispose(); return output; }); } }; } }); // web/lib/onnxjs/attribute.ts var import_onnx3, Attribute2; var init_attribute = __esm({ "web/lib/onnxjs/attribute.ts"() { "use strict"; init_ort_generated(); import_onnx3 = __toESM(require_onnx()); init_tensor2(); init_util(); Attribute2 = class _Attribute { constructor(attributes) { this._attributes = /* @__PURE__ */ new Map(); if (attributes !== null && attributes !== void 0) { for (const attr of attributes) { if (attr instanceof import_onnx3.onnx.AttributeProto) { this._attributes.set(attr.name, [_Attribute.getValue(attr), _Attribute.getType(attr)]); } else if (attr instanceof import_attribute.Attribute) { this._attributes.set(attr.name(), [_Attribute.getValue(attr), _Attribute.getType(attr)]); } } if (this._attributes.size < attributes.length) { throw new Error("duplicated attribute names"); } } } set(key, type, value) { this._attributes.set(key, [value, type]); } delete(key) { this._attributes.delete(key); } getFloat(key, defaultValue) { return this.get(key, "float", defaultValue); } getInt(key, defaultValue) { return this.get(key, "int", defaultValue); } getString(key, defaultValue) { return this.get(key, "string", defaultValue); } getTensor(key, defaultValue) { return this.get(key, "tensor", defaultValue); } getFloats(key, defaultValue) { return this.get(key, "floats", defaultValue); } getInts(key, defaultValue) { return this.get(key, "ints", defaultValue); } getStrings(key, defaultValue) { return this.get(key, "strings", defaultValue); } getTensors(key, defaultValue) { return this.get(key, "tensors", defaultValue); } get(key, type, defaultValue) { const valueAndType = this._attributes.get(key); if (valueAndType === void 0) { if (defaultValue !== void 0) { return defaultValue; } throw new Error(`required attribute not found: ${key}`); } if (valueAndType[1] !== type) { throw new Error(`type mismatch: expected ${type} but got ${valueAndType[1]}`); } return valueAndType[0]; } static getType(attr) { const type = attr instanceof import_onnx3.onnx.AttributeProto ? attr.type : attr.type(); switch (type) { case import_onnx3.onnx.AttributeProto.AttributeType.FLOAT: return "float"; case import_onnx3.onnx.AttributeProto.AttributeType.INT: return "int"; case import_onnx3.onnx.AttributeProto.AttributeType.STRING: return "string"; case import_onnx3.onnx.AttributeProto.AttributeType.TENSOR: return "tensor"; case import_onnx3.onnx.AttributeProto.AttributeType.FLOATS: return "floats"; case import_onnx3.onnx.AttributeProto.AttributeType.INTS: return "ints"; case import_onnx3.onnx.AttributeProto.AttributeType.STRINGS: return "strings"; case import_onnx3.onnx.AttributeProto.AttributeType.TENSORS: return "tensors"; default: throw new Error(`attribute type is not supported yet: ${import_onnx3.onnx.AttributeProto.AttributeType[type]}`); } } static getValue(attr) { const attrType = attr instanceof import_onnx3.onnx.AttributeProto ? attr.type : attr.type(); if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.GRAPH || attrType === import_onnx3.onnx.AttributeProto.AttributeType.GRAPHS) { throw new Error("graph attribute is not supported yet"); } const value = this.getValueNoCheck(attr); if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.INT && LongUtil.isLong(value)) { return LongUtil.longToNumber(value); } if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.INTS) { const arr = value; const numberValue = new Array(arr.length); for (let i = 0; i < arr.length; i++) { const maybeLong = arr[i]; numberValue[i] = LongUtil.longToNumber(maybeLong); } return numberValue; } if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.TENSOR) { return attr instanceof import_onnx3.onnx.AttributeProto ? Tensor4.fromProto(value) : Tensor4.fromOrtTensor(value); } if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.TENSORS) { if (attr instanceof import_onnx3.onnx.AttributeProto) { const tensorProtos = value; return tensorProtos.map((value2) => Tensor4.fromProto(value2)); } else if (attr instanceof import_attribute.Attribute) { const tensorProtos = value; return tensorProtos.map((value2) => Tensor4.fromOrtTensor(value2)); } } if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.STRING) { if (attr instanceof import_onnx3.onnx.AttributeProto) { const utf8String = value; return decodeUtf8String(utf8String); } } if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.STRINGS) { if (attr instanceof import_onnx3.onnx.AttributeProto) { const utf8Strings = value; return utf8Strings.map(decodeUtf8String); } } return value; } static getValueNoCheck(attr) { return attr instanceof import_onnx3.onnx.AttributeProto ? this.getValueNoCheckFromOnnxFormat(attr) : this.getValueNoCheckFromOrtFormat(attr); } static getValueNoCheckFromOnnxFormat(attr) { switch (attr.type) { case import_onnx3.onnx.AttributeProto.AttributeType.FLOAT: return attr.f; case import_onnx3.onnx.AttributeProto.AttributeType.INT: return attr.i; case import_onnx3.onnx.AttributeProto.AttributeType.STRING: return attr.s; case import_onnx3.onnx.AttributeProto.AttributeType.TENSOR: return attr.t; case import_onnx3.onnx.AttributeProto.AttributeType.GRAPH: return attr.g; case import_onnx3.onnx.AttributeProto.AttributeType.FLOATS: return attr.floats; case import_onnx3.onnx.AttributeProto.AttributeType.INTS: return attr.ints; case import_onnx3.onnx.AttributeProto.AttributeType.STRINGS: return attr.strings; case import_onnx3.onnx.AttributeProto.AttributeType.TENSORS: return attr.tensors; case import_onnx3.onnx.AttributeProto.AttributeType.GRAPHS: return attr.graphs; default: throw new Error(`unsupported attribute type: ${import_onnx3.onnx.AttributeProto.AttributeType[attr.type]}`); } } static getValueNoCheckFromOrtFormat(attr) { switch (attr.type()) { case import_attribute_type.AttributeType.FLOAT: return attr.f(); case import_attribute_type.AttributeType.INT: return attr.i(); case import_attribute_type.AttributeType.STRING: return attr.s(); case import_attribute_type.AttributeType.TENSOR: return attr.t(); case import_attribute_type.AttributeType.GRAPH: return attr.g(); case import_attribute_type.AttributeType.FLOATS: return attr.floatsArray(); case import_attribute_type.AttributeType.INTS: { const ints = []; for (let i = 0; i < attr.intsLength(); i++) { ints.push(attr.ints(i)); } return ints; } case import_attribute_type.AttributeType.STRINGS: { const strings = []; for (let i = 0; i < attr.stringsLength(); i++) { strings.push(attr.strings(i)); } return strings; } case import_attribute_type.AttributeType.TENSORS: { const tensors = []; for (let i = 0; i < attr.tensorsLength(); i++) { tensors.push(attr.tensors(i)); } return tensors; } // case ortFbs.AttributeType.GRAPHS: // TODO: Subgraph not supported yet. // const graphs = []; // for (let i = 0; i < attr.graphsLength(); i++) { // graphs.push(attr.graphs(i)!); // } // return graphs; default: throw new Error(`unsupported attribute type: ${import_attribute_type.AttributeType[attr.type()]}`); } } }; } }); // web/lib/onnxjs/graph.ts var import_onnx4, Graph2, Value, Node2, GraphImpl; var init_graph = __esm({ "web/lib/onnxjs/graph.ts"() { "use strict"; init_attribute(); init_ort_generated(); import_onnx4 = __toESM(require_onnx()); init_tensor2(); init_util(); Graph2 = { /** * construct a graph from a graph protobuf type */ from: (graphProto, initializer) => new GraphImpl(graphProto, initializer) }; Value = class { constructor(valueInfo) { this._from = void 0; this._to = []; this.tensor = void 0; this.type = void 0; if (valueInfo) { this.type = ProtoUtil.tensorValueTypeFromProto(valueInfo.type.tensorType); } } // -1 represent from initializer get from() { return this._from; } get to() { return this._to; } }; Node2 = class { constructor(_nodeProto, name2) { if (_nodeProto instanceof import_onnx4.onnx.NodeProto) { this.name = _nodeProto.name; this.opType = _nodeProto.opType; this.attributes = new Attribute2(_nodeProto.attribute); } else if (_nodeProto instanceof import_node.Node) { this.name = name2 ?? _nodeProto.name(); this.opType = _nodeProto.opType(); this.attributes = new Attribute2(ProtoUtil.tensorAttributesFromORTFormat(_nodeProto)); } this.inputs = []; this.outputs = []; this.executeNode = true; } }; GraphImpl = class { constructor(graph, graphInitializer) { if (!graph) { throw new TypeError("graph is empty"); } this.buildGraph(graph); this.transformGraph(graphInitializer); this.checkIsAcyclic(); } getInputIndices() { return this._allInputIndices; } getInputNames() { return this._allInputNames; } getOutputIndices() { return this._allOutputIndices; } getOutputNames() { return this._allOutputNames; } getValues() { return this._allData; } getNodes() { return this._nodes; } buildGraph(graph) { if (graph instanceof import_onnx4.onnx.GraphProto) { this.buildGraphFromOnnxFormat(graph); } else if (graph instanceof import_graph.Graph) { this.buildGraphFromOrtFormat(graph); } else { throw new TypeError("Graph type is not supported."); } } buildGraphFromOnnxFormat(graph) { const dataIndices = /* @__PURE__ */ new Map(); this._allData = []; this._allInputIndices = []; this._allInputNames = []; this._allOutputIndices = []; this._allOutputNames = []; this._nodes = []; const nodesIndices = /* @__PURE__ */ new Map(); if (!graph.input) { throw new Error("missing information in graph: input"); } const inputValueNames = []; for (const i of graph.input) { if (dataIndices.has(i.name)) { throw new Error(`duplicated input name: ${i.name}`); } const currentIndex = this._allData.push(new Value(i)) - 1; dataIndices.set(i.name, currentIndex); inputValueNames.push(i.name); } if (!graph.initializer) { throw new Error("missing information in graph: initializer"); } for (const i of graph.initializer) { let index = dataIndices.get(i.name); if (index === void 0) { const value = new Value(); value.type = { shape: { dims: ProtoUtil.tensorDimsFromProto(i.dims) }, tensorType: ProtoUtil.tensorDataTypeFromProto(i.dataType) }; index = this._allData.push(value) - 1; dataIndices.set(i.name, index); } this._allData[index]._from = -1; this._allData[index].tensor = Tensor4.fromProto(i); } for (let i = 0; i < this._allData.length; i++) { if (!this._allData[i].tensor) { this._allInputIndices.push(i); this._allInputNames.push(inputValueNames[i]); } } if (!graph.output) { throw new Error("missing information in graph: output"); } for (const i of graph.output) { if (dataIndices.has(i.name)) { throw new Error(`duplicated output name: ${i.name}`); } const currentIndex = this._allData.push(new Value(i)) - 1; dataIndices.set(i.name, currentIndex); this._allOutputIndices.push(currentIndex); this._allOutputNames.push(i.name); } if (!graph.node) { throw new Error("missing information in graph: node"); } for (const nodeProto of graph.node) { if (!nodeProto.name) { for (let pick = 0; ; pick++) { const name2 = `unnamed_${nodeProto.opType}_${pick}`; if (!nodesIndices.has(name2)) { nodeProto.name = name2; break; } } } if (nodesIndices.has(nodeProto.name)) { throw new Error(`duplicated node name: ${nodeProto.name}`); } const currentIndex = this._nodes.push(new Node2(nodeProto)) - 1; nodesIndices.set(nodeProto.name, currentIndex); } for (let i = 0; i < this._nodes.length; i++) { const node = this._nodes[i]; const nodeProto = graph.node[i]; if (!nodeProto.output) { throw new Error(`missing output for node: ${nodeProto.name}`); } for (const output of nodeProto.output) { let dataIndex = dataIndices.get(output); if (typeof dataIndex === "undefined") { dataIndex = this._allData.push(new Value()) - 1; dataIndices.set(output, dataIndex); } node.outputs.push(dataIndex); if (this._allData[dataIndex]._from !== void 0) { throw new Error(`multiple nodes output to one data value: ${dataIndex}`); } this._allData[dataIndex]._from = i; if (nodeProto.opType === "Constant") { if (!nodeProto.attribute || nodeProto.attribute.length !== 1 || !nodeProto.attribute[0].t) { throw new Error("missing attributes or missing tensor value in attributes for this Constant operator"); } if (!nodeProto.output || nodeProto.output.length !== 1) { throw new Error("missing output or incorrect number of outputs for this Constant operator"); } node.outputs.pop(); node.executeNode = false; this._allData[dataIndex]._from = -1; this._allData[dataIndex].tensor = Tensor4.fromProto(nodeProto.attribute[0].t); } } } for (let i = 0; i < this._nodes.length; i++) { const node = this._nodes[i]; const nodeProto = graph.node[i]; if (!nodeProto.input) { throw new Error(`missing input for node: ${nodeProto.name}`); } for (const input of nodeProto.input) { const dataIndex = dataIndices.get(input); if (typeof dataIndex === "undefined") { if (input === "" && (nodeProto.input.length === 3 || nodeProto.input.length === 4) && nodeProto.opType === "Resize") { continue; } throw new Error(`unrecognized input '${input}' for node: ${nodeProto.name}`); } node.inputs.push(dataIndex); this._allData[dataIndex]._to.push(i); } } return true; } buildGraphFromOrtFormat(graph) { const dataIndices = /* @__PURE__ */ new Map(); this._allData = []; this._allInputIndices = []; this._allInputNames = []; this._allOutputIndices = []; this._allOutputNames = []; this._nodes = []; const nodesIndices = /* @__PURE__ */ new Map(); const inputValueNames = []; for (let i = 0; i < graph.inputsLength(); i++) { const inputName = graph.inputs(i); if (dataIndices.has(inputName)) { throw new Error(`duplicated input name: ${inputName}`); } for (let j = 0; j < graph.nodeArgsLength(); j++) { if (graph.nodeArgs(j)?.name() === inputName) { const value = new Value(); const valueType = graph.nodeArgs(j)?.type()?.valueType(); if (valueType !== import_type_info_value.TypeInfoValue.tensor_type) { throw new Error("Unexpected value type for the nodeArg."); } const valueInfo = graph.nodeArgs(j).type().value(new import_tensor_type_and_shape.TensorTypeAndShape()); const type = ProtoUtil.tensorDataTypeFromProto(valueInfo.elemType()); const shape2 = valueInfo.shape(); const dims = []; for (let k = 0; k < shape2.dimLength(); k++) { dims.push(LongUtil.longToNumber(shape2.dim(k).value().dimValue())); } value.type = { shape: { dims }, tensorType: type }; const currentIndex = this._allData.push(value) - 1; dataIndices.set(inputName, currentIndex); inputValueNames.push(inputName); } } } for (let i = 0; i < graph.initializersLength(); i++) { const initializer = graph.initializers(i); let index = dataIndices.get(initializer.name()); if (index === void 0) { const value = new Value(); const dims = ProtoUtil.tensorDimsFromORTFormat(initializer); const type = ProtoUtil.tensorDataTypeFromProto(initializer.dataType()); value.type = { shape: { dims }, tensorType: type }; index = this._allData.push(value) - 1; dataIndices.set(initializer.name(), index); } this._allData[index]._from = -1; this._allData[index].tensor = Tensor4.fromOrtTensor(initializer); } for (let i = 0; i < this._allData.length; i++) { if (!this._allData[i].tensor) { this._allInputIndices.push(i); this._allInputNames.push(inputValueNames[i]); } } for (let i = 0; i < graph.outputsLength(); i++) { const outputName = graph.outputs(i); if (dataIndices.has(outputName)) { throw new Error(`duplicated output name: ${outputName}`); } const currentIndex = this._allData.push(new Value()) - 1; dataIndices.set(outputName, currentIndex); this._allOutputIndices.push(currentIndex); this._allOutputNames.push(outputName); } if (!graph.nodes) { throw new Error("missing information in graph: node"); } for (let i = 0; i < graph.nodesLength(); i++) { const nodeProto = graph.nodes(i); let name2 = nodeProto.name(); if (!name2) { for (let pick = 0; ; pick++) { name2 = `unnamed_${nodeProto.opType()}_${pick}`; if (!nodesIndices.has(name2)) { break; } } } if (nodesIndices.has(name2)) { throw new Error(`duplicated node name: ${name2}`); } const currentIndex = this._nodes.push(new Node2(nodeProto, name2)) - 1; nodesIndices.set(name2, currentIndex); } for (let i = 0; i < this._nodes.length; i++) { const node = this._nodes[i]; const nodeProto = graph.nodes(i); if (nodeProto == null) { throw new Error(`No node exists at index ${i}`); } if (nodeProto?.outputsLength() === 0) { throw new Error(`missing output for node: ${nodeProto.name}`); } for (let j = 0; j < nodeProto?.outputsLength(); j++) { const output = nodeProto?.outputs(j); let dataIndex = dataIndices.get(output); if (typeof dataIndex === "undefined") { dataIndex = this._allData.push(new Value()) - 1; dataIndices.set(output, dataIndex); } node.outputs.push(dataIndex); if (this._allData[dataIndex]._from !== void 0) { throw new Error(`multiple nodes output to one data value: ${dataIndex}`); } this._allData[dataIndex]._from = i; if (nodeProto.opType() === "Constant") { if (nodeProto.attributesLength() !== 1 || !nodeProto.attributes(0).t()) { throw new Error("missing attributes or missing tensor value in attributes for this Constant operator"); } if (nodeProto.outputsLength() !== 1) { throw new Error("missing output or incorrect number of outputs for this Constant operator"); } node.outputs.pop(); node.executeNode = false; this._allData[dataIndex]._from = -1; this._allData[dataIndex].tensor = Tensor4.fromOrtTensor(nodeProto.attributes(0).t()); } } } for (let i = 0; i < this._nodes.length; i++) { const node = this._nodes[i]; const nodeProto = graph.nodes(i); if (nodeProto.inputsLength() === 0) { throw new Error(`missing input for node: ${nodeProto.name}`); } for (let j = 0; j < nodeProto.inputsLength(); j++) { const input = nodeProto.inputs(j); const dataIndex = dataIndices.get(input); if (typeof dataIndex === "undefined") { throw new Error(`unrecognized input '${input}' for node: ${nodeProto.name()}`); } node.inputs.push(dataIndex); this._allData[dataIndex]._to.push(i); } } } checkIsAcyclic() { const starters = /* @__PURE__ */ new Set(); this._allInputIndices.forEach((i) => { const data = this._allData[i]; data._to.forEach((j) => { starters.add(j); }); }); const nodesStack = Array.from(starters); const nodesState = new Array(this._nodes.length).fill("white"); while (nodesStack.length > 0) { const nodeIndex = nodesStack.pop(); if (nodesState[nodeIndex] === "gray") { nodesState[nodeIndex] = "black"; } else { nodesStack.push(nodeIndex); nodesState[nodeIndex] = "gray"; this._nodes[nodeIndex].outputs.forEach((outgoingEdgeIndex) => { const data = this._allData[outgoingEdgeIndex]; if (typeof data.tensor !== "undefined") { throw new Error("node outputs should not be initialized"); } if (data._from !== nodeIndex) { throw new Error("from property of the Value object doesn't match index of Node being processed"); } data._to.forEach((downstreamNodeIndex) => { if (nodesState[downstreamNodeIndex] === "gray") { throw new Error("model graph is cyclic"); } else if (nodesState[downstreamNodeIndex] === "white") { nodesStack.push(downstreamNodeIndex); } }); }); } } } transformGraph(graphInitializer) { this.removeAllIdentityNodes(); this.removeAllDropoutNodes(); this.fuseConvActivationNodes(); if (graphInitializer) { graphInitializer.transformGraph(this); } this.finalizeGraph(); } /** * finalize the graph. * * this function should be called after all the transformation completed. * this function removes all unnecessary nodes and values from the graph */ finalizeGraph() { let offset = 0; const newIndices = new Array(this._nodes.length, 0); let nodePossition = 0; for (let i = 0; i < this._nodes.length; i++) { newIndices[i] = nodePossition; if (this._nodes[i].executeNode) { if (nodePossition !== i) { this._nodes[nodePossition] = this._nodes[i]; } nodePossition++; } else { this._nodes[i].outputs.forEach((ind) => { this._allData[ind]._from = -2; }); } } this._nodes.splice(nodePossition, this._nodes.length - nodePossition); for (let i = 0; i < this._allData.length; i++) { const currentData = this._allData[i]; if (currentData._from !== void 0 && currentData._from !== -1 && currentData._from !== -2) { currentData._from = newIndices[currentData._from]; } for (let j = 0; j < currentData._to.length; j++) { if (currentData._to[j] >= 0) { currentData._to[j] = newIndices[currentData._to[j]]; } else { throw new Error("Trying to update a removed node"); } } } offset = 0; for (let i = 0; i < this._allData.length; i++) { if (this._allData[i].from === -2 && this._allOutputIndices.indexOf(i + offset) === -1) { offset++; this._allData.splice(i, 1); i--; continue; } if (offset > 0) { let ind = -1; if (this._allData[i].from !== void 0 && this._allData[i].from !== -1) { ind = this._nodes[this._allData[i].from].outputs.indexOf(i + offset); if (ind !== -1) { this._nodes[this._allData[i].from].outputs[ind] = i; } } else { ind = this._allInputIndices.indexOf(i + offset); if (ind !== -1) { this._allInputIndices[ind] = i; } } this._allData[i].to.forEach((node) => { ind = this._nodes[node].inputs.indexOf(i + offset); if (ind !== -1) { this._nodes[node].inputs[ind] = i; } }); if (this._allData[i].to.length === 0) { ind = this._allOutputIndices.indexOf(i + offset); if (ind !== -1) { this._allOutputIndices[ind] = i; } } } } } /** * Delete the specified node. Assume the node has one incoming input and the first output connected to other nodes. * An input validation must be done before calling this function. * @param nodeIndex The index of node to be deleted */ deleteNode(nodeIndex) { const node = this._nodes[nodeIndex]; if (node.outputs.length > 1) { for (let i = 1; i < node.outputs.length; i++) { if (this._allData[node.outputs[i]].to.length > 0) { throw new Error("Node deletion with more than one output connected to other nodes is not supported. "); } } } node.executeNode = false; const inputValueIndex = node.inputs[0]; const outputValueIndex = node.outputs[0]; const nodesConsumingOutput = this._allData[outputValueIndex].to; for (let i = 0; i < node.inputs.length; i++) { const delIndex = this._allData[node.inputs[i]].to.indexOf(nodeIndex); if (delIndex === -1) { throw new Error("The Value object doesn't have the current Node in it's 'to' property "); } this._allData[node.inputs[i]].to.splice(delIndex, 1); } this._allData[outputValueIndex]._to = []; const index = this._allOutputIndices.indexOf(outputValueIndex); if (index !== -1) { this._allOutputIndices[index] = inputValueIndex; } if (nodesConsumingOutput && nodesConsumingOutput.length > 0) { for (const nodeIndex2 of nodesConsumingOutput) { const replaceIndex = this._nodes[nodeIndex2].inputs.indexOf(outputValueIndex); if (replaceIndex === -1) { throw new Error("The Node object doesn't have the output Value in it's 'inputs' property "); } this._nodes[nodeIndex2].inputs[replaceIndex] = inputValueIndex; this._allData[inputValueIndex].to.push(nodeIndex2); } } } removeAllDropoutNodes() { let nodeIndex = 0; for (const node of this._nodes) { if (node.opType === "Dropout") { if (node.inputs.length !== 1) { throw new Error("Dropout nodes should only contain one input. "); } if (node.outputs.length !== 1 && node.outputs.length !== 2) { throw new Error("Dropout nodes should contain either 1 or 2 output(s)"); } if (node.outputs.length === 2 && this._allData[node.outputs[1]]._to.length !== 0) { throw new Error("Dropout nodes's second output should not be referenced by other nodes"); } this.deleteNode(nodeIndex); } nodeIndex++; } } removeAllIdentityNodes() { let nodeIndex = 0; for (const node of this._nodes) { if (node.opType === "Identity") { this.deleteNode(nodeIndex); } nodeIndex++; } } isActivation(n) { switch (n.opType) { // TODO: add other activation methods case "Relu": case "Sigmoid": case "Clip": return true; default: return false; } } fuseConvActivationNodes() { for (const node of this._nodes) { if (node.opType === "Conv") { const next = this._allData[node.outputs[0]]._to; if (next.length === 1 && this.isActivation(this._nodes[next[0]])) { const child = this._nodes[next[0]]; if (child.opType === "Clip") { if (child.inputs.length === 1) { try { node.attributes.set("activation_params", "floats", [ child.attributes.getFloat("min"), child.attributes.getFloat("max") ]); } catch { node.attributes.set("activation_params", "floats", [MIN_CLIP, MAX_CLIP]); } } else if (child.inputs.length >= 3 && this._allData[child.inputs[1]].tensor !== void 0 && this._allData[child.inputs[2]].tensor !== void 0) { node.attributes.set("activation_params", "floats", [ this._allData[child.inputs[1]].tensor.floatData[0], this._allData[child.inputs[2]].tensor.floatData[0] ]); } else { continue; } } node.attributes.set("activation", "string", child.opType); this.deleteNode(next[0]); } } } } }; } }); // web/lib/onnxjs/model.ts var flatbuffers, import_onnx5, Model2; var init_model = __esm({ "web/lib/onnxjs/model.ts"() { "use strict"; flatbuffers = __toESM(require_flatbuffers()); init_graph(); init_ort_generated(); import_onnx5 = __toESM(require_onnx()); init_util(); Model2 = class { // empty model constructor() { } load(buf, graphInitializer, isOrtFormat) { let onnxError; if (!isOrtFormat) { try { this.loadFromOnnxFormat(buf, graphInitializer); return; } catch (e) { if (isOrtFormat !== void 0) { throw e; } onnxError = e; } } try { this.loadFromOrtFormat(buf, graphInitializer); } catch (e) { if (isOrtFormat !== void 0) { throw e; } throw new Error(`Failed to load model as ONNX format: ${onnxError} as ORT format: ${e}`); } } loadFromOnnxFormat(buf, graphInitializer) { const modelProto = import_onnx5.onnx.ModelProto.decode(buf); const irVersion = LongUtil.longToNumber(modelProto.irVersion); if (irVersion < 3) { throw new Error("only support ONNX model with IR_VERSION>=3"); } this._opsets = modelProto.opsetImport.map((i) => ({ domain: i.domain, version: LongUtil.longToNumber(i.version) })); this._graph = Graph2.from(modelProto.graph, graphInitializer); } loadFromOrtFormat(buf, graphInitializer) { const fb = new flatbuffers.ByteBuffer(buf); const ortModel = import_inference_session.InferenceSession.getRootAsInferenceSession(fb).model(); const irVersion = LongUtil.longToNumber(ortModel.irVersion()); if (irVersion < 3) { throw new Error("only support ONNX model with IR_VERSION>=3"); } this._opsets = []; for (let i = 0; i < ortModel.opsetImportLength(); i++) { const opsetId = ortModel.opsetImport(i); this._opsets.push({ domain: opsetId?.domain(), version: LongUtil.longToNumber(opsetId.version()) }); } this._graph = Graph2.from(ortModel.graph(), graphInitializer); } get graph() { return this._graph; } get opsets() { return this._opsets; } }; } }); // web/lib/onnxjs/session.ts var Session; var init_session = __esm({ "web/lib/onnxjs/session.ts"() { "use strict"; init_backend2(); init_execution_plan(); init_instrument(); init_model(); Session = class { constructor(config = {}) { this._initialized = false; this.backendHint = config.backendHint; this.profiler = Profiler.create(config.profiler); this.context = { profiler: this.profiler, graphInputTypes: [], graphInputDims: [] }; } get inputNames() { return this._model.graph.getInputNames(); } get outputNames() { return this._model.graph.getOutputNames(); } startProfiling() { this.profiler.start(); } endProfiling() { this.profiler.stop(); } async loadModel(arg, byteOffset, length) { await this.profiler.event("session", "Session.loadModel", async () => { const backend2 = await resolveBackend(this.backendHint); this.sessionHandler = backend2.createSessionHandler(this.context); this._model = new Model2(); if (typeof arg === "string") { const isOrtFormat = arg.endsWith(".ort"); if (false) { const { readFile } = null; const buf = await readFile(arg); this.initialize(buf, isOrtFormat); } else { const response = await fetch(arg); const buf = await response.arrayBuffer(); this.initialize(new Uint8Array(buf), isOrtFormat); } } else if (!ArrayBuffer.isView(arg)) { const arr = new Uint8Array(arg, byteOffset || 0, length || arg.byteLength); this.initialize(arr); } else { this.initialize(arg); } }); } initialize(modelProtoBlob, isOrtFormat) { if (this._initialized) { throw new Error("already initialized"); } this.profiler.event("session", "Session.initialize", () => { const graphInitializer = this.sessionHandler.transformGraph ? this.sessionHandler : void 0; this._model.load(modelProtoBlob, graphInitializer, isOrtFormat); if (this.sessionHandler.onGraphInitialized) { this.sessionHandler.onGraphInitialized(this._model.graph); } this.initializeOps(this._model.graph); this._executionPlan = new ExecutionPlan(this._model.graph, this._ops, this.profiler); }); this._initialized = true; } async run(inputs) { if (!this._initialized) { throw new Error("session not initialized yet"); } return this.profiler.event("session", "Session.run", async () => { const inputTensors = this.normalizeAndValidateInputs(inputs); const outputTensors = await this._executionPlan.execute(this.sessionHandler, inputTensors); return this.createOutput(outputTensors); }); } normalizeAndValidateInputs(inputs) { const modelInputNames = this._model.graph.getInputNames(); if (Array.isArray(inputs)) { if (inputs.length !== modelInputNames.length) { throw new Error(`incorrect input array length: expected ${modelInputNames.length} but got ${inputs.length}`); } } else { if (inputs.size !== modelInputNames.length) { throw new Error(`incorrect input map size: expected ${modelInputNames.length} but got ${inputs.size}`); } const sortedInputs = new Array(inputs.size); let sortedInputsIndex = 0; for (let i = 0; i < modelInputNames.length; ++i) { const tensor = inputs.get(modelInputNames[i]); if (!tensor) { throw new Error(`missing input tensor for: '${name}'`); } sortedInputs[sortedInputsIndex++] = tensor; } inputs = sortedInputs; } if (!this.context.graphInputTypes || this.context.graphInputTypes.length === 0 || !this.context.graphInputDims || this.context.graphInputDims.length === 0) { const modelInputIndices = this._model.graph.getInputIndices(); const modelValues = this._model.graph.getValues(); const graphInputDims = new Array(modelInputIndices.length); for (let i = 0; i < modelInputIndices.length; ++i) { const graphInput = modelValues[modelInputIndices[i]]; graphInputDims[i] = graphInput.type.shape.dims; this.context.graphInputTypes.push(graphInput.type.tensorType); this.context.graphInputDims.push(inputs[i].dims); } this.validateInputTensorDims(graphInputDims, inputs, true); } else { this.validateInputTensorDims(this.context.graphInputDims, inputs, false); } this.validateInputTensorTypes(this.context.graphInputTypes, inputs); return inputs; } validateInputTensorTypes(graphInputTypes, givenInputs) { for (let i = 0; i < givenInputs.length; i++) { const expectedType = graphInputTypes[i]; const actualType = givenInputs[i].type; if (expectedType !== actualType) { throw new Error(`input tensor[${i}] check failed: expected type '${expectedType}' but got ${actualType}`); } } } validateInputTensorDims(graphInputDims, givenInputs, noneDimSupported) { for (let i = 0; i < givenInputs.length; i++) { const expectedDims = graphInputDims[i]; const actualDims = givenInputs[i].dims; if (!this.compareTensorDims(expectedDims, actualDims, noneDimSupported)) { throw new Error( `input tensor[${i}] check failed: expected shape '[${expectedDims.join(",")}]' but got [${actualDims.join( "," )}]` ); } } } compareTensorDims(expectedDims, actualDims, noneDimSupported) { if (expectedDims.length !== actualDims.length) { return false; } for (let i = 0; i < expectedDims.length; ++i) { if (expectedDims[i] !== actualDims[i] && (!noneDimSupported || expectedDims[i] !== 0)) { return false; } } return true; } createOutput(outputTensors) { const modelOutputNames = this._model.graph.getOutputNames(); if (outputTensors.length !== modelOutputNames.length) { throw new Error("expected number of outputs do not match number of generated outputs"); } const output = /* @__PURE__ */ new Map(); for (let i = 0; i < modelOutputNames.length; ++i) { output.set(modelOutputNames[i], outputTensors[i]); } return output; } initializeOps(graph) { const nodes = graph.getNodes(); this._ops = new Array(nodes.length); for (let i = 0; i < nodes.length; i++) { this._ops[i] = this.sessionHandler.resolve(nodes[i], this._model.opsets, graph); } } }; } }); // web/lib/onnxjs/session-handler-inference.ts var OnnxjsSessionHandler; var init_session_handler_inference = __esm({ "web/lib/onnxjs/session-handler-inference.ts"() { "use strict"; init_esm(); init_tensor2(); OnnxjsSessionHandler = class { constructor(session) { this.session = session; this.inputNames = this.session.inputNames; this.outputNames = this.session.outputNames; } get inputMetadata() { throw new Error("Getting model metadata is not supported in webgl backend."); } get outputMetadata() { throw new Error("Getting model metadata is not supported in webgl backend."); } async dispose() { } async run(feeds, _fetches, _options) { const inputMap = /* @__PURE__ */ new Map(); for (const name2 in feeds) { if (Object.hasOwnProperty.call(feeds, name2)) { const feed = feeds[name2]; inputMap.set( name2, new Tensor4( feed.dims, feed.type, void 0, void 0, feed.data ) ); } } const outputMap = await this.session.run(inputMap); const output = {}; outputMap.forEach((tensor, name2) => { output[name2] = new Tensor2(tensor.type, tensor.data, tensor.dims); }); return output; } startProfiling() { this.session.startProfiling(); } endProfiling() { this.session.endProfiling(); } }; } }); // web/lib/backend-onnxjs.ts var backend_onnxjs_exports = {}; __export(backend_onnxjs_exports, { onnxjsBackend: () => onnxjsBackend }); var OnnxjsBackend, onnxjsBackend; var init_backend_onnxjs = __esm({ "web/lib/backend-onnxjs.ts"() { "use strict"; init_session(); init_session_handler_inference(); OnnxjsBackend = class { // eslint-disable-next-line @typescript-eslint/no-empty-function async init() { } async createInferenceSessionHandler(pathOrBuffer, options) { const session = new Session(options); if (typeof pathOrBuffer === "string") { await session.loadModel(pathOrBuffer); } else { await session.loadModel(pathOrBuffer); } return new OnnxjsSessionHandler(session); } }; onnxjsBackend = new OnnxjsBackend(); } }); // web/lib/index.ts init_esm(); init_esm(); init_esm(); // web/lib/version.ts var version2 = "1.26.0"; // web/lib/index.ts var index_default = esm_exports; if (true) { const onnxjsBackend2 = (init_backend_onnxjs(), __toCommonJS(backend_onnxjs_exports)).onnxjsBackend; registerBackend("webgl", onnxjsBackend2, -10); } if (false) { throw new Error( "The current build is specified to enable both JSEP and WebGPU EP. This is not a valid configuration. JSEP and WebGPU EPs cannot be enabled at the same time." ); } if (false) { throw new Error( "The current build is specified to enable WebNN EP without JSEP or WebGPU EP. This is not a valid configuration. WebNN EP requires either JSEP or WebGPU EP to be enabled." ); } if (false) { const wasmBackend = null.wasmBackend; if (false) { registerBackend("webgpu", wasmBackend, 5); } if (false) { registerBackend("webnn", wasmBackend, 5); } registerBackend("cpu", wasmBackend, 10); registerBackend("wasm", wasmBackend, 10); } Object.defineProperty(env2.versions, "web", { value: version2, enumerable: true }); export { InferenceSession2 as InferenceSession, TRACE, TRACE_EVENT_BEGIN, TRACE_EVENT_END, TRACE_FUNC_BEGIN, TRACE_FUNC_END, Tensor2 as Tensor, index_default as default, env2 as env, registerBackend }; /*! Bundled license information: long/index.js: (** * @license * Copyright 2009 The Closure Library Authors * Copyright 2020 Daniel Wirtz / The long.js Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 *) */ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vY29tbW9uL2xpYi9iYWNrZW5kLWltcGwudHMiLCAiLi4vLi4vY29tbW9uL2xpYi9iYWNrZW5kLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvdmVyc2lvbi50cyIsICIuLi8uLi9jb21tb24vbGliL2Vudi1pbXBsLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvZW52LnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvdGVuc29yLWNvbnZlcnNpb24taW1wbC50cyIsICIuLi8uLi9jb21tb24vbGliL3RlbnNvci1mYWN0b3J5LWltcGwudHMiLCAiLi4vLi4vY29tbW9uL2xpYi90ZW5zb3ItaW1wbC10eXBlLW1hcHBpbmcudHMiLCAiLi4vLi4vY29tbW9uL2xpYi90ZW5zb3ItdXRpbHMtaW1wbC50cyIsICIuLi8uLi9jb21tb24vbGliL3RlbnNvci1pbXBsLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvdGVuc29yLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvdHJhY2UudHMiLCAiLi4vLi4vY29tbW9uL2xpYi9pbmZlcmVuY2Utc2Vzc2lvbi1pbXBsLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvaW5mZXJlbmNlLXNlc3Npb24udHMiLCAiLi4vLi4vY29tbW9uL2xpYi90ZW5zb3ItY29udmVyc2lvbi50cyIsICIuLi8uLi9jb21tb24vbGliL3RlbnNvci1mYWN0b3J5LnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvb25ueC1tb2RlbC50cyIsICIuLi8uLi9jb21tb24vbGliL29ubngtdmFsdWUudHMiLCAiLi4vLi4vY29tbW9uL2xpYi9pbmRleC50cyIsICIuLi9saWIvb25ueGpzL2luc3RydW1lbnQudHMiLCAiLi4vbGliL29ubnhqcy9vcHNldC50cyIsICIuLi9ub2RlX21vZHVsZXMvZ3VpZC10eXBlc2NyaXB0L2Rpc3QvZ3VpZC5qcyIsICIuLi9ub2RlX21vZHVsZXMvbG9uZy9pbmRleC5qcyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2FyZy10eXBlLnRzIiwgIi4uL25vZGVfbW9kdWxlcy9mbGF0YnVmZmVycy9qcy9jb25zdGFudHMuanMiLCAiLi4vbm9kZV9tb2R1bGVzL2ZsYXRidWZmZXJzL2pzL3V0aWxzLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9mbGF0YnVmZmVycy9qcy9lbmNvZGluZy5qcyIsICIuLi9ub2RlX21vZHVsZXMvZmxhdGJ1ZmZlcnMvanMvYnl0ZS1idWZmZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL2ZsYXRidWZmZXJzL2pzL2J1aWxkZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL2ZsYXRidWZmZXJzL2pzL2ZsYXRidWZmZXJzLmpzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvYXJnLXR5cGUtYW5kLWluZGV4LnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvYXR0cmlidXRlLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ub2RlLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ub2RlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZWRnZS1lbmQudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ub2RlLWVkZ2UudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ub2Rlcy10by1vcHRpbWl6ZS1pbmRpY2VzLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvcnVudGltZS1vcHRpbWl6YXRpb24tcmVjb3JkLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvcnVudGltZS1vcHRpbWl6YXRpb24tcmVjb3JkLWNvbnRhaW5lci1lbnRyeS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9ucy50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3RlbnNvci1kYXRhLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy90ZW5zb3IudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9zcGFyc2UtdGVuc29yLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbWFwLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9zZXF1ZW5jZS10eXBlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZGltZW5zaW9uLXZhbHVlLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9kaW1lbnNpb24tdmFsdWUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9kaW1lbnNpb24udHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9zaGFwZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3RlbnNvci10eXBlLWFuZC1zaGFwZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3R5cGUtaW5mby12YWx1ZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3R5cGUtaW5mby50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3ZhbHVlLWluZm8udHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ncmFwaC50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2F0dHJpYnV0ZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQta2VybmVsLWNyZWF0ZS1pbmZvcy50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQtbm9kZS1pbmRleC1hbmQta2VybmVsLWRlZi1oYXNoLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZGVwcmVjYXRlZC1zdWItZ3JhcGgtc2Vzc2lvbi1zdGF0ZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQtc2Vzc2lvbi1zdGF0ZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2tlcm5lbC10eXBlLXN0ci1hcmdzLWVudHJ5LnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvb3AtaWQta2VybmVsLXR5cGUtc3RyLWFyZ3MtZW50cnkudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9rZXJuZWwtdHlwZS1zdHItcmVzb2x2ZXIudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9vcGVyYXRvci1zZXQtaWQudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9zdHJpbmctc3RyaW5nLWVudHJ5LnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbW9kZWwudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9pbmZlcmVuY2Utc2Vzc2lvbi50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkLnRzIiwgIi4uL25vZGVfbW9kdWxlcy9AcHJvdG9idWZqcy9hc3Byb21pc2UvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL2Jhc2U2NC9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvZXZlbnRlbWl0dGVyL2luZGV4LmpzIiwgIi4uL25vZGVfbW9kdWxlcy9AcHJvdG9idWZqcy9mbG9hdC9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvaW5xdWlyZS9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvdXRmOC9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvcG9vbC9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvdXRpbC9sb25nYml0cy5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvdXRpbC9taW5pbWFsLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy93cml0ZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3dyaXRlcl9idWZmZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3JlYWRlci5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvcmVhZGVyX2J1ZmZlci5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvcnBjL3NlcnZpY2UuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3JwYy5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvcm9vdHMuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL2luZGV4LW1pbmltYWwuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvbWluaW1hbC5qcyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvcHJvdG9idWYvb25ueC5qcyIsICIuLi9saWIvb25ueGpzL3V0aWwudHMiLCAiLi4vbGliL29ubnhqcy90ZW5zb3IudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLXNvdXJjZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3R5cGVzLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvdXRpbHMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcGFja2luZy11dGlscy50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9wYWNrLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Jlc2hhcGUtcGFja2VkLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3VpbnQ4LWVuY29kZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy91bnBhY2sudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90ZXh0dXJlLWRhdGEtZW5jb2Rlci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3RleHR1cmUtbGF5b3V0LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvaW5mZXJlbmNlLWhhbmRsZXIudHMiLCAiLi4vbGliL29ubnhqcy9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXkudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvYmF0Y2gtbm9ybWFsaXphdGlvbi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtZGVmaW5pdGlvbnMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvYmluYXJ5LW9wLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2Nhc3QudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29uY2F0LXBhY2tlZC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb25jYXQudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdW5hcnktb3AudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZnVzZS11dGlscy50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb252LWdyb3VwZWQudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvaW0yY29sLXBhY2sudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvbWF0bXVsLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL21hdG11bC1wYWNrLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2NvbnYtcGFjay50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9pbTJjb2wudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZG90LXByb2R1Y3QudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29udi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb252LXRyYW5zcG9zZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy90cmFuc3Bvc2UudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZGVwdGgtdG8tc3BhY2UudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZmxhdHRlbi50cyIsICIuLi9saWIvb25ueGpzL29wZXJhdG9ycy50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9nYXRoZXIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZ2VtbS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9pbWFnZS1zY2FsZXIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvaW5zdGFuY2Utbm9ybWFsaXphdGlvbi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9scm4udHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcGFkLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Bvb2wudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcmVkdWNlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Jlc2hhcGUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdXBzYW1wbGUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcmVzaXplLXBhY2tlZC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zaGFwZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zbGljZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zb2Z0bWF4LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3NwbGl0LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3NxdWVlemUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc3VtLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3RpbGUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdW5zcXVlZXplLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3AtcmVzb2x2ZS1ydWxlcy50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtZnVuY3Rpb24taW5saW5lci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3RleHR1cmUtbGF5b3V0LXN0cmF0ZWd5LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1jb29yZGluYXRlLWxpYi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtZW5jb2RpbmctbGliLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1mcmFnY29sb3ItbGliLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1zaGFwZS11dGlscy1saWIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLXZlYy1saWIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLXJlZ2lzdGVyZWQtbGlicy50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtcHJlcHJvY2Vzc29yLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvcHJvZ3JhbS1tYW5hZ2VyLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvdGV4dHVyZS1tYW5hZ2VyLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvc2Vzc2lvbi1oYW5kbGVyLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvd2ViZ2wtY29udGV4dC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3dlYmdsLWNvbnRleHQtZmFjdG9yeS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL2JhY2tlbmQtd2ViZ2wudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kLnRzIiwgIi4uL2xpYi9vbm54anMvZXhlY3V0aW9uLXBsYW4udHMiLCAiLi4vbGliL29ubnhqcy9hdHRyaWJ1dGUudHMiLCAiLi4vbGliL29ubnhqcy9ncmFwaC50cyIsICIuLi9saWIvb25ueGpzL21vZGVsLnRzIiwgIi4uL2xpYi9vbm54anMvc2Vzc2lvbi50cyIsICIuLi9saWIvb25ueGpzL3Nlc3Npb24taGFuZGxlci1pbmZlcmVuY2UudHMiLCAiLi4vbGliL2JhY2tlbmQtb25ueGpzLnRzIiwgIi4uL2xpYi9pbmRleC50cyIsICIuLi9saWIvdmVyc2lvbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEJhY2tlbmQgfSBmcm9tICcuL2JhY2tlbmQuanMnO1xuaW1wb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbiB9IGZyb20gJy4vaW5mZXJlbmNlLXNlc3Npb24uanMnO1xuXG5pbnRlcmZhY2UgQmFja2VuZEluZm8ge1xuICBiYWNrZW5kOiBCYWNrZW5kO1xuICBwcmlvcml0eTogbnVtYmVyO1xuXG4gIGluaXRQcm9taXNlPzogUHJvbWlzZTx2b2lkPjtcbiAgaW5pdGlhbGl6ZWQ/OiBib29sZWFuO1xuICBhYm9ydGVkPzogYm9vbGVhbjtcbiAgZXJyb3I/OiBzdHJpbmc7XG59XG5cbmNvbnN0IGJhY2tlbmRzOiBNYXA8c3RyaW5nLCBCYWNrZW5kSW5mbz4gPSBuZXcgTWFwKCk7XG5jb25zdCBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHk6IHN0cmluZ1tdID0gW107XG5cbi8qKlxuICogUmVnaXN0ZXIgYSBiYWNrZW5kLlxuICpcbiAqIEBwYXJhbSBuYW1lIC0gdGhlIG5hbWUgYXMgYSBrZXkgdG8gbG9va3VwIGFzIGFuIGV4ZWN1dGlvbiBwcm92aWRlci5cbiAqIEBwYXJhbSBiYWNrZW5kIC0gdGhlIGJhY2tlbmQgb2JqZWN0LlxuICogQHBhcmFtIHByaW9yaXR5IC0gYW4gaW50ZWdlciBpbmRpY2F0aW5nIHRoZSBwcmlvcml0eSBvZiB0aGUgYmFja2VuZC4gSGlnaGVyIG51bWJlciBtZWFucyBoaWdoZXIgcHJpb3JpdHkuIGlmIHByaW9yaXR5XG4gKiA8IDAsIGl0IHdpbGwgYmUgY29uc2lkZXJlZCBhcyBhICdiZXRhJyB2ZXJzaW9uIGFuZCB3aWxsIG5vdCBiZSB1c2VkIGFzIGEgZmFsbGJhY2sgYmFja2VuZCBieSBkZWZhdWx0LlxuICpcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGNvbnN0IHJlZ2lzdGVyQmFja2VuZCA9IChuYW1lOiBzdHJpbmcsIGJhY2tlbmQ6IEJhY2tlbmQsIHByaW9yaXR5OiBudW1iZXIpOiB2b2lkID0+IHtcbiAgaWYgKGJhY2tlbmQgJiYgdHlwZW9mIGJhY2tlbmQuaW5pdCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgYmFja2VuZC5jcmVhdGVJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IGN1cnJlbnRCYWNrZW5kID0gYmFja2VuZHMuZ2V0KG5hbWUpO1xuICAgIGlmIChjdXJyZW50QmFja2VuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBiYWNrZW5kcy5zZXQobmFtZSwgeyBiYWNrZW5kLCBwcmlvcml0eSB9KTtcbiAgICB9IGVsc2UgaWYgKGN1cnJlbnRCYWNrZW5kLnByaW9yaXR5ID4gcHJpb3JpdHkpIHtcbiAgICAgIC8vIHNhbWUgbmFtZSBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQgd2l0aCBhIGhpZ2hlciBwcmlvcml0eS4gc2tpcCByZWdpc3RlcmF0aW9uLlxuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAoY3VycmVudEJhY2tlbmQucHJpb3JpdHkgPT09IHByaW9yaXR5KSB7XG4gICAgICBpZiAoY3VycmVudEJhY2tlbmQuYmFja2VuZCAhPT0gYmFja2VuZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCByZWdpc3RlciBiYWNrZW5kIFwiJHtuYW1lfVwiIHVzaW5nIHByaW9yaXR5ICR7cHJpb3JpdHl9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHByaW9yaXR5ID49IDApIHtcbiAgICAgIGNvbnN0IGkgPSBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHkuaW5kZXhPZihuYW1lKTtcbiAgICAgIGlmIChpICE9PSAtMSkge1xuICAgICAgICBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHkuc3BsaWNlKGksIDEpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoYmFja2VuZHMuZ2V0KGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eVtpXSkhLnByaW9yaXR5IDw9IHByaW9yaXR5KSB7XG4gICAgICAgICAgYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5LnNwbGljZShpLCAwLCBuYW1lKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eS5wdXNoKG5hbWUpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdub3QgYSB2YWxpZCBiYWNrZW5kJyk7XG59O1xuXG4vKipcbiAqIFRyeSB0byByZXNvbHZlIGFuZCBpbml0aWFsaXplIGEgYmFja2VuZC5cbiAqXG4gKiBAcGFyYW0gYmFja2VuZE5hbWUgLSB0aGUgbmFtZSBvZiB0aGUgYmFja2VuZC5cbiAqIEByZXR1cm5zIHRoZSBiYWNrZW5kIGluc3RhbmNlIGlmIHJlc29sdmVkIGFuZCBpbml0aWFsaXplZCBzdWNjZXNzZnVsbHksIG9yIGFuIGVycm9yIG1lc3NhZ2UgaWYgZmFpbGVkLlxuICovXG5jb25zdCB0cnlSZXNvbHZlQW5kSW5pdGlhbGl6ZUJhY2tlbmQgPSBhc3luYyAoYmFja2VuZE5hbWU6IHN0cmluZyk6IFByb21pc2U8QmFja2VuZCB8IHN0cmluZz4gPT4ge1xuICBjb25zdCBiYWNrZW5kSW5mbyA9IGJhY2tlbmRzLmdldChiYWNrZW5kTmFtZSk7XG4gIGlmICghYmFja2VuZEluZm8pIHtcbiAgICByZXR1cm4gJ2JhY2tlbmQgbm90IGZvdW5kLic7XG4gIH1cblxuICBpZiAoYmFja2VuZEluZm8uaW5pdGlhbGl6ZWQpIHtcbiAgICByZXR1cm4gYmFja2VuZEluZm8uYmFja2VuZDtcbiAgfSBlbHNlIGlmIChiYWNrZW5kSW5mby5hYm9ydGVkKSB7XG4gICAgcmV0dXJuIGJhY2tlbmRJbmZvLmVycm9yITtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBpc0luaXRpYWxpemluZyA9ICEhYmFja2VuZEluZm8uaW5pdFByb21pc2U7XG4gICAgdHJ5IHtcbiAgICAgIGlmICghaXNJbml0aWFsaXppbmcpIHtcbiAgICAgICAgYmFja2VuZEluZm8uaW5pdFByb21pc2UgPSBiYWNrZW5kSW5mby5iYWNrZW5kLmluaXQoYmFja2VuZE5hbWUpO1xuICAgICAgfVxuICAgICAgYXdhaXQgYmFja2VuZEluZm8uaW5pdFByb21pc2U7XG4gICAgICBiYWNrZW5kSW5mby5pbml0aWFsaXplZCA9IHRydWU7XG4gICAgICByZXR1cm4gYmFja2VuZEluZm8uYmFja2VuZDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoIWlzSW5pdGlhbGl6aW5nKSB7XG4gICAgICAgIGJhY2tlbmRJbmZvLmVycm9yID0gYCR7ZX1gO1xuICAgICAgICBiYWNrZW5kSW5mby5hYm9ydGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYWNrZW5kSW5mby5lcnJvciE7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGRlbGV0ZSBiYWNrZW5kSW5mby5pbml0UHJvbWlzZTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogUmVzb2x2ZSBleGVjdXRpb24gcHJvdmlkZXJzIGZyb20gdGhlIHNwZWNpZmljIHNlc3Npb24gb3B0aW9ucy5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIHRoZSBzZXNzaW9uIG9wdGlvbnMgb2JqZWN0LlxuICogQHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSB0dXBsZSBvZiBhbiBpbml0aWFsaXplZCBiYWNrZW5kIGluc3RhbmNlIGFuZCBhIHNlc3Npb24gb3B0aW9ucyBvYmplY3Qgd2l0aFxuICogZmlsdGVyZWQgRVAgbGlzdC5cbiAqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCByZXNvbHZlQmFja2VuZEFuZEV4ZWN1dGlvblByb3ZpZGVycyA9IGFzeW5jIChcbiAgb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyxcbik6IFByb21pc2U8W2JhY2tlbmQ6IEJhY2tlbmQsIG9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnNdPiA9PiB7XG4gIC8vIGV4dHJhY3QgYmFja2VuZCBoaW50cyBmcm9tIHNlc3Npb24gb3B0aW9uc1xuICBjb25zdCBlcHMgPSBvcHRpb25zLmV4ZWN1dGlvblByb3ZpZGVycyB8fCBbXTtcbiAgY29uc3QgYmFja2VuZEhpbnRzID0gZXBzLm1hcCgoaSkgPT4gKHR5cGVvZiBpID09PSAnc3RyaW5nJyA/IGkgOiBpLm5hbWUpKTtcbiAgY29uc3QgYmFja2VuZE5hbWVzID0gYmFja2VuZEhpbnRzLmxlbmd0aCA9PT0gMCA/IGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eSA6IGJhY2tlbmRIaW50cztcblxuICAvLyB0cnkgdG8gcmVzb2x2ZSBhbmQgaW5pdGlhbGl6ZSBhbGwgcmVxdWVzdGVkIGJhY2tlbmRzXG4gIGxldCBiYWNrZW5kOiBCYWNrZW5kIHwgdW5kZWZpbmVkO1xuICBjb25zdCBlcnJvcnMgPSBbXTtcbiAgY29uc3QgYXZhaWxhYmxlQmFja2VuZE5hbWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGZvciAoY29uc3QgYmFja2VuZE5hbWUgb2YgYmFja2VuZE5hbWVzKSB7XG4gICAgY29uc3QgcmVzb2x2ZVJlc3VsdCA9IGF3YWl0IHRyeVJlc29sdmVBbmRJbml0aWFsaXplQmFja2VuZChiYWNrZW5kTmFtZSk7XG4gICAgaWYgKHR5cGVvZiByZXNvbHZlUmVzdWx0ID09PSAnc3RyaW5nJykge1xuICAgICAgZXJyb3JzLnB1c2goeyBuYW1lOiBiYWNrZW5kTmFtZSwgZXJyOiByZXNvbHZlUmVzdWx0IH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIWJhY2tlbmQpIHtcbiAgICAgICAgYmFja2VuZCA9IHJlc29sdmVSZXN1bHQ7XG4gICAgICB9XG4gICAgICBpZiAoYmFja2VuZCA9PT0gcmVzb2x2ZVJlc3VsdCkge1xuICAgICAgICBhdmFpbGFibGVCYWNrZW5kTmFtZXMuYWRkKGJhY2tlbmROYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBpZiBubyBiYWNrZW5kIGlzIGF2YWlsYWJsZSwgdGhyb3cgZXJyb3IuXG4gIGlmICghYmFja2VuZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgbm8gYXZhaWxhYmxlIGJhY2tlbmQgZm91bmQuIEVSUjogJHtlcnJvcnMubWFwKChlKSA9PiBgWyR7ZS5uYW1lfV0gJHtlLmVycn1gKS5qb2luKCcsICcpfWApO1xuICB9XG5cbiAgLy8gZm9yIGVhY2ggZXhwbGljaXRseSByZXF1ZXN0ZWQgYmFja2VuZCwgaWYgaXQncyBub3QgYXZhaWxhYmxlLCBvdXRwdXQgd2FybmluZyBtZXNzYWdlLlxuICBmb3IgKGNvbnN0IHsgbmFtZSwgZXJyIH0gb2YgZXJyb3JzKSB7XG4gICAgaWYgKGJhY2tlbmRIaW50cy5pbmNsdWRlcyhuYW1lKSkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYHJlbW92aW5nIHJlcXVlc3RlZCBleGVjdXRpb24gcHJvdmlkZXIgXCIke25hbWV9XCIgZnJvbSBzZXNzaW9uIG9wdGlvbnMgYmVjYXVzZSBpdCBpcyBub3QgYXZhaWxhYmxlOiAke2Vycn1gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBmaWx0ZXJlZEVwcyA9IGVwcy5maWx0ZXIoKGkpID0+IGF2YWlsYWJsZUJhY2tlbmROYW1lcy5oYXModHlwZW9mIGkgPT09ICdzdHJpbmcnID8gaSA6IGkubmFtZSkpO1xuXG4gIHJldHVybiBbXG4gICAgYmFja2VuZCxcbiAgICBuZXcgUHJveHkob3B0aW9ucywge1xuICAgICAgZ2V0OiAodGFyZ2V0LCBwcm9wKSA9PiB7XG4gICAgICAgIGlmIChwcm9wID09PSAnZXhlY3V0aW9uUHJvdmlkZXJzJykge1xuICAgICAgICAgIHJldHVybiBmaWx0ZXJlZEVwcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wKTtcbiAgICAgIH0sXG4gICAgfSksXG4gIF07XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBJbmZlcmVuY2VTZXNzaW9uIH0gZnJvbSAnLi9pbmZlcmVuY2Utc2Vzc2lvbi5qcyc7XG5pbXBvcnQgeyBPbm54VmFsdWUgfSBmcm9tICcuL29ubngtdmFsdWUuanMnO1xuXG4vKipcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIFNlc3Npb25IYW5kbGVyIHtcbiAgdHlwZSBGZWVkc1R5cGUgPSB7IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfTtcbiAgdHlwZSBGZXRjaGVzVHlwZSA9IHsgW25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZSB8IG51bGwgfTtcbiAgdHlwZSBSZXR1cm5UeXBlID0geyBbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlIH07XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBzaGFyZWQgU2Vzc2lvbkhhbmRsZXIgZnVuY3Rpb25hbGl0eVxuICpcbiAqIEBpZ25vcmVcbiAqL1xuaW50ZXJmYWNlIFNlc3Npb25IYW5kbGVyIHtcbiAgZGlzcG9zZSgpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIHJlYWRvbmx5IGlucHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICByZWFkb25seSBvdXRwdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG5cbiAgcmVhZG9ubHkgaW5wdXRNZXRhZGF0YTogcmVhZG9ubHkgSW5mZXJlbmNlU2Vzc2lvbi5WYWx1ZU1ldGFkYXRhW107XG4gIHJlYWRvbmx5IG91dHB1dE1ldGFkYXRhOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXTtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnQgYSBoYW5kbGVyIGluc3RhbmNlIG9mIGFuIGluZmVyZW5jZSBzZXNzaW9uLlxuICpcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciBleHRlbmRzIFNlc3Npb25IYW5kbGVyIHtcbiAgc3RhcnRQcm9maWxpbmcoKTogdm9pZDtcbiAgZW5kUHJvZmlsaW5nKCk6IHZvaWQ7XG5cbiAgcnVuKFxuICAgIGZlZWRzOiBTZXNzaW9uSGFuZGxlci5GZWVkc1R5cGUsXG4gICAgZmV0Y2hlczogU2Vzc2lvbkhhbmRsZXIuRmV0Y2hlc1R5cGUsXG4gICAgb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zLFxuICApOiBQcm9taXNlPFNlc3Npb25IYW5kbGVyLlJldHVyblR5cGU+O1xufVxuXG4vKipcbiAqIFJlcHJlc2VudCBhIGJhY2tlbmQgdGhhdCBwcm92aWRlcyBpbXBsZW1lbnRhdGlvbiBvZiBtb2RlbCBpbmZlcmVuY2luZy5cbiAqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmFja2VuZCB7XG4gIC8qKlxuICAgKiBJbml0aWFsaXplIHRoZSBiYWNrZW5kIGFzeW5jaHJvbm91c2x5LiBTaG91bGQgdGhyb3cgd2hlbiBmYWlsZWQuXG4gICAqL1xuICBpbml0KGJhY2tlbmROYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIGNyZWF0ZUluZmVyZW5jZVNlc3Npb25IYW5kbGVyKFxuICAgIHVyaU9yQnVmZmVyOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25IYW5kbGVyPjtcbn1cblxuZXhwb3J0IHsgcmVnaXN0ZXJCYWNrZW5kIH0gZnJvbSAnLi9iYWNrZW5kLWltcGwuanMnO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vLyBUaGlzIGZpbGUgaXMgZ2VuZXJhdGVkIGJ5IC9qcy9zY3JpcHRzL3VwZGF0ZS12ZXJzaW9uLnRzXG4vLyBEbyBub3QgbW9kaWZ5IGZpbGUgY29udGVudCBtYW51YWxseS5cblxuZXhwb3J0IGNvbnN0IHZlcnNpb24gPSAnMS4yNi4wJztcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRW52IH0gZnJvbSAnLi9lbnYuanMnO1xuaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4vdmVyc2lvbi5qcyc7XG5cbnR5cGUgTG9nTGV2ZWxUeXBlID0gRW52Wydsb2dMZXZlbCddO1xuXG5sZXQgbG9nTGV2ZWxWYWx1ZTogUmVxdWlyZWQ8TG9nTGV2ZWxUeXBlPiA9ICd3YXJuaW5nJztcblxuZXhwb3J0IGNvbnN0IGVudjogRW52ID0ge1xuICB3YXNtOiB7fSBhcyBFbnYuV2ViQXNzZW1ibHlGbGFncyxcbiAgd2ViZ2w6IHt9IGFzIEVudi5XZWJHTEZsYWdzLFxuICB3ZWJncHU6IHt9IGFzIEVudi5XZWJHcHVGbGFncyxcbiAgdmVyc2lvbnM6IHsgY29tbW9uOiB2ZXJzaW9uIH0sXG5cbiAgc2V0IGxvZ0xldmVsKHZhbHVlOiBMb2dMZXZlbFR5cGUpIHtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJyB8fCBbJ3ZlcmJvc2UnLCAnaW5mbycsICd3YXJuaW5nJywgJ2Vycm9yJywgJ2ZhdGFsJ10uaW5kZXhPZih2YWx1ZSkgPT09IC0xKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGxvZ2dpbmcgbGV2ZWw6ICR7dmFsdWV9YCk7XG4gICAgfVxuICAgIGxvZ0xldmVsVmFsdWUgPSB2YWx1ZTtcbiAgfSxcbiAgZ2V0IGxvZ0xldmVsKCk6IFJlcXVpcmVkPExvZ0xldmVsVHlwZT4ge1xuICAgIHJldHVybiBsb2dMZXZlbFZhbHVlO1xuICB9LFxufTtcblxuLy8gc2V0IHByb3BlcnR5ICdsb2dMZXZlbCcgc28gdGhhdCB0aGV5IGNhbiBiZSBjb3JyZWN0bHkgdHJhbnNmZXJyZWQgdG8gd29ya2VyIGJ5IGBwb3N0TWVzc2FnZSgpYC5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbnYsICdsb2dMZXZlbCcsIHsgZW51bWVyYWJsZTogdHJ1ZSB9KTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZW52IGFzIGVudkltcGwgfSBmcm9tICcuL2Vudi1pbXBsLmpzJztcbmltcG9ydCB7IFRyeUdldEdsb2JhbFR5cGUgfSBmcm9tICcuL3R5cGUtaGVscGVyLmpzJztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIEVudiB7XG4gIGV4cG9ydCB0eXBlIFdhc21QYXRoUHJlZml4ID0gc3RyaW5nO1xuICBleHBvcnQgaW50ZXJmYWNlIFdhc21GaWxlUGF0aHMge1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgdGhlIG92ZXJyaWRlIHBhdGggZm9yIHRoZSBtYWluIC53YXNtIGZpbGUuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhdGggc2hvdWxkIGJlIGFuIGFic29sdXRlIHBhdGguXG4gICAgICpcbiAgICAgKiBJZiBub3QgbW9kaWZpZWQsIHRoZSBmaWxlbmFtZSBvZiB0aGUgLndhc20gZmlsZSBpczpcbiAgICAgKiAtIGBvcnQtd2FzbS1zaW1kLXRocmVhZGVkLndhc21gIGZvciBkZWZhdWx0IGJ1aWxkXG4gICAgICogLSBgb3J0LXdhc20tc2ltZC10aHJlYWRlZC5qc2VwLndhc21gIGZvciBKU0VQIGJ1aWxkICh3aXRoIFdlYkdQVSBhbmQgV2ViTk4pXG4gICAgICogLSBgb3J0LXdhc20tc2ltZC10aHJlYWRlZC5hc3luY2lmeS53YXNtYCBmb3IgV2ViR1BVIGJ1aWxkIHdpdGggQXN5bmNpZnkgKHdpdGggV2ViTk4pXG4gICAgICogLSBgb3J0LXdhc20tc2ltZC10aHJlYWRlZC5qc3BpLndhc21gIGZvciBXZWJHUFUgYnVpbGQgd2l0aCBKU1BJIHN1cHBvcnQgKHdpdGggV2ViTk4pXG4gICAgICovXG4gICAgd2FzbT86IFVSTCB8IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHRoZSBvdmVycmlkZSBwYXRoIGZvciB0aGUgbWFpbiAubWpzIGZpbGUuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhdGggc2hvdWxkIGJlIGFuIGFic29sdXRlIHBhdGguXG4gICAgICpcbiAgICAgKiBJZiBub3QgbW9kaWZpZWQsIHRoZSBmaWxlbmFtZSBvZiB0aGUgLm1qcyBmaWxlIGlzOlxuICAgICAqIC0gYG9ydC13YXNtLXNpbWQtdGhyZWFkZWQubWpzYCBmb3IgZGVmYXVsdCBidWlsZFxuICAgICAqIC0gYG9ydC13YXNtLXNpbWQtdGhyZWFkZWQuanNlcC5tanNgIGZvciBKU0VQIGJ1aWxkICh3aXRoIFdlYkdQVSBhbmQgV2ViTk4pXG4gICAgICogLSBgb3J0LXdhc20tc2ltZC10aHJlYWRlZC5hc3luY2lmeS5tanNgIGZvciBXZWJHUFUgYnVpbGQgd2l0aCBBc3luY2lmeSAod2l0aCBXZWJOTilcbiAgICAgKiAtIGBvcnQtd2FzbS1zaW1kLXRocmVhZGVkLmpzcGkubWpzYCBmb3IgV2ViR1BVIGJ1aWxkIHdpdGggSlNQSSBzdXBwb3J0ICh3aXRoIFdlYk5OKVxuICAgICAqL1xuICAgIG1qcz86IFVSTCB8IHN0cmluZztcbiAgfVxuICBleHBvcnQgdHlwZSBXYXNtUHJlZml4T3JGaWxlUGF0aHMgPSBXYXNtUGF0aFByZWZpeCB8IFdhc21GaWxlUGF0aHM7XG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViQXNzZW1ibHlGbGFncyB7XG4gICAgLyoqXG4gICAgICogc2V0IG9yIGdldCBudW1iZXIgb2YgdGhyZWFkKHMpLiBJZiBvbWl0dGVkIG9yIHNldCB0byAwLCBudW1iZXIgb2YgdGhyZWFkKHMpIHdpbGwgYmUgZGV0ZXJtaW5lZCBieSBzeXN0ZW0uIElmIHNldFxuICAgICAqIHRvIDEsIG5vIHdvcmtlciB0aHJlYWQgd2lsbCBiZSBzcGF3bmVkLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IHdoZW4gV2ViQXNzZW1ibHkgbXVsdGl0aHJlYWQgZmVhdHVyZSBpcyBhdmFpbGFibGUgaW4gY3VycmVudCBjb250ZXh0LlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgMGBcbiAgICAgKi9cbiAgICBudW1UaHJlYWRzPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogc2V0IGEgdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRvIGVuYWJsZSBTSU1ELlxuICAgICAqXG4gICAgICogT05OWCBSdW50aW1lIHdpbGwgcGVyZm9ybSBmZWF0dXJlIGRldGVjdGlvbiBiYXNlZCBvbiB0aGUgdmFsdWUgb2YgdGhpcyBwcm9wZXJ0eS4gU3BlY2lmaWNhbGx5LCB3aGVuIHRoZSB2YWx1ZSBpc1xuICAgICAqIHNldCB0bzpcbiAgICAgKiAtIGB1bmRlZmluZWRgLCBgdHJ1ZWAgb3IgYFwiZml4ZWRcImA6IHdpbGwgY2hlY2sgYXZhaWxhYmlsaXR5IG9mIEZpeGVkLXdpZHRoIFNJTUQuXG4gICAgICogLSBgXCJyZWxheGVkXCJgOiB3aWxsIGNoZWNrIGF2YWlsYWJpbGl0eSBvZiBSZWxheGVkIFNJTUQuXG4gICAgICogLSBgZmFsc2VgOiB3aWxsIG5vdCBwZXJmb3JtIFNJTUQgZmVhdHVyZSBjaGVja2luZy5cbiAgICAgKlxuICAgICAqIFNldHRpbmcgdGhpcyBwcm9wZXJ0eSBkb2VzIG5vdCBtYWtlIE9OTlggUnVudGltZSB0byBzd2l0Y2ggdG8gdGhlIGNvcnJlc3BvbmRpbmcgcnVudGltZSBhdXRvbWF0aWNhbGx5LiBVc2VyIG5lZWRcbiAgICAgKiB0byBzZXQgYHdhc21QYXRoc2Agb3IgYHdhc21CaW5hcnlgIHByb3BlcnR5IHRvIGxvYWQgdGhlIGNvcnJlc3BvbmRpbmcgcnVudGltZS5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSB3aGVuIFdlYkFzc2VtYmx5IFNJTUQgZmVhdHVyZSBpcyBhdmFpbGFibGUgaW4gY3VycmVudCBjb250ZXh0LlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgdHJ1ZWBcbiAgICAgKi9cbiAgICBzaW1kPzogYm9vbGVhbiB8ICdmaXhlZCcgfCAncmVsYXhlZCc7XG5cbiAgICAvKipcbiAgICAgKiBzZXQgb3IgZ2V0IGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gZW5hYmxlIHRyYWNlLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAgICpcbiAgICAgKiBAZGVwcmVjYXRlZCBVc2UgYGVudi50cmFjZWAgaW5zdGVhZC4gSWYgYGVudi50cmFjZWAgaXMgc2V0LCB0aGlzIHByb3BlcnR5IHdpbGwgYmUgaWdub3JlZC5cbiAgICAgKi9cbiAgICB0cmFjZT86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IGEgbnVtYmVyIHNwZWNpZnlpbmcgdGhlIHRpbWVvdXQgZm9yIGluaXRpYWxpemF0aW9uIG9mIFdlYkFzc2VtYmx5IGJhY2tlbmQsIGluIG1pbGxpc2Vjb25kcy4gQSB6ZXJvXG4gICAgICogdmFsdWUgaW5kaWNhdGVzIG5vIHRpbWVvdXQgaXMgc2V0LlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgMGBcbiAgICAgKi9cbiAgICBpbml0VGltZW91dD86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFNldCBhIGN1c3RvbSBVUkwgcHJlZml4IHRvIHRoZSAud2FzbS8ubWpzIGZpbGVzLCBvciBhbiBvYmplY3Qgb2Ygb3ZlcnJpZGVzIGZvciBib3RoIC53YXNtLy5tanMgZmlsZS4gVGhlIG92ZXJyaWRlXG4gICAgICogcGF0aCBzaG91bGQgYmUgYW4gYWJzb2x1dGUgcGF0aC5cbiAgICAgKi9cbiAgICB3YXNtUGF0aHM/OiBXYXNtUHJlZml4T3JGaWxlUGF0aHM7XG5cbiAgICAvKipcbiAgICAgKiBTZXQgYSBjdXN0b20gYnVmZmVyIHdoaWNoIGNvbnRhaW5zIHRoZSBXZWJBc3NlbWJseSBiaW5hcnkuIElmIHRoaXMgcHJvcGVydHkgaXMgc2V0LCB0aGUgYHdhc21QYXRoc2AgcHJvcGVydHkgd2lsbFxuICAgICAqIGJlIGlnbm9yZWQuXG4gICAgICovXG4gICAgd2FzbUJpbmFyeT86IEFycmF5QnVmZmVyTGlrZSB8IFVpbnQ4QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gcHJveHkgdGhlIGV4ZWN1dGlvbiBvZiBtYWluIHRocmVhZCB0byBhIHdvcmtlciB0aHJlYWQuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICAgKi9cbiAgICBwcm94eT86IGJvb2xlYW47XG4gIH1cblxuICBleHBvcnQgaW50ZXJmYWNlIFdlYkdMRmxhZ3Mge1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIFdlYkdMIENvbnRleHQgSUQgKHdlYmdsIG9yIHdlYmdsMikuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGAnd2ViZ2wyJ2BcbiAgICAgKi9cbiAgICBjb250ZXh0SWQ/OiAnd2ViZ2wnIHwgJ3dlYmdsMic7XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBXZWJHTCByZW5kZXJpbmcgY29udGV4dC5cbiAgICAgKi9cbiAgICByZWFkb25seSBjb250ZXh0OiBXZWJHTFJlbmRlcmluZ0NvbnRleHQ7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgbWF4aW11bSBiYXRjaCBzaXplIGZvciBtYXRtdWwuIDAgbWVhbnMgdG8gZGlzYWJsZSBiYXRjaGluZy5cbiAgICAgKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICovXG4gICAgbWF0bXVsTWF4QmF0Y2hTaXplPzogbnVtYmVyO1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIHRleHR1cmUgY2FjaGUgbW9kZS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYCdmdWxsJ2BcbiAgICAgKi9cbiAgICB0ZXh0dXJlQ2FjaGVNb2RlPzogJ2luaXRpYWxpemVyT25seScgfCAnZnVsbCc7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgcGFja2VkIHRleHR1cmUgbW9kZVxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAgICovXG4gICAgcGFjaz86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB3aGV0aGVyIGVuYWJsZSBhc3luYyBkb3dubG9hZC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgICAqL1xuICAgIGFzeW5jPzogYm9vbGVhbjtcbiAgfVxuXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViR3B1UHJvZmlsaW5nRGF0YVYxVGVuc29yTWV0YWRhdGEge1xuICAgIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICAgIGRhdGFUeXBlOiBzdHJpbmc7XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJHcHVQcm9maWxpbmdEYXRhVjEge1xuICAgIHZlcnNpb246IDE7XG4gICAgaW5wdXRzTWV0YWRhdGE6IHJlYWRvbmx5IFdlYkdwdVByb2ZpbGluZ0RhdGFWMVRlbnNvck1ldGFkYXRhW107XG4gICAgb3V0cHV0c01ldGFkYXRhOiByZWFkb25seSBXZWJHcHVQcm9maWxpbmdEYXRhVjFUZW5zb3JNZXRhZGF0YVtdO1xuICAgIGtlcm5lbElkOiBudW1iZXI7XG4gICAga2VybmVsVHlwZTogc3RyaW5nO1xuICAgIGtlcm5lbE5hbWU6IHN0cmluZztcbiAgICBwcm9ncmFtTmFtZTogc3RyaW5nO1xuICAgIHN0YXJ0VGltZTogbnVtYmVyO1xuICAgIGVuZFRpbWU6IG51bWJlcjtcbiAgfVxuXG4gIGV4cG9ydCB0eXBlIFdlYkdwdVByb2ZpbGluZ0RhdGEgPSBXZWJHcHVQcm9maWxpbmdEYXRhVjE7XG5cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJHcHVGbGFncyB7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgcHJvZmlsaW5nIG1vZGUuXG4gICAgICpcbiAgICAgKiBAZGVwcmVjYXRlZCBVc2UgYGVudi53ZWJncHUucHJvZmlsaW5nLm1vZGVgIGluc3RlYWQuIElmIGBlbnYud2ViZ3B1LnByb2ZpbGluZy5tb2RlYCBpcyBzZXQsIHRoaXMgcHJvcGVydHkgd2lsbCBiZVxuICAgICAqIGlnbm9yZWQuXG4gICAgICovXG4gICAgcHJvZmlsaW5nTW9kZT86ICdvZmYnIHwgJ2RlZmF1bHQnO1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIHByb2ZpbGluZyBjb25maWd1cmF0aW9uLlxuICAgICAqL1xuICAgIHByb2ZpbGluZzoge1xuICAgICAgLyoqXG4gICAgICAgKiBTZXQgb3IgZ2V0IHRoZSBwcm9maWxpbmcgbW9kZS5cbiAgICAgICAqXG4gICAgICAgKiBAZGVmYXVsdFZhbHVlIGAnb2ZmJ2BcbiAgICAgICAqL1xuICAgICAgbW9kZT86ICdvZmYnIHwgJ2RlZmF1bHQnO1xuXG4gICAgICAvKipcbiAgICAgICAqIFNldCBvciBnZXQgYSBjYWxsYmFjayBmdW5jdGlvbiB3aGVuIGEgcHJvZmlsaW5nIGRhdGEgaXMgcmVjZWl2ZWQuIElmIG5vdCBzZXQsIHRoZSBwcm9maWxpbmcgZGF0YSB3aWxsIGJlXG4gICAgICAgKiBwcmludGVkIHRvIGNvbnNvbGUuXG4gICAgICAgKi9cbiAgICAgIG9uZGF0YT86IChkYXRhOiBXZWJHcHVQcm9maWxpbmdEYXRhKSA9PiB2b2lkO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgcG93ZXIgcHJlZmVyZW5jZS5cbiAgICAgKlxuICAgICAqIFNldHRpbmcgdGhpcyBwcm9wZXJ0eSBvbmx5IGhhcyBlZmZlY3QgYmVmb3JlIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gVGhlIHZhbHVlIHdpbGwgYmVcbiAgICAgKiB1c2VkIGFzIG9wdGlvbnMgZm9yIGBuYXZpZ2F0b3IuZ3B1LnJlcXVlc3RBZGFwdGVyKClgLlxuICAgICAqXG4gICAgICogU2VlIHtAbGluayBodHRwczovL2dwdXdlYi5naXRodWIuaW8vZ3B1d2ViLyNkaWN0ZGVmLWdwdXJlcXVlc3RhZGFwdGVyb3B0aW9uc30gZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYHVuZGVmaW5lZGBcbiAgICAgKlxuICAgICAqIEBkZXByZWNhdGVkIENyZWF0ZSB5b3VyIG93biBHUFVBZGFwdGVyLCB1c2UgaXQgdG8gY3JlYXRlIGEgR1BVRGV2aWNlIGluc3RhbmNlIGFuZCBzZXQge0BsaW5rIGRldmljZX0gcHJvcGVydHkgaWZcbiAgICAgKiB5b3Ugd2FudCB0byB1c2UgYSBzcGVjaWZpYyBwb3dlciBwcmVmZXJlbmNlLlxuICAgICAqL1xuICAgIHBvd2VyUHJlZmVyZW5jZT86ICdsb3ctcG93ZXInIHwgJ2hpZ2gtcGVyZm9ybWFuY2UnO1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIGZvcmNlIGZhbGxiYWNrIGFkYXB0ZXIgZmxhZy5cbiAgICAgKlxuICAgICAqIFNldHRpbmcgdGhpcyBwcm9wZXJ0eSBvbmx5IGhhcyBlZmZlY3QgYmVmb3JlIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gVGhlIHZhbHVlIHdpbGwgYmVcbiAgICAgKiB1c2VkIGFzIG9wdGlvbnMgZm9yIGBuYXZpZ2F0b3IuZ3B1LnJlcXVlc3RBZGFwdGVyKClgLlxuICAgICAqXG4gICAgICogU2VlIHtAbGluayBodHRwczovL2dwdXdlYi5naXRodWIuaW8vZ3B1d2ViLyNkaWN0ZGVmLWdwdXJlcXVlc3RhZGFwdGVyb3B0aW9uc30gZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYHVuZGVmaW5lZGBcbiAgICAgKlxuICAgICAqIEBkZXByZWNhdGVkIENyZWF0ZSB5b3VyIG93biBHUFVBZGFwdGVyLCB1c2UgaXQgdG8gY3JlYXRlIGEgR1BVRGV2aWNlIGluc3RhbmNlIGFuZCBzZXQge0BsaW5rIGRldmljZX0gcHJvcGVydHkgaWZcbiAgICAgKiB5b3Ugd2FudCB0byB1c2UgYSBzcGVjaWZpYyBmYWxsYmFjayBvcHRpb24uXG4gICAgICovXG4gICAgZm9yY2VGYWxsYmFja0FkYXB0ZXI/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIGFkYXB0ZXIgZm9yIFdlYkdQVS5cbiAgICAgKlxuICAgICAqIFNldHRpbmcgdGhpcyBwcm9wZXJ0eSBvbmx5IGhhcyBlZmZlY3QgYmVmb3JlIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gVGhlIHZhbHVlIHdpbGwgYmVcbiAgICAgKiB1c2VkIGFzIHRoZSBHUFUgYWRhcHRlciBmb3IgdGhlIHVuZGVybHlpbmcgV2ViR1BVIGJhY2tlbmQgdG8gY3JlYXRlIEdQVSBkZXZpY2UuXG4gICAgICpcbiAgICAgKiBJZiB0aGlzIHByb3BlcnR5IGlzIG5vdCBzZXQsIGl0IHdpbGwgYmUgYXZhaWxhYmxlIHRvIGdldCBhZnRlciB0aGUgZmlyc3QgV2ViR1BVIGluZmVyZW5jZSBzZXNzaW9uIGlzIGNyZWF0ZWQuIFRoZVxuICAgICAqIHZhbHVlIHdpbGwgYmUgdGhlIEdQVSBhZGFwdGVyIHRoYXQgY3JlYXRlZCBieSB0aGUgdW5kZXJseWluZyBXZWJHUFUgYmFja2VuZC5cbiAgICAgKlxuICAgICAqIFdoZW4gdXNlIHdpdGggVHlwZVNjcmlwdCwgdGhlIHR5cGUgb2YgdGhpcyBwcm9wZXJ0eSBpcyBgR1BVQWRhcHRlcmAgZGVmaW5lZCBpbiBcIkB3ZWJncHUvdHlwZXNcIi5cbiAgICAgKlxuICAgICAqIEBkZXByZWNhdGVkIEl0IGlzIG5vIGxvbmdlciByZWNvbW1lbmRlZCB0byB1c2UgdGhpcyBwcm9wZXJ0eS4gVGhlIGxhdGVzdCBXZWJHUFUgc3BlYyBhZGRzIGBHUFVEZXZpY2UuYWRhcHRlckluZm9gXG4gICAgICogKGh0dHBzOi8vd3d3LnczLm9yZy9UUi93ZWJncHUvI2RvbS1ncHVkZXZpY2UtYWRhcHRlcmluZm8pLCB3aGljaCBhbGxvd3MgdG8gZ2V0IHRoZSBhZGFwdGVyIGluZm9ybWF0aW9uIGZyb20gdGhlXG4gICAgICogZGV2aWNlLiBXaGVuIGl0J3MgYXZhaWxhYmxlLCB0aGVyZSBpcyBubyBuZWVkIHRvIHNldC9nZXQgdGhlIHtAbGluayBhZGFwdGVyfSBwcm9wZXJ0eS5cbiAgICAgKi9cbiAgICBhZGFwdGVyOiBUcnlHZXRHbG9iYWxUeXBlPCdHUFVBZGFwdGVyJz47XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgR1BVIGRldmljZSBmb3IgV2ViR1BVLlxuICAgICAqXG4gICAgICogVGhlcmUgYXJlIDMgdmFsaWQgc2NlbmFyaW9zIG9mIGFjY2Vzc2luZyB0aGlzIHByb3BlcnR5OlxuICAgICAqIC0gU2V0IGEgdmFsdWUgYmVmb3JlIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gVGhlIHZhbHVlIHdpbGwgYmUgdXNlZCBieSB0aGUgV2ViR1BVIGJhY2tlbmRcbiAgICAgKiB0byBwZXJmb3JtIGNhbGN1bGF0aW9ucy4gSWYgdGhlIHZhbHVlIGlzIG5vdCBhIGBHUFVEZXZpY2VgIG9iamVjdCwgYW4gZXJyb3Igd2lsbCBiZSB0aHJvd24uXG4gICAgICogLSBHZXQgdGhlIHZhbHVlIGJlZm9yZSB0aGUgZmlyc3QgV2ViR1BVIGluZmVyZW5jZSBzZXNzaW9uIGlzIGNyZWF0ZWQuIFRoaXMgd2lsbCB0cnkgdG8gY3JlYXRlIGEgbmV3IEdQVURldmljZVxuICAgICAqIGluc3RhbmNlLiBSZXR1cm5zIGEgYFByb21pc2VgIHRoYXQgcmVzb2x2ZXMgdG8gYSBgR1BVRGV2aWNlYCBvYmplY3QuXG4gICAgICogLSBHZXQgdGhlIHZhbHVlIGFmdGVyIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gUmV0dXJucyBhIHJlc29sdmVkIGBQcm9taXNlYCB0byB0aGVcbiAgICAgKiBgR1BVRGV2aWNlYCBvYmplY3QgdXNlZCBieSB0aGUgV2ViR1BVIGJhY2tlbmQuXG4gICAgICovXG4gICAgZ2V0IGRldmljZSgpOiBQcm9taXNlPFRyeUdldEdsb2JhbFR5cGU8J0dQVURldmljZSc+PjtcbiAgICBzZXQgZGV2aWNlKHZhbHVlOiBUcnlHZXRHbG9iYWxUeXBlPCdHUFVEZXZpY2UnPik7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB3aGV0aGVyIHZhbGlkYXRlIGlucHV0IGNvbnRlbnQuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICAgKi9cbiAgICB2YWxpZGF0ZUlucHV0Q29udGVudD86IGJvb2xlYW47XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBFbnYge1xuICAvKipcbiAgICogc2V0IHRoZSBzZXZlcml0eSBsZXZlbCBmb3IgbG9nZ2luZy5cbiAgICpcbiAgICogQGRlZmF1bHRWYWx1ZSBgJ3dhcm5pbmcnYFxuICAgKi9cbiAgbG9nTGV2ZWw/OiAndmVyYm9zZScgfCAnaW5mbycgfCAnd2FybmluZycgfCAnZXJyb3InIHwgJ2ZhdGFsJztcblxuICAvKipcbiAgICogSW5kaWNhdGUgd2hldGhlciBydW4gaW4gZGVidWcgbW9kZS5cbiAgICpcbiAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAqL1xuICBkZWJ1Zz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIHNldCBvciBnZXQgYSBib29sZWFuIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0byBlbmFibGUgdHJhY2UuXG4gICAqXG4gICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgKi9cbiAgdHJhY2U/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBHZXQgdmVyc2lvbiBvZiB0aGUgY3VycmVudCBwYWNrYWdlLlxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbnM6IHtcbiAgICByZWFkb25seSBjb21tb246IHN0cmluZztcbiAgICByZWFkb25seSB3ZWI/OiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgbm9kZT86IHN0cmluZztcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG4gICAgcmVhZG9ubHkgJ3JlYWN0LW5hdGl2ZSc/OiBzdHJpbmc7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudCBhIHNldCBvZiBmbGFncyBmb3IgV2ViQXNzZW1ibHlcbiAgICovXG4gIHJlYWRvbmx5IHdhc206IEVudi5XZWJBc3NlbWJseUZsYWdzO1xuXG4gIC8qKlxuICAgKiBSZXByZXNlbnQgYSBzZXQgb2YgZmxhZ3MgZm9yIFdlYkdMXG4gICAqL1xuICByZWFkb25seSB3ZWJnbDogRW52LldlYkdMRmxhZ3M7XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudCBhIHNldCBvZiBmbGFncyBmb3IgV2ViR1BVXG4gICAqL1xuICByZWFkb25seSB3ZWJncHU6IEVudi5XZWJHcHVGbGFncztcblxuICBbbmFtZTogc3RyaW5nXTogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnQgYSBzZXQgb2YgZmxhZ3MgYXMgYSBnbG9iYWwgc2luZ2xldG9uLlxuICovXG5leHBvcnQgY29uc3QgZW52OiBFbnYgPSBlbnZJbXBsO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3JUb0RhdGFVcmxPcHRpb25zLCBUZW5zb3JUb0ltYWdlRGF0YU9wdGlvbnMgfSBmcm9tICcuL3RlbnNvci1jb252ZXJzaW9uLmpzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yLmpzJztcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IudG9EYXRhVVJMKClcbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvclRvRGF0YVVSTCA9ICh0ZW5zb3I6IFRlbnNvciwgb3B0aW9ucz86IFRlbnNvclRvRGF0YVVybE9wdGlvbnMpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBjYW52YXMgPSB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykgOiBuZXcgT2Zmc2NyZWVuQ2FudmFzKDEsIDEpO1xuICBjYW52YXMud2lkdGggPSB0ZW5zb3IuZGltc1szXTtcbiAgY2FudmFzLmhlaWdodCA9IHRlbnNvci5kaW1zWzJdO1xuICBjb25zdCBwaXhlbHMyRENvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKSBhc1xuICAgIHwgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEXG4gICAgfCBPZmZzY3JlZW5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkRcbiAgICB8IG51bGw7XG5cbiAgaWYgKHBpeGVsczJEQ29udGV4dCAhPSBudWxsKSB7XG4gICAgLy8gRGVmYXVsdCB2YWx1ZXMgZm9yIGhlaWdodCBhbmQgd2lkdGggJiBmb3JtYXRcbiAgICBsZXQgd2lkdGg6IG51bWJlcjtcbiAgICBsZXQgaGVpZ2h0OiBudW1iZXI7XG4gICAgaWYgKG9wdGlvbnM/LnRlbnNvckxheW91dCAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMudGVuc29yTGF5b3V0ID09PSAnTkhXQycpIHtcbiAgICAgIHdpZHRoID0gdGVuc29yLmRpbXNbMl07XG4gICAgICBoZWlnaHQgPSB0ZW5zb3IuZGltc1szXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRGVmYXVsdCBsYXlvdXQgaXMgTkNXSFxuICAgICAgd2lkdGggPSB0ZW5zb3IuZGltc1szXTtcbiAgICAgIGhlaWdodCA9IHRlbnNvci5kaW1zWzJdO1xuICAgIH1cblxuICAgIGNvbnN0IGlucHV0Zm9ybWF0ID0gb3B0aW9ucz8uZm9ybWF0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmZvcm1hdCA6ICdSR0InO1xuXG4gICAgY29uc3Qgbm9ybSA9IG9wdGlvbnM/Lm5vcm07XG4gICAgbGV0IG5vcm1NZWFuOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgICBsZXQgbm9ybUJpYXM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgIGlmIChub3JtID09PSB1bmRlZmluZWQgfHwgbm9ybS5tZWFuID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG5vcm1NZWFuID0gWzI1NSwgMjU1LCAyNTUsIDI1NV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2Ygbm9ybS5tZWFuID09PSAnbnVtYmVyJykge1xuICAgICAgICBub3JtTWVhbiA9IFtub3JtLm1lYW4sIG5vcm0ubWVhbiwgbm9ybS5tZWFuLCBub3JtLm1lYW5dO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbm9ybU1lYW4gPSBbbm9ybS5tZWFuWzBdLCBub3JtLm1lYW5bMV0sIG5vcm0ubWVhblsyXSwgMF07XG4gICAgICAgIGlmIChub3JtLm1lYW5bM10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG5vcm1NZWFuWzNdID0gbm9ybS5tZWFuWzNdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChub3JtID09PSB1bmRlZmluZWQgfHwgbm9ybS5iaWFzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG5vcm1CaWFzID0gWzAsIDAsIDAsIDBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodHlwZW9mIG5vcm0uYmlhcyA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgbm9ybUJpYXMgPSBbbm9ybS5iaWFzLCBub3JtLmJpYXMsIG5vcm0uYmlhcywgbm9ybS5iaWFzXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vcm1CaWFzID0gW25vcm0uYmlhc1swXSwgbm9ybS5iaWFzWzFdLCBub3JtLmJpYXNbMl0sIDBdO1xuICAgICAgICBpZiAobm9ybS5iaWFzWzNdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBub3JtQmlhc1szXSA9IG5vcm0uYmlhc1szXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHN0cmlkZSA9IGhlaWdodCAqIHdpZHRoO1xuICAgIC8vIERlZmF1bHQgcG9pbnRlciBhc3NpZ25tZW50c1xuICAgIGxldCByVGVuc29yUG9pbnRlciA9IDAsXG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZSxcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMixcbiAgICAgIGFUZW5zb3JQb2ludGVyID0gLTE7XG5cbiAgICAvLyBVcGRhdGluZyB0aGUgcG9pbnRlciBhc3NpZ25tZW50cyBiYXNlZCBvbiB0aGUgaW5wdXQgaW1hZ2UgZm9ybWF0XG4gICAgaWYgKGlucHV0Zm9ybWF0ID09PSAnUkdCQScpIHtcbiAgICAgIHJUZW5zb3JQb2ludGVyID0gMDtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICAgICAgYVRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAzO1xuICAgIH0gZWxzZSBpZiAoaW5wdXRmb3JtYXQgPT09ICdSR0InKSB7XG4gICAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgICB9IGVsc2UgaWYgKGlucHV0Zm9ybWF0ID09PSAnUkJHJykge1xuICAgICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoZWlnaHQ7IGkrKykge1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB3aWR0aDsgaisrKSB7XG4gICAgICAgIGNvbnN0IFIgPSAoKHRlbnNvci5kYXRhW3JUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1swXSkgKiBub3JtTWVhblswXTsgLy8gUiB2YWx1ZVxuICAgICAgICBjb25zdCBHID0gKCh0ZW5zb3IuZGF0YVtnVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbMV0pICogbm9ybU1lYW5bMV07IC8vIEcgdmFsdWVcbiAgICAgICAgY29uc3QgQiA9ICgodGVuc29yLmRhdGFbYlRlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzJdKSAqIG5vcm1NZWFuWzJdOyAvLyBCIHZhbHVlXG4gICAgICAgIGNvbnN0IEEgPSBhVGVuc29yUG9pbnRlciA9PT0gLTEgPyAyNTUgOiAoKHRlbnNvci5kYXRhW2FUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1szXSkgKiBub3JtTWVhblszXTsgLy8gQSB2YWx1ZVxuXG4gICAgICAgIHBpeGVsczJEQ29udGV4dC5maWxsU3R5bGUgPSAncmdiYSgnICsgUiArICcsJyArIEcgKyAnLCcgKyBCICsgJywnICsgQSArICcpJztcbiAgICAgICAgcGl4ZWxzMkRDb250ZXh0LmZpbGxSZWN0KGosIGksIDEsIDEpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoJ3RvRGF0YVVSTCcgaW4gY2FudmFzKSB7XG4gICAgICByZXR1cm4gY2FudmFzLnRvRGF0YVVSTCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RvRGF0YVVSTCBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBhY2Nlc3MgaW1hZ2UgZGF0YScpO1xuICB9XG59O1xuXG4vKipcbiAqIGltcGxlbWVudGF0aW9uIG9mIFRlbnNvci50b0ltYWdlRGF0YSgpXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JUb0ltYWdlRGF0YSA9ICh0ZW5zb3I6IFRlbnNvciwgb3B0aW9ucz86IFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyk6IEltYWdlRGF0YSA9PiB7XG4gIGNvbnN0IHBpeGVsczJEQ29udGV4dCA9XG4gICAgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJ1xuICAgICAgPyBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKS5nZXRDb250ZXh0KCcyZCcpXG4gICAgICA6IChuZXcgT2Zmc2NyZWVuQ2FudmFzKDEsIDEpLmdldENvbnRleHQoJzJkJykgYXMgT2Zmc2NyZWVuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEKTtcbiAgbGV0IGltYWdlOiBJbWFnZURhdGE7XG4gIGlmIChwaXhlbHMyRENvbnRleHQgIT0gbnVsbCkge1xuICAgIC8vIERlZmF1bHQgdmFsdWVzIGZvciBoZWlnaHQgYW5kIHdpZHRoICYgZm9ybWF0XG4gICAgbGV0IHdpZHRoOiBudW1iZXI7XG4gICAgbGV0IGhlaWdodDogbnVtYmVyO1xuICAgIGxldCBjaGFubmVsczogbnVtYmVyO1xuICAgIGlmIChvcHRpb25zPy50ZW5zb3JMYXlvdXQgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnRlbnNvckxheW91dCA9PT0gJ05IV0MnKSB7XG4gICAgICB3aWR0aCA9IHRlbnNvci5kaW1zWzJdO1xuICAgICAgaGVpZ2h0ID0gdGVuc29yLmRpbXNbMV07XG4gICAgICBjaGFubmVscyA9IHRlbnNvci5kaW1zWzNdO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZWZhdWx0IGxheW91dCBpcyBOQ1dIXG4gICAgICB3aWR0aCA9IHRlbnNvci5kaW1zWzNdO1xuICAgICAgaGVpZ2h0ID0gdGVuc29yLmRpbXNbMl07XG4gICAgICBjaGFubmVscyA9IHRlbnNvci5kaW1zWzFdO1xuICAgIH1cbiAgICBjb25zdCBpbnB1dGZvcm1hdCA9IG9wdGlvbnMgIT09IHVuZGVmaW5lZCA/IChvcHRpb25zLmZvcm1hdCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5mb3JtYXQgOiAnUkdCJykgOiAnUkdCJztcblxuICAgIGNvbnN0IG5vcm0gPSBvcHRpb25zPy5ub3JtO1xuICAgIGxldCBub3JtTWVhbjogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgbGV0IG5vcm1CaWFzOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgICBpZiAobm9ybSA9PT0gdW5kZWZpbmVkIHx8IG5vcm0ubWVhbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBub3JtTWVhbiA9IFsyNTUsIDI1NSwgMjU1LCAyNTVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodHlwZW9mIG5vcm0ubWVhbiA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgbm9ybU1lYW4gPSBbbm9ybS5tZWFuLCBub3JtLm1lYW4sIG5vcm0ubWVhbiwgbm9ybS5tZWFuXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vcm1NZWFuID0gW25vcm0ubWVhblswXSwgbm9ybS5tZWFuWzFdLCBub3JtLm1lYW5bMl0sIDI1NV07XG4gICAgICAgIGlmIChub3JtLm1lYW5bM10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG5vcm1NZWFuWzNdID0gbm9ybS5tZWFuWzNdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChub3JtID09PSB1bmRlZmluZWQgfHwgbm9ybS5iaWFzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG5vcm1CaWFzID0gWzAsIDAsIDAsIDBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodHlwZW9mIG5vcm0uYmlhcyA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgbm9ybUJpYXMgPSBbbm9ybS5iaWFzLCBub3JtLmJpYXMsIG5vcm0uYmlhcywgbm9ybS5iaWFzXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vcm1CaWFzID0gW25vcm0uYmlhc1swXSwgbm9ybS5iaWFzWzFdLCBub3JtLmJpYXNbMl0sIDBdO1xuICAgICAgICBpZiAobm9ybS5iaWFzWzNdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBub3JtQmlhc1szXSA9IG5vcm0uYmlhc1szXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHN0cmlkZSA9IGhlaWdodCAqIHdpZHRoO1xuICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChcbiAgICAgICAgKG9wdGlvbnMuZm9ybWF0ICE9PSB1bmRlZmluZWQgJiYgY2hhbm5lbHMgPT09IDQgJiYgb3B0aW9ucy5mb3JtYXQgIT09ICdSR0JBJykgfHxcbiAgICAgICAgKGNoYW5uZWxzID09PSAzICYmIG9wdGlvbnMuZm9ybWF0ICE9PSAnUkdCJyAmJiBvcHRpb25zLmZvcm1hdCAhPT0gJ0JHUicpXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGVuc29yIGZvcm1hdCBkb2Vzbid0IG1hdGNoIGlucHV0IHRlbnNvciBkaW1zXCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIERlZmF1bHQgcG9pbnRlciBhc3NpZ25tZW50c1xuICAgIGNvbnN0IHN0ZXAgPSA0O1xuICAgIGxldCBySW1hZ2VQb2ludGVyID0gMCxcbiAgICAgIGdJbWFnZVBvaW50ZXIgPSAxLFxuICAgICAgYkltYWdlUG9pbnRlciA9IDIsXG4gICAgICBhSW1hZ2VQb2ludGVyID0gMztcbiAgICBsZXQgclRlbnNvclBvaW50ZXIgPSAwLFxuICAgICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGUsXG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDIsXG4gICAgICBhVGVuc29yUG9pbnRlciA9IC0xO1xuXG4gICAgLy8gVXBkYXRpbmcgdGhlIHBvaW50ZXIgYXNzaWdubWVudHMgYmFzZWQgb24gdGhlIGlucHV0IGltYWdlIGZvcm1hdFxuICAgIGlmIChpbnB1dGZvcm1hdCA9PT0gJ1JHQkEnKSB7XG4gICAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgICAgIGFUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMztcbiAgICB9IGVsc2UgaWYgKGlucHV0Zm9ybWF0ID09PSAnUkdCJykge1xuICAgICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gICAgfSBlbHNlIGlmIChpbnB1dGZvcm1hdCA9PT0gJ1JCRycpIHtcbiAgICAgIHJUZW5zb3JQb2ludGVyID0gMDtcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICAgIH1cblxuICAgIGltYWdlID0gcGl4ZWxzMkRDb250ZXh0LmNyZWF0ZUltYWdlRGF0YSh3aWR0aCwgaGVpZ2h0KTtcblxuICAgIGZvciAoXG4gICAgICBsZXQgaSA9IDA7XG4gICAgICBpIDwgaGVpZ2h0ICogd2lkdGg7XG4gICAgICBySW1hZ2VQb2ludGVyICs9IHN0ZXAsIGdJbWFnZVBvaW50ZXIgKz0gc3RlcCwgYkltYWdlUG9pbnRlciArPSBzdGVwLCBhSW1hZ2VQb2ludGVyICs9IHN0ZXAsIGkrK1xuICAgICkge1xuICAgICAgaW1hZ2UuZGF0YVtySW1hZ2VQb2ludGVyXSA9ICgodGVuc29yLmRhdGFbclRlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzBdKSAqIG5vcm1NZWFuWzBdOyAvLyBSIHZhbHVlXG4gICAgICBpbWFnZS5kYXRhW2dJbWFnZVBvaW50ZXJdID0gKCh0ZW5zb3IuZGF0YVtnVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbMV0pICogbm9ybU1lYW5bMV07IC8vIEcgdmFsdWVcbiAgICAgIGltYWdlLmRhdGFbYkltYWdlUG9pbnRlcl0gPSAoKHRlbnNvci5kYXRhW2JUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1syXSkgKiBub3JtTWVhblsyXTsgLy8gQiB2YWx1ZVxuICAgICAgaW1hZ2UuZGF0YVthSW1hZ2VQb2ludGVyXSA9XG4gICAgICAgIGFUZW5zb3JQb2ludGVyID09PSAtMSA/IDI1NSA6ICgodGVuc29yLmRhdGFbYVRlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzNdKSAqIG5vcm1NZWFuWzNdOyAvLyBBIHZhbHVlXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBhY2Nlc3MgaW1hZ2UgZGF0YScpO1xuICB9XG4gIHJldHVybiBpbWFnZTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7XG4gIE9wdGlvbnNEaW1lbnNpb25zLFxuICBPcHRpb25zRm9ybWF0LFxuICBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMsXG4gIE9wdGlvbnNUZW5zb3JGb3JtYXQsXG4gIE9wdGlvbnNUZW5zb3JMYXlvdXQsXG4gIFRlbnNvckZyb21HcHVCdWZmZXJPcHRpb25zLFxuICBUZW5zb3JGcm9tSW1hZ2VCaXRtYXBPcHRpb25zLFxuICBUZW5zb3JGcm9tSW1hZ2VEYXRhT3B0aW9ucyxcbiAgVGVuc29yRnJvbUltYWdlRWxlbWVudE9wdGlvbnMsXG4gIFRlbnNvckZyb21NTFRlbnNvck9wdGlvbnMsXG4gIFRlbnNvckZyb21UZXh0dXJlT3B0aW9ucyxcbiAgVGVuc29yRnJvbVVybE9wdGlvbnMsXG59IGZyb20gJy4vdGVuc29yLWZhY3RvcnkuanMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3ItaW1wbC5qcyc7XG5pbXBvcnQgeyBUZW5zb3IgYXMgVGVuc29ySW50ZXJmYWNlIH0gZnJvbSAnLi90ZW5zb3IuanMnO1xuXG5pbnRlcmZhY2UgQnVmZmVyVG9UZW5zb3JPcHRpb25zXG4gIGV4dGVuZHMgT3B0aW9uc0RpbWVuc2lvbnMsXG4gICAgT3B0aW9uc1RlbnNvckxheW91dCxcbiAgICBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMsXG4gICAgT3B0aW9uc0Zvcm1hdCxcbiAgICBPcHRpb25zVGVuc29yRm9ybWF0IHt9XG5cbi8qKlxuICogQ3JlYXRlIGEgbmV3IHRlbnNvciBvYmplY3QgZnJvbSBpbWFnZSBvYmplY3RcbiAqXG4gKiBAcGFyYW0gYnVmZmVyIC0gRXh0cmFjdGVkIGltYWdlIGJ1ZmZlciBkYXRhIC0gYXNzdW1pbmcgUkdCQSBmb3JtYXRcbiAqIEBwYXJhbSBpbWFnZUZvcm1hdCAtIGlucHV0IGltYWdlIGNvbmZpZ3VyYXRpb24gLSByZXF1aXJlZCBjb25maWd1cmF0aW9ucyBoZWlnaHQsIHdpZHRoLCBmb3JtYXRcbiAqIEBwYXJhbSB0ZW5zb3JGb3JtYXQgLSBvdXRwdXQgdGVuc29yIGNvbmZpZ3VyYXRpb24gLSBEZWZhdWx0IGlzIFJHQiBmb3JtYXRcbiAqL1xuZXhwb3J0IGNvbnN0IGJ1ZmZlclRvVGVuc29yID0gKGJ1ZmZlcjogVWludDhDbGFtcGVkQXJyYXkgfCB1bmRlZmluZWQsIG9wdGlvbnM6IEJ1ZmZlclRvVGVuc29yT3B0aW9ucyk6IFRlbnNvciA9PiB7XG4gIGlmIChidWZmZXIgPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW1hZ2UgYnVmZmVyIG11c3QgYmUgZGVmaW5lZCcpO1xuICB9XG4gIGlmIChvcHRpb25zLmhlaWdodCA9PT0gdW5kZWZpbmVkIHx8IG9wdGlvbnMud2lkdGggPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW1hZ2UgaGVpZ2h0IGFuZCB3aWR0aCBtdXN0IGJlIGRlZmluZWQnKTtcbiAgfVxuICBpZiAob3B0aW9ucy50ZW5zb3JMYXlvdXQgPT09ICdOSFdDJykge1xuICAgIHRocm93IG5ldyBFcnJvcignTkhXQyBUZW5zb3IgbGF5b3V0IGlzIG5vdCBzdXBwb3J0ZWQgeWV0Jyk7XG4gIH1cblxuICBjb25zdCB7IGhlaWdodCwgd2lkdGggfSA9IG9wdGlvbnM7XG5cbiAgY29uc3Qgbm9ybSA9IG9wdGlvbnMubm9ybSA/PyB7IG1lYW46IDI1NSwgYmlhczogMCB9O1xuICBsZXQgbm9ybU1lYW46IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICBsZXQgbm9ybUJpYXM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuXG4gIGlmICh0eXBlb2Ygbm9ybS5tZWFuID09PSAnbnVtYmVyJykge1xuICAgIG5vcm1NZWFuID0gW25vcm0ubWVhbiwgbm9ybS5tZWFuLCBub3JtLm1lYW4sIG5vcm0ubWVhbl07XG4gIH0gZWxzZSB7XG4gICAgbm9ybU1lYW4gPSBbbm9ybS5tZWFuIVswXSwgbm9ybS5tZWFuIVsxXSwgbm9ybS5tZWFuIVsyXSwgbm9ybS5tZWFuIVszXSA/PyAyNTVdO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBub3JtLmJpYXMgPT09ICdudW1iZXInKSB7XG4gICAgbm9ybUJpYXMgPSBbbm9ybS5iaWFzLCBub3JtLmJpYXMsIG5vcm0uYmlhcywgbm9ybS5iaWFzXTtcbiAgfSBlbHNlIHtcbiAgICBub3JtQmlhcyA9IFtub3JtLmJpYXMhWzBdLCBub3JtLmJpYXMhWzFdLCBub3JtLmJpYXMhWzJdLCBub3JtLmJpYXMhWzNdID8/IDBdO1xuICB9XG5cbiAgY29uc3QgaW5wdXRmb3JtYXQgPSBvcHRpb25zLmZvcm1hdCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5mb3JtYXQgOiAnUkdCQSc7XG4gIC8vIGRlZmF1bHQgdmFsdWUgaXMgUkdCQSBzaW5jZSBpbWFnZWRhdGEgYW5kIEhUTUxJbWFnZUVsZW1lbnQgdXNlcyBpdFxuXG4gIGNvbnN0IG91dHB1dGZvcm1hdCA9XG4gICAgb3B0aW9ucy50ZW5zb3JGb3JtYXQgIT09IHVuZGVmaW5lZCA/IChvcHRpb25zLnRlbnNvckZvcm1hdCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy50ZW5zb3JGb3JtYXQgOiAnUkdCJykgOiAnUkdCJztcbiAgY29uc3Qgc3RyaWRlID0gaGVpZ2h0ICogd2lkdGg7XG4gIGNvbnN0IGZsb2F0MzJEYXRhID0gb3V0cHV0Zm9ybWF0ID09PSAnUkdCQScgPyBuZXcgRmxvYXQzMkFycmF5KHN0cmlkZSAqIDQpIDogbmV3IEZsb2F0MzJBcnJheShzdHJpZGUgKiAzKTtcblxuICAvLyBEZWZhdWx0IHBvaW50ZXIgYXNzaWdubWVudHNcbiAgbGV0IHN0ZXAgPSA0LFxuICAgIHJJbWFnZVBvaW50ZXIgPSAwLFxuICAgIGdJbWFnZVBvaW50ZXIgPSAxLFxuICAgIGJJbWFnZVBvaW50ZXIgPSAyLFxuICAgIGFJbWFnZVBvaW50ZXIgPSAzO1xuICBsZXQgclRlbnNvclBvaW50ZXIgPSAwLFxuICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlLFxuICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMixcbiAgICBhVGVuc29yUG9pbnRlciA9IC0xO1xuXG4gIC8vIFVwZGF0aW5nIHRoZSBwb2ludGVyIGFzc2lnbm1lbnRzIGJhc2VkIG9uIHRoZSBpbnB1dCBpbWFnZSBmb3JtYXRcbiAgaWYgKGlucHV0Zm9ybWF0ID09PSAnUkdCJykge1xuICAgIHN0ZXAgPSAzO1xuICAgIHJJbWFnZVBvaW50ZXIgPSAwO1xuICAgIGdJbWFnZVBvaW50ZXIgPSAxO1xuICAgIGJJbWFnZVBvaW50ZXIgPSAyO1xuICAgIGFJbWFnZVBvaW50ZXIgPSAtMTtcbiAgfVxuXG4gIC8vIFVwZGF0aW5nIHRoZSBwb2ludGVyIGFzc2lnbm1lbnRzIGJhc2VkIG9uIHRoZSBvdXRwdXQgdGVuc29yIGZvcm1hdFxuICBpZiAob3V0cHV0Zm9ybWF0ID09PSAnUkdCQScpIHtcbiAgICBhVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDM7XG4gIH0gZWxzZSBpZiAob3V0cHV0Zm9ybWF0ID09PSAnUkJHJykge1xuICAgIHJUZW5zb3JQb2ludGVyID0gMDtcbiAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gIH0gZWxzZSBpZiAob3V0cHV0Zm9ybWF0ID09PSAnQkdSJykge1xuICAgIGJUZW5zb3JQb2ludGVyID0gMDtcbiAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICByVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gIH1cblxuICBmb3IgKFxuICAgIGxldCBpID0gMDtcbiAgICBpIDwgc3RyaWRlO1xuICAgIGkrKywgckltYWdlUG9pbnRlciArPSBzdGVwLCBiSW1hZ2VQb2ludGVyICs9IHN0ZXAsIGdJbWFnZVBvaW50ZXIgKz0gc3RlcCwgYUltYWdlUG9pbnRlciArPSBzdGVwXG4gICkge1xuICAgIGZsb2F0MzJEYXRhW3JUZW5zb3JQb2ludGVyKytdID0gKGJ1ZmZlcltySW1hZ2VQb2ludGVyXSArIG5vcm1CaWFzWzBdKSAvIG5vcm1NZWFuWzBdO1xuICAgIGZsb2F0MzJEYXRhW2dUZW5zb3JQb2ludGVyKytdID0gKGJ1ZmZlcltnSW1hZ2VQb2ludGVyXSArIG5vcm1CaWFzWzFdKSAvIG5vcm1NZWFuWzFdO1xuICAgIGZsb2F0MzJEYXRhW2JUZW5zb3JQb2ludGVyKytdID0gKGJ1ZmZlcltiSW1hZ2VQb2ludGVyXSArIG5vcm1CaWFzWzJdKSAvIG5vcm1NZWFuWzJdO1xuICAgIGlmIChhVGVuc29yUG9pbnRlciAhPT0gLTEgJiYgYUltYWdlUG9pbnRlciAhPT0gLTEpIHtcbiAgICAgIGZsb2F0MzJEYXRhW2FUZW5zb3JQb2ludGVyKytdID0gKGJ1ZmZlclthSW1hZ2VQb2ludGVyXSArIG5vcm1CaWFzWzNdKSAvIG5vcm1NZWFuWzNdO1xuICAgIH1cbiAgfVxuXG4gIC8vIEZsb2F0MzJBcnJheSAtPiBvcnQuVGVuc29yXG4gIGNvbnN0IG91dHB1dFRlbnNvciA9XG4gICAgb3V0cHV0Zm9ybWF0ID09PSAnUkdCQSdcbiAgICAgID8gbmV3IFRlbnNvcignZmxvYXQzMicsIGZsb2F0MzJEYXRhLCBbMSwgNCwgaGVpZ2h0LCB3aWR0aF0pXG4gICAgICA6IG5ldyBUZW5zb3IoJ2Zsb2F0MzInLCBmbG9hdDMyRGF0YSwgWzEsIDMsIGhlaWdodCwgd2lkdGhdKTtcbiAgcmV0dXJuIG91dHB1dFRlbnNvcjtcbn07XG5cbi8qKlxuICogaW1wbGVtZW50YXRpb24gb2YgVGVuc29yLmZyb21JbWFnZSgpLlxuICovXG5leHBvcnQgY29uc3QgdGVuc29yRnJvbUltYWdlID0gYXN5bmMgKFxuICBpbWFnZTogSW1hZ2VEYXRhIHwgSFRNTEltYWdlRWxlbWVudCB8IEltYWdlQml0bWFwIHwgc3RyaW5nLFxuICBvcHRpb25zPzpcbiAgICB8IFRlbnNvckZyb21JbWFnZURhdGFPcHRpb25zXG4gICAgfCBUZW5zb3JGcm9tSW1hZ2VFbGVtZW50T3B0aW9uc1xuICAgIHwgVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9uc1xuICAgIHwgVGVuc29yRnJvbVVybE9wdGlvbnMsXG4pOiBQcm9taXNlPFRlbnNvcj4gPT4ge1xuICAvLyBjaGVja2luZyB0aGUgdHlwZSBvZiBpbWFnZSBvYmplY3RcbiAgY29uc3QgaXNIVE1MSW1hZ2VFbGUgPSB0eXBlb2YgSFRNTEltYWdlRWxlbWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgaW1hZ2UgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50O1xuICBjb25zdCBpc0ltYWdlRGF0YUVsZSA9IHR5cGVvZiBJbWFnZURhdGEgIT09ICd1bmRlZmluZWQnICYmIGltYWdlIGluc3RhbmNlb2YgSW1hZ2VEYXRhO1xuICBjb25zdCBpc0ltYWdlQml0bWFwID0gdHlwZW9mIEltYWdlQml0bWFwICE9PSAndW5kZWZpbmVkJyAmJiBpbWFnZSBpbnN0YW5jZW9mIEltYWdlQml0bWFwO1xuICBjb25zdCBpc1N0cmluZyA9IHR5cGVvZiBpbWFnZSA9PT0gJ3N0cmluZyc7XG5cbiAgbGV0IGRhdGE6IFVpbnQ4Q2xhbXBlZEFycmF5IHwgdW5kZWZpbmVkO1xuICBsZXQgYnVmZmVyVG9UZW5zb3JPcHRpb25zOiBCdWZmZXJUb1RlbnNvck9wdGlvbnMgPSBvcHRpb25zID8/IHt9O1xuXG4gIGNvbnN0IGNyZWF0ZUNhbnZhcyA9ICgpID0+IHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIE9mZnNjcmVlbkNhbnZhcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBuZXcgT2Zmc2NyZWVuQ2FudmFzKDEsIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbnZhcyBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gICAgfVxuICB9O1xuICBjb25zdCBjcmVhdGVDYW52YXNDb250ZXh0ID0gKGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgfCBPZmZzY3JlZW5DYW52YXMpID0+IHtcbiAgICBpZiAodHlwZW9mIEhUTUxDYW52YXNFbGVtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBjYW52YXMgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudCkge1xuICAgICAgcmV0dXJuIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgIH0gZWxzZSBpZiAoY2FudmFzIGluc3RhbmNlb2YgT2Zmc2NyZWVuQ2FudmFzKSB7XG4gICAgICByZXR1cm4gY2FudmFzLmdldENvbnRleHQoJzJkJykgYXMgT2Zmc2NyZWVuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH07XG4gIC8vIGZpbGxpbmcgYW5kIGNoZWNraW5nIGltYWdlIGNvbmZpZ3VyYXRpb24gb3B0aW9uc1xuICBpZiAoaXNIVE1MSW1hZ2VFbGUpIHtcbiAgICAvLyBIVE1MSW1hZ2VFbGVtZW50IC0gaW1hZ2Ugb2JqZWN0IC0gZm9ybWF0IGlzIFJHQkEgYnkgZGVmYXVsdFxuICAgIGNvbnN0IGNhbnZhcyA9IGNyZWF0ZUNhbnZhcygpO1xuICAgIGNhbnZhcy53aWR0aCA9IGltYWdlLndpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBpbWFnZS5oZWlnaHQ7XG4gICAgY29uc3QgcGl4ZWxzMkRDb250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dChjYW52YXMpO1xuXG4gICAgaWYgKHBpeGVsczJEQ29udGV4dCAhPSBudWxsKSB7XG4gICAgICBsZXQgaGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xuICAgICAgbGV0IHdpZHRoID0gaW1hZ2Uud2lkdGg7XG4gICAgICBpZiAob3B0aW9ucyAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMucmVzaXplZEhlaWdodCAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMucmVzaXplZFdpZHRoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaGVpZ2h0ID0gb3B0aW9ucy5yZXNpemVkSGVpZ2h0O1xuICAgICAgICB3aWR0aCA9IG9wdGlvbnMucmVzaXplZFdpZHRoO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgIGlmIChvcHRpb25zLnRlbnNvckZvcm1hdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbWFnZSBpbnB1dCBjb25maWcgZm9ybWF0IG11c3QgYmUgUkdCQSBmb3IgSFRNTEltYWdlRWxlbWVudCcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy50ZW5zb3JGb3JtYXQgPSAnUkdCQSc7XG4gICAgICAgIH1cbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLmhlaWdodCA9IGhlaWdodDtcbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLndpZHRoID0gd2lkdGg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMudGVuc29yRm9ybWF0ID0gJ1JHQkEnO1xuICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMud2lkdGggPSB3aWR0aDtcbiAgICAgIH1cblxuICAgICAgcGl4ZWxzMkRDb250ZXh0LmRyYXdJbWFnZShpbWFnZSwgMCwgMCk7XG4gICAgICBkYXRhID0gcGl4ZWxzMkRDb250ZXh0LmdldEltYWdlRGF0YSgwLCAwLCB3aWR0aCwgaGVpZ2h0KS5kYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBub3QgYWNjZXNzIGltYWdlIGRhdGEnKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNJbWFnZURhdGFFbGUpIHtcbiAgICBsZXQgaGVpZ2h0OiBudW1iZXI7XG4gICAgbGV0IHdpZHRoOiBudW1iZXI7XG5cbiAgICBpZiAob3B0aW9ucyAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMucmVzaXplZFdpZHRoICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy5yZXNpemVkSGVpZ2h0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGhlaWdodCA9IG9wdGlvbnMucmVzaXplZEhlaWdodDtcbiAgICAgIHdpZHRoID0gb3B0aW9ucy5yZXNpemVkV2lkdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhlaWdodCA9IGltYWdlLmhlaWdodDtcbiAgICAgIHdpZHRoID0gaW1hZ2Uud2lkdGg7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zID0gb3B0aW9ucztcbiAgICB9XG4gICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLmZvcm1hdCA9ICdSR0JBJztcbiAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy53aWR0aCA9IHdpZHRoO1xuXG4gICAgaWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgdGVtcENhbnZhcyA9IGNyZWF0ZUNhbnZhcygpO1xuXG4gICAgICB0ZW1wQ2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgICB0ZW1wQ2FudmFzLmhlaWdodCA9IGhlaWdodDtcblxuICAgICAgY29uc3QgcGl4ZWxzMkRDb250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dCh0ZW1wQ2FudmFzKTtcblxuICAgICAgaWYgKHBpeGVsczJEQ29udGV4dCAhPSBudWxsKSB7XG4gICAgICAgIHBpeGVsczJEQ29udGV4dC5wdXRJbWFnZURhdGEoaW1hZ2UsIDAsIDApO1xuICAgICAgICBkYXRhID0gcGl4ZWxzMkRDb250ZXh0LmdldEltYWdlRGF0YSgwLCAwLCB3aWR0aCwgaGVpZ2h0KS5kYXRhO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gbm90IGFjY2VzcyBpbWFnZSBkYXRhJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGRhdGEgPSBpbWFnZS5kYXRhO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc0ltYWdlQml0bWFwKSB7XG4gICAgLy8gSW1hZ2VCaXRtYXAgLSBpbWFnZSBvYmplY3QgLSBmb3JtYXQgbXVzdCBiZSBwcm92aWRlZCBieSB1c2VyXG4gICAgaWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQbGVhc2UgcHJvdmlkZSBpbWFnZSBjb25maWcgd2l0aCBmb3JtYXQgZm9yIEltYWdlYml0bWFwJyk7XG4gICAgfVxuXG4gICAgY29uc3QgY2FudmFzID0gY3JlYXRlQ2FudmFzKCk7XG4gICAgY2FudmFzLndpZHRoID0gaW1hZ2Uud2lkdGg7XG4gICAgY2FudmFzLmhlaWdodCA9IGltYWdlLmhlaWdodDtcbiAgICBjb25zdCBwaXhlbHMyRENvbnRleHQgPSBjcmVhdGVDYW52YXNDb250ZXh0KGNhbnZhcyk7XG5cbiAgICBpZiAocGl4ZWxzMkRDb250ZXh0ICE9IG51bGwpIHtcbiAgICAgIGNvbnN0IGhlaWdodCA9IGltYWdlLmhlaWdodDtcbiAgICAgIGNvbnN0IHdpZHRoID0gaW1hZ2Uud2lkdGg7XG4gICAgICBwaXhlbHMyRENvbnRleHQuZHJhd0ltYWdlKGltYWdlLCAwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIGRhdGEgPSBwaXhlbHMyRENvbnRleHQuZ2V0SW1hZ2VEYXRhKDAsIDAsIHdpZHRoLCBoZWlnaHQpLmRhdGE7XG4gICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLndpZHRoID0gd2lkdGg7XG4gICAgICByZXR1cm4gYnVmZmVyVG9UZW5zb3IoZGF0YSwgYnVmZmVyVG9UZW5zb3JPcHRpb25zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gbm90IGFjY2VzcyBpbWFnZSBkYXRhJyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzU3RyaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IGNhbnZhcyA9IGNyZWF0ZUNhbnZhcygpO1xuICAgICAgY29uc3QgY29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQoY2FudmFzKTtcbiAgICAgIGlmICghaW1hZ2UgfHwgIWNvbnRleHQpIHtcbiAgICAgICAgcmV0dXJuIHJlamVjdCgpO1xuICAgICAgfVxuICAgICAgY29uc3QgbmV3SW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICAgIG5ld0ltYWdlLmNyb3NzT3JpZ2luID0gJ0Fub255bW91cyc7XG4gICAgICBuZXdJbWFnZS5zcmMgPSBpbWFnZTtcbiAgICAgIG5ld0ltYWdlLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgY2FudmFzLndpZHRoID0gbmV3SW1hZ2Uud2lkdGg7XG4gICAgICAgIGNhbnZhcy5oZWlnaHQgPSBuZXdJbWFnZS5oZWlnaHQ7XG4gICAgICAgIGNvbnRleHQuZHJhd0ltYWdlKG5ld0ltYWdlLCAwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xuICAgICAgICBjb25zdCBpbWcgPSBjb250ZXh0LmdldEltYWdlRGF0YSgwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xuXG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy5oZWlnaHQgPSBjYW52YXMuaGVpZ2h0O1xuICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMud2lkdGggPSBjYW52YXMud2lkdGg7XG4gICAgICAgIHJlc29sdmUoYnVmZmVyVG9UZW5zb3IoaW1nLmRhdGEsIGJ1ZmZlclRvVGVuc29yT3B0aW9ucykpO1xuICAgICAgfTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGRhdGEgcHJvdmlkZWQgaXMgbm90IHN1cHBvcnRlZCAtIGFib3J0ZWQgdGVuc29yIGNyZWF0aW9uJyk7XG4gIH1cblxuICBpZiAoZGF0YSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGJ1ZmZlclRvVGVuc29yKGRhdGEsIGJ1ZmZlclRvVGVuc29yT3B0aW9ucyk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBkYXRhIHByb3ZpZGVkIGlzIG5vdCBzdXBwb3J0ZWQgLSBhYm9ydGVkIHRlbnNvciBjcmVhdGlvbicpO1xuICB9XG59O1xuXG4vKipcbiAqIGltcGxlbWVudGF0aW9uIG9mIFRlbnNvci5mcm9tVGV4dHVyZSgpLlxuICovXG5leHBvcnQgY29uc3QgdGVuc29yRnJvbVRleHR1cmUgPSA8VCBleHRlbmRzIFRlbnNvckludGVyZmFjZS5UZXh0dXJlRGF0YVR5cGVzPihcbiAgdGV4dHVyZTogVGVuc29ySW50ZXJmYWNlLlRleHR1cmVUeXBlLFxuICBvcHRpb25zOiBUZW5zb3JGcm9tVGV4dHVyZU9wdGlvbnM8VD4sXG4pOiBUZW5zb3IgPT4ge1xuICBjb25zdCB7IHdpZHRoLCBoZWlnaHQsIGRvd25sb2FkLCBkaXNwb3NlIH0gPSBvcHRpb25zO1xuICAvLyBBbHdheXMgYXNzdW1lIFJHQkFGMzIuIFRPRE86IHN1cHBvcnQgZGlmZmVyZW50IHRleHR1cmUgZm9ybWF0XG4gIGNvbnN0IGRpbXMgPSBbMSwgaGVpZ2h0LCB3aWR0aCwgNF07XG4gIHJldHVybiBuZXcgVGVuc29yKHsgbG9jYXRpb246ICd0ZXh0dXJlJywgdHlwZTogJ2Zsb2F0MzInLCB0ZXh0dXJlLCBkaW1zLCBkb3dubG9hZCwgZGlzcG9zZSB9KTtcbn07XG5cbi8qKlxuICogaW1wbGVtZW50YXRpb24gb2YgVGVuc29yLmZyb21HcHVCdWZmZXIoKS5cbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvckZyb21HcHVCdWZmZXIgPSA8VCBleHRlbmRzIFRlbnNvckludGVyZmFjZS5HcHVCdWZmZXJEYXRhVHlwZXM+KFxuICBncHVCdWZmZXI6IFRlbnNvckludGVyZmFjZS5HcHVCdWZmZXJUeXBlLFxuICBvcHRpb25zOiBUZW5zb3JGcm9tR3B1QnVmZmVyT3B0aW9uczxUPixcbik6IFRlbnNvciA9PiB7XG4gIGNvbnN0IHsgZGF0YVR5cGUsIGRpbXMsIGRvd25sb2FkLCBkaXNwb3NlIH0gPSBvcHRpb25zO1xuICByZXR1cm4gbmV3IFRlbnNvcih7IGxvY2F0aW9uOiAnZ3B1LWJ1ZmZlcicsIHR5cGU6IGRhdGFUeXBlID8/ICdmbG9hdDMyJywgZ3B1QnVmZmVyLCBkaW1zLCBkb3dubG9hZCwgZGlzcG9zZSB9KTtcbn07XG5cbi8qKlxuICogaW1wbGVtZW50YXRpb24gb2YgVGVuc29yLmZyb21NTFRlbnNvcigpLlxuICovXG5leHBvcnQgY29uc3QgdGVuc29yRnJvbU1MVGVuc29yID0gPFQgZXh0ZW5kcyBUZW5zb3JJbnRlcmZhY2UuTUxUZW5zb3JEYXRhVHlwZXM+KFxuICBtbFRlbnNvcjogVGVuc29ySW50ZXJmYWNlLk1MVGVuc29yVHlwZSxcbiAgb3B0aW9uczogVGVuc29yRnJvbU1MVGVuc29yT3B0aW9uczxUPixcbik6IFRlbnNvciA9PiB7XG4gIGNvbnN0IHsgZGF0YVR5cGUsIGRpbXMsIGRvd25sb2FkLCBkaXNwb3NlIH0gPSBvcHRpb25zO1xuICByZXR1cm4gbmV3IFRlbnNvcih7IGxvY2F0aW9uOiAnbWwtdGVuc29yJywgdHlwZTogZGF0YVR5cGUgPz8gJ2Zsb2F0MzInLCBtbFRlbnNvciwgZGltcywgZG93bmxvYWQsIGRpc3Bvc2UgfSk7XG59O1xuXG4vKipcbiAqIGltcGxlbWVudGF0aW9uIG9mIFRlbnNvci5mcm9tUGlubmVkQnVmZmVyKCkuXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JGcm9tUGlubmVkQnVmZmVyID0gPFQgZXh0ZW5kcyBUZW5zb3JJbnRlcmZhY2UuQ3B1UGlubmVkRGF0YVR5cGVzPihcbiAgdHlwZTogVCxcbiAgYnVmZmVyOiBUZW5zb3JJbnRlcmZhY2UuRGF0YVR5cGVNYXBbVF0sXG4gIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSxcbik6IFRlbnNvciA9PiBuZXcgVGVuc29yKHsgbG9jYXRpb246ICdjcHUtcGlubmVkJywgdHlwZSwgZGF0YTogYnVmZmVyLCBkaW1zOiBkaW1zID8/IFtidWZmZXIubGVuZ3RoXSB9KTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3IuanMnO1xuXG5leHBvcnQgdHlwZSBTdXBwb3J0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3JzID1cbiAgfCBGbG9hdDMyQXJyYXlDb25zdHJ1Y3RvclxuICB8IFVpbnQ4QXJyYXlDb25zdHJ1Y3RvclxuICB8IEludDhBcnJheUNvbnN0cnVjdG9yXG4gIHwgVWludDE2QXJyYXlDb25zdHJ1Y3RvclxuICB8IEludDE2QXJyYXlDb25zdHJ1Y3RvclxuICB8IEludDMyQXJyYXlDb25zdHJ1Y3RvclxuICB8IEJpZ0ludDY0QXJyYXlDb25zdHJ1Y3RvclxuICB8IFVpbnQ4QXJyYXlDb25zdHJ1Y3RvclxuICB8IEZsb2F0NjRBcnJheUNvbnN0cnVjdG9yXG4gIHwgVWludDMyQXJyYXlDb25zdHJ1Y3RvclxuICB8IEJpZ1VpbnQ2NEFycmF5Q29uc3RydWN0b3I7XG5leHBvcnQgdHlwZSBTdXBwb3J0ZWRUeXBlZEFycmF5ID0gSW5zdGFuY2VUeXBlPFN1cHBvcnRlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvcnM+O1xuXG4vLyBhIHJ1bnRpbWUgbWFwIHRoYXQgbWFwcyB0eXBlIHN0cmluZyB0byBUeXBlZEFycmF5IGNvbnN0cnVjdG9yLiBTaG91bGQgbWF0Y2ggVGVuc29yLkRhdGFUeXBlTWFwLlxuZXhwb3J0IGNvbnN0IE5VTUVSSUNfVEVOU09SX1RZUEVfVE9fVFlQRURBUlJBWV9NQVAgPSBuZXcgTWFwPHN0cmluZywgU3VwcG9ydGVkVHlwZWRBcnJheUNvbnN0cnVjdG9ycz4oW1xuICBbJ2Zsb2F0MzInLCBGbG9hdDMyQXJyYXldLFxuICBbJ3VpbnQ4JywgVWludDhBcnJheV0sXG4gIFsnaW50OCcsIEludDhBcnJheV0sXG4gIFsndWludDE2JywgVWludDE2QXJyYXldLFxuICBbJ2ludDE2JywgSW50MTZBcnJheV0sXG4gIFsnaW50MzInLCBJbnQzMkFycmF5XSxcbiAgWydib29sJywgVWludDhBcnJheV0sXG4gIFsnZmxvYXQ2NCcsIEZsb2F0NjRBcnJheV0sXG4gIFsndWludDMyJywgVWludDMyQXJyYXldLFxuICBbJ2ludDQnLCBVaW50OEFycmF5XSxcbiAgWyd1aW50NCcsIFVpbnQ4QXJyYXldLFxuXSk7XG5cbi8vIGEgcnVudGltZSBtYXAgdGhhdCBtYXBzIHR5cGUgc3RyaW5nIHRvIFR5cGVkQXJyYXkgY29uc3RydWN0b3IuIFNob3VsZCBtYXRjaCBUZW5zb3IuRGF0YVR5cGVNYXAuXG5leHBvcnQgY29uc3QgTlVNRVJJQ19URU5TT1JfVFlQRURBUlJBWV9UT19UWVBFX01BUCA9IG5ldyBNYXA8U3VwcG9ydGVkVHlwZWRBcnJheUNvbnN0cnVjdG9ycywgVGVuc29yLlR5cGU+KFtcbiAgW0Zsb2F0MzJBcnJheSwgJ2Zsb2F0MzInXSxcbiAgW1VpbnQ4QXJyYXksICd1aW50OCddLFxuICBbSW50OEFycmF5LCAnaW50OCddLFxuICBbVWludDE2QXJyYXksICd1aW50MTYnXSxcbiAgW0ludDE2QXJyYXksICdpbnQxNiddLFxuICBbSW50MzJBcnJheSwgJ2ludDMyJ10sXG4gIFtGbG9hdDY0QXJyYXksICdmbG9hdDY0J10sXG4gIFtVaW50MzJBcnJheSwgJ3VpbnQzMiddLFxuXSk7XG5cbi8vIHRoZSBmb2xsb3dpbmcgY29kZSBhbGxvd3MgZGVsYXlpbmcgZXhlY3V0aW9uIG9mIEJpZ0ludC9GbG9hdDE2QXJyYXkgY2hlY2tpbmcuIFRoaXMgYWxsb3dzIGxhenkgaW5pdGlhbGl6YXRpb24gZm9yXG4vLyBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQIGFuZCBOVU1FUklDX1RFTlNPUl9UWVBFREFSUkFZX1RPX1RZUEVfTUFQLCB3aGljaCBhbGxvd3MgQmlnSW50L0Zsb2F0MTZBcnJheVxuLy8gcG9seWZpbGwgaWYgYXZhaWxhYmxlLlxubGV0IGlzVHlwZWRBcnJheUNoZWNrZWQgPSBmYWxzZTtcbmV4cG9ydCBjb25zdCBjaGVja1R5cGVkQXJyYXkgPSAoKSA9PiB7XG4gIGlmICghaXNUeXBlZEFycmF5Q2hlY2tlZCkge1xuICAgIGlzVHlwZWRBcnJheUNoZWNrZWQgPSB0cnVlO1xuICAgIGNvbnN0IGlzQmlnSW50NjRBcnJheUF2YWlsYWJsZSA9IHR5cGVvZiBCaWdJbnQ2NEFycmF5ICE9PSAndW5kZWZpbmVkJyAmJiBCaWdJbnQ2NEFycmF5LmZyb207XG4gICAgY29uc3QgaXNCaWdVaW50NjRBcnJheUF2YWlsYWJsZSA9IHR5cGVvZiBCaWdVaW50NjRBcnJheSAhPT0gJ3VuZGVmaW5lZCcgJiYgQmlnVWludDY0QXJyYXkuZnJvbTtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24sIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCBGbG9hdDE2QXJyYXkgPSAoZ2xvYmFsVGhpcyBhcyBhbnkpLkZsb2F0MTZBcnJheTtcbiAgICBjb25zdCBpc0Zsb2F0MTZBcnJheUF2YWlsYWJsZSA9IHR5cGVvZiBGbG9hdDE2QXJyYXkgIT09ICd1bmRlZmluZWQnICYmIEZsb2F0MTZBcnJheS5mcm9tO1xuXG4gICAgaWYgKGlzQmlnSW50NjRBcnJheUF2YWlsYWJsZSkge1xuICAgICAgTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUC5zZXQoJ2ludDY0JywgQmlnSW50NjRBcnJheSk7XG4gICAgICBOVU1FUklDX1RFTlNPUl9UWVBFREFSUkFZX1RPX1RZUEVfTUFQLnNldChCaWdJbnQ2NEFycmF5LCAnaW50NjQnKTtcbiAgICB9XG4gICAgaWYgKGlzQmlnVWludDY0QXJyYXlBdmFpbGFibGUpIHtcbiAgICAgIE5VTUVSSUNfVEVOU09SX1RZUEVfVE9fVFlQRURBUlJBWV9NQVAuc2V0KCd1aW50NjQnLCBCaWdVaW50NjRBcnJheSk7XG4gICAgICBOVU1FUklDX1RFTlNPUl9UWVBFREFSUkFZX1RPX1RZUEVfTUFQLnNldChCaWdVaW50NjRBcnJheSwgJ3VpbnQ2NCcpO1xuICAgIH1cbiAgICBpZiAoaXNGbG9hdDE2QXJyYXlBdmFpbGFibGUpIHtcbiAgICAgIE5VTUVSSUNfVEVOU09SX1RZUEVfVE9fVFlQRURBUlJBWV9NQVAuc2V0KCdmbG9hdDE2JywgRmxvYXQxNkFycmF5KTtcbiAgICAgIE5VTUVSSUNfVEVOU09SX1RZUEVEQVJSQVlfVE9fVFlQRV9NQVAuc2V0KEZsb2F0MTZBcnJheSwgJ2Zsb2F0MTYnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaWYgRmxvYXQxNkFycmF5IGlzIG5vdCBhdmFpbGFibGUsIHVzZSAnVWludDE2QXJyYXknIHRvIHN0b3JlIHRoZSBkYXRhLlxuICAgICAgTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUC5zZXQoJ2Zsb2F0MTYnLCBVaW50MTZBcnJheSk7XG4gICAgfVxuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1xuICBDcHVQaW5uZWRDb25zdHJ1Y3RvclBhcmFtZXRlcnMsXG4gIEdwdUJ1ZmZlckNvbnN0cnVjdG9yUGFyYW1ldGVycyxcbiAgTUxUZW5zb3JDb25zdHJ1Y3RvclBhcmFtZXRlcnMsXG4gIFRleHR1cmVDb25zdHJ1Y3RvclBhcmFtZXRlcnMsXG59IGZyb20gJy4vdGVuc29yLWZhY3RvcnkuanMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3ItaW1wbC5qcyc7XG5cbi8qKlxuICogY2FsY3VsYXRlIHNpemUgZnJvbSBkaW1zLlxuICpcbiAqIEBwYXJhbSBkaW1zIHRoZSBkaW1zIGFycmF5LiBNYXkgYmUgYW4gaWxsZWdhbCBpbnB1dC5cbiAqL1xuZXhwb3J0IGNvbnN0IGNhbGN1bGF0ZVNpemUgPSAoZGltczogcmVhZG9ubHkgdW5rbm93bltdKTogbnVtYmVyID0+IHtcbiAgbGV0IHNpemUgPSAxO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBkaW0gPSBkaW1zW2ldO1xuICAgIGlmICh0eXBlb2YgZGltICE9PSAnbnVtYmVyJyB8fCAhTnVtYmVyLmlzU2FmZUludGVnZXIoZGltKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgZGltc1ske2l9XSBtdXN0IGJlIGFuIGludGVnZXIsIGdvdDogJHtkaW19YCk7XG4gICAgfVxuICAgIGlmIChkaW0gPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgZGltc1ske2l9XSBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIsIGdvdDogJHtkaW19YCk7XG4gICAgfVxuICAgIHNpemUgKj0gZGltO1xuICB9XG4gIHJldHVybiBzaXplO1xufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IucmVzaGFwZSgpXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JSZXNoYXBlID0gKHRlbnNvcjogVGVuc29yLCBkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IFRlbnNvciA9PiB7XG4gIHN3aXRjaCAodGVuc29yLmxvY2F0aW9uKSB7XG4gICAgY2FzZSAnY3B1JzpcbiAgICAgIHJldHVybiBuZXcgVGVuc29yKHRlbnNvci50eXBlLCB0ZW5zb3IuZGF0YSwgZGltcyk7XG4gICAgY2FzZSAnY3B1LXBpbm5lZCc6XG4gICAgICByZXR1cm4gbmV3IFRlbnNvcih7XG4gICAgICAgIGxvY2F0aW9uOiAnY3B1LXBpbm5lZCcsXG4gICAgICAgIGRhdGE6IHRlbnNvci5kYXRhIGFzIENwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVyc1snZGF0YSddLFxuICAgICAgICB0eXBlOiB0ZW5zb3IudHlwZSBhcyBDcHVQaW5uZWRDb25zdHJ1Y3RvclBhcmFtZXRlcnNbJ3R5cGUnXSxcbiAgICAgICAgZGltcyxcbiAgICAgIH0pO1xuICAgIGNhc2UgJ3RleHR1cmUnOlxuICAgICAgcmV0dXJuIG5ldyBUZW5zb3Ioe1xuICAgICAgICBsb2NhdGlvbjogJ3RleHR1cmUnLFxuICAgICAgICB0ZXh0dXJlOiB0ZW5zb3IudGV4dHVyZSxcbiAgICAgICAgdHlwZTogdGVuc29yLnR5cGUgYXMgVGV4dHVyZUNvbnN0cnVjdG9yUGFyYW1ldGVyc1sndHlwZSddLFxuICAgICAgICBkaW1zLFxuICAgICAgfSk7XG4gICAgY2FzZSAnZ3B1LWJ1ZmZlcic6XG4gICAgICByZXR1cm4gbmV3IFRlbnNvcih7XG4gICAgICAgIGxvY2F0aW9uOiAnZ3B1LWJ1ZmZlcicsXG4gICAgICAgIGdwdUJ1ZmZlcjogdGVuc29yLmdwdUJ1ZmZlcixcbiAgICAgICAgdHlwZTogdGVuc29yLnR5cGUgYXMgR3B1QnVmZmVyQ29uc3RydWN0b3JQYXJhbWV0ZXJzWyd0eXBlJ10sXG4gICAgICAgIGRpbXMsXG4gICAgICB9KTtcbiAgICBjYXNlICdtbC10ZW5zb3InOlxuICAgICAgcmV0dXJuIG5ldyBUZW5zb3Ioe1xuICAgICAgICBsb2NhdGlvbjogJ21sLXRlbnNvcicsXG4gICAgICAgIG1sVGVuc29yOiB0ZW5zb3IubWxUZW5zb3IsXG4gICAgICAgIHR5cGU6IHRlbnNvci50eXBlIGFzIE1MVGVuc29yQ29uc3RydWN0b3JQYXJhbWV0ZXJzWyd0eXBlJ10sXG4gICAgICAgIGRpbXMsXG4gICAgICB9KTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGB0ZW5zb3JSZXNoYXBlOiB0ZW5zb3IgbG9jYXRpb24gJHt0ZW5zb3IubG9jYXRpb259IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgdGVuc29yVG9EYXRhVVJMLCB0ZW5zb3JUb0ltYWdlRGF0YSB9IGZyb20gJy4vdGVuc29yLWNvbnZlcnNpb24taW1wbC5qcyc7XG5pbXBvcnQgeyBUZW5zb3JUb0RhdGFVcmxPcHRpb25zLCBUZW5zb3JUb0ltYWdlRGF0YU9wdGlvbnMgfSBmcm9tICcuL3RlbnNvci1jb252ZXJzaW9uLmpzJztcbmltcG9ydCB7XG4gIHRlbnNvckZyb21HcHVCdWZmZXIsXG4gIHRlbnNvckZyb21JbWFnZSxcbiAgdGVuc29yRnJvbU1MVGVuc29yLFxuICB0ZW5zb3JGcm9tUGlubmVkQnVmZmVyLFxuICB0ZW5zb3JGcm9tVGV4dHVyZSxcbn0gZnJvbSAnLi90ZW5zb3ItZmFjdG9yeS1pbXBsLmpzJztcbmltcG9ydCB7XG4gIENwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVycyxcbiAgR3B1QnVmZmVyQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxuICBNTFRlbnNvckNvbnN0cnVjdG9yUGFyYW1ldGVycyxcbiAgVGVuc29yRnJvbUdwdUJ1ZmZlck9wdGlvbnMsXG4gIFRlbnNvckZyb21JbWFnZUJpdG1hcE9wdGlvbnMsXG4gIFRlbnNvckZyb21JbWFnZURhdGFPcHRpb25zLFxuICBUZW5zb3JGcm9tSW1hZ2VFbGVtZW50T3B0aW9ucyxcbiAgVGVuc29yRnJvbU1MVGVuc29yT3B0aW9ucyxcbiAgVGVuc29yRnJvbVRleHR1cmVPcHRpb25zLFxuICBUZW5zb3JGcm9tVXJsT3B0aW9ucyxcbiAgVGV4dHVyZUNvbnN0cnVjdG9yUGFyYW1ldGVycyxcbn0gZnJvbSAnLi90ZW5zb3ItZmFjdG9yeS5qcyc7XG5pbXBvcnQge1xuICBjaGVja1R5cGVkQXJyYXksXG4gIE5VTUVSSUNfVEVOU09SX1RZUEVfVE9fVFlQRURBUlJBWV9NQVAsXG4gIE5VTUVSSUNfVEVOU09SX1RZUEVEQVJSQVlfVE9fVFlQRV9NQVAsXG4gIFN1cHBvcnRlZFR5cGVkQXJyYXksXG4gIFN1cHBvcnRlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvcnMsXG59IGZyb20gJy4vdGVuc29yLWltcGwtdHlwZS1tYXBwaW5nLmpzJztcbmltcG9ydCB7IGNhbGN1bGF0ZVNpemUsIHRlbnNvclJlc2hhcGUgfSBmcm9tICcuL3RlbnNvci11dGlscy1pbXBsLmpzJztcbmltcG9ydCB7IFRlbnNvciBhcyBUZW5zb3JJbnRlcmZhY2UgfSBmcm9tICcuL3RlbnNvci5qcyc7XG5cbi8vIHR5cGUgYWxpYXNlcyBmb3IgdGhvc2UgZXhwb3J0ZWQgZnJvbSBUZW5zb3IgaW50ZXJmYWNlXG5cbnR5cGUgVGVuc29yVHlwZSA9IFRlbnNvckludGVyZmFjZS5UeXBlO1xudHlwZSBUZW5zb3JEYXRhVHlwZSA9IFRlbnNvckludGVyZmFjZS5EYXRhVHlwZTtcbnR5cGUgVGVuc29yRGF0YUxvY2F0aW9uID0gVGVuc29ySW50ZXJmYWNlLkRhdGFMb2NhdGlvbjtcbnR5cGUgVGVuc29yVGV4dHVyZVR5cGUgPSBUZW5zb3JJbnRlcmZhY2UuVGV4dHVyZVR5cGU7XG50eXBlIFRlbnNvckdwdUJ1ZmZlclR5cGUgPSBUZW5zb3JJbnRlcmZhY2UuR3B1QnVmZmVyVHlwZTtcbnR5cGUgVGVuc29yTUxUZW5zb3JUeXBlID0gVGVuc29ySW50ZXJmYWNlLk1MVGVuc29yVHlwZTtcblxuLyoqXG4gKiB0aGUgaW1wbGVtZW50YXRpb24gb2YgVGVuc29yIGludGVyZmFjZS5cbiAqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBUZW5zb3IgaW1wbGVtZW50cyBUZW5zb3JJbnRlcmZhY2Uge1xuICAvLyAjcmVnaW9uIGNvbnN0cnVjdG9yc1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgQ1BVIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gdHlwZSwgZGF0YSBhbmQgZGltcy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHR5cGU6IFRlbnNvclR5cGUsXG4gICAgZGF0YTogVGVuc29yRGF0YVR5cGUgfCBVaW50OENsYW1wZWRBcnJheSB8IHJlYWRvbmx5IHN0cmluZ1tdIHwgcmVhZG9ubHkgbnVtYmVyW10gfCByZWFkb25seSBib29sZWFuW10sXG4gICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuICApO1xuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IENQVSB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuIFR5cGUgaXMgaW5mZXJyZWQgZnJvbSBkYXRhLlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgZGF0YTogVGVuc29yRGF0YVR5cGUgfCBVaW50OENsYW1wZWRBcnJheSB8IHJlYWRvbmx5IHN0cmluZ1tdIHwgcmVhZG9ubHkgYm9vbGVhbltdLFxuICAgIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTtcbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIHBpbm5lZCBDUFUgZGF0YSB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZCBkaW1zLlxuICAgKlxuICAgKiBUZW5zb3IncyBsb2NhdGlvbiB3aWxsIGJlIHNldCB0byAnY3B1LXBpbm5lZCcuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBTcGVjaWZ5IHRoZSBwYXJhbWV0ZXJzIHRvIGNvbnN0cnVjdCB0aGUgdGVuc29yLlxuICAgKi9cbiAgY29uc3RydWN0b3IocGFyYW1zOiBDcHVQaW5uZWRDb25zdHJ1Y3RvclBhcmFtZXRlcnMpO1xuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgV2ViR0wgdGV4dHVyZSB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZCBkaW1zLlxuICAgKlxuICAgKiBUZW5zb3IncyBsb2NhdGlvbiB3aWxsIGJlIHNldCB0byAndGV4dHVyZScuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBTcGVjaWZ5IHRoZSBwYXJhbWV0ZXJzIHRvIGNvbnN0cnVjdCB0aGUgdGVuc29yLlxuICAgKi9cbiAgY29uc3RydWN0b3IocGFyYW1zOiBUZXh0dXJlQ29uc3RydWN0b3JQYXJhbWV0ZXJzKTtcbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIFdlYkdQVSBidWZmZXIgd2l0aCB0aGUgZ2l2ZW4gdHlwZSBhbmQgZGltcy5cbiAgICpcbiAgICogVGVuc29yJ3MgbG9jYXRpb24gd2lsbCBiZSBzZXQgdG8gJ2dwdS1idWZmZXInLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gU3BlY2lmeSB0aGUgcGFyYW1ldGVycyB0byBjb25zdHJ1Y3QgdGhlIHRlbnNvci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHBhcmFtczogR3B1QnVmZmVyQ29uc3RydWN0b3JQYXJhbWV0ZXJzKTtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgV2ViTk4gTUxUZW5zb3Igd2l0aCB0aGUgZ2l2ZW4gdHlwZSBhbmQgZGltcy5cbiAgICpcbiAgICogVGVuc29yJ3MgbG9jYXRpb24gd2lsbCBiZSBzZXQgdG8gJ21sLXRlbnNvcicuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBTcGVjaWZ5IHRoZSBwYXJhbWV0ZXJzIHRvIGNvbnN0cnVjdCB0aGUgdGVuc29yLlxuICAgKi9cbiAgY29uc3RydWN0b3IocGFyYW1zOiBNTFRlbnNvckNvbnN0cnVjdG9yUGFyYW1ldGVycyk7XG5cbiAgLyoqXG4gICAqIGltcGxlbWVudGF0aW9uLlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgYXJnMDpcbiAgICAgIHwgVGVuc29yVHlwZVxuICAgICAgfCBUZW5zb3JEYXRhVHlwZVxuICAgICAgfCBVaW50OENsYW1wZWRBcnJheVxuICAgICAgfCByZWFkb25seSBzdHJpbmdbXVxuICAgICAgfCByZWFkb25seSBib29sZWFuW11cbiAgICAgIHwgQ3B1UGlubmVkQ29uc3RydWN0b3JQYXJhbWV0ZXJzXG4gICAgICB8IFRleHR1cmVDb25zdHJ1Y3RvclBhcmFtZXRlcnNcbiAgICAgIHwgR3B1QnVmZmVyQ29uc3RydWN0b3JQYXJhbWV0ZXJzXG4gICAgICB8IE1MVGVuc29yQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxuICAgIGFyZzE/OiBUZW5zb3JEYXRhVHlwZSB8IFVpbnQ4Q2xhbXBlZEFycmF5IHwgcmVhZG9ubHkgbnVtYmVyW10gfCByZWFkb25seSBzdHJpbmdbXSB8IHJlYWRvbmx5IGJvb2xlYW5bXSxcbiAgICBhcmcyPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICkge1xuICAgIC8vIHBlcmZvcm0gb25lLXRpbWUgY2hlY2sgZm9yIEJpZ0ludC9GbG9hdDE2QXJyYXkgc3VwcG9ydFxuICAgIGNoZWNrVHlwZWRBcnJheSgpO1xuXG4gICAgbGV0IHR5cGU6IFRlbnNvclR5cGU7XG4gICAgbGV0IGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gICAgaWYgKHR5cGVvZiBhcmcwID09PSAnb2JqZWN0JyAmJiAnbG9jYXRpb24nIGluIGFyZzApIHtcbiAgICAgIC8vXG4gICAgICAvLyBjb25zdHJ1Y3RpbmcgdGVuc29yIGZyb20gc3BlY2lmaWMgbG9jYXRpb25cbiAgICAgIC8vXG4gICAgICB0aGlzLmRhdGFMb2NhdGlvbiA9IGFyZzAubG9jYXRpb247XG4gICAgICB0eXBlID0gYXJnMC50eXBlO1xuICAgICAgZGltcyA9IGFyZzAuZGltcztcbiAgICAgIHN3aXRjaCAoYXJnMC5sb2NhdGlvbikge1xuICAgICAgICBjYXNlICdjcHUtcGlubmVkJzoge1xuICAgICAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZWRBcnJheUNvbnN0cnVjdG9yID0gTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUC5nZXQodHlwZSk7XG4gICAgICAgICAgaWYgKCFleHBlY3RlZFR5cGVkQXJyYXlDb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgdW5zdXBwb3J0ZWQgdHlwZSBcIiR7dHlwZX1cIiB0byBjcmVhdGUgdGVuc29yIGZyb20gcGlubmVkIGJ1ZmZlcmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIShhcmcwLmRhdGEgaW5zdGFuY2VvZiBleHBlY3RlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYGJ1ZmZlciBzaG91bGQgYmUgb2YgdHlwZSAke2V4cGVjdGVkVHlwZWRBcnJheUNvbnN0cnVjdG9yLm5hbWV9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuY3B1RGF0YSA9IGFyZzAuZGF0YTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICd0ZXh0dXJlJzoge1xuICAgICAgICAgIGlmICh0eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYHVuc3VwcG9ydGVkIHR5cGUgXCIke3R5cGV9XCIgdG8gY3JlYXRlIHRlbnNvciBmcm9tIHRleHR1cmVgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5ncHVUZXh0dXJlRGF0YSA9IGFyZzAudGV4dHVyZTtcbiAgICAgICAgICB0aGlzLmRvd25sb2FkZXIgPSBhcmcwLmRvd25sb2FkO1xuICAgICAgICAgIHRoaXMuZGlzcG9zZXIgPSBhcmcwLmRpc3Bvc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnZ3B1LWJ1ZmZlcic6IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0eXBlICE9PSAnZmxvYXQzMicgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICdmbG9hdDE2JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2ludDMyJyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2ludDY0JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ3VpbnQzMicgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICd1aW50OCcgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICdib29sJyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ3VpbnQ0JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2ludDQnXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGB1bnN1cHBvcnRlZCB0eXBlIFwiJHt0eXBlfVwiIHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbSBncHUgYnVmZmVyYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuZ3B1QnVmZmVyRGF0YSA9IGFyZzAuZ3B1QnVmZmVyO1xuICAgICAgICAgIHRoaXMuZG93bmxvYWRlciA9IGFyZzAuZG93bmxvYWQ7XG4gICAgICAgICAgdGhpcy5kaXNwb3NlciA9IGFyZzAuZGlzcG9zZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdtbC10ZW5zb3InOiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdHlwZSAhPT0gJ2Zsb2F0MzInICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnZmxvYXQxNicgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICdpbnQzMicgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICdpbnQ2NCcgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICd1aW50MzInICYmXG4gICAgICAgICAgICB0eXBlICE9PSAndWludDY0JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2ludDgnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAndWludDgnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnYm9vbCcgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICd1aW50NCcgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICdpbnQ0J1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgdW5zdXBwb3J0ZWQgdHlwZSBcIiR7dHlwZX1cIiB0byBjcmVhdGUgdGVuc29yIGZyb20gTUxUZW5zb3JgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5tbFRlbnNvckRhdGEgPSBhcmcwLm1sVGVuc29yO1xuICAgICAgICAgIHRoaXMuZG93bmxvYWRlciA9IGFyZzAuZG93bmxvYWQ7XG4gICAgICAgICAgdGhpcy5kaXNwb3NlciA9IGFyZzAuZGlzcG9zZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVGVuc29yIGNvbnN0cnVjdG9yOiB1bnN1cHBvcnRlZCBsb2NhdGlvbiAnJHt0aGlzLmRhdGFMb2NhdGlvbn0nYCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vXG4gICAgICAvLyBjb25zdHJ1Y3RpbmcgdGVuc29yIG9mIGxvY2F0aW9uICdjcHUnXG4gICAgICAvL1xuICAgICAgbGV0IGRhdGE6IFRlbnNvckRhdGFUeXBlO1xuICAgICAgbGV0IG1heWJlRGltczogdHlwZW9mIGFyZzEgfCB0eXBlb2YgYXJnMjtcbiAgICAgIC8vIGNoZWNrIHdoZXRoZXIgYXJnMCBpcyB0eXBlIG9yIGRhdGFcbiAgICAgIGlmICh0eXBlb2YgYXJnMCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgLy9cbiAgICAgICAgLy8gT3ZlcnJpZGU6IGNvbnN0cnVjdG9yKHR5cGUsIGRhdGEsIC4uLilcbiAgICAgICAgLy9cbiAgICAgICAgdHlwZSA9IGFyZzA7XG4gICAgICAgIG1heWJlRGltcyA9IGFyZzI7XG4gICAgICAgIGlmIChhcmcwID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIC8vIHN0cmluZyB0ZW5zb3JcbiAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoYXJnMSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJBIHN0cmluZyB0ZW5zb3IncyBkYXRhIG11c3QgYmUgYSBzdHJpbmcgYXJyYXkuXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyB3ZSBkb24ndCBjaGVjayB3aGV0aGVyIGV2ZXJ5IGVsZW1lbnQgaW4gdGhlIGFycmF5IGlzIHN0cmluZzsgdGhpcyBpcyB0b28gc2xvdy4gd2UgYXNzdW1lIGl0J3MgY29ycmVjdCBhbmRcbiAgICAgICAgICAvLyBlcnJvciB3aWxsIGJlIHBvcHVsYXRlZCBhdCBpbmZlcmVuY2VcbiAgICAgICAgICBkYXRhID0gYXJnMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBudW1lcmljIHRlbnNvclxuICAgICAgICAgIGNvbnN0IHR5cGVkQXJyYXlDb25zdHJ1Y3RvciA9IE5VTUVSSUNfVEVOU09SX1RZUEVfVE9fVFlQRURBUlJBWV9NQVAuZ2V0KGFyZzApO1xuICAgICAgICAgIGlmICh0eXBlZEFycmF5Q29uc3RydWN0b3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgVW5zdXBwb3J0ZWQgdGVuc29yIHR5cGU6ICR7YXJnMH0uYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGFyZzEpKSB7XG4gICAgICAgICAgICBpZiAoKGFyZzAgPT09ICdmbG9hdDE2JyAmJiB0eXBlZEFycmF5Q29uc3RydWN0b3IgPT09IFVpbnQxNkFycmF5KSB8fCBhcmcwID09PSAndWludDQnIHx8IGFyZzAgPT09ICdpbnQ0Jykge1xuICAgICAgICAgICAgICAvLyAtICdmbG9hdDE2JzpcbiAgICAgICAgICAgICAgLy8gICBXaGVuIG5vIEZsb2F0MTZBcnJheSBwb2x5ZmlsbCBpcyB1c2VkLCB3ZSBjYW5ub3QgY3JlYXRlICdmbG9hdDE2JyB0ZW5zb3IgZnJvbSBudW1iZXIgYXJyYXkuXG4gICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgIC8vICAgVGhyb3cgZXJyb3IgaGVyZSBiZWNhdXNlIHdoZW4gdXNlciB0cnkgdG8gdXNlIG51bWJlciBhcnJheSBhcyBkYXRhLFxuICAgICAgICAgICAgICAvLyAgIGUuZy4gbmV3IFRlbnNvcignZmxvYXQxNicsIFsxLCAyLCAzLCA0XSwgZGltcykpLCBpdCB3aWxsIGFjdHVhbGx5IGNhbGxcbiAgICAgICAgICAgICAgLy8gICBVaW50MTZBcnJheS5mcm9tKGFyZzEpIHdoaWNoIGdlbmVyYXRlcyB3cm9uZyBkYXRhLlxuICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAvLyAtICd1aW50NCcgYW5kICdpbnQ0JzpcbiAgICAgICAgICAgICAgLy8gICBVaW50OEFycmF5LmZyb20oYXJnMSkgd2lsbCBnZW5lcmF0ZSB3cm9uZyBkYXRhIGZvciAndWludDQnIGFuZCAnaW50NCcgdGVuc29yLlxuICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgICAgIGBDcmVhdGluZyBhICR7YXJnMH0gdGVuc29yIGZyb20gbnVtYmVyIGFycmF5IGlzIG5vdCBzdXBwb3J0ZWQuIFBsZWFzZSB1c2UgJHt0eXBlZEFycmF5Q29uc3RydWN0b3IubmFtZX0gYXMgZGF0YS5gLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcwID09PSAndWludDY0JyB8fCBhcmcwID09PSAnaW50NjQnKSB7XG4gICAgICAgICAgICAgIC8vIHVzZSAnYXMgYW55JyBoZXJlIGJlY2F1c2U6XG4gICAgICAgICAgICAgIC8vIDEuIFR5cGVTY3JpcHQncyBjaGVjayBvbiB0eXBlIG9mICdBcnJheS5pc0FycmF5KCknIGRvZXMgbm90IHdvcmsgd2l0aCByZWFkb25seSBhcnJheXMuXG4gICAgICAgICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L1R5cGVTY3JpcHQvaXNzdWVzLzE3MDAyXG4gICAgICAgICAgICAgIC8vIDIuIFR5cGVTY3JpcHQncyBjaGVjayBvbiB1bmlvbiB0eXBlIG9mICcoQmlnSW50NjRBcnJheUNvbnN0cnVjdG9yfEJpZ1VpbnQ2NEFycmF5Q29uc3RydWN0b3IpLmZyb20oKSdcbiAgICAgICAgICAgICAgLy8gZG9lcyBub3QgYWNjZXB0IHBhcmFtZXRlciBtYXBGbi5cbiAgICAgICAgICAgICAgLy8gMy4gcGFyYW1ldGVycyBvZiAnU3VwcG9ydGVkVHlwZWRBcnJheUNvbnN0cnVjdG9ycy5mcm9tKCknIGRvZXMgbm90IG1hdGNoIHRoZSByZXF1aXJlbWVudCBvZiB0aGUgdW5pb25cbiAgICAgICAgICAgICAgLy8gdHlwZS5cblxuICAgICAgICAgICAgICAvLyBhc3N1bWUgJ2FyZzEnIGlzIG9mIHR5cGUgXCJyZWFkb25seSBudW1iZXJbXXxyZWFkb25seSBiaWdpbnRbXVwiIGhlcmUuXG5cbiAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgICAgICAgZGF0YSA9ICh0eXBlZEFycmF5Q29uc3RydWN0b3IgYXMgYW55KS5mcm9tKGFyZzEsIEJpZ0ludCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBhc3N1bWUgJ2FyZzEnIGlzIG9mIHR5cGUgXCJyZWFkb25seSBudW1iZXJbXVwiIGhlcmUuXG4gICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICAgICAgIGRhdGEgPSAodHlwZWRBcnJheUNvbnN0cnVjdG9yIGFzIGFueSkuZnJvbShhcmcxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKGFyZzEgaW5zdGFuY2VvZiB0eXBlZEFycmF5Q29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgIGRhdGEgPSBhcmcxO1xuICAgICAgICAgIH0gZWxzZSBpZiAoYXJnMSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5KSB7XG4gICAgICAgICAgICBpZiAoYXJnMCA9PT0gJ3VpbnQ4Jykge1xuICAgICAgICAgICAgICBkYXRhID0gVWludDhBcnJheS5mcm9tKGFyZzEpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgQSBVaW50OENsYW1wZWRBcnJheSB0ZW5zb3IncyBkYXRhIG11c3QgYmUgdHlwZSBvZiB1aW50OGApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoYXJnMCA9PT0gJ2Zsb2F0MTYnICYmIGFyZzEgaW5zdGFuY2VvZiBVaW50MTZBcnJheSAmJiB0eXBlZEFycmF5Q29uc3RydWN0b3IgIT09IFVpbnQxNkFycmF5KSB7XG4gICAgICAgICAgICAvLyB3aGVuIEZsb2F0MTZBcnJheSBpcyBhdmFpbGFibGUgYW5kIGRhdGEgaXMgb2YgdHlwZSBVaW50MTZBcnJheS5cbiAgICAgICAgICAgIC8vIFdlIGFsbG93IFVpbnQxNkFycmF5IHRvIGJlIHBhc3NlZCBpbiBhcyBkYXRhIGZvciAnZmxvYXQxNicgdGVuc29yIHVudGlsIEZsb2F0MTZBcnJheSBpcyBnZW5lcmFsbHlcbiAgICAgICAgICAgIC8vIHN1cHBvcnRlZCBpbiBKYXZhU2NyaXB0IGVudmlyb25tZW50LlxuXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAgICAgZGF0YSA9IG5ldyAoZ2xvYmFsVGhpcyBhcyBhbnkpLkZsb2F0MTZBcnJheShhcmcxLmJ1ZmZlciwgYXJnMS5ieXRlT2Zmc2V0LCBhcmcxLmxlbmd0aCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEEgJHt0eXBlfSB0ZW5zb3IncyBkYXRhIG11c3QgYmUgdHlwZSBvZiAke3R5cGVkQXJyYXlDb25zdHJ1Y3Rvcn1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vXG4gICAgICAgIC8vIE92ZXJyaWRlOiBjb25zdHJ1Y3RvcihkYXRhLCAuLi4pXG4gICAgICAgIC8vXG4gICAgICAgIG1heWJlRGltcyA9IGFyZzE7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGFyZzApKSB7XG4gICAgICAgICAgLy8gb25seSBib29sZWFuW10gYW5kIHN0cmluZ1tdIGlzIHN1cHBvcnRlZFxuICAgICAgICAgIGlmIChhcmcwLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGVuc29yIHR5cGUgY2Fubm90IGJlIGluZmVycmVkIGZyb20gYW4gZW1wdHkgYXJyYXkuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGZpcnN0RWxlbWVudFR5cGUgPSB0eXBlb2YgYXJnMFswXTtcbiAgICAgICAgICBpZiAoZmlyc3RFbGVtZW50VHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHR5cGUgPSAnc3RyaW5nJztcbiAgICAgICAgICAgIGRhdGEgPSBhcmcwO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZmlyc3RFbGVtZW50VHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICB0eXBlID0gJ2Jvb2wnO1xuICAgICAgICAgICAgLy8gJ2FyZzAnIGlzIG9mIHR5cGUgJ2Jvb2xlYW5bXScuIFVpbnQ4QXJyYXkuZnJvbShib29sZWFuW10pIGFjdHVhbGx5IHdvcmtzLCBidXQgdHlwZXNjcmlwdCB0aGlua3MgdGhpcyBpc1xuICAgICAgICAgICAgLy8gd3JvbmcgdHlwZS4gV2UgdXNlICdhcyBhbnknIHRvIG1ha2UgaXQgaGFwcHkuXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAgICAgZGF0YSA9IFVpbnQ4QXJyYXkuZnJvbShhcmcwIGFzIGFueVtdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgSW52YWxpZCBlbGVtZW50IHR5cGUgb2YgZGF0YSBhcnJheTogJHtmaXJzdEVsZW1lbnRUeXBlfS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoYXJnMCBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5KSB7XG4gICAgICAgICAgdHlwZSA9ICd1aW50OCc7XG4gICAgICAgICAgZGF0YSA9IFVpbnQ4QXJyYXkuZnJvbShhcmcwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBnZXQgdGVuc29yIHR5cGUgZnJvbSBUeXBlZEFycmF5XG4gICAgICAgICAgY29uc3QgbWFwcGVkVHlwZSA9IE5VTUVSSUNfVEVOU09SX1RZUEVEQVJSQVlfVE9fVFlQRV9NQVAuZ2V0KFxuICAgICAgICAgICAgYXJnMC5jb25zdHJ1Y3RvciBhcyBTdXBwb3J0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3JzLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKG1hcHBlZFR5cGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgVW5zdXBwb3J0ZWQgdHlwZSBmb3IgdGVuc29yIGRhdGE6ICR7YXJnMC5jb25zdHJ1Y3Rvcn0uYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHR5cGUgPSBtYXBwZWRUeXBlO1xuICAgICAgICAgIGRhdGEgPSBhcmcwIGFzIFN1cHBvcnRlZFR5cGVkQXJyYXk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gdHlwZSBhbmQgZGF0YSBpcyBwcm9jZXNzZWQsIG5vdyBwcm9jZXNzaW5nIGRpbXNcbiAgICAgIGlmIChtYXliZURpbXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBhc3N1bWUgMS1EIHRlbnNvciBpZiBkaW1zIG9taXR0ZWRcbiAgICAgICAgbWF5YmVEaW1zID0gW2RhdGEubGVuZ3RoXTtcbiAgICAgIH0gZWxzZSBpZiAoIUFycmF5LmlzQXJyYXkobWF5YmVEaW1zKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQSB0ZW5zb3IncyBkaW1zIG11c3QgYmUgYSBudW1iZXIgYXJyYXlcIik7XG4gICAgICB9XG4gICAgICBkaW1zID0gbWF5YmVEaW1zIGFzIHJlYWRvbmx5IG51bWJlcltdO1xuXG4gICAgICB0aGlzLmNwdURhdGEgPSBkYXRhO1xuICAgICAgdGhpcy5kYXRhTG9jYXRpb24gPSAnY3B1JztcbiAgICB9XG5cbiAgICAvLyBwZXJmb3JtIGNoZWNrIG9uIGRpbXNcbiAgICBjb25zdCBzaXplID0gY2FsY3VsYXRlU2l6ZShkaW1zKTtcbiAgICAvLyBpZiBkYXRhIGlzIG9uIENQVSwgY2hlY2sgd2hldGhlciBkYXRhIGxlbmd0aCBtYXRjaGVzIHRlbnNvciBzaXplXG4gICAgaWYgKHRoaXMuY3B1RGF0YSAmJiBzaXplICE9PSB0aGlzLmNwdURhdGEubGVuZ3RoKSB7XG4gICAgICBpZiAoKHR5cGUgPT09ICd1aW50NCcgfHwgdHlwZSA9PT0gJ2ludDQnKSAmJiBNYXRoLmNlaWwoc2l6ZSAvIDIpID09PSB0aGlzLmNwdURhdGEubGVuZ3RoKSB7XG4gICAgICAgIC8vIGZvciAodSlpbnQ0LCB0aGUgZGF0YSBsZW5ndGggaXMgaGFsZiBvZiB0aGUgdGVuc29yIHNpemUuIFNvIHdlIGNoZWNrIHRoaXMgc3BlY2lhbCBjYXNlIHdoZW4gc2l6ZSBpcyBvZGQuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRlbnNvcidzIHNpemUoJHtzaXplfSkgZG9lcyBub3QgbWF0Y2ggZGF0YSBsZW5ndGgoJHt0aGlzLmNwdURhdGEubGVuZ3RofSkuYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB0aGlzLmRpbXMgPSBkaW1zO1xuICAgIHRoaXMuc2l6ZSA9IHNpemU7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gZmFjdG9yeVxuICBzdGF0aWMgYXN5bmMgZnJvbUltYWdlKFxuICAgIGltYWdlOiBJbWFnZURhdGEgfCBIVE1MSW1hZ2VFbGVtZW50IHwgSW1hZ2VCaXRtYXAgfCBzdHJpbmcsXG4gICAgb3B0aW9ucz86XG4gICAgICB8IFRlbnNvckZyb21JbWFnZURhdGFPcHRpb25zXG4gICAgICB8IFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zXG4gICAgICB8IFRlbnNvckZyb21JbWFnZUJpdG1hcE9wdGlvbnNcbiAgICAgIHwgVGVuc29yRnJvbVVybE9wdGlvbnMsXG4gICk6IFByb21pc2U8VGVuc29ySW50ZXJmYWNlPiB7XG4gICAgcmV0dXJuIHRlbnNvckZyb21JbWFnZShpbWFnZSwgb3B0aW9ucyk7XG4gIH1cblxuICBzdGF0aWMgZnJvbVRleHR1cmU8VCBleHRlbmRzIFRlbnNvckludGVyZmFjZS5UZXh0dXJlRGF0YVR5cGVzPihcbiAgICB0ZXh0dXJlOiBUZW5zb3JUZXh0dXJlVHlwZSxcbiAgICBvcHRpb25zOiBUZW5zb3JGcm9tVGV4dHVyZU9wdGlvbnM8VD4sXG4gICk6IFRlbnNvckludGVyZmFjZSB7XG4gICAgcmV0dXJuIHRlbnNvckZyb21UZXh0dXJlKHRleHR1cmUsIG9wdGlvbnMpO1xuICB9XG5cbiAgc3RhdGljIGZyb21HcHVCdWZmZXI8VCBleHRlbmRzIFRlbnNvckludGVyZmFjZS5HcHVCdWZmZXJEYXRhVHlwZXM+KFxuICAgIGdwdUJ1ZmZlcjogVGVuc29yR3B1QnVmZmVyVHlwZSxcbiAgICBvcHRpb25zOiBUZW5zb3JGcm9tR3B1QnVmZmVyT3B0aW9uczxUPixcbiAgKTogVGVuc29ySW50ZXJmYWNlIHtcbiAgICByZXR1cm4gdGVuc29yRnJvbUdwdUJ1ZmZlcihncHVCdWZmZXIsIG9wdGlvbnMpO1xuICB9XG5cbiAgc3RhdGljIGZyb21NTFRlbnNvcjxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLk1MVGVuc29yRGF0YVR5cGVzPihcbiAgICBtbFRlbnNvcjogVGVuc29yTUxUZW5zb3JUeXBlLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21NTFRlbnNvck9wdGlvbnM8VD4sXG4gICk6IFRlbnNvckludGVyZmFjZSB7XG4gICAgcmV0dXJuIHRlbnNvckZyb21NTFRlbnNvcihtbFRlbnNvciwgb3B0aW9ucyk7XG4gIH1cblxuICBzdGF0aWMgZnJvbVBpbm5lZEJ1ZmZlcjxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLkNwdVBpbm5lZERhdGFUeXBlcz4oXG4gICAgdHlwZTogVCxcbiAgICBidWZmZXI6IFRlbnNvckludGVyZmFjZS5EYXRhVHlwZU1hcFtUXSxcbiAgICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IFRlbnNvciB7XG4gICAgcmV0dXJuIHRlbnNvckZyb21QaW5uZWRCdWZmZXIodHlwZSwgYnVmZmVyLCBkaW1zKTtcbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIGNvbnZlcnNpb25zXG4gIHRvRGF0YVVSTChvcHRpb25zPzogVGVuc29yVG9EYXRhVXJsT3B0aW9ucyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRlbnNvclRvRGF0YVVSTCh0aGlzLCBvcHRpb25zKTtcbiAgfVxuXG4gIHRvSW1hZ2VEYXRhKG9wdGlvbnM/OiBUZW5zb3JUb0ltYWdlRGF0YU9wdGlvbnMpOiBJbWFnZURhdGEge1xuICAgIHJldHVybiB0ZW5zb3JUb0ltYWdlRGF0YSh0aGlzLCBvcHRpb25zKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBwdWJsaWMgZmllbGRzXG4gIHJlYWRvbmx5IGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSB0eXBlOiBUZW5zb3JUeXBlO1xuICByZWFkb25seSBzaXplOiBudW1iZXI7XG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHByaXZhdGUgZmllbGRzXG5cbiAgLyoqXG4gICAqIHN0b3JlcyB0aGUgbG9jYXRpb24gb2YgdGhlIGRhdGEuXG4gICAqL1xuICBwcml2YXRlIGRhdGFMb2NhdGlvbjogVGVuc29yRGF0YUxvY2F0aW9uO1xuXG4gIC8qKlxuICAgKiBzdG9yZXMgdGhlIGRhdGEgb24gQ1BVLCBpZiBsb2NhdGlvbiBpcyAnY3B1JyBvciAnY3B1LXBpbm5lZCcuIG90aGVyd2lzZSBlbXB0eS5cbiAgICovXG4gIHByaXZhdGUgY3B1RGF0YT86IFRlbnNvckRhdGFUeXBlO1xuXG4gIC8qKlxuICAgKiBzdG9yZXMgdGhlIHVuZGVybHlpbmcgdGV4dHVyZSB3aGVuIGxvY2F0aW9uIGlzICd0ZXh0dXJlJy4gb3RoZXJ3aXNlIGVtcHR5LlxuICAgKi9cbiAgcHJpdmF0ZSBncHVUZXh0dXJlRGF0YT86IFRlbnNvclRleHR1cmVUeXBlO1xuXG4gIC8qKlxuICAgKiBzdG9yZXMgdGhlIHVuZGVybHlpbmcgR1BVIGJ1ZmZlciB3aGVuIGxvY2F0aW9uIGlzICdncHUtYnVmZmVyJy4gb3RoZXJ3aXNlIGVtcHR5LlxuICAgKi9cbiAgcHJpdmF0ZSBncHVCdWZmZXJEYXRhPzogVGVuc29yR3B1QnVmZmVyVHlwZTtcblxuICAvKipcbiAgICogc3RvcmVzIHRoZSB1bmRlcmx5aW5nIFdlYk5OIE1MVGVuc29yIHdoZW4gbG9jYXRpb24gaXMgJ21sLXRlbnNvcicuIG90aGVyd2lzZSBlbXB0eS5cbiAgICovXG4gIHByaXZhdGUgbWxUZW5zb3JEYXRhPzogVGVuc29yTUxUZW5zb3JUeXBlO1xuXG4gIC8qKlxuICAgKiBzdG9yZXMgYW4gb3B0aW9uYWwgZG93bmxvYWRlciBmdW5jdGlvbiB0byBkb3dubG9hZCBkYXRhIGZyb20gR1BVIHRvIENQVS5cbiAgICovXG4gIHByaXZhdGUgZG93bmxvYWRlcj8oKTogUHJvbWlzZTxUZW5zb3JEYXRhVHlwZT47XG5cbiAgLyoqXG4gICAqIGEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGRhdGEgaXMgYmVpbmcgZG93bmxvYWRlZCBmcm9tIEdQVSB0byBDUFUuXG4gICAqL1xuICBwcml2YXRlIGlzRG93bmxvYWRpbmc/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBzdG9yZXMgYW4gb3B0aW9uYWwgZGlzcG9zZXIgZnVuY3Rpb24gdG8gZGlzcG9zZSB0aGUgdW5kZXJseWluZyBkYXRhLlxuICAgKi9cbiAgcHJpdmF0ZSBkaXNwb3Nlcj8oKTogdm9pZDtcbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcHJvcGVydGllc1xuICBnZXQgZGF0YSgpOiBUZW5zb3JEYXRhVHlwZSB7XG4gICAgdGhpcy5lbnN1cmVWYWxpZCgpO1xuICAgIGlmICghdGhpcy5jcHVEYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdUaGUgZGF0YSBpcyBub3Qgb24gQ1BVLiBVc2UgYGdldERhdGEoKWAgdG8gZG93bmxvYWQgR1BVIGRhdGEgdG8gQ1BVLCAnICtcbiAgICAgICAgICAnb3IgdXNlIGB0ZXh0dXJlYCBvciBgZ3B1QnVmZmVyYCBwcm9wZXJ0eSB0byBhY2Nlc3MgdGhlIEdQVSBkYXRhIGRpcmVjdGx5LicsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jcHVEYXRhO1xuICB9XG5cbiAgZ2V0IGxvY2F0aW9uKCk6IFRlbnNvckRhdGFMb2NhdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YUxvY2F0aW9uO1xuICB9XG5cbiAgZ2V0IHRleHR1cmUoKTogVGVuc29yVGV4dHVyZVR5cGUge1xuICAgIHRoaXMuZW5zdXJlVmFsaWQoKTtcbiAgICBpZiAoIXRoaXMuZ3B1VGV4dHVyZURhdGEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGRhdGEgaXMgbm90IHN0b3JlZCBhcyBhIFdlYkdMIHRleHR1cmUuJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmdwdVRleHR1cmVEYXRhO1xuICB9XG5cbiAgZ2V0IGdwdUJ1ZmZlcigpOiBUZW5zb3JHcHVCdWZmZXJUeXBlIHtcbiAgICB0aGlzLmVuc3VyZVZhbGlkKCk7XG4gICAgaWYgKCF0aGlzLmdwdUJ1ZmZlckRhdGEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGRhdGEgaXMgbm90IHN0b3JlZCBhcyBhIFdlYkdQVSBidWZmZXIuJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmdwdUJ1ZmZlckRhdGE7XG4gIH1cblxuICBnZXQgbWxUZW5zb3IoKTogVGVuc29yTUxUZW5zb3JUeXBlIHtcbiAgICB0aGlzLmVuc3VyZVZhbGlkKCk7XG4gICAgaWYgKCF0aGlzLm1sVGVuc29yRGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgZGF0YSBpcyBub3Qgc3RvcmVkIGFzIGEgV2ViTk4gTUxUZW5zb3IuJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLm1sVGVuc29yRGF0YTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBtZXRob2RzXG5cbiAgYXN5bmMgZ2V0RGF0YShyZWxlYXNlRGF0YT86IGJvb2xlYW4pOiBQcm9taXNlPFRlbnNvckRhdGFUeXBlPiB7XG4gICAgdGhpcy5lbnN1cmVWYWxpZCgpO1xuICAgIHN3aXRjaCAodGhpcy5kYXRhTG9jYXRpb24pIHtcbiAgICAgIGNhc2UgJ2NwdSc6XG4gICAgICBjYXNlICdjcHUtcGlubmVkJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YTtcbiAgICAgIGNhc2UgJ3RleHR1cmUnOlxuICAgICAgY2FzZSAnZ3B1LWJ1ZmZlcic6XG4gICAgICBjYXNlICdtbC10ZW5zb3InOiB7XG4gICAgICAgIGlmICghdGhpcy5kb3dubG9hZGVyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgY3VycmVudCB0ZW5zb3IgaXMgbm90IGNyZWF0ZWQgd2l0aCBhIHNwZWNpZmllZCBkYXRhIGRvd25sb2FkZXIuJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaXNEb3dubG9hZGluZykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGN1cnJlbnQgdGVuc29yIGlzIGJlaW5nIGRvd25sb2FkZWQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLmlzRG93bmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLmRvd25sb2FkZXIoKTtcbiAgICAgICAgICB0aGlzLmRvd25sb2FkZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgdGhpcy5kYXRhTG9jYXRpb24gPSAnY3B1JztcbiAgICAgICAgICB0aGlzLmNwdURhdGEgPSBkYXRhO1xuXG4gICAgICAgICAgaWYgKHJlbGVhc2VEYXRhICYmIHRoaXMuZGlzcG9zZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZGlzcG9zZXIoKTtcbiAgICAgICAgICAgIHRoaXMuZGlzcG9zZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgdGhpcy5pc0Rvd25sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgY2Fubm90IGdldCBkYXRhIGZyb20gbG9jYXRpb246ICR7dGhpcy5kYXRhTG9jYXRpb259YCk7XG4gICAgfVxuICB9XG5cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc0Rvd25sb2FkaW5nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjdXJyZW50IHRlbnNvciBpcyBiZWluZyBkb3dubG9hZGVkLicpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmRpc3Bvc2VyKSB7XG4gICAgICB0aGlzLmRpc3Bvc2VyKCk7XG4gICAgICB0aGlzLmRpc3Bvc2VyID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB0aGlzLmNwdURhdGEgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5ncHVUZXh0dXJlRGF0YSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmdwdUJ1ZmZlckRhdGEgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5tbFRlbnNvckRhdGEgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5kb3dubG9hZGVyID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuaXNEb3dubG9hZGluZyA9IHVuZGVmaW5lZDtcblxuICAgIHRoaXMuZGF0YUxvY2F0aW9uID0gJ25vbmUnO1xuICB9XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gdGVuc29yIHV0aWxpdGllc1xuICBwcml2YXRlIGVuc3VyZVZhbGlkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRhdGFMb2NhdGlvbiA9PT0gJ25vbmUnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSB0ZW5zb3IgaXMgZGlzcG9zZWQuJyk7XG4gICAgfVxuICB9XG5cbiAgcmVzaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IFRlbnNvckludGVyZmFjZSB7XG4gICAgdGhpcy5lbnN1cmVWYWxpZCgpO1xuICAgIGlmICh0aGlzLmRvd25sb2FkZXIgfHwgdGhpcy5kaXNwb3Nlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgcmVzaGFwZSBhIHRlbnNvciB0aGF0IG93bnMgR1BVIHJlc291cmNlLicpO1xuICAgIH1cbiAgICByZXR1cm4gdGVuc29yUmVzaGFwZSh0aGlzLCBkaW1zKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvckZhY3RvcnkgfSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LmpzJztcbmltcG9ydCB7IFRlbnNvciBhcyBUZW5zb3JJbXBsIH0gZnJvbSAnLi90ZW5zb3ItaW1wbC5qcyc7XG5pbXBvcnQgeyBUeXBlZFRlbnNvclV0aWxzIH0gZnJvbSAnLi90ZW5zb3ItdXRpbHMuanMnO1xuaW1wb3J0IHsgVHJ5R2V0R2xvYmFsVHlwZSB9IGZyb20gJy4vdHlwZS1oZWxwZXIuanMnO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlICovXG5cbi8qKlxuICogcmVwcmVzZW50IGEgYmFzaWMgdGVuc29yIHdpdGggc3BlY2lmaWVkIGRpbWVuc2lvbnMgYW5kIGRhdGEgdHlwZS5cbiAqL1xuaW50ZXJmYWNlIFR5cGVkVGVuc29yQmFzZTxUIGV4dGVuZHMgVGVuc29yLlR5cGU+IHtcbiAgLyoqXG4gICAqIEdldCB0aGUgZGltZW5zaW9ucyBvZiB0aGUgdGVuc29yLlxuICAgKi9cbiAgcmVhZG9ubHkgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG4gIC8qKlxuICAgKiBHZXQgdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLlxuICAgKi9cbiAgcmVhZG9ubHkgdHlwZTogVDtcbiAgLyoqXG4gICAqIEdldCB0aGUgYnVmZmVyIGRhdGEgb2YgdGhlIHRlbnNvci5cbiAgICpcbiAgICogSWYgdGhlIGRhdGEgaXMgbm90IG9uIENQVSAoZWcuIGl0J3MgaW4gdGhlIGZvcm0gb2YgV2ViR0wgdGV4dHVyZSBvciBXZWJHUFUgYnVmZmVyKSwgdGhyb3cgZXJyb3IuXG4gICAqL1xuICByZWFkb25seSBkYXRhOiBUZW5zb3IuRGF0YVR5cGVNYXBbVF07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9jYXRpb246IFRlbnNvci5EYXRhTG9jYXRpb247XG4gIC8qKlxuICAgKiBHZXQgdGhlIFdlYkdMIHRleHR1cmUgdGhhdCBob2xkcyB0aGUgdGVuc29yIGRhdGEuXG4gICAqXG4gICAqIElmIHRoZSBkYXRhIGlzIG5vdCBvbiBHUFUgYXMgV2ViR0wgdGV4dHVyZSwgdGhyb3cgZXJyb3IuXG4gICAqL1xuICByZWFkb25seSB0ZXh0dXJlOiBUZW5zb3IuVGV4dHVyZVR5cGU7XG4gIC8qKlxuICAgKiBHZXQgdGhlIFdlYkdQVSBidWZmZXIgdGhhdCBob2xkcyB0aGUgdGVuc29yIGRhdGEuXG4gICAqXG4gICAqIElmIHRoZSBkYXRhIGlzIG5vdCBvbiBHUFUgYXMgV2ViR1BVIGJ1ZmZlciwgdGhyb3cgZXJyb3IuXG4gICAqL1xuICByZWFkb25seSBncHVCdWZmZXI6IFRlbnNvci5HcHVCdWZmZXJUeXBlO1xuXG4gIC8qKlxuICAgKiBHZXQgdGhlIFdlYk5OIE1MVGVuc29yIHRoYXQgaG9sZHMgdGhlIHRlbnNvciBkYXRhLlxuICAgKlxuICAgKiBJZiB0aGUgZGF0YSBpcyBub3QgaW4gYSBXZWJOTiBNTFRlbnNvciwgdGhyb3cgZXJyb3IuXG4gICAqL1xuICByZWFkb25seSBtbFRlbnNvcjogVGVuc29yLk1MVGVuc29yVHlwZTtcblxuICAvKipcbiAgICogR2V0IHRoZSBidWZmZXIgZGF0YSBvZiB0aGUgdGVuc29yLlxuICAgKlxuICAgKiBJZiB0aGUgZGF0YSBpcyBvbiBDUFUsIHJldHVybnMgdGhlIGRhdGEgaW1tZWRpYXRlbHkuXG4gICAqIElmIHRoZSBkYXRhIGlzIG9uIEdQVSwgZG93bmxvYWRzIHRoZSBkYXRhIGFuZCByZXR1cm5zIHRoZSBwcm9taXNlLlxuICAgKlxuICAgKiBAcGFyYW0gcmVsZWFzZURhdGEgLSB3aGV0aGVyIHJlbGVhc2UgdGhlIGRhdGEgb24gR1BVLiBJZ25vcmUgaWYgZGF0YSBpcyBhbHJlYWR5IG9uIENQVS5cbiAgICovXG4gIGdldERhdGEocmVsZWFzZURhdGE/OiBib29sZWFuKTogUHJvbWlzZTxUZW5zb3IuRGF0YVR5cGVNYXBbVF0+O1xuXG4gIC8qKlxuICAgKiBEaXNwb3NlIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICpcbiAgICogSWYgdGhlIGRhdGEgaXMgb24gQ1BVLCByZW1vdmUgaXRzIGludGVybmFsIHJlZmVyZW5jZSB0byB0aGUgdW5kZXJseWluZyBkYXRhLlxuICAgKiBJZiB0aGUgZGF0YSBpcyBvbiBHUFUsIHJlbGVhc2UgdGhlIGRhdGEgb24gR1BVLlxuICAgKlxuICAgKiBBZnRlciBjYWxsaW5nIHRoaXMgZnVuY3Rpb24sIHRoZSB0ZW5zb3IgaXMgY29uc2lkZXJlZCBubyBsb25nZXIgdmFsaWQuIEl0cyBsb2NhdGlvbiB3aWxsIGJlIHNldCB0byAnbm9uZScuXG4gICAqL1xuICBkaXNwb3NlKCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBUZW5zb3Ige1xuICBpbnRlcmZhY2UgRGF0YVR5cGVNYXAge1xuICAgIGZsb2F0MzI6IEZsb2F0MzJBcnJheTtcbiAgICB1aW50ODogVWludDhBcnJheTtcbiAgICBpbnQ4OiBJbnQ4QXJyYXk7XG4gICAgdWludDE2OiBVaW50MTZBcnJheTtcbiAgICBpbnQxNjogSW50MTZBcnJheTtcbiAgICBpbnQzMjogSW50MzJBcnJheTtcbiAgICBpbnQ2NDogQmlnSW50NjRBcnJheTtcbiAgICBzdHJpbmc6IHN0cmluZ1tdO1xuICAgIGJvb2w6IFVpbnQ4QXJyYXk7XG4gICAgZmxvYXQxNjogVWludDE2QXJyYXk7IC8vIEtlZXAgdXNpbmcgVWludDE2QXJyYXkgdW50aWwgd2UgaGF2ZSBhIGNvbmNyZXRlIHNvbHV0aW9uIGZvciBmbG9hdCAxNi5cbiAgICBmbG9hdDY0OiBGbG9hdDY0QXJyYXk7XG4gICAgdWludDMyOiBVaW50MzJBcnJheTtcbiAgICB1aW50NjQ6IEJpZ1VpbnQ2NEFycmF5O1xuICAgIC8vIGNvbXBsZXg2NDogbmV2ZXI7XG4gICAgLy8gY29tcGxleDEyODogbmV2ZXI7XG4gICAgLy8gYmZsb2F0MTY6IG5ldmVyO1xuICAgIHVpbnQ0OiBVaW50OEFycmF5O1xuICAgIGludDQ6IEludDhBcnJheTtcbiAgfVxuXG4gIGludGVyZmFjZSBFbGVtZW50VHlwZU1hcCB7XG4gICAgZmxvYXQzMjogbnVtYmVyO1xuICAgIHVpbnQ4OiBudW1iZXI7XG4gICAgaW50ODogbnVtYmVyO1xuICAgIHVpbnQxNjogbnVtYmVyO1xuICAgIGludDE2OiBudW1iZXI7XG4gICAgaW50MzI6IG51bWJlcjtcbiAgICBpbnQ2NDogYmlnaW50O1xuICAgIHN0cmluZzogc3RyaW5nO1xuICAgIGJvb2w6IGJvb2xlYW47XG4gICAgZmxvYXQxNjogbnVtYmVyOyAvLyBLZWVwIHVzaW5nIFVpbnQxNkFycmF5IHVudGlsIHdlIGhhdmUgYSBjb25jcmV0ZSBzb2x1dGlvbiBmb3IgZmxvYXQgMTYuXG4gICAgZmxvYXQ2NDogbnVtYmVyO1xuICAgIHVpbnQzMjogbnVtYmVyO1xuICAgIHVpbnQ2NDogYmlnaW50O1xuICAgIC8vIGNvbXBsZXg2NDogbmV2ZXI7XG4gICAgLy8gY29tcGxleDEyODogbmV2ZXI7XG4gICAgLy8gYmZsb2F0MTY6IG5ldmVyO1xuICAgIHVpbnQ0OiBudW1iZXI7XG4gICAgaW50NDogbnVtYmVyO1xuICB9XG5cbiAgdHlwZSBEYXRhVHlwZSA9IERhdGFUeXBlTWFwW1R5cGVdO1xuICB0eXBlIEVsZW1lbnRUeXBlID0gRWxlbWVudFR5cGVNYXBbVHlwZV07XG5cbiAgLyoqXG4gICAqIHN1cHBvcnRlZCBkYXRhIHR5cGVzIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIHBpbm5lZCBDUFUgYnVmZmVyXG4gICAqL1xuICBleHBvcnQgdHlwZSBDcHVQaW5uZWREYXRhVHlwZXMgPSBFeGNsdWRlPFRlbnNvci5UeXBlLCAnc3RyaW5nJz47XG5cbiAgLyoqXG4gICAqIHR5cGUgYWxpYXMgZm9yIFdlYkdMIHRleHR1cmVcbiAgICovXG4gIGV4cG9ydCB0eXBlIFRleHR1cmVUeXBlID0gV2ViR0xUZXh0dXJlO1xuXG4gIC8qKlxuICAgKiBzdXBwb3J0ZWQgZGF0YSB0eXBlcyBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBXZWJHTCB0ZXh0dXJlXG4gICAqL1xuICBleHBvcnQgdHlwZSBUZXh0dXJlRGF0YVR5cGVzID0gJ2Zsb2F0MzInO1xuXG4gIHR5cGUgR3B1QnVmZmVyVHlwZUZhbGxiYWNrID0geyBzaXplOiBudW1iZXI7IG1hcFN0YXRlOiAndW5tYXBwZWQnIHwgJ3BlbmRpbmcnIHwgJ21hcHBlZCcgfTtcbiAgLyoqXG4gICAqIHR5cGUgYWxpYXMgZm9yIFdlYkdQVSBidWZmZXJcbiAgICovXG4gIGV4cG9ydCB0eXBlIEdwdUJ1ZmZlclR5cGUgPSBUcnlHZXRHbG9iYWxUeXBlPCdHUFVCdWZmZXInLCBHcHVCdWZmZXJUeXBlRmFsbGJhY2s+O1xuXG4gIHR5cGUgTUxUZW5zb3JUeXBlRmFsbGJhY2sgPSB7IGRlc3Ryb3koKTogdm9pZCB9O1xuICAvKipcbiAgICogdHlwZSBhbGlhcyBmb3IgV2ViTk4gTUxUZW5zb3JcbiAgICpcbiAgICogVGhlIHNwZWNpZmljYXRpb24gZm9yIFdlYk5OJ3MgTUxUZW5zb3IgaXMgY3VycmVudGx5IGluIGZsdXguXG4gICAqL1xuICBleHBvcnQgdHlwZSBNTFRlbnNvclR5cGUgPSBUcnlHZXRHbG9iYWxUeXBlPCdNTFRlbnNvcicsIE1MVGVuc29yVHlwZUZhbGxiYWNrPjtcblxuICAvKipcbiAgICogc3VwcG9ydGVkIGRhdGEgdHlwZXMgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgV2ViR1BVIGJ1ZmZlclxuICAgKi9cbiAgZXhwb3J0IHR5cGUgR3B1QnVmZmVyRGF0YVR5cGVzID0gJ2Zsb2F0MzInIHwgJ2Zsb2F0MTYnIHwgJ2ludDMyJyB8ICdpbnQ2NCcgfCAndWludDMyJyB8ICd1aW50OCcgfCAnYm9vbCc7XG5cbiAgLyoqXG4gICAqIHN1cHBvcnRlZCBkYXRhIHR5cGVzIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIFdlYk5OIE1MVGVuc29yXG4gICAqL1xuICBleHBvcnQgdHlwZSBNTFRlbnNvckRhdGFUeXBlcyA9XG4gICAgfCAnZmxvYXQzMidcbiAgICB8ICdmbG9hdDE2J1xuICAgIHwgJ2ludDgnXG4gICAgfCAndWludDgnXG4gICAgfCAnaW50MzInXG4gICAgfCAndWludDMyJ1xuICAgIHwgJ2ludDY0J1xuICAgIHwgJ3VpbnQ2NCdcbiAgICB8ICdib29sJ1xuICAgIHwgJ3VpbnQ0J1xuICAgIHwgJ2ludDQnO1xuXG4gIC8qKlxuICAgKiByZXByZXNlbnQgd2hlcmUgdGhlIHRlbnNvciBkYXRhIGlzIHN0b3JlZFxuICAgKi9cbiAgZXhwb3J0IHR5cGUgRGF0YUxvY2F0aW9uID0gJ25vbmUnIHwgJ2NwdScgfCAnY3B1LXBpbm5lZCcgfCAndGV4dHVyZScgfCAnZ3B1LWJ1ZmZlcicgfCAnbWwtdGVuc29yJztcblxuICAvKipcbiAgICogcmVwcmVzZW50IHRoZSBkYXRhIHR5cGUgb2YgYSB0ZW5zb3JcbiAgICovXG4gIGV4cG9ydCB0eXBlIFR5cGUgPSBrZXlvZiBEYXRhVHlwZU1hcDtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnQgbXVsdGktZGltZW5zaW9uYWwgYXJyYXlzIHRvIGZlZWQgdG8gb3IgZmV0Y2ggZnJvbSBtb2RlbCBpbmZlcmVuY2luZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUeXBlZFRlbnNvcjxUIGV4dGVuZHMgVGVuc29yLlR5cGU+IGV4dGVuZHMgVHlwZWRUZW5zb3JCYXNlPFQ+LCBUeXBlZFRlbnNvclV0aWxzPFQ+IHt9XG4vKipcbiAqIFJlcHJlc2VudCBtdWx0aS1kaW1lbnNpb25hbCBhcnJheXMgdG8gZmVlZCB0byBvciBmZXRjaCBmcm9tIG1vZGVsIGluZmVyZW5jaW5nLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvciBleHRlbmRzIFR5cGVkVGVuc29yQmFzZTxUZW5zb3IuVHlwZT4sIFR5cGVkVGVuc29yVXRpbHM8VGVuc29yLlR5cGU+IHt9XG5cbi8qKlxuICogdHlwZSBUZW5zb3JDb25zdHJ1Y3RvciBkZWZpbmVzIHRoZSBjb25zdHJ1Y3RvcnMgb2YgJ1RlbnNvcicgdG8gY3JlYXRlIENQVSB0ZW5zb3IgaW5zdGFuY2VzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckNvbnN0cnVjdG9yIGV4dGVuZHMgVGVuc29yRmFjdG9yeSB7XG4gIC8vICNyZWdpb24gQ1BVIHRlbnNvciAtIHNwZWNpZnkgZWxlbWVudCB0eXBlXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgc3RyaW5nIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gdHlwZSwgZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSBTcGVjaWZ5IHRoZSBlbGVtZW50IHR5cGUuXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoXG4gICAgdHlwZTogJ3N0cmluZycsXG4gICAgZGF0YTogVGVuc29yLkRhdGFUeXBlTWFwWydzdHJpbmcnXSB8IHJlYWRvbmx5IHN0cmluZ1tdLFxuICAgIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogVHlwZWRUZW5zb3I8J3N0cmluZyc+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgYm9vbCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIHR5cGUsIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gU3BlY2lmeSB0aGUgZWxlbWVudCB0eXBlLlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKFxuICAgIHR5cGU6ICdib29sJyxcbiAgICBkYXRhOiBUZW5zb3IuRGF0YVR5cGVNYXBbJ2Jvb2wnXSB8IHJlYWRvbmx5IGJvb2xlYW5bXSxcbiAgICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IFR5cGVkVGVuc29yPCdib29sJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB1aW50OCB0ZW5zb3Igb2JqZWN0IGZyb20gYSBVaW50OENsYW1wZWRBcnJheSwgZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSBTcGVjaWZ5IHRoZSBlbGVtZW50IHR5cGUuXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAodHlwZTogJ3VpbnQ4JywgZGF0YTogVWludDhDbGFtcGVkQXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCd1aW50OCc+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgNjQtYml0IGludGVnZXIgdHlwZWQgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiB0eXBlLCBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFNwZWNpZnkgdGhlIGVsZW1lbnQgdHlwZS5cbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IDxUIGV4dGVuZHMgJ3VpbnQ2NCcgfCAnaW50NjQnPihcbiAgICB0eXBlOiBULFxuICAgIGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFtUXSB8IHJlYWRvbmx5IGJpZ2ludFtdIHwgcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuICApOiBUeXBlZFRlbnNvcjxUPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IG51bWVyaWMgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiB0eXBlLCBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFNwZWNpZnkgdGhlIGVsZW1lbnQgdHlwZS5cbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IDxUIGV4dGVuZHMgRXhjbHVkZTxUZW5zb3IuVHlwZSwgJ3N0cmluZycgfCAnYm9vbCcgfCAndWludDY0JyB8ICdpbnQ2NCc+PihcbiAgICB0eXBlOiBULFxuICAgIGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFtUXSB8IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogVHlwZWRUZW5zb3I8VD47XG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIENQVSB0ZW5zb3IgLSBpbmZlciBlbGVtZW50IHR5cGVzXG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBmbG9hdDMyIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBGbG9hdDMyQXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCdmbG9hdDMyJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBpbnQ4IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBJbnQ4QXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCdpbnQ4Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB1aW50OCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogVWludDhBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J3VpbnQ4Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB1aW50OCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogVWludDhDbGFtcGVkQXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCd1aW50OCc+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdWludDE2IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBVaW50MTZBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J3VpbnQxNic+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgaW50MTYgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IEludDE2QXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCdpbnQxNic+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgaW50MzIgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IEludDMyQXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCdpbnQzMic+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgaW50NjQgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IEJpZ0ludDY0QXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCdpbnQ2NCc+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgc3RyaW5nIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiByZWFkb25seSBzdHJpbmdbXSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J3N0cmluZyc+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgYm9vbCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogcmVhZG9ubHkgYm9vbGVhbltdLCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwnYm9vbCc+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgZmxvYXQ2NCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogRmxvYXQ2NEFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwnZmxvYXQ2NCc+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdWludDMyIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBVaW50MzJBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J3VpbnQzMic+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdWludDY0IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBCaWdVaW50NjRBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J3VpbnQ2NCc+O1xuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIENQVSB0ZW5zb3IgLSBmYWxsIGJhY2sgdG8gbm9uLWdlbmVyaWMgdGVuc29yIHR5cGUgZGVjbGFyYXRpb25cblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gdHlwZSwgZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSBTcGVjaWZ5IHRoZSBlbGVtZW50IHR5cGUuXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoXG4gICAgdHlwZTogVGVuc29yLlR5cGUsXG4gICAgZGF0YTogVGVuc29yLkRhdGFUeXBlIHwgcmVhZG9ubHkgbnVtYmVyW10gfCByZWFkb25seSBzdHJpbmdbXSB8IHJlYWRvbmx5IGJpZ2ludFtdIHwgcmVhZG9ubHkgYm9vbGVhbltdLFxuICAgIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogVGVuc29yO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IFRlbnNvci5EYXRhVHlwZSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yO1xuICAvLyAjZW5kcmVnaW9uXG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbmV4cG9ydCBjb25zdCBUZW5zb3IgPSBUZW5zb3JJbXBsIGFzIFRlbnNvckNvbnN0cnVjdG9yO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBlbnYgfSBmcm9tICcuL2Vudi1pbXBsLmpzJztcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCBUUkFDRSA9IChkZXZpY2VUeXBlOiBzdHJpbmcsIGxhYmVsOiBzdHJpbmcpID0+IHtcbiAgaWYgKHR5cGVvZiBlbnYudHJhY2UgPT09ICd1bmRlZmluZWQnID8gIWVudi53YXNtLnRyYWNlIDogIWVudi50cmFjZSkge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLnRpbWVTdGFtcChgJHtkZXZpY2VUeXBlfTo6T1JUOjoke2xhYmVsfWApO1xufTtcblxuY29uc3QgVFJBQ0VfRlVOQyA9IChtc2c6IHN0cmluZywgZXh0cmFNc2c/OiBzdHJpbmcpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgRXJyb3IoKS5zdGFjaz8uc3BsaXQoL1xcclxcbnxcXHJ8XFxuL2cpIHx8IFtdO1xuICBsZXQgaGFzVHJhY2VGdW5jID0gZmFsc2U7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc3RhY2subGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoaGFzVHJhY2VGdW5jICYmICFzdGFja1tpXS5pbmNsdWRlcygnVFJBQ0VfRlVOQycpKSB7XG4gICAgICBsZXQgbGFiZWwgPSBgRlVOQ18ke21zZ306OiR7c3RhY2tbaV0udHJpbSgpLnNwbGl0KCcgJylbMV19YDtcbiAgICAgIGlmIChleHRyYU1zZykge1xuICAgICAgICBsYWJlbCArPSBgOjoke2V4dHJhTXNnfWA7XG4gICAgICB9XG4gICAgICBUUkFDRSgnQ1BVJywgbGFiZWwpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc3RhY2tbaV0uaW5jbHVkZXMoJ1RSQUNFX0ZVTkMnKSkge1xuICAgICAgaGFzVHJhY2VGdW5jID0gdHJ1ZTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgY29uc3QgVFJBQ0VfRlVOQ19CRUdJTiA9IChleHRyYU1zZz86IHN0cmluZykgPT4ge1xuICBpZiAodHlwZW9mIGVudi50cmFjZSA9PT0gJ3VuZGVmaW5lZCcgPyAhZW52Lndhc20udHJhY2UgOiAhZW52LnRyYWNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIFRSQUNFX0ZVTkMoJ0JFR0lOJywgZXh0cmFNc2cpO1xufTtcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCBUUkFDRV9GVU5DX0VORCA9IChleHRyYU1zZz86IHN0cmluZykgPT4ge1xuICBpZiAodHlwZW9mIGVudi50cmFjZSA9PT0gJ3VuZGVmaW5lZCcgPyAhZW52Lndhc20udHJhY2UgOiAhZW52LnRyYWNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIFRSQUNFX0ZVTkMoJ0VORCcsIGV4dHJhTXNnKTtcbn07XG5cbi8qKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgY29uc3QgVFJBQ0VfRVZFTlRfQkVHSU4gPSAoZXh0cmFNc2c/OiBzdHJpbmcpID0+IHtcbiAgaWYgKHR5cGVvZiBlbnYudHJhY2UgPT09ICd1bmRlZmluZWQnID8gIWVudi53YXNtLnRyYWNlIDogIWVudi50cmFjZSkge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLnRpbWUoYE9SVDo6JHtleHRyYU1zZ31gKTtcbn07XG5cbi8qKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgY29uc3QgVFJBQ0VfRVZFTlRfRU5EID0gKGV4dHJhTXNnPzogc3RyaW5nKSA9PiB7XG4gIGlmICh0eXBlb2YgZW52LnRyYWNlID09PSAndW5kZWZpbmVkJyA/ICFlbnYud2FzbS50cmFjZSA6ICFlbnYudHJhY2UpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgY29uc29sZS50aW1lRW5kKGBPUlQ6OiR7ZXh0cmFNc2d9YCk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyByZXNvbHZlQmFja2VuZEFuZEV4ZWN1dGlvblByb3ZpZGVycyB9IGZyb20gJy4vYmFja2VuZC1pbXBsLmpzJztcbmltcG9ydCB7IEluZmVyZW5jZVNlc3Npb25IYW5kbGVyIH0gZnJvbSAnLi9iYWNrZW5kLmpzJztcbmltcG9ydCB7IEluZmVyZW5jZVNlc3Npb24gYXMgSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZSB9IGZyb20gJy4vaW5mZXJlbmNlLXNlc3Npb24uanMnO1xuaW1wb3J0IHsgT25ueFZhbHVlIH0gZnJvbSAnLi9vbm54LXZhbHVlLmpzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yLmpzJztcbmltcG9ydCB7IFRSQUNFX0ZVTkNfQkVHSU4sIFRSQUNFX0ZVTkNfRU5ELCBUUkFDRV9FVkVOVF9CRUdJTiwgVFJBQ0VfRVZFTlRfRU5EIH0gZnJvbSAnLi90cmFjZS5qcyc7XG5cbnR5cGUgU2Vzc2lvbk9wdGlvbnMgPSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLlNlc3Npb25PcHRpb25zO1xudHlwZSBSdW5PcHRpb25zID0gSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZS5SdW5PcHRpb25zO1xudHlwZSBGZWVkc1R5cGUgPSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLkZlZWRzVHlwZTtcbnR5cGUgRmV0Y2hlc1R5cGUgPSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLkZldGNoZXNUeXBlO1xudHlwZSBSZXR1cm5UeXBlID0gSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZS5SZXR1cm5UeXBlO1xuXG5leHBvcnQgY2xhc3MgSW5mZXJlbmNlU2Vzc2lvbiBpbXBsZW1lbnRzIEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2Uge1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKGhhbmRsZXI6IEluZmVyZW5jZVNlc3Npb25IYW5kbGVyKSB7XG4gICAgdGhpcy5oYW5kbGVyID0gaGFuZGxlcjtcbiAgfVxuICBydW4oZmVlZHM6IEZlZWRzVHlwZSwgb3B0aW9ucz86IFJ1bk9wdGlvbnMpOiBQcm9taXNlPFJldHVyblR5cGU+O1xuICBydW4oZmVlZHM6IEZlZWRzVHlwZSwgZmV0Y2hlczogRmV0Y2hlc1R5cGUsIG9wdGlvbnM/OiBSdW5PcHRpb25zKTogUHJvbWlzZTxSZXR1cm5UeXBlPjtcbiAgYXN5bmMgcnVuKGZlZWRzOiBGZWVkc1R5cGUsIGFyZzE/OiBGZXRjaGVzVHlwZSB8IFJ1bk9wdGlvbnMsIGFyZzI/OiBSdW5PcHRpb25zKTogUHJvbWlzZTxSZXR1cm5UeXBlPiB7XG4gICAgVFJBQ0VfRlVOQ19CRUdJTigpO1xuICAgIFRSQUNFX0VWRU5UX0JFR0lOKCdJbmZlcmVuY2VTZXNzaW9uLnJ1bicpO1xuICAgIGNvbnN0IGZldGNoZXM6IHsgW25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZSB8IG51bGwgfSA9IHt9O1xuICAgIGxldCBvcHRpb25zOiBSdW5PcHRpb25zID0ge307XG4gICAgLy8gY2hlY2sgaW5wdXRzXG4gICAgaWYgKHR5cGVvZiBmZWVkcyAhPT0gJ29iamVjdCcgfHwgZmVlZHMgPT09IG51bGwgfHwgZmVlZHMgaW5zdGFuY2VvZiBUZW5zb3IgfHwgQXJyYXkuaXNBcnJheShmZWVkcykpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgIFwiJ2ZlZWRzJyBtdXN0IGJlIGFuIG9iamVjdCB0aGF0IHVzZSBpbnB1dCBuYW1lcyBhcyBrZXlzIGFuZCBPbm54VmFsdWUgYXMgY29ycmVzcG9uZGluZyB2YWx1ZXMuXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIGxldCBpc0ZldGNoZXNFbXB0eSA9IHRydWU7XG4gICAgLy8gZGV0ZXJtaW5lIHdoaWNoIG92ZXJyaWRlIGlzIGJlaW5nIHVzZWRcbiAgICBpZiAodHlwZW9mIGFyZzEgPT09ICdvYmplY3QnKSB7XG4gICAgICBpZiAoYXJnMSA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmV4cGVjdGVkIGFyZ3VtZW50WzFdOiBjYW5ub3QgYmUgbnVsbC4nKTtcbiAgICAgIH1cbiAgICAgIGlmIChhcmcxIGluc3RhbmNlb2YgVGVuc29yKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInZmV0Y2hlcycgY2Fubm90IGJlIGEgVGVuc29yXCIpO1xuICAgICAgfVxuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShhcmcxKSkge1xuICAgICAgICBpZiAoYXJnMS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ2ZldGNoZXMnIGNhbm5vdCBiZSBhbiBlbXB0eSBhcnJheS5cIik7XG4gICAgICAgIH1cbiAgICAgICAgaXNGZXRjaGVzRW1wdHkgPSBmYWxzZTtcbiAgICAgICAgLy8gb3V0cHV0IG5hbWVzXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBhcmcxKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidmZXRjaGVzJyBtdXN0IGJlIGEgc3RyaW5nIGFycmF5IG9yIGFuIG9iamVjdC5cIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0aGlzLm91dHB1dE5hbWVzLmluZGV4T2YobmFtZSkgPT09IC0xKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgJ2ZldGNoZXMnIGNvbnRhaW5zIGludmFsaWQgb3V0cHV0IG5hbWU6ICR7bmFtZX0uYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZldGNoZXNbbmFtZV0gPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBhcmcyID09PSAnb2JqZWN0JyAmJiBhcmcyICE9PSBudWxsKSB7XG4gICAgICAgICAgb3B0aW9ucyA9IGFyZzI7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidvcHRpb25zJyBtdXN0IGJlIGFuIG9iamVjdC5cIik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGRlY2lkZSB3aGV0aGVyIGFyZzEgaXMgZmV0Y2hlcyBvciBvcHRpb25zXG4gICAgICAgIC8vIGlmIGFueSBvdXRwdXQgbmFtZSBpcyBwcmVzZW50IGFuZCBpdHMgdmFsdWUgaXMgdmFsaWQgT25ueFZhbHVlLCB3ZSBjb25zaWRlciBpdCBmZXRjaGVzXG4gICAgICAgIGxldCBpc0ZldGNoZXMgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgYXJnMUtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhhcmcxKTtcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIHRoaXMub3V0cHV0TmFtZXMpIHtcbiAgICAgICAgICBpZiAoYXJnMUtleXMuaW5kZXhPZihuYW1lKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNvbnN0IHYgPSAoYXJnMSBhcyBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLk51bGxhYmxlT25ueFZhbHVlTWFwVHlwZSlbbmFtZV07XG4gICAgICAgICAgICBpZiAodiA9PT0gbnVsbCB8fCB2IGluc3RhbmNlb2YgVGVuc29yKSB7XG4gICAgICAgICAgICAgIGlzRmV0Y2hlcyA9IHRydWU7XG4gICAgICAgICAgICAgIGlzRmV0Y2hlc0VtcHR5ID0gZmFsc2U7XG4gICAgICAgICAgICAgIGZldGNoZXNbbmFtZV0gPSB2O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0ZldGNoZXMpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGFyZzIgPT09ICdvYmplY3QnICYmIGFyZzIgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBhcmcyO1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ29wdGlvbnMnIG11c3QgYmUgYW4gb2JqZWN0LlwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3B0aW9ucyA9IGFyZzEgYXMgUnVuT3B0aW9ucztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiVW5leHBlY3RlZCBhcmd1bWVudFsxXTogbXVzdCBiZSAnZmV0Y2hlcycgb3IgJ29wdGlvbnMnLlwiKTtcbiAgICB9XG5cbiAgICAvLyBjaGVjayBpZiBhbGwgaW5wdXRzIGFyZSBpbiBmZWVkXG4gICAgZm9yIChjb25zdCBuYW1lIG9mIHRoaXMuaW5wdXROYW1lcykge1xuICAgICAgaWYgKHR5cGVvZiBmZWVkc1tuYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dCAnJHtuYW1lfScgaXMgbWlzc2luZyBpbiAnZmVlZHMnLmApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGlmIG5vIGZldGNoZXMgaXMgc3BlY2lmaWVkLCB3ZSB1c2UgdGhlIGZ1bGwgb3V0cHV0IG5hbWVzIGxpc3RcbiAgICBpZiAoaXNGZXRjaGVzRW1wdHkpIHtcbiAgICAgIGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLm91dHB1dE5hbWVzKSB7XG4gICAgICAgIGZldGNoZXNbbmFtZV0gPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGZlZWRzLCBmZXRjaGVzIGFuZCBvcHRpb25zIGFyZSBwcmVwYXJlZFxuXG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuaGFuZGxlci5ydW4oZmVlZHMsIGZldGNoZXMsIG9wdGlvbnMpO1xuICAgIGNvbnN0IHJldHVyblZhbHVlOiB7IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfSA9IHt9O1xuICAgIGZvciAoY29uc3Qga2V5IGluIHJlc3VsdHMpIHtcbiAgICAgIGlmIChPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHRzLCBrZXkpKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHJlc3VsdHNba2V5XTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFRlbnNvcikge1xuICAgICAgICAgIHJldHVyblZhbHVlW2tleV0gPSByZXN1bHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVba2V5XSA9IG5ldyBUZW5zb3IocmVzdWx0LnR5cGUsIHJlc3VsdC5kYXRhLCByZXN1bHQuZGltcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgVFJBQ0VfRVZFTlRfRU5EKCdJbmZlcmVuY2VTZXNzaW9uLnJ1bicpO1xuICAgIFRSQUNFX0ZVTkNfRU5EKCk7XG4gICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICB9XG5cbiAgYXN5bmMgcmVsZWFzZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVyLmRpc3Bvc2UoKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGUocGF0aDogc3RyaW5nLCBvcHRpb25zPzogU2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2U+O1xuICBzdGF0aWMgY3JlYXRlKGJ1ZmZlcjogQXJyYXlCdWZmZXJMaWtlLCBvcHRpb25zPzogU2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2U+O1xuICBzdGF0aWMgY3JlYXRlKFxuICAgIGJ1ZmZlcjogQXJyYXlCdWZmZXJMaWtlLFxuICAgIGJ5dGVPZmZzZXQ6IG51bWJlcixcbiAgICBieXRlTGVuZ3RoPzogbnVtYmVyLFxuICAgIG9wdGlvbnM/OiBTZXNzaW9uT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlPjtcbiAgc3RhdGljIGNyZWF0ZShidWZmZXI6IFVpbnQ4QXJyYXksIG9wdGlvbnM/OiBTZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZT47XG4gIHN0YXRpYyBhc3luYyBjcmVhdGUoXG4gICAgYXJnMDogc3RyaW5nIHwgQXJyYXlCdWZmZXJMaWtlIHwgVWludDhBcnJheSxcbiAgICBhcmcxPzogU2Vzc2lvbk9wdGlvbnMgfCBudW1iZXIsXG4gICAgYXJnMj86IG51bWJlcixcbiAgICBhcmczPzogU2Vzc2lvbk9wdGlvbnMsXG4gICk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZT4ge1xuICAgIFRSQUNFX0ZVTkNfQkVHSU4oKTtcbiAgICBUUkFDRV9FVkVOVF9CRUdJTignSW5mZXJlbmNlU2Vzc2lvbi5jcmVhdGUnKTtcbiAgICAvLyBlaXRoZXIgbG9hZCBmcm9tIGEgZmlsZSBvciBidWZmZXJcbiAgICBsZXQgZmlsZVBhdGhPclVpbnQ4QXJyYXk6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gICAgbGV0IG9wdGlvbnM6IFNlc3Npb25PcHRpb25zID0ge307XG5cbiAgICBpZiAodHlwZW9mIGFyZzAgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmaWxlUGF0aE9yVWludDhBcnJheSA9IGFyZzA7XG4gICAgICBpZiAodHlwZW9mIGFyZzEgPT09ICdvYmplY3QnICYmIGFyZzEgIT09IG51bGwpIHtcbiAgICAgICAgb3B0aW9ucyA9IGFyZzE7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcxICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ29wdGlvbnMnIG11c3QgYmUgYW4gb2JqZWN0LlwiKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGFyZzAgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICBmaWxlUGF0aE9yVWludDhBcnJheSA9IGFyZzA7XG4gICAgICBpZiAodHlwZW9mIGFyZzEgPT09ICdvYmplY3QnICYmIGFyZzEgIT09IG51bGwpIHtcbiAgICAgICAgb3B0aW9ucyA9IGFyZzE7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcxICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ29wdGlvbnMnIG11c3QgYmUgYW4gb2JqZWN0LlwiKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKFxuICAgICAgYXJnMCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8XG4gICAgICAodHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiBhcmcwIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXIpXG4gICAgKSB7XG4gICAgICBjb25zdCBidWZmZXIgPSBhcmcwO1xuICAgICAgbGV0IGJ5dGVPZmZzZXQgPSAwO1xuICAgICAgbGV0IGJ5dGVMZW5ndGggPSBhcmcwLmJ5dGVMZW5ndGg7XG4gICAgICBpZiAodHlwZW9mIGFyZzEgPT09ICdvYmplY3QnICYmIGFyZzEgIT09IG51bGwpIHtcbiAgICAgICAgb3B0aW9ucyA9IGFyZzE7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcxID09PSAnbnVtYmVyJykge1xuICAgICAgICBieXRlT2Zmc2V0ID0gYXJnMTtcbiAgICAgICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihieXRlT2Zmc2V0KSkge1xuICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiJ2J5dGVPZmZzZXQnIG11c3QgYmUgYW4gaW50ZWdlci5cIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJ5dGVPZmZzZXQgPCAwIHx8IGJ5dGVPZmZzZXQgPj0gYnVmZmVyLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgJ2J5dGVPZmZzZXQnIGlzIG91dCBvZiByYW5nZSBbMCwgJHtidWZmZXIuYnl0ZUxlbmd0aH0pLmApO1xuICAgICAgICB9XG4gICAgICAgIGJ5dGVMZW5ndGggPSBhcmcwLmJ5dGVMZW5ndGggLSBieXRlT2Zmc2V0O1xuICAgICAgICBpZiAodHlwZW9mIGFyZzIgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgYnl0ZUxlbmd0aCA9IGFyZzI7XG4gICAgICAgICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihieXRlTGVuZ3RoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCInYnl0ZUxlbmd0aCcgbXVzdCBiZSBhbiBpbnRlZ2VyLlwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGJ5dGVMZW5ndGggPD0gMCB8fCBieXRlT2Zmc2V0ICsgYnl0ZUxlbmd0aCA+IGJ1ZmZlci5ieXRlTGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgJ2J5dGVMZW5ndGgnIGlzIG91dCBvZiByYW5nZSAoMCwgJHtidWZmZXIuYnl0ZUxlbmd0aCAtIGJ5dGVPZmZzZXR9XS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHR5cGVvZiBhcmczID09PSAnb2JqZWN0JyAmJiBhcmczICE9PSBudWxsKSB7XG4gICAgICAgICAgICBvcHRpb25zID0gYXJnMztcbiAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmczICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidvcHRpb25zJyBtdXN0IGJlIGFuIG9iamVjdC5cIik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInYnl0ZUxlbmd0aCcgbXVzdCBiZSBhIG51bWJlci5cIik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInb3B0aW9ucycgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgICAgfVxuICAgICAgZmlsZVBhdGhPclVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiVW5leHBlY3RlZCBhcmd1bWVudFswXTogbXVzdCBiZSAncGF0aCcgb3IgJ2J1ZmZlcicuXCIpO1xuICAgIH1cblxuICAgIC8vIHJlc29sdmUgYmFja2VuZCwgdXBkYXRlIHNlc3Npb24gb3B0aW9ucyB3aXRoIHZhbGlkYXRlZCBFUHMsIGFuZCBjcmVhdGUgc2Vzc2lvbiBoYW5kbGVyXG4gICAgY29uc3QgW2JhY2tlbmQsIG9wdGlvbnNXaXRoVmFsaWRhdGVkRVBzXSA9IGF3YWl0IHJlc29sdmVCYWNrZW5kQW5kRXhlY3V0aW9uUHJvdmlkZXJzKG9wdGlvbnMpO1xuICAgIGNvbnN0IGhhbmRsZXIgPSBhd2FpdCBiYWNrZW5kLmNyZWF0ZUluZmVyZW5jZVNlc3Npb25IYW5kbGVyKGZpbGVQYXRoT3JVaW50OEFycmF5LCBvcHRpb25zV2l0aFZhbGlkYXRlZEVQcyk7XG4gICAgVFJBQ0VfRVZFTlRfRU5EKCdJbmZlcmVuY2VTZXNzaW9uLmNyZWF0ZScpO1xuICAgIFRSQUNFX0ZVTkNfRU5EKCk7XG4gICAgcmV0dXJuIG5ldyBJbmZlcmVuY2VTZXNzaW9uKGhhbmRsZXIpO1xuICB9XG5cbiAgc3RhcnRQcm9maWxpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5oYW5kbGVyLnN0YXJ0UHJvZmlsaW5nKCk7XG4gIH1cbiAgZW5kUHJvZmlsaW5nKCk6IHZvaWQge1xuICAgIHRoaXMuaGFuZGxlci5lbmRQcm9maWxpbmcoKTtcbiAgfVxuXG4gIGdldCBpbnB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVyLmlucHV0TmFtZXM7XG4gIH1cbiAgZ2V0IG91dHB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVyLm91dHB1dE5hbWVzO1xuICB9XG5cbiAgZ2V0IGlucHV0TWV0YWRhdGEoKTogcmVhZG9ubHkgSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZS5WYWx1ZU1ldGFkYXRhW10ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIuaW5wdXRNZXRhZGF0YTtcbiAgfVxuXG4gIGdldCBvdXRwdXRNZXRhZGF0YSgpOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLlZhbHVlTWV0YWRhdGFbXSB7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlci5vdXRwdXRNZXRhZGF0YTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlcjogSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXI7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEluZmVyZW5jZVNlc3Npb24gYXMgSW5mZXJlbmNlU2Vzc2lvbkltcGwgfSBmcm9tICcuL2luZmVyZW5jZS1zZXNzaW9uLWltcGwuanMnO1xuaW1wb3J0IHsgT25ueE1vZGVsT3B0aW9ucyB9IGZyb20gJy4vb25ueC1tb2RlbC5qcyc7XG5pbXBvcnQgeyBPbm54VmFsdWUsIE9ubnhWYWx1ZURhdGFMb2NhdGlvbiB9IGZyb20gJy4vb25ueC12YWx1ZS5qcyc7XG5pbXBvcnQgdHlwZSB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yLmpzJztcbmltcG9ydCB7IFRyeUdldEdsb2JhbFR5cGUgfSBmcm9tICcuL3R5cGUtaGVscGVyLmpzJztcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlZGVjbGFyZSAqL1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgSW5mZXJlbmNlU2Vzc2lvbiB7XG4gIC8vICNyZWdpb24gaW5wdXQvb3V0cHV0IHR5cGVzXG5cbiAgdHlwZSBPbm54VmFsdWVNYXBUeXBlID0geyByZWFkb25seSBbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlIH07XG4gIHR5cGUgTnVsbGFibGVPbm54VmFsdWVNYXBUeXBlID0geyByZWFkb25seSBbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlIHwgbnVsbCB9O1xuXG4gIC8qKlxuICAgKiBBIGZlZWRzIChtb2RlbCBpbnB1dHMpIGlzIGFuIG9iamVjdCB0aGF0IHVzZXMgaW5wdXQgbmFtZXMgYXMga2V5cyBhbmQgT25ueFZhbHVlIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgKi9cbiAgdHlwZSBGZWVkc1R5cGUgPSBPbm54VmFsdWVNYXBUeXBlO1xuXG4gIC8qKlxuICAgKiBBIGZldGNoZXMgKG1vZGVsIG91dHB1dHMpIGNvdWxkIGJlIG9uZSBvZiB0aGUgZm9sbG93aW5nOlxuICAgKlxuICAgKiAtIE9taXR0ZWQuIFVzZSBtb2RlbCdzIG91dHB1dCBuYW1lcyBkZWZpbml0aW9uLlxuICAgKiAtIEFuIGFycmF5IG9mIHN0cmluZyBpbmRpY2F0aW5nIHRoZSBvdXRwdXQgbmFtZXMuXG4gICAqIC0gQW4gb2JqZWN0IHRoYXQgdXNlIG91dHB1dCBuYW1lcyBhcyBrZXlzIGFuZCBPbm54VmFsdWUgb3IgbnVsbCBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICpcbiAgICogQHJlbWFya1xuICAgKiBkaWZmZXJlbnQgZnJvbSBpbnB1dCBhcmd1bWVudCwgaW4gb3V0cHV0LCBPbm54VmFsdWUgaXMgb3B0aW9uYWwuIElmIGFuIE9ubnhWYWx1ZSBpcyBwcmVzZW50IGl0IHdpbGwgYmVcbiAgICogdXNlZCBhcyBhIHByZS1hbGxvY2F0ZWQgdmFsdWUgYnkgdGhlIGluZmVyZW5jZSBlbmdpbmU7IGlmIG9taXR0ZWQsIGluZmVyZW5jZSBlbmdpbmUgd2lsbCBhbGxvY2F0ZSBidWZmZXJcbiAgICogaW50ZXJuYWxseS5cbiAgICovXG4gIHR5cGUgRmV0Y2hlc1R5cGUgPSByZWFkb25seSBzdHJpbmdbXSB8IE51bGxhYmxlT25ueFZhbHVlTWFwVHlwZTtcblxuICAvKipcbiAgICogQSBpbmZlcmVuY2luZyByZXR1cm4gdHlwZSBpcyBhbiBvYmplY3QgdGhhdCB1c2VzIG91dHB1dCBuYW1lcyBhcyBrZXlzIGFuZCBPbm54VmFsdWUgYXMgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAqL1xuICB0eXBlIFJldHVyblR5cGUgPSBPbm54VmFsdWVNYXBUeXBlO1xuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHNlc3Npb24gb3B0aW9uc1xuXG4gIC8qKlxuICAgKiBBIHNldCBvZiBjb25maWd1cmF0aW9ucyBmb3Igc2Vzc2lvbiBiZWhhdmlvci5cbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgU2Vzc2lvbk9wdGlvbnMgZXh0ZW5kcyBPbm54TW9kZWxPcHRpb25zIHtcbiAgICAvKipcbiAgICAgKiBBbiBhcnJheSBvZiBleGVjdXRpb24gcHJvdmlkZXIgb3B0aW9ucy5cbiAgICAgKlxuICAgICAqIEFuIGV4ZWN1dGlvbiBwcm92aWRlciBvcHRpb24gY2FuIGJlIGEgc3RyaW5nIGluZGljYXRpbmcgdGhlIG5hbWUgb2YgdGhlIGV4ZWN1dGlvbiBwcm92aWRlcixcbiAgICAgKiBvciBhbiBvYmplY3Qgb2YgY29ycmVzcG9uZGluZyB0eXBlLlxuICAgICAqL1xuICAgIGV4ZWN1dGlvblByb3ZpZGVycz86IHJlYWRvbmx5IEV4ZWN1dGlvblByb3ZpZGVyQ29uZmlnW107XG5cbiAgICAvKipcbiAgICAgKiBUaGUgaW50cmEgT1AgdGhyZWFkcyBudW1iZXIuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKS5cbiAgICAgKi9cbiAgICBpbnRyYU9wTnVtVGhyZWFkcz86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBpbnRlciBPUCB0aHJlYWRzIG51bWJlci5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpLlxuICAgICAqL1xuICAgIGludGVyT3BOdW1UaHJlYWRzPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGZyZWUgZGltZW5zaW9uIG92ZXJyaWRlLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGZyZWVEaW1lbnNpb25PdmVycmlkZXM/OiB7IHJlYWRvbmx5IFtkaW1lbnNpb25OYW1lOiBzdHJpbmddOiBudW1iZXIgfTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBvcHRpbWl6YXRpb24gbGV2ZWwuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgZ3JhcGhPcHRpbWl6YXRpb25MZXZlbD86ICdkaXNhYmxlZCcgfCAnYmFzaWMnIHwgJ2V4dGVuZGVkJyB8ICdsYXlvdXQnIHwgJ2FsbCc7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIGVuYWJsZSBDUFUgbWVtb3J5IGFyZW5hLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGVuYWJsZUNwdU1lbUFyZW5hPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgZW5hYmxlIG1lbW9yeSBwYXR0ZXJuLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGVuYWJsZU1lbVBhdHRlcm4/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogRXhlY3V0aW9uIG1vZGUuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgZXhlY3V0aW9uTW9kZT86ICdzZXF1ZW50aWFsJyB8ICdwYXJhbGxlbCc7XG5cbiAgICAvKipcbiAgICAgKiBPcHRpbWl6ZWQgbW9kZWwgZmlsZSBwYXRoLlxuICAgICAqXG4gICAgICogSWYgdGhpcyBzZXR0aW5nIGlzIHNwZWNpZmllZCwgdGhlIG9wdGltaXplZCBtb2RlbCB3aWxsIGJlIGR1bXBlZC4gSW4gYnJvd3NlciwgYSBibG9iIHdpbGwgYmUgY3JlYXRlZFxuICAgICAqIHdpdGggYSBwb3AtdXAgd2luZG93LlxuICAgICAqL1xuICAgIG9wdGltaXplZE1vZGVsRmlsZVBhdGg/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIGVuYWJsZSBwcm9maWxpbmcuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYSBwbGFjZWhvbGRlciBmb3IgYSBmdXR1cmUgdXNlLlxuICAgICAqL1xuICAgIGVuYWJsZVByb2ZpbGluZz86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBGaWxlIHByZWZpeCBmb3IgcHJvZmlsaW5nLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGEgcGxhY2Vob2xkZXIgZm9yIGEgZnV0dXJlIHVzZS5cbiAgICAgKi9cbiAgICBwcm9maWxlRmlsZVByZWZpeD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIExvZyBJRC5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBsb2dJZD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIExvZyBzZXZlcml0eSBsZXZlbC4gU2VlXG4gICAgICogaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9vbm54cnVudGltZS9ibG9iL21haW4vaW5jbHVkZS9vbm54cnVudGltZS9jb3JlL2NvbW1vbi9sb2dnaW5nL3NldmVyaXR5LmhcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBsb2dTZXZlcml0eUxldmVsPzogMCB8IDEgfCAyIHwgMyB8IDQ7XG5cbiAgICAvKipcbiAgICAgKiBMb2cgdmVyYm9zaXR5IGxldmVsLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIFdlYkFzc2VtYmx5IGJhY2tlbmQuIFdpbGwgc3VwcG9ydCBOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSBsYXRlclxuICAgICAqL1xuICAgIGxvZ1ZlcmJvc2l0eUxldmVsPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogU3BlY2lmeSBzdHJpbmcgYXMgYSBwcmVmZXJyZWQgZGF0YSBsb2NhdGlvbiBmb3IgYWxsIG91dHB1dHMsIG9yIGFuIG9iamVjdCB0aGF0IHVzZSBvdXRwdXQgbmFtZXMgYXMga2V5cyBhbmQgYVxuICAgICAqIHByZWZlcnJlZCBkYXRhIGxvY2F0aW9uIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIFdlYiBmb3IgV2ViR0wgYW5kIFdlYkdQVSBFUC5cbiAgICAgKi9cbiAgICBwcmVmZXJyZWRPdXRwdXRMb2NhdGlvbj86IE9ubnhWYWx1ZURhdGFMb2NhdGlvbiB8IHsgcmVhZG9ubHkgW291dHB1dE5hbWU6IHN0cmluZ106IE9ubnhWYWx1ZURhdGFMb2NhdGlvbiB9O1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciBlbmFibGUgZ3JhcGggY2FwdHVyZS5cbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgV2ViIGZvciBXZWJHUFUgRVAuXG4gICAgICovXG4gICAgZW5hYmxlR3JhcGhDYXB0dXJlPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFN0b3JlIGNvbmZpZ3VyYXRpb25zIGZvciBhIHNlc3Npb24uIFNlZVxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvb25ueHJ1bnRpbWUvYmxvYi9tYWluL2luY2x1ZGUvb25ueHJ1bnRpbWUvY29yZS9zZXNzaW9uL1xuICAgICAqIG9ubnhydW50aW1lX3Nlc3Npb25fb3B0aW9uc19jb25maWdfa2V5cy5oXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gV2ViQXNzZW1ibHkgYmFja2VuZC4gV2lsbCBzdXBwb3J0IE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlIGxhdGVyXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZXh0cmE6IHtcbiAgICAgKiAgIHNlc3Npb246IHtcbiAgICAgKiAgICAgc2V0X2Rlbm9ybWFsX2FzX3plcm86IFwiMVwiLFxuICAgICAqICAgICBkaXNhYmxlX3ByZXBhY2tpbmc6IFwiMVwiXG4gICAgICogICB9LFxuICAgICAqICAgb3B0aW1pemF0aW9uOiB7XG4gICAgICogICAgIGVuYWJsZV9nZWx1X2FwcHJveGltYXRpb246IFwiMVwiXG4gICAgICogICB9XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGV4dHJhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIH1cblxuICAvLyAjcmVnaW9uIGV4ZWN1dGlvbiBwcm92aWRlcnNcblxuICAvLyBDdXJyZW50bHksIHdlIGhhdmUgdGhlIGZvbGxvd2luZyBiYWNrZW5kcyB0byBzdXBwb3J0IGV4ZWN1dGlvbiBwcm92aWRlcnM6XG4gIC8vIEJhY2tlbmQgTm9kZS5qcyBiaW5kaW5nOiBzdXBwb3J0cyAnY3B1JywgJ2RtbCcgKHdpbjMyKSwgJ2NvcmVtbCcgKG1hY09TKSBhbmQgJ2N1ZGEnIChsaW51eCkuXG4gIC8vIEJhY2tlbmQgV2ViQXNzZW1ibHk6IHN1cHBvcnRzICdjcHUnLCAnd2FzbScsICd3ZWJncHUnIGFuZCAnd2Vibm4nLlxuICAvLyBCYWNrZW5kIE9OTlguanM6IHN1cHBvcnRzICd3ZWJnbCcuXG4gIC8vIEJhY2tlbmQgUmVhY3QgTmF0aXZlOiBzdXBwb3J0cyAnY3B1JywgJ3hubnBhY2snLCAnY29yZW1sJyAoaU9TKSwgJ25uYXBpJyAoQW5kcm9pZCkuXG4gIGludGVyZmFjZSBFeGVjdXRpb25Qcm92aWRlck9wdGlvbk1hcCB7XG4gICAgY29yZW1sOiBDb3JlTUxFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICBjcHU6IENwdUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIGN1ZGE6IEN1ZGFFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICBkbWw6IERtbEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIG5uYXBpOiBObmFwaUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHRlbnNvcnJ0OiBUZW5zb3JSdEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHdhc206IFdlYkFzc2VtYmx5RXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgd2ViZ2w6IFdlYkdMRXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgd2ViZ3B1OiBXZWJHcHVFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICB3ZWJubjogV2ViTk5FeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICBxbm46IFFubkV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHhubnBhY2s6IFhubnBhY2tFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgfVxuXG4gIHR5cGUgRXhlY3V0aW9uUHJvdmlkZXJOYW1lID0ga2V5b2YgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb25NYXA7XG4gIHR5cGUgRXhlY3V0aW9uUHJvdmlkZXJDb25maWcgPVxuICAgIHwgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb25NYXBbRXhlY3V0aW9uUHJvdmlkZXJOYW1lXVxuICAgIHwgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb25cbiAgICB8IEV4ZWN1dGlvblByb3ZpZGVyTmFtZVxuICAgIHwgc3RyaW5nO1xuXG4gIGV4cG9ydCBpbnRlcmZhY2UgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIENwdUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdjcHUnO1xuICAgIHVzZUFyZW5hPzogYm9vbGVhbjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIEN1ZGFFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnY3VkYSc7XG4gICAgZGV2aWNlSWQ/OiBudW1iZXI7XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBEbWxFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnZG1sJztcbiAgICBkZXZpY2VJZD86IG51bWJlcjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFRlbnNvclJ0RXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3RlbnNvcnJ0JztcbiAgICBkZXZpY2VJZD86IG51bWJlcjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFdlYkFzc2VtYmx5RXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3dhc20nO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViR0xFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnd2ViZ2wnO1xuICAgIC8vIFRPRE86IGFkZCBmbGFnc1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgWG5ucGFja0V4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICd4bm5wYWNrJztcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFdlYkdwdUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICd3ZWJncHUnO1xuXG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgcHJlZmVycmVkIGxheW91dCB3aGVuIHJ1bm5pbmcgbGF5b3V0IHNlbnNpdGl2ZSBvcGVyYXRvcnMuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCAnTkNIVydcbiAgICAgKi9cbiAgICBwcmVmZXJyZWRMYXlvdXQ/OiAnTkNIVycgfCAnTkhXQyc7XG5cbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IGEgbGlzdCBvZiBub2RlIG5hbWVzIHRoYXQgc2hvdWxkIGJlIGV4ZWN1dGVkIG9uIENQVSBldmVuIHdoZW4gV2ViR1BVIEVQIGlzIHVzZWQuXG4gICAgICovXG4gICAgZm9yY2VDcHVOb2RlTmFtZXM/OiByZWFkb25seSBzdHJpbmdbXTtcblxuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgdGhlIHZhbGlkYXRpb24gbW9kZSBmb3IgV2ViR1BVIGV4ZWN1dGlvbiBwcm92aWRlci5cbiAgICAgKiAtICdkaXNhYmxlZCc6IERpc2FibGUgYWxsIHZhbGlkYXRpb24uXG4gICAgICogV2hlbiB1c2VkIGluIE5vZGUuanMsIGRpc2FibGUgdmFsaWRhdGlvbiBtYXkgY2F1c2UgcHJvY2VzcyBjcmFzaCBpZiBXZWJHUFUgZXJyb3JzIG9jY3VyLiBCZSBjYXV0aW91cyB3aGVuIHVzaW5nXG4gICAgICogdGhpcyBtb2RlLlxuICAgICAqIFdoZW4gdXNlZCBpbiB3ZWIsIHRoaXMgbW9kZSBpcyBlcXVpdmFsZW50IHRvICd3Z3B1T25seScuXG4gICAgICogLSAnd2dwdU9ubHknOiBQZXJmb3JtIFdlYkdQVSBpbnRlcm5hbCB2YWxpZGF0aW9uIG9ubHkuXG4gICAgICogLSAnYmFzaWMnOiBQZXJmb3JtIGJhc2ljIHZhbGlkYXRpb24gaW5jbHVkaW5nIFdlYkdQVSBpbnRlcm5hbCB2YWxpZGF0aW9uLiBUaGlzIGlzIHRoZSBkZWZhdWx0IG1vZGUuXG4gICAgICogLSAnZnVsbCc6IFBlcmZvcm0gZnVsbCB2YWxpZGF0aW9uLiBUaGlzIG1vZGUgbWF5IGhhdmUgcGVyZm9ybWFuY2UgaW1wYWN0LiBVc2UgaXQgZm9yIGRlYnVnZ2luZyBwdXJwb3NlLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgJ2Jhc2ljJ1xuICAgICAqL1xuICAgIHZhbGlkYXRpb25Nb2RlPzogJ2Rpc2FibGVkJyB8ICd3Z3B1T25seScgfCAnYmFzaWMnIHwgJ2Z1bGwnO1xuXG4gICAgLyoqXG4gICAgICogU3BlY2lmeSBhbiBvcHRpb25hbCBXZWJHUFUgZGV2aWNlIHRvIGJlIHVzZWQgYnkgdGhlIFdlYkdQVSBleGVjdXRpb24gcHJvdmlkZXIuXG4gICAgICovXG4gICAgZGV2aWNlPzogVHJ5R2V0R2xvYmFsVHlwZTwnR1BVRGV2aWNlJz47XG4gIH1cblxuICAvLyAjcmVnaW9uIFdlYk5OIG9wdGlvbnNcblxuICBpbnRlcmZhY2UgV2ViTk5FeGVjdXRpb25Qcm92aWRlck5hbWUgZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3dlYm5uJztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIGEgc2V0IG9mIG9wdGlvbnMgZm9yIGNyZWF0aW5nIGEgV2ViTk4gTUxDb250ZXh0LlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi93ZWJubi8jZGljdGRlZi1tbGNvbnRleHRvcHRpb25zXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFdlYk5OQ29udGV4dE9wdGlvbnMge1xuICAgIGRldmljZVR5cGU/OiAnY3B1JyB8ICdncHUnIHwgJ25wdSc7XG4gICAgbnVtVGhyZWFkcz86IG51bWJlcjtcbiAgICBwb3dlclByZWZlcmVuY2U/OiAnZGVmYXVsdCcgfCAnbG93LXBvd2VyJyB8ICdoaWdoLXBlcmZvcm1hbmNlJztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIGEgc2V0IG9mIG9wdGlvbnMgZm9yIFdlYk5OIGV4ZWN1dGlvbiBwcm92aWRlciB3aXRob3V0IE1MQ29udGV4dC5cbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViTk5PcHRpb25zV2l0aG91dE1MQ29udGV4dCBleHRlbmRzIFdlYk5ORXhlY3V0aW9uUHJvdmlkZXJOYW1lLCBXZWJOTkNvbnRleHRPcHRpb25zIHtcbiAgICBjb250ZXh0PzogbmV2ZXI7XG4gIH1cblxuICAvKipcbiAgICogUmVwcmVzZW50cyBhIHNldCBvZiBvcHRpb25zIGZvciBXZWJOTiBleGVjdXRpb24gcHJvdmlkZXIgd2l0aCBNTENvbnRleHQuXG4gICAqXG4gICAqIFdoZW4gTUxDb250ZXh0IGlzIHByb3ZpZGVkLCB0aGUgZGV2aWNlVHlwZSBpcyBhbHNvIHJlcXVpcmVkIHNvIHRoYXQgdGhlIFdlYk5OIEVQIGNhbiBkZXRlcm1pbmUgdGhlIHByZWZlcnJlZFxuICAgKiBjaGFubmVsIGxheW91dC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvd2Vibm4vI2RvbS1tbC1jcmVhdGVjb250ZXh0XG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFdlYk5OT3B0aW9uc1dpdGhNTENvbnRleHRcbiAgICBleHRlbmRzIFdlYk5ORXhlY3V0aW9uUHJvdmlkZXJOYW1lLFxuICAgICAgT21pdDxXZWJOTkNvbnRleHRPcHRpb25zLCAnZGV2aWNlVHlwZSc+LFxuICAgICAgUmVxdWlyZWQ8UGljazxXZWJOTkNvbnRleHRPcHRpb25zLCAnZGV2aWNlVHlwZSc+PiB7XG4gICAgY29udGV4dDogVHJ5R2V0R2xvYmFsVHlwZTwnTUxDb250ZXh0Jz47XG4gIH1cblxuICAvKipcbiAgICogUmVwcmVzZW50cyBhIHNldCBvZiBvcHRpb25zIGZvciBXZWJOTiBleGVjdXRpb24gcHJvdmlkZXIgd2l0aCBNTENvbnRleHQgd2hpY2ggaXMgY3JlYXRlZCBmcm9tIEdQVURldmljZS5cbiAgICpcbiAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvd2Vibm4vI2RvbS1tbC1jcmVhdGVjb250ZXh0LWdwdWRldmljZVxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJOTk9wdGlvbnNXZWJHcHUgZXh0ZW5kcyBXZWJOTkV4ZWN1dGlvblByb3ZpZGVyTmFtZSB7XG4gICAgY29udGV4dDogVHJ5R2V0R2xvYmFsVHlwZTwnTUxDb250ZXh0Jz47XG4gICAgZ3B1RGV2aWNlOiBUcnlHZXRHbG9iYWxUeXBlPCdHUFVEZXZpY2UnPjtcbiAgfVxuXG4gIC8qKlxuICAgKiBPcHRpb25zIGZvciBXZWJOTiBleGVjdXRpb24gcHJvdmlkZXIuXG4gICAqL1xuICBleHBvcnQgdHlwZSBXZWJOTkV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uID1cbiAgICB8IFdlYk5OT3B0aW9uc1dpdGhvdXRNTENvbnRleHRcbiAgICB8IFdlYk5OT3B0aW9uc1dpdGhNTENvbnRleHRcbiAgICB8IFdlYk5OT3B0aW9uc1dlYkdwdTtcblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgZXhwb3J0IGludGVyZmFjZSBRbm5FeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAncW5uJztcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHRoZSBRTk4gYmFja2VuZCB0eXBlLiBFLmcuLCAnY3B1JyBvciAnaHRwJy5cbiAgICAgKiBNdXR1YWxseSBleGNsdXNpdmUgd2l0aCBgYmFja2VuZFBhdGhgLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgJ2h0cCdcbiAgICAgKi9cbiAgICBiYWNrZW5kVHlwZT86IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IGEgcGF0aCB0byB0aGUgUU5OIGJhY2tlbmQgbGlicmFyeS5cbiAgICAgKiBNdXR1YWxseSBleGNsdXNpdmUgd2l0aCBgYmFja2VuZFR5cGVgLlxuICAgICAqL1xuICAgIGJhY2tlbmRQYXRoPzogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgd2hldGhlciB0byBlbmFibGUgSFRQIEZQMTYgcHJlY2lzaW9uLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgdHJ1ZVxuICAgICAqL1xuICAgIGVuYWJsZUZwMTZQcmVjaXNpb24/OiBib29sZWFuO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ29yZU1MRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ2NvcmVtbCc7XG4gICAgLyoqXG4gICAgICogVGhlIGJpdCBmbGFncyBmb3IgQ29yZU1MIGV4ZWN1dGlvbiBwcm92aWRlci5cbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqIENPUkVNTF9GTEFHX1VTRV9DUFVfT05MWSA9IDB4MDAxXG4gICAgICogQ09SRU1MX0ZMQUdfRU5BQkxFX09OX1NVQkdSQVBIID0gMHgwMDJcbiAgICAgKiBDT1JFTUxfRkxBR19PTkxZX0VOQUJMRV9ERVZJQ0VfV0lUSF9BTkUgPSAweDAwNFxuICAgICAqIENPUkVNTF9GTEFHX09OTFlfQUxMT1dfU1RBVElDX0lOUFVUX1NIQVBFUyA9IDB4MDA4XG4gICAgICogQ09SRU1MX0ZMQUdfQ1JFQVRFX01MUFJPR1JBTSA9IDB4MDEwXG4gICAgICogQ09SRU1MX0ZMQUdfVVNFX0NQVV9BTkRfR1BVID0gMHgwMjBcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFNlZSBpbmNsdWRlL29ubnhydW50aW1lL2NvcmUvcHJvdmlkZXJzL2NvcmVtbC9jb3JlbWxfcHJvdmlkZXJfZmFjdG9yeS5oIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICpcbiAgICAgKiBUaGlzIGZsYWcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZykuXG4gICAgICovXG4gICAgY29yZU1sRmxhZ3M/OiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB3aGV0aGVyIHRvIHVzZSBDUFUgb25seSBpbiBDb3JlTUwgRVAuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKHJlYWN0LW5hdGl2ZSkuXG4gICAgICovXG4gICAgdXNlQ1BVT25seT86IGJvb2xlYW47XG4gICAgdXNlQ1BVQW5kR1BVPzogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHdoZXRoZXIgdG8gZW5hYmxlIENvcmVNTCBFUCBvbiBzdWJncmFwaC5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAocmVhY3QtbmF0aXZlKS5cbiAgICAgKi9cbiAgICBlbmFibGVPblN1YmdyYXBoPzogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHdoZXRoZXIgdG8gb25seSBlbmFibGUgQ29yZU1MIEVQIGZvciBBcHBsZSBkZXZpY2VzIHdpdGggQU5FIChBcHBsZSBOZXVyYWwgRW5naW5lKS5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAocmVhY3QtbmF0aXZlKS5cbiAgICAgKi9cbiAgICBvbmx5RW5hYmxlRGV2aWNlV2l0aEFORT86IGJvb2xlYW47XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBObmFwaUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdubmFwaSc7XG4gICAgdXNlRlAxNj86IGJvb2xlYW47XG4gICAgdXNlTkNIVz86IGJvb2xlYW47XG4gICAgY3B1RGlzYWJsZWQ/OiBib29sZWFuO1xuICAgIGNwdU9ubHk/OiBib29sZWFuO1xuICB9XG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBydW4gb3B0aW9uc1xuXG4gIC8qKlxuICAgKiBBIHNldCBvZiBjb25maWd1cmF0aW9ucyBmb3IgaW5mZXJlbmNlIHJ1biBiZWhhdmlvclxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBSdW5PcHRpb25zIHtcbiAgICAvKipcbiAgICAgKiBMb2cgc2V2ZXJpdHkgbGV2ZWwuIFNlZVxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvb25ueHJ1bnRpbWUvYmxvYi9tYWluL2luY2x1ZGUvb25ueHJ1bnRpbWUvY29yZS9jb21tb24vbG9nZ2luZy9zZXZlcml0eS5oXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgbG9nU2V2ZXJpdHlMZXZlbD86IDAgfCAxIHwgMiB8IDMgfCA0O1xuXG4gICAgLyoqXG4gICAgICogTG9nIHZlcmJvc2l0eSBsZXZlbC5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBXZWJBc3NlbWJseSBiYWNrZW5kLiBXaWxsIHN1cHBvcnQgTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUgbGF0ZXJcbiAgICAgKi9cbiAgICBsb2dWZXJib3NpdHlMZXZlbD86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFRlcm1pbmF0ZSBhbGwgaW5jb21wbGV0ZSBPcnRSdW4gY2FsbHMgYXMgc29vbiBhcyBwb3NzaWJsZSBpZiB0cnVlXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gV2ViQXNzZW1ibHkgYmFja2VuZC4gV2lsbCBzdXBwb3J0IE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlIGxhdGVyXG4gICAgICovXG4gICAgdGVybWluYXRlPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIEEgdGFnIGZvciB0aGUgUnVuKCkgY2FsbHMgdXNpbmcgdGhpc1xuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIHRhZz86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFNldCBhIHNpbmdsZSBydW4gY29uZmlndXJhdGlvbiBlbnRyeS4gU2VlXG4gICAgICogaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9vbm54cnVudGltZS9ibG9iL21haW4vaW5jbHVkZS9vbm54cnVudGltZS9jb3JlL3Nlc3Npb24vXG4gICAgICogb25ueHJ1bnRpbWVfcnVuX29wdGlvbnNfY29uZmlnX2tleXMuaFxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIFdlYkFzc2VtYmx5IGJhY2tlbmQuIFdpbGwgc3VwcG9ydCBOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSBsYXRlclxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogZXh0cmE6IHtcbiAgICAgKiAgIG1lbW9yeToge1xuICAgICAqICAgICBlbmFibGVfbWVtb3J5X2FyZW5hX3Nocmlua2FnZTogXCIxXCIsXG4gICAgICogICB9XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGV4dHJhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIH1cblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiB2YWx1ZSBtZXRhZGF0YVxuXG4gIC8qKlxuICAgKiBUaGUgY29tbW9uIHBhcnQgb2YgdGhlIHZhbHVlIG1ldGFkYXRhIHR5cGUgZm9yIGJvdGggdGVuc29yIGFuZCBub24tdGVuc29yIHZhbHVlcy5cbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgVmFsdWVNZXRhZGF0YUJhc2Uge1xuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBzcGVjaWZpZWQgaW5wdXQgb3Igb3V0cHV0LlxuICAgICAqL1xuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIHRoZSBtZXRhZGF0YSBvZiBhIG5vbi10ZW5zb3IgdmFsdWUuXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIE5vblRlbnNvclZhbHVlTWV0YWRhdGEgZXh0ZW5kcyBWYWx1ZU1ldGFkYXRhQmFzZSB7XG4gICAgLyoqXG4gICAgICogR2V0IGEgdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSB2YWx1ZSBpcyBhIHRlbnNvci5cbiAgICAgKi9cbiAgICByZWFkb25seSBpc1RlbnNvcjogZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogUmVwcmVzZW50cyB0aGUgbWV0YWRhdGEgb2YgYSB0ZW5zb3IgdmFsdWUuXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFRlbnNvclZhbHVlTWV0YWRhdGEgZXh0ZW5kcyBWYWx1ZU1ldGFkYXRhQmFzZSB7XG4gICAgLyoqXG4gICAgICogR2V0IGEgdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSB2YWx1ZSBpcyBhIHRlbnNvci5cbiAgICAgKi9cbiAgICByZWFkb25seSBpc1RlbnNvcjogdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IHR5cGU6IFRlbnNvci5UeXBlO1xuICAgIC8qKlxuICAgICAqIEdldCB0aGUgc2hhcGUgb2YgdGhlIHRlbnNvci5cbiAgICAgKlxuICAgICAqIElmIHRoZSBzaGFwZSBpcyBub3QgZGVmaW5lZCwgdGhlIHZhbHVlIHdpbGwgYW4gZW1wdHkgYXJyYXkuIE90aGVyd2lzZSwgaXQgd2lsbCBiZSBhbiBhcnJheSByZXByZXNlbnRpbmcgdGhlIHNoYXBlXG4gICAgICogb2YgdGhlIHRlbnNvci4gRWFjaCBlbGVtZW50IGluIHRoZSBhcnJheSBjYW4gYmUgYSBudW1iZXIgb3IgYSBzdHJpbmcuIElmIHRoZSBlbGVtZW50IGlzIGEgbnVtYmVyLCBpdCByZXByZXNlbnRzXG4gICAgICogdGhlIGNvcnJlc3BvbmRpbmcgZGltZW5zaW9uIHNpemUuIElmIHRoZSBlbGVtZW50IGlzIGEgc3RyaW5nLCBpdCByZXByZXNlbnRzIGEgc3ltYm9saWMgZGltZW5zaW9uLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IHNoYXBlOiBSZWFkb25seUFycmF5PG51bWJlciB8IHN0cmluZz47XG4gIH1cblxuICAvKipcbiAgICogUmVwcmVzZW50cyB0aGUgbWV0YWRhdGEgb2YgYSB2YWx1ZS5cbiAgICovXG4gIGV4cG9ydCB0eXBlIFZhbHVlTWV0YWRhdGEgPSBOb25UZW5zb3JWYWx1ZU1ldGFkYXRhIHwgVGVuc29yVmFsdWVNZXRhZGF0YTtcblxuICAvLyAjZW5kcmVnaW9uXG59XG5cbi8qKlxuICogUmVwcmVzZW50IGEgcnVudGltZSBpbnN0YW5jZSBvZiBhbiBPTk5YIG1vZGVsLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEluZmVyZW5jZVNlc3Npb24ge1xuICAvLyAjcmVnaW9uIHJ1bigpXG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgdGhlIG1vZGVsIGFzeW5jaHJvbm91c2x5IHdpdGggdGhlIGdpdmVuIGZlZWRzIGFuZCBvcHRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0gZmVlZHMgLSBSZXByZXNlbnRhdGlvbiBvZiB0aGUgbW9kZWwgaW5wdXQuIFNlZSB0eXBlIGRlc2NyaXB0aW9uIG9mIGBJbmZlcmVuY2VTZXNzaW9uLklucHV0VHlwZWAgZm9yIGRldGFpbC5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25hbC4gQSBzZXQgb2Ygb3B0aW9ucyB0aGF0IGNvbnRyb2xzIHRoZSBiZWhhdmlvciBvZiBtb2RlbCBpbmZlcmVuY2UuXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgbWFwLCB3aGljaCB1c2VzIG91dHB1dCBuYW1lcyBhcyBrZXlzIGFuZCBPbm54VmFsdWUgYXMgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAqL1xuICBydW4oZmVlZHM6IEluZmVyZW5jZVNlc3Npb24uRmVlZHNUeXBlLCBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uLlJldHVyblR5cGU+O1xuXG4gIC8qKlxuICAgKiBFeGVjdXRlIHRoZSBtb2RlbCBhc3luY2hyb25vdXNseSB3aXRoIHRoZSBnaXZlbiBmZWVkcywgZmV0Y2hlcyBhbmQgb3B0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIGZlZWRzIC0gUmVwcmVzZW50YXRpb24gb2YgdGhlIG1vZGVsIGlucHV0LiBTZWUgdHlwZSBkZXNjcmlwdGlvbiBvZiBgSW5mZXJlbmNlU2Vzc2lvbi5JbnB1dFR5cGVgIGZvciBkZXRhaWwuXG4gICAqIEBwYXJhbSBmZXRjaGVzIC0gUmVwcmVzZW50YXRpb24gb2YgdGhlIG1vZGVsIG91dHB1dC4gU2VlIHR5cGUgZGVzY3JpcHRpb24gb2YgYEluZmVyZW5jZVNlc3Npb24uT3V0cHV0VHlwZWAgZm9yXG4gICAqIGRldGFpbC5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25hbC4gQSBzZXQgb2Ygb3B0aW9ucyB0aGF0IGNvbnRyb2xzIHRoZSBiZWhhdmlvciBvZiBtb2RlbCBpbmZlcmVuY2UuXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgbWFwLCB3aGljaCB1c2VzIG91dHB1dCBuYW1lcyBhcyBrZXlzIGFuZCBPbm54VmFsdWUgYXMgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAqL1xuICBydW4oXG4gICAgZmVlZHM6IEluZmVyZW5jZVNlc3Npb24uRmVlZHNUeXBlLFxuICAgIGZldGNoZXM6IEluZmVyZW5jZVNlc3Npb24uRmV0Y2hlc1R5cGUsXG4gICAgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uLlJldHVyblR5cGU+O1xuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHJlbGVhc2UoKVxuXG4gIC8qKlxuICAgKiBSZWxlYXNlIHRoZSBpbmZlcmVuY2Ugc2Vzc2lvbiBhbmQgdGhlIHVuZGVybHlpbmcgcmVzb3VyY2VzLlxuICAgKi9cbiAgcmVsZWFzZSgpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHByb2ZpbGluZ1xuXG4gIC8qKlxuICAgKiBTdGFydCBwcm9maWxpbmcuXG4gICAqL1xuICBzdGFydFByb2ZpbGluZygpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBFbmQgcHJvZmlsaW5nLlxuICAgKi9cbiAgZW5kUHJvZmlsaW5nKCk6IHZvaWQ7XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gbWV0YWRhdGFcblxuICAvKipcbiAgICogR2V0IGlucHV0IG5hbWVzIG9mIHRoZSBsb2FkZWQgbW9kZWwuXG4gICAqL1xuICByZWFkb25seSBpbnB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcblxuICAvKipcbiAgICogR2V0IG91dHB1dCBuYW1lcyBvZiB0aGUgbG9hZGVkIG1vZGVsLlxuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBHZXQgaW5wdXQgbWV0YWRhdGEgb2YgdGhlIGxvYWRlZCBtb2RlbC5cbiAgICovXG4gIHJlYWRvbmx5IGlucHV0TWV0YWRhdGE6IHJlYWRvbmx5IEluZmVyZW5jZVNlc3Npb24uVmFsdWVNZXRhZGF0YVtdO1xuXG4gIC8qKlxuICAgKiBHZXQgb3V0cHV0IG1ldGFkYXRhIG9mIHRoZSBsb2FkZWQgbW9kZWwuXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRNZXRhZGF0YTogcmVhZG9ubHkgSW5mZXJlbmNlU2Vzc2lvbi5WYWx1ZU1ldGFkYXRhW107XG5cbiAgLy8gI2VuZHJlZ2lvblxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEluZmVyZW5jZVNlc3Npb25GYWN0b3J5IHtcbiAgLy8gI3JlZ2lvbiBjcmVhdGUoKVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24gYW5kIGxvYWQgbW9kZWwgYXN5bmNocm9ub3VzbHkgZnJvbSBhbiBPTk5YIG1vZGVsIGZpbGUuXG4gICAqXG4gICAqIEBwYXJhbSB1cmkgLSBUaGUgVVJJIG9yIGZpbGUgcGF0aCBvZiB0aGUgbW9kZWwgdG8gbG9hZC5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBzcGVjaWZ5IGNvbmZpZ3VyYXRpb24gZm9yIGNyZWF0aW5nIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBJbmZlcmVuY2VTZXNzaW9uIG9iamVjdC5cbiAgICovXG4gIGNyZWF0ZSh1cmk6IHN0cmluZywgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24+O1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24gYW5kIGxvYWQgbW9kZWwgYXN5bmNocm9ub3VzbHkgZnJvbSBhbiBhcnJheSBidWZlci5cbiAgICpcbiAgICogQHBhcmFtIGJ1ZmZlciAtIEFuIEFycmF5QnVmZmVyIHJlcHJlc2VudGF0aW9uIG9mIGFuIE9OTlggbW9kZWwuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gc3BlY2lmeSBjb25maWd1cmF0aW9uIGZvciBjcmVhdGluZyBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gSW5mZXJlbmNlU2Vzc2lvbiBvYmplY3QuXG4gICAqL1xuICBjcmVhdGUoYnVmZmVyOiBBcnJheUJ1ZmZlckxpa2UsIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uPjtcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uIGFuZCBsb2FkIG1vZGVsIGFzeW5jaHJvbm91c2x5IGZyb20gc2VnbWVudCBvZiBhbiBhcnJheSBidWZlci5cbiAgICpcbiAgICogQHBhcmFtIGJ1ZmZlciAtIEFuIEFycmF5QnVmZmVyIHJlcHJlc2VudGF0aW9uIG9mIGFuIE9OTlggbW9kZWwuXG4gICAqIEBwYXJhbSBieXRlT2Zmc2V0IC0gVGhlIGJlZ2lubmluZyBvZiB0aGUgc3BlY2lmaWVkIHBvcnRpb24gb2YgdGhlIGFycmF5IGJ1ZmZlci5cbiAgICogQHBhcmFtIGJ5dGVMZW5ndGggLSBUaGUgbGVuZ3RoIGluIGJ5dGVzIG9mIHRoZSBhcnJheSBidWZmZXIuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gc3BlY2lmeSBjb25maWd1cmF0aW9uIGZvciBjcmVhdGluZyBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gSW5mZXJlbmNlU2Vzc2lvbiBvYmplY3QuXG4gICAqL1xuICBjcmVhdGUoXG4gICAgYnVmZmVyOiBBcnJheUJ1ZmZlckxpa2UsXG4gICAgYnl0ZU9mZnNldDogbnVtYmVyLFxuICAgIGJ5dGVMZW5ndGg/OiBudW1iZXIsXG4gICAgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMsXG4gICk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbj47XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbiBhbmQgbG9hZCBtb2RlbCBhc3luY2hyb25vdXNseSBmcm9tIGEgVWludDhBcnJheS5cbiAgICpcbiAgICogQHBhcmFtIGJ1ZmZlciAtIEEgVWludDhBcnJheSByZXByZXNlbnRhdGlvbiBvZiBhbiBPTk5YIG1vZGVsLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIHNwZWNpZnkgY29uZmlndXJhdGlvbiBmb3IgY3JlYXRpbmcgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24uXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEluZmVyZW5jZVNlc3Npb24gb2JqZWN0LlxuICAgKi9cbiAgY3JlYXRlKGJ1ZmZlcjogVWludDhBcnJheSwgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24+O1xuXG4gIC8vICNlbmRyZWdpb25cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZXhwb3J0IGNvbnN0IEluZmVyZW5jZVNlc3Npb246IEluZmVyZW5jZVNlc3Npb25GYWN0b3J5ID0gSW5mZXJlbmNlU2Vzc2lvbkltcGw7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IE9wdGlvbnNGb3JtYXQsIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycywgT3B0aW9uc1RlbnNvckxheW91dCB9IGZyb20gJy4vdGVuc29yLWZhY3RvcnkuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvclRvRGF0YVVybE9wdGlvbnMgZXh0ZW5kcyBPcHRpb25zVGVuc29yTGF5b3V0LCBPcHRpb25zRm9ybWF0LCBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMge31cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JUb0ltYWdlRGF0YU9wdGlvbnMgZXh0ZW5kcyBPcHRpb25zVGVuc29yTGF5b3V0LCBPcHRpb25zRm9ybWF0LCBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMge31cblxuZXhwb3J0IGludGVyZmFjZSBDb252ZXJzaW9uVXRpbHMge1xuICAvKipcbiAgICogY3JlYXRlcyBhIERhdGFVUkwgaW5zdGFuY2UgZnJvbSB0ZW5zb3JcbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIGEgRGF0YVVSTCBpbnN0YW5jZSBmcm9tIHRoZSB0ZW5zb3IuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYGZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogQHJldHVybnMgYSBEYXRhVVJMIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGltYWdlIGNvbnZlcnRlZCBmcm9tIHRlbnNvciBkYXRhXG4gICAqL1xuICB0b0RhdGFVUkwob3B0aW9ucz86IFRlbnNvclRvRGF0YVVybE9wdGlvbnMpOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIGNyZWF0ZXMgYW4gSW1hZ2VEYXRhIGluc3RhbmNlIGZyb20gdGVuc29yXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyBhbiBJbWFnZURhdGEgaW5zdGFuY2UgZnJvbSB0aGUgdGVuc29yLlxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGRlZmF1bHQgc2V0dGluZ3Mgd2lsbCBiZSBhcHBsaWVkOlxuICAgKiAtIGBmb3JtYXRgOiBgJ1JHQidgXG4gICAqIC0gYHRlbnNvckxheW91dGA6IGAnTkNIVydgXG4gICAqIEByZXR1cm5zIGFuIEltYWdlRGF0YSBpbnN0YW5jZSByZXByZXNlbnRpbmcgdGhlIGltYWdlIGNvbnZlcnRlZCBmcm9tIHRlbnNvciBkYXRhXG4gICAqL1xuICB0b0ltYWdlRGF0YShvcHRpb25zPzogVGVuc29yVG9JbWFnZURhdGFPcHRpb25zKTogSW1hZ2VEYXRhO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IsIFR5cGVkVGVuc29yIH0gZnJvbSAnLi90ZW5zb3IuanMnO1xuXG5leHBvcnQgdHlwZSBJbWFnZUZvcm1hdCA9ICdSR0InIHwgJ1JHQkEnIHwgJ0JHUicgfCAnUkJHJztcbmV4cG9ydCB0eXBlIEltYWdlVGVuc29yTGF5b3V0ID0gJ05IV0MnIHwgJ05DSFcnO1xuXG4vLyB0aGUgZm9sbG93aW5nIHJlZ2lvbiBjb250YWlucyB0eXBlIGRlZmluaXRpb25zIGZvciBjb25zdHJ1Y3RpbmcgdGVuc29yIGZyb20gYSBzcGVjaWZpYyBsb2NhdGlvbi5cblxuLy8gI3JlZ2lvbiB0eXBlcyBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBzcGVjaWZpYyBsb2NhdGlvblxuXG4vKipcbiAqIHJlcHJlc2VudCBjb21tb24gcHJvcGVydGllcyBvZiB0aGUgcGFyYW1ldGVyIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIHNwZWNpZmljIGxvY2F0aW9uLlxuICovXG5pbnRlcmZhY2UgQ29tbW9uQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IGV4dGVuZHMgUGljazxUZW5zb3IsICdkaW1zJz4ge1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAqL1xuICByZWFkb25seSB0eXBlOiBUO1xufVxuXG4vKipcbiAqIHJlcHJlc2VudCB0aGUgcGFyYW1ldGVyIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIEdQVSByZXNvdXJjZS5cbiAqL1xuaW50ZXJmYWNlIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQgZXh0ZW5kcyBUZW5zb3IuVHlwZT4ge1xuICAvKipcbiAgICogYW4gb3B0aW9uYWwgY2FsbGJhY2sgZnVuY3Rpb24gdG8gZG93bmxvYWQgZGF0YSBmcm9tIEdQVSB0byBDUFUuXG4gICAqXG4gICAqIElmIG5vdCBwcm92aWRlZCwgdGhlIHRlbnNvciB0cmVhdCB0aGUgR1BVIGRhdGEgYXMgZXh0ZXJuYWwgcmVzb3VyY2UuXG4gICAqL1xuICBkb3dubG9hZD8oKTogUHJvbWlzZTxUZW5zb3IuRGF0YVR5cGVNYXBbVF0+O1xuXG4gIC8qKlxuICAgKiBhbiBvcHRpb25hbCBjYWxsYmFjayBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIHdoZW4gdGhlIHRlbnNvciBpcyBkaXNwb3NlZC5cbiAgICpcbiAgICogSWYgbm90IHByb3ZpZGVkLCB0aGUgdGVuc29yIHRyZWF0IHRoZSBHUFUgZGF0YSBhcyBleHRlcm5hbCByZXNvdXJjZS5cbiAgICovXG4gIGRpc3Bvc2U/KCk6IHZvaWQ7XG59XG5cbi8qKlxuICogcmVwcmVzZW50IHRoZSBwYXJhbWV0ZXIgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgcGlubmVkIENQVSBidWZmZXJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDcHVQaW5uZWRDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VCBleHRlbmRzIFRlbnNvci5DcHVQaW5uZWREYXRhVHlwZXMgPSBUZW5zb3IuQ3B1UGlubmVkRGF0YVR5cGVzPlxuICBleHRlbmRzIENvbW1vbkNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBsb2NhdGlvbiBvZiB0aGUgZGF0YSB0byBiZSAnY3B1LXBpbm5lZCcuXG4gICAqL1xuICByZWFkb25seSBsb2NhdGlvbjogJ2NwdS1waW5uZWQnO1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgQ1BVIHBpbm5lZCBidWZmZXIgdGhhdCBob2xkcyB0aGUgdGVuc29yIGRhdGEuXG4gICAqL1xuICByZWFkb25seSBkYXRhOiBUZW5zb3IuRGF0YVR5cGVNYXBbVF07XG59XG5cbi8qKlxuICogcmVwcmVzZW50IHRoZSBwYXJhbWV0ZXIgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgV2ViR0wgdGV4dHVyZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRleHR1cmVDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VCBleHRlbmRzIFRlbnNvci5UZXh0dXJlRGF0YVR5cGVzID0gVGVuc29yLlRleHR1cmVEYXRhVHlwZXM+XG4gIGV4dGVuZHMgQ29tbW9uQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+LFxuICAgIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIHRvIGJlICd0ZXh0dXJlJy5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiAndGV4dHVyZSc7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBXZWJHTCB0ZXh0dXJlIHRoYXQgaG9sZHMgdGhlIHRlbnNvciBkYXRhLlxuICAgKi9cbiAgcmVhZG9ubHkgdGV4dHVyZTogVGVuc29yLlRleHR1cmVUeXBlO1xufVxuXG4vKipcbiAqIHJlcHJlc2VudCB0aGUgcGFyYW1ldGVyIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIFdlYkdQVSBidWZmZXJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHcHVCdWZmZXJDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VCBleHRlbmRzIFRlbnNvci5HcHVCdWZmZXJEYXRhVHlwZXMgPSBUZW5zb3IuR3B1QnVmZmVyRGF0YVR5cGVzPlxuICBleHRlbmRzIENvbW1vbkNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPixcbiAgICBHcHVSZXNvdXJjZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBsb2NhdGlvbiBvZiB0aGUgZGF0YSB0byBiZSAnZ3B1LWJ1ZmZlcicuXG4gICAqL1xuICByZWFkb25seSBsb2NhdGlvbjogJ2dwdS1idWZmZXInO1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgV2ViR1BVIGJ1ZmZlciB0aGF0IGhvbGRzIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICovXG4gIHJlYWRvbmx5IGdwdUJ1ZmZlcjogVGVuc29yLkdwdUJ1ZmZlclR5cGU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTUxUZW5zb3JDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VCBleHRlbmRzIFRlbnNvci5NTFRlbnNvckRhdGFUeXBlcyA9IFRlbnNvci5NTFRlbnNvckRhdGFUeXBlcz5cbiAgZXh0ZW5kcyBDb21tb25Db25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4sXG4gICAgR3B1UmVzb3VyY2VDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4ge1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgbG9jYXRpb24gb2YgdGhlIGRhdGEgdG8gYmUgJ21sLXRlbnNvcicuXG4gICAqL1xuICByZWFkb25seSBsb2NhdGlvbjogJ21sLXRlbnNvcic7XG5cbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIFdlYk5OIE1MVGVuc29yIHRoYXQgaG9sZHMgdGhlIHRlbnNvciBkYXRhLlxuICAgKi9cbiAgcmVhZG9ubHkgbWxUZW5zb3I6IFRlbnNvci5NTFRlbnNvclR5cGU7XG59XG5cbi8vICNlbmRyZWdpb25cblxuLy8gdGhlIGZvbGxvd2luZyByZWdpb24gY29udGFpbnMgdHlwZSBkZWZpbml0aW9ucyBvZiBlYWNoIGluZGl2aWR1YWwgb3B0aW9ucy5cbi8vIHRoZSB0ZW5zb3IgZmFjdG9yeSBmdW5jdGlvbnMgdXNlIGEgY29tcG9zaXRpb24gb2YgdGhvc2Ugb3B0aW9ucyBhcyB0aGUgcGFyYW1ldGVyIHR5cGUuXG5cbi8vICNyZWdpb24gT3B0aW9ucyBmaWVsZHNcblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zRm9ybWF0IHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgaW1hZ2UgZm9ybWF0IHJlcHJlc2VudGVkIGluIFJHQkEgY29sb3Igc3BhY2UuXG4gICAqL1xuICBmb3JtYXQ/OiBJbWFnZUZvcm1hdDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zVGVuc29yRm9ybWF0IHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgaW1hZ2UgZm9ybWF0IG9mIHRoZSB0ZW5zb3IuXG4gICAqXG4gICAqIE5PVEU6IHRoaXMgaXMgZGlmZmVyZW50IGZyb20gb3B0aW9uICdmb3JtYXQnLiBXaGlsZSBvcHRpb24gJ2Zvcm1hdCcgcmVwcmVzZW50cyB0aGUgb3JpZ2luYWwgaW1hZ2UsICd0ZW5zb3JGb3JtYXQnXG4gICAqIHJlcHJlc2VudHMgdGhlIHRhcmdldCBmb3JtYXQgb2YgdGhlIHRlbnNvci4gQSB0cmFuc3Bvc2Ugd2lsbCBiZSBwZXJmb3JtZWQgaWYgdGhleSBhcmUgZGlmZmVyZW50LlxuICAgKi9cbiAgdGVuc29yRm9ybWF0PzogSW1hZ2VGb3JtYXQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9uc1RlbnNvckRhdGFUeXBlIHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAqL1xuICBkYXRhVHlwZT86ICdmbG9hdDMyJyB8ICd1aW50OCc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9uc1RlbnNvckxheW91dCB7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgdGhlIHRlbnNvciBsYXlvdXQgd2hlbiByZXByZXNlbnRpbmcgZGF0YSBvZiBvbmUgb3IgbW9yZSBpbWFnZShzKS5cbiAgICovXG4gIHRlbnNvckxheW91dD86IEltYWdlVGVuc29yTGF5b3V0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnNEaW1lbnNpb25zIHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgaW1hZ2UgaGVpZ2h0IGluIHBpeGVsXG4gICAqL1xuICBoZWlnaHQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgdGhlIGltYWdlIHdpZHRoIGluIHBpeGVsXG4gICAqL1xuICB3aWR0aD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25SZXNpemVkRGltZW5zaW9ucyB7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgdGhlIHJlc2l6ZWQgaGVpZ2h0LiBJZiBvbWl0dGVkLCBvcmlnaW5hbCBoZWlnaHQgd2lsbCBiZSB1c2VkLlxuICAgKi9cbiAgcmVzaXplZEhlaWdodD86IG51bWJlcjtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyByZXNpemVkIHdpZHRoIC0gY2FuIGJlIGFjY2Vzc2VkIHZpYSB0ZW5zb3IgZGltZW5zaW9ucyBhcyB3ZWxsXG4gICAqL1xuICByZXNpemVkV2lkdGg/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyBub3JtYWxpemF0aW9uIHBhcmFtZXRlcnMgd2hlbiBwcmVwcm9jZXNzaW5nIHRoZSBpbWFnZSBhcyBtb2RlbCBpbnB1dC5cbiAgICpcbiAgICogRGF0YSBlbGVtZW50IGFyZSByYW5nZWQgZnJvbSAwIHRvIDI1NS5cbiAgICovXG4gIG5vcm0/OiB7XG4gICAgLyoqXG4gICAgICogVGhlICdiaWFzJyB2YWx1ZSBmb3IgaW1hZ2Ugbm9ybWFsaXphdGlvbi5cbiAgICAgKiAtIElmIG9taXR0ZWQsIHVzZSBkZWZhdWx0IHZhbHVlIDAuXG4gICAgICogLSBJZiBpdCdzIGEgc2luZ2xlIG51bWJlciwgYXBwbHkgdG8gZWFjaCBjaGFubmVsXG4gICAgICogLSBJZiBpdCdzIGFuIGFycmF5IG9mIDMgb3IgNCBudW1iZXJzLCBhcHBseSBlbGVtZW50LXdpc2UuIE51bWJlciBvZiBlbGVtZW50cyBuZWVkIHRvIG1hdGNoIHRoZSBudW1iZXIgb2YgY2hhbm5lbHNcbiAgICAgKiBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgaW1hZ2UgZm9ybWF0XG4gICAgICovXG4gICAgYmlhcz86IG51bWJlciB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgIC8qKlxuICAgICAqIFRoZSAnbWVhbicgdmFsdWUgZm9yIGltYWdlIG5vcm1hbGl6YXRpb24uXG4gICAgICogLSBJZiBvbWl0dGVkLCB1c2UgZGVmYXVsdCB2YWx1ZSAyNTUuXG4gICAgICogLSBJZiBpdCdzIGEgc2luZ2xlIG51bWJlciwgYXBwbHkgdG8gZWFjaCBjaGFubmVsXG4gICAgICogLSBJZiBpdCdzIGFuIGFycmF5IG9mIDMgb3IgNCBudW1iZXJzLCBhcHBseSBlbGVtZW50LXdpc2UuIE51bWJlciBvZiBlbGVtZW50cyBuZWVkIHRvIG1hdGNoIHRoZSBudW1iZXIgb2YgY2hhbm5lbHNcbiAgICAgKiBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgaW1hZ2UgZm9ybWF0XG4gICAgICovXG4gICAgbWVhbj86IG51bWJlciB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICB9O1xufVxuXG4vLyAjZW5kcmVnaW9uXG5cbi8vICNyZWdpb24gT3B0aW9ucyBjb21wb3NpdGlvblxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZyb21JbWFnZURhdGFPcHRpb25zXG4gIGV4dGVuZHMgT3B0aW9uUmVzaXplZERpbWVuc2lvbnMsXG4gICAgT3B0aW9uc1RlbnNvckZvcm1hdCxcbiAgICBPcHRpb25zVGVuc29yTGF5b3V0LFxuICAgIE9wdGlvbnNUZW5zb3JEYXRhVHlwZSxcbiAgICBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMge31cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGcm9tSW1hZ2VFbGVtZW50T3B0aW9uc1xuICBleHRlbmRzIE9wdGlvblJlc2l6ZWREaW1lbnNpb25zLFxuICAgIE9wdGlvbnNUZW5zb3JGb3JtYXQsXG4gICAgT3B0aW9uc1RlbnNvckxheW91dCxcbiAgICBPcHRpb25zVGVuc29yRGF0YVR5cGUsXG4gICAgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbVVybE9wdGlvbnNcbiAgZXh0ZW5kcyBPcHRpb25zRGltZW5zaW9ucyxcbiAgICBPcHRpb25SZXNpemVkRGltZW5zaW9ucyxcbiAgICBPcHRpb25zVGVuc29yRm9ybWF0LFxuICAgIE9wdGlvbnNUZW5zb3JMYXlvdXQsXG4gICAgT3B0aW9uc1RlbnNvckRhdGFUeXBlLFxuICAgIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZyb21JbWFnZUJpdG1hcE9wdGlvbnNcbiAgZXh0ZW5kcyBPcHRpb25SZXNpemVkRGltZW5zaW9ucyxcbiAgICBPcHRpb25zVGVuc29yRm9ybWF0LFxuICAgIE9wdGlvbnNUZW5zb3JMYXlvdXQsXG4gICAgT3B0aW9uc1RlbnNvckRhdGFUeXBlLFxuICAgIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZyb21UZXh0dXJlT3B0aW9uczxUIGV4dGVuZHMgVGVuc29yLlRleHR1cmVEYXRhVHlwZXM+XG4gIGV4dGVuZHMgUmVxdWlyZWQ8T3B0aW9uc0RpbWVuc2lvbnM+LFxuICAgIE9wdGlvbnNGb3JtYXQsXG4gICAgR3B1UmVzb3VyY2VDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4gLyogVE9ETzogYWRkIG1vcmUgKi8ge31cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGcm9tR3B1QnVmZmVyT3B0aW9uczxUIGV4dGVuZHMgVGVuc29yLkdwdUJ1ZmZlckRhdGFUeXBlcz5cbiAgZXh0ZW5kcyBQaWNrPFRlbnNvciwgJ2RpbXMnPixcbiAgICBHcHVSZXNvdXJjZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiB7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLlxuICAgKi9cbiAgZGF0YVR5cGU/OiBUO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZyb21NTFRlbnNvck9wdGlvbnM8VCBleHRlbmRzIFRlbnNvci5NTFRlbnNvckRhdGFUeXBlcz5cbiAgZXh0ZW5kcyBQaWNrPFRlbnNvciwgJ2RpbXMnPixcbiAgICBHcHVSZXNvdXJjZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiB7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLlxuICAgKi9cbiAgZGF0YVR5cGU/OiBUO1xufVxuXG4vLyAjZW5kcmVnaW9uXG5cbi8qKlxuICogdHlwZSBUZW5zb3JGYWN0b3J5IGRlZmluZXMgdGhlIGZhY3RvcnkgZnVuY3Rpb25zIG9mICdUZW5zb3InIHRvIGNyZWF0ZSB0ZW5zb3IgaW5zdGFuY2VzIGZyb20gZXhpc3RpbmcgZGF0YSBvclxuICogcmVzb3VyY2VzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZhY3Rvcnkge1xuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYW4gSW1hZ2VEYXRhIG9iamVjdFxuICAgKlxuICAgKiBAcGFyYW0gaW1hZ2VEYXRhIC0gdGhlIEltYWdlRGF0YSBvYmplY3QgdG8gY3JlYXRlIHRlbnNvciBmcm9tXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBJbWFnZURhdGEuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYHRlbnNvckZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogLSBgZGF0YVR5cGVgOiBgJ2Zsb2F0MzInYFxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21JbWFnZShcbiAgICBpbWFnZURhdGE6IEltYWdlRGF0YSxcbiAgICBvcHRpb25zPzogVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnMsXG4gICk6IFByb21pc2U8VHlwZWRUZW5zb3I8J2Zsb2F0MzInPiB8IFR5cGVkVGVuc29yPCd1aW50OCc+PjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBIVE1MSW1hZ2VFbGVtZW50IG9iamVjdFxuICAgKlxuICAgKiBAcGFyYW0gaW1hZ2VFbGVtZW50IC0gdGhlIEhUTUxJbWFnZUVsZW1lbnQgb2JqZWN0IHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIG9iamVjdCByZXByZXNlbnRpbmcgb3B0aW9ucyBmb3IgY3JlYXRpbmcgdGVuc29yIGZyb20gSFRNTEltYWdlRWxlbWVudC5cbiAgICpcbiAgICogVGhlIGZvbGxvd2luZyBkZWZhdWx0IHNldHRpbmdzIHdpbGwgYmUgYXBwbGllZDpcbiAgICogLSBgdGVuc29yRm9ybWF0YDogYCdSR0InYFxuICAgKiAtIGB0ZW5zb3JMYXlvdXRgOiBgJ05DSFcnYFxuICAgKiAtIGBkYXRhVHlwZWA6IGAnZmxvYXQzMidgXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgdGVuc29yIG9iamVjdFxuICAgKi9cbiAgZnJvbUltYWdlKFxuICAgIGltYWdlRWxlbWVudDogSFRNTEltYWdlRWxlbWVudCxcbiAgICBvcHRpb25zPzogVGVuc29yRnJvbUltYWdlRWxlbWVudE9wdGlvbnMsXG4gICk6IFByb21pc2U8VHlwZWRUZW5zb3I8J2Zsb2F0MzInPiB8IFR5cGVkVGVuc29yPCd1aW50OCc+PjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gVVJMXG4gICAqXG4gICAqIEBwYXJhbSB1cmxTb3VyY2UgLSBhIHN0cmluZyBhcyBhIFVSTCB0byB0aGUgaW1hZ2Ugb3IgYSBkYXRhIFVSTCBjb250YWluaW5nIHRoZSBpbWFnZSBkYXRhLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIG9iamVjdCByZXByZXNlbnRpbmcgb3B0aW9ucyBmb3IgY3JlYXRpbmcgdGVuc29yIGZyb20gVVJMLlxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGRlZmF1bHQgc2V0dGluZ3Mgd2lsbCBiZSBhcHBsaWVkOlxuICAgKiAtIGB0ZW5zb3JGb3JtYXRgOiBgJ1JHQidgXG4gICAqIC0gYHRlbnNvckxheW91dGA6IGAnTkNIVydgXG4gICAqIC0gYGRhdGFUeXBlYDogYCdmbG9hdDMyJ2BcbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tSW1hZ2UodXJsU291cmNlOiBzdHJpbmcsIG9wdGlvbnM/OiBUZW5zb3JGcm9tVXJsT3B0aW9ucyk6IFByb21pc2U8VHlwZWRUZW5zb3I8J2Zsb2F0MzInPiB8IFR5cGVkVGVuc29yPCd1aW50OCc+PjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYW4gSW1hZ2VCaXRtYXAgb2JqZWN0XG4gICAqXG4gICAqIEBwYXJhbSBiaXRtYXAgLSB0aGUgSW1hZ2VCaXRtYXAgb2JqZWN0IHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIG9iamVjdCByZXByZXNlbnRpbmcgb3B0aW9ucyBmb3IgY3JlYXRpbmcgdGVuc29yIGZyb20gVVJMLlxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGRlZmF1bHQgc2V0dGluZ3Mgd2lsbCBiZSBhcHBsaWVkOlxuICAgKiAtIGB0ZW5zb3JGb3JtYXRgOiBgJ1JHQidgXG4gICAqIC0gYHRlbnNvckxheW91dGA6IGAnTkNIVydgXG4gICAqIC0gYGRhdGFUeXBlYDogYCdmbG9hdDMyJ2BcbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tSW1hZ2UoXG4gICAgYml0bWFwOiBJbWFnZUJpdG1hcCxcbiAgICBvcHRpb25zOiBUZW5zb3JGcm9tSW1hZ2VCaXRtYXBPcHRpb25zLFxuICApOiBQcm9taXNlPFR5cGVkVGVuc29yPCdmbG9hdDMyJz4gfCBUeXBlZFRlbnNvcjwndWludDgnPj47XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhIHRlbnNvciBmcm9tIGEgV2ViR0wgdGV4dHVyZVxuICAgKlxuICAgKiBAcGFyYW0gdGV4dHVyZSAtIHRoZSBXZWJHTFRleHR1cmUgb2JqZWN0IHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIG9iamVjdCByZXByZXNlbnRpbmcgb3B0aW9ucyBmb3IgY3JlYXRpbmcgdGVuc29yIGZyb20gV2ViR0wgdGV4dHVyZS5cbiAgICpcbiAgICogVGhlIG9wdGlvbnMgaW5jbHVkZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAgICogLSBgd2lkdGhgOiB0aGUgd2lkdGggb2YgdGhlIHRleHR1cmUuIFJlcXVpcmVkLlxuICAgKiAtIGBoZWlnaHRgOiB0aGUgaGVpZ2h0IG9mIHRoZSB0ZXh0dXJlLiBSZXF1aXJlZC5cbiAgICogLSBgZm9ybWF0YDogdGhlIGZvcm1hdCBvZiB0aGUgdGV4dHVyZS4gSWYgb21pdHRlZCwgYXNzdW1lICdSR0JBJy5cbiAgICogLSBgZG93bmxvYWRgOiBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBkb3dubG9hZCB0aGUgdGVuc29yIGRhdGEgZnJvbSBHUFUgdG8gQ1BVLiBJZiBvbWl0dGVkLCB0aGUgR1BVIGRhdGFcbiAgICogd2lsbCBub3QgYmUgYWJsZSB0byBkb3dubG9hZC4gVXN1YWxseSwgdGhpcyBpcyBwcm92aWRlZCBieSBhIEdQVSBiYWNrZW5kIGZvciB0aGUgaW5mZXJlbmNlIG91dHB1dHMuIFVzZXJzIGRvbid0XG4gICAqIG5lZWQgdG8gcHJvdmlkZSB0aGlzIGZ1bmN0aW9uLlxuICAgKiAtIGBkaXNwb3NlYDogYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZGlzcG9zZSB0aGUgdGVuc29yIGRhdGEgb24gR1BVLiBJZiBvbWl0dGVkLCB0aGUgR1BVIGRhdGEgd2lsbCBub3QgYmUgZGlzcG9zZWQuXG4gICAqIFVzdWFsbHksIHRoaXMgaXMgcHJvdmlkZWQgYnkgYSBHUFUgYmFja2VuZCBmb3IgdGhlIGluZmVyZW5jZSBvdXRwdXRzLiBVc2VycyBkb24ndCBuZWVkIHRvIHByb3ZpZGUgdGhpcyBmdW5jdGlvbi5cbiAgICpcbiAgICogQHJldHVybnMgYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tVGV4dHVyZTxUIGV4dGVuZHMgVGVuc29yLlRleHR1cmVEYXRhVHlwZXMgPSAnZmxvYXQzMic+KFxuICAgIHRleHR1cmU6IFRlbnNvci5UZXh0dXJlVHlwZSxcbiAgICBvcHRpb25zOiBUZW5zb3JGcm9tVGV4dHVyZU9wdGlvbnM8VD4sXG4gICk6IFR5cGVkVGVuc29yPCdmbG9hdDMyJz47XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhIHRlbnNvciBmcm9tIGEgV2ViR1BVIGJ1ZmZlclxuICAgKlxuICAgKiBAcGFyYW0gYnVmZmVyIC0gdGhlIEdQVUJ1ZmZlciBvYmplY3QgdG8gY3JlYXRlIHRlbnNvciBmcm9tXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBXZWJHUFUgYnVmZmVyLlxuICAgKlxuICAgKiBUaGUgb3B0aW9ucyBpbmNsdWRlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICAgKiAtIGBkYXRhVHlwZWA6IHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYXNzdW1lICdmbG9hdDMyJy5cbiAgICogLSBgZGltc2A6IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gUmVxdWlyZWQuXG4gICAqIC0gYGRvd25sb2FkYDogYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZG93bmxvYWQgdGhlIHRlbnNvciBkYXRhIGZyb20gR1BVIHRvIENQVS4gSWYgb21pdHRlZCwgdGhlIEdQVSBkYXRhXG4gICAqIHdpbGwgbm90IGJlIGFibGUgdG8gZG93bmxvYWQuIFVzdWFsbHksIHRoaXMgaXMgcHJvdmlkZWQgYnkgYSBHUFUgYmFja2VuZCBmb3IgdGhlIGluZmVyZW5jZSBvdXRwdXRzLiBVc2VycyBkb24ndFxuICAgKiBuZWVkIHRvIHByb3ZpZGUgdGhpcyBmdW5jdGlvbi5cbiAgICogLSBgZGlzcG9zZWA6IGFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGRpc3Bvc2UgdGhlIHRlbnNvciBkYXRhIG9uIEdQVS4gSWYgb21pdHRlZCwgdGhlIEdQVSBkYXRhIHdpbGwgbm90IGJlIGRpc3Bvc2VkLlxuICAgKiBVc3VhbGx5LCB0aGlzIGlzIHByb3ZpZGVkIGJ5IGEgR1BVIGJhY2tlbmQgZm9yIHRoZSBpbmZlcmVuY2Ugb3V0cHV0cy4gVXNlcnMgZG9uJ3QgbmVlZCB0byBwcm92aWRlIHRoaXMgZnVuY3Rpb24uXG4gICAqXG4gICAqIEByZXR1cm5zIGEgdGVuc29yIG9iamVjdFxuICAgKi9cbiAgZnJvbUdwdUJ1ZmZlcjxUIGV4dGVuZHMgVGVuc29yLkdwdUJ1ZmZlckRhdGFUeXBlcz4oXG4gICAgYnVmZmVyOiBUZW5zb3IuR3B1QnVmZmVyVHlwZSxcbiAgICBvcHRpb25zOiBUZW5zb3JGcm9tR3B1QnVmZmVyT3B0aW9uczxUPixcbiAgKTogVHlwZWRUZW5zb3I8VD47XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhIHRlbnNvciBmcm9tIGEgV2ViTk4gTUxUZW5zb3JcbiAgICpcbiAgICogQHBhcmFtIHRlbnNvciAtIHRoZSBNTFRlbnNvciBvYmplY3QgdG8gY3JlYXRlIHRlbnNvciBmcm9tXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBhIFdlYk5OIE1MVGVuc29yLlxuICAgKlxuICAgKiBUaGUgb3B0aW9ucyBpbmNsdWRlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICAgKiAtIGBkYXRhVHlwZWA6IHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYXNzdW1lICdmbG9hdDMyJy5cbiAgICogLSBgZGltc2A6IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gUmVxdWlyZWQuXG4gICAqIC0gYGRvd25sb2FkYDogYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZG93bmxvYWQgdGhlIHRlbnNvciBkYXRhIGZyb20gdGhlIE1MVGVuc29yIHRvIENQVS4gSWYgb21pdHRlZCwgdGhlIE1MVGVuc29yXG4gICAqIGRhdGEgd2lsbCBub3QgYmUgYWJsZSB0byBkb3dubG9hZC4gVXN1YWxseSwgdGhpcyBpcyBwcm92aWRlZCBieSB0aGUgV2ViTk4gYmFja2VuZCBmb3IgdGhlIGluZmVyZW5jZSBvdXRwdXRzLlxuICAgKiBVc2VycyBkb24ndCBuZWVkIHRvIHByb3ZpZGUgdGhpcyBmdW5jdGlvbi5cbiAgICogLSBgZGlzcG9zZWA6IGFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGRpc3Bvc2UgdGhlIHRlbnNvciBkYXRhIG9uIHRoZSBXZWJOTiBNTFRlbnNvci4gSWYgb21pdHRlZCwgdGhlIE1MVGVuc29yIHdpbGxcbiAgICogbm90IGJlIGRpc3Bvc2VkLiBVc3VhbGx5LCB0aGlzIGlzIHByb3ZpZGVkIGJ5IHRoZSBXZWJOTiBiYWNrZW5kIGZvciB0aGUgaW5mZXJlbmNlIG91dHB1dHMuIFVzZXJzIGRvbid0IG5lZWQgdG9cbiAgICogcHJvdmlkZSB0aGlzIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21NTFRlbnNvcjxUIGV4dGVuZHMgVGVuc29yLk1MVGVuc29yRGF0YVR5cGVzPihcbiAgICB0ZW5zb3I6IFRlbnNvci5NTFRlbnNvclR5cGUsXG4gICAgb3B0aW9uczogVGVuc29yRnJvbU1MVGVuc29yT3B0aW9uczxUPixcbiAgKTogVHlwZWRUZW5zb3I8VD47XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhIHRlbnNvciBmcm9tIGEgcHJlLWFsbG9jYXRlZCBidWZmZXIuIFRoZSBidWZmZXIgd2lsbCBiZSB1c2VkIGFzIGEgcGlubmVkIGJ1ZmZlci5cbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSB0aGUgdGVuc29yIGVsZW1lbnQgdHlwZS5cbiAgICogQHBhcmFtIGJ1ZmZlciAtIGEgVHlwZWRBcnJheSBjb3JyZXNwb25kaW5nIHRvIHRoZSB0eXBlLlxuICAgKiBAcGFyYW0gZGltcyAtIHNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICpcbiAgICogQHJldHVybnMgYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tUGlubmVkQnVmZmVyPFQgZXh0ZW5kcyBFeGNsdWRlPFRlbnNvci5UeXBlLCAnc3RyaW5nJz4+KFxuICAgIHR5cGU6IFQsXG4gICAgYnVmZmVyOiBUZW5zb3IuRGF0YVR5cGVNYXBbVF0sXG4gICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuICApOiBUeXBlZFRlbnNvcjxUPjtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLyoqXG4gKiBBIHN0cmluZyB0aGF0IHJlcHJlc2VudHMgYSBmaWxlJ3MgVVJMIG9yIHBhdGguXG4gKlxuICogUGF0aCBpcyB2YWlsYWJsZSBvbmx5IGluIG9ubnhydW50aW1lLW5vZGUgb3Igb25ueHJ1bnRpbWUtd2ViIHJ1bm5pbmcgaW4gTm9kZS5qcy5cbiAqL1xuZXhwb3J0IHR5cGUgRmlsZVVybE9yUGF0aCA9IHN0cmluZztcblxuLyoqXG4gKiBBIEJsb2Igb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhIGZpbGUuXG4gKi9cbmV4cG9ydCB0eXBlIEZpbGVCbG9iID0gQmxvYjtcblxuLyoqXG4gKiBBIFVpbnQ4QXJyYXksIEFycmF5QnVmZmVyIG9yIFNoYXJlZEFycmF5QnVmZmVyIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgYSBmaWxlIGNvbnRlbnQuXG4gKlxuICogV2hlbiBpdCBpcyBhbiBBcnJheUJ1ZmZlciBvciBTaGFyZWRBcnJheUJ1ZmZlciwgdGhlIHdob2xlIGJ1ZmZlciBpcyBhc3N1bWVkIHRvIGJlIHRoZSBmaWxlIGNvbnRlbnQuXG4gKi9cbmV4cG9ydCB0eXBlIEZpbGVEYXRhID0gVWludDhBcnJheSB8IEFycmF5QnVmZmVyTGlrZTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgZmlsZSB0aGF0IGNhbiBiZSBsb2FkZWQgYnkgdGhlIE9OTlggUnVudGltZSBKYXZhU2NyaXB0IEFQSS5cbiAqL1xuZXhwb3J0IHR5cGUgRmlsZVR5cGUgPSBGaWxlVXJsT3JQYXRoIHwgRmlsZUJsb2IgfCBGaWxlRGF0YTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIGV4dGVybmFsIGRhdGEgZmlsZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFeHRlcm5hbERhdGFGaWxlRGVzY3JpcHRpb24ge1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgZXh0ZXJuYWwgZGF0YSBmaWxlLlxuICAgKi9cbiAgZGF0YTogRmlsZVR5cGU7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBmaWxlIHBhdGguXG4gICAqL1xuICBwYXRoOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhbiBleHRlcm5hbCBkYXRhIGZpbGUuXG4gKlxuICogV2hlbiB1c2luZyBhIHN0cmluZywgaXQgc2hvdWxkIGJlIGEgZmlsZSBVUkwgb3IgcGF0aCB0aGF0IGluIHRoZSBzYW1lIGRpcmVjdG9yeSBhcyB0aGUgbW9kZWwgZmlsZS5cbiAqL1xuZXhwb3J0IHR5cGUgRXh0ZXJuYWxEYXRhRmlsZVR5cGUgPSBFeHRlcm5hbERhdGFGaWxlRGVzY3JpcHRpb24gfCBGaWxlVXJsT3JQYXRoO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIG1vZGVsIGxvYWRpbmcuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT25ueE1vZGVsT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5aW5nIGEgbGlzdCBvZiBmaWxlcyB0aGF0IHJlcHJlc2VudHMgdGhlIGV4dGVybmFsIGRhdGEuXG4gICAqL1xuICBleHRlcm5hbERhdGE/OiByZWFkb25seSBFeHRlcm5hbERhdGFGaWxlVHlwZVtdO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvci5qcyc7XG5cbmV4cG9ydCB0eXBlIE5vblRlbnNvclR5cGUgPSBuZXZlcjtcblxuLyoqXG4gKiBUeXBlIE9ubnhWYWx1ZSBSZXByZXNlbnRzIGJvdGggdGVuc29ycyBhbmQgbm9uLXRlbnNvcnMgdmFsdWUgZm9yIG1vZGVsJ3MgaW5wdXRzL291dHB1dHMuXG4gKlxuICogTk9URTogY3VycmVudGx5IG5vdCBzdXBwb3J0IG5vbi10ZW5zb3JcbiAqL1xuZXhwb3J0IHR5cGUgT25ueFZhbHVlID0gVGVuc29yIHwgTm9uVGVuc29yVHlwZTtcblxuLyoqXG4gKiBUeXBlIE9ubnhWYWx1ZURhdGFMb2NhdGlvbiByZXByZXNlbnRzIHRoZSBsb2NhdGlvbiBvZiB0aGUgZGF0YSBvZiBhbiBPbm54VmFsdWUuXG4gKi9cbmV4cG9ydCB0eXBlIE9ubnhWYWx1ZURhdGFMb2NhdGlvbiA9IFRlbnNvci5EYXRhTG9jYXRpb247XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8qKlxuICogIyBPTk5YIFJ1bnRpbWUgSmF2YVNjcmlwdCBBUElcbiAqXG4gKiBPTk5YIFJ1bnRpbWUgSmF2YVNjcmlwdCBBUEkgaXMgYSB1bmlmaWVkIEFQSSBmb3IgYWxsIEphdmFTY3JpcHQgdXNhZ2VzLCBpbmNsdWRpbmcgdGhlIGZvbGxvd2luZyBOUE0gcGFja2FnZXM6XG4gKlxuICogLSBbb25ueHJ1bnRpbWUtbm9kZV0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2Uvb25ueHJ1bnRpbWUtbm9kZSlcbiAqIC0gW29ubnhydW50aW1lLXdlYl0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2Uvb25ueHJ1bnRpbWUtd2ViKVxuICogLSBbb25ueHJ1bnRpbWUtcmVhY3QtbmF0aXZlXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9vbm54cnVudGltZS1yZWFjdC1uYXRpdmUpXG4gKlxuICogU2VlIGFsc286XG4gKiAtIFtHZXQgU3RhcnRlZF0oaHR0cHM6Ly9vbm54cnVudGltZS5haS9kb2NzL2dldC1zdGFydGVkL3dpdGgtamF2YXNjcmlwdC8pXG4gKiAtIFtJbmZlcmVuY2UgZXhhbXBsZXNdKGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvb25ueHJ1bnRpbWUtaW5mZXJlbmNlLWV4YW1wbGVzL3RyZWUvbWFpbi9qcylcbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2JhY2tlbmQuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9lbnYuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9pbmZlcmVuY2Utc2Vzc2lvbi5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3RlbnNvci5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3RlbnNvci1jb252ZXJzaW9uLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdGVuc29yLWZhY3RvcnkuanMnO1xuZXhwb3J0ICogZnJvbSAnLi90cmFjZS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL29ubngtbW9kZWwuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9vbm54LXZhbHVlLmpzJztcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRW52IH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHsgV2ViR0xDb250ZXh0IH0gZnJvbSAnLi9iYWNrZW5kcy93ZWJnbC93ZWJnbC1jb250ZXh0JztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIExvZ2dlciB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgU2V2ZXJpdHlUeXBlTWFwIHtcbiAgICB2ZXJib3NlOiAndic7XG4gICAgaW5mbzogJ2knO1xuICAgIHdhcm5pbmc6ICd3JztcbiAgICBlcnJvcjogJ2UnO1xuICAgIGZhdGFsOiAnZic7XG4gIH1cblxuICBleHBvcnQgdHlwZSBTZXZlcml0eSA9IGtleW9mIFNldmVyaXR5VHlwZU1hcDtcblxuICBleHBvcnQgdHlwZSBQcm92aWRlciA9ICdub25lJyB8ICdjb25zb2xlJztcblxuICAvKipcbiAgICogTG9nZ2luZyBjb25maWcgdGhhdCB1c2VkIHRvIGNvbnRyb2wgdGhlIGJlaGF2aW9yIG9mIGxvZ2dlclxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBDb25maWcge1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgdGhlIGxvZ2dpbmcgcHJvdmlkZXIuICdjb25zb2xlJyBieSBkZWZhdWx0XG4gICAgICovXG4gICAgcHJvdmlkZXI/OiBQcm92aWRlcjtcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHRoZSBtaW5pbWFsIGxvZ2dlciBzZXZlcml0eS4gJ3dhcm5pbmcnIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBtaW5pbWFsU2V2ZXJpdHk/OiBMb2dnZXIuU2V2ZXJpdHk7XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0byBvdXRwdXQgZGF0ZSB0aW1lIGluIGxvZy4gdHJ1ZSBieSBkZWZhdWx0XG4gICAgICovXG4gICAgbG9nRGF0ZVRpbWU/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdG8gb3V0cHV0IHNvdXJjZSBpbmZvcm1hdGlvbiAoTm90IHlldCBzdXBwb3J0ZWQpLiBmYWxzZSBieSBkZWZhdWx0XG4gICAgICovXG4gICAgbG9nU291cmNlTG9jYXRpb24/OiBib29sZWFuO1xuICB9XG5cbiAgZXhwb3J0IGludGVyZmFjZSBDYXRlZ29yaXplZExvZ2dlciB7XG4gICAgdmVyYm9zZShjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICAgIGluZm8oY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgICB3YXJuaW5nKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gICAgZXJyb3IoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgICBmYXRhbChjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB9XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlXG5leHBvcnQgaW50ZXJmYWNlIExvZ2dlciB7XG4gIChjYXRlZ29yeTogc3RyaW5nKTogTG9nZ2VyLkNhdGVnb3JpemVkTG9nZ2VyO1xuXG4gIHZlcmJvc2UoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgdmVyYm9zZShjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBpbmZvKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGluZm8oY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgd2FybmluZyhjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB3YXJuaW5nKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGVycm9yKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGVycm9yKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGZhdGFsKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGZhdGFsKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFJlc2V0IHRoZSBsb2dnZXIgY29uZmlndXJhdGlvbi5cbiAgICogQHBhcmFtIGNvbmZpZyBzcGVjaWZ5IGFuIG9wdGlvbmFsIGRlZmF1bHQgY29uZmlnXG4gICAqL1xuICByZXNldChjb25maWc/OiBMb2dnZXIuQ29uZmlnKTogdm9pZDtcbiAgLyoqXG4gICAqIFNldCB0aGUgbG9nZ2VyJ3MgYmVoYXZpb3Igb24gdGhlIGdpdmVuIGNhdGVnb3J5XG4gICAqIEBwYXJhbSBjYXRlZ29yeSBzcGVjaWZ5IGEgY2F0ZWdvcnkgc3RyaW5nLiBJZiAnKicgaXMgc3BlY2lmaWVkLCBhbGwgcHJldmlvdXMgY29uZmlndXJhdGlvbiB3aWxsIGJlIG92ZXJ3cml0dGVuLiBJZlxuICAgKiAnJyBpcyBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IGJlaGF2aW9yIHdpbGwgYmUgdXBkYXRlZC5cbiAgICogQHBhcmFtIGNvbmZpZyB0aGUgY29uZmlnIG9iamVjdCB0byBpbmRpY2F0ZSB0aGUgbG9nZ2VyJ3MgYmVoYXZpb3JcbiAgICovXG4gIHNldChjYXRlZ29yeTogc3RyaW5nLCBjb25maWc6IExvZ2dlci5Db25maWcpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGxvZ2dlcidzIGJlaGF2aW9yIGZyb20gb3J0LWNvbW1vbiBlbnZcbiAgICogQHBhcmFtIGVudiB0aGUgZW52IHVzZWQgdG8gc2V0IGxvZ2dlci4gQ3VycmVudGx5IG9ubHkgc2V0dGluZyBsb2dsZXZlbCBpcyBzdXBwb3J0ZWQgdGhyb3VnaCBFbnYuXG4gICAqL1xuICBzZXRXaXRoRW52KGVudjogRW52KTogdm9pZDtcbn1cblxuaW50ZXJmYWNlIExvZ2dlclByb3ZpZGVyIHtcbiAgbG9nKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIGNvbnRlbnQ6IHN0cmluZywgY2F0ZWdvcnk/OiBzdHJpbmcpOiB2b2lkO1xufVxuY2xhc3MgTm9PcExvZ2dlclByb3ZpZGVyIGltcGxlbWVudHMgTG9nZ2VyUHJvdmlkZXIge1xuICBsb2coX3NldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIF9jb250ZW50OiBzdHJpbmcsIF9jYXRlZ29yeT86IHN0cmluZykge1xuICAgIC8vIGRvIG5vdGhpbmdcbiAgfVxufVxuY2xhc3MgQ29uc29sZUxvZ2dlclByb3ZpZGVyIGltcGxlbWVudHMgTG9nZ2VyUHJvdmlkZXIge1xuICBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgY29udGVudDogc3RyaW5nLCBjYXRlZ29yeT86IHN0cmluZykge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgY29uc29sZS5sb2coYCR7dGhpcy5jb2xvcihzZXZlcml0eSl9ICR7Y2F0ZWdvcnkgPyAnXFx4MWJbMzVtJyArIGNhdGVnb3J5ICsgJ1xceDFiWzBtICcgOiAnJ30ke2NvbnRlbnR9YCk7XG4gIH1cblxuICBwcml2YXRlIGNvbG9yKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHkpIHtcbiAgICBzd2l0Y2ggKHNldmVyaXR5KSB7XG4gICAgICBjYXNlICd2ZXJib3NlJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlszNDs0MG12XFx4MWJbMG0nO1xuICAgICAgY2FzZSAnaW5mbyc6XG4gICAgICAgIHJldHVybiAnXFx4MWJbMzJtaVxceDFiWzBtJztcbiAgICAgIGNhc2UgJ3dhcm5pbmcnOlxuICAgICAgICByZXR1cm4gJ1xceDFiWzMwOzQzbXdcXHgxYlswbSc7XG4gICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgIHJldHVybiAnXFx4MWJbMzE7NDBtZVxceDFiWzBtJztcbiAgICAgIGNhc2UgJ2ZhdGFsJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlsxMDFtZlxceDFiWzBtJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgc2V2ZXJpdHk6ICR7c2V2ZXJpdHl9YCk7XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IFNFVkVSSVRZX1ZBTFVFID0ge1xuICB2ZXJib3NlOiAxMDAwLFxuICBpbmZvOiAyMDAwLFxuICB3YXJuaW5nOiA0MDAwLFxuICBlcnJvcjogNTAwMCxcbiAgZmF0YWw6IDYwMDAsXG59O1xuXG5jb25zdCBMT0dHRVJfUFJPVklERVJfTUFQOiB7IHJlYWRvbmx5IFtwcm92aWRlcjogc3RyaW5nXTogUmVhZG9ubHk8TG9nZ2VyUHJvdmlkZXI+IH0gPSB7XG4gIFsnbm9uZSddOiBuZXcgTm9PcExvZ2dlclByb3ZpZGVyKCksXG4gIFsnY29uc29sZSddOiBuZXcgQ29uc29sZUxvZ2dlclByb3ZpZGVyKCksXG59O1xuY29uc3QgTE9HR0VSX0RFRkFVTFRfQ09ORklHID0ge1xuICBwcm92aWRlcjogJ2NvbnNvbGUnLFxuICBtaW5pbWFsU2V2ZXJpdHk6ICd3YXJuaW5nJyxcbiAgbG9nRGF0ZVRpbWU6IHRydWUsXG4gIGxvZ1NvdXJjZUxvY2F0aW9uOiBmYWxzZSxcbn07XG5sZXQgTE9HR0VSX0NPTkZJR19NQVA6IHsgW2NhdGVnb3J5OiBzdHJpbmddOiBSZWFkb25seTxSZXF1aXJlZDxMb2dnZXIuQ29uZmlnPj4gfSA9IHtcbiAgWycnXTogTE9HR0VSX0RFRkFVTFRfQ09ORklHIGFzIFJlcXVpcmVkPExvZ2dlci5Db25maWc+LFxufTtcblxuZnVuY3Rpb24gbG9nKGNhdGVnb3J5OiBzdHJpbmcpOiBMb2dnZXIuQ2F0ZWdvcml6ZWRMb2dnZXI7XG5mdW5jdGlvbiBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgY29udGVudDogc3RyaW5nKTogdm9pZDtcbmZ1bmN0aW9uIGxvZyhzZXZlcml0eTogTG9nZ2VyLlNldmVyaXR5LCBjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuZnVuY3Rpb24gbG9nKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIGFyZzE6IHN0cmluZywgYXJnMj86IHN0cmluZyk6IHZvaWQ7XG5mdW5jdGlvbiBsb2coXG4gIGFyZzA6IHN0cmluZyB8IExvZ2dlci5TZXZlcml0eSxcbiAgYXJnMT86IHN0cmluZyxcbiAgYXJnMj86IHN0cmluZyB8IG51bWJlcixcbiAgYXJnMz86IG51bWJlcixcbik6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlciB8IHZvaWQge1xuICBpZiAoYXJnMSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gbG9nKGNhdGVnb3J5OiBzdHJpbmcpOiBMb2dnZXIuQ2F0ZWdvcml6ZWRMb2dnZXI7XG4gICAgcmV0dXJuIGNyZWF0ZUNhdGVnb3JpemVkTG9nZ2VyKGFyZzApO1xuICB9IGVsc2UgaWYgKGFyZzIgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGxvZyhzZXZlcml0eSwgY29udGVudCk7XG4gICAgbG9nSW50ZXJuYWwoYXJnMCBhcyBMb2dnZXIuU2V2ZXJpdHksIGFyZzEsIDEpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcyID09PSAnbnVtYmVyJyAmJiBhcmczID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBsb2coc2V2ZXJpdHksIGNvbnRlbnQsIHN0YWNrKVxuICAgIGxvZ0ludGVybmFsKGFyZzAgYXMgTG9nZ2VyLlNldmVyaXR5LCBhcmcxLCBhcmcyKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiA9PT0gJ3N0cmluZycgJiYgYXJnMyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gbG9nKHNldmVyaXR5LCBjYXRlZ29yeSwgY29udGVudClcbiAgICBsb2dJbnRlcm5hbChhcmcwIGFzIExvZ2dlci5TZXZlcml0eSwgYXJnMiwgMSwgYXJnMSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgPT09ICdzdHJpbmcnICYmIHR5cGVvZiBhcmczID09PSAnbnVtYmVyJykge1xuICAgIC8vIGxvZyhzZXZlcml0eSwgY2F0ZWdvcnksIGNvbnRlbnQsIHN0YWNrKVxuICAgIGxvZ0ludGVybmFsKGFyZzAgYXMgTG9nZ2VyLlNldmVyaXR5LCBhcmcyLCBhcmczLCBhcmcxKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnB1dCBpcyB2YWxpZCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNhdGVnb3JpemVkTG9nZ2VyKGNhdGVnb3J5OiBzdHJpbmcpOiBMb2dnZXIuQ2F0ZWdvcml6ZWRMb2dnZXIge1xuICByZXR1cm4ge1xuICAgIHZlcmJvc2U6IGxvZy52ZXJib3NlLmJpbmQobnVsbCwgY2F0ZWdvcnkpLFxuICAgIGluZm86IGxvZy5pbmZvLmJpbmQobnVsbCwgY2F0ZWdvcnkpLFxuICAgIHdhcm5pbmc6IGxvZy53YXJuaW5nLmJpbmQobnVsbCwgY2F0ZWdvcnkpLFxuICAgIGVycm9yOiBsb2cuZXJyb3IuYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgZmF0YWw6IGxvZy5mYXRhbC5iaW5kKG51bGwsIGNhdGVnb3J5KSxcbiAgfTtcbn1cblxuLy8gTk9URTogYXJndW1lbnQgJ2NhdGVnb3J5JyBpcyBwdXQgdGhlIGxhc3QgcGFyYW1ldGVyIGJlY2F1c2UgdHlwZXNjcmlwdFxuLy8gZG9lc24ndCBhbGxvdyBvcHRpb25hbCBhcmd1bWVudCBwdXQgaW4gZnJvbnQgb2YgcmVxdWlyZWQgYXJndW1lbnQuIFRoaXNcbi8vIG9yZGVyIGlzIGRpZmZlcmVudCBmcm9tIGEgdXN1YWwgbG9nZ2luZyBBUEkuXG5mdW5jdGlvbiBsb2dJbnRlcm5hbChzZXZlcml0eTogTG9nZ2VyLlNldmVyaXR5LCBjb250ZW50OiBzdHJpbmcsIF9zdGFjazogbnVtYmVyLCBjYXRlZ29yeT86IHN0cmluZykge1xuICBjb25zdCBjb25maWcgPSBMT0dHRVJfQ09ORklHX01BUFtjYXRlZ29yeSB8fCAnJ10gfHwgTE9HR0VSX0NPTkZJR19NQVBbJyddO1xuICBpZiAoU0VWRVJJVFlfVkFMVUVbc2V2ZXJpdHldIDwgU0VWRVJJVFlfVkFMVUVbY29uZmlnLm1pbmltYWxTZXZlcml0eV0pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoY29uZmlnLmxvZ0RhdGVUaW1lKSB7XG4gICAgY29udGVudCA9IGAke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKX18JHtjb250ZW50fWA7XG4gIH1cblxuICBpZiAoY29uZmlnLmxvZ1NvdXJjZUxvY2F0aW9uKSB7XG4gICAgLy8gVE9ETzogY2FsY3VsYXRlIHNvdXJjZSBsb2NhdGlvbiBmcm9tICdzdGFjaydcbiAgfVxuXG4gIExPR0dFUl9QUk9WSURFUl9NQVBbY29uZmlnLnByb3ZpZGVyXS5sb2coc2V2ZXJpdHksIGNvbnRlbnQsIGNhdGVnb3J5KTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1uYW1lc3BhY2Vcbm5hbWVzcGFjZSBsb2cge1xuICBleHBvcnQgZnVuY3Rpb24gdmVyYm9zZShjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gdmVyYm9zZShjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gdmVyYm9zZShhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ3ZlcmJvc2UnLCBhcmcwLCBhcmcxKTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gaW5mbyhjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gaW5mbyhjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gaW5mbyhhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ2luZm8nLCBhcmcwLCBhcmcxKTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gd2FybmluZyhjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gd2FybmluZyhjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gd2FybmluZyhhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ3dhcm5pbmcnLCBhcmcwLCBhcmcxKTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gZXJyb3IoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIGVycm9yKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBlcnJvcihhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ2Vycm9yJywgYXJnMCwgYXJnMSk7XG4gIH1cbiAgZXhwb3J0IGZ1bmN0aW9uIGZhdGFsKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBmYXRhbChjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gZmF0YWwoYXJnMDogc3RyaW5nLCBhcmcxPzogc3RyaW5nKSB7XG4gICAgbG9nKCdmYXRhbCcsIGFyZzAsIGFyZzEpO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIHJlc2V0KGNvbmZpZz86IExvZ2dlci5Db25maWcpOiB2b2lkIHtcbiAgICBMT0dHRVJfQ09ORklHX01BUCA9IHt9O1xuICAgIHNldCgnJywgY29uZmlnIHx8IHt9KTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gc2V0KGNhdGVnb3J5OiBzdHJpbmcsIGNvbmZpZzogTG9nZ2VyLkNvbmZpZyk6IHZvaWQge1xuICAgIGlmIChjYXRlZ29yeSA9PT0gJyonKSB7XG4gICAgICByZXNldChjb25maWcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBwcmV2aW91c0NvbmZpZyA9IExPR0dFUl9DT05GSUdfTUFQW2NhdGVnb3J5XSB8fCBMT0dHRVJfREVGQVVMVF9DT05GSUc7XG4gICAgICBMT0dHRVJfQ09ORklHX01BUFtjYXRlZ29yeV0gPSB7XG4gICAgICAgIHByb3ZpZGVyOiBjb25maWcucHJvdmlkZXIgfHwgcHJldmlvdXNDb25maWcucHJvdmlkZXIsXG4gICAgICAgIG1pbmltYWxTZXZlcml0eTogY29uZmlnLm1pbmltYWxTZXZlcml0eSB8fCBwcmV2aW91c0NvbmZpZy5taW5pbWFsU2V2ZXJpdHksXG4gICAgICAgIGxvZ0RhdGVUaW1lOiBjb25maWcubG9nRGF0ZVRpbWUgPT09IHVuZGVmaW5lZCA/IHByZXZpb3VzQ29uZmlnLmxvZ0RhdGVUaW1lIDogY29uZmlnLmxvZ0RhdGVUaW1lLFxuICAgICAgICBsb2dTb3VyY2VMb2NhdGlvbjpcbiAgICAgICAgICBjb25maWcubG9nU291cmNlTG9jYXRpb24gPT09IHVuZGVmaW5lZCA/IHByZXZpb3VzQ29uZmlnLmxvZ1NvdXJjZUxvY2F0aW9uIDogY29uZmlnLmxvZ1NvdXJjZUxvY2F0aW9uLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiB3ZSB3YW50IHRvIHN1cHBvcnQgd2lsZGNhcmQgb3IgcmVnZXg/XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gc2V0V2l0aEVudihlbnY6IEVudik6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZzogTG9nZ2VyLkNvbmZpZyA9IHt9O1xuICAgIGlmIChlbnYubG9nTGV2ZWwpIHtcbiAgICAgIGNvbmZpZy5taW5pbWFsU2V2ZXJpdHkgPSBlbnYubG9nTGV2ZWwgYXMgTG9nZ2VyLlNldmVyaXR5O1xuICAgIH1cbiAgICBzZXQoJycsIGNvbmZpZyk7XG4gIH1cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmUsIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZXhwb3J0IGNvbnN0IExvZ2dlcjogTG9nZ2VyID0gbG9nO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgUHJvZmlsZXIge1xuICBleHBvcnQgaW50ZXJmYWNlIENvbmZpZyB7XG4gICAgbWF4TnVtYmVyRXZlbnRzPzogbnVtYmVyO1xuICAgIGZsdXNoQmF0Y2hTaXplPzogbnVtYmVyO1xuICAgIGZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcbiAgfVxuXG4gIGV4cG9ydCB0eXBlIEV2ZW50Q2F0ZWdvcnkgPSAnc2Vzc2lvbicgfCAnbm9kZScgfCAnb3AnIHwgJ2JhY2tlbmQnO1xuXG4gIGV4cG9ydCBpbnRlcmZhY2UgRXZlbnQge1xuICAgIGVuZCgpOiB2b2lkIHwgUHJvbWlzZTx2b2lkPjtcbiAgfVxufVxuLy8gVE9ET1xuLy8gY2xhc3MgV2ViR0xFdmVudCBpbXBsZW1lbnRzIFByb2ZpbGVyLkV2ZW50IHt9XG5cbmNsYXNzIEV2ZW50IGltcGxlbWVudHMgUHJvZmlsZXIuRXZlbnQge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksXG4gICAgcHVibGljIG5hbWU6IHN0cmluZyxcbiAgICBwdWJsaWMgc3RhcnRUaW1lOiBudW1iZXIsXG4gICAgcHJpdmF0ZSBlbmRDYWxsYmFjazogKGU6IEV2ZW50KSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPixcbiAgICBwdWJsaWMgdGltZXI/OiBXZWJHTFF1ZXJ5LFxuICAgIHB1YmxpYyBjdHg/OiBXZWJHTENvbnRleHQsXG4gICkge31cblxuICBhc3luYyBlbmQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZW5kQ2FsbGJhY2sodGhpcyk7XG4gIH1cblxuICBhc3luYyBjaGVja1RpbWVyKCk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgaWYgKHRoaXMuY3R4ID09PSB1bmRlZmluZWQgfHwgdGhpcy50aW1lciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHdlYmdsIHRpbWVyIGZvdW5kJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3R4LmVuZFRpbWVyKCk7XG4gICAgICByZXR1cm4gdGhpcy5jdHgud2FpdEZvclF1ZXJ5QW5kR2V0VGltZSh0aGlzLnRpbWVyKTtcbiAgICB9XG4gIH1cbn1cblxuY2xhc3MgRXZlbnRSZWNvcmQge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksXG4gICAgcHVibGljIG5hbWU6IHN0cmluZyxcbiAgICBwdWJsaWMgc3RhcnRUaW1lOiBudW1iZXIsXG4gICAgcHVibGljIGVuZFRpbWU6IG51bWJlcixcbiAgKSB7fVxufVxuXG5leHBvcnQgY2xhc3MgUHJvZmlsZXIge1xuICBzdGF0aWMgY3JlYXRlKGNvbmZpZz86IFByb2ZpbGVyLkNvbmZpZyk6IFByb2ZpbGVyIHtcbiAgICBpZiAoY29uZmlnID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBuZXcgdGhpcygpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IHRoaXMoY29uZmlnLm1heE51bWJlckV2ZW50cywgY29uZmlnLmZsdXNoQmF0Y2hTaXplLCBjb25maWcuZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzKTtcbiAgfVxuXG4gIHByaXZhdGUgY29uc3RydWN0b3IobWF4TnVtYmVyRXZlbnRzPzogbnVtYmVyLCBmbHVzaEJhdGNoU2l6ZT86IG51bWJlciwgZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzPzogbnVtYmVyKSB7XG4gICAgdGhpcy5fc3RhcnRlZCA9IGZhbHNlO1xuICAgIHRoaXMuX21heE51bWJlckV2ZW50cyA9IG1heE51bWJlckV2ZW50cyA9PT0gdW5kZWZpbmVkID8gMTAwMDAgOiBtYXhOdW1iZXJFdmVudHM7XG4gICAgdGhpcy5fZmx1c2hCYXRjaFNpemUgPSBmbHVzaEJhdGNoU2l6ZSA9PT0gdW5kZWZpbmVkID8gMTAgOiBmbHVzaEJhdGNoU2l6ZTtcbiAgICB0aGlzLl9mbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHMgPSBmbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHMgPT09IHVuZGVmaW5lZCA/IDUwMDAgOiBmbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHM7XG4gIH1cblxuICAvLyBzdGFydCBwcm9maWxpbmdcbiAgc3RhcnQoKSB7XG4gICAgdGhpcy5fc3RhcnRlZCA9IHRydWU7XG4gICAgdGhpcy5fdGltaW5nRXZlbnRzID0gW107XG4gICAgdGhpcy5fZmx1c2hUaW1lID0gbm93KCk7XG4gICAgdGhpcy5fZmx1c2hQb2ludGVyID0gMDtcbiAgfVxuXG4gIC8vIHN0b3AgcHJvZmlsaW5nXG4gIHN0b3AoKSB7XG4gICAgdGhpcy5fc3RhcnRlZCA9IGZhbHNlO1xuICAgIGZvciAoOyB0aGlzLl9mbHVzaFBvaW50ZXIgPCB0aGlzLl90aW1pbmdFdmVudHMubGVuZ3RoOyB0aGlzLl9mbHVzaFBvaW50ZXIrKykge1xuICAgICAgdGhpcy5sb2dPbmVFdmVudCh0aGlzLl90aW1pbmdFdmVudHNbdGhpcy5fZmx1c2hQb2ludGVyXSk7XG4gICAgfVxuICB9XG5cbiAgLy8gY3JlYXRlIGFuIGV2ZW50IHNjb3BlIGZvciB0aGUgc3BlY2lmaWMgZnVuY3Rpb25cbiAgZXZlbnQ8VD4oY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksIG5hbWU6IHN0cmluZywgZnVuYzogKCkgPT4gVCwgY3R4PzogV2ViR0xDb250ZXh0KTogVDtcbiAgZXZlbnQ8VD4oY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksIG5hbWU6IHN0cmluZywgZnVuYzogKCkgPT4gUHJvbWlzZTxUPiwgY3R4PzogV2ViR0xDb250ZXh0KTogUHJvbWlzZTxUPjtcblxuICBldmVudDxUPihcbiAgICBjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgZnVuYzogKCkgPT4gVCB8IFByb21pc2U8VD4sXG4gICAgY3R4PzogV2ViR0xDb250ZXh0LFxuICApOiBUIHwgUHJvbWlzZTxUPiB7XG4gICAgY29uc3QgZXZlbnQgPSB0aGlzLl9zdGFydGVkID8gdGhpcy5iZWdpbihjYXRlZ29yeSwgbmFtZSwgY3R4KSA6IHVuZGVmaW5lZDtcbiAgICBsZXQgaXNQcm9taXNlID0gZmFsc2U7XG5cbiAgICBjb25zdCByZXMgPSBmdW5jKCk7XG5cbiAgICAvLyB3ZSBjb25zaWRlciBhIHRoZW4tYWJsZSBvYmplY3QgaXMgYSBwcm9taXNlXG4gICAgaWYgKHJlcyAmJiB0eXBlb2YgKHJlcyBhcyBQcm9taXNlPFQ+KS50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpc1Byb21pc2UgPSB0cnVlO1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPFQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgKHJlcyBhcyBQcm9taXNlPFQ+KS50aGVuKFxuICAgICAgICAgIGFzeW5jICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgLy8gZnVsZmlsbGVkXG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgYXdhaXQgZXZlbnQuZW5kKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIGFzeW5jIChyZWFzb24pID0+IHtcbiAgICAgICAgICAgIC8vIHJlamVjdGVkXG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgYXdhaXQgZXZlbnQuZW5kKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZWplY3QocmVhc29uKTtcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmICghaXNQcm9taXNlICYmIGV2ZW50KSB7XG4gICAgICBjb25zdCBldmVudFJlcyA9IGV2ZW50LmVuZCgpO1xuICAgICAgaWYgKGV2ZW50UmVzICYmIHR5cGVvZiBldmVudFJlcy50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxUPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgZXZlbnRSZXMudGhlbihcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgLy8gZnVsZmlsbGVkXG4gICAgICAgICAgICAgIHJlc29sdmUocmVzKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAocmVhc29uKSA9PiB7XG4gICAgICAgICAgICAgIC8vIHJlamVjdGVkXG4gICAgICAgICAgICAgIHJlamVjdChyZWFzb24pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIC8vIGJlZ2luIGFuIGV2ZW50XG4gIGJlZ2luKGNhdGVnb3J5OiBQcm9maWxlci5FdmVudENhdGVnb3J5LCBuYW1lOiBzdHJpbmcsIGN0eD86IFdlYkdMQ29udGV4dCk6IEV2ZW50IHtcbiAgICBpZiAoIXRoaXMuX3N0YXJ0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigncHJvZmlsZXIgaXMgbm90IHN0YXJ0ZWQgeWV0Jyk7XG4gICAgfVxuICAgIGlmIChjdHggPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3Qgc3RhcnRUaW1lID0gbm93KCk7XG4gICAgICB0aGlzLmZsdXNoKHN0YXJ0VGltZSk7XG4gICAgICByZXR1cm4gbmV3IEV2ZW50KGNhdGVnb3J5LCBuYW1lLCBzdGFydFRpbWUsIChlKSA9PiB0aGlzLmVuZFN5bmMoZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0aW1lcjogV2ViR0xRdWVyeSA9IGN0eC5iZWdpblRpbWVyKCk7XG4gICAgICByZXR1cm4gbmV3IEV2ZW50KGNhdGVnb3J5LCBuYW1lLCAwLCBhc3luYyAoZSkgPT4gdGhpcy5lbmQoZSksIHRpbWVyLCBjdHgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGVuZCB0aGUgc3BlY2lmaWMgZXZlbnRcbiAgcHJpdmF0ZSBhc3luYyBlbmQoZXZlbnQ6IEV2ZW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZW5kVGltZTogbnVtYmVyID0gYXdhaXQgZXZlbnQuY2hlY2tUaW1lcigpO1xuICAgIGlmICh0aGlzLl90aW1pbmdFdmVudHMubGVuZ3RoIDwgdGhpcy5fbWF4TnVtYmVyRXZlbnRzKSB7XG4gICAgICB0aGlzLl90aW1pbmdFdmVudHMucHVzaChuZXcgRXZlbnRSZWNvcmQoZXZlbnQuY2F0ZWdvcnksIGV2ZW50Lm5hbWUsIGV2ZW50LnN0YXJ0VGltZSwgZW5kVGltZSkpO1xuICAgICAgdGhpcy5mbHVzaChlbmRUaW1lKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGVuZFN5bmMoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgZW5kVGltZTogbnVtYmVyID0gbm93KCk7XG4gICAgaWYgKHRoaXMuX3RpbWluZ0V2ZW50cy5sZW5ndGggPCB0aGlzLl9tYXhOdW1iZXJFdmVudHMpIHtcbiAgICAgIHRoaXMuX3RpbWluZ0V2ZW50cy5wdXNoKG5ldyBFdmVudFJlY29yZChldmVudC5jYXRlZ29yeSwgZXZlbnQubmFtZSwgZXZlbnQuc3RhcnRUaW1lLCBlbmRUaW1lKSk7XG4gICAgICB0aGlzLmZsdXNoKGVuZFRpbWUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbG9nT25lRXZlbnQoZXZlbnQ6IEV2ZW50UmVjb3JkKSB7XG4gICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICBgUHJvZmlsZXIuJHtldmVudC5jYXRlZ29yeX1gLFxuICAgICAgYCR7KGV2ZW50LmVuZFRpbWUgLSBldmVudC5zdGFydFRpbWUpLnRvRml4ZWQoMil9bXMgb24gZXZlbnQgJyR7ZXZlbnQubmFtZX0nIGF0ICR7ZXZlbnQuZW5kVGltZS50b0ZpeGVkKDIpfWAsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZmx1c2goY3VycmVudFRpbWU6IG51bWJlcikge1xuICAgIGlmIChcbiAgICAgIHRoaXMuX3RpbWluZ0V2ZW50cy5sZW5ndGggLSB0aGlzLl9mbHVzaFBvaW50ZXIgPj0gdGhpcy5fZmx1c2hCYXRjaFNpemUgfHxcbiAgICAgIGN1cnJlbnRUaW1lIC0gdGhpcy5fZmx1c2hUaW1lID49IHRoaXMuX2ZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kc1xuICAgICkge1xuICAgICAgLy8gc2hvdWxkIGZsdXNoIHdoZW4gZWl0aGVyIGJhdGNoIHNpemUgYWNjdW11bGF0ZWQgb3IgaW50ZXJ2YWwgZWxlcHNlZFxuXG4gICAgICBmb3IgKFxuICAgICAgICBjb25zdCBwcmV2aW91c1BvaW50ZXIgPSB0aGlzLl9mbHVzaFBvaW50ZXI7XG4gICAgICAgIHRoaXMuX2ZsdXNoUG9pbnRlciA8IHByZXZpb3VzUG9pbnRlciArIHRoaXMuX2ZsdXNoQmF0Y2hTaXplICYmIHRoaXMuX2ZsdXNoUG9pbnRlciA8IHRoaXMuX3RpbWluZ0V2ZW50cy5sZW5ndGg7XG4gICAgICAgIHRoaXMuX2ZsdXNoUG9pbnRlcisrXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5sb2dPbmVFdmVudCh0aGlzLl90aW1pbmdFdmVudHNbdGhpcy5fZmx1c2hQb2ludGVyXSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2ZsdXNoVGltZSA9IG5vdygpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBzdGFydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9zdGFydGVkO1xuICB9XG4gIHByaXZhdGUgX3N0YXJ0ZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfdGltaW5nRXZlbnRzOiBFdmVudFJlY29yZFtdO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX21heE51bWJlckV2ZW50czogbnVtYmVyO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZsdXNoQmF0Y2hTaXplOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIHByaXZhdGUgX2ZsdXNoVGltZTogbnVtYmVyO1xuICBwcml2YXRlIF9mbHVzaFBvaW50ZXIgPSAwO1xufVxuXG4vKipcbiAqIHJldHVybnMgYSBudW1iZXIgdG8gcmVwcmVzZW50IHRoZSBjdXJyZW50IHRpbWVzdGFtcCBpbiBhIHJlc29sdXRpb24gYXMgaGlnaCBhcyBwb3NzaWJsZS5cbiAqL1xuZXhwb3J0IGNvbnN0IG5vdyA9IHR5cGVvZiBwZXJmb3JtYW5jZSAhPT0gJ3VuZGVmaW5lZCcgJiYgcGVyZm9ybWFuY2Uubm93ID8gKCkgPT4gcGVyZm9ybWFuY2Uubm93KCkgOiBEYXRlLm5vdztcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuL29wZXJhdG9ycyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BTZXQge1xuICBkb21haW46IHN0cmluZztcbiAgdmVyc2lvbjogbnVtYmVyO1xufVxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIE9wU2V0IHtcbiAgLyoqXG4gICAqIERvbWFpbiBvZiBhbiBvcHNldCwgaXQgY2FuIGJlIGFuIGVtcHR5IHN0cmluZyhkZWZhdWx0IHZhbHVlLCByZXByZXNlbnQgZm9yIGFpLm9ubngpLCBvciAnYWkub25ueC5tbCdcbiAgICovXG4gIHR5cGUgRG9tYWluID0gJycgfCAnYWkub25ueC5tbCcgfCAnY29tLm1pY3Jvc29mdCc7XG4gIC8qKlxuICAgKiBBIHJlc29sdmUgcnVsZSBjb25zaXN0cyBvZiA0IG9yIDUgaXRlbXM6IG9wVHlwZSwgb3BTZXREb21haW4sIHZlcnNpb25TZWxlY3Rvciwgb3BlcmF0b3JJbXBsZW1lbnRhdGlvbiBhbmRcbiAgICogb3BlcmF0b3JJbml0aWFsaXphdGlvbiAob3B0aW9uYWwpXG4gICAqL1xuICB0eXBlIFJlc29sdmVSdWxlID1cbiAgICB8IFtzdHJpbmcsIERvbWFpbiwgc3RyaW5nLCBPcGVyYXRvckltcGxlbWVudGF0aW9uPEdyYXBoLk5vZGU+XVxuICAgIHwgW3N0cmluZywgRG9tYWluLCBzdHJpbmcsIE9wZXJhdG9ySW1wbGVtZW50YXRpb248dW5rbm93bj4sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb248dW5rbm93bj5dO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZU9wZXJhdG9yKG5vZGU6IEdyYXBoLk5vZGUsIG9wc2V0czogcmVhZG9ubHkgT3BTZXRbXSwgcnVsZXM6IHJlYWRvbmx5IE9wU2V0LlJlc29sdmVSdWxlW10pIHtcbiAgZm9yIChjb25zdCBydWxlIG9mIHJ1bGVzKSB7XG4gICAgY29uc3Qgb3BUeXBlID0gcnVsZVswXTtcbiAgICBjb25zdCBkb21haW4gPSBydWxlWzFdO1xuICAgIGNvbnN0IHZlcnNpb25TZWxlY3RvciA9IHJ1bGVbMl07XG4gICAgY29uc3Qgb3BJbXBsID0gcnVsZVszXTtcbiAgICBjb25zdCBvcEluaXQgPSBydWxlWzRdO1xuXG4gICAgaWYgKG5vZGUub3BUeXBlID09PSBvcFR5cGUpIHtcbiAgICAgIC8vIG9wZXJhdG9yIHR5cGUgbWF0Y2hlc1xuICAgICAgZm9yIChjb25zdCBvcHNldCBvZiBvcHNldHMpIHtcbiAgICAgICAgLy8gb3BzZXQgJycgYW5kICdhaS5vbm54JyBhcmUgY29uc2lkZXJlZCB0aGUgc2FtZS5cbiAgICAgICAgaWYgKG9wc2V0LmRvbWFpbiA9PT0gZG9tYWluIHx8IChvcHNldC5kb21haW4gPT09ICdhaS5vbm54JyAmJiBkb21haW4gPT09ICcnKSkge1xuICAgICAgICAgIC8vIG9wc2V0IGRvbWFpbiBmb3VuZFxuICAgICAgICAgIGlmIChtYXRjaFNlbGVjdG9yKG9wc2V0LnZlcnNpb24sIHZlcnNpb25TZWxlY3RvcikpIHtcbiAgICAgICAgICAgIHJldHVybiB7IG9wSW1wbCwgb3BJbml0IH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICBgY2Fubm90IHJlc29sdmUgb3BlcmF0b3IgJyR7bm9kZS5vcFR5cGV9JyB3aXRoIG9wc2V0czogJHtvcHNldHNcbiAgICAgIC5tYXAoKHNldCkgPT4gYCR7c2V0LmRvbWFpbiB8fCAnYWkub25ueCd9IHYke3NldC52ZXJzaW9ufWApXG4gICAgICAuam9pbignLCAnKX1gLFxuICApO1xufVxuXG5mdW5jdGlvbiBtYXRjaFNlbGVjdG9yKHZlcnNpb246IG51bWJlciwgc2VsZWN0b3I6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBpZiAoc2VsZWN0b3IuZW5kc1dpdGgoJysnKSkge1xuICAgIC8vIG1pbmltdW0gdmVyc2lvbiBtYXRjaCAoJzcrJyBleHBlY3RzIHZlcnNpb24+PTcpXG4gICAgY29uc3QgcmFuZ2VTdGFydCA9IE51bWJlci5wYXJzZUludChzZWxlY3Rvci5zdWJzdHJpbmcoMCwgc2VsZWN0b3IubGVuZ3RoIC0gMSksIDEwKTtcbiAgICByZXR1cm4gIWlzTmFOKHJhbmdlU3RhcnQpICYmIHJhbmdlU3RhcnQgPD0gdmVyc2lvbjtcbiAgfSBlbHNlIGlmIChzZWxlY3Rvci5zcGxpdCgnLScpLmxlbmd0aCA9PT0gMikge1xuICAgIC8vIHJhbmdlIG1hdGNoICgnNi04JyBleHBlY3RzIDY8PXZlcnNpb248PTgpXG4gICAgY29uc3QgcGFpciA9IHNlbGVjdG9yLnNwbGl0KCctJyk7XG4gICAgY29uc3QgcmFuZ2VTdGFydCA9IE51bWJlci5wYXJzZUludChwYWlyWzBdLCAxMCk7XG4gICAgY29uc3QgcmFuZ2VFbmQgPSBOdW1iZXIucGFyc2VJbnQocGFpclsxXSwgMTApO1xuICAgIHJldHVybiAhaXNOYU4ocmFuZ2VTdGFydCkgJiYgIWlzTmFOKHJhbmdlRW5kKSAmJiByYW5nZVN0YXJ0IDw9IHZlcnNpb24gJiYgdmVyc2lvbiA8PSByYW5nZUVuZDtcbiAgfSBlbHNlIHtcbiAgICAvLyBleGFjdCBtYXRjaCAoJzcnIGV4cGVjdHMgdmVyc2lvbj09PTcpXG4gICAgcmV0dXJuIE51bWJlci5wYXJzZUludChzZWxlY3RvciwgMTApID09PSB2ZXJzaW9uO1xuICB9XG59XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XHJcbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XHJcbnZhciBHdWlkID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gR3VpZChndWlkKSB7XHJcbiAgICAgICAgaWYgKCFndWlkKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGFyZ3VtZW50OyBgdmFsdWVgIGhhcyBubyB2YWx1ZS5cIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMudmFsdWUgPSBHdWlkLkVNUFRZO1xyXG4gICAgICAgIGlmIChndWlkICYmIEd1aWQuaXNHdWlkKGd1aWQpKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBndWlkO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIEd1aWQuaXNHdWlkID0gZnVuY3Rpb24gKGd1aWQpIHtcclxuICAgICAgICB2YXIgdmFsdWUgPSBndWlkLnRvU3RyaW5nKCk7XHJcbiAgICAgICAgcmV0dXJuIGd1aWQgJiYgKGd1aWQgaW5zdGFuY2VvZiBHdWlkIHx8IEd1aWQudmFsaWRhdG9yLnRlc3QodmFsdWUpKTtcclxuICAgIH07XHJcbiAgICBHdWlkLmNyZWF0ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEd1aWQoW0d1aWQuZ2VuKDIpLCBHdWlkLmdlbigxKSwgR3VpZC5nZW4oMSksIEd1aWQuZ2VuKDEpLCBHdWlkLmdlbigzKV0uam9pbihcIi1cIikpO1xyXG4gICAgfTtcclxuICAgIEd1aWQuY3JlYXRlRW1wdHkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBHdWlkKFwiZW1wdHlndWlkXCIpO1xyXG4gICAgfTtcclxuICAgIEd1aWQucGFyc2UgPSBmdW5jdGlvbiAoZ3VpZCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgR3VpZChndWlkKTtcclxuICAgIH07XHJcbiAgICBHdWlkLnJhdyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gW0d1aWQuZ2VuKDIpLCBHdWlkLmdlbigxKSwgR3VpZC5nZW4oMSksIEd1aWQuZ2VuKDEpLCBHdWlkLmdlbigzKV0uam9pbihcIi1cIik7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5nZW4gPSBmdW5jdGlvbiAoY291bnQpIHtcclxuICAgICAgICB2YXIgb3V0ID0gXCJcIjtcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcclxuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWJpdHdpc2VcclxuICAgICAgICAgICAgb3V0ICs9ICgoKDEgKyBNYXRoLnJhbmRvbSgpKSAqIDB4MTAwMDApIHwgMCkudG9TdHJpbmcoMTYpLnN1YnN0cmluZygxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG91dDtcclxuICAgIH07XHJcbiAgICBHdWlkLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiAob3RoZXIpIHtcclxuICAgICAgICAvLyBDb21wYXJpbmcgc3RyaW5nIGB2YWx1ZWAgYWdhaW5zdCBwcm92aWRlZCBgZ3VpZGAgd2lsbCBhdXRvLWNhbGxcclxuICAgICAgICAvLyB0b1N0cmluZyBvbiBgZ3VpZGAgZm9yIGNvbXBhcmlzb25cclxuICAgICAgICByZXR1cm4gR3VpZC5pc0d1aWQob3RoZXIpICYmIHRoaXMudmFsdWUgPT09IG90aGVyLnRvU3RyaW5nKCk7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZSA9PT0gR3VpZC5FTVBUWTtcclxuICAgIH07XHJcbiAgICBHdWlkLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcclxuICAgIH07XHJcbiAgICBHdWlkLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdmFsdWU6IHRoaXMudmFsdWVcclxuICAgICAgICB9O1xyXG4gICAgfTtcclxuICAgIEd1aWQudmFsaWRhdG9yID0gbmV3IFJlZ0V4cChcIl5bYS16MC05XXs4fS1bYS16MC05XXs0fS1bYS16MC05XXs0fS1bYS16MC05XXs0fS1bYS16MC05XXsxMn0kXCIsIFwiaVwiKTtcclxuICAgIEd1aWQuRU1QVFkgPSBcIjAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiO1xyXG4gICAgcmV0dXJuIEd1aWQ7XHJcbn0oKSk7XHJcbmV4cG9ydHMuR3VpZCA9IEd1aWQ7XHJcbiIsICIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAwOSBUaGUgQ2xvc3VyZSBMaWJyYXJ5IEF1dGhvcnNcbiAqIENvcHlyaWdodCAyMDIwIERhbmllbCBXaXJ0eiAvIFRoZSBsb25nLmpzIEF1dGhvcnMuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cblxuLy8gV2ViQXNzZW1ibHkgb3B0aW1pemF0aW9ucyB0byBkbyBuYXRpdmUgaTY0IG11bHRpcGxpY2F0aW9uIGFuZCBkaXZpZGVcbnZhciB3YXNtID0gbnVsbDtcbnRyeSB7XG4gIHdhc20gPSBuZXcgV2ViQXNzZW1ibHkuSW5zdGFuY2UobmV3IFdlYkFzc2VtYmx5Lk1vZHVsZShuZXcgVWludDhBcnJheShbXG4gICAgMCwgOTcsIDExNSwgMTA5LCAxLCAwLCAwLCAwLCAxLCAxMywgMiwgOTYsIDAsIDEsIDEyNywgOTYsIDQsIDEyNywgMTI3LCAxMjcsIDEyNywgMSwgMTI3LCAzLCA3LCA2LCAwLCAxLCAxLCAxLCAxLCAxLCA2LCA2LCAxLCAxMjcsIDEsIDY1LCAwLCAxMSwgNywgNTAsIDYsIDMsIDEwOSwgMTE3LCAxMDgsIDAsIDEsIDUsIDEwMCwgMTA1LCAxMTgsIDk1LCAxMTUsIDAsIDIsIDUsIDEwMCwgMTA1LCAxMTgsIDk1LCAxMTcsIDAsIDMsIDUsIDExNCwgMTAxLCAxMDksIDk1LCAxMTUsIDAsIDQsIDUsIDExNCwgMTAxLCAxMDksIDk1LCAxMTcsIDAsIDUsIDgsIDEwMywgMTAxLCAxMTYsIDk1LCAxMDQsIDEwNSwgMTAzLCAxMDQsIDAsIDAsIDEwLCAxOTEsIDEsIDYsIDQsIDAsIDM1LCAwLCAxMSwgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI2LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LCAxNjcsIDExLCAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLCAzMiwgMywgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAxMjcsIDM0LCA0LCA2NiwgMzIsIDEzNSwgMTY3LCAzNiwgMCwgMzIsIDQsIDE2NywgMTEsIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEyOCwgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLCAzMiwgNCwgMTY3LCAxMSwgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI5LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LCAxNjcsIDExLCAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLCAzMiwgMywgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAxMzAsIDM0LCA0LCA2NiwgMzIsIDEzNSwgMTY3LCAzNiwgMCwgMzIsIDQsIDE2NywgMTFcbiAgXSkpLCB7fSkuZXhwb3J0cztcbn0gY2F0Y2ggKGUpIHtcbiAgLy8gbm8gd2FzbSBzdXBwb3J0IDooXG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIDY0IGJpdCB0d28ncy1jb21wbGVtZW50IGludGVnZXIsIGdpdmVuIGl0cyBsb3cgYW5kIGhpZ2ggMzIgYml0IHZhbHVlcyBhcyAqc2lnbmVkKiBpbnRlZ2Vycy5cbiAqICBTZWUgdGhlIGZyb20qIGZ1bmN0aW9ucyBiZWxvdyBmb3IgbW9yZSBjb252ZW5pZW50IHdheXMgb2YgY29uc3RydWN0aW5nIExvbmdzLlxuICogQGV4cG9ydHMgTG9uZ1xuICogQGNsYXNzIEEgTG9uZyBjbGFzcyBmb3IgcmVwcmVzZW50aW5nIGEgNjQgYml0IHR3bydzLWNvbXBsZW1lbnQgaW50ZWdlciB2YWx1ZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBsb3cgVGhlIGxvdyAoc2lnbmVkKSAzMiBiaXRzIG9mIHRoZSBsb25nXG4gKiBAcGFyYW0ge251bWJlcn0gaGlnaCBUaGUgaGlnaCAoc2lnbmVkKSAzMiBiaXRzIG9mIHRoZSBsb25nXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gTG9uZyhsb3csIGhpZ2gsIHVuc2lnbmVkKSB7XG5cbiAgLyoqXG4gICAqIFRoZSBsb3cgMzIgYml0cyBhcyBhIHNpZ25lZCB2YWx1ZS5cbiAgICogQHR5cGUge251bWJlcn1cbiAgICovXG4gIHRoaXMubG93ID0gbG93IHwgMDtcblxuICAvKipcbiAgICogVGhlIGhpZ2ggMzIgYml0cyBhcyBhIHNpZ25lZCB2YWx1ZS5cbiAgICogQHR5cGUge251bWJlcn1cbiAgICovXG4gIHRoaXMuaGlnaCA9IGhpZ2ggfCAwO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdC5cbiAgICogQHR5cGUge2Jvb2xlYW59XG4gICAqL1xuICB0aGlzLnVuc2lnbmVkID0gISF1bnNpZ25lZDtcbn1cblxuLy8gVGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uIG9mIGEgbG9uZyBpcyB0aGUgdHdvIGdpdmVuIHNpZ25lZCwgMzItYml0IHZhbHVlcy5cbi8vIFdlIHVzZSAzMi1iaXQgcGllY2VzIGJlY2F1c2UgdGhlc2UgYXJlIHRoZSBzaXplIG9mIGludGVnZXJzIG9uIHdoaWNoXG4vLyBKYXZhc2NyaXB0IHBlcmZvcm1zIGJpdC1vcGVyYXRpb25zLiAgRm9yIG9wZXJhdGlvbnMgbGlrZSBhZGRpdGlvbiBhbmRcbi8vIG11bHRpcGxpY2F0aW9uLCB3ZSBzcGxpdCBlYWNoIG51bWJlciBpbnRvIDE2IGJpdCBwaWVjZXMsIHdoaWNoIGNhbiBlYXNpbHkgYmVcbi8vIG11bHRpcGxpZWQgd2l0aGluIEphdmFzY3JpcHQncyBmbG9hdGluZy1wb2ludCByZXByZXNlbnRhdGlvbiB3aXRob3V0IG92ZXJmbG93XG4vLyBvciBjaGFuZ2UgaW4gc2lnbi5cbi8vXG4vLyBJbiB0aGUgYWxnb3JpdGhtcyBiZWxvdywgd2UgZnJlcXVlbnRseSByZWR1Y2UgdGhlIG5lZ2F0aXZlIGNhc2UgdG8gdGhlXG4vLyBwb3NpdGl2ZSBjYXNlIGJ5IG5lZ2F0aW5nIHRoZSBpbnB1dChzKSBhbmQgdGhlbiBwb3N0LXByb2Nlc3NpbmcgdGhlIHJlc3VsdC5cbi8vIE5vdGUgdGhhdCB3ZSBtdXN0IEFMV0FZUyBjaGVjayBzcGVjaWFsbHkgd2hldGhlciB0aG9zZSB2YWx1ZXMgYXJlIE1JTl9WQUxVRVxuLy8gKC0yXjYzKSBiZWNhdXNlIC1NSU5fVkFMVUUgPT0gTUlOX1ZBTFVFIChzaW5jZSAyXjYzIGNhbm5vdCBiZSByZXByZXNlbnRlZCBhc1xuLy8gYSBwb3NpdGl2ZSBudW1iZXIsIGl0IG92ZXJmbG93cyBiYWNrIGludG8gYSBuZWdhdGl2ZSkuICBOb3QgaGFuZGxpbmcgdGhpc1xuLy8gY2FzZSB3b3VsZCBvZnRlbiByZXN1bHQgaW4gaW5maW5pdGUgcmVjdXJzaW9uLlxuLy9cbi8vIENvbW1vbiBjb25zdGFudCB2YWx1ZXMgWkVSTywgT05FLCBORUdfT05FLCBldGMuIGFyZSBkZWZpbmVkIGJlbG93IHRoZSBmcm9tKlxuLy8gbWV0aG9kcyBvbiB3aGljaCB0aGV5IGRlcGVuZC5cblxuLyoqXG4gKiBBbiBpbmRpY2F0b3IgdXNlZCB0byByZWxpYWJseSBkZXRlcm1pbmUgaWYgYW4gb2JqZWN0IGlzIGEgTG9uZyBvciBub3QuXG4gKiBAdHlwZSB7Ym9vbGVhbn1cbiAqIEBjb25zdFxuICogQHByaXZhdGVcbiAqL1xuTG9uZy5wcm90b3R5cGUuX19pc0xvbmdfXztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KExvbmcucHJvdG90eXBlLCBcIl9faXNMb25nX19cIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblxuLyoqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7Kn0gb2JqIE9iamVjdFxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gaXNMb25nKG9iaikge1xuICByZXR1cm4gKG9iaiAmJiBvYmpbXCJfX2lzTG9uZ19fXCJdKSA9PT0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgbnVtYmVyXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICogQGlubmVyXG4gKi9cbmZ1bmN0aW9uIGN0ejMyKHZhbHVlKSB7XG4gIHZhciBjID0gTWF0aC5jbHozMih2YWx1ZSAmIC12YWx1ZSk7XG4gIHJldHVybiB2YWx1ZSA/IDMxIC0gYyA6IGM7XG59XG5cbi8qKlxuICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgYSBMb25nLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyp9IG9iaiBPYmplY3RcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nLmlzTG9uZyA9IGlzTG9uZztcblxuLyoqXG4gKiBBIGNhY2hlIG9mIHRoZSBMb25nIHJlcHJlc2VudGF0aW9ucyBvZiBzbWFsbCBpbnRlZ2VyIHZhbHVlcy5cbiAqIEB0eXBlIHshT2JqZWN0fVxuICogQGlubmVyXG4gKi9cbnZhciBJTlRfQ0FDSEUgPSB7fTtcblxuLyoqXG4gKiBBIGNhY2hlIG9mIHRoZSBMb25nIHJlcHJlc2VudGF0aW9ucyBvZiBzbWFsbCB1bnNpZ25lZCBpbnRlZ2VyIHZhbHVlcy5cbiAqIEB0eXBlIHshT2JqZWN0fVxuICogQGlubmVyXG4gKi9cbnZhciBVSU5UX0NBQ0hFID0ge307XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxuICogQHJldHVybnMgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbmZ1bmN0aW9uIGZyb21JbnQodmFsdWUsIHVuc2lnbmVkKSB7XG4gIHZhciBvYmosIGNhY2hlZE9iaiwgY2FjaGU7XG4gIGlmICh1bnNpZ25lZCkge1xuICAgIHZhbHVlID4+Pj0gMDtcbiAgICBpZiAoY2FjaGUgPSAoMCA8PSB2YWx1ZSAmJiB2YWx1ZSA8IDI1NikpIHtcbiAgICAgIGNhY2hlZE9iaiA9IFVJTlRfQ0FDSEVbdmFsdWVdO1xuICAgICAgaWYgKGNhY2hlZE9iailcbiAgICAgICAgcmV0dXJuIGNhY2hlZE9iajtcbiAgICB9XG4gICAgb2JqID0gZnJvbUJpdHModmFsdWUsIDAsIHRydWUpO1xuICAgIGlmIChjYWNoZSlcbiAgICAgIFVJTlRfQ0FDSEVbdmFsdWVdID0gb2JqO1xuICAgIHJldHVybiBvYmo7XG4gIH0gZWxzZSB7XG4gICAgdmFsdWUgfD0gMDtcbiAgICBpZiAoY2FjaGUgPSAoLTEyOCA8PSB2YWx1ZSAmJiB2YWx1ZSA8IDEyOCkpIHtcbiAgICAgIGNhY2hlZE9iaiA9IElOVF9DQUNIRVt2YWx1ZV07XG4gICAgICBpZiAoY2FjaGVkT2JqKVxuICAgICAgICByZXR1cm4gY2FjaGVkT2JqO1xuICAgIH1cbiAgICBvYmogPSBmcm9tQml0cyh2YWx1ZSwgdmFsdWUgPCAwID8gLTEgOiAwLCBmYWxzZSk7XG4gICAgaWYgKGNhY2hlKVxuICAgICAgSU5UX0NBQ0hFW3ZhbHVlXSA9IG9iajtcbiAgICByZXR1cm4gb2JqO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiAzMiBiaXQgaW50ZWdlciB2YWx1ZS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSAzMiBiaXQgaW50ZWdlciBpbiBxdWVzdGlvblxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXG4gKi9cbkxvbmcuZnJvbUludCA9IGZyb21JbnQ7XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxuICogQHJldHVybnMgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbmZ1bmN0aW9uIGZyb21OdW1iZXIodmFsdWUsIHVuc2lnbmVkKSB7XG4gIGlmIChpc05hTih2YWx1ZSkpXG4gICAgcmV0dXJuIHVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xuICBpZiAodW5zaWduZWQpIHtcbiAgICBpZiAodmFsdWUgPCAwKVxuICAgICAgcmV0dXJuIFVaRVJPO1xuICAgIGlmICh2YWx1ZSA+PSBUV09fUFdSXzY0X0RCTClcbiAgICAgIHJldHVybiBNQVhfVU5TSUdORURfVkFMVUU7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHZhbHVlIDw9IC1UV09fUFdSXzYzX0RCTClcbiAgICAgIHJldHVybiBNSU5fVkFMVUU7XG4gICAgaWYgKHZhbHVlICsgMSA+PSBUV09fUFdSXzYzX0RCTClcbiAgICAgIHJldHVybiBNQVhfVkFMVUU7XG4gIH1cbiAgaWYgKHZhbHVlIDwgMClcbiAgICByZXR1cm4gZnJvbU51bWJlcigtdmFsdWUsIHVuc2lnbmVkKS5uZWcoKTtcbiAgcmV0dXJuIGZyb21CaXRzKCh2YWx1ZSAlIFRXT19QV1JfMzJfREJMKSB8IDAsICh2YWx1ZSAvIFRXT19QV1JfMzJfREJMKSB8IDAsIHVuc2lnbmVkKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRpbmcgdGhlIGdpdmVuIHZhbHVlLCBwcm92aWRlZCB0aGF0IGl0IGlzIGEgZmluaXRlIG51bWJlci4gT3RoZXJ3aXNlLCB6ZXJvIGlzIHJldHVybmVkLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVGhlIG51bWJlciBpbiBxdWVzdGlvblxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXG4gKi9cbkxvbmcuZnJvbU51bWJlciA9IGZyb21OdW1iZXI7XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IGxvd0JpdHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoQml0c1xuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWRcbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG5mdW5jdGlvbiBmcm9tQml0cyhsb3dCaXRzLCBoaWdoQml0cywgdW5zaWduZWQpIHtcbiAgcmV0dXJuIG5ldyBMb25nKGxvd0JpdHMsIGhpZ2hCaXRzLCB1bnNpZ25lZCk7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSA2NCBiaXQgaW50ZWdlciB0aGF0IGNvbWVzIGJ5IGNvbmNhdGVuYXRpbmcgdGhlIGdpdmVuIGxvdyBhbmQgaGlnaCBiaXRzLiBFYWNoIGlzXG4gKiAgYXNzdW1lZCB0byB1c2UgMzIgYml0cy5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IGxvd0JpdHMgVGhlIGxvdyAzMiBiaXRzXG4gKiBAcGFyYW0ge251bWJlcn0gaGlnaEJpdHMgVGhlIGhpZ2ggMzIgYml0c1xuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXG4gKi9cbkxvbmcuZnJvbUJpdHMgPSBmcm9tQml0cztcblxuLyoqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSBiYXNlXG4gKiBAcGFyYW0ge251bWJlcn0gZXhwb25lbnRcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKiBAaW5uZXJcbiAqL1xudmFyIHBvd19kYmwgPSBNYXRoLnBvdzsgLy8gVXNlZCA0IHRpbWVzICg0KjggdG8gMTUrNClcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKiBAcGFyYW0geyhib29sZWFufG51bWJlcik9fSB1bnNpZ25lZFxuICogQHBhcmFtIHtudW1iZXI9fSByYWRpeFxuICogQHJldHVybnMgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbmZ1bmN0aW9uIGZyb21TdHJpbmcoc3RyLCB1bnNpZ25lZCwgcmFkaXgpIHtcbiAgaWYgKHN0ci5sZW5ndGggPT09IDApXG4gICAgdGhyb3cgRXJyb3IoJ2VtcHR5IHN0cmluZycpO1xuICBpZiAodHlwZW9mIHVuc2lnbmVkID09PSAnbnVtYmVyJykge1xuICAgIC8vIEZvciBnb29nLm1hdGgubG9uZyBjb21wYXRpYmlsaXR5XG4gICAgcmFkaXggPSB1bnNpZ25lZDtcbiAgICB1bnNpZ25lZCA9IGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIHVuc2lnbmVkID0gISF1bnNpZ25lZDtcbiAgfVxuICBpZiAoc3RyID09PSBcIk5hTlwiIHx8IHN0ciA9PT0gXCJJbmZpbml0eVwiIHx8IHN0ciA9PT0gXCIrSW5maW5pdHlcIiB8fCBzdHIgPT09IFwiLUluZmluaXR5XCIpXG4gICAgcmV0dXJuIHVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xuICByYWRpeCA9IHJhZGl4IHx8IDEwO1xuICBpZiAocmFkaXggPCAyIHx8IDM2IDwgcmFkaXgpXG4gICAgdGhyb3cgUmFuZ2VFcnJvcigncmFkaXgnKTtcblxuICB2YXIgcDtcbiAgaWYgKChwID0gc3RyLmluZGV4T2YoJy0nKSkgPiAwKVxuICAgIHRocm93IEVycm9yKCdpbnRlcmlvciBoeXBoZW4nKTtcbiAgZWxzZSBpZiAocCA9PT0gMCkge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHN0ci5zdWJzdHJpbmcoMSksIHVuc2lnbmVkLCByYWRpeCkubmVnKCk7XG4gIH1cblxuICAvLyBEbyBzZXZlcmFsICg4KSBkaWdpdHMgZWFjaCB0aW1lIHRocm91Z2ggdGhlIGxvb3AsIHNvIGFzIHRvXG4gIC8vIG1pbmltaXplIHRoZSBjYWxscyB0byB0aGUgdmVyeSBleHBlbnNpdmUgZW11bGF0ZWQgZGl2LlxuICB2YXIgcmFkaXhUb1Bvd2VyID0gZnJvbU51bWJlcihwb3dfZGJsKHJhZGl4LCA4KSk7XG5cbiAgdmFyIHJlc3VsdCA9IFpFUk87XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSArPSA4KSB7XG4gICAgdmFyIHNpemUgPSBNYXRoLm1pbig4LCBzdHIubGVuZ3RoIC0gaSksXG4gICAgICB2YWx1ZSA9IHBhcnNlSW50KHN0ci5zdWJzdHJpbmcoaSwgaSArIHNpemUpLCByYWRpeCk7XG4gICAgaWYgKHNpemUgPCA4KSB7XG4gICAgICB2YXIgcG93ZXIgPSBmcm9tTnVtYmVyKHBvd19kYmwocmFkaXgsIHNpemUpKTtcbiAgICAgIHJlc3VsdCA9IHJlc3VsdC5tdWwocG93ZXIpLmFkZChmcm9tTnVtYmVyKHZhbHVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCA9IHJlc3VsdC5tdWwocmFkaXhUb1Bvd2VyKTtcbiAgICAgIHJlc3VsdCA9IHJlc3VsdC5hZGQoZnJvbU51bWJlcih2YWx1ZSkpO1xuICAgIH1cbiAgfVxuICByZXN1bHQudW5zaWduZWQgPSB1bnNpZ25lZDtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gc3RyaW5nLCB3cml0dGVuIHVzaW5nIHRoZSBzcGVjaWZpZWQgcmFkaXguXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgVGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIExvbmdcbiAqIEBwYXJhbSB7KGJvb2xlYW58bnVtYmVyKT19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAqIEBwYXJhbSB7bnVtYmVyPX0gcmFkaXggVGhlIHJhZGl4IGluIHdoaWNoIHRoZSB0ZXh0IGlzIHdyaXR0ZW4gKDItMzYpLCBkZWZhdWx0cyB0byAxMFxuICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXG4gKi9cbkxvbmcuZnJvbVN0cmluZyA9IGZyb21TdHJpbmc7XG5cbi8qKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd8IXtsb3c6IG51bWJlciwgaGlnaDogbnVtYmVyLCB1bnNpZ25lZDogYm9vbGVhbn19IHZhbFxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWRcbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG5mdW5jdGlvbiBmcm9tVmFsdWUodmFsLCB1bnNpZ25lZCkge1xuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpXG4gICAgcmV0dXJuIGZyb21OdW1iZXIodmFsLCB1bnNpZ25lZCk7XG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJylcbiAgICByZXR1cm4gZnJvbVN0cmluZyh2YWwsIHVuc2lnbmVkKTtcbiAgLy8gVGhyb3dzIGZvciBub24tb2JqZWN0cywgY29udmVydHMgbm9uLWluc3RhbmNlb2YgTG9uZzpcbiAgcmV0dXJuIGZyb21CaXRzKHZhbC5sb3csIHZhbC5oaWdoLCB0eXBlb2YgdW5zaWduZWQgPT09ICdib29sZWFuJyA/IHVuc2lnbmVkIDogdmFsLnVuc2lnbmVkKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIHZhbHVlIHRvIGEgTG9uZyB1c2luZyB0aGUgYXBwcm9wcmlhdGUgZnJvbSogZnVuY3Rpb24gZm9yIGl0cyB0eXBlLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd8IXtsb3c6IG51bWJlciwgaGlnaDogbnVtYmVyLCB1bnNpZ25lZDogYm9vbGVhbn19IHZhbCBWYWx1ZVxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQHJldHVybnMgeyFMb25nfVxuICovXG5Mb25nLmZyb21WYWx1ZSA9IGZyb21WYWx1ZTtcblxuLy8gTk9URTogdGhlIGNvbXBpbGVyIHNob3VsZCBpbmxpbmUgdGhlc2UgY29uc3RhbnQgdmFsdWVzIGJlbG93IGFuZCB0aGVuIHJlbW92ZSB0aGVzZSB2YXJpYWJsZXMsIHNvIHRoZXJlIHNob3VsZCBiZVxuLy8gbm8gcnVudGltZSBwZW5hbHR5IGZvciB0aGVzZS5cblxuLyoqXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQGNvbnN0XG4gKiBAaW5uZXJcbiAqL1xudmFyIFRXT19QV1JfMTZfREJMID0gMSA8PCAxNjtcblxuLyoqXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQGNvbnN0XG4gKiBAaW5uZXJcbiAqL1xudmFyIFRXT19QV1JfMjRfREJMID0gMSA8PCAyNDtcblxuLyoqXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQGNvbnN0XG4gKiBAaW5uZXJcbiAqL1xudmFyIFRXT19QV1JfMzJfREJMID0gVFdPX1BXUl8xNl9EQkwgKiBUV09fUFdSXzE2X0RCTDtcblxuLyoqXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQGNvbnN0XG4gKiBAaW5uZXJcbiAqL1xudmFyIFRXT19QV1JfNjRfREJMID0gVFdPX1BXUl8zMl9EQkwgKiBUV09fUFdSXzMyX0RCTDtcblxuLyoqXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQGNvbnN0XG4gKiBAaW5uZXJcbiAqL1xudmFyIFRXT19QV1JfNjNfREJMID0gVFdPX1BXUl82NF9EQkwgLyAyO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBjb25zdFxuICogQGlubmVyXG4gKi9cbnZhciBUV09fUFdSXzI0ID0gZnJvbUludChUV09fUFdSXzI0X0RCTCk7XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbnZhciBaRVJPID0gZnJvbUludCgwKTtcblxuLyoqXG4gKiBTaWduZWQgemVyby5cbiAqIEB0eXBlIHshTG9uZ31cbiAqL1xuTG9uZy5aRVJPID0gWkVSTztcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIFVaRVJPID0gZnJvbUludCgwLCB0cnVlKTtcblxuLyoqXG4gKiBVbnNpZ25lZCB6ZXJvLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLlVaRVJPID0gVVpFUk87XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbnZhciBPTkUgPSBmcm9tSW50KDEpO1xuXG4vKipcbiAqIFNpZ25lZCBvbmUuXG4gKiBAdHlwZSB7IUxvbmd9XG4gKi9cbkxvbmcuT05FID0gT05FO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG52YXIgVU9ORSA9IGZyb21JbnQoMSwgdHJ1ZSk7XG5cbi8qKlxuICogVW5zaWduZWQgb25lLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLlVPTkUgPSBVT05FO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG52YXIgTkVHX09ORSA9IGZyb21JbnQoLTEpO1xuXG4vKipcbiAqIFNpZ25lZCBuZWdhdGl2ZSBvbmUuXG4gKiBAdHlwZSB7IUxvbmd9XG4gKi9cbkxvbmcuTkVHX09ORSA9IE5FR19PTkU7XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbnZhciBNQVhfVkFMVUUgPSBmcm9tQml0cygweEZGRkZGRkZGIHwgMCwgMHg3RkZGRkZGRiB8IDAsIGZhbHNlKTtcblxuLyoqXG4gKiBNYXhpbXVtIHNpZ25lZCB2YWx1ZS5cbiAqIEB0eXBlIHshTG9uZ31cbiAqL1xuTG9uZy5NQVhfVkFMVUUgPSBNQVhfVkFMVUU7XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbnZhciBNQVhfVU5TSUdORURfVkFMVUUgPSBmcm9tQml0cygweEZGRkZGRkZGIHwgMCwgMHhGRkZGRkZGRiB8IDAsIHRydWUpO1xuXG4vKipcbiAqIE1heGltdW0gdW5zaWduZWQgdmFsdWUuXG4gKiBAdHlwZSB7IUxvbmd9XG4gKi9cbkxvbmcuTUFYX1VOU0lHTkVEX1ZBTFVFID0gTUFYX1VOU0lHTkVEX1ZBTFVFO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG52YXIgTUlOX1ZBTFVFID0gZnJvbUJpdHMoMCwgMHg4MDAwMDAwMCB8IDAsIGZhbHNlKTtcblxuLyoqXG4gKiBNaW5pbXVtIHNpZ25lZCB2YWx1ZS5cbiAqIEB0eXBlIHshTG9uZ31cbiAqL1xuTG9uZy5NSU5fVkFMVUUgPSBNSU5fVkFMVUU7XG5cbi8qKlxuICogQGFsaWFzIExvbmcucHJvdG90eXBlXG4gKiBAaW5uZXJcbiAqL1xudmFyIExvbmdQcm90b3R5cGUgPSBMb25nLnByb3RvdHlwZTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgTG9uZyB0byBhIDMyIGJpdCBpbnRlZ2VyLCBhc3N1bWluZyBpdCBpcyBhIDMyIGJpdCBpbnRlZ2VyLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS50b0ludCA9IGZ1bmN0aW9uIHRvSW50KCkge1xuICByZXR1cm4gdGhpcy51bnNpZ25lZCA/IHRoaXMubG93ID4+PiAwIDogdGhpcy5sb3c7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGEgdGhlIG5lYXJlc3QgZmxvYXRpbmctcG9pbnQgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB2YWx1ZSAoZG91YmxlLCA1MyBiaXQgbWFudGlzc2EpLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS50b051bWJlciA9IGZ1bmN0aW9uIHRvTnVtYmVyKCkge1xuICBpZiAodGhpcy51bnNpZ25lZClcbiAgICByZXR1cm4gKCh0aGlzLmhpZ2ggPj4+IDApICogVFdPX1BXUl8zMl9EQkwpICsgKHRoaXMubG93ID4+PiAwKTtcbiAgcmV0dXJuIHRoaXMuaGlnaCAqIFRXT19QV1JfMzJfREJMICsgKHRoaXMubG93ID4+PiAwKTtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhlIExvbmcgdG8gYSBzdHJpbmcgd3JpdHRlbiBpbiB0aGUgc3BlY2lmaWVkIHJhZGl4LlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHtudW1iZXI9fSByYWRpeCBSYWRpeCAoMi0zNiksIGRlZmF1bHRzIHRvIDEwXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICogQG92ZXJyaWRlXG4gKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgcmFkaXhgIGlzIG91dCBvZiByYW5nZVxuICovXG5Mb25nUHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcocmFkaXgpIHtcbiAgcmFkaXggPSByYWRpeCB8fCAxMDtcbiAgaWYgKHJhZGl4IDwgMiB8fCAzNiA8IHJhZGl4KVxuICAgIHRocm93IFJhbmdlRXJyb3IoJ3JhZGl4Jyk7XG4gIGlmICh0aGlzLmlzWmVybygpKVxuICAgIHJldHVybiAnMCc7XG4gIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkgeyAvLyBVbnNpZ25lZCBMb25ncyBhcmUgbmV2ZXIgbmVnYXRpdmVcbiAgICBpZiAodGhpcy5lcShNSU5fVkFMVUUpKSB7XG4gICAgICAvLyBXZSBuZWVkIHRvIGNoYW5nZSB0aGUgTG9uZyB2YWx1ZSBiZWZvcmUgaXQgY2FuIGJlIG5lZ2F0ZWQsIHNvIHdlIHJlbW92ZVxuICAgICAgLy8gdGhlIGJvdHRvbS1tb3N0IGRpZ2l0IGluIHRoaXMgYmFzZSBhbmQgdGhlbiByZWN1cnNlIHRvIGRvIHRoZSByZXN0LlxuICAgICAgdmFyIHJhZGl4TG9uZyA9IGZyb21OdW1iZXIocmFkaXgpLFxuICAgICAgICBkaXYgPSB0aGlzLmRpdihyYWRpeExvbmcpLFxuICAgICAgICByZW0xID0gZGl2Lm11bChyYWRpeExvbmcpLnN1Yih0aGlzKTtcbiAgICAgIHJldHVybiBkaXYudG9TdHJpbmcocmFkaXgpICsgcmVtMS50b0ludCgpLnRvU3RyaW5nKHJhZGl4KTtcbiAgICB9IGVsc2VcbiAgICAgIHJldHVybiAnLScgKyB0aGlzLm5lZygpLnRvU3RyaW5nKHJhZGl4KTtcbiAgfVxuXG4gIC8vIERvIHNldmVyYWwgKDYpIGRpZ2l0cyBlYWNoIHRpbWUgdGhyb3VnaCB0aGUgbG9vcCwgc28gYXMgdG9cbiAgLy8gbWluaW1pemUgdGhlIGNhbGxzIHRvIHRoZSB2ZXJ5IGV4cGVuc2l2ZSBlbXVsYXRlZCBkaXYuXG4gIHZhciByYWRpeFRvUG93ZXIgPSBmcm9tTnVtYmVyKHBvd19kYmwocmFkaXgsIDYpLCB0aGlzLnVuc2lnbmVkKSxcbiAgICByZW0gPSB0aGlzO1xuICB2YXIgcmVzdWx0ID0gJyc7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgdmFyIHJlbURpdiA9IHJlbS5kaXYocmFkaXhUb1Bvd2VyKSxcbiAgICAgIGludHZhbCA9IHJlbS5zdWIocmVtRGl2Lm11bChyYWRpeFRvUG93ZXIpKS50b0ludCgpID4+PiAwLFxuICAgICAgZGlnaXRzID0gaW50dmFsLnRvU3RyaW5nKHJhZGl4KTtcbiAgICByZW0gPSByZW1EaXY7XG4gICAgaWYgKHJlbS5pc1plcm8oKSlcbiAgICAgIHJldHVybiBkaWdpdHMgKyByZXN1bHQ7XG4gICAgZWxzZSB7XG4gICAgICB3aGlsZSAoZGlnaXRzLmxlbmd0aCA8IDYpXG4gICAgICAgIGRpZ2l0cyA9ICcwJyArIGRpZ2l0cztcbiAgICAgIHJlc3VsdCA9ICcnICsgZGlnaXRzICsgcmVzdWx0O1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBHZXRzIHRoZSBoaWdoIDMyIGJpdHMgYXMgYSBzaWduZWQgaW50ZWdlci5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFNpZ25lZCBoaWdoIGJpdHNcbiAqL1xuTG9uZ1Byb3RvdHlwZS5nZXRIaWdoQml0cyA9IGZ1bmN0aW9uIGdldEhpZ2hCaXRzKCkge1xuICByZXR1cm4gdGhpcy5oaWdoO1xufTtcblxuLyoqXG4gKiBHZXRzIHRoZSBoaWdoIDMyIGJpdHMgYXMgYW4gdW5zaWduZWQgaW50ZWdlci5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFVuc2lnbmVkIGhpZ2ggYml0c1xuICovXG5Mb25nUHJvdG90eXBlLmdldEhpZ2hCaXRzVW5zaWduZWQgPSBmdW5jdGlvbiBnZXRIaWdoQml0c1Vuc2lnbmVkKCkge1xuICByZXR1cm4gdGhpcy5oaWdoID4+PiAwO1xufTtcblxuLyoqXG4gKiBHZXRzIHRoZSBsb3cgMzIgYml0cyBhcyBhIHNpZ25lZCBpbnRlZ2VyLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge251bWJlcn0gU2lnbmVkIGxvdyBiaXRzXG4gKi9cbkxvbmdQcm90b3R5cGUuZ2V0TG93Qml0cyA9IGZ1bmN0aW9uIGdldExvd0JpdHMoKSB7XG4gIHJldHVybiB0aGlzLmxvdztcbn07XG5cbi8qKlxuICogR2V0cyB0aGUgbG93IDMyIGJpdHMgYXMgYW4gdW5zaWduZWQgaW50ZWdlci5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFVuc2lnbmVkIGxvdyBiaXRzXG4gKi9cbkxvbmdQcm90b3R5cGUuZ2V0TG93Qml0c1Vuc2lnbmVkID0gZnVuY3Rpb24gZ2V0TG93Qml0c1Vuc2lnbmVkKCkge1xuICByZXR1cm4gdGhpcy5sb3cgPj4+IDA7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIG51bWJlciBvZiBiaXRzIG5lZWRlZCB0byByZXByZXNlbnQgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoaXMgTG9uZy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbkxvbmdQcm90b3R5cGUuZ2V0TnVtQml0c0FicyA9IGZ1bmN0aW9uIGdldE51bUJpdHNBYnMoKSB7XG4gIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkgLy8gVW5zaWduZWQgTG9uZ3MgYXJlIG5ldmVyIG5lZ2F0aXZlXG4gICAgcmV0dXJuIHRoaXMuZXEoTUlOX1ZBTFVFKSA/IDY0IDogdGhpcy5uZWcoKS5nZXROdW1CaXRzQWJzKCk7XG4gIHZhciB2YWwgPSB0aGlzLmhpZ2ggIT0gMCA/IHRoaXMuaGlnaCA6IHRoaXMubG93O1xuICBmb3IgKHZhciBiaXQgPSAzMTsgYml0ID4gMDsgYml0LS0pXG4gICAgaWYgKCh2YWwgJiAoMSA8PCBiaXQpKSAhPSAwKVxuICAgICAgYnJlYWs7XG4gIHJldHVybiB0aGlzLmhpZ2ggIT0gMCA/IGJpdCArIDMzIDogYml0ICsgMTtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHplcm8uXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5pc1plcm8gPSBmdW5jdGlvbiBpc1plcm8oKSB7XG4gIHJldHVybiB0aGlzLmhpZ2ggPT09IDAgJiYgdGhpcy5sb3cgPT09IDA7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB6ZXJvLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2lzWmVyb30uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5lcXogPSBMb25nUHJvdG90eXBlLmlzWmVybztcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBuZWdhdGl2ZS5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmlzTmVnYXRpdmUgPSBmdW5jdGlvbiBpc05lZ2F0aXZlKCkge1xuICByZXR1cm4gIXRoaXMudW5zaWduZWQgJiYgdGhpcy5oaWdoIDwgMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgcG9zaXRpdmUgb3IgemVyby5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmlzUG9zaXRpdmUgPSBmdW5jdGlvbiBpc1Bvc2l0aXZlKCkge1xuICByZXR1cm4gdGhpcy51bnNpZ25lZCB8fCB0aGlzLmhpZ2ggPj0gMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgb2RkLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuaXNPZGQgPSBmdW5jdGlvbiBpc09kZCgpIHtcbiAgcmV0dXJuICh0aGlzLmxvdyAmIDEpID09PSAxO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBldmVuLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuaXNFdmVuID0gZnVuY3Rpb24gaXNFdmVuKCkge1xuICByZXR1cm4gKHRoaXMubG93ICYgMSkgPT09IDA7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMob3RoZXIpIHtcbiAgaWYgKCFpc0xvbmcob3RoZXIpKVxuICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcbiAgaWYgKHRoaXMudW5zaWduZWQgIT09IG90aGVyLnVuc2lnbmVkICYmICh0aGlzLmhpZ2ggPj4+IDMxKSA9PT0gMSAmJiAob3RoZXIuaGlnaCA+Pj4gMzEpID09PSAxKVxuICAgIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHRoaXMuaGlnaCA9PT0gb3RoZXIuaGlnaCAmJiB0aGlzLmxvdyA9PT0gb3RoZXIubG93O1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2VxdWFsc30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmVxID0gTG9uZ1Byb3RvdHlwZS5lcXVhbHM7XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZGlmZmVycyBmcm9tIHRoZSBzcGVjaWZpZWQncy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLm5vdEVxdWFscyA9IGZ1bmN0aW9uIG5vdEVxdWFscyhvdGhlcikge1xuICByZXR1cm4gIXRoaXMuZXEoLyogdmFsaWRhdGVzICovIG90aGVyKTtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZGlmZmVycyBmcm9tIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNub3RFcXVhbHN9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5uZXEgPSBMb25nUHJvdG90eXBlLm5vdEVxdWFscztcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBkaWZmZXJzIGZyb20gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI25vdEVxdWFsc30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLm5lID0gTG9uZ1Byb3RvdHlwZS5ub3RFcXVhbHM7XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIHRoZSBzcGVjaWZpZWQncy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmxlc3NUaGFuID0gZnVuY3Rpb24gbGVzc1RoYW4ob3RoZXIpIHtcbiAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpIDwgMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNsZXNzVGhhbn0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmx0ID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbjtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubGVzc1RoYW5PckVxdWFsID0gZnVuY3Rpb24gbGVzc1RoYW5PckVxdWFsKG90aGVyKSB7XG4gIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA8PSAwO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2xlc3NUaGFuT3JFcXVhbH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmx0ZSA9IExvbmdQcm90b3R5cGUubGVzc1RoYW5PckVxdWFsO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbGVzc1RoYW5PckVxdWFsfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubGUgPSBMb25nUHJvdG90eXBlLmxlc3NUaGFuT3JFcXVhbDtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gdGhlIHNwZWNpZmllZCdzLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW4gPSBmdW5jdGlvbiBncmVhdGVyVGhhbihvdGhlcikge1xuICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPiAwO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2dyZWF0ZXJUaGFufS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuZ3QgPSBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWwgPSBmdW5jdGlvbiBncmVhdGVyVGhhbk9yRXF1YWwob3RoZXIpIHtcbiAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpID49IDA7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW5PckVxdWFsfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuZ3RlID0gTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWw7XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNncmVhdGVyVGhhbk9yRXF1YWx9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5nZSA9IExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW5PckVxdWFsO1xuXG4vKipcbiAqIENvbXBhcmVzIHRoaXMgTG9uZydzIHZhbHVlIHdpdGggdGhlIHNwZWNpZmllZCdzLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge251bWJlcn0gMCBpZiB0aGV5IGFyZSB0aGUgc2FtZSwgMSBpZiB0aGUgdGhpcyBpcyBncmVhdGVyIGFuZCAtMVxuICogIGlmIHRoZSBnaXZlbiBvbmUgaXMgZ3JlYXRlclxuICovXG5Mb25nUHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlKG90aGVyKSB7XG4gIGlmICghaXNMb25nKG90aGVyKSlcbiAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XG4gIGlmICh0aGlzLmVxKG90aGVyKSlcbiAgICByZXR1cm4gMDtcbiAgdmFyIHRoaXNOZWcgPSB0aGlzLmlzTmVnYXRpdmUoKSxcbiAgICBvdGhlck5lZyA9IG90aGVyLmlzTmVnYXRpdmUoKTtcbiAgaWYgKHRoaXNOZWcgJiYgIW90aGVyTmVnKVxuICAgIHJldHVybiAtMTtcbiAgaWYgKCF0aGlzTmVnICYmIG90aGVyTmVnKVxuICAgIHJldHVybiAxO1xuICAvLyBBdCB0aGlzIHBvaW50IHRoZSBzaWduIGJpdHMgYXJlIHRoZSBzYW1lXG4gIGlmICghdGhpcy51bnNpZ25lZClcbiAgICByZXR1cm4gdGhpcy5zdWIob3RoZXIpLmlzTmVnYXRpdmUoKSA/IC0xIDogMTtcbiAgLy8gQm90aCBhcmUgcG9zaXRpdmUgaWYgYXQgbGVhc3Qgb25lIGlzIHVuc2lnbmVkXG4gIHJldHVybiAob3RoZXIuaGlnaCA+Pj4gMCkgPiAodGhpcy5oaWdoID4+PiAwKSB8fCAob3RoZXIuaGlnaCA9PT0gdGhpcy5oaWdoICYmIChvdGhlci5sb3cgPj4+IDApID4gKHRoaXMubG93ID4+PiAwKSkgPyAtMSA6IDE7XG59O1xuXG4vKipcbiAqIENvbXBhcmVzIHRoaXMgTG9uZydzIHZhbHVlIHdpdGggdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2NvbXBhcmV9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7bnVtYmVyfSAwIGlmIHRoZXkgYXJlIHRoZSBzYW1lLCAxIGlmIHRoZSB0aGlzIGlzIGdyZWF0ZXIgYW5kIC0xXG4gKiAgaWYgdGhlIGdpdmVuIG9uZSBpcyBncmVhdGVyXG4gKi9cbkxvbmdQcm90b3R5cGUuY29tcCA9IExvbmdQcm90b3R5cGUuY29tcGFyZTtcblxuLyoqXG4gKiBOZWdhdGVzIHRoaXMgTG9uZydzIHZhbHVlLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFMb25nfSBOZWdhdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5uZWdhdGUgPSBmdW5jdGlvbiBuZWdhdGUoKSB7XG4gIGlmICghdGhpcy51bnNpZ25lZCAmJiB0aGlzLmVxKE1JTl9WQUxVRSkpXG4gICAgcmV0dXJuIE1JTl9WQUxVRTtcbiAgcmV0dXJuIHRoaXMubm90KCkuYWRkKE9ORSk7XG59O1xuXG4vKipcbiAqIE5lZ2F0ZXMgdGhpcyBMb25nJ3MgdmFsdWUuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbmVnYXRlfS5cbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMgeyFMb25nfSBOZWdhdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5uZWcgPSBMb25nUHJvdG90eXBlLm5lZ2F0ZTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzdW0gb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBhZGRlbmQgQWRkZW5kXG4gKiBAcmV0dXJucyB7IUxvbmd9IFN1bVxuICovXG5Mb25nUHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZChhZGRlbmQpIHtcbiAgaWYgKCFpc0xvbmcoYWRkZW5kKSlcbiAgICBhZGRlbmQgPSBmcm9tVmFsdWUoYWRkZW5kKTtcblxuICAvLyBEaXZpZGUgZWFjaCBudW1iZXIgaW50byA0IGNodW5rcyBvZiAxNiBiaXRzLCBhbmQgdGhlbiBzdW0gdGhlIGNodW5rcy5cblxuICB2YXIgYTQ4ID0gdGhpcy5oaWdoID4+PiAxNjtcbiAgdmFyIGEzMiA9IHRoaXMuaGlnaCAmIDB4RkZGRjtcbiAgdmFyIGExNiA9IHRoaXMubG93ID4+PiAxNjtcbiAgdmFyIGEwMCA9IHRoaXMubG93ICYgMHhGRkZGO1xuXG4gIHZhciBiNDggPSBhZGRlbmQuaGlnaCA+Pj4gMTY7XG4gIHZhciBiMzIgPSBhZGRlbmQuaGlnaCAmIDB4RkZGRjtcbiAgdmFyIGIxNiA9IGFkZGVuZC5sb3cgPj4+IDE2O1xuICB2YXIgYjAwID0gYWRkZW5kLmxvdyAmIDB4RkZGRjtcblxuICB2YXIgYzQ4ID0gMCwgYzMyID0gMCwgYzE2ID0gMCwgYzAwID0gMDtcbiAgYzAwICs9IGEwMCArIGIwMDtcbiAgYzE2ICs9IGMwMCA+Pj4gMTY7XG4gIGMwMCAmPSAweEZGRkY7XG4gIGMxNiArPSBhMTYgKyBiMTY7XG4gIGMzMiArPSBjMTYgPj4+IDE2O1xuICBjMTYgJj0gMHhGRkZGO1xuICBjMzIgKz0gYTMyICsgYjMyO1xuICBjNDggKz0gYzMyID4+PiAxNjtcbiAgYzMyICY9IDB4RkZGRjtcbiAgYzQ4ICs9IGE0OCArIGI0ODtcbiAgYzQ4ICY9IDB4RkZGRjtcbiAgcmV0dXJuIGZyb21CaXRzKChjMTYgPDwgMTYpIHwgYzAwLCAoYzQ4IDw8IDE2KSB8IGMzMiwgdGhpcy51bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGRpZmZlcmVuY2Ugb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBzdWJ0cmFoZW5kIFN1YnRyYWhlbmRcbiAqIEByZXR1cm5zIHshTG9uZ30gRGlmZmVyZW5jZVxuICovXG5Mb25nUHJvdG90eXBlLnN1YnRyYWN0ID0gZnVuY3Rpb24gc3VidHJhY3Qoc3VidHJhaGVuZCkge1xuICBpZiAoIWlzTG9uZyhzdWJ0cmFoZW5kKSlcbiAgICBzdWJ0cmFoZW5kID0gZnJvbVZhbHVlKHN1YnRyYWhlbmQpO1xuICByZXR1cm4gdGhpcy5hZGQoc3VidHJhaGVuZC5uZWcoKSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGRpZmZlcmVuY2Ugb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3N1YnRyYWN0fS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBzdWJ0cmFoZW5kIFN1YnRyYWhlbmRcbiAqIEByZXR1cm5zIHshTG9uZ30gRGlmZmVyZW5jZVxuICovXG5Mb25nUHJvdG90eXBlLnN1YiA9IExvbmdQcm90b3R5cGUuc3VidHJhY3Q7XG5cbi8qKlxuICogUmV0dXJucyB0aGUgcHJvZHVjdCBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG11bHRpcGxpZXIgTXVsdGlwbGllclxuICogQHJldHVybnMgeyFMb25nfSBQcm9kdWN0XG4gKi9cbkxvbmdQcm90b3R5cGUubXVsdGlwbHkgPSBmdW5jdGlvbiBtdWx0aXBseShtdWx0aXBsaWVyKSB7XG4gIGlmICh0aGlzLmlzWmVybygpKVxuICAgIHJldHVybiB0aGlzO1xuICBpZiAoIWlzTG9uZyhtdWx0aXBsaWVyKSlcbiAgICBtdWx0aXBsaWVyID0gZnJvbVZhbHVlKG11bHRpcGxpZXIpO1xuXG4gIC8vIHVzZSB3YXNtIHN1cHBvcnQgaWYgcHJlc2VudFxuICBpZiAod2FzbSkge1xuICAgIHZhciBsb3cgPSB3YXNtW1wibXVsXCJdKHRoaXMubG93LFxuICAgICAgdGhpcy5oaWdoLFxuICAgICAgbXVsdGlwbGllci5sb3csXG4gICAgICBtdWx0aXBsaWVyLmhpZ2gpO1xuICAgIHJldHVybiBmcm9tQml0cyhsb3csIHdhc21bXCJnZXRfaGlnaFwiXSgpLCB0aGlzLnVuc2lnbmVkKTtcbiAgfVxuXG4gIGlmIChtdWx0aXBsaWVyLmlzWmVybygpKVxuICAgIHJldHVybiB0aGlzLnVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xuICBpZiAodGhpcy5lcShNSU5fVkFMVUUpKVxuICAgIHJldHVybiBtdWx0aXBsaWVyLmlzT2RkKCkgPyBNSU5fVkFMVUUgOiBaRVJPO1xuICBpZiAobXVsdGlwbGllci5lcShNSU5fVkFMVUUpKVxuICAgIHJldHVybiB0aGlzLmlzT2RkKCkgPyBNSU5fVkFMVUUgOiBaRVJPO1xuXG4gIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkge1xuICAgIGlmIChtdWx0aXBsaWVyLmlzTmVnYXRpdmUoKSlcbiAgICAgIHJldHVybiB0aGlzLm5lZygpLm11bChtdWx0aXBsaWVyLm5lZygpKTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gdGhpcy5uZWcoKS5tdWwobXVsdGlwbGllcikubmVnKCk7XG4gIH0gZWxzZSBpZiAobXVsdGlwbGllci5pc05lZ2F0aXZlKCkpXG4gICAgcmV0dXJuIHRoaXMubXVsKG11bHRpcGxpZXIubmVnKCkpLm5lZygpO1xuXG4gIC8vIElmIGJvdGggbG9uZ3MgYXJlIHNtYWxsLCB1c2UgZmxvYXQgbXVsdGlwbGljYXRpb25cbiAgaWYgKHRoaXMubHQoVFdPX1BXUl8yNCkgJiYgbXVsdGlwbGllci5sdChUV09fUFdSXzI0KSlcbiAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLnRvTnVtYmVyKCkgKiBtdWx0aXBsaWVyLnRvTnVtYmVyKCksIHRoaXMudW5zaWduZWQpO1xuXG4gIC8vIERpdmlkZSBlYWNoIGxvbmcgaW50byA0IGNodW5rcyBvZiAxNiBiaXRzLCBhbmQgdGhlbiBhZGQgdXAgNHg0IHByb2R1Y3RzLlxuICAvLyBXZSBjYW4gc2tpcCBwcm9kdWN0cyB0aGF0IHdvdWxkIG92ZXJmbG93LlxuXG4gIHZhciBhNDggPSB0aGlzLmhpZ2ggPj4+IDE2O1xuICB2YXIgYTMyID0gdGhpcy5oaWdoICYgMHhGRkZGO1xuICB2YXIgYTE2ID0gdGhpcy5sb3cgPj4+IDE2O1xuICB2YXIgYTAwID0gdGhpcy5sb3cgJiAweEZGRkY7XG5cbiAgdmFyIGI0OCA9IG11bHRpcGxpZXIuaGlnaCA+Pj4gMTY7XG4gIHZhciBiMzIgPSBtdWx0aXBsaWVyLmhpZ2ggJiAweEZGRkY7XG4gIHZhciBiMTYgPSBtdWx0aXBsaWVyLmxvdyA+Pj4gMTY7XG4gIHZhciBiMDAgPSBtdWx0aXBsaWVyLmxvdyAmIDB4RkZGRjtcblxuICB2YXIgYzQ4ID0gMCwgYzMyID0gMCwgYzE2ID0gMCwgYzAwID0gMDtcbiAgYzAwICs9IGEwMCAqIGIwMDtcbiAgYzE2ICs9IGMwMCA+Pj4gMTY7XG4gIGMwMCAmPSAweEZGRkY7XG4gIGMxNiArPSBhMTYgKiBiMDA7XG4gIGMzMiArPSBjMTYgPj4+IDE2O1xuICBjMTYgJj0gMHhGRkZGO1xuICBjMTYgKz0gYTAwICogYjE2O1xuICBjMzIgKz0gYzE2ID4+PiAxNjtcbiAgYzE2ICY9IDB4RkZGRjtcbiAgYzMyICs9IGEzMiAqIGIwMDtcbiAgYzQ4ICs9IGMzMiA+Pj4gMTY7XG4gIGMzMiAmPSAweEZGRkY7XG4gIGMzMiArPSBhMTYgKiBiMTY7XG4gIGM0OCArPSBjMzIgPj4+IDE2O1xuICBjMzIgJj0gMHhGRkZGO1xuICBjMzIgKz0gYTAwICogYjMyO1xuICBjNDggKz0gYzMyID4+PiAxNjtcbiAgYzMyICY9IDB4RkZGRjtcbiAgYzQ4ICs9IGE0OCAqIGIwMCArIGEzMiAqIGIxNiArIGExNiAqIGIzMiArIGEwMCAqIGI0ODtcbiAgYzQ4ICY9IDB4RkZGRjtcbiAgcmV0dXJuIGZyb21CaXRzKChjMTYgPDwgMTYpIHwgYzAwLCAoYzQ4IDw8IDE2KSB8IGMzMiwgdGhpcy51bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHByb2R1Y3Qgb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI211bHRpcGx5fS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBtdWx0aXBsaWVyIE11bHRpcGxpZXJcbiAqIEByZXR1cm5zIHshTG9uZ30gUHJvZHVjdFxuICovXG5Mb25nUHJvdG90eXBlLm11bCA9IExvbmdQcm90b3R5cGUubXVsdGlwbHk7XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgZGl2aWRlZCBieSB0aGUgc3BlY2lmaWVkLiBUaGUgcmVzdWx0IGlzIHNpZ25lZCBpZiB0aGlzIExvbmcgaXMgc2lnbmVkIG9yXG4gKiAgdW5zaWduZWQgaWYgdGhpcyBMb25nIGlzIHVuc2lnbmVkLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcbiAqIEByZXR1cm5zIHshTG9uZ30gUXVvdGllbnRcbiAqL1xuTG9uZ1Byb3RvdHlwZS5kaXZpZGUgPSBmdW5jdGlvbiBkaXZpZGUoZGl2aXNvcikge1xuICBpZiAoIWlzTG9uZyhkaXZpc29yKSlcbiAgICBkaXZpc29yID0gZnJvbVZhbHVlKGRpdmlzb3IpO1xuICBpZiAoZGl2aXNvci5pc1plcm8oKSlcbiAgICB0aHJvdyBFcnJvcignZGl2aXNpb24gYnkgemVybycpO1xuXG4gIC8vIHVzZSB3YXNtIHN1cHBvcnQgaWYgcHJlc2VudFxuICBpZiAod2FzbSkge1xuICAgIC8vIGd1YXJkIGFnYWluc3Qgc2lnbmVkIGRpdmlzaW9uIG92ZXJmbG93OiB0aGUgbGFyZ2VzdFxuICAgIC8vIG5lZ2F0aXZlIG51bWJlciAvIC0xIHdvdWxkIGJlIDEgbGFyZ2VyIHRoYW4gdGhlIGxhcmdlc3RcbiAgICAvLyBwb3NpdGl2ZSBudW1iZXIsIGR1ZSB0byB0d28ncyBjb21wbGVtZW50LlxuICAgIGlmICghdGhpcy51bnNpZ25lZCAmJlxuICAgICAgdGhpcy5oaWdoID09PSAtMHg4MDAwMDAwMCAmJlxuICAgICAgZGl2aXNvci5sb3cgPT09IC0xICYmIGRpdmlzb3IuaGlnaCA9PT0gLTEpIHtcbiAgICAgIC8vIGJlIGNvbnNpc3RlbnQgd2l0aCBub24td2FzbSBjb2RlIHBhdGhcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICB2YXIgbG93ID0gKHRoaXMudW5zaWduZWQgPyB3YXNtW1wiZGl2X3VcIl0gOiB3YXNtW1wiZGl2X3NcIl0pKFxuICAgICAgdGhpcy5sb3csXG4gICAgICB0aGlzLmhpZ2gsXG4gICAgICBkaXZpc29yLmxvdyxcbiAgICAgIGRpdmlzb3IuaGlnaFxuICAgICk7XG4gICAgcmV0dXJuIGZyb21CaXRzKGxvdywgd2FzbVtcImdldF9oaWdoXCJdKCksIHRoaXMudW5zaWduZWQpO1xuICB9XG5cbiAgaWYgKHRoaXMuaXNaZXJvKCkpXG4gICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XG4gIHZhciBhcHByb3gsIHJlbSwgcmVzO1xuICBpZiAoIXRoaXMudW5zaWduZWQpIHtcbiAgICAvLyBUaGlzIHNlY3Rpb24gaXMgb25seSByZWxldmFudCBmb3Igc2lnbmVkIGxvbmdzIGFuZCBpcyBkZXJpdmVkIGZyb20gdGhlXG4gICAgLy8gY2xvc3VyZSBsaWJyYXJ5IGFzIGEgd2hvbGUuXG4gICAgaWYgKHRoaXMuZXEoTUlOX1ZBTFVFKSkge1xuICAgICAgaWYgKGRpdmlzb3IuZXEoT05FKSB8fCBkaXZpc29yLmVxKE5FR19PTkUpKVxuICAgICAgICByZXR1cm4gTUlOX1ZBTFVFOyAgLy8gcmVjYWxsIHRoYXQgLU1JTl9WQUxVRSA9PSBNSU5fVkFMVUVcbiAgICAgIGVsc2UgaWYgKGRpdmlzb3IuZXEoTUlOX1ZBTFVFKSlcbiAgICAgICAgcmV0dXJuIE9ORTtcbiAgICAgIGVsc2Uge1xuICAgICAgICAvLyBBdCB0aGlzIHBvaW50LCB3ZSBoYXZlIHxvdGhlcnwgPj0gMiwgc28gfHRoaXMvb3RoZXJ8IDwgfE1JTl9WQUxVRXwuXG4gICAgICAgIHZhciBoYWxmVGhpcyA9IHRoaXMuc2hyKDEpO1xuICAgICAgICBhcHByb3ggPSBoYWxmVGhpcy5kaXYoZGl2aXNvcikuc2hsKDEpO1xuICAgICAgICBpZiAoYXBwcm94LmVxKFpFUk8pKSB7XG4gICAgICAgICAgcmV0dXJuIGRpdmlzb3IuaXNOZWdhdGl2ZSgpID8gT05FIDogTkVHX09ORTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZW0gPSB0aGlzLnN1YihkaXZpc29yLm11bChhcHByb3gpKTtcbiAgICAgICAgICByZXMgPSBhcHByb3guYWRkKHJlbS5kaXYoZGl2aXNvcikpO1xuICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGRpdmlzb3IuZXEoTUlOX1ZBTFVFKSlcbiAgICAgIHJldHVybiB0aGlzLnVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xuICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkge1xuICAgICAgaWYgKGRpdmlzb3IuaXNOZWdhdGl2ZSgpKVxuICAgICAgICByZXR1cm4gdGhpcy5uZWcoKS5kaXYoZGl2aXNvci5uZWcoKSk7XG4gICAgICByZXR1cm4gdGhpcy5uZWcoKS5kaXYoZGl2aXNvcikubmVnKCk7XG4gICAgfSBlbHNlIGlmIChkaXZpc29yLmlzTmVnYXRpdmUoKSlcbiAgICAgIHJldHVybiB0aGlzLmRpdihkaXZpc29yLm5lZygpKS5uZWcoKTtcbiAgICByZXMgPSBaRVJPO1xuICB9IGVsc2Uge1xuICAgIC8vIFRoZSBhbGdvcml0aG0gYmVsb3cgaGFzIG5vdCBiZWVuIG1hZGUgZm9yIHVuc2lnbmVkIGxvbmdzLiBJdCdzIHRoZXJlZm9yZVxuICAgIC8vIHJlcXVpcmVkIHRvIHRha2Ugc3BlY2lhbCBjYXJlIG9mIHRoZSBNU0IgcHJpb3IgdG8gcnVubmluZyBpdC5cbiAgICBpZiAoIWRpdmlzb3IudW5zaWduZWQpXG4gICAgICBkaXZpc29yID0gZGl2aXNvci50b1Vuc2lnbmVkKCk7XG4gICAgaWYgKGRpdmlzb3IuZ3QodGhpcykpXG4gICAgICByZXR1cm4gVVpFUk87XG4gICAgaWYgKGRpdmlzb3IuZ3QodGhpcy5zaHJ1KDEpKSkgLy8gMTUgPj4+IDEgPSA3IDsgd2l0aCBkaXZpc29yID0gOCA7IHRydWVcbiAgICAgIHJldHVybiBVT05FO1xuICAgIHJlcyA9IFVaRVJPO1xuICB9XG5cbiAgLy8gUmVwZWF0IHRoZSBmb2xsb3dpbmcgdW50aWwgdGhlIHJlbWFpbmRlciBpcyBsZXNzIHRoYW4gb3RoZXI6ICBmaW5kIGFcbiAgLy8gZmxvYXRpbmctcG9pbnQgdGhhdCBhcHByb3hpbWF0ZXMgcmVtYWluZGVyIC8gb3RoZXIgKmZyb20gYmVsb3cqLCBhZGQgdGhpc1xuICAvLyBpbnRvIHRoZSByZXN1bHQsIGFuZCBzdWJ0cmFjdCBpdCBmcm9tIHRoZSByZW1haW5kZXIuICBJdCBpcyBjcml0aWNhbCB0aGF0XG4gIC8vIHRoZSBhcHByb3hpbWF0ZSB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHJlYWwgdmFsdWUgc28gdGhhdCB0aGVcbiAgLy8gcmVtYWluZGVyIG5ldmVyIGJlY29tZXMgbmVnYXRpdmUuXG4gIHJlbSA9IHRoaXM7XG4gIHdoaWxlIChyZW0uZ3RlKGRpdmlzb3IpKSB7XG4gICAgLy8gQXBwcm94aW1hdGUgdGhlIHJlc3VsdCBvZiBkaXZpc2lvbi4gVGhpcyBtYXkgYmUgYSBsaXR0bGUgZ3JlYXRlciBvclxuICAgIC8vIHNtYWxsZXIgdGhhbiB0aGUgYWN0dWFsIHZhbHVlLlxuICAgIGFwcHJveCA9IE1hdGgubWF4KDEsIE1hdGguZmxvb3IocmVtLnRvTnVtYmVyKCkgLyBkaXZpc29yLnRvTnVtYmVyKCkpKTtcblxuICAgIC8vIFdlIHdpbGwgdHdlYWsgdGhlIGFwcHJveGltYXRlIHJlc3VsdCBieSBjaGFuZ2luZyBpdCBpbiB0aGUgNDgtdGggZGlnaXQgb3JcbiAgICAvLyB0aGUgc21hbGxlc3Qgbm9uLWZyYWN0aW9uYWwgZGlnaXQsIHdoaWNoZXZlciBpcyBsYXJnZXIuXG4gICAgdmFyIGxvZzIgPSBNYXRoLmNlaWwoTWF0aC5sb2coYXBwcm94KSAvIE1hdGguTE4yKSxcbiAgICAgIGRlbHRhID0gKGxvZzIgPD0gNDgpID8gMSA6IHBvd19kYmwoMiwgbG9nMiAtIDQ4KSxcblxuICAgICAgLy8gRGVjcmVhc2UgdGhlIGFwcHJveGltYXRpb24gdW50aWwgaXQgaXMgc21hbGxlciB0aGFuIHRoZSByZW1haW5kZXIuICBOb3RlXG4gICAgICAvLyB0aGF0IGlmIGl0IGlzIHRvbyBsYXJnZSwgdGhlIHByb2R1Y3Qgb3ZlcmZsb3dzIGFuZCBpcyBuZWdhdGl2ZS5cbiAgICAgIGFwcHJveFJlcyA9IGZyb21OdW1iZXIoYXBwcm94KSxcbiAgICAgIGFwcHJveFJlbSA9IGFwcHJveFJlcy5tdWwoZGl2aXNvcik7XG4gICAgd2hpbGUgKGFwcHJveFJlbS5pc05lZ2F0aXZlKCkgfHwgYXBwcm94UmVtLmd0KHJlbSkpIHtcbiAgICAgIGFwcHJveCAtPSBkZWx0YTtcbiAgICAgIGFwcHJveFJlcyA9IGZyb21OdW1iZXIoYXBwcm94LCB0aGlzLnVuc2lnbmVkKTtcbiAgICAgIGFwcHJveFJlbSA9IGFwcHJveFJlcy5tdWwoZGl2aXNvcik7XG4gICAgfVxuXG4gICAgLy8gV2Uga25vdyB0aGUgYW5zd2VyIGNhbid0IGJlIHplcm8uLi4gYW5kIGFjdHVhbGx5LCB6ZXJvIHdvdWxkIGNhdXNlXG4gICAgLy8gaW5maW5pdGUgcmVjdXJzaW9uIHNpbmNlIHdlIHdvdWxkIG1ha2Ugbm8gcHJvZ3Jlc3MuXG4gICAgaWYgKGFwcHJveFJlcy5pc1plcm8oKSlcbiAgICAgIGFwcHJveFJlcyA9IE9ORTtcblxuICAgIHJlcyA9IHJlcy5hZGQoYXBwcm94UmVzKTtcbiAgICByZW0gPSByZW0uc3ViKGFwcHJveFJlbSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgZGl2aWRlZCBieSB0aGUgc3BlY2lmaWVkLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2RpdmlkZX0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXG4gKiBAcmV0dXJucyB7IUxvbmd9IFF1b3RpZW50XG4gKi9cbkxvbmdQcm90b3R5cGUuZGl2ID0gTG9uZ1Byb3RvdHlwZS5kaXZpZGU7XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgbW9kdWxvIHRoZSBzcGVjaWZpZWQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxuICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcbiAqL1xuTG9uZ1Byb3RvdHlwZS5tb2R1bG8gPSBmdW5jdGlvbiBtb2R1bG8oZGl2aXNvcikge1xuICBpZiAoIWlzTG9uZyhkaXZpc29yKSlcbiAgICBkaXZpc29yID0gZnJvbVZhbHVlKGRpdmlzb3IpO1xuXG4gIC8vIHVzZSB3YXNtIHN1cHBvcnQgaWYgcHJlc2VudFxuICBpZiAod2FzbSkge1xuICAgIHZhciBsb3cgPSAodGhpcy51bnNpZ25lZCA/IHdhc21bXCJyZW1fdVwiXSA6IHdhc21bXCJyZW1fc1wiXSkoXG4gICAgICB0aGlzLmxvdyxcbiAgICAgIHRoaXMuaGlnaCxcbiAgICAgIGRpdmlzb3IubG93LFxuICAgICAgZGl2aXNvci5oaWdoXG4gICAgKTtcbiAgICByZXR1cm4gZnJvbUJpdHMobG93LCB3YXNtW1wiZ2V0X2hpZ2hcIl0oKSwgdGhpcy51bnNpZ25lZCk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5zdWIodGhpcy5kaXYoZGl2aXNvcikubXVsKGRpdmlzb3IpKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgbW9kdWxvIHRoZSBzcGVjaWZpZWQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbW9kdWxvfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcbiAqIEByZXR1cm5zIHshTG9uZ30gUmVtYWluZGVyXG4gKi9cbkxvbmdQcm90b3R5cGUubW9kID0gTG9uZ1Byb3RvdHlwZS5tb2R1bG87XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgbW9kdWxvIHRoZSBzcGVjaWZpZWQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbW9kdWxvfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcbiAqIEByZXR1cm5zIHshTG9uZ30gUmVtYWluZGVyXG4gKi9cbkxvbmdQcm90b3R5cGUucmVtID0gTG9uZ1Byb3RvdHlwZS5tb2R1bG87XG5cbi8qKlxuICogUmV0dXJucyB0aGUgYml0d2lzZSBOT1Qgb2YgdGhpcyBMb25nLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFMb25nfVxuICovXG5Mb25nUHJvdG90eXBlLm5vdCA9IGZ1bmN0aW9uIG5vdCgpIHtcbiAgcmV0dXJuIGZyb21CaXRzKH50aGlzLmxvdywgfnRoaXMuaGlnaCwgdGhpcy51bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgY291bnQgbGVhZGluZyB6ZXJvcyBvZiB0aGlzIExvbmcuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IW51bWJlcn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5jb3VudExlYWRpbmdaZXJvcyA9IGZ1bmN0aW9uIGNvdW50TGVhZGluZ1plcm9zKCkge1xuICByZXR1cm4gdGhpcy5oaWdoID8gTWF0aC5jbHozMih0aGlzLmhpZ2gpIDogTWF0aC5jbHozMih0aGlzLmxvdykgKyAzMjtcbn07XG5cbi8qKlxuICogUmV0dXJucyBjb3VudCBsZWFkaW5nIHplcm9zLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2NvdW50TGVhZGluZ1plcm9zfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ31cbiAqIEByZXR1cm5zIHshbnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLmNseiA9IExvbmdQcm90b3R5cGUuY291bnRMZWFkaW5nWmVyb3M7XG5cbi8qKlxuICogUmV0dXJucyBjb3VudCB0cmFpbGluZyB6ZXJvcyBvZiB0aGlzIExvbmcuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IW51bWJlcn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5jb3VudFRyYWlsaW5nWmVyb3MgPSBmdW5jdGlvbiBjb3VudFRyYWlsaW5nWmVyb3MoKSB7XG4gIHJldHVybiB0aGlzLmxvdyA/IGN0ejMyKHRoaXMubG93KSA6IGN0ejMyKHRoaXMuaGlnaCkgKyAzMjtcbn07XG5cbi8qKlxuICogUmV0dXJucyBjb3VudCB0cmFpbGluZyB6ZXJvcy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNjb3VudFRyYWlsaW5nWmVyb3N9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfVxuICogQHJldHVybnMgeyFudW1iZXJ9XG4gKi9cbkxvbmdQcm90b3R5cGUuY3R6ID0gTG9uZ1Byb3RvdHlwZS5jb3VudFRyYWlsaW5nWmVyb3M7XG5cbi8qKlxuICogUmV0dXJucyB0aGUgYml0d2lzZSBBTkQgb2YgdGhpcyBMb25nIGFuZCB0aGUgc3BlY2lmaWVkLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciBMb25nXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKi9cbkxvbmdQcm90b3R5cGUuYW5kID0gZnVuY3Rpb24gYW5kKG90aGVyKSB7XG4gIGlmICghaXNMb25nKG90aGVyKSlcbiAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XG4gIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdyAmIG90aGVyLmxvdywgdGhpcy5oaWdoICYgb3RoZXIuaGlnaCwgdGhpcy51bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGJpdHdpc2UgT1Igb2YgdGhpcyBMb25nIGFuZCB0aGUgc3BlY2lmaWVkLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciBMb25nXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKi9cbkxvbmdQcm90b3R5cGUub3IgPSBmdW5jdGlvbiBvcihvdGhlcikge1xuICBpZiAoIWlzTG9uZyhvdGhlcikpXG4gICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xuICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgfCBvdGhlci5sb3csIHRoaXMuaGlnaCB8IG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBiaXR3aXNlIFhPUiBvZiB0aGlzIExvbmcgYW5kIHRoZSBnaXZlbiBvbmUuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqL1xuTG9uZ1Byb3RvdHlwZS54b3IgPSBmdW5jdGlvbiB4b3Iob3RoZXIpIHtcbiAgaWYgKCFpc0xvbmcob3RoZXIpKVxuICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcbiAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93IF4gb3RoZXIubG93LCB0aGlzLmhpZ2ggXiBvdGhlci5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHNoaWZ0ZWQgdG8gdGhlIGxlZnQgYnkgdGhlIGdpdmVuIGFtb3VudC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnNoaWZ0TGVmdCA9IGZ1bmN0aW9uIHNoaWZ0TGVmdChudW1CaXRzKSB7XG4gIGlmIChpc0xvbmcobnVtQml0cykpXG4gICAgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcbiAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMClcbiAgICByZXR1cm4gdGhpcztcbiAgZWxzZSBpZiAobnVtQml0cyA8IDMyKVxuICAgIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdyA8PCBudW1CaXRzLCAodGhpcy5oaWdoIDw8IG51bUJpdHMpIHwgKHRoaXMubG93ID4+PiAoMzIgLSBudW1CaXRzKSksIHRoaXMudW5zaWduZWQpO1xuICBlbHNlXG4gICAgcmV0dXJuIGZyb21CaXRzKDAsIHRoaXMubG93IDw8IChudW1CaXRzIC0gMzIpLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHNoaWZ0ZWQgdG8gdGhlIGxlZnQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdExlZnR9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5zaGwgPSBMb25nUHJvdG90eXBlLnNoaWZ0TGVmdDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgYXJpdGhtZXRpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnNoaWZ0UmlnaHQgPSBmdW5jdGlvbiBzaGlmdFJpZ2h0KG51bUJpdHMpIHtcbiAgaWYgKGlzTG9uZyhudW1CaXRzKSlcbiAgICBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xuICBpZiAoKG51bUJpdHMgJj0gNjMpID09PSAwKVxuICAgIHJldHVybiB0aGlzO1xuICBlbHNlIGlmIChudW1CaXRzIDwgMzIpXG4gICAgcmV0dXJuIGZyb21CaXRzKCh0aGlzLmxvdyA+Pj4gbnVtQml0cykgfCAodGhpcy5oaWdoIDw8ICgzMiAtIG51bUJpdHMpKSwgdGhpcy5oaWdoID4+IG51bUJpdHMsIHRoaXMudW5zaWduZWQpO1xuICBlbHNlXG4gICAgcmV0dXJuIGZyb21CaXRzKHRoaXMuaGlnaCA+PiAobnVtQml0cyAtIDMyKSwgdGhpcy5oaWdoID49IDAgPyAwIDogLTEsIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgYXJpdGhtZXRpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdFJpZ2h0fS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hyID0gTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBsb2dpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZCA9IGZ1bmN0aW9uIHNoaWZ0UmlnaHRVbnNpZ25lZChudW1CaXRzKSB7XG4gIGlmIChpc0xvbmcobnVtQml0cykpIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XG4gIGlmICgobnVtQml0cyAmPSA2MykgPT09IDApIHJldHVybiB0aGlzO1xuICBpZiAobnVtQml0cyA8IDMyKSByZXR1cm4gZnJvbUJpdHMoKHRoaXMubG93ID4+PiBudW1CaXRzKSB8ICh0aGlzLmhpZ2ggPDwgKDMyIC0gbnVtQml0cykpLCB0aGlzLmhpZ2ggPj4+IG51bUJpdHMsIHRoaXMudW5zaWduZWQpO1xuICBpZiAobnVtQml0cyA9PT0gMzIpIHJldHVybiBmcm9tQml0cyh0aGlzLmhpZ2gsIDAsIHRoaXMudW5zaWduZWQpO1xuICByZXR1cm4gZnJvbUJpdHModGhpcy5oaWdoID4+PiAobnVtQml0cyAtIDMyKSwgMCwgdGhpcy51bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBsb2dpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdFJpZ2h0VW5zaWduZWR9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5zaHJ1ID0gTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQ7XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGxvZ2ljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3NoaWZ0UmlnaHRVbnNpZ25lZH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnNocl91ID0gTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQ7XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHJvdGF0ZWQgdG8gdGhlIGxlZnQgYnkgdGhlIGdpdmVuIGFtb3VudC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFJvdGF0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnJvdGF0ZUxlZnQgPSBmdW5jdGlvbiByb3RhdGVMZWZ0KG51bUJpdHMpIHtcbiAgdmFyIGI7XG4gIGlmIChpc0xvbmcobnVtQml0cykpIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XG4gIGlmICgobnVtQml0cyAmPSA2MykgPT09IDApIHJldHVybiB0aGlzO1xuICBpZiAobnVtQml0cyA9PT0gMzIpIHJldHVybiBmcm9tQml0cyh0aGlzLmhpZ2gsIHRoaXMubG93LCB0aGlzLnVuc2lnbmVkKTtcbiAgaWYgKG51bUJpdHMgPCAzMikge1xuICAgIGIgPSAoMzIgLSBudW1CaXRzKTtcbiAgICByZXR1cm4gZnJvbUJpdHMoKCh0aGlzLmxvdyA8PCBudW1CaXRzKSB8ICh0aGlzLmhpZ2ggPj4+IGIpKSwgKCh0aGlzLmhpZ2ggPDwgbnVtQml0cykgfCAodGhpcy5sb3cgPj4+IGIpKSwgdGhpcy51bnNpZ25lZCk7XG4gIH1cbiAgbnVtQml0cyAtPSAzMjtcbiAgYiA9ICgzMiAtIG51bUJpdHMpO1xuICByZXR1cm4gZnJvbUJpdHMoKCh0aGlzLmhpZ2ggPDwgbnVtQml0cykgfCAodGhpcy5sb3cgPj4+IGIpKSwgKCh0aGlzLmxvdyA8PCBudW1CaXRzKSB8ICh0aGlzLmhpZ2ggPj4+IGIpKSwgdGhpcy51bnNpZ25lZCk7XG59XG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyByb3RhdGVkIHRvIHRoZSBsZWZ0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjcm90YXRlTGVmdH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFJvdGF0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnJvdGwgPSBMb25nUHJvdG90eXBlLnJvdGF0ZUxlZnQ7XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHJvdGF0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBSb3RhdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5yb3RhdGVSaWdodCA9IGZ1bmN0aW9uIHJvdGF0ZVJpZ2h0KG51bUJpdHMpIHtcbiAgdmFyIGI7XG4gIGlmIChpc0xvbmcobnVtQml0cykpIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XG4gIGlmICgobnVtQml0cyAmPSA2MykgPT09IDApIHJldHVybiB0aGlzO1xuICBpZiAobnVtQml0cyA9PT0gMzIpIHJldHVybiBmcm9tQml0cyh0aGlzLmhpZ2gsIHRoaXMubG93LCB0aGlzLnVuc2lnbmVkKTtcbiAgaWYgKG51bUJpdHMgPCAzMikge1xuICAgIGIgPSAoMzIgLSBudW1CaXRzKTtcbiAgICByZXR1cm4gZnJvbUJpdHMoKCh0aGlzLmhpZ2ggPDwgYikgfCAodGhpcy5sb3cgPj4+IG51bUJpdHMpKSwgKCh0aGlzLmxvdyA8PCBiKSB8ICh0aGlzLmhpZ2ggPj4+IG51bUJpdHMpKSwgdGhpcy51bnNpZ25lZCk7XG4gIH1cbiAgbnVtQml0cyAtPSAzMjtcbiAgYiA9ICgzMiAtIG51bUJpdHMpO1xuICByZXR1cm4gZnJvbUJpdHMoKCh0aGlzLmxvdyA8PCBiKSB8ICh0aGlzLmhpZ2ggPj4+IG51bUJpdHMpKSwgKCh0aGlzLmhpZ2ggPDwgYikgfCAodGhpcy5sb3cgPj4+IG51bUJpdHMpKSwgdGhpcy51bnNpZ25lZCk7XG59XG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyByb3RhdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3JvdGF0ZVJpZ2h0fS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gUm90YXRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUucm90ciA9IExvbmdQcm90b3R5cGUucm90YXRlUmlnaHQ7XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBMb25nIHRvIHNpZ25lZC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshTG9uZ30gU2lnbmVkIGxvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS50b1NpZ25lZCA9IGZ1bmN0aW9uIHRvU2lnbmVkKCkge1xuICBpZiAoIXRoaXMudW5zaWduZWQpXG4gICAgcmV0dXJuIHRoaXM7XG4gIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdywgdGhpcy5oaWdoLCBmYWxzZSk7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byB1bnNpZ25lZC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshTG9uZ30gVW5zaWduZWQgbG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnRvVW5zaWduZWQgPSBmdW5jdGlvbiB0b1Vuc2lnbmVkKCkge1xuICBpZiAodGhpcy51bnNpZ25lZClcbiAgICByZXR1cm4gdGhpcztcbiAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93LCB0aGlzLmhpZ2gsIHRydWUpO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gaXRzIGJ5dGUgcmVwcmVzZW50YXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBsZSBXaGV0aGVyIGxpdHRsZSBvciBiaWcgZW5kaWFuLCBkZWZhdWx0cyB0byBiaWcgZW5kaWFuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBCeXRlIHJlcHJlc2VudGF0aW9uXG4gKi9cbkxvbmdQcm90b3R5cGUudG9CeXRlcyA9IGZ1bmN0aW9uIHRvQnl0ZXMobGUpIHtcbiAgcmV0dXJuIGxlID8gdGhpcy50b0J5dGVzTEUoKSA6IHRoaXMudG9CeXRlc0JFKCk7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byBpdHMgbGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gTGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXG4gKi9cbkxvbmdQcm90b3R5cGUudG9CeXRlc0xFID0gZnVuY3Rpb24gdG9CeXRlc0xFKCkge1xuICB2YXIgaGkgPSB0aGlzLmhpZ2gsXG4gICAgbG8gPSB0aGlzLmxvdztcbiAgcmV0dXJuIFtcbiAgICBsbyAmIDB4ZmYsXG4gICAgbG8gPj4+IDggJiAweGZmLFxuICAgIGxvID4+PiAxNiAmIDB4ZmYsXG4gICAgbG8gPj4+IDI0LFxuICAgIGhpICYgMHhmZixcbiAgICBoaSA+Pj4gOCAmIDB4ZmYsXG4gICAgaGkgPj4+IDE2ICYgMHhmZixcbiAgICBoaSA+Pj4gMjRcbiAgXTtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBiaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBCaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cbiAqL1xuTG9uZ1Byb3RvdHlwZS50b0J5dGVzQkUgPSBmdW5jdGlvbiB0b0J5dGVzQkUoKSB7XG4gIHZhciBoaSA9IHRoaXMuaGlnaCxcbiAgICBsbyA9IHRoaXMubG93O1xuICByZXR1cm4gW1xuICAgIGhpID4+PiAyNCxcbiAgICBoaSA+Pj4gMTYgJiAweGZmLFxuICAgIGhpID4+PiA4ICYgMHhmZixcbiAgICBoaSAmIDB4ZmYsXG4gICAgbG8gPj4+IDI0LFxuICAgIGxvID4+PiAxNiAmIDB4ZmYsXG4gICAgbG8gPj4+IDggJiAweGZmLFxuICAgIGxvICYgMHhmZlxuICBdO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgTG9uZyBmcm9tIGl0cyBieXRlIHJlcHJlc2VudGF0aW9uLlxuICogQHBhcmFtIHshQXJyYXkuPG51bWJlcj59IGJ5dGVzIEJ5dGUgcmVwcmVzZW50YXRpb25cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IGxlIFdoZXRoZXIgbGl0dGxlIG9yIGJpZyBlbmRpYW4sIGRlZmF1bHRzIHRvIGJpZyBlbmRpYW5cbiAqIEByZXR1cm5zIHtMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXG4gKi9cbkxvbmcuZnJvbUJ5dGVzID0gZnVuY3Rpb24gZnJvbUJ5dGVzKGJ5dGVzLCB1bnNpZ25lZCwgbGUpIHtcbiAgcmV0dXJuIGxlID8gTG9uZy5mcm9tQnl0ZXNMRShieXRlcywgdW5zaWduZWQpIDogTG9uZy5mcm9tQnl0ZXNCRShieXRlcywgdW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgTG9uZyBmcm9tIGl0cyBsaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXG4gKiBAcGFyYW0geyFBcnJheS48bnVtYmVyPn0gYnl0ZXMgTGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcmV0dXJucyB7TG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxuICovXG5Mb25nLmZyb21CeXRlc0xFID0gZnVuY3Rpb24gZnJvbUJ5dGVzTEUoYnl0ZXMsIHVuc2lnbmVkKSB7XG4gIHJldHVybiBuZXcgTG9uZyhcbiAgICBieXRlc1swXSB8XG4gICAgYnl0ZXNbMV0gPDwgOCB8XG4gICAgYnl0ZXNbMl0gPDwgMTYgfFxuICAgIGJ5dGVzWzNdIDw8IDI0LFxuICAgIGJ5dGVzWzRdIHxcbiAgICBieXRlc1s1XSA8PCA4IHxcbiAgICBieXRlc1s2XSA8PCAxNiB8XG4gICAgYnl0ZXNbN10gPDwgMjQsXG4gICAgdW5zaWduZWRcbiAgKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIExvbmcgZnJvbSBpdHMgYmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxuICogQHBhcmFtIHshQXJyYXkuPG51bWJlcj59IGJ5dGVzIEJpZyBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvblxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQHJldHVybnMge0xvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tQnl0ZXNCRSA9IGZ1bmN0aW9uIGZyb21CeXRlc0JFKGJ5dGVzLCB1bnNpZ25lZCkge1xuICByZXR1cm4gbmV3IExvbmcoXG4gICAgYnl0ZXNbNF0gPDwgMjQgfFxuICAgIGJ5dGVzWzVdIDw8IDE2IHxcbiAgICBieXRlc1s2XSA8PCA4IHxcbiAgICBieXRlc1s3XSxcbiAgICBieXRlc1swXSA8PCAyNCB8XG4gICAgYnl0ZXNbMV0gPDwgMTYgfFxuICAgIGJ5dGVzWzJdIDw8IDggfFxuICAgIGJ5dGVzWzNdLFxuICAgIHVuc2lnbmVkXG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBMb25nO1xuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuZXhwb3J0IGVudW0gQXJnVHlwZSB7XG4gIElOUFVUID0gMCxcbiAgT1VUUFVUID0gMSxcbn1cbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuU0laRV9QUkVGSVhfTEVOR1RIID0gZXhwb3J0cy5GSUxFX0lERU5USUZJRVJfTEVOR1RIID0gZXhwb3J0cy5TSVpFT0ZfSU5UID0gZXhwb3J0cy5TSVpFT0ZfU0hPUlQgPSB2b2lkIDA7XG5leHBvcnRzLlNJWkVPRl9TSE9SVCA9IDI7XG5leHBvcnRzLlNJWkVPRl9JTlQgPSA0O1xuZXhwb3J0cy5GSUxFX0lERU5USUZJRVJfTEVOR1RIID0gNDtcbmV4cG9ydHMuU0laRV9QUkVGSVhfTEVOR1RIID0gNDtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuaXNMaXR0bGVFbmRpYW4gPSBleHBvcnRzLmZsb2F0NjQgPSBleHBvcnRzLmZsb2F0MzIgPSBleHBvcnRzLmludDMyID0gdm9pZCAwO1xuZXhwb3J0cy5pbnQzMiA9IG5ldyBJbnQzMkFycmF5KDIpO1xuZXhwb3J0cy5mbG9hdDMyID0gbmV3IEZsb2F0MzJBcnJheShleHBvcnRzLmludDMyLmJ1ZmZlcik7XG5leHBvcnRzLmZsb2F0NjQgPSBuZXcgRmxvYXQ2NEFycmF5KGV4cG9ydHMuaW50MzIuYnVmZmVyKTtcbmV4cG9ydHMuaXNMaXR0bGVFbmRpYW4gPSBuZXcgVWludDE2QXJyYXkobmV3IFVpbnQ4QXJyYXkoWzEsIDBdKS5idWZmZXIpWzBdID09PSAxO1xuIiwgIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5FbmNvZGluZyA9IHZvaWQgMDtcbnZhciBFbmNvZGluZztcbihmdW5jdGlvbiAoRW5jb2RpbmcpIHtcbiAgICBFbmNvZGluZ1tFbmNvZGluZ1tcIlVURjhfQllURVNcIl0gPSAxXSA9IFwiVVRGOF9CWVRFU1wiO1xuICAgIEVuY29kaW5nW0VuY29kaW5nW1wiVVRGMTZfU1RSSU5HXCJdID0gMl0gPSBcIlVURjE2X1NUUklOR1wiO1xufSkoRW5jb2RpbmcgfHwgKGV4cG9ydHMuRW5jb2RpbmcgPSBFbmNvZGluZyA9IHt9KSk7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkJ5dGVCdWZmZXIgPSB2b2lkIDA7XG5jb25zdCBjb25zdGFudHNfanNfMSA9IHJlcXVpcmUoXCIuL2NvbnN0YW50cy5qc1wiKTtcbmNvbnN0IHV0aWxzX2pzXzEgPSByZXF1aXJlKFwiLi91dGlscy5qc1wiKTtcbmNvbnN0IGVuY29kaW5nX2pzXzEgPSByZXF1aXJlKFwiLi9lbmNvZGluZy5qc1wiKTtcbmNsYXNzIEJ5dGVCdWZmZXIge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBCeXRlQnVmZmVyIHdpdGggYSBnaXZlbiBhcnJheSBvZiBieXRlcyAoYFVpbnQ4QXJyYXlgKVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGJ5dGVzXykge1xuICAgICAgICB0aGlzLmJ5dGVzXyA9IGJ5dGVzXztcbiAgICAgICAgdGhpcy5wb3NpdGlvbl8gPSAwO1xuICAgICAgICB0aGlzLnRleHRfZGVjb2Rlcl8gPSBuZXcgVGV4dERlY29kZXIoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuZCBhbGxvY2F0ZSBhIG5ldyBCeXRlQnVmZmVyIHdpdGggYSBnaXZlbiBzaXplLlxuICAgICAqL1xuICAgIHN0YXRpYyBhbGxvY2F0ZShieXRlX3NpemUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBCeXRlQnVmZmVyKG5ldyBVaW50OEFycmF5KGJ5dGVfc2l6ZSkpO1xuICAgIH1cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5wb3NpdGlvbl8gPSAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHVuZGVybHlpbmcgYFVpbnQ4QXJyYXlgLlxuICAgICAqL1xuICAgIGJ5dGVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ieXRlc187XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgYnVmZmVyJ3MgcG9zaXRpb24uXG4gICAgICovXG4gICAgcG9zaXRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uXztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBidWZmZXIncyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBzZXRQb3NpdGlvbihwb3NpdGlvbikge1xuICAgICAgICB0aGlzLnBvc2l0aW9uXyA9IHBvc2l0aW9uO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGJ1ZmZlcidzIGNhcGFjaXR5LlxuICAgICAqL1xuICAgIGNhcGFjaXR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ieXRlc18ubGVuZ3RoO1xuICAgIH1cbiAgICByZWFkSW50OChvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZFVpbnQ4KG9mZnNldCkgPDwgMjQgPj4gMjQ7XG4gICAgfVxuICAgIHJlYWRVaW50OChvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYnl0ZXNfW29mZnNldF07XG4gICAgfVxuICAgIHJlYWRJbnQxNihvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZFVpbnQxNihvZmZzZXQpIDw8IDE2ID4+IDE2O1xuICAgIH1cbiAgICByZWFkVWludDE2KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ieXRlc19bb2Zmc2V0XSB8IHRoaXMuYnl0ZXNfW29mZnNldCArIDFdIDw8IDg7XG4gICAgfVxuICAgIHJlYWRJbnQzMihvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYnl0ZXNfW29mZnNldF0gfCB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAxXSA8PCA4IHwgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMl0gPDwgMTYgfCB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAzXSA8PCAyNDtcbiAgICB9XG4gICAgcmVhZFVpbnQzMihvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZEludDMyKG9mZnNldCkgPj4+IDA7XG4gICAgfVxuICAgIHJlYWRJbnQ2NChvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIEJpZ0ludC5hc0ludE4oNjQsIEJpZ0ludCh0aGlzLnJlYWRVaW50MzIob2Zmc2V0KSkgKyAoQmlnSW50KHRoaXMucmVhZFVpbnQzMihvZmZzZXQgKyA0KSkgPDwgQmlnSW50KDMyKSkpO1xuICAgIH1cbiAgICByZWFkVWludDY0KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gQmlnSW50LmFzVWludE4oNjQsIEJpZ0ludCh0aGlzLnJlYWRVaW50MzIob2Zmc2V0KSkgKyAoQmlnSW50KHRoaXMucmVhZFVpbnQzMihvZmZzZXQgKyA0KSkgPDwgQmlnSW50KDMyKSkpO1xuICAgIH1cbiAgICByZWFkRmxvYXQzMihvZmZzZXQpIHtcbiAgICAgICAgdXRpbHNfanNfMS5pbnQzMlswXSA9IHRoaXMucmVhZEludDMyKG9mZnNldCk7XG4gICAgICAgIHJldHVybiB1dGlsc19qc18xLmZsb2F0MzJbMF07XG4gICAgfVxuICAgIHJlYWRGbG9hdDY0KG9mZnNldCkge1xuICAgICAgICB1dGlsc19qc18xLmludDMyW3V0aWxzX2pzXzEuaXNMaXR0bGVFbmRpYW4gPyAwIDogMV0gPSB0aGlzLnJlYWRJbnQzMihvZmZzZXQpO1xuICAgICAgICB1dGlsc19qc18xLmludDMyW3V0aWxzX2pzXzEuaXNMaXR0bGVFbmRpYW4gPyAxIDogMF0gPSB0aGlzLnJlYWRJbnQzMihvZmZzZXQgKyA0KTtcbiAgICAgICAgcmV0dXJuIHV0aWxzX2pzXzEuZmxvYXQ2NFswXTtcbiAgICB9XG4gICAgd3JpdGVJbnQ4KG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0XSA9IHZhbHVlO1xuICAgIH1cbiAgICB3cml0ZVVpbnQ4KG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0XSA9IHZhbHVlO1xuICAgIH1cbiAgICB3cml0ZUludDE2KG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0XSA9IHZhbHVlO1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAxXSA9IHZhbHVlID4+IDg7XG4gICAgfVxuICAgIHdyaXRlVWludDE2KG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0XSA9IHZhbHVlO1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAxXSA9IHZhbHVlID4+IDg7XG4gICAgfVxuICAgIHdyaXRlSW50MzIob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgICAgIHRoaXMuYnl0ZXNfW29mZnNldCArIDFdID0gdmFsdWUgPj4gODtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMl0gPSB2YWx1ZSA+PiAxNjtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgM10gPSB2YWx1ZSA+PiAyNDtcbiAgICB9XG4gICAgd3JpdGVVaW50MzIob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgICAgIHRoaXMuYnl0ZXNfW29mZnNldCArIDFdID0gdmFsdWUgPj4gODtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMl0gPSB2YWx1ZSA+PiAxNjtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgM10gPSB2YWx1ZSA+PiAyNDtcbiAgICB9XG4gICAgd3JpdGVJbnQ2NChvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMud3JpdGVJbnQzMihvZmZzZXQsIE51bWJlcihCaWdJbnQuYXNJbnROKDMyLCB2YWx1ZSkpKTtcbiAgICAgICAgdGhpcy53cml0ZUludDMyKG9mZnNldCArIDQsIE51bWJlcihCaWdJbnQuYXNJbnROKDMyLCB2YWx1ZSA+PiBCaWdJbnQoMzIpKSkpO1xuICAgIH1cbiAgICB3cml0ZVVpbnQ2NChvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMud3JpdGVVaW50MzIob2Zmc2V0LCBOdW1iZXIoQmlnSW50LmFzVWludE4oMzIsIHZhbHVlKSkpO1xuICAgICAgICB0aGlzLndyaXRlVWludDMyKG9mZnNldCArIDQsIE51bWJlcihCaWdJbnQuYXNVaW50TigzMiwgdmFsdWUgPj4gQmlnSW50KDMyKSkpKTtcbiAgICB9XG4gICAgd3JpdGVGbG9hdDMyKG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdXRpbHNfanNfMS5mbG9hdDMyWzBdID0gdmFsdWU7XG4gICAgICAgIHRoaXMud3JpdGVJbnQzMihvZmZzZXQsIHV0aWxzX2pzXzEuaW50MzJbMF0pO1xuICAgIH1cbiAgICB3cml0ZUZsb2F0NjQob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB1dGlsc19qc18xLmZsb2F0NjRbMF0gPSB2YWx1ZTtcbiAgICAgICAgdGhpcy53cml0ZUludDMyKG9mZnNldCwgdXRpbHNfanNfMS5pbnQzMlt1dGlsc19qc18xLmlzTGl0dGxlRW5kaWFuID8gMCA6IDFdKTtcbiAgICAgICAgdGhpcy53cml0ZUludDMyKG9mZnNldCArIDQsIHV0aWxzX2pzXzEuaW50MzJbdXRpbHNfanNfMS5pc0xpdHRsZUVuZGlhbiA/IDEgOiAwXSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZmlsZSBpZGVudGlmaWVyLiAgIEJlaGF2aW9yIGlzIHVuZGVmaW5lZCBmb3IgRmxhdEJ1ZmZlcnMgd2hvc2VcbiAgICAgKiBzY2hlbWEgZG9lcyBub3QgaW5jbHVkZSBhIGZpbGVfaWRlbnRpZmllciAobGlrZWx5IHBvaW50cyBhdCBwYWRkaW5nIG9yIHRoZVxuICAgICAqIHN0YXJ0IG9mIGEgdGhlIHJvb3QgdnRhYmxlKS5cbiAgICAgKi9cbiAgICBnZXRCdWZmZXJJZGVudGlmaWVyKCkge1xuICAgICAgICBpZiAodGhpcy5ieXRlc18ubGVuZ3RoIDwgdGhpcy5wb3NpdGlvbl8gKyBjb25zdGFudHNfanNfMS5TSVpFT0ZfSU5UICtcbiAgICAgICAgICAgIGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRmxhdEJ1ZmZlcnM6IEJ5dGVCdWZmZXIgaXMgdG9vIHNob3J0IHRvIGNvbnRhaW4gYW4gaWRlbnRpZmllci4nKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzdWx0ID0gXCJcIjtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb25zdGFudHNfanNfMS5GSUxFX0lERU5USUZJRVJfTEVOR1RIOyBpKyspIHtcbiAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMucmVhZEludDgodGhpcy5wb3NpdGlvbl8gKyBjb25zdGFudHNfanNfMS5TSVpFT0ZfSU5UICsgaSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExvb2sgdXAgYSBmaWVsZCBpbiB0aGUgdnRhYmxlLCByZXR1cm4gYW4gb2Zmc2V0IGludG8gdGhlIG9iamVjdCwgb3IgMCBpZiB0aGVcbiAgICAgKiBmaWVsZCBpcyBub3QgcHJlc2VudC5cbiAgICAgKi9cbiAgICBfX29mZnNldChiYl9wb3MsIHZ0YWJsZV9vZmZzZXQpIHtcbiAgICAgICAgY29uc3QgdnRhYmxlID0gYmJfcG9zIC0gdGhpcy5yZWFkSW50MzIoYmJfcG9zKTtcbiAgICAgICAgcmV0dXJuIHZ0YWJsZV9vZmZzZXQgPCB0aGlzLnJlYWRJbnQxNih2dGFibGUpID8gdGhpcy5yZWFkSW50MTYodnRhYmxlICsgdnRhYmxlX29mZnNldCkgOiAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIGFueSBUYWJsZS1kZXJpdmVkIHR5cGUgdG8gcG9pbnQgdG8gdGhlIHVuaW9uIGF0IHRoZSBnaXZlbiBvZmZzZXQuXG4gICAgICovXG4gICAgX191bmlvbih0LCBvZmZzZXQpIHtcbiAgICAgICAgdC5iYl9wb3MgPSBvZmZzZXQgKyB0aGlzLnJlYWRJbnQzMihvZmZzZXQpO1xuICAgICAgICB0LmJiID0gdGhpcztcbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIEphdmFTY3JpcHQgc3RyaW5nIGZyb20gVVRGLTggZGF0YSBzdG9yZWQgaW5zaWRlIHRoZSBGbGF0QnVmZmVyLlxuICAgICAqIFRoaXMgYWxsb2NhdGVzIGEgbmV3IHN0cmluZyBhbmQgY29udmVydHMgdG8gd2lkZSBjaGFycyB1cG9uIGVhY2ggYWNjZXNzLlxuICAgICAqXG4gICAgICogVG8gYXZvaWQgdGhlIGNvbnZlcnNpb24gdG8gc3RyaW5nLCBwYXNzIEVuY29kaW5nLlVURjhfQllURVMgYXMgdGhlXG4gICAgICogXCJvcHRpb25hbEVuY29kaW5nXCIgYXJndW1lbnQuIFRoaXMgaXMgdXNlZnVsIGZvciBhdm9pZGluZyBjb252ZXJzaW9uIHdoZW5cbiAgICAgKiB0aGUgZGF0YSB3aWxsIGp1c3QgYmUgcGFja2FnZWQgYmFjayB1cCBpbiBhbm90aGVyIEZsYXRCdWZmZXIgbGF0ZXIgb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb2Zmc2V0XG4gICAgICogQHBhcmFtIG9wdF9lbmNvZGluZyBEZWZhdWx0cyB0byBVVEYxNl9TVFJJTkdcbiAgICAgKi9cbiAgICBfX3N0cmluZyhvZmZzZXQsIG9wdF9lbmNvZGluZykge1xuICAgICAgICBvZmZzZXQgKz0gdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0ICs9IGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQ7XG4gICAgICAgIGNvbnN0IHV0ZjhieXRlcyA9IHRoaXMuYnl0ZXNfLnN1YmFycmF5KG9mZnNldCwgb2Zmc2V0ICsgbGVuZ3RoKTtcbiAgICAgICAgaWYgKG9wdF9lbmNvZGluZyA9PT0gZW5jb2RpbmdfanNfMS5FbmNvZGluZy5VVEY4X0JZVEVTKVxuICAgICAgICAgICAgcmV0dXJuIHV0ZjhieXRlcztcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudGV4dF9kZWNvZGVyXy5kZWNvZGUodXRmOGJ5dGVzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlIHVuaW9ucyB0aGF0IGNhbiBjb250YWluIHN0cmluZyBhcyBpdHMgbWVtYmVyLCBpZiBhIFRhYmxlLWRlcml2ZWQgdHlwZSB0aGVuIGluaXRpYWxpemUgaXQsXG4gICAgICogaWYgYSBzdHJpbmcgdGhlbiByZXR1cm4gYSBuZXcgb25lXG4gICAgICpcbiAgICAgKiBXQVJOSU5HOiBzdHJpbmdzIGFyZSBpbW11dGFibGUgaW4gSlMgc28gd2UgY2FuJ3QgY2hhbmdlIHRoZSBzdHJpbmcgdGhhdCB0aGUgdXNlciBnYXZlIHVzLCB0aGlzXG4gICAgICogbWFrZXMgdGhlIGJlaGF2aW91ciBvZiBfX3VuaW9uX3dpdGhfc3RyaW5nIGRpZmZlcmVudCBjb21wYXJlZCB0byBfX3VuaW9uXG4gICAgICovXG4gICAgX191bmlvbl93aXRoX3N0cmluZyhvLCBvZmZzZXQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX19zdHJpbmcob2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fX3VuaW9uKG8sIG9mZnNldCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlIHRoZSByZWxhdGl2ZSBvZmZzZXQgc3RvcmVkIGF0IFwib2Zmc2V0XCJcbiAgICAgKi9cbiAgICBfX2luZGlyZWN0KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gb2Zmc2V0ICsgdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBzdGFydCBvZiBkYXRhIG9mIGEgdmVjdG9yIHdob3NlIG9mZnNldCBpcyBzdG9yZWQgYXQgXCJvZmZzZXRcIiBpbiB0aGlzIG9iamVjdC5cbiAgICAgKi9cbiAgICBfX3ZlY3RvcihvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIG9mZnNldCArIHRoaXMucmVhZEludDMyKG9mZnNldCkgKyBjb25zdGFudHNfanNfMS5TSVpFT0ZfSU5UOyAvLyBkYXRhIHN0YXJ0cyBhZnRlciB0aGUgbGVuZ3RoXG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgbGVuZ3RoIG9mIGEgdmVjdG9yIHdob3NlIG9mZnNldCBpcyBzdG9yZWQgYXQgXCJvZmZzZXRcIiBpbiB0aGlzIG9iamVjdC5cbiAgICAgKi9cbiAgICBfX3ZlY3Rvcl9sZW4ob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRJbnQzMihvZmZzZXQgKyB0aGlzLnJlYWRJbnQzMihvZmZzZXQpKTtcbiAgICB9XG4gICAgX19oYXNfaWRlbnRpZmllcihpZGVudCkge1xuICAgICAgICBpZiAoaWRlbnQubGVuZ3RoICE9IGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRmxhdEJ1ZmZlcnM6IGZpbGUgaWRlbnRpZmllciBtdXN0IGJlIGxlbmd0aCAnICtcbiAgICAgICAgICAgICAgICBjb25zdGFudHNfanNfMS5GSUxFX0lERU5USUZJRVJfTEVOR1RIKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGlkZW50LmNoYXJDb2RlQXQoaSkgIT0gdGhpcy5yZWFkSW50OCh0aGlzLnBvc2l0aW9uKCkgKyBjb25zdGFudHNfanNfMS5TSVpFT0ZfSU5UICsgaSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgaGVscGVyIGZ1bmN0aW9uIGZvciBnZW5lcmF0aW5nIGxpc3QgZm9yIG9iaiBhcGlcbiAgICAgKi9cbiAgICBjcmVhdGVTY2FsYXJMaXN0KGxpc3RBY2Nlc3NvciwgbGlzdExlbmd0aCkge1xuICAgICAgICBjb25zdCByZXQgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0TGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbCA9IGxpc3RBY2Nlc3NvcihpKTtcbiAgICAgICAgICAgIGlmICh2YWwgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXQucHVzaCh2YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgaGVscGVyIGZ1bmN0aW9uIGZvciBnZW5lcmF0aW5nIGxpc3QgZm9yIG9iaiBhcGlcbiAgICAgKiBAcGFyYW0gbGlzdEFjY2Vzc29yIGZ1bmN0aW9uIHRoYXQgYWNjZXB0cyBhbiBpbmRleCBhbmQgcmV0dXJuIGRhdGEgYXQgdGhhdCBpbmRleFxuICAgICAqIEBwYXJhbSBsaXN0TGVuZ3RoIGxpc3RMZW5ndGhcbiAgICAgKiBAcGFyYW0gcmVzIHJlc3VsdCBsaXN0XG4gICAgICovXG4gICAgY3JlYXRlT2JqTGlzdChsaXN0QWNjZXNzb3IsIGxpc3RMZW5ndGgpIHtcbiAgICAgICAgY29uc3QgcmV0ID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdExlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBjb25zdCB2YWwgPSBsaXN0QWNjZXNzb3IoaSk7XG4gICAgICAgICAgICBpZiAodmFsICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0LnB1c2godmFsLnVucGFjaygpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cbn1cbmV4cG9ydHMuQnl0ZUJ1ZmZlciA9IEJ5dGVCdWZmZXI7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkJ1aWxkZXIgPSB2b2lkIDA7XG5jb25zdCBieXRlX2J1ZmZlcl9qc18xID0gcmVxdWlyZShcIi4vYnl0ZS1idWZmZXIuanNcIik7XG5jb25zdCBjb25zdGFudHNfanNfMSA9IHJlcXVpcmUoXCIuL2NvbnN0YW50cy5qc1wiKTtcbmNsYXNzIEJ1aWxkZXIge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIEZsYXRCdWZmZXJCdWlsZGVyLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wdF9pbml0aWFsX3NpemUpIHtcbiAgICAgICAgLyoqIE1pbmltdW0gYWxpZ25tZW50IGVuY291bnRlcmVkIHNvIGZhci4gKi9cbiAgICAgICAgdGhpcy5taW5hbGlnbiA9IDE7XG4gICAgICAgIC8qKiBUaGUgdnRhYmxlIGZvciB0aGUgY3VycmVudCB0YWJsZS4gKi9cbiAgICAgICAgdGhpcy52dGFibGUgPSBudWxsO1xuICAgICAgICAvKiogVGhlIGFtb3VudCBvZiBmaWVsZHMgd2UncmUgYWN0dWFsbHkgdXNpbmcuICovXG4gICAgICAgIHRoaXMudnRhYmxlX2luX3VzZSA9IDA7XG4gICAgICAgIC8qKiBXaGV0aGVyIHdlIGFyZSBjdXJyZW50bHkgc2VyaWFsaXppbmcgYSB0YWJsZS4gKi9cbiAgICAgICAgdGhpcy5pc05lc3RlZCA9IGZhbHNlO1xuICAgICAgICAvKiogU3RhcnRpbmcgb2Zmc2V0IG9mIHRoZSBjdXJyZW50IHN0cnVjdC90YWJsZS4gKi9cbiAgICAgICAgdGhpcy5vYmplY3Rfc3RhcnQgPSAwO1xuICAgICAgICAvKiogTGlzdCBvZiBvZmZzZXRzIG9mIGFsbCB2dGFibGVzLiAqL1xuICAgICAgICB0aGlzLnZ0YWJsZXMgPSBbXTtcbiAgICAgICAgLyoqIEZvciB0aGUgY3VycmVudCB2ZWN0b3IgYmVpbmcgYnVpbHQuICovXG4gICAgICAgIHRoaXMudmVjdG9yX251bV9lbGVtcyA9IDA7XG4gICAgICAgIC8qKiBGYWxzZSBvbWl0cyBkZWZhdWx0IHZhbHVlcyBmcm9tIHRoZSBzZXJpYWxpemVkIGRhdGEgKi9cbiAgICAgICAgdGhpcy5mb3JjZV9kZWZhdWx0cyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN0cmluZ19tYXBzID0gbnVsbDtcbiAgICAgICAgdGhpcy50ZXh0X2VuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgICAgICAgbGV0IGluaXRpYWxfc2l6ZTtcbiAgICAgICAgaWYgKCFvcHRfaW5pdGlhbF9zaXplKSB7XG4gICAgICAgICAgICBpbml0aWFsX3NpemUgPSAxMDI0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5pdGlhbF9zaXplID0gb3B0X2luaXRpYWxfc2l6ZTtcbiAgICAgICAgfVxuICAgICAgICAvKipcbiAgICAgICAgICogQHR5cGUge0J5dGVCdWZmZXJ9XG4gICAgICAgICAqIEBwcml2YXRlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmJiID0gYnl0ZV9idWZmZXJfanNfMS5CeXRlQnVmZmVyLmFsbG9jYXRlKGluaXRpYWxfc2l6ZSk7XG4gICAgICAgIHRoaXMuc3BhY2UgPSBpbml0aWFsX3NpemU7XG4gICAgfVxuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLmJiLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuc3BhY2UgPSB0aGlzLmJiLmNhcGFjaXR5KCk7XG4gICAgICAgIHRoaXMubWluYWxpZ24gPSAxO1xuICAgICAgICB0aGlzLnZ0YWJsZSA9IG51bGw7XG4gICAgICAgIHRoaXMudnRhYmxlX2luX3VzZSA9IDA7XG4gICAgICAgIHRoaXMuaXNOZXN0ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5vYmplY3Rfc3RhcnQgPSAwO1xuICAgICAgICB0aGlzLnZ0YWJsZXMgPSBbXTtcbiAgICAgICAgdGhpcy52ZWN0b3JfbnVtX2VsZW1zID0gMDtcbiAgICAgICAgdGhpcy5mb3JjZV9kZWZhdWx0cyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN0cmluZ19tYXBzID0gbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW4gb3JkZXIgdG8gc2F2ZSBzcGFjZSwgZmllbGRzIHRoYXQgYXJlIHNldCB0byB0aGVpciBkZWZhdWx0IHZhbHVlXG4gICAgICogZG9uJ3QgZ2V0IHNlcmlhbGl6ZWQgaW50byB0aGUgYnVmZmVyLiBGb3JjaW5nIGRlZmF1bHRzIHByb3ZpZGVzIGFcbiAgICAgKiB3YXkgdG8gbWFudWFsbHkgZGlzYWJsZSB0aGlzIG9wdGltaXphdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBmb3JjZURlZmF1bHRzIHRydWUgYWx3YXlzIHNlcmlhbGl6ZXMgZGVmYXVsdCB2YWx1ZXNcbiAgICAgKi9cbiAgICBmb3JjZURlZmF1bHRzKGZvcmNlRGVmYXVsdHMpIHtcbiAgICAgICAgdGhpcy5mb3JjZV9kZWZhdWx0cyA9IGZvcmNlRGVmYXVsdHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgQnl0ZUJ1ZmZlciByZXByZXNlbnRpbmcgdGhlIEZsYXRCdWZmZXIuIE9ubHkgY2FsbCB0aGlzIGFmdGVyIHlvdSd2ZVxuICAgICAqIGNhbGxlZCBmaW5pc2goKS4gVGhlIGFjdHVhbCBkYXRhIHN0YXJ0cyBhdCB0aGUgQnl0ZUJ1ZmZlcidzIGN1cnJlbnQgcG9zaXRpb24sXG4gICAgICogbm90IG5lY2Vzc2FyaWx5IGF0IDAuXG4gICAgICovXG4gICAgZGF0YUJ1ZmZlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYmI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgYnl0ZXMgcmVwcmVzZW50aW5nIHRoZSBGbGF0QnVmZmVyLiBPbmx5IGNhbGwgdGhpcyBhZnRlciB5b3UndmVcbiAgICAgKiBjYWxsZWQgZmluaXNoKCkuXG4gICAgICovXG4gICAgYXNVaW50OEFycmF5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5iYi5ieXRlcygpLnN1YmFycmF5KHRoaXMuYmIucG9zaXRpb24oKSwgdGhpcy5iYi5wb3NpdGlvbigpICsgdGhpcy5vZmZzZXQoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFByZXBhcmUgdG8gd3JpdGUgYW4gZWxlbWVudCBvZiBgc2l6ZWAgYWZ0ZXIgYGFkZGl0aW9uYWxfYnl0ZXNgIGhhdmUgYmVlblxuICAgICAqIHdyaXR0ZW4sIGUuZy4gaWYgeW91IHdyaXRlIGEgc3RyaW5nLCB5b3UgbmVlZCB0byBhbGlnbiBzdWNoIHRoZSBpbnQgbGVuZ3RoXG4gICAgICogZmllbGQgaXMgYWxpZ25lZCB0byA0IGJ5dGVzLCBhbmQgdGhlIHN0cmluZyBkYXRhIGZvbGxvd3MgaXQgZGlyZWN0bHkuIElmIGFsbFxuICAgICAqIHlvdSBuZWVkIHRvIGRvIGlzIGFsaWdubWVudCwgYGFkZGl0aW9uYWxfYnl0ZXNgIHdpbGwgYmUgMC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzaXplIFRoaXMgaXMgdGhlIG9mIHRoZSBuZXcgZWxlbWVudCB0byB3cml0ZVxuICAgICAqIEBwYXJhbSBhZGRpdGlvbmFsX2J5dGVzIFRoZSBwYWRkaW5nIHNpemVcbiAgICAgKi9cbiAgICBwcmVwKHNpemUsIGFkZGl0aW9uYWxfYnl0ZXMpIHtcbiAgICAgICAgLy8gVHJhY2sgdGhlIGJpZ2dlc3QgdGhpbmcgd2UndmUgZXZlciBhbGlnbmVkIHRvLlxuICAgICAgICBpZiAoc2l6ZSA+IHRoaXMubWluYWxpZ24pIHtcbiAgICAgICAgICAgIHRoaXMubWluYWxpZ24gPSBzaXplO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZpbmQgdGhlIGFtb3VudCBvZiBhbGlnbm1lbnQgbmVlZGVkIHN1Y2ggdGhhdCBgc2l6ZWAgaXMgcHJvcGVybHlcbiAgICAgICAgLy8gYWxpZ25lZCBhZnRlciBgYWRkaXRpb25hbF9ieXRlc2BcbiAgICAgICAgY29uc3QgYWxpZ25fc2l6ZSA9ICgofih0aGlzLmJiLmNhcGFjaXR5KCkgLSB0aGlzLnNwYWNlICsgYWRkaXRpb25hbF9ieXRlcykpICsgMSkgJiAoc2l6ZSAtIDEpO1xuICAgICAgICAvLyBSZWFsbG9jYXRlIHRoZSBidWZmZXIgaWYgbmVlZGVkLlxuICAgICAgICB3aGlsZSAodGhpcy5zcGFjZSA8IGFsaWduX3NpemUgKyBzaXplICsgYWRkaXRpb25hbF9ieXRlcykge1xuICAgICAgICAgICAgY29uc3Qgb2xkX2J1Zl9zaXplID0gdGhpcy5iYi5jYXBhY2l0eSgpO1xuICAgICAgICAgICAgdGhpcy5iYiA9IEJ1aWxkZXIuZ3Jvd0J5dGVCdWZmZXIodGhpcy5iYik7XG4gICAgICAgICAgICB0aGlzLnNwYWNlICs9IHRoaXMuYmIuY2FwYWNpdHkoKSAtIG9sZF9idWZfc2l6ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBhZChhbGlnbl9zaXplKTtcbiAgICB9XG4gICAgcGFkKGJ5dGVfc2l6ZSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ5dGVfc2l6ZTsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLmJiLndyaXRlSW50OCgtLXRoaXMuc3BhY2UsIDApO1xuICAgICAgICB9XG4gICAgfVxuICAgIHdyaXRlSW50OCh2YWx1ZSkge1xuICAgICAgICB0aGlzLmJiLndyaXRlSW50OCh0aGlzLnNwYWNlIC09IDEsIHZhbHVlKTtcbiAgICB9XG4gICAgd3JpdGVJbnQxNih2YWx1ZSkge1xuICAgICAgICB0aGlzLmJiLndyaXRlSW50MTYodGhpcy5zcGFjZSAtPSAyLCB2YWx1ZSk7XG4gICAgfVxuICAgIHdyaXRlSW50MzIodmFsdWUpIHtcbiAgICAgICAgdGhpcy5iYi53cml0ZUludDMyKHRoaXMuc3BhY2UgLT0gNCwgdmFsdWUpO1xuICAgIH1cbiAgICB3cml0ZUludDY0KHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYmIud3JpdGVJbnQ2NCh0aGlzLnNwYWNlIC09IDgsIHZhbHVlKTtcbiAgICB9XG4gICAgd3JpdGVGbG9hdDMyKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYmIud3JpdGVGbG9hdDMyKHRoaXMuc3BhY2UgLT0gNCwgdmFsdWUpO1xuICAgIH1cbiAgICB3cml0ZUZsb2F0NjQodmFsdWUpIHtcbiAgICAgICAgdGhpcy5iYi53cml0ZUZsb2F0NjQodGhpcy5zcGFjZSAtPSA4LCB2YWx1ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhbiBgaW50OGAgdG8gdGhlIGJ1ZmZlciwgcHJvcGVybHkgYWxpZ25lZCwgYW5kIGdyb3dzIHRoZSBidWZmZXIgKGlmIG5lY2Vzc2FyeSkuXG4gICAgICogQHBhcmFtIHZhbHVlIFRoZSBgaW50OGAgdG8gYWRkIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgYWRkSW50OCh2YWx1ZSkge1xuICAgICAgICB0aGlzLnByZXAoMSwgMCk7XG4gICAgICAgIHRoaXMud3JpdGVJbnQ4KHZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIGBpbnQxNmAgdG8gdGhlIGJ1ZmZlciwgcHJvcGVybHkgYWxpZ25lZCwgYW5kIGdyb3dzIHRoZSBidWZmZXIgKGlmIG5lY2Vzc2FyeSkuXG4gICAgICogQHBhcmFtIHZhbHVlIFRoZSBgaW50MTZgIHRvIGFkZCB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGFkZEludDE2KHZhbHVlKSB7XG4gICAgICAgIHRoaXMucHJlcCgyLCAwKTtcbiAgICAgICAgdGhpcy53cml0ZUludDE2KHZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIGBpbnQzMmAgdG8gdGhlIGJ1ZmZlciwgcHJvcGVybHkgYWxpZ25lZCwgYW5kIGdyb3dzIHRoZSBidWZmZXIgKGlmIG5lY2Vzc2FyeSkuXG4gICAgICogQHBhcmFtIHZhbHVlIFRoZSBgaW50MzJgIHRvIGFkZCB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGFkZEludDMyKHZhbHVlKSB7XG4gICAgICAgIHRoaXMucHJlcCg0LCAwKTtcbiAgICAgICAgdGhpcy53cml0ZUludDMyKHZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIGBpbnQ2NGAgdG8gdGhlIGJ1ZmZlciwgcHJvcGVybHkgYWxpZ25lZCwgYW5kIGdyb3dzIHRoZSBidWZmZXIgKGlmIG5lY2Vzc2FyeSkuXG4gICAgICogQHBhcmFtIHZhbHVlIFRoZSBgaW50NjRgIHRvIGFkZCB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGFkZEludDY0KHZhbHVlKSB7XG4gICAgICAgIHRoaXMucHJlcCg4LCAwKTtcbiAgICAgICAgdGhpcy53cml0ZUludDY0KHZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgYGZsb2F0MzJgIHRvIHRoZSBidWZmZXIsIHByb3Blcmx5IGFsaWduZWQsIGFuZCBncm93cyB0aGUgYnVmZmVyIChpZiBuZWNlc3NhcnkpLlxuICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYGZsb2F0MzJgIHRvIGFkZCB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGFkZEZsb2F0MzIodmFsdWUpIHtcbiAgICAgICAgdGhpcy5wcmVwKDQsIDApO1xuICAgICAgICB0aGlzLndyaXRlRmxvYXQzMih2YWx1ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhIGBmbG9hdDY0YCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGBmbG9hdDY0YCB0byBhZGQgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBhZGRGbG9hdDY0KHZhbHVlKSB7XG4gICAgICAgIHRoaXMucHJlcCg4LCAwKTtcbiAgICAgICAgdGhpcy53cml0ZUZsb2F0NjQodmFsdWUpO1xuICAgIH1cbiAgICBhZGRGaWVsZEludDgodm9mZnNldCwgdmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICBpZiAodGhpcy5mb3JjZV9kZWZhdWx0cyB8fCB2YWx1ZSAhPSBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkSW50OCh2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLnNsb3Qodm9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkRmllbGRJbnQxNih2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRJbnQxNih2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLnNsb3Qodm9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkRmllbGRJbnQzMih2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRJbnQzMih2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLnNsb3Qodm9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkRmllbGRJbnQ2NCh2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9PSBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkSW50NjQodmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFkZEZpZWxkRmxvYXQzMih2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRGbG9hdDMyKHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRGaWVsZEZsb2F0NjQodm9mZnNldCwgdmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICBpZiAodGhpcy5mb3JjZV9kZWZhdWx0cyB8fCB2YWx1ZSAhPSBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkRmxvYXQ2NCh2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLnNsb3Qodm9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkRmllbGRPZmZzZXQodm9mZnNldCwgdmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICBpZiAodGhpcy5mb3JjZV9kZWZhdWx0cyB8fCB2YWx1ZSAhPSBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkT2Zmc2V0KHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdHJ1Y3RzIGFyZSBzdG9yZWQgaW5saW5lLCBzbyBub3RoaW5nIGFkZGl0aW9uYWwgaXMgYmVpbmcgYWRkZWQuIGBkYCBpcyBhbHdheXMgMC5cbiAgICAgKi9cbiAgICBhZGRGaWVsZFN0cnVjdCh2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPSBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMubmVzdGVkKHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdHJ1Y3R1cmVzIGFyZSBhbHdheXMgc3RvcmVkIGlubGluZSwgdGhleSBuZWVkIHRvIGJlIGNyZWF0ZWQgcmlnaHRcbiAgICAgKiB3aGVyZSB0aGV5J3JlIHVzZWQuICBZb3UnbGwgZ2V0IHRoaXMgYXNzZXJ0aW9uIGZhaWx1cmUgaWYgeW91XG4gICAgICogY3JlYXRlZCBpdCBlbHNld2hlcmUuXG4gICAgICovXG4gICAgbmVzdGVkKG9iaikge1xuICAgICAgICBpZiAob2JqICE9IHRoaXMub2Zmc2V0KCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZsYXRCdWZmZXJzOiBzdHJ1Y3QgbXVzdCBiZSBzZXJpYWxpemVkIGlubGluZS4nKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTaG91bGQgbm90IGJlIGNyZWF0aW5nIGFueSBvdGhlciBvYmplY3QsIHN0cmluZyBvciB2ZWN0b3JcbiAgICAgKiB3aGlsZSBhbiBvYmplY3QgaXMgYmVpbmcgY29uc3RydWN0ZWRcbiAgICAgKi9cbiAgICBub3ROZXN0ZWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzTmVzdGVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGbGF0QnVmZmVyczogb2JqZWN0IHNlcmlhbGl6YXRpb24gbXVzdCBub3QgYmUgbmVzdGVkLicpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgY3VycmVudCB2dGFibGUgYXQgYHZvZmZzZXRgIHRvIHRoZSBjdXJyZW50IGxvY2F0aW9uIGluIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgc2xvdCh2b2Zmc2V0KSB7XG4gICAgICAgIGlmICh0aGlzLnZ0YWJsZSAhPT0gbnVsbClcbiAgICAgICAgICAgIHRoaXMudnRhYmxlW3ZvZmZzZXRdID0gdGhpcy5vZmZzZXQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHJldHVybnMgT2Zmc2V0IHJlbGF0aXZlIHRvIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBvZmZzZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJiLmNhcGFjaXR5KCkgLSB0aGlzLnNwYWNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEb3VibGVzIHRoZSBzaXplIG9mIHRoZSBiYWNraW5nIEJ5dGVCdWZmZXIgYW5kIGNvcGllcyB0aGUgb2xkIGRhdGEgdG93YXJkc1xuICAgICAqIHRoZSBlbmQgb2YgdGhlIG5ldyBidWZmZXIgKHNpbmNlIHdlIGJ1aWxkIHRoZSBidWZmZXIgYmFja3dhcmRzKS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBiYiBUaGUgY3VycmVudCBidWZmZXIgd2l0aCB0aGUgZXhpc3RpbmcgZGF0YVxuICAgICAqIEByZXR1cm5zIEEgbmV3IGJ5dGUgYnVmZmVyIHdpdGggdGhlIG9sZCBkYXRhIGNvcGllZFxuICAgICAqIHRvIGl0LiBUaGUgZGF0YSBpcyBsb2NhdGVkIGF0IHRoZSBlbmQgb2YgdGhlIGJ1ZmZlci5cbiAgICAgKlxuICAgICAqIHVpbnQ4QXJyYXkuc2V0KCkgZm9ybWFsbHkgdGFrZXMge0FycmF5PG51bWJlcj58QXJyYXlCdWZmZXJWaWV3fSwgc28gdG8gcGFzc1xuICAgICAqIGl0IGEgdWludDhBcnJheSB3ZSBuZWVkIHRvIHN1cHByZXNzIHRoZSB0eXBlIGNoZWNrOlxuICAgICAqIEBzdXBwcmVzcyB7Y2hlY2tUeXBlc31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ3Jvd0J5dGVCdWZmZXIoYmIpIHtcbiAgICAgICAgY29uc3Qgb2xkX2J1Zl9zaXplID0gYmIuY2FwYWNpdHkoKTtcbiAgICAgICAgLy8gRW5zdXJlIHdlIGRvbid0IGdyb3cgYmV5b25kIHdoYXQgZml0cyBpbiBhbiBpbnQuXG4gICAgICAgIGlmIChvbGRfYnVmX3NpemUgJiAweEMwMDAwMDAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXRCdWZmZXJzOiBjYW5ub3QgZ3JvdyBidWZmZXIgYmV5b25kIDIgZ2lnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5ld19idWZfc2l6ZSA9IG9sZF9idWZfc2l6ZSA8PCAxO1xuICAgICAgICBjb25zdCBuYmIgPSBieXRlX2J1ZmZlcl9qc18xLkJ5dGVCdWZmZXIuYWxsb2NhdGUobmV3X2J1Zl9zaXplKTtcbiAgICAgICAgbmJiLnNldFBvc2l0aW9uKG5ld19idWZfc2l6ZSAtIG9sZF9idWZfc2l6ZSk7XG4gICAgICAgIG5iYi5ieXRlcygpLnNldChiYi5ieXRlcygpLCBuZXdfYnVmX3NpemUgLSBvbGRfYnVmX3NpemUpO1xuICAgICAgICByZXR1cm4gbmJiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIG9uIG9mZnNldCwgcmVsYXRpdmUgdG8gd2hlcmUgaXQgd2lsbCBiZSB3cml0dGVuLlxuICAgICAqXG4gICAgICogQHBhcmFtIG9mZnNldCBUaGUgb2Zmc2V0IHRvIGFkZC5cbiAgICAgKi9cbiAgICBhZGRPZmZzZXQob2Zmc2V0KSB7XG4gICAgICAgIHRoaXMucHJlcChjb25zdGFudHNfanNfMS5TSVpFT0ZfSU5ULCAwKTsgLy8gRW5zdXJlIGFsaWdubWVudCBpcyBhbHJlYWR5IGRvbmUuXG4gICAgICAgIHRoaXMud3JpdGVJbnQzMih0aGlzLm9mZnNldCgpIC0gb2Zmc2V0ICsgY29uc3RhbnRzX2pzXzEuU0laRU9GX0lOVCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IGVuY29kaW5nIGEgbmV3IG9iamVjdCBpbiB0aGUgYnVmZmVyLiAgVXNlcnMgd2lsbCBub3QgdXN1YWxseSBuZWVkIHRvXG4gICAgICogY2FsbCB0aGlzIGRpcmVjdGx5LiBUaGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIgd2lsbCBnZW5lcmF0ZSBoZWxwZXIgbWV0aG9kc1xuICAgICAqIHRoYXQgY2FsbCB0aGlzIG1ldGhvZCBpbnRlcm5hbGx5LlxuICAgICAqL1xuICAgIHN0YXJ0T2JqZWN0KG51bWZpZWxkcykge1xuICAgICAgICB0aGlzLm5vdE5lc3RlZCgpO1xuICAgICAgICBpZiAodGhpcy52dGFibGUgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy52dGFibGUgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZ0YWJsZV9pbl91c2UgPSBudW1maWVsZHM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtZmllbGRzOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMudnRhYmxlW2ldID0gMDsgLy8gVGhpcyB3aWxsIHB1c2ggYWRkaXRpb25hbCBlbGVtZW50cyBhcyBuZWVkZWRcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmlzTmVzdGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5vYmplY3Rfc3RhcnQgPSB0aGlzLm9mZnNldCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBGaW5pc2ggb2ZmIHdyaXRpbmcgdGhlIG9iamVjdCB0aGF0IGlzIHVuZGVyIGNvbnN0cnVjdGlvbi5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBvZmZzZXQgdG8gdGhlIG9iamVjdCBpbnNpZGUgYGRhdGFCdWZmZXJgXG4gICAgICovXG4gICAgZW5kT2JqZWN0KCkge1xuICAgICAgICBpZiAodGhpcy52dGFibGUgPT0gbnVsbCB8fCAhdGhpcy5pc05lc3RlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0QnVmZmVyczogZW5kT2JqZWN0IGNhbGxlZCB3aXRob3V0IHN0YXJ0T2JqZWN0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hZGRJbnQzMigwKTtcbiAgICAgICAgY29uc3QgdnRhYmxlbG9jID0gdGhpcy5vZmZzZXQoKTtcbiAgICAgICAgLy8gVHJpbSB0cmFpbGluZyB6ZXJvZXMuXG4gICAgICAgIGxldCBpID0gdGhpcy52dGFibGVfaW5fdXNlIC0gMTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVtcHR5XG4gICAgICAgIGZvciAoOyBpID49IDAgJiYgdGhpcy52dGFibGVbaV0gPT0gMDsgaS0tKSB7IH1cbiAgICAgICAgY29uc3QgdHJpbW1lZF9zaXplID0gaSArIDE7XG4gICAgICAgIC8vIFdyaXRlIG91dCB0aGUgY3VycmVudCB2dGFibGUuXG4gICAgICAgIGZvciAoOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgLy8gT2Zmc2V0IHJlbGF0aXZlIHRvIHRoZSBzdGFydCBvZiB0aGUgdGFibGUuXG4gICAgICAgICAgICB0aGlzLmFkZEludDE2KHRoaXMudnRhYmxlW2ldICE9IDAgPyB2dGFibGVsb2MgLSB0aGlzLnZ0YWJsZVtpXSA6IDApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHN0YW5kYXJkX2ZpZWxkcyA9IDI7IC8vIFRoZSBmaWVsZHMgYmVsb3c6XG4gICAgICAgIHRoaXMuYWRkSW50MTYodnRhYmxlbG9jIC0gdGhpcy5vYmplY3Rfc3RhcnQpO1xuICAgICAgICBjb25zdCBsZW4gPSAodHJpbW1lZF9zaXplICsgc3RhbmRhcmRfZmllbGRzKSAqIGNvbnN0YW50c19qc18xLlNJWkVPRl9TSE9SVDtcbiAgICAgICAgdGhpcy5hZGRJbnQxNihsZW4pO1xuICAgICAgICAvLyBTZWFyY2ggZm9yIGFuIGV4aXN0aW5nIHZ0YWJsZSB0aGF0IG1hdGNoZXMgdGhlIGN1cnJlbnQgb25lLlxuICAgICAgICBsZXQgZXhpc3RpbmdfdnRhYmxlID0gMDtcbiAgICAgICAgY29uc3QgdnQxID0gdGhpcy5zcGFjZTtcbiAgICAgICAgb3V0ZXJfbG9vcDogZm9yIChpID0gMDsgaSA8IHRoaXMudnRhYmxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgdnQyID0gdGhpcy5iYi5jYXBhY2l0eSgpIC0gdGhpcy52dGFibGVzW2ldO1xuICAgICAgICAgICAgaWYgKGxlbiA9PSB0aGlzLmJiLnJlYWRJbnQxNih2dDIpKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IGNvbnN0YW50c19qc18xLlNJWkVPRl9TSE9SVDsgaiA8IGxlbjsgaiArPSBjb25zdGFudHNfanNfMS5TSVpFT0ZfU0hPUlQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuYmIucmVhZEludDE2KHZ0MSArIGopICE9IHRoaXMuYmIucmVhZEludDE2KHZ0MiArIGopKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBvdXRlcl9sb29wO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGV4aXN0aW5nX3Z0YWJsZSA9IHRoaXMudnRhYmxlc1tpXTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZXhpc3RpbmdfdnRhYmxlKSB7XG4gICAgICAgICAgICAvLyBGb3VuZCBhIG1hdGNoOlxuICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBjdXJyZW50IHZ0YWJsZS5cbiAgICAgICAgICAgIHRoaXMuc3BhY2UgPSB0aGlzLmJiLmNhcGFjaXR5KCkgLSB2dGFibGVsb2M7XG4gICAgICAgICAgICAvLyBQb2ludCB0YWJsZSB0byBleGlzdGluZyB2dGFibGUuXG4gICAgICAgICAgICB0aGlzLmJiLndyaXRlSW50MzIodGhpcy5zcGFjZSwgZXhpc3RpbmdfdnRhYmxlIC0gdnRhYmxlbG9jKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIE5vIG1hdGNoOlxuICAgICAgICAgICAgLy8gQWRkIHRoZSBsb2NhdGlvbiBvZiB0aGUgY3VycmVudCB2dGFibGUgdG8gdGhlIGxpc3Qgb2YgdnRhYmxlcy5cbiAgICAgICAgICAgIHRoaXMudnRhYmxlcy5wdXNoKHRoaXMub2Zmc2V0KCkpO1xuICAgICAgICAgICAgLy8gUG9pbnQgdGFibGUgdG8gY3VycmVudCB2dGFibGUuXG4gICAgICAgICAgICB0aGlzLmJiLndyaXRlSW50MzIodGhpcy5iYi5jYXBhY2l0eSgpIC0gdnRhYmxlbG9jLCB0aGlzLm9mZnNldCgpIC0gdnRhYmxlbG9jKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmlzTmVzdGVkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiB2dGFibGVsb2M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmFsaXplIGEgYnVmZmVyLCBwb2l0aW5nIHRvIHRoZSBnaXZlbiBgcm9vdF90YWJsZWAuXG4gICAgICovXG4gICAgZmluaXNoKHJvb3RfdGFibGUsIG9wdF9maWxlX2lkZW50aWZpZXIsIG9wdF9zaXplX3ByZWZpeCkge1xuICAgICAgICBjb25zdCBzaXplX3ByZWZpeCA9IG9wdF9zaXplX3ByZWZpeCA/IGNvbnN0YW50c19qc18xLlNJWkVfUFJFRklYX0xFTkdUSCA6IDA7XG4gICAgICAgIGlmIChvcHRfZmlsZV9pZGVudGlmaWVyKSB7XG4gICAgICAgICAgICBjb25zdCBmaWxlX2lkZW50aWZpZXIgPSBvcHRfZmlsZV9pZGVudGlmaWVyO1xuICAgICAgICAgICAgdGhpcy5wcmVwKHRoaXMubWluYWxpZ24sIGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQgK1xuICAgICAgICAgICAgICAgIGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEggKyBzaXplX3ByZWZpeCk7XG4gICAgICAgICAgICBpZiAoZmlsZV9pZGVudGlmaWVyLmxlbmd0aCAhPSBjb25zdGFudHNfanNfMS5GSUxFX0lERU5USUZJRVJfTEVOR1RIKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRmxhdEJ1ZmZlcnM6IGZpbGUgaWRlbnRpZmllciBtdXN0IGJlIGxlbmd0aCAnICtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRzX2pzXzEuRklMRV9JREVOVElGSUVSX0xFTkdUSCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gY29uc3RhbnRzX2pzXzEuRklMRV9JREVOVElGSUVSX0xFTkdUSCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgdGhpcy53cml0ZUludDgoZmlsZV9pZGVudGlmaWVyLmNoYXJDb2RlQXQoaSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJlcCh0aGlzLm1pbmFsaWduLCBjb25zdGFudHNfanNfMS5TSVpFT0ZfSU5UICsgc2l6ZV9wcmVmaXgpO1xuICAgICAgICB0aGlzLmFkZE9mZnNldChyb290X3RhYmxlKTtcbiAgICAgICAgaWYgKHNpemVfcHJlZml4KSB7XG4gICAgICAgICAgICB0aGlzLmFkZEludDMyKHRoaXMuYmIuY2FwYWNpdHkoKSAtIHRoaXMuc3BhY2UpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYmIuc2V0UG9zaXRpb24odGhpcy5zcGFjZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmFsaXplIGEgc2l6ZSBwcmVmaXhlZCBidWZmZXIsIHBvaW50aW5nIHRvIHRoZSBnaXZlbiBgcm9vdF90YWJsZWAuXG4gICAgICovXG4gICAgZmluaXNoU2l6ZVByZWZpeGVkKHJvb3RfdGFibGUsIG9wdF9maWxlX2lkZW50aWZpZXIpIHtcbiAgICAgICAgdGhpcy5maW5pc2gocm9vdF90YWJsZSwgb3B0X2ZpbGVfaWRlbnRpZmllciwgdHJ1ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoaXMgY2hlY2tzIGEgcmVxdWlyZWQgZmllbGQgaGFzIGJlZW4gc2V0IGluIGEgZ2l2ZW4gdGFibGUgdGhhdCBoYXNcbiAgICAgKiBqdXN0IGJlZW4gY29uc3RydWN0ZWQuXG4gICAgICovXG4gICAgcmVxdWlyZWRGaWVsZCh0YWJsZSwgZmllbGQpIHtcbiAgICAgICAgY29uc3QgdGFibGVfc3RhcnQgPSB0aGlzLmJiLmNhcGFjaXR5KCkgLSB0YWJsZTtcbiAgICAgICAgY29uc3QgdnRhYmxlX3N0YXJ0ID0gdGFibGVfc3RhcnQgLSB0aGlzLmJiLnJlYWRJbnQzMih0YWJsZV9zdGFydCk7XG4gICAgICAgIGNvbnN0IG9rID0gZmllbGQgPCB0aGlzLmJiLnJlYWRJbnQxNih2dGFibGVfc3RhcnQpICYmXG4gICAgICAgICAgICB0aGlzLmJiLnJlYWRJbnQxNih2dGFibGVfc3RhcnQgKyBmaWVsZCkgIT0gMDtcbiAgICAgICAgLy8gSWYgdGhpcyBmYWlscywgdGhlIGNhbGxlciB3aWxsIHNob3cgd2hhdCBmaWVsZCBuZWVkcyB0byBiZSBzZXQuXG4gICAgICAgIGlmICghb2spIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZsYXRCdWZmZXJzOiBmaWVsZCAnICsgZmllbGQgKyAnIG11c3QgYmUgc2V0Jyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgYSBuZXcgYXJyYXkvdmVjdG9yIG9mIG9iamVjdHMuICBVc2VycyB1c3VhbGx5IHdpbGwgbm90IGNhbGxcbiAgICAgKiB0aGlzIGRpcmVjdGx5LiBUaGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIgd2lsbCBjcmVhdGUgYSBzdGFydC9lbmRcbiAgICAgKiBtZXRob2QgZm9yIHZlY3RvciB0eXBlcyBpbiBnZW5lcmF0ZWQgY29kZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlbGVtX3NpemUgVGhlIHNpemUgb2YgZWFjaCBlbGVtZW50IGluIHRoZSBhcnJheVxuICAgICAqIEBwYXJhbSBudW1fZWxlbXMgVGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgYXJyYXlcbiAgICAgKiBAcGFyYW0gYWxpZ25tZW50IFRoZSBhbGlnbm1lbnQgb2YgdGhlIGFycmF5XG4gICAgICovXG4gICAgc3RhcnRWZWN0b3IoZWxlbV9zaXplLCBudW1fZWxlbXMsIGFsaWdubWVudCkge1xuICAgICAgICB0aGlzLm5vdE5lc3RlZCgpO1xuICAgICAgICB0aGlzLnZlY3Rvcl9udW1fZWxlbXMgPSBudW1fZWxlbXM7XG4gICAgICAgIHRoaXMucHJlcChjb25zdGFudHNfanNfMS5TSVpFT0ZfSU5ULCBlbGVtX3NpemUgKiBudW1fZWxlbXMpO1xuICAgICAgICB0aGlzLnByZXAoYWxpZ25tZW50LCBlbGVtX3NpemUgKiBudW1fZWxlbXMpOyAvLyBKdXN0IGluIGNhc2UgYWxpZ25tZW50ID4gaW50LlxuICAgIH1cbiAgICAvKipcbiAgICAgKiBGaW5pc2ggb2ZmIHRoZSBjcmVhdGlvbiBvZiBhbiBhcnJheSBhbmQgYWxsIGl0cyBlbGVtZW50cy4gVGhlIGFycmF5IG11c3QgYmVcbiAgICAgKiBjcmVhdGVkIHdpdGggYHN0YXJ0VmVjdG9yYC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBvZmZzZXQgYXQgd2hpY2ggdGhlIG5ld2x5IGNyZWF0ZWQgYXJyYXlcbiAgICAgKiBzdGFydHMuXG4gICAgICovXG4gICAgZW5kVmVjdG9yKCkge1xuICAgICAgICB0aGlzLndyaXRlSW50MzIodGhpcy52ZWN0b3JfbnVtX2VsZW1zKTtcbiAgICAgICAgcmV0dXJuIHRoaXMub2Zmc2V0KCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVuY29kZSB0aGUgc3RyaW5nIGBzYCBpbiB0aGUgYnVmZmVyIHVzaW5nIFVURi04LiBJZiB0aGUgc3RyaW5nIHBhc3NlZCBoYXNcbiAgICAgKiBhbHJlYWR5IGJlZW4gc2Vlbiwgd2UgcmV0dXJuIHRoZSBvZmZzZXQgb2YgdGhlIGFscmVhZHkgd3JpdHRlbiBzdHJpbmdcbiAgICAgKlxuICAgICAqIEBwYXJhbSBzIFRoZSBzdHJpbmcgdG8gZW5jb2RlXG4gICAgICogQHJldHVybiBUaGUgb2Zmc2V0IGluIHRoZSBidWZmZXIgd2hlcmUgdGhlIGVuY29kZWQgc3RyaW5nIHN0YXJ0c1xuICAgICAqL1xuICAgIGNyZWF0ZVNoYXJlZFN0cmluZyhzKSB7XG4gICAgICAgIGlmICghcykge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnN0cmluZ19tYXBzKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmluZ19tYXBzID0gbmV3IE1hcCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnN0cmluZ19tYXBzLmhhcyhzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RyaW5nX21hcHMuZ2V0KHMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuY3JlYXRlU3RyaW5nKHMpO1xuICAgICAgICB0aGlzLnN0cmluZ19tYXBzLnNldChzLCBvZmZzZXQpO1xuICAgICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFbmNvZGUgdGhlIHN0cmluZyBgc2AgaW4gdGhlIGJ1ZmZlciB1c2luZyBVVEYtOC4gSWYgYSBVaW50OEFycmF5IGlzIHBhc3NlZFxuICAgICAqIGluc3RlYWQgb2YgYSBzdHJpbmcsIGl0IGlzIGFzc3VtZWQgdG8gY29udGFpbiB2YWxpZCBVVEYtOCBlbmNvZGVkIGRhdGEuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcyBUaGUgc3RyaW5nIHRvIGVuY29kZVxuICAgICAqIEByZXR1cm4gVGhlIG9mZnNldCBpbiB0aGUgYnVmZmVyIHdoZXJlIHRoZSBlbmNvZGVkIHN0cmluZyBzdGFydHNcbiAgICAgKi9cbiAgICBjcmVhdGVTdHJpbmcocykge1xuICAgICAgICBpZiAocyA9PT0gbnVsbCB8fCBzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGxldCB1dGY4O1xuICAgICAgICBpZiAocyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgICAgICAgIHV0ZjggPSBzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdXRmOCA9IHRoaXMudGV4dF9lbmNvZGVyLmVuY29kZShzKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFkZEludDgoMCk7XG4gICAgICAgIHRoaXMuc3RhcnRWZWN0b3IoMSwgdXRmOC5sZW5ndGgsIDEpO1xuICAgICAgICB0aGlzLmJiLnNldFBvc2l0aW9uKHRoaXMuc3BhY2UgLT0gdXRmOC5sZW5ndGgpO1xuICAgICAgICB0aGlzLmJiLmJ5dGVzKCkuc2V0KHV0ZjgsIHRoaXMuc3BhY2UpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbmRWZWN0b3IoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgYnl0ZSB2ZWN0b3IuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdiBUaGUgYnl0ZXMgdG8gYWRkXG4gICAgICogQHJldHVybnMgVGhlIG9mZnNldCBpbiB0aGUgYnVmZmVyIHdoZXJlIHRoZSBieXRlIHZlY3RvciBzdGFydHNcbiAgICAgKi9cbiAgICBjcmVhdGVCeXRlVmVjdG9yKHYpIHtcbiAgICAgICAgaWYgKHYgPT09IG51bGwgfHwgdiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0YXJ0VmVjdG9yKDEsIHYubGVuZ3RoLCAxKTtcbiAgICAgICAgdGhpcy5iYi5zZXRQb3NpdGlvbih0aGlzLnNwYWNlIC09IHYubGVuZ3RoKTtcbiAgICAgICAgdGhpcy5iYi5ieXRlcygpLnNldCh2LCB0aGlzLnNwYWNlKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5kVmVjdG9yKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIHBhY2sgYW4gb2JqZWN0XG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBvZmZzZXQgb2Ygb2JqXG4gICAgICovXG4gICAgY3JlYXRlT2JqZWN0T2Zmc2V0KG9iaikge1xuICAgICAgICBpZiAob2JqID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZVN0cmluZyhvYmopO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG9iai5wYWNrKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIHBhY2sgYSBsaXN0IG9mIG9iamVjdFxuICAgICAqXG4gICAgICogQHJldHVybnMgbGlzdCBvZiBvZmZzZXRzIG9mIGVhY2ggbm9uIG51bGwgb2JqZWN0XG4gICAgICovXG4gICAgY3JlYXRlT2JqZWN0T2Zmc2V0TGlzdChsaXN0KSB7XG4gICAgICAgIGNvbnN0IHJldCA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbCA9IGxpc3RbaV07XG4gICAgICAgICAgICBpZiAodmFsICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0LnB1c2godGhpcy5jcmVhdGVPYmplY3RPZmZzZXQodmFsKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGbGF0QnVmZmVyczogQXJndW1lbnQgZm9yIGNyZWF0ZU9iamVjdE9mZnNldExpc3QgY2Fubm90IGNvbnRhaW4gbnVsbC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cbiAgICBjcmVhdGVTdHJ1Y3RPZmZzZXRMaXN0KGxpc3QsIHN0YXJ0RnVuYykge1xuICAgICAgICBzdGFydEZ1bmModGhpcywgbGlzdC5sZW5ndGgpO1xuICAgICAgICB0aGlzLmNyZWF0ZU9iamVjdE9mZnNldExpc3QobGlzdC5zbGljZSgpLnJldmVyc2UoKSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVuZFZlY3RvcigpO1xuICAgIH1cbn1cbmV4cG9ydHMuQnVpbGRlciA9IEJ1aWxkZXI7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkJ5dGVCdWZmZXIgPSBleHBvcnRzLkJ1aWxkZXIgPSBleHBvcnRzLkVuY29kaW5nID0gZXhwb3J0cy5pc0xpdHRsZUVuZGlhbiA9IGV4cG9ydHMuZmxvYXQ2NCA9IGV4cG9ydHMuZmxvYXQzMiA9IGV4cG9ydHMuaW50MzIgPSBleHBvcnRzLlNJWkVfUFJFRklYX0xFTkdUSCA9IGV4cG9ydHMuRklMRV9JREVOVElGSUVSX0xFTkdUSCA9IGV4cG9ydHMuU0laRU9GX0lOVCA9IGV4cG9ydHMuU0laRU9GX1NIT1JUID0gdm9pZCAwO1xudmFyIGNvbnN0YW50c19qc18xID0gcmVxdWlyZShcIi4vY29uc3RhbnRzLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiU0laRU9GX1NIT1JUXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdGFudHNfanNfMS5TSVpFT0ZfU0hPUlQ7IH0gfSk7XG52YXIgY29uc3RhbnRzX2pzXzIgPSByZXF1aXJlKFwiLi9jb25zdGFudHMuanNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJTSVpFT0ZfSU5UXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdGFudHNfanNfMi5TSVpFT0ZfSU5UOyB9IH0pO1xudmFyIGNvbnN0YW50c19qc18zID0gcmVxdWlyZShcIi4vY29uc3RhbnRzLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiRklMRV9JREVOVElGSUVSX0xFTkdUSFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RhbnRzX2pzXzMuRklMRV9JREVOVElGSUVSX0xFTkdUSDsgfSB9KTtcbnZhciBjb25zdGFudHNfanNfNCA9IHJlcXVpcmUoXCIuL2NvbnN0YW50cy5qc1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlNJWkVfUFJFRklYX0xFTkdUSFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RhbnRzX2pzXzQuU0laRV9QUkVGSVhfTEVOR1RIOyB9IH0pO1xudmFyIHV0aWxzX2pzXzEgPSByZXF1aXJlKFwiLi91dGlscy5qc1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImludDMyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB1dGlsc19qc18xLmludDMyOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZmxvYXQzMlwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdXRpbHNfanNfMS5mbG9hdDMyOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZmxvYXQ2NFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdXRpbHNfanNfMS5mbG9hdDY0OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiaXNMaXR0bGVFbmRpYW5cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHV0aWxzX2pzXzEuaXNMaXR0bGVFbmRpYW47IH0gfSk7XG52YXIgZW5jb2RpbmdfanNfMSA9IHJlcXVpcmUoXCIuL2VuY29kaW5nLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiRW5jb2RpbmdcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGVuY29kaW5nX2pzXzEuRW5jb2Rpbmc7IH0gfSk7XG52YXIgYnVpbGRlcl9qc18xID0gcmVxdWlyZShcIi4vYnVpbGRlci5qc1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkJ1aWxkZXJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJ1aWxkZXJfanNfMS5CdWlsZGVyOyB9IH0pO1xudmFyIGJ5dGVfYnVmZmVyX2pzXzEgPSByZXF1aXJlKFwiLi9ieXRlLWJ1ZmZlci5qc1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkJ5dGVCdWZmZXJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJ5dGVfYnVmZmVyX2pzXzEuQnl0ZUJ1ZmZlcjsgfSB9KTtcbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgQXJnVHlwZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9hcmctdHlwZS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBBcmdUeXBlQW5kSW5kZXgge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IEFyZ1R5cGVBbmRJbmRleCB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNBcmdUeXBlQW5kSW5kZXgoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEFyZ1R5cGVBbmRJbmRleCk6IEFyZ1R5cGVBbmRJbmRleCB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IEFyZ1R5cGVBbmRJbmRleCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0FyZ1R5cGVBbmRJbmRleChiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogQXJnVHlwZUFuZEluZGV4KTogQXJnVHlwZUFuZEluZGV4IHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgQXJnVHlwZUFuZEluZGV4KCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBhcmdUeXBlKCk6IEFyZ1R5cGUge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDgodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogQXJnVHlwZS5JTlBVVDtcbiAgfVxuXG4gIGluZGV4KCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRBcmdUeXBlQW5kSW5kZXgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gIH1cblxuICBzdGF0aWMgYWRkQXJnVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBhcmdUeXBlOiBBcmdUeXBlKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDgoMCwgYXJnVHlwZSwgQXJnVHlwZS5JTlBVVCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW5kZXgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaW5kZXg6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMigxLCBpbmRleCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kQXJnVHlwZUFuZEluZGV4KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVBcmdUeXBlQW5kSW5kZXgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgYXJnVHlwZTogQXJnVHlwZSwgaW5kZXg6IG51bWJlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgQXJnVHlwZUFuZEluZGV4LnN0YXJ0QXJnVHlwZUFuZEluZGV4KGJ1aWxkZXIpO1xuICAgIEFyZ1R5cGVBbmRJbmRleC5hZGRBcmdUeXBlKGJ1aWxkZXIsIGFyZ1R5cGUpO1xuICAgIEFyZ1R5cGVBbmRJbmRleC5hZGRJbmRleChidWlsZGVyLCBpbmRleCk7XG4gICAgcmV0dXJuIEFyZ1R5cGVBbmRJbmRleC5lbmRBcmdUeXBlQW5kSW5kZXgoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmV4cG9ydCBlbnVtIEF0dHJpYnV0ZVR5cGUge1xuICBVTkRFRklORUQgPSAwLFxuICBGTE9BVCA9IDEsXG4gIElOVCA9IDIsXG4gIFNUUklORyA9IDMsXG4gIFRFTlNPUiA9IDQsXG4gIEdSQVBIID0gNSxcbiAgRkxPQVRTID0gNixcbiAgSU5UUyA9IDcsXG4gIFNUUklOR1MgPSA4LFxuICBURU5TT1JTID0gOSxcbiAgR1JBUEhTID0gMTAsXG4gIFNQQVJTRV9URU5TT1IgPSAxMSxcbiAgU1BBUlNFX1RFTlNPUlMgPSAxMixcbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmV4cG9ydCBlbnVtIE5vZGVUeXBlIHtcbiAgUHJpbWl0aXZlID0gMCxcbiAgRnVzZWQgPSAxLFxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBBdHRyaWJ1dGUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvYXR0cmlidXRlLmpzJztcbmltcG9ydCB7IE5vZGVUeXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL25vZGUtdHlwZS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBOb2RlIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBOb2RlIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc05vZGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE5vZGUpOiBOb2RlIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgTm9kZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc05vZGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE5vZGUpOiBOb2RlIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgTm9kZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgbmFtZSgpOiBzdHJpbmcgfCBudWxsO1xuICBuYW1lKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIG5hbWUob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBkb2NTdHJpbmcoKTogc3RyaW5nIHwgbnVsbDtcbiAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGRvbWFpbigpOiBzdHJpbmcgfCBudWxsO1xuICBkb21haW4ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZG9tYWluKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgc2luY2VWZXJzaW9uKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBpbmRleCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG9wVHlwZSgpOiBzdHJpbmcgfCBudWxsO1xuICBvcFR5cGUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgb3BUeXBlKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHR5cGUoKTogTm9kZVR5cGUge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBOb2RlVHlwZS5QcmltaXRpdmU7XG4gIH1cblxuICBleGVjdXRpb25Qcm92aWRlclR5cGUoKTogc3RyaW5nIHwgbnVsbDtcbiAgZXhlY3V0aW9uUHJvdmlkZXJUeXBlKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGV4ZWN1dGlvblByb3ZpZGVyVHlwZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBpbnB1dHMoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgaW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheTtcbiAgaW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDIwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBpbnB1dHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG91dHB1dHMoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgb3V0cHV0cyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gIG91dHB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjIpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIG91dHB1dHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjIpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGF0dHJpYnV0ZXMoaW5kZXg6IG51bWJlciwgb2JqPzogQXR0cmlidXRlKTogQXR0cmlidXRlIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI0KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IEF0dHJpYnV0ZSgpKS5fX2luaXQoXG4gICAgICAgICAgdGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLFxuICAgICAgICAgIHRoaXMuYmIhLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBhdHRyaWJ1dGVzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBpbnB1dEFyZ0NvdW50cyhpbmRleDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCkgOiAwO1xuICB9XG5cbiAgaW5wdXRBcmdDb3VudHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGlucHV0QXJnQ291bnRzQXJyYXkoKTogSW50MzJBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyNik7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyBuZXcgSW50MzJBcnJheShcbiAgICAgICAgICB0aGlzLmJiIS5ieXRlcygpLmJ1ZmZlcixcbiAgICAgICAgICB0aGlzLmJiIS5ieXRlcygpLmJ5dGVPZmZzZXQgKyB0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCksXG4gICAgICAgICAgdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgaW1wbGljaXRJbnB1dHMoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgaW1wbGljaXRJbnB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5O1xuICBpbXBsaWNpdElucHV0cyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgaW1wbGljaXRJbnB1dHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjgpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE5vZGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMTMpO1xuICB9XG5cbiAgc3RhdGljIGFkZE5hbWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBuYW1lT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREb2NTdHJpbmcoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGRvY1N0cmluZ09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkRG9tYWluKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRvbWFpbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgyLCBkb21haW5PZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZFNpbmNlVmVyc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBzaW5jZVZlcnNpb246IG51bWJlcikge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMigzLCBzaW5jZVZlcnNpb24sIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZEluZGV4KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGluZGV4OiBudW1iZXIpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoNCwgaW5kZXgsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZE9wVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBvcFR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNSwgb3BUeXBlT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHR5cGU6IE5vZGVUeXBlKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDYsIHR5cGUsIE5vZGVUeXBlLlByaW1pdGl2ZSk7XG4gIH1cblxuICBzdGF0aWMgYWRkRXhlY3V0aW9uUHJvdmlkZXJUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGV4ZWN1dGlvblByb3ZpZGVyVHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg3LCBleGVjdXRpb25Qcm92aWRlclR5cGVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZElucHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbnB1dHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoOCwgaW5wdXRzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbnB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0SW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRPdXRwdXRzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG91dHB1dHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoOSwgb3V0cHV0c09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlT3V0cHV0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRPdXRwdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRBdHRyaWJ1dGVzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGF0dHJpYnV0ZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMTAsIGF0dHJpYnV0ZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUF0dHJpYnV0ZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0QXR0cmlidXRlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW5wdXRBcmdDb3VudHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaW5wdXRBcmdDb3VudHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMTEsIGlucHV0QXJnQ291bnRzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbnB1dEFyZ0NvdW50c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBudW1iZXJbXSB8IEludDMyQXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQ7XG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBUaGlzIFVpbnQ4QXJyYXkgb3ZlcmxvYWQgd2lsbCBiZSByZW1vdmVkIGluIHRoZSBmdXR1cmUuXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlSW5wdXRBcmdDb3VudHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogbnVtYmVyW10gfCBVaW50OEFycmF5KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0O1xuICBzdGF0aWMgY3JlYXRlSW5wdXRBcmdDb3VudHNWZWN0b3IoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBkYXRhOiBudW1iZXJbXSB8IEludDMyQXJyYXkgfCBVaW50OEFycmF5LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZEludDMyKGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbnB1dEFyZ0NvdW50c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW1wbGljaXRJbnB1dHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaW1wbGljaXRJbnB1dHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMTIsIGltcGxpY2l0SW5wdXRzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbXBsaWNpdElucHV0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbXBsaWNpdElucHV0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kTm9kZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlTm9kZShcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIG5hbWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBkb21haW5PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBzaW5jZVZlcnNpb246IG51bWJlcixcbiAgICBpbmRleDogbnVtYmVyLFxuICAgIG9wVHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIHR5cGU6IE5vZGVUeXBlLFxuICAgIGV4ZWN1dGlvblByb3ZpZGVyVHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGlucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIG91dHB1dHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBhdHRyaWJ1dGVzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgaW5wdXRBcmdDb3VudHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBpbXBsaWNpdElucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIE5vZGUuc3RhcnROb2RlKGJ1aWxkZXIpO1xuICAgIE5vZGUuYWRkTmFtZShidWlsZGVyLCBuYW1lT2Zmc2V0KTtcbiAgICBOb2RlLmFkZERvY1N0cmluZyhidWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQpO1xuICAgIE5vZGUuYWRkRG9tYWluKGJ1aWxkZXIsIGRvbWFpbk9mZnNldCk7XG4gICAgTm9kZS5hZGRTaW5jZVZlcnNpb24oYnVpbGRlciwgc2luY2VWZXJzaW9uKTtcbiAgICBOb2RlLmFkZEluZGV4KGJ1aWxkZXIsIGluZGV4KTtcbiAgICBOb2RlLmFkZE9wVHlwZShidWlsZGVyLCBvcFR5cGVPZmZzZXQpO1xuICAgIE5vZGUuYWRkVHlwZShidWlsZGVyLCB0eXBlKTtcbiAgICBOb2RlLmFkZEV4ZWN1dGlvblByb3ZpZGVyVHlwZShidWlsZGVyLCBleGVjdXRpb25Qcm92aWRlclR5cGVPZmZzZXQpO1xuICAgIE5vZGUuYWRkSW5wdXRzKGJ1aWxkZXIsIGlucHV0c09mZnNldCk7XG4gICAgTm9kZS5hZGRPdXRwdXRzKGJ1aWxkZXIsIG91dHB1dHNPZmZzZXQpO1xuICAgIE5vZGUuYWRkQXR0cmlidXRlcyhidWlsZGVyLCBhdHRyaWJ1dGVzT2Zmc2V0KTtcbiAgICBOb2RlLmFkZElucHV0QXJnQ291bnRzKGJ1aWxkZXIsIGlucHV0QXJnQ291bnRzT2Zmc2V0KTtcbiAgICBOb2RlLmFkZEltcGxpY2l0SW5wdXRzKGJ1aWxkZXIsIGltcGxpY2l0SW5wdXRzT2Zmc2V0KTtcbiAgICByZXR1cm4gTm9kZS5lbmROb2RlKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmV4cG9ydCBjbGFzcyBFZGdlRW5kIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBFZGdlRW5kIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbm9kZUluZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MpO1xuICB9XG5cbiAgc3JjQXJnSW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgNCk7XG4gIH1cblxuICBkc3RBcmdJbmRleCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYl9wb3MgKyA4KTtcbiAgfVxuXG4gIHN0YXRpYyBzaXplT2YoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gMTI7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlRWRnZUVuZChcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIG5vZGVfaW5kZXg6IG51bWJlcixcbiAgICBzcmNfYXJnX2luZGV4OiBudW1iZXIsXG4gICAgZHN0X2FyZ19pbmRleDogbnVtYmVyLFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIucHJlcCg0LCAxMik7XG4gICAgYnVpbGRlci53cml0ZUludDMyKGRzdF9hcmdfaW5kZXgpO1xuICAgIGJ1aWxkZXIud3JpdGVJbnQzMihzcmNfYXJnX2luZGV4KTtcbiAgICBidWlsZGVyLndyaXRlSW50MzIobm9kZV9pbmRleCk7XG4gICAgcmV0dXJuIGJ1aWxkZXIub2Zmc2V0KCk7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgRWRnZUVuZCB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9lZGdlLWVuZC5qcyc7XG5cbmV4cG9ydCBjbGFzcyBOb2RlRWRnZSB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogTm9kZUVkZ2Uge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzTm9kZUVkZ2UoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE5vZGVFZGdlKTogTm9kZUVkZ2Uge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlRWRnZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc05vZGVFZGdlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBOb2RlRWRnZSk6IE5vZGVFZGdlIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgTm9kZUVkZ2UoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIG5vZGVJbmRleCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZFVpbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgaW5wdXRFZGdlcyhpbmRleDogbnVtYmVyLCBvYmo/OiBFZGdlRW5kKTogRWRnZUVuZCB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IEVkZ2VFbmQoKSkuX19pbml0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogMTIsIHRoaXMuYmIhKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgaW5wdXRFZGdlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBvdXRwdXRFZGdlcyhpbmRleDogbnVtYmVyLCBvYmo/OiBFZGdlRW5kKTogRWRnZUVuZCB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IEVkZ2VFbmQoKSkuX19pbml0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogMTIsIHRoaXMuYmIhKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgb3V0cHV0RWRnZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0Tm9kZUVkZ2UoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMyk7XG4gIH1cblxuICBzdGF0aWMgYWRkTm9kZUluZGV4KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVJbmRleDogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDAsIG5vZGVJbmRleCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW5wdXRFZGdlcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbnB1dEVkZ2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGlucHV0RWRnZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0SW5wdXRFZGdlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3RvcigxMiwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZE91dHB1dEVkZ2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG91dHB1dEVkZ2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDIsIG91dHB1dEVkZ2VzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE91dHB1dEVkZ2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDEyLCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kTm9kZUVkZ2UoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU5vZGVFZGdlKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgbm9kZUluZGV4OiBudW1iZXIsXG4gICAgaW5wdXRFZGdlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIG91dHB1dEVkZ2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgTm9kZUVkZ2Uuc3RhcnROb2RlRWRnZShidWlsZGVyKTtcbiAgICBOb2RlRWRnZS5hZGROb2RlSW5kZXgoYnVpbGRlciwgbm9kZUluZGV4KTtcbiAgICBOb2RlRWRnZS5hZGRJbnB1dEVkZ2VzKGJ1aWxkZXIsIGlucHV0RWRnZXNPZmZzZXQpO1xuICAgIE5vZGVFZGdlLmFkZE91dHB1dEVkZ2VzKGJ1aWxkZXIsIG91dHB1dEVkZ2VzT2Zmc2V0KTtcbiAgICByZXR1cm4gTm9kZUVkZ2UuZW5kTm9kZUVkZ2UoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuLyoqXG4gKiBub2RlcyB0byBjb25zaWRlciBmb3IgYSBydW50aW1lIG9wdGltaXphdGlvblxuICogc2VlIGNvcnJlc3BvbmRpbmcgdHlwZSBpbiBvbm54cnVudGltZS9jb3JlL2dyYXBoL3J1bnRpbWVfb3B0aW1pemF0aW9uX3JlY29yZC5oXG4gKi9cbmV4cG9ydCBjbGFzcyBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc05vZGVzVG9PcHRpbWl6ZUluZGljZXMoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogTm9kZXNUb09wdGltaXplSW5kaWNlcyxcbiAgKTogTm9kZXNUb09wdGltaXplSW5kaWNlcyB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNOb2Rlc1RvT3B0aW1pemVJbmRpY2VzKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IE5vZGVzVG9PcHRpbWl6ZUluZGljZXMsXG4gICk6IE5vZGVzVG9PcHRpbWl6ZUluZGljZXMge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBub2RlSW5kaWNlcyhpbmRleDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDMyKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCkgOiAwO1xuICB9XG5cbiAgbm9kZUluZGljZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgbm9kZUluZGljZXNBcnJheSgpOiBVaW50MzJBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IG5ldyBVaW50MzJBcnJheShcbiAgICAgICAgICB0aGlzLmJiIS5ieXRlcygpLmJ1ZmZlcixcbiAgICAgICAgICB0aGlzLmJiIS5ieXRlcygpLmJ5dGVPZmZzZXQgKyB0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCksXG4gICAgICAgICAgdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgbnVtSW5wdXRzKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBudW1PdXRwdXRzKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBoYXNWYXJpYWRpY0lucHV0KCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMCk7XG4gICAgcmV0dXJuIG9mZnNldCA/ICEhdGhpcy5iYiEucmVhZEludDgodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogZmFsc2U7XG4gIH1cblxuICBoYXNWYXJpYWRpY091dHB1dCgpOiBib29sZWFuIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgIHJldHVybiBvZmZzZXQgPyAhIXRoaXMuYmIhLnJlYWRJbnQ4KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IGZhbHNlO1xuICB9XG5cbiAgbnVtVmFyaWFkaWNJbnB1dHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBudW1WYXJpYWRpY091dHB1dHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnROb2Rlc1RvT3B0aW1pemVJbmRpY2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDcpO1xuICB9XG5cbiAgc3RhdGljIGFkZE5vZGVJbmRpY2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVJbmRpY2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG5vZGVJbmRpY2VzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVOb2RlSW5kaWNlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBudW1iZXJbXSB8IFVpbnQzMkFycmF5KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0O1xuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgVGhpcyBVaW50OEFycmF5IG92ZXJsb2FkIHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgZnV0dXJlLlxuICAgKi9cbiAgc3RhdGljIGNyZWF0ZU5vZGVJbmRpY2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IG51bWJlcltdIHwgVWludDhBcnJheSk6IGZsYXRidWZmZXJzLk9mZnNldDtcbiAgc3RhdGljIGNyZWF0ZU5vZGVJbmRpY2VzVmVjdG9yKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgZGF0YTogbnVtYmVyW10gfCBVaW50MzJBcnJheSB8IFVpbnQ4QXJyYXksXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkSW50MzIoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE5vZGVJbmRpY2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGROdW1JbnB1dHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtSW5wdXRzOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMSwgbnVtSW5wdXRzLCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGROdW1PdXRwdXRzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bU91dHB1dHM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMigyLCBudW1PdXRwdXRzLCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRIYXNWYXJpYWRpY0lucHV0KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGhhc1ZhcmlhZGljSW5wdXQ6IGJvb2xlYW4pIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50OCgzLCAraGFzVmFyaWFkaWNJbnB1dCwgK2ZhbHNlKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRIYXNWYXJpYWRpY091dHB1dChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBoYXNWYXJpYWRpY091dHB1dDogYm9vbGVhbikge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ4KDQsICtoYXNWYXJpYWRpY091dHB1dCwgK2ZhbHNlKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGROdW1WYXJpYWRpY0lucHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1WYXJpYWRpY0lucHV0czogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDUsIG51bVZhcmlhZGljSW5wdXRzLCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGROdW1WYXJpYWRpY091dHB1dHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtVmFyaWFkaWNPdXRwdXRzOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoNiwgbnVtVmFyaWFkaWNPdXRwdXRzLCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBlbmROb2Rlc1RvT3B0aW1pemVJbmRpY2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVOb2Rlc1RvT3B0aW1pemVJbmRpY2VzKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgbm9kZUluZGljZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBudW1JbnB1dHM6IG51bWJlcixcbiAgICBudW1PdXRwdXRzOiBudW1iZXIsXG4gICAgaGFzVmFyaWFkaWNJbnB1dDogYm9vbGVhbixcbiAgICBoYXNWYXJpYWRpY091dHB1dDogYm9vbGVhbixcbiAgICBudW1WYXJpYWRpY0lucHV0czogbnVtYmVyLFxuICAgIG51bVZhcmlhZGljT3V0cHV0czogbnVtYmVyLFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMuc3RhcnROb2Rlc1RvT3B0aW1pemVJbmRpY2VzKGJ1aWxkZXIpO1xuICAgIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMuYWRkTm9kZUluZGljZXMoYnVpbGRlciwgbm9kZUluZGljZXNPZmZzZXQpO1xuICAgIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMuYWRkTnVtSW5wdXRzKGJ1aWxkZXIsIG51bUlucHV0cyk7XG4gICAgTm9kZXNUb09wdGltaXplSW5kaWNlcy5hZGROdW1PdXRwdXRzKGJ1aWxkZXIsIG51bU91dHB1dHMpO1xuICAgIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMuYWRkSGFzVmFyaWFkaWNJbnB1dChidWlsZGVyLCBoYXNWYXJpYWRpY0lucHV0KTtcbiAgICBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzLmFkZEhhc1ZhcmlhZGljT3V0cHV0KGJ1aWxkZXIsIGhhc1ZhcmlhZGljT3V0cHV0KTtcbiAgICBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzLmFkZE51bVZhcmlhZGljSW5wdXRzKGJ1aWxkZXIsIG51bVZhcmlhZGljSW5wdXRzKTtcbiAgICBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzLmFkZE51bVZhcmlhZGljT3V0cHV0cyhidWlsZGVyLCBudW1WYXJpYWRpY091dHB1dHMpO1xuICAgIHJldHVybiBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzLmVuZE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgTm9kZXNUb09wdGltaXplSW5kaWNlcyB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9ub2Rlcy10by1vcHRpbWl6ZS1pbmRpY2VzLmpzJztcblxuLyoqXG4gKiBhIHNpbmdsZSBydW50aW1lIG9wdGltaXphdGlvblxuICogc2VlIGNvcnJlc3BvbmRpbmcgdHlwZSBpbiBvbm54cnVudGltZS9jb3JlL2dyYXBoL3J1bnRpbWVfb3B0aW1pemF0aW9uX3JlY29yZC5oXG4gKi9cbmV4cG9ydCBjbGFzcyBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc1J1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogUnVudGltZU9wdGltaXphdGlvblJlY29yZCxcbiAgKTogUnVudGltZU9wdGltaXphdGlvblJlY29yZCB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQsXG4gICk6IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBhY3Rpb25JZCgpOiBzdHJpbmcgfCBudWxsO1xuICBhY3Rpb25JZChvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBhY3Rpb25JZChvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIG5vZGVzVG9PcHRpbWl6ZUluZGljZXMob2JqPzogTm9kZXNUb09wdGltaXplSW5kaWNlcyk6IE5vZGVzVG9PcHRpbWl6ZUluZGljZXMgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBwcm9kdWNlZE9wSWRzKGluZGV4OiBudW1iZXIpOiBzdHJpbmc7XG4gIHByb2R1Y2VkT3BJZHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5O1xuICBwcm9kdWNlZE9wSWRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBwcm9kdWNlZE9wSWRzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZEFjdGlvbklkKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGFjdGlvbklkT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGFjdGlvbklkT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGROb2Rlc1RvT3B0aW1pemVJbmRpY2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVzVG9PcHRpbWl6ZUluZGljZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgbm9kZXNUb09wdGltaXplSW5kaWNlc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkUHJvZHVjZWRPcElkcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBwcm9kdWNlZE9wSWRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDMsIHByb2R1Y2VkT3BJZHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVByb2R1Y2VkT3BJZHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0UHJvZHVjZWRPcElkc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kUnVudGltZU9wdGltaXphdGlvblJlY29yZChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgUnVudGltZU9wdGltaXphdGlvblJlY29yZCB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9ydW50aW1lLW9wdGltaXphdGlvbi1yZWNvcmQuanMnO1xuXG5leHBvcnQgY2xhc3MgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5IHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSxcbiAgKTogUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5IHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KCkpLl9faW5pdChcbiAgICAgIGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksXG4gICAgICBiYixcbiAgICApO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1J1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeShcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnksXG4gICk6IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSgpKS5fX2luaXQoXG4gICAgICBiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLFxuICAgICAgYmIsXG4gICAgKTtcbiAgfVxuXG4gIG9wdGltaXplck5hbWUoKTogc3RyaW5nIHwgbnVsbDtcbiAgb3B0aW1pemVyTmFtZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBvcHRpbWl6ZXJOYW1lKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgcnVudGltZU9wdGltaXphdGlvblJlY29yZHMoaW5kZXg6IG51bWJlciwgb2JqPzogUnVudGltZU9wdGltaXphdGlvblJlY29yZCk6IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkKCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRPcHRpbWl6ZXJOYW1lKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG9wdGltaXplck5hbWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgb3B0aW1pemVyTmFtZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkUnVudGltZU9wdGltaXphdGlvblJlY29yZHMoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBydW50aW1lT3B0aW1pemF0aW9uUmVjb3Jkc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIHJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVSdW50aW1lT3B0aW1pemF0aW9uUmVjb3Jkc1ZlY3RvcihcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdLFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0UnVudGltZU9wdGltaXphdGlvblJlY29yZHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGVuZFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIGJ1aWxkZXIucmVxdWlyZWRGaWVsZChvZmZzZXQsIDQpOyAvLyBvcHRpbWl6ZXJfbmFtZVxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgb3B0aW1pemVyTmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIHJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5LnN0YXJ0UnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KGJ1aWxkZXIpO1xuICAgIFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeS5hZGRPcHRpbWl6ZXJOYW1lKGJ1aWxkZXIsIG9wdGltaXplck5hbWVPZmZzZXQpO1xuICAgIFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeS5hZGRSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkcyhidWlsZGVyLCBydW50aW1lT3B0aW1pemF0aW9uUmVjb3Jkc09mZnNldCk7XG4gICAgcmV0dXJuIFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeS5lbmRSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5IH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9uLXJlY29yZC1jb250YWluZXItZW50cnkuanMnO1xuXG5leHBvcnQgY2xhc3MgUnVudGltZU9wdGltaXphdGlvbnMge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFJ1bnRpbWVPcHRpbWl6YXRpb25zIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc1J1bnRpbWVPcHRpbWl6YXRpb25zKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBSdW50aW1lT3B0aW1pemF0aW9ucyk6IFJ1bnRpbWVPcHRpbWl6YXRpb25zIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgUnVudGltZU9wdGltaXphdGlvbnMoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNSdW50aW1lT3B0aW1pemF0aW9ucyhcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBSdW50aW1lT3B0aW1pemF0aW9ucyxcbiAgKTogUnVudGltZU9wdGltaXphdGlvbnMge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBSdW50aW1lT3B0aW1pemF0aW9ucygpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgLyoqXG4gICAqIG1hcHBpbmcgZnJvbSBvcHRpbWl6ZXIgbmFtZSB0byBbUnVudGltZU9wdGltaXphdGlvblJlY29yZF1cbiAgICovXG4gIHJlY29yZHMoXG4gICAgaW5kZXg6IG51bWJlcixcbiAgICBvYmo/OiBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnksXG4gICk6IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSgpKS5fX2luaXQoXG4gICAgICAgICAgdGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLFxuICAgICAgICAgIHRoaXMuYmIhLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICByZWNvcmRzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFJ1bnRpbWVPcHRpbWl6YXRpb25zKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDEpO1xuICB9XG5cbiAgc3RhdGljIGFkZFJlY29yZHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgcmVjb3Jkc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCByZWNvcmRzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVSZWNvcmRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFJlY29yZHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGVuZFJ1bnRpbWVPcHRpbWl6YXRpb25zKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVSdW50aW1lT3B0aW1pemF0aW9ucyhcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIHJlY29yZHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBSdW50aW1lT3B0aW1pemF0aW9ucy5zdGFydFJ1bnRpbWVPcHRpbWl6YXRpb25zKGJ1aWxkZXIpO1xuICAgIFJ1bnRpbWVPcHRpbWl6YXRpb25zLmFkZFJlY29yZHMoYnVpbGRlciwgcmVjb3Jkc09mZnNldCk7XG4gICAgcmV0dXJuIFJ1bnRpbWVPcHRpbWl6YXRpb25zLmVuZFJ1bnRpbWVPcHRpbWl6YXRpb25zKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5leHBvcnQgZW51bSBUZW5zb3JEYXRhVHlwZSB7XG4gIFVOREVGSU5FRCA9IDAsXG4gIEZMT0FUID0gMSxcbiAgVUlOVDggPSAyLFxuICBJTlQ4ID0gMyxcbiAgVUlOVDE2ID0gNCxcbiAgSU5UMTYgPSA1LFxuICBJTlQzMiA9IDYsXG4gIElOVDY0ID0gNyxcbiAgU1RSSU5HID0gOCxcbiAgQk9PTCA9IDksXG4gIEZMT0FUMTYgPSAxMCxcbiAgRE9VQkxFID0gMTEsXG4gIFVJTlQzMiA9IDEyLFxuICBVSU5UNjQgPSAxMyxcbiAgQ09NUExFWDY0ID0gMTQsXG4gIENPTVBMRVgxMjggPSAxNSxcbiAgQkZMT0FUMTYgPSAxNixcbiAgRkxPQVQ4RTRNM0ZOID0gMTcsXG4gIEZMT0FUOEU0TTNGTlVaID0gMTgsXG4gIEZMT0FUOEU1TTIgPSAxOSxcbiAgRkxPQVQ4RTVNMkZOVVogPSAyMCxcbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgVGVuc29yRGF0YVR5cGUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvdGVuc29yLWRhdGEtdHlwZS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBUZW5zb3Ige1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFRlbnNvciB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNUZW5zb3IoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFRlbnNvcik6IFRlbnNvciB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFRlbnNvcigpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1RlbnNvcihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogVGVuc29yKTogVGVuc29yIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgVGVuc29yKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBuYW1lKCk6IHN0cmluZyB8IG51bGw7XG4gIG5hbWUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgbmFtZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGRvY1N0cmluZygpOiBzdHJpbmcgfCBudWxsO1xuICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgZGltcyhpbmRleDogbnVtYmVyKTogYmlnaW50IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50NjQodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA4KSA6IEJpZ0ludCgwKTtcbiAgfVxuXG4gIGRpbXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgZGF0YVR5cGUoKTogVGVuc29yRGF0YVR5cGUge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBUZW5zb3JEYXRhVHlwZS5VTkRFRklORUQ7XG4gIH1cblxuICByYXdEYXRhKGluZGV4OiBudW1iZXIpOiBudW1iZXIgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDgodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXgpIDogMDtcbiAgfVxuXG4gIHJhd0RhdGFMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHJhd0RhdGFBcnJheSgpOiBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IG5ldyBVaW50OEFycmF5KFxuICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnVmZmVyLFxuICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnl0ZU9mZnNldCArIHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgICB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBzdHJpbmdEYXRhKGluZGV4OiBudW1iZXIpOiBzdHJpbmc7XG4gIHN0cmluZ0RhdGEoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5O1xuICBzdHJpbmdEYXRhKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBzdHJpbmdEYXRhTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBleHRlcm5hbERhdGFPZmZzZXQoKTogYmlnaW50IHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50NjQodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogQmlnSW50KCctMScpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0VGVuc29yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDcpO1xuICB9XG5cbiAgc3RhdGljIGFkZE5hbWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBuYW1lT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREb2NTdHJpbmcoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGRvY1N0cmluZ09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkRGltcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkaW1zT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDIsIGRpbXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZURpbXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogYmlnaW50W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgZGF0YS5sZW5ndGgsIDgpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZEludDY0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnREaW1zVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDgsIG51bUVsZW1zLCA4KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREYXRhVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhVHlwZTogVGVuc29yRGF0YVR5cGUpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMywgZGF0YVR5cGUsIFRlbnNvckRhdGFUeXBlLlVOREVGSU5FRCk7XG4gIH1cblxuICBzdGF0aWMgYWRkUmF3RGF0YShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCByYXdEYXRhT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDQsIHJhd0RhdGFPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVJhd0RhdGFWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogbnVtYmVyW10gfCBVaW50OEFycmF5KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDEsIGRhdGEubGVuZ3RoLCAxKTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRJbnQ4KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRSYXdEYXRhVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDEsIG51bUVsZW1zLCAxKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRTdHJpbmdEYXRhKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHN0cmluZ0RhdGFPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNSwgc3RyaW5nRGF0YU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlU3RyaW5nRGF0YVZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRTdHJpbmdEYXRhVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRFeHRlcm5hbERhdGFPZmZzZXQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZXh0ZXJuYWxEYXRhT2Zmc2V0OiBiaWdpbnQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50NjQoNiwgZXh0ZXJuYWxEYXRhT2Zmc2V0LCBCaWdJbnQoJy0xJykpO1xuICB9XG5cbiAgc3RhdGljIGVuZFRlbnNvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlVGVuc29yKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGRvY1N0cmluZ09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGRpbXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBkYXRhVHlwZTogVGVuc29yRGF0YVR5cGUsXG4gICAgcmF3RGF0YU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIHN0cmluZ0RhdGFPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBleHRlcm5hbERhdGFPZmZzZXQ6IGJpZ2ludCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBUZW5zb3Iuc3RhcnRUZW5zb3IoYnVpbGRlcik7XG4gICAgVGVuc29yLmFkZE5hbWUoYnVpbGRlciwgbmFtZU9mZnNldCk7XG4gICAgVGVuc29yLmFkZERvY1N0cmluZyhidWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQpO1xuICAgIFRlbnNvci5hZGREaW1zKGJ1aWxkZXIsIGRpbXNPZmZzZXQpO1xuICAgIFRlbnNvci5hZGREYXRhVHlwZShidWlsZGVyLCBkYXRhVHlwZSk7XG4gICAgVGVuc29yLmFkZFJhd0RhdGEoYnVpbGRlciwgcmF3RGF0YU9mZnNldCk7XG4gICAgVGVuc29yLmFkZFN0cmluZ0RhdGEoYnVpbGRlciwgc3RyaW5nRGF0YU9mZnNldCk7XG4gICAgVGVuc29yLmFkZEV4dGVybmFsRGF0YU9mZnNldChidWlsZGVyLCBleHRlcm5hbERhdGFPZmZzZXQpO1xuICAgIHJldHVybiBUZW5zb3IuZW5kVGVuc29yKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy90ZW5zb3IuanMnO1xuXG5leHBvcnQgY2xhc3MgU3BhcnNlVGVuc29yIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBTcGFyc2VUZW5zb3Ige1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzU3BhcnNlVGVuc29yKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTcGFyc2VUZW5zb3IpOiBTcGFyc2VUZW5zb3Ige1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBTcGFyc2VUZW5zb3IoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNTcGFyc2VUZW5zb3IoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFNwYXJzZVRlbnNvcik6IFNwYXJzZVRlbnNvciB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFNwYXJzZVRlbnNvcigpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgdmFsdWVzKG9iaj86IFRlbnNvcik6IFRlbnNvciB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgVGVuc29yKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDogbnVsbDtcbiAgfVxuXG4gIGluZGljZXMob2JqPzogVGVuc29yKTogVGVuc29yIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBUZW5zb3IoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOiBudWxsO1xuICB9XG5cbiAgZGltcyhpbmRleDogbnVtYmVyKTogYmlnaW50IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50NjQodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA4KSA6IEJpZ0ludCgwKTtcbiAgfVxuXG4gIGRpbXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0U3BhcnNlVGVuc29yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDMpO1xuICB9XG5cbiAgc3RhdGljIGFkZFZhbHVlcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB2YWx1ZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgdmFsdWVzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRJbmRpY2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGluZGljZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgaW5kaWNlc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkRGltcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkaW1zT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDIsIGRpbXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZURpbXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogYmlnaW50W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgZGF0YS5sZW5ndGgsIDgpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZEludDY0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnREaW1zVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDgsIG51bUVsZW1zLCA4KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRTcGFyc2VUZW5zb3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IFRlbnNvckRhdGFUeXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3RlbnNvci1kYXRhLXR5cGUuanMnO1xuaW1wb3J0IHsgVHlwZUluZm8gfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvdHlwZS1pbmZvLmpzJztcblxuZXhwb3J0IGNsYXNzIE1hcFR5cGUge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IE1hcFR5cGUge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzTWFwVHlwZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTWFwVHlwZSk6IE1hcFR5cGUge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBNYXBUeXBlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzTWFwVHlwZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTWFwVHlwZSk6IE1hcFR5cGUge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBNYXBUeXBlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBrZXlUeXBlKCk6IFRlbnNvckRhdGFUeXBlIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBUZW5zb3JEYXRhVHlwZS5VTkRFRklORUQ7XG4gIH1cblxuICB2YWx1ZVR5cGUob2JqPzogVHlwZUluZm8pOiBUeXBlSW5mbyB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgVHlwZUluZm8oKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOiBudWxsO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0TWFwVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRLZXlUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtleVR5cGU6IFRlbnNvckRhdGFUeXBlKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDAsIGtleVR5cGUsIFRlbnNvckRhdGFUeXBlLlVOREVGSU5FRCk7XG4gIH1cblxuICBzdGF0aWMgYWRkVmFsdWVUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHZhbHVlVHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCB2YWx1ZVR5cGVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZE1hcFR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IFR5cGVJbmZvIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3R5cGUtaW5mby5qcyc7XG5cbmV4cG9ydCBjbGFzcyBTZXF1ZW5jZVR5cGUge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFNlcXVlbmNlVHlwZSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNTZXF1ZW5jZVR5cGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFNlcXVlbmNlVHlwZSk6IFNlcXVlbmNlVHlwZSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFNlcXVlbmNlVHlwZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1NlcXVlbmNlVHlwZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogU2VxdWVuY2VUeXBlKTogU2VxdWVuY2VUeXBlIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgU2VxdWVuY2VUeXBlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBlbGVtVHlwZShvYmo/OiBUeXBlSW5mbyk6IFR5cGVJbmZvIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBUeXBlSW5mbygpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRTZXF1ZW5jZVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMSk7XG4gIH1cblxuICBzdGF0aWMgYWRkRWxlbVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZWxlbVR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgZWxlbVR5cGVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZFNlcXVlbmNlVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlU2VxdWVuY2VUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGVsZW1UeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIFNlcXVlbmNlVHlwZS5zdGFydFNlcXVlbmNlVHlwZShidWlsZGVyKTtcbiAgICBTZXF1ZW5jZVR5cGUuYWRkRWxlbVR5cGUoYnVpbGRlciwgZWxlbVR5cGVPZmZzZXQpO1xuICAgIHJldHVybiBTZXF1ZW5jZVR5cGUuZW5kU2VxdWVuY2VUeXBlKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5leHBvcnQgZW51bSBEaW1lbnNpb25WYWx1ZVR5cGUge1xuICBVTktOT1dOID0gMCxcbiAgVkFMVUUgPSAxLFxuICBQQVJBTSA9IDIsXG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IERpbWVuc2lvblZhbHVlVHlwZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9kaW1lbnNpb24tdmFsdWUtdHlwZS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBEaW1lbnNpb25WYWx1ZSB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogRGltZW5zaW9uVmFsdWUge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzRGltZW5zaW9uVmFsdWUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IERpbWVuc2lvblZhbHVlKTogRGltZW5zaW9uVmFsdWUge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBEaW1lbnNpb25WYWx1ZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0RpbWVuc2lvblZhbHVlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBEaW1lbnNpb25WYWx1ZSk6IERpbWVuc2lvblZhbHVlIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGltZW5zaW9uVmFsdWUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGRpbVR5cGUoKTogRGltZW5zaW9uVmFsdWVUeXBlIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ4KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IERpbWVuc2lvblZhbHVlVHlwZS5VTktOT1dOO1xuICB9XG5cbiAgZGltVmFsdWUoKTogYmlnaW50IHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBCaWdJbnQoJzAnKTtcbiAgfVxuXG4gIGRpbVBhcmFtKCk6IHN0cmluZyB8IG51bGw7XG4gIGRpbVBhcmFtKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGRpbVBhcmFtKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0RGltZW5zaW9uVmFsdWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMyk7XG4gIH1cblxuICBzdGF0aWMgYWRkRGltVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkaW1UeXBlOiBEaW1lbnNpb25WYWx1ZVR5cGUpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50OCgwLCBkaW1UeXBlLCBEaW1lbnNpb25WYWx1ZVR5cGUuVU5LTk9XTik7XG4gIH1cblxuICBzdGF0aWMgYWRkRGltVmFsdWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGltVmFsdWU6IGJpZ2ludCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ2NCgxLCBkaW1WYWx1ZSwgQmlnSW50KCcwJykpO1xuICB9XG5cbiAgc3RhdGljIGFkZERpbVBhcmFtKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRpbVBhcmFtT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDIsIGRpbVBhcmFtT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBlbmREaW1lbnNpb25WYWx1ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlRGltZW5zaW9uVmFsdWUoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBkaW1UeXBlOiBEaW1lbnNpb25WYWx1ZVR5cGUsXG4gICAgZGltVmFsdWU6IGJpZ2ludCxcbiAgICBkaW1QYXJhbU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIERpbWVuc2lvblZhbHVlLnN0YXJ0RGltZW5zaW9uVmFsdWUoYnVpbGRlcik7XG4gICAgRGltZW5zaW9uVmFsdWUuYWRkRGltVHlwZShidWlsZGVyLCBkaW1UeXBlKTtcbiAgICBEaW1lbnNpb25WYWx1ZS5hZGREaW1WYWx1ZShidWlsZGVyLCBkaW1WYWx1ZSk7XG4gICAgRGltZW5zaW9uVmFsdWUuYWRkRGltUGFyYW0oYnVpbGRlciwgZGltUGFyYW1PZmZzZXQpO1xuICAgIHJldHVybiBEaW1lbnNpb25WYWx1ZS5lbmREaW1lbnNpb25WYWx1ZShidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBEaW1lbnNpb25WYWx1ZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9kaW1lbnNpb24tdmFsdWUuanMnO1xuXG5leHBvcnQgY2xhc3MgRGltZW5zaW9uIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBEaW1lbnNpb24ge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzRGltZW5zaW9uKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBEaW1lbnNpb24pOiBEaW1lbnNpb24ge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBEaW1lbnNpb24oKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNEaW1lbnNpb24oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IERpbWVuc2lvbik6IERpbWVuc2lvbiB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IERpbWVuc2lvbigpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgdmFsdWUob2JqPzogRGltZW5zaW9uVmFsdWUpOiBEaW1lbnNpb25WYWx1ZSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgRGltZW5zaW9uVmFsdWUoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOiBudWxsO1xuICB9XG5cbiAgZGVub3RhdGlvbigpOiBzdHJpbmcgfCBudWxsO1xuICBkZW5vdGF0aW9uKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGRlbm90YXRpb24ob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnREaW1lbnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gIH1cblxuICBzdGF0aWMgYWRkVmFsdWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgdmFsdWVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZERlbm90YXRpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGVub3RhdGlvbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBkZW5vdGF0aW9uT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBlbmREaW1lbnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZURpbWVuc2lvbihcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIHZhbHVlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgZGVub3RhdGlvbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIERpbWVuc2lvbi5zdGFydERpbWVuc2lvbihidWlsZGVyKTtcbiAgICBEaW1lbnNpb24uYWRkVmFsdWUoYnVpbGRlciwgdmFsdWVPZmZzZXQpO1xuICAgIERpbWVuc2lvbi5hZGREZW5vdGF0aW9uKGJ1aWxkZXIsIGRlbm90YXRpb25PZmZzZXQpO1xuICAgIHJldHVybiBEaW1lbnNpb24uZW5kRGltZW5zaW9uKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IERpbWVuc2lvbiB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9kaW1lbnNpb24uanMnO1xuXG5leHBvcnQgY2xhc3MgU2hhcGUge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFNoYXBlIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc1NoYXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTaGFwZSk6IFNoYXBlIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgU2hhcGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNTaGFwZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogU2hhcGUpOiBTaGFwZSB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFNoYXBlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBkaW0oaW5kZXg6IG51bWJlciwgb2JqPzogRGltZW5zaW9uKTogRGltZW5zaW9uIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgRGltZW5zaW9uKCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIGRpbUxlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRTaGFwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgxKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREaW0oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGltT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGRpbU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlRGltVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydERpbVZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kU2hhcGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVNoYXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRpbU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBTaGFwZS5zdGFydFNoYXBlKGJ1aWxkZXIpO1xuICAgIFNoYXBlLmFkZERpbShidWlsZGVyLCBkaW1PZmZzZXQpO1xuICAgIHJldHVybiBTaGFwZS5lbmRTaGFwZShidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBTaGFwZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9zaGFwZS5qcyc7XG5pbXBvcnQgeyBUZW5zb3JEYXRhVHlwZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy90ZW5zb3ItZGF0YS10eXBlLmpzJztcblxuZXhwb3J0IGNsYXNzIFRlbnNvclR5cGVBbmRTaGFwZSB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogVGVuc29yVHlwZUFuZFNoYXBlIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc1RlbnNvclR5cGVBbmRTaGFwZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogVGVuc29yVHlwZUFuZFNoYXBlKTogVGVuc29yVHlwZUFuZFNoYXBlIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgVGVuc29yVHlwZUFuZFNoYXBlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzVGVuc29yVHlwZUFuZFNoYXBlKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IFRlbnNvclR5cGVBbmRTaGFwZSxcbiAgKTogVGVuc29yVHlwZUFuZFNoYXBlIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgVGVuc29yVHlwZUFuZFNoYXBlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBlbGVtVHlwZSgpOiBUZW5zb3JEYXRhVHlwZSB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogVGVuc29yRGF0YVR5cGUuVU5ERUZJTkVEO1xuICB9XG5cbiAgc2hhcGUob2JqPzogU2hhcGUpOiBTaGFwZSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgU2hhcGUoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOiBudWxsO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0VGVuc29yVHlwZUFuZFNoYXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDIpO1xuICB9XG5cbiAgc3RhdGljIGFkZEVsZW1UeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGVsZW1UeXBlOiBUZW5zb3JEYXRhVHlwZSkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMigwLCBlbGVtVHlwZSwgVGVuc29yRGF0YVR5cGUuVU5ERUZJTkVEKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRTaGFwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBzaGFwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBzaGFwZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kVGVuc29yVHlwZUFuZFNoYXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0IHsgTWFwVHlwZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9tYXAtdHlwZS5qcyc7XG5pbXBvcnQgeyBTZXF1ZW5jZVR5cGUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvc2VxdWVuY2UtdHlwZS5qcyc7XG5pbXBvcnQgeyBUZW5zb3JUeXBlQW5kU2hhcGUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvdGVuc29yLXR5cGUtYW5kLXNoYXBlLmpzJztcblxuZXhwb3J0IGVudW0gVHlwZUluZm9WYWx1ZSB7XG4gIE5PTkUgPSAwLFxuICB0ZW5zb3JfdHlwZSA9IDEsXG4gIHNlcXVlbmNlX3R5cGUgPSAyLFxuICBtYXBfdHlwZSA9IDMsXG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1bmlvblRvVHlwZUluZm9WYWx1ZShcbiAgdHlwZTogVHlwZUluZm9WYWx1ZSxcbiAgYWNjZXNzb3I6IChvYmo6IE1hcFR5cGUgfCBTZXF1ZW5jZVR5cGUgfCBUZW5zb3JUeXBlQW5kU2hhcGUpID0+IE1hcFR5cGUgfCBTZXF1ZW5jZVR5cGUgfCBUZW5zb3JUeXBlQW5kU2hhcGUgfCBudWxsLFxuKTogTWFwVHlwZSB8IFNlcXVlbmNlVHlwZSB8IFRlbnNvclR5cGVBbmRTaGFwZSB8IG51bGwge1xuICBzd2l0Y2ggKFR5cGVJbmZvVmFsdWVbdHlwZV0pIHtcbiAgICBjYXNlICdOT05FJzpcbiAgICAgIHJldHVybiBudWxsO1xuICAgIGNhc2UgJ3RlbnNvcl90eXBlJzpcbiAgICAgIHJldHVybiBhY2Nlc3NvcihuZXcgVGVuc29yVHlwZUFuZFNoYXBlKCkpISBhcyBUZW5zb3JUeXBlQW5kU2hhcGU7XG4gICAgY2FzZSAnc2VxdWVuY2VfdHlwZSc6XG4gICAgICByZXR1cm4gYWNjZXNzb3IobmV3IFNlcXVlbmNlVHlwZSgpKSEgYXMgU2VxdWVuY2VUeXBlO1xuICAgIGNhc2UgJ21hcF90eXBlJzpcbiAgICAgIHJldHVybiBhY2Nlc3NvcihuZXcgTWFwVHlwZSgpKSEgYXMgTWFwVHlwZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVuaW9uTGlzdFRvVHlwZUluZm9WYWx1ZShcbiAgdHlwZTogVHlwZUluZm9WYWx1ZSxcbiAgYWNjZXNzb3I6IChcbiAgICBpbmRleDogbnVtYmVyLFxuICAgIG9iajogTWFwVHlwZSB8IFNlcXVlbmNlVHlwZSB8IFRlbnNvclR5cGVBbmRTaGFwZSxcbiAgKSA9PiBNYXBUeXBlIHwgU2VxdWVuY2VUeXBlIHwgVGVuc29yVHlwZUFuZFNoYXBlIHwgbnVsbCxcbiAgaW5kZXg6IG51bWJlcixcbik6IE1hcFR5cGUgfCBTZXF1ZW5jZVR5cGUgfCBUZW5zb3JUeXBlQW5kU2hhcGUgfCBudWxsIHtcbiAgc3dpdGNoIChUeXBlSW5mb1ZhbHVlW3R5cGVdKSB7XG4gICAgY2FzZSAnTk9ORSc6XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICBjYXNlICd0ZW5zb3JfdHlwZSc6XG4gICAgICByZXR1cm4gYWNjZXNzb3IoaW5kZXgsIG5ldyBUZW5zb3JUeXBlQW5kU2hhcGUoKSkhIGFzIFRlbnNvclR5cGVBbmRTaGFwZTtcbiAgICBjYXNlICdzZXF1ZW5jZV90eXBlJzpcbiAgICAgIHJldHVybiBhY2Nlc3NvcihpbmRleCwgbmV3IFNlcXVlbmNlVHlwZSgpKSEgYXMgU2VxdWVuY2VUeXBlO1xuICAgIGNhc2UgJ21hcF90eXBlJzpcbiAgICAgIHJldHVybiBhY2Nlc3NvcihpbmRleCwgbmV3IE1hcFR5cGUoKSkhIGFzIE1hcFR5cGU7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBudWxsO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IFR5cGVJbmZvVmFsdWUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvdHlwZS1pbmZvLXZhbHVlLmpzJztcblxuZXhwb3J0IGNsYXNzIFR5cGVJbmZvIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBUeXBlSW5mbyB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNUeXBlSW5mbyhiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogVHlwZUluZm8pOiBUeXBlSW5mbyB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFR5cGVJbmZvKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzVHlwZUluZm8oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFR5cGVJbmZvKTogVHlwZUluZm8ge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBUeXBlSW5mbygpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgZGVub3RhdGlvbigpOiBzdHJpbmcgfCBudWxsO1xuICBkZW5vdGF0aW9uKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGRlbm90YXRpb24ob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICB2YWx1ZVR5cGUoKTogVHlwZUluZm9WYWx1ZSB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDgodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogVHlwZUluZm9WYWx1ZS5OT05FO1xuICB9XG5cbiAgdmFsdWUob2JqOiBhbnkpOiBhbnkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdW5pb24ob2JqLCB0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBudWxsO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0VHlwZUluZm8oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMyk7XG4gIH1cblxuICBzdGF0aWMgYWRkRGVub3RhdGlvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkZW5vdGF0aW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGRlbm90YXRpb25PZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZFZhbHVlVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB2YWx1ZVR5cGU6IFR5cGVJbmZvVmFsdWUpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50OCgxLCB2YWx1ZVR5cGUsIFR5cGVJbmZvVmFsdWUuTk9ORSk7XG4gIH1cblxuICBzdGF0aWMgYWRkVmFsdWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgdmFsdWVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZFR5cGVJbmZvKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVUeXBlSW5mbyhcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIGRlbm90YXRpb25PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICB2YWx1ZVR5cGU6IFR5cGVJbmZvVmFsdWUsXG4gICAgdmFsdWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBUeXBlSW5mby5zdGFydFR5cGVJbmZvKGJ1aWxkZXIpO1xuICAgIFR5cGVJbmZvLmFkZERlbm90YXRpb24oYnVpbGRlciwgZGVub3RhdGlvbk9mZnNldCk7XG4gICAgVHlwZUluZm8uYWRkVmFsdWVUeXBlKGJ1aWxkZXIsIHZhbHVlVHlwZSk7XG4gICAgVHlwZUluZm8uYWRkVmFsdWUoYnVpbGRlciwgdmFsdWVPZmZzZXQpO1xuICAgIHJldHVybiBUeXBlSW5mby5lbmRUeXBlSW5mbyhidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBUeXBlSW5mbyB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy90eXBlLWluZm8uanMnO1xuXG5leHBvcnQgY2xhc3MgVmFsdWVJbmZvIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBWYWx1ZUluZm8ge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzVmFsdWVJbmZvKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBWYWx1ZUluZm8pOiBWYWx1ZUluZm8ge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBWYWx1ZUluZm8oKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNWYWx1ZUluZm8oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFZhbHVlSW5mbyk6IFZhbHVlSW5mbyB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFZhbHVlSW5mbygpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgbmFtZSgpOiBzdHJpbmcgfCBudWxsO1xuICBuYW1lKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIG5hbWUob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBkb2NTdHJpbmcoKTogc3RyaW5nIHwgbnVsbDtcbiAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHR5cGUob2JqPzogVHlwZUluZm8pOiBUeXBlSW5mbyB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgVHlwZUluZm8oKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOiBudWxsO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0VmFsdWVJbmZvKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDMpO1xuICB9XG5cbiAgc3RhdGljIGFkZE5hbWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBuYW1lT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREb2NTdHJpbmcoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGRvY1N0cmluZ09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB0eXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDIsIHR5cGVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZFZhbHVlSW5mbyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgTm9kZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9ub2RlLmpzJztcbmltcG9ydCB7IE5vZGVFZGdlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL25vZGUtZWRnZS5qcyc7XG5pbXBvcnQgeyBSdW50aW1lT3B0aW1pemF0aW9ucyB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9ydW50aW1lLW9wdGltaXphdGlvbnMuanMnO1xuaW1wb3J0IHsgU3BhcnNlVGVuc29yIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3NwYXJzZS10ZW5zb3IuanMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3RlbnNvci5qcyc7XG5pbXBvcnQgeyBWYWx1ZUluZm8gfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvdmFsdWUtaW5mby5qcyc7XG5cbmV4cG9ydCBjbGFzcyBHcmFwaCB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogR3JhcGgge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzR3JhcGgoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEdyYXBoKTogR3JhcGgge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBHcmFwaCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0dyYXBoKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBHcmFwaCk6IEdyYXBoIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgR3JhcGgoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGluaXRpYWxpemVycyhpbmRleDogbnVtYmVyLCBvYmo/OiBUZW5zb3IpOiBUZW5zb3IgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBUZW5zb3IoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSwgdGhpcy5iYiEpXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBpbml0aWFsaXplcnNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgbm9kZUFyZ3MoaW5kZXg6IG51bWJlciwgb2JqPzogVmFsdWVJbmZvKTogVmFsdWVJbmZvIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgVmFsdWVJbmZvKCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIG5vZGVBcmdzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG5vZGVzKGluZGV4OiBudW1iZXIsIG9iaj86IE5vZGUpOiBOb2RlIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgTm9kZSgpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISlcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIG5vZGVzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG1heE5vZGVJbmRleCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG5vZGVFZGdlcyhpbmRleDogbnVtYmVyLCBvYmo/OiBOb2RlRWRnZSk6IE5vZGVFZGdlIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IE5vZGVFZGdlKCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIG5vZGVFZGdlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgaW5wdXRzKGluZGV4OiBudW1iZXIpOiBzdHJpbmc7XG4gIGlucHV0cyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gIGlucHV0cyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgaW5wdXRzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBvdXRwdXRzKGluZGV4OiBudW1iZXIpOiBzdHJpbmc7XG4gIG91dHB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5O1xuICBvdXRwdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBvdXRwdXRzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzcGFyc2VJbml0aWFsaXplcnMoaW5kZXg6IG51bWJlciwgb2JqPzogU3BhcnNlVGVuc29yKTogU3BhcnNlVGVuc29yIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE4KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IFNwYXJzZVRlbnNvcigpKS5fX2luaXQoXG4gICAgICAgICAgdGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLFxuICAgICAgICAgIHRoaXMuYmIhLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBzcGFyc2VJbml0aWFsaXplcnNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTgpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHJ1bnRpbWVPcHRpbWl6YXRpb25zKG9iaj86IFJ1bnRpbWVPcHRpbWl6YXRpb25zKTogUnVudGltZU9wdGltaXphdGlvbnMgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjApO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgUnVudGltZU9wdGltaXphdGlvbnMoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISlcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEdyYXBoKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDkpO1xuICB9XG5cbiAgc3RhdGljIGFkZEluaXRpYWxpemVycyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbml0aWFsaXplcnNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgaW5pdGlhbGl6ZXJzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbml0aWFsaXplcnNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0SW5pdGlhbGl6ZXJzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGROb2RlQXJncyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBub2RlQXJnc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBub2RlQXJnc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlTm9kZUFyZ3NWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0Tm9kZUFyZ3NWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZE5vZGVzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDIsIG5vZGVzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVOb2Rlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnROb2Rlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkTWF4Tm9kZUluZGV4KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG1heE5vZGVJbmRleDogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDMsIG1heE5vZGVJbmRleCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkTm9kZUVkZ2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVFZGdlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg0LCBub2RlRWRnZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU5vZGVFZGdlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnROb2RlRWRnZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZElucHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbnB1dHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNSwgaW5wdXRzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbnB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0SW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRPdXRwdXRzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG91dHB1dHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNiwgb3V0cHV0c09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlT3V0cHV0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRPdXRwdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRTcGFyc2VJbml0aWFsaXplcnMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgc3BhcnNlSW5pdGlhbGl6ZXJzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDcsIHNwYXJzZUluaXRpYWxpemVyc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlU3BhcnNlSW5pdGlhbGl6ZXJzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFNwYXJzZUluaXRpYWxpemVyc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkUnVudGltZU9wdGltaXphdGlvbnMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgcnVudGltZU9wdGltaXphdGlvbnNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoOCwgcnVudGltZU9wdGltaXphdGlvbnNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZEdyYXBoKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBBdHRyaWJ1dGVUeXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2F0dHJpYnV0ZS10eXBlLmpzJztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2dyYXBoLmpzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy90ZW5zb3IuanMnO1xuXG5leHBvcnQgY2xhc3MgQXR0cmlidXRlIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBBdHRyaWJ1dGUge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzQXR0cmlidXRlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBBdHRyaWJ1dGUpOiBBdHRyaWJ1dGUge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBBdHRyaWJ1dGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNBdHRyaWJ1dGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEF0dHJpYnV0ZSk6IEF0dHJpYnV0ZSB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IEF0dHJpYnV0ZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgbmFtZSgpOiBzdHJpbmcgfCBudWxsO1xuICBuYW1lKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIG5hbWUob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBkb2NTdHJpbmcoKTogc3RyaW5nIHwgbnVsbDtcbiAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHR5cGUoKTogQXR0cmlidXRlVHlwZSB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogQXR0cmlidXRlVHlwZS5VTkRFRklORUQ7XG4gIH1cblxuICBmKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEZsb2F0MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMC4wO1xuICB9XG5cbiAgaSgpOiBiaWdpbnQge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBCaWdJbnQoJzAnKTtcbiAgfVxuXG4gIHMoKTogc3RyaW5nIHwgbnVsbDtcbiAgcyhvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBzKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHQob2JqPzogVGVuc29yKTogVGVuc29yIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgVGVuc29yKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDogbnVsbDtcbiAgfVxuXG4gIGcob2JqPzogR3JhcGgpOiBHcmFwaCB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IEdyYXBoKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDogbnVsbDtcbiAgfVxuXG4gIGZsb2F0cyhpbmRleDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDIwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEZsb2F0MzIodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSA6IDA7XG4gIH1cblxuICBmbG9hdHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGZsb2F0c0FycmF5KCk6IEZsb2F0MzJBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMCk7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyBuZXcgRmxvYXQzMkFycmF5KFxuICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnVmZmVyLFxuICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnl0ZU9mZnNldCArIHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgICB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBpbnRzKGluZGV4OiBudW1iZXIpOiBiaWdpbnQgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjIpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50NjQodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA4KSA6IEJpZ0ludCgwKTtcbiAgfVxuXG4gIGludHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjIpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0cmluZ3MoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgc3RyaW5ncyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gIHN0cmluZ3MoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHN0cmluZ3NMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHRlbnNvcnMoaW5kZXg6IG51bWJlciwgb2JqPzogVGVuc29yKTogVGVuc29yIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IFRlbnNvcigpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISlcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHRlbnNvcnNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGdyYXBocyhpbmRleDogbnVtYmVyLCBvYmo/OiBHcmFwaCk6IEdyYXBoIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI4KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IEdyYXBoKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgZ3JhcGhzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRBdHRyaWJ1dGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMTMpO1xuICB9XG5cbiAgc3RhdGljIGFkZE5hbWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBuYW1lT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREb2NTdHJpbmcoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGRvY1N0cmluZ09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB0eXBlOiBBdHRyaWJ1dGVUeXBlKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDIsIHR5cGUsIEF0dHJpYnV0ZVR5cGUuVU5ERUZJTkVEKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRGKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGY6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRGbG9hdDMyKDMsIGYsIDAuMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpOiBiaWdpbnQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50NjQoNCwgaSwgQmlnSW50KCcwJykpO1xuICB9XG5cbiAgc3RhdGljIGFkZFMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg1LCBzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRUKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHRPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNiwgdE9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkRyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBnT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDcsIGdPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZEZsb2F0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBmbG9hdHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoOCwgZmxvYXRzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVGbG9hdHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogbnVtYmVyW10gfCBGbG9hdDMyQXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQ7XG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBUaGlzIFVpbnQ4QXJyYXkgb3ZlcmxvYWQgd2lsbCBiZSByZW1vdmVkIGluIHRoZSBmdXR1cmUuXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlRmxvYXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IG51bWJlcltdIHwgVWludDhBcnJheSk6IGZsYXRidWZmZXJzLk9mZnNldDtcbiAgc3RhdGljIGNyZWF0ZUZsb2F0c1ZlY3RvcihcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIGRhdGE6IG51bWJlcltdIHwgRmxvYXQzMkFycmF5IHwgVWludDhBcnJheSxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRGbG9hdDMyKGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRGbG9hdHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZEludHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaW50c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg5LCBpbnRzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbnRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGJpZ2ludFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDgsIGRhdGEubGVuZ3RoLCA4KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRJbnQ2NChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0SW50c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig4LCBudW1FbGVtcywgOCk7XG4gIH1cblxuICBzdGF0aWMgYWRkU3RyaW5ncyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBzdHJpbmdzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEwLCBzdHJpbmdzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVTdHJpbmdzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFN0cmluZ3NWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZFRlbnNvcnMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdGVuc29yc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxMSwgdGVuc29yc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlVGVuc29yc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRUZW5zb3JzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRHcmFwaHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZ3JhcGhzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEyLCBncmFwaHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUdyYXBoc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRHcmFwaHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGVuZEF0dHJpYnV0ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuLyoqXG4gKiBkZXByZWNhdGVkOiBubyBsb25nZXIgdXNpbmcga2VybmVsIGRlZiBoYXNoZXNcbiAqL1xuZXhwb3J0IGNsYXNzIERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc0RlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyhcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MsXG4gICk6IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcygpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0RlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyhcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MsXG4gICk6IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcygpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgbm9kZUluZGljZXMoaW5kZXg6IG51bWJlcik6IG51bWJlciB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZFVpbnQzMih0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpIDogMDtcbiAgfVxuXG4gIG5vZGVJbmRpY2VzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG5vZGVJbmRpY2VzQXJyYXkoKTogVWludDMyQXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyBuZXcgVWludDMyQXJyYXkoXG4gICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5idWZmZXIsXG4gICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5ieXRlT2Zmc2V0ICsgdGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpLFxuICAgICAgICAgIHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCksXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIGtlcm5lbERlZkhhc2hlcyhpbmRleDogbnVtYmVyKTogYmlnaW50IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDY0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogOCkgOiBCaWdJbnQoMCk7XG4gIH1cblxuICBrZXJuZWxEZWZIYXNoZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0RGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDIpO1xuICB9XG5cbiAgc3RhdGljIGFkZE5vZGVJbmRpY2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVJbmRpY2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG5vZGVJbmRpY2VzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVOb2RlSW5kaWNlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBudW1iZXJbXSB8IFVpbnQzMkFycmF5KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0O1xuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgVGhpcyBVaW50OEFycmF5IG92ZXJsb2FkIHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgZnV0dXJlLlxuICAgKi9cbiAgc3RhdGljIGNyZWF0ZU5vZGVJbmRpY2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IG51bWJlcltdIHwgVWludDhBcnJheSk6IGZsYXRidWZmZXJzLk9mZnNldDtcbiAgc3RhdGljIGNyZWF0ZU5vZGVJbmRpY2VzVmVjdG9yKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgZGF0YTogbnVtYmVyW10gfCBVaW50MzJBcnJheSB8IFVpbnQ4QXJyYXksXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkSW50MzIoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE5vZGVJbmRpY2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRLZXJuZWxEZWZIYXNoZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwga2VybmVsRGVmSGFzaGVzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGtlcm5lbERlZkhhc2hlc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlS2VybmVsRGVmSGFzaGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGJpZ2ludFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDgsIGRhdGEubGVuZ3RoLCA4KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRJbnQ2NChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0S2VybmVsRGVmSGFzaGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDgsIG51bUVsZW1zLCA4KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmREZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZURlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyhcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIG5vZGVJbmRpY2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAga2VybmVsRGVmSGFzaGVzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zLnN0YXJ0RGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zKGJ1aWxkZXIpO1xuICAgIERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcy5hZGROb2RlSW5kaWNlcyhidWlsZGVyLCBub2RlSW5kaWNlc09mZnNldCk7XG4gICAgRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zLmFkZEtlcm5lbERlZkhhc2hlcyhidWlsZGVyLCBrZXJuZWxEZWZIYXNoZXNPZmZzZXQpO1xuICAgIHJldHVybiBEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MuZW5kRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbi8qKlxuICogZGVwcmVjYXRlZDogbm8gbG9uZ2VyIHVzaW5nIGtlcm5lbCBkZWYgaGFzaGVzXG4gKi9cbmV4cG9ydCBjbGFzcyBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2gge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2goXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2gsXG4gICk6IERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2goKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaChcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCxcbiAgKTogRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2gge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgbm9kZUluZGV4KCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBrZXJuZWxEZWZIYXNoKCk6IGJpZ2ludCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDY0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IEJpZ0ludCgnMCcpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0RGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2goYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gIH1cblxuICBzdGF0aWMgYWRkTm9kZUluZGV4KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVJbmRleDogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDAsIG5vZGVJbmRleCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkS2VybmVsRGVmSGFzaChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBrZXJuZWxEZWZIYXNoOiBiaWdpbnQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50NjQoMSwga2VybmVsRGVmSGFzaCwgQmlnSW50KCcwJykpO1xuICB9XG5cbiAgc3RhdGljIGVuZERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaChcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIG5vZGVJbmRleDogbnVtYmVyLFxuICAgIGtlcm5lbERlZkhhc2g6IGJpZ2ludCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaC5zdGFydERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoKGJ1aWxkZXIpO1xuICAgIERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoLmFkZE5vZGVJbmRleChidWlsZGVyLCBub2RlSW5kZXgpO1xuICAgIERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoLmFkZEtlcm5lbERlZkhhc2goYnVpbGRlciwga2VybmVsRGVmSGFzaCk7XG4gICAgcmV0dXJuIERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoLmVuZERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvZGVwcmVjYXRlZC1zZXNzaW9uLXN0YXRlLmpzJztcblxuLyoqXG4gKiBkZXByZWNhdGVkOiBubyBsb25nZXIgdXNpbmcga2VybmVsIGRlZiBoYXNoZXNcbiAqL1xuZXhwb3J0IGNsYXNzIERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc0RlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZShcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBEZXByZWNhdGVkU3ViR3JhcGhTZXNzaW9uU3RhdGUsXG4gICk6IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0RlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZShcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBEZXByZWNhdGVkU3ViR3JhcGhTZXNzaW9uU3RhdGUsXG4gICk6IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgZ3JhcGhJZCgpOiBzdHJpbmcgfCBudWxsO1xuICBncmFwaElkKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGdyYXBoSWQob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBzZXNzaW9uU3RhdGUob2JqPzogRGVwcmVjYXRlZFNlc3Npb25TdGF0ZSk6IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBEZXByZWNhdGVkU2Vzc2lvblN0YXRlKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnREZXByZWNhdGVkU3ViR3JhcGhTZXNzaW9uU3RhdGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gIH1cblxuICBzdGF0aWMgYWRkR3JhcGhJZChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBncmFwaElkT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGdyYXBoSWRPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZFNlc3Npb25TdGF0ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBzZXNzaW9uU3RhdGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgc2Vzc2lvblN0YXRlT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBlbmREZXByZWNhdGVkU3ViR3JhcGhTZXNzaW9uU3RhdGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICBidWlsZGVyLnJlcXVpcmVkRmllbGQob2Zmc2V0LCA0KTsgLy8gZ3JhcGhfaWRcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9kZXByZWNhdGVkLWtlcm5lbC1jcmVhdGUtaW5mb3MuanMnO1xuaW1wb3J0IHsgRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQtc3ViLWdyYXBoLXNlc3Npb24tc3RhdGUuanMnO1xuXG4vKipcbiAqIGRlcHJlY2F0ZWQ6IG5vIGxvbmdlciB1c2luZyBrZXJuZWwgZGVmIGhhc2hlc1xuICovXG5leHBvcnQgY2xhc3MgRGVwcmVjYXRlZFNlc3Npb25TdGF0ZSB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogRGVwcmVjYXRlZFNlc3Npb25TdGF0ZSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNEZXByZWNhdGVkU2Vzc2lvblN0YXRlKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUsXG4gICk6IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBEZXByZWNhdGVkU2Vzc2lvblN0YXRlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzRGVwcmVjYXRlZFNlc3Npb25TdGF0ZShcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBEZXByZWNhdGVkU2Vzc2lvblN0YXRlLFxuICApOiBEZXByZWNhdGVkU2Vzc2lvblN0YXRlIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGVwcmVjYXRlZFNlc3Npb25TdGF0ZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAga2VybmVscyhvYmo/OiBEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MpOiBEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISlcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHN1YkdyYXBoU2Vzc2lvblN0YXRlcyhpbmRleDogbnVtYmVyLCBvYmo/OiBEZXByZWNhdGVkU3ViR3JhcGhTZXNzaW9uU3RhdGUpOiBEZXByZWNhdGVkU3ViR3JhcGhTZXNzaW9uU3RhdGUgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBEZXByZWNhdGVkU3ViR3JhcGhTZXNzaW9uU3RhdGUoKSkuX19pbml0KFxuICAgICAgICAgIHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSxcbiAgICAgICAgICB0aGlzLmJiISxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgc3ViR3JhcGhTZXNzaW9uU3RhdGVzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gIH1cblxuICBzdGF0aWMgYWRkS2VybmVscyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBrZXJuZWxzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGtlcm5lbHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZFN1YkdyYXBoU2Vzc2lvblN0YXRlcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBzdWJHcmFwaFNlc3Npb25TdGF0ZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgc3ViR3JhcGhTZXNzaW9uU3RhdGVzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVTdWJHcmFwaFNlc3Npb25TdGF0ZXNWZWN0b3IoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFN1YkdyYXBoU2Vzc2lvblN0YXRlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kRGVwcmVjYXRlZFNlc3Npb25TdGF0ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlRGVwcmVjYXRlZFNlc3Npb25TdGF0ZShcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIGtlcm5lbHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBzdWJHcmFwaFNlc3Npb25TdGF0ZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBEZXByZWNhdGVkU2Vzc2lvblN0YXRlLnN0YXJ0RGVwcmVjYXRlZFNlc3Npb25TdGF0ZShidWlsZGVyKTtcbiAgICBEZXByZWNhdGVkU2Vzc2lvblN0YXRlLmFkZEtlcm5lbHMoYnVpbGRlciwga2VybmVsc09mZnNldCk7XG4gICAgRGVwcmVjYXRlZFNlc3Npb25TdGF0ZS5hZGRTdWJHcmFwaFNlc3Npb25TdGF0ZXMoYnVpbGRlciwgc3ViR3JhcGhTZXNzaW9uU3RhdGVzT2Zmc2V0KTtcbiAgICByZXR1cm4gRGVwcmVjYXRlZFNlc3Npb25TdGF0ZS5lbmREZXByZWNhdGVkU2Vzc2lvblN0YXRlKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IEFyZ1R5cGVBbmRJbmRleCB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9hcmctdHlwZS1hbmQtaW5kZXguanMnO1xuXG5leHBvcnQgY2xhc3MgS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IEtlcm5lbFR5cGVTdHJBcmdzRW50cnksXG4gICk6IEtlcm5lbFR5cGVTdHJBcmdzRW50cnkge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5LFxuICApOiBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAga2VybmVsVHlwZVN0cigpOiBzdHJpbmcgfCBudWxsO1xuICBrZXJuZWxUeXBlU3RyKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGtlcm5lbFR5cGVTdHIob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBhcmdzKGluZGV4OiBudW1iZXIsIG9iaj86IEFyZ1R5cGVBbmRJbmRleCk6IEFyZ1R5cGVBbmRJbmRleCB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IEFyZ1R5cGVBbmRJbmRleCgpKS5fX2luaXQoXG4gICAgICAgICAgdGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLFxuICAgICAgICAgIHRoaXMuYmIhLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBhcmdzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEtlcm5lbFR5cGVTdHJBcmdzRW50cnkoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gIH1cblxuICBzdGF0aWMgYWRkS2VybmVsVHlwZVN0cihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBrZXJuZWxUeXBlU3RyT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGtlcm5lbFR5cGVTdHJPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZEFyZ3MoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgYXJnc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBhcmdzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVBcmdzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEFyZ3NWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGVuZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICBidWlsZGVyLnJlcXVpcmVkRmllbGQob2Zmc2V0LCA0KTsgLy8ga2VybmVsX3R5cGVfc3RyXG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAga2VybmVsVHlwZVN0ck9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGFyZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5LnN0YXJ0S2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyKTtcbiAgICBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5LmFkZEtlcm5lbFR5cGVTdHIoYnVpbGRlciwga2VybmVsVHlwZVN0ck9mZnNldCk7XG4gICAgS2VybmVsVHlwZVN0ckFyZ3NFbnRyeS5hZGRBcmdzKGJ1aWxkZXIsIGFyZ3NPZmZzZXQpO1xuICAgIHJldHVybiBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5LmVuZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9rZXJuZWwtdHlwZS1zdHItYXJncy1lbnRyeS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnksXG4gICk6IE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSxcbiAgKTogT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgb3BJZCgpOiBzdHJpbmcgfCBudWxsO1xuICBvcElkKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIG9wSWQob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBrZXJuZWxUeXBlU3RyQXJncyhpbmRleDogbnVtYmVyLCBvYmo/OiBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KTogS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IEtlcm5lbFR5cGVTdHJBcmdzRW50cnkoKSkuX19pbml0KFxuICAgICAgICAgIHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSxcbiAgICAgICAgICB0aGlzLmJiISxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAga2VybmVsVHlwZVN0ckFyZ3NMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0T3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gIH1cblxuICBzdGF0aWMgYWRkT3BJZChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBvcElkT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG9wSWRPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZEtlcm5lbFR5cGVTdHJBcmdzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtlcm5lbFR5cGVTdHJBcmdzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGtlcm5lbFR5cGVTdHJBcmdzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVLZXJuZWxUeXBlU3RyQXJnc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRLZXJuZWxUeXBlU3RyQXJnc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICBidWlsZGVyLnJlcXVpcmVkRmllbGQob2Zmc2V0LCA0KTsgLy8gb3BfaWRcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgb3BJZE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGtlcm5lbFR5cGVTdHJBcmdzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkuc3RhcnRPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyKTtcbiAgICBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeS5hZGRPcElkKGJ1aWxkZXIsIG9wSWRPZmZzZXQpO1xuICAgIE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5LmFkZEtlcm5lbFR5cGVTdHJBcmdzKGJ1aWxkZXIsIGtlcm5lbFR5cGVTdHJBcmdzT2Zmc2V0KTtcbiAgICByZXR1cm4gT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkuZW5kT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvb3AtaWQta2VybmVsLXR5cGUtc3RyLWFyZ3MtZW50cnkuanMnO1xuXG5leHBvcnQgY2xhc3MgS2VybmVsVHlwZVN0clJlc29sdmVyIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzS2VybmVsVHlwZVN0clJlc29sdmVyKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IEtlcm5lbFR5cGVTdHJSZXNvbHZlcixcbiAgKTogS2VybmVsVHlwZVN0clJlc29sdmVyIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgS2VybmVsVHlwZVN0clJlc29sdmVyKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzS2VybmVsVHlwZVN0clJlc29sdmVyKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IEtlcm5lbFR5cGVTdHJSZXNvbHZlcixcbiAgKTogS2VybmVsVHlwZVN0clJlc29sdmVyIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgS2VybmVsVHlwZVN0clJlc29sdmVyKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBvcEtlcm5lbFR5cGVTdHJBcmdzKGluZGV4OiBudW1iZXIsIG9iaj86IE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KTogT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSgpKS5fX2luaXQoXG4gICAgICAgICAgdGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLFxuICAgICAgICAgIHRoaXMuYmIhLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBvcEtlcm5lbFR5cGVTdHJBcmdzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEtlcm5lbFR5cGVTdHJSZXNvbHZlcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgxKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRPcEtlcm5lbFR5cGVTdHJBcmdzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG9wS2VybmVsVHlwZVN0ckFyZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgb3BLZXJuZWxUeXBlU3RyQXJnc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlT3BLZXJuZWxUeXBlU3RyQXJnc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRPcEtlcm5lbFR5cGVTdHJBcmdzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRLZXJuZWxUeXBlU3RyUmVzb2x2ZXIoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUtlcm5lbFR5cGVTdHJSZXNvbHZlcihcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIG9wS2VybmVsVHlwZVN0ckFyZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIuc3RhcnRLZXJuZWxUeXBlU3RyUmVzb2x2ZXIoYnVpbGRlcik7XG4gICAgS2VybmVsVHlwZVN0clJlc29sdmVyLmFkZE9wS2VybmVsVHlwZVN0ckFyZ3MoYnVpbGRlciwgb3BLZXJuZWxUeXBlU3RyQXJnc09mZnNldCk7XG4gICAgcmV0dXJuIEtlcm5lbFR5cGVTdHJSZXNvbHZlci5lbmRLZXJuZWxUeXBlU3RyUmVzb2x2ZXIoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuZXhwb3J0IGNsYXNzIE9wZXJhdG9yU2V0SWQge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IE9wZXJhdG9yU2V0SWQge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzT3BlcmF0b3JTZXRJZChiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogT3BlcmF0b3JTZXRJZCk6IE9wZXJhdG9yU2V0SWQge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBPcGVyYXRvclNldElkKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzT3BlcmF0b3JTZXRJZChiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogT3BlcmF0b3JTZXRJZCk6IE9wZXJhdG9yU2V0SWQge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBPcGVyYXRvclNldElkKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBkb21haW4oKTogc3RyaW5nIHwgbnVsbDtcbiAgZG9tYWluKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGRvbWFpbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHZlcnNpb24oKTogYmlnaW50IHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBCaWdJbnQoJzAnKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE9wZXJhdG9yU2V0SWQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gIH1cblxuICBzdGF0aWMgYWRkRG9tYWluKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRvbWFpbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBkb21haW5PZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZFZlcnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmVyc2lvbjogYmlnaW50KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDY0KDEsIHZlcnNpb24sIEJpZ0ludCgnMCcpKTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRPcGVyYXRvclNldElkKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVPcGVyYXRvclNldElkKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgZG9tYWluT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgdmVyc2lvbjogYmlnaW50LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIE9wZXJhdG9yU2V0SWQuc3RhcnRPcGVyYXRvclNldElkKGJ1aWxkZXIpO1xuICAgIE9wZXJhdG9yU2V0SWQuYWRkRG9tYWluKGJ1aWxkZXIsIGRvbWFpbk9mZnNldCk7XG4gICAgT3BlcmF0b3JTZXRJZC5hZGRWZXJzaW9uKGJ1aWxkZXIsIHZlcnNpb24pO1xuICAgIHJldHVybiBPcGVyYXRvclNldElkLmVuZE9wZXJhdG9yU2V0SWQoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuZXhwb3J0IGNsYXNzIFN0cmluZ1N0cmluZ0VudHJ5IHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBTdHJpbmdTdHJpbmdFbnRyeSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNTdHJpbmdTdHJpbmdFbnRyeShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogU3RyaW5nU3RyaW5nRW50cnkpOiBTdHJpbmdTdHJpbmdFbnRyeSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFN0cmluZ1N0cmluZ0VudHJ5KCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzU3RyaW5nU3RyaW5nRW50cnkoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogU3RyaW5nU3RyaW5nRW50cnksXG4gICk6IFN0cmluZ1N0cmluZ0VudHJ5IHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgU3RyaW5nU3RyaW5nRW50cnkoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGtleSgpOiBzdHJpbmcgfCBudWxsO1xuICBrZXkob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAga2V5KG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgdmFsdWUoKTogc3RyaW5nIHwgbnVsbDtcbiAgdmFsdWUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgdmFsdWUob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRTdHJpbmdTdHJpbmdFbnRyeShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRLZXkoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwga2V5T2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGtleU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkVmFsdWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgdmFsdWVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZFN0cmluZ1N0cmluZ0VudHJ5KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVTdHJpbmdTdHJpbmdFbnRyeShcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIGtleU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIHZhbHVlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgU3RyaW5nU3RyaW5nRW50cnkuc3RhcnRTdHJpbmdTdHJpbmdFbnRyeShidWlsZGVyKTtcbiAgICBTdHJpbmdTdHJpbmdFbnRyeS5hZGRLZXkoYnVpbGRlciwga2V5T2Zmc2V0KTtcbiAgICBTdHJpbmdTdHJpbmdFbnRyeS5hZGRWYWx1ZShidWlsZGVyLCB2YWx1ZU9mZnNldCk7XG4gICAgcmV0dXJuIFN0cmluZ1N0cmluZ0VudHJ5LmVuZFN0cmluZ1N0cmluZ0VudHJ5KGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2dyYXBoLmpzJztcbmltcG9ydCB7IE9wZXJhdG9yU2V0SWQgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvb3BlcmF0b3Itc2V0LWlkLmpzJztcbmltcG9ydCB7IFN0cmluZ1N0cmluZ0VudHJ5IH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3N0cmluZy1zdHJpbmctZW50cnkuanMnO1xuXG5leHBvcnQgY2xhc3MgTW9kZWwge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IE1vZGVsIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc01vZGVsKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBNb2RlbCk6IE1vZGVsIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgTW9kZWwoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNNb2RlbChiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTW9kZWwpOiBNb2RlbCB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE1vZGVsKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBpclZlcnNpb24oKTogYmlnaW50IHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBCaWdJbnQoJzAnKTtcbiAgfVxuXG4gIG9wc2V0SW1wb3J0KGluZGV4OiBudW1iZXIsIG9iaj86IE9wZXJhdG9yU2V0SWQpOiBPcGVyYXRvclNldElkIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgT3BlcmF0b3JTZXRJZCgpKS5fX2luaXQoXG4gICAgICAgICAgdGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLFxuICAgICAgICAgIHRoaXMuYmIhLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBvcHNldEltcG9ydExlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBwcm9kdWNlck5hbWUoKTogc3RyaW5nIHwgbnVsbDtcbiAgcHJvZHVjZXJOYW1lKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIHByb2R1Y2VyTmFtZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHByb2R1Y2VyVmVyc2lvbigpOiBzdHJpbmcgfCBudWxsO1xuICBwcm9kdWNlclZlcnNpb24ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgcHJvZHVjZXJWZXJzaW9uKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGRvbWFpbigpOiBzdHJpbmcgfCBudWxsO1xuICBkb21haW4ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZG9tYWluKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIG1vZGVsVmVyc2lvbigpOiBiaWdpbnQge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBCaWdJbnQoJzAnKTtcbiAgfVxuXG4gIGRvY1N0cmluZygpOiBzdHJpbmcgfCBudWxsO1xuICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGdyYXBoKG9iaj86IEdyYXBoKTogR3JhcGggfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTgpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBHcmFwaCgpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6IG51bGw7XG4gIH1cblxuICBncmFwaERvY1N0cmluZygpOiBzdHJpbmcgfCBudWxsO1xuICBncmFwaERvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBncmFwaERvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBtZXRhZGF0YVByb3BzKGluZGV4OiBudW1iZXIsIG9iaj86IFN0cmluZ1N0cmluZ0VudHJ5KTogU3RyaW5nU3RyaW5nRW50cnkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjIpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgU3RyaW5nU3RyaW5nRW50cnkoKSkuX19pbml0KFxuICAgICAgICAgIHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSxcbiAgICAgICAgICB0aGlzLmJiISxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgbWV0YWRhdGFQcm9wc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0TW9kZWwoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMTApO1xuICB9XG5cbiAgc3RhdGljIGFkZElyVmVyc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpclZlcnNpb246IGJpZ2ludCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ2NCgwLCBpclZlcnNpb24sIEJpZ0ludCgnMCcpKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRPcHNldEltcG9ydChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBvcHNldEltcG9ydE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBvcHNldEltcG9ydE9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlT3BzZXRJbXBvcnRWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0T3BzZXRJbXBvcnRWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZFByb2R1Y2VyTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBwcm9kdWNlck5hbWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgcHJvZHVjZXJOYW1lT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRQcm9kdWNlclZlcnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgcHJvZHVjZXJWZXJzaW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDMsIHByb2R1Y2VyVmVyc2lvbk9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkRG9tYWluKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRvbWFpbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg0LCBkb21haW5PZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZE1vZGVsVmVyc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBtb2RlbFZlcnNpb246IGJpZ2ludCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ2NCg1LCBtb2RlbFZlcnNpb24sIEJpZ0ludCgnMCcpKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREb2NTdHJpbmcoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDYsIGRvY1N0cmluZ09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkR3JhcGgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZ3JhcGhPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNywgZ3JhcGhPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZEdyYXBoRG9jU3RyaW5nKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGdyYXBoRG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDgsIGdyYXBoRG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRNZXRhZGF0YVByb3BzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG1ldGFkYXRhUHJvcHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoOSwgbWV0YWRhdGFQcm9wc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlTWV0YWRhdGFQcm9wc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRNZXRhZGF0YVByb3BzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRNb2RlbChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgS2VybmVsVHlwZVN0clJlc29sdmVyIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2tlcm5lbC10eXBlLXN0ci1yZXNvbHZlci5qcyc7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9tb2RlbC5qcyc7XG5cbmV4cG9ydCBjbGFzcyBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc0luZmVyZW5jZVNlc3Npb24oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEluZmVyZW5jZVNlc3Npb24pOiBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgSW5mZXJlbmNlU2Vzc2lvbigpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0luZmVyZW5jZVNlc3Npb24oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEluZmVyZW5jZVNlc3Npb24pOiBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgSW5mZXJlbmNlU2Vzc2lvbigpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGJ1ZmZlckhhc0lkZW50aWZpZXIoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gYmIuX19oYXNfaWRlbnRpZmllcignT1JUTScpO1xuICB9XG5cbiAgb3J0VmVyc2lvbigpOiBzdHJpbmcgfCBudWxsO1xuICBvcnRWZXJzaW9uKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIG9ydFZlcnNpb24ob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBtb2RlbChvYmo/OiBNb2RlbCk6IE1vZGVsIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBNb2RlbCgpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6IG51bGw7XG4gIH1cblxuICBrZXJuZWxUeXBlU3RyUmVzb2x2ZXIob2JqPzogS2VybmVsVHlwZVN0clJlc29sdmVyKTogS2VybmVsVHlwZVN0clJlc29sdmVyIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IEtlcm5lbFR5cGVTdHJSZXNvbHZlcigpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0SW5mZXJlbmNlU2Vzc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCg0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRPcnRWZXJzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG9ydFZlcnNpb25PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgb3J0VmVyc2lvbk9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkTW9kZWwoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbW9kZWxPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgbW9kZWxPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZEtlcm5lbFR5cGVTdHJSZXNvbHZlcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBrZXJuZWxUeXBlU3RyUmVzb2x2ZXJPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMywga2VybmVsVHlwZVN0clJlc29sdmVyT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRJbmZlcmVuY2VTZXNzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBmaW5pc2hJbmZlcmVuY2VTZXNzaW9uQnVmZmVyKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5maW5pc2gob2Zmc2V0LCAnT1JUTScpO1xuICB9XG5cbiAgc3RhdGljIGZpbmlzaFNpemVQcmVmaXhlZEluZmVyZW5jZVNlc3Npb25CdWZmZXIoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmZpbmlzaChvZmZzZXQsICdPUlRNJywgdHJ1ZSk7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmV4cG9ydCB7IEFyZ1R5cGUgfSBmcm9tICcuL2Zicy9hcmctdHlwZS5qcyc7XG5leHBvcnQgeyBBcmdUeXBlQW5kSW5kZXggfSBmcm9tICcuL2Zicy9hcmctdHlwZS1hbmQtaW5kZXguanMnO1xuZXhwb3J0IHsgQXR0cmlidXRlIH0gZnJvbSAnLi9mYnMvYXR0cmlidXRlLmpzJztcbmV4cG9ydCB7IEF0dHJpYnV0ZVR5cGUgfSBmcm9tICcuL2Zicy9hdHRyaWJ1dGUtdHlwZS5qcyc7XG5leHBvcnQgeyBEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MgfSBmcm9tICcuL2Zicy9kZXByZWNhdGVkLWtlcm5lbC1jcmVhdGUtaW5mb3MuanMnO1xuZXhwb3J0IHsgRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2ggfSBmcm9tICcuL2Zicy9kZXByZWNhdGVkLW5vZGUtaW5kZXgtYW5kLWtlcm5lbC1kZWYtaGFzaC5qcyc7XG5leHBvcnQgeyBEZXByZWNhdGVkU2Vzc2lvblN0YXRlIH0gZnJvbSAnLi9mYnMvZGVwcmVjYXRlZC1zZXNzaW9uLXN0YXRlLmpzJztcbmV4cG9ydCB7IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSB9IGZyb20gJy4vZmJzL2RlcHJlY2F0ZWQtc3ViLWdyYXBoLXNlc3Npb24tc3RhdGUuanMnO1xuZXhwb3J0IHsgRGltZW5zaW9uIH0gZnJvbSAnLi9mYnMvZGltZW5zaW9uLmpzJztcbmV4cG9ydCB7IERpbWVuc2lvblZhbHVlIH0gZnJvbSAnLi9mYnMvZGltZW5zaW9uLXZhbHVlLmpzJztcbmV4cG9ydCB7IERpbWVuc2lvblZhbHVlVHlwZSB9IGZyb20gJy4vZmJzL2RpbWVuc2lvbi12YWx1ZS10eXBlLmpzJztcbmV4cG9ydCB7IEVkZ2VFbmQgfSBmcm9tICcuL2Zicy9lZGdlLWVuZC5qcyc7XG5leHBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZmJzL2dyYXBoLmpzJztcbmV4cG9ydCB7IEluZmVyZW5jZVNlc3Npb24gfSBmcm9tICcuL2Zicy9pbmZlcmVuY2Utc2Vzc2lvbi5qcyc7XG5leHBvcnQgeyBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IH0gZnJvbSAnLi9mYnMva2VybmVsLXR5cGUtc3RyLWFyZ3MtZW50cnkuanMnO1xuZXhwb3J0IHsgS2VybmVsVHlwZVN0clJlc29sdmVyIH0gZnJvbSAnLi9mYnMva2VybmVsLXR5cGUtc3RyLXJlc29sdmVyLmpzJztcbmV4cG9ydCB7IE1hcFR5cGUgfSBmcm9tICcuL2Zicy9tYXAtdHlwZS5qcyc7XG5leHBvcnQgeyBNb2RlbCB9IGZyb20gJy4vZmJzL21vZGVsLmpzJztcbmV4cG9ydCB7IE5vZGUgfSBmcm9tICcuL2Zicy9ub2RlLmpzJztcbmV4cG9ydCB7IE5vZGVFZGdlIH0gZnJvbSAnLi9mYnMvbm9kZS1lZGdlLmpzJztcbmV4cG9ydCB7IE5vZGVUeXBlIH0gZnJvbSAnLi9mYnMvbm9kZS10eXBlLmpzJztcbmV4cG9ydCB7IE5vZGVzVG9PcHRpbWl6ZUluZGljZXMgfSBmcm9tICcuL2Zicy9ub2Rlcy10by1vcHRpbWl6ZS1pbmRpY2VzLmpzJztcbmV4cG9ydCB7IE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IH0gZnJvbSAnLi9mYnMvb3AtaWQta2VybmVsLXR5cGUtc3RyLWFyZ3MtZW50cnkuanMnO1xuZXhwb3J0IHsgT3BlcmF0b3JTZXRJZCB9IGZyb20gJy4vZmJzL29wZXJhdG9yLXNldC1pZC5qcyc7XG5leHBvcnQgeyBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkIH0gZnJvbSAnLi9mYnMvcnVudGltZS1vcHRpbWl6YXRpb24tcmVjb3JkLmpzJztcbmV4cG9ydCB7IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSB9IGZyb20gJy4vZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9uLXJlY29yZC1jb250YWluZXItZW50cnkuanMnO1xuZXhwb3J0IHsgUnVudGltZU9wdGltaXphdGlvbnMgfSBmcm9tICcuL2Zicy9ydW50aW1lLW9wdGltaXphdGlvbnMuanMnO1xuZXhwb3J0IHsgU2VxdWVuY2VUeXBlIH0gZnJvbSAnLi9mYnMvc2VxdWVuY2UtdHlwZS5qcyc7XG5leHBvcnQgeyBTaGFwZSB9IGZyb20gJy4vZmJzL3NoYXBlLmpzJztcbmV4cG9ydCB7IFNwYXJzZVRlbnNvciB9IGZyb20gJy4vZmJzL3NwYXJzZS10ZW5zb3IuanMnO1xuZXhwb3J0IHsgU3RyaW5nU3RyaW5nRW50cnkgfSBmcm9tICcuL2Zicy9zdHJpbmctc3RyaW5nLWVudHJ5LmpzJztcbmV4cG9ydCB7IFRlbnNvciB9IGZyb20gJy4vZmJzL3RlbnNvci5qcyc7XG5leHBvcnQgeyBUZW5zb3JEYXRhVHlwZSB9IGZyb20gJy4vZmJzL3RlbnNvci1kYXRhLXR5cGUuanMnO1xuZXhwb3J0IHsgVGVuc29yVHlwZUFuZFNoYXBlIH0gZnJvbSAnLi9mYnMvdGVuc29yLXR5cGUtYW5kLXNoYXBlLmpzJztcbmV4cG9ydCB7IFR5cGVJbmZvIH0gZnJvbSAnLi9mYnMvdHlwZS1pbmZvLmpzJztcbmV4cG9ydCB7IFR5cGVJbmZvVmFsdWUgfSBmcm9tICcuL2Zicy90eXBlLWluZm8tdmFsdWUuanMnO1xuZXhwb3J0IHsgVmFsdWVJbmZvIH0gZnJvbSAnLi9mYnMvdmFsdWUtaW5mby5qcyc7XG4iLCAiZXhwb3J0ICogZnJvbSAnLi9vbm54cnVudGltZS9mYnMnO1xuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGFzUHJvbWlzZTtcclxuXHJcbi8qKlxyXG4gKiBDYWxsYmFjayBhcyB1c2VkIGJ5IHtAbGluayB1dGlsLmFzUHJvbWlzZX0uXHJcbiAqIEB0eXBlZGVmIGFzUHJvbWlzZUNhbGxiYWNrXHJcbiAqIEB0eXBlIHtmdW5jdGlvbn1cclxuICogQHBhcmFtIHtFcnJvcnxudWxsfSBlcnJvciBFcnJvciwgaWYgYW55XHJcbiAqIEBwYXJhbSB7Li4uKn0gcGFyYW1zIEFkZGl0aW9uYWwgYXJndW1lbnRzXHJcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBwcm9taXNlIGZyb20gYSBub2RlLXN0eWxlIGNhbGxiYWNrIGZ1bmN0aW9uLlxyXG4gKiBAbWVtYmVyb2YgdXRpbFxyXG4gKiBAcGFyYW0ge2FzUHJvbWlzZUNhbGxiYWNrfSBmbiBGdW5jdGlvbiB0byBjYWxsXHJcbiAqIEBwYXJhbSB7Kn0gY3R4IEZ1bmN0aW9uIGNvbnRleHRcclxuICogQHBhcmFtIHsuLi4qfSBwYXJhbXMgRnVuY3Rpb24gYXJndW1lbnRzXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPCo+fSBQcm9taXNpZmllZCBmdW5jdGlvblxyXG4gKi9cclxuZnVuY3Rpb24gYXNQcm9taXNlKGZuLCBjdHgvKiwgdmFyYXJncyAqLykge1xyXG4gICAgdmFyIHBhcmFtcyAgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpLFxyXG4gICAgICAgIG9mZnNldCAgPSAwLFxyXG4gICAgICAgIGluZGV4ICAgPSAyLFxyXG4gICAgICAgIHBlbmRpbmcgPSB0cnVlO1xyXG4gICAgd2hpbGUgKGluZGV4IDwgYXJndW1lbnRzLmxlbmd0aClcclxuICAgICAgICBwYXJhbXNbb2Zmc2V0KytdID0gYXJndW1lbnRzW2luZGV4KytdO1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIGV4ZWN1dG9yKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIHBhcmFtc1tvZmZzZXRdID0gZnVuY3Rpb24gY2FsbGJhY2soZXJyLyosIHZhcmFyZ3MgKi8pIHtcclxuICAgICAgICAgICAgaWYgKHBlbmRpbmcpIHtcclxuICAgICAgICAgICAgICAgIHBlbmRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIGlmIChlcnIpXHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyYW1zID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAob2Zmc2V0IDwgcGFyYW1zLmxlbmd0aClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zW29mZnNldCsrXSA9IGFyZ3VtZW50c1tvZmZzZXRdO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUuYXBwbHkobnVsbCwgcGFyYW1zKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgZm4uYXBwbHkoY3R4IHx8IG51bGwsIHBhcmFtcyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIGlmIChwZW5kaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBwZW5kaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG59XHJcbiIsICJcInVzZSBzdHJpY3RcIjtcclxuXHJcbi8qKlxyXG4gKiBBIG1pbmltYWwgYmFzZTY0IGltcGxlbWVudGF0aW9uIGZvciBudW1iZXIgYXJyYXlzLlxyXG4gKiBAbWVtYmVyb2YgdXRpbFxyXG4gKiBAbmFtZXNwYWNlXHJcbiAqL1xyXG52YXIgYmFzZTY0ID0gZXhwb3J0cztcclxuXHJcbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBieXRlIGxlbmd0aCBvZiBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZy5cclxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBCYXNlNjQgZW5jb2RlZCBzdHJpbmdcclxuICogQHJldHVybnMge251bWJlcn0gQnl0ZSBsZW5ndGhcclxuICovXHJcbmJhc2U2NC5sZW5ndGggPSBmdW5jdGlvbiBsZW5ndGgoc3RyaW5nKSB7XHJcbiAgICB2YXIgcCA9IHN0cmluZy5sZW5ndGg7XHJcbiAgICBpZiAoIXApXHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICB2YXIgbiA9IDA7XHJcbiAgICB3aGlsZSAoLS1wICUgNCA+IDEgJiYgc3RyaW5nLmNoYXJBdChwKSA9PT0gXCI9XCIpXHJcbiAgICAgICAgKytuO1xyXG4gICAgcmV0dXJuIE1hdGguY2VpbChzdHJpbmcubGVuZ3RoICogMykgLyA0IC0gbjtcclxufTtcclxuXHJcbi8vIEJhc2U2NCBlbmNvZGluZyB0YWJsZVxyXG52YXIgYjY0ID0gbmV3IEFycmF5KDY0KTtcclxuXHJcbi8vIEJhc2U2NCBkZWNvZGluZyB0YWJsZVxyXG52YXIgczY0ID0gbmV3IEFycmF5KDEyMyk7XHJcblxyXG4vLyA2NS4uOTAsIDk3Li4xMjIsIDQ4Li41NywgNDMsIDQ3XHJcbmZvciAodmFyIGkgPSAwOyBpIDwgNjQ7KVxyXG4gICAgczY0W2I2NFtpXSA9IGkgPCAyNiA/IGkgKyA2NSA6IGkgPCA1MiA/IGkgKyA3MSA6IGkgPCA2MiA/IGkgLSA0IDogaSAtIDU5IHwgNDNdID0gaSsrO1xyXG5cclxuLyoqXHJcbiAqIEVuY29kZXMgYSBidWZmZXIgdG8gYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcuXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmZmVyIFNvdXJjZSBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFNvdXJjZSBzdGFydFxyXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIFNvdXJjZSBlbmRcclxuICogQHJldHVybnMge3N0cmluZ30gQmFzZTY0IGVuY29kZWQgc3RyaW5nXHJcbiAqL1xyXG5iYXNlNjQuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGJ1ZmZlciwgc3RhcnQsIGVuZCkge1xyXG4gICAgdmFyIHBhcnRzID0gbnVsbCxcclxuICAgICAgICBjaHVuayA9IFtdO1xyXG4gICAgdmFyIGkgPSAwLCAvLyBvdXRwdXQgaW5kZXhcclxuICAgICAgICBqID0gMCwgLy8gZ290byBpbmRleFxyXG4gICAgICAgIHQ7ICAgICAvLyB0ZW1wb3JhcnlcclxuICAgIHdoaWxlIChzdGFydCA8IGVuZCkge1xyXG4gICAgICAgIHZhciBiID0gYnVmZmVyW3N0YXJ0KytdO1xyXG4gICAgICAgIHN3aXRjaCAoaikge1xyXG4gICAgICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICAgICAgICBjaHVua1tpKytdID0gYjY0W2IgPj4gMl07XHJcbiAgICAgICAgICAgICAgICB0ID0gKGIgJiAzKSA8PCA0O1xyXG4gICAgICAgICAgICAgICAgaiA9IDE7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAxOlxyXG4gICAgICAgICAgICAgICAgY2h1bmtbaSsrXSA9IGI2NFt0IHwgYiA+PiA0XTtcclxuICAgICAgICAgICAgICAgIHQgPSAoYiAmIDE1KSA8PCAyO1xyXG4gICAgICAgICAgICAgICAgaiA9IDI7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAyOlxyXG4gICAgICAgICAgICAgICAgY2h1bmtbaSsrXSA9IGI2NFt0IHwgYiA+PiA2XTtcclxuICAgICAgICAgICAgICAgIGNodW5rW2krK10gPSBiNjRbYiAmIDYzXTtcclxuICAgICAgICAgICAgICAgIGogPSAwO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChpID4gODE5MSkge1xyXG4gICAgICAgICAgICAocGFydHMgfHwgKHBhcnRzID0gW10pKS5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaHVuaykpO1xyXG4gICAgICAgICAgICBpID0gMDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoaikge1xyXG4gICAgICAgIGNodW5rW2krK10gPSBiNjRbdF07XHJcbiAgICAgICAgY2h1bmtbaSsrXSA9IDYxO1xyXG4gICAgICAgIGlmIChqID09PSAxKVxyXG4gICAgICAgICAgICBjaHVua1tpKytdID0gNjE7XHJcbiAgICB9XHJcbiAgICBpZiAocGFydHMpIHtcclxuICAgICAgICBpZiAoaSlcclxuICAgICAgICAgICAgcGFydHMucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY2h1bmsuc2xpY2UoMCwgaSkpKTtcclxuICAgICAgICByZXR1cm4gcGFydHMuam9pbihcIlwiKTtcclxuICAgIH1cclxuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY2h1bmsuc2xpY2UoMCwgaSkpO1xyXG59O1xyXG5cclxudmFyIGludmFsaWRFbmNvZGluZyA9IFwiaW52YWxpZCBlbmNvZGluZ1wiO1xyXG5cclxuLyoqXHJcbiAqIERlY29kZXMgYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdG8gYSBidWZmZXIuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgU291cmNlIHN0cmluZ1xyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZmZlciBEZXN0aW5hdGlvbiBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBEZXN0aW5hdGlvbiBvZmZzZXRcclxuICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW5cclxuICogQHRocm93cyB7RXJyb3J9IElmIGVuY29kaW5nIGlzIGludmFsaWRcclxuICovXHJcbmJhc2U2NC5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUoc3RyaW5nLCBidWZmZXIsIG9mZnNldCkge1xyXG4gICAgdmFyIHN0YXJ0ID0gb2Zmc2V0O1xyXG4gICAgdmFyIGogPSAwLCAvLyBnb3RvIGluZGV4XHJcbiAgICAgICAgdDsgICAgIC8vIHRlbXBvcmFyeVxyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJpbmcubGVuZ3RoOykge1xyXG4gICAgICAgIHZhciBjID0gc3RyaW5nLmNoYXJDb2RlQXQoaSsrKTtcclxuICAgICAgICBpZiAoYyA9PT0gNjEgJiYgaiA+IDEpXHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGlmICgoYyA9IHM2NFtjXSkgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoaW52YWxpZEVuY29kaW5nKTtcclxuICAgICAgICBzd2l0Y2ggKGopIHtcclxuICAgICAgICAgICAgY2FzZSAwOlxyXG4gICAgICAgICAgICAgICAgdCA9IGM7XHJcbiAgICAgICAgICAgICAgICBqID0gMTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gdCA8PCAyIHwgKGMgJiA0OCkgPj4gNDtcclxuICAgICAgICAgICAgICAgIHQgPSBjO1xyXG4gICAgICAgICAgICAgICAgaiA9IDI7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAyOlxyXG4gICAgICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9ICh0ICYgMTUpIDw8IDQgfCAoYyAmIDYwKSA+PiAyO1xyXG4gICAgICAgICAgICAgICAgdCA9IGM7XHJcbiAgICAgICAgICAgICAgICBqID0gMztcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDM6XHJcbiAgICAgICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gKHQgJiAzKSA8PCA2IHwgYztcclxuICAgICAgICAgICAgICAgIGogPSAwO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGogPT09IDEpXHJcbiAgICAgICAgdGhyb3cgRXJyb3IoaW52YWxpZEVuY29kaW5nKTtcclxuICAgIHJldHVybiBvZmZzZXQgLSBzdGFydDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGUgc3BlY2lmaWVkIHN0cmluZyBhcHBlYXJzIHRvIGJlIGJhc2U2NCBlbmNvZGVkLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFN0cmluZyB0byB0ZXN0XHJcbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgcHJvYmFibHkgYmFzZTY0IGVuY29kZWQsIG90aGVyd2lzZSBmYWxzZVxyXG4gKi9cclxuYmFzZTY0LnRlc3QgPSBmdW5jdGlvbiB0ZXN0KHN0cmluZykge1xyXG4gICAgcmV0dXJuIC9eKD86W0EtWmEtejAtOSsvXXs0fSkqKD86W0EtWmEtejAtOSsvXXsyfT09fFtBLVphLXowLTkrL117M309KT8kLy50ZXN0KHN0cmluZyk7XHJcbn07XHJcbiIsICJcInVzZSBzdHJpY3RcIjtcclxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XHJcblxyXG4vKipcclxuICogQ29uc3RydWN0cyBhIG5ldyBldmVudCBlbWl0dGVyIGluc3RhbmNlLlxyXG4gKiBAY2xhc3NkZXNjIEEgbWluaW1hbCBldmVudCBlbWl0dGVyLlxyXG4gKiBAbWVtYmVyb2YgdXRpbFxyXG4gKiBAY29uc3RydWN0b3JcclxuICovXHJcbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZ2lzdGVyZWQgbGlzdGVuZXJzLlxyXG4gICAgICogQHR5cGUge09iamVjdC48c3RyaW5nLCo+fVxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdGhpcy5fbGlzdGVuZXJzID0ge307XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZWdpc3RlcnMgYW4gZXZlbnQgbGlzdGVuZXIuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBldnQgRXZlbnQgbmFtZVxyXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBmbiBMaXN0ZW5lclxyXG4gKiBAcGFyYW0geyp9IFtjdHhdIExpc3RlbmVyIGNvbnRleHRcclxuICogQHJldHVybnMge3V0aWwuRXZlbnRFbWl0dGVyfSBgdGhpc2BcclxuICovXHJcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBmdW5jdGlvbiBvbihldnQsIGZuLCBjdHgpIHtcclxuICAgICh0aGlzLl9saXN0ZW5lcnNbZXZ0XSB8fCAodGhpcy5fbGlzdGVuZXJzW2V2dF0gPSBbXSkpLnB1c2goe1xyXG4gICAgICAgIGZuICA6IGZuLFxyXG4gICAgICAgIGN0eCA6IGN0eCB8fCB0aGlzXHJcbiAgICB9KTtcclxuICAgIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJlbW92ZXMgYW4gZXZlbnQgbGlzdGVuZXIgb3IgYW55IG1hdGNoaW5nIGxpc3RlbmVycyBpZiBhcmd1bWVudHMgYXJlIG9taXR0ZWQuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBbZXZ0XSBFdmVudCBuYW1lLiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgaWYgb21pdHRlZC5cclxuICogQHBhcmFtIHtmdW5jdGlvbn0gW2ZuXSBMaXN0ZW5lciB0byByZW1vdmUuIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBvZiBgZXZ0YCBpZiBvbWl0dGVkLlxyXG4gKiBAcmV0dXJucyB7dXRpbC5FdmVudEVtaXR0ZXJ9IGB0aGlzYFxyXG4gKi9cclxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiBvZmYoZXZ0LCBmbikge1xyXG4gICAgaWYgKGV2dCA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICAgIHRoaXMuX2xpc3RlbmVycyA9IHt9O1xyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgaWYgKGZuID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgIHRoaXMuX2xpc3RlbmVyc1tldnRdID0gW107XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnNbZXZ0XTtcclxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOylcclxuICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNbaV0uZm4gPT09IGZuKVxyXG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgKytpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEVtaXRzIGFuIGV2ZW50IGJ5IGNhbGxpbmcgaXRzIGxpc3RlbmVycyB3aXRoIHRoZSBzcGVjaWZpZWQgYXJndW1lbnRzLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZ0IEV2ZW50IG5hbWVcclxuICogQHBhcmFtIHsuLi4qfSBhcmdzIEFyZ3VtZW50c1xyXG4gKiBAcmV0dXJucyB7dXRpbC5FdmVudEVtaXR0ZXJ9IGB0aGlzYFxyXG4gKi9cclxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdChldnQpIHtcclxuICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnNbZXZ0XTtcclxuICAgIGlmIChsaXN0ZW5lcnMpIHtcclxuICAgICAgICB2YXIgYXJncyA9IFtdLFxyXG4gICAgICAgICAgICBpID0gMTtcclxuICAgICAgICBmb3IgKDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7KVxyXG4gICAgICAgICAgICBhcmdzLnB1c2goYXJndW1lbnRzW2krK10pO1xyXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOylcclxuICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmZuLmFwcGx5KGxpc3RlbmVyc1tpKytdLmN0eCwgYXJncyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxufTtcclxuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KGZhY3RvcnkpO1xyXG5cclxuLyoqXHJcbiAqIFJlYWRzIC8gd3JpdGVzIGZsb2F0cyAvIGRvdWJsZXMgZnJvbSAvIHRvIGJ1ZmZlcnMuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXRcclxuICogQG5hbWVzcGFjZVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBXcml0ZXMgYSAzMiBiaXQgZmxvYXQgdG8gYSBidWZmZXIgdXNpbmcgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LndyaXRlRmxvYXRMRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBUYXJnZXQgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgVGFyZ2V0IGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogV3JpdGVzIGEgMzIgYml0IGZsb2F0IHRvIGEgYnVmZmVyIHVzaW5nIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC53cml0ZUZsb2F0QkVcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWwgVmFsdWUgdG8gd3JpdGVcclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgVGFyZ2V0IGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFRhcmdldCBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFJlYWRzIGEgMzIgYml0IGZsb2F0IGZyb20gYSBidWZmZXIgdXNpbmcgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LnJlYWRGbG9hdExFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBTb3VyY2UgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgU291cmNlIGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBSZWFkcyBhIDMyIGJpdCBmbG9hdCBmcm9tIGEgYnVmZmVyIHVzaW5nIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC5yZWFkRmxvYXRCRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFNvdXJjZSBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICovXHJcblxyXG4vKipcclxuICogV3JpdGVzIGEgNjQgYml0IGRvdWJsZSB0byBhIGJ1ZmZlciB1c2luZyBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQud3JpdGVEb3VibGVMRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBUYXJnZXQgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgVGFyZ2V0IGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogV3JpdGVzIGEgNjQgYml0IGRvdWJsZSB0byBhIGJ1ZmZlciB1c2luZyBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQud3JpdGVEb3VibGVCRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBUYXJnZXQgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgVGFyZ2V0IGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogUmVhZHMgYSA2NCBiaXQgZG91YmxlIGZyb20gYSBidWZmZXIgdXNpbmcgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LnJlYWREb3VibGVMRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFNvdXJjZSBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICovXHJcblxyXG4vKipcclxuICogUmVhZHMgYSA2NCBiaXQgZG91YmxlIGZyb20gYSBidWZmZXIgdXNpbmcgYmlnIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LnJlYWREb3VibGVCRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFNvdXJjZSBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICovXHJcblxyXG4vLyBGYWN0b3J5IGZ1bmN0aW9uIGZvciB0aGUgcHVycG9zZSBvZiBub2RlLWJhc2VkIHRlc3RpbmcgaW4gbW9kaWZpZWQgZ2xvYmFsIGVudmlyb25tZW50c1xyXG5mdW5jdGlvbiBmYWN0b3J5KGV4cG9ydHMpIHtcclxuXHJcbiAgICAvLyBmbG9hdDogdHlwZWQgYXJyYXlcclxuICAgIGlmICh0eXBlb2YgRmxvYXQzMkFycmF5ICE9PSBcInVuZGVmaW5lZFwiKSAoZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBmMzIgPSBuZXcgRmxvYXQzMkFycmF5KFsgLTAgXSksXHJcbiAgICAgICAgICAgIGY4YiA9IG5ldyBVaW50OEFycmF5KGYzMi5idWZmZXIpLFxyXG4gICAgICAgICAgICBsZSAgPSBmOGJbM10gPT09IDEyODtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gd3JpdGVGbG9hdF9mMzJfY3B5KHZhbCwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjMyWzBdID0gdmFsO1xyXG4gICAgICAgICAgICBidWZbcG9zICAgIF0gPSBmOGJbMF07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAxXSA9IGY4YlsxXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDJdID0gZjhiWzJdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgM10gPSBmOGJbM107XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiB3cml0ZUZsb2F0X2YzMl9yZXYodmFsLCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICBmMzJbMF0gPSB2YWw7XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgICAgXSA9IGY4YlszXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDFdID0gZjhiWzJdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMl0gPSBmOGJbMV07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAzXSA9IGY4YlswXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy53cml0ZUZsb2F0TEUgPSBsZSA/IHdyaXRlRmxvYXRfZjMyX2NweSA6IHdyaXRlRmxvYXRfZjMyX3JldjtcclxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG4gICAgICAgIGV4cG9ydHMud3JpdGVGbG9hdEJFID0gbGUgPyB3cml0ZUZsb2F0X2YzMl9yZXYgOiB3cml0ZUZsb2F0X2YzMl9jcHk7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHJlYWRGbG9hdF9mMzJfY3B5KGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGY4YlswXSA9IGJ1Zltwb3MgICAgXTtcclxuICAgICAgICAgICAgZjhiWzFdID0gYnVmW3BvcyArIDFdO1xyXG4gICAgICAgICAgICBmOGJbMl0gPSBidWZbcG9zICsgMl07XHJcbiAgICAgICAgICAgIGY4YlszXSA9IGJ1Zltwb3MgKyAzXTtcclxuICAgICAgICAgICAgcmV0dXJuIGYzMlswXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHJlYWRGbG9hdF9mMzJfcmV2KGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGY4YlszXSA9IGJ1Zltwb3MgICAgXTtcclxuICAgICAgICAgICAgZjhiWzJdID0gYnVmW3BvcyArIDFdO1xyXG4gICAgICAgICAgICBmOGJbMV0gPSBidWZbcG9zICsgMl07XHJcbiAgICAgICAgICAgIGY4YlswXSA9IGJ1Zltwb3MgKyAzXTtcclxuICAgICAgICAgICAgcmV0dXJuIGYzMlswXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRmxvYXRMRSA9IGxlID8gcmVhZEZsb2F0X2YzMl9jcHkgOiByZWFkRmxvYXRfZjMyX3JldjtcclxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG4gICAgICAgIGV4cG9ydHMucmVhZEZsb2F0QkUgPSBsZSA/IHJlYWRGbG9hdF9mMzJfcmV2IDogcmVhZEZsb2F0X2YzMl9jcHk7XHJcblxyXG4gICAgLy8gZmxvYXQ6IGllZWU3NTRcclxuICAgIH0pKCk7IGVsc2UgKGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICBmdW5jdGlvbiB3cml0ZUZsb2F0X2llZWU3NTQod3JpdGVVaW50LCB2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIHZhciBzaWduID0gdmFsIDwgMCA/IDEgOiAwO1xyXG4gICAgICAgICAgICBpZiAoc2lnbilcclxuICAgICAgICAgICAgICAgIHZhbCA9IC12YWw7XHJcbiAgICAgICAgICAgIGlmICh2YWwgPT09IDApXHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoMSAvIHZhbCA+IDAgPyAvKiBwb3NpdGl2ZSAqLyAwIDogLyogbmVnYXRpdmUgMCAqLyAyMTQ3NDgzNjQ4LCBidWYsIHBvcyk7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGlzTmFOKHZhbCkpXHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoMjE0MzI4OTM0NCwgYnVmLCBwb3MpO1xyXG4gICAgICAgICAgICBlbHNlIGlmICh2YWwgPiAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KSAvLyArLUluZmluaXR5XHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoKHNpZ24gPDwgMzEgfCAyMTM5MDk1MDQwKSA+Pj4gMCwgYnVmLCBwb3MpO1xyXG4gICAgICAgICAgICBlbHNlIGlmICh2YWwgPCAxLjE3NTQ5NDM1MDgyMjI4NzVlLTM4KSAvLyBkZW5vcm1hbFxyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KChzaWduIDw8IDMxIHwgTWF0aC5yb3VuZCh2YWwgLyAxLjQwMTI5ODQ2NDMyNDgxN2UtNDUpKSA+Pj4gMCwgYnVmLCBwb3MpO1xyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHZhciBleHBvbmVudCA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsKSAvIE1hdGguTE4yKSxcclxuICAgICAgICAgICAgICAgICAgICBtYW50aXNzYSA9IE1hdGgucm91bmQodmFsICogTWF0aC5wb3coMiwgLWV4cG9uZW50KSAqIDgzODg2MDgpICYgODM4ODYwNztcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgoc2lnbiA8PCAzMSB8IGV4cG9uZW50ICsgMTI3IDw8IDIzIHwgbWFudGlzc2EpID4+PiAwLCBidWYsIHBvcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGV4cG9ydHMud3JpdGVGbG9hdExFID0gd3JpdGVGbG9hdF9pZWVlNzU0LmJpbmQobnVsbCwgd3JpdGVVaW50TEUpO1xyXG4gICAgICAgIGV4cG9ydHMud3JpdGVGbG9hdEJFID0gd3JpdGVGbG9hdF9pZWVlNzU0LmJpbmQobnVsbCwgd3JpdGVVaW50QkUpO1xyXG5cclxuICAgICAgICBmdW5jdGlvbiByZWFkRmxvYXRfaWVlZTc1NChyZWFkVWludCwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgdmFyIHVpbnQgPSByZWFkVWludChidWYsIHBvcyksXHJcbiAgICAgICAgICAgICAgICBzaWduID0gKHVpbnQgPj4gMzEpICogMiArIDEsXHJcbiAgICAgICAgICAgICAgICBleHBvbmVudCA9IHVpbnQgPj4+IDIzICYgMjU1LFxyXG4gICAgICAgICAgICAgICAgbWFudGlzc2EgPSB1aW50ICYgODM4ODYwNztcclxuICAgICAgICAgICAgcmV0dXJuIGV4cG9uZW50ID09PSAyNTVcclxuICAgICAgICAgICAgICAgID8gbWFudGlzc2FcclxuICAgICAgICAgICAgICAgID8gTmFOXHJcbiAgICAgICAgICAgICAgICA6IHNpZ24gKiBJbmZpbml0eVxyXG4gICAgICAgICAgICAgICAgOiBleHBvbmVudCA9PT0gMCAvLyBkZW5vcm1hbFxyXG4gICAgICAgICAgICAgICAgPyBzaWduICogMS40MDEyOTg0NjQzMjQ4MTdlLTQ1ICogbWFudGlzc2FcclxuICAgICAgICAgICAgICAgIDogc2lnbiAqIE1hdGgucG93KDIsIGV4cG9uZW50IC0gMTUwKSAqIChtYW50aXNzYSArIDgzODg2MDgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRmxvYXRMRSA9IHJlYWRGbG9hdF9pZWVlNzU0LmJpbmQobnVsbCwgcmVhZFVpbnRMRSk7XHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRmxvYXRCRSA9IHJlYWRGbG9hdF9pZWVlNzU0LmJpbmQobnVsbCwgcmVhZFVpbnRCRSk7XHJcblxyXG4gICAgfSkoKTtcclxuXHJcbiAgICAvLyBkb3VibGU6IHR5cGVkIGFycmF5XHJcbiAgICBpZiAodHlwZW9mIEZsb2F0NjRBcnJheSAhPT0gXCJ1bmRlZmluZWRcIikgKGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgZjY0ID0gbmV3IEZsb2F0NjRBcnJheShbLTBdKSxcclxuICAgICAgICAgICAgZjhiID0gbmV3IFVpbnQ4QXJyYXkoZjY0LmJ1ZmZlciksXHJcbiAgICAgICAgICAgIGxlICA9IGY4Yls3XSA9PT0gMTI4O1xyXG5cclxuICAgICAgICBmdW5jdGlvbiB3cml0ZURvdWJsZV9mNjRfY3B5KHZhbCwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjY0WzBdID0gdmFsO1xyXG4gICAgICAgICAgICBidWZbcG9zICAgIF0gPSBmOGJbMF07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAxXSA9IGY4YlsxXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDJdID0gZjhiWzJdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgM10gPSBmOGJbM107XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyA0XSA9IGY4Yls0XTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDVdID0gZjhiWzVdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgNl0gPSBmOGJbNl07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyA3XSA9IGY4Yls3XTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHdyaXRlRG91YmxlX2Y2NF9yZXYodmFsLCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICBmNjRbMF0gPSB2YWw7XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgICAgXSA9IGY4Yls3XTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDFdID0gZjhiWzZdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMl0gPSBmOGJbNV07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAzXSA9IGY4Yls0XTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDRdID0gZjhiWzNdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgNV0gPSBmOGJbMl07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyA2XSA9IGY4YlsxXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDddID0gZjhiWzBdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLndyaXRlRG91YmxlTEUgPSBsZSA/IHdyaXRlRG91YmxlX2Y2NF9jcHkgOiB3cml0ZURvdWJsZV9mNjRfcmV2O1xyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy53cml0ZURvdWJsZUJFID0gbGUgPyB3cml0ZURvdWJsZV9mNjRfcmV2IDogd3JpdGVEb3VibGVfZjY0X2NweTtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gcmVhZERvdWJsZV9mNjRfY3B5KGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGY4YlswXSA9IGJ1Zltwb3MgICAgXTtcclxuICAgICAgICAgICAgZjhiWzFdID0gYnVmW3BvcyArIDFdO1xyXG4gICAgICAgICAgICBmOGJbMl0gPSBidWZbcG9zICsgMl07XHJcbiAgICAgICAgICAgIGY4YlszXSA9IGJ1Zltwb3MgKyAzXTtcclxuICAgICAgICAgICAgZjhiWzRdID0gYnVmW3BvcyArIDRdO1xyXG4gICAgICAgICAgICBmOGJbNV0gPSBidWZbcG9zICsgNV07XHJcbiAgICAgICAgICAgIGY4Yls2XSA9IGJ1Zltwb3MgKyA2XTtcclxuICAgICAgICAgICAgZjhiWzddID0gYnVmW3BvcyArIDddO1xyXG4gICAgICAgICAgICByZXR1cm4gZjY0WzBdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gcmVhZERvdWJsZV9mNjRfcmV2KGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGY4Yls3XSA9IGJ1Zltwb3MgICAgXTtcclxuICAgICAgICAgICAgZjhiWzZdID0gYnVmW3BvcyArIDFdO1xyXG4gICAgICAgICAgICBmOGJbNV0gPSBidWZbcG9zICsgMl07XHJcbiAgICAgICAgICAgIGY4Yls0XSA9IGJ1Zltwb3MgKyAzXTtcclxuICAgICAgICAgICAgZjhiWzNdID0gYnVmW3BvcyArIDRdO1xyXG4gICAgICAgICAgICBmOGJbMl0gPSBidWZbcG9zICsgNV07XHJcbiAgICAgICAgICAgIGY4YlsxXSA9IGJ1Zltwb3MgKyA2XTtcclxuICAgICAgICAgICAgZjhiWzBdID0gYnVmW3BvcyArIDddO1xyXG4gICAgICAgICAgICByZXR1cm4gZjY0WzBdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLnJlYWREb3VibGVMRSA9IGxlID8gcmVhZERvdWJsZV9mNjRfY3B5IDogcmVhZERvdWJsZV9mNjRfcmV2O1xyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRG91YmxlQkUgPSBsZSA/IHJlYWREb3VibGVfZjY0X3JldiA6IHJlYWREb3VibGVfZjY0X2NweTtcclxuXHJcbiAgICAvLyBkb3VibGU6IGllZWU3NTRcclxuICAgIH0pKCk7IGVsc2UgKGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICBmdW5jdGlvbiB3cml0ZURvdWJsZV9pZWVlNzU0KHdyaXRlVWludCwgb2ZmMCwgb2ZmMSwgdmFsLCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICB2YXIgc2lnbiA9IHZhbCA8IDAgPyAxIDogMDtcclxuICAgICAgICAgICAgaWYgKHNpZ24pXHJcbiAgICAgICAgICAgICAgICB2YWwgPSAtdmFsO1xyXG4gICAgICAgICAgICBpZiAodmFsID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoMCwgYnVmLCBwb3MgKyBvZmYwKTtcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgxIC8gdmFsID4gMCA/IC8qIHBvc2l0aXZlICovIDAgOiAvKiBuZWdhdGl2ZSAwICovIDIxNDc0ODM2NDgsIGJ1ZiwgcG9zICsgb2ZmMSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNOYU4odmFsKSkge1xyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KDAsIGJ1ZiwgcG9zICsgb2ZmMCk7XHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoMjE0Njk1OTM2MCwgYnVmLCBwb3MgKyBvZmYxKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWwgPiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOCkgeyAvLyArLUluZmluaXR5XHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoMCwgYnVmLCBwb3MgKyBvZmYwKTtcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgoc2lnbiA8PCAzMSB8IDIxNDY0MzUwNzIpID4+PiAwLCBidWYsIHBvcyArIG9mZjEpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdmFyIG1hbnRpc3NhO1xyXG4gICAgICAgICAgICAgICAgaWYgKHZhbCA8IDIuMjI1MDczODU4NTA3MjAxNGUtMzA4KSB7IC8vIGRlbm9ybWFsXHJcbiAgICAgICAgICAgICAgICAgICAgbWFudGlzc2EgPSB2YWwgLyA1ZS0zMjQ7XHJcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVVaW50KG1hbnRpc3NhID4+PiAwLCBidWYsIHBvcyArIG9mZjApO1xyXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlVWludCgoc2lnbiA8PCAzMSB8IG1hbnRpc3NhIC8gNDI5NDk2NzI5NikgPj4+IDAsIGJ1ZiwgcG9zICsgb2ZmMSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBleHBvbmVudCA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsKSAvIE1hdGguTE4yKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXhwb25lbnQgPT09IDEwMjQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9uZW50ID0gMTAyMztcclxuICAgICAgICAgICAgICAgICAgICBtYW50aXNzYSA9IHZhbCAqIE1hdGgucG93KDIsIC1leHBvbmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVVaW50KG1hbnRpc3NhICogNDUwMzU5OTYyNzM3MDQ5NiA+Pj4gMCwgYnVmLCBwb3MgKyBvZmYwKTtcclxuICAgICAgICAgICAgICAgICAgICB3cml0ZVVpbnQoKHNpZ24gPDwgMzEgfCBleHBvbmVudCArIDEwMjMgPDwgMjAgfCBtYW50aXNzYSAqIDEwNDg1NzYgJiAxMDQ4NTc1KSA+Pj4gMCwgYnVmLCBwb3MgKyBvZmYxKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZXhwb3J0cy53cml0ZURvdWJsZUxFID0gd3JpdGVEb3VibGVfaWVlZTc1NC5iaW5kKG51bGwsIHdyaXRlVWludExFLCAwLCA0KTtcclxuICAgICAgICBleHBvcnRzLndyaXRlRG91YmxlQkUgPSB3cml0ZURvdWJsZV9pZWVlNzU0LmJpbmQobnVsbCwgd3JpdGVVaW50QkUsIDQsIDApO1xyXG5cclxuICAgICAgICBmdW5jdGlvbiByZWFkRG91YmxlX2llZWU3NTQocmVhZFVpbnQsIG9mZjAsIG9mZjEsIGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIHZhciBsbyA9IHJlYWRVaW50KGJ1ZiwgcG9zICsgb2ZmMCksXHJcbiAgICAgICAgICAgICAgICBoaSA9IHJlYWRVaW50KGJ1ZiwgcG9zICsgb2ZmMSk7XHJcbiAgICAgICAgICAgIHZhciBzaWduID0gKGhpID4+IDMxKSAqIDIgKyAxLFxyXG4gICAgICAgICAgICAgICAgZXhwb25lbnQgPSBoaSA+Pj4gMjAgJiAyMDQ3LFxyXG4gICAgICAgICAgICAgICAgbWFudGlzc2EgPSA0Mjk0OTY3Mjk2ICogKGhpICYgMTA0ODU3NSkgKyBsbztcclxuICAgICAgICAgICAgcmV0dXJuIGV4cG9uZW50ID09PSAyMDQ3XHJcbiAgICAgICAgICAgICAgICA/IG1hbnRpc3NhXHJcbiAgICAgICAgICAgICAgICA/IE5hTlxyXG4gICAgICAgICAgICAgICAgOiBzaWduICogSW5maW5pdHlcclxuICAgICAgICAgICAgICAgIDogZXhwb25lbnQgPT09IDAgLy8gZGVub3JtYWxcclxuICAgICAgICAgICAgICAgID8gc2lnbiAqIDVlLTMyNCAqIG1hbnRpc3NhXHJcbiAgICAgICAgICAgICAgICA6IHNpZ24gKiBNYXRoLnBvdygyLCBleHBvbmVudCAtIDEwNzUpICogKG1hbnRpc3NhICsgNDUwMzU5OTYyNzM3MDQ5Nik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBleHBvcnRzLnJlYWREb3VibGVMRSA9IHJlYWREb3VibGVfaWVlZTc1NC5iaW5kKG51bGwsIHJlYWRVaW50TEUsIDAsIDQpO1xyXG4gICAgICAgIGV4cG9ydHMucmVhZERvdWJsZUJFID0gcmVhZERvdWJsZV9pZWVlNzU0LmJpbmQobnVsbCwgcmVhZFVpbnRCRSwgNCwgMCk7XHJcblxyXG4gICAgfSkoKTtcclxuXHJcbiAgICByZXR1cm4gZXhwb3J0cztcclxufVxyXG5cclxuLy8gdWludCBoZWxwZXJzXHJcblxyXG5mdW5jdGlvbiB3cml0ZVVpbnRMRSh2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICBidWZbcG9zICAgIF0gPSAgdmFsICAgICAgICAmIDI1NTtcclxuICAgIGJ1Zltwb3MgKyAxXSA9ICB2YWwgPj4+IDggICYgMjU1O1xyXG4gICAgYnVmW3BvcyArIDJdID0gIHZhbCA+Pj4gMTYgJiAyNTU7XHJcbiAgICBidWZbcG9zICsgM10gPSAgdmFsID4+PiAyNDtcclxufVxyXG5cclxuZnVuY3Rpb24gd3JpdGVVaW50QkUodmFsLCBidWYsIHBvcykge1xyXG4gICAgYnVmW3BvcyAgICBdID0gIHZhbCA+Pj4gMjQ7XHJcbiAgICBidWZbcG9zICsgMV0gPSAgdmFsID4+PiAxNiAmIDI1NTtcclxuICAgIGJ1Zltwb3MgKyAyXSA9ICB2YWwgPj4+IDggICYgMjU1O1xyXG4gICAgYnVmW3BvcyArIDNdID0gIHZhbCAgICAgICAgJiAyNTU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlYWRVaW50TEUoYnVmLCBwb3MpIHtcclxuICAgIHJldHVybiAoYnVmW3BvcyAgICBdXHJcbiAgICAgICAgICB8IGJ1Zltwb3MgKyAxXSA8PCA4XHJcbiAgICAgICAgICB8IGJ1Zltwb3MgKyAyXSA8PCAxNlxyXG4gICAgICAgICAgfCBidWZbcG9zICsgM10gPDwgMjQpID4+PiAwO1xyXG59XHJcblxyXG5mdW5jdGlvbiByZWFkVWludEJFKGJ1ZiwgcG9zKSB7XHJcbiAgICByZXR1cm4gKGJ1Zltwb3MgICAgXSA8PCAyNFxyXG4gICAgICAgICAgfCBidWZbcG9zICsgMV0gPDwgMTZcclxuICAgICAgICAgIHwgYnVmW3BvcyArIDJdIDw8IDhcclxuICAgICAgICAgIHwgYnVmW3BvcyArIDNdKSA+Pj4gMDtcclxufVxyXG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XHJcbm1vZHVsZS5leHBvcnRzID0gaW5xdWlyZTtcclxuXHJcbi8qKlxyXG4gKiBSZXF1aXJlcyBhIG1vZHVsZSBvbmx5IGlmIGF2YWlsYWJsZS5cclxuICogQG1lbWJlcm9mIHV0aWxcclxuICogQHBhcmFtIHtzdHJpbmd9IG1vZHVsZU5hbWUgTW9kdWxlIHRvIHJlcXVpcmVcclxuICogQHJldHVybnMgez9PYmplY3R9IFJlcXVpcmVkIG1vZHVsZSBpZiBhdmFpbGFibGUgYW5kIG5vdCBlbXB0eSwgb3RoZXJ3aXNlIGBudWxsYFxyXG4gKi9cclxuZnVuY3Rpb24gaW5xdWlyZShtb2R1bGVOYW1lKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHZhciBtb2QgPSBldmFsKFwicXVpcmVcIi5yZXBsYWNlKC9eLyxcInJlXCIpKShtb2R1bGVOYW1lKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1ldmFsXHJcbiAgICAgICAgaWYgKG1vZCAmJiAobW9kLmxlbmd0aCB8fCBPYmplY3Qua2V5cyhtb2QpLmxlbmd0aCkpXHJcbiAgICAgICAgICAgIHJldHVybiBtb2Q7XHJcbiAgICB9IGNhdGNoIChlKSB7fSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWVtcHR5XHJcbiAgICByZXR1cm4gbnVsbDtcclxufVxyXG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vKipcclxuICogQSBtaW5pbWFsIFVURjggaW1wbGVtZW50YXRpb24gZm9yIG51bWJlciBhcnJheXMuXHJcbiAqIEBtZW1iZXJvZiB1dGlsXHJcbiAqIEBuYW1lc3BhY2VcclxuICovXHJcbnZhciB1dGY4ID0gZXhwb3J0cztcclxuXHJcbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBVVEY4IGJ5dGUgbGVuZ3RoIG9mIGEgc3RyaW5nLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFN0cmluZ1xyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBCeXRlIGxlbmd0aFxyXG4gKi9cclxudXRmOC5sZW5ndGggPSBmdW5jdGlvbiB1dGY4X2xlbmd0aChzdHJpbmcpIHtcclxuICAgIHZhciBsZW4gPSAwLFxyXG4gICAgICAgIGMgPSAwO1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJpbmcubGVuZ3RoOyArK2kpIHtcclxuICAgICAgICBjID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7XHJcbiAgICAgICAgaWYgKGMgPCAxMjgpXHJcbiAgICAgICAgICAgIGxlbiArPSAxO1xyXG4gICAgICAgIGVsc2UgaWYgKGMgPCAyMDQ4KVxyXG4gICAgICAgICAgICBsZW4gKz0gMjtcclxuICAgICAgICBlbHNlIGlmICgoYyAmIDB4RkMwMCkgPT09IDB4RDgwMCAmJiAoc3RyaW5nLmNoYXJDb2RlQXQoaSArIDEpICYgMHhGQzAwKSA9PT0gMHhEQzAwKSB7XHJcbiAgICAgICAgICAgICsraTtcclxuICAgICAgICAgICAgbGVuICs9IDQ7XHJcbiAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICAgIGxlbiArPSAzO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGxlbjtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZWFkcyBVVEY4IGJ5dGVzIGFzIGEgc3RyaW5nLlxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZmZlciBTb3VyY2UgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCBTb3VyY2Ugc3RhcnRcclxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBTb3VyY2UgZW5kXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFN0cmluZyByZWFkXHJcbiAqL1xyXG51dGY4LnJlYWQgPSBmdW5jdGlvbiB1dGY4X3JlYWQoYnVmZmVyLCBzdGFydCwgZW5kKSB7XHJcbiAgICB2YXIgbGVuID0gZW5kIC0gc3RhcnQ7XHJcbiAgICBpZiAobGVuIDwgMSlcclxuICAgICAgICByZXR1cm4gXCJcIjtcclxuICAgIHZhciBwYXJ0cyA9IG51bGwsXHJcbiAgICAgICAgY2h1bmsgPSBbXSxcclxuICAgICAgICBpID0gMCwgLy8gY2hhciBvZmZzZXRcclxuICAgICAgICB0OyAgICAgLy8gdGVtcG9yYXJ5XHJcbiAgICB3aGlsZSAoc3RhcnQgPCBlbmQpIHtcclxuICAgICAgICB0ID0gYnVmZmVyW3N0YXJ0KytdO1xyXG4gICAgICAgIGlmICh0IDwgMTI4KVxyXG4gICAgICAgICAgICBjaHVua1tpKytdID0gdDtcclxuICAgICAgICBlbHNlIGlmICh0ID4gMTkxICYmIHQgPCAyMjQpXHJcbiAgICAgICAgICAgIGNodW5rW2krK10gPSAodCAmIDMxKSA8PCA2IHwgYnVmZmVyW3N0YXJ0KytdICYgNjM7XHJcbiAgICAgICAgZWxzZSBpZiAodCA+IDIzOSAmJiB0IDwgMzY1KSB7XHJcbiAgICAgICAgICAgIHQgPSAoKHQgJiA3KSA8PCAxOCB8IChidWZmZXJbc3RhcnQrK10gJiA2MykgPDwgMTIgfCAoYnVmZmVyW3N0YXJ0KytdICYgNjMpIDw8IDYgfCBidWZmZXJbc3RhcnQrK10gJiA2MykgLSAweDEwMDAwO1xyXG4gICAgICAgICAgICBjaHVua1tpKytdID0gMHhEODAwICsgKHQgPj4gMTApO1xyXG4gICAgICAgICAgICBjaHVua1tpKytdID0gMHhEQzAwICsgKHQgJiAxMDIzKTtcclxuICAgICAgICB9IGVsc2VcclxuICAgICAgICAgICAgY2h1bmtbaSsrXSA9ICh0ICYgMTUpIDw8IDEyIHwgKGJ1ZmZlcltzdGFydCsrXSAmIDYzKSA8PCA2IHwgYnVmZmVyW3N0YXJ0KytdICYgNjM7XHJcbiAgICAgICAgaWYgKGkgPiA4MTkxKSB7XHJcbiAgICAgICAgICAgIChwYXJ0cyB8fCAocGFydHMgPSBbXSkpLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNodW5rKSk7XHJcbiAgICAgICAgICAgIGkgPSAwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChwYXJ0cykge1xyXG4gICAgICAgIGlmIChpKVxyXG4gICAgICAgICAgICBwYXJ0cy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaHVuay5zbGljZSgwLCBpKSkpO1xyXG4gICAgICAgIHJldHVybiBwYXJ0cy5qb2luKFwiXCIpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaHVuay5zbGljZSgwLCBpKSk7XHJcbn07XHJcblxyXG4vKipcclxuICogV3JpdGVzIGEgc3RyaW5nIGFzIFVURjggYnl0ZXMuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgU291cmNlIHN0cmluZ1xyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZmZlciBEZXN0aW5hdGlvbiBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBEZXN0aW5hdGlvbiBvZmZzZXRcclxuICogQHJldHVybnMge251bWJlcn0gQnl0ZXMgd3JpdHRlblxyXG4gKi9cclxudXRmOC53cml0ZSA9IGZ1bmN0aW9uIHV0Zjhfd3JpdGUoc3RyaW5nLCBidWZmZXIsIG9mZnNldCkge1xyXG4gICAgdmFyIHN0YXJ0ID0gb2Zmc2V0LFxyXG4gICAgICAgIGMxLCAvLyBjaGFyYWN0ZXIgMVxyXG4gICAgICAgIGMyOyAvLyBjaGFyYWN0ZXIgMlxyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJpbmcubGVuZ3RoOyArK2kpIHtcclxuICAgICAgICBjMSA9IHN0cmluZy5jaGFyQ29kZUF0KGkpO1xyXG4gICAgICAgIGlmIChjMSA8IDEyOCkge1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzE7XHJcbiAgICAgICAgfSBlbHNlIGlmIChjMSA8IDIwNDgpIHtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxID4+IDYgICAgICAgfCAxOTI7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSAgICAgICAmIDYzIHwgMTI4O1xyXG4gICAgICAgIH0gZWxzZSBpZiAoKGMxICYgMHhGQzAwKSA9PT0gMHhEODAwICYmICgoYzIgPSBzdHJpbmcuY2hhckNvZGVBdChpICsgMSkpICYgMHhGQzAwKSA9PT0gMHhEQzAwKSB7XHJcbiAgICAgICAgICAgIGMxID0gMHgxMDAwMCArICgoYzEgJiAweDAzRkYpIDw8IDEwKSArIChjMiAmIDB4MDNGRik7XHJcbiAgICAgICAgICAgICsraTtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxID4+IDE4ICAgICAgfCAyNDA7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSA+PiAxMiAmIDYzIHwgMTI4O1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgPj4gNiAgJiA2MyB8IDEyODtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxICAgICAgICYgNjMgfCAxMjg7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxID4+IDEyICAgICAgfCAyMjQ7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSA+PiA2ICAmIDYzIHwgMTI4O1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgICAgICAgJiA2MyB8IDEyODtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gb2Zmc2V0IC0gc3RhcnQ7XHJcbn07XHJcbiIsICJcInVzZSBzdHJpY3RcIjtcclxubW9kdWxlLmV4cG9ydHMgPSBwb29sO1xyXG5cclxuLyoqXHJcbiAqIEFuIGFsbG9jYXRvciBhcyB1c2VkIGJ5IHtAbGluayB1dGlsLnBvb2x9LlxyXG4gKiBAdHlwZWRlZiBQb29sQWxsb2NhdG9yXHJcbiAqIEB0eXBlIHtmdW5jdGlvbn1cclxuICogQHBhcmFtIHtudW1iZXJ9IHNpemUgQnVmZmVyIHNpemVcclxuICogQHJldHVybnMge1VpbnQ4QXJyYXl9IEJ1ZmZlclxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBBIHNsaWNlciBhcyB1c2VkIGJ5IHtAbGluayB1dGlsLnBvb2x9LlxyXG4gKiBAdHlwZWRlZiBQb29sU2xpY2VyXHJcbiAqIEB0eXBlIHtmdW5jdGlvbn1cclxuICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFN0YXJ0IG9mZnNldFxyXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZCBvZmZzZXRcclxuICogQHJldHVybnMge1VpbnQ4QXJyYXl9IEJ1ZmZlciBzbGljZVxyXG4gKiBAdGhpcyB7VWludDhBcnJheX1cclxuICovXHJcblxyXG4vKipcclxuICogQSBnZW5lcmFsIHB1cnBvc2UgYnVmZmVyIHBvb2wuXHJcbiAqIEBtZW1iZXJvZiB1dGlsXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge1Bvb2xBbGxvY2F0b3J9IGFsbG9jIEFsbG9jYXRvclxyXG4gKiBAcGFyYW0ge1Bvb2xTbGljZXJ9IHNsaWNlIFNsaWNlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gW3NpemU9ODE5Ml0gU2xhYiBzaXplXHJcbiAqIEByZXR1cm5zIHtQb29sQWxsb2NhdG9yfSBQb29sZWQgYWxsb2NhdG9yXHJcbiAqL1xyXG5mdW5jdGlvbiBwb29sKGFsbG9jLCBzbGljZSwgc2l6ZSkge1xyXG4gICAgdmFyIFNJWkUgICA9IHNpemUgfHwgODE5MjtcclxuICAgIHZhciBNQVggICAgPSBTSVpFID4+PiAxO1xyXG4gICAgdmFyIHNsYWIgICA9IG51bGw7XHJcbiAgICB2YXIgb2Zmc2V0ID0gU0laRTtcclxuICAgIHJldHVybiBmdW5jdGlvbiBwb29sX2FsbG9jKHNpemUpIHtcclxuICAgICAgICBpZiAoc2l6ZSA8IDEgfHwgc2l6ZSA+IE1BWClcclxuICAgICAgICAgICAgcmV0dXJuIGFsbG9jKHNpemUpO1xyXG4gICAgICAgIGlmIChvZmZzZXQgKyBzaXplID4gU0laRSkge1xyXG4gICAgICAgICAgICBzbGFiID0gYWxsb2MoU0laRSk7XHJcbiAgICAgICAgICAgIG9mZnNldCA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBidWYgPSBzbGljZS5jYWxsKHNsYWIsIG9mZnNldCwgb2Zmc2V0ICs9IHNpemUpO1xyXG4gICAgICAgIGlmIChvZmZzZXQgJiA3KSAvLyBhbGlnbiB0byAzMiBiaXRcclxuICAgICAgICAgICAgb2Zmc2V0ID0gKG9mZnNldCB8IDcpICsgMTtcclxuICAgICAgICByZXR1cm4gYnVmO1xyXG4gICAgfTtcclxufVxyXG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IExvbmdCaXRzO1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsL21pbmltYWxcIik7XG5cbi8qKlxuICogQ29uc3RydWN0cyBuZXcgbG9uZyBiaXRzLlxuICogQGNsYXNzZGVzYyBIZWxwZXIgY2xhc3MgZm9yIHdvcmtpbmcgd2l0aCB0aGUgbG93IGFuZCBoaWdoIGJpdHMgb2YgYSA2NCBiaXQgdmFsdWUuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge251bWJlcn0gbG8gTG93IDMyIGJpdHMsIHVuc2lnbmVkXG4gKiBAcGFyYW0ge251bWJlcn0gaGkgSGlnaCAzMiBiaXRzLCB1bnNpZ25lZFxuICovXG5mdW5jdGlvbiBMb25nQml0cyhsbywgaGkpIHtcblxuICAgIC8vIG5vdGUgdGhhdCB0aGUgY2FzdHMgYmVsb3cgYXJlIHRoZW9yZXRpY2FsbHkgdW5uZWNlc3NhcnkgYXMgb2YgdG9kYXksIGJ1dCBvbGRlciBzdGF0aWNhbGx5XG4gICAgLy8gZ2VuZXJhdGVkIGNvbnZlcnRlciBjb2RlIG1pZ2h0IHN0aWxsIGNhbGwgdGhlIGN0b3Igd2l0aCBzaWduZWQgMzJiaXRzLiBrZXB0IGZvciBjb21wYXQuXG5cbiAgICAvKipcbiAgICAgKiBMb3cgYml0cy5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMubG8gPSBsbyA+Pj4gMDtcblxuICAgIC8qKlxuICAgICAqIEhpZ2ggYml0cy5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMuaGkgPSBoaSA+Pj4gMDtcbn1cblxuLyoqXG4gKiBaZXJvIGJpdHMuXG4gKiBAbWVtYmVyb2YgdXRpbC5Mb25nQml0c1xuICogQHR5cGUge3V0aWwuTG9uZ0JpdHN9XG4gKi9cbnZhciB6ZXJvID0gTG9uZ0JpdHMuemVybyA9IG5ldyBMb25nQml0cygwLCAwKTtcblxuemVyby50b051bWJlciA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbnplcm8uenpFbmNvZGUgPSB6ZXJvLnp6RGVjb2RlID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9O1xuemVyby5sZW5ndGggPSBmdW5jdGlvbigpIHsgcmV0dXJuIDE7IH07XG5cbi8qKlxuICogWmVybyBoYXNoLlxuICogQG1lbWJlcm9mIHV0aWwuTG9uZ0JpdHNcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbnZhciB6ZXJvSGFzaCA9IExvbmdCaXRzLnplcm9IYXNoID0gXCJcXDBcXDBcXDBcXDBcXDBcXDBcXDBcXDBcIjtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIG5ldyBsb25nIGJpdHMgZnJvbSB0aGUgc3BlY2lmaWVkIG51bWJlci5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZVxuICogQHJldHVybnMge3V0aWwuTG9uZ0JpdHN9IEluc3RhbmNlXG4gKi9cbkxvbmdCaXRzLmZyb21OdW1iZXIgPSBmdW5jdGlvbiBmcm9tTnVtYmVyKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09PSAwKVxuICAgICAgICByZXR1cm4gemVybztcbiAgICB2YXIgc2lnbiA9IHZhbHVlIDwgMDtcbiAgICBpZiAoc2lnbilcbiAgICAgICAgdmFsdWUgPSAtdmFsdWU7XG4gICAgdmFyIGxvID0gdmFsdWUgPj4+IDAsXG4gICAgICAgIGhpID0gKHZhbHVlIC0gbG8pIC8gNDI5NDk2NzI5NiA+Pj4gMDtcbiAgICBpZiAoc2lnbikge1xuICAgICAgICBoaSA9IH5oaSA+Pj4gMDtcbiAgICAgICAgbG8gPSB+bG8gPj4+IDA7XG4gICAgICAgIGlmICgrK2xvID4gNDI5NDk2NzI5NSkge1xuICAgICAgICAgICAgbG8gPSAwO1xuICAgICAgICAgICAgaWYgKCsraGkgPiA0Mjk0OTY3Mjk1KVxuICAgICAgICAgICAgICAgIGhpID0gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbmV3IExvbmdCaXRzKGxvLCBoaSk7XG59O1xuXG4vKipcbiAqIENvbnN0cnVjdHMgbmV3IGxvbmcgYml0cyBmcm9tIGEgbnVtYmVyLCBsb25nIG9yIHN0cmluZy5cbiAqIEBwYXJhbSB7TG9uZ3xudW1iZXJ8c3RyaW5nfSB2YWx1ZSBWYWx1ZVxuICogQHJldHVybnMge3V0aWwuTG9uZ0JpdHN9IEluc3RhbmNlXG4gKi9cbkxvbmdCaXRzLmZyb20gPSBmdW5jdGlvbiBmcm9tKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgcmV0dXJuIExvbmdCaXRzLmZyb21OdW1iZXIodmFsdWUpO1xuICAgIGlmICh1dGlsLmlzU3RyaW5nKHZhbHVlKSkge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgICBpZiAodXRpbC5Mb25nKVxuICAgICAgICAgICAgdmFsdWUgPSB1dGlsLkxvbmcuZnJvbVN0cmluZyh2YWx1ZSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJldHVybiBMb25nQml0cy5mcm9tTnVtYmVyKHBhcnNlSW50KHZhbHVlLCAxMCkpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWUubG93IHx8IHZhbHVlLmhpZ2ggPyBuZXcgTG9uZ0JpdHModmFsdWUubG93ID4+PiAwLCB2YWx1ZS5oaWdoID4+PiAwKSA6IHplcm87XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIHRoaXMgbG9uZyBiaXRzIHRvIGEgcG9zc2libHkgdW5zYWZlIEphdmFTY3JpcHQgbnVtYmVyLlxuICogQHBhcmFtIHtib29sZWFufSBbdW5zaWduZWQ9ZmFsc2VdIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBQb3NzaWJseSB1bnNhZmUgbnVtYmVyXG4gKi9cbkxvbmdCaXRzLnByb3RvdHlwZS50b051bWJlciA9IGZ1bmN0aW9uIHRvTnVtYmVyKHVuc2lnbmVkKSB7XG4gICAgaWYgKCF1bnNpZ25lZCAmJiB0aGlzLmhpID4+PiAzMSkge1xuICAgICAgICB2YXIgbG8gPSB+dGhpcy5sbyArIDEgPj4+IDAsXG4gICAgICAgICAgICBoaSA9IH50aGlzLmhpICAgICA+Pj4gMDtcbiAgICAgICAgaWYgKCFsbylcbiAgICAgICAgICAgIGhpID0gaGkgKyAxID4+PiAwO1xuICAgICAgICByZXR1cm4gLShsbyArIGhpICogNDI5NDk2NzI5Nik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmxvICsgdGhpcy5oaSAqIDQyOTQ5NjcyOTY7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIHRoaXMgbG9uZyBiaXRzIHRvIGEgbG9uZy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Vuc2lnbmVkPWZhbHNlXSBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdFxuICogQHJldHVybnMge0xvbmd9IExvbmdcbiAqL1xuTG9uZ0JpdHMucHJvdG90eXBlLnRvTG9uZyA9IGZ1bmN0aW9uIHRvTG9uZyh1bnNpZ25lZCkge1xuICAgIHJldHVybiB1dGlsLkxvbmdcbiAgICAgICAgPyBuZXcgdXRpbC5Mb25nKHRoaXMubG8gfCAwLCB0aGlzLmhpIHwgMCwgQm9vbGVhbih1bnNpZ25lZCkpXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIDogeyBsb3c6IHRoaXMubG8gfCAwLCBoaWdoOiB0aGlzLmhpIHwgMCwgdW5zaWduZWQ6IEJvb2xlYW4odW5zaWduZWQpIH07XG59O1xuXG52YXIgY2hhckNvZGVBdCA9IFN0cmluZy5wcm90b3R5cGUuY2hhckNvZGVBdDtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIG5ldyBsb25nIGJpdHMgZnJvbSB0aGUgc3BlY2lmaWVkIDggY2hhcmFjdGVycyBsb25nIGhhc2guXG4gKiBAcGFyYW0ge3N0cmluZ30gaGFzaCBIYXNoXG4gKiBAcmV0dXJucyB7dXRpbC5Mb25nQml0c30gQml0c1xuICovXG5Mb25nQml0cy5mcm9tSGFzaCA9IGZ1bmN0aW9uIGZyb21IYXNoKGhhc2gpIHtcbiAgICBpZiAoaGFzaCA9PT0gemVyb0hhc2gpXG4gICAgICAgIHJldHVybiB6ZXJvO1xuICAgIHJldHVybiBuZXcgTG9uZ0JpdHMoXG4gICAgICAgICggY2hhckNvZGVBdC5jYWxsKGhhc2gsIDApXG4gICAgICAgIHwgY2hhckNvZGVBdC5jYWxsKGhhc2gsIDEpIDw8IDhcbiAgICAgICAgfCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgMikgPDwgMTZcbiAgICAgICAgfCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgMykgPDwgMjQpID4+PiAwXG4gICAgLFxuICAgICAgICAoIGNoYXJDb2RlQXQuY2FsbChoYXNoLCA0KVxuICAgICAgICB8IGNoYXJDb2RlQXQuY2FsbChoYXNoLCA1KSA8PCA4XG4gICAgICAgIHwgY2hhckNvZGVBdC5jYWxsKGhhc2gsIDYpIDw8IDE2XG4gICAgICAgIHwgY2hhckNvZGVBdC5jYWxsKGhhc2gsIDcpIDw8IDI0KSA+Pj4gMFxuICAgICk7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIHRoaXMgbG9uZyBiaXRzIHRvIGEgOCBjaGFyYWN0ZXJzIGxvbmcgaGFzaC5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IEhhc2hcbiAqL1xuTG9uZ0JpdHMucHJvdG90eXBlLnRvSGFzaCA9IGZ1bmN0aW9uIHRvSGFzaCgpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShcbiAgICAgICAgdGhpcy5sbyAgICAgICAgJiAyNTUsXG4gICAgICAgIHRoaXMubG8gPj4+IDggICYgMjU1LFxuICAgICAgICB0aGlzLmxvID4+PiAxNiAmIDI1NSxcbiAgICAgICAgdGhpcy5sbyA+Pj4gMjQgICAgICAsXG4gICAgICAgIHRoaXMuaGkgICAgICAgICYgMjU1LFxuICAgICAgICB0aGlzLmhpID4+PiA4ICAmIDI1NSxcbiAgICAgICAgdGhpcy5oaSA+Pj4gMTYgJiAyNTUsXG4gICAgICAgIHRoaXMuaGkgPj4+IDI0XG4gICAgKTtcbn07XG5cbi8qKlxuICogWmlnLXphZyBlbmNvZGVzIHRoaXMgbG9uZyBiaXRzLlxuICogQHJldHVybnMge3V0aWwuTG9uZ0JpdHN9IGB0aGlzYFxuICovXG5Mb25nQml0cy5wcm90b3R5cGUuenpFbmNvZGUgPSBmdW5jdGlvbiB6ekVuY29kZSgpIHtcbiAgICB2YXIgbWFzayA9ICAgdGhpcy5oaSA+PiAzMTtcbiAgICB0aGlzLmhpICA9ICgodGhpcy5oaSA8PCAxIHwgdGhpcy5sbyA+Pj4gMzEpIF4gbWFzaykgPj4+IDA7XG4gICAgdGhpcy5sbyAgPSAoIHRoaXMubG8gPDwgMSAgICAgICAgICAgICAgICAgICBeIG1hc2spID4+PiAwO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBaaWctemFnIGRlY29kZXMgdGhpcyBsb25nIGJpdHMuXG4gKiBAcmV0dXJucyB7dXRpbC5Mb25nQml0c30gYHRoaXNgXG4gKi9cbkxvbmdCaXRzLnByb3RvdHlwZS56ekRlY29kZSA9IGZ1bmN0aW9uIHp6RGVjb2RlKCkge1xuICAgIHZhciBtYXNrID0gLSh0aGlzLmxvICYgMSk7XG4gICAgdGhpcy5sbyAgPSAoKHRoaXMubG8gPj4+IDEgfCB0aGlzLmhpIDw8IDMxKSBeIG1hc2spID4+PiAwO1xuICAgIHRoaXMuaGkgID0gKCB0aGlzLmhpID4+PiAxICAgICAgICAgICAgICAgICAgXiBtYXNrKSA+Pj4gMDtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgbGVuZ3RoIG9mIHRoaXMgbG9uZ2JpdHMgd2hlbiBlbmNvZGVkIGFzIGEgdmFyaW50LlxuICogQHJldHVybnMge251bWJlcn0gTGVuZ3RoXG4gKi9cbkxvbmdCaXRzLnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbiBsZW5ndGgoKSB7XG4gICAgdmFyIHBhcnQwID0gIHRoaXMubG8sXG4gICAgICAgIHBhcnQxID0gKHRoaXMubG8gPj4+IDI4IHwgdGhpcy5oaSA8PCA0KSA+Pj4gMCxcbiAgICAgICAgcGFydDIgPSAgdGhpcy5oaSA+Pj4gMjQ7XG4gICAgcmV0dXJuIHBhcnQyID09PSAwXG4gICAgICAgICA/IHBhcnQxID09PSAwXG4gICAgICAgICAgID8gcGFydDAgPCAxNjM4NFxuICAgICAgICAgICAgID8gcGFydDAgPCAxMjggPyAxIDogMlxuICAgICAgICAgICAgIDogcGFydDAgPCAyMDk3MTUyID8gMyA6IDRcbiAgICAgICAgICAgOiBwYXJ0MSA8IDE2Mzg0XG4gICAgICAgICAgICAgPyBwYXJ0MSA8IDEyOCA/IDUgOiA2XG4gICAgICAgICAgICAgOiBwYXJ0MSA8IDIwOTcxNTIgPyA3IDogOFxuICAgICAgICAgOiBwYXJ0MiA8IDEyOCA/IDkgOiAxMDtcbn07XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgdXRpbCA9IGV4cG9ydHM7XG5cbi8vIHVzZWQgdG8gcmV0dXJuIGEgUHJvbWlzZSB3aGVyZSBjYWxsYmFjayBpcyBvbWl0dGVkXG51dGlsLmFzUHJvbWlzZSA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy9hc3Byb21pc2VcIik7XG5cbi8vIGNvbnZlcnRzIHRvIC8gZnJvbSBiYXNlNjQgZW5jb2RlZCBzdHJpbmdzXG51dGlsLmJhc2U2NCA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy9iYXNlNjRcIik7XG5cbi8vIGJhc2UgY2xhc3Mgb2YgcnBjLlNlcnZpY2VcbnV0aWwuRXZlbnRFbWl0dGVyID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL2V2ZW50ZW1pdHRlclwiKTtcblxuLy8gZmxvYXQgaGFuZGxpbmcgYWNjcm9zcyBicm93c2Vyc1xudXRpbC5mbG9hdCA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy9mbG9hdFwiKTtcblxuLy8gcmVxdWlyZXMgbW9kdWxlcyBvcHRpb25hbGx5IGFuZCBoaWRlcyB0aGUgY2FsbCBmcm9tIGJ1bmRsZXJzXG51dGlsLmlucXVpcmUgPSByZXF1aXJlKFwiQHByb3RvYnVmanMvaW5xdWlyZVwiKTtcblxuLy8gY29udmVydHMgdG8gLyBmcm9tIHV0ZjggZW5jb2RlZCBzdHJpbmdzXG51dGlsLnV0ZjggPSByZXF1aXJlKFwiQHByb3RvYnVmanMvdXRmOFwiKTtcblxuLy8gcHJvdmlkZXMgYSBub2RlLWxpa2UgYnVmZmVyIHBvb2wgaW4gdGhlIGJyb3dzZXJcbnV0aWwucG9vbCA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy9wb29sXCIpO1xuXG4vLyB1dGlsaXR5IHRvIHdvcmsgd2l0aCB0aGUgbG93IGFuZCBoaWdoIGJpdHMgb2YgYSA2NCBiaXQgdmFsdWVcbnV0aWwuTG9uZ0JpdHMgPSByZXF1aXJlKFwiLi9sb25nYml0c1wiKTtcblxuLyoqXG4gKiBXaGV0aGVyIHJ1bm5pbmcgd2l0aGluIG5vZGUgb3Igbm90LlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEB0eXBlIHtib29sZWFufVxuICovXG51dGlsLmlzTm9kZSA9IEJvb2xlYW4odHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIlxuICAgICAgICAgICAgICAgICAgICYmIGdsb2JhbFxuICAgICAgICAgICAgICAgICAgICYmIGdsb2JhbC5wcm9jZXNzXG4gICAgICAgICAgICAgICAgICAgJiYgZ2xvYmFsLnByb2Nlc3MudmVyc2lvbnNcbiAgICAgICAgICAgICAgICAgICAmJiBnbG9iYWwucHJvY2Vzcy52ZXJzaW9ucy5ub2RlKTtcblxuLyoqXG4gKiBHbG9iYWwgb2JqZWN0IHJlZmVyZW5jZS5cbiAqIEBtZW1iZXJvZiB1dGlsXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG51dGlsLmdsb2JhbCA9IHV0aWwuaXNOb2RlICYmIGdsb2JhbFxuICAgICAgICAgICB8fCB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIHdpbmRvd1xuICAgICAgICAgICB8fCB0eXBlb2Ygc2VsZiAgICE9PSBcInVuZGVmaW5lZFwiICYmIHNlbGZcbiAgICAgICAgICAgfHwgdGhpczsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1pbnZhbGlkLXRoaXNcblxuLyoqXG4gKiBBbiBpbW11YWJsZSBlbXB0eSBhcnJheS5cbiAqIEBtZW1iZXJvZiB1dGlsXG4gKiBAdHlwZSB7QXJyYXkuPCo+fVxuICogQGNvbnN0XG4gKi9cbnV0aWwuZW1wdHlBcnJheSA9IE9iamVjdC5mcmVlemUgPyBPYmplY3QuZnJlZXplKFtdKSA6IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIFtdOyAvLyB1c2VkIG9uIHByb3RvdHlwZXNcblxuLyoqXG4gKiBBbiBpbW11dGFibGUgZW1wdHkgb2JqZWN0LlxuICogQHR5cGUge09iamVjdH1cbiAqIEBjb25zdFxuICovXG51dGlsLmVtcHR5T2JqZWN0ID0gT2JqZWN0LmZyZWV6ZSA/IE9iamVjdC5mcmVlemUoe30pIDogLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8ge307IC8vIHVzZWQgb24gcHJvdG90eXBlc1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYW4gaW50ZWdlci5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHsqfSB2YWx1ZSBWYWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSB2YWx1ZSBpcyBhbiBpbnRlZ2VyXG4gKi9cbnV0aWwuaXNJbnRlZ2VyID0gTnVtYmVyLmlzSW50ZWdlciB8fCAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyBmdW5jdGlvbiBpc0ludGVnZXIodmFsdWUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiICYmIGlzRmluaXRlKHZhbHVlKSAmJiBNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWU7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYSBzdHJpbmcuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIHZhbHVlIGlzIGEgc3RyaW5nXG4gKi9cbnV0aWwuaXNTdHJpbmcgPSBmdW5jdGlvbiBpc1N0cmluZyh2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgfHwgdmFsdWUgaW5zdGFuY2VvZiBTdHJpbmc7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYSBub24tbnVsbCBvYmplY3QuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIHZhbHVlIGlzIGEgbm9uLW51bGwgb2JqZWN0XG4gKi9cbnV0aWwuaXNPYmplY3QgPSBmdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCI7XG59O1xuXG4vKipcbiAqIENoZWNrcyBpZiBhIHByb3BlcnR5IG9uIGEgbWVzc2FnZSBpcyBjb25zaWRlcmVkIHRvIGJlIHByZXNlbnQuXG4gKiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayB1dGlsLmlzU2V0fS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBQbGFpbiBvYmplY3Qgb3IgbWVzc2FnZSBpbnN0YW5jZVxuICogQHBhcmFtIHtzdHJpbmd9IHByb3AgUHJvcGVydHkgbmFtZVxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiBjb25zaWRlcmVkIHRvIGJlIHByZXNlbnQsIG90aGVyd2lzZSBgZmFsc2VgXG4gKi9cbnV0aWwuaXNzZXQgPVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHByb3BlcnR5IG9uIGEgbWVzc2FnZSBpcyBjb25zaWRlcmVkIHRvIGJlIHByZXNlbnQuXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFBsYWluIG9iamVjdCBvciBtZXNzYWdlIGluc3RhbmNlXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvcCBQcm9wZXJ0eSBuYW1lXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIGNvbnNpZGVyZWQgdG8gYmUgcHJlc2VudCwgb3RoZXJ3aXNlIGBmYWxzZWBcbiAqL1xudXRpbC5pc1NldCA9IGZ1bmN0aW9uIGlzU2V0KG9iaiwgcHJvcCkge1xuICAgIHZhciB2YWx1ZSA9IG9ialtwcm9wXTtcbiAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiBvYmouaGFzT3duUHJvcGVydHkocHJvcCkpIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxLCBuby1wcm90b3R5cGUtYnVpbHRpbnNcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiB8fCAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZS5sZW5ndGggOiBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoKSA+IDA7XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuLyoqXG4gKiBBbnkgY29tcGF0aWJsZSBCdWZmZXIgaW5zdGFuY2UuXG4gKiBUaGlzIGlzIGEgbWluaW1hbCBzdGFuZC1hbG9uZSBkZWZpbml0aW9uIG9mIGEgQnVmZmVyIGluc3RhbmNlLiBUaGUgYWN0dWFsIHR5cGUgaXMgdGhhdCBleHBvcnRlZCBieSBub2RlJ3MgdHlwaW5ncy5cbiAqIEBpbnRlcmZhY2UgQnVmZmVyXG4gKiBAZXh0ZW5kcyBVaW50OEFycmF5XG4gKi9cblxuLyoqXG4gKiBOb2RlJ3MgQnVmZmVyIGNsYXNzIGlmIGF2YWlsYWJsZS5cbiAqIEB0eXBlIHtDb25zdHJ1Y3RvcjxCdWZmZXI+fVxuICovXG51dGlsLkJ1ZmZlciA9IChmdW5jdGlvbigpIHtcbiAgICB0cnkge1xuICAgICAgICB2YXIgQnVmZmVyID0gdXRpbC5pbnF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcjtcbiAgICAgICAgLy8gcmVmdXNlIHRvIHVzZSBub24tbm9kZSBidWZmZXJzIGlmIG5vdCBleHBsaWNpdGx5IGFzc2lnbmVkIChwZXJmIHJlYXNvbnMpOlxuICAgICAgICByZXR1cm4gQnVmZmVyLnByb3RvdHlwZS51dGY4V3JpdGUgPyBCdWZmZXIgOiAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyBudWxsO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxufSkoKTtcblxuLy8gSW50ZXJuYWwgYWxpYXMgb2Ygb3IgcG9seWZ1bGwgZm9yIEJ1ZmZlci5mcm9tLlxudXRpbC5fQnVmZmVyX2Zyb20gPSBudWxsO1xuXG4vLyBJbnRlcm5hbCBhbGlhcyBvZiBvciBwb2x5ZmlsbCBmb3IgQnVmZmVyLmFsbG9jVW5zYWZlLlxudXRpbC5fQnVmZmVyX2FsbG9jVW5zYWZlID0gbnVsbDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGJ1ZmZlciBvZiB3aGF0ZXZlciB0eXBlIHN1cHBvcnRlZCBieSB0aGUgZW52aXJvbm1lbnQuXG4gKiBAcGFyYW0ge251bWJlcnxudW1iZXJbXX0gW3NpemVPckFycmF5PTBdIEJ1ZmZlciBzaXplIG9yIG51bWJlciBhcnJheVxuICogQHJldHVybnMge1VpbnQ4QXJyYXl8QnVmZmVyfSBCdWZmZXJcbiAqL1xudXRpbC5uZXdCdWZmZXIgPSBmdW5jdGlvbiBuZXdCdWZmZXIoc2l6ZU9yQXJyYXkpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIHJldHVybiB0eXBlb2Ygc2l6ZU9yQXJyYXkgPT09IFwibnVtYmVyXCJcbiAgICAgICAgPyB1dGlsLkJ1ZmZlclxuICAgICAgICAgICAgPyB1dGlsLl9CdWZmZXJfYWxsb2NVbnNhZmUoc2l6ZU9yQXJyYXkpXG4gICAgICAgICAgICA6IG5ldyB1dGlsLkFycmF5KHNpemVPckFycmF5KVxuICAgICAgICA6IHV0aWwuQnVmZmVyXG4gICAgICAgICAgICA/IHV0aWwuX0J1ZmZlcl9mcm9tKHNpemVPckFycmF5KVxuICAgICAgICAgICAgOiB0eXBlb2YgVWludDhBcnJheSA9PT0gXCJ1bmRlZmluZWRcIlxuICAgICAgICAgICAgICAgID8gc2l6ZU9yQXJyYXlcbiAgICAgICAgICAgICAgICA6IG5ldyBVaW50OEFycmF5KHNpemVPckFycmF5KTtcbn07XG5cbi8qKlxuICogQXJyYXkgaW1wbGVtZW50YXRpb24gdXNlZCBpbiB0aGUgYnJvd3Nlci4gYFVpbnQ4QXJyYXlgIGlmIHN1cHBvcnRlZCwgb3RoZXJ3aXNlIGBBcnJheWAuXG4gKiBAdHlwZSB7Q29uc3RydWN0b3I8VWludDhBcnJheT59XG4gKi9cbnV0aWwuQXJyYXkgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gXCJ1bmRlZmluZWRcIiA/IFVpbnQ4QXJyYXkgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gOiBBcnJheTtcblxuLyoqXG4gKiBBbnkgY29tcGF0aWJsZSBMb25nIGluc3RhbmNlLlxuICogVGhpcyBpcyBhIG1pbmltYWwgc3RhbmQtYWxvbmUgZGVmaW5pdGlvbiBvZiBhIExvbmcgaW5zdGFuY2UuIFRoZSBhY3R1YWwgdHlwZSBpcyB0aGF0IGV4cG9ydGVkIGJ5IGxvbmcuanMuXG4gKiBAaW50ZXJmYWNlIExvbmdcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb3cgTG93IGJpdHNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBoaWdoIEhpZ2ggYml0c1xuICogQHByb3BlcnR5IHtib29sZWFufSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdFxuICovXG5cbi8qKlxuICogTG9uZy5qcydzIExvbmcgY2xhc3MgaWYgYXZhaWxhYmxlLlxuICogQHR5cGUge0NvbnN0cnVjdG9yPExvbmc+fVxuICovXG51dGlsLkxvbmcgPSAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyB1dGlsLmdsb2JhbC5kY29kZUlPICYmIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIHV0aWwuZ2xvYmFsLmRjb2RlSU8uTG9uZ1xuICAgICAgICAgfHwgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gdXRpbC5nbG9iYWwuTG9uZ1xuICAgICAgICAgfHwgdXRpbC5pbnF1aXJlKFwibG9uZ1wiKTtcblxuLyoqXG4gKiBSZWd1bGFyIGV4cHJlc3Npb24gdXNlZCB0byB2ZXJpZnkgMiBiaXQgKGBib29sYCkgbWFwIGtleXMuXG4gKiBAdHlwZSB7UmVnRXhwfVxuICogQGNvbnN0XG4gKi9cbnV0aWwua2V5MlJlID0gL150cnVlfGZhbHNlfDB8MSQvO1xuXG4vKipcbiAqIFJlZ3VsYXIgZXhwcmVzc2lvbiB1c2VkIHRvIHZlcmlmeSAzMiBiaXQgKGBpbnQzMmAgZXRjLikgbWFwIGtleXMuXG4gKiBAdHlwZSB7UmVnRXhwfVxuICogQGNvbnN0XG4gKi9cbnV0aWwua2V5MzJSZSA9IC9eLT8oPzowfFsxLTldWzAtOV0qKSQvO1xuXG4vKipcbiAqIFJlZ3VsYXIgZXhwcmVzc2lvbiB1c2VkIHRvIHZlcmlmeSA2NCBiaXQgKGBpbnQ2NGAgZXRjLikgbWFwIGtleXMuXG4gKiBAdHlwZSB7UmVnRXhwfVxuICogQGNvbnN0XG4gKi9cbnV0aWwua2V5NjRSZSA9IC9eKD86W1xcXFx4MDAtXFxcXHhmZl17OH18LT8oPzowfFsxLTldWzAtOV0qKSkkLztcblxuLyoqXG4gKiBDb252ZXJ0cyBhIG51bWJlciBvciBsb25nIHRvIGFuIDggY2hhcmFjdGVycyBsb25nIGhhc2ggc3RyaW5nLlxuICogQHBhcmFtIHtMb25nfG51bWJlcn0gdmFsdWUgVmFsdWUgdG8gY29udmVydFxuICogQHJldHVybnMge3N0cmluZ30gSGFzaFxuICovXG51dGlsLmxvbmdUb0hhc2ggPSBmdW5jdGlvbiBsb25nVG9IYXNoKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlXG4gICAgICAgID8gdXRpbC5Mb25nQml0cy5mcm9tKHZhbHVlKS50b0hhc2goKVxuICAgICAgICA6IHV0aWwuTG9uZ0JpdHMuemVyb0hhc2g7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIGFuIDggY2hhcmFjdGVycyBsb25nIGhhc2ggc3RyaW5nIHRvIGEgbG9uZyBvciBudW1iZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gaGFzaCBIYXNoXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFt1bnNpZ25lZD1mYWxzZV0gV2hldGhlciB1bnNpZ25lZCBvciBub3RcbiAqIEByZXR1cm5zIHtMb25nfG51bWJlcn0gT3JpZ2luYWwgdmFsdWVcbiAqL1xudXRpbC5sb25nRnJvbUhhc2ggPSBmdW5jdGlvbiBsb25nRnJvbUhhc2goaGFzaCwgdW5zaWduZWQpIHtcbiAgICB2YXIgYml0cyA9IHV0aWwuTG9uZ0JpdHMuZnJvbUhhc2goaGFzaCk7XG4gICAgaWYgKHV0aWwuTG9uZylcbiAgICAgICAgcmV0dXJuIHV0aWwuTG9uZy5mcm9tQml0cyhiaXRzLmxvLCBiaXRzLmhpLCB1bnNpZ25lZCk7XG4gICAgcmV0dXJuIGJpdHMudG9OdW1iZXIoQm9vbGVhbih1bnNpZ25lZCkpO1xufTtcblxuLyoqXG4gKiBNZXJnZXMgdGhlIHByb3BlcnRpZXMgb2YgdGhlIHNvdXJjZSBvYmplY3QgaW50byB0aGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IGRzdCBEZXN0aW5hdGlvbiBvYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IHNyYyBTb3VyY2Ugb2JqZWN0XG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpZk5vdFNldD1mYWxzZV0gTWVyZ2VzIG9ubHkgaWYgdGhlIGtleSBpcyBub3QgYWxyZWFkeSBzZXRcbiAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gRGVzdGluYXRpb24gb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIG1lcmdlKGRzdCwgc3JjLCBpZk5vdFNldCkgeyAvLyB1c2VkIGJ5IGNvbnZlcnRlcnNcbiAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMoc3JjKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICBpZiAoZHN0W2tleXNbaV1dID09PSB1bmRlZmluZWQgfHwgIWlmTm90U2V0KVxuICAgICAgICAgICAgZHN0W2tleXNbaV1dID0gc3JjW2tleXNbaV1dO1xuICAgIHJldHVybiBkc3Q7XG59XG5cbnV0aWwubWVyZ2UgPSBtZXJnZTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIGEgc3RyaW5nIHRvIGxvd2VyIGNhc2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byBjb252ZXJ0XG4gKiBAcmV0dXJucyB7c3RyaW5nfSBDb252ZXJ0ZWQgc3RyaW5nXG4gKi9cbnV0aWwubGNGaXJzdCA9IGZ1bmN0aW9uIGxjRmlyc3Qoc3RyKSB7XG4gICAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIHN0ci5zdWJzdHJpbmcoMSk7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjdXN0b20gZXJyb3IgY29uc3RydWN0b3IuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgRXJyb3IgbmFtZVxuICogQHJldHVybnMge0NvbnN0cnVjdG9yPEVycm9yPn0gQ3VzdG9tIGVycm9yIGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIG5ld0Vycm9yKG5hbWUpIHtcblxuICAgIGZ1bmN0aW9uIEN1c3RvbUVycm9yKG1lc3NhZ2UsIHByb3BlcnRpZXMpIHtcblxuICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ3VzdG9tRXJyb3IpKVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBDdXN0b21FcnJvcihtZXNzYWdlLCBwcm9wZXJ0aWVzKTtcblxuICAgICAgICAvLyBFcnJvci5jYWxsKHRoaXMsIG1lc3NhZ2UpO1xuICAgICAgICAvLyBeIGp1c3QgcmV0dXJucyBhIG5ldyBlcnJvciBpbnN0YW5jZSBiZWNhdXNlIHRoZSBjdG9yIGNhbiBiZSBjYWxsZWQgYXMgYSBmdW5jdGlvblxuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcIm1lc3NhZ2VcIiwgeyBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbWVzc2FnZTsgfSB9KTtcblxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIC8vIG5vZGVcbiAgICAgICAgICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIEN1c3RvbUVycm9yKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIFwic3RhY2tcIiwgeyB2YWx1ZTogbmV3IEVycm9yKCkuc3RhY2sgfHwgXCJcIiB9KTtcblxuICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgIG1lcmdlKHRoaXMsIHByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIEN1c3RvbUVycm9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgICB2YWx1ZTogQ3VzdG9tRXJyb3IsXG4gICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBuYW1lOiB7XG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHsgcmV0dXJuIG5hbWU7IH0sXG4gICAgICAgICAgICBzZXQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgLy8gY29uZmlndXJhYmxlOiBmYWxzZSB3b3VsZCBhY2N1cmF0ZWx5IHByZXNlcnZlIHRoZSBiZWhhdmlvciBvZlxuICAgICAgICAgICAgLy8gdGhlIG9yaWdpbmFsLCBidXQgSSdtIGd1ZXNzaW5nIHRoYXQgd2FzIG5vdCBpbnRlbnRpb25hbC5cbiAgICAgICAgICAgIC8vIEZvciBhbiBhY3R1YWwgZXJyb3Igc3ViY2xhc3MsIHRoaXMgcHJvcGVydHkgd291bGRcbiAgICAgICAgICAgIC8vIGJlIGNvbmZpZ3VyYWJsZS5cbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgdG9TdHJpbmc6IHtcbiAgICAgICAgICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZSgpIHsgcmV0dXJuIHRoaXMubmFtZSArIFwiOiBcIiArIHRoaXMubWVzc2FnZTsgfSxcbiAgICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIH0sXG4gICAgfSk7XG5cbiAgICByZXR1cm4gQ3VzdG9tRXJyb3I7XG59XG5cbnV0aWwubmV3RXJyb3IgPSBuZXdFcnJvcjtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IHByb3RvY29sIGVycm9yLlxuICogQGNsYXNzZGVzYyBFcnJvciBzdWJjbGFzcyBpbmRpY2F0aW5nIGEgcHJvdG9jb2wgc3BlY2lmYyBlcnJvci5cbiAqIEBtZW1iZXJvZiB1dGlsXG4gKiBAZXh0ZW5kcyBFcnJvclxuICogQHRlbXBsYXRlIFQgZXh0ZW5kcyBNZXNzYWdlPFQ+XG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIEVycm9yIG1lc3NhZ2VcbiAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IFtwcm9wZXJ0aWVzXSBBZGRpdGlvbmFsIHByb3BlcnRpZXNcbiAqIEBleGFtcGxlXG4gKiB0cnkge1xuICogICAgIE15TWVzc2FnZS5kZWNvZGUoc29tZUJ1ZmZlcik7IC8vIHRocm93cyBpZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAqIH0gY2F0Y2ggKGUpIHtcbiAqICAgICBpZiAoZSBpbnN0YW5jZW9mIFByb3RvY29sRXJyb3IgJiYgZS5pbnN0YW5jZSlcbiAqICAgICAgICAgY29uc29sZS5sb2coXCJkZWNvZGVkIHNvIGZhcjogXCIgKyBKU09OLnN0cmluZ2lmeShlLmluc3RhbmNlKSk7XG4gKiB9XG4gKi9cbnV0aWwuUHJvdG9jb2xFcnJvciA9IG5ld0Vycm9yKFwiUHJvdG9jb2xFcnJvclwiKTtcblxuLyoqXG4gKiBTbyBmYXIgZGVjb2RlZCBtZXNzYWdlIGluc3RhbmNlLlxuICogQG5hbWUgdXRpbC5Qcm90b2NvbEVycm9yI2luc3RhbmNlXG4gKiBAdHlwZSB7TWVzc2FnZTxUPn1cbiAqL1xuXG4vKipcbiAqIEEgT25lT2YgZ2V0dGVyIGFzIHJldHVybmVkIGJ5IHtAbGluayB1dGlsLm9uZU9mR2V0dGVyfS5cbiAqIEB0eXBlZGVmIE9uZU9mR2V0dGVyXG4gKiBAdHlwZSB7ZnVuY3Rpb259XG4gKiBAcmV0dXJucyB7c3RyaW5nfHVuZGVmaW5lZH0gU2V0IGZpZWxkIG5hbWUsIGlmIGFueVxuICovXG5cbi8qKlxuICogQnVpbGRzIGEgZ2V0dGVyIGZvciBhIG9uZW9mJ3MgcHJlc2VudCBmaWVsZCBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmdbXX0gZmllbGROYW1lcyBGaWVsZCBuYW1lc1xuICogQHJldHVybnMge09uZU9mR2V0dGVyfSBVbmJvdW5kIGdldHRlclxuICovXG51dGlsLm9uZU9mR2V0dGVyID0gZnVuY3Rpb24gZ2V0T25lT2YoZmllbGROYW1lcykge1xuICAgIHZhciBmaWVsZE1hcCA9IHt9O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZmllbGROYW1lcy5sZW5ndGg7ICsraSlcbiAgICAgICAgZmllbGRNYXBbZmllbGROYW1lc1tpXV0gPSAxO1xuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMge3N0cmluZ3x1bmRlZmluZWR9IFNldCBmaWVsZCBuYW1lLCBpZiBhbnlcbiAgICAgKiBAdGhpcyBPYmplY3RcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGNvbnNpc3RlbnQtcmV0dXJuXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyh0aGlzKSwgaSA9IGtleXMubGVuZ3RoIC0gMTsgaSA+IC0xOyAtLWkpXG4gICAgICAgICAgICBpZiAoZmllbGRNYXBba2V5c1tpXV0gPT09IDEgJiYgdGhpc1trZXlzW2ldXSAhPT0gdW5kZWZpbmVkICYmIHRoaXNba2V5c1tpXV0gIT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGtleXNbaV07XG4gICAgfTtcbn07XG5cbi8qKlxuICogQSBPbmVPZiBzZXR0ZXIgYXMgcmV0dXJuZWQgYnkge0BsaW5rIHV0aWwub25lT2ZTZXR0ZXJ9LlxuICogQHR5cGVkZWYgT25lT2ZTZXR0ZXJcbiAqIEB0eXBlIHtmdW5jdGlvbn1cbiAqIEBwYXJhbSB7c3RyaW5nfHVuZGVmaW5lZH0gdmFsdWUgRmllbGQgbmFtZVxuICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAqL1xuXG4vKipcbiAqIEJ1aWxkcyBhIHNldHRlciBmb3IgYSBvbmVvZidzIHByZXNlbnQgZmllbGQgbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nW119IGZpZWxkTmFtZXMgRmllbGQgbmFtZXNcbiAqIEByZXR1cm5zIHtPbmVPZlNldHRlcn0gVW5ib3VuZCBzZXR0ZXJcbiAqL1xudXRpbC5vbmVPZlNldHRlciA9IGZ1bmN0aW9uIHNldE9uZU9mKGZpZWxkTmFtZXMpIHtcblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIEZpZWxkIG5hbWVcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICAgICAqIEB0aGlzIE9iamVjdFxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICByZXR1cm4gZnVuY3Rpb24obmFtZSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZpZWxkTmFtZXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBpZiAoZmllbGROYW1lc1tpXSAhPT0gbmFtZSlcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpc1tmaWVsZE5hbWVzW2ldXTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBEZWZhdWx0IGNvbnZlcnNpb24gb3B0aW9ucyB1c2VkIGZvciB7QGxpbmsgTWVzc2FnZSN0b0pTT059IGltcGxlbWVudGF0aW9ucy5cbiAqXG4gKiBUaGVzZSBvcHRpb25zIGFyZSBjbG9zZSB0byBwcm90bzMncyBKU09OIG1hcHBpbmcgd2l0aCB0aGUgZXhjZXB0aW9uIHRoYXQgaW50ZXJuYWwgdHlwZXMgbGlrZSBBbnkgYXJlIGhhbmRsZWQganVzdCBsaWtlIG1lc3NhZ2VzLiBNb3JlIHByZWNpc2VseTpcbiAqXG4gKiAtIExvbmdzIGJlY29tZSBzdHJpbmdzXG4gKiAtIEVudW1zIGJlY29tZSBzdHJpbmcga2V5c1xuICogLSBCeXRlcyBiZWNvbWUgYmFzZTY0IGVuY29kZWQgc3RyaW5nc1xuICogLSAoU3ViLSlNZXNzYWdlcyBiZWNvbWUgcGxhaW4gb2JqZWN0c1xuICogLSBNYXBzIGJlY29tZSBwbGFpbiBvYmplY3RzIHdpdGggYWxsIHN0cmluZyBrZXlzXG4gKiAtIFJlcGVhdGVkIGZpZWxkcyBiZWNvbWUgYXJyYXlzXG4gKiAtIE5hTiBhbmQgSW5maW5pdHkgZm9yIGZsb2F0IGFuZCBkb3VibGUgZmllbGRzIGJlY29tZSBzdHJpbmdzXG4gKlxuICogQHR5cGUge0lDb252ZXJzaW9uT3B0aW9uc31cbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy9kb2NzL3Byb3RvMz9obD1lbiNqc29uXG4gKi9cbnV0aWwudG9KU09OT3B0aW9ucyA9IHtcbiAgICBsb25nczogU3RyaW5nLFxuICAgIGVudW1zOiBTdHJpbmcsXG4gICAgYnl0ZXM6IFN0cmluZyxcbiAgICBqc29uOiB0cnVlXG59O1xuXG4vLyBTZXRzIHVwIGJ1ZmZlciB1dGlsaXR5IGFjY29yZGluZyB0byB0aGUgZW52aXJvbm1lbnQgKGNhbGxlZCBpbiBpbmRleC1taW5pbWFsKVxudXRpbC5fY29uZmlndXJlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIEJ1ZmZlciA9IHV0aWwuQnVmZmVyO1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICghQnVmZmVyKSB7XG4gICAgICAgIHV0aWwuX0J1ZmZlcl9mcm9tID0gdXRpbC5fQnVmZmVyX2FsbG9jVW5zYWZlID0gbnVsbDtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBiZWNhdXNlIG5vZGUgNC54IGJ1ZmZlcnMgYXJlIGluY29tcGF0aWJsZSAmIGltbXV0YWJsZVxuICAgIC8vIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Rjb2RlSU8vcHJvdG9idWYuanMvcHVsbC82NjVcbiAgICB1dGlsLl9CdWZmZXJfZnJvbSA9IEJ1ZmZlci5mcm9tICE9PSBVaW50OEFycmF5LmZyb20gJiYgQnVmZmVyLmZyb20gfHxcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgZnVuY3Rpb24gQnVmZmVyX2Zyb20odmFsdWUsIGVuY29kaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZSwgZW5jb2RpbmcpO1xuICAgICAgICB9O1xuICAgIHV0aWwuX0J1ZmZlcl9hbGxvY1Vuc2FmZSA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSB8fFxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBmdW5jdGlvbiBCdWZmZXJfYWxsb2NVbnNhZmUoc2l6ZSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXIoc2l6ZSk7XG4gICAgICAgIH07XG59O1xuIiwgIlwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBXcml0ZXI7XG5cbnZhciB1dGlsICAgICAgPSByZXF1aXJlKFwiLi91dGlsL21pbmltYWxcIik7XG5cbnZhciBCdWZmZXJXcml0ZXI7IC8vIGN5Y2xpY1xuXG52YXIgTG9uZ0JpdHMgID0gdXRpbC5Mb25nQml0cyxcbiAgICBiYXNlNjQgICAgPSB1dGlsLmJhc2U2NCxcbiAgICB1dGY4ICAgICAgPSB1dGlsLnV0Zjg7XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyB3cml0ZXIgb3BlcmF0aW9uIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBTY2hlZHVsZWQgd3JpdGVyIG9wZXJhdGlvbi5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtmdW5jdGlvbigqLCBVaW50OEFycmF5LCBudW1iZXIpfSBmbiBGdW5jdGlvbiB0byBjYWxsXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuIFZhbHVlIGJ5dGUgbGVuZ3RoXG4gKiBAcGFyYW0geyp9IHZhbCBWYWx1ZSB0byB3cml0ZVxuICogQGlnbm9yZVxuICovXG5mdW5jdGlvbiBPcChmbiwgbGVuLCB2YWwpIHtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHRvIGNhbGwuXG4gICAgICogQHR5cGUge2Z1bmN0aW9uKFVpbnQ4QXJyYXksIG51bWJlciwgKil9XG4gICAgICovXG4gICAgdGhpcy5mbiA9IGZuO1xuXG4gICAgLyoqXG4gICAgICogVmFsdWUgYnl0ZSBsZW5ndGguXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmxlbiA9IGxlbjtcblxuICAgIC8qKlxuICAgICAqIE5leHQgb3BlcmF0aW9uLlxuICAgICAqIEB0eXBlIHtXcml0ZXIuT3B8dW5kZWZpbmVkfVxuICAgICAqL1xuICAgIHRoaXMubmV4dCA9IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFZhbHVlIHRvIHdyaXRlLlxuICAgICAqIEB0eXBlIHsqfVxuICAgICAqL1xuICAgIHRoaXMudmFsID0gdmFsOyAvLyB0eXBlIHZhcmllc1xufVxuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZnVuY3Rpb24gbm9vcCgpIHt9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tZW1wdHktZnVuY3Rpb25cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IHdyaXRlciBzdGF0ZSBpbnN0YW5jZS5cbiAqIEBjbGFzc2Rlc2MgQ29waWVkIHdyaXRlciBzdGF0ZS5cbiAqIEBtZW1iZXJvZiBXcml0ZXJcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtXcml0ZXJ9IHdyaXRlciBXcml0ZXIgdG8gY29weSBzdGF0ZSBmcm9tXG4gKiBAaWdub3JlXG4gKi9cbmZ1bmN0aW9uIFN0YXRlKHdyaXRlcikge1xuXG4gICAgLyoqXG4gICAgICogQ3VycmVudCBoZWFkLlxuICAgICAqIEB0eXBlIHtXcml0ZXIuT3B9XG4gICAgICovXG4gICAgdGhpcy5oZWFkID0gd3JpdGVyLmhlYWQ7XG5cbiAgICAvKipcbiAgICAgKiBDdXJyZW50IHRhaWwuXG4gICAgICogQHR5cGUge1dyaXRlci5PcH1cbiAgICAgKi9cbiAgICB0aGlzLnRhaWwgPSB3cml0ZXIudGFpbDtcblxuICAgIC8qKlxuICAgICAqIEN1cnJlbnQgYnVmZmVyIGxlbmd0aC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMubGVuID0gd3JpdGVyLmxlbjtcblxuICAgIC8qKlxuICAgICAqIE5leHQgc3RhdGUuXG4gICAgICogQHR5cGUge1N0YXRlfG51bGx9XG4gICAgICovXG4gICAgdGhpcy5uZXh0ID0gd3JpdGVyLnN0YXRlcztcbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IHdyaXRlciBpbnN0YW5jZS5cbiAqIEBjbGFzc2Rlc2MgV2lyZSBmb3JtYXQgd3JpdGVyIHVzaW5nIGBVaW50OEFycmF5YCBpZiBhdmFpbGFibGUsIG90aGVyd2lzZSBgQXJyYXlgLlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIFdyaXRlcigpIHtcblxuICAgIC8qKlxuICAgICAqIEN1cnJlbnQgbGVuZ3RoLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5sZW4gPSAwO1xuXG4gICAgLyoqXG4gICAgICogT3BlcmF0aW9ucyBoZWFkLlxuICAgICAqIEB0eXBlIHtPYmplY3R9XG4gICAgICovXG4gICAgdGhpcy5oZWFkID0gbmV3IE9wKG5vb3AsIDAsIDApO1xuXG4gICAgLyoqXG4gICAgICogT3BlcmF0aW9ucyB0YWlsXG4gICAgICogQHR5cGUge09iamVjdH1cbiAgICAgKi9cbiAgICB0aGlzLnRhaWwgPSB0aGlzLmhlYWQ7XG5cbiAgICAvKipcbiAgICAgKiBMaW5rZWQgZm9ya2VkIHN0YXRlcy5cbiAgICAgKiBAdHlwZSB7T2JqZWN0fG51bGx9XG4gICAgICovXG4gICAgdGhpcy5zdGF0ZXMgPSBudWxsO1xuXG4gICAgLy8gV2hlbiBhIHZhbHVlIGlzIHdyaXR0ZW4sIHRoZSB3cml0ZXIgY2FsY3VsYXRlcyBpdHMgYnl0ZSBsZW5ndGggYW5kIHB1dHMgaXQgaW50byBhIGxpbmtlZFxuICAgIC8vIGxpc3Qgb2Ygb3BlcmF0aW9ucyB0byBwZXJmb3JtIHdoZW4gZmluaXNoKCkgaXMgY2FsbGVkLiBUaGlzIGJvdGggYWxsb3dzIHVzIHRvIGFsbG9jYXRlXG4gICAgLy8gYnVmZmVycyBvZiB0aGUgZXhhY3QgcmVxdWlyZWQgc2l6ZSBhbmQgcmVkdWNlcyB0aGUgYW1vdW50IG9mIHdvcmsgd2UgaGF2ZSB0byBkbyBjb21wYXJlZFxuICAgIC8vIHRvIGZpcnN0IGNhbGN1bGF0aW5nIG92ZXIgb2JqZWN0cyBhbmQgdGhlbiBlbmNvZGluZyBvdmVyIG9iamVjdHMuIEluIG91ciBjYXNlLCB0aGUgZW5jb2RpbmdcbiAgICAvLyBwYXJ0IGlzIGp1c3QgYSBsaW5rZWQgbGlzdCB3YWxrIGNhbGxpbmcgb3BlcmF0aW9ucyB3aXRoIGFscmVhZHkgcHJlcGFyZWQgdmFsdWVzLlxufVxuXG52YXIgY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgIHJldHVybiB1dGlsLkJ1ZmZlclxuICAgICAgICA/IGZ1bmN0aW9uIGNyZWF0ZV9idWZmZXJfc2V0dXAoKSB7XG4gICAgICAgICAgICByZXR1cm4gKFdyaXRlci5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGVfYnVmZmVyKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQnVmZmVyV3JpdGVyKCk7XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICB9XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIDogZnVuY3Rpb24gY3JlYXRlX2FycmF5KCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBXcml0ZXIoKTtcbiAgICAgICAgfTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyB3cml0ZXIuXG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtCdWZmZXJXcml0ZXJ8V3JpdGVyfSBBIHtAbGluayBCdWZmZXJXcml0ZXJ9IHdoZW4gQnVmZmVycyBhcmUgc3VwcG9ydGVkLCBvdGhlcndpc2UgYSB7QGxpbmsgV3JpdGVyfVxuICovXG5Xcml0ZXIuY3JlYXRlID0gY3JlYXRlKCk7XG5cbi8qKlxuICogQWxsb2NhdGVzIGEgYnVmZmVyIG9mIHRoZSBzcGVjaWZpZWQgc2l6ZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIEJ1ZmZlciBzaXplXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gQnVmZmVyXG4gKi9cbldyaXRlci5hbGxvYyA9IGZ1bmN0aW9uIGFsbG9jKHNpemUpIHtcbiAgICByZXR1cm4gbmV3IHV0aWwuQXJyYXkoc2l6ZSk7XG59O1xuXG4vLyBVc2UgVWludDhBcnJheSBidWZmZXIgcG9vbCBpbiB0aGUgYnJvd3NlciwganVzdCBsaWtlIG5vZGUgZG9lcyB3aXRoIGJ1ZmZlcnNcbi8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG5pZiAodXRpbC5BcnJheSAhPT0gQXJyYXkpXG4gICAgV3JpdGVyLmFsbG9jID0gdXRpbC5wb29sKFdyaXRlci5hbGxvYywgdXRpbC5BcnJheS5wcm90b3R5cGUuc3ViYXJyYXkpO1xuXG4vKipcbiAqIFB1c2hlcyBhIG5ldyBvcGVyYXRpb24gdG8gdGhlIHF1ZXVlLlxuICogQHBhcmFtIHtmdW5jdGlvbihVaW50OEFycmF5LCBudW1iZXIsICopfSBmbiBGdW5jdGlvbiB0byBjYWxsXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuIFZhbHVlIGJ5dGUgbGVuZ3RoXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEBwcml2YXRlXG4gKi9cbldyaXRlci5wcm90b3R5cGUuX3B1c2ggPSBmdW5jdGlvbiBwdXNoKGZuLCBsZW4sIHZhbCkge1xuICAgIHRoaXMudGFpbCA9IHRoaXMudGFpbC5uZXh0ID0gbmV3IE9wKGZuLCBsZW4sIHZhbCk7XG4gICAgdGhpcy5sZW4gKz0gbGVuO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gd3JpdGVCeXRlKHZhbCwgYnVmLCBwb3MpIHtcbiAgICBidWZbcG9zXSA9IHZhbCAmIDI1NTtcbn1cblxuZnVuY3Rpb24gd3JpdGVWYXJpbnQzMih2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgd2hpbGUgKHZhbCA+IDEyNykge1xuICAgICAgICBidWZbcG9zKytdID0gdmFsICYgMTI3IHwgMTI4O1xuICAgICAgICB2YWwgPj4+PSA3O1xuICAgIH1cbiAgICBidWZbcG9zXSA9IHZhbDtcbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IHZhcmludCB3cml0ZXIgb3BlcmF0aW9uIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBTY2hlZHVsZWQgdmFyaW50IHdyaXRlciBvcGVyYXRpb24uXG4gKiBAZXh0ZW5kcyBPcFxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuIFZhbHVlIGJ5dGUgbGVuZ3RoXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsIFZhbHVlIHRvIHdyaXRlXG4gKiBAaWdub3JlXG4gKi9cbmZ1bmN0aW9uIFZhcmludE9wKGxlbiwgdmFsKSB7XG4gICAgdGhpcy5sZW4gPSBsZW47XG4gICAgdGhpcy5uZXh0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMudmFsID0gdmFsO1xufVxuXG5WYXJpbnRPcC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKE9wLnByb3RvdHlwZSk7XG5WYXJpbnRPcC5wcm90b3R5cGUuZm4gPSB3cml0ZVZhcmludDMyO1xuXG4vKipcbiAqIFdyaXRlcyBhbiB1bnNpZ25lZCAzMiBiaXQgdmFsdWUgYXMgYSB2YXJpbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLnVpbnQzMiA9IGZ1bmN0aW9uIHdyaXRlX3VpbnQzMih2YWx1ZSkge1xuICAgIC8vIGhlcmUsIHRoZSBjYWxsIHRvIHRoaXMucHVzaCBoYXMgYmVlbiBpbmxpbmVkIGFuZCBhIHZhcmludCBzcGVjaWZpYyBPcCBzdWJjbGFzcyBpcyB1c2VkLlxuICAgIC8vIHVpbnQzMiBpcyBieSBmYXIgdGhlIG1vc3QgZnJlcXVlbnRseSB1c2VkIG9wZXJhdGlvbiBhbmQgYmVuZWZpdHMgc2lnbmlmaWNhbnRseSBmcm9tIHRoaXMuXG4gICAgdGhpcy5sZW4gKz0gKHRoaXMudGFpbCA9IHRoaXMudGFpbC5uZXh0ID0gbmV3IFZhcmludE9wKFxuICAgICAgICAodmFsdWUgPSB2YWx1ZSA+Pj4gMClcbiAgICAgICAgICAgICAgICA8IDEyOCAgICAgICA/IDFcbiAgICAgICAgOiB2YWx1ZSA8IDE2Mzg0ICAgICA/IDJcbiAgICAgICAgOiB2YWx1ZSA8IDIwOTcxNTIgICA/IDNcbiAgICAgICAgOiB2YWx1ZSA8IDI2ODQzNTQ1NiA/IDRcbiAgICAgICAgOiAgICAgICAgICAgICAgICAgICAgIDUsXG4gICAgdmFsdWUpKS5sZW47XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIHNpZ25lZCAzMiBiaXQgdmFsdWUgYXMgYSB2YXJpbnQuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuaW50MzIgPSBmdW5jdGlvbiB3cml0ZV9pbnQzMih2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSA8IDBcbiAgICAgICAgPyB0aGlzLl9wdXNoKHdyaXRlVmFyaW50NjQsIDEwLCBMb25nQml0cy5mcm9tTnVtYmVyKHZhbHVlKSkgLy8gMTAgYnl0ZXMgcGVyIHNwZWNcbiAgICAgICAgOiB0aGlzLnVpbnQzMih2YWx1ZSk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIDMyIGJpdCB2YWx1ZSBhcyBhIHZhcmludCwgemlnLXphZyBlbmNvZGVkLlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5zaW50MzIgPSBmdW5jdGlvbiB3cml0ZV9zaW50MzIodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy51aW50MzIoKHZhbHVlIDw8IDEgXiB2YWx1ZSA+PiAzMSkgPj4+IDApO1xufTtcblxuZnVuY3Rpb24gd3JpdGVWYXJpbnQ2NCh2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgd2hpbGUgKHZhbC5oaSkge1xuICAgICAgICBidWZbcG9zKytdID0gdmFsLmxvICYgMTI3IHwgMTI4O1xuICAgICAgICB2YWwubG8gPSAodmFsLmxvID4+PiA3IHwgdmFsLmhpIDw8IDI1KSA+Pj4gMDtcbiAgICAgICAgdmFsLmhpID4+Pj0gNztcbiAgICB9XG4gICAgd2hpbGUgKHZhbC5sbyA+IDEyNykge1xuICAgICAgICBidWZbcG9zKytdID0gdmFsLmxvICYgMTI3IHwgMTI4O1xuICAgICAgICB2YWwubG8gPSB2YWwubG8gPj4+IDc7XG4gICAgfVxuICAgIGJ1Zltwb3MrK10gPSB2YWwubG87XG59XG5cbi8qKlxuICogV3JpdGVzIGFuIHVuc2lnbmVkIDY0IGJpdCB2YWx1ZSBhcyBhIHZhcmludC5cbiAqIEBwYXJhbSB7TG9uZ3xudW1iZXJ8c3RyaW5nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGB2YWx1ZWAgaXMgYSBzdHJpbmcgYW5kIG5vIGxvbmcgbGlicmFyeSBpcyBwcmVzZW50LlxuICovXG5Xcml0ZXIucHJvdG90eXBlLnVpbnQ2NCA9IGZ1bmN0aW9uIHdyaXRlX3VpbnQ2NCh2YWx1ZSkge1xuICAgIHZhciBiaXRzID0gTG9uZ0JpdHMuZnJvbSh2YWx1ZSk7XG4gICAgcmV0dXJuIHRoaXMuX3B1c2god3JpdGVWYXJpbnQ2NCwgYml0cy5sZW5ndGgoKSwgYml0cyk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIHNpZ25lZCA2NCBiaXQgdmFsdWUgYXMgYSB2YXJpbnQuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7TG9uZ3xudW1iZXJ8c3RyaW5nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGB2YWx1ZWAgaXMgYSBzdHJpbmcgYW5kIG5vIGxvbmcgbGlicmFyeSBpcyBwcmVzZW50LlxuICovXG5Xcml0ZXIucHJvdG90eXBlLmludDY0ID0gV3JpdGVyLnByb3RvdHlwZS51aW50NjQ7XG5cbi8qKlxuICogV3JpdGVzIGEgc2lnbmVkIDY0IGJpdCB2YWx1ZSBhcyBhIHZhcmludCwgemlnLXphZyBlbmNvZGVkLlxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYHZhbHVlYCBpcyBhIHN0cmluZyBhbmQgbm8gbG9uZyBsaWJyYXJ5IGlzIHByZXNlbnQuXG4gKi9cbldyaXRlci5wcm90b3R5cGUuc2ludDY0ID0gZnVuY3Rpb24gd3JpdGVfc2ludDY0KHZhbHVlKSB7XG4gICAgdmFyIGJpdHMgPSBMb25nQml0cy5mcm9tKHZhbHVlKS56ekVuY29kZSgpO1xuICAgIHJldHVybiB0aGlzLl9wdXNoKHdyaXRlVmFyaW50NjQsIGJpdHMubGVuZ3RoKCksIGJpdHMpO1xufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBib29saXNoIHZhbHVlIGFzIGEgdmFyaW50LlxuICogQHBhcmFtIHtib29sZWFufSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuYm9vbCA9IGZ1bmN0aW9uIHdyaXRlX2Jvb2wodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZUJ5dGUsIDEsIHZhbHVlID8gMSA6IDApO1xufTtcblxuZnVuY3Rpb24gd3JpdGVGaXhlZDMyKHZhbCwgYnVmLCBwb3MpIHtcbiAgICBidWZbcG9zICAgIF0gPSAgdmFsICAgICAgICAgJiAyNTU7XG4gICAgYnVmW3BvcyArIDFdID0gIHZhbCA+Pj4gOCAgICYgMjU1O1xuICAgIGJ1Zltwb3MgKyAyXSA9ICB2YWwgPj4+IDE2ICAmIDI1NTtcbiAgICBidWZbcG9zICsgM10gPSAgdmFsID4+PiAyNDtcbn1cblxuLyoqXG4gKiBXcml0ZXMgYW4gdW5zaWduZWQgMzIgYml0IHZhbHVlIGFzIGZpeGVkIDMyIGJpdHMuXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLmZpeGVkMzIgPSBmdW5jdGlvbiB3cml0ZV9maXhlZDMyKHZhbHVlKSB7XG4gICAgcmV0dXJuIHRoaXMuX3B1c2god3JpdGVGaXhlZDMyLCA0LCB2YWx1ZSA+Pj4gMCk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIHNpZ25lZCAzMiBiaXQgdmFsdWUgYXMgZml4ZWQgMzIgYml0cy5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5zZml4ZWQzMiA9IFdyaXRlci5wcm90b3R5cGUuZml4ZWQzMjtcblxuLyoqXG4gKiBXcml0ZXMgYW4gdW5zaWduZWQgNjQgYml0IHZhbHVlIGFzIGZpeGVkIDY0IGJpdHMuXG4gKiBAcGFyYW0ge0xvbmd8bnVtYmVyfHN0cmluZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgdmFsdWVgIGlzIGEgc3RyaW5nIGFuZCBubyBsb25nIGxpYnJhcnkgaXMgcHJlc2VudC5cbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5maXhlZDY0ID0gZnVuY3Rpb24gd3JpdGVfZml4ZWQ2NCh2YWx1ZSkge1xuICAgIHZhciBiaXRzID0gTG9uZ0JpdHMuZnJvbSh2YWx1ZSk7XG4gICAgcmV0dXJuIHRoaXMuX3B1c2god3JpdGVGaXhlZDMyLCA0LCBiaXRzLmxvKS5fcHVzaCh3cml0ZUZpeGVkMzIsIDQsIGJpdHMuaGkpO1xufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBzaWduZWQgNjQgYml0IHZhbHVlIGFzIGZpeGVkIDY0IGJpdHMuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7TG9uZ3xudW1iZXJ8c3RyaW5nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGB2YWx1ZWAgaXMgYSBzdHJpbmcgYW5kIG5vIGxvbmcgbGlicmFyeSBpcyBwcmVzZW50LlxuICovXG5Xcml0ZXIucHJvdG90eXBlLnNmaXhlZDY0ID0gV3JpdGVyLnByb3RvdHlwZS5maXhlZDY0O1xuXG4vKipcbiAqIFdyaXRlcyBhIGZsb2F0ICgzMiBiaXQpLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLmZsb2F0ID0gZnVuY3Rpb24gd3JpdGVfZmxvYXQodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh1dGlsLmZsb2F0LndyaXRlRmxvYXRMRSwgNCwgdmFsdWUpO1xufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBkb3VibGUgKDY0IGJpdCBmbG9hdCkuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuZG91YmxlID0gZnVuY3Rpb24gd3JpdGVfZG91YmxlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHRoaXMuX3B1c2godXRpbC5mbG9hdC53cml0ZURvdWJsZUxFLCA4LCB2YWx1ZSk7XG59O1xuXG52YXIgd3JpdGVCeXRlcyA9IHV0aWwuQXJyYXkucHJvdG90eXBlLnNldFxuICAgID8gZnVuY3Rpb24gd3JpdGVCeXRlc19zZXQodmFsLCBidWYsIHBvcykge1xuICAgICAgICBidWYuc2V0KHZhbCwgcG9zKTsgLy8gYWxzbyB3b3JrcyBmb3IgcGxhaW4gYXJyYXkgdmFsdWVzXG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgOiBmdW5jdGlvbiB3cml0ZUJ5dGVzX2Zvcih2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgYnVmW3BvcyArIGldID0gdmFsW2ldO1xuICAgIH07XG5cbi8qKlxuICogV3JpdGVzIGEgc2VxdWVuY2Ugb2YgYnl0ZXMuXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl8c3RyaW5nfSB2YWx1ZSBCdWZmZXIgb3IgYmFzZTY0IGVuY29kZWQgc3RyaW5nIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5ieXRlcyA9IGZ1bmN0aW9uIHdyaXRlX2J5dGVzKHZhbHVlKSB7XG4gICAgdmFyIGxlbiA9IHZhbHVlLmxlbmd0aCA+Pj4gMDtcbiAgICBpZiAoIWxlbilcbiAgICAgICAgcmV0dXJuIHRoaXMuX3B1c2god3JpdGVCeXRlLCAxLCAwKTtcbiAgICBpZiAodXRpbC5pc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgICAgdmFyIGJ1ZiA9IFdyaXRlci5hbGxvYyhsZW4gPSBiYXNlNjQubGVuZ3RoKHZhbHVlKSk7XG4gICAgICAgIGJhc2U2NC5kZWNvZGUodmFsdWUsIGJ1ZiwgMCk7XG4gICAgICAgIHZhbHVlID0gYnVmO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy51aW50MzIobGVuKS5fcHVzaCh3cml0ZUJ5dGVzLCBsZW4sIHZhbHVlKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgc3RyaW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5zdHJpbmcgPSBmdW5jdGlvbiB3cml0ZV9zdHJpbmcodmFsdWUpIHtcbiAgICB2YXIgbGVuID0gdXRmOC5sZW5ndGgodmFsdWUpO1xuICAgIHJldHVybiBsZW5cbiAgICAgICAgPyB0aGlzLnVpbnQzMihsZW4pLl9wdXNoKHV0Zjgud3JpdGUsIGxlbiwgdmFsdWUpXG4gICAgICAgIDogdGhpcy5fcHVzaCh3cml0ZUJ5dGUsIDEsIDApO1xufTtcblxuLyoqXG4gKiBGb3JrcyB0aGlzIHdyaXRlcidzIHN0YXRlIGJ5IHB1c2hpbmcgaXQgdG8gYSBzdGFjay5cbiAqIENhbGxpbmcge0BsaW5rIFdyaXRlciNyZXNldHxyZXNldH0gb3Ige0BsaW5rIFdyaXRlciNsZGVsaW18bGRlbGltfSByZXNldHMgdGhlIHdyaXRlciB0byB0aGUgcHJldmlvdXMgc3RhdGUuXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5mb3JrID0gZnVuY3Rpb24gZm9yaygpIHtcbiAgICB0aGlzLnN0YXRlcyA9IG5ldyBTdGF0ZSh0aGlzKTtcbiAgICB0aGlzLmhlYWQgPSB0aGlzLnRhaWwgPSBuZXcgT3Aobm9vcCwgMCwgMCk7XG4gICAgdGhpcy5sZW4gPSAwO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZXNldHMgdGhpcyBpbnN0YW5jZSB0byB0aGUgbGFzdCBzdGF0ZS5cbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24gcmVzZXQoKSB7XG4gICAgaWYgKHRoaXMuc3RhdGVzKSB7XG4gICAgICAgIHRoaXMuaGVhZCAgID0gdGhpcy5zdGF0ZXMuaGVhZDtcbiAgICAgICAgdGhpcy50YWlsICAgPSB0aGlzLnN0YXRlcy50YWlsO1xuICAgICAgICB0aGlzLmxlbiAgICA9IHRoaXMuc3RhdGVzLmxlbjtcbiAgICAgICAgdGhpcy5zdGF0ZXMgPSB0aGlzLnN0YXRlcy5uZXh0O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG5ldyBPcChub29wLCAwLCAwKTtcbiAgICAgICAgdGhpcy5sZW4gID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlc2V0cyB0byB0aGUgbGFzdCBzdGF0ZSBhbmQgYXBwZW5kcyB0aGUgZm9yayBzdGF0ZSdzIGN1cnJlbnQgd3JpdGUgbGVuZ3RoIGFzIGEgdmFyaW50IGZvbGxvd2VkIGJ5IGl0cyBvcGVyYXRpb25zLlxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUubGRlbGltID0gZnVuY3Rpb24gbGRlbGltKCkge1xuICAgIHZhciBoZWFkID0gdGhpcy5oZWFkLFxuICAgICAgICB0YWlsID0gdGhpcy50YWlsLFxuICAgICAgICBsZW4gID0gdGhpcy5sZW47XG4gICAgdGhpcy5yZXNldCgpLnVpbnQzMihsZW4pO1xuICAgIGlmIChsZW4pIHtcbiAgICAgICAgdGhpcy50YWlsLm5leHQgPSBoZWFkLm5leHQ7IC8vIHNraXAgbm9vcFxuICAgICAgICB0aGlzLnRhaWwgPSB0YWlsO1xuICAgICAgICB0aGlzLmxlbiArPSBsZW47XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBGaW5pc2hlcyB0aGUgd3JpdGUgb3BlcmF0aW9uLlxuICogQHJldHVybnMge1VpbnQ4QXJyYXl9IEZpbmlzaGVkIGJ1ZmZlclxuICovXG5Xcml0ZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uIGZpbmlzaCgpIHtcbiAgICB2YXIgaGVhZCA9IHRoaXMuaGVhZC5uZXh0LCAvLyBza2lwIG5vb3BcbiAgICAgICAgYnVmICA9IHRoaXMuY29uc3RydWN0b3IuYWxsb2ModGhpcy5sZW4pLFxuICAgICAgICBwb3MgID0gMDtcbiAgICB3aGlsZSAoaGVhZCkge1xuICAgICAgICBoZWFkLmZuKGhlYWQudmFsLCBidWYsIHBvcyk7XG4gICAgICAgIHBvcyArPSBoZWFkLmxlbjtcbiAgICAgICAgaGVhZCA9IGhlYWQubmV4dDtcbiAgICB9XG4gICAgLy8gdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbnVsbDtcbiAgICByZXR1cm4gYnVmO1xufTtcblxuV3JpdGVyLl9jb25maWd1cmUgPSBmdW5jdGlvbihCdWZmZXJXcml0ZXJfKSB7XG4gICAgQnVmZmVyV3JpdGVyID0gQnVmZmVyV3JpdGVyXztcbiAgICBXcml0ZXIuY3JlYXRlID0gY3JlYXRlKCk7XG4gICAgQnVmZmVyV3JpdGVyLl9jb25maWd1cmUoKTtcbn07XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IEJ1ZmZlcldyaXRlcjtcblxuLy8gZXh0ZW5kcyBXcml0ZXJcbnZhciBXcml0ZXIgPSByZXF1aXJlKFwiLi93cml0ZXJcIik7XG4oQnVmZmVyV3JpdGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoV3JpdGVyLnByb3RvdHlwZSkpLmNvbnN0cnVjdG9yID0gQnVmZmVyV3JpdGVyO1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCIuL3V0aWwvbWluaW1hbFwiKTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IGJ1ZmZlciB3cml0ZXIgaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIFdpcmUgZm9ybWF0IHdyaXRlciB1c2luZyBub2RlIGJ1ZmZlcnMuXG4gKiBAZXh0ZW5kcyBXcml0ZXJcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBCdWZmZXJXcml0ZXIoKSB7XG4gICAgV3JpdGVyLmNhbGwodGhpcyk7XG59XG5cbkJ1ZmZlcldyaXRlci5fY29uZmlndXJlID0gZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIEFsbG9jYXRlcyBhIGJ1ZmZlciBvZiB0aGUgc3BlY2lmaWVkIHNpemUuXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNpemUgQnVmZmVyIHNpemVcbiAgICAgKiBAcmV0dXJucyB7QnVmZmVyfSBCdWZmZXJcbiAgICAgKi9cbiAgICBCdWZmZXJXcml0ZXIuYWxsb2MgPSB1dGlsLl9CdWZmZXJfYWxsb2NVbnNhZmU7XG5cbiAgICBCdWZmZXJXcml0ZXIud3JpdGVCeXRlc0J1ZmZlciA9IHV0aWwuQnVmZmVyICYmIHV0aWwuQnVmZmVyLnByb3RvdHlwZSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkgJiYgdXRpbC5CdWZmZXIucHJvdG90eXBlLnNldC5uYW1lID09PSBcInNldFwiXG4gICAgICAgID8gZnVuY3Rpb24gd3JpdGVCeXRlc0J1ZmZlcl9zZXQodmFsLCBidWYsIHBvcykge1xuICAgICAgICAgIGJ1Zi5zZXQodmFsLCBwb3MpOyAvLyBmYXN0ZXIgdGhhbiBjb3B5IChyZXF1aXJlcyBub2RlID49IDQgd2hlcmUgQnVmZmVycyBleHRlbmQgVWludDhBcnJheSBhbmQgc2V0IGlzIHByb3Blcmx5IGluaGVyaXRlZClcbiAgICAgICAgICAvLyBhbHNvIHdvcmtzIGZvciBwbGFpbiBhcnJheSB2YWx1ZXNcbiAgICAgICAgfVxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICA6IGZ1bmN0aW9uIHdyaXRlQnl0ZXNCdWZmZXJfY29weSh2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgICAgICAgaWYgKHZhbC5jb3B5KSAvLyBCdWZmZXIgdmFsdWVzXG4gICAgICAgICAgICB2YWwuY29weShidWYsIHBvcywgMCwgdmFsLmxlbmd0aCk7XG4gICAgICAgICAgZWxzZSBmb3IgKHZhciBpID0gMDsgaSA8IHZhbC5sZW5ndGg7KSAvLyBwbGFpbiBhcnJheSB2YWx1ZXNcbiAgICAgICAgICAgIGJ1Zltwb3MrK10gPSB2YWxbaSsrXTtcbiAgICAgICAgfTtcbn07XG5cblxuLyoqXG4gKiBAb3ZlcnJpZGVcbiAqL1xuQnVmZmVyV3JpdGVyLnByb3RvdHlwZS5ieXRlcyA9IGZ1bmN0aW9uIHdyaXRlX2J5dGVzX2J1ZmZlcih2YWx1ZSkge1xuICAgIGlmICh1dGlsLmlzU3RyaW5nKHZhbHVlKSlcbiAgICAgICAgdmFsdWUgPSB1dGlsLl9CdWZmZXJfZnJvbSh2YWx1ZSwgXCJiYXNlNjRcIik7XG4gICAgdmFyIGxlbiA9IHZhbHVlLmxlbmd0aCA+Pj4gMDtcbiAgICB0aGlzLnVpbnQzMihsZW4pO1xuICAgIGlmIChsZW4pXG4gICAgICAgIHRoaXMuX3B1c2goQnVmZmVyV3JpdGVyLndyaXRlQnl0ZXNCdWZmZXIsIGxlbiwgdmFsdWUpO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gd3JpdGVTdHJpbmdCdWZmZXIodmFsLCBidWYsIHBvcykge1xuICAgIGlmICh2YWwubGVuZ3RoIDwgNDApIC8vIHBsYWluIGpzIGlzIGZhc3RlciBmb3Igc2hvcnQgc3RyaW5ncyAocHJvYmFibHkgZHVlIHRvIHJlZHVuZGFudCBhc3NlcnRpb25zKVxuICAgICAgICB1dGlsLnV0Zjgud3JpdGUodmFsLCBidWYsIHBvcyk7XG4gICAgZWxzZSBpZiAoYnVmLnV0ZjhXcml0ZSlcbiAgICAgICAgYnVmLnV0ZjhXcml0ZSh2YWwsIHBvcyk7XG4gICAgZWxzZVxuICAgICAgICBidWYud3JpdGUodmFsLCBwb3MpO1xufVxuXG4vKipcbiAqIEBvdmVycmlkZVxuICovXG5CdWZmZXJXcml0ZXIucHJvdG90eXBlLnN0cmluZyA9IGZ1bmN0aW9uIHdyaXRlX3N0cmluZ19idWZmZXIodmFsdWUpIHtcbiAgICB2YXIgbGVuID0gdXRpbC5CdWZmZXIuYnl0ZUxlbmd0aCh2YWx1ZSk7XG4gICAgdGhpcy51aW50MzIobGVuKTtcbiAgICBpZiAobGVuKVxuICAgICAgICB0aGlzLl9wdXNoKHdyaXRlU3RyaW5nQnVmZmVyLCBsZW4sIHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cblxuLyoqXG4gKiBGaW5pc2hlcyB0aGUgd3JpdGUgb3BlcmF0aW9uLlxuICogQG5hbWUgQnVmZmVyV3JpdGVyI2ZpbmlzaFxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7QnVmZmVyfSBGaW5pc2hlZCBidWZmZXJcbiAqL1xuXG5CdWZmZXJXcml0ZXIuX2NvbmZpZ3VyZSgpO1xuIiwgIlwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBSZWFkZXI7XG5cbnZhciB1dGlsICAgICAgPSByZXF1aXJlKFwiLi91dGlsL21pbmltYWxcIik7XG5cbnZhciBCdWZmZXJSZWFkZXI7IC8vIGN5Y2xpY1xuXG52YXIgTG9uZ0JpdHMgID0gdXRpbC5Mb25nQml0cyxcbiAgICB1dGY4ICAgICAgPSB1dGlsLnV0Zjg7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBpbmRleE91dE9mUmFuZ2UocmVhZGVyLCB3cml0ZUxlbmd0aCkge1xuICAgIHJldHVybiBSYW5nZUVycm9yKFwiaW5kZXggb3V0IG9mIHJhbmdlOiBcIiArIHJlYWRlci5wb3MgKyBcIiArIFwiICsgKHdyaXRlTGVuZ3RoIHx8IDEpICsgXCIgPiBcIiArIHJlYWRlci5sZW4pO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgcmVhZGVyIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgYnVmZmVyLlxuICogQGNsYXNzZGVzYyBXaXJlIGZvcm1hdCByZWFkZXIgdXNpbmcgYFVpbnQ4QXJyYXlgIGlmIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIGBBcnJheWAuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmZmVyIEJ1ZmZlciB0byByZWFkIGZyb21cbiAqL1xuZnVuY3Rpb24gUmVhZGVyKGJ1ZmZlcikge1xuXG4gICAgLyoqXG4gICAgICogUmVhZCBidWZmZXIuXG4gICAgICogQHR5cGUge1VpbnQ4QXJyYXl9XG4gICAgICovXG4gICAgdGhpcy5idWYgPSBidWZmZXI7XG5cbiAgICAvKipcbiAgICAgKiBSZWFkIGJ1ZmZlciBwb3NpdGlvbi5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMucG9zID0gMDtcblxuICAgIC8qKlxuICAgICAqIFJlYWQgYnVmZmVyIGxlbmd0aC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMubGVuID0gYnVmZmVyLmxlbmd0aDtcbn1cblxudmFyIGNyZWF0ZV9hcnJheSA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSBcInVuZGVmaW5lZFwiXG4gICAgPyBmdW5jdGlvbiBjcmVhdGVfdHlwZWRfYXJyYXkoYnVmZmVyKSB7XG4gICAgICAgIGlmIChidWZmZXIgaW5zdGFuY2VvZiBVaW50OEFycmF5IHx8IEFycmF5LmlzQXJyYXkoYnVmZmVyKSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVhZGVyKGJ1ZmZlcik7XG4gICAgICAgIHRocm93IEVycm9yKFwiaWxsZWdhbCBidWZmZXJcIik7XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgOiBmdW5jdGlvbiBjcmVhdGVfYXJyYXkoYnVmZmVyKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGJ1ZmZlcikpXG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlYWRlcihidWZmZXIpO1xuICAgICAgICB0aHJvdyBFcnJvcihcImlsbGVnYWwgYnVmZmVyXCIpO1xuICAgIH07XG5cbnZhciBjcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gICAgcmV0dXJuIHV0aWwuQnVmZmVyXG4gICAgICAgID8gZnVuY3Rpb24gY3JlYXRlX2J1ZmZlcl9zZXR1cChidWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiAoUmVhZGVyLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZV9idWZmZXIoYnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHV0aWwuQnVmZmVyLmlzQnVmZmVyKGJ1ZmZlcilcbiAgICAgICAgICAgICAgICAgICAgPyBuZXcgQnVmZmVyUmVhZGVyKGJ1ZmZlcilcbiAgICAgICAgICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgICAgICAgICAgICAgOiBjcmVhdGVfYXJyYXkoYnVmZmVyKTtcbiAgICAgICAgICAgIH0pKGJ1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgOiBjcmVhdGVfYXJyYXk7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgcmVhZGVyIHVzaW5nIHRoZSBzcGVjaWZpZWQgYnVmZmVyLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl8QnVmZmVyfSBidWZmZXIgQnVmZmVyIHRvIHJlYWQgZnJvbVxuICogQHJldHVybnMge1JlYWRlcnxCdWZmZXJSZWFkZXJ9IEEge0BsaW5rIEJ1ZmZlclJlYWRlcn0gaWYgYGJ1ZmZlcmAgaXMgYSBCdWZmZXIsIG90aGVyd2lzZSBhIHtAbGluayBSZWFkZXJ9XG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgYGJ1ZmZlcmAgaXMgbm90IGEgdmFsaWQgYnVmZmVyXG4gKi9cblJlYWRlci5jcmVhdGUgPSBjcmVhdGUoKTtcblxuUmVhZGVyLnByb3RvdHlwZS5fc2xpY2UgPSB1dGlsLkFycmF5LnByb3RvdHlwZS5zdWJhcnJheSB8fCAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyB1dGlsLkFycmF5LnByb3RvdHlwZS5zbGljZTtcblxuLyoqXG4gKiBSZWFkcyBhIHZhcmludCBhcyBhbiB1bnNpZ25lZCAzMiBiaXQgdmFsdWUuXG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS51aW50MzIgPSAoZnVuY3Rpb24gcmVhZF91aW50MzJfc2V0dXAoKSB7XG4gICAgdmFyIHZhbHVlID0gNDI5NDk2NzI5NTsgLy8gb3B0aW1pemVyIHR5cGUtaGludCwgdGVuZHMgdG8gZGVvcHQgb3RoZXJ3aXNlICg/ISlcbiAgICByZXR1cm4gZnVuY3Rpb24gcmVhZF91aW50MzIoKSB7XG4gICAgICAgIHZhbHVlID0gKCAgICAgICAgIHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNyAgICAgICApID4+PiAwOyBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpIHJldHVybiB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSAodmFsdWUgfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA8PCAgNykgPj4+IDA7IGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOCkgcmV0dXJuIHZhbHVlO1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8IDE0KSA+Pj4gMDsgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KSByZXR1cm4gdmFsdWU7XG4gICAgICAgIHZhbHVlID0gKHZhbHVlIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNykgPDwgMjEpID4+PiAwOyBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpIHJldHVybiB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSAodmFsdWUgfCAodGhpcy5idWZbdGhpcy5wb3NdICYgIDE1KSA8PCAyOCkgPj4+IDA7IGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOCkgcmV0dXJuIHZhbHVlO1xuXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICBpZiAoKHRoaXMucG9zICs9IDUpID4gdGhpcy5sZW4pIHtcbiAgICAgICAgICAgIHRoaXMucG9zID0gdGhpcy5sZW47XG4gICAgICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgMTApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9O1xufSkoKTtcblxuLyoqXG4gKiBSZWFkcyBhIHZhcmludCBhcyBhIHNpZ25lZCAzMiBiaXQgdmFsdWUuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuaW50MzIgPSBmdW5jdGlvbiByZWFkX2ludDMyKCkge1xuICAgIHJldHVybiB0aGlzLnVpbnQzMigpIHwgMDtcbn07XG5cbi8qKlxuICogUmVhZHMgYSB6aWctemFnIGVuY29kZWQgdmFyaW50IGFzIGEgc2lnbmVkIDMyIGJpdCB2YWx1ZS5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5zaW50MzIgPSBmdW5jdGlvbiByZWFkX3NpbnQzMigpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLnVpbnQzMigpO1xuICAgIHJldHVybiB2YWx1ZSA+Pj4gMSBeIC0odmFsdWUgJiAxKSB8IDA7XG59O1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1pbnZhbGlkLXRoaXMgKi9cblxuZnVuY3Rpb24gcmVhZExvbmdWYXJpbnQoKSB7XG4gICAgLy8gdGVuZHMgdG8gZGVvcHQgd2l0aCBsb2NhbCB2YXJzIGZvciBvY3RldCBldGMuXG4gICAgdmFyIGJpdHMgPSBuZXcgTG9uZ0JpdHMoMCwgMCk7XG4gICAgdmFyIGkgPSAwO1xuICAgIGlmICh0aGlzLmxlbiAtIHRoaXMucG9zID4gNCkgeyAvLyBmYXN0IHJvdXRlIChsbylcbiAgICAgICAgZm9yICg7IGkgPCA0OyArK2kpIHtcbiAgICAgICAgICAgIC8vIDFzdC4uNHRoXG4gICAgICAgICAgICBiaXRzLmxvID0gKGJpdHMubG8gfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA8PCBpICogNykgPj4+IDA7XG4gICAgICAgICAgICBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpdHM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNXRoXG4gICAgICAgIGJpdHMubG8gPSAoYml0cy5sbyB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8IDI4KSA+Pj4gMDtcbiAgICAgICAgYml0cy5oaSA9IChiaXRzLmhpIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNykgPj4gIDQpID4+PiAwO1xuICAgICAgICBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpXG4gICAgICAgICAgICByZXR1cm4gYml0cztcbiAgICAgICAgaSA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZm9yICg7IGkgPCAzOyArK2kpIHtcbiAgICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICAgICAgaWYgKHRoaXMucG9zID49IHRoaXMubGVuKVxuICAgICAgICAgICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzKTtcbiAgICAgICAgICAgIC8vIDFzdC4uM3RoXG4gICAgICAgICAgICBiaXRzLmxvID0gKGJpdHMubG8gfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA8PCBpICogNykgPj4+IDA7XG4gICAgICAgICAgICBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpdHM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNHRoXG4gICAgICAgIGJpdHMubG8gPSAoYml0cy5sbyB8ICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSAmIDEyNykgPDwgaSAqIDcpID4+PiAwO1xuICAgICAgICByZXR1cm4gYml0cztcbiAgICB9XG4gICAgaWYgKHRoaXMubGVuIC0gdGhpcy5wb3MgPiA0KSB7IC8vIGZhc3Qgcm91dGUgKGhpKVxuICAgICAgICBmb3IgKDsgaSA8IDU7ICsraSkge1xuICAgICAgICAgICAgLy8gNnRoLi4xMHRoXG4gICAgICAgICAgICBiaXRzLmhpID0gKGJpdHMuaGkgfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA8PCBpICogNyArIDMpID4+PiAwO1xuICAgICAgICAgICAgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KVxuICAgICAgICAgICAgICAgIHJldHVybiBiaXRzO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZm9yICg7IGkgPCA1OyArK2kpIHtcbiAgICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICAgICAgaWYgKHRoaXMucG9zID49IHRoaXMubGVuKVxuICAgICAgICAgICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzKTtcbiAgICAgICAgICAgIC8vIDZ0aC4uMTB0aFxuICAgICAgICAgICAgYml0cy5oaSA9IChiaXRzLmhpIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNykgPDwgaSAqIDcgKyAzKSA+Pj4gMDtcbiAgICAgICAgICAgIGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOClcbiAgICAgICAgICAgICAgICByZXR1cm4gYml0cztcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIHRocm93IEVycm9yKFwiaW52YWxpZCB2YXJpbnQgZW5jb2RpbmdcIik7XG59XG5cbi8qIGVzbGludC1lbmFibGUgbm8taW52YWxpZC10aGlzICovXG5cbi8qKlxuICogUmVhZHMgYSB2YXJpbnQgYXMgYSBzaWduZWQgNjQgYml0IHZhbHVlLlxuICogQG5hbWUgUmVhZGVyI2ludDY0XG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtMb25nfSBWYWx1ZSByZWFkXG4gKi9cblxuLyoqXG4gKiBSZWFkcyBhIHZhcmludCBhcyBhbiB1bnNpZ25lZCA2NCBiaXQgdmFsdWUuXG4gKiBAbmFtZSBSZWFkZXIjdWludDY0XG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtMb25nfSBWYWx1ZSByZWFkXG4gKi9cblxuLyoqXG4gKiBSZWFkcyBhIHppZy16YWcgZW5jb2RlZCB2YXJpbnQgYXMgYSBzaWduZWQgNjQgYml0IHZhbHVlLlxuICogQG5hbWUgUmVhZGVyI3NpbnQ2NFxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7TG9uZ30gVmFsdWUgcmVhZFxuICovXG5cbi8qKlxuICogUmVhZHMgYSB2YXJpbnQgYXMgYSBib29sZWFuLlxuICogQHJldHVybnMge2Jvb2xlYW59IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5ib29sID0gZnVuY3Rpb24gcmVhZF9ib29sKCkge1xuICAgIHJldHVybiB0aGlzLnVpbnQzMigpICE9PSAwO1xufTtcblxuZnVuY3Rpb24gcmVhZEZpeGVkMzJfZW5kKGJ1ZiwgZW5kKSB7IC8vIG5vdGUgdGhhdCB0aGlzIHVzZXMgYGVuZGAsIG5vdCBgcG9zYFxuICAgIHJldHVybiAoYnVmW2VuZCAtIDRdXG4gICAgICAgICAgfCBidWZbZW5kIC0gM10gPDwgOFxuICAgICAgICAgIHwgYnVmW2VuZCAtIDJdIDw8IDE2XG4gICAgICAgICAgfCBidWZbZW5kIC0gMV0gPDwgMjQpID4+PiAwO1xufVxuXG4vKipcbiAqIFJlYWRzIGZpeGVkIDMyIGJpdHMgYXMgYW4gdW5zaWduZWQgMzIgYml0IGludGVnZXIuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuZml4ZWQzMiA9IGZ1bmN0aW9uIHJlYWRfZml4ZWQzMigpIHtcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICh0aGlzLnBvcyArIDQgPiB0aGlzLmxlbilcbiAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMsIDQpO1xuXG4gICAgcmV0dXJuIHJlYWRGaXhlZDMyX2VuZCh0aGlzLmJ1ZiwgdGhpcy5wb3MgKz0gNCk7XG59O1xuXG4vKipcbiAqIFJlYWRzIGZpeGVkIDMyIGJpdHMgYXMgYSBzaWduZWQgMzIgYml0IGludGVnZXIuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuc2ZpeGVkMzIgPSBmdW5jdGlvbiByZWFkX3NmaXhlZDMyKCkge1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHRoaXMucG9zICsgNCA+IHRoaXMubGVuKVxuICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgNCk7XG5cbiAgICByZXR1cm4gcmVhZEZpeGVkMzJfZW5kKHRoaXMuYnVmLCB0aGlzLnBvcyArPSA0KSB8IDA7XG59O1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1pbnZhbGlkLXRoaXMgKi9cblxuZnVuY3Rpb24gcmVhZEZpeGVkNjQoLyogdGhpczogUmVhZGVyICovKSB7XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAodGhpcy5wb3MgKyA4ID4gdGhpcy5sZW4pXG4gICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCA4KTtcblxuICAgIHJldHVybiBuZXcgTG9uZ0JpdHMocmVhZEZpeGVkMzJfZW5kKHRoaXMuYnVmLCB0aGlzLnBvcyArPSA0KSwgcmVhZEZpeGVkMzJfZW5kKHRoaXMuYnVmLCB0aGlzLnBvcyArPSA0KSk7XG59XG5cbi8qIGVzbGludC1lbmFibGUgbm8taW52YWxpZC10aGlzICovXG5cbi8qKlxuICogUmVhZHMgZml4ZWQgNjQgYml0cy5cbiAqIEBuYW1lIFJlYWRlciNmaXhlZDY0XG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtMb25nfSBWYWx1ZSByZWFkXG4gKi9cblxuLyoqXG4gKiBSZWFkcyB6aWctemFnIGVuY29kZWQgZml4ZWQgNjQgYml0cy5cbiAqIEBuYW1lIFJlYWRlciNzZml4ZWQ2NFxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7TG9uZ30gVmFsdWUgcmVhZFxuICovXG5cbi8qKlxuICogUmVhZHMgYSBmbG9hdCAoMzIgYml0KSBhcyBhIG51bWJlci5cbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLmZsb2F0ID0gZnVuY3Rpb24gcmVhZF9mbG9hdCgpIHtcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICh0aGlzLnBvcyArIDQgPiB0aGlzLmxlbilcbiAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMsIDQpO1xuXG4gICAgdmFyIHZhbHVlID0gdXRpbC5mbG9hdC5yZWFkRmxvYXRMRSh0aGlzLmJ1ZiwgdGhpcy5wb3MpO1xuICAgIHRoaXMucG9zICs9IDQ7XG4gICAgcmV0dXJuIHZhbHVlO1xufTtcblxuLyoqXG4gKiBSZWFkcyBhIGRvdWJsZSAoNjQgYml0IGZsb2F0KSBhcyBhIG51bWJlci5cbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLmRvdWJsZSA9IGZ1bmN0aW9uIHJlYWRfZG91YmxlKCkge1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHRoaXMucG9zICsgOCA+IHRoaXMubGVuKVxuICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgNCk7XG5cbiAgICB2YXIgdmFsdWUgPSB1dGlsLmZsb2F0LnJlYWREb3VibGVMRSh0aGlzLmJ1ZiwgdGhpcy5wb3MpO1xuICAgIHRoaXMucG9zICs9IDg7XG4gICAgcmV0dXJuIHZhbHVlO1xufTtcblxuLyoqXG4gKiBSZWFkcyBhIHNlcXVlbmNlIG9mIGJ5dGVzIHByZWNlZWRlZCBieSBpdHMgbGVuZ3RoIGFzIGEgdmFyaW50LlxuICogQHJldHVybnMge1VpbnQ4QXJyYXl9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5ieXRlcyA9IGZ1bmN0aW9uIHJlYWRfYnl0ZXMoKSB7XG4gICAgdmFyIGxlbmd0aCA9IHRoaXMudWludDMyKCksXG4gICAgICAgIHN0YXJ0ICA9IHRoaXMucG9zLFxuICAgICAgICBlbmQgICAgPSB0aGlzLnBvcyArIGxlbmd0aDtcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmIChlbmQgPiB0aGlzLmxlbilcbiAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMsIGxlbmd0aCk7XG5cbiAgICB0aGlzLnBvcyArPSBsZW5ndGg7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5idWYpKSAvLyBwbGFpbiBhcnJheVxuICAgICAgICByZXR1cm4gdGhpcy5idWYuc2xpY2Uoc3RhcnQsIGVuZCk7XG5cbiAgICBpZiAoc3RhcnQgPT09IGVuZCkgeyAvLyBmaXggZm9yIElFIDEwL1dpbjggYW5kIG90aGVycycgc3ViYXJyYXkgcmV0dXJuaW5nIGFycmF5IG9mIHNpemUgMVxuICAgICAgICB2YXIgbmF0aXZlQnVmZmVyID0gdXRpbC5CdWZmZXI7XG4gICAgICAgIHJldHVybiBuYXRpdmVCdWZmZXJcbiAgICAgICAgICAgID8gbmF0aXZlQnVmZmVyLmFsbG9jKDApXG4gICAgICAgICAgICA6IG5ldyB0aGlzLmJ1Zi5jb25zdHJ1Y3RvcigwKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3NsaWNlLmNhbGwodGhpcy5idWYsIHN0YXJ0LCBlbmQpO1xufTtcblxuLyoqXG4gKiBSZWFkcyBhIHN0cmluZyBwcmVjZWVkZWQgYnkgaXRzIGJ5dGUgbGVuZ3RoIGFzIGEgdmFyaW50LlxuICogQHJldHVybnMge3N0cmluZ30gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLnN0cmluZyA9IGZ1bmN0aW9uIHJlYWRfc3RyaW5nKCkge1xuICAgIHZhciBieXRlcyA9IHRoaXMuYnl0ZXMoKTtcbiAgICByZXR1cm4gdXRmOC5yZWFkKGJ5dGVzLCAwLCBieXRlcy5sZW5ndGgpO1xufTtcblxuLyoqXG4gKiBTa2lwcyB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBieXRlcyBpZiBzcGVjaWZpZWQsIG90aGVyd2lzZSBza2lwcyBhIHZhcmludC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBMZW5ndGggaWYga25vd24sIG90aGVyd2lzZSBhIHZhcmludCBpcyBhc3N1bWVkXG4gKiBAcmV0dXJucyB7UmVhZGVyfSBgdGhpc2BcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5za2lwID0gZnVuY3Rpb24gc2tpcChsZW5ndGgpIHtcbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgaWYgKHRoaXMucG9zICsgbGVuZ3RoID4gdGhpcy5sZW4pXG4gICAgICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgbGVuZ3RoKTtcbiAgICAgICAgdGhpcy5wb3MgKz0gbGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICAgICAgaWYgKHRoaXMucG9zID49IHRoaXMubGVuKVxuICAgICAgICAgICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzKTtcbiAgICAgICAgfSB3aGlsZSAodGhpcy5idWZbdGhpcy5wb3MrK10gJiAxMjgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2tpcHMgdGhlIG5leHQgZWxlbWVudCBvZiB0aGUgc3BlY2lmaWVkIHdpcmUgdHlwZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB3aXJlVHlwZSBXaXJlIHR5cGUgcmVjZWl2ZWRcbiAqIEByZXR1cm5zIHtSZWFkZXJ9IGB0aGlzYFxuICovXG5SZWFkZXIucHJvdG90eXBlLnNraXBUeXBlID0gZnVuY3Rpb24od2lyZVR5cGUpIHtcbiAgICBzd2l0Y2ggKHdpcmVUeXBlKSB7XG4gICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgIHRoaXMuc2tpcCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgIHRoaXMuc2tpcCg4KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICB0aGlzLnNraXAodGhpcy51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgd2hpbGUgKCh3aXJlVHlwZSA9IHRoaXMudWludDMyKCkgJiA3KSAhPT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2tpcFR5cGUod2lyZVR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgIHRoaXMuc2tpcCg0KTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcImludmFsaWQgd2lyZSB0eXBlIFwiICsgd2lyZVR5cGUgKyBcIiBhdCBvZmZzZXQgXCIgKyB0aGlzLnBvcyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xufTtcblxuUmVhZGVyLl9jb25maWd1cmUgPSBmdW5jdGlvbihCdWZmZXJSZWFkZXJfKSB7XG4gICAgQnVmZmVyUmVhZGVyID0gQnVmZmVyUmVhZGVyXztcbiAgICBSZWFkZXIuY3JlYXRlID0gY3JlYXRlKCk7XG4gICAgQnVmZmVyUmVhZGVyLl9jb25maWd1cmUoKTtcblxuICAgIHZhciBmbiA9IHV0aWwuTG9uZyA/IFwidG9Mb25nXCIgOiAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyBcInRvTnVtYmVyXCI7XG4gICAgdXRpbC5tZXJnZShSZWFkZXIucHJvdG90eXBlLCB7XG5cbiAgICAgICAgaW50NjQ6IGZ1bmN0aW9uIHJlYWRfaW50NjQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZExvbmdWYXJpbnQuY2FsbCh0aGlzKVtmbl0oZmFsc2UpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHVpbnQ2NDogZnVuY3Rpb24gcmVhZF91aW50NjQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZExvbmdWYXJpbnQuY2FsbCh0aGlzKVtmbl0odHJ1ZSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2ludDY0OiBmdW5jdGlvbiByZWFkX3NpbnQ2NCgpIHtcbiAgICAgICAgICAgIHJldHVybiByZWFkTG9uZ1ZhcmludC5jYWxsKHRoaXMpLnp6RGVjb2RlKClbZm5dKGZhbHNlKTtcbiAgICAgICAgfSxcblxuICAgICAgICBmaXhlZDY0OiBmdW5jdGlvbiByZWFkX2ZpeGVkNjQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZEZpeGVkNjQuY2FsbCh0aGlzKVtmbl0odHJ1ZSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2ZpeGVkNjQ6IGZ1bmN0aW9uIHJlYWRfc2ZpeGVkNjQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZEZpeGVkNjQuY2FsbCh0aGlzKVtmbl0oZmFsc2UpO1xuICAgICAgICB9XG5cbiAgICB9KTtcbn07XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IEJ1ZmZlclJlYWRlcjtcblxuLy8gZXh0ZW5kcyBSZWFkZXJcbnZhciBSZWFkZXIgPSByZXF1aXJlKFwiLi9yZWFkZXJcIik7XG4oQnVmZmVyUmVhZGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoUmVhZGVyLnByb3RvdHlwZSkpLmNvbnN0cnVjdG9yID0gQnVmZmVyUmVhZGVyO1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCIuL3V0aWwvbWluaW1hbFwiKTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IGJ1ZmZlciByZWFkZXIgaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIFdpcmUgZm9ybWF0IHJlYWRlciB1c2luZyBub2RlIGJ1ZmZlcnMuXG4gKiBAZXh0ZW5kcyBSZWFkZXJcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtCdWZmZXJ9IGJ1ZmZlciBCdWZmZXIgdG8gcmVhZCBmcm9tXG4gKi9cbmZ1bmN0aW9uIEJ1ZmZlclJlYWRlcihidWZmZXIpIHtcbiAgICBSZWFkZXIuY2FsbCh0aGlzLCBidWZmZXIpO1xuXG4gICAgLyoqXG4gICAgICogUmVhZCBidWZmZXIuXG4gICAgICogQG5hbWUgQnVmZmVyUmVhZGVyI2J1ZlxuICAgICAqIEB0eXBlIHtCdWZmZXJ9XG4gICAgICovXG59XG5cbkJ1ZmZlclJlYWRlci5fY29uZmlndXJlID0gZnVuY3Rpb24gKCkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKHV0aWwuQnVmZmVyKVxuICAgICAgICBCdWZmZXJSZWFkZXIucHJvdG90eXBlLl9zbGljZSA9IHV0aWwuQnVmZmVyLnByb3RvdHlwZS5zbGljZTtcbn07XG5cblxuLyoqXG4gKiBAb3ZlcnJpZGVcbiAqL1xuQnVmZmVyUmVhZGVyLnByb3RvdHlwZS5zdHJpbmcgPSBmdW5jdGlvbiByZWFkX3N0cmluZ19idWZmZXIoKSB7XG4gICAgdmFyIGxlbiA9IHRoaXMudWludDMyKCk7IC8vIG1vZGlmaWVzIHBvc1xuICAgIHJldHVybiB0aGlzLmJ1Zi51dGY4U2xpY2VcbiAgICAgICAgPyB0aGlzLmJ1Zi51dGY4U2xpY2UodGhpcy5wb3MsIHRoaXMucG9zID0gTWF0aC5taW4odGhpcy5wb3MgKyBsZW4sIHRoaXMubGVuKSlcbiAgICAgICAgOiB0aGlzLmJ1Zi50b1N0cmluZyhcInV0Zi04XCIsIHRoaXMucG9zLCB0aGlzLnBvcyA9IE1hdGgubWluKHRoaXMucG9zICsgbGVuLCB0aGlzLmxlbikpO1xufTtcblxuLyoqXG4gKiBSZWFkcyBhIHNlcXVlbmNlIG9mIGJ5dGVzIHByZWNlZWRlZCBieSBpdHMgbGVuZ3RoIGFzIGEgdmFyaW50LlxuICogQG5hbWUgQnVmZmVyUmVhZGVyI2J5dGVzXG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtCdWZmZXJ9IFZhbHVlIHJlYWRcbiAqL1xuXG5CdWZmZXJSZWFkZXIuX2NvbmZpZ3VyZSgpO1xuIiwgIlwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBTZXJ2aWNlO1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsL21pbmltYWxcIik7XG5cbi8vIEV4dGVuZHMgRXZlbnRFbWl0dGVyXG4oU2VydmljZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHV0aWwuRXZlbnRFbWl0dGVyLnByb3RvdHlwZSkpLmNvbnN0cnVjdG9yID0gU2VydmljZTtcblxuLyoqXG4gKiBBIHNlcnZpY2UgbWV0aG9kIGNhbGxiYWNrIGFzIHVzZWQgYnkge0BsaW5rIHJwYy5TZXJ2aWNlTWV0aG9kfFNlcnZpY2VNZXRob2R9LlxuICpcbiAqIERpZmZlcnMgZnJvbSB7QGxpbmsgUlBDSW1wbENhbGxiYWNrfSBpbiB0aGF0IGl0IGlzIGFuIGFjdHVhbCBjYWxsYmFjayBvZiBhIHNlcnZpY2UgbWV0aG9kIHdoaWNoIG1heSBub3QgcmV0dXJuIGByZXNwb25zZSA9IG51bGxgLlxuICogQHR5cGVkZWYgcnBjLlNlcnZpY2VNZXRob2RDYWxsYmFja1xuICogQHRlbXBsYXRlIFRSZXMgZXh0ZW5kcyBNZXNzYWdlPFRSZXM+XG4gKiBAdHlwZSB7ZnVuY3Rpb259XG4gKiBAcGFyYW0ge0Vycm9yfG51bGx9IGVycm9yIEVycm9yLCBpZiBhbnlcbiAqIEBwYXJhbSB7VFJlc30gW3Jlc3BvbnNlXSBSZXNwb25zZSBtZXNzYWdlXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICovXG5cbi8qKlxuICogQSBzZXJ2aWNlIG1ldGhvZCBwYXJ0IG9mIGEge0BsaW5rIHJwYy5TZXJ2aWNlfSBhcyBjcmVhdGVkIGJ5IHtAbGluayBTZXJ2aWNlLmNyZWF0ZX0uXG4gKiBAdHlwZWRlZiBycGMuU2VydmljZU1ldGhvZFxuICogQHRlbXBsYXRlIFRSZXEgZXh0ZW5kcyBNZXNzYWdlPFRSZXE+XG4gKiBAdGVtcGxhdGUgVFJlcyBleHRlbmRzIE1lc3NhZ2U8VFJlcz5cbiAqIEB0eXBlIHtmdW5jdGlvbn1cbiAqIEBwYXJhbSB7VFJlcXxQcm9wZXJ0aWVzPFRSZXE+fSByZXF1ZXN0IFJlcXVlc3QgbWVzc2FnZSBvciBwbGFpbiBvYmplY3RcbiAqIEBwYXJhbSB7cnBjLlNlcnZpY2VNZXRob2RDYWxsYmFjazxUUmVzPn0gW2NhbGxiYWNrXSBOb2RlLXN0eWxlIGNhbGxiYWNrIGNhbGxlZCB3aXRoIHRoZSBlcnJvciwgaWYgYW55LCBhbmQgdGhlIHJlc3BvbnNlIG1lc3NhZ2VcbiAqIEByZXR1cm5zIHtQcm9taXNlPE1lc3NhZ2U8VFJlcz4+fSBQcm9taXNlIGlmIGBjYWxsYmFja2AgaGFzIGJlZW4gb21pdHRlZCwgb3RoZXJ3aXNlIGB1bmRlZmluZWRgXG4gKi9cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IFJQQyBzZXJ2aWNlIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBBbiBSUEMgc2VydmljZSBhcyByZXR1cm5lZCBieSB7QGxpbmsgU2VydmljZSNjcmVhdGV9LlxuICogQGV4cG9ydHMgcnBjLlNlcnZpY2VcbiAqIEBleHRlbmRzIHV0aWwuRXZlbnRFbWl0dGVyXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7UlBDSW1wbH0gcnBjSW1wbCBSUEMgaW1wbGVtZW50YXRpb25cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JlcXVlc3REZWxpbWl0ZWQ9ZmFsc2VdIFdoZXRoZXIgcmVxdWVzdHMgYXJlIGxlbmd0aC1kZWxpbWl0ZWRcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Jlc3BvbnNlRGVsaW1pdGVkPWZhbHNlXSBXaGV0aGVyIHJlc3BvbnNlcyBhcmUgbGVuZ3RoLWRlbGltaXRlZFxuICovXG5mdW5jdGlvbiBTZXJ2aWNlKHJwY0ltcGwsIHJlcXVlc3REZWxpbWl0ZWQsIHJlc3BvbnNlRGVsaW1pdGVkKSB7XG5cbiAgICBpZiAodHlwZW9mIHJwY0ltcGwgIT09IFwiZnVuY3Rpb25cIilcbiAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwicnBjSW1wbCBtdXN0IGJlIGEgZnVuY3Rpb25cIik7XG5cbiAgICB1dGlsLkV2ZW50RW1pdHRlci5jYWxsKHRoaXMpO1xuXG4gICAgLyoqXG4gICAgICogUlBDIGltcGxlbWVudGF0aW9uLiBCZWNvbWVzIGBudWxsYCBvbmNlIHRoZSBzZXJ2aWNlIGlzIGVuZGVkLlxuICAgICAqIEB0eXBlIHtSUENJbXBsfG51bGx9XG4gICAgICovXG4gICAgdGhpcy5ycGNJbXBsID0gcnBjSW1wbDtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgcmVxdWVzdHMgYXJlIGxlbmd0aC1kZWxpbWl0ZWQuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgdGhpcy5yZXF1ZXN0RGVsaW1pdGVkID0gQm9vbGVhbihyZXF1ZXN0RGVsaW1pdGVkKTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgcmVzcG9uc2VzIGFyZSBsZW5ndGgtZGVsaW1pdGVkLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIHRoaXMucmVzcG9uc2VEZWxpbWl0ZWQgPSBCb29sZWFuKHJlc3BvbnNlRGVsaW1pdGVkKTtcbn1cblxuLyoqXG4gKiBDYWxscyBhIHNlcnZpY2UgbWV0aG9kIHRocm91Z2gge0BsaW5rIHJwYy5TZXJ2aWNlI3JwY0ltcGx8cnBjSW1wbH0uXG4gKiBAcGFyYW0ge01ldGhvZHxycGMuU2VydmljZU1ldGhvZDxUUmVxLFRSZXM+fSBtZXRob2QgUmVmbGVjdGVkIG9yIHN0YXRpYyBtZXRob2RcbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8VFJlcT59IHJlcXVlc3RDdG9yIFJlcXVlc3QgY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8VFJlcz59IHJlc3BvbnNlQ3RvciBSZXNwb25zZSBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtUUmVxfFByb3BlcnRpZXM8VFJlcT59IHJlcXVlc3QgUmVxdWVzdCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdFxuICogQHBhcmFtIHtycGMuU2VydmljZU1ldGhvZENhbGxiYWNrPFRSZXM+fSBjYWxsYmFjayBTZXJ2aWNlIGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICogQHRlbXBsYXRlIFRSZXEgZXh0ZW5kcyBNZXNzYWdlPFRSZXE+XG4gKiBAdGVtcGxhdGUgVFJlcyBleHRlbmRzIE1lc3NhZ2U8VFJlcz5cbiAqL1xuU2VydmljZS5wcm90b3R5cGUucnBjQ2FsbCA9IGZ1bmN0aW9uIHJwY0NhbGwobWV0aG9kLCByZXF1ZXN0Q3RvciwgcmVzcG9uc2VDdG9yLCByZXF1ZXN0LCBjYWxsYmFjaykge1xuXG4gICAgaWYgKCFyZXF1ZXN0KVxuICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJyZXF1ZXN0IG11c3QgYmUgc3BlY2lmaWVkXCIpO1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIGlmICghY2FsbGJhY2spXG4gICAgICAgIHJldHVybiB1dGlsLmFzUHJvbWlzZShycGNDYWxsLCBzZWxmLCBtZXRob2QsIHJlcXVlc3RDdG9yLCByZXNwb25zZUN0b3IsIHJlcXVlc3QpO1xuXG4gICAgaWYgKCFzZWxmLnJwY0ltcGwpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsgY2FsbGJhY2soRXJyb3IoXCJhbHJlYWR5IGVuZGVkXCIpKTsgfSwgMCk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHNlbGYucnBjSW1wbChcbiAgICAgICAgICAgIG1ldGhvZCxcbiAgICAgICAgICAgIHJlcXVlc3RDdG9yW3NlbGYucmVxdWVzdERlbGltaXRlZCA/IFwiZW5jb2RlRGVsaW1pdGVkXCIgOiBcImVuY29kZVwiXShyZXF1ZXN0KS5maW5pc2goKSxcbiAgICAgICAgICAgIGZ1bmN0aW9uIHJwY0NhbGxiYWNrKGVyciwgcmVzcG9uc2UpIHtcblxuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5lbWl0KFwiZXJyb3JcIiwgZXJyLCBtZXRob2QpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5lbmQoLyogZW5kZWRCeVJQQyAqLyB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIShyZXNwb25zZSBpbnN0YW5jZW9mIHJlc3BvbnNlQ3RvcikpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gcmVzcG9uc2VDdG9yW3NlbGYucmVzcG9uc2VEZWxpbWl0ZWQgPyBcImRlY29kZURlbGltaXRlZFwiIDogXCJkZWNvZGVcIl0ocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZW1pdChcImVycm9yXCIsIGVyciwgbWV0aG9kKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgc2VsZi5lbWl0KFwiZGF0YVwiLCByZXNwb25zZSwgbWV0aG9kKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgcmVzcG9uc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBzZWxmLmVtaXQoXCJlcnJvclwiLCBlcnIsIG1ldGhvZCk7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNhbGxiYWNrKGVycik7IH0sIDApO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbn07XG5cbi8qKlxuICogRW5kcyB0aGlzIHNlcnZpY2UgYW5kIGVtaXRzIHRoZSBgZW5kYCBldmVudC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2VuZGVkQnlSUEM9ZmFsc2VdIFdoZXRoZXIgdGhlIHNlcnZpY2UgaGFzIGJlZW4gZW5kZWQgYnkgdGhlIFJQQyBpbXBsZW1lbnRhdGlvbi5cbiAqIEByZXR1cm5zIHtycGMuU2VydmljZX0gYHRoaXNgXG4gKi9cblNlcnZpY2UucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uIGVuZChlbmRlZEJ5UlBDKSB7XG4gICAgaWYgKHRoaXMucnBjSW1wbCkge1xuICAgICAgICBpZiAoIWVuZGVkQnlSUEMpIC8vIHNpZ25hbCBlbmQgdG8gcnBjSW1wbFxuICAgICAgICAgICAgdGhpcy5ycGNJbXBsKG51bGwsIG51bGwsIG51bGwpO1xuICAgICAgICB0aGlzLnJwY0ltcGwgPSBudWxsO1xuICAgICAgICB0aGlzLmVtaXQoXCJlbmRcIikub2ZmKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xufTtcbiIsICJcInVzZSBzdHJpY3RcIjtcblxuLyoqXG4gKiBTdHJlYW1pbmcgUlBDIGhlbHBlcnMuXG4gKiBAbmFtZXNwYWNlXG4gKi9cbnZhciBycGMgPSBleHBvcnRzO1xuXG4vKipcbiAqIFJQQyBpbXBsZW1lbnRhdGlvbiBwYXNzZWQgdG8ge0BsaW5rIFNlcnZpY2UjY3JlYXRlfSBwZXJmb3JtaW5nIGEgc2VydmljZSByZXF1ZXN0IG9uIG5ldHdvcmsgbGV2ZWwsIGkuZS4gYnkgdXRpbGl6aW5nIGh0dHAgcmVxdWVzdHMgb3Igd2Vic29ja2V0cy5cbiAqIEB0eXBlZGVmIFJQQ0ltcGxcbiAqIEB0eXBlIHtmdW5jdGlvbn1cbiAqIEBwYXJhbSB7TWV0aG9kfHJwYy5TZXJ2aWNlTWV0aG9kPE1lc3NhZ2U8e30+LE1lc3NhZ2U8e30+Pn0gbWV0aG9kIFJlZmxlY3RlZCBvciBzdGF0aWMgbWV0aG9kIGJlaW5nIGNhbGxlZFxuICogQHBhcmFtIHtVaW50OEFycmF5fSByZXF1ZXN0RGF0YSBSZXF1ZXN0IGRhdGFcbiAqIEBwYXJhbSB7UlBDSW1wbENhbGxiYWNrfSBjYWxsYmFjayBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAqIEBleGFtcGxlXG4gKiBmdW5jdGlvbiBycGNJbXBsKG1ldGhvZCwgcmVxdWVzdERhdGEsIGNhbGxiYWNrKSB7XG4gKiAgICAgaWYgKHByb3RvYnVmLnV0aWwubGNGaXJzdChtZXRob2QubmFtZSkgIT09IFwibXlNZXRob2RcIikgLy8gY29tcGF0aWJsZSB3aXRoIHN0YXRpYyBjb2RlXG4gKiAgICAgICAgIHRocm93IEVycm9yKFwibm8gc3VjaCBtZXRob2RcIik7XG4gKiAgICAgYXN5bmNocm9ub3VzbHlPYnRhaW5BUmVzcG9uc2UocmVxdWVzdERhdGEsIGZ1bmN0aW9uKGVyciwgcmVzcG9uc2VEYXRhKSB7XG4gKiAgICAgICAgIGNhbGxiYWNrKGVyciwgcmVzcG9uc2VEYXRhKTtcbiAqICAgICB9KTtcbiAqIH1cbiAqL1xuXG4vKipcbiAqIE5vZGUtc3R5bGUgY2FsbGJhY2sgYXMgdXNlZCBieSB7QGxpbmsgUlBDSW1wbH0uXG4gKiBAdHlwZWRlZiBSUENJbXBsQ2FsbGJhY2tcbiAqIEB0eXBlIHtmdW5jdGlvbn1cbiAqIEBwYXJhbSB7RXJyb3J8bnVsbH0gZXJyb3IgRXJyb3IsIGlmIGFueSwgb3RoZXJ3aXNlIGBudWxsYFxuICogQHBhcmFtIHtVaW50OEFycmF5fG51bGx9IFtyZXNwb25zZV0gUmVzcG9uc2UgZGF0YSBvciBgbnVsbGAgdG8gc2lnbmFsIGVuZCBvZiBzdHJlYW0sIGlmIHRoZXJlIGhhc24ndCBiZWVuIGFuIGVycm9yXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICovXG5cbnJwYy5TZXJ2aWNlID0gcmVxdWlyZShcIi4vcnBjL3NlcnZpY2VcIik7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG4vKipcbiAqIE5hbWVkIHJvb3RzLlxuICogVGhpcyBpcyB3aGVyZSBwYmpzIHN0b3JlcyBnZW5lcmF0ZWQgc3RydWN0dXJlcyAodGhlIG9wdGlvbiBgLXIsIC0tcm9vdGAgc3BlY2lmaWVzIGEgbmFtZSkuXG4gKiBDYW4gYWxzbyBiZSB1c2VkIG1hbnVhbGx5IHRvIG1ha2Ugcm9vdHMgYXZhaWxhYmxlIGFjcm9zcyBtb2R1bGVzLlxuICogQG5hbWUgcm9vdHNcbiAqIEB0eXBlIHtPYmplY3QuPHN0cmluZyxSb290Pn1cbiAqIEBleGFtcGxlXG4gKiAvLyBwYmpzIC1yIG15cm9vdCAtbyBjb21waWxlZC5qcyAuLi5cbiAqXG4gKiAvLyBpbiBhbm90aGVyIG1vZHVsZTpcbiAqIHJlcXVpcmUoXCIuL2NvbXBpbGVkLmpzXCIpO1xuICpcbiAqIC8vIGluIGFueSBzdWJzZXF1ZW50IG1vZHVsZTpcbiAqIHZhciByb290ID0gcHJvdG9idWYucm9vdHNbXCJteXJvb3RcIl07XG4gKi9cbiIsICJcInVzZSBzdHJpY3RcIjtcbnZhciBwcm90b2J1ZiA9IGV4cG9ydHM7XG5cbi8qKlxuICogQnVpbGQgdHlwZSwgb25lIG9mIGBcImZ1bGxcImAsIGBcImxpZ2h0XCJgIG9yIGBcIm1pbmltYWxcImAuXG4gKiBAbmFtZSBidWlsZFxuICogQHR5cGUge3N0cmluZ31cbiAqIEBjb25zdFxuICovXG5wcm90b2J1Zi5idWlsZCA9IFwibWluaW1hbFwiO1xuXG4vLyBTZXJpYWxpemF0aW9uXG5wcm90b2J1Zi5Xcml0ZXIgICAgICAgPSByZXF1aXJlKFwiLi93cml0ZXJcIik7XG5wcm90b2J1Zi5CdWZmZXJXcml0ZXIgPSByZXF1aXJlKFwiLi93cml0ZXJfYnVmZmVyXCIpO1xucHJvdG9idWYuUmVhZGVyICAgICAgID0gcmVxdWlyZShcIi4vcmVhZGVyXCIpO1xucHJvdG9idWYuQnVmZmVyUmVhZGVyID0gcmVxdWlyZShcIi4vcmVhZGVyX2J1ZmZlclwiKTtcblxuLy8gVXRpbGl0eVxucHJvdG9idWYudXRpbCAgICAgICAgID0gcmVxdWlyZShcIi4vdXRpbC9taW5pbWFsXCIpO1xucHJvdG9idWYucnBjICAgICAgICAgID0gcmVxdWlyZShcIi4vcnBjXCIpO1xucHJvdG9idWYucm9vdHMgICAgICAgID0gcmVxdWlyZShcIi4vcm9vdHNcIik7XG5wcm90b2J1Zi5jb25maWd1cmUgICAgPSBjb25maWd1cmU7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4vKipcbiAqIFJlY29uZmlndXJlcyB0aGUgbGlicmFyeSBhY2NvcmRpbmcgdG8gdGhlIGVudmlyb25tZW50LlxuICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24gY29uZmlndXJlKCkge1xuICAgIHByb3RvYnVmLnV0aWwuX2NvbmZpZ3VyZSgpO1xuICAgIHByb3RvYnVmLldyaXRlci5fY29uZmlndXJlKHByb3RvYnVmLkJ1ZmZlcldyaXRlcik7XG4gICAgcHJvdG9idWYuUmVhZGVyLl9jb25maWd1cmUocHJvdG9idWYuQnVmZmVyUmVhZGVyKTtcbn1cblxuLy8gU2V0IHVwIGJ1ZmZlciB1dGlsaXR5IGFjY29yZGluZyB0byB0aGUgZW52aXJvbm1lbnRcbmNvbmZpZ3VyZSgpO1xuIiwgIi8vIG1pbmltYWwgbGlicmFyeSBlbnRyeSBwb2ludC5cblxuXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL3NyYy9pbmRleC1taW5pbWFsXCIpO1xuIiwgIi8qZXNsaW50LWRpc2FibGUgYmxvY2stc2NvcGVkLXZhciwgaWQtbGVuZ3RoLCBuby1jb250cm9sLXJlZ2V4LCBuby1tYWdpYy1udW1iZXJzLCBuby1wcm90b3R5cGUtYnVpbHRpbnMsIG5vLXJlZGVjbGFyZSwgbm8tc2hhZG93LCBuby12YXIsIHNvcnQtdmFycyovXG4ndXNlIHN0cmljdCc7XG5cbnZhciAkcHJvdG9idWYgPSByZXF1aXJlKCdwcm90b2J1ZmpzL21pbmltYWwnKTtcblxuLy8gQ29tbW9uIGFsaWFzZXNcbnZhciAkUmVhZGVyID0gJHByb3RvYnVmLlJlYWRlcixcbiAgJFdyaXRlciA9ICRwcm90b2J1Zi5Xcml0ZXIsXG4gICR1dGlsID0gJHByb3RvYnVmLnV0aWw7XG5cbi8vIEV4cG9ydGVkIHJvb3QgbmFtZXNwYWNlXG52YXIgJHJvb3QgPSAkcHJvdG9idWYucm9vdHNbJ2RlZmF1bHQnXSB8fCAoJHByb3RvYnVmLnJvb3RzWydkZWZhdWx0J10gPSB7fSk7XG5cbiRyb290Lm9ubnggPSAoZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogTmFtZXNwYWNlIG9ubnguXG4gICAqIEBleHBvcnRzIG9ubnhcbiAgICogQG5hbWVzcGFjZVxuICAgKi9cbiAgdmFyIG9ubnggPSB7fTtcblxuICAvKipcbiAgICogVmVyc2lvbiBlbnVtLlxuICAgKiBAbmFtZSBvbm54LlZlcnNpb25cbiAgICogQGVudW0ge251bWJlcn1cbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IF9TVEFSVF9WRVJTSU9OPTAgX1NUQVJUX1ZFUlNJT04gdmFsdWVcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAxN18xMF8xMD0xIElSX1ZFUlNJT05fMjAxN18xMF8xMCB2YWx1ZVxuICAgKiBAcHJvcGVydHkge251bWJlcn0gSVJfVkVSU0lPTl8yMDE3XzEwXzMwPTIgSVJfVkVSU0lPTl8yMDE3XzEwXzMwIHZhbHVlXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OXzIwMTdfMTFfMz0zIElSX1ZFUlNJT05fMjAxN18xMV8zIHZhbHVlXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OXzIwMTlfMV8yMj00IElSX1ZFUlNJT05fMjAxOV8xXzIyIHZhbHVlXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OXzIwMTlfM18xOD01IElSX1ZFUlNJT05fMjAxOV8zXzE4IHZhbHVlXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OXzIwMTlfOV8xOT02IElSX1ZFUlNJT05fMjAxOV85XzE5IHZhbHVlXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OXzIwMjBfNV84PTcgSVJfVkVSU0lPTl8yMDIwXzVfOCB2YWx1ZVxuICAgKiBAcHJvcGVydHkge251bWJlcn0gSVJfVkVSU0lPTl8yMDIxXzdfMzA9OCBJUl9WRVJTSU9OXzIwMjFfN18zMCB2YWx1ZVxuICAgKiBAcHJvcGVydHkge251bWJlcn0gSVJfVkVSU0lPTj05IElSX1ZFUlNJT04gdmFsdWVcbiAgICovXG4gIG9ubnguVmVyc2lvbiA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZhbHVlc0J5SWQgPSB7fSxcbiAgICAgIHZhbHVlcyA9IE9iamVjdC5jcmVhdGUodmFsdWVzQnlJZCk7XG4gICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzBdID0gJ19TVEFSVF9WRVJTSU9OJyldID0gMDtcbiAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMV0gPSAnSVJfVkVSU0lPTl8yMDE3XzEwXzEwJyldID0gMTtcbiAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMl0gPSAnSVJfVkVSU0lPTl8yMDE3XzEwXzMwJyldID0gMjtcbiAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbM10gPSAnSVJfVkVSU0lPTl8yMDE3XzExXzMnKV0gPSAzO1xuICAgIHZhbHVlc1sodmFsdWVzQnlJZFs0XSA9ICdJUl9WRVJTSU9OXzIwMTlfMV8yMicpXSA9IDQ7XG4gICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzVdID0gJ0lSX1ZFUlNJT05fMjAxOV8zXzE4JyldID0gNTtcbiAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbNl0gPSAnSVJfVkVSU0lPTl8yMDE5XzlfMTknKV0gPSA2O1xuICAgIHZhbHVlc1sodmFsdWVzQnlJZFs3XSA9ICdJUl9WRVJTSU9OXzIwMjBfNV84JyldID0gNztcbiAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbOF0gPSAnSVJfVkVSU0lPTl8yMDIxXzdfMzAnKV0gPSA4O1xuICAgIHZhbHVlc1sodmFsdWVzQnlJZFs5XSA9ICdJUl9WRVJTSU9OJyldID0gOTtcbiAgICByZXR1cm4gdmFsdWVzO1xuICB9KSgpO1xuXG4gIG9ubnguQXR0cmlidXRlUHJvdG8gPSAoZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgb2YgYW4gQXR0cmlidXRlUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElBdHRyaWJ1dGVQcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtuYW1lXSBBdHRyaWJ1dGVQcm90byBuYW1lXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW3JlZkF0dHJOYW1lXSBBdHRyaWJ1dGVQcm90byByZWZBdHRyTmFtZVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb2NTdHJpbmddIEF0dHJpYnV0ZVByb3RvIGRvY1N0cmluZ1xuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlfG51bGx9IFt0eXBlXSBBdHRyaWJ1dGVQcm90byB0eXBlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ8bnVsbH0gW2ZdIEF0dHJpYnV0ZVByb3RvIGZcbiAgICAgKiBAcHJvcGVydHkge251bWJlcnxMb25nfG51bGx9IFtpXSBBdHRyaWJ1dGVQcm90byBpXG4gICAgICogQHByb3BlcnR5IHtVaW50OEFycmF5fG51bGx9IFtzXSBBdHRyaWJ1dGVQcm90byBzXG4gICAgICogQHByb3BlcnR5IHtvbm54LklUZW5zb3JQcm90b3xudWxsfSBbdF0gQXR0cmlidXRlUHJvdG8gdFxuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JR3JhcGhQcm90b3xudWxsfSBbZ10gQXR0cmlidXRlUHJvdG8gZ1xuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JU3BhcnNlVGVuc29yUHJvdG98bnVsbH0gW3NwYXJzZVRlbnNvcl0gQXR0cmlidXRlUHJvdG8gc3BhcnNlVGVuc29yXG4gICAgICogQHByb3BlcnR5IHtvbm54LklUeXBlUHJvdG98bnVsbH0gW3RwXSBBdHRyaWJ1dGVQcm90byB0cFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcj58bnVsbH0gW2Zsb2F0c10gQXR0cmlidXRlUHJvdG8gZmxvYXRzXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48bnVtYmVyfExvbmc+fG51bGx9IFtpbnRzXSBBdHRyaWJ1dGVQcm90byBpbnRzXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48VWludDhBcnJheT58bnVsbH0gW3N0cmluZ3NdIEF0dHJpYnV0ZVByb3RvIHN0cmluZ3NcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklUZW5zb3JQcm90bz58bnVsbH0gW3RlbnNvcnNdIEF0dHJpYnV0ZVByb3RvIHRlbnNvcnNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklHcmFwaFByb3RvPnxudWxsfSBbZ3JhcGhzXSBBdHRyaWJ1dGVQcm90byBncmFwaHNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklTcGFyc2VUZW5zb3JQcm90bz58bnVsbH0gW3NwYXJzZVRlbnNvcnNdIEF0dHJpYnV0ZVByb3RvIHNwYXJzZVRlbnNvcnNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklUeXBlUHJvdG8+fG51bGx9IFt0eXBlUHJvdG9zXSBBdHRyaWJ1dGVQcm90byB0eXBlUHJvdG9zXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IEF0dHJpYnV0ZVByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGFuIEF0dHJpYnV0ZVByb3RvLlxuICAgICAqIEBpbXBsZW1lbnRzIElBdHRyaWJ1dGVQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JQXR0cmlidXRlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBBdHRyaWJ1dGVQcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICB0aGlzLmZsb2F0cyA9IFtdO1xuICAgICAgdGhpcy5pbnRzID0gW107XG4gICAgICB0aGlzLnN0cmluZ3MgPSBbXTtcbiAgICAgIHRoaXMudGVuc29ycyA9IFtdO1xuICAgICAgdGhpcy5ncmFwaHMgPSBbXTtcbiAgICAgIHRoaXMuc3BhcnNlVGVuc29ycyA9IFtdO1xuICAgICAgdGhpcy50eXBlUHJvdG9zID0gW107XG4gICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gbmFtZS5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5uYW1lID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byByZWZBdHRyTmFtZS5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IHJlZkF0dHJOYW1lXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUucmVmQXR0ck5hbWUgPSAnJztcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIGRvY1N0cmluZy5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLmRvY1N0cmluZyA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gdHlwZS5cbiAgICAgKiBAbWVtYmVyIHtvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGV9IHR5cGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS50eXBlID0gMDtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIGYuXG4gICAgICogQG1lbWJlciB7bnVtYmVyfSBmXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuZiA9IDA7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byBpLlxuICAgICAqIEBtZW1iZXIge251bWJlcnxMb25nfSBpXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuaSA9ICR1dGlsLkxvbmcgPyAkdXRpbC5Mb25nLmZyb21CaXRzKDAsIDAsIGZhbHNlKSA6IDA7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byBzLlxuICAgICAqIEBtZW1iZXIge1VpbnQ4QXJyYXl9IHNcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5zID0gJHV0aWwubmV3QnVmZmVyKFtdKTtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIHQuXG4gICAgICogQG1lbWJlciB7b25ueC5JVGVuc29yUHJvdG98bnVsbHx1bmRlZmluZWR9IHRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS50ID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIGcuXG4gICAgICogQG1lbWJlciB7b25ueC5JR3JhcGhQcm90b3xudWxsfHVuZGVmaW5lZH0gZ1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLmcgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gc3BhcnNlVGVuc29yLlxuICAgICAqIEBtZW1iZXIge29ubnguSVNwYXJzZVRlbnNvclByb3RvfG51bGx8dW5kZWZpbmVkfSBzcGFyc2VUZW5zb3JcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5zcGFyc2VUZW5zb3IgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gdHAuXG4gICAgICogQG1lbWJlciB7b25ueC5JVHlwZVByb3RvfG51bGx8dW5kZWZpbmVkfSB0cFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnRwID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIGZsb2F0cy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyPn0gZmxvYXRzXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuZmxvYXRzID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIGludHMuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcnxMb25nPn0gaW50c1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLmludHMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gc3RyaW5ncy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48VWludDhBcnJheT59IHN0cmluZ3NcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5zdHJpbmdzID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIHRlbnNvcnMuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVRlbnNvclByb3RvPn0gdGVuc29yc1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnRlbnNvcnMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gZ3JhcGhzLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklHcmFwaFByb3RvPn0gZ3JhcGhzXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuZ3JhcGhzID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIHNwYXJzZVRlbnNvcnMuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVNwYXJzZVRlbnNvclByb3RvPn0gc3BhcnNlVGVuc29yc1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnNwYXJzZVRlbnNvcnMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gdHlwZVByb3Rvcy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVHlwZVByb3RvPn0gdHlwZVByb3Rvc1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnR5cGVQcm90b3MgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBBdHRyaWJ1dGVQcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JQXR0cmlidXRlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5BdHRyaWJ1dGVQcm90b30gQXR0cmlidXRlUHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGVQcm90byhwcm9wZXJ0aWVzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguQXR0cmlidXRlUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JQXR0cmlidXRlUHJvdG99IG1lc3NhZ2UgQXR0cmlidXRlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICduYW1lJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8gMTApLnN0cmluZyhtZXNzYWdlLm5hbWUpO1xuICAgICAgaWYgKG1lc3NhZ2UuZiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdmJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgNSA9Ki8gMjEpLmZsb2F0KG1lc3NhZ2UuZik7XG4gICAgICBpZiAobWVzc2FnZS5pICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2knKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAzLCB3aXJlVHlwZSAwID0qLyAyNCkuaW50NjQobWVzc2FnZS5pKTtcbiAgICAgIGlmIChtZXNzYWdlLnMgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAncycpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDQsIHdpcmVUeXBlIDIgPSovIDM0KS5ieXRlcyhtZXNzYWdlLnMpO1xuICAgICAgaWYgKG1lc3NhZ2UudCAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICd0JykpXG4gICAgICAgICRyb290Lm9ubnguVGVuc29yUHJvdG8uZW5jb2RlKG1lc3NhZ2UudCwgd3JpdGVyLnVpbnQzMigvKiBpZCA1LCB3aXJlVHlwZSAyID0qLyA0MikuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmcgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZycpKVxuICAgICAgICAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZW5jb2RlKG1lc3NhZ2UuZywgd3JpdGVyLnVpbnQzMigvKiBpZCA2LCB3aXJlVHlwZSAyID0qLyA1MCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmZsb2F0cyAhPSBudWxsICYmIG1lc3NhZ2UuZmxvYXRzLmxlbmd0aCkge1xuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDcsIHdpcmVUeXBlIDIgPSovIDU4KS5mb3JrKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5mbG9hdHMubGVuZ3RoOyArK2kpIHdyaXRlci5mbG9hdChtZXNzYWdlLmZsb2F0c1tpXSk7XG4gICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmludHMgIT0gbnVsbCAmJiBtZXNzYWdlLmludHMubGVuZ3RoKSB7XG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgOCwgd2lyZVR5cGUgMiA9Ki8gNjYpLmZvcmsoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmludHMubGVuZ3RoOyArK2kpIHdyaXRlci5pbnQ2NChtZXNzYWdlLmludHNbaV0pO1xuICAgICAgICB3cml0ZXIubGRlbGltKCk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zdHJpbmdzICE9IG51bGwgJiYgbWVzc2FnZS5zdHJpbmdzLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA5LCB3aXJlVHlwZSAyID0qLyA3NCkuYnl0ZXMobWVzc2FnZS5zdHJpbmdzW2ldKTtcbiAgICAgIGlmIChtZXNzYWdlLnRlbnNvcnMgIT0gbnVsbCAmJiBtZXNzYWdlLnRlbnNvcnMubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudGVuc29ycy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlRlbnNvclByb3RvLmVuY29kZShtZXNzYWdlLnRlbnNvcnNbaV0sIHdyaXRlci51aW50MzIoLyogaWQgMTAsIHdpcmVUeXBlIDIgPSovIDgyKS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZ3JhcGhzICE9IG51bGwgJiYgbWVzc2FnZS5ncmFwaHMubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZ3JhcGhzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguR3JhcGhQcm90by5lbmNvZGUobWVzc2FnZS5ncmFwaHNbaV0sIHdyaXRlci51aW50MzIoLyogaWQgMTEsIHdpcmVUeXBlIDIgPSovIDkwKS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RvY1N0cmluZycpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEzLCB3aXJlVHlwZSAyID0qLyAxMDYpLnN0cmluZyhtZXNzYWdlLmRvY1N0cmluZyk7XG4gICAgICBpZiAobWVzc2FnZS50cCAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICd0cCcpKVxuICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5lbmNvZGUobWVzc2FnZS50cCwgd3JpdGVyLnVpbnQzMigvKiBpZCAxNCwgd2lyZVR5cGUgMiA9Ki8gMTE0KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UudHlwZVByb3RvcyAhPSBudWxsICYmIG1lc3NhZ2UudHlwZVByb3Rvcy5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS50eXBlUHJvdG9zLmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UudHlwZVByb3Rvc1tpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTUsIHdpcmVUeXBlIDIgPSovIDEyMikuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS50eXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3R5cGUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyMCwgd2lyZVR5cGUgMCA9Ki8gMTYwKS5pbnQzMihtZXNzYWdlLnR5cGUpO1xuICAgICAgaWYgKG1lc3NhZ2UucmVmQXR0ck5hbWUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAncmVmQXR0ck5hbWUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyMSwgd2lyZVR5cGUgMiA9Ki8gMTcwKS5zdHJpbmcobWVzc2FnZS5yZWZBdHRyTmFtZSk7XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VUZW5zb3IgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnc3BhcnNlVGVuc29yJykpXG4gICAgICAgICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8uZW5jb2RlKFxuICAgICAgICAgIG1lc3NhZ2Uuc3BhcnNlVGVuc29yLFxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMjIsIHdpcmVUeXBlIDIgPSovIDE3OCkuZm9yaygpLFxuICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2Uuc3BhcnNlVGVuc29ycyAhPSBudWxsICYmIG1lc3NhZ2Uuc3BhcnNlVGVuc29ycy5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5zcGFyc2VUZW5zb3JzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5zcGFyc2VUZW5zb3JzW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyMywgd2lyZVR5cGUgMiA9Ki8gMTg2KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBBdHRyaWJ1dGVQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LkF0dHJpYnV0ZVByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSUF0dHJpYnV0ZVByb3RvfSBtZXNzYWdlIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhbiBBdHRyaWJ1dGVQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LkF0dHJpYnV0ZVByb3RvfSBBdHRyaWJ1dGVQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8oKTtcbiAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICBtZXNzYWdlLm5hbWUgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAyMToge1xuICAgICAgICAgICAgbWVzc2FnZS5yZWZBdHRyTmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDEzOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmRvY1N0cmluZyA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDIwOiB7XG4gICAgICAgICAgICBtZXNzYWdlLnR5cGUgPSByZWFkZXIuaW50MzIoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZiA9IHJlYWRlci5mbG9hdCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMzoge1xuICAgICAgICAgICAgbWVzc2FnZS5pID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA0OiB7XG4gICAgICAgICAgICBtZXNzYWdlLnMgPSByZWFkZXIuYnl0ZXMoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDU6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDY6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZyA9ICRyb290Lm9ubnguR3JhcGhQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjI6IHtcbiAgICAgICAgICAgIG1lc3NhZ2Uuc3BhcnNlVGVuc29yID0gJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTQ6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UudHAgPSAkcm9vdC5vbm54LlR5cGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNzoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5mbG9hdHMgJiYgbWVzc2FnZS5mbG9hdHMubGVuZ3RoKSkgbWVzc2FnZS5mbG9hdHMgPSBbXTtcbiAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpIG1lc3NhZ2UuZmxvYXRzLnB1c2gocmVhZGVyLmZsb2F0KCkpO1xuICAgICAgICAgICAgfSBlbHNlIG1lc3NhZ2UuZmxvYXRzLnB1c2gocmVhZGVyLmZsb2F0KCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgODoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbnRzICYmIG1lc3NhZ2UuaW50cy5sZW5ndGgpKSBtZXNzYWdlLmludHMgPSBbXTtcbiAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpIG1lc3NhZ2UuaW50cy5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgIH0gZWxzZSBtZXNzYWdlLmludHMucHVzaChyZWFkZXIuaW50NjQoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA5OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLnN0cmluZ3MgJiYgbWVzc2FnZS5zdHJpbmdzLmxlbmd0aCkpIG1lc3NhZ2Uuc3RyaW5ncyA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5zdHJpbmdzLnB1c2gocmVhZGVyLmJ5dGVzKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTA6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UudGVuc29ycyAmJiBtZXNzYWdlLnRlbnNvcnMubGVuZ3RoKSkgbWVzc2FnZS50ZW5zb3JzID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnRlbnNvcnMucHVzaCgkcm9vdC5vbm54LlRlbnNvclByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTE6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZ3JhcGhzICYmIG1lc3NhZ2UuZ3JhcGhzLmxlbmd0aCkpIG1lc3NhZ2UuZ3JhcGhzID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmdyYXBocy5wdXNoKCRyb290Lm9ubnguR3JhcGhQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDIzOiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLnNwYXJzZVRlbnNvcnMgJiYgbWVzc2FnZS5zcGFyc2VUZW5zb3JzLmxlbmd0aCkpIG1lc3NhZ2Uuc3BhcnNlVGVuc29ycyA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5zcGFyc2VUZW5zb3JzLnB1c2goJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDE1OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLnR5cGVQcm90b3MgJiYgbWVzc2FnZS50eXBlUHJvdG9zLmxlbmd0aCkpIG1lc3NhZ2UudHlwZVByb3RvcyA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS50eXBlUHJvdG9zLnB1c2goJHJvb3Qub25ueC5UeXBlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhbiBBdHRyaWJ1dGVQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcmV0dXJucyB7b25ueC5BdHRyaWJ1dGVQcm90b30gQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVmVyaWZpZXMgYW4gQXR0cmlidXRlUHJvdG8gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UubmFtZSkpIHJldHVybiAnbmFtZTogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLnJlZkF0dHJOYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncmVmQXR0ck5hbWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnJlZkF0dHJOYW1lKSkgcmV0dXJuICdyZWZBdHRyTmFtZTogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSkgcmV0dXJuICdkb2NTdHJpbmc6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS50eXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndHlwZScpKVxuICAgICAgICBzd2l0Y2ggKG1lc3NhZ2UudHlwZSkge1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gJ3R5cGU6IGVudW0gdmFsdWUgZXhwZWN0ZWQnO1xuICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgIGNhc2UgMTE6XG4gICAgICAgICAgY2FzZSAxMzpcbiAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgIGNhc2UgODpcbiAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgY2FzZSAxMDpcbiAgICAgICAgICBjYXNlIDEyOlxuICAgICAgICAgIGNhc2UgMTQ6XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2YnKSlcbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmYgIT09ICdudW1iZXInKSByZXR1cm4gJ2Y6IG51bWJlciBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5pICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaScpKVxuICAgICAgICBpZiAoXG4gICAgICAgICAgISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmkpICYmXG4gICAgICAgICAgIShtZXNzYWdlLmkgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaS5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmkuaGlnaCkpXG4gICAgICAgIClcbiAgICAgICAgICByZXR1cm4gJ2k6IGludGVnZXJ8TG9uZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5zICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncycpKVxuICAgICAgICBpZiAoISgobWVzc2FnZS5zICYmIHR5cGVvZiBtZXNzYWdlLnMubGVuZ3RoID09PSAnbnVtYmVyJykgfHwgJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5zKSkpXG4gICAgICAgICAgcmV0dXJuICdzOiBidWZmZXIgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UudCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3QnKSkge1xuICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnZlcmlmeShtZXNzYWdlLnQpO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAndC4nICsgZXJyb3I7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZycpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguR3JhcGhQcm90by52ZXJpZnkobWVzc2FnZS5nKTtcbiAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2cuJyArIGVycm9yO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uuc3BhcnNlVGVuc29yICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc3BhcnNlVGVuc29yJykpIHtcbiAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS5zcGFyc2VUZW5zb3IpO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnc3BhcnNlVGVuc29yLicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnRwICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndHAnKSkge1xuICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by52ZXJpZnkobWVzc2FnZS50cCk7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuICd0cC4nICsgZXJyb3I7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5mbG9hdHMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdmbG9hdHMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5mbG9hdHMpKSByZXR1cm4gJ2Zsb2F0czogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZmxvYXRzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5mbG9hdHNbaV0gIT09ICdudW1iZXInKSByZXR1cm4gJ2Zsb2F0czogbnVtYmVyW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuaW50cyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2ludHMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbnRzKSkgcmV0dXJuICdpbnRzOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnRzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pbnRzW2ldKSAmJlxuICAgICAgICAgICAgIShtZXNzYWdlLmludHNbaV0gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaW50c1tpXS5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludHNbaV0uaGlnaCkpXG4gICAgICAgICAgKVxuICAgICAgICAgICAgcmV0dXJuICdpbnRzOiBpbnRlZ2VyfExvbmdbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zdHJpbmdzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc3RyaW5ncycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLnN0cmluZ3MpKSByZXR1cm4gJ3N0cmluZ3M6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIShcbiAgICAgICAgICAgICAgKG1lc3NhZ2Uuc3RyaW5nc1tpXSAmJiB0eXBlb2YgbWVzc2FnZS5zdHJpbmdzW2ldLmxlbmd0aCA9PT0gJ251bWJlcicpIHx8XG4gICAgICAgICAgICAgICR1dGlsLmlzU3RyaW5nKG1lc3NhZ2Uuc3RyaW5nc1tpXSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gJ3N0cmluZ3M6IGJ1ZmZlcltdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnRlbnNvcnMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0ZW5zb3JzJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UudGVuc29ycykpIHJldHVybiAndGVuc29yczogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudGVuc29ycy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udmVyaWZ5KG1lc3NhZ2UudGVuc29yc1tpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3RlbnNvcnMuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5ncmFwaHMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdncmFwaHMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5ncmFwaHMpKSByZXR1cm4gJ2dyYXBoczogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZ3JhcGhzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnZlcmlmeShtZXNzYWdlLmdyYXBoc1tpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2dyYXBocy4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnNwYXJzZVRlbnNvcnMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzcGFyc2VUZW5zb3JzJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uuc3BhcnNlVGVuc29ycykpIHJldHVybiAnc3BhcnNlVGVuc29yczogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uuc3BhcnNlVGVuc29ycy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8udmVyaWZ5KG1lc3NhZ2Uuc3BhcnNlVGVuc29yc1tpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3NwYXJzZVRlbnNvcnMuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS50eXBlUHJvdG9zICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndHlwZVByb3RvcycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLnR5cGVQcm90b3MpKSByZXR1cm4gJ3R5cGVQcm90b3M6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnR5cGVQcm90b3MubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by52ZXJpZnkobWVzc2FnZS50eXBlUHJvdG9zW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAndHlwZVByb3Rvcy4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5BdHRyaWJ1dGVQcm90b30gQXR0cmlidXRlUHJvdG9cbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvKSByZXR1cm4gb2JqZWN0O1xuICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90bygpO1xuICAgICAgaWYgKG9iamVjdC5uYW1lICE9IG51bGwpIG1lc3NhZ2UubmFtZSA9IFN0cmluZyhvYmplY3QubmFtZSk7XG4gICAgICBpZiAob2JqZWN0LnJlZkF0dHJOYW1lICE9IG51bGwpIG1lc3NhZ2UucmVmQXR0ck5hbWUgPSBTdHJpbmcob2JqZWN0LnJlZkF0dHJOYW1lKTtcbiAgICAgIGlmIChvYmplY3QuZG9jU3RyaW5nICE9IG51bGwpIG1lc3NhZ2UuZG9jU3RyaW5nID0gU3RyaW5nKG9iamVjdC5kb2NTdHJpbmcpO1xuICAgICAgc3dpdGNoIChvYmplY3QudHlwZSkge1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICBtZXNzYWdlLnR5cGUgPSBvYmplY3QudHlwZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnVU5ERUZJTkVEJzpcbiAgICAgICAgY2FzZSAwOlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDA7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0ZMT0FUJzpcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0lOVCc6XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdTVFJJTkcnOlxuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gMztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnVEVOU09SJzpcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0dSQVBIJzpcbiAgICAgICAgY2FzZSA1OlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1NQQVJTRV9URU5TT1InOlxuICAgICAgICBjYXNlIDExOlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDExO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdUWVBFX1BST1RPJzpcbiAgICAgICAgY2FzZSAxMzpcbiAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAxMztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnRkxPQVRTJzpcbiAgICAgICAgY2FzZSA2OlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDY7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0lOVFMnOlxuICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gNztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnU1RSSU5HUyc6XG4gICAgICAgIGNhc2UgODpcbiAgICAgICAgICBtZXNzYWdlLnR5cGUgPSA4O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdURU5TT1JTJzpcbiAgICAgICAgY2FzZSA5OlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0dSQVBIUyc6XG4gICAgICAgIGNhc2UgMTA6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gMTA7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1NQQVJTRV9URU5TT1JTJzpcbiAgICAgICAgY2FzZSAxMjpcbiAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAxMjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnVFlQRV9QUk9UT1MnOlxuICAgICAgICBjYXNlIDE0OlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDE0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5mICE9IG51bGwpIG1lc3NhZ2UuZiA9IE51bWJlcihvYmplY3QuZik7XG4gICAgICBpZiAob2JqZWN0LmkgIT0gbnVsbClcbiAgICAgICAgaWYgKCR1dGlsLkxvbmcpIChtZXNzYWdlLmkgPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QuaSkpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaSA9PT0gJ3N0cmluZycpIG1lc3NhZ2UuaSA9IHBhcnNlSW50KG9iamVjdC5pLCAxMCk7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaSA9PT0gJ251bWJlcicpIG1lc3NhZ2UuaSA9IG9iamVjdC5pO1xuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmkgPT09ICdvYmplY3QnKVxuICAgICAgICAgIG1lc3NhZ2UuaSA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuaS5sb3cgPj4+IDAsIG9iamVjdC5pLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCk7XG4gICAgICBpZiAob2JqZWN0LnMgIT0gbnVsbClcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QucyA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgJHV0aWwuYmFzZTY0LmRlY29kZShvYmplY3QucywgKG1lc3NhZ2UucyA9ICR1dGlsLm5ld0J1ZmZlcigkdXRpbC5iYXNlNjQubGVuZ3RoKG9iamVjdC5zKSkpLCAwKTtcbiAgICAgICAgZWxzZSBpZiAob2JqZWN0LnMubGVuZ3RoID49IDApIG1lc3NhZ2UucyA9IG9iamVjdC5zO1xuICAgICAgaWYgKG9iamVjdC50ICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudCAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguQXR0cmlidXRlUHJvdG8udDogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3QudCk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmcgIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5nICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by5nOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5nID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmZyb21PYmplY3Qob2JqZWN0LmcpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5zcGFyc2VUZW5zb3IgIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zcGFyc2VUZW5zb3IgIT09ICdvYmplY3QnKVxuICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguQXR0cmlidXRlUHJvdG8uc3BhcnNlVGVuc29yOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5zcGFyc2VUZW5zb3IgPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLmZyb21PYmplY3Qob2JqZWN0LnNwYXJzZVRlbnNvcik7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LnRwICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudHAgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLnRwOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS50cCA9ICRyb290Lm9ubnguVHlwZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LnRwKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZmxvYXRzKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuZmxvYXRzKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by5mbG9hdHM6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuZmxvYXRzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmZsb2F0cy5sZW5ndGg7ICsraSkgbWVzc2FnZS5mbG9hdHNbaV0gPSBOdW1iZXIob2JqZWN0LmZsb2F0c1tpXSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmludHMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5pbnRzKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by5pbnRzOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmludHMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuaW50cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UuaW50c1tpXSA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5pbnRzW2ldKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmludHNbaV0gPT09ICdzdHJpbmcnKSBtZXNzYWdlLmludHNbaV0gPSBwYXJzZUludChvYmplY3QuaW50c1tpXSwgMTApO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaW50c1tpXSA9PT0gJ251bWJlcicpIG1lc3NhZ2UuaW50c1tpXSA9IG9iamVjdC5pbnRzW2ldO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaW50c1tpXSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICBtZXNzYWdlLmludHNbaV0gPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmludHNbaV0ubG93ID4+PiAwLCBvYmplY3QuaW50c1tpXS5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5zdHJpbmdzKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Quc3RyaW5ncykpIHRocm93IFR5cGVFcnJvcignLm9ubnguQXR0cmlidXRlUHJvdG8uc3RyaW5nczogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5zdHJpbmdzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LnN0cmluZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3RyaW5nc1tpXSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAkdXRpbC5iYXNlNjQuZGVjb2RlKFxuICAgICAgICAgICAgICBvYmplY3Quc3RyaW5nc1tpXSxcbiAgICAgICAgICAgICAgKG1lc3NhZ2Uuc3RyaW5nc1tpXSA9ICR1dGlsLm5ld0J1ZmZlcigkdXRpbC5iYXNlNjQubGVuZ3RoKG9iamVjdC5zdHJpbmdzW2ldKSkpLFxuICAgICAgICAgICAgICAwLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICBlbHNlIGlmIChvYmplY3Quc3RyaW5nc1tpXS5sZW5ndGggPj0gMCkgbWVzc2FnZS5zdHJpbmdzW2ldID0gb2JqZWN0LnN0cmluZ3NbaV07XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LnRlbnNvcnMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC50ZW5zb3JzKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by50ZW5zb3JzOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnRlbnNvcnMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QudGVuc29ycy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnRlbnNvcnNbaV0gIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLnRlbnNvcnM6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UudGVuc29yc1tpXSA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3QudGVuc29yc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZ3JhcGhzKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuZ3JhcGhzKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by5ncmFwaHM6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuZ3JhcGhzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmdyYXBocy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmdyYXBoc1tpXSAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguQXR0cmlidXRlUHJvdG8uZ3JhcGhzOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLmdyYXBoc1tpXSA9ICRyb290Lm9ubnguR3JhcGhQcm90by5mcm9tT2JqZWN0KG9iamVjdC5ncmFwaHNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LnNwYXJzZVRlbnNvcnMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5zcGFyc2VUZW5zb3JzKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by5zcGFyc2VUZW5zb3JzOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvcnMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Quc3BhcnNlVGVuc29ycy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnNwYXJzZVRlbnNvcnNbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by5zcGFyc2VUZW5zb3JzOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvcnNbaV0gPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLmZyb21PYmplY3Qob2JqZWN0LnNwYXJzZVRlbnNvcnNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LnR5cGVQcm90b3MpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC50eXBlUHJvdG9zKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by50eXBlUHJvdG9zOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnR5cGVQcm90b3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QudHlwZVByb3Rvcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnR5cGVQcm90b3NbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by50eXBlUHJvdG9zOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLnR5cGVQcm90b3NbaV0gPSAkcm9vdC5vbm54LlR5cGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC50eXBlUHJvdG9zW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhbiBBdHRyaWJ1dGVQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LkF0dHJpYnV0ZVByb3RvfSBtZXNzYWdlIEF0dHJpYnV0ZVByb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0LmZsb2F0cyA9IFtdO1xuICAgICAgICBvYmplY3QuaW50cyA9IFtdO1xuICAgICAgICBvYmplY3Quc3RyaW5ncyA9IFtdO1xuICAgICAgICBvYmplY3QudGVuc29ycyA9IFtdO1xuICAgICAgICBvYmplY3QuZ3JhcGhzID0gW107XG4gICAgICAgIG9iamVjdC50eXBlUHJvdG9zID0gW107XG4gICAgICAgIG9iamVjdC5zcGFyc2VUZW5zb3JzID0gW107XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QubmFtZSA9ICcnO1xuICAgICAgICBvYmplY3QuZiA9IDA7XG4gICAgICAgIGlmICgkdXRpbC5Mb25nKSB7XG4gICAgICAgICAgdmFyIGxvbmcgPSBuZXcgJHV0aWwuTG9uZygwLCAwLCBmYWxzZSk7XG4gICAgICAgICAgb2JqZWN0LmkgPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBsb25nLnRvU3RyaW5nKCkgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBsb25nLnRvTnVtYmVyKCkgOiBsb25nO1xuICAgICAgICB9IGVsc2Ugb2JqZWN0LmkgPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyAnMCcgOiAwO1xuICAgICAgICBpZiAob3B0aW9ucy5ieXRlcyA9PT0gU3RyaW5nKSBvYmplY3QucyA9ICcnO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBvYmplY3QucyA9IFtdO1xuICAgICAgICAgIGlmIChvcHRpb25zLmJ5dGVzICE9PSBBcnJheSkgb2JqZWN0LnMgPSAkdXRpbC5uZXdCdWZmZXIob2JqZWN0LnMpO1xuICAgICAgICB9XG4gICAgICAgIG9iamVjdC50ID0gbnVsbDtcbiAgICAgICAgb2JqZWN0LmcgPSBudWxsO1xuICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gJyc7XG4gICAgICAgIG9iamVjdC50cCA9IG51bGw7XG4gICAgICAgIG9iamVjdC50eXBlID0gb3B0aW9ucy5lbnVtcyA9PT0gU3RyaW5nID8gJ1VOREVGSU5FRCcgOiAwO1xuICAgICAgICBvYmplY3QucmVmQXR0ck5hbWUgPSAnJztcbiAgICAgICAgb2JqZWN0LnNwYXJzZVRlbnNvciA9IG51bGw7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpKSBvYmplY3QubmFtZSA9IG1lc3NhZ2UubmFtZTtcbiAgICAgIGlmIChtZXNzYWdlLmYgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdmJykpXG4gICAgICAgIG9iamVjdC5mID0gb3B0aW9ucy5qc29uICYmICFpc0Zpbml0ZShtZXNzYWdlLmYpID8gU3RyaW5nKG1lc3NhZ2UuZikgOiBtZXNzYWdlLmY7XG4gICAgICBpZiAobWVzc2FnZS5pICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaScpKVxuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuaSA9PT0gJ251bWJlcicpIG9iamVjdC5pID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuaSkgOiBtZXNzYWdlLmk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBvYmplY3QuaSA9XG4gICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuaSlcbiAgICAgICAgICAgICAgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXJcbiAgICAgICAgICAgICAgICA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmkubG93ID4+PiAwLCBtZXNzYWdlLmkuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgIDogbWVzc2FnZS5pO1xuICAgICAgaWYgKG1lc3NhZ2UucyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3MnKSlcbiAgICAgICAgb2JqZWN0LnMgPVxuICAgICAgICAgIG9wdGlvbnMuYnl0ZXMgPT09IFN0cmluZ1xuICAgICAgICAgICAgPyAkdXRpbC5iYXNlNjQuZW5jb2RlKG1lc3NhZ2UucywgMCwgbWVzc2FnZS5zLmxlbmd0aClcbiAgICAgICAgICAgIDogb3B0aW9ucy5ieXRlcyA9PT0gQXJyYXlcbiAgICAgICAgICAgICAgPyBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChtZXNzYWdlLnMpXG4gICAgICAgICAgICAgIDogbWVzc2FnZS5zO1xuICAgICAgaWYgKG1lc3NhZ2UudCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3QnKSlcbiAgICAgICAgb2JqZWN0LnQgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2UudCwgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZycpKVxuICAgICAgICBvYmplY3QuZyA9ICRyb290Lm9ubnguR3JhcGhQcm90by50b09iamVjdChtZXNzYWdlLmcsIG9wdGlvbnMpO1xuICAgICAgaWYgKG1lc3NhZ2UuZmxvYXRzICYmIG1lc3NhZ2UuZmxvYXRzLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuZmxvYXRzID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5mbG9hdHMubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LmZsb2F0c1tqXSA9XG4gICAgICAgICAgICBvcHRpb25zLmpzb24gJiYgIWlzRmluaXRlKG1lc3NhZ2UuZmxvYXRzW2pdKSA/IFN0cmluZyhtZXNzYWdlLmZsb2F0c1tqXSkgOiBtZXNzYWdlLmZsb2F0c1tqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmludHMgJiYgbWVzc2FnZS5pbnRzLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuaW50cyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW50cy5sZW5ndGg7ICsrailcbiAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuaW50c1tqXSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICBvYmplY3QuaW50c1tqXSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmludHNbal0pIDogbWVzc2FnZS5pbnRzW2pdO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIG9iamVjdC5pbnRzW2pdID1cbiAgICAgICAgICAgICAgb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuaW50c1tqXSlcbiAgICAgICAgICAgICAgICA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlclxuICAgICAgICAgICAgICAgICAgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS5pbnRzW2pdLmxvdyA+Pj4gMCwgbWVzc2FnZS5pbnRzW2pdLmhpZ2ggPj4+IDApLnRvTnVtYmVyKClcbiAgICAgICAgICAgICAgICAgIDogbWVzc2FnZS5pbnRzW2pdO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uuc3RyaW5ncyAmJiBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5zdHJpbmdzID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5zdHJpbmdzLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5zdHJpbmdzW2pdID1cbiAgICAgICAgICAgIG9wdGlvbnMuYnl0ZXMgPT09IFN0cmluZ1xuICAgICAgICAgICAgICA/ICR1dGlsLmJhc2U2NC5lbmNvZGUobWVzc2FnZS5zdHJpbmdzW2pdLCAwLCBtZXNzYWdlLnN0cmluZ3Nbal0ubGVuZ3RoKVxuICAgICAgICAgICAgICA6IG9wdGlvbnMuYnl0ZXMgPT09IEFycmF5XG4gICAgICAgICAgICAgICAgPyBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChtZXNzYWdlLnN0cmluZ3Nbal0pXG4gICAgICAgICAgICAgICAgOiBtZXNzYWdlLnN0cmluZ3Nbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS50ZW5zb3JzICYmIG1lc3NhZ2UudGVuc29ycy5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LnRlbnNvcnMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnRlbnNvcnMubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LnRlbnNvcnNbal0gPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2UudGVuc29yc1tqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5ncmFwaHMgJiYgbWVzc2FnZS5ncmFwaHMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5ncmFwaHMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmdyYXBocy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuZ3JhcGhzW2pdID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZ3JhcGhzW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKSBvYmplY3QuZG9jU3RyaW5nID0gbWVzc2FnZS5kb2NTdHJpbmc7XG4gICAgICBpZiAobWVzc2FnZS50cCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3RwJykpXG4gICAgICAgIG9iamVjdC50cCA9ICRyb290Lm9ubnguVHlwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UudHAsIG9wdGlvbnMpO1xuICAgICAgaWYgKG1lc3NhZ2UudHlwZVByb3RvcyAmJiBtZXNzYWdlLnR5cGVQcm90b3MubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC50eXBlUHJvdG9zID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS50eXBlUHJvdG9zLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC50eXBlUHJvdG9zW2pdID0gJHJvb3Qub25ueC5UeXBlUHJvdG8udG9PYmplY3QobWVzc2FnZS50eXBlUHJvdG9zW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0eXBlJykpXG4gICAgICAgIG9iamVjdC50eXBlID1cbiAgICAgICAgICBvcHRpb25zLmVudW1zID09PSBTdHJpbmdcbiAgICAgICAgICAgID8gJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlW21lc3NhZ2UudHlwZV0gPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICA/IG1lc3NhZ2UudHlwZVxuICAgICAgICAgICAgICA6ICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZVttZXNzYWdlLnR5cGVdXG4gICAgICAgICAgICA6IG1lc3NhZ2UudHlwZTtcbiAgICAgIGlmIChtZXNzYWdlLnJlZkF0dHJOYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncmVmQXR0ck5hbWUnKSlcbiAgICAgICAgb2JqZWN0LnJlZkF0dHJOYW1lID0gbWVzc2FnZS5yZWZBdHRyTmFtZTtcbiAgICAgIGlmIChtZXNzYWdlLnNwYXJzZVRlbnNvciAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NwYXJzZVRlbnNvcicpKVxuICAgICAgICBvYmplY3Quc3BhcnNlVGVuc29yID0gJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by50b09iamVjdChtZXNzYWdlLnNwYXJzZVRlbnNvciwgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VUZW5zb3JzICYmIG1lc3NhZ2Uuc3BhcnNlVGVuc29ycy5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LnNwYXJzZVRlbnNvcnMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnNwYXJzZVRlbnNvcnMubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LnNwYXJzZVRlbnNvcnNbal0gPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uuc3BhcnNlVGVuc29yc1tqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIEF0dHJpYnV0ZVByb3RvIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguQXR0cmlidXRlUHJvdG8nO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVUeXBlIGVudW0uXG4gICAgICogQG5hbWUgb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlXG4gICAgICogQGVudW0ge251bWJlcn1cbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gVU5ERUZJTkVEPTAgVU5ERUZJTkVEIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IEZMT0FUPTEgRkxPQVQgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UPTIgSU5UIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFNUUklORz0zIFNUUklORyB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBURU5TT1I9NCBURU5TT1IgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gR1JBUEg9NSBHUkFQSCB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBTUEFSU0VfVEVOU09SPTExIFNQQVJTRV9URU5TT1IgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gVFlQRV9QUk9UTz0xMyBUWVBFX1BST1RPIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IEZMT0FUUz02IEZMT0FUUyB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJTlRTPTcgSU5UUyB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBTVFJJTkdTPTggU1RSSU5HUyB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBURU5TT1JTPTkgVEVOU09SUyB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBHUkFQSFM9MTAgR1JBUEhTIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFNQQVJTRV9URU5TT1JTPTEyIFNQQVJTRV9URU5TT1JTIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFRZUEVfUFJPVE9TPTE0IFRZUEVfUFJPVE9TIHZhbHVlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsdWVzQnlJZCA9IHt9LFxuICAgICAgICB2YWx1ZXMgPSBPYmplY3QuY3JlYXRlKHZhbHVlc0J5SWQpO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzBdID0gJ1VOREVGSU5FRCcpXSA9IDA7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMV0gPSAnRkxPQVQnKV0gPSAxO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzJdID0gJ0lOVCcpXSA9IDI7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbM10gPSAnU1RSSU5HJyldID0gMztcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFs0XSA9ICdURU5TT1InKV0gPSA0O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzVdID0gJ0dSQVBIJyldID0gNTtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxMV0gPSAnU1BBUlNFX1RFTlNPUicpXSA9IDExO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzEzXSA9ICdUWVBFX1BST1RPJyldID0gMTM7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbNl0gPSAnRkxPQVRTJyldID0gNjtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFs3XSA9ICdJTlRTJyldID0gNztcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFs4XSA9ICdTVFJJTkdTJyldID0gODtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFs5XSA9ICdURU5TT1JTJyldID0gOTtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxMF0gPSAnR1JBUEhTJyldID0gMTA7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTJdID0gJ1NQQVJTRV9URU5TT1JTJyldID0gMTI7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTRdID0gJ1RZUEVfUFJPVE9TJyldID0gMTQ7XG4gICAgICByZXR1cm4gdmFsdWVzO1xuICAgIH0pKCk7XG5cbiAgICByZXR1cm4gQXR0cmlidXRlUHJvdG87XG4gIH0pKCk7XG5cbiAgb25ueC5WYWx1ZUluZm9Qcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhIFZhbHVlSW5mb1Byb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGludGVyZmFjZSBJVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbbmFtZV0gVmFsdWVJbmZvUHJvdG8gbmFtZVxuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JVHlwZVByb3RvfG51bGx9IFt0eXBlXSBWYWx1ZUluZm9Qcm90byB0eXBlXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvY1N0cmluZ10gVmFsdWVJbmZvUHJvdG8gZG9jU3RyaW5nXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFZhbHVlSW5mb1Byb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgVmFsdWVJbmZvUHJvdG8uXG4gICAgICogQGltcGxlbWVudHMgSVZhbHVlSW5mb1Byb3RvXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvbm54LklWYWx1ZUluZm9Qcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIFZhbHVlSW5mb1Byb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZUluZm9Qcm90byBuYW1lLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gbmFtZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8ucHJvdG90eXBlLm5hbWUgPSAnJztcblxuICAgIC8qKlxuICAgICAqIFZhbHVlSW5mb1Byb3RvIHR5cGUuXG4gICAgICogQG1lbWJlciB7b25ueC5JVHlwZVByb3RvfG51bGx8dW5kZWZpbmVkfSB0eXBlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBWYWx1ZUluZm9Qcm90by5wcm90b3R5cGUudHlwZSA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZUluZm9Qcm90byBkb2NTdHJpbmcuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBkb2NTdHJpbmdcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFZhbHVlSW5mb1Byb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSAnJztcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgVmFsdWVJbmZvUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVZhbHVlSW5mb1Byb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguVmFsdWVJbmZvUHJvdG99IFZhbHVlSW5mb1Byb3RvIGluc3RhbmNlXG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgVmFsdWVJbmZvUHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBWYWx1ZUluZm9Qcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlZhbHVlSW5mb1Byb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVZhbHVlSW5mb1Byb3RvfSBtZXNzYWdlIFZhbHVlSW5mb1Byb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBWYWx1ZUluZm9Qcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnbmFtZScpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovIDEwKS5zdHJpbmcobWVzc2FnZS5uYW1lKTtcbiAgICAgIGlmIChtZXNzYWdlLnR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAndHlwZScpKVxuICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5lbmNvZGUobWVzc2FnZS50eXBlLCB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovIDE4KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RvY1N0cmluZycpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDIgPSovIDI2KS5zdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFZhbHVlSW5mb1Byb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVmFsdWVJbmZvUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVmFsdWVJbmZvUHJvdG99IG1lc3NhZ2UgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFZhbHVlSW5mb1Byb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5WYWx1ZUluZm9Qcm90b30gVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFZhbHVlSW5mb1Byb3RvLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgbWVzc2FnZS5uYW1lID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgbWVzc2FnZS50eXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDM6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBWYWx1ZUluZm9Qcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcmV0dXJucyB7b25ueC5WYWx1ZUluZm9Qcm90b30gVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFZhbHVlSW5mb1Byb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVmVyaWZpZXMgYSBWYWx1ZUluZm9Qcm90byBtZXNzYWdlLlxuICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIFZhbHVlSW5mb1Byb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCduYW1lJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5uYW1lKSkgcmV0dXJuICduYW1lOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UudHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3R5cGUnKSkge1xuICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by52ZXJpZnkobWVzc2FnZS50eXBlKTtcbiAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3R5cGUuJyArIGVycm9yO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9jU3RyaW5nJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpKSByZXR1cm4gJ2RvY1N0cmluZzogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54LlZhbHVlSW5mb1Byb3RvfSBWYWx1ZUluZm9Qcm90b1xuICAgICAqL1xuICAgIFZhbHVlSW5mb1Byb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvKCk7XG4gICAgICBpZiAob2JqZWN0Lm5hbWUgIT0gbnVsbCkgbWVzc2FnZS5uYW1lID0gU3RyaW5nKG9iamVjdC5uYW1lKTtcbiAgICAgIGlmIChvYmplY3QudHlwZSAhPSBudWxsKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnR5cGUgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlZhbHVlSW5mb1Byb3RvLnR5cGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC50eXBlKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZG9jU3RyaW5nICE9IG51bGwpIG1lc3NhZ2UuZG9jU3RyaW5nID0gU3RyaW5nKG9iamVjdC5kb2NTdHJpbmcpO1xuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFZhbHVlSW5mb1Byb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguVmFsdWVJbmZvUHJvdG99IG1lc3NhZ2UgVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAqL1xuICAgIFZhbHVlSW5mb1Byb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QubmFtZSA9ICcnO1xuICAgICAgICBvYmplY3QudHlwZSA9IG51bGw7XG4gICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSAnJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCduYW1lJykpIG9iamVjdC5uYW1lID0gbWVzc2FnZS5uYW1lO1xuICAgICAgaWYgKG1lc3NhZ2UudHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3R5cGUnKSlcbiAgICAgICAgb2JqZWN0LnR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by50b09iamVjdChtZXNzYWdlLnR5cGUsIG9wdGlvbnMpO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9jU3RyaW5nJykpIG9iamVjdC5kb2NTdHJpbmcgPSBtZXNzYWdlLmRvY1N0cmluZztcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgVmFsdWVJbmZvUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBWYWx1ZUluZm9Qcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBWYWx1ZUluZm9Qcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5WYWx1ZUluZm9Qcm90byc7XG4gICAgfTtcblxuICAgIHJldHVybiBWYWx1ZUluZm9Qcm90bztcbiAgfSkoKTtcblxuICBvbm54Lk5vZGVQcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhIE5vZGVQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSU5vZGVQcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPHN0cmluZz58bnVsbH0gW2lucHV0XSBOb2RlUHJvdG8gaW5wdXRcbiAgICAgKiBAcHJvcGVydHkge0FycmF5LjxzdHJpbmc+fG51bGx9IFtvdXRwdXRdIE5vZGVQcm90byBvdXRwdXRcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbbmFtZV0gTm9kZVByb3RvIG5hbWVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbb3BUeXBlXSBOb2RlUHJvdG8gb3BUeXBlXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvbWFpbl0gTm9kZVByb3RvIGRvbWFpblxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSUF0dHJpYnV0ZVByb3RvPnxudWxsfSBbYXR0cmlidXRlXSBOb2RlUHJvdG8gYXR0cmlidXRlXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvY1N0cmluZ10gTm9kZVByb3RvIGRvY1N0cmluZ1xuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBOb2RlUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBOb2RlUHJvdG8uXG4gICAgICogQGltcGxlbWVudHMgSU5vZGVQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JTm9kZVByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICovXG4gICAgZnVuY3Rpb24gTm9kZVByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgIHRoaXMuaW5wdXQgPSBbXTtcbiAgICAgIHRoaXMub3V0cHV0ID0gW107XG4gICAgICB0aGlzLmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE5vZGVQcm90byBpbnB1dC5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48c3RyaW5nPn0gaW5wdXRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8ucHJvdG90eXBlLmlucHV0ID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIE5vZGVQcm90byBvdXRwdXQuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPHN0cmluZz59IG91dHB1dFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE5vZGVQcm90by5wcm90b3R5cGUub3V0cHV0ID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIE5vZGVQcm90byBuYW1lLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gbmFtZVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE5vZGVQcm90by5wcm90b3R5cGUubmFtZSA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogTm9kZVByb3RvIG9wVHlwZS5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IG9wVHlwZVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE5vZGVQcm90by5wcm90b3R5cGUub3BUeXBlID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBOb2RlUHJvdG8gZG9tYWluLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9tYWluXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTm9kZVByb3RvLnByb3RvdHlwZS5kb21haW4gPSAnJztcblxuICAgIC8qKlxuICAgICAqIE5vZGVQcm90byBhdHRyaWJ1dGUuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSUF0dHJpYnV0ZVByb3RvPn0gYXR0cmlidXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTm9kZVByb3RvLnByb3RvdHlwZS5hdHRyaWJ1dGUgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogTm9kZVByb3RvIGRvY1N0cmluZy5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE5vZGVQcm90by5wcm90b3R5cGUuZG9jU3RyaW5nID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IE5vZGVQcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSU5vZGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtvbm54Lk5vZGVQcm90b30gTm9kZVByb3RvIGluc3RhbmNlXG4gICAgICovXG4gICAgTm9kZVByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbmV3IE5vZGVQcm90byhwcm9wZXJ0aWVzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE5vZGVQcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54Lk5vZGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JTm9kZVByb3RvfSBtZXNzYWdlIE5vZGVQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgTm9kZVByb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgIT0gbnVsbCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmlucHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8gMTApLnN0cmluZyhtZXNzYWdlLmlucHV0W2ldKTtcbiAgICAgIGlmIChtZXNzYWdlLm91dHB1dCAhPSBudWxsICYmIG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm91dHB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovIDE4KS5zdHJpbmcobWVzc2FnZS5vdXRwdXRbaV0pO1xuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICduYW1lJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMywgd2lyZVR5cGUgMiA9Ki8gMjYpLnN0cmluZyhtZXNzYWdlLm5hbWUpO1xuICAgICAgaWYgKG1lc3NhZ2Uub3BUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ29wVHlwZScpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDQsIHdpcmVUeXBlIDIgPSovIDM0KS5zdHJpbmcobWVzc2FnZS5vcFR5cGUpO1xuICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlICE9IG51bGwgJiYgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGVbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDUsIHdpcmVUeXBlIDIgPSovIDQyKS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkb2NTdHJpbmcnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA2LCB3aXJlVHlwZSAyID0qLyA1MCkuc3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKTtcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkb21haW4nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA3LCB3aXJlVHlwZSAyID0qLyA1OCkuc3RyaW5nKG1lc3NhZ2UuZG9tYWluKTtcbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBOb2RlUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5Ob2RlUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSU5vZGVQcm90b30gbWVzc2FnZSBOb2RlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIE5vZGVQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIE5vZGVQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5Ob2RlUHJvdG99IE5vZGVQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgTm9kZVByb3RvLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54Lk5vZGVQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuaW5wdXQgJiYgbWVzc2FnZS5pbnB1dC5sZW5ndGgpKSBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmlucHV0LnB1c2gocmVhZGVyLnN0cmluZygpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uub3V0cHV0ICYmIG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aCkpIG1lc3NhZ2Uub3V0cHV0ID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLm91dHB1dC5wdXNoKHJlYWRlci5zdHJpbmcoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAzOiB7XG4gICAgICAgICAgICBtZXNzYWdlLm5hbWUgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA0OiB7XG4gICAgICAgICAgICBtZXNzYWdlLm9wVHlwZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDc6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZG9tYWluID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5hdHRyaWJ1dGUgJiYgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoKSkgbWVzc2FnZS5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuYXR0cmlidXRlLnB1c2goJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDY6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBOb2RlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54Lk5vZGVQcm90b30gTm9kZVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIE5vZGVQcm90byBtZXNzYWdlLlxuICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpbnB1dCcpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmlucHV0KSkgcmV0dXJuICdpbnB1dDogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW5wdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmlucHV0W2ldKSkgcmV0dXJuICdpbnB1dDogc3RyaW5nW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnb3V0cHV0JykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uub3V0cHV0KSkgcmV0dXJuICdvdXRwdXQ6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm91dHB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2Uub3V0cHV0W2ldKSkgcmV0dXJuICdvdXRwdXQ6IHN0cmluZ1tdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCduYW1lJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5uYW1lKSkgcmV0dXJuICduYW1lOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2Uub3BUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnb3BUeXBlJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5vcFR5cGUpKSByZXR1cm4gJ29wVHlwZTogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvbWFpbicpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9tYWluKSkgcmV0dXJuICdkb21haW46IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdhdHRyaWJ1dGUnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5hdHRyaWJ1dGUpKSByZXR1cm4gJ2F0dHJpYnV0ZTogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by52ZXJpZnkobWVzc2FnZS5hdHRyaWJ1dGVbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdhdHRyaWJ1dGUuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvY1N0cmluZykpIHJldHVybiAnZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBOb2RlUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5Ob2RlUHJvdG99IE5vZGVQcm90b1xuICAgICAqL1xuICAgIE5vZGVQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54Lk5vZGVQcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguTm9kZVByb3RvKCk7XG4gICAgICBpZiAob2JqZWN0LmlucHV0KSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuaW5wdXQpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54Lk5vZGVQcm90by5pbnB1dDogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5pbnB1dCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5pbnB1dC5sZW5ndGg7ICsraSkgbWVzc2FnZS5pbnB1dFtpXSA9IFN0cmluZyhvYmplY3QuaW5wdXRbaV0pO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5vdXRwdXQpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5vdXRwdXQpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54Lk5vZGVQcm90by5vdXRwdXQ6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2Uub3V0cHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lm91dHB1dC5sZW5ndGg7ICsraSkgbWVzc2FnZS5vdXRwdXRbaV0gPSBTdHJpbmcob2JqZWN0Lm91dHB1dFtpXSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0Lm5hbWUgIT0gbnVsbCkgbWVzc2FnZS5uYW1lID0gU3RyaW5nKG9iamVjdC5uYW1lKTtcbiAgICAgIGlmIChvYmplY3Qub3BUeXBlICE9IG51bGwpIG1lc3NhZ2Uub3BUeXBlID0gU3RyaW5nKG9iamVjdC5vcFR5cGUpO1xuICAgICAgaWYgKG9iamVjdC5kb21haW4gIT0gbnVsbCkgbWVzc2FnZS5kb21haW4gPSBTdHJpbmcob2JqZWN0LmRvbWFpbik7XG4gICAgICBpZiAob2JqZWN0LmF0dHJpYnV0ZSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmF0dHJpYnV0ZSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguTm9kZVByb3RvLmF0dHJpYnV0ZTogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuYXR0cmlidXRlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuYXR0cmlidXRlW2ldICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Ob2RlUHJvdG8uYXR0cmlidXRlOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZVtpXSA9ICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8uZnJvbU9iamVjdChvYmplY3QuYXR0cmlidXRlW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5kb2NTdHJpbmcgIT0gbnVsbCkgbWVzc2FnZS5kb2NTdHJpbmcgPSBTdHJpbmcob2JqZWN0LmRvY1N0cmluZyk7XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgTm9kZVByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54Lk5vZGVQcm90b30gbWVzc2FnZSBOb2RlUHJvdG9cbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAqL1xuICAgIE5vZGVQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0LmlucHV0ID0gW107XG4gICAgICAgIG9iamVjdC5vdXRwdXQgPSBbXTtcbiAgICAgICAgb2JqZWN0LmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0Lm5hbWUgPSAnJztcbiAgICAgICAgb2JqZWN0Lm9wVHlwZSA9ICcnO1xuICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gJyc7XG4gICAgICAgIG9iamVjdC5kb21haW4gPSAnJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmlucHV0ICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5pbnB1dCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW5wdXQubGVuZ3RoOyArK2opIG9iamVjdC5pbnB1dFtqXSA9IG1lc3NhZ2UuaW5wdXRbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5vdXRwdXQgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5vdXRwdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLm91dHB1dC5sZW5ndGg7ICsraikgb2JqZWN0Lm91dHB1dFtqXSA9IG1lc3NhZ2Uub3V0cHV0W2pdO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSkgb2JqZWN0Lm5hbWUgPSBtZXNzYWdlLm5hbWU7XG4gICAgICBpZiAobWVzc2FnZS5vcFR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdvcFR5cGUnKSkgb2JqZWN0Lm9wVHlwZSA9IG1lc3NhZ2Uub3BUeXBlO1xuICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlICYmIG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuYXR0cmlidXRlID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LmF0dHJpYnV0ZVtqXSA9ICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8udG9PYmplY3QobWVzc2FnZS5hdHRyaWJ1dGVbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9jU3RyaW5nJykpIG9iamVjdC5kb2NTdHJpbmcgPSBtZXNzYWdlLmRvY1N0cmluZztcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvbWFpbicpKSBvYmplY3QuZG9tYWluID0gbWVzc2FnZS5kb21haW47XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIE5vZGVQcm90byB0byBKU09OLlxuICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgTm9kZVByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgTm9kZVByb3RvXG4gICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguTm9kZVByb3RvJztcbiAgICB9O1xuXG4gICAgcmV0dXJuIE5vZGVQcm90bztcbiAgfSkoKTtcblxuICBvbm54LlRyYWluaW5nSW5mb1Byb3RvID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgVHJhaW5pbmdJbmZvUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElUcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JR3JhcGhQcm90b3xudWxsfSBbaW5pdGlhbGl6YXRpb25dIFRyYWluaW5nSW5mb1Byb3RvIGluaXRpYWxpemF0aW9uXG4gICAgICogQHByb3BlcnR5IHtvbm54LklHcmFwaFByb3RvfG51bGx9IFthbGdvcml0aG1dIFRyYWluaW5nSW5mb1Byb3RvIGFsZ29yaXRobVxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fG51bGx9IFtpbml0aWFsaXphdGlvbkJpbmRpbmddIFRyYWluaW5nSW5mb1Byb3RvIGluaXRpYWxpemF0aW9uQmluZGluZ1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fG51bGx9IFt1cGRhdGVCaW5kaW5nXSBUcmFpbmluZ0luZm9Qcm90byB1cGRhdGVCaW5kaW5nXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFRyYWluaW5nSW5mb1Byb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgVHJhaW5pbmdJbmZvUHJvdG8uXG4gICAgICogQGltcGxlbWVudHMgSVRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvbm54LklUcmFpbmluZ0luZm9Qcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIFRyYWluaW5nSW5mb1Byb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgIHRoaXMuaW5pdGlhbGl6YXRpb25CaW5kaW5nID0gW107XG4gICAgICB0aGlzLnVwZGF0ZUJpbmRpbmcgPSBbXTtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmFpbmluZ0luZm9Qcm90byBpbml0aWFsaXphdGlvbi5cbiAgICAgKiBAbWVtYmVyIHtvbm54LklHcmFwaFByb3RvfG51bGx8dW5kZWZpbmVkfSBpbml0aWFsaXphdGlvblxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8ucHJvdG90eXBlLmluaXRpYWxpemF0aW9uID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFRyYWluaW5nSW5mb1Byb3RvIGFsZ29yaXRobS5cbiAgICAgKiBAbWVtYmVyIHtvbm54LklHcmFwaFByb3RvfG51bGx8dW5kZWZpbmVkfSBhbGdvcml0aG1cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRyYWluaW5nSW5mb1Byb3RvLnByb3RvdHlwZS5hbGdvcml0aG0gPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVHJhaW5pbmdJbmZvUHJvdG8gaW5pdGlhbGl6YXRpb25CaW5kaW5nLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvPn0gaW5pdGlhbGl6YXRpb25CaW5kaW5nXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by5wcm90b3R5cGUuaW5pdGlhbGl6YXRpb25CaW5kaW5nID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIFRyYWluaW5nSW5mb1Byb3RvIHVwZGF0ZUJpbmRpbmcuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fSB1cGRhdGVCaW5kaW5nXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by5wcm90b3R5cGUudXBkYXRlQmluZGluZyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IFRyYWluaW5nSW5mb1Byb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUcmFpbmluZ0luZm9Qcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRyYWluaW5nSW5mb1Byb3RvfSBUcmFpbmluZ0luZm9Qcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRyYWluaW5nSW5mb1Byb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbmV3IFRyYWluaW5nSW5mb1Byb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVHJhaW5pbmdJbmZvUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UcmFpbmluZ0luZm9Qcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUcmFpbmluZ0luZm9Qcm90b30gbWVzc2FnZSBUcmFpbmluZ0luZm9Qcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXphdGlvbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdpbml0aWFsaXphdGlvbicpKVxuICAgICAgICAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZW5jb2RlKG1lc3NhZ2UuaW5pdGlhbGl6YXRpb24sIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8gMTApLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5hbGdvcml0aG0gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnYWxnb3JpdGhtJykpXG4gICAgICAgICRyb290Lm9ubnguR3JhcGhQcm90by5lbmNvZGUobWVzc2FnZS5hbGdvcml0aG0sIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZy5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAzLCB3aXJlVHlwZSAyID0qLyAyNikuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS51cGRhdGVCaW5kaW5nICE9IG51bGwgJiYgbWVzc2FnZS51cGRhdGVCaW5kaW5nLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnVwZGF0ZUJpbmRpbmcubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UudXBkYXRlQmluZGluZ1tpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNCwgd2lyZVR5cGUgMiA9Ki8gMzQpLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRyYWluaW5nSW5mb1Byb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHJhaW5pbmdJbmZvUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVHJhaW5pbmdJbmZvUHJvdG99IG1lc3NhZ2UgVHJhaW5pbmdJbmZvUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFRyYWluaW5nSW5mb1Byb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVHJhaW5pbmdJbmZvUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5UcmFpbmluZ0luZm9Qcm90b30gVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFRyYWluaW5nSW5mb1Byb3RvLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRyYWluaW5nSW5mb1Byb3RvKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXphdGlvbiA9ICRyb290Lm9ubnguR3JhcGhQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgbWVzc2FnZS5hbGdvcml0aG0gPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDM6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nICYmIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nLmxlbmd0aCkpXG4gICAgICAgICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZy5wdXNoKCRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDQ6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UudXBkYXRlQmluZGluZyAmJiBtZXNzYWdlLnVwZGF0ZUJpbmRpbmcubGVuZ3RoKSkgbWVzc2FnZS51cGRhdGVCaW5kaW5nID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnVwZGF0ZUJpbmRpbmcucHVzaCgkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFRyYWluaW5nSW5mb1Byb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LlRyYWluaW5nSW5mb1Byb3RvfSBUcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIFRyYWluaW5nSW5mb1Byb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuaW5pdGlhbGl6YXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpbml0aWFsaXphdGlvbicpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguR3JhcGhQcm90by52ZXJpZnkobWVzc2FnZS5pbml0aWFsaXphdGlvbik7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdpbml0aWFsaXphdGlvbi4nICsgZXJyb3I7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5hbGdvcml0aG0gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdhbGdvcml0aG0nKSkge1xuICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udmVyaWZ5KG1lc3NhZ2UuYWxnb3JpdGhtKTtcbiAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2FsZ29yaXRobS4nICsgZXJyb3I7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpbml0aWFsaXphdGlvbkJpbmRpbmcnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcpKSByZXR1cm4gJ2luaXRpYWxpemF0aW9uQmluZGluZzogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnZlcmlmeShtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZ1tpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2luaXRpYWxpemF0aW9uQmluZGluZy4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnVwZGF0ZUJpbmRpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd1cGRhdGVCaW5kaW5nJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UudXBkYXRlQmluZGluZykpIHJldHVybiAndXBkYXRlQmluZGluZzogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudXBkYXRlQmluZGluZy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by52ZXJpZnkobWVzc2FnZS51cGRhdGVCaW5kaW5nW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAndXBkYXRlQmluZGluZy4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgVHJhaW5pbmdJbmZvUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRyYWluaW5nSW5mb1Byb3RvfSBUcmFpbmluZ0luZm9Qcm90b1xuICAgICAqL1xuICAgIFRyYWluaW5nSW5mb1Byb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVHJhaW5pbmdJbmZvUHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRyYWluaW5nSW5mb1Byb3RvKCk7XG4gICAgICBpZiAob2JqZWN0LmluaXRpYWxpemF0aW9uICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuaW5pdGlhbGl6YXRpb24gIT09ICdvYmplY3QnKVxuICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguVHJhaW5pbmdJbmZvUHJvdG8uaW5pdGlhbGl6YXRpb246IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmluaXRpYWxpemF0aW9uID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmZyb21PYmplY3Qob2JqZWN0LmluaXRpYWxpemF0aW9uKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuYWxnb3JpdGhtICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuYWxnb3JpdGhtICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UcmFpbmluZ0luZm9Qcm90by5hbGdvcml0aG06IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmFsZ29yaXRobSA9ICRyb290Lm9ubnguR3JhcGhQcm90by5mcm9tT2JqZWN0KG9iamVjdC5hbGdvcml0aG0pO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5pbml0aWFsaXphdGlvbkJpbmRpbmcpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5pbml0aWFsaXphdGlvbkJpbmRpbmcpKVxuICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguVHJhaW5pbmdJbmZvUHJvdG8uaW5pdGlhbGl6YXRpb25CaW5kaW5nOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5pbml0aWFsaXphdGlvbkJpbmRpbmcubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5pbml0aWFsaXphdGlvbkJpbmRpbmdbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UcmFpbmluZ0luZm9Qcm90by5pbml0aWFsaXphdGlvbkJpbmRpbmc6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nW2ldID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmZyb21PYmplY3QoXG4gICAgICAgICAgICBvYmplY3QuaW5pdGlhbGl6YXRpb25CaW5kaW5nW2ldLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QudXBkYXRlQmluZGluZykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnVwZGF0ZUJpbmRpbmcpKVxuICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguVHJhaW5pbmdJbmZvUHJvdG8udXBkYXRlQmluZGluZzogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS51cGRhdGVCaW5kaW5nID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LnVwZGF0ZUJpbmRpbmcubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC51cGRhdGVCaW5kaW5nW2ldICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguVHJhaW5pbmdJbmZvUHJvdG8udXBkYXRlQmluZGluZzogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS51cGRhdGVCaW5kaW5nW2ldID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmZyb21PYmplY3Qob2JqZWN0LnVwZGF0ZUJpbmRpbmdbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgVHJhaW5pbmdJbmZvUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5UcmFpbmluZ0luZm9Qcm90b30gbWVzc2FnZSBUcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgIGlmIChvcHRpb25zLmFycmF5cyB8fCBvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5pbml0aWFsaXphdGlvbkJpbmRpbmcgPSBbXTtcbiAgICAgICAgb2JqZWN0LnVwZGF0ZUJpbmRpbmcgPSBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5pbml0aWFsaXphdGlvbiA9IG51bGw7XG4gICAgICAgIG9iamVjdC5hbGdvcml0aG0gPSBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuaW5pdGlhbGl6YXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpbml0aWFsaXphdGlvbicpKVxuICAgICAgICBvYmplY3QuaW5pdGlhbGl6YXRpb24gPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udG9PYmplY3QobWVzc2FnZS5pbml0aWFsaXphdGlvbiwgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS5hbGdvcml0aG0gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdhbGdvcml0aG0nKSlcbiAgICAgICAgb2JqZWN0LmFsZ29yaXRobSA9ICRyb290Lm9ubnguR3JhcGhQcm90by50b09iamVjdChtZXNzYWdlLmFsZ29yaXRobSwgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcgJiYgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5pbml0aWFsaXphdGlvbkJpbmRpbmcgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuaW5pdGlhbGl6YXRpb25CaW5kaW5nW2pdID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnRvT2JqZWN0KFxuICAgICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmdbal0sXG4gICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS51cGRhdGVCaW5kaW5nICYmIG1lc3NhZ2UudXBkYXRlQmluZGluZy5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LnVwZGF0ZUJpbmRpbmcgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnVwZGF0ZUJpbmRpbmcubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LnVwZGF0ZUJpbmRpbmdbal0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udG9PYmplY3QobWVzc2FnZS51cGRhdGVCaW5kaW5nW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgVHJhaW5pbmdJbmZvUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBUcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UcmFpbmluZ0luZm9Qcm90byc7XG4gICAgfTtcblxuICAgIHJldHVybiBUcmFpbmluZ0luZm9Qcm90bztcbiAgfSkoKTtcblxuICBvbm54Lk1vZGVsUHJvdG8gPSAoZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgb2YgYSBNb2RlbFByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGludGVyZmFjZSBJTW9kZWxQcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfExvbmd8bnVsbH0gW2lyVmVyc2lvbl0gTW9kZWxQcm90byBpclZlcnNpb25cbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklPcGVyYXRvclNldElkUHJvdG8+fG51bGx9IFtvcHNldEltcG9ydF0gTW9kZWxQcm90byBvcHNldEltcG9ydFxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtwcm9kdWNlck5hbWVdIE1vZGVsUHJvdG8gcHJvZHVjZXJOYW1lXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW3Byb2R1Y2VyVmVyc2lvbl0gTW9kZWxQcm90byBwcm9kdWNlclZlcnNpb25cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9tYWluXSBNb2RlbFByb3RvIGRvbWFpblxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfExvbmd8bnVsbH0gW21vZGVsVmVyc2lvbl0gTW9kZWxQcm90byBtb2RlbFZlcnNpb25cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9jU3RyaW5nXSBNb2RlbFByb3RvIGRvY1N0cmluZ1xuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JR3JhcGhQcm90b3xudWxsfSBbZ3JhcGhdIE1vZGVsUHJvdG8gZ3JhcGhcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvPnxudWxsfSBbbWV0YWRhdGFQcm9wc10gTW9kZWxQcm90byBtZXRhZGF0YVByb3BzXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JVHJhaW5pbmdJbmZvUHJvdG8+fG51bGx9IFt0cmFpbmluZ0luZm9dIE1vZGVsUHJvdG8gdHJhaW5pbmdJbmZvXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JRnVuY3Rpb25Qcm90bz58bnVsbH0gW2Z1bmN0aW9uc10gTW9kZWxQcm90byBmdW5jdGlvbnNcbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgTW9kZWxQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIE1vZGVsUHJvdG8uXG4gICAgICogQGltcGxlbWVudHMgSU1vZGVsUHJvdG9cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29ubnguSU1vZGVsUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBNb2RlbFByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgIHRoaXMub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgIHRoaXMubWV0YWRhdGFQcm9wcyA9IFtdO1xuICAgICAgdGhpcy50cmFpbmluZ0luZm8gPSBbXTtcbiAgICAgIHRoaXMuZnVuY3Rpb25zID0gW107XG4gICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTW9kZWxQcm90byBpclZlcnNpb24uXG4gICAgICogQG1lbWJlciB7bnVtYmVyfExvbmd9IGlyVmVyc2lvblxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5pclZlcnNpb24gPSAkdXRpbC5Mb25nID8gJHV0aWwuTG9uZy5mcm9tQml0cygwLCAwLCBmYWxzZSkgOiAwO1xuXG4gICAgLyoqXG4gICAgICogTW9kZWxQcm90byBvcHNldEltcG9ydC5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JT3BlcmF0b3JTZXRJZFByb3RvPn0gb3BzZXRJbXBvcnRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTW9kZWxQcm90by5wcm90b3R5cGUub3BzZXRJbXBvcnQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogTW9kZWxQcm90byBwcm9kdWNlck5hbWUuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBwcm9kdWNlck5hbWVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTW9kZWxQcm90by5wcm90b3R5cGUucHJvZHVjZXJOYW1lID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBNb2RlbFByb3RvIHByb2R1Y2VyVmVyc2lvbi5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IHByb2R1Y2VyVmVyc2lvblxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5wcm9kdWNlclZlcnNpb24gPSAnJztcblxuICAgIC8qKlxuICAgICAqIE1vZGVsUHJvdG8gZG9tYWluLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9tYWluXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLmRvbWFpbiA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogTW9kZWxQcm90byBtb2RlbFZlcnNpb24uXG4gICAgICogQG1lbWJlciB7bnVtYmVyfExvbmd9IG1vZGVsVmVyc2lvblxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5tb2RlbFZlcnNpb24gPSAkdXRpbC5Mb25nID8gJHV0aWwuTG9uZy5mcm9tQml0cygwLCAwLCBmYWxzZSkgOiAwO1xuXG4gICAgLyoqXG4gICAgICogTW9kZWxQcm90byBkb2NTdHJpbmcuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBkb2NTdHJpbmdcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTW9kZWxQcm90by5wcm90b3R5cGUuZG9jU3RyaW5nID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBNb2RlbFByb3RvIGdyYXBoLlxuICAgICAqIEBtZW1iZXIge29ubnguSUdyYXBoUHJvdG98bnVsbHx1bmRlZmluZWR9IGdyYXBoXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLmdyYXBoID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIE1vZGVsUHJvdG8gbWV0YWRhdGFQcm9wcy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz59IG1ldGFkYXRhUHJvcHNcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTW9kZWxQcm90by5wcm90b3R5cGUubWV0YWRhdGFQcm9wcyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBNb2RlbFByb3RvIHRyYWluaW5nSW5mby5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVHJhaW5pbmdJbmZvUHJvdG8+fSB0cmFpbmluZ0luZm9cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTW9kZWxQcm90by5wcm90b3R5cGUudHJhaW5pbmdJbmZvID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIE1vZGVsUHJvdG8gZnVuY3Rpb25zLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklGdW5jdGlvblByb3RvPn0gZnVuY3Rpb25zXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLmZ1bmN0aW9ucyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IE1vZGVsUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JTW9kZWxQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtvbm54Lk1vZGVsUHJvdG99IE1vZGVsUHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbmV3IE1vZGVsUHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBNb2RlbFByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguTW9kZWxQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSU1vZGVsUHJvdG99IG1lc3NhZ2UgTW9kZWxQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgTW9kZWxQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLmlyVmVyc2lvbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdpclZlcnNpb24nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAwID0qLyA4KS5pbnQ2NChtZXNzYWdlLmlyVmVyc2lvbik7XG4gICAgICBpZiAobWVzc2FnZS5wcm9kdWNlck5hbWUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAncHJvZHVjZXJOYW1lJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLnN0cmluZyhtZXNzYWdlLnByb2R1Y2VyTmFtZSk7XG4gICAgICBpZiAobWVzc2FnZS5wcm9kdWNlclZlcnNpb24gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAncHJvZHVjZXJWZXJzaW9uJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMywgd2lyZVR5cGUgMiA9Ki8gMjYpLnN0cmluZyhtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbik7XG4gICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZG9tYWluJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNCwgd2lyZVR5cGUgMiA9Ki8gMzQpLnN0cmluZyhtZXNzYWdlLmRvbWFpbik7XG4gICAgICBpZiAobWVzc2FnZS5tb2RlbFZlcnNpb24gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnbW9kZWxWZXJzaW9uJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMCA9Ki8gNDApLmludDY0KG1lc3NhZ2UubW9kZWxWZXJzaW9uKTtcbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkb2NTdHJpbmcnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA2LCB3aXJlVHlwZSAyID0qLyA1MCkuc3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKTtcbiAgICAgIGlmIChtZXNzYWdlLmdyYXBoICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2dyYXBoJykpXG4gICAgICAgICRyb290Lm9ubnguR3JhcGhQcm90by5lbmNvZGUobWVzc2FnZS5ncmFwaCwgd3JpdGVyLnVpbnQzMigvKiBpZCA3LCB3aXJlVHlwZSAyID0qLyA1OCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLm9wc2V0SW1wb3J0ICE9IG51bGwgJiYgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLm9wc2V0SW1wb3J0W2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA4LCB3aXJlVHlwZSAyID0qLyA2NikuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5tZXRhZGF0YVByb3BzICE9IG51bGwgJiYgbWVzc2FnZS5tZXRhZGF0YVByb3BzLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm1ldGFkYXRhUHJvcHMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UubWV0YWRhdGFQcm9wc1tpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTQsIHdpcmVUeXBlIDIgPSovIDExNCkuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS50cmFpbmluZ0luZm8gIT0gbnVsbCAmJiBtZXNzYWdlLnRyYWluaW5nSW5mby5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS50cmFpbmluZ0luZm8ubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5UcmFpbmluZ0luZm9Qcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLnRyYWluaW5nSW5mb1tpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMjAsIHdpcmVUeXBlIDIgPSovIDE2MikuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5mdW5jdGlvbnMgIT0gbnVsbCAmJiBtZXNzYWdlLmZ1bmN0aW9ucy5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5mdW5jdGlvbnMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5GdW5jdGlvblByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UuZnVuY3Rpb25zW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyNSwgd2lyZVR5cGUgMiA9Ki8gMjAyKS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBNb2RlbFByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguTW9kZWxQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSU1vZGVsUHJvdG99IG1lc3NhZ2UgTW9kZWxQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgTW9kZWxQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIE1vZGVsUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54Lk1vZGVsUHJvdG99IE1vZGVsUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIE1vZGVsUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguTW9kZWxQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuaXJWZXJzaW9uID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA4OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLm9wc2V0SW1wb3J0ICYmIG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoKSkgbWVzc2FnZS5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydC5wdXNoKCRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgbWVzc2FnZS5wcm9kdWNlck5hbWUgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAzOiB7XG4gICAgICAgICAgICBtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbiA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDQ6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZG9tYWluID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNToge1xuICAgICAgICAgICAgbWVzc2FnZS5tb2RlbFZlcnNpb24gPSByZWFkZXIuaW50NjQoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDY6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNzoge1xuICAgICAgICAgICAgbWVzc2FnZS5ncmFwaCA9ICRyb290Lm9ubnguR3JhcGhQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTQ6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UubWV0YWRhdGFQcm9wcyAmJiBtZXNzYWdlLm1ldGFkYXRhUHJvcHMubGVuZ3RoKSkgbWVzc2FnZS5tZXRhZGF0YVByb3BzID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLm1ldGFkYXRhUHJvcHMucHVzaCgkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAyMDoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS50cmFpbmluZ0luZm8gJiYgbWVzc2FnZS50cmFpbmluZ0luZm8ubGVuZ3RoKSkgbWVzc2FnZS50cmFpbmluZ0luZm8gPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UudHJhaW5pbmdJbmZvLnB1c2goJHJvb3Qub25ueC5UcmFpbmluZ0luZm9Qcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDI1OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmZ1bmN0aW9ucyAmJiBtZXNzYWdlLmZ1bmN0aW9ucy5sZW5ndGgpKSBtZXNzYWdlLmZ1bmN0aW9ucyA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5mdW5jdGlvbnMucHVzaCgkcm9vdC5vbm54LkZ1bmN0aW9uUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIE1vZGVsUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcmV0dXJucyB7b25ueC5Nb2RlbFByb3RvfSBNb2RlbFByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVmVyaWZpZXMgYSBNb2RlbFByb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmlyVmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2lyVmVyc2lvbicpKVxuICAgICAgICBpZiAoXG4gICAgICAgICAgISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmlyVmVyc2lvbikgJiZcbiAgICAgICAgICAhKG1lc3NhZ2UuaXJWZXJzaW9uICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmlyVmVyc2lvbi5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmlyVmVyc2lvbi5oaWdoKSlcbiAgICAgICAgKVxuICAgICAgICAgIHJldHVybiAnaXJWZXJzaW9uOiBpbnRlZ2VyfExvbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2Uub3BzZXRJbXBvcnQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdvcHNldEltcG9ydCcpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm9wc2V0SW1wb3J0KSkgcmV0dXJuICdvcHNldEltcG9ydDogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90by52ZXJpZnkobWVzc2FnZS5vcHNldEltcG9ydFtpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ29wc2V0SW1wb3J0LicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UucHJvZHVjZXJOYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncHJvZHVjZXJOYW1lJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5wcm9kdWNlck5hbWUpKSByZXR1cm4gJ3Byb2R1Y2VyTmFtZTogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3Byb2R1Y2VyVmVyc2lvbicpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uKSkgcmV0dXJuICdwcm9kdWNlclZlcnNpb246IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb21haW4nKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvbWFpbikpIHJldHVybiAnZG9tYWluOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UubW9kZWxWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbW9kZWxWZXJzaW9uJykpXG4gICAgICAgIGlmIChcbiAgICAgICAgICAhJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UubW9kZWxWZXJzaW9uKSAmJlxuICAgICAgICAgICEoXG4gICAgICAgICAgICBtZXNzYWdlLm1vZGVsVmVyc2lvbiAmJlxuICAgICAgICAgICAgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UubW9kZWxWZXJzaW9uLmxvdykgJiZcbiAgICAgICAgICAgICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLm1vZGVsVmVyc2lvbi5oaWdoKVxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgICAgIHJldHVybiAnbW9kZWxWZXJzaW9uOiBpbnRlZ2VyfExvbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9jU3RyaW5nJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpKSByZXR1cm4gJ2RvY1N0cmluZzogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmdyYXBoICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZ3JhcGgnKSkge1xuICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udmVyaWZ5KG1lc3NhZ2UuZ3JhcGgpO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnZ3JhcGguJyArIGVycm9yO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubWV0YWRhdGFQcm9wcyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ21ldGFkYXRhUHJvcHMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5tZXRhZGF0YVByb3BzKSkgcmV0dXJuICdtZXRhZGF0YVByb3BzOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5tZXRhZGF0YVByb3BzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnZlcmlmeShtZXNzYWdlLm1ldGFkYXRhUHJvcHNbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdtZXRhZGF0YVByb3BzLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudHJhaW5pbmdJbmZvICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndHJhaW5pbmdJbmZvJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UudHJhaW5pbmdJbmZvKSkgcmV0dXJuICd0cmFpbmluZ0luZm86IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnRyYWluaW5nSW5mby5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHJhaW5pbmdJbmZvUHJvdG8udmVyaWZ5KG1lc3NhZ2UudHJhaW5pbmdJbmZvW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAndHJhaW5pbmdJbmZvLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZnVuY3Rpb25zICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZnVuY3Rpb25zJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuZnVuY3Rpb25zKSkgcmV0dXJuICdmdW5jdGlvbnM6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmZ1bmN0aW9ucy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguRnVuY3Rpb25Qcm90by52ZXJpZnkobWVzc2FnZS5mdW5jdGlvbnNbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdmdW5jdGlvbnMuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIE1vZGVsUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICogQHJldHVybnMge29ubnguTW9kZWxQcm90b30gTW9kZWxQcm90b1xuICAgICAqL1xuICAgIE1vZGVsUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5Nb2RlbFByb3RvKSByZXR1cm4gb2JqZWN0O1xuICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5Nb2RlbFByb3RvKCk7XG4gICAgICBpZiAob2JqZWN0LmlyVmVyc2lvbiAhPSBudWxsKVxuICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UuaXJWZXJzaW9uID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmlyVmVyc2lvbikpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaXJWZXJzaW9uID09PSAnc3RyaW5nJykgbWVzc2FnZS5pclZlcnNpb24gPSBwYXJzZUludChvYmplY3QuaXJWZXJzaW9uLCAxMCk7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaXJWZXJzaW9uID09PSAnbnVtYmVyJykgbWVzc2FnZS5pclZlcnNpb24gPSBvYmplY3QuaXJWZXJzaW9uO1xuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmlyVmVyc2lvbiA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgbWVzc2FnZS5pclZlcnNpb24gPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmlyVmVyc2lvbi5sb3cgPj4+IDAsIG9iamVjdC5pclZlcnNpb24uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgIGlmIChvYmplY3Qub3BzZXRJbXBvcnQpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5vcHNldEltcG9ydCkpIHRocm93IFR5cGVFcnJvcignLm9ubnguTW9kZWxQcm90by5vcHNldEltcG9ydDogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5vcHNldEltcG9ydC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm9wc2V0SW1wb3J0W2ldICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguTW9kZWxQcm90by5vcHNldEltcG9ydDogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydFtpXSA9ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmZyb21PYmplY3Qob2JqZWN0Lm9wc2V0SW1wb3J0W2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5wcm9kdWNlck5hbWUgIT0gbnVsbCkgbWVzc2FnZS5wcm9kdWNlck5hbWUgPSBTdHJpbmcob2JqZWN0LnByb2R1Y2VyTmFtZSk7XG4gICAgICBpZiAob2JqZWN0LnByb2R1Y2VyVmVyc2lvbiAhPSBudWxsKSBtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbiA9IFN0cmluZyhvYmplY3QucHJvZHVjZXJWZXJzaW9uKTtcbiAgICAgIGlmIChvYmplY3QuZG9tYWluICE9IG51bGwpIG1lc3NhZ2UuZG9tYWluID0gU3RyaW5nKG9iamVjdC5kb21haW4pO1xuICAgICAgaWYgKG9iamVjdC5tb2RlbFZlcnNpb24gIT0gbnVsbClcbiAgICAgICAgaWYgKCR1dGlsLkxvbmcpIChtZXNzYWdlLm1vZGVsVmVyc2lvbiA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5tb2RlbFZlcnNpb24pKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0Lm1vZGVsVmVyc2lvbiA9PT0gJ3N0cmluZycpIG1lc3NhZ2UubW9kZWxWZXJzaW9uID0gcGFyc2VJbnQob2JqZWN0Lm1vZGVsVmVyc2lvbiwgMTApO1xuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0Lm1vZGVsVmVyc2lvbiA9PT0gJ251bWJlcicpIG1lc3NhZ2UubW9kZWxWZXJzaW9uID0gb2JqZWN0Lm1vZGVsVmVyc2lvbjtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5tb2RlbFZlcnNpb24gPT09ICdvYmplY3QnKVxuICAgICAgICAgIG1lc3NhZ2UubW9kZWxWZXJzaW9uID0gbmV3ICR1dGlsLkxvbmdCaXRzKFxuICAgICAgICAgICAgb2JqZWN0Lm1vZGVsVmVyc2lvbi5sb3cgPj4+IDAsXG4gICAgICAgICAgICBvYmplY3QubW9kZWxWZXJzaW9uLmhpZ2ggPj4+IDAsXG4gICAgICAgICAgKS50b051bWJlcigpO1xuICAgICAgaWYgKG9iamVjdC5kb2NTdHJpbmcgIT0gbnVsbCkgbWVzc2FnZS5kb2NTdHJpbmcgPSBTdHJpbmcob2JqZWN0LmRvY1N0cmluZyk7XG4gICAgICBpZiAob2JqZWN0LmdyYXBoICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZ3JhcGggIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54Lk1vZGVsUHJvdG8uZ3JhcGg6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmdyYXBoID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmZyb21PYmplY3Qob2JqZWN0LmdyYXBoKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QubWV0YWRhdGFQcm9wcykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0Lm1ldGFkYXRhUHJvcHMpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54Lk1vZGVsUHJvdG8ubWV0YWRhdGFQcm9wczogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5tZXRhZGF0YVByb3BzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lm1ldGFkYXRhUHJvcHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5tZXRhZGF0YVByb3BzW2ldICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguTW9kZWxQcm90by5tZXRhZGF0YVByb3BzOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLm1ldGFkYXRhUHJvcHNbaV0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZnJvbU9iamVjdChvYmplY3QubWV0YWRhdGFQcm9wc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QudHJhaW5pbmdJbmZvKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QudHJhaW5pbmdJbmZvKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Nb2RlbFByb3RvLnRyYWluaW5nSW5mbzogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS50cmFpbmluZ0luZm8gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QudHJhaW5pbmdJbmZvLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudHJhaW5pbmdJbmZvW2ldICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguTW9kZWxQcm90by50cmFpbmluZ0luZm86IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UudHJhaW5pbmdJbmZvW2ldID0gJHJvb3Qub25ueC5UcmFpbmluZ0luZm9Qcm90by5mcm9tT2JqZWN0KG9iamVjdC50cmFpbmluZ0luZm9baV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmZ1bmN0aW9ucykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmZ1bmN0aW9ucykpIHRocm93IFR5cGVFcnJvcignLm9ubnguTW9kZWxQcm90by5mdW5jdGlvbnM6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuZnVuY3Rpb25zID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmZ1bmN0aW9ucy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmZ1bmN0aW9uc1tpXSAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguTW9kZWxQcm90by5mdW5jdGlvbnM6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UuZnVuY3Rpb25zW2ldID0gJHJvb3Qub25ueC5GdW5jdGlvblByb3RvLmZyb21PYmplY3Qob2JqZWN0LmZ1bmN0aW9uc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBNb2RlbFByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5Nb2RlbFByb3RvfSBtZXNzYWdlIE1vZGVsUHJvdG9cbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgIGlmIChvcHRpb25zLmFycmF5cyB8fCBvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICBvYmplY3QubWV0YWRhdGFQcm9wcyA9IFtdO1xuICAgICAgICBvYmplY3QudHJhaW5pbmdJbmZvID0gW107XG4gICAgICAgIG9iamVjdC5mdW5jdGlvbnMgPSBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIGlmICgkdXRpbC5Mb25nKSB7XG4gICAgICAgICAgdmFyIGxvbmcgPSBuZXcgJHV0aWwuTG9uZygwLCAwLCBmYWxzZSk7XG4gICAgICAgICAgb2JqZWN0LmlyVmVyc2lvbiA9XG4gICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBsb25nLnRvU3RyaW5nKCkgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBsb25nLnRvTnVtYmVyKCkgOiBsb25nO1xuICAgICAgICB9IGVsc2Ugb2JqZWN0LmlyVmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICcwJyA6IDA7XG4gICAgICAgIG9iamVjdC5wcm9kdWNlck5hbWUgPSAnJztcbiAgICAgICAgb2JqZWN0LnByb2R1Y2VyVmVyc2lvbiA9ICcnO1xuICAgICAgICBvYmplY3QuZG9tYWluID0gJyc7XG4gICAgICAgIGlmICgkdXRpbC5Mb25nKSB7XG4gICAgICAgICAgdmFyIGxvbmcgPSBuZXcgJHV0aWwuTG9uZygwLCAwLCBmYWxzZSk7XG4gICAgICAgICAgb2JqZWN0Lm1vZGVsVmVyc2lvbiA9XG4gICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBsb25nLnRvU3RyaW5nKCkgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBsb25nLnRvTnVtYmVyKCkgOiBsb25nO1xuICAgICAgICB9IGVsc2Ugb2JqZWN0Lm1vZGVsVmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICcwJyA6IDA7XG4gICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSAnJztcbiAgICAgICAgb2JqZWN0LmdyYXBoID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmlyVmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2lyVmVyc2lvbicpKVxuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuaXJWZXJzaW9uID09PSAnbnVtYmVyJylcbiAgICAgICAgICBvYmplY3QuaXJWZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuaXJWZXJzaW9uKSA6IG1lc3NhZ2UuaXJWZXJzaW9uO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgb2JqZWN0LmlyVmVyc2lvbiA9XG4gICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuaXJWZXJzaW9uKVxuICAgICAgICAgICAgICA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlclxuICAgICAgICAgICAgICAgID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuaXJWZXJzaW9uLmxvdyA+Pj4gMCwgbWVzc2FnZS5pclZlcnNpb24uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgIDogbWVzc2FnZS5pclZlcnNpb247XG4gICAgICBpZiAobWVzc2FnZS5wcm9kdWNlck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdwcm9kdWNlck5hbWUnKSlcbiAgICAgICAgb2JqZWN0LnByb2R1Y2VyTmFtZSA9IG1lc3NhZ2UucHJvZHVjZXJOYW1lO1xuICAgICAgaWYgKG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncHJvZHVjZXJWZXJzaW9uJykpXG4gICAgICAgIG9iamVjdC5wcm9kdWNlclZlcnNpb24gPSBtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbjtcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvbWFpbicpKSBvYmplY3QuZG9tYWluID0gbWVzc2FnZS5kb21haW47XG4gICAgICBpZiAobWVzc2FnZS5tb2RlbFZlcnNpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdtb2RlbFZlcnNpb24nKSlcbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLm1vZGVsVmVyc2lvbiA9PT0gJ251bWJlcicpXG4gICAgICAgICAgb2JqZWN0Lm1vZGVsVmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLm1vZGVsVmVyc2lvbikgOiBtZXNzYWdlLm1vZGVsVmVyc2lvbjtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIG9iamVjdC5tb2RlbFZlcnNpb24gPVxuICAgICAgICAgICAgb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLm1vZGVsVmVyc2lvbilcbiAgICAgICAgICAgICAgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXJcbiAgICAgICAgICAgICAgICA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLm1vZGVsVmVyc2lvbi5sb3cgPj4+IDAsIG1lc3NhZ2UubW9kZWxWZXJzaW9uLmhpZ2ggPj4+IDApLnRvTnVtYmVyKClcbiAgICAgICAgICAgICAgICA6IG1lc3NhZ2UubW9kZWxWZXJzaW9uO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9jU3RyaW5nJykpIG9iamVjdC5kb2NTdHJpbmcgPSBtZXNzYWdlLmRvY1N0cmluZztcbiAgICAgIGlmIChtZXNzYWdlLmdyYXBoICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZ3JhcGgnKSlcbiAgICAgICAgb2JqZWN0LmdyYXBoID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZ3JhcGgsIG9wdGlvbnMpO1xuICAgICAgaWYgKG1lc3NhZ2Uub3BzZXRJbXBvcnQgJiYgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0Lm9wc2V0SW1wb3J0ID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3Qub3BzZXRJbXBvcnRbal0gPSAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90by50b09iamVjdChtZXNzYWdlLm9wc2V0SW1wb3J0W2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm1ldGFkYXRhUHJvcHMgJiYgbWVzc2FnZS5tZXRhZGF0YVByb3BzLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QubWV0YWRhdGFQcm9wcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QubWV0YWRhdGFQcm9wc1tqXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by50b09iamVjdChtZXNzYWdlLm1ldGFkYXRhUHJvcHNbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudHJhaW5pbmdJbmZvICYmIG1lc3NhZ2UudHJhaW5pbmdJbmZvLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QudHJhaW5pbmdJbmZvID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS50cmFpbmluZ0luZm8ubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LnRyYWluaW5nSW5mb1tqXSA9ICRyb290Lm9ubnguVHJhaW5pbmdJbmZvUHJvdG8udG9PYmplY3QobWVzc2FnZS50cmFpbmluZ0luZm9bal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZnVuY3Rpb25zICYmIG1lc3NhZ2UuZnVuY3Rpb25zLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuZnVuY3Rpb25zID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5mdW5jdGlvbnMubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LmZ1bmN0aW9uc1tqXSA9ICRyb290Lm9ubnguRnVuY3Rpb25Qcm90by50b09iamVjdChtZXNzYWdlLmZ1bmN0aW9uc1tqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIE1vZGVsUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgTW9kZWxQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguTW9kZWxQcm90byc7XG4gICAgfTtcblxuICAgIHJldHVybiBNb2RlbFByb3RvO1xuICB9KSgpO1xuXG4gIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElTdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2tleV0gU3RyaW5nU3RyaW5nRW50cnlQcm90byBrZXlcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbdmFsdWVdIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gdmFsdWVcbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgU3RyaW5nU3RyaW5nRW50cnlQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uXG4gICAgICogQGltcGxlbWVudHMgSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBTdHJpbmdTdHJpbmdFbnRyeVByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIGtleS5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGtleVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLnByb3RvdHlwZS5rZXkgPSAnJztcblxuICAgIC8qKlxuICAgICAqIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gdmFsdWUuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSB2YWx1ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLnByb3RvdHlwZS52YWx1ZSA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvfSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIGluc3RhbmNlXG4gICAgICovXG4gICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBTdHJpbmdTdHJpbmdFbnRyeVByb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvfSBtZXNzYWdlIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS5rZXkgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAna2V5JykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8gMTApLnN0cmluZyhtZXNzYWdlLmtleSk7XG4gICAgICBpZiAobWVzc2FnZS52YWx1ZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICd2YWx1ZScpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovIDE4KS5zdHJpbmcobWVzc2FnZS52YWx1ZSk7XG4gICAgICByZXR1cm4gd3JpdGVyO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvfSBtZXNzYWdlIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvfSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8oKTtcbiAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmtleSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UudmFsdWUgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcmV0dXJucyB7b25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvfSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVmVyaWZpZXMgYSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmtleSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2tleScpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2Uua2V5KSkgcmV0dXJuICdrZXk6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS52YWx1ZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3ZhbHVlJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS52YWx1ZSkpIHJldHVybiAndmFsdWU6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICogQHJldHVybnMge29ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b30gU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvKSByZXR1cm4gb2JqZWN0O1xuICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvKCk7XG4gICAgICBpZiAob2JqZWN0LmtleSAhPSBudWxsKSBtZXNzYWdlLmtleSA9IFN0cmluZyhvYmplY3Qua2V5KTtcbiAgICAgIGlmIChvYmplY3QudmFsdWUgIT0gbnVsbCkgbWVzc2FnZS52YWx1ZSA9IFN0cmluZyhvYmplY3QudmFsdWUpO1xuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IG1lc3NhZ2UgU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0LmtleSA9ICcnO1xuICAgICAgICBvYmplY3QudmFsdWUgPSAnJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmtleSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2tleScpKSBvYmplY3Qua2V5ID0gbWVzc2FnZS5rZXk7XG4gICAgICBpZiAobWVzc2FnZS52YWx1ZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3ZhbHVlJykpIG9iamVjdC52YWx1ZSA9IG1lc3NhZ2UudmFsdWU7XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90byc7XG4gICAgfTtcblxuICAgIHJldHVybiBTdHJpbmdTdHJpbmdFbnRyeVByb3RvO1xuICB9KSgpO1xuXG4gIG9ubnguVGVuc29yQW5ub3RhdGlvbiA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhIFRlbnNvckFubm90YXRpb24uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElUZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW3RlbnNvck5hbWVdIFRlbnNvckFubm90YXRpb24gdGVuc29yTmFtZVxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fG51bGx9IFtxdWFudFBhcmFtZXRlclRlbnNvck5hbWVzXSBUZW5zb3JBbm5vdGF0aW9uIHF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNcbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgVGVuc29yQW5ub3RhdGlvbi5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFRlbnNvckFubm90YXRpb24uXG4gICAgICogQGltcGxlbWVudHMgSVRlbnNvckFubm90YXRpb25cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29ubnguSVRlbnNvckFubm90YXRpb249fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBUZW5zb3JBbm5vdGF0aW9uKHByb3BlcnRpZXMpIHtcbiAgICAgIHRoaXMucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyA9IFtdO1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRlbnNvckFubm90YXRpb24gdGVuc29yTmFtZS5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IHRlbnNvck5hbWVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yQW5ub3RhdGlvbi5wcm90b3R5cGUudGVuc29yTmFtZSA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yQW5ub3RhdGlvbiBxdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvPn0gcXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1xuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JBbm5vdGF0aW9uLnByb3RvdHlwZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgVGVuc29yQW5ub3RhdGlvbiBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JBbm5vdGF0aW9uPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguVGVuc29yQW5ub3RhdGlvbn0gVGVuc29yQW5ub3RhdGlvbiBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgVGVuc29yQW5ub3RhdGlvbihwcm9wZXJ0aWVzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRlbnNvckFubm90YXRpb24gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JBbm5vdGF0aW9uLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yQW5ub3RhdGlvbn0gbWVzc2FnZSBUZW5zb3JBbm5vdGF0aW9uIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBUZW5zb3JBbm5vdGF0aW9uLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgaWYgKG1lc3NhZ2UudGVuc29yTmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICd0ZW5zb3JOYW1lJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8gMTApLnN0cmluZyhtZXNzYWdlLnRlbnNvck5hbWUpO1xuICAgICAgaWYgKG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyAhPSBudWxsICYmIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovIDE4KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3JBbm5vdGF0aW9uIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yQW5ub3RhdGlvbi52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVRlbnNvckFubm90YXRpb259IG1lc3NhZ2UgVGVuc29yQW5ub3RhdGlvbiBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVGVuc29yQW5ub3RhdGlvbi5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFRlbnNvckFubm90YXRpb24gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvckFubm90YXRpb259IFRlbnNvckFubm90YXRpb25cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yQW5ub3RhdGlvbigpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UudGVuc29yTmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyAmJiBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMubGVuZ3RoKSlcbiAgICAgICAgICAgICAgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMucHVzaCgkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFRlbnNvckFubm90YXRpb24gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JBbm5vdGF0aW9ufSBUZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBUZW5zb3JBbm5vdGF0aW9uLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVmVyaWZpZXMgYSBUZW5zb3JBbm5vdGF0aW9uIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBUZW5zb3JBbm5vdGF0aW9uLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLnRlbnNvck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0ZW5zb3JOYW1lJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS50ZW5zb3JOYW1lKSkgcmV0dXJuICd0ZW5zb3JOYW1lOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3F1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzKSkgcmV0dXJuICdxdWFudFBhcmFtZXRlclRlbnNvck5hbWVzOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnZlcmlmeShtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdxdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBUZW5zb3JBbm5vdGF0aW9uIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvckFubm90YXRpb259IFRlbnNvckFubm90YXRpb25cbiAgICAgKi9cbiAgICBUZW5zb3JBbm5vdGF0aW9uLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVGVuc29yQW5ub3RhdGlvbikgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yQW5ub3RhdGlvbigpO1xuICAgICAgaWYgKG9iamVjdC50ZW5zb3JOYW1lICE9IG51bGwpIG1lc3NhZ2UudGVuc29yTmFtZSA9IFN0cmluZyhvYmplY3QudGVuc29yTmFtZSk7XG4gICAgICBpZiAob2JqZWN0LnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzKSlcbiAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlRlbnNvckFubm90YXRpb24ucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lczogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzW2ldICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yQW5ub3RhdGlvbi5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNbaV0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZnJvbU9iamVjdChcbiAgICAgICAgICAgIG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzW2ldLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBUZW5zb3JBbm5vdGF0aW9uIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JBbm5vdGF0aW9ufSBtZXNzYWdlIFRlbnNvckFubm90YXRpb25cbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgIGlmIChvcHRpb25zLmFycmF5cyB8fCBvcHRpb25zLmRlZmF1bHRzKSBvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyA9IFtdO1xuICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIG9iamVjdC50ZW5zb3JOYW1lID0gJyc7XG4gICAgICBpZiAobWVzc2FnZS50ZW5zb3JOYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndGVuc29yTmFtZScpKSBvYmplY3QudGVuc29yTmFtZSA9IG1lc3NhZ2UudGVuc29yTmFtZTtcbiAgICAgIGlmIChtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMgJiYgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1tqXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by50b09iamVjdChcbiAgICAgICAgICAgIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1tqXSxcbiAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgVGVuc29yQW5ub3RhdGlvbiB0byBKU09OLlxuICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBUZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICovXG4gICAgVGVuc29yQW5ub3RhdGlvbi5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UZW5zb3JBbm5vdGF0aW9uJztcbiAgICB9O1xuXG4gICAgcmV0dXJuIFRlbnNvckFubm90YXRpb247XG4gIH0pKCk7XG5cbiAgb25ueC5HcmFwaFByb3RvID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgR3JhcGhQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSUdyYXBoUHJvdG9cbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklOb2RlUHJvdG8+fG51bGx9IFtub2RlXSBHcmFwaFByb3RvIG5vZGVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbbmFtZV0gR3JhcGhQcm90byBuYW1lXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JVGVuc29yUHJvdG8+fG51bGx9IFtpbml0aWFsaXplcl0gR3JhcGhQcm90byBpbml0aWFsaXplclxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVNwYXJzZVRlbnNvclByb3RvPnxudWxsfSBbc3BhcnNlSW5pdGlhbGl6ZXJdIEdyYXBoUHJvdG8gc3BhcnNlSW5pdGlhbGl6ZXJcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9jU3RyaW5nXSBHcmFwaFByb3RvIGRvY1N0cmluZ1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVZhbHVlSW5mb1Byb3RvPnxudWxsfSBbaW5wdXRdIEdyYXBoUHJvdG8gaW5wdXRcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklWYWx1ZUluZm9Qcm90bz58bnVsbH0gW291dHB1dF0gR3JhcGhQcm90byBvdXRwdXRcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklWYWx1ZUluZm9Qcm90bz58bnVsbH0gW3ZhbHVlSW5mb10gR3JhcGhQcm90byB2YWx1ZUluZm9cbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklUZW5zb3JBbm5vdGF0aW9uPnxudWxsfSBbcXVhbnRpemF0aW9uQW5ub3RhdGlvbl0gR3JhcGhQcm90byBxdWFudGl6YXRpb25Bbm5vdGF0aW9uXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IEdyYXBoUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBHcmFwaFByb3RvLlxuICAgICAqIEBpbXBsZW1lbnRzIElHcmFwaFByb3RvXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvbm54LklHcmFwaFByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICovXG4gICAgZnVuY3Rpb24gR3JhcGhQcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICB0aGlzLm5vZGUgPSBbXTtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgIHRoaXMuc3BhcnNlSW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgIHRoaXMuaW5wdXQgPSBbXTtcbiAgICAgIHRoaXMub3V0cHV0ID0gW107XG4gICAgICB0aGlzLnZhbHVlSW5mbyA9IFtdO1xuICAgICAgdGhpcy5xdWFudGl6YXRpb25Bbm5vdGF0aW9uID0gW107XG4gICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR3JhcGhQcm90byBub2RlLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklOb2RlUHJvdG8+fSBub2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLm5vZGUgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogR3JhcGhQcm90byBuYW1lLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gbmFtZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLnByb3RvdHlwZS5uYW1lID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBHcmFwaFByb3RvIGluaXRpYWxpemVyLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklUZW5zb3JQcm90bz59IGluaXRpYWxpemVyXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLmluaXRpYWxpemVyID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIEdyYXBoUHJvdG8gc3BhcnNlSW5pdGlhbGl6ZXIuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVNwYXJzZVRlbnNvclByb3RvPn0gc3BhcnNlSW5pdGlhbGl6ZXJcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgR3JhcGhQcm90by5wcm90b3R5cGUuc3BhcnNlSW5pdGlhbGl6ZXIgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogR3JhcGhQcm90byBkb2NTdHJpbmcuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBkb2NTdHJpbmdcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgR3JhcGhQcm90by5wcm90b3R5cGUuZG9jU3RyaW5nID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBHcmFwaFByb3RvIGlucHV0LlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklWYWx1ZUluZm9Qcm90bz59IGlucHV0XG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLmlucHV0ID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIEdyYXBoUHJvdG8gb3V0cHV0LlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklWYWx1ZUluZm9Qcm90bz59IG91dHB1dFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLnByb3RvdHlwZS5vdXRwdXQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogR3JhcGhQcm90byB2YWx1ZUluZm8uXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVZhbHVlSW5mb1Byb3RvPn0gdmFsdWVJbmZvXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLnZhbHVlSW5mbyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBHcmFwaFByb3RvIHF1YW50aXphdGlvbkFubm90YXRpb24uXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVRlbnNvckFubm90YXRpb24+fSBxdWFudGl6YXRpb25Bbm5vdGF0aW9uXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLnF1YW50aXphdGlvbkFubm90YXRpb24gPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBHcmFwaFByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSUdyYXBoUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5HcmFwaFByb3RvfSBHcmFwaFByb3RvIGluc3RhbmNlXG4gICAgICovXG4gICAgR3JhcGhQcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBHcmFwaFByb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgR3JhcGhQcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LkdyYXBoUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklHcmFwaFByb3RvfSBtZXNzYWdlIEdyYXBoUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIEdyYXBoUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS5ub2RlICE9IG51bGwgJiYgbWVzc2FnZS5ub2RlLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm5vZGUubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5Ob2RlUHJvdG8uZW5jb2RlKG1lc3NhZ2Uubm9kZVtpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnbmFtZScpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovIDE4KS5zdHJpbmcobWVzc2FnZS5uYW1lKTtcbiAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemVyICE9IG51bGwgJiYgbWVzc2FnZS5pbml0aWFsaXplci5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbml0aWFsaXplci5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlRlbnNvclByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6ZXJbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDUsIHdpcmVUeXBlIDIgPSovIDQyKS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkb2NTdHJpbmcnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMCwgd2lyZVR5cGUgMiA9Ki8gODIpLnN0cmluZyhtZXNzYWdlLmRvY1N0cmluZyk7XG4gICAgICBpZiAobWVzc2FnZS5pbnB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW5wdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLmlucHV0W2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMSwgd2lyZVR5cGUgMiA9Ki8gOTApLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICE9IG51bGwgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5vdXRwdXRbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEyLCB3aXJlVHlwZSAyID0qLyA5OCkuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS52YWx1ZUluZm8gIT0gbnVsbCAmJiBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS52YWx1ZUluZm8ubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLnZhbHVlSW5mb1tpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTMsIHdpcmVUeXBlIDIgPSovIDEwNikuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbltpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTQsIHdpcmVUeXBlIDIgPSovIDExNCkuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VJbml0aWFsaXplciAhPSBudWxsICYmIG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXIubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXIubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxNSwgd2lyZVR5cGUgMiA9Ki8gMTIyKS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBHcmFwaFByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguR3JhcGhQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSUdyYXBoUHJvdG99IG1lc3NhZ2UgR3JhcGhQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgR3JhcGhQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIEdyYXBoUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LkdyYXBoUHJvdG99IEdyYXBoUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIEdyYXBoUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguR3JhcGhQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uubm9kZSAmJiBtZXNzYWdlLm5vZGUubGVuZ3RoKSkgbWVzc2FnZS5ub2RlID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLm5vZGUucHVzaCgkcm9vdC5vbm54Lk5vZGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDU6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuaW5pdGlhbGl6ZXIgJiYgbWVzc2FnZS5pbml0aWFsaXplci5sZW5ndGgpKSBtZXNzYWdlLmluaXRpYWxpemVyID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmluaXRpYWxpemVyLnB1c2goJHJvb3Qub25ueC5UZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDE1OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyICYmIG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXIubGVuZ3RoKSkgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplciA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplci5wdXNoKCRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMDoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbnB1dCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aCkpIG1lc3NhZ2UuaW5wdXQgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5wdXQucHVzaCgkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTI6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uub3V0cHV0ICYmIG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aCkpIG1lc3NhZ2Uub3V0cHV0ID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLm91dHB1dC5wdXNoKCRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMzoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS52YWx1ZUluZm8gJiYgbWVzc2FnZS52YWx1ZUluZm8ubGVuZ3RoKSkgbWVzc2FnZS52YWx1ZUluZm8gPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UudmFsdWVJbmZvLnB1c2goJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDE0OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24gJiYgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uLmxlbmd0aCkpXG4gICAgICAgICAgICAgIG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uLnB1c2goJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBHcmFwaFByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHJldHVybnMge29ubnguR3JhcGhQcm90b30gR3JhcGhQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgR3JhcGhQcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFZlcmlmaWVzIGEgR3JhcGhQcm90byBtZXNzYWdlLlxuICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICovXG4gICAgR3JhcGhQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5ub2RlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbm9kZScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm5vZGUpKSByZXR1cm4gJ25vZGU6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm5vZGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54Lk5vZGVQcm90by52ZXJpZnkobWVzc2FnZS5ub2RlW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnbm9kZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCduYW1lJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5uYW1lKSkgcmV0dXJuICduYW1lOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuaW5pdGlhbGl6ZXIgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpbml0aWFsaXplcicpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmluaXRpYWxpemVyKSkgcmV0dXJuICdpbml0aWFsaXplcjogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW5pdGlhbGl6ZXIubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnZlcmlmeShtZXNzYWdlLmluaXRpYWxpemVyW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnaW5pdGlhbGl6ZXIuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VJbml0aWFsaXplciAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NwYXJzZUluaXRpYWxpemVyJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXIpKSByZXR1cm4gJ3NwYXJzZUluaXRpYWxpemVyOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplci5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8udmVyaWZ5KG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXJbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdzcGFyc2VJbml0aWFsaXplci4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSkgcmV0dXJuICdkb2NTdHJpbmc6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5pbnB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2lucHV0JykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuaW5wdXQpKSByZXR1cm4gJ2lucHV0OiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udmVyaWZ5KG1lc3NhZ2UuaW5wdXRbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdpbnB1dC4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm91dHB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ291dHB1dCcpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm91dHB1dCkpIHJldHVybiAnb3V0cHV0OiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vdXRwdXQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLnZlcmlmeShtZXNzYWdlLm91dHB1dFtpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ291dHB1dC4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnZhbHVlSW5mbyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3ZhbHVlSW5mbycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLnZhbHVlSW5mbykpIHJldHVybiAndmFsdWVJbmZvOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS52YWx1ZUluZm8ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLnZlcmlmeShtZXNzYWdlLnZhbHVlSW5mb1tpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3ZhbHVlSW5mby4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdxdWFudGl6YXRpb25Bbm5vdGF0aW9uJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbikpIHJldHVybiAncXVhbnRpemF0aW9uQW5ub3RhdGlvbjogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbi5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yQW5ub3RhdGlvbi52ZXJpZnkobWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAncXVhbnRpemF0aW9uQW5ub3RhdGlvbi4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgR3JhcGhQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5HcmFwaFByb3RvfSBHcmFwaFByb3RvXG4gICAgICovXG4gICAgR3JhcGhQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LkdyYXBoUHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LkdyYXBoUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3Qubm9kZSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0Lm5vZGUpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8ubm9kZTogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5ub2RlID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lm5vZGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5ub2RlW2ldICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLm5vZGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2Uubm9kZVtpXSA9ICRyb290Lm9ubnguTm9kZVByb3RvLmZyb21PYmplY3Qob2JqZWN0Lm5vZGVbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0Lm5hbWUgIT0gbnVsbCkgbWVzc2FnZS5uYW1lID0gU3RyaW5nKG9iamVjdC5uYW1lKTtcbiAgICAgIGlmIChvYmplY3QuaW5pdGlhbGl6ZXIpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5pbml0aWFsaXplcikpIHRocm93IFR5cGVFcnJvcignLm9ubnguR3JhcGhQcm90by5pbml0aWFsaXplcjogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5pbml0aWFsaXplciA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5pbml0aWFsaXplci5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmluaXRpYWxpemVyW2ldICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguR3JhcGhQcm90by5pbml0aWFsaXplcjogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXplcltpXSA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3QuaW5pdGlhbGl6ZXJbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LnNwYXJzZUluaXRpYWxpemVyKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXIpKVxuICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguR3JhcGhQcm90by5zcGFyc2VJbml0aWFsaXplcjogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplciA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5zcGFyc2VJbml0aWFsaXplci5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnNwYXJzZUluaXRpYWxpemVyW2ldICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguR3JhcGhQcm90by5zcGFyc2VJbml0aWFsaXplcjogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplcltpXSA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXJbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmRvY1N0cmluZyAhPSBudWxsKSBtZXNzYWdlLmRvY1N0cmluZyA9IFN0cmluZyhvYmplY3QuZG9jU3RyaW5nKTtcbiAgICAgIGlmIChvYmplY3QuaW5wdXQpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5pbnB1dCkpIHRocm93IFR5cGVFcnJvcignLm9ubnguR3JhcGhQcm90by5pbnB1dDogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5pbnB1dCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5pbnB1dC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmlucHV0W2ldICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLmlucHV0OiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLmlucHV0W2ldID0gJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5mcm9tT2JqZWN0KG9iamVjdC5pbnB1dFtpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3Qub3V0cHV0KSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Qub3V0cHV0KSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLm91dHB1dDogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5vdXRwdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Qub3V0cHV0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Qub3V0cHV0W2ldICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLm91dHB1dDogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5vdXRwdXRbaV0gPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmZyb21PYmplY3Qob2JqZWN0Lm91dHB1dFtpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QudmFsdWVJbmZvKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QudmFsdWVJbmZvKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLnZhbHVlSW5mbzogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS52YWx1ZUluZm8gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QudmFsdWVJbmZvLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudmFsdWVJbmZvW2ldICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLnZhbHVlSW5mbzogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS52YWx1ZUluZm9baV0gPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmZyb21PYmplY3Qob2JqZWN0LnZhbHVlSW5mb1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QucXVhbnRpemF0aW9uQW5ub3RhdGlvbikge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb24pKVxuICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguR3JhcGhQcm90by5xdWFudGl6YXRpb25Bbm5vdGF0aW9uOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QucXVhbnRpemF0aW9uQW5ub3RhdGlvbi5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb25baV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLnF1YW50aXphdGlvbkFubm90YXRpb246IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbltpXSA9ICRyb290Lm9ubnguVGVuc29yQW5ub3RhdGlvbi5mcm9tT2JqZWN0KG9iamVjdC5xdWFudGl6YXRpb25Bbm5vdGF0aW9uW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIEdyYXBoUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LkdyYXBoUHJvdG99IG1lc3NhZ2UgR3JhcGhQcm90b1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgR3JhcGhQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0Lm5vZGUgPSBbXTtcbiAgICAgICAgb2JqZWN0LmluaXRpYWxpemVyID0gW107XG4gICAgICAgIG9iamVjdC5pbnB1dCA9IFtdO1xuICAgICAgICBvYmplY3Qub3V0cHV0ID0gW107XG4gICAgICAgIG9iamVjdC52YWx1ZUluZm8gPSBbXTtcbiAgICAgICAgb2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb24gPSBbXTtcbiAgICAgICAgb2JqZWN0LnNwYXJzZUluaXRpYWxpemVyID0gW107XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QubmFtZSA9ICcnO1xuICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gJyc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5ub2RlICYmIG1lc3NhZ2Uubm9kZS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0Lm5vZGUgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLm5vZGUubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0Lm5vZGVbal0gPSAkcm9vdC5vbm54Lk5vZGVQcm90by50b09iamVjdChtZXNzYWdlLm5vZGVbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSkgb2JqZWN0Lm5hbWUgPSBtZXNzYWdlLm5hbWU7XG4gICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXplciAmJiBtZXNzYWdlLmluaXRpYWxpemVyLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuaW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmluaXRpYWxpemVyLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5pbml0aWFsaXplcltqXSA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS5pbml0aWFsaXplcltqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSkgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgJiYgbWVzc2FnZS5pbnB1dC5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmlucHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuaW5wdXRbal0gPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLnRvT2JqZWN0KG1lc3NhZ2UuaW5wdXRbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICYmIG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aCkge1xuICAgICAgICBvYmplY3Qub3V0cHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5vdXRwdXQubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0Lm91dHB1dFtqXSA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udG9PYmplY3QobWVzc2FnZS5vdXRwdXRbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudmFsdWVJbmZvICYmIG1lc3NhZ2UudmFsdWVJbmZvLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QudmFsdWVJbmZvID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS52YWx1ZUluZm8ubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LnZhbHVlSW5mb1tqXSA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udG9PYmplY3QobWVzc2FnZS52YWx1ZUluZm9bal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiAmJiBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5xdWFudGl6YXRpb25Bbm5vdGF0aW9uID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5xdWFudGl6YXRpb25Bbm5vdGF0aW9uW2pdID0gJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uLnRvT2JqZWN0KFxuICAgICAgICAgICAgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uW2pdLFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXIgJiYgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplci5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LnNwYXJzZUluaXRpYWxpemVyID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplci5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXJbal0gPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXJbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhpcyBHcmFwaFByb3RvIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgR3JhcGhQcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIEdyYXBoUHJvdG9cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LkdyYXBoUHJvdG8nO1xuICAgIH07XG5cbiAgICByZXR1cm4gR3JhcGhQcm90bztcbiAgfSkoKTtcblxuICBvbm54LlRlbnNvclByb3RvID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgVGVuc29yUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElUZW5zb3JQcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcnxMb25nPnxudWxsfSBbZGltc10gVGVuc29yUHJvdG8gZGltc1xuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfG51bGx9IFtkYXRhVHlwZV0gVGVuc29yUHJvdG8gZGF0YVR5cGVcbiAgICAgKiBAcHJvcGVydHkge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnR8bnVsbH0gW3NlZ21lbnRdIFRlbnNvclByb3RvIHNlZ21lbnRcbiAgICAgKiBAcHJvcGVydHkge0FycmF5LjxudW1iZXI+fG51bGx9IFtmbG9hdERhdGFdIFRlbnNvclByb3RvIGZsb2F0RGF0YVxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcj58bnVsbH0gW2ludDMyRGF0YV0gVGVuc29yUHJvdG8gaW50MzJEYXRhXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48VWludDhBcnJheT58bnVsbH0gW3N0cmluZ0RhdGFdIFRlbnNvclByb3RvIHN0cmluZ0RhdGFcbiAgICAgKiBAcHJvcGVydHkge0FycmF5LjxudW1iZXJ8TG9uZz58bnVsbH0gW2ludDY0RGF0YV0gVGVuc29yUHJvdG8gaW50NjREYXRhXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW25hbWVdIFRlbnNvclByb3RvIG5hbWVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9jU3RyaW5nXSBUZW5zb3JQcm90byBkb2NTdHJpbmdcbiAgICAgKiBAcHJvcGVydHkge1VpbnQ4QXJyYXl8bnVsbH0gW3Jhd0RhdGFdIFRlbnNvclByb3RvIHJhd0RhdGFcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvPnxudWxsfSBbZXh0ZXJuYWxEYXRhXSBUZW5zb3JQcm90byBleHRlcm5hbERhdGFcbiAgICAgKiBAcHJvcGVydHkge29ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9ufG51bGx9IFtkYXRhTG9jYXRpb25dIFRlbnNvclByb3RvIGRhdGFMb2NhdGlvblxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcj58bnVsbH0gW2RvdWJsZURhdGFdIFRlbnNvclByb3RvIGRvdWJsZURhdGFcbiAgICAgKiBAcHJvcGVydHkge0FycmF5LjxudW1iZXJ8TG9uZz58bnVsbH0gW3VpbnQ2NERhdGFdIFRlbnNvclByb3RvIHVpbnQ2NERhdGFcbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgVGVuc29yUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBUZW5zb3JQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJVGVuc29yUHJvdG9cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29ubnguSVRlbnNvclByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICovXG4gICAgZnVuY3Rpb24gVGVuc29yUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgdGhpcy5kaW1zID0gW107XG4gICAgICB0aGlzLmZsb2F0RGF0YSA9IFtdO1xuICAgICAgdGhpcy5pbnQzMkRhdGEgPSBbXTtcbiAgICAgIHRoaXMuc3RyaW5nRGF0YSA9IFtdO1xuICAgICAgdGhpcy5pbnQ2NERhdGEgPSBbXTtcbiAgICAgIHRoaXMuZXh0ZXJuYWxEYXRhID0gW107XG4gICAgICB0aGlzLmRvdWJsZURhdGEgPSBbXTtcbiAgICAgIHRoaXMudWludDY0RGF0YSA9IFtdO1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRlbnNvclByb3RvIGRpbXMuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcnxMb25nPn0gZGltc1xuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmRpbXMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gZGF0YVR5cGUuXG4gICAgICogQG1lbWJlciB7bnVtYmVyfSBkYXRhVHlwZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmRhdGFUeXBlID0gMDtcblxuICAgIC8qKlxuICAgICAqIFRlbnNvclByb3RvIHNlZ21lbnQuXG4gICAgICogQG1lbWJlciB7b25ueC5UZW5zb3JQcm90by5JU2VnbWVudHxudWxsfHVuZGVmaW5lZH0gc2VnbWVudFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLnNlZ21lbnQgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gZmxvYXREYXRhLlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxudW1iZXI+fSBmbG9hdERhdGFcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5mbG9hdERhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gaW50MzJEYXRhLlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxudW1iZXI+fSBpbnQzMkRhdGFcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5pbnQzMkRhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gc3RyaW5nRGF0YS5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48VWludDhBcnJheT59IHN0cmluZ0RhdGFcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5zdHJpbmdEYXRhID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIFRlbnNvclByb3RvIGludDY0RGF0YS5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyfExvbmc+fSBpbnQ2NERhdGFcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5pbnQ2NERhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gbmFtZS5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5uYW1lID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JQcm90byBkb2NTdHJpbmcuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBkb2NTdHJpbmdcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSAnJztcblxuICAgIC8qKlxuICAgICAqIFRlbnNvclByb3RvIHJhd0RhdGEuXG4gICAgICogQG1lbWJlciB7VWludDhBcnJheX0gcmF3RGF0YVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLnJhd0RhdGEgPSAkdXRpbC5uZXdCdWZmZXIoW10pO1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gZXh0ZXJuYWxEYXRhLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvPn0gZXh0ZXJuYWxEYXRhXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuZXh0ZXJuYWxEYXRhID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIFRlbnNvclByb3RvIGRhdGFMb2NhdGlvbi5cbiAgICAgKiBAbWVtYmVyIHtvbm54LlRlbnNvclByb3RvLkRhdGFMb2NhdGlvbn0gZGF0YUxvY2F0aW9uXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuZGF0YUxvY2F0aW9uID0gMDtcblxuICAgIC8qKlxuICAgICAqIFRlbnNvclByb3RvIGRvdWJsZURhdGEuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcj59IGRvdWJsZURhdGFcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5kb3VibGVEYXRhID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIFRlbnNvclByb3RvIHVpbnQ2NERhdGEuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcnxMb25nPn0gdWludDY0RGF0YVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLnVpbnQ2NERhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBUZW5zb3JQcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JQcm90b30gVGVuc29yUHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBUZW5zb3JQcm90byhwcm9wZXJ0aWVzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRlbnNvclByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yUHJvdG99IG1lc3NhZ2UgVGVuc29yUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZGltcyAhPSBudWxsICYmIG1lc3NhZ2UuZGltcy5sZW5ndGgpIHtcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuZm9yaygpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZGltcy5sZW5ndGg7ICsraSkgd3JpdGVyLmludDY0KG1lc3NhZ2UuZGltc1tpXSk7XG4gICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRhdGFUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RhdGFUeXBlJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMCA9Ki8gMTYpLmludDMyKG1lc3NhZ2UuZGF0YVR5cGUpO1xuICAgICAgaWYgKG1lc3NhZ2Uuc2VnbWVudCAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdzZWdtZW50JykpXG4gICAgICAgICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudC5lbmNvZGUoXG4gICAgICAgICAgbWVzc2FnZS5zZWdtZW50LFxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMywgd2lyZVR5cGUgMiA9Ki8gMjYpLmZvcmsoKSxcbiAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmZsb2F0RGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuZmxvYXREYXRhLmxlbmd0aCkge1xuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDQsIHdpcmVUeXBlIDIgPSovIDM0KS5mb3JrKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5mbG9hdERhdGEubGVuZ3RoOyArK2kpIHdyaXRlci5mbG9hdChtZXNzYWdlLmZsb2F0RGF0YVtpXSk7XG4gICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmludDMyRGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaW50MzJEYXRhLmxlbmd0aCkge1xuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDUsIHdpcmVUeXBlIDIgPSovIDQyKS5mb3JrKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnQzMkRhdGEubGVuZ3RoOyArK2kpIHdyaXRlci5pbnQzMihtZXNzYWdlLmludDMyRGF0YVtpXSk7XG4gICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnN0cmluZ0RhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLnN0cmluZ0RhdGEubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uuc3RyaW5nRGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDYsIHdpcmVUeXBlIDIgPSovIDUwKS5ieXRlcyhtZXNzYWdlLnN0cmluZ0RhdGFbaV0pO1xuICAgICAgaWYgKG1lc3NhZ2UuaW50NjREYXRhICE9IG51bGwgJiYgbWVzc2FnZS5pbnQ2NERhdGEubGVuZ3RoKSB7XG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNywgd2lyZVR5cGUgMiA9Ki8gNTgpLmZvcmsoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmludDY0RGF0YS5sZW5ndGg7ICsraSkgd3JpdGVyLmludDY0KG1lc3NhZ2UuaW50NjREYXRhW2ldKTtcbiAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICduYW1lJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgOCwgd2lyZVR5cGUgMiA9Ki8gNjYpLnN0cmluZyhtZXNzYWdlLm5hbWUpO1xuICAgICAgaWYgKG1lc3NhZ2UucmF3RGF0YSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdyYXdEYXRhJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgOSwgd2lyZVR5cGUgMiA9Ki8gNzQpLmJ5dGVzKG1lc3NhZ2UucmF3RGF0YSk7XG4gICAgICBpZiAobWVzc2FnZS5kb3VibGVEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5kb3VibGVEYXRhLmxlbmd0aCkge1xuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEwLCB3aXJlVHlwZSAyID0qLyA4MikuZm9yaygpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZG91YmxlRGF0YS5sZW5ndGg7ICsraSkgd3JpdGVyLmRvdWJsZShtZXNzYWdlLmRvdWJsZURhdGFbaV0pO1xuICAgICAgICB3cml0ZXIubGRlbGltKCk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS51aW50NjREYXRhICE9IG51bGwgJiYgbWVzc2FnZS51aW50NjREYXRhLmxlbmd0aCkge1xuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDExLCB3aXJlVHlwZSAyID0qLyA5MCkuZm9yaygpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudWludDY0RGF0YS5sZW5ndGg7ICsraSkgd3JpdGVyLnVpbnQ2NChtZXNzYWdlLnVpbnQ2NERhdGFbaV0pO1xuICAgICAgICB3cml0ZXIubGRlbGltKCk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZG9jU3RyaW5nJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTIsIHdpcmVUeXBlIDIgPSovIDk4KS5zdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpO1xuICAgICAgaWYgKG1lc3NhZ2UuZXh0ZXJuYWxEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5leHRlcm5hbERhdGEubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZXh0ZXJuYWxEYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLmV4dGVybmFsRGF0YVtpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTMsIHdpcmVUeXBlIDIgPSovIDEwNikuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5kYXRhTG9jYXRpb24gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZGF0YUxvY2F0aW9uJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTQsIHdpcmVUeXBlIDAgPSovIDExMikuaW50MzIobWVzc2FnZS5kYXRhTG9jYXRpb24pO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRlbnNvclByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yUHJvdG99IG1lc3NhZ2UgVGVuc29yUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVGVuc29yUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JQcm90b30gVGVuc29yUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFRlbnNvclByb3RvLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclByb3RvKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5kaW1zICYmIG1lc3NhZ2UuZGltcy5sZW5ndGgpKSBtZXNzYWdlLmRpbXMgPSBbXTtcbiAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpIG1lc3NhZ2UuZGltcy5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgIH0gZWxzZSBtZXNzYWdlLmRpbXMucHVzaChyZWFkZXIuaW50NjQoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmRhdGFUeXBlID0gcmVhZGVyLmludDMyKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAzOiB7XG4gICAgICAgICAgICBtZXNzYWdlLnNlZ21lbnQgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDQ6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZmxvYXREYXRhICYmIG1lc3NhZ2UuZmxvYXREYXRhLmxlbmd0aCkpIG1lc3NhZ2UuZmxvYXREYXRhID0gW107XG4gICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgIHZhciBlbmQyID0gcmVhZGVyLnVpbnQzMigpICsgcmVhZGVyLnBvcztcbiAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKSBtZXNzYWdlLmZsb2F0RGF0YS5wdXNoKHJlYWRlci5mbG9hdCgpKTtcbiAgICAgICAgICAgIH0gZWxzZSBtZXNzYWdlLmZsb2F0RGF0YS5wdXNoKHJlYWRlci5mbG9hdCgpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDU6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuaW50MzJEYXRhICYmIG1lc3NhZ2UuaW50MzJEYXRhLmxlbmd0aCkpIG1lc3NhZ2UuaW50MzJEYXRhID0gW107XG4gICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgIHZhciBlbmQyID0gcmVhZGVyLnVpbnQzMigpICsgcmVhZGVyLnBvcztcbiAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKSBtZXNzYWdlLmludDMyRGF0YS5wdXNoKHJlYWRlci5pbnQzMigpKTtcbiAgICAgICAgICAgIH0gZWxzZSBtZXNzYWdlLmludDMyRGF0YS5wdXNoKHJlYWRlci5pbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDY6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uuc3RyaW5nRGF0YSAmJiBtZXNzYWdlLnN0cmluZ0RhdGEubGVuZ3RoKSkgbWVzc2FnZS5zdHJpbmdEYXRhID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnN0cmluZ0RhdGEucHVzaChyZWFkZXIuYnl0ZXMoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA3OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmludDY0RGF0YSAmJiBtZXNzYWdlLmludDY0RGF0YS5sZW5ndGgpKSBtZXNzYWdlLmludDY0RGF0YSA9IFtdO1xuICAgICAgICAgICAgaWYgKCh0YWcgJiA3KSA9PT0gMikge1xuICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMikgbWVzc2FnZS5pbnQ2NERhdGEucHVzaChyZWFkZXIuaW50NjQoKSk7XG4gICAgICAgICAgICB9IGVsc2UgbWVzc2FnZS5pbnQ2NERhdGEucHVzaChyZWFkZXIuaW50NjQoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA4OiB7XG4gICAgICAgICAgICBtZXNzYWdlLm5hbWUgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMjoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA5OiB7XG4gICAgICAgICAgICBtZXNzYWdlLnJhd0RhdGEgPSByZWFkZXIuYnl0ZXMoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDEzOiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmV4dGVybmFsRGF0YSAmJiBtZXNzYWdlLmV4dGVybmFsRGF0YS5sZW5ndGgpKSBtZXNzYWdlLmV4dGVybmFsRGF0YSA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5leHRlcm5hbERhdGEucHVzaCgkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxNDoge1xuICAgICAgICAgICAgbWVzc2FnZS5kYXRhTG9jYXRpb24gPSByZWFkZXIuaW50MzIoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDEwOiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmRvdWJsZURhdGEgJiYgbWVzc2FnZS5kb3VibGVEYXRhLmxlbmd0aCkpIG1lc3NhZ2UuZG91YmxlRGF0YSA9IFtdO1xuICAgICAgICAgICAgaWYgKCh0YWcgJiA3KSA9PT0gMikge1xuICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMikgbWVzc2FnZS5kb3VibGVEYXRhLnB1c2gocmVhZGVyLmRvdWJsZSgpKTtcbiAgICAgICAgICAgIH0gZWxzZSBtZXNzYWdlLmRvdWJsZURhdGEucHVzaChyZWFkZXIuZG91YmxlKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTE6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UudWludDY0RGF0YSAmJiBtZXNzYWdlLnVpbnQ2NERhdGEubGVuZ3RoKSkgbWVzc2FnZS51aW50NjREYXRhID0gW107XG4gICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgIHZhciBlbmQyID0gcmVhZGVyLnVpbnQzMigpICsgcmVhZGVyLnBvcztcbiAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKSBtZXNzYWdlLnVpbnQ2NERhdGEucHVzaChyZWFkZXIudWludDY0KCkpO1xuICAgICAgICAgICAgfSBlbHNlIG1lc3NhZ2UudWludDY0RGF0YS5wdXNoKHJlYWRlci51aW50NjQoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFRlbnNvclByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvfSBUZW5zb3JQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIFRlbnNvclByb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICovXG4gICAgVGVuc29yUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuZGltcyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RpbXMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5kaW1zKSkgcmV0dXJuICdkaW1zOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5kaW1zLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kaW1zW2ldKSAmJlxuICAgICAgICAgICAgIShtZXNzYWdlLmRpbXNbaV0gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltc1tpXS5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbXNbaV0uaGlnaCkpXG4gICAgICAgICAgKVxuICAgICAgICAgICAgcmV0dXJuICdkaW1zOiBpbnRlZ2VyfExvbmdbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kYXRhVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RhdGFUeXBlJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGF0YVR5cGUpKSByZXR1cm4gJ2RhdGFUeXBlOiBpbnRlZ2VyIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLnNlZ21lbnQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzZWdtZW50JykpIHtcbiAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5TZWdtZW50LnZlcmlmeShtZXNzYWdlLnNlZ21lbnQpO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnc2VnbWVudC4nICsgZXJyb3I7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5mbG9hdERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdmbG9hdERhdGEnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5mbG9hdERhdGEpKSByZXR1cm4gJ2Zsb2F0RGF0YTogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZmxvYXREYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5mbG9hdERhdGFbaV0gIT09ICdudW1iZXInKSByZXR1cm4gJ2Zsb2F0RGF0YTogbnVtYmVyW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuaW50MzJEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaW50MzJEYXRhJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuaW50MzJEYXRhKSkgcmV0dXJuICdpbnQzMkRhdGE6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmludDMyRGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludDMyRGF0YVtpXSkpIHJldHVybiAnaW50MzJEYXRhOiBpbnRlZ2VyW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uuc3RyaW5nRGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3N0cmluZ0RhdGEnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5zdHJpbmdEYXRhKSkgcmV0dXJuICdzdHJpbmdEYXRhOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5zdHJpbmdEYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICEoXG4gICAgICAgICAgICAgIChtZXNzYWdlLnN0cmluZ0RhdGFbaV0gJiYgdHlwZW9mIG1lc3NhZ2Uuc3RyaW5nRGF0YVtpXS5sZW5ndGggPT09ICdudW1iZXInKSB8fFxuICAgICAgICAgICAgICAkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnN0cmluZ0RhdGFbaV0pXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICAgICAgcmV0dXJuICdzdHJpbmdEYXRhOiBidWZmZXJbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5pbnQ2NERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpbnQ2NERhdGEnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbnQ2NERhdGEpKSByZXR1cm4gJ2ludDY0RGF0YTogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW50NjREYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pbnQ2NERhdGFbaV0pICYmXG4gICAgICAgICAgICAhKFxuICAgICAgICAgICAgICBtZXNzYWdlLmludDY0RGF0YVtpXSAmJlxuICAgICAgICAgICAgICAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pbnQ2NERhdGFbaV0ubG93KSAmJlxuICAgICAgICAgICAgICAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pbnQ2NERhdGFbaV0uaGlnaClcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gJ2ludDY0RGF0YTogaW50ZWdlcnxMb25nW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm5hbWUpKSByZXR1cm4gJ25hbWU6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvY1N0cmluZykpIHJldHVybiAnZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UucmF3RGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3Jhd0RhdGEnKSlcbiAgICAgICAgaWYgKCEoKG1lc3NhZ2UucmF3RGF0YSAmJiB0eXBlb2YgbWVzc2FnZS5yYXdEYXRhLmxlbmd0aCA9PT0gJ251bWJlcicpIHx8ICR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UucmF3RGF0YSkpKVxuICAgICAgICAgIHJldHVybiAncmF3RGF0YTogYnVmZmVyIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmV4dGVybmFsRGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2V4dGVybmFsRGF0YScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmV4dGVybmFsRGF0YSkpIHJldHVybiAnZXh0ZXJuYWxEYXRhOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5leHRlcm5hbERhdGEubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5KG1lc3NhZ2UuZXh0ZXJuYWxEYXRhW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnZXh0ZXJuYWxEYXRhLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZGF0YUxvY2F0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZGF0YUxvY2F0aW9uJykpXG4gICAgICAgIHN3aXRjaCAobWVzc2FnZS5kYXRhTG9jYXRpb24pIHtcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuICdkYXRhTG9jYXRpb246IGVudW0gdmFsdWUgZXhwZWN0ZWQnO1xuICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZG91YmxlRGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvdWJsZURhdGEnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5kb3VibGVEYXRhKSkgcmV0dXJuICdkb3VibGVEYXRhOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5kb3VibGVEYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5kb3VibGVEYXRhW2ldICE9PSAnbnVtYmVyJykgcmV0dXJuICdkb3VibGVEYXRhOiBudW1iZXJbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS51aW50NjREYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndWludDY0RGF0YScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLnVpbnQ2NERhdGEpKSByZXR1cm4gJ3VpbnQ2NERhdGE6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnVpbnQ2NERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLnVpbnQ2NERhdGFbaV0pICYmXG4gICAgICAgICAgICAhKFxuICAgICAgICAgICAgICBtZXNzYWdlLnVpbnQ2NERhdGFbaV0gJiZcbiAgICAgICAgICAgICAgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UudWludDY0RGF0YVtpXS5sb3cpICYmXG4gICAgICAgICAgICAgICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLnVpbnQ2NERhdGFbaV0uaGlnaClcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gJ3VpbnQ2NERhdGE6IGludGVnZXJ8TG9uZ1tdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgVGVuc29yUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvfSBUZW5zb3JQcm90b1xuICAgICAqL1xuICAgIFRlbnNvclByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVGVuc29yUHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclByb3RvKCk7XG4gICAgICBpZiAob2JqZWN0LmRpbXMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5kaW1zKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JQcm90by5kaW1zOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmRpbXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZGltcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UuZGltc1tpXSA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5kaW1zW2ldKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmRpbXNbaV0gPT09ICdzdHJpbmcnKSBtZXNzYWdlLmRpbXNbaV0gPSBwYXJzZUludChvYmplY3QuZGltc1tpXSwgMTApO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltc1tpXSA9PT0gJ251bWJlcicpIG1lc3NhZ2UuZGltc1tpXSA9IG9iamVjdC5kaW1zW2ldO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltc1tpXSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICBtZXNzYWdlLmRpbXNbaV0gPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmRpbXNbaV0ubG93ID4+PiAwLCBvYmplY3QuZGltc1tpXS5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5kYXRhVHlwZSAhPSBudWxsKSBtZXNzYWdlLmRhdGFUeXBlID0gb2JqZWN0LmRhdGFUeXBlIHwgMDtcbiAgICAgIGlmIChvYmplY3Quc2VnbWVudCAhPSBudWxsKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnNlZ21lbnQgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlRlbnNvclByb3RvLnNlZ21lbnQ6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnNlZ21lbnQgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQuZnJvbU9iamVjdChvYmplY3Quc2VnbWVudCk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmZsb2F0RGF0YSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmZsb2F0RGF0YSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yUHJvdG8uZmxvYXREYXRhOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmZsb2F0RGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5mbG9hdERhdGEubGVuZ3RoOyArK2kpIG1lc3NhZ2UuZmxvYXREYXRhW2ldID0gTnVtYmVyKG9iamVjdC5mbG9hdERhdGFbaV0pO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5pbnQzMkRhdGEpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5pbnQzMkRhdGEpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlRlbnNvclByb3RvLmludDMyRGF0YTogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5pbnQzMkRhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuaW50MzJEYXRhLmxlbmd0aDsgKytpKSBtZXNzYWdlLmludDMyRGF0YVtpXSA9IG9iamVjdC5pbnQzMkRhdGFbaV0gfCAwO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5zdHJpbmdEYXRhKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Quc3RyaW5nRGF0YSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yUHJvdG8uc3RyaW5nRGF0YTogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5zdHJpbmdEYXRhID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LnN0cmluZ0RhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3RyaW5nRGF0YVtpXSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAkdXRpbC5iYXNlNjQuZGVjb2RlKFxuICAgICAgICAgICAgICBvYmplY3Quc3RyaW5nRGF0YVtpXSxcbiAgICAgICAgICAgICAgKG1lc3NhZ2Uuc3RyaW5nRGF0YVtpXSA9ICR1dGlsLm5ld0J1ZmZlcigkdXRpbC5iYXNlNjQubGVuZ3RoKG9iamVjdC5zdHJpbmdEYXRhW2ldKSkpLFxuICAgICAgICAgICAgICAwLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICBlbHNlIGlmIChvYmplY3Quc3RyaW5nRGF0YVtpXS5sZW5ndGggPj0gMCkgbWVzc2FnZS5zdHJpbmdEYXRhW2ldID0gb2JqZWN0LnN0cmluZ0RhdGFbaV07XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmludDY0RGF0YSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmludDY0RGF0YSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yUHJvdG8uaW50NjREYXRhOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmludDY0RGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5pbnQ2NERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKCR1dGlsLkxvbmcpIChtZXNzYWdlLmludDY0RGF0YVtpXSA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5pbnQ2NERhdGFbaV0pKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaW50NjREYXRhW2ldID09PSAnc3RyaW5nJykgbWVzc2FnZS5pbnQ2NERhdGFbaV0gPSBwYXJzZUludChvYmplY3QuaW50NjREYXRhW2ldLCAxMCk7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pbnQ2NERhdGFbaV0gPT09ICdudW1iZXInKSBtZXNzYWdlLmludDY0RGF0YVtpXSA9IG9iamVjdC5pbnQ2NERhdGFbaV07XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pbnQ2NERhdGFbaV0gPT09ICdvYmplY3QnKVxuICAgICAgICAgICAgbWVzc2FnZS5pbnQ2NERhdGFbaV0gPSBuZXcgJHV0aWwuTG9uZ0JpdHMoXG4gICAgICAgICAgICAgIG9iamVjdC5pbnQ2NERhdGFbaV0ubG93ID4+PiAwLFxuICAgICAgICAgICAgICBvYmplY3QuaW50NjREYXRhW2ldLmhpZ2ggPj4+IDAsXG4gICAgICAgICAgICApLnRvTnVtYmVyKCk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0Lm5hbWUgIT0gbnVsbCkgbWVzc2FnZS5uYW1lID0gU3RyaW5nKG9iamVjdC5uYW1lKTtcbiAgICAgIGlmIChvYmplY3QuZG9jU3RyaW5nICE9IG51bGwpIG1lc3NhZ2UuZG9jU3RyaW5nID0gU3RyaW5nKG9iamVjdC5kb2NTdHJpbmcpO1xuICAgICAgaWYgKG9iamVjdC5yYXdEYXRhICE9IG51bGwpXG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnJhd0RhdGEgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICR1dGlsLmJhc2U2NC5kZWNvZGUoXG4gICAgICAgICAgICBvYmplY3QucmF3RGF0YSxcbiAgICAgICAgICAgIChtZXNzYWdlLnJhd0RhdGEgPSAkdXRpbC5uZXdCdWZmZXIoJHV0aWwuYmFzZTY0Lmxlbmd0aChvYmplY3QucmF3RGF0YSkpKSxcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgKTtcbiAgICAgICAgZWxzZSBpZiAob2JqZWN0LnJhd0RhdGEubGVuZ3RoID49IDApIG1lc3NhZ2UucmF3RGF0YSA9IG9iamVjdC5yYXdEYXRhO1xuICAgICAgaWYgKG9iamVjdC5leHRlcm5hbERhdGEpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5leHRlcm5hbERhdGEpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlRlbnNvclByb3RvLmV4dGVybmFsRGF0YTogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5leHRlcm5hbERhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZXh0ZXJuYWxEYXRhLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZXh0ZXJuYWxEYXRhW2ldICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yUHJvdG8uZXh0ZXJuYWxEYXRhOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLmV4dGVybmFsRGF0YVtpXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5mcm9tT2JqZWN0KG9iamVjdC5leHRlcm5hbERhdGFbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKG9iamVjdC5kYXRhTG9jYXRpb24pIHtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5kYXRhTG9jYXRpb24gPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICBtZXNzYWdlLmRhdGFMb2NhdGlvbiA9IG9iamVjdC5kYXRhTG9jYXRpb247XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0RFRkFVTFQnOlxuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgbWVzc2FnZS5kYXRhTG9jYXRpb24gPSAwO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdFWFRFUk5BTCc6XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBtZXNzYWdlLmRhdGFMb2NhdGlvbiA9IDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmRvdWJsZURhdGEpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5kb3VibGVEYXRhKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JQcm90by5kb3VibGVEYXRhOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmRvdWJsZURhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZG91YmxlRGF0YS5sZW5ndGg7ICsraSkgbWVzc2FnZS5kb3VibGVEYXRhW2ldID0gTnVtYmVyKG9iamVjdC5kb3VibGVEYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QudWludDY0RGF0YSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnVpbnQ2NERhdGEpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlRlbnNvclByb3RvLnVpbnQ2NERhdGE6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UudWludDY0RGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC51aW50NjREYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSAobWVzc2FnZS51aW50NjREYXRhW2ldID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LnVpbnQ2NERhdGFbaV0pKS51bnNpZ25lZCA9IHRydWU7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC51aW50NjREYXRhW2ldID09PSAnc3RyaW5nJykgbWVzc2FnZS51aW50NjREYXRhW2ldID0gcGFyc2VJbnQob2JqZWN0LnVpbnQ2NERhdGFbaV0sIDEwKTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LnVpbnQ2NERhdGFbaV0gPT09ICdudW1iZXInKSBtZXNzYWdlLnVpbnQ2NERhdGFbaV0gPSBvYmplY3QudWludDY0RGF0YVtpXTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LnVpbnQ2NERhdGFbaV0gPT09ICdvYmplY3QnKVxuICAgICAgICAgICAgbWVzc2FnZS51aW50NjREYXRhW2ldID0gbmV3ICR1dGlsLkxvbmdCaXRzKFxuICAgICAgICAgICAgICBvYmplY3QudWludDY0RGF0YVtpXS5sb3cgPj4+IDAsXG4gICAgICAgICAgICAgIG9iamVjdC51aW50NjREYXRhW2ldLmhpZ2ggPj4+IDAsXG4gICAgICAgICAgICApLnRvTnVtYmVyKHRydWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFRlbnNvclByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG99IG1lc3NhZ2UgVGVuc29yUHJvdG9cbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QuZGltcyA9IFtdO1xuICAgICAgICBvYmplY3QuZmxvYXREYXRhID0gW107XG4gICAgICAgIG9iamVjdC5pbnQzMkRhdGEgPSBbXTtcbiAgICAgICAgb2JqZWN0LnN0cmluZ0RhdGEgPSBbXTtcbiAgICAgICAgb2JqZWN0LmludDY0RGF0YSA9IFtdO1xuICAgICAgICBvYmplY3QuZG91YmxlRGF0YSA9IFtdO1xuICAgICAgICBvYmplY3QudWludDY0RGF0YSA9IFtdO1xuICAgICAgICBvYmplY3QuZXh0ZXJuYWxEYXRhID0gW107XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QuZGF0YVR5cGUgPSAwO1xuICAgICAgICBvYmplY3Quc2VnbWVudCA9IG51bGw7XG4gICAgICAgIG9iamVjdC5uYW1lID0gJyc7XG4gICAgICAgIGlmIChvcHRpb25zLmJ5dGVzID09PSBTdHJpbmcpIG9iamVjdC5yYXdEYXRhID0gJyc7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIG9iamVjdC5yYXdEYXRhID0gW107XG4gICAgICAgICAgaWYgKG9wdGlvbnMuYnl0ZXMgIT09IEFycmF5KSBvYmplY3QucmF3RGF0YSA9ICR1dGlsLm5ld0J1ZmZlcihvYmplY3QucmF3RGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9ICcnO1xuICAgICAgICBvYmplY3QuZGF0YUxvY2F0aW9uID0gb3B0aW9ucy5lbnVtcyA9PT0gU3RyaW5nID8gJ0RFRkFVTFQnIDogMDtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRpbXMgJiYgbWVzc2FnZS5kaW1zLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuZGltcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuZGltcy5sZW5ndGg7ICsrailcbiAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuZGltc1tqXSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICBvYmplY3QuZGltc1tqXSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmRpbXNbal0pIDogbWVzc2FnZS5kaW1zW2pdO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIG9iamVjdC5kaW1zW2pdID1cbiAgICAgICAgICAgICAgb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuZGltc1tqXSlcbiAgICAgICAgICAgICAgICA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlclxuICAgICAgICAgICAgICAgICAgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS5kaW1zW2pdLmxvdyA+Pj4gMCwgbWVzc2FnZS5kaW1zW2pdLmhpZ2ggPj4+IDApLnRvTnVtYmVyKClcbiAgICAgICAgICAgICAgICAgIDogbWVzc2FnZS5kaW1zW2pdO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZGF0YVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkYXRhVHlwZScpKSBvYmplY3QuZGF0YVR5cGUgPSBtZXNzYWdlLmRhdGFUeXBlO1xuICAgICAgaWYgKG1lc3NhZ2Uuc2VnbWVudCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NlZ21lbnQnKSlcbiAgICAgICAgb2JqZWN0LnNlZ21lbnQgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQudG9PYmplY3QobWVzc2FnZS5zZWdtZW50LCBvcHRpb25zKTtcbiAgICAgIGlmIChtZXNzYWdlLmZsb2F0RGF0YSAmJiBtZXNzYWdlLmZsb2F0RGF0YS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmZsb2F0RGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuZmxvYXREYXRhLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5mbG9hdERhdGFbal0gPVxuICAgICAgICAgICAgb3B0aW9ucy5qc29uICYmICFpc0Zpbml0ZShtZXNzYWdlLmZsb2F0RGF0YVtqXSkgPyBTdHJpbmcobWVzc2FnZS5mbG9hdERhdGFbal0pIDogbWVzc2FnZS5mbG9hdERhdGFbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5pbnQzMkRhdGEgJiYgbWVzc2FnZS5pbnQzMkRhdGEubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5pbnQzMkRhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmludDMyRGF0YS5sZW5ndGg7ICsraikgb2JqZWN0LmludDMyRGF0YVtqXSA9IG1lc3NhZ2UuaW50MzJEYXRhW2pdO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uuc3RyaW5nRGF0YSAmJiBtZXNzYWdlLnN0cmluZ0RhdGEubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5zdHJpbmdEYXRhID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5zdHJpbmdEYXRhLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5zdHJpbmdEYXRhW2pdID1cbiAgICAgICAgICAgIG9wdGlvbnMuYnl0ZXMgPT09IFN0cmluZ1xuICAgICAgICAgICAgICA/ICR1dGlsLmJhc2U2NC5lbmNvZGUobWVzc2FnZS5zdHJpbmdEYXRhW2pdLCAwLCBtZXNzYWdlLnN0cmluZ0RhdGFbal0ubGVuZ3RoKVxuICAgICAgICAgICAgICA6IG9wdGlvbnMuYnl0ZXMgPT09IEFycmF5XG4gICAgICAgICAgICAgICAgPyBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChtZXNzYWdlLnN0cmluZ0RhdGFbal0pXG4gICAgICAgICAgICAgICAgOiBtZXNzYWdlLnN0cmluZ0RhdGFbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5pbnQ2NERhdGEgJiYgbWVzc2FnZS5pbnQ2NERhdGEubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5pbnQ2NERhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmludDY0RGF0YS5sZW5ndGg7ICsrailcbiAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuaW50NjREYXRhW2pdID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgIG9iamVjdC5pbnQ2NERhdGFbal0gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBTdHJpbmcobWVzc2FnZS5pbnQ2NERhdGFbal0pIDogbWVzc2FnZS5pbnQ2NERhdGFbal07XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgb2JqZWN0LmludDY0RGF0YVtqXSA9XG4gICAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZ1xuICAgICAgICAgICAgICAgID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLmludDY0RGF0YVtqXSlcbiAgICAgICAgICAgICAgICA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlclxuICAgICAgICAgICAgICAgICAgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS5pbnQ2NERhdGFbal0ubG93ID4+PiAwLCBtZXNzYWdlLmludDY0RGF0YVtqXS5oaWdoID4+PiAwKS50b051bWJlcigpXG4gICAgICAgICAgICAgICAgICA6IG1lc3NhZ2UuaW50NjREYXRhW2pdO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSkgb2JqZWN0Lm5hbWUgPSBtZXNzYWdlLm5hbWU7XG4gICAgICBpZiAobWVzc2FnZS5yYXdEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncmF3RGF0YScpKVxuICAgICAgICBvYmplY3QucmF3RGF0YSA9XG4gICAgICAgICAgb3B0aW9ucy5ieXRlcyA9PT0gU3RyaW5nXG4gICAgICAgICAgICA/ICR1dGlsLmJhc2U2NC5lbmNvZGUobWVzc2FnZS5yYXdEYXRhLCAwLCBtZXNzYWdlLnJhd0RhdGEubGVuZ3RoKVxuICAgICAgICAgICAgOiBvcHRpb25zLmJ5dGVzID09PSBBcnJheVxuICAgICAgICAgICAgICA/IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG1lc3NhZ2UucmF3RGF0YSlcbiAgICAgICAgICAgICAgOiBtZXNzYWdlLnJhd0RhdGE7XG4gICAgICBpZiAobWVzc2FnZS5kb3VibGVEYXRhICYmIG1lc3NhZ2UuZG91YmxlRGF0YS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmRvdWJsZURhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmRvdWJsZURhdGEubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LmRvdWJsZURhdGFbal0gPVxuICAgICAgICAgICAgb3B0aW9ucy5qc29uICYmICFpc0Zpbml0ZShtZXNzYWdlLmRvdWJsZURhdGFbal0pID8gU3RyaW5nKG1lc3NhZ2UuZG91YmxlRGF0YVtqXSkgOiBtZXNzYWdlLmRvdWJsZURhdGFbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS51aW50NjREYXRhICYmIG1lc3NhZ2UudWludDY0RGF0YS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LnVpbnQ2NERhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnVpbnQ2NERhdGEubGVuZ3RoOyArK2opXG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLnVpbnQ2NERhdGFbal0gPT09ICdudW1iZXInKVxuICAgICAgICAgICAgb2JqZWN0LnVpbnQ2NERhdGFbal0gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBTdHJpbmcobWVzc2FnZS51aW50NjREYXRhW2pdKSA6IG1lc3NhZ2UudWludDY0RGF0YVtqXTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBvYmplY3QudWludDY0RGF0YVtqXSA9XG4gICAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZ1xuICAgICAgICAgICAgICAgID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLnVpbnQ2NERhdGFbal0pXG4gICAgICAgICAgICAgICAgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXJcbiAgICAgICAgICAgICAgICAgID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UudWludDY0RGF0YVtqXS5sb3cgPj4+IDAsIG1lc3NhZ2UudWludDY0RGF0YVtqXS5oaWdoID4+PiAwKS50b051bWJlcih0cnVlKVxuICAgICAgICAgICAgICAgICAgOiBtZXNzYWdlLnVpbnQ2NERhdGFbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSkgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgaWYgKG1lc3NhZ2UuZXh0ZXJuYWxEYXRhICYmIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuZXh0ZXJuYWxEYXRhID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5leHRlcm5hbERhdGEubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LmV4dGVybmFsRGF0YVtqXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by50b09iamVjdChtZXNzYWdlLmV4dGVybmFsRGF0YVtqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kYXRhTG9jYXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkYXRhTG9jYXRpb24nKSlcbiAgICAgICAgb2JqZWN0LmRhdGFMb2NhdGlvbiA9XG4gICAgICAgICAgb3B0aW9ucy5lbnVtcyA9PT0gU3RyaW5nXG4gICAgICAgICAgICA/ICRyb290Lm9ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9uW21lc3NhZ2UuZGF0YUxvY2F0aW9uXSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgID8gbWVzc2FnZS5kYXRhTG9jYXRpb25cbiAgICAgICAgICAgICAgOiAkcm9vdC5vbm54LlRlbnNvclByb3RvLkRhdGFMb2NhdGlvblttZXNzYWdlLmRhdGFMb2NhdGlvbl1cbiAgICAgICAgICAgIDogbWVzc2FnZS5kYXRhTG9jYXRpb247XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIFRlbnNvclByb3RvIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgVGVuc29yUHJvdG9cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguVGVuc29yUHJvdG8nO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEYXRhVHlwZSBlbnVtLlxuICAgICAqIEBuYW1lIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGVcbiAgICAgKiBAZW51bSB7bnVtYmVyfVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBVTkRFRklORUQ9MCBVTkRFRklORUQgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ9MSBGTE9BVCB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBVSU5UOD0yIFVJTlQ4IHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IElOVDg9MyBJTlQ4IHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFVJTlQxNj00IFVJTlQxNiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJTlQxNj01IElOVDE2IHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IElOVDMyPTYgSU5UMzIgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UNjQ9NyBJTlQ2NCB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBTVFJJTkc9OCBTVFJJTkcgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gQk9PTD05IEJPT0wgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQxNj0xMCBGTE9BVDE2IHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IERPVUJMRT0xMSBET1VCTEUgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gVUlOVDMyPTEyIFVJTlQzMiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBVSU5UNjQ9MTMgVUlOVDY0IHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IENPTVBMRVg2ND0xNCBDT01QTEVYNjQgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gQ09NUExFWDEyOD0xNSBDT01QTEVYMTI4IHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IEJGTE9BVDE2PTE2IEJGTE9BVDE2IHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IEZMT0FUOEU0TTNGTj0xNyBGTE9BVDhFNE0zRk4gdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ4RTRNM0ZOVVo9MTggRkxPQVQ4RTRNM0ZOVVogdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ4RTVNMj0xOSBGTE9BVDhFNU0yIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IEZMT0FUOEU1TTJGTlVaPTIwIEZMT0FUOEU1TTJGTlVaIHZhbHVlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8uRGF0YVR5cGUgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHZhbHVlc0J5SWQgPSB7fSxcbiAgICAgICAgdmFsdWVzID0gT2JqZWN0LmNyZWF0ZSh2YWx1ZXNCeUlkKTtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFswXSA9ICdVTkRFRklORUQnKV0gPSAwO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzFdID0gJ0ZMT0FUJyldID0gMTtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsyXSA9ICdVSU5UOCcpXSA9IDI7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbM10gPSAnSU5UOCcpXSA9IDM7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbNF0gPSAnVUlOVDE2JyldID0gNDtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFs1XSA9ICdJTlQxNicpXSA9IDU7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbNl0gPSAnSU5UMzInKV0gPSA2O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzddID0gJ0lOVDY0JyldID0gNztcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFs4XSA9ICdTVFJJTkcnKV0gPSA4O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzldID0gJ0JPT0wnKV0gPSA5O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzEwXSA9ICdGTE9BVDE2JyldID0gMTA7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTFdID0gJ0RPVUJMRScpXSA9IDExO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzEyXSA9ICdVSU5UMzInKV0gPSAxMjtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxM10gPSAnVUlOVDY0JyldID0gMTM7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTRdID0gJ0NPTVBMRVg2NCcpXSA9IDE0O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzE1XSA9ICdDT01QTEVYMTI4JyldID0gMTU7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTZdID0gJ0JGTE9BVDE2JyldID0gMTY7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTddID0gJ0ZMT0FUOEU0TTNGTicpXSA9IDE3O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzE4XSA9ICdGTE9BVDhFNE0zRk5VWicpXSA9IDE4O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzE5XSA9ICdGTE9BVDhFNU0yJyldID0gMTk7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMjBdID0gJ0ZMT0FUOEU1TTJGTlVaJyldID0gMjA7XG4gICAgICByZXR1cm4gdmFsdWVzO1xuICAgIH0pKCk7XG5cbiAgICBUZW5zb3JQcm90by5TZWdtZW50ID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKlxuICAgICAgICogUHJvcGVydGllcyBvZiBhIFNlZ21lbnQuXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICogQGludGVyZmFjZSBJU2VnbWVudFxuICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbYmVnaW5dIFNlZ21lbnQgYmVnaW5cbiAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfExvbmd8bnVsbH0gW2VuZF0gU2VnbWVudCBlbmRcbiAgICAgICAqL1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgU2VnbWVudC5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBTZWdtZW50LlxuICAgICAgICogQGltcGxlbWVudHMgSVNlZ21lbnRcbiAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclByb3RvLklTZWdtZW50PX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKi9cbiAgICAgIGZ1bmN0aW9uIFNlZ21lbnQocHJvcGVydGllcykge1xuICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgfVxuXG4gICAgICAvKipcbiAgICAgICAqIFNlZ21lbnQgYmVnaW4uXG4gICAgICAgKiBAbWVtYmVyIHtudW1iZXJ8TG9uZ30gYmVnaW5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBTZWdtZW50LnByb3RvdHlwZS5iZWdpbiA9ICR1dGlsLkxvbmcgPyAkdXRpbC5Mb25nLmZyb21CaXRzKDAsIDAsIGZhbHNlKSA6IDA7XG5cbiAgICAgIC8qKlxuICAgICAgICogU2VnbWVudCBlbmQuXG4gICAgICAgKiBAbWVtYmVyIHtudW1iZXJ8TG9uZ30gZW5kXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC5wcm90b3R5cGUuZW5kID0gJHV0aWwuTG9uZyA/ICR1dGlsLkxvbmcuZnJvbUJpdHMoMCwgMCwgZmFsc2UpIDogMDtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgbmV3IFNlZ21lbnQgaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclByb3RvLklTZWdtZW50PX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JQcm90by5TZWdtZW50fSBTZWdtZW50IGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTZWdtZW50KHByb3BlcnRpZXMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU2VnbWVudCBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclByb3RvLlNlZ21lbnQudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnR9IG1lc3NhZ2UgU2VnbWVudCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICovXG4gICAgICBTZWdtZW50LmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgIGlmIChtZXNzYWdlLmJlZ2luICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2JlZ2luJykpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAwID0qLyA4KS5pbnQ2NChtZXNzYWdlLmJlZ2luKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZW5kICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2VuZCcpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMCA9Ki8gMTYpLmludDY0KG1lc3NhZ2UuZW5kKTtcbiAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFNlZ21lbnQgbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JQcm90by5TZWdtZW50LnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclByb3RvLklTZWdtZW50fSBtZXNzYWdlIFNlZ21lbnQgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGEgU2VnbWVudCBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yUHJvdG8uU2VnbWVudH0gU2VnbWVudFxuICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICovXG4gICAgICBTZWdtZW50LmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQoKTtcbiAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgbWVzc2FnZS5iZWdpbiA9IHJlYWRlci5pbnQ2NCgpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgICBtZXNzYWdlLmVuZCA9IHJlYWRlci5pbnQ2NCgpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGEgU2VnbWVudCBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JQcm90by5TZWdtZW50fSBTZWdtZW50XG4gICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQuZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogVmVyaWZpZXMgYSBTZWdtZW50IG1lc3NhZ2UuXG4gICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICAgIGlmIChtZXNzYWdlLmJlZ2luICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnYmVnaW4nKSlcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuYmVnaW4pICYmXG4gICAgICAgICAgICAhKG1lc3NhZ2UuYmVnaW4gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuYmVnaW4ubG93KSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5iZWdpbi5oaWdoKSlcbiAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gJ2JlZ2luOiBpbnRlZ2VyfExvbmcgZXhwZWN0ZWQnO1xuICAgICAgICBpZiAobWVzc2FnZS5lbmQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdlbmQnKSlcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZW5kKSAmJlxuICAgICAgICAgICAgIShtZXNzYWdlLmVuZCAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5lbmQubG93KSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5lbmQuaGlnaCkpXG4gICAgICAgICAgKVxuICAgICAgICAgICAgcmV0dXJuICdlbmQ6IGludGVnZXJ8TG9uZyBleHBlY3RlZCc7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgU2VnbWVudCBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yUHJvdG8uU2VnbWVudH0gU2VnbWVudFxuICAgICAgICovXG4gICAgICBTZWdtZW50LmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UZW5zb3JQcm90by5TZWdtZW50KSByZXR1cm4gb2JqZWN0O1xuICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQoKTtcbiAgICAgICAgaWYgKG9iamVjdC5iZWdpbiAhPSBudWxsKVxuICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSAobWVzc2FnZS5iZWdpbiA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5iZWdpbikpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5iZWdpbiA9PT0gJ3N0cmluZycpIG1lc3NhZ2UuYmVnaW4gPSBwYXJzZUludChvYmplY3QuYmVnaW4sIDEwKTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmJlZ2luID09PSAnbnVtYmVyJykgbWVzc2FnZS5iZWdpbiA9IG9iamVjdC5iZWdpbjtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmJlZ2luID09PSAnb2JqZWN0JylcbiAgICAgICAgICAgIG1lc3NhZ2UuYmVnaW4gPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmJlZ2luLmxvdyA+Pj4gMCwgb2JqZWN0LmJlZ2luLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCk7XG4gICAgICAgIGlmIChvYmplY3QuZW5kICE9IG51bGwpXG4gICAgICAgICAgaWYgKCR1dGlsLkxvbmcpIChtZXNzYWdlLmVuZCA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5lbmQpKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZW5kID09PSAnc3RyaW5nJykgbWVzc2FnZS5lbmQgPSBwYXJzZUludChvYmplY3QuZW5kLCAxMCk7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5lbmQgPT09ICdudW1iZXInKSBtZXNzYWdlLmVuZCA9IG9iamVjdC5lbmQ7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5lbmQgPT09ICdvYmplY3QnKVxuICAgICAgICAgICAgbWVzc2FnZS5lbmQgPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmVuZC5sb3cgPj4+IDAsIG9iamVjdC5lbmQuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFNlZ21lbnQgbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG8uU2VnbWVudH0gbWVzc2FnZSBTZWdtZW50XG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQudG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgaWYgKCR1dGlsLkxvbmcpIHtcbiAgICAgICAgICAgIHZhciBsb25nID0gbmV3ICR1dGlsLkxvbmcoMCwgMCwgZmFsc2UpO1xuICAgICAgICAgICAgb2JqZWN0LmJlZ2luID1cbiAgICAgICAgICAgICAgb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gbG9uZy50b1N0cmluZygpIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbG9uZy50b051bWJlcigpIDogbG9uZztcbiAgICAgICAgICB9IGVsc2Ugb2JqZWN0LmJlZ2luID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJzAnIDogMDtcbiAgICAgICAgICBpZiAoJHV0aWwuTG9uZykge1xuICAgICAgICAgICAgdmFyIGxvbmcgPSBuZXcgJHV0aWwuTG9uZygwLCAwLCBmYWxzZSk7XG4gICAgICAgICAgICBvYmplY3QuZW5kID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gbG9uZy50b1N0cmluZygpIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbG9uZy50b051bWJlcigpIDogbG9uZztcbiAgICAgICAgICB9IGVsc2Ugb2JqZWN0LmVuZCA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICcwJyA6IDA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1lc3NhZ2UuYmVnaW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdiZWdpbicpKVxuICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5iZWdpbiA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICBvYmplY3QuYmVnaW4gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBTdHJpbmcobWVzc2FnZS5iZWdpbikgOiBtZXNzYWdlLmJlZ2luO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIG9iamVjdC5iZWdpbiA9XG4gICAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZ1xuICAgICAgICAgICAgICAgID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLmJlZ2luKVxuICAgICAgICAgICAgICAgIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyXG4gICAgICAgICAgICAgICAgICA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmJlZ2luLmxvdyA+Pj4gMCwgbWVzc2FnZS5iZWdpbi5oaWdoID4+PiAwKS50b051bWJlcigpXG4gICAgICAgICAgICAgICAgICA6IG1lc3NhZ2UuYmVnaW47XG4gICAgICAgIGlmIChtZXNzYWdlLmVuZCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2VuZCcpKVxuICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5lbmQgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgb2JqZWN0LmVuZCA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmVuZCkgOiBtZXNzYWdlLmVuZDtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBvYmplY3QuZW5kID1cbiAgICAgICAgICAgICAgb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuZW5kKVxuICAgICAgICAgICAgICAgIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyXG4gICAgICAgICAgICAgICAgICA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmVuZC5sb3cgPj4+IDAsIG1lc3NhZ2UuZW5kLmhpZ2ggPj4+IDApLnRvTnVtYmVyKClcbiAgICAgICAgICAgICAgICAgIDogbWVzc2FnZS5lbmQ7XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnZlcnRzIHRoaXMgU2VnbWVudCB0byBKU09OLlxuICAgICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFNlZ21lbnRcbiAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQuZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UZW5zb3JQcm90by5TZWdtZW50JztcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBTZWdtZW50O1xuICAgIH0pKCk7XG5cbiAgICAvKipcbiAgICAgKiBEYXRhTG9jYXRpb24gZW51bS5cbiAgICAgKiBAbmFtZSBvbm54LlRlbnNvclByb3RvLkRhdGFMb2NhdGlvblxuICAgICAqIEBlbnVtIHtudW1iZXJ9XG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IERFRkFVTFQ9MCBERUZBVUxUIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IEVYVEVSTkFMPTEgRVhURVJOQUwgdmFsdWVcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5EYXRhTG9jYXRpb24gPSAoZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHZhbHVlc0J5SWQgPSB7fSxcbiAgICAgICAgdmFsdWVzID0gT2JqZWN0LmNyZWF0ZSh2YWx1ZXNCeUlkKTtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFswXSA9ICdERUZBVUxUJyldID0gMDtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxXSA9ICdFWFRFUk5BTCcpXSA9IDE7XG4gICAgICByZXR1cm4gdmFsdWVzO1xuICAgIH0pKCk7XG5cbiAgICByZXR1cm4gVGVuc29yUHJvdG87XG4gIH0pKCk7XG5cbiAgb25ueC5TcGFyc2VUZW5zb3JQcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhIFNwYXJzZVRlbnNvclByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGludGVyZmFjZSBJU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAcHJvcGVydHkge29ubnguSVRlbnNvclByb3RvfG51bGx9IFt2YWx1ZXNdIFNwYXJzZVRlbnNvclByb3RvIHZhbHVlc1xuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JVGVuc29yUHJvdG98bnVsbH0gW2luZGljZXNdIFNwYXJzZVRlbnNvclByb3RvIGluZGljZXNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5LjxudW1iZXJ8TG9uZz58bnVsbH0gW2RpbXNdIFNwYXJzZVRlbnNvclByb3RvIGRpbXNcbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgU3BhcnNlVGVuc29yUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBTcGFyc2VUZW5zb3JQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29ubnguSVNwYXJzZVRlbnNvclByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICovXG4gICAgZnVuY3Rpb24gU3BhcnNlVGVuc29yUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgdGhpcy5kaW1zID0gW107XG4gICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3BhcnNlVGVuc29yUHJvdG8gdmFsdWVzLlxuICAgICAqIEBtZW1iZXIge29ubnguSVRlbnNvclByb3RvfG51bGx8dW5kZWZpbmVkfSB2YWx1ZXNcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFNwYXJzZVRlbnNvclByb3RvLnByb3RvdHlwZS52YWx1ZXMgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogU3BhcnNlVGVuc29yUHJvdG8gaW5kaWNlcy5cbiAgICAgKiBAbWVtYmVyIHtvbm54LklUZW5zb3JQcm90b3xudWxsfHVuZGVmaW5lZH0gaW5kaWNlc1xuICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8ucHJvdG90eXBlLmluZGljZXMgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogU3BhcnNlVGVuc29yUHJvdG8gZGltcy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyfExvbmc+fSBkaW1zXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by5wcm90b3R5cGUuZGltcyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IFNwYXJzZVRlbnNvclByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklTcGFyc2VUZW5zb3JQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtvbm54LlNwYXJzZVRlbnNvclByb3RvfSBTcGFyc2VUZW5zb3JQcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIFNwYXJzZVRlbnNvclByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbmV3IFNwYXJzZVRlbnNvclByb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU3BhcnNlVGVuc29yUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5TcGFyc2VUZW5zb3JQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklTcGFyc2VUZW5zb3JQcm90b30gbWVzc2FnZSBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS52YWx1ZXMgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAndmFsdWVzJykpXG4gICAgICAgICRyb290Lm9ubnguVGVuc29yUHJvdG8uZW5jb2RlKG1lc3NhZ2UudmFsdWVzLCB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovIDEwKS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuaW5kaWNlcyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdpbmRpY2VzJykpXG4gICAgICAgICRyb290Lm9ubnguVGVuc29yUHJvdG8uZW5jb2RlKG1lc3NhZ2UuaW5kaWNlcywgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLyAxOCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmRpbXMgIT0gbnVsbCAmJiBtZXNzYWdlLmRpbXMubGVuZ3RoKSB7XG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMywgd2lyZVR5cGUgMiA9Ki8gMjYpLmZvcmsoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmRpbXMubGVuZ3RoOyArK2kpIHdyaXRlci5pbnQ2NChtZXNzYWdlLmRpbXNbaV0pO1xuICAgICAgICB3cml0ZXIubGRlbGltKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gd3JpdGVyO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU3BhcnNlVGVuc29yUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5TcGFyc2VUZW5zb3JQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklTcGFyc2VUZW5zb3JQcm90b30gbWVzc2FnZSBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlNwYXJzZVRlbnNvclByb3RvfSBTcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8oKTtcbiAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICBtZXNzYWdlLnZhbHVlcyA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5kaWNlcyA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDM6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZGltcyAmJiBtZXNzYWdlLmRpbXMubGVuZ3RoKSkgbWVzc2FnZS5kaW1zID0gW107XG4gICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgIHZhciBlbmQyID0gcmVhZGVyLnVpbnQzMigpICsgcmVhZGVyLnBvcztcbiAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKSBtZXNzYWdlLmRpbXMucHVzaChyZWFkZXIuaW50NjQoKSk7XG4gICAgICAgICAgICB9IGVsc2UgbWVzc2FnZS5kaW1zLnB1c2gocmVhZGVyLmludDY0KCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcmV0dXJucyB7b25ueC5TcGFyc2VUZW5zb3JQcm90b30gU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFNwYXJzZVRlbnNvclByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVmVyaWZpZXMgYSBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlLlxuICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIFNwYXJzZVRlbnNvclByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLnZhbHVlcyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3ZhbHVlcycpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udmVyaWZ5KG1lc3NhZ2UudmFsdWVzKTtcbiAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3ZhbHVlcy4nICsgZXJyb3I7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5pbmRpY2VzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaW5kaWNlcycpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udmVyaWZ5KG1lc3NhZ2UuaW5kaWNlcyk7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdpbmRpY2VzLicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRpbXMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkaW1zJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuZGltcykpIHJldHVybiAnZGltczogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZGltcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltc1tpXSkgJiZcbiAgICAgICAgICAgICEobWVzc2FnZS5kaW1zW2ldICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbXNbaV0ubG93KSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kaW1zW2ldLmhpZ2gpKVxuICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiAnZGltczogaW50ZWdlcnxMb25nW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICogQHJldHVybnMge29ubnguU3BhcnNlVGVuc29yUHJvdG99IFNwYXJzZVRlbnNvclByb3RvXG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QudmFsdWVzICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudmFsdWVzICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5TcGFyc2VUZW5zb3JQcm90by52YWx1ZXM6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnZhbHVlcyA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3QudmFsdWVzKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuaW5kaWNlcyAhPSBudWxsKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmluZGljZXMgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlNwYXJzZVRlbnNvclByb3RvLmluZGljZXM6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmluZGljZXMgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLmZyb21PYmplY3Qob2JqZWN0LmluZGljZXMpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5kaW1zKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuZGltcykpIHRocm93IFR5cGVFcnJvcignLm9ubnguU3BhcnNlVGVuc29yUHJvdG8uZGltczogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5kaW1zID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmRpbXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKCR1dGlsLkxvbmcpIChtZXNzYWdlLmRpbXNbaV0gPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QuZGltc1tpXSkpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5kaW1zW2ldID09PSAnc3RyaW5nJykgbWVzc2FnZS5kaW1zW2ldID0gcGFyc2VJbnQob2JqZWN0LmRpbXNbaV0sIDEwKTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmRpbXNbaV0gPT09ICdudW1iZXInKSBtZXNzYWdlLmRpbXNbaV0gPSBvYmplY3QuZGltc1tpXTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmRpbXNbaV0gPT09ICdvYmplY3QnKVxuICAgICAgICAgICAgbWVzc2FnZS5kaW1zW2ldID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC5kaW1zW2ldLmxvdyA+Pj4gMCwgb2JqZWN0LmRpbXNbaV0uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LlNwYXJzZVRlbnNvclByb3RvfSBtZXNzYWdlIFNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIG9iamVjdC5kaW1zID0gW107XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QudmFsdWVzID0gbnVsbDtcbiAgICAgICAgb2JqZWN0LmluZGljZXMgPSBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudmFsdWVzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmFsdWVzJykpXG4gICAgICAgIG9iamVjdC52YWx1ZXMgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2UudmFsdWVzLCBvcHRpb25zKTtcbiAgICAgIGlmIChtZXNzYWdlLmluZGljZXMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpbmRpY2VzJykpXG4gICAgICAgIG9iamVjdC5pbmRpY2VzID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by50b09iamVjdChtZXNzYWdlLmluZGljZXMsIG9wdGlvbnMpO1xuICAgICAgaWYgKG1lc3NhZ2UuZGltcyAmJiBtZXNzYWdlLmRpbXMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5kaW1zID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5kaW1zLmxlbmd0aDsgKytqKVxuICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5kaW1zW2pdID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgIG9iamVjdC5kaW1zW2pdID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuZGltc1tqXSkgOiBtZXNzYWdlLmRpbXNbal07XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgb2JqZWN0LmRpbXNbal0gPVxuICAgICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgICA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5kaW1zW2pdKVxuICAgICAgICAgICAgICAgIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyXG4gICAgICAgICAgICAgICAgICA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmRpbXNbal0ubG93ID4+PiAwLCBtZXNzYWdlLmRpbXNbal0uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgICAgOiBtZXNzYWdlLmRpbXNbal07XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIFNwYXJzZVRlbnNvclByb3RvIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAqL1xuICAgIFNwYXJzZVRlbnNvclByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguU3BhcnNlVGVuc29yUHJvdG8nO1xuICAgIH07XG5cbiAgICByZXR1cm4gU3BhcnNlVGVuc29yUHJvdG87XG4gIH0pKCk7XG5cbiAgb25ueC5UZW5zb3JTaGFwZVByb3RvID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgVGVuc29yU2hhcGVQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSVRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LlRlbnNvclNoYXBlUHJvdG8uSURpbWVuc2lvbj58bnVsbH0gW2RpbV0gVGVuc29yU2hhcGVQcm90byBkaW1cbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgVGVuc29yU2hhcGVQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFRlbnNvclNoYXBlUHJvdG8uXG4gICAgICogQGltcGxlbWVudHMgSVRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29ubnguSVRlbnNvclNoYXBlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBUZW5zb3JTaGFwZVByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgIHRoaXMuZGltID0gW107XG4gICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGVuc29yU2hhcGVQcm90byBkaW0uXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguVGVuc29yU2hhcGVQcm90by5JRGltZW5zaW9uPn0gZGltXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclNoYXBlUHJvdG8ucHJvdG90eXBlLmRpbSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IFRlbnNvclNoYXBlUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yU2hhcGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclNoYXBlUHJvdG99IFRlbnNvclNoYXBlUHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JTaGFwZVByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbmV3IFRlbnNvclNoYXBlUHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yU2hhcGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVRlbnNvclNoYXBlUHJvdG99IG1lc3NhZ2UgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVGVuc29yU2hhcGVQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLmRpbSAhPSBudWxsICYmIG1lc3NhZ2UuZGltLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmRpbS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UuZGltW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICByZXR1cm4gd3JpdGVyO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclNoYXBlUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JTaGFwZVByb3RvfSBtZXNzYWdlIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFRlbnNvclNoYXBlUHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JTaGFwZVByb3RvfSBUZW5zb3JTaGFwZVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBUZW5zb3JTaGFwZVByb3RvLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8oKTtcbiAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmRpbSAmJiBtZXNzYWdlLmRpbS5sZW5ndGgpKSBtZXNzYWdlLmRpbSA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5kaW0ucHVzaCgkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90b30gVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVGVuc29yU2hhcGVQcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFZlcmlmaWVzIGEgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlLlxuICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICovXG4gICAgVGVuc29yU2hhcGVQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5kaW0gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkaW0nKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5kaW0pKSByZXR1cm4gJ2RpbTogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZGltLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbi52ZXJpZnkobWVzc2FnZS5kaW1baV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdkaW0uJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90b30gVGVuc29yU2hhcGVQcm90b1xuICAgICAqL1xuICAgIFRlbnNvclNoYXBlUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvKSByZXR1cm4gb2JqZWN0O1xuICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvKCk7XG4gICAgICBpZiAob2JqZWN0LmRpbSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmRpbSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yU2hhcGVQcm90by5kaW06IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuZGltID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmRpbS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmRpbVtpXSAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yU2hhcGVQcm90by5kaW06IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UuZGltW2ldID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbi5mcm9tT2JqZWN0KG9iamVjdC5kaW1baV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yU2hhcGVQcm90b30gbWVzc2FnZSBUZW5zb3JTaGFwZVByb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBUZW5zb3JTaGFwZVByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykgb2JqZWN0LmRpbSA9IFtdO1xuICAgICAgaWYgKG1lc3NhZ2UuZGltICYmIG1lc3NhZ2UuZGltLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuZGltID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5kaW0ubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LmRpbVtqXSA9ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24udG9PYmplY3QobWVzc2FnZS5kaW1bal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhpcyBUZW5zb3JTaGFwZVByb3RvIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgVGVuc29yU2hhcGVQcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBUZW5zb3JTaGFwZVByb3RvLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlRlbnNvclNoYXBlUHJvdG8nO1xuICAgIH07XG5cbiAgICBUZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbiA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAvKipcbiAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBEaW1lbnNpb24uXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICAgKiBAaW50ZXJmYWNlIElEaW1lbnNpb25cbiAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfExvbmd8bnVsbH0gW2RpbVZhbHVlXSBEaW1lbnNpb24gZGltVmFsdWVcbiAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkaW1QYXJhbV0gRGltZW5zaW9uIGRpbVBhcmFtXG4gICAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZGVub3RhdGlvbl0gRGltZW5zaW9uIGRlbm90YXRpb25cbiAgICAgICAqL1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgRGltZW5zaW9uLlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgRGltZW5zaW9uLlxuICAgICAgICogQGltcGxlbWVudHMgSURpbWVuc2lvblxuICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yU2hhcGVQcm90by5JRGltZW5zaW9uPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKi9cbiAgICAgIGZ1bmN0aW9uIERpbWVuc2lvbihwcm9wZXJ0aWVzKSB7XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICB9XG5cbiAgICAgIC8qKlxuICAgICAgICogRGltZW5zaW9uIGRpbVZhbHVlLlxuICAgICAgICogQG1lbWJlciB7bnVtYmVyfExvbmd8bnVsbHx1bmRlZmluZWR9IGRpbVZhbHVlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIERpbWVuc2lvbi5wcm90b3R5cGUuZGltVmFsdWUgPSBudWxsO1xuXG4gICAgICAvKipcbiAgICAgICAqIERpbWVuc2lvbiBkaW1QYXJhbS5cbiAgICAgICAqIEBtZW1iZXIge3N0cmluZ3xudWxsfHVuZGVmaW5lZH0gZGltUGFyYW1cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLnByb3RvdHlwZS5kaW1QYXJhbSA9IG51bGw7XG5cbiAgICAgIC8qKlxuICAgICAgICogRGltZW5zaW9uIGRlbm90YXRpb24uXG4gICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRlbm90YXRpb25cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLnByb3RvdHlwZS5kZW5vdGF0aW9uID0gJyc7XG5cbiAgICAgIC8vIE9uZU9mIGZpZWxkIG5hbWVzIGJvdW5kIHRvIHZpcnR1YWwgZ2V0dGVycyBhbmQgc2V0dGVyc1xuICAgICAgdmFyICRvbmVPZkZpZWxkcztcblxuICAgICAgLyoqXG4gICAgICAgKiBEaW1lbnNpb24gdmFsdWUuXG4gICAgICAgKiBAbWVtYmVyIHtcImRpbVZhbHVlXCJ8XCJkaW1QYXJhbVwifHVuZGVmaW5lZH0gdmFsdWVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KERpbWVuc2lvbi5wcm90b3R5cGUsICd2YWx1ZScsIHtcbiAgICAgICAgZ2V0OiAkdXRpbC5vbmVPZkdldHRlcigoJG9uZU9mRmllbGRzID0gWydkaW1WYWx1ZScsICdkaW1QYXJhbSddKSksXG4gICAgICAgIHNldDogJHV0aWwub25lT2ZTZXR0ZXIoJG9uZU9mRmllbGRzKSxcbiAgICAgIH0pO1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBuZXcgRGltZW5zaW9uIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yU2hhcGVQcm90by5JRGltZW5zaW9uPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbn0gRGltZW5zaW9uIGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIERpbWVuc2lvbi5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICByZXR1cm4gbmV3IERpbWVuc2lvbihwcm9wZXJ0aWVzKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIERpbWVuc2lvbiBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JTaGFwZVByb3RvLklEaW1lbnNpb259IG1lc3NhZ2UgRGltZW5zaW9uIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIERpbWVuc2lvbi5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICBpZiAobWVzc2FnZS5kaW1WYWx1ZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkaW1WYWx1ZScpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMCA9Ki8gOCkuaW50NjQobWVzc2FnZS5kaW1WYWx1ZSk7XG4gICAgICAgIGlmIChtZXNzYWdlLmRpbVBhcmFtICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RpbVBhcmFtJykpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLyAxOCkuc3RyaW5nKG1lc3NhZ2UuZGltUGFyYW0pO1xuICAgICAgICBpZiAobWVzc2FnZS5kZW5vdGF0aW9uICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2Rlbm90YXRpb24nKSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDIgPSovIDI2KS5zdHJpbmcobWVzc2FnZS5kZW5vdGF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIERpbWVuc2lvbiBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JTaGFwZVByb3RvLklEaW1lbnNpb259IG1lc3NhZ2UgRGltZW5zaW9uIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIERpbWVuc2lvbi5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGEgRGltZW5zaW9uIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb259IERpbWVuc2lvblxuICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICovXG4gICAgICBEaW1lbnNpb24uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24oKTtcbiAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgbWVzc2FnZS5kaW1WYWx1ZSA9IHJlYWRlci5pbnQ2NCgpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgICBtZXNzYWdlLmRpbVBhcmFtID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgMzoge1xuICAgICAgICAgICAgICBtZXNzYWdlLmRlbm90YXRpb24gPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBEaW1lbnNpb24gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9ufSBEaW1lbnNpb25cbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIFZlcmlmaWVzIGEgRGltZW5zaW9uIG1lc3NhZ2UuXG4gICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICovXG4gICAgICBEaW1lbnNpb24udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICAgIHZhciBwcm9wZXJ0aWVzID0ge307XG4gICAgICAgIGlmIChtZXNzYWdlLmRpbVZhbHVlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZGltVmFsdWUnKSkge1xuICAgICAgICAgIHByb3BlcnRpZXMudmFsdWUgPSAxO1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kaW1WYWx1ZSkgJiZcbiAgICAgICAgICAgICEobWVzc2FnZS5kaW1WYWx1ZSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kaW1WYWx1ZS5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbVZhbHVlLmhpZ2gpKVxuICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiAnZGltVmFsdWU6IGludGVnZXJ8TG9uZyBleHBlY3RlZCc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1lc3NhZ2UuZGltUGFyYW0gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkaW1QYXJhbScpKSB7XG4gICAgICAgICAgaWYgKHByb3BlcnRpZXMudmFsdWUgPT09IDEpIHJldHVybiAndmFsdWU6IG11bHRpcGxlIHZhbHVlcyc7XG4gICAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRpbVBhcmFtKSkgcmV0dXJuICdkaW1QYXJhbTogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVzc2FnZS5kZW5vdGF0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZGVub3RhdGlvbicpKVxuICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kZW5vdGF0aW9uKSkgcmV0dXJuICdkZW5vdGF0aW9uOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIERpbWVuc2lvbiBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9ufSBEaW1lbnNpb25cbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbikgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbigpO1xuICAgICAgICBpZiAob2JqZWN0LmRpbVZhbHVlICE9IG51bGwpXG4gICAgICAgICAgaWYgKCR1dGlsLkxvbmcpIChtZXNzYWdlLmRpbVZhbHVlID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmRpbVZhbHVlKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmRpbVZhbHVlID09PSAnc3RyaW5nJykgbWVzc2FnZS5kaW1WYWx1ZSA9IHBhcnNlSW50KG9iamVjdC5kaW1WYWx1ZSwgMTApO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltVmFsdWUgPT09ICdudW1iZXInKSBtZXNzYWdlLmRpbVZhbHVlID0gb2JqZWN0LmRpbVZhbHVlO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltVmFsdWUgPT09ICdvYmplY3QnKVxuICAgICAgICAgICAgbWVzc2FnZS5kaW1WYWx1ZSA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuZGltVmFsdWUubG93ID4+PiAwLCBvYmplY3QuZGltVmFsdWUuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgICAgaWYgKG9iamVjdC5kaW1QYXJhbSAhPSBudWxsKSBtZXNzYWdlLmRpbVBhcmFtID0gU3RyaW5nKG9iamVjdC5kaW1QYXJhbSk7XG4gICAgICAgIGlmIChvYmplY3QuZGVub3RhdGlvbiAhPSBudWxsKSBtZXNzYWdlLmRlbm90YXRpb24gPSBTdHJpbmcob2JqZWN0LmRlbm90YXRpb24pO1xuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgRGltZW5zaW9uIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbn0gbWVzc2FnZSBEaW1lbnNpb25cbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykgb2JqZWN0LmRlbm90YXRpb24gPSAnJztcbiAgICAgICAgaWYgKG1lc3NhZ2UuZGltVmFsdWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkaW1WYWx1ZScpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmRpbVZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgIG9iamVjdC5kaW1WYWx1ZSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmRpbVZhbHVlKSA6IG1lc3NhZ2UuZGltVmFsdWU7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgb2JqZWN0LmRpbVZhbHVlID1cbiAgICAgICAgICAgICAgb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuZGltVmFsdWUpXG4gICAgICAgICAgICAgICAgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXJcbiAgICAgICAgICAgICAgICAgID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuZGltVmFsdWUubG93ID4+PiAwLCBtZXNzYWdlLmRpbVZhbHVlLmhpZ2ggPj4+IDApLnRvTnVtYmVyKClcbiAgICAgICAgICAgICAgICAgIDogbWVzc2FnZS5kaW1WYWx1ZTtcbiAgICAgICAgICBpZiAob3B0aW9ucy5vbmVvZnMpIG9iamVjdC52YWx1ZSA9ICdkaW1WYWx1ZSc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1lc3NhZ2UuZGltUGFyYW0gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkaW1QYXJhbScpKSB7XG4gICAgICAgICAgb2JqZWN0LmRpbVBhcmFtID0gbWVzc2FnZS5kaW1QYXJhbTtcbiAgICAgICAgICBpZiAob3B0aW9ucy5vbmVvZnMpIG9iamVjdC52YWx1ZSA9ICdkaW1QYXJhbSc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1lc3NhZ2UuZGVub3RhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2Rlbm90YXRpb24nKSkgb2JqZWN0LmRlbm90YXRpb24gPSBtZXNzYWdlLmRlbm90YXRpb247XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnZlcnRzIHRoaXMgRGltZW5zaW9uIHRvIEpTT04uXG4gICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIERpbWVuc2lvbi5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgRGltZW5zaW9uXG4gICAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24nO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIERpbWVuc2lvbjtcbiAgICB9KSgpO1xuXG4gICAgcmV0dXJuIFRlbnNvclNoYXBlUHJvdG87XG4gIH0pKCk7XG5cbiAgb25ueC5UeXBlUHJvdG8gPSAoZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgb2YgYSBUeXBlUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElUeXBlUHJvdG9cbiAgICAgKiBAcHJvcGVydHkge29ubnguVHlwZVByb3RvLklUZW5zb3J8bnVsbH0gW3RlbnNvclR5cGVdIFR5cGVQcm90byB0ZW5zb3JUeXBlXG4gICAgICogQHByb3BlcnR5IHtvbm54LlR5cGVQcm90by5JU2VxdWVuY2V8bnVsbH0gW3NlcXVlbmNlVHlwZV0gVHlwZVByb3RvIHNlcXVlbmNlVHlwZVxuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5UeXBlUHJvdG8uSU1hcHxudWxsfSBbbWFwVHlwZV0gVHlwZVByb3RvIG1hcFR5cGVcbiAgICAgKiBAcHJvcGVydHkge29ubnguVHlwZVByb3RvLklPcHRpb25hbHxudWxsfSBbb3B0aW9uYWxUeXBlXSBUeXBlUHJvdG8gb3B0aW9uYWxUeXBlXG4gICAgICogQHByb3BlcnR5IHtvbm54LlR5cGVQcm90by5JU3BhcnNlVGVuc29yfG51bGx9IFtzcGFyc2VUZW5zb3JUeXBlXSBUeXBlUHJvdG8gc3BhcnNlVGVuc29yVHlwZVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkZW5vdGF0aW9uXSBUeXBlUHJvdG8gZGVub3RhdGlvblxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBUeXBlUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBUeXBlUHJvdG8uXG4gICAgICogQGltcGxlbWVudHMgSVR5cGVQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JVHlwZVByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICovXG4gICAgZnVuY3Rpb24gVHlwZVByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUeXBlUHJvdG8gdGVuc29yVHlwZS5cbiAgICAgKiBAbWVtYmVyIHtvbm54LlR5cGVQcm90by5JVGVuc29yfG51bGx8dW5kZWZpbmVkfSB0ZW5zb3JUeXBlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVHlwZVByb3RvLnByb3RvdHlwZS50ZW5zb3JUeXBlID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFR5cGVQcm90byBzZXF1ZW5jZVR5cGUuXG4gICAgICogQG1lbWJlciB7b25ueC5UeXBlUHJvdG8uSVNlcXVlbmNlfG51bGx8dW5kZWZpbmVkfSBzZXF1ZW5jZVR5cGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8ucHJvdG90eXBlLnNlcXVlbmNlVHlwZSA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBUeXBlUHJvdG8gbWFwVHlwZS5cbiAgICAgKiBAbWVtYmVyIHtvbm54LlR5cGVQcm90by5JTWFwfG51bGx8dW5kZWZpbmVkfSBtYXBUeXBlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVHlwZVByb3RvLnByb3RvdHlwZS5tYXBUeXBlID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFR5cGVQcm90byBvcHRpb25hbFR5cGUuXG4gICAgICogQG1lbWJlciB7b25ueC5UeXBlUHJvdG8uSU9wdGlvbmFsfG51bGx8dW5kZWZpbmVkfSBvcHRpb25hbFR5cGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8ucHJvdG90eXBlLm9wdGlvbmFsVHlwZSA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBUeXBlUHJvdG8gc3BhcnNlVGVuc29yVHlwZS5cbiAgICAgKiBAbWVtYmVyIHtvbm54LlR5cGVQcm90by5JU3BhcnNlVGVuc29yfG51bGx8dW5kZWZpbmVkfSBzcGFyc2VUZW5zb3JUeXBlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVHlwZVByb3RvLnByb3RvdHlwZS5zcGFyc2VUZW5zb3JUeXBlID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFR5cGVQcm90byBkZW5vdGF0aW9uLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gZGVub3RhdGlvblxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFR5cGVQcm90by5wcm90b3R5cGUuZGVub3RhdGlvbiA9ICcnO1xuXG4gICAgLy8gT25lT2YgZmllbGQgbmFtZXMgYm91bmQgdG8gdmlydHVhbCBnZXR0ZXJzIGFuZCBzZXR0ZXJzXG4gICAgdmFyICRvbmVPZkZpZWxkcztcblxuICAgIC8qKlxuICAgICAqIFR5cGVQcm90byB2YWx1ZS5cbiAgICAgKiBAbWVtYmVyIHtcInRlbnNvclR5cGVcInxcInNlcXVlbmNlVHlwZVwifFwibWFwVHlwZVwifFwib3B0aW9uYWxUeXBlXCJ8XCJzcGFyc2VUZW5zb3JUeXBlXCJ8dW5kZWZpbmVkfSB2YWx1ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUeXBlUHJvdG8ucHJvdG90eXBlLCAndmFsdWUnLCB7XG4gICAgICBnZXQ6ICR1dGlsLm9uZU9mR2V0dGVyKFxuICAgICAgICAoJG9uZU9mRmllbGRzID0gWyd0ZW5zb3JUeXBlJywgJ3NlcXVlbmNlVHlwZScsICdtYXBUeXBlJywgJ29wdGlvbmFsVHlwZScsICdzcGFyc2VUZW5zb3JUeXBlJ10pLFxuICAgICAgKSxcbiAgICAgIHNldDogJHV0aWwub25lT2ZTZXR0ZXIoJG9uZU9mRmllbGRzKSxcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgVHlwZVByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVHlwZVByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvfSBUeXBlUHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgVHlwZVByb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVHlwZVByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUeXBlUHJvdG99IG1lc3NhZ2UgVHlwZVByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS50ZW5zb3JUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3RlbnNvclR5cGUnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yLmVuY29kZShcbiAgICAgICAgICBtZXNzYWdlLnRlbnNvclR5cGUsXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuZm9yaygpLFxuICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2Uuc2VxdWVuY2VUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3NlcXVlbmNlVHlwZScpKVxuICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5TZXF1ZW5jZS5lbmNvZGUoXG4gICAgICAgICAgbWVzc2FnZS5zZXF1ZW5jZVR5cGUsXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA0LCB3aXJlVHlwZSAyID0qLyAzNCkuZm9yaygpLFxuICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UubWFwVHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdtYXBUeXBlJykpXG4gICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLk1hcC5lbmNvZGUobWVzc2FnZS5tYXBUeXBlLCB3cml0ZXIudWludDMyKC8qIGlkIDUsIHdpcmVUeXBlIDIgPSovIDQyKS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZGVub3RhdGlvbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkZW5vdGF0aW9uJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNiwgd2lyZVR5cGUgMiA9Ki8gNTApLnN0cmluZyhtZXNzYWdlLmRlbm90YXRpb24pO1xuICAgICAgaWYgKG1lc3NhZ2Uuc3BhcnNlVGVuc29yVHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdzcGFyc2VUZW5zb3JUeXBlJykpXG4gICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvci5lbmNvZGUoXG4gICAgICAgICAgbWVzc2FnZS5zcGFyc2VUZW5zb3JUeXBlLFxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgOCwgd2lyZVR5cGUgMiA9Ki8gNjYpLmZvcmsoKSxcbiAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLm9wdGlvbmFsVHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdvcHRpb25hbFR5cGUnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UeXBlUHJvdG8uT3B0aW9uYWwuZW5jb2RlKFxuICAgICAgICAgIG1lc3NhZ2Uub3B0aW9uYWxUeXBlLFxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgOSwgd2lyZVR5cGUgMiA9Ki8gNzQpLmZvcmsoKSxcbiAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUeXBlUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVR5cGVQcm90b30gbWVzc2FnZSBUeXBlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFR5cGVQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFR5cGVQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG99IFR5cGVQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVHlwZVByb3RvLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UudGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlRlbnNvci5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNDoge1xuICAgICAgICAgICAgbWVzc2FnZS5zZXF1ZW5jZVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5TZXF1ZW5jZS5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNToge1xuICAgICAgICAgICAgbWVzc2FnZS5tYXBUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uTWFwLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA5OiB7XG4gICAgICAgICAgICBtZXNzYWdlLm9wdGlvbmFsVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLk9wdGlvbmFsLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA4OiB7XG4gICAgICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvclR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3IuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDY6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZGVub3RhdGlvbiA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVHlwZVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG99IFR5cGVQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVHlwZVByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVmVyaWZpZXMgYSBUeXBlUHJvdG8gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICovXG4gICAgVHlwZVByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIHZhciBwcm9wZXJ0aWVzID0ge307XG4gICAgICBpZiAobWVzc2FnZS50ZW5zb3JUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndGVuc29yVHlwZScpKSB7XG4gICAgICAgIHByb3BlcnRpZXMudmFsdWUgPSAxO1xuICAgICAgICB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yLnZlcmlmeShtZXNzYWdlLnRlbnNvclR5cGUpO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICd0ZW5zb3JUeXBlLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uuc2VxdWVuY2VUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc2VxdWVuY2VUeXBlJykpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMudmFsdWUgPT09IDEpIHJldHVybiAndmFsdWU6IG11bHRpcGxlIHZhbHVlcyc7XG4gICAgICAgIHByb3BlcnRpZXMudmFsdWUgPSAxO1xuICAgICAgICB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uU2VxdWVuY2UudmVyaWZ5KG1lc3NhZ2Uuc2VxdWVuY2VUeXBlKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnc2VxdWVuY2VUeXBlLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubWFwVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ21hcFR5cGUnKSkge1xuICAgICAgICBpZiAocHJvcGVydGllcy52YWx1ZSA9PT0gMSkgcmV0dXJuICd2YWx1ZTogbXVsdGlwbGUgdmFsdWVzJztcbiAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by5NYXAudmVyaWZ5KG1lc3NhZ2UubWFwVHlwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ21hcFR5cGUuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5vcHRpb25hbFR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdvcHRpb25hbFR5cGUnKSkge1xuICAgICAgICBpZiAocHJvcGVydGllcy52YWx1ZSA9PT0gMSkgcmV0dXJuICd2YWx1ZTogbXVsdGlwbGUgdmFsdWVzJztcbiAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by5PcHRpb25hbC52ZXJpZnkobWVzc2FnZS5vcHRpb25hbFR5cGUpO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdvcHRpb25hbFR5cGUuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VUZW5zb3JUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc3BhcnNlVGVuc29yVHlwZScpKSB7XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLnZhbHVlID09PSAxKSByZXR1cm4gJ3ZhbHVlOiBtdWx0aXBsZSB2YWx1ZXMnO1xuICAgICAgICBwcm9wZXJ0aWVzLnZhbHVlID0gMTtcbiAgICAgICAge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvci52ZXJpZnkobWVzc2FnZS5zcGFyc2VUZW5zb3JUeXBlKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnc3BhcnNlVGVuc29yVHlwZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRlbm90YXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkZW5vdGF0aW9uJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kZW5vdGF0aW9uKSkgcmV0dXJuICdkZW5vdGF0aW9uOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBUeXBlUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG99IFR5cGVQcm90b1xuICAgICAqL1xuICAgIFR5cGVQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlR5cGVQcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvKCk7XG4gICAgICBpZiAob2JqZWN0LnRlbnNvclR5cGUgIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC50ZW5zb3JUeXBlICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8udGVuc29yVHlwZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UudGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlRlbnNvci5mcm9tT2JqZWN0KG9iamVjdC50ZW5zb3JUeXBlKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3Quc2VxdWVuY2VUeXBlICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc2VxdWVuY2VUeXBlICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8uc2VxdWVuY2VUeXBlOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5zZXF1ZW5jZVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5TZXF1ZW5jZS5mcm9tT2JqZWN0KG9iamVjdC5zZXF1ZW5jZVR5cGUpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5tYXBUeXBlICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QubWFwVHlwZSAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguVHlwZVByb3RvLm1hcFR5cGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLm1hcFR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5NYXAuZnJvbU9iamVjdChvYmplY3QubWFwVHlwZSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0Lm9wdGlvbmFsVHlwZSAhPSBudWxsKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm9wdGlvbmFsVHlwZSAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguVHlwZVByb3RvLm9wdGlvbmFsVHlwZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2Uub3B0aW9uYWxUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uT3B0aW9uYWwuZnJvbU9iamVjdChvYmplY3Qub3B0aW9uYWxUeXBlKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3Quc3BhcnNlVGVuc29yVHlwZSAhPSBudWxsKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnNwYXJzZVRlbnNvclR5cGUgIT09ICdvYmplY3QnKVxuICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguVHlwZVByb3RvLnNwYXJzZVRlbnNvclR5cGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvclR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3IuZnJvbU9iamVjdChvYmplY3Quc3BhcnNlVGVuc29yVHlwZSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmRlbm90YXRpb24gIT0gbnVsbCkgbWVzc2FnZS5kZW5vdGF0aW9uID0gU3RyaW5nKG9iamVjdC5kZW5vdGF0aW9uKTtcbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBUeXBlUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvfSBtZXNzYWdlIFR5cGVQcm90b1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgVHlwZVByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykgb2JqZWN0LmRlbm90YXRpb24gPSAnJztcbiAgICAgIGlmIChtZXNzYWdlLnRlbnNvclR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0ZW5zb3JUeXBlJykpIHtcbiAgICAgICAgb2JqZWN0LnRlbnNvclR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IudG9PYmplY3QobWVzc2FnZS50ZW5zb3JUeXBlLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKG9wdGlvbnMub25lb2ZzKSBvYmplY3QudmFsdWUgPSAndGVuc29yVHlwZSc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zZXF1ZW5jZVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzZXF1ZW5jZVR5cGUnKSkge1xuICAgICAgICBvYmplY3Quc2VxdWVuY2VUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uU2VxdWVuY2UudG9PYmplY3QobWVzc2FnZS5zZXF1ZW5jZVR5cGUsIG9wdGlvbnMpO1xuICAgICAgICBpZiAob3B0aW9ucy5vbmVvZnMpIG9iamVjdC52YWx1ZSA9ICdzZXF1ZW5jZVR5cGUnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubWFwVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ21hcFR5cGUnKSkge1xuICAgICAgICBvYmplY3QubWFwVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLk1hcC50b09iamVjdChtZXNzYWdlLm1hcFR5cGUsIG9wdGlvbnMpO1xuICAgICAgICBpZiAob3B0aW9ucy5vbmVvZnMpIG9iamVjdC52YWx1ZSA9ICdtYXBUeXBlJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRlbm90YXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkZW5vdGF0aW9uJykpIG9iamVjdC5kZW5vdGF0aW9uID0gbWVzc2FnZS5kZW5vdGF0aW9uO1xuICAgICAgaWYgKG1lc3NhZ2Uuc3BhcnNlVGVuc29yVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NwYXJzZVRlbnNvclR5cGUnKSkge1xuICAgICAgICBvYmplY3Quc3BhcnNlVGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvci50b09iamVjdChtZXNzYWdlLnNwYXJzZVRlbnNvclR5cGUsIG9wdGlvbnMpO1xuICAgICAgICBpZiAob3B0aW9ucy5vbmVvZnMpIG9iamVjdC52YWx1ZSA9ICdzcGFyc2VUZW5zb3JUeXBlJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm9wdGlvbmFsVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ29wdGlvbmFsVHlwZScpKSB7XG4gICAgICAgIG9iamVjdC5vcHRpb25hbFR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5PcHRpb25hbC50b09iamVjdChtZXNzYWdlLm9wdGlvbmFsVHlwZSwgb3B0aW9ucyk7XG4gICAgICAgIGlmIChvcHRpb25zLm9uZW9mcykgb2JqZWN0LnZhbHVlID0gJ29wdGlvbmFsVHlwZSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIFR5cGVQcm90byB0byBKU09OLlxuICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgVHlwZVByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgVHlwZVByb3RvXG4gICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguVHlwZVByb3RvJztcbiAgICB9O1xuXG4gICAgVHlwZVByb3RvLlRlbnNvciA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAvKipcbiAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBUZW5zb3IuXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAqIEBpbnRlcmZhY2UgSVRlbnNvclxuICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8bnVsbH0gW2VsZW1UeXBlXSBUZW5zb3IgZWxlbVR5cGVcbiAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JVGVuc29yU2hhcGVQcm90b3xudWxsfSBbc2hhcGVdIFRlbnNvciBzaGFwZVxuICAgICAgICovXG5cbiAgICAgIC8qKlxuICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBUZW5zb3IuXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFRlbnNvci5cbiAgICAgICAqIEBpbXBsZW1lbnRzIElUZW5zb3JcbiAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JVGVuc29yPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKi9cbiAgICAgIGZ1bmN0aW9uIFRlbnNvcihwcm9wZXJ0aWVzKSB7XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICB9XG5cbiAgICAgIC8qKlxuICAgICAgICogVGVuc29yIGVsZW1UeXBlLlxuICAgICAgICogQG1lbWJlciB7bnVtYmVyfSBlbGVtVHlwZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIFRlbnNvci5wcm90b3R5cGUuZWxlbVR5cGUgPSAwO1xuXG4gICAgICAvKipcbiAgICAgICAqIFRlbnNvciBzaGFwZS5cbiAgICAgICAqIEBtZW1iZXIge29ubnguSVRlbnNvclNoYXBlUHJvdG98bnVsbHx1bmRlZmluZWR9IHNoYXBlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgVGVuc29yLnByb3RvdHlwZS5zaGFwZSA9IG51bGw7XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIG5ldyBUZW5zb3IgaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JVGVuc29yPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uVGVuc29yfSBUZW5zb3IgaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgVGVuc29yLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGVuc29yKHByb3BlcnRpZXMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVGVuc29yIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLlRlbnNvci52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVRlbnNvcn0gbWVzc2FnZSBUZW5zb3IgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgVGVuc29yLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2VsZW1UeXBlJykpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAwID0qLyA4KS5pbnQzMihtZXNzYWdlLmVsZW1UeXBlKTtcbiAgICAgICAgaWYgKG1lc3NhZ2Uuc2hhcGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnc2hhcGUnKSlcbiAgICAgICAgICAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uZW5jb2RlKG1lc3NhZ2Uuc2hhcGUsIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3IgbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8uVGVuc29yLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JVGVuc29yfSBtZXNzYWdlIFRlbnNvciBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICovXG4gICAgICBUZW5zb3IuZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRGVjb2RlcyBhIFRlbnNvciBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlRlbnNvcn0gVGVuc29yXG4gICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgKi9cbiAgICAgIFRlbnNvci5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yKCk7XG4gICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UuZWxlbVR5cGUgPSByZWFkZXIuaW50MzIoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgICAgbWVzc2FnZS5zaGFwZSA9ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGEgVGVuc29yIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5UZW5zb3J9IFRlbnNvclxuICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICovXG4gICAgICBUZW5zb3IuZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogVmVyaWZpZXMgYSBUZW5zb3IgbWVzc2FnZS5cbiAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAqL1xuICAgICAgVGVuc29yLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2VsZW1UeXBlJykpXG4gICAgICAgICAgaWYgKCEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5lbGVtVHlwZSkpIHJldHVybiAnZWxlbVR5cGU6IGludGVnZXIgZXhwZWN0ZWQnO1xuICAgICAgICBpZiAobWVzc2FnZS5zaGFwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NoYXBlJykpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8udmVyaWZ5KG1lc3NhZ2Uuc2hhcGUpO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdzaGFwZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBUZW5zb3IgbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5UZW5zb3J9IFRlbnNvclxuICAgICAgICovXG4gICAgICBUZW5zb3IuZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IpIHJldHVybiBvYmplY3Q7XG4gICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLlRlbnNvcigpO1xuICAgICAgICBpZiAob2JqZWN0LmVsZW1UeXBlICE9IG51bGwpIG1lc3NhZ2UuZWxlbVR5cGUgPSBvYmplY3QuZWxlbVR5cGUgfCAwO1xuICAgICAgICBpZiAob2JqZWN0LnNoYXBlICE9IG51bGwpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zaGFwZSAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguVHlwZVByb3RvLlRlbnNvci5zaGFwZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5zaGFwZSA9ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC5zaGFwZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFRlbnNvciBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uVGVuc29yfSBtZXNzYWdlIFRlbnNvclxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICovXG4gICAgICBUZW5zb3IudG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgb2JqZWN0LmVsZW1UeXBlID0gMDtcbiAgICAgICAgICBvYmplY3Quc2hhcGUgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZWxlbVR5cGUnKSkgb2JqZWN0LmVsZW1UeXBlID0gbWVzc2FnZS5lbGVtVHlwZTtcbiAgICAgICAgaWYgKG1lc3NhZ2Uuc2hhcGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzaGFwZScpKVxuICAgICAgICAgIG9iamVjdC5zaGFwZSA9ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by50b09iamVjdChtZXNzYWdlLnNoYXBlLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ29udmVydHMgdGhpcyBUZW5zb3IgdG8gSlNPTi5cbiAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICovXG4gICAgICBUZW5zb3IucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFRlbnNvclxuICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgICAqL1xuICAgICAgVGVuc29yLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguVHlwZVByb3RvLlRlbnNvcic7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gVGVuc29yO1xuICAgIH0pKCk7XG5cbiAgICBUeXBlUHJvdG8uU2VxdWVuY2UgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgLyoqXG4gICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgU2VxdWVuY2UuXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAqIEBpbnRlcmZhY2UgSVNlcXVlbmNlXG4gICAgICAgKiBAcHJvcGVydHkge29ubnguSVR5cGVQcm90b3xudWxsfSBbZWxlbVR5cGVdIFNlcXVlbmNlIGVsZW1UeXBlXG4gICAgICAgKi9cblxuICAgICAgLyoqXG4gICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFNlcXVlbmNlLlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBTZXF1ZW5jZS5cbiAgICAgICAqIEBpbXBsZW1lbnRzIElTZXF1ZW5jZVxuICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklTZXF1ZW5jZT19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICovXG4gICAgICBmdW5jdGlvbiBTZXF1ZW5jZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICB9XG5cbiAgICAgIC8qKlxuICAgICAgICogU2VxdWVuY2UgZWxlbVR5cGUuXG4gICAgICAgKiBAbWVtYmVyIHtvbm54LklUeXBlUHJvdG98bnVsbHx1bmRlZmluZWR9IGVsZW1UeXBlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBTZXF1ZW5jZS5wcm90b3R5cGUuZWxlbVR5cGUgPSBudWxsO1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBuZXcgU2VxdWVuY2UgaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklTZXF1ZW5jZT19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlNlcXVlbmNlfSBTZXF1ZW5jZSBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBTZXF1ZW5jZS5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICByZXR1cm4gbmV3IFNlcXVlbmNlKHByb3BlcnRpZXMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU2VxdWVuY2UgbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8uU2VxdWVuY2UudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNlcXVlbmNlfSBtZXNzYWdlIFNlcXVlbmNlIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIFNlcXVlbmNlLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2VsZW1UeXBlJykpXG4gICAgICAgICAgJHJvb3Qub25ueC5UeXBlUHJvdG8uZW5jb2RlKG1lc3NhZ2UuZWxlbVR5cGUsIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8gMTApLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTZXF1ZW5jZSBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5TZXF1ZW5jZS52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JU2VxdWVuY2V9IG1lc3NhZ2UgU2VxdWVuY2UgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgU2VxdWVuY2UuZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRGVjb2RlcyBhIFNlcXVlbmNlIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5TZXF1ZW5jZX0gU2VxdWVuY2VcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgU2VxdWVuY2UuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlKCk7XG4gICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UuZWxlbVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGEgU2VxdWVuY2UgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uU2VxdWVuY2V9IFNlcXVlbmNlXG4gICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgKi9cbiAgICAgIFNlcXVlbmNlLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIFZlcmlmaWVzIGEgU2VxdWVuY2UgbWVzc2FnZS5cbiAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICovXG4gICAgICBTZXF1ZW5jZS52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdlbGVtVHlwZScpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UeXBlUHJvdG8udmVyaWZ5KG1lc3NhZ2UuZWxlbVR5cGUpO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdlbGVtVHlwZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBTZXF1ZW5jZSBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uU2VxdWVuY2V9IFNlcXVlbmNlXG4gICAgICAgKi9cbiAgICAgIFNlcXVlbmNlLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UeXBlUHJvdG8uU2VxdWVuY2UpIHJldHVybiBvYmplY3Q7XG4gICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlKCk7XG4gICAgICAgIGlmIChvYmplY3QuZWxlbVR5cGUgIT0gbnVsbCkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmVsZW1UeXBlICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguVHlwZVByb3RvLlNlcXVlbmNlLmVsZW1UeXBlOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLmVsZW1UeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZnJvbU9iamVjdChvYmplY3QuZWxlbVR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBTZXF1ZW5jZSBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5TZXF1ZW5jZX0gbWVzc2FnZSBTZXF1ZW5jZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICovXG4gICAgICBTZXF1ZW5jZS50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIG9iamVjdC5lbGVtVHlwZSA9IG51bGw7XG4gICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZWxlbVR5cGUnKSlcbiAgICAgICAgICBvYmplY3QuZWxlbVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by50b09iamVjdChtZXNzYWdlLmVsZW1UeXBlLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ29udmVydHMgdGhpcyBTZXF1ZW5jZSB0byBKU09OLlxuICAgICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgU2VxdWVuY2UucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFNlcXVlbmNlXG4gICAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgKi9cbiAgICAgIFNlcXVlbmNlLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguVHlwZVByb3RvLlNlcXVlbmNlJztcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBTZXF1ZW5jZTtcbiAgICB9KSgpO1xuXG4gICAgVHlwZVByb3RvLk1hcCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAvKipcbiAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBNYXAuXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAqIEBpbnRlcmZhY2UgSU1hcFxuICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8bnVsbH0gW2tleVR5cGVdIE1hcCBrZXlUeXBlXG4gICAgICAgKiBAcHJvcGVydHkge29ubnguSVR5cGVQcm90b3xudWxsfSBbdmFsdWVUeXBlXSBNYXAgdmFsdWVUeXBlXG4gICAgICAgKi9cblxuICAgICAgLyoqXG4gICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IE1hcC5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgTWFwLlxuICAgICAgICogQGltcGxlbWVudHMgSU1hcFxuICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklNYXA9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqL1xuICAgICAgZnVuY3Rpb24gTWFwKHByb3BlcnRpZXMpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBNYXAga2V5VHlwZS5cbiAgICAgICAqIEBtZW1iZXIge251bWJlcn0ga2V5VHlwZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIE1hcC5wcm90b3R5cGUua2V5VHlwZSA9IDA7XG5cbiAgICAgIC8qKlxuICAgICAgICogTWFwIHZhbHVlVHlwZS5cbiAgICAgICAqIEBtZW1iZXIge29ubnguSVR5cGVQcm90b3xudWxsfHVuZGVmaW5lZH0gdmFsdWVUeXBlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgTWFwLnByb3RvdHlwZS52YWx1ZVR5cGUgPSBudWxsO1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBuZXcgTWFwIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSU1hcD19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLk1hcH0gTWFwIGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIE1hcC5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICByZXR1cm4gbmV3IE1hcChwcm9wZXJ0aWVzKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE1hcCBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5NYXAudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklNYXB9IG1lc3NhZ2UgTWFwIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIE1hcC5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICBpZiAobWVzc2FnZS5rZXlUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2tleVR5cGUnKSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDAgPSovIDgpLmludDMyKG1lc3NhZ2Uua2V5VHlwZSk7XG4gICAgICAgIGlmIChtZXNzYWdlLnZhbHVlVHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICd2YWx1ZVR5cGUnKSlcbiAgICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5lbmNvZGUobWVzc2FnZS52YWx1ZVR5cGUsIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBNYXAgbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8uTWFwLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JTWFwfSBtZXNzYWdlIE1hcCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICovXG4gICAgICBNYXAuZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRGVjb2RlcyBhIE1hcCBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLk1hcH0gTWFwXG4gICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgKi9cbiAgICAgIE1hcC5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uTWFwKCk7XG4gICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2Uua2V5VHlwZSA9IHJlYWRlci5pbnQzMigpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgICBtZXNzYWdlLnZhbHVlVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBNYXAgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLk1hcH0gTWFwXG4gICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgKi9cbiAgICAgIE1hcC5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBWZXJpZmllcyBhIE1hcCBtZXNzYWdlLlxuICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICovXG4gICAgICBNYXAudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICAgIGlmIChtZXNzYWdlLmtleVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdrZXlUeXBlJykpXG4gICAgICAgICAgaWYgKCEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5rZXlUeXBlKSkgcmV0dXJuICdrZXlUeXBlOiBpbnRlZ2VyIGV4cGVjdGVkJztcbiAgICAgICAgaWYgKG1lc3NhZ2UudmFsdWVUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmFsdWVUeXBlJykpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by52ZXJpZnkobWVzc2FnZS52YWx1ZVR5cGUpO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICd2YWx1ZVR5cGUuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgTWFwIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uTWFwfSBNYXBcbiAgICAgICAqL1xuICAgICAgTWFwLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UeXBlUHJvdG8uTWFwKSByZXR1cm4gb2JqZWN0O1xuICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90by5NYXAoKTtcbiAgICAgICAgaWYgKG9iamVjdC5rZXlUeXBlICE9IG51bGwpIG1lc3NhZ2Uua2V5VHlwZSA9IG9iamVjdC5rZXlUeXBlIHwgMDtcbiAgICAgICAgaWYgKG9iamVjdC52YWx1ZVR5cGUgIT0gbnVsbCkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnZhbHVlVHlwZSAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguVHlwZVByb3RvLk1hcC52YWx1ZVR5cGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UudmFsdWVUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZnJvbU9iamVjdChvYmplY3QudmFsdWVUeXBlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgTWFwIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5NYXB9IG1lc3NhZ2UgTWFwXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIE1hcC50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICBvYmplY3Qua2V5VHlwZSA9IDA7XG4gICAgICAgICAgb2JqZWN0LnZhbHVlVHlwZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1lc3NhZ2Uua2V5VHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2tleVR5cGUnKSkgb2JqZWN0LmtleVR5cGUgPSBtZXNzYWdlLmtleVR5cGU7XG4gICAgICAgIGlmIChtZXNzYWdlLnZhbHVlVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3ZhbHVlVHlwZScpKVxuICAgICAgICAgIG9iamVjdC52YWx1ZVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by50b09iamVjdChtZXNzYWdlLnZhbHVlVHlwZSwgb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnZlcnRzIHRoaXMgTWFwIHRvIEpTT04uXG4gICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgTWFwLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBNYXBcbiAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgKi9cbiAgICAgIE1hcC5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlR5cGVQcm90by5NYXAnO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIE1hcDtcbiAgICB9KSgpO1xuXG4gICAgVHlwZVByb3RvLk9wdGlvbmFsID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKlxuICAgICAgICogUHJvcGVydGllcyBvZiBhbiBPcHRpb25hbC5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGludGVyZmFjZSBJT3B0aW9uYWxcbiAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JVHlwZVByb3RvfG51bGx9IFtlbGVtVHlwZV0gT3B0aW9uYWwgZWxlbVR5cGVcbiAgICAgICAqL1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgT3B0aW9uYWwuXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhbiBPcHRpb25hbC5cbiAgICAgICAqIEBpbXBsZW1lbnRzIElPcHRpb25hbFxuICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklPcHRpb25hbD19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICovXG4gICAgICBmdW5jdGlvbiBPcHRpb25hbChwcm9wZXJ0aWVzKSB7XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICB9XG5cbiAgICAgIC8qKlxuICAgICAgICogT3B0aW9uYWwgZWxlbVR5cGUuXG4gICAgICAgKiBAbWVtYmVyIHtvbm54LklUeXBlUHJvdG98bnVsbHx1bmRlZmluZWR9IGVsZW1UeXBlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uT3B0aW9uYWxcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBPcHRpb25hbC5wcm90b3R5cGUuZWxlbVR5cGUgPSBudWxsO1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBuZXcgT3B0aW9uYWwgaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklPcHRpb25hbD19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLk9wdGlvbmFsfSBPcHRpb25hbCBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBPcHRpb25hbC5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICByZXR1cm4gbmV3IE9wdGlvbmFsKHByb3BlcnRpZXMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgT3B0aW9uYWwgbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8uT3B0aW9uYWwudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uT3B0aW9uYWxcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSU9wdGlvbmFsfSBtZXNzYWdlIE9wdGlvbmFsIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIE9wdGlvbmFsLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2VsZW1UeXBlJykpXG4gICAgICAgICAgJHJvb3Qub25ueC5UeXBlUHJvdG8uZW5jb2RlKG1lc3NhZ2UuZWxlbVR5cGUsIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8gMTApLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBPcHRpb25hbCBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5PcHRpb25hbC52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JT3B0aW9uYWx9IG1lc3NhZ2UgT3B0aW9uYWwgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgT3B0aW9uYWwuZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRGVjb2RlcyBhbiBPcHRpb25hbCBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uT3B0aW9uYWx9IE9wdGlvbmFsXG4gICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgKi9cbiAgICAgIE9wdGlvbmFsLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90by5PcHRpb25hbCgpO1xuICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgICBtZXNzYWdlLmVsZW1UeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRGVjb2RlcyBhbiBPcHRpb25hbCBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5PcHRpb25hbH0gT3B0aW9uYWxcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgT3B0aW9uYWwuZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogVmVyaWZpZXMgYW4gT3B0aW9uYWwgbWVzc2FnZS5cbiAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICovXG4gICAgICBPcHRpb25hbC52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdlbGVtVHlwZScpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UeXBlUHJvdG8udmVyaWZ5KG1lc3NhZ2UuZWxlbVR5cGUpO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdlbGVtVHlwZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYW4gT3B0aW9uYWwgbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLk9wdGlvbmFsfSBPcHRpb25hbFxuICAgICAgICovXG4gICAgICBPcHRpb25hbC5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVHlwZVByb3RvLk9wdGlvbmFsKSByZXR1cm4gb2JqZWN0O1xuICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90by5PcHRpb25hbCgpO1xuICAgICAgICBpZiAob2JqZWN0LmVsZW1UeXBlICE9IG51bGwpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5lbGVtVHlwZSAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlR5cGVQcm90by5PcHRpb25hbC5lbGVtVHlwZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5lbGVtVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LmVsZW1UeXBlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGFuIE9wdGlvbmFsIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLk9wdGlvbmFsfSBtZXNzYWdlIE9wdGlvbmFsXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIE9wdGlvbmFsLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykgb2JqZWN0LmVsZW1UeXBlID0gbnVsbDtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdlbGVtVHlwZScpKVxuICAgICAgICAgIG9iamVjdC5lbGVtVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZWxlbVR5cGUsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDb252ZXJ0cyB0aGlzIE9wdGlvbmFsIHRvIEpTT04uXG4gICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uT3B0aW9uYWxcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICovXG4gICAgICBPcHRpb25hbC5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgT3B0aW9uYWxcbiAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uT3B0aW9uYWxcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgICAqL1xuICAgICAgT3B0aW9uYWwuZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UeXBlUHJvdG8uT3B0aW9uYWwnO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIE9wdGlvbmFsO1xuICAgIH0pKCk7XG5cbiAgICBUeXBlUHJvdG8uU3BhcnNlVGVuc29yID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKlxuICAgICAgICogUHJvcGVydGllcyBvZiBhIFNwYXJzZVRlbnNvci5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGludGVyZmFjZSBJU3BhcnNlVGVuc29yXG4gICAgICAgKiBAcHJvcGVydHkge251bWJlcnxudWxsfSBbZWxlbVR5cGVdIFNwYXJzZVRlbnNvciBlbGVtVHlwZVxuICAgICAgICogQHByb3BlcnR5IHtvbm54LklUZW5zb3JTaGFwZVByb3RvfG51bGx9IFtzaGFwZV0gU3BhcnNlVGVuc29yIHNoYXBlXG4gICAgICAgKi9cblxuICAgICAgLyoqXG4gICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFNwYXJzZVRlbnNvci5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgU3BhcnNlVGVuc29yLlxuICAgICAgICogQGltcGxlbWVudHMgSVNwYXJzZVRlbnNvclxuICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklTcGFyc2VUZW5zb3I9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqL1xuICAgICAgZnVuY3Rpb24gU3BhcnNlVGVuc29yKHByb3BlcnRpZXMpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBTcGFyc2VUZW5zb3IgZWxlbVR5cGUuXG4gICAgICAgKiBAbWVtYmVyIHtudW1iZXJ9IGVsZW1UeXBlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgU3BhcnNlVGVuc29yLnByb3RvdHlwZS5lbGVtVHlwZSA9IDA7XG5cbiAgICAgIC8qKlxuICAgICAgICogU3BhcnNlVGVuc29yIHNoYXBlLlxuICAgICAgICogQG1lbWJlciB7b25ueC5JVGVuc29yU2hhcGVQcm90b3xudWxsfHVuZGVmaW5lZH0gc2hhcGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBTcGFyc2VUZW5zb3IucHJvdG90eXBlLnNoYXBlID0gbnVsbDtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgbmV3IFNwYXJzZVRlbnNvciBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklTcGFyc2VUZW5zb3I9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3J9IFNwYXJzZVRlbnNvciBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBTcGFyc2VUZW5zb3IuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTcGFyc2VUZW5zb3IocHJvcGVydGllcyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTcGFyc2VUZW5zb3IgbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JU3BhcnNlVGVuc29yfSBtZXNzYWdlIFNwYXJzZVRlbnNvciBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICovXG4gICAgICBTcGFyc2VUZW5zb3IuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZWxlbVR5cGUnKSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDAgPSovIDgpLmludDMyKG1lc3NhZ2UuZWxlbVR5cGUpO1xuICAgICAgICBpZiAobWVzc2FnZS5zaGFwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdzaGFwZScpKVxuICAgICAgICAgICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5lbmNvZGUobWVzc2FnZS5zaGFwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLyAxOCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFNwYXJzZVRlbnNvciBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3IudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklTcGFyc2VUZW5zb3J9IG1lc3NhZ2UgU3BhcnNlVGVuc29yIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGEgU3BhcnNlVGVuc29yIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yfSBTcGFyc2VUZW5zb3JcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgU3BhcnNlVGVuc29yLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3IoKTtcbiAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgbWVzc2FnZS5lbGVtVHlwZSA9IHJlYWRlci5pbnQzMigpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgICBtZXNzYWdlLnNoYXBlID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBTcGFyc2VUZW5zb3IgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcn0gU3BhcnNlVGVuc29yXG4gICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBWZXJpZmllcyBhIFNwYXJzZVRlbnNvciBtZXNzYWdlLlxuICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICovXG4gICAgICBTcGFyc2VUZW5zb3IudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZWxlbVR5cGUnKSlcbiAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmVsZW1UeXBlKSkgcmV0dXJuICdlbGVtVHlwZTogaW50ZWdlciBleHBlY3RlZCc7XG4gICAgICAgIGlmIChtZXNzYWdlLnNoYXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc2hhcGUnKSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by52ZXJpZnkobWVzc2FnZS5zaGFwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3NoYXBlLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIFNwYXJzZVRlbnNvciBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcn0gU3BhcnNlVGVuc29yXG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcikgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yKCk7XG4gICAgICAgIGlmIChvYmplY3QuZWxlbVR5cGUgIT0gbnVsbCkgbWVzc2FnZS5lbGVtVHlwZSA9IG9iamVjdC5lbGVtVHlwZSB8IDA7XG4gICAgICAgIGlmIChvYmplY3Quc2hhcGUgIT0gbnVsbCkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnNoYXBlICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yLnNoYXBlOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLnNoYXBlID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LnNoYXBlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgU3BhcnNlVGVuc29yIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3J9IG1lc3NhZ2UgU3BhcnNlVGVuc29yXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICBvYmplY3QuZWxlbVR5cGUgPSAwO1xuICAgICAgICAgIG9iamVjdC5zaGFwZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdlbGVtVHlwZScpKSBvYmplY3QuZWxlbVR5cGUgPSBtZXNzYWdlLmVsZW1UeXBlO1xuICAgICAgICBpZiAobWVzc2FnZS5zaGFwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NoYXBlJykpXG4gICAgICAgICAgb2JqZWN0LnNoYXBlID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uuc2hhcGUsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDb252ZXJ0cyB0aGlzIFNwYXJzZVRlbnNvciB0byBKU09OLlxuICAgICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvclxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgU3BhcnNlVGVuc29yXG4gICAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICovXG4gICAgICBTcGFyc2VUZW5zb3IuZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yJztcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBTcGFyc2VUZW5zb3I7XG4gICAgfSkoKTtcblxuICAgIHJldHVybiBUeXBlUHJvdG87XG4gIH0pKCk7XG5cbiAgb25ueC5PcGVyYXRvclNldElkUHJvdG8gPSAoZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgb2YgYW4gT3BlcmF0b3JTZXRJZFByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGludGVyZmFjZSBJT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvbWFpbl0gT3BlcmF0b3JTZXRJZFByb3RvIGRvbWFpblxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfExvbmd8bnVsbH0gW3ZlcnNpb25dIE9wZXJhdG9yU2V0SWRQcm90byB2ZXJzaW9uXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IE9wZXJhdG9yU2V0SWRQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhbiBPcGVyYXRvclNldElkUHJvdG8uXG4gICAgICogQGltcGxlbWVudHMgSU9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JT3BlcmF0b3JTZXRJZFByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICovXG4gICAgZnVuY3Rpb24gT3BlcmF0b3JTZXRJZFByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPcGVyYXRvclNldElkUHJvdG8gZG9tYWluLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9tYWluXG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgT3BlcmF0b3JTZXRJZFByb3RvLnByb3RvdHlwZS5kb21haW4gPSAnJztcblxuICAgIC8qKlxuICAgICAqIE9wZXJhdG9yU2V0SWRQcm90byB2ZXJzaW9uLlxuICAgICAqIEBtZW1iZXIge251bWJlcnxMb25nfSB2ZXJzaW9uXG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgT3BlcmF0b3JTZXRJZFByb3RvLnByb3RvdHlwZS52ZXJzaW9uID0gJHV0aWwuTG9uZyA/ICR1dGlsLkxvbmcuZnJvbUJpdHMoMCwgMCwgZmFsc2UpIDogMDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgT3BlcmF0b3JTZXRJZFByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JT3BlcmF0b3JTZXRJZFByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguT3BlcmF0b3JTZXRJZFByb3RvfSBPcGVyYXRvclNldElkUHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBPcGVyYXRvclNldElkUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgT3BlcmF0b3JTZXRJZFByb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgT3BlcmF0b3JTZXRJZFByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklPcGVyYXRvclNldElkUHJvdG99IG1lc3NhZ2UgT3BlcmF0b3JTZXRJZFByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBPcGVyYXRvclNldElkUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZG9tYWluJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8gMTApLnN0cmluZyhtZXNzYWdlLmRvbWFpbik7XG4gICAgICBpZiAobWVzc2FnZS52ZXJzaW9uICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3ZlcnNpb24nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAwID0qLyAxNikuaW50NjQobWVzc2FnZS52ZXJzaW9uKTtcbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5PcGVyYXRvclNldElkUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSU9wZXJhdG9yU2V0SWRQcm90b30gbWVzc2FnZSBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhbiBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICogQHJldHVybnMge29ubnguT3BlcmF0b3JTZXRJZFByb3RvfSBPcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5PcGVyYXRvclNldElkUHJvdG8oKTtcbiAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmRvbWFpbiA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UudmVyc2lvbiA9IHJlYWRlci5pbnQ2NCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYW4gT3BlcmF0b3JTZXRJZFByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcmV0dXJucyB7b25ueC5PcGVyYXRvclNldElkUHJvdG99IE9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgT3BlcmF0b3JTZXRJZFByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVmVyaWZpZXMgYW4gT3BlcmF0b3JTZXRJZFByb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb21haW4nKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvbWFpbikpIHJldHVybiAnZG9tYWluOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UudmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3ZlcnNpb24nKSlcbiAgICAgICAgaWYgKFxuICAgICAgICAgICEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS52ZXJzaW9uKSAmJlxuICAgICAgICAgICEobWVzc2FnZS52ZXJzaW9uICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLnZlcnNpb24ubG93KSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS52ZXJzaW9uLmhpZ2gpKVxuICAgICAgICApXG4gICAgICAgICAgcmV0dXJuICd2ZXJzaW9uOiBpbnRlZ2VyfExvbmcgZXhwZWN0ZWQnO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gT3BlcmF0b3JTZXRJZFByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICogQHJldHVybnMge29ubnguT3BlcmF0b3JTZXRJZFByb3RvfSBPcGVyYXRvclNldElkUHJvdG9cbiAgICAgKi9cbiAgICBPcGVyYXRvclNldElkUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5PcGVyYXRvclNldElkUHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90bygpO1xuICAgICAgaWYgKG9iamVjdC5kb21haW4gIT0gbnVsbCkgbWVzc2FnZS5kb21haW4gPSBTdHJpbmcob2JqZWN0LmRvbWFpbik7XG4gICAgICBpZiAob2JqZWN0LnZlcnNpb24gIT0gbnVsbClcbiAgICAgICAgaWYgKCR1dGlsLkxvbmcpIChtZXNzYWdlLnZlcnNpb24gPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QudmVyc2lvbikpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QudmVyc2lvbiA9PT0gJ3N0cmluZycpIG1lc3NhZ2UudmVyc2lvbiA9IHBhcnNlSW50KG9iamVjdC52ZXJzaW9uLCAxMCk7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QudmVyc2lvbiA9PT0gJ251bWJlcicpIG1lc3NhZ2UudmVyc2lvbiA9IG9iamVjdC52ZXJzaW9uO1xuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LnZlcnNpb24gPT09ICdvYmplY3QnKVxuICAgICAgICAgIG1lc3NhZ2UudmVyc2lvbiA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QudmVyc2lvbi5sb3cgPj4+IDAsIG9iamVjdC52ZXJzaW9uLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCk7XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGFuIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5PcGVyYXRvclNldElkUHJvdG99IG1lc3NhZ2UgT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBPcGVyYXRvclNldElkUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5kb21haW4gPSAnJztcbiAgICAgICAgaWYgKCR1dGlsLkxvbmcpIHtcbiAgICAgICAgICB2YXIgbG9uZyA9IG5ldyAkdXRpbC5Mb25nKDAsIDAsIGZhbHNlKTtcbiAgICAgICAgICBvYmplY3QudmVyc2lvbiA9XG4gICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBsb25nLnRvU3RyaW5nKCkgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBsb25nLnRvTnVtYmVyKCkgOiBsb25nO1xuICAgICAgICB9IGVsc2Ugb2JqZWN0LnZlcnNpb24gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyAnMCcgOiAwO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9tYWluJykpIG9iamVjdC5kb21haW4gPSBtZXNzYWdlLmRvbWFpbjtcbiAgICAgIGlmIChtZXNzYWdlLnZlcnNpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd2ZXJzaW9uJykpXG4gICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS52ZXJzaW9uID09PSAnbnVtYmVyJylcbiAgICAgICAgICBvYmplY3QudmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLnZlcnNpb24pIDogbWVzc2FnZS52ZXJzaW9uO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgb2JqZWN0LnZlcnNpb24gPVxuICAgICAgICAgICAgb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLnZlcnNpb24pXG4gICAgICAgICAgICAgIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyXG4gICAgICAgICAgICAgICAgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS52ZXJzaW9uLmxvdyA+Pj4gMCwgbWVzc2FnZS52ZXJzaW9uLmhpZ2ggPj4+IDApLnRvTnVtYmVyKClcbiAgICAgICAgICAgICAgICA6IG1lc3NhZ2UudmVyc2lvbjtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgT3BlcmF0b3JTZXRJZFByb3RvIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBPcGVyYXRvclNldElkUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBPcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5PcGVyYXRvclNldElkUHJvdG8nO1xuICAgIH07XG5cbiAgICByZXR1cm4gT3BlcmF0b3JTZXRJZFByb3RvO1xuICB9KSgpO1xuXG4gIC8qKlxuICAgKiBPcGVyYXRvclN0YXR1cyBlbnVtLlxuICAgKiBAbmFtZSBvbm54Lk9wZXJhdG9yU3RhdHVzXG4gICAqIEBlbnVtIHtudW1iZXJ9XG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBFWFBFUklNRU5UQUw9MCBFWFBFUklNRU5UQUwgdmFsdWVcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IFNUQUJMRT0xIFNUQUJMRSB2YWx1ZVxuICAgKi9cbiAgb25ueC5PcGVyYXRvclN0YXR1cyA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZhbHVlc0J5SWQgPSB7fSxcbiAgICAgIHZhbHVlcyA9IE9iamVjdC5jcmVhdGUodmFsdWVzQnlJZCk7XG4gICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzBdID0gJ0VYUEVSSU1FTlRBTCcpXSA9IDA7XG4gICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzFdID0gJ1NUQUJMRScpXSA9IDE7XG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfSkoKTtcblxuICBvbm54LkZ1bmN0aW9uUHJvdG8gPSAoZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgb2YgYSBGdW5jdGlvblByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGludGVyZmFjZSBJRnVuY3Rpb25Qcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtuYW1lXSBGdW5jdGlvblByb3RvIG5hbWVcbiAgICAgKiBAcHJvcGVydHkge0FycmF5LjxzdHJpbmc+fG51bGx9IFtpbnB1dF0gRnVuY3Rpb25Qcm90byBpbnB1dFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPHN0cmluZz58bnVsbH0gW291dHB1dF0gRnVuY3Rpb25Qcm90byBvdXRwdXRcbiAgICAgKiBAcHJvcGVydHkge0FycmF5LjxzdHJpbmc+fG51bGx9IFthdHRyaWJ1dGVdIEZ1bmN0aW9uUHJvdG8gYXR0cmlidXRlXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JQXR0cmlidXRlUHJvdG8+fG51bGx9IFthdHRyaWJ1dGVQcm90b10gRnVuY3Rpb25Qcm90byBhdHRyaWJ1dGVQcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSU5vZGVQcm90bz58bnVsbH0gW25vZGVdIEZ1bmN0aW9uUHJvdG8gbm9kZVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb2NTdHJpbmddIEZ1bmN0aW9uUHJvdG8gZG9jU3RyaW5nXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JT3BlcmF0b3JTZXRJZFByb3RvPnxudWxsfSBbb3BzZXRJbXBvcnRdIEZ1bmN0aW9uUHJvdG8gb3BzZXRJbXBvcnRcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9tYWluXSBGdW5jdGlvblByb3RvIGRvbWFpblxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBGdW5jdGlvblByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgRnVuY3Rpb25Qcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJRnVuY3Rpb25Qcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JRnVuY3Rpb25Qcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEZ1bmN0aW9uUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgdGhpcy5pbnB1dCA9IFtdO1xuICAgICAgdGhpcy5vdXRwdXQgPSBbXTtcbiAgICAgIHRoaXMuYXR0cmlidXRlID0gW107XG4gICAgICB0aGlzLmF0dHJpYnV0ZVByb3RvID0gW107XG4gICAgICB0aGlzLm5vZGUgPSBbXTtcbiAgICAgIHRoaXMub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvblByb3RvIG5hbWUuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBuYW1lXG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8ucHJvdG90eXBlLm5hbWUgPSAnJztcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uUHJvdG8gaW5wdXQuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPHN0cmluZz59IGlucHV0XG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8ucHJvdG90eXBlLmlucHV0ID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uUHJvdG8gb3V0cHV0LlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxzdHJpbmc+fSBvdXRwdXRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5wcm90b3R5cGUub3V0cHV0ID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uUHJvdG8gYXR0cmlidXRlLlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxzdHJpbmc+fSBhdHRyaWJ1dGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5wcm90b3R5cGUuYXR0cmlidXRlID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uUHJvdG8gYXR0cmlidXRlUHJvdG8uXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSUF0dHJpYnV0ZVByb3RvPn0gYXR0cmlidXRlUHJvdG9cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5wcm90b3R5cGUuYXR0cmlidXRlUHJvdG8gPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb25Qcm90byBub2RlLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklOb2RlUHJvdG8+fSBub2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8ucHJvdG90eXBlLm5vZGUgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb25Qcm90byBkb2NTdHJpbmcuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBkb2NTdHJpbmdcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5wcm90b3R5cGUuZG9jU3RyaW5nID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvblByb3RvIG9wc2V0SW1wb3J0LlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklPcGVyYXRvclNldElkUHJvdG8+fSBvcHNldEltcG9ydFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5vcHNldEltcG9ydCA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvblByb3RvIGRvbWFpbi5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvbWFpblxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5kb21haW4gPSAnJztcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgRnVuY3Rpb25Qcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklGdW5jdGlvblByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguRnVuY3Rpb25Qcm90b30gRnVuY3Rpb25Qcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgRnVuY3Rpb25Qcm90byhwcm9wZXJ0aWVzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIEZ1bmN0aW9uUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5GdW5jdGlvblByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JRnVuY3Rpb25Qcm90b30gbWVzc2FnZSBGdW5jdGlvblByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICduYW1lJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8gMTApLnN0cmluZyhtZXNzYWdlLm5hbWUpO1xuICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgIT0gbnVsbCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmlucHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNCwgd2lyZVR5cGUgMiA9Ki8gMzQpLnN0cmluZyhtZXNzYWdlLmlucHV0W2ldKTtcbiAgICAgIGlmIChtZXNzYWdlLm91dHB1dCAhPSBudWxsICYmIG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm91dHB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDUsIHdpcmVUeXBlIDIgPSovIDQyKS5zdHJpbmcobWVzc2FnZS5vdXRwdXRbaV0pO1xuICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlICE9IG51bGwgJiYgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aDsgKytpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNiwgd2lyZVR5cGUgMiA9Ki8gNTApLnN0cmluZyhtZXNzYWdlLmF0dHJpYnV0ZVtpXSk7XG4gICAgICBpZiAobWVzc2FnZS5ub2RlICE9IG51bGwgJiYgbWVzc2FnZS5ub2RlLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm5vZGUubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5Ob2RlUHJvdG8uZW5jb2RlKG1lc3NhZ2Uubm9kZVtpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCA3LCB3aXJlVHlwZSAyID0qLyA1OCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkb2NTdHJpbmcnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA4LCB3aXJlVHlwZSAyID0qLyA2Nikuc3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKTtcbiAgICAgIGlmIChtZXNzYWdlLm9wc2V0SW1wb3J0ICE9IG51bGwgJiYgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLm9wc2V0SW1wb3J0W2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA5LCB3aXJlVHlwZSAyID0qLyA3NCkuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZG9tYWluJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTAsIHdpcmVUeXBlIDIgPSovIDgyKS5zdHJpbmcobWVzc2FnZS5kb21haW4pO1xuICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8gIT0gbnVsbCAmJiBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvLmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGVQcm90b1tpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTEsIHdpcmVUeXBlIDIgPSovIDkwKS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBGdW5jdGlvblByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguRnVuY3Rpb25Qcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSUZ1bmN0aW9uUHJvdG99IG1lc3NhZ2UgRnVuY3Rpb25Qcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIEZ1bmN0aW9uUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LkZ1bmN0aW9uUHJvdG99IEZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguRnVuY3Rpb25Qcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDQ6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuaW5wdXQgJiYgbWVzc2FnZS5pbnB1dC5sZW5ndGgpKSBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmlucHV0LnB1c2gocmVhZGVyLnN0cmluZygpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDU6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uub3V0cHV0ICYmIG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aCkpIG1lc3NhZ2Uub3V0cHV0ID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLm91dHB1dC5wdXNoKHJlYWRlci5zdHJpbmcoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA2OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmF0dHJpYnV0ZSAmJiBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGgpKSBtZXNzYWdlLmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGUucHVzaChyZWFkZXIuc3RyaW5nKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTE6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8gJiYgbWVzc2FnZS5hdHRyaWJ1dGVQcm90by5sZW5ndGgpKSBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvLnB1c2goJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDc6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uubm9kZSAmJiBtZXNzYWdlLm5vZGUubGVuZ3RoKSkgbWVzc2FnZS5ub2RlID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLm5vZGUucHVzaCgkcm9vdC5vbm54Lk5vZGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDg6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgOToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5vcHNldEltcG9ydCAmJiBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aCkpIG1lc3NhZ2Uub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2Uub3BzZXRJbXBvcnQucHVzaCgkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDEwOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmRvbWFpbiA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgRnVuY3Rpb25Qcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LkZ1bmN0aW9uUHJvdG99IEZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIEZ1bmN0aW9uUHJvdG8gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm5hbWUpKSByZXR1cm4gJ25hbWU6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5pbnB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2lucHV0JykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuaW5wdXQpKSByZXR1cm4gJ2lucHV0OiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuaW5wdXRbaV0pKSByZXR1cm4gJ2lucHV0OiBzdHJpbmdbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5vdXRwdXQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdvdXRwdXQnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5vdXRwdXQpKSByZXR1cm4gJ291dHB1dDogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5vdXRwdXRbaV0pKSByZXR1cm4gJ291dHB1dDogc3RyaW5nW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnYXR0cmlidXRlJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuYXR0cmlidXRlKSkgcmV0dXJuICdhdHRyaWJ1dGU6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuYXR0cmlidXRlW2ldKSkgcmV0dXJuICdhdHRyaWJ1dGU6IHN0cmluZ1tdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmF0dHJpYnV0ZVByb3RvICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnYXR0cmlidXRlUHJvdG8nKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5hdHRyaWJ1dGVQcm90bykpIHJldHVybiAnYXR0cmlidXRlUHJvdG86IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by52ZXJpZnkobWVzc2FnZS5hdHRyaWJ1dGVQcm90b1tpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2F0dHJpYnV0ZVByb3RvLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uubm9kZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25vZGUnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5ub2RlKSkgcmV0dXJuICdub2RlOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5ub2RlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5Ob2RlUHJvdG8udmVyaWZ5KG1lc3NhZ2Uubm9kZVtpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ25vZGUuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvY1N0cmluZykpIHJldHVybiAnZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2Uub3BzZXRJbXBvcnQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdvcHNldEltcG9ydCcpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm9wc2V0SW1wb3J0KSkgcmV0dXJuICdvcHNldEltcG9ydDogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90by52ZXJpZnkobWVzc2FnZS5vcHNldEltcG9ydFtpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ29wc2V0SW1wb3J0LicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9tYWluJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb21haW4pKSByZXR1cm4gJ2RvbWFpbjogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRnVuY3Rpb25Qcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5GdW5jdGlvblByb3RvfSBGdW5jdGlvblByb3RvXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LkZ1bmN0aW9uUHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LkZ1bmN0aW9uUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QubmFtZSAhPSBudWxsKSBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgaWYgKG9iamVjdC5pbnB1dCkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmlucHV0KSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5GdW5jdGlvblByb3RvLmlucHV0OiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmlucHV0Lmxlbmd0aDsgKytpKSBtZXNzYWdlLmlucHV0W2ldID0gU3RyaW5nKG9iamVjdC5pbnB1dFtpXSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0Lm91dHB1dCkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0Lm91dHB1dCkpIHRocm93IFR5cGVFcnJvcignLm9ubnguRnVuY3Rpb25Qcm90by5vdXRwdXQ6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2Uub3V0cHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lm91dHB1dC5sZW5ndGg7ICsraSkgbWVzc2FnZS5vdXRwdXRbaV0gPSBTdHJpbmcob2JqZWN0Lm91dHB1dFtpXSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmF0dHJpYnV0ZSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmF0dHJpYnV0ZSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguRnVuY3Rpb25Qcm90by5hdHRyaWJ1dGU6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuYXR0cmlidXRlID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmF0dHJpYnV0ZS5sZW5ndGg7ICsraSkgbWVzc2FnZS5hdHRyaWJ1dGVbaV0gPSBTdHJpbmcob2JqZWN0LmF0dHJpYnV0ZVtpXSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmF0dHJpYnV0ZVByb3RvKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuYXR0cmlidXRlUHJvdG8pKVxuICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguRnVuY3Rpb25Qcm90by5hdHRyaWJ1dGVQcm90bzogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGVQcm90byA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5hdHRyaWJ1dGVQcm90by5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmF0dHJpYnV0ZVByb3RvW2ldICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguRnVuY3Rpb25Qcm90by5hdHRyaWJ1dGVQcm90bzogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGVQcm90b1tpXSA9ICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8uZnJvbU9iamVjdChvYmplY3QuYXR0cmlidXRlUHJvdG9baV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0Lm5vZGUpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5ub2RlKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5GdW5jdGlvblByb3RvLm5vZGU6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2Uubm9kZSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5ub2RlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Qubm9kZVtpXSAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguRnVuY3Rpb25Qcm90by5ub2RlOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLm5vZGVbaV0gPSAkcm9vdC5vbm54Lk5vZGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC5ub2RlW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5kb2NTdHJpbmcgIT0gbnVsbCkgbWVzc2FnZS5kb2NTdHJpbmcgPSBTdHJpbmcob2JqZWN0LmRvY1N0cmluZyk7XG4gICAgICBpZiAob2JqZWN0Lm9wc2V0SW1wb3J0KSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Qub3BzZXRJbXBvcnQpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkZ1bmN0aW9uUHJvdG8ub3BzZXRJbXBvcnQ6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2Uub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Qub3BzZXRJbXBvcnQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5vcHNldEltcG9ydFtpXSAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkZ1bmN0aW9uUHJvdG8ub3BzZXRJbXBvcnQ6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2Uub3BzZXRJbXBvcnRbaV0gPSAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90by5mcm9tT2JqZWN0KG9iamVjdC5vcHNldEltcG9ydFtpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZG9tYWluICE9IG51bGwpIG1lc3NhZ2UuZG9tYWluID0gU3RyaW5nKG9iamVjdC5kb21haW4pO1xuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIEZ1bmN0aW9uUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LkZ1bmN0aW9uUHJvdG99IG1lc3NhZ2UgRnVuY3Rpb25Qcm90b1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0LmlucHV0ID0gW107XG4gICAgICAgIG9iamVjdC5vdXRwdXQgPSBbXTtcbiAgICAgICAgb2JqZWN0LmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgICBvYmplY3Qubm9kZSA9IFtdO1xuICAgICAgICBvYmplY3Qub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgICAgb2JqZWN0LmF0dHJpYnV0ZVByb3RvID0gW107XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QubmFtZSA9ICcnO1xuICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gJyc7XG4gICAgICAgIG9iamVjdC5kb21haW4gPSAnJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCduYW1lJykpIG9iamVjdC5uYW1lID0gbWVzc2FnZS5uYW1lO1xuICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgJiYgbWVzc2FnZS5pbnB1dC5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmlucHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraikgb2JqZWN0LmlucHV0W2pdID0gbWVzc2FnZS5pbnB1dFtqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm91dHB1dCAmJiBtZXNzYWdlLm91dHB1dC5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0Lm91dHB1dCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytqKSBvYmplY3Qub3V0cHV0W2pdID0gbWVzc2FnZS5vdXRwdXRbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGUgJiYgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGg7ICsraikgb2JqZWN0LmF0dHJpYnV0ZVtqXSA9IG1lc3NhZ2UuYXR0cmlidXRlW2pdO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uubm9kZSAmJiBtZXNzYWdlLm5vZGUubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5ub2RlID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5ub2RlLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5ub2RlW2pdID0gJHJvb3Qub25ueC5Ob2RlUHJvdG8udG9PYmplY3QobWVzc2FnZS5ub2RlW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKSBvYmplY3QuZG9jU3RyaW5nID0gbWVzc2FnZS5kb2NTdHJpbmc7XG4gICAgICBpZiAobWVzc2FnZS5vcHNldEltcG9ydCAmJiBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aCkge1xuICAgICAgICBvYmplY3Qub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5vcHNldEltcG9ydFtqXSA9ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uub3BzZXRJbXBvcnRbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9tYWluJykpIG9iamVjdC5kb21haW4gPSBtZXNzYWdlLmRvbWFpbjtcbiAgICAgIGlmIChtZXNzYWdlLmF0dHJpYnV0ZVByb3RvICYmIG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8ubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5hdHRyaWJ1dGVQcm90byA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8ubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LmF0dHJpYnV0ZVByb3RvW2pdID0gJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by50b09iamVjdChtZXNzYWdlLmF0dHJpYnV0ZVByb3RvW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgRnVuY3Rpb25Qcm90byB0byBKU09OLlxuICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBGdW5jdGlvblByb3RvXG4gICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5GdW5jdGlvblByb3RvJztcbiAgICB9O1xuXG4gICAgcmV0dXJuIEZ1bmN0aW9uUHJvdG87XG4gIH0pKCk7XG5cbiAgcmV0dXJuIG9ubng7XG59KSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9ICRyb290O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgTG9uZyBmcm9tICdsb25nJztcblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCAqIGFzIG9ydEZicyBmcm9tICcuL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQgeyBvbm54IH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuXG4vLyBjaGVjayB0aGUgaW5wdXRzIHNoYXBlIGJlZm9yZSBydW5uaW5nIGFuIE9QLlxuLy8gcmV0dXJuIHRydWUgd2hlbiB0aGUgaW5wdXRzIHBhc3MgdGhlIGNoZWNrXG4vLyByZXR1cm4gZmFsc2Ugd2hlbiB0aGUgaW5wdXRzIGRvIG5vdCBmaXQgdGhlIHJlcXVpcmVtZW50XG4vLyB0aHJvdyBleGNlcHRpb24gd2hlbiBmYXRhbCBlcnJvciBvciBub3QgaW1wbGVtZW50ZWRcbmV4cG9ydCBmdW5jdGlvbiBjaGVja0lucHV0c1NoYXBlKGlucHV0czogVGVuc29yW10sIC4uLmV4cGVjdGVkRGltZW5zaW9uczogbnVtYmVyW10pOiBib29sZWFuIHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gZXhwZWN0ZWREaW1lbnNpb25zLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgIGlmICghaW5wdXRzW2ldLmRpbXMgfHwgaW5wdXRzW2ldLmRpbXMubGVuZ3RoICE9PSBleHBlY3RlZERpbWVuc2lvbnNbaV0pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIEV2YWx1YXRlcyB0aGUgZ2l2ZW4gZXhwcmVzc2lvbiBhbmQgYXNzZXJ0cyBlcnJvciBtZXNzYWdlIGlmIGNvbmRpdGlvbiBpcyB1bm1ldC5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoZXhwcjogYm9vbGVhbiwgbXNnOiAoKSA9PiBzdHJpbmcpIHtcbiAgaWYgKCFleHByKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKHR5cGVvZiBtc2cgPT09ICdzdHJpbmcnID8gbXNnIDogbXNnKCkpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBBcnJheVV0aWwge1xuICAvKipcbiAgICogVmVyaWZpZXMgaWYgMiBpbnB1dCBhcnJheXMgY29udGFpbiB0aGUgc2FtZSBlbGVtZW50cy5cbiAgICogQHBhcmFtIG4xIEFycmF5IDFcbiAgICogQHBhcmFtIG4yIEFycmF5IDJcbiAgICogQHJldHVybnMgV2hldGhlciB0aGVzZSAyIGFyZSBlcXVhbFxuICAgKi9cbiAgc3RhdGljIGFycmF5c0VxdWFsKFxuICAgIG4xOlxuICAgICAgfCByZWFkb25seSBudW1iZXJbXVxuICAgICAgfCBJbnQ4QXJyYXlcbiAgICAgIHwgVWludDhBcnJheVxuICAgICAgfCBJbnQxNkFycmF5XG4gICAgICB8IFVpbnQxNkFycmF5XG4gICAgICB8IEludDMyQXJyYXlcbiAgICAgIHwgVWludDMyQXJyYXlcbiAgICAgIHwgVWludDhDbGFtcGVkQXJyYXlcbiAgICAgIHwgRmxvYXQzMkFycmF5XG4gICAgICB8IEZsb2F0NjRBcnJheSxcbiAgICBuMjpcbiAgICAgIHwgcmVhZG9ubHkgbnVtYmVyW11cbiAgICAgIHwgSW50OEFycmF5XG4gICAgICB8IFVpbnQ4QXJyYXlcbiAgICAgIHwgSW50MTZBcnJheVxuICAgICAgfCBVaW50MTZBcnJheVxuICAgICAgfCBJbnQzMkFycmF5XG4gICAgICB8IFVpbnQzMkFycmF5XG4gICAgICB8IFVpbnQ4Q2xhbXBlZEFycmF5XG4gICAgICB8IEZsb2F0MzJBcnJheVxuICAgICAgfCBGbG9hdDY0QXJyYXksXG4gICkge1xuICAgIGlmIChuMS5sZW5ndGggIT09IG4yLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG4xLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAobjFbaV0gIT09IG4yW2ldKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIE1hdE11bFV0aWwge1xuICAvKipcbiAgICogRml4IHRoZSBpbnB1dCBzaGFwZXMgZm9yIE1hdE11bCBvcGVyYXRpb24gaWYgdGhleSBuZWVkIGZpeGluZ1xuICAgKiBAcGFyYW0gZGltc0EgVGhlIHNoYXBlIG9mIHRlbnNvciBBLiBTaG91bGQgYmUgYW4gYXJyYXkgb2YgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHBhcmFtIGRpbXNCIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQi4gU2hvdWxkIGJlIGFuIGFycmF5IG9mIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEByZXR1cm5zIEEgdHVwbGUgY29udGFpbmluZyB0aGUgcHJlcHJvY2Vzc2VkIGlucHV0IHNoYXBlcyBhcyByZXF1aXJlZCBieSBPTk5YIHNwZWNpZmljYXRpb25zXG4gICAqL1xuICBzdGF0aWMgcHJlcHJvY2Vzc0lucHV0U2hhcGVzKFxuICAgIGRpbXNBOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBkaW1zQjogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IFtyZWFkb25seSBudW1iZXJbXSwgcmVhZG9ubHkgbnVtYmVyW11dIHtcbiAgICAvLyBJZiB0aGUgZmlyc3QgYXJndW1lbnQgaXMgMS1ELCBpdCBpcyBwcm9tb3RlZCB0byBhIG1hdHJpeCBieSBwcmVwZW5kaW5nXG4gICAgLy8gYSAxIHRvIGl0cyBkaW1lbnNpb25zLiBBZnRlciBtYXRyaXggbXVsdGlwbGljYXRpb24gdGhlIHByZXBlbmRlZCAxIGlzXG4gICAgLy8gcmVtb3ZlZC5cbiAgICBjb25zdCBhID0gZGltc0EubGVuZ3RoID09PSAxID8gWzEsIGRpbXNBWzBdXSA6IGRpbXNBO1xuXG4gICAgLy8gSWYgdGhlIHNlY29uZCBhcmd1bWVudCBpcyAxLUQsIGl0IGlzIHByb21vdGVkIHRvIGEgbWF0cml4IGJ5IGFwcGVuZGluZ1xuICAgIC8vIGEgMSB0byBpdHMgZGltZW5zaW9ucy4gQWZ0ZXIgbWF0cml4IG11bHRpcGxpY2F0aW9uIHRoZSBhcHBlbmRlZCAxIGlzXG4gICAgLy8gcmVtb3ZlZC5cbiAgICBjb25zdCBiID0gZGltc0IubGVuZ3RoID09PSAxID8gW2RpbXNCWzBdLCAxXSA6IGRpbXNCO1xuXG4gICAgcmV0dXJuIFthLCBiXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXggdGhlIG91dHB1dCBzaGFwZSBjb21wdXRlZCBmb3IgTWF0TXVsIG9wZXJhdGlvbiBpZiBpdCBuZWVkcyBmaXhpbmdcbiAgICogQHBhcmFtIG91dHB1dFNoYXBlIFRoZSBjb21wdXRlZCBvdXRwdXRTaGFwZS4gU2hvdWxkIGJlIGFuIGFycmF5IChhdCBsZWFzdCBvZiBsZW5ndGggMikgb2YgcG9zaXRpdmUgaW50ZWdlcnMuXG4gICAqIFRoaXMgd2lsbCBiZSBtdXRhdGVkLlxuICAgKiBAcGFyYW0gYVJhbmsgVGhlIHJhbmsgb2YgdGVuc29yIEEuXG4gICAqIEBwYXJhbSBiUmFuayBUaGUgcmFuayBvZiB0ZW5zb3IgQi5cbiAgICovXG4gIHN0YXRpYyBwb3N0cHJvY2Vzc091dHB1dFNoYXBlKG91dHB1dFNoYXBlOiBudW1iZXJbXSwgYVJhbms6IG51bWJlciwgYlJhbms6IG51bWJlcikge1xuICAgIC8vIFJlbW92ZSBwcmVwZW5kZWQgZGltZW5zaW9uIGlmIGZpcnN0IGlucHV0IGlzIDFkXG4gICAgaWYgKGFSYW5rID09PSAxKSB7XG4gICAgICAvLyBvdXRwdXRTaGFwZSA9IG91dHB1dFNoYXBlLnNsaWNlKDAsIG91dHB1dFNoYXBlLmxlbmd0aCAtIDIpLmNvbmNhdChvdXRwdXRTaGFwZS5zbGljZShvdXRwdXRTaGFwZS5sZW5ndGggLSAxKSk7XG4gICAgICBvdXRwdXRTaGFwZS5zcGxpY2Uob3V0cHV0U2hhcGUubGVuZ3RoIC0gMiwgMSk7XG4gICAgfVxuICAgIC8vIFJlbW92ZSBhcHBlbmRlZCBkaW1lbnNpb24gaWYgc2Vjb25kIGlucHV0IGlzIDFkXG4gICAgaWYgKGJSYW5rID09PSAxKSB7XG4gICAgICBvdXRwdXRTaGFwZS5wb3AoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBleHBlY3RlZCBzaGFwZSB3aGVuIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuICAgKiBAcGFyYW0gYSBUaGUgc2hhcGUgb2YgdGVuc29yIEEuIFNob3VsZCBiZSBhIHR1cGxlIG9mIDIgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHBhcmFtIGIgVGhlIHNoYXBlIG9mIHRlbnNvciBCLiBTaG91bGQgYmUgYSB0dXBsZSBvZiAyIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEByZXR1cm5zIFRoZSBleHBlY3RlZCBzaGFwZSBvZiB0aGUgcmVzdWx0LCBvciB1bmRlZmluZWQgaWYgTi9BXG4gICAqL1xuICBzdGF0aWMgY2FsY01hdE11bFNoYXBlKGE6IFtudW1iZXIsIG51bWJlcl0sIGI6IFtudW1iZXIsIG51bWJlcl0pOiBbbnVtYmVyLCBudW1iZXJdIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gYVsxXSAhPT0gYlswXSA/IHVuZGVmaW5lZCA6IFthWzBdLCBiWzFdXTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQnJvYWRjYXN0VXRpbCB7XG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIGV4cGVjdGVkIHNoYXBlIHdoZW4gYnJvYWRjYXN0aW5nIDIgdGVuc29yc1xuICAgKiBAcGFyYW0gYSBUaGUgc2hhcGUgb2YgdGVuc29yIEEuIFNob3VsZCBiZSBhbiBhcnJheSBvZiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0gYiBUaGUgc2hhcGUgb2YgdGVuc29yIEIuIFNob3VsZCBiZSBhbiBhcnJheSBvZiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0gaXNNYXRNdWwgV2hldGhlciB0aGUgb3BlcmF0aW9uIGlzIE1hdE11bFxuICAgKiBAcmV0dXJucyBUaGUgZXhwZWN0ZWQgc2hhcGUgb2YgdGhlIHJlc3VsdCwgb3IgdW5kZWZpbmVkIGlmIE4vQVxuICAgKi9cbiAgc3RhdGljIGNhbGNTaGFwZShcbiAgICBhZGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgYmRpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGlzTWF0TXVsID0gZmFsc2UsXG4gICk6IHJlYWRvbmx5IG51bWJlcltdIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBhcmFuayA9IGFkaW1zLmxlbmd0aDtcbiAgICBjb25zdCBicmFuayA9IGJkaW1zLmxlbmd0aDtcbiAgICBpZiAoYXJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBiZGltcztcbiAgICB9XG4gICAgaWYgKGJyYW5rID09PSAwKSB7XG4gICAgICByZXR1cm4gYWRpbXM7XG4gICAgfVxuICAgIGNvbnN0IGNyYW5rID0gTWF0aC5tYXgoYWRpbXMubGVuZ3RoLCBiZGltcy5sZW5ndGgpO1xuICAgIGNvbnN0IGNkaW1zID0gbmV3IEFycmF5PG51bWJlcj4oY3JhbmspO1xuXG4gICAgLy8gY2FsY3VsYXRlIHRoZSBsYXN0IDIgZGltZW5zaW9uIGlmIGl0IGlzIE1hdE11bFxuICAgIGlmIChpc01hdE11bCkge1xuICAgICAgaWYgKGFyYW5rIDwgMiB8fCBicmFuayA8IDIpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNTaGFwZU1hdE11bCA9IE1hdE11bFV0aWwuY2FsY01hdE11bFNoYXBlKFxuICAgICAgICBbYWRpbXNbYXJhbmsgLSAyXSwgYWRpbXNbYXJhbmsgLSAxXV0sXG4gICAgICAgIFtiZGltc1ticmFuayAtIDJdLCBiZGltc1ticmFuayAtIDFdXSxcbiAgICAgICk7XG4gICAgICBpZiAoY1NoYXBlTWF0TXVsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIFtjZGltc1tjcmFuayAtIDJdLCBjZGltc1tjcmFuayAtIDFdXSA9IGNTaGFwZU1hdE11bDtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gaXNNYXRNdWwgPyAzIDogMTsgaSA8PSBjcmFuazsgaSsrKSB7XG4gICAgICBjb25zdCBhTGVuID0gYXJhbmsgLSBpIDwgMCA/IDEgOiBhZGltc1thcmFuayAtIGldO1xuICAgICAgY29uc3QgYkxlbiA9IGJyYW5rIC0gaSA8IDAgPyAxIDogYmRpbXNbYnJhbmsgLSBpXTtcblxuICAgICAgaWYgKGFMZW4gIT09IGJMZW4gJiYgYUxlbiA+IDEgJiYgYkxlbiA+IDEpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGNkaW1zW2NyYW5rIC0gaV0gPSBNYXRoLm1heChhTGVuLCBiTGVuKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2RpbXM7XG4gIH1cblxuICAvKipcbiAgICogR2l2ZW4gdGhlIGluZGljZXMgb2YgYSBicm9hZGNhc3RlZCB0ZW5zb3IsIGNhbGN1bGF0ZSB0aGUgb3JpZ2luYWwgaW5kaWNlc1xuICAgKiBAcGFyYW0gYnJvYWRjYXN0ZWRJbmRpY2VzIFRoZSBnaXZlbiBpbmRpY2VzIG9mIHRoZSBicm9hZGNhc3RlZCB0ZW5zb3IuXG4gICAqIEBwYXJhbSBvcmlnaW5hbFNoYXBlIFRoZSBvcmlnaW5hbCBzaGFwZSBvZiB0aGUgdGVuc29yIGJlZm9yZSBicm9hZGNhc3RcbiAgICogQHJldHVybnMgVGhlIGNhbGN1bGF0ZWQgaW5kaWNlcyB0aGF0IG1hcHMgdG8gdGhlIG9yaWdpbmFsIHRlbnNvci5cbiAgICovXG4gIHN0YXRpYyBpbmRleChicm9hZGNhc3RlZEluZGljZXM6IHJlYWRvbmx5IG51bWJlcltdLCBvcmlnaW5hbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlcltdIHtcbiAgICAvLyBOT1RFIDE6IHdlIGFzc3VtZSB0aGUgcGFyYW1ldGVyIGJyb2FkY2FzdGVkSW5kaWNlcyBpcyB2YWxpZC4gaWUuIGl0IHNob3VsZCBoYXZlIHRoZSBzYW1lXG4gICAgLy8gbGVuZ3RoIGFzIHRoZSBicm9hZGNhc3RlZCBzaGFwZSwgYW5kIGZvciBlYWNoIGRpbWVuc2lvbiB0aGUgaW5kZXggc2hvdWxkXG4gICAgLy8gbm90IGJlIG91dCBvZiByYW5nZS5cbiAgICBjb25zdCBvcmlnaW5hbEluZGljZXMgPSBuZXcgQXJyYXkob3JpZ2luYWxTaGFwZS5sZW5ndGgpO1xuICAgIEJyb2FkY2FzdFV0aWwuZmlsbEluZGV4KGJyb2FkY2FzdGVkSW5kaWNlcywgb3JpZ2luYWxTaGFwZSwgb3JpZ2luYWxJbmRpY2VzKTtcbiAgICByZXR1cm4gb3JpZ2luYWxJbmRpY2VzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdpdmVuIHRoZSBpbmRpY2VzIG9mIGEgYnJvYWRjYXN0ZWQgdGVuc29yLCBjYWxjdWxhdGUgdGhlIG9yaWdpbmFsIGluZGljZXNcbiAgICogQHBhcmFtIGJyb2FkY2FzdGVkSW5kaWNlcyBUaGUgZ2l2ZW4gaW5kaWNlcyBvZiB0aGUgYnJvYWRjYXN0ZWQgdGVuc29yLlxuICAgKiBAcGFyYW0gb3JpZ2luYWxTaGFwZSBUaGUgb3JpZ2luYWwgc2hhcGUgb2YgdGhlIHRlbnNvciBiZWZvcmUgYnJvYWRjYXN0XG4gICAqIEBwYXJhbSBvcmlnaW5hbEluZGljZXMgVGhlIG1hcHBpbmcgb2YgYnJvYWRjYXN0ZWRJbmRpY2VzIHRvIHRoZSBvcmlnaW5hbEluZGljZXMgKG91dHB1dCBwYXJhbWV0ZXIgLSB3aWxsIGJlXG4gICAqICAgICBtdXRhdGVkKS5cbiAgICovXG4gIHN0YXRpYyBmaWxsSW5kZXgoYnJvYWRjYXN0ZWRJbmRpY2VzOiByZWFkb25seSBudW1iZXJbXSwgb3JpZ2luYWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIG9yaWdpbmFsSW5kaWNlczogbnVtYmVyW10pIHtcbiAgICAvLyBOT1RFIDE6IHdlIGFzc3VtZSB0aGUgcGFyYW1ldGVyIGJyb2FkY2FzdGVkSW5kaWNlcyBpcyB2YWxpZC4gaWUuIGl0IHNob3VsZCBoYXZlIHRoZSBzYW1lIGxlbmd0aCBhcyB0aGVcbiAgICAvLyBicm9hZGNhc3RlZCBzaGFwZSwgYW5kIGZvciBlYWNoIGRpbWVuc2lvbiB0aGUgaW5kZXggc2hvdWxkIG5vdCBiZSBvdXQgb2YgcmFuZ2UuXG4gICAgLy8gTk9URSAyOiB3ZSBhc3N1bWUgdGhlIHBhcmFtZXRlciBvcmlnaW5hbEluZGljZXMgaGFzIHRoZSBzYW1lIGxlbmd0aCBhcyB0aGUgb3JpZ2luYWxTaGFwZVxuICAgIGNvbnN0IGRpbU9mZnNldCA9IGJyb2FkY2FzdGVkSW5kaWNlcy5sZW5ndGggLSBvcmlnaW5hbFNoYXBlLmxlbmd0aDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9yaWdpbmFsU2hhcGUubGVuZ3RoOyBpKyspIHtcbiAgICAgIG9yaWdpbmFsSW5kaWNlc1tpXSA9IGJyb2FkY2FzdGVkSW5kaWNlc1tkaW1PZmZzZXQgKyBpXSAlIG9yaWdpbmFsU2hhcGVbaV07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gdGhlIGJyb2FkY2FzdGluZyBvcGVyYXRpb24gb24gdGhlIHNwZWNpZmljIG9wZXJhdG9yXG4gICAqIEBwYXJhbSBhIFRoZSBpbnB1dCB0ZW5zb3IgQVxuICAgKiBAcGFyYW0gYiBUaGUgaW5wdXQgdGVuc29yIEJcbiAgICogQHBhcmFtIG9wIFRoZSBvcGVyYXRvciBsYW1iZGEgZnVuY3Rpb25cbiAgICogQHBhcmFtIGlucGxhY2UgV2hldGhlciB0byB3cml0ZSB0aGUgcmVzdWx0IGJhY2sgdG8gQS5cbiAgICogQHJldHVybnMgVGhlIHJlc3VsdCB0ZW5zb3IsIG9yIHVuZGVmaW5lZCBpZiBpbnB1dCBub3QgYnJvYWRjYXN0YWJsZS5cbiAgICovXG4gIHN0YXRpYyBjYWxjKFxuICAgIGE6IFRlbnNvcixcbiAgICBiOiBUZW5zb3IsXG4gICAgb3A6IChhOiBzdHJpbmcgfCBudW1iZXIsIGI6IHN0cmluZyB8IG51bWJlcikgPT4gc3RyaW5nIHwgbnVtYmVyLFxuICAgIGlucGxhY2U6IGJvb2xlYW4sXG4gICAgcmVzdWx0VHlwZT86IFRlbnNvci5EYXRhVHlwZSxcbiAgKTogVGVuc29yIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBvdXRwdXRTaGFwZSA9IEJyb2FkY2FzdFV0aWwuY2FsY1NoYXBlKGEuZGltcywgYi5kaW1zKTtcblxuICAgIGlmIChvdXRwdXRTaGFwZSkge1xuICAgICAgaWYgKGlucGxhY2UgJiYgIVNoYXBlVXRpbC5hcmVFcXVhbChvdXRwdXRTaGFwZSwgYS5kaW1zKSkge1xuICAgICAgICAvLyBCIGlzIG5vdCBicm9hZGNhc3RhYmxlIHRvIEEsIGZhaWxlZCB0byBjYWxjdWxhdGUgaW5wbGFjZS5cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcbiAgICAgIGNvbnN0IGMgPSBpbnBsYWNlID8gYSA6IG5ldyBUZW5zb3Iob3V0cHV0U2hhcGUsIHJlc3VsdFR5cGUgfHwgYS50eXBlKTtcblxuICAgICAgLy8gYm90aCBpbnB1dHMgYXJlIHNjYWxhcnNcbiAgICAgIGlmIChvdXRwdXRTaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgYy5zZXQoW10sIG9wKGEuZ2V0KFtdKSBhcyBudW1iZXIsIGIuZ2V0KFtdKSBhcyBudW1iZXIpKTtcbiAgICAgIH1cblxuICAgICAgLy8gYXQgbGVhc3Qgb25lIGlucHV0IGlzIGEgbm9uLXNjYWxhclxuICAgICAgZWxzZSB7XG4gICAgICAgIGNvbnN0IG91dHB1dEluZGljZXMgPSBuZXcgQXJyYXk8bnVtYmVyPihvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICAgICAgICBjb25zdCBvcmlnaW5hbEluZGljZXNBID0gbmV3IEFycmF5KGEuZGltcy5sZW5ndGgpO1xuICAgICAgICBjb25zdCBvcmlnaW5hbEluZGljZXNCID0gbmV3IEFycmF5KGIuZGltcy5sZW5ndGgpO1xuICAgICAgICBsZXQgdmFsQTogc3RyaW5nIHwgbnVtYmVyID0gMDtcbiAgICAgICAgbGV0IHZhbEI6IHN0cmluZyB8IG51bWJlciA9IDA7XG4gICAgICAgIGxldCBpc0FTY2FsYXIgPSBmYWxzZTtcbiAgICAgICAgbGV0IGlzQlNjYWxhciA9IGZhbHNlO1xuICAgICAgICBpZiAoYS5kaW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHZhbEEgPSBhLmdldChbXSkgYXMgbnVtYmVyO1xuICAgICAgICAgIGlzQVNjYWxhciA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGIuZGltcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB2YWxCID0gYi5nZXQoW10pIGFzIG51bWJlcjtcbiAgICAgICAgICBpc0JTY2FsYXIgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXN0OiBudW1iZXI7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgICAgICAgLy8gdHJhdmVyc2FsIGluZGljZXNcbiAgICAgICAgICByZXN0ID0gaTtcbiAgICAgICAgICBmb3IgKGxldCBqID0gb3V0cHV0U2hhcGUubGVuZ3RoIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgICAgICAgIG91dHB1dEluZGljZXNbal0gPSByZXN0ICUgb3V0cHV0U2hhcGVbal07XG4gICAgICAgICAgICByZXN0ID0gTWF0aC5mbG9vcihyZXN0IC8gb3V0cHV0U2hhcGVbal0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghaXNBU2NhbGFyKSB7XG4gICAgICAgICAgICAvLyBtYXAgb3V0cHV0SW5kaWNlcyAod2hpY2ggaXMgYWN0dWFsbHkgYnJvYWRjYXN0ZWQpIHRvIHRoZSBvcmlnaW5hbEluZGljZXNcbiAgICAgICAgICAgIEJyb2FkY2FzdFV0aWwuZmlsbEluZGV4KG91dHB1dEluZGljZXMsIGEuZGltcywgb3JpZ2luYWxJbmRpY2VzQSk7XG4gICAgICAgICAgICB2YWxBID0gYS5nZXQob3JpZ2luYWxJbmRpY2VzQSkgYXMgbnVtYmVyO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWlzQlNjYWxhcikge1xuICAgICAgICAgICAgQnJvYWRjYXN0VXRpbC5maWxsSW5kZXgob3V0cHV0SW5kaWNlcywgYi5kaW1zLCBvcmlnaW5hbEluZGljZXNCKTtcbiAgICAgICAgICAgIHZhbEIgPSBiLmdldChvcmlnaW5hbEluZGljZXNCKSBhcyBudW1iZXI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYy5zZXQob3V0cHV0SW5kaWNlcywgb3AodmFsQSwgdmFsQikpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjO1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIGlmIGEgc2hhcGUgaXMgdW5pZGlyZWN0aW9uYWwgYnJvYWRjYXN0YWJsZSB0byBhbm90aGVyIHNoYXBlXG4gICAqIEBwYXJhbSBzaGFwZSBUaGUgaW5wdXQgc2hhcGVcbiAgICogQHBhcmFtIGZpbmFsU2hhcGUgVGhlIGRlc2lyZWQgc2hhcGUgYWZ0ZXIgYnJvYWRjYXN0aW5nXG4gICAqL1xuICBzdGF0aWMgaXNWYWxpZEJyb2FkY2FzdChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGZpbmFsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogYm9vbGVhbiB7XG4gICAgLy8gYWxpZ24gc2hhcGUgdG8gdGhlIHJpZ2h0XG4gICAgY29uc3QgaW5wdXRSYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IGZpbmFsUmFuayA9IGZpbmFsU2hhcGUubGVuZ3RoO1xuICAgIGlmIChpbnB1dFJhbmsgPiBmaW5hbFJhbmspIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPD0gaW5wdXRSYW5rOyBpKyspIHtcbiAgICAgIGlmIChzaGFwZVtpbnB1dFJhbmsgLSBpXSAhPT0gMSAmJiBzaGFwZVtpbnB1dFJhbmsgLSBpXSAhPT0gZmluYWxTaGFwZVtmaW5hbFJhbmsgLSBpXSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZSB0aGUgYnJvYWRjYXN0ZWQgZGltcyBpbiBpbnB1dCBzaGFwZSBiYXNlZCBvbiB0aGUgZ2l2ZW4gb3V0cHV0IHNoYXBlLlxuICAgKiBOb3RlIHRoYXQgdGhpcyBmdW5jdGlvbiBvbmx5IHJldHVybnMgdGhlIGJyb2FkY2FzdGVkIGRpbXMuXG4gICAqIEBwYXJhbSBpbnB1dFNoYXBlIFRoZSBpbnB1dCBzaGFwZVxuICAgKiBAcGFyYW0gb3V0cHV0U2hhcGUgVGhlIG91dHB1dCBzaGFwZVxuICAgKiBAcmV0dXJucyBUaGUgYnJvYWRjYXN0ZWQgZGltcyBpbiBpbnB1dCBzaGFwZS5cbiAgICovXG4gIHN0YXRpYyBnZXRCcm9hZGNhc3REaW1zKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgY29uc3QgaW5SYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgZGltczogbnVtYmVyW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluUmFuazsgaSsrKSB7XG4gICAgICBjb25zdCBkaW0gPSBpblJhbmsgLSAxIC0gaTtcbiAgICAgIGNvbnN0IGEgPSBpbnB1dFNoYXBlW2RpbV0gfHwgMTtcbiAgICAgIGNvbnN0IGIgPSBvdXRwdXRTaGFwZVtvdXRwdXRTaGFwZS5sZW5ndGggLSAxIC0gaV0gfHwgMTtcbiAgICAgIGlmIChiID4gMSAmJiBhID09PSAxKSB7XG4gICAgICAgIGRpbXMudW5zaGlmdChkaW0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGltcztcbiAgfVxufVxuXG4vLyBjb3B5IGFycmF5IGhlbHBlclxuLy8gbWltaWNzIG1lbWNweSBhcyBtdWNoIGFzIHBvc3NpYmxlXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlDb3B5SGVscGVyKFxuICB0YXJnZXQ6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gIHNvdXJjZTogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgdGFyZ2V0SW5kZXg6IG51bWJlcixcbiAgc291cmNlSW5kZXg6IG51bWJlcixcbiAgYmxvY2tTaXplOiBudW1iZXIsXG4pIHtcbiAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cbiAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cbiAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGluZGljZXMgdG8gYmUgY29waWVkIGFyZSBvdXRzaWRlIGJvdW5kcycpO1xuICB9XG4gIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldCBhcnJheSBpcyB0b28gc21hbGwgdG8gaG9sZCByZXN1bHQnKTtcbiAgfVxuXG4gIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdID0gc291cmNlW3NvdXJjZUluZGV4ICsgb2Zmc2V0XTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgR2VtbVV0aWwge1xuICAvLyB3aWxsIG1ha2Ugc3VyZSBpbnB1dCBzaGFwZXMgYXJlIGNvbXBhdGlibGUgZm9yIHRoaXMgb3BcbiAgLy8gYW5kIHJldHVybiBiYWNrIHRoZSBzaGFwZSBvZiB0aGUgb3V0cHV0IGluIHRoZSBmb3JtIG9mIGEgdHVwbGVcbiAgLy8gd2lsbCB0aHJvdyBleGNlcHRpb24gaWYgdGhlIGlucHV0IHNoYXBlcyBhcmUgbm90IGNvbXBhdGlibGVcbiAgc3RhdGljIGdldFNoYXBlT2ZHZW1tUmVzdWx0KFxuICAgIGxlZnRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgdHJhbnNMZWZ0OiBib29sZWFuLFxuICAgIHJpZ2h0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHRyYW5zUmlnaHQ6IGJvb2xlYW4sXG4gICAgYmlhc1NoYXBlPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBpZiAobGVmdFNoYXBlLmxlbmd0aCAhPT0gMiB8fCByaWdodFNoYXBlLmxlbmd0aCAhPT0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzaGFwZSBuZWVkIHRvIGJlIG9mIHNpemUgMicpO1xuICAgIH1cblxuICAgIGxldCBNOiBudW1iZXI7XG4gICAgbGV0IEs6IG51bWJlcjtcbiAgICBsZXQgTjogbnVtYmVyO1xuXG4gICAgaWYgKHRyYW5zTGVmdCkge1xuICAgICAgTSA9IGxlZnRTaGFwZVsxXTtcbiAgICAgIEsgPSBsZWZ0U2hhcGVbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIE0gPSBsZWZ0U2hhcGVbMF07XG4gICAgICBLID0gbGVmdFNoYXBlWzFdO1xuICAgIH1cblxuICAgIGxldCBrRGltID0gLTE7XG5cbiAgICBpZiAodHJhbnNSaWdodCkge1xuICAgICAgTiA9IHJpZ2h0U2hhcGVbMF07XG4gICAgICBrRGltID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgTiA9IHJpZ2h0U2hhcGVbMV07XG4gICAgICBrRGltID0gMDtcbiAgICB9XG5cbiAgICBpZiAocmlnaHRTaGFwZVtrRGltXSAhPT0gSykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdkaW1lbnNpb24gbWlzbWF0Y2gnKTtcbiAgICB9XG5cbiAgICBpZiAoTSA8PSAwIHx8IE4gPD0gMCB8fCBLIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBzaGFwZSBzcGVjaWZpZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoYmlhc1NoYXBlICYmICFCcm9hZGNhc3RVdGlsLmlzVmFsaWRCcm9hZGNhc3QoYmlhc1NoYXBlLCBbTSwgTl0pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dlbW06IGludmFsaWQgYmlhcyBzaGFwZSBmb3IgYnJvYWRjYXN0Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFtNLCBOLCBLXTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUHJvdG9VdGlsIHtcbiAgc3RhdGljIHRlbnNvckRhdGFUeXBlRnJvbVByb3RvKHR5cGVQcm90bzogb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZSB8IG9ydEZicy5UZW5zb3JEYXRhVHlwZSk6IFRlbnNvci5EYXRhVHlwZSB7XG4gICAgc3dpdGNoICh0eXBlUHJvdG8pIHtcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ4OlxuICAgICAgICByZXR1cm4gJ2ludDgnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ4OlxuICAgICAgICByZXR1cm4gJ3VpbnQ4JztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5CT09MOlxuICAgICAgICByZXR1cm4gJ2Jvb2wnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDE2OlxuICAgICAgICByZXR1cm4gJ2ludDE2JztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMTY6XG4gICAgICAgIHJldHVybiAndWludDE2JztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjpcbiAgICAgICAgcmV0dXJuICdpbnQzMic7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDMyOlxuICAgICAgICByZXR1cm4gJ3VpbnQzMic7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRkxPQVQ6XG4gICAgICAgIHJldHVybiAnZmxvYXQzMic7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFOlxuICAgICAgICByZXR1cm4gJ2Zsb2F0NjQnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlNUUklORzpcbiAgICAgICAgcmV0dXJuICdzdHJpbmcnO1xuXG4gICAgICAvLyBGb3IgSU5UNjQvVUlOVDY0LCByZWR1Y2UgdGhlaXIgdmFsdWUgdG8gMzItYml0cy5cbiAgICAgIC8vIFNob3VsZCB0aHJvdyBleGNlcHRpb24gd2hlbiBvdmVyZmxvd1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0OlxuICAgICAgICByZXR1cm4gJ2ludDMyJztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQ6XG4gICAgICAgIHJldHVybiAndWludDMyJztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7b25ueC5UZW5zb3JQcm90by5EYXRhVHlwZVt0eXBlUHJvdG9dfWApO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB0ZW5zb3JEYXRhVHlwZVN0cmluZ1RvRW51bSh0eXBlOiBzdHJpbmcpOiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlIHtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgJ2ludDgnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ4O1xuICAgICAgY2FzZSAndWludDgnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UODtcbiAgICAgIGNhc2UgJ2Jvb2wnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5CT09MO1xuICAgICAgY2FzZSAnaW50MTYnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQxNjtcbiAgICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQxNjtcbiAgICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMzI7XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzI7XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRkxPQVQ7XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFO1xuICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuU1RSSU5HO1xuICAgICAgY2FzZSAnaW50NjQnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ2NDtcbiAgICAgIGNhc2UgJ3VpbnQ2NCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDtcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7dHlwZX1gKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdGVuc29yRGltc0Zyb21Qcm90byhkaW1zOiBBcnJheTxudW1iZXIgfCBMb25nPik6IG51bWJlcltdIHtcbiAgICAvLyBnZXQgcmlkIG9mIExvbmcgdHlwZSBmb3IgZGltc1xuICAgIHJldHVybiBkaW1zLm1hcCgoZCkgPT4gKExvbmcuaXNMb25nKGQpID8gZC50b051bWJlcigpIDogZCkpO1xuICB9XG5cbiAgc3RhdGljIHRlbnNvclZhbHVlVHlwZUZyb21Qcm90byh2YWx1ZVR5cGU6IG9ubnguVHlwZVByb3RvLklUZW5zb3IpOiBHcmFwaC5WYWx1ZVR5cGUge1xuICAgIHJldHVybiB7XG4gICAgICB0ZW5zb3JUeXBlOiBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8odmFsdWVUeXBlLmVsZW1UeXBlISksXG4gICAgICBzaGFwZTogeyBkaW1zOiBQcm90b1V0aWwudGVuc29yRGltc0Zyb21Qcm90byh2YWx1ZVR5cGUuc2hhcGUhLmRpbSEubWFwKChkKSA9PiBkLmRpbVZhbHVlISkpIH0sXG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyB0ZW5zb3JEaW1zRnJvbU9SVEZvcm1hdCh0ZW5zb3I6IG9ydEZicy5UZW5zb3IpIHtcbiAgICBjb25zdCBkaW1zID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZW5zb3IuZGltc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGRpbXMucHVzaChMb25nVXRpbC5sb25nVG9OdW1iZXIodGVuc29yLmRpbXMoaSkhKSk7XG4gICAgfVxuICAgIHJldHVybiBkaW1zO1xuICB9XG5cbiAgc3RhdGljIHRlbnNvckF0dHJpYnV0ZXNGcm9tT1JURm9ybWF0KG5vZGU6IG9ydEZicy5Ob2RlKSB7XG4gICAgY29uc3QgYXR0cmlidXRlcyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZS5hdHRyaWJ1dGVzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgYXR0cmlidXRlcy5wdXNoKG5vZGUuYXR0cmlidXRlcyhpKSEpO1xuICAgIH1cbiAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTG9uZ1V0aWwge1xuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB0byBnZXQgYSBudW1iZXIgZnJvbSBsb25nIHR5cGUgb2YgZGF0YSBmb3IgYXR0cmlidXRlLCBkaW0sIGFuZCBpciB2ZXJzaW9uLFxuICAvLyB3aGljaCB2YWx1ZXMgYXJlIHNpZ25lZCBpbnRlZ2Vycy5cbiAgLy8gVG8gbWFrZSBpdCBtb3JlIGdlbmVyaWMsIGFkZCBhbiBvcHRpb25hbCBwYXJhbWV0ZXIgdG8gY29udmVydCB0byBhIHVuc2lnbmVkIG51bWJlci5cbiAgc3RhdGljIGxvbmdUb051bWJlcihuOiBMb25nIHwgYmlnaW50IHwgbnVtYmVyKSB7XG4gICAgaWYgKExvbmcuaXNMb25nKG4pKSB7XG4gICAgICByZXR1cm4gbi50b051bWJlcigpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG4gPT09ICdiaWdpbnQnKSB7XG4gICAgICByZXR1cm4gTnVtYmVyKG4pO1xuICAgIH1cbiAgICByZXR1cm4gbjtcbiAgfVxuICBzdGF0aWMgaXNMb25nKG46IHVua25vd24pIHtcbiAgICByZXR1cm4gTG9uZy5pc0xvbmcobikgfHwgdHlwZW9mIG4gPT09ICdiaWdpbnQnO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTaGFwZVV0aWwge1xuICBzdGF0aWMgc2l6ZShkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlciB7XG4gICAgcmV0dXJuIFNoYXBlVXRpbC5nZXRTaXplRnJvbURpbWVuc2lvblJhbmdlKGRpbXMsIDAsIGRpbXMubGVuZ3RoKTtcbiAgfVxuXG4gIC8vIGBheGlzYCBpbmNsdXNpdmVcbiAgc3RhdGljIHNpemVGcm9tRGltZW5zaW9uKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChheGlzIDwgMCB8fCBheGlzID4gZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBkaW1lbnNpb24gb2YgJHtheGlzfSBmb3Igc2l6ZUZyb21EaW1lbnNpb24gYXMgVGVuc29yIGhhcyAke2RpbXMubGVuZ3RofSBkaW1lbnNpb25zLmApO1xuICAgIH1cbiAgICByZXR1cm4gU2hhcGVVdGlsLmdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltcywgYXhpcywgZGltcy5sZW5ndGgpO1xuICB9XG5cbiAgLy8gYGF4aXNgIGV4Y2x1c2l2ZVxuICBzdGF0aWMgc2l6ZVRvRGltZW5zaW9uKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChheGlzIDwgMCB8fCBheGlzID4gZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBkaW1lbnNpb24gb2YgJHtheGlzfSBmb3Igc2l6ZVRvRGltZW5zaW9uIGFzIFRlbnNvciBoYXMgJHtkaW1zLmxlbmd0aH0gZGltZW5zaW9ucy5gKTtcbiAgICB9XG4gICAgcmV0dXJuIFNoYXBlVXRpbC5nZXRTaXplRnJvbURpbWVuc2lvblJhbmdlKGRpbXMsIDAsIGF4aXMpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgc2l6ZSA9IDE7XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgIC8vIHNhZmV0eSBjaGVjayBhcyB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgbXVsdGlwbGUgb3RoZXIgbWV0aG9kcyByZXF1aXJpbmcgc2l6ZS5cbiAgICAgIC8vIHNpemUgY2Fubm90IGJlIDAgb3IgbmVnYXRpdmUuXG4gICAgICBpZiAoZGltc1tpXSA8PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAnY2Fubm90IGdldCB2YWxpZCBzaXplIGZyb20gc3BlY2lmaWVkIGRpbWVuc2lvbiByYW5nZS4gTW9zdCBsaWtlbHkgdGhlIHJhbmdlIGNvbnRhaW5zIDAgb3IgbmVnYXRpdmUgdmFsdWVzIGluIHRoZW0uJyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHNpemUgKj0gZGltc1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIHNpemU7XG4gIH1cblxuICBzdGF0aWMgY29tcHV0ZVN0cmlkZXMoZGltczogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgY29uc3QgcmFuayA9IGRpbXMubGVuZ3RoO1xuICAgIGlmIChyYW5rID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfSBlbHNlIGlmIChyYW5rID09PSAxKSB7XG4gICAgICByZXR1cm4gWzFdO1xuICAgIH1cbiAgICBjb25zdCBzdHJpZGVzID0gbmV3IEFycmF5KHJhbmspO1xuICAgIHN0cmlkZXNbcmFuayAtIDFdID0gMTtcbiAgICBzdHJpZGVzW3JhbmsgLSAyXSA9IGRpbXNbcmFuayAtIDFdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMzsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHN0cmlkZXNbaV0gPSBzdHJpZGVzW2kgKyAxXSAqIGRpbXNbaSArIDFdO1xuICAgIH1cbiAgICByZXR1cm4gc3RyaWRlcztcbiAgfVxuXG4gIHN0YXRpYyB0cmFuc3Bvc2UoZGltczogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgY29uc3QgY29weSA9IGRpbXMuc2xpY2UoKTtcbiAgICByZXR1cm4gY29weS5yZXZlcnNlKCk7XG4gIH1cblxuICBzdGF0aWMgaW5kaWNlc1RvT2Zmc2V0KGluZGljZXM6IHJlYWRvbmx5IG51bWJlcltdLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSwgYXhpcz86IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGF4aXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgYXhpcyA9IGluZGljZXMubGVuZ3RoO1xuICAgIH1cbiAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF4aXM7ICsraSkge1xuICAgICAgb2Zmc2V0ICs9IHN0cmlkZXNbaV0gKiBpbmRpY2VzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIG9mZnNldFRvSW5kaWNlcyhvZmZzZXQ6IG51bWJlciwgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgY29uc3QgcmFuayA9IHN0cmlkZXMubGVuZ3RoO1xuICAgIGlmIChyYW5rID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfSBlbHNlIGlmIChyYW5rID09PSAxKSB7XG4gICAgICByZXR1cm4gW29mZnNldCAqIHN0cmlkZXNbMF1dO1xuICAgIH1cbiAgICBjb25zdCBpbmRpY2VzOiBudW1iZXJbXSA9IG5ldyBBcnJheShzdHJpZGVzLmxlbmd0aCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRpY2VzLmxlbmd0aCAtIDE7ICsraSkge1xuICAgICAgaW5kaWNlc1tpXSA9IE1hdGguZmxvb3Iob2Zmc2V0IC8gc3RyaWRlc1tpXSk7XG4gICAgICBvZmZzZXQgLT0gaW5kaWNlc1tpXSAqIHN0cmlkZXNbaV07XG4gICAgfVxuICAgIGluZGljZXNbaW5kaWNlcy5sZW5ndGggLSAxXSA9IG9mZnNldDtcbiAgICByZXR1cm4gaW5kaWNlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBub3JtYWxpemUgYXhpcyBvZiByYW5nZSBbLXIsIHIpIGludG8gWzAsIHIpLlxuICAgKi9cbiAgc3RhdGljIG5vcm1hbGl6ZUF4aXMoYXhpczogbnVtYmVyLCB0ZW5zb3JSYW5rOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChheGlzIDwgLXRlbnNvclJhbmsgJiYgYXhpcyA+PSB0ZW5zb3JSYW5rKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc3VwcG9ydGVkIGF4aXMgZm9yIHRoaXMgb3BlcmF0aW9uLicpO1xuICAgIH1cbiAgICByZXR1cm4gYXhpcyA8IDAgPyBheGlzICsgdGVuc29yUmFuayA6IGF4aXM7XG4gIH1cblxuICBzdGF0aWMgbm9ybWFsaXplQXhlcyhheGVzOiByZWFkb25seSBudW1iZXJbXSwgdGVuc29yUmFuazogbnVtYmVyKTogbnVtYmVyW10ge1xuICAgIHJldHVybiBheGVzLm1hcCgoeCkgPT4gdGhpcy5ub3JtYWxpemVBeGlzKHgsIHRlbnNvclJhbmspKTtcbiAgfVxuXG4gIC8vIEluY3JlbWVudCBhbiBpbmRleCBpbnRvIGEgdGVuc29yIChpbiBsZXhpY29ncmFwaGljXG4gIC8vIG9yZGVyaW5nKSwgd3JhcHBpbmcgYXJvdW5kIHRoZSBzcGVjaWZpZWQgdXBwZXJfYm91bmQuXG4gIC8qKlxuICAgKiBJbmNyZW1lbnQgYW4gaW5kZXggaW50byBhIHRlbnNvciAoaW4gbGV4aWNvZ3JhcGhpYyBvcmRlcmluZyksIHdyYXBwaW5nIGFyb3VuZCB0aGUgc3BlY2lmaWVkIHVwcGVyX2JvdW5kLlxuICAgKiBAcGFyYW0gaW5kZXggR2l2ZW4gaW5kZXggdG8gaW5jcmVtZW50IChXaWxsIGJlIG11dGF0ZWQpXG4gICAqIEBwYXJhbSBkaW1zIFRoZSBkaW1lbnNpb25zIG9mIHRoZSB0ZW5zb3IgZm9yIHdoaWNoIHRoZSBnaXZlbiBpbmRleCBjb3JyZXNwb25kcyB0b1xuICAgKiBAcGFyYW0gYXhpc1RvSW5jcmVtZW50T24gVGhlIDEtaW5kZXhlZCBheGlzIHRvIGluY3JlbWVudCBvbi4gSWYgdW5kZWZpbmVkLCBheGlzVG9JbmNyZW1lbnRPbiA9PSByYW5rXG4gICAqL1xuICBzdGF0aWMgaW5jcmVtZW50SW5kZXgoaW5kZXg6IG51bWJlcltdLCBkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhpc1RvSW5jcmVtZW50T24/OiBudW1iZXIpIHtcbiAgICBpZiAoZGltcy5sZW5ndGggPT09IDAgfHwgaW5kZXgubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0luZGV4IGluY3JlbWVudGluZyB1bnN1cHBvcnRlZCBmb3Igc2NhbGFyIFRlbnNvcicpO1xuICAgIH1cbiAgICBpZiAoYXhpc1RvSW5jcmVtZW50T24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgYXhpc1RvSW5jcmVtZW50T24gPSBkaW1zLmxlbmd0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGF4aXNUb0luY3JlbWVudE9uIDw9IDAgfHwgYXhpc1RvSW5jcmVtZW50T24gPiBkaW1zLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0luY29ycmVjdCBheGlzIHRvIGluY3JlbWVudCBvbicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAobGV0IGsgPSBheGlzVG9JbmNyZW1lbnRPbiAtIDE7IGsgPj0gMDsgLS1rKSB7XG4gICAgICBpbmRleFtrXSsrO1xuICAgICAgaWYgKGluZGV4W2tdIDwgZGltc1trXSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGluZGV4W2tdID0gMDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHJvZHVjZXMgYSBuZXcgZGltZW5zaW9ucyBhcnJheSBiYXNlZCBvbiB0aGUgdmFsdWVzIGluIHRoZSAnb3JpZ2luYWxEaW1lbnNpb25zJyBhbmQgJ3NoYXBlJyBhcnJheVxuICAgKiBVc2VkIGluIFJlc2hhcGVcbiAgICogQHBhcmFtIG9yaWdpbmFsRGltcyBPcmlnaW5hbCBTaGFwZSBhcnJheVxuICAgKiBAcGFyYW0gc2hhcGVIaW50cyBhcnJheSBjb250YWluaW5nIHZhbHVlcyB0byBjb21wdXRlIHRoZSBuZXcgZGltZW5zaW9uc1xuICAgKiBGb3IgZXhhbXBsZTpcbiAgICogb3JpZ2luYWxEaW1zID0gWzIsMl0gYW5kIHNoYXBlSGludHMgPSBbMCwtMV0gd2lsbCByZXR1cm4gWzIsMl1cbiAgICogb3JpZ2luYWxEaW1zID0gWzIsMl0gYW5kIHNoYXBlSGludHMgPSBbNF0gd2lsbCByZXR1cm4gWzRdXG4gICAqIG9yaWdpbmFsRGltcyA9IFsyLDJdIGFuZCBzaGFwZUhpbnRzID0gWzVdIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uXG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9vbm54L29ubngvYmxvYi9tYWluL2RvY3MvT3BlcmF0b3JzLm1kI1Jlc2hhcGVcbiAgICovXG5cbiAgc3RhdGljIGNhbGN1bGF0ZVJlc2hhcGVkRGltcyhvcmlnaW5hbERpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBzaGFwZUhpbnRzOiBBcnJheUxpa2U8bnVtYmVyPik6IG51bWJlcltdIHtcbiAgICAvLyByZXNoYXBlIHRvIGEgU2NhbGFyIFRlbnNvclxuICAgIGlmIChzaGFwZUhpbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKG9yaWdpbmFsRGltcy5sZW5ndGggPT09IDAgfHwgU2hhcGVVdGlsLnNpemUob3JpZ2luYWxEaW1zKSA9PT0gMSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCByZXNoYXBlIHRvIGEgc2NhbGFyIFRlbnNvcicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG5EaW1zID0gc2hhcGVIaW50cy5sZW5ndGg7XG4gICAgY29uc3QgcmVzaGFwZWREaW1zID0gbmV3IEFycmF5PG51bWJlcj4obkRpbXMpO1xuICAgIGxldCB1bmtub3duRGltZW5zaW9uID0gLTE7XG4gICAgbGV0IG5ld1RlbnNvclNpemUgPSAxO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbkRpbXM7IGkrKykge1xuICAgICAgaWYgKHNoYXBlSGludHNbaV0gPCAtMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2EgZGltZW5zaW9uIGluIHNoYXBlIGhpbnRzIGNhbm5vdCBiZSBsZXNzIHRoYW4gLTEnKTtcbiAgICAgIH1cbiAgICAgIGlmIChzaGFwZUhpbnRzW2ldID09PSAtMSkge1xuICAgICAgICBpZiAodW5rbm93bkRpbWVuc2lvbiAhPT0gLTEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2F0IG1vc3Qgb25lIGRpbWVuc2lvbiBpbiBzaGFwZSBoaW50cyBjYW4gYmUgLTEnKTtcbiAgICAgICAgfVxuICAgICAgICB1bmtub3duRGltZW5zaW9uID0gaTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChzaGFwZUhpbnRzW2ldID09PSAwKSB7XG4gICAgICAgICAgaWYgKGkgPj0gb3JpZ2luYWxEaW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgZGltZW5zaW9uIHdpdGggdmFsdWUgemVybyBleGNlZWRzIHRoZSBkaW1lbnNpb24gc2l6ZSBvZiB0aGUgaW5wdXQgdGVuc29yJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc2hhcGVkRGltc1tpXSA9IG9yaWdpbmFsRGltc1tpXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNoYXBlZERpbXNbaV0gPSBzaGFwZUhpbnRzW2ldO1xuICAgICAgICB9XG4gICAgICAgIG5ld1RlbnNvclNpemUgKj0gcmVzaGFwZWREaW1zW2ldO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG9sZFRlbnNvclNpemUgPSBTaGFwZVV0aWwuc2l6ZShvcmlnaW5hbERpbXMpO1xuICAgIGlmICh1bmtub3duRGltZW5zaW9uICE9PSAtMSkge1xuICAgICAgaWYgKG9sZFRlbnNvclNpemUgJSBuZXdUZW5zb3JTaXplICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgdGhlIGlucHV0IHRlbnNvciBjYW5ub3QgYmUgcmVzaGFwZWQgdG8gdGhlIHJlcXVlc3RlZCBzaGFwZS4gSW5wdXQgc2hhcGU6IFske1xuICAgICAgICAgICAgb3JpZ2luYWxEaW1zXG4gICAgICAgICAgfV0gT3V0cHV0IHNoYXBlOiBbJHtzaGFwZUhpbnRzfV1gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmVzaGFwZWREaW1zW3Vua25vd25EaW1lbnNpb25dID0gb2xkVGVuc29yU2l6ZSAvIG5ld1RlbnNvclNpemU7XG4gICAgfVxuICAgIC8vIHZhbGlkYXRlIHNpemVzIGZyb20gb3JpZ2luYWxEaW1zIGFuZCByZXNoYXBlZERpbXMgbWF0Y2hcbiAgICBlbHNlIHtcbiAgICAgIGlmIChuZXdUZW5zb3JTaXplICE9PSBvbGRUZW5zb3JTaXplKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInJlc2hhcGVkRGltcyBhbmQgb3JpZ2luYWxEaW1zIGRvbid0IGhhdmUgbWF0Y2hpbmcgc2l6ZXNcIik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXNoYXBlZERpbXM7XG4gIH1cblxuICAvKipcbiAgICogU29ydHMgYSBnaXZlbiBhcnJheSBiYXNlZCBvbiB0aGUgaW5kaWNlcyBpbiB0aGUgUGVybSBhcnJheVxuICAgKiBVc2VkIGluIFRyYW5zcG9zZVxuICAgKiBAcGFyYW0gYSBBcnJheSB0byBiZSBzb3J0ZWQgc3VjaCBhcyBkaW1zIG9yIHN0cmlkZXNcbiAgICogQHBhcmFtIHBlcm0gUGVybSBnaXZlbjsgaWYgbnVsbCBhIHdpbGwgYmUgcmV2ZXJzZWRcbiAgICovXG4gIHN0YXRpYyBzb3J0QmFzZWRPblBlcm0oYTogcmVhZG9ubHkgbnVtYmVyW10sIHBlcm0/OiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBpZiAocGVybSkge1xuICAgICAgcmV0dXJuIHBlcm0ubWFwKCh2KSA9PiBhW3ZdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGEuc2xpY2UoKS5yZXZlcnNlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhZHMgYSBnaXZlbiBzaGFwZSBhY2NvcmRpbmcgdG8gdGhlIHBhZGRpbmcgdmFsdWVzXG4gICAqIEBwYXJhbSBkaW1zIHNoYXBlIG9mIHRoZSBUZW5zb3IgdG8gYmUgcGFkZGVkXG4gICAqIEBwYXJhbSBwYWQgcGFkIHZhbHVlc1xuICAgKi9cbiAgc3RhdGljIHBhZFNoYXBlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBwYWQ6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IHJhbmsgPSBkaW1zLmxlbmd0aDtcbiAgICByZXR1cm4gZGltcy5tYXAoKHYsIGkpID0+IHYgKyBwYWRbaV0gKyBwYWRbaSArIHJhbmtdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIGlmIHRoZSB0d28gc2hhcGVzIGFyZSBpZGVudGljYWxcbiAgICogQHBhcmFtIHNoYXBlMVxuICAgKiBAcGFyYW0gc2hhcGUyXG4gICAqL1xuICBzdGF0aWMgYXJlRXF1YWwoc2hhcGUxOiByZWFkb25seSBudW1iZXJbXSwgc2hhcGUyOiByZWFkb25seSBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICAgIGlmIChzaGFwZTEubGVuZ3RoICE9PSBzaGFwZTIubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBzaGFwZTEuZXZlcnkoKHYsIGkpID0+IHYgPT09IHNoYXBlMltpXSk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGlmIHRoZSBnaXZlbiBgZGltc2Agb3IgYHNoYXBlYCBpcyB2YWxpZCBpbiBPTk5YLmpzIGNvbnRleHQgYW5kIHJldHVybnMgZGF0YSBzaXplXG4gICAqIEBwYXJhbSBkaW1zIC0gaW5wdXQgYGRpbXNgIHRoYXQgbmVlZHMgdG8gYmUgY2hlY2tlZFxuICAgKi9cbiAgc3RhdGljIHZhbGlkYXRlRGltc0FuZENhbGNTaXplKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyIHtcbiAgICBpZiAoZGltcy5sZW5ndGggPiA2KSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdPbmx5IHJhbmsgMCB0byA2IGlzIHN1cHBvcnRlZCBmb3IgdGVuc29yIHNoYXBlLicpO1xuICAgIH1cbiAgICBsZXQgc2l6ZSA9IDE7XG4gICAgZm9yIChjb25zdCBuIG9mIGRpbXMpIHtcbiAgICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihuKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBJbnZhbGlkIHNoYXBlOiAke259IGlzIG5vdCBhbiBpbnRlZ2VyYCk7XG4gICAgICB9XG4gICAgICBpZiAobiA8IDAgfHwgbiA+IDIxNDc0ODM2NDcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgSW52YWxpZCBzaGFwZTogbGVuZ3RoICR7bn0gaXMgbm90IGFsbG93ZWRgKTtcbiAgICAgIH1cbiAgICAgIHNpemUgKj0gbjtcbiAgICB9XG4gICAgcmV0dXJuIHNpemU7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyB0aGUgc2hhcGUgb2Ygb3V0cHV0IHRlbnNvciB5ID0gZmxhdHRlbih4LCBheGlzKVxuICAgKiBAcGFyYW0gZGltcyAtIHNoYXBlIG9mIGlucHV0IHRlbnNvclxuICAgKiBAcGFyYW0gYXhpcyAtIGZsYXR0ZW4gYXhpcywgaW4gdGhlIHJhbmdlIFstciwgcl1cbiAgICovXG4gIHN0YXRpYyBmbGF0dGVuU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXM6IG51bWJlcik6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBpZiAoYXhpcyA8IDApIHtcbiAgICAgIGF4aXMgKz0gZGltcy5sZW5ndGg7XG4gICAgfVxuICAgIGNvbnN0IHRvdGFsID0gZGltcy5yZWR1Y2UoKHgsIHkpID0+IHggKiB5LCAxKTtcbiAgICBjb25zdCByaWdodCA9IGRpbXMuc2xpY2UoYXhpcykucmVkdWNlKCh4LCB5KSA9PiB4ICogeSwgMSk7XG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IFt0b3RhbCAvIHJpZ2h0LCByaWdodF07XG5cbiAgICByZXR1cm4gb3V0cHV0RGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIHRoZSBzaGFwZSBvZiBvdXRwdXQgdGVuc29yIHkgPSBzcXVlZXplKHgsIGF4ZXMpXG4gICAqIEBwYXJhbSBkaW1zIC0gc2hhcGUgb2YgaW5wdXQgdGVuc29yXG4gICAqIEBwYXJhbSBheGVzIC0gc3F1ZWV6ZSBheGVzXG4gICAqL1xuICBzdGF0aWMgc3F1ZWV6ZVNoYXBlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGVzOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCBvdXRwdXREaW1zID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblxuICAgIC8vIHNhbml0eSBjaGVja1xuICAgIGF4ZXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhlcyhheGVzLCBkaW1zLmxlbmd0aCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGluU3F1ZWV6ZUxpc3QgPSBheGVzLmluZGV4T2YoaSkgPj0gMDtcbiAgICAgIGlmIChpblNxdWVlemVMaXN0ICYmIGRpbXNbaV0gIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzcXVlZXplIGFuIGF4aXMgb2Ygc2l6ZSBkaWZmZXJlbnQgdGhhbiAxJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICgoYXhlcy5sZW5ndGggPT09IDAgJiYgZGltc1tpXSA+IDEpIHx8IChheGVzLmxlbmd0aCA+IDAgJiYgIWluU3F1ZWV6ZUxpc3QpKSB7XG4gICAgICAgIG91dHB1dERpbXMucHVzaChkaW1zW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0RGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIHRoZSBzaGFwZSBvZiBvdXRwdXQgdGVuc29yIHkgPSB1bnNxdWVlemUoeCwgYXhlcylcbiAgICogQHBhcmFtIGRpbXMgLSBzaGFwZSBvZiBpbnB1dCB0ZW5zb3JcbiAgICogQHBhcmFtIGF4ZXMgLSB1bnNxdWVlemUgYXhlc1xuICAgKi9cbiAgc3RhdGljIHVuc3F1ZWV6ZVNoYXBlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGVzOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCBvdXRwdXREaW1zID0gbmV3IEFycmF5PG51bWJlcj4oZGltcy5sZW5ndGggKyBheGVzLmxlbmd0aCk7XG5cbiAgICAvLyBpbml0aWFsaXplIHRoZSBhcnJheSBlbGVtZW50cyB0byAwXG4gICAgb3V0cHV0RGltcy5maWxsKDApO1xuXG4gICAgLy8gc2V0IGFsbCBheGVzIGluZGljZXMgdG8gMSBpbiBvdXRwdXREaW1zIGFuZCBjaGVjayBmb3IgZHVwbGljYXRlc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXhlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF4ZXNbaV0sIG91dHB1dERpbXMubGVuZ3RoKTtcbiAgICAgIGlmIChheGlzID49IG91dHB1dERpbXMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIidheGVzJyBoYXMgYW4gb3V0IG9mIHJhbmdlIGF4aXNcIik7XG4gICAgICB9XG4gICAgICBpZiAob3V0cHV0RGltc1theGlzXSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCInYXhlcycgaGFzIGEgZHVwbGljYXRlIGF4aXNcIik7XG4gICAgICB9XG5cbiAgICAgIG91dHB1dERpbXNbYXhpc10gPSAxO1xuICAgIH1cblxuICAgIC8vIGZpbGwgaW4gdGhlIHplcm8gZW50cmllcyBvZiBvdXRwdXREaW1zIHdpdGggdGhlIGlucHV0IHRlbnNvcidzIHNoYXBlXG4gICAgbGV0IGlucHV0RGltc0l0ZXJhdG9yID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dHB1dERpbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChvdXRwdXREaW1zW2ldID09PSAwKSB7XG4gICAgICAgIG91dHB1dERpbXNbaV0gPSBkaW1zW2lucHV0RGltc0l0ZXJhdG9yKytdO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNhbml0eSBjaGVjayBhc3NlcnRpb24uICdpbnB1dERpbXNJdGVyYXRvcidcbiAgICAvLyBzaG91bGQgYmUgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZiAnZGltcydcbiAgICBpZiAoaW5wdXREaW1zSXRlcmF0b3IgIT09IGRpbXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RoZSB1bnNxdWVlemVkIGRpbWVuc2lvbiBjb3VsZCBub3QgYmUgZXN0YWJsaXNoZWQnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0RGltcztcbiAgfVxufVxuXG4vLyBidW5jaCBvZiBoZWxwZXIgbWV0aG9kcyB0aGF0IGRvIGEgdmFyaWV0eSBvZiBtYXRoIG9wZXJhdGlvbnNcbmV4cG9ydCBjbGFzcyBNYXRoVXRpbCB7XG4gIC8vIHkgPSAoeCp4KSArIHlcbiAgc3RhdGljIHNxcihcbiAgICB0YXJnZXQ6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgc291cmNlOiBudW1iZXJbXSB8IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHRhcmdldEluZGV4OiBudW1iZXIsXG4gICAgc291cmNlSW5kZXg6IG51bWJlcixcbiAgICBibG9ja1NpemU6IG51bWJlcixcbiAgKSB7XG4gICAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICAgIH1cblxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gKz0gTWF0aC5wb3coc291cmNlW3NvdXJjZUluZGV4ICsgb2Zmc2V0XSwgMik7XG4gICAgfVxuICB9XG5cbiAgLy8geSA9IGF4ICsgeVxuICBzdGF0aWMgYXhweShcbiAgICB0YXJnZXQ6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgc291cmNlOiBudW1iZXJbXSB8IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHRhcmdldEluZGV4OiBudW1iZXIsXG4gICAgc291cmNlSW5kZXg6IG51bWJlcixcbiAgICBibG9ja1NpemU6IG51bWJlcixcbiAgICBhbHBoYTogbnVtYmVyLFxuICApIHtcbiAgICBpZiAoc291cmNlSW5kZXggPCAwIHx8IHNvdXJjZUluZGV4ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlSW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggPCAwIHx8IHRhcmdldEluZGV4ID49IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0SW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAoc291cmNlSW5kZXggKyBibG9ja1NpemUgPiBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZSBpbmRpY2VzIHRvIGJlIGNvcGllZCBhcmUgb3V0c2lkZSBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4ICsgYmxvY2tTaXplID4gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXQgYXJyYXkgaXMgdG9vIHNtYWxsIHRvIGhvbGQgcmVzdWx0Jyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgYmxvY2tTaXplOyBvZmZzZXQrKykge1xuICAgICAgdGFyZ2V0W3RhcmdldEluZGV4ICsgb2Zmc2V0XSArPSBhbHBoYSAqIHNvdXJjZVtzb3VyY2VJbmRleCArIG9mZnNldF07XG4gICAgfVxuICB9XG5cbiAgLy8geSA9IHBvdyh4LCBiKVxuICBzdGF0aWMgcG93eChcbiAgICB0YXJnZXQ6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgc291cmNlOiBudW1iZXJbXSB8IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHRhcmdldEluZGV4OiBudW1iZXIsXG4gICAgc291cmNlSW5kZXg6IG51bWJlcixcbiAgICBibG9ja1NpemU6IG51bWJlcixcbiAgICBiOiBudW1iZXIsXG4gICkge1xuICAgIGlmIChzb3VyY2VJbmRleCA8IDAgfHwgc291cmNlSW5kZXggPj0gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCA8IDAgfHwgdGFyZ2V0SW5kZXggPj0gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmIChzb3VyY2VJbmRleCArIGJsb2NrU2l6ZSA+IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGluZGljZXMgdG8gYmUgY29waWVkIGFyZSBvdXRzaWRlIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggKyBibG9ja1NpemUgPiB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldCBhcnJheSBpcyB0b28gc21hbGwgdG8gaG9sZCByZXN1bHQnKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBibG9ja1NpemU7IG9mZnNldCsrKSB7XG4gICAgICB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdID0gTWF0aC5wb3coc291cmNlW3NvdXJjZUluZGV4ICsgb2Zmc2V0XSwgYik7XG4gICAgfVxuICB9XG5cbiAgLy8geSA9IHggKiB5XG4gIHN0YXRpYyBtdWwoXG4gICAgdGFyZ2V0OiBudW1iZXJbXSB8IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHNvdXJjZTogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICB0YXJnZXRJbmRleDogbnVtYmVyLFxuICAgIHNvdXJjZUluZGV4OiBudW1iZXIsXG4gICAgYmxvY2tTaXplOiBudW1iZXIsXG4gICkge1xuICAgIGlmIChzb3VyY2VJbmRleCA8IDAgfHwgc291cmNlSW5kZXggPj0gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCA8IDAgfHwgdGFyZ2V0SW5kZXggPj0gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmIChzb3VyY2VJbmRleCArIGJsb2NrU2l6ZSA+IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGluZGljZXMgdG8gYmUgY29waWVkIGFyZSBvdXRzaWRlIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggKyBibG9ja1NpemUgPiB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldCBhcnJheSBpcyB0b28gc21hbGwgdG8gaG9sZCByZXN1bHQnKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBibG9ja1NpemU7IG9mZnNldCsrKSB7XG4gICAgICB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdID0gc291cmNlW3NvdXJjZUluZGV4ICsgb2Zmc2V0XSAqIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF07XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTcGxpdFV0aWwge1xuICAvKipcbiAgICogQ2FsY3VsYXRlcyBuZXcgU2hhcGVzIGZyb20gZXhpc3Rpbmcgb25lIGFuZCB0aGUgc3BsaXRzIGdpdmVuIGFsb25nIHRoZSBheGlzIHByb3ZpZGVzXG4gICAqIEBwYXJhbSBkaW1zIFNoYXBlIG9mIHRoZSBUZW5zb3IgdG8gYmUgc3BsaXR0ZWQgaW50byB0d28gb3IgbW9yZSBTaGFwZXNcbiAgICogQHBhcmFtIGF4aXMgVGhlIGRpbWVuc2lvbiBhbG9uZyB3aGljaCB0aGUgVGVuc29yIHdpbGwgYmUgc3BsaXRcbiAgICogQHBhcmFtIHNwbGl0cyBPZmZzZXRzIGZvciB0aGUgc3RhcnQgb2YgZWFjaCBzcGxpdFxuICAgKi9cbiAgc3RhdGljIHNwbGl0U2hhcGUoXG4gICAgZGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgYXhpczogbnVtYmVyLFxuICAgIHNwbGl0OiBudW1iZXJbXSxcbiAgICBudW1PdXRwdXRzPzogbnVtYmVyLFxuICApOiBbbnVtYmVyW11bXSwgbnVtYmVyW11dIHtcbiAgICBpZiAoc3BsaXQubGVuZ3RoID09PSAwKSB7XG4gICAgICBpZiAoIW51bU91dHB1dHMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibmVlZCB0byBrbm93IG51bWJlciBvZiBvdXRwdXRzIHdoZW4gdGhlICdzcGxpdCcgYXR0cmlidXRlIGlzIG5vdCBzcGVjaWZpZWRcIik7XG4gICAgICB9XG4gICAgICBTcGxpdFV0aWwuZGV0ZXJtaW5lU3BsaXQoZGltc1theGlzXSwgbnVtT3V0cHV0cywgc3BsaXQpO1xuICAgIH1cblxuICAgIGNvbnN0IHNoYXBlczogbnVtYmVyW11bXSA9IFtdO1xuICAgIGNvbnN0IG9mZnNldHMgPSBbMF07XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzcGxpdC5sZW5ndGg7ICsraSkge1xuICAgICAgaWYgKGkgIT09IDApIHtcbiAgICAgICAgb2Zmc2V0cy5wdXNoKG9mZnNldHNbaSAtIDFdICsgc3BsaXRbaSAtIDFdKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNoYXBlID0gZGltcy5zbGljZSgpO1xuICAgICAgc2hhcGVbYXhpc10gPSBzcGxpdFtpXTtcbiAgICAgIHNoYXBlcy5wdXNoKHNoYXBlKTtcbiAgICB9XG4gICAgcmV0dXJuIFtzaGFwZXMsIG9mZnNldHNdO1xuICB9XG5cbiAgc3RhdGljIGRldGVybWluZVNwbGl0KG51bUVsZW1lbnRzQWxvbmdBeGlzOiBudW1iZXIsIG51bU91dHB1dHM6IG51bWJlciwgc3BsaXQ6IG51bWJlcltdKSB7XG4gICAgLy8gSWYgJ3NwbGl0JyBpcyBub3Qgc3BlY2lmaWVkIGJ5IHRoZSB1c2VyLCB3ZSBuZWVkIHRvIHBhcnRpdGlvbiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGVxdWFsbHkgYW1vbmcgdGhlIG91dHB1dHNcbiAgICBpZiAobnVtRWxlbWVudHNBbG9uZ0F4aXMgJSBudW1PdXRwdXRzICE9PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBzcGxpdCB0ZW5zb3IgdG8gZXF1YWwgc2l6ZWQgcGFydHMnKTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1PdXRwdXRzOyArK2kpIHtcbiAgICAgIHNwbGl0LnB1c2gobnVtRWxlbWVudHNBbG9uZ0F4aXMgLyBudW1PdXRwdXRzKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFJlZHVjZVV0aWwge1xuICAvKipcbiAgICogUGVyZm9ybSByZWR1Y2Ugb3BlcmF0aW9ucyBvbiB0aGUgc3BlY2lmaWMgb3BlcmF0b3JcbiAgICogQHBhcmFtIGEgSW5wdXQgdGVuc29yIGRhdGFcbiAgICogQHBhcmFtIGF4ZXMgVGhlIGRpbWVuc2lvbnMgYWxvbmcgd2hpY2ggdGhlIFRlbnNvciB3aWxsIGJlIHJlZHVjZWRcbiAgICogQHBhcmFtIGtlZXBkaW1zIElmIHNldCB0byB0cnVlLCB0aGUgYXhlcyB3aGljaCBhcmUgcmVkdWNlZCBhcmUgbGVmdCBpbiB0aGVcbiAgICogICAgcmVzdWx0IGFzIGRpbWVuc2lvbnMgd2l0aCBzaXplIG9uZS5cbiAgICogQHBhcmFtIG9wMSBUaGUgb3BlcmF0aW9uIHRvIGJlIHBlcmZvcm1lZCBvbiBlYWNoIGVsZW1lbnQgaW4gdGhlIHRlbnNvclxuICAgKiBAcGFyYW0gb3AyIFRoZSBvcGVyYXRpb24gdG8gYmUgcGVyZm9ybWVkIGJldHdlZW4gZWxlbWVudHMgaW4gdGhlIHRlbnNvclxuICAgKi9cbiAgc3RhdGljIGNhbGNSZWR1Y2UoXG4gICAgYTogVGVuc29yLFxuICAgIGF4ZXM6IG51bWJlcltdLFxuICAgIGtlZXBkaW1zOiBib29sZWFuLFxuICAgIG9wMTogKGI6IG51bWJlcikgPT4gbnVtYmVyLFxuICAgIG9wMjogKGE6IG51bWJlciwgYjogbnVtYmVyKSA9PiBudW1iZXIsXG4gICk6IFRlbnNvciB7XG4gICAgY29uc3QgZGltcyA9IGEuZGltcy5zbGljZSgwKTtcbiAgICAvLyBpZiBheGVzIGlzIG5vdCBzZXQsIHBlcmZvcm0gcmVkdWNlIG9uIGFsbCBheGVzXG4gICAgaWYgKGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBkaW1zLmZvckVhY2goKF9kLCBpbmQpID0+IGF4ZXMucHVzaChpbmQpKTtcbiAgICB9XG4gICAgLy8gZ2V0IGEgdGVtcG9yYXJ5IGJyb2FkY2FzdGFibGUgb3V0cHV0IHNoYXBlXG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IFJlZHVjZVV0aWwuY2FsY1JlZHVjZVNoYXBlKGRpbXMsIGF4ZXMsIHRydWUpO1xuXG4gICAgLy8gbG9vcCB0aHJvdWdoIHRoZSBvdXRwdXQgYW5kIGNhbGN1bGF0ZSByZXN1bHQgb25lIGJ5IG9uZVxuICAgIGNvbnN0IHNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXREaW1zKTtcbiAgICBjb25zdCB5ID0gbmV3IFRlbnNvcihvdXRwdXREaW1zLCBhLnR5cGUpO1xuICAgIGNvbnN0IHN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMob3V0cHV0RGltcyk7XG4gICAgY29uc3QgaW5wdXRTdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKGRpbXMpO1xuICAgIGNvbnN0IGluZGljZXNZID0gbmV3IEFycmF5KGRpbXMubGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNpemU7IGkrKykge1xuICAgICAgY29uc3QgaW5kaWNlcyA9IFNoYXBlVXRpbC5vZmZzZXRUb0luZGljZXMoaSwgc3RyaWRlcyk7XG4gICAgICAvLyBtYXAgaW5kZXhcbiAgICAgIEJyb2FkY2FzdFV0aWwuZmlsbEluZGV4KGluZGljZXMsIGRpbXMsIGluZGljZXNZKTtcbiAgICAgIHkuc2V0KFxuICAgICAgICBpbmRpY2VzLFxuICAgICAgICBSZWR1Y2VVdGlsLmNhbGNSZWR1Y2VCeUF4aXMoXG4gICAgICAgICAgYS5udW1iZXJEYXRhLFxuICAgICAgICAgIGF4ZXMsXG4gICAgICAgICAgZGltcyxcbiAgICAgICAgICAwLFxuICAgICAgICAgIFNoYXBlVXRpbC5pbmRpY2VzVG9PZmZzZXQoaW5kaWNlc1ksIGlucHV0U3RyaWRlcyksXG4gICAgICAgICAgb3AxLFxuICAgICAgICAgIG9wMixcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGtlZXBkaW1zKSB7XG4gICAgICByZXR1cm4geTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8ga2VlcGRpbXMgPT0gMCwgY2FsY3VsYXRlIHRoZSBleHBlY3RlZCBzaGFwZVxuICAgICAgcmV0dXJuIG5ldyBUZW5zb3IoXG4gICAgICAgIFJlZHVjZVV0aWwuY2FsY1JlZHVjZVNoYXBlKGRpbXMsIGF4ZXMsIGtlZXBkaW1zKSxcbiAgICAgICAgeS50eXBlLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgeS5kYXRhLFxuICAgICAgICB5LmRhdGFJZCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gcmVkdWNlIG9wZXJhdGlvbnMgb24gdGhlIHNwZWNpZmljIG9wZXJhdG9yIG9uIHNwZWNpZmljIGF4ZXNcbiAgICogQHBhcmFtIGEgSW5wdXQgdGVuc29yIGRhdGFcbiAgICogQHBhcmFtIGF4ZXMgVGhlIGRpbWVuc2lvbnMgYWxvbmcgd2hpY2ggdGhlIFRlbnNvciB3aWxsIGJlIHJlZHVjZWRcbiAgICogQHBhcmFtIGRpbXMgVGhlIGlucHV0IGRpbWVuc2lvbi5cbiAgICogQHBhcmFtIGN1ckF4aXNJbmQgSW5kZXggaW4gYXhlcyBzcGVjaWZ5aW5nIHRoZSBjdXJyZW50IGRpbWVuc2lvbiBhbG9uZ1xuICAgKiAgICAgIHdoaWNoIHRoZSB0ZW5zb3Igd2lsbCBiZSByZWR1Y2VkXG4gICAqIEBwYXJhbSBwb3MgVGhlIGN1cnJlbnQgaW5kZXggb2YgZWxlbWVudCB0byBwZXJmb3JtIG9wZXJhdGlvblxuICAgKiBAcGFyYW0gb3AxIFRoZSBvcGVyYXRpb24gdG8gYmUgcGVyZm9ybWVkIG9uIGVhY2ggZWxlbWVudCBpbiB0aGUgdGVuc29yXG4gICAqIEBwYXJhbSBvcDIgVGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgYmV0d2VlbiBlbGVtZW50cyBpbiB0aGUgdGVuc29yXG4gICAqL1xuICBzdGF0aWMgY2FsY1JlZHVjZUJ5QXhpcyhcbiAgICBpbnB1dDogVGVuc29yLk51bWJlclR5cGUsXG4gICAgYXhlczogbnVtYmVyW10sXG4gICAgZGltczogbnVtYmVyW10sXG4gICAgY3VyQXhpc0luZDogbnVtYmVyLFxuICAgIHBvczogbnVtYmVyLFxuICAgIG9wMTogKGI6IG51bWJlcikgPT4gbnVtYmVyLFxuICAgIG9wMjogKGE6IG51bWJlciwgYjogbnVtYmVyKSA9PiBudW1iZXIsXG4gICk6IG51bWJlciB7XG4gICAgbGV0IHJlcyA9IDA7XG4gICAgaWYgKGN1ckF4aXNJbmQgPj0gYXhlcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBvcDEoaW5wdXRbcG9zXSk7XG4gICAgfVxuICAgIGNvbnN0IGF4aXMgPSBheGVzW2N1ckF4aXNJbmRdO1xuICAgIGNvbnN0IHN0ZXAgPSBheGlzID49IGRpbXMubGVuZ3RoID8gMSA6IFNoYXBlVXRpbC5zaXplKGRpbXMuc2xpY2UoYXhpcyArIDEpKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbXNbYXhpc107IGkrKykge1xuICAgICAgcmVzID1cbiAgICAgICAgaSA9PT0gMFxuICAgICAgICAgID8gUmVkdWNlVXRpbC5jYWxjUmVkdWNlQnlBeGlzKGlucHV0LCBheGVzLCBkaW1zLCBjdXJBeGlzSW5kICsgMSwgcG9zLCBvcDEsIG9wMilcbiAgICAgICAgICA6IG9wMihyZXMsIFJlZHVjZVV0aWwuY2FsY1JlZHVjZUJ5QXhpcyhpbnB1dCwgYXhlcywgZGltcywgY3VyQXhpc0luZCArIDEsIHBvcywgb3AxLCBvcDIpKTtcbiAgICAgIHBvcyArPSBzdGVwO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSB0aGUgZXhwZWN0ZWQgc2hhcGUgb2YgYSByZWR1Y2Ugb3BlcmF0aW9uXG4gICAqIEBwYXJhbSBkaW1zIFRoZSBpbnB1dCB0ZW5zb3IgZGltZW5zaW9uXG4gICAqIEBwYXJhbSBheGVzIFRoZSBkaW1lbnNpb25zIGFsb25nIHdoaWNoIHRoZSBUZW5zb3Igd2lsbCBiZSByZWR1Y2VkXG4gICAqIEBwYXJhbSBrZWVwZGltcyBJZiBzZXQgdG8gdHJ1ZSwgdGhlIGF4ZXMgd2hpY2ggYXJlIHJlZHVjZWQgYXJlIGxlZnQgaW4gdGhlXG4gICAqICAgIHJlc3VsdCBhcyBkaW1lbnNpb25zIHdpdGggc2l6ZSBvbmUuXG4gICAqL1xuICBzdGF0aWMgY2FsY1JlZHVjZVNoYXBlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGVzOiByZWFkb25seSBudW1iZXJbXSwga2VlcERpbXM6IGJvb2xlYW4pOiBudW1iZXJbXSB7XG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IGRpbXMuc2xpY2UoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF4ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChrZWVwRGltcykge1xuICAgICAgICBvdXRwdXREaW1zW2F4ZXNbaV1dID0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG91dHB1dERpbXNbYXhlc1tpXV0gPSAwO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0RGltcy5maWx0ZXIoKGRpbSkgPT4gZGltICE9PSAwKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUG9vbENvbnZVdGlsIHtcbiAgLyoqXG4gICAqIEFkanVzdCB0aGUga2VybmVsLCBzdHJpZGVzLCBwYWRzIHRvIGNvcnJlY3QgcmFuay4gU2V0IHRvIGRlZmF1bHQgdmFsdWUgaWYgbm90IHByZXNlbnRcbiAgICogQHBhcmFtIGlzR2xvYmFsT3BlcmF0b3IgSWYgdHJ1ZSwgcGVyZm9ybSBnbG9iYWwgcG9vbGluZy5cbiAgICogQHBhcmFtIGlucHV0RGltcyBUaGUgaW5wdXQgdGVuc29yIGRpbWVuc2lvbi5cbiAgICogQHBhcmFtIGtlcm5lbFNoYXBlIFRoZSBzaXplIG9mIHRoZSBrZXJuZWwgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gc3RyaWRlcyBTdHJpZGUgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gZGlsYXRpb25zIERpbGF0aW9uIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIHBhZHMgUGFkZGluZyBmb3IgdGhlIGJlZ2lubmluZyBhbmQgZW5kaW5nIGFsb25nIGVhY2ggYXhpcy5cbiAgICovXG4gIHN0YXRpYyBhZGp1c3RQb29sQXR0cmlidXRlcyhcbiAgICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAga2VybmVsU2hhcGU6IG51bWJlcltdLFxuICAgIHN0cmlkZXM6IG51bWJlcltdLFxuICAgIGRpbGF0aW9uczogbnVtYmVyW10sXG4gICAgcGFkczogbnVtYmVyW10sXG4gICkge1xuICAgIGlmICghaXNHbG9iYWxPcGVyYXRvciAmJiBrZXJuZWxTaGFwZS5sZW5ndGggIT09IGlucHV0RGltcy5sZW5ndGggLSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2xlbmd0aCBvZiBzcGVjaWZpZWQga2VybmVsIHNoYXBlcyBzaG91bGQgYmUgMiBsZXNzIHRoYW4gbGVuZ3RoIG9mIGlucHV0IGRpbWVuc2lvbnMnKTtcbiAgICB9XG5cbiAgICBpZiAoaXNHbG9iYWxPcGVyYXRvcikge1xuICAgICAgLy8gYWRqdXN0IGtlcm5lbCBzaGFwZSB0byBjb3ZlciB0aGUgaW5wdXQgZGltc1xuICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgaW5wdXREaW1zLmxlbmd0aCAtIDI7IGRpbSsrKSB7XG4gICAgICAgIGlmIChkaW0gPj0ga2VybmVsU2hhcGUubGVuZ3RoKSB7XG4gICAgICAgICAga2VybmVsU2hhcGUucHVzaChpbnB1dERpbXNbZGltICsgMl0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGtlcm5lbFNoYXBlW2RpbV0gPSBpbnB1dERpbXNbZGltICsgMl07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhZGp1c3Qgc3RyaWRlcyBsZW5ndGggdG8gbWF0Y2gga2VybmVsIHNoYXBlIGxlbmd0aFxuICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGtlcm5lbFNoYXBlLmxlbmd0aDsgZGltKyspIHtcbiAgICAgIGlmIChkaW0gPCBzdHJpZGVzLmxlbmd0aCkge1xuICAgICAgICBpZiAoc3RyaWRlc1tkaW1dIDwgMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignc3RyaWRlcyBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEnKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyaWRlcy5wdXNoKDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkanVzdCBkaWxhdGlvbiB2YWx1ZVxuICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGtlcm5lbFNoYXBlLmxlbmd0aDsgZGltKyspIHtcbiAgICAgIGlmIChkaW0gPCBkaWxhdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgIGlmIChkaWxhdGlvbnNbZGltXSA8IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RpbGF0aW9ucyBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEnKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGlsYXRpb25zLnB1c2goMSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYWRqdXN0IHBhZHMgbGVuZ3RoIHRvIG1hdGNoIDIgKiBrZXJuZWwgc2hhcGUgbGVuZ3RoXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwga2VybmVsU2hhcGUubGVuZ3RoICogMjsgZGltKyspIHtcbiAgICAgIGlmIChkaW0gPCBwYWRzLmxlbmd0aCkge1xuICAgICAgICBpZiAocGFkc1tkaW1dIDwgMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcigncGFkIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYWRzLnB1c2goMCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2FuaXR5IGNoZWNrcyBmb3IgdmFsdWVzIGluIGtlcm5lbCBzaGFwZXMgYW5kIHBhZHNcbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBrZXJuZWxTaGFwZS5sZW5ndGg7IGRpbSsrKSB7XG4gICAgICBpZiAoa2VybmVsU2hhcGVbZGltXSA8PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigna2VybmVsIHNoYXBlcyBuZWVkIHRvIGJlIGdyZWF0ZXIgdGhhbiAwJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYWRzW2RpbV0gPj0ga2VybmVsU2hhcGVbZGltXSB8fCBwYWRzW2RpbSArIGtlcm5lbFNoYXBlLmxlbmd0aF0gPj0ga2VybmVsU2hhcGVbZGltXSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhZHMgc2hvdWxkIGJlIHNtYWxsZXIgdGhhbiBrZXJuZWwnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBhZGp1c3QgcGFkIHZhbHVlcyBiYXNlZCBvbiAnYXV0b1BhZCcgYXR0cmlidXRlXG4gIHN0YXRpYyBhZGp1c3RQYWRzQmFzZWRPbkF1dG9QYWQoXG4gICAgaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBwYWRzOiBudW1iZXJbXSxcbiAgICBhdXRvUGFkPzogc3RyaW5nLFxuICApIHtcbiAgICBpZiAoIWF1dG9QYWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocGFkcy5sZW5ndGggIT09IDIgKiAoaW5wdXREaW1zLmxlbmd0aCAtIDIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2xlbmd0aCBvZiBwYWRzIHNob3VsZCBiZSB0d2ljZSB0aGUgbGVuZ3RoIG9mIGRhdGEgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGlmIChzdHJpZGVzLmxlbmd0aCAhPT0gaW5wdXREaW1zLmxlbmd0aCAtIDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIHN0cmlkZXMgc2hvdWxkIGJlIHRoZSBsZW5ndGggb2YgZGF0YSBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgaWYgKGtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXREaW1zLmxlbmd0aCAtIDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIGtlcm5lbCBzaGFwZXMgc2hvdWxkIGJlIHRoZSBsZW5ndGggb2YgZGF0YSBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgaW5wdXREaW1zLmxlbmd0aCAtIDI7IGRpbSsrKSB7XG4gICAgICBQb29sQ29udlV0aWwuYWRqdXN0UGFkQW5kUmV0dXJuU2hhcGUoXG4gICAgICAgIGlucHV0RGltc1tkaW0gKyAyXSxcbiAgICAgICAgc3RyaWRlc1tkaW1dLFxuICAgICAgICBkaWxhdGlvbnNbZGltXSxcbiAgICAgICAga2VybmVsU2hhcGVbZGltXSxcbiAgICAgICAgcGFkcyxcbiAgICAgICAgZGltLFxuICAgICAgICBkaW0gKyBpbnB1dERpbXMubGVuZ3RoIC0gMixcbiAgICAgICAgYXV0b1BhZCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSB0aGUgb3V0cHV0IHNoYXBlIGZvciBQb29sIG9wcyBiYXNlZCBvbiBpbnB1dCBhdHRyaWJ1dGVzLiAoU2hvdWxkIGJlIHVzZWQgb25seSBmb3IgUG9vbCBvcHMpXG4gICAqIEBwYXJhbSBpc0dsb2JhbE9wZXJhdG9yIElmIHRydWUsIHBlcmZvcm0gZ2xvYmFsIHBvb2xpbmcuXG4gICAqIEBwYXJhbSBpbnB1dERpbXMgVGhlIGlucHV0IHRlbnNvciBkaW1lbnNpb24uIChpbnB1dHNbMF0uZGltcylcbiAgICogQHBhcmFtIHN0cmlkZXMgU3RyaWRlIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGRpbGF0aW9ucyBEaWxhdGlvbiBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBrZXJuZWxTaGFwZSBUaGUgc2l6ZSBvZiB0aGUga2VybmVsIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIHBhZHMgUGFkZGluZyBmb3IgdGhlIGJlZ2lubmluZyBhbmQgZW5kaW5nIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGF1dG9QYWQgREVQUkVDQVRFRCBhdHRyaWJ1dGUgc3VwcG9ydGVkIGZvciBsZWdhY3kgbW9kZWxzLiBTcGVjaWZpZXMgaG93IHRvIGltcGxpY2l0bHkgY2FsY3VsYXRlIHBhZHMgaW4gZWFjaFxuICAgKiAgICAgZGltZW5zaW9uLiBDYW4gdGFrZSB2YWx1ZXMgTk9UU0VULCBTQU1FX1VQUEVSLCBTQU1FX0xPV0VSLCBvciBWQUxJRC5cbiAgICovXG4gIHN0YXRpYyBjb21wdXRlUG9vbE91dHB1dFNoYXBlKFxuICAgIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4gICAgaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBzdHJpZGVzOiBudW1iZXJbXSxcbiAgICBkaWxhdGlvbnM6IG51bWJlcltdLFxuICAgIGtlcm5lbFNoYXBlOiBudW1iZXJbXSxcbiAgICBwYWRzOiBudW1iZXJbXSxcbiAgICBhdXRvUGFkPzogc3RyaW5nLFxuICApOiBudW1iZXJbXSB7XG4gICAgaWYgKGlucHV0RGltcy5sZW5ndGggPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCBzaGFwZSBtdXN0IGJlIG9mIHNpemUgZ3JlYXRlciB0aGFuIDAnKTtcbiAgICB9XG5cbiAgICAvLyBBZGQgYmF0Y2ggc2l6ZSBhbmQgbnVtYmVyIG9mIGNoYW5uZWxzIG9mIG91dHB1dFxuICAgIGNvbnN0IG91dHB1dERpbXMgPSBbaW5wdXREaW1zWzBdLCBpbnB1dERpbXNbMV1dO1xuXG4gICAgUG9vbENvbnZVdGlsLmNvbXB1dGVTaGFwZUhlbHBlcihcbiAgICAgIGlzR2xvYmFsT3BlcmF0b3IsXG4gICAgICBpbnB1dERpbXMsXG4gICAgICBvdXRwdXREaW1zLFxuICAgICAgc3RyaWRlcyxcbiAgICAgIGRpbGF0aW9ucyxcbiAgICAgIGtlcm5lbFNoYXBlLFxuICAgICAgcGFkcyxcbiAgICAgIGF1dG9QYWQsXG4gICAgKTtcbiAgICByZXR1cm4gb3V0cHV0RGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIG91dHB1dCBzaGFwZSBmb3IgQ29udiBvcCBiYXNlZCBvbiBpbnB1dCBhdHRyaWJ1dGVzLiAoU2hvdWxkIGJlIHVzZWQgb25seSBmb3IgQ29udiBvcClcbiAgICogQHBhcmFtIGlucHV0RGltcyBUaGUgaW5wdXQgdGVuc29yIGRpbWVuc2lvbi4gKGlucHV0c1swXS5kaW1zKVxuICAgKiBAcGFyYW0gZmlsdGVyRGltcyBUaGUgZmlsdGVyIHRlbnNvciBkaW1lbnNpb24uIChpbnB1dHNbMV0uZGltcylcbiAgICogQHBhcmFtIHN0cmlkZXMgU3RyaWRlIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGtlcm5lbFNoYXBlIFRoZSBzaXplIG9mIHRoZSBrZXJuZWwgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gcGFkcyBQYWRkaW5nIGZvciB0aGUgYmVnaW5uaW5nIGFuZCBlbmRpbmcgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gYXV0b1BhZCBERVBSRUNBVEVEIGF0dHJpYnV0ZSBzdXBwb3J0ZWQgZm9yIGxlZ2FjeSBtb2RlbHMuIFNwZWNpZmllcyBob3cgdG8gaW1wbGljaXRseSBjYWxjdWxhdGUgcGFkcyBpbiBlYWNoXG4gICAqICAgICBkaW1lbnNpb24uIENhbiB0YWtlIHZhbHVlcyBOT1RTRVQsIFNBTUVfVVBQRVIsIFNBTUVfTE9XRVIsIG9yIFZBTElELlxuICAgKi9cbiAgc3RhdGljIGNvbXB1dGVDb252T3V0cHV0U2hhcGUoXG4gICAgaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBmaWx0ZXJEaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBzdHJpZGVzOiBudW1iZXJbXSxcbiAgICBkaWxhdGlvbnM6IG51bWJlcltdLFxuICAgIGtlcm5lbFNoYXBlOiBudW1iZXJbXSxcbiAgICBwYWRzOiBudW1iZXJbXSxcbiAgICBhdXRvUGFkPzogc3RyaW5nLFxuICApOiBudW1iZXJbXSB7XG4gICAgaWYgKGlucHV0RGltcy5sZW5ndGggPD0gMCB8fCBmaWx0ZXJEaW1zLmxlbmd0aCA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQgdGVuc29yIGRpbXMgb3IgaW52YWxpZCBmaWx0ZXIgdGVuc29yIGRpbXMnKTtcbiAgICB9XG5cbiAgICAvLyBBZGQgYmF0Y2ggc2l6ZSBhbmQgbnVtYmVyIG9mIGNoYW5uZWxzIG9mIG91dHB1dFxuICAgIGNvbnN0IG91dHB1dERpbXMgPSBbaW5wdXREaW1zWzBdLCBmaWx0ZXJEaW1zWzBdXTtcblxuICAgIFBvb2xDb252VXRpbC5jb21wdXRlU2hhcGVIZWxwZXIoZmFsc2UsIGlucHV0RGltcywgb3V0cHV0RGltcywgc3RyaWRlcywgZGlsYXRpb25zLCBrZXJuZWxTaGFwZSwgcGFkcywgYXV0b1BhZCk7XG4gICAgcmV0dXJuIG91dHB1dERpbXM7XG4gIH1cblxuICAvLyB3aWxsIGNvbXB1dGUgb3V0cHV0IHNoYXBlcyBmb3IgZGF0YSBkaW1lbnNpb25zIE9OTFkgKGkuZS4pIG5vIGJhdGNoIHNpemUgYW5kIGNoYW5uZWxzXG4gIC8vIGNhbGxlZCBieSBjb21wdXRlUG9vbE91dHB1dFNoYXBlKCkgYW5kIGNvbXB1dGVDb252T3V0cHV0U2hhcGUoKVxuICAvLyBhZGp1c3QgcGFkcyBiYXNlZCBvbiAnYXV0b1BhZCcgYXR0cmlidXRlIHByaW9yIHRvIHNoYXBlIGNvbXB1dGF0aW9uXG4gIHByaXZhdGUgc3RhdGljIGNvbXB1dGVTaGFwZUhlbHBlcihcbiAgICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgb3V0cHV0RGltczogbnVtYmVyW10sXG4gICAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgYXV0b1BhZD86IHN0cmluZyxcbiAgKSB7XG4gICAgaWYgKGlzR2xvYmFsT3BlcmF0b3IpIHtcbiAgICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGlucHV0RGltcy5sZW5ndGggLSAyOyBkaW0rKykge1xuICAgICAgICBvdXRwdXREaW1zLnB1c2goMSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGlucHV0RGltcy5sZW5ndGggLSAyOyBkaW0rKykge1xuICAgICAgICBvdXRwdXREaW1zLnB1c2goXG4gICAgICAgICAgUG9vbENvbnZVdGlsLmFkanVzdFBhZEFuZFJldHVyblNoYXBlKFxuICAgICAgICAgICAgaW5wdXREaW1zW2RpbSArIDJdLFxuICAgICAgICAgICAgc3RyaWRlc1tkaW1dLFxuICAgICAgICAgICAgZGlsYXRpb25zW2RpbV0sXG4gICAgICAgICAgICBrZXJuZWxTaGFwZVtkaW1dLFxuICAgICAgICAgICAgcGFkcyxcbiAgICAgICAgICAgIGRpbSxcbiAgICAgICAgICAgIGRpbSArIGlucHV0RGltcy5sZW5ndGggLSAyLFxuICAgICAgICAgICAgYXV0b1BhZCxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGhlbHBlciBmb3IgY29tcHV0ZVNoYXBlSGVscGVyKCkgYW5kIGFkanVzdFBhZHNCYXNlZE9uQXV0b1BhZCgpXG4gIC8vIGFkanVzdHMgcGFkIHZhbHVlIGZvciBnaXZlbiAnYXV0b1BhZCcgc3RyaW5nIGFuZCBjb21wdXRlcyBvdXRwdXQgc2hhcGUgYWxvbmcgYSBwYXJ0aWN1bGFyIGRpbWVuc2lvblxuICBwcml2YXRlIHN0YXRpYyBhZGp1c3RQYWRBbmRSZXR1cm5TaGFwZShcbiAgICBpblNpemU6IG51bWJlcixcbiAgICBzdHJpZGU6IG51bWJlcixcbiAgICBkaWxhdGlvbjogbnVtYmVyLFxuICAgIGtlcm5lbDogbnVtYmVyLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICAgIHBhZEhlYWRJbmRleDogbnVtYmVyLFxuICAgIHBhZFRhaWxJbmRleDogbnVtYmVyLFxuICAgIGF1dG9QYWQ/OiBzdHJpbmcsXG4gICk6IG51bWJlciB7XG4gICAgY29uc3QgZGtlcm5lbCA9IGRpbGF0aW9uICogKGtlcm5lbCAtIDEpICsgMTtcbiAgICBpZiAoYXV0b1BhZCAmJiBhdXRvUGFkICE9PSAnTk9UU0VUJykge1xuICAgICAgc3dpdGNoIChhdXRvUGFkKSB7XG4gICAgICAgIGNhc2UgJ1ZBTElEJzpcbiAgICAgICAgICBwYWRzW3BhZEhlYWRJbmRleF0gPSAwO1xuICAgICAgICAgIHBhZHNbcGFkVGFpbEluZGV4XSA9IDA7XG4gICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKGluU2l6ZSAtIGRrZXJuZWwpIC8gc3RyaWRlICsgMSk7XG4gICAgICAgIGNhc2UgJ1NBTUVfTE9XRVInOlxuICAgICAgICBjYXNlICdTQU1FX1VQUEVSJzpcbiAgICAgICAgICBpZiAoZGlsYXRpb24gIT09IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRGlsYXRpb24gbm90IHN1cHBvcnRlZCBmb3IgU0FNRV9VUFBFUiBvciBTQU1FX0xPV0VSJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGxlZ2FjeVRhcmdldFNpemUgPSAoaW5TaXplICsgc3RyaWRlIC0gMSkgLyBzdHJpZGU7XG4gICAgICAgICAgICBjb25zdCBwYWROZWVkZWQgPSAobGVnYWN5VGFyZ2V0U2l6ZSAtIDEpICogc3RyaWRlICsga2VybmVsIC0gaW5TaXplO1xuICAgICAgICAgICAgcGFkc1twYWRIZWFkSW5kZXhdID0gYXV0b1BhZCA9PT0gJ1NBTUVfTE9XRVInID8gTWF0aC5mbG9vcigocGFkTmVlZGVkICsgMSkgLyAyKSA6IE1hdGguZmxvb3IocGFkTmVlZGVkIC8gMik7XG4gICAgICAgICAgICBwYWRzW3BhZFRhaWxJbmRleF0gPSBwYWROZWVkZWQgLSBwYWRzW3BhZEhlYWRJbmRleF07XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5mbG9vcigoaW5TaXplICsgcGFkTmVlZGVkIC0ga2VybmVsKSAvIHN0cmlkZSArIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIEF1dG9QYWQgdHlwZScpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gTWF0aC5mbG9vcigoaW5TaXplICsgcGFkc1twYWRIZWFkSW5kZXhdICsgcGFkc1twYWRUYWlsSW5kZXhdIC0gZGtlcm5lbCkgLyBzdHJpZGUgKyAxKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IE1JTl9DTElQID0gLTMuNDAyODIzNDY2Mzg1Mjg4NmUzODtcbmV4cG9ydCBjb25zdCBNQVhfQ0xJUCA9IDMuNDAyODIzNDY2Mzg1Mjg4NmUzODtcblxuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZVV0ZjhTdHJpbmcoYnVmZmVyOiBVaW50OEFycmF5KTogc3RyaW5nIHtcbiAgcmV0dXJuIG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShidWZmZXIpO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHdWlkIH0gZnJvbSAnZ3VpZC10eXBlc2NyaXB0JztcbmltcG9ydCBMb25nIGZyb20gJ2xvbmcnO1xuXG5pbXBvcnQgKiBhcyBvcnRGYnMgZnJvbSAnLi9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ydC1nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgb25ueCB9IGZyb20gJy4vb3J0LXNjaGVtYS9wcm90b2J1Zi9vbm54JztcbmltcG9ydCB7IGRlY29kZVV0ZjhTdHJpbmcsIFByb3RvVXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi91dGlsJztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIFRlbnNvciB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgRGF0YVR5cGVNYXAge1xuICAgIGJvb2w6IFVpbnQ4QXJyYXk7XG4gICAgZmxvYXQzMjogRmxvYXQzMkFycmF5O1xuICAgIGZsb2F0NjQ6IEZsb2F0NjRBcnJheTtcbiAgICBzdHJpbmc6IHN0cmluZ1tdO1xuICAgIGludDg6IEludDhBcnJheTtcbiAgICB1aW50ODogVWludDhBcnJheTtcbiAgICBpbnQxNjogSW50MTZBcnJheTtcbiAgICB1aW50MTY6IFVpbnQxNkFycmF5O1xuICAgIGludDMyOiBJbnQzMkFycmF5O1xuICAgIHVpbnQzMjogVWludDMyQXJyYXk7XG4gICAgaW50NjQ6IEJpZ0ludDY0QXJyYXk7XG4gIH1cblxuICBleHBvcnQgdHlwZSBEYXRhVHlwZSA9IGtleW9mIERhdGFUeXBlTWFwO1xuXG4gIGV4cG9ydCB0eXBlIFN0cmluZ1R5cGUgPSBUZW5zb3IuRGF0YVR5cGVNYXBbJ3N0cmluZyddO1xuICBleHBvcnQgdHlwZSBCb29sZWFuVHlwZSA9IFRlbnNvci5EYXRhVHlwZU1hcFsnYm9vbCddO1xuICBleHBvcnQgdHlwZSBJbnRlZ2VyVHlwZSA9XG4gICAgfCBUZW5zb3IuRGF0YVR5cGVNYXBbJ2ludDgnXVxuICAgIHwgVGVuc29yLkRhdGFUeXBlTWFwWyd1aW50OCddXG4gICAgfCBUZW5zb3IuRGF0YVR5cGVNYXBbJ2ludDE2J11cbiAgICB8IFRlbnNvci5EYXRhVHlwZU1hcFsndWludDE2J11cbiAgICB8IFRlbnNvci5EYXRhVHlwZU1hcFsnaW50MzInXVxuICAgIHwgVGVuc29yLkRhdGFUeXBlTWFwWyd1aW50MzInXTtcbiAgZXhwb3J0IHR5cGUgRmxvYXRUeXBlID0gVGVuc29yLkRhdGFUeXBlTWFwWydmbG9hdDMyJ10gfCBUZW5zb3IuRGF0YVR5cGVNYXBbJ2Zsb2F0NjQnXTtcbiAgZXhwb3J0IHR5cGUgTnVtYmVyVHlwZSA9IEJvb2xlYW5UeXBlIHwgSW50ZWdlclR5cGUgfCBGbG9hdFR5cGU7XG5cbiAgZXhwb3J0IHR5cGUgSWQgPSBHdWlkO1xufVxuXG50eXBlIFRlbnNvckRhdGEgPSBUZW5zb3IuRGF0YVR5cGVNYXBbVGVuc29yLkRhdGFUeXBlXTtcblxudHlwZSBEYXRhUHJvdmlkZXIgPSAoaWQ6IFRlbnNvci5JZCkgPT4gVGVuc29yRGF0YTtcbnR5cGUgQXN5bmNEYXRhUHJvdmlkZXIgPSAoaWQ6IFRlbnNvci5JZCkgPT4gUHJvbWlzZTxUZW5zb3JEYXRhPjtcblxuZXhwb3J0IGNsYXNzIFRlbnNvciB7XG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgdGVuc29yIGRhdGFcbiAgICovXG4gIGdldCBkYXRhKCk6IFRlbnNvckRhdGEge1xuICAgIGlmICh0aGlzLmNhY2hlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGFQcm92aWRlciEodGhpcy5kYXRhSWQpO1xuICAgICAgaWYgKGRhdGEubGVuZ3RoICE9PSB0aGlzLnNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMZW5ndGggb2YgZGF0YSBwcm92aWRlZCBieSB0aGUgRGF0YSBQcm92aWRlciBpcyBpbmNvbnNpc3RlbnQgd2l0aCB0aGUgZGltcyBvZiB0aGlzIFRlbnNvci4nKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2FjaGUgPSBkYXRhO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgc3RyaW5nIHRlbnNvciBkYXRhLiBTaG91bGQgb25seSB1c2Ugd2hlbiB0eXBlIGlzIFNUUklOR1xuICAgKi9cbiAgZ2V0IHN0cmluZ0RhdGEoKSB7XG4gICAgaWYgKHRoaXMudHlwZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2RhdGEgdHlwZSBpcyBub3Qgc3RyaW5nJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZGF0YSBhcyBUZW5zb3IuU3RyaW5nVHlwZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgaW50ZWdlciB0ZW5zb3IgZGF0YS4gU2hvdWxkIG9ubHkgdXNlIHdoZW4gdHlwZSBpcyBvbmUgb2YgdGhlIGZvbGxvd2luZzogKFVJTlQ4LCBJTlQ4LCBVSU5UMTYsXG4gICAqIElOVDE2LCBJTlQzMiwgVUlOVDMyLCBCT09MKVxuICAgKi9cbiAgZ2V0IGludGVnZXJEYXRhKCkge1xuICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICBjYXNlICdpbnQ4JzpcbiAgICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgY2FzZSAnYm9vbCc6XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEgYXMgVGVuc29yLkludGVnZXJUeXBlO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdkYXRhIHR5cGUgaXMgbm90IGludGVnZXIgKHVpbnQ4LCBpbnQ4LCB1aW50MTYsIGludDE2LCBpbnQzMiwgdWludDMyLCBib29sKScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgZmxvYXQgdGVuc29yIGRhdGEuIFNob3VsZCBvbmx5IHVzZSB3aGVuIHR5cGUgaXMgb25lIG9mIHRoZSBmb2xsb3dpbmc6IChGTE9BVCwgRE9VQkxFKVxuICAgKi9cbiAgZ2V0IGZsb2F0RGF0YSgpIHtcbiAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YSBhcyBUZW5zb3IuRmxvYXRUeXBlO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdkYXRhIHR5cGUgaXMgbm90IGZsb2F0IChmbG9hdDMyLCBmbG9hdDY0KScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgbnVtYmVyIHRlbnNvciBkYXRhLiBTaG91bGQgb25seSB1c2Ugd2hlbiB0eXBlIGlzIG9uZSBvZiB0aGUgZm9sbG93aW5nOiAoVUlOVDgsIElOVDgsIFVJTlQxNixcbiAgICogSU5UMTYsIElOVDMyLCBVSU5UMzIsIEJPT0wsIEZMT0FULCBET1VCTEUpXG4gICAqL1xuICBnZXQgbnVtYmVyRGF0YSgpIHtcbiAgICBpZiAodGhpcy50eXBlICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHRoaXMuZGF0YSBhcyBUZW5zb3IuTnVtYmVyVHlwZTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndHlwZSBjYW5ub3QgYmUgbm9uLW51bWJlciAoc3RyaW5nKScpO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB2YWx1ZSBvZiBhbiBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRpY2VzXG4gICAqL1xuICBnZXQoaW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3IuRGF0YVR5cGVNYXBbVGVuc29yLkRhdGFUeXBlXVtudW1iZXJdIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhW1NoYXBlVXRpbC5pbmRpY2VzVG9PZmZzZXQoaW5kaWNlcywgdGhpcy5zdHJpZGVzKV07XG4gIH1cblxuICAvKipcbiAgICogc2V0IHZhbHVlIG9mIGFuIGVsZW1lbnQgYXQgdGhlIGdpdmVuIGluZGljZXNcbiAgICovXG4gIHNldChpbmRpY2VzOiByZWFkb25seSBudW1iZXJbXSwgdmFsdWU6IFRlbnNvci5EYXRhVHlwZU1hcFtUZW5zb3IuRGF0YVR5cGVdW251bWJlcl0pIHtcbiAgICB0aGlzLmRhdGFbU2hhcGVVdGlsLmluZGljZXNUb09mZnNldChpbmRpY2VzLCB0aGlzLnN0cmlkZXMpXSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgdW5kZXJseWluZyB0ZW5zb3IgZGF0YSBhc3luY2hyb25vdXNseVxuICAgKi9cbiAgYXN5bmMgZ2V0RGF0YSgpOiBQcm9taXNlPFRlbnNvckRhdGE+IHtcbiAgICBpZiAodGhpcy5jYWNoZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmNhY2hlID0gYXdhaXQgdGhpcy5hc3luY0RhdGFQcm92aWRlciEodGhpcy5kYXRhSWQpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgdGVuc29yXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2l6ZTogbnVtYmVyO1xuXG4gIHByaXZhdGUgX3N0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICAvKipcbiAgICogZ2V0IHRoZSBzdHJpZGVzIGZvciBlYWNoIGRpbWVuc2lvblxuICAgKi9cbiAgZ2V0IHN0cmlkZXMoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmICghdGhpcy5fc3RyaWRlcykge1xuICAgICAgdGhpcy5fc3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyh0aGlzLmRpbXMpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc3RyaWRlcztcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgICAqIGdldCB0aGUgZGltZW5zaW9ucyBvZiB0aGUgdGVuc29yXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIC8qKlxuICAgICAqIGdldCB0aGUgdHlwZSBvZiB0aGUgdGVuc29yXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHR5cGU6IFRlbnNvci5EYXRhVHlwZSxcbiAgICBwcml2YXRlIGRhdGFQcm92aWRlcj86IERhdGFQcm92aWRlcixcbiAgICBwcml2YXRlIGFzeW5jRGF0YVByb3ZpZGVyPzogQXN5bmNEYXRhUHJvdmlkZXIsXG4gICAgcHJpdmF0ZSBjYWNoZT86IFRlbnNvckRhdGEsXG4gICAgLyoqXG4gICAgICogZ2V0IHRoZSBkYXRhIElEIHRoYXQgdXNlZCB0byBtYXAgdG8gYSB0ZW5zb3IgZGF0YVxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBkYXRhSWQ6IEd1aWQgPSBHdWlkLmNyZWF0ZSgpLFxuICApIHtcbiAgICB0aGlzLnNpemUgPSBTaGFwZVV0aWwudmFsaWRhdGVEaW1zQW5kQ2FsY1NpemUoZGltcyk7XG4gICAgY29uc3Qgc2l6ZSA9IHRoaXMuc2l6ZTtcbiAgICBjb25zdCBlbXB0eSA9IGRhdGFQcm92aWRlciA9PT0gdW5kZWZpbmVkICYmIGFzeW5jRGF0YVByb3ZpZGVyID09PSB1bmRlZmluZWQgJiYgY2FjaGUgPT09IHVuZGVmaW5lZDtcblxuICAgIGlmIChjYWNoZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoY2FjaGUubGVuZ3RoICE9PSBzaXplKSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW5wdXQgZGltcyBkb2Vzbid0IG1hdGNoIGRhdGEgbGVuZ3RoLlwiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmIChjYWNoZSAhPT0gdW5kZWZpbmVkICYmICghQXJyYXkuaXNBcnJheShjYWNoZSkgfHwgIWNhY2hlLmV2ZXJ5KChpKSA9PiB0eXBlb2YgaSA9PT0gJ3N0cmluZycpKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdjYWNoZSBzaG91bGQgYmUgYSBzdHJpbmcgYXJyYXknKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVtcHR5KSB7XG4gICAgICAgIHRoaXMuY2FjaGUgPSBuZXcgQXJyYXk8c3RyaW5nPihzaXplKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGNhY2hlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgY29uc3RydWN0b3IgPSBkYXRhdmlld0NvbnN0cnVjdG9yKHR5cGUpO1xuICAgICAgICBpZiAoIShjYWNoZSBpbnN0YW5jZW9mIGNvbnN0cnVjdG9yKSkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYGNhY2hlIHNob3VsZCBiZSB0eXBlICR7Y29uc3RydWN0b3IubmFtZX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZW1wdHkpIHtcbiAgICAgICAgY29uc3QgYnVmID0gbmV3IEFycmF5QnVmZmVyKHNpemUgKiBzaXplb2YodHlwZSkpO1xuICAgICAgICB0aGlzLmNhY2hlID0gY3JlYXRlVmlldyhidWYsIHR5cGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgbmV3IFRlbnNvciBmcm9tIGEgT05OWCBUZW5zb3Igb2JqZWN0XG4gICAqIEBwYXJhbSB0ZW5zb3JQcm90byB0aGUgT05OWCBUZW5zb3JcbiAgICovXG4gIHN0YXRpYyBmcm9tUHJvdG8odGVuc29yUHJvdG86IG9ubnguSVRlbnNvclByb3RvKTogVGVuc29yIHtcbiAgICBpZiAoIXRlbnNvclByb3RvKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBjb25zdHJ1Y3QgVmFsdWUgZnJvbSBhbiBlbXB0eSB0ZW5zb3InKTtcbiAgICB9XG4gICAgY29uc3QgdHlwZSA9IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byh0ZW5zb3JQcm90by5kYXRhVHlwZSEpO1xuICAgIGNvbnN0IGRpbXMgPSBQcm90b1V0aWwudGVuc29yRGltc0Zyb21Qcm90byh0ZW5zb3JQcm90by5kaW1zISk7XG5cbiAgICBjb25zdCB2YWx1ZSA9IG5ldyBUZW5zb3IoZGltcywgdHlwZSk7XG5cbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIFdoZW4gaXQncyBTVFJJTkcgdHlwZSwgdGhlIHZhbHVlIHNob3VsZCBhbHdheXMgYmUgc3RvcmVkIGluIGZpZWxkXG4gICAgICAvLyAnc3RyaW5nRGF0YSdcbiAgICAgIHRlbnNvclByb3RvLnN0cmluZ0RhdGEhLmZvckVhY2goKHN0ciwgaSkgPT4ge1xuICAgICAgICB2YWx1ZS5kYXRhW2ldID0gZGVjb2RlVXRmOFN0cmluZyhzdHIpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHRlbnNvclByb3RvLnJhd0RhdGEgJiZcbiAgICAgIHR5cGVvZiB0ZW5zb3JQcm90by5yYXdEYXRhLmJ5dGVMZW5ndGggPT09ICdudW1iZXInICYmXG4gICAgICB0ZW5zb3JQcm90by5yYXdEYXRhLmJ5dGVMZW5ndGggPiAwXG4gICAgKSB7XG4gICAgICAvLyBOT1QgY29uc2lkZXJpbmcgc2VnbWVudCBmb3Igbm93IChJTVBPUlRBTlQpXG5cbiAgICAgIC8vIHBvcHVsYXRlIHZhbHVlIGZyb20gcmF3RGF0YVxuICAgICAgY29uc3QgZGF0YURlc3QgPSB2YWx1ZS5kYXRhO1xuICAgICAgY29uc3QgZGF0YVNvdXJjZSA9IG5ldyBEYXRhVmlldyhcbiAgICAgICAgdGVuc29yUHJvdG8ucmF3RGF0YS5idWZmZXIsXG4gICAgICAgIHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZU9mZnNldCxcbiAgICAgICAgdGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlTGVuZ3RoLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGVsZW1lbnRTaXplID0gc2l6ZW9mUHJvdG8odGVuc29yUHJvdG8uZGF0YVR5cGUhKTtcbiAgICAgIGNvbnN0IGxlbmd0aCA9IHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZUxlbmd0aCAvIGVsZW1lbnRTaXplO1xuXG4gICAgICBpZiAodGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlTGVuZ3RoICUgZWxlbWVudFNpemUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGJ1ZmZlciBsZW5ndGgnKTtcbiAgICAgIH1cbiAgICAgIGlmIChkYXRhRGVzdC5sZW5ndGggIT09IGxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2J1ZmZlciBsZW5ndGggbWlzbWF0Y2gnKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBuID0gcmVhZFByb3RvKGRhdGFTb3VyY2UsIHRlbnNvclByb3RvLmRhdGFUeXBlISwgaSAqIGVsZW1lbnRTaXplKTtcbiAgICAgICAgZGF0YURlc3RbaV0gPSBuO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBwb3B1bGF0ZSB2YWx1ZSBmcm9tIGFycmF5XG4gICAgICBsZXQgYXJyYXk6IEFycmF5PG51bWJlciB8IExvbmc+O1xuICAgICAgc3dpdGNoICh0ZW5zb3JQcm90by5kYXRhVHlwZSkge1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRkxPQVQ6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by5mbG9hdERhdGEhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMzI6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQxNjpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQxNjpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDg6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UODpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkJPT0w6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by5pbnQzMkRhdGEhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQ6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by5pbnQ2NERhdGEhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFOlxuICAgICAgICAgIGFycmF5ID0gdGVuc29yUHJvdG8uZG91YmxlRGF0YSE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzI6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQ6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by51aW50NjREYXRhITtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgcnVuIGhlcmVcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc3BlY2lmaWMgZXJyb3InKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFycmF5ID09PSBudWxsIHx8IGFycmF5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdmYWlsZWQgdG8gcG9wdWxhdGUgZGF0YSBmcm9tIGEgdGVuc29ycHJvdG8gdmFsdWUnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGF0YSA9IHZhbHVlLmRhdGE7XG4gICAgICBpZiAoZGF0YS5sZW5ndGggIT09IGFycmF5Lmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FycmF5IGxlbmd0aCBtaXNtYXRjaCcpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhcnJheVtpXTtcbiAgICAgICAgaWYgKExvbmcuaXNMb25nKGVsZW1lbnQpKSB7XG4gICAgICAgICAgZGF0YVtpXSA9IGxvbmdUb051bWJlcihlbGVtZW50LCB0ZW5zb3JQcm90by5kYXRhVHlwZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGF0YVtpXSA9IGVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0IG5ldyBUZW5zb3IgZnJvbSByYXcgZGF0YVxuICAgKiBAcGFyYW0gZGF0YSB0aGUgcmF3IGRhdGEgb2JqZWN0LiBTaG91bGQgYmUgYSBzdHJpbmcgYXJyYXkgZm9yICdzdHJpbmcnIHRlbnNvciwgYW5kIHRoZSBjb3JyZXNwb25kaW5nIHR5cGVkIGFycmF5XG4gICAqIGZvciBvdGhlciB0eXBlcyBvZiB0ZW5zb3IuXG4gICAqIEBwYXJhbSBkaW1zIHRoZSBkaW1lbnNpb25zIG9mIHRoZSB0ZW5zb3JcbiAgICogQHBhcmFtIHR5cGUgdGhlIHR5cGUgb2YgdGhlIHRlbnNvclxuICAgKi9cbiAgc3RhdGljIGZyb21EYXRhKGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFtUZW5zb3IuRGF0YVR5cGVdLCBkaW1zOiByZWFkb25seSBudW1iZXJbXSwgdHlwZTogVGVuc29yLkRhdGFUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBUZW5zb3IoZGltcywgdHlwZSwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGRhdGEpO1xuICB9XG5cbiAgc3RhdGljIGZyb21PcnRUZW5zb3Iob3J0VGVuc29yOiBvcnRGYnMuVGVuc29yKSB7XG4gICAgaWYgKCFvcnRUZW5zb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGNvbnN0cnVjdCBWYWx1ZSBmcm9tIGFuIGVtcHR5IHRlbnNvcicpO1xuICAgIH1cbiAgICBjb25zdCBkaW1zID0gUHJvdG9VdGlsLnRlbnNvckRpbXNGcm9tT1JURm9ybWF0KG9ydFRlbnNvcik7XG4gICAgY29uc3QgdHlwZSA9IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byhvcnRUZW5zb3IuZGF0YVR5cGUoKSk7XG5cbiAgICBjb25zdCB2YWx1ZSA9IG5ldyBUZW5zb3IoZGltcywgdHlwZSk7XG5cbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIFdoZW4gaXQncyBTVFJJTkcgdHlwZSwgdGhlIHZhbHVlIHNob3VsZCBhbHdheXMgYmUgc3RvcmVkIGluIGZpZWxkXG4gICAgICAvLyAnc3RyaW5nRGF0YSdcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3J0VGVuc29yLnN0cmluZ0RhdGFMZW5ndGgoKTsgaSsrKSB7XG4gICAgICAgIHZhbHVlLmRhdGFbaV0gPSBvcnRUZW5zb3Iuc3RyaW5nRGF0YShpKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKFxuICAgICAgb3J0VGVuc29yLnJhd0RhdGFBcnJheSgpICYmXG4gICAgICB0eXBlb2Ygb3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSA9PT0gJ251bWJlcicgJiZcbiAgICAgIG9ydFRlbnNvci5yYXdEYXRhTGVuZ3RoKCkgPiAwXG4gICAgKSB7XG4gICAgICAvLyBOT1QgY29uc2lkZXJpbmcgc2VnbWVudCBmb3Igbm93IChJTVBPUlRBTlQpXG5cbiAgICAgIC8vIHBvcHVsYXRlIHZhbHVlIGZyb20gcmF3RGF0YVxuICAgICAgY29uc3QgZGF0YURlc3QgPSB2YWx1ZS5kYXRhO1xuICAgICAgY29uc3QgZGF0YVNvdXJjZSA9IG5ldyBEYXRhVmlldyhcbiAgICAgICAgb3J0VGVuc29yLnJhd0RhdGFBcnJheSgpIS5idWZmZXIsXG4gICAgICAgIG9ydFRlbnNvci5yYXdEYXRhQXJyYXkoKSEuYnl0ZU9mZnNldCxcbiAgICAgICAgb3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSxcbiAgICAgICk7XG4gICAgICBjb25zdCBlbGVtZW50U2l6ZSA9IHNpemVvZlByb3RvKG9ydFRlbnNvci5kYXRhVHlwZSgpKTtcbiAgICAgIGNvbnN0IGxlbmd0aCA9IG9ydFRlbnNvci5yYXdEYXRhTGVuZ3RoKCkgLyBlbGVtZW50U2l6ZTtcblxuICAgICAgaWYgKG9ydFRlbnNvci5yYXdEYXRhTGVuZ3RoKCkgJSBlbGVtZW50U2l6ZSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYnVmZmVyIGxlbmd0aCcpO1xuICAgICAgfVxuICAgICAgaWYgKGRhdGFEZXN0Lmxlbmd0aCAhPT0gbGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYnVmZmVyIGxlbmd0aCBtaXNtYXRjaCcpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG4gPSByZWFkUHJvdG8oZGF0YVNvdXJjZSwgb3J0VGVuc29yLmRhdGFUeXBlKCksIGkgKiBlbGVtZW50U2l6ZSk7XG4gICAgICAgIGRhdGFEZXN0W2ldID0gbjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNpemVvZih0eXBlOiBUZW5zb3IuRGF0YVR5cGUpOiBudW1iZXIge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdib29sJzpcbiAgICBjYXNlICdpbnQ4JzpcbiAgICBjYXNlICd1aW50OCc6XG4gICAgICByZXR1cm4gMTtcbiAgICBjYXNlICdpbnQxNic6XG4gICAgY2FzZSAndWludDE2JzpcbiAgICAgIHJldHVybiAyO1xuICAgIGNhc2UgJ2ludDMyJzpcbiAgICBjYXNlICd1aW50MzInOlxuICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgcmV0dXJuIDQ7XG4gICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICByZXR1cm4gODtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgY2FsY3VsYXRlIHNpemVvZigpIG9uIHR5cGUgJHt0eXBlfWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNpemVvZlByb3RvKHR5cGU6IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUgfCBvcnRGYnMuVGVuc29yRGF0YVR5cGUpOiBudW1iZXIge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDg6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDg6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkJPT0w6XG4gICAgICByZXR1cm4gMTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDE2OlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQxNjpcbiAgICAgIHJldHVybiAyO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMzI6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQzMjpcbiAgICAgIHJldHVybiA0O1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ2NDpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFOlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQ6XG4gICAgICByZXR1cm4gODtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgY2FsY3VsYXRlIHNpemVvZigpIG9uIHR5cGUgJHtvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlW3R5cGVdfWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZpZXcoZGF0YUJ1ZmZlcjogQXJyYXlCdWZmZXIsIHR5cGU6IFRlbnNvci5EYXRhVHlwZSkge1xuICByZXR1cm4gbmV3IChkYXRhdmlld0NvbnN0cnVjdG9yKHR5cGUpKShkYXRhQnVmZmVyKTtcbn1cblxuZnVuY3Rpb24gZGF0YXZpZXdDb25zdHJ1Y3Rvcih0eXBlOiBUZW5zb3IuRGF0YVR5cGUpIHtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnYm9vbCc6XG4gICAgY2FzZSAndWludDgnOlxuICAgICAgcmV0dXJuIFVpbnQ4QXJyYXk7XG4gICAgY2FzZSAnaW50OCc6XG4gICAgICByZXR1cm4gSW50OEFycmF5O1xuICAgIGNhc2UgJ2ludDE2JzpcbiAgICAgIHJldHVybiBJbnQxNkFycmF5O1xuICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICByZXR1cm4gVWludDE2QXJyYXk7XG4gICAgY2FzZSAnaW50MzInOlxuICAgICAgcmV0dXJuIEludDMyQXJyYXk7XG4gICAgY2FzZSAndWludDMyJzpcbiAgICAgIHJldHVybiBVaW50MzJBcnJheTtcbiAgICBjYXNlICdpbnQ2NCc6XG4gICAgICByZXR1cm4gQmlnSW50NjRBcnJheTtcbiAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgIHJldHVybiBGbG9hdDMyQXJyYXk7XG4gICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICByZXR1cm4gRmxvYXQ2NEFycmF5O1xuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBzaG91bGQgbmV2ZXIgcnVuIHRvIGhlcmVcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5zcGVjaWZpZWQgZXJyb3InKTtcbiAgfVxufVxuXG4vLyBjb252ZXJ0IGEgbG9uZyBudW1iZXIgdG8gYSAzMi1iaXQgaW50ZWdlciAoY2FzdC1kb3duKVxuZnVuY3Rpb24gbG9uZ1RvTnVtYmVyKGk6IExvbmcsIHR5cGU6IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUgfCBvcnRGYnMuVGVuc29yRGF0YVR5cGUpOiBudW1iZXIge1xuICAvLyBJTlQ2NCwgVUlOVDMyLCBVSU5UNjRcbiAgaWYgKHR5cGUgPT09IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQgfHwgdHlwZSA9PT0gb3J0RmJzLlRlbnNvckRhdGFUeXBlLklOVDY0KSB7XG4gICAgaWYgKGkuZ3JlYXRlclRoYW5PckVxdWFsKDIxNDc0ODM2NDgpIHx8IGkubGVzc1RoYW4oLTIxNDc0ODM2NDgpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnQ2NCBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKFxuICAgIHR5cGUgPT09IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDMyIHx8XG4gICAgdHlwZSA9PT0gb3J0RmJzLlRlbnNvckRhdGFUeXBlLlVJTlQzMiB8fFxuICAgIHR5cGUgPT09IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDY0IHx8XG4gICAgdHlwZSA9PT0gb3J0RmJzLlRlbnNvckRhdGFUeXBlLlVJTlQ2NFxuICApIHtcbiAgICBpZiAoaS5ncmVhdGVyVGhhbk9yRXF1YWwoNDI5NDk2NzI5NikgfHwgaS5sZXNzVGhhbigwKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndWludDY0IGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgbm90IGEgTE9ORyB0eXBlOiAke29ubnguVGVuc29yUHJvdG8uRGF0YVR5cGVbdHlwZV19YCk7XG4gIH1cblxuICByZXR1cm4gaS50b051bWJlcigpO1xufVxuXG4vLyByZWFkIG9uZSB2YWx1ZSBmcm9tIFRlbnNvclByb3RvXG5mdW5jdGlvbiByZWFkUHJvdG8oXG4gIHZpZXc6IERhdGFWaWV3LFxuICB0eXBlOiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlIHwgb3J0RmJzLlRlbnNvckRhdGFUeXBlLFxuICBieXRlT2Zmc2V0OiBudW1iZXIsXG4pOiBudW1iZXIge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuQk9PTDpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDg6XG4gICAgICByZXR1cm4gdmlldy5nZXRVaW50OChieXRlT2Zmc2V0KTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UODpcbiAgICAgIHJldHVybiB2aWV3LmdldEludDgoYnl0ZU9mZnNldCk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQxNjpcbiAgICAgIHJldHVybiB2aWV3LmdldFVpbnQxNihieXRlT2Zmc2V0LCB0cnVlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMTY6XG4gICAgICByZXR1cm4gdmlldy5nZXRJbnQxNihieXRlT2Zmc2V0LCB0cnVlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRkxPQVQ6XG4gICAgICByZXR1cm4gdmlldy5nZXRGbG9hdDMyKGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjpcbiAgICAgIHJldHVybiB2aWV3LmdldEludDMyKGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzI6XG4gICAgICByZXR1cm4gdmlldy5nZXRVaW50MzIoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0OlxuICAgICAgcmV0dXJuIGxvbmdUb051bWJlcihcbiAgICAgICAgTG9uZy5mcm9tQml0cyh2aWV3LmdldFVpbnQzMihieXRlT2Zmc2V0LCB0cnVlKSwgdmlldy5nZXRVaW50MzIoYnl0ZU9mZnNldCArIDQsIHRydWUpLCBmYWxzZSksXG4gICAgICAgIHR5cGUsXG4gICAgICApO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5ET1VCTEU6XG4gICAgICByZXR1cm4gdmlldy5nZXRGbG9hdDY0KGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQ6XG4gICAgICByZXR1cm4gbG9uZ1RvTnVtYmVyKFxuICAgICAgICBMb25nLmZyb21CaXRzKHZpZXcuZ2V0VWludDMyKGJ5dGVPZmZzZXQsIHRydWUpLCB2aWV3LmdldFVpbnQzMihieXRlT2Zmc2V0ICsgNCwgdHJ1ZSksIHRydWUpLFxuICAgICAgICB0eXBlLFxuICAgICAgKTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgcmVhZCBmcm9tIERhdGFWaWV3IGZvciB0eXBlICR7b25ueC5UZW5zb3JQcm90by5EYXRhVHlwZVt0eXBlXX1gKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vKipcbiAqIHJlcHJlc2VudCBhIHZlcnNpb24gaXJyZWxldmFudCBhYnN0cmFjdGlvbiBvZiBmb3IgR0xTTCBzb3VyY2UgY29kZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdsc2wge1xuICByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGF0dHJpYnV0ZTogc3RyaW5nO1xuICByZWFkb25seSB2YXJ5aW5nVmVydGV4OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZhcnlpbmdGcmFnOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRleHR1cmUyRDogc3RyaW5nO1xuICByZWFkb25seSBvdXRwdXQ6IHN0cmluZztcbiAgcmVhZG9ubHkgb3V0cHV0RGVjbGFyYXRpb246IHN0cmluZztcbn1cblxuY29uc3QgR0xTTF9FU18yXzA6IEdsc2wgPSB7XG4gIHZlcnNpb246ICcnLFxuICBhdHRyaWJ1dGU6ICdhdHRyaWJ1dGUnLFxuICB2YXJ5aW5nVmVydGV4OiAndmFyeWluZycsXG4gIHZhcnlpbmdGcmFnOiAndmFyeWluZycsXG4gIHRleHR1cmUyRDogJ3RleHR1cmUyRCcsXG4gIG91dHB1dDogJ2dsX0ZyYWdDb2xvcicsXG4gIG91dHB1dERlY2xhcmF0aW9uOiAnJyxcbn07XG5jb25zdCBHTFNMX0VTXzNfMDogR2xzbCA9IHtcbiAgdmVyc2lvbjogJyN2ZXJzaW9uIDMwMCBlcycsXG4gIGF0dHJpYnV0ZTogJ2luJyxcbiAgdmFyeWluZ1ZlcnRleDogJ291dCcsXG4gIHZhcnlpbmdGcmFnOiAnaW4nLFxuICB0ZXh0dXJlMkQ6ICd0ZXh0dXJlJyxcbiAgb3V0cHV0OiAnb3V0cHV0Q29sb3InLFxuICBvdXRwdXREZWNsYXJhdGlvbjogJ291dCB2ZWM0IG91dHB1dENvbG9yOycsXG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0R2xzbCh2ZXJzaW9uOiAxIHwgMikge1xuICByZXR1cm4gdmVyc2lvbiA9PT0gMSA/IEdMU0xfRVNfMl8wIDogR0xTTF9FU18zXzA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRWZXJ0ZXhTaGFkZXJTb3VyY2UodmVyc2lvbjogMSB8IDIpOiBzdHJpbmcge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbCh2ZXJzaW9uKTtcbiAgcmV0dXJuIGAke2dsc2wudmVyc2lvbn1cbiAgICAgIHByZWNpc2lvbiBoaWdocCBmbG9hdDtcbiAgICAgICR7Z2xzbC5hdHRyaWJ1dGV9IHZlYzMgcG9zaXRpb247XG4gICAgICAke2dsc2wuYXR0cmlidXRlfSB2ZWMyIHRleHR1cmVDb29yZDtcblxuICAgICAgJHtnbHNsLnZhcnlpbmdWZXJ0ZXh9IHZlYzIgVGV4Q29vcmRzO1xuXG4gICAgICB2b2lkIG1haW4oKVxuICAgICAge1xuICAgICAgICAgIGdsX1Bvc2l0aW9uID0gdmVjNChwb3NpdGlvbiwgMS4wKTtcbiAgICAgICAgICBUZXhDb29yZHMgPSB0ZXh0dXJlQ29vcmQ7XG4gICAgICB9YDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZyYWdTaGFkZXJQcmVhbWJsZSh2ZXJzaW9uOiAxIHwgMik6IHN0cmluZyB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHZlcnNpb24pO1xuICByZXR1cm4gYCR7Z2xzbC52ZXJzaW9ufVxuICAgIHByZWNpc2lvbiBoaWdocCBmbG9hdDtcbiAgICBwcmVjaXNpb24gaGlnaHAgaW50O1xuICAgIHByZWNpc2lvbiBoaWdocCBzYW1wbGVyMkQ7XG4gICAgJHtnbHNsLnZhcnlpbmdGcmFnfSB2ZWMyIFRleENvb3JkcztcbiAgICAke2dsc2wub3V0cHV0RGVjbGFyYXRpb259XG4gICAgY29uc3QgdmVjMiBoYWxmQ1IgPSB2ZWMyKDAuNSwgMC41KTtcblxuICAgIC8vIEN1c3RvbSB2ZWN0b3IgdHlwZXMgdG8gaGFuZGxlIGhpZ2hlciBkaW1lbmFsaXRpZXMuXG4gICAgc3RydWN0IGl2ZWM1XG4gICAge1xuICAgICAgaW50IHg7XG4gICAgICBpbnQgeTtcbiAgICAgIGludCB6O1xuICAgICAgaW50IHc7XG4gICAgICBpbnQgdTtcbiAgICB9O1xuXG4gICAgc3RydWN0IGl2ZWM2XG4gICAge1xuICAgICAgaW50IHg7XG4gICAgICBpbnQgeTtcbiAgICAgIGludCB6O1xuICAgICAgaW50IHc7XG4gICAgICBpbnQgdTtcbiAgICAgIGludCB2O1xuICAgIH07XG5cbiAgICBpbnQgaW1vZChpbnQgeCwgaW50IHkpIHtcbiAgICAgIHJldHVybiB4IC0geSAqICh4IC8geSk7XG4gICAgfVxuXG4gICAgYDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERlZmF1bHRGcmFnU2hhZGVyTWFpbih2ZXJzaW9uOiAxIHwgMiwgb3V0cHV0U2hhcGVMZW5ndGg6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHZlcnNpb24pO1xuICByZXR1cm4gYFxuICB2b2lkIG1haW4oKSB7XG4gICAgaW50IGluZGljZXNbJHtvdXRwdXRTaGFwZUxlbmd0aH1dO1xuICAgIHRvVmVjKFRleENvb3JkcywgaW5kaWNlcyk7XG4gICAgdmVjNCByZXN1bHQgPSB2ZWM0KHByb2Nlc3MoaW5kaWNlcykpO1xuICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICB9XG4gIGA7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uL3RlbnNvcic7XG5cbi8qKlxuICogTGF5b3V0IGluZm8gaXMgdXNlZCBmb3IgbWFwcGluZyBuLWRpbWVuc2lvbmFsIGFycmF5IHRvIDJEIHRleHR1cmVzXG4gKiBUaGUgbGF5b3V0IGlzIGNyZWF0ZWQgYnkgdGhlIFRleHR1cmVMYXlvdXRTdHJhdGVneSBiYXNlZCBvblxuICogdGhlIFRlbnNvcidzIGRpbWVuc2lvbnMgYW5kIHN0cmlkZXNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlTGF5b3V0IHtcbiAgd2lkdGg6IG51bWJlcjtcbiAgaGVpZ2h0OiBudW1iZXI7XG4gIC8qKlxuICAgKiBzcGVjaWZ5IHRoZSBudW1iZXIgb2YgdmFsdWUgdGhhdCBlbmNvZGVkIGluIGEgc2luZ2xlIHBpeGVsXG4gICAqL1xuICBjaGFubmVsczogMSB8IDIgfCAzIHwgNDtcbiAgLyoqXG4gICAqIHdoZXRoZXIgaW4gcGFja2VkIG1vZGUgb3Igbm90XG4gICAqL1xuICBpc1BhY2tlZD86IGJvb2xlYW47XG4gIC8qKlxuICAgKiB0aGUgbm9ybWFsaXplZCBzaGFwZVxuICAgKi9cbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuICAvKipcbiAgICogdGhlIHN0cmlkZSBvZiBlYWNoIGRpbWVuc2lvbnMsIGNhbGN1bGF0ZWQgYWNjb3JkaW5nIHRvIHNoYXBlXG4gICAqL1xuICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXTtcbiAgLyoqXG4gICAqIHRoZSBvcmlnaW5hbCBzaGFwZShkaW1zKSBvZiB0aGUgY29ycmVzcG9uZGluZyB0ZW5zb3JcbiAgICovXG4gIHVucGFja2VkU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gIHJldmVyc2VkV0g/OiBib29sZWFuO1xufVxuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlRGF0YSBleHRlbmRzIFRleHR1cmVMYXlvdXQge1xuICB0ZW5zb3I6IFRlbnNvcjtcbiAgdGV4dHVyZTogV2ViR0xUZXh0dXJlO1xufVxuXG5leHBvcnQgZW51bSBUZXh0dXJlVHlwZSB7XG4gIHVucGFja2VkLCAvLyA8LS0gbm9ybWFsIHVucGFja2VkIHRleHR1cmVcbiAgdW5wYWNrZWRSZXZlcnNlZCwgLy8gPC0tIHVucGFja2VkIHRleHR1cmUgdXNlZCBpbiBvbGQgT05OWC5qcyBpbXBsZW1lbnRhdGlvbiAoZGVwcmVjYXRlZClcbiAgcGFja2VkLCAvLyA8LS0gbm9ybWFsIHBhY2tlZCB0ZXh0dXJlXG4gIGRvd25sb2FkVWludDhBc0Zsb2F0LCAvLyA8LS0gT05MWSB1c2VkIGluIHRleHR1cmUgZG93bmxvYWRpbmcgZm9yIGlPUyBkZXZpY2VzXG4gIHBhY2tlZExhc3REaW1lbnNpb24sIC8vIDwtLSBPTkxZIHVzZWQgaW4gb2xkIE9OTlguanMgQ29udiBpbXBsZW1lbnRhdGlvbiBmb3IgaW5wdXQgVyAoZGVwcmVjYXRlZClcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JJbmZvIHtcbiAgaWQ/OiBUZW5zb3IuSWQ7XG4gIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICB0eXBlOiBUZW5zb3IuRGF0YVR5cGU7XG4gIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtVmFyaWFibGUge1xuICB0eXBlOiAnZmxvYXQnIHwgJ2ludCc7XG4gIG5hbWU6IHN0cmluZztcbiAgYXJyYXlMZW5ndGg/OiBudW1iZXI7XG4gIGRhdGE6IG51bWJlciB8IG51bWJlcltdO1xufVxuXG4vKipcbiAqIEEgc2V0IG9mIG1ldGFkYXRhIG9mIGEgc2hhZGVyIHByb2dyYW0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbU1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIHRoZSBuYW1lIG9mIHRoZSBwcm9ncmFtLiB1c2VkIGZvciBkZWJ1Z2dpbmcgYW5kIHByb2ZpbGluZ1xuICAgKi9cbiAgbmFtZTogc3RyaW5nO1xuICAvKipcbiAgICogdGV4dHVyZSB0eXBlcyBmb3IgZWFjaCBpbnB1dFxuICAgKi9cbiAgaW5wdXRUeXBlczogVGV4dHVyZVR5cGVbXTtcbiAgLyoqXG4gICAqIG5hbWVzIG9mIGVhY2ggaW5wdXRcbiAgICovXG4gIGlucHV0TmFtZXM6IHN0cmluZ1tdO1xuICAvKipcbiAgICogYW4gb3B0aW9uYWwgc3RyaW5nIGFzIGEgY2FjaGUgaGludCBpbiB0aGUgYXJ0aWZhY3QgY2FjaGVcbiAgICovXG4gIGNhY2hlSGludD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIFByb2dyYW1JbmZvTG9hZGVyIGFsbG93c1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb2dyYW1JbmZvTG9hZGVyIGV4dGVuZHMgUHJvZ3JhbU1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIGEgZnVuY3Rpb24gdG8gZ2V0IHRoZSBwcm9ncmFtIGluZm9cbiAgICovXG4gIGdldCgpOiBQcm9ncmFtSW5mbztcbn1cblxuLyoqXG4gKiBBIHNldCBvZiBkYXRhIHRoYXQgcmVwcmVzZW50IGEgc2hhZGVyIHByb2dyYW1cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtSW5mbyBleHRlbmRzIFByb2dyYW1NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBpbmZvcm1hdGlvbiBvZiB1bmlmb3JtIHZhcmlhYmxlc1xuICAgKi9cbiAgdmFyaWFibGVzPzogUHJvZ3JhbVZhcmlhYmxlW107XG4gIC8qKlxuICAgKiB0ZW5zb3IgaW5mbyBmb3Igb3V0cHV0XG4gICAqL1xuICBvdXRwdXQ6IFRlbnNvckluZm87XG4gIC8qKlxuICAgKiB0aGUgc2hhZGVyJ3MgcHJvY2Vzc2luZyBzb3VyY2UgY29kZVxuICAgKi9cbiAgc2hhZGVyU291cmNlOiBzdHJpbmc7XG4gIC8qKlxuICAgKiB3aGV0aGVyIHRoZSBzaGFkZXIgc291cmNlIGNvbnRhaW5zIGEgY3VzdG9taXplZCBtYWluIGZ1bmN0aW9uIGltcGxlbWVudGF0aW9uXG4gICAqL1xuICBoYXNNYWluPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWYXJpYWJsZUluZm8ge1xuICB0eXBlOiAnZmxvYXQnIHwgJ2ludCc7XG4gIG5hbWU6IHN0cmluZztcbiAgYXJyYXlMZW5ndGg/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbVZhcmlhYmxlIHtcbiAgdHlwZTogJ2Zsb2F0JyB8ICdpbnQnO1xuICBuYW1lOiBzdHJpbmc7XG4gIGFycmF5TGVuZ3RoPzogbnVtYmVyO1xuICBkYXRhOiBudW1iZXIgfCBudW1iZXJbXTtcbn1cblxuLyoqXG4gKiBJbmZvcm1hdGlvbiBvZiB1bmlmb3JtcyB0aGF0IHNoYWRlciB1c2VzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVW5pZm9ybUluZm8ge1xuICB0eXBlOiAnc2FtcGxlcjJEJyB8IFZhcmlhYmxlSW5mb1sndHlwZSddO1xuICBuYW1lOiBzdHJpbmc7XG4gIGFycmF5TGVuZ3RoPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVuaWZvcm1Mb2NhdGlvbiBleHRlbmRzIFVuaWZvcm1JbmZvIHtcbiAgbG9jYXRpb246IFdlYkdMVW5pZm9ybUxvY2F0aW9uO1xufVxuXG4vKipcbiAqIEFydGlmYWN0IGlzIHRoZSByZXN1bHQgb2YgY29tcGlsYXRpb25cbiAqIEl0IGRvZXMgbm90IGNvbnRhaW4gaW5wdXQgb2Ygb3V0cHV0IGRhdGFcbiAqIEhvd2V2ZXIgYW55dGhpbmcgdGhhdCBjb3VsZCBiZSBydW4gYXMgYSBcInByb2dyYW1cIlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFydGlmYWN0IHtcbiAgcHJvZ3JhbUluZm86IFByb2dyYW1JbmZvO1xuICBwcm9ncmFtOiBXZWJHTFByb2dyYW07XG4gIHVuaWZvcm1Mb2NhdGlvbnM6IFVuaWZvcm1Mb2NhdGlvbltdO1xuICBhdHRyaWJMb2NhdGlvbnM6IHsgcG9zaXRpb246IG51bWJlcjsgdGV4dHVyZUNvb3JkOiBudW1iZXIgfTtcbn1cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBBcnRpZmFjdCB7XG4gIHR5cGUgVW5pZm9ybUxvY2F0aW9ucyA9IEFydGlmYWN0Wyd1bmlmb3JtTG9jYXRpb25zJ107XG4gIHR5cGUgQXR0cmliTG9jYXRpb25zID0gQXJ0aWZhY3RbJ2F0dHJpYkxvY2F0aW9ucyddO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVuaWZvcm1EYXRhIHtcbiAgW25hbWU6IHN0cmluZ106IG51bWJlciB8IG51bWJlcltdO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuLi8uLi91dGlsJztcbi8qKlxuICogR2l2ZW4gYSBub24gUkdCQSBzaGFwZSBjYWxjdWxhdGUgdGhlIFIgdmVyc2lvblxuICogSXQgaXMgYXNzdW1lZCB0aGF0IHRoZSBkaW1lbnNpb25zIGFyZSBtdWx0aXBsZXMgb2YgZ2l2ZW4gY2hhbm5lbHNcbiAqIE5PVEU6IGl0IGlzIGFsd2F5cyB0aGUgbGFzdCBkaW0gdGhhdCBnZXRzIHBhY2tlZC5cbiAqIEBwYXJhbSB1bnBhY2tlZFNoYXBlIG9yaWdpbmFsIHNoYXBlIHRvIGNyZWF0ZSBhIHBhY2tlZCB2ZXJzaW9uIGZyb21cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFBhY2tlZFNoYXBlKHVucGFja2VkU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICBjb25zdCBsZW4gPSB1bnBhY2tlZFNoYXBlLmxlbmd0aDtcbiAgcmV0dXJuIHVucGFja2VkU2hhcGUuc2xpY2UoMCwgbGVuIC0gMSkuY29uY2F0KHVucGFja2VkU2hhcGVbbGVuIC0gMV0gLyA0KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlcGVhdGVkVHJ5KFxuICBjaGVja0ZuOiAoKSA9PiBib29sZWFuLFxuICBkZWxheUZuID0gKF9jb3VudGVyOiBudW1iZXIpID0+IDAsXG4gIG1heENvdW50ZXI/OiBudW1iZXIsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBsZXQgdHJ5Q291bnQgPSAwO1xuXG4gICAgY29uc3QgdHJ5Rm4gPSAoKSA9PiB7XG4gICAgICBpZiAoY2hlY2tGbigpKSB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0cnlDb3VudCsrO1xuXG4gICAgICBjb25zdCBuZXh0QmFja29mZiA9IGRlbGF5Rm4odHJ5Q291bnQpO1xuXG4gICAgICBpZiAobWF4Q291bnRlciAhPSBudWxsICYmIHRyeUNvdW50ID49IG1heENvdW50ZXIpIHtcbiAgICAgICAgcmVqZWN0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHNldFRpbWVvdXQodHJ5Rm4sIG5leHRCYWNrb2ZmKTtcbiAgICB9O1xuXG4gICAgdHJ5Rm4oKTtcbiAgfSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIHRoZSBmdW5jdGlvbiBuYW1lIGZyb20gYW4gaW5wdXQgc2FtcGxlciBuYW1lLlxuICogQHBhcmFtIHNhbXBsZXJOYW1lIE5hbWUgb2YgdGhlIHNhbXBsZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWUoc2FtcGxlck5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydCh0eXBlb2Ygc2FtcGxlck5hbWUgIT09ICd1bmRlZmluZWQnICYmIHNhbXBsZXJOYW1lLmxlbmd0aCAhPT0gMCwgKCkgPT4gJ2VtcHR5IHN0cmluZyBmb3VuZCBmb3Igc2FtcGxlciBuYW1lJyk7XG4gIHJldHVybiAnZ2V0JyArIHNhbXBsZXJOYW1lLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc2FtcGxlck5hbWUuc2xpY2UoMSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIHRoZSBmdW5jdGlvbiBuYW1lIGZyb20gYW4gaW5wdXQgc2FtcGxlciBuYW1lIGF0IG91dHB1dCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSBzYW1wbGVyTmFtZSBOYW1lIG9mIHRoZSBzYW1wbGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lQXRPdXRDb29yZHMoc2FtcGxlck5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydCh0eXBlb2Ygc2FtcGxlck5hbWUgIT09ICd1bmRlZmluZWQnICYmIHNhbXBsZXJOYW1lLmxlbmd0aCAhPT0gMCwgKCkgPT4gJ2VtcHR5IHN0cmluZyBmb3VuZCBmb3Igc2FtcGxlciBuYW1lJyk7XG4gIHJldHVybiAnZ2V0JyArIHNhbXBsZXJOYW1lLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc2FtcGxlck5hbWUuc2xpY2UoMSkgKyAnQXRPdXRDb29yZHMnO1xufVxuXG4vKiogUmV0dXJucyBhIG5ldyBpbnB1dCBzaGFwZSAoYSBjb3B5KSB0aGF0IGhhcyBhIHNxdWVlemVkIGxvZ2ljYWwgc2hhcGUuICovXG5leHBvcnQgZnVuY3Rpb24gc3F1ZWV6ZUlucHV0U2hhcGUoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHNxdWVlemVkU2hhcGU6IG51bWJlcltdKTogbnVtYmVyW10ge1xuICAvLyBEZWVwIGNvcHkuXG4gIGxldCBuZXdJbnB1dFNoYXBlOiBudW1iZXJbXSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaW5wdXRTaGFwZSkpO1xuICBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZWRTaGFwZTtcbiAgcmV0dXJuIG5ld0lucHV0U2hhcGU7XG59XG5cbi8qKiBSZXR1cm5zIGEgbGlzdCBvZiBzcXVlZXplZCBwYXJhbWV0ZXJzIGZvciBzaGFkZXIgZnVuY3Rpb25zICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3F1ZWV6ZWRQYXJhbXMocGFyYW1zOiBzdHJpbmdbXSwga2VwdERpbXM6IG51bWJlcltdKTogc3RyaW5nIHtcbiAgcmV0dXJuIGtlcHREaW1zLm1hcCgoZCkgPT4gcGFyYW1zW2RdKS5qb2luKCcsICcpO1xufVxuXG4vKiogUmV0dXJucyB0aGUgZGF0YSB0eXBlIGZvciBkaWZmZXJlbnQgcmFua3MuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29vcmRzRGF0YVR5cGUocmFuazogbnVtYmVyKTogc3RyaW5nIHtcbiAgaWYgKHJhbmsgPD0gMSkge1xuICAgIHJldHVybiAnaW50JztcbiAgfSBlbHNlIGlmIChyYW5rID09PSAyKSB7XG4gICAgcmV0dXJuICdpdmVjMic7XG4gIH0gZWxzZSBpZiAocmFuayA9PT0gMykge1xuICAgIHJldHVybiAnaXZlYzMnO1xuICB9IGVsc2UgaWYgKHJhbmsgPT09IDQpIHtcbiAgICByZXR1cm4gJ2l2ZWM0JztcbiAgfSBlbHNlIGlmIChyYW5rID09PSA1KSB7XG4gICAgcmV0dXJuICdpdmVjNSc7XG4gIH0gZWxzZSBpZiAocmFuayA9PT0gNikge1xuICAgIHJldHVybiAnaXZlYzYnO1xuICB9IGVsc2Uge1xuICAgIHRocm93IEVycm9yKGBHUFUgZm9yIHJhbmsgJHtyYW5rfSBpcyBub3QgeWV0IHN1cHBvcnRlZGApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRHbENoYW5uZWxzKHJhbmsgPSA2KTogc3RyaW5nW10ge1xuICByZXR1cm4gWyd4JywgJ3knLCAneicsICd3JywgJ3UnLCAndiddLnNsaWNlKDAsIHJhbmspO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBnZXRHbENoYW5uZWxzIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmVjQ2hhbm5lbHMobmFtZTogc3RyaW5nLCByYW5rOiBudW1iZXIpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBnZXRHbENoYW5uZWxzKHJhbmspLm1hcCgoZCkgPT4gYCR7bmFtZX0uJHtkfWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2hhbm5lbHMobmFtZTogc3RyaW5nLCByYW5rOiBudW1iZXIpOiBzdHJpbmdbXSB7XG4gIGlmIChyYW5rID09PSAxKSB7XG4gICAgcmV0dXJuIFtuYW1lXTtcbiAgfVxuICByZXR1cm4gZ2V0VmVjQ2hhbm5lbHMobmFtZSwgcmFuayk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1bnBhY2tGcm9tQ2hhbm5lbCgpOiBzdHJpbmcge1xuICByZXR1cm4gYFxuICAgIGZsb2F0IGdldENoYW5uZWwodmVjNCBmcmFnLCBpbnQgZGltKSB7XG4gICAgICBpbnQgbW9kQ29vcmQgPSBpbW9kKGRpbSwgMik7XG4gICAgICByZXR1cm4gbW9kQ29vcmQgPT0gMCA/IGZyYWcuciA6IGZyYWcuZztcbiAgICB9XG5cbiAgICBmbG9hdCBnZXRDaGFubmVsKHZlYzQgZnJhZywgdmVjMiBpbm5lckRpbXMpIHtcbiAgICAgIHZlYzIgbW9kQ29vcmQgPSBtb2QoaW5uZXJEaW1zLCAyLik7XG4gICAgICByZXR1cm4gbW9kQ29vcmQueCA9PSAwLiA/XG4gICAgICAgIChtb2RDb29yZC55ID09IDAuID8gZnJhZy5yIDogZnJhZy5nKSA6XG4gICAgICAgIChtb2RDb29yZC55ID09IDAuID8gZnJhZy5iIDogZnJhZy5hKTtcbiAgICB9XG4gIGA7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGdldENvb3Jkc0RhdGFUeXBlIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5pbXBvcnQgeyBnZXRDaGFubmVscyB9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IHBhY2tQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdwYWNrJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZFJldmVyc2VkXSxcbn07XG5cbmNvbnN0IGNyZWF0ZVBhY2tQcm9ncmFtSW5mbyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IpOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0LmRpbXM7XG5cbiAgY29uc3QgaW5wdXRSYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG4gIC8vIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUgd29uJ3QgY2hhbmdlIG91dHB1dCByYW5rLiBOZWVkIHRvIHZlcmlmeSBieSBydW5uaW5nIHRlc3RzXG4gIGNvbnN0IG91dHB1dFJhbmsgPSBpbnB1dC5kaW1zLmxlbmd0aDtcblxuICBjb25zdCBjb29yZHNEYXRhVHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKG91dHB1dFJhbmspO1xuICBjb25zdCBjaGFubmVscyA9IGdldENoYW5uZWxzKCdyYycsIG91dHB1dFJhbmspO1xuICBjb25zdCBzZXR1cCA9IGdldFNldHVwKG91dHB1dFJhbmssIGNoYW5uZWxzLCBpbnB1dFNoYXBlW2lucHV0U2hhcGUubGVuZ3RoIC0gMl0sIGlucHV0U2hhcGVbaW5wdXRTaGFwZS5sZW5ndGggLSAxXSk7XG5cbiAgbGV0IHJldmVyc2VkSW5wdXRXSDtcbiAgaWYgKGlucHV0UmFuayA9PT0gMCkge1xuICAgIHJldmVyc2VkSW5wdXRXSCA9IFsxLCAxXTtcbiAgfSBlbHNlIGlmIChpbnB1dFJhbmsgPT09IDEpIHtcbiAgICByZXZlcnNlZElucHV0V0ggPSBbaW5wdXRTaGFwZVswXSwgMV07XG4gIH0gZWxzZSB7XG4gICAgcmV2ZXJzZWRJbnB1dFdIID0gW2lucHV0U2hhcGVbb3V0cHV0UmFuayAtIDFdLCBpbnB1dFNoYXBlW291dHB1dFJhbmsgLSAyXV07XG4gIH1cbiAgY29uc3Qgb3V0T2ZCb3VuZHNDb25kaXRpb24gPSBnZXRPdXRPZkJvdW5kc0NvbmRpdGlvbihvdXRwdXRSYW5rLCByZXZlcnNlZElucHV0V0gsIGNoYW5uZWxzKTtcbiAgY29uc3Qgb3V0cHV0ID0gZ2V0T3V0cHV0KGlucHV0U2hhcGUsIGNoYW5uZWxzKTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgICAke2Nvb3Jkc0RhdGFUeXBlfSByYyA9IGdldE91dHB1dENvb3JkcygpO1xuXG4gICAgICAgICAgaWYoJHtvdXRPZkJvdW5kc0NvbmRpdGlvbn0pIHtcbiAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmVjNCgwKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgJHtzZXR1cH1cblxuICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KCR7b3V0cHV0fSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLnBhY2tQcm9ncmFtTWV0YWRhdGEsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW5wdXQuZGltcywgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQYWNrUHJvZ3JhbUluZm9Mb2FkZXIgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4gKHtcbiAgLi4ucGFja1Byb2dyYW1NZXRhZGF0YSxcbiAgZ2V0OiAoKSA9PiBjcmVhdGVQYWNrUHJvZ3JhbUluZm8oaGFuZGxlciwgaW5wdXQpLFxufSk7XG5cbi8qKlxuICogY2hlY2sgb3V0cHV0IGNvb3JkaW5hdGUgbG9jYXRpb24gYW5kIHJldHVybiBmYWxzZSBpZiBpdCBpcyBvdXRzaWRlIGlucHV0J3Mgd2lkdGgvaGVpZ2h0IGJvdW5kYXJ5XG4gKi9cbmZ1bmN0aW9uIGdldE91dE9mQm91bmRzQ29uZGl0aW9uKHJhbms6IG51bWJlciwgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBkaW1zOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIGlmIChyYW5rID09PSAwKSB7XG4gICAgcmV0dXJuICdmYWxzZSc7XG4gIH1cbiAgaWYgKHJhbmsgPT09IDEpIHtcbiAgICByZXR1cm4gYHJjID4gJHtzaGFwZVswXX1gO1xuICB9XG5cbiAgbGV0IGNvbmQgPSAnJztcbiAgZm9yIChsZXQgaSA9IHJhbmsgLSAyOyBpIDwgcmFuazsgaSsrKSB7XG4gICAgY29uZCArPSBgJHtkaW1zW2ldfSA+PSAke3NoYXBlW2kgLSByYW5rICsgMl19YDtcbiAgICBpZiAoaSA8IHJhbmsgLSAxKSB7XG4gICAgICBjb25kICs9ICd8fCc7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvbmQ7XG59XG5cbi8qKlxuICogY29kZSBzbmlwcGV0IHRvIHNhbXBsZSBpbnB1dCB0ZXh0dXJlIHdpdGggb3V0cHV0IGNvb3JkaW5hdGVzXG4gKi9cbmZ1bmN0aW9uIGdldE91dHB1dChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGRpbXM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICBpZiAocmFuayA9PT0gMCkge1xuICAgIHJldHVybiAnZ2V0QSgpLCAwLCAwLCAwJztcbiAgfVxuXG4gIGlmIChyYW5rID09PSAxKSB7XG4gICAgcmV0dXJuIGBnZXRBKHJjKSxcbiAgICAgICAgICAgIHJjICsgMSA+PSAke3NoYXBlWzBdfSA/IDAuIDogZ2V0QShyYyArIDEpLFxuICAgICAgICAgICAgMCwgMGA7XG4gIH1cblxuICBjb25zdCBjb29yZDAwID0gJ3IsIGMnO1xuICBjb25zdCBjb29yZDAxID0gJ3IsIGNwMSc7XG4gIGNvbnN0IGNvb3JkMTAgPSAncnAxLCBjJztcbiAgY29uc3QgY29vcmQxMSA9ICdycDEsIGNwMSc7XG4gIGxldCBEID0gJyc7XG4gIGlmIChyYW5rID4gMikge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDI7ICsraSkge1xuICAgICAgRCA9IEQgKyBgJHtkaW1zW2ldfSxgO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYGdldEEoJHtEfSR7Y29vcmQwMH0pLFxuICAgICAgICAgIHJFZGdlID8gMC4gOiBnZXRBKCR7RH0ke2Nvb3JkMTB9KSxcbiAgICAgICAgICBjRWRnZSA/IDAuIDogZ2V0QSgke0R9JHtjb29yZDAxfSksXG4gICAgICAgICAgckVkZ2UgfHwgY0VkZ2UgPyAwLiA6IGdldEEoJHtEfSR7Y29vcmQxMX0pYDtcbn1cblxuLyoqXG4gKiBjb2RlIHNuaXBwZXQgdG8gc2V0dXAgNCBjb29yZGluYXRlcyBhbmQgZWRnZSBjb25kaXRpb25zXG4gKi9cbmZ1bmN0aW9uIGdldFNldHVwKHJhbms6IG51bWJlciwgZGltczogc3RyaW5nW10sIHJvd3M6IG51bWJlciwgY29sczogbnVtYmVyKTogc3RyaW5nIHtcbiAgaWYgKHJhbmsgPT09IDAgfHwgcmFuayA9PT0gMSkge1xuICAgIHJldHVybiAnJztcbiAgfVxuICAvLyByYW5rID49IDIgZm9yIHdpZHRoK2hlaWdodCBwYWNrLlxuICBlbHNlIHtcbiAgICBjb25zdCBzZXR1cCA9IGBcbiAgICBpbnQgciA9ICR7ZGltc1tyYW5rIC0gMl19O1xuICAgIGludCBjID0gJHtkaW1zW3JhbmsgLSAxXX07XG4gICAgaW50IHJwMSA9ICR7ZGltc1tyYW5rIC0gMl19ICsgMTtcbiAgICBpbnQgY3AxID0gJHtkaW1zW3JhbmsgLSAxXX0gKyAxO1xuICAgIGJvb2wgckVkZ2UgPSBycDEgPj0gJHtjb2xzfTtcbiAgICBib29sIGNFZGdlID0gY3AxID49ICR7cm93c307XG4gICAgYDtcbiAgICByZXR1cm4gc2V0dXA7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgdW5wYWNrRnJvbUNoYW5uZWwgfSBmcm9tICcuL3BhY2tpbmctdXRpbHMnO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtTWV0YWRhdGEgPSAob3V0cHV0U2hhcGUzRDogcmVhZG9ubHkgbnVtYmVyW10pID0+ICh7XG4gIG5hbWU6ICdSZXNoYXBlIChwYWNrZWQpJyxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnBhY2tlZF0sXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBjYWNoZUhpbnQ6IGAke291dHB1dFNoYXBlM0R9YCxcbn0pO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtSW5mbyA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDNEOiBUZW5zb3IsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIG91dHB1dFNoYXBlM0Q6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlM0QgPSBpbnB1dDNELmRpbXMgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICBjb25zdCBzcXVlZXplZE91dHB1dFNoYXBlID0gb3V0cHV0U2hhcGUzRCBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG5cbiAgbGV0IG1haW5Mb29wID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgbGV0IG91dHB1dENvb3JkcyA9ICcnO1xuICAgIHN3aXRjaCAoaSkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICBvdXRwdXRDb29yZHMgPSAnb3V0cHV0Q29vcmRzID0gcmM7JztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIG91dHB1dENvb3JkcyA9ICdvdXRwdXRDb29yZHMgPSBpdmVjMyhyYy54LCByYy55KzEsIHJjLnopOyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICBvdXRwdXRDb29yZHMgPSAnb3V0cHV0Q29vcmRzID0gaXZlYzMocmMueCwgcmMueSwgcmMueisxKTsnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgb3V0cHV0Q29vcmRzID0gJ291dHB1dENvb3JkcyA9IGl2ZWMzKHJjLngsIHJjLnkrMSwgcmMueisxKTsnO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgIH1cblxuICAgIG1haW5Mb29wICs9IGBcbiAgICAgICAgJHtvdXRwdXRDb29yZHN9XG4gICAgICAgICR7aSA+IDAgPyAnaWYob3V0cHV0Q29vcmRzLnkgPCByb3dzICYmIG91dHB1dENvb3Jkcy56IDwgY29scyl7JyA6ICcnfVxuICAgICAgICAgIGludCBmbGF0dGVuZWRJbmRleCA9IGdldEZsYXR0ZW5lZEluZGV4KG91dHB1dENvb3Jkcyk7XG5cbiAgICAgICAgICBpdmVjMyBpbnB1dFJDID0gaW5wdXRDb29yZHNGcm9tUmVzaGFwZWRPdXRDb29yZHMoZmxhdHRlbmVkSW5kZXgpO1xuICAgICAgICAgIHZlYzIgaW5uZXJEaW1zID0gdmVjMihmbG9hdChpbnB1dFJDLnkpLGZsb2F0KGlucHV0UkMueikpO1xuXG4gICAgICAgICAgcmVzdWx0WyR7aX1dID0gZ2V0Q2hhbm5lbChnZXRBKGlucHV0UkMueCwgaW5wdXRSQy55LCBpbnB1dFJDLnopLCBpbm5lckRpbXMpO1xuXG4gICAgICAgICR7aSA+IDAgPyAnfScgOiAnJ31cbiAgICAgIGA7XG4gIH1cbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICR7Z2V0UmVzaGFwZWRJbnB1dENvb3JkcyhpbnB1dFNoYXBlM0QpfVxuICAgICAgJHtnZXRGbGF0dGVuZWRJbmRleEZyb20zRChzcXVlZXplZE91dHB1dFNoYXBlKX1cbiAgICAgICR7dW5wYWNrRnJvbUNoYW5uZWwoKX1cblxuICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICBpdmVjMyByYyA9IGdldE91dHB1dENvb3JkcygpO1xuXG4gICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNCgwLjApO1xuXG4gICAgICAgIGl2ZWMzIG91dHB1dENvb3JkcztcbiAgICAgICAgaW50IHJvd3MgPSAke3NxdWVlemVkT3V0cHV0U2hhcGVbMl19O1xuICAgICAgICBpbnQgY29scyA9ICR7c3F1ZWV6ZWRPdXRwdXRTaGFwZVsxXX07XG5cbiAgICAgICAgJHttYWluTG9vcH1cbiAgICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgICB9XG4gICAgYDtcblxuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBzcXVlZXplZE91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dDNELnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDNEOiBUZW5zb3IsXG4gIG91dHB1dFNoYXBlM0Q6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1NZXRhZGF0YShvdXRwdXRTaGFwZTNEKTtcbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbUluZm8oaGFuZGxlciwgaW5wdXQzRCwgbWV0YWRhdGEsIG91dHB1dFNoYXBlM0QpIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcHJvY2Vzc0RpbXMzRChzaGFwZTogQXJyYXlMaWtlPG51bWJlcj4pOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0ge1xuICBpZiAoc2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIFsxLCAxLCAxXTtcbiAgfVxuICAvLyBUT0RPOiBzcXVlZXplIG90aGVyIHNoYXBlcyB0byAyRCBjYXNlXG4gIGxldCBiYXRjaCA9IDE7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2hhcGUubGVuZ3RoIC0gMjsgKytpKSB7XG4gICAgYmF0Y2ggKj0gc2hhcGVbaV07XG4gIH1cbiAgcmV0dXJuIFtiYXRjaCwgc2hhcGUubGVuZ3RoID4gMSA/IHNoYXBlW3NoYXBlLmxlbmd0aCAtIDJdIDogMSwgc2hhcGVbc2hhcGUubGVuZ3RoIC0gMV1dO1xufVxuXG4vLyBGb3IgcGFja2VkIHJlc2hhcGUsIHdlIG5lZWQgdG8gcmUtYXJyYW5nZSB0ZXhlbCBkYXRhIGZvciBvdXRwdXQgc2hhcGUuXG4vLyBPdXIgcGFjayBpcyBkZXNpZ25lZCB0byBwYWNrIGEgMngyIHRpbGUgaW4gbGFzdCBoIGFuZCB3IGRpbWVuc2lvbiwgc29cbi8vIGZvciB0aGUgcmVzaGFwZWQgbmV3IHRlbnNvciwgd2UganVzdCBuZWVkIHRvIHJlLWFycmFuZ2UgdGhlIGxhc3QgaCBhbmRcbi8vIHcgZGltZW5zaW9uLiBGb3IgYW55IHNoYXBlIHRoYXQgaXMgbm90IGluIDNELCBpLmUuIFtiYXRjaCwgVywgSF0sIHdlXG4vLyBmaXJzdCBjb252ZXJ0IGl0IHRvIDNEIGJ5IGNvbGxhcHNpbmcgb3RoZXIgZGltZW5zaW9uIHRvIGJhdGNoIGRpbSwgdGhlblxuLy8gcHJvY2VzcyB3aXRoIHRoZSBsYXN0IHR3byBkaW1lbnNpb25zLlxuLy8gTm90ZTogd2Ugb25seSBuZWVkIHRoZSBzaGFwZSB0ZW5zb3IgdG8gY2FsY3VsYXRlIG91dHB1dCBzaGFwZSwgc28gdGhlXG4vLyBjb250ZW50IGluIHNoYXBlIHRlbnNvciBpcyBuZXZlciB1cGxvYWRlZCB0byBHUFUuIEl0IGlzIGFsd2F5cyBrZXB0IGluIENQVS5cbi8vIFRPRE86IG9wdGltaXplIHRoZSBhbGdvcml0aG0gLS0gaW4gc29tZSBjYXNlcywgaWYgdGhlIGxhc3QgdHdvIGRpbXMgYXJlXG4vLyB0aGUgc2FtZSBiZXR3ZWVuIGlucHV0IHNoYXBlIGFuZCBvdXRwdXQgc2hhcGUsIHRoZSBwYWNrZWQgcmVzaGFwZSBjYW4gYmVcbi8vIHRyZWF0ZWQgYXMgbm8tb3AuXG5leHBvcnQgZnVuY3Rpb24gaXNSZXNoYXBlQ2hlYXAoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIHJlc2hhcGVkRGltczogcmVhZG9ubHkgbnVtYmVyW10pIHtcbiAgbGV0IGlzQ2hlYXBSZXNoYXBlID0gZmFsc2U7XG4gIGlmIChkaW1zLmxlbmd0aCA9PT0gMCB8fCByZXNoYXBlZERpbXMubGVuZ3RoID09PSAwKSB7XG4gICAgLy8gc2NhbGFyXG4gICAgaXNDaGVhcFJlc2hhcGUgPSB0cnVlO1xuICB9IGVsc2UgaWYgKGRpbXMubGVuZ3RoIDwgMiB8fCByZXNoYXBlZERpbXMubGVuZ3RoIDwgMikge1xuICAgIC8vIDFEXG4gICAgaXNDaGVhcFJlc2hhcGUgPSBkaW1zW2RpbXMubGVuZ3RoIC0gMV0gPT09IHJlc2hhcGVkRGltc1tyZXNoYXBlZERpbXMubGVuZ3RoIC0gMV07XG4gIH0gZWxzZSB7XG4gICAgLy8gMkQgK1xuICAgIGlzQ2hlYXBSZXNoYXBlID1cbiAgICAgIGRpbXNbZGltcy5sZW5ndGggLSAxXSA9PT0gcmVzaGFwZWREaW1zW3Jlc2hhcGVkRGltcy5sZW5ndGggLSAxXSAmJlxuICAgICAgZGltc1tkaW1zLmxlbmd0aCAtIDJdID09PSByZXNoYXBlZERpbXNbcmVzaGFwZWREaW1zLmxlbmd0aCAtIDJdO1xuICB9XG5cbiAgcmV0dXJuIGlzQ2hlYXBSZXNoYXBlO1xufVxuXG5mdW5jdGlvbiBnZXRSZXNoYXBlZElucHV0Q29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0pOiBzdHJpbmcge1xuICBjb25zdCBzdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKHNoYXBlKTtcbiAgY29uc3QgY29vcmRzID0gWydiJywgJ3InLCAnYyddO1xuICBjb25zdCBpbmRleCA9ICdpbmRleCc7XG4gIGNvbnN0IGNvb3Jkc0Zyb21JbmRleFNuaXBwZXQgPSBzdHJpZGVzXG4gICAgLm1hcCgoc3RyaWRlLCBpKSA9PiB7XG4gICAgICBjb25zdCBsaW5lMSA9IGBpbnQgJHtjb29yZHNbaV19ID0gJHtpbmRleH0gLyAke3N0cmlkZX1gO1xuICAgICAgY29uc3QgbGluZTIgPVxuICAgICAgICBpID09PSBzdHJpZGVzLmxlbmd0aCAtIDFcbiAgICAgICAgICA/IGBpbnQgJHtjb29yZHNbaSArIDFdfSA9ICR7aW5kZXh9IC0gJHtjb29yZHNbaV19ICogJHtzdHJpZGV9YFxuICAgICAgICAgIDogYGluZGV4IC09ICR7Y29vcmRzW2ldfSAqICR7c3RyaWRlfWA7XG4gICAgICByZXR1cm4gYCR7bGluZTF9OyAke2xpbmUyfTtgO1xuICAgIH0pXG4gICAgLmpvaW4oJycpO1xuXG4gIHJldHVybiBgXG4gICAgaXZlYzMgaW5wdXRDb29yZHNGcm9tUmVzaGFwZWRPdXRDb29yZHMoaW50IGluZGV4KSB7XG4gICAgICAke2Nvb3Jkc0Zyb21JbmRleFNuaXBwZXR9XG4gICAgICByZXR1cm4gaXZlYzMoYiwgciwgYyk7XG4gICAgfVxuICBgO1xufVxuXG5mdW5jdGlvbiBnZXRGbGF0dGVuZWRJbmRleEZyb20zRChzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdKTogc3RyaW5nIHtcbiAgY29uc3Qgc3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhzaGFwZSk7XG5cbiAgcmV0dXJuIGBcbiAgaW50IGdldEZsYXR0ZW5lZEluZGV4KGl2ZWMzIGNvb3Jkcykge1xuICAgIC8vIHJldmVyc2UgeSwgeiBvcmRlclxuICAgIHJldHVybiBjb29yZHMueCAqICR7c3RyaWRlc1swXX0gKyBjb29yZHMueiAqICR7c3RyaWRlc1sxXX0gKyBjb29yZHMueTtcbiAgfVxuYDtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFRleHR1cmVEYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IGVuY29kZUFzVWludDggPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGV4dHVyZURhdGEpOiBUZXh0dXJlRGF0YSA9PiB7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXQuc2hhcGU7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgLyoqXG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS90ZW5zb3JmbG93L3RmanMtY29yZS9ibG9iL21hc3Rlci9zcmMva2VybmVscy93ZWJnbC9lbmNvZGVfZmxvYXRfZ3B1LnRzXG4gICAqL1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgY29uc3QgZmxvYXQgRkxPQVRfTUFYID0gMS43MDE0MTE4NGUzODtcbiAgICBjb25zdCBmbG9hdCBGTE9BVF9NSU4gPSAxLjE3NTQ5NDM1ZS0zODtcblxuICAgIGJvb2wgaXNOYU4oZmxvYXQgdmFsKSB7XG4gICAgICByZXR1cm4gKHZhbCA8IDEuMCB8fCAwLjAgPCB2YWwgfHwgdmFsID09IDAuMCkgPyBmYWxzZSA6IHRydWU7XG4gICAgfVxuXG4gICAgaGlnaHAgdmVjNCBlbmNvZGVBc1VpbnQ4KGhpZ2hwIGZsb2F0IHYpIHtcbiAgICAgIGlmIChpc05hTih2KSkge1xuICAgICAgICByZXR1cm4gdmVjNCgyNTUsIDI1NSwgMjU1LCAyNTUpO1xuICAgICAgfVxuXG4gICAgICBoaWdocCBmbG9hdCBhdiA9IGFicyh2KTtcblxuICAgICAgaWYoYXYgPCBGTE9BVF9NSU4pIHtcbiAgICAgICAgcmV0dXJuIHZlYzQoMC4wLCAwLjAsIDAuMCwgMC4wKTtcbiAgICAgIH0gZWxzZSBpZih2ID4gRkxPQVRfTUFYKSB7XG4gICAgICAgIHJldHVybiB2ZWM0KDAuMCwgMC4wLCAxMjguMCwgMTI3LjApIC8gMjU1LjA7XG4gICAgICB9IGVsc2UgaWYodiA8IC1GTE9BVF9NQVgpIHtcbiAgICAgICAgcmV0dXJuIHZlYzQoMC4wLCAwLjAsICAxMjguMCwgMjU1LjApIC8gMjU1LjA7XG4gICAgICB9XG5cbiAgICAgIGhpZ2hwIHZlYzQgYyA9IHZlYzQoMCwwLDAsMCk7XG5cbiAgICAgIGhpZ2hwIGZsb2F0IGUgPSBmbG9vcihsb2cyKGF2KSk7XG4gICAgICBoaWdocCBmbG9hdCBtID0gZXhwMihmcmFjdChsb2cyKGF2KSkpIC0gMS4wO1xuXG4gICAgICBjWzJdID0gZmxvb3IoMTI4LjAgKiBtKTtcbiAgICAgIG0gLT0gY1syXSAvIDEyOC4wO1xuICAgICAgY1sxXSA9IGZsb29yKDMyNzY4LjAgKiBtKTtcbiAgICAgIG0gLT0gY1sxXSAvIDMyNzY4LjA7XG4gICAgICBjWzBdID0gZmxvb3IoODM4ODYwOC4wICogbSk7XG5cbiAgICAgIGhpZ2hwIGZsb2F0IGViaWFzID0gZSArIDEyNy4wO1xuICAgICAgY1szXSA9IGZsb29yKGViaWFzIC8gMi4wKTtcbiAgICAgIGViaWFzIC09IGNbM10gKiAyLjA7XG4gICAgICBjWzJdICs9IGZsb29yKGViaWFzKSAqIDEyOC4wO1xuXG4gICAgICBjWzNdICs9IDEyOC4wICogc3RlcCgwLjAsIC12KTtcblxuICAgICAgcmV0dXJuIGMgLyAyNTUuMDtcbiAgICB9XG5cbiAgICB2b2lkIG1haW4oKSB7XG4gICAgICBmbG9hdCB2YWx1ZSA9ICR7Z2xzbC50ZXh0dXJlMkR9KFgsVGV4Q29vcmRzKS5yO1xuICAgICAgJHtnbHNsLm91dHB1dH0gPSBlbmNvZGVBc1VpbnQ4KHZhbHVlKTtcbiAgICB9YDtcbiAgY29uc3QgcHJvZ3JhbUluZm8gPSB7XG4gICAgbmFtZTogJ1VpbnQ4RW5jb2RlJyxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICAgIGlucHV0TmFtZXM6IFsnWCddLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudGVuc29yLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5kb3dubG9hZFVpbnQ4QXNGbG9hdCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xuICByZXR1cm4gaW5mZXJlbmNlSGFuZGxlci5leGVjdXRlUHJvZ3JhbShwcm9ncmFtSW5mbywgW2lucHV0LnRlbnNvcl0pO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0Q29vcmRzRGF0YVR5cGUgfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IGdldENoYW5uZWxzLCB1bnBhY2tGcm9tQ2hhbm5lbCB9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IHVucGFja1Byb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ3VucGFjaycsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVVbnBhY2tQcm9ncmFtSW5mbyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IpOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHJhbmsgPSBpbnB1dC5kaW1zLmxlbmd0aDtcblxuICBjb25zdCBjaGFubmVscyA9IGdldENoYW5uZWxzKCdyYycsIHJhbmspO1xuICBjb25zdCBpbm5lckRpbXMgPSBjaGFubmVscy5zbGljZSgtMik7XG4gIGNvbnN0IGNvb3Jkc0RhdGFUeXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUocmFuayk7XG4gIGNvbnN0IHVucGFja0NoYW5uZWwgPSB1bnBhY2tGcm9tQ2hhbm5lbCgpO1xuICBjb25zdCBpc1NjYWxhciA9IGlucHV0LmRpbXMubGVuZ3RoID09PSAwO1xuICBjb25zdCBzb3VyY2VDb29yZHMgPSBpc1NjYWxhciA/ICcnIDogZ2V0U291cmNlQ29vcmRzKHJhbmssIGNoYW5uZWxzKTtcbiAgY29uc3QgY29vcmRzID0gcmFuayA8PSAxID8gJ3JjJyA6IGB2ZWMyKCR7aW5uZXJEaW1zLmpvaW4oJywnKX0pYDtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgJHt1bnBhY2tDaGFubmVsfVxuICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICR7Y29vcmRzRGF0YVR5cGV9IHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG5cbiAgICAgICAvLyBTYW1wbGUgdGhlIHRleHR1cmUgd2l0aCB0aGUgY29vcmRzIHRvIGdldCB0aGUgcmdiYSBjaGFubmVsIHZhbHVlLlxuICAgICAgIHZlYzQgcGFja2VkSW5wdXQgPSBnZXRBKCR7c291cmNlQ29vcmRzfSk7XG5cbiAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQoZ2V0Q2hhbm5lbChwYWNrZWRJbnB1dCwgJHtjb29yZHN9KSwgMCwgMCwgMCk7XG4gICAgIH1cbiAgIGA7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi51bnBhY2tQcm9ncmFtTWV0YWRhdGEsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW5wdXQuZGltcywgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVVucGFja1Byb2dyYW1JbmZvTG9hZGVyID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvTG9hZGVyID0+ICh7XG4gIC4uLnVucGFja1Byb2dyYW1NZXRhZGF0YSxcbiAgZ2V0OiAoKSA9PiBjcmVhdGVVbnBhY2tQcm9ncmFtSW5mbyhoYW5kbGVyLCBpbnB1dCksXG59KTtcblxuZnVuY3Rpb24gZ2V0U291cmNlQ29vcmRzKHJhbms6IG51bWJlciwgZGltczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBpZiAocmFuayA9PT0gMSkge1xuICAgIHJldHVybiAncmMnO1xuICB9XG5cbiAgbGV0IGNvb3JkcyA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7IGkrKykge1xuICAgIGNvb3JkcyArPSBkaW1zW2ldO1xuICAgIGlmIChpIDwgcmFuayAtIDEpIHtcbiAgICAgIGNvb3JkcyArPSAnLCc7XG4gICAgfVxuICB9XG4gIHJldHVybiBjb29yZHM7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJy4uLy4uL2luc3RydW1lbnQnO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgRW5jb2RlciB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgRGF0YVR5cGVNYXAge1xuICAgIGZsb2F0OiBGbG9hdDMyQXJyYXk7XG4gICAgYnl0ZTogVWludDhBcnJheTtcbiAgICBpbnQ6IFVpbnQzMkFycmF5O1xuICB9XG4gIGV4cG9ydCB0eXBlIERhdGFUeXBlID0ga2V5b2YgRGF0YVR5cGVNYXA7XG4gIHR5cGUgRGF0YUFycmF5VHlwZSA9IERhdGFUeXBlTWFwW0RhdGFUeXBlXTtcbn1cblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXG5leHBvcnQgY29uc3QgZW51bSBFbmNvZGVyVXNhZ2Uge1xuICBEZWZhdWx0ID0gMCxcbiAgVXBsb2FkT25seSxcbiAgRG93bmxvYWQ0Qnl0ZXNBc0Zsb2F0MzIsXG59XG4vKiBlc2xpbnQtZW5hYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiAqL1xuXG4vKipcbiAqIEFic3RyYWN0aW9uIGZvciBtYXBwaW5nIGRhdGEgdHlwZXMgdG8gdGV4dHVyZSB0ZXhsZXRzXG4gKiBFbmNvZGluZyBtZWFucyBob3cgYSBGbG9hdDMyIGlzIG1hcHBlZCB0byAxIG9yIDQgY2hhbm5lbHMgZm9yIGVhY2ggdGV4bGV0XG4gKiBEZWNvZGluZyBtZWFucyBob3cgYSB0ZXhsZXQncyBjaGFubmVscyBhcmUgbWFwcGVkIHRvIGEgcmVzdWx0aW5nIEZsb2F0MzJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEYXRhRW5jb2RlciB7XG4gIGludGVybmFsRm9ybWF0OiBudW1iZXI7XG4gIGZvcm1hdDogbnVtYmVyO1xuICB0ZXh0dXJlVHlwZTogbnVtYmVyO1xuICBjaGFubmVsU2l6ZTogbnVtYmVyO1xuICBlbmNvZGUoc3JjOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUsIHRleHR1cmVTaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGU7XG4gIGFsbG9jYXRlKHNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZTtcbiAgZGVjb2RlKGJ1ZmZlcjogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCBkYXRhU2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlO1xufVxuLyoqXG4gKiBXZWJHTDIgZGF0YSBlbmNvZGVyXG4gKiBVc2VzIFIzMkYgYXMgdGhlIGZvcm1hdCBmb3IgdGV4bGV0XG4gKi9cbmV4cG9ydCBjbGFzcyBSZWRGbG9hdDMyRGF0YUVuY29kZXIgaW1wbGVtZW50cyBEYXRhRW5jb2RlciB7XG4gIGludGVybmFsRm9ybWF0OiBudW1iZXI7XG4gIGZvcm1hdDogbnVtYmVyO1xuICB0ZXh0dXJlVHlwZTogbnVtYmVyO1xuICBjaGFubmVsU2l6ZTogbnVtYmVyO1xuICBjb25zdHJ1Y3RvcihnbDogV2ViR0wyUmVuZGVyaW5nQ29udGV4dCwgY2hhbm5lbHMgPSAxKSB7XG4gICAgaWYgKGNoYW5uZWxzID09PSAxKSB7XG4gICAgICB0aGlzLmludGVybmFsRm9ybWF0ID0gZ2wuUjMyRjtcbiAgICAgIHRoaXMuZm9ybWF0ID0gZ2wuUkVEO1xuICAgICAgdGhpcy50ZXh0dXJlVHlwZSA9IGdsLkZMT0FUO1xuICAgICAgdGhpcy5jaGFubmVsU2l6ZSA9IGNoYW5uZWxzO1xuICAgIH0gZWxzZSBpZiAoY2hhbm5lbHMgPT09IDQpIHtcbiAgICAgIHRoaXMuaW50ZXJuYWxGb3JtYXQgPSBnbC5SR0JBMzJGO1xuICAgICAgdGhpcy5mb3JtYXQgPSBnbC5SR0JBO1xuICAgICAgdGhpcy50ZXh0dXJlVHlwZSA9IGdsLkZMT0FUO1xuICAgICAgdGhpcy5jaGFubmVsU2l6ZSA9IGNoYW5uZWxzO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgbnVtYmVyIG9mIGNoYW5uZWxzOiAke2NoYW5uZWxzfWApO1xuICAgIH1cbiAgfVxuICBlbmNvZGUoc3JjOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUsIHRleHR1cmVTaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUge1xuICAgIGxldCByZXN1bHQ6IEZsb2F0MzJBcnJheTtcbiAgICBsZXQgc291cmNlOiBGbG9hdDMyQXJyYXk7XG4gICAgaWYgKHNyYy5jb25zdHJ1Y3RvciAhPT0gRmxvYXQzMkFycmF5KSB7XG4gICAgICBMb2dnZXIud2FybmluZygnRW5jb2RlcicsICdkYXRhIHdhcyBub3Qgb2YgdHlwZSBGbG9hdDMyOyBjcmVhdGluZyBuZXcgRmxvYXQzMkFycmF5Jyk7XG4gICAgICBzb3VyY2UgPSBuZXcgRmxvYXQzMkFycmF5KHNyYyk7XG4gICAgfVxuICAgIGlmICh0ZXh0dXJlU2l6ZSAqIHRoaXMuY2hhbm5lbFNpemUgPiBzcmMubGVuZ3RoKSB7XG4gICAgICBMb2dnZXIud2FybmluZygnRW5jb2RlcicsICdTb3VyY2UgZGF0YSB0b28gc21hbGwuIEFsbG9jYXRpbmcgbGFyZ2VyIGFycmF5Jyk7XG4gICAgICBzb3VyY2UgPSBzcmMgYXMgRmxvYXQzMkFycmF5O1xuICAgICAgcmVzdWx0ID0gdGhpcy5hbGxvY2F0ZSh0ZXh0dXJlU2l6ZSAqIHRoaXMuY2hhbm5lbFNpemUpIGFzIEZsb2F0MzJBcnJheTtcbiAgICAgIHNvdXJjZS5mb3JFYWNoKCh2LCBpKSA9PiAocmVzdWx0W2ldID0gdikpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzb3VyY2UgPSBzcmMgYXMgRmxvYXQzMkFycmF5O1xuICAgICAgcmVzdWx0ID0gc291cmNlO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIGFsbG9jYXRlKHNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoc2l6ZSAqIDQpO1xuICB9XG4gIGRlY29kZShidWZmZXI6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgZGF0YVNpemU6IG51bWJlcik6IEZsb2F0MzJBcnJheSB7XG4gICAgaWYgKHRoaXMuY2hhbm5lbFNpemUgPT09IDEpIHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkRGF0YSA9IChidWZmZXIgYXMgRmxvYXQzMkFycmF5KS5maWx0ZXIoKF92YWx1ZSwgaW5kZXgpID0+IGluZGV4ICUgNCA9PT0gMCkuc3ViYXJyYXkoMCwgZGF0YVNpemUpO1xuICAgICAgcmV0dXJuIGZpbHRlcmVkRGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1ZmZlci5zdWJhcnJheSgwLCBkYXRhU2l6ZSkgYXMgRmxvYXQzMkFycmF5O1xuICB9XG59XG4vKipcbiAqIERhdGEgZW5jb2RlciBmb3IgV2ViR0wgMSB3aXRoIHN1cHBvcnQgZm9yIGZsb2F0aW5nIHBvaW50IHRleHR1cmVcbiAqL1xuZXhwb3J0IGNsYXNzIFJHQkFGbG9hdERhdGFFbmNvZGVyIGltcGxlbWVudHMgRGF0YUVuY29kZXIge1xuICBpbnRlcm5hbEZvcm1hdDogbnVtYmVyO1xuICBmb3JtYXQ6IG51bWJlcjtcbiAgdGV4dHVyZVR5cGU6IG51bWJlcjtcbiAgY2hhbm5lbFNpemU6IG51bWJlcjtcbiAgY29uc3RydWN0b3IoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgY2hhbm5lbHMgPSAxLCB0ZXh0dXJlVHlwZT86IG51bWJlcikge1xuICAgIGlmIChjaGFubmVscyAhPT0gMSAmJiBjaGFubmVscyAhPT0gNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIG51bWJlciBvZiBjaGFubmVsczogJHtjaGFubmVsc31gKTtcbiAgICB9XG4gICAgdGhpcy5pbnRlcm5hbEZvcm1hdCA9IGdsLlJHQkE7XG4gICAgdGhpcy5mb3JtYXQgPSBnbC5SR0JBO1xuICAgIHRoaXMuY2hhbm5lbFNpemUgPSBjaGFubmVscztcbiAgICB0aGlzLnRleHR1cmVUeXBlID0gdGV4dHVyZVR5cGUgfHwgZ2wuRkxPQVQ7XG4gIH1cbiAgZW5jb2RlKHNyYzogRmxvYXQzMkFycmF5LCB0ZXh0dXJlU2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICBsZXQgZGVzdCA9IHNyYztcbiAgICBpZiAodGhpcy5jaGFubmVsU2l6ZSA9PT0gMSkge1xuICAgICAgTG9nZ2VyLnZlcmJvc2UoJ0VuY29kZXInLCAnRXhwbG9kaW5nIGludG8gYSBsYXJnZXIgYXJyYXknKTtcbiAgICAgIGRlc3QgPSB0aGlzLmFsbG9jYXRlKHRleHR1cmVTaXplKSBhcyBGbG9hdDMyQXJyYXk7XG4gICAgICBzcmMuZm9yRWFjaCgodiwgaSkgPT4gKGRlc3RbaSAqIDRdID0gdikpO1xuICAgIH1cbiAgICByZXR1cm4gZGVzdDtcbiAgfVxuICBhbGxvY2F0ZShzaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUge1xuICAgIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KHNpemUgKiA0KTtcbiAgfVxuICBkZWNvZGUoYnVmZmVyOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUsIGRhdGFTaXplOiBudW1iZXIpOiBGbG9hdDMyQXJyYXkge1xuICAgIGlmICh0aGlzLmNoYW5uZWxTaXplID09PSAxKSB7XG4gICAgICBjb25zdCBmaWx0ZXJlZERhdGEgPSAoYnVmZmVyIGFzIEZsb2F0MzJBcnJheSkuZmlsdGVyKChfdmFsdWUsIGluZGV4KSA9PiBpbmRleCAlIDQgPT09IDApLnN1YmFycmF5KDAsIGRhdGFTaXplKTtcbiAgICAgIHJldHVybiBmaWx0ZXJlZERhdGE7XG4gICAgfVxuICAgIHJldHVybiBidWZmZXIuc3ViYXJyYXkoMCwgZGF0YVNpemUpIGFzIEZsb2F0MzJBcnJheTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgVWludDhEYXRhRW5jb2RlciBpbXBsZW1lbnRzIERhdGFFbmNvZGVyIHtcbiAgaW50ZXJuYWxGb3JtYXQ6IG51bWJlcjtcbiAgZm9ybWF0OiBudW1iZXI7XG4gIHRleHR1cmVUeXBlOiBudW1iZXI7XG4gIGNoYW5uZWxTaXplID0gNDtcbiAgY29uc3RydWN0b3IoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgY2hhbm5lbHMgPSAxKSB7XG4gICAgaWYgKGNoYW5uZWxzID09PSAxKSB7XG4gICAgICB0aGlzLmludGVybmFsRm9ybWF0ID0gZ2wuQUxQSEE7XG4gICAgICB0aGlzLmZvcm1hdCA9IGdsLkFMUEhBOyAvLyBub3QgdGVzdGVkXG4gICAgICB0aGlzLnRleHR1cmVUeXBlID0gZ2wuVU5TSUdORURfQllURTtcbiAgICAgIHRoaXMuY2hhbm5lbFNpemUgPSBjaGFubmVscztcbiAgICB9IGVsc2UgaWYgKGNoYW5uZWxzID09PSA0KSB7XG4gICAgICB0aGlzLmludGVybmFsRm9ybWF0ID0gZ2wuUkdCQTtcbiAgICAgIHRoaXMuZm9ybWF0ID0gZ2wuUkdCQTtcbiAgICAgIHRoaXMudGV4dHVyZVR5cGUgPSBnbC5VTlNJR05FRF9CWVRFO1xuICAgICAgdGhpcy5jaGFubmVsU2l6ZSA9IGNoYW5uZWxzO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgbnVtYmVyIG9mIGNoYW5uZWxzOiAke2NoYW5uZWxzfWApO1xuICAgIH1cbiAgfVxuICBlbmNvZGUoc3JjOiBVaW50OEFycmF5LCBfdGV4dHVyZVNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KHNyYy5idWZmZXIsIHNyYy5ieXRlT2Zmc2V0LCBzcmMuYnl0ZUxlbmd0aCk7XG4gIH1cbiAgYWxsb2NhdGUoc2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoc2l6ZSAqIHRoaXMuY2hhbm5lbFNpemUpO1xuICB9XG4gIGRlY29kZShidWZmZXI6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgZGF0YVNpemU6IG51bWJlcik6IFVpbnQ4QXJyYXkge1xuICAgIGlmIChidWZmZXIgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICByZXR1cm4gYnVmZmVyLnN1YmFycmF5KDAsIGRhdGFTaXplKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGFycmF5IHR5cGU6ICR7YnVmZmVyLmNvbnN0cnVjdG9yfWApO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5pbXBvcnQgeyBUZXh0dXJlTGF5b3V0U3RyYXRlZ3ksIFdpZHRoSGVpZ2h0UHJlZnMgfSBmcm9tICcuL3RleHR1cmUtbGF5b3V0LXN0cmF0ZWd5JztcbmltcG9ydCB7IFRleHR1cmVMYXlvdXQsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVRleHR1cmVUeXBlID0gKFxuICB0ZXh0dXJlTGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSxcbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUsXG4pOiBUZXh0dXJlTGF5b3V0ID0+IHtcbiAgY29uc3QgY2hhbm5lbCA9IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS51bnBhY2tlZCB8fCB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUudW5wYWNrZWRSZXZlcnNlZCA/IDEgOiA0O1xuICBjb25zdCBpc1BhY2tlZCA9IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQ7XG4gIGNvbnN0IHJldmVyc2VXSCA9IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS51bnBhY2tlZFJldmVyc2VkIHx8IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQ7XG4gIGNvbnN0IGJyZWFrQXhpcyA9IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uID8gc2hhcGUubGVuZ3RoIC0gMSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgdW5wYWNrZWRTaGFwZSA9XG4gICAgdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb25cbiAgICAgID8gc2hhcGUubWFwKChkLCBpKSA9PiAoaSA9PT0gc2hhcGUubGVuZ3RoIC0gMSA/IGQgKiA0IDogZCkpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgcmV0dXJuIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUodGV4dHVyZUxheW91dFN0cmF0ZWd5LCBzaGFwZSwgY2hhbm5lbCwgdW5wYWNrZWRTaGFwZSwge1xuICAgIGlzUGFja2VkLFxuICAgIHJldmVyc2VXSCxcbiAgICBicmVha0F4aXMsXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodCA9IChcbiAgdGV4dHVyZUxheW91dFN0cmF0ZWd5OiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3ksXG4gIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLFxuKTogW251bWJlciwgbnVtYmVyXSA9PiB7XG4gIGNvbnN0IGxheW91dCA9IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUodGV4dHVyZUxheW91dFN0cmF0ZWd5LCBzaGFwZSwgdGV4dHVyZVR5cGUpO1xuICByZXR1cm4gW2xheW91dC53aWR0aCwgbGF5b3V0LmhlaWdodF07XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIFRleHR1cmVMYXlvdXQgb2JqZWN0IGZyb20gc2hhcGUuXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVNoYXBlID0gKFxuICB0ZXh0dXJlTGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSxcbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBjaGFubmVsczogMSB8IDQgPSAxLFxuICB1bnBhY2tlZFNoYXBlPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHByZWZzPzogV2lkdGhIZWlnaHRQcmVmcyxcbik6IFRleHR1cmVMYXlvdXQgPT4ge1xuICBjb25zdCBpc1BhY2tlZCA9ICEhKHByZWZzICYmIHByZWZzLmlzUGFja2VkKTtcbiAgY29uc3QgW3dpZHRoLCBoZWlnaHRdID0gdGV4dHVyZUxheW91dFN0cmF0ZWd5LmNvbXB1dGVUZXh0dXJlV0goaXNQYWNrZWQgPyB1bnBhY2tlZFNoYXBlIHx8IHNoYXBlIDogc2hhcGUsIHByZWZzKTtcbiAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgbGV0IGluZmVycmVkRGltcyA9IHNoYXBlLnNsaWNlKDApO1xuICBpZiAocmFuayA9PT0gMCkge1xuICAgIGluZmVycmVkRGltcyA9IFsxXTtcbiAgfVxuICBpZiAoY2hhbm5lbHMgPT09IDEpIHtcbiAgICAvLyB1bnBhY2tlZFNoYXBlIHdpbGwgdGFrZSBgc2hhcGVgIGFuZCBub3QgYGluZmVycmVkRGltc2Agc28gYXMgdG8gY3JlYXRlIGEgc2NhbGFyIFRlbnNvciBpZiBuZWVkIGJlXG4gICAgdW5wYWNrZWRTaGFwZSA9IHNoYXBlO1xuICB9IGVsc2UgaWYgKGlzUGFja2VkKSB7XG4gICAgaWYgKGNoYW5uZWxzICE9PSA0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2EgcGFja2VkIHRleHR1cmUgbXVzdCBiZSA0LWNoYW5uZWwnKTtcbiAgICB9XG4gICAgdW5wYWNrZWRTaGFwZSA9IHNoYXBlO1xuICAgIGlmIChyYW5rID4gMCkge1xuICAgICAgaW5mZXJyZWREaW1zW3JhbmsgLSAxXSA9IE1hdGguY2VpbChpbmZlcnJlZERpbXNbcmFuayAtIDFdIC8gMik7XG4gICAgfVxuICAgIGlmIChyYW5rID4gMSkge1xuICAgICAgaW5mZXJyZWREaW1zW3JhbmsgLSAyXSA9IE1hdGguY2VpbChpbmZlcnJlZERpbXNbcmFuayAtIDJdIC8gMik7XG4gICAgfVxuICB9IGVsc2UgaWYgKCF1bnBhY2tlZFNoYXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnBhY2tlZCBzaGFwZSBpcyBuZWVkZWQgd2hlbiB1c2luZyBjaGFubmVscyA+IDEnKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIHdpZHRoLFxuICAgIGhlaWdodCxcbiAgICBjaGFubmVscyxcbiAgICBpc1BhY2tlZCxcbiAgICBzaGFwZTogaW5mZXJyZWREaW1zLFxuICAgIHN0cmlkZXM6IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhpbmZlcnJlZERpbXMpLFxuICAgIHVucGFja2VkU2hhcGUsXG4gICAgcmV2ZXJzZWRXSDogcHJlZnMgJiYgcHJlZnMucmV2ZXJzZVdILFxuICB9O1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uLy4uL2JhY2tlbmQnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmltcG9ydCB7IGNyZWF0ZVBhY2tQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vb3BzL3BhY2snO1xuaW1wb3J0IHsgY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbUluZm9Mb2FkZXIsIGlzUmVzaGFwZUNoZWFwLCBwcm9jZXNzRGltczNEIH0gZnJvbSAnLi9vcHMvcmVzaGFwZS1wYWNrZWQnO1xuaW1wb3J0IHsgZW5jb2RlQXNVaW50OCB9IGZyb20gJy4vb3BzL3VpbnQ4LWVuY29kZSc7XG5pbXBvcnQgeyBjcmVhdGVVbnBhY2tQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vb3BzL3VucGFjayc7XG5pbXBvcnQgeyBXZWJHTFNlc3Npb25IYW5kbGVyIH0gZnJvbSAnLi9zZXNzaW9uLWhhbmRsZXInO1xuaW1wb3J0IHsgRW5jb2RlclVzYWdlIH0gZnJvbSAnLi90ZXh0dXJlLWRhdGEtZW5jb2Rlcic7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQsXG4gIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUsXG4gIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUsXG59IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQnO1xuaW1wb3J0IHsgQXJ0aWZhY3QsIFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgVGV4dHVyZURhdGEsIFRleHR1cmVMYXlvdXQsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi90eXBlcyc7XG5cbmNvbnN0IGdldFByb2dyYW1JbmZvVW5pcXVlS2V5ID0gKFxuICBwcm9ncmFtSW5mbzogUHJvZ3JhbUluZm8gfCBQcm9ncmFtSW5mb0xvYWRlcixcbiAgaW5wdXRUZXh0dXJlRGF0YXM6IFRleHR1cmVEYXRhW10sXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBpbnB1dHMgPSBpbnB1dFRleHR1cmVEYXRhc1xuICAgIC5tYXAoKHRleHR1cmUpID0+IGAke3RleHR1cmUudW5wYWNrZWRTaGFwZS5qb2luKCcsJyl9OyR7dGV4dHVyZS53aWR0aH14JHt0ZXh0dXJlLmhlaWdodH1gKVxuICAgIC5qb2luKCdfJyk7XG4gIGxldCBrZXkgPSBwcm9ncmFtSW5mby5uYW1lO1xuICBpZiAocHJvZ3JhbUluZm8uY2FjaGVIaW50KSB7XG4gICAga2V5ICs9ICdbJyArIHByb2dyYW1JbmZvLmNhY2hlSGludCArICddJztcbiAgfVxuICBrZXkgKz0gJzonICsgaW5wdXRzO1xuICByZXR1cm4ga2V5O1xufTtcblxuZXhwb3J0IGNsYXNzIFdlYkdMSW5mZXJlbmNlSGFuZGxlciBpbXBsZW1lbnRzIEluZmVyZW5jZUhhbmRsZXIge1xuICBwcml2YXRlIHBhY2tlZFRleHR1cmVEYXRhQ2FjaGU6IE1hcDxUZW5zb3IuSWQsIFRleHR1cmVEYXRhPjtcbiAgcHJpdmF0ZSB1bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGU6IE1hcDxUZW5zb3IuSWQsIFRleHR1cmVEYXRhPjtcbiAgY29uc3RydWN0b3IocHVibGljIHNlc3Npb246IFdlYkdMU2Vzc2lvbkhhbmRsZXIpIHtcbiAgICB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMgW3dpZHRoLCBoZWlnaHRdXG4gICAqL1xuICBjYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICByZXR1cm4gY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KHRoaXMuc2Vzc2lvbi5sYXlvdXRTdHJhdGVneSwgc2hhcGUsIHRleHR1cmVUeXBlKTtcbiAgfVxuXG4gIGV4ZWN1dGVQcm9ncmFtKHByb2dyYW06IFByb2dyYW1JbmZvIHwgUHJvZ3JhbUluZm9Mb2FkZXIsIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10pOiBUZXh0dXJlRGF0YSB7XG4gICAgaWYgKGlucHV0cy5sZW5ndGggPCBwcm9ncmFtLmlucHV0TmFtZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYElucHV0IHNpemUgbXVzdG4ndCBiZSBsZXNzIHRoYW4gJHtwcm9ncmFtLmlucHV0TmFtZXMubGVuZ3RofS5gKTtcbiAgICB9XG4gICAgaWYgKHByb2dyYW0uaW5wdXROYW1lcy5sZW5ndGggIT09IHByb2dyYW0uaW5wdXRUeXBlcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgbmFtZXMgc2l6ZSBkb2VzIG5vdCBtYXRjaCBpbnB1dCB0eXBlcycpO1xuICAgIH1cblxuICAgIC8vIGNyZWF0ZSB0ZXh0dXJlIGluZm8gZm9yIGlucHV0XG4gICAgY29uc3QgaW5wdXRUZXh0dXJlRGF0YXM6IFRleHR1cmVEYXRhW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb2dyYW0uaW5wdXROYW1lcy5sZW5ndGg7ICsraSkge1xuICAgICAgaW5wdXRUZXh0dXJlRGF0YXNbaV0gPSB0aGlzLmdldE9yQ3JlYXRlVGV4dHVyZURhdGEoaW5wdXRzW2ldLCBwcm9ncmFtLmlucHV0VHlwZXNbaV0pO1xuICAgIH1cblxuICAgIGNvbnN0IGtleSA9IGdldFByb2dyYW1JbmZvVW5pcXVlS2V5KHByb2dyYW0sIGlucHV0VGV4dHVyZURhdGFzKTtcbiAgICBsZXQgYXJ0aWZhY3QgPSB0aGlzLnNlc3Npb24ucHJvZ3JhbU1hbmFnZXIuZ2V0QXJ0aWZhY3Qoa2V5KTtcbiAgICBjb25zdCBwcm9ncmFtSW5mbyA9IGFydGlmYWN0XG4gICAgICA/IGFydGlmYWN0LnByb2dyYW1JbmZvXG4gICAgICA6IHR5cGVvZiAocHJvZ3JhbSBhcyBQcm9ncmFtSW5mb0xvYWRlcikuZ2V0ID09PSAnZnVuY3Rpb24nXG4gICAgICAgID8gKHByb2dyYW0gYXMgUHJvZ3JhbUluZm9Mb2FkZXIpLmdldCgpXG4gICAgICAgIDogKHByb2dyYW0gYXMgUHJvZ3JhbUluZm8pO1xuXG4gICAgLy8gY3JlYXRlIHRleHR1cmUgaW5mbyBmb3Igb3V0cHV0XG4gICAgY29uc3Qgb3V0cHV0VGV4dHVyZUxheW91dCA9IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUoXG4gICAgICB0aGlzLnNlc3Npb24ubGF5b3V0U3RyYXRlZ3ksXG4gICAgICBwcm9ncmFtSW5mby5vdXRwdXQuZGltcyxcbiAgICAgIHByb2dyYW1JbmZvLm91dHB1dC50ZXh0dXJlVHlwZSxcbiAgICApO1xuICAgIGNvbnN0IG91dHB1dFRleHR1cmVEYXRhID0gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YShvdXRwdXRUZXh0dXJlTGF5b3V0LCBwcm9ncmFtSW5mby5vdXRwdXQudHlwZSk7XG5cbiAgICBpZiAoIWFydGlmYWN0KSB7XG4gICAgICBhcnRpZmFjdCA9IHRoaXMuc2Vzc2lvbi5wcm9ncmFtTWFuYWdlci5idWlsZChwcm9ncmFtSW5mbywgaW5wdXRUZXh0dXJlRGF0YXMsIG91dHB1dFRleHR1cmVEYXRhKTtcbiAgICAgIHRoaXMuc2Vzc2lvbi5wcm9ncmFtTWFuYWdlci5zZXRBcnRpZmFjdChrZXksIGFydGlmYWN0KTtcbiAgICB9XG5cbiAgICB0aGlzLnJ1blByb2dyYW0oYXJ0aWZhY3QsIGlucHV0VGV4dHVyZURhdGFzLCBvdXRwdXRUZXh0dXJlRGF0YSk7XG4gICAgcmV0dXJuIG91dHB1dFRleHR1cmVEYXRhO1xuICB9XG5cbiAgcnVuKHByb2dyYW06IFByb2dyYW1JbmZvTG9hZGVyLCBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdKTogVGVuc29yIHtcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlRGF0YSA9IHRoaXMuZXhlY3V0ZVByb2dyYW0ocHJvZ3JhbSwgaW5wdXRzKTtcbiAgICByZXR1cm4gb3V0cHV0VGV4dHVyZURhdGEudGVuc29yO1xuICB9XG5cbiAgcHJpdmF0ZSBydW5Qcm9ncmFtKGFydGlmYWN0OiBBcnRpZmFjdCwgaW5wdXRzOiBUZXh0dXJlRGF0YVtdLCBvdXRwdXQ6IFRleHR1cmVEYXRhKTogdm9pZCB7XG4gICAgLy8gaW5wdXQgc2hvdWxkIG1hdGNoXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dHMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmICghIWlucHV0c1tpXS5pc1BhY2tlZCAhPT0gKGFydGlmYWN0LnByb2dyYW1JbmZvLmlucHV0VHlwZXNbaV0gPT09IFRleHR1cmVUeXBlLnBhY2tlZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dFske2l9XSBwcm9wZXJ0eSBwYWNrZWQgaW5jb25zaXN0ZW50YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gb3V0cHV0IHNob3VsZCBtYXRjaFxuICAgIGlmICghIW91dHB1dC5pc1BhY2tlZCAhPT0gKGFydGlmYWN0LnByb2dyYW1JbmZvLm91dHB1dC50ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdvdXRwdXQgcHJvcGVydHkgcGFja2VkIGluY29uc2lzdGVudCcpO1xuICAgIH1cblxuICAgIHRoaXMuc2Vzc2lvbi5wcm9ncmFtTWFuYWdlci5ydW4oYXJ0aWZhY3QsIGlucHV0cywgb3V0cHV0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBUZXh0dXJlRGF0YSBvYmplY3QgZnJvbSBhIHRlbnNvci5cbiAgICogVXNhZ2UgPSBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seS5cbiAgICogSWYgYSByZWxhdGVkIHRleHR1cmUgZGF0YSBpcyBmb3VuZCBpbiBjYWNoZSwgcmV0dXJucyBpdDtcbiAgICogT3RoZXJ3aXNlOlxuICAgKiAgIENyZWF0ZXMgYSBuZXcgdGV4dHVyZSBsYXlvdXQgaWYgbm90IHByb3ZpZGVkO1xuICAgKiAgIENyZWF0ZXMgV2ViR0xUZXh0dXJlIHdpdGggdGhlIGxheW91dDtcbiAgICogICBVcGxvYWQgdGVuc29yIGRhdGEgdG8gdGhlIHRleHR1cmU7XG4gICAqICAgQ3JlYXRlcyBhIHRleHR1cmUgZGF0YSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiB0ZW5zb3IuXG4gICAqIEBwYXJhbSB0ZW5zb3IgdGhlIHRlbnNvciB3aXRoIGRhdGEgdG8gdXBsb2FkXG4gICAqL1xuICBwcml2YXRlIGdldE9yQ3JlYXRlVGV4dHVyZURhdGEodGVuc29yOiBUZW5zb3IsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZSkge1xuICAgIGxldCB0ZCA9IHRoaXMuZ2V0VGV4dHVyZURhdGEodGVuc29yLmRhdGFJZCwgdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZCk7XG5cbiAgICBpZiAoIXRkKSB7XG4gICAgICAvLyBjaGVjayBpZiB3ZSBoYXZlIHRleHR1cmUgZGF0YSBpbiBkaWZmZXJlbnQgdHlwZVxuICAgICAgdGQgPSB0aGlzLmdldFRleHR1cmVEYXRhKHRlbnNvci5kYXRhSWQsIHRleHR1cmVUeXBlICE9PSBUZXh0dXJlVHlwZS5wYWNrZWQpO1xuICAgICAgaWYgKHRkKSB7XG4gICAgICAgIGlmICh0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucGFjayh0ZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudW5wYWNrKHRkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdGQpIHtcbiAgICAgIGNvbnN0IGxheW91dCA9IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUodGhpcy5zZXNzaW9uLmxheW91dFN0cmF0ZWd5LCB0ZW5zb3IuZGltcywgdGV4dHVyZVR5cGUpO1xuXG4gICAgICBpZiAodGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24pIHtcbiAgICAgICAgY29uc3QgZ3JvdXAgPSAxO1xuICAgICAgICBjb25zdCBjaGFubmVscyA9IDQ7XG4gICAgICAgIGNvbnN0IHNoYXBlID0gdGVuc29yLmRpbXM7XG4gICAgICAgIGlmIChzaGFwZS5sZW5ndGggPT09IDQpIHtcbiAgICAgICAgICAvLyBwcmUtcHJvY2Vzc2luZyBmb3Iga2VybmVsIGRhdGEgb2YgQ29udi5cbiAgICAgICAgICAvL1xuICAgICAgICAgIC8vIFRPRE86IGN1cnJlbnRseSB0aGlzIGlzIGEgaGFja2luZyB0byBvdmVyd3JpdGUgQ29udidzIHdlaWdodC4gVGhlIGNvcnJlY3Qgd2F5IHRvIGRvIHRoaXMgc2hvdWxkIGJlOlxuICAgICAgICAgIC8vIDEuIGltcGxlbWVudCB0ZXh0dXJlIGJhc2VkIGNvbnN0LWZvbGRpbmdcbiAgICAgICAgICAvLyAyLiBjcmVhdGUgYSBXZWJHTCBwcm9ncmFtIFwicHJlcHJvY2Vzc0NvbnZXZWlnaHRcIiB0byBkbyB0aGUgc2FtZSB3b3JrIGFzIGJlbG93XG4gICAgICAgICAgLy8gMy4gcnVuIHRoZSBwcm9ncmFtIGJlZm9yZSBkb3RQcm9kdWN0LlxuICAgICAgICAgIC8vXG4gICAgICAgICAgY29uc3QgYWRqdXN0ZWRLZXJuZWxTaGFwZSA9IFtzaGFwZVswXSwgTWF0aC5jZWlsKChzaGFwZVsxXSAqIHNoYXBlWzJdICogc2hhcGVbM10pIC8gY2hhbm5lbHMpXTtcbiAgICAgICAgICBjb25zdCBhZGp1c3RlZExheW91dCA9IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUoXG4gICAgICAgICAgICB0aGlzLnNlc3Npb24ubGF5b3V0U3RyYXRlZ3ksXG4gICAgICAgICAgICBhZGp1c3RlZEtlcm5lbFNoYXBlLFxuICAgICAgICAgICAgdGV4dHVyZVR5cGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBsZXQgYnVmZmVyID0gdGVuc29yLm51bWJlckRhdGE7XG4gICAgICAgICAgaWYgKChzaGFwZVsxXSAqIHNoYXBlWzJdICogc2hhcGVbM10pICUgY2hhbm5lbHMgIT09IDApIHtcbiAgICAgICAgICAgIGNvbnN0IG51bUZlYXR1cmVNYXBzID0gc2hhcGVbMF07XG4gICAgICAgICAgICBjb25zdCBvbGRSb3dTaXplID0gc2hhcGVbMV0gKiBzaGFwZVsyXSAqIHNoYXBlWzNdO1xuICAgICAgICAgICAgY29uc3QgbmV3Um93U2l6ZSA9IE1hdGguY2VpbCgob2xkUm93U2l6ZSAqIGdyb3VwKSAvIGNoYW5uZWxzKSAqIGNoYW5uZWxzO1xuICAgICAgICAgICAgY29uc3QgbmV3U2l6ZSA9IG51bUZlYXR1cmVNYXBzICogbmV3Um93U2l6ZTtcbiAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkobmV3U2l6ZSk7XG4gICAgICAgICAgICBmb3IgKGxldCBmID0gMDsgZiA8IG51bUZlYXR1cmVNYXBzOyArK2YpIHtcbiAgICAgICAgICAgICAgY29uc3Qgb2xkT2Zmc2V0ID0gZiAqIG9sZFJvd1NpemU7XG4gICAgICAgICAgICAgIGNvbnN0IG5ld09mZnNldCA9IGYgKiBuZXdSb3dTaXplICsgKGYgJSBncm91cCkgKiBvbGRSb3dTaXplO1xuICAgICAgICAgICAgICBidWZmZXIuc2V0KHRlbnNvci5udW1iZXJEYXRhLnN1YmFycmF5KG9sZE9mZnNldCwgb2xkT2Zmc2V0ICsgb2xkUm93U2l6ZSksIG5ld09mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhKGFkanVzdGVkTGF5b3V0LCB0ZW5zb3IudHlwZSwgYnVmZmVyLCB0ZW5zb3IsIEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZCkge1xuICAgICAgICBjb25zdCB1bnBhY2tlZFRleHR1cmVMYXlvdXQgPSBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVNoYXBlKHRoaXMuc2Vzc2lvbi5sYXlvdXRTdHJhdGVneSwgdGVuc29yLmRpbXMsIDEsIFtdLCB7XG4gICAgICAgICAgcmV2ZXJzZVdIOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgdW5wYWNrZWRUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGEoXG4gICAgICAgICAgdW5wYWNrZWRUZXh0dXJlTGF5b3V0LFxuICAgICAgICAgIHRlbnNvci50eXBlLFxuICAgICAgICAgIHRlbnNvci5udW1iZXJEYXRhLFxuICAgICAgICAgIHRlbnNvcixcbiAgICAgICAgICBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSxcbiAgICAgICAgKTtcbiAgICAgICAgdGQgPSB0aGlzLnBhY2sodW5wYWNrZWRUZXh0dXJlRGF0YSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZCA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGEobGF5b3V0LCB0ZW5zb3IudHlwZSwgdGVuc29yLm51bWJlckRhdGEsIHRlbnNvciwgRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGQ7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgVGV4dHVyZURhdGEgb2JqZWN0IHVzaW5nIHRoZSBnaXZlbiBkYXRhIGFuZCBiaW5kIHRvIHRoZSBnaXZlbiB0ZW5zb3IuXG4gICAqIFVzYWdlID0gRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkuXG4gICAqIE5PVEU6IHRoaXMgZnVuY3Rpb24gaXMgYSBoYWNrIGZvciBDb252IGltcGxlbWVudGF0aW9uLiBzaG91bGQgcmVtb3ZlIHRoaXMgZnVuY3Rpb24sIGFmdGVyIHJld3JpdGluZyBDb252XG4gICAqIGltcGxlbWVudGF0aW9uIGJ5IEdyYXBoLlRyYW5zZm9ybWVyXG4gICAqIEBwYXJhbSBkYXRhVHlwZSB0aGUgdGVuc29yIGRhdGEgdHlwZVxuICAgKiBAcGFyYW0gZGF0YSB0aGUgYWN0dWFsIGRhdGEgdG8gdXBsb2FkXG4gICAqIEBwYXJhbSB0ZW5zb3IgdGhlIHRlbnNvciB0byBiaW5kLiB0ZW5zb3IncyBkYXRhIGlzIGlnbm9yZWQuXG4gICAqL1xuICBjcmVhdGVUZXh0dXJlRGF0YUZyb21MYXlvdXRCaW5kVGVuc29yKFxuICAgIGxheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLFxuICAgIGRhdGE6IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHRlbnNvcjogVGVuc29yLFxuICApOiBUZXh0dXJlRGF0YSB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlVGV4dHVyZURhdGEobGF5b3V0LCBkYXRhVHlwZSwgZGF0YSwgdGVuc29yLCBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVRleHR1cmVEYXRhKFxuICAgIGxheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLFxuICAgIGRhdGE/OiBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICB0ZW5zb3I/OiBUZW5zb3IsXG4gICAgdXNhZ2U/OiBFbmNvZGVyVXNhZ2UsXG4gICk6IFRleHR1cmVEYXRhIHtcbiAgICBMb2dnZXIudmVyYm9zZSgnSW5mZXJlbmNlSGFuZGxlcicsIGBDcmVhdGluZyBUZXh0dXJlRGF0YTogbGF5b3V0Olske0pTT04uc3RyaW5naWZ5KGxheW91dCl9XWApO1xuICAgIGNvbnN0IHRleHR1cmUgPSB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIuY3JlYXRlVGV4dHVyZUZyb21MYXlvdXQoZGF0YVR5cGUsIGxheW91dCwgZGF0YSwgdXNhZ2UpO1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhRnJvbVRleHR1cmUobGF5b3V0LCBkYXRhVHlwZSwgdGV4dHVyZSwgdGVuc29yKTtcbiAgfVxuXG4gIHJlc2hhcGVVbnBhY2tlZChpbnB1dDogVGVuc29yLCByZXNoYXBlZERpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yIHtcbiAgICBjb25zdCBpbnB1dFREID0gdGhpcy5nZXRPckNyZWF0ZVRleHR1cmVEYXRhKGlucHV0LCBUZXh0dXJlVHlwZS51bnBhY2tlZCk7XG4gICAgY29uc3QgbmV3VGV4dHVyZUxheW91dDogVGV4dHVyZUxheW91dCA9IHtcbiAgICAgIGNoYW5uZWxzOiBpbnB1dFRELmNoYW5uZWxzLFxuICAgICAgaGVpZ2h0OiBpbnB1dFRELmhlaWdodCxcbiAgICAgIHdpZHRoOiBpbnB1dFRELndpZHRoLFxuICAgICAgLy8gaGFuZGxlIHJlc2hhcGluZyBpbnRvIHNjYWxhciBUZW5zb3JzXG4gICAgICBzaGFwZTogcmVzaGFwZWREaW1zLmxlbmd0aCAhPT0gMCA/IHJlc2hhcGVkRGltcyA6IFsxXSxcbiAgICAgIHN0cmlkZXM6IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhyZXNoYXBlZERpbXMpLFxuICAgICAgdW5wYWNrZWRTaGFwZTogcmVzaGFwZWREaW1zLFxuICAgIH07XG4gICAgY29uc3QgbmV3VGV4dHVyZURhdGEgPSB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhRnJvbVRleHR1cmUobmV3VGV4dHVyZUxheW91dCwgaW5wdXQudHlwZSwgaW5wdXRURC50ZXh0dXJlKTtcbiAgICByZXR1cm4gbmV3VGV4dHVyZURhdGEudGVuc29yO1xuICB9XG5cbiAgcmVzaGFwZVBhY2tlZChpbnB1dDogVGVuc29yLCByZXNoYXBlZERpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yIHtcbiAgICBjb25zdCBpbnB1dFREID0gdGhpcy5nZXRPckNyZWF0ZVRleHR1cmVEYXRhKGlucHV0LCBUZXh0dXJlVHlwZS5wYWNrZWQpO1xuXG4gICAgLy8gY2hlY2sgaWYgdGhlIHJlc2hhcGUgaXMgJ2NoZWFwJ1xuICAgIGlmIChpc1Jlc2hhcGVDaGVhcChpbnB1dC5kaW1zLCByZXNoYXBlZERpbXMpKSB7XG4gICAgICBjb25zdCBuZXdUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0ge1xuICAgICAgICBjaGFubmVsczogaW5wdXRURC5jaGFubmVscyxcbiAgICAgICAgaGVpZ2h0OiBpbnB1dFRELmhlaWdodCxcbiAgICAgICAgd2lkdGg6IGlucHV0VEQud2lkdGgsXG4gICAgICAgIC8vIGhhbmRsZSByZXNoYXBpbmcgaW50byBzY2FsYXIgVGVuc29yc1xuICAgICAgICBzaGFwZTogcmVzaGFwZWREaW1zLmxlbmd0aCAhPT0gMCA/IHJlc2hhcGVkRGltcyA6IFsxXSxcbiAgICAgICAgc3RyaWRlczogU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKHJlc2hhcGVkRGltcyksXG4gICAgICAgIHVucGFja2VkU2hhcGU6IHJlc2hhcGVkRGltcyxcbiAgICAgICAgaXNQYWNrZWQ6IHRydWUsXG4gICAgICB9O1xuICAgICAgY29uc3QgbmV3VGV4dHVyZURhdGEgPSB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhRnJvbVRleHR1cmUobmV3VGV4dHVyZUxheW91dCwgaW5wdXQudHlwZSwgaW5wdXRURC50ZXh0dXJlKTtcbiAgICAgIHJldHVybiBuZXdUZXh0dXJlRGF0YS50ZW5zb3I7XG4gICAgfVxuXG4gICAgY29uc3Qgc3F1ZWV6ZWRJbnB1dFNoYXBlID0gcHJvY2Vzc0RpbXMzRChpbnB1dC5kaW1zKTtcbiAgICBjb25zdCBzcXVlZXplZE91dHB1dFNoYXBlID0gcHJvY2Vzc0RpbXMzRChyZXNoYXBlZERpbXMpO1xuXG4gICAgY29uc3Qgc3F1ZWV6ZWRJbnB1dFRlbnNvciA9IHRoaXMucmVzaGFwZVBhY2tlZChpbnB1dCwgc3F1ZWV6ZWRJbnB1dFNoYXBlKTtcbiAgICBjb25zdCBzcXVlZXplZE91dHB1dFRlbnNvciA9IHRoaXMucnVuKFxuICAgICAgY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbUluZm9Mb2FkZXIodGhpcywgc3F1ZWV6ZWRJbnB1dFRlbnNvciwgc3F1ZWV6ZWRPdXRwdXRTaGFwZSksXG4gICAgICBbc3F1ZWV6ZWRJbnB1dFRlbnNvcl0sXG4gICAgKTtcbiAgICBjb25zdCBvdXRwdXRUZW5zb3IgPSB0aGlzLnJlc2hhcGVQYWNrZWQoc3F1ZWV6ZWRPdXRwdXRUZW5zb3IsIHJlc2hhcGVkRGltcyk7XG4gICAgcmV0dXJuIG91dHB1dFRlbnNvcjtcbiAgfVxuXG4gIGNhc3QoaW5wdXQ6IFRlbnNvciwgdHlwZTogVGVuc29yLkRhdGFUeXBlKTogVGVuc29yIHtcbiAgICBjb25zdCBpbnB1dFREID0gdGhpcy5nZXRPckNyZWF0ZVRleHR1cmVEYXRhKGlucHV0LCBUZXh0dXJlVHlwZS51bnBhY2tlZCk7XG4gICAgY29uc3QgbmV3VGV4dHVyZURhdGEgPSB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhRnJvbVRleHR1cmUoaW5wdXRURCBhcyBUZXh0dXJlTGF5b3V0LCB0eXBlLCBpbnB1dFRELnRleHR1cmUpO1xuICAgIHJldHVybiBuZXdUZXh0dXJlRGF0YS50ZW5zb3I7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVRleHR1cmVEYXRhRnJvbVRleHR1cmUoXG4gICAgbGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsXG4gICAgdGV4dHVyZTogV2ViR0xUZXh0dXJlLFxuICAgIHRlbnNvcj86IFRlbnNvcixcbiAgICB0ZW5zb3JJZD86IFRlbnNvci5JZCxcbiAgKSB7XG4gICAgY29uc3QgdGV4dHVyZURhdGE6IFRleHR1cmVEYXRhID0ge1xuICAgICAgLi4ubGF5b3V0LFxuICAgICAgdGVuc29yOlxuICAgICAgICB0ZW5zb3IgfHxcbiAgICAgICAgbmV3IFRlbnNvcihcbiAgICAgICAgICBsYXlvdXQudW5wYWNrZWRTaGFwZSxcbiAgICAgICAgICBkYXRhVHlwZSxcbiAgICAgICAgICAoX2lkOiBUZW5zb3IuSWQpID0+IHRoaXMucmVhZFRleHR1cmUodGV4dHVyZURhdGEpLFxuICAgICAgICAgIGFzeW5jIChfaWQ6IFRlbnNvci5JZCkgPT4gdGhpcy5yZWFkVGV4dHVyZUFzeW5jKHRleHR1cmVEYXRhKSxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgdGVuc29ySWQsXG4gICAgICAgICksXG4gICAgICB0ZXh0dXJlLFxuICAgIH07XG4gICAgdGhpcy5zZXRUZXh0dXJlRGF0YSh0ZXh0dXJlRGF0YS50ZW5zb3IuZGF0YUlkLCB0ZXh0dXJlRGF0YSwgbGF5b3V0LmlzUGFja2VkKTtcbiAgICByZXR1cm4gdGV4dHVyZURhdGE7XG4gIH1cblxuICBwcml2YXRlIGdldFRleHR1cmVEYXRhKHRlbnNvcklkOiBUZW5zb3IuSWQsIGlzUGFja2VkID0gZmFsc2UpOiBUZXh0dXJlRGF0YSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvbi5pc0luaXRpYWxpemVyKHRlbnNvcklkKVxuICAgICAgPyB0aGlzLnNlc3Npb24uZ2V0VGV4dHVyZURhdGEodGVuc29ySWQsIGlzUGFja2VkKVxuICAgICAgOiBpc1BhY2tlZFxuICAgICAgICA/IHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5nZXQodGVuc29ySWQpXG4gICAgICAgIDogdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZ2V0KHRlbnNvcklkKTtcbiAgfVxuICBzZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZDogVGVuc29yLklkLCB0ZDogVGV4dHVyZURhdGEsIGlzUGFja2VkID0gZmFsc2UpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIodGVuc29ySWQpKSB7XG4gICAgICB0aGlzLnNlc3Npb24uc2V0VGV4dHVyZURhdGEodGVuc29ySWQsIHRkLCBpc1BhY2tlZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIChpc1BhY2tlZCA/IHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA6IHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlKS5zZXQodGVuc29ySWQsIHRkKTtcbiAgICB9XG4gIH1cbiAgaXNUZXh0dXJlTGF5b3V0Q2FjaGVkKHRlbnNvcjogVGVuc29yLCBpc1BhY2tlZCA9IGZhbHNlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5nZXRUZXh0dXJlRGF0YSh0ZW5zb3IuZGF0YUlkLCBpc1BhY2tlZCk7XG4gIH1cblxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5jbGVhckFjdGl2ZVRleHR1cmVzKCk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmZvckVhY2goKHRkKSA9PiB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIucmVsZWFzZVRleHR1cmUodGQpKTtcbiAgICB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZm9yRWFjaCgodGQpID0+IHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCkpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICB9XG5cbiAgcmVhZFRleHR1cmUodGV4dHVyZURhdGE6IFRleHR1cmVEYXRhKTogVGVuc29yLk51bWJlclR5cGUge1xuICAgIGlmICh0ZXh0dXJlRGF0YS5pc1BhY2tlZCkge1xuICAgICAgcmV0dXJuIHRoaXMucmVhZFRleHR1cmUodGhpcy51bnBhY2sodGV4dHVyZURhdGEpKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQuaXNGbG9hdDMyRG93bmxvYWRTdXBwb3J0ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIucmVhZFVpbnQ4VGV4dHVyZUFzRmxvYXQoZW5jb2RlQXNVaW50OCh0aGlzLCB0ZXh0dXJlRGF0YSkpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlYWRUZXh0dXJlKHRleHR1cmVEYXRhLCB0ZXh0dXJlRGF0YS50ZW5zb3IudHlwZSwgdGV4dHVyZURhdGEuY2hhbm5lbHMpO1xuICB9XG5cbiAgYXN5bmMgcmVhZFRleHR1cmVBc3luYyh0ZXh0dXJlRGF0YTogVGV4dHVyZURhdGEpOiBQcm9taXNlPFRlbnNvci5OdW1iZXJUeXBlPiB7XG4gICAgaWYgKHRleHR1cmVEYXRhLmlzUGFja2VkKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWFkVGV4dHVyZUFzeW5jKHRoaXMudW5wYWNrKHRleHR1cmVEYXRhKSk7XG4gICAgfVxuICAgIGlmICghdGhpcy5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LmlzRmxvYXQzMkRvd25sb2FkU3VwcG9ydGVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlYWRVaW50OFRleHR1cmVBc0Zsb2F0KGVuY29kZUFzVWludDgodGhpcywgdGV4dHVyZURhdGEpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWFkVGV4dHVyZUFzeW5jKHRleHR1cmVEYXRhLCB0ZXh0dXJlRGF0YS50ZW5zb3IudHlwZSwgdGV4dHVyZURhdGEuY2hhbm5lbHMpO1xuICB9XG5cbiAgcGFjayhpbnB1dDogVGV4dHVyZURhdGEpOiBUZXh0dXJlRGF0YSB7XG4gICAgY29uc3Qgb3V0cHV0VGV4dHVyZURhdGEgPSB0aGlzLmV4ZWN1dGVQcm9ncmFtKGNyZWF0ZVBhY2tQcm9ncmFtSW5mb0xvYWRlcih0aGlzLCBpbnB1dC50ZW5zb3IpLCBbaW5wdXQudGVuc29yXSk7XG4gICAgcmV0dXJuIG91dHB1dFRleHR1cmVEYXRhO1xuICB9XG5cbiAgdW5wYWNrKGlucHV0OiBUZXh0dXJlRGF0YSk6IFRleHR1cmVEYXRhIHtcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlRGF0YSA9IHRoaXMuZXhlY3V0ZVByb2dyYW0oY3JlYXRlVW5wYWNrUHJvZ3JhbUluZm9Mb2FkZXIodGhpcywgaW5wdXQudGVuc29yKSwgW2lucHV0LnRlbnNvcl0pO1xuICAgIHJldHVybiBvdXRwdXRUZXh0dXJlRGF0YTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5jbGFzcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXlJbXBsIHtcbiAgY29uc3RydWN0b3IoYXR0cmlidXRlOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcywgYXR0cmlidXRlKTtcbiAgfVxuXG4gIHByaXZhdGUga2V5OiBzdHJpbmc7XG4gIHB1YmxpYyBnZXQgY2FjaGVLZXkoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMua2V5KSB7XG4gICAgICB0aGlzLmtleSA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMpXG4gICAgICAgIC5zb3J0KClcbiAgICAgICAgLm1hcCgobmFtZSkgPT4gYCR7KHRoaXMgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW25hbWVdfWApXG4gICAgICAgIC5qb2luKCc7Jyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmtleTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGNhY2hlS2V5OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgPSA8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHVua25vd24+PihcbiAgYXR0cmlidXRlOiBULFxuKTogVCAmIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSA9PiBuZXcgQXR0cmlidXRlV2l0aENhY2hlS2V5SW1wbChhdHRyaWJ1dGUpIGFzIHVua25vd24gYXMgVCAmIEF0dHJpYnV0ZVdpdGhDYWNoZUtleTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICBlcHNpbG9uOiBudW1iZXI7XG4gIG1vbWVudHVtOiBudW1iZXI7XG4gIHNwYXRpYWw6IG51bWJlcjtcbn1cblxuY29uc3QgYmF0Y2hOb3JtYWxpemF0aW9uUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnQmF0Y2hOb3JtYWxpemF0aW9uJyxcbiAgaW5wdXROYW1lczogWydBJywgJ1NjYWxlJywgJ0InLCAnTWVhbicsICdWYXJpYW5jZSddLFxuICBpbnB1dFR5cGVzOiBbXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gIF0sXG59O1xuXG5leHBvcnQgY29uc3QgYmF0Y2hOb3JtYWxpemF0aW9uOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLmJhdGNoTm9ybWFsaXphdGlvblByb2dyYW1NZXRhZGF0YSxcbiAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlQmF0Y2hOb3JtYWxpemF0aW9uUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBlcHNpbG9uID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdlcHNpbG9uJywgMWUtNSk7XG4gIGNvbnN0IG1vbWVudHVtID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtb21lbnR1bScsIDAuOSk7XG4gIGNvbnN0IHNwYXRpYWwgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdzcGF0aWFsJywgMSk7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBlcHNpbG9uLCBtb21lbnR1bSwgc3BhdGlhbCB9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZUJhdGNoTm9ybWFsaXphdGlvblByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgcmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcbiAgY29uc3QgW3NjYWxlV2lkdGgsIHNjYWxlSGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGlucHV0c1sxXS5kaW1zLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICApO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gIGZsb2F0IHByb2Nlc3MoaW50WyR7cmFua31dIGluZGljZXMpIHtcbiAgICB2ZWMyIHBvc2l0aW9uID0gb2Zmc2V0VG9Db29yZHMoaW5kaWNlc1sxXSwgJHtzY2FsZVdpZHRofSwgJHtzY2FsZUhlaWdodH0pO1xuICAgIGZsb2F0IHNjYWxlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KFNjYWxlLCBwb3NpdGlvbikpO1xuICAgIGZsb2F0IG1lYW4gPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oTWVhbiwgcG9zaXRpb24pKTtcbiAgICBmbG9hdCB2YXJpYW5jZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShWYXJpYW5jZSwgcG9zaXRpb24pKTtcbiAgICBmbG9hdCBiID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEIsIHBvc2l0aW9uKSk7XG5cbiAgICByZXR1cm4gc2NhbGUgKiAoIChfQShpbmRpY2VzKSAtIG1lYW4pIC8gc3FydCh2YXJpYW5jZSArIGZsb2F0KCR7YXR0cmlidXRlcy5lcHNpbG9ufSkpICkgKyBiO1xuICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5iYXRjaE5vcm1hbGl6YXRpb25Qcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IGlucHV0c1swXS5kaW1zLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSA1KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdCYXRjaE5vcm1hbGl6YXRpb24gcmVxdWlyZXMgNSBpbnB1dHMuJyk7XG4gIH1cblxuICBjb25zdCBYID0gaW5wdXRzWzBdO1xuICBjb25zdCBzY2FsZSA9IGlucHV0c1sxXTtcbiAgY29uc3QgQiA9IGlucHV0c1syXTtcbiAgY29uc3QgbWVhbiA9IGlucHV0c1szXTtcbiAgY29uc3QgdmFyXyA9IGlucHV0c1s0XTtcblxuICAvLyBpbnB1dCBzaG91bGQgYXRsZWFzdCBoYXZlIHRocmVlIGRpbWVuc2lvbnMgLSBOLEMsZGltMSwuLi4sZGltblxuICAvLyBvdGhlciBpbnB1dHMgY2FuIGhhdmUgb25seSBvbmUgZGltZW5zaW9uc1xuICBpZiAoXG4gICAgWC5kaW1zLmxlbmd0aCA8IDMgfHxcbiAgICBzY2FsZS5kaW1zLmxlbmd0aCAhPT0gMSB8fFxuICAgIEIuZGltcy5sZW5ndGggIT09IDEgfHxcbiAgICBtZWFuLmRpbXMubGVuZ3RoICE9PSAxIHx8XG4gICAgdmFyXy5kaW1zLmxlbmd0aCAhPT0gMVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKFxuICAgIHNjYWxlLmRpbXNbMF0gIT09IFguZGltc1sxXSB8fFxuICAgIEIuZGltc1swXSAhPT0gWC5kaW1zWzFdIHx8XG4gICAgbWVhbi5kaW1zWzBdICE9PSBYLmRpbXNbMV0gfHxcbiAgICB2YXJfLmRpbXNbMF0gIT09IFguZGltc1sxXVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKFxuICAgIChYLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBYLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAoc2NhbGUudHlwZSAhPT0gJ2Zsb2F0MzInICYmIHNjYWxlLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAoQi50eXBlICE9PSAnZmxvYXQzMicgJiYgQi50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKG1lYW4udHlwZSAhPT0gJ2Zsb2F0MzInICYmIG1lYW4udHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgICh2YXJfLnR5cGUgIT09ICdmbG9hdDMyJyAmJiB2YXJfLnR5cGUgIT09ICdmbG9hdDY0JylcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHRlbnNvciB0eXBlcy4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVMYXlvdXQgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IFdlYkdMQ29udGV4dCB9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiAqL1xuZXhwb3J0IGVudW0gRnVuY3Rpb25UeXBlIHtcbiAgVmFsdWVCYXNlZCxcbiAgUG9zaXRpb25hbCxcbn1cbmV4cG9ydCBpbnRlcmZhY2UgR2xzbEZ1bmN0aW9uPFQgZXh0ZW5kcyBGdW5jdGlvblR5cGU+IHtcbiAgYm9keTogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIHR5cGU6IFQ7XG59XG5leHBvcnQgdHlwZSBHbHNsVmFsdWVGdW5jdGlvbiA9IEdsc2xGdW5jdGlvbjxGdW5jdGlvblR5cGUuVmFsdWVCYXNlZD47XG5leHBvcnQgaW50ZXJmYWNlIEdsc2xQb3NpdGlvbmFsRnVuY3Rpb24gZXh0ZW5kcyBHbHNsRnVuY3Rpb248RnVuY3Rpb25UeXBlLlBvc2l0aW9uYWw+IHtcbiAgaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGNsYXNzIEdsc2xDb250ZXh0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGdsQ29udGV4dDogV2ViR0xDb250ZXh0LFxuICAgIHB1YmxpYyBwcm9ncmFtSW5mbzogUHJvZ3JhbUluZm8sXG4gICAgcHVibGljIGlucHV0VGV4dHVyZUxheW91dHM6IFRleHR1cmVMYXlvdXRbXSxcbiAgICBwdWJsaWMgb3V0cHV0VGV4dHVyZUxheW91dDogVGV4dHVyZUxheW91dCxcbiAgKSB7fVxufVxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEdsc2xMaWIge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgY29udGV4dDogR2xzbENvbnRleHQpIHt9XG4gIGFic3RyYWN0IGdldEZ1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9O1xuICBhYnN0cmFjdCBnZXRDdXN0b21UeXBlcygpOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfTtcbn1cblxuLy8gYWJzdHJhY3Rpb24gdG8gcmVwcmVzZW50IGEgR0xTTCBsaWJyYXJ5IHJvdXRpbmUgYW5kIGl0J3MgZGVwZW5kZW5jaWVzXG5leHBvcnQgY2xhc3MgR2xzbExpYlJvdXRpbmUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgcm91dGluZUJvZHk6IHN0cmluZyxcbiAgICBwdWJsaWMgZGVwZW5kZW5jaWVzPzogc3RyaW5nW10sXG4gICkge31cbn1cblxuLy8gYWJzdHJhY3Rpb24gdG8gcmVwcmVzZW50IGEgR0xTTCBsaWJyYXJ5IHJvdXRpbmUgYW5kIGl0J3MgZGVwZW5kZW5jaWVzIEFTIEdSQVBIIE5vZGVzXG4vLyB0aGlzIGxldmVsIG9mIGFic3RyYWN0aW9uIGlzIHVzZWQgdG8gdG9wb2xvZ2ljYWxseSBzb3J0IHJvdXRpbmVzIGJlZm9yZSBmcmFnbWVudCBzaGFkZSBpbmNsdXNpb25cbmV4cG9ydCBjbGFzcyBHbHNsTGliUm91dGluZU5vZGUge1xuICBkZXBlbmRlbmNpZXM6IEdsc2xMaWJSb3V0aW5lTm9kZVtdO1xuICByb3V0aW5lQm9keTogc3RyaW5nO1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nLFxuICAgIHJvdXRpbmVCb2R5Pzogc3RyaW5nLFxuICAgIGRlcGVuZGVuY2llcz86IEdsc2xMaWJSb3V0aW5lTm9kZVtdLFxuICApIHtcbiAgICBpZiAoZGVwZW5kZW5jaWVzKSB7XG4gICAgICB0aGlzLmRlcGVuZGVuY2llcyA9IGRlcGVuZGVuY2llcztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kZXBlbmRlbmNpZXMgPSBbXTtcbiAgICB9XG5cbiAgICBpZiAocm91dGluZUJvZHkpIHtcbiAgICAgIHRoaXMucm91dGluZUJvZHkgPSByb3V0aW5lQm9keTtcbiAgICB9XG4gIH1cbiAgYWRkRGVwZW5kZW5jeShub2RlOiBHbHNsTGliUm91dGluZU5vZGUpIHtcbiAgICBpZiAobm9kZSkge1xuICAgICAgdGhpcy5kZXBlbmRlbmNpZXMucHVzaChub2RlKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gdG9wb2xvZ2ljYWxseSBzb3J0IEdMU0wgbGlicmFyeSByb3V0aW5lcyAoZ3JhcGggbm9kZXMgYWJzdHJhY3Rpb24pIGJlZm9yZSBzaGFkZXIgc2NyaXB0IGluY2x1c2lvblxuZXhwb3J0IGNsYXNzIFRvcG9sb2dpY2FsU29ydEdsc2xSb3V0aW5lcyB7XG4gIHN0YXRpYyByZXR1cm5PcmRlcmVkTm9kZXMobm9kZXM6IEdsc2xMaWJSb3V0aW5lTm9kZVtdKTogR2xzbExpYlJvdXRpbmVOb2RlW10ge1xuICAgIGlmICghbm9kZXMgfHwgbm9kZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgaWYgKG5vZGVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIG5vZGVzO1xuICAgIH1cblxuICAgIGNvbnN0IGN5Y2xlQ2hlY2sgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBjb25zdCBhbHJlYWR5VHJhdmVyc2VkID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IEFycmF5PEdsc2xMaWJSb3V0aW5lTm9kZT4oKTtcblxuICAgIHRoaXMuY3JlYXRlT3JkZXJlZE5vZGVzKG5vZGVzLCBjeWNsZUNoZWNrLCBhbHJlYWR5VHJhdmVyc2VkLCByZXN1bHQpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjcmVhdGVPcmRlcmVkTm9kZXMoXG4gICAgZ3JhcGhOb2RlczogR2xzbExpYlJvdXRpbmVOb2RlW10sXG4gICAgY3ljbGVDaGVjazogU2V0PHN0cmluZz4sXG4gICAgYWxyZWFkeVRyYXZlcnNlZDogU2V0PHN0cmluZz4sXG4gICAgcmVzdWx0OiBHbHNsTGliUm91dGluZU5vZGVbXSxcbiAgKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaE5vZGVzLmxlbmd0aDsgKytpKSB7XG4gICAgICB0aGlzLmRmc1RyYXZlcnNlKGdyYXBoTm9kZXNbaV0sIGN5Y2xlQ2hlY2ssIGFscmVhZHlUcmF2ZXJzZWQsIHJlc3VsdCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZGZzVHJhdmVyc2UoXG4gICAgcm9vdDogR2xzbExpYlJvdXRpbmVOb2RlLFxuICAgIGN5Y2xlQ2hlY2s6IFNldDxzdHJpbmc+LFxuICAgIGFscmVhZHlUcmF2ZXJzZWQ6IFNldDxzdHJpbmc+LFxuICAgIHJlc3VsdDogR2xzbExpYlJvdXRpbmVOb2RlW10sXG4gICkge1xuICAgIC8vIGlmIHRoaXMgcm9vdCBoYXMgYWxyZWFkeSBiZWVuIHRyYXZlcnNlZCByZXR1cm5cbiAgICBpZiAoIXJvb3QgfHwgYWxyZWFkeVRyYXZlcnNlZC5oYXMocm9vdC5uYW1lKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGN5Y2xpYyBkZXBlbmRlbmN5IGhhcyBiZWVuIGRldGVjdGVkXG4gICAgaWYgKGN5Y2xlQ2hlY2suaGFzKHJvb3QubmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkN5Y2xpYyBkZXBlbmRlbmN5IGRldGVjdGVkLiBDYW4ndCB0b3BvbG9naWNhbGx5IHNvcnQgcm91dGluZXMgbmVlZGVkIGZvciBzaGFkZXIuXCIpO1xuICAgIH1cblxuICAgIC8vIGhvbGQgdGhpcyBub2RlIHRvIGRldGVjdCBjeWNsZXMgaWYgYW55XG4gICAgY3ljbGVDaGVjay5hZGQocm9vdC5uYW1lKTtcblxuICAgIC8vIHRyYXZlcnNlIGNoaWxkcmVuIGluIGEgZGZzIGZhc2hpb25cbiAgICBjb25zdCBkZXBlbmRlbmNpZXMgPSByb290LmRlcGVuZGVuY2llcztcbiAgICBpZiAoZGVwZW5kZW5jaWVzICYmIGRlcGVuZGVuY2llcy5sZW5ndGggPiAwKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRlcGVuZGVuY2llcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB0aGlzLmRmc1RyYXZlcnNlKGRlcGVuZGVuY2llc1tpXSwgY3ljbGVDaGVjaywgYWxyZWFkeVRyYXZlcnNlZCwgcmVzdWx0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhZGQgdG8gcmVzdWx0IGhvbGRlclxuICAgIHJlc3VsdC5wdXNoKHJvb3QpO1xuXG4gICAgLy8gbWFyayB0aGlzIG5vZGUgYXMgdHJhdmVyc2VkIHNvIHRoYXQgd2UgZG9uJ3QgdHJhdmVyc2UgZnJvbSB0aGlzIGFnYWluXG4gICAgYWxyZWFkeVRyYXZlcnNlZC5hZGQocm9vdC5uYW1lKTtcblxuICAgIC8vIHJlbGVhc2UgdGhlIGhvbGRcbiAgICBjeWNsZUNoZWNrLmRlbGV0ZShyb290Lm5hbWUpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBCcm9hZGNhc3RVdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IEZ1bmN0aW9uVHlwZSwgR2xzbFZhbHVlRnVuY3Rpb24gfSBmcm9tICcuLi9nbHNsLWRlZmluaXRpb25zJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2xzbEFkZCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnYWRkXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBhICsgYjtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2MSArIHYyO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbERpdigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnZGl2Xyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBhIC8gYjtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2MSAvIHYyO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbE11bCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnbXVsXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBhICogYjtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2MSAqIHYyO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFN1YigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnc3ViXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBhIC0gYjtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2MSAtIHYyO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEVxdWFsKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdlcXVhbF8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoYSA9PSBiKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2ZWM0KGVxdWFsKHYxLCB2MikpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEdyZWF0ZXIoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2dyZWF0ZXJfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KGEgPiBiKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2ZWM0KCB2MS5yID4gdjIuciAsXG4gICAgICB2MS5nID4gdjIuZyxcbiAgICAgIHYxLmIgPiB2Mi5iLFxuICAgICAgdjEuYSA+IHYyLmEgKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xMZXNzKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdsZXNzXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBmbG9hdChhIDwgYik7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdmVjNCggdjEuciA8IHYyLnIgLFxuICAgICAgICAgICAgICAgIHYxLmcgPCB2Mi5nLFxuICAgICAgICAgICAgICAgIHYxLmIgPCB2Mi5iLFxuICAgICAgICAgICAgICAgIHYxLmEgPCB2Mi5hICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQW5kKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdhbmRfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KCBib29sKGEpICYmIGJvb2woYikgKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIGJ2ZWM0IGIxID0gYnZlYzQodjEpO1xuICAgIGJ2ZWM0IGIyID0gYnZlYzQodjIpO1xuICAgIHJldHVybiB2ZWM0KCBiMS5yICYmIGIyLnIgLFxuICAgICAgICAgICAgICAgIGIxLmcgJiYgYjIuZyxcbiAgICAgICAgICAgICAgICBiMS5iICYmIGIyLmIsXG4gICAgICAgICAgICAgICAgYjEuYSAmJiBiMi5hICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsT3IoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ29yXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBmbG9hdCggYm9vbChhKSB8fCBib29sKGIpICk7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICBidmVjNCBiMSA9IGJ2ZWM0KHYxKTtcbiAgICBidmVjNCBiMiA9IGJ2ZWM0KHYyKTtcbiAgICByZXR1cm4gdmVjNCggYjEuciB8fCBiMi5yICxcbiAgICAgICAgICAgICAgICBiMS5nIHx8IGIyLmcsXG4gICAgICAgICAgICAgICAgYjEuYiB8fCBiMi5iLFxuICAgICAgICAgICAgICAgIGIxLmEgfHwgYjIuYSApO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFhvcigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAneG9yXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBmbG9hdCggYm9vbChhKSBeXiBib29sKGIpICk7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICBidmVjNCBiMSA9IGJ2ZWM0KHYxKTtcbiAgICBidmVjNCBiMiA9IGJ2ZWM0KHYyKTtcbiAgICByZXR1cm4gdmVjNCggYjEuciBeXiBiMi5yICxcbiAgICAgICAgICAgICAgICBiMS5nIF5eIGIyLmcsXG4gICAgICAgICAgICAgICAgYjEuYiBeXiBiMi5iLFxuICAgICAgICAgICAgICAgIGIxLmEgXl4gYjIuYSApO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFBvdygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpbkJpbmFyeSgncG93Jyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFBSZWx1KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdwcmVsdV8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gYSA8IDAuMCA/IGEgKiBiOiBhO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHZlYzQoXG4gICAgICB2MS5yIDwgMC4wID8gdjEuciAqIHYyLnI6IHYxLnIsXG4gICAgICB2MS5nIDwgMC4wID8gdjEuZyAqIHYyLmc6IHYxLmcsXG4gICAgICB2MS5iIDwgMC4wID8gdjEuYiAqIHYyLmI6IHYxLmIsXG4gICAgICB2MS5hIDwgMC4wID8gdjEuYSAqIHYyLmE6IHYxLmFcbiAgICAgICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cblxuZnVuY3Rpb24gZ2xzbEJ1aWx0aW5CaW5hcnkoZm5hbWU6IHN0cmluZyk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9IGAke2ZuYW1lfV9gO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gJHtmbmFtZX0oYSwgYik7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gJHtmbmFtZX0odjEsIHYyKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuXG5jb25zdCBjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBnbHNsRnVuYzogR2xzbFZhbHVlRnVuY3Rpb24sXG4gIG91dHB1dFRlbnNvclR5cGU6IFRlbnNvci5EYXRhVHlwZSA9IGlucHV0c1swXS50eXBlLFxuICBjYWNoZUtleT86IHN0cmluZyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgdGV4dHVyZVR5cGUgPSBoYW5kbGVyLnNlc3Npb24ucGFjayA/IFRleHR1cmVUeXBlLnBhY2tlZCA6IFRleHR1cmVUeXBlLnVucGFja2VkO1xuICByZXR1cm4ge1xuICAgIG5hbWU6IGdsc2xGdW5jLm5hbWUsXG4gICAgaW5wdXROYW1lczogWydBJywgJ0InXSxcbiAgICBpbnB1dFR5cGVzOiBbdGV4dHVyZVR5cGUsIHRleHR1cmVUeXBlXSxcbiAgICBjYWNoZUhpbnQ6IGNhY2hlS2V5LFxuICAgIGdldDogKCkgPT4gY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm8oaGFuZGxlciwgaW5wdXRzLCBnbHNsRnVuYywgb3V0cHV0VGVuc29yVHlwZSksXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVCaW5hcnlQcm9ncmFtSW5mbyA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBnbHNsRnVuYzogR2xzbFZhbHVlRnVuY3Rpb24sXG4gIG91dHB1dFRlbnNvclR5cGU6IFRlbnNvci5EYXRhVHlwZSA9IGlucHV0c1swXS50eXBlLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCB0ZXh0dXJlVHlwZSA9IGhhbmRsZXIuc2Vzc2lvbi5wYWNrID8gVGV4dHVyZVR5cGUucGFja2VkIDogVGV4dHVyZVR5cGUudW5wYWNrZWQ7XG4gIGNvbnN0IGlzQnJvYWRjYXN0ID0gIVNoYXBlVXRpbC5hcmVFcXVhbChpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmRpbXMpO1xuICBsZXQgb3V0cHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcblxuICBjb25zdCB1c2VQYWNrZWRUZXh0dXJlID0gaGFuZGxlci5zZXNzaW9uLnBhY2s7XG5cbiAgaWYgKGlzQnJvYWRjYXN0KSB7XG4gICAgY29uc3QgY2FsY3VsYXRlZFNoYXBlID0gQnJvYWRjYXN0VXRpbC5jYWxjU2hhcGUoaW5wdXRzWzBdLmRpbXMsIGlucHV0c1sxXS5kaW1zLCBmYWxzZSk7XG4gICAgaWYgKCFjYWxjdWxhdGVkU2hhcGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IHBlcmZvcm0gYmluYXJ5IG9wIG9uIHRoZSBnaXZlbiB0ZW5zb3JzXCIpO1xuICAgIH1cbiAgICBvdXRwdXRTaGFwZSA9IGNhbGN1bGF0ZWRTaGFwZTtcbiAgICBjb25zdCBvdXRwdXRSYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IGFSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSAwID8gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIDogMTtcbiAgICBjb25zdCBiUmFuayA9IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gMCA/IGlucHV0c1sxXS5kaW1zLmxlbmd0aCA6IDE7XG4gICAgY29uc3QgYUJjYXN0ID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSAwID8gJ2JjYXN0SW5kaWNlc19BKGluZGljZXMsIGFpbmRpY2VzKTsnIDogJ2FpbmRpY2VzWzBdID0gMDsnO1xuICAgIGNvbnN0IGJCY2FzdCA9IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gMCA/ICdiY2FzdEluZGljZXNfQihpbmRpY2VzLCBiaW5kaWNlcyk7JyA6ICdiaW5kaWNlc1swXSA9IDA7JztcblxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSB1c2VQYWNrZWRUZXh0dXJlXG4gICAgICA/IGBcbiAgICAgICR7Z2xzbEZ1bmMuYm9keX1cbiAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgdmVjNCBhID0gZ2V0QUF0T3V0Q29vcmRzKCk7XG4gICAgICAgIHZlYzQgYiA9IGdldEJBdE91dENvb3JkcygpO1xuICAgICAgICB2ZWM0IHJlc3VsdCA9ICR7Z2xzbEZ1bmMubmFtZX0oYSwgYik7XG4gICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgfWBcbiAgICAgIDogYFxuICAgICAgJHtnbHNsRnVuYy5ib2R5fVxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske291dHB1dFJhbmt9XSkge1xuICAgICAgICBpbnQgYWluZGljZXNbJHthUmFua31dO1xuICAgICAgICBpbnQgYmluZGljZXNbJHtiUmFua31dO1xuICAgICAgICAke2FCY2FzdH1cbiAgICAgICAgJHtiQmNhc3R9XG4gICAgICAgIHJldHVybiAke2dsc2xGdW5jLm5hbWV9KF9BKGFpbmRpY2VzKSwgX0IoYmluZGljZXMpKTtcbiAgICAgIH1gO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IGdsc2xGdW5jLm5hbWUsXG4gICAgICBpbnB1dE5hbWVzOiBbJ0EnLCAnQiddLFxuICAgICAgaW5wdXRUeXBlczogW3RleHR1cmVUeXBlLCB0ZXh0dXJlVHlwZV0sXG4gICAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IG91dHB1dFRlbnNvclR5cGUsIHRleHR1cmVUeXBlIH0sXG4gICAgICBzaGFkZXJTb3VyY2UsXG4gICAgICBoYXNNYWluOiB1c2VQYWNrZWRUZXh0dXJlLFxuICAgIH07XG4gIH1cbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgJHtnbHNsRnVuYy5ib2R5fVxuICAgIHZvaWQgbWFpbigpIHtcbiAgICAgIHZlYzQgdjEgPSAke2dsc2wudGV4dHVyZTJEfShBLCBUZXhDb29yZHMpO1xuICAgICAgdmVjNCB2MiA9ICR7Z2xzbC50ZXh0dXJlMkR9KEIsIFRleENvb3Jkcyk7XG4gICAgICB2ZWM0IHJlc3VsdCA9ICR7Z2xzbEZ1bmMubmFtZX0odjEsIHYyKTtcbiAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgIH1cbiAgICBgO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogZ2xzbEZ1bmMubmFtZSxcbiAgICBpbnB1dE5hbWVzOiBbJ0EnLCAnQiddLFxuICAgIGlucHV0VHlwZXM6IFt0ZXh0dXJlVHlwZSwgdGV4dHVyZVR5cGVdLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dHNbMF0uZGltcywgdHlwZTogb3V0cHV0VGVuc29yVHlwZSwgdGV4dHVyZVR5cGUgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBhZGQgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xBZGQoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgYW5kID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsQW5kKCksICdib29sJyksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgZGl2ID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsRGl2KCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGVxdWFsID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsRXF1YWwoKSwgJ2Jvb2wnKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBncmVhdGVyID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsR3JlYXRlcigpLCAnYm9vbCcpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGxlc3MgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xMZXNzKCksICdib29sJyksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgbXVsID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsTXVsKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IG9yID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsT3IoKSwgJ2Jvb2wnKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBwb3cgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xQb3coKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgcFJlbHUgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xQUmVsdSgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBzdWIgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xTdWIoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgeG9yID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsWG9yKCksICdib29sJyksIGlucHV0cyksXG5dO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFByb3RvVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3QgY2FzdDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxUZW5zb3IuRGF0YVR5cGU+ID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIHRvOiBUZW5zb3IuRGF0YVR5cGUsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIHJldHVybiBbaGFuZGxlci5jYXN0KGlucHV0c1swXSwgdG8pXTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNhc3RBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFRlbnNvci5EYXRhVHlwZT4gPSAobm9kZTogR3JhcGguTm9kZSk6IFRlbnNvci5EYXRhVHlwZSA9PlxuICBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8obm9kZS5hdHRyaWJ1dGVzLmdldEludCgndG8nKSk7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2FzdCByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGdldENvb3Jkc0RhdGFUeXBlLCBnZXRHbENoYW5uZWxzIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5pbXBvcnQgeyBDb25jYXRBdHRyaWJ1dGVzIH0gZnJvbSAnLi9jb25jYXQnO1xuaW1wb3J0IHsgZ2V0Q2hhbm5lbHMsIHVucGFja0Zyb21DaGFubmVsIH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcblxuY29uc3QgY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbU1ldGFkYXRhID0gKGlucHV0Q291bnQ6IG51bWJlciwgY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdDb25jYXQgKHBhY2tlZCknLFxuICBpbnB1dE5hbWVzOiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBpbnB1dENvdW50IH0sIChfdiwgaSkgPT4gYFgke2l9YCksXG4gIGlucHV0VHlwZXM6IEFycmF5KGlucHV0Q291bnQpLmZpbGwoVGV4dHVyZVR5cGUucGFja2VkKSxcbiAgY2FjaGVIaW50LFxufSk7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF4aXM6IG51bWJlcixcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGlmIChheGlzID49IGlucHV0U2hhcGUubGVuZ3RoIHx8IGF4aXMgPCAtMSAqIGlucHV0U2hhcGUubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiYXhpcyBzcGVjaWZpZWQgZm9yIGNvbmNhdCBkb2Vzbid0IG1hdGNoIGlucHV0IGRpbWVuc2lvbmFsaXR5XCIpO1xuICB9XG4gIGlmIChheGlzIDwgMCkge1xuICAgIGF4aXMgPSBpbnB1dFNoYXBlLmxlbmd0aCArIGF4aXM7XG4gIH1cbiAgLy8gZW5zdXJlIGFsbCBvZiB0aGUgbm9uLWNvbmNhdGVuYXRlZCBheGVzIG1hdGNoIGVhY2ggb3RoZXJcbiAgLy8gY2FsY3VsYXRlIHRoZSBzaGFwZSBvZiB0aGUgb3V0cHV0IHRlbnNvciB3aGlsZSB3ZSBkbyB0aGF0XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRTaGFwZS5zbGljZSgwKTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBkYXRhTlNoYXBlID0gaW5wdXRzW2ldLmRpbXMuc2xpY2UoKTtcbiAgICBmb3IgKGxldCBheGlzSW5kZXggPSAwOyBheGlzSW5kZXggPCBpbnB1dFNoYXBlLmxlbmd0aDsgYXhpc0luZGV4KyspIHtcbiAgICAgIC8vIGFkZCB0byB0aGUgcGxhY2Vob2xkZXIgZm9yIGNvbXB1dGluZyBvdXRwdXQgc2hhcGVcbiAgICAgIGlmIChheGlzSW5kZXggPT09IGF4aXMpIHtcbiAgICAgICAgb3V0cHV0U2hhcGVbYXhpc10gKz0gZGF0YU5TaGFwZVtheGlzSW5kZXhdO1xuICAgICAgfVxuICAgICAgLy8gZW5zdXJlIGFsbCBub24tY2FuY2F0ZW5hdGVkIGF4ZXMgbWF0Y2ggZWFjaCBvdGhlclxuICAgICAgZWxzZSBpZiAoaW5wdXRTaGFwZVtheGlzSW5kZXhdICE9PSBkYXRhTlNoYXBlW2F4aXNJbmRleF0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub24gY29uY2F0IGRpbWVuc2lvbnMgbXVzdCBtYXRjaCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGNvb3JkcyA9IGdldENoYW5uZWxzKCdjb29yZHMnLCByYW5rKTtcbiAgY29uc3QgZHR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShyYW5rKTtcbiAgY29uc3QgdW5wYWNrQ2hhbm5lbCA9IHVucGFja0Zyb21DaGFubmVsKCk7XG5cbiAgY29uc3Qgc2hhcGVzID0gaW5wdXRzLm1hcCgoaSkgPT4gaS5kaW1zKTtcbiAgY29uc3QgY2hhbm5lbHMgPSBnZXRHbENoYW5uZWxzKHJhbmspO1xuICBjb25zdCBvZmZzZXRzOiBudW1iZXJbXSA9IG5ldyBBcnJheShzaGFwZXMubGVuZ3RoIC0gMSk7XG5cbiAgb2Zmc2V0c1swXSA9IHNoYXBlc1swXVtheGlzXTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBvZmZzZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgb2Zmc2V0c1tpXSA9IG9mZnNldHNbaSAtIDFdICsgc2hhcGVzW2ldW2F4aXNdO1xuICB9XG5cbiAgY29uc3QgY2hhbm5lbCA9IGNoYW5uZWxzW2F4aXNdO1xuICBjb25zdCBsYXN0Q2hhbm5lbHMgPSBjaGFubmVscy5zbGljZSgtMik7XG4gIGNvbnN0IGFsbENoYW5uZWxzID0gY2hhbm5lbHMuam9pbigpO1xuXG4gIGxldCBnZXRWYWx1ZVNuaXBwZXQgPSBgaWYgKCR7Y2hhbm5lbH0gPCAke29mZnNldHNbMF19KSB7XG4gICAgICAgIHJldHVybiBnZXRDaGFubmVsKFxuICAgICAgICAgICAgZ2V0WDAoJHthbGxDaGFubmVsc30pLCB2ZWMyKCR7bGFzdENoYW5uZWxzLmpvaW4oKX0pKTtcbiAgICAgICAgfWA7XG4gIGZvciAobGV0IGkgPSAxOyBpIDwgb2Zmc2V0cy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHNoaWZ0ID0gb2Zmc2V0c1tpIC0gMV07XG4gICAgZ2V0VmFsdWVTbmlwcGV0ICs9IGBcbiAgICAgICAgICAgIGlmICgke2NoYW5uZWx9IDwgJHtvZmZzZXRzW2ldfSAgJiYgJHtjaGFubmVsfSA+PSAke29mZnNldHNbaSAtIDFdfSkge1xuICAgICAgICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChcbiAgICAgICAgICAgICAgICBnZXRYJHtpfSgke2dldFNoaWZ0ZWRDaGFubmVsc1NuaXBwZXQoY2hhbm5lbHMsIGNoYW5uZWwsIHNoaWZ0KX0pLFxuICAgICAgICAgICAgICAgIHZlYzIoJHtnZXRTaGlmdGVkQ2hhbm5lbHNTbmlwcGV0KGxhc3RDaGFubmVscywgY2hhbm5lbCwgc2hpZnQpfSkpO1xuICAgICAgICAgICAgfWA7XG4gIH1cbiAgY29uc3QgbGFzdEluZGV4ID0gb2Zmc2V0cy5sZW5ndGg7XG4gIGNvbnN0IHNoaWZ0ID0gb2Zmc2V0c1tvZmZzZXRzLmxlbmd0aCAtIDFdO1xuICBnZXRWYWx1ZVNuaXBwZXQgKz0gYFxuICAgICAgICAgICAgcmV0dXJuIGdldENoYW5uZWwoXG4gICAgICAgICAgICAgIGdldFgke2xhc3RJbmRleH0oJHtnZXRTaGlmdGVkQ2hhbm5lbHNTbmlwcGV0KGNoYW5uZWxzLCBjaGFubmVsLCBzaGlmdCl9KSxcbiAgICAgICAgICAgICAgdmVjMigke2dldFNoaWZ0ZWRDaGFubmVsc1NuaXBwZXQobGFzdENoYW5uZWxzLCBjaGFubmVsLCBzaGlmdCl9KSk7YDtcblxuICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICAgICR7dW5wYWNrQ2hhbm5lbH1cbiAgICAgICAgICBmbG9hdCBnZXRWYWx1ZSgke2NoYW5uZWxzLm1hcCgoeCkgPT4gJ2ludCAnICsgeCl9KSB7XG4gICAgICAgICAgICAke2dldFZhbHVlU25pcHBldH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgICAgICAke2R0eXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICAgICAgICAgIGludCBsYXN0RGltID0gY29vcmRzLiR7Y2hhbm5lbHNbcmFuayAtIDFdfTtcbiAgICAgICAgICAgIGNvb3Jkcy4ke2NoYW5uZWxzW3JhbmsgLSAxXX0gPSBjb29yZHMuJHtjaGFubmVsc1tyYW5rIC0gMl19O1xuICAgICAgICAgICAgY29vcmRzLiR7Y2hhbm5lbHNbcmFuayAtIDJdfSA9IGxhc3REaW07XG5cbiAgICAgICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNChnZXRWYWx1ZSgke2Nvb3Jkc30pLCAwLiwgMC4sIDAuKTtcblxuICAgICAgICAgICAgJHtjb29yZHNbcmFuayAtIDFdfSA9ICR7Y29vcmRzW3JhbmsgLSAxXX0gKyAxO1xuICAgICAgICAgICAgaWYgKCR7Y29vcmRzW3JhbmsgLSAxXX0gPCAke291dHB1dFNoYXBlW3JhbmsgLSAxXX0pIHtcbiAgICAgICAgICAgICAgcmVzdWx0LmcgPSBnZXRWYWx1ZSgke2Nvb3Jkc30pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAke2Nvb3Jkc1tyYW5rIC0gMl19ID0gJHtjb29yZHNbcmFuayAtIDJdfSArIDE7XG4gICAgICAgICAgICBpZiAoJHtjb29yZHNbcmFuayAtIDJdfSA8ICR7b3V0cHV0U2hhcGVbcmFuayAtIDJdfSkge1xuICAgICAgICAgICAgICByZXN1bHQuYSA9IGdldFZhbHVlKCR7Y29vcmRzfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICR7Y29vcmRzW3JhbmsgLSAxXX0gPSAke2Nvb3Jkc1tyYW5rIC0gMV19IC0gMTtcbiAgICAgICAgICAgIGlmICgke2Nvb3Jkc1tyYW5rIC0gMl19IDwgJHtvdXRwdXRTaGFwZVtyYW5rIC0gMl19ICYmXG4gICAgICAgICAgICAgICAgJHtjb29yZHNbcmFuayAtIDFdfSA8ICR7b3V0cHV0U2hhcGVbcmFuayAtIDFdfSkge1xuICAgICAgICAgICAgICByZXN1bHQuYiA9IGdldFZhbHVlKCR7Y29vcmRzfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29uY2F0QXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVQYWNrZWRDb25jYXRQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCwgYXR0cmlidXRlcy5jYWNoZUtleSk7XG4gIHJldHVybiB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvKGhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIGF0dHJpYnV0ZXMuYXhpcykgfTtcbn07XG5cbmNvbnN0IGdldFNoaWZ0ZWRDaGFubmVsc1NuaXBwZXQgPSAoY2hhbm5lbHM6IHN0cmluZ1tdLCBjaGFubmVsOiBzdHJpbmcsIHNoaWZ0OiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBjaGFubmVsSWR4ID0gY2hhbm5lbHMuaW5kZXhPZihjaGFubmVsKTtcbiAgY29uc3QgcmVzID0gY2hhbm5lbHMubWFwKChjLCBpZHgpID0+IHtcbiAgICBpZiAoaWR4ID09PSBjaGFubmVsSWR4KSB7XG4gICAgICByZXR1cm4gYCR7Y30gLSAke3NoaWZ0fWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXMuam9pbigpO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9jb25jYXQtcGFja2VkJztcblxuZXhwb3J0IGludGVyZmFjZSBDb25jYXRBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhpczogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgY29uY2F0OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPENvbmNhdEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbmNhdEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGlmIChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24ucGFjayAmJiBpbnB1dHNbMF0uZGltcy5sZW5ndGggPiAxKSB7XG4gICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICBjcmVhdGVQYWNrZWRDb25jYXRQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAgICAgaW5wdXRzLFxuICAgICk7XG4gICAgcmV0dXJuIFtvdXRwdXRdO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgY3JlYXRlVW5wYWNrZWRDb25jYXRQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAgICAgaW5wdXRzLFxuICAgICk7XG4gICAgcmV0dXJuIFtvdXRwdXRdO1xuICB9XG59O1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1NZXRhZGF0YSA9IChpbnB1dENvdW50OiBudW1iZXIsIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnQ29uY2F0JyxcbiAgaW5wdXROYW1lczogQXJyYXkuZnJvbSh7IGxlbmd0aDogaW5wdXRDb3VudCB9LCAoX3YsIGkpID0+IGBYJHtpfWApLFxuICBpbnB1dFR5cGVzOiBBcnJheShpbnB1dENvdW50KS5maWxsKFRleHR1cmVUeXBlLnVucGFja2VkKSxcbiAgY2FjaGVIaW50LFxufSk7XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbUluZm8gPSAoXG4gIF9oYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF4aXM6IG51bWJlcixcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGlmIChheGlzID49IGlucHV0U2hhcGUubGVuZ3RoIHx8IGF4aXMgPCAtMSAqIGlucHV0U2hhcGUubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiYXhpcyBzcGVjaWZpZWQgZm9yIGNvbmNhdCBkb2Vzbid0IG1hdGNoIGlucHV0IGRpbWVuc2lvbmFsaXR5XCIpO1xuICB9XG4gIGlmIChheGlzIDwgMCkge1xuICAgIGF4aXMgPSBpbnB1dFNoYXBlLmxlbmd0aCArIGF4aXM7XG4gIH1cbiAgLy8gZW5zdXJlIGFsbCBvZiB0aGUgbm9uLWNvbmNhdGVuYXRlZCBheGVzIG1hdGNoIGVhY2ggb3RoZXJcbiAgLy8gY2FsY3VsYXRlIHRoZSBzaGFwZSBvZiB0aGUgb3V0cHV0IHRlbnNvciB3aGlsZSB3ZSBkbyB0aGF0XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRTaGFwZS5zbGljZSgwKTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBkYXRhTlNoYXBlID0gaW5wdXRzW2ldLmRpbXMuc2xpY2UoKTtcbiAgICBmb3IgKGxldCBheGlzSW5kZXggPSAwOyBheGlzSW5kZXggPCBpbnB1dFNoYXBlLmxlbmd0aDsgYXhpc0luZGV4KyspIHtcbiAgICAgIC8vIGFkZCB0byB0aGUgcGxhY2Vob2xkZXIgZm9yIGNvbXB1dGluZyBvdXRwdXQgc2hhcGVcbiAgICAgIGlmIChheGlzSW5kZXggPT09IGF4aXMpIHtcbiAgICAgICAgb3V0cHV0U2hhcGVbYXhpc10gKz0gZGF0YU5TaGFwZVtheGlzSW5kZXhdO1xuICAgICAgfVxuICAgICAgLy8gZW5zdXJlIGFsbCBub24tY2FuY2F0ZW5hdGVkIGF4ZXMgbWF0Y2ggZWFjaCBvdGhlclxuICAgICAgZWxzZSBpZiAoaW5wdXRTaGFwZVtheGlzSW5kZXhdICE9PSBkYXRhTlNoYXBlW2F4aXNJbmRleF0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub24gY29uY2F0IGRpbWVuc2lvbnMgbXVzdCBtYXRjaCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3Qgc2l6ZUluQ29uY2F0QXhpcyA9IG5ldyBBcnJheTxudW1iZXI+KGlucHV0cy5sZW5ndGgpO1xuICBsZXQgcHJldmlvdXNTdW0gPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHNpemVJbkNvbmNhdEF4aXMubGVuZ3RoOyArK2kpIHtcbiAgICBwcmV2aW91c1N1bSArPSBpbnB1dHNbaV0uZGltc1theGlzXTtcbiAgICBzaXplSW5Db25jYXRBeGlzW2ldID0gcHJldmlvdXNTdW07XG4gIH1cblxuICBsZXQgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc01ldGhvZCA9ICcnO1xuICAvLyBpbiBtb3N0IGNhc2VzIGxpbmVhciBzZWFyY2ggaXMgc3VmZmljaWVudCwgYXMgaW4gbW9zdCBzY2VuYXJpb3MsIG9ubHkgMiB0ZW5zb3JzIGFyZSBjb25jYXRlbmF0ZWRcbiAgaWYgKGlucHV0cy5sZW5ndGggPCA1KSB7XG4gICAgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc01ldGhvZCA9IGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNMaW5lYXJTZWFyY2goc2l6ZUluQ29uY2F0QXhpcyk7XG4gIH0gZWxzZSB7XG4gICAgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc01ldGhvZCA9IGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNCaW5hcnlTZWFyY2goc2l6ZUluQ29uY2F0QXhpcyk7XG4gIH1cblxuICBjb25zdCBmZXRjaERhdGFGcm9tQ29ycmVjdFRleHR1cmVNZXRob2QgPSBnZXRGZXRjaERhdGFGcm9tQ29ycmVjdFRleHR1cmVNZXRob2QoaW5wdXRzLmxlbmd0aCwgcmFuayk7XG4gIGNvbnN0IGdldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleE1ldGhvZCA9IGdldEdldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleE1ldGhvZChzaXplSW5Db25jYXRBeGlzKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICAke2ZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZU1ldGhvZH1cbiAgICAgICAgJHtnZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXhNZXRob2R9XG4gICAgICAgICR7Z2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc01ldGhvZH1cbiAgICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCB0ZXh0dXJlSW5kZXggPSBnZXRUZXh0dXJlV2hlcmVEYXRhUmVzaWRlcyAoaW5kaWNlc1ske2F4aXN9XSk7XG5cbiAgICAgICAgICBpZih0ZXh0dXJlSW5kZXggIT0gMCkge1xuICAgICAgICAgICAgaW5kaWNlc1ske2F4aXN9XSA9IGluZGljZXNbJHtheGlzfV0gLSBpbnQoZ2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4KHRleHR1cmVJbmRleC1pbnQoMSkpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlKHRleHR1cmVJbmRleCwgaW5kaWNlcyk7XG4gICAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29uY2F0QXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlVW5wYWNrZWRDb25jYXRQcm9ncmFtSW5mbyhoYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBhdHRyaWJ1dGVzLmF4aXMpIH07XG59O1xuXG5jb25zdCBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTGluZWFyU2VhcmNoID0gKHNpemVJbkNvbmNhdEF4aXM6IG51bWJlcltdKTogc3RyaW5nID0+IHtcbiAgY29uc3Qgc2VhcmNoQXhpcyA9IHNpemVJbkNvbmNhdEF4aXMubWFwKFxuICAgIChzaXplLCBpKSA9PiBgaWYoaW5kZXg8JHtzaXplfSkge3JldHVybiAke2l9O31cbmAsXG4gICk7XG4gIHJldHVybiBgaW50IGdldFRleHR1cmVXaGVyZURhdGFSZXNpZGVzKGludCBpbmRleCkge1xuICAgICAgJHtzZWFyY2hBeGlzLmpvaW4oJycpfVxuICAgIH1gO1xufTtcblxuLy8gVE9ETzogSW1wbGVtZW50IEJpbmFyeVNlYXJjaCBpbiBHTFNMXG5jb25zdCBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzQmluYXJ5U2VhcmNoID0gKHNpemVJbkNvbmNhdEF4aXM6IG51bWJlcltdKTogc3RyaW5nID0+XG4gIGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNMaW5lYXJTZWFyY2goc2l6ZUluQ29uY2F0QXhpcyk7XG5cbmNvbnN0IGdldEZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZU1ldGhvZCA9IChudW1iZXJPZlRlbnNvcnM6IG51bWJlciwgdGVuc29yUmFuazogbnVtYmVyKSA9PiB7XG4gIGNvbnN0IGNvZGVMaW5lczogc3RyaW5nW10gPSBbYGZsb2F0IGZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZShpbnQgdGV4dHVyZUluZGV4LCBpbnQgaW5kaWNlc1ske3RlbnNvclJhbmt9XSkge2BdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlck9mVGVuc29yczsgKytpKSB7XG4gICAgaWYgKGkgPT09IDApIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGlmICh0ZXh0dXJlSW5kZXggPT0gJHtpfSkgeyByZXR1cm4gX1gke2l9KGluZGljZXMpOyB9YCk7XG4gICAgfSBlbHNlIGlmIChpID09PSBudW1iZXJPZlRlbnNvcnMgLSAxKSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBlbHNlIHsgcmV0dXJuIF9YJHtpfShpbmRpY2VzKTsgfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBlbHNlIGlmICh0ZXh0dXJlSW5kZXggPT0gJHtpfSkgeyByZXR1cm4gX1gke2l9KGluZGljZXMpOyB9YCk7XG4gICAgfVxuICB9XG4gIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgJ30nKTtcbiAgcmV0dXJuIGNvZGVMaW5lcy5qb2luKCdcXG4nKTtcbn07XG5cbmNvbnN0IGdldEdldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleE1ldGhvZCA9IChzaXplSW5Db25jYXRBeGlzOiBudW1iZXJbXSk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGNvZGVMaW5lczogc3RyaW5nW10gPSBbJ2ludCBnZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXgoaW50IGluZGV4KSB7J107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZUluQ29uY2F0QXhpcy5sZW5ndGg7ICsraSkge1xuICAgIGlmIChpID09PSAwKSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBpZiAoaW5kZXggPT0gJHtpfSkgeyByZXR1cm4gJHtzaXplSW5Db25jYXRBeGlzW2ldfTsgfWApO1xuICAgIH0gZWxzZSBpZiAoaSA9PT0gc2l6ZUluQ29uY2F0QXhpcy5sZW5ndGggLSAxKSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBlbHNlIHsgcmV0dXJuICR7c2l6ZUluQ29uY2F0QXhpc1tpXX07IH1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyBgZWxzZSBpZiAoaW5kZXggPT0gJHtpfSkgeyByZXR1cm4gJHtzaXplSW5Db25jYXRBeGlzW2ldfTsgfWApO1xuICAgIH1cbiAgfVxuICBjb2RlTGluZXMucHVzaCgnXFx0JyArICd9Jyk7XG5cbiAgcmV0dXJuIGNvZGVMaW5lcy5qb2luKCdcXG4nKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNvbmNhdEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248Q29uY2F0QXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IENvbmNhdEF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpczogbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycpIH0pO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0b28gZmV3IGlucHV0cycpO1xuICB9XG5cbiAgY29uc3QgaW5wdXRUeXBlID0gaW5wdXRzWzBdLnR5cGU7XG4gIGNvbnN0IGlucHV0RGltZW5zaW9uYWxpdHkgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG5cbiAgLy8gVE9ETzogU3VwcG9ydCBzdHJpbmcgY29uY2F0XG4gIGlmIChpbnB1dFR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzdHJpbmcgdGVuc29yIGlzIG5vdCBzdXBwb3J0ZWQgeWV0Jyk7XG4gIH1cblxuICBmb3IgKGNvbnN0IGlucHV0IG9mIGlucHV0cykge1xuICAgIC8vIG1ha2Ugc3VyZSB0eXBlcyBvZiBhbGwgaW5wdXRzIG1hdGNoXG4gICAgaWYgKGlucHV0LnR5cGUgIT09IGlucHV0VHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCB0ZW5zb3JzIHNob3VsZCBiZSBvbmUgdHlwZScpO1xuICAgIH1cblxuICAgIC8vIG1ha2Ugc3VyZSB0aGUgZGltZW5zaW9uYWxpdHkgb2YgYWxsIGlucHV0cyBhcmUgdGhlIHNhbWVcbiAgICBpZiAoaW5wdXQuZGltcy5sZW5ndGggIT09IGlucHV0RGltZW5zaW9uYWxpdHkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgdGVuc29ycyBzaG91bGQgaGF2ZSB0aGUgc2FtZSBzaGFwZScpO1xuICAgIH1cbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgTUFYX0NMSVAsIE1JTl9DTElQIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBGdW5jdGlvblR5cGUsIEdsc2xWYWx1ZUZ1bmN0aW9uIH0gZnJvbSAnLi4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2xzbEFicygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdhYnMnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQWNvcygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdhY29zJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEFzaW4oKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnYXNpbicpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xBdGFuKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2F0YW4nKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQ2VpbCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdjZWlsJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbENvcygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdjb3MnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsRWx1KGFscGhhOiBudW1iZXIpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnZWx1JztcbiAgY29uc3QgYm9keSA9IGBcbiAgY29uc3QgZmxvYXQgYWxwaGEgPSBmbG9hdCgke2FscGhhfSk7XG5cbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBhID49IDAuMCA/IGE6IChleHAoYSkgLSAxLjApICogYWxwaGE7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gdmVjNCgke25hbWV9Xyh2LngpLCAke25hbWV9Xyh2LnkpLCAke25hbWV9Xyh2LnopLCAke25hbWV9Xyh2LncpKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xFeHAoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnZXhwJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEZsb29yKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2Zsb29yJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbENsaXAobWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2NsaXAnO1xuICBjb25zdCBib2R5ID0gYFxuICBjb25zdCBmbG9hdCBtaW4gPSBmbG9hdCgke21pbn0pO1xuICBjb25zdCBmbG9hdCBtYXggPSBmbG9hdCgke21heH0pO1xuXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gY2xhbXAoYSwgbWluLCBtYXgpO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIGNsYW1wKHYsIG1pbiwgbWF4KTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xJZGVudGl0eSgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnaW5kZW50aXR5JztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBhO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIHY7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTGVha3lSZWx1KGFscGhhOiBudW1iZXIpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnbGVha3lSZWx1JztcbiAgY29uc3QgYm9keSA9IGBcbiAgY29uc3QgZmxvYXQgYWxwaGEgPSBmbG9hdCgke2FscGhhfSk7XG5cbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBhIDwgMC4wID8gYSAqIGFscGhhIDogYTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiB2ZWM0KCR7bmFtZX1fKHYueCksICR7bmFtZX1fKHYueSksICR7bmFtZX1fKHYueiksICR7bmFtZX1fKHYudykpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbExvZygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdsb2cnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTmVnKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICduZWcnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIC1hO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIC12O1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbE5vdCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnbm90JztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBmbG9hdCggISBib29sKGEpICk7XG4gIH1cbiAgYm9vbCAke25hbWV9Xyhib29sIGEpIHtcbiAgICByZXR1cm4gIWE7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gdmVjNCghYm9vbCh2LngpLCAhYm9vbCh2LnkpLCAhYm9vbCh2LnopLCAhYm9vbCh2LncpKTtcbiAgfVxuICBidmVjNCAke25hbWV9XyhidmVjNCB2KSB7XG4gICAgcmV0dXJuIGJ2ZWM0KCF2LngsICF2LnksICF2LnosICF2LncpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFNpbigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdzaW4nKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsUmVsdSgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAncmVsdSc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gbWF4KCBhLCAwLjAgKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiBtYXgoIHYsIDAuMCApO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFNpZ21vaWQoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3NpZ21vaWQnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIDEuMCAvICgxLjAgKyBleHAoLWEpKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiAxLjAgLyAoMS4wICsgZXhwKC12KSk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsU3FydCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdzcXJ0Jyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFRhbigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCd0YW4nKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsVGFuaCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAndGFuaCc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICBhID0gY2xhbXAoYSwgLTEwLiwgMTAuKTtcbiAgICBhID0gZXhwKDIuKmEpO1xuICAgIHJldHVybiAoYSAtIDEuKSAvIChhICsgMS4pO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgdiA9IGNsYW1wKHYsIC0xMC4sIDEwLik7XG4gICAgdiA9IGV4cCgyLip2KTtcbiAgICByZXR1cm4gKHYgLSAxLikgLyAodiArIDEuKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZnVuY3Rpb24gZ2xzbEJ1aWx0aW5VbmFyeShuYW1lOiBzdHJpbmcpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gJHtuYW1lfShhKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiAke25hbWV9KHYpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5cbi8vLy8vXG4vLy8vL1xuLy8vLy9cblxuY29uc3QgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dDogVGVuc29yLFxuICBnbHNsRnVuYzogR2xzbFZhbHVlRnVuY3Rpb24sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHRleHR1cmVUeXBlID0gaGFuZGxlci5zZXNzaW9uLnBhY2sgPyBUZXh0dXJlVHlwZS5wYWNrZWQgOiBUZXh0dXJlVHlwZS51bnBhY2tlZDtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dC5kaW1zLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZSB9LFxuICAgIHNoYWRlclNvdXJjZTogYFxuICAgICAke2dsc2xGdW5jLmJvZHl9XG4gICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICB2ZWM0IHYgPSAke2dsc2wudGV4dHVyZTJEfShBLCBUZXhDb29yZHMpO1xuICAgICAgIHYgPSAke2dsc2xGdW5jLm5hbWV9Xyh2KTtcbiAgICAgICAke2dsc2wub3V0cHV0fSA9IHY7XG4gICAgIH1cbiAgICAgYCxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBnbHNsRnVuYzogR2xzbFZhbHVlRnVuY3Rpb24sXG4gIGNhY2hlS2V5Pzogc3RyaW5nLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCB0ZXh0dXJlVHlwZSA9IGhhbmRsZXIuc2Vzc2lvbi5wYWNrID8gVGV4dHVyZVR5cGUucGFja2VkIDogVGV4dHVyZVR5cGUudW5wYWNrZWQ7XG4gIGNvbnN0IG1ldGFkYXRhID0geyBuYW1lOiBnbHNsRnVuYy5uYW1lLCBpbnB1dFR5cGVzOiBbdGV4dHVyZVR5cGVdLCBpbnB1dE5hbWVzOiBbJ0EnXSwgY2FjaGVIaW50OiBjYWNoZUtleSB9O1xuICByZXR1cm4geyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dCwgZ2xzbEZ1bmMpIH07XG59O1xuXG5leHBvcnQgY29uc3QgYWJzID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xBYnMoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgYWNvcyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQWNvcygpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBhc2luID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xBc2luKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGF0YW4gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbEF0YW4oKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgaW50ZXJmYWNlIENsaXBBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgbWluOiBudW1iZXI7XG4gIHJlYWRvbmx5IG1heDogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgY2xpcCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IENsaXBBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKFxuICAgICAgaGFuZGxlcixcbiAgICAgIGlucHV0c1swXSxcbiAgICAgIGdsc2xDbGlwKGF0dHJpYnV0ZXMubWluLCBhdHRyaWJ1dGVzLm1heCksXG4gICAgICBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICksXG4gICAgaW5wdXRzLFxuICApLFxuXTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ2xpcEF0dHJpYnV0ZXMgPSAobm9kZTogR3JhcGguTm9kZSk6IENsaXBBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgbWluOiBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ21pbicsIE1JTl9DTElQKSxcbiAgICBtYXg6IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnbWF4JywgTUFYX0NMSVApLFxuICB9KTtcblxuZXhwb3J0IGNvbnN0IGNsaXBWMTEgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICBjb25zdCBhdHRyaWJ1dGVzID0gZ2VuZXJhdGVDbGlwQXR0cmlidXRlc0Zyb21JbnB1dHMoaGFuZGxlciwgaW5wdXRzKTtcbiAgcmV0dXJuIGNsaXAoaGFuZGxlciwgW2lucHV0c1swXV0sIGF0dHJpYnV0ZXMpO1xufTtcblxuY29uc3QgZ2VuZXJhdGVDbGlwQXR0cmlidXRlc0Zyb21JbnB1dHMgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogQ2xpcEF0dHJpYnV0ZXMgPT4ge1xuICBpZiAoXG4gICAgaW5wdXRzLmxlbmd0aCA+PSAzICYmXG4gICAgKCFoYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMV0uZGF0YUlkKSB8fCAhaGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzJdLmRhdGFJZCkpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignZHluYW1pYyBjbGlwIGF0dHJpYnV0ZXMgYXJlIG5vdCBhbGxvd2VkJyk7XG4gIH1cblxuICBjb25zdCBtaW4gPSBpbnB1dHMubGVuZ3RoID49IDMgPyBpbnB1dHNbMV0ubnVtYmVyRGF0YVswXSA6IE1JTl9DTElQO1xuICBjb25zdCBtYXggPSBpbnB1dHMubGVuZ3RoID49IDMgPyBpbnB1dHNbMl0ubnVtYmVyRGF0YVswXSA6IE1BWF9DTElQO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgbWluLCBtYXggfSk7XG59O1xuXG5leHBvcnQgY29uc3QgY2VpbCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQ2VpbCgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBjb3MgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbENvcygpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBpbnRlcmZhY2UgRWx1QXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGFscGhhOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBlbHUgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBFbHVBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbEVsdShhdHRyaWJ1dGVzLmFscGhhKSwgYXR0cmlidXRlcy5jYWNoZUtleSksXG4gICAgaW5wdXRzLFxuICApLFxuXTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlRWx1QXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlKTogRWx1QXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBhbHBoYTogbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdhbHBoYScsIDEuMCkgfSk7XG5cbmV4cG9ydCBjb25zdCBleHAgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbEV4cCgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBmbG9vciA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsRmxvb3IoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgaWRlbnRpdHkgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbElkZW50aXR5KCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGludGVyZmFjZSBMZWFreVJlbHVBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYWxwaGE6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGxlYWt5UmVsdSA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBMZWFreVJlbHVBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbExlYWt5UmVsdShhdHRyaWJ1dGVzLmFscGhhKSwgYXR0cmlidXRlcy5jYWNoZUtleSksXG4gICAgaW5wdXRzLFxuICApLFxuXTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTGVha3lSZWx1QXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlKTogTGVha3lSZWx1QXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBhbHBoYTogbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdhbHBoYScsIDAuMDEpIH0pO1xuXG5leHBvcnQgY29uc3QgbG9nID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xMb2coKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgbmVnID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xOZWcoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3Qgbm90ID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xOb3QoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgcmVsdSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsUmVsdSgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBzaWdtb2lkID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xTaWdtb2lkKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHNpbiA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsU2luKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHNxcnQgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFNxcnQoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgdGFuID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xUYW4oKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgdGFuaCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsVGFuaCgpKSwgaW5wdXRzKSxcbl07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZSc7XG5pbXBvcnQgeyBNQVhfQ0xJUCwgTUlOX0NMSVAgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IEdsc2xWYWx1ZUZ1bmN0aW9uIH0gZnJvbSAnLi4vZ2xzbC1kZWZpbml0aW9ucyc7XG5cbmltcG9ydCB7IGdsc2xDbGlwLCBnbHNsUmVsdSwgZ2xzbFNpZ21vaWQgfSBmcm9tICcuL3VuYXJ5LW9wJztcblxuZXhwb3J0IGludGVyZmFjZSBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIHtcbiAgcmVhZG9ubHkgYWN0aXZhdGlvbjogc3RyaW5nO1xuICByZWFkb25seSBjbGlwTWluPzogbnVtYmVyO1xuICByZWFkb25seSBjbGlwTWF4PzogbnVtYmVyO1xuICByZWFkb25seSBhY3RpdmF0aW9uQ2FjaGVLZXk6IHN0cmluZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFjdGl2YXRpb25TbmlwcGV0KGF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMpIHtcbiAgbGV0IGZ1bmM6IEdsc2xWYWx1ZUZ1bmN0aW9uO1xuICBzd2l0Y2ggKGF0dHJpYnV0ZXMuYWN0aXZhdGlvbikge1xuICAgIGNhc2UgJ1JlbHUnOlxuICAgICAgZnVuYyA9IGdsc2xSZWx1KCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdTaWdtb2lkJzpcbiAgICAgIGZ1bmMgPSBnbHNsU2lnbW9pZCgpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnQ2xpcCc6XG4gICAgICBmdW5jID0gZ2xzbENsaXAoYXR0cmlidXRlcy5jbGlwTWluISwgYXR0cmlidXRlcy5jbGlwTWF4ISk7XG4gICAgICBicmVhaztcbiAgICAvLyBUT0RPOiBhZGRpbmcgb3RoZXIgYWN0aXZhdGlvbnMgdGhhdCBjYW4gYmUgZnVzZWQuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB7IGFjdGl2YXRpb25GdW5jdGlvbjogJycsIGFwcGx5QWN0aXZhdGlvbjogJycgfTtcbiAgfVxuXG4gIGNvbnN0IGFjdGl2YXRpb25OYW1lID0gZnVuYy5uYW1lO1xuICBjb25zdCBhY3RpdmF0aW9uRnVuY3Rpb24gPSBmdW5jLmJvZHk7XG4gIGNvbnN0IGFwcGx5QWN0aXZhdGlvbiA9IGB2YWx1ZSA9ICR7YWN0aXZhdGlvbk5hbWV9Xyh2YWx1ZSk7YDtcbiAgcmV0dXJuIHsgYWN0aXZhdGlvbkZ1bmN0aW9uLCBhcHBseUFjdGl2YXRpb24gfTtcbn1cblxuZXhwb3J0IGNvbnN0IHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBBdHRyaWJ1dGUpOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYWN0aXZhdGlvbiA9IGF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdhY3RpdmF0aW9uJywgJycpO1xuXG4gIGlmIChhY3RpdmF0aW9uID09PSAnQ2xpcCcpIHtcbiAgICBjb25zdCBbY2xpcE1pbiwgY2xpcE1heF0gPSBhdHRyaWJ1dGVzLmdldEZsb2F0cygnYWN0aXZhdGlvbl9wYXJhbXMnLCBbTUlOX0NMSVAsIE1BWF9DTElQXSk7XG4gICAgcmV0dXJuIHsgYWN0aXZhdGlvbiwgY2xpcE1heCwgY2xpcE1pbiwgYWN0aXZhdGlvbkNhY2hlS2V5OiBgJHthY3RpdmF0aW9ufToke2NsaXBNaW59LCR7Y2xpcE1heH1gIH07XG4gIH1cbiAgcmV0dXJuIHsgYWN0aXZhdGlvbiwgYWN0aXZhdGlvbkNhY2hlS2V5OiBhY3RpdmF0aW9uIH07XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi8uLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjYWxjdWxhdGVPdXRwdXRTaGFwZSwgQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuL2NvbnYnO1xuaW1wb3J0IHsgZ2V0QWN0aXZhdGlvblNuaXBwZXQgfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGNhY2hlSGludDogc3RyaW5nKTogUHJvZ3JhbU1ldGFkYXRhID0+ICh7XG4gIG5hbWU6ICdHcm91cGVkQ29udicsXG4gIGlucHV0TmFtZXM6IGhhc0JpYXMgPyBbJ1gnLCAnVycsICdCaWFzJ10gOiBbJ1gnLCAnVyddLFxuICBpbnB1dFR5cGVzOiBoYXNCaWFzXG4gICAgPyBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF1cbiAgICA6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA+IDI7XG4gIGNvbnN0IHByb2Nlc3NCaWFzID0gaGFzQmlhcyA/ICd2YWx1ZSArPSBnZXRCaWFzKG91dHB1dF9jaGFubmVsKTsnIDogJyc7XG4gIGNvbnN0IHhTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IHdTaGFwZSA9IGlucHV0c1sxXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IG91dHB1dENoYW5uZWxzUGVyR3JvdXAgPSB3U2hhcGVbMF0gLyBhdHRyaWJ1dGVzLmdyb3VwO1xuICBMb2dnZXIudmVyYm9zZShcbiAgICAnR3JvdXBlZENvbnYnLFxuICAgIGBhdXRwUGFkOiR7YXR0cmlidXRlcy5hdXRvUGFkfSwgZGlsYXRpb25zOiR7YXR0cmlidXRlcy5kaWxhdGlvbnN9LCBncm91cDoke2F0dHJpYnV0ZXMuZ3JvdXB9LCBrZXJuZWxTaGFwZToke1xuICAgICAgYXR0cmlidXRlcy5rZXJuZWxTaGFwZVxuICAgIH0sIHBhZHM6JHthdHRyaWJ1dGVzLnBhZHN9LCBzdHJpZGVzOiR7YXR0cmlidXRlcy5zdHJpZGVzfWAsXG4gICk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gY2FsY3VsYXRlT3V0cHV0U2hhcGUoeFNoYXBlLCB3U2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgeyBhY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbiB9ID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlcyk7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICBjb25zdCBpdmVjMiBzdHJpZGVzID0gaXZlYzIoJHthdHRyaWJ1dGVzLnN0cmlkZXNbMF19LCAke2F0dHJpYnV0ZXMuc3RyaWRlc1sxXX0pO1xuICBjb25zdCBpdmVjMiBwYWRzID0gaXZlYzIoJHthdHRyaWJ1dGVzLnBhZHNbMF19LCAke2F0dHJpYnV0ZXMucGFkc1sxXX0pO1xuICAke2FjdGl2YXRpb25GdW5jdGlvbn1cbiAgdm9pZCBtYWluKCkge1xuICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAgIGludCBiYXRjaCA9IGNvb3Jkcy54O1xuICAgIGludCBvdXRwdXRfY2hhbm5lbCA9IGNvb3Jkcy55O1xuICAgIGl2ZWMyIHhSQ0Nvcm5lciA9IGNvb3Jkcy56dyAqIHN0cmlkZXMgLSBwYWRzO1xuICAgIGludCBncm91cF9pZCA9IG91dHB1dF9jaGFubmVsIC8gJHtvdXRwdXRDaGFubmVsc1Blckdyb3VwfTtcblxuICAgIGZsb2F0IHZhbHVlID0gMC4wO1xuICAgIGZvciAoaW50IHdJbkNoYW5uZWwgPSAwOyB3SW5DaGFubmVsIDwgJHt3U2hhcGVbMV19OyB3SW5DaGFubmVsKyspIHtcbiAgICAgIGludCBpbnB1dF9jaGFubmVsID0gZ3JvdXBfaWQgKiAke3dTaGFwZVsxXX0gKyB3SW5DaGFubmVsO1xuICAgICAgZm9yIChpbnQgd0hlaWdodCA9IDA7IHdIZWlnaHQgPCAke3dTaGFwZVsyXX07IHdIZWlnaHQrKykge1xuICAgICAgICBpbnQgeEhlaWdodCA9IHhSQ0Nvcm5lci54ICsgd0hlaWdodCAqICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMF19O1xuXG4gICAgICAgIGlmICh4SGVpZ2h0IDwgMCB8fCB4SGVpZ2h0ID49ICR7eFNoYXBlWzJdfSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChpbnQgd1dpZHRoID0gMDsgd1dpZHRoIDwgJHt3U2hhcGVbM119OyB3V2lkdGgrKykge1xuICAgICAgICAgIGludCB4V2lkdGggPSB4UkNDb3JuZXIueSArIHdXaWR0aCAqICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMV19O1xuICAgICAgICAgIGlmICh4V2lkdGggPCAwIHx8IHhXaWR0aCA+PSAke3hTaGFwZVszXX0pIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZsb2F0IHhWYWwgPSBnZXRYKGJhdGNoLCBpbnB1dF9jaGFubmVsLCB4V2lkdGgsIHhIZWlnaHQpO1xuICAgICAgICAgIGZsb2F0IHdWYWwgPSBnZXRXKG91dHB1dF9jaGFubmVsLCB3SW5DaGFubmVsLCB3V2lkdGgsIHdIZWlnaHQpO1xuICAgICAgICAgIHZhbHVlICs9IHhWYWwqd1ZhbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAke3Byb2Nlc3NCaWFzfVxuICAgICR7YXBwbHlBY3RpdmF0aW9ufVxuICAgICR7Z2xzbC5vdXRwdXR9ID0gdmVjNCh2YWx1ZSwgLjAsIC4wLCAuMCk7XG4gIH1cbmA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCA+IDIsIGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIGdldDogKCkgPT4gY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgbWV0YWRhdGEsIGF0dHJpYnV0ZXMpLFxuICB9O1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IENvbnZBdHRyaWJ1dGVzIH0gZnJvbSAnLi9jb252JztcbmltcG9ydCB7IHVucGFja0Zyb21DaGFubmVsIH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcblxuY29uc3QgY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbU1ldGFkYXRhID0gKGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnSW0yQ29sIChwYWNrZWQpJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS5wYWNrZWRdLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgeDogVGVuc29yLFxuICB3OiBUZW5zb3IsXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHhzaGFwZSA9IHguZGltcztcbiAgY29uc3Qgd3NoYXBlID0gdy5kaW1zO1xuICBjb25zdCByb3dEaW0gPSAyO1xuICBjb25zdCBjb2xEaW0gPSAzO1xuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBpbTJjb2xTaGFwZSA9IFt3c2hhcGVbMV0gKiB3c2hhcGVbMl0gKiB3c2hhcGVbM10sIG91dHB1dFNoYXBlWzJdICogb3V0cHV0U2hhcGVbM11dO1xuICBjb25zdCBrZXJuZWxTaXplID0gd3NoYXBlWzJdICogd3NoYXBlWzNdO1xuICBjb25zdCB1bnBhY2tDaGFubmVsID0gdW5wYWNrRnJvbUNoYW5uZWwoKTtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBsZXQgdW5yb2xsZWQgPSAnJztcblxuICBmb3IgKGxldCByb3cgPSAwOyByb3cgPD0gMTsgcm93KyspIHtcbiAgICBmb3IgKGxldCBjb2wgPSAwOyBjb2wgPD0gMTsgY29sKyspIHtcbiAgICAgIHVucm9sbGVkICs9IGBcbiAgICAgICAgICAgIGJsb2NrSW5kZXggPSByYy54ICsgJHtjb2x9O1xuICAgICAgICAgICAgcG9zID0gcmMueSArICR7cm93fTtcblxuICAgICAgICAgICAgaWYoYmxvY2tJbmRleCA8ICR7aW0yY29sU2hhcGVbMV19ICYmIHBvcyA8ICR7aW0yY29sU2hhcGVbMF19KSB7XG4gICAgICAgICAgICAgIG9mZnNldFkgPSBpbnQoYmxvY2tJbmRleCAvICgke291dHB1dFNoYXBlW3JhbmsgLSAxXX0pKSAqICR7YXR0cmlidXRlcy5zdHJpZGVzWzBdfSAtXG4gICAgICAgICAgICAgICAgJHthdHRyaWJ1dGVzLnBhZHNbMF19O1xuICAgICAgICAgICAgICBkMCA9IG9mZnNldFkgKyAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzBdfSAqIChpbW9kKHBvcywgJHtrZXJuZWxTaXplfSkgLyAke3dzaGFwZVsyXX0pO1xuXG4gICAgICAgICAgICAgIGlmKGQwIDwgJHt4c2hhcGVbcm93RGltXX0gJiYgZDAgPj0gMCkge1xuICAgICAgICAgICAgICAgIG9mZnNldFggPSBpbW9kKGJsb2NrSW5kZXgsICR7b3V0cHV0U2hhcGVbcmFuayAtIDFdfSkgKiAke2F0dHJpYnV0ZXMuc3RyaWRlc1sxXX0gLVxuICAgICAgICAgICAgICAgICAgJHthdHRyaWJ1dGVzLnBhZHNbMV19O1xuICAgICAgICAgICAgICAgIGQxID0gb2Zmc2V0WCArICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMV19ICogaW1vZChpbW9kKHBvcywgJHtrZXJuZWxTaXplfSksICR7d3NoYXBlWzJdfSk7XG5cbiAgICAgICAgICAgICAgICBpZihkMSA8ICR7eHNoYXBlW2NvbERpbV19ICYmIGQxID49IDApIHtcblxuICAgICAgICAgICAgICAgICAgY2ggPSBpbnQoZmxvYXQocG9zKS8gJHtrZXJuZWxTaXplfS4pO1xuICAgICAgICAgICAgICAgICAgICBpbm5lckRpbXMgPSB2ZWMyKGQwLCBkMSk7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdFske3JvdyAqIDIgKyBjb2x9XSA9IGdldENoYW5uZWwoXG4gICAgICAgICAgICAgICAgICAgICAgZ2V0QSgwLCBjaCwgaW50KGlubmVyRGltcy54KSxcbiAgICAgICAgICAgICAgICAgICAgICBpbnQoaW5uZXJEaW1zLnkpKSwgaW5uZXJEaW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIGA7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHt1bnBhY2tDaGFubmVsfVxuXG4gICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgIGl2ZWMyIHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuMCk7XG4gICAgICAgICAgaW50IGJsb2NrSW5kZXgsIHBvcywgb2Zmc2V0WSwgZDAsIG9mZnNldFgsIGQxLCBjaDtcbiAgICAgICAgICB2ZWMyIGlubmVyRGltcztcbiAgICAgICAgICAke3Vucm9sbGVkfVxuICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgfVxuICAgICAgICAgICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW0yY29sU2hhcGUsIHR5cGU6IHgudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIHg6IFRlbnNvcixcbiAgdzogVGVuc29yLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1NZXRhZGF0YShhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhLCB4LCB3LCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcyksXG4gIH07XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IEJyb2FkY2FzdFV0aWwsIFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0Q29vcmRzRGF0YVR5cGUsIGdldEdsQ2hhbm5lbHMgfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IGdldEFjdGl2YXRpb25TbmlwcGV0LCBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLCBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuaW1wb3J0IHsgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL21hdG11bC1wYWNrJztcblxuZXhwb3J0IGNvbnN0IG1hdE11bDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIGlmIChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24ucGFjaykge1xuICAgIHJldHVybiBbaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKV07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihpbnB1dHMsIGF0dHJpYnV0ZXMpLCBpbnB1dHMpXTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTWF0TXVsQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgPT4gcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKG5vZGUuYXR0cmlidXRlcyk7XG5cbmNvbnN0IGNyZWF0ZU1hdG11bFByb2dyYW1NZXRhZGF0YSA9IChoYXNCaWFzOiBib29sZWFuLCBjYWNoZUhpbnQ6IHN0cmluZykgPT4gKHtcbiAgbmFtZTogJ01hdE11bCcsXG4gIGlucHV0TmFtZXM6IGhhc0JpYXMgPyBbJ0EnLCAnQicsICdCaWFzJ10gOiBbJ0EnLCAnQiddLFxuICBpbnB1dFR5cGVzOiBoYXNCaWFzXG4gICAgPyBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF1cbiAgICA6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICBjYWNoZUhpbnQsXG59KTtcblxuZnVuY3Rpb24gY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm8oXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGFjdGl2YXRpb25BdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8ge1xuICBjb25zdCBhU2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgYlNoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gQnJvYWRjYXN0VXRpbC5jYWxjU2hhcGUoYVNoYXBlLCBiU2hhcGUsIHRydWUpO1xuICBpZiAoIW91dHB1dFNoYXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgdXNlIG1hdG11bCBvbiB0aGUgZ2l2ZW4gdGVuc29yc1wiKTtcbiAgfVxuICBjb25zdCBjb29yZHNEYXRhVHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IGFsbEdsQ2hhbm5lbHMgPSBnZXRHbENoYW5uZWxzKCk7XG4gIGNvbnN0IHsgYWN0aXZhdGlvbkZ1bmN0aW9uLCBhcHBseUFjdGl2YXRpb24gfSA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGFjdGl2YXRpb25BdHRyaWJ1dGVzKTtcblxuICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA+IDI7XG4gIGNvbnN0IHByb2Nlc3NCaWFzID0gaGFzQmlhcyA/ICd2YWx1ZSArPSBnZXRCaWFzRm9yTWF0bXVsKCk7JyA6ICcnO1xuICBjb25zdCBnZXRCaWFzRm9yTWF0bXVsU25pcHBldCA9IGhhc0JpYXNcbiAgICA/IGAke2dldEJpYXNGb3JNYXRtdWwoY29vcmRzRGF0YVR5cGUsIGFsbEdsQ2hhbm5lbHMsIGlucHV0c1syXS5kaW1zLCBvdXRwdXRTaGFwZSwgZmFsc2UpfWBcbiAgICA6ICcnO1xuXG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGFyYW5rID0gYVNoYXBlLmxlbmd0aDtcbiAgY29uc3QgYnJhbmsgPSBiU2hhcGUubGVuZ3RoO1xuICBjb25zdCBzaGFyZWREaW0gPSBhU2hhcGVbYVNoYXBlLmxlbmd0aCAtIDFdO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgJHthY3RpdmF0aW9uRnVuY3Rpb259XG4gICAgJHtnZXRCaWFzRm9yTWF0bXVsU25pcHBldH1cbiAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgIGludCBhWyR7YXJhbmt9XTtcbiAgICAgICAgaW50IGJbJHticmFua31dO1xuICAgICAgICBiY2FzdE1hdG11bEluZGljZXNfQShpbmRpY2VzLCBhKTtcbiAgICAgICAgYmNhc3RNYXRtdWxJbmRpY2VzX0IoaW5kaWNlcywgYik7XG5cbiAgICAgICAgZmxvYXQgdmFsdWU7XG4gICAgICAgIGZvciAoaW50IGs9MDsgazwke3NoYXJlZERpbX07ICsraykge1xuICAgICAgICAgICAgYVske2FyYW5rIC0gMX1dID0gaztcbiAgICAgICAgICAgIGJbJHticmFuayAtIDJ9XSA9IGs7XG4gICAgICAgICAgICB2YWx1ZSArPSBfQShhKSAqIF9CKGIpO1xuICAgICAgICB9XG4gICAgICAgICR7cHJvY2Vzc0JpYXN9XG4gICAgICAgICR7YXBwbHlBY3RpdmF0aW9ufVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIoXG4gIGlucHV0czogVGVuc29yW10sXG4gIGFjdGl2YXRpb25BdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZU1hdG11bFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoID4gMiwgYWN0aXZhdGlvbkF0dHJpYnV0ZXMuYWN0aXZhdGlvbkNhY2hlS2V5KTtcbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm8obWV0YWRhdGEsIGlucHV0cywgYWN0aXZhdGlvbkF0dHJpYnV0ZXMpIH07XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignTWF0TXVsIHJlcXVpcmVzIDIgaW5wdXRzLicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS5kaW1zW2lucHV0c1swXS5kaW1zLmxlbmd0aCAtIDFdICE9PSBpbnB1dHNbMV0uZGltc1tpbnB1dHNbMV0uZGltcy5sZW5ndGggLSAyXSkge1xuICAgIHRocm93IG5ldyBFcnJvcignc2hhcmVkIGRpbWVuc2lvbiBkb2VzIG5vdCBtYXRjaC4nKTtcbiAgfVxuXG4gIGlmIChcbiAgICAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgIChpbnB1dHNbMV0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQ2NCcpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW5wdXRzIHNob3VsZCBiZSBmbG9hdCB0eXBlJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09IGlucHV0c1sxXS50eXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dHMgdHlwZXMgc2hvdWxkIG1hdGNoJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCaWFzRm9yTWF0bXVsKFxuICBjb29yZHNEYXRhVHlwZTogc3RyaW5nLFxuICBhbGxHbENoYW5uZWxzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgaW5TaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG91dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgaXNQYWNrZWQ6IGJvb2xlYW4sXG4pOiBzdHJpbmcge1xuICBsZXQgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJyc7XG4gIGNvbnN0IGluUmFuayA9IGluU2hhcGUubGVuZ3RoO1xuICBjb25zdCBvdXRSYW5rID0gb3V0U2hhcGUubGVuZ3RoO1xuICBjb25zdCByYW5rRGlmZiA9IG91dFJhbmsgLSBpblJhbms7XG4gIGlmIChvdXRSYW5rIDwgMiAmJiBpblJhbmsgPiAwKSB7XG4gICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJ2Nvb3Jkcyc7XG4gIH0gZWxzZSB7XG4gICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gaW5TaGFwZS5tYXAoKF9zLCBpKSA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tpICsgcmFua0RpZmZdfWApLmpvaW4oJywgJyk7XG4gIH1cbiAgY29uc3QgYnJvYWRjYXN0RGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpblNoYXBlLCBvdXRTaGFwZSk7XG4gIGNvbnN0IGNvb3Jkc1NuaXBwZXQgPSBicm9hZGNhc3REaW1zLm1hcCgoZCkgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbZCArIHJhbmtEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICBjb25zdCBpblNpemUgPSBTaGFwZVV0aWwuc2l6ZShpblNoYXBlKTtcbiAgY29uc3QgaXNJbnB1dFNjYWxhciA9IGluU2l6ZSA9PT0gMTtcbiAgbGV0IG91dHB1dCA9ICd2ZWM0KG91dHB1dFZhbHVlLnh4LCBvdXRwdXRWYWx1ZS55eSknO1xuICBpZiAoaXNJbnB1dFNjYWxhcikge1xuICAgIG91dHB1dCA9ICd2ZWM0KG91dHB1dFZhbHVlLngpJztcbiAgfVxuICBjb25zdCBnZXRCaWFzRm9yTWF0bXVsU291cmNlID0gaXNQYWNrZWRcbiAgICA/IGBcbnZlYzQgZ2V0Qmlhc0Zvck1hdG11bCgpIHtcbiAgJHtjb29yZHNEYXRhVHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICR7Y29vcmRzU25pcHBldH1cbiAgdmVjNCBvdXRwdXRWYWx1ZSA9IGdldEJpYXMoJHt1bnBhY2tlZENvb3Jkc1NuaXBwZXR9KTtcbiAgcmV0dXJuICR7b3V0cHV0fTtcbn1gXG4gICAgOiBgXG5mbG9hdCBnZXRCaWFzRm9yTWF0bXVsKCkge1xuICAke2Nvb3Jkc0RhdGFUeXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgJHtjb29yZHNTbmlwcGV0fVxuICByZXR1cm4gZ2V0Qmlhcyhjb29yZHMueCk7XG59YDtcblxuICByZXR1cm4gZ2V0Qmlhc0Zvck1hdG11bFNvdXJjZTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IEJyb2FkY2FzdFV0aWwsIFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGdldENvb3Jkc0RhdGFUeXBlLCBnZXRHbENoYW5uZWxzIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5pbXBvcnQgeyBnZXRBY3RpdmF0aW9uU25pcHBldCwgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQgeyBnZXRCaWFzRm9yTWF0bXVsIH0gZnJvbSAnLi9tYXRtdWwnO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtTWV0YWRhdGEgPSAoaGFzQmlhczogYm9vbGVhbiwgY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdNYXRNdWwgKHBhY2tlZCknLFxuICBpbnB1dE5hbWVzOiBoYXNCaWFzID8gWydBJywgJ0InLCAnQmlhcyddIDogWydBJywgJ0InXSxcbiAgaW5wdXRUeXBlczogaGFzQmlhc1xuICAgID8gW1RleHR1cmVUeXBlLnBhY2tlZCwgVGV4dHVyZVR5cGUucGFja2VkLCBUZXh0dXJlVHlwZS5wYWNrZWRdXG4gICAgOiBbVGV4dHVyZVR5cGUucGFja2VkLCBUZXh0dXJlVHlwZS5wYWNrZWRdLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYWN0aXZhdGlvbkF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID4gMjtcbiAgY29uc3QgcHJvY2Vzc0JpYXMgPSBoYXNCaWFzID8gJ3ZhbHVlICs9IGdldEJpYXNGb3JNYXRtdWwoKTsnIDogJyc7XG4gIGNvbnN0IGFTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBiU2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBCcm9hZGNhc3RVdGlsLmNhbGNTaGFwZShhU2hhcGUsIGJTaGFwZSwgdHJ1ZSk7XG4gIGNvbnN0IGlzQnJvYWRjYXN0ID0gIVNoYXBlVXRpbC5hcmVFcXVhbChpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmRpbXMpO1xuXG4gIGlmICghb3V0cHV0U2hhcGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCB1c2UgbWF0bXVsIG9uIHRoZSBnaXZlbiB0ZW5zb3JzXCIpO1xuICB9XG4gIGNvbnN0IHNoYXJlZERpbSA9IGFTaGFwZVthU2hhcGUubGVuZ3RoIC0gMV07XG4gIGNvbnN0IHNoYXJlZERpbUluZGV4ID0gTWF0aC5jZWlsKHNoYXJlZERpbSAvIDIpO1xuICBjb25zdCBhUmFuayA9IGFTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGJSYW5rID0gYlNoYXBlLmxlbmd0aDtcblxuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IGNvb3Jkc0RhdGFUeXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3Qgb3V0UmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgYWxsR2xDaGFubmVscyA9IGdldEdsQ2hhbm5lbHMoKTtcbiAgY29uc3QgeyBhY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbiB9ID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYWN0aXZhdGlvbkF0dHJpYnV0ZXMpO1xuXG4gIGNvbnN0IGdldEJpYXNGb3JNYXRtdWxTbmlwcGV0ID0gaGFzQmlhc1xuICAgID8gYCR7Z2V0Qmlhc0Zvck1hdG11bChjb29yZHNEYXRhVHlwZSwgYWxsR2xDaGFubmVscywgaW5wdXRzWzJdLmRpbXMsIG91dHB1dFNoYXBlLCB0cnVlKX1gXG4gICAgOiAnJztcblxuICBjb25zdCBnZXRCY2FzdGVkU2FtcGxlckZvck1hdG11bFNuaXBwZXQgPSBpc0Jyb2FkY2FzdFxuICAgID8gYCR7Z2V0QmNhc3RTYW1wbGVyRm9yTWF0bXVsKGNvb3Jkc0RhdGFUeXBlLCBhbGxHbENoYW5uZWxzLCBpbnB1dHMsIG91dHB1dFNoYXBlKX1gXG4gICAgOiAnJztcblxuICBjb25zdCBnZXRTYW1wbGVyQUluTG9vcFNuaXBwZXQgPSBpc0Jyb2FkY2FzdCA/ICdnZXRBQXRPdXRDb29yZHNNYXRtdWwoaSknIDogYGdldEEoJHtnZXRBKGFsbEdsQ2hhbm5lbHMsIGFSYW5rKX0pYDtcbiAgY29uc3QgZ2V0U2FtcGxlckJJbkxvb3BTbmlwcGV0ID0gaXNCcm9hZGNhc3QgPyAnZ2V0QkF0T3V0Q29vcmRzTWF0bXVsKGkpJyA6IGBnZXRCKCR7Z2V0QihhbGxHbENoYW5uZWxzLCBiUmFuayl9KWA7XG4gIGNvbnN0IGdldE91dHB1dENvb3Jkc1NuaXBwZXQgPSBpc0Jyb2FkY2FzdFxuICAgID8gJydcbiAgICA6IGAke2Nvb3Jkc0RhdGFUeXBlfSByYyA9XG4gICAgICAgICAgZ2V0T3V0cHV0Q29vcmRzKCk7IGludCBsYXN0RGltID0gcmMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAxXX07IHJjLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMV19ID1cbiAgICAgICAgICByYy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDJdfTsgcmMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAyXX0gPSBsYXN0RGltO1xuICAgICAgYDtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICAgICAgJHtnZXRCY2FzdGVkU2FtcGxlckZvck1hdG11bFNuaXBwZXR9XG4gICAgICAgICAgICAke2dldEJpYXNGb3JNYXRtdWxTbmlwcGV0fVxuICAgICAgICAgICAgJHthY3RpdmF0aW9uRnVuY3Rpb259XG4gICAgICAgICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgICAgICAgICR7Z2V0T3V0cHV0Q29vcmRzU25pcHBldH1cblxuICAgICAgICAgICAgICB2ZWM0IHZhbHVlID0gdmVjNCgwKTtcbiAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke3NoYXJlZERpbUluZGV4fTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmVjNCBhID0gJHtnZXRTYW1wbGVyQUluTG9vcFNuaXBwZXR9O1xuICAgICAgICAgICAgICAgIHZlYzQgYiA9ICR7Z2V0U2FtcGxlckJJbkxvb3BTbmlwcGV0fTtcblxuICAgICAgICAgICAgICAgIHZhbHVlICs9IChhLnJyYmIgKiBiLnJncmcpO1xuICAgICAgICAgICAgICAgIHZhbHVlICs9IChhLmdnYWEgKiBiLmJhYmEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICR7cHJvY2Vzc0JpYXN9XG4gICAgICAgICAgICAgICR7YXBwbHlBY3RpdmF0aW9ufVxuICAgICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZhbHVlO1xuICAgICAgICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGFjdGl2YXRpb25BdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoID4gMiwgYWN0aXZhdGlvbkF0dHJpYnV0ZXMuYWN0aXZhdGlvbkNhY2hlS2V5KTtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIGFjdGl2YXRpb25BdHRyaWJ1dGVzKSxcbiAgfTtcbn07XG5cbmZ1bmN0aW9uIGdldEJjYXN0U2FtcGxlckZvck1hdG11bChcbiAgY29vcmRzRGF0YVR5cGU6IHN0cmluZyxcbiAgYWxsR2xDaGFubmVsczogcmVhZG9ubHkgc3RyaW5nW10sXG4gIGlucHV0czogVGVuc29yW10sXG4gIG91dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbik6IHN0cmluZyB7XG4gIGxldCB1bnBhY2tlZEFDb29yZHNTbmlwcGV0ID0gW107XG4gIGxldCB1bnBhY2tlZEJDb29yZHNTbmlwcGV0ID0gW107XG5cbiAgY29uc3QgaW5BU2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgaW5CU2hhcGUgPSBpbnB1dHNbMV0uZGltcztcblxuICBjb25zdCBpbkFSYW5rID0gaW5BU2hhcGUubGVuZ3RoO1xuICBjb25zdCBpbkJSYW5rID0gaW5CU2hhcGUubGVuZ3RoO1xuXG4gIGNvbnN0IG91dFJhbmsgPSBvdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IHJhbmtBRGlmZiA9IG91dFJhbmsgLSBpbkFSYW5rO1xuICBjb25zdCByYW5rQkRpZmYgPSBvdXRSYW5rIC0gaW5CUmFuaztcblxuICB1bnBhY2tlZEFDb29yZHNTbmlwcGV0ID0gaW5BU2hhcGUubWFwKChfcywgaSkgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbaSArIHJhbmtBRGlmZl19YCk7XG4gIHVucGFja2VkQUNvb3Jkc1NuaXBwZXRbaW5BUmFuayAtIDFdID0gJ2kqMic7XG4gIHVucGFja2VkQUNvb3Jkc1NuaXBwZXQuam9pbignLCAnKTtcbiAgdW5wYWNrZWRCQ29vcmRzU25pcHBldCA9IGluQlNoYXBlLm1hcCgoX3MsIGkpID0+IGBjb29yZHMuJHthbGxHbENoYW5uZWxzW2kgKyByYW5rQkRpZmZdfWApO1xuICB1bnBhY2tlZEJDb29yZHNTbmlwcGV0W2luQlJhbmsgLSAyXSA9ICdpKjInO1xuICB1bnBhY2tlZEJDb29yZHNTbmlwcGV0LmpvaW4oJywgJyk7XG5cbiAgY29uc3QgYnJvYWRjYXN0QURpbXMgPSBCcm9hZGNhc3RVdGlsLmdldEJyb2FkY2FzdERpbXMoaW5BU2hhcGUsIG91dFNoYXBlKTtcbiAgY29uc3QgYnJvYWRjYXN0QkRpbXMgPSBCcm9hZGNhc3RVdGlsLmdldEJyb2FkY2FzdERpbXMoaW5CU2hhcGUsIG91dFNoYXBlKTtcblxuICBjb25zdCBjb29yZHNBU25pcHBldCA9IGJyb2FkY2FzdEFEaW1zLm1hcCgoZCkgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbZCArIHJhbmtBRGlmZl19ID0gMDtgKS5qb2luKCdcXG4nKTtcbiAgY29uc3QgY29vcmRzQlNuaXBwZXQgPSBicm9hZGNhc3RCRGltcy5tYXAoKGQpID0+IGBjb29yZHMuJHthbGxHbENoYW5uZWxzW2QgKyByYW5rQkRpZmZdfSA9IDA7YCkuam9pbignXFxuJyk7XG4gIGNvbnN0IHN3YXBEaW1TbmlwcGV0ID0gYGludCBsYXN0RGltID0gY29vcmRzLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMV19O1xuICBjb29yZHMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAxXX0gPSBjb29yZHMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAyXX07XG4gIGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDJdfSA9IGxhc3REaW07YDtcblxuICBjb25zdCBnZXRCY2FzdFNhbXBsZXJNYXRtdWxTb3VyY2UgPSBgXG52ZWM0IGdldEFBdE91dENvb3Jkc01hdG11bChpbnQgaSkge1xuICAke2Nvb3Jkc0RhdGFUeXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgJHtzd2FwRGltU25pcHBldH1cbiAgJHtjb29yZHNBU25pcHBldH1cbiAgdmVjNCBvdXRwdXRWYWx1ZSA9IGdldEEoJHt1bnBhY2tlZEFDb29yZHNTbmlwcGV0fSk7XG4gIHJldHVybiBvdXRwdXRWYWx1ZTtcbn1cblxudmVjNCBnZXRCQXRPdXRDb29yZHNNYXRtdWwoaW50IGkpIHtcbiAgJHtjb29yZHNEYXRhVHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICR7c3dhcERpbVNuaXBwZXR9XG4gICR7Y29vcmRzQlNuaXBwZXR9XG4gIHZlYzQgb3V0cHV0VmFsdWUgPSBnZXRCKCR7dW5wYWNrZWRCQ29vcmRzU25pcHBldH0pO1xuICByZXR1cm4gb3V0cHV0VmFsdWU7XG59YDtcblxuICByZXR1cm4gZ2V0QmNhc3RTYW1wbGVyTWF0bXVsU291cmNlO1xufVxuXG5mdW5jdGlvbiBnZXRBKGFsbEdsQ2hhbm5lbHM6IHN0cmluZ1tdLCByYW5rOiBudW1iZXIpOiBzdHJpbmcge1xuICBsZXQgcmVzID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDI7IGkrKykge1xuICAgIHJlcyArPSBgcmMuJHthbGxHbENoYW5uZWxzW2ldfSwgYDtcbiAgfVxuICByZXMgKz0gYHJjLiR7YWxsR2xDaGFubmVsc1tyYW5rIC0gMl19LCBgICsgJ2kqMic7XG4gIHJldHVybiByZXM7XG59XG5cbmZ1bmN0aW9uIGdldEIoYWxsR2xDaGFubmVsczogc3RyaW5nW10sIHJhbms6IG51bWJlcik6IHN0cmluZyB7XG4gIGxldCByZXMgPSAnJztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rIC0gMjsgaSsrKSB7XG4gICAgcmVzICs9IGByYy4ke2FsbEdsQ2hhbm5lbHNbaV19LCBgO1xuICB9XG4gIHJlcyArPSAnaSoyLCAnICsgYHJjLiR7YWxsR2xDaGFubmVsc1tyYW5rIC0gMV19YDtcbiAgcmV0dXJuIHJlcztcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuaW1wb3J0IHsgY2FsY3VsYXRlT3V0cHV0U2hhcGUsIENvbnZBdHRyaWJ1dGVzIH0gZnJvbSAnLi9jb252JztcbmltcG9ydCB7IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9pbTJjb2wtcGFjayc7XG5pbXBvcnQgeyBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vbWF0bXVsLXBhY2snO1xuXG5leHBvcnQgY29uc3QgY29udjJEUGFja2VkUG9pbnR3aXNlID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgeHNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGtzaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGNhbGN1bGF0ZU91dHB1dFNoYXBlKHhzaGFwZSwga3NoYXBlLCBhdHRyaWJ1dGVzLmRpbGF0aW9ucywgYXR0cmlidXRlcy5wYWRzLCBhdHRyaWJ1dGVzLnN0cmlkZXMpO1xuICBjb25zdCByZXNoYXBlZFggPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVQYWNrZWQoaW5wdXRzWzBdLCBbeHNoYXBlWzFdLCB4c2hhcGVbMl0gKiB4c2hhcGVbM11dKTtcbiAgY29uc3QgcmVzaGFwZWRLID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlUGFja2VkKGlucHV0c1sxXSwgW2tzaGFwZVswXSwga3NoYXBlWzFdXSk7XG5cbiAgY29uc3QgbWF0bXVsSW5wdXRzID0gaW5wdXRzLmxlbmd0aCA+IDIgPyBbcmVzaGFwZWRLLCByZXNoYXBlZFgsIGlucHV0c1syXV0gOiBbcmVzaGFwZWRLLCByZXNoYXBlZFhdO1xuICBjb25zdCBtYXRtdWxPdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBtYXRtdWxJbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAgIG1hdG11bElucHV0cyxcbiAgKTtcbiAgcmV0dXJuIGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVBhY2tlZChtYXRtdWxPdXRwdXQsIG91dHB1dFNoYXBlKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb252MkRQYWNrZWQgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3IgPT4ge1xuICBjb25zdCB4c2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gY2FsY3VsYXRlT3V0cHV0U2hhcGUoeHNoYXBlLCBrc2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG5cbiAgLy8gcnVuIGltMmNvbFxuICBjb25zdCBpbTJjb2xPdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVQYWNrZWRJbTJDb2xQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGlucHV0c1sxXSwgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpLFxuICAgIFtpbnB1dHNbMF1dLFxuICApO1xuXG4gIC8vIHJlc2hhcGUga2VybmVsXG4gIGNvbnN0IGtlcm5lbFJlc2hhcGVkID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlUGFja2VkKGlucHV0c1sxXSwgW2tzaGFwZVswXSwga3NoYXBlWzFdICoga3NoYXBlWzJdICoga3NoYXBlWzNdXSk7XG5cbiAgLy8gcnVuIG1hdG11bFxuICBjb25zdCBtYXRtdWxJbnB1dHMgPSBpbnB1dHMubGVuZ3RoID09PSAzID8gW2tlcm5lbFJlc2hhcGVkLCBpbTJjb2xPdXRwdXQsIGlucHV0c1syXV0gOiBba2VybmVsUmVzaGFwZWQsIGltMmNvbE91dHB1dF07XG4gIGNvbnN0IG1hdG11bE91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIG1hdG11bElucHV0cywgYXR0cmlidXRlcyksXG4gICAgbWF0bXVsSW5wdXRzLFxuICApO1xuXG4gIC8vIHJlc2hhcGUgb3V0cHV0XG4gIGNvbnN0IG91dHB1dFJlc2hhcGVkID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlUGFja2VkKG1hdG11bE91dHB1dCwgb3V0cHV0U2hhcGUpO1xuICByZXR1cm4gb3V0cHV0UmVzaGFwZWQ7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBDb252QXR0cmlidXRlcyB9IGZyb20gJy4vY29udic7XG5cbmNvbnN0IGNyZWF0ZUltMkNvbFByb2dyYW1NZXRhZGF0YSA9IChjYWNoZUhpbnQ6IHN0cmluZykgPT4gKHtcbiAgbmFtZTogJ0ltMkNvbCcsXG4gIGlucHV0TmFtZXM6IFsnWCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlSW0yQ29sUHJvZ3JhbUluZm8gPSAoXG4gIF9pbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIHg6IFRlbnNvcixcbiAgdzogVGVuc29yLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCB4c2hhcGUgPSB4LmRpbXM7XG4gIGNvbnN0IHdzaGFwZSA9IHcuZGltcztcblxuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBpbTJjb2xEaW1zID0gY2FsY3VsYXRlSW0yQ29sRGltcyh4c2hhcGUsIHdzaGFwZSwgb3V0cHV0U2hhcGUsIDQpO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgY29uc3QgaW50IFhDID0gJHt4c2hhcGVbMV19O1xuICAgICAgICBjb25zdCBpbnQgWEggPSAke3hzaGFwZVsyXX07XG4gICAgICAgIGNvbnN0IGludCBYVyA9ICR7eHNoYXBlWzNdfTtcbiAgICAgICAgY29uc3QgaW50IEtIID0gJHthdHRyaWJ1dGVzLmtlcm5lbFNoYXBlWzBdfTtcbiAgICAgICAgY29uc3QgaW50IEtXID0gJHthdHRyaWJ1dGVzLmtlcm5lbFNoYXBlWzFdfTtcbiAgICAgICAgY29uc3QgaW50IGRpbGF0aW9uSCA9ICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMF19O1xuICAgICAgICBjb25zdCBpbnQgZGlsYXRpb25XID0gJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXX07XG4gICAgICAgIGNvbnN0IGludCBzdHJpZGVIID0gJHthdHRyaWJ1dGVzLnN0cmlkZXNbMF19O1xuICAgICAgICBjb25zdCBpbnQgc3RyaWRlVyA9ICR7YXR0cmlidXRlcy5zdHJpZGVzWzFdfTtcbiAgICAgICAgY29uc3QgaW50IHBhZEggPSAke2F0dHJpYnV0ZXMucGFkc1swXX07XG4gICAgICAgIGNvbnN0IGludCBwYWRXID0gJHthdHRyaWJ1dGVzLnBhZHNbMV19O1xuICAgICAgICBjb25zdCBpbnQgS0hLVyA9IEtIKktXO1xuICAgICAgICBjb25zdCBpbnQgWENLSEtXID0gWEMgKiBLSEtXO1xuICAgICAgICBjb25zdCBpbnQgb3V0cHV0Q2hhbm5lbHMgPSA0O1xuICAgICAgICB2ZWM0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgYiAgPSBpbmRpY2VzWzBdOyAvLyBiYXRjaCBzaXplXG4gICAgICAgICAgaW50IG9oID0gaW5kaWNlc1sxXSAqIHN0cmlkZUggLSBwYWRIOyAvL291dHB1dCBoZWlnaHRcbiAgICAgICAgICBpbnQgb3cgPSBpbmRpY2VzWzJdICogc3RyaWRlVyAtIHBhZFc7IC8vb3V0cHV0IHdpZHRoXG4gICAgICAgICAgaW50IHAgPSBpbmRpY2VzWzNdICogb3V0cHV0Q2hhbm5lbHM7IC8vcGF0Y2hcbiAgICAgICAgICB2ZWM0IHZhbHVlID0gdmVjNCgwLjApO1xuICAgICAgICAgIGZvcihpbnQgaT0wOyBpIDwgb3V0cHV0Q2hhbm5lbHM7ICsraSkge1xuICAgICAgICAgICAgaWYocCA8IFhDS0hLVykge1xuICAgICAgICAgICAgICBpbnQgcGF0Y2hDID0gcCAvIEtIS1c7XG4gICAgICAgICAgICAgIGludCBwYXRjaEggPSAocCAtIHBhdGNoQypLSEtXKSAvIEtXO1xuICAgICAgICAgICAgICBpbnQgcGF0Y2hXID0gKHAgLSBwYXRjaEMqS0hLVykgLSBwYXRjaEggKiBLVztcbiAgICAgICAgICAgICAgaW50IHhoMiA9IG9oICsgcGF0Y2hIICogZGlsYXRpb25IO1xuICAgICAgICAgICAgICBpbnQgeHcyID0gb3cgKyBwYXRjaFcgKiBkaWxhdGlvblc7XG4gICAgICAgICAgICAgIGludCB4WyR7eHNoYXBlLmxlbmd0aH1dO1xuICAgICAgICAgICAgICB4WzBdID0gYjtcbiAgICAgICAgICAgICAgeFsxXSA9IHBhdGNoQztcbiAgICAgICAgICAgICAgeFsyXSA9IHhoMjtcbiAgICAgICAgICAgICAgeFszXSA9IHh3MjtcbiAgICAgICAgICAgICAgaWYoeGgyID49IDAgJiZcbiAgICAgICAgICAgICAgICAgIHhoMiA8IFhIICYmXG4gICAgICAgICAgICAgICAgICB4dzIgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgeHcyIDwgWFcpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZVtpXSA9IF9YKHgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICArK3A7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbTJjb2xEaW1zLCB0eXBlOiB4LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUltMkNvbFByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIHg6IFRlbnNvcixcbiAgdzogVGVuc29yLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZUltMkNvbFByb2dyYW1NZXRhZGF0YShhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBnZXQ6ICgpID0+IGNyZWF0ZUltMkNvbFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhLCB4LCB3LCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcyksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY2FsY3VsYXRlSW0yQ29sRGltcyA9IChcbiAgaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBjaGFubmVscyA9IDQsXG4pOiBudW1iZXJbXSA9PiBbXG4gIG91dHB1dFNoYXBlWzBdLFxuICBvdXRwdXRTaGFwZVsyXSxcbiAgb3V0cHV0U2hhcGVbM10sXG4gIE1hdGguY2VpbCgoaW5wdXRTaGFwZVsxXSAqIGtlcm5lbFNoYXBlWzJdICoga2VybmVsU2hhcGVbM10pIC8gY2hhbm5lbHMpLFxuXTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgZ2V0QWN0aXZhdGlvblNuaXBwZXQsIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuaW1wb3J0IHsgY2FsY3VsYXRlSW0yQ29sRGltcyB9IGZyb20gJy4vaW0yY29sJztcblxuY29uc3QgY3JlYXRlRG90UHJvZHVjdFByb2dyYW1NZXRhZGF0YSA9IChoYXNCaWFzOiBib29sZWFuLCBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKSA9PiAoe1xuICBuYW1lOiAnQ29udkRvdFByb2R1Y3QnLFxuICBpbnB1dE5hbWVzOiBoYXNCaWFzID8gWydJbTJDb2wnLCAnSycsICdCJ10gOiBbJ0ltMkNvbCcsICdLJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXNcbiAgICA/IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbiwgVGV4dHVyZVR5cGUudW5wYWNrZWRdXG4gICAgOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb25dLFxuICBjYWNoZUtleTogYXR0cmlidXRlcy5hY3RpdmF0aW9uQ2FjaGVLZXksXG59KTtcblxuY29uc3QgY3JlYXRlRG90UHJvZHVjdFByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIG91dHB1dFNoYXBlOiBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgeHNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGtzaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBhZGp1c3RlZEtlcm5lbFNoYXBlID0gW2tzaGFwZVswXSwgTWF0aC5jZWlsKCh4c2hhcGVbMV0gKiBrc2hhcGVbMl0gKiBrc2hhcGVbM10pIC8gNCldO1xuICBjb25zdCBpbTJjb2xTaGFwZSA9IGNhbGN1bGF0ZUltMkNvbERpbXMoeHNoYXBlLCBrc2hhcGUsIG91dHB1dFNoYXBlKTtcbiAgY29uc3QgW2tXaWR0aCwga0hlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBhZGp1c3RlZEtlcm5lbFNoYXBlLFxuICAgIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24sXG4gICk7XG5cbiAgY29uc3QgaW0yY29sU3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhpbTJjb2xTaGFwZSk7XG4gIGNvbnN0IFtpbTJjb2xXaWR0aCwgaW0yY29sSGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGltMmNvbFNoYXBlLFxuICAgIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24sXG4gICk7XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3QgaW5pdFZhbHVlID0gaW5wdXRzLmxlbmd0aCA8IDMgPyAnMC4wJyA6ICdfQihiKSc7XG4gIGNvbnN0IHNoYXJlZERpbSA9IE1hdGguY2VpbCgoeHNoYXBlWzFdICoga3NoYXBlWzJdICoga3NoYXBlWzNdKSAvIDQpO1xuICBjb25zdCB7IGFjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9uIH0gPSBnZXRBY3RpdmF0aW9uU25pcHBldChhdHRyaWJ1dGVzKTtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4ke2FjdGl2YXRpb25GdW5jdGlvbn1cbmZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgaW50IGJbMV07XG4gIGJbMF0gPSBpbmRpY2VzWzFdO1xuICBpbnQgaW0yY29sWzRdO1xuICBpbTJjb2xbMF0gPSBpbmRpY2VzWzBdO1xuICBpbTJjb2xbMV0gPSBpbmRpY2VzWzJdO1xuICBpbTJjb2xbMl0gPSBpbmRpY2VzWzNdO1xuICBpbnQgaW0yY29sT2Zmc2V0ID0gaW0yY29sWzBdICogJHtpbTJjb2xTdHJpZGVzWzBdfSArIGltMmNvbFsxXSAqICR7aW0yY29sU3RyaWRlc1sxXX0gKyBpbTJjb2xbMl0gKiAke1xuICAgIGltMmNvbFN0cmlkZXNbMl1cbiAgfTtcbiAgaW50IGtlcm5lbE9mZnNldCA9IGluZGljZXNbMV0gKiAke2FkanVzdGVkS2VybmVsU2hhcGVbMV19O1xuICBmbG9hdCB2YWx1ZSA9ICR7aW5pdFZhbHVlfTtcbiAgZm9yIChpbnQgaSA9IDA7IGkgPCAke3NoYXJlZERpbX07ICsraSkge1xuICAgIHZlYzIgaW0yY29sQ29vcmRzID0gb2Zmc2V0VG9Db29yZHMoaW0yY29sT2Zmc2V0LCAke2ltMmNvbFdpZHRofSwgJHtpbTJjb2xIZWlnaHR9KTtcbiAgICB2ZWMyIGtlcm5lbENvb3JkcyA9IG9mZnNldFRvQ29vcmRzKGtlcm5lbE9mZnNldCwgJHtrV2lkdGh9LCAke2tIZWlnaHR9KTtcbiAgICB2YWx1ZSArPSBkb3QoJHtnbHNsLnRleHR1cmUyRH0oSW0yQ29sLCBpbTJjb2xDb29yZHMpLCAke2dsc2wudGV4dHVyZTJEfShLLCBrZXJuZWxDb29yZHMpKTtcbiAgICArK2ltMmNvbE9mZnNldDtcbiAgICArK2tlcm5lbE9mZnNldDtcbiAgfVxuICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgcmV0dXJuIHZhbHVlO1xufWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBvdXRwdXRTaGFwZTogbnVtYmVyW10sXG4gIGF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlRG90UHJvZHVjdFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoID4gMiwgYXR0cmlidXRlcyk7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgZ2V0OiAoKSA9PiBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpLFxuICB9O1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uLy4uLy4uL2JhY2tlbmQnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBQb29sQ29udlV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuaW1wb3J0IHsgY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9jb252LWdyb3VwZWQnO1xuaW1wb3J0IHsgY29udjJEUGFja2VkIH0gZnJvbSAnLi9jb252LXBhY2snO1xuaW1wb3J0IHsgY3JlYXRlRG90UHJvZHVjdFByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9kb3QtcHJvZHVjdCc7XG5pbXBvcnQgeyBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLCBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuaW1wb3J0IHsgY3JlYXRlSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL2ltMmNvbCc7XG5pbXBvcnQgeyBjcmVhdGVNYXRtdWxQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vbWF0bXVsJztcblxuZXhwb3J0IGNvbnN0IGNhbGN1bGF0ZU91dHB1dFNoYXBlID0gKFxuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBhZGp1c3RQYWRzOiByZWFkb25seSBudW1iZXJbXSxcbiAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBudW1iZXJbXSA9PiB7XG4gIGNvbnN0IGJhdGNoU2l6ZSA9IGlucHV0U2hhcGVbMF07XG4gIGNvbnN0IGlucHV0U3BhdGlhbFNoYXBlID0gaW5wdXRTaGFwZS5zbGljZSgyKTtcbiAgY29uc3Qgc3BhdGlhbFJhbmsgPSBpbnB1dFNwYXRpYWxTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IG91dENoYW5uZWxzID0ga2VybmVsU2hhcGVbMF07XG4gIGNvbnN0IGtlcm5lbFNwYXRpYWxTaGFwZSA9IGtlcm5lbFNoYXBlLnNsaWNlKDIpO1xuICBjb25zdCBkaWxhdGVkS2VybmVsU2hhcGUgPSBrZXJuZWxTcGF0aWFsU2hhcGUubWFwKCh2LCBpKSA9PiB2ICsgKHYgLSAxKSAqIChkaWxhdGlvbnNbaV0gLSAxKSk7XG4gIGNvbnN0IGlucHV0U3BhdGlhbFNoYXBlV2l0aFBhZCA9IGlucHV0U3BhdGlhbFNoYXBlLm1hcCgodiwgaSkgPT4gdiArIGFkanVzdFBhZHNbaV0gKyBhZGp1c3RQYWRzW2kgKyBzcGF0aWFsUmFua10pO1xuICBjb25zdCBvdXRwdXRTcGF0aWFsU2hhcGUgPSBpbnB1dFNwYXRpYWxTaGFwZVdpdGhQYWQubWFwKCh2LCBpKSA9PlxuICAgIE1hdGguZmxvb3IoKHYgLSBkaWxhdGVkS2VybmVsU2hhcGVbaV0gKyBzdHJpZGVzW2ldKSAvIHN0cmlkZXNbaV0pLFxuICApO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFtiYXRjaFNpemUsIG91dENoYW5uZWxzXS5jb25jYXQoLi4ub3V0cHV0U3BhdGlhbFNoYXBlKTtcbiAgcmV0dXJuIG91dHB1dFNoYXBlO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBDb252QXR0cmlidXRlcyBleHRlbmRzIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF1dG9QYWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgZ3JvdXA6IG51bWJlcjtcbiAgcmVhZG9ubHkga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBwYWRzOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbmV4cG9ydCBjb25zdCBjb252OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPENvbnZBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7IC8vIGN1cnJlbnRseSB3aWxsIGZhaWwgaWYgbm90IGNvbnYyRFxuICByZXR1cm4gY29udjJkKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyk7XG59O1xuXG5jb25zdCBjb252MmQ6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248Q29udkF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCBhZGp1c3RlZEF0dHJpYnV0ZXMgPSBnZXRBZGp1c3RlZENvbnZBdHRyaWJ1dGVzKGF0dHJpYnV0ZXMsIGlucHV0cyk7XG4gIGNvbnN0IHBhY2tNb2RlID0gaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLnBhY2s7XG4gIGNvbnN0IGlzUG9pbnR3aXNlID0gYWRqdXN0ZWRBdHRyaWJ1dGVzLmtlcm5lbFNoYXBlWzBdID09PSAxICYmIGFkanVzdGVkQXR0cmlidXRlcy5rZXJuZWxTaGFwZVsxXSA9PT0gMTtcbiAgaWYgKGFkanVzdGVkQXR0cmlidXRlcy5ncm91cCA+IDEpIHtcbiAgICBjb25zdCByZXN1bHQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgIGNyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyksXG4gICAgICBpbnB1dHMsXG4gICAgKTtcbiAgICByZXR1cm4gW3Jlc3VsdF07XG4gIH0gZWxzZSBpZiAoaXNQb2ludHdpc2UgJiYgcGFja01vZGUpIHtcbiAgICByZXR1cm4gW2NvbnYyRFVucGFja2VkUG9pbnR3aXNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzKV07XG4gIH0gZWxzZSBpZiAocGFja01vZGUgJiYgaW5wdXRzWzBdLmRpbXMubGVuZ3RoID09PSA0ICYmIGlucHV0c1swXS5kaW1zWzBdID09PSAxICYmICFpc1BvaW50d2lzZSkge1xuICAgIHJldHVybiBbY29udjJEUGFja2VkKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzKV07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtjb252MkRVbnBhY2tlZChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyldO1xuICB9XG59O1xuXG5jb25zdCBjb252MkRVbnBhY2tlZFBvaW50d2lzZSA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFRlbnNvciA9PiB7XG4gIGNvbnN0IHhzaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBrc2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBjYWxjdWxhdGVPdXRwdXRTaGFwZSh4c2hhcGUsIGtzaGFwZSwgYXR0cmlidXRlcy5kaWxhdGlvbnMsIGF0dHJpYnV0ZXMucGFkcywgYXR0cmlidXRlcy5zdHJpZGVzKTtcbiAgY29uc3QgcmVzaGFwZWRYID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBbeHNoYXBlWzFdLCB4c2hhcGVbMl0gKiB4c2hhcGVbM11dKTtcbiAgY29uc3QgcmVzaGFwZWRLID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzFdLCBba3NoYXBlWzBdLCBrc2hhcGVbMV1dKTtcblxuICBjb25zdCBtYXRtdWxJbnB1dHMgPSBpbnB1dHMubGVuZ3RoID4gMiA/IFtyZXNoYXBlZEssIHJlc2hhcGVkWCwgaW5wdXRzWzJdXSA6IFtyZXNoYXBlZEssIHJlc2hhcGVkWF07XG4gIGNvbnN0IG1hdG11bE91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvTG9hZGVyKG1hdG11bElucHV0cywgYXR0cmlidXRlcyksIG1hdG11bElucHV0cyk7XG4gIHJldHVybiBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChtYXRtdWxPdXRwdXQsIG91dHB1dFNoYXBlKTtcbn07XG5cbmNvbnN0IGNvbnYyRFVucGFja2VkID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgeHNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGtzaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGNhbGN1bGF0ZU91dHB1dFNoYXBlKHhzaGFwZSwga3NoYXBlLCBhdHRyaWJ1dGVzLmRpbGF0aW9ucywgYXR0cmlidXRlcy5wYWRzLCBhdHRyaWJ1dGVzLnN0cmlkZXMpO1xuICBjb25zdCB4SW0yQ29sID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgY3JlYXRlSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBpbnB1dHNbMV0sIG91dHB1dFNoYXBlLCBhdHRyaWJ1dGVzKSxcbiAgICBbaW5wdXRzWzBdXSxcbiAgKTtcblxuICBjb25zdCBkb3RQcm9kdWN0SW5wdXRzID0gaW5wdXRzLmxlbmd0aCA9PT0gMyA/IFt4SW0yQ29sLCBpbnB1dHNbMV0sIGlucHV0c1syXV0gOiBbeEltMkNvbCwgaW5wdXRzWzFdXTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgY3JlYXRlRG90UHJvZHVjdFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpLFxuICAgIGRvdFByb2R1Y3RJbnB1dHMsXG4gICk7XG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5jb25zdCBnZXRBZGp1c3RlZENvbnZBdHRyaWJ1dGVzID0gPFQgZXh0ZW5kcyBDb252QXR0cmlidXRlcz4oYXR0cmlidXRlczogVCwgaW5wdXRzOiBUZW5zb3JbXSk6IFQgPT4ge1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGUuc2xpY2UoKTtcbiAgLy8gaWYga2VybmVsU2hhcGUgaXMgbm90IHNwZWNpZmllZCBpbiB0aGUgYXR0cmlidXRlcyBvZiB0aGlzIG9wLCBpbmZlciBpdCBmcm9tIHRoZSB3ZWlnaHQgdGVuc29yIGRpbXNcbiAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChsZXQgaSA9IDI7IGkgPCBpbnB1dHNbMV0uZGltcy5sZW5ndGg7ICsraSkge1xuICAgICAga2VybmVsU2hhcGUucHVzaChpbnB1dHNbMV0uZGltc1tpXSk7XG4gICAgfVxuICB9XG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLnBhZHMuc2xpY2UoKTtcbiAgUG9vbENvbnZVdGlsLmFkanVzdFBhZHNCYXNlZE9uQXV0b1BhZChcbiAgICBpbnB1dHNbMF0uZGltcyxcbiAgICBhdHRyaWJ1dGVzLnN0cmlkZXMsXG4gICAgYXR0cmlidXRlcy5kaWxhdGlvbnMsXG4gICAga2VybmVsU2hhcGUsXG4gICAgcGFkcyxcbiAgICBhdHRyaWJ1dGVzLmF1dG9QYWQsXG4gICk7XG5cbiAgLy8gYWx3YXlzIHJldHVybiBhIG5ldyBvYmplY3Qgc28gZG9lcyBub3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCBhdHRyaWJ1dGVzXG4gIGNvbnN0IG5ld0F0dHJpYnV0ZXM6IFQgPSBPYmplY3QuYXNzaWduKHt9LCBhdHRyaWJ1dGVzKTtcbiAgT2JqZWN0LmFzc2lnbihuZXdBdHRyaWJ1dGVzLCB7IGtlcm5lbFNoYXBlLCBwYWRzLCBjYWNoZUtleTogYXR0cmlidXRlcy5jYWNoZUtleSB9KTtcbiAgcmV0dXJuIG5ld0F0dHJpYnV0ZXM7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VDb252QXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxDb252QXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IENvbnZBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXR0cmlidXRlcyA9IG5vZGUuYXR0cmlidXRlcztcbiAgY29uc3QgYWN0aXZhdGlvbkF0dHJpYnV0ZXMgPSBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMoYXR0cmlidXRlcyk7XG4gIC8vIFRPRE8gOiBNYWtlIHRoaXMgZ2VuZXJpYyBlbm91Z2ggdG8gY29tcHV0ZSBkZWZhdWx0IGF0dHJpYnV0ZXMgZm9yIG11bHRpLWRpbWVuc2lvbmFsIGNvbnZcbiAgY29uc3QgYXV0b1BhZCA9IGF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdhdXRvX3BhZCcsICdOT1RTRVQnKTtcbiAgY29uc3QgZGlsYXRpb25zID0gYXR0cmlidXRlcy5nZXRJbnRzKCdkaWxhdGlvbnMnLCBbMSwgMV0pO1xuICBjb25zdCBncm91cCA9IGF0dHJpYnV0ZXMuZ2V0SW50KCdncm91cCcsIDEpO1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMuZ2V0SW50cygna2VybmVsX3NoYXBlJywgW10pO1xuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5nZXRJbnRzKCdwYWRzJywgWzAsIDAsIDAsIDBdKTtcbiAgY29uc3Qgc3RyaWRlcyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnc3RyaWRlcycsIFsxLCAxXSk7XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgYXV0b1BhZCxcbiAgICBkaWxhdGlvbnMsXG4gICAgZ3JvdXAsXG4gICAga2VybmVsU2hhcGUsXG4gICAgcGFkcyxcbiAgICBzdHJpZGVzLFxuICAgIC4uLmFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuICB9KTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIC8vIFJlZmVyIHRvIHRoZSBiZWxvdyBsaW5rIGZvciBhbGwgaW5wdXQgY2hlY2tzXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9vbm54L29ubngvYmxvYi9tYWluL2RvY3MvT3BlcmF0b3JzLm1kI0NvbnZcbiAgaWYgKCFpbnB1dHMgfHwgKGlucHV0cy5sZW5ndGggIT09IDIgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnYgcmVxdWlyZXMgMiBvciAzIGlucHV0cycpO1xuICB9XG5cbiAgLy8gVE9ETyA6IE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIG11bHRpLWRpbWVuc2lvbmFsIGNvbnZcbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCB8fCBpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2N1cnJlbnRseSBvbmx5IHN1cHBvcnQgMi1kaW1lbnNpb25hbCBjb252Jyk7XG4gIH1cblxuICAvLyBGSUxURVJfSU5fQ0hBTk5FTCBzaG91bGQgYmUgZXF1YWwgdG8gREFUQV9DSEFOTkVMXG4gIGNvbnN0IGRhdGFDaGFubmVsID0gaW5wdXRzWzBdLmRpbXNbMV07XG4gIGNvbnN0IGZpbHRlckluQ2hhbm5lbCA9IGlucHV0c1sxXS5kaW1zWzFdICogYXR0cmlidXRlcy5ncm91cDtcbiAgaWYgKGRhdGFDaGFubmVsICE9PSBmaWx0ZXJJbkNoYW5uZWwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZJTFRFUl9JTl9DSEFOTkVMIHNob3VsZCBiZSBlcXVhbCB0byBEQVRBX0NIQU5ORUwnKTtcbiAgfVxuXG4gIC8vIGlmIGJpYXMgaXMgcHJvdmlkZWQgaXQgc2hvdWxkIGJlIDFEIGFuZCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHNob3VsZCBiZSBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGZlYXR1cmUgbWFwc1xuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiAoaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAxIHx8IGlucHV0c1sxXS5kaW1zWzBdICE9PSBpbnB1dHNbMl0uZGltc1swXSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYmlhcycpO1xuICB9XG5cbiAgY29uc3Qgc3BhdGlhbFJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAyO1xuICAvLyB3cm9uZyBkaWxhdGlvbnMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLmRpbGF0aW9ucy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBkaWxhdGlvbnMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gV3Jvbmcgc3RyaWRlcyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBzdHJpZGVzIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIHBhZHMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLnBhZHMubGVuZ3RoICE9PSBzcGF0aWFsUmFuayAqIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHBhZHMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmsgKiAyfURgKTtcbiAgfVxuXG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIHNwZWNpZmllZCwgaXQncyBkYXRhIGxlbmd0aCBtdXN0IGJlIDIgbGVzcyB0aGFuIGRpbXMgbGVuZ3RoIG9mIHRoZSB3ZWlnaHRzIHRlbnNvclxuICAvLyAodGhlIGZpcnN0IDIgZGltcyBhcmUgYmF0Y2hfc2l6ZSBhbmQgY2hhbm5lbHMpXG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gMCAmJiBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBrZXJuZWwgc2hhcGUnKTtcbiAgfVxuXG4gIC8vIFRPRE8gOiBOZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBmbG9hdDY0XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInIHx8IGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnYgaW5wdXQoWCxXKSBzaG91bGQgYmUgZmxvYXQgdGVuc29yJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMl0udHlwZSAhPT0gJ2Zsb2F0MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252IGlucHV0KGJpYXMpIHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi8uLi8uLi9iYWNrZW5kJztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuL2NvbnYnO1xuaW1wb3J0IHsgZ2V0QWN0aXZhdGlvblNuaXBwZXQsIHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5cbmNvbnN0IGNvbXB1dGVUb3RhbFBhZCA9IChcbiAgaW5EaW06IG51bWJlcixcbiAgc3RyaWRlOiBudW1iZXIsXG4gIGFkajogbnVtYmVyLFxuICBrZXJuZWw6IG51bWJlcixcbiAgZGlsYXRpb246IG51bWJlcixcbiAgb3V0U2l6ZTogbnVtYmVyLFxuKSA9PiAoaW5EaW0gLSAxKSAqIHN0cmlkZSArIGFkaiArIChrZXJuZWwgLSAxKSAqIGRpbGF0aW9uICsgMSAtIG91dFNpemU7XG5cbmNvbnN0IGRpc3RyaWJ1dGVQYWRkaW5nID0gKHRvdGFsUGFkOiBudW1iZXIsIGF1dG9QYWQ6IHN0cmluZywgcGFkczogbnVtYmVyW10sIGhlYWQ6IG51bWJlciwgdGFpbDogbnVtYmVyKSA9PiB7XG4gIGNvbnN0IHNtYWxsUGFkID0gTWF0aC5mbG9vcih0b3RhbFBhZCAvIDIpO1xuICBpZiAoYXV0b1BhZCA9PT0gJ1NBTUVfVVBQRVInKSB7XG4gICAgcGFkc1toZWFkXSA9IHNtYWxsUGFkO1xuICAgIHBhZHNbdGFpbF0gPSB0b3RhbFBhZCAtIHNtYWxsUGFkO1xuICB9IGVsc2UgaWYgKGF1dG9QYWQgPT09ICdTQU1FX0xPV0VSJykge1xuICAgIHBhZHNbaGVhZF0gPSB0b3RhbFBhZCAtIHNtYWxsUGFkO1xuICAgIHBhZHNbdGFpbF0gPSBzbWFsbFBhZDtcbiAgfVxufTtcblxuY29uc3QgY2FsY3VsYXRlT3V0cHV0U2hhcGVBbmRQYWRzID0gKFxuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBhdXRvUGFkOiBzdHJpbmcsXG4gIHBhZHM6IG51bWJlcltdLFxuICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgb3V0cHV0UGFkZGluZzogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG91dHB1dFNoYXBlOiBudW1iZXJbXSxcbikgPT4ge1xuICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0U2hhcGUubGVuZ3RoIC0gMjtcbiAgY29uc3QgdXBkYXRlU2hhcGUgPSBvdXRwdXRTaGFwZS5sZW5ndGggPT09IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc3BhdGlhbFJhbms7ICsraSkge1xuICAgIGNvbnN0IG91dFNpemUgPSB1cGRhdGVTaGFwZSA/IGlucHV0U2hhcGVbaSArIDJdICogc3RyaWRlc1tpXSA6IG91dHB1dFNoYXBlW2ldO1xuICAgIGNvbnN0IHRvdGFsUGFkID0gY29tcHV0ZVRvdGFsUGFkKGlucHV0U2hhcGVbaSArIDJdLCBzdHJpZGVzW2ldLCBwYWRzW2ldLCBrZXJuZWxTaGFwZVtpXSwgZGlsYXRpb25zW2ldLCBvdXRTaXplKTtcbiAgICBkaXN0cmlidXRlUGFkZGluZyh0b3RhbFBhZCwgYXV0b1BhZCwgcGFkcywgaSwgaSArIHNwYXRpYWxSYW5rKTtcbiAgICBpZiAodXBkYXRlU2hhcGUpIHtcbiAgICAgIG91dHB1dFNoYXBlLnB1c2goXG4gICAgICAgIHN0cmlkZXNbaV0gKiAoaW5wdXRTaGFwZVtpICsgMl0gLSAxKSArXG4gICAgICAgICAgb3V0cHV0UGFkZGluZ1tpXSArXG4gICAgICAgICAgKGtlcm5lbFNoYXBlW2ldIC0gMSkgKiBkaWxhdGlvbnNbaV0gK1xuICAgICAgICAgIDEgLVxuICAgICAgICAgIHBhZHNbaV0gLVxuICAgICAgICAgIHBhZHNbaSArIHNwYXRpYWxSYW5rXSxcbiAgICAgICk7XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzIGV4dGVuZHMgQ29udkF0dHJpYnV0ZXMge1xuICByZWFkb25seSBvdXRwdXRQYWRkaW5nOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5leHBvcnQgY29uc3QgY29udlRyYW5zcG9zZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxDb252VHJhbnNwb3NlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGF0dHJpYnV0ZXMpOyAvLyBjdXJyZW50bHkgd2lsbCBmYWlsIGlmIG5vdCBjb252VHJhbnNwb3NlMkRcbiAgcmV0dXJuIGNvbnZUcmFuc3Bvc2UyZChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpO1xufTtcblxuY29uc3QgY29udlRyYW5zcG9zZTJkOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgYWRqdXN0ZWRBdHRyaWJ1dGVzID0gZ2V0QWRqdXN0ZWRDb252VHJhbnNwb3NlQXR0cmlidXRlcyhhdHRyaWJ1dGVzLCBpbnB1dHMpO1xuICByZXR1cm4gW2NvbnZUcmFuc3Bvc2UyRFVucGFja2VkKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzKV07XG59O1xuXG5jb25zdCBjcmVhdGVDb252VHJhbnNwb3NlUHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnQ29udlRyYW5zcG9zZScsXG4gIGlucHV0TmFtZXM6IGhhc0JpYXMgPyBbJ1gnLCAnVycsICdCJ10gOiBbJ1gnLCAnVyddLFxuICBpbnB1dFR5cGVzOiBoYXNCaWFzXG4gICAgPyBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF1cbiAgICA6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRDb252VHJhbnNwb3NlUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID4gMjtcbiAgY29uc3QgdmFsdWVJbml0ID0gaGFzQmlhcyA/ICdnZXRCKG91dHB1dF9jaGFubmVsKScgOiAnMC4wJztcbiAgY29uc3QgeFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IHdTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBvdXRwdXRDaGFubmVsc1Blckdyb3VwID0gd1NoYXBlWzFdO1xuICBjb25zdCBpbnB1dENoYW5uZWxzUGVyR3JvdXAgPSB3U2hhcGVbMF0gLyBhdHRyaWJ1dGVzLmdyb3VwO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFtpbnB1dHNbMF0uZGltc1swXSwgaW5wdXRzWzFdLmRpbXNbMV0gKiBhdHRyaWJ1dGVzLmdyb3VwLCAuLi5hdHRyaWJ1dGVzLm91dHB1dFNoYXBlXTtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCB7IGFjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9uIH0gPSBnZXRBY3RpdmF0aW9uU25pcHBldChhdHRyaWJ1dGVzKTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gIGNvbnN0IGl2ZWMyIHN0cmlkZXMgPSBpdmVjMigke2F0dHJpYnV0ZXMuc3RyaWRlc1swXX0sICR7YXR0cmlidXRlcy5zdHJpZGVzWzFdfSk7XG4gIGNvbnN0IGl2ZWMyIHBhZHMgPSBpdmVjMigke2F0dHJpYnV0ZXMucGFkc1swXX0sICR7YXR0cmlidXRlcy5wYWRzWzFdfSk7XG4gICR7YWN0aXZhdGlvbkZ1bmN0aW9ufVxuICB2b2lkIG1haW4oKSB7XG4gICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgaW50IGJhdGNoID0gY29vcmRzLng7XG4gICAgaW50IG91dHB1dF9jaGFubmVsID0gY29vcmRzLnk7XG5cbiAgICBpdmVjMiBsb2MgPSBjb29yZHMuencgKyBwYWRzO1xuXG4gICAgaW50IGdyb3VwX2lkID0gb3V0cHV0X2NoYW5uZWwgLyAke291dHB1dENoYW5uZWxzUGVyR3JvdXB9O1xuICAgIGludCB3T3V0Q2hhbm5lbCA9IG91dHB1dF9jaGFubmVsIC0gZ3JvdXBfaWQgKiAke291dHB1dENoYW5uZWxzUGVyR3JvdXB9O1xuXG4gICAgZmxvYXQgdmFsdWUgPSAke3ZhbHVlSW5pdH07XG4gICAgZm9yIChpbnQgaW5DaGFubmVsT2Zmc2V0ID0gMDsgaW5DaGFubmVsT2Zmc2V0IDwgJHtpbnB1dENoYW5uZWxzUGVyR3JvdXB9OyBpbkNoYW5uZWxPZmZzZXQrKykge1xuICAgICAgaW50IGlucHV0X2NoYW5uZWwgPSBncm91cF9pZCAqICR7aW5wdXRDaGFubmVsc1Blckdyb3VwfSArIGluQ2hhbm5lbE9mZnNldDtcbiAgICAgIGZvciAoaW50IHdXT2ZmID0gMDsgd1dPZmYgPCAke3dTaGFwZVsyXX07IHdXT2ZmKyspIHtcbiAgICAgICAgZm9yIChpbnQgd0hPZmYgPSAwOyB3SE9mZiA8ICR7d1NoYXBlWzNdfTsgd0hPZmYrKykge1xuICAgICAgICAgIGl2ZWMyIHdPZmYgPSBpdmVjMih3V09mZiAqICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMF19LCB3SE9mZiAqICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMV19KTtcbiAgICAgICAgICBpdmVjMiB3TG9jID0gbG9jIC0gd09mZjtcbiAgICAgICAgICBpdmVjMiB3TG9jSW4gPSB3TG9jIC8gc3RyaWRlcztcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB3TG9jSW4gKiBzdHJpZGVzID09IHdMb2MgJiZcbiAgICAgICAgICAgIHdMb2NJbi54ID49IDAgJiYgd0xvY0luLnggPCAke3hTaGFwZVsyXX0gJiZcbiAgICAgICAgICAgIHdMb2NJbi55ID49IDAgJiYgd0xvY0luLnkgPCAke3hTaGFwZVszXX1cbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGZsb2F0IHhWYWwgPSBnZXRYKGJhdGNoLCBpbnB1dF9jaGFubmVsLCB3TG9jSW4ueSwgd0xvY0luLngpO1xuICAgICAgICAgICAgZmxvYXQgd1ZhbCA9IGdldFcoaW5wdXRfY2hhbm5lbCwgd091dENoYW5uZWwsIHdIT2ZmLCB3V09mZik7XG4gICAgICAgICAgICB2YWx1ZSArPSB4VmFsICogd1ZhbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KHZhbHVlLCAuMCwgLjAsIC4wKTtcbiAgfVxuYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkQ29udlRyYW5zcG9zZVByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZUNvbnZUcmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCA+IDIsIGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIGdldDogKCkgPT4gY3JlYXRlVW5wYWNrZWRDb252VHJhbnNwb3NlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBtZXRhZGF0YSwgYXR0cmlidXRlcyksXG4gIH07XG59O1xuXG5jb25zdCBjb252VHJhbnNwb3NlMkRVbnBhY2tlZCA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyxcbik6IFRlbnNvciA9PiB7XG4gIGNvbnN0IHJlc3VsdCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZVVucGFja2VkQ29udlRyYW5zcG9zZVByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRDb252VHJhbnNwb3NlQXR0cmlidXRlcyA9IDxUIGV4dGVuZHMgQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXM+KGF0dHJpYnV0ZXM6IFQsIGlucHV0czogVGVuc29yW10pOiBUID0+IHtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLnNsaWNlKCk7XG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIGF0dHJpYnV0ZXMgb2YgdGhpcyBvcCwgaW5mZXIgaXQgZnJvbSB0aGUgd2VpZ2h0IHRlbnNvciBkaW1zXG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgIGZvciAobGV0IGkgPSAyOyBpIDwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGtlcm5lbFNoYXBlLnB1c2goaW5wdXRzWzFdLmRpbXNbaV0pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLnBhZHMuc2xpY2UoKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBhdHRyaWJ1dGVzLm91dHB1dFNoYXBlLnNsaWNlKCk7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgLy8gSWYgb3V0cHV0U2hhcGUgaXMgbm90IHNwZWNpZmllZCBpbiB0aGUgYXR0cmlidXRlcyBvZiB0aGlzIG9wLCBpbmZlciBpdCBmcm9tIHRoZSBwYXJhbWV0ZXJzXG4gIC8vIFNpbWlsYXJseSwgYXV0b21hdGljYWxseSBpbmZlciBwYWRzIGlmIG5vdCBzcGVjaWZpZWRcbiAgY2FsY3VsYXRlT3V0cHV0U2hhcGVBbmRQYWRzKFxuICAgIGlucHV0U2hhcGUsXG4gICAga2VybmVsU2hhcGUsXG4gICAgYXR0cmlidXRlcy5kaWxhdGlvbnMsXG4gICAgYXR0cmlidXRlcy5hdXRvUGFkLFxuICAgIHBhZHMsXG4gICAgYXR0cmlidXRlcy5zdHJpZGVzLFxuICAgIGF0dHJpYnV0ZXMub3V0cHV0UGFkZGluZyxcbiAgICBvdXRwdXRTaGFwZSxcbiAgKTtcblxuICAvLyBhbHdheXMgcmV0dXJuIGEgbmV3IG9iamVjdCBzbyBkb2VzIG5vdCBtb2RpZnkgdGhlIG9yaWdpbmFsIGF0dHJpYnV0ZXNcbiAgY29uc3QgbmV3QXR0cmlidXRlczogVCA9IE9iamVjdC5hc3NpZ24oe30sIGF0dHJpYnV0ZXMpO1xuICBPYmplY3QuYXNzaWduKG5ld0F0dHJpYnV0ZXMsIHsga2VybmVsU2hhcGUsIHBhZHMsIG91dHB1dFNoYXBlLCBjYWNoZUtleTogYXR0cmlidXRlcy5jYWNoZUtleSB9KTtcbiAgcmV0dXJuIG5ld0F0dHJpYnV0ZXM7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VDb252VHJhbnNwb3NlQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxDb252VHJhbnNwb3NlQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSBub2RlLmF0dHJpYnV0ZXM7XG4gIGNvbnN0IGFjdGl2YXRpb25BdHRyaWJ1dGVzID0gcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKGF0dHJpYnV0ZXMpO1xuICAvLyBUT0RPIDogTWFrZSB0aGlzIGdlbmVyaWMgZW5vdWdoIHRvIGNvbXB1dGUgZGVmYXVsdCBhdHRyaWJ1dGVzIGZvciBtdWx0aS1kaW1lbnNpb25hbCBjb252XG4gIGNvbnN0IGF1dG9QYWQgPSBhdHRyaWJ1dGVzLmdldFN0cmluZygnYXV0b19wYWQnLCAnTk9UU0VUJyk7XG4gIGNvbnN0IGRpbGF0aW9ucyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnZGlsYXRpb25zJywgWzEsIDFdKTtcbiAgY29uc3QgZ3JvdXAgPSBhdHRyaWJ1dGVzLmdldEludCgnZ3JvdXAnLCAxKTtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmdldEludHMoJ2tlcm5lbF9zaGFwZScsIFtdKTtcbiAgY29uc3Qgb3V0cHV0UGFkZGluZyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnb3V0cHV0X3BhZGRpbmcnLCBbMCwgMF0pO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnb3V0cHV0X3NoYXBlJywgW10pO1xuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5nZXRJbnRzKCdwYWRzJywgWzAsIDAsIDAsIDBdKTtcbiAgY29uc3Qgc3RyaWRlcyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnc3RyaWRlcycsIFsxLCAxXSk7XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgYXV0b1BhZCxcbiAgICBkaWxhdGlvbnMsXG4gICAgZ3JvdXAsXG4gICAga2VybmVsU2hhcGUsXG4gICAgb3V0cHV0UGFkZGluZyxcbiAgICBvdXRwdXRTaGFwZSxcbiAgICBwYWRzLFxuICAgIHN0cmlkZXMsXG4gICAgLi4uYWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4gIH0pO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgLy8gUmVmZXIgdG8gdGhlIGJlbG93IGxpbmsgZm9yIGFsbCBpbnB1dCBjaGVja3NcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9PcGVyYXRvcnMubWQjQ29udlxuICBpZiAoIWlucHV0cyB8fCAoaW5wdXRzLmxlbmd0aCAhPT0gMiAmJiBpbnB1dHMubGVuZ3RoICE9PSAzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udiByZXF1aXJlcyAyIG9yIDMgaW5wdXRzJyk7XG4gIH1cblxuICAvLyBUT0RPIDogTmVlZCB0byBhZGQgc3VwcG9ydCBmb3IgbXVsdGktZGltZW5zaW9uYWwgY29udlxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0IHx8IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY3VycmVudGx5IG9ubHkgc3VwcG9ydCAyLWRpbWVuc2lvbmFsIGNvbnYnKTtcbiAgfVxuXG4gIC8vIEZJTFRFUl9JTl9DSEFOTkVMIHNob3VsZCBiZSBlcXVhbCB0byBEQVRBX0NIQU5ORUxcbiAgY29uc3QgZGF0YUNoYW5uZWwgPSBpbnB1dHNbMF0uZGltc1sxXTtcbiAgY29uc3QgZmlsdGVySW5DaGFubmVsID0gaW5wdXRzWzFdLmRpbXNbMF07XG4gIGlmIChkYXRhQ2hhbm5lbCAhPT0gZmlsdGVySW5DaGFubmVsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGSUxURVJfSU5fQ0hBTk5FTCBzaG91bGQgYmUgZXF1YWwgdG8gREFUQV9DSEFOTkVMJyk7XG4gIH1cblxuICBjb25zdCBmZWF0dXJlTWFwcyA9IGlucHV0c1sxXS5kaW1zWzFdICogYXR0cmlidXRlcy5ncm91cDtcblxuICAvLyBpZiBiaWFzIGlzIHByb3ZpZGVkIGl0IHNob3VsZCBiZSAxRCBhbmQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBzaG91bGQgYmUgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBmZWF0dXJlIG1hcHNcbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgKGlucHV0c1syXS5kaW1zLmxlbmd0aCAhPT0gMSB8fCBpbnB1dHNbMl0uZGltc1swXSAhPT0gZmVhdHVyZU1hcHMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGJpYXMnKTtcbiAgfVxuXG4gIGNvbnN0IHNwYXRpYWxSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMjtcbiAgLy8gd3JvbmcgZGlsYXRpb25zIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5kaWxhdGlvbnMubGVuZ3RoICE9PSBzcGF0aWFsUmFuaykge1xuICAgIHRocm93IG5ldyBFcnJvcihgZGlsYXRpb25zIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIHN0cmlkZXMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLnN0cmlkZXMubGVuZ3RoICE9PSBzcGF0aWFsUmFuaykge1xuICAgIHRocm93IG5ldyBFcnJvcihgc3RyaWRlcyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBwYWRzIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmsgKiAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBwYWRzIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rICogMn1EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBvdXRwdXQgcGFkZGluZyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMub3V0cHV0UGFkZGluZy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBvdXRwdXRfcGFkZGluZyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBpZiBrZXJuZWxTaGFwZSBpcyBzcGVjaWZpZWQsIGl0J3MgZGF0YSBsZW5ndGggbXVzdCBiZSAyIGxlc3MgdGhhbiBkaW1zIGxlbmd0aCBvZiB0aGUgd2VpZ2h0cyB0ZW5zb3JcbiAgLy8gKHRoZSBmaXJzdCAyIGRpbXMgYXJlIGJhdGNoX3NpemUgYW5kIGNoYW5uZWxzKVxuICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggIT09IDAgJiYgYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggIT09IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAtIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQga2VybmVsIHNoYXBlJyk7XG4gIH1cblxuICAvLyBhcyB3aXRoIGtlcm5lbFNoYXBlLCBtdXN0IGhhdmUgc2FtZSBudW1iZXIgb2Ygc3BhdGlhbCBkaW1zIGFzIGlucHV0XG4gIGlmIChhdHRyaWJ1dGVzLm91dHB1dFNoYXBlLmxlbmd0aCAhPT0gMCAmJiBhdHRyaWJ1dGVzLm91dHB1dFNoYXBlLmxlbmd0aCAhPT0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBvdXRwdXQgc2hhcGUnKTtcbiAgfVxuXG4gIC8vIFRPRE8gOiBOZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBmbG9hdDY0XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInIHx8IGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnZUcmFuc3Bvc2UgaW5wdXQoWCxXKSBzaG91bGQgYmUgZmxvYXQgdGVuc29yJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMl0udHlwZSAhPT0gJ2Zsb2F0MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252VHJhbnNwb3NlIGlucHV0KGJpYXMpIHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc3Bvc2VBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgcGVybTogbnVtYmVyW107XG59XG5cbmNvbnN0IHRyYW5zcG9zZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1RyYW5zcG9zZScsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHRyYW5zcG9zZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxUcmFuc3Bvc2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBUcmFuc3Bvc2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7XG4gICAgICAuLi50cmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcy5wZXJtKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVHJhbnNwb3NlQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxUcmFuc3Bvc2VBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IFRyYW5zcG9zZUF0dHJpYnV0ZXMgPT4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgcGVybTogbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3Blcm0nLCBbXSkgfSk7XG5cbmNvbnN0IGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvID0gKFxuICBfaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBwZXJtOiBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0LmRpbXM7XG4gIHBlcm0gPSBnZXRBZGp1c3RlZFBlcm0oaW5wdXRTaGFwZSwgcGVybSk7XG4gIGNvbnN0IHVucGFja2VkT3V0cHV0U2hhcGUgPSBnZXRPdXRwdXRTaGFwZShpbnB1dFNoYXBlLCBwZXJtKTtcbiAgY29uc3QgcmFuayA9IGlucHV0U2hhcGUubGVuZ3RoO1xuICAvLyBBIGRpbXM9WyR7aW5wdXRzWzBdLmRpbXMudG9TdHJpbmcoKX1dXG4gIC8vIG91dCBEaW1zPVske3VucGFja2VkT3V0cHV0U2hhcGUudG9TdHJpbmcoKX1dXG4gIC8vIGJhc2VkIG9uIHBlcm09WyR7cGVybS50b1N0cmluZygpfV1cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHtnZXRQZXJtRnVuY3Rpb25Cb2R5KCdwZXJtJywgcGVybSwgcmFuayl9XG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgIGludCBhWyR7cmFua31dO1xuICAgICAgICBwZXJtKGEsIGluZGljZXMpO1xuICAgICAgICByZXR1cm4gX0EoYSk7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi50cmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IHVucGFja2VkT3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGdldEFkanVzdGVkUGVybSA9IChpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcGVybTogbnVtYmVyW10pOiBudW1iZXJbXSA9PiB7XG4gIGlmIChwZXJtICYmIHBlcm0ubGVuZ3RoICE9PSBpbnB1dFNoYXBlLmxlbmd0aCkge1xuICAgIHBlcm0gPSBbLi4uaW5wdXRTaGFwZS5rZXlzKCldLnJldmVyc2UoKTtcbiAgfVxuICByZXR1cm4gcGVybTtcbn07XG5cbmNvbnN0IGdldE91dHB1dFNoYXBlID0gKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwZXJtOiBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdID0+IHtcbiAgcGVybSA9IGdldEFkanVzdGVkUGVybShpbnB1dFNoYXBlLCBwZXJtKTtcbiAgcmV0dXJuIFNoYXBlVXRpbC5zb3J0QmFzZWRPblBlcm0oaW5wdXRTaGFwZSwgcGVybSk7XG59O1xuXG5jb25zdCBnZXRQZXJtRnVuY3Rpb25Cb2R5ID0gKG5hbWU6IHN0cmluZywgcGVybTogbnVtYmVyW10sIHJhbms6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHJldmVyc2VGdW5jID0gW107XG4gIHJldmVyc2VGdW5jLnB1c2goYHZvaWQgJHtuYW1lfShvdXQgaW50IGFbJHtyYW5rfV0sIGludCBzcmNbJHtyYW5rfV0pIHtgKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICByZXZlcnNlRnVuYy5wdXNoKGBcXHRhWyR7cGVybVtpXX1dPXNyY1ske2l9XTtgKTtcbiAgfVxuICByZXZlcnNlRnVuYy5wdXNoKCdcXHR9Jyk7XG4gIHJldHVybiByZXZlcnNlRnVuYy5qb2luKCdcXG4nKTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVHJhbnNwb3NlIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCBzaG91bGQgYmUgZmxvYXQgdGVuc29yJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5pbXBvcnQgeyB0cmFuc3Bvc2UsIFRyYW5zcG9zZUF0dHJpYnV0ZXMgfSBmcm9tICcuL3RyYW5zcG9zZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVwdGhUb1NwYWNlQXR0cmlidXRlcyB7XG4gIG1vZGU6ICdEQ1InIHwgJ0NSRCc7XG4gIGJsb2Nrc2l6ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgZGVwdGhUb1NwYWNlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPERlcHRoVG9TcGFjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IERlcHRoVG9TcGFjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IGJsb2Nrc2l6ZSA9IGF0dHJpYnV0ZXMuYmxvY2tzaXplO1xuICBjb25zdCBibG9ja3NpemVTcXIgPSBibG9ja3NpemUgKiBibG9ja3NpemU7XG4gIGNvbnN0IHRyYW5zcG9zZVBlcm0gPSBhdHRyaWJ1dGVzLm1vZGUgPT09ICdEQ1InID8gWzAsIDMsIDQsIDEsIDUsIDJdIDogWzAsIDEsIDQsIDIsIDUsIDNdO1xuICBjb25zdCBmaXJzdFJlc2hhcGVTaGFwZSA9XG4gICAgYXR0cmlidXRlcy5tb2RlID09PSAnRENSJ1xuICAgICAgPyBbXG4gICAgICAgICAgaW5wdXRzWzBdLmRpbXNbMF0sXG4gICAgICAgICAgYmxvY2tzaXplLFxuICAgICAgICAgIGJsb2Nrc2l6ZSxcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1sxXSAvIGJsb2Nrc2l6ZVNxcixcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1syXSxcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1szXSxcbiAgICAgICAgXVxuICAgICAgOiBbXG4gICAgICAgICAgaW5wdXRzWzBdLmRpbXNbMF0sXG4gICAgICAgICAgaW5wdXRzWzBdLmRpbXNbMV0gLyBibG9ja3NpemVTcXIsXG4gICAgICAgICAgYmxvY2tzaXplLFxuICAgICAgICAgIGJsb2Nrc2l6ZSxcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1syXSxcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1szXSxcbiAgICAgICAgXTtcblxuICAvLyBjb25zdCB0cmFuc3Bvc2UgPSBuZXcgV2ViR0xUcmFuc3Bvc2UoKTtcbiAgLy8gY29uc3QgYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGUodW5kZWZpbmVkKTtcbiAgLy8gYXR0cmlidXRlcy5zZXQoJ3Blcm0nLCAnaW50cycsIHRyYW5zcG9zZVBlcm0pO1xuICAvLyB0cmFuc3Bvc2UuaW5pdGlhbGl6ZShhdHRyaWJ1dGVzKTtcblxuICAvLyBGaXJzdCByZXNoYXBlXG4gIGNvbnN0IGZpcnN0UmVzaGFwZWRUZW5zb3IgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIGZpcnN0UmVzaGFwZVNoYXBlKTtcblxuICAvLyB0cmFuc3Bvc2VcbiAgY29uc3QgdHJhbnNwb3NlQXR0cmlidXRlczogVHJhbnNwb3NlQXR0cmlidXRlcyA9IHsgcGVybTogdHJhbnNwb3NlUGVybSwgY2FjaGVLZXk6IGAke3RyYW5zcG9zZVBlcm19YCB9O1xuICBjb25zdCBbdHJhbnNwb3NlT3V0cHV0XSA9IHRyYW5zcG9zZShpbmZlcmVuY2VIYW5kbGVyLCBbZmlyc3RSZXNoYXBlZFRlbnNvcl0sIHRyYW5zcG9zZUF0dHJpYnV0ZXMpO1xuXG4gIC8vIFNlY29uZCByZXNoYXBlXG4gIGNvbnN0IHNlY29uZFJlc2hhcGVTaGFwZSA9IFtcbiAgICBpbnB1dHNbMF0uZGltc1swXSxcbiAgICBpbnB1dHNbMF0uZGltc1sxXSAvIGJsb2Nrc2l6ZVNxcixcbiAgICBpbnB1dHNbMF0uZGltc1syXSAqIGJsb2Nrc2l6ZSxcbiAgICBpbnB1dHNbMF0uZGltc1szXSAqIGJsb2Nrc2l6ZSxcbiAgXTtcbiAgY29uc3QgcmVzdWx0ID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQodHJhbnNwb3NlT3V0cHV0LCBzZWNvbmRSZXNoYXBlU2hhcGUpO1xuICByZXR1cm4gW3Jlc3VsdF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPERlcHRoVG9TcGFjZUF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogRGVwdGhUb1NwYWNlQXR0cmlidXRlcyA9PiB7XG4gIC8vIHByb2Nlc3Npbmcgbm9kZSBhdHRyaWJ1dGVzXG4gIGNvbnN0IGJsb2Nrc2l6ZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2Jsb2Nrc2l6ZScpO1xuICBpZiAoYmxvY2tzaXplIDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgYmxvY2tzaXplIG11c3QgYmUgPj0gMSwgYnV0IGdvdCA6ICR7YmxvY2tzaXplfSBmb3IgRGVwdGhUb1NwYWNlYCk7XG4gIH1cbiAgY29uc3QgbW9kZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ21vZGUnLCAnRENSJyk7XG4gIGlmIChtb2RlICE9PSAnRENSJyAmJiBtb2RlICE9PSAnQ1JEJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgdW5yZWNvZ25pemVkIG1vZGU6ICR7bW9kZX0gZm9yIERlcHRoVG9TcGFjZWApO1xuICB9XG4gIHJldHVybiB7IG1vZGUsIGJsb2Nrc2l6ZSB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRGVwdGhUb1NwYWNlIGV4cGVjdCAxIGlucHV0cywgYnV0IGdvdCAke2lucHV0cy5sZW5ndGh9YCk7XG4gIH1cblxuICAvLyBJbnB1dCBoYXMgdG8gYmUgYSA0LUQgdGVuc29yXG4gIC8vIFRPRE86IFN1cHBvcnQgc3RyaW5nIGRlcHRoLXRvLXNwYWNlLlxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnIHx8IGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0RlcHRoVG9TcGFjZSBpbnB1dCBzaG91bGQgYmUgYSA0LUQgbnVtZXJpYyB0ZW5zb3InKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuZXhwb3J0IGNvbnN0IGZsYXR0ZW46IE9wZXJhdG9ySW1wbGVtZW50YXRpb248bnVtYmVyPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBheGlzOiBudW1iZXIsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXhpcyk7XG5cbiAgY29uc3Qgb3V0cHV0RGltcyA9IFNoYXBlVXRpbC5mbGF0dGVuU2hhcGUoaW5wdXRzWzBdLmRpbXMsIGF4aXMpO1xuICByZXR1cm4gW2luZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1swXSwgb3V0cHV0RGltcyldO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlRmxhdHRlbkF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248bnVtYmVyPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogbnVtYmVyID0+XG4gIG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnLCAxKTsgLy8gZGVmYXVsdCBheGlzIGlzIDFcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhpczogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXR0ZW4gcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGNvbnN0IHIgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGlmIChyID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzY2FsYXIgdGVuc29yIGlzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gIH1cblxuICBpZiAoYXhpcyA8IC1yIHx8IGF4aXMgPiByKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGF4aXMnKTtcbiAgfVxuXG4gIC8vIFRPRE86IFN1cHBvcnQgc3RyaW5nIHR5cGVcbiAgaWYgKGlucHV0c1swXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignc3RyaW5nIHRlbnNvciBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi9iYWNrZW5kJztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi9ncmFwaCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvcic7XG5cbmV4cG9ydCB0eXBlIE9wZXJhdG9ySW1wbGVtZW50YXRpb248VD4gPSAoaW5mZXJlbmNlSGFuZGxlcjogSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgY29udGV4dDogVCkgPT4gVGVuc29yW107XG5leHBvcnQgdHlwZSBPcGVyYXRvckluaXRpYWxpemF0aW9uPFQ+ID0gKG5vZGU6IEdyYXBoLk5vZGUsIGdyYXBoOiBHcmFwaCkgPT4gVDtcblxuZXhwb3J0IGludGVyZmFjZSBPcGVyYXRvciB7XG4gIHJlYWRvbmx5IGltcGw6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248dW5rbm93bj47XG4gIHJlYWRvbmx5IGNvbnRleHQ6IEdyYXBoLk5vZGUgfCB1bmtub3duO1xufVxuXG5leHBvcnQgY29uc3QgTlVNQkVSX1RZUEVTOiByZWFkb25seSBUZW5zb3IuRGF0YVR5cGVbXSA9IFtcbiAgJ2Zsb2F0MzInLFxuICAnZmxvYXQ2NCcsXG4gICdpbnQzMicsXG4gICdpbnQxNicsXG4gICdpbnQ4JyxcbiAgJ3VpbnQxNicsXG4gICd1aW50MzInLFxuICAndWludDgnLFxuXTtcbmV4cG9ydCBjb25zdCBJTlRfVFlQRVM6IHJlYWRvbmx5IFRlbnNvci5EYXRhVHlwZVtdID0gWydpbnQzMicsICdpbnQxNicsICdpbnQ4JywgJ3VpbnQxNicsICd1aW50MzInLCAndWludDgnXTtcbmV4cG9ydCBjb25zdCBGTE9BVF9UWVBFUzogcmVhZG9ubHkgVGVuc29yLkRhdGFUeXBlW10gPSBbJ2Zsb2F0MzInLCAnZmxvYXQ2NCddO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE5VTUJFUl9UWVBFUywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmludGVyZmFjZSBHYXRoZXJBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhpczogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgZ2F0aGVyOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEdhdGhlckF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEdhdGhlckF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcy5heGlzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR2F0aGVyQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxHYXRoZXJBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogR2F0aGVyQXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGlzOiBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdheGlzJywgMCkgfSk7XG5cbmNvbnN0IGdhdGhlclByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0dhdGhlcicsXG4gIGlucHV0TmFtZXM6IFsnQScsICdCJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3QgY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm8gPSAoXG4gIF9oYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF4aXM6IG51bWJlcixcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IGluZGV4RGF0YVNoYXBlID0gaW5wdXRzWzFdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBuZXcgQXJyYXkoaW5wdXRTaGFwZS5sZW5ndGggKyBpbmRleERhdGFTaGFwZS5sZW5ndGggLSAxKTtcblxuICBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXhpcywgaW5wdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBpbmRleENvcHlPcHM6IHN0cmluZ1tdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0U2hhcGUubGVuZ3RoOyBpKyspIHtcbiAgICAvLyBvdXRwdXRTaGFwZSBpcyBkaXZpZGVkIGludG8gdGhyZWUgcGFydHM6IEEsIEIsIENcbiAgICAvLyB8MCAgICAgICAgYXhpc3wgIGF4aXMgKyBpbmRleERhdGFTaGFwZS5sZW5ndGggfCAgICAgICAgICBlbmR8XG4gICAgLy8gfCAgICAgQSAgICAgICB8ICAgICAgICAgICAgIEIgICAgICAgICAgICAgICAgIHwgICAgICBDICAgICAgfFxuICAgIC8vXG4gICAgLy8gaW5wdXRJZHg6IFtBLCBpbnB1dHNbMV1bQl0sIENdXG4gICAgaWYgKGkgPCBheGlzKSB7XG4gICAgICAvLyBBXG4gICAgICBvdXRwdXRTaGFwZVtpXSA9IGlucHV0U2hhcGVbaV07XG4gICAgICBpbmRleENvcHlPcHMucHVzaChgaW5wdXRJZHhbJHtpfV0gPSBvdXRwdXRJZHhbJHtpfV07YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpIDwgYXhpcyArIGluZGV4RGF0YVNoYXBlLmxlbmd0aCkge1xuICAgICAgICAvLyBCXG4gICAgICAgIG91dHB1dFNoYXBlW2ldID0gaW5kZXhEYXRhU2hhcGVbaSAtIGF4aXNdO1xuICAgICAgICBpbmRleENvcHlPcHMucHVzaChgaW5kZXhEYXRhSWR4WyR7aSAtIGF4aXN9XSA9IG91dHB1dElkeFske2l9XTtgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIENcbiAgICAgICAgb3V0cHV0U2hhcGVbaV0gPSBpbnB1dFNoYXBlW2kgLSBpbmRleERhdGFTaGFwZS5sZW5ndGggKyAxXTsgLy8gc2tpcCAxIGZvciBheGlzXG4gICAgICAgIGluZGV4Q29weU9wcy5wdXNoKGBpbnB1dElkeFske2kgLSBpbmRleERhdGFTaGFwZS5sZW5ndGggKyAxfV0gPSBvdXRwdXRJZHhbJHtpfV07YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgb3JhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGggfHwgMTtcbiAgY29uc3QgaXJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgaURyYW5rID0gaW5kZXhEYXRhU2hhcGUubGVuZ3RoIHx8IDE7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IG91dHB1dElkeFske29yYW5rfV0pIHtcbiAgICAgICAgaW50IGlucHV0SWR4WyR7aXJhbmt9XTtcbiAgICAgICAgaW50IGluZGV4RGF0YUlkeFske2lEcmFua31dO1xuICAgICAgICBpbmRleERhdGFJZHhbMF0gPSAwO1xuICAgICAgICAke2luZGV4Q29weU9wcy5qb2luKCdcXG4gICAgICAgICcpfVxuICAgICAgICBpbnQgaWR4ID0gaW50KF9CKGluZGV4RGF0YUlkeCkpO1xuICAgICAgICBpbnB1dElkeFske2F4aXN9XSA9IGlkeCA8IDAgPyBpZHggKyAke2lucHV0U2hhcGVbYXhpc119IDogaWR4O1xuICAgICAgICByZXR1cm4gX0EoaW5wdXRJZHgpO1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogR2F0aGVyQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSB7IC4uLmdhdGhlclByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5IH07XG4gIHJldHVybiB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUdhdGhlclByb2dyYW1JbmZvKGhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIGF0dHJpYnV0ZXMuYXhpcykgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF4aXM6IG51bWJlcik6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHYXRoZXIgcmVxdWlyZXMgMiBpbnB1dHMuJyk7XG4gIH1cbiAgY29uc3QgdGVuc29yUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcbiAgaWYgKHRlbnNvclJhbmsgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmIChheGlzIDwgLXRlbnNvclJhbmsgfHwgYXhpcyA+IHRlbnNvclJhbmsgLSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGF4aXMuJyk7XG4gIH1cbiAgaWYgKE5VTUJFUl9UWVBFUy5pbmRleE9mKGlucHV0c1swXS50eXBlKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJyAmJiBpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDE2Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgR2VtbVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBHZW1tQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHRyYW5zQTogYm9vbGVhbjtcbiAgdHJhbnNCOiBib29sZWFuO1xuICBhbHBoYTogbnVtYmVyO1xuICBiZXRhOiBudW1iZXI7XG4gIGlzT3B0aW9uYWxDOiBib29sZWFuOyAvLyBpbiBvcHNldCAxMSwgQyBiZWNvbWVzIG9wdGlvbmFsXG59XG5cbmV4cG9ydCBjb25zdCBnZW1tOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEdlbW1BdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBHZW1tQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlR2VtbVByb2dyYW1JbmZvTG9hZGVyKGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmNvbnN0IHBhcnNlR2VtbUF0dHJpYnV0ZXMgPSAobm9kZTogR3JhcGguTm9kZSwgaXNPcHRpb25hbEM6IGJvb2xlYW4pOiBHZW1tQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IHRyYW5zQSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3RyYW5zQScsIDApICE9PSAwO1xuICBjb25zdCB0cmFuc0IgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCd0cmFuc0InLCAwKSAhPT0gMDtcbiAgY29uc3QgYWxwaGEgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2FscGhhJywgMS4wKTtcbiAgY29uc3QgYmV0YSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYmV0YScsIDEuMCk7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyB0cmFuc0EsIHRyYW5zQiwgYWxwaGEsIGJldGEsIGlzT3B0aW9uYWxDIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR2VtbUF0dHJpYnV0ZXNWNzogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxHZW1tQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IEdlbW1BdHRyaWJ1dGVzID0+XG4gIHBhcnNlR2VtbUF0dHJpYnV0ZXMobm9kZSwgZmFsc2UpO1xuXG5leHBvcnQgY29uc3QgcGFyc2VHZW1tQXR0cmlidXRlc1YxMTogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxHZW1tQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IEdlbW1BdHRyaWJ1dGVzID0+XG4gIHBhcnNlR2VtbUF0dHJpYnV0ZXMobm9kZSwgdHJ1ZSk7XG5cbmNvbnN0IGNyZWF0ZUdlbW1Qcm9ncmFtSW5mb0xvYWRlciA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBHZW1tQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSB7XG4gICAgbmFtZTogJ0dlbW0nLFxuICAgIGlucHV0TmFtZXM6IGlucHV0cy5sZW5ndGggPT09IDMgPyBbJ0EnLCAnQicsICdDJ10gOiBbJ0EnLCAnQiddLFxuICAgIGlucHV0VHlwZXM6XG4gICAgICBpbnB1dHMubGVuZ3RoID09PSAzXG4gICAgICAgID8gW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdXG4gICAgICAgIDogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAga2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICB9O1xuXG4gIHJldHVybiB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUdlbW1Qcm9ncmFtSW5mbyhtZXRhZGF0YSwgaW5wdXRzLCBhdHRyaWJ1dGVzKSB9O1xufTtcblxuY29uc3QgY3JlYXRlR2VtbVByb2dyYW1JbmZvID0gKFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBHZW1tQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgYVNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgYlNoYXBlID0gaW5wdXRzWzFdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgW00sIE5dID0gR2VtbVV0aWwuZ2V0U2hhcGVPZkdlbW1SZXN1bHQoXG4gICAgYVNoYXBlLFxuICAgIGF0dHJpYnV0ZXMudHJhbnNBLFxuICAgIGJTaGFwZSxcbiAgICBhdHRyaWJ1dGVzLnRyYW5zQixcbiAgICBpbnB1dHMubGVuZ3RoID09PSAzID8gaW5wdXRzWzJdLmRpbXMgOiB1bmRlZmluZWQsXG4gICk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW00sIE5dO1xuICBpZiAoIW91dHB1dFNoYXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgdXNlIGdlbW0gb24gdGhlIGdpdmVuIHRlbnNvcnNcIik7XG4gIH1cbiAgbGV0IHNoYXJlZERpbSA9IGFTaGFwZVthU2hhcGUubGVuZ3RoIC0gMV07XG4gIGxldCBsaW5lID0gJyc7XG4gIGlmIChhdHRyaWJ1dGVzLnRyYW5zQSkge1xuICAgIHNoYXJlZERpbSA9IGFTaGFwZVswXTtcbiAgfVxuICBpZiAoYXR0cmlidXRlcy50cmFuc0EgJiYgYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICBsaW5lID0gJ3ZhbHVlICs9IF9BX1QoYSkgKiBfQl9UKGIpOyc7XG4gIH0gZWxzZSBpZiAoYXR0cmlidXRlcy50cmFuc0EgJiYgIWF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgbGluZSA9ICd2YWx1ZSArPSBfQV9UKGEpICogX0IoYik7JztcbiAgfSBlbHNlIGlmICghYXR0cmlidXRlcy50cmFuc0EgJiYgYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICBsaW5lID0gJ3ZhbHVlICs9IF9BKGEpICogX0JfVChiKTsnO1xuICB9IGVsc2UgaWYgKCFhdHRyaWJ1dGVzLnRyYW5zQSAmJiAhYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICBsaW5lID0gJ3ZhbHVlICs9IF9BKGEpICogX0IoYik7JztcbiAgfVxuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBkZWNsYXJlQyA9IGlucHV0cy5sZW5ndGggPT09IDMgPyBgaW50IGNbJHtpbnB1dHNbMl0uZGltcy5sZW5ndGh9XTtgIDogJyc7XG4gIGNvbnN0IGJyb2FkY2FzdEMgPSBpbnB1dHMubGVuZ3RoID09PSAzID8gJ2JjYXN0SW5kaWNlc19DKGluZGljZXMsIGMpOycgOiAnJztcbiAgY29uc3QgY2FsY3VsYXRlQyA9IGlucHV0cy5sZW5ndGggPT09IDMgPyAndmFsdWUgKz0gYmV0YSAqIF9DKGMpOycgOiAnJztcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBhWyR7cmFua31dO1xuICAgICAgICAgIGludCBiWyR7cmFua31dO1xuICAgICAgICAgICR7ZGVjbGFyZUN9XG5cbiAgICAgICAgICBjb3B5VmVjKGluZGljZXMsIGEpO1xuICAgICAgICAgIGNvcHlWZWMoaW5kaWNlcywgYik7XG4gICAgICAgICAgJHticm9hZGNhc3RDfVxuXG4gICAgICAgICAgZmxvYXQgdmFsdWUgPSAwLjA7XG4gICAgICAgICAgZm9yIChpbnQgaz0wOyBrPCR7c2hhcmVkRGltfTsgKytrKSB7XG4gICAgICAgICAgICAgIGFbJHtyYW5rIC0gMX1dID0gaztcbiAgICAgICAgICAgICAgYlske3JhbmsgLSAyfV0gPSBrO1xuICAgICAgICAgICAgICAke2xpbmV9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZSAqIGFscGhhO1xuICAgICAgICAgICR7Y2FsY3VsYXRlQ31cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICB2YXJpYWJsZXM6IFtcbiAgICAgIHsgbmFtZTogJ2FscGhhJywgdHlwZTogJ2Zsb2F0JywgZGF0YTogYXR0cmlidXRlcy5hbHBoYSB9LFxuICAgICAgeyBuYW1lOiAnYmV0YScsIHR5cGU6ICdmbG9hdCcsIGRhdGE6IGF0dHJpYnV0ZXMuYmV0YSB9LFxuICAgIF0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogR2VtbUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGlzIG1pc3NpbmcnKTtcbiAgfVxuICBpZiAoYXR0cmlidXRlcy5pc09wdGlvbmFsQyAmJiAoaW5wdXRzLmxlbmd0aCA8IDIgfHwgaW5wdXRzLmxlbmd0aCA+IDMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKCFhdHRyaWJ1dGVzLmlzT3B0aW9uYWxDICYmIGlucHV0cy5sZW5ndGggIT09IDMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dlbW0gcmVxdWlyZXMgMyBpbnB1dHMnKTtcbiAgfVxuXG4gIC8vICdDJyBjYW4gYmUgb2YgZGltZW5zaW9uYWxpdHkgMSBvciAyIG9ubHlcbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAxICYmIGlucHV0c1syXS5kaW1zLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZSBvZiBDJyk7XG4gIH1cblxuICBpZiAoXG4gICAgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAoaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMV0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgIChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1syXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzJdLnR5cGUgIT09ICdmbG9hdDY0JylcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09IGlucHV0c1sxXS50eXBlIHx8IChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1swXS50eXBlICE9PSBpbnB1dHNbMl0udHlwZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHR5cGVzIGFyZSBtaXNtYXRjaGVkJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEltYWdlU2NhbGVyQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHNjYWxlOiBudW1iZXI7XG4gIGJpYXM6IG51bWJlcltdO1xufVxuXG5leHBvcnQgY29uc3QgaW1hZ2VTY2FsZXI6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248SW1hZ2VTY2FsZXJBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBJbWFnZVNjYWxlckF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZUltYWdlU2NhbGVyUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEltYWdlU2NhbGVyQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBJbWFnZVNjYWxlckF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBzY2FsZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnc2NhbGUnKTtcbiAgY29uc3QgYmlhcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdHMoJ2JpYXMnKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IHNjYWxlLCBiaWFzIH0pO1xufTtcblxuY29uc3QgaW1hZ2VTY2FsZXJQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdJbWFnZVNjYWxlcicsXG4gIGlucHV0TmFtZXM6IFsnWCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3QgY3JlYXRlSW1hZ2VTY2FsZXJQcm9ncmFtSW5mbyA9IChcbiAgX2hhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGdldEJpYXNNZXRob2QgPSBjcmVhdGVHZXRCaWFzTWV0aG9kKGF0dHJpYnV0ZXMuYmlhcy5sZW5ndGgpO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke2dldEJpYXNNZXRob2R9XG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgIHJldHVybiBfWChpbmRpY2VzKSAqIHNjYWxlICsgZ2V0QmlhcyhiaWFzLCBpbmRpY2VzWzFdKTtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHZhcmlhYmxlczogW1xuICAgICAgeyBuYW1lOiAnYmlhcycsIHR5cGU6ICdmbG9hdCcsIGFycmF5TGVuZ3RoOiBhdHRyaWJ1dGVzLmJpYXMubGVuZ3RoLCBkYXRhOiBhdHRyaWJ1dGVzLmJpYXMgfSxcbiAgICAgIHsgbmFtZTogJ3NjYWxlJywgdHlwZTogJ2Zsb2F0JywgZGF0YTogYXR0cmlidXRlcy5zY2FsZSB9LFxuICAgIF0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlSW1hZ2VTY2FsZXJQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBJbWFnZVNjYWxlckF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0geyAuLi5pbWFnZVNjYWxlclByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5IH07XG4gIHJldHVybiB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUltYWdlU2NhbGVyUHJvZ3JhbUluZm8oaGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgYXR0cmlidXRlcykgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZUdldEJpYXNNZXRob2QgPSAobnVtQ2hhbm5lbHM6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGNvZGVMaW5lczogc3RyaW5nW10gPSBbYGZsb2F0IGdldEJpYXMoZmxvYXQgYmlhc1ske251bUNoYW5uZWxzfV0sIGludCBjaGFubmVsKSB7YF07XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtQ2hhbm5lbHM7ICsraSkge1xuICAgIGlmIChpID09PSAwKSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBpZiAoY2hhbm5lbCA9PSAke2l9KSB7IHJldHVybiBiaWFzWyR7aX1dOyB9YCk7XG4gICAgfSBlbHNlIGlmIChpID09PSBudW1DaGFubmVscyAtIDEpIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGVsc2UgeyByZXR1cm4gYmlhc1ske2l9XTsgfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBlbHNlIGlmIChjaGFubmVsID09ICR7aX0pIHsgcmV0dXJuIGJpYXNbJHtpfV07IH1gKTtcbiAgICB9XG4gIH1cbiAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyAnfScpO1xuICByZXR1cm4gY29kZUxpbmVzLmpvaW4oJ1xcbicpO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbWFnZVNjYWxlciByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCBpbnN0YW5jZU5vcm1hbGl6YXRpb246IE9wZXJhdG9ySW1wbGVtZW50YXRpb248bnVtYmVyPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBlcHNpbG9uOiBudW1iZXIsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3QgbWVhbkFuZFZhcmlhbmNlID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlTWVhbkFuZFZhcmlhbmNlUHJvZ3JhbUluZm9Mb2FkZXIoaW5wdXRzWzBdKSwgaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgY3JlYXRlQ29tcHV0ZU91dHB1dFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgZXBzaWxvbiwgbWVhbkFuZFZhcmlhbmNlLmRpbXMpLFxuICAgIFtpbnB1dHNbMF0sIG1lYW5BbmRWYXJpYW5jZSwgaW5wdXRzWzFdLCBpbnB1dHNbMl1dLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VJbnN0YW5jZU5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPG51bWJlcj4gPSAobm9kZTogR3JhcGguTm9kZSk6IG51bWJlciA9PlxuICBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2Vwc2lsb24nLCAxZS01KTtcblxuY29uc3QgbWVhbkFuZFZhcmlhbmNlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnSW5zdGFuY2VOb3JtYWxpemF0aW9uX01lYW5BbmRWYXJpYW5jZScsXG4gIGlucHV0TmFtZXM6IFsnWCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3QgY3JlYXRlTWVhbkFuZFZhcmlhbmNlUHJvZ3JhbUluZm8gPSAobWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgeERpbXMgPSBpbnB1dC5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IGNoYW5uZWwgPSB4RGltc1sxXTtcbiAgY29uc3QgY2hhbm5lbFNpemUgPSB4RGltc1syXSAqIHhEaW1zWzNdO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFt4RGltc1swXSwgY2hhbm5lbF07XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgdmVjNCBwcm9jZXNzKGludFsyXSBpbmRpY2VzKSB7XG4gICAgICAgIHZlYzQgdiA9IHZlYzQoMC4wKTtcbiAgICAgICAgaW50IGFbNF07XG4gICAgICAgIGFbMF0gPSBpbmRpY2VzWzBdO1xuICAgICAgICBhWzFdID0gaW5kaWNlc1sxXTtcbiAgICAgICAgZmxvYXQgdGVtcCA9IDAuMDtcbiAgICAgICAgZm9yKGludCBhMj0wOyBhMjwke3hEaW1zWzJdfTsgYTIrKykge1xuICAgICAgICAgIGFbMl0gPSBhMjtcbiAgICAgICAgICBmb3IoaW50IGEzPTA7IGEzPCR7eERpbXNbM119OyBhMysrKSB7XG4gICAgICAgICAgICBhWzNdID0gYTM7XG4gICAgICAgICAgICBmbG9hdCB4ID0gX1goYSk7XG4gICAgICAgICAgICB0ZW1wICs9IHg7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZsb2F0IG1lYW4gPSB0ZW1wIC8gZmxvYXQoJHtjaGFubmVsU2l6ZX0pO1xuICAgICAgICB0ZW1wID0gMC4wO1xuICAgICAgICBmb3IoaW50IGEyPTA7IGEyPCR7eERpbXNbMl19OyBhMisrKSB7XG4gICAgICAgICAgYVsyXSA9IGEyO1xuICAgICAgICAgIGZvcihpbnQgYTM9MDsgYTM8JHt4RGltc1szXX07IGEzKyspIHtcbiAgICAgICAgICAgIGFbM10gPSBhMztcbiAgICAgICAgICAgIGZsb2F0IHggPSBfWChhKTtcbiAgICAgICAgICAgIHRlbXAgKz0gKHggLSBtZWFuKSAqICh4IC0gbWVhbik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHYuciA9IG1lYW47XG4gICAgICAgIHYuZyA9IHRlbXAgLyBmbG9hdCgke2NoYW5uZWxTaXplfSk7XG5cbiAgICAgICAgcmV0dXJuIHY7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlTWVhbkFuZFZhcmlhbmNlUHJvZ3JhbUluZm9Mb2FkZXIgPSAoaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvTG9hZGVyID0+ICh7XG4gIC4uLm1lYW5BbmRWYXJpYW5jZVByb2dyYW1NZXRhZGF0YSxcbiAgZ2V0OiAoKSA9PiBjcmVhdGVNZWFuQW5kVmFyaWFuY2VQcm9ncmFtSW5mbyhtZWFuQW5kVmFyaWFuY2VQcm9ncmFtTWV0YWRhdGEsIGlucHV0KSxcbn0pO1xuXG5jb25zdCBjb21wdXRlT3V0cHV0UHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnSW5zdGFuY2VOb3JtYWxpemF0aW9uX0NvbXB1dGVPdXRwdXQnLFxuICBpbnB1dE5hbWVzOiBbJ1gnLCAnTWVhbkFuZFZhcmlhbmNlJywgJ1NjYWxlJywgJ0InXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3QgY3JlYXRlQ29tcHV0ZU91dHB1dFByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGVwc2lsb246IG51bWJlcixcbiAgbWVhbkFuZFZhcmlhbmNlU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IFt0ZXh0dXJlV2lkdGgsIHRleHR1cmVIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgbWVhbkFuZFZhcmlhbmNlU2hhcGUsXG4gICAgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbixcbiAgKTtcbiAgY29uc3QgW21lYW5BbmRWYXJpYW5jZVdpZHRoLCBtZWFuQW5kVmFyaWFuY2VIZWlnaHRdID0gW3RleHR1cmVXaWR0aCAvIDQsIHRleHR1cmVIZWlnaHRdO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICB2ZWM0IGdldF9NZWFuQW5kVmFyaWFuY2UoaW50WzJdIG12KSB7XG4gICAgICAgIGludCBvZmZzZXQgPSBpbmRpY2VzVG9PZmZzZXRfTWVhbkFuZFZhcmlhbmNlKG12KTtcbiAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhvZmZzZXQsICR7bWVhbkFuZFZhcmlhbmNlV2lkdGh9LCAke21lYW5BbmRWYXJpYW5jZUhlaWdodH0pO1xuICAgICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oTWVhbkFuZFZhcmlhbmNlLCBjb29yZHMpO1xuICAgICAgfVxuXG4gICAgICBmbG9hdCBwcm9jZXNzKGludFs0XSBpbmRpY2VzKSB7XG4gICAgICAgIGludCBtdlsyXTtcbiAgICAgICAgbXZbMF0gPSBpbmRpY2VzWzBdO1xuICAgICAgICBtdlsxXSA9IGluZGljZXNbMV07XG4gICAgICAgIHZlYzQgbWVhbl9hbmRfdmFyaWFuY2UgPSBnZXRfTWVhbkFuZFZhcmlhbmNlKG12KTtcbiAgICAgICAgZmxvYXQgbWVhbiA9IG1lYW5fYW5kX3ZhcmlhbmNlLnI7XG4gICAgICAgIGZsb2F0IHZhcmlhbmNlID0gbWVhbl9hbmRfdmFyaWFuY2UuZztcblxuICAgICAgICBpbnQgc2JbMV07XG4gICAgICAgIHNiWzBdID0gaW5kaWNlc1sxXTtcbiAgICAgICAgZmxvYXQgc2NhbGUgPSBfU2NhbGUoc2IpO1xuICAgICAgICBmbG9hdCBiID0gX0Ioc2IpO1xuXG4gICAgICAgIHJldHVybiBzY2FsZSAqIChfWChpbmRpY2VzKSAtIG1lYW4pIC8gc3FydCh2YXJpYW5jZSArIGVwc2lsb24pICsgYjtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dC5kaW1zLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICB2YXJpYWJsZXM6IFt7IG5hbWU6ICdlcHNpbG9uJywgdHlwZTogJ2Zsb2F0JywgZGF0YTogZXBzaWxvbiB9XSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVDb21wdXRlT3V0cHV0UHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgZXBzaWxvbjogbnVtYmVyLFxuICBtZWFuQW5kVmFyaWFuY2VTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0geyAuLi5jb21wdXRlT3V0cHV0UHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGAke2Vwc2lsb259YCB9O1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIGdldDogKCkgPT4gY3JlYXRlQ29tcHV0ZU91dHB1dFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dCwgZXBzaWxvbiwgbWVhbkFuZFZhcmlhbmNlU2hhcGUpLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnN0YW5jZU5vcm1hbGl6YXRpb24gcmVxdWlyZXMgMyBpbnB1dHMuJyk7XG4gIH1cblxuICBjb25zdCBYID0gaW5wdXRzWzBdO1xuICBjb25zdCBzY2FsZSA9IGlucHV0c1sxXTtcbiAgY29uc3QgQiA9IGlucHV0c1syXTtcblxuICAvLyBpbnB1dCBzaG91bGQgYXQgbGVhc3QgaGF2ZSB0aHJlZSBkaW1lbnNpb25zIC0gTixDLGRpbTEsLi4uLGRpbW5cbiAgLy8gb3RoZXIgaW5wdXRzIGNhbiBoYXZlIG9ubHkgb25lIGRpbWVuc2lvbnNcbiAgaWYgKFguZGltcy5sZW5ndGggPCAzIHx8IHNjYWxlLmRpbXMubGVuZ3RoICE9PSAxIHx8IEIuZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKHNjYWxlLmRpbXNbMF0gIT09IFguZGltc1sxXSB8fCBCLmRpbXNbMF0gIT09IFguZGltc1sxXSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgc2hhcGVzIGFyZSBtaXNtYXRjaGVkLicpO1xuICB9XG4gIGlmIChcbiAgICAoWC50eXBlICE9PSAnZmxvYXQzMicgJiYgWC50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKHNjYWxlLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBzY2FsZS50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKEIudHlwZSAhPT0gJ2Zsb2F0MzInICYmIEIudHlwZSAhPT0gJ2Zsb2F0NjQnKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdPbmx5IHN1cHBvcnQgNC1EIGlucHV0IHNoYXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTHJuQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIGFscGhhOiBudW1iZXI7XG4gIGJldGE6IG51bWJlcjtcbiAgYmlhczogbnVtYmVyO1xuICBzaXplOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBscm46IE9wZXJhdG9ySW1wbGVtZW50YXRpb248THJuQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogTHJuQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICAvLyBpZiAoaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLnBhY2spIHtcbiAgLy8gICByZXR1cm4gW2luZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZVBhY2tlZExyblByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksXG4gIC8vICAgaW5wdXRzKV07XG4gIC8vIH0gZWxzZSB7XG4gIHJldHVybiBbaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlTHJuUHJvZ3JhbUluZm9Mb2FkZXIoaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKV07XG4gIC8vfVxufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTHJuQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxMcm5BdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogTHJuQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGFscGhhID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdhbHBoYScsIDAuMDAwMSk7XG4gIGNvbnN0IGJldGEgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2JldGEnLCAwLjc1KTtcbiAgY29uc3QgYmlhcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYmlhcycsIDEuMCk7XG4gIGNvbnN0IHNpemUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdzaXplJyk7XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGFscGhhLCBiZXRhLCBiaWFzLCBzaXplIH0pO1xufTtcblxuY29uc3QgbHJuUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnTFJOJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5mdW5jdGlvbiBjcmVhdGVMcm5Qcm9ncmFtSW5mbyhpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBMcm5BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8ge1xuICBjb25zdCBDID0gaW5wdXRzWzBdLmRpbXNbMV07XG4gIGNvbnN0IHJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGNvbnN0IGZyb20gPSAtTWF0aC5mbG9vcigoYXR0cmlidXRlcy5zaXplIC0gMSkgLyAyKTtcbiAgY29uc3QgdG8gPSBNYXRoLmNlaWwoKGF0dHJpYnV0ZXMuc2l6ZSAtIDEpIC8gMik7XG4gIGNvbnN0IGFscGhhID0gYGZsb2F0KCR7YXR0cmlidXRlcy5hbHBoYX0pIC8gZmxvYXQoJHthdHRyaWJ1dGVzLnNpemV9KWA7XG4gIGNvbnN0IGJpYXMgPSBgZmxvYXQoJHthdHRyaWJ1dGVzLmJpYXN9KWA7XG4gIGNvbnN0IGJldGEgPSBgZmxvYXQoJHthdHRyaWJ1dGVzLmJldGF9KWA7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IGMgPSBpbmRpY2VzWzFdO1xuICAgICAgICBmbG9hdCB4ID0gX1goaW5kaWNlcyk7XG4gICAgICAgIGZsb2F0IHNxdWFyZV9zdW0gPSAwLjA7XG5cbiAgICAgICAgZm9yIChpbnQgaSA9ICR7ZnJvbX07IGkgPD0gJHt0b307IGkrKykge1xuICAgICAgICAgIGludCBpZHggPSBjICsgaTtcbiAgICAgICAgICBpZiAoYyA+PSAwICYmIGMgPCAke0N9KSB7XG4gICAgICAgICAgICBpbmRpY2VzWzFdID0gaWR4O1xuICAgICAgICAgICAgZmxvYXQgaiA9IF9YKGluZGljZXMpO1xuICAgICAgICAgICAgc3F1YXJlX3N1bSArPSBqICogajtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggLyBwb3coJHtiaWFzfSArICR7YWxwaGF9ICogc3F1YXJlX3N1bSwgJHtiZXRhfSk7XG4gICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubHJuUHJvZ3JhbU1ldGFkYXRhLFxuICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW5wdXRzWzBdLmRpbXMsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVMcm5Qcm9ncmFtSW5mb0xvYWRlcihpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBMcm5BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm9Mb2FkZXIge1xuICByZXR1cm4geyAuLi5scm5Qcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgZ2V0OiAoKSA9PiBjcmVhdGVMcm5Qcm9ncmFtSW5mbyhpbnB1dHMsIGF0dHJpYnV0ZXMpIH07XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTFJOIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY3VycmVudGx5IG9ubHkgc3VwcG9ydCBMUk4gZm9yIGlucHV0IHdpdGggXCJOQ0hXXCIgZm9ybWF0Jyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHNob3VsZCBiZSBmbG9hdCB0eXBlJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBnZXRHbHNsLCBHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBhZEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBtb2RlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHBhZHM6IG51bWJlcltdO1xuICByZWFkb25seSB2YWx1ZTogbnVtYmVyO1xufVxuXG5jb25zdCBwYWRQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdQYWQnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCBwYWRWMjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxQYWRBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBQYWRBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0c1YyKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLnBhZFByb2dyYW1NZXRhZGF0YSxcbiAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlUGFkUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBhdHRyaWJ1dGVzKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlUGFkQXR0cmlidXRlc1YyOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFBhZEF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBQYWRBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgbW9kZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ21vZGUnLCAnY29uc3RhbnQnKTtcbiAgY29uc3QgdmFsdWUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ3ZhbHVlJywgMC4wKTtcbiAgY29uc3QgcGFkcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdwYWRzJyk7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBtb2RlLCB2YWx1ZSwgcGFkcyB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYWRWMTE6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248c3RyaW5nPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBtb2RlOiBzdHJpbmcsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzVjExKGlucHV0cyk7XG4gIGNvbnN0IGF0dHJ1YnV0ZXMgPSBnZW5lcmF0ZVBhZEF0dHJpYnV0ZXNGcm9tSW5wdXRzKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgbW9kZSk7XG4gIHJldHVybiBwYWRWMihpbmZlcmVuY2VIYW5kbGVyLCBbaW5wdXRzWzBdXSwgYXR0cnVidXRlcyk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VQYWRBdHRyaWJ1dGVzVjExOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPHN0cmluZz4gPSAobm9kZTogR3JhcGguTm9kZSk6IHN0cmluZyA9PlxuICBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdtb2RlJywgJ2NvbnN0YW50Jyk7XG5cbmNvbnN0IGdlbmVyYXRlUGFkQXR0cmlidXRlc0Zyb21JbnB1dHMgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgbW9kZTogc3RyaW5nLFxuKTogUGFkQXR0cmlidXRlcyA9PiB7XG4gIGlmIChcbiAgICAhaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzFdLmRhdGFJZCkgfHxcbiAgICAoaW5wdXRzLmxlbmd0aCA+PSAzICYmICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMl0uZGF0YUlkKSlcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkeW5hbWljIHBhZCBhdHRyaWJ1dGVzIGFyZSBub3QgYWxsb3dlZCcpO1xuICB9XG5cbiAgY29uc3QgcGFkcyA9IEFycmF5LmZyb20oaW5wdXRzWzFdLmludGVnZXJEYXRhKTtcbiAgY29uc3QgdmFsdWUgPSBpbnB1dHMubGVuZ3RoID49IDMgPyBpbnB1dHNbMl0uZmxvYXREYXRhWzBdIDogMC4wO1xuXG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBtb2RlLCBwYWRzLCB2YWx1ZSB9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZVBhZFByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGF0dHJpYnV0ZXM6IFBhZEF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gU2hhcGVVdGlsLnBhZFNoYXBlKGlucHV0LmRpbXMuc2xpY2UoKSwgYXR0cmlidXRlcy5wYWRzKTtcbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgcGFkRnVuY3Rpb24gPSBnZXRQYWRGdW5jdGlvbihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dCwgYXR0cmlidXRlcyk7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICR7cGFkRnVuY3Rpb259XG4gICAgICBmbG9hdCBwcm9jZXNzKGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG4gICAgICAgICAgcmV0dXJuIHBhZEEoaW5kaWNlcyk7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnUGFkJyxcbiAgICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHNWMiA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhZCByZXF1aXJlcyAxIGlucHV0Jyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0c1YxMSA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IChpbnB1dHMubGVuZ3RoICE9PSAyICYmIGlucHV0cy5sZW5ndGggIT09IDMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQYWQgcmVxdWlyZXMgMiBvciAzIGlucHV0cycpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHMubGVuZ3RoID49IDMgJiYgaW5wdXRzWzJdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmNvbnN0IGdldFBhZEZ1bmN0aW9uID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvciwgYXR0cmlidXRlczogUGFkQXR0cmlidXRlcyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgW3dpZHRoLCBoZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoaW5wdXQuZGltcywgVGV4dHVyZVR5cGUudW5wYWNrZWQpO1xuICBjb25zdCBzdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKGlucHV0LmRpbXMpO1xuXG4gIHN3aXRjaCAoYXR0cmlidXRlcy5tb2RlKSB7XG4gICAgY2FzZSAnY29uc3RhbnQnOlxuICAgICAgcmV0dXJuIGdldFBhZENvbnN0YW50KGdsc2wsIGlucHV0LmRpbXMsIHN0cmlkZXMsIHdpZHRoLCBoZWlnaHQsIGF0dHJpYnV0ZXMucGFkcywgYXR0cmlidXRlcy52YWx1ZSk7XG4gICAgY2FzZSAncmVmbGVjdCc6XG4gICAgICByZXR1cm4gZ2V0UGFkUmVmbGVjdChnbHNsLCBpbnB1dC5kaW1zLCBzdHJpZGVzLCB3aWR0aCwgaGVpZ2h0LCBhdHRyaWJ1dGVzLnBhZHMpO1xuICAgIGNhc2UgJ2VkZ2UnOlxuICAgICAgcmV0dXJuIGdldFBhZEVkZ2UoZ2xzbCwgaW5wdXQuZGltcywgc3RyaWRlcywgd2lkdGgsIGhlaWdodCwgYXR0cmlidXRlcy5wYWRzKTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG1vZGUnKTtcbiAgfVxufTtcblxuY29uc3QgZ2V0UGFkQ29uc3RhbnQgPSAoXG4gIGdsc2w6IEdsc2wsXG4gIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHdpZHRoOiBudW1iZXIsXG4gIGhlaWdodDogbnVtYmVyLFxuICBwYWRzOiBudW1iZXJbXSxcbiAgdmFsdWU6IG51bWJlcixcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gIGxldCBibG9jayA9ICcnO1xuICBmb3IgKGxldCBpID0gcmFuayAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgYmxvY2sgKz0gYFxuICAgICAgICBrID0gbVske2l9XSAtICR7cGFkc1tpXX07XG4gICAgICAgIGlmIChrIDwgMCkgIHJldHVybiBjb25zdGFudDtcbiAgICAgICAgaWYgKGsgPj0gJHtzaGFwZVtpXX0pIHJldHVybiBjb25zdGFudDtcbiAgICAgICAgb2Zmc2V0ICs9IGsgKiAke3N0cmlkZXNbaV19O1xuICAgICAgICBgO1xuICB9XG4gIHJldHVybiBgXG4gICAgICBmbG9hdCBwYWRBKGludCBtWyR7cmFua31dKSB7XG4gICAgICAgIGNvbnN0IGZsb2F0IGNvbnN0YW50ID0gZmxvYXQoJHt2YWx1ZX0pO1xuICAgICAgICBpbnQgb2Zmc2V0ID0gMDtcbiAgICAgICAgaW50IGsgPSAwO1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHt3aWR0aH0sICR7aGVpZ2h0fSk7XG4gICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIGNvb3JkcykpO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBgO1xufTtcblxuY29uc3QgZ2V0UGFkUmVmbGVjdCA9IChcbiAgZ2xzbDogR2xzbCxcbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgd2lkdGg6IG51bWJlcixcbiAgaGVpZ2h0OiBudW1iZXIsXG4gIHBhZHM6IG51bWJlcltdLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICBsZXQgYmxvY2sgPSAnJztcbiAgZm9yIChsZXQgaSA9IHJhbmsgLSAxOyBpID49IDA7IC0taSkge1xuICAgIGJsb2NrICs9IGBcbiAgICAgICAgayA9IG1bJHtpfV0gLSAke3BhZHNbaV19O1xuICAgICAgICBpZiAoayA8IDApIHsgayA9IC1rOyB9XG4gICAgICAgIHtcbiAgICAgICAgICBjb25zdCBpbnQgXzJuXzEgPSAkezIgKiAoc2hhcGVbaV0gLSAxKX07XG4gICAgICAgICAgayA9IGludCggbW9kKCBmbG9hdChrKSwgZmxvYXQoXzJuXzEpICkgKSA7XG4gICAgICAgICAgaWYoayA+PSAke3NoYXBlW2ldfSkgeyBrID0gXzJuXzEgLSBrOyB9XG4gICAgICAgIH1cbiAgICAgICAgb2Zmc2V0ICs9IGsgKiAke3N0cmlkZXNbaV19O1xuICAgICAgICBgO1xuICB9XG4gIHJldHVybiBgXG4gICAgICBmbG9hdCBwYWRBKGludCBtWyR7cmFua31dKSB7XG4gICAgICAgIGludCBvZmZzZXQgPSAwO1xuICAgICAgICBpbnQgayA9IDA7XG4gICAgICAgICR7YmxvY2t9XG4gICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgZmxvYXQgdmFsdWUgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgY29vcmRzKSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGA7XG59O1xuXG5jb25zdCBnZXRQYWRFZGdlID0gKFxuICBnbHNsOiBHbHNsLFxuICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICB3aWR0aDogbnVtYmVyLFxuICBoZWlnaHQ6IG51bWJlcixcbiAgcGFkczogbnVtYmVyW10sXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gIGxldCBibG9jayA9ICcnO1xuICBmb3IgKGxldCBpID0gcmFuayAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgYmxvY2sgKz0gYFxuICAgICAgICBrID0gbVske2l9XSAtICR7cGFkc1tpXX07XG4gICAgICAgIGlmIChrIDwgMCkgIGsgPSAwO1xuICAgICAgICBpZiAoayA+PSAke3NoYXBlW2ldfSkgayA9ICR7c2hhcGVbaV0gLSAxfTtcbiAgICAgICAgb2Zmc2V0ICs9IGsgKiAke3N0cmlkZXNbaV19O1xuICAgICAgYDtcbiAgfVxuICByZXR1cm4gYFxuICAgICAgZmxvYXQgcGFkQShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICBpbnQgb2Zmc2V0ID0gMDtcbiAgICAgICAgaW50IGsgPSAwO1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHt3aWR0aH0sICR7aGVpZ2h0fSk7XG4gICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIGNvb3JkcykpO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBgO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBQb29sQ29udlV0aWwsIFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXZlcmFnZVBvb2xBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXV0b1BhZDogc3RyaW5nO1xuICByZWFkb25seSBjZWlsTW9kZTogbnVtYmVyO1xuICByZWFkb25seSBjb3VudEluY2x1ZGVQYWQ6IGJvb2xlYW47XG4gIHJlYWRvbmx5IGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHBhZHM6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5leHBvcnQgY29uc3QgYXZlcmFnZVBvb2w6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248QXZlcmFnZVBvb2xBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdBdmVyYWdlUG9vbCcsXG4gICAgaW5wdXROYW1lczogWydYJ10sXG4gICAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gIH07XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlQXZlcmFnZVBvb2xQcm9ncmFtSW5mbyhpbnB1dHMsIG1ldGFkYXRhLCBmYWxzZSwgYXR0cmlidXRlcykgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUF2ZXJhZ2VQb29sQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxBdmVyYWdlUG9vbEF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXV0b1BhZCA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2F1dG9fcGFkJywgJ05PVFNFVCcpO1xuICBjb25zdCBjZWlsTW9kZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2NlaWxfbW9kZScsIDApO1xuICBjb25zdCBjb3VudEluY2x1ZGVQYWQgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdjb3VudF9pbmNsdWRlX3BhZCcsIDApID09PSAwID8gZmFsc2UgOiB0cnVlO1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdrZXJuZWxfc2hhcGUnKTtcbiAgY29uc3Qgc3RyaWRlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdzdHJpZGVzJywgW10pO1xuICBjb25zdCBwYWRzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnLCBbXSk7XG5cbiAgLy8gVE9ETzogc3VwcG9ydCBhdHRyaWJ1dGUgJ2NlaWxfbW9kZSdcbiAgaWYgKGNlaWxNb2RlICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1c2luZyBjZWlsKCkgaW4gc2hhcGUgY29tcHV0YXRpb24gaXMgbm90IHlldCBzdXBwb3J0ZWQgZm9yIEF2ZXJhZ2VQb29sJyk7XG4gIH1cblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXV0b1BhZCwgY2VpbE1vZGUsIGNvdW50SW5jbHVkZVBhZCwga2VybmVsU2hhcGUsIHN0cmlkZXMsIHBhZHMgfSk7XG59O1xuXG5jb25zdCBjcmVhdGVBdmVyYWdlUG9vbFByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuICBhdHRyaWJ1dGVzOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IFthZGp1c3RlZEF0dHJpYnV0ZXMsIG91dHB1dFNoYXBlXSA9IGdldEFkanVzdGVkUG9vbEF0dHJpYnV0ZXNBbmRPdXRwdXRTaGFwZShcbiAgICBpbnB1dHMsXG4gICAgYXR0cmlidXRlcyxcbiAgICBpc0dsb2JhbE9wZXJhdG9yLFxuICApO1xuICBjb25zdCBrZXJuZWxTaXplID0gU2hhcGVVdGlsLnNpemUoYWRqdXN0ZWRBdHRyaWJ1dGVzLmtlcm5lbFNoYXBlKTtcbiAgY29uc3Qgb3AxID0gJ3ZhbHVlICs9IF9YKHgpOyc7XG4gIGxldCBvcDIgPSAnJztcbiAgaWYgKGFkanVzdGVkQXR0cmlidXRlcy5jb3VudEluY2x1ZGVQYWQpIHtcbiAgICBvcDIgKz0gYHZhbHVlIC89IGZsb2F0KCR7a2VybmVsU2l6ZX0pO2A7XG4gIH0gZWxzZSB7XG4gICAgb3AyICs9IGB2YWx1ZSAvPSBmbG9hdCgke2tlcm5lbFNpemV9IC0gcGFkKTtgO1xuICB9XG4gIGNvbnN0IHBvb2xpbmdDb2RlID0gZ2VuZXJhdGVQb29saW5nQ29kZShpbnB1dHNbMF0uZGltcywgYWRqdXN0ZWRBdHRyaWJ1dGVzLCBvcDEsIG9wMiwgJzAuMCcpO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICR7cG9vbGluZ0NvZGV9XG4gICAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnbG9iYWxBdmVyYWdlUG9vbDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxBdmVyYWdlUG9vbEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3QgbWV0YWRhdGEgPSB7XG4gICAgbmFtZTogJ0dsb2JhbEF2ZXJhZ2VQb29sJyxcbiAgICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICAgIGNhY2hlSGludDogYCR7YXR0cmlidXRlcy5jb3VudEluY2x1ZGVQYWR9YCxcbiAgfTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVBdmVyYWdlUG9vbFByb2dyYW1JbmZvKGlucHV0cywgbWV0YWRhdGEsIHRydWUsIGF0dHJpYnV0ZXMpIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VHbG9iYWxBdmVyYWdlUG9vbEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248QXZlcmFnZVBvb2xBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGNvdW50SW5jbHVkZVBhZCA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2NvdW50X2luY2x1ZGVfcGFkJywgMCkgPT09IDAgPyBmYWxzZSA6IHRydWU7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe1xuICAgIGF1dG9QYWQ6ICcnLFxuICAgIGNlaWxNb2RlOiAwLFxuICAgIGNvdW50SW5jbHVkZVBhZCxcbiAgICBrZXJuZWxTaGFwZTogW10sXG4gICAgc3RyaWRlczogW10sXG4gICAgcGFkczogW10sXG4gIH0pO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBNYXhQb29sQXR0cmlidXRlcyBleHRlbmRzIEF2ZXJhZ2VQb29sQXR0cmlidXRlcyB7XG4gIHJlYWRvbmx5IHN0b3JhZ2VPcmRlcjogbnVtYmVyO1xuICByZWFkb25seSBkaWxhdGlvbnM6IG51bWJlcltdO1xufVxuXG5leHBvcnQgY29uc3QgbWF4UG9vbDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxNYXhQb29sQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogTWF4UG9vbEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdNYXhQb29sJyxcbiAgICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgfTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVNYXhQb29sUHJvZ3JhbUluZm8oaW5wdXRzLCBtZXRhZGF0YSwgZmFsc2UsIGF0dHJpYnV0ZXMpIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VNYXhQb29sQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxNYXhQb29sQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBNYXhQb29sQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGF1dG9QYWQgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdhdXRvX3BhZCcsICdOT1RTRVQnKTtcbiAgY29uc3QgY2VpbE1vZGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdjZWlsX21vZGUnLCAwKTtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygna2VybmVsX3NoYXBlJyk7XG4gIGNvbnN0IHN0cmlkZXMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnc3RyaWRlcycsIFtdKTtcbiAgY29uc3QgcGFkcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdwYWRzJywgW10pO1xuICBjb25zdCBzdG9yYWdlT3JkZXIgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdzdG9yYWdlX29yZGVyJywgMCk7XG4gIGNvbnN0IGRpbGF0aW9ucyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdkaWxhdGlvbnMnLCBbXSk7XG5cbiAgLy8gVE9ETzogc3VwcG9ydCBhdHRyaWJ1dGUgJ2NlaWxfbW9kZScgYW5kICdzdG9yYWdlX29yZGVyJ1xuICBpZiAoc3RvcmFnZU9yZGVyICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjb2x1bW4gbWFqb3Igc3RvcmFnZSBvcmRlciBpcyBub3QgeWV0IHN1cHBvcnRlZCBmb3IgTWF4UG9vbCcpO1xuICB9XG4gIGlmIChjZWlsTW9kZSAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcigndXNpbmcgY2VpbCgpIGluIHNoYXBlIGNvbXB1dGF0aW9uIGlzIG5vdCB5ZXQgc3VwcG9ydGVkIGZvciBNYXhQb29sJyk7XG4gIH1cblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBhdXRvUGFkLFxuICAgIGNlaWxNb2RlLFxuICAgIGNvdW50SW5jbHVkZVBhZDogZmFsc2UsXG4gICAga2VybmVsU2hhcGUsXG4gICAgc3RyaWRlcyxcbiAgICBwYWRzLFxuICAgIHN0b3JhZ2VPcmRlcixcbiAgICBkaWxhdGlvbnMsXG4gIH0pO1xufTtcblxuY29uc3QgY3JlYXRlTWF4UG9vbFByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuICBhdHRyaWJ1dGVzOiBNYXhQb29sQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgW2FkanVzdGVkQXR0cmlidXRlcywgb3V0cHV0U2hhcGVdID0gZ2V0QWRqdXN0ZWRQb29sQXR0cmlidXRlc0FuZE91dHB1dFNoYXBlKFxuICAgIGlucHV0cyxcbiAgICBhdHRyaWJ1dGVzLFxuICAgIGlzR2xvYmFsT3BlcmF0b3IsXG4gICk7XG4gIGNvbnN0IG9wMSA9IGBcbiAgICAgIHZhbHVlID0gbWF4KF9YKHgpLCB2YWx1ZSk7XG4gICAgYDtcbiAgY29uc3Qgb3AyID0gJyc7XG4gIGNvbnN0IHBvb2xpbmdDb2RlID0gZ2VuZXJhdGVQb29saW5nQ29kZShpbnB1dHNbMF0uZGltcywgYWRqdXN0ZWRBdHRyaWJ1dGVzLCBvcDEsIG9wMiwgJy0xZTUnKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHtwb29saW5nQ29kZX1cbiAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGdldEFkanVzdGVkUG9vbEF0dHJpYnV0ZXNBbmRPdXRwdXRTaGFwZSA9IChcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzIHwgTWF4UG9vbEF0dHJpYnV0ZXMsXG4gIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4pOiBbQXZlcmFnZVBvb2xBdHRyaWJ1dGVzIHwgTWF4UG9vbEF0dHJpYnV0ZXMsIG51bWJlcltdXSA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBoYXNEaWxhdGlvbnMgPSBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChhdHRyaWJ1dGVzLCAnZGlsYXRpb25zJyk7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5zbGljZSgpO1xuICBjb25zdCBzdHJpZGVzID0gYXR0cmlidXRlcy5zdHJpZGVzLnNsaWNlKCk7XG4gIGNvbnN0IGRpbGF0aW9uczogbnVtYmVyW10gPSBoYXNEaWxhdGlvbnMgPyAoYXR0cmlidXRlcyBhcyBNYXhQb29sQXR0cmlidXRlcykuZGlsYXRpb25zLnNsaWNlKCkgOiBbXTtcbiAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMucGFkcy5zbGljZSgpO1xuICBQb29sQ29udlV0aWwuYWRqdXN0UG9vbEF0dHJpYnV0ZXMoaXNHbG9iYWxPcGVyYXRvciwgaW5wdXRTaGFwZSwga2VybmVsU2hhcGUsIHN0cmlkZXMsIGRpbGF0aW9ucywgcGFkcyk7XG5cbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBQb29sQ29udlV0aWwuY29tcHV0ZVBvb2xPdXRwdXRTaGFwZShcbiAgICBpc0dsb2JhbE9wZXJhdG9yLFxuICAgIGlucHV0U2hhcGUsXG4gICAgc3RyaWRlcyxcbiAgICBkaWxhdGlvbnMsXG4gICAga2VybmVsU2hhcGUsXG4gICAgcGFkcyxcbiAgICBhdHRyaWJ1dGVzLmF1dG9QYWQsXG4gICk7XG5cbiAgY29uc3QgbmV3QXR0cmlidXRlcyA9IE9iamVjdC5hc3NpZ24oe30sIGF0dHJpYnV0ZXMpO1xuICBpZiAoaGFzRGlsYXRpb25zKSB7XG4gICAgT2JqZWN0LmFzc2lnbihuZXdBdHRyaWJ1dGVzLCB7IGtlcm5lbFNoYXBlLCBzdHJpZGVzLCBwYWRzLCBkaWxhdGlvbnMsIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5IH0pO1xuICB9IGVsc2Uge1xuICAgIE9iamVjdC5hc3NpZ24obmV3QXR0cmlidXRlcywgeyBrZXJuZWxTaGFwZSwgc3RyaWRlcywgcGFkcywgY2FjaGVLZXk6IGF0dHJpYnV0ZXMuY2FjaGVLZXkgfSk7XG4gIH1cbiAgcmV0dXJuIFtuZXdBdHRyaWJ1dGVzLCBvdXRwdXRTaGFwZV07XG59O1xuXG5jb25zdCBnbG9iYWxNYXhQb29sQXR0cmlidXRlcyA9IHtcbiAgYXV0b1BhZDogJycsXG4gIGNlaWxNb2RlOiAwLFxuICBjb3VudEluY2x1ZGVQYWQ6IGZhbHNlLFxuICBrZXJuZWxTaGFwZTogW10sXG4gIHN0cmlkZXM6IFtdLFxuICBwYWRzOiBbXSxcbiAgc3RvcmFnZU9yZGVyOiAwLFxuICBkaWxhdGlvbnM6IFtdLFxuICBjYWNoZUtleTogJycsXG59O1xuXG5jb25zdCBnbG9iYWxNYXhQb29sTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdHbG9iYWxNYXhQb29sJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3QgZ2xvYmFsTWF4UG9vbCA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLmdsb2JhbE1heFBvb2xNZXRhZGF0YSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlTWF4UG9vbFByb2dyYW1JbmZvKGlucHV0cywgZ2xvYmFsTWF4UG9vbE1ldGFkYXRhLCB0cnVlLCBnbG9iYWxNYXhQb29sQXR0cmlidXRlcyksXG4gICAgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUG9vbCBvcHMgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmNvbnN0IGdlbmVyYXRlUG9vbGluZ0NvZGUgPSAoXG4gIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyxcbiAgb3AxOiBzdHJpbmcsXG4gIG9wMjogc3RyaW5nLFxuICBzdGFydDogc3RyaW5nLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcmFuayA9IGlucHV0RGltcy5sZW5ndGg7XG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCA8PSAyKSB7XG4gICAgY29uc3Qga3cgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlW2F0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoIC0gMV07XG4gICAgY29uc3Qgc3cgPSBhdHRyaWJ1dGVzLnN0cmlkZXNbYXR0cmlidXRlcy5zdHJpZGVzLmxlbmd0aCAtIDFdO1xuICAgIGNvbnN0IHB3U3RhcnQgPSBhdHRyaWJ1dGVzLnBhZHNbYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAvIDIgLSAxXTtcbiAgICBjb25zdCBwd0VuZCA9IGF0dHJpYnV0ZXMucGFkc1thdHRyaWJ1dGVzLnBhZHMubGVuZ3RoIC0gMV07XG4gICAgY29uc3QgZGltVyA9IGlucHV0RGltc1tyYW5rIC0gMV07XG4gICAgbGV0IGNvZGVXID0gJyc7XG4gICAgbGV0IGNvZGVIID0gJyc7XG4gICAgbGV0IGNvZGVIRW5kID0gJyc7XG4gICAgaWYgKHB3U3RhcnQgKyBwd0VuZCAhPT0gMCkge1xuICAgICAgY29kZVcgPSBgXG4gICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke2t3fTsgaSsrKSB7XG4gICAgICAgICAgICB4WyR7cmFua30gLSAxXSA9IGluZGljZXNbJHtyYW5rfSAtIDFdICogJHtzd30gLSAke3B3U3RhcnR9ICsgaTtcbiAgICAgICAgICAgIGlmICh4WyR7cmFua30gLSAxXSA8IDAgfHwgeFske3Jhbmt9IC0gMV0gPj0gJHtkaW1XfSkge1xuICAgICAgICAgICAgICBwYWQrKztcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAke29wMX1cbiAgICAgICAgICB9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZVcgPSBgXG4gICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke2t3fTsgaSsrKSB7XG4gICAgICAgICAgICB4WyR7cmFua30gLSAxXSA9IGluZGljZXNbJHtyYW5rfSAtIDFdICogJHtzd30gLSAke3B3U3RhcnR9ICsgaTtcbiAgICAgICAgICAgICR7b3AxfVxuICAgICAgICAgIH1gO1xuICAgIH1cblxuICAgIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCA9PT0gMikge1xuICAgICAgY29uc3Qga2ggPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlW2F0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoIC0gMl07XG4gICAgICBjb25zdCBzaCA9IGF0dHJpYnV0ZXMuc3RyaWRlc1thdHRyaWJ1dGVzLnN0cmlkZXMubGVuZ3RoIC0gMl07XG4gICAgICBjb25zdCBwaFN0YXJ0ID0gYXR0cmlidXRlcy5wYWRzW2F0dHJpYnV0ZXMucGFkcy5sZW5ndGggLyAyIC0gMl07XG4gICAgICBjb25zdCBwaEVuZCA9IGF0dHJpYnV0ZXMucGFkc1thdHRyaWJ1dGVzLnBhZHMubGVuZ3RoIC0gMl07XG4gICAgICBjb25zdCBkaW1IID0gaW5wdXREaW1zW3JhbmsgLSAyXTtcbiAgICAgIGlmIChwaFN0YXJ0ICsgcGhFbmQgIT09IDApIHtcbiAgICAgICAgY29kZUggPSBgXG4gICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8ICR7a2h9OyBqKyspIHtcbiAgICAgICAgICAgICAgeFske3Jhbmt9IC0gMl0gPSBpbmRpY2VzWyR7cmFua30gLSAyXSAqICR7c2h9IC0gJHtwaFN0YXJ0fSArIGo7XG4gICAgICAgICAgICAgIGlmICh4WyR7cmFua30gLSAyXSA8IDAgfHwgeFske3Jhbmt9IC0gMl0gPj0gJHtkaW1IfSkge1xuICAgICAgICAgICAgICAgIHBhZCs9ICR7a3d9O1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvZGVIID0gYFxuICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCAke2tofTsgaisrKSB7XG4gICAgICAgICAgICAgIHhbJHtyYW5rfSAtIDJdID0gaW5kaWNlc1ske3Jhbmt9IC0gMl0gKiAke3NofSAtICR7cGhTdGFydH0gKyBqO1xuICAgICAgICAgICAgYDtcbiAgICAgIH1cbiAgICAgIGNvZGVIRW5kID0gYFxuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICB9XG5cbiAgICBjb25zdCBwb29saW5nQ29kZSA9IGBcbiAgICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCB4WyR7cmFua31dO1xuICAgICAgICAgIGNvcHlWZWMoaW5kaWNlcywgeCk7XG5cbiAgICAgICAgICBmbG9hdCB2YWx1ZSA9ICR7c3RhcnR9O1xuICAgICAgICAgIGludCBwYWQgPSAwO1xuICAgICAgICAgICR7Y29kZUh9XG4gICAgICAgICAgJHtjb2RlV31cbiAgICAgICAgICAke2NvZGVIRW5kfVxuICAgICAgICAgICR7b3AyfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gcG9vbGluZ0NvZGU7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qga2VybmVsU2l6ZSA9IFNoYXBlVXRpbC5zaXplKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUpO1xuICAgIGNvbnN0IGtlcm5lbFN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoYXR0cmlidXRlcy5rZXJuZWxTaGFwZSk7XG4gICAgY29uc3Qgc3RyaWRlc1JhbmsgPSBrZXJuZWxTdHJpZGVzLmxlbmd0aDtcbiAgICBjb25zdCBwYWRzUmFuayA9IGF0dHJpYnV0ZXMucGFkcy5sZW5ndGg7XG4gICAgY29uc3Qgb2Zmc2V0VG9JbmRpY2VzRnVuY3Rpb24gPSBvZmZzZXRUb0luZGljZXMoc3RyaWRlc1JhbmspO1xuICAgIGNvbnN0IGNvcHlJbnB1dERpbXMgPSBjb3B5QXJyYXkoaW5wdXREaW1zLCAnaW5wdXREaW1zJyk7XG4gICAgY29uc3QgY29weVBhZHMgPSBjb3B5QXJyYXkoYXR0cmlidXRlcy5wYWRzLCAncGFkcycpO1xuICAgIGNvbnN0IGNvcHlLZXJuZWxTdHJpZGVzID0gY29weUFycmF5KGtlcm5lbFN0cmlkZXMsICdrZXJuZWxTdHJpZGVzJyk7XG4gICAgY29uc3QgY29weVN0cmlkZXMgPSBjb3B5QXJyYXkoYXR0cmlidXRlcy5zdHJpZGVzLCAnc3RyaWRlcycpO1xuICAgIGNvbnN0IGhhc1BhZHMgPSBhdHRyaWJ1dGVzLnBhZHMucmVkdWNlKChzdW0sIGN1cikgPT4gc3VtICsgY3VyKTtcbiAgICBsZXQgcGFkQ29kZSA9ICcnO1xuICAgIGlmIChoYXNQYWRzKSB7XG4gICAgICBwYWRDb2RlID0gYFxuICAgICAgICAgICAgaWYgKHhbal0gPj0gaW5wdXREaW1zW2pdIHx8IHhbal0gPCAwKSB7XG4gICAgICAgICAgICAgIHBhZCsrO1xuICAgICAgICAgICAgICBpc1BhZCA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWlzUGFkKSB7XG4gICAgICAgICAgICAke29wMX1cbiAgICAgICAgICB9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcGFkQ29kZSA9IGBcbiAgICAgICAgICB9XG4gICAgICAgICAgJHtvcDF9XG4gICAgICAgIGA7XG4gICAgfVxuICAgIGNvbnN0IHBvb2xpbmdDb2RlID0gYFxuICAgICAgICAke29mZnNldFRvSW5kaWNlc0Z1bmN0aW9ufVxuICAgICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IHhbJHtyYW5rfV07XG4gICAgICAgICAgY29weVZlYyhpbmRpY2VzLCB4KTtcbiAgICAgICAgICBpbnQgb2Zmc2V0WyR7c3RyaWRlc1Jhbmt9XTtcbiAgICAgICAgICBpbnQgcGFkc1ske3BhZHNSYW5rfV07XG4gICAgICAgICAgaW50IGlucHV0RGltc1ske3Jhbmt9XTtcbiAgICAgICAgICBpbnQga2VybmVsU3RyaWRlc1ske3N0cmlkZXNSYW5rfV07XG4gICAgICAgICAgaW50IHN0cmlkZXNbJHtzdHJpZGVzUmFua31dO1xuICAgICAgICAgICR7Y29weVBhZHN9XG4gICAgICAgICAgJHtjb3B5SW5wdXREaW1zfVxuICAgICAgICAgICR7Y29weVN0cmlkZXN9XG4gICAgICAgICAgJHtjb3B5S2VybmVsU3RyaWRlc31cblxuICAgICAgICAgIGZsb2F0IHZhbHVlID0gJHtzdGFydH07XG4gICAgICAgICAgaW50IHBhZCA9IDA7XG4gICAgICAgICAgYm9vbCBpc1BhZCA9IGZhbHNlO1xuICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtrZXJuZWxTaXplfTsgaSsrKSB7XG4gICAgICAgICAgICBvZmZzZXRUb0luZGljZXMoaSwga2VybmVsU3RyaWRlcywgb2Zmc2V0KTtcbiAgICAgICAgICAgIGlzUGFkID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKGludCBqID0gJHtyYW5rfSAtICR7c3RyaWRlc1Jhbmt9OyBqIDwgJHtyYW5rfTsgaisrKSB7XG4gICAgICAgICAgICAgIHhbal0gPSBpbmRpY2VzW2pdICogc3RyaWRlc1tqIC0gJHtyYW5rfSArICR7c3RyaWRlc1Jhbmt9XVxuICAgICAgICAgICAgICAgICsgb2Zmc2V0W2ogLSAke3Jhbmt9ICsgJHtzdHJpZGVzUmFua31dIC0gcGFkc1tqIC0gMl07XG4gICAgICAgICAgICAgICR7cGFkQ29kZX1cbiAgICAgICAgICB9XG4gICAgICAgICAgJHtvcDJ9XG5cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIHBvb2xpbmdDb2RlO1xuICB9XG59O1xuXG5jb25zdCBjb3B5QXJyYXkgPSAoYXJyYXk6IHJlYWRvbmx5IG51bWJlcltdLCBhcnJheU5hbWU6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGxldCBibG9jayA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgYmxvY2sgKz0gYFxuICAgICAgJHthcnJheU5hbWV9WyR7aX1dID0gJHthcnJheVtpXX07XG4gICAgYDtcbiAgfVxuICByZXR1cm4gYmxvY2s7XG59O1xuXG5jb25zdCBvZmZzZXRUb0luZGljZXMgPSAocmFuazogbnVtYmVyKTogc3RyaW5nID0+IGBcbiAgdm9pZCBvZmZzZXRUb0luZGljZXMoaW50IG9mZnNldCwgaW50WyR7cmFua31dIHN0cmlkZXMsIG91dCBpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuICAgIGlmICgke3Jhbmt9ID09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke3Jhbmt9IC0gMTsgKytpKSB7XG4gICAgICBpbmRpY2VzW2ldID0gb2Zmc2V0IC8gc3RyaWRlc1tpXTtcbiAgICAgIG9mZnNldCAtPSBpbmRpY2VzW2ldICogc3RyaWRlc1tpXTtcbiAgICB9XG4gICAgaW5kaWNlc1ske3Jhbmt9IC0gMV0gPSBvZmZzZXQ7XG4gIH1gO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE5VTUJFUl9UWVBFUywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBSZWR1Y2VBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhlczogbnVtYmVyW107XG4gIHJlYWRvbmx5IGtlZXBEaW1zOiBib29sZWFuO1xufVxuXG4vLyByZXR1cm4gW2luaXQgb3BzLCByZWR1Y2Ugb3BzLCBmaW5hbCBvcHNdXG50eXBlIFJlZHVjZU9wID0gKGlucHV0czogVGVuc29yW10sIGF4ZXM6IG51bWJlcltdKSA9PiBzdHJpbmdbXTtcblxuY29uc3QgcmVkdWNlID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4gIG5hbWU6IHN0cmluZyxcbiAgcmVkdWNlT3A6IFJlZHVjZU9wLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIGNvbnN0IHJlZHVjZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgICBuYW1lLFxuICAgIGlucHV0TmFtZXM6IFsnQSddLFxuICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIH07XG5cbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4ucmVkdWNlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVSZWR1Y2VQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsIG5hbWUsIHJlZHVjZU9wLCByZWR1Y2VQcm9ncmFtTWV0YWRhdGEpLFxuICAgIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBSZWR1Y2VBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXhlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdheGVzJywgW10pO1xuICBjb25zdCBrZWVwRGltcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2tlZXBkaW1zJywgMSkgPT09IDE7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGVzLCBrZWVwRGltcyB9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZVJlZHVjZVByb2dyYW1JbmZvID0gKFxuICBfaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuICBfbmFtZTogc3RyaW5nLFxuICByZWR1Y2VPcDogUmVkdWNlT3AsXG4gIHJlZHVjZVByb2dyYW1NZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBvdXRwdXRTaGFwZTogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgaVJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggfHwgMTtcblxuICBjb25zdCBpZHhDb3B5ID0gW107IC8vIGNvcHkgb3V0cHV0IGluZGV4ZXMgdG8gaW5wdXQgaW5kZXhlc1xuXG4gIGNvbnN0IGF4ZXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhlcyhhdHRyaWJ1dGVzLmF4ZXMsIGlucHV0c1swXS5kaW1zLmxlbmd0aCk7XG4gIGNvbnN0IG9wcyA9IHJlZHVjZU9wKGlucHV0cywgYXhlcyk7XG4gIGxldCByZWR1Y2VPcHMgPSBvcHNbMV07XG5cbiAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dHNbMF0uZGltcy5sZW5ndGg7IGsrKykge1xuICAgIC8vIGlmIHRoaXMgYXhpcyBpcyByZWR1Y2VkXG4gICAgaWYgKGF4ZXMuaW5kZXhPZihrKSA+PSAwIHx8IGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBpZiAoYXR0cmlidXRlcy5rZWVwRGltcykge1xuICAgICAgICBvdXRwdXRTaGFwZS5wdXNoKDEpO1xuICAgICAgfSAvLyBlbHNlIHsgcmVtb3ZlIHRoZSBheGlzIGZyb20gb3V0cHV0U2hhcGU7IH1cblxuICAgICAgLy8gbG9vcCBvdmVyIHRoZSBkLXRoIGF4aXNcbiAgICAgIHJlZHVjZU9wcyA9IGBcbiAgICAgICAgICBmb3IoaW50IGoke2t9ID0gMDsgaiR7a30gPCAke2lucHV0c1swXS5kaW1zW2tdfTsgaiR7a30rKykge1xuICAgICAgICAgICAgaW5wdXRJZHhbJHtrfV0gPSBqJHtrfTtcbiAgICAgICAgICAgICR7cmVkdWNlT3BzfVxuICAgICAgICAgIH1gO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZHhDb3B5LnB1c2goYGlucHV0SWR4WyR7a31dID0gb3V0cHV0SWR4WyR7b3V0cHV0U2hhcGUubGVuZ3RofV07YCk7XG5cbiAgICAgIG91dHB1dFNoYXBlLnB1c2goaW5wdXRzWzBdLmRpbXNba10pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG9SYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoIHx8IDE7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgb3V0cHV0SWR4WyR7b1Jhbmt9XSkge1xuICAgICAgICBmbG9hdCB2YWx1ZTsgICAgICAgICAgICAgICAgIC8vIGZpbmFsIHJlc3VsdFxuICAgICAgICBpbnQgaW5wdXRJZHhbJHtpUmFua31dOyAgICAgIC8vIGFkZHJlc3NpbmcgaW5wdXQgZGF0YVxuICAgICAgICAke2lkeENvcHkuam9pbignXFxuJyl9XG4gICAgICAgICR7b3BzWzBdfSAgICAgICAvLyBpbml0IG9wcyBmb3IgcmVkdWNlIG1heC9taW5cbiAgICAgICAgJHtyZWR1Y2VPcHN9XG4gICAgICAgICR7b3BzWzJdfSAgICAgICAvLyBmaW5hbCBjb21wdXRhdGlvbiBmb3IgcmVkdWNlIG1lYW5cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfWA7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5yZWR1Y2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICAvLyBUT0RPOiBzdXBwb3J0IFJlZHVjZSogb3BlcmF0b3JzIHdpdGggMiBpbnB1dHMuXG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlZHVjZSBvcCByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKE5VTUJFUl9UWVBFUy5pbmRleE9mKGlucHV0c1swXS50eXBlKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZVN1bTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoKTogc3RyaW5nW10gPT4gWyd2YWx1ZSA9IDAuMDsnLCAndmFsdWUgKz0gX0EoaW5wdXRJZHgpOycsICcnXTtcbiAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VTdW0nLCByZWR1Y2VPcCk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWVhbjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhlczogbnVtYmVyW10pOiBzdHJpbmdbXSA9PiB7XG4gICAgbGV0IHNpemUgPSAxLjA7XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dHNbMF0uZGltcy5sZW5ndGg7IGsrKykge1xuICAgICAgaWYgKGF4ZXMuaW5kZXhPZihrKSA+PSAwIHx8IGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHNpemUgKj0gaW5wdXRzWzBdLmRpbXNba107XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFsndmFsdWUgPSAwLjA7JywgJ3ZhbHVlICs9IF9BKGlucHV0SWR4KTsnLCBgdmFsdWUgLz0gJHtzaXplfS47YF07IC8vIGVuc3VyZSByZWFsIG51bWJlciB3aXRoIGAuYFxuICB9O1xuICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZU1lYW4nLCByZWR1Y2VPcCk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWF4OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dHM6IFRlbnNvcltdLCBheGVzOiBudW1iZXJbXSk6IHN0cmluZ1tdID0+IHtcbiAgICBjb25zdCBpZHhaZXJvID0gW107XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dHNbMF0uZGltcy5sZW5ndGg7IGsrKykge1xuICAgICAgaWYgKGF4ZXMuaW5kZXhPZihrKSA+PSAwIHx8IGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGlkeFplcm8ucHVzaChgaW5wdXRJZHhbJHtrfV0gPSAwO2ApOyAvLyBmaXJzdCBlbGVtZW50XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFtgJHtpZHhaZXJvLmpvaW4oJ1xcbicpfVxcbnZhbHVlID0gX0EoaW5wdXRJZHgpO2AsICd2YWx1ZSA9IG1heCh2YWx1ZSwgX0EoaW5wdXRJZHgpKTsnLCAnJ107XG4gIH07XG4gIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlTWF4JywgcmVkdWNlT3ApO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZU1pbjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhlczogbnVtYmVyW10pOiBzdHJpbmdbXSA9PiB7XG4gICAgY29uc3QgaWR4WmVybyA9IFtdO1xuICAgIGZvciAobGV0IGsgPSAwOyBrIDwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoOyBrKyspIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZHhaZXJvLnB1c2goYGlucHV0SWR4WyR7a31dID0gMDtgKTsgLy8gZmlyc3QgZWxlbWVudFxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBbYCR7aWR4WmVyby5qb2luKCdcXG4nKX1cXG52YWx1ZSA9IF9BKGlucHV0SWR4KTtgLCAndmFsdWUgPSBtaW4odmFsdWUsIF9BKGlucHV0SWR4KSk7JywgJyddO1xuICB9O1xuICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZU1pbicsIHJlZHVjZU9wKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VQcm9kOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9ICgpOiBzdHJpbmdbXSA9PiBbJ3ZhbHVlID0gMS4wOycsICd2YWx1ZSAqPSBfQShpbnB1dElkeCk7JywgJyddO1xuICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZVByb2QnLCByZWR1Y2VPcCk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9ICgpOiBzdHJpbmdbXSA9PiBbJ3ZhbHVlID0gMC4wOycsICd2YWx1ZSArPSBfQShpbnB1dElkeCk7JywgJ3ZhbHVlID0gbG9nKHZhbHVlKTsnXTtcbiAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VMb2dTdW0nLCByZWR1Y2VPcCk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtU3F1YXJlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9ICgpOiBzdHJpbmdbXSA9PiBbJ2Zsb2F0IHQ7IHZhbHVlID0gMC4wOycsICd0ID0gX0EoaW5wdXRJZHgpOyB2YWx1ZSArPSB0ICogdDsnLCAnJ107XG4gIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlTG9nU3VtU3F1YXJlJywgcmVkdWNlT3ApO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3QgcmVzaGFwZSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlc2hhcGVkRGltcyA9IFNoYXBlVXRpbC5jYWxjdWxhdGVSZXNoYXBlZERpbXMoaW5wdXRzWzBdLmRpbXMsIGlucHV0c1sxXS5pbnRlZ2VyRGF0YSk7XG4gIGlmIChoYW5kbGVyLnNlc3Npb24ucGFjaykge1xuICAgIHJldHVybiBbaGFuZGxlci5yZXNoYXBlUGFja2VkKGlucHV0c1swXSwgcmVzaGFwZWREaW1zKV07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtoYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIHJlc2hhcGVkRGltcyldO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXBzYW1wbGVBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgb3BzZXQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgaXNSZXNpemU6IGJvb2xlYW47XG4gIHJlYWRvbmx5IG1vZGU6IHN0cmluZztcbiAgcmVhZG9ubHkgc2NhbGVzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgZXh0cmFwb2xhdGlvblZhbHVlOiBudW1iZXI7XG4gIHJlYWRvbmx5IGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHVzZUV4dHJhcG9sYXRpb246IGJvb2xlYW47XG4gIHJlYWRvbmx5IG5lZWRSb2lJbnB1dDogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbmVhcmVzdE1vZGU6IHN0cmluZztcbiAgcmVhZG9ubHkgY3ViaWNDb2VmZmljaWVudEE6IG51bWJlcjtcbiAgcmVhZG9ubHkgZXhjbHVkZU91dHNpZGU6IGJvb2xlYW47XG4gIHJlYWRvbmx5IHVzZU5lYXJlc3QyeE9wdGltaXphdGlvbjogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcm9pSW5wdXRJZHg6IG51bWJlcjtcbiAgcmVhZG9ubHkgc2NhbGVzSW5wdXRJZHg6IG51bWJlcjtcbiAgcmVhZG9ubHkgc2l6ZXNJbnB1dElkeDogbnVtYmVyO1xufVxuXG5jb25zdCB1cHNhbXBsZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1Vwc2FtcGxlJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3QgdXBzYW1wbGU6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBVcHNhbXBsZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLnVwc2FtcGxlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVVcHNhbXBsZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksXG4gICAgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y3OiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBVcHNhbXBsZUF0dHJpYnV0ZXMgPT4gcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXMobm9kZSwgNyk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y5OiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBVcHNhbXBsZUF0dHJpYnV0ZXMgPT4gcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXMobm9kZSwgOSk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlLCBvcHNldDogbnVtYmVyKTogVXBzYW1wbGVBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgaXNSZXNpemUgPSBvcHNldCA+PSAxMDtcblxuICAvLyBwcm9jZXNzaW5nIG5vZGUgYXR0cmlidXRlc1xuICBjb25zdCBtb2RlID0gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbW9kZScsICduZWFyZXN0Jyk7XG4gIGlmIChtb2RlICE9PSAnbmVhcmVzdCcgJiYgbW9kZSAhPT0gJ2xpbmVhcicgJiYgKG9wc2V0IDwgMTEgfHwgbW9kZSAhPT0gJ2N1YmljJykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHVucmVjb2duaXplZCBtb2RlOiAke21vZGV9YCk7XG4gIH1cblxuICBsZXQgc2NhbGVzOiBudW1iZXJbXSA9IFtdO1xuICBpZiAob3BzZXQgPCA5KSB7XG4gICAgc2NhbGVzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0cygnc2NhbGVzJyk7XG4gICAgc2NhbGVzVmFsaWRhdGlvbihzY2FsZXMsIG1vZGUsIGlzUmVzaXplKTtcbiAgfVxuXG4gIGNvbnN0IGV4dHJhcG9sYXRpb25WYWx1ZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnZXh0cmFwb2xhdGlvbl92YWx1ZScsIDAuMCk7XG5cbiAgY29uc3QgY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgPVxuICAgIG9wc2V0ID4gMTAgPyBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdjb29yZGluYXRlX3RyYW5zZm9ybWF0aW9uX21vZGUnLCAnaGFsZl9waXhlbCcpIDogJ2FzeW1tZXRyaWMnO1xuICBpZiAoXG4gICAgW1xuICAgICAgJ2FzeW1tZXRyaWMnLFxuICAgICAgJ3B5dG9yY2hfaGFsZl9waXhlbCcsXG4gICAgICAndGZfaGFsZl9waXhlbF9mb3Jfbm4nLFxuICAgICAgJ2FsaWduX2Nvcm5lcnMnLFxuICAgICAgJ3RmX2Nyb3BfYW5kX3Jlc2l6ZScsXG4gICAgICAnaGFsZl9waXhlbCcsXG4gICAgXS5pbmRleE9mKGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlKSA9PT0gLTFcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBjb29yZGluYXRlX3RyYW5zZm9ybV9tb2RlICcke2Nvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlfScgaXMgbm90IHN1cHBvcnRlZGApO1xuICB9XG4gIGNvbnN0IG5lZWRSb2lJbnB1dCA9IGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlID09PSAndGZfY3JvcF9hbmRfcmVzaXplJztcbiAgY29uc3QgdXNlRXh0cmFwb2xhdGlvbiA9IG5lZWRSb2lJbnB1dDtcblxuICBjb25zdCBuZWFyZXN0TW9kZSA9XG4gICAgbW9kZSA9PT0gJ25lYXJlc3QnICYmIG9wc2V0ID49IDExID8gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbmVhcmVzdF9tb2RlJywgJ3JvdW5kX3ByZWZlcl9mbG9vcicpIDogJyc7XG4gIGlmIChbJ3JvdW5kX3ByZWZlcl9mbG9vcicsICdyb3VuZF9wcmVmZXJfY2VpbCcsICdmbG9vcicsICdjZWlsJywgJyddLmluZGV4T2YobmVhcmVzdE1vZGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgbmVhcmVzdF9tb2RlICcke25lYXJlc3RNb2RlfScgaXMgbm90IHN1cHBvcnRlZGApO1xuICB9XG5cbiAgY29uc3QgY3ViaWNDb2VmZmljaWVudEEgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2N1YmljX2NvZWZmX2EnLCAtMC43NSk7XG4gIGNvbnN0IGV4Y2x1ZGVPdXRzaWRlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnZXhjbHVkZV9vdXRzaWRlJywgMCkgIT09IDA7XG4gIGlmIChleGNsdWRlT3V0c2lkZSAmJiBtb2RlICE9PSAnY3ViaWMnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdleGNsdWRlX291dHNpZGUgY2FuIGJlIHNldCB0byAxIG9ubHkgd2hlbiBtb2RlIGlzIENVQklDLicpO1xuICB9XG5cbiAgY29uc3QgdXNlTmVhcmVzdDJ4T3B0aW1pemF0aW9uID1cbiAgICBvcHNldCA8IDExID8gdHJ1ZSA6IG1vZGUgPT09ICduZWFyZXN0JyAmJiBjb29yZGluYXRlVHJhbnNmb3JtTW9kZSA9PT0gJ2FzeW1tZXRyaWMnICYmIG5lYXJlc3RNb2RlID09PSAnZmxvb3InO1xuXG4gIGxldCByb2lJbnB1dElkeCA9IDA7XG4gIGxldCBzY2FsZXNJbnB1dElkeCA9IDA7XG4gIGxldCBzaXplc0lucHV0SWR4ID0gMDtcblxuICBpZiAob3BzZXQgPiAxMCkge1xuICAgIC8vIGhhbmRsZSB3aGVuIHJvaUlucHV0IGlzIG5vdCBnaXZlblxuICAgIGlmIChub2RlLmlucHV0cy5sZW5ndGggPiAyKSB7XG4gICAgICByb2lJbnB1dElkeCA9IDE7XG4gICAgICBzY2FsZXNJbnB1dElkeCA9IDI7XG4gICAgICBzaXplc0lucHV0SWR4ID0gMztcbiAgICB9IGVsc2Uge1xuICAgICAgc2NhbGVzSW5wdXRJZHggPSAxO1xuICAgICAgc2l6ZXNJbnB1dElkeCA9IDI7XG4gICAgfVxuICB9IGVsc2UgaWYgKG9wc2V0ID09PSA5KSB7XG4gICAgc2NhbGVzSW5wdXRJZHggPSAxO1xuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgb3BzZXQsXG4gICAgaXNSZXNpemUsXG4gICAgbW9kZSxcbiAgICBzY2FsZXMsXG4gICAgZXh0cmFwb2xhdGlvblZhbHVlLFxuICAgIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlLFxuICAgIHVzZUV4dHJhcG9sYXRpb24sXG4gICAgbmVlZFJvaUlucHV0LFxuICAgIG5lYXJlc3RNb2RlLFxuICAgIGN1YmljQ29lZmZpY2llbnRBLFxuICAgIGV4Y2x1ZGVPdXRzaWRlLFxuICAgIHVzZU5lYXJlc3QyeE9wdGltaXphdGlvbixcbiAgICByb2lJbnB1dElkeCxcbiAgICBzY2FsZXNJbnB1dElkeCxcbiAgICBzaXplc0lucHV0SWR4LFxuICB9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZVVwc2FtcGxlUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IFtpbnB1dFdpZHRoLCBpbnB1dEhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBpbnB1dHNbMF0uZGltcyxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgKTtcblxuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLm1hcCgoZGltLCBpKSA9PiBNYXRoLmZsb29yKGRpbSAqIGF0dHJpYnV0ZXMuc2NhbGVzW2ldKSk7XG4gIGNvbnN0IFtvdXRwdXRXaWR0aCwgb3V0cHV0SGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIG91dHB1dFNoYXBlLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICApO1xuICBjb25zdCBkaW0gPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3Qgb3V0cHV0UGl0Y2hlcyA9IG5ldyBBcnJheTxudW1iZXI+KGRpbSk7XG4gIGNvbnN0IGlucHV0UGl0Y2hlcyA9IG5ldyBBcnJheTxudW1iZXI+KGRpbSk7XG4gIGxldCBwcmVjYWxjdWxhdGVkUGl0Y2hlcyA9IGBcbiAgICAgIGludCBvdXRwdXRfcGl0Y2hlc1ske2RpbX1dO1xuICAgICAgaW50IGlucHV0X3BpdGNoZXNbJHtkaW19XTtcbiAgICAgIGA7XG4gIGZvciAobGV0IGQgPSBkaW0gLSAxOyBkID49IDA7IGQtLSkge1xuICAgIG91dHB1dFBpdGNoZXNbZF0gPSBkID09PSBkaW0gLSAxID8gMSA6IG91dHB1dFBpdGNoZXNbZCArIDFdICogb3V0cHV0U2hhcGVbZCArIDFdO1xuICAgIGlucHV0UGl0Y2hlc1tkXSA9IGQgPT09IGRpbSAtIDEgPyAxIDogaW5wdXRQaXRjaGVzW2QgKyAxXSAqIGlucHV0c1swXS5kaW1zW2QgKyAxXTtcblxuICAgIHByZWNhbGN1bGF0ZWRQaXRjaGVzICs9IGBcbiAgICAgICAgb3V0cHV0X3BpdGNoZXNbJHtkfV0gPSAke291dHB1dFBpdGNoZXNbZF19O1xuICAgICAgICBpbnB1dF9waXRjaGVzWyR7ZH1dID0gJHtpbnB1dFBpdGNoZXNbZF19O1xuICAgICAgICBgO1xuICB9XG4gIGNvbnN0IGdldElucHV0RmxvYXRGdW5jdGlvbiA9IGBcbiAgICAgIGZsb2F0IGdldElucHV0RmxvYXQoaW50IGluZGV4KSB7XG4gICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMoaW5kZXgsICR7aW5wdXRXaWR0aH0sICR7aW5wdXRIZWlnaHR9KTtcbiAgICAgICAgZmxvYXQgdmFsdWUgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oWCwgY29vcmRzKSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGA7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID1cbiAgICBhdHRyaWJ1dGVzLm1vZGUgPT09ICduZWFyZXN0J1xuICAgICAgPyAvLyBuZWFyZXN0XG4gICAgICAgIGBcbiAgICAke2dldElucHV0RmxvYXRGdW5jdGlvbn1cbiAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7ZGltfV0pIHtcbiAgICAgIGludCBpbnB1dF9pbmRleCA9IDA7XG4gICAgICBpbnQgb3V0cHV0X2luZGV4ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke291dHB1dFdpZHRofSwgJHtvdXRwdXRIZWlnaHR9KTtcblxuICAgICAgJHtwcmVjYWxjdWxhdGVkUGl0Y2hlc31cblxuICAgICAgaW50IGQsIG07XG4gICAgICBmb3IgKGludCBkaW0gPSAwOyBkaW0gPCAke2RpbX07ICsrZGltKSB7XG4gICAgICAgIGQgPSBvdXRwdXRfaW5kZXggLyBvdXRwdXRfcGl0Y2hlc1tkaW1dO1xuICAgICAgICBtID0gb3V0cHV0X2luZGV4IC0gZCAqIG91dHB1dF9waXRjaGVzW2RpbV07XG4gICAgICAgIG91dHB1dF9pbmRleCA9IG07XG5cbiAgICAgICAgaWYgKHNjYWxlc1tkaW1dICE9IDEgJiYgZCA+IDApIHtcbiAgICAgICAgICBpbnQgZDIgPSBkIC8gc2NhbGVzW2RpbV07XG4gICAgICAgICAgbSA9IGQgLSBkMiAqIHNjYWxlc1tkaW1dO1xuICAgICAgICAgIGQgPSBkMjtcbiAgICAgICAgfVxuICAgICAgICBpbnB1dF9pbmRleCArPSBpbnB1dF9waXRjaGVzW2RpbV0gKiBkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCk7XG4gICAgfWBcbiAgICAgIDogZGltID09PSA0XG4gICAgICAgID8gLy8gYmlsaW5lYXIgNERcbiAgICAgICAgICBgXG4gICAgJHtnZXRJbnB1dEZsb2F0RnVuY3Rpb259XG4gICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1s0XSkge1xuICAgICAgaW50IGlucHV0X2luZGV4ID0gMDtcbiAgICAgIGludCBvdXRwdXRfaW5kZXggPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7b3V0cHV0V2lkdGh9LCAke291dHB1dEhlaWdodH0pO1xuXG4gICAgICAke3ByZWNhbGN1bGF0ZWRQaXRjaGVzfVxuXG4gICAgICBpbnQgbTtcbiAgICAgIGludCBpbmRleF9vZl9kaW0wLCBpbmRleF9vZl9kaW0xLCBpbmRleF9vZl9kaW0yLCBpbmRleF9vZl9kaW0zO1xuICAgICAgaW5kZXhfb2ZfZGltMCA9IG91dHB1dF9pbmRleCAvIG91dHB1dF9waXRjaGVzWzBdO1xuICAgICAgbSA9IG91dHB1dF9pbmRleCAtIGluZGV4X29mX2RpbTAgKiBvdXRwdXRfcGl0Y2hlc1swXTtcbiAgICAgIGluZGV4X29mX2RpbTEgPSBtIC8gb3V0cHV0X3BpdGNoZXNbMV07XG4gICAgICBtID0gbSAtIGluZGV4X29mX2RpbTEgKiBvdXRwdXRfcGl0Y2hlc1sxXTtcbiAgICAgIGluZGV4X29mX2RpbTIgPSBtIC8gb3V0cHV0X3BpdGNoZXNbMl07XG4gICAgICBtID0gbSAtIGluZGV4X29mX2RpbTIgKiBvdXRwdXRfcGl0Y2hlc1syXTtcbiAgICAgIGluZGV4X29mX2RpbTMgPSBtO1xuXG4gICAgICBpbnQgaW5kZXhfb2ZfaW5wdXRfZGltMiwgaW5kZXhfb2ZfaW5wdXRfZGltMywgeF9vZmZzZXQsIHlfb2Zmc2V0O1xuICAgICAgaW5kZXhfb2ZfaW5wdXRfZGltMiA9IGluZGV4X29mX2RpbTIgLyBzY2FsZXNbMl07XG4gICAgICB5X29mZnNldCA9IGluZGV4X29mX2RpbTIgLSBpbmRleF9vZl9pbnB1dF9kaW0yICogc2NhbGVzWzJdO1xuICAgICAgaW5kZXhfb2ZfaW5wdXRfZGltMyA9IGluZGV4X29mX2RpbTMgLyBzY2FsZXNbM107XG4gICAgICB4X29mZnNldCA9IGluZGV4X29mX2RpbTMgLSBpbmRleF9vZl9pbnB1dF9kaW0zICogc2NhbGVzWzNdO1xuXG4gICAgICBpbnB1dF9pbmRleCA9IGluZGV4X29mX2RpbTAgKiBpbnB1dF9waXRjaGVzWzBdICtcbiAgICAgICAgICAgIGluZGV4X29mX2RpbTEgKiBpbnB1dF9waXRjaGVzWzFdICtcbiAgICAgICAgICAgIGluZGV4X29mX2lucHV0X2RpbTIgKiBpbnB1dF9waXRjaGVzWzJdICtcbiAgICAgICAgICAgIGluZGV4X29mX2lucHV0X2RpbTM7XG5cbiAgICAgIGZsb2F0IHgwMCA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXgpO1xuICAgICAgZmxvYXQgeDEwLCB4MDEsIHgxMTtcblxuICAgICAgYm9vbCBlbmRfb2ZfZGltMiA9IGZhbHNlO1xuICAgICAgaWYgKGluZGV4X29mX2lucHV0X2RpbTIgPT0gKCR7aW5wdXRzWzBdLmRpbXNbMl19IC0gMSkpIHtcbiAgICAgICAgLy8gSXQncyB0aGUgZW5kIGluIGRpbWVuc2lvbiAyXG4gICAgICAgIHgwMSA9IHgwMDtcbiAgICAgICAgZW5kX29mX2RpbTIgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeDAxID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIGlucHV0X3BpdGNoZXNbMl0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5kZXhfb2ZfaW5wdXRfZGltMyA9PSAoaW5wdXRfcGl0Y2hlc1syXSAtIDEpKSB7XG4gICAgICAgIC8vIEl0J3MgdGhlIGVuZCBpbiBkaW1lbnNpb24gM1xuICAgICAgICB4MTAgPSB4MDA7XG4gICAgICAgIHgxMSA9IHgwMTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB4MTAgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4ICsgMSk7XG4gICAgICAgIHgxMSA9IGVuZF9vZl9kaW0yID8geDEwIDogZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIGlucHV0X3BpdGNoZXNbMl0gKyAxKTtcbiAgICAgIH1cblxuICAgICAgZmxvYXQgeTAgPSB4MDAgKyBmbG9hdCh5X29mZnNldCkgKiAoeDAxIC0geDAwKSAvIGZsb2F0KHNjYWxlc1syXSk7XG4gICAgICBmbG9hdCB5MSA9IHgxMCArIGZsb2F0KHlfb2Zmc2V0KSAqICh4MTEgLSB4MTApIC8gZmxvYXQoc2NhbGVzWzJdKTtcbiAgICAgIHJldHVybiB5MCArIGZsb2F0KHhfb2Zmc2V0KSAqICh5MSAtIHkwKSAvIGZsb2F0KHNjYWxlc1szXSk7XG4gICAgfWBcbiAgICAgICAgOiAvLyBiaWxpbmVhciAyRFxuICAgICAgICAgIGBcbiAgICAke2dldElucHV0RmxvYXRGdW5jdGlvbn1cbiAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWzJdKSB7XG4gICAgICBpbnQgaW5wdXRfaW5kZXggPSAwO1xuICAgICAgaW50IG91dHB1dF9pbmRleCA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHtvdXRwdXRXaWR0aH0sICR7b3V0cHV0SGVpZ2h0fSk7XG5cbiAgICAgICR7cHJlY2FsY3VsYXRlZFBpdGNoZXN9XG5cbiAgICAgIGludCBtO1xuICAgICAgaW50IGluZGV4X29mX2RpbTAsIGluZGV4X29mX2RpbTE7XG4gICAgICBpbmRleF9vZl9kaW0wID0gb3V0cHV0X2luZGV4IC8gb3V0cHV0X3BpdGNoZXNbMF07XG4gICAgICBtID0gb3V0cHV0X2luZGV4IC0gaW5kZXhfb2ZfZGltMCAqIG91dHB1dF9waXRjaGVzWzBdO1xuICAgICAgaW5kZXhfb2ZfZGltMSA9IG07XG5cbiAgICAgIGludCBpbmRleF9vZl9pbnB1dF9kaW0wLCBpbmRleF9vZl9pbnB1dF9kaW0xLCB4X29mZnNldCwgeV9vZmZzZXQ7XG4gICAgICBpbmRleF9vZl9pbnB1dF9kaW0wID0gaW5kZXhfb2ZfZGltMCAvIHNjYWxlc1swXTtcbiAgICAgIHlfb2Zmc2V0ID0gaW5kZXhfb2ZfZGltMCAtIGluZGV4X29mX2lucHV0X2RpbTAgKiBzY2FsZXNbMF07XG4gICAgICBpbmRleF9vZl9pbnB1dF9kaW0xID0gaW5kZXhfb2ZfZGltMSAvIHNjYWxlc1sxXTtcbiAgICAgIHhfb2Zmc2V0ID0gaW5kZXhfb2ZfZGltMSAtIGluZGV4X29mX2lucHV0X2RpbTEgKiBzY2FsZXNbMV07XG5cbiAgICAgIGlucHV0X2luZGV4ID0gaW5kZXhfb2ZfaW5wdXRfZGltMCAqIGlucHV0X3BpdGNoZXNbMF0gKyBpbmRleF9vZl9pbnB1dF9kaW0xO1xuXG4gICAgICBmbG9hdCB4MDAgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4KTtcbiAgICAgIGZsb2F0IHgxMCwgeDAxLCB4MTE7XG5cbiAgICAgIGJvb2wgZW5kX29mX2RpbTAgPSBmYWxzZTtcbiAgICAgIGlmIChpbmRleF9vZl9pbnB1dF9kaW0wID09ICgke2lucHV0c1swXS5kaW1zWzBdfSAtIDEpKSB7XG4gICAgICAgIC8vIEl0J3MgdGhlIGVuZCBpbiBkaW1lbnNpb24gMFxuICAgICAgICB4MDEgPSB4MDA7XG4gICAgICAgIGVuZF9vZl9kaW0wID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHgwMSA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyBpbnB1dF9waXRjaGVzWzBdKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluZGV4X29mX2lucHV0X2RpbTEgPT0gKGlucHV0X3BpdGNoZXNbMF0gLSAxKSkge1xuICAgICAgICAvLyBJdCdzIHRoZSBlbmQgaW4gZGltZW5zaW9uIDFcbiAgICAgICAgeDEwID0geDAwO1xuICAgICAgICB4MTEgPSB4MDE7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgeDEwID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIDEpO1xuICAgICAgICB4MTEgPSBlbmRfb2ZfZGltMCA/IHgxMCA6IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyBpbnB1dF9waXRjaGVzWzBdICsgMSk7XG4gICAgICB9XG5cbiAgICAgIGZsb2F0IHkwID0geDAwICsgZmxvYXQoeV9vZmZzZXQpICogKHgwMSAtIHgwMCkgLyBmbG9hdChzY2FsZXNbMF0pO1xuICAgICAgZmxvYXQgeTEgPSB4MTAgKyBmbG9hdCh5X29mZnNldCkgKiAoeDExIC0geDEwKSAvIGZsb2F0KHNjYWxlc1swXSk7XG4gICAgICByZXR1cm4geTAgKyBmbG9hdCh4X29mZnNldCkgKiAoeTEgLSB5MCkgLyBmbG9hdChzY2FsZXNbMV0pO1xuICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLnVwc2FtcGxlUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICB2YXJpYWJsZXM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3NjYWxlcycsXG4gICAgICAgIHR5cGU6ICdpbnQnLFxuICAgICAgICBhcnJheUxlbmd0aDogYXR0cmlidXRlcy5zY2FsZXMubGVuZ3RoLFxuICAgICAgICBkYXRhOiBhdHRyaWJ1dGVzLnNjYWxlcy5tYXAoKHgpID0+IE1hdGguY2VpbCh4KSksXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlOiBVcHNhbXBsZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgaWYgKFxuICAgICFpbnB1dHMgfHxcbiAgICAoYXR0cmlidXRlLm9wc2V0IDwgOSAmJiBpbnB1dHMubGVuZ3RoICE9PSAxKSB8fFxuICAgIChhdHRyaWJ1dGUub3BzZXQgPj0gOSAmJiBhdHRyaWJ1dGUub3BzZXQgPCAxMSAmJiBpbnB1dHMubGVuZ3RoICE9PSAyKSB8fFxuICAgIChhdHRyaWJ1dGUub3BzZXQgPj0gMTEgJiYgaW5wdXRzLmxlbmd0aCA8IDIpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dHMuJyk7XG4gIH1cblxuICBpZiAoYXR0cmlidXRlLnNjYWxlcy5sZW5ndGggPiAwICYmIGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gYXR0cmlidXRlLnNjYWxlcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHRlbnNvciB0eXBlcy4nKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHNjYWxlc1ZhbGlkYXRpb24gPSAoc2NhbGVzOiBudW1iZXJbXSwgbW9kZTogc3RyaW5nLCBpc1Jlc2l6ZTogYm9vbGVhbik6IHZvaWQgPT4ge1xuICBpZiAoIWlzUmVzaXplKSB7XG4gICAgZm9yIChjb25zdCBzY2FsZSBvZiBzY2FsZXMpIHtcbiAgICAgIGlmIChzY2FsZSA8IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTY2FsZSB2YWx1ZSBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEuJyk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZvciAoY29uc3Qgc2NhbGUgb2Ygc2NhbGVzKSB7XG4gICAgICBpZiAoc2NhbGUgPD0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NjYWxlIHZhbHVlIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gMC4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKG1vZGUgPT09ICdsaW5lYXInIHx8IG1vZGUgPT09ICdjdWJpYycpIHtcbiAgICBpZiAoc2NhbGVzLmxlbmd0aCAhPT0gMiAmJiAoc2NhbGVzLmxlbmd0aCAhPT0gNCB8fCBzY2FsZXNbMF0gIT09IDEgfHwgc2NhbGVzWzFdICE9PSAxKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAnTGluZWFyJyBtb2RlIGFuZCAnQ3ViaWMnIG1vZGUgb25seSBzdXBwb3J0IDItRCBpbnB1dHMgKCdCaWxpbmVhcicsICdCaWN1YmljJykgXFxcbiAgICAgICAgb3IgNC1EIGlucHV0cyB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIG91dGVybW9zdCAyIHNjYWxlIHZhbHVlcyBiZWluZyAxIFxcXG4gICAgICAgIGluIHRoZSAke2lzUmVzaXplID8gJ1Jlc2l6ZScgOiAnVXBzYW1wbGUnfSBvcGVhcnRvci5gKTtcbiAgICB9XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGdldENvb3Jkc0RhdGFUeXBlIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5pbXBvcnQgeyB1bnBhY2tGcm9tQ2hhbm5lbCB9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5pbXBvcnQgeyBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcywgc2NhbGVzVmFsaWRhdGlvbiwgVXBzYW1wbGVBdHRyaWJ1dGVzLCB2YWxpZGF0ZUlucHV0cyB9IGZyb20gJy4vdXBzYW1wbGUnO1xuXG5jb25zdCByZXNpemVQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdSZXNpemUnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3QgcmVzaXplOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7XG4gICAgICAuLi5yZXNpemVQcm9ncmFtTWV0YWRhdGEsXG4gICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tlZFJlc2l6ZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksXG4gICAgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTA6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IFVwc2FtcGxlQXR0cmlidXRlcyA9PiBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcyhub2RlLCAxMCk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTE6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IFVwc2FtcGxlQXR0cmlidXRlcyA9PiBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcyhub2RlLCAxMSk7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZFJlc2l6ZVByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBbc2NhbGVzLCBvdXRwdXRTaGFwZV0gPSBwcmVwYXJlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7XG5cbiAgY29uc3QgaXNTYW1lID0gc2NhbGVzLmV2ZXJ5KChzOiBudW1iZXIpID0+IHMgPT09IDEpICYmIGF0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgIT09ICd0Zl9jcm9wX2FuZF9yZXNpemUnO1xuICBpZiAoaXNTYW1lKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnJlc2l6ZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWQgfSxcbiAgICAgIGhhc01haW46IHRydWUsXG4gICAgICBzaGFkZXJTb3VyY2U6IGB2b2lkIG1haW4oKSB7XG4gICAgICAgICAgICAgICAgICAgIHZlYzQgdiA9ICR7Z2xzbC50ZXh0dXJlMkR9KFgsIFRleENvb3Jkcyk7XG4gICAgICAgICAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdjtcbiAgICAgICAgICAgICAgICB9YCxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgZGltID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBpZiAoZGltIDwgMikge1xuICAgIHRocm93IG5ldyBFcnJvcihgb3V0cHV0IGRpbWVuc2lvbiBzaG91bGQgYmUgYXQgbGVhc3QgMiwgYnV0IGdvdCAke2RpbX1gKTtcbiAgfVxuXG4gIGNvbnN0IG91dHB1dEhlaWdodCA9IG91dHB1dFNoYXBlW2RpbSAtIDJdO1xuICBjb25zdCBvdXRwdXRXaWR0aCA9IG91dHB1dFNoYXBlW2RpbSAtIDFdO1xuXG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgaWYgKGRpbSAhPT0gaW5wdXRTaGFwZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG91dHB1dCBkaW1lbnNpb24gc2hvdWxkIG1hdGNoIGlucHV0ICR7aW5wdXRTaGFwZS5sZW5ndGh9LCBidXQgZ290ICR7ZGltfWApO1xuICB9XG4gIGNvbnN0IGlucHV0SGVpZ2h0ID0gaW5wdXRTaGFwZVtkaW0gLSAyXTtcbiAgY29uc3QgaW5wdXRXaWR0aCA9IGlucHV0U2hhcGVbZGltIC0gMV07XG5cbiAgY29uc3Qgc2NhbGVzSGVpZ2h0ID0gc2NhbGVzW2RpbSAtIDJdO1xuICBjb25zdCBzY2FsZXNXaWR0aCA9IHNjYWxlc1tkaW0gLSAxXTtcblxuICBsZXQgZ2V0U291cmNlRnJhY0luZGV4ID0gJyc7XG5cbiAgaWYgKGF0dHJpYnV0ZXMubW9kZSAhPT0gJ2xpbmVhcicpIHtcbiAgICAvLyBUT0RPOiBzdXBwb3J0IG90aGVyIG1vZGVzXG4gICAgdGhyb3cgbmV3IEVycm9yKGByZXNpemUgKHBhY2tlZCkgZG9lcyBub3Qgc3VwcG9ydCBtb2RlOiAnJHthdHRyaWJ1dGVzLm1vZGV9J2ApO1xuICB9XG4gIHN3aXRjaCAoYXR0cmlidXRlcy5jb29yZGluYXRlVHJhbnNmb3JtTW9kZSkge1xuICAgIGNhc2UgJ2FzeW1tZXRyaWMnOlxuICAgICAgZ2V0U291cmNlRnJhY0luZGV4ID0gYFxuICAgICAgICAgICAgICAgICAgICB2ZWM0IGdldFNvdXJjZUZyYWNJbmRleChpdmVjNCBjb29yZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2ZWM0KGNvb3JkcykgLyBzY2FsZVdIV0g7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnaGFsZl9waXhlbCc6XG4gICAgICBnZXRTb3VyY2VGcmFjSW5kZXggPSBgXG4gICAgICAgICAgICAgICAgICAgIHZlYzQgZ2V0U291cmNlRnJhY0luZGV4KGl2ZWM0IGNvb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh2ZWM0KGNvb3JkcykgKyAwLjUpIC8gc2NhbGVXSFdIIC0gMC41O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3B5dG9yY2hfaGFsZl9waXhlbCc6XG4gICAgICBnZXRTb3VyY2VGcmFjSW5kZXggPSBgXG4gICAgICAgICAgICAgICAgICAgIHZlYzQgZ2V0U291cmNlRnJhY0luZGV4KGl2ZWM0IGNvb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVjNCBmY29vcmRzID0gdmVjNChjb29yZHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZlYzQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRXaWR0aH0uMCA+IDEuMCA/IChmY29vcmRzLnggKyAwLjUpIC8gc2NhbGVXSFdILnggLSAwLjUgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRIZWlnaHR9LjAgPiAxLjAgPyAoZmNvb3Jkcy55ICsgMC41KSAvIHNjYWxlV0hXSC55IC0gMC41IDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7b3V0cHV0V2lkdGh9LjAgPiAxLjAgPyAoZmNvb3Jkcy56ICsgMC41KSAvIHNjYWxlV0hXSC56IC0gMC41IDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7b3V0cHV0SGVpZ2h0fS4wID4gMS4wID8gKGZjb29yZHMudyArIDAuNSkgLyBzY2FsZVdIV0gudyAtIDAuNSA6IDAuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2FsaWduX2Nvcm5lcnMnOlxuICAgICAgZ2V0U291cmNlRnJhY0luZGV4ID0gYFxuICAgICAgICAgICAgICAgICAgICB2ZWM0IGdldFNvdXJjZUZyYWNJbmRleChpdmVjNCBjb29yZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlYzQgcmVzaXplZCA9IHZlYzQoJHtvdXRwdXRXaWR0aH0uMCAtIDEuMCwgJHtvdXRwdXRIZWlnaHR9LjAgLSAxLjAsICR7b3V0cHV0V2lkdGh9LjAgLSAxLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRIZWlnaHR9LjAgLSAxLjApO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVjNCBvcmlnaW5hbCA9IHZlYzQoJHtpbnB1dFdpZHRofS4wIC0gMS4wLCAke2lucHV0SGVpZ2h0fS4wIC0gMS4wLCAke2lucHV0V2lkdGh9LjAgLSAxLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtpbnB1dEhlaWdodH0uMCAtIDEuMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZWM0IG5ld19zY2FsZSA9IG9yaWdpbmFsIC8gcmVzaXplZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2ZWM0KGNvb3JkcykgKiBuZXdfc2NhbGU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIFRPRE86c3VwcG9ydGluZyBvdGhlciBjb29yZGluYXRlVHJhbnNmb3JtTW9kZXNcbiAgICAgIHRocm93IG5ldyBFcnJvcihgcmVzaXplIChwYWNrZWQpIGRvZXMgbm90IHN1cHBvcnQgY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGU6IFxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcke2F0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGV9J2ApO1xuICB9XG5cbiAgY29uc3QgY29vcmRzRGF0YVR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShkaW0pO1xuICBjb25zdCB1bnBhY2tDaGFubmVsID0gdW5wYWNrRnJvbUNoYW5uZWwoKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICAgICAgY29uc3QgdmVjMiBpbnB1dFdIID0gdmVjMigke2lucHV0SGVpZ2h0fS4wLCAke2lucHV0V2lkdGh9LjApO1xuICAgICAgICAgICAgY29uc3QgdmVjNCBzY2FsZVdIV0ggPSB2ZWM0KGZsb2F0KCR7c2NhbGVzSGVpZ2h0fSksIGZsb2F0KCR7c2NhbGVzV2lkdGh9KSwgZmxvYXQoJHtzY2FsZXNIZWlnaHR9KSwgZmxvYXQoJHtcbiAgICAgICAgICAgICAgc2NhbGVzV2lkdGhcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICR7dW5wYWNrQ2hhbm5lbH1cbiAgICAgICAgICAgICR7Z2V0U291cmNlRnJhY0luZGV4fVxuICAgICAgICAgICAgZmxvYXQgZ2V0QVZhbHVlKGludCB4MTAsIGludCByLCBpbnQgYywgaW50IGQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChnZXRBKHgxMCwgciwgYywgZCksIHZlYzIoYywgZCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICAgICAgICAgICR7Y29vcmRzRGF0YVR5cGV9IHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG5cbiAgICAgICAgICAgICAgICBpbnQgYmF0Y2ggPSByY1swXTtcbiAgICAgICAgICAgICAgICBpbnQgZGVwdGggPSByY1sxXTtcblxuICAgICAgICAgICAgICAgIC8vIHJldHJpZXZlIHRoZSA0IGNvb3JkaW5hdGVzIHRoYXQgaXMgdXNlZCBpbiB0aGUgNCBwYWNrZWQgb3V0cHV0IHZhbHVlcy5cbiAgICAgICAgICAgICAgICBpdmVjNCBjb29yZHMgPSBpdmVjNChyYy53eiwgcmMudyArIDEsIHJjLnogKyAxKTtcblxuICAgICAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgc291cmNlIGluZGV4IGluIGZyYWN0aW9uXG4gICAgICAgICAgICAgICAgdmVjNCBzb3VyY2VGcmFjID0gZ2V0U291cmNlRnJhY0luZGV4KGNvb3Jkcyk7XG5cbiAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIGxvd2VyIGFuZCB1cHBlciBib3VuZCBvZiB0aGUgNCB2YWx1ZXMgdGhhdCB3aWxsIGJlIHBhY2tlZCBpbnRvIG9uZSB0ZXhlbC5cbiAgICAgICAgICAgICAgICBpdmVjNCB4MDAgPSBpdmVjNChtYXgoc291cmNlRnJhYy54eSwgdmVjMigwLjApKSwgbWluKGlucHV0V0ggLSAxLjAsIGNlaWwoc291cmNlRnJhYy54eSkpKTtcbiAgICAgICAgICAgICAgICBpdmVjNCB4MDEgPSBpdmVjNChtYXgoc291cmNlRnJhYy54dywgdmVjMigwLjApKSwgbWluKGlucHV0V0ggLSAxLjAsIGNlaWwoc291cmNlRnJhYy54dykpKTtcbiAgICAgICAgICAgICAgICBpdmVjNCB4MTAgPSBpdmVjNChtYXgoc291cmNlRnJhYy56eSwgdmVjMigwLjApKSwgbWluKGlucHV0V0ggLSAxLjAsIGNlaWwoc291cmNlRnJhYy56eSkpKTtcbiAgICAgICAgICAgICAgICBpdmVjNCB4MTEgPSBpdmVjNChtYXgoc291cmNlRnJhYy56dywgdmVjMigwLjApKSwgbWluKGlucHV0V0ggLSAxLjAsIGNlaWwoc291cmNlRnJhYy56dykpKTtcblxuICAgICAgICAgICAgICAgIGJvb2wgaGFzTmV4dFJvdyA9IHJjLncgPCAke291dHB1dEhlaWdodCAtIDF9O1xuICAgICAgICAgICAgICAgIGJvb2wgaGFzTmV4dENvbCA9IHJjLnogPCAke291dHB1dFdpZHRoIC0gMX07XG5cbiAgICAgICAgICAgICAgICAvLyBwYWNrIHgwMCwgeDAxLCB4MTAsIHgxMSdzIHRvcC1sZWZ0IGNvcm5lciBpbnRvIG9uZSB2ZWM0IHN0cnVjdHVyZVxuICAgICAgICAgICAgICAgIHZlYzQgdG9wTGVmdCA9IHZlYzQoXG4gICAgICAgICAgICAgICAgICAgIGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMC54LCB4MDAueSksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDEueCwgeDAxLnkpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDEwLngsIHgxMC55KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTEueCwgeDExLnkpIDogMC4wKTtcblxuICAgICAgICAgICAgICAgIC8vIHBhY2sgeDAwLCB4MDEsIHgxMCwgeDExJ3MgdG9wLXJpZ2h0IGNvcm5lciBpbnRvIG9uZSB2ZWM0IHN0cnVjdHVyZVxuICAgICAgICAgICAgICAgIHZlYzQgdG9wUmlnaHQgPSB2ZWM0KFxuICAgICAgICAgICAgICAgICAgICBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDAueCwgeDAwLncpLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Q29sID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAxLngsIHgwMS53KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dFJvdyA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMC54LCB4MTAudykgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIChoYXNOZXh0Um93ICYmIGhhc05leHRDb2wpID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDExLngsIHgxMS53KSA6IDAuMCk7XG5cbiAgICAgICAgICAgICAgICAvLyBwYWNrIHgwMCwgeDAxLCB4MTAsIHgxMSdzIGJvdHRvbS1sZWZ0IGNvcm5lciBpbnRvIG9uZSB2ZWM0IHN0cnVjdHVyZVxuICAgICAgICAgICAgICAgIHZlYzQgYm90dG9tTGVmdCA9IHZlYzQoXG4gICAgICAgICAgICAgICAgICAgIGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMC56LCB4MDAueSksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDEueiwgeDAxLnkpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDEwLnosIHgxMC55KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTEueiwgeDExLnkpIDogMC4wKTtcblxuICAgICAgICAgICAgICAgIC8vIHBhY2sgeDAwLCB4MDEsIHgxMCwgeDExJ3MgYm90dG9tLXJpZ2h0IGNvcm5lciBpbnRvIG9uZSB2ZWM0IHN0cnVjdHVyZVxuICAgICAgICAgICAgICAgIHZlYzQgYm90dG9tUmlnaHQgPSB2ZWM0KFxuICAgICAgICAgICAgICAgICAgICBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDAueiwgeDAwLncpLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Q29sID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAxLnosIHgwMS53KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dFJvdyA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMC56LCB4MTAudykgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIChoYXNOZXh0Um93ICYmIGhhc05leHRDb2wpID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDExLnosIHgxMS53KSA6IDAuMCk7XG5cbiAgICAgICAgICAgICAgICAvLyBjYWxjdWxhdGUgdGhlIGludGVycG9sYXRpb24gZnJhY3Rpb24gb24gdSBhbmQgdiBkaXJlY3Rpb25cbiAgICAgICAgICAgICAgICB2ZWM0IGZyYWMgPSB2ZWM0KHNvdXJjZUZyYWMpIC0gZmxvb3Ioc291cmNlRnJhYyk7XG4gICAgICAgICAgICAgICAgdmVjNCBjbGFtcEZyYWMgPSBjbGFtcChmcmFjLCB2ZWM0KDAuMCksIHZlYzQoMS4wKSk7XG5cbiAgICAgICAgICAgICAgICB2ZWM0IHRvcCA9IG1peCh0b3BMZWZ0LCB0b3BSaWdodCwgY2xhbXBGcmFjLnl3eXcpO1xuICAgICAgICAgICAgICAgIHZlYzQgYm90dG9tID0gbWl4KGJvdHRvbUxlZnQsIGJvdHRvbVJpZ2h0LCBjbGFtcEZyYWMueXd5dyk7XG4gICAgICAgICAgICAgICAgdmVjNCBuZXdWYWx1ZSA9IG1peCh0b3AsIGJvdHRvbSwgY2xhbXBGcmFjLnh4enopO1xuXG4gICAgICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KG5ld1ZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5yZXNpemVQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZCB9LFxuICAgIGhhc01haW46IHRydWUsXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgcHJlcGFyZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBVcHNhbXBsZUF0dHJpYnV0ZXMpOiBbcmVhZG9ubHkgbnVtYmVyW10sIHJlYWRvbmx5IG51bWJlcltdXSA9PiB7XG4gIGNvbnN0IHggPSBpbnB1dHNbMF07XG4gIGNvbnN0IHhEaW1zID0geC5kaW1zO1xuXG4gIGxldCBzY2FsZXMgPSBhdHRyaWJ1dGVzLnNjYWxlcztcbiAgbGV0IG91dHB1dFNpemVzOiBudW1iZXJbXSB8IHVuZGVmaW5lZDtcbiAgaWYgKHNjYWxlcy5sZW5ndGggPT09IDApIHtcbiAgICBjb25zdCBzY2FsZXNUZW5zb3IgPSBpbnB1dHNbYXR0cmlidXRlcy5zY2FsZXNJbnB1dElkeF07XG4gICAgaWYgKHNjYWxlc1RlbnNvciAmJiBzY2FsZXNUZW5zb3Iuc2l6ZSAhPT0gMCkge1xuICAgICAgaWYgKGlucHV0c1thdHRyaWJ1dGVzLnNpemVzSW5wdXRJZHhdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgb2Ygc2NhbGVzIG9yIHNpemVzIG11c3QgYmUgcHJvdmlkZWQgYXMgaW5wdXQuJyk7XG4gICAgICB9XG4gICAgICBzY2FsZXMgPSBwYXJzZVNjYWxlc0RhdGEoc2NhbGVzVGVuc29yLCBhdHRyaWJ1dGVzLm1vZGUsIGF0dHJpYnV0ZXMuaXNSZXNpemUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzaXplc1RlbnNvciA9IGlucHV0c1thdHRyaWJ1dGVzLnNpemVzSW5wdXRJZHhdO1xuICAgICAgaWYgKCFzaXplc1RlbnNvciB8fCBzaXplc1RlbnNvci5zaXplID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRWl0aGVyIHNjYWxlcyBvciBzaXplcyBNVVNUIGJlIHByb3ZpZGVkIGFzIGlucHV0LicpO1xuICAgICAgfVxuXG4gICAgICBvdXRwdXRTaXplcyA9IEFycmF5LmZyb20oc2l6ZXNUZW5zb3IuaW50ZWdlckRhdGEpO1xuICAgICAgc2NhbGVzID0gcGFyc2VTY2FsZXNEYXRhRnJvbU91dHB1dFNpemUob3V0cHV0U2l6ZXMsIHhEaW1zLCBhdHRyaWJ1dGVzLm1vZGUsIGF0dHJpYnV0ZXMuaXNSZXNpemUpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoaW5wdXRzW2F0dHJpYnV0ZXMuc2l6ZXNJbnB1dElkeF0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgb2Ygc2NhbGVzIG9yIHNpemVzIG11c3QgYmUgcHJvdmlkZWQgYXMgaW5wdXQuJyk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgeURpbXMgPSBvdXRwdXRTaXplcyB8fCB4RGltcy5tYXAoKGRpbSwgaSkgPT4gTWF0aC5mbG9vcihkaW0gKiBzY2FsZXNbaV0pKTtcblxuICByZXR1cm4gW3NjYWxlcywgeURpbXNdO1xufTtcblxuY29uc3QgcGFyc2VTY2FsZXNEYXRhID0gKHNjYWxlOiBUZW5zb3IsIG1vZGU6IHN0cmluZywgaXNSZXNpemU6IGJvb2xlYW4pOiBudW1iZXJbXSA9PiB7XG4gIGNvbnN0IHNjYWxlcyA9IEFycmF5LmZyb20oc2NhbGUuZmxvYXREYXRhKTtcbiAgc2NhbGVzVmFsaWRhdGlvbihzY2FsZXMsIG1vZGUsIGlzUmVzaXplKTtcbiAgcmV0dXJuIHNjYWxlcztcbn07XG5cbmNvbnN0IHBhcnNlU2NhbGVzRGF0YUZyb21PdXRwdXRTaXplID0gKFxuICB5RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHhEaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgbW9kZTogc3RyaW5nLFxuICBpc1Jlc2l6ZTogYm9vbGVhbixcbik6IG51bWJlcltdID0+IHtcbiAgY29uc3QgbGVuZ3RoID0geERpbXMubGVuZ3RoO1xuICBjb25zdCBzY2FsZXMgPSBuZXcgQXJyYXk8bnVtYmVyPihsZW5ndGgpO1xuXG4gIGZvciAobGV0IGkgPSAwLCBlbmQgPSBsZW5ndGg7IGkgPCBlbmQ7IGkrKykge1xuICAgIGlmICh4RGltc1tpXSA9PT0gMCkge1xuICAgICAgaWYgKHlEaW1zW2ldICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgZGltIGlzIHplcm8gYnV0IHJlcXVpcmVkIG91dHB1dCBkaW0gaXMgbm9uLXplcm8uJyk7XG4gICAgICB9XG4gICAgICBzY2FsZXNbaV0gPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZXNbaV0gPSB5RGltc1tpXSAvIHhEaW1zW2ldO1xuICAgIH1cbiAgfVxuICBzY2FsZXNWYWxpZGF0aW9uKHNjYWxlcywgbW9kZSwgaXNSZXNpemUpO1xuICByZXR1cm4gc2NhbGVzO1xufTtcblxuLy8gcm9pIGRhdGEgaXMgbm90IHVzZWQgeWV0LiBidXQgbGVhdmUgaGVyZSBmb3IgZnV0dXJlIHVzYWdlLlxuLy8gY29uc3QgZ2V0Um9pID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcykgOiBudW1iZXJbXSA9PiB7XG4vLyAgICAgbGV0IHJvaTogbnVtYmVyW10gPSBbXTtcbi8vICAgICBpZiAoYXR0cmlidXRlcy5uZWVkUm9pSW5wdXQpIHtcbi8vICAgICAgICAgaWYgKGF0dHJpYnV0ZXMucm9pSW5wdXRJZHggPD0gMCkge1xuLy8gICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHJvaSBpbnB1dCBpbmRleC4nKTtcbi8vICAgICAgICAgfVxuLy8gICAgICAgICBjb25zdCByb2lUZW5zb3IgPSBpbnB1dHNbYXR0cmlidXRlcy5yb2lJbnB1dElkeF07XG4vLyAgICAgICAgIHJvaSA9IHJvaVRlbnNvci5zaXplID4gMCA/IEFycmF5LmZyb20ocm9pVGVuc29yLmZsb2F0RGF0YSkgOiBbXTtcbi8vICAgICB9IGVsc2Uge1xuLy8gICAgICAgICByb2kgPSBuZXcgQXJyYXkoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICogMikuZmlsbCgwKTtcbi8vICAgICB9XG4vLyAgICAgcmV0dXJuIHJvaTtcbi8vIH07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCBzaGFwZSA9IChfaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICByZXR1cm4gW25ldyBUZW5zb3IoW2lucHV0c1swXS5kaW1zLmxlbmd0aF0sICdpbnQzMicsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBuZXcgSW50MzJBcnJheShpbnB1dHNbMF0uZGltcykpXTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBOVU1CRVJfVFlQRVMsIE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNsaWNlQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF4ZXM6IG51bWJlcltdO1xuICByZWFkb25seSBlbmRzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgc3RhcnRzOiBudW1iZXJbXTtcbn1cblxuY29uc3Qgc2xpY2VQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdTbGljZScsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHNsaWNlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFNsaWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogU2xpY2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7XG4gICAgICAuLi5zbGljZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlU2xpY2VQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGF0dHJpYnV0ZXMpLFxuICAgIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTbGljZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248U2xpY2VBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogU2xpY2VBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3Qgc3RhcnRzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3N0YXJ0cycpO1xuICBjb25zdCBlbmRzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2VuZHMnKTtcbiAgY29uc3QgYXhlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdheGVzJywgW10pO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgc3RhcnRzLCBlbmRzLCBheGVzIH0pO1xufTtcblxuY29uc3QgY3JlYXRlU2xpY2VQcm9ncmFtSW5mbyA9IChcbiAgX2luZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgYXR0cmlidXRlczogU2xpY2VBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBheGVzID0gYXR0cmlidXRlcy5heGVzLmxlbmd0aCA9PT0gMCA/IGlucHV0LmRpbXMuc2xpY2UoMCkubWFwKChfdmFsLCBpKSA9PiBpKSA6IGF0dHJpYnV0ZXMuYXhlcztcbiAgY29uc3Qgbm9ybWFsaXplZEF4ZXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhlcyhheGVzLCBpbnB1dC5kaW1zLmxlbmd0aCk7XG4gIGNvbnN0IHN0YXJ0cyA9IGF0dHJpYnV0ZXMuc3RhcnRzLm1hcCgoc3RhcnQsIGkpID0+IHtcbiAgICBpZiAoc3RhcnQgPiBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXSAtIDEpIHtcbiAgICAgIHJldHVybiBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXTtcbiAgICB9XG4gICAgcmV0dXJuIFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKHN0YXJ0LCBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXSk7XG4gIH0pO1xuICBjb25zdCBlbmRzID0gYXR0cmlidXRlcy5lbmRzLm1hcCgoZW5kLCBpKSA9PiB7XG4gICAgaWYgKGVuZCA+IGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dIC0gMSkge1xuICAgICAgcmV0dXJuIGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dO1xuICAgIH1cbiAgICByZXR1cm4gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoZW5kLCBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXSk7XG4gIH0pO1xuXG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXQuZGltcy5zbGljZSgpO1xuXG4gIGNvbnN0IHNsaWNlT3BzOiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG5vcm1hbGl6ZWRBeGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgb3V0cHV0U2hhcGVbbm9ybWFsaXplZEF4ZXNbaV1dID0gZW5kc1tpXSAtIHN0YXJ0c1tpXTtcbiAgICBpZiAoc3RhcnRzW2ldID4gMCkge1xuICAgICAgc2xpY2VPcHMucHVzaChgb3V0cHV0SWR4WyR7bm9ybWFsaXplZEF4ZXNbaV19XSArPSAke3N0YXJ0c1tpXX07YCk7XG4gICAgfSAvLyBlbHNlIHsgc2xpY2VPcHMucHVzaChgb3V0cHV0SWR4WyR7bm9ybWFsaXplZEF4ZXNbaV19XSArPSAwO2ApOyB9XG4gIH1cblxuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBvdXRwdXRJZHhbJHtyYW5rfV0pIHtcbiAgICAgICAgJHtzbGljZU9wcy5qb2luKCdcXG4gICAgICAnKX1cbiAgICAgICAgcmV0dXJuIF9BKG91dHB1dElkeCk7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5zbGljZVByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2xpY2UgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuICBpZiAoTlVNQkVSX1RZUEVTLmluZGV4T2YoaW5wdXRzWzBdLnR5cGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2xpY2VWMTAgPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0c1YxMChpbnB1dHMpO1xuICBjb25zdCBhdHRyaWJ1dGVzID0gZ2VuZXJhdGVTbGljZUF0dHJpYnV0ZXNGcm9tSW5wdXRzKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLnNsaWNlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVTbGljZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcyksXG4gICAgfSxcbiAgICBbaW5wdXRzWzBdXSxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgZ2VuZXJhdGVTbGljZUF0dHJpYnV0ZXNGcm9tSW5wdXRzID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4pOiBTbGljZUF0dHJpYnV0ZXMgPT4ge1xuICBpZiAoXG4gICAgIWluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1sxXS5kYXRhSWQpIHx8XG4gICAgIWluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1syXS5kYXRhSWQpIHx8XG4gICAgKGlucHV0cy5sZW5ndGggPj0gNCAmJiAhaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzNdLmRhdGFJZCkpIHx8XG4gICAgKGlucHV0cy5sZW5ndGggPj0gNSAmJiAhaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzRdLmRhdGFJZCkpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignZHluYW1pYyBzbGljZSBhdHRyaWJ1dGVzIGFyZSBub3QgYWxsb3dlZCcpO1xuICB9XG5cbiAgaWYgKGlucHV0cy5sZW5ndGggPj0gNSAmJiBpbnB1dHNbNF0uaW50ZWdlckRhdGEuc29tZSgoaTogbnVtYmVyKSA9PiBpICE9PSAxKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignY3VycmVudGx5IG5vbi0xIHN0ZXBzIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIFNsaWNlJyk7XG4gIH1cblxuICBjb25zdCBzdGFydHMgPSBBcnJheS5mcm9tKGlucHV0c1sxXS5pbnRlZ2VyRGF0YSk7XG4gIGNvbnN0IGVuZHMgPSBBcnJheS5mcm9tKGlucHV0c1syXS5pbnRlZ2VyRGF0YSk7XG4gIGNvbnN0IGF4ZXMgPSBpbnB1dHMubGVuZ3RoID49IDQgPyBBcnJheS5mcm9tKGlucHV0c1szXS5pbnRlZ2VyRGF0YSkgOiBbXTtcbiAgY29uc3QgY2FjaGVLZXkgPSBgJHtheGVzfTske3N0YXJ0c307JHtlbmRzfWA7XG4gIHJldHVybiB7IHN0YXJ0cywgZW5kcywgYXhlcywgY2FjaGVLZXkgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzVjEwID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCA8IDMgfHwgaW5wdXRzLmxlbmd0aCA+IDUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgbnVtYmVyLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJyB8fCBpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzJdLnR5cGUgIT09ICdpbnQzMicgfHwgaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0cy5sZW5ndGggPj0gNCAmJiAoaW5wdXRzWzNdLnR5cGUgIT09ICdpbnQzMicgfHwgaW5wdXRzWzNdLmRpbXMubGVuZ3RoICE9PSAxKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHMubGVuZ3RoID49IDUgJiYgKGlucHV0c1s0XS50eXBlICE9PSAnaW50MzInIHx8IGlucHV0c1s0XS5kaW1zLmxlbmd0aCAhPT0gMSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IHRyYW5zcG9zZSwgVHJhbnNwb3NlQXR0cmlidXRlcyB9IGZyb20gJy4vdHJhbnNwb3NlJztcblxuZXhwb3J0IGludGVyZmFjZSBTb2Z0bWF4QXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF4aXM6IG51bWJlcjtcbn1cblxuY29uc3Qgc29mdG1heENvbXB1dGVNYXhQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdTb2Z0bWF4Q29tcHV0ZU1heCcsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3Qgc29mdG1heENvbXB1dGVTY2FsZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1NvZnRtYXhDb21wdXRlU2NhbGUnLFxuICBpbnB1dE5hbWVzOiBbJ0EnLCAnTWF4J10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3Qgc29mdG1heFByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1NvZnRNYXgnLFxuICBpbnB1dE5hbWVzOiBbJ0EnLCAnTWF4JywgJ05vcm0nXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHNvZnRtYXg6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248U29mdG1heEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFNvZnRtYXhBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXR0cmlidXRlcy5heGlzLCBpbnB1dFNoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IGxvZ2ljYWxSb3dDb3VudCA9IFNoYXBlVXRpbC5zaXplVG9EaW1lbnNpb24oaW5wdXRTaGFwZSwgYXhpcyk7XG4gIGNvbnN0IGZlYXR1cmVDb3VudCA9IFNoYXBlVXRpbC5zaXplRnJvbURpbWVuc2lvbihpbnB1dFNoYXBlLCBheGlzKTtcblxuICBjb25zdCBvdXRwdXQgPSBjb21wdXRlU29mdG1heChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsIGxvZ2ljYWxSb3dDb3VudCwgZmVhdHVyZUNvdW50KTtcbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFNvZnRtYXhBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IFNvZnRtYXhBdHRyaWJ1dGVzID0+IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGF4aXM6IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnLCAxKSB9KTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlU29mdG1heEF0dHJpYnV0ZXNWMTM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248U29mdG1heEF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogU29mdG1heEF0dHJpYnV0ZXMgPT4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpczogbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIC0xKSB9KTtcblxuLy8gVGhlIFwic2VtYW50aWNcIiBtZWFuaW5nIG9mIGF4aXMgaGFzIGNoYW5nZWQgaW4gb3BzZXQtMTMuXG4vLyBQbGVhc2UgY29tcGFyZTogaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9PcGVyYXRvcnMubWQjU29mdG1heFxuLy8gd2l0aCBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L2Jsb2IvbWFpbi9kb2NzL0NoYW5nZWxvZy5tZCNTb2Z0bWF4LTExIGZvciBkZXRhaWxlZCBleHBsYW5hdGlvbnNcbi8vIFRvIGFjY291bnQgZm9yIHRoZSBvcHNldC0xMyBiZWhhdmlvciwgb3VyIHBsYW4gd2lsbCBiZSB0byB0cmFuc3Bvc2UgdGhlIFwiYXhpc1wiIGRpbSB0byB0aGUgaW5uZXJtb3N0IGRpbVxuLy8gYW5kIHBlcmZvcm0gc29mdG1heCBhbmQgdGhlbiByZXZlcnNlIHRoZSB0cmFuc3Bvc2UuIFdlIGNhbiBza2lwIHRoZSB0cmFuc3Bvc2luZyBhc3BlY3QgaWYgdGhlIGF4aXMgaXMgYWxyZWFkeVxuLy8gdGhlIGlubmVybW9zdCBkaW1cbmV4cG9ydCBjb25zdCBzb2Z0bWF4VjEzOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFNvZnRtYXhBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBTb2Z0bWF4QXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMuYXhpcywgaW5wdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCByYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3QgaXNUcmFuc3Bvc2VSZXF1aXJlZCA9IGF4aXMgIT09IHJhbmsgLSAxID8gdHJ1ZSA6IGZhbHNlO1xuICBjb25zdCB0cmFuc3Bvc2VkSW5wdXRTaGFwZTogbnVtYmVyW10gPSBbXTtcbiAgbGV0IHBlcm06IG51bWJlcltdID0gW107XG4gIGxldCB0cmFuc3Bvc2VkSW5wdXRzOiBUZW5zb3JbXSA9IFtdO1xuICBsZXQgdHJhbnNwb3NlQXR0cmlidXRlOiBUcmFuc3Bvc2VBdHRyaWJ1dGVzO1xuXG4gIGlmIChpc1RyYW5zcG9zZVJlcXVpcmVkKSB7XG4gICAgcGVybSA9IEFycmF5LmZyb20oeyBsZW5ndGg6IHJhbmsgfSkubWFwKChfLCBpKSA9PiBpKTtcblxuICAgIC8vIHN3YXAgdGhlIGlubmVybW9zdCBkaW0gd2l0aCB0aGUgZGltIGNvcnJlc3BvbmRpbmcgdG8gYXhpc1xuICAgIHBlcm1bYXhpc10gPSByYW5rIC0gMTtcbiAgICBwZXJtW3JhbmsgLSAxXSA9IGF4aXM7XG5cbiAgICBwZXJtLm1hcCgocCkgPT4gdHJhbnNwb3NlZElucHV0U2hhcGUucHVzaChpbnB1dFNoYXBlW3BdKSk7XG5cbiAgICB0cmFuc3Bvc2VBdHRyaWJ1dGUgPSBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBwZXJtIH0pO1xuICAgIHRyYW5zcG9zZWRJbnB1dHMgPSB0cmFuc3Bvc2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCB0cmFuc3Bvc2VBdHRyaWJ1dGUpO1xuICB9XG5cbiAgY29uc3QgbG9naWNhbFJvd0NvdW50ID0gaXNUcmFuc3Bvc2VSZXF1aXJlZFxuICAgID8gU2hhcGVVdGlsLnNpemVUb0RpbWVuc2lvbih0cmFuc3Bvc2VkSW5wdXRTaGFwZSwgcmFuayAtIDEpXG4gICAgOiBTaGFwZVV0aWwuc2l6ZVRvRGltZW5zaW9uKGlucHV0U2hhcGUsIHJhbmsgLSAxKTtcbiAgY29uc3QgZmVhdHVyZUNvdW50ID0gaXNUcmFuc3Bvc2VSZXF1aXJlZFxuICAgID8gU2hhcGVVdGlsLnNpemVGcm9tRGltZW5zaW9uKHRyYW5zcG9zZWRJbnB1dFNoYXBlLCByYW5rIC0gMSlcbiAgICA6IFNoYXBlVXRpbC5zaXplRnJvbURpbWVuc2lvbihpbnB1dFNoYXBlLCByYW5rIC0gMSk7XG5cbiAgY29uc3Qgb3V0cHV0ID0gY29tcHV0ZVNvZnRtYXgoXG4gICAgaW5mZXJlbmNlSGFuZGxlcixcbiAgICBpc1RyYW5zcG9zZVJlcXVpcmVkID8gdHJhbnNwb3NlZElucHV0cyA6IGlucHV0cyxcbiAgICBhdHRyaWJ1dGVzLFxuICAgIGxvZ2ljYWxSb3dDb3VudCxcbiAgICBmZWF0dXJlQ291bnQsXG4gICk7XG5cbiAgaWYgKGlzVHJhbnNwb3NlUmVxdWlyZWQpIHtcbiAgICBjb25zdCByZXZlcnNlZE91dHB1dCA9IHRyYW5zcG9zZShpbmZlcmVuY2VIYW5kbGVyLCBvdXRwdXQsIHRyYW5zcG9zZUF0dHJpYnV0ZSEpO1xuICAgIHJldHVybiByZXZlcnNlZE91dHB1dDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG59O1xuXG5jb25zdCBjb21wdXRlU29mdG1heCA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBTb2Z0bWF4QXR0cmlidXRlcyxcbiAgbG9naWNhbFJvd0NvdW50OiBudW1iZXIsXG4gIGZlYXR1cmVDb3VudDogbnVtYmVyLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCBjb21wdXRlTWF4UHJvZ3JhbUluZm8gPSBjcmVhdGVDb21wdXRlTWF4UHJvZ3JhbUluZm8oXG4gICAgaW5mZXJlbmNlSGFuZGxlcixcbiAgICBpbnB1dHNbMF0sXG4gICAgbG9naWNhbFJvd0NvdW50LFxuICAgIGZlYXR1cmVDb3VudCxcbiAgICBbbG9naWNhbFJvd0NvdW50XSxcbiAgKTtcbiAgY29uc3QgbWF4ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5zb2Z0bWF4Q29tcHV0ZU1heFByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LCBnZXQ6ICgpID0+IGNvbXB1dGVNYXhQcm9ncmFtSW5mbyB9LFxuICAgIGlucHV0cyxcbiAgKTtcblxuICBjb25zdCBjb21wdXRlU2NhbGVQcm9ncmFtSW5mbyA9IGNyZWF0ZUNvbXB1dFNjYWxlUHJvZ3JhbUluZm8oXG4gICAgaW5mZXJlbmNlSGFuZGxlcixcbiAgICBpbnB1dHNbMF0sXG4gICAgbG9naWNhbFJvd0NvdW50LFxuICAgIGZlYXR1cmVDb3VudCxcbiAgICBjb21wdXRlTWF4UHJvZ3JhbUluZm8ub3V0cHV0LmRpbXMsXG4gICAgW2xvZ2ljYWxSb3dDb3VudF0sXG4gICk7XG4gIGNvbnN0IHNjYWxlID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5zb2Z0bWF4Q29tcHV0ZVNjYWxlUHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGdldDogKCkgPT4gY29tcHV0ZVNjYWxlUHJvZ3JhbUluZm8gfSxcbiAgICBbaW5wdXRzWzBdLCBtYXhdLFxuICApO1xuXG4gIGNvbnN0IHNvZnRNYXhQcm9ncmFtSW5mbyA9IGNyZWF0ZVNvZnRNYXhQcm9ncmFtSW5mbyhcbiAgICBpbmZlcmVuY2VIYW5kbGVyLFxuICAgIGlucHV0c1swXSxcbiAgICBsb2dpY2FsUm93Q291bnQsXG4gICAgZmVhdHVyZUNvdW50LFxuICAgIGNvbXB1dGVNYXhQcm9ncmFtSW5mby5vdXRwdXQuZGltcyxcbiAgICBjb21wdXRlU2NhbGVQcm9ncmFtSW5mby5vdXRwdXQuZGltcyxcbiAgKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5zb2Z0bWF4UHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGdldDogKCkgPT4gc29mdE1heFByb2dyYW1JbmZvIH0sXG4gICAgW2lucHV0c1swXSwgbWF4LCBzY2FsZV0sXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgdGV4dHVyZSB0aGF0IGNvbnRhaW5zIHRoZSBtYXhpbXVtIHZhbHVlIG9mIGVhY2ggb2YgdGhlICdOJyByb3dzXG4gKi9cbmNvbnN0IGNyZWF0ZUNvbXB1dGVNYXhQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBsb2dpY2FsUm93Q291bnQ6IG51bWJlcixcbiAgZmVhdHVyZUNvdW50OiBudW1iZXIsXG4gIG91dHB1dFNoYXBlOiBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgW3RleHR1cmVXaWR0aCwgdGV4dHVyZUhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBpbnB1dC5kaW1zLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICApO1xuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuXG4gIGlmIChsb2dpY2FsUm93Q291bnQgPCAxIHx8IGZlYXR1cmVDb3VudCA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvZ2ljYWwgcm93IGNvdW50IE4gYW5kIGZlYXR1cmUgY291bnQgRCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gIH1cblxuICBpZiAob3V0cHV0U2hhcGUubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdEaW1lbnNpb25hbGl0eSBvZiB0aGUgb3V0cHV0IHNob3VsZCBiZSAxJyk7XG4gIH1cblxuICBpZiAob3V0cHV0U2hhcGVbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgb2YgdGhlIG91dHB1dCBzaG91bGQgYmUgZXF1YWwgdG8gbG9naWNhbCByb3cgY291bnQnKTtcbiAgfVxuXG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuICAgICAgICBpbnQgbG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0ID0gaW5kaWNlc1swXSAqICR7ZmVhdHVyZUNvdW50fTtcblxuICAgICAgICBmbG9hdCBtYXggPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgb2Zmc2V0VG9Db29yZHMobG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0LCAke3RleHR1cmVXaWR0aH0sXG4gICAgICAgICR7dGV4dHVyZUhlaWdodH0gKSkpO1xuICAgICAgICBmb3IoaW50IGk9MTsgaTwke2ZlYXR1cmVDb3VudH07ICsraSlcbiAgICAgICAge1xuICAgICAgICAgIGZsb2F0IGN1cnJlbnQgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgb2Zmc2V0VG9Db29yZHMobG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0ICsgaSxcbiAgICAgICAgICAgICR7dGV4dHVyZVdpZHRofSwgJHt0ZXh0dXJlSGVpZ2h0fSkpKTtcbiAgICAgICAgICBpZihjdXJyZW50ID4gbWF4KVxuICAgICAgICAgIG1heCA9IGN1cnJlbnQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWF4O1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4uc29mdG1heENvbXB1dGVNYXhQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIHRleHR1cmUgdGhhdCBjb250YWlucyB0aGUgbm9ybWFsaXphdGlvbiBmYWN0b3IgZm9yIGVhY2ggb2YgdGhlICdOJyByb3dzXG4gKi9cbmNvbnN0IGNyZWF0ZUNvbXB1dFNjYWxlUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgbG9naWNhbFJvd0NvdW50OiBudW1iZXIsXG4gIGZlYXR1cmVDb3VudDogbnVtYmVyLFxuICBtYXhFbGVtZW50UGVyTG9naWNhbFJvdzogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG91dHB1dFNoYXBlOiBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgW3RleHR1cmVXaWR0aCwgdGV4dHVyZUhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBpbnB1dC5kaW1zLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICApO1xuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuXG4gIGlmIChsb2dpY2FsUm93Q291bnQgPCAxIHx8IGZlYXR1cmVDb3VudCA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvZ2ljYWwgcm93IGNvdW50IE4gYW5kIGZlYXR1cmUgY291bnQgRCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gIH1cblxuICBpZiAob3V0cHV0U2hhcGUubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdEaW1lbnNpb25hbGl0eSBvZiB0aGUgb3V0cHV0IHNob3VsZCBiZSAxJyk7XG4gIH1cblxuICBpZiAob3V0cHV0U2hhcGVbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgb2YgdGhlIG91dHB1dCBzaG91bGQgYmUgZXF1YWwgdG8gbG9naWNhbCByb3cgY291bnQnKTtcbiAgfVxuXG4gIGlmIChtYXhFbGVtZW50UGVyTG9naWNhbFJvdy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbWVuc2lvbmFsaXR5IG9mIHRoZSBpbnRlcm1lZGlhdGUgcmVzdWx0cyBzaG91bGQgYmUgMScpO1xuICB9XG5cbiAgaWYgKG1heEVsZW1lbnRQZXJMb2dpY2FsUm93WzBdICE9PSBsb2dpY2FsUm93Q291bnQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NoYXBlIG9mIHRoZSBpbnRlcm1lZGlhdGUgcmVzdWx0cyBzaG91bGQgYmUgZXF1YWwgdG8gbG9naWNhbCByb3cgY291bnQnKTtcbiAgfVxuXG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuICAgICAgICBpbnQgbG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0ID0gaW5kaWNlc1swXSAqICR7ZmVhdHVyZUNvdW50fTtcblxuICAgICAgICBmbG9hdCBub3JtX2ZhY3RvciA9IDAuMDtcbiAgICAgICAgZmxvYXQgbWF4ID0gX01heChpbmRpY2VzKTtcbiAgICAgICAgZm9yKGludCBpPTA7IGk8JHtmZWF0dXJlQ291bnR9OyArK2kpXG4gICAgICAgIHtcbiAgICAgICAgICBub3JtX2ZhY3RvciArPSBleHAoZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIG9mZnNldFRvQ29vcmRzKGxvZ2ljYWxfcm93X3N0YXJ0X29mZnNldCArIGksXG4gICAgICAgICAgICAke3RleHR1cmVXaWR0aH0sICR7dGV4dHVyZUhlaWdodH0pKSkgLSBtYXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vcm1fZmFjdG9yO1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4uc29mdG1heENvbXB1dGVTY2FsZVByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZVNvZnRNYXhQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBsb2dpY2FsUm93Q291bnQ6IG51bWJlcixcbiAgZmVhdHVyZUNvdW50OiBudW1iZXIsXG4gIG1heEVsZW1lbnRQZXJMb2dpY2FsUm93OiByZWFkb25seSBudW1iZXJbXSxcbiAgbm9ybWFsaXphdGlvblBlckxvZ2ljYWxSb3c6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBbdGV4dHVyZVdpZHRoLCB0ZXh0dXJlSGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGlucHV0LmRpbXMsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICk7XG4gIGNvbnN0IHJhbmsgPSBpbnB1dC5kaW1zLmxlbmd0aDtcblxuICBpZiAobG9naWNhbFJvd0NvdW50IDwgMSB8fCBmZWF0dXJlQ291bnQgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdMb2dpY2FsIHJvdyBjb3VudCBOIGFuZCBmZWF0dXJlIGNvdW50IEQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICB9XG5cbiAgaWYgKG1heEVsZW1lbnRQZXJMb2dpY2FsUm93Lmxlbmd0aCAhPT0gMSB8fCBub3JtYWxpemF0aW9uUGVyTG9naWNhbFJvdy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbWVuc2lvbmFsaXR5IG9mIHRoZSBpbnRlcm1lZGlhdGUgcmVzdWx0cyBzaG91bGQgYmUgMScpO1xuICB9XG5cbiAgaWYgKG1heEVsZW1lbnRQZXJMb2dpY2FsUm93WzBdICE9PSBsb2dpY2FsUm93Q291bnQgfHwgbm9ybWFsaXphdGlvblBlckxvZ2ljYWxSb3dbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgb2YgdGhlIGludGVybWVkaWF0ZSByZXN1bHRzIHNob3VsZCBiZSBlcXVhbCB0byBsb2dpY2FsIHJvdyBjb3VudCcpO1xuICB9XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuXG4gICAgICAvLyBnZXQgb2Zmc2V0IG9mIGN1cnJlbnQgbG9naWNhbCB0ZW5zb3IgaW5kZXggZnJvbSB0aGUgMi1EIHRleHR1cmUgY29vcmRpbmF0ZXMgKFRleENvb3JkcylcbiAgICAgIGludCBvZmZzZXQgPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7dGV4dHVyZVdpZHRofSwgJHt0ZXh0dXJlSGVpZ2h0fSk7XG5cbiAgICAgIC8vZGV0ZXJtaW5lIHRoZSBsb2dpY2FsIHJvdyBmb3IgdGhpcyBpbmRleFxuICAgICAgaW50IGxvZ2ljYWxfcm93X2luZGV4WzFdO1xuICAgICAgbG9naWNhbF9yb3dfaW5kZXhbMF0gPSBvZmZzZXQgLyAke2ZlYXR1cmVDb3VudH07XG5cbiAgICAgIGZsb2F0IG5vcm1fZmFjdG9yID0gX05vcm0obG9naWNhbF9yb3dfaW5kZXgpO1xuXG4gICAgICAvLyBhdm9pZCBwb3NzaWJsZSBkaXZpc2lvbiBieSAwXG4gICAgICAvLyBpZiBub3JtX2ZhY29yIGlzIDAsIGFsbCBlbGVtZW50cyBhcmUgemVyb1xuICAgICAgLy8gaWYgc28sIHJldHVybiAwXG4gICAgICBpZihub3JtX2ZhY3RvciA9PSAwLjApXG4gICAgICAgIHJldHVybiAwLjA7XG5cbiAgICAgIHJldHVybiBleHAoX0EoaW5kaWNlcykgLSBfTWF4KGxvZ2ljYWxfcm93X2luZGV4KSkgLyBub3JtX2ZhY3RvcjtcbiAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5zb2Z0bWF4UHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dC5kaW1zLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvZnRtYXggcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZScpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCwgU3BsaXRVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3BsaXRBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhpczogbnVtYmVyO1xuICByZWFkb25seSBzcGxpdDogbnVtYmVyW107XG4gIHJlYWRvbmx5IG51bU91dHB1dHM6IG51bWJlcjtcbn1cblxuY29uc3Qgc3BsaXRQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdTcGxpdCcsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHNwbGl0OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFNwbGl0QXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogU3BsaXRBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0c1swXS5kaW1zLmxlbmd0aCk7XG4gIGNvbnN0IGNvdW50ID0gZ2V0UHJvZ3JhbUNvdW50KGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXhpcywgYXR0cmlidXRlcyk7XG4gIGNvbnN0IG91dHB1dDogVGVuc29yW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7XG4gICAgb3V0cHV0LnB1c2goXG4gICAgICBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAge1xuICAgICAgICAgIC4uLnNwbGl0UHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgICAgIGNhY2hlSGludDogYCR7YXR0cmlidXRlcy5jYWNoZUtleX07JHtpfWAsXG4gICAgICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVTcGxpdFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcywgYXhpcywgaSksXG4gICAgICAgIH0sXG4gICAgICAgIGlucHV0cyxcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTcGxpdEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248U3BsaXRBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogU3BsaXRBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXhpcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnLCAwKTtcbiAgY29uc3Qgc3BsaXQgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnc3BsaXQnLCBbXSk7XG4gIGNvbnN0IG51bU91dHB1dHMgPSBub2RlLm91dHB1dHMubGVuZ3RoO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpcywgc3BsaXQsIG51bU91dHB1dHMgfSk7XG59O1xuXG5jb25zdCBnZXRQcm9ncmFtQ291bnQgPSAoXG4gIF9pbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF4aXM6IG51bWJlcixcbiAgYXR0cmlidXRlczogU3BsaXRBdHRyaWJ1dGVzLFxuKTogbnVtYmVyID0+IHtcbiAgY29uc3QgWywgb2Zmc2V0c10gPSBTcGxpdFV0aWwuc3BsaXRTaGFwZShpbnB1dHNbMF0uZGltcywgYXhpcywgYXR0cmlidXRlcy5zcGxpdCwgYXR0cmlidXRlcy5udW1PdXRwdXRzKTtcbiAgcmV0dXJuIG9mZnNldHMubGVuZ3RoO1xufTtcblxuY29uc3QgY3JlYXRlU3BsaXRQcm9ncmFtSW5mbyA9IChcbiAgX2luZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgYXR0cmlidXRlczogU3BsaXRBdHRyaWJ1dGVzLFxuICBheGlzOiBudW1iZXIsXG4gIGluZGV4OiBudW1iZXIsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IFtzaGFwZXMsIG9mZnNldHNdID0gU3BsaXRVdGlsLnNwbGl0U2hhcGUoaW5wdXQuZGltcywgYXhpcywgYXR0cmlidXRlcy5zcGxpdCwgYXR0cmlidXRlcy5udW1PdXRwdXRzKTtcbiAgY29uc3Qgb2Zmc2V0ID0gb2Zmc2V0c1tpbmRleF07XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gc2hhcGVzW2luZGV4XTtcbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICBpbmRpY2VzWyR7YXhpc31dICs9ICR7b2Zmc2V0fTtcbiAgICAgICAgcmV0dXJuIF9BKGluZGljZXMpO1xuICAgICAgfVxuICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4uc3BsaXRQcm9ncmFtTWV0YWRhdGEsXG4gICAgY2FjaGVIaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fToke2luZGV4fWAsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NwbGl0IHJlcXVpcmVzIG9uZSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ2ludDgnICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICd1aW50OCcgJiZcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ2ludDE2JyAmJlxuICAgIGlucHV0c1swXS50eXBlICE9PSAndWludDE2JyAmJlxuICAgIGlucHV0c1swXS50eXBlICE9PSAnaW50MzInICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICd1aW50MzInICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJlxuICAgIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcgJiZcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ2Jvb2wnXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3Qgc3F1ZWV6ZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxudW1iZXJbXT4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXhlczogbnVtYmVyW10sXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gU2hhcGVVdGlsLnNxdWVlemVTaGFwZShpbnB1dHNbMF0uZGltcywgYXhlcyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1swXSwgb3V0cHV0U2hhcGUpO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3Qgc3F1ZWV6ZVYxMyA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzVjEzKGlucHV0cyk7XG4gIHJldHVybiBzcXVlZXplKGluZmVyZW5jZUhhbmRsZXIsIFtpbnB1dHNbMF1dLCBBcnJheS5mcm9tKGlucHV0c1sxXS5pbnRlZ2VyRGF0YSkpO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlU3F1ZWV6ZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248bnVtYmVyW10+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBudW1iZXJbXSA9PlxuICBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnYXhlcycpO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NxdWVlemUgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQgdGVuc29yIHR5cGVzLicpO1xuICB9XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0c1YxMyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NxdWVlemUgcmVxdWlyZXMgMiBpbnB1dHMuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IHN1bSA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3Qgc3VtUHJvZ3JhbU1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdTdW0nLFxuICAgIGlucHV0TmFtZXM6IGlucHV0cy5tYXAoKF92LCBpKSA9PiBgWCR7aX1gKSxcbiAgICBpbnB1dFR5cGVzOiBuZXcgQXJyYXkoaW5wdXRzLmxlbmd0aCkuZmlsbChUZXh0dXJlVHlwZS51bnBhY2tlZCksXG4gIH07XG5cbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5zdW1Qcm9ncmFtTWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlU3VtUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBzdW1Qcm9ncmFtTWV0YWRhdGEpIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5jb25zdCBjcmVhdGVTdW1Qcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBzdW1Qcm9ncmFtTWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IHN1bUxpbmUgPSBpbnB1dHMubWFwKChfdiwgaSkgPT4gYCR7Z2xzbC50ZXh0dXJlMkR9KFgke2l9LFRleENvb3JkcylgKS5qb2luKCcgKyAnKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICB2ZWM0IHJlc3VsdCA9ICR7c3VtTGluZX07XG4gICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgfVxuICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4uc3VtUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIGhhc01haW46IHRydWUsXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTdW0gcmVxdWlyZXMgaW5wdXRzLicpO1xuICB9XG5cbiAgY29uc3QgbGVuZ3RoID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoO1xuICBmb3IgKGxldCBpID0gMTsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChsZW5ndGggIT09IGlucHV0c1tpXS5kaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBzaGFwZXMgYXJlIG1pc21hdGNoZWQuJyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBsZW5ndGg7IGorKykge1xuICAgICAgaWYgKGlucHV0c1swXS5kaW1zW2pdICE9PSBpbnB1dHNbaV0uZGltc1tqXSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHNoYXBlcyBhcmUgbm90IG1hdGNoZWQuJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGZvciAobGV0IGkgPSAxOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGlucHV0c1swXS50eXBlICE9PSBpbnB1dHNbaV0udHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCB0eXBlcyBhcmUgbm90IG1hdGNoZWQuJyk7XG4gICAgfVxuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBOVU1CRVJfVFlQRVMgfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgY29uc3QgdGlsZSA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3QgdGlsZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgICBuYW1lOiAnVGlsZScsXG4gICAgaW5wdXROYW1lczogWydBJ10sXG4gICAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgfTtcblxuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLnRpbGVQcm9ncmFtTWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlVGlsZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgdGlsZVByb2dyYW1NZXRhZGF0YSkgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmNvbnN0IGNyZWF0ZVRpbGVQcm9ncmFtSW5mbyA9IChcbiAgX2hhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgdGlsZVByb2dyYW1NZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBuZXcgQXJyYXkoaW5wdXRTaGFwZS5sZW5ndGgpO1xuXG4gIGNvbnN0IHRpbGVPcHM6IHN0cmluZ1tdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRTaGFwZS5sZW5ndGg7IGkrKykge1xuICAgIG91dHB1dFNoYXBlW2ldID0gaW5wdXRTaGFwZVtpXSAqIGlucHV0c1sxXS5udW1iZXJEYXRhW2ldO1xuICAgIHRpbGVPcHMucHVzaChgaW5wdXRJZHhbJHtpfV0gPSBpbnQobW9kKGZsb2F0KG91dHB1dElkeFske2l9XSksICR7aW5wdXRTaGFwZVtpXX0uKSk7YCk7XG4gIH1cblxuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBvdXRwdXRJZHhbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IGlucHV0SWR4WyR7cmFua31dO1xuICAgICAgICAke3RpbGVPcHMuam9pbignXFxuJyl9XG4gICAgICAgIHJldHVybiBfQShpbnB1dElkeCk7XG4gICAgICB9XG4gICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi50aWxlUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignVGlsZSByZXF1aXJlcyAyIGlucHV0LicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBzZWNvbmQgaW5wdXQgc2hhcGUgbXVzdCAxIGRpbWVuc2lvbi4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzFdLmRpbXNbMF0gIT09IGlucHV0c1swXS5kaW1zLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoTlVNQkVSX1RZUEVTLmluZGV4T2YoaW5wdXRzWzBdLnR5cGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJyAmJiBpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDE2Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCByZXBlYXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuZXhwb3J0IGNvbnN0IHVuc3F1ZWV6ZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxudW1iZXJbXT4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXhlczogbnVtYmVyW10sXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gU2hhcGVVdGlsLnVuc3F1ZWV6ZVNoYXBlKGlucHV0c1swXS5kaW1zLCBheGVzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBvdXRwdXRTaGFwZSk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCB1bnNxdWVlemVWMTMgPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0c1YxMyhpbnB1dHMpO1xuICByZXR1cm4gdW5zcXVlZXplKGluZmVyZW5jZUhhbmRsZXIsIFtpbnB1dHNbMF1dLCBBcnJheS5mcm9tKGlucHV0c1sxXS5pbnRlZ2VyRGF0YSkpO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVW5zcXVlZXplQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxudW1iZXJbXT4gPSAobm9kZTogR3JhcGguTm9kZSk6IG51bWJlcltdID0+XG4gIG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdheGVzJyk7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5zcXVlZXplIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHRlbnNvciB0eXBlcy4nKTtcbiAgfVxufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHNWMTMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnNxdWVlemUgcmVxdWlyZXMgMiBpbnB1dHMuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgT3BTZXQgfSBmcm9tICcuLi8uLi9vcHNldCc7XG5cbmltcG9ydCB7IGJhdGNoTm9ybWFsaXphdGlvbiwgcGFyc2VCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvYmF0Y2gtbm9ybWFsaXphdGlvbic7XG5pbXBvcnQgKiBhcyBiaW5hcnlPcHMgZnJvbSAnLi9vcHMvYmluYXJ5LW9wJztcbmltcG9ydCB7IGNhc3QsIHBhcnNlQ2FzdEF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9jYXN0JztcbmltcG9ydCB7IGNvbmNhdCwgcGFyc2VDb25jYXRBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvY29uY2F0JztcbmltcG9ydCB7IGNvbnYsIHBhcnNlQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9jb252JztcbmltcG9ydCB7IGNvbnZUcmFuc3Bvc2UsIHBhcnNlQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9jb252LXRyYW5zcG9zZSc7XG5pbXBvcnQgeyBkZXB0aFRvU3BhY2UsIHBhcnNlRGVwdGhUb1NwYWNlQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2RlcHRoLXRvLXNwYWNlJztcbmltcG9ydCB7IGZsYXR0ZW4sIHBhcnNlRmxhdHRlbkF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9mbGF0dGVuJztcbmltcG9ydCB7IGdhdGhlciwgcGFyc2VHYXRoZXJBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvZ2F0aGVyJztcbmltcG9ydCB7IGdlbW0sIHBhcnNlR2VtbUF0dHJpYnV0ZXNWMTEsIHBhcnNlR2VtbUF0dHJpYnV0ZXNWNyB9IGZyb20gJy4vb3BzL2dlbW0nO1xuaW1wb3J0IHsgaW1hZ2VTY2FsZXIsIHBhcnNlSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvaW1hZ2Utc2NhbGVyJztcbmltcG9ydCB7IGluc3RhbmNlTm9ybWFsaXphdGlvbiwgcGFyc2VJbnN0YW5jZU5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvaW5zdGFuY2Utbm9ybWFsaXphdGlvbic7XG5pbXBvcnQgeyBscm4sIHBhcnNlTHJuQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2xybic7XG5pbXBvcnQgeyBtYXRNdWwsIHBhcnNlTWF0TXVsQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL21hdG11bCc7XG5pbXBvcnQgeyBwYWRWMTEsIHBhZFYyLCBwYXJzZVBhZEF0dHJpYnV0ZXNWMTEsIHBhcnNlUGFkQXR0cmlidXRlc1YyIH0gZnJvbSAnLi9vcHMvcGFkJztcbmltcG9ydCB7XG4gIGF2ZXJhZ2VQb29sLFxuICBnbG9iYWxBdmVyYWdlUG9vbCxcbiAgZ2xvYmFsTWF4UG9vbCxcbiAgbWF4UG9vbCxcbiAgcGFyc2VBdmVyYWdlUG9vbEF0dHJpYnV0ZXMsXG4gIHBhcnNlR2xvYmFsQXZlcmFnZVBvb2xBdHRyaWJ1dGVzLFxuICBwYXJzZU1heFBvb2xBdHRyaWJ1dGVzLFxufSBmcm9tICcuL29wcy9wb29sJztcbmltcG9ydCB7XG4gIHBhcnNlUmVkdWNlQXR0cmlidXRlcyxcbiAgcmVkdWNlTG9nU3VtLFxuICByZWR1Y2VMb2dTdW1TcXVhcmUsXG4gIHJlZHVjZU1heCxcbiAgcmVkdWNlTWVhbixcbiAgcmVkdWNlTWluLFxuICByZWR1Y2VQcm9kLFxuICByZWR1Y2VTdW0sXG59IGZyb20gJy4vb3BzL3JlZHVjZSc7XG5pbXBvcnQgeyByZXNoYXBlIH0gZnJvbSAnLi9vcHMvcmVzaGFwZSc7XG5pbXBvcnQgeyBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTAsIHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMSwgcmVzaXplIH0gZnJvbSAnLi9vcHMvcmVzaXplLXBhY2tlZCc7XG5pbXBvcnQgeyBzaGFwZSB9IGZyb20gJy4vb3BzL3NoYXBlJztcbmltcG9ydCB7IHBhcnNlU2xpY2VBdHRyaWJ1dGVzLCBzbGljZSwgc2xpY2VWMTAgfSBmcm9tICcuL29wcy9zbGljZSc7XG5pbXBvcnQgeyBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzLCBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzVjEzLCBzb2Z0bWF4LCBzb2Z0bWF4VjEzIH0gZnJvbSAnLi9vcHMvc29mdG1heCc7XG5pbXBvcnQgeyBwYXJzZVNwbGl0QXR0cmlidXRlcywgc3BsaXQgfSBmcm9tICcuL29wcy9zcGxpdCc7XG5pbXBvcnQgeyBwYXJzZVNxdWVlemVBdHRyaWJ1dGVzLCBzcXVlZXplLCBzcXVlZXplVjEzIH0gZnJvbSAnLi9vcHMvc3F1ZWV6ZSc7XG5pbXBvcnQgeyBzdW0gfSBmcm9tICcuL29wcy9zdW0nO1xuaW1wb3J0IHsgdGlsZSB9IGZyb20gJy4vb3BzL3RpbGUnO1xuaW1wb3J0IHsgcGFyc2VUcmFuc3Bvc2VBdHRyaWJ1dGVzLCB0cmFuc3Bvc2UgfSBmcm9tICcuL29wcy90cmFuc3Bvc2UnO1xuaW1wb3J0ICogYXMgdW5hcnlPcHMgZnJvbSAnLi9vcHMvdW5hcnktb3AnO1xuaW1wb3J0IHsgcGFyc2VVbnNxdWVlemVBdHRyaWJ1dGVzLCB1bnNxdWVlemUsIHVuc3F1ZWV6ZVYxMyB9IGZyb20gJy4vb3BzL3Vuc3F1ZWV6ZSc7XG5pbXBvcnQgeyBwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y3LCBwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y5LCB1cHNhbXBsZSB9IGZyb20gJy4vb3BzL3Vwc2FtcGxlJztcblxuZXhwb3J0IGNvbnN0IFdFQkdMX09QX1JFU09MVkVfUlVMRVM6IHJlYWRvbmx5IE9wU2V0LlJlc29sdmVSdWxlW10gPSBbXG4gIFsnQWJzJywgJycsICc2KycsIHVuYXJ5T3BzLmFic10sXG4gIFsnQWNvcycsICcnLCAnNysnLCB1bmFyeU9wcy5hY29zXSxcbiAgWydBZGQnLCAnJywgJzcrJywgYmluYXJ5T3BzLmFkZF0sXG4gIFsnQW5kJywgJycsICc3KycsIGJpbmFyeU9wcy5hbmRdLFxuICBbJ0FzaW4nLCAnJywgJzcrJywgdW5hcnlPcHMuYXNpbl0sXG4gIFsnQXRhbicsICcnLCAnNysnLCB1bmFyeU9wcy5hdGFuXSxcbiAgLy8gVE9ETzogc3VwcG9ydCBuZXcgYXR0cmlidXRlcyBmb3IgQXZlcmFnZVBvb2wtMTBcbiAgWydBdmVyYWdlUG9vbCcsICcnLCAnNysnLCBhdmVyYWdlUG9vbCwgcGFyc2VBdmVyYWdlUG9vbEF0dHJpYnV0ZXNdLFxuICBbJ0JhdGNoTm9ybWFsaXphdGlvbicsICcnLCAnNysnLCBiYXRjaE5vcm1hbGl6YXRpb24sIHBhcnNlQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlc10sXG4gIFsnQ2FzdCcsICcnLCAnNisnLCBjYXN0LCBwYXJzZUNhc3RBdHRyaWJ1dGVzXSxcbiAgWydDZWlsJywgJycsICc2KycsIHVuYXJ5T3BzLmNlaWxdLFxuICBbJ0NsaXAnLCAnJywgJzYtMTAnLCB1bmFyeU9wcy5jbGlwLCB1bmFyeU9wcy5wYXJzZUNsaXBBdHRyaWJ1dGVzXSxcbiAgWydDbGlwJywgJycsICcxMSsnLCB1bmFyeU9wcy5jbGlwVjExXSxcbiAgWydDb25jYXQnLCAnJywgJzQrJywgY29uY2F0LCBwYXJzZUNvbmNhdEF0dHJpYnV0ZXNdLFxuICBbJ0NvbnYnLCAnJywgJzErJywgY29udiwgcGFyc2VDb252QXR0cmlidXRlc10sXG4gIFsnQ29udlRyYW5zcG9zZScsICcnLCAnMSsnLCBjb252VHJhbnNwb3NlLCBwYXJzZUNvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzXSxcbiAgWydDb3MnLCAnJywgJzcrJywgdW5hcnlPcHMuY29zXSxcbiAgWydEaXYnLCAnJywgJzcrJywgYmluYXJ5T3BzLmRpdl0sXG4gIFsnRHJvcG91dCcsICcnLCAnNysnLCB1bmFyeU9wcy5pZGVudGl0eV0sXG4gIFsnRGVwdGhUb1NwYWNlJywgJycsICcxKycsIGRlcHRoVG9TcGFjZSwgcGFyc2VEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzXSxcbiAgWydFcXVhbCcsICcnLCAnNysnLCBiaW5hcnlPcHMuZXF1YWxdLFxuICBbJ0VsdScsICcnLCAnNisnLCB1bmFyeU9wcy5lbHUsIHVuYXJ5T3BzLnBhcnNlRWx1QXR0cmlidXRlc10sXG4gIFsnRXhwJywgJycsICc2KycsIHVuYXJ5T3BzLmV4cF0sXG4gIFsnRmxhdHRlbicsICcnLCAnMSsnLCBmbGF0dGVuLCBwYXJzZUZsYXR0ZW5BdHRyaWJ1dGVzXSxcbiAgWydGbG9vcicsICcnLCAnNisnLCB1bmFyeU9wcy5mbG9vcl0sXG4gIFsnRnVzZWRDb252JywgJ2NvbS5taWNyb3NvZnQnLCAnMSsnLCBjb252LCBwYXJzZUNvbnZBdHRyaWJ1dGVzXSxcbiAgWydHYXRoZXInLCAnJywgJzErJywgZ2F0aGVyLCBwYXJzZUdhdGhlckF0dHJpYnV0ZXNdLFxuICBbJ0dlbW0nLCAnJywgJzctMTAnLCBnZW1tLCBwYXJzZUdlbW1BdHRyaWJ1dGVzVjddLFxuICBbJ0dlbW0nLCAnJywgJzExKycsIGdlbW0sIHBhcnNlR2VtbUF0dHJpYnV0ZXNWMTFdLFxuICBbJ0dsb2JhbEF2ZXJhZ2VQb29sJywgJycsICcxKycsIGdsb2JhbEF2ZXJhZ2VQb29sLCBwYXJzZUdsb2JhbEF2ZXJhZ2VQb29sQXR0cmlidXRlc10sXG4gIFsnR2xvYmFsTWF4UG9vbCcsICcnLCAnMSsnLCBnbG9iYWxNYXhQb29sXSxcbiAgWydHcmVhdGVyJywgJycsICc3KycsIGJpbmFyeU9wcy5ncmVhdGVyXSxcbiAgWydJZGVudGl0eScsICcnLCAnMSsnLCB1bmFyeU9wcy5pZGVudGl0eV0sXG4gIFsnSW1hZ2VTY2FsZXInLCAnJywgJzErJywgaW1hZ2VTY2FsZXIsIHBhcnNlSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzXSxcbiAgWydJbnN0YW5jZU5vcm1hbGl6YXRpb24nLCAnJywgJzYrJywgaW5zdGFuY2VOb3JtYWxpemF0aW9uLCBwYXJzZUluc3RhbmNlTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXNdLFxuICBbJ0xlYWt5UmVsdScsICcnLCAnNisnLCB1bmFyeU9wcy5sZWFreVJlbHUsIHVuYXJ5T3BzLnBhcnNlTGVha3lSZWx1QXR0cmlidXRlc10sXG4gIFsnTGVzcycsICcnLCAnNysnLCBiaW5hcnlPcHMubGVzc10sXG4gIFsnTFJOJywgJycsICcxKycsIGxybiwgcGFyc2VMcm5BdHRyaWJ1dGVzXSxcbiAgWydMb2cnLCAnJywgJzYrJywgdW5hcnlPcHMubG9nXSxcbiAgWydNYXRNdWwnLCAnJywgJzErJywgbWF0TXVsLCBwYXJzZU1hdE11bEF0dHJpYnV0ZXNdLFxuICAvLyBUT0RPOiBzdXBwb3J0IG5ldyBhdHRyaWJ1dGVzIGZvciBNYXhQb29sLTggYW5kIE1heFBvb2wtMTBcbiAgWydNYXhQb29sJywgJycsICcxKycsIG1heFBvb2wsIHBhcnNlTWF4UG9vbEF0dHJpYnV0ZXNdLFxuICBbJ011bCcsICcnLCAnNysnLCBiaW5hcnlPcHMubXVsXSxcbiAgWydOZWcnLCAnJywgJzYrJywgdW5hcnlPcHMubmVnXSxcbiAgWydOb3QnLCAnJywgJzErJywgdW5hcnlPcHMubm90XSxcbiAgWydPcicsICcnLCAnNysnLCBiaW5hcnlPcHMub3JdLFxuICBbJ1BhZCcsICcnLCAnMi0xMCcsIHBhZFYyLCBwYXJzZVBhZEF0dHJpYnV0ZXNWMl0sXG4gIFsnUGFkJywgJycsICcxMSsnLCBwYWRWMTEsIHBhcnNlUGFkQXR0cmlidXRlc1YxMV0sXG4gIFsnUG93JywgJycsICc3KycsIGJpbmFyeU9wcy5wb3ddLFxuICBbJ1BSZWx1JywgJycsICc3KycsIGJpbmFyeU9wcy5wUmVsdV0sXG4gIFsnUmVkdWNlTG9nU3VtJywgJycsICcxKycsIHJlZHVjZUxvZ1N1bSwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWR1Y2VNYXgnLCAnJywgJzErJywgcmVkdWNlTWF4LCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZU1lYW4nLCAnJywgJzErJywgcmVkdWNlTWVhbiwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWR1Y2VNaW4nLCAnJywgJzErJywgcmVkdWNlTWluLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZVByb2QnLCAnJywgJzErJywgcmVkdWNlUHJvZCwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWR1Y2VTdW0nLCAnJywgJzEtMTInLCByZWR1Y2VTdW0sIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlU3VtU3F1YXJlJywgJycsICcxKycsIHJlZHVjZUxvZ1N1bVNxdWFyZSwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWx1JywgJycsICc2KycsIHVuYXJ5T3BzLnJlbHVdLFxuICBbJ1Jlc2hhcGUnLCAnJywgJzUrJywgcmVzaGFwZV0sXG4gIFsnUmVzaXplJywgJycsICcxMCcsIHJlc2l6ZSwgcGFyc2VSZXNpemVBdHRyaWJ1dGVzVjEwXSxcbiAgWydSZXNpemUnLCAnJywgJzExKycsIHJlc2l6ZSwgcGFyc2VSZXNpemVBdHRyaWJ1dGVzVjExXSxcbiAgWydTaGFwZScsICcnLCAnMSsnLCBzaGFwZV0sXG4gIFsnU2lnbW9pZCcsICcnLCAnNisnLCB1bmFyeU9wcy5zaWdtb2lkXSxcbiAgWydTaW4nLCAnJywgJzcrJywgdW5hcnlPcHMuc2luXSxcbiAgWydTbGljZScsICcnLCAnMTArJywgc2xpY2VWMTBdLCAvLyBUT0RPOiBzdXBwb3J0ICdzdGVwcycgZm9yIFNsaWNlLTEwXG4gIFsnU2xpY2UnLCAnJywgJzEtOScsIHNsaWNlLCBwYXJzZVNsaWNlQXR0cmlidXRlc10sXG4gIC8vIFRoZSBcInNlbWFudGljXCIgbWVhbmluZyBvZiBheGlzIGhhcyBjaGFuZ2VkIGluIG9wc2V0LTEzLlxuICBbJ1NvZnRtYXgnLCAnJywgJzEtMTInLCBzb2Z0bWF4LCBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzXSxcbiAgWydTb2Z0bWF4JywgJycsICcxMysnLCBzb2Z0bWF4VjEzLCBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzVjEzXSxcbiAgLy8gJ1NwbGl0JyBvcGVyYXRvciBoYXMgYW4gb3B0aW9uYWwgYXR0cmlidXRlICdzcGxpdCdcbiAgLy8gdGhpcyBhdHRyaWJ1dGUgZGV0ZXJtaW5lcyBob3cgdGhlIHNwZWNpZmllZCBheGlzIG9mIGlucHV0IGRhdGEgaXMgc3BsaXQuXG4gIC8vIFdoZW4gdGhlIGF0dHJpYnV0ZSBpcyBtaXNzaW5nLCB3ZSBuZWVkIHRoZSBjb3VudCBvZiBudW1iZXIgb2Ygb3V0cHV0c1xuICAvLyBzbyB0aGF0IHdlIGNhbiBkZXRlcm1pbmUgdGhlICdzcGxpdCcgYXR0cmlidXRlIGZyb20gdGhlIHJ1bnRpbWUgaW5wdXQgdG8gdGhlIE9wZXJhdG9yXG4gIFsnU3BsaXQnLCAnJywgJzItMTInLCBzcGxpdCwgcGFyc2VTcGxpdEF0dHJpYnV0ZXNdLFxuICBbJ1NxcnQnLCAnJywgJzYrJywgdW5hcnlPcHMuc3FydF0sXG4gIFsnU3F1ZWV6ZScsICcnLCAnMS0xMicsIHNxdWVlemUsIHBhcnNlU3F1ZWV6ZUF0dHJpYnV0ZXNdLFxuICBbJ1NxdWVlemUnLCAnJywgJzEzKycsIHNxdWVlemVWMTNdLFxuICBbJ1N1YicsICcnLCAnNysnLCBiaW5hcnlPcHMuc3ViXSxcbiAgWydTdW0nLCAnJywgJzYrJywgc3VtXSxcbiAgWydUYW4nLCAnJywgJzcrJywgdW5hcnlPcHMudGFuXSxcbiAgWydUYW5oJywgJycsICc2KycsIHVuYXJ5T3BzLnRhbmhdLFxuICBbJ1RpbGUnLCAnJywgJzYrJywgdGlsZV0sXG4gIFsnVHJhbnNwb3NlJywgJycsICcxKycsIHRyYW5zcG9zZSwgcGFyc2VUcmFuc3Bvc2VBdHRyaWJ1dGVzXSxcbiAgWydVcHNhbXBsZScsICcnLCAnNy04JywgdXBzYW1wbGUsIHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjddLFxuICBbJ1Vwc2FtcGxlJywgJycsICc5JywgdXBzYW1wbGUsIHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjldLFxuICBbJ1Vuc3F1ZWV6ZScsICcnLCAnMS0xMicsIHVuc3F1ZWV6ZSwgcGFyc2VVbnNxdWVlemVBdHRyaWJ1dGVzXSxcbiAgWydVbnNxdWVlemUnLCAnJywgJzEzKycsIHVuc3F1ZWV6ZVYxM10sXG4gIFsnWG9yJywgJycsICc3KycsIGJpbmFyeU9wcy54b3JdLFxuXTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuY29uc3QgSU5MSU5FX0ZVTkNfREVGX1JFR0VYID0gL0BpbmxpbmVbXFxzXFxuXFxyXSsoXFx3KylbXFxzXFxuXFxyXSsoWzAtOWEtekEtWl9dKylcXHMqXFwoKFteKV0qKVxcKVxccyp7KChbXn1dfFtcXG5cXHJdKSopfS9nbTtcbmNvbnN0IEZVTkNfQ0FMTF9SRUdFWCA9ICcoXFxcXHcrKT9cXFxccysoW18wLTlhLXpBLVpdKylcXFxccys9XFxcXHMrX19GVU5DX19cXFxcKCguKilcXFxcKVxcXFxzKjsnO1xuLyoqXG4gKiBHTFNMIHByZXByb2Nlc3NvciByZXNwb25zaWJsZSBmb3IgcmVzb2x2aW5nIEBpbmxpbmUgZGlyZWN0aXZlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVwbGFjZUlubGluZXMoc2NyaXB0OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBpbmxpbmVEZWZzOiB7IFtuYW1lOiBzdHJpbmddOiB7IHBhcmFtczogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IG5hbWU6IHN0cmluZyB9IHwgbnVsbD47IGJvZHk6IHN0cmluZyB9IH0gPSB7fTtcbiAgbGV0IG1hdGNoO1xuICB3aGlsZSAoKG1hdGNoID0gSU5MSU5FX0ZVTkNfREVGX1JFR0VYLmV4ZWMoc2NyaXB0KSkgIT09IG51bGwpIHtcbiAgICBjb25zdCBwYXJhbXMgPSBtYXRjaFszXVxuICAgICAgLnNwbGl0KCcsJylcbiAgICAgIC5tYXAoKHMpID0+IHtcbiAgICAgICAgY29uc3QgdG9rZW5zID0gcy50cmltKCkuc3BsaXQoJyAnKTtcbiAgICAgICAgaWYgKHRva2VucyAmJiB0b2tlbnMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgcmV0dXJuIHsgdHlwZTogdG9rZW5zWzBdLCBuYW1lOiB0b2tlbnNbMV0gfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKCh2KSA9PiB2ICE9PSBudWxsKTtcbiAgICBpbmxpbmVEZWZzW21hdGNoWzJdXSA9IHsgcGFyYW1zLCBib2R5OiBtYXRjaFs0XSB9O1xuICB9XG4gIGZvciAoY29uc3QgbmFtZSBpbiBpbmxpbmVEZWZzKSB7XG4gICAgY29uc3QgcmVnZXhTdHJpbmcgPSBGVU5DX0NBTExfUkVHRVgucmVwbGFjZSgnX19GVU5DX18nLCBuYW1lKTtcbiAgICBjb25zdCByZWdleCA9IG5ldyBSZWdFeHAocmVnZXhTdHJpbmcsICdnbScpO1xuICAgIHdoaWxlICgobWF0Y2ggPSByZWdleC5leGVjKHNjcmlwdCkpICE9PSBudWxsKSB7XG4gICAgICBjb25zdCB0eXBlID0gbWF0Y2hbMV07XG4gICAgICBjb25zdCB2YXJpYWJsZSA9IG1hdGNoWzJdO1xuICAgICAgY29uc3QgcGFyYW1zID0gbWF0Y2hbM10uc3BsaXQoJywnKTtcbiAgICAgIGNvbnN0IGRlY2xMaW5lID0gdHlwZSA/IGAke3R5cGV9ICR7dmFyaWFibGV9O2AgOiAnJztcbiAgICAgIGxldCBuZXdCb2R5OiBzdHJpbmcgPSBpbmxpbmVEZWZzW25hbWVdLmJvZHk7XG4gICAgICBsZXQgcGFyYW1SZWRlY0xpbmUgPSAnJztcbiAgICAgIGlubGluZURlZnNbbmFtZV0ucGFyYW1zLmZvckVhY2goKHYsIGkpID0+IHtcbiAgICAgICAgaWYgKHYpIHtcbiAgICAgICAgICBwYXJhbVJlZGVjTGluZSArPSBgJHt2LnR5cGV9ICR7di5uYW1lfSA9ICR7cGFyYW1zW2ldfTtcXG5gO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIG5ld0JvZHkgPSBgJHtwYXJhbVJlZGVjTGluZX1cXG4gJHtuZXdCb2R5fWA7XG4gICAgICBuZXdCb2R5ID0gbmV3Qm9keS5yZXBsYWNlKCdyZXR1cm4nLCBgJHt2YXJpYWJsZX0gPSBgKTtcbiAgICAgIGNvbnN0IHJlcGxhY2VtZW50ID0gYFxuICAgICAgJHtkZWNsTGluZX1cbiAgICAgIHtcbiAgICAgICAgJHtuZXdCb2R5fVxuICAgICAgfVxuICAgICAgYDtcbiAgICAgIHNjcmlwdCA9IHNjcmlwdC5yZXBsYWNlKG1hdGNoWzBdLCByZXBsYWNlbWVudCk7XG4gICAgfVxuICB9XG4gIHNjcmlwdCA9IHNjcmlwdC5yZXBsYWNlKElOTElORV9GVU5DX0RFRl9SRUdFWCwgJycpO1xuICByZXR1cm4gc2NyaXB0O1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG4vKiogTGF5b3V0IHByZWZlcmVuY2VzICovXG5leHBvcnQgaW50ZXJmYWNlIFdpZHRoSGVpZ2h0UHJlZnMge1xuICBicmVha0F4aXM/OiBudW1iZXI7XG4gIGlzUGFja2VkPzogYm9vbGVhbjtcbiAgcmV2ZXJzZVdIPzogYm9vbGVhbjtcbn1cbi8qKlxuICogVGV4dHVyZUxheW91dFN0cmF0ZWd5IGlzIGFuIGFic3RyYWN0aW9uIGZvciBkaWZmZXJlbnQgcGxhbnNcbiAqIGZvciBtYXBwaW5nIG4tZGltZW5zaW9uYWwgYXJyYXlzIHRvIDJEIHRleHR1cmVzIChhbmQgYmFjaylcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kge1xuICBjb21wdXRlVGV4dHVyZVdIKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcHJlZnM/OiBXaWR0aEhlaWdodFByZWZzKTogW251bWJlciwgbnVtYmVyXTtcbn1cblxuLyoqXG4gKiBUaGlzIHN0cmF0ZWd5IHRyeSB0byBmaW5kIHRoZSBtaW5pbWFsIG1heChXLEgpIHRoYXQgZnVsZmlsbHMgKFcgKiBIID09IHRvdGFsU2l6ZSlcbiAqL1xuZXhwb3J0IGNsYXNzIEFsd2F5c0tlZXBPcmlnaW5hbFNpemVTdHJhdGVneSBpbXBsZW1lbnRzIFRleHR1cmVMYXlvdXRTdHJhdGVneSB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBtYXhUZXh0dXJlU2l6ZTogbnVtYmVyKSB7fVxuICBjb21wdXRlVGV4dHVyZVdIKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcHJlZnM/OiBXaWR0aEhlaWdodFByZWZzKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgLy8gc2NhbGFyIHRlbnNvclxuICAgIGlmIChzaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBbMSwgMV07XG4gICAgfVxuICAgIGNvbnN0IG1heFRleHR1cmVTaXplID0gdGhpcy5tYXhUZXh0dXJlU2l6ZTtcbiAgICBpZiAocHJlZnMgJiYgcHJlZnMuYnJlYWtBeGlzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIGNoZWNrIHRvIHNlZSBpZiBkaW1zIGZpdFxuICAgICAgY29uc3Qgd3NpemUgPSBwcmVmcy5icmVha0F4aXMgPj0gc2hhcGUubGVuZ3RoID8gMSA6IHNoYXBlLnNsaWNlKHByZWZzLmJyZWFrQXhpcykucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG4gICAgICBjb25zdCBoc2l6ZSA9IHByZWZzLmJyZWFrQXhpcyA8PSAwID8gMSA6IHNoYXBlLnNsaWNlKDAsIHByZWZzLmJyZWFrQXhpcykucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG4gICAgICBpZiAod3NpemUgPiBtYXhUZXh0dXJlU2l6ZSB8fCBoc2l6ZSA+IG1heFRleHR1cmVTaXplKSB7XG4gICAgICAgIC8vIGlnbm9yZSBwcmVmZXJlbmNlc1xuICAgICAgICAvLyBjb250aW51ZSB3aXRoIGRlZmF1bHQgbGF5b3V0XG4gICAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICdUZXh0dXJlTGF5b3V0JyxcbiAgICAgICAgICBgR2l2ZW4gd2lkdGgvaGVpZ2h0IHByZWZlcmVuY2VzIHdlcmUgdW5hdHRhaW5hYmxlOiBzaGFwZToke3NoYXBlfSwgYnJlYWtBeGlzOiR7cHJlZnMuYnJlYWtBeGlzfWAsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gW3dzaXplLCBoc2l6ZV07XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHRvdGFsU2l6ZSA9IHNoYXBlLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuXG4gICAgbGV0IHdpZHRoID0gTWF0aC5mbG9vcihNYXRoLnNxcnQodG90YWxTaXplKSk7XG5cbiAgICBmb3IgKDsgd2lkdGggPCBtYXhUZXh0dXJlU2l6ZSAmJiB3aWR0aCA8IHRvdGFsU2l6ZTsgd2lkdGgrKykge1xuICAgICAgaWYgKHRvdGFsU2l6ZSAlIHdpZHRoID09PSAwKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh3aWR0aCA+PSBtYXhUZXh0dXJlU2l6ZSB8fCB0b3RhbFNpemUgJSB3aWR0aCAhPT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgZ2l2ZW4gZGltZW5zaW9ucyBhcmUgb3V0c2lkZSB0aGlzIEdQVSdzIGJvdW5kYXJpZXM6ICR7c2hhcGV9YCk7XG4gICAgfVxuICAgIHJldHVybiBbd2lkdGgsIHRvdGFsU2l6ZSAvIHdpZHRoXTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUHJlZmVyTG9naWNhbFN0cmF0ZWd5IGltcGxlbWVudHMgVGV4dHVyZUxheW91dFN0cmF0ZWd5IHtcbiAgY29uc3RydWN0b3IocHVibGljIG1heFRleHR1cmVTaXplOiBudW1iZXIpIHt9XG4gIGNvbXB1dGVUZXh0dXJlV0goc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwcmVmcz86IFdpZHRoSGVpZ2h0UHJlZnMpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICBjb25zdCB3aCA9IHRoaXMuY29tcHV0ZVRleHR1cmUoc2hhcGUsIHByZWZzKTtcbiAgICBpZiAocHJlZnMgJiYgcHJlZnMuaXNQYWNrZWQpIHtcbiAgICAgIHdoWzBdIC89IDI7XG4gICAgICB3aFsxXSAvPSAyO1xuICAgIH1cbiAgICBpZiAocHJlZnMgJiYgcHJlZnMucmV2ZXJzZVdIKSB7XG4gICAgICByZXR1cm4gW3doWzFdLCB3aFswXV07XG4gICAgfVxuICAgIHJldHVybiB3aDtcbiAgfVxuXG4gIGNvbXB1dGVUZXh0dXJlKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcHJlZnM/OiBXaWR0aEhlaWdodFByZWZzKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgY29uc3QgaXNQYWNrZWQgPSBwcmVmcyAmJiBwcmVmcy5pc1BhY2tlZDtcbiAgICAvLyBzY2FsYXIgdGVuc29yXG4gICAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGlzUGFja2VkID8gWzIsIDJdIDogWzEsIDFdO1xuICAgIH1cbiAgICBsZXQgbWF4VGV4dHVyZVNpemUgPSB0aGlzLm1heFRleHR1cmVTaXplO1xuICAgIGlmIChwcmVmcyAmJiBwcmVmcy5icmVha0F4aXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gY2hlY2sgdG8gc2VlIGlmIGRpbXMgZml0XG4gICAgICBjb25zdCB3c2l6ZSA9IHByZWZzLmJyZWFrQXhpcyA+PSBzaGFwZS5sZW5ndGggPyAxIDogc2hhcGUuc2xpY2UocHJlZnMuYnJlYWtBeGlzKS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcbiAgICAgIGNvbnN0IGhzaXplID0gcHJlZnMuYnJlYWtBeGlzIDw9IDAgPyAxIDogc2hhcGUuc2xpY2UoMCwgcHJlZnMuYnJlYWtBeGlzKS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcbiAgICAgIGlmICh3c2l6ZSA+IG1heFRleHR1cmVTaXplIHx8IGhzaXplID4gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgICAgLy8gaWdub3JlIHByZWZlcmVuY2VzXG4gICAgICAgIC8vIGNvbnRpbnVlIHdpdGggZGVmYXVsdCBsYXlvdXRcbiAgICAgICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICAgJ1RleHR1cmVMYXlvdXQnLFxuICAgICAgICAgIGBHaXZlbiB3aWR0aC9oZWlnaHQgcHJlZmVyZW5jZXMgd2VyZSB1bmF0dGFpbmFibGU6IHNoYXBlOiR7c2hhcGV9LCBicmVha0F4aXM6JHtwcmVmcy5icmVha0F4aXN9YCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbd3NpemUsIGhzaXplXTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IGxvZ1NoYXBlID0gc2hhcGUuc2xpY2UoMCk7XG4gICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICBtYXhUZXh0dXJlU2l6ZSA9IG1heFRleHR1cmVTaXplICogMjtcblxuICAgICAgLy8gVGhpcyBsb2dpYyBlbnN1cmVzIHdlIGFjY3VyYXRlbHkgY291bnQgdGhlIG51bWJlciBvZiBwYWNrZWQgdGV4ZWxzIG5lZWRlZFxuICAgICAgLy8gdG8gYWNjb21tb2RhdGUgdGhlIHRlbnNvci4gV2UgY2FuIG9ubHkgcGFjayB2YWx1ZXMgaW4gdGhlIHNhbWUgdGV4ZWwgaWZcbiAgICAgIC8vIHRoZXkgYXJlIGZyb20gYWRqYWNlbnQgcGFpcnMgb2Ygcm93cy9jb2xzIHdpdGhpbiB0aGUgc2FtZSBiYXRjaC4gU28gaWYgYVxuICAgICAgLy8gdGVuc29yIGhhcyAzIHJvd3MsIHdlIHByZXRlbmQgaXQgaGFzIDQgcm93cyBpbiBvcmRlciB0byBhY2NvdW50IGZvciB0aGVcbiAgICAgIC8vIGZhY3QgdGhhdCB0aGUgdGV4ZWxzIGNvbnRhaW5pbmcgdGhlIHRoaXJkIHJvdyBhcmUgaGFsZiBlbXB0eS5cbiAgICAgIGxvZ1NoYXBlID0gbG9nU2hhcGUubWFwKChfZCwgaSkgPT5cbiAgICAgICAgaSA+PSBsb2dTaGFwZS5sZW5ndGggLSAyID8gKGxvZ1NoYXBlW2ldICUgMiA9PT0gMCA/IGxvZ1NoYXBlW2ldIDogbG9nU2hhcGVbaV0gKyAxKSA6IGxvZ1NoYXBlW2ldLFxuICAgICAgKTtcblxuICAgICAgLy8gUGFja2VkIHRleHR1cmUgaGVpZ2h0IGlzIGF0IGxlYXN0IDIgKHRoZSBjaGFubmVsIGhlaWdodCBvZiBhIHNpbmdsZVxuICAgICAgLy8gdGV4ZWwpLlxuICAgICAgaWYgKGxvZ1NoYXBlLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBsb2dTaGFwZSA9IFsyLCBsb2dTaGFwZVswXV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSWYgbG9naWNhbCBzaGFwZSBpcyAyLCB3ZSBkb24ndCBzcXVlZXplLCBzaW5jZSB3ZSB3YW50IHRvIG1hdGNoIHBoeXNpY2FsLlxuICAgIGlmIChsb2dTaGFwZS5sZW5ndGggIT09IDIpIHtcbiAgICAgIGNvbnN0IHNxdWVlemVSZXN1bHQgPSBzcXVlZXplU2hhcGUobG9nU2hhcGUpO1xuICAgICAgbG9nU2hhcGUgPSBzcXVlZXplUmVzdWx0Lm5ld1NoYXBlO1xuICAgIH1cblxuICAgIGNvbnN0IHNpemUgPSBzaXplRnJvbVNoYXBlKGxvZ1NoYXBlKTtcbiAgICBpZiAobG9nU2hhcGUubGVuZ3RoIDw9IDEgJiYgc2l6ZSA8PSBtYXhUZXh0dXJlU2l6ZSkge1xuICAgICAgcmV0dXJuIFsxLCBzaXplXTtcbiAgICB9IGVsc2UgaWYgKGxvZ1NoYXBlLmxlbmd0aCA9PT0gMiAmJiBsb2dTaGFwZVswXSA8PSBtYXhUZXh0dXJlU2l6ZSAmJiBsb2dTaGFwZVsxXSA8PSBtYXhUZXh0dXJlU2l6ZSkge1xuICAgICAgcmV0dXJuIGxvZ1NoYXBlIGFzIFtudW1iZXIsIG51bWJlcl07XG4gICAgfSBlbHNlIGlmIChsb2dTaGFwZS5sZW5ndGggPT09IDMgJiYgbG9nU2hhcGVbMF0gKiBsb2dTaGFwZVsxXSA8PSBtYXhUZXh0dXJlU2l6ZSAmJiBsb2dTaGFwZVsyXSA8PSBtYXhUZXh0dXJlU2l6ZSkge1xuICAgICAgcmV0dXJuIFtsb2dTaGFwZVswXSAqIGxvZ1NoYXBlWzFdLCBsb2dTaGFwZVsyXV07XG4gICAgfSBlbHNlIGlmIChsb2dTaGFwZS5sZW5ndGggPT09IDMgJiYgbG9nU2hhcGVbMF0gPD0gbWF4VGV4dHVyZVNpemUgJiYgbG9nU2hhcGVbMV0gKiBsb2dTaGFwZVsyXSA8PSBtYXhUZXh0dXJlU2l6ZSkge1xuICAgICAgcmV0dXJuIFtsb2dTaGFwZVswXSwgbG9nU2hhcGVbMV0gKiBsb2dTaGFwZVsyXV07XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGxvZ1NoYXBlLmxlbmd0aCA9PT0gNCAmJlxuICAgICAgbG9nU2hhcGVbMF0gKiBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdIDw9IG1heFRleHR1cmVTaXplICYmXG4gICAgICBsb2dTaGFwZVszXSA8PSBtYXhUZXh0dXJlU2l6ZVxuICAgICkge1xuICAgICAgcmV0dXJuIFtsb2dTaGFwZVswXSAqIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl0sIGxvZ1NoYXBlWzNdXTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgbG9nU2hhcGUubGVuZ3RoID09PSA0ICYmXG4gICAgICBsb2dTaGFwZVswXSA8PSBtYXhUZXh0dXJlU2l6ZSAmJlxuICAgICAgbG9nU2hhcGVbMV0gKiBsb2dTaGFwZVsyXSAqIGxvZ1NoYXBlWzNdIDw9IG1heFRleHR1cmVTaXplXG4gICAgKSB7XG4gICAgICByZXR1cm4gW2xvZ1NoYXBlWzBdLCBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdICogbG9nU2hhcGVbM11dO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaXNQYWNrZWQpIHtcbiAgICAgICAgLy8gRm9yIHBhY2tlZCB0ZXh0dXJlcyBzaXplIGVxdWFscyB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzIHJlcXVpcmVkIHRvXG4gICAgICAgIC8vIGFjY29tbW9kYXRlIHRoZSB0ZXh0dXJlIGRhdGEuIEhvd2V2ZXIgaW4gb3JkZXIgdG8gc3F1YXJpZnkgc3VjaCB0aGF0XG4gICAgICAgIC8vIGlubmVyIGRpbWVuc2lvbnMgc3RheSBldmVuLCB3ZSByZXdyaXRlIHNpemUgdG8gZXF1YWwgdGhlIG51bWJlciBvZlxuICAgICAgICAvLyB0ZXhlbHMuIFRoZW4gaW4gdGhlIHJldHVybiBzdGF0ZW1lbnQgd2UgcmVoeWRyYXRlIHRoZSBzcXVhcmlmaWVkXG4gICAgICAgIC8vIGRpbWVuc2lvbnMgdG8gY2hhbm5lbCB1bml0cy5cbiAgICAgICAgcmV0dXJuIHNpemVUb1NxdWFyaXNoU2hhcGUoc2l6ZSAvIDQpLm1hcCgoZCkgPT4gZCAqIDIpIGFzIFtudW1iZXIsIG51bWJlcl07XG4gICAgICB9XG4gICAgICByZXR1cm4gc2l6ZVRvU3F1YXJpc2hTaGFwZShzaXplKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNxdWVlemVTaGFwZShzaGFwZTogbnVtYmVyW10sIGF4aXM/OiBudW1iZXJbXSk6IHsgbmV3U2hhcGU6IG51bWJlcltdOyBrZXB0RGltczogbnVtYmVyW10gfSB7XG4gIGNvbnN0IG5ld1NoYXBlOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBrZXB0RGltczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgaXNFbXB0eUFycmF5ID0gYXhpcyAhPSBudWxsICYmIEFycmF5LmlzQXJyYXkoYXhpcykgJiYgYXhpcy5sZW5ndGggPT09IDA7XG4gIGNvbnN0IGF4ZXMgPSBheGlzID09IG51bGwgfHwgaXNFbXB0eUFycmF5ID8gbnVsbCA6IHBhcnNlQXhpc1BhcmFtKGF4aXMsIHNoYXBlKS5zb3J0KCk7XG4gIGxldCBqID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaGFwZS5sZW5ndGg7ICsraSkge1xuICAgIGlmIChheGVzICE9IG51bGwpIHtcbiAgICAgIGlmIChheGVzW2pdID09PSBpICYmIHNoYXBlW2ldICE9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuJ3Qgc3F1ZWV6ZSBheGlzICR7aX0gc2luY2UgaXRzIGRpbSAnJHtzaGFwZVtpXX0nIGlzIG5vdCAxYCk7XG4gICAgICB9XG4gICAgICBpZiAoKGF4ZXNbal0gPT0gbnVsbCB8fCBheGVzW2pdID4gaSkgJiYgc2hhcGVbaV0gPT09IDEpIHtcbiAgICAgICAgbmV3U2hhcGUucHVzaChzaGFwZVtpXSk7XG4gICAgICAgIGtlcHREaW1zLnB1c2goaSk7XG4gICAgICB9XG4gICAgICBpZiAoYXhlc1tqXSA8PSBpKSB7XG4gICAgICAgIGorKztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNoYXBlW2ldICE9PSAxKSB7XG4gICAgICBuZXdTaGFwZS5wdXNoKHNoYXBlW2ldKTtcbiAgICAgIGtlcHREaW1zLnB1c2goaSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7IG5ld1NoYXBlLCBrZXB0RGltcyB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VBeGlzUGFyYW0oYXhpczogbnVtYmVyIHwgbnVtYmVyW10sIHNoYXBlOiBudW1iZXJbXSk6IG51bWJlcltdIHtcbiAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICAvLyBOb3JtYWxpemUgaW5wdXRcbiAgYXhpcyA9IGF4aXMgPT0gbnVsbCA/IHNoYXBlLm1hcCgoX3MsIGkpID0+IGkpIDogKFtdIGFzIG51bWJlcltdKS5jb25jYXQoYXhpcyk7XG5cbiAgLy8gQ2hlY2sgZm9yIHZhbGlkIHJhbmdlXG4gIGFzc2VydChcbiAgICBheGlzLmV2ZXJ5KChheCkgPT4gYXggPj0gLXJhbmsgJiYgYXggPCByYW5rKSxcbiAgICAoKSA9PiBgQWxsIHZhbHVlcyBpbiBheGlzIHBhcmFtIG11c3QgYmUgaW4gcmFuZ2UgWy0ke3Jhbmt9LCAke3Jhbmt9KSBidXQgYCArIGBnb3QgYXhpcyAke2F4aXN9YCxcbiAgKTtcblxuICAvLyBDaGVjayBmb3Igb25seSBpbnRlZ2Vyc1xuICBhc3NlcnQoYXhpcy5ldmVyeShpc0ludCksICgpID0+ICdBbGwgdmFsdWVzIGluIGF4aXMgcGFyYW0gbXVzdCBiZSBpbnRlZ2VycyBidXQgJyArIGBnb3QgYXhpcyAke2F4aXN9YCk7XG5cbiAgLy8gSGFuZGxlIG5lZ2F0aXZlIGF4aXMuXG4gIHJldHVybiBheGlzLm1hcCgoYSkgPT4gKGEgPCAwID8gcmFuayArIGEgOiBhKSk7XG59XG5leHBvcnQgZnVuY3Rpb24gaXNJbnQoYTogbnVtYmVyKTogYm9vbGVhbiB7XG4gIHJldHVybiBhICUgMSA9PT0gMDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzaXplRnJvbVNoYXBlKHNoYXBlOiBudW1iZXJbXSk6IG51bWJlciB7XG4gIGlmIChzaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICAvLyBTY2FsYXIuXG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgbGV0IHNpemUgPSBzaGFwZVswXTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBzaGFwZS5sZW5ndGg7IGkrKykge1xuICAgIHNpemUgKj0gc2hhcGVbaV07XG4gIH1cbiAgcmV0dXJuIHNpemU7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0Um93c0NvbHMoc2hhcGU6IG51bWJlcltdKTogW251bWJlciwgbnVtYmVyXSB7XG4gIGlmIChzaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBFcnJvcignQ2Fubm90IGdldCByb3dzIGFuZCBjb2x1bW5zIG9mIGFuIGVtcHR5IHNoYXBlIGFycmF5LicpO1xuICB9XG5cbiAgcmV0dXJuIFtzaGFwZS5sZW5ndGggPiAxID8gc2hhcGVbc2hhcGUubGVuZ3RoIC0gMl0gOiAxLCBzaGFwZVtzaGFwZS5sZW5ndGggLSAxXV07XG59XG5leHBvcnQgZnVuY3Rpb24gc2l6ZVRvU3F1YXJpc2hTaGFwZShzaXplOiBudW1iZXIpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgY29uc3Qgd2lkdGggPSBNYXRoLmNlaWwoTWF0aC5zcXJ0KHNpemUpKTtcbiAgcmV0dXJuIFt3aWR0aCwgTWF0aC5jZWlsKHNpemUgLyB3aWR0aCldO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldEJhdGNoRGltKHNoYXBlOiBudW1iZXJbXSwgZGltc1RvU2tpcCA9IDIpOiBudW1iZXIge1xuICByZXR1cm4gc2l6ZUZyb21TaGFwZShzaGFwZS5zbGljZSgwLCBzaGFwZS5sZW5ndGggLSBkaW1zVG9Ta2lwKSk7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEFycmF5VXRpbCwgQnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmltcG9ydCB7IEdsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZSB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBzcXVlZXplU2hhcGUgfSBmcm9tICcuL3RleHR1cmUtbGF5b3V0LXN0cmF0ZWd5JztcbmltcG9ydCB7IFRleHR1cmVMYXlvdXQgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7XG4gIGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZSxcbiAgZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lQXRPdXRDb29yZHMsXG4gIGdldENvb3Jkc0RhdGFUeXBlLFxuICBnZXRHbENoYW5uZWxzLFxuICBnZXRTcXVlZXplZFBhcmFtcyxcbiAgc3F1ZWV6ZUlucHV0U2hhcGUsXG59IGZyb20gJy4vdXRpbHMnO1xuXG4vKipcbiAqIEdMU0wgTGlicmFyeSByZXNwb25zaWJsZSBmb3IgZGF0YSB0eXBlcyBhbmQgcm91dGluZXMgZm9yIG1hbmlwdWxhdGluZ1xuICogY29vcmRpbmF0ZXMgYW5kIG1hcHBpbmcgdG8vZnJvbSB0ZW5zb3IgaW5kaWNlc1xuICovXG5leHBvcnQgY2xhc3MgQ29vcmRzR2xzbExpYiBleHRlbmRzIEdsc2xMaWIge1xuICByZXR1cm5UeXBlOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMub2Zmc2V0VG9Db29yZHMoKSxcbiAgICAgIC4uLnRoaXMuY29vcmRzVG9PZmZzZXQoKSxcbiAgICAgIC4uLnRoaXMudG9WZWMoKSxcbiAgICAgIC4uLnRoaXMudmFsdWVGcm9tKCksXG4gICAgICAvLyBUT0RPIHJldHVybiB0aGVzZSBvbmx5IHdoZW4gcGFja2luZyBpcyBlbmFibGVkLlxuICAgICAgLi4udGhpcy5nZXRDb21tb25VdGlsRnVuY3MoKSxcbiAgICAgIC4uLnRoaXMuZ2V0SW5wdXRzU2FtcGxpbmdTbmlwcGV0cygpLFxuICAgICAgLi4udGhpcy5nZXRPdXRwdXRTYW1wbGluZ1NuaXBwZXQoKSxcbiAgICB9O1xuICB9XG4gIGdldEN1c3RvbVR5cGVzKCkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICAvKipcbiAgICogUHJvZHVjZXMgYSBmdW5jdGlvbiB0aGF0IGNhbiBtYXAgZnJvbVxuICAgKiAyRCBub3JtYWx6aWVkIGNvb3JkaW5hdGVzIChzLHQpIHRvIGEgZmxhdCBvZmZzZXRcbiAgICovXG4gIHByb3RlY3RlZCBvZmZzZXRUb0Nvb3JkcygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBmdW5jTmFtZSA9ICdvZmZzZXRUb0Nvb3Jkcyc7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9mZnNldFRvQ29vcmRzOiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgdmVjMiAke2Z1bmNOYW1lfShpbnQgb2Zmc2V0LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHtcbiAgICAgICAgaW50IHQgPSBvZmZzZXQgLyB3aWR0aDtcbiAgICAgICAgaW50IHMgPSBvZmZzZXQgLSB0KndpZHRoO1xuICAgICAgICB2ZWMyIGNvb3JkcyA9ICh2ZWMyKHMsdCkgKyB2ZWMyKDAuNSwwLjUpKSAvIHZlYzIod2lkdGgsIGhlaWdodCk7XG4gICAgICAgIHJldHVybiBjb29yZHM7XG4gICAgICB9XG4gICAgICBgKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2R1Y2VzIGEgZnVuY3Rpb24gdGhhdCBjYW4gbWFwIGZyb21cbiAgICogMkQgbm9ybWFsemllZCBjb29yZGluYXRlcyAocyx0KSB0byBhIGZsYXQgb2Zmc2V0XG4gICAqL1xuICBwcm90ZWN0ZWQgY29vcmRzVG9PZmZzZXQoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgZnVuY05hbWUgPSAnY29vcmRzVG9PZmZzZXQnO1xuICAgIHJldHVybiB7XG4gICAgICBjb29yZHNUb09mZnNldDogbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIGludCAke2Z1bmNOYW1lfSh2ZWMyIGNvb3JkcywgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7XG4gICAgICAgIGZsb2F0IHMgPSBjb29yZHMucyAqIGZsb2F0KHdpZHRoKTtcbiAgICAgICAgZmxvYXQgdCA9IGNvb3Jkcy50ICogZmxvYXQoaGVpZ2h0KTtcbiAgICAgICAgaW50IG9mZnNldCA9IGludCh0KSAqIHdpZHRoICsgaW50KHMpO1xuICAgICAgICByZXR1cm4gb2Zmc2V0O1xuICAgICAgfVxuICAgICAgYCksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgY29kZSBmb3Igb3V0cHV0IHNhbXBsZXIuXG4gICAqL1xuXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRTYW1wbGluZ1NuaXBwZXQoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgaWYgKG91dHB1dExheW91dC5pc1BhY2tlZCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0KG91dHB1dExheW91dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0KG91dHB1dExheW91dCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBjb2RlIGZvciBwYWNrZWQgb3V0cHV0IHNhbXBsZXIuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0KG91dHB1dExheW91dDogVGV4dHVyZUxheW91dCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dFNoYXBlID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgb3V0VGV4U2hhcGUgPSBbb3V0cHV0TGF5b3V0LndpZHRoLCBvdXRwdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICBjb25zdCBmdW5jTmFtZSA9ICdnZXRPdXRwdXRDb29yZHMnO1xuICAgIHN3aXRjaCAob3V0U2hhcGUubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFNjYWxhckNvb3JkcygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0UGFja2VkMURDb29yZHMob3V0U2hhcGUgYXMgW251bWJlcl0sIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0UGFja2VkMkRDb29yZHMob3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRQYWNrZWQzRENvb3JkcyhcbiAgICAgICAgICBvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRQYWNrZWRORENvb3JkcyhvdXRTaGFwZSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgfVxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgLy8gVE9ETyB3ZSBuZWVkIHRoaXMgdG8gcHJvcGVybHkgcmV0dXJuIGEgcGFja2VkIHZlYzQgZnJvbSBrZXJuZWxzLlxuICAgIC8vIFJlcGxhY2UgYWxsICd7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0JyB3aXRoICdzZXRPdXRwdXQocmVzdWx0KScgaW4gYWxsIGtlcm5lbHMuXG4gICAgY29uc3QgZmxvYXRUZXh0dXJlU2V0UkdCQVNvdXJjZSA9IGBcbiAgICAgIHZvaWQgc2V0T3V0cHV0KHZlYzQgdmFsKSB7XG4gICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmFsO1xuICAgICAgfVxuICAgIGA7XG4gICAgY29uc3QgZmxvYXRUZXh0dXJlU2V0UkdCQUZ1bmNOYW1lID0gJ2Zsb2F0VGV4dHVyZVNldFJHQkEnO1xuICAgIHJlc3VsdFtmbG9hdFRleHR1cmVTZXRSR0JBRnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGZsb2F0VGV4dHVyZVNldFJHQkFTb3VyY2UpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGNvZGUgZm9yIHVucGFja2VkIG91dHB1dCBzYW1wbGVyLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0KG91dHB1dExheW91dDogVGV4dHVyZUxheW91dCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dFNoYXBlID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgb3V0VGV4U2hhcGUgPSBbb3V0cHV0TGF5b3V0LndpZHRoLCBvdXRwdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICBjb25zdCBmdW5jTmFtZSA9ICdnZXRPdXRwdXRDb29yZHMnO1xuICAgIHN3aXRjaCAob3V0U2hhcGUubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFNjYWxhckNvb3JkcygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0VW5wYWNrZWQxRENvb3JkcyhvdXRTaGFwZSBhcyBbbnVtYmVyXSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDJEQ29vcmRzKFxuICAgICAgICAgIG91dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkM0RDb29yZHMoXG4gICAgICAgICAgb3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA0OlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDREQ29vcmRzKFxuICAgICAgICAgIG91dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA1OlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDVEQ29vcmRzKFxuICAgICAgICAgIG91dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDY6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkNkRDb29yZHMoXG4gICAgICAgICAgb3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBvdXRwdXQgZGltZW5zaW9uYWxpdHk6ICR7b3V0U2hhcGUubGVuZ3RofWApO1xuICAgIH1cbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIC8vIFRPRE8gd2UgbmVlZCB0aGlzIHRvIHByb3Blcmx5IHJldHVybiBhIHBhY2tlZCB2ZWM0IGZyb20ga2VybmVscy5cbiAgICAvLyBSZXBsYWNlIGFsbCAne2dsc2wub3V0cHV0fSA9IHJlc3VsdCcgd2l0aCAnc2V0T3V0cHV0KHJlc3VsdCknIGluIGFsbCBrZXJuZWxzLlxuICAgIGNvbnN0IGZsb2F0VGV4dHVyZVNldFJTb3VyY2UgPSBgXG4gICAgICAgIHZvaWQgc2V0T3V0cHV0KGZsb2F0IHZhbCkge1xuICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmVjNCh2YWwsIDAsIDAsIDApO1xuICAgICAgICB9XG4gICAgYDtcbiAgICBjb25zdCBmbG9hdFRleHR1cmVTZXRSRnVuY05hbWUgPSAnZmxvYXRUZXh0dXJlU2V0Uic7XG4gICAgcmVzdWx0W2Zsb2F0VGV4dHVyZVNldFJGdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoZmxvYXRUZXh0dXJlU2V0UlNvdXJjZSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTY2FsYXIgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFNjYWxhckNvb3JkcygpOiBHbHNsTGliUm91dGluZSB7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICBgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAxRCBwYWNrZWQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFBhY2tlZDFEQ29vcmRzKF9zaGFwZTogW251bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gdGV4U2hhcGU7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGlmIChwYWNrZWRUZXhTaGFwZVswXSA9PT0gMSkge1xuICAgICAgc291cmNlID0gYFxuICAgICAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgICByZXR1cm4gMiAqIGludChUZXhDb29yZHMueSAqICR7cGFja2VkVGV4U2hhcGVbMV19LjApO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgICB9XG5cbiAgICBpZiAocGFja2VkVGV4U2hhcGVbMV0gPT09IDEpIHtcbiAgICAgIHNvdXJjZSA9IGBcbiAgICAgICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgICAgcmV0dXJuIDIgKiBpbnQoVGV4Q29vcmRzLnggKiAke3BhY2tlZFRleFNoYXBlWzBdfS4wKTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gICAgfVxuXG4gICAgc291cmNlID0gYFxuICAgICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHtwYWNrZWRUZXhTaGFwZVswXX0sICR7cGFja2VkVGV4U2hhcGVbMV19KSk7XG4gICAgICAgICAgcmV0dXJuIDIgKiAocmVzVGV4UkMueSAqICR7cGFja2VkVGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueCk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIDJEIHBhY2tlZCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0UGFja2VkMkRDb29yZHMoc2hhcGU6IFtudW1iZXIsIG51bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBpZiAoQXJyYXlVdGlsLmFycmF5c0VxdWFsKHNoYXBlLCB0ZXhTaGFwZSkpIHtcbiAgICAgIHNvdXJjZSA9IGBcbiAgICAgICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIHJldHVybiAyICogaXZlYzIoVGV4Q29vcmRzLnh5ICogdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgICB9XG5cbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IHRleFNoYXBlO1xuICAgIC8vIHRleGVscyBuZWVkZWQgdG8gYWNjb21tb2RhdGUgYSBsb2dpY2FsIHJvd1xuICAgIGNvbnN0IHRleGVsc0luTG9naWNhbFJvdyA9IE1hdGguY2VpbChzaGFwZVsxXSAvIDIpO1xuXG4gICAgLyoqXG4gICAgICogZ2V0T3V0cHV0Q29vcmRzXG4gICAgICpcbiAgICAgKiByZXNUZXhSQzogVGhlIHJvd3MgYW5kIGNvbHVtbnMgb2YgdGhlIHRleGVscy4gSWYgeW91IG1vdmUgb3ZlciBvbmVcbiAgICAgKiB0ZXhlbCB0byB0aGUgcmlnaHQgaW4gdGhlIHBhY2tlZCB0ZXh0dXJlLCB5b3UgYXJlIG1vdmluZyBvdmVyIG9uZSBjb2x1bW5cbiAgICAgKiAobm90IHR3bykuXG4gICAgICpcbiAgICAgKiBpbmRleDogVGhlIHRleGVsIGluZGV4XG4gICAgICovXG4gICAgc291cmNlID0gYFxuICAgICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7cGFja2VkVGV4U2hhcGVbMF19LCAke3BhY2tlZFRleFNoYXBlWzFdfSkpO1xuXG4gICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7cGFja2VkVGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcblxuICAgICAgICAgIC8vIHJldmVyc2UgciBhbmQgYyBvcmRlciBmb3IgcGFja2VkIHRleHR1cmVcbiAgICAgICAgICBpbnQgciA9IGltb2QoaW5kZXgsICR7dGV4ZWxzSW5Mb2dpY2FsUm93fSkgKiAyO1xuICAgICAgICAgIGludCBjID0gMiAqIChpbmRleCAvICR7dGV4ZWxzSW5Mb2dpY2FsUm93fSk7XG5cbiAgICAgICAgICByZXR1cm4gaXZlYzIociwgYyk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIDNEIHBhY2tlZCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0UGFja2VkM0RDb29yZHMoc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSBbdGV4U2hhcGVbMF0sIHRleFNoYXBlWzFdXTtcbiAgICBjb25zdCB0ZXhlbHNJbkxvZ2ljYWxSb3cgPSBNYXRoLmNlaWwoc2hhcGVbMl0gLyAyKTtcbiAgICBjb25zdCB0ZXhlbHNJbkJhdGNoID0gdGV4ZWxzSW5Mb2dpY2FsUm93ICogTWF0aC5jZWlsKHNoYXBlWzFdIC8gMik7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBpdmVjMyBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7cGFja2VkVGV4U2hhcGVbMF19LCAke3BhY2tlZFRleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3BhY2tlZFRleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG5cbiAgICAgICAgICBpbnQgYiA9IGluZGV4IC8gJHt0ZXhlbHNJbkJhdGNofTtcbiAgICAgICAgICBpbmRleCAtPSBiICogJHt0ZXhlbHNJbkJhdGNofTtcblxuICAgICAgICAgIC8vIHJldmVyc2UgciBhbmQgYyBvcmRlciBmb3IgcGFja2VkIHRleHR1cmVcbiAgICAgICAgICBpbnQgciA9IGltb2QoaW5kZXgsICR7dGV4ZWxzSW5Mb2dpY2FsUm93fSkgKiAyO1xuICAgICAgICAgIGludCBjID0gMiAqIChpbmRleCAvICR7dGV4ZWxzSW5Mb2dpY2FsUm93fSk7XG5cbiAgICAgICAgICByZXR1cm4gaXZlYzMoYiwgciwgYyk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIE5EIHBhY2tlZCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0UGFja2VkTkRDb29yZHMoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IFt0ZXhTaGFwZVswXSwgdGV4U2hhcGVbMV1dO1xuXG4gICAgY29uc3QgdGV4ZWxzSW5Mb2dpY2FsUm93ID0gTWF0aC5jZWlsKHNoYXBlW3NoYXBlLmxlbmd0aCAtIDFdIC8gMik7XG4gICAgY29uc3QgdGV4ZWxzSW5CYXRjaCA9IHRleGVsc0luTG9naWNhbFJvdyAqIE1hdGguY2VpbChzaGFwZVtzaGFwZS5sZW5ndGggLSAyXSAvIDIpO1xuICAgIGxldCB0ZXhlbHNJbkJhdGNoTiA9IHRleGVsc0luQmF0Y2g7XG4gICAgbGV0IGJhdGNoZXMgPSAnJztcbiAgICBsZXQgY29vcmRzID0gJ2IsIHIsIGMnO1xuXG4gICAgZm9yIChsZXQgYiA9IDI7IGIgPCBzaGFwZS5sZW5ndGggLSAxOyBiKyspIHtcbiAgICAgIHRleGVsc0luQmF0Y2hOICo9IHNoYXBlW3NoYXBlLmxlbmd0aCAtIGIgLSAxXTtcbiAgICAgIGJhdGNoZXMgPVxuICAgICAgICBgXG4gICAgICBpbnQgYiR7Yn0gPSBpbmRleCAvICR7dGV4ZWxzSW5CYXRjaE59O1xuICAgICAgaW5kZXggLT0gYiR7Yn0gKiAke3RleGVsc0luQmF0Y2hOfTtcbiAgICBgICsgYmF0Y2hlcztcbiAgICAgIGNvb3JkcyA9IGBiJHtifSwgYCArIGNvb3JkcztcbiAgICB9XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgaXZlYyR7c2hhcGUubGVuZ3RofSBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHtwYWNrZWRUZXhTaGFwZVswXX0sICR7cGFja2VkVGV4U2hhcGVbMV19KSk7XG4gICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3BhY2tlZFRleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG5cbiAgICAgICAgJHtiYXRjaGVzfVxuXG4gICAgICAgIGludCBiID0gaW5kZXggLyAke3RleGVsc0luQmF0Y2h9O1xuICAgICAgICBpbmRleCAtPSBiICogJHt0ZXhlbHNJbkJhdGNofTtcblxuICAgICAgICAvLyByZXZlcnNlIHIgYW5kIGMgb3JkZXIgZm9yIHBhY2tlZCB0ZXh0dXJlXG4gICAgICAgIGludCByID0gaW1vZChpbmRleCwgJHt0ZXhlbHNJbkxvZ2ljYWxSb3d9KSAqIDI7XG4gICAgICAgIGludCBjID0gMiAqIChpbmRleCAvICR7dGV4ZWxzSW5Mb2dpY2FsUm93fSk7XG5cbiAgICAgICAgcmV0dXJuIGl2ZWMke3NoYXBlLmxlbmd0aH0oJHtjb29yZHN9KTtcbiAgICAgIH1cbiAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAxRCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQxRENvb3Jkcyhfc2hhcGU6IFtudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIHJldHVybiByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAyRCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQyRENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgICAgaW50IHIgPSBpbmRleCAvICR7c2hhcGVbMV19O1xuICAgICAgICAgIGludCBjID0gaW5kZXggLSByICogJHtzaGFwZVsxXX07XG4gICAgICAgICAgcmV0dXJuIGl2ZWMyKHIsIGMpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAzRCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQzRENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBsZXQgc291cmNlID0gJyc7XG4gICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICAgIGxldCBzdHJpZGVzID0gbnVsbDtcbiAgICBpZiAocmFuayA8IDIpIHtcbiAgICAgIHN0cmlkZXMgPSBbXTtcbiAgICB9XG5cbiAgICBzdHJpZGVzID0gbmV3IEFycmF5KHJhbmsgLSAxKTtcbiAgICBzdHJpZGVzW3JhbmsgLSAyXSA9IHNoYXBlW3JhbmsgLSAxXTtcbiAgICBmb3IgKGxldCBpID0gcmFuayAtIDM7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBzdHJpZGVzW2ldID0gc3RyaWRlc1tpICsgMV0gKiBzaGFwZVtpICsgMV07XG4gICAgfVxuICAgIGNvbnN0IGNvb3Jkc1RvQ29tcHV0ZSA9IFsncicsICdjJywgJ2QnXTtcbiAgICBjb25zdCBjb29yZHNGcm9tSW5kZXhTbmlwcGV0ID0gc3RyaWRlc1xuICAgICAgLm1hcCgoc3RyaWRlLCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IGxpbmUxID0gYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gPSBpbmRleCAvICR7c3RyaWRlfWA7XG4gICAgICAgIGNvbnN0IGxpbmUyID1cbiAgICAgICAgICBpID09PSBzdHJpZGVzLmxlbmd0aCAtIDFcbiAgICAgICAgICAgID8gYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpICsgMV19ID0gaW5kZXggLSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gXG4gICAgICAgICAgICA6IGBpbmRleCAtPSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gO1xuICAgICAgICByZXR1cm4gYCR7bGluZTF9OyAke2xpbmUyfTtgO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcnKTtcblxuICAgIHNvdXJjZSA9IGBcbiAgICAgICAgaXZlYzMgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgICAgICByZXR1cm4gaXZlYzMociwgYywgZCk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDREIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRVbnBhY2tlZDREQ29vcmRzKFxuICAgIHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSxcbiAgKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gICAgbGV0IHN0cmlkZXMgPSBudWxsO1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgc3RyaWRlcyA9IFtdO1xuICAgIH1cblxuICAgIHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayAtIDEpO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gc2hhcGVbcmFuayAtIDFdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMzsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHN0cmlkZXNbaV0gPSBzdHJpZGVzW2kgKyAxXSAqIHNoYXBlW2kgKyAxXTtcbiAgICB9XG4gICAgY29uc3QgY29vcmRzVG9Db21wdXRlID0gWydyJywgJ2MnLCAnZCcsICdkMiddO1xuICAgIGNvbnN0IGNvb3Jkc0Zyb21JbmRleFNuaXBwZXQgPSBzdHJpZGVzXG4gICAgICAubWFwKChzdHJpZGUsIGkpID0+IHtcbiAgICAgICAgY29uc3QgbGluZTEgPSBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2ldfSA9IGluZGV4IC8gJHtzdHJpZGV9YDtcbiAgICAgICAgY29uc3QgbGluZTIgPVxuICAgICAgICAgIGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMVxuICAgICAgICAgICAgPyBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2kgKyAxXX0gPSBpbmRleCAtICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWBcbiAgICAgICAgICAgIDogYGluZGV4IC09ICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWA7XG4gICAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJycpO1xuXG4gICAgc291cmNlID0gYFxuICAgICAgaXZlYzQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgICAgICByZXR1cm4gaXZlYzQociwgYywgZCwgZDIpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA1RCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQ1RENvb3JkcyhcbiAgICBzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSxcbiAgKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gICAgbGV0IHN0cmlkZXMgPSBudWxsO1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgc3RyaWRlcyA9IFtdO1xuICAgIH1cblxuICAgIHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayAtIDEpO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gc2hhcGVbcmFuayAtIDFdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMzsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHN0cmlkZXNbaV0gPSBzdHJpZGVzW2kgKyAxXSAqIHNoYXBlW2kgKyAxXTtcbiAgICB9XG4gICAgY29uc3QgY29vcmRzVG9Db21wdXRlID0gWydyJywgJ2MnLCAnZCcsICdkMicsICdkMyddO1xuICAgIGNvbnN0IGNvb3Jkc0Zyb21JbmRleFNuaXBwZXQgPSBzdHJpZGVzXG4gICAgICAubWFwKChzdHJpZGUsIGkpID0+IHtcbiAgICAgICAgY29uc3QgbGluZTEgPSBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2ldfSA9IGluZGV4IC8gJHtzdHJpZGV9YDtcbiAgICAgICAgY29uc3QgbGluZTIgPVxuICAgICAgICAgIGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMVxuICAgICAgICAgICAgPyBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2kgKyAxXX0gPSBpbmRleCAtICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWBcbiAgICAgICAgICAgIDogYGluZGV4IC09ICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWA7XG4gICAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJycpO1xuXG4gICAgc291cmNlID0gYFxuICAgICAgaXZlYzUgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgICAgICByZXR1cm4gaXZlYzUociwgYywgZCwgZDIsIGQzKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgNkQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkNkRDb29yZHMoXG4gICAgc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSxcbiAgKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gICAgbGV0IHN0cmlkZXMgPSBudWxsO1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgc3RyaWRlcyA9IFtdO1xuICAgIH1cblxuICAgIHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayAtIDEpO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gc2hhcGVbcmFuayAtIDFdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMzsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHN0cmlkZXNbaV0gPSBzdHJpZGVzW2kgKyAxXSAqIHNoYXBlW2kgKyAxXTtcbiAgICB9XG4gICAgY29uc3QgY29vcmRzVG9Db21wdXRlID0gWydyJywgJ2MnLCAnZCcsICdkMicsICdkMycsICdkNCddO1xuICAgIGNvbnN0IGNvb3Jkc0Zyb21JbmRleFNuaXBwZXQgPSBzdHJpZGVzXG4gICAgICAubWFwKChzdHJpZGUsIGkpID0+IHtcbiAgICAgICAgY29uc3QgbGluZTEgPSBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2ldfSA9IGluZGV4IC8gJHtzdHJpZGV9YDtcbiAgICAgICAgY29uc3QgbGluZTIgPVxuICAgICAgICAgIGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMVxuICAgICAgICAgICAgPyBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2kgKyAxXX0gPSBpbmRleCAtICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWBcbiAgICAgICAgICAgIDogYGluZGV4IC09ICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWA7XG4gICAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJycpO1xuXG4gICAgc291cmNlID0gYFxuICAgICBpdmVjNiBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgICAke2Nvb3Jkc0Zyb21JbmRleFNuaXBwZXR9XG4gICAgICAgICByZXR1cm4gaXZlYzYociwgYywgZCwgZDIsIGQzLCBkNCk7XG4gICAgICAgfVxuICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgY29kZSBmb3IgY29tbW9uIFVWIGNvb3JkcyBjb21wdXRhdGlvbiB1dGlsaXR5IGZ1bmN0aW9ucy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRDb21tb25VdGlsRnVuY3MoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgbGV0IGZ1bmNOYW1lID0gJ3V2RnJvbUZsYXQnO1xuICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgIHZlYzIgdXZGcm9tRmxhdChpbnQgdGV4TnVtUiwgaW50IHRleE51bUMsIGludCBpbmRleCkge1xuICAgICAgaW50IHRleEMgPSBpbmRleCAvIHRleE51bVI7XG4gICAgICBpbnQgdGV4UiA9IGluZGV4IC0gdGV4QyAqIHRleE51bVI7XG4gICAgICAvLyBUT0RPOiBzd2FwIHRleFIsIHRleEMgb3JkZXIgaW4gZm9sbG93aW5nIGZ1bmN0aW9uIHNvIHJvdyBpcyBjb3JyZXNwb25kaW5nIHRvIHUgYW5kIGNvbHVtbiBpcyBjb3JyZXNwb25kaW5nIHRvXG4gICAgICAvLyAgICAgICB2LlxuICAgICAgcmV0dXJuICh2ZWMyKHRleFIsIHRleEMpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtUiwgdGV4TnVtQyk7XG4gICAgfVxuICAgIGApO1xuICAgIGZ1bmNOYW1lID0gJ3BhY2tlZFVWZnJvbTFEJztcbiAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIHZlYzIgcGFja2VkVVZmcm9tMUQoaW50IHRleE51bVIsIGludCB0ZXhOdW1DLCBpbnQgaW5kZXgpIHtcbiAgICAgICAgaW50IHRleGVsSW5kZXggPSBpbmRleCAvIDI7XG4gICAgICAgIGludCB0ZXhSID0gdGV4ZWxJbmRleCAvIHRleE51bUM7XG4gICAgICAgIGludCB0ZXhDID0gdGV4ZWxJbmRleCAtIHRleFIgKiB0ZXhOdW1DO1xuICAgICAgICByZXR1cm4gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMih0ZXhOdW1DLCB0ZXhOdW1SKTtcbiAgICAgIH1cbiAgICAgIGApO1xuICAgIGZ1bmNOYW1lID0gJ3BhY2tlZFVWZnJvbTJEJztcbiAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIHZlYzIgcGFja2VkVVZmcm9tMkQoaW50IHRleE51bVIsIGludCB0ZXhOdW1DLCBpbnQgdGV4ZWxzSW5Mb2dpY2FsUm93LCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgIGludCB0ZXhlbEluZGV4ID0gKHJvdyAvIDIpICogdGV4ZWxzSW5Mb2dpY2FsUm93ICsgKGNvbCAvIDIpO1xuICAgICAgICBpbnQgdGV4UiA9IHRleGVsSW5kZXggLyB0ZXhOdW1DO1xuICAgICAgICBpbnQgdGV4QyA9IHRleGVsSW5kZXggLSB0ZXhSICogdGV4TnVtQztcbiAgICAgICAgcmV0dXJuICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtQywgdGV4TnVtUik7XG4gICAgICB9XG4gICAgICBgKTtcbiAgICBmdW5jTmFtZSA9ICdwYWNrZWRVVmZyb20zRCc7XG4gICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICB2ZWMyIHBhY2tlZFVWZnJvbTNEKGludCB0ZXhOdW1SLCBpbnQgdGV4TnVtQyxcbiAgICAgICAgICBpbnQgdGV4ZWxzSW5CYXRjaCwgaW50IHRleGVsc0luTG9naWNhbFJvdywgaW50IGIsXG4gICAgICAgICAgaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICBpbnQgaW5kZXggPSBiICogdGV4ZWxzSW5CYXRjaCArIChyb3cgLyAyKSAqIHRleGVsc0luTG9naWNhbFJvdyArIChjb2wgLyAyKTtcbiAgICAgICAgaW50IHRleFIgPSBpbmRleCAvIHRleE51bUM7XG4gICAgICAgIGludCB0ZXhDID0gaW5kZXggLSB0ZXhSICogdGV4TnVtQztcbiAgICAgICAgcmV0dXJuICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtQywgdGV4TnVtUik7XG4gICAgICB9XG4gICAgICBgKTtcbiAgICBmdW5jTmFtZSA9ICdzYW1wbGVUZXh0dXJlJztcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgICBmbG9hdCBzYW1wbGVUZXh0dXJlKHNhbXBsZXIyRCB0ZXh0dXJlU2FtcGxlciwgdmVjMiB1dikge1xuICAgICAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KHRleHR1cmVTYW1wbGVyLCB1dikucjtcbiAgICAgICAgfWApO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0aW5nIHNuaXBwZXRzIGZvciBpbnB1dHNcbiAgICovXG4gIHByb3RlY3RlZCBnZXRJbnB1dHNTYW1wbGluZ1NuaXBwZXRzKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIGNvbnN0IG91dHB1dExheW91dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKHNhbXBsZXJOYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBpbnB1dExheW91dCA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldO1xuICAgICAgY29uc3QgZnVuY05hbWUgPSBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWUoc2FtcGxlck5hbWUpO1xuICAgICAgaWYgKGlucHV0TGF5b3V0LmlzUGFja2VkKSB7XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldFBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIHNhbXBsZXJOYW1lLCBpbnB1dExheW91dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIHNhbXBsZXJOYW1lLCBpbnB1dExheW91dCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG91dENvb3JkRnVuY05hbWUgPSBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWVBdE91dENvb3JkcyhzYW1wbGVyTmFtZSk7XG4gICAgICBpZiAoaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGggPD0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoKSB7XG4gICAgICAgIGlmIChpbnB1dExheW91dC5pc1BhY2tlZCkge1xuICAgICAgICAgIHJlc3VsdFtvdXRDb29yZEZ1bmNOYW1lXSA9IHRoaXMuZ2V0UGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKFxuICAgICAgICAgICAgb3V0Q29vcmRGdW5jTmFtZSxcbiAgICAgICAgICAgIGlucHV0TGF5b3V0LFxuICAgICAgICAgICAgb3V0cHV0TGF5b3V0LFxuICAgICAgICAgICAgc2FtcGxlck5hbWUsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXN1bHRbb3V0Q29vcmRGdW5jTmFtZV0gPSB0aGlzLmdldFVucGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKFxuICAgICAgICAgICAgb3V0Q29vcmRGdW5jTmFtZSxcbiAgICAgICAgICAgIGlucHV0TGF5b3V0LFxuICAgICAgICAgICAgb3V0cHV0TGF5b3V0LFxuICAgICAgICAgICAgc2FtcGxlck5hbWUsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rpbmcgc25pcHBldHMgZm9yIG91dHB1dCBjb29yZGluYXRlcyBvZiBzYW1wbGVyc1xuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXJBdE91dHB1dENvb3JkcyhcbiAgICBmdW5jTmFtZTogc3RyaW5nLFxuICAgIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIG91dHB1dExheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBpblNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBvdXRTaGFwZSA9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHRleE5hbWUgPSBuYW1lO1xuICAgIGNvbnN0IHRleEZ1bmNTbmlwcGV0ID0gZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lKHRleE5hbWUpO1xuXG4gICAgY29uc3QgaW5SYW5rID0gaW5TaGFwZS5sZW5ndGg7XG4gICAgY29uc3Qgb3V0UmFuayA9IG91dFNoYXBlLmxlbmd0aDtcblxuICAgIGNvbnN0IGJyb2FkY2FzdERpbXMgPSBCcm9hZGNhc3RVdGlsLmdldEJyb2FkY2FzdERpbXMoaW5TaGFwZSwgb3V0U2hhcGUpO1xuXG4gICAgY29uc3QgdHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKG91dFJhbmspO1xuICAgIGNvbnN0IHJhbmtEaWZmID0gb3V0UmFuayAtIGluUmFuaztcbiAgICBsZXQgY29vcmRzU25pcHBldDogc3RyaW5nO1xuICAgIGNvbnN0IGZpZWxkcyA9IGdldEdsQ2hhbm5lbHMoKTtcblxuICAgIGlmIChpblJhbmsgPT09IDApIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSAnJztcbiAgICB9IGVsc2UgaWYgKG91dFJhbmsgPCAyICYmIGJyb2FkY2FzdERpbXMubGVuZ3RoID49IDEpIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSAnY29vcmRzID0gMDsnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb29yZHNTbmlwcGV0ID0gYnJvYWRjYXN0RGltcy5tYXAoKGQpID0+IGBjb29yZHMuJHtmaWVsZHNbZCArIHJhbmtEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICAgIH1cbiAgICBsZXQgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJyc7XG4gICAgaWYgKG91dFJhbmsgPCAyICYmIGluUmFuayA+IDApIHtcbiAgICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9ICdjb29yZHMnO1xuICAgIH0gZWxzZSB7XG4gICAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSBpblNoYXBlLm1hcCgoX3MsIGkpID0+IGBjb29yZHMuJHtmaWVsZHNbaSArIHJhbmtEaWZmXX1gKS5qb2luKCcsICcpO1xuICAgIH1cblxuICAgIGxldCBvdXRwdXQgPSAncmV0dXJuIG91dHB1dFZhbHVlOyc7XG4gICAgY29uc3QgaW5TaXplID0gU2hhcGVVdGlsLnNpemUoaW5TaGFwZSk7XG4gICAgY29uc3QgaXNJbnB1dFNjYWxhciA9IGluU2l6ZSA9PT0gMTtcbiAgICBjb25zdCBvdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0U2hhcGUpO1xuICAgIGNvbnN0IGlzT3V0cHV0U2NhbGFyID0gb3V0U2l6ZSA9PT0gMTtcblxuICAgIGlmIChpblJhbmsgPT09IDEgJiYgIWlzSW5wdXRTY2FsYXIgJiYgIWlzT3V0cHV0U2NhbGFyKSB7XG4gICAgICBvdXRwdXQgPSBgXG4gICAgICAgIHJldHVybiB2ZWM0KG91dHB1dFZhbHVlLnh5LCBvdXRwdXRWYWx1ZS54eSk7XG4gICAgICBgO1xuICAgIH0gZWxzZSBpZiAoaXNJbnB1dFNjYWxhciAmJiAhaXNPdXRwdXRTY2FsYXIpIHtcbiAgICAgIGlmIChvdXRSYW5rID09PSAxKSB7XG4gICAgICAgIG91dHB1dCA9IGBcbiAgICAgICAgICByZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54LCBvdXRwdXRWYWx1ZS54LCAwLiwgMC4pO1xuICAgICAgICBgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0ID0gYFxuICAgICAgICAgIHJldHVybiB2ZWM0KG91dHB1dFZhbHVlLngpO1xuICAgICAgICBgO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoYnJvYWRjYXN0RGltcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHJvd3MgPSBpblJhbmsgLSAyO1xuICAgICAgY29uc3QgY29scyA9IGluUmFuayAtIDE7XG5cbiAgICAgIGlmIChicm9hZGNhc3REaW1zLmluZGV4T2Yocm93cykgPiAtMSAmJiBicm9hZGNhc3REaW1zLmluZGV4T2YoY29scykgPiAtMSkge1xuICAgICAgICBvdXRwdXQgPSAncmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCk7JztcbiAgICAgIH0gZWxzZSBpZiAoYnJvYWRjYXN0RGltcy5pbmRleE9mKHJvd3MpID4gLTEpIHtcbiAgICAgICAgb3V0cHV0ID0gJ3JldHVybiB2ZWM0KG91dHB1dFZhbHVlLngsIG91dHB1dFZhbHVlLnksICcgKyAnb3V0cHV0VmFsdWUueCwgb3V0cHV0VmFsdWUueSk7JztcbiAgICAgIH0gZWxzZSBpZiAoYnJvYWRjYXN0RGltcy5pbmRleE9mKGNvbHMpID4gLTEpIHtcbiAgICAgICAgb3V0cHV0ID0gJ3JldHVybiB2ZWM0KG91dHB1dFZhbHVlLnh4LCBvdXRwdXRWYWx1ZS56eik7JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzd2FwTGFzdERpbXNTbmlwcGV0ID0gYFxuICAgICAgICBpbnQgbGFzdERpbSA9IGNvb3Jkcy4ke2ZpZWxkc1tvdXRSYW5rIC0gMV19O1xuICAgICAgICBjb29yZHMuJHtmaWVsZHNbb3V0UmFuayAtIDFdfSA9IGNvb3Jkcy4ke2ZpZWxkc1tvdXRSYW5rIC0gMl19O1xuICAgICAgICBjb29yZHMuJHtmaWVsZHNbb3V0UmFuayAtIDJdfSA9IGxhc3REaW07XG4gICAgICBgO1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgIHZlYzQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICR7dHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgICAgICR7c3dhcExhc3REaW1zU25pcHBldH1cbiAgICAgICAgJHtjb29yZHNTbmlwcGV0fVxuICAgICAgICB2ZWM0IG91dHB1dFZhbHVlID0gJHt0ZXhGdW5jU25pcHBldH0oJHt1bnBhY2tlZENvb3Jkc1NuaXBwZXR9KTtcbiAgICAgICAgJHtvdXRwdXR9XG4gICAgICB9XG4gICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5nZXRPdXRwdXRDb29yZHMnXSk7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0aW5nIHNuaXBwZXRzIGZvciB1bnBhY2tlZCBvdXRwdXQgY29vcmRpbmF0ZXMgb2Ygc2FtcGxlcnNcbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXJBdE91dHB1dENvb3JkcyhcbiAgICBmdW5jTmFtZTogc3RyaW5nLFxuICAgIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIG91dHB1dExheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBvdXRUZXhTaGFwZSA9IFtvdXRwdXRMYXlvdXQud2lkdGgsIG91dHB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IGluVGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQud2lkdGgsIGlucHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgaW5SYW5rID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGg7XG4gICAgY29uc3Qgb3V0UmFuayA9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBpblNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBvdXRTaGFwZSA9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHRleEZ1bmNTbmlwcGV0ID0gZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lKG5hbWUpO1xuXG4gICAgaWYgKGluUmFuayA9PT0gb3V0UmFuayAmJiBBcnJheVV0aWwuYXJyYXlzRXF1YWwoaW5UZXhTaGFwZSwgb3V0VGV4U2hhcGUpKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCBUZXhDb29yZHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgdHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKG91dFJhbmspO1xuICAgIGNvbnN0IGJyb2FkY2FzdERpbXMgPSBCcm9hZGNhc3RVdGlsLmdldEJyb2FkY2FzdERpbXMoaW5TaGFwZSwgb3V0U2hhcGUpO1xuICAgIGNvbnN0IHJhbmtEaWZmID0gb3V0UmFuayAtIGluUmFuaztcbiAgICBsZXQgY29vcmRzU25pcHBldDogc3RyaW5nO1xuICAgIGNvbnN0IGZpZWxkcyA9IGdldEdsQ2hhbm5lbHMoKTtcblxuICAgIGlmIChpblJhbmsgPT09IDApIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSAnJztcbiAgICB9IGVsc2UgaWYgKG91dFJhbmsgPCAyICYmIGJyb2FkY2FzdERpbXMubGVuZ3RoID49IDEpIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSAnY29vcmRzID0gMDsnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb29yZHNTbmlwcGV0ID0gYnJvYWRjYXN0RGltcy5tYXAoKGQpID0+IGBjb29yZHMuJHtmaWVsZHNbZCArIHJhbmtEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICAgIH1cbiAgICBsZXQgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJyc7XG4gICAgaWYgKG91dFJhbmsgPCAyICYmIGluUmFuayA+IDApIHtcbiAgICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9ICdjb29yZHMnO1xuICAgIH0gZWxzZSB7XG4gICAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlLm1hcCgoX3MsIGkpID0+IGBjb29yZHMuJHtmaWVsZHNbaSArIHJhbmtEaWZmXX1gKS5qb2luKCcsICcpO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KCkge1xuICAgICAgICAgICR7dHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgICAgICAgJHtjb29yZHNTbmlwcGV0fVxuICAgICAgICAgIHJldHVybiAke3RleEZ1bmNTbmlwcGV0fSgke3VucGFja2VkQ29vcmRzU25pcHBldH0pO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLmdldE91dHB1dENvb3JkcyddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rpbmcgc25pcHBldHMgZm9yIHBhY2tlZCBvcGVyYXRpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBzd2l0Y2ggKGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZFNhbXBsZXJTY2FsYXIoZnVuY05hbWUsIG5hbWUpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYWNrZWRTYW1wbGVyMUQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkU2FtcGxlcjJEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZFNhbXBsZXIzRChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkU2FtcGxlck5EKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdGluZyBzbmlwcGV0cyBmb3IgdW5wYWNrZWQgb3BlcmF0aW9ucy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgc3dpdGNoIChzaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyU2NhbGFyKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjFEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjJEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDQ6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjREKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDU6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjVEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDY6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjZEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyBUT0RPIHN1cHBvcnQgbW9yZSBkaW1lbnNpb25hbGl0aWVzXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgZGltZW5zaW9uICR7c2hhcGUubGVuZ3RofS1EYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhY2tlZCBzY2FsYXIgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyU2NhbGFyKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICB2ZWM0ICR7ZnVuY05hbWV9KCkge1xuICAgICAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIGhhbGZDUik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYWNrZWQgMUQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyMUQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCB0ZXhTaGFwZSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IFt0ZXhTaGFwZVsxXSwgdGV4U2hhcGVbMF1dO1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oaW50IGluZGV4KSB7XG4gICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tMUQoXG4gICAgICAke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0sIGluZGV4KTtcbiAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCB1dik7XG4gICAgfWA7XG4gICAgY29uc3Qgc291cmNlID0gcGFja2VkU2FtcGxlcjtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5wYWNrZWRVVmZyb20xRCddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYWNrZWQgMkQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyMkQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3QgdGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQud2lkdGgsIGlucHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICBjb25zdCB0ZXhOdW1SID0gdGV4U2hhcGVbMF07XG4gICAgY29uc3QgdGV4TnVtQyA9IHRleFNoYXBlWzFdO1xuXG4gICAgaWYgKHRleFNoYXBlICE9IG51bGwgJiYgQXJyYXlVdGlsLmFycmF5c0VxdWFsKHNoYXBlLCB0ZXhTaGFwZSkpIHtcbiAgICAgIGNvbnN0IHBhY2tlZFNhbXBsZXIgPSBgdmVjNCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgIHZlYzIgdXYgPSAodmVjMihjb2wsIHJvdykgKyBoYWxmQ1IpIC8gdmVjMigke3RleE51bUN9LjAsICR7dGV4TnVtUn0uMCk7XG4gICAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCB1dik7XG4gICAgICB9YDtcblxuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShwYWNrZWRTYW1wbGVyKTtcbiAgICB9XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSB0ZXhTaGFwZTtcbiAgICBjb25zdCB2YWx1ZXNQZXJSb3cgPSBNYXRoLmNlaWwoc2hhcGVbMV0gLyAyKTtcbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgdmVjMiB1diA9IHBhY2tlZFVWZnJvbTJEKCR7cGFja2VkVGV4U2hhcGVbMV19LCAke3BhY2tlZFRleFNoYXBlWzBdfSwgJHt2YWx1ZXNQZXJSb3d9LCByb3csIGNvbCk7XG4gICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgdXYpO1xuICAgIH1gO1xuICAgIGNvbnN0IHNvdXJjZSA9IHBhY2tlZFNhbXBsZXI7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMucGFja2VkVVZmcm9tMkQnXSk7XG4gIH1cblxuICAvKipcbiAgICogUGFja2VkIDNEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHRleFNoYXBlID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gW3RleFNoYXBlWzBdLCB0ZXhTaGFwZVsxXV07XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcblxuICAgIGlmIChzaGFwZVswXSA9PT0gMSkge1xuICAgICAgY29uc3Qgc3F1ZWV6ZWRTaGFwZSA9IHNoYXBlLnNsaWNlKDEpO1xuICAgICAgY29uc3Qga2VwdERpbXMgPSBbMSwgMl07XG4gICAgICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIHNxdWVlemVkU2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydiJywgJ3JvdycsICdjb2wnXTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG4gICAgICBjb25zdCBzYW1wbGVyUm91dGluZSA9IHRoaXMuZ2V0UGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgbmFtZSwgbmV3SW5wdXRMYXlvdXQpO1xuICAgICAgY29uc3QgcGFja2VkU2FtcGxlciA9IGAke3NhbXBsZXJSb3V0aW5lLnJvdXRpbmVCb2R5fVxuICAgICAgdmVjNCAke2Z1bmNOYW1lfShpbnQgYiwgaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgfSBgO1xuICAgICAgY29uc3Qgc291cmNlID0gcGFja2VkU2FtcGxlcjtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBzYW1wbGVyUm91dGluZS5kZXBlbmRlbmNpZXMpO1xuICAgIH1cbiAgICBjb25zdCB0ZXhOdW1SID0gcGFja2VkVGV4U2hhcGVbMF07XG4gICAgY29uc3QgdGV4TnVtQyA9IHBhY2tlZFRleFNoYXBlWzFdO1xuXG4gICAgY29uc3QgdmFsdWVzUGVyUm93ID0gTWF0aC5jZWlsKHNoYXBlWzJdIC8gMik7XG4gICAgY29uc3QgdGV4ZWxzSW5CYXRjaCA9IHZhbHVlc1BlclJvdyAqIE1hdGguY2VpbChzaGFwZVsxXSAvIDIpO1xuXG4gICAgY29uc3QgcGFja2VkU2FtcGxlciA9IGB2ZWM0ICR7ZnVuY05hbWV9KGludCBiLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tM0QoXG4gICAgICAgICR7dGV4TnVtQ30sICR7dGV4TnVtUn0sICR7dGV4ZWxzSW5CYXRjaH0sICR7dmFsdWVzUGVyUm93fSwgYiwgcm93LCBjb2wpO1xuICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIHV2KTt9YDtcbiAgICBjb25zdCBzb3VyY2UgPSBwYWNrZWRTYW1wbGVyO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnBhY2tlZFVWZnJvbTNEJ10pO1xuICB9XG4gIC8qXG4gICAqIFBhY2tlZCBORCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXJORChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHRleFNoYXBlID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IFt0ZXhTaGFwZVswXSwgdGV4U2hhcGVbMV1dO1xuICAgIGNvbnN0IHRleE51bVIgPSBwYWNrZWRUZXhTaGFwZVsxXTtcbiAgICBjb25zdCB0ZXhOdW1DID0gcGFja2VkVGV4U2hhcGVbMF07XG4gICAgY29uc3QgdmFsdWVzUGVyUm93ID0gTWF0aC5jZWlsKHNoYXBlW3JhbmsgLSAxXSAvIDIpO1xuICAgIGxldCB0ZXhlbHNJbkJhdGNoID0gdmFsdWVzUGVyUm93ICogTWF0aC5jZWlsKHNoYXBlW3JhbmsgLSAyXSAvIDIpO1xuICAgIGxldCBwYXJhbXMgPSAnaW50IGIsIGludCByb3csIGludCBjb2wnO1xuICAgIGxldCBpbmRleCA9IGBiICogJHt0ZXhlbHNJbkJhdGNofSArIChyb3cgLyAyKSAqICR7dmFsdWVzUGVyUm93fSArIChjb2wgLyAyKWA7XG4gICAgZm9yIChsZXQgYiA9IDI7IGIgPCByYW5rIC0gMTsgYisrKSB7XG4gICAgICBwYXJhbXMgPSBgaW50IGIke2J9LCBgICsgcGFyYW1zO1xuICAgICAgdGV4ZWxzSW5CYXRjaCAqPSBzaGFwZVtyYW5rIC0gYiAtIDFdO1xuICAgICAgaW5kZXggPSBgYiR7Yn0gKiAke3RleGVsc0luQmF0Y2h9ICsgYCArIGluZGV4O1xuICAgIH1cbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oJHtwYXJhbXN9KSB7XG4gICAgICBpbnQgaW5kZXggPSAke2luZGV4fTtcbiAgICAgIGludCB0ZXhSID0gaW5kZXggLyAke3RleE51bUN9O1xuICAgICAgaW50IHRleEMgPSBpbmRleCAtIHRleFIgKiAke3RleE51bUN9O1xuICAgICAgdmVjMiB1diA9ICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIoJHt0ZXhOdW1DfSwgJHt0ZXhOdW1SfSk7XG4gICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgdXYpO1xuICAgIH1gO1xuICAgIGNvbnN0IHNvdXJjZSA9IHBhY2tlZFNhbXBsZXI7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIHNjYWxhciBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlclNjYWxhcihmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IFt0ZXhOdW1SLCB0ZXhOdW1DXSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBpZiAodGV4TnVtUiA9PT0gMSAmJiB0ZXhOdW1DID09PSAxKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCBoYWxmQ1IpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgICBpbnQgb2Zmc2V0XyR7bmFtZX0gPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7dGV4TnVtUn0sICR7dGV4TnVtQ30pO1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIG9mZnNldF8ke25hbWV9KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFtcbiAgICAgICdjb29yZGluYXRlcy51dkZyb21GbGF0JyxcbiAgICAgICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJyxcbiAgICAgICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCcsXG4gICAgXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgMUQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXIxRChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHROdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdE51bUMgPSBpbnB1dExheW91dC5oZWlnaHQ7XG5cbiAgICBpZiAodE51bUMgPT09IDEgJiYgdE51bVIgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGluZGV4KSB7XG4gICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgaGFsZkNSKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgaWYgKHROdW1DID09PSAxKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGluZGV4KSB7XG4gICAgICAgICAgICB2ZWMyIHV2ID0gdmVjMigoZmxvYXQoaW5kZXgpICsgMC41KSAvICR7dE51bVJ9LjAsIDAuNSk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG4gICAgaWYgKHROdW1SID09PSAxKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGluZGV4KSB7XG4gICAgICAgICAgICB2ZWMyIHV2ID0gdmVjMigwLjUsIChmbG9hdChpbmRleCkgKyAwLjUpIC8gJHt0TnVtQ30uMCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3ROdW1SfSwgJHt0TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDJEIHNuaXBwZXQuXG4gICAqL1xuXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXIyRChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcblxuICAgIC8vIFRPRE86IG1vZGlmeSByb3cvY29sIG9yZGVyIGZvciBvdGhlciBkaW1lbnNpb25zLlxuICAgIGNvbnN0IHRleFNoYXBlID0gW2lucHV0TGF5b3V0LmhlaWdodCwgaW5wdXRMYXlvdXQud2lkdGhdO1xuXG4gICAgaWYgKHRleFNoYXBlICE9IG51bGwgJiYgQXJyYXlVdGlsLmFycmF5c0VxdWFsKHNoYXBlLCB0ZXhTaGFwZSkpIHtcbiAgICAgIGNvbnN0IHRleE51bVIgPSB0ZXhTaGFwZVsxXTtcbiAgICAgIGNvbnN0IHRleE51bUMgPSB0ZXhTaGFwZVswXTtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICB2ZWMyIHV2ID0gKHZlYzIocm93LCBjb2wpICsgaGFsZkNSKSAvIHZlYzIoJHt0ZXhOdW1SfS4wLCAke3RleE51bUN9LjApO1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBuZXdTaGFwZSwga2VwdERpbXMgfSA9IHNxdWVlemVTaGFwZShzaGFwZSBhcyBudW1iZXJbXSk7XG4gICAgY29uc3Qgc3F1ZWV6ZWRTaGFwZSA9IG5ld1NoYXBlO1xuICAgIGlmIChzcXVlZXplZFNoYXBlLmxlbmd0aCA8IHNoYXBlLmxlbmd0aCkge1xuICAgICAgY29uc3QgbmV3SW5wdXRTaGFwZSA9IHNxdWVlemVJbnB1dFNoYXBlKHNoYXBlLCBzcXVlZXplZFNoYXBlKTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IFsnY29sJywgJ3JvdyddO1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgICR7dGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIG5hbWUsIG5ld0lucHV0TGF5b3V0KS5yb3V0aW5lQm9keX1cbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgdGV4TnVtUiA9IHRleFNoYXBlWzFdO1xuICAgIGNvbnN0IHRleE51bUMgPSB0ZXhTaGFwZVswXTtcbiAgICBpZiAodGV4TnVtQyA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIGludCBvZmZzZXRfJHtuYW1lfSA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSk7XG4gICAgICAgICAgICBmbG9hdCBpbmRleCA9IGRvdCh2ZWMzKHJvdywgY29sLCBvZmZzZXRfJHtuYW1lfSksIHZlYzMoJHtzaGFwZVsxXX0sIDEsIDEpKTtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKDAuNSwgKGluZGV4ICsgMC41KSAvICR7dGV4TnVtUn0uMCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgICB9XG5cbiAgICBpZiAodGV4TnVtUiA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIGludCBvZmZzZXRfJHtuYW1lfSA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSk7XG4gICAgICAgICAgICBmbG9hdCBpbmRleCA9IGRvdCh2ZWMzKHJvdywgY29sLCBvZmZzZXRfJHtuYW1lfSksIHZlYzMoJHtzaGFwZVsxXX0sIDEsIDEpKTtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKChpbmRleCArIDAuNSkgLyAke3RleE51bUN9LjAsIDAuNSk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICBpbnQgaW5kZXggPSBjb2wgKiAke3NoYXBlWzFdfSArIHJvdztcbiAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3RleE51bVJ9LCAke3RleE51bUN9LCBpbmRleCk7XG4gICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbXG4gICAgICAnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsXG4gICAgICAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsXG4gICAgICAnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnLFxuICAgIF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDNEIHNuaXBwZXQuXG4gICAqL1xuXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXIzRChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBzdHJpZGUwID0gc2hhcGVbMV0gKiBzaGFwZVsyXTtcbiAgICBjb25zdCBzdHJpZGUxID0gc2hhcGVbMl07XG5cbiAgICBjb25zdCB7IG5ld1NoYXBlLCBrZXB0RGltcyB9ID0gc3F1ZWV6ZVNoYXBlKHNoYXBlIGFzIG51bWJlcltdKTtcbiAgICBjb25zdCBzcXVlZXplZFNoYXBlID0gbmV3U2hhcGU7XG4gICAgaWYgKHNxdWVlemVkU2hhcGUubGVuZ3RoIDwgc2hhcGUubGVuZ3RoKSB7XG4gICAgICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIHNxdWVlemVkU2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydiYXRjaCcsICdjb2wnLCAncm93J107XG4gICAgICAvLyBEZWVwIGNvcHkgb2YgaW5wdXQgdGV4dHVyZSBsYXlvdXQuXG4gICAgICBjb25zdCBuZXdJbnB1dExheW91dDogVGV4dHVyZUxheW91dCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaW5wdXRMYXlvdXQpKTtcbiAgICAgIG5ld0lucHV0TGF5b3V0LnVucGFja2VkU2hhcGUgPSBuZXdJbnB1dFNoYXBlO1xuICAgICAgY29uc3Qgcm91dGluZSA9IHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCk7XG4gICAgICAvLyBUT0RPOiByZXZpc2l0IHRoZSBsb2dpYyBoZXJlIHRvIG1ha2UgaXQgc2ltcGxlclxuICAgICAgY29uc3QgcmV2RGltcyA9IGtlcHREaW1zLnJldmVyc2UoKTtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICAke3JvdXRpbmUucm91dGluZUJvZHl9XG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGJhdGNoLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIHJldkRpbXMpfSk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIHJvdXRpbmUuZGVwZW5kZW5jaWVzKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGRlcHRoLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICAvLyBFeHBsaWNpdGx5IHVzZSBpbnRlZ2VyIG9wZXJhdGlvbnMgYXMgZG90KCkgb25seSB3b3JrcyBvbiBmbG9hdHMuXG4gICAgICAgICAgICBpbnQgaW5kZXggPSBkZXB0aCAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICsgcm93O1xuICAgICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSwgaW5kZXgpO1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFtcbiAgICAgICdjb29yZGluYXRlcy51dkZyb21GbGF0JyxcbiAgICAgICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJyxcbiAgICAgICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCcsXG4gICAgXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgNEQgc25pcHBldC5cbiAgICovXG5cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjREKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHN0cmlkZTIgPSBzaGFwZVszXTtcbiAgICBjb25zdCBzdHJpZGUxID0gc2hhcGVbMl0gKiBzdHJpZGUyO1xuICAgIGNvbnN0IHN0cmlkZTAgPSBzaGFwZVsxXSAqIHN0cmlkZTE7XG5cbiAgICAvL1xuICAgIC8vIFRPRE86IHJlLWVuYWJsZSB0aGlzIHNob3J0Y3V0IG9uY2UgdGhlIGluZGV4IGNhbGN1bGF0aW9uIGJ1ZyBpcyBmaXhlZC5cbiAgICAvL1xuICAgIC8vIGNvbnN0IHtuZXdTaGFwZSwga2VwdERpbXN9ID0gc3F1ZWV6ZVNoYXBlKHNoYXBlIGFzIG51bWJlcltdKTtcbiAgICAvLyBpZiAobmV3U2hhcGUubGVuZ3RoIDwgc2hhcGUubGVuZ3RoKSB7XG4gICAgLy8gICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIG5ld1NoYXBlKTtcbiAgICAvLyAgIGNvbnN0IHBhcmFtcyA9IFsncm93JywgJ2NvbCcsICdkZXB0aCcsICdkZXB0aDInXTtcbiAgICAvLyAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAvLyAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgIC8vICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG4gICAgLy8gICBjb25zdCBzb3VyY2UgPSBgXG4gICAgLy8gICAgICAgJHt0aGlzLmdldFVucGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgbmFtZSwgbmV3SW5wdXRMYXlvdXQpLnJvdXRpbmVCb2R5fVxuICAgIC8vICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMikge1xuICAgIC8vICAgICAgICAgcmV0dXJuICR7ZnVuY05hbWV9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMocGFyYW1zLCBrZXB0RGltcyl9KTtcbiAgICAvLyAgICAgICB9XG4gICAgLy8gICAgIGA7XG4gICAgLy8gICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKFxuICAgIC8vICAgICAgIHNvdXJjZSwgWydjb29yZGluYXRlcy51dkZyb21GbGF0JywgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLCAnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnXSk7XG4gICAgLy8gfVxuXG4gICAgY29uc3QgdGV4TnVtUiA9IGlucHV0TGF5b3V0LndpZHRoO1xuICAgIGNvbnN0IHRleE51bUMgPSBpbnB1dExheW91dC5oZWlnaHQ7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIpIHtcbiAgICAgICAgICBpbnQgaW5kZXggPSByb3cgKiAke3N0cmlkZTB9ICsgY29sICogJHtzdHJpZGUxfSArXG4gICAgICAgICAgICAgIGRlcHRoMiAqICR7c3RyaWRlMn0gKyBkZXB0aDtcbiAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3RleE51bVJ9LCAke3RleE51bUN9LCBpbmRleCk7XG4gICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLCAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA1RCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjVEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHN0cmlkZTMgPSBzaGFwZVs0XTtcbiAgICBjb25zdCBzdHJpZGUyID0gc2hhcGVbM10gKiBzdHJpZGUzO1xuICAgIGNvbnN0IHN0cmlkZTEgPSBzaGFwZVsyXSAqIHN0cmlkZTI7XG4gICAgY29uc3Qgc3RyaWRlMCA9IHNoYXBlWzFdICogc3RyaWRlMTtcblxuICAgIGNvbnN0IHsgbmV3U2hhcGUsIGtlcHREaW1zIH0gPSBzcXVlZXplU2hhcGUoc2hhcGUgYXMgbnVtYmVyW10pO1xuICAgIGlmIChuZXdTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgbmV3U2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydyb3cnLCAnY29sJywgJ2RlcHRoJywgJ2RlcHRoMicsICdkZXB0aDMnXTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG5cbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICAke3RoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCkucm91dGluZUJvZHl9XG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLCAnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCddKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMiwgaW50IGRlcHRoMykge1xuICAgICAgICAgIGludCBpbmRleCA9IHJvdyAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICsgZGVwdGggKiAke3N0cmlkZTJ9ICtcbiAgICAgICAgICBkZXB0aDMgKiAke3N0cmlkZTN9ICsgZGVwdGgyO1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy51dkZyb21GbGF0J10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDZEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyNkQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgc3RyaWRlNCA9IHNoYXBlWzVdO1xuICAgIGNvbnN0IHN0cmlkZTMgPSBzaGFwZVs0XSAqIHN0cmlkZTQ7XG4gICAgY29uc3Qgc3RyaWRlMiA9IHNoYXBlWzNdICogc3RyaWRlMztcbiAgICBjb25zdCBzdHJpZGUxID0gc2hhcGVbMl0gKiBzdHJpZGUyO1xuICAgIGNvbnN0IHN0cmlkZTAgPSBzaGFwZVsxXSAqIHN0cmlkZTE7XG5cbiAgICBjb25zdCB7IG5ld1NoYXBlLCBrZXB0RGltcyB9ID0gc3F1ZWV6ZVNoYXBlKHNoYXBlIGFzIG51bWJlcltdKTtcbiAgICBpZiAobmV3U2hhcGUubGVuZ3RoIDwgc2hhcGUubGVuZ3RoKSB7XG4gICAgICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIG5ld1NoYXBlKTtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IFsncm93JywgJ2NvbCcsICdkZXB0aCcsICdkZXB0aDInLCAnZGVwdGgzJywgJ2RlcHRoNCddO1xuICAgICAgLy8gRGVlcCBjb3B5IG9mIGlucHV0IHRleHR1cmUgbGF5b3V0LlxuICAgICAgY29uc3QgbmV3SW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0TGF5b3V0KSk7XG4gICAgICBuZXdJbnB1dExheW91dC51bnBhY2tlZFNoYXBlID0gbmV3SW5wdXRTaGFwZTtcblxuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgICAgJHt0aGlzLmdldFVucGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgbmFtZSwgbmV3SW5wdXRMYXlvdXQpLnJvdXRpbmVCb2R5fVxuICAgICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLFxuICAgICAgICAgICAgICBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzLCBpbnQgZGVwdGg0KSB7XG4gICAgICAgICAgICAgIHJldHVybiAke2Z1bmNOYW1lfSgke2dldFNxdWVlemVkUGFyYW1zKHBhcmFtcywga2VwdERpbXMpfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLCAnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCddKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLFxuICAgICAgICAgICAgaW50IGRlcHRoMiwgaW50IGRlcHRoMywgaW50IGRlcHRoNCkge1xuICAgICAgICAgICAgaW50IGluZGV4ID0gcm93ICogJHtzdHJpZGUwfSArIGNvbCAqICR7c3RyaWRlMX0gKyBkZXB0aCAqICR7c3RyaWRlMn0gK1xuICAgICAgICAgICAgZGVwdGgyICogJHtzdHJpZGUzfSArIGRlcHRoMyAqICR7c3RyaWRlNH0gKyBkZXB0aDQ7XG4gICAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3RleE51bVJ9LCAke3RleE51bUN9LCBpbmRleCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbXG4gICAgICAnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsXG4gICAgICAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsXG4gICAgICAnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnLFxuICAgIF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgaXMgdGhlIG1haW4gZnVuY3Rpb24gdG8gbWFwIGZyb20gdGhlIGdpdmVuIHRleHR1cmUgY29vcmRpbmF0ZXMgKHMsdClcbiAgICogdG8gbG9naWNhbCBpbmRpY2VzIGZvciB0aGUgb3V0cHV0XG4gICAqIFRoZXJlIHdpbGwgb25seSBiZSBvbmUgc2luZ2xlIHZhcmlhdGlvbiBvZiB0aGlzXG4gICAqIEFsc28gc2VlIGNvb3Jkc1RvT2Zmc2V0IGFuZCBvZmZzZXRUb0luZGljZXMgZm9yIGlucHV0LXNwZWNpZmljIHZlcnNpb25zXG4gICAqL1xuICBwcm90ZWN0ZWQgdG9WZWMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0cHV0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgY29uc3QgcmFuayA9IG91dHB1dC5zaGFwZS5sZW5ndGg7XG4gICAgY29uc3Qgc3RyaWRlcyA9IG91dHB1dC5zdHJpZGVzO1xuICAgIGNvbnN0IHhTY2FsZSA9IG91dHB1dC53aWR0aDtcbiAgICBjb25zdCB5U2NhbGUgPSBvdXRwdXQuaGVpZ2h0O1xuXG4gICAgY29uc3Qgc3RyaWRlc0Jsb2NrID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rIC0gMTsgKytpKSB7XG4gICAgICBzdHJpZGVzQmxvY2sucHVzaChgXG4gICAgICAgIGNbJHtpfV0gPSBvZmZzZXQgLyAke3N0cmlkZXNbaV19O2ApO1xuICAgICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgICBvZmZzZXQgLT0gY1ske2l9XSAqICR7c3RyaWRlc1tpXX07YCk7XG4gICAgfVxuICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgICAgY1ske3JhbmsgLSAxfV0gPSBvZmZzZXQ7YCk7XG4gICAgY29uc3QgYm9keSA9IGBcbiAgICAgIHZvaWQgdG9WZWModmVjMiB0ZXhDb29yZHMsIG91dCBpbnQgY1ske3Jhbmt9XSkge1xuICAgICAgICBpbnQgb2Zmc2V0ID0gY29vcmRzVG9PZmZzZXQodGV4Q29vcmRzLCAke3hTY2FsZX0sICR7eVNjYWxlfSk7XG4gICAgICAgICR7c3RyaWRlc0Jsb2NrLmpvaW4oJycpfVxuICAgICAgfVxuICAgICAgdm9pZCB0b1ZlYyhpbnQgb2Zmc2V0LCBvdXQgaW50IGNbJHtyYW5rfV0pIHtcbiAgICAgICAgJHtzdHJpZGVzQmxvY2suam9pbignJyl9XG4gICAgICB9XG4gICAgYDtcbiAgICByZXR1cm4geyB0b1ZlYzogbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHksIFsnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnXSkgfTtcbiAgfVxuICAvKipcbiAgICogVGhlc2UgYXJlIHZhbHVlIGdldHRlciBmdW5jdGlvbnMgZ2VuZXJhdGVkIGZvciBlYWNoIGlucHV0XG4gICAqIEVhY2ggZnVuY3Rpb24gaXMgaGFyZHdpcmVkIHRvIHRoZSBuYW1lIGFuZCBkaW1lbnNpb25zIG9mIHRoZSBpbnB1dFxuICAgKiBBbiAnX1QnIHZhcmlhdGlvbiBpcyBhbHNvIHByb2R1Y2VkIHdoaWNoIGFjY2Vzc2VzIHZhbHVlcyBhcyBpZiB0aGVcbiAgICogaW5wdXQgd2FzIHRyYW5zcG9zZWRcbiAgICovXG4gIHByb3RlY3RlZCB2YWx1ZUZyb20oKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgY29uc3QgbGF5b3V0ID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV07XG4gICAgICBjb25zdCBzaGFwZSA9IGxheW91dC51bnBhY2tlZFNoYXBlLmxlbmd0aCA+IDAgPyBsYXlvdXQudW5wYWNrZWRTaGFwZSA6IGxheW91dC5zaGFwZTtcbiAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICBsZXQgZnVuY05hbWUgPSBgXyR7bmFtZX1gO1xuICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZSh0aGlzLmdldFZhbHVlRnJvbVNpbmdsZShuYW1lLCByYW5rLCBsYXlvdXQud2lkdGgsIGxheW91dC5oZWlnaHQsIGZhbHNlKSwgW1xuICAgICAgICBgc2hhcGVVdGlscy5pbmRpY2VzVG9PZmZzZXQke2Z1bmNOYW1lfWAsXG4gICAgICAgICdjb29yZGluYXRlcy5vZmZzZXRUb0Nvb3JkcycsXG4gICAgICAgICdmcmFnY29sb3IuZ2V0Q29sb3JBc0Zsb2F0JyxcbiAgICAgIF0pO1xuICAgICAgZnVuY05hbWUgPSBmdW5jTmFtZSArICdfVCc7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKHRoaXMuZ2V0VmFsdWVGcm9tU2luZ2xlKG5hbWUsIHJhbmssIGxheW91dC53aWR0aCwgbGF5b3V0LmhlaWdodCwgdHJ1ZSksIFtcbiAgICAgICAgYHNoYXBlVXRpbHMuaW5kaWNlc1RvT2Zmc2V0JHtmdW5jTmFtZX1gLFxuICAgICAgICAnY29vcmRpbmF0ZXMub2Zmc2V0VG9Db29yZHMnLFxuICAgICAgICAnZnJhZ2NvbG9yLmdldENvbG9yQXNGbG9hdCcsXG4gICAgICBdKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIC8qKlxuICAgKiBQcm9kdWNlcyBvbmUgdmFsdWUgZ2V0dGVyIGZ1bmN0aW9uIGZvciB0aGUgbmFtZSBhbmQgcmFuayBnaXZlblxuICAgKiBJZiBhIHRyYW5zcG9zZSBpcyBzZXQgcHJvcGVyIG9mZnNldFRvQ29vcmRzIG1hcHBpbmcgd2lsbCBiZSB1c2VkXG4gICAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgdGhlIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSByYW5rIHJhbmsgb2YgdGhlIGlucHV0XG4gICAqIEBwYXJhbSB0cmFuc3Bvc2Ugd2hldGhlciBvciBub3Qgc2hvdWxkIGdlbmVyYXRlIGEgdHJhbnNwb3NlIHZhcmlhdGlvblxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFZhbHVlRnJvbVNpbmdsZShcbiAgICB2YXJOYW1lOiBzdHJpbmcsXG4gICAgcmFuazogbnVtYmVyLFxuICAgIHdpZHRoOiBudW1iZXIsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICAgdHJhbnNwb3NlOiBib29sZWFuLFxuICApOiBzdHJpbmcge1xuICAgIGxldCBuYW1lID0gYF8ke3Zhck5hbWV9YDtcbiAgICBpZiAodHJhbnNwb3NlKSB7XG4gICAgICBuYW1lID0gbmFtZSArICdfVCc7XG4gICAgfVxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgcmV0dXJuIGBcbiAgICAgICAgZmxvYXQgJHtuYW1lfShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBvZmZzZXQgPSBpbmRpY2VzVG9PZmZzZXQke25hbWV9KG0pO1xuICAgICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfSgke3Zhck5hbWV9LCBjb29yZHMpKTtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9kdWNlcyBhIHBhY2tlZCB2YWx1ZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIHRoZSBuYW1lIGFuZCByYW5rIGdpdmVuXG4gICAqIElmIGEgdHJhbnNwb3NlIGlzIHNldCBwcm9wZXIgb2Zmc2V0VG9Db29yZHMgbWFwcGluZyB3aWxsIGJlIHVzZWRcbiAgICogQHBhcmFtIG5hbWUgbmFtZSBvZiB0aGUgZnVuY3Rpb25cbiAgICogQHBhcmFtIHJhbmsgcmFuayBvZiB0aGUgaW5wdXRcbiAgICogQHBhcmFtIHRyYW5zcG9zZSB3aGV0aGVyIG9yIG5vdCBzaG91bGQgZ2VuZXJhdGUgYSB0cmFuc3Bvc2UgdmFyaWF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkVmFsdWVGcm9tKFxuICAgIHZhck5hbWU6IHN0cmluZyxcbiAgICByYW5rOiBudW1iZXIsXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICB0cmFuc3Bvc2U6IGJvb2xlYW4sXG4gICk6IHN0cmluZyB7XG4gICAgbGV0IG5hbWUgPSBgXyR7dmFyTmFtZX1fUGFja2A7XG4gICAgaWYgKHRyYW5zcG9zZSkge1xuICAgICAgbmFtZSA9IG5hbWUgKyAnX1QnO1xuICAgIH1cbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIHJldHVybiBgXG4gICAgICAgIHZlYzQgJHtuYW1lfShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBvZmZzZXQgPSBpbmRpY2VzVG9PZmZzZXRfJHt2YXJOYW1lfShtKTtcbiAgICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHt3aWR0aH0sICR7aGVpZ2h0fSk7XG4gICAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7dmFyTmFtZX0sIGNvb3Jkcyk7XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmUgfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuXG4vKipcbiAqIFRoaXMgR0xTTCBsaWJyYXJ5IGhhbmRsZXMgcm91dGluZXMgY29udmVydGluZ1xuICogZmxvYXQzMiB0by9mcm9tIFVuc2lnbmVkIGJ5dGUgb3IgZmxvYXQgMTZcbiAqL1xuZXhwb3J0IGNsYXNzIEVuY29kaW5nR2xzbExpYiBleHRlbmRzIEdsc2xMaWIge1xuICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBHbHNsQ29udGV4dCkge1xuICAgIHN1cGVyKGNvbnRleHQpO1xuICB9XG4gIGdldEZ1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4geyAuLi50aGlzLmVuY29kZUZsb2F0MzIoKSwgLi4udGhpcy5kZWNvZGVGbG9hdDMyKCkgfTtcbiAgfVxuICBnZXRDdXN0b21UeXBlcygpOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIHByb3RlY3RlZCBlbmNvZGVGbG9hdDMyKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIHJldHVybiB7XG4gICAgICBlbmNvZGU6IG5ldyBHbHNsTGliUm91dGluZShgaGlnaHAgdmVjNCBlbmNvZGUoaGlnaHAgZmxvYXQgZikge1xuICAgICAgICByZXR1cm4gdmVjNChmLCAwLjAsIDAuMCwgMC4wKTtcbiAgICAgIH1cbiAgICAgICAgYCksXG4gICAgfTtcbiAgfVxuICBwcm90ZWN0ZWQgZGVjb2RlRmxvYXQzMigpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4ge1xuICAgICAgZGVjb2RlOiBuZXcgR2xzbExpYlJvdXRpbmUoYGhpZ2hwIGZsb2F0IGRlY29kZShoaWdocCB2ZWM0IHJnYmEpIHtcbiAgICAgICAgcmV0dXJuIHJnYmEucjtcbiAgICAgIH1cbiAgICAgICAgYCksXG4gICAgfTtcbiAgfVxuICAvKipcbiAgICogcmV0dXJucyB0aGUgcm91dGluZSB0byBlbmNvZGUgZW5jb2RlIGEgMzJiaXQgZmxvYXQgdG8gYSB2ZWM0IChvZiB1bnNpZ25lZCBieXRlcylcbiAgICogQGNyZWRpdDogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzA1OTk2Mi9ob3ctZG8taS1jb252ZXJ0LWEtdmVjNC1yZ2JhLXZhbHVlLXRvLWEtZmxvYXRcbiAgICovXG4gIHByb3RlY3RlZCBlbmNvZGVVaW50OCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBlbmRpYW5uZXNzID0gRW5jb2RpbmdHbHNsTGliLmlzTGl0dGxlRW5kaWFuKCkgPyAncmdiYS5yZ2JhPXJnYmEuYWJncjsnIDogJyc7XG4gICAgcmV0dXJuIHtcbiAgICAgIGVuY29kZTogbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIGhpZ2hwIHZlYzQgZW5jb2RlKGhpZ2hwIGZsb2F0IGYpIHtcbiAgICAgICAgaGlnaHAgZmxvYXQgRiA9IGFicyhmKTtcbiAgICAgICAgaGlnaHAgZmxvYXQgU2lnbiA9IHN0ZXAoMC4wLC1mKTtcbiAgICAgICAgaGlnaHAgZmxvYXQgRXhwb25lbnQgPSBmbG9vcihsb2cyKEYpKTtcbiAgICAgICAgaGlnaHAgZmxvYXQgTWFudGlzc2EgPSAoZXhwMigtIEV4cG9uZW50KSAqIEYpO1xuICAgICAgICBFeHBvbmVudCA9IGZsb29yKGxvZzIoRikgKyAxMjcuMCkgKyBmbG9vcihsb2cyKE1hbnRpc3NhKSk7XG4gICAgICAgIGhpZ2hwIHZlYzQgcmdiYTtcbiAgICAgICAgcmdiYVswXSA9IDEyOC4wICogU2lnbiAgKyBmbG9vcihFeHBvbmVudCpleHAyKC0xLjApKTtcbiAgICAgICAgcmdiYVsxXSA9IDEyOC4wICogbW9kKEV4cG9uZW50LDIuMCkgKyBtb2QoZmxvb3IoTWFudGlzc2EqMTI4LjApLDEyOC4wKTtcbiAgICAgICAgcmdiYVsyXSA9IGZsb29yKG1vZChmbG9vcihNYW50aXNzYSpleHAyKDIzLjAgLTguMCkpLGV4cDIoOC4wKSkpO1xuICAgICAgICByZ2JhWzNdID0gZmxvb3IoZXhwMigyMy4wKSptb2QoTWFudGlzc2EsZXhwMigtMTUuMCkpKTtcbiAgICAgICAgJHtlbmRpYW5uZXNzfVxuICAgICAgICByZ2JhID0gcmdiYSAvIDI1NS4wOyAvLyB2YWx1ZXMgbmVlZCB0byBiZSBub3JtYWxpemVkIHRvIFswLDFdXG4gICAgICAgIHJldHVybiByZ2JhO1xuICAgIH1cbiAgICAgICAgYCksXG4gICAgfTtcbiAgfVxuICAvKipcbiAgICogcmV0dXJucyB0aGUgcm91dGluZSB0byBlbmNvZGUgYSB2ZWM0IG9mIHVuc2lnbmVkIGJ5dGVzIHRvIGZsb2F0MzJcbiAgICogQGNyZWRpdDogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzA1OTk2Mi9ob3ctZG8taS1jb252ZXJ0LWEtdmVjNC1yZ2JhLXZhbHVlLXRvLWEtZmxvYXRcbiAgICovXG4gIHByb3RlY3RlZCBkZWNvZGVVaW50OCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBlbmRpYW5uZXNzID0gRW5jb2RpbmdHbHNsTGliLmlzTGl0dGxlRW5kaWFuKCkgPyAncmdiYS5yZ2JhPXJnYmEuYWJncjsnIDogJyc7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRlY29kZTogbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgICAgaGlnaHAgZmxvYXQgZGVjb2RlKGhpZ2hwIHZlYzQgcmdiYSkge1xuICAgICAgICAgIHJnYmEgPSByZ2JhICogMjU1LjA7IC8vIHZhbHVlcyBuZWVkIHRvIGJlIGRlLW5vcm1hbGl6ZWQgZnJvbSBbMCwxXSB0byBbMCwyNTVdXG4gICAgICAgICAgJHtlbmRpYW5uZXNzfVxuICAgICAgICAgIGhpZ2hwIGZsb2F0IFNpZ24gPSAxLjAgLSBzdGVwKDEyOC4wLHJnYmFbMF0pKjIuMDtcbiAgICAgICAgICBoaWdocCBmbG9hdCBFeHBvbmVudCA9IDIuMCAqIG1vZChyZ2JhWzBdLDEyOC4wKSArIHN0ZXAoMTI4LjAscmdiYVsxXSkgLSAxMjcuMDtcbiAgICAgICAgICBoaWdocCBmbG9hdCBNYW50aXNzYSA9IG1vZChyZ2JhWzFdLDEyOC4wKSo2NTUzNi4wICsgcmdiYVsyXSoyNTYuMCArcmdiYVszXSArIGZsb2F0KDB4ODAwMDAwKTtcbiAgICAgICAgICBoaWdocCBmbG9hdCBSZXN1bHQgPSAgU2lnbiAqIGV4cDIoRXhwb25lbnQpICogKE1hbnRpc3NhICogZXhwMigtMjMuMCApKTtcbiAgICAgICAgICByZXR1cm4gUmVzdWx0O1xuICAgICAgfVxuICAgICAgICBgKSxcbiAgICB9O1xuICB9XG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBtYWNoaW5lIGlzIGxpdHRsZSBlbmRpYW4gb3Igbm90XG4gICAqIEBjcmVkaXQ6IGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL1Rvb1RhbGxOYXRlLzQ3NTA5NTNcbiAgICovXG4gIHN0YXRpYyBpc0xpdHRsZUVuZGlhbigpOiBib29sZWFuIHtcbiAgICBjb25zdCBiID0gbmV3IEFycmF5QnVmZmVyKDQpO1xuICAgIGNvbnN0IGEgPSBuZXcgVWludDMyQXJyYXkoYik7XG4gICAgY29uc3QgYyA9IG5ldyBVaW50OEFycmF5KGIpO1xuICAgIGFbMF0gPSAweGRlYWRiZWVmO1xuICAgIGlmIChjWzBdID09PSAweGVmKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGNbMF0gPT09IDB4ZGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGVuZGlhbm5lc3MnKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmUgfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4vZ2xzbC1zb3VyY2UnO1xuXG4vKipcbiAqIFRoaXMgR0xTTCBsaWJyYXJ5IGhhbmRsZXMgcm91dGluZXMgYXJvdW5kIHJlYWRpbmcgYSB0ZXhsZXQgYW5kIHdyaXRpbmcgdG8gaXRcbiAqIFJlYWRpbmcgYW5kIHdyaXRpbmcgY291bGQgYmUgbW9yZSB0aGFuIGp1c3QgZGVhbGluZyB3aXRoIG9uZSBjaGFubmVsXG4gKiBJdCBtYXkgcmVxdWlyZSBlbmNvZGluZy9kZWNvZGluZyB0by9mcm9tIDQgY2hhbm5lbHMgaW50byBvbmVcbiAqL1xuZXhwb3J0IGNsYXNzIEZyYWdDb2xvckdsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgcmV0dXJuIHsgLi4udGhpcy5zZXRGcmFnQ29sb3IoKSwgLi4udGhpcy5nZXRDb2xvckFzRmxvYXQoKSB9O1xuICB9XG4gIGdldEN1c3RvbVR5cGVzKCk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgICByZXR1cm4ge307XG4gIH1cbiAgcHJvdGVjdGVkIHNldEZyYWdDb2xvcigpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIHJldHVybiB7XG4gICAgICBzZXRGcmFnQ29sb3I6IG5ldyBHbHNsTGliUm91dGluZShcbiAgICAgICAgYFxuICAgICAgICB2b2lkIHNldEZyYWdDb2xvcihmbG9hdCB2YWx1ZSkge1xuICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSBlbmNvZGUodmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGAsXG4gICAgICAgIFsnZW5jb2RpbmcuZW5jb2RlJ10sXG4gICAgICApLFxuICAgIH07XG4gIH1cbiAgcHJvdGVjdGVkIGdldENvbG9yQXNGbG9hdCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4ge1xuICAgICAgZ2V0Q29sb3JBc0Zsb2F0OiBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgIGBcbiAgICAgICAgZmxvYXQgZ2V0Q29sb3JBc0Zsb2F0KHZlYzQgY29sb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBkZWNvZGUoY29sb3IpO1xuICAgICAgICB9XG4gICAgICAgIGAsXG4gICAgICAgIFsnZW5jb2RpbmcuZGVjb2RlJ10sXG4gICAgICApLFxuICAgIH07XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR2xzbENvbnRleHQsIEdsc2xMaWIsIEdsc2xMaWJSb3V0aW5lIH0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcblxuLyoqXG4gKiBHTFNMIExpYnJhcnkgcmVzcG9uc2libGUgZm9yIGRhdGEgdHlwZXMgYW5kIHJvdXRpbmVzIGZvciBtYW5pcHVsYXRpbmdcbiAqIGNvb3JkaW5hdGVzIGFuZCBtYXBwaW5nIHRvL2Zyb20gdGVuc29yIGluZGljZXNcbiAqL1xuZXhwb3J0IGNsYXNzIFNoYXBlVXRpbHNHbHNsTGliIGV4dGVuZHMgR2xzbExpYiB7XG4gIGNvbnN0cnVjdG9yKGNvbnRleHQ6IEdsc2xDb250ZXh0KSB7XG4gICAgc3VwZXIoY29udGV4dCk7XG4gIH1cbiAgZ2V0RnVuY3Rpb25zKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLmJjYXN0SW5kZXgoKSxcbiAgICAgIC4uLnRoaXMuYmNhc3RNYXRtdWxJbmRleCgpLFxuICAgICAgLi4udGhpcy5vZmZzZXRUb0luZGljZXMoKSxcbiAgICAgIC4uLnRoaXMuaW5kaWNlc1RvT2Zmc2V0KCksXG4gICAgICAuLi50aGlzLmluY3JlbWVudEluZGljZXMoKSxcbiAgICB9O1xuICB9XG4gIGdldEN1c3RvbVR5cGVzKCkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBwcm90ZWN0ZWQgYmNhc3RJbmRleCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRSYW5rID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0udW5wYWNrZWRTaGFwZTtcbiAgICAgIGlmIChzaGFwZS5sZW5ndGggPD0gb3V0cHV0UmFuaykge1xuICAgICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgICBjb25zdCBkaW1PZmZzZXQgPSBvdXRwdXRSYW5rIC0gcmFuaztcbiAgICAgICAgY29uc3QgZnVuY05hbWUgPSBgYmNhc3RJbmRpY2VzXyR7bmFtZX1gO1xuICAgICAgICBsZXQgYmxvY2sgPSAnJztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICAgICAgICBibG9jayArPSBgXG4gICAgICAgICAgcmVhbEluZGljZXNbJHtpfV0gPSBpbnQoIG1vZChmbG9hdChiY2FzdGVkSW5kaWNlc1ske2RpbU9mZnNldCArIGl9XSksICR7c2hhcGVbaV19LjApICk7XG4gICAgICAgICAgYDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBib2R5ID0gYFxuICAgICAgICB2b2lkICR7ZnVuY05hbWV9IChpbnQgYmNhc3RlZEluZGljZXNbJHtvdXRwdXRSYW5rfV0sIG91dCBpbnQgcmVhbEluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICAke2Jsb2NrfVxuICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBwcm90ZWN0ZWQgYmNhc3RNYXRtdWxJbmRleCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRSYW5rID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc2hhcGU7XG4gICAgICBpZiAoIShzaGFwZS5sZW5ndGggPCAyIHx8IHNoYXBlLmxlbmd0aCA+IG91dHB1dFJhbmspKSB7XG4gICAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGRpbU9mZnNldCA9IG91dHB1dFJhbmsgLSByYW5rO1xuICAgICAgICBjb25zdCBmdW5jTmFtZSA9IGBiY2FzdE1hdG11bEluZGljZXNfJHtuYW1lfWA7XG4gICAgICAgIGxldCBibG9jayA9ICcnO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAyOyArK2kpIHtcbiAgICAgICAgICBibG9jayArPSBgXG4gICAgICAgICAgcmVhbEluZGljZXNbJHtpfV0gPSBpbnQoIG1vZChmbG9hdChiY2FzdGVkSW5kaWNlc1ske2RpbU9mZnNldCArIGl9XSksICR7c2hhcGVbaV19LjApICk7XG4gICAgICAgICAgYDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBib2R5ID0gYFxuICAgICAgICB2b2lkICR7ZnVuY05hbWV9KGludCBiY2FzdGVkSW5kaWNlc1ske291dHB1dFJhbmt9XSwgb3V0IGludCByZWFsSW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgICR7YmxvY2t9XG4gICAgICAgICAgcmVhbEluZGljZXNbJHtyYW5rIC0gMX1dID0gYmNhc3RlZEluZGljZXNbJHtvdXRwdXRSYW5rIC0gMX1dO1xuICAgICAgICAgIHJlYWxJbmRpY2VzWyR7cmFuayAtIDJ9XSA9IGJjYXN0ZWRJbmRpY2VzWyR7b3V0cHV0UmFuayAtIDJ9XTtcbiAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcHJvdGVjdGVkIGluZGljZXNUb09mZnNldCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBzaGFwZSA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnNoYXBlO1xuICAgICAgY29uc3Qgc3RyaWRlcyA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnN0cmlkZXM7XG4gICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgbGV0IGZ1bmNOYW1lID0gYGluZGljZXNUb09mZnNldF8ke25hbWV9YDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoU2hhcGVVdGlsc0dsc2xMaWIuaW5kZXhUb09mZnNldFNpbmdsZShmdW5jTmFtZSwgcmFuaywgc3RyaWRlcykpO1xuICAgICAgZnVuY05hbWUgPSBgaW5kaWNlc1RvT2Zmc2V0XyR7bmFtZX1fVGA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKFxuICAgICAgICBTaGFwZVV0aWxzR2xzbExpYi5pbmRleFRvT2Zmc2V0U2luZ2xlKGZ1bmNOYW1lLCByYW5rLCBzdHJpZGVzLnNsaWNlKCkucmV2ZXJzZSgpKSxcbiAgICAgICk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBzdGF0aWMgaW5kZXhUb09mZnNldFNpbmdsZShuYW1lOiBzdHJpbmcsIHJhbms6IG51bWJlciwgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10pOiBzdHJpbmcge1xuICAgIGxldCBibG9jayA9ICcnO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIGJsb2NrICs9IGBcbiAgICAgICAgb2Zmc2V0ICs9IGluZGljZXNbJHtpfV0gKiAke3N0cmlkZXNbaV19O1xuICAgICAgICBgO1xuICAgIH1cbiAgICByZXR1cm4gYFxuICAgICAgaW50ICR7bmFtZX0oaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IG9mZnNldCA9IDA7XG4gICAgICAgICR7YmxvY2t9XG4gICAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgICB9XG4gICAgICBgO1xuICB9XG4gIHByb3RlY3RlZCBvZmZzZXRUb0luZGljZXMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgY29uc3Qgc2hhcGUgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS5zaGFwZTtcbiAgICAgIGNvbnN0IHN0cmlkZXMgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS5zdHJpZGVzO1xuICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgIGxldCBmdW5jTmFtZSA9IGBvZmZzZXRUb0luZGljZXNfJHtuYW1lfWA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKFNoYXBlVXRpbHNHbHNsTGliLm9mZnNldFRvSW5kaWNlc1NpbmdsZShmdW5jTmFtZSwgcmFuaywgc3RyaWRlcykpO1xuICAgICAgZnVuY05hbWUgPSBgb2Zmc2V0VG9JbmRpY2VzXyR7bmFtZX1fVGA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKFxuICAgICAgICBTaGFwZVV0aWxzR2xzbExpYi5vZmZzZXRUb0luZGljZXNTaW5nbGUoZnVuY05hbWUsIHJhbmssIHN0cmlkZXMuc2xpY2UoKS5yZXZlcnNlKCkpLFxuICAgICAgKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHN0YXRpYyBvZmZzZXRUb0luZGljZXNTaW5nbGUobmFtZTogc3RyaW5nLCByYW5rOiBudW1iZXIsIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdHJpZGVzQmxvY2sgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAxOyArK2kpIHtcbiAgICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgIGluZGljZXNbJHtpfV0gPSBvZmZzZXQgLyAke3N0cmlkZXNbaV19O2ApO1xuICAgICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgICBvZmZzZXQgLT0gaW5kaWNlc1ske2l9XSAqICR7c3RyaWRlc1tpXX07YCk7XG4gICAgfVxuICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgIGluZGljZXNbJHtyYW5rIC0gMX1dID0gb2Zmc2V0O2ApO1xuICAgIHJldHVybiBgXG4gICAgICB2b2lkICR7bmFtZX0oaW50IG9mZnNldCwgb3V0IGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICR7c3RyaWRlc0Jsb2NrLmpvaW4oJycpfVxuICAgICAgfVxuICAgICAgYDtcbiAgfVxuICBwcm90ZWN0ZWQgaW5jcmVtZW50SW5kaWNlcygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBzaGFwZSA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnNoYXBlO1xuICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgIGNvbnN0IGZ1bmNOYW1lID0gYGluY3JlbWVudEluZGljZXNfJHtuYW1lfWA7XG4gICAgICBsZXQgc2hhcGVJbml0ID0gJyc7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7ICsraSkge1xuICAgICAgICBzaGFwZUluaXQgKz0gYFxuICAgICAgICBzaGFwZVske2l9XSA9ICR7c2hhcGVbaV19O2A7XG4gICAgICB9XG4gICAgICBjb25zdCBib2R5ID0gYFxuICAgICAgICB2b2lkICR7ZnVuY05hbWV9KGludCBheGlzLCBvdXQgaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgc2hhcGVbJHtyYW5rfV07XG4gICAgICAgICAgJHtzaGFwZUluaXR9O1xuICAgICAgICAgIGZvcihpbnQgaSA9ICR7cmFua30gLTEgOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgaWYoaSA+IGF4aXMpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaW5kaWNlc1tpXSArPSAxO1xuICAgICAgICAgICAgaWYoaW5kaWNlc1tpXSA8IHNoYXBlW2ldKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5kaWNlc1tpXSA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR2xzbENvbnRleHQsIEdsc2xMaWIsIEdsc2xMaWJSb3V0aW5lIH0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcblxuLyoqXG4gKiBHTFNMIExpYnJhcnkgcmVzcG9uc2libGUgZm9yIHZlYyByb3V0aW5lc1xuICogVmVjIGlzIGFuIHZhcmlhYmxlIGxlbmd0aCBpbnQgYXJyYXkuIFRoZSBsZW5ndGggaXMgZml4ZWQgYXQgdGhlIHRpbWUgb2ZcbiAqIGdlbmVyYXRpbmcgdGhlIGxpYnJhcnkgZnVuY3Rpb25zIGZyb20gdGhlIGRpbWVuc2lvbnMgb2YgdGhlIG91dHB1dC5cbiAqL1xuZXhwb3J0IGNsYXNzIFZlY0dsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRDdXN0b21UeXBlcygpOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIGdldEZ1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4geyAuLi50aGlzLmJpbmFyeVZlY0Z1bmN0aW9ucygpLCAuLi50aGlzLmNvcHlWZWMoKSwgLi4udGhpcy5zZXRWZWNJdGVtKCksIC4uLnRoaXMuZ2V0VmVjSXRlbSgpIH07XG4gIH1cbiAgcHJvdGVjdGVkIGJpbmFyeVZlY0Z1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBjb25zdCByYW5rID0gb3V0cHV0TGF5b3V0LnNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBuYW1lT3A6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9ID0geyBhZGQ6ICcrPScsIHN1YjogJy09JywgbXVsOiAnKj0nLCBkaXY6ICcvPScgfTtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IG5hbWUgaW4gbmFtZU9wKSB7XG4gICAgICBjb25zdCBmbmFtZSA9IGAke25hbWV9VmVjYDtcbiAgICAgIGxldCBhc3NpZ25tZW50QmxvY2sgPSAnJztcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgICAgIGFzc2lnbm1lbnRCbG9jayArPSBgXG4gICAgICAgICAgZGVzdFske2l9XSAke25hbWVPcFtuYW1lXX0gc3JjWyR7aX1dO1xuICAgICAgICAgIGA7XG4gICAgICB9XG4gICAgICBjb25zdCBib2R5ID0gYFxuICAgICAgICB2b2lkICR7Zm5hbWV9KGludCBzcmNbJHtyYW5rfV0sIG91dCBpbnQgZGVzdFske3Jhbmt9XSkge1xuICAgICAgICAgICR7YXNzaWdubWVudEJsb2NrfVxuICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXN1bHRbZm5hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcHJvdGVjdGVkIGNvcHlWZWMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgY29uc3QgcmFuayA9IG91dHB1dExheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgbGV0IGFzc2lnbm1lbnRCbG9jayA9ICcnO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgICBhc3NpZ25tZW50QmxvY2sgKz0gYFxuICAgICAgICBkZXN0WyR7aX1dID0gc3JjWyR7aX1dO1xuICAgICAgICBgO1xuICAgIH1cbiAgICBjb25zdCBib2R5ID0gYFxuICAgICAgdm9pZCBjb3B5VmVjKGludCBzcmNbJHtyYW5rfV0sIG91dCBpbnQgZGVzdFske3Jhbmt9XSkge1xuICAgICAgICAke2Fzc2lnbm1lbnRCbG9ja31cbiAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIHsgY29weVZlYzogbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0VmVjSXRlbSgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBjb25zdCByYW5rID0gb3V0cHV0TGF5b3V0LnNoYXBlLmxlbmd0aDtcbiAgICBsZXQgYmxvY2sgPSBgXG4gICAgICAgIGlmKGluZGV4IDwgMClcbiAgICAgICAgICAgIGluZGV4ID0ke3Jhbmt9ICsgaW5kZXg7XG4gICAgICAgIGlmIChpbmRleCA9PSAwKVxuICAgICAgICAgICAgbVswXSA9IHZhbHVlO1xuICAgICAgICBgO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmFuayAtIDE7ICsraSkge1xuICAgICAgYmxvY2sgKz0gYFxuICAgICAgICBlbHNlIGlmIChpbmRleCA9PSAke2l9KVxuICAgICAgICAgICAgbVske2l9XSA9IHZhbHVlO1xuICAgICAgICAgICAgYDtcbiAgICB9XG4gICAgYmxvY2sgKz0gYFxuICAgICAgICBlbHNlXG4gICAgICAgICAgICBtWyR7cmFuayAtIDF9XSA9IHZhbHVlO1xuICAgICAgICBgO1xuICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICB2b2lkIHNldFZlY0l0ZW0ob3V0IGludCBtWyR7cmFua31dLCBpbnQgaW5kZXgsIGludCB2YWx1ZSkge1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgfVxuICAgICAgICBgO1xuICAgIHJldHVybiB7IHNldFZlY0l0ZW06IG5ldyBHbHNsTGliUm91dGluZShib2R5KSB9O1xuICB9XG4gIHByb3RlY3RlZCBnZXRWZWNJdGVtKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dHB1dExheW91dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGxldCBibG9jayA9IGBcbiAgICAgICAgaWYoaW5kZXggPCAwKVxuICAgICAgICAgICAgaW5kZXggPSAke3Jhbmt9ICsgaW5kZXg7XG4gICAgICAgIGlmIChpbmRleCA9PSAwKVxuICAgICAgICAgICAgcmV0dXJuIG1bMF07XG4gICAgICBgO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmFuayAtIDE7ICsraSkge1xuICAgICAgYmxvY2sgKz0gYFxuICAgICAgICBlbHNlIGlmIChpbmRleCA9PSAke2l9KVxuICAgICAgICAgICAgcmV0dXJuIG1bJHtpfV07XG4gICAgICBgO1xuICAgIH1cbiAgICBibG9jayArPSBgXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJldHVybiBtWyR7cmFuayAtIDF9XTtcbiAgICAgICAgYDtcbiAgICBjb25zdCBib2R5ID0gYFxuICAgICAgaW50IGdldFZlY0l0ZW0oaW50IG1bJHtyYW5rfV0sIGludCBpbmRleCkge1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgfVxuICAgIGA7XG4gICAgcmV0dXJuIHsgZ2V0VmVjSXRlbTogbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpIH07XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQ29vcmRzR2xzbExpYiB9IGZyb20gJy4vZ2xzbC1jb29yZGluYXRlLWxpYic7XG5pbXBvcnQgeyBHbHNsQ29udGV4dCwgR2xzbExpYiB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBFbmNvZGluZ0dsc2xMaWIgfSBmcm9tICcuL2dsc2wtZW5jb2RpbmctbGliJztcbmltcG9ydCB7IEZyYWdDb2xvckdsc2xMaWIgfSBmcm9tICcuL2dsc2wtZnJhZ2NvbG9yLWxpYic7XG5pbXBvcnQgeyBTaGFwZVV0aWxzR2xzbExpYiB9IGZyb20gJy4vZ2xzbC1zaGFwZS11dGlscy1saWInO1xuaW1wb3J0IHsgVmVjR2xzbExpYiB9IGZyb20gJy4vZ2xzbC12ZWMtbGliJztcblxuZXhwb3J0IGNvbnN0IGdsc2xSZWdpc3RyeTogeyBbbmFtZTogc3RyaW5nXTogbmV3IChjb250ZXh0OiBHbHNsQ29udGV4dCkgPT4gR2xzbExpYiB9ID0ge1xuICBlbmNvZGluZzogRW5jb2RpbmdHbHNsTGliLFxuICBmcmFnY29sb3I6IEZyYWdDb2xvckdsc2xMaWIsXG4gIHZlYzogVmVjR2xzbExpYixcbiAgc2hhcGVVdGlsczogU2hhcGVVdGlsc0dsc2xMaWIsXG4gIGNvb3JkaW5hdGVzOiBDb29yZHNHbHNsTGliLFxuICAvLyAgJ2FycmF5cyc6IEFycmF5R2xzbFNMaWJcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZU5vZGUsIFRvcG9sb2dpY2FsU29ydEdsc2xSb3V0aW5lcyB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyByZXBsYWNlSW5saW5lcyB9IGZyb20gJy4vZ2xzbC1mdW5jdGlvbi1pbmxpbmVyJztcbmltcG9ydCB7IGdsc2xSZWdpc3RyeSB9IGZyb20gJy4vZ2xzbC1yZWdpc3RlcmVkLWxpYnMnO1xuaW1wb3J0IHsgZ2V0RGVmYXVsdEZyYWdTaGFkZXJNYWluLCBnZXRGcmFnU2hhZGVyUHJlYW1ibGUgfSBmcm9tICcuL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlTGF5b3V0LCBWYXJpYWJsZUluZm8gfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IFdlYkdMQ29udGV4dCB9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbi8qKlxuICogUHJlcHJvY2Vzc29yIGZvciB0aGUgYWRkaXRpb25zIHRvIHRoZSBHTFNMIGxhbmd1YWdlXG4gKiBJdCBkZWFscyB3aXRoOlxuICogIEBpbmNsdWRlIGRpcmVjdGl2ZXNcbiAqICBAaW5saW5lXG4gKiAgTG9vcCB1bnJvbGxpbmcgKG5vdCBpbXBsZW1lbnRlZClcbiAqICBNYWNybyByZXNvbHV0aW9uIChub3QgaW1wbGVtZW50ZWQpXG4gKi9cbmV4cG9ydCBjbGFzcyBHbHNsUHJlcHJvY2Vzc29yIHtcbiAgcmVhZG9ubHkgY29udGV4dDogR2xzbENvbnRleHQ7XG4gIHJlYWRvbmx5IGxpYnM6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWIgfSA9IHt9O1xuICByZWFkb25seSBnbHNsTGliUm91dGluZURlcGVuZGVuY3lHcmFwaDogeyBbcm91dGluZU5hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lTm9kZSB9ID0ge307XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQsXG4gICAgcHJvZ3JhbUluZm86IFByb2dyYW1JbmZvLFxuICAgIGlucHV0VGV4dHVyZUxheW91dHM6IFRleHR1cmVMYXlvdXRbXSxcbiAgICBvdXRwdXRUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICApIHtcbiAgICB0aGlzLmNvbnRleHQgPSBuZXcgR2xzbENvbnRleHQoZ2xDb250ZXh0LCBwcm9ncmFtSW5mbywgaW5wdXRUZXh0dXJlTGF5b3V0cywgb3V0cHV0VGV4dHVyZUxheW91dCk7XG5cbiAgICAvLyBjb25zdHJ1Y3QgR2xzbExpYnNcbiAgICBPYmplY3Qua2V5cyhnbHNsUmVnaXN0cnkpLmZvckVhY2goKG5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgbGliID0gbmV3IGdsc2xSZWdpc3RyeVtuYW1lXSh0aGlzLmNvbnRleHQpO1xuICAgICAgdGhpcy5saWJzW25hbWVdID0gbGliO1xuICAgIH0pO1xuXG4gICAgLy8gY29uc3RydWN0IEdsc2xSb3V0aW5lRGVwZW5kZW5jeUdyYXBoXG4gICAgY29uc3QgbWFwID0gdGhpcy5nbHNsTGliUm91dGluZURlcGVuZGVuY3lHcmFwaDtcbiAgICBmb3IgKGNvbnN0IGxpYk5hbWUgaW4gdGhpcy5saWJzKSB7XG4gICAgICBjb25zdCBsaWIgPSB0aGlzLmxpYnNbbGliTmFtZV07XG4gICAgICBjb25zdCByb3V0aW5lc0luTGliID0gbGliLmdldEZ1bmN0aW9ucygpO1xuICAgICAgZm9yIChjb25zdCByb3V0aW5lIGluIHJvdXRpbmVzSW5MaWIpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gbGliTmFtZSArICcuJyArIHJvdXRpbmU7XG4gICAgICAgIGxldCBjdXJyZW50Tm9kZTogR2xzbExpYlJvdXRpbmVOb2RlO1xuICAgICAgICBpZiAobWFwW2tleV0pIHtcbiAgICAgICAgICBjdXJyZW50Tm9kZSA9IG1hcFtrZXldO1xuICAgICAgICAgIGN1cnJlbnROb2RlLnJvdXRpbmVCb2R5ID0gcm91dGluZXNJbkxpYltyb3V0aW5lXS5yb3V0aW5lQm9keTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdXJyZW50Tm9kZSA9IG5ldyBHbHNsTGliUm91dGluZU5vZGUoa2V5LCByb3V0aW5lc0luTGliW3JvdXRpbmVdLnJvdXRpbmVCb2R5KTtcbiAgICAgICAgICBtYXBba2V5XSA9IGN1cnJlbnROb2RlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IHJvdXRpbmVzSW5MaWJbcm91dGluZV0uZGVwZW5kZW5jaWVzO1xuICAgICAgICBpZiAoZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZXBlbmRlbmNpZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmICghbWFwW2RlcGVuZGVuY2llc1tpXV0pIHtcbiAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IG5ldyBHbHNsTGliUm91dGluZU5vZGUoZGVwZW5kZW5jaWVzW2ldKTtcbiAgICAgICAgICAgICAgbWFwW2RlcGVuZGVuY2llc1tpXV0gPSBub2RlO1xuICAgICAgICAgICAgICBjdXJyZW50Tm9kZS5hZGREZXBlbmRlbmN5KG5vZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY3VycmVudE5vZGUuYWRkRGVwZW5kZW5jeShtYXBbZGVwZW5kZW5jaWVzW2ldXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJlcHJvY2VzcygpOiBzdHJpbmcge1xuICAgIGNvbnN0IHByb2dyYW1JbmZvID0gdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvO1xuICAgIGxldCBzb3VyY2UgPSBwcm9ncmFtSW5mby5zaGFkZXJTb3VyY2U7XG5cbiAgICAvLyBhcHBlbmQgbWFpbigpIGZ1bmN0aW9uXG4gICAgaWYgKCF0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaGFzTWFpbikge1xuICAgICAgc291cmNlID0gYCR7c291cmNlfVxuICAgICAgJHtnZXREZWZhdWx0RnJhZ1NoYWRlck1haW4odGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uLCB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dC5zaGFwZS5sZW5ndGgpfWA7XG4gICAgfVxuICAgIC8vIHJlcGxhY2UgaW5saW5lc1xuICAgIHNvdXJjZSA9IHJlcGxhY2VJbmxpbmVzKHNvdXJjZSk7XG5cbiAgICAvLyBjb25jYXQgZmluYWwgc291cmNlIHN0cmluZ1xuICAgIHJldHVybiBgJHtnZXRGcmFnU2hhZGVyUHJlYW1ibGUodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKX1cbiAgICAke3RoaXMuZ2V0VW5pZm9ybXMocHJvZ3JhbUluZm8uaW5wdXROYW1lcywgcHJvZ3JhbUluZm8udmFyaWFibGVzKX1cbiAgICAke3RoaXMuZ2V0SW1wb3J0cyhzb3VyY2UpfVxuICAgICR7c291cmNlfWA7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0SW1wb3J0cyhzY3JpcHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3Qgcm91dGluZXNJbmNsdWRlZCA9IHRoaXMuc2VsZWN0R2xzbExpYlJvdXRpbmVzVG9CZUluY2x1ZGVkKHNjcmlwdCk7XG5cbiAgICBpZiAocm91dGluZXNJbmNsdWRlZC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICBsZXQgcm91dGluZXMgPSAnJztcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvdXRpbmVzSW5jbHVkZWQubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmIChyb3V0aW5lc0luY2x1ZGVkW2ldLnJvdXRpbmVCb2R5KSB7XG4gICAgICAgIHJvdXRpbmVzICs9IHJvdXRpbmVzSW5jbHVkZWRbaV0ucm91dGluZUJvZHkgKyAnXFxuJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyBib2R5IGZvciB0aGUgR2xzbCBMaWJyYXJ5IHJvdXRpbmU6ICR7cm91dGluZXNJbmNsdWRlZFtpXS5uYW1lfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByb3V0aW5lcztcbiAgfVxuICBwcml2YXRlIHNlbGVjdEdsc2xMaWJSb3V0aW5lc1RvQmVJbmNsdWRlZChzY3JpcHQ6IHN0cmluZyk6IEdsc2xMaWJSb3V0aW5lTm9kZVtdIHtcbiAgICBjb25zdCBub2RlczogR2xzbExpYlJvdXRpbmVOb2RlW10gPSBbXTtcblxuICAgIE9iamVjdC5rZXlzKHRoaXMuZ2xzbExpYlJvdXRpbmVEZXBlbmRlbmN5R3JhcGgpLmZvckVhY2goKGNsYXNzQW5kUm91dGluZSkgPT4ge1xuICAgICAgY29uc3Qgcm91dGluZSA9IGNsYXNzQW5kUm91dGluZS5zcGxpdCgnLicpWzFdO1xuICAgICAgaWYgKHNjcmlwdC5pbmRleE9mKHJvdXRpbmUpICE9PSAtMSkge1xuICAgICAgICBub2Rlcy5wdXNoKHRoaXMuZ2xzbExpYlJvdXRpbmVEZXBlbmRlbmN5R3JhcGhbY2xhc3NBbmRSb3V0aW5lXSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gVG9wb2xvZ2ljYWxTb3J0R2xzbFJvdXRpbmVzLnJldHVybk9yZGVyZWROb2Rlcyhub2Rlcyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0VW5pZm9ybXMoc2FtcGxlcnM/OiBzdHJpbmdbXSwgdmFyaWFibGVzPzogVmFyaWFibGVJbmZvW10pOiBzdHJpbmcge1xuICAgIGNvbnN0IHVuaWZvcm1MaW5lczogc3RyaW5nW10gPSBbXTtcbiAgICBpZiAoc2FtcGxlcnMpIHtcbiAgICAgIGZvciAoY29uc3Qgc2FtcGxlciBvZiBzYW1wbGVycykge1xuICAgICAgICB1bmlmb3JtTGluZXMucHVzaChgdW5pZm9ybSBzYW1wbGVyMkQgJHtzYW1wbGVyfTtgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHZhcmlhYmxlcykge1xuICAgICAgZm9yIChjb25zdCB2YXJpYWJsZSBvZiB2YXJpYWJsZXMpIHtcbiAgICAgICAgdW5pZm9ybUxpbmVzLnB1c2goXG4gICAgICAgICAgYHVuaWZvcm0gJHt2YXJpYWJsZS50eXBlfSAke3ZhcmlhYmxlLm5hbWV9JHt2YXJpYWJsZS5hcnJheUxlbmd0aCA/IGBbJHt2YXJpYWJsZS5hcnJheUxlbmd0aH1dYCA6ICcnfTtgLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5pZm9ybUxpbmVzLmpvaW4oJ1xcbicpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IExvZ2dlciwgUHJvZmlsZXIgfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcblxuaW1wb3J0IHsgR2xzbFByZXByb2Nlc3NvciB9IGZyb20gJy4vZ2xzbC1wcmVwcm9jZXNzb3InO1xuaW1wb3J0IHsgZ2V0VmVydGV4U2hhZGVyU291cmNlIH0gZnJvbSAnLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kgfSBmcm9tICcuL3RleHR1cmUtbGF5b3V0LXN0cmF0ZWd5JztcbmltcG9ydCB7IEFydGlmYWN0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVZhcmlhYmxlLCBUZXh0dXJlRGF0YSwgVGV4dHVyZUxheW91dCwgVmFyaWFibGVJbmZvIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL3dlYmdsLWNvbnRleHQnO1xuXG4vKipcbiAqIFByb2dyYW1NYW5hZ2VyIGlzIHRoZSBtYWluIGNsYXNzIGJlaGluZCBydW5uaW5nIGNvbXB1dGF0aW9uc1xuICogSXQgYnVpbGRzIFByb2dyYW1JbmZvJ3MgaW50byBBcnRpZmFjdHNcbiAqIEl0IGNvbXBpbGVzIGdpdmVuIFByb2dyYW1JbmZvJ3MgaW50byBXZWJHTCBQcm9yYW1zIChjYWNoZWQgYXMgQXJ0aWZhY3RzKVxuICogVXNlcyB0aGUgYXJ0aWZhY3QgdG8gcnVuIHRoZSBjb21wdXRhdGlvbiBieSBjYWxsaW5nIERyYXcgb25cbiAqIHRoZSBXZWJHTCBkcmF3aW5nIGJ1ZmZlclxuICogUHJvZ3JhbU1hbmFnZXIgYXV0b21hdGljYWxseSBtYXBzIChiaW5kcykgaW5wdXQgdmFyaWFibGVzIHRvIHRoZWlyXG4gKiBjb3JyZXNwb25kaW5nIExvY2F0aW9uJ3MgaW4gdGhlIGJpbmFyeSBwcm9ncmFtXG4gKi9cbmV4cG9ydCBjbGFzcyBQcm9ncmFtTWFuYWdlciB7XG4gIHJlcG86IE1hcDx1bmtub3duLCBBcnRpZmFjdD47IC8vIHRoaXMgc2hvdWxkIGJlIHBlci1zZXNzaW9uIG9iamVjdFxuICB2ZXJ0ZXhTaGFkZXI6IFdlYkdMU2hhZGVyO1xuICBhdHRyaWJ1dGVzQm91bmQ6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj4sXG4gICAgcHVibGljIGdsQ29udGV4dDogV2ViR0xDb250ZXh0LFxuICAgIHB1YmxpYyB0ZXh0dXJlTGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSxcbiAgKSB7XG4gICAgdGhpcy5yZXBvID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuYXR0cmlidXRlc0JvdW5kID0gZmFsc2U7XG4gIH1cbiAgZ2V0QXJ0aWZhY3Qoa2V5OiB1bmtub3duKTogQXJ0aWZhY3QgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnJlcG8uZ2V0KGtleSk7XG4gIH1cbiAgc2V0QXJ0aWZhY3Qoa2V5OiB1bmtub3duLCBhcnRpZmFjdDogQXJ0aWZhY3QpOiB2b2lkIHtcbiAgICB0aGlzLnJlcG8uc2V0KGtleSwgYXJ0aWZhY3QpO1xuICB9XG4gIHJ1bihidWlsZEFydGlmYWN0OiBBcnRpZmFjdCwgaW5wdXRzOiBUZXh0dXJlRGF0YVtdLCBvdXRwdXQ6IFRleHR1cmVEYXRhKTogdm9pZCB7XG4gICAgdGhpcy5wcm9maWxlci5ldmVudChcbiAgICAgICdvcCcsXG4gICAgICBgUHJvZ3JhbU1hbmFnZXIucnVuICR7YnVpbGRBcnRpZmFjdC5wcm9ncmFtSW5mby5uYW1lID8/ICd1bmtub3duIGtlcm5lbCd9YCxcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3QgZ2wgPSB0aGlzLmdsQ29udGV4dC5nbDtcbiAgICAgICAgY29uc3QgcHJvZ3JhbSA9IGJ1aWxkQXJ0aWZhY3QucHJvZ3JhbTtcbiAgICAgICAgZ2wudXNlUHJvZ3JhbShwcm9ncmFtKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLmJpbmRPdXRwdXQob3V0cHV0KTtcbiAgICAgICAgICBpZiAoIXRoaXMuYXR0cmlidXRlc0JvdW5kKSB7XG4gICAgICAgICAgICB0aGlzLmJpbmRBdHRyaWJ1dGVzKGJ1aWxkQXJ0aWZhY3QuYXR0cmliTG9jYXRpb25zKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5iaW5kVW5pZm9ybXMoYnVpbGRBcnRpZmFjdC51bmlmb3JtTG9jYXRpb25zLCBidWlsZEFydGlmYWN0LnByb2dyYW1JbmZvLnZhcmlhYmxlcyA/PyBbXSwgaW5wdXRzKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgTG9nZ2VyLmVycm9yKCdQcm9ncmFtTWFuYWdlcicsIGJ1aWxkQXJ0aWZhY3QucHJvZ3JhbUluZm8uc2hhZGVyU291cmNlKTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wcm9maWxlci5ldmVudCgnYmFja2VuZCcsICdHbENvbnRleHQuZHJhdygpJywgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuZ2xDb250ZXh0LmRyYXcoKTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgdGhpcy5nbENvbnRleHQsXG4gICAgKTtcbiAgfVxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnZlcnRleFNoYWRlcikge1xuICAgICAgdGhpcy5nbENvbnRleHQuZGVsZXRlU2hhZGVyKHRoaXMudmVydGV4U2hhZGVyKTtcbiAgICB9XG4gICAgdGhpcy5yZXBvLmZvckVhY2goKGEpID0+IHRoaXMuZ2xDb250ZXh0LmRlbGV0ZVByb2dyYW0oYS5wcm9ncmFtKSk7XG4gIH1cbiAgYnVpbGQocHJvZ3JhbUluZm86IFByb2dyYW1JbmZvLCBpbnB1dFRleHR1cmVMYXlvdXRzOiBUZXh0dXJlTGF5b3V0W10sIG91dHB1dFRleHR1cmVMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBBcnRpZmFjdCB7XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnUHJvZ3JhbU1hbmFnZXIuYnVpbGQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcmVwcm9jZXNzb3IgPSBuZXcgR2xzbFByZXByb2Nlc3Nvcih0aGlzLmdsQ29udGV4dCwgcHJvZ3JhbUluZm8sIGlucHV0VGV4dHVyZUxheW91dHMsIG91dHB1dFRleHR1cmVMYXlvdXQpO1xuICAgICAgY29uc3QgZnJhZ1NjcmlwdCA9IHByZXByb2Nlc3Nvci5wcmVwcm9jZXNzKCk7XG4gICAgICBjb25zdCBwcm9ncmFtID0gdGhpcy5jb21waWxlKGZyYWdTY3JpcHQpO1xuICAgICAgY29uc3QgYXJ0aWZhY3QgPSB7XG4gICAgICAgIHByb2dyYW1JbmZvLFxuICAgICAgICBwcm9ncmFtLFxuICAgICAgICB1bmlmb3JtTG9jYXRpb25zOiB0aGlzLmdldFVuaWZvcm1Mb2NhdGlvbnMoXG4gICAgICAgICAgcHJvZ3JhbSxcbiAgICAgICAgICBwcmVwcm9jZXNzb3IuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLFxuICAgICAgICAgIHByZXByb2Nlc3Nvci5jb250ZXh0LnByb2dyYW1JbmZvLnZhcmlhYmxlcyxcbiAgICAgICAgKSxcbiAgICAgICAgYXR0cmliTG9jYXRpb25zOiB0aGlzLmdldEF0dHJpYkxvY2F0aW9ucyhwcm9ncmFtKSxcbiAgICAgIH07XG4gICAgICByZXR1cm4gYXJ0aWZhY3Q7XG4gICAgfSk7XG4gIH1cbiAgcHJvdGVjdGVkIGNvbXBpbGUoZnJhZ1NoYWRlclNjcmlwdDogc3RyaW5nKTogV2ViR0xQcm9ncmFtIHtcbiAgICBpZiAoIXRoaXMudmVydGV4U2hhZGVyKSB7XG4gICAgICBMb2dnZXIudmVyYm9zZSgnUHJvcmdyYW1NYW5hZ2VyJywgJ0NvbXBpbGluZyBhbmQgY2FjaGluZyBWZXJ0ZXggc2hhZGVyIGZvciB0aGUgZmlyc3QgdGltZScpO1xuICAgICAgY29uc3QgdmVydGV4U2hhZGVyU2NyaXB0ID0gZ2V0VmVydGV4U2hhZGVyU291cmNlKHRoaXMuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgICAgdGhpcy52ZXJ0ZXhTaGFkZXIgPSB0aGlzLmdsQ29udGV4dC5jb21waWxlU2hhZGVyKHZlcnRleFNoYWRlclNjcmlwdCwgdGhpcy5nbENvbnRleHQuZ2wuVkVSVEVYX1NIQURFUik7XG4gICAgfVxuICAgIGlmIChlbnYuZGVidWcpIHtcbiAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAnUHJvcmdyYW1NYW5hZ2VyJyxcbiAgICAgICAgYEZyYWdTaGFkZXI6XG4ke2ZyYWdTaGFkZXJTY3JpcHR9XG5gLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgZnJhZ1NoYWRlciA9IHRoaXMuZ2xDb250ZXh0LmNvbXBpbGVTaGFkZXIoZnJhZ1NoYWRlclNjcmlwdCwgdGhpcy5nbENvbnRleHQuZ2wuRlJBR01FTlRfU0hBREVSKTtcbiAgICBjb25zdCBwcm9ncmFtID0gdGhpcy5nbENvbnRleHQuY3JlYXRlUHJvZ3JhbSh0aGlzLnZlcnRleFNoYWRlciwgZnJhZ1NoYWRlcik7XG4gICAgdGhpcy5nbENvbnRleHQuZGVsZXRlU2hhZGVyKGZyYWdTaGFkZXIpO1xuICAgIHJldHVybiBwcm9ncmFtO1xuICB9XG4gIGJpbmRPdXRwdXQodGQ6IFRleHR1cmVEYXRhKTogdm9pZCB7XG4gICAgY29uc3Qgd2lkdGggPSB0ZC53aWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSB0ZC5oZWlnaHQ7XG4gICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAnUHJvcmdyYW1NYW5hZ2VyJyxcbiAgICAgIGBCaW5kaW5nIG91dHB1dCB0ZXh0dXJlIHRvIEZyYW1lYnVmZmVyOiB3L2g9JHt3aWR0aH0vJHtoZWlnaHR9LCBzaGFwZT0ke3RkLnNoYXBlfSwgdHlwZT0ke3RkLnRlbnNvci50eXBlfWAsXG4gICAgKTtcbiAgICB0aGlzLmdsQ29udGV4dC5hdHRhY2hGcmFtZWJ1ZmZlcih0ZC50ZXh0dXJlLCB3aWR0aCwgaGVpZ2h0KTtcbiAgfVxuICBiaW5kQXR0cmlidXRlcyhhdHRyaWJMb2NhdGlvbnM6IEFydGlmYWN0LkF0dHJpYkxvY2F0aW9ucyk6IHZvaWQge1xuICAgIGNvbnN0IHBvc2l0aW9uSGFuZGxlID0gYXR0cmliTG9jYXRpb25zLnBvc2l0aW9uO1xuICAgIGNvbnN0IHRleHR1cmVDb29yZEhhbmRsZSA9IGF0dHJpYkxvY2F0aW9ucy50ZXh0dXJlQ29vcmQ7XG4gICAgdGhpcy5nbENvbnRleHQuc2V0VmVydGV4QXR0cmlidXRlcyhwb3NpdGlvbkhhbmRsZSwgdGV4dHVyZUNvb3JkSGFuZGxlKTtcbiAgICB0aGlzLmF0dHJpYnV0ZXNCb3VuZCA9IHRydWU7XG4gIH1cbiAgYmluZFVuaWZvcm1zKFxuICAgIHVuaWZvcm1Mb2NhdGlvbnM6IEFydGlmYWN0LlVuaWZvcm1Mb2NhdGlvbnMsXG4gICAgdmFyaWFibGVzOiBQcm9ncmFtVmFyaWFibGVbXSxcbiAgICB0ZXh0dXJlczogVGV4dHVyZURhdGFbXSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsQ29udGV4dC5nbDtcbiAgICBsZXQgdGV4dHVyZVBvc2l0aW9uID0gMDtcbiAgICBmb3IgKGNvbnN0IHsgbmFtZSwgdHlwZSwgbG9jYXRpb24sIGFycmF5TGVuZ3RoIH0gb2YgdW5pZm9ybUxvY2F0aW9ucykge1xuICAgICAgY29uc3QgdmFsdWUgPSB2YXJpYWJsZXMuZmluZCgodikgPT4gdi5uYW1lID09PSBuYW1lKT8uZGF0YTtcbiAgICAgIGlmICh0eXBlICE9PSAnc2FtcGxlcjJEJyAmJiAhdmFsdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB2YXJpYWJsZSAnJHtuYW1lfScgZG9lcyBub3QgaGF2ZSBkYXRhIGRlZmluZWQgaW4gcHJvZ3JhbSBpbmZvYCk7XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSAnc2FtcGxlcjJEJzpcbiAgICAgICAgICB0aGlzLmJpbmRUZXh0dXJlKHRleHR1cmVzW3RleHR1cmVQb3NpdGlvbl0sIGxvY2F0aW9uLCB0ZXh0dXJlUG9zaXRpb24pO1xuICAgICAgICAgIHRleHR1cmVQb3NpdGlvbisrO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdmbG9hdCc6XG4gICAgICAgICAgaWYgKGFycmF5TGVuZ3RoKSB7XG4gICAgICAgICAgICBnbC51bmlmb3JtMWZ2KGxvY2F0aW9uLCB2YWx1ZSBhcyBudW1iZXJbXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsLnVuaWZvcm0xZihsb2NhdGlvbiwgdmFsdWUgYXMgbnVtYmVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2ludCc6XG4gICAgICAgICAgaWYgKGFycmF5TGVuZ3RoKSB7XG4gICAgICAgICAgICBnbC51bmlmb3JtMWl2KGxvY2F0aW9uLCB2YWx1ZSBhcyBudW1iZXJbXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsLnVuaWZvcm0xaShsb2NhdGlvbiwgdmFsdWUgYXMgbnVtYmVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmlmb3JtIG5vdCBpbXBsZW1lbnRlZDogJHt0eXBlfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBiaW5kVGV4dHVyZSh0ZDogVGV4dHVyZURhdGEsIHVuaWZvcm1IYW5kbGU6IFdlYkdMVW5pZm9ybUxvY2F0aW9uLCBwb3NpdGlvbjogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5nbENvbnRleHQuYmluZFRleHR1cmVUb1VuaWZvcm0odGQudGV4dHVyZSwgcG9zaXRpb24sIHVuaWZvcm1IYW5kbGUpO1xuICB9XG4gIGdldEF0dHJpYkxvY2F0aW9ucyhwcm9ncmFtOiBXZWJHTFByb2dyYW0pOiBBcnRpZmFjdC5BdHRyaWJMb2NhdGlvbnMge1xuICAgIHJldHVybiB7XG4gICAgICBwb3NpdGlvbjogdGhpcy5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAncG9zaXRpb24nKSxcbiAgICAgIHRleHR1cmVDb29yZDogdGhpcy5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAndGV4dHVyZUNvb3JkJyksXG4gICAgfTtcbiAgfVxuICBnZXRVbmlmb3JtTG9jYXRpb25zKFxuICAgIHByb2dyYW06IFdlYkdMUHJvZ3JhbSxcbiAgICBzYW1wbGVycz86IHN0cmluZ1tdLFxuICAgIHZhcmlhYmxlcz86IFZhcmlhYmxlSW5mb1tdLFxuICApOiBBcnRpZmFjdC5Vbmlmb3JtTG9jYXRpb25zIHtcbiAgICBjb25zdCB1bmlmb3JtTG9jYXRpb25zOiBBcnRpZmFjdC5Vbmlmb3JtTG9jYXRpb25zID0gW107XG4gICAgaWYgKHNhbXBsZXJzKSB7XG4gICAgICBmb3IgKGNvbnN0IHNhbXBsZXIgb2Ygc2FtcGxlcnMpIHtcbiAgICAgICAgdW5pZm9ybUxvY2F0aW9ucy5wdXNoKHtcbiAgICAgICAgICBuYW1lOiBzYW1wbGVyLFxuICAgICAgICAgIHR5cGU6ICdzYW1wbGVyMkQnLFxuICAgICAgICAgIGxvY2F0aW9uOiB0aGlzLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCBzYW1wbGVyKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh2YXJpYWJsZXMpIHtcbiAgICAgIGZvciAoY29uc3QgdmFyaWFibGUgb2YgdmFyaWFibGVzKSB7XG4gICAgICAgIHVuaWZvcm1Mb2NhdGlvbnMucHVzaCh7IC4uLnZhcmlhYmxlLCBsb2NhdGlvbjogdGhpcy5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgdmFyaWFibGUubmFtZSkgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1bmlmb3JtTG9jYXRpb25zO1xuICB9XG4gIGdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtOiBXZWJHTFByb2dyYW0sIG5hbWU6IHN0cmluZyk6IFdlYkdMVW5pZm9ybUxvY2F0aW9uIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2xDb250ZXh0LmdsO1xuICAgIGNvbnN0IHJlZmVyZW5jZSA9IGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCBuYW1lKTtcbiAgICBpZiAocmVmZXJlbmNlID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuaWZvcm0gJHtuYW1lfSBub3QgZm91bmQuYCk7XG4gICAgfVxuICAgIHJldHVybiByZWZlcmVuY2U7XG4gIH1cbiAgZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbTogV2ViR0xQcm9ncmFtLCBuYW1lOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbENvbnRleHQuZ2w7XG4gICAgY29uc3QgYXR0cmlidXRlTG9jYXRpb246IG51bWJlciA9IGdsLmdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sIG5hbWUpO1xuICAgIHJldHVybiBhdHRyaWJ1dGVMb2NhdGlvbjtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBMb2dnZXIsIFByb2ZpbGVyIH0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi90ZW5zb3InO1xuXG5pbXBvcnQgeyBFbmNvZGVyLCBFbmNvZGVyVXNhZ2UgfSBmcm9tICcuL3RleHR1cmUtZGF0YS1lbmNvZGVyJztcbmltcG9ydCB7IFRleHR1cmVMYXlvdXRTdHJhdGVneSB9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHsgVGV4dHVyZURhdGEsIFRleHR1cmVMYXlvdXQgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IFdlYkdMQ29udGV4dCB9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dHVyZU1hbmFnZXJDb25maWcge1xuICByZXVzZVRleHR1cmVzPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUZXh0dXJlTWFuYWdlciBpcyB0aGUgbWFpbmx5IHJlc3BvbnNpYmxlIGZvciBjYWNoaW5nIFRleHR1cmVzXG4gKiBUZXh0dXJlcyBhcmUgY2FjaGVkIGluIDIgbGV2ZWxzOlxuICogICAxLiB0aGUgdGV4dHVyZXMgd2hpY2ggYXJlIGFzc29jaWF0ZWQgd2l0aCBhIGRhdGFJZCAoZnJvbSBUZW5zb3IpXG4gKiAgICBDYWNoaW5nIHRoZXNlIGlzIGNydWNpYWwgdG8gcGVyZm9ybWFuY2UuIFRoZXNlIGFyZSBJbi11c2UgVGV4dHVyZXNcbiAqICAgMi4gdGV4dHVyZXMgd2hpY2ggYXJlIG5vdCBpbiB1c2UgYnkgYW55IGN1cnJlbnQgUHJvZ3JhbUluZm8vVGVuc29yXG4gKiAgICAgVGhlc2UgYXJlIGNhbGxlZCBGcmVlIFRleHR1cmVzXG4gKiBUZXh0dXJlTWFuYWdlciBpcyBhbHNvIHVzZWQgdG8gaGVscCBjcmVhdGluZyB0ZXh0dXJlcy4gRm9yIHRoaXMgaXRcbiAqIHVzZXMgV2ViR0xDb250ZXh0IGFuZCBUZXh0dXJlTGF5b3V0U3RyYXRlZ3lcbiAqL1xuZXhwb3J0IGNsYXNzIFRleHR1cmVNYW5hZ2VyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBpblVzZVRleHR1cmVzOiBNYXA8c3RyaW5nLCBXZWJHTFRleHR1cmVbXT47XG4gIHByaXZhdGUgcmVhZG9ubHkgaWRsZVRleHR1cmVzOiBNYXA8c3RyaW5nLCBXZWJHTFRleHR1cmVbXT47XG4gIHByaXZhdGUgcmVhZG9ubHkgdGV4dHVyZUxvb2t1cDogTWFwPFdlYkdMVGV4dHVyZSwgc3RyaW5nPjtcbiAgcHJpdmF0ZSByZWFkb25seSBwZW5kaW5nUmVhZDogTWFwPFRlbnNvci5JZCwgQXJyYXk8KGFycjogVGVuc29yLk51bWJlclR5cGUpID0+IHZvaWQ+PiA9IG5ldyBNYXAoKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQsXG4gICAgcHVibGljIGxheW91dFN0cmF0ZWd5OiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3ksXG4gICAgcHVibGljIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj4sXG4gICAgcHJpdmF0ZSBjb25maWc6IFRleHR1cmVNYW5hZ2VyQ29uZmlnLFxuICApIHtcbiAgICBpZiAoY29uZmlnLnJldXNlVGV4dHVyZXMpIHtcbiAgICAgIHRoaXMuaW5Vc2VUZXh0dXJlcyA9IG5ldyBNYXAoKTtcbiAgICAgIHRoaXMuaWRsZVRleHR1cmVzID0gbmV3IE1hcCgpO1xuICAgICAgdGhpcy50ZXh0dXJlTG9va3VwID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgfVxuICBjcmVhdGVUZXh0dXJlRnJvbUxheW91dChcbiAgICBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLFxuICAgIGxheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBkYXRhPzogVGVuc29yLk51bWJlclR5cGUsXG4gICAgdXNhZ2U/OiBFbmNvZGVyVXNhZ2UsXG4gICkge1xuICAgIGNvbnN0IHRleHR1cmVEYXRhVHlwZSA9IHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSk7XG5cbiAgICBjb25zdCBlbmNvZGVyID0gdGhpcy5nbENvbnRleHQuZ2V0RW5jb2Rlcih0ZXh0dXJlRGF0YVR5cGUsIGxheW91dC5jaGFubmVscyB8fCAxLCB1c2FnZSk7XG4gICAgaWYgKGxheW91dC5pc1BhY2tlZCAmJiB1c2FnZSA9PT0gRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuICAgIGNvbnN0IHdpZHRoID0gbGF5b3V0LndpZHRoO1xuICAgIGNvbnN0IGhlaWdodCA9IGxheW91dC5oZWlnaHQ7XG5cbiAgICBsZXQga2V5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgbGV0IGluVXNlVGV4dHVyZXM6IFdlYkdMVGV4dHVyZVtdIHwgdW5kZWZpbmVkO1xuICAgIGlmICh0aGlzLmNvbmZpZy5yZXVzZVRleHR1cmVzKSB7XG4gICAgICBrZXkgPSBgJHt3aWR0aH14JHtoZWlnaHR9XyR7ZW5jb2Rlci5mb3JtYXR9XyR7ZW5jb2Rlci5pbnRlcm5hbEZvcm1hdH1fJHtlbmNvZGVyLnRleHR1cmVUeXBlfWA7XG4gICAgICBpblVzZVRleHR1cmVzID0gdGhpcy5pblVzZVRleHR1cmVzLmdldChrZXkpO1xuICAgICAgaWYgKCFpblVzZVRleHR1cmVzKSB7XG4gICAgICAgIGluVXNlVGV4dHVyZXMgPSBbXTtcbiAgICAgICAgdGhpcy5pblVzZVRleHR1cmVzLnNldChrZXksIGluVXNlVGV4dHVyZXMpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBpZGxlVGV4dHVyZXMgPSB0aGlzLmlkbGVUZXh0dXJlcy5nZXQoa2V5KTtcbiAgICAgIGlmIChpZGxlVGV4dHVyZXMgJiYgaWRsZVRleHR1cmVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgdGV4dHVyZSA9IGlkbGVUZXh0dXJlcy5wb3AoKSE7XG4gICAgICAgIGluVXNlVGV4dHVyZXMucHVzaCh0ZXh0dXJlKTtcbiAgICAgICAgaWYgKHVzYWdlID09PSBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSkge1xuICAgICAgICAgIHRoaXMuZ2xDb250ZXh0LnVwZGF0ZVRleHR1cmUodGV4dHVyZSwgd2lkdGgsIGhlaWdodCwgZW5jb2RlciwgdGhpcy50b1RleHR1cmVEYXRhKGRhdGFUeXBlLCBkYXRhKSEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0ZXh0dXJlO1xuICAgICAgfVxuICAgIH1cblxuICAgIExvZ2dlci52ZXJib3NlKCdUZXh0dXJlTWFuYWdlcicsIGBDcmVhdGluZyBuZXcgdGV4dHVyZSBvZiBzaXplICR7bGF5b3V0LndpZHRofXgke2xheW91dC5oZWlnaHR9YCk7XG4gICAgY29uc3QgdGV4dHVyZSA9IHRoaXMuZ2xDb250ZXh0LmFsbG9jYXRlVGV4dHVyZSh3aWR0aCwgaGVpZ2h0LCBlbmNvZGVyLCB0aGlzLnRvVGV4dHVyZURhdGEoZGF0YVR5cGUsIGRhdGEpKTtcblxuICAgIGlmICh0aGlzLmNvbmZpZy5yZXVzZVRleHR1cmVzKSB7XG4gICAgICBpblVzZVRleHR1cmVzIS5wdXNoKHRleHR1cmUpO1xuICAgICAgdGhpcy50ZXh0dXJlTG9va3VwLnNldCh0ZXh0dXJlLCBrZXkhKTtcbiAgICB9XG4gICAgcmV0dXJuIHRleHR1cmU7XG4gIH1cbiAgcmVhZFRleHR1cmUodGQ6IFRleHR1cmVEYXRhLCBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLCBjaGFubmVscz86IG51bWJlcik6IFRlbnNvci5OdW1iZXJUeXBlIHtcbiAgICBpZiAoIWNoYW5uZWxzKSB7XG4gICAgICBjaGFubmVscyA9IDE7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdiYWNrZW5kJywgJ1RleHR1cmVNYW5hZ2VyLnJlYWRUZXh0dXJlJywgKCkgPT4ge1xuICAgICAgY29uc3QgZGF0YVNpemUgPSB0ZC5zaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKSAqIGNoYW5uZWxzITtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdsQ29udGV4dC5yZWFkVGV4dHVyZShcbiAgICAgICAgdGQudGV4dHVyZSxcbiAgICAgICAgdGQud2lkdGgsXG4gICAgICAgIHRkLmhlaWdodCxcbiAgICAgICAgZGF0YVNpemUsXG4gICAgICAgIHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSksXG4gICAgICAgIGNoYW5uZWxzISxcbiAgICAgICk7XG4gICAgICByZXR1cm4gdGhpcy50b1RlbnNvckRhdGEoZGF0YVR5cGUsIGRhdGEpO1xuICAgIH0pO1xuICB9XG4gIGFzeW5jIHJlYWRUZXh0dXJlQXN5bmModGQ6IFRleHR1cmVEYXRhLCBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLCBjaGFubmVscz86IG51bWJlcik6IFByb21pc2U8VGVuc29yLk51bWJlclR5cGU+IHtcbiAgICBjb25zdCBkYXRhSWQgPSB0ZC50ZW5zb3IuZGF0YUlkO1xuICAgIGlmICghY2hhbm5lbHMpIHtcbiAgICAgIGNoYW5uZWxzID0gMTtcbiAgICB9XG4gICAgaWYgKHRoaXMucGVuZGluZ1JlYWQuaGFzKGRhdGFJZCkpIHtcbiAgICAgIGNvbnN0IHN1YnNjcmliZXJzID0gdGhpcy5wZW5kaW5nUmVhZC5nZXQoZGF0YUlkKTtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxUZW5zb3IuTnVtYmVyVHlwZT4oKHJlc29sdmUpID0+IHN1YnNjcmliZXJzPy5wdXNoKHJlc29sdmUpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnVGV4dHVyZU1hbmFnZXIucmVhZFRleHR1cmVBc3luYycsIGFzeW5jICgpID0+IHtcbiAgICAgIHRoaXMucGVuZGluZ1JlYWQuc2V0KGRhdGFJZCwgW10pO1xuICAgICAgY29uc3QgZGF0YVNpemUgPSB0ZC5zaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKSAqIGNoYW5uZWxzITtcbiAgICAgIC8vIGFkZCBhIGZlbmNlIHdhaXRpbmcgZm9yIHRoZSBkYXRhIHRvIGJlIHJlYWR5XG4gICAgICBhd2FpdCB0aGlzLmdsQ29udGV4dC5jcmVhdGVBbmRXYWl0Rm9yRmVuY2UoKTtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdsQ29udGV4dC5yZWFkVGV4dHVyZShcbiAgICAgICAgdGQudGV4dHVyZSxcbiAgICAgICAgdGQud2lkdGgsXG4gICAgICAgIHRkLmhlaWdodCxcbiAgICAgICAgZGF0YVNpemUsXG4gICAgICAgIHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSksXG4gICAgICAgIGNoYW5uZWxzISxcbiAgICAgICk7XG4gICAgICBjb25zdCB0ZW5zb3JEYXRhID0gdGhpcy50b1RlbnNvckRhdGEoZGF0YVR5cGUsIGRhdGEpO1xuICAgICAgY29uc3Qgc3Vic2NyaWJlcnMgPSB0aGlzLnBlbmRpbmdSZWFkLmdldChkYXRhSWQpO1xuICAgICAgdGhpcy5wZW5kaW5nUmVhZC5kZWxldGUoZGF0YUlkKTtcbiAgICAgIHN1YnNjcmliZXJzPy5mb3JFYWNoKChyZXNvbHZlKSA9PiByZXNvbHZlKHRlbnNvckRhdGEpKTtcbiAgICAgIHJldHVybiB0ZW5zb3JEYXRhO1xuICAgIH0pO1xuICB9XG4gIHJlYWRVaW50OFRleHR1cmVBc0Zsb2F0KHRkOiBUZXh0dXJlRGF0YSk6IEZsb2F0MzJBcnJheSB7XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnVGV4dHVyZU1hbmFnZXIucmVhZFVpbnQ4VGV4dHVyZUFzRmxvYXQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBkYXRhU2l6ZSA9IHRkLnNoYXBlLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZ2xDb250ZXh0LnJlYWRUZXh0dXJlKHRkLnRleHR1cmUsIHRkLndpZHRoLCB0ZC5oZWlnaHQsIGRhdGFTaXplICogNCwgJ2J5dGUnLCA0KTtcbiAgICAgIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KGRhdGEuYnVmZmVyLCBkYXRhLmJ5dGVPZmZzZXQsIGRhdGFTaXplKTtcbiAgICB9KTtcbiAgfVxuICByZWxlYXNlVGV4dHVyZSh0ZXh0dXJlRGF0YTogVGV4dHVyZURhdGEsIGRlbGV0ZVRleHR1cmU/OiBib29sZWFuKTogdm9pZCB7XG4gICAgbGV0IGtleTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGlmICh0aGlzLmNvbmZpZy5yZXVzZVRleHR1cmVzKSB7XG4gICAgICBrZXkgPSB0aGlzLnRleHR1cmVMb29rdXAuZ2V0KHRleHR1cmVEYXRhLnRleHR1cmUpO1xuICAgICAgaWYgKGtleSkge1xuICAgICAgICBpZiAoZGVsZXRlVGV4dHVyZSkge1xuICAgICAgICAgIHRoaXMudGV4dHVyZUxvb2t1cC5kZWxldGUoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpblVzZVRleHR1cmVzID0gdGhpcy5pblVzZVRleHR1cmVzLmdldChrZXkpO1xuICAgICAgICBpZiAoaW5Vc2VUZXh0dXJlcykge1xuICAgICAgICAgIGNvbnN0IGluZGV4ID0gaW5Vc2VUZXh0dXJlcy5pbmRleE9mKHRleHR1cmVEYXRhLnRleHR1cmUpO1xuICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIGluVXNlVGV4dHVyZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIGxldCBpZGxlVGV4dHVyZXMgPSB0aGlzLmlkbGVUZXh0dXJlcy5nZXQoa2V5KTtcbiAgICAgICAgICAgIGlmICghaWRsZVRleHR1cmVzKSB7XG4gICAgICAgICAgICAgIGlkbGVUZXh0dXJlcyA9IFtdO1xuICAgICAgICAgICAgICB0aGlzLmlkbGVUZXh0dXJlcy5zZXQoa2V5LCBpZGxlVGV4dHVyZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWRsZVRleHR1cmVzLnB1c2godGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFrZXkgfHwgZGVsZXRlVGV4dHVyZSkge1xuICAgICAgTG9nZ2VyLnZlcmJvc2UoJ1RleHR1cmVNYW5hZ2VyJywgYERlbGV0aW5nIHRleHR1cmUgb2Ygc2l6ZSAke3RleHR1cmVEYXRhLndpZHRofXgke3RleHR1cmVEYXRhLmhlaWdodH1gKTtcbiAgICAgIHRoaXMuZ2xDb250ZXh0LmRlbGV0ZVRleHR1cmUodGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgfVxuICB9XG4gIHRvVGVuc29yRGF0YShkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLCBkYXRhOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUpOiBUZW5zb3IuTnVtYmVyVHlwZSB7XG4gICAgc3dpdGNoIChkYXRhVHlwZSkge1xuICAgICAgY2FzZSAnaW50MTYnOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEludDE2QXJyYXkgPyBkYXRhIDogSW50MTZBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAnaW50MzInOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEludDMyQXJyYXkgPyBkYXRhIDogSW50MzJBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAnaW50OCc6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgSW50OEFycmF5ID8gZGF0YSA6IEludDhBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAndWludDE2JzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBVaW50MTZBcnJheSA/IGRhdGEgOiBVaW50MTZBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAndWludDMyJzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBVaW50MzJBcnJheSA/IGRhdGEgOiBVaW50MzJBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAndWludDgnOlxuICAgICAgY2FzZSAnYm9vbCc6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgVWludDhBcnJheSA/IGRhdGEgOiBVaW50OEFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyBkYXRhIDogRmxvYXQzMkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkgPyBkYXRhIDogRmxvYXQ2NEFycmF5LmZyb20oZGF0YSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRlbnNvckRhdGEgdHlwZSAke2RhdGFUeXBlfSBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gICAgfVxuICB9XG4gIHRvVGV4dHVyZURhdGEoX2RhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsIGRhdGE6IFRlbnNvci5OdW1iZXJUeXBlIHwgdW5kZWZpbmVkKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWRhdGEpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gZGF0YSA6IG5ldyBGbG9hdDMyQXJyYXkoZGF0YSk7XG4gICAgLypcbiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICBjYXNlICd1aW50MTYnOlxuICAgICAgY2FzZSAndWludDMyJzpcbiAgICAgICAgcmV0dXJuIChkYXRhLmNvbnN0cnVjdG9yID09PSBVaW50MzJBcnJheSkgPyBkYXRhIGFzIFVpbnQzMkFycmF5IDogbmV3IFVpbnQzMkFycmF5KGRhdGEpO1xuICAgICAgY2FzZSAnaW50OCc6XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICBjYXNlICdib29sJzpcbiAgICAgICAgcmV0dXJuIChkYXRhLmNvbnN0cnVjdG9yID09PSBVaW50OEFycmF5KSA/IGRhdGEgYXMgVWludDhBcnJheSA6IG5ldyBVaW50OEFycmF5KGRhdGEpO1xuICAgICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIChkYXRhLmNvbnN0cnVjdG9yID09PSBGbG9hdDMyQXJyYXkpID8gZGF0YSBhcyBGbG9hdDMyQXJyYXkgOiBuZXcgRmxvYXQzMkFycmF5KGRhdGEpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW5zb3JEYXRhIHR5cGUgJHtkYXRhVHlwZX0gaXMgbm90IHN1cHBvcnRlZGApO1xuICAgIH1cbiAgICAqL1xuICB9XG4gIHRvRW5jb2RlclR5cGUoX2RhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUpOiBFbmNvZGVyLkRhdGFUeXBlIHtcbiAgICByZXR1cm4gJ2Zsb2F0JztcbiAgICAvLyBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgLy8gICBjYXNlICdpbnQxNic6XG4gICAgLy8gICBjYXNlICdpbnQzMic6XG4gICAgLy8gICBjYXNlICd1aW50MTYnOlxuICAgIC8vICAgY2FzZSAndWludDMyJzpcbiAgICAvLyAgICAgcmV0dXJuICdpbnQnO1xuICAgIC8vICAgY2FzZSAndWludDgnOlxuICAgIC8vICAgY2FzZSAnYm9vbCc6XG4gICAgLy8gICAgIHJldHVybiAnYnl0ZSc7XG4gICAgLy8gICBjYXNlICdmbG9hdDMyJzpcbiAgICAvLyAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgIC8vICAgICByZXR1cm4gJ2Zsb2F0JztcbiAgICAvLyAgIGRlZmF1bHQ6XG4gICAgLy8gICAgIHRocm93IG5ldyBFcnJvcihgVGVuc29yRGF0YSB0eXBlICR7ZGF0YVR5cGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICAvLyB9XG4gIH1cbiAgY2xlYXJBY3RpdmVUZXh0dXJlcygpOiB2b2lkIHtcbiAgICB0aGlzLmdsQ29udGV4dC5jbGVhckFjdGl2ZVRleHR1cmVzKCk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuLi8uLi9iYWNrZW5kJztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQgeyBPcGVyYXRvciB9IGZyb20gJy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBPcFNldCwgcmVzb2x2ZU9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vb3BzZXQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL3Nlc3Npb24nO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMQmFja2VuZCB9IGZyb20gJy4uL2JhY2tlbmQtd2ViZ2wnO1xuXG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFdFQkdMX09QX1JFU09MVkVfUlVMRVMgfSBmcm9tICcuL29wLXJlc29sdmUtcnVsZXMnO1xuaW1wb3J0IHsgUHJvZ3JhbU1hbmFnZXIgfSBmcm9tICcuL3Byb2dyYW0tbWFuYWdlcic7XG5pbXBvcnQgeyBQcmVmZXJMb2dpY2FsU3RyYXRlZ3ksIFRleHR1cmVMYXlvdXRTdHJhdGVneSB9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHsgVGV4dHVyZU1hbmFnZXIgfSBmcm9tICcuL3RleHR1cmUtbWFuYWdlcic7XG5pbXBvcnQgeyBUZXh0dXJlRGF0YSB9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgY2xhc3MgV2ViR0xTZXNzaW9uSGFuZGxlciBpbXBsZW1lbnRzIFNlc3Npb25IYW5kbGVyIHtcbiAgcHJvZ3JhbU1hbmFnZXI6IFByb2dyYW1NYW5hZ2VyO1xuICB0ZXh0dXJlTWFuYWdlcjogVGV4dHVyZU1hbmFnZXI7XG4gIGxheW91dFN0cmF0ZWd5OiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3k7XG4gIHBhY2tlZFRleHR1cmVEYXRhQ2FjaGU6IE1hcDxUZW5zb3IuSWQsIFRleHR1cmVEYXRhPjtcbiAgdW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlOiBNYXA8VGVuc29yLklkLCBUZXh0dXJlRGF0YT47XG4gIHBhY2sydW5wYWNrTWFwOiBNYXA8VGVuc29yLklkLCBUZW5zb3IuSWQ+O1xuICB1bnBhY2sycGFja01hcDogTWFwPFRlbnNvci5JZCwgVGVuc29yLklkPjtcbiAgaW5pdGlhbGl6ZXJzOiBTZXQ8VGVuc29yLklkPjtcbiAgcGFjaz86IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGJhY2tlbmQ6IFdlYkdMQmFja2VuZCxcbiAgICBwdWJsaWMgcmVhZG9ubHkgY29udGV4dDogU2Vzc2lvbi5Db250ZXh0LFxuICApIHtcbiAgICB0aGlzLmxheW91dFN0cmF0ZWd5ID0gbmV3IFByZWZlckxvZ2ljYWxTdHJhdGVneShiYWNrZW5kLmdsQ29udGV4dC5tYXhUZXh0dXJlU2l6ZSk7XG4gICAgdGhpcy5wcm9ncmFtTWFuYWdlciA9IG5ldyBQcm9ncmFtTWFuYWdlcih0aGlzLmNvbnRleHQucHJvZmlsZXIsIGJhY2tlbmQuZ2xDb250ZXh0LCB0aGlzLmxheW91dFN0cmF0ZWd5KTtcbiAgICB0aGlzLnRleHR1cmVNYW5hZ2VyID0gbmV3IFRleHR1cmVNYW5hZ2VyKGJhY2tlbmQuZ2xDb250ZXh0LCB0aGlzLmxheW91dFN0cmF0ZWd5LCB0aGlzLmNvbnRleHQucHJvZmlsZXIsIHtcbiAgICAgIHJldXNlVGV4dHVyZXM6IGJhY2tlbmQudGV4dHVyZUNhY2hlTW9kZSA9PT0gJ2Z1bGwnLFxuICAgIH0pO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnBhY2sgPSBiYWNrZW5kLnBhY2s7XG4gICAgdGhpcy5wYWNrMnVucGFja01hcCA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFjazJwYWNrTWFwID0gbmV3IE1hcCgpO1xuICB9XG5cbiAgY3JlYXRlSW5mZXJlbmNlSGFuZGxlcigpIHtcbiAgICByZXR1cm4gbmV3IFdlYkdMSW5mZXJlbmNlSGFuZGxlcih0aGlzKTtcbiAgfVxuICBvbkdyYXBoSW5pdGlhbGl6ZWQoZ3JhcGg6IEdyYXBoKTogdm9pZCB7XG4gICAgY29uc3QgaW5pdGlhbGl6ZXJzID0gZ3JhcGhcbiAgICAgIC5nZXRWYWx1ZXMoKVxuICAgICAgLmZpbHRlcigodikgPT4gdi5mcm9tID09PSAtMSAmJiB2LnRlbnNvcilcbiAgICAgIC5tYXAoKHYpID0+IHYudGVuc29yIS5kYXRhSWQpO1xuICAgIHRoaXMuaW5pdGlhbGl6ZXJzID0gbmV3IFNldChpbml0aWFsaXplcnMpO1xuICB9XG4gIGlzSW5pdGlhbGl6ZXIodGVuc29ySWQ6IFRlbnNvci5JZCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmluaXRpYWxpemVycyA/IHRoaXMuaW5pdGlhbGl6ZXJzLmhhcyh0ZW5zb3JJZCkgOiBmYWxzZTtcbiAgfVxuICBhZGRJbml0aWFsaXplcih0ZW5zb3JJZDogVGVuc29yLklkKTogdm9pZCB7XG4gICAgdGhpcy5pbml0aWFsaXplcnMuYWRkKHRlbnNvcklkKTtcbiAgfVxuICBnZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZDogVGVuc29yLklkLCBpc1BhY2tlZDogYm9vbGVhbik6IFRleHR1cmVEYXRhIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoaXNQYWNrZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZ2V0KHRlbnNvcklkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmdldCh0ZW5zb3JJZCk7XG4gICAgfVxuICB9XG4gIHNldFRleHR1cmVEYXRhKHRlbnNvcklkOiBUZW5zb3IuSWQsIHRleHR1cmVEYXRhOiBUZXh0dXJlRGF0YSwgaXNQYWNrZWQgPSBmYWxzZSk6IHZvaWQge1xuICAgIExvZ2dlci52ZXJib3NlKCdXZWJHTFNlc3Npb25IYW5kbGVyJywgJ1N0b3JpbmcgVGV4dHVyZSBkYXRhIGluIGNhY2hlJyk7XG4gICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuc2V0KHRlbnNvcklkLCB0ZXh0dXJlRGF0YSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLnNldCh0ZW5zb3JJZCwgdGV4dHVyZURhdGEpO1xuICAgIH1cbiAgfVxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMucHJvZ3JhbU1hbmFnZXIuZGlzcG9zZSgpO1xuICAgIHRoaXMudGV4dHVyZU1hbmFnZXIuY2xlYXJBY3RpdmVUZXh0dXJlcygpO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5mb3JFYWNoKCh0ZCkgPT4gdGhpcy50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCwgdHJ1ZSkpO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZS5mb3JFYWNoKCh0ZCkgPT4gdGhpcy50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCwgdHJ1ZSkpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICB9XG4gIHJlc29sdmUobm9kZTogR3JhcGguTm9kZSwgb3BzZXRzOiByZWFkb25seSBPcFNldFtdLCBncmFwaDogR3JhcGgpOiBPcGVyYXRvciB7XG4gICAgY29uc3Qgb3AgPSByZXNvbHZlT3BlcmF0b3Iobm9kZSwgb3BzZXRzLCBXRUJHTF9PUF9SRVNPTFZFX1JVTEVTKTtcbiAgICByZXR1cm4geyBpbXBsOiBvcC5vcEltcGwsIGNvbnRleHQ6IG9wLm9wSW5pdCA/IG9wLm9wSW5pdChub2RlLCBncmFwaCkgOiBub2RlIH07XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZW52IH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0ICogYXMgRGF0YUVuY29kZXJzIGZyb20gJy4vdGV4dHVyZS1kYXRhLWVuY29kZXInO1xuaW1wb3J0IHsgRGF0YUVuY29kZXIsIEVuY29kZXIsIEVuY29kZXJVc2FnZSB9IGZyb20gJy4vdGV4dHVyZS1kYXRhLWVuY29kZXInO1xuaW1wb3J0IHsgcmVwZWF0ZWRUcnkgfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBGZW5jZUNvbnRleHQge1xuICBxdWVyeTogV2ViR0xTeW5jIHwgbnVsbDtcbiAgaXNGZW5jZVBhc3NlZCgpOiBib29sZWFuO1xufVxuXG50eXBlIFBvbGxJdGVtID0ge1xuICBpc0RvbmVGbjogKCkgPT4gYm9vbGVhbjtcbiAgcmVzb2x2ZUZuOiAoKSA9PiB2b2lkO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhclNlYXJjaExhc3RUcnVlKGFycjogQXJyYXk8KCkgPT4gYm9vbGVhbj4pOiBudW1iZXIge1xuICBsZXQgaSA9IDA7XG4gIGZvciAoOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgaXNEb25lID0gYXJyW2ldKCk7XG4gICAgaWYgKCFpc0RvbmUpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gaSAtIDE7XG59XG5cbi8qKlxuICogQWJzdHJhY3Rpb24gYW5kIHdyYXBwZXIgYXJvdW5kIFdlYkdMUmVuZGVyaW5nQ29udGV4dCBhbmQgaXRzIG9wZXJhdGlvbnNcbiAqL1xuZXhwb3J0IGNsYXNzIFdlYkdMQ29udGV4dCB7XG4gIGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQ7XG4gIHZlcnNpb246IDEgfCAyO1xuXG4gIHByaXZhdGUgdmVydGV4YnVmZmVyOiBXZWJHTEJ1ZmZlcjtcbiAgcHJpdmF0ZSBmcmFtZWJ1ZmZlcjogV2ViR0xGcmFtZWJ1ZmZlcjtcblxuICAvLyBXZWJHTCBmbGFncyBhbmQgdml0YWwgcGFyYW1ldGVyc1xuICBwcml2YXRlIGlzRmxvYXRUZXh0dXJlQXR0YWNoYWJsZVRvRnJhbWVCdWZmZXI6IGJvb2xlYW47XG4gIGlzRmxvYXQzMkRvd25sb2FkU3VwcG9ydGVkOiBib29sZWFuO1xuICBpc1JlbmRlckZsb2F0MzJTdXBwb3J0ZWQ6IGJvb2xlYW47XG4gIGlzQmxlbmRTdXBwb3J0ZWQ6IGJvb2xlYW47XG4gIG1heFRleHR1cmVTaXplOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbWF4Q29tYmluZWRUZXh0dXJlSW1hZ2VVbml0czogbnVtYmVyO1xuICBwcml2YXRlIG1heFRleHR1cmVJbWFnZVVuaXRzOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbWF4Q3ViZU1hcFRleHR1cmVTaXplOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgc2hhZGluZ0xhbmd1YWdlVmVyc2lvbjogc3RyaW5nO1xuICAvLyBwcml2YXRlIHdlYmdsVmVuZG9yOiBzdHJpbmc7XG4gIC8vIHByaXZhdGUgd2ViZ2xWZXJzaW9uOiBzdHJpbmc7XG5cbiAgLy8gV2ViR0wyIGZsYWdzIGFuZCB2aXRhbCBwYXJhbWV0ZXJzXG4gIC8vIHByaXZhdGUgbWF4M0RUZXh0dXJlU2l6ZTogbnVtYmVyO1xuICAvLyBwcml2YXRlIG1heEFycmF5VGV4dHVyZUxheWVyczogbnVtYmVyO1xuICAvLyBwcml2YXRlIG1heENvbG9yQXR0YWNobWVudHM6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBtYXhEcmF3QnVmZmVyczogbnVtYmVyO1xuXG4gIC8vIFdlYkdMIGV4dGVuc2lvbnNcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNhbWVsY2FzZVxuICB0ZXh0dXJlRmxvYXRFeHRlbnNpb246IE9FU190ZXh0dXJlX2Zsb2F0IHwgbnVsbDtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNhbWVsY2FzZVxuICB0ZXh0dXJlSGFsZkZsb2F0RXh0ZW5zaW9uOiBPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0IHwgbnVsbDtcblxuICAvLyBXZWJHTDIgZXh0ZW5zaW9uc1xuICBjb2xvckJ1ZmZlckZsb2F0RXh0ZW5zaW9uOiB1bmtub3duIHwgbnVsbDtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuICBkaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb246IHsgVElNRV9FTEFQU0VEX0VYVDogR0xlbnVtOyBHUFVfRElTSk9JTlRfRVhUOiBHTGVudW0gfSB8IG51bGw7XG5cbiAgcHJpdmF0ZSBkaXNwb3NlZDogYm9vbGVhbjtcbiAgcHJpdmF0ZSBmcmFtZUJ1ZmZlckJvdW5kID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdmVyc2lvbjogMSB8IDIpIHtcbiAgICB0aGlzLmdsID0gZ2w7XG4gICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjtcblxuICAgIHRoaXMuZ2V0RXh0ZW5zaW9ucygpO1xuICAgIHRoaXMudmVydGV4YnVmZmVyID0gdGhpcy5jcmVhdGVWZXJ0ZXhidWZmZXIoKTtcbiAgICB0aGlzLmZyYW1lYnVmZmVyID0gdGhpcy5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgIHRoaXMucXVlcnlWaXRhbFBhcmFtZXRlcnMoKTtcbiAgfVxuXG4gIGFsbG9jYXRlVGV4dHVyZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgZW5jb2RlcjogRGF0YUVuY29kZXIsIGRhdGE/OiBFbmNvZGVyLkRhdGFBcnJheVR5cGUpOiBXZWJHTFRleHR1cmUge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAvLyBjcmVhdGUgdGhlIHRleHR1cmVcbiAgICBjb25zdCB0ZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuICAgIC8vIGJpbmQgdGhlIHRleHR1cmUgc28gdGhlIGZvbGxvd2luZyBtZXRob2RzIGVmZmVjdCB0aGlzIHRleHR1cmUuXG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01JTl9GSUxURVIsIGdsLk5FQVJFU1QpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NQUdfRklMVEVSLCBnbC5ORUFSRVNUKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9TLCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9ULCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICBjb25zdCBidWZmZXIgPSBkYXRhID8gZW5jb2Rlci5lbmNvZGUoZGF0YSwgd2lkdGggKiBoZWlnaHQpIDogbnVsbDtcbiAgICBnbC50ZXhJbWFnZTJEKFxuICAgICAgZ2wuVEVYVFVSRV8yRCxcbiAgICAgIDAsIC8vIExldmVsIG9mIGRldGFpbC5cbiAgICAgIGVuY29kZXIuaW50ZXJuYWxGb3JtYXQsXG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIDAsIC8vIEFsd2F5cyAwIGluIE9wZW5HTCBFUy5cbiAgICAgIGVuY29kZXIuZm9ybWF0LFxuICAgICAgZW5jb2Rlci50ZXh0dXJlVHlwZSxcbiAgICAgIGJ1ZmZlcixcbiAgICApO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICAgIHJldHVybiB0ZXh0dXJlIGFzIFdlYkdMVGV4dHVyZTtcbiAgfVxuICB1cGRhdGVUZXh0dXJlKFxuICAgIHRleHR1cmU6IFdlYkdMVGV4dHVyZSxcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIGVuY29kZXI6IERhdGFFbmNvZGVyLFxuICAgIGRhdGE6IEVuY29kZXIuRGF0YUFycmF5VHlwZSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIGNvbnN0IGJ1ZmZlciA9IGVuY29kZXIuZW5jb2RlKGRhdGEsIHdpZHRoICogaGVpZ2h0KTtcbiAgICBnbC50ZXhTdWJJbWFnZTJEKFxuICAgICAgZ2wuVEVYVFVSRV8yRCxcbiAgICAgIDAsIC8vIGxldmVsXG4gICAgICAwLCAvLyB4b2Zmc2V0XG4gICAgICAwLCAvLyB5b2Zmc2V0XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIGVuY29kZXIuZm9ybWF0LFxuICAgICAgZW5jb2Rlci50ZXh0dXJlVHlwZSxcbiAgICAgIGJ1ZmZlcixcbiAgICApO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGF0dGFjaEZyYW1lYnVmZmVyKHRleHR1cmU6IFdlYkdMVGV4dHVyZSwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgLy8gTWFrZSBpdCB0aGUgdGFyZ2V0IGZvciBmcmFtZWJ1ZmZlciBvcGVyYXRpb25zIC0gaW5jbHVkaW5nIHJlbmRlcmluZy5cbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIHRoaXMuZnJhbWVidWZmZXIpO1xuICAgIGdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGdsLkZSQU1FQlVGRkVSLCBnbC5DT0xPUl9BVFRBQ0hNRU5UMCwgZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSwgMCk7IC8vIDAsIHdlIGFyZW4ndCB1c2luZyBNSVBNQVBzXG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgZ2wudmlld3BvcnQoMCwgMCwgd2lkdGgsIGhlaWdodCk7XG4gICAgZ2wuc2Npc3NvcigwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgfVxuICByZWFkVGV4dHVyZShcbiAgICB0ZXh0dXJlOiBXZWJHTFRleHR1cmUsXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICBkYXRhU2l6ZTogbnVtYmVyLFxuICAgIGRhdGFUeXBlOiBFbmNvZGVyLkRhdGFUeXBlLFxuICAgIGNoYW5uZWxzOiBudW1iZXIsXG4gICk6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGlmICghY2hhbm5lbHMpIHtcbiAgICAgIGNoYW5uZWxzID0gMTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmZyYW1lQnVmZmVyQm91bmQpIHtcbiAgICAgIHRoaXMuYXR0YWNoRnJhbWVidWZmZXIodGV4dHVyZSwgd2lkdGgsIGhlaWdodCk7XG4gICAgfVxuICAgIGNvbnN0IGVuY29kZXIgPSB0aGlzLmdldEVuY29kZXIoZGF0YVR5cGUsIGNoYW5uZWxzKTtcbiAgICBjb25zdCBidWZmZXIgPSBlbmNvZGVyLmFsbG9jYXRlKHdpZHRoICogaGVpZ2h0KTtcbiAgICAvLyBiaW5kIHRleHR1cmUgdG8gZnJhbWVidWZmZXJcbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICBnbC5mcmFtZWJ1ZmZlclRleHR1cmUyRChnbC5GUkFNRUJVRkZFUiwgZ2wuQ09MT1JfQVRUQUNITUVOVDAsIGdsLlRFWFRVUkVfMkQsIHRleHR1cmUsIDApOyAvLyAwLCB3ZSBhcmVuJ3QgdXNpbmcgTUlQTUFQc1xuICAgIC8vIFRPRE86IENoZWNrIGlmIGZyYW1lYnVmZmVyIGlzIHJlYWR5XG4gICAgZ2wucmVhZFBpeGVscygwLCAwLCB3aWR0aCwgaGVpZ2h0LCBnbC5SR0JBLCBlbmNvZGVyLnRleHR1cmVUeXBlLCBidWZmZXIpO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICAgIC8vIHVuYmluZCBGQlxuICAgIHJldHVybiBlbmNvZGVyLmRlY29kZShidWZmZXIsIGRhdGFTaXplKTtcbiAgfVxuXG4gIGlzRnJhbWVidWZmZXJSZWFkeSgpOiBib29sZWFuIHtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgbG9naWMgdG8gY2hlY2sgaWYgdGhlIGZyYW1lYnVmZmVyIGlzIHJlYWR5XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgZ2V0QWN0aXZlVGV4dHVyZSgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBuID0gZ2wuZ2V0UGFyYW1ldGVyKHRoaXMuZ2wuQUNUSVZFX1RFWFRVUkUpO1xuICAgIHJldHVybiBgVEVYVFVSRSR7biAtIGdsLlRFWFRVUkUwfWA7XG4gIH1cbiAgZ2V0VGV4dHVyZUJpbmRpbmcoKTogV2ViR0xUZXh0dXJlIHtcbiAgICByZXR1cm4gdGhpcy5nbC5nZXRQYXJhbWV0ZXIodGhpcy5nbC5URVhUVVJFX0JJTkRJTkdfMkQpO1xuICB9XG4gIGdldEZyYW1lYnVmZmVyQmluZGluZygpOiBXZWJHTEZyYW1lYnVmZmVyIHtcbiAgICByZXR1cm4gdGhpcy5nbC5nZXRQYXJhbWV0ZXIodGhpcy5nbC5GUkFNRUJVRkZFUl9CSU5ESU5HKTtcbiAgfVxuICBzZXRWZXJ0ZXhBdHRyaWJ1dGVzKHBvc2l0aW9uSGFuZGxlOiBudW1iZXIsIHRleHR1cmVDb29yZEhhbmRsZTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIocG9zaXRpb25IYW5kbGUsIDMsIGdsLkZMT0FULCBmYWxzZSwgMjAsIDApO1xuICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHBvc2l0aW9uSGFuZGxlKTtcbiAgICBpZiAodGV4dHVyZUNvb3JkSGFuZGxlICE9PSAtMSkge1xuICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcih0ZXh0dXJlQ29vcmRIYW5kbGUsIDIsIGdsLkZMT0FULCBmYWxzZSwgMjAsIDEyKTtcbiAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHRleHR1cmVDb29yZEhhbmRsZSk7XG4gICAgfVxuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGNyZWF0ZVByb2dyYW0odmVydGV4U2hhZGVyOiBXZWJHTFNoYWRlciwgZnJhZ1NoYWRlcjogV2ViR0xTaGFkZXIpOiBXZWJHTFByb2dyYW0ge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBwcm9ncmFtID0gZ2wuY3JlYXRlUHJvZ3JhbSgpITtcblxuICAgIC8vIHRoZSBwcm9ncmFtIGNvbnNpc3RzIG9mIG91ciBzaGFkZXJzXG4gICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIHZlcnRleFNoYWRlcik7XG4gICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIGZyYWdTaGFkZXIpO1xuICAgIGdsLmxpbmtQcm9ncmFtKHByb2dyYW0pO1xuICAgIHJldHVybiBwcm9ncmFtO1xuICB9XG4gIGNvbXBpbGVTaGFkZXIoc2hhZGVyU291cmNlOiBzdHJpbmcsIHNoYWRlclR5cGU6IG51bWJlcik6IFdlYkdMU2hhZGVyIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgY29uc3Qgc2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKHNoYWRlclR5cGUpO1xuICAgIGlmICghc2hhZGVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNyZWF0ZVNoYWRlcigpIHJldHVybmVkIG51bGwgd2l0aCB0eXBlICR7c2hhZGVyVHlwZX1gKTtcbiAgICB9XG5cbiAgICBnbC5zaGFkZXJTb3VyY2Uoc2hhZGVyLCBzaGFkZXJTb3VyY2UpO1xuICAgIGdsLmNvbXBpbGVTaGFkZXIoc2hhZGVyKTtcbiAgICBpZiAoZ2wuZ2V0U2hhZGVyUGFyYW1ldGVyKHNoYWRlciwgZ2wuQ09NUElMRV9TVEFUVVMpID09PSBmYWxzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gY29tcGlsZSBzaGFkZXI6ICR7Z2wuZ2V0U2hhZGVySW5mb0xvZyhzaGFkZXIpfVxuU2hhZGVyIHNvdXJjZTpcbiR7c2hhZGVyU291cmNlfWApO1xuICAgIH1cbiAgICByZXR1cm4gc2hhZGVyO1xuICB9XG4gIGRlbGV0ZVNoYWRlcihzaGFkZXI6IFdlYkdMU2hhZGVyKTogdm9pZCB7XG4gICAgdGhpcy5nbC5kZWxldGVTaGFkZXIoc2hhZGVyKTtcbiAgfVxuICBiaW5kVGV4dHVyZVRvVW5pZm9ybSh0ZXh0dXJlOiBXZWJHTFRleHR1cmUsIHBvc2l0aW9uOiBudW1iZXIsIHVuaWZvcm1IYW5kbGU6IFdlYkdMVW5pZm9ybUxvY2F0aW9uKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGdsLmFjdGl2ZVRleHR1cmUoZ2wuVEVYVFVSRTAgKyBwb3NpdGlvbik7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgZ2wudW5pZm9ybTFpKHVuaWZvcm1IYW5kbGUsIHBvc2l0aW9uKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgfVxuICBkcmF3KCk6IHZvaWQge1xuICAgIHRoaXMuZ2wuZHJhd0FycmF5cyh0aGlzLmdsLlRSSUFOR0xFX1NUUklQLCAwLCA0KTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgfVxuICBjaGVja0Vycm9yKCk6IHZvaWQge1xuICAgIGlmIChlbnYuZGVidWcpIHtcbiAgICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAgIGNvbnN0IGVycm9yID0gZ2wuZ2V0RXJyb3IoKTtcbiAgICAgIGxldCBsYWJlbCA9ICcnO1xuICAgICAgc3dpdGNoIChlcnJvcikge1xuICAgICAgICBjYXNlIGdsLk5PX0VSUk9SOlxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY2FzZSBnbC5JTlZBTElEX0VOVU06XG4gICAgICAgICAgbGFiZWwgPSAnSU5WQUxJRF9FTlVNJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBnbC5JTlZBTElEX1ZBTFVFOlxuICAgICAgICAgIGxhYmVsID0gJ0lOVkFMSURfVkFMVUUnO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIGdsLklOVkFMSURfT1BFUkFUSU9OOlxuICAgICAgICAgIGxhYmVsID0gJ0lOVkFMSURfT1BFUkFUSU9OJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBnbC5JTlZBTElEX0ZSQU1FQlVGRkVSX09QRVJBVElPTjpcbiAgICAgICAgICBsYWJlbCA9ICdJTlZBTElEX0ZSQU1FQlVGRkVSX09QRVJBVElPTic7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgZ2wuT1VUX09GX01FTU9SWTpcbiAgICAgICAgICBsYWJlbCA9ICdPVVRfT0ZfTUVNT1JZJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBnbC5DT05URVhUX0xPU1RfV0VCR0w6XG4gICAgICAgICAgbGFiZWwgPSAnQ09OVEVYVF9MT1NUX1dFQkdMJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBsYWJlbCA9IGBVbmtub3duIFdlYkdMIEVycm9yOiAke2Vycm9yLnRvU3RyaW5nKDE2KX1gO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGxhYmVsKTtcbiAgICB9XG4gIH1cbiAgZGVsZXRlVGV4dHVyZSh0ZXh0dXJlOiBXZWJHTFRleHR1cmUpOiB2b2lkIHtcbiAgICB0aGlzLmdsLmRlbGV0ZVRleHR1cmUodGV4dHVyZSk7XG4gIH1cbiAgZGVsZXRlUHJvZ3JhbShwcm9ncmFtOiBXZWJHTFByb2dyYW0pOiB2b2lkIHtcbiAgICB0aGlzLmdsLmRlbGV0ZVByb2dyYW0ocHJvZ3JhbSk7XG4gIH1cbiAgZ2V0RW5jb2RlcihkYXRhVHlwZTogRW5jb2Rlci5EYXRhVHlwZSwgY2hhbm5lbHM6IG51bWJlciwgdXNhZ2U6IEVuY29kZXJVc2FnZSA9IEVuY29kZXJVc2FnZS5EZWZhdWx0KTogRGF0YUVuY29kZXIge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIHJldHVybiBuZXcgRGF0YUVuY29kZXJzLlJlZEZsb2F0MzJEYXRhRW5jb2Rlcih0aGlzLmdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQsIGNoYW5uZWxzKTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICBjYXNlICdmbG9hdCc6XG4gICAgICAgIGlmICh1c2FnZSA9PT0gRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkgfHwgdGhpcy5pc1JlbmRlckZsb2F0MzJTdXBwb3J0ZWQpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IERhdGFFbmNvZGVycy5SR0JBRmxvYXREYXRhRW5jb2Rlcih0aGlzLmdsLCBjaGFubmVscyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBEYXRhRW5jb2RlcnMuUkdCQUZsb2F0RGF0YUVuY29kZXIoXG4gICAgICAgICAgICB0aGlzLmdsLFxuICAgICAgICAgICAgY2hhbm5lbHMsXG4gICAgICAgICAgICB0aGlzLnRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb24hLkhBTEZfRkxPQVRfT0VTLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgJ2ludCc6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJyk7XG4gICAgICBjYXNlICdieXRlJzpcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRhRW5jb2RlcnMuVWludDhEYXRhRW5jb2Rlcih0aGlzLmdsLCBjaGFubmVscyk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGF0YVR5cGU6ICR7ZGF0YVR5cGV9YCk7XG4gICAgfVxuICB9XG4gIGNsZWFyQWN0aXZlVGV4dHVyZXMoKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGZvciAobGV0IHVuaXQgPSAwOyB1bml0IDwgdGhpcy5tYXhUZXh0dXJlSW1hZ2VVbml0czsgKyt1bml0KSB7XG4gICAgICBnbC5hY3RpdmVUZXh0dXJlKGdsLlRFWFRVUkUwICsgdW5pdCk7XG4gICAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCBudWxsKTtcbiAgICB9XG4gIH1cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNwb3NlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBudWxsKTtcbiAgICBnbC5kZWxldGVGcmFtZWJ1ZmZlcih0aGlzLmZyYW1lYnVmZmVyKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgbnVsbCk7XG4gICAgZ2wuZGVsZXRlQnVmZmVyKHRoaXMudmVydGV4YnVmZmVyKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkVMRU1FTlRfQVJSQVlfQlVGRkVSLCBudWxsKTtcbiAgICBnbC5maW5pc2goKTtcbiAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRGVmYXVsdEdlb21ldHJ5KCk6IEZsb2F0MzJBcnJheSB7XG4gICAgLy8gU2V0cyBvZiB4LHkseig9MCkscyx0IGNvb3JkaW5hdGVzLlxuICAgIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KFtcbiAgICAgIC0xLjAsXG4gICAgICAxLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAxLjAsIC8vIHVwcGVyIGxlZnRcbiAgICAgIC0xLjAsXG4gICAgICAtMS4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wLCAvLyBsb3dlciBsZWZ0XG4gICAgICAxLjAsXG4gICAgICAxLjAsXG4gICAgICAwLjAsXG4gICAgICAxLjAsXG4gICAgICAxLjAsIC8vIHVwcGVyIHJpZ2h0XG4gICAgICAxLjAsXG4gICAgICAtMS4wLFxuICAgICAgMC4wLFxuICAgICAgMS4wLFxuICAgICAgMC4wLCAvLyBsb3dlciByaWdodFxuICAgIF0pO1xuICB9XG4gIHByaXZhdGUgY3JlYXRlVmVydGV4YnVmZmVyKCk6IFdlYkdMQnVmZmVyIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgY29uc3QgYnVmZmVyID0gZ2wuY3JlYXRlQnVmZmVyKCk7XG4gICAgaWYgKCFidWZmZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY3JlYXRlQnVmZmVyKCkgcmV0dXJuZWQgbnVsbCcpO1xuICAgIH1cbiAgICBjb25zdCBnZW9tZXRyeSA9IHRoaXMuY3JlYXRlRGVmYXVsdEdlb21ldHJ5KCk7XG4gICAgZ2wuYmluZEJ1ZmZlcihnbC5BUlJBWV9CVUZGRVIsIGJ1ZmZlcik7XG4gICAgZ2wuYnVmZmVyRGF0YShnbC5BUlJBWV9CVUZGRVIsIGdlb21ldHJ5LCBnbC5TVEFUSUNfRFJBVyk7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgcmV0dXJuIGJ1ZmZlcjtcbiAgfVxuICBwcml2YXRlIGNyZWF0ZUZyYW1lYnVmZmVyKCk6IFdlYkdMRnJhbWVidWZmZXIge1xuICAgIGNvbnN0IGZiID0gdGhpcy5nbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgIGlmICghZmIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY3JlYXRlRnJhbWVidWZmZXIgcmV0dXJuZWQgbnVsbCcpO1xuICAgIH1cbiAgICByZXR1cm4gZmI7XG4gIH1cblxuICBwcml2YXRlIHF1ZXJ5Vml0YWxQYXJhbWV0ZXJzKCk6IHZvaWQge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcblxuICAgIHRoaXMuaXNGbG9hdFRleHR1cmVBdHRhY2hhYmxlVG9GcmFtZUJ1ZmZlciA9IHRoaXMuY2hlY2tGbG9hdFRleHR1cmVBdHRhY2hhYmxlVG9GcmFtZUJ1ZmZlcigpO1xuICAgIHRoaXMuaXNSZW5kZXJGbG9hdDMyU3VwcG9ydGVkID0gdGhpcy5jaGVja1JlbmRlckZsb2F0MzIoKTtcbiAgICB0aGlzLmlzRmxvYXQzMkRvd25sb2FkU3VwcG9ydGVkID0gdGhpcy5jaGVja0Zsb2F0MzJEb3dubG9hZCgpO1xuXG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMSAmJiAhdGhpcy50ZXh0dXJlSGFsZkZsb2F0RXh0ZW5zaW9uICYmICF0aGlzLmlzUmVuZGVyRmxvYXQzMlN1cHBvcnRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdib3RoIGZsb2F0MzIgYW5kIGZsb2F0MTYgVGV4dHVyZVR5cGUgYXJlIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG5cbiAgICB0aGlzLmlzQmxlbmRTdXBwb3J0ZWQgPSAhdGhpcy5pc1JlbmRlckZsb2F0MzJTdXBwb3J0ZWQgfHwgdGhpcy5jaGVja0Zsb2F0MzJCbGVuZCgpO1xuXG4gICAgLy8gdGhpcy5tYXhDb21iaW5lZFRleHR1cmVJbWFnZVVuaXRzID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLk1BWF9DT01CSU5FRF9URVhUVVJFX0lNQUdFX1VOSVRTKTtcbiAgICB0aGlzLm1heFRleHR1cmVTaXplID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLk1BWF9URVhUVVJFX1NJWkUpO1xuICAgIHRoaXMubWF4VGV4dHVyZUltYWdlVW5pdHMgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX1RFWFRVUkVfSU1BR0VfVU5JVFMpO1xuICAgIC8vIHRoaXMubWF4Q3ViZU1hcFRleHR1cmVTaXplID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLk1BWF9DVUJFX01BUF9URVhUVVJFX1NJWkUpO1xuICAgIC8vIHRoaXMuc2hhZGluZ0xhbmd1YWdlVmVyc2lvbiA9IGdsLmdldFBhcmFtZXRlcihnbC5TSEFESU5HX0xBTkdVQUdFX1ZFUlNJT04pO1xuICAgIC8vIHRoaXMud2ViZ2xWZW5kb3IgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuVkVORE9SKTtcbiAgICAvLyB0aGlzLndlYmdsVmVyc2lvbiA9IGdsLmdldFBhcmFtZXRlcihnbC5WRVJTSU9OKTtcblxuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIC8vIHRoaXMubWF4M0RUZXh0dXJlU2l6ZSA9IGdsLmdldFBhcmFtZXRlcihXZWJHTDJSZW5kZXJpbmdDb250ZXh0Lk1BWF8zRF9URVhUVVJFX1NJWkUpO1xuICAgICAgLy8gdGhpcy5tYXhBcnJheVRleHR1cmVMYXllcnMgPSBnbC5nZXRQYXJhbWV0ZXIoV2ViR0wyUmVuZGVyaW5nQ29udGV4dC5NQVhfQVJSQVlfVEVYVFVSRV9MQVlFUlMpO1xuICAgICAgLy8gdGhpcy5tYXhDb2xvckF0dGFjaG1lbnRzID0gZ2wuZ2V0UGFyYW1ldGVyKFdlYkdMMlJlbmRlcmluZ0NvbnRleHQuTUFYX0NPTE9SX0FUVEFDSE1FTlRTKTtcbiAgICAgIC8vIHRoaXMubWF4RHJhd0J1ZmZlcnMgPSBnbC5nZXRQYXJhbWV0ZXIoV2ViR0wyUmVuZGVyaW5nQ29udGV4dC5NQVhfRFJBV19CVUZGRVJTKTtcbiAgICB9XG4gIH1cbiAgcHJpdmF0ZSBnZXRFeHRlbnNpb25zKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIHRoaXMuY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbiA9IHRoaXMuZ2wuZ2V0RXh0ZW5zaW9uKCdFWFRfY29sb3JfYnVmZmVyX2Zsb2F0Jyk7XG4gICAgICB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbiA9IHRoaXMuZ2wuZ2V0RXh0ZW5zaW9uKCdFWFRfZGlzam9pbnRfdGltZXJfcXVlcnlfd2ViZ2wyJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGV4dHVyZUZsb2F0RXh0ZW5zaW9uID0gdGhpcy5nbC5nZXRFeHRlbnNpb24oJ09FU190ZXh0dXJlX2Zsb2F0Jyk7XG4gICAgICB0aGlzLnRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb24gPSB0aGlzLmdsLmdldEV4dGVuc2lvbignT0VTX3RleHR1cmVfaGFsZl9mbG9hdCcpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tGbG9hdFRleHR1cmVBdHRhY2hhYmxlVG9GcmFtZUJ1ZmZlcigpOiBib29sZWFuIHtcbiAgICAvLyB0ZXN0IHdoZXRoZXIgRmxvYXQzMiB0ZXh0dXJlIGlzIHN1cHBvcnRlZDpcbiAgICAvLyBTVEVQLjEgY3JlYXRlIGEgZmxvYXQgdGV4dHVyZVxuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCB0ZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbiAgICBjb25zdCBpbnRlcm5hbEZvcm1hdCA9IHRoaXMudmVyc2lvbiA9PT0gMiA/IChnbCBhcyB1bmtub3duIGFzIHsgUkdCQTMyRjogbnVtYmVyIH0pLlJHQkEzMkYgOiBnbC5SR0JBO1xuICAgIGdsLnRleEltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgaW50ZXJuYWxGb3JtYXQsIDEsIDEsIDAsIGdsLlJHQkEsIGdsLkZMT0FULCBudWxsKTtcbiAgICAvLyBTVEVQLjIgYmluZCBhIGZyYW1lIGJ1ZmZlclxuICAgIGNvbnN0IGZyYW1lQnVmZmVyID0gZ2wuY3JlYXRlRnJhbWVidWZmZXIoKTtcbiAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIGZyYW1lQnVmZmVyKTtcbiAgICAvLyBTVEVQLjMgYXR0YWNoIHRleHR1cmUgdG8gZnJhbWVidWZmZXJcbiAgICBnbC5mcmFtZWJ1ZmZlclRleHR1cmUyRChnbC5GUkFNRUJVRkZFUiwgZ2wuQ09MT1JfQVRUQUNITUVOVDAsIGdsLlRFWFRVUkVfMkQsIHRleHR1cmUsIDApO1xuICAgIC8vIFNURVAuNCB0ZXN0IHdoZXRoZXIgZnJhbWVidWZmZXIgaXMgY29tcGxldGVcbiAgICBjb25zdCBpc0NvbXBsZXRlID0gZ2wuY2hlY2tGcmFtZWJ1ZmZlclN0YXR1cyhnbC5GUkFNRUJVRkZFUikgPT09IGdsLkZSQU1FQlVGRkVSX0NPTVBMRVRFO1xuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIG51bGwpO1xuICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgbnVsbCk7XG4gICAgZ2wuZGVsZXRlVGV4dHVyZSh0ZXh0dXJlKTtcbiAgICBnbC5kZWxldGVGcmFtZWJ1ZmZlcihmcmFtZUJ1ZmZlcik7XG4gICAgcmV0dXJuIGlzQ29tcGxldGU7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrUmVuZGVyRmxvYXQzMigpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICBpZiAoIXRoaXMuY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy50ZXh0dXJlRmxvYXRFeHRlbnNpb24pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5pc0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0Zsb2F0MzJEb3dubG9hZCgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICBpZiAoIXRoaXMuY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy50ZXh0dXJlRmxvYXRFeHRlbnNpb24pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLmdsLmdldEV4dGVuc2lvbignV0VCR0xfY29sb3JfYnVmZmVyX2Zsb2F0JykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5pc0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIHdoZXRoZXIgR0xfQkxFTkQgaXMgc3VwcG9ydGVkXG4gICAqL1xuICBwcml2YXRlIGNoZWNrRmxvYXQzMkJsZW5kKCk6IGJvb2xlYW4ge1xuICAgIC8vIGl0IGxvb2tzIGxpa2UgY3VycmVudGx5ICgyMDE5LTA1LTA4KSB0aGVyZSBpcyBubyBlYXN5IHdheSB0byBkZXRlY3Qgd2hldGhlciBCTEVORCBpcyBzdXBwb3J0ZWRcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L29ubnhqcy9pc3N1ZXMvMTQ1XG5cbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG5cbiAgICBsZXQgdGV4dHVyZTogV2ViR0xUZXh0dXJlIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICBsZXQgZnJhbWVCdWZmZXI6IFdlYkdMRnJhbWVidWZmZXIgfCBudWxsIHwgdW5kZWZpbmVkO1xuICAgIGxldCB2ZXJ0ZXhTaGFkZXI6IFdlYkdMU2hhZGVyIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICBsZXQgZnJhZ21lbnRTaGFkZXI6IFdlYkdMU2hhZGVyIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICBsZXQgcHJvZ3JhbTogV2ViR0xQcm9ncmFtIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuICAgIHRyeSB7XG4gICAgICB0ZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuICAgICAgZnJhbWVCdWZmZXIgPSBnbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbiAgICAgIGNvbnN0IGludGVybmFsRm9ybWF0ID0gdGhpcy52ZXJzaW9uID09PSAyID8gKGdsIGFzIHVua25vd24gYXMgeyBSR0JBMzJGOiBudW1iZXIgfSkuUkdCQTMyRiA6IGdsLlJHQkE7XG4gICAgICBnbC50ZXhJbWFnZTJEKGdsLlRFWFRVUkVfMkQsIDAsIGludGVybmFsRm9ybWF0LCAxLCAxLCAwLCBnbC5SR0JBLCBnbC5GTE9BVCwgbnVsbCk7XG5cbiAgICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgZnJhbWVCdWZmZXIpO1xuICAgICAgZ2wuZnJhbWVidWZmZXJUZXh0dXJlMkQoZ2wuRlJBTUVCVUZGRVIsIGdsLkNPTE9SX0FUVEFDSE1FTlQwLCBnbC5URVhUVVJFXzJELCB0ZXh0dXJlLCAwKTtcblxuICAgICAgZ2wuZW5hYmxlKGdsLkJMRU5EKTtcblxuICAgICAgdmVydGV4U2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKGdsLlZFUlRFWF9TSEFERVIpO1xuICAgICAgaWYgKCF2ZXJ0ZXhTaGFkZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgZ2wuc2hhZGVyU291cmNlKHZlcnRleFNoYWRlciwgJ3ZvaWQgbWFpbigpe30nKTtcbiAgICAgIGdsLmNvbXBpbGVTaGFkZXIodmVydGV4U2hhZGVyKTtcblxuICAgICAgZnJhZ21lbnRTaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIoZ2wuRlJBR01FTlRfU0hBREVSKTtcbiAgICAgIGlmICghZnJhZ21lbnRTaGFkZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgZ2wuc2hhZGVyU291cmNlKGZyYWdtZW50U2hhZGVyLCAncHJlY2lzaW9uIGhpZ2hwIGZsb2F0O3ZvaWQgbWFpbigpe2dsX0ZyYWdDb2xvcj12ZWM0KDAuNSk7fScpO1xuICAgICAgZ2wuY29tcGlsZVNoYWRlcihmcmFnbWVudFNoYWRlcik7XG5cbiAgICAgIHByb2dyYW0gPSBnbC5jcmVhdGVQcm9ncmFtKCk7XG4gICAgICBpZiAoIXByb2dyYW0pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIHZlcnRleFNoYWRlcik7XG4gICAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgZnJhZ21lbnRTaGFkZXIpO1xuICAgICAgZ2wubGlua1Byb2dyYW0ocHJvZ3JhbSk7XG4gICAgICBnbC51c2VQcm9ncmFtKHByb2dyYW0pO1xuXG4gICAgICBnbC5kcmF3QXJyYXlzKGdsLlBPSU5UUywgMCwgMSk7XG4gICAgICByZXR1cm4gZ2wuZ2V0RXJyb3IoKSA9PT0gZ2wuTk9fRVJST1I7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGdsLmRpc2FibGUoZ2wuQkxFTkQpO1xuXG4gICAgICBpZiAocHJvZ3JhbSkge1xuICAgICAgICBnbC5kZWxldGVQcm9ncmFtKHByb2dyYW0pO1xuICAgICAgfVxuICAgICAgaWYgKHZlcnRleFNoYWRlcikge1xuICAgICAgICBnbC5kZWxldGVTaGFkZXIodmVydGV4U2hhZGVyKTtcbiAgICAgIH1cbiAgICAgIGlmIChmcmFnbWVudFNoYWRlcikge1xuICAgICAgICBnbC5kZWxldGVTaGFkZXIoZnJhZ21lbnRTaGFkZXIpO1xuICAgICAgfVxuICAgICAgaWYgKGZyYW1lQnVmZmVyKSB7XG4gICAgICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgbnVsbCk7XG4gICAgICAgIGdsLmRlbGV0ZUZyYW1lYnVmZmVyKGZyYW1lQnVmZmVyKTtcbiAgICAgIH1cbiAgICAgIGlmICh0ZXh0dXJlKSB7XG4gICAgICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIG51bGwpO1xuICAgICAgICBnbC5kZWxldGVUZXh0dXJlKHRleHR1cmUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGJlZ2luVGltZXIoKTogV2ViR0xRdWVyeSB7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMiAmJiB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbikge1xuICAgICAgY29uc3QgZ2wyID0gdGhpcy5nbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0O1xuICAgICAgY29uc3QgZXh0ID0gdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb247XG5cbiAgICAgIGNvbnN0IHF1ZXJ5ID0gZ2wyLmNyZWF0ZVF1ZXJ5KCkgYXMgV2ViR0xRdWVyeTtcbiAgICAgIGdsMi5iZWdpblF1ZXJ5KGV4dC5USU1FX0VMQVBTRURfRVhULCBxdWVyeSk7XG4gICAgICByZXR1cm4gcXVlcnk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRPRE86IGFkZCB3ZWJnbCAxIGhhbmRsaW5nLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJHTDEgcHJvZmlsaW5nIGN1cnJlbnRseSBub3Qgc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfVxuXG4gIGVuZFRpbWVyKCkge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIgJiYgdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb24pIHtcbiAgICAgIGNvbnN0IGdsMiA9IHRoaXMuZ2wgYXMgV2ViR0wyUmVuZGVyaW5nQ29udGV4dDtcbiAgICAgIGNvbnN0IGV4dCA9IHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uO1xuICAgICAgZ2wyLmVuZFF1ZXJ5KGV4dC5USU1FX0VMQVBTRURfRVhUKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVE9ETzogYWRkIHdlYmdsIDEgaGFuZGxpbmcuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMMSBwcm9maWxpbmcgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH1cblxuICBpc1RpbWVyUmVzdWx0QXZhaWxhYmxlKHF1ZXJ5OiBXZWJHTFF1ZXJ5KTogYm9vbGVhbiB7XG4gICAgbGV0IGF2YWlsYWJsZSA9IGZhbHNlLFxuICAgICAgZGlzam9pbnQgPSBmYWxzZTtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyICYmIHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uKSB7XG4gICAgICBjb25zdCBnbDIgPSB0aGlzLmdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQ7XG4gICAgICBjb25zdCBleHQgPSB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbjtcblxuICAgICAgYXZhaWxhYmxlID0gZ2wyLmdldFF1ZXJ5UGFyYW1ldGVyKHF1ZXJ5LCBnbDIuUVVFUllfUkVTVUxUX0FWQUlMQUJMRSk7XG4gICAgICBkaXNqb2ludCA9IGdsMi5nZXRQYXJhbWV0ZXIoZXh0LkdQVV9ESVNKT0lOVF9FWFQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUT0RPOiBhZGQgd2ViZ2wgMSBoYW5kbGluZy5cbiAgICAgIHRocm93IG5ldyBFcnJvcignV2ViR0wxIHByb2ZpbGluZyBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBhdmFpbGFibGUgJiYgIWRpc2pvaW50O1xuICB9XG5cbiAgZ2V0VGltZXJSZXN1bHQocXVlcnk6IFdlYkdMUXVlcnkpOiBudW1iZXIge1xuICAgIGxldCB0aW1lRWxhcHNlZCA9IDA7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMikge1xuICAgICAgY29uc3QgZ2wyID0gdGhpcy5nbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0O1xuICAgICAgdGltZUVsYXBzZWQgPSBnbDIuZ2V0UXVlcnlQYXJhbWV0ZXIocXVlcnksIGdsMi5RVUVSWV9SRVNVTFQpO1xuICAgICAgZ2wyLmRlbGV0ZVF1ZXJ5KHF1ZXJ5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVE9ETzogYWRkIHdlYmdsIDEgaGFuZGxpbmcuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMMSBwcm9maWxpbmcgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gICAgLy8gcmV0dXJuIG1pbGxpc2Vjb25kc1xuICAgIHJldHVybiB0aW1lRWxhcHNlZCAvIDEwMDAwMDA7XG4gIH1cblxuICBhc3luYyB3YWl0Rm9yUXVlcnlBbmRHZXRUaW1lKHF1ZXJ5OiBXZWJHTFF1ZXJ5KTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBhd2FpdCByZXBlYXRlZFRyeSgoKSA9PiB0aGlzLmlzVGltZXJSZXN1bHRBdmFpbGFibGUocXVlcnkpKTtcbiAgICByZXR1cm4gdGhpcy5nZXRUaW1lclJlc3VsdChxdWVyeSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgY3JlYXRlQW5kV2FpdEZvckZlbmNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGZlbmNlQ29udGV4dCA9IHRoaXMuY3JlYXRlRmVuY2UodGhpcy5nbCk7XG4gICAgcmV0dXJuIHRoaXMucG9sbEZlbmNlKGZlbmNlQ29udGV4dCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUZlbmNlKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQpOiBGZW5jZUNvbnRleHQge1xuICAgIGxldCBpc0ZlbmNlUGFzc2VkOiAoKSA9PiBib29sZWFuO1xuICAgIGNvbnN0IGdsMiA9IGdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQ7XG4gICAgY29uc3QgcXVlcnkgPSBnbDIuZmVuY2VTeW5jKGdsMi5TWU5DX0dQVV9DT01NQU5EU19DT01QTEVURSwgMCk7XG4gICAgZ2wuZmx1c2goKTtcbiAgICBpZiAocXVlcnkgPT09IG51bGwpIHtcbiAgICAgIGlzRmVuY2VQYXNzZWQgPSAoKSA9PiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBpc0ZlbmNlUGFzc2VkID0gKCkgPT4ge1xuICAgICAgICBjb25zdCBzdGF0dXMgPSBnbDIuY2xpZW50V2FpdFN5bmMocXVlcnksIDAsIDApO1xuICAgICAgICByZXR1cm4gc3RhdHVzID09PSBnbDIuQUxSRUFEWV9TSUdOQUxFRCB8fCBzdGF0dXMgPT09IGdsMi5DT05ESVRJT05fU0FUSVNGSUVEO1xuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgcXVlcnksIGlzRmVuY2VQYXNzZWQgfTtcbiAgfVxuXG4gIGFzeW5jIHBvbGxGZW5jZShmZW5jZUNvbnRleHQ6IEZlbmNlQ29udGV4dCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgdm9pZCB0aGlzLmFkZEl0ZW1Ub1BvbGwoXG4gICAgICAgICgpID0+IGZlbmNlQ29udGV4dC5pc0ZlbmNlUGFzc2VkKCksXG4gICAgICAgICgpID0+IHJlc29sdmUoKSxcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGl0ZW1zVG9Qb2xsOiBQb2xsSXRlbVtdID0gW107XG5cbiAgcG9sbEl0ZW1zKCk6IHZvaWQge1xuICAgIC8vIEZpbmQgdGhlIGxhc3QgcXVlcnkgdGhhdCBoYXMgZmluaXNoZWQuXG4gICAgY29uc3QgaW5kZXggPSBsaW5lYXJTZWFyY2hMYXN0VHJ1ZSh0aGlzLml0ZW1zVG9Qb2xsLm1hcCgoeCkgPT4geC5pc0RvbmVGbikpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IGluZGV4OyArK2kpIHtcbiAgICAgIGNvbnN0IHsgcmVzb2x2ZUZuIH0gPSB0aGlzLml0ZW1zVG9Qb2xsW2ldO1xuICAgICAgcmVzb2x2ZUZuKCk7XG4gICAgfVxuICAgIHRoaXMuaXRlbXNUb1BvbGwgPSB0aGlzLml0ZW1zVG9Qb2xsLnNsaWNlKGluZGV4ICsgMSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFkZEl0ZW1Ub1BvbGwoaXNEb25lRm46ICgpID0+IGJvb2xlYW4sIHJlc29sdmVGbjogKCkgPT4gdm9pZCkge1xuICAgIHRoaXMuaXRlbXNUb1BvbGwucHVzaCh7IGlzRG9uZUZuLCByZXNvbHZlRm4gfSk7XG4gICAgaWYgKHRoaXMuaXRlbXNUb1BvbGwubGVuZ3RoID4gMSkge1xuICAgICAgLy8gV2UgYWxyZWFkeSBoYXZlIGEgcnVubmluZyBsb29wIHRoYXQgcG9sbHMuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFN0YXJ0IGEgbmV3IGxvb3AgdGhhdCBwb2xscy5cbiAgICBhd2FpdCByZXBlYXRlZFRyeSgoKSA9PiB7XG4gICAgICB0aGlzLnBvbGxJdGVtcygpO1xuICAgICAgLy8gRW5kIHRoZSBsb29wIGlmIG5vIG1vcmUgaXRlbXMgdG8gcG9sbC5cbiAgICAgIHJldHVybiB0aGlzLml0ZW1zVG9Qb2xsLmxlbmd0aCA9PT0gMDtcbiAgICB9KTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcblxuaW1wb3J0IHsgV2ViR0xDb250ZXh0IH0gZnJvbSAnLi93ZWJnbC1jb250ZXh0JztcblxuY29uc3QgY2FjaGU6IHsgW2NvbnRleHRJZDogc3RyaW5nXTogV2ViR0xDb250ZXh0IH0gPSB7fTtcblxuLyoqXG4gKiBUaGlzIGZhY3RvcnkgZnVuY3Rpb24gY3JlYXRlcyBwcm9wZXIgV2ViR0xSZW5kZXJpbmdDb250ZXh0IGJhc2VkIG9uXG4gKiB0aGUgY3VycmVudCBicm93c2VycyBjYXBhYmlsaXRpZXNcbiAqIFRoZSBvcmRlciBpcyBmcm9tIGhpZ2hlci9tb3N0IHJlY2VudCB2ZXJzaW9ucyB0byBtb3N0IGJhc2ljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVXZWJHTENvbnRleHQoY29udGV4dElkPzogJ3dlYmdsJyB8ICd3ZWJnbDInKTogV2ViR0xDb250ZXh0IHtcbiAgbGV0IGNvbnRleHQ6IFdlYkdMQ29udGV4dCB8IHVuZGVmaW5lZDtcbiAgaWYgKCghY29udGV4dElkIHx8IGNvbnRleHRJZCA9PT0gJ3dlYmdsMicpICYmICd3ZWJnbDInIGluIGNhY2hlKSB7XG4gICAgY29udGV4dCA9IGNhY2hlLndlYmdsMjtcbiAgfSBlbHNlIGlmICgoIWNvbnRleHRJZCB8fCBjb250ZXh0SWQgPT09ICd3ZWJnbCcpICYmICd3ZWJnbCcgaW4gY2FjaGUpIHtcbiAgICBjb250ZXh0ID0gY2FjaGUud2ViZ2w7XG4gIH1cblxuICBpZiAoIWNvbnRleHQpIHtcbiAgICB0cnkge1xuICAgICAgLy8gdHJ5IHRvIGNyZWF0ZSB3ZWJnbCBjb250ZXh0IGZyb20gYW4gb2Zmc2NyZWVuIGNhbnZhc1xuICAgICAgY29uc3Qgb2Zmc2NyZWVuQ2FudmFzID0gY3JlYXRlT2Zmc2NyZWVuQ2FudmFzKCk7XG4gICAgICBjb250ZXh0ID0gY3JlYXRlTmV3V2ViR0xDb250ZXh0KG9mZnNjcmVlbkNhbnZhcywgY29udGV4dElkKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIGlmIGZhaWxlZCwgZmFsbGJhY2sgdG8gdHJ5IHRvIHVzZSBhIG5vcm1hbCBjYW52YXMgZWxlbWVudFxuICAgICAgY29uc3QgY2FudmFzID0gY3JlYXRlQ2FudmFzKCk7XG4gICAgICBjb250ZXh0ID0gY3JlYXRlTmV3V2ViR0xDb250ZXh0KGNhbnZhcywgY29udGV4dElkKTtcbiAgICB9XG4gIH1cblxuICBjb250ZXh0SWQgPSBjb250ZXh0SWQgfHwgY29udGV4dC52ZXJzaW9uID09PSAxID8gJ3dlYmdsJyA6ICd3ZWJnbDInO1xuICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG5cbiAgY2FjaGVbY29udGV4dElkXSA9IGNvbnRleHQ7XG5cbiAgaWYgKGdsLmlzQ29udGV4dExvc3QoKSkge1xuICAgIGRlbGV0ZSBjYWNoZVtjb250ZXh0SWRdO1xuICAgIHJldHVybiBjcmVhdGVXZWJHTENvbnRleHQoY29udGV4dElkKTtcbiAgfVxuXG4gIGdsLmRpc2FibGUoZ2wuREVQVEhfVEVTVCk7XG4gIGdsLmRpc2FibGUoZ2wuU1RFTkNJTF9URVNUKTtcbiAgZ2wuZGlzYWJsZShnbC5CTEVORCk7XG4gIGdsLmRpc2FibGUoZ2wuRElUSEVSKTtcbiAgZ2wuZGlzYWJsZShnbC5QT0xZR09OX09GRlNFVF9GSUxMKTtcbiAgZ2wuZGlzYWJsZShnbC5TQU1QTEVfQ09WRVJBR0UpO1xuICBnbC5lbmFibGUoZ2wuU0NJU1NPUl9URVNUKTtcbiAgZ2wuZW5hYmxlKGdsLkNVTExfRkFDRSk7XG4gIGdsLmN1bGxGYWNlKGdsLkJBQ0spO1xuXG4gIHJldHVybiBjb250ZXh0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTmV3V2ViR0xDb250ZXh0KGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQsIGNvbnRleHRJZD86ICd3ZWJnbCcgfCAnd2ViZ2wyJyk6IFdlYkdMQ29udGV4dCB7XG4gIGNvbnN0IGNvbnRleHRBdHRyaWJ1dGVzOiBXZWJHTENvbnRleHRBdHRyaWJ1dGVzID0ge1xuICAgIGFscGhhOiBmYWxzZSxcbiAgICBkZXB0aDogZmFsc2UsXG4gICAgYW50aWFsaWFzOiBmYWxzZSxcbiAgICBzdGVuY2lsOiBmYWxzZSxcbiAgICBwcmVzZXJ2ZURyYXdpbmdCdWZmZXI6IGZhbHNlLFxuICAgIHByZW11bHRpcGxpZWRBbHBoYTogZmFsc2UsXG4gICAgZmFpbElmTWFqb3JQZXJmb3JtYW5jZUNhdmVhdDogZmFsc2UsXG4gIH07XG4gIGxldCBnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0IHwgbnVsbDtcbiAgY29uc3QgY2EgPSBjb250ZXh0QXR0cmlidXRlcztcbiAgaWYgKCFjb250ZXh0SWQgfHwgY29udGV4dElkID09PSAnd2ViZ2wyJykge1xuICAgIGdsID0gY2FudmFzLmdldENvbnRleHQoJ3dlYmdsMicsIGNhKTtcbiAgICBpZiAoZ2wpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBuZXcgV2ViR0xDb250ZXh0KGdsLCAyKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBMb2dnZXIud2FybmluZygnR2xDb250ZXh0RmFjdG9yeScsIGBmYWlsZWQgdG8gY3JlYXRlIFdlYkdMQ29udGV4dCB1c2luZyBjb250ZXh0SWQgJ3dlYmdsMicuIEVycm9yOiAke2Vycn1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKCFjb250ZXh0SWQgfHwgY29udGV4dElkID09PSAnd2ViZ2wnKSB7XG4gICAgZ2wgPSBjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wnLCBjYSkgfHwgKGNhbnZhcy5nZXRDb250ZXh0KCdleHBlcmltZW50YWwtd2ViZ2wnLCBjYSkgYXMgV2ViR0xSZW5kZXJpbmdDb250ZXh0KTtcbiAgICBpZiAoZ2wpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBuZXcgV2ViR0xDb250ZXh0KGdsLCAxKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBMb2dnZXIud2FybmluZyhcbiAgICAgICAgICAnR2xDb250ZXh0RmFjdG9yeScsXG4gICAgICAgICAgYGZhaWxlZCB0byBjcmVhdGUgV2ViR0xDb250ZXh0IHVzaW5nIGNvbnRleHRJZCAnd2ViZ2wnIG9yICdleHBlcmltZW50YWwtd2ViZ2wnLiBFcnJvcjogJHtlcnJ9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZGVjbGFyZSBsZXQgT2Zmc2NyZWVuQ2FudmFzOiB7IG5ldyAod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiBIVE1MQ2FudmFzRWxlbWVudCB9O1xuXG5mdW5jdGlvbiBjcmVhdGVDYW52YXMoKTogSFRNTENhbnZhc0VsZW1lbnQge1xuICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ZhaWxlZCB0byBjcmVhdGUgY2FudmFzOiBkb2N1bWVudCBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gIH1cbiAgY29uc3QgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICBjYW52YXMud2lkdGggPSAxO1xuICBjYW52YXMuaGVpZ2h0ID0gMTtcbiAgcmV0dXJuIGNhbnZhcztcbn1cblxuZnVuY3Rpb24gY3JlYXRlT2Zmc2NyZWVuQ2FudmFzKCk6IEhUTUxDYW52YXNFbGVtZW50IHtcbiAgaWYgKHR5cGVvZiBPZmZzY3JlZW5DYW52YXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZmFpbGVkIHRvIGNyZWF0ZSBvZmZzY3JlZW4gY2FudmFzOiBPZmZzY3JlZW5DYW52YXMgaXMgbm90IHN1cHBvcnRlZCcpO1xuICB9XG4gIHJldHVybiBuZXcgT2Zmc2NyZWVuQ2FudmFzKDEsIDEpO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBlbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBCYWNrZW5kLCBTZXNzaW9uSGFuZGxlciB9IGZyb20gJy4uL2JhY2tlbmQnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vc2Vzc2lvbic7XG5cbmltcG9ydCB7IFdlYkdMU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuL3dlYmdsL3Nlc3Npb24taGFuZGxlcic7XG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL3dlYmdsL3dlYmdsLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlV2ViR0xDb250ZXh0IH0gZnJvbSAnLi93ZWJnbC93ZWJnbC1jb250ZXh0LWZhY3RvcnknO1xuXG4vKipcbiAqIFdlYkdMQmFja2VuZCBpcyB0aGUgZW50cnkgcG9pbnQgZm9yIGFsbCBXZWJHTCBvcGVyYXRpb25zXG4gKiBXaGVuIGl0IHN0YXJ0cyBpdCBjcmVhdGVkIHRoZSBXZWJHTFJlbmRlcmluZ0NvbnRleHRcbiAqIGFuZCBvdGhlciBtYWluIGZyYW1ld29yayBjb21wb25lbnRzIHN1Y2ggYXMgUHJvZ3JhbSBhbmQgVGV4dHVyZSBNYW5hZ2Vyc1xuICovXG5leHBvcnQgY2xhc3MgV2ViR0xCYWNrZW5kIGltcGxlbWVudHMgQmFja2VuZCB7XG4gIGdsQ29udGV4dDogV2ViR0xDb250ZXh0O1xuXG4gIGdldCBjb250ZXh0SWQoKTogJ3dlYmdsJyB8ICd3ZWJnbDInIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLmNvbnRleHRJZDtcbiAgfVxuICBzZXQgY29udGV4dElkKHZhbHVlOiAnd2ViZ2wnIHwgJ3dlYmdsMicgfCB1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wuY29udGV4dElkID0gdmFsdWU7XG4gIH1cblxuICBnZXQgbWF0bXVsTWF4QmF0Y2hTaXplKCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGVudi53ZWJnbC5tYXRtdWxNYXhCYXRjaFNpemU7XG4gIH1cbiAgc2V0IG1hdG11bE1heEJhdGNoU2l6ZSh2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgZW52LndlYmdsLm1hdG11bE1heEJhdGNoU2l6ZSA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IHRleHR1cmVDYWNoZU1vZGUoKTogJ2luaXRpYWxpemVyT25seScgfCAnZnVsbCcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBlbnYud2ViZ2wudGV4dHVyZUNhY2hlTW9kZTtcbiAgfVxuICBzZXQgdGV4dHVyZUNhY2hlTW9kZSh2YWx1ZTogJ2luaXRpYWxpemVyT25seScgfCAnZnVsbCcgfCB1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wudGV4dHVyZUNhY2hlTW9kZSA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IHBhY2soKTogYm9vbGVhbiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGVudi53ZWJnbC5wYWNrO1xuICB9XG4gIHNldCBwYWNrKHZhbHVlOiBib29sZWFuIHwgdW5kZWZpbmVkKSB7XG4gICAgZW52LndlYmdsLnBhY2sgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBhc3luYygpOiBib29sZWFuIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLmFzeW5jO1xuICB9XG4gIHNldCBhc3luYyh2YWx1ZTogYm9vbGVhbiB8IHVuZGVmaW5lZCkge1xuICAgIGVudi53ZWJnbC5hc3luYyA9IHZhbHVlO1xuICB9XG5cbiAgaW5pdGlhbGl6ZSgpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5nbENvbnRleHQgPSBjcmVhdGVXZWJHTENvbnRleHQodGhpcy5jb250ZXh0SWQpO1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLm1hdG11bE1heEJhdGNoU2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgdGhpcy5tYXRtdWxNYXhCYXRjaFNpemUgPSAxNjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdGhpcy50ZXh0dXJlQ2FjaGVNb2RlICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLnRleHR1cmVDYWNoZU1vZGUgPSAnZnVsbCc7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHRoaXMucGFjayAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRoaXMucGFjayA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB0aGlzLmFzeW5jICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdGhpcy5hc3luYyA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBMb2dnZXIuc2V0V2l0aEVudihlbnYpO1xuXG4gICAgICBpZiAoIWVudi53ZWJnbC5jb250ZXh0KSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbnYud2ViZ2wsICdjb250ZXh0JywgeyB2YWx1ZTogdGhpcy5nbENvbnRleHQuZ2wgfSk7XG4gICAgICB9XG5cbiAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAnV2ViR0xCYWNrZW5kJyxcbiAgICAgICAgYENyZWF0ZWQgV2ViR0xDb250ZXh0OiAke3R5cGVvZiB0aGlzLmdsQ29udGV4dH0gd2l0aCBtYXRtdWxNYXhCYXRjaFNpemU6ICR7XG4gICAgICAgICAgdGhpcy5tYXRtdWxNYXhCYXRjaFNpemVcbiAgICAgICAgfTsgdGV4dHVyZUNhY2hlTW9kZTogJHt0aGlzLnRleHR1cmVDYWNoZU1vZGV9OyBwYWNrOiAke3RoaXMucGFja307IGFzeW5jOiAke3RoaXMuYXN5bmN9LmAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgTG9nZ2VyLndhcm5pbmcoJ1dlYkdMQmFja2VuZCcsIGBVbmFibGUgdG8gaW5pdGlhbGl6ZSBXZWJHTEJhY2tlbmQuICR7ZX1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgY3JlYXRlU2Vzc2lvbkhhbmRsZXIoY29udGV4dDogU2Vzc2lvbi5Db250ZXh0KTogU2Vzc2lvbkhhbmRsZXIge1xuICAgIHJldHVybiBuZXcgV2ViR0xTZXNzaW9uSGFuZGxlcih0aGlzLCBjb250ZXh0KTtcbiAgfVxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuZ2xDb250ZXh0LmRpc3Bvc2UoKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBXZWJHTEJhY2tlbmQgfSBmcm9tICcuL2JhY2tlbmRzL2JhY2tlbmQtd2ViZ2wnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9yIH0gZnJvbSAnLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgT3BTZXQgfSBmcm9tICcuL29wc2V0JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL3Nlc3Npb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEluZmVyZW5jZUhhbmRsZXIge1xuICAvKipcbiAgICogZGlzcG9zZSB0aGUgaW5mZXJlbmNlIGhhbmRsZXIuIGl0IHdpbGwgYmUgY2FsbGVkIGFzIHRoZSBsYXN0IHN0ZXAgaW4gU2Vzc2lvbi5ydW4oKVxuICAgKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNlc3Npb25IYW5kbGVyIHtcbiAgLyoqXG4gICAqIHRyYW5zZm9ybSB0aGUgZ3JhcGggYXQgaW5pdGlhbGl6YXRpb24gdGltZVxuICAgKiBAcGFyYW0gZ3JhcGhUcmFuc2Zvcm1lciB0aGUgZ3JhcGggdHJhbnNmb3JtZXIgdG8gbWFuaXB1bGF0ZSB0aGUgbW9kZWwgZ3JhcGhcbiAgICovXG4gIHRyYW5zZm9ybUdyYXBoPyhncmFwaFRyYW5zZm9ybWVyOiBHcmFwaC5UcmFuc2Zvcm1lcik6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiBJbmZlcmVuY2VIYW5kbGVyIHRvIHVzZSBpbiBhIFNlc3Npb24ucnVuKCkgY2FsbFxuICAgKi9cbiAgY3JlYXRlSW5mZXJlbmNlSGFuZGxlcigpOiBJbmZlcmVuY2VIYW5kbGVyO1xuXG4gIC8qKlxuICAgKiBkaXNwb3NlIHRoZSBzZXNzaW9uIGhhbmRsZXIuIGl0IHdpbGwgYmUgY2FsbGVkIHdoZW4gYSBzZXNzaW9uIGlzIGJlaW5nIGRpc3Bvc2VkIGV4cGxpY2l0bHlcbiAgICovXG4gIGRpc3Bvc2UoKTogdm9pZDtcblxuICAvKipcbiAgICogUmVzb2x2ZXMgdGhlIG9wZXJhdG9yIGZyb20gdGhlIG5hbWUgYW5kIG9wc2V0IHZlcnNpb247IGJhY2tlbmQgc3BlY2lmaWNcbiAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgdG8gcmVzb2x2ZVxuICAgKiBAcGFyYW0gb3BzZXRzIGEgbGlzdCBvZiBvcHNldHMgdGhhdCBleHBvcnRlZCBmcm9tIHRoZSBtb2RlbFxuICAgKiBAcGFyYW0gZ3JhcGggdGhlIGNvbXBsZXRlbHkgaW5pdGlhbGl6ZWQgZ3JhcGhcbiAgICovXG4gIHJlc29sdmUobm9kZTogR3JhcGguTm9kZSwgb3BzZXRzOiByZWFkb25seSBPcFNldFtdLCBncmFwaDogR3JhcGgpOiBPcGVyYXRvcjtcblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgbGV0J3MgdGhlIHNlc3Npb25IYW5kbGVyIGtub3cgdGhhdCB0aGUgZ3JhcGggaW5pdGlhbGl6YXRpb24gaXMgY29tcGxldGVcbiAgICogQHBhcmFtIGdyYXBoIHRoZSBjb21wbGV0ZWx5IGluaXRpYWxpemVkIGdyYXBoXG4gICAqL1xuICBvbkdyYXBoSW5pdGlhbGl6ZWQ/KGdyYXBoOiBHcmFwaCk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIGEgcmVmZXJlbmNlIHRvIHRoZSBjb3JyZXNwb25kaW5nIGJhY2tlbmRcbiAgICovXG4gIHJlYWRvbmx5IGJhY2tlbmQ6IEJhY2tlbmQ7XG5cbiAgLyoqXG4gICAqIGEgcmVmZXJlbmNlIHRvIHRoZSBzZXNzaW9uIGNvbnRleHRcbiAgICovXG4gIHJlYWRvbmx5IGNvbnRleHQ6IFNlc3Npb24uQ29udGV4dDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCYWNrZW5kIHtcbiAgLyoqXG4gICAqIGluaXRpYWxpemUgdGhlIGJhY2tlbmQuIHdpbGwgYmUgY2FsbGVkIG9ubHkgb25jZSwgd2hlbiB0aGUgZmlyc3QgdGltZSB0aGVcbiAgICogYmFja2VuZCBpdCB0byBiZSB1c2VkXG4gICAqL1xuICBpbml0aWFsaXplKCk6IGJvb2xlYW4gfCBQcm9taXNlPGJvb2xlYW4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgU2Vzc2lvbkhhbmRsZXIgdG8gdXNlIGluIGEgU2Vzc2lvbiBvYmplY3QncyBsaWZlY3ljbGVcbiAgICovXG4gIGNyZWF0ZVNlc3Npb25IYW5kbGVyKGNvbnRleHQ6IFNlc3Npb24uQ29udGV4dCk6IFNlc3Npb25IYW5kbGVyO1xuXG4gIC8qKlxuICAgKiBkaXNwb3NlIHRoZSBiYWNrZW5kLiBjdXJyZW50bHkgdGhpcyB3aWxsIG5vdCBiZSBjYWxsZWRcbiAgICovXG4gIGRpc3Bvc2UoKTogdm9pZDtcbn1cblxuLy8gY2FjaGVzIGFsbCBpbml0aWFsaXplZCBiYWNrZW5kIGluc3RhbmNlc1xuY29uc3QgYmFja2VuZHNDYWNoZTogTWFwPHN0cmluZywgQmFja2VuZD4gPSBuZXcgTWFwKCk7XG5cbmV4cG9ydCBjb25zdCBiYWNrZW5kOiB7IFtuYW1lOiBzdHJpbmddOiBCYWNrZW5kIH0gPSB7XG4gIHdlYmdsOiBuZXcgV2ViR0xCYWNrZW5kKCksXG59O1xuXG4vKipcbiAqIFJlc29sdmUgYSByZWZlcmVuY2UgdG8gdGhlIGJhY2tlbmQuIElmIGEgaGludCBpcyBzcGVjaWZpZWQsIHRoZSBjb3JyZXNwb25kaW5nXG4gKiBiYWNrZW5kIHdpbGwgYmUgdXNlZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlc29sdmVCYWNrZW5kKGhpbnQ/OiBzdHJpbmcgfCByZWFkb25seSBzdHJpbmdbXSk6IFByb21pc2U8QmFja2VuZD4ge1xuICBpZiAoIWhpbnQpIHtcbiAgICByZXR1cm4gcmVzb2x2ZUJhY2tlbmQoWyd3ZWJnbCddKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBoaW50cyA9IHR5cGVvZiBoaW50ID09PSAnc3RyaW5nJyA/IFtoaW50XSA6IGhpbnQ7XG5cbiAgICBmb3IgKGNvbnN0IGJhY2tlbmRIaW50IG9mIGhpbnRzKSB7XG4gICAgICBjb25zdCBjYWNoZSA9IGJhY2tlbmRzQ2FjaGUuZ2V0KGJhY2tlbmRIaW50KTtcbiAgICAgIGlmIChjYWNoZSkge1xuICAgICAgICByZXR1cm4gY2FjaGU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGJhY2tlbmQgPSBhd2FpdCB0cnlMb2FkQmFja2VuZChiYWNrZW5kSGludCk7XG4gICAgICBpZiAoYmFja2VuZCkge1xuICAgICAgICByZXR1cm4gYmFja2VuZDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ25vIGF2YWlsYWJsZSBiYWNrZW5kIHRvIHVzZScpO1xufVxuXG5hc3luYyBmdW5jdGlvbiB0cnlMb2FkQmFja2VuZChiYWNrZW5kSGludDogc3RyaW5nKTogUHJvbWlzZTxCYWNrZW5kIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IGJhY2tlbmRPYmogPSBiYWNrZW5kO1xuXG4gIGlmICh0eXBlb2YgYmFja2VuZE9ialtiYWNrZW5kSGludF0gIT09ICd1bmRlZmluZWQnICYmIGlzQmFja2VuZChiYWNrZW5kT2JqW2JhY2tlbmRIaW50XSkpIHtcbiAgICBjb25zdCBiYWNrZW5kID0gYmFja2VuZE9ialtiYWNrZW5kSGludF07XG4gICAgbGV0IGluaXQgPSBiYWNrZW5kLmluaXRpYWxpemUoKTtcbiAgICBpZiAodHlwZW9mIGluaXQgPT09ICdvYmplY3QnICYmICd0aGVuJyBpbiBpbml0KSB7XG4gICAgICBpbml0ID0gYXdhaXQgaW5pdDtcbiAgICB9XG4gICAgaWYgKGluaXQpIHtcbiAgICAgIGJhY2tlbmRzQ2FjaGUuc2V0KGJhY2tlbmRIaW50LCBiYWNrZW5kKTtcbiAgICAgIHJldHVybiBiYWNrZW5kO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGlzQmFja2VuZChvYmo6IHVua25vd24pIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgY29uc3QgbyA9IG9iaiBhcyBhbnk7XG5cbiAgLy8gY2hlY2sgaWYgYW4gb2JqZWN0IGlzIGEgQmFja2VuZCBpbnN0YW5jZVxuICBpZiAoXG4gICAgJ2luaXRpYWxpemUnIGluIG8gJiZcbiAgICB0eXBlb2Ygby5pbml0aWFsaXplID09PSAnZnVuY3Rpb24nICYmIC8vIGluaXRpYWxpemUoKVxuICAgICdjcmVhdGVTZXNzaW9uSGFuZGxlcicgaW4gbyAmJlxuICAgIHR5cGVvZiBvLmNyZWF0ZVNlc3Npb25IYW5kbGVyID09PSAnZnVuY3Rpb24nICYmIC8vIGNyZWF0ZVNlc3Npb25IYW5kbGVyKClcbiAgICAnZGlzcG9zZScgaW4gbyAmJlxuICAgIHR5cGVvZiBvLmRpc3Bvc2UgPT09ICdmdW5jdGlvbicgLy8gZGlzcG9zZSgpXG4gICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgdHlwZSBCYWNrZW5kVHlwZSA9IEJhY2tlbmQ7XG5leHBvcnQgdHlwZSBTZXNzaW9uSGFuZGxlclR5cGUgPSBSZXR1cm5UeXBlPEJhY2tlbmRUeXBlWydjcmVhdGVTZXNzaW9uSGFuZGxlciddPjtcbmV4cG9ydCB0eXBlIEluZmVyZW5jZUhhbmRsZXJUeXBlID0gUmV0dXJuVHlwZTxTZXNzaW9uSGFuZGxlclR5cGVbJ2NyZWF0ZUluZmVyZW5jZUhhbmRsZXInXT47XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFNlc3Npb25IYW5kbGVyIH0gZnJvbSAnLi9iYWNrZW5kJztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi9ncmFwaCc7XG5pbXBvcnQgeyBMb2dnZXIsIFByb2ZpbGVyIH0gZnJvbSAnLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IE9wZXJhdG9yIH0gZnJvbSAnLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuXG5jbGFzcyBLZXJuZWxPcCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBvcDogT3BlcmF0b3IsXG4gICAgcHVibGljIG5vZGU6IEdyYXBoLk5vZGUsXG4gICkge31cbn1cblxuZXhwb3J0IGNsYXNzIEV4ZWN1dGlvblBsYW4ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGdyYXBoOiBHcmFwaCxcbiAgICBvcHM6IE9wZXJhdG9yW10sXG4gICAgcHJpdmF0ZSBwcm9maWxlcjogUmVhZG9ubHk8UHJvZmlsZXI+LFxuICApIHtcbiAgICB0aGlzLmluaXRpYWxpemUob3BzKTtcbiAgfVxuXG4gIGluaXRpYWxpemUob3BzOiBPcGVyYXRvcltdKSB7XG4gICAgdGhpcy5wcm9maWxlci5ldmVudCgnc2Vzc2lvbicsICdFeGVjdXRpb25QbGFuLmluaXRpYWxpemUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBncmFwaE5vZGVzID0gdGhpcy5ncmFwaC5nZXROb2RlcygpO1xuICAgICAgaWYgKGdyYXBoTm9kZXMubGVuZ3RoICE9PSBvcHMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIHNpemUgb2Ygbm9kZXMgYW5kIE9QcyBkbyBub3QgbWF0Y2guJyk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX29wcyA9IG9wcy5tYXAoKG9wLCBpKSA9PiBuZXcgS2VybmVsT3Aob3AsIGdyYXBoTm9kZXNbaV0pKTtcbiAgICAgIHRoaXMucmVzZXQoKTtcblxuICAgICAgLy8gbG9vayBmb3Igc3RhcnRlciBub2RlKHMpXG4gICAgICB0aGlzLl9zdGFydGVyID0gW107XG4gICAgICB0aGlzLl9vcHMuZm9yRWFjaCgob3AsIGkpID0+IHtcbiAgICAgICAgbGV0IHJlc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgZm9yIChjb25zdCBpbnB1dCBvZiBvcC5ub2RlLmlucHV0cykge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICF0aGlzLl92YWx1ZXNbaW5wdXRdICYmIC8vIG5vdCBhbiBpbml0aWFsaXplZCBpbnB1dFxuICAgICAgICAgICAgdGhpcy5ncmFwaC5nZXRJbnB1dEluZGljZXMoKS5pbmRleE9mKGlucHV0KSA9PT0gLTEgLy8gbm90IG1vZGVsIGlucHV0XG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXNvbHZlZCA9IGZhbHNlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChyZXNvbHZlZCkge1xuICAgICAgICAgIHRoaXMuX3N0YXJ0ZXIucHVzaChpKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICByZXNldCgpIHtcbiAgICB0aGlzLl92YWx1ZXMgPSB0aGlzLmdyYXBoLmdldFZhbHVlcygpLm1hcCgoaSkgPT4gaS50ZW5zb3IpO1xuICB9XG5cbiAgYXN5bmMgZXhlY3V0ZShzZXNzaW9uSGFuZGxlcjogU2Vzc2lvbkhhbmRsZXIsIG1vZGVsSW5wdXRzOiBUZW5zb3JbXSk6IFByb21pc2U8VGVuc29yW10+IHtcbiAgICByZXR1cm4gdGhpcy5wcm9maWxlci5ldmVudCgnc2Vzc2lvbicsICdFeGVjdXRpb25QbGFuLmV4ZWN1dGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyByZXNldCBtZWRpZW0gcmVzdWx0XG4gICAgICB0aGlzLnJlc2V0KCk7XG5cbiAgICAgIC8vIGNyZWF0ZSBpbmZlcmVuY2UgaGFuZGxlclxuICAgICAgY29uc3QgaW5mZXJlbmNlSGFuZGxlciA9IHNlc3Npb25IYW5kbGVyLmNyZWF0ZUluZmVyZW5jZUhhbmRsZXIoKTtcblxuICAgICAgLy8gcG9wdWxhdGUgaW5wdXRzIHZhbHVlXG4gICAgICBjb25zdCBncmFwaElucHV0cyA9IHRoaXMuZ3JhcGguZ2V0SW5wdXRJbmRpY2VzKCk7XG4gICAgICBpZiAobW9kZWxJbnB1dHMubGVuZ3RoICE9PSBncmFwaElucHV0cy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBudW1iZXIgb2YgaW5wdXQgdGVuc29ycyBkb24ndCBtYXRjaCB0aGUgbnVtYmVyIG9mIGlucHV0cyB0byB0aGUgbW9kZWw6IGFjdHVhbDogJHtcbiAgICAgICAgICAgIG1vZGVsSW5wdXRzLmxlbmd0aFxuICAgICAgICAgIH0gZXhwZWN0ZWQ6ICR7Z3JhcGhJbnB1dHMubGVuZ3RofWAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIG1vZGVsSW5wdXRzLmZvckVhY2goKGlucHV0LCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gZ3JhcGhJbnB1dHNbaV07XG4gICAgICAgIHRoaXMuX3ZhbHVlc1tpbmRleF0gPSBpbnB1dDtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBwcmVwYXJlIHJ1bm5pbmcgc2VxdWVuY2VcbiAgICAgIGNvbnN0IHNlcXVlbmNlOiBudW1iZXJbXSA9IHRoaXMuX3N0YXJ0ZXIuc2xpY2UoMCk7XG5cbiAgICAgIC8vIGV4ZWN1dGlvbiBpdGVyYXRpb25zXG4gICAgICBjb25zdCBncmFwaFZhbHVlcyA9IHRoaXMuZ3JhcGguZ2V0VmFsdWVzKCk7XG4gICAgICBjb25zdCBncmFwaE5vZGVzID0gdGhpcy5ncmFwaC5nZXROb2RlcygpO1xuXG4gICAgICBsZXQgcmVhciA9IDA7XG4gICAgICB3aGlsZSAocmVhciA8IHNlcXVlbmNlLmxlbmd0aCkge1xuICAgICAgICBjb25zdCB0aGlzT3BJbmRleCA9IHNlcXVlbmNlW3JlYXIrK107XG4gICAgICAgIGNvbnN0IHRoaXNPcCA9IHRoaXMuX29wc1t0aGlzT3BJbmRleF07XG5cbiAgICAgICAgLy8gY2hlY2sgaW5wdXRcbiAgICAgICAgY29uc3QgaW5wdXRMaXN0ID0gdGhpc09wLm5vZGUuaW5wdXRzLm1hcCgoaSkgPT4gdGhpcy5fdmFsdWVzW2ldKTtcbiAgICAgICAgaWYgKGlucHV0TGlzdC5pbmRleE9mKHVuZGVmaW5lZCkgIT09IC0xKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnJlc29sdmVkIGlucHV0IGRldGVjdGVkOiBvcDogJHt0aGlzT3Aubm9kZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJ1blxuICAgICAgICBjb25zdCBpbnB1dFRlbnNvcnMgPSBpbnB1dExpc3QgYXMgVGVuc29yW107XG4gICAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICdFeGVjUGxhbicsXG4gICAgICAgICAgYFJ1bm5pbmcgb3A6JHt0aGlzT3Aubm9kZS5uYW1lfSAoJHtpbnB1dFRlbnNvcnNcbiAgICAgICAgICAgIC5tYXAoKHQsIGkpID0+IGAnJHt0aGlzT3Aubm9kZS5pbnB1dHNbaV19JzogJHt0LnR5cGV9WyR7dC5kaW1zLmpvaW4oJywnKX1dYClcbiAgICAgICAgICAgIC5qb2luKCcsICcpfSlgLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IG91dHB1dExpc3QgPSBhd2FpdCB0aGlzLnByb2ZpbGVyLmV2ZW50KCdub2RlJywgdGhpc09wLm5vZGUubmFtZSwgYXN5bmMgKCkgPT5cbiAgICAgICAgICB0aGlzT3Aub3AuaW1wbChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dFRlbnNvcnMsIHRoaXNPcC5vcC5jb250ZXh0KSxcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBjaGVjayBvdXRwdXRcbiAgICAgICAgaWYgKG91dHB1dExpc3QubGVuZ3RoICE9PSB0aGlzT3Aubm9kZS5vdXRwdXRzLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndGhlIHNpemUgb2Ygb3V0cHV0IGRvZXMgbm90IG1hdGNoIG1vZGVsIGRlZmluaXRpb24uJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaWxsIHZhbHVlXG4gICAgICAgIG91dHB1dExpc3QuZm9yRWFjaCgob3V0cHV0LCBpKSA9PiB7XG4gICAgICAgICAgY29uc3QgaiA9IHRoaXNPcC5ub2RlLm91dHB1dHNbaV07XG4gICAgICAgICAgaWYgKHRoaXMuX3ZhbHVlc1tqXSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBvdXRwdXQgWyR7an1dIGFscmVhZHkgaGFzIHZhbHVlOiBvcDoke3RoaXNPcC5ub2RlLm5hbWV9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuX3ZhbHVlc1tqXSA9IG91dHB1dDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gcmVzb2x2ZSBkb3duc3RyZWFtIG5vZGVzXG4gICAgICAgIGNvbnN0IGRvd25zdHJlYW1Ob2RlcyA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICAgICAgICBvdXRwdXRMaXN0LmZvckVhY2goKF9vdXRwdXQsIGkpID0+IHtcbiAgICAgICAgICBjb25zdCBqID0gdGhpc09wLm5vZGUub3V0cHV0c1tpXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGN1cnJlbnREb3duc3RyZWFtTm9kZUluZGV4IG9mIGdyYXBoVmFsdWVzW2pdLnRvKSB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RG93bnN0cmVhbU5vZGUgPSBncmFwaE5vZGVzW2N1cnJlbnREb3duc3RyZWFtTm9kZUluZGV4XTtcbiAgICAgICAgICAgIGxldCByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGsgb2YgY3VycmVudERvd25zdHJlYW1Ob2RlLmlucHV0cykge1xuICAgICAgICAgICAgICBpZiAoIXRoaXMuX3ZhbHVlc1trXSkge1xuICAgICAgICAgICAgICAgIHJlc29sdmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXNvbHZlZCkge1xuICAgICAgICAgICAgICBkb3duc3RyZWFtTm9kZXMuYWRkKGN1cnJlbnREb3duc3RyZWFtTm9kZUluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBzZXF1ZW5jZS5wdXNoKC4uLmRvd25zdHJlYW1Ob2Rlcyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG91dHB1dDogVGVuc29yW10gPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ncmFwaC5nZXRPdXRwdXRJbmRpY2VzKCkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0SW5kZXggPSB0aGlzLmdyYXBoLmdldE91dHB1dEluZGljZXMoKVtpXTtcbiAgICAgICAgY29uc3Qgb3V0cHV0VGVuc29yID0gdGhpcy5fdmFsdWVzW291dHB1dEluZGV4XTtcbiAgICAgICAgaWYgKG91dHB1dFRlbnNvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGByZXF1aXJlZCBvdXRwdXQgWyR7b3V0cHV0SW5kZXh9XSBkb2VzIG5vdCBoYXZlIHZhbHVlYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG91dHB1dEluZGV4ID09PSAwKSB7XG4gICAgICAgICAgYXdhaXQgb3V0cHV0VGVuc29yLmdldERhdGEoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2b2lkIG91dHB1dFRlbnNvci5kYXRhO1xuICAgICAgICB9XG4gICAgICAgIG91dHB1dC5wdXNoKG91dHB1dFRlbnNvcik7XG4gICAgICB9XG4gICAgICBMb2dnZXIudmVyYm9zZSgnRXhlY1BsYW4nLCAnZGlzcG9zaW5nIG9mIGluZmVyZW5jZUhhbmRsZXInKTtcbiAgICAgIGluZmVyZW5jZUhhbmRsZXIuZGlzcG9zZSgpO1xuICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9KTtcbiAgfVxuXG4gIF92YWx1ZXM6IEFycmF5PFRlbnNvciB8IHVuZGVmaW5lZD47XG4gIF9vcHM6IEtlcm5lbE9wW107XG4gIF9zdGFydGVyOiBudW1iZXJbXTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IExvbmcgZnJvbSAnbG9uZyc7XG5cbmltcG9ydCAqIGFzIG9ydEZicyBmcm9tICcuL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQgeyBvbm54IH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuaW1wb3J0IHsgZGVjb2RlVXRmOFN0cmluZywgTG9uZ1V0aWwgfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgQXR0cmlidXRlIHtcbiAgZXhwb3J0IGludGVyZmFjZSBEYXRhVHlwZU1hcCB7XG4gICAgZmxvYXQ6IG51bWJlcjtcbiAgICBpbnQ6IG51bWJlcjtcbiAgICBzdHJpbmc6IHN0cmluZztcbiAgICB0ZW5zb3I6IFRlbnNvcjtcbiAgICBmbG9hdHM6IG51bWJlcltdO1xuICAgIGludHM6IG51bWJlcltdO1xuICAgIHN0cmluZ3M6IHN0cmluZ1tdO1xuICAgIHRlbnNvcnM6IFRlbnNvcltdO1xuICB9XG5cbiAgZXhwb3J0IHR5cGUgRGF0YVR5cGUgPSBrZXlvZiBEYXRhVHlwZU1hcDtcbn1cblxudHlwZSBWYWx1ZVR5cGVzID0gQXR0cmlidXRlLkRhdGFUeXBlTWFwW0F0dHJpYnV0ZS5EYXRhVHlwZV07XG5cbnR5cGUgVmFsdWUgPSBbVmFsdWVUeXBlcywgQXR0cmlidXRlLkRhdGFUeXBlXTtcblxuZXhwb3J0IGNsYXNzIEF0dHJpYnV0ZSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJpYnV0ZXM6IG9ubnguSUF0dHJpYnV0ZVByb3RvW10gfCBvcnRGYnMuQXR0cmlidXRlW10gfCBudWxsIHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5fYXR0cmlidXRlcyA9IG5ldyBNYXAoKTtcbiAgICBpZiAoYXR0cmlidXRlcyAhPT0gbnVsbCAmJiBhdHRyaWJ1dGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGZvciAoY29uc3QgYXR0ciBvZiBhdHRyaWJ1dGVzKSB7XG4gICAgICAgIGlmIChhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90bykge1xuICAgICAgICAgIHRoaXMuX2F0dHJpYnV0ZXMuc2V0KGF0dHIubmFtZSwgW0F0dHJpYnV0ZS5nZXRWYWx1ZShhdHRyKSwgQXR0cmlidXRlLmdldFR5cGUoYXR0cildKTtcbiAgICAgICAgfSBlbHNlIGlmIChhdHRyIGluc3RhbmNlb2Ygb3J0RmJzLkF0dHJpYnV0ZSkge1xuICAgICAgICAgIHRoaXMuX2F0dHJpYnV0ZXMuc2V0KGF0dHIubmFtZSgpISwgW0F0dHJpYnV0ZS5nZXRWYWx1ZShhdHRyKSwgQXR0cmlidXRlLmdldFR5cGUoYXR0cildKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHRoaXMuX2F0dHJpYnV0ZXMuc2l6ZSA8IGF0dHJpYnV0ZXMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZHVwbGljYXRlZCBhdHRyaWJ1dGUgbmFtZXMnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzZXQoa2V5OiBzdHJpbmcsIHR5cGU6IEF0dHJpYnV0ZS5EYXRhVHlwZSwgdmFsdWU6IFZhbHVlVHlwZXMpOiB2b2lkIHtcbiAgICB0aGlzLl9hdHRyaWJ1dGVzLnNldChrZXksIFt2YWx1ZSwgdHlwZV0pO1xuICB9XG4gIGRlbGV0ZShrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuX2F0dHJpYnV0ZXMuZGVsZXRlKGtleSk7XG4gIH1cbiAgZ2V0RmxvYXQoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnZmxvYXQnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdmbG9hdCcsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRJbnQoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnaW50J10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnaW50JywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldFN0cmluZyhrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydzdHJpbmcnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdzdHJpbmcnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0VGVuc29yKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ3RlbnNvciddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ3RlbnNvcicsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRGbG9hdHMoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnZmxvYXRzJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnZmxvYXRzJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldEludHMoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnaW50cyddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ2ludHMnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0U3RyaW5ncyhrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydzdHJpbmdzJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnc3RyaW5ncycsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRUZW5zb3JzKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ3RlbnNvcnMnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICd0ZW5zb3JzJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0PFYgZXh0ZW5kcyBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbQXR0cmlidXRlLkRhdGFUeXBlXT4oXG4gICAga2V5OiBzdHJpbmcsXG4gICAgdHlwZTogQXR0cmlidXRlLkRhdGFUeXBlLFxuICAgIGRlZmF1bHRWYWx1ZT86IFYsXG4gICk6IFYge1xuICAgIGNvbnN0IHZhbHVlQW5kVHlwZSA9IHRoaXMuX2F0dHJpYnV0ZXMuZ2V0KGtleSk7XG4gICAgaWYgKHZhbHVlQW5kVHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihgcmVxdWlyZWQgYXR0cmlidXRlIG5vdCBmb3VuZDogJHtrZXl9YCk7XG4gICAgfVxuICAgIGlmICh2YWx1ZUFuZFR5cGVbMV0gIT09IHR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdHlwZSBtaXNtYXRjaDogZXhwZWN0ZWQgJHt0eXBlfSBidXQgZ290ICR7dmFsdWVBbmRUeXBlWzFdfWApO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWVBbmRUeXBlWzBdIGFzIFY7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRUeXBlKGF0dHI6IG9ubnguSUF0dHJpYnV0ZVByb3RvIHwgb3J0RmJzLkF0dHJpYnV0ZSk6IEF0dHJpYnV0ZS5EYXRhVHlwZSB7XG4gICAgY29uc3QgdHlwZSA9IGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvID8gYXR0ci50eXBlIDogKGF0dHIgYXMgb3J0RmJzLkF0dHJpYnV0ZSkudHlwZSgpO1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuRkxPQVQ6XG4gICAgICAgIHJldHVybiAnZmxvYXQnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UOlxuICAgICAgICByZXR1cm4gJ2ludCc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkc6XG4gICAgICAgIHJldHVybiAnc3RyaW5nJztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlRFTlNPUjpcbiAgICAgICAgcmV0dXJuICd0ZW5zb3InO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuRkxPQVRTOlxuICAgICAgICByZXR1cm4gJ2Zsb2F0cyc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlRTOlxuICAgICAgICByZXR1cm4gJ2ludHMnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuU1RSSU5HUzpcbiAgICAgICAgcmV0dXJuICdzdHJpbmdzJztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlRFTlNPUlM6XG4gICAgICAgIHJldHVybiAndGVuc29ycyc7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGF0dHJpYnV0ZSB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQgeWV0OiAke29ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZVt0eXBlXX1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRWYWx1ZShhdHRyOiBvbm54LklBdHRyaWJ1dGVQcm90byB8IG9ydEZicy5BdHRyaWJ1dGUpIHtcbiAgICBjb25zdCBhdHRyVHlwZSA9IGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvID8gYXR0ci50eXBlIDogKGF0dHIgYXMgb3J0RmJzLkF0dHJpYnV0ZSkudHlwZSgpO1xuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkdSQVBIIHx8IGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuR1JBUEhTKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dyYXBoIGF0dHJpYnV0ZSBpcyBub3Qgc3VwcG9ydGVkIHlldCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXRWYWx1ZU5vQ2hlY2soYXR0cik7XG5cbiAgICAvLyBjYXN0IExPTkcgdG8gbnVtYmVyXG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UICYmIExvbmdVdGlsLmlzTG9uZyh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBMb25nVXRpbC5sb25nVG9OdW1iZXIodmFsdWUgYXMgYmlnaW50IHwgTG9uZyk7XG4gICAgfVxuXG4gICAgLy8gY2FzdCBMT05HW10gdG8gbnVtYmVyW11cbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlRTKSB7XG4gICAgICBjb25zdCBhcnIgPSB2YWx1ZSBhcyBBcnJheTxudW1iZXIgfCBMb25nIHwgYmlnaW50PjtcbiAgICAgIGNvbnN0IG51bWJlclZhbHVlOiBudW1iZXJbXSA9IG5ldyBBcnJheTxudW1iZXI+KGFyci5sZW5ndGgpO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBtYXliZUxvbmcgPSBhcnJbaV07XG4gICAgICAgIG51bWJlclZhbHVlW2ldID0gTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKG1heWJlTG9uZyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudW1iZXJWYWx1ZTtcbiAgICB9XG5cbiAgICAvLyBjYXN0IG9ubnguVGVuc29yUHJvdG8gdG8gb25ueGpzLlRlbnNvclxuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlRFTlNPUikge1xuICAgICAgcmV0dXJuIGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgID8gVGVuc29yLmZyb21Qcm90byh2YWx1ZSBhcyBvbm54LklUZW5zb3JQcm90bylcbiAgICAgICAgOiBUZW5zb3IuZnJvbU9ydFRlbnNvcih2YWx1ZSBhcyBvcnRGYnMuVGVuc29yKTtcbiAgICB9XG5cbiAgICAvLyBjYXN0IG9ubnguVGVuc29yUHJvdG9bXSB0byBvbm54anMuVGVuc29yW11cbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5URU5TT1JTKSB7XG4gICAgICBpZiAoYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG8pIHtcbiAgICAgICAgY29uc3QgdGVuc29yUHJvdG9zID0gdmFsdWUgYXMgb25ueC5JVGVuc29yUHJvdG9bXTtcbiAgICAgICAgcmV0dXJuIHRlbnNvclByb3Rvcy5tYXAoKHZhbHVlKSA9PiBUZW5zb3IuZnJvbVByb3RvKHZhbHVlKSk7XG4gICAgICB9IGVsc2UgaWYgKGF0dHIgaW5zdGFuY2VvZiBvcnRGYnMuQXR0cmlidXRlKSB7XG4gICAgICAgIGNvbnN0IHRlbnNvclByb3RvcyA9IHZhbHVlIGFzIG9ydEZicy5UZW5zb3JbXTtcbiAgICAgICAgcmV0dXJuIHRlbnNvclByb3Rvcy5tYXAoKHZhbHVlKSA9PiBUZW5zb3IuZnJvbU9ydFRlbnNvcih2YWx1ZSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGNhc3QgVWludDhBcnJheSB0byBzdHJpbmdcbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkcpIHtcbiAgICAgIC8vIHN0cmluZyBpbiBvbm54IGF0dHJpYnV0ZSBpcyBvZiB1aW50OGFycmF5IHR5cGUsIHNvIHdlIG5lZWQgdG8gY29udmVydCBpdCB0byBzdHJpbmcgYmVsb3cuIFdoaWxlIGluIG9ydCBmb3JtYXQsXG4gICAgICAvLyBzdHJpbmcgYXR0cmlidXRlcyBhcmUgcmV0dXJuZWQgYXMgc3RyaW5nLCBzbyBubyBjb252ZXJzaW9uIGlzIG5lZWRlZC5cbiAgICAgIGlmIChhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90bykge1xuICAgICAgICBjb25zdCB1dGY4U3RyaW5nID0gdmFsdWUgYXMgVWludDhBcnJheTtcbiAgICAgICAgcmV0dXJuIGRlY29kZVV0ZjhTdHJpbmcodXRmOFN0cmluZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gY2FzdCBVaW50OEFycmF5W10gdG8gc3RyaW5nW11cbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkdTKSB7XG4gICAgICAvLyBzdHJpbmdzIGluIG9ubnggYXR0cmlidXRlIGlzIHJldHVybmVkIGFzIHVpbnQ4YXJyYXlbXSwgc28gd2UgbmVlZCB0byBjb252ZXJ0IGl0IHRvIHN0cmluZ1tdIGJlbG93LiBXaGlsZSBpbiBvcnRcbiAgICAgIC8vIGZvcm1hdCBzdHJpbmdzIGF0dHJpYnV0ZXMgYXJlIHJldHVybmVkIGFzIHN0cmluZ1tdLCBzbyBubyBjb252ZXJzaW9uIGlzIG5lZWRlZC5cbiAgICAgIGlmIChhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90bykge1xuICAgICAgICBjb25zdCB1dGY4U3RyaW5ncyA9IHZhbHVlIGFzIFVpbnQ4QXJyYXlbXTtcbiAgICAgICAgcmV0dXJuIHV0ZjhTdHJpbmdzLm1hcChkZWNvZGVVdGY4U3RyaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWUgYXMgVmFsdWVUeXBlcztcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFZhbHVlTm9DaGVjayhhdHRyOiBvbm54LklBdHRyaWJ1dGVQcm90byB8IG9ydEZicy5BdHRyaWJ1dGUpIHtcbiAgICByZXR1cm4gYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgID8gdGhpcy5nZXRWYWx1ZU5vQ2hlY2tGcm9tT25ueEZvcm1hdChhdHRyKVxuICAgICAgOiB0aGlzLmdldFZhbHVlTm9DaGVja0Zyb21PcnRGb3JtYXQoYXR0ciBhcyBvcnRGYnMuQXR0cmlidXRlKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFZhbHVlTm9DaGVja0Zyb21Pbm54Rm9ybWF0KGF0dHI6IG9ubnguSUF0dHJpYnV0ZVByb3RvKSB7XG4gICAgc3dpdGNoIChhdHRyLnR5cGUhKSB7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5GTE9BVDpcbiAgICAgICAgcmV0dXJuIGF0dHIuZjtcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLklOVDpcbiAgICAgICAgcmV0dXJuIGF0dHIuaTtcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklORzpcbiAgICAgICAgcmV0dXJuIGF0dHIucztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlRFTlNPUjpcbiAgICAgICAgcmV0dXJuIGF0dHIudDtcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkdSQVBIOlxuICAgICAgICByZXR1cm4gYXR0ci5nO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuRkxPQVRTOlxuICAgICAgICByZXR1cm4gYXR0ci5mbG9hdHM7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlRTOlxuICAgICAgICByZXR1cm4gYXR0ci5pbnRzO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuU1RSSU5HUzpcbiAgICAgICAgcmV0dXJuIGF0dHIuc3RyaW5ncztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlRFTlNPUlM6XG4gICAgICAgIHJldHVybiBhdHRyLnRlbnNvcnM7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5HUkFQSFM6XG4gICAgICAgIHJldHVybiBhdHRyLmdyYXBocztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgYXR0cmlidXRlIHR5cGU6ICR7b25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlW2F0dHIudHlwZSFdfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFZhbHVlTm9DaGVja0Zyb21PcnRGb3JtYXQoYXR0cjogb3J0RmJzLkF0dHJpYnV0ZSkge1xuICAgIHN3aXRjaCAoYXR0ci50eXBlKCkpIHtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuRkxPQVQ6XG4gICAgICAgIHJldHVybiBhdHRyLmYoKTtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuSU5UOlxuICAgICAgICByZXR1cm4gYXR0ci5pKCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLlNUUklORzpcbiAgICAgICAgcmV0dXJuIGF0dHIucygpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5URU5TT1I6XG4gICAgICAgIHJldHVybiBhdHRyLnQoKTtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuR1JBUEg6XG4gICAgICAgIHJldHVybiBhdHRyLmcoKTtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuRkxPQVRTOlxuICAgICAgICByZXR1cm4gYXR0ci5mbG9hdHNBcnJheSgpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5JTlRTOiB7XG4gICAgICAgIGNvbnN0IGludHMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRyLmludHNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICAgICAgaW50cy5wdXNoKGF0dHIuaW50cyhpKSEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnRzO1xuICAgICAgfVxuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5TVFJJTkdTOiB7XG4gICAgICAgIGNvbnN0IHN0cmluZ3MgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRyLnN0cmluZ3NMZW5ndGgoKTsgaSsrKSB7XG4gICAgICAgICAgc3RyaW5ncy5wdXNoKGF0dHIuc3RyaW5ncyhpKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0cmluZ3M7XG4gICAgICB9XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLlRFTlNPUlM6IHtcbiAgICAgICAgY29uc3QgdGVuc29ycyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dHIudGVuc29yc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgICAgICB0ZW5zb3JzLnB1c2goYXR0ci50ZW5zb3JzKGkpISk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRlbnNvcnM7XG4gICAgICB9XG4gICAgICAvLyBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLkdSQVBIUzpcbiAgICAgIC8vIFRPRE86IFN1YmdyYXBoIG5vdCBzdXBwb3J0ZWQgeWV0LlxuICAgICAgLy8gY29uc3QgZ3JhcGhzID0gW107XG4gICAgICAvLyBmb3IgKGxldCBpID0gMDsgaSA8IGF0dHIuZ3JhcGhzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgLy8gICBncmFwaHMucHVzaChhdHRyLmdyYXBocyhpKSEpO1xuICAgICAgLy8gfVxuICAgICAgLy8gcmV0dXJuIGdyYXBocztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgYXR0cmlidXRlIHR5cGU6ICR7b3J0RmJzLkF0dHJpYnV0ZVR5cGVbYXR0ci50eXBlKCldfWApO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBfYXR0cmlidXRlczogTWFwPHN0cmluZywgVmFsdWU+O1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGUgfSBmcm9tICcuL2F0dHJpYnV0ZSc7XG5pbXBvcnQgKiBhcyBvcnRGYnMgZnJvbSAnLi9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ydC1nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgb25ueCB9IGZyb20gJy4vb3J0LXNjaGVtYS9wcm90b2J1Zi9vbm54JztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yJztcbmltcG9ydCB7IExvbmdVdGlsLCBNQVhfQ0xJUCwgTUlOX0NMSVAsIFByb3RvVXRpbCB9IGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBHcmFwaCB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgU2hhcGUge1xuICAgIHJlYWRvbmx5IGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgVmFsdWVUeXBlIHtcbiAgICByZWFkb25seSB0ZW5zb3JUeXBlOiBUZW5zb3IuRGF0YVR5cGU7XG4gICAgcmVhZG9ubHkgc2hhcGU6IFNoYXBlO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgVmFsdWUge1xuICAgIC8vIHRoZSB0ZW5zb3IgZGF0YS4gZW1wdHkgZm9yIG5vbi1pbml0aWFsaXplZCBpbnB1dHNcbiAgICByZWFkb25seSB0ZW5zb3I/OiBUZW5zb3I7XG5cbiAgICAvLyBpbmRleCB0byB0aGUgTm9kZSB3aGVyZSB0aGUgdmFsdWUgY29tZXMgZnJvbS4gLTEgZm9yIGluaXRpYWxpemVyLlxuICAgIHJlYWRvbmx5IGZyb206IG51bWJlcjtcblxuICAgIC8vIGluZGljZXMgdG8gdGhlIE5vZGVzIHdoZXJlIHRoZSB2YWx1ZXMgZ28gdG8uXG4gICAgcmVhZG9ubHkgdG86IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gICAgLy8gdmFsdWUgdHlwZSBzcGVjaWZpY2F0aW9uLiBlbXB0eSBmb3Igbm9uLWlucHV0IHZhbHVlcy5cbiAgICByZWFkb25seSB0eXBlPzogVmFsdWVUeXBlO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgTm9kZSB7XG4gICAgLy8gbmFtZSBvZiB0aGUgbm9kZVxuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAgIC8vIHRoZSBvcGVyYXRvciB0eXBlXG4gICAgcmVhZG9ubHkgb3BUeXBlOiBzdHJpbmc7XG5cbiAgICAvLyBpbmRpY2VzIHRvIHRoZSBWYWx1ZXMgd2hlcmUgdGhlIGlucHV0cyBjb21lIGZyb20uXG4gICAgcmVhZG9ubHkgaW5wdXRzOiByZWFkb25seSBudW1iZXJbXTtcblxuICAgIC8vIGluZGljZXMgdG8gdGhlIFZhbHVlcyB3aGVyZSB0aGUgb3V0cHVzIGdvIHRvLlxuICAgIHJlYWRvbmx5IG91dHB1dHM6IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gICAgLy8gdGhlIGF0dHJpYnV0ZXMgdGhhdCB1c2VkIGJ5IHRoZSBvcGVyYXRvclxuICAgIHJlYWRvbmx5IGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBhIFRyYW5zZm9ybWVyIGlzIGFuIGluc3RhbmNlIHRoYXQgYWxsb3dzIGFsbCBwb3NzaWJsZSB0cmFuc2Zvcm1hdGlvbiBvcGVyYXRpb25zIHRoYXQgYXBwbGllZCB0byBhIGdyYXBoXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFRyYW5zZm9ybWVyIHtcbiAgICByZW1vdmVBbGxJZGVudGl0eU5vZGVzKCk6IHZvaWQ7XG4gICAgcmVtb3ZlQWxsRHJvcG91dE5vZGVzKCk6IHZvaWQ7XG4gICAgZnVzZUNvbnZBY3RpdmF0aW9uTm9kZXMoKTogdm9pZDtcbiAgICAvLyBUT0RPOiBhZGQgZ2VuZXJpYyBmdW5jdGlvbnMgdG8gbWFuaXB1bGF0ZSB0aGUgZ3JhcGhcbiAgfVxuXG4gIC8vIGFuIGluaXRpYWxpemVyIGNhbiB1c2UgdHJhbnNmb3JtZXIgdG8gdHJhbnNmb3JtIHRoZSBncmFwaFxuICBleHBvcnQgaW50ZXJmYWNlIEluaXRpYWxpemVyIHtcbiAgICB0cmFuc2Zvcm1HcmFwaCh0cmFuc2Zvcm1lcjogVHJhbnNmb3JtZXIpOiB2b2lkO1xuICB9XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlXG5leHBvcnQgaW50ZXJmYWNlIEdyYXBoIHtcbiAgZ2V0SW5wdXRJbmRpY2VzKCk6IHJlYWRvbmx5IG51bWJlcltdO1xuICBnZXRJbnB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICBnZXRPdXRwdXRJbmRpY2VzKCk6IHJlYWRvbmx5IG51bWJlcltdO1xuICBnZXRPdXRwdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXTtcbiAgZ2V0VmFsdWVzKCk6IHJlYWRvbmx5IEdyYXBoLlZhbHVlW107XG4gIGdldE5vZGVzKCk6IHJlYWRvbmx5IEdyYXBoLk5vZGVbXTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiwgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlZGVjbGFyZVxuZXhwb3J0IGNvbnN0IEdyYXBoID0ge1xuICAvKipcbiAgICogY29uc3RydWN0IGEgZ3JhcGggZnJvbSBhIGdyYXBoIHByb3RvYnVmIHR5cGVcbiAgICovXG4gIGZyb206IChncmFwaFByb3RvOiBvbm54LklHcmFwaFByb3RvIHwgb3J0RmJzLkdyYXBoLCBpbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKSA9PlxuICAgIG5ldyBHcmFwaEltcGwoZ3JhcGhQcm90bywgaW5pdGlhbGl6ZXIpLFxufTtcblxuY2xhc3MgVmFsdWUgaW1wbGVtZW50cyBHcmFwaC5WYWx1ZSB7XG4gIGNvbnN0cnVjdG9yKHZhbHVlSW5mbz86IG9ubnguSVZhbHVlSW5mb1Byb3RvKSB7XG4gICAgdGhpcy5fZnJvbSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl90byA9IFtdO1xuICAgIHRoaXMudGVuc29yID0gdW5kZWZpbmVkO1xuICAgIHRoaXMudHlwZSA9IHVuZGVmaW5lZDtcblxuICAgIGlmICh2YWx1ZUluZm8pIHtcbiAgICAgIHRoaXMudHlwZSA9IFByb3RvVXRpbC50ZW5zb3JWYWx1ZVR5cGVGcm9tUHJvdG8odmFsdWVJbmZvLnR5cGUhLnRlbnNvclR5cGUhKTtcbiAgICB9XG4gIH1cblxuICBfZnJvbT86IG51bWJlcjsgLy8gLTEgcmVwcmVzZW50IGZyb20gaW5pdGlhbGl6ZXJcbiAgZ2V0IGZyb20oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Zyb20hO1xuICB9XG4gIF90bzogbnVtYmVyW107XG4gIGdldCB0bygpIHtcbiAgICByZXR1cm4gdGhpcy5fdG87XG4gIH1cbiAgdHlwZT86IEdyYXBoLlZhbHVlVHlwZTtcbiAgdGVuc29yPzogVGVuc29yO1xufVxuXG5jbGFzcyBOb2RlIGltcGxlbWVudHMgR3JhcGguTm9kZSB7XG4gIGNvbnN0cnVjdG9yKF9ub2RlUHJvdG86IG9ubnguSU5vZGVQcm90byB8IG9ydEZicy5Ob2RlLCBuYW1lPzogc3RyaW5nKSB7XG4gICAgaWYgKF9ub2RlUHJvdG8gaW5zdGFuY2VvZiBvbm54Lk5vZGVQcm90bykge1xuICAgICAgdGhpcy5uYW1lID0gX25vZGVQcm90by5uYW1lO1xuICAgICAgdGhpcy5vcFR5cGUgPSBfbm9kZVByb3RvLm9wVHlwZTtcbiAgICAgIHRoaXMuYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGUoX25vZGVQcm90by5hdHRyaWJ1dGUpO1xuICAgIH0gZWxzZSBpZiAoX25vZGVQcm90byBpbnN0YW5jZW9mIG9ydEZicy5Ob2RlKSB7XG4gICAgICB0aGlzLm5hbWUgPSBuYW1lID8/IF9ub2RlUHJvdG8ubmFtZSgpITtcbiAgICAgIHRoaXMub3BUeXBlID0gX25vZGVQcm90by5vcFR5cGUoKSE7XG4gICAgICB0aGlzLmF0dHJpYnV0ZXMgPSBuZXcgQXR0cmlidXRlKFByb3RvVXRpbC50ZW5zb3JBdHRyaWJ1dGVzRnJvbU9SVEZvcm1hdChfbm9kZVByb3RvKSk7XG4gICAgfVxuXG4gICAgdGhpcy5pbnB1dHMgPSBbXTtcbiAgICB0aGlzLm91dHB1dHMgPSBbXTtcbiAgICB0aGlzLmV4ZWN1dGVOb2RlID0gdHJ1ZTtcbiAgfVxuXG4gIG5hbWU6IHN0cmluZztcbiAgb3BUeXBlOiBzdHJpbmc7XG4gIGlucHV0czogbnVtYmVyW107XG4gIG91dHB1dHM6IG51bWJlcltdO1xuICBhdHRyaWJ1dGVzOiBBdHRyaWJ1dGU7XG4gIGV4ZWN1dGVOb2RlOiBib29sZWFuO1xufVxuXG5jbGFzcyBHcmFwaEltcGwgaW1wbGVtZW50cyBHcmFwaCwgR3JhcGguVHJhbnNmb3JtZXIge1xuICBwcml2YXRlIF9hbGxEYXRhOiBWYWx1ZVtdO1xuXG4gIHByaXZhdGUgX2FsbElucHV0SW5kaWNlczogbnVtYmVyW107XG4gIHByaXZhdGUgX2FsbElucHV0TmFtZXM6IHN0cmluZ1tdO1xuXG4gIHByaXZhdGUgX2FsbE91dHB1dEluZGljZXM6IG51bWJlcltdO1xuICBwcml2YXRlIF9hbGxPdXRwdXROYW1lczogc3RyaW5nW107XG5cbiAgcHJpdmF0ZSBfbm9kZXM6IE5vZGVbXTtcblxuICBjb25zdHJ1Y3RvcihncmFwaDogb25ueC5JR3JhcGhQcm90byB8IG9ydEZicy5HcmFwaCwgZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKSB7XG4gICAgaWYgKCFncmFwaCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZ3JhcGggaXMgZW1wdHknKTtcbiAgICB9XG5cbiAgICAvLyBidWlsZCB0aGUgZ3JhcGggLSB3aWxsIHRocm93IGV4Y2VwdGlvbnMgaWYgc29tZXRoaW5nIGZhdGFsIGlzIGRldGVjdGVkXG4gICAgdGhpcy5idWlsZEdyYXBoKGdyYXBoKTtcblxuICAgIC8vIGV4ZWN1dGUgYW55IHRyYW5zZm9ybWF0aW9uIGxvZ2ljIGZvciB0aGUgZ3JhcGggKGlmIGFwcGxpY2FibGUpXG4gICAgdGhpcy50cmFuc2Zvcm1HcmFwaChncmFwaEluaXRpYWxpemVyKTtcblxuICAgIC8vIGNoZWNrIGZvciBjeWNsZXMgYW5kIG90aGVyIGluY29uc2lzdGVuY2llcyAtIHdpbGwgdGhyb3cgZXhjZXB0aW9ucyBpZiBzb21ldGhpbmcgZmF0YWwgaXMgZGV0ZWN0ZWRcbiAgICB0aGlzLmNoZWNrSXNBY3ljbGljKCk7XG4gIH1cblxuICBnZXRJbnB1dEluZGljZXMoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxJbnB1dEluZGljZXM7XG4gIH1cblxuICBnZXRJbnB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsSW5wdXROYW1lcztcbiAgfVxuXG4gIGdldE91dHB1dEluZGljZXMoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzO1xuICB9XG5cbiAgZ2V0T3V0cHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxPdXRwdXROYW1lcztcbiAgfVxuXG4gIGdldFZhbHVlcygpOiByZWFkb25seSBHcmFwaC5WYWx1ZVtdIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsRGF0YTtcbiAgfVxuXG4gIGdldE5vZGVzKCk6IHJlYWRvbmx5IEdyYXBoLk5vZGVbXSB7XG4gICAgcmV0dXJuIHRoaXMuX25vZGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZEdyYXBoKGdyYXBoOiBvbm54LklHcmFwaFByb3RvIHwgb3J0RmJzLkdyYXBoKSB7XG4gICAgLy8gYnVpbGQgdGhlIGdyYXBoIC0gd2lsbCB0aHJvdyBleGNlcHRpb25zIGlmIHNvbWV0aGluZyBmYXRhbCBpcyBkZXRlY3RlZFxuICAgIGlmIChncmFwaCBpbnN0YW5jZW9mIG9ubnguR3JhcGhQcm90bykge1xuICAgICAgdGhpcy5idWlsZEdyYXBoRnJvbU9ubnhGb3JtYXQoZ3JhcGgpO1xuICAgIH0gZWxzZSBpZiAoZ3JhcGggaW5zdGFuY2VvZiBvcnRGYnMuR3JhcGgpIHtcbiAgICAgIHRoaXMuYnVpbGRHcmFwaEZyb21PcnRGb3JtYXQoZ3JhcGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdHcmFwaCB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgYnVpbGRHcmFwaEZyb21Pbm54Rm9ybWF0KGdyYXBoOiBvbm54LklHcmFwaFByb3RvKSB7XG4gICAgY29uc3QgZGF0YUluZGljZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIHRoaXMuX2FsbERhdGEgPSBbXTtcblxuICAgIHRoaXMuX2FsbElucHV0SW5kaWNlcyA9IFtdO1xuICAgIHRoaXMuX2FsbElucHV0TmFtZXMgPSBbXTtcblxuICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXMgPSBbXTtcbiAgICB0aGlzLl9hbGxPdXRwdXROYW1lcyA9IFtdO1xuXG4gICAgdGhpcy5fbm9kZXMgPSBbXTtcblxuICAgIGNvbnN0IG5vZGVzSW5kaWNlcyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG5cbiAgICAvLyBzY2FuIGFsbCBpbnB1dHNcbiAgICBpZiAoIWdyYXBoLmlucHV0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgaW5mb3JtYXRpb24gaW4gZ3JhcGg6IGlucHV0Jyk7XG4gICAgfVxuICAgIGNvbnN0IGlucHV0VmFsdWVOYW1lcyA9IFtdO1xuICAgIGZvciAoY29uc3QgaSBvZiBncmFwaC5pbnB1dCkge1xuICAgICAgaWYgKGRhdGFJbmRpY2VzLmhhcyhpLm5hbWUhKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgaW5wdXQgbmFtZTogJHtpLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2gobmV3IFZhbHVlKGkpKSAtIDE7XG4gICAgICBkYXRhSW5kaWNlcy5zZXQoaS5uYW1lISwgY3VycmVudEluZGV4KTtcbiAgICAgIGlucHV0VmFsdWVOYW1lcy5wdXNoKGkubmFtZSEpO1xuICAgIH1cblxuICAgIC8vIHNjYW4gYWxsIGluaXRpYWxpemVyc1xuICAgIGlmICghZ3JhcGguaW5pdGlhbGl6ZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBpbmZvcm1hdGlvbiBpbiBncmFwaDogaW5pdGlhbGl6ZXInKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBpIG9mIGdyYXBoLmluaXRpYWxpemVyKSB7XG4gICAgICBsZXQgaW5kZXggPSBkYXRhSW5kaWNlcy5nZXQoaS5uYW1lISk7XG4gICAgICBpZiAoaW5kZXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG5ldyBWYWx1ZSgpO1xuICAgICAgICB2YWx1ZS50eXBlID0ge1xuICAgICAgICAgIHNoYXBlOiB7IGRpbXM6IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbVByb3RvKGkuZGltcyEpIH0sXG4gICAgICAgICAgdGVuc29yVHlwZTogUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKGkuZGF0YVR5cGUhKSxcbiAgICAgICAgfTtcbiAgICAgICAgaW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2godmFsdWUpIC0gMTtcbiAgICAgICAgZGF0YUluZGljZXMuc2V0KGkubmFtZSEsIGluZGV4KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2FsbERhdGFbaW5kZXhdLl9mcm9tID0gLTE7XG4gICAgICB0aGlzLl9hbGxEYXRhW2luZGV4XS50ZW5zb3IgPSBUZW5zb3IuZnJvbVByb3RvKGkpO1xuICAgIH1cblxuICAgIC8vIGZpbHRlciBvdXQgaW5wdXQgaW5kaWNlc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fYWxsRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKCF0aGlzLl9hbGxEYXRhW2ldLnRlbnNvcikge1xuICAgICAgICB0aGlzLl9hbGxJbnB1dEluZGljZXMucHVzaChpKTtcbiAgICAgICAgdGhpcy5fYWxsSW5wdXROYW1lcy5wdXNoKGlucHV0VmFsdWVOYW1lc1tpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2NhbiBhbGwgb3V0cHV0c1xuICAgIGlmICghZ3JhcGgub3V0cHV0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgaW5mb3JtYXRpb24gaW4gZ3JhcGg6IG91dHB1dCcpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGkgb2YgZ3JhcGgub3V0cHV0KSB7XG4gICAgICBpZiAoZGF0YUluZGljZXMuaGFzKGkubmFtZSEpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBvdXRwdXQgbmFtZTogJHtpLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2gobmV3IFZhbHVlKGkpKSAtIDE7XG4gICAgICBkYXRhSW5kaWNlcy5zZXQoaS5uYW1lISwgY3VycmVudEluZGV4KTtcbiAgICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXMucHVzaChjdXJyZW50SW5kZXgpO1xuICAgICAgdGhpcy5fYWxsT3V0cHV0TmFtZXMucHVzaChpLm5hbWUhKTtcbiAgICB9XG5cbiAgICAvLyBzY2FuIGFsbCBub2Rlc1xuICAgIGlmICghZ3JhcGgubm9kZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGluZm9ybWF0aW9uIGluIGdyYXBoOiBub2RlJyk7XG4gICAgfVxuICAgIGZvciAoY29uc3Qgbm9kZVByb3RvIG9mIGdyYXBoLm5vZGUpIHtcbiAgICAgIGlmICghbm9kZVByb3RvLm5hbWUpIHtcbiAgICAgICAgLy8gYXNzaWduIGEgbmFtZSB0byB0aGUgbm9kZSBpZiBpdCBkb2Vzbid0IGhhdmUgb25lXG4gICAgICAgIGZvciAobGV0IHBpY2sgPSAwOyA7IHBpY2srKykge1xuICAgICAgICAgIGNvbnN0IG5hbWUgPSBgdW5uYW1lZF8ke25vZGVQcm90by5vcFR5cGV9XyR7cGlja31gO1xuICAgICAgICAgIGlmICghbm9kZXNJbmRpY2VzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgbm9kZVByb3RvLm5hbWUgPSBuYW1lO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChub2Rlc0luZGljZXMuaGFzKG5vZGVQcm90by5uYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgbm9kZSBuYW1lOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fbm9kZXMucHVzaChuZXcgTm9kZShub2RlUHJvdG8pKSAtIDE7XG4gICAgICBub2Rlc0luZGljZXMuc2V0KG5vZGVQcm90by5uYW1lLCBjdXJyZW50SW5kZXgpO1xuICAgIH1cblxuICAgIC8vIHNjYW4gbm9kZSdzIG91dHB1dHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5fbm9kZXNbaV07XG4gICAgICBjb25zdCBub2RlUHJvdG8gPSBncmFwaC5ub2RlW2ldO1xuICAgICAgaWYgKCFub2RlUHJvdG8ub3V0cHV0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBvdXRwdXQgZm9yIG5vZGU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IG91dHB1dCBvZiBub2RlUHJvdG8ub3V0cHV0KSB7XG4gICAgICAgIGxldCBkYXRhSW5kZXggPSBkYXRhSW5kaWNlcy5nZXQob3V0cHV0KTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgZGF0YUluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZSgpKSAtIDE7XG4gICAgICAgICAgZGF0YUluZGljZXMuc2V0KG91dHB1dCwgZGF0YUluZGV4KTtcbiAgICAgICAgfVxuICAgICAgICBub2RlLm91dHB1dHMucHVzaChkYXRhSW5kZXgpO1xuXG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbXVsdGlwbGUgbm9kZXMgb3V0cHV0IHRvIG9uZSBkYXRhIHZhbHVlOiAke2RhdGFJbmRleH1gKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gPSBpO1xuXG4gICAgICAgIC8vIGZvciB0aGUgJ0NvbnN0YW50JyBvcGVyYXRvciwganVzdCBjcmVhdGUgYSBuZXcgZWRnZSBpbiB0aGUgZ3JhcGggY29ycmVzcG9uZGluZyB0byB0aGUgJ291dHB1dCcgb2YgdGhlXG4gICAgICAgIC8vIG9wZXJhdG9yIGFuZCBpZ25vcmUgdGhlIG5vZGUgZnJvbSB0aGUgZ3JhcGhcbiAgICAgICAgaWYgKG5vZGVQcm90by5vcFR5cGUgPT09ICdDb25zdGFudCcpIHtcbiAgICAgICAgICBpZiAoIW5vZGVQcm90by5hdHRyaWJ1dGUgfHwgbm9kZVByb3RvLmF0dHJpYnV0ZS5sZW5ndGggIT09IDEgfHwgIW5vZGVQcm90by5hdHRyaWJ1dGVbMF0udCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGF0dHJpYnV0ZXMgb3IgbWlzc2luZyB0ZW5zb3IgdmFsdWUgaW4gYXR0cmlidXRlcyBmb3IgdGhpcyBDb25zdGFudCBvcGVyYXRvcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5vZGVQcm90by5vdXRwdXQgfHwgbm9kZVByb3RvLm91dHB1dC5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBvdXRwdXQgb3IgaW5jb3JyZWN0IG51bWJlciBvZiBvdXRwdXRzIGZvciB0aGlzIENvbnN0YW50IG9wZXJhdG9yJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG5vZGUub3V0cHV0cy5wb3AoKTtcbiAgICAgICAgICBub2RlLmV4ZWN1dGVOb2RlID0gZmFsc2U7XG5cbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gPSAtMTtcbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0udGVuc29yID0gVGVuc29yLmZyb21Qcm90byhub2RlUHJvdG8uYXR0cmlidXRlWzBdLnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2NhbiBub2RlJ3MgaW5wdXRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgbm9kZSA9IHRoaXMuX25vZGVzW2ldO1xuICAgICAgY29uc3Qgbm9kZVByb3RvID0gZ3JhcGgubm9kZVtpXTtcblxuICAgICAgaWYgKCFub2RlUHJvdG8uaW5wdXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIGlucHV0IGZvciBub2RlOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBpbnB1dCBvZiBub2RlUHJvdG8uaW5wdXQpIHtcbiAgICAgICAgY29uc3QgZGF0YUluZGV4ID0gZGF0YUluZGljZXMuZ2V0KGlucHV0KTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgLy8gaGFuZGxlIGV4Y2VwdGlvbiB3aGVuIG9wc2V0ID4gOSBhbmQgcm9pIC8gc2NhbGVzIG5vdCBnaXZlblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGlucHV0ID09PSAnJyAmJlxuICAgICAgICAgICAgKG5vZGVQcm90by5pbnB1dC5sZW5ndGggPT09IDMgfHwgbm9kZVByb3RvLmlucHV0Lmxlbmd0aCA9PT0gNCkgJiZcbiAgICAgICAgICAgIG5vZGVQcm90by5vcFR5cGUgPT09ICdSZXNpemUnXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnJlY29nbml6ZWQgaW5wdXQgJyR7aW5wdXR9JyBmb3Igbm9kZTogJHtub2RlUHJvdG8ubmFtZX1gKTtcbiAgICAgICAgfVxuICAgICAgICBub2RlLmlucHV0cy5wdXNoKGRhdGFJbmRleCk7XG5cbiAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl90by5wdXNoKGkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZEdyYXBoRnJvbU9ydEZvcm1hdChncmFwaDogb3J0RmJzLkdyYXBoKSB7XG4gICAgY29uc3QgZGF0YUluZGljZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIHRoaXMuX2FsbERhdGEgPSBbXTtcblxuICAgIHRoaXMuX2FsbElucHV0SW5kaWNlcyA9IFtdO1xuICAgIHRoaXMuX2FsbElucHV0TmFtZXMgPSBbXTtcblxuICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXMgPSBbXTtcbiAgICB0aGlzLl9hbGxPdXRwdXROYW1lcyA9IFtdO1xuXG4gICAgdGhpcy5fbm9kZXMgPSBbXTtcblxuICAgIGNvbnN0IG5vZGVzSW5kaWNlcyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG5cbiAgICAvLyBzY2FuIGFsbCBpbnB1dHNcbiAgICBjb25zdCBpbnB1dFZhbHVlTmFtZXMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoLmlucHV0c0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGNvbnN0IGlucHV0TmFtZSA9IGdyYXBoLmlucHV0cyhpKTtcbiAgICAgIGlmIChkYXRhSW5kaWNlcy5oYXMoaW5wdXROYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgaW5wdXQgbmFtZTogJHtpbnB1dE5hbWV9YCk7XG4gICAgICB9XG4gICAgICAvLyBGaW5kIHRoZSBpbnB1dCB0eXBlSW5mbyBmcm9tIG5vZGVhcmdzXG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGdyYXBoLm5vZGVBcmdzTGVuZ3RoKCk7IGorKykge1xuICAgICAgICBpZiAoZ3JhcGgubm9kZUFyZ3Moaik/Lm5hbWUoKSA9PT0gaW5wdXROYW1lKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBuZXcgVmFsdWUoKTtcbiAgICAgICAgICBjb25zdCB2YWx1ZVR5cGUgPSBncmFwaC5ub2RlQXJncyhqKT8udHlwZSgpPy52YWx1ZVR5cGUoKTtcbiAgICAgICAgICBpZiAodmFsdWVUeXBlICE9PSBvcnRGYnMuVHlwZUluZm9WYWx1ZS50ZW5zb3JfdHlwZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIHZhbHVlIHR5cGUgZm9yIHRoZSBub2RlQXJnLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB2YWx1ZUluZm8gPSBncmFwaC5ub2RlQXJncyhqKSEudHlwZSgpIS52YWx1ZShuZXcgb3J0RmJzLlRlbnNvclR5cGVBbmRTaGFwZSgpKSE7XG4gICAgICAgICAgY29uc3QgdHlwZSA9IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byh2YWx1ZUluZm8uZWxlbVR5cGUoKSk7XG4gICAgICAgICAgY29uc3Qgc2hhcGUgPSB2YWx1ZUluZm8uc2hhcGUoKSE7XG4gICAgICAgICAgY29uc3QgZGltcyA9IFtdO1xuICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgc2hhcGUuZGltTGVuZ3RoKCkhOyBrKyspIHtcbiAgICAgICAgICAgIGRpbXMucHVzaChMb25nVXRpbC5sb25nVG9OdW1iZXIoc2hhcGUuZGltKGspIS52YWx1ZSgpIS5kaW1WYWx1ZSgpISkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YWx1ZS50eXBlID0geyBzaGFwZTogeyBkaW1zIH0sIHRlbnNvclR5cGU6IHR5cGUgfTtcbiAgICAgICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2godmFsdWUpIC0gMTtcbiAgICAgICAgICBkYXRhSW5kaWNlcy5zZXQoaW5wdXROYW1lLCBjdXJyZW50SW5kZXgpO1xuICAgICAgICAgIGlucHV0VmFsdWVOYW1lcy5wdXNoKGlucHV0TmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gY2hlY2sgaW5pdGlhbGl6ZXJzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaC5pbml0aWFsaXplcnNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICBjb25zdCBpbml0aWFsaXplciA9IGdyYXBoLmluaXRpYWxpemVycyhpKSE7XG4gICAgICBsZXQgaW5kZXggPSBkYXRhSW5kaWNlcy5nZXQoaW5pdGlhbGl6ZXIubmFtZSgpISk7XG4gICAgICBpZiAoaW5kZXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG5ldyBWYWx1ZSgpO1xuICAgICAgICBjb25zdCBkaW1zID0gUHJvdG9VdGlsLnRlbnNvckRpbXNGcm9tT1JURm9ybWF0KGluaXRpYWxpemVyKTtcbiAgICAgICAgY29uc3QgdHlwZSA9IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byhpbml0aWFsaXplci5kYXRhVHlwZSgpKTtcbiAgICAgICAgdmFsdWUudHlwZSA9IHsgc2hhcGU6IHsgZGltcyB9LCB0ZW5zb3JUeXBlOiB0eXBlIH07XG4gICAgICAgIGluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKHZhbHVlKSAtIDE7XG4gICAgICAgIGRhdGFJbmRpY2VzLnNldChpbml0aWFsaXplci5uYW1lKCkhLCBpbmRleCk7XG4gICAgICB9XG4gICAgICB0aGlzLl9hbGxEYXRhW2luZGV4XS5fZnJvbSA9IC0xO1xuICAgICAgdGhpcy5fYWxsRGF0YVtpbmRleF0udGVuc29yID0gVGVuc29yLmZyb21PcnRUZW5zb3IoaW5pdGlhbGl6ZXIpO1xuICAgIH1cblxuICAgIC8vIGZpbHRlciBvdXQgaW5wdXQgaW5kaWNlc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fYWxsRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKCF0aGlzLl9hbGxEYXRhW2ldLnRlbnNvcikge1xuICAgICAgICB0aGlzLl9hbGxJbnB1dEluZGljZXMucHVzaChpKTtcbiAgICAgICAgdGhpcy5fYWxsSW5wdXROYW1lcy5wdXNoKGlucHV0VmFsdWVOYW1lc1tpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2NhbiBhbGwgb3V0cHV0c1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ3JhcGgub3V0cHV0c0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGNvbnN0IG91dHB1dE5hbWUgPSBncmFwaC5vdXRwdXRzKGkpO1xuICAgICAgaWYgKGRhdGFJbmRpY2VzLmhhcyhvdXRwdXROYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgb3V0cHV0IG5hbWU6ICR7b3V0cHV0TmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaChuZXcgVmFsdWUoKSkgLSAxO1xuICAgICAgZGF0YUluZGljZXMuc2V0KG91dHB1dE5hbWUsIGN1cnJlbnRJbmRleCk7XG4gICAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzLnB1c2goY3VycmVudEluZGV4KTtcbiAgICAgIHRoaXMuX2FsbE91dHB1dE5hbWVzLnB1c2gob3V0cHV0TmFtZSk7XG4gICAgfVxuXG4gICAgLy8gc2NhbiBhbGwgbm9kZXNcbiAgICBpZiAoIWdyYXBoLm5vZGVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgaW5mb3JtYXRpb24gaW4gZ3JhcGg6IG5vZGUnKTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaC5ub2Rlc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGNvbnN0IG5vZGVQcm90byA9IGdyYXBoLm5vZGVzKGkpO1xuICAgICAgbGV0IG5hbWUgPSBub2RlUHJvdG8hLm5hbWUoKTtcbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICAvLyBhc3NpZ24gYSBuYW1lIHRvIHRoZSBub2RlIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmVcbiAgICAgICAgZm9yIChsZXQgcGljayA9IDA7IDsgcGljaysrKSB7XG4gICAgICAgICAgbmFtZSA9IGB1bm5hbWVkXyR7bm9kZVByb3RvIS5vcFR5cGUoKX1fJHtwaWNrfWA7XG4gICAgICAgICAgaWYgKCFub2Rlc0luZGljZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICAvLyBhbiB1bmlxdWUgbmFtZSBpcyBmb3VuZC4gYnJlYWsuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGVzSW5kaWNlcy5oYXMobmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBkdXBsaWNhdGVkIG5vZGUgbmFtZTogJHtuYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fbm9kZXMucHVzaChuZXcgTm9kZShub2RlUHJvdG8hLCBuYW1lKSkgLSAxO1xuICAgICAgbm9kZXNJbmRpY2VzLnNldChuYW1lLCBjdXJyZW50SW5kZXgpO1xuICAgIH1cblxuICAgIC8vIHNjYW4gbm9kZSdzIG91dHB1dHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5fbm9kZXNbaV07XG4gICAgICBjb25zdCBub2RlUHJvdG8gPSBncmFwaC5ub2RlcyhpKTtcbiAgICAgIGlmIChub2RlUHJvdG8gPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIG5vZGUgZXhpc3RzIGF0IGluZGV4ICR7aX1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChub2RlUHJvdG8/Lm91dHB1dHNMZW5ndGgoKSA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG1pc3Npbmcgb3V0cHV0IGZvciBub2RlOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBub2RlUHJvdG8/Lm91dHB1dHNMZW5ndGgoKTsgaisrKSB7XG4gICAgICAgIGNvbnN0IG91dHB1dCA9IG5vZGVQcm90bz8ub3V0cHV0cyhqKTtcbiAgICAgICAgbGV0IGRhdGFJbmRleCA9IGRhdGFJbmRpY2VzLmdldChvdXRwdXQpO1xuICAgICAgICBpZiAodHlwZW9mIGRhdGFJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBkYXRhSW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2gobmV3IFZhbHVlKCkpIC0gMTtcbiAgICAgICAgICBkYXRhSW5kaWNlcy5zZXQob3V0cHV0LCBkYXRhSW5kZXgpO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUub3V0cHV0cy5wdXNoKGRhdGFJbmRleCk7XG5cbiAgICAgICAgaWYgKHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fZnJvbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtdWx0aXBsZSBub2RlcyBvdXRwdXQgdG8gb25lIGRhdGEgdmFsdWU6ICR7ZGF0YUluZGV4fWApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fZnJvbSA9IGk7XG5cbiAgICAgICAgLy8gZm9yIHRoZSAnQ29uc3RhbnQnIG9wZXJhdG9yLCBqdXN0IGNyZWF0ZSBhIG5ldyBlZGdlIGluIHRoZSBncmFwaCBjb3JyZXNwb25kaW5nIHRvIHRoZSAnb3V0cHV0JyBvZiB0aGVcbiAgICAgICAgLy8gb3BlcmF0b3IgYW5kIGlnbm9yZSB0aGUgbm9kZSBmcm9tIHRoZSBncmFwaFxuICAgICAgICBpZiAobm9kZVByb3RvLm9wVHlwZSgpID09PSAnQ29uc3RhbnQnKSB7XG4gICAgICAgICAgaWYgKG5vZGVQcm90by5hdHRyaWJ1dGVzTGVuZ3RoKCkgIT09IDEgfHwgIW5vZGVQcm90by5hdHRyaWJ1dGVzKDApIS50KCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBhdHRyaWJ1dGVzIG9yIG1pc3NpbmcgdGVuc29yIHZhbHVlIGluIGF0dHJpYnV0ZXMgZm9yIHRoaXMgQ29uc3RhbnQgb3BlcmF0b3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG5vZGVQcm90by5vdXRwdXRzTGVuZ3RoKCkgIT09IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBvdXRwdXQgb3IgaW5jb3JyZWN0IG51bWJlciBvZiBvdXRwdXRzIGZvciB0aGlzIENvbnN0YW50IG9wZXJhdG9yJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG5vZGUub3V0cHV0cy5wb3AoKTtcbiAgICAgICAgICBub2RlLmV4ZWN1dGVOb2RlID0gZmFsc2U7XG5cbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gPSAtMTtcbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0udGVuc29yID0gVGVuc29yLmZyb21PcnRUZW5zb3Iobm9kZVByb3RvLmF0dHJpYnV0ZXMoMCkhLnQoKSEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2NhbiBub2RlJ3MgaW5wdXRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgbm9kZSA9IHRoaXMuX25vZGVzW2ldO1xuICAgICAgY29uc3Qgbm9kZVByb3RvID0gZ3JhcGgubm9kZXMoaSkhO1xuXG4gICAgICBpZiAobm9kZVByb3RvLmlucHV0c0xlbmd0aCgpID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBpbnB1dCBmb3Igbm9kZTogJHtub2RlUHJvdG8ubmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbm9kZVByb3RvLmlucHV0c0xlbmd0aCgpITsgaisrKSB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gbm9kZVByb3RvLmlucHV0cyhqKSE7XG4gICAgICAgIGNvbnN0IGRhdGFJbmRleCA9IGRhdGFJbmRpY2VzLmdldChpbnB1dCk7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YUluZGV4ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5yZWNvZ25pemVkIGlucHV0ICcke2lucHV0fScgZm9yIG5vZGU6ICR7bm9kZVByb3RvIS5uYW1lKCl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZS5pbnB1dHMucHVzaChkYXRhSW5kZXgpO1xuXG4gICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fdG8ucHVzaChpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNoZWNrSXNBY3ljbGljKCkge1xuICAgIC8vIGdvIHRocm91Z2ggdGhlIGdyYXBoIGFuZCBjaGVjayBmb3IgY3ljbGVzIG9yIG90aGVyIGZhdGFsIGluY29uc2lzdGVuY2llc1xuICAgIGNvbnN0IHN0YXJ0ZXJzOiBTZXQ8bnVtYmVyPiA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICAgIHRoaXMuX2FsbElucHV0SW5kaWNlcy5mb3JFYWNoKChpKSA9PiB7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5fYWxsRGF0YVtpXTtcbiAgICAgIGRhdGEuX3RvLmZvckVhY2goKGopID0+IHtcbiAgICAgICAgc3RhcnRlcnMuYWRkKGopO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBJdGVyYXRpdmUgREZTIHRvIGNoZWNrIGZvciBjeWNsZXNcbiAgICBjb25zdCBub2Rlc1N0YWNrID0gQXJyYXkuZnJvbShzdGFydGVycyk7XG4gICAgY29uc3Qgbm9kZXNTdGF0ZSA9IG5ldyBBcnJheTxzdHJpbmc+KHRoaXMuX25vZGVzLmxlbmd0aCkuZmlsbCgnd2hpdGUnKTtcblxuICAgIHdoaWxlIChub2Rlc1N0YWNrLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IG5vZGVJbmRleCA9IG5vZGVzU3RhY2sucG9wKCkhO1xuICAgICAgLy8gdGhpcyBub2RlIGhhcyBub3cgYmVlbiBwcm9jZXNzZWQgY29tcGxldGVseS4gTWFyayB0aGlzIG5vZGUgJ2JsYWNrJyB0byBkZW5vdGUgdGhpcy5cbiAgICAgIGlmIChub2Rlc1N0YXRlW25vZGVJbmRleF0gPT09ICdncmF5Jykge1xuICAgICAgICBub2Rlc1N0YXRlW25vZGVJbmRleF0gPSAnYmxhY2snO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gdGhpcyBub2RlIGlzIHVuZGVyIHByb2Nlc3Npbmcgc3RhZ2UuIG1hcmsgdGhpcyBub2RlICdncmF5JyB0byBkZW5vdGUgdGhpcy5cbiAgICAgICAgbm9kZXNTdGFjay5wdXNoKG5vZGVJbmRleCk7XG4gICAgICAgIG5vZGVzU3RhdGVbbm9kZUluZGV4XSA9ICdncmF5JztcblxuICAgICAgICB0aGlzLl9ub2Rlc1tub2RlSW5kZXhdLm91dHB1dHMuZm9yRWFjaCgob3V0Z29pbmdFZGdlSW5kZXgpID0+IHtcbiAgICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5fYWxsRGF0YVtvdXRnb2luZ0VkZ2VJbmRleF07XG4gICAgICAgICAgaWYgKHR5cGVvZiBkYXRhLnRlbnNvciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbm9kZSBvdXRwdXRzIHNob3VsZCBub3QgYmUgaW5pdGlhbGl6ZWQnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGRhdGEuX2Zyb20gIT09IG5vZGVJbmRleCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZnJvbSBwcm9wZXJ0eSBvZiB0aGUgVmFsdWUgb2JqZWN0IGRvZXNuJ3QgbWF0Y2ggaW5kZXggb2YgTm9kZSBiZWluZyBwcm9jZXNzZWRcIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRhdGEuX3RvLmZvckVhY2goKGRvd25zdHJlYW1Ob2RlSW5kZXgpID0+IHtcbiAgICAgICAgICAgIC8vIGJhY2sgZWRnZSBmb3VuZCAtIGN5Y2xpY1xuICAgICAgICAgICAgaWYgKG5vZGVzU3RhdGVbZG93bnN0cmVhbU5vZGVJbmRleF0gPT09ICdncmF5Jykge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21vZGVsIGdyYXBoIGlzIGN5Y2xpYycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gdHJlZSBlZGdlIGZvdW5kIC0gY29udGludWUgcHJvY2Vzc2luZyBieSBhZGRpbmcgaXQgdG8gc3RhY2tcbiAgICAgICAgICAgIGVsc2UgaWYgKG5vZGVzU3RhdGVbZG93bnN0cmVhbU5vZGVJbmRleF0gPT09ICd3aGl0ZScpIHtcbiAgICAgICAgICAgICAgbm9kZXNTdGFjay5wdXNoKGRvd25zdHJlYW1Ob2RlSW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHRyYW5zZm9ybUdyYXBoKGdyYXBoSW5pdGlhbGl6ZXI/OiBHcmFwaC5Jbml0aWFsaXplcik6IHZvaWQge1xuICAgIC8vIGFwcGx5IGNvbW1vbiB0cmFuc2Zvcm1cbiAgICB0aGlzLnJlbW92ZUFsbElkZW50aXR5Tm9kZXMoKTtcbiAgICB0aGlzLnJlbW92ZUFsbERyb3BvdXROb2RlcygpO1xuICAgIHRoaXMuZnVzZUNvbnZBY3RpdmF0aW9uTm9kZXMoKTtcbiAgICAvLyBhcHBseSBpbml0aWFsaXplciBzcGVjaWZpYyB0cmFuc2Zvcm1cbiAgICBpZiAoZ3JhcGhJbml0aWFsaXplcikge1xuICAgICAgZ3JhcGhJbml0aWFsaXplci50cmFuc2Zvcm1HcmFwaCh0aGlzKTtcbiAgICB9XG5cbiAgICAvLyBmaW5hbGl6ZSBncmFwaFxuICAgIHRoaXMuZmluYWxpemVHcmFwaCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIGZpbmFsaXplIHRoZSBncmFwaC5cbiAgICpcbiAgICogdGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgY2FsbGVkIGFmdGVyIGFsbCB0aGUgdHJhbnNmb3JtYXRpb24gY29tcGxldGVkLlxuICAgKiB0aGlzIGZ1bmN0aW9uIHJlbW92ZXMgYWxsIHVubmVjZXNzYXJ5IG5vZGVzIGFuZCB2YWx1ZXMgZnJvbSB0aGUgZ3JhcGhcbiAgICovXG4gIGZpbmFsaXplR3JhcGgoKSB7XG4gICAgbGV0IG9mZnNldCA9IDA7XG4gICAgLy8gZGVsZXRlIGFsbCBub2RlcyB0aGF0IGFyZSBub3QgYmVpbmcgZXhlY3V0ZWRcbiAgICAvLyBUaGUgZ3JhcGggaXMgcmVwcmVzZW50ZWQgdXNpbmcgdGhlc2UgdHdvIGFycmF5c1xuICAgIC8vIHRoaXMuX25vZGVzIC0gQXJyYXkgaG9sZGluZyB0aGUga2VybmVscyB0byBleGVjdXRlIC0gZWFjaCBlbnRyeSBpcyBhIGtlcm5lbCBwb2ludGluZyB0byB0aGlzLl9hbGxEYXRhXG4gICAgLy8gdGhpcy5fYWxsRGF0YSAtIGhvbGQgMiBmaWVsZHMgLSB0byBbXSAmIGZyb20gLSB0aGVzZSBmZWlsZWRzIGhvbGQgdGhlIGdyYXBoIG1hcCBmb3IgaW5wdXRzIGFuZCBvdXRwdXRzIHBlciBub2RlXG4gICAgLy8gbmV3SW5kaWNlcyAtIHJlbWFwcGluZyB0aGUgZ3JhcGggYWZ0ZXIgcmVhZGluZyB0aGUgZmxhZyAnZXhlY3V0ZU5vZGUnXG4gICAgY29uc3QgbmV3SW5kaWNlcyA9IG5ldyBBcnJheTxudW1iZXI+KHRoaXMuX25vZGVzLmxlbmd0aCwgMCk7XG4gICAgbGV0IG5vZGVQb3NzaXRpb24gPSAwO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgLy8gZ2l2aW5nIG5ldyBpbmRleGVzIHRvIHRoZSBub2RlcyBiYXNlZCBvbiBleGVjdXRpb24gZmxhZ1xuICAgICAgbmV3SW5kaWNlc1tpXSA9IG5vZGVQb3NzaXRpb247XG4gICAgICBpZiAodGhpcy5fbm9kZXNbaV0uZXhlY3V0ZU5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGVQb3NzaXRpb24gIT09IGkpIHtcbiAgICAgICAgICB0aGlzLl9ub2Rlc1tub2RlUG9zc2l0aW9uXSA9IHRoaXMuX25vZGVzW2ldO1xuICAgICAgICB9XG4gICAgICAgIG5vZGVQb3NzaXRpb24rKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGRlbGV0ZSBhbGwgb3V0cHV0IHZhbHVlc1xuICAgICAgICB0aGlzLl9ub2Rlc1tpXS5vdXRwdXRzLmZvckVhY2goKGluZCkgPT4ge1xuICAgICAgICAgIHRoaXMuX2FsbERhdGFbaW5kXS5fZnJvbSA9IC0yO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyByZW1vdmluZyB0aGUgdW51c2VkIG5vZGVzXG4gICAgdGhpcy5fbm9kZXMuc3BsaWNlKG5vZGVQb3NzaXRpb24sIHRoaXMuX25vZGVzLmxlbmd0aCAtIG5vZGVQb3NzaXRpb24pO1xuXG4gICAgLy8gVXBkYXRpbmcgdGhpcy5fYWxsRGF0YSBhY2NvcmRpbmcgdG8gdGhlIG5ldyB0aGlzLl9ub2Rlc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fYWxsRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgY3VycmVudERhdGEgPSB0aGlzLl9hbGxEYXRhW2ldO1xuICAgICAgaWYgKGN1cnJlbnREYXRhLl9mcm9tICE9PSB1bmRlZmluZWQgJiYgY3VycmVudERhdGEuX2Zyb20gIT09IC0xICYmIGN1cnJlbnREYXRhLl9mcm9tICE9PSAtMikge1xuICAgICAgICBjdXJyZW50RGF0YS5fZnJvbSA9IG5ld0luZGljZXNbY3VycmVudERhdGEuX2Zyb21dO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGN1cnJlbnREYXRhLl90by5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAoY3VycmVudERhdGEuX3RvW2pdID49IDApIHtcbiAgICAgICAgICBjdXJyZW50RGF0YS5fdG9bal0gPSBuZXdJbmRpY2VzW2N1cnJlbnREYXRhLl90b1tqXV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUcnlpbmcgdG8gdXBkYXRlIGEgcmVtb3ZlZCBub2RlJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBvZmZzZXQgPSAwO1xuICAgIC8vIGRlbGV0ZSBhbGwgdmFsdWVzIHRoYXQgYXJlIG5vdCBiZWluZyByZWZlcmVuY2VkXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hbGxEYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvLyBpZiBjdXJyZW50IHZhbHVlIGlzIG5laXRoZXIgbGlua2VkIHRvIG5leHQgbm9kZSwgbm9yIGFuIG91dHB1dCB2YWx1ZSwgcmVtb3ZlIGl0LlxuICAgICAgaWYgKHRoaXMuX2FsbERhdGFbaV0uZnJvbSA9PT0gLTIgJiYgdGhpcy5fYWxsT3V0cHV0SW5kaWNlcy5pbmRleE9mKGkgKyBvZmZzZXQpID09PSAtMSkge1xuICAgICAgICBvZmZzZXQrKztcbiAgICAgICAgdGhpcy5fYWxsRGF0YS5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGktLTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAob2Zmc2V0ID4gMCkge1xuICAgICAgICBsZXQgaW5kID0gLTE7XG4gICAgICAgIC8vIGlmIGN1cnJlbnQgdmFsdWUgaXMgbmVpdGhlciBhbiBpbnB1dCB2YWx1ZSBub3IgYW4gaW5pdGlhbGl6ZXIsIGZpbmQgdGhlIG5vZGUgaXQnc1xuICAgICAgICAvLyBjb21pbmcgZnJvbSBhbmQgdXBkYXRlIHRoZSBjb3JyZXNwb25kaW5nIG5vZGUgb3V0cHV0XG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2ldLmZyb20gIT09IHVuZGVmaW5lZCAmJiB0aGlzLl9hbGxEYXRhW2ldLmZyb20gIT09IC0xKSB7XG4gICAgICAgICAgaW5kID0gdGhpcy5fbm9kZXNbdGhpcy5fYWxsRGF0YVtpXS5mcm9tXS5vdXRwdXRzLmluZGV4T2YoaSArIG9mZnNldCk7XG4gICAgICAgICAgaWYgKGluZCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX25vZGVzW3RoaXMuX2FsbERhdGFbaV0uZnJvbV0ub3V0cHV0c1tpbmRdID0gaTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gaWYgY3VycmVudCB2YWx1ZSBpcyBhbiBpbnB1dCB2YWx1ZSwgdXBkYXRlIGl0cyByZWZlcmVuY2UgaW4gaW5wdXRJbmRpY2VzXG4gICAgICAgICAgaW5kID0gdGhpcy5fYWxsSW5wdXRJbmRpY2VzLmluZGV4T2YoaSArIG9mZnNldCk7XG4gICAgICAgICAgaWYgKGluZCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX2FsbElucHV0SW5kaWNlc1tpbmRdID0gaTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaW5kIHRoZSBub2RlIHRoYXQgdGhlIGN1cnJlbnQgdmFsdWUgaXMgbGlua2luZyB0byBhbmQgdXBkYXRlIGl0cyBpbnB1dCByZWZlcmVuY2VcbiAgICAgICAgdGhpcy5fYWxsRGF0YVtpXS50by5mb3JFYWNoKChub2RlKSA9PiB7XG4gICAgICAgICAgaW5kID0gdGhpcy5fbm9kZXNbbm9kZV0uaW5wdXRzLmluZGV4T2YoaSArIG9mZnNldCk7XG4gICAgICAgICAgaWYgKGluZCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX25vZGVzW25vZGVdLmlucHV0c1tpbmRdID0gaTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy5fYWxsRGF0YVtpXS50by5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAvLyBpZiBjdXJyZW50IHZhbHVlIGlzIGEgZ3JhcGggb3V0cHV0LCB1cGRhdGUgaXRzIHJlZmVyZW5jZSBpbiBvdXRwdXRJbmRpY2VzXG4gICAgICAgICAgaW5kID0gdGhpcy5fYWxsT3V0cHV0SW5kaWNlcy5pbmRleE9mKGkgKyBvZmZzZXQpO1xuICAgICAgICAgIGlmIChpbmQgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzW2luZF0gPSBpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgdGhlIHNwZWNpZmllZCBub2RlLiBBc3N1bWUgdGhlIG5vZGUgaGFzIG9uZSBpbmNvbWluZyBpbnB1dCBhbmQgdGhlIGZpcnN0IG91dHB1dCBjb25uZWN0ZWQgdG8gb3RoZXIgbm9kZXMuXG4gICAqIEFuIGlucHV0IHZhbGlkYXRpb24gbXVzdCBiZSBkb25lIGJlZm9yZSBjYWxsaW5nIHRoaXMgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSBub2RlSW5kZXggVGhlIGluZGV4IG9mIG5vZGUgdG8gYmUgZGVsZXRlZFxuICAgKi9cbiAgcHJpdmF0ZSBkZWxldGVOb2RlKG5vZGVJbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuX25vZGVzW25vZGVJbmRleF07XG4gICAgaWYgKG5vZGUub3V0cHV0cy5sZW5ndGggPiAxKSB7XG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8IG5vZGUub3V0cHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAodGhpcy5fYWxsRGF0YVtub2RlLm91dHB1dHNbaV1dLnRvLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vZGUgZGVsZXRpb24gd2l0aCBtb3JlIHRoYW4gb25lIG91dHB1dCBjb25uZWN0ZWQgdG8gb3RoZXIgbm9kZXMgaXMgbm90IHN1cHBvcnRlZC4gJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyB0aGlzIG5vZGUgd2lsIG5vdCBiZSBleGVjdXRlZFxuICAgIG5vZGUuZXhlY3V0ZU5vZGUgPSBmYWxzZTtcbiAgICBjb25zdCBpbnB1dFZhbHVlSW5kZXggPSBub2RlLmlucHV0c1swXTtcbiAgICBjb25zdCBvdXRwdXRWYWx1ZUluZGV4ID0gbm9kZS5vdXRwdXRzWzBdO1xuICAgIGNvbnN0IG5vZGVzQ29uc3VtaW5nT3V0cHV0ID0gdGhpcy5fYWxsRGF0YVtvdXRwdXRWYWx1ZUluZGV4XS50bztcblxuICAgIC8vIHJlbW92ZSB0aGlzIG5vZGUgZnJvbSB0aGUgdG8gcHJvcGVydHkgb2YgdGhlIGlucHV0IFZhbHVlXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2RlLmlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZGVsSW5kZXggPSB0aGlzLl9hbGxEYXRhW25vZGUuaW5wdXRzW2ldXS50by5pbmRleE9mKG5vZGVJbmRleCk7XG4gICAgICAvLyBzaG91bGQgbm90IGhhcHBlblxuICAgICAgaWYgKGRlbEluZGV4ID09PSAtMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgVmFsdWUgb2JqZWN0IGRvZXNuJ3QgaGF2ZSB0aGUgY3VycmVudCBOb2RlIGluIGl0J3MgJ3RvJyBwcm9wZXJ0eSBcIik7XG4gICAgICB9XG4gICAgICB0aGlzLl9hbGxEYXRhW25vZGUuaW5wdXRzW2ldXS50by5zcGxpY2UoZGVsSW5kZXgsIDEpO1xuICAgIH1cblxuICAgIC8vIGNsZWFyIG5vZGUgaW5kaWNlcyBjb25zdW1pbmcgdGhpcyBvdXRwdXQgVmFsdWVcbiAgICB0aGlzLl9hbGxEYXRhW291dHB1dFZhbHVlSW5kZXhdLl90byA9IFtdO1xuXG4gICAgLy8gaWYgdGhlIG91dHB1dCBvZiB0aGlzIG5vZGUgaXMgYSBncmFwaCBvdXRwdXQsIGFkanVzdCB0aGUgaW5kZXggYXBwcm9wcmlhdGVseVxuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fYWxsT3V0cHV0SW5kaWNlcy5pbmRleE9mKG91dHB1dFZhbHVlSW5kZXgpO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXNbaW5kZXhdID0gaW5wdXRWYWx1ZUluZGV4O1xuICAgIH1cblxuICAgIC8vIG92ZXJyaWRlIHRoZSBpbnB1dHMgZm9yIG5vZGVzIGNvbnN1bWluZyB0aGlzIG5vZGUncyBvdXRwdXQgd2l0aCB0aGUgaW5wdXQgdG8gdGhpcyBub2RlXG4gICAgaWYgKG5vZGVzQ29uc3VtaW5nT3V0cHV0ICYmIG5vZGVzQ29uc3VtaW5nT3V0cHV0Lmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAoY29uc3Qgbm9kZUluZGV4IG9mIG5vZGVzQ29uc3VtaW5nT3V0cHV0KSB7XG4gICAgICAgIGNvbnN0IHJlcGxhY2VJbmRleCA9IHRoaXMuX25vZGVzW25vZGVJbmRleF0uaW5wdXRzLmluZGV4T2Yob3V0cHV0VmFsdWVJbmRleCk7XG4gICAgICAgIC8vIHNob3VsZCBub3QgaGFwcGVuXG4gICAgICAgIGlmIChyZXBsYWNlSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIE5vZGUgb2JqZWN0IGRvZXNuJ3QgaGF2ZSB0aGUgb3V0cHV0IFZhbHVlIGluIGl0J3MgJ2lucHV0cycgcHJvcGVydHkgXCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX25vZGVzW25vZGVJbmRleF0uaW5wdXRzW3JlcGxhY2VJbmRleF0gPSBpbnB1dFZhbHVlSW5kZXg7XG4gICAgICAgIHRoaXMuX2FsbERhdGFbaW5wdXRWYWx1ZUluZGV4XS50by5wdXNoKG5vZGVJbmRleCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmVtb3ZlQWxsRHJvcG91dE5vZGVzKCkge1xuICAgIGxldCBub2RlSW5kZXggPSAwO1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9ub2Rlcykge1xuICAgICAgLy8gd2VlZCBvdXQgJ0Ryb3BvdXQnIG5vZGVzIHNvIHRoYXQgbm8gdGltZSBpcyB3YXN0ZWQgaW4gZXhlY3V0aW9uXG4gICAgICBpZiAobm9kZS5vcFR5cGUgPT09ICdEcm9wb3V0Jykge1xuICAgICAgICAvLyB0aGUgbm9kZSBzaG91bGQgaGF2ZSBleGFjdGx5IDEgaW5wdXQgYW5kIDEgb3IgMiBvdXRwdXRzXG4gICAgICAgIGlmIChub2RlLmlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Ryb3BvdXQgbm9kZXMgc2hvdWxkIG9ubHkgY29udGFpbiBvbmUgaW5wdXQuICcpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChub2RlLm91dHB1dHMubGVuZ3RoICE9PSAxICYmIG5vZGUub3V0cHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Ryb3BvdXQgbm9kZXMgc2hvdWxkIGNvbnRhaW4gZWl0aGVyIDEgb3IgMiBvdXRwdXQocyknKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB0aGUgc2Vjb25kIG91dHB1dCBzaG91bGQgbm90IGJlIHJlZmVyZW5jZWQgYnkgYW55IG90aGVyIG5vZGVcbiAgICAgICAgaWYgKG5vZGUub3V0cHV0cy5sZW5ndGggPT09IDIgJiYgdGhpcy5fYWxsRGF0YVtub2RlLm91dHB1dHNbMV1dLl90by5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEcm9wb3V0IG5vZGVzJ3Mgc2Vjb25kIG91dHB1dCBzaG91bGQgbm90IGJlIHJlZmVyZW5jZWQgYnkgb3RoZXIgbm9kZXNcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZWxldGVOb2RlKG5vZGVJbmRleCk7XG4gICAgICB9XG4gICAgICBub2RlSW5kZXgrKztcbiAgICB9XG4gIH1cblxuICByZW1vdmVBbGxJZGVudGl0eU5vZGVzKCkge1xuICAgIGxldCBub2RlSW5kZXggPSAwO1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9ub2Rlcykge1xuICAgICAgLy8gd2VlZCBvdXQgJ0lkZW50aXR5JyBub2RlcyBzbyB0aGF0IG5vIHRpbWUgaXMgd2FzdGVkIGluIGV4ZWN1dGlvblxuICAgICAgaWYgKG5vZGUub3BUeXBlID09PSAnSWRlbnRpdHknKSB7XG4gICAgICAgIHRoaXMuZGVsZXRlTm9kZShub2RlSW5kZXgpO1xuICAgICAgfVxuICAgICAgbm9kZUluZGV4Kys7XG4gICAgfVxuICB9XG5cbiAgaXNBY3RpdmF0aW9uKG46IE5vZGUpOiBib29sZWFuIHtcbiAgICBzd2l0Y2ggKG4ub3BUeXBlKSB7XG4gICAgICAvLyBUT0RPOiBhZGQgb3RoZXIgYWN0aXZhdGlvbiBtZXRob2RzXG4gICAgICBjYXNlICdSZWx1JzpcbiAgICAgIGNhc2UgJ1NpZ21vaWQnOlxuICAgICAgY2FzZSAnQ2xpcCc6XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGZ1c2VDb252QWN0aXZhdGlvbk5vZGVzKCkge1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9ub2Rlcykge1xuICAgICAgaWYgKG5vZGUub3BUeXBlID09PSAnQ29udicpIHtcbiAgICAgICAgY29uc3QgbmV4dCA9IHRoaXMuX2FsbERhdGFbbm9kZS5vdXRwdXRzWzBdXS5fdG87XG4gICAgICAgIGlmIChuZXh0Lmxlbmd0aCA9PT0gMSAmJiB0aGlzLmlzQWN0aXZhdGlvbih0aGlzLl9ub2Rlc1tuZXh0WzBdXSkpIHtcbiAgICAgICAgICBjb25zdCBjaGlsZCA9IHRoaXMuX25vZGVzW25leHRbMF1dO1xuICAgICAgICAgIGlmIChjaGlsZC5vcFR5cGUgPT09ICdDbGlwJykge1xuICAgICAgICAgICAgaWYgKGNoaWxkLmlucHV0cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBub2RlLmF0dHJpYnV0ZXMuc2V0KCdhY3RpdmF0aW9uX3BhcmFtcycsICdmbG9hdHMnLCBbXG4gICAgICAgICAgICAgICAgICBjaGlsZC5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtaW4nKSxcbiAgICAgICAgICAgICAgICAgIGNoaWxkLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ21heCcpLFxuICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgICBub2RlLmF0dHJpYnV0ZXMuc2V0KCdhY3RpdmF0aW9uX3BhcmFtcycsICdmbG9hdHMnLCBbTUlOX0NMSVAsIE1BWF9DTElQXSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgIGNoaWxkLmlucHV0cy5sZW5ndGggPj0gMyAmJlxuICAgICAgICAgICAgICB0aGlzLl9hbGxEYXRhW2NoaWxkLmlucHV0c1sxXV0udGVuc29yICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgdGhpcy5fYWxsRGF0YVtjaGlsZC5pbnB1dHNbMl1dLnRlbnNvciAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgbm9kZS5hdHRyaWJ1dGVzLnNldCgnYWN0aXZhdGlvbl9wYXJhbXMnLCAnZmxvYXRzJywgW1xuICAgICAgICAgICAgICAgIHRoaXMuX2FsbERhdGFbY2hpbGQuaW5wdXRzWzFdXS50ZW5zb3IhLmZsb2F0RGF0YVswXSxcbiAgICAgICAgICAgICAgICB0aGlzLl9hbGxEYXRhW2NoaWxkLmlucHV0c1syXV0udGVuc29yIS5mbG9hdERhdGFbMF0sXG4gICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gU2tpcCBmdXNpb24gd2l0aCBjbGlwIG5vZGUgc2luY2UgY2xpcCBtaW4gYW5kIGNsaXAgbWF4IGFyZSBub3QgY29taW5nIGZyb20gaW5pdGlhbGl6ZXJcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIG5vZGUuYXR0cmlidXRlcy5zZXQoJ2FjdGl2YXRpb24nLCAnc3RyaW5nJywgY2hpbGQub3BUeXBlKTtcbiAgICAgICAgICB0aGlzLmRlbGV0ZU5vZGUobmV4dFswXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BTZXQgfSBmcm9tICcuL29wc2V0JztcbmltcG9ydCAqIGFzIG9ydEZicyBmcm9tICcuL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQgeyBvbm54IH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHsgTG9uZ1V0aWwgfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgY2xhc3MgTW9kZWwge1xuICAvLyBlbXB0eSBtb2RlbFxuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgbG9hZChidWY6IFVpbnQ4QXJyYXksIGdyYXBoSW5pdGlhbGl6ZXI/OiBHcmFwaC5Jbml0aWFsaXplciwgaXNPcnRGb3JtYXQ/OiBib29sZWFuKTogdm9pZCB7XG4gICAgbGV0IG9ubnhFcnJvcjogRXJyb3IgfCB1bmRlZmluZWQ7XG4gICAgaWYgKCFpc09ydEZvcm1hdCkge1xuICAgICAgLy8gaXNPcnRGb3JtYXQgPT09IGZhbHNlIHx8IGlzT3J0Rm9ybWF0ID09PSB1bmRlZmluZWRcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMubG9hZEZyb21Pbm54Rm9ybWF0KGJ1ZiwgZ3JhcGhJbml0aWFsaXplcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGlzT3J0Rm9ybWF0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIG9ubnhFcnJvciA9IGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMubG9hZEZyb21PcnRGb3JtYXQoYnVmLCBncmFwaEluaXRpYWxpemVyKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoaXNPcnRGb3JtYXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgICAgLy8gVHJpZWQgYm90aCBmb3JtYXRzIGFuZCBmYWlsZWQgKHdoZW4gaXNPcnRGb3JtYXQgPT09IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGxvYWQgbW9kZWwgYXMgT05OWCBmb3JtYXQ6ICR7b25ueEVycm9yfVxcbmFzIE9SVCBmb3JtYXQ6ICR7ZX1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGxvYWRGcm9tT25ueEZvcm1hdChidWY6IFVpbnQ4QXJyYXksIGdyYXBoSW5pdGlhbGl6ZXI/OiBHcmFwaC5Jbml0aWFsaXplcik6IHZvaWQge1xuICAgIGNvbnN0IG1vZGVsUHJvdG8gPSBvbm54Lk1vZGVsUHJvdG8uZGVjb2RlKGJ1Zik7XG4gICAgY29uc3QgaXJWZXJzaW9uID0gTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKG1vZGVsUHJvdG8uaXJWZXJzaW9uKTtcbiAgICBpZiAoaXJWZXJzaW9uIDwgMykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdvbmx5IHN1cHBvcnQgT05OWCBtb2RlbCB3aXRoIElSX1ZFUlNJT04+PTMnKTtcbiAgICB9XG5cbiAgICB0aGlzLl9vcHNldHMgPSBtb2RlbFByb3RvLm9wc2V0SW1wb3J0Lm1hcCgoaSkgPT4gKHtcbiAgICAgIGRvbWFpbjogaS5kb21haW4gYXMgc3RyaW5nLFxuICAgICAgdmVyc2lvbjogTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKGkudmVyc2lvbiEpLFxuICAgIH0pKTtcblxuICAgIHRoaXMuX2dyYXBoID0gR3JhcGguZnJvbShtb2RlbFByb3RvLmdyYXBoISwgZ3JhcGhJbml0aWFsaXplcik7XG4gIH1cblxuICBwcml2YXRlIGxvYWRGcm9tT3J0Rm9ybWF0KGJ1ZjogVWludDhBcnJheSwgZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKTogdm9pZCB7XG4gICAgY29uc3QgZmIgPSBuZXcgZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcihidWYpO1xuICAgIGNvbnN0IG9ydE1vZGVsID0gb3J0RmJzLkluZmVyZW5jZVNlc3Npb24uZ2V0Um9vdEFzSW5mZXJlbmNlU2Vzc2lvbihmYikubW9kZWwoKSE7XG4gICAgY29uc3QgaXJWZXJzaW9uID0gTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKG9ydE1vZGVsLmlyVmVyc2lvbigpKTtcbiAgICBpZiAoaXJWZXJzaW9uIDwgMykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdvbmx5IHN1cHBvcnQgT05OWCBtb2RlbCB3aXRoIElSX1ZFUlNJT04+PTMnKTtcbiAgICB9XG4gICAgdGhpcy5fb3BzZXRzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcnRNb2RlbC5vcHNldEltcG9ydExlbmd0aCgpOyBpKyspIHtcbiAgICAgIGNvbnN0IG9wc2V0SWQgPSBvcnRNb2RlbC5vcHNldEltcG9ydChpKSE7XG4gICAgICB0aGlzLl9vcHNldHMucHVzaCh7IGRvbWFpbjogb3BzZXRJZD8uZG9tYWluKCkgYXMgc3RyaW5nLCB2ZXJzaW9uOiBMb25nVXRpbC5sb25nVG9OdW1iZXIob3BzZXRJZC52ZXJzaW9uKCkhKSB9KTtcbiAgICB9XG5cbiAgICB0aGlzLl9ncmFwaCA9IEdyYXBoLmZyb20ob3J0TW9kZWwuZ3JhcGgoKSEsIGdyYXBoSW5pdGlhbGl6ZXIpO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ3JhcGg6IEdyYXBoO1xuICBnZXQgZ3JhcGgoKTogR3JhcGgge1xuICAgIHJldHVybiB0aGlzLl9ncmFwaDtcbiAgfVxuXG4gIHByaXZhdGUgX29wc2V0czogT3BTZXRbXTtcbiAgZ2V0IG9wc2V0cygpOiByZWFkb25seSBPcFNldFtdIHtcbiAgICByZXR1cm4gdGhpcy5fb3BzZXRzO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IHJlc29sdmVCYWNrZW5kLCBTZXNzaW9uSGFuZGxlclR5cGUgfSBmcm9tICcuL2JhY2tlbmQnO1xuaW1wb3J0IHsgRXhlY3V0aW9uUGxhbiB9IGZyb20gJy4vZXhlY3V0aW9uLXBsYW4nO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7IFByb2ZpbGVyIH0gZnJvbSAnLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSAnLi9tb2RlbCc7XG5pbXBvcnQgeyBPcGVyYXRvciB9IGZyb20gJy4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yJztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIFNlc3Npb24ge1xuICBleHBvcnQgaW50ZXJmYWNlIENvbmZpZyB7XG4gICAgYmFja2VuZEhpbnQ/OiBzdHJpbmc7XG4gICAgcHJvZmlsZXI/OiBQcm9maWxlci5Db25maWc7XG4gIH1cblxuICBleHBvcnQgaW50ZXJmYWNlIENvbnRleHQge1xuICAgIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj47XG4gICAgZ3JhcGhJbnB1dFR5cGVzPzogVGVuc29yLkRhdGFUeXBlW107XG4gICAgZ3JhcGhJbnB1dERpbXM/OiBBcnJheTxyZWFkb25seSBudW1iZXJbXT47XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNlc3Npb24ge1xuICBjb25zdHJ1Y3Rvcihjb25maWc6IFNlc3Npb24uQ29uZmlnID0ge30pIHtcbiAgICB0aGlzLl9pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgIHRoaXMuYmFja2VuZEhpbnQgPSBjb25maWcuYmFja2VuZEhpbnQ7XG4gICAgdGhpcy5wcm9maWxlciA9IFByb2ZpbGVyLmNyZWF0ZShjb25maWcucHJvZmlsZXIpO1xuICAgIHRoaXMuY29udGV4dCA9IHsgcHJvZmlsZXI6IHRoaXMucHJvZmlsZXIsIGdyYXBoSW5wdXRUeXBlczogW10sIGdyYXBoSW5wdXREaW1zOiBbXSB9O1xuICB9XG5cbiAgZ2V0IGlucHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9tb2RlbC5ncmFwaC5nZXRJbnB1dE5hbWVzKCk7XG4gIH1cbiAgZ2V0IG91dHB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0T3V0cHV0TmFtZXMoKTtcbiAgfVxuXG4gIHN0YXJ0UHJvZmlsaW5nKCkge1xuICAgIHRoaXMucHJvZmlsZXIuc3RhcnQoKTtcbiAgfVxuXG4gIGVuZFByb2ZpbGluZygpIHtcbiAgICB0aGlzLnByb2ZpbGVyLnN0b3AoKTtcbiAgfVxuXG4gIGFzeW5jIGxvYWRNb2RlbCh1cmk6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gIGFzeW5jIGxvYWRNb2RlbChidWZmZXI6IEFycmF5QnVmZmVyLCBieXRlT2Zmc2V0PzogbnVtYmVyLCBsZW5ndGg/OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+O1xuICBhc3luYyBsb2FkTW9kZWwoYnVmZmVyOiBVaW50OEFycmF5KTogUHJvbWlzZTx2b2lkPjtcbiAgYXN5bmMgbG9hZE1vZGVsKGFyZzogc3RyaW5nIHwgQXJyYXlCdWZmZXIgfCBVaW50OEFycmF5LCBieXRlT2Zmc2V0PzogbnVtYmVyLCBsZW5ndGg/OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ1Nlc3Npb24ubG9hZE1vZGVsJywgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gcmVzb2x2ZSBiYWNrZW5kIGFuZCBzZXNzaW9uIGhhbmRsZXJcbiAgICAgIGNvbnN0IGJhY2tlbmQgPSBhd2FpdCByZXNvbHZlQmFja2VuZCh0aGlzLmJhY2tlbmRIaW50KTtcbiAgICAgIHRoaXMuc2Vzc2lvbkhhbmRsZXIgPSBiYWNrZW5kLmNyZWF0ZVNlc3Npb25IYW5kbGVyKHRoaXMuY29udGV4dCk7XG5cbiAgICAgIHRoaXMuX21vZGVsID0gbmV3IE1vZGVsKCk7XG4gICAgICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc3QgaXNPcnRGb3JtYXQgPSBhcmcuZW5kc1dpdGgoJy5vcnQnKTtcbiAgICAgICAgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb25zICYmIHByb2Nlc3MudmVyc2lvbnMubm9kZSkge1xuICAgICAgICAgIC8vIG5vZGVcbiAgICAgICAgICBjb25zdCB7IHJlYWRGaWxlIH0gPSByZXF1aXJlKCdub2RlOmZzL3Byb21pc2VzJyk7XG4gICAgICAgICAgY29uc3QgYnVmID0gYXdhaXQgcmVhZEZpbGUoYXJnKTtcbiAgICAgICAgICB0aGlzLmluaXRpYWxpemUoYnVmLCBpc09ydEZvcm1hdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gYnJvd3NlclxuICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYXJnKTtcbiAgICAgICAgICBjb25zdCBidWYgPSBhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpO1xuICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZShuZXcgVWludDhBcnJheShidWYpLCBpc09ydEZvcm1hdCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIUFycmF5QnVmZmVyLmlzVmlldyhhcmcpKSB7XG4gICAgICAgIC8vIGxvYWQgbW9kZWwgZnJvbSBBcnJheUJ1ZmZlclxuICAgICAgICBjb25zdCBhcnIgPSBuZXcgVWludDhBcnJheShhcmcsIGJ5dGVPZmZzZXQgfHwgMCwgbGVuZ3RoIHx8IGFyZy5ieXRlTGVuZ3RoKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplKGFycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBsb2FkIG1vZGVsIGZyb20gVWludDhhcnJheVxuICAgICAgICB0aGlzLmluaXRpYWxpemUoYXJnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZShtb2RlbFByb3RvQmxvYjogVWludDhBcnJheSwgaXNPcnRGb3JtYXQ/OiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FscmVhZHkgaW5pdGlhbGl6ZWQnKTtcbiAgICB9XG5cbiAgICB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ1Nlc3Npb24uaW5pdGlhbGl6ZScsICgpID0+IHtcbiAgICAgIC8vIGxvYWQgZ3JhcGhcbiAgICAgIGNvbnN0IGdyYXBoSW5pdGlhbGl6ZXIgPSB0aGlzLnNlc3Npb25IYW5kbGVyLnRyYW5zZm9ybUdyYXBoXG4gICAgICAgID8gKHRoaXMuc2Vzc2lvbkhhbmRsZXIgYXMgR3JhcGguSW5pdGlhbGl6ZXIpXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgdGhpcy5fbW9kZWwubG9hZChtb2RlbFByb3RvQmxvYiwgZ3JhcGhJbml0aWFsaXplciwgaXNPcnRGb3JtYXQpO1xuXG4gICAgICAvLyBncmFwaCBpcyBjb21wbGV0ZWx5IGluaXRpYWx6aWVkIGF0IHRoaXMgc3RhZ2UgLCBsZXQgdGhlIGludGVyZXN0ZWQgaGFuZGxlcnMga25vd1xuICAgICAgaWYgKHRoaXMuc2Vzc2lvbkhhbmRsZXIub25HcmFwaEluaXRpYWxpemVkKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbkhhbmRsZXIub25HcmFwaEluaXRpYWxpemVkKHRoaXMuX21vZGVsLmdyYXBoKTtcbiAgICAgIH1cbiAgICAgIC8vIGluaXRpYWxpemUgZWFjaCBvcGVyYXRvciBpbiB0aGUgZ3JhcGhcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZU9wcyh0aGlzLl9tb2RlbC5ncmFwaCk7XG5cbiAgICAgIC8vIGluc3RhbnRpYXRlIGFuIEV4ZWN1dGlvblBsYW4gb2JqZWN0IHRvIGJlIHVzZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0XG4gICAgICB0aGlzLl9leGVjdXRpb25QbGFuID0gbmV3IEV4ZWN1dGlvblBsYW4odGhpcy5fbW9kZWwuZ3JhcGgsIHRoaXMuX29wcywgdGhpcy5wcm9maWxlcik7XG4gICAgfSk7XG5cbiAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7XG4gIH1cblxuICBhc3luYyBydW4oaW5wdXRzOiBNYXA8c3RyaW5nLCBUZW5zb3I+IHwgVGVuc29yW10pOiBQcm9taXNlPE1hcDxzdHJpbmcsIFRlbnNvcj4+IHtcbiAgICBpZiAoIXRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Nlc3Npb24gbm90IGluaXRpYWxpemVkIHlldCcpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ1Nlc3Npb24ucnVuJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgaW5wdXRUZW5zb3JzID0gdGhpcy5ub3JtYWxpemVBbmRWYWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gICAgICBjb25zdCBvdXRwdXRUZW5zb3JzID0gYXdhaXQgdGhpcy5fZXhlY3V0aW9uUGxhbi5leGVjdXRlKHRoaXMuc2Vzc2lvbkhhbmRsZXIsIGlucHV0VGVuc29ycyk7XG5cbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZU91dHB1dChvdXRwdXRUZW5zb3JzKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbm9ybWFsaXplQW5kVmFsaWRhdGVJbnB1dHMoaW5wdXRzOiBNYXA8c3RyaW5nLCBUZW5zb3I+IHwgVGVuc29yW10pOiBUZW5zb3JbXSB7XG4gICAgY29uc3QgbW9kZWxJbnB1dE5hbWVzID0gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0SW5wdXROYW1lcygpO1xuXG4gICAgLy8gbm9ybWFsaXplIGlucHV0c1xuICAgIC8vIGlucHV0czogVGVuc29yW11cbiAgICBpZiAoQXJyYXkuaXNBcnJheShpbnB1dHMpKSB7XG4gICAgICBpZiAoaW5wdXRzLmxlbmd0aCAhPT0gbW9kZWxJbnB1dE5hbWVzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGluY29ycmVjdCBpbnB1dCBhcnJheSBsZW5ndGg6IGV4cGVjdGVkICR7bW9kZWxJbnB1dE5hbWVzLmxlbmd0aH0gYnV0IGdvdCAke2lucHV0cy5sZW5ndGh9YCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGNvbnZlcnQgbWFwIHRvIGFycmF5XG4gICAgLy8gaW5wdXRzOiBNYXA8c3RyaW5nLCBUZW5zb3I+XG4gICAgZWxzZSB7XG4gICAgICBpZiAoaW5wdXRzLnNpemUgIT09IG1vZGVsSW5wdXROYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbmNvcnJlY3QgaW5wdXQgbWFwIHNpemU6IGV4cGVjdGVkICR7bW9kZWxJbnB1dE5hbWVzLmxlbmd0aH0gYnV0IGdvdCAke2lucHV0cy5zaXplfWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzb3J0ZWRJbnB1dHMgPSBuZXcgQXJyYXk8VGVuc29yPihpbnB1dHMuc2l6ZSk7XG4gICAgICBsZXQgc29ydGVkSW5wdXRzSW5kZXggPSAwO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtb2RlbElucHV0TmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgY29uc3QgdGVuc29yID0gaW5wdXRzLmdldChtb2RlbElucHV0TmFtZXNbaV0pO1xuICAgICAgICBpZiAoIXRlbnNvcikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBpbnB1dCB0ZW5zb3IgZm9yOiAnJHtuYW1lfSdgKTtcbiAgICAgICAgfVxuICAgICAgICBzb3J0ZWRJbnB1dHNbc29ydGVkSW5wdXRzSW5kZXgrK10gPSB0ZW5zb3I7XG4gICAgICB9XG5cbiAgICAgIGlucHV0cyA9IHNvcnRlZElucHV0cztcbiAgICB9XG5cbiAgICAvLyB2YWxpZGF0ZSBkaW1zIHJlcXVpcmVtZW50c1xuICAgIC8vIEZpcnN0IHNlc3Npb24gcnVuIC0gZ3JhcGggaW5wdXQgZGF0YSBpcyBub3QgY2FjaGVkIGZvciB0aGUgc2Vzc2lvblxuICAgIGlmIChcbiAgICAgICF0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dFR5cGVzIHx8XG4gICAgICB0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dFR5cGVzLmxlbmd0aCA9PT0gMCB8fFxuICAgICAgIXRoaXMuY29udGV4dC5ncmFwaElucHV0RGltcyB8fFxuICAgICAgdGhpcy5jb250ZXh0LmdyYXBoSW5wdXREaW1zLmxlbmd0aCA9PT0gMFxuICAgICkge1xuICAgICAgY29uc3QgbW9kZWxJbnB1dEluZGljZXMgPSB0aGlzLl9tb2RlbC5ncmFwaC5nZXRJbnB1dEluZGljZXMoKTtcbiAgICAgIGNvbnN0IG1vZGVsVmFsdWVzID0gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0VmFsdWVzKCk7XG5cbiAgICAgIGNvbnN0IGdyYXBoSW5wdXREaW1zID0gbmV3IEFycmF5PHJlYWRvbmx5IG51bWJlcltdPihtb2RlbElucHV0SW5kaWNlcy5sZW5ndGgpO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1vZGVsSW5wdXRJbmRpY2VzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGNvbnN0IGdyYXBoSW5wdXQgPSBtb2RlbFZhbHVlc1ttb2RlbElucHV0SW5kaWNlc1tpXV07XG4gICAgICAgIGdyYXBoSW5wdXREaW1zW2ldID0gZ3JhcGhJbnB1dC50eXBlIS5zaGFwZS5kaW1zO1xuXG4gICAgICAgIC8vIGNhY2hlZCBmb3Igc2Vjb25kIGFuZCBzdWJzZXF1ZW50IHJ1bnMuXG4gICAgICAgIC8vIFNvbWUgcGFydHMgb2YgdGhlIGZyYW1ld29yayB3b3JrcyBvbiB0aGUgYXNzdW1wdGlvbiB0aGF0IHRoZSBncmFwaCBhbmQgdHlwZXMgYW5kIHNoYXBlcyBhcmUgc3RhdGljXG4gICAgICAgIHRoaXMuY29udGV4dC5ncmFwaElucHV0VHlwZXMhLnB1c2goZ3JhcGhJbnB1dC50eXBlIS50ZW5zb3JUeXBlKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LmdyYXBoSW5wdXREaW1zIS5wdXNoKGlucHV0c1tpXS5kaW1zKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy52YWxpZGF0ZUlucHV0VGVuc29yRGltcyhncmFwaElucHV0RGltcywgaW5wdXRzLCB0cnVlKTtcbiAgICB9XG5cbiAgICAvLyBTZWNvbmQgYW5kIHN1YnNlcXVlbnQgc2Vzc2lvbiBydW5zIC0gZ3JhcGggaW5wdXQgZGF0YSBpcyBjYWNoZWQgZm9yIHRoZSBzZXNzaW9uXG4gICAgZWxzZSB7XG4gICAgICB0aGlzLnZhbGlkYXRlSW5wdXRUZW5zb3JEaW1zKHRoaXMuY29udGV4dC5ncmFwaElucHV0RGltcywgaW5wdXRzLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgLy8gdmFsaWRhdGUgdHlwZXMgcmVxdWlyZW1lbnRcbiAgICB0aGlzLnZhbGlkYXRlSW5wdXRUZW5zb3JUeXBlcyh0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dFR5cGVzISwgaW5wdXRzKTtcblxuICAgIHJldHVybiBpbnB1dHM7XG4gIH1cblxuICBwcml2YXRlIHZhbGlkYXRlSW5wdXRUZW5zb3JUeXBlcyhncmFwaElucHV0VHlwZXM6IFRlbnNvci5EYXRhVHlwZVtdLCBnaXZlbklucHV0czogVGVuc29yW10pIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdpdmVuSW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSBncmFwaElucHV0VHlwZXNbaV07XG4gICAgICBjb25zdCBhY3R1YWxUeXBlID0gZ2l2ZW5JbnB1dHNbaV0udHlwZTtcbiAgICAgIGlmIChleHBlY3RlZFR5cGUgIT09IGFjdHVhbFR5cGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dCB0ZW5zb3JbJHtpfV0gY2hlY2sgZmFpbGVkOiBleHBlY3RlZCB0eXBlICcke2V4cGVjdGVkVHlwZX0nIGJ1dCBnb3QgJHthY3R1YWxUeXBlfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVJbnB1dFRlbnNvckRpbXMoXG4gICAgZ3JhcGhJbnB1dERpbXM6IEFycmF5PHJlYWRvbmx5IG51bWJlcltdPixcbiAgICBnaXZlbklucHV0czogVGVuc29yW10sXG4gICAgbm9uZURpbVN1cHBvcnRlZDogYm9vbGVhbixcbiAgKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBnaXZlbklucHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZXhwZWN0ZWREaW1zID0gZ3JhcGhJbnB1dERpbXNbaV07XG4gICAgICBjb25zdCBhY3R1YWxEaW1zID0gZ2l2ZW5JbnB1dHNbaV0uZGltcztcbiAgICAgIGlmICghdGhpcy5jb21wYXJlVGVuc29yRGltcyhleHBlY3RlZERpbXMsIGFjdHVhbERpbXMsIG5vbmVEaW1TdXBwb3J0ZWQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgaW5wdXQgdGVuc29yWyR7aX1dIGNoZWNrIGZhaWxlZDogZXhwZWN0ZWQgc2hhcGUgJ1ske2V4cGVjdGVkRGltcy5qb2luKCcsJyl9XScgYnV0IGdvdCBbJHthY3R1YWxEaW1zLmpvaW4oXG4gICAgICAgICAgICAnLCcsXG4gICAgICAgICAgKX1dYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNvbXBhcmVUZW5zb3JEaW1zKFxuICAgIGV4cGVjdGVkRGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgYWN0dWFsRGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgbm9uZURpbVN1cHBvcnRlZDogYm9vbGVhbixcbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKGV4cGVjdGVkRGltcy5sZW5ndGggIT09IGFjdHVhbERpbXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBleHBlY3RlZERpbXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmIChleHBlY3RlZERpbXNbaV0gIT09IGFjdHVhbERpbXNbaV0gJiYgKCFub25lRGltU3VwcG9ydGVkIHx8IGV4cGVjdGVkRGltc1tpXSAhPT0gMCkpIHtcbiAgICAgICAgLy8gZGF0YSBzaGFwZSBtaXNtYXRjaCBBTkQgbm90IGEgJ05vbmUnIGRpbWVuc2lvbi5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVPdXRwdXQob3V0cHV0VGVuc29yczogVGVuc29yW10pOiBNYXA8c3RyaW5nLCBUZW5zb3I+IHtcbiAgICBjb25zdCBtb2RlbE91dHB1dE5hbWVzID0gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0T3V0cHV0TmFtZXMoKTtcbiAgICBpZiAob3V0cHV0VGVuc29ycy5sZW5ndGggIT09IG1vZGVsT3V0cHV0TmFtZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGVkIG51bWJlciBvZiBvdXRwdXRzIGRvIG5vdCBtYXRjaCBudW1iZXIgb2YgZ2VuZXJhdGVkIG91dHB1dHMnKTtcbiAgICB9XG5cbiAgICBjb25zdCBvdXRwdXQgPSBuZXcgTWFwPHN0cmluZywgVGVuc29yPigpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbW9kZWxPdXRwdXROYW1lcy5sZW5ndGg7ICsraSkge1xuICAgICAgb3V0cHV0LnNldChtb2RlbE91dHB1dE5hbWVzW2ldLCBvdXRwdXRUZW5zb3JzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplT3BzKGdyYXBoOiBHcmFwaCk6IHZvaWQge1xuICAgIGNvbnN0IG5vZGVzID0gZ3JhcGguZ2V0Tm9kZXMoKTtcbiAgICB0aGlzLl9vcHMgPSBuZXcgQXJyYXkobm9kZXMubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuX29wc1tpXSA9IHRoaXMuc2Vzc2lvbkhhbmRsZXIucmVzb2x2ZShub2Rlc1tpXSwgdGhpcy5fbW9kZWwub3BzZXRzLCBncmFwaCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfbW9kZWw6IE1vZGVsO1xuICBwcml2YXRlIF9pbml0aWFsaXplZDogYm9vbGVhbjtcblxuICBwcml2YXRlIF9vcHM6IE9wZXJhdG9yW107XG4gIHByaXZhdGUgX2V4ZWN1dGlvblBsYW46IEV4ZWN1dGlvblBsYW47XG5cbiAgcHJpdmF0ZSBiYWNrZW5kSGludD86IHN0cmluZztcblxuICBwcml2YXRlIHNlc3Npb25IYW5kbGVyOiBTZXNzaW9uSGFuZGxlclR5cGU7XG4gIHByaXZhdGUgY29udGV4dDogU2Vzc2lvbi5Db250ZXh0O1xuICBwcml2YXRlIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj47XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEluZmVyZW5jZVNlc3Npb24sIEluZmVyZW5jZVNlc3Npb25IYW5kbGVyLCBTZXNzaW9uSGFuZGxlciwgVGVuc29yIH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vc2Vzc2lvbic7XG5pbXBvcnQgeyBUZW5zb3IgYXMgT25ueGpzVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuXG5leHBvcnQgY2xhc3MgT25ueGpzU2Vzc2lvbkhhbmRsZXIgaW1wbGVtZW50cyBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbikge1xuICAgIHRoaXMuaW5wdXROYW1lcyA9IHRoaXMuc2Vzc2lvbi5pbnB1dE5hbWVzO1xuICAgIHRoaXMub3V0cHV0TmFtZXMgPSB0aGlzLnNlc3Npb24ub3V0cHV0TmFtZXM7XG4gIH1cblxuICBnZXQgaW5wdXRNZXRhZGF0YSgpOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHZXR0aW5nIG1vZGVsIG1ldGFkYXRhIGlzIG5vdCBzdXBwb3J0ZWQgaW4gd2ViZ2wgYmFja2VuZC4nKTtcbiAgfVxuXG4gIGdldCBvdXRwdXRNZXRhZGF0YSgpOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHZXR0aW5nIG1vZGVsIG1ldGFkYXRhIGlzIG5vdCBzdXBwb3J0ZWQgaW4gd2ViZ2wgYmFja2VuZC4nKTtcbiAgfVxuXG4gIGFzeW5jIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPiB7fVxuICBpbnB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcbiAgb3V0cHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICBhc3luYyBydW4oXG4gICAgZmVlZHM6IFNlc3Npb25IYW5kbGVyLkZlZWRzVHlwZSxcbiAgICBfZmV0Y2hlczogU2Vzc2lvbkhhbmRsZXIuRmV0Y2hlc1R5cGUsXG4gICAgX29wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxTZXNzaW9uSGFuZGxlci5SZXR1cm5UeXBlPiB7XG4gICAgY29uc3QgaW5wdXRNYXAgPSBuZXcgTWFwPHN0cmluZywgT25ueGpzVGVuc29yPigpO1xuICAgIGZvciAoY29uc3QgbmFtZSBpbiBmZWVkcykge1xuICAgICAgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKGZlZWRzLCBuYW1lKSkge1xuICAgICAgICBjb25zdCBmZWVkID0gZmVlZHNbbmFtZV07XG4gICAgICAgIGlucHV0TWFwLnNldChcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIG5ldyBPbm54anNUZW5zb3IoXG4gICAgICAgICAgICBmZWVkLmRpbXMsXG4gICAgICAgICAgICBmZWVkLnR5cGUgYXMgT25ueGpzVGVuc29yLkRhdGFUeXBlLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgZmVlZC5kYXRhIGFzIE9ubnhqc1RlbnNvci5OdW1iZXJUeXBlLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IG91dHB1dE1hcCA9IGF3YWl0IHRoaXMuc2Vzc2lvbi5ydW4oaW5wdXRNYXApO1xuICAgIGNvbnN0IG91dHB1dDogU2Vzc2lvbkhhbmRsZXIuUmV0dXJuVHlwZSA9IHt9O1xuICAgIG91dHB1dE1hcC5mb3JFYWNoKCh0ZW5zb3IsIG5hbWUpID0+IHtcbiAgICAgIG91dHB1dFtuYW1lXSA9IG5ldyBUZW5zb3IodGVuc29yLnR5cGUsIHRlbnNvci5kYXRhLCB0ZW5zb3IuZGltcyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfVxuICBzdGFydFByb2ZpbGluZygpOiB2b2lkIHtcbiAgICB0aGlzLnNlc3Npb24uc3RhcnRQcm9maWxpbmcoKTtcbiAgfVxuICBlbmRQcm9maWxpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5zZXNzaW9uLmVuZFByb2ZpbGluZygpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEJhY2tlbmQsIEluZmVyZW5jZVNlc3Npb24sIEluZmVyZW5jZVNlc3Npb25IYW5kbGVyIH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vb25ueGpzL3Nlc3Npb24nO1xuaW1wb3J0IHsgT25ueGpzU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuL29ubnhqcy9zZXNzaW9uLWhhbmRsZXItaW5mZXJlbmNlJztcblxuY2xhc3MgT25ueGpzQmFja2VuZCBpbXBsZW1lbnRzIEJhY2tlbmQge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gIGFzeW5jIGluaXQoKTogUHJvbWlzZTx2b2lkPiB7fVxuXG4gIGFzeW5jIGNyZWF0ZUluZmVyZW5jZVNlc3Npb25IYW5kbGVyKFxuICAgIHBhdGhPckJ1ZmZlcjogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcj4ge1xuICAgIC8vIE5PVEU6IFNlc3Npb24uQ29uZmlnKGZyb20gb25ueC5qcykgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zKGZyb21cbiAgICAvLyBvbm54cnVudGltZS1jb21tb24pLlxuICAgIC8vICAgICAgIEluIGZ1dHVyZSB3ZSBzaG91bGQgcmVtb3ZlIFNlc3Npb24uQ29uZmlnIGFuZCB1c2UgSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucy5cbiAgICAvLyAgICAgICBDdXJyZW50bHkgd2UgYWxsb3cgdGhpcyB0byBoYXBwZW4gdG8gbWFrZSB0ZXN0IHJ1bm5lciB3b3JrLlxuICAgIGNvbnN0IHNlc3Npb24gPSBuZXcgU2Vzc2lvbihvcHRpb25zIGFzIHVua25vd24gYXMgU2Vzc2lvbi5Db25maWcpO1xuXG4gICAgLy8gdHlwZXNjcmlwdCBjYW5ub3QgbWVyZ2UgbWV0aG9kIG92ZXJyaWRlIGNvcnJlY3RseSAoc28gZmFyIGluIDQuMi4zKS4gbmVlZCBpZi1lbHNlIHRvIGNhbGwgdGhlIG1ldGhvZC5cbiAgICBpZiAodHlwZW9mIHBhdGhPckJ1ZmZlciA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGF3YWl0IHNlc3Npb24ubG9hZE1vZGVsKHBhdGhPckJ1ZmZlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHNlc3Npb24ubG9hZE1vZGVsKHBhdGhPckJ1ZmZlcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBPbm54anNTZXNzaW9uSGFuZGxlcihzZXNzaW9uKTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgb25ueGpzQmFja2VuZCA9IG5ldyBPbm54anNCYWNrZW5kKCk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMgKi9cblxuLy8gV2UgdXNlIFwicmVxdWlyZVwiIGluc3RlYWQgb2YgXCJpbXBvcnRcIiBoZXJlIGJlY2F1c2UgaW1wb3J0IHN0YXRlbWVudCBtdXN0IGJlIHB1dCBpbiB0b3AgbGV2ZWwuIE91ciBjdXJyZW50IGNvZGUgZG9lc1xuLy8gbm90IGFsbG93IGJ1bmRsZXIgdG8gdHJlZS1zaGFraW5nIGNvZGUgYXMgZXhwZWN0ZWQgYmVjYXVzZSBzb21lIGNvZGVzIGFyZSB0cmVhdGVkIGFzIGhhdmluZyBzaWRlIGVmZmVjdHMuXG4vLyBTbyB3ZSBpbXBvcnQgY29kZSBpbnNpZGUgdGhlIGlmLWNsYXVzZSB0byBhbGxvdyBidW5kbGVyIHJlbW92ZSB0aGUgY29kZSBzYWZlbHkuXG5cbmV4cG9ydCAqIGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5pbXBvcnQgKiBhcyBvcnQgZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcbmV4cG9ydCBkZWZhdWx0IG9ydDtcblxuaW1wb3J0IHsgcmVnaXN0ZXJCYWNrZW5kLCBlbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4vdmVyc2lvbic7XG5cbmlmICghQlVJTERfREVGUy5ESVNBQkxFX1dFQkdMKSB7XG4gIGNvbnN0IG9ubnhqc0JhY2tlbmQgPSByZXF1aXJlKCcuL2JhY2tlbmQtb25ueGpzJykub25ueGpzQmFja2VuZDtcbiAgcmVnaXN0ZXJCYWNrZW5kKCd3ZWJnbCcsIG9ubnhqc0JhY2tlbmQsIC0xMCk7XG59XG5cbmlmICghQlVJTERfREVGUy5ESVNBQkxFX0pTRVAgJiYgIUJVSUxEX0RFRlMuRElTQUJMRV9XRUJHUFUpIHtcbiAgdGhyb3cgbmV3IEVycm9yKFxuICAgICdUaGUgY3VycmVudCBidWlsZCBpcyBzcGVjaWZpZWQgdG8gZW5hYmxlIGJvdGggSlNFUCBhbmQgV2ViR1BVIEVQLiBUaGlzIGlzIG5vdCBhIHZhbGlkIGNvbmZpZ3VyYXRpb24uICcgK1xuICAgICAgJ0pTRVAgYW5kIFdlYkdQVSBFUHMgY2Fubm90IGJlIGVuYWJsZWQgYXQgdGhlIHNhbWUgdGltZS4nLFxuICApO1xufVxuXG5pZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XRUJOTiAmJiBCVUlMRF9ERUZTLkRJU0FCTEVfSlNFUCAmJiBCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR1BVKSB7XG4gIHRocm93IG5ldyBFcnJvcihcbiAgICAnVGhlIGN1cnJlbnQgYnVpbGQgaXMgc3BlY2lmaWVkIHRvIGVuYWJsZSBXZWJOTiBFUCB3aXRob3V0IEpTRVAgb3IgV2ViR1BVIEVQLiBUaGlzIGlzIG5vdCBhIHZhbGlkIGNvbmZpZ3VyYXRpb24uICcgK1xuICAgICAgJ1dlYk5OIEVQIHJlcXVpcmVzIGVpdGhlciBKU0VQIG9yIFdlYkdQVSBFUCB0byBiZSBlbmFibGVkLicsXG4gICk7XG59XG5cbmlmICghQlVJTERfREVGUy5ESVNBQkxFX1dBU00pIHtcbiAgY29uc3Qgd2FzbUJhY2tlbmQgPSByZXF1aXJlKCcuL2JhY2tlbmQtd2FzbScpLndhc21CYWNrZW5kO1xuICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9KU0VQIHx8ICFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR1BVKSB7XG4gICAgcmVnaXN0ZXJCYWNrZW5kKCd3ZWJncHUnLCB3YXNtQmFja2VuZCwgNSk7XG4gIH1cbiAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCTk4pIHtcbiAgICByZWdpc3RlckJhY2tlbmQoJ3dlYm5uJywgd2FzbUJhY2tlbmQsIDUpO1xuICB9XG4gIHJlZ2lzdGVyQmFja2VuZCgnY3B1Jywgd2FzbUJhY2tlbmQsIDEwKTtcbiAgcmVnaXN0ZXJCYWNrZW5kKCd3YXNtJywgd2FzbUJhY2tlbmQsIDEwKTtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGVudi52ZXJzaW9ucywgJ3dlYicsIHsgdmFsdWU6IHZlcnNpb24sIGVudW1lcmFibGU6IHRydWUgfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8vIFRoaXMgZmlsZSBpcyBnZW5lcmF0ZWQgYnkgL2pzL3NjcmlwdHMvdXBkYXRlLXZlcnNpb24udHNcbi8vIERvIG5vdCBtb2RpZnkgZmlsZSBjb250ZW50IG1hbnVhbGx5LlxuXG5leHBvcnQgY29uc3QgdmVyc2lvbiA9ICcxLjI2LjAnO1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLElBZ0JNLFVBQ0EsMEJBWU8saUJBd0NQLGdDQXdDTztBQTdHYjs7O0FBZ0JBLElBQU0sV0FBcUMsb0JBQUksSUFBRztBQUNsRCxJQUFNLDJCQUFxQyxDQUFBO0FBWXBDLElBQU0sa0JBQWtCLENBQUNBLE9BQWNDLFVBQWtCLGFBQTBCO0FBQ3hGLFVBQUlBLFlBQVcsT0FBT0EsU0FBUSxTQUFTLGNBQWMsT0FBT0EsU0FBUSxrQ0FBa0MsWUFBWTtBQUNoSCxjQUFNLGlCQUFpQixTQUFTLElBQUlELEtBQUk7QUFDeEMsWUFBSSxtQkFBbUIsUUFBVztBQUNoQyxtQkFBUyxJQUFJQSxPQUFNLEVBQUUsU0FBQUMsVUFBUyxTQUFRLENBQUU7bUJBQy9CLGVBQWUsV0FBVyxVQUFVO0FBRTdDO21CQUNTLGVBQWUsYUFBYSxVQUFVO0FBQy9DLGNBQUksZUFBZSxZQUFZQSxVQUFTO0FBQ3RDLGtCQUFNLElBQUksTUFBTSw0QkFBNEJELEtBQUksb0JBQW9CLFFBQVEsRUFBRTs7O0FBSWxGLFlBQUksWUFBWSxHQUFHO0FBQ2pCLGdCQUFNLElBQUkseUJBQXlCLFFB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QUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFHO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FB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LFFBQU87QUFDYixRQUFNLE9BQU87QUFBQSxVQUNMQSxLQUFJO0FBQUE7QUFBQTtBQUFBLFNBR0xBLEtBQUk7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFPWCxTQUFPLEVBQUUsTUFBTSxNQUFBQSxPQUFNLHlCQUE4QjtBQUNyRDtBQUNPLFNBQVMsVUFBNkI7QUFDM0MsUUFBTUEsUUFBTztBQUNiLFFBQU0sT0FBTztBQUFBLFVBQ0xBLEtBQUk7QUFBQTtBQUFBO0FBQUEsU0FHTEEsS0FBSTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFTWCxTQUFPLEVBQUUsTUFBTSxNQUFBQSxPQUFNLHlCQUE4QjtBQUNyRDtBQUNPLFNBQVMsU0FBNEI7QUFDMUMsUUFBTUEsUUFBTztBQUNiLFFBQU0sT0FBTztBQUFBLFVBQ0xBLEtBQUk7QUFBQTtBQUFBO0FBQUEsU0FHTEEsS0FBSTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFTWCxTQUFPLEVBQUUsTUFBTSxNQUFBQSxPQUFNLHlCQUE4QjtBQUNyRDtBQUNPLFNBQVMsVUFBNkI7QUFDM0MsUUFBTUEsUUFBTztBQUNiLFFBQU0sT0FBTztBQUFBLFVBQ0xBLEtBQUk7QUFBQTtBQUFBO0FBQUEsU0FHTEEsS0FBSTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFTWCxTQUFPLEVBQUUsTUFBTSxNQUFBQSxPQUFNLHlCQUE4QjtBQUNyRDtBQUNPLFNBQVMsVUFBNkI7QUFDM0MsU0FBTyxrQkFBa0IsS0FBSztBQUNoQztBQUNPLFNBQVMsWUFBK0I7QUFDN0MsUUFBTUEsUUFBTztBQUNiLFFBQU0sT0FBTztBQUFBLFVBQ0xBLEtBQUk7QUFBQTtBQUFBO0FBQUEsU0FHTEEsS0FBSTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFTWCxTQUFPLEVBQUUsTUFBTSxNQUFBQSxPQUFNLHlCQUE4QjtBQUNyRDtBQUVBLFNBQVMsa0JBQWtCLE9BQWtD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QUFRLFVBQVUsWUFBWTtBQUFBLFFBQ3RDO0FBRUEsZUFBTyxJQUFJLHFCQUFxQixPQUFPO0FBQUEsTUFDekM7QUFBQSxJQUNGO0FBRU8sSUFBTSxnQkFBZ0IsSUFBSSxjQUFjO0FBQUE7QUFBQTs7O0FDeEIvQztBQUNBO0FBR0E7OztBQ1BPLElBQU1DLFdBQVU7OztBREt2QixJQUFPLGdCQUFRO0FBS2YsSUFBSSxNQUEyQjtBQUM3QixRQUFNQyxpQkFBZ0IsOERBQTRCO0FBQ2xELGtCQUFnQixTQUFTQSxnQkFBZSxHQUFHO0FBQzdDO0FBRUEsSUFBSSxPQUF3RDtBQUMxRCxRQUFNLElBQUk7QUFBQSxJQUNSO0FBQUEsRUFFRjtBQUNGO0FBRUEsSUFBSSxPQUFtRjtBQUNyRixRQUFNLElBQUk7QUFBQSxJQUNSO0FBQUEsRUFFRjtBQUNGO0FBRUEsSUFBSSxPQUEwQjtBQUM1QixRQUFNLGNBQWMsS0FBMEI7QUFDOUMsTUFBZ0MsT0FBNEI7QUFDMUQsb0JBQWdCLFVBQVUsYUFBYSxDQUFDO0FBQUEsRUFDMUM7QUFDQSxNQUFJLE9BQTJCO0FBQzdCLG9CQUFnQixTQUFTLGFBQWEsQ0FBQztBQUFBLEVBQ3pDO0FBQ0Esa0JBQWdCLE9BQU8sYUFBYSxFQUFFO0FBQ3RDLGtCQUFnQixRQUFRLGFBQWEsRUFBRTtBQUN6QztBQUVBLE9BQU8sZUFBZUMsS0FBSSxVQUFVLE9BQU8sRUFBRSxPQUFPQyxVQUFTLFlBQVksS0FBSyxDQUFDOyIsCiAgIm5hbWVzIjogWyJuYW1lIiwgImJhY2tlbmQiLCAiaSIsICJlbnYiLCAiY3JlYXRlQ2FudmFzIiwgIlRlbnNvciIsICJUZW5zb3IiLCAibmFtZSIsICJiYWNrZW5kIiwgIkluZmVyZW5jZVNlc3Npb24iLCAiSW5mZXJlbmNlU2Vzc2lvbiIsICJUZW5zb3IiLCAiZW52IiwgImxvZyIsICJlbnYiLCAibmFtZSIsICJ2ZXJzaW9uIiwgImV4cG9ydHMiLCAiR3VpZCIsICJjYWNoZSIsICJkaXYiLCAibG9nMiIsICJBcmdUeXBlIiwgImV4cG9ydHMiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgImV4cG9ydHMiLCAiRW5jb2RpbmciLCAiZXhwb3J0cyIsICJCeXRlQnVmZmVyIiwgImV4cG9ydHMiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgIm1vZCIsICJBcmdUeXBlQW5kSW5kZXgiLCAiZmxhdGJ1ZmZlcnMiLCAiQXR0cmlidXRlVHlwZSIsICJleHBvcnRzIiwgIk5vZGVUeXBlIiwgImV4cG9ydHMiLCAiZXhwb3J0cyIsICJtb2QiLCAiTm9kZSIsICJmbGF0YnVmZmVycyIsICJFZGdlRW5kIiwgImV4cG9ydHMiLCAiZXhwb3J0cyIsICJtb2QiLCAiTm9kZUVkZ2UiLCAiZmxhdGJ1ZmZlcnMiLCAiZXhwb3J0cyIsICJtb2QiLCAiZmxhdGJ1ZmZlcnMiLCAiTm9kZXNUb09wdGltaXplSW5kaWNlcyIsICJtb2QiLCAiZXhwb3J0cyIsICJSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkIiwgImZsYXRidWZmZXJzIiwgImV4cG9ydHMiLCAibW9kIiwgIlJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSIsICJmbGF0YnVmZmVycyIsICJleHBvcnRzIiwgIm1vZCIsICJSdW50aW1lT3B0aW1pemF0aW9ucyIsICJmbGF0YnVmZmVycyIsICJUZW5zb3JEYXRhVHlwZSIsICJleHBvcnRzIiwgImV4cG9ydHMiLCAibW9kIiwgIlRlbnNvciIsICJmbGF0YnVmZmVycyIsICJleHBvcnRzIiwgIm1vZCIsICJTcGFyc2VUZW5zb3IiLCAiZmxhdGJ1ZmZlcnMiLCAiZXhwb3J0cyIsICJtb2QiLCAiTWFwVHlwZSIsICJmbGF0YnVmZmVycyIsICJleHBvcnRzIiwgIm1vZCIsICJTZXF1ZW5jZVR5cGUiLCAiZmxhdGJ1ZmZlcnMiLCAiRGltZW5zaW9uVmFsdWVUeXBlIiwgImV4cG9ydHMiLCAiZXhwb3J0cyIsICJtb2QiLCAiRGltZW5zaW9uVmFsdWUiLCAiZmxhdGJ1ZmZlcnMiLCAiZXhwb3J0cyIsICJtb2QiLCAiRGltZW5zaW9uIiwgImZsYXRidWZmZXJzIiwgImV4cG9ydHMiLCAibW9kIiwgIlNoYXBlIiwgImZsYXRidWZmZXJzIiwgImV4cG9ydHMiLCAibW9kIiwgIlRlbnNvclR5cGVBbmRTaGFwZSIsICJmbGF0YnVmZmVycyIsICJUeXBlSW5mb1ZhbHVlIiwgImV4cG9ydHMiLCAiZXhwb3J0cyIsICJtb2QiLCAiVHlwZUluZm8iLCAiZmxhdGJ1ZmZlcnMiLCAiZXhwb3J0cyIsICJtb2QiLCAiVmFsdWVJbmZvIiwgImZsYXRidWZmZXJzIiwgImV4cG9ydHMiLCAibW9kIiwgImZsYXRidWZmZXJzIiwgIkdyYXBoIiwgImV4cG9ydHMiLCAibW9kIiwgImZsYXRidWZmZXJzIiwgIkF0dHJpYnV0ZSIsICJleHBvcnRzIiwgIm1vZCIsICJmbGF0YnVmZmVycyIsICJEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MiLCAiZXhwb3J0cyIsICJtb2QiLCAiZmxhdGJ1ZmZlcnMiLCAiRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2giLCAiZXhwb3J0cyIsICJtb2QiLCAiZmxhdGJ1ZmZlcnMiLCAiRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlIiwgIm1vZCIsICJleHBvcnRzIiwgIkRlcHJlY2F0ZWRTZXNzaW9uU3RhdGUiLCAiZmxhdGJ1ZmZlcnMiLCAiZXhwb3J0cyIsICJtb2QiLCAiS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSIsICJmbGF0YnVmZmVycyIsICJleHBvcnRzIiwgIm1vZCIsICJPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSIsICJmbGF0YnVmZmVycyIsICJleHBvcnRzIiwgIm1vZCIsICJLZXJuZWxUeXBlU3RyUmVzb2x2ZXIiLCAiZmxhdGJ1ZmZlcnMiLCAiZXhwb3J0cyIsICJtb2QiLCAiZmxhdGJ1ZmZlcnMiLCAiT3BlcmF0b3JTZXRJZCIsICJleHBvcnRzIiwgIm1vZCIsICJmbGF0YnVmZmVycyIsICJTdHJpbmdTdHJpbmdFbnRyeSIsICJleHBvcnRzIiwgIm1vZCIsICJmbGF0YnVmZmVycyIsICJNb2RlbCIsICJleHBvcnRzIiwgIm1vZCIsICJJbmZlcmVuY2VTZXNzaW9uIiwgImZsYXRidWZmZXJzIiwgImltcG9ydF90ZW5zb3IiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAicGFyYW1zIiwgIm9mZnNldCIsICJleHBvcnRzIiwgImkiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJzbGljZSIsICJzaXplIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImZyb21OdW1iZXIiLCAidG9OdW1iZXIiLCAiZXhwb3J0cyIsICJCdWZmZXIiLCAibmFtZSIsICJpIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImNyZWF0ZSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJjcmVhdGVfYXJyYXkiLCAiY3JlYXRlIiwgImJ1ZmZlciIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJzZWxmIiwgImVyciIsICJleHBvcnRzIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImV4cG9ydHMiLCAicmVxdWlyZV9taW5pbWFsIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgIm9ubngiLCAiRGltZW5zaW9uIiwgIlRlbnNvciIsICJNYXAiLCAiU3BhcnNlVGVuc29yIiwgImluaXRfdGVuc29yIiwgIlRlbnNvciIsICJzaGFwZSIsICJzcGxpdCIsICJpbXBvcnRfb25ueCIsICJUZW5zb3IiLCAiaW5pdF90ZW5zb3IiLCAiY2FjaGUiLCAidmVyc2lvbiIsICJuYW1lIiwgInNoYXBlIiwgInNoYXBlIiwgInNoYXBlIiwgImluaXRfdGVuc29yIiwgInNoYXBlIiwgIlRlbnNvciIsICJuYW1lIiwgIm5hbWUiLCAibmFtZSIsICJhZGQiLCAiYW5kIiwgIm9yIiwgInhvciIsICJnbHNsIiwgInNoYWRlclNvdXJjZSIsICJ2YWxpZGF0ZUlucHV0cyIsICJzaGlmdCIsICJ2YWxpZGF0ZUlucHV0cyIsICJuYW1lIiwgImxvZyIsICJub3QiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAibmFtZSIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJzaGFwZSIsICJ2YWxpZGF0ZUlucHV0cyIsICJzdW0iLCAidmFsaWRhdGVJbnB1dHMiLCAibmFtZSIsICJpbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAiZGltIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgImluaXRfdGVuc29yIiwgIlRlbnNvciIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJzcGxpdCIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0c1YxMyIsICJhZGQiLCAiYW5kIiwgImxvZyIsICJub3QiLCAib3IiLCAieG9yIiwgIm5hbWUiLCAic2hhcGUiLCAic2hhcGUiLCAibmFtZSIsICJzb3VyY2UiLCAicGFja2VkU2FtcGxlciIsICJ0ZXhOdW1SIiwgInRleE51bUMiLCAidHJhbnNwb3NlIiwgIm5hbWUiLCAic2hhcGUiLCAiaSIsICJuYW1lIiwgIm5hbWUiLCAiZW52IiwgIm5hbWUiLCAidGV4dHVyZSIsICJiYWNrZW5kIiwgInZlcnNpb24iLCAiZW52IiwgImVudiIsICJjYWNoZSIsICJiYWNrZW5kIiwgImluaXRfYmFja2VuZCIsICJvdXRwdXQiLCAiaW1wb3J0X29ubngiLCAiQXR0cmlidXRlIiwgImluaXRfdGVuc29yIiwgIlRlbnNvciIsICJ2YWx1ZSIsICJpbXBvcnRfb25ueCIsICJHcmFwaCIsICJOb2RlIiwgImluaXRfdGVuc29yIiwgIm5hbWUiLCAiQXR0cmlidXRlIiwgIlRlbnNvciIsICJzaGFwZSIsICJub2RlSW5kZXgiLCAiaW1wb3J0X29ubngiLCAiTW9kZWwiLCAiR3JhcGgiLCAiaW5pdF9iYWNrZW5kIiwgImJhY2tlbmQiLCAiTW9kZWwiLCAiaW5pdF90ZW5zb3IiLCAibmFtZSIsICJUZW5zb3IiLCAidmVyc2lvbiIsICJvbm54anNCYWNrZW5kIiwgImVudiIsICJ2ZXJzaW9uIl0KfQo=