diff --git "a/dist/ort.webgl.mjs" "b/dist/ort.webgl.mjs" new file mode 100755--- /dev/null +++ "b/dist/ort.webgl.mjs" @@ -0,0 +1,24126 @@ +/*! + * ONNX Runtime Web v1.23.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); + +// web/node_modules/onnxruntime-common/dist/esm/backend-impl.js +var backends, backendsSortedByPriority, registerBackend, tryResolveAndInitializeBackend, resolveBackendAndExecutionProviders; +var init_backend_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/backend-impl.js"() { + 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); + } + }) + ]; + }; + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/backend.js +var init_backend = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/backend.js"() { + init_backend_impl(); + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/version.js +var version; +var init_version = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/version.js"() { + version = "1.23.0"; + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/env-impl.js +var logLevelValue, env; +var init_env_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/env-impl.js"() { + 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 }); + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/env.js +var env2; +var init_env = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/env.js"() { + init_env_impl(); + env2 = env; + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/tensor-conversion-impl.js +var tensorToDataURL, tensorToImageData; +var init_tensor_conversion_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-conversion-impl.js"() { + 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; + }; + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/tensor-factory-impl.js +var bufferToTensor, tensorFromImage, tensorFromTexture, tensorFromGpuBuffer, tensorFromMLTensor, tensorFromPinnedBuffer; +var init_tensor_factory_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-factory-impl.js"() { + 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] }); + } +}); + +// web/node_modules/onnxruntime-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({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-impl-type-mapping.js"() { + 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); + } + } + }; + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/tensor-utils-impl.js +var calculateSize, tensorReshape; +var init_tensor_utils_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-utils-impl.js"() { + 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`); + } + }; + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/tensor-impl.js +var Tensor; +var init_tensor_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-impl.js"() { + 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); + } + }; + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/tensor.js +var Tensor2; +var init_tensor = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor.js"() { + init_tensor_impl(); + Tensor2 = Tensor; + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/trace.js +var TRACE, TRACE_FUNC, TRACE_FUNC_BEGIN, TRACE_FUNC_END; +var init_trace = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/trace.js"() { + 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); + }; + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/inference-session-impl.js +var InferenceSession; +var init_inference_session_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/inference-session-impl.js"() { + init_backend_impl(); + init_tensor(); + init_trace(); + InferenceSession = class _InferenceSession { + constructor(handler) { + this.handler = handler; + } + async run(feeds, arg1, arg2) { + TRACE_FUNC_BEGIN(); + 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_FUNC_END(); + return returnValue; + } + async release() { + return this.handler.dispose(); + } + static async create(arg0, arg1, arg2, arg3) { + TRACE_FUNC_BEGIN(); + 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_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; + } + }; + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/inference-session.js +var InferenceSession2; +var init_inference_session = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/inference-session.js"() { + init_inference_session_impl(); + InferenceSession2 = InferenceSession; + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/tensor-conversion.js +var init_tensor_conversion = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-conversion.js"() { + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/tensor-factory.js +var init_tensor_factory = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-factory.js"() { + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/onnx-model.js +var init_onnx_model = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/onnx-model.js"() { + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/onnx-value.js +var init_onnx_value = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/onnx-value.js"() { + } +}); + +// web/node_modules/onnxruntime-common/dist/esm/index.js +var esm_exports = {}; +__export(esm_exports, { + InferenceSession: () => InferenceSession2, + TRACE: () => TRACE, + TRACE_FUNC_BEGIN: () => TRACE_FUNC_BEGIN, + TRACE_FUNC_END: () => TRACE_FUNC_END, + Tensor: () => Tensor2, + env: () => env2, + registerBackend: () => registerBackend +}); +var init_esm = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/index.js"() { + 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 (atleast 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 broadcas + * @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( + // eslint-disable-next-line max-len + "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; + } + /** + * normailze 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 (e) { + 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 { + 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 (e) { + 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.23.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) { + const wasmBackend = null.wasmBackend; + if (false) { + registerBackend("webgpu", wasmBackend, 5); + 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_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,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vbm9kZV9tb2R1bGVzL29ubnhydW50aW1lLWNvbW1vbi9saWIvYmFja2VuZC1pbXBsLnRzIiwgIi4uL25vZGVfbW9kdWxlcy9vbm54cnVudGltZS1jb21tb24vbGliL2JhY2tlbmQudHMiLCAiLi4vbm9kZV9tb2R1bGVzL29ubnhydW50aW1lLWNvbW1vbi9saWIvdmVyc2lvbi50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi9lbnYtaW1wbC50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi9lbnYudHMiLCAiLi4vbm9kZV9tb2R1bGVzL29ubnhydW50aW1lLWNvbW1vbi9saWIvdGVuc29yLWNvbnZlcnNpb24taW1wbC50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi90ZW5zb3ItZmFjdG9yeS1pbXBsLnRzIiwgIi4uL25vZGVfbW9kdWxlcy9vbm54cnVudGltZS1jb21tb24vbGliL3RlbnNvci1pbXBsLXR5cGUtbWFwcGluZy50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi90ZW5zb3ItdXRpbHMtaW1wbC50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi90ZW5zb3ItaW1wbC50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi90ZW5zb3IudHMiLCAiLi4vbm9kZV9tb2R1bGVzL29ubnhydW50aW1lLWNvbW1vbi9saWIvdHJhY2UudHMiLCAiLi4vbm9kZV9tb2R1bGVzL29ubnhydW50aW1lLWNvbW1vbi9saWIvaW5mZXJlbmNlLXNlc3Npb24taW1wbC50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi9pbmZlcmVuY2Utc2Vzc2lvbi50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi90ZW5zb3ItY29udmVyc2lvbi50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi90ZW5zb3ItZmFjdG9yeS50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi9vbm54LW1vZGVsLnRzIiwgIi4uL25vZGVfbW9kdWxlcy9vbm54cnVudGltZS1jb21tb24vbGliL29ubngtdmFsdWUudHMiLCAiLi4vbm9kZV9tb2R1bGVzL29ubnhydW50aW1lLWNvbW1vbi9saWIvaW5kZXgudHMiLCAiLi4vbGliL29ubnhqcy9pbnN0cnVtZW50LnRzIiwgIi4uL2xpYi9vbm54anMvb3BzZXQudHMiLCAiLi4vbm9kZV9tb2R1bGVzL2d1aWQtdHlwZXNjcmlwdC9kaXN0L2d1aWQuanMiLCAiLi4vbm9kZV9tb2R1bGVzL2xvbmcvaW5kZXguanMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9hcmctdHlwZS50cyIsICIuLi9ub2RlX21vZHVsZXMvZmxhdGJ1ZmZlcnMvanMvY29uc3RhbnRzLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9mbGF0YnVmZmVycy9qcy91dGlscy5qcyIsICIuLi9ub2RlX21vZHVsZXMvZmxhdGJ1ZmZlcnMvanMvZW5jb2RpbmcuanMiLCAiLi4vbm9kZV9tb2R1bGVzL2ZsYXRidWZmZXJzL2pzL2J5dGUtYnVmZmVyLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9mbGF0YnVmZmVycy9qcy9idWlsZGVyLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9mbGF0YnVmZmVycy9qcy9mbGF0YnVmZmVycy5qcyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2FyZy10eXBlLWFuZC1pbmRleC50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2F0dHJpYnV0ZS10eXBlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbm9kZS10eXBlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbm9kZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2VkZ2UtZW5kLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbm9kZS1lZGdlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbm9kZXMtdG8tb3B0aW1pemUtaW5kaWNlcy50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9uLXJlY29yZC50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9uLXJlY29yZC1jb250YWluZXItZW50cnkudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ydW50aW1lLW9wdGltaXphdGlvbnMudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy90ZW5zb3ItZGF0YS10eXBlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvdGVuc29yLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvc3BhcnNlLXRlbnNvci50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL21hcC10eXBlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvc2VxdWVuY2UtdHlwZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2RpbWVuc2lvbi12YWx1ZS10eXBlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZGltZW5zaW9uLXZhbHVlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZGltZW5zaW9uLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvc2hhcGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy90ZW5zb3ItdHlwZS1hbmQtc2hhcGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy90eXBlLWluZm8tdmFsdWUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy90eXBlLWluZm8udHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy92YWx1ZS1pbmZvLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZ3JhcGgudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9hdHRyaWJ1dGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9kZXByZWNhdGVkLWtlcm5lbC1jcmVhdGUtaW5mb3MudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9kZXByZWNhdGVkLW5vZGUtaW5kZXgtYW5kLWtlcm5lbC1kZWYtaGFzaC50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQtc3ViLWdyYXBoLXNlc3Npb24tc3RhdGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9kZXByZWNhdGVkLXNlc3Npb24tc3RhdGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9rZXJuZWwtdHlwZS1zdHItYXJncy1lbnRyeS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL29wLWlkLWtlcm5lbC10eXBlLXN0ci1hcmdzLWVudHJ5LnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMva2VybmVsLXR5cGUtc3RyLXJlc29sdmVyLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvb3BlcmF0b3Itc2V0LWlkLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvc3RyaW5nLXN0cmluZy1lbnRyeS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL21vZGVsLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvaW5mZXJlbmNlLXNlc3Npb24udHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZC50cyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvYXNwcm9taXNlL2luZGV4LmpzIiwgIi4uL25vZGVfbW9kdWxlcy9AcHJvdG9idWZqcy9iYXNlNjQvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL2V2ZW50ZW1pdHRlci9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvZmxvYXQvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL2lucXVpcmUvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL3V0ZjgvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL3Bvb2wvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3V0aWwvbG9uZ2JpdHMuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3V0aWwvbWluaW1hbC5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvd3JpdGVyLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy93cml0ZXJfYnVmZmVyLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy9yZWFkZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3JlYWRlcl9idWZmZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3JwYy9zZXJ2aWNlLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy9ycGMuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3Jvb3RzLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy9pbmRleC1taW5pbWFsLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL21pbmltYWwuanMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubnguanMiLCAiLi4vbGliL29ubnhqcy91dGlsLnRzIiwgIi4uL2xpYi9vbm54anMvdGVuc29yLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1zb3VyY2UudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90eXBlcy50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3V0aWxzLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3BhY2tpbmctdXRpbHMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcGFjay50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9yZXNoYXBlLXBhY2tlZC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy91aW50OC1lbmNvZGUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdW5wYWNrLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvdGV4dHVyZS1kYXRhLWVuY29kZXIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90ZXh0dXJlLWxheW91dC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2luZmVyZW5jZS1oYW5kbGVyLnRzIiwgIi4uL2xpYi9vbm54anMvYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2JhdGNoLW5vcm1hbGl6YXRpb24udHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLWRlZmluaXRpb25zLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2JpbmFyeS1vcC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jYXN0LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2NvbmNhdC1wYWNrZWQudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29uY2F0LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3VuYXJ5LW9wLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2Z1c2UtdXRpbHMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29udi1ncm91cGVkLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2ltMmNvbC1wYWNrLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL21hdG11bC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9tYXRtdWwtcGFjay50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb252LXBhY2sudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvaW0yY29sLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2RvdC1wcm9kdWN0LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2NvbnYudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29udi10cmFuc3Bvc2UudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdHJhbnNwb3NlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2RlcHRoLXRvLXNwYWNlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2ZsYXR0ZW4udHMiLCAiLi4vbGliL29ubnhqcy9vcGVyYXRvcnMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZ2F0aGVyLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2dlbW0udHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvaW1hZ2Utc2NhbGVyLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2luc3RhbmNlLW5vcm1hbGl6YXRpb24udHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvbHJuLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3BhZC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9wb29sLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3JlZHVjZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9yZXNoYXBlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Vwc2FtcGxlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Jlc2l6ZS1wYWNrZWQudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc2hhcGUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc2xpY2UudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc29mdG1heC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zcGxpdC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zcXVlZXplLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3N1bS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy90aWxlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Vuc3F1ZWV6ZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wLXJlc29sdmUtcnVsZXMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLWZ1bmN0aW9uLWlubGluZXIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90ZXh0dXJlLWxheW91dC1zdHJhdGVneS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtY29vcmRpbmF0ZS1saWIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLWVuY29kaW5nLWxpYi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtZnJhZ2NvbG9yLWxpYi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtc2hhcGUtdXRpbHMtbGliLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC12ZWMtbGliLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1yZWdpc3RlcmVkLWxpYnMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLXByZXByb2Nlc3Nvci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3Byb2dyYW0tbWFuYWdlci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3RleHR1cmUtbWFuYWdlci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3Nlc3Npb24taGFuZGxlci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3dlYmdsLWNvbnRleHQudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC93ZWJnbC1jb250ZXh0LWZhY3RvcnkudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy9iYWNrZW5kLXdlYmdsLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZC50cyIsICIuLi9saWIvb25ueGpzL2V4ZWN1dGlvbi1wbGFuLnRzIiwgIi4uL2xpYi9vbm54anMvYXR0cmlidXRlLnRzIiwgIi4uL2xpYi9vbm54anMvZ3JhcGgudHMiLCAiLi4vbGliL29ubnhqcy9tb2RlbC50cyIsICIuLi9saWIvb25ueGpzL3Nlc3Npb24udHMiLCAiLi4vbGliL29ubnhqcy9zZXNzaW9uLWhhbmRsZXItaW5mZXJlbmNlLnRzIiwgIi4uL2xpYi9iYWNrZW5kLW9ubnhqcy50cyIsICIuLi9saWIvaW5kZXgudHMiLCAiLi4vbGliL3ZlcnNpb24udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBCYWNrZW5kIH0gZnJvbSAnLi9iYWNrZW5kLmpzJztcbmltcG9ydCB7IEluZmVyZW5jZVNlc3Npb24gfSBmcm9tICcuL2luZmVyZW5jZS1zZXNzaW9uLmpzJztcblxuaW50ZXJmYWNlIEJhY2tlbmRJbmZvIHtcbiAgYmFja2VuZDogQmFja2VuZDtcbiAgcHJpb3JpdHk6IG51bWJlcjtcblxuICBpbml0UHJvbWlzZT86IFByb21pc2U8dm9pZD47XG4gIGluaXRpYWxpemVkPzogYm9vbGVhbjtcbiAgYWJvcnRlZD86IGJvb2xlYW47XG4gIGVycm9yPzogc3RyaW5nO1xufVxuXG5jb25zdCBiYWNrZW5kczogTWFwPHN0cmluZywgQmFja2VuZEluZm8+ID0gbmV3IE1hcCgpO1xuY29uc3QgYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5OiBzdHJpbmdbXSA9IFtdO1xuXG4vKipcbiAqIFJlZ2lzdGVyIGEgYmFja2VuZC5cbiAqXG4gKiBAcGFyYW0gbmFtZSAtIHRoZSBuYW1lIGFzIGEga2V5IHRvIGxvb2t1cCBhcyBhbiBleGVjdXRpb24gcHJvdmlkZXIuXG4gKiBAcGFyYW0gYmFja2VuZCAtIHRoZSBiYWNrZW5kIG9iamVjdC5cbiAqIEBwYXJhbSBwcmlvcml0eSAtIGFuIGludGVnZXIgaW5kaWNhdGluZyB0aGUgcHJpb3JpdHkgb2YgdGhlIGJhY2tlbmQuIEhpZ2hlciBudW1iZXIgbWVhbnMgaGlnaGVyIHByaW9yaXR5LiBpZiBwcmlvcml0eVxuICogPCAwLCBpdCB3aWxsIGJlIGNvbnNpZGVyZWQgYXMgYSAnYmV0YScgdmVyc2lvbiBhbmQgd2lsbCBub3QgYmUgdXNlZCBhcyBhIGZhbGxiYWNrIGJhY2tlbmQgYnkgZGVmYXVsdC5cbiAqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCByZWdpc3RlckJhY2tlbmQgPSAobmFtZTogc3RyaW5nLCBiYWNrZW5kOiBCYWNrZW5kLCBwcmlvcml0eTogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGlmIChiYWNrZW5kICYmIHR5cGVvZiBiYWNrZW5kLmluaXQgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGJhY2tlbmQuY3JlYXRlSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zdCBjdXJyZW50QmFja2VuZCA9IGJhY2tlbmRzLmdldChuYW1lKTtcbiAgICBpZiAoY3VycmVudEJhY2tlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgYmFja2VuZHMuc2V0KG5hbWUsIHsgYmFja2VuZCwgcHJpb3JpdHkgfSk7XG4gICAgfSBlbHNlIGlmIChjdXJyZW50QmFja2VuZC5wcmlvcml0eSA+IHByaW9yaXR5KSB7XG4gICAgICAvLyBzYW1lIG5hbWUgaXMgYWxyZWFkeSByZWdpc3RlcmVkIHdpdGggYSBoaWdoZXIgcHJpb3JpdHkuIHNraXAgcmVnaXN0ZXJhdGlvbi5cbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKGN1cnJlbnRCYWNrZW5kLnByaW9yaXR5ID09PSBwcmlvcml0eSkge1xuICAgICAgaWYgKGN1cnJlbnRCYWNrZW5kLmJhY2tlbmQgIT09IGJhY2tlbmQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgcmVnaXN0ZXIgYmFja2VuZCBcIiR7bmFtZX1cIiB1c2luZyBwcmlvcml0eSAke3ByaW9yaXR5fWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwcmlvcml0eSA+PSAwKSB7XG4gICAgICBjb25zdCBpID0gYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5LmluZGV4T2YobmFtZSk7XG4gICAgICBpZiAoaSAhPT0gLTEpIHtcbiAgICAgICAgYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5LnNwbGljZShpLCAxKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGJhY2tlbmRzLmdldChiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHlbaV0pIS5wcmlvcml0eSA8PSBwcmlvcml0eSkge1xuICAgICAgICAgIGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eS5zcGxpY2UoaSwgMCwgbmFtZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHkucHVzaChuYW1lKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignbm90IGEgdmFsaWQgYmFja2VuZCcpO1xufTtcblxuLyoqXG4gKiBUcnkgdG8gcmVzb2x2ZSBhbmQgaW5pdGlhbGl6ZSBhIGJhY2tlbmQuXG4gKlxuICogQHBhcmFtIGJhY2tlbmROYW1lIC0gdGhlIG5hbWUgb2YgdGhlIGJhY2tlbmQuXG4gKiBAcmV0dXJucyB0aGUgYmFja2VuZCBpbnN0YW5jZSBpZiByZXNvbHZlZCBhbmQgaW5pdGlhbGl6ZWQgc3VjY2Vzc2Z1bGx5LCBvciBhbiBlcnJvciBtZXNzYWdlIGlmIGZhaWxlZC5cbiAqL1xuY29uc3QgdHJ5UmVzb2x2ZUFuZEluaXRpYWxpemVCYWNrZW5kID0gYXN5bmMgKGJhY2tlbmROYW1lOiBzdHJpbmcpOiBQcm9taXNlPEJhY2tlbmQgfCBzdHJpbmc+ID0+IHtcbiAgY29uc3QgYmFja2VuZEluZm8gPSBiYWNrZW5kcy5nZXQoYmFja2VuZE5hbWUpO1xuICBpZiAoIWJhY2tlbmRJbmZvKSB7XG4gICAgcmV0dXJuICdiYWNrZW5kIG5vdCBmb3VuZC4nO1xuICB9XG5cbiAgaWYgKGJhY2tlbmRJbmZvLmluaXRpYWxpemVkKSB7XG4gICAgcmV0dXJuIGJhY2tlbmRJbmZvLmJhY2tlbmQ7XG4gIH0gZWxzZSBpZiAoYmFja2VuZEluZm8uYWJvcnRlZCkge1xuICAgIHJldHVybiBiYWNrZW5kSW5mby5lcnJvciE7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgaXNJbml0aWFsaXppbmcgPSAhIWJhY2tlbmRJbmZvLmluaXRQcm9taXNlO1xuICAgIHRyeSB7XG4gICAgICBpZiAoIWlzSW5pdGlhbGl6aW5nKSB7XG4gICAgICAgIGJhY2tlbmRJbmZvLmluaXRQcm9taXNlID0gYmFja2VuZEluZm8uYmFja2VuZC5pbml0KGJhY2tlbmROYW1lKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IGJhY2tlbmRJbmZvLmluaXRQcm9taXNlO1xuICAgICAgYmFja2VuZEluZm8uaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIGJhY2tlbmRJbmZvLmJhY2tlbmQ7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKCFpc0luaXRpYWxpemluZykge1xuICAgICAgICBiYWNrZW5kSW5mby5lcnJvciA9IGAke2V9YDtcbiAgICAgICAgYmFja2VuZEluZm8uYWJvcnRlZCA9IHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFja2VuZEluZm8uZXJyb3IhO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBkZWxldGUgYmFja2VuZEluZm8uaW5pdFByb21pc2U7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIFJlc29sdmUgZXhlY3V0aW9uIHByb3ZpZGVycyBmcm9tIHRoZSBzcGVjaWZpYyBzZXNzaW9uIG9wdGlvbnMuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSB0aGUgc2Vzc2lvbiBvcHRpb25zIG9iamVjdC5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgdHVwbGUgb2YgYW4gaW5pdGlhbGl6ZWQgYmFja2VuZCBpbnN0YW5jZSBhbmQgYSBzZXNzaW9uIG9wdGlvbnMgb2JqZWN0IHdpdGhcbiAqIGZpbHRlcmVkIEVQIGxpc3QuXG4gKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgY29uc3QgcmVzb2x2ZUJhY2tlbmRBbmRFeGVjdXRpb25Qcm92aWRlcnMgPSBhc3luYyAoXG4gIG9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMsXG4pOiBQcm9taXNlPFtiYWNrZW5kOiBCYWNrZW5kLCBvcHRpb25zOiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zXT4gPT4ge1xuICAvLyBleHRyYWN0IGJhY2tlbmQgaGludHMgZnJvbSBzZXNzaW9uIG9wdGlvbnNcbiAgY29uc3QgZXBzID0gb3B0aW9ucy5leGVjdXRpb25Qcm92aWRlcnMgfHwgW107XG4gIGNvbnN0IGJhY2tlbmRIaW50cyA9IGVwcy5tYXAoKGkpID0+ICh0eXBlb2YgaSA9PT0gJ3N0cmluZycgPyBpIDogaS5uYW1lKSk7XG4gIGNvbnN0IGJhY2tlbmROYW1lcyA9IGJhY2tlbmRIaW50cy5sZW5ndGggPT09IDAgPyBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHkgOiBiYWNrZW5kSGludHM7XG5cbiAgLy8gdHJ5IHRvIHJlc29sdmUgYW5kIGluaXRpYWxpemUgYWxsIHJlcXVlc3RlZCBiYWNrZW5kc1xuICBsZXQgYmFja2VuZDogQmFja2VuZCB8IHVuZGVmaW5lZDtcbiAgY29uc3QgZXJyb3JzID0gW107XG4gIGNvbnN0IGF2YWlsYWJsZUJhY2tlbmROYW1lcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBmb3IgKGNvbnN0IGJhY2tlbmROYW1lIG9mIGJhY2tlbmROYW1lcykge1xuICAgIGNvbnN0IHJlc29sdmVSZXN1bHQgPSBhd2FpdCB0cnlSZXNvbHZlQW5kSW5pdGlhbGl6ZUJhY2tlbmQoYmFja2VuZE5hbWUpO1xuICAgIGlmICh0eXBlb2YgcmVzb2x2ZVJlc3VsdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVycm9ycy5wdXNoKHsgbmFtZTogYmFja2VuZE5hbWUsIGVycjogcmVzb2x2ZVJlc3VsdCB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFiYWNrZW5kKSB7XG4gICAgICAgIGJhY2tlbmQgPSByZXNvbHZlUmVzdWx0O1xuICAgICAgfVxuICAgICAgaWYgKGJhY2tlbmQgPT09IHJlc29sdmVSZXN1bHQpIHtcbiAgICAgICAgYXZhaWxhYmxlQmFja2VuZE5hbWVzLmFkZChiYWNrZW5kTmFtZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgbm8gYmFja2VuZCBpcyBhdmFpbGFibGUsIHRocm93IGVycm9yLlxuICBpZiAoIWJhY2tlbmQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG5vIGF2YWlsYWJsZSBiYWNrZW5kIGZvdW5kLiBFUlI6ICR7ZXJyb3JzLm1hcCgoZSkgPT4gYFske2UubmFtZX1dICR7ZS5lcnJ9YCkuam9pbignLCAnKX1gKTtcbiAgfVxuXG4gIC8vIGZvciBlYWNoIGV4cGxpY2l0bHkgcmVxdWVzdGVkIGJhY2tlbmQsIGlmIGl0J3Mgbm90IGF2YWlsYWJsZSwgb3V0cHV0IHdhcm5pbmcgbWVzc2FnZS5cbiAgZm9yIChjb25zdCB7IG5hbWUsIGVyciB9IG9mIGVycm9ycykge1xuICAgIGlmIChiYWNrZW5kSGludHMuaW5jbHVkZXMobmFtZSkpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGByZW1vdmluZyByZXF1ZXN0ZWQgZXhlY3V0aW9uIHByb3ZpZGVyIFwiJHtuYW1lfVwiIGZyb20gc2Vzc2lvbiBvcHRpb25zIGJlY2F1c2UgaXQgaXMgbm90IGF2YWlsYWJsZTogJHtlcnJ9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZmlsdGVyZWRFcHMgPSBlcHMuZmlsdGVyKChpKSA9PiBhdmFpbGFibGVCYWNrZW5kTmFtZXMuaGFzKHR5cGVvZiBpID09PSAnc3RyaW5nJyA/IGkgOiBpLm5hbWUpKTtcblxuICByZXR1cm4gW1xuICAgIGJhY2tlbmQsXG4gICAgbmV3IFByb3h5KG9wdGlvbnMsIHtcbiAgICAgIGdldDogKHRhcmdldCwgcHJvcCkgPT4ge1xuICAgICAgICBpZiAocHJvcCA9PT0gJ2V4ZWN1dGlvblByb3ZpZGVycycpIHtcbiAgICAgICAgICByZXR1cm4gZmlsdGVyZWRFcHM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgcHJvcCk7XG4gICAgICB9LFxuICAgIH0pLFxuICBdO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbiB9IGZyb20gJy4vaW5mZXJlbmNlLXNlc3Npb24uanMnO1xuaW1wb3J0IHsgT25ueFZhbHVlIH0gZnJvbSAnLi9vbm54LXZhbHVlLmpzJztcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBTZXNzaW9uSGFuZGxlciB7XG4gIHR5cGUgRmVlZHNUeXBlID0geyBbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlIH07XG4gIHR5cGUgRmV0Y2hlc1R5cGUgPSB7IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfCBudWxsIH07XG4gIHR5cGUgUmV0dXJuVHlwZSA9IHsgW25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZSB9O1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgc2hhcmVkIFNlc3Npb25IYW5kbGVyIGZ1bmN0aW9uYWxpdHlcbiAqXG4gKiBAaWdub3JlXG4gKi9cbmludGVyZmFjZSBTZXNzaW9uSGFuZGxlciB7XG4gIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPjtcblxuICByZWFkb25seSBpbnB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcbiAgcmVhZG9ubHkgb3V0cHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIHJlYWRvbmx5IGlucHV0TWV0YWRhdGE6IHJlYWRvbmx5IEluZmVyZW5jZVNlc3Npb24uVmFsdWVNZXRhZGF0YVtdO1xuICByZWFkb25seSBvdXRwdXRNZXRhZGF0YTogcmVhZG9ubHkgSW5mZXJlbmNlU2Vzc2lvbi5WYWx1ZU1ldGFkYXRhW107XG59XG5cbi8qKlxuICogUmVwcmVzZW50IGEgaGFuZGxlciBpbnN0YW5jZSBvZiBhbiBpbmZlcmVuY2Ugc2Vzc2lvbi5cbiAqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIgZXh0ZW5kcyBTZXNzaW9uSGFuZGxlciB7XG4gIHN0YXJ0UHJvZmlsaW5nKCk6IHZvaWQ7XG4gIGVuZFByb2ZpbGluZygpOiB2b2lkO1xuXG4gIHJ1bihcbiAgICBmZWVkczogU2Vzc2lvbkhhbmRsZXIuRmVlZHNUeXBlLFxuICAgIGZldGNoZXM6IFNlc3Npb25IYW5kbGVyLkZldGNoZXNUeXBlLFxuICAgIG9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxTZXNzaW9uSGFuZGxlci5SZXR1cm5UeXBlPjtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnQgYSBiYWNrZW5kIHRoYXQgcHJvdmlkZXMgaW1wbGVtZW50YXRpb24gb2YgbW9kZWwgaW5mZXJlbmNpbmcuXG4gKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJhY2tlbmQge1xuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgYmFja2VuZCBhc3luY2hyb25vdXNseS4gU2hvdWxkIHRocm93IHdoZW4gZmFpbGVkLlxuICAgKi9cbiAgaW5pdChiYWNrZW5kTmFtZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPjtcblxuICBjcmVhdGVJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcihcbiAgICB1cmlPckJ1ZmZlcjogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcj47XG59XG5cbmV4cG9ydCB7IHJlZ2lzdGVyQmFja2VuZCB9IGZyb20gJy4vYmFja2VuZC1pbXBsLmpzJztcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLy8gVGhpcyBmaWxlIGlzIGdlbmVyYXRlZCBieSAvanMvc2NyaXB0cy91cGRhdGUtdmVyc2lvbi50c1xuLy8gRG8gbm90IG1vZGlmeSBmaWxlIGNvbnRlbnQgbWFudWFsbHkuXG5cbmV4cG9ydCBjb25zdCB2ZXJzaW9uID0gJzEuMjMuMCc7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEVudiB9IGZyb20gJy4vZW52LmpzJztcbmltcG9ydCB7IHZlcnNpb24gfSBmcm9tICcuL3ZlcnNpb24uanMnO1xuXG50eXBlIExvZ0xldmVsVHlwZSA9IEVudlsnbG9nTGV2ZWwnXTtcblxubGV0IGxvZ0xldmVsVmFsdWU6IFJlcXVpcmVkPExvZ0xldmVsVHlwZT4gPSAnd2FybmluZyc7XG5cbmV4cG9ydCBjb25zdCBlbnY6IEVudiA9IHtcbiAgd2FzbToge30gYXMgRW52LldlYkFzc2VtYmx5RmxhZ3MsXG4gIHdlYmdsOiB7fSBhcyBFbnYuV2ViR0xGbGFncyxcbiAgd2ViZ3B1OiB7fSBhcyBFbnYuV2ViR3B1RmxhZ3MsXG4gIHZlcnNpb25zOiB7IGNvbW1vbjogdmVyc2lvbiB9LFxuXG4gIHNldCBsb2dMZXZlbCh2YWx1ZTogTG9nTGV2ZWxUeXBlKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycgfHwgWyd2ZXJib3NlJywgJ2luZm8nLCAnd2FybmluZycsICdlcnJvcicsICdmYXRhbCddLmluZGV4T2YodmFsdWUpID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBsb2dnaW5nIGxldmVsOiAke3ZhbHVlfWApO1xuICAgIH1cbiAgICBsb2dMZXZlbFZhbHVlID0gdmFsdWU7XG4gIH0sXG4gIGdldCBsb2dMZXZlbCgpOiBSZXF1aXJlZDxMb2dMZXZlbFR5cGU+IHtcbiAgICByZXR1cm4gbG9nTGV2ZWxWYWx1ZTtcbiAgfSxcbn07XG5cbi8vIHNldCBwcm9wZXJ0eSAnbG9nTGV2ZWwnIHNvIHRoYXQgdGhleSBjYW4gYmUgY29ycmVjdGx5IHRyYW5zZmVycmVkIHRvIHdvcmtlciBieSBgcG9zdE1lc3NhZ2UoKWAuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZW52LCAnbG9nTGV2ZWwnLCB7IGVudW1lcmFibGU6IHRydWUgfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiBhcyBlbnZJbXBsIH0gZnJvbSAnLi9lbnYtaW1wbC5qcyc7XG5pbXBvcnQgeyBUcnlHZXRHbG9iYWxUeXBlIH0gZnJvbSAnLi90eXBlLWhlbHBlci5qcyc7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBFbnYge1xuICBleHBvcnQgdHlwZSBXYXNtUGF0aFByZWZpeCA9IHN0cmluZztcbiAgZXhwb3J0IGludGVyZmFjZSBXYXNtRmlsZVBhdGhzIHtcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHRoZSBvdmVycmlkZSBwYXRoIGZvciB0aGUgbWFpbiAud2FzbSBmaWxlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXRoIHNob3VsZCBiZSBhbiBhYnNvbHV0ZSBwYXRoLlxuICAgICAqXG4gICAgICogSWYgbm90IG1vZGlmaWVkLCB0aGUgZmlsZW5hbWUgb2YgdGhlIC53YXNtIGZpbGUgaXM6XG4gICAgICogLSBgb3J0LXdhc20tc2ltZC10aHJlYWRlZC53YXNtYCBmb3IgZGVmYXVsdCBidWlsZFxuICAgICAqIC0gYG9ydC13YXNtLXNpbWQtdGhyZWFkZWQuanNlcC53YXNtYCBmb3IgSlNFUCBidWlsZCAod2l0aCBXZWJHUFUgYW5kIFdlYk5OKVxuICAgICAqL1xuICAgIHdhc20/OiBVUkwgfCBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgb3ZlcnJpZGUgcGF0aCBmb3IgdGhlIG1haW4gLm1qcyBmaWxlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXRoIHNob3VsZCBiZSBhbiBhYnNvbHV0ZSBwYXRoLlxuICAgICAqXG4gICAgICogSWYgbm90IG1vZGlmaWVkLCB0aGUgZmlsZW5hbWUgb2YgdGhlIC5tanMgZmlsZSBpczpcbiAgICAgKiAtIGBvcnQtd2FzbS1zaW1kLXRocmVhZGVkLm1qc2AgZm9yIGRlZmF1bHQgYnVpbGRcbiAgICAgKiAtIGBvcnQtd2FzbS1zaW1kLXRocmVhZGVkLmpzZXAubWpzYCBmb3IgSlNFUCBidWlsZCAod2l0aCBXZWJHUFUgYW5kIFdlYk5OKVxuICAgICAqL1xuICAgIG1qcz86IFVSTCB8IHN0cmluZztcbiAgfVxuICBleHBvcnQgdHlwZSBXYXNtUHJlZml4T3JGaWxlUGF0aHMgPSBXYXNtUGF0aFByZWZpeCB8IFdhc21GaWxlUGF0aHM7XG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViQXNzZW1ibHlGbGFncyB7XG4gICAgLyoqXG4gICAgICogc2V0IG9yIGdldCBudW1iZXIgb2YgdGhyZWFkKHMpLiBJZiBvbWl0dGVkIG9yIHNldCB0byAwLCBudW1iZXIgb2YgdGhyZWFkKHMpIHdpbGwgYmUgZGV0ZXJtaW5lZCBieSBzeXN0ZW0uIElmIHNldFxuICAgICAqIHRvIDEsIG5vIHdvcmtlciB0aHJlYWQgd2lsbCBiZSBzcGF3bmVkLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IHdoZW4gV2ViQXNzZW1ibHkgbXVsdGl0aHJlYWQgZmVhdHVyZSBpcyBhdmFpbGFibGUgaW4gY3VycmVudCBjb250ZXh0LlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgMGBcbiAgICAgKi9cbiAgICBudW1UaHJlYWRzPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogc2V0IGEgdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRvIGVuYWJsZSBTSU1ELlxuICAgICAqXG4gICAgICogT05OWCBSdW50aW1lIHdpbGwgcGVyZm9ybSBmZWF0dXJlIGRldGVjdGlvbiBiYXNlZCBvbiB0aGUgdmFsdWUgb2YgdGhpcyBwcm9wZXJ0eS4gU3BlY2lmaWNhbGx5LCB3aGVuIHRoZSB2YWx1ZSBpc1xuICAgICAqIHNldCB0bzpcbiAgICAgKiAtIGB1bmRlZmluZWRgLCBgdHJ1ZWAgb3IgYFwiZml4ZWRcImA6IHdpbGwgY2hlY2sgYXZhaWxhYmlsaXR5IG9mIEZpeGVkLXdpZHRoIFNJTUQuXG4gICAgICogLSBgXCJyZWxheGVkXCJgOiB3aWxsIGNoZWNrIGF2YWlsYWJpbGl0eSBvZiBSZWxheGVkIFNJTUQuXG4gICAgICogLSBgZmFsc2VgOiB3aWxsIG5vdCBwZXJmb3JtIFNJTUQgZmVhdHVyZSBjaGVja2luZy5cbiAgICAgKlxuICAgICAqIFNldHRpbmcgdGhpcyBwcm9wZXJ0eSBkb2VzIG5vdCBtYWtlIE9OTlggUnVudGltZSB0byBzd2l0Y2ggdG8gdGhlIGNvcnJlc3BvbmRpbmcgcnVudGltZSBhdXRvbWF0aWNhbGx5LiBVc2VyIG5lZWRcbiAgICAgKiB0byBzZXQgYHdhc21QYXRoc2Agb3IgYHdhc21CaW5hcnlgIHByb3BlcnR5IHRvIGxvYWQgdGhlIGNvcnJlc3BvbmRpbmcgcnVudGltZS5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSB3aGVuIFdlYkFzc2VtYmx5IFNJTUQgZmVhdHVyZSBpcyBhdmFpbGFibGUgaW4gY3VycmVudCBjb250ZXh0LlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgdHJ1ZWBcbiAgICAgKi9cbiAgICBzaW1kPzogYm9vbGVhbiB8ICdmaXhlZCcgfCAncmVsYXhlZCc7XG5cbiAgICAvKipcbiAgICAgKiBzZXQgb3IgZ2V0IGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gZW5hYmxlIHRyYWNlLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAgICpcbiAgICAgKiBAZGVwcmVjYXRlZCBVc2UgYGVudi50cmFjZWAgaW5zdGVhZC4gSWYgYGVudi50cmFjZWAgaXMgc2V0LCB0aGlzIHByb3BlcnR5IHdpbGwgYmUgaWdub3JlZC5cbiAgICAgKi9cbiAgICB0cmFjZT86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IGEgbnVtYmVyIHNwZWNpZnlpbmcgdGhlIHRpbWVvdXQgZm9yIGluaXRpYWxpemF0aW9uIG9mIFdlYkFzc2VtYmx5IGJhY2tlbmQsIGluIG1pbGxpc2Vjb25kcy4gQSB6ZXJvXG4gICAgICogdmFsdWUgaW5kaWNhdGVzIG5vIHRpbWVvdXQgaXMgc2V0LlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgMGBcbiAgICAgKi9cbiAgICBpbml0VGltZW91dD86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFNldCBhIGN1c3RvbSBVUkwgcHJlZml4IHRvIHRoZSAud2FzbS8ubWpzIGZpbGVzLCBvciBhbiBvYmplY3Qgb2Ygb3ZlcnJpZGVzIGZvciBib3RoIC53YXNtLy5tanMgZmlsZS4gVGhlIG92ZXJyaWRlXG4gICAgICogcGF0aCBzaG91bGQgYmUgYW4gYWJzb2x1dGUgcGF0aC5cbiAgICAgKi9cbiAgICB3YXNtUGF0aHM/OiBXYXNtUHJlZml4T3JGaWxlUGF0aHM7XG5cbiAgICAvKipcbiAgICAgKiBTZXQgYSBjdXN0b20gYnVmZmVyIHdoaWNoIGNvbnRhaW5zIHRoZSBXZWJBc3NlbWJseSBiaW5hcnkuIElmIHRoaXMgcHJvcGVydHkgaXMgc2V0LCB0aGUgYHdhc21QYXRoc2AgcHJvcGVydHkgd2lsbFxuICAgICAqIGJlIGlnbm9yZWQuXG4gICAgICovXG4gICAgd2FzbUJpbmFyeT86IEFycmF5QnVmZmVyTGlrZSB8IFVpbnQ4QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gcHJveHkgdGhlIGV4ZWN1dGlvbiBvZiBtYWluIHRocmVhZCB0byBhIHdvcmtlciB0aHJlYWQuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICAgKi9cbiAgICBwcm94eT86IGJvb2xlYW47XG4gIH1cblxuICBleHBvcnQgaW50ZXJmYWNlIFdlYkdMRmxhZ3Mge1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIFdlYkdMIENvbnRleHQgSUQgKHdlYmdsIG9yIHdlYmdsMikuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGAnd2ViZ2wyJ2BcbiAgICAgKi9cbiAgICBjb250ZXh0SWQ/OiAnd2ViZ2wnIHwgJ3dlYmdsMic7XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBXZWJHTCByZW5kZXJpbmcgY29udGV4dC5cbiAgICAgKi9cbiAgICByZWFkb25seSBjb250ZXh0OiBXZWJHTFJlbmRlcmluZ0NvbnRleHQ7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgbWF4aW11bSBiYXRjaCBzaXplIGZvciBtYXRtdWwuIDAgbWVhbnMgdG8gZGlzYWJsZSBiYXRjaGluZy5cbiAgICAgKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICovXG4gICAgbWF0bXVsTWF4QmF0Y2hTaXplPzogbnVtYmVyO1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIHRleHR1cmUgY2FjaGUgbW9kZS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYCdmdWxsJ2BcbiAgICAgKi9cbiAgICB0ZXh0dXJlQ2FjaGVNb2RlPzogJ2luaXRpYWxpemVyT25seScgfCAnZnVsbCc7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgcGFja2VkIHRleHR1cmUgbW9kZVxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAgICovXG4gICAgcGFjaz86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB3aGV0aGVyIGVuYWJsZSBhc3luYyBkb3dubG9hZC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgICAqL1xuICAgIGFzeW5jPzogYm9vbGVhbjtcbiAgfVxuXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViR3B1UHJvZmlsaW5nRGF0YVYxVGVuc29yTWV0YWRhdGEge1xuICAgIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICAgIGRhdGFUeXBlOiBzdHJpbmc7XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJHcHVQcm9maWxpbmdEYXRhVjEge1xuICAgIHZlcnNpb246IDE7XG4gICAgaW5wdXRzTWV0YWRhdGE6IHJlYWRvbmx5IFdlYkdwdVByb2ZpbGluZ0RhdGFWMVRlbnNvck1ldGFkYXRhW107XG4gICAgb3V0cHV0c01ldGFkYXRhOiByZWFkb25seSBXZWJHcHVQcm9maWxpbmdEYXRhVjFUZW5zb3JNZXRhZGF0YVtdO1xuICAgIGtlcm5lbElkOiBudW1iZXI7XG4gICAga2VybmVsVHlwZTogc3RyaW5nO1xuICAgIGtlcm5lbE5hbWU6IHN0cmluZztcbiAgICBwcm9ncmFtTmFtZTogc3RyaW5nO1xuICAgIHN0YXJ0VGltZTogbnVtYmVyO1xuICAgIGVuZFRpbWU6IG51bWJlcjtcbiAgfVxuXG4gIGV4cG9ydCB0eXBlIFdlYkdwdVByb2ZpbGluZ0RhdGEgPSBXZWJHcHVQcm9maWxpbmdEYXRhVjE7XG5cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJHcHVGbGFncyB7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgcHJvZmlsaW5nIG1vZGUuXG4gICAgICpcbiAgICAgKiBAZGVwcmVjYXRlZCBVc2UgYGVudi53ZWJncHUucHJvZmlsaW5nLm1vZGVgIGluc3RlYWQuIElmIGBlbnYud2ViZ3B1LnByb2ZpbGluZy5tb2RlYCBpcyBzZXQsIHRoaXMgcHJvcGVydHkgd2lsbCBiZVxuICAgICAqIGlnbm9yZWQuXG4gICAgICovXG4gICAgcHJvZmlsaW5nTW9kZT86ICdvZmYnIHwgJ2RlZmF1bHQnO1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIHByb2ZpbGluZyBjb25maWd1cmF0aW9uLlxuICAgICAqL1xuICAgIHByb2ZpbGluZzoge1xuICAgICAgLyoqXG4gICAgICAgKiBTZXQgb3IgZ2V0IHRoZSBwcm9maWxpbmcgbW9kZS5cbiAgICAgICAqXG4gICAgICAgKiBAZGVmYXVsdFZhbHVlIGAnb2ZmJ2BcbiAgICAgICAqL1xuICAgICAgbW9kZT86ICdvZmYnIHwgJ2RlZmF1bHQnO1xuXG4gICAgICAvKipcbiAgICAgICAqIFNldCBvciBnZXQgYSBjYWxsYmFjayBmdW5jdGlvbiB3aGVuIGEgcHJvZmlsaW5nIGRhdGEgaXMgcmVjZWl2ZWQuIElmIG5vdCBzZXQsIHRoZSBwcm9maWxpbmcgZGF0YSB3aWxsIGJlXG4gICAgICAgKiBwcmludGVkIHRvIGNvbnNvbGUuXG4gICAgICAgKi9cbiAgICAgIG9uZGF0YT86IChkYXRhOiBXZWJHcHVQcm9maWxpbmdEYXRhKSA9PiB2b2lkO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgcG93ZXIgcHJlZmVyZW5jZS5cbiAgICAgKlxuICAgICAqIFNldHRpbmcgdGhpcyBwcm9wZXJ0eSBvbmx5IGhhcyBlZmZlY3QgYmVmb3JlIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gVGhlIHZhbHVlIHdpbGwgYmVcbiAgICAgKiB1c2VkIGFzIG9wdGlvbnMgZm9yIGBuYXZpZ2F0b3IuZ3B1LnJlcXVlc3RBZGFwdGVyKClgLlxuICAgICAqXG4gICAgICogU2VlIHtAbGluayBodHRwczovL2dwdXdlYi5naXRodWIuaW8vZ3B1d2ViLyNkaWN0ZGVmLWdwdXJlcXVlc3RhZGFwdGVyb3B0aW9uc30gZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYHVuZGVmaW5lZGBcbiAgICAgKlxuICAgICAqIEBkZXByZWNhdGVkIENyZWF0ZSB5b3VyIG93biBHUFVBZGFwdGVyLCB1c2UgaXQgdG8gY3JlYXRlIGEgR1BVRGV2aWNlIGluc3RhbmNlIGFuZCBzZXQge0BsaW5rIGRldmljZX0gcHJvcGVydHkgaWZcbiAgICAgKiB5b3Ugd2FudCB0byB1c2UgYSBzcGVjaWZpYyBwb3dlciBwcmVmZXJlbmNlLlxuICAgICAqL1xuICAgIHBvd2VyUHJlZmVyZW5jZT86ICdsb3ctcG93ZXInIHwgJ2hpZ2gtcGVyZm9ybWFuY2UnO1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIGZvcmNlIGZhbGxiYWNrIGFkYXB0ZXIgZmxhZy5cbiAgICAgKlxuICAgICAqIFNldHRpbmcgdGhpcyBwcm9wZXJ0eSBvbmx5IGhhcyBlZmZlY3QgYmVmb3JlIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gVGhlIHZhbHVlIHdpbGwgYmVcbiAgICAgKiB1c2VkIGFzIG9wdGlvbnMgZm9yIGBuYXZpZ2F0b3IuZ3B1LnJlcXVlc3RBZGFwdGVyKClgLlxuICAgICAqXG4gICAgICogU2VlIHtAbGluayBodHRwczovL2dwdXdlYi5naXRodWIuaW8vZ3B1d2ViLyNkaWN0ZGVmLWdwdXJlcXVlc3RhZGFwdGVyb3B0aW9uc30gZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYHVuZGVmaW5lZGBcbiAgICAgKlxuICAgICAqIEBkZXByZWNhdGVkIENyZWF0ZSB5b3VyIG93biBHUFVBZGFwdGVyLCB1c2UgaXQgdG8gY3JlYXRlIGEgR1BVRGV2aWNlIGluc3RhbmNlIGFuZCBzZXQge0BsaW5rIGRldmljZX0gcHJvcGVydHkgaWZcbiAgICAgKiB5b3Ugd2FudCB0byB1c2UgYSBzcGVjaWZpYyBmYWxsYmFjayBvcHRpb24uXG4gICAgICovXG4gICAgZm9yY2VGYWxsYmFja0FkYXB0ZXI/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIGFkYXB0ZXIgZm9yIFdlYkdQVS5cbiAgICAgKlxuICAgICAqIFNldHRpbmcgdGhpcyBwcm9wZXJ0eSBvbmx5IGhhcyBlZmZlY3QgYmVmb3JlIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gVGhlIHZhbHVlIHdpbGwgYmVcbiAgICAgKiB1c2VkIGFzIHRoZSBHUFUgYWRhcHRlciBmb3IgdGhlIHVuZGVybHlpbmcgV2ViR1BVIGJhY2tlbmQgdG8gY3JlYXRlIEdQVSBkZXZpY2UuXG4gICAgICpcbiAgICAgKiBJZiB0aGlzIHByb3BlcnR5IGlzIG5vdCBzZXQsIGl0IHdpbGwgYmUgYXZhaWxhYmxlIHRvIGdldCBhZnRlciB0aGUgZmlyc3QgV2ViR1BVIGluZmVyZW5jZSBzZXNzaW9uIGlzIGNyZWF0ZWQuIFRoZVxuICAgICAqIHZhbHVlIHdpbGwgYmUgdGhlIEdQVSBhZGFwdGVyIHRoYXQgY3JlYXRlZCBieSB0aGUgdW5kZXJseWluZyBXZWJHUFUgYmFja2VuZC5cbiAgICAgKlxuICAgICAqIFdoZW4gdXNlIHdpdGggVHlwZVNjcmlwdCwgdGhlIHR5cGUgb2YgdGhpcyBwcm9wZXJ0eSBpcyBgR1BVQWRhcHRlcmAgZGVmaW5lZCBpbiBcIkB3ZWJncHUvdHlwZXNcIi5cbiAgICAgKlxuICAgICAqIEBkZXByZWNhdGVkIEl0IGlzIG5vIGxvbmdlciByZWNvbW1lbmRlZCB0byB1c2UgdGhpcyBwcm9wZXJ0eS4gVGhlIGxhdGVzdCBXZWJHUFUgc3BlYyBhZGRzIGBHUFVEZXZpY2UuYWRhcHRlckluZm9gXG4gICAgICogKGh0dHBzOi8vd3d3LnczLm9yZy9UUi93ZWJncHUvI2RvbS1ncHVkZXZpY2UtYWRhcHRlcmluZm8pLCB3aGljaCBhbGxvd3MgdG8gZ2V0IHRoZSBhZGFwdGVyIGluZm9ybWF0aW9uIGZyb20gdGhlXG4gICAgICogZGV2aWNlLiBXaGVuIGl0J3MgYXZhaWxhYmxlLCB0aGVyZSBpcyBubyBuZWVkIHRvIHNldC9nZXQgdGhlIHtAbGluayBhZGFwdGVyfSBwcm9wZXJ0eS5cbiAgICAgKi9cbiAgICBhZGFwdGVyOiBUcnlHZXRHbG9iYWxUeXBlPCdHUFVBZGFwdGVyJz47XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgR1BVIGRldmljZSBmb3IgV2ViR1BVLlxuICAgICAqXG4gICAgICogVGhlcmUgYXJlIDMgdmFsaWQgc2NlbmFyaW9zIG9mIGFjY2Vzc2luZyB0aGlzIHByb3BlcnR5OlxuICAgICAqIC0gU2V0IGEgdmFsdWUgYmVmb3JlIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gVGhlIHZhbHVlIHdpbGwgYmUgdXNlZCBieSB0aGUgV2ViR1BVIGJhY2tlbmRcbiAgICAgKiB0byBwZXJmb3JtIGNhbGN1bGF0aW9ucy4gSWYgdGhlIHZhbHVlIGlzIG5vdCBhIGBHUFVEZXZpY2VgIG9iamVjdCwgYW4gZXJyb3Igd2lsbCBiZSB0aHJvd24uXG4gICAgICogLSBHZXQgdGhlIHZhbHVlIGJlZm9yZSB0aGUgZmlyc3QgV2ViR1BVIGluZmVyZW5jZSBzZXNzaW9uIGlzIGNyZWF0ZWQuIFRoaXMgd2lsbCB0cnkgdG8gY3JlYXRlIGEgbmV3IEdQVURldmljZVxuICAgICAqIGluc3RhbmNlLiBSZXR1cm5zIGEgYFByb21pc2VgIHRoYXQgcmVzb2x2ZXMgdG8gYSBgR1BVRGV2aWNlYCBvYmplY3QuXG4gICAgICogLSBHZXQgdGhlIHZhbHVlIGFmdGVyIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gUmV0dXJucyBhIHJlc29sdmVkIGBQcm9taXNlYCB0byB0aGVcbiAgICAgKiBgR1BVRGV2aWNlYCBvYmplY3QgdXNlZCBieSB0aGUgV2ViR1BVIGJhY2tlbmQuXG4gICAgICovXG4gICAgZ2V0IGRldmljZSgpOiBQcm9taXNlPFRyeUdldEdsb2JhbFR5cGU8J0dQVURldmljZSc+PjtcbiAgICBzZXQgZGV2aWNlKHZhbHVlOiBUcnlHZXRHbG9iYWxUeXBlPCdHUFVEZXZpY2UnPik7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB3aGV0aGVyIHZhbGlkYXRlIGlucHV0IGNvbnRlbnQuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICAgKi9cbiAgICB2YWxpZGF0ZUlucHV0Q29udGVudD86IGJvb2xlYW47XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBFbnYge1xuICAvKipcbiAgICogc2V0IHRoZSBzZXZlcml0eSBsZXZlbCBmb3IgbG9nZ2luZy5cbiAgICpcbiAgICogQGRlZmF1bHRWYWx1ZSBgJ3dhcm5pbmcnYFxuICAgKi9cbiAgbG9nTGV2ZWw/OiAndmVyYm9zZScgfCAnaW5mbycgfCAnd2FybmluZycgfCAnZXJyb3InIHwgJ2ZhdGFsJztcblxuICAvKipcbiAgICogSW5kaWNhdGUgd2hldGhlciBydW4gaW4gZGVidWcgbW9kZS5cbiAgICpcbiAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAqL1xuICBkZWJ1Zz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIHNldCBvciBnZXQgYSBib29sZWFuIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0byBlbmFibGUgdHJhY2UuXG4gICAqXG4gICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgKi9cbiAgdHJhY2U/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBHZXQgdmVyc2lvbiBvZiB0aGUgY3VycmVudCBwYWNrYWdlLlxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbnM6IHtcbiAgICByZWFkb25seSBjb21tb246IHN0cmluZztcbiAgICByZWFkb25seSB3ZWI/OiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgbm9kZT86IHN0cmluZztcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG4gICAgcmVhZG9ubHkgJ3JlYWN0LW5hdGl2ZSc/OiBzdHJpbmc7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudCBhIHNldCBvZiBmbGFncyBmb3IgV2ViQXNzZW1ibHlcbiAgICovXG4gIHJlYWRvbmx5IHdhc206IEVudi5XZWJBc3NlbWJseUZsYWdzO1xuXG4gIC8qKlxuICAgKiBSZXByZXNlbnQgYSBzZXQgb2YgZmxhZ3MgZm9yIFdlYkdMXG4gICAqL1xuICByZWFkb25seSB3ZWJnbDogRW52LldlYkdMRmxhZ3M7XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudCBhIHNldCBvZiBmbGFncyBmb3IgV2ViR1BVXG4gICAqL1xuICByZWFkb25seSB3ZWJncHU6IEVudi5XZWJHcHVGbGFncztcblxuICBbbmFtZTogc3RyaW5nXTogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnQgYSBzZXQgb2YgZmxhZ3MgYXMgYSBnbG9iYWwgc2luZ2xldG9uLlxuICovXG5leHBvcnQgY29uc3QgZW52OiBFbnYgPSBlbnZJbXBsO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3JUb0RhdGFVcmxPcHRpb25zLCBUZW5zb3JUb0ltYWdlRGF0YU9wdGlvbnMgfSBmcm9tICcuL3RlbnNvci1jb252ZXJzaW9uLmpzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yLmpzJztcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IudG9EYXRhVVJMKClcbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvclRvRGF0YVVSTCA9ICh0ZW5zb3I6IFRlbnNvciwgb3B0aW9ucz86IFRlbnNvclRvRGF0YVVybE9wdGlvbnMpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBjYW52YXMgPSB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykgOiBuZXcgT2Zmc2NyZWVuQ2FudmFzKDEsIDEpO1xuICBjYW52YXMud2lkdGggPSB0ZW5zb3IuZGltc1szXTtcbiAgY2FudmFzLmhlaWdodCA9IHRlbnNvci5kaW1zWzJdO1xuICBjb25zdCBwaXhlbHMyRENvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKSBhc1xuICAgIHwgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEXG4gICAgfCBPZmZzY3JlZW5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkRcbiAgICB8IG51bGw7XG5cbiAgaWYgKHBpeGVsczJEQ29udGV4dCAhPSBudWxsKSB7XG4gICAgLy8gRGVmYXVsdCB2YWx1ZXMgZm9yIGhlaWdodCBhbmQgd2lkdGggJiBmb3JtYXRcbiAgICBsZXQgd2lkdGg6IG51bWJlcjtcbiAgICBsZXQgaGVpZ2h0OiBudW1iZXI7XG4gICAgaWYgKG9wdGlvbnM/LnRlbnNvckxheW91dCAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMudGVuc29yTGF5b3V0ID09PSAnTkhXQycpIHtcbiAgICAgIHdpZHRoID0gdGVuc29yLmRpbXNbMl07XG4gICAgICBoZWlnaHQgPSB0ZW5zb3IuZGltc1szXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRGVmYXVsdCBsYXlvdXQgaXMgTkNXSFxuICAgICAgd2lkdGggPSB0ZW5zb3IuZGltc1szXTtcbiAgICAgIGhlaWdodCA9IHRlbnNvci5kaW1zWzJdO1xuICAgIH1cblxuICAgIGNvbnN0IGlucHV0Zm9ybWF0ID0gb3B0aW9ucz8uZm9ybWF0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmZvcm1hdCA6ICdSR0InO1xuXG4gICAgY29uc3Qgbm9ybSA9IG9wdGlvbnM/Lm5vcm07XG4gICAgbGV0IG5vcm1NZWFuOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgICBsZXQgbm9ybUJpYXM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgIGlmIChub3JtID09PSB1bmRlZmluZWQgfHwgbm9ybS5tZWFuID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG5vcm1NZWFuID0gWzI1NSwgMjU1LCAyNTUsIDI1NV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2Ygbm9ybS5tZWFuID09PSAnbnVtYmVyJykge1xuICAgICAgICBub3JtTWVhbiA9IFtub3JtLm1lYW4sIG5vcm0ubWVhbiwgbm9ybS5tZWFuLCBub3JtLm1lYW5dO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbm9ybU1lYW4gPSBbbm9ybS5tZWFuWzBdLCBub3JtLm1lYW5bMV0sIG5vcm0ubWVhblsyXSwgMF07XG4gICAgICAgIGlmIChub3JtLm1lYW5bM10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG5vcm1NZWFuWzNdID0gbm9ybS5tZWFuWzNdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChub3JtID09PSB1bmRlZmluZWQgfHwgbm9ybS5iaWFzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG5vcm1CaWFzID0gWzAsIDAsIDAsIDBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodHlwZW9mIG5vcm0uYmlhcyA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgbm9ybUJpYXMgPSBbbm9ybS5iaWFzLCBub3JtLmJpYXMsIG5vcm0uYmlhcywgbm9ybS5iaWFzXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vcm1CaWFzID0gW25vcm0uYmlhc1swXSwgbm9ybS5iaWFzWzFdLCBub3JtLmJpYXNbMl0sIDBdO1xuICAgICAgICBpZiAobm9ybS5iaWFzWzNdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBub3JtQmlhc1szXSA9IG5vcm0uYmlhc1szXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHN0cmlkZSA9IGhlaWdodCAqIHdpZHRoO1xuICAgIC8vIERlZmF1bHQgcG9pbnRlciBhc3NpZ25tZW50c1xuICAgIGxldCByVGVuc29yUG9pbnRlciA9IDAsXG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZSxcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMixcbiAgICAgIGFUZW5zb3JQb2ludGVyID0gLTE7XG5cbiAgICAvLyBVcGRhdGluZyB0aGUgcG9pbnRlciBhc3NpZ25tZW50cyBiYXNlZCBvbiB0aGUgaW5wdXQgaW1hZ2UgZm9ybWF0XG4gICAgaWYgKGlucHV0Zm9ybWF0ID09PSAnUkdCQScpIHtcbiAgICAgIHJUZW5zb3JQb2ludGVyID0gMDtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICAgICAgYVRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAzO1xuICAgIH0gZWxzZSBpZiAoaW5wdXRmb3JtYXQgPT09ICdSR0InKSB7XG4gICAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgICB9IGVsc2UgaWYgKGlucHV0Zm9ybWF0ID09PSAnUkJHJykge1xuICAgICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoZWlnaHQ7IGkrKykge1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB3aWR0aDsgaisrKSB7XG4gICAgICAgIGNvbnN0IFIgPSAoKHRlbnNvci5kYXRhW3JUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1swXSkgKiBub3JtTWVhblswXTsgLy8gUiB2YWx1ZVxuICAgICAgICBjb25zdCBHID0gKCh0ZW5zb3IuZGF0YVtnVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbMV0pICogbm9ybU1lYW5bMV07IC8vIEcgdmFsdWVcbiAgICAgICAgY29uc3QgQiA9ICgodGVuc29yLmRhdGFbYlRlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzJdKSAqIG5vcm1NZWFuWzJdOyAvLyBCIHZhbHVlXG4gICAgICAgIGNvbnN0IEEgPSBhVGVuc29yUG9pbnRlciA9PT0gLTEgPyAyNTUgOiAoKHRlbnNvci5kYXRhW2FUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1szXSkgKiBub3JtTWVhblszXTsgLy8gQSB2YWx1ZVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3Jlc3RyaWN0LXBsdXMtb3BlcmFuZHNcbiAgICAgICAgcGl4ZWxzMkRDb250ZXh0LmZpbGxTdHlsZSA9ICdyZ2JhKCcgKyBSICsgJywnICsgRyArICcsJyArIEIgKyAnLCcgKyBBICsgJyknO1xuICAgICAgICBwaXhlbHMyRENvbnRleHQuZmlsbFJlY3QoaiwgaSwgMSwgMSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICgndG9EYXRhVVJMJyBpbiBjYW52YXMpIHtcbiAgICAgIHJldHVybiBjYW52YXMudG9EYXRhVVJMKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndG9EYXRhVVJMIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gbm90IGFjY2VzcyBpbWFnZSBkYXRhJyk7XG4gIH1cbn07XG5cbi8qKlxuICogaW1wbGVtZW50YXRpb24gb2YgVGVuc29yLnRvSW1hZ2VEYXRhKClcbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvclRvSW1hZ2VEYXRhID0gKHRlbnNvcjogVGVuc29yLCBvcHRpb25zPzogVGVuc29yVG9JbWFnZURhdGFPcHRpb25zKTogSW1hZ2VEYXRhID0+IHtcbiAgY29uc3QgcGl4ZWxzMkRDb250ZXh0ID1cbiAgICB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnXG4gICAgICA/IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQoJzJkJylcbiAgICAgIDogKG5ldyBPZmZzY3JlZW5DYW52YXMoMSwgMSkuZ2V0Q29udGV4dCgnMmQnKSBhcyBPZmZzY3JlZW5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQpO1xuICBsZXQgaW1hZ2U6IEltYWdlRGF0YTtcbiAgaWYgKHBpeGVsczJEQ29udGV4dCAhPSBudWxsKSB7XG4gICAgLy8gRGVmYXVsdCB2YWx1ZXMgZm9yIGhlaWdodCBhbmQgd2lkdGggJiBmb3JtYXRcbiAgICBsZXQgd2lkdGg6IG51bWJlcjtcbiAgICBsZXQgaGVpZ2h0OiBudW1iZXI7XG4gICAgbGV0IGNoYW5uZWxzOiBudW1iZXI7XG4gICAgaWYgKG9wdGlvbnM/LnRlbnNvckxheW91dCAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMudGVuc29yTGF5b3V0ID09PSAnTkhXQycpIHtcbiAgICAgIHdpZHRoID0gdGVuc29yLmRpbXNbMl07XG4gICAgICBoZWlnaHQgPSB0ZW5zb3IuZGltc1sxXTtcbiAgICAgIGNoYW5uZWxzID0gdGVuc29yLmRpbXNbM107XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZmF1bHQgbGF5b3V0IGlzIE5DV0hcbiAgICAgIHdpZHRoID0gdGVuc29yLmRpbXNbM107XG4gICAgICBoZWlnaHQgPSB0ZW5zb3IuZGltc1syXTtcbiAgICAgIGNoYW5uZWxzID0gdGVuc29yLmRpbXNbMV07XG4gICAgfVxuICAgIGNvbnN0IGlucHV0Zm9ybWF0ID0gb3B0aW9ucyAhPT0gdW5kZWZpbmVkID8gKG9wdGlvbnMuZm9ybWF0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmZvcm1hdCA6ICdSR0InKSA6ICdSR0InO1xuXG4gICAgY29uc3Qgbm9ybSA9IG9wdGlvbnM/Lm5vcm07XG4gICAgbGV0IG5vcm1NZWFuOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgICBsZXQgbm9ybUJpYXM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgIGlmIChub3JtID09PSB1bmRlZmluZWQgfHwgbm9ybS5tZWFuID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG5vcm1NZWFuID0gWzI1NSwgMjU1LCAyNTUsIDI1NV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2Ygbm9ybS5tZWFuID09PSAnbnVtYmVyJykge1xuICAgICAgICBub3JtTWVhbiA9IFtub3JtLm1lYW4sIG5vcm0ubWVhbiwgbm9ybS5tZWFuLCBub3JtLm1lYW5dO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbm9ybU1lYW4gPSBbbm9ybS5tZWFuWzBdLCBub3JtLm1lYW5bMV0sIG5vcm0ubWVhblsyXSwgMjU1XTtcbiAgICAgICAgaWYgKG5vcm0ubWVhblszXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbm9ybU1lYW5bM10gPSBub3JtLm1lYW5bM107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG5vcm0gPT09IHVuZGVmaW5lZCB8fCBub3JtLmJpYXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgbm9ybUJpYXMgPSBbMCwgMCwgMCwgMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2Ygbm9ybS5iaWFzID09PSAnbnVtYmVyJykge1xuICAgICAgICBub3JtQmlhcyA9IFtub3JtLmJpYXMsIG5vcm0uYmlhcywgbm9ybS5iaWFzLCBub3JtLmJpYXNdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbm9ybUJpYXMgPSBbbm9ybS5iaWFzWzBdLCBub3JtLmJpYXNbMV0sIG5vcm0uYmlhc1syXSwgMF07XG4gICAgICAgIGlmIChub3JtLmJpYXNbM10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG5vcm1CaWFzWzNdID0gbm9ybS5iaWFzWzNdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc3RyaWRlID0gaGVpZ2h0ICogd2lkdGg7XG4gICAgaWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKFxuICAgICAgICAob3B0aW9ucy5mb3JtYXQgIT09IHVuZGVmaW5lZCAmJiBjaGFubmVscyA9PT0gNCAmJiBvcHRpb25zLmZvcm1hdCAhPT0gJ1JHQkEnKSB8fFxuICAgICAgICAoY2hhbm5lbHMgPT09IDMgJiYgb3B0aW9ucy5mb3JtYXQgIT09ICdSR0InICYmIG9wdGlvbnMuZm9ybWF0ICE9PSAnQkdSJylcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUZW5zb3IgZm9ybWF0IGRvZXNuJ3QgbWF0Y2ggaW5wdXQgdGVuc29yIGRpbXNcIik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRGVmYXVsdCBwb2ludGVyIGFzc2lnbm1lbnRzXG4gICAgY29uc3Qgc3RlcCA9IDQ7XG4gICAgbGV0IHJJbWFnZVBvaW50ZXIgPSAwLFxuICAgICAgZ0ltYWdlUG9pbnRlciA9IDEsXG4gICAgICBiSW1hZ2VQb2ludGVyID0gMixcbiAgICAgIGFJbWFnZVBvaW50ZXIgPSAzO1xuICAgIGxldCByVGVuc29yUG9pbnRlciA9IDAsXG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZSxcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMixcbiAgICAgIGFUZW5zb3JQb2ludGVyID0gLTE7XG5cbiAgICAvLyBVcGRhdGluZyB0aGUgcG9pbnRlciBhc3NpZ25tZW50cyBiYXNlZCBvbiB0aGUgaW5wdXQgaW1hZ2UgZm9ybWF0XG4gICAgaWYgKGlucHV0Zm9ybWF0ID09PSAnUkdCQScpIHtcbiAgICAgIHJUZW5zb3JQb2ludGVyID0gMDtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICAgICAgYVRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAzO1xuICAgIH0gZWxzZSBpZiAoaW5wdXRmb3JtYXQgPT09ICdSR0InKSB7XG4gICAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgICB9IGVsc2UgaWYgKGlucHV0Zm9ybWF0ID09PSAnUkJHJykge1xuICAgICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gICAgfVxuXG4gICAgaW1hZ2UgPSBwaXhlbHMyRENvbnRleHQuY3JlYXRlSW1hZ2VEYXRhKHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgZm9yIChcbiAgICAgIGxldCBpID0gMDtcbiAgICAgIGkgPCBoZWlnaHQgKiB3aWR0aDtcbiAgICAgIHJJbWFnZVBvaW50ZXIgKz0gc3RlcCwgZ0ltYWdlUG9pbnRlciArPSBzdGVwLCBiSW1hZ2VQb2ludGVyICs9IHN0ZXAsIGFJbWFnZVBvaW50ZXIgKz0gc3RlcCwgaSsrXG4gICAgKSB7XG4gICAgICBpbWFnZS5kYXRhW3JJbWFnZVBvaW50ZXJdID0gKCh0ZW5zb3IuZGF0YVtyVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbMF0pICogbm9ybU1lYW5bMF07IC8vIFIgdmFsdWVcbiAgICAgIGltYWdlLmRhdGFbZ0ltYWdlUG9pbnRlcl0gPSAoKHRlbnNvci5kYXRhW2dUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1sxXSkgKiBub3JtTWVhblsxXTsgLy8gRyB2YWx1ZVxuICAgICAgaW1hZ2UuZGF0YVtiSW1hZ2VQb2ludGVyXSA9ICgodGVuc29yLmRhdGFbYlRlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzJdKSAqIG5vcm1NZWFuWzJdOyAvLyBCIHZhbHVlXG4gICAgICBpbWFnZS5kYXRhW2FJbWFnZVBvaW50ZXJdID1cbiAgICAgICAgYVRlbnNvclBvaW50ZXIgPT09IC0xID8gMjU1IDogKCh0ZW5zb3IuZGF0YVthVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbM10pICogbm9ybU1lYW5bM107IC8vIEEgdmFsdWVcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gbm90IGFjY2VzcyBpbWFnZSBkYXRhJyk7XG4gIH1cbiAgcmV0dXJuIGltYWdlO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtcbiAgT3B0aW9uc0RpbWVuc2lvbnMsXG4gIE9wdGlvbnNGb3JtYXQsXG4gIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyxcbiAgT3B0aW9uc1RlbnNvckZvcm1hdCxcbiAgT3B0aW9uc1RlbnNvckxheW91dCxcbiAgVGVuc29yRnJvbUdwdUJ1ZmZlck9wdGlvbnMsXG4gIFRlbnNvckZyb21JbWFnZUJpdG1hcE9wdGlvbnMsXG4gIFRlbnNvckZyb21JbWFnZURhdGFPcHRpb25zLFxuICBUZW5zb3JGcm9tSW1hZ2VFbGVtZW50T3B0aW9ucyxcbiAgVGVuc29yRnJvbU1MVGVuc29yT3B0aW9ucyxcbiAgVGVuc29yRnJvbVRleHR1cmVPcHRpb25zLFxuICBUZW5zb3JGcm9tVXJsT3B0aW9ucyxcbn0gZnJvbSAnLi90ZW5zb3ItZmFjdG9yeS5qcyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvci1pbXBsLmpzJztcbmltcG9ydCB7IFRlbnNvciBhcyBUZW5zb3JJbnRlcmZhY2UgfSBmcm9tICcuL3RlbnNvci5qcyc7XG5cbmludGVyZmFjZSBCdWZmZXJUb1RlbnNvck9wdGlvbnNcbiAgZXh0ZW5kcyBPcHRpb25zRGltZW5zaW9ucyxcbiAgICBPcHRpb25zVGVuc29yTGF5b3V0LFxuICAgIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyxcbiAgICBPcHRpb25zRm9ybWF0LFxuICAgIE9wdGlvbnNUZW5zb3JGb3JtYXQge31cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIGltYWdlIG9iamVjdFxuICpcbiAqIEBwYXJhbSBidWZmZXIgLSBFeHRyYWN0ZWQgaW1hZ2UgYnVmZmVyIGRhdGEgLSBhc3N1bWluZyBSR0JBIGZvcm1hdFxuICogQHBhcmFtIGltYWdlRm9ybWF0IC0gaW5wdXQgaW1hZ2UgY29uZmlndXJhdGlvbiAtIHJlcXVpcmVkIGNvbmZpZ3VyYXRpb25zIGhlaWdodCwgd2lkdGgsIGZvcm1hdFxuICogQHBhcmFtIHRlbnNvckZvcm1hdCAtIG91dHB1dCB0ZW5zb3IgY29uZmlndXJhdGlvbiAtIERlZmF1bHQgaXMgUkdCIGZvcm1hdFxuICovXG5leHBvcnQgY29uc3QgYnVmZmVyVG9UZW5zb3IgPSAoYnVmZmVyOiBVaW50OENsYW1wZWRBcnJheSB8IHVuZGVmaW5lZCwgb3B0aW9uczogQnVmZmVyVG9UZW5zb3JPcHRpb25zKTogVGVuc29yID0+IHtcbiAgaWYgKGJ1ZmZlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbWFnZSBidWZmZXIgbXVzdCBiZSBkZWZpbmVkJyk7XG4gIH1cbiAgaWYgKG9wdGlvbnMuaGVpZ2h0ID09PSB1bmRlZmluZWQgfHwgb3B0aW9ucy53aWR0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbWFnZSBoZWlnaHQgYW5kIHdpZHRoIG11c3QgYmUgZGVmaW5lZCcpO1xuICB9XG4gIGlmIChvcHRpb25zLnRlbnNvckxheW91dCA9PT0gJ05IV0MnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdOSFdDIFRlbnNvciBsYXlvdXQgaXMgbm90IHN1cHBvcnRlZCB5ZXQnKTtcbiAgfVxuXG4gIGNvbnN0IHsgaGVpZ2h0LCB3aWR0aCB9ID0gb3B0aW9ucztcblxuICBjb25zdCBub3JtID0gb3B0aW9ucy5ub3JtID8/IHsgbWVhbjogMjU1LCBiaWFzOiAwIH07XG4gIGxldCBub3JtTWVhbjogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gIGxldCBub3JtQmlhczogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG5cbiAgaWYgKHR5cGVvZiBub3JtLm1lYW4gPT09ICdudW1iZXInKSB7XG4gICAgbm9ybU1lYW4gPSBbbm9ybS5tZWFuLCBub3JtLm1lYW4sIG5vcm0ubWVhbiwgbm9ybS5tZWFuXTtcbiAgfSBlbHNlIHtcbiAgICBub3JtTWVhbiA9IFtub3JtLm1lYW4hWzBdLCBub3JtLm1lYW4hWzFdLCBub3JtLm1lYW4hWzJdLCBub3JtLm1lYW4hWzNdID8/IDI1NV07XG4gIH1cblxuICBpZiAodHlwZW9mIG5vcm0uYmlhcyA9PT0gJ251bWJlcicpIHtcbiAgICBub3JtQmlhcyA9IFtub3JtLmJpYXMsIG5vcm0uYmlhcywgbm9ybS5iaWFzLCBub3JtLmJpYXNdO1xuICB9IGVsc2Uge1xuICAgIG5vcm1CaWFzID0gW25vcm0uYmlhcyFbMF0sIG5vcm0uYmlhcyFbMV0sIG5vcm0uYmlhcyFbMl0sIG5vcm0uYmlhcyFbM10gPz8gMF07XG4gIH1cblxuICBjb25zdCBpbnB1dGZvcm1hdCA9IG9wdGlvbnMuZm9ybWF0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmZvcm1hdCA6ICdSR0JBJztcbiAgLy8gZGVmYXVsdCB2YWx1ZSBpcyBSR0JBIHNpbmNlIGltYWdlZGF0YSBhbmQgSFRNTEltYWdlRWxlbWVudCB1c2VzIGl0XG5cbiAgY29uc3Qgb3V0cHV0Zm9ybWF0ID1cbiAgICBvcHRpb25zLnRlbnNvckZvcm1hdCAhPT0gdW5kZWZpbmVkID8gKG9wdGlvbnMudGVuc29yRm9ybWF0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnRlbnNvckZvcm1hdCA6ICdSR0InKSA6ICdSR0InO1xuICBjb25zdCBzdHJpZGUgPSBoZWlnaHQgKiB3aWR0aDtcbiAgY29uc3QgZmxvYXQzMkRhdGEgPSBvdXRwdXRmb3JtYXQgPT09ICdSR0JBJyA/IG5ldyBGbG9hdDMyQXJyYXkoc3RyaWRlICogNCkgOiBuZXcgRmxvYXQzMkFycmF5KHN0cmlkZSAqIDMpO1xuXG4gIC8vIERlZmF1bHQgcG9pbnRlciBhc3NpZ25tZW50c1xuICBsZXQgc3RlcCA9IDQsXG4gICAgckltYWdlUG9pbnRlciA9IDAsXG4gICAgZ0ltYWdlUG9pbnRlciA9IDEsXG4gICAgYkltYWdlUG9pbnRlciA9IDIsXG4gICAgYUltYWdlUG9pbnRlciA9IDM7XG4gIGxldCByVGVuc29yUG9pbnRlciA9IDAsXG4gICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGUsXG4gICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyLFxuICAgIGFUZW5zb3JQb2ludGVyID0gLTE7XG5cbiAgLy8gVXBkYXRpbmcgdGhlIHBvaW50ZXIgYXNzaWdubWVudHMgYmFzZWQgb24gdGhlIGlucHV0IGltYWdlIGZvcm1hdFxuICBpZiAoaW5wdXRmb3JtYXQgPT09ICdSR0InKSB7XG4gICAgc3RlcCA9IDM7XG4gICAgckltYWdlUG9pbnRlciA9IDA7XG4gICAgZ0ltYWdlUG9pbnRlciA9IDE7XG4gICAgYkltYWdlUG9pbnRlciA9IDI7XG4gICAgYUltYWdlUG9pbnRlciA9IC0xO1xuICB9XG5cbiAgLy8gVXBkYXRpbmcgdGhlIHBvaW50ZXIgYXNzaWdubWVudHMgYmFzZWQgb24gdGhlIG91dHB1dCB0ZW5zb3IgZm9ybWF0XG4gIGlmIChvdXRwdXRmb3JtYXQgPT09ICdSR0JBJykge1xuICAgIGFUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMztcbiAgfSBlbHNlIGlmIChvdXRwdXRmb3JtYXQgPT09ICdSQkcnKSB7XG4gICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgfSBlbHNlIGlmIChvdXRwdXRmb3JtYXQgPT09ICdCR1InKSB7XG4gICAgYlRlbnNvclBvaW50ZXIgPSAwO1xuICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgIHJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgfVxuXG4gIGZvciAoXG4gICAgbGV0IGkgPSAwO1xuICAgIGkgPCBzdHJpZGU7XG4gICAgaSsrLCBySW1hZ2VQb2ludGVyICs9IHN0ZXAsIGJJbWFnZVBvaW50ZXIgKz0gc3RlcCwgZ0ltYWdlUG9pbnRlciArPSBzdGVwLCBhSW1hZ2VQb2ludGVyICs9IHN0ZXBcbiAgKSB7XG4gICAgZmxvYXQzMkRhdGFbclRlbnNvclBvaW50ZXIrK10gPSAoYnVmZmVyW3JJbWFnZVBvaW50ZXJdICsgbm9ybUJpYXNbMF0pIC8gbm9ybU1lYW5bMF07XG4gICAgZmxvYXQzMkRhdGFbZ1RlbnNvclBvaW50ZXIrK10gPSAoYnVmZmVyW2dJbWFnZVBvaW50ZXJdICsgbm9ybUJpYXNbMV0pIC8gbm9ybU1lYW5bMV07XG4gICAgZmxvYXQzMkRhdGFbYlRlbnNvclBvaW50ZXIrK10gPSAoYnVmZmVyW2JJbWFnZVBvaW50ZXJdICsgbm9ybUJpYXNbMl0pIC8gbm9ybU1lYW5bMl07XG4gICAgaWYgKGFUZW5zb3JQb2ludGVyICE9PSAtMSAmJiBhSW1hZ2VQb2ludGVyICE9PSAtMSkge1xuICAgICAgZmxvYXQzMkRhdGFbYVRlbnNvclBvaW50ZXIrK10gPSAoYnVmZmVyW2FJbWFnZVBvaW50ZXJdICsgbm9ybUJpYXNbM10pIC8gbm9ybU1lYW5bM107XG4gICAgfVxuICB9XG5cbiAgLy8gRmxvYXQzMkFycmF5IC0+IG9ydC5UZW5zb3JcbiAgY29uc3Qgb3V0cHV0VGVuc29yID1cbiAgICBvdXRwdXRmb3JtYXQgPT09ICdSR0JBJ1xuICAgICAgPyBuZXcgVGVuc29yKCdmbG9hdDMyJywgZmxvYXQzMkRhdGEsIFsxLCA0LCBoZWlnaHQsIHdpZHRoXSlcbiAgICAgIDogbmV3IFRlbnNvcignZmxvYXQzMicsIGZsb2F0MzJEYXRhLCBbMSwgMywgaGVpZ2h0LCB3aWR0aF0pO1xuICByZXR1cm4gb3V0cHV0VGVuc29yO1xufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IuZnJvbUltYWdlKCkuXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JGcm9tSW1hZ2UgPSBhc3luYyAoXG4gIGltYWdlOiBJbWFnZURhdGEgfCBIVE1MSW1hZ2VFbGVtZW50IHwgSW1hZ2VCaXRtYXAgfCBzdHJpbmcsXG4gIG9wdGlvbnM/OlxuICAgIHwgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnNcbiAgICB8IFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zXG4gICAgfCBUZW5zb3JGcm9tSW1hZ2VCaXRtYXBPcHRpb25zXG4gICAgfCBUZW5zb3JGcm9tVXJsT3B0aW9ucyxcbik6IFByb21pc2U8VGVuc29yPiA9PiB7XG4gIC8vIGNoZWNraW5nIHRoZSB0eXBlIG9mIGltYWdlIG9iamVjdFxuICBjb25zdCBpc0hUTUxJbWFnZUVsZSA9IHR5cGVvZiBIVE1MSW1hZ2VFbGVtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBpbWFnZSBpbnN0YW5jZW9mIEhUTUxJbWFnZUVsZW1lbnQ7XG4gIGNvbnN0IGlzSW1hZ2VEYXRhRWxlID0gdHlwZW9mIEltYWdlRGF0YSAhPT0gJ3VuZGVmaW5lZCcgJiYgaW1hZ2UgaW5zdGFuY2VvZiBJbWFnZURhdGE7XG4gIGNvbnN0IGlzSW1hZ2VCaXRtYXAgPSB0eXBlb2YgSW1hZ2VCaXRtYXAgIT09ICd1bmRlZmluZWQnICYmIGltYWdlIGluc3RhbmNlb2YgSW1hZ2VCaXRtYXA7XG4gIGNvbnN0IGlzU3RyaW5nID0gdHlwZW9mIGltYWdlID09PSAnc3RyaW5nJztcblxuICBsZXQgZGF0YTogVWludDhDbGFtcGVkQXJyYXkgfCB1bmRlZmluZWQ7XG4gIGxldCBidWZmZXJUb1RlbnNvck9wdGlvbnM6IEJ1ZmZlclRvVGVuc29yT3B0aW9ucyA9IG9wdGlvbnMgPz8ge307XG5cbiAgY29uc3QgY3JlYXRlQ2FudmFzID0gKCkgPT4ge1xuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgT2Zmc2NyZWVuQ2FudmFzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIG5ldyBPZmZzY3JlZW5DYW52YXMoMSwgMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2FudmFzIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH07XG4gIGNvbnN0IGNyZWF0ZUNhbnZhc0NvbnRleHQgPSAoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IE9mZnNjcmVlbkNhbnZhcykgPT4ge1xuICAgIGlmICh0eXBlb2YgSFRNTENhbnZhc0VsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIGNhbnZhcyBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KSB7XG4gICAgICByZXR1cm4gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgfSBlbHNlIGlmIChjYW52YXMgaW5zdGFuY2VvZiBPZmZzY3JlZW5DYW52YXMpIHtcbiAgICAgIHJldHVybiBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKSBhcyBPZmZzY3JlZW5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfTtcbiAgLy8gZmlsbGluZyBhbmQgY2hlY2tpbmcgaW1hZ2UgY29uZmlndXJhdGlvbiBvcHRpb25zXG4gIGlmIChpc0hUTUxJbWFnZUVsZSkge1xuICAgIC8vIEhUTUxJbWFnZUVsZW1lbnQgLSBpbWFnZSBvYmplY3QgLSBmb3JtYXQgaXMgUkdCQSBieSBkZWZhdWx0XG4gICAgY29uc3QgY2FudmFzID0gY3JlYXRlQ2FudmFzKCk7XG4gICAgY2FudmFzLndpZHRoID0gaW1hZ2Uud2lkdGg7XG4gICAgY2FudmFzLmhlaWdodCA9IGltYWdlLmhlaWdodDtcbiAgICBjb25zdCBwaXhlbHMyRENvbnRleHQgPSBjcmVhdGVDYW52YXNDb250ZXh0KGNhbnZhcyk7XG5cbiAgICBpZiAocGl4ZWxzMkRDb250ZXh0ICE9IG51bGwpIHtcbiAgICAgIGxldCBoZWlnaHQgPSBpbWFnZS5oZWlnaHQ7XG4gICAgICBsZXQgd2lkdGggPSBpbWFnZS53aWR0aDtcbiAgICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy5yZXNpemVkSGVpZ2h0ICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy5yZXNpemVkV2lkdGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBoZWlnaHQgPSBvcHRpb25zLnJlc2l6ZWRIZWlnaHQ7XG4gICAgICAgIHdpZHRoID0gb3B0aW9ucy5yZXNpemVkV2lkdGg7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zID0gb3B0aW9ucztcbiAgICAgICAgaWYgKG9wdGlvbnMudGVuc29yRm9ybWF0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltYWdlIGlucHV0IGNvbmZpZyBmb3JtYXQgbXVzdCBiZSBSR0JBIGZvciBIVE1MSW1hZ2VFbGVtZW50Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLnRlbnNvckZvcm1hdCA9ICdSR0JBJztcbiAgICAgICAgfVxuICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMud2lkdGggPSB3aWR0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy50ZW5zb3JGb3JtYXQgPSAnUkdCQSc7XG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy53aWR0aCA9IHdpZHRoO1xuICAgICAgfVxuXG4gICAgICBwaXhlbHMyRENvbnRleHQuZHJhd0ltYWdlKGltYWdlLCAwLCAwKTtcbiAgICAgIGRhdGEgPSBwaXhlbHMyRENvbnRleHQuZ2V0SW1hZ2VEYXRhKDAsIDAsIHdpZHRoLCBoZWlnaHQpLmRhdGE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBhY2Nlc3MgaW1hZ2UgZGF0YScpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc0ltYWdlRGF0YUVsZSkge1xuICAgIGxldCBoZWlnaHQ6IG51bWJlcjtcbiAgICBsZXQgd2lkdGg6IG51bWJlcjtcblxuICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy5yZXNpemVkV2lkdGggIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnJlc2l6ZWRIZWlnaHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaGVpZ2h0ID0gb3B0aW9ucy5yZXNpemVkSGVpZ2h0O1xuICAgICAgd2lkdGggPSBvcHRpb25zLnJlc2l6ZWRXaWR0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgaGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xuICAgICAgd2lkdGggPSBpbWFnZS53aWR0aDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMgPSBvcHRpb25zO1xuICAgIH1cbiAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMuZm9ybWF0ID0gJ1JHQkEnO1xuICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLndpZHRoID0gd2lkdGg7XG5cbiAgICBpZiAob3B0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCB0ZW1wQ2FudmFzID0gY3JlYXRlQ2FudmFzKCk7XG5cbiAgICAgIHRlbXBDYW52YXMud2lkdGggPSB3aWR0aDtcbiAgICAgIHRlbXBDYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuXG4gICAgICBjb25zdCBwaXhlbHMyRENvbnRleHQgPSBjcmVhdGVDYW52YXNDb250ZXh0KHRlbXBDYW52YXMpO1xuXG4gICAgICBpZiAocGl4ZWxzMkRDb250ZXh0ICE9IG51bGwpIHtcbiAgICAgICAgcGl4ZWxzMkRDb250ZXh0LnB1dEltYWdlRGF0YShpbWFnZSwgMCwgMCk7XG4gICAgICAgIGRhdGEgPSBwaXhlbHMyRENvbnRleHQuZ2V0SW1hZ2VEYXRhKDAsIDAsIHdpZHRoLCBoZWlnaHQpLmRhdGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBub3QgYWNjZXNzIGltYWdlIGRhdGEnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YSA9IGltYWdlLmRhdGE7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzSW1hZ2VCaXRtYXApIHtcbiAgICAvLyBJbWFnZUJpdG1hcCAtIGltYWdlIG9iamVjdCAtIGZvcm1hdCBtdXN0IGJlIHByb3ZpZGVkIGJ5IHVzZXJcbiAgICBpZiAob3B0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBwcm92aWRlIGltYWdlIGNvbmZpZyB3aXRoIGZvcm1hdCBmb3IgSW1hZ2ViaXRtYXAnKTtcbiAgICB9XG5cbiAgICBjb25zdCBjYW52YXMgPSBjcmVhdGVDYW52YXMoKTtcbiAgICBjYW52YXMud2lkdGggPSBpbWFnZS53aWR0aDtcbiAgICBjYW52YXMuaGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xuICAgIGNvbnN0IHBpeGVsczJEQ29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQoY2FudmFzKTtcblxuICAgIGlmIChwaXhlbHMyRENvbnRleHQgIT0gbnVsbCkge1xuICAgICAgY29uc3QgaGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xuICAgICAgY29uc3Qgd2lkdGggPSBpbWFnZS53aWR0aDtcbiAgICAgIHBpeGVsczJEQ29udGV4dC5kcmF3SW1hZ2UoaW1hZ2UsIDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuICAgICAgZGF0YSA9IHBpeGVsczJEQ29udGV4dC5nZXRJbWFnZURhdGEoMCwgMCwgd2lkdGgsIGhlaWdodCkuZGF0YTtcbiAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMud2lkdGggPSB3aWR0aDtcbiAgICAgIHJldHVybiBidWZmZXJUb1RlbnNvcihkYXRhLCBidWZmZXJUb1RlbnNvck9wdGlvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBub3QgYWNjZXNzIGltYWdlIGRhdGEnKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNTdHJpbmcpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgY2FudmFzID0gY3JlYXRlQ2FudmFzKCk7XG4gICAgICBjb25zdCBjb250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dChjYW52YXMpO1xuICAgICAgaWYgKCFpbWFnZSB8fCAhY29udGV4dCkge1xuICAgICAgICByZXR1cm4gcmVqZWN0KCk7XG4gICAgICB9XG4gICAgICBjb25zdCBuZXdJbWFnZSA9IG5ldyBJbWFnZSgpO1xuICAgICAgbmV3SW1hZ2UuY3Jvc3NPcmlnaW4gPSAnQW5vbnltb3VzJztcbiAgICAgIG5ld0ltYWdlLnNyYyA9IGltYWdlO1xuICAgICAgbmV3SW1hZ2Uub25sb2FkID0gKCkgPT4ge1xuICAgICAgICBjYW52YXMud2lkdGggPSBuZXdJbWFnZS53aWR0aDtcbiAgICAgICAgY2FudmFzLmhlaWdodCA9IG5ld0ltYWdlLmhlaWdodDtcbiAgICAgICAgY29udGV4dC5kcmF3SW1hZ2UobmV3SW1hZ2UsIDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XG4gICAgICAgIGNvbnN0IGltZyA9IGNvbnRleHQuZ2V0SW1hZ2VEYXRhKDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XG5cbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLmhlaWdodCA9IGNhbnZhcy5oZWlnaHQ7XG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy53aWR0aCA9IGNhbnZhcy53aWR0aDtcbiAgICAgICAgcmVzb2x2ZShidWZmZXJUb1RlbnNvcihpbWcuZGF0YSwgYnVmZmVyVG9UZW5zb3JPcHRpb25zKSk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgZGF0YSBwcm92aWRlZCBpcyBub3Qgc3VwcG9ydGVkIC0gYWJvcnRlZCB0ZW5zb3IgY3JlYXRpb24nKTtcbiAgfVxuXG4gIGlmIChkYXRhICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gYnVmZmVyVG9UZW5zb3IoZGF0YSwgYnVmZmVyVG9UZW5zb3JPcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGRhdGEgcHJvdmlkZWQgaXMgbm90IHN1cHBvcnRlZCAtIGFib3J0ZWQgdGVuc29yIGNyZWF0aW9uJyk7XG4gIH1cbn07XG5cbi8qKlxuICogaW1wbGVtZW50YXRpb24gb2YgVGVuc29yLmZyb21UZXh0dXJlKCkuXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JGcm9tVGV4dHVyZSA9IDxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLlRleHR1cmVEYXRhVHlwZXM+KFxuICB0ZXh0dXJlOiBUZW5zb3JJbnRlcmZhY2UuVGV4dHVyZVR5cGUsXG4gIG9wdGlvbnM6IFRlbnNvckZyb21UZXh0dXJlT3B0aW9uczxUPixcbik6IFRlbnNvciA9PiB7XG4gIGNvbnN0IHsgd2lkdGgsIGhlaWdodCwgZG93bmxvYWQsIGRpc3Bvc2UgfSA9IG9wdGlvbnM7XG4gIC8vIEFsd2F5cyBhc3N1bWUgUkdCQUYzMi4gVE9ETzogc3VwcG9ydCBkaWZmZXJlbnQgdGV4dHVyZSBmb3JtYXRcbiAgY29uc3QgZGltcyA9IFsxLCBoZWlnaHQsIHdpZHRoLCA0XTtcbiAgcmV0dXJuIG5ldyBUZW5zb3IoeyBsb2NhdGlvbjogJ3RleHR1cmUnLCB0eXBlOiAnZmxvYXQzMicsIHRleHR1cmUsIGRpbXMsIGRvd25sb2FkLCBkaXNwb3NlIH0pO1xufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IuZnJvbUdwdUJ1ZmZlcigpLlxuICovXG5leHBvcnQgY29uc3QgdGVuc29yRnJvbUdwdUJ1ZmZlciA9IDxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLkdwdUJ1ZmZlckRhdGFUeXBlcz4oXG4gIGdwdUJ1ZmZlcjogVGVuc29ySW50ZXJmYWNlLkdwdUJ1ZmZlclR5cGUsXG4gIG9wdGlvbnM6IFRlbnNvckZyb21HcHVCdWZmZXJPcHRpb25zPFQ+LFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgeyBkYXRhVHlwZSwgZGltcywgZG93bmxvYWQsIGRpc3Bvc2UgfSA9IG9wdGlvbnM7XG4gIHJldHVybiBuZXcgVGVuc29yKHsgbG9jYXRpb246ICdncHUtYnVmZmVyJywgdHlwZTogZGF0YVR5cGUgPz8gJ2Zsb2F0MzInLCBncHVCdWZmZXIsIGRpbXMsIGRvd25sb2FkLCBkaXNwb3NlIH0pO1xufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IuZnJvbU1MVGVuc29yKCkuXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JGcm9tTUxUZW5zb3IgPSA8VCBleHRlbmRzIFRlbnNvckludGVyZmFjZS5NTFRlbnNvckRhdGFUeXBlcz4oXG4gIG1sVGVuc29yOiBUZW5zb3JJbnRlcmZhY2UuTUxUZW5zb3JUeXBlLFxuICBvcHRpb25zOiBUZW5zb3JGcm9tTUxUZW5zb3JPcHRpb25zPFQ+LFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgeyBkYXRhVHlwZSwgZGltcywgZG93bmxvYWQsIGRpc3Bvc2UgfSA9IG9wdGlvbnM7XG4gIHJldHVybiBuZXcgVGVuc29yKHsgbG9jYXRpb246ICdtbC10ZW5zb3InLCB0eXBlOiBkYXRhVHlwZSA/PyAnZmxvYXQzMicsIG1sVGVuc29yLCBkaW1zLCBkb3dubG9hZCwgZGlzcG9zZSB9KTtcbn07XG5cbi8qKlxuICogaW1wbGVtZW50YXRpb24gb2YgVGVuc29yLmZyb21QaW5uZWRCdWZmZXIoKS5cbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvckZyb21QaW5uZWRCdWZmZXIgPSA8VCBleHRlbmRzIFRlbnNvckludGVyZmFjZS5DcHVQaW5uZWREYXRhVHlwZXM+KFxuICB0eXBlOiBULFxuICBidWZmZXI6IFRlbnNvckludGVyZmFjZS5EYXRhVHlwZU1hcFtUXSxcbiAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuKTogVGVuc29yID0+IG5ldyBUZW5zb3IoeyBsb2NhdGlvbjogJ2NwdS1waW5uZWQnLCB0eXBlLCBkYXRhOiBidWZmZXIsIGRpbXM6IGRpbXMgPz8gW2J1ZmZlci5sZW5ndGhdIH0pO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvci5qcyc7XG5cbmV4cG9ydCB0eXBlIFN1cHBvcnRlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvcnMgPVxuICB8IEZsb2F0MzJBcnJheUNvbnN0cnVjdG9yXG4gIHwgVWludDhBcnJheUNvbnN0cnVjdG9yXG4gIHwgSW50OEFycmF5Q29uc3RydWN0b3JcbiAgfCBVaW50MTZBcnJheUNvbnN0cnVjdG9yXG4gIHwgSW50MTZBcnJheUNvbnN0cnVjdG9yXG4gIHwgSW50MzJBcnJheUNvbnN0cnVjdG9yXG4gIHwgQmlnSW50NjRBcnJheUNvbnN0cnVjdG9yXG4gIHwgVWludDhBcnJheUNvbnN0cnVjdG9yXG4gIHwgRmxvYXQ2NEFycmF5Q29uc3RydWN0b3JcbiAgfCBVaW50MzJBcnJheUNvbnN0cnVjdG9yXG4gIHwgQmlnVWludDY0QXJyYXlDb25zdHJ1Y3RvcjtcbmV4cG9ydCB0eXBlIFN1cHBvcnRlZFR5cGVkQXJyYXkgPSBJbnN0YW5jZVR5cGU8U3VwcG9ydGVkVHlwZWRBcnJheUNvbnN0cnVjdG9ycz47XG5cbi8vIGEgcnVudGltZSBtYXAgdGhhdCBtYXBzIHR5cGUgc3RyaW5nIHRvIFR5cGVkQXJyYXkgY29uc3RydWN0b3IuIFNob3VsZCBtYXRjaCBUZW5zb3IuRGF0YVR5cGVNYXAuXG5leHBvcnQgY29uc3QgTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUCA9IG5ldyBNYXA8c3RyaW5nLCBTdXBwb3J0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3JzPihbXG4gIFsnZmxvYXQzMicsIEZsb2F0MzJBcnJheV0sXG4gIFsndWludDgnLCBVaW50OEFycmF5XSxcbiAgWydpbnQ4JywgSW50OEFycmF5XSxcbiAgWyd1aW50MTYnLCBVaW50MTZBcnJheV0sXG4gIFsnaW50MTYnLCBJbnQxNkFycmF5XSxcbiAgWydpbnQzMicsIEludDMyQXJyYXldLFxuICBbJ2Jvb2wnLCBVaW50OEFycmF5XSxcbiAgWydmbG9hdDY0JywgRmxvYXQ2NEFycmF5XSxcbiAgWyd1aW50MzInLCBVaW50MzJBcnJheV0sXG4gIFsnaW50NCcsIFVpbnQ4QXJyYXldLFxuICBbJ3VpbnQ0JywgVWludDhBcnJheV0sXG5dKTtcblxuLy8gYSBydW50aW1lIG1hcCB0aGF0IG1hcHMgdHlwZSBzdHJpbmcgdG8gVHlwZWRBcnJheSBjb25zdHJ1Y3Rvci4gU2hvdWxkIG1hdGNoIFRlbnNvci5EYXRhVHlwZU1hcC5cbmV4cG9ydCBjb25zdCBOVU1FUklDX1RFTlNPUl9UWVBFREFSUkFZX1RPX1RZUEVfTUFQID0gbmV3IE1hcDxTdXBwb3J0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3JzLCBUZW5zb3IuVHlwZT4oW1xuICBbRmxvYXQzMkFycmF5LCAnZmxvYXQzMiddLFxuICBbVWludDhBcnJheSwgJ3VpbnQ4J10sXG4gIFtJbnQ4QXJyYXksICdpbnQ4J10sXG4gIFtVaW50MTZBcnJheSwgJ3VpbnQxNiddLFxuICBbSW50MTZBcnJheSwgJ2ludDE2J10sXG4gIFtJbnQzMkFycmF5LCAnaW50MzInXSxcbiAgW0Zsb2F0NjRBcnJheSwgJ2Zsb2F0NjQnXSxcbiAgW1VpbnQzMkFycmF5LCAndWludDMyJ10sXG5dKTtcblxuLy8gdGhlIGZvbGxvd2luZyBjb2RlIGFsbG93cyBkZWxheWluZyBleGVjdXRpb24gb2YgQmlnSW50L0Zsb2F0MTZBcnJheSBjaGVja2luZy4gVGhpcyBhbGxvd3MgbGF6eSBpbml0aWFsaXphdGlvbiBmb3Jcbi8vIE5VTUVSSUNfVEVOU09SX1RZUEVfVE9fVFlQRURBUlJBWV9NQVAgYW5kIE5VTUVSSUNfVEVOU09SX1RZUEVEQVJSQVlfVE9fVFlQRV9NQVAsIHdoaWNoIGFsbG93cyBCaWdJbnQvRmxvYXQxNkFycmF5XG4vLyBwb2x5ZmlsbCBpZiBhdmFpbGFibGUuXG5sZXQgaXNUeXBlZEFycmF5Q2hlY2tlZCA9IGZhbHNlO1xuZXhwb3J0IGNvbnN0IGNoZWNrVHlwZWRBcnJheSA9ICgpID0+IHtcbiAgaWYgKCFpc1R5cGVkQXJyYXlDaGVja2VkKSB7XG4gICAgaXNUeXBlZEFycmF5Q2hlY2tlZCA9IHRydWU7XG4gICAgY29uc3QgaXNCaWdJbnQ2NEFycmF5QXZhaWxhYmxlID0gdHlwZW9mIEJpZ0ludDY0QXJyYXkgIT09ICd1bmRlZmluZWQnICYmIEJpZ0ludDY0QXJyYXkuZnJvbTtcbiAgICBjb25zdCBpc0JpZ1VpbnQ2NEFycmF5QXZhaWxhYmxlID0gdHlwZW9mIEJpZ1VpbnQ2NEFycmF5ICE9PSAndW5kZWZpbmVkJyAmJiBCaWdVaW50NjRBcnJheS5mcm9tO1xuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiwgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IEZsb2F0MTZBcnJheSA9IChnbG9iYWxUaGlzIGFzIGFueSkuRmxvYXQxNkFycmF5O1xuICAgIGNvbnN0IGlzRmxvYXQxNkFycmF5QXZhaWxhYmxlID0gdHlwZW9mIEZsb2F0MTZBcnJheSAhPT0gJ3VuZGVmaW5lZCcgJiYgRmxvYXQxNkFycmF5LmZyb207XG5cbiAgICBpZiAoaXNCaWdJbnQ2NEFycmF5QXZhaWxhYmxlKSB7XG4gICAgICBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQLnNldCgnaW50NjQnLCBCaWdJbnQ2NEFycmF5KTtcbiAgICAgIE5VTUVSSUNfVEVOU09SX1RZUEVEQVJSQVlfVE9fVFlQRV9NQVAuc2V0KEJpZ0ludDY0QXJyYXksICdpbnQ2NCcpO1xuICAgIH1cbiAgICBpZiAoaXNCaWdVaW50NjRBcnJheUF2YWlsYWJsZSkge1xuICAgICAgTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUC5zZXQoJ3VpbnQ2NCcsIEJpZ1VpbnQ2NEFycmF5KTtcbiAgICAgIE5VTUVSSUNfVEVOU09SX1RZUEVEQVJSQVlfVE9fVFlQRV9NQVAuc2V0KEJpZ1VpbnQ2NEFycmF5LCAndWludDY0Jyk7XG4gICAgfVxuICAgIGlmIChpc0Zsb2F0MTZBcnJheUF2YWlsYWJsZSkge1xuICAgICAgTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUC5zZXQoJ2Zsb2F0MTYnLCBGbG9hdDE2QXJyYXkpO1xuICAgICAgTlVNRVJJQ19URU5TT1JfVFlQRURBUlJBWV9UT19UWVBFX01BUC5zZXQoRmxvYXQxNkFycmF5LCAnZmxvYXQxNicpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBpZiBGbG9hdDE2QXJyYXkgaXMgbm90IGF2YWlsYWJsZSwgdXNlICdVaW50MTZBcnJheScgdG8gc3RvcmUgdGhlIGRhdGEuXG4gICAgICBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQLnNldCgnZmxvYXQxNicsIFVpbnQxNkFycmF5KTtcbiAgICB9XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7XG4gIENwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVycyxcbiAgR3B1QnVmZmVyQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxuICBNTFRlbnNvckNvbnN0cnVjdG9yUGFyYW1ldGVycyxcbiAgVGV4dHVyZUNvbnN0cnVjdG9yUGFyYW1ldGVycyxcbn0gZnJvbSAnLi90ZW5zb3ItZmFjdG9yeS5qcyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvci1pbXBsLmpzJztcblxuLyoqXG4gKiBjYWxjdWxhdGUgc2l6ZSBmcm9tIGRpbXMuXG4gKlxuICogQHBhcmFtIGRpbXMgdGhlIGRpbXMgYXJyYXkuIE1heSBiZSBhbiBpbGxlZ2FsIGlucHV0LlxuICovXG5leHBvcnQgY29uc3QgY2FsY3VsYXRlU2l6ZSA9IChkaW1zOiByZWFkb25seSB1bmtub3duW10pOiBudW1iZXIgPT4ge1xuICBsZXQgc2l6ZSA9IDE7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZGltcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGRpbSA9IGRpbXNbaV07XG4gICAgaWYgKHR5cGVvZiBkaW0gIT09ICdudW1iZXInIHx8ICFOdW1iZXIuaXNTYWZlSW50ZWdlcihkaW0pKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBkaW1zWyR7aX1dIG11c3QgYmUgYW4gaW50ZWdlciwgZ290OiAke2RpbX1gKTtcbiAgICB9XG4gICAgaWYgKGRpbSA8IDApIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBkaW1zWyR7aX1dIG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50ZWdlciwgZ290OiAke2RpbX1gKTtcbiAgICB9XG4gICAgc2l6ZSAqPSBkaW07XG4gIH1cbiAgcmV0dXJuIHNpemU7XG59O1xuXG4vKipcbiAqIGltcGxlbWVudGF0aW9uIG9mIFRlbnNvci5yZXNoYXBlKClcbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvclJlc2hhcGUgPSAodGVuc29yOiBUZW5zb3IsIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yID0+IHtcbiAgc3dpdGNoICh0ZW5zb3IubG9jYXRpb24pIHtcbiAgICBjYXNlICdjcHUnOlxuICAgICAgcmV0dXJuIG5ldyBUZW5zb3IodGVuc29yLnR5cGUsIHRlbnNvci5kYXRhLCBkaW1zKTtcbiAgICBjYXNlICdjcHUtcGlubmVkJzpcbiAgICAgIHJldHVybiBuZXcgVGVuc29yKHtcbiAgICAgICAgbG9jYXRpb246ICdjcHUtcGlubmVkJyxcbiAgICAgICAgZGF0YTogdGVuc29yLmRhdGEgYXMgQ3B1UGlubmVkQ29uc3RydWN0b3JQYXJhbWV0ZXJzWydkYXRhJ10sXG4gICAgICAgIHR5cGU6IHRlbnNvci50eXBlIGFzIENwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVyc1sndHlwZSddLFxuICAgICAgICBkaW1zLFxuICAgICAgfSk7XG4gICAgY2FzZSAndGV4dHVyZSc6XG4gICAgICByZXR1cm4gbmV3IFRlbnNvcih7XG4gICAgICAgIGxvY2F0aW9uOiAndGV4dHVyZScsXG4gICAgICAgIHRleHR1cmU6IHRlbnNvci50ZXh0dXJlLFxuICAgICAgICB0eXBlOiB0ZW5zb3IudHlwZSBhcyBUZXh0dXJlQ29uc3RydWN0b3JQYXJhbWV0ZXJzWyd0eXBlJ10sXG4gICAgICAgIGRpbXMsXG4gICAgICB9KTtcbiAgICBjYXNlICdncHUtYnVmZmVyJzpcbiAgICAgIHJldHVybiBuZXcgVGVuc29yKHtcbiAgICAgICAgbG9jYXRpb246ICdncHUtYnVmZmVyJyxcbiAgICAgICAgZ3B1QnVmZmVyOiB0ZW5zb3IuZ3B1QnVmZmVyLFxuICAgICAgICB0eXBlOiB0ZW5zb3IudHlwZSBhcyBHcHVCdWZmZXJDb25zdHJ1Y3RvclBhcmFtZXRlcnNbJ3R5cGUnXSxcbiAgICAgICAgZGltcyxcbiAgICAgIH0pO1xuICAgIGNhc2UgJ21sLXRlbnNvcic6XG4gICAgICByZXR1cm4gbmV3IFRlbnNvcih7XG4gICAgICAgIGxvY2F0aW9uOiAnbWwtdGVuc29yJyxcbiAgICAgICAgbWxUZW5zb3I6IHRlbnNvci5tbFRlbnNvcixcbiAgICAgICAgdHlwZTogdGVuc29yLnR5cGUgYXMgTUxUZW5zb3JDb25zdHJ1Y3RvclBhcmFtZXRlcnNbJ3R5cGUnXSxcbiAgICAgICAgZGltcyxcbiAgICAgIH0pO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHRlbnNvclJlc2hhcGU6IHRlbnNvciBsb2NhdGlvbiAke3RlbnNvci5sb2NhdGlvbn0gaXMgbm90IHN1cHBvcnRlZGApO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyB0ZW5zb3JUb0RhdGFVUkwsIHRlbnNvclRvSW1hZ2VEYXRhIH0gZnJvbSAnLi90ZW5zb3ItY29udmVyc2lvbi1pbXBsLmpzJztcbmltcG9ydCB7IFRlbnNvclRvRGF0YVVybE9wdGlvbnMsIFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyB9IGZyb20gJy4vdGVuc29yLWNvbnZlcnNpb24uanMnO1xuaW1wb3J0IHtcbiAgdGVuc29yRnJvbUdwdUJ1ZmZlcixcbiAgdGVuc29yRnJvbUltYWdlLFxuICB0ZW5zb3JGcm9tTUxUZW5zb3IsXG4gIHRlbnNvckZyb21QaW5uZWRCdWZmZXIsXG4gIHRlbnNvckZyb21UZXh0dXJlLFxufSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LWltcGwuanMnO1xuaW1wb3J0IHtcbiAgQ3B1UGlubmVkQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxuICBHcHVCdWZmZXJDb25zdHJ1Y3RvclBhcmFtZXRlcnMsXG4gIE1MVGVuc29yQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxuICBUZW5zb3JGcm9tR3B1QnVmZmVyT3B0aW9ucyxcbiAgVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9ucyxcbiAgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnMsXG4gIFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zLFxuICBUZW5zb3JGcm9tTUxUZW5zb3JPcHRpb25zLFxuICBUZW5zb3JGcm9tVGV4dHVyZU9wdGlvbnMsXG4gIFRlbnNvckZyb21VcmxPcHRpb25zLFxuICBUZXh0dXJlQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxufSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LmpzJztcbmltcG9ydCB7XG4gIGNoZWNrVHlwZWRBcnJheSxcbiAgTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUCxcbiAgTlVNRVJJQ19URU5TT1JfVFlQRURBUlJBWV9UT19UWVBFX01BUCxcbiAgU3VwcG9ydGVkVHlwZWRBcnJheSxcbiAgU3VwcG9ydGVkVHlwZWRBcnJheUNvbnN0cnVjdG9ycyxcbn0gZnJvbSAnLi90ZW5zb3ItaW1wbC10eXBlLW1hcHBpbmcuanMnO1xuaW1wb3J0IHsgY2FsY3VsYXRlU2l6ZSwgdGVuc29yUmVzaGFwZSB9IGZyb20gJy4vdGVuc29yLXV0aWxzLWltcGwuanMnO1xuaW1wb3J0IHsgVGVuc29yIGFzIFRlbnNvckludGVyZmFjZSB9IGZyb20gJy4vdGVuc29yLmpzJztcblxuLy8gdHlwZSBhbGlhc2VzIGZvciB0aG9zZSBleHBvcnRlZCBmcm9tIFRlbnNvciBpbnRlcmZhY2VcblxudHlwZSBUZW5zb3JUeXBlID0gVGVuc29ySW50ZXJmYWNlLlR5cGU7XG50eXBlIFRlbnNvckRhdGFUeXBlID0gVGVuc29ySW50ZXJmYWNlLkRhdGFUeXBlO1xudHlwZSBUZW5zb3JEYXRhTG9jYXRpb24gPSBUZW5zb3JJbnRlcmZhY2UuRGF0YUxvY2F0aW9uO1xudHlwZSBUZW5zb3JUZXh0dXJlVHlwZSA9IFRlbnNvckludGVyZmFjZS5UZXh0dXJlVHlwZTtcbnR5cGUgVGVuc29yR3B1QnVmZmVyVHlwZSA9IFRlbnNvckludGVyZmFjZS5HcHVCdWZmZXJUeXBlO1xudHlwZSBUZW5zb3JNTFRlbnNvclR5cGUgPSBUZW5zb3JJbnRlcmZhY2UuTUxUZW5zb3JUeXBlO1xuXG4vKipcbiAqIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IgaW50ZXJmYWNlLlxuICpcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGNsYXNzIFRlbnNvciBpbXBsZW1lbnRzIFRlbnNvckludGVyZmFjZSB7XG4gIC8vICNyZWdpb24gY29uc3RydWN0b3JzXG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBDUFUgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiB0eXBlLCBkYXRhIGFuZCBkaW1zLlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgdHlwZTogVGVuc29yVHlwZSxcbiAgICBkYXRhOiBUZW5zb3JEYXRhVHlwZSB8IFVpbnQ4Q2xhbXBlZEFycmF5IHwgcmVhZG9ubHkgc3RyaW5nW10gfCByZWFkb25seSBudW1iZXJbXSB8IHJlYWRvbmx5IGJvb2xlYW5bXSxcbiAgICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgQ1BVIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy4gVHlwZSBpcyBpbmZlcnJlZCBmcm9tIGRhdGEuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBkYXRhOiBUZW5zb3JEYXRhVHlwZSB8IFVpbnQ4Q2xhbXBlZEFycmF5IHwgcmVhZG9ubHkgc3RyaW5nW10gfCByZWFkb25seSBib29sZWFuW10sXG4gICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuICApO1xuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgcGlubmVkIENQVSBkYXRhIHdpdGggdGhlIGdpdmVuIHR5cGUgYW5kIGRpbXMuXG4gICAqXG4gICAqIFRlbnNvcidzIGxvY2F0aW9uIHdpbGwgYmUgc2V0IHRvICdjcHUtcGlubmVkJy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFNwZWNpZnkgdGhlIHBhcmFtZXRlcnMgdG8gY29uc3RydWN0IHRoZSB0ZW5zb3IuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihwYXJhbXM6IENwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVycyk7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBXZWJHTCB0ZXh0dXJlIHdpdGggdGhlIGdpdmVuIHR5cGUgYW5kIGRpbXMuXG4gICAqXG4gICAqIFRlbnNvcidzIGxvY2F0aW9uIHdpbGwgYmUgc2V0IHRvICd0ZXh0dXJlJy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFNwZWNpZnkgdGhlIHBhcmFtZXRlcnMgdG8gY29uc3RydWN0IHRoZSB0ZW5zb3IuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihwYXJhbXM6IFRleHR1cmVDb25zdHJ1Y3RvclBhcmFtZXRlcnMpO1xuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgV2ViR1BVIGJ1ZmZlciB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZCBkaW1zLlxuICAgKlxuICAgKiBUZW5zb3IncyBsb2NhdGlvbiB3aWxsIGJlIHNldCB0byAnZ3B1LWJ1ZmZlcicuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBTcGVjaWZ5IHRoZSBwYXJhbWV0ZXJzIHRvIGNvbnN0cnVjdCB0aGUgdGVuc29yLlxuICAgKi9cbiAgY29uc3RydWN0b3IocGFyYW1zOiBHcHVCdWZmZXJDb25zdHJ1Y3RvclBhcmFtZXRlcnMpO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBXZWJOTiBNTFRlbnNvciB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZCBkaW1zLlxuICAgKlxuICAgKiBUZW5zb3IncyBsb2NhdGlvbiB3aWxsIGJlIHNldCB0byAnbWwtdGVuc29yJy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFNwZWNpZnkgdGhlIHBhcmFtZXRlcnMgdG8gY29uc3RydWN0IHRoZSB0ZW5zb3IuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihwYXJhbXM6IE1MVGVuc29yQ29uc3RydWN0b3JQYXJhbWV0ZXJzKTtcblxuICAvKipcbiAgICogaW1wbGVtZW50YXRpb24uXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBhcmcwOlxuICAgICAgfCBUZW5zb3JUeXBlXG4gICAgICB8IFRlbnNvckRhdGFUeXBlXG4gICAgICB8IFVpbnQ4Q2xhbXBlZEFycmF5XG4gICAgICB8IHJlYWRvbmx5IHN0cmluZ1tdXG4gICAgICB8IHJlYWRvbmx5IGJvb2xlYW5bXVxuICAgICAgfCBDcHVQaW5uZWRDb25zdHJ1Y3RvclBhcmFtZXRlcnNcbiAgICAgIHwgVGV4dHVyZUNvbnN0cnVjdG9yUGFyYW1ldGVyc1xuICAgICAgfCBHcHVCdWZmZXJDb25zdHJ1Y3RvclBhcmFtZXRlcnNcbiAgICAgIHwgTUxUZW5zb3JDb25zdHJ1Y3RvclBhcmFtZXRlcnMsXG4gICAgYXJnMT86IFRlbnNvckRhdGFUeXBlIHwgVWludDhDbGFtcGVkQXJyYXkgfCByZWFkb25seSBudW1iZXJbXSB8IHJlYWRvbmx5IHN0cmluZ1tdIHwgcmVhZG9ubHkgYm9vbGVhbltdLFxuICAgIGFyZzI/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKSB7XG4gICAgLy8gcGVyZm9ybSBvbmUtdGltZSBjaGVjayBmb3IgQmlnSW50L0Zsb2F0MTZBcnJheSBzdXBwb3J0XG4gICAgY2hlY2tUeXBlZEFycmF5KCk7XG5cbiAgICBsZXQgdHlwZTogVGVuc29yVHlwZTtcbiAgICBsZXQgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgICBpZiAodHlwZW9mIGFyZzAgPT09ICdvYmplY3QnICYmICdsb2NhdGlvbicgaW4gYXJnMCkge1xuICAgICAgLy9cbiAgICAgIC8vIGNvbnN0cnVjdGluZyB0ZW5zb3IgZnJvbSBzcGVjaWZpYyBsb2NhdGlvblxuICAgICAgLy9cbiAgICAgIHRoaXMuZGF0YUxvY2F0aW9uID0gYXJnMC5sb2NhdGlvbjtcbiAgICAgIHR5cGUgPSBhcmcwLnR5cGU7XG4gICAgICBkaW1zID0gYXJnMC5kaW1zO1xuICAgICAgc3dpdGNoIChhcmcwLmxvY2F0aW9uKSB7XG4gICAgICAgIGNhc2UgJ2NwdS1waW5uZWQnOiB7XG4gICAgICAgICAgY29uc3QgZXhwZWN0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3IgPSBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQLmdldCh0eXBlKTtcbiAgICAgICAgICBpZiAoIWV4cGVjdGVkVHlwZWRBcnJheUNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGB1bnN1cHBvcnRlZCB0eXBlIFwiJHt0eXBlfVwiIHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbSBwaW5uZWQgYnVmZmVyYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghKGFyZzAuZGF0YSBpbnN0YW5jZW9mIGV4cGVjdGVkVHlwZWRBcnJheUNvbnN0cnVjdG9yKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgYnVmZmVyIHNob3VsZCBiZSBvZiB0eXBlICR7ZXhwZWN0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3IubmFtZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5jcHVEYXRhID0gYXJnMC5kYXRhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ3RleHR1cmUnOiB7XG4gICAgICAgICAgaWYgKHR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgdW5zdXBwb3J0ZWQgdHlwZSBcIiR7dHlwZX1cIiB0byBjcmVhdGUgdGVuc29yIGZyb20gdGV4dHVyZWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmdwdVRleHR1cmVEYXRhID0gYXJnMC50ZXh0dXJlO1xuICAgICAgICAgIHRoaXMuZG93bmxvYWRlciA9IGFyZzAuZG93bmxvYWQ7XG4gICAgICAgICAgdGhpcy5kaXNwb3NlciA9IGFyZzAuZGlzcG9zZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdncHUtYnVmZmVyJzoge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGUgIT09ICdmbG9hdDMyJyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2Zsb2F0MTYnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnaW50MzInICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnaW50NjQnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAndWludDMyJyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ3VpbnQ4JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2Jvb2wnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAndWludDQnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnaW50NCdcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYHVuc3VwcG9ydGVkIHR5cGUgXCIke3R5cGV9XCIgdG8gY3JlYXRlIHRlbnNvciBmcm9tIGdwdSBidWZmZXJgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5ncHVCdWZmZXJEYXRhID0gYXJnMC5ncHVCdWZmZXI7XG4gICAgICAgICAgdGhpcy5kb3dubG9hZGVyID0gYXJnMC5kb3dubG9hZDtcbiAgICAgICAgICB0aGlzLmRpc3Bvc2VyID0gYXJnMC5kaXNwb3NlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ21sLXRlbnNvcic6IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0eXBlICE9PSAnZmxvYXQzMicgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICdmbG9hdDE2JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2ludDMyJyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2ludDY0JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ3VpbnQzMicgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICd1aW50NjQnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnaW50OCcgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICd1aW50OCcgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICdib29sJyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ3VpbnQ0JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2ludDQnXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGB1bnN1cHBvcnRlZCB0eXBlIFwiJHt0eXBlfVwiIHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbSBNTFRlbnNvcmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLm1sVGVuc29yRGF0YSA9IGFyZzAubWxUZW5zb3I7XG4gICAgICAgICAgdGhpcy5kb3dubG9hZGVyID0gYXJnMC5kb3dubG9hZDtcbiAgICAgICAgICB0aGlzLmRpc3Bvc2VyID0gYXJnMC5kaXNwb3NlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW5zb3IgY29uc3RydWN0b3I6IHVuc3VwcG9ydGVkIGxvY2F0aW9uICcke3RoaXMuZGF0YUxvY2F0aW9ufSdgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy9cbiAgICAgIC8vIGNvbnN0cnVjdGluZyB0ZW5zb3Igb2YgbG9jYXRpb24gJ2NwdSdcbiAgICAgIC8vXG4gICAgICBsZXQgZGF0YTogVGVuc29yRGF0YVR5cGU7XG4gICAgICBsZXQgbWF5YmVEaW1zOiB0eXBlb2YgYXJnMSB8IHR5cGVvZiBhcmcyO1xuICAgICAgLy8gY2hlY2sgd2hldGhlciBhcmcwIGlzIHR5cGUgb3IgZGF0YVxuICAgICAgaWYgKHR5cGVvZiBhcmcwID09PSAnc3RyaW5nJykge1xuICAgICAgICAvL1xuICAgICAgICAvLyBPdmVycmlkZTogY29uc3RydWN0b3IodHlwZSwgZGF0YSwgLi4uKVxuICAgICAgICAvL1xuICAgICAgICB0eXBlID0gYXJnMDtcbiAgICAgICAgbWF5YmVEaW1zID0gYXJnMjtcbiAgICAgICAgaWYgKGFyZzAgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgLy8gc3RyaW5nIHRlbnNvclxuICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcmcxKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkEgc3RyaW5nIHRlbnNvcidzIGRhdGEgbXVzdCBiZSBhIHN0cmluZyBhcnJheS5cIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHdlIGRvbid0IGNoZWNrIHdoZXRoZXIgZXZlcnkgZWxlbWVudCBpbiB0aGUgYXJyYXkgaXMgc3RyaW5nOyB0aGlzIGlzIHRvbyBzbG93LiB3ZSBhc3N1bWUgaXQncyBjb3JyZWN0IGFuZFxuICAgICAgICAgIC8vIGVycm9yIHdpbGwgYmUgcG9wdWxhdGVkIGF0IGluZmVyZW5jZVxuICAgICAgICAgIGRhdGEgPSBhcmcxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIG51bWVyaWMgdGVuc29yXG4gICAgICAgICAgY29uc3QgdHlwZWRBcnJheUNvbnN0cnVjdG9yID0gTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUC5nZXQoYXJnMCk7XG4gICAgICAgICAgaWYgKHR5cGVkQXJyYXlDb25zdHJ1Y3RvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBVbnN1cHBvcnRlZCB0ZW5zb3IgdHlwZTogJHthcmcwfS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYXJnMSkpIHtcbiAgICAgICAgICAgIGlmICgoYXJnMCA9PT0gJ2Zsb2F0MTYnICYmIHR5cGVkQXJyYXlDb25zdHJ1Y3RvciA9PT0gVWludDE2QXJyYXkpIHx8IGFyZzAgPT09ICd1aW50NCcgfHwgYXJnMCA9PT0gJ2ludDQnKSB7XG4gICAgICAgICAgICAgIC8vIC0gJ2Zsb2F0MTYnOlxuICAgICAgICAgICAgICAvLyAgIFdoZW4gbm8gRmxvYXQxNkFycmF5IHBvbHlmaWxsIGlzIHVzZWQsIHdlIGNhbm5vdCBjcmVhdGUgJ2Zsb2F0MTYnIHRlbnNvciBmcm9tIG51bWJlciBhcnJheS5cbiAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgLy8gICBUaHJvdyBlcnJvciBoZXJlIGJlY2F1c2Ugd2hlbiB1c2VyIHRyeSB0byB1c2UgbnVtYmVyIGFycmF5IGFzIGRhdGEsXG4gICAgICAgICAgICAgIC8vICAgZS5nLiBuZXcgVGVuc29yKCdmbG9hdDE2JywgWzEsIDIsIDMsIDRdLCBkaW1zKSksIGl0IHdpbGwgYWN0dWFsbHkgY2FsbFxuICAgICAgICAgICAgICAvLyAgIFVpbnQxNkFycmF5LmZyb20oYXJnMSkgd2hpY2ggZ2VuZXJhdGVzIHdyb25nIGRhdGEuXG4gICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgIC8vIC0gJ3VpbnQ0JyBhbmQgJ2ludDQnOlxuICAgICAgICAgICAgICAvLyAgIFVpbnQ4QXJyYXkuZnJvbShhcmcxKSB3aWxsIGdlbmVyYXRlIHdyb25nIGRhdGEgZm9yICd1aW50NCcgYW5kICdpbnQ0JyB0ZW5zb3IuXG4gICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICAgICAgYENyZWF0aW5nIGEgJHthcmcwfSB0ZW5zb3IgZnJvbSBudW1iZXIgYXJyYXkgaXMgbm90IHN1cHBvcnRlZC4gUGxlYXNlIHVzZSAke3R5cGVkQXJyYXlDb25zdHJ1Y3Rvci5uYW1lfSBhcyBkYXRhLmAsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFyZzAgPT09ICd1aW50NjQnIHx8IGFyZzAgPT09ICdpbnQ2NCcpIHtcbiAgICAgICAgICAgICAgLy8gdXNlICdhcyBhbnknIGhlcmUgYmVjYXVzZTpcbiAgICAgICAgICAgICAgLy8gMS4gVHlwZVNjcmlwdCdzIGNoZWNrIG9uIHR5cGUgb2YgJ0FycmF5LmlzQXJyYXkoKScgZG9lcyBub3Qgd29yayB3aXRoIHJlYWRvbmx5IGFycmF5cy5cbiAgICAgICAgICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvVHlwZVNjcmlwdC9pc3N1ZXMvMTcwMDJcbiAgICAgICAgICAgICAgLy8gMi4gVHlwZVNjcmlwdCdzIGNoZWNrIG9uIHVuaW9uIHR5cGUgb2YgJyhCaWdJbnQ2NEFycmF5Q29uc3RydWN0b3J8QmlnVWludDY0QXJyYXlDb25zdHJ1Y3RvcikuZnJvbSgpJ1xuICAgICAgICAgICAgICAvLyBkb2VzIG5vdCBhY2NlcHQgcGFyYW1ldGVyIG1hcEZuLlxuICAgICAgICAgICAgICAvLyAzLiBwYXJhbWV0ZXJzIG9mICdTdXBwb3J0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3JzLmZyb20oKScgZG9lcyBub3QgbWF0Y2ggdGhlIHJlcXVpcmVtZW50IG9mIHRoZSB1bmlvblxuICAgICAgICAgICAgICAvLyB0eXBlLlxuXG4gICAgICAgICAgICAgIC8vIGFzc3VtZSAnYXJnMScgaXMgb2YgdHlwZSBcInJlYWRvbmx5IG51bWJlcltdfHJlYWRvbmx5IGJpZ2ludFtdXCIgaGVyZS5cblxuICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAgICAgICBkYXRhID0gKHR5cGVkQXJyYXlDb25zdHJ1Y3RvciBhcyBhbnkpLmZyb20oYXJnMSwgQmlnSW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIGFzc3VtZSAnYXJnMScgaXMgb2YgdHlwZSBcInJlYWRvbmx5IG51bWJlcltdXCIgaGVyZS5cbiAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgICAgICAgZGF0YSA9ICh0eXBlZEFycmF5Q29uc3RydWN0b3IgYXMgYW55KS5mcm9tKGFyZzEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoYXJnMSBpbnN0YW5jZW9mIHR5cGVkQXJyYXlDb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgZGF0YSA9IGFyZzE7XG4gICAgICAgICAgfSBlbHNlIGlmIChhcmcxIGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXkpIHtcbiAgICAgICAgICAgIGlmIChhcmcwID09PSAndWludDgnKSB7XG4gICAgICAgICAgICAgIGRhdGEgPSBVaW50OEFycmF5LmZyb20oYXJnMSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBBIFVpbnQ4Q2xhbXBlZEFycmF5IHRlbnNvcidzIGRhdGEgbXVzdCBiZSB0eXBlIG9mIHVpbnQ4YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChhcmcwID09PSAnZmxvYXQxNicgJiYgYXJnMSBpbnN0YW5jZW9mIFVpbnQxNkFycmF5ICYmIHR5cGVkQXJyYXlDb25zdHJ1Y3RvciAhPT0gVWludDE2QXJyYXkpIHtcbiAgICAgICAgICAgIC8vIHdoZW4gRmxvYXQxNkFycmF5IGlzIGF2YWlsYWJsZSBhbmQgZGF0YSBpcyBvZiB0eXBlIFVpbnQxNkFycmF5LlxuICAgICAgICAgICAgLy8gV2UgYWxsb3cgVWludDE2QXJyYXkgdG8gYmUgcGFzc2VkIGluIGFzIGRhdGEgZm9yICdmbG9hdDE2JyB0ZW5zb3IgdW50aWwgRmxvYXQxNkFycmF5IGlzIGdlbmVyYWxseVxuICAgICAgICAgICAgLy8gc3VwcG9ydGVkIGluIEphdmFTY3JpcHQgZW52aXJvbm1lbnQuXG5cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICAgICBkYXRhID0gbmV3IChnbG9iYWxUaGlzIGFzIGFueSkuRmxvYXQxNkFycmF5KGFyZzEuYnVmZmVyLCBhcmcxLmJ5dGVPZmZzZXQsIGFyZzEubGVuZ3RoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgQSAke3R5cGV9IHRlbnNvcidzIGRhdGEgbXVzdCBiZSB0eXBlIG9mICR7dHlwZWRBcnJheUNvbnN0cnVjdG9yfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy9cbiAgICAgICAgLy8gT3ZlcnJpZGU6IGNvbnN0cnVjdG9yKGRhdGEsIC4uLilcbiAgICAgICAgLy9cbiAgICAgICAgbWF5YmVEaW1zID0gYXJnMTtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYXJnMCkpIHtcbiAgICAgICAgICAvLyBvbmx5IGJvb2xlYW5bXSBhbmQgc3RyaW5nW10gaXMgc3VwcG9ydGVkXG4gICAgICAgICAgaWYgKGFyZzAubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUZW5zb3IgdHlwZSBjYW5ub3QgYmUgaW5mZXJyZWQgZnJvbSBhbiBlbXB0eSBhcnJheS4nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgZmlyc3RFbGVtZW50VHlwZSA9IHR5cGVvZiBhcmcwWzBdO1xuICAgICAgICAgIGlmIChmaXJzdEVsZW1lbnRUeXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdHlwZSA9ICdzdHJpbmcnO1xuICAgICAgICAgICAgZGF0YSA9IGFyZzA7XG4gICAgICAgICAgfSBlbHNlIGlmIChmaXJzdEVsZW1lbnRUeXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHR5cGUgPSAnYm9vbCc7XG4gICAgICAgICAgICAvLyAnYXJnMCcgaXMgb2YgdHlwZSAnYm9vbGVhbltdJy4gVWludDhBcnJheS5mcm9tKGJvb2xlYW5bXSkgYWN0dWFsbHkgd29ya3MsIGJ1dCB0eXBlc2NyaXB0IHRoaW5rcyB0aGlzIGlzXG4gICAgICAgICAgICAvLyB3cm9uZyB0eXBlLiBXZSB1c2UgJ2FzIGFueScgdG8gbWFrZSBpdCBoYXBweS5cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICAgICBkYXRhID0gVWludDhBcnJheS5mcm9tKGFyZzAgYXMgYW55W10pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBJbnZhbGlkIGVsZW1lbnQgdHlwZSBvZiBkYXRhIGFycmF5OiAke2ZpcnN0RWxlbWVudFR5cGV9LmApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChhcmcwIGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXkpIHtcbiAgICAgICAgICB0eXBlID0gJ3VpbnQ4JztcbiAgICAgICAgICBkYXRhID0gVWludDhBcnJheS5mcm9tKGFyZzApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGdldCB0ZW5zb3IgdHlwZSBmcm9tIFR5cGVkQXJyYXlcbiAgICAgICAgICBjb25zdCBtYXBwZWRUeXBlID0gTlVNRVJJQ19URU5TT1JfVFlQRURBUlJBWV9UT19UWVBFX01BUC5nZXQoXG4gICAgICAgICAgICBhcmcwLmNvbnN0cnVjdG9yIGFzIFN1cHBvcnRlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvcnMsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAobWFwcGVkVHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBVbnN1cHBvcnRlZCB0eXBlIGZvciB0ZW5zb3IgZGF0YTogJHthcmcwLmNvbnN0cnVjdG9yfS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdHlwZSA9IG1hcHBlZFR5cGU7XG4gICAgICAgICAgZGF0YSA9IGFyZzAgYXMgU3VwcG9ydGVkVHlwZWRBcnJheTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyB0eXBlIGFuZCBkYXRhIGlzIHByb2Nlc3NlZCwgbm93IHByb2Nlc3NpbmcgZGltc1xuICAgICAgaWYgKG1heWJlRGltcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIGFzc3VtZSAxLUQgdGVuc29yIGlmIGRpbXMgb21pdHRlZFxuICAgICAgICBtYXliZURpbXMgPSBbZGF0YS5sZW5ndGhdO1xuICAgICAgfSBlbHNlIGlmICghQXJyYXkuaXNBcnJheShtYXliZURpbXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJBIHRlbnNvcidzIGRpbXMgbXVzdCBiZSBhIG51bWJlciBhcnJheVwiKTtcbiAgICAgIH1cbiAgICAgIGRpbXMgPSBtYXliZURpbXMgYXMgcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgICAgIHRoaXMuY3B1RGF0YSA9IGRhdGE7XG4gICAgICB0aGlzLmRhdGFMb2NhdGlvbiA9ICdjcHUnO1xuICAgIH1cblxuICAgIC8vIHBlcmZvcm0gY2hlY2sgb24gZGltc1xuICAgIGNvbnN0IHNpemUgPSBjYWxjdWxhdGVTaXplKGRpbXMpO1xuICAgIC8vIGlmIGRhdGEgaXMgb24gQ1BVLCBjaGVjayB3aGV0aGVyIGRhdGEgbGVuZ3RoIG1hdGNoZXMgdGVuc29yIHNpemVcbiAgICBpZiAodGhpcy5jcHVEYXRhICYmIHNpemUgIT09IHRoaXMuY3B1RGF0YS5sZW5ndGgpIHtcbiAgICAgIGlmICgodHlwZSA9PT0gJ3VpbnQ0JyB8fCB0eXBlID09PSAnaW50NCcpICYmIE1hdGguY2VpbChzaXplIC8gMikgPT09IHRoaXMuY3B1RGF0YS5sZW5ndGgpIHtcbiAgICAgICAgLy8gZm9yICh1KWludDQsIHRoZSBkYXRhIGxlbmd0aCBpcyBoYWxmIG9mIHRoZSB0ZW5zb3Igc2l6ZS4gU28gd2UgY2hlY2sgdGhpcyBzcGVjaWFsIGNhc2Ugd2hlbiBzaXplIGlzIG9kZC5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVGVuc29yJ3Mgc2l6ZSgke3NpemV9KSBkb2VzIG5vdCBtYXRjaCBkYXRhIGxlbmd0aCgke3RoaXMuY3B1RGF0YS5sZW5ndGh9KS5gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIHRoaXMuZGltcyA9IGRpbXM7XG4gICAgdGhpcy5zaXplID0gc2l6ZTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBmYWN0b3J5XG4gIHN0YXRpYyBhc3luYyBmcm9tSW1hZ2UoXG4gICAgaW1hZ2U6IEltYWdlRGF0YSB8IEhUTUxJbWFnZUVsZW1lbnQgfCBJbWFnZUJpdG1hcCB8IHN0cmluZyxcbiAgICBvcHRpb25zPzpcbiAgICAgIHwgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnNcbiAgICAgIHwgVGVuc29yRnJvbUltYWdlRWxlbWVudE9wdGlvbnNcbiAgICAgIHwgVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9uc1xuICAgICAgfCBUZW5zb3JGcm9tVXJsT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxUZW5zb3JJbnRlcmZhY2U+IHtcbiAgICByZXR1cm4gdGVuc29yRnJvbUltYWdlKGltYWdlLCBvcHRpb25zKTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tVGV4dHVyZTxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLlRleHR1cmVEYXRhVHlwZXM+KFxuICAgIHRleHR1cmU6IFRlbnNvclRleHR1cmVUeXBlLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21UZXh0dXJlT3B0aW9uczxUPixcbiAgKTogVGVuc29ySW50ZXJmYWNlIHtcbiAgICByZXR1cm4gdGVuc29yRnJvbVRleHR1cmUodGV4dHVyZSwgb3B0aW9ucyk7XG4gIH1cblxuICBzdGF0aWMgZnJvbUdwdUJ1ZmZlcjxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLkdwdUJ1ZmZlckRhdGFUeXBlcz4oXG4gICAgZ3B1QnVmZmVyOiBUZW5zb3JHcHVCdWZmZXJUeXBlLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21HcHVCdWZmZXJPcHRpb25zPFQ+LFxuICApOiBUZW5zb3JJbnRlcmZhY2Uge1xuICAgIHJldHVybiB0ZW5zb3JGcm9tR3B1QnVmZmVyKGdwdUJ1ZmZlciwgb3B0aW9ucyk7XG4gIH1cblxuICBzdGF0aWMgZnJvbU1MVGVuc29yPFQgZXh0ZW5kcyBUZW5zb3JJbnRlcmZhY2UuTUxUZW5zb3JEYXRhVHlwZXM+KFxuICAgIG1sVGVuc29yOiBUZW5zb3JNTFRlbnNvclR5cGUsXG4gICAgb3B0aW9uczogVGVuc29yRnJvbU1MVGVuc29yT3B0aW9uczxUPixcbiAgKTogVGVuc29ySW50ZXJmYWNlIHtcbiAgICByZXR1cm4gdGVuc29yRnJvbU1MVGVuc29yKG1sVGVuc29yLCBvcHRpb25zKTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tUGlubmVkQnVmZmVyPFQgZXh0ZW5kcyBUZW5zb3JJbnRlcmZhY2UuQ3B1UGlubmVkRGF0YVR5cGVzPihcbiAgICB0eXBlOiBULFxuICAgIGJ1ZmZlcjogVGVuc29ySW50ZXJmYWNlLkRhdGFUeXBlTWFwW1RdLFxuICAgIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogVGVuc29yIHtcbiAgICByZXR1cm4gdGVuc29yRnJvbVBpbm5lZEJ1ZmZlcih0eXBlLCBidWZmZXIsIGRpbXMpO1xuICB9XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gY29udmVyc2lvbnNcbiAgdG9EYXRhVVJMKG9wdGlvbnM/OiBUZW5zb3JUb0RhdGFVcmxPcHRpb25zKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGVuc29yVG9EYXRhVVJMKHRoaXMsIG9wdGlvbnMpO1xuICB9XG5cbiAgdG9JbWFnZURhdGEob3B0aW9ucz86IFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyk6IEltYWdlRGF0YSB7XG4gICAgcmV0dXJuIHRlbnNvclRvSW1hZ2VEYXRhKHRoaXMsIG9wdGlvbnMpO1xuICB9XG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHB1YmxpYyBmaWVsZHNcbiAgcmVhZG9ubHkgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHR5cGU6IFRlbnNvclR5cGU7XG4gIHJlYWRvbmx5IHNpemU6IG51bWJlcjtcbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcHJpdmF0ZSBmaWVsZHNcblxuICAvKipcbiAgICogc3RvcmVzIHRoZSBsb2NhdGlvbiBvZiB0aGUgZGF0YS5cbiAgICovXG4gIHByaXZhdGUgZGF0YUxvY2F0aW9uOiBUZW5zb3JEYXRhTG9jYXRpb247XG5cbiAgLyoqXG4gICAqIHN0b3JlcyB0aGUgZGF0YSBvbiBDUFUsIGlmIGxvY2F0aW9uIGlzICdjcHUnIG9yICdjcHUtcGlubmVkJy4gb3RoZXJ3aXNlIGVtcHR5LlxuICAgKi9cbiAgcHJpdmF0ZSBjcHVEYXRhPzogVGVuc29yRGF0YVR5cGU7XG5cbiAgLyoqXG4gICAqIHN0b3JlcyB0aGUgdW5kZXJseWluZyB0ZXh0dXJlIHdoZW4gbG9jYXRpb24gaXMgJ3RleHR1cmUnLiBvdGhlcndpc2UgZW1wdHkuXG4gICAqL1xuICBwcml2YXRlIGdwdVRleHR1cmVEYXRhPzogVGVuc29yVGV4dHVyZVR5cGU7XG5cbiAgLyoqXG4gICAqIHN0b3JlcyB0aGUgdW5kZXJseWluZyBHUFUgYnVmZmVyIHdoZW4gbG9jYXRpb24gaXMgJ2dwdS1idWZmZXInLiBvdGhlcndpc2UgZW1wdHkuXG4gICAqL1xuICBwcml2YXRlIGdwdUJ1ZmZlckRhdGE/OiBUZW5zb3JHcHVCdWZmZXJUeXBlO1xuXG4gIC8qKlxuICAgKiBzdG9yZXMgdGhlIHVuZGVybHlpbmcgV2ViTk4gTUxUZW5zb3Igd2hlbiBsb2NhdGlvbiBpcyAnbWwtdGVuc29yJy4gb3RoZXJ3aXNlIGVtcHR5LlxuICAgKi9cbiAgcHJpdmF0ZSBtbFRlbnNvckRhdGE/OiBUZW5zb3JNTFRlbnNvclR5cGU7XG5cbiAgLyoqXG4gICAqIHN0b3JlcyBhbiBvcHRpb25hbCBkb3dubG9hZGVyIGZ1bmN0aW9uIHRvIGRvd25sb2FkIGRhdGEgZnJvbSBHUFUgdG8gQ1BVLlxuICAgKi9cbiAgcHJpdmF0ZSBkb3dubG9hZGVyPygpOiBQcm9taXNlPFRlbnNvckRhdGFUeXBlPjtcblxuICAvKipcbiAgICogYSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGUgZGF0YSBpcyBiZWluZyBkb3dubG9hZGVkIGZyb20gR1BVIHRvIENQVS5cbiAgICovXG4gIHByaXZhdGUgaXNEb3dubG9hZGluZz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIHN0b3JlcyBhbiBvcHRpb25hbCBkaXNwb3NlciBmdW5jdGlvbiB0byBkaXNwb3NlIHRoZSB1bmRlcmx5aW5nIGRhdGEuXG4gICAqL1xuICBwcml2YXRlIGRpc3Bvc2VyPygpOiB2b2lkO1xuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBwcm9wZXJ0aWVzXG4gIGdldCBkYXRhKCk6IFRlbnNvckRhdGFUeXBlIHtcbiAgICB0aGlzLmVuc3VyZVZhbGlkKCk7XG4gICAgaWYgKCF0aGlzLmNwdURhdGEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1RoZSBkYXRhIGlzIG5vdCBvbiBDUFUuIFVzZSBgZ2V0RGF0YSgpYCB0byBkb3dubG9hZCBHUFUgZGF0YSB0byBDUFUsICcgK1xuICAgICAgICAgICdvciB1c2UgYHRleHR1cmVgIG9yIGBncHVCdWZmZXJgIHByb3BlcnR5IHRvIGFjY2VzcyB0aGUgR1BVIGRhdGEgZGlyZWN0bHkuJyxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNwdURhdGE7XG4gIH1cblxuICBnZXQgbG9jYXRpb24oKTogVGVuc29yRGF0YUxvY2F0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhTG9jYXRpb247XG4gIH1cblxuICBnZXQgdGV4dHVyZSgpOiBUZW5zb3JUZXh0dXJlVHlwZSB7XG4gICAgdGhpcy5lbnN1cmVWYWxpZCgpO1xuICAgIGlmICghdGhpcy5ncHVUZXh0dXJlRGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgZGF0YSBpcyBub3Qgc3RvcmVkIGFzIGEgV2ViR0wgdGV4dHVyZS4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ3B1VGV4dHVyZURhdGE7XG4gIH1cblxuICBnZXQgZ3B1QnVmZmVyKCk6IFRlbnNvckdwdUJ1ZmZlclR5cGUge1xuICAgIHRoaXMuZW5zdXJlVmFsaWQoKTtcbiAgICBpZiAoIXRoaXMuZ3B1QnVmZmVyRGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgZGF0YSBpcyBub3Qgc3RvcmVkIGFzIGEgV2ViR1BVIGJ1ZmZlci4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ3B1QnVmZmVyRGF0YTtcbiAgfVxuXG4gIGdldCBtbFRlbnNvcigpOiBUZW5zb3JNTFRlbnNvclR5cGUge1xuICAgIHRoaXMuZW5zdXJlVmFsaWQoKTtcbiAgICBpZiAoIXRoaXMubWxUZW5zb3JEYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBkYXRhIGlzIG5vdCBzdG9yZWQgYXMgYSBXZWJOTiBNTFRlbnNvci4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubWxUZW5zb3JEYXRhO1xuICB9XG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIG1ldGhvZHNcblxuICBhc3luYyBnZXREYXRhKHJlbGVhc2VEYXRhPzogYm9vbGVhbik6IFByb21pc2U8VGVuc29yRGF0YVR5cGU+IHtcbiAgICB0aGlzLmVuc3VyZVZhbGlkKCk7XG4gICAgc3dpdGNoICh0aGlzLmRhdGFMb2NhdGlvbikge1xuICAgICAgY2FzZSAnY3B1JzpcbiAgICAgIGNhc2UgJ2NwdS1waW5uZWQnOlxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhO1xuICAgICAgY2FzZSAndGV4dHVyZSc6XG4gICAgICBjYXNlICdncHUtYnVmZmVyJzpcbiAgICAgIGNhc2UgJ21sLXRlbnNvcic6IHtcbiAgICAgICAgaWYgKCF0aGlzLmRvd25sb2FkZXIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjdXJyZW50IHRlbnNvciBpcyBub3QgY3JlYXRlZCB3aXRoIGEgc3BlY2lmaWVkIGRhdGEgZG93bmxvYWRlci4nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5pc0Rvd25sb2FkaW5nKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgY3VycmVudCB0ZW5zb3IgaXMgYmVpbmcgZG93bmxvYWRlZC4nKTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuaXNEb3dubG9hZGluZyA9IHRydWU7XG4gICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuZG93bmxvYWRlcigpO1xuICAgICAgICAgIHRoaXMuZG93bmxvYWRlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB0aGlzLmRhdGFMb2NhdGlvbiA9ICdjcHUnO1xuICAgICAgICAgIHRoaXMuY3B1RGF0YSA9IGRhdGE7XG5cbiAgICAgICAgICBpZiAocmVsZWFzZURhdGEgJiYgdGhpcy5kaXNwb3Nlcikge1xuICAgICAgICAgICAgdGhpcy5kaXNwb3NlcigpO1xuICAgICAgICAgICAgdGhpcy5kaXNwb3NlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICB0aGlzLmlzRG93bmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgZ2V0IGRhdGEgZnJvbSBsb2NhdGlvbjogJHt0aGlzLmRhdGFMb2NhdGlvbn1gKTtcbiAgICB9XG4gIH1cblxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzRG93bmxvYWRpbmcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGN1cnJlbnQgdGVuc29yIGlzIGJlaW5nIGRvd25sb2FkZWQuJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZGlzcG9zZXIpIHtcbiAgICAgIHRoaXMuZGlzcG9zZXIoKTtcbiAgICAgIHRoaXMuZGlzcG9zZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuY3B1RGF0YSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmdwdVRleHR1cmVEYXRhID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZ3B1QnVmZmVyRGF0YSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1sVGVuc29yRGF0YSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmRvd25sb2FkZXIgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5pc0Rvd25sb2FkaW5nID0gdW5kZWZpbmVkO1xuXG4gICAgdGhpcy5kYXRhTG9jYXRpb24gPSAnbm9uZSc7XG4gIH1cblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiB0ZW5zb3IgdXRpbGl0aWVzXG4gIHByaXZhdGUgZW5zdXJlVmFsaWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGF0YUxvY2F0aW9uID09PSAnbm9uZScpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIHRlbnNvciBpcyBkaXNwb3NlZC4nKTtcbiAgICB9XG4gIH1cblxuICByZXNoYXBlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29ySW50ZXJmYWNlIHtcbiAgICB0aGlzLmVuc3VyZVZhbGlkKCk7XG4gICAgaWYgKHRoaXMuZG93bmxvYWRlciB8fCB0aGlzLmRpc3Bvc2VyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCByZXNoYXBlIGEgdGVuc29yIHRoYXQgb3ducyBHUFUgcmVzb3VyY2UuJyk7XG4gICAgfVxuICAgIHJldHVybiB0ZW5zb3JSZXNoYXBlKHRoaXMsIGRpbXMpO1xuICB9XG4gIC8vICNlbmRyZWdpb25cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yRmFjdG9yeSB9IGZyb20gJy4vdGVuc29yLWZhY3RvcnkuanMnO1xuaW1wb3J0IHsgVGVuc29yIGFzIFRlbnNvckltcGwgfSBmcm9tICcuL3RlbnNvci1pbXBsLmpzJztcbmltcG9ydCB7IFR5cGVkVGVuc29yVXRpbHMgfSBmcm9tICcuL3RlbnNvci11dGlscy5qcyc7XG5pbXBvcnQgeyBUcnlHZXRHbG9iYWxUeXBlIH0gZnJvbSAnLi90eXBlLWhlbHBlci5qcyc7XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmUgKi9cblxuLyoqXG4gKiByZXByZXNlbnQgYSBiYXNpYyB0ZW5zb3Igd2l0aCBzcGVjaWZpZWQgZGltZW5zaW9ucyBhbmQgZGF0YSB0eXBlLlxuICovXG5pbnRlcmZhY2UgVHlwZWRUZW5zb3JCYXNlPFQgZXh0ZW5kcyBUZW5zb3IuVHlwZT4ge1xuICAvKipcbiAgICogR2V0IHRoZSBkaW1lbnNpb25zIG9mIHRoZSB0ZW5zb3IuXG4gICAqL1xuICByZWFkb25seSBkaW1zOiByZWFkb25seSBudW1iZXJbXTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAqL1xuICByZWFkb25seSB0eXBlOiBUO1xuICAvKipcbiAgICogR2V0IHRoZSBidWZmZXIgZGF0YSBvZiB0aGUgdGVuc29yLlxuICAgKlxuICAgKiBJZiB0aGUgZGF0YSBpcyBub3Qgb24gQ1BVIChlZy4gaXQncyBpbiB0aGUgZm9ybSBvZiBXZWJHTCB0ZXh0dXJlIG9yIFdlYkdQVSBidWZmZXIpLCB0aHJvdyBlcnJvci5cbiAgICovXG4gIHJlYWRvbmx5IGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFtUXTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbG9jYXRpb24gb2YgdGhlIGRhdGEuXG4gICAqL1xuICByZWFkb25seSBsb2NhdGlvbjogVGVuc29yLkRhdGFMb2NhdGlvbjtcbiAgLyoqXG4gICAqIEdldCB0aGUgV2ViR0wgdGV4dHVyZSB0aGF0IGhvbGRzIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICpcbiAgICogSWYgdGhlIGRhdGEgaXMgbm90IG9uIEdQVSBhcyBXZWJHTCB0ZXh0dXJlLCB0aHJvdyBlcnJvci5cbiAgICovXG4gIHJlYWRvbmx5IHRleHR1cmU6IFRlbnNvci5UZXh0dXJlVHlwZTtcbiAgLyoqXG4gICAqIEdldCB0aGUgV2ViR1BVIGJ1ZmZlciB0aGF0IGhvbGRzIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICpcbiAgICogSWYgdGhlIGRhdGEgaXMgbm90IG9uIEdQVSBhcyBXZWJHUFUgYnVmZmVyLCB0aHJvdyBlcnJvci5cbiAgICovXG4gIHJlYWRvbmx5IGdwdUJ1ZmZlcjogVGVuc29yLkdwdUJ1ZmZlclR5cGU7XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgV2ViTk4gTUxUZW5zb3IgdGhhdCBob2xkcyB0aGUgdGVuc29yIGRhdGEuXG4gICAqXG4gICAqIElmIHRoZSBkYXRhIGlzIG5vdCBpbiBhIFdlYk5OIE1MVGVuc29yLCB0aHJvdyBlcnJvci5cbiAgICovXG4gIHJlYWRvbmx5IG1sVGVuc29yOiBUZW5zb3IuTUxUZW5zb3JUeXBlO1xuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGJ1ZmZlciBkYXRhIG9mIHRoZSB0ZW5zb3IuXG4gICAqXG4gICAqIElmIHRoZSBkYXRhIGlzIG9uIENQVSwgcmV0dXJucyB0aGUgZGF0YSBpbW1lZGlhdGVseS5cbiAgICogSWYgdGhlIGRhdGEgaXMgb24gR1BVLCBkb3dubG9hZHMgdGhlIGRhdGEgYW5kIHJldHVybnMgdGhlIHByb21pc2UuXG4gICAqXG4gICAqIEBwYXJhbSByZWxlYXNlRGF0YSAtIHdoZXRoZXIgcmVsZWFzZSB0aGUgZGF0YSBvbiBHUFUuIElnbm9yZSBpZiBkYXRhIGlzIGFscmVhZHkgb24gQ1BVLlxuICAgKi9cbiAgZ2V0RGF0YShyZWxlYXNlRGF0YT86IGJvb2xlYW4pOiBQcm9taXNlPFRlbnNvci5EYXRhVHlwZU1hcFtUXT47XG5cbiAgLyoqXG4gICAqIERpc3Bvc2UgdGhlIHRlbnNvciBkYXRhLlxuICAgKlxuICAgKiBJZiB0aGUgZGF0YSBpcyBvbiBDUFUsIHJlbW92ZSBpdHMgaW50ZXJuYWwgcmVmZXJlbmNlIHRvIHRoZSB1bmRlcmx5aW5nIGRhdGEuXG4gICAqIElmIHRoZSBkYXRhIGlzIG9uIEdQVSwgcmVsZWFzZSB0aGUgZGF0YSBvbiBHUFUuXG4gICAqXG4gICAqIEFmdGVyIGNhbGxpbmcgdGhpcyBmdW5jdGlvbiwgdGhlIHRlbnNvciBpcyBjb25zaWRlcmVkIG5vIGxvbmdlciB2YWxpZC4gSXRzIGxvY2F0aW9uIHdpbGwgYmUgc2V0IHRvICdub25lJy5cbiAgICovXG4gIGRpc3Bvc2UoKTogdm9pZDtcbn1cblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIFRlbnNvciB7XG4gIGludGVyZmFjZSBEYXRhVHlwZU1hcCB7XG4gICAgZmxvYXQzMjogRmxvYXQzMkFycmF5O1xuICAgIHVpbnQ4OiBVaW50OEFycmF5O1xuICAgIGludDg6IEludDhBcnJheTtcbiAgICB1aW50MTY6IFVpbnQxNkFycmF5O1xuICAgIGludDE2OiBJbnQxNkFycmF5O1xuICAgIGludDMyOiBJbnQzMkFycmF5O1xuICAgIGludDY0OiBCaWdJbnQ2NEFycmF5O1xuICAgIHN0cmluZzogc3RyaW5nW107XG4gICAgYm9vbDogVWludDhBcnJheTtcbiAgICBmbG9hdDE2OiBVaW50MTZBcnJheTsgLy8gS2VlcCB1c2luZyBVaW50MTZBcnJheSB1bnRpbCB3ZSBoYXZlIGEgY29uY3JldGUgc29sdXRpb24gZm9yIGZsb2F0IDE2LlxuICAgIGZsb2F0NjQ6IEZsb2F0NjRBcnJheTtcbiAgICB1aW50MzI6IFVpbnQzMkFycmF5O1xuICAgIHVpbnQ2NDogQmlnVWludDY0QXJyYXk7XG4gICAgLy8gY29tcGxleDY0OiBuZXZlcjtcbiAgICAvLyBjb21wbGV4MTI4OiBuZXZlcjtcbiAgICAvLyBiZmxvYXQxNjogbmV2ZXI7XG4gICAgdWludDQ6IFVpbnQ4QXJyYXk7XG4gICAgaW50NDogSW50OEFycmF5O1xuICB9XG5cbiAgaW50ZXJmYWNlIEVsZW1lbnRUeXBlTWFwIHtcbiAgICBmbG9hdDMyOiBudW1iZXI7XG4gICAgdWludDg6IG51bWJlcjtcbiAgICBpbnQ4OiBudW1iZXI7XG4gICAgdWludDE2OiBudW1iZXI7XG4gICAgaW50MTY6IG51bWJlcjtcbiAgICBpbnQzMjogbnVtYmVyO1xuICAgIGludDY0OiBiaWdpbnQ7XG4gICAgc3RyaW5nOiBzdHJpbmc7XG4gICAgYm9vbDogYm9vbGVhbjtcbiAgICBmbG9hdDE2OiBudW1iZXI7IC8vIEtlZXAgdXNpbmcgVWludDE2QXJyYXkgdW50aWwgd2UgaGF2ZSBhIGNvbmNyZXRlIHNvbHV0aW9uIGZvciBmbG9hdCAxNi5cbiAgICBmbG9hdDY0OiBudW1iZXI7XG4gICAgdWludDMyOiBudW1iZXI7XG4gICAgdWludDY0OiBiaWdpbnQ7XG4gICAgLy8gY29tcGxleDY0OiBuZXZlcjtcbiAgICAvLyBjb21wbGV4MTI4OiBuZXZlcjtcbiAgICAvLyBiZmxvYXQxNjogbmV2ZXI7XG4gICAgdWludDQ6IG51bWJlcjtcbiAgICBpbnQ0OiBudW1iZXI7XG4gIH1cblxuICB0eXBlIERhdGFUeXBlID0gRGF0YVR5cGVNYXBbVHlwZV07XG4gIHR5cGUgRWxlbWVudFR5cGUgPSBFbGVtZW50VHlwZU1hcFtUeXBlXTtcblxuICAvKipcbiAgICogc3VwcG9ydGVkIGRhdGEgdHlwZXMgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgcGlubmVkIENQVSBidWZmZXJcbiAgICovXG4gIGV4cG9ydCB0eXBlIENwdVBpbm5lZERhdGFUeXBlcyA9IEV4Y2x1ZGU8VGVuc29yLlR5cGUsICdzdHJpbmcnPjtcblxuICAvKipcbiAgICogdHlwZSBhbGlhcyBmb3IgV2ViR0wgdGV4dHVyZVxuICAgKi9cbiAgZXhwb3J0IHR5cGUgVGV4dHVyZVR5cGUgPSBXZWJHTFRleHR1cmU7XG5cbiAgLyoqXG4gICAqIHN1cHBvcnRlZCBkYXRhIHR5cGVzIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIFdlYkdMIHRleHR1cmVcbiAgICovXG4gIGV4cG9ydCB0eXBlIFRleHR1cmVEYXRhVHlwZXMgPSAnZmxvYXQzMic7XG5cbiAgdHlwZSBHcHVCdWZmZXJUeXBlRmFsbGJhY2sgPSB7IHNpemU6IG51bWJlcjsgbWFwU3RhdGU6ICd1bm1hcHBlZCcgfCAncGVuZGluZycgfCAnbWFwcGVkJyB9O1xuICAvKipcbiAgICogdHlwZSBhbGlhcyBmb3IgV2ViR1BVIGJ1ZmZlclxuICAgKi9cbiAgZXhwb3J0IHR5cGUgR3B1QnVmZmVyVHlwZSA9IFRyeUdldEdsb2JhbFR5cGU8J0dQVUJ1ZmZlcicsIEdwdUJ1ZmZlclR5cGVGYWxsYmFjaz47XG5cbiAgdHlwZSBNTFRlbnNvclR5cGVGYWxsYmFjayA9IHsgZGVzdHJveSgpOiB2b2lkIH07XG4gIC8qKlxuICAgKiB0eXBlIGFsaWFzIGZvciBXZWJOTiBNTFRlbnNvclxuICAgKlxuICAgKiBUaGUgc3BlY2lmaWNhdGlvbiBmb3IgV2ViTk4ncyBNTFRlbnNvciBpcyBjdXJyZW50bHkgaW4gZmx1eC5cbiAgICovXG4gIGV4cG9ydCB0eXBlIE1MVGVuc29yVHlwZSA9IFRyeUdldEdsb2JhbFR5cGU8J01MVGVuc29yJywgTUxUZW5zb3JUeXBlRmFsbGJhY2s+O1xuXG4gIC8qKlxuICAgKiBzdXBwb3J0ZWQgZGF0YSB0eXBlcyBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBXZWJHUFUgYnVmZmVyXG4gICAqL1xuICBleHBvcnQgdHlwZSBHcHVCdWZmZXJEYXRhVHlwZXMgPSAnZmxvYXQzMicgfCAnZmxvYXQxNicgfCAnaW50MzInIHwgJ2ludDY0JyB8ICd1aW50MzInIHwgJ3VpbnQ4JyB8ICdib29sJztcblxuICAvKipcbiAgICogc3VwcG9ydGVkIGRhdGEgdHlwZXMgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgV2ViTk4gTUxUZW5zb3JcbiAgICovXG4gIGV4cG9ydCB0eXBlIE1MVGVuc29yRGF0YVR5cGVzID1cbiAgICB8ICdmbG9hdDMyJ1xuICAgIHwgJ2Zsb2F0MTYnXG4gICAgfCAnaW50OCdcbiAgICB8ICd1aW50OCdcbiAgICB8ICdpbnQzMidcbiAgICB8ICd1aW50MzInXG4gICAgfCAnaW50NjQnXG4gICAgfCAndWludDY0J1xuICAgIHwgJ2Jvb2wnXG4gICAgfCAndWludDQnXG4gICAgfCAnaW50NCc7XG5cbiAgLyoqXG4gICAqIHJlcHJlc2VudCB3aGVyZSB0aGUgdGVuc29yIGRhdGEgaXMgc3RvcmVkXG4gICAqL1xuICBleHBvcnQgdHlwZSBEYXRhTG9jYXRpb24gPSAnbm9uZScgfCAnY3B1JyB8ICdjcHUtcGlubmVkJyB8ICd0ZXh0dXJlJyB8ICdncHUtYnVmZmVyJyB8ICdtbC10ZW5zb3InO1xuXG4gIC8qKlxuICAgKiByZXByZXNlbnQgdGhlIGRhdGEgdHlwZSBvZiBhIHRlbnNvclxuICAgKi9cbiAgZXhwb3J0IHR5cGUgVHlwZSA9IGtleW9mIERhdGFUeXBlTWFwO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudCBtdWx0aS1kaW1lbnNpb25hbCBhcnJheXMgdG8gZmVlZCB0byBvciBmZXRjaCBmcm9tIG1vZGVsIGluZmVyZW5jaW5nLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFR5cGVkVGVuc29yPFQgZXh0ZW5kcyBUZW5zb3IuVHlwZT4gZXh0ZW5kcyBUeXBlZFRlbnNvckJhc2U8VD4sIFR5cGVkVGVuc29yVXRpbHM8VD4ge31cbi8qKlxuICogUmVwcmVzZW50IG11bHRpLWRpbWVuc2lvbmFsIGFycmF5cyB0byBmZWVkIHRvIG9yIGZldGNoIGZyb20gbW9kZWwgaW5mZXJlbmNpbmcuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yIGV4dGVuZHMgVHlwZWRUZW5zb3JCYXNlPFRlbnNvci5UeXBlPiwgVHlwZWRUZW5zb3JVdGlsczxUZW5zb3IuVHlwZT4ge31cblxuLyoqXG4gKiB0eXBlIFRlbnNvckNvbnN0cnVjdG9yIGRlZmluZXMgdGhlIGNvbnN0cnVjdG9ycyBvZiAnVGVuc29yJyB0byBjcmVhdGUgQ1BVIHRlbnNvciBpbnN0YW5jZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yQ29uc3RydWN0b3IgZXh0ZW5kcyBUZW5zb3JGYWN0b3J5IHtcbiAgLy8gI3JlZ2lvbiBDUFUgdGVuc29yIC0gc3BlY2lmeSBlbGVtZW50IHR5cGVcbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBzdHJpbmcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiB0eXBlLCBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFNwZWNpZnkgdGhlIGVsZW1lbnQgdHlwZS5cbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChcbiAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICBkYXRhOiBUZW5zb3IuRGF0YVR5cGVNYXBbJ3N0cmluZyddIHwgcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuICApOiBUeXBlZFRlbnNvcjwnc3RyaW5nJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBib29sIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gdHlwZSwgZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSBTcGVjaWZ5IHRoZSBlbGVtZW50IHR5cGUuXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoXG4gICAgdHlwZTogJ2Jvb2wnLFxuICAgIGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFsnYm9vbCddIHwgcmVhZG9ubHkgYm9vbGVhbltdLFxuICAgIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogVHlwZWRUZW5zb3I8J2Jvb2wnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHVpbnQ4IHRlbnNvciBvYmplY3QgZnJvbSBhIFVpbnQ4Q2xhbXBlZEFycmF5LCBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFNwZWNpZnkgdGhlIGVsZW1lbnQgdHlwZS5cbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3ICh0eXBlOiAndWludDgnLCBkYXRhOiBVaW50OENsYW1wZWRBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J3VpbnQ4Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyA2NC1iaXQgaW50ZWdlciB0eXBlZCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIHR5cGUsIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gU3BlY2lmeSB0aGUgZWxlbWVudCB0eXBlLlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgPFQgZXh0ZW5kcyAndWludDY0JyB8ICdpbnQ2NCc+KFxuICAgIHR5cGU6IFQsXG4gICAgZGF0YTogVGVuc29yLkRhdGFUeXBlTWFwW1RdIHwgcmVhZG9ubHkgYmlnaW50W10gfCByZWFkb25seSBudW1iZXJbXSxcbiAgICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IFR5cGVkVGVuc29yPFQ+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgbnVtZXJpYyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIHR5cGUsIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gU3BlY2lmeSB0aGUgZWxlbWVudCB0eXBlLlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgPFQgZXh0ZW5kcyBFeGNsdWRlPFRlbnNvci5UeXBlLCAnc3RyaW5nJyB8ICdib29sJyB8ICd1aW50NjQnIHwgJ2ludDY0Jz4+KFxuICAgIHR5cGU6IFQsXG4gICAgZGF0YTogVGVuc29yLkRhdGFUeXBlTWFwW1RdIHwgcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuICApOiBUeXBlZFRlbnNvcjxUPjtcbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gQ1BVIHRlbnNvciAtIGluZmVyIGVsZW1lbnQgdHlwZXNcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IGZsb2F0MzIgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IEZsb2F0MzJBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2Zsb2F0MzInPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IGludDggdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IEludDhBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2ludDgnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHVpbnQ4IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBVaW50OEFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwndWludDgnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHVpbnQ4IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBVaW50OENsYW1wZWRBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J3VpbnQ4Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB1aW50MTYgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IFVpbnQxNkFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwndWludDE2Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBpbnQxNiB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogSW50MTZBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2ludDE2Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBpbnQzMiB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogSW50MzJBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2ludDMyJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBpbnQ2NCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogQmlnSW50NjRBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2ludDY0Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBzdHJpbmcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IHJlYWRvbmx5IHN0cmluZ1tdLCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwnc3RyaW5nJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBib29sIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiByZWFkb25seSBib29sZWFuW10sIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCdib29sJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBmbG9hdDY0IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBGbG9hdDY0QXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCdmbG9hdDY0Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB1aW50MzIgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IFVpbnQzMkFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwndWludDMyJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB1aW50NjQgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IEJpZ1VpbnQ2NEFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwndWludDY0Jz47XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gQ1BVIHRlbnNvciAtIGZhbGwgYmFjayB0byBub24tZ2VuZXJpYyB0ZW5zb3IgdHlwZSBkZWNsYXJhdGlvblxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiB0eXBlLCBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFNwZWNpZnkgdGhlIGVsZW1lbnQgdHlwZS5cbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChcbiAgICB0eXBlOiBUZW5zb3IuVHlwZSxcbiAgICBkYXRhOiBUZW5zb3IuRGF0YVR5cGUgfCByZWFkb25seSBudW1iZXJbXSB8IHJlYWRvbmx5IHN0cmluZ1tdIHwgcmVhZG9ubHkgYmlnaW50W10gfCByZWFkb25seSBib29sZWFuW10sXG4gICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuICApOiBUZW5zb3I7XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogVGVuc29yLkRhdGFUeXBlLCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3I7XG4gIC8vICNlbmRyZWdpb25cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZXhwb3J0IGNvbnN0IFRlbnNvciA9IFRlbnNvckltcGwgYXMgVGVuc29yQ29uc3RydWN0b3I7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiB9IGZyb20gJy4vZW52LWltcGwuanMnO1xuXG4vKipcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGNvbnN0IFRSQUNFID0gKGRldmljZVR5cGU6IHN0cmluZywgbGFiZWw6IHN0cmluZykgPT4ge1xuICBpZiAodHlwZW9mIGVudi50cmFjZSA9PT0gJ3VuZGVmaW5lZCcgPyAhZW52Lndhc20udHJhY2UgOiAhZW52LnRyYWNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gIGNvbnNvbGUudGltZVN0YW1wKGAke2RldmljZVR5cGV9OjpPUlQ6OiR7bGFiZWx9YCk7XG59O1xuXG5jb25zdCBUUkFDRV9GVU5DID0gKG1zZzogc3RyaW5nLCBleHRyYU1zZz86IHN0cmluZykgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBFcnJvcigpLnN0YWNrPy5zcGxpdCgvXFxyXFxufFxccnxcXG4vZykgfHwgW107XG4gIGxldCBoYXNUcmFjZUZ1bmMgPSBmYWxzZTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdGFjay5sZW5ndGg7IGkrKykge1xuICAgIGlmIChoYXNUcmFjZUZ1bmMgJiYgIXN0YWNrW2ldLmluY2x1ZGVzKCdUUkFDRV9GVU5DJykpIHtcbiAgICAgIGxldCBsYWJlbCA9IGBGVU5DXyR7bXNnfTo6JHtzdGFja1tpXS50cmltKCkuc3BsaXQoJyAnKVsxXX1gO1xuICAgICAgaWYgKGV4dHJhTXNnKSB7XG4gICAgICAgIGxhYmVsICs9IGA6OiR7ZXh0cmFNc2d9YDtcbiAgICAgIH1cbiAgICAgIFRSQUNFKCdDUFUnLCBsYWJlbCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChzdGFja1tpXS5pbmNsdWRlcygnVFJBQ0VfRlVOQycpKSB7XG4gICAgICBoYXNUcmFjZUZ1bmMgPSB0cnVlO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCBUUkFDRV9GVU5DX0JFR0lOID0gKGV4dHJhTXNnPzogc3RyaW5nKSA9PiB7XG4gIGlmICh0eXBlb2YgZW52LnRyYWNlID09PSAndW5kZWZpbmVkJyA/ICFlbnYud2FzbS50cmFjZSA6ICFlbnYudHJhY2UpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgVFJBQ0VfRlVOQygnQkVHSU4nLCBleHRyYU1zZyk7XG59O1xuXG4vKipcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGNvbnN0IFRSQUNFX0ZVTkNfRU5EID0gKGV4dHJhTXNnPzogc3RyaW5nKSA9PiB7XG4gIGlmICh0eXBlb2YgZW52LnRyYWNlID09PSAndW5kZWZpbmVkJyA/ICFlbnYud2FzbS50cmFjZSA6ICFlbnYudHJhY2UpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgVFJBQ0VfRlVOQygnRU5EJywgZXh0cmFNc2cpO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgcmVzb2x2ZUJhY2tlbmRBbmRFeGVjdXRpb25Qcm92aWRlcnMgfSBmcm9tICcuL2JhY2tlbmQtaW1wbC5qcyc7XG5pbXBvcnQgeyBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciB9IGZyb20gJy4vYmFja2VuZC5qcyc7XG5pbXBvcnQgeyBJbmZlcmVuY2VTZXNzaW9uIGFzIEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UgfSBmcm9tICcuL2luZmVyZW5jZS1zZXNzaW9uLmpzJztcbmltcG9ydCB7IE9ubnhWYWx1ZSB9IGZyb20gJy4vb25ueC12YWx1ZS5qcyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvci5qcyc7XG5pbXBvcnQgeyBUUkFDRV9GVU5DX0JFR0lOLCBUUkFDRV9GVU5DX0VORCB9IGZyb20gJy4vdHJhY2UuanMnO1xuXG50eXBlIFNlc3Npb25PcHRpb25zID0gSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZS5TZXNzaW9uT3B0aW9ucztcbnR5cGUgUnVuT3B0aW9ucyA9IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuUnVuT3B0aW9ucztcbnR5cGUgRmVlZHNUeXBlID0gSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZS5GZWVkc1R5cGU7XG50eXBlIEZldGNoZXNUeXBlID0gSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZS5GZXRjaGVzVHlwZTtcbnR5cGUgUmV0dXJuVHlwZSA9IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuUmV0dXJuVHlwZTtcblxuZXhwb3J0IGNsYXNzIEluZmVyZW5jZVNlc3Npb24gaW1wbGVtZW50cyBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlIHtcbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihoYW5kbGVyOiBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcikge1xuICAgIHRoaXMuaGFuZGxlciA9IGhhbmRsZXI7XG4gIH1cbiAgcnVuKGZlZWRzOiBGZWVkc1R5cGUsIG9wdGlvbnM/OiBSdW5PcHRpb25zKTogUHJvbWlzZTxSZXR1cm5UeXBlPjtcbiAgcnVuKGZlZWRzOiBGZWVkc1R5cGUsIGZldGNoZXM6IEZldGNoZXNUeXBlLCBvcHRpb25zPzogUnVuT3B0aW9ucyk6IFByb21pc2U8UmV0dXJuVHlwZT47XG4gIGFzeW5jIHJ1bihmZWVkczogRmVlZHNUeXBlLCBhcmcxPzogRmV0Y2hlc1R5cGUgfCBSdW5PcHRpb25zLCBhcmcyPzogUnVuT3B0aW9ucyk6IFByb21pc2U8UmV0dXJuVHlwZT4ge1xuICAgIFRSQUNFX0ZVTkNfQkVHSU4oKTtcbiAgICBjb25zdCBmZXRjaGVzOiB7IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfCBudWxsIH0gPSB7fTtcbiAgICBsZXQgb3B0aW9uczogUnVuT3B0aW9ucyA9IHt9O1xuICAgIC8vIGNoZWNrIGlucHV0c1xuICAgIGlmICh0eXBlb2YgZmVlZHMgIT09ICdvYmplY3QnIHx8IGZlZWRzID09PSBudWxsIHx8IGZlZWRzIGluc3RhbmNlb2YgVGVuc29yIHx8IEFycmF5LmlzQXJyYXkoZmVlZHMpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICBcIidmZWVkcycgbXVzdCBiZSBhbiBvYmplY3QgdGhhdCB1c2UgaW5wdXQgbmFtZXMgYXMga2V5cyBhbmQgT25ueFZhbHVlIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlwiLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBsZXQgaXNGZXRjaGVzRW1wdHkgPSB0cnVlO1xuICAgIC8vIGRldGVybWluZSB3aGljaCBvdmVycmlkZSBpcyBiZWluZyB1c2VkXG4gICAgaWYgKHR5cGVvZiBhcmcxID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKGFyZzEgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5leHBlY3RlZCBhcmd1bWVudFsxXTogY2Fubm90IGJlIG51bGwuJyk7XG4gICAgICB9XG4gICAgICBpZiAoYXJnMSBpbnN0YW5jZW9mIFRlbnNvcikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ2ZldGNoZXMnIGNhbm5vdCBiZSBhIFRlbnNvclwiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYXJnMSkpIHtcbiAgICAgICAgaWYgKGFyZzEubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidmZXRjaGVzJyBjYW5ub3QgYmUgYW4gZW1wdHkgYXJyYXkuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlzRmV0Y2hlc0VtcHR5ID0gZmFsc2U7XG4gICAgICAgIC8vIG91dHB1dCBuYW1lc1xuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgYXJnMSkge1xuICAgICAgICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInZmV0Y2hlcycgbXVzdCBiZSBhIHN0cmluZyBhcnJheSBvciBhbiBvYmplY3QuXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodGhpcy5vdXRwdXROYW1lcy5pbmRleE9mKG5hbWUpID09PSAtMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYCdmZXRjaGVzJyBjb250YWlucyBpbnZhbGlkIG91dHB1dCBuYW1lOiAke25hbWV9LmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmZXRjaGVzW25hbWVdID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgYXJnMiA9PT0gJ29iamVjdCcgJiYgYXJnMiAhPT0gbnVsbCkge1xuICAgICAgICAgIG9wdGlvbnMgPSBhcmcyO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInb3B0aW9ucycgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBkZWNpZGUgd2hldGhlciBhcmcxIGlzIGZldGNoZXMgb3Igb3B0aW9uc1xuICAgICAgICAvLyBpZiBhbnkgb3V0cHV0IG5hbWUgaXMgcHJlc2VudCBhbmQgaXRzIHZhbHVlIGlzIHZhbGlkIE9ubnhWYWx1ZSwgd2UgY29uc2lkZXIgaXQgZmV0Y2hlc1xuICAgICAgICBsZXQgaXNGZXRjaGVzID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IGFyZzFLZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoYXJnMSk7XG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLm91dHB1dE5hbWVzKSB7XG4gICAgICAgICAgaWYgKGFyZzFLZXlzLmluZGV4T2YobmFtZSkgIT09IC0xKSB7XG4gICAgICAgICAgICBjb25zdCB2ID0gKGFyZzEgYXMgSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZS5OdWxsYWJsZU9ubnhWYWx1ZU1hcFR5cGUpW25hbWVdO1xuICAgICAgICAgICAgaWYgKHYgPT09IG51bGwgfHwgdiBpbnN0YW5jZW9mIFRlbnNvcikge1xuICAgICAgICAgICAgICBpc0ZldGNoZXMgPSB0cnVlO1xuICAgICAgICAgICAgICBpc0ZldGNoZXNFbXB0eSA9IGZhbHNlO1xuICAgICAgICAgICAgICBmZXRjaGVzW25hbWVdID0gdjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNGZXRjaGVzKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBhcmcyID09PSAnb2JqZWN0JyAmJiBhcmcyICE9PSBudWxsKSB7XG4gICAgICAgICAgICBvcHRpb25zID0gYXJnMjtcbiAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidvcHRpb25zJyBtdXN0IGJlIGFuIG9iamVjdC5cIik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9wdGlvbnMgPSBhcmcxIGFzIFJ1bk9wdGlvbnM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcxICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlVuZXhwZWN0ZWQgYXJndW1lbnRbMV06IG11c3QgYmUgJ2ZldGNoZXMnIG9yICdvcHRpb25zJy5cIik7XG4gICAgfVxuXG4gICAgLy8gY2hlY2sgaWYgYWxsIGlucHV0cyBhcmUgaW4gZmVlZFxuICAgIGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLmlucHV0TmFtZXMpIHtcbiAgICAgIGlmICh0eXBlb2YgZmVlZHNbbmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXQgJyR7bmFtZX0nIGlzIG1pc3NpbmcgaW4gJ2ZlZWRzJy5gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpZiBubyBmZXRjaGVzIGlzIHNwZWNpZmllZCwgd2UgdXNlIHRoZSBmdWxsIG91dHB1dCBuYW1lcyBsaXN0XG4gICAgaWYgKGlzRmV0Y2hlc0VtcHR5KSB7XG4gICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgdGhpcy5vdXRwdXROYW1lcykge1xuICAgICAgICBmZXRjaGVzW25hbWVdID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBmZWVkcywgZmV0Y2hlcyBhbmQgb3B0aW9ucyBhcmUgcHJlcGFyZWRcblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmhhbmRsZXIucnVuKGZlZWRzLCBmZXRjaGVzLCBvcHRpb25zKTtcbiAgICBjb25zdCByZXR1cm5WYWx1ZTogeyBbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlIH0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiByZXN1bHRzKSB7XG4gICAgICBpZiAoT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwocmVzdWx0cywga2V5KSkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSByZXN1bHRzW2tleV07XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBUZW5zb3IpIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZVtrZXldID0gcmVzdWx0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVyblZhbHVlW2tleV0gPSBuZXcgVGVuc29yKHJlc3VsdC50eXBlLCByZXN1bHQuZGF0YSwgcmVzdWx0LmRpbXMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIFRSQUNFX0ZVTkNfRU5EKCk7XG4gICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICB9XG5cbiAgYXN5bmMgcmVsZWFzZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVyLmRpc3Bvc2UoKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGUocGF0aDogc3RyaW5nLCBvcHRpb25zPzogU2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2U+O1xuICBzdGF0aWMgY3JlYXRlKGJ1ZmZlcjogQXJyYXlCdWZmZXJMaWtlLCBvcHRpb25zPzogU2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2U+O1xuICBzdGF0aWMgY3JlYXRlKFxuICAgIGJ1ZmZlcjogQXJyYXlCdWZmZXJMaWtlLFxuICAgIGJ5dGVPZmZzZXQ6IG51bWJlcixcbiAgICBieXRlTGVuZ3RoPzogbnVtYmVyLFxuICAgIG9wdGlvbnM/OiBTZXNzaW9uT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlPjtcbiAgc3RhdGljIGNyZWF0ZShidWZmZXI6IFVpbnQ4QXJyYXksIG9wdGlvbnM/OiBTZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZT47XG4gIHN0YXRpYyBhc3luYyBjcmVhdGUoXG4gICAgYXJnMDogc3RyaW5nIHwgQXJyYXlCdWZmZXJMaWtlIHwgVWludDhBcnJheSxcbiAgICBhcmcxPzogU2Vzc2lvbk9wdGlvbnMgfCBudW1iZXIsXG4gICAgYXJnMj86IG51bWJlcixcbiAgICBhcmczPzogU2Vzc2lvbk9wdGlvbnMsXG4gICk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZT4ge1xuICAgIFRSQUNFX0ZVTkNfQkVHSU4oKTtcbiAgICAvLyBlaXRoZXIgbG9hZCBmcm9tIGEgZmlsZSBvciBidWZmZXJcbiAgICBsZXQgZmlsZVBhdGhPclVpbnQ4QXJyYXk6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gICAgbGV0IG9wdGlvbnM6IFNlc3Npb25PcHRpb25zID0ge307XG5cbiAgICBpZiAodHlwZW9mIGFyZzAgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmaWxlUGF0aE9yVWludDhBcnJheSA9IGFyZzA7XG4gICAgICBpZiAodHlwZW9mIGFyZzEgPT09ICdvYmplY3QnICYmIGFyZzEgIT09IG51bGwpIHtcbiAgICAgICAgb3B0aW9ucyA9IGFyZzE7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcxICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ29wdGlvbnMnIG11c3QgYmUgYW4gb2JqZWN0LlwiKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGFyZzAgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICBmaWxlUGF0aE9yVWludDhBcnJheSA9IGFyZzA7XG4gICAgICBpZiAodHlwZW9mIGFyZzEgPT09ICdvYmplY3QnICYmIGFyZzEgIT09IG51bGwpIHtcbiAgICAgICAgb3B0aW9ucyA9IGFyZzE7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcxICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ29wdGlvbnMnIG11c3QgYmUgYW4gb2JqZWN0LlwiKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKFxuICAgICAgYXJnMCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8XG4gICAgICAodHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiBhcmcwIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXIpXG4gICAgKSB7XG4gICAgICBjb25zdCBidWZmZXIgPSBhcmcwO1xuICAgICAgbGV0IGJ5dGVPZmZzZXQgPSAwO1xuICAgICAgbGV0IGJ5dGVMZW5ndGggPSBhcmcwLmJ5dGVMZW5ndGg7XG4gICAgICBpZiAodHlwZW9mIGFyZzEgPT09ICdvYmplY3QnICYmIGFyZzEgIT09IG51bGwpIHtcbiAgICAgICAgb3B0aW9ucyA9IGFyZzE7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcxID09PSAnbnVtYmVyJykge1xuICAgICAgICBieXRlT2Zmc2V0ID0gYXJnMTtcbiAgICAgICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihieXRlT2Zmc2V0KSkge1xuICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiJ2J5dGVPZmZzZXQnIG11c3QgYmUgYW4gaW50ZWdlci5cIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJ5dGVPZmZzZXQgPCAwIHx8IGJ5dGVPZmZzZXQgPj0gYnVmZmVyLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgJ2J5dGVPZmZzZXQnIGlzIG91dCBvZiByYW5nZSBbMCwgJHtidWZmZXIuYnl0ZUxlbmd0aH0pLmApO1xuICAgICAgICB9XG4gICAgICAgIGJ5dGVMZW5ndGggPSBhcmcwLmJ5dGVMZW5ndGggLSBieXRlT2Zmc2V0O1xuICAgICAgICBpZiAodHlwZW9mIGFyZzIgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgYnl0ZUxlbmd0aCA9IGFyZzI7XG4gICAgICAgICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihieXRlTGVuZ3RoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCInYnl0ZUxlbmd0aCcgbXVzdCBiZSBhbiBpbnRlZ2VyLlwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGJ5dGVMZW5ndGggPD0gMCB8fCBieXRlT2Zmc2V0ICsgYnl0ZUxlbmd0aCA+IGJ1ZmZlci5ieXRlTGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgJ2J5dGVMZW5ndGgnIGlzIG91dCBvZiByYW5nZSAoMCwgJHtidWZmZXIuYnl0ZUxlbmd0aCAtIGJ5dGVPZmZzZXR9XS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHR5cGVvZiBhcmczID09PSAnb2JqZWN0JyAmJiBhcmczICE9PSBudWxsKSB7XG4gICAgICAgICAgICBvcHRpb25zID0gYXJnMztcbiAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmczICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidvcHRpb25zJyBtdXN0IGJlIGFuIG9iamVjdC5cIik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInYnl0ZUxlbmd0aCcgbXVzdCBiZSBhIG51bWJlci5cIik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInb3B0aW9ucycgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgICAgfVxuICAgICAgZmlsZVBhdGhPclVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiVW5leHBlY3RlZCBhcmd1bWVudFswXTogbXVzdCBiZSAncGF0aCcgb3IgJ2J1ZmZlcicuXCIpO1xuICAgIH1cblxuICAgIC8vIHJlc29sdmUgYmFja2VuZCwgdXBkYXRlIHNlc3Npb24gb3B0aW9ucyB3aXRoIHZhbGlkYXRlZCBFUHMsIGFuZCBjcmVhdGUgc2Vzc2lvbiBoYW5kbGVyXG4gICAgY29uc3QgW2JhY2tlbmQsIG9wdGlvbnNXaXRoVmFsaWRhdGVkRVBzXSA9IGF3YWl0IHJlc29sdmVCYWNrZW5kQW5kRXhlY3V0aW9uUHJvdmlkZXJzKG9wdGlvbnMpO1xuICAgIGNvbnN0IGhhbmRsZXIgPSBhd2FpdCBiYWNrZW5kLmNyZWF0ZUluZmVyZW5jZVNlc3Npb25IYW5kbGVyKGZpbGVQYXRoT3JVaW50OEFycmF5LCBvcHRpb25zV2l0aFZhbGlkYXRlZEVQcyk7XG4gICAgVFJBQ0VfRlVOQ19FTkQoKTtcbiAgICByZXR1cm4gbmV3IEluZmVyZW5jZVNlc3Npb24oaGFuZGxlcik7XG4gIH1cblxuICBzdGFydFByb2ZpbGluZygpOiB2b2lkIHtcbiAgICB0aGlzLmhhbmRsZXIuc3RhcnRQcm9maWxpbmcoKTtcbiAgfVxuICBlbmRQcm9maWxpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5oYW5kbGVyLmVuZFByb2ZpbGluZygpO1xuICB9XG5cbiAgZ2V0IGlucHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIuaW5wdXROYW1lcztcbiAgfVxuICBnZXQgb3V0cHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIub3V0cHV0TmFtZXM7XG4gIH1cblxuICBnZXQgaW5wdXRNZXRhZGF0YSgpOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLlZhbHVlTWV0YWRhdGFbXSB7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlci5pbnB1dE1ldGFkYXRhO1xuICB9XG5cbiAgZ2V0IG91dHB1dE1ldGFkYXRhKCk6IHJlYWRvbmx5IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuVmFsdWVNZXRhZGF0YVtdIHtcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVyLm91dHB1dE1ldGFkYXRhO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVyOiBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcjtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbiBhcyBJbmZlcmVuY2VTZXNzaW9uSW1wbCB9IGZyb20gJy4vaW5mZXJlbmNlLXNlc3Npb24taW1wbC5qcyc7XG5pbXBvcnQgeyBPbm54TW9kZWxPcHRpb25zIH0gZnJvbSAnLi9vbm54LW1vZGVsLmpzJztcbmltcG9ydCB7IE9ubnhWYWx1ZSwgT25ueFZhbHVlRGF0YUxvY2F0aW9uIH0gZnJvbSAnLi9vbm54LXZhbHVlLmpzJztcbmltcG9ydCB0eXBlIHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3IuanMnO1xuaW1wb3J0IHsgVHJ5R2V0R2xvYmFsVHlwZSB9IGZyb20gJy4vdHlwZS1oZWxwZXIuanMnO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlICovXG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgLy8gI3JlZ2lvbiBpbnB1dC9vdXRwdXQgdHlwZXNcblxuICB0eXBlIE9ubnhWYWx1ZU1hcFR5cGUgPSB7IHJlYWRvbmx5IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfTtcbiAgdHlwZSBOdWxsYWJsZU9ubnhWYWx1ZU1hcFR5cGUgPSB7IHJlYWRvbmx5IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfCBudWxsIH07XG5cbiAgLyoqXG4gICAqIEEgZmVlZHMgKG1vZGVsIGlucHV0cykgaXMgYW4gb2JqZWN0IHRoYXQgdXNlcyBpbnB1dCBuYW1lcyBhcyBrZXlzIGFuZCBPbm54VmFsdWUgYXMgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAqL1xuICB0eXBlIEZlZWRzVHlwZSA9IE9ubnhWYWx1ZU1hcFR5cGU7XG5cbiAgLyoqXG4gICAqIEEgZmV0Y2hlcyAobW9kZWwgb3V0cHV0cykgY291bGQgYmUgb25lIG9mIHRoZSBmb2xsb3dpbmc6XG4gICAqXG4gICAqIC0gT21pdHRlZC4gVXNlIG1vZGVsJ3Mgb3V0cHV0IG5hbWVzIGRlZmluaXRpb24uXG4gICAqIC0gQW4gYXJyYXkgb2Ygc3RyaW5nIGluZGljYXRpbmcgdGhlIG91dHB1dCBuYW1lcy5cbiAgICogLSBBbiBvYmplY3QgdGhhdCB1c2Ugb3V0cHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBvciBudWxsIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcmVtYXJrXG4gICAqIGRpZmZlcmVudCBmcm9tIGlucHV0IGFyZ3VtZW50LCBpbiBvdXRwdXQsIE9ubnhWYWx1ZSBpcyBvcHRpb25hbC4gSWYgYW4gT25ueFZhbHVlIGlzIHByZXNlbnQgaXQgd2lsbCBiZVxuICAgKiB1c2VkIGFzIGEgcHJlLWFsbG9jYXRlZCB2YWx1ZSBieSB0aGUgaW5mZXJlbmNlIGVuZ2luZTsgaWYgb21pdHRlZCwgaW5mZXJlbmNlIGVuZ2luZSB3aWxsIGFsbG9jYXRlIGJ1ZmZlclxuICAgKiBpbnRlcm5hbGx5LlxuICAgKi9cbiAgdHlwZSBGZXRjaGVzVHlwZSA9IHJlYWRvbmx5IHN0cmluZ1tdIHwgTnVsbGFibGVPbm54VmFsdWVNYXBUeXBlO1xuXG4gIC8qKlxuICAgKiBBIGluZmVyZW5jaW5nIHJldHVybiB0eXBlIGlzIGFuIG9iamVjdCB0aGF0IHVzZXMgb3V0cHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICovXG4gIHR5cGUgUmV0dXJuVHlwZSA9IE9ubnhWYWx1ZU1hcFR5cGU7XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gc2Vzc2lvbiBvcHRpb25zXG5cbiAgLyoqXG4gICAqIEEgc2V0IG9mIGNvbmZpZ3VyYXRpb25zIGZvciBzZXNzaW9uIGJlaGF2aW9yLlxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBTZXNzaW9uT3B0aW9ucyBleHRlbmRzIE9ubnhNb2RlbE9wdGlvbnMge1xuICAgIC8qKlxuICAgICAqIEFuIGFycmF5IG9mIGV4ZWN1dGlvbiBwcm92aWRlciBvcHRpb25zLlxuICAgICAqXG4gICAgICogQW4gZXhlY3V0aW9uIHByb3ZpZGVyIG9wdGlvbiBjYW4gYmUgYSBzdHJpbmcgaW5kaWNhdGluZyB0aGUgbmFtZSBvZiB0aGUgZXhlY3V0aW9uIHByb3ZpZGVyLFxuICAgICAqIG9yIGFuIG9iamVjdCBvZiBjb3JyZXNwb25kaW5nIHR5cGUuXG4gICAgICovXG4gICAgZXhlY3V0aW9uUHJvdmlkZXJzPzogcmVhZG9ubHkgRXhlY3V0aW9uUHJvdmlkZXJDb25maWdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBpbnRyYSBPUCB0aHJlYWRzIG51bWJlci5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpLlxuICAgICAqL1xuICAgIGludHJhT3BOdW1UaHJlYWRzPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGludGVyIE9QIHRocmVhZHMgbnVtYmVyLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkuXG4gICAgICovXG4gICAgaW50ZXJPcE51bVRocmVhZHM/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZnJlZSBkaW1lbnNpb24gb3ZlcnJpZGUuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgZnJlZURpbWVuc2lvbk92ZXJyaWRlcz86IHsgcmVhZG9ubHkgW2RpbWVuc2lvbk5hbWU6IHN0cmluZ106IG51bWJlciB9O1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wdGltaXphdGlvbiBsZXZlbC5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBncmFwaE9wdGltaXphdGlvbkxldmVsPzogJ2Rpc2FibGVkJyB8ICdiYXNpYycgfCAnZXh0ZW5kZWQnIHwgJ2FsbCc7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIGVuYWJsZSBDUFUgbWVtb3J5IGFyZW5hLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGVuYWJsZUNwdU1lbUFyZW5hPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgZW5hYmxlIG1lbW9yeSBwYXR0ZXJuLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGVuYWJsZU1lbVBhdHRlcm4/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogRXhlY3V0aW9uIG1vZGUuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgZXhlY3V0aW9uTW9kZT86ICdzZXF1ZW50aWFsJyB8ICdwYXJhbGxlbCc7XG5cbiAgICAvKipcbiAgICAgKiBPcHRpbWl6ZWQgbW9kZWwgZmlsZSBwYXRoLlxuICAgICAqXG4gICAgICogSWYgdGhpcyBzZXR0aW5nIGlzIHNwZWNpZmllZCwgdGhlIG9wdGltaXplZCBtb2RlbCB3aWxsIGJlIGR1bXBlZC4gSW4gYnJvd3NlciwgYSBibG9iIHdpbGwgYmUgY3JlYXRlZFxuICAgICAqIHdpdGggYSBwb3AtdXAgd2luZG93LlxuICAgICAqL1xuICAgIG9wdGltaXplZE1vZGVsRmlsZVBhdGg/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIGVuYWJsZSBwcm9maWxpbmcuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYSBwbGFjZWhvbGRlciBmb3IgYSBmdXR1cmUgdXNlLlxuICAgICAqL1xuICAgIGVuYWJsZVByb2ZpbGluZz86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBGaWxlIHByZWZpeCBmb3IgcHJvZmlsaW5nLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGEgcGxhY2Vob2xkZXIgZm9yIGEgZnV0dXJlIHVzZS5cbiAgICAgKi9cbiAgICBwcm9maWxlRmlsZVByZWZpeD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIExvZyBJRC5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBsb2dJZD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIExvZyBzZXZlcml0eSBsZXZlbC4gU2VlXG4gICAgICogaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9vbm54cnVudGltZS9ibG9iL21haW4vaW5jbHVkZS9vbm54cnVudGltZS9jb3JlL2NvbW1vbi9sb2dnaW5nL3NldmVyaXR5LmhcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBsb2dTZXZlcml0eUxldmVsPzogMCB8IDEgfCAyIHwgMyB8IDQ7XG5cbiAgICAvKipcbiAgICAgKiBMb2cgdmVyYm9zaXR5IGxldmVsLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIFdlYkFzc2VtYmx5IGJhY2tlbmQuIFdpbGwgc3VwcG9ydCBOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSBsYXRlclxuICAgICAqL1xuICAgIGxvZ1ZlcmJvc2l0eUxldmVsPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogU3BlY2lmeSBzdHJpbmcgYXMgYSBwcmVmZXJyZWQgZGF0YSBsb2NhdGlvbiBmb3IgYWxsIG91dHB1dHMsIG9yIGFuIG9iamVjdCB0aGF0IHVzZSBvdXRwdXQgbmFtZXMgYXMga2V5cyBhbmQgYVxuICAgICAqIHByZWZlcnJlZCBkYXRhIGxvY2F0aW9uIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIFdlYiBmb3IgV2ViR0wgYW5kIFdlYkdQVSBFUC5cbiAgICAgKi9cbiAgICBwcmVmZXJyZWRPdXRwdXRMb2NhdGlvbj86IE9ubnhWYWx1ZURhdGFMb2NhdGlvbiB8IHsgcmVhZG9ubHkgW291dHB1dE5hbWU6IHN0cmluZ106IE9ubnhWYWx1ZURhdGFMb2NhdGlvbiB9O1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciBlbmFibGUgZ3JhcGggY2FwdHVyZS5cbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgV2ViIGZvciBXZWJHUFUgRVAuXG4gICAgICovXG4gICAgZW5hYmxlR3JhcGhDYXB0dXJlPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFN0b3JlIGNvbmZpZ3VyYXRpb25zIGZvciBhIHNlc3Npb24uIFNlZVxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvb25ueHJ1bnRpbWUvYmxvYi9tYWluL2luY2x1ZGUvb25ueHJ1bnRpbWUvY29yZS9zZXNzaW9uL1xuICAgICAqIG9ubnhydW50aW1lX3Nlc3Npb25fb3B0aW9uc19jb25maWdfa2V5cy5oXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gV2ViQXNzZW1ibHkgYmFja2VuZC4gV2lsbCBzdXBwb3J0IE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlIGxhdGVyXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZXh0cmE6IHtcbiAgICAgKiAgIHNlc3Npb246IHtcbiAgICAgKiAgICAgc2V0X2Rlbm9ybWFsX2FzX3plcm86IFwiMVwiLFxuICAgICAqICAgICBkaXNhYmxlX3ByZXBhY2tpbmc6IFwiMVwiXG4gICAgICogICB9LFxuICAgICAqICAgb3B0aW1pemF0aW9uOiB7XG4gICAgICogICAgIGVuYWJsZV9nZWx1X2FwcHJveGltYXRpb246IFwiMVwiXG4gICAgICogICB9XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGV4dHJhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIH1cblxuICAvLyAjcmVnaW9uIGV4ZWN1dGlvbiBwcm92aWRlcnNcblxuICAvLyBDdXJyZW50bHksIHdlIGhhdmUgdGhlIGZvbGxvd2luZyBiYWNrZW5kcyB0byBzdXBwb3J0IGV4ZWN1dGlvbiBwcm92aWRlcnM6XG4gIC8vIEJhY2tlbmQgTm9kZS5qcyBiaW5kaW5nOiBzdXBwb3J0cyAnY3B1JywgJ2RtbCcgKHdpbjMyKSwgJ2NvcmVtbCcgKG1hY09TKSBhbmQgJ2N1ZGEnIChsaW51eCkuXG4gIC8vIEJhY2tlbmQgV2ViQXNzZW1ibHk6IHN1cHBvcnRzICdjcHUnLCAnd2FzbScsICd3ZWJncHUnIGFuZCAnd2Vibm4nLlxuICAvLyBCYWNrZW5kIE9OTlguanM6IHN1cHBvcnRzICd3ZWJnbCcuXG4gIC8vIEJhY2tlbmQgUmVhY3QgTmF0aXZlOiBzdXBwb3J0cyAnY3B1JywgJ3hubnBhY2snLCAnY29yZW1sJyAoaU9TKSwgJ25uYXBpJyAoQW5kcm9pZCkuXG4gIGludGVyZmFjZSBFeGVjdXRpb25Qcm92aWRlck9wdGlvbk1hcCB7XG4gICAgY29yZW1sOiBDb3JlTUxFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICBjcHU6IENwdUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIGN1ZGE6IEN1ZGFFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICBkbWw6IERtbEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIG5uYXBpOiBObmFwaUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHRlbnNvcnJ0OiBUZW5zb3JSdEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHdhc206IFdlYkFzc2VtYmx5RXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgd2ViZ2w6IFdlYkdMRXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgd2ViZ3B1OiBXZWJHcHVFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICB3ZWJubjogV2ViTk5FeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICBxbm46IFFubkV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHhubnBhY2s6IFhubnBhY2tFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgfVxuXG4gIHR5cGUgRXhlY3V0aW9uUHJvdmlkZXJOYW1lID0ga2V5b2YgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb25NYXA7XG4gIHR5cGUgRXhlY3V0aW9uUHJvdmlkZXJDb25maWcgPVxuICAgIHwgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb25NYXBbRXhlY3V0aW9uUHJvdmlkZXJOYW1lXVxuICAgIHwgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb25cbiAgICB8IEV4ZWN1dGlvblByb3ZpZGVyTmFtZVxuICAgIHwgc3RyaW5nO1xuXG4gIGV4cG9ydCBpbnRlcmZhY2UgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIENwdUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdjcHUnO1xuICAgIHVzZUFyZW5hPzogYm9vbGVhbjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIEN1ZGFFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnY3VkYSc7XG4gICAgZGV2aWNlSWQ/OiBudW1iZXI7XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBEbWxFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnZG1sJztcbiAgICBkZXZpY2VJZD86IG51bWJlcjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFRlbnNvclJ0RXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3RlbnNvcnJ0JztcbiAgICBkZXZpY2VJZD86IG51bWJlcjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFdlYkFzc2VtYmx5RXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3dhc20nO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViR0xFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnd2ViZ2wnO1xuICAgIC8vIFRPRE86IGFkZCBmbGFnc1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgWG5ucGFja0V4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICd4bm5wYWNrJztcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFdlYkdwdUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICd3ZWJncHUnO1xuICAgIHByZWZlcnJlZExheW91dD86ICdOQ0hXJyB8ICdOSFdDJztcbiAgfVxuXG4gIC8vICNyZWdpb24gV2ViTk4gb3B0aW9uc1xuXG4gIGludGVyZmFjZSBXZWJOTkV4ZWN1dGlvblByb3ZpZGVyTmFtZSBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnd2Vibm4nO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgYSBzZXQgb2Ygb3B0aW9ucyBmb3IgY3JlYXRpbmcgYSBXZWJOTiBNTENvbnRleHQuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSL3dlYm5uLyNkaWN0ZGVmLW1sY29udGV4dG9wdGlvbnNcbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViTk5Db250ZXh0T3B0aW9ucyB7XG4gICAgZGV2aWNlVHlwZT86ICdjcHUnIHwgJ2dwdScgfCAnbnB1JztcbiAgICBudW1UaHJlYWRzPzogbnVtYmVyO1xuICAgIHBvd2VyUHJlZmVyZW5jZT86ICdkZWZhdWx0JyB8ICdsb3ctcG93ZXInIHwgJ2hpZ2gtcGVyZm9ybWFuY2UnO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgYSBzZXQgb2Ygb3B0aW9ucyBmb3IgV2ViTk4gZXhlY3V0aW9uIHByb3ZpZGVyIHdpdGhvdXQgTUxDb250ZXh0LlxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJOTk9wdGlvbnNXaXRob3V0TUxDb250ZXh0IGV4dGVuZHMgV2ViTk5FeGVjdXRpb25Qcm92aWRlck5hbWUsIFdlYk5OQ29udGV4dE9wdGlvbnMge1xuICAgIGNvbnRleHQ/OiBuZXZlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIGEgc2V0IG9mIG9wdGlvbnMgZm9yIFdlYk5OIGV4ZWN1dGlvbiBwcm92aWRlciB3aXRoIE1MQ29udGV4dC5cbiAgICpcbiAgICogV2hlbiBNTENvbnRleHQgaXMgcHJvdmlkZWQsIHRoZSBkZXZpY2VUeXBlIGlzIGFsc28gcmVxdWlyZWQgc28gdGhhdCB0aGUgV2ViTk4gRVAgY2FuIGRldGVybWluZSB0aGUgcHJlZmVycmVkXG4gICAqIGNoYW5uZWwgbGF5b3V0LlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi93ZWJubi8jZG9tLW1sLWNyZWF0ZWNvbnRleHRcbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViTk5PcHRpb25zV2l0aE1MQ29udGV4dFxuICAgIGV4dGVuZHMgV2ViTk5FeGVjdXRpb25Qcm92aWRlck5hbWUsXG4gICAgICBPbWl0PFdlYk5OQ29udGV4dE9wdGlvbnMsICdkZXZpY2VUeXBlJz4sXG4gICAgICBSZXF1aXJlZDxQaWNrPFdlYk5OQ29udGV4dE9wdGlvbnMsICdkZXZpY2VUeXBlJz4+IHtcbiAgICBjb250ZXh0OiBUcnlHZXRHbG9iYWxUeXBlPCdNTENvbnRleHQnPjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIGEgc2V0IG9mIG9wdGlvbnMgZm9yIFdlYk5OIGV4ZWN1dGlvbiBwcm92aWRlciB3aXRoIE1MQ29udGV4dCB3aGljaCBpcyBjcmVhdGVkIGZyb20gR1BVRGV2aWNlLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi93ZWJubi8jZG9tLW1sLWNyZWF0ZWNvbnRleHQtZ3B1ZGV2aWNlXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFdlYk5OT3B0aW9uc1dlYkdwdSBleHRlbmRzIFdlYk5ORXhlY3V0aW9uUHJvdmlkZXJOYW1lIHtcbiAgICBjb250ZXh0OiBUcnlHZXRHbG9iYWxUeXBlPCdNTENvbnRleHQnPjtcbiAgICBncHVEZXZpY2U6IFRyeUdldEdsb2JhbFR5cGU8J0dQVURldmljZSc+O1xuICB9XG5cbiAgLyoqXG4gICAqIE9wdGlvbnMgZm9yIFdlYk5OIGV4ZWN1dGlvbiBwcm92aWRlci5cbiAgICovXG4gIGV4cG9ydCB0eXBlIFdlYk5ORXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gPVxuICAgIHwgV2ViTk5PcHRpb25zV2l0aG91dE1MQ29udGV4dFxuICAgIHwgV2ViTk5PcHRpb25zV2l0aE1MQ29udGV4dFxuICAgIHwgV2ViTk5PcHRpb25zV2ViR3B1O1xuXG4gIC8vICNlbmRyZWdpb25cblxuICBleHBvcnQgaW50ZXJmYWNlIFFubkV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdxbm4nO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgdGhlIFFOTiBiYWNrZW5kIHR5cGUuIEUuZy4sICdjcHUnIG9yICdodHAnLlxuICAgICAqIE11dHVhbGx5IGV4Y2x1c2l2ZSB3aXRoIGBiYWNrZW5kUGF0aGAuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCAnaHRwJ1xuICAgICAqL1xuICAgIGJhY2tlbmRUeXBlPzogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgYSBwYXRoIHRvIHRoZSBRTk4gYmFja2VuZCBsaWJyYXJ5LlxuICAgICAqIE11dHVhbGx5IGV4Y2x1c2l2ZSB3aXRoIGBiYWNrZW5kVHlwZWAuXG4gICAgICovXG4gICAgYmFja2VuZFBhdGg/OiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB3aGV0aGVyIHRvIGVuYWJsZSBIVFAgRlAxNiBwcmVjaXNpb24uXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICovXG4gICAgZW5hYmxlRnAxNlByZWNpc2lvbj86IGJvb2xlYW47XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBDb3JlTUxFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnY29yZW1sJztcbiAgICAvKipcbiAgICAgKiBUaGUgYml0IGZsYWdzIGZvciBDb3JlTUwgZXhlY3V0aW9uIHByb3ZpZGVyLlxuICAgICAqXG4gICAgICogYGBgXG4gICAgICogQ09SRU1MX0ZMQUdfVVNFX0NQVV9PTkxZID0gMHgwMDFcbiAgICAgKiBDT1JFTUxfRkxBR19FTkFCTEVfT05fU1VCR1JBUEggPSAweDAwMlxuICAgICAqIENPUkVNTF9GTEFHX09OTFlfRU5BQkxFX0RFVklDRV9XSVRIX0FORSA9IDB4MDA0XG4gICAgICogQ09SRU1MX0ZMQUdfT05MWV9BTExPV19TVEFUSUNfSU5QVVRfU0hBUEVTID0gMHgwMDhcbiAgICAgKiBDT1JFTUxfRkxBR19DUkVBVEVfTUxQUk9HUkFNID0gMHgwMTBcbiAgICAgKiBDT1JFTUxfRkxBR19VU0VfQ1BVX0FORF9HUFUgPSAweDAyMFxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogU2VlIGluY2x1ZGUvb25ueHJ1bnRpbWUvY29yZS9wcm92aWRlcnMvY29yZW1sL2NvcmVtbF9wcm92aWRlcl9mYWN0b3J5LmggZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIFRoaXMgZmxhZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nKS5cbiAgICAgKi9cbiAgICBjb3JlTWxGbGFncz86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHdoZXRoZXIgdG8gdXNlIENQVSBvbmx5IGluIENvcmVNTCBFUC5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAocmVhY3QtbmF0aXZlKS5cbiAgICAgKi9cbiAgICB1c2VDUFVPbmx5PzogYm9vbGVhbjtcbiAgICB1c2VDUFVBbmRHUFU/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgd2hldGhlciB0byBlbmFibGUgQ29yZU1MIEVQIG9uIHN1YmdyYXBoLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChyZWFjdC1uYXRpdmUpLlxuICAgICAqL1xuICAgIGVuYWJsZU9uU3ViZ3JhcGg/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgd2hldGhlciB0byBvbmx5IGVuYWJsZSBDb3JlTUwgRVAgZm9yIEFwcGxlIGRldmljZXMgd2l0aCBBTkUgKEFwcGxlIE5ldXJhbCBFbmdpbmUpLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChyZWFjdC1uYXRpdmUpLlxuICAgICAqL1xuICAgIG9ubHlFbmFibGVEZXZpY2VXaXRoQU5FPzogYm9vbGVhbjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIE5uYXBpRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ25uYXBpJztcbiAgICB1c2VGUDE2PzogYm9vbGVhbjtcbiAgICB1c2VOQ0hXPzogYm9vbGVhbjtcbiAgICBjcHVEaXNhYmxlZD86IGJvb2xlYW47XG4gICAgY3B1T25seT86IGJvb2xlYW47XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHJ1biBvcHRpb25zXG5cbiAgLyoqXG4gICAqIEEgc2V0IG9mIGNvbmZpZ3VyYXRpb25zIGZvciBpbmZlcmVuY2UgcnVuIGJlaGF2aW9yXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFJ1bk9wdGlvbnMge1xuICAgIC8qKlxuICAgICAqIExvZyBzZXZlcml0eSBsZXZlbC4gU2VlXG4gICAgICogaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9vbm54cnVudGltZS9ibG9iL21haW4vaW5jbHVkZS9vbm54cnVudGltZS9jb3JlL2NvbW1vbi9sb2dnaW5nL3NldmVyaXR5LmhcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBsb2dTZXZlcml0eUxldmVsPzogMCB8IDEgfCAyIHwgMyB8IDQ7XG5cbiAgICAvKipcbiAgICAgKiBMb2cgdmVyYm9zaXR5IGxldmVsLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIFdlYkFzc2VtYmx5IGJhY2tlbmQuIFdpbGwgc3VwcG9ydCBOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSBsYXRlclxuICAgICAqL1xuICAgIGxvZ1ZlcmJvc2l0eUxldmVsPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogVGVybWluYXRlIGFsbCBpbmNvbXBsZXRlIE9ydFJ1biBjYWxscyBhcyBzb29uIGFzIHBvc3NpYmxlIGlmIHRydWVcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBXZWJBc3NlbWJseSBiYWNrZW5kLiBXaWxsIHN1cHBvcnQgTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUgbGF0ZXJcbiAgICAgKi9cbiAgICB0ZXJtaW5hdGU/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogQSB0YWcgZm9yIHRoZSBSdW4oKSBjYWxscyB1c2luZyB0aGlzXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgdGFnPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogU2V0IGEgc2luZ2xlIHJ1biBjb25maWd1cmF0aW9uIGVudHJ5LiBTZWVcbiAgICAgKiBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L29ubnhydW50aW1lL2Jsb2IvbWFpbi9pbmNsdWRlL29ubnhydW50aW1lL2NvcmUvc2Vzc2lvbi9cbiAgICAgKiBvbm54cnVudGltZV9ydW5fb3B0aW9uc19jb25maWdfa2V5cy5oXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gV2ViQXNzZW1ibHkgYmFja2VuZC4gV2lsbCBzdXBwb3J0IE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlIGxhdGVyXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBleHRyYToge1xuICAgICAqICAgbWVtb3J5OiB7XG4gICAgICogICAgIGVuYWJsZV9tZW1vcnlfYXJlbmFfc2hyaW5rYWdlOiBcIjFcIixcbiAgICAgKiAgIH1cbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZXh0cmE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHZhbHVlIG1ldGFkYXRhXG5cbiAgLyoqXG4gICAqIFRoZSBjb21tb24gcGFydCBvZiB0aGUgdmFsdWUgbWV0YWRhdGEgdHlwZSBmb3IgYm90aCB0ZW5zb3IgYW5kIG5vbi10ZW5zb3IgdmFsdWVzLlxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBWYWx1ZU1ldGFkYXRhQmFzZSB7XG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHNwZWNpZmllZCBpbnB1dCBvciBvdXRwdXQuXG4gICAgICovXG4gICAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgdGhlIG1ldGFkYXRhIG9mIGEgbm9uLXRlbnNvciB2YWx1ZS5cbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgTm9uVGVuc29yVmFsdWVNZXRhZGF0YSBleHRlbmRzIFZhbHVlTWV0YWRhdGFCYXNlIHtcbiAgICAvKipcbiAgICAgKiBHZXQgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHZhbHVlIGlzIGEgdGVuc29yLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IGlzVGVuc29yOiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIHRoZSBtZXRhZGF0YSBvZiBhIHRlbnNvciB2YWx1ZS5cbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgVGVuc29yVmFsdWVNZXRhZGF0YSBleHRlbmRzIFZhbHVlTWV0YWRhdGFCYXNlIHtcbiAgICAvKipcbiAgICAgKiBHZXQgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHZhbHVlIGlzIGEgdGVuc29yLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IGlzVGVuc29yOiB0cnVlO1xuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAgICovXG4gICAgcmVhZG9ubHkgdHlwZTogVGVuc29yLlR5cGU7XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBzaGFwZSBvZiB0aGUgdGVuc29yLlxuICAgICAqXG4gICAgICogSWYgdGhlIHNoYXBlIGlzIG5vdCBkZWZpbmVkLCB0aGUgdmFsdWUgd2lsbCBhbiBlbXB0eSBhcnJheS4gT3RoZXJ3aXNlLCBpdCB3aWxsIGJlIGFuIGFycmF5IHJlcHJlc2VudGluZyB0aGUgc2hhcGVcbiAgICAgKiBvZiB0aGUgdGVuc29yLiBFYWNoIGVsZW1lbnQgaW4gdGhlIGFycmF5IGNhbiBiZSBhIG51bWJlciBvciBhIHN0cmluZy4gSWYgdGhlIGVsZW1lbnQgaXMgYSBudW1iZXIsIGl0IHJlcHJlc2VudHNcbiAgICAgKiB0aGUgY29ycmVzcG9uZGluZyBkaW1lbnNpb24gc2l6ZS4gSWYgdGhlIGVsZW1lbnQgaXMgYSBzdHJpbmcsIGl0IHJlcHJlc2VudHMgYSBzeW1ib2xpYyBkaW1lbnNpb24uXG4gICAgICovXG4gICAgcmVhZG9ubHkgc2hhcGU6IFJlYWRvbmx5QXJyYXk8bnVtYmVyIHwgc3RyaW5nPjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIHRoZSBtZXRhZGF0YSBvZiBhIHZhbHVlLlxuICAgKi9cbiAgZXhwb3J0IHR5cGUgVmFsdWVNZXRhZGF0YSA9IE5vblRlbnNvclZhbHVlTWV0YWRhdGEgfCBUZW5zb3JWYWx1ZU1ldGFkYXRhO1xuXG4gIC8vICNlbmRyZWdpb25cbn1cblxuLyoqXG4gKiBSZXByZXNlbnQgYSBydW50aW1lIGluc3RhbmNlIG9mIGFuIE9OTlggbW9kZWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW5mZXJlbmNlU2Vzc2lvbiB7XG4gIC8vICNyZWdpb24gcnVuKClcblxuICAvKipcbiAgICogRXhlY3V0ZSB0aGUgbW9kZWwgYXN5bmNocm9ub3VzbHkgd2l0aCB0aGUgZ2l2ZW4gZmVlZHMgYW5kIG9wdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBmZWVkcyAtIFJlcHJlc2VudGF0aW9uIG9mIHRoZSBtb2RlbCBpbnB1dC4gU2VlIHR5cGUgZGVzY3JpcHRpb24gb2YgYEluZmVyZW5jZVNlc3Npb24uSW5wdXRUeXBlYCBmb3IgZGV0YWlsLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsLiBBIHNldCBvZiBvcHRpb25zIHRoYXQgY29udHJvbHMgdGhlIGJlaGF2aW9yIG9mIG1vZGVsIGluZmVyZW5jZS5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBtYXAsIHdoaWNoIHVzZXMgb3V0cHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICovXG4gIHJ1bihmZWVkczogSW5mZXJlbmNlU2Vzc2lvbi5GZWVkc1R5cGUsIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24uUmV0dXJuVHlwZT47XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgdGhlIG1vZGVsIGFzeW5jaHJvbm91c2x5IHdpdGggdGhlIGdpdmVuIGZlZWRzLCBmZXRjaGVzIGFuZCBvcHRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0gZmVlZHMgLSBSZXByZXNlbnRhdGlvbiBvZiB0aGUgbW9kZWwgaW5wdXQuIFNlZSB0eXBlIGRlc2NyaXB0aW9uIG9mIGBJbmZlcmVuY2VTZXNzaW9uLklucHV0VHlwZWAgZm9yIGRldGFpbC5cbiAgICogQHBhcmFtIGZldGNoZXMgLSBSZXByZXNlbnRhdGlvbiBvZiB0aGUgbW9kZWwgb3V0cHV0LiBTZWUgdHlwZSBkZXNjcmlwdGlvbiBvZiBgSW5mZXJlbmNlU2Vzc2lvbi5PdXRwdXRUeXBlYCBmb3JcbiAgICogZGV0YWlsLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsLiBBIHNldCBvZiBvcHRpb25zIHRoYXQgY29udHJvbHMgdGhlIGJlaGF2aW9yIG9mIG1vZGVsIGluZmVyZW5jZS5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBtYXAsIHdoaWNoIHVzZXMgb3V0cHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICovXG4gIHJ1bihcbiAgICBmZWVkczogSW5mZXJlbmNlU2Vzc2lvbi5GZWVkc1R5cGUsXG4gICAgZmV0Y2hlczogSW5mZXJlbmNlU2Vzc2lvbi5GZXRjaGVzVHlwZSxcbiAgICBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24uUmV0dXJuVHlwZT47XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcmVsZWFzZSgpXG5cbiAgLyoqXG4gICAqIFJlbGVhc2UgdGhlIGluZmVyZW5jZSBzZXNzaW9uIGFuZCB0aGUgdW5kZXJseWluZyByZXNvdXJjZXMuXG4gICAqL1xuICByZWxlYXNlKCk6IFByb21pc2U8dm9pZD47XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcHJvZmlsaW5nXG5cbiAgLyoqXG4gICAqIFN0YXJ0IHByb2ZpbGluZy5cbiAgICovXG4gIHN0YXJ0UHJvZmlsaW5nKCk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIEVuZCBwcm9maWxpbmcuXG4gICAqL1xuICBlbmRQcm9maWxpbmcoKTogdm9pZDtcblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBtZXRhZGF0YVxuXG4gIC8qKlxuICAgKiBHZXQgaW5wdXQgbmFtZXMgb2YgdGhlIGxvYWRlZCBtb2RlbC5cbiAgICovXG4gIHJlYWRvbmx5IGlucHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBHZXQgb3V0cHV0IG5hbWVzIG9mIHRoZSBsb2FkZWQgbW9kZWwuXG4gICAqL1xuICByZWFkb25seSBvdXRwdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEdldCBpbnB1dCBtZXRhZGF0YSBvZiB0aGUgbG9hZGVkIG1vZGVsLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5wdXRNZXRhZGF0YTogcmVhZG9ubHkgSW5mZXJlbmNlU2Vzc2lvbi5WYWx1ZU1ldGFkYXRhW107XG5cbiAgLyoqXG4gICAqIEdldCBvdXRwdXQgbWV0YWRhdGEgb2YgdGhlIGxvYWRlZCBtb2RlbC5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dE1ldGFkYXRhOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXTtcblxuICAvLyAjZW5kcmVnaW9uXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5mZXJlbmNlU2Vzc2lvbkZhY3Rvcnkge1xuICAvLyAjcmVnaW9uIGNyZWF0ZSgpXG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbiBhbmQgbG9hZCBtb2RlbCBhc3luY2hyb25vdXNseSBmcm9tIGFuIE9OTlggbW9kZWwgZmlsZS5cbiAgICpcbiAgICogQHBhcmFtIHVyaSAtIFRoZSBVUkkgb3IgZmlsZSBwYXRoIG9mIHRoZSBtb2RlbCB0byBsb2FkLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIHNwZWNpZnkgY29uZmlndXJhdGlvbiBmb3IgY3JlYXRpbmcgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24uXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEluZmVyZW5jZVNlc3Npb24gb2JqZWN0LlxuICAgKi9cbiAgY3JlYXRlKHVyaTogc3RyaW5nLCBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbj47XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbiBhbmQgbG9hZCBtb2RlbCBhc3luY2hyb25vdXNseSBmcm9tIGFuIGFycmF5IGJ1ZmVyLlxuICAgKlxuICAgKiBAcGFyYW0gYnVmZmVyIC0gQW4gQXJyYXlCdWZmZXIgcmVwcmVzZW50YXRpb24gb2YgYW4gT05OWCBtb2RlbC5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBzcGVjaWZ5IGNvbmZpZ3VyYXRpb24gZm9yIGNyZWF0aW5nIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBJbmZlcmVuY2VTZXNzaW9uIG9iamVjdC5cbiAgICovXG4gIGNyZWF0ZShidWZmZXI6IEFycmF5QnVmZmVyTGlrZSwgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24+O1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24gYW5kIGxvYWQgbW9kZWwgYXN5bmNocm9ub3VzbHkgZnJvbSBzZWdtZW50IG9mIGFuIGFycmF5IGJ1ZmVyLlxuICAgKlxuICAgKiBAcGFyYW0gYnVmZmVyIC0gQW4gQXJyYXlCdWZmZXIgcmVwcmVzZW50YXRpb24gb2YgYW4gT05OWCBtb2RlbC5cbiAgICogQHBhcmFtIGJ5dGVPZmZzZXQgLSBUaGUgYmVnaW5uaW5nIG9mIHRoZSBzcGVjaWZpZWQgcG9ydGlvbiBvZiB0aGUgYXJyYXkgYnVmZmVyLlxuICAgKiBAcGFyYW0gYnl0ZUxlbmd0aCAtIFRoZSBsZW5ndGggaW4gYnl0ZXMgb2YgdGhlIGFycmF5IGJ1ZmZlci5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBzcGVjaWZ5IGNvbmZpZ3VyYXRpb24gZm9yIGNyZWF0aW5nIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBJbmZlcmVuY2VTZXNzaW9uIG9iamVjdC5cbiAgICovXG4gIGNyZWF0ZShcbiAgICBidWZmZXI6IEFycmF5QnVmZmVyTGlrZSxcbiAgICBieXRlT2Zmc2V0OiBudW1iZXIsXG4gICAgYnl0ZUxlbmd0aD86IG51bWJlcixcbiAgICBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uPjtcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uIGFuZCBsb2FkIG1vZGVsIGFzeW5jaHJvbm91c2x5IGZyb20gYSBVaW50OEFycmF5LlxuICAgKlxuICAgKiBAcGFyYW0gYnVmZmVyIC0gQSBVaW50OEFycmF5IHJlcHJlc2VudGF0aW9uIG9mIGFuIE9OTlggbW9kZWwuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gc3BlY2lmeSBjb25maWd1cmF0aW9uIGZvciBjcmVhdGluZyBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gSW5mZXJlbmNlU2Vzc2lvbiBvYmplY3QuXG4gICAqL1xuICBjcmVhdGUoYnVmZmVyOiBVaW50OEFycmF5LCBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbj47XG5cbiAgLy8gI2VuZHJlZ2lvblxufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG5leHBvcnQgY29uc3QgSW5mZXJlbmNlU2Vzc2lvbjogSW5mZXJlbmNlU2Vzc2lvbkZhY3RvcnkgPSBJbmZlcmVuY2VTZXNzaW9uSW1wbDtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgT3B0aW9uc0Zvcm1hdCwgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzLCBPcHRpb25zVGVuc29yTGF5b3V0IH0gZnJvbSAnLi90ZW5zb3ItZmFjdG9yeS5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yVG9EYXRhVXJsT3B0aW9ucyBleHRlbmRzIE9wdGlvbnNUZW5zb3JMYXlvdXQsIE9wdGlvbnNGb3JtYXQsIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyBleHRlbmRzIE9wdGlvbnNUZW5zb3JMYXlvdXQsIE9wdGlvbnNGb3JtYXQsIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbnZlcnNpb25VdGlscyB7XG4gIC8qKlxuICAgKiBjcmVhdGVzIGEgRGF0YVVSTCBpbnN0YW5jZSBmcm9tIHRlbnNvclxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIG9iamVjdCByZXByZXNlbnRpbmcgb3B0aW9ucyBmb3IgY3JlYXRpbmcgYSBEYXRhVVJMIGluc3RhbmNlIGZyb20gdGhlIHRlbnNvci5cbiAgICpcbiAgICogVGhlIGZvbGxvd2luZyBkZWZhdWx0IHNldHRpbmdzIHdpbGwgYmUgYXBwbGllZDpcbiAgICogLSBgZm9ybWF0YDogYCdSR0InYFxuICAgKiAtIGB0ZW5zb3JMYXlvdXRgOiBgJ05DSFcnYFxuICAgKiBAcmV0dXJucyBhIERhdGFVUkwgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgaW1hZ2UgY29udmVydGVkIGZyb20gdGVuc29yIGRhdGFcbiAgICovXG4gIHRvRGF0YVVSTChvcHRpb25zPzogVGVuc29yVG9EYXRhVXJsT3B0aW9ucyk6IHN0cmluZztcblxuICAvKipcbiAgICogY3JlYXRlcyBhbiBJbWFnZURhdGEgaW5zdGFuY2UgZnJvbSB0ZW5zb3JcbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIGFuIEltYWdlRGF0YSBpbnN0YW5jZSBmcm9tIHRoZSB0ZW5zb3IuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYGZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogQHJldHVybnMgYW4gSW1hZ2VEYXRhIGluc3RhbmNlIHJlcHJlc2VudGluZyB0aGUgaW1hZ2UgY29udmVydGVkIGZyb20gdGVuc29yIGRhdGFcbiAgICovXG4gIHRvSW1hZ2VEYXRhKG9wdGlvbnM/OiBUZW5zb3JUb0ltYWdlRGF0YU9wdGlvbnMpOiBJbWFnZURhdGE7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciwgVHlwZWRUZW5zb3IgfSBmcm9tICcuL3RlbnNvci5qcyc7XG5cbmV4cG9ydCB0eXBlIEltYWdlRm9ybWF0ID0gJ1JHQicgfCAnUkdCQScgfCAnQkdSJyB8ICdSQkcnO1xuZXhwb3J0IHR5cGUgSW1hZ2VUZW5zb3JMYXlvdXQgPSAnTkhXQycgfCAnTkNIVyc7XG5cbi8vIHRoZSBmb2xsb3dpbmcgcmVnaW9uIGNvbnRhaW5zIHR5cGUgZGVmaW5pdGlvbnMgZm9yIGNvbnN0cnVjdGluZyB0ZW5zb3IgZnJvbSBhIHNwZWNpZmljIGxvY2F0aW9uLlxuXG4vLyAjcmVnaW9uIHR5cGVzIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIHNwZWNpZmljIGxvY2F0aW9uXG5cbi8qKlxuICogcmVwcmVzZW50IGNvbW1vbiBwcm9wZXJ0aWVzIG9mIHRoZSBwYXJhbWV0ZXIgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgc3BlY2lmaWMgbG9jYXRpb24uXG4gKi9cbmludGVyZmFjZSBDb21tb25Db25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4gZXh0ZW5kcyBQaWNrPFRlbnNvciwgJ2RpbXMnPiB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci5cbiAgICovXG4gIHJlYWRvbmx5IHR5cGU6IFQ7XG59XG5cbi8qKlxuICogcmVwcmVzZW50IHRoZSBwYXJhbWV0ZXIgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgR1BVIHJlc291cmNlLlxuICovXG5pbnRlcmZhY2UgR3B1UmVzb3VyY2VDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VCBleHRlbmRzIFRlbnNvci5UeXBlPiB7XG4gIC8qKlxuICAgKiBhbiBvcHRpb25hbCBjYWxsYmFjayBmdW5jdGlvbiB0byBkb3dubG9hZCBkYXRhIGZyb20gR1BVIHRvIENQVS5cbiAgICpcbiAgICogSWYgbm90IHByb3ZpZGVkLCB0aGUgdGVuc29yIHRyZWF0IHRoZSBHUFUgZGF0YSBhcyBleHRlcm5hbCByZXNvdXJjZS5cbiAgICovXG4gIGRvd25sb2FkPygpOiBQcm9taXNlPFRlbnNvci5EYXRhVHlwZU1hcFtUXT47XG5cbiAgLyoqXG4gICAqIGFuIG9wdGlvbmFsIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGUgdGVuc29yIGlzIGRpc3Bvc2VkLlxuICAgKlxuICAgKiBJZiBub3QgcHJvdmlkZWQsIHRoZSB0ZW5zb3IgdHJlYXQgdGhlIEdQVSBkYXRhIGFzIGV4dGVybmFsIHJlc291cmNlLlxuICAgKi9cbiAgZGlzcG9zZT8oKTogdm9pZDtcbn1cblxuLyoqXG4gKiByZXByZXNlbnQgdGhlIHBhcmFtZXRlciBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBwaW5uZWQgQ1BVIGJ1ZmZlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIENwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVyczxUIGV4dGVuZHMgVGVuc29yLkNwdVBpbm5lZERhdGFUeXBlcyA9IFRlbnNvci5DcHVQaW5uZWREYXRhVHlwZXM+XG4gIGV4dGVuZHMgQ29tbW9uQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIHRvIGJlICdjcHUtcGlubmVkJy5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiAnY3B1LXBpbm5lZCc7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBDUFUgcGlubmVkIGJ1ZmZlciB0aGF0IGhvbGRzIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICovXG4gIHJlYWRvbmx5IGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFtUXTtcbn1cblxuLyoqXG4gKiByZXByZXNlbnQgdGhlIHBhcmFtZXRlciBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBXZWJHTCB0ZXh0dXJlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dHVyZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUIGV4dGVuZHMgVGVuc29yLlRleHR1cmVEYXRhVHlwZXMgPSBUZW5zb3IuVGV4dHVyZURhdGFUeXBlcz5cbiAgZXh0ZW5kcyBDb21tb25Db25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4sXG4gICAgR3B1UmVzb3VyY2VDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4ge1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgbG9jYXRpb24gb2YgdGhlIGRhdGEgdG8gYmUgJ3RleHR1cmUnLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9jYXRpb246ICd0ZXh0dXJlJztcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIFdlYkdMIHRleHR1cmUgdGhhdCBob2xkcyB0aGUgdGVuc29yIGRhdGEuXG4gICAqL1xuICByZWFkb25seSB0ZXh0dXJlOiBUZW5zb3IuVGV4dHVyZVR5cGU7XG59XG5cbi8qKlxuICogcmVwcmVzZW50IHRoZSBwYXJhbWV0ZXIgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgV2ViR1BVIGJ1ZmZlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdwdUJ1ZmZlckNvbnN0cnVjdG9yUGFyYW1ldGVyczxUIGV4dGVuZHMgVGVuc29yLkdwdUJ1ZmZlckRhdGFUeXBlcyA9IFRlbnNvci5HcHVCdWZmZXJEYXRhVHlwZXM+XG4gIGV4dGVuZHMgQ29tbW9uQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+LFxuICAgIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIHRvIGJlICdncHUtYnVmZmVyJy5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiAnZ3B1LWJ1ZmZlcic7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBXZWJHUFUgYnVmZmVyIHRoYXQgaG9sZHMgdGhlIHRlbnNvciBkYXRhLlxuICAgKi9cbiAgcmVhZG9ubHkgZ3B1QnVmZmVyOiBUZW5zb3IuR3B1QnVmZmVyVHlwZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNTFRlbnNvckNvbnN0cnVjdG9yUGFyYW1ldGVyczxUIGV4dGVuZHMgVGVuc29yLk1MVGVuc29yRGF0YVR5cGVzID0gVGVuc29yLk1MVGVuc29yRGF0YVR5cGVzPlxuICBleHRlbmRzIENvbW1vbkNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPixcbiAgICBHcHVSZXNvdXJjZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBsb2NhdGlvbiBvZiB0aGUgZGF0YSB0byBiZSAnbWwtdGVuc29yJy5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiAnbWwtdGVuc29yJztcblxuICAvKipcbiAgICogU3BlY2lmeSB0aGUgV2ViTk4gTUxUZW5zb3IgdGhhdCBob2xkcyB0aGUgdGVuc29yIGRhdGEuXG4gICAqL1xuICByZWFkb25seSBtbFRlbnNvcjogVGVuc29yLk1MVGVuc29yVHlwZTtcbn1cblxuLy8gI2VuZHJlZ2lvblxuXG4vLyB0aGUgZm9sbG93aW5nIHJlZ2lvbiBjb250YWlucyB0eXBlIGRlZmluaXRpb25zIG9mIGVhY2ggaW5kaXZpZHVhbCBvcHRpb25zLlxuLy8gdGhlIHRlbnNvciBmYWN0b3J5IGZ1bmN0aW9ucyB1c2UgYSBjb21wb3NpdGlvbiBvZiB0aG9zZSBvcHRpb25zIGFzIHRoZSBwYXJhbWV0ZXIgdHlwZS5cblxuLy8gI3JlZ2lvbiBPcHRpb25zIGZpZWxkc1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnNGb3JtYXQge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBpbWFnZSBmb3JtYXQgcmVwcmVzZW50ZWQgaW4gUkdCQSBjb2xvciBzcGFjZS5cbiAgICovXG4gIGZvcm1hdD86IEltYWdlRm9ybWF0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnNUZW5zb3JGb3JtYXQge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBpbWFnZSBmb3JtYXQgb2YgdGhlIHRlbnNvci5cbiAgICpcbiAgICogTk9URTogdGhpcyBpcyBkaWZmZXJlbnQgZnJvbSBvcHRpb24gJ2Zvcm1hdCcuIFdoaWxlIG9wdGlvbiAnZm9ybWF0JyByZXByZXNlbnRzIHRoZSBvcmlnaW5hbCBpbWFnZSwgJ3RlbnNvckZvcm1hdCdcbiAgICogcmVwcmVzZW50cyB0aGUgdGFyZ2V0IGZvcm1hdCBvZiB0aGUgdGVuc29yLiBBIHRyYW5zcG9zZSB3aWxsIGJlIHBlcmZvcm1lZCBpZiB0aGV5IGFyZSBkaWZmZXJlbnQuXG4gICAqL1xuICB0ZW5zb3JGb3JtYXQ/OiBJbWFnZUZvcm1hdDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zVGVuc29yRGF0YVR5cGUge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci5cbiAgICovXG4gIGRhdGFUeXBlPzogJ2Zsb2F0MzInIHwgJ3VpbnQ4Jztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zVGVuc29yTGF5b3V0IHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgdGVuc29yIGxheW91dCB3aGVuIHJlcHJlc2VudGluZyBkYXRhIG9mIG9uZSBvciBtb3JlIGltYWdlKHMpLlxuICAgKi9cbiAgdGVuc29yTGF5b3V0PzogSW1hZ2VUZW5zb3JMYXlvdXQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9uc0RpbWVuc2lvbnMge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBpbWFnZSBoZWlnaHQgaW4gcGl4ZWxcbiAgICovXG4gIGhlaWdodD86IG51bWJlcjtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgaW1hZ2Ugd2lkdGggaW4gcGl4ZWxcbiAgICovXG4gIHdpZHRoPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvblJlc2l6ZWREaW1lbnNpb25zIHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgcmVzaXplZCBoZWlnaHQuIElmIG9taXR0ZWQsIG9yaWdpbmFsIGhlaWdodCB3aWxsIGJlIHVzZWQuXG4gICAqL1xuICByZXNpemVkSGVpZ2h0PzogbnVtYmVyO1xuICAvKipcbiAgICogRGVzY3JpYmVzIHJlc2l6ZWQgd2lkdGggLSBjYW4gYmUgYWNjZXNzZWQgdmlhIHRlbnNvciBkaW1lbnNpb25zIGFzIHdlbGxcbiAgICovXG4gIHJlc2l6ZWRXaWR0aD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMge1xuICAvKipcbiAgICogRGVzY3JpYmVzIG5vcm1hbGl6YXRpb24gcGFyYW1ldGVycyB3aGVuIHByZXByb2Nlc3NpbmcgdGhlIGltYWdlIGFzIG1vZGVsIGlucHV0LlxuICAgKlxuICAgKiBEYXRhIGVsZW1lbnQgYXJlIHJhbmdlZCBmcm9tIDAgdG8gMjU1LlxuICAgKi9cbiAgbm9ybT86IHtcbiAgICAvKipcbiAgICAgKiBUaGUgJ2JpYXMnIHZhbHVlIGZvciBpbWFnZSBub3JtYWxpemF0aW9uLlxuICAgICAqIC0gSWYgb21pdHRlZCwgdXNlIGRlZmF1bHQgdmFsdWUgMC5cbiAgICAgKiAtIElmIGl0J3MgYSBzaW5nbGUgbnVtYmVyLCBhcHBseSB0byBlYWNoIGNoYW5uZWxcbiAgICAgKiAtIElmIGl0J3MgYW4gYXJyYXkgb2YgMyBvciA0IG51bWJlcnMsIGFwcGx5IGVsZW1lbnQtd2lzZS4gTnVtYmVyIG9mIGVsZW1lbnRzIG5lZWQgdG8gbWF0Y2ggdGhlIG51bWJlciBvZiBjaGFubmVsc1xuICAgICAqIGZvciB0aGUgY29ycmVzcG9uZGluZyBpbWFnZSBmb3JtYXRcbiAgICAgKi9cbiAgICBiaWFzPzogbnVtYmVyIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgLyoqXG4gICAgICogVGhlICdtZWFuJyB2YWx1ZSBmb3IgaW1hZ2Ugbm9ybWFsaXphdGlvbi5cbiAgICAgKiAtIElmIG9taXR0ZWQsIHVzZSBkZWZhdWx0IHZhbHVlIDI1NS5cbiAgICAgKiAtIElmIGl0J3MgYSBzaW5nbGUgbnVtYmVyLCBhcHBseSB0byBlYWNoIGNoYW5uZWxcbiAgICAgKiAtIElmIGl0J3MgYW4gYXJyYXkgb2YgMyBvciA0IG51bWJlcnMsIGFwcGx5IGVsZW1lbnQtd2lzZS4gTnVtYmVyIG9mIGVsZW1lbnRzIG5lZWQgdG8gbWF0Y2ggdGhlIG51bWJlciBvZiBjaGFubmVsc1xuICAgICAqIGZvciB0aGUgY29ycmVzcG9uZGluZyBpbWFnZSBmb3JtYXRcbiAgICAgKi9cbiAgICBtZWFuPzogbnVtYmVyIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gIH07XG59XG5cbi8vICNlbmRyZWdpb25cblxuLy8gI3JlZ2lvbiBPcHRpb25zIGNvbXBvc2l0aW9uXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnNcbiAgZXh0ZW5kcyBPcHRpb25SZXNpemVkRGltZW5zaW9ucyxcbiAgICBPcHRpb25zVGVuc29yRm9ybWF0LFxuICAgIE9wdGlvbnNUZW5zb3JMYXlvdXQsXG4gICAgT3B0aW9uc1RlbnNvckRhdGFUeXBlLFxuICAgIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zXG4gIGV4dGVuZHMgT3B0aW9uUmVzaXplZERpbWVuc2lvbnMsXG4gICAgT3B0aW9uc1RlbnNvckZvcm1hdCxcbiAgICBPcHRpb25zVGVuc29yTGF5b3V0LFxuICAgIE9wdGlvbnNUZW5zb3JEYXRhVHlwZSxcbiAgICBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMge31cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGcm9tVXJsT3B0aW9uc1xuICBleHRlbmRzIE9wdGlvbnNEaW1lbnNpb25zLFxuICAgIE9wdGlvblJlc2l6ZWREaW1lbnNpb25zLFxuICAgIE9wdGlvbnNUZW5zb3JGb3JtYXQsXG4gICAgT3B0aW9uc1RlbnNvckxheW91dCxcbiAgICBPcHRpb25zVGVuc29yRGF0YVR5cGUsXG4gICAgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9uc1xuICBleHRlbmRzIE9wdGlvblJlc2l6ZWREaW1lbnNpb25zLFxuICAgIE9wdGlvbnNUZW5zb3JGb3JtYXQsXG4gICAgT3B0aW9uc1RlbnNvckxheW91dCxcbiAgICBPcHRpb25zVGVuc29yRGF0YVR5cGUsXG4gICAgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbVRleHR1cmVPcHRpb25zPFQgZXh0ZW5kcyBUZW5zb3IuVGV4dHVyZURhdGFUeXBlcz5cbiAgZXh0ZW5kcyBSZXF1aXJlZDxPcHRpb25zRGltZW5zaW9ucz4sXG4gICAgT3B0aW9uc0Zvcm1hdCxcbiAgICBHcHVSZXNvdXJjZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiAvKiBUT0RPOiBhZGQgbW9yZSAqLyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZyb21HcHVCdWZmZXJPcHRpb25zPFQgZXh0ZW5kcyBUZW5zb3IuR3B1QnVmZmVyRGF0YVR5cGVzPlxuICBleHRlbmRzIFBpY2s8VGVuc29yLCAnZGltcyc+LFxuICAgIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAqL1xuICBkYXRhVHlwZT86IFQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbU1MVGVuc29yT3B0aW9uczxUIGV4dGVuZHMgVGVuc29yLk1MVGVuc29yRGF0YVR5cGVzPlxuICBleHRlbmRzIFBpY2s8VGVuc29yLCAnZGltcyc+LFxuICAgIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAqL1xuICBkYXRhVHlwZT86IFQ7XG59XG5cbi8vICNlbmRyZWdpb25cblxuLyoqXG4gKiB0eXBlIFRlbnNvckZhY3RvcnkgZGVmaW5lcyB0aGUgZmFjdG9yeSBmdW5jdGlvbnMgb2YgJ1RlbnNvcicgdG8gY3JlYXRlIHRlbnNvciBpbnN0YW5jZXMgZnJvbSBleGlzdGluZyBkYXRhIG9yXG4gKiByZXNvdXJjZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRmFjdG9yeSB7XG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhbiBJbWFnZURhdGEgb2JqZWN0XG4gICAqXG4gICAqIEBwYXJhbSBpbWFnZURhdGEgLSB0aGUgSW1hZ2VEYXRhIG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIEltYWdlRGF0YS5cbiAgICpcbiAgICogVGhlIGZvbGxvd2luZyBkZWZhdWx0IHNldHRpbmdzIHdpbGwgYmUgYXBwbGllZDpcbiAgICogLSBgdGVuc29yRm9ybWF0YDogYCdSR0InYFxuICAgKiAtIGB0ZW5zb3JMYXlvdXRgOiBgJ05DSFcnYFxuICAgKiAtIGBkYXRhVHlwZWA6IGAnZmxvYXQzMidgXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgdGVuc29yIG9iamVjdFxuICAgKi9cbiAgZnJvbUltYWdlKFxuICAgIGltYWdlRGF0YTogSW1hZ2VEYXRhLFxuICAgIG9wdGlvbnM/OiBUZW5zb3JGcm9tSW1hZ2VEYXRhT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxUeXBlZFRlbnNvcjwnZmxvYXQzMic+IHwgVHlwZWRUZW5zb3I8J3VpbnQ4Jz4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhIEhUTUxJbWFnZUVsZW1lbnQgb2JqZWN0XG4gICAqXG4gICAqIEBwYXJhbSBpbWFnZUVsZW1lbnQgLSB0aGUgSFRNTEltYWdlRWxlbWVudCBvYmplY3QgdG8gY3JlYXRlIHRlbnNvciBmcm9tXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBIVE1MSW1hZ2VFbGVtZW50LlxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGRlZmF1bHQgc2V0dGluZ3Mgd2lsbCBiZSBhcHBsaWVkOlxuICAgKiAtIGB0ZW5zb3JGb3JtYXRgOiBgJ1JHQidgXG4gICAqIC0gYHRlbnNvckxheW91dGA6IGAnTkNIVydgXG4gICAqIC0gYGRhdGFUeXBlYDogYCdmbG9hdDMyJ2BcbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tSW1hZ2UoXG4gICAgaW1hZ2VFbGVtZW50OiBIVE1MSW1hZ2VFbGVtZW50LFxuICAgIG9wdGlvbnM/OiBUZW5zb3JGcm9tSW1hZ2VFbGVtZW50T3B0aW9ucyxcbiAgKTogUHJvbWlzZTxUeXBlZFRlbnNvcjwnZmxvYXQzMic+IHwgVHlwZWRUZW5zb3I8J3VpbnQ4Jz4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBVUkxcbiAgICpcbiAgICogQHBhcmFtIHVybFNvdXJjZSAtIGEgc3RyaW5nIGFzIGEgVVJMIHRvIHRoZSBpbWFnZSBvciBhIGRhdGEgVVJMIGNvbnRhaW5pbmcgdGhlIGltYWdlIGRhdGEuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBVUkwuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYHRlbnNvckZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogLSBgZGF0YVR5cGVgOiBgJ2Zsb2F0MzInYFxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21JbWFnZSh1cmxTb3VyY2U6IHN0cmluZywgb3B0aW9ucz86IFRlbnNvckZyb21VcmxPcHRpb25zKTogUHJvbWlzZTxUeXBlZFRlbnNvcjwnZmxvYXQzMic+IHwgVHlwZWRUZW5zb3I8J3VpbnQ4Jz4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhbiBJbWFnZUJpdG1hcCBvYmplY3RcbiAgICpcbiAgICogQHBhcmFtIGJpdG1hcCAtIHRoZSBJbWFnZUJpdG1hcCBvYmplY3QgdG8gY3JlYXRlIHRlbnNvciBmcm9tXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBVUkwuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYHRlbnNvckZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogLSBgZGF0YVR5cGVgOiBgJ2Zsb2F0MzInYFxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21JbWFnZShcbiAgICBiaXRtYXA6IEltYWdlQml0bWFwLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21JbWFnZUJpdG1hcE9wdGlvbnMsXG4gICk6IFByb21pc2U8VHlwZWRUZW5zb3I8J2Zsb2F0MzInPiB8IFR5cGVkVGVuc29yPCd1aW50OCc+PjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBXZWJHTCB0ZXh0dXJlXG4gICAqXG4gICAqIEBwYXJhbSB0ZXh0dXJlIC0gdGhlIFdlYkdMVGV4dHVyZSBvYmplY3QgdG8gY3JlYXRlIHRlbnNvciBmcm9tXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBXZWJHTCB0ZXh0dXJlLlxuICAgKlxuICAgKiBUaGUgb3B0aW9ucyBpbmNsdWRlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICAgKiAtIGB3aWR0aGA6IHRoZSB3aWR0aCBvZiB0aGUgdGV4dHVyZS4gUmVxdWlyZWQuXG4gICAqIC0gYGhlaWdodGA6IHRoZSBoZWlnaHQgb2YgdGhlIHRleHR1cmUuIFJlcXVpcmVkLlxuICAgKiAtIGBmb3JtYXRgOiB0aGUgZm9ybWF0IG9mIHRoZSB0ZXh0dXJlLiBJZiBvbWl0dGVkLCBhc3N1bWUgJ1JHQkEnLlxuICAgKiAtIGBkb3dubG9hZGA6IGFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGRvd25sb2FkIHRoZSB0ZW5zb3IgZGF0YSBmcm9tIEdQVSB0byBDUFUuIElmIG9taXR0ZWQsIHRoZSBHUFUgZGF0YVxuICAgKiB3aWxsIG5vdCBiZSBhYmxlIHRvIGRvd25sb2FkLiBVc3VhbGx5LCB0aGlzIGlzIHByb3ZpZGVkIGJ5IGEgR1BVIGJhY2tlbmQgZm9yIHRoZSBpbmZlcmVuY2Ugb3V0cHV0cy4gVXNlcnMgZG9uJ3RcbiAgICogbmVlZCB0byBwcm92aWRlIHRoaXMgZnVuY3Rpb24uXG4gICAqIC0gYGRpc3Bvc2VgOiBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBkaXNwb3NlIHRoZSB0ZW5zb3IgZGF0YSBvbiBHUFUuIElmIG9taXR0ZWQsIHRoZSBHUFUgZGF0YSB3aWxsIG5vdCBiZSBkaXNwb3NlZC5cbiAgICogVXN1YWxseSwgdGhpcyBpcyBwcm92aWRlZCBieSBhIEdQVSBiYWNrZW5kIGZvciB0aGUgaW5mZXJlbmNlIG91dHB1dHMuIFVzZXJzIGRvbid0IG5lZWQgdG8gcHJvdmlkZSB0aGlzIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21UZXh0dXJlPFQgZXh0ZW5kcyBUZW5zb3IuVGV4dHVyZURhdGFUeXBlcyA9ICdmbG9hdDMyJz4oXG4gICAgdGV4dHVyZTogVGVuc29yLlRleHR1cmVUeXBlLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21UZXh0dXJlT3B0aW9uczxUPixcbiAgKTogVHlwZWRUZW5zb3I8J2Zsb2F0MzInPjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBXZWJHUFUgYnVmZmVyXG4gICAqXG4gICAqIEBwYXJhbSBidWZmZXIgLSB0aGUgR1BVQnVmZmVyIG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIFdlYkdQVSBidWZmZXIuXG4gICAqXG4gICAqIFRoZSBvcHRpb25zIGluY2x1ZGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gICAqIC0gYGRhdGFUeXBlYDogdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhc3N1bWUgJ2Zsb2F0MzInLlxuICAgKiAtIGBkaW1zYDogdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBSZXF1aXJlZC5cbiAgICogLSBgZG93bmxvYWRgOiBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBkb3dubG9hZCB0aGUgdGVuc29yIGRhdGEgZnJvbSBHUFUgdG8gQ1BVLiBJZiBvbWl0dGVkLCB0aGUgR1BVIGRhdGFcbiAgICogd2lsbCBub3QgYmUgYWJsZSB0byBkb3dubG9hZC4gVXN1YWxseSwgdGhpcyBpcyBwcm92aWRlZCBieSBhIEdQVSBiYWNrZW5kIGZvciB0aGUgaW5mZXJlbmNlIG91dHB1dHMuIFVzZXJzIGRvbid0XG4gICAqIG5lZWQgdG8gcHJvdmlkZSB0aGlzIGZ1bmN0aW9uLlxuICAgKiAtIGBkaXNwb3NlYDogYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZGlzcG9zZSB0aGUgdGVuc29yIGRhdGEgb24gR1BVLiBJZiBvbWl0dGVkLCB0aGUgR1BVIGRhdGEgd2lsbCBub3QgYmUgZGlzcG9zZWQuXG4gICAqIFVzdWFsbHksIHRoaXMgaXMgcHJvdmlkZWQgYnkgYSBHUFUgYmFja2VuZCBmb3IgdGhlIGluZmVyZW5jZSBvdXRwdXRzLiBVc2VycyBkb24ndCBuZWVkIHRvIHByb3ZpZGUgdGhpcyBmdW5jdGlvbi5cbiAgICpcbiAgICogQHJldHVybnMgYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tR3B1QnVmZmVyPFQgZXh0ZW5kcyBUZW5zb3IuR3B1QnVmZmVyRGF0YVR5cGVzPihcbiAgICBidWZmZXI6IFRlbnNvci5HcHVCdWZmZXJUeXBlLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21HcHVCdWZmZXJPcHRpb25zPFQ+LFxuICApOiBUeXBlZFRlbnNvcjxUPjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBXZWJOTiBNTFRlbnNvclxuICAgKlxuICAgKiBAcGFyYW0gdGVuc29yIC0gdGhlIE1MVGVuc29yIG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIGEgV2ViTk4gTUxUZW5zb3IuXG4gICAqXG4gICAqIFRoZSBvcHRpb25zIGluY2x1ZGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gICAqIC0gYGRhdGFUeXBlYDogdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhc3N1bWUgJ2Zsb2F0MzInLlxuICAgKiAtIGBkaW1zYDogdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBSZXF1aXJlZC5cbiAgICogLSBgZG93bmxvYWRgOiBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBkb3dubG9hZCB0aGUgdGVuc29yIGRhdGEgZnJvbSB0aGUgTUxUZW5zb3IgdG8gQ1BVLiBJZiBvbWl0dGVkLCB0aGUgTUxUZW5zb3JcbiAgICogZGF0YSB3aWxsIG5vdCBiZSBhYmxlIHRvIGRvd25sb2FkLiBVc3VhbGx5LCB0aGlzIGlzIHByb3ZpZGVkIGJ5IHRoZSBXZWJOTiBiYWNrZW5kIGZvciB0aGUgaW5mZXJlbmNlIG91dHB1dHMuXG4gICAqIFVzZXJzIGRvbid0IG5lZWQgdG8gcHJvdmlkZSB0aGlzIGZ1bmN0aW9uLlxuICAgKiAtIGBkaXNwb3NlYDogYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZGlzcG9zZSB0aGUgdGVuc29yIGRhdGEgb24gdGhlIFdlYk5OIE1MVGVuc29yLiBJZiBvbWl0dGVkLCB0aGUgTUxUZW5zb3Igd2lsbFxuICAgKiBub3QgYmUgZGlzcG9zZWQuIFVzdWFsbHksIHRoaXMgaXMgcHJvdmlkZWQgYnkgdGhlIFdlYk5OIGJhY2tlbmQgZm9yIHRoZSBpbmZlcmVuY2Ugb3V0cHV0cy4gVXNlcnMgZG9uJ3QgbmVlZCB0b1xuICAgKiBwcm92aWRlIHRoaXMgZnVuY3Rpb24uXG4gICAqXG4gICAqIEByZXR1cm5zIGEgdGVuc29yIG9iamVjdFxuICAgKi9cbiAgZnJvbU1MVGVuc29yPFQgZXh0ZW5kcyBUZW5zb3IuTUxUZW5zb3JEYXRhVHlwZXM+KFxuICAgIHRlbnNvcjogVGVuc29yLk1MVGVuc29yVHlwZSxcbiAgICBvcHRpb25zOiBUZW5zb3JGcm9tTUxUZW5zb3JPcHRpb25zPFQ+LFxuICApOiBUeXBlZFRlbnNvcjxUPjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBwcmUtYWxsb2NhdGVkIGJ1ZmZlci4gVGhlIGJ1ZmZlciB3aWxsIGJlIHVzZWQgYXMgYSBwaW5uZWQgYnVmZmVyLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIHRoZSB0ZW5zb3IgZWxlbWVudCB0eXBlLlxuICAgKiBAcGFyYW0gYnVmZmVyIC0gYSBUeXBlZEFycmF5IGNvcnJlc3BvbmRpbmcgdG8gdGhlIHR5cGUuXG4gICAqIEBwYXJhbSBkaW1zIC0gc3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21QaW5uZWRCdWZmZXI8VCBleHRlbmRzIEV4Y2x1ZGU8VGVuc29yLlR5cGUsICdzdHJpbmcnPj4oXG4gICAgdHlwZTogVCxcbiAgICBidWZmZXI6IFRlbnNvci5EYXRhVHlwZU1hcFtUXSxcbiAgICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IFR5cGVkVGVuc29yPFQ+O1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vKipcbiAqIEEgc3RyaW5nIHRoYXQgcmVwcmVzZW50cyBhIGZpbGUncyBVUkwgb3IgcGF0aC5cbiAqXG4gKiBQYXRoIGlzIHZhaWxhYmxlIG9ubHkgaW4gb25ueHJ1bnRpbWUtbm9kZSBvciBvbm54cnVudGltZS13ZWIgcnVubmluZyBpbiBOb2RlLmpzLlxuICovXG5leHBvcnQgdHlwZSBGaWxlVXJsT3JQYXRoID0gc3RyaW5nO1xuXG4vKipcbiAqIEEgQmxvYiBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgZmlsZS5cbiAqL1xuZXhwb3J0IHR5cGUgRmlsZUJsb2IgPSBCbG9iO1xuXG4vKipcbiAqIEEgVWludDhBcnJheSwgQXJyYXlCdWZmZXIgb3IgU2hhcmVkQXJyYXlCdWZmZXIgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhIGZpbGUgY29udGVudC5cbiAqXG4gKiBXaGVuIGl0IGlzIGFuIEFycmF5QnVmZmVyIG9yIFNoYXJlZEFycmF5QnVmZmVyLCB0aGUgd2hvbGUgYnVmZmVyIGlzIGFzc3VtZWQgdG8gYmUgdGhlIGZpbGUgY29udGVudC5cbiAqL1xuZXhwb3J0IHR5cGUgRmlsZURhdGEgPSBVaW50OEFycmF5IHwgQXJyYXlCdWZmZXJMaWtlO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBmaWxlIHRoYXQgY2FuIGJlIGxvYWRlZCBieSB0aGUgT05OWCBSdW50aW1lIEphdmFTY3JpcHQgQVBJLlxuICovXG5leHBvcnQgdHlwZSBGaWxlVHlwZSA9IEZpbGVVcmxPclBhdGggfCBGaWxlQmxvYiB8IEZpbGVEYXRhO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gZXh0ZXJuYWwgZGF0YSBmaWxlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4dGVybmFsRGF0YUZpbGVEZXNjcmlwdGlvbiB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBleHRlcm5hbCBkYXRhIGZpbGUuXG4gICAqL1xuICBkYXRhOiBGaWxlVHlwZTtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGZpbGUgcGF0aC5cbiAgICovXG4gIHBhdGg6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIGV4dGVybmFsIGRhdGEgZmlsZS5cbiAqXG4gKiBXaGVuIHVzaW5nIGEgc3RyaW5nLCBpdCBzaG91bGQgYmUgYSBmaWxlIFVSTCBvciBwYXRoIHRoYXQgaW4gdGhlIHNhbWUgZGlyZWN0b3J5IGFzIHRoZSBtb2RlbCBmaWxlLlxuICovXG5leHBvcnQgdHlwZSBFeHRlcm5hbERhdGFGaWxlVHlwZSA9IEV4dGVybmFsRGF0YUZpbGVEZXNjcmlwdGlvbiB8IEZpbGVVcmxPclBhdGg7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgbW9kZWwgbG9hZGluZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPbm54TW9kZWxPcHRpb25zIHtcbiAgLyoqXG4gICAqIFNwZWNpZnlpbmcgYSBsaXN0IG9mIGZpbGVzIHRoYXQgcmVwcmVzZW50cyB0aGUgZXh0ZXJuYWwgZGF0YS5cbiAgICovXG4gIGV4dGVybmFsRGF0YT86IHJlYWRvbmx5IEV4dGVybmFsRGF0YUZpbGVUeXBlW107XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yLmpzJztcblxuZXhwb3J0IHR5cGUgTm9uVGVuc29yVHlwZSA9IG5ldmVyO1xuXG4vKipcbiAqIFR5cGUgT25ueFZhbHVlIFJlcHJlc2VudHMgYm90aCB0ZW5zb3JzIGFuZCBub24tdGVuc29ycyB2YWx1ZSBmb3IgbW9kZWwncyBpbnB1dHMvb3V0cHV0cy5cbiAqXG4gKiBOT1RFOiBjdXJyZW50bHkgbm90IHN1cHBvcnQgbm9uLXRlbnNvclxuICovXG5leHBvcnQgdHlwZSBPbm54VmFsdWUgPSBUZW5zb3IgfCBOb25UZW5zb3JUeXBlO1xuXG4vKipcbiAqIFR5cGUgT25ueFZhbHVlRGF0YUxvY2F0aW9uIHJlcHJlc2VudHMgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIG9mIGFuIE9ubnhWYWx1ZS5cbiAqL1xuZXhwb3J0IHR5cGUgT25ueFZhbHVlRGF0YUxvY2F0aW9uID0gVGVuc29yLkRhdGFMb2NhdGlvbjtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLyoqXG4gKiAjIE9OTlggUnVudGltZSBKYXZhU2NyaXB0IEFQSVxuICpcbiAqIE9OTlggUnVudGltZSBKYXZhU2NyaXB0IEFQSSBpcyBhIHVuaWZpZWQgQVBJIGZvciBhbGwgSmF2YVNjcmlwdCB1c2FnZXMsIGluY2x1ZGluZyB0aGUgZm9sbG93aW5nIE5QTSBwYWNrYWdlczpcbiAqXG4gKiAtIFtvbm54cnVudGltZS1ub2RlXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9vbm54cnVudGltZS1ub2RlKVxuICogLSBbb25ueHJ1bnRpbWUtd2ViXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9vbm54cnVudGltZS13ZWIpXG4gKiAtIFtvbm54cnVudGltZS1yZWFjdC1uYXRpdmVdKGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL29ubnhydW50aW1lLXJlYWN0LW5hdGl2ZSlcbiAqXG4gKiBTZWUgYWxzbzpcbiAqIC0gW0dldCBTdGFydGVkXShodHRwczovL29ubnhydW50aW1lLmFpL2RvY3MvZ2V0LXN0YXJ0ZWQvd2l0aC1qYXZhc2NyaXB0LylcbiAqIC0gW0luZmVyZW5jZSBleGFtcGxlc10oaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9vbm54cnVudGltZS1pbmZlcmVuY2UtZXhhbXBsZXMvdHJlZS9tYWluL2pzKVxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vYmFja2VuZC5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2Vudi5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2luZmVyZW5jZS1zZXNzaW9uLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdGVuc29yLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdGVuc29yLWNvbnZlcnNpb24uanMnO1xuZXhwb3J0ICogZnJvbSAnLi90ZW5zb3ItZmFjdG9yeS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3RyYWNlLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vb25ueC1tb2RlbC5qcyc7XG5leHBvcnQgKiBmcm9tICcuL29ubngtdmFsdWUuanMnO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBFbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL2JhY2tlbmRzL3dlYmdsL3dlYmdsLWNvbnRleHQnO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgTG9nZ2VyIHtcbiAgZXhwb3J0IGludGVyZmFjZSBTZXZlcml0eVR5cGVNYXAge1xuICAgIHZlcmJvc2U6ICd2JztcbiAgICBpbmZvOiAnaSc7XG4gICAgd2FybmluZzogJ3cnO1xuICAgIGVycm9yOiAnZSc7XG4gICAgZmF0YWw6ICdmJztcbiAgfVxuXG4gIGV4cG9ydCB0eXBlIFNldmVyaXR5ID0ga2V5b2YgU2V2ZXJpdHlUeXBlTWFwO1xuXG4gIGV4cG9ydCB0eXBlIFByb3ZpZGVyID0gJ25vbmUnIHwgJ2NvbnNvbGUnO1xuXG4gIC8qKlxuICAgKiBMb2dnaW5nIGNvbmZpZyB0aGF0IHVzZWQgdG8gY29udHJvbCB0aGUgYmVoYXZpb3Igb2YgbG9nZ2VyXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIENvbmZpZyB7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgbG9nZ2luZyBwcm92aWRlci4gJ2NvbnNvbGUnIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBwcm92aWRlcj86IFByb3ZpZGVyO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgdGhlIG1pbmltYWwgbG9nZ2VyIHNlcnZlcml0eS4gJ3dhcm5pbmcnIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBtaW5pbWFsU2V2ZXJpdHk/OiBMb2dnZXIuU2V2ZXJpdHk7XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0byBvdXRwdXQgZGF0ZSB0aW1lIGluIGxvZy4gdHJ1ZSBieSBkZWZhdWx0XG4gICAgICovXG4gICAgbG9nRGF0ZVRpbWU/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdG8gb3V0cHV0IHNvdXJjZSBpbmZvcm1hdGlvbiAoTm90IHlldCBzdXBwb3J0ZWQpLiBmYWxzZSBieSBkZWZhdWx0XG4gICAgICovXG4gICAgbG9nU291cmNlTG9jYXRpb24/OiBib29sZWFuO1xuICB9XG5cbiAgZXhwb3J0IGludGVyZmFjZSBDYXRlZ29yaXplZExvZ2dlciB7XG4gICAgdmVyYm9zZShjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICAgIGluZm8oY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgICB3YXJuaW5nKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gICAgZXJyb3IoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgICBmYXRhbChjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB9XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlXG5leHBvcnQgaW50ZXJmYWNlIExvZ2dlciB7XG4gIChjYXRlZ29yeTogc3RyaW5nKTogTG9nZ2VyLkNhdGVnb3JpemVkTG9nZ2VyO1xuXG4gIHZlcmJvc2UoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgdmVyYm9zZShjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBpbmZvKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGluZm8oY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgd2FybmluZyhjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB3YXJuaW5nKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGVycm9yKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGVycm9yKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGZhdGFsKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGZhdGFsKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFJlc2V0IHRoZSBsb2dnZXIgY29uZmlndXJhdGlvbi5cbiAgICogQHBhcmFtIGNvbmZpZyBzcGVjaWZ5IGFuIG9wdGlvbmFsIGRlZmF1bHQgY29uZmlnXG4gICAqL1xuICByZXNldChjb25maWc/OiBMb2dnZXIuQ29uZmlnKTogdm9pZDtcbiAgLyoqXG4gICAqIFNldCB0aGUgbG9nZ2VyJ3MgYmVoYXZpb3Igb24gdGhlIGdpdmVuIGNhdGVnb3J5XG4gICAqIEBwYXJhbSBjYXRlZ29yeSBzcGVjaWZ5IGEgY2F0ZWdvcnkgc3RyaW5nLiBJZiAnKicgaXMgc3BlY2lmaWVkLCBhbGwgcHJldmlvdXMgY29uZmlndXJhdGlvbiB3aWxsIGJlIG92ZXJ3cml0dGVuLiBJZlxuICAgKiAnJyBpcyBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IGJlaGF2aW9yIHdpbGwgYmUgdXBkYXRlZC5cbiAgICogQHBhcmFtIGNvbmZpZyB0aGUgY29uZmlnIG9iamVjdCB0byBpbmRpY2F0ZSB0aGUgbG9nZ2VyJ3MgYmVoYXZpb3JcbiAgICovXG4gIHNldChjYXRlZ29yeTogc3RyaW5nLCBjb25maWc6IExvZ2dlci5Db25maWcpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGxvZ2dlcidzIGJlaGF2aW9yIGZyb20gb3J0LWNvbW1vbiBlbnZcbiAgICogQHBhcmFtIGVudiB0aGUgZW52IHVzZWQgdG8gc2V0IGxvZ2dlci4gQ3VycmVudGx5IG9ubHkgc2V0dGluZyBsb2dsZXZlbCBpcyBzdXBwb3J0ZWQgdGhyb3VnaCBFbnYuXG4gICAqL1xuICBzZXRXaXRoRW52KGVudjogRW52KTogdm9pZDtcbn1cblxuaW50ZXJmYWNlIExvZ2dlclByb3ZpZGVyIHtcbiAgbG9nKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIGNvbnRlbnQ6IHN0cmluZywgY2F0ZWdvcnk/OiBzdHJpbmcpOiB2b2lkO1xufVxuY2xhc3MgTm9PcExvZ2dlclByb3ZpZGVyIGltcGxlbWVudHMgTG9nZ2VyUHJvdmlkZXIge1xuICBsb2coX3NldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIF9jb250ZW50OiBzdHJpbmcsIF9jYXRlZ29yeT86IHN0cmluZykge1xuICAgIC8vIGRvIG5vdGhpbmdcbiAgfVxufVxuY2xhc3MgQ29uc29sZUxvZ2dlclByb3ZpZGVyIGltcGxlbWVudHMgTG9nZ2VyUHJvdmlkZXIge1xuICBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgY29udGVudDogc3RyaW5nLCBjYXRlZ29yeT86IHN0cmluZykge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgY29uc29sZS5sb2coYCR7dGhpcy5jb2xvcihzZXZlcml0eSl9ICR7Y2F0ZWdvcnkgPyAnXFx4MWJbMzVtJyArIGNhdGVnb3J5ICsgJ1xceDFiWzBtICcgOiAnJ30ke2NvbnRlbnR9YCk7XG4gIH1cblxuICBwcml2YXRlIGNvbG9yKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHkpIHtcbiAgICBzd2l0Y2ggKHNldmVyaXR5KSB7XG4gICAgICBjYXNlICd2ZXJib3NlJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlszNDs0MG12XFx4MWJbMG0nO1xuICAgICAgY2FzZSAnaW5mbyc6XG4gICAgICAgIHJldHVybiAnXFx4MWJbMzJtaVxceDFiWzBtJztcbiAgICAgIGNhc2UgJ3dhcm5pbmcnOlxuICAgICAgICByZXR1cm4gJ1xceDFiWzMwOzQzbXdcXHgxYlswbSc7XG4gICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgIHJldHVybiAnXFx4MWJbMzE7NDBtZVxceDFiWzBtJztcbiAgICAgIGNhc2UgJ2ZhdGFsJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlsxMDFtZlxceDFiWzBtJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgc2V2ZXJpdHk6ICR7c2V2ZXJpdHl9YCk7XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IFNFVkVSSVRZX1ZBTFVFID0ge1xuICB2ZXJib3NlOiAxMDAwLFxuICBpbmZvOiAyMDAwLFxuICB3YXJuaW5nOiA0MDAwLFxuICBlcnJvcjogNTAwMCxcbiAgZmF0YWw6IDYwMDAsXG59O1xuXG5jb25zdCBMT0dHRVJfUFJPVklERVJfTUFQOiB7IHJlYWRvbmx5IFtwcm92aWRlcjogc3RyaW5nXTogUmVhZG9ubHk8TG9nZ2VyUHJvdmlkZXI+IH0gPSB7XG4gIFsnbm9uZSddOiBuZXcgTm9PcExvZ2dlclByb3ZpZGVyKCksXG4gIFsnY29uc29sZSddOiBuZXcgQ29uc29sZUxvZ2dlclByb3ZpZGVyKCksXG59O1xuY29uc3QgTE9HR0VSX0RFRkFVTFRfQ09ORklHID0ge1xuICBwcm92aWRlcjogJ2NvbnNvbGUnLFxuICBtaW5pbWFsU2V2ZXJpdHk6ICd3YXJuaW5nJyxcbiAgbG9nRGF0ZVRpbWU6IHRydWUsXG4gIGxvZ1NvdXJjZUxvY2F0aW9uOiBmYWxzZSxcbn07XG5sZXQgTE9HR0VSX0NPTkZJR19NQVA6IHsgW2NhdGVnb3J5OiBzdHJpbmddOiBSZWFkb25seTxSZXF1aXJlZDxMb2dnZXIuQ29uZmlnPj4gfSA9IHtcbiAgWycnXTogTE9HR0VSX0RFRkFVTFRfQ09ORklHIGFzIFJlcXVpcmVkPExvZ2dlci5Db25maWc+LFxufTtcblxuZnVuY3Rpb24gbG9nKGNhdGVnb3J5OiBzdHJpbmcpOiBMb2dnZXIuQ2F0ZWdvcml6ZWRMb2dnZXI7XG5mdW5jdGlvbiBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgY29udGVudDogc3RyaW5nKTogdm9pZDtcbmZ1bmN0aW9uIGxvZyhzZXZlcml0eTogTG9nZ2VyLlNldmVyaXR5LCBjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuZnVuY3Rpb24gbG9nKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIGFyZzE6IHN0cmluZywgYXJnMj86IHN0cmluZyk6IHZvaWQ7XG5mdW5jdGlvbiBsb2coXG4gIGFyZzA6IHN0cmluZyB8IExvZ2dlci5TZXZlcml0eSxcbiAgYXJnMT86IHN0cmluZyxcbiAgYXJnMj86IHN0cmluZyB8IG51bWJlcixcbiAgYXJnMz86IG51bWJlcixcbik6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlciB8IHZvaWQge1xuICBpZiAoYXJnMSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gbG9nKGNhdGVnb3J5OiBzdHJpbmcpOiBMb2dnZXIuQ2F0ZWdvcml6ZWRMb2dnZXI7XG4gICAgcmV0dXJuIGNyZWF0ZUNhdGVnb3JpemVkTG9nZ2VyKGFyZzApO1xuICB9IGVsc2UgaWYgKGFyZzIgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGxvZyhzZXZlcml0eSwgY29udGVudCk7XG4gICAgbG9nSW50ZXJuYWwoYXJnMCBhcyBMb2dnZXIuU2V2ZXJpdHksIGFyZzEsIDEpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcyID09PSAnbnVtYmVyJyAmJiBhcmczID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBsb2coc2V2ZXJpdHksIGNvbnRlbnQsIHN0YWNrKVxuICAgIGxvZ0ludGVybmFsKGFyZzAgYXMgTG9nZ2VyLlNldmVyaXR5LCBhcmcxLCBhcmcyKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiA9PT0gJ3N0cmluZycgJiYgYXJnMyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gbG9nKHNldmVyaXR5LCBjYXRlZ29yeSwgY29udGVudClcbiAgICBsb2dJbnRlcm5hbChhcmcwIGFzIExvZ2dlci5TZXZlcml0eSwgYXJnMiwgMSwgYXJnMSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgPT09ICdzdHJpbmcnICYmIHR5cGVvZiBhcmczID09PSAnbnVtYmVyJykge1xuICAgIC8vIGxvZyhzZXZlcml0eSwgY2F0ZWdvcnksIGNvbnRlbnQsIHN0YWNrKVxuICAgIGxvZ0ludGVybmFsKGFyZzAgYXMgTG9nZ2VyLlNldmVyaXR5LCBhcmcyLCBhcmczLCBhcmcxKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnB1dCBpcyB2YWxpZCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNhdGVnb3JpemVkTG9nZ2VyKGNhdGVnb3J5OiBzdHJpbmcpOiBMb2dnZXIuQ2F0ZWdvcml6ZWRMb2dnZXIge1xuICByZXR1cm4ge1xuICAgIHZlcmJvc2U6IGxvZy52ZXJib3NlLmJpbmQobnVsbCwgY2F0ZWdvcnkpLFxuICAgIGluZm86IGxvZy5pbmZvLmJpbmQobnVsbCwgY2F0ZWdvcnkpLFxuICAgIHdhcm5pbmc6IGxvZy53YXJuaW5nLmJpbmQobnVsbCwgY2F0ZWdvcnkpLFxuICAgIGVycm9yOiBsb2cuZXJyb3IuYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgZmF0YWw6IGxvZy5mYXRhbC5iaW5kKG51bGwsIGNhdGVnb3J5KSxcbiAgfTtcbn1cblxuLy8gTk9URTogYXJndW1lbnQgJ2NhdGVnb3J5JyBpcyBwdXQgdGhlIGxhc3QgcGFyYW1ldGVyIGJlYWNhdXNlIHR5cGVzY3JpcHRcbi8vIGRvZXNuJ3QgYWxsb3cgb3B0aW9uYWwgYXJndW1lbnQgcHV0IGluIGZyb250IG9mIHJlcXVpcmVkIGFyZ3VtZW50LiBUaGlzXG4vLyBvcmRlciBpcyBkaWZmZXJlbnQgZnJvbSBhIHVzdWFsIGxvZ2dpbmcgQVBJLlxuZnVuY3Rpb24gbG9nSW50ZXJuYWwoc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgY29udGVudDogc3RyaW5nLCBfc3RhY2s6IG51bWJlciwgY2F0ZWdvcnk/OiBzdHJpbmcpIHtcbiAgY29uc3QgY29uZmlnID0gTE9HR0VSX0NPTkZJR19NQVBbY2F0ZWdvcnkgfHwgJyddIHx8IExPR0dFUl9DT05GSUdfTUFQWycnXTtcbiAgaWYgKFNFVkVSSVRZX1ZBTFVFW3NldmVyaXR5XSA8IFNFVkVSSVRZX1ZBTFVFW2NvbmZpZy5taW5pbWFsU2V2ZXJpdHldKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGNvbmZpZy5sb2dEYXRlVGltZSkge1xuICAgIGNvbnRlbnQgPSBgJHtuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCl9fCR7Y29udGVudH1gO1xuICB9XG5cbiAgaWYgKGNvbmZpZy5sb2dTb3VyY2VMb2NhdGlvbikge1xuICAgIC8vIFRPRE86IGNhbGN1bGF0ZSBzb3VyY2UgbG9jYXRpb24gZnJvbSAnc3RhY2snXG4gIH1cblxuICBMT0dHRVJfUFJPVklERVJfTUFQW2NvbmZpZy5wcm92aWRlcl0ubG9nKHNldmVyaXR5LCBjb250ZW50LCBjYXRlZ29yeSk7XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbmFtZXNwYWNlXG5uYW1lc3BhY2UgbG9nIHtcbiAgZXhwb3J0IGZ1bmN0aW9uIHZlcmJvc2UoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIHZlcmJvc2UoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIHZlcmJvc2UoYXJnMDogc3RyaW5nLCBhcmcxPzogc3RyaW5nKSB7XG4gICAgbG9nKCd2ZXJib3NlJywgYXJnMCwgYXJnMSk7XG4gIH1cbiAgZXhwb3J0IGZ1bmN0aW9uIGluZm8oY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIGluZm8oY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIGluZm8oYXJnMDogc3RyaW5nLCBhcmcxPzogc3RyaW5nKSB7XG4gICAgbG9nKCdpbmZvJywgYXJnMCwgYXJnMSk7XG4gIH1cbiAgZXhwb3J0IGZ1bmN0aW9uIHdhcm5pbmcoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIHdhcm5pbmcoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIHdhcm5pbmcoYXJnMDogc3RyaW5nLCBhcmcxPzogc3RyaW5nKSB7XG4gICAgbG9nKCd3YXJuaW5nJywgYXJnMCwgYXJnMSk7XG4gIH1cbiAgZXhwb3J0IGZ1bmN0aW9uIGVycm9yKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBlcnJvcihjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gZXJyb3IoYXJnMDogc3RyaW5nLCBhcmcxPzogc3RyaW5nKSB7XG4gICAgbG9nKCdlcnJvcicsIGFyZzAsIGFyZzEpO1xuICB9XG4gIGV4cG9ydCBmdW5jdGlvbiBmYXRhbChjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gZmF0YWwoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIGZhdGFsKGFyZzA6IHN0cmluZywgYXJnMT86IHN0cmluZykge1xuICAgIGxvZygnZmF0YWwnLCBhcmcwLCBhcmcxKTtcbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiByZXNldChjb25maWc/OiBMb2dnZXIuQ29uZmlnKTogdm9pZCB7XG4gICAgTE9HR0VSX0NPTkZJR19NQVAgPSB7fTtcbiAgICBzZXQoJycsIGNvbmZpZyB8fCB7fSk7XG4gIH1cbiAgZXhwb3J0IGZ1bmN0aW9uIHNldChjYXRlZ29yeTogc3RyaW5nLCBjb25maWc6IExvZ2dlci5Db25maWcpOiB2b2lkIHtcbiAgICBpZiAoY2F0ZWdvcnkgPT09ICcqJykge1xuICAgICAgcmVzZXQoY29uZmlnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgcHJldmlvdXNDb25maWcgPSBMT0dHRVJfQ09ORklHX01BUFtjYXRlZ29yeV0gfHwgTE9HR0VSX0RFRkFVTFRfQ09ORklHO1xuICAgICAgTE9HR0VSX0NPTkZJR19NQVBbY2F0ZWdvcnldID0ge1xuICAgICAgICBwcm92aWRlcjogY29uZmlnLnByb3ZpZGVyIHx8IHByZXZpb3VzQ29uZmlnLnByb3ZpZGVyLFxuICAgICAgICBtaW5pbWFsU2V2ZXJpdHk6IGNvbmZpZy5taW5pbWFsU2V2ZXJpdHkgfHwgcHJldmlvdXNDb25maWcubWluaW1hbFNldmVyaXR5LFxuICAgICAgICBsb2dEYXRlVGltZTogY29uZmlnLmxvZ0RhdGVUaW1lID09PSB1bmRlZmluZWQgPyBwcmV2aW91c0NvbmZpZy5sb2dEYXRlVGltZSA6IGNvbmZpZy5sb2dEYXRlVGltZSxcbiAgICAgICAgbG9nU291cmNlTG9jYXRpb246XG4gICAgICAgICAgY29uZmlnLmxvZ1NvdXJjZUxvY2F0aW9uID09PSB1bmRlZmluZWQgPyBwcmV2aW91c0NvbmZpZy5sb2dTb3VyY2VMb2NhdGlvbiA6IGNvbmZpZy5sb2dTb3VyY2VMb2NhdGlvbixcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gVE9ETzogd2Ugd2FudCB0byBzdXBwb3J0IHdpbGRjYXJkIG9yIHJlZ2V4P1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIHNldFdpdGhFbnYoZW52OiBFbnYpOiB2b2lkIHtcbiAgICBjb25zdCBjb25maWc6IExvZ2dlci5Db25maWcgPSB7fTtcbiAgICBpZiAoZW52LmxvZ0xldmVsKSB7XG4gICAgICBjb25maWcubWluaW1hbFNldmVyaXR5ID0gZW52LmxvZ0xldmVsIGFzIExvZ2dlci5TZXZlcml0eTtcbiAgICB9XG4gICAgc2V0KCcnLCBjb25maWcpO1xuICB9XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlLCBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbmV4cG9ydCBjb25zdCBMb2dnZXI6IExvZ2dlciA9IGxvZztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIFByb2ZpbGVyIHtcbiAgZXhwb3J0IGludGVyZmFjZSBDb25maWcge1xuICAgIG1heE51bWJlckV2ZW50cz86IG51bWJlcjtcbiAgICBmbHVzaEJhdGNoU2l6ZT86IG51bWJlcjtcbiAgICBmbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG4gIH1cblxuICBleHBvcnQgdHlwZSBFdmVudENhdGVnb3J5ID0gJ3Nlc3Npb24nIHwgJ25vZGUnIHwgJ29wJyB8ICdiYWNrZW5kJztcblxuICBleHBvcnQgaW50ZXJmYWNlIEV2ZW50IHtcbiAgICBlbmQoKTogdm9pZCB8IFByb21pc2U8dm9pZD47XG4gIH1cbn1cbi8vIFRPRE9cbi8vIGNsYXNzIFdlYkdMRXZlbnQgaW1wbGVtZW50cyBQcm9maWxlci5FdmVudCB7fVxuXG5jbGFzcyBFdmVudCBpbXBsZW1lbnRzIFByb2ZpbGVyLkV2ZW50IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGNhdGVnb3J5OiBQcm9maWxlci5FdmVudENhdGVnb3J5LFxuICAgIHB1YmxpYyBuYW1lOiBzdHJpbmcsXG4gICAgcHVibGljIHN0YXJ0VGltZTogbnVtYmVyLFxuICAgIHByaXZhdGUgZW5kQ2FsbGJhY2s6IChlOiBFdmVudCkgPT4gdm9pZCB8IFByb21pc2U8dm9pZD4sXG4gICAgcHVibGljIHRpbWVyPzogV2ViR0xRdWVyeSxcbiAgICBwdWJsaWMgY3R4PzogV2ViR0xDb250ZXh0LFxuICApIHt9XG5cbiAgYXN5bmMgZW5kKCkge1xuICAgIHJldHVybiB0aGlzLmVuZENhbGxiYWNrKHRoaXMpO1xuICB9XG5cbiAgYXN5bmMgY2hlY2tUaW1lcigpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGlmICh0aGlzLmN0eCA9PT0gdW5kZWZpbmVkIHx8IHRoaXMudGltZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyB3ZWJnbCB0aW1lciBmb3VuZCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmN0eC5lbmRUaW1lcigpO1xuICAgICAgcmV0dXJuIHRoaXMuY3R4LndhaXRGb3JRdWVyeUFuZEdldFRpbWUodGhpcy50aW1lcik7XG4gICAgfVxuICB9XG59XG5cbmNsYXNzIEV2ZW50UmVjb3JkIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGNhdGVnb3J5OiBQcm9maWxlci5FdmVudENhdGVnb3J5LFxuICAgIHB1YmxpYyBuYW1lOiBzdHJpbmcsXG4gICAgcHVibGljIHN0YXJ0VGltZTogbnVtYmVyLFxuICAgIHB1YmxpYyBlbmRUaW1lOiBudW1iZXIsXG4gICkge31cbn1cblxuZXhwb3J0IGNsYXNzIFByb2ZpbGVyIHtcbiAgc3RhdGljIGNyZWF0ZShjb25maWc/OiBQcm9maWxlci5Db25maWcpOiBQcm9maWxlciB7XG4gICAgaWYgKGNvbmZpZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gbmV3IHRoaXMoKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyB0aGlzKGNvbmZpZy5tYXhOdW1iZXJFdmVudHMsIGNvbmZpZy5mbHVzaEJhdGNoU2l6ZSwgY29uZmlnLmZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcyk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKG1heE51bWJlckV2ZW50cz86IG51bWJlciwgZmx1c2hCYXRjaFNpemU/OiBudW1iZXIsIGZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcz86IG51bWJlcikge1xuICAgIHRoaXMuX3N0YXJ0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9tYXhOdW1iZXJFdmVudHMgPSBtYXhOdW1iZXJFdmVudHMgPT09IHVuZGVmaW5lZCA/IDEwMDAwIDogbWF4TnVtYmVyRXZlbnRzO1xuICAgIHRoaXMuX2ZsdXNoQmF0Y2hTaXplID0gZmx1c2hCYXRjaFNpemUgPT09IHVuZGVmaW5lZCA/IDEwIDogZmx1c2hCYXRjaFNpemU7XG4gICAgdGhpcy5fZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzID0gZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzID09PSB1bmRlZmluZWQgPyA1MDAwIDogZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzO1xuICB9XG5cbiAgLy8gc3RhcnQgcHJvZmlsaW5nXG4gIHN0YXJ0KCkge1xuICAgIHRoaXMuX3N0YXJ0ZWQgPSB0cnVlO1xuICAgIHRoaXMuX3RpbWluZ0V2ZW50cyA9IFtdO1xuICAgIHRoaXMuX2ZsdXNoVGltZSA9IG5vdygpO1xuICAgIHRoaXMuX2ZsdXNoUG9pbnRlciA9IDA7XG4gIH1cblxuICAvLyBzdG9wIHByb2ZpbGluZ1xuICBzdG9wKCkge1xuICAgIHRoaXMuX3N0YXJ0ZWQgPSBmYWxzZTtcbiAgICBmb3IgKDsgdGhpcy5fZmx1c2hQb2ludGVyIDwgdGhpcy5fdGltaW5nRXZlbnRzLmxlbmd0aDsgdGhpcy5fZmx1c2hQb2ludGVyKyspIHtcbiAgICAgIHRoaXMubG9nT25lRXZlbnQodGhpcy5fdGltaW5nRXZlbnRzW3RoaXMuX2ZsdXNoUG9pbnRlcl0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIGNyZWF0ZSBhbiBldmVudCBzY29wZSBmb3IgdGhlIHNwZWNpZmljIGZ1bmN0aW9uXG4gIGV2ZW50PFQ+KGNhdGVnb3J5OiBQcm9maWxlci5FdmVudENhdGVnb3J5LCBuYW1lOiBzdHJpbmcsIGZ1bmM6ICgpID0+IFQsIGN0eD86IFdlYkdMQ29udGV4dCk6IFQ7XG4gIGV2ZW50PFQ+KGNhdGVnb3J5OiBQcm9maWxlci5FdmVudENhdGVnb3J5LCBuYW1lOiBzdHJpbmcsIGZ1bmM6ICgpID0+IFByb21pc2U8VD4sIGN0eD86IFdlYkdMQ29udGV4dCk6IFByb21pc2U8VD47XG5cbiAgZXZlbnQ8VD4oXG4gICAgY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGZ1bmM6ICgpID0+IFQgfCBQcm9taXNlPFQ+LFxuICAgIGN0eD86IFdlYkdMQ29udGV4dCxcbiAgKTogVCB8IFByb21pc2U8VD4ge1xuICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fc3RhcnRlZCA/IHRoaXMuYmVnaW4oY2F0ZWdvcnksIG5hbWUsIGN0eCkgOiB1bmRlZmluZWQ7XG4gICAgbGV0IGlzUHJvbWlzZSA9IGZhbHNlO1xuXG4gICAgY29uc3QgcmVzID0gZnVuYygpO1xuXG4gICAgLy8gd2UgY29uc2lkZXIgYSB0aGVuLWFibGUgb2JqZWN0IGlzIGEgcHJvbWlzZVxuICAgIGlmIChyZXMgJiYgdHlwZW9mIChyZXMgYXMgUHJvbWlzZTxUPikudGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaXNQcm9taXNlID0gdHJ1ZTtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxUPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIChyZXMgYXMgUHJvbWlzZTxUPikudGhlbihcbiAgICAgICAgICBhc3luYyAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIC8vIGZ1bGZpbGxlZFxuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgIGF3YWl0IGV2ZW50LmVuZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzb2x2ZSh2YWx1ZSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBhc3luYyAocmVhc29uKSA9PiB7XG4gICAgICAgICAgICAvLyByZWplY3RlZFxuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgIGF3YWl0IGV2ZW50LmVuZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVqZWN0KHJlYXNvbik7XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoIWlzUHJvbWlzZSAmJiBldmVudCkge1xuICAgICAgY29uc3QgZXZlbnRSZXMgPSBldmVudC5lbmQoKTtcbiAgICAgIGlmIChldmVudFJlcyAmJiB0eXBlb2YgZXZlbnRSZXMudGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8VD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgIGV2ZW50UmVzLnRoZW4oXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgIC8vIGZ1bGZpbGxlZFxuICAgICAgICAgICAgICByZXNvbHZlKHJlcyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgKHJlYXNvbikgPT4ge1xuICAgICAgICAgICAgICAvLyByZWplY3RlZFxuICAgICAgICAgICAgICByZWplY3QocmVhc29uKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICAvLyBiZWdpbiBhbiBldmVudFxuICBiZWdpbihjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSwgbmFtZTogc3RyaW5nLCBjdHg/OiBXZWJHTENvbnRleHQpOiBFdmVudCB7XG4gICAgaWYgKCF0aGlzLl9zdGFydGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2ZpbGVyIGlzIG5vdCBzdGFydGVkIHlldCcpO1xuICAgIH1cbiAgICBpZiAoY3R4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IG5vdygpO1xuICAgICAgdGhpcy5mbHVzaChzdGFydFRpbWUpO1xuICAgICAgcmV0dXJuIG5ldyBFdmVudChjYXRlZ29yeSwgbmFtZSwgc3RhcnRUaW1lLCAoZSkgPT4gdGhpcy5lbmRTeW5jKGUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdGltZXI6IFdlYkdMUXVlcnkgPSBjdHguYmVnaW5UaW1lcigpO1xuICAgICAgcmV0dXJuIG5ldyBFdmVudChjYXRlZ29yeSwgbmFtZSwgMCwgYXN5bmMgKGUpID0+IHRoaXMuZW5kKGUpLCB0aW1lciwgY3R4KTtcbiAgICB9XG4gIH1cblxuICAvLyBlbmQgdGhlIHNwZWNpZmljIGV2ZW50XG4gIHByaXZhdGUgYXN5bmMgZW5kKGV2ZW50OiBFdmVudCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGVuZFRpbWU6IG51bWJlciA9IGF3YWl0IGV2ZW50LmNoZWNrVGltZXIoKTtcbiAgICBpZiAodGhpcy5fdGltaW5nRXZlbnRzLmxlbmd0aCA8IHRoaXMuX21heE51bWJlckV2ZW50cykge1xuICAgICAgdGhpcy5fdGltaW5nRXZlbnRzLnB1c2gobmV3IEV2ZW50UmVjb3JkKGV2ZW50LmNhdGVnb3J5LCBldmVudC5uYW1lLCBldmVudC5zdGFydFRpbWUsIGVuZFRpbWUpKTtcbiAgICAgIHRoaXMuZmx1c2goZW5kVGltZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBlbmRTeW5jKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IGVuZFRpbWU6IG51bWJlciA9IG5vdygpO1xuICAgIGlmICh0aGlzLl90aW1pbmdFdmVudHMubGVuZ3RoIDwgdGhpcy5fbWF4TnVtYmVyRXZlbnRzKSB7XG4gICAgICB0aGlzLl90aW1pbmdFdmVudHMucHVzaChuZXcgRXZlbnRSZWNvcmQoZXZlbnQuY2F0ZWdvcnksIGV2ZW50Lm5hbWUsIGV2ZW50LnN0YXJ0VGltZSwgZW5kVGltZSkpO1xuICAgICAgdGhpcy5mbHVzaChlbmRUaW1lKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGxvZ09uZUV2ZW50KGV2ZW50OiBFdmVudFJlY29yZCkge1xuICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgYFByb2ZpbGVyLiR7ZXZlbnQuY2F0ZWdvcnl9YCxcbiAgICAgIGAkeyhldmVudC5lbmRUaW1lIC0gZXZlbnQuc3RhcnRUaW1lKS50b0ZpeGVkKDIpfW1zIG9uIGV2ZW50ICcke2V2ZW50Lm5hbWV9JyBhdCAke2V2ZW50LmVuZFRpbWUudG9GaXhlZCgyKX1gLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGZsdXNoKGN1cnJlbnRUaW1lOiBudW1iZXIpIHtcbiAgICBpZiAoXG4gICAgICB0aGlzLl90aW1pbmdFdmVudHMubGVuZ3RoIC0gdGhpcy5fZmx1c2hQb2ludGVyID49IHRoaXMuX2ZsdXNoQmF0Y2hTaXplIHx8XG4gICAgICBjdXJyZW50VGltZSAtIHRoaXMuX2ZsdXNoVGltZSA+PSB0aGlzLl9mbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHNcbiAgICApIHtcbiAgICAgIC8vIHNob3VsZCBmbHVzaCB3aGVuIGVpdGhlciBiYXRjaCBzaXplIGFjY3VtbGF0ZWQgb3IgaW50ZXJ2YWwgZWxlcHNlZFxuXG4gICAgICBmb3IgKFxuICAgICAgICBjb25zdCBwcmV2aW91c1BvaW50ZXIgPSB0aGlzLl9mbHVzaFBvaW50ZXI7XG4gICAgICAgIHRoaXMuX2ZsdXNoUG9pbnRlciA8IHByZXZpb3VzUG9pbnRlciArIHRoaXMuX2ZsdXNoQmF0Y2hTaXplICYmIHRoaXMuX2ZsdXNoUG9pbnRlciA8IHRoaXMuX3RpbWluZ0V2ZW50cy5sZW5ndGg7XG4gICAgICAgIHRoaXMuX2ZsdXNoUG9pbnRlcisrXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5sb2dPbmVFdmVudCh0aGlzLl90aW1pbmdFdmVudHNbdGhpcy5fZmx1c2hQb2ludGVyXSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2ZsdXNoVGltZSA9IG5vdygpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBzdGFydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9zdGFydGVkO1xuICB9XG4gIHByaXZhdGUgX3N0YXJ0ZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfdGltaW5nRXZlbnRzOiBFdmVudFJlY29yZFtdO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX21heE51bWJlckV2ZW50czogbnVtYmVyO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZsdXNoQmF0Y2hTaXplOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIHByaXZhdGUgX2ZsdXNoVGltZTogbnVtYmVyO1xuICBwcml2YXRlIF9mbHVzaFBvaW50ZXIgPSAwO1xufVxuXG4vKipcbiAqIHJldHVybnMgYSBudW1iZXIgdG8gcmVwcmVzZW50IHRoZSBjdXJyZW50IHRpbWVzdGFtcCBpbiBhIHJlc29sdXRpb24gYXMgaGlnaCBhcyBwb3NzaWJsZS5cbiAqL1xuZXhwb3J0IGNvbnN0IG5vdyA9IHR5cGVvZiBwZXJmb3JtYW5jZSAhPT0gJ3VuZGVmaW5lZCcgJiYgcGVyZm9ybWFuY2Uubm93ID8gKCkgPT4gcGVyZm9ybWFuY2Uubm93KCkgOiBEYXRlLm5vdztcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuL29wZXJhdG9ycyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BTZXQge1xuICBkb21haW46IHN0cmluZztcbiAgdmVyc2lvbjogbnVtYmVyO1xufVxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIE9wU2V0IHtcbiAgLyoqXG4gICAqIERvbWFpbiBvZiBhbiBvcHNldCwgaXQgY2FuIGJlIGFuIGVtcHR5IHN0cmluZyhkZWZhdWx0IHZhbHVlLCByZXByZXNlbnQgZm9yIGFpLm9ubngpLCBvciAnYWkub25ueC5tbCdcbiAgICovXG4gIHR5cGUgRG9tYWluID0gJycgfCAnYWkub25ueC5tbCcgfCAnY29tLm1pY3Jvc29mdCc7XG4gIC8qKlxuICAgKiBBIHJlc29sdmUgcnVsZSBjb25zaXN0cyBvZiA0IG9yIDUgaXRlbXM6IG9wVHlwZSwgb3BTZXREb21haW4sIHZlcnNpb25TZWxlY3Rvciwgb3BlcmF0b3JJbXBsZW1lbnRhdGlvbiBhbmRcbiAgICogb3BlcmF0b3JJbml0aWFsaXphdGlvbiAob3B0aW9uYWwpXG4gICAqL1xuICB0eXBlIFJlc29sdmVSdWxlID1cbiAgICB8IFtzdHJpbmcsIERvbWFpbiwgc3RyaW5nLCBPcGVyYXRvckltcGxlbWVudGF0aW9uPEdyYXBoLk5vZGU+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+fSBKU09OIG9iamVjdFxuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBGdW5jdGlvblByb3RvXG4gICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5GdW5jdGlvblByb3RvJztcbiAgICB9O1xuXG4gICAgcmV0dXJuIEZ1bmN0aW9uUHJvdG87XG4gIH0pKCk7XG5cbiAgcmV0dXJuIG9ubng7XG59KSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9ICRyb290O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgTG9uZyBmcm9tICdsb25nJztcblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCAqIGFzIG9ydEZicyBmcm9tICcuL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQgeyBvbm54IH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuXG4vLyBjaGVjayB0aGUgaW5wdXRzIHNoYXBlIGJlZm9yZSBydW5uaW5nIGFuIE9QLlxuLy8gcmV0dXJuIHRydWUgd2hlbiB0aGUgaW5wdXRzIHBhc3MgdGhlIGNoZWNrXG4vLyByZXR1cm4gZmFsc2Ugd2hlbiB0aGUgaW5wdXRzIGRvIG5vdCBmaXQgdGhlIHJlcXVpcmVtZW50XG4vLyB0aHJvdyBleGNlcHRpb24gd2hlbiBmYXRhbCBlcnJvciBvciBub3QgaW1wbGVtZW50ZWRcbmV4cG9ydCBmdW5jdGlvbiBjaGVja0lucHV0c1NoYXBlKGlucHV0czogVGVuc29yW10sIC4uLmV4cGVjdGVkRGltZW5zaW9uczogbnVtYmVyW10pOiBib29sZWFuIHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gZXhwZWN0ZWREaW1lbnNpb25zLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgIGlmICghaW5wdXRzW2ldLmRpbXMgfHwgaW5wdXRzW2ldLmRpbXMubGVuZ3RoICE9PSBleHBlY3RlZERpbWVuc2lvbnNbaV0pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIEV2YWx1YXRlcyB0aGUgZ2l2ZW4gZXhwcmVzc2lvbiBhbmQgYXNzZXJ0cyBlcnJvciBtZXNzYWdlIGlmIGNvbmRpdGlvbiBpcyB1bm1ldC5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoZXhwcjogYm9vbGVhbiwgbXNnOiAoKSA9PiBzdHJpbmcpIHtcbiAgaWYgKCFleHByKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKHR5cGVvZiBtc2cgPT09ICdzdHJpbmcnID8gbXNnIDogbXNnKCkpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBBcnJheVV0aWwge1xuICAvKipcbiAgICogVmVyaWZpZXMgaWYgMiBpbnB1dCBhcnJheXMgY29udGFpbiB0aGUgc2FtZSBlbGVtZW50cy5cbiAgICogQHBhcmFtIG4xIEFycmF5IDFcbiAgICogQHBhcmFtIG4yIEFycmF5IDJcbiAgICogQHJldHVybnMgV2hldGhlciB0aGVzZSAyIGFyZSBlcXVhbFxuICAgKi9cbiAgc3RhdGljIGFycmF5c0VxdWFsKFxuICAgIG4xOlxuICAgICAgfCByZWFkb25seSBudW1iZXJbXVxuICAgICAgfCBJbnQ4QXJyYXlcbiAgICAgIHwgVWludDhBcnJheVxuICAgICAgfCBJbnQxNkFycmF5XG4gICAgICB8IFVpbnQxNkFycmF5XG4gICAgICB8IEludDMyQXJyYXlcbiAgICAgIHwgVWludDMyQXJyYXlcbiAgICAgIHwgVWludDhDbGFtcGVkQXJyYXlcbiAgICAgIHwgRmxvYXQzMkFycmF5XG4gICAgICB8IEZsb2F0NjRBcnJheSxcbiAgICBuMjpcbiAgICAgIHwgcmVhZG9ubHkgbnVtYmVyW11cbiAgICAgIHwgSW50OEFycmF5XG4gICAgICB8IFVpbnQ4QXJyYXlcbiAgICAgIHwgSW50MTZBcnJheVxuICAgICAgfCBVaW50MTZBcnJheVxuICAgICAgfCBJbnQzMkFycmF5XG4gICAgICB8IFVpbnQzMkFycmF5XG4gICAgICB8IFVpbnQ4Q2xhbXBlZEFycmF5XG4gICAgICB8IEZsb2F0MzJBcnJheVxuICAgICAgfCBGbG9hdDY0QXJyYXksXG4gICkge1xuICAgIGlmIChuMS5sZW5ndGggIT09IG4yLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG4xLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAobjFbaV0gIT09IG4yW2ldKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIE1hdE11bFV0aWwge1xuICAvKipcbiAgICogRml4IHRoZSBpbnB1dCBzaGFwZXMgZm9yIE1hdE11bCBvcGVyYXRpb24gaWYgdGhleSBuZWVkIGZpeGluZ1xuICAgKiBAcGFyYW0gZGltc0EgVGhlIHNoYXBlIG9mIHRlbnNvciBBLiBTaG91bGQgYmUgYW4gYXJyYXkgb2YgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHBhcmFtIGRpbXNCIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQi4gU2hvdWxkIGJlIGFuIGFycmF5IG9mIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEByZXR1cm5zIEEgdHVwbGUgY29udGFpbmluZyB0aGUgcHJlcHJvY2Vzc2VkIGlucHV0IHNoYXBlcyBhcyByZXF1aXJlZCBieSBPTk5YIHNwZWNpZmljYXRpb25zXG4gICAqL1xuICBzdGF0aWMgcHJlcHJvY2Vzc0lucHV0U2hhcGVzKFxuICAgIGRpbXNBOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBkaW1zQjogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IFtyZWFkb25seSBudW1iZXJbXSwgcmVhZG9ubHkgbnVtYmVyW11dIHtcbiAgICAvLyBJZiB0aGUgZmlyc3QgYXJndW1lbnQgaXMgMS1ELCBpdCBpcyBwcm9tb3RlZCB0byBhIG1hdHJpeCBieSBwcmVwZW5kaW5nXG4gICAgLy8gYSAxIHRvIGl0cyBkaW1lbnNpb25zLiBBZnRlciBtYXRyaXggbXVsdGlwbGljYXRpb24gdGhlIHByZXBlbmRlZCAxIGlzXG4gICAgLy8gcmVtb3ZlZC5cbiAgICBjb25zdCBhID0gZGltc0EubGVuZ3RoID09PSAxID8gWzEsIGRpbXNBWzBdXSA6IGRpbXNBO1xuXG4gICAgLy8gSWYgdGhlIHNlY29uZCBhcmd1bWVudCBpcyAxLUQsIGl0IGlzIHByb21vdGVkIHRvIGEgbWF0cml4IGJ5IGFwcGVuZGluZ1xuICAgIC8vIGEgMSB0byBpdHMgZGltZW5zaW9ucy4gQWZ0ZXIgbWF0cml4IG11bHRpcGxpY2F0aW9uIHRoZSBhcHBlbmRlZCAxIGlzXG4gICAgLy8gcmVtb3ZlZC5cbiAgICBjb25zdCBiID0gZGltc0IubGVuZ3RoID09PSAxID8gW2RpbXNCWzBdLCAxXSA6IGRpbXNCO1xuXG4gICAgcmV0dXJuIFthLCBiXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXggdGhlIG91dHB1dCBzaGFwZSBjb21wdXRlZCBmb3IgTWF0TXVsIG9wZXJhdGlvbiBpZiBpdCBuZWVkcyBmaXhpbmdcbiAgICogQHBhcmFtIG91dHB1dFNoYXBlIFRoZSBjb21wdXRlZCBvdXRwdXRTaGFwZS4gU2hvdWxkIGJlIGFuIGFycmF5IChhdGxlYXN0IG9mIGxlbmd0aCAyKSBvZiBwb3NpdGl2ZSBpbnRlZ2Vycy5cbiAgICogVGhpcyB3aWxsIGJlIG11dGF0ZWQuXG4gICAqIEBwYXJhbSBhUmFuayBUaGUgcmFuayBvZiB0ZW5zb3IgQS5cbiAgICogQHBhcmFtIGJSYW5rIFRoZSByYW5rIG9mIHRlbnNvciBCLlxuICAgKi9cbiAgc3RhdGljIHBvc3Rwcm9jZXNzT3V0cHV0U2hhcGUob3V0cHV0U2hhcGU6IG51bWJlcltdLCBhUmFuazogbnVtYmVyLCBiUmFuazogbnVtYmVyKSB7XG4gICAgLy8gUmVtb3ZlIHByZXBlbmRlZCBkaW1lbnNpb24gaWYgZmlyc3QgaW5wdXQgaXMgMWRcbiAgICBpZiAoYVJhbmsgPT09IDEpIHtcbiAgICAgIC8vIG91dHB1dFNoYXBlID0gb3V0cHV0U2hhcGUuc2xpY2UoMCwgb3V0cHV0U2hhcGUubGVuZ3RoIC0gMikuY29uY2F0KG91dHB1dFNoYXBlLnNsaWNlKG91dHB1dFNoYXBlLmxlbmd0aCAtIDEpKTtcbiAgICAgIG91dHB1dFNoYXBlLnNwbGljZShvdXRwdXRTaGFwZS5sZW5ndGggLSAyLCAxKTtcbiAgICB9XG4gICAgLy8gUmVtb3ZlIGFwcGVuZGVkIGRpbWVuc2lvbiBpZiBzZWNvbmQgaW5wdXQgaXMgMWRcbiAgICBpZiAoYlJhbmsgPT09IDEpIHtcbiAgICAgIG91dHB1dFNoYXBlLnBvcCgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIGV4cGVjdGVkIHNoYXBlIHdoZW4gbWF0cml4IG11bHRpcGxpY2F0aW9uXG4gICAqIEBwYXJhbSBhIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQS4gU2hvdWxkIGJlIGEgdHVwbGUgb2YgMiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0gYiBUaGUgc2hhcGUgb2YgdGVuc29yIEIuIFNob3VsZCBiZSBhIHR1cGxlIG9mIDIgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHJldHVybnMgVGhlIGV4cGVjdGVkIHNoYXBlIG9mIHRoZSByZXN1bHQsIG9yIHVuZGVmaW5lZCBpZiBOL0FcbiAgICovXG4gIHN0YXRpYyBjYWxjTWF0TXVsU2hhcGUoYTogW251bWJlciwgbnVtYmVyXSwgYjogW251bWJlciwgbnVtYmVyXSk6IFtudW1iZXIsIG51bWJlcl0gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBhWzFdICE9PSBiWzBdID8gdW5kZWZpbmVkIDogW2FbMF0sIGJbMV1dO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBCcm9hZGNhc3RVdGlsIHtcbiAgLyoqXG4gICAqIENhbGN1bGF0ZSB0aGUgZXhwZWN0ZWQgc2hhcGUgd2hlbiBicm9hZGNhc3RpbmcgMiB0ZW5zb3JzXG4gICAqIEBwYXJhbSBhIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQS4gU2hvdWxkIGJlIGFuIGFycmF5IG9mIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEBwYXJhbSBiIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQi4gU2hvdWxkIGJlIGFuIGFycmF5IG9mIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEBwYXJhbSBpc01hdE11bCBXaGV0aGVyIHRoZSBvcGVyYXRpb24gaXMgTWF0TXVsXG4gICAqIEByZXR1cm5zIFRoZSBleHBlY3RlZCBzaGFwZSBvZiB0aGUgcmVzdWx0LCBvciB1bmRlZmluZWQgaWYgTi9BXG4gICAqL1xuICBzdGF0aWMgY2FsY1NoYXBlKFxuICAgIGFkaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBiZGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgaXNNYXRNdWwgPSBmYWxzZSxcbiAgKTogcmVhZG9ubHkgbnVtYmVyW10gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGFyYW5rID0gYWRpbXMubGVuZ3RoO1xuICAgIGNvbnN0IGJyYW5rID0gYmRpbXMubGVuZ3RoO1xuICAgIGlmIChhcmFuayA9PT0gMCkge1xuICAgICAgcmV0dXJuIGJkaW1zO1xuICAgIH1cbiAgICBpZiAoYnJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBhZGltcztcbiAgICB9XG4gICAgY29uc3QgY3JhbmsgPSBNYXRoLm1heChhZGltcy5sZW5ndGgsIGJkaW1zLmxlbmd0aCk7XG4gICAgY29uc3QgY2RpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPihjcmFuayk7XG5cbiAgICAvLyBjYWxjdWxhdGUgdGhlIGxhc3QgMiBkaW1lbnNpb24gaWYgaXQgaXMgTWF0TXVsXG4gICAgaWYgKGlzTWF0TXVsKSB7XG4gICAgICBpZiAoYXJhbmsgPCAyIHx8IGJyYW5rIDwgMikge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgY29uc3QgY1NoYXBlTWF0TXVsID0gTWF0TXVsVXRpbC5jYWxjTWF0TXVsU2hhcGUoXG4gICAgICAgIFthZGltc1thcmFuayAtIDJdLCBhZGltc1thcmFuayAtIDFdXSxcbiAgICAgICAgW2JkaW1zW2JyYW5rIC0gMl0sIGJkaW1zW2JyYW5rIC0gMV1dLFxuICAgICAgKTtcbiAgICAgIGlmIChjU2hhcGVNYXRNdWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgW2NkaW1zW2NyYW5rIC0gMl0sIGNkaW1zW2NyYW5rIC0gMV1dID0gY1NoYXBlTWF0TXVsO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSBpc01hdE11bCA/IDMgOiAxOyBpIDw9IGNyYW5rOyBpKyspIHtcbiAgICAgIGNvbnN0IGFMZW4gPSBhcmFuayAtIGkgPCAwID8gMSA6IGFkaW1zW2FyYW5rIC0gaV07XG4gICAgICBjb25zdCBiTGVuID0gYnJhbmsgLSBpIDwgMCA/IDEgOiBiZGltc1ticmFuayAtIGldO1xuXG4gICAgICBpZiAoYUxlbiAhPT0gYkxlbiAmJiBhTGVuID4gMSAmJiBiTGVuID4gMSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgY2RpbXNbY3JhbmsgLSBpXSA9IE1hdGgubWF4KGFMZW4sIGJMZW4pO1xuICAgIH1cblxuICAgIHJldHVybiBjZGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiB0aGUgaW5kaWNlcyBvZiBhIGJyb2FkY2FzdGVkIHRlbnNvciwgY2FsY3VsYXRlIHRoZSBvcmlnaW5hbCBpbmRpY2VzXG4gICAqIEBwYXJhbSBicm9hZGNhc3RlZEluZGljZXMgVGhlIGdpdmVuIGluZGljZXMgb2YgdGhlIGJyb2FkY2FzdGVkIHRlbnNvci5cbiAgICogQHBhcmFtIG9yaWdpbmFsU2hhcGUgVGhlIG9yaWdpbmFsIHNoYXBlIG9mIHRoZSB0ZW5zb3IgYmVmb3JlIGJyb2FkY2FzXG4gICAqIEByZXR1cm5zIFRoZSBjYWxjdWxhdGVkIGluZGljZXMgdGhhdCBtYXBzIHRvIHRoZSBvcmlnaW5hbCB0ZW5zb3IuXG4gICAqL1xuICBzdGF0aWMgaW5kZXgoYnJvYWRjYXN0ZWRJbmRpY2VzOiByZWFkb25seSBudW1iZXJbXSwgb3JpZ2luYWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgLy8gTk9URSAxOiB3ZSBhc3N1bWUgdGhlIHBhcmFtZXRlciBicm9hZGNhc3RlZEluZGljZXMgaXMgdmFsaWQuIGllLiBpdCBzaG91bGQgaGF2ZSB0aGUgc2FtZVxuICAgIC8vIGxlbmd0aCBhcyB0aGUgYnJvYWRjYXN0ZWQgc2hhcGUsIGFuZCBmb3IgZWFjaCBkaW1lbnNpb24gdGhlIGluZGV4IHNob3VsZFxuICAgIC8vIG5vdCBiZSBvdXQgb2YgcmFuZ2UuXG4gICAgY29uc3Qgb3JpZ2luYWxJbmRpY2VzID0gbmV3IEFycmF5KG9yaWdpbmFsU2hhcGUubGVuZ3RoKTtcbiAgICBCcm9hZGNhc3RVdGlsLmZpbGxJbmRleChicm9hZGNhc3RlZEluZGljZXMsIG9yaWdpbmFsU2hhcGUsIG9yaWdpbmFsSW5kaWNlcyk7XG4gICAgcmV0dXJuIG9yaWdpbmFsSW5kaWNlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiB0aGUgaW5kaWNlcyBvZiBhIGJyb2FkY2FzdGVkIHRlbnNvciwgY2FsY3VsYXRlIHRoZSBvcmlnaW5hbCBpbmRpY2VzXG4gICAqIEBwYXJhbSBicm9hZGNhc3RlZEluZGljZXMgVGhlIGdpdmVuIGluZGljZXMgb2YgdGhlIGJyb2FkY2FzdGVkIHRlbnNvci5cbiAgICogQHBhcmFtIG9yaWdpbmFsU2hhcGUgVGhlIG9yaWdpbmFsIHNoYXBlIG9mIHRoZSB0ZW5zb3IgYmVmb3JlIGJyb2FkY2FzdFxuICAgKiBAcGFyYW0gb3JpZ2luYWxJbmRpY2VzIFRoZSBtYXBwaW5nIG9mIGJyb2FkY2FzdGVkSW5kaWNlcyB0byB0aGUgb3JpZ2luYWxJbmRpY2VzIChvdXRwdXQgcGFyYW1ldGVyIC0gd2lsbCBiZVxuICAgKiAgICAgbXV0YXRlZCkuXG4gICAqL1xuICBzdGF0aWMgZmlsbEluZGV4KGJyb2FkY2FzdGVkSW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10sIG9yaWdpbmFsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBvcmlnaW5hbEluZGljZXM6IG51bWJlcltdKSB7XG4gICAgLy8gTk9URSAxOiB3ZSBhc3N1bWUgdGhlIHBhcmFtZXRlciBicm9hZGNhc3RlZEluZGljZXMgaXMgdmFsaWQuIGllLiBpdCBzaG91bGQgaGF2ZSB0aGUgc2FtZSBsZW5ndGggYXMgdGhlXG4gICAgLy8gYnJvYWRjYXN0ZWQgc2hhcGUsIGFuZCBmb3IgZWFjaCBkaW1lbnNpb24gdGhlIGluZGV4IHNob3VsZCBub3QgYmUgb3V0IG9mIHJhbmdlLlxuICAgIC8vIE5PVEUgMjogd2UgYXNzdW1lIHRoZSBwYXJhbWV0ZXIgb3JpZ2luYWxJbmRpY2VzIGhhcyB0aGUgc2FtZSBsZW5ndGggYXMgdGhlIG9yaWdpbmFsU2hhcGVcbiAgICBjb25zdCBkaW1PZmZzZXQgPSBicm9hZGNhc3RlZEluZGljZXMubGVuZ3RoIC0gb3JpZ2luYWxTaGFwZS5sZW5ndGg7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcmlnaW5hbFNoYXBlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBvcmlnaW5hbEluZGljZXNbaV0gPSBicm9hZGNhc3RlZEluZGljZXNbZGltT2Zmc2V0ICsgaV0gJSBvcmlnaW5hbFNoYXBlW2ldO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIHRoZSBicm9hZGNhc3Rpbmcgb3BlcmF0aW9uIG9uIHRoZSBzcGVjaWZpYyBvcGVyYXRvclxuICAgKiBAcGFyYW0gYSBUaGUgaW5wdXQgdGVuc29yIEFcbiAgICogQHBhcmFtIGIgVGhlIGlucHV0IHRlbnNvciBCXG4gICAqIEBwYXJhbSBvcCBUaGUgb3BlcmF0b3IgbGFtYmRhIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSBpbnBsYWNlIFdoZXRoZXIgdG8gd3JpdGUgdGhlIHJlc3VsdCBiYWNrIHRvIEEuXG4gICAqIEByZXR1cm5zIFRoZSByZXN1bHQgdGVuc29yLCBvciB1bmRlZmluZWQgaWYgaW5wdXQgbm90IGJyb2FkY2FzdGFibGUuXG4gICAqL1xuICBzdGF0aWMgY2FsYyhcbiAgICBhOiBUZW5zb3IsXG4gICAgYjogVGVuc29yLFxuICAgIG9wOiAoYTogc3RyaW5nIHwgbnVtYmVyLCBiOiBzdHJpbmcgfCBudW1iZXIpID0+IHN0cmluZyB8IG51bWJlcixcbiAgICBpbnBsYWNlOiBib29sZWFuLFxuICAgIHJlc3VsdFR5cGU/OiBUZW5zb3IuRGF0YVR5cGUsXG4gICk6IFRlbnNvciB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBCcm9hZGNhc3RVdGlsLmNhbGNTaGFwZShhLmRpbXMsIGIuZGltcyk7XG5cbiAgICBpZiAob3V0cHV0U2hhcGUpIHtcbiAgICAgIGlmIChpbnBsYWNlICYmICFTaGFwZVV0aWwuYXJlRXF1YWwob3V0cHV0U2hhcGUsIGEuZGltcykpIHtcbiAgICAgICAgLy8gQiBpcyBub3QgYnJvYWRjYXN0YWJsZSB0byBBLCBmYWlsZWQgdG8gY2FsY3VsYXRlIGlucGxhY2UuXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gICAgICBjb25zdCBjID0gaW5wbGFjZSA/IGEgOiBuZXcgVGVuc29yKG91dHB1dFNoYXBlLCByZXN1bHRUeXBlIHx8IGEudHlwZSk7XG5cbiAgICAgIC8vIGJvdGggaW5wdXRzIGFyZSBzY2FsYXJzXG4gICAgICBpZiAob3V0cHV0U2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGMuc2V0KFtdLCBvcChhLmdldChbXSkgYXMgbnVtYmVyLCBiLmdldChbXSkgYXMgbnVtYmVyKSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGF0bGVhc3Qgb25lIGlucHV0IGlzIGEgbm9uLXNjYWxhclxuICAgICAgZWxzZSB7XG4gICAgICAgIGNvbnN0IG91dHB1dEluZGljZXMgPSBuZXcgQXJyYXk8bnVtYmVyPihvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICAgICAgICBjb25zdCBvcmlnaW5hbEluZGljZXNBID0gbmV3IEFycmF5KGEuZGltcy5sZW5ndGgpO1xuICAgICAgICBjb25zdCBvcmlnaW5hbEluZGljZXNCID0gbmV3IEFycmF5KGIuZGltcy5sZW5ndGgpO1xuICAgICAgICBsZXQgdmFsQTogc3RyaW5nIHwgbnVtYmVyID0gMDtcbiAgICAgICAgbGV0IHZhbEI6IHN0cmluZyB8IG51bWJlciA9IDA7XG4gICAgICAgIGxldCBpc0FTY2FsYXIgPSBmYWxzZTtcbiAgICAgICAgbGV0IGlzQlNjYWxhciA9IGZhbHNlO1xuICAgICAgICBpZiAoYS5kaW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHZhbEEgPSBhLmdldChbXSkgYXMgbnVtYmVyO1xuICAgICAgICAgIGlzQVNjYWxhciA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGIuZGltcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB2YWxCID0gYi5nZXQoW10pIGFzIG51bWJlcjtcbiAgICAgICAgICBpc0JTY2FsYXIgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXN0OiBudW1iZXI7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgICAgICAgLy8gdHJhdmVyc2FsIGluZGljZXNcbiAgICAgICAgICByZXN0ID0gaTtcbiAgICAgICAgICBmb3IgKGxldCBqID0gb3V0cHV0U2hhcGUubGVuZ3RoIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgICAgICAgIG91dHB1dEluZGljZXNbal0gPSByZXN0ICUgb3V0cHV0U2hhcGVbal07XG4gICAgICAgICAgICByZXN0ID0gTWF0aC5mbG9vcihyZXN0IC8gb3V0cHV0U2hhcGVbal0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghaXNBU2NhbGFyKSB7XG4gICAgICAgICAgICAvLyBtYXAgb3V0cHV0SW5kaWNlcyAod2hpY2ggaXMgYWN0dWFsbHkgYnJvYWRjYXN0ZWQpIHRvIHRoZSBvcmlnaW5hbEluZGljZXNcbiAgICAgICAgICAgIEJyb2FkY2FzdFV0aWwuZmlsbEluZGV4KG91dHB1dEluZGljZXMsIGEuZGltcywgb3JpZ2luYWxJbmRpY2VzQSk7XG4gICAgICAgICAgICB2YWxBID0gYS5nZXQob3JpZ2luYWxJbmRpY2VzQSkgYXMgbnVtYmVyO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWlzQlNjYWxhcikge1xuICAgICAgICAgICAgQnJvYWRjYXN0VXRpbC5maWxsSW5kZXgob3V0cHV0SW5kaWNlcywgYi5kaW1zLCBvcmlnaW5hbEluZGljZXNCKTtcbiAgICAgICAgICAgIHZhbEIgPSBiLmdldChvcmlnaW5hbEluZGljZXNCKSBhcyBudW1iZXI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYy5zZXQob3V0cHV0SW5kaWNlcywgb3AodmFsQSwgdmFsQikpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjO1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIGlmIGEgc2hhcGUgaXMgdW5pZGlyZWN0aW9uYWwgYnJvYWRjYXN0YWJsZSB0byBhbm90aGVyIHNoYXBlXG4gICAqIEBwYXJhbSBzaGFwZSBUaGUgaW5wdXQgc2hhcGVcbiAgICogQHBhcmFtIGZpbmFsU2hhcGUgVGhlIGRlc2lyZWQgc2hhcGUgYWZ0ZXIgYnJvYWRjYXN0aW5nXG4gICAqL1xuICBzdGF0aWMgaXNWYWxpZEJyb2FkY2FzdChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGZpbmFsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogYm9vbGVhbiB7XG4gICAgLy8gYWxpZ24gc2hhcGUgdG8gdGhlIHJpZ2h0XG4gICAgY29uc3QgaW5wdXRSYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IGZpbmFsUmFuayA9IGZpbmFsU2hhcGUubGVuZ3RoO1xuICAgIGlmIChpbnB1dFJhbmsgPiBmaW5hbFJhbmspIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPD0gaW5wdXRSYW5rOyBpKyspIHtcbiAgICAgIGlmIChzaGFwZVtpbnB1dFJhbmsgLSBpXSAhPT0gMSAmJiBzaGFwZVtpbnB1dFJhbmsgLSBpXSAhPT0gZmluYWxTaGFwZVtmaW5hbFJhbmsgLSBpXSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZSB0aGUgYnJvYWRjYXN0ZWQgZGltcyBpbiBpbnB1dCBzaGFwZSBiYXNlZCBvbiB0aGUgZ2l2ZW4gb3V0cHV0IHNoYXBlLlxuICAgKiBOb3RlIHRoYXQgdGhpcyBmdW5jdGlvbiBvbmx5IHJldHVybnMgdGhlIGJyb2FkY2FzdGVkIGRpbXMuXG4gICAqIEBwYXJhbSBpbnB1dFNoYXBlIFRoZSBpbnB1dCBzaGFwZVxuICAgKiBAcGFyYW0gb3V0cHV0U2hhcGUgVGhlIG91dHB1dCBzaGFwZVxuICAgKiBAcmV0dXJucyBUaGUgYnJvYWRjYXN0ZWQgZGltcyBpbiBpbnB1dCBzaGFwZS5cbiAgICovXG4gIHN0YXRpYyBnZXRCcm9hZGNhc3REaW1zKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgY29uc3QgaW5SYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgZGltczogbnVtYmVyW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluUmFuazsgaSsrKSB7XG4gICAgICBjb25zdCBkaW0gPSBpblJhbmsgLSAxIC0gaTtcbiAgICAgIGNvbnN0IGEgPSBpbnB1dFNoYXBlW2RpbV0gfHwgMTtcbiAgICAgIGNvbnN0IGIgPSBvdXRwdXRTaGFwZVtvdXRwdXRTaGFwZS5sZW5ndGggLSAxIC0gaV0gfHwgMTtcbiAgICAgIGlmIChiID4gMSAmJiBhID09PSAxKSB7XG4gICAgICAgIGRpbXMudW5zaGlmdChkaW0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGltcztcbiAgfVxufVxuXG4vLyBjb3B5IGFycmF5IGhlbHBlclxuLy8gbWltaWNzIG1lbWNweSBhcyBtdWNoIGFzIHBvc3NpYmxlXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlDb3B5SGVscGVyKFxuICB0YXJnZXQ6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gIHNvdXJjZTogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgdGFyZ2V0SW5kZXg6IG51bWJlcixcbiAgc291cmNlSW5kZXg6IG51bWJlcixcbiAgYmxvY2tTaXplOiBudW1iZXIsXG4pIHtcbiAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cbiAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cbiAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGluZGljZXMgdG8gYmUgY29waWVkIGFyZSBvdXRzaWRlIGJvdW5kcycpO1xuICB9XG4gIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldCBhcnJheSBpcyB0b28gc21hbGwgdG8gaG9sZCByZXN1bHQnKTtcbiAgfVxuXG4gIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdID0gc291cmNlW3NvdXJjZUluZGV4ICsgb2Zmc2V0XTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgR2VtbVV0aWwge1xuICAvLyB3aWxsIG1ha2Ugc3VyZSBpbnB1dCBzaGFwZXMgYXJlIGNvbXBhdGlibGUgZm9yIHRoaXMgb3BcbiAgLy8gYW5kIHJldHVybiBiYWNrIHRoZSBzaGFwZSBvZiB0aGUgb3V0cHV0IGluIHRoZSBmb3JtIG9mIGEgdHVwbGVcbiAgLy8gd2lsbCB0aHJvdyBleGNlcHRpb24gaWYgdGhlIGlucHV0IHNoYXBlcyBhcmUgbm90IGNvbXBhdGlibGVcbiAgc3RhdGljIGdldFNoYXBlT2ZHZW1tUmVzdWx0KFxuICAgIGxlZnRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgdHJhbnNMZWZ0OiBib29sZWFuLFxuICAgIHJpZ2h0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHRyYW5zUmlnaHQ6IGJvb2xlYW4sXG4gICAgYmlhc1NoYXBlPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBpZiAobGVmdFNoYXBlLmxlbmd0aCAhPT0gMiB8fCByaWdodFNoYXBlLmxlbmd0aCAhPT0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzaGFwZSBuZWVkIHRvIGJlIG9mIHNpemUgMicpO1xuICAgIH1cblxuICAgIGxldCBNOiBudW1iZXI7XG4gICAgbGV0IEs6IG51bWJlcjtcbiAgICBsZXQgTjogbnVtYmVyO1xuXG4gICAgaWYgKHRyYW5zTGVmdCkge1xuICAgICAgTSA9IGxlZnRTaGFwZVsxXTtcbiAgICAgIEsgPSBsZWZ0U2hhcGVbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIE0gPSBsZWZ0U2hhcGVbMF07XG4gICAgICBLID0gbGVmdFNoYXBlWzFdO1xuICAgIH1cblxuICAgIGxldCBrRGltID0gLTE7XG5cbiAgICBpZiAodHJhbnNSaWdodCkge1xuICAgICAgTiA9IHJpZ2h0U2hhcGVbMF07XG4gICAgICBrRGltID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgTiA9IHJpZ2h0U2hhcGVbMV07XG4gICAgICBrRGltID0gMDtcbiAgICB9XG5cbiAgICBpZiAocmlnaHRTaGFwZVtrRGltXSAhPT0gSykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdkaW1lbnNpb24gbWlzbWF0Y2gnKTtcbiAgICB9XG5cbiAgICBpZiAoTSA8PSAwIHx8IE4gPD0gMCB8fCBLIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBzaGFwZSBzcGVjaWZpZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoYmlhc1NoYXBlICYmICFCcm9hZGNhc3RVdGlsLmlzVmFsaWRCcm9hZGNhc3QoYmlhc1NoYXBlLCBbTSwgTl0pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dlbW06IGludmFsaWQgYmlhcyBzaGFwZSBmb3IgYnJvYWRjYXN0Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFtNLCBOLCBLXTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUHJvdG9VdGlsIHtcbiAgc3RhdGljIHRlbnNvckRhdGFUeXBlRnJvbVByb3RvKHR5cGVQcm90bzogb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZSB8IG9ydEZicy5UZW5zb3JEYXRhVHlwZSk6IFRlbnNvci5EYXRhVHlwZSB7XG4gICAgc3dpdGNoICh0eXBlUHJvdG8pIHtcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ4OlxuICAgICAgICByZXR1cm4gJ2ludDgnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ4OlxuICAgICAgICByZXR1cm4gJ3VpbnQ4JztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5CT09MOlxuICAgICAgICByZXR1cm4gJ2Jvb2wnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDE2OlxuICAgICAgICByZXR1cm4gJ2ludDE2JztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMTY6XG4gICAgICAgIHJldHVybiAndWludDE2JztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjpcbiAgICAgICAgcmV0dXJuICdpbnQzMic7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDMyOlxuICAgICAgICByZXR1cm4gJ3VpbnQzMic7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRkxPQVQ6XG4gICAgICAgIHJldHVybiAnZmxvYXQzMic7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFOlxuICAgICAgICByZXR1cm4gJ2Zsb2F0NjQnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlNUUklORzpcbiAgICAgICAgcmV0dXJuICdzdHJpbmcnO1xuXG4gICAgICAvLyBGb3IgSU5UNjQvVUlOVDY0LCByZWR1Y2UgdGhlaXIgdmFsdWUgdG8gMzItYml0cy5cbiAgICAgIC8vIFNob3VsZCB0aHJvdyBleGNlcHRpb24gd2hlbiBvdmVyZmxvd1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0OlxuICAgICAgICByZXR1cm4gJ2ludDMyJztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQ6XG4gICAgICAgIHJldHVybiAndWludDMyJztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7b25ueC5UZW5zb3JQcm90by5EYXRhVHlwZVt0eXBlUHJvdG9dfWApO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB0ZW5zb3JEYXRhVHlwZVN0cmluZ1RvRW51bSh0eXBlOiBzdHJpbmcpOiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlIHtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgJ2ludDgnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ4O1xuICAgICAgY2FzZSAndWludDgnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UODtcbiAgICAgIGNhc2UgJ2Jvb2wnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5CT09MO1xuICAgICAgY2FzZSAnaW50MTYnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQxNjtcbiAgICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQxNjtcbiAgICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMzI7XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzI7XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRkxPQVQ7XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFO1xuICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuU1RSSU5HO1xuICAgICAgY2FzZSAnaW50NjQnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ2NDtcbiAgICAgIGNhc2UgJ3VpbnQ2NCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDtcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7dHlwZX1gKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdGVuc29yRGltc0Zyb21Qcm90byhkaW1zOiBBcnJheTxudW1iZXIgfCBMb25nPik6IG51bWJlcltdIHtcbiAgICAvLyBnZXQgcmlkIG9mIExvbmcgdHlwZSBmb3IgZGltc1xuICAgIHJldHVybiBkaW1zLm1hcCgoZCkgPT4gKExvbmcuaXNMb25nKGQpID8gZC50b051bWJlcigpIDogZCkpO1xuICB9XG5cbiAgc3RhdGljIHRlbnNvclZhbHVlVHlwZUZyb21Qcm90byh2YWx1ZVR5cGU6IG9ubnguVHlwZVByb3RvLklUZW5zb3IpOiBHcmFwaC5WYWx1ZVR5cGUge1xuICAgIHJldHVybiB7XG4gICAgICB0ZW5zb3JUeXBlOiBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8odmFsdWVUeXBlLmVsZW1UeXBlISksXG4gICAgICBzaGFwZTogeyBkaW1zOiBQcm90b1V0aWwudGVuc29yRGltc0Zyb21Qcm90byh2YWx1ZVR5cGUuc2hhcGUhLmRpbSEubWFwKChkKSA9PiBkLmRpbVZhbHVlISkpIH0sXG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyB0ZW5zb3JEaW1zRnJvbU9SVEZvcm1hdCh0ZW5zb3I6IG9ydEZicy5UZW5zb3IpIHtcbiAgICBjb25zdCBkaW1zID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZW5zb3IuZGltc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGRpbXMucHVzaChMb25nVXRpbC5sb25nVG9OdW1iZXIodGVuc29yLmRpbXMoaSkhKSk7XG4gICAgfVxuICAgIHJldHVybiBkaW1zO1xuICB9XG5cbiAgc3RhdGljIHRlbnNvckF0dHJpYnV0ZXNGcm9tT1JURm9ybWF0KG5vZGU6IG9ydEZicy5Ob2RlKSB7XG4gICAgY29uc3QgYXR0cmlidXRlcyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZS5hdHRyaWJ1dGVzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgYXR0cmlidXRlcy5wdXNoKG5vZGUuYXR0cmlidXRlcyhpKSEpO1xuICAgIH1cbiAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTG9uZ1V0aWwge1xuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB0byBnZXQgYSBudW1iZXIgZnJvbSBsb25nIHR5cGUgb2YgZGF0YSBmb3IgYXR0cmlidXRlLCBkaW0sIGFuZCBpciB2ZXJzaW9uLFxuICAvLyB3aGljaCB2YWx1ZXMgYXJlIHNpZ25lZCBpbnRlZ2Vycy5cbiAgLy8gVG8gbWFrZSBpdCBtb3JlIGdlbmVyaWMsIGFkZCBhbiBvcHRpb25hbCBwYXJhbWV0ZXIgdG8gY29udmVydCB0byBhIHVuc2lnbmVkIG51bWJlci5cbiAgc3RhdGljIGxvbmdUb051bWJlcihuOiBMb25nIHwgYmlnaW50IHwgbnVtYmVyKSB7XG4gICAgaWYgKExvbmcuaXNMb25nKG4pKSB7XG4gICAgICByZXR1cm4gbi50b051bWJlcigpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG4gPT09ICdiaWdpbnQnKSB7XG4gICAgICByZXR1cm4gTnVtYmVyKG4pO1xuICAgIH1cbiAgICByZXR1cm4gbjtcbiAgfVxuICBzdGF0aWMgaXNMb25nKG46IHVua25vd24pIHtcbiAgICByZXR1cm4gTG9uZy5pc0xvbmcobikgfHwgdHlwZW9mIG4gPT09ICdiaWdpbnQnO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTaGFwZVV0aWwge1xuICBzdGF0aWMgc2l6ZShkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlciB7XG4gICAgcmV0dXJuIFNoYXBlVXRpbC5nZXRTaXplRnJvbURpbWVuc2lvblJhbmdlKGRpbXMsIDAsIGRpbXMubGVuZ3RoKTtcbiAgfVxuXG4gIC8vIGBheGlzYCBpbmNsdXNpdmVcbiAgc3RhdGljIHNpemVGcm9tRGltZW5zaW9uKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChheGlzIDwgMCB8fCBheGlzID4gZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBkaW1lbnNpb24gb2YgJHtheGlzfSBmb3Igc2l6ZUZyb21EaW1lbnNpb24gYXMgVGVuc29yIGhhcyAke2RpbXMubGVuZ3RofSBkaW1lbnNpb25zLmApO1xuICAgIH1cbiAgICByZXR1cm4gU2hhcGVVdGlsLmdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltcywgYXhpcywgZGltcy5sZW5ndGgpO1xuICB9XG5cbiAgLy8gYGF4aXNgIGV4Y2x1c2l2ZVxuICBzdGF0aWMgc2l6ZVRvRGltZW5zaW9uKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChheGlzIDwgMCB8fCBheGlzID4gZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBkaW1lbnNpb24gb2YgJHtheGlzfSBmb3Igc2l6ZVRvRGltZW5zaW9uIGFzIFRlbnNvciBoYXMgJHtkaW1zLmxlbmd0aH0gZGltZW5zaW9ucy5gKTtcbiAgICB9XG4gICAgcmV0dXJuIFNoYXBlVXRpbC5nZXRTaXplRnJvbURpbWVuc2lvblJhbmdlKGRpbXMsIDAsIGF4aXMpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgc2l6ZSA9IDE7XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgIC8vIHNhZmV0eSBjaGVjayBhcyB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgbXVsdGlwbGUgb3RoZXIgbWV0aG9kcyByZXF1aXJpbmcgc2l6ZS5cbiAgICAgIC8vIHNpemUgY2Fubm90IGJlIDAgb3IgbmVnYXRpdmUuXG4gICAgICBpZiAoZGltc1tpXSA8PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgICAgICdjYW5ub3QgZ2V0IHZhbGlkIHNpemUgZnJvbSBzcGVjaWZpZWQgZGltZW5zaW9uIHJhbmdlLiBNb3N0IGxpa2VseSB0aGUgcmFuZ2UgY29udGFpbnMgMCBvciBuZWdhdGl2ZSB2YWx1ZXMgaW4gdGhlbS4nLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgc2l6ZSAqPSBkaW1zW2ldO1xuICAgIH1cbiAgICByZXR1cm4gc2l6ZTtcbiAgfVxuXG4gIHN0YXRpYyBjb21wdXRlU3RyaWRlcyhkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCByYW5rID0gZGltcy5sZW5ndGg7XG4gICAgaWYgKHJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9IGVsc2UgaWYgKHJhbmsgPT09IDEpIHtcbiAgICAgIHJldHVybiBbMV07XG4gICAgfVxuICAgIGNvbnN0IHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMV0gPSAxO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gZGltc1tyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogZGltc1tpICsgMV07XG4gICAgfVxuICAgIHJldHVybiBzdHJpZGVzO1xuICB9XG5cbiAgc3RhdGljIHRyYW5zcG9zZShkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCBjb3B5ID0gZGltcy5zbGljZSgpO1xuICAgIHJldHVybiBjb3B5LnJldmVyc2UoKTtcbiAgfVxuXG4gIHN0YXRpYyBpbmRpY2VzVG9PZmZzZXQoaW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10sIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzPzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoYXhpcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBheGlzID0gaW5kaWNlcy5sZW5ndGg7XG4gICAgfVxuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXhpczsgKytpKSB7XG4gICAgICBvZmZzZXQgKz0gc3RyaWRlc1tpXSAqIGluZGljZXNbaV07XG4gICAgfVxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgb2Zmc2V0VG9JbmRpY2VzKG9mZnNldDogbnVtYmVyLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCByYW5rID0gc3RyaWRlcy5sZW5ndGg7XG4gICAgaWYgKHJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9IGVsc2UgaWYgKHJhbmsgPT09IDEpIHtcbiAgICAgIHJldHVybiBbb2Zmc2V0ICogc3RyaWRlc1swXV07XG4gICAgfVxuICAgIGNvbnN0IGluZGljZXM6IG51bWJlcltdID0gbmV3IEFycmF5KHN0cmlkZXMubGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluZGljZXMubGVuZ3RoIC0gMTsgKytpKSB7XG4gICAgICBpbmRpY2VzW2ldID0gTWF0aC5mbG9vcihvZmZzZXQgLyBzdHJpZGVzW2ldKTtcbiAgICAgIG9mZnNldCAtPSBpbmRpY2VzW2ldICogc3RyaWRlc1tpXTtcbiAgICB9XG4gICAgaW5kaWNlc1tpbmRpY2VzLmxlbmd0aCAtIDFdID0gb2Zmc2V0O1xuICAgIHJldHVybiBpbmRpY2VzO1xuICB9XG5cbiAgLyoqXG4gICAqIG5vcm1haWx6ZSBheGlzIG9mIHJhbmdlIFstciwgcikgaW50byBbMCwgcikuXG4gICAqL1xuICBzdGF0aWMgbm9ybWFsaXplQXhpcyhheGlzOiBudW1iZXIsIHRlbnNvclJhbms6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGF4aXMgPCAtdGVuc29yUmFuayAmJiBheGlzID49IHRlbnNvclJhbmspIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5zdXBwb3J0ZWQgYXhpcyBmb3IgdGhpcyBvcGVyYXRpb24uJyk7XG4gICAgfVxuICAgIHJldHVybiBheGlzIDwgMCA/IGF4aXMgKyB0ZW5zb3JSYW5rIDogYXhpcztcbiAgfVxuXG4gIHN0YXRpYyBub3JtYWxpemVBeGVzKGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdLCB0ZW5zb3JSYW5rOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIGF4ZXMubWFwKCh4KSA9PiB0aGlzLm5vcm1hbGl6ZUF4aXMoeCwgdGVuc29yUmFuaykpO1xuICB9XG5cbiAgLy8gSW5jcmVtZW50IGFuIGluZGV4IGludG8gYSB0ZW5zb3IgKGluIGxleGljb2dyYXBoaWNcbiAgLy8gb3JkZXJpbmcpLCB3cmFwcGluZyBhcm91bmQgdGhlIHNwZWNpZmllZCB1cHBlcl9ib3VuZC5cbiAgLyoqXG4gICAqIEluY3JlbWVudCBhbiBpbmRleCBpbnRvIGEgdGVuc29yIChpbiBsZXhpY29ncmFwaGljIG9yZGVyaW5nKSwgd3JhcHBpbmcgYXJvdW5kIHRoZSBzcGVjaWZpZWQgdXBwZXJfYm91bmQuXG4gICAqIEBwYXJhbSBpbmRleCBHaXZlbiBpbmRleCB0byBpbmNyZW1lbnQgKFdpbGwgYmUgbXV0YXRlZClcbiAgICogQHBhcmFtIGRpbXMgVGhlIGRpbWVuc2lvbnMgb2YgdGhlIHRlbnNvciBmb3Igd2hpY2ggdGhlIGdpdmVuIGluZGV4IGNvcnJlc3BvbmRzIHRvXG4gICAqIEBwYXJhbSBheGlzVG9JbmNyZW1lbnRPbiBUaGUgMS1pbmRleGVkIGF4aXMgdG8gaW5jcmVtZW50IG9uLiBJZiB1bmRlZmluZWQsIGF4aXNUb0luY3JlbWVudE9uID09IHJhbmtcbiAgICovXG4gIHN0YXRpYyBpbmNyZW1lbnRJbmRleChpbmRleDogbnVtYmVyW10sIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzVG9JbmNyZW1lbnRPbj86IG51bWJlcikge1xuICAgIGlmIChkaW1zLmxlbmd0aCA9PT0gMCB8fCBpbmRleC5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5kZXggaW5jcmVtZW50aW5nIHVuc3VwcG9ydGVkIGZvciBzY2FsYXIgVGVuc29yJyk7XG4gICAgfVxuICAgIGlmIChheGlzVG9JbmNyZW1lbnRPbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBheGlzVG9JbmNyZW1lbnRPbiA9IGRpbXMubGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoYXhpc1RvSW5jcmVtZW50T24gPD0gMCB8fCBheGlzVG9JbmNyZW1lbnRPbiA+IGRpbXMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5jb3JyZWN0IGF4aXMgdG8gaW5jcmVtZW50IG9uJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgayA9IGF4aXNUb0luY3JlbWVudE9uIC0gMTsgayA+PSAwOyAtLWspIHtcbiAgICAgIGluZGV4W2tdKys7XG4gICAgICBpZiAoaW5kZXhba10gPCBkaW1zW2tdKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaW5kZXhba10gPSAwO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9kdWNlcyBhIG5ldyBkaW1lbnNpb25zIGFycmF5IGJhc2VkIG9uIHRoZSB2YWx1ZXMgaW4gdGhlICdvcmlnaW5hbERpbWVuc2lvbnMnIGFuZCAnc2hhcGUnIGFycmF5XG4gICAqIFVzZWQgaW4gUmVzaGFwZVxuICAgKiBAcGFyYW0gb3JpZ2luYWxEaW1zIE9yaWdpbmFsIFNoYXBlIGFycmF5XG4gICAqIEBwYXJhbSBzaGFwZUhpbnRzIGFycmF5IGNvbnRhaW5pbmcgdmFsdWVzIHRvIGNvbXB1dGUgdGhlIG5ldyBkaW1lbnNpb25zXG4gICAqIEZvciBleGFtcGxlOlxuICAgKiBvcmlnaW5hbERpbXMgPSBbMiwyXSBhbmQgc2hhcGVIaW50cyA9IFswLC0xXSB3aWxsIHJldHVybiBbMiwyXVxuICAgKiBvcmlnaW5hbERpbXMgPSBbMiwyXSBhbmQgc2hhcGVIaW50cyA9IFs0XSB3aWxsIHJldHVybiBbNF1cbiAgICogb3JpZ2luYWxEaW1zID0gWzIsMl0gYW5kIHNoYXBlSGludHMgPSBbNV0gd2lsbCB0aHJvdyBhbiBleGNlcHRpb25cbiAgICogaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9PcGVyYXRvcnMubWQjUmVzaGFwZVxuICAgKi9cblxuICBzdGF0aWMgY2FsY3VsYXRlUmVzaGFwZWREaW1zKG9yaWdpbmFsRGltczogcmVhZG9ubHkgbnVtYmVyW10sIHNoYXBlSGludHM6IEFycmF5TGlrZTxudW1iZXI+KTogbnVtYmVyW10ge1xuICAgIC8vIHJlc2hhcGUgdG8gYSBTY2FsYXIgVGVuc29yXG4gICAgaWYgKHNoYXBlSGludHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBpZiAob3JpZ2luYWxEaW1zLmxlbmd0aCA9PT0gMCB8fCBTaGFwZVV0aWwuc2l6ZShvcmlnaW5hbERpbXMpID09PSAxKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IHJlc2hhcGUgdG8gYSBzY2FsYXIgVGVuc29yJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbkRpbXMgPSBzaGFwZUhpbnRzLmxlbmd0aDtcbiAgICBjb25zdCByZXNoYXBlZERpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPihuRGltcyk7XG4gICAgbGV0IHVua25vd25EaW1lbnNpb24gPSAtMTtcbiAgICBsZXQgbmV3VGVuc29yU2l6ZSA9IDE7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuRGltczsgaSsrKSB7XG4gICAgICBpZiAoc2hhcGVIaW50c1tpXSA8IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYSBkaW1lbnNpb24gaW4gc2hhcGUgaGludHMgY2Fubm90IGJlIGxlc3MgdGhhbiAtMScpO1xuICAgICAgfVxuICAgICAgaWYgKHNoYXBlSGludHNbaV0gPT09IC0xKSB7XG4gICAgICAgIGlmICh1bmtub3duRGltZW5zaW9uICE9PSAtMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignYXQgbW9zdCBvbmUgZGltZW5zaW9uIGluIHNoYXBlIGhpbnRzIGNhbiBiZSAtMScpO1xuICAgICAgICB9XG4gICAgICAgIHVua25vd25EaW1lbnNpb24gPSBpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHNoYXBlSGludHNbaV0gPT09IDApIHtcbiAgICAgICAgICBpZiAoaSA+PSBvcmlnaW5hbERpbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RoZSBkaW1lbnNpb24gd2l0aCB2YWx1ZSB6ZXJvIGV4Y2VlZHMgdGhlIGRpbWVuc2lvbiBzaXplIG9mIHRoZSBpbnB1dCB0ZW5zb3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzaGFwZWREaW1zW2ldID0gb3JpZ2luYWxEaW1zW2ldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc2hhcGVkRGltc1tpXSA9IHNoYXBlSGludHNbaV07XG4gICAgICAgIH1cbiAgICAgICAgbmV3VGVuc29yU2l6ZSAqPSByZXNoYXBlZERpbXNbaV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgb2xkVGVuc29yU2l6ZSA9IFNoYXBlVXRpbC5zaXplKG9yaWdpbmFsRGltcyk7XG4gICAgaWYgKHVua25vd25EaW1lbnNpb24gIT09IC0xKSB7XG4gICAgICBpZiAob2xkVGVuc29yU2l6ZSAlIG5ld1RlbnNvclNpemUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGB0aGUgaW5wdXQgdGVuc29yIGNhbm5vdCBiZSByZXNoYXBlZCB0byB0aGUgcmVxdWVzdGVkIHNoYXBlLiBJbnB1dCBzaGFwZTogWyR7XG4gICAgICAgICAgICBvcmlnaW5hbERpbXNcbiAgICAgICAgICB9XSBPdXRwdXQgc2hhcGU6IFske3NoYXBlSGludHN9XWAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXNoYXBlZERpbXNbdW5rbm93bkRpbWVuc2lvbl0gPSBvbGRUZW5zb3JTaXplIC8gbmV3VGVuc29yU2l6ZTtcbiAgICB9XG4gICAgLy8gdmFsaWRhdGUgc2l6ZXMgZnJvbSBvcmlnaW5hbERpbXMgYW5kIHJlc2hhcGVkRGltcyBtYXRjaFxuICAgIGVsc2Uge1xuICAgICAgaWYgKG5ld1RlbnNvclNpemUgIT09IG9sZFRlbnNvclNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwicmVzaGFwZWREaW1zIGFuZCBvcmlnaW5hbERpbXMgZG9uJ3QgaGF2ZSBtYXRjaGluZyBzaXplc1wiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc2hhcGVkRGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTb3J0cyBhIGdpdmVuIGFycmF5IGJhc2VkIG9uIHRoZSBpbmRpY2VzIGluIHRoZSBQZXJtIGFycmF5XG4gICAqIFVzZWQgaW4gVHJhbnNwb3NlXG4gICAqIEBwYXJhbSBhIEFycmF5IHRvIGJlIHNvcnRlZCBzdWNoIGFzIGRpbXMgb3Igc3RyaWRlc1xuICAgKiBAcGFyYW0gcGVybSBQZXJtIGdpdmVuOyBpZiBudWxsIGEgd2lsbCBiZSByZXZlcnNlZFxuICAgKi9cbiAgc3RhdGljIHNvcnRCYXNlZE9uUGVybShhOiByZWFkb25seSBudW1iZXJbXSwgcGVybT86IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmIChwZXJtKSB7XG4gICAgICByZXR1cm4gcGVybS5tYXAoKHYpID0+IGFbdl0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYS5zbGljZSgpLnJldmVyc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGFkcyBhIGdpdmVuIHNoYXBlIGFjY29yZGluZyB0byB0aGUgcGFkZGluZyB2YWx1ZXNcbiAgICogQHBhcmFtIGRpbXMgc2hhcGUgb2YgdGhlIFRlbnNvciB0byBiZSBwYWRkZWRcbiAgICogQHBhcmFtIHBhZCBwYWQgdmFsdWVzXG4gICAqL1xuICBzdGF0aWMgcGFkU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIHBhZDogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgY29uc3QgcmFuayA9IGRpbXMubGVuZ3RoO1xuICAgIHJldHVybiBkaW1zLm1hcCgodiwgaSkgPT4gdiArIHBhZFtpXSArIHBhZFtpICsgcmFua10pO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgaWYgdGhlIHR3byBzaGFwZXMgYXJlIGlkZW50aWNhbFxuICAgKiBAcGFyYW0gc2hhcGUxXG4gICAqIEBwYXJhbSBzaGFwZTJcbiAgICovXG4gIHN0YXRpYyBhcmVFcXVhbChzaGFwZTE6IHJlYWRvbmx5IG51bWJlcltdLCBzaGFwZTI6IHJlYWRvbmx5IG51bWJlcltdKTogYm9vbGVhbiB7XG4gICAgaWYgKHNoYXBlMS5sZW5ndGggIT09IHNoYXBlMi5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHNoYXBlMS5ldmVyeSgodiwgaSkgPT4gdiA9PT0gc2hhcGUyW2ldKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgaWYgdGhlIGdpdmVuIGBkaW1zYCBvciBgc2hhcGVgIGlzIHZhbGlkIGluIE9OTlguanMgY29udGV4dCBhbmQgcmV0dXJucyBkYXRhIHNpemVcbiAgICogQHBhcmFtIGRpbXMgLSBpbnB1dCBgZGltc2AgdGhhdCBuZWVkcyB0byBiZSBjaGVja2VkXG4gICAqL1xuICBzdGF0aWMgdmFsaWRhdGVEaW1zQW5kQ2FsY1NpemUoZGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBudW1iZXIge1xuICAgIGlmIChkaW1zLmxlbmd0aCA+IDYpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ09ubHkgcmFuayAwIHRvIDYgaXMgc3VwcG9ydGVkIGZvciB0ZW5zb3Igc2hhcGUuJyk7XG4gICAgfVxuICAgIGxldCBzaXplID0gMTtcbiAgICBmb3IgKGNvbnN0IG4gb2YgZGltcykge1xuICAgICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKG4pKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgc2hhcGU6ICR7bn0gaXMgbm90IGFuIGludGVnZXJgKTtcbiAgICAgIH1cbiAgICAgIGlmIChuIDwgMCB8fCBuID4gMjE0NzQ4MzY0Nykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBJbnZhbGlkIHNoYXBlOiBsZW5ndGggJHtufSBpcyBub3QgYWxsb3dlZGApO1xuICAgICAgfVxuICAgICAgc2l6ZSAqPSBuO1xuICAgIH1cbiAgICByZXR1cm4gc2l6ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIHRoZSBzaGFwZSBvZiBvdXRwdXQgdGVuc29yIHkgPSBmbGF0dGVuKHgsIGF4aXMpXG4gICAqIEBwYXJhbSBkaW1zIC0gc2hhcGUgb2YgaW5wdXQgdGVuc29yXG4gICAqIEBwYXJhbSBheGlzIC0gZmxhdHRlbiBheGlzLCBpbiB0aGUgcmFuZ2UgWy1yLCByXVxuICAgKi9cbiAgc3RhdGljIGZsYXR0ZW5TaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhpczogbnVtYmVyKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmIChheGlzIDwgMCkge1xuICAgICAgYXhpcyArPSBkaW1zLmxlbmd0aDtcbiAgICB9XG4gICAgY29uc3QgdG90YWwgPSBkaW1zLnJlZHVjZSgoeCwgeSkgPT4geCAqIHksIDEpO1xuICAgIGNvbnN0IHJpZ2h0ID0gZGltcy5zbGljZShheGlzKS5yZWR1Y2UoKHgsIHkpID0+IHggKiB5LCAxKTtcbiAgICBjb25zdCBvdXRwdXREaW1zID0gW3RvdGFsIC8gcmlnaHQsIHJpZ2h0XTtcblxuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgdGhlIHNoYXBlIG9mIG91dHB1dCB0ZW5zb3IgeSA9IHNxdWVlemUoeCwgYXhlcylcbiAgICogQHBhcmFtIGRpbXMgLSBzaGFwZSBvZiBpbnB1dCB0ZW5zb3JcbiAgICogQHBhcmFtIGF4ZXMgLSBzcXVlZXplIGF4ZXNcbiAgICovXG4gIHN0YXRpYyBzcXVlZXplU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IG91dHB1dERpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPigpO1xuXG4gICAgLy8gc2FuaXR5IGNoZWNrXG4gICAgYXhlcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGVzKGF4ZXMsIGRpbXMubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGltcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgaW5TcXVlZXplTGlzdCA9IGF4ZXMuaW5kZXhPZihpKSA+PSAwO1xuICAgICAgaWYgKGluU3F1ZWV6ZUxpc3QgJiYgZGltc1tpXSAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NxdWVlemUgYW4gYXhpcyBvZiBzaXplIGRpZmZlcmVudCB0aGFuIDEnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKChheGVzLmxlbmd0aCA9PT0gMCAmJiBkaW1zW2ldID4gMSkgfHwgKGF4ZXMubGVuZ3RoID4gMCAmJiAhaW5TcXVlZXplTGlzdCkpIHtcbiAgICAgICAgb3V0cHV0RGltcy5wdXNoKGRpbXNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgdGhlIHNoYXBlIG9mIG91dHB1dCB0ZW5zb3IgeSA9IHVuc3F1ZWV6ZSh4LCBheGVzKVxuICAgKiBAcGFyYW0gZGltcyAtIHNoYXBlIG9mIGlucHV0IHRlbnNvclxuICAgKiBAcGFyYW0gYXhlcyAtIHVuc3F1ZWV6ZSBheGVzXG4gICAqL1xuICBzdGF0aWMgdW5zcXVlZXplU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IG91dHB1dERpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPihkaW1zLmxlbmd0aCArIGF4ZXMubGVuZ3RoKTtcblxuICAgIC8vIGluaXRpYWxpemUgdGhlIGFycmF5IGVsZW1lbnRzIHRvIDBcbiAgICBvdXRwdXREaW1zLmZpbGwoMCk7XG5cbiAgICAvLyBzZXQgYWxsIGF4ZXMgaW5kaWNlcyB0byAxIGluIG91dHB1dERpbXMgYW5kIGNoZWNrIGZvciBkdXBsaWNhdGVzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBheGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXhlc1tpXSwgb3V0cHV0RGltcy5sZW5ndGgpO1xuICAgICAgaWYgKGF4aXMgPj0gb3V0cHV0RGltcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiJ2F4ZXMnIGhhcyBhbiBvdXQgb2YgcmFuZ2UgYXhpc1wiKTtcbiAgICAgIH1cbiAgICAgIGlmIChvdXRwdXREaW1zW2F4aXNdICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIidheGVzJyBoYXMgYSBkdXBsaWNhdGUgYXhpc1wiKTtcbiAgICAgIH1cblxuICAgICAgb3V0cHV0RGltc1theGlzXSA9IDE7XG4gICAgfVxuXG4gICAgLy8gZmlsbCBpbiB0aGUgemVybyBlbnRyaWVzIG9mIG91dHB1dERpbXMgd2l0aCB0aGUgaW5wdXQgdGVuc29yJ3Mgc2hhcGVcbiAgICBsZXQgaW5wdXREaW1zSXRlcmF0b3IgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0RGltcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG91dHB1dERpbXNbaV0gPT09IDApIHtcbiAgICAgICAgb3V0cHV0RGltc1tpXSA9IGRpbXNbaW5wdXREaW1zSXRlcmF0b3IrK107XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2FuaXR5IGNoZWNrIGFzc2VydGlvbi4gJ2lucHV0RGltc0l0ZXJhdG9yJ1xuICAgIC8vIHNob3VsZCBiZSBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mICdkaW1zJ1xuICAgIGlmIChpbnB1dERpbXNJdGVyYXRvciAhPT0gZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGhlIHVuc3F1ZWV6ZWQgZGltZW5zaW9uIGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG59XG5cbi8vIGJ1bmNoIG9mIGhlbHBlciBtZXRob2RzIHRoYXQgZG8gYSB2YXJpZXR5IG9mIG1hdGggb3BlcmF0aW9uc1xuZXhwb3J0IGNsYXNzIE1hdGhVdGlsIHtcbiAgLy8geSA9ICh4KngpICsgeVxuICBzdGF0aWMgc3FyKFxuICAgIHRhcmdldDogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICBzb3VyY2U6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgdGFyZ2V0SW5kZXg6IG51bWJlcixcbiAgICBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgIGJsb2NrU2l6ZTogbnVtYmVyLFxuICApIHtcbiAgICBpZiAoc291cmNlSW5kZXggPCAwIHx8IHNvdXJjZUluZGV4ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlSW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggPCAwIHx8IHRhcmdldEluZGV4ID49IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0SW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAoc291cmNlSW5kZXggKyBibG9ja1NpemUgPiBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZSBpbmRpY2VzIHRvIGJlIGNvcGllZCBhcmUgb3V0c2lkZSBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4ICsgYmxvY2tTaXplID4gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXQgYXJyYXkgaXMgdG9vIHNtYWxsIHRvIGhvbGQgcmVzdWx0Jyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgYmxvY2tTaXplOyBvZmZzZXQrKykge1xuICAgICAgdGFyZ2V0W3RhcmdldEluZGV4ICsgb2Zmc2V0XSArPSBNYXRoLnBvdyhzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdLCAyKTtcbiAgICB9XG4gIH1cblxuICAvLyB5ID0gYXggKyB5XG4gIHN0YXRpYyBheHB5KFxuICAgIHRhcmdldDogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICBzb3VyY2U6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgdGFyZ2V0SW5kZXg6IG51bWJlcixcbiAgICBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgIGJsb2NrU2l6ZTogbnVtYmVyLFxuICAgIGFscGhhOiBudW1iZXIsXG4gICkge1xuICAgIGlmIChzb3VyY2VJbmRleCA8IDAgfHwgc291cmNlSW5kZXggPj0gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCA8IDAgfHwgdGFyZ2V0SW5kZXggPj0gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmIChzb3VyY2VJbmRleCArIGJsb2NrU2l6ZSA+IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGluZGljZXMgdG8gYmUgY29waWVkIGFyZSBvdXRzaWRlIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggKyBibG9ja1NpemUgPiB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldCBhcnJheSBpcyB0b28gc21hbGwgdG8gaG9sZCByZXN1bHQnKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBibG9ja1NpemU7IG9mZnNldCsrKSB7XG4gICAgICB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdICs9IGFscGhhICogc291cmNlW3NvdXJjZUluZGV4ICsgb2Zmc2V0XTtcbiAgICB9XG4gIH1cblxuICAvLyB5ID0gcG93KHgsIGIpXG4gIHN0YXRpYyBwb3d4KFxuICAgIHRhcmdldDogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICBzb3VyY2U6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgdGFyZ2V0SW5kZXg6IG51bWJlcixcbiAgICBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgIGJsb2NrU2l6ZTogbnVtYmVyLFxuICAgIGI6IG51bWJlcixcbiAgKSB7XG4gICAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICAgIH1cblxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gPSBNYXRoLnBvdyhzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdLCBiKTtcbiAgICB9XG4gIH1cblxuICAvLyB5ID0geCAqIHlcbiAgc3RhdGljIG11bChcbiAgICB0YXJnZXQ6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgc291cmNlOiBudW1iZXJbXSB8IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHRhcmdldEluZGV4OiBudW1iZXIsXG4gICAgc291cmNlSW5kZXg6IG51bWJlcixcbiAgICBibG9ja1NpemU6IG51bWJlcixcbiAgKSB7XG4gICAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICAgIH1cblxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gPSBzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdICogdGFyZ2V0W3RhcmdldEluZGV4ICsgb2Zmc2V0XTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNwbGl0VXRpbCB7XG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIG5ldyBTaGFwZXMgZnJvbSBleGlzdGluZyBvbmUgYW5kIHRoZSBzcGxpdHMgZ2l2ZW4gYWxvbmcgdGhlIGF4aXMgcHJvdmlkZXNcbiAgICogQHBhcmFtIGRpbXMgU2hhcGUgb2YgdGhlIFRlbnNvciB0byBiZSBzcGxpdHRlZCBpbnRvIHR3byBvciBtb3JlIFNoYXBlc1xuICAgKiBAcGFyYW0gYXhpcyBUaGUgZGltZW5zaW9uIGFsb25nIHdoaWNoIHRoZSBUZW5zb3Igd2lsbCBiZSBzcGxpdFxuICAgKiBAcGFyYW0gc3BsaXRzIE9mZnNldHMgZm9yIHRoZSBzdGFydCBvZiBlYWNoIHNwbGl0XG4gICAqL1xuICBzdGF0aWMgc3BsaXRTaGFwZShcbiAgICBkaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBheGlzOiBudW1iZXIsXG4gICAgc3BsaXQ6IG51bWJlcltdLFxuICAgIG51bU91dHB1dHM/OiBudW1iZXIsXG4gICk6IFtudW1iZXJbXVtdLCBudW1iZXJbXV0ge1xuICAgIGlmIChzcGxpdC5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmICghbnVtT3V0cHV0cykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJuZWVkIHRvIGtub3cgbnVtYmVyIG9mIG91dHB1dHMgd2hlbiB0aGUgJ3NwbGl0JyBhdHRyaWJ1dGUgaXMgbm90IHNwZWNpZmllZFwiKTtcbiAgICAgIH1cbiAgICAgIFNwbGl0VXRpbC5kZXRlcm1pbmVTcGxpdChkaW1zW2F4aXNdLCBudW1PdXRwdXRzLCBzcGxpdCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2hhcGVzOiBudW1iZXJbXVtdID0gW107XG4gICAgY29uc3Qgb2Zmc2V0cyA9IFswXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNwbGl0Lmxlbmd0aDsgKytpKSB7XG4gICAgICBpZiAoaSAhPT0gMCkge1xuICAgICAgICBvZmZzZXRzLnB1c2gob2Zmc2V0c1tpIC0gMV0gKyBzcGxpdFtpIC0gMV0pO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2hhcGUgPSBkaW1zLnNsaWNlKCk7XG4gICAgICBzaGFwZVtheGlzXSA9IHNwbGl0W2ldO1xuICAgICAgc2hhcGVzLnB1c2goc2hhcGUpO1xuICAgIH1cbiAgICByZXR1cm4gW3NoYXBlcywgb2Zmc2V0c107XG4gIH1cblxuICBzdGF0aWMgZGV0ZXJtaW5lU3BsaXQobnVtRWxlbWVudHNBbG9uZ0F4aXM6IG51bWJlciwgbnVtT3V0cHV0czogbnVtYmVyLCBzcGxpdDogbnVtYmVyW10pIHtcbiAgICAvLyBJZiAnc3BsaXQnIGlzIG5vdCBzcGVjaWZpZWQgYnkgdGhlIHVzZXIsIHdlIG5lZWQgdG8gcGFydGl0aW9uIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgZXF1YWxseSBhbW9uZyB0aGUgb3V0cHV0c1xuICAgIGlmIChudW1FbGVtZW50c0Fsb25nQXhpcyAlIG51bU91dHB1dHMgIT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IHNwbGl0IHRlbnNvciB0byBlcXVhbCBzaXplZCBwYXJ0cycpO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bU91dHB1dHM7ICsraSkge1xuICAgICAgc3BsaXQucHVzaChudW1FbGVtZW50c0Fsb25nQXhpcyAvIG51bU91dHB1dHMpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUmVkdWNlVXRpbCB7XG4gIC8qKlxuICAgKiBQZXJmb3JtIHJlZHVjZSBvcGVyYXRpb25zIG9uIHRoZSBzcGVjaWZpYyBvcGVyYXRvclxuICAgKiBAcGFyYW0gYSBJbnB1dCB0ZW5zb3IgZGF0YVxuICAgKiBAcGFyYW0gYXhlcyBUaGUgZGltZW5zaW9ucyBhbG9uZyB3aGljaCB0aGUgVGVuc29yIHdpbGwgYmUgcmVkdWNlZFxuICAgKiBAcGFyYW0ga2VlcGRpbXMgSWYgc2V0IHRvIHRydWUsIHRoZSBheGVzIHdoaWNoIGFyZSByZWR1Y2VkIGFyZSBsZWZ0IGluIHRoZVxuICAgKiAgICByZXN1bHQgYXMgZGltZW5zaW9ucyB3aXRoIHNpemUgb25lLlxuICAgKiBAcGFyYW0gb3AxIFRoZSBvcGVyYXRpb24gdG8gYmUgcGVyZm9ybWVkIG9uIGVhY2ggZWxlbWVudCBpbiB0aGUgdGVuc29yXG4gICAqIEBwYXJhbSBvcDIgVGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgYmV0d2VlbiBlbGVtZW50cyBpbiB0aGUgdGVuc29yXG4gICAqL1xuICBzdGF0aWMgY2FsY1JlZHVjZShcbiAgICBhOiBUZW5zb3IsXG4gICAgYXhlczogbnVtYmVyW10sXG4gICAga2VlcGRpbXM6IGJvb2xlYW4sXG4gICAgb3AxOiAoYjogbnVtYmVyKSA9PiBudW1iZXIsXG4gICAgb3AyOiAoYTogbnVtYmVyLCBiOiBudW1iZXIpID0+IG51bWJlcixcbiAgKTogVGVuc29yIHtcbiAgICBjb25zdCBkaW1zID0gYS5kaW1zLnNsaWNlKDApO1xuICAgIC8vIGlmIGF4ZXMgaXMgbm90IHNldCwgcGVyZm9ybSByZWR1Y2Ugb24gYWxsIGF4ZXNcbiAgICBpZiAoYXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGRpbXMuZm9yRWFjaCgoX2QsIGluZCkgPT4gYXhlcy5wdXNoKGluZCkpO1xuICAgIH1cbiAgICAvLyBnZXQgYSB0ZW1wb3JhcnkgYnJvYWRjYXN0YWJsZSBvdXRwdXQgc2hhcGVcbiAgICBjb25zdCBvdXRwdXREaW1zID0gUmVkdWNlVXRpbC5jYWxjUmVkdWNlU2hhcGUoZGltcywgYXhlcywgdHJ1ZSk7XG5cbiAgICAvLyBsb29wIHRocm91Z2ggdGhlIG91dHB1dCBhbmQgY2FsY3VsYXRlIHJlc3VsdCBvbmUgYnkgb25lXG4gICAgY29uc3Qgc2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dERpbXMpO1xuICAgIGNvbnN0IHkgPSBuZXcgVGVuc29yKG91dHB1dERpbXMsIGEudHlwZSk7XG4gICAgY29uc3Qgc3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhvdXRwdXREaW1zKTtcbiAgICBjb25zdCBpbnB1dFN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoZGltcyk7XG4gICAgY29uc3QgaW5kaWNlc1kgPSBuZXcgQXJyYXkoZGltcy5sZW5ndGgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgICBjb25zdCBpbmRpY2VzID0gU2hhcGVVdGlsLm9mZnNldFRvSW5kaWNlcyhpLCBzdHJpZGVzKTtcbiAgICAgIC8vIG1hcCBpbmRleFxuICAgICAgQnJvYWRjYXN0VXRpbC5maWxsSW5kZXgoaW5kaWNlcywgZGltcywgaW5kaWNlc1kpO1xuICAgICAgeS5zZXQoXG4gICAgICAgIGluZGljZXMsXG4gICAgICAgIFJlZHVjZVV0aWwuY2FsY1JlZHVjZUJ5QXhpcyhcbiAgICAgICAgICBhLm51bWJlckRhdGEsXG4gICAgICAgICAgYXhlcyxcbiAgICAgICAgICBkaW1zLFxuICAgICAgICAgIDAsXG4gICAgICAgICAgU2hhcGVVdGlsLmluZGljZXNUb09mZnNldChpbmRpY2VzWSwgaW5wdXRTdHJpZGVzKSxcbiAgICAgICAgICBvcDEsXG4gICAgICAgICAgb3AyLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoa2VlcGRpbXMpIHtcbiAgICAgIHJldHVybiB5O1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBrZWVwZGltcyA9PSAwLCBjYWxjdWxhdGUgdGhlIGV4cGVjdGVkIHNoYXBlXG4gICAgICByZXR1cm4gbmV3IFRlbnNvcihcbiAgICAgICAgUmVkdWNlVXRpbC5jYWxjUmVkdWNlU2hhcGUoZGltcywgYXhlcywga2VlcGRpbXMpLFxuICAgICAgICB5LnR5cGUsXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICB5LmRhdGEsXG4gICAgICAgIHkuZGF0YUlkLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybSByZWR1Y2Ugb3BlcmF0aW9ucyBvbiB0aGUgc3BlY2lmaWMgb3BlcmF0b3Igb24gc3BlY2lmaWMgYXhlc1xuICAgKiBAcGFyYW0gYSBJbnB1dCB0ZW5zb3IgZGF0YVxuICAgKiBAcGFyYW0gYXhlcyBUaGUgZGltZW5zaW9ucyBhbG9uZyB3aGljaCB0aGUgVGVuc29yIHdpbGwgYmUgcmVkdWNlZFxuICAgKiBAcGFyYW0gZGltcyBUaGUgaW5wdXQgZGltZW5zaW9uLlxuICAgKiBAcGFyYW0gY3VyQXhpc0luZCBJbmRleCBpbiBheGVzIHNwZWNpZnlpbmcgdGhlIGN1cnJlbnQgZGltZW5zaW9uIGFsb25nXG4gICAqICAgICAgd2hpY2ggdGhlIHRlbnNvciB3aWxsIGJlIHJlZHVjZWRcbiAgICogQHBhcmFtIHBvcyBUaGUgY3VycmVudCBpbmRleCBvZiBlbGVtZW50IHRvIHBlcmZvcm0gb3BlcmF0aW9uXG4gICAqIEBwYXJhbSBvcDEgVGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgb24gZWFjaCBlbGVtZW50IGluIHRoZSB0ZW5zb3JcbiAgICogQHBhcmFtIG9wMiBUaGUgb3BlcmF0aW9uIHRvIGJlIHBlcmZvcm1lZCBiZXR3ZWVuIGVsZW1lbnRzIGluIHRoZSB0ZW5zb3JcbiAgICovXG4gIHN0YXRpYyBjYWxjUmVkdWNlQnlBeGlzKFxuICAgIGlucHV0OiBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICBheGVzOiBudW1iZXJbXSxcbiAgICBkaW1zOiBudW1iZXJbXSxcbiAgICBjdXJBeGlzSW5kOiBudW1iZXIsXG4gICAgcG9zOiBudW1iZXIsXG4gICAgb3AxOiAoYjogbnVtYmVyKSA9PiBudW1iZXIsXG4gICAgb3AyOiAoYTogbnVtYmVyLCBiOiBudW1iZXIpID0+IG51bWJlcixcbiAgKTogbnVtYmVyIHtcbiAgICBsZXQgcmVzID0gMDtcbiAgICBpZiAoY3VyQXhpc0luZCA+PSBheGVzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIG9wMShpbnB1dFtwb3NdKTtcbiAgICB9XG4gICAgY29uc3QgYXhpcyA9IGF4ZXNbY3VyQXhpc0luZF07XG4gICAgY29uc3Qgc3RlcCA9IGF4aXMgPj0gZGltcy5sZW5ndGggPyAxIDogU2hhcGVVdGlsLnNpemUoZGltcy5zbGljZShheGlzICsgMSkpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGltc1theGlzXTsgaSsrKSB7XG4gICAgICByZXMgPVxuICAgICAgICBpID09PSAwXG4gICAgICAgICAgPyBSZWR1Y2VVdGlsLmNhbGNSZWR1Y2VCeUF4aXMoaW5wdXQsIGF4ZXMsIGRpbXMsIGN1ckF4aXNJbmQgKyAxLCBwb3MsIG9wMSwgb3AyKVxuICAgICAgICAgIDogb3AyKHJlcywgUmVkdWNlVXRpbC5jYWxjUmVkdWNlQnlBeGlzKGlucHV0LCBheGVzLCBkaW1zLCBjdXJBeGlzSW5kICsgMSwgcG9zLCBvcDEsIG9wMikpO1xuICAgICAgcG9zICs9IHN0ZXA7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBleHBlY3RlZCBzaGFwZSBvZiBhIHJlZHVjZSBvcGVyYXRpb25cbiAgICogQHBhcmFtIGRpbXMgVGhlIGlucHV0IHRlbnNvciBkaW1lbnNpb25cbiAgICogQHBhcmFtIGF4ZXMgVGhlIGRpbWVuc2lvbnMgYWxvbmcgd2hpY2ggdGhlIFRlbnNvciB3aWxsIGJlIHJlZHVjZWRcbiAgICogQHBhcmFtIGtlZXBkaW1zIElmIHNldCB0byB0cnVlLCB0aGUgYXhlcyB3aGljaCBhcmUgcmVkdWNlZCBhcmUgbGVmdCBpbiB0aGVcbiAgICogICAgcmVzdWx0IGFzIGRpbWVuc2lvbnMgd2l0aCBzaXplIG9uZS5cbiAgICovXG4gIHN0YXRpYyBjYWxjUmVkdWNlU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdLCBrZWVwRGltczogYm9vbGVhbik6IG51bWJlcltdIHtcbiAgICBjb25zdCBvdXRwdXREaW1zID0gZGltcy5zbGljZSgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXhlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGtlZXBEaW1zKSB7XG4gICAgICAgIG91dHB1dERpbXNbYXhlc1tpXV0gPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0RGltc1theGVzW2ldXSA9IDA7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXREaW1zLmZpbHRlcigoZGltKSA9PiBkaW0gIT09IDApO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQb29sQ29udlV0aWwge1xuICAvKipcbiAgICogQWRqdXN0IHRoZSBrZXJuZWwsIHN0cmlkZXMsIHBhZHMgdG8gY29ycmVjdCByYW5rLiBTZXQgdG8gZGVmYXVsdCB2YWx1ZSBpZiBub3QgcHJlc2VudFxuICAgKiBAcGFyYW0gaXNHbG9iYWxPcGVyYXRvciBJZiB0cnVlLCBwZXJmb3JtIGdsb2JhbCBwb29saW5nLlxuICAgKiBAcGFyYW0gaW5wdXREaW1zIFRoZSBpbnB1dCB0ZW5zb3IgZGltZW5zaW9uLlxuICAgKiBAcGFyYW0ga2VybmVsU2hhcGUgVGhlIHNpemUgb2YgdGhlIGtlcm5lbCBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBzdHJpZGVzIFN0cmlkZSBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBkaWxhdGlvbnMgRGlsYXRpb24gYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gcGFkcyBQYWRkaW5nIGZvciB0aGUgYmVnaW5uaW5nIGFuZCBlbmRpbmcgYWxvbmcgZWFjaCBheGlzLlxuICAgKi9cbiAgc3RhdGljIGFkanVzdFBvb2xBdHRyaWJ1dGVzKFxuICAgIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4gICAgaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogbnVtYmVyW10sXG4gICAgc3RyaWRlczogbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiBudW1iZXJbXSxcbiAgICBwYWRzOiBudW1iZXJbXSxcbiAgKSB7XG4gICAgaWYgKCFpc0dsb2JhbE9wZXJhdG9yICYmIGtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXREaW1zLmxlbmd0aCAtIDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIHNwZWNpZmllZCBrZXJuZWwgc2hhcGVzIHNob3VsZCBiZSAyIGxlc3MgdGhhbiBsZW5ndGggb2YgaW5wdXQgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGlmIChpc0dsb2JhbE9wZXJhdG9yKSB7XG4gICAgICAvLyBhZGp1c3Qga2VybmVsIHNoYXBlIHRvIGNvdmVyIHRoZSBpbnB1dCBkaW1zXG4gICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgICAgaWYgKGRpbSA+PSBrZXJuZWxTaGFwZS5sZW5ndGgpIHtcbiAgICAgICAgICBrZXJuZWxTaGFwZS5wdXNoKGlucHV0RGltc1tkaW0gKyAyXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAga2VybmVsU2hhcGVbZGltXSA9IGlucHV0RGltc1tkaW0gKyAyXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkanVzdCBzdHJpZGVzIGxlbmd0aCB0byBtYXRjaCBrZXJuZWwgc2hhcGUgbGVuZ3RoXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwga2VybmVsU2hhcGUubGVuZ3RoOyBkaW0rKykge1xuICAgICAgaWYgKGRpbSA8IHN0cmlkZXMubGVuZ3RoKSB7XG4gICAgICAgIGlmIChzdHJpZGVzW2RpbV0gPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdHJpZGVzIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHJpZGVzLnB1c2goMSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYWRqdXN0IGRpbGF0aW9uIHZhbHVlXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwga2VybmVsU2hhcGUubGVuZ3RoOyBkaW0rKykge1xuICAgICAgaWYgKGRpbSA8IGRpbGF0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKGRpbGF0aW9uc1tkaW1dIDwgMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZGlsYXRpb25zIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaWxhdGlvbnMucHVzaCgxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhZGp1c3QgcGFkcyBsZW5ndGggdG8gbWF0Y2ggMiAqIGtlcm5lbCBzaGFwZSBsZW5ndGhcbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBrZXJuZWxTaGFwZS5sZW5ndGggKiAyOyBkaW0rKykge1xuICAgICAgaWYgKGRpbSA8IHBhZHMubGVuZ3RoKSB7XG4gICAgICAgIGlmIChwYWRzW2RpbV0gPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdwYWQgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhZHMucHVzaCgwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzYW5pdHkgY2hlY2tzIGZvciB2YWx1ZXMgaW4ga2VybmVsIHNoYXBlcyBhbmQgcGFkc1xuICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGtlcm5lbFNoYXBlLmxlbmd0aDsgZGltKyspIHtcbiAgICAgIGlmIChrZXJuZWxTaGFwZVtkaW1dIDw9IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdrZXJuZWwgc2hhcGVzIG5lZWQgdG8gYmUgZ3JlYXRlciB0aGFuIDAnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhZHNbZGltXSA+PSBrZXJuZWxTaGFwZVtkaW1dIHx8IHBhZHNbZGltICsga2VybmVsU2hhcGUubGVuZ3RoXSA+PSBrZXJuZWxTaGFwZVtkaW1dKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncGFkcyBzaG91bGQgYmUgc21hbGxlciB0aGFuIGtlcm5lbCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGFkanVzdCBwYWQgdmFsdWVzIGJhc2VkIG9uICdhdXRvUGFkJyBhdHRyaWJ1dGVcbiAgc3RhdGljIGFkanVzdFBhZHNCYXNlZE9uQXV0b1BhZChcbiAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICAgIGF1dG9QYWQ/OiBzdHJpbmcsXG4gICkge1xuICAgIGlmICghYXV0b1BhZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwYWRzLmxlbmd0aCAhPT0gMiAqIChpbnB1dERpbXMubGVuZ3RoIC0gMikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIHBhZHMgc2hvdWxkIGJlIHR3aWNlIHRoZSBsZW5ndGggb2YgZGF0YSBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgaWYgKHN0cmlkZXMubGVuZ3RoICE9PSBpbnB1dERpbXMubGVuZ3RoIC0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggb2Ygc3RyaWRlcyBzaG91bGQgYmUgdGhlIGxlbmd0aCBvZiBkYXRhIGRpbWVuc2lvbnMnKTtcbiAgICB9XG5cbiAgICBpZiAoa2VybmVsU2hhcGUubGVuZ3RoICE9PSBpbnB1dERpbXMubGVuZ3RoIC0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggb2Yga2VybmVsIHNoYXBlcyBzaG91bGQgYmUgdGhlIGxlbmd0aCBvZiBkYXRhIGRpbWVuc2lvbnMnKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgIFBvb2xDb252VXRpbC5hZGp1c3RQYWRBbmRSZXR1cm5TaGFwZShcbiAgICAgICAgaW5wdXREaW1zW2RpbSArIDJdLFxuICAgICAgICBzdHJpZGVzW2RpbV0sXG4gICAgICAgIGRpbGF0aW9uc1tkaW1dLFxuICAgICAgICBrZXJuZWxTaGFwZVtkaW1dLFxuICAgICAgICBwYWRzLFxuICAgICAgICBkaW0sXG4gICAgICAgIGRpbSArIGlucHV0RGltcy5sZW5ndGggLSAyLFxuICAgICAgICBhdXRvUGFkLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBvdXRwdXQgc2hhcGUgZm9yIFBvb2wgb3BzIGJhc2VkIG9uIGlucHV0IGF0dHJpYnV0ZXMuIChTaG91bGQgYmUgdXNlZCBvbmx5IGZvciBQb29sIG9wcylcbiAgICogQHBhcmFtIGlzR2xvYmFsT3BlcmF0b3IgSWYgdHJ1ZSwgcGVyZm9ybSBnbG9iYWwgcG9vbGluZy5cbiAgICogQHBhcmFtIGlucHV0RGltcyBUaGUgaW5wdXQgdGVuc29yIGRpbWVuc2lvbi4gKGlucHV0c1swXS5kaW1zKVxuICAgKiBAcGFyYW0gc3RyaWRlcyBTdHJpZGUgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gZGlsYXRpb25zIERpbGF0aW9uIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGtlcm5lbFNoYXBlIFRoZSBzaXplIG9mIHRoZSBrZXJuZWwgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gcGFkcyBQYWRkaW5nIGZvciB0aGUgYmVnaW5uaW5nIGFuZCBlbmRpbmcgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gYXV0b1BhZCBERVBSRUNBVEVEIGF0dHJpYnV0ZSBzdXBwb3J0ZWQgZm9yIGxlZ2FjeSBtb2RlbHMuIFNwZWNpZmllcyBob3cgdG8gaW1wbGljaXRseSBjYWxjdWxhdGUgcGFkcyBpbiBlYWNoXG4gICAqICAgICBkaW1lbnNpb24uIENhbiB0YWtlIHZhbHVlcyBOT1RTRVQsIFNBTUVfVVBQRVIsIFNBTUVfTE9XRVIsIG9yIFZBTElELlxuICAgKi9cbiAgc3RhdGljIGNvbXB1dGVQb29sT3V0cHV0U2hhcGUoXG4gICAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbixcbiAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHN0cmlkZXM6IG51bWJlcltdLFxuICAgIGRpbGF0aW9uczogbnVtYmVyW10sXG4gICAga2VybmVsU2hhcGU6IG51bWJlcltdLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICAgIGF1dG9QYWQ/OiBzdHJpbmcsXG4gICk6IG51bWJlcltdIHtcbiAgICBpZiAoaW5wdXREaW1zLmxlbmd0aCA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHNoYXBlIG11c3QgYmUgb2Ygc2l6ZSBncmVhdGVyIHRoYW4gMCcpO1xuICAgIH1cblxuICAgIC8vIEFkZCBiYXRjaCBzaXplIGFuZCBudW1iZXIgb2YgY2hhbm5lbHMgb2Ygb3V0cHV0XG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IFtpbnB1dERpbXNbMF0sIGlucHV0RGltc1sxXV07XG5cbiAgICBQb29sQ29udlV0aWwuY29tcHV0ZVNoYXBlSGVscGVyKFxuICAgICAgaXNHbG9iYWxPcGVyYXRvcixcbiAgICAgIGlucHV0RGltcyxcbiAgICAgIG91dHB1dERpbXMsXG4gICAgICBzdHJpZGVzLFxuICAgICAgZGlsYXRpb25zLFxuICAgICAga2VybmVsU2hhcGUsXG4gICAgICBwYWRzLFxuICAgICAgYXV0b1BhZCxcbiAgICApO1xuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSB0aGUgb3V0cHV0IHNoYXBlIGZvciBDb252IG9wIGJhc2VkIG9uIGlucHV0IGF0dHJpYnV0ZXMuIChTaG91bGQgYmUgdXNlZCBvbmx5IGZvciBDb252IG9wKVxuICAgKiBAcGFyYW0gaW5wdXREaW1zIFRoZSBpbnB1dCB0ZW5zb3IgZGltZW5zaW9uLiAoaW5wdXRzWzBdLmRpbXMpXG4gICAqIEBwYXJhbSBmaWx0ZXJEaW1zIFRoZSBmaWx0ZXIgdGVuc29yIGRpbWVuc2lvbi4gKGlucHV0c1sxXS5kaW1zKVxuICAgKiBAcGFyYW0gc3RyaWRlcyBTdHJpZGUgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0ga2VybmVsU2hhcGUgVGhlIHNpemUgb2YgdGhlIGtlcm5lbCBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBwYWRzIFBhZGRpbmcgZm9yIHRoZSBiZWdpbm5pbmcgYW5kIGVuZGluZyBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBhdXRvUGFkIERFUFJFQ0FURUQgYXR0cmlidXRlIHN1cHBvcnRlZCBmb3IgbGVnYWN5IG1vZGVscy4gU3BlY2lmaWVzIGhvdyB0byBpbXBsaWNpdGx5IGNhbGN1bGF0ZSBwYWRzIGluIGVhY2hcbiAgICogICAgIGRpbWVuc2lvbi4gQ2FuIHRha2UgdmFsdWVzIE5PVFNFVCwgU0FNRV9VUFBFUiwgU0FNRV9MT1dFUiwgb3IgVkFMSUQuXG4gICAqL1xuICBzdGF0aWMgY29tcHV0ZUNvbnZPdXRwdXRTaGFwZShcbiAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGZpbHRlckRpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHN0cmlkZXM6IG51bWJlcltdLFxuICAgIGRpbGF0aW9uczogbnVtYmVyW10sXG4gICAga2VybmVsU2hhcGU6IG51bWJlcltdLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICAgIGF1dG9QYWQ/OiBzdHJpbmcsXG4gICk6IG51bWJlcltdIHtcbiAgICBpZiAoaW5wdXREaW1zLmxlbmd0aCA8PSAwIHx8IGZpbHRlckRpbXMubGVuZ3RoIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCB0ZW5zb3IgZGltcyBvciBpbnZhbGlkIGZpbHRlciB0ZW5zb3IgZGltcycpO1xuICAgIH1cblxuICAgIC8vIEFkZCBiYXRjaCBzaXplIGFuZCBudW1iZXIgb2YgY2hhbm5lbHMgb2Ygb3V0cHV0XG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IFtpbnB1dERpbXNbMF0sIGZpbHRlckRpbXNbMF1dO1xuXG4gICAgUG9vbENvbnZVdGlsLmNvbXB1dGVTaGFwZUhlbHBlcihmYWxzZSwgaW5wdXREaW1zLCBvdXRwdXREaW1zLCBzdHJpZGVzLCBkaWxhdGlvbnMsIGtlcm5lbFNoYXBlLCBwYWRzLCBhdXRvUGFkKTtcbiAgICByZXR1cm4gb3V0cHV0RGltcztcbiAgfVxuXG4gIC8vIHdpbGwgY29tcHV0ZSBvdXRwdXQgc2hhcGVzIGZvciBkYXRhIGRpbWVuc2lvbnMgT05MWSAoaS5lLikgbm8gYmF0Y2ggc2l6ZSBhbmQgY2hhbm5lbHNcbiAgLy8gY2FsbGVkIGJ5IGNvbXB1dGVQb29sT3V0cHV0U2hhcGUoKSBhbmQgY29tcHV0ZUNvbnZPdXRwdXRTaGFwZSgpXG4gIC8vIGFkanVzdCBwYWRzIGJhc2VkIG9uICdhdXRvUGFkJyBhdHRyaWJ1dGUgcHJpb3IgdG8gc2hhcGUgY29tcHV0YXRpb25cbiAgcHJpdmF0ZSBzdGF0aWMgY29tcHV0ZVNoYXBlSGVscGVyKFxuICAgIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4gICAgaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBvdXRwdXREaW1zOiBudW1iZXJbXSxcbiAgICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBwYWRzOiBudW1iZXJbXSxcbiAgICBhdXRvUGFkPzogc3RyaW5nLFxuICApIHtcbiAgICBpZiAoaXNHbG9iYWxPcGVyYXRvcikge1xuICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgaW5wdXREaW1zLmxlbmd0aCAtIDI7IGRpbSsrKSB7XG4gICAgICAgIG91dHB1dERpbXMucHVzaCgxKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgaW5wdXREaW1zLmxlbmd0aCAtIDI7IGRpbSsrKSB7XG4gICAgICAgIG91dHB1dERpbXMucHVzaChcbiAgICAgICAgICBQb29sQ29udlV0aWwuYWRqdXN0UGFkQW5kUmV0dXJuU2hhcGUoXG4gICAgICAgICAgICBpbnB1dERpbXNbZGltICsgMl0sXG4gICAgICAgICAgICBzdHJpZGVzW2RpbV0sXG4gICAgICAgICAgICBkaWxhdGlvbnNbZGltXSxcbiAgICAgICAgICAgIGtlcm5lbFNoYXBlW2RpbV0sXG4gICAgICAgICAgICBwYWRzLFxuICAgICAgICAgICAgZGltLFxuICAgICAgICAgICAgZGltICsgaW5wdXREaW1zLmxlbmd0aCAtIDIsXG4gICAgICAgICAgICBhdXRvUGFkLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gaGVscGVyIGZvciBjb21wdXRlU2hhcGVIZWxwZXIoKSBhbmQgYWRqdXN0UGFkc0Jhc2VkT25BdXRvUGFkKClcbiAgLy8gYWRqdXN0cyBwYWQgdmFsdWUgZm9yIGdpdmVuICdhdXRvUGFkJyBzdHJpbmcgYW5kIGNvbXB1dGVzIG91dHB1dCBzaGFwZSBhbG9uZyBhIHBhcnRpY3VsYXIgZGltZW5zaW9uXG4gIHByaXZhdGUgc3RhdGljIGFkanVzdFBhZEFuZFJldHVyblNoYXBlKFxuICAgIGluU2l6ZTogbnVtYmVyLFxuICAgIHN0cmlkZTogbnVtYmVyLFxuICAgIGRpbGF0aW9uOiBudW1iZXIsXG4gICAga2VybmVsOiBudW1iZXIsXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgcGFkSGVhZEluZGV4OiBudW1iZXIsXG4gICAgcGFkVGFpbEluZGV4OiBudW1iZXIsXG4gICAgYXV0b1BhZD86IHN0cmluZyxcbiAgKTogbnVtYmVyIHtcbiAgICBjb25zdCBka2VybmVsID0gZGlsYXRpb24gKiAoa2VybmVsIC0gMSkgKyAxO1xuICAgIGlmIChhdXRvUGFkICYmIGF1dG9QYWQgIT09ICdOT1RTRVQnKSB7XG4gICAgICBzd2l0Y2ggKGF1dG9QYWQpIHtcbiAgICAgICAgY2FzZSAnVkFMSUQnOlxuICAgICAgICAgIHBhZHNbcGFkSGVhZEluZGV4XSA9IDA7XG4gICAgICAgICAgcGFkc1twYWRUYWlsSW5kZXhdID0gMDtcbiAgICAgICAgICByZXR1cm4gTWF0aC5mbG9vcigoaW5TaXplIC0gZGtlcm5lbCkgLyBzdHJpZGUgKyAxKTtcbiAgICAgICAgY2FzZSAnU0FNRV9MT1dFUic6XG4gICAgICAgIGNhc2UgJ1NBTUVfVVBQRVInOlxuICAgICAgICAgIGlmIChkaWxhdGlvbiAhPT0gMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEaWxhdGlvbiBub3Qgc3VwcG9ydGVkIGZvciBTQU1FX1VQUEVSIG9yIFNBTUVfTE9XRVInKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgbGVnYWN5VGFyZ2V0U2l6ZSA9IChpblNpemUgKyBzdHJpZGUgLSAxKSAvIHN0cmlkZTtcbiAgICAgICAgICAgIGNvbnN0IHBhZE5lZWRlZCA9IChsZWdhY3lUYXJnZXRTaXplIC0gMSkgKiBzdHJpZGUgKyBrZXJuZWwgLSBpblNpemU7XG4gICAgICAgICAgICBwYWRzW3BhZEhlYWRJbmRleF0gPSBhdXRvUGFkID09PSAnU0FNRV9MT1dFUicgPyBNYXRoLmZsb29yKChwYWROZWVkZWQgKyAxKSAvIDIpIDogTWF0aC5mbG9vcihwYWROZWVkZWQgLyAyKTtcbiAgICAgICAgICAgIHBhZHNbcGFkVGFpbEluZGV4XSA9IHBhZE5lZWRlZCAtIHBhZHNbcGFkSGVhZEluZGV4XTtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKChpblNpemUgKyBwYWROZWVkZWQgLSBrZXJuZWwpIC8gc3RyaWRlICsgMSk7XG4gICAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgQXV0b1BhZCB0eXBlJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBNYXRoLmZsb29yKChpblNpemUgKyBwYWRzW3BhZEhlYWRJbmRleF0gKyBwYWRzW3BhZFRhaWxJbmRleF0gLSBka2VybmVsKSAvIHN0cmlkZSArIDEpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgTUlOX0NMSVAgPSAtMy40MDI4MjM0NjYzODUyODg2ZTM4O1xuZXhwb3J0IGNvbnN0IE1BWF9DTElQID0gMy40MDI4MjM0NjYzODUyODg2ZTM4O1xuXG5leHBvcnQgZnVuY3Rpb24gZGVjb2RlVXRmOFN0cmluZyhidWZmZXI6IFVpbnQ4QXJyYXkpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKGJ1ZmZlcik7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEd1aWQgfSBmcm9tICdndWlkLXR5cGVzY3JpcHQnO1xuaW1wb3J0IExvbmcgZnJvbSAnbG9uZyc7XG5cbmltcG9ydCAqIGFzIG9ydEZicyBmcm9tICcuL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQgeyBvbm54IH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHsgZGVjb2RlVXRmOFN0cmluZywgUHJvdG9VdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgVGVuc29yIHtcbiAgZXhwb3J0IGludGVyZmFjZSBEYXRhVHlwZU1hcCB7XG4gICAgYm9vbDogVWludDhBcnJheTtcbiAgICBmbG9hdDMyOiBGbG9hdDMyQXJyYXk7XG4gICAgZmxvYXQ2NDogRmxvYXQ2NEFycmF5O1xuICAgIHN0cmluZzogc3RyaW5nW107XG4gICAgaW50ODogSW50OEFycmF5O1xuICAgIHVpbnQ4OiBVaW50OEFycmF5O1xuICAgIGludDE2OiBJbnQxNkFycmF5O1xuICAgIHVpbnQxNjogVWludDE2QXJyYXk7XG4gICAgaW50MzI6IEludDMyQXJyYXk7XG4gICAgdWludDMyOiBVaW50MzJBcnJheTtcbiAgICBpbnQ2NDogQmlnSW50NjRBcnJheTtcbiAgfVxuXG4gIGV4cG9ydCB0eXBlIERhdGFUeXBlID0ga2V5b2YgRGF0YVR5cGVNYXA7XG5cbiAgZXhwb3J0IHR5cGUgU3RyaW5nVHlwZSA9IFRlbnNvci5EYXRhVHlwZU1hcFsnc3RyaW5nJ107XG4gIGV4cG9ydCB0eXBlIEJvb2xlYW5UeXBlID0gVGVuc29yLkRhdGFUeXBlTWFwWydib29sJ107XG4gIGV4cG9ydCB0eXBlIEludGVnZXJUeXBlID1cbiAgICB8IFRlbnNvci5EYXRhVHlwZU1hcFsnaW50OCddXG4gICAgfCBUZW5zb3IuRGF0YVR5cGVNYXBbJ3VpbnQ4J11cbiAgICB8IFRlbnNvci5EYXRhVHlwZU1hcFsnaW50MTYnXVxuICAgIHwgVGVuc29yLkRhdGFUeXBlTWFwWyd1aW50MTYnXVxuICAgIHwgVGVuc29yLkRhdGFUeXBlTWFwWydpbnQzMiddXG4gICAgfCBUZW5zb3IuRGF0YVR5cGVNYXBbJ3VpbnQzMiddO1xuICBleHBvcnQgdHlwZSBGbG9hdFR5cGUgPSBUZW5zb3IuRGF0YVR5cGVNYXBbJ2Zsb2F0MzInXSB8IFRlbnNvci5EYXRhVHlwZU1hcFsnZmxvYXQ2NCddO1xuICBleHBvcnQgdHlwZSBOdW1iZXJUeXBlID0gQm9vbGVhblR5cGUgfCBJbnRlZ2VyVHlwZSB8IEZsb2F0VHlwZTtcblxuICBleHBvcnQgdHlwZSBJZCA9IEd1aWQ7XG59XG5cbnR5cGUgVGVuc29yRGF0YSA9IFRlbnNvci5EYXRhVHlwZU1hcFtUZW5zb3IuRGF0YVR5cGVdO1xuXG50eXBlIERhdGFQcm92aWRlciA9IChpZDogVGVuc29yLklkKSA9PiBUZW5zb3JEYXRhO1xudHlwZSBBc3luY0RhdGFQcm92aWRlciA9IChpZDogVGVuc29yLklkKSA9PiBQcm9taXNlPFRlbnNvckRhdGE+O1xuXG5leHBvcnQgY2xhc3MgVGVuc29yIHtcbiAgLyoqXG4gICAqIGdldCB0aGUgdW5kZXJseWluZyB0ZW5zb3IgZGF0YVxuICAgKi9cbiAgZ2V0IGRhdGEoKTogVGVuc29yRGF0YSB7XG4gICAgaWYgKHRoaXMuY2FjaGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZGF0YVByb3ZpZGVyISh0aGlzLmRhdGFJZCk7XG4gICAgICBpZiAoZGF0YS5sZW5ndGggIT09IHRoaXMuc2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0xlbmd0aCBvZiBkYXRhIHByb3ZpZGVkIGJ5IHRoZSBEYXRhIFByb3ZpZGVyIGlzIGluY29uc2lzdGVudCB3aXRoIHRoZSBkaW1zIG9mIHRoaXMgVGVuc29yLicpO1xuICAgICAgfVxuICAgICAgdGhpcy5jYWNoZSA9IGRhdGE7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNhY2hlO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgdW5kZXJseWluZyBzdHJpbmcgdGVuc29yIGRhdGEuIFNob3VsZCBvbmx5IHVzZSB3aGVuIHR5cGUgaXMgU1RSSU5HXG4gICAqL1xuICBnZXQgc3RyaW5nRGF0YSgpIHtcbiAgICBpZiAodGhpcy50eXBlICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZGF0YSB0eXBlIGlzIG5vdCBzdHJpbmcnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5kYXRhIGFzIFRlbnNvci5TdHJpbmdUeXBlO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgdW5kZXJseWluZyBpbnRlZ2VyIHRlbnNvciBkYXRhLiBTaG91bGQgb25seSB1c2Ugd2hlbiB0eXBlIGlzIG9uZSBvZiB0aGUgZm9sbG93aW5nOiAoVUlOVDgsIElOVDgsIFVJTlQxNixcbiAgICogSU5UMTYsIElOVDMyLCBVSU5UMzIsIEJPT0wpXG4gICAqL1xuICBnZXQgaW50ZWdlckRhdGEoKSB7XG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgIGNhc2UgJ2ludDgnOlxuICAgICAgY2FzZSAndWludDE2JzpcbiAgICAgIGNhc2UgJ2ludDE2JzpcbiAgICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgICBjYXNlICdib29sJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YSBhcyBUZW5zb3IuSW50ZWdlclR5cGU7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2RhdGEgdHlwZSBpcyBub3QgaW50ZWdlciAodWludDgsIGludDgsIHVpbnQxNiwgaW50MTYsIGludDMyLCB1aW50MzIsIGJvb2wpJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgdW5kZXJseWluZyBmbG9hdCB0ZW5zb3IgZGF0YS4gU2hvdWxkIG9ubHkgdXNlIHdoZW4gdHlwZSBpcyBvbmUgb2YgdGhlIGZvbGxvd2luZzogKEZMT0FULCBET1VCTEUpXG4gICAqL1xuICBnZXQgZmxvYXREYXRhKCkge1xuICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhIGFzIFRlbnNvci5GbG9hdFR5cGU7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2RhdGEgdHlwZSBpcyBub3QgZmxvYXQgKGZsb2F0MzIsIGZsb2F0NjQpJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgdW5kZXJseWluZyBudW1iZXIgdGVuc29yIGRhdGEuIFNob3VsZCBvbmx5IHVzZSB3aGVuIHR5cGUgaXMgb25lIG9mIHRoZSBmb2xsb3dpbmc6IChVSU5UOCwgSU5UOCwgVUlOVDE2LFxuICAgKiBJTlQxNiwgSU5UMzIsIFVJTlQzMiwgQk9PTCwgRkxPQVQsIERPVUJMRSlcbiAgICovXG4gIGdldCBudW1iZXJEYXRhKCkge1xuICAgIGlmICh0aGlzLnR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gdGhpcy5kYXRhIGFzIFRlbnNvci5OdW1iZXJUeXBlO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0eXBlIGNhbm5vdCBiZSBub24tbnVtYmVyIChzdHJpbmcpJyk7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHZhbHVlIG9mIGFuIGVsZW1lbnQgYXQgdGhlIGdpdmVuIGluZGljZXNcbiAgICovXG4gIGdldChpbmRpY2VzOiByZWFkb25seSBudW1iZXJbXSk6IFRlbnNvci5EYXRhVHlwZU1hcFtUZW5zb3IuRGF0YVR5cGVdW251bWJlcl0ge1xuICAgIHJldHVybiB0aGlzLmRhdGFbU2hhcGVVdGlsLmluZGljZXNUb09mZnNldChpbmRpY2VzLCB0aGlzLnN0cmlkZXMpXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBzZXQgdmFsdWUgb2YgYW4gZWxlbWVudCBhdCB0aGUgZ2l2ZW4gaW5kaWNlc1xuICAgKi9cbiAgc2V0KGluZGljZXM6IHJlYWRvbmx5IG51bWJlcltdLCB2YWx1ZTogVGVuc29yLkRhdGFUeXBlTWFwW1RlbnNvci5EYXRhVHlwZV1bbnVtYmVyXSkge1xuICAgIHRoaXMuZGF0YVtTaGFwZVV0aWwuaW5kaWNlc1RvT2Zmc2V0KGluZGljZXMsIHRoaXMuc3RyaWRlcyldID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSB1bmRlcmx5aW5nIHRlbnNvciBkYXRhIGFzeW5jaHJvbm91c2x5XG4gICAqL1xuICBhc3luYyBnZXREYXRhKCk6IFByb21pc2U8VGVuc29yRGF0YT4ge1xuICAgIGlmICh0aGlzLmNhY2hlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuY2FjaGUgPSBhd2FpdCB0aGlzLmFzeW5jRGF0YVByb3ZpZGVyISh0aGlzLmRhdGFJZCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNhY2hlO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSB0ZW5zb3JcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzaXplOiBudW1iZXI7XG5cbiAgcHJpdmF0ZSBfc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW107XG4gIC8qKlxuICAgKiBnZXQgdGhlIHN0cmlkZXMgZm9yIGVhY2ggZGltZW5zaW9uXG4gICAqL1xuICBnZXQgc3RyaWRlcygpOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgaWYgKCF0aGlzLl9zdHJpZGVzKSB7XG4gICAgICB0aGlzLl9zdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKHRoaXMuZGltcyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9zdHJpZGVzO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgICogZ2V0IHRoZSBkaW1lbnNpb25zIG9mIHRoZSB0ZW5zb3JcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgZGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgLyoqXG4gICAgICogZ2V0IHRoZSB0eXBlIG9mIHRoZSB0ZW5zb3JcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdHlwZTogVGVuc29yLkRhdGFUeXBlLFxuICAgIHByaXZhdGUgZGF0YVByb3ZpZGVyPzogRGF0YVByb3ZpZGVyLFxuICAgIHByaXZhdGUgYXN5bmNEYXRhUHJvdmlkZXI/OiBBc3luY0RhdGFQcm92aWRlcixcbiAgICBwcml2YXRlIGNhY2hlPzogVGVuc29yRGF0YSxcbiAgICAvKipcbiAgICAgKiBnZXQgdGhlIGRhdGEgSUQgdGhhdCB1c2VkIHRvIG1hcCB0byBhIHRlbnNvciBkYXRhXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGRhdGFJZDogR3VpZCA9IEd1aWQuY3JlYXRlKCksXG4gICkge1xuICAgIHRoaXMuc2l6ZSA9IFNoYXBlVXRpbC52YWxpZGF0ZURpbXNBbmRDYWxjU2l6ZShkaW1zKTtcbiAgICBjb25zdCBzaXplID0gdGhpcy5zaXplO1xuICAgIGNvbnN0IGVtcHR5ID0gZGF0YVByb3ZpZGVyID09PSB1bmRlZmluZWQgJiYgYXN5bmNEYXRhUHJvdmlkZXIgPT09IHVuZGVmaW5lZCAmJiBjYWNoZSA9PT0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKGNhY2hlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChjYWNoZS5sZW5ndGggIT09IHNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnB1dCBkaW1zIGRvZXNuJ3QgbWF0Y2ggZGF0YSBsZW5ndGguXCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKGNhY2hlICE9PSB1bmRlZmluZWQgJiYgKCFBcnJheS5pc0FycmF5KGNhY2hlKSB8fCAhY2FjaGUuZXZlcnkoKGkpID0+IHR5cGVvZiBpID09PSAnc3RyaW5nJykpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2NhY2hlIHNob3VsZCBiZSBhIHN0cmluZyBhcnJheScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZW1wdHkpIHtcbiAgICAgICAgdGhpcy5jYWNoZSA9IG5ldyBBcnJheTxzdHJpbmc+KHNpemUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoY2FjaGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCBjb25zdHJ1Y3RvciA9IGRhdGF2aWV3Q29uc3RydWN0b3IodHlwZSk7XG4gICAgICAgIGlmICghKGNhY2hlIGluc3RhbmNlb2YgY29uc3RydWN0b3IpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgY2FjaGUgc2hvdWxkIGJlIHR5cGUgJHtjb25zdHJ1Y3Rvci5uYW1lfWApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChlbXB0eSkge1xuICAgICAgICBjb25zdCBidWYgPSBuZXcgQXJyYXlCdWZmZXIoc2l6ZSAqIHNpemVvZih0eXBlKSk7XG4gICAgICAgIHRoaXMuY2FjaGUgPSBjcmVhdGVWaWV3KGJ1ZiwgdHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBuZXcgVGVuc29yIGZyb20gYSBPTk5YIFRlbnNvciBvYmplY3RcbiAgICogQHBhcmFtIHRlbnNvclByb3RvIHRoZSBPTk5YIFRlbnNvclxuICAgKi9cbiAgc3RhdGljIGZyb21Qcm90byh0ZW5zb3JQcm90bzogb25ueC5JVGVuc29yUHJvdG8pOiBUZW5zb3Ige1xuICAgIGlmICghdGVuc29yUHJvdG8pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGNvbnN0cnVjdCBWYWx1ZSBmcm9tIGFuIGVtcHR5IHRlbnNvcicpO1xuICAgIH1cbiAgICBjb25zdCB0eXBlID0gUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKHRlbnNvclByb3RvLmRhdGFUeXBlISk7XG4gICAgY29uc3QgZGltcyA9IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbVByb3RvKHRlbnNvclByb3RvLmRpbXMhKTtcblxuICAgIGNvbnN0IHZhbHVlID0gbmV3IFRlbnNvcihkaW1zLCB0eXBlKTtcblxuICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gV2hlbiBpdCdzIFNUUklORyB0eXBlLCB0aGUgdmFsdWUgc2hvdWxkIGFsd2F5cyBiZSBzdG9yZWQgaW4gZmllbGRcbiAgICAgIC8vICdzdHJpbmdEYXRhJ1xuICAgICAgdGVuc29yUHJvdG8uc3RyaW5nRGF0YSEuZm9yRWFjaCgoc3RyLCBpKSA9PiB7XG4gICAgICAgIHZhbHVlLmRhdGFbaV0gPSBkZWNvZGVVdGY4U3RyaW5nKHN0cik7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdGVuc29yUHJvdG8ucmF3RGF0YSAmJlxuICAgICAgdHlwZW9mIHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZUxlbmd0aCA9PT0gJ251bWJlcicgJiZcbiAgICAgIHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZUxlbmd0aCA+IDBcbiAgICApIHtcbiAgICAgIC8vIE5PVCBjb25zaWRlcmluZyBzZWdtZW50IGZvciBub3cgKElNUE9SVEFOVClcblxuICAgICAgLy8gcG9wdWxhdGUgdmFsdWUgZnJvbSByYXdEYXRhXG4gICAgICBjb25zdCBkYXRhRGVzdCA9IHZhbHVlLmRhdGE7XG4gICAgICBjb25zdCBkYXRhU291cmNlID0gbmV3IERhdGFWaWV3KFxuICAgICAgICB0ZW5zb3JQcm90by5yYXdEYXRhLmJ1ZmZlcixcbiAgICAgICAgdGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlT2Zmc2V0LFxuICAgICAgICB0ZW5zb3JQcm90by5yYXdEYXRhLmJ5dGVMZW5ndGgsXG4gICAgICApO1xuICAgICAgY29uc3QgZWxlbWVudFNpemUgPSBzaXplb2ZQcm90byh0ZW5zb3JQcm90by5kYXRhVHlwZSEpO1xuICAgICAgY29uc3QgbGVuZ3RoID0gdGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlTGVuZ3RoIC8gZWxlbWVudFNpemU7XG5cbiAgICAgIGlmICh0ZW5zb3JQcm90by5yYXdEYXRhLmJ5dGVMZW5ndGggJSBlbGVtZW50U2l6ZSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYnVmZmVyIGxlbmd0aCcpO1xuICAgICAgfVxuICAgICAgaWYgKGRhdGFEZXN0Lmxlbmd0aCAhPT0gbGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYnVmZmVyIGxlbmd0aCBtaXNtYXRjaCcpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG4gPSByZWFkUHJvdG8oZGF0YVNvdXJjZSwgdGVuc29yUHJvdG8uZGF0YVR5cGUhLCBpICogZWxlbWVudFNpemUpO1xuICAgICAgICBkYXRhRGVzdFtpXSA9IG47XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHBvcHVsYXRlIHZhbHVlIGZyb20gYXJyYXlcbiAgICAgIGxldCBhcnJheTogQXJyYXk8bnVtYmVyIHwgTG9uZz47XG4gICAgICBzd2l0Y2ggKHRlbnNvclByb3RvLmRhdGFUeXBlKSB7XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDpcbiAgICAgICAgICBhcnJheSA9IHRlbnNvclByb3RvLmZsb2F0RGF0YSE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDE2OlxuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDE2OlxuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UODpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ4OlxuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuQk9PTDpcbiAgICAgICAgICBhcnJheSA9IHRlbnNvclByb3RvLmludDMyRGF0YSE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ2NDpcbiAgICAgICAgICBhcnJheSA9IHRlbnNvclByb3RvLmludDY0RGF0YSE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5ET1VCTEU6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by5kb3VibGVEYXRhITtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQzMjpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDpcbiAgICAgICAgICBhcnJheSA9IHRlbnNvclByb3RvLnVpbnQ2NERhdGEhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8vIHNob3VsZCBuZXZlciBydW4gaGVyZVxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndW5zcGVjaWZpYyBlcnJvcicpO1xuICAgICAgfVxuXG4gICAgICBpZiAoYXJyYXkgPT09IG51bGwgfHwgYXJyYXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZhaWxlZCB0byBwb3B1bGF0ZSBkYXRhIGZyb20gYSB0ZW5zb3Jwcm90byB2YWx1ZScpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkYXRhID0gdmFsdWUuZGF0YTtcbiAgICAgIGlmIChkYXRhLmxlbmd0aCAhPT0gYXJyYXkubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYXJyYXkgbGVuZ3RoIG1pc21hdGNoJyk7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGFycmF5W2ldO1xuICAgICAgICBpZiAoTG9uZy5pc0xvbmcoZWxlbWVudCkpIHtcbiAgICAgICAgICBkYXRhW2ldID0gbG9uZ1RvTnVtYmVyKGVsZW1lbnQsIHRlbnNvclByb3RvLmRhdGFUeXBlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkYXRhW2ldID0gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgbmV3IFRlbnNvciBmcm9tIHJhdyBkYXRhXG4gICAqIEBwYXJhbSBkYXRhIHRoZSByYXcgZGF0YSBvYmplY3QuIFNob3VsZCBiZSBhIHN0cmluZyBhcnJheSBmb3IgJ3N0cmluZycgdGVuc29yLCBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgdHlwZWQgYXJyYXlcbiAgICogZm9yIG90aGVyIHR5cGVzIG9mIHRlbnNvci5cbiAgICogQHBhcmFtIGRpbXMgdGhlIGRpbWVuc2lvbnMgb2YgdGhlIHRlbnNvclxuICAgKiBAcGFyYW0gdHlwZSB0aGUgdHlwZSBvZiB0aGUgdGVuc29yXG4gICAqL1xuICBzdGF0aWMgZnJvbURhdGEoZGF0YTogVGVuc29yLkRhdGFUeXBlTWFwW1RlbnNvci5EYXRhVHlwZV0sIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCB0eXBlOiBUZW5zb3IuRGF0YVR5cGUpIHtcbiAgICByZXR1cm4gbmV3IFRlbnNvcihkaW1zLCB0eXBlLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgZGF0YSk7XG4gIH1cblxuICBzdGF0aWMgZnJvbU9ydFRlbnNvcihvcnRUZW5zb3I6IG9ydEZicy5UZW5zb3IpIHtcbiAgICBpZiAoIW9ydFRlbnNvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3QgY29uc3RydWN0IFZhbHVlIGZyb20gYW4gZW1wdHkgdGVuc29yJyk7XG4gICAgfVxuICAgIGNvbnN0IGRpbXMgPSBQcm90b1V0aWwudGVuc29yRGltc0Zyb21PUlRGb3JtYXQob3J0VGVuc29yKTtcbiAgICBjb25zdCB0eXBlID0gUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKG9ydFRlbnNvci5kYXRhVHlwZSgpKTtcblxuICAgIGNvbnN0IHZhbHVlID0gbmV3IFRlbnNvcihkaW1zLCB0eXBlKTtcblxuICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gV2hlbiBpdCdzIFNUUklORyB0eXBlLCB0aGUgdmFsdWUgc2hvdWxkIGFsd2F5cyBiZSBzdG9yZWQgaW4gZmllbGRcbiAgICAgIC8vICdzdHJpbmdEYXRhJ1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcnRUZW5zb3Iuc3RyaW5nRGF0YUxlbmd0aCgpOyBpKyspIHtcbiAgICAgICAgdmFsdWUuZGF0YVtpXSA9IG9ydFRlbnNvci5zdHJpbmdEYXRhKGkpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoXG4gICAgICBvcnRUZW5zb3IucmF3RGF0YUFycmF5KCkgJiZcbiAgICAgIHR5cGVvZiBvcnRUZW5zb3IucmF3RGF0YUxlbmd0aCgpID09PSAnbnVtYmVyJyAmJlxuICAgICAgb3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSA+IDBcbiAgICApIHtcbiAgICAgIC8vIE5PVCBjb25zaWRlcmluZyBzZWdtZW50IGZvciBub3cgKElNUE9SVEFOVClcblxuICAgICAgLy8gcG9wdWxhdGUgdmFsdWUgZnJvbSByYXdEYXRhXG4gICAgICBjb25zdCBkYXRhRGVzdCA9IHZhbHVlLmRhdGE7XG4gICAgICBjb25zdCBkYXRhU291cmNlID0gbmV3IERhdGFWaWV3KFxuICAgICAgICBvcnRUZW5zb3IucmF3RGF0YUFycmF5KCkhLmJ1ZmZlcixcbiAgICAgICAgb3J0VGVuc29yLnJhd0RhdGFBcnJheSgpIS5ieXRlT2Zmc2V0LFxuICAgICAgICBvcnRUZW5zb3IucmF3RGF0YUxlbmd0aCgpLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGVsZW1lbnRTaXplID0gc2l6ZW9mUHJvdG8ob3J0VGVuc29yLmRhdGFUeXBlKCkpO1xuICAgICAgY29uc3QgbGVuZ3RoID0gb3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSAvIGVsZW1lbnRTaXplO1xuXG4gICAgICBpZiAob3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSAlIGVsZW1lbnRTaXplICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBidWZmZXIgbGVuZ3RoJyk7XG4gICAgICB9XG4gICAgICBpZiAoZGF0YURlc3QubGVuZ3RoICE9PSBsZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdidWZmZXIgbGVuZ3RoIG1pc21hdGNoJyk7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgbiA9IHJlYWRQcm90byhkYXRhU291cmNlLCBvcnRUZW5zb3IuZGF0YVR5cGUoKSwgaSAqIGVsZW1lbnRTaXplKTtcbiAgICAgICAgZGF0YURlc3RbaV0gPSBuO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2l6ZW9mKHR5cGU6IFRlbnNvci5EYXRhVHlwZSk6IG51bWJlciB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ2Jvb2wnOlxuICAgIGNhc2UgJ2ludDgnOlxuICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgIHJldHVybiAxO1xuICAgIGNhc2UgJ2ludDE2JzpcbiAgICBjYXNlICd1aW50MTYnOlxuICAgICAgcmV0dXJuIDI7XG4gICAgY2FzZSAnaW50MzInOlxuICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICByZXR1cm4gNDtcbiAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgIHJldHVybiA4O1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCBjYWxjdWxhdGUgc2l6ZW9mKCkgb24gdHlwZSAke3R5cGV9YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2l6ZW9mUHJvdG8odHlwZTogb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZSB8IG9ydEZicy5UZW5zb3JEYXRhVHlwZSk6IG51bWJlciB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UODpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UODpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuQk9PTDpcbiAgICAgIHJldHVybiAxO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMTY6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDE2OlxuICAgICAgcmV0dXJuIDI7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkZMT0FUOlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDMyOlxuICAgICAgcmV0dXJuIDQ7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0OlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5ET1VCTEU6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDpcbiAgICAgIHJldHVybiA4O1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCBjYWxjdWxhdGUgc2l6ZW9mKCkgb24gdHlwZSAke29ubnguVGVuc29yUHJvdG8uRGF0YVR5cGVbdHlwZV19YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlVmlldyhkYXRhQnVmZmVyOiBBcnJheUJ1ZmZlciwgdHlwZTogVGVuc29yLkRhdGFUeXBlKSB7XG4gIHJldHVybiBuZXcgKGRhdGF2aWV3Q29uc3RydWN0b3IodHlwZSkpKGRhdGFCdWZmZXIpO1xufVxuXG5mdW5jdGlvbiBkYXRhdmlld0NvbnN0cnVjdG9yKHR5cGU6IFRlbnNvci5EYXRhVHlwZSkge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdib29sJzpcbiAgICBjYXNlICd1aW50OCc6XG4gICAgICByZXR1cm4gVWludDhBcnJheTtcbiAgICBjYXNlICdpbnQ4JzpcbiAgICAgIHJldHVybiBJbnQ4QXJyYXk7XG4gICAgY2FzZSAnaW50MTYnOlxuICAgICAgcmV0dXJuIEludDE2QXJyYXk7XG4gICAgY2FzZSAndWludDE2JzpcbiAgICAgIHJldHVybiBVaW50MTZBcnJheTtcbiAgICBjYXNlICdpbnQzMic6XG4gICAgICByZXR1cm4gSW50MzJBcnJheTtcbiAgICBjYXNlICd1aW50MzInOlxuICAgICAgcmV0dXJuIFVpbnQzMkFycmF5O1xuICAgIGNhc2UgJ2ludDY0JzpcbiAgICAgIHJldHVybiBCaWdJbnQ2NEFycmF5O1xuICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgcmV0dXJuIEZsb2F0MzJBcnJheTtcbiAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgIHJldHVybiBGbG9hdDY0QXJyYXk7XG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIHNob3VsZCBuZXZlciBydW4gdG8gaGVyZVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bnNwZWNpZmllZCBlcnJvcicpO1xuICB9XG59XG5cbi8vIGNvbnZlcnQgYSBsb25nIG51bWJlciB0byBhIDMyLWJpdCBpbnRlZ2VyIChjYXN0LWRvd24pXG5mdW5jdGlvbiBsb25nVG9OdW1iZXIoaTogTG9uZywgdHlwZTogb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZSB8IG9ydEZicy5UZW5zb3JEYXRhVHlwZSk6IG51bWJlciB7XG4gIC8vIElOVDY0LCBVSU5UMzIsIFVJTlQ2NFxuICBpZiAodHlwZSA9PT0gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ2NCB8fCB0eXBlID09PSBvcnRGYnMuVGVuc29yRGF0YVR5cGUuSU5UNjQpIHtcbiAgICBpZiAoaS5ncmVhdGVyVGhhbk9yRXF1YWwoMjE0NzQ4MzY0OCkgfHwgaS5sZXNzVGhhbigtMjE0NzQ4MzY0OCkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludDY0IGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoXG4gICAgdHlwZSA9PT0gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzIgfHxcbiAgICB0eXBlID09PSBvcnRGYnMuVGVuc29yRGF0YVR5cGUuVUlOVDMyIHx8XG4gICAgdHlwZSA9PT0gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQgfHxcbiAgICB0eXBlID09PSBvcnRGYnMuVGVuc29yRGF0YVR5cGUuVUlOVDY0XG4gICkge1xuICAgIGlmIChpLmdyZWF0ZXJUaGFuT3JFcXVhbCg0Mjk0OTY3Mjk2KSB8fCBpLmxlc3NUaGFuKDApKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd1aW50NjQgaXMgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBub3QgYSBMT05HIHR5cGU6ICR7b25ueC5UZW5zb3JQcm90by5EYXRhVHlwZVt0eXBlXX1gKTtcbiAgfVxuXG4gIHJldHVybiBpLnRvTnVtYmVyKCk7XG59XG5cbi8vIHJlYWQgb25lIHZhbHVlIGZyb20gVGVuc29yUHJvdG9cbmZ1bmN0aW9uIHJlYWRQcm90byhcbiAgdmlldzogRGF0YVZpZXcsXG4gIHR5cGU6IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUgfCBvcnRGYnMuVGVuc29yRGF0YVR5cGUsXG4gIGJ5dGVPZmZzZXQ6IG51bWJlcixcbik6IG51bWJlciB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5CT09MOlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UODpcbiAgICAgIHJldHVybiB2aWV3LmdldFVpbnQ4KGJ5dGVPZmZzZXQpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ4OlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0SW50OChieXRlT2Zmc2V0KTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDE2OlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0VWludDE2KGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQxNjpcbiAgICAgIHJldHVybiB2aWV3LmdldEludDE2KGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDpcbiAgICAgIHJldHVybiB2aWV3LmdldEZsb2F0MzIoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDMyOlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0SW50MzIoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQzMjpcbiAgICAgIHJldHVybiB2aWV3LmdldFVpbnQzMihieXRlT2Zmc2V0LCB0cnVlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQ6XG4gICAgICByZXR1cm4gbG9uZ1RvTnVtYmVyKFxuICAgICAgICBMb25nLmZyb21CaXRzKHZpZXcuZ2V0VWludDMyKGJ5dGVPZmZzZXQsIHRydWUpLCB2aWV3LmdldFVpbnQzMihieXRlT2Zmc2V0ICsgNCwgdHJ1ZSksIGZhbHNlKSxcbiAgICAgICAgdHlwZSxcbiAgICAgICk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkRPVUJMRTpcbiAgICAgIHJldHVybiB2aWV3LmdldEZsb2F0NjQoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDpcbiAgICAgIHJldHVybiBsb25nVG9OdW1iZXIoXG4gICAgICAgIExvbmcuZnJvbUJpdHModmlldy5nZXRVaW50MzIoYnl0ZU9mZnNldCwgdHJ1ZSksIHZpZXcuZ2V0VWludDMyKGJ5dGVPZmZzZXQgKyA0LCB0cnVlKSwgdHJ1ZSksXG4gICAgICAgIHR5cGUsXG4gICAgICApO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCByZWFkIGZyb20gRGF0YVZpZXcgZm9yIHR5cGUgJHtvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlW3R5cGVdfWApO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8qKlxuICogcmVwcmVzZW50IGEgdmVyc2lvbiBpcnJlbGV2YW50IGFic3RyYWN0aW9uIG9mIGZvciBHTFNMIHNvdXJjZSBjb2RlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR2xzbCB7XG4gIHJlYWRvbmx5IHZlcnNpb246IHN0cmluZztcbiAgcmVhZG9ubHkgYXR0cmlidXRlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZhcnlpbmdWZXJ0ZXg6IHN0cmluZztcbiAgcmVhZG9ubHkgdmFyeWluZ0ZyYWc6IHN0cmluZztcbiAgcmVhZG9ubHkgdGV4dHVyZTJEOiBzdHJpbmc7XG4gIHJlYWRvbmx5IG91dHB1dDogc3RyaW5nO1xuICByZWFkb25seSBvdXRwdXREZWNsYXJhdGlvbjogc3RyaW5nO1xufVxuXG5jb25zdCBHTFNMX0VTXzJfMDogR2xzbCA9IHtcbiAgdmVyc2lvbjogJycsXG4gIGF0dHJpYnV0ZTogJ2F0dHJpYnV0ZScsXG4gIHZhcnlpbmdWZXJ0ZXg6ICd2YXJ5aW5nJyxcbiAgdmFyeWluZ0ZyYWc6ICd2YXJ5aW5nJyxcbiAgdGV4dHVyZTJEOiAndGV4dHVyZTJEJyxcbiAgb3V0cHV0OiAnZ2xfRnJhZ0NvbG9yJyxcbiAgb3V0cHV0RGVjbGFyYXRpb246ICcnLFxufTtcbmNvbnN0IEdMU0xfRVNfM18wOiBHbHNsID0ge1xuICB2ZXJzaW9uOiAnI3ZlcnNpb24gMzAwIGVzJyxcbiAgYXR0cmlidXRlOiAnaW4nLFxuICB2YXJ5aW5nVmVydGV4OiAnb3V0JyxcbiAgdmFyeWluZ0ZyYWc6ICdpbicsXG4gIHRleHR1cmUyRDogJ3RleHR1cmUnLFxuICBvdXRwdXQ6ICdvdXRwdXRDb2xvcicsXG4gIG91dHB1dERlY2xhcmF0aW9uOiAnb3V0IHZlYzQgb3V0cHV0Q29sb3I7Jyxcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRHbHNsKHZlcnNpb246IDEgfCAyKSB7XG4gIHJldHVybiB2ZXJzaW9uID09PSAxID8gR0xTTF9FU18yXzAgOiBHTFNMX0VTXzNfMDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZlcnRleFNoYWRlclNvdXJjZSh2ZXJzaW9uOiAxIHwgMik6IHN0cmluZyB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHZlcnNpb24pO1xuICByZXR1cm4gYCR7Z2xzbC52ZXJzaW9ufVxuICAgICAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0O1xuICAgICAgJHtnbHNsLmF0dHJpYnV0ZX0gdmVjMyBwb3NpdGlvbjtcbiAgICAgICR7Z2xzbC5hdHRyaWJ1dGV9IHZlYzIgdGV4dHVyZUNvb3JkO1xuXG4gICAgICAke2dsc2wudmFyeWluZ1ZlcnRleH0gdmVjMiBUZXhDb29yZHM7XG5cbiAgICAgIHZvaWQgbWFpbigpXG4gICAgICB7XG4gICAgICAgICAgZ2xfUG9zaXRpb24gPSB2ZWM0KHBvc2l0aW9uLCAxLjApO1xuICAgICAgICAgIFRleENvb3JkcyA9IHRleHR1cmVDb29yZDtcbiAgICAgIH1gO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnJhZ1NoYWRlclByZWFtYmxlKHZlcnNpb246IDEgfCAyKTogc3RyaW5nIHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2wodmVyc2lvbik7XG4gIHJldHVybiBgJHtnbHNsLnZlcnNpb259XG4gICAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0O1xuICAgIHByZWNpc2lvbiBoaWdocCBpbnQ7XG4gICAgcHJlY2lzaW9uIGhpZ2hwIHNhbXBsZXIyRDtcbiAgICAke2dsc2wudmFyeWluZ0ZyYWd9IHZlYzIgVGV4Q29vcmRzO1xuICAgICR7Z2xzbC5vdXRwdXREZWNsYXJhdGlvbn1cbiAgICBjb25zdCB2ZWMyIGhhbGZDUiA9IHZlYzIoMC41LCAwLjUpO1xuXG4gICAgLy8gQ3VzdG9tIHZlY3RvciB0eXBlcyB0byBoYW5kbGUgaGlnaGVyIGRpbWVuYWxpdGllcy5cbiAgICBzdHJ1Y3QgaXZlYzVcbiAgICB7XG4gICAgICBpbnQgeDtcbiAgICAgIGludCB5O1xuICAgICAgaW50IHo7XG4gICAgICBpbnQgdztcbiAgICAgIGludCB1O1xuICAgIH07XG5cbiAgICBzdHJ1Y3QgaXZlYzZcbiAgICB7XG4gICAgICBpbnQgeDtcbiAgICAgIGludCB5O1xuICAgICAgaW50IHo7XG4gICAgICBpbnQgdztcbiAgICAgIGludCB1O1xuICAgICAgaW50IHY7XG4gICAgfTtcblxuICAgIGludCBpbW9kKGludCB4LCBpbnQgeSkge1xuICAgICAgcmV0dXJuIHggLSB5ICogKHggLyB5KTtcbiAgICB9XG5cbiAgICBgO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVmYXVsdEZyYWdTaGFkZXJNYWluKHZlcnNpb246IDEgfCAyLCBvdXRwdXRTaGFwZUxlbmd0aDogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2wodmVyc2lvbik7XG4gIHJldHVybiBgXG4gIHZvaWQgbWFpbigpIHtcbiAgICBpbnQgaW5kaWNlc1ske291dHB1dFNoYXBlTGVuZ3RofV07XG4gICAgdG9WZWMoVGV4Q29vcmRzLCBpbmRpY2VzKTtcbiAgICB2ZWM0IHJlc3VsdCA9IHZlYzQocHJvY2VzcyhpbmRpY2VzKSk7XG4gICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gIH1cbiAgYDtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vdGVuc29yJztcblxuLyoqXG4gKiBMYXlvdXQgaW5mbyBpcyB1c2VkIGZvciBtYXBwaW5nIG4tZGltZW5zaW9uYWwgYXJyYXkgdG8gMkQgdGV4dHVyZXNcbiAqIFRoZSBsYXlvdXQgaXMgY3JlYXRlZCBieSB0aGUgVGV4dHVyZUxheW91dFN0cmF0ZWd5IGJhc2VkIG9uXG4gKiB0aGUgVGVuc29yJ3MgZGltZW5zaW9ucyBhbmQgc3RyaWRlc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFRleHR1cmVMYXlvdXQge1xuICB3aWR0aDogbnVtYmVyO1xuICBoZWlnaHQ6IG51bWJlcjtcbiAgLyoqXG4gICAqIHNwZWNpZnkgdGhlIG51bWJlciBvZiB2YWx1ZSB0aGF0IGVuY29kZWQgaW4gYSBzaW5nbGUgcGl4ZWxcbiAgICovXG4gIGNoYW5uZWxzOiAxIHwgMiB8IDMgfCA0O1xuICAvKipcbiAgICogd2hldGhlciBpbiBwYWNrZWQgbW9kZSBvciBub3RcbiAgICovXG4gIGlzUGFja2VkPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIHRoZSBub3JtYWxpemVkIHNoYXBlXG4gICAqL1xuICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG4gIC8qKlxuICAgKiB0aGUgc3RyaWRlIG9mIGVhY2ggZGltZW5zaW9ucywgY2FsY3VsYXRlZCBhY2NvcmRpbmcgdG8gc2hhcGVcbiAgICovXG4gIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICAvKipcbiAgICogdGhlIG9yaWdpbmFsIHNoYXBlKGRpbXMpIG9mIHRoZSBjb3JyZXNwb25kaW5nIHRlbnNvclxuICAgKi9cbiAgdW5wYWNrZWRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgcmV2ZXJzZWRXSD86IGJvb2xlYW47XG59XG5leHBvcnQgaW50ZXJmYWNlIFRleHR1cmVEYXRhIGV4dGVuZHMgVGV4dHVyZUxheW91dCB7XG4gIHRlbnNvcjogVGVuc29yO1xuICB0ZXh0dXJlOiBXZWJHTFRleHR1cmU7XG59XG5cbmV4cG9ydCBlbnVtIFRleHR1cmVUeXBlIHtcbiAgdW5wYWNrZWQsIC8vIDwtLSBub3JtYWwgdW5wYWNrZWQgdGV4dHVyZVxuICB1bnBhY2tlZFJldmVyc2VkLCAvLyA8LS0gdW5wYWNrZWQgdGV4dHVyZSB1c2VkIGluIG9sZCBPTk5YLmpzIGltcGxlbWVudGF0aW9uIChkZXByZWNhdGVkKVxuICBwYWNrZWQsIC8vIDwtLSBub3JtYWwgcGFja2VkIHRleHR1cmVcbiAgZG93bmxvYWRVaW50OEFzRmxvYXQsIC8vIDwtLSBPTkxZIHVzZWQgaW4gdGV4dHVyZSBkb3dubG9hZGluZyBmb3IgaU9TIGRldmljZXNcbiAgcGFja2VkTGFzdERpbWVuc2lvbiwgLy8gPC0tIE9OTFkgdXNlZCBpbiBvbGQgT05OWC5qcyBDb252IGltcGxlbWVudGF0aW9uIGZvciBpbnB1dCBXIChkZXByZWNhdGVkKVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckluZm8ge1xuICBpZD86IFRlbnNvci5JZDtcbiAgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHR5cGU6IFRlbnNvci5EYXRhVHlwZTtcbiAgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFByb2dyYW1WYXJpYWJsZSB7XG4gIHR5cGU6ICdmbG9hdCcgfCAnaW50JztcbiAgbmFtZTogc3RyaW5nO1xuICBhcnJheUxlbmd0aD86IG51bWJlcjtcbiAgZGF0YTogbnVtYmVyIHwgbnVtYmVyW107XG59XG5cbi8qKlxuICogQSBzZXQgb2YgbWV0YWRhdGEgb2YgYSBzaGFkZXIgcHJvZ3JhbS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtTWV0YWRhdGEge1xuICAvKipcbiAgICogdGhlIG5hbWUgb2YgdGhlIHByb2dyYW0uIHVzZWQgZm9yIGRlYnVnZ2luZyBhbmQgcHJvZmlsaW5nXG4gICAqL1xuICBuYW1lOiBzdHJpbmc7XG4gIC8qKlxuICAgKiB0ZXh0dXJlIHR5cGVzIGZvciBlYWNoIGlucHV0XG4gICAqL1xuICBpbnB1dFR5cGVzOiBUZXh0dXJlVHlwZVtdO1xuICAvKipcbiAgICogbmFtZXMgb2YgZWFjaCBpbnB1dFxuICAgKi9cbiAgaW5wdXROYW1lczogc3RyaW5nW107XG4gIC8qKlxuICAgKiBhbiBvcHRpb25hbCBzdHJpbmcgYXMgYSBjYWNoZSBoaW50IGluIHRoZSBhcnRpZmFjdCBjYWNoZVxuICAgKi9cbiAgY2FjaGVIaW50Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgUHJvZ3JhbUluZm9Mb2FkZXIgYWxsb3dzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbUluZm9Mb2FkZXIgZXh0ZW5kcyBQcm9ncmFtTWV0YWRhdGEge1xuICAvKipcbiAgICogYSBmdW5jdGlvbiB0byBnZXQgdGhlIHByb2dyYW0gaW5mb1xuICAgKi9cbiAgZ2V0KCk6IFByb2dyYW1JbmZvO1xufVxuXG4vKipcbiAqIEEgc2V0IG9mIGRhdGEgdGhhdCByZXByZXNlbnQgYSBzaGFkZXIgcHJvZ3JhbVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb2dyYW1JbmZvIGV4dGVuZHMgUHJvZ3JhbU1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIGluZm9ybWF0aW9uIG9mIHVuaWZvcm0gdmFyaWFibGVzXG4gICAqL1xuICB2YXJpYWJsZXM/OiBQcm9ncmFtVmFyaWFibGVbXTtcbiAgLyoqXG4gICAqIHRlbnNvciBpbmZvIGZvciBvdXRwdXRcbiAgICovXG4gIG91dHB1dDogVGVuc29ySW5mbztcbiAgLyoqXG4gICAqIHRoZSBzaGFkZXIncyBwcm9jZXNzaW5nIHNvdXJjZSBjb2RlXG4gICAqL1xuICBzaGFkZXJTb3VyY2U6IHN0cmluZztcbiAgLyoqXG4gICAqIHdoZXRoZXIgdGhlIHNoYWRlciBzb3VyY2UgY29udGFpbnMgYSBjdXN0b21pemVkIG1haW4gZnVuY3Rpb24gaW1wbGVtZW50YXRpb25cbiAgICovXG4gIGhhc01haW4/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZhcmlhYmxlSW5mbyB7XG4gIHR5cGU6ICdmbG9hdCcgfCAnaW50JztcbiAgbmFtZTogc3RyaW5nO1xuICBhcnJheUxlbmd0aD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtVmFyaWFibGUge1xuICB0eXBlOiAnZmxvYXQnIHwgJ2ludCc7XG4gIG5hbWU6IHN0cmluZztcbiAgYXJyYXlMZW5ndGg/OiBudW1iZXI7XG4gIGRhdGE6IG51bWJlciB8IG51bWJlcltdO1xufVxuXG4vKipcbiAqIEluZm9ybWF0aW9uIG9mIHVuaWZvcm1zIHRoYXQgc2hhZGVyIHVzZXNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVbmlmb3JtSW5mbyB7XG4gIHR5cGU6ICdzYW1wbGVyMkQnIHwgVmFyaWFibGVJbmZvWyd0eXBlJ107XG4gIG5hbWU6IHN0cmluZztcbiAgYXJyYXlMZW5ndGg/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVW5pZm9ybUxvY2F0aW9uIGV4dGVuZHMgVW5pZm9ybUluZm8ge1xuICBsb2NhdGlvbjogV2ViR0xVbmlmb3JtTG9jYXRpb247XG59XG5cbi8qKlxuICogQXJ0aWZhY3QgaXMgdGhlIHJlc3VsdCBvZiBjb21waWxhdGlvblxuICogSXQgZG9lcyBub3QgY29udGFpbiBpbnB1dCBvZiBvdXRwdXQgZGF0YVxuICogSG93ZXZlciBhbnl0aGluZyB0aGF0IGNvdWxkIGJlIHJ1biBhcyBhIFwicHJvZ3JhbVwiXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXJ0aWZhY3Qge1xuICBwcm9ncmFtSW5mbzogUHJvZ3JhbUluZm87XG4gIHByb2dyYW06IFdlYkdMUHJvZ3JhbTtcbiAgdW5pZm9ybUxvY2F0aW9uczogVW5pZm9ybUxvY2F0aW9uW107XG4gIGF0dHJpYkxvY2F0aW9uczogeyBwb3NpdGlvbjogbnVtYmVyOyB0ZXh0dXJlQ29vcmQ6IG51bWJlciB9O1xufVxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIEFydGlmYWN0IHtcbiAgdHlwZSBVbmlmb3JtTG9jYXRpb25zID0gQXJ0aWZhY3RbJ3VuaWZvcm1Mb2NhdGlvbnMnXTtcbiAgdHlwZSBBdHRyaWJMb2NhdGlvbnMgPSBBcnRpZmFjdFsnYXR0cmliTG9jYXRpb25zJ107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVW5pZm9ybURhdGEge1xuICBbbmFtZTogc3RyaW5nXTogbnVtYmVyIHwgbnVtYmVyW107XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuLyoqXG4gKiBHaXZlbiBhIG5vbiBSR0JBIHNoYXBlIGNhbGN1bGF0ZSB0aGUgUiB2ZXJzaW9uXG4gKiBJdCBpcyBhc3N1bWVkIHRoYXQgdGhlIGRpbWVuc2lvbnMgYXJlIG11bHRpcGxlcyBvZiBnaXZlbiBjaGFubmVsc1xuICogTk9URTogaXQgaXMgYWx3YXlzIHRoZSBsYXN0IGRpbSB0aGF0IGdldHMgcGFja2VkLlxuICogQHBhcmFtIHVucGFja2VkU2hhcGUgb3JpZ2luYWwgc2hhcGUgdG8gY3JlYXRlIGEgcGFja2VkIHZlcnNpb24gZnJvbVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGFja2VkU2hhcGUodW5wYWNrZWRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gIGNvbnN0IGxlbiA9IHVucGFja2VkU2hhcGUubGVuZ3RoO1xuICByZXR1cm4gdW5wYWNrZWRTaGFwZS5zbGljZSgwLCBsZW4gLSAxKS5jb25jYXQodW5wYWNrZWRTaGFwZVtsZW4gLSAxXSAvIDQpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVwZWF0ZWRUcnkoXG4gIGNoZWNrRm46ICgpID0+IGJvb2xlYW4sXG4gIGRlbGF5Rm4gPSAoX2NvdW50ZXI6IG51bWJlcikgPT4gMCxcbiAgbWF4Q291bnRlcj86IG51bWJlcixcbik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGxldCB0cnlDb3VudCA9IDA7XG5cbiAgICBjb25zdCB0cnlGbiA9ICgpID0+IHtcbiAgICAgIGlmIChjaGVja0ZuKCkpIHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRyeUNvdW50Kys7XG5cbiAgICAgIGNvbnN0IG5leHRCYWNrb2ZmID0gZGVsYXlGbih0cnlDb3VudCk7XG5cbiAgICAgIGlmIChtYXhDb3VudGVyICE9IG51bGwgJiYgdHJ5Q291bnQgPj0gbWF4Q291bnRlcikge1xuICAgICAgICByZWplY3QoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc2V0VGltZW91dCh0cnlGbiwgbmV4dEJhY2tvZmYpO1xuICAgIH07XG5cbiAgICB0cnlGbigpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgdGhlIGZ1bmN0aW9uIG5hbWUgZnJvbSBhbiBpbnB1dCBzYW1wbGVyIG5hbWUuXG4gKiBAcGFyYW0gc2FtcGxlck5hbWUgTmFtZSBvZiB0aGUgc2FtcGxlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZShzYW1wbGVyTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0KHR5cGVvZiBzYW1wbGVyTmFtZSAhPT0gJ3VuZGVmaW5lZCcgJiYgc2FtcGxlck5hbWUubGVuZ3RoICE9PSAwLCAoKSA9PiAnZW1wdHkgc3RyaW5nIGZvdW5kIGZvciBzYW1wbGVyIG5hbWUnKTtcbiAgcmV0dXJuICdnZXQnICsgc2FtcGxlck5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzYW1wbGVyTmFtZS5zbGljZSgxKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgdGhlIGZ1bmN0aW9uIG5hbWUgZnJvbSBhbiBpbnB1dCBzYW1wbGVyIG5hbWUgYXQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHNhbXBsZXJOYW1lIE5hbWUgb2YgdGhlIHNhbXBsZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWVBdE91dENvb3JkcyhzYW1wbGVyTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0KHR5cGVvZiBzYW1wbGVyTmFtZSAhPT0gJ3VuZGVmaW5lZCcgJiYgc2FtcGxlck5hbWUubGVuZ3RoICE9PSAwLCAoKSA9PiAnZW1wdHkgc3RyaW5nIGZvdW5kIGZvciBzYW1wbGVyIG5hbWUnKTtcbiAgcmV0dXJuICdnZXQnICsgc2FtcGxlck5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzYW1wbGVyTmFtZS5zbGljZSgxKSArICdBdE91dENvb3Jkcyc7XG59XG5cbi8qKiBSZXR1cm5zIGEgbmV3IGlucHV0IHNoYXBlIChhIGNvcHkpIHRoYXQgaGFzIGEgc3F1ZWV6ZWQgbG9naWNhbCBzaGFwZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzcXVlZXplSW5wdXRTaGFwZShpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgc3F1ZWV6ZWRTaGFwZTogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gIC8vIERlZXAgY29weS5cbiAgbGV0IG5ld0lucHV0U2hhcGU6IG51bWJlcltdID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dFNoYXBlKSk7XG4gIG5ld0lucHV0U2hhcGUgPSBzcXVlZXplZFNoYXBlO1xuICByZXR1cm4gbmV3SW5wdXRTaGFwZTtcbn1cblxuLyoqIFJldHVybnMgYSBsaXN0IG9mIHNxdWVlemVkIHBhcmFtZXRlcnMgZm9yIHNoYWRlciBmdW5jdGlvbnMgKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXM6IHN0cmluZ1tdLCBrZXB0RGltczogbnVtYmVyW10pOiBzdHJpbmcge1xuICByZXR1cm4ga2VwdERpbXMubWFwKChkKSA9PiBwYXJhbXNbZF0pLmpvaW4oJywgJyk7XG59XG5cbi8qKiBSZXR1cm5zIHRoZSBkYXRhIHR5cGUgZm9yIGRpZmZlcmVudCByYW5rcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb29yZHNEYXRhVHlwZShyYW5rOiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAocmFuayA8PSAxKSB7XG4gICAgcmV0dXJuICdpbnQnO1xuICB9IGVsc2UgaWYgKHJhbmsgPT09IDIpIHtcbiAgICByZXR1cm4gJ2l2ZWMyJztcbiAgfSBlbHNlIGlmIChyYW5rID09PSAzKSB7XG4gICAgcmV0dXJuICdpdmVjMyc7XG4gIH0gZWxzZSBpZiAocmFuayA9PT0gNCkge1xuICAgIHJldHVybiAnaXZlYzQnO1xuICB9IGVsc2UgaWYgKHJhbmsgPT09IDUpIHtcbiAgICByZXR1cm4gJ2l2ZWM1JztcbiAgfSBlbHNlIGlmIChyYW5rID09PSA2KSB7XG4gICAgcmV0dXJuICdpdmVjNic7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgRXJyb3IoYEdQVSBmb3IgcmFuayAke3Jhbmt9IGlzIG5vdCB5ZXQgc3VwcG9ydGVkYCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEdsQ2hhbm5lbHMocmFuayA9IDYpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBbJ3gnLCAneScsICd6JywgJ3cnLCAndScsICd2J10uc2xpY2UoMCwgcmFuayk7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGdldEdsQ2hhbm5lbHMgfSBmcm9tICcuLi91dGlscyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRWZWNDaGFubmVscyhuYW1lOiBzdHJpbmcsIHJhbms6IG51bWJlcik6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIGdldEdsQ2hhbm5lbHMocmFuaykubWFwKChkKSA9PiBgJHtuYW1lfS4ke2R9YCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGFubmVscyhuYW1lOiBzdHJpbmcsIHJhbms6IG51bWJlcik6IHN0cmluZ1tdIHtcbiAgaWYgKHJhbmsgPT09IDEpIHtcbiAgICByZXR1cm4gW25hbWVdO1xuICB9XG4gIHJldHVybiBnZXRWZWNDaGFubmVscyhuYW1lLCByYW5rKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVucGFja0Zyb21DaGFubmVsKCk6IHN0cmluZyB7XG4gIHJldHVybiBgXG4gICAgZmxvYXQgZ2V0Q2hhbm5lbCh2ZWM0IGZyYWcsIGludCBkaW0pIHtcbiAgICAgIGludCBtb2RDb29yZCA9IGltb2QoZGltLCAyKTtcbiAgICAgIHJldHVybiBtb2RDb29yZCA9PSAwID8gZnJhZy5yIDogZnJhZy5nO1xuICAgIH1cblxuICAgIGZsb2F0IGdldENoYW5uZWwodmVjNCBmcmFnLCB2ZWMyIGlubmVyRGltcykge1xuICAgICAgdmVjMiBtb2RDb29yZCA9IG1vZChpbm5lckRpbXMsIDIuKTtcbiAgICAgIHJldHVybiBtb2RDb29yZC54ID09IDAuID9cbiAgICAgICAgKG1vZENvb3JkLnkgPT0gMC4gPyBmcmFnLnIgOiBmcmFnLmcpIDpcbiAgICAgICAgKG1vZENvb3JkLnkgPT0gMC4gPyBmcmFnLmIgOiBmcmFnLmEpO1xuICAgIH1cbiAgYDtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0Q29vcmRzRGF0YVR5cGUgfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IGdldENoYW5uZWxzIH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcblxuY29uc3QgcGFja1Byb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ3BhY2snLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkUmV2ZXJzZWRdLFxufTtcblxuY29uc3QgY3JlYXRlUGFja1Byb2dyYW1JbmZvID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXQuZGltcztcblxuICBjb25zdCBpbnB1dFJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgLy8gY3JlYXRlVGV4dHVyZUxheW91dEZyb21TaGFwZSB3b24ndCBjaGFuZ2Ugb3V0cHV0IHJhbmsuIE5lZWQgdG8gdmVyaWZ5IGJ5IHJ1bm5pbmcgdGVzdHNcbiAgY29uc3Qgb3V0cHV0UmFuayA9IGlucHV0LmRpbXMubGVuZ3RoO1xuXG4gIGNvbnN0IGNvb3Jkc0RhdGFUeXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0cHV0UmFuayk7XG4gIGNvbnN0IGNoYW5uZWxzID0gZ2V0Q2hhbm5lbHMoJ3JjJywgb3V0cHV0UmFuayk7XG4gIGNvbnN0IHNldHVwID0gZ2V0U2V0dXAob3V0cHV0UmFuaywgY2hhbm5lbHMsIGlucHV0U2hhcGVbaW5wdXRTaGFwZS5sZW5ndGggLSAyXSwgaW5wdXRTaGFwZVtpbnB1dFNoYXBlLmxlbmd0aCAtIDFdKTtcblxuICBsZXQgcmV2ZXJzZWRJbnB1dFdIO1xuICBpZiAoaW5wdXRSYW5rID09PSAwKSB7XG4gICAgcmV2ZXJzZWRJbnB1dFdIID0gWzEsIDFdO1xuICB9IGVsc2UgaWYgKGlucHV0UmFuayA9PT0gMSkge1xuICAgIHJldmVyc2VkSW5wdXRXSCA9IFtpbnB1dFNoYXBlWzBdLCAxXTtcbiAgfSBlbHNlIHtcbiAgICByZXZlcnNlZElucHV0V0ggPSBbaW5wdXRTaGFwZVtvdXRwdXRSYW5rIC0gMV0sIGlucHV0U2hhcGVbb3V0cHV0UmFuayAtIDJdXTtcbiAgfVxuICBjb25zdCBvdXRPZkJvdW5kc0NvbmRpdGlvbiA9IGdldE91dE9mQm91bmRzQ29uZGl0aW9uKG91dHB1dFJhbmssIHJldmVyc2VkSW5wdXRXSCwgY2hhbm5lbHMpO1xuICBjb25zdCBvdXRwdXQgPSBnZXRPdXRwdXQoaW5wdXRTaGFwZSwgY2hhbm5lbHMpO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICAgICR7Y29vcmRzRGF0YVR5cGV9IHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG5cbiAgICAgICAgICBpZigke291dE9mQm91bmRzQ29uZGl0aW9ufSkge1xuICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KDApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAke3NldHVwfVxuXG4gICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQoJHtvdXRwdXR9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4ucGFja1Byb2dyYW1NZXRhZGF0YSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dC5kaW1zLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tQcm9ncmFtSW5mb0xvYWRlciA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IpOiBQcm9ncmFtSW5mb0xvYWRlciA9PiAoe1xuICAuLi5wYWNrUHJvZ3JhbU1ldGFkYXRhLFxuICBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tQcm9ncmFtSW5mbyhoYW5kbGVyLCBpbnB1dCksXG59KTtcblxuLyoqXG4gKiBjaGVjayBvdXRwdXQgY29vcmRpbmF0ZSBsb2NhdGlvbiBhbmQgcmV0dXJuIGZhbHNlIGlmIGl0IGlzIG91dHNpZGUgaW5wdXQncyB3aWR0aC9oZWlnaHQgYm91bmRhcnlcbiAqL1xuZnVuY3Rpb24gZ2V0T3V0T2ZCb3VuZHNDb25kaXRpb24ocmFuazogbnVtYmVyLCBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGRpbXM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgaWYgKHJhbmsgPT09IDApIHtcbiAgICByZXR1cm4gJ2ZhbHNlJztcbiAgfVxuICBpZiAocmFuayA9PT0gMSkge1xuICAgIHJldHVybiBgcmMgPiAke3NoYXBlWzBdfWA7XG4gIH1cblxuICBsZXQgY29uZCA9ICcnO1xuICBmb3IgKGxldCBpID0gcmFuayAtIDI7IGkgPCByYW5rOyBpKyspIHtcbiAgICBjb25kICs9IGAke2RpbXNbaV19ID49ICR7c2hhcGVbaSAtIHJhbmsgKyAyXX1gO1xuICAgIGlmIChpIDwgcmFuayAtIDEpIHtcbiAgICAgIGNvbmQgKz0gJ3x8JztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY29uZDtcbn1cblxuLyoqXG4gKiBjb2RlIHNuaXBwZXQgdG8gc2FtcGxlIGlucHV0IHRleHR1cmUgd2l0aCBvdXRwdXQgY29vcmRpbmF0ZXNcbiAqL1xuZnVuY3Rpb24gZ2V0T3V0cHV0KHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgZGltczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gIGlmIChyYW5rID09PSAwKSB7XG4gICAgcmV0dXJuICdnZXRBKCksIDAsIDAsIDAnO1xuICB9XG5cbiAgaWYgKHJhbmsgPT09IDEpIHtcbiAgICByZXR1cm4gYGdldEEocmMpLFxuICAgICAgICAgICAgcmMgKyAxID49ICR7c2hhcGVbMF19ID8gMC4gOiBnZXRBKHJjICsgMSksXG4gICAgICAgICAgICAwLCAwYDtcbiAgfVxuXG4gIGNvbnN0IGNvb3JkMDAgPSAnciwgYyc7XG4gIGNvbnN0IGNvb3JkMDEgPSAnciwgY3AxJztcbiAgY29uc3QgY29vcmQxMCA9ICdycDEsIGMnO1xuICBjb25zdCBjb29yZDExID0gJ3JwMSwgY3AxJztcbiAgbGV0IEQgPSAnJztcbiAgaWYgKHJhbmsgPiAyKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rIC0gMjsgKytpKSB7XG4gICAgICBEID0gRCArIGAke2RpbXNbaV19LGA7XG4gICAgfVxuICB9XG4gIHJldHVybiBgZ2V0QSgke0R9JHtjb29yZDAwfSksXG4gICAgICAgICAgckVkZ2UgPyAwLiA6IGdldEEoJHtEfSR7Y29vcmQxMH0pLFxuICAgICAgICAgIGNFZGdlID8gMC4gOiBnZXRBKCR7RH0ke2Nvb3JkMDF9KSxcbiAgICAgICAgICByRWRnZSB8fCBjRWRnZSA/IDAuIDogZ2V0QSgke0R9JHtjb29yZDExfSlgO1xufVxuXG4vKipcbiAqIGNvZGUgc25pcHBldCB0byBzZXR1cCA0IGNvb3JkaW5hdGVzIGFuZCBlZGdlIGNvbmRpdGlvbnNcbiAqL1xuZnVuY3Rpb24gZ2V0U2V0dXAocmFuazogbnVtYmVyLCBkaW1zOiBzdHJpbmdbXSwgcm93czogbnVtYmVyLCBjb2xzOiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAocmFuayA9PT0gMCB8fCByYW5rID09PSAxKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIC8vIHJhbmsgPj0gMiBmb3Igd2lkdGgraGVpZ2h0IHBhY2suXG4gIGVsc2Uge1xuICAgIGNvbnN0IHNldHVwID0gYFxuICAgIGludCByID0gJHtkaW1zW3JhbmsgLSAyXX07XG4gICAgaW50IGMgPSAke2RpbXNbcmFuayAtIDFdfTtcbiAgICBpbnQgcnAxID0gJHtkaW1zW3JhbmsgLSAyXX0gKyAxO1xuICAgIGludCBjcDEgPSAke2RpbXNbcmFuayAtIDFdfSArIDE7XG4gICAgYm9vbCByRWRnZSA9IHJwMSA+PSAke2NvbHN9O1xuICAgIGJvb2wgY0VkZ2UgPSBjcDEgPj0gJHtyb3dzfTtcbiAgICBgO1xuICAgIHJldHVybiBzZXR1cDtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyB1bnBhY2tGcm9tQ2hhbm5lbCB9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1NZXRhZGF0YSA9IChvdXRwdXRTaGFwZTNEOiByZWFkb25seSBudW1iZXJbXSkgPT4gKHtcbiAgbmFtZTogJ1Jlc2hhcGUgKHBhY2tlZCknLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUucGFja2VkXSxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGNhY2hlSGludDogYCR7b3V0cHV0U2hhcGUzRH1gLFxufSk7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1JbmZvID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0M0Q6IFRlbnNvcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgb3V0cHV0U2hhcGUzRDogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUzRCA9IGlucHV0M0QuZGltcyBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gIGNvbnN0IHNxdWVlemVkT3V0cHV0U2hhcGUgPSBvdXRwdXRTaGFwZTNEIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcblxuICBsZXQgbWFpbkxvb3AgPSAnJztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICBsZXQgb3V0cHV0Q29vcmRzID0gJyc7XG4gICAgc3dpdGNoIChpKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIG91dHB1dENvb3JkcyA9ICdvdXRwdXRDb29yZHMgPSByYzsnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgb3V0cHV0Q29vcmRzID0gJ291dHB1dENvb3JkcyA9IGl2ZWMzKHJjLngsIHJjLnkrMSwgcmMueik7JztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIG91dHB1dENvb3JkcyA9ICdvdXRwdXRDb29yZHMgPSBpdmVjMyhyYy54LCByYy55LCByYy56KzEpOyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICBvdXRwdXRDb29yZHMgPSAnb3V0cHV0Q29vcmRzID0gaXZlYzMocmMueCwgcmMueSsxLCByYy56KzEpOyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgfVxuXG4gICAgbWFpbkxvb3AgKz0gYFxuICAgICAgICAke291dHB1dENvb3Jkc31cbiAgICAgICAgJHtpID4gMCA/ICdpZihvdXRwdXRDb29yZHMueSA8IHJvd3MgJiYgb3V0cHV0Q29vcmRzLnogPCBjb2xzKXsnIDogJyd9XG4gICAgICAgICAgaW50IGZsYXR0ZW5lZEluZGV4ID0gZ2V0RmxhdHRlbmVkSW5kZXgob3V0cHV0Q29vcmRzKTtcblxuICAgICAgICAgIGl2ZWMzIGlucHV0UkMgPSBpbnB1dENvb3Jkc0Zyb21SZXNoYXBlZE91dENvb3JkcyhmbGF0dGVuZWRJbmRleCk7XG4gICAgICAgICAgdmVjMiBpbm5lckRpbXMgPSB2ZWMyKGZsb2F0KGlucHV0UkMueSksZmxvYXQoaW5wdXRSQy56KSk7XG5cbiAgICAgICAgICByZXN1bHRbJHtpfV0gPSBnZXRDaGFubmVsKGdldEEoaW5wdXRSQy54LCBpbnB1dFJDLnksIGlucHV0UkMueiksIGlubmVyRGltcyk7XG5cbiAgICAgICAgJHtpID4gMCA/ICd9JyA6ICcnfVxuICAgICAgYDtcbiAgfVxuICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHtnZXRSZXNoYXBlZElucHV0Q29vcmRzKGlucHV0U2hhcGUzRCl9XG4gICAgICAke2dldEZsYXR0ZW5lZEluZGV4RnJvbTNEKHNxdWVlemVkT3V0cHV0U2hhcGUpfVxuICAgICAgJHt1bnBhY2tGcm9tQ2hhbm5lbCgpfVxuXG4gICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgIGl2ZWMzIHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG5cbiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuMCk7XG5cbiAgICAgICAgaXZlYzMgb3V0cHV0Q29vcmRzO1xuICAgICAgICBpbnQgcm93cyA9ICR7c3F1ZWV6ZWRPdXRwdXRTaGFwZVsyXX07XG4gICAgICAgIGludCBjb2xzID0gJHtzcXVlZXplZE91dHB1dFNoYXBlWzFdfTtcblxuICAgICAgICAke21haW5Mb29wfVxuICAgICAgICAke2dsc2wub3V0cHV0fSA9IHJlc3VsdDtcbiAgICAgIH1cbiAgICBgO1xuXG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IHNxdWVlemVkT3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0M0QudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0M0Q6IFRlbnNvcixcbiAgb3V0cHV0U2hhcGUzRDogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbU1ldGFkYXRhKG91dHB1dFNoYXBlM0QpO1xuICByZXR1cm4geyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtSW5mbyhoYW5kbGVyLCBpbnB1dDNELCBtZXRhZGF0YSwgb3V0cHV0U2hhcGUzRCkgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBwcm9jZXNzRGltczNEKHNoYXBlOiBBcnJheUxpa2U8bnVtYmVyPik6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSB7XG4gIGlmIChzaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gWzEsIDEsIDFdO1xuICB9XG4gIC8vIFRPRE86IHNxdWVlemUgb3RoZXIgc2hhcGVzIHRvIDJEIGNhc2VcbiAgbGV0IGJhdGNoID0gMTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaGFwZS5sZW5ndGggLSAyOyArK2kpIHtcbiAgICBiYXRjaCAqPSBzaGFwZVtpXTtcbiAgfVxuICByZXR1cm4gW2JhdGNoLCBzaGFwZS5sZW5ndGggPiAxID8gc2hhcGVbc2hhcGUubGVuZ3RoIC0gMl0gOiAxLCBzaGFwZVtzaGFwZS5sZW5ndGggLSAxXV07XG59XG5cbi8vIEZvciBwYWNrZWQgcmVzaGFwZSwgd2UgbmVlZCB0byByZS1hcnJhbmdlIHRleGVsIGRhdGEgZm9yIG91dHB1dCBzaGFwZS5cbi8vIE91ciBwYWNrIGlzIGRlc2lnbmVkIHRvIHBhY2sgYSAyeDIgdGlsZSBpbiBsYXN0IGggYW5kIHcgZGltZW5zaW9uLCBzb1xuLy8gZm9yIHRoZSByZXNoYXBlZCBuZXcgdGVuc29yLCB3ZSBqdXN0IG5lZWQgdG8gcmUtYXJyYW5nZSB0aGUgbGFzdCBoIGFuZFxuLy8gdyBkaW1lbnNpb24uIEZvciBhbnkgc2hhcGUgdGhhdCBpcyBub3QgaW4gM0QsIGkuZS4gW2JhdGNoLCBXLCBIXSwgd2Vcbi8vIGZpcnN0IGNvbnZlcnQgaXQgdG8gM0QgYnkgY29sbGFwc2luZyBvdGhlciBkaW1lbnNpb24gdG8gYmF0Y2ggZGltLCB0aGVuXG4vLyBwcm9jZXNzIHdpdGggdGhlIGxhc3QgdHdvIGRpbWVuc2lvbnMuXG4vLyBOb3RlOiB3ZSBvbmx5IG5lZWQgdGhlIHNoYXBlIHRlbnNvciB0byBjYWxjdWxhdGUgb3V0cHV0IHNoYXBlLCBzbyB0aGVcbi8vIGNvbnRlbnQgaW4gc2hhcGUgdGVuc29yIGlzIG5ldmVyIHVwbG9hZGVkIHRvIEdQVS4gSXQgaXMgYWx3YXlzIGtlcHQgaW4gQ1BVLlxuLy8gVE9ETzogb3B0aW1pemUgdGhlIGFsZ29yaXRobSAtLSBpbiBzb21lIGNhc2VzLCBpZiB0aGUgbGFzdCB0d28gZGltcyBhcmVcbi8vIHRoZSBzYW1lIGJldHdlZW4gaW5wdXQgc2hhcGUgYW5kIG91dHB1dCBzaGFwZSwgdGhlIHBhY2tlZCByZXNoYXBlIGNhbiBiZVxuLy8gdHJlYXRlZCBhcyBuby1vcC5cbmV4cG9ydCBmdW5jdGlvbiBpc1Jlc2hhcGVDaGVhcChkaW1zOiByZWFkb25seSBudW1iZXJbXSwgcmVzaGFwZWREaW1zOiByZWFkb25seSBudW1iZXJbXSkge1xuICBsZXQgaXNDaGVhcFJlc2hhcGUgPSBmYWxzZTtcbiAgaWYgKGRpbXMubGVuZ3RoID09PSAwIHx8IHJlc2hhcGVkRGltcy5sZW5ndGggPT09IDApIHtcbiAgICAvLyBzY2FsYXJcbiAgICBpc0NoZWFwUmVzaGFwZSA9IHRydWU7XG4gIH0gZWxzZSBpZiAoZGltcy5sZW5ndGggPCAyIHx8IHJlc2hhcGVkRGltcy5sZW5ndGggPCAyKSB7XG4gICAgLy8gMURcbiAgICBpc0NoZWFwUmVzaGFwZSA9IGRpbXNbZGltcy5sZW5ndGggLSAxXSA9PT0gcmVzaGFwZWREaW1zW3Jlc2hhcGVkRGltcy5sZW5ndGggLSAxXTtcbiAgfSBlbHNlIHtcbiAgICAvLyAyRCArXG4gICAgaXNDaGVhcFJlc2hhcGUgPVxuICAgICAgZGltc1tkaW1zLmxlbmd0aCAtIDFdID09PSByZXNoYXBlZERpbXNbcmVzaGFwZWREaW1zLmxlbmd0aCAtIDFdICYmXG4gICAgICBkaW1zW2RpbXMubGVuZ3RoIC0gMl0gPT09IHJlc2hhcGVkRGltc1tyZXNoYXBlZERpbXMubGVuZ3RoIC0gMl07XG4gIH1cblxuICByZXR1cm4gaXNDaGVhcFJlc2hhcGU7XG59XG5cbmZ1bmN0aW9uIGdldFJlc2hhcGVkSW5wdXRDb29yZHMoc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSk6IHN0cmluZyB7XG4gIGNvbnN0IHN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoc2hhcGUpO1xuICBjb25zdCBjb29yZHMgPSBbJ2InLCAncicsICdjJ107XG4gIGNvbnN0IGluZGV4ID0gJ2luZGV4JztcbiAgY29uc3QgY29vcmRzRnJvbUluZGV4U25pcHBldCA9IHN0cmlkZXNcbiAgICAubWFwKChzdHJpZGUsIGkpID0+IHtcbiAgICAgIGNvbnN0IGxpbmUxID0gYGludCAke2Nvb3Jkc1tpXX0gPSAke2luZGV4fSAvICR7c3RyaWRlfWA7XG4gICAgICBjb25zdCBsaW5lMiA9XG4gICAgICAgIGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMVxuICAgICAgICAgID8gYGludCAke2Nvb3Jkc1tpICsgMV19ID0gJHtpbmRleH0gLSAke2Nvb3Jkc1tpXX0gKiAke3N0cmlkZX1gXG4gICAgICAgICAgOiBgaW5kZXggLT0gJHtjb29yZHNbaV19ICogJHtzdHJpZGV9YDtcbiAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgfSlcbiAgICAuam9pbignJyk7XG5cbiAgcmV0dXJuIGBcbiAgICBpdmVjMyBpbnB1dENvb3Jkc0Zyb21SZXNoYXBlZE91dENvb3JkcyhpbnQgaW5kZXgpIHtcbiAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgIHJldHVybiBpdmVjMyhiLCByLCBjKTtcbiAgICB9XG4gIGA7XG59XG5cbmZ1bmN0aW9uIGdldEZsYXR0ZW5lZEluZGV4RnJvbTNEKHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0pOiBzdHJpbmcge1xuICBjb25zdCBzdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKHNoYXBlKTtcblxuICByZXR1cm4gYFxuICBpbnQgZ2V0RmxhdHRlbmVkSW5kZXgoaXZlYzMgY29vcmRzKSB7XG4gICAgLy8gcmV2ZXJzZSB5LCB6IG9yZGVyXG4gICAgcmV0dXJuIGNvb3Jkcy54ICogJHtzdHJpZGVzWzBdfSArIGNvb3Jkcy56ICogJHtzdHJpZGVzWzFdfSArIGNvb3Jkcy55O1xuICB9XG5gO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgVGV4dHVyZURhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgY29uc3QgZW5jb2RlQXNVaW50OCA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZXh0dXJlRGF0YSk6IFRleHR1cmVEYXRhID0+IHtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dC5zaGFwZTtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAvKipcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL3RlbnNvcmZsb3cvdGZqcy1jb3JlL2Jsb2IvbWFzdGVyL3NyYy9rZXJuZWxzL3dlYmdsL2VuY29kZV9mbG9hdF9ncHUudHNcbiAgICovXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICBjb25zdCBmbG9hdCBGTE9BVF9NQVggPSAxLjcwMTQxMTg0ZTM4O1xuICAgIGNvbnN0IGZsb2F0IEZMT0FUX01JTiA9IDEuMTc1NDk0MzVlLTM4O1xuXG4gICAgYm9vbCBpc05hTihmbG9hdCB2YWwpIHtcbiAgICAgIHJldHVybiAodmFsIDwgMS4wIHx8IDAuMCA8IHZhbCB8fCB2YWwgPT0gMC4wKSA/IGZhbHNlIDogdHJ1ZTtcbiAgICB9XG5cbiAgICBoaWdocCB2ZWM0IGVuY29kZUFzVWludDgoaGlnaHAgZmxvYXQgdikge1xuICAgICAgaWYgKGlzTmFOKHYpKSB7XG4gICAgICAgIHJldHVybiB2ZWM0KDI1NSwgMjU1LCAyNTUsIDI1NSk7XG4gICAgICB9XG5cbiAgICAgIGhpZ2hwIGZsb2F0IGF2ID0gYWJzKHYpO1xuXG4gICAgICBpZihhdiA8IEZMT0FUX01JTikge1xuICAgICAgICByZXR1cm4gdmVjNCgwLjAsIDAuMCwgMC4wLCAwLjApO1xuICAgICAgfSBlbHNlIGlmKHYgPiBGTE9BVF9NQVgpIHtcbiAgICAgICAgcmV0dXJuIHZlYzQoMC4wLCAwLjAsIDEyOC4wLCAxMjcuMCkgLyAyNTUuMDtcbiAgICAgIH0gZWxzZSBpZih2IDwgLUZMT0FUX01BWCkge1xuICAgICAgICByZXR1cm4gdmVjNCgwLjAsIDAuMCwgIDEyOC4wLCAyNTUuMCkgLyAyNTUuMDtcbiAgICAgIH1cblxuICAgICAgaGlnaHAgdmVjNCBjID0gdmVjNCgwLDAsMCwwKTtcblxuICAgICAgaGlnaHAgZmxvYXQgZSA9IGZsb29yKGxvZzIoYXYpKTtcbiAgICAgIGhpZ2hwIGZsb2F0IG0gPSBleHAyKGZyYWN0KGxvZzIoYXYpKSkgLSAxLjA7XG5cbiAgICAgIGNbMl0gPSBmbG9vcigxMjguMCAqIG0pO1xuICAgICAgbSAtPSBjWzJdIC8gMTI4LjA7XG4gICAgICBjWzFdID0gZmxvb3IoMzI3NjguMCAqIG0pO1xuICAgICAgbSAtPSBjWzFdIC8gMzI3NjguMDtcbiAgICAgIGNbMF0gPSBmbG9vcig4Mzg4NjA4LjAgKiBtKTtcblxuICAgICAgaGlnaHAgZmxvYXQgZWJpYXMgPSBlICsgMTI3LjA7XG4gICAgICBjWzNdID0gZmxvb3IoZWJpYXMgLyAyLjApO1xuICAgICAgZWJpYXMgLT0gY1szXSAqIDIuMDtcbiAgICAgIGNbMl0gKz0gZmxvb3IoZWJpYXMpICogMTI4LjA7XG5cbiAgICAgIGNbM10gKz0gMTI4LjAgKiBzdGVwKDAuMCwgLXYpO1xuXG4gICAgICByZXR1cm4gYyAvIDI1NS4wO1xuICAgIH1cblxuICAgIHZvaWQgbWFpbigpIHtcbiAgICAgIGZsb2F0IHZhbHVlID0gJHtnbHNsLnRleHR1cmUyRH0oWCxUZXhDb29yZHMpLnI7XG4gICAgICAke2dsc2wub3V0cHV0fSA9IGVuY29kZUFzVWludDgodmFsdWUpO1xuICAgIH1gO1xuICBjb25zdCBwcm9ncmFtSW5mbyA9IHtcbiAgICBuYW1lOiAnVWludDhFbmNvZGUnLFxuICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgaW5wdXROYW1lczogWydYJ10sXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50ZW5zb3IudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLmRvd25sb2FkVWludDhBc0Zsb2F0IH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG4gIHJldHVybiBpbmZlcmVuY2VIYW5kbGVyLmV4ZWN1dGVQcm9ncmFtKHByb2dyYW1JbmZvLCBbaW5wdXQudGVuc29yXSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRDb29yZHNEYXRhVHlwZSB9IGZyb20gJy4uL3V0aWxzJztcblxuaW1wb3J0IHsgZ2V0Q2hhbm5lbHMsIHVucGFja0Zyb21DaGFubmVsIH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcblxuY29uc3QgdW5wYWNrUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAndW5wYWNrJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVVucGFja1Byb2dyYW1JbmZvID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgcmFuayA9IGlucHV0LmRpbXMubGVuZ3RoO1xuXG4gIGNvbnN0IGNoYW5uZWxzID0gZ2V0Q2hhbm5lbHMoJ3JjJywgcmFuayk7XG4gIGNvbnN0IGlubmVyRGltcyA9IGNoYW5uZWxzLnNsaWNlKC0yKTtcbiAgY29uc3QgY29vcmRzRGF0YVR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShyYW5rKTtcbiAgY29uc3QgdW5wYWNrQ2hhbm5lbCA9IHVucGFja0Zyb21DaGFubmVsKCk7XG4gIGNvbnN0IGlzU2NhbGFyID0gaW5wdXQuZGltcy5sZW5ndGggPT09IDA7XG4gIGNvbnN0IHNvdXJjZUNvb3JkcyA9IGlzU2NhbGFyID8gJycgOiBnZXRTb3VyY2VDb29yZHMocmFuaywgY2hhbm5lbHMpO1xuICBjb25zdCBjb29yZHMgPSByYW5rIDw9IDEgPyAncmMnIDogYHZlYzIoJHtpbm5lckRpbXMuam9pbignLCcpfSlgO1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAke3VucGFja0NoYW5uZWx9XG4gICAgdm9pZCBtYWluKCkge1xuICAgICAgJHtjb29yZHNEYXRhVHlwZX0gcmMgPSBnZXRPdXRwdXRDb29yZHMoKTtcblxuICAgICAgIC8vIFNhbXBsZSB0aGUgdGV4dHVyZSB3aXRoIHRoZSBjb29yZHMgdG8gZ2V0IHRoZSByZ2JhIGNoYW5uZWwgdmFsdWUuXG4gICAgICAgdmVjNCBwYWNrZWRJbnB1dCA9IGdldEEoJHtzb3VyY2VDb29yZHN9KTtcblxuICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmVjNChnZXRDaGFubmVsKHBhY2tlZElucHV0LCAke2Nvb3Jkc30pLCAwLCAwLCAwKTtcbiAgICAgfVxuICAgYDtcblxuICByZXR1cm4ge1xuICAgIC4uLnVucGFja1Byb2dyYW1NZXRhZGF0YSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dC5kaW1zLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVW5wYWNrUHJvZ3JhbUluZm9Mb2FkZXIgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4gKHtcbiAgLi4udW5wYWNrUHJvZ3JhbU1ldGFkYXRhLFxuICBnZXQ6ICgpID0+IGNyZWF0ZVVucGFja1Byb2dyYW1JbmZvKGhhbmRsZXIsIGlucHV0KSxcbn0pO1xuXG5mdW5jdGlvbiBnZXRTb3VyY2VDb29yZHMocmFuazogbnVtYmVyLCBkaW1zOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIGlmIChyYW5rID09PSAxKSB7XG4gICAgcmV0dXJuICdyYyc7XG4gIH1cblxuICBsZXQgY29vcmRzID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgaSsrKSB7XG4gICAgY29vcmRzICs9IGRpbXNbaV07XG4gICAgaWYgKGkgPCByYW5rIC0gMSkge1xuICAgICAgY29vcmRzICs9ICcsJztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNvb3Jkcztcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBFbmNvZGVyIHtcbiAgZXhwb3J0IGludGVyZmFjZSBEYXRhVHlwZU1hcCB7XG4gICAgZmxvYXQ6IEZsb2F0MzJBcnJheTtcbiAgICBieXRlOiBVaW50OEFycmF5O1xuICAgIGludDogVWludDMyQXJyYXk7XG4gIH1cbiAgZXhwb3J0IHR5cGUgRGF0YVR5cGUgPSBrZXlvZiBEYXRhVHlwZU1hcDtcbiAgdHlwZSBEYXRhQXJyYXlUeXBlID0gRGF0YVR5cGVNYXBbRGF0YVR5cGVdO1xufVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24gKi9cbmV4cG9ydCBjb25zdCBlbnVtIEVuY29kZXJVc2FnZSB7XG4gIERlZmF1bHQgPSAwLFxuICBVcGxvYWRPbmx5LFxuICBEb3dubG9hZDRCeXRlc0FzRmxvYXQzMixcbn1cbi8qIGVzbGludC1lbmFibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXG5cbi8qKlxuICogQWJzdHJhY3Rpb24gZm9yIG1hcHBpbmcgZGF0YSB0eXBlcyB0byB0ZXh0dXJlIHRleGxldHNcbiAqIEVuY29kaW5nIG1lYW5zIGhvdyBhIEZsb2F0MzIgaXMgbWFwcGVkIHRvIDEgb3IgNCBjaGFubmVscyBmb3IgZWFjaCB0ZXhsZXRcbiAqIERlY29kaW5nIG1lYW5zIGhvdyBhIHRleGxldCdzIGNoYW5uZWxzIGFyZSBtYXBwZWQgdG8gYSByZXN1bHRpbmcgRmxvYXQzMlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERhdGFFbmNvZGVyIHtcbiAgaW50ZXJuYWxGb3JtYXQ6IG51bWJlcjtcbiAgZm9ybWF0OiBudW1iZXI7XG4gIHRleHR1cmVUeXBlOiBudW1iZXI7XG4gIGNoYW5uZWxTaXplOiBudW1iZXI7XG4gIGVuY29kZShzcmM6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgdGV4dHVyZVNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZTtcbiAgYWxsb2NhdGUoc2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlO1xuICBkZWNvZGUoYnVmZmVyOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUsIGRhdGFTaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGU7XG59XG4vKipcbiAqIFdlYkdMMiBkYXRhIGVuY29kZXJcbiAqIFVzZXMgUjMyRiBhcyB0aGUgZm9ybWF0IGZvciB0ZXhsZXRcbiAqL1xuZXhwb3J0IGNsYXNzIFJlZEZsb2F0MzJEYXRhRW5jb2RlciBpbXBsZW1lbnRzIERhdGFFbmNvZGVyIHtcbiAgaW50ZXJuYWxGb3JtYXQ6IG51bWJlcjtcbiAgZm9ybWF0OiBudW1iZXI7XG4gIHRleHR1cmVUeXBlOiBudW1iZXI7XG4gIGNoYW5uZWxTaXplOiBudW1iZXI7XG4gIGNvbnN0cnVjdG9yKGdsOiBXZWJHTDJSZW5kZXJpbmdDb250ZXh0LCBjaGFubmVscyA9IDEpIHtcbiAgICBpZiAoY2hhbm5lbHMgPT09IDEpIHtcbiAgICAgIHRoaXMuaW50ZXJuYWxGb3JtYXQgPSBnbC5SMzJGO1xuICAgICAgdGhpcy5mb3JtYXQgPSBnbC5SRUQ7XG4gICAgICB0aGlzLnRleHR1cmVUeXBlID0gZ2wuRkxPQVQ7XG4gICAgICB0aGlzLmNoYW5uZWxTaXplID0gY2hhbm5lbHM7XG4gICAgfSBlbHNlIGlmIChjaGFubmVscyA9PT0gNCkge1xuICAgICAgdGhpcy5pbnRlcm5hbEZvcm1hdCA9IGdsLlJHQkEzMkY7XG4gICAgICB0aGlzLmZvcm1hdCA9IGdsLlJHQkE7XG4gICAgICB0aGlzLnRleHR1cmVUeXBlID0gZ2wuRkxPQVQ7XG4gICAgICB0aGlzLmNoYW5uZWxTaXplID0gY2hhbm5lbHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBudW1iZXIgb2YgY2hhbm5lbHM6ICR7Y2hhbm5lbHN9YCk7XG4gICAgfVxuICB9XG4gIGVuY29kZShzcmM6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgdGV4dHVyZVNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgbGV0IHJlc3VsdDogRmxvYXQzMkFycmF5O1xuICAgIGxldCBzb3VyY2U6IEZsb2F0MzJBcnJheTtcbiAgICBpZiAoc3JjLmNvbnN0cnVjdG9yICE9PSBGbG9hdDMyQXJyYXkpIHtcbiAgICAgIExvZ2dlci53YXJuaW5nKCdFbmNvZGVyJywgJ2RhdGEgd2FzIG5vdCBvZiB0eXBlIEZsb2F0MzI7IGNyZWF0aW5nIG5ldyBGbG9hdDMyQXJyYXknKTtcbiAgICAgIHNvdXJjZSA9IG5ldyBGbG9hdDMyQXJyYXkoc3JjKTtcbiAgICB9XG4gICAgaWYgKHRleHR1cmVTaXplICogdGhpcy5jaGFubmVsU2l6ZSA+IHNyYy5sZW5ndGgpIHtcbiAgICAgIExvZ2dlci53YXJuaW5nKCdFbmNvZGVyJywgJ1NvdXJjZSBkYXRhIHRvbyBzbWFsbC4gQWxsb2NhdGluZyBsYXJnZXIgYXJyYXknKTtcbiAgICAgIHNvdXJjZSA9IHNyYyBhcyBGbG9hdDMyQXJyYXk7XG4gICAgICByZXN1bHQgPSB0aGlzLmFsbG9jYXRlKHRleHR1cmVTaXplICogdGhpcy5jaGFubmVsU2l6ZSkgYXMgRmxvYXQzMkFycmF5O1xuICAgICAgc291cmNlLmZvckVhY2goKHYsIGkpID0+IChyZXN1bHRbaV0gPSB2KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNvdXJjZSA9IHNyYyBhcyBGbG9hdDMyQXJyYXk7XG4gICAgICByZXN1bHQgPSBzb3VyY2U7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgYWxsb2NhdGUoc2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShzaXplICogNCk7XG4gIH1cbiAgZGVjb2RlKGJ1ZmZlcjogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCBkYXRhU2l6ZTogbnVtYmVyKTogRmxvYXQzMkFycmF5IHtcbiAgICBpZiAodGhpcy5jaGFubmVsU2l6ZSA9PT0gMSkge1xuICAgICAgY29uc3QgZmlsdGVyZWREYXRhID0gKGJ1ZmZlciBhcyBGbG9hdDMyQXJyYXkpLmZpbHRlcigoX3ZhbHVlLCBpbmRleCkgPT4gaW5kZXggJSA0ID09PSAwKS5zdWJhcnJheSgwLCBkYXRhU2l6ZSk7XG4gICAgICByZXR1cm4gZmlsdGVyZWREYXRhO1xuICAgIH1cbiAgICByZXR1cm4gYnVmZmVyLnN1YmFycmF5KDAsIGRhdGFTaXplKSBhcyBGbG9hdDMyQXJyYXk7XG4gIH1cbn1cbi8qKlxuICogRGF0YSBlbmNvZGVyIGZvciBXZWJHTCAxIHdpdGggc3VwcG9ydCBmb3IgZmxvYXRpbmcgcG9pbnQgdGV4dHVyZVxuICovXG5leHBvcnQgY2xhc3MgUkdCQUZsb2F0RGF0YUVuY29kZXIgaW1wbGVtZW50cyBEYXRhRW5jb2RlciB7XG4gIGludGVybmFsRm9ybWF0OiBudW1iZXI7XG4gIGZvcm1hdDogbnVtYmVyO1xuICB0ZXh0dXJlVHlwZTogbnVtYmVyO1xuICBjaGFubmVsU2l6ZTogbnVtYmVyO1xuICBjb25zdHJ1Y3RvcihnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCBjaGFubmVscyA9IDEsIHRleHR1cmVUeXBlPzogbnVtYmVyKSB7XG4gICAgaWYgKGNoYW5uZWxzICE9PSAxICYmIGNoYW5uZWxzICE9PSA0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgbnVtYmVyIG9mIGNoYW5uZWxzOiAke2NoYW5uZWxzfWApO1xuICAgIH1cbiAgICB0aGlzLmludGVybmFsRm9ybWF0ID0gZ2wuUkdCQTtcbiAgICB0aGlzLmZvcm1hdCA9IGdsLlJHQkE7XG4gICAgdGhpcy5jaGFubmVsU2l6ZSA9IGNoYW5uZWxzO1xuICAgIHRoaXMudGV4dHVyZVR5cGUgPSB0ZXh0dXJlVHlwZSB8fCBnbC5GTE9BVDtcbiAgfVxuICBlbmNvZGUoc3JjOiBGbG9hdDMyQXJyYXksIHRleHR1cmVTaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUge1xuICAgIGxldCBkZXN0ID0gc3JjO1xuICAgIGlmICh0aGlzLmNoYW5uZWxTaXplID09PSAxKSB7XG4gICAgICBMb2dnZXIudmVyYm9zZSgnRW5jb2RlcicsICdFeHBsb2RpbmcgaW50byBhIGxhcmdlciBhcnJheScpO1xuICAgICAgZGVzdCA9IHRoaXMuYWxsb2NhdGUodGV4dHVyZVNpemUpIGFzIEZsb2F0MzJBcnJheTtcbiAgICAgIHNyYy5mb3JFYWNoKCh2LCBpKSA9PiAoZGVzdFtpICogNF0gPSB2KSk7XG4gICAgfVxuICAgIHJldHVybiBkZXN0O1xuICB9XG4gIGFsbG9jYXRlKHNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoc2l6ZSAqIDQpO1xuICB9XG4gIGRlY29kZShidWZmZXI6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgZGF0YVNpemU6IG51bWJlcik6IEZsb2F0MzJBcnJheSB7XG4gICAgaWYgKHRoaXMuY2hhbm5lbFNpemUgPT09IDEpIHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkRGF0YSA9IChidWZmZXIgYXMgRmxvYXQzMkFycmF5KS5maWx0ZXIoKF92YWx1ZSwgaW5kZXgpID0+IGluZGV4ICUgNCA9PT0gMCkuc3ViYXJyYXkoMCwgZGF0YVNpemUpO1xuICAgICAgcmV0dXJuIGZpbHRlcmVkRGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1ZmZlci5zdWJhcnJheSgwLCBkYXRhU2l6ZSkgYXMgRmxvYXQzMkFycmF5O1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBVaW50OERhdGFFbmNvZGVyIGltcGxlbWVudHMgRGF0YUVuY29kZXIge1xuICBpbnRlcm5hbEZvcm1hdDogbnVtYmVyO1xuICBmb3JtYXQ6IG51bWJlcjtcbiAgdGV4dHVyZVR5cGU6IG51bWJlcjtcbiAgY2hhbm5lbFNpemUgPSA0O1xuICBjb25zdHJ1Y3RvcihnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCBjaGFubmVscyA9IDEpIHtcbiAgICBpZiAoY2hhbm5lbHMgPT09IDEpIHtcbiAgICAgIHRoaXMuaW50ZXJuYWxGb3JtYXQgPSBnbC5BTFBIQTtcbiAgICAgIHRoaXMuZm9ybWF0ID0gZ2wuQUxQSEE7IC8vIG5vdCB0ZXN0ZWRcbiAgICAgIHRoaXMudGV4dHVyZVR5cGUgPSBnbC5VTlNJR05FRF9CWVRFO1xuICAgICAgdGhpcy5jaGFubmVsU2l6ZSA9IGNoYW5uZWxzO1xuICAgIH0gZWxzZSBpZiAoY2hhbm5lbHMgPT09IDQpIHtcbiAgICAgIHRoaXMuaW50ZXJuYWxGb3JtYXQgPSBnbC5SR0JBO1xuICAgICAgdGhpcy5mb3JtYXQgPSBnbC5SR0JBO1xuICAgICAgdGhpcy50ZXh0dXJlVHlwZSA9IGdsLlVOU0lHTkVEX0JZVEU7XG4gICAgICB0aGlzLmNoYW5uZWxTaXplID0gY2hhbm5lbHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBudW1iZXIgb2YgY2hhbm5lbHM6ICR7Y2hhbm5lbHN9YCk7XG4gICAgfVxuICB9XG4gIGVuY29kZShzcmM6IFVpbnQ4QXJyYXksIF90ZXh0dXJlU2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoc3JjLmJ1ZmZlciwgc3JjLmJ5dGVPZmZzZXQsIHNyYy5ieXRlTGVuZ3RoKTtcbiAgfVxuICBhbGxvY2F0ZShzaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheShzaXplICogdGhpcy5jaGFubmVsU2l6ZSk7XG4gIH1cbiAgZGVjb2RlKGJ1ZmZlcjogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCBkYXRhU2l6ZTogbnVtYmVyKTogVWludDhBcnJheSB7XG4gICAgaWYgKGJ1ZmZlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgIHJldHVybiBidWZmZXIuc3ViYXJyYXkoMCwgZGF0YVNpemUpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgYXJyYXkgdHlwZTogJHtidWZmZXIuY29uc3RydWN0b3J9YCk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmltcG9ydCB7IFRleHR1cmVMYXlvdXRTdHJhdGVneSwgV2lkdGhIZWlnaHRQcmVmcyB9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHsgVGV4dHVyZUxheW91dCwgVGV4dHVyZVR5cGUgfSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUgPSAoXG4gIHRleHR1cmVMYXlvdXRTdHJhdGVneTogVGV4dHVyZUxheW91dFN0cmF0ZWd5LFxuICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZSxcbik6IFRleHR1cmVMYXlvdXQgPT4ge1xuICBjb25zdCBjaGFubmVsID0gdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnVucGFja2VkIHx8IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS51bnBhY2tlZFJldmVyc2VkID8gMSA6IDQ7XG4gIGNvbnN0IGlzUGFja2VkID0gdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZDtcbiAgY29uc3QgcmV2ZXJzZVdIID0gdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnVucGFja2VkUmV2ZXJzZWQgfHwgdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZDtcbiAgY29uc3QgYnJlYWtBeGlzID0gdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24gPyBzaGFwZS5sZW5ndGggLSAxIDogdW5kZWZpbmVkO1xuICBjb25zdCB1bnBhY2tlZFNoYXBlID1cbiAgICB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvblxuICAgICAgPyBzaGFwZS5tYXAoKGQsIGkpID0+IChpID09PSBzaGFwZS5sZW5ndGggLSAxID8gZCAqIDQgOiBkKSlcbiAgICAgIDogdW5kZWZpbmVkO1xuICByZXR1cm4gY3JlYXRlVGV4dHVyZUxheW91dEZyb21TaGFwZSh0ZXh0dXJlTGF5b3V0U3RyYXRlZ3ksIHNoYXBlLCBjaGFubmVsLCB1bnBhY2tlZFNoYXBlLCB7XG4gICAgaXNQYWNrZWQsXG4gICAgcmV2ZXJzZVdILFxuICAgIGJyZWFrQXhpcyxcbiAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0ID0gKFxuICB0ZXh0dXJlTGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSxcbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUsXG4pOiBbbnVtYmVyLCBudW1iZXJdID0+IHtcbiAgY29uc3QgbGF5b3V0ID0gY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZSh0ZXh0dXJlTGF5b3V0U3RyYXRlZ3ksIHNoYXBlLCB0ZXh0dXJlVHlwZSk7XG4gIHJldHVybiBbbGF5b3V0LndpZHRoLCBsYXlvdXQuaGVpZ2h0XTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgVGV4dHVyZUxheW91dCBvYmplY3QgZnJvbSBzaGFwZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUgPSAoXG4gIHRleHR1cmVMYXlvdXRTdHJhdGVneTogVGV4dHVyZUxheW91dFN0cmF0ZWd5LFxuICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGNoYW5uZWxzOiAxIHwgNCA9IDEsXG4gIHVucGFja2VkU2hhcGU/OiByZWFkb25seSBudW1iZXJbXSxcbiAgcHJlZnM/OiBXaWR0aEhlaWdodFByZWZzLFxuKTogVGV4dHVyZUxheW91dCA9PiB7XG4gIGNvbnN0IGlzUGFja2VkID0gISEocHJlZnMgJiYgcHJlZnMuaXNQYWNrZWQpO1xuICBjb25zdCBbd2lkdGgsIGhlaWdodF0gPSB0ZXh0dXJlTGF5b3V0U3RyYXRlZ3kuY29tcHV0ZVRleHR1cmVXSChpc1BhY2tlZCA/IHVucGFja2VkU2hhcGUgfHwgc2hhcGUgOiBzaGFwZSwgcHJlZnMpO1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICBsZXQgaW5mZXJyZWREaW1zID0gc2hhcGUuc2xpY2UoMCk7XG4gIGlmIChyYW5rID09PSAwKSB7XG4gICAgaW5mZXJyZWREaW1zID0gWzFdO1xuICB9XG4gIGlmIChjaGFubmVscyA9PT0gMSkge1xuICAgIC8vIHVucGFja2VkU2hhcGUgd2lsbCB0YWtlIGBzaGFwZWAgYW5kIG5vdCBgaW5mZXJyZWREaW1zYCBzbyBhcyB0byBjcmVhdGUgYSBzY2FsYXIgVGVuc29yIGlmIG5lZWQgYmVcbiAgICB1bnBhY2tlZFNoYXBlID0gc2hhcGU7XG4gIH0gZWxzZSBpZiAoaXNQYWNrZWQpIHtcbiAgICBpZiAoY2hhbm5lbHMgIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYSBwYWNrZWQgdGV4dHVyZSBtdXN0IGJlIDQtY2hhbm5lbCcpO1xuICAgIH1cbiAgICB1bnBhY2tlZFNoYXBlID0gc2hhcGU7XG4gICAgaWYgKHJhbmsgPiAwKSB7XG4gICAgICBpbmZlcnJlZERpbXNbcmFuayAtIDFdID0gTWF0aC5jZWlsKGluZmVycmVkRGltc1tyYW5rIC0gMV0gLyAyKTtcbiAgICB9XG4gICAgaWYgKHJhbmsgPiAxKSB7XG4gICAgICBpbmZlcnJlZERpbXNbcmFuayAtIDJdID0gTWF0aC5jZWlsKGluZmVycmVkRGltc1tyYW5rIC0gMl0gLyAyKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIXVucGFja2VkU2hhcGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1VucGFja2VkIHNoYXBlIGlzIG5lZWRlZCB3aGVuIHVzaW5nIGNoYW5uZWxzID4gMScpO1xuICB9XG4gIHJldHVybiB7XG4gICAgd2lkdGgsXG4gICAgaGVpZ2h0LFxuICAgIGNoYW5uZWxzLFxuICAgIGlzUGFja2VkLFxuICAgIHNoYXBlOiBpbmZlcnJlZERpbXMsXG4gICAgc3RyaWRlczogU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKGluZmVycmVkRGltcyksXG4gICAgdW5wYWNrZWRTaGFwZSxcbiAgICByZXZlcnNlZFdIOiBwcmVmcyAmJiBwcmVmcy5yZXZlcnNlV0gsXG4gIH07XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vLi4vYmFja2VuZCc7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcblxuaW1wb3J0IHsgY3JlYXRlUGFja1Byb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9vcHMvcGFjayc7XG5pbXBvcnQgeyBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtSW5mb0xvYWRlciwgaXNSZXNoYXBlQ2hlYXAsIHByb2Nlc3NEaW1zM0QgfSBmcm9tICcuL29wcy9yZXNoYXBlLXBhY2tlZCc7XG5pbXBvcnQgeyBlbmNvZGVBc1VpbnQ4IH0gZnJvbSAnLi9vcHMvdWludDgtZW5jb2RlJztcbmltcG9ydCB7IGNyZWF0ZVVucGFja1Byb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9vcHMvdW5wYWNrJztcbmltcG9ydCB7IFdlYkdMU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuL3Nlc3Npb24taGFuZGxlcic7XG5pbXBvcnQgeyBFbmNvZGVyVXNhZ2UgfSBmcm9tICcuL3RleHR1cmUtZGF0YS1lbmNvZGVyJztcbmltcG9ydCB7XG4gIGNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodCxcbiAgY3JlYXRlVGV4dHVyZUxheW91dEZyb21TaGFwZSxcbiAgY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZSxcbn0gZnJvbSAnLi90ZXh0dXJlLWxheW91dCc7XG5pbXBvcnQgeyBBcnRpZmFjdCwgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBUZXh0dXJlRGF0YSwgVGV4dHVyZUxheW91dCwgVGV4dHVyZVR5cGUgfSBmcm9tICcuL3R5cGVzJztcblxuY29uc3QgZ2V0UHJvZ3JhbUluZm9VbmlxdWVLZXkgPSAoXG4gIHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mbyB8IFByb2dyYW1JbmZvTG9hZGVyLFxuICBpbnB1dFRleHR1cmVEYXRhczogVGV4dHVyZURhdGFbXSxcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGlucHV0cyA9IGlucHV0VGV4dHVyZURhdGFzXG4gICAgLm1hcCgodGV4dHVyZSkgPT4gYCR7dGV4dHVyZS51bnBhY2tlZFNoYXBlLmpvaW4oJywnKX07JHt0ZXh0dXJlLndpZHRofXgke3RleHR1cmUuaGVpZ2h0fWApXG4gICAgLmpvaW4oJ18nKTtcbiAgbGV0IGtleSA9IHByb2dyYW1JbmZvLm5hbWU7XG4gIGlmIChwcm9ncmFtSW5mby5jYWNoZUhpbnQpIHtcbiAgICBrZXkgKz0gJ1snICsgcHJvZ3JhbUluZm8uY2FjaGVIaW50ICsgJ10nO1xuICB9XG4gIGtleSArPSAnOicgKyBpbnB1dHM7XG4gIHJldHVybiBrZXk7XG59O1xuXG5leHBvcnQgY2xhc3MgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIGltcGxlbWVudHMgSW5mZXJlbmNlSGFuZGxlciB7XG4gIHByaXZhdGUgcGFja2VkVGV4dHVyZURhdGFDYWNoZTogTWFwPFRlbnNvci5JZCwgVGV4dHVyZURhdGE+O1xuICBwcml2YXRlIHVucGFja2VkVGV4dHVyZURhdGFDYWNoZTogTWFwPFRlbnNvci5JZCwgVGV4dHVyZURhdGE+O1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgc2Vzc2lvbjogV2ViR0xTZXNzaW9uSGFuZGxlcikge1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyBbd2lkdGgsIGhlaWdodF1cbiAgICovXG4gIGNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZSk6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIHJldHVybiBjYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQodGhpcy5zZXNzaW9uLmxheW91dFN0cmF0ZWd5LCBzaGFwZSwgdGV4dHVyZVR5cGUpO1xuICB9XG5cbiAgZXhlY3V0ZVByb2dyYW0ocHJvZ3JhbTogUHJvZ3JhbUluZm8gfCBQcm9ncmFtSW5mb0xvYWRlciwgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSk6IFRleHR1cmVEYXRhIHtcbiAgICBpZiAoaW5wdXRzLmxlbmd0aCA8IHByb2dyYW0uaW5wdXROYW1lcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgc2l6ZSBtdXN0bid0IGJlIGxlc3MgdGhhbiAke3Byb2dyYW0uaW5wdXROYW1lcy5sZW5ndGh9LmApO1xuICAgIH1cbiAgICBpZiAocHJvZ3JhbS5pbnB1dE5hbWVzLmxlbmd0aCAhPT0gcHJvZ3JhbS5pbnB1dFR5cGVzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCBuYW1lcyBzaXplIGRvZXMgbm90IG1hdGNoIGlucHV0IHR5cGVzJyk7XG4gICAgfVxuXG4gICAgLy8gY3JlYXRlIHRleHR1cmUgaW5mbyBmb3IgaW5wdXRcbiAgICBjb25zdCBpbnB1dFRleHR1cmVEYXRhczogVGV4dHVyZURhdGFbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvZ3JhbS5pbnB1dE5hbWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICBpbnB1dFRleHR1cmVEYXRhc1tpXSA9IHRoaXMuZ2V0T3JDcmVhdGVUZXh0dXJlRGF0YShpbnB1dHNbaV0sIHByb2dyYW0uaW5wdXRUeXBlc1tpXSk7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5ID0gZ2V0UHJvZ3JhbUluZm9VbmlxdWVLZXkocHJvZ3JhbSwgaW5wdXRUZXh0dXJlRGF0YXMpO1xuICAgIGxldCBhcnRpZmFjdCA9IHRoaXMuc2Vzc2lvbi5wcm9ncmFtTWFuYWdlci5nZXRBcnRpZmFjdChrZXkpO1xuICAgIGNvbnN0IHByb2dyYW1JbmZvID0gYXJ0aWZhY3RcbiAgICAgID8gYXJ0aWZhY3QucHJvZ3JhbUluZm9cbiAgICAgIDogdHlwZW9mIChwcm9ncmFtIGFzIFByb2dyYW1JbmZvTG9hZGVyKS5nZXQgPT09ICdmdW5jdGlvbidcbiAgICAgICAgPyAocHJvZ3JhbSBhcyBQcm9ncmFtSW5mb0xvYWRlcikuZ2V0KClcbiAgICAgICAgOiAocHJvZ3JhbSBhcyBQcm9ncmFtSW5mbyk7XG5cbiAgICAvLyBjcmVhdGUgdGV4dHVyZSBpbmZvIGZvciBvdXRwdXRcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlTGF5b3V0ID0gY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZShcbiAgICAgIHRoaXMuc2Vzc2lvbi5sYXlvdXRTdHJhdGVneSxcbiAgICAgIHByb2dyYW1JbmZvLm91dHB1dC5kaW1zLFxuICAgICAgcHJvZ3JhbUluZm8ub3V0cHV0LnRleHR1cmVUeXBlLFxuICAgICk7XG4gICAgY29uc3Qgb3V0cHV0VGV4dHVyZURhdGEgPSB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhKG91dHB1dFRleHR1cmVMYXlvdXQsIHByb2dyYW1JbmZvLm91dHB1dC50eXBlKTtcblxuICAgIGlmICghYXJ0aWZhY3QpIHtcbiAgICAgIGFydGlmYWN0ID0gdGhpcy5zZXNzaW9uLnByb2dyYW1NYW5hZ2VyLmJ1aWxkKHByb2dyYW1JbmZvLCBpbnB1dFRleHR1cmVEYXRhcywgb3V0cHV0VGV4dHVyZURhdGEpO1xuICAgICAgdGhpcy5zZXNzaW9uLnByb2dyYW1NYW5hZ2VyLnNldEFydGlmYWN0KGtleSwgYXJ0aWZhY3QpO1xuICAgIH1cblxuICAgIHRoaXMucnVuUHJvZ3JhbShhcnRpZmFjdCwgaW5wdXRUZXh0dXJlRGF0YXMsIG91dHB1dFRleHR1cmVEYXRhKTtcbiAgICByZXR1cm4gb3V0cHV0VGV4dHVyZURhdGE7XG4gIH1cblxuICBydW4ocHJvZ3JhbTogUHJvZ3JhbUluZm9Mb2FkZXIsIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10pOiBUZW5zb3Ige1xuICAgIGNvbnN0IG91dHB1dFRleHR1cmVEYXRhID0gdGhpcy5leGVjdXRlUHJvZ3JhbShwcm9ncmFtLCBpbnB1dHMpO1xuICAgIHJldHVybiBvdXRwdXRUZXh0dXJlRGF0YS50ZW5zb3I7XG4gIH1cblxuICBwcml2YXRlIHJ1blByb2dyYW0oYXJ0aWZhY3Q6IEFydGlmYWN0LCBpbnB1dHM6IFRleHR1cmVEYXRhW10sIG91dHB1dDogVGV4dHVyZURhdGEpOiB2b2lkIHtcbiAgICAvLyBpbnB1dCBzaG91bGQgbWF0Y2hcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7ICsraSkge1xuICAgICAgaWYgKCEhaW5wdXRzW2ldLmlzUGFja2VkICE9PSAoYXJ0aWZhY3QucHJvZ3JhbUluZm8uaW5wdXRUeXBlc1tpXSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0WyR7aX1dIHByb3BlcnR5IHBhY2tlZCBpbmNvbnNpc3RlbnRgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBvdXRwdXQgc2hvdWxkIG1hdGNoXG4gICAgaWYgKCEhb3V0cHV0LmlzUGFja2VkICE9PSAoYXJ0aWZhY3QucHJvZ3JhbUluZm8ub3V0cHV0LnRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ291dHB1dCBwcm9wZXJ0eSBwYWNrZWQgaW5jb25zaXN0ZW50Jyk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXNzaW9uLnByb2dyYW1NYW5hZ2VyLnJ1bihhcnRpZmFjdCwgaW5wdXRzLCBvdXRwdXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIFRleHR1cmVEYXRhIG9iamVjdCBmcm9tIGEgdGVuc29yLlxuICAgKiBVc2FnZSA9IEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5LlxuICAgKiBJZiBhIHJlbGF0ZWQgdGV4dHVyZSBkYXRhIGlzIGZvdW5kIGluIGNhY2hlLCByZXR1cm5zIGl0O1xuICAgKiBPdGhlcndpc2U6XG4gICAqICAgQ3JlYXRlcyBhIG5ldyB0ZXh0dXJlIGxheW91dCBpZiBub3QgcHJvdmlkZWQ7XG4gICAqICAgQ3JlYXRlcyBXZWJHTFRleHR1cmUgd2l0aCB0aGUgbGF5b3V0O1xuICAgKiAgIFVwbG9hZCB0ZW5zb3IgZGF0YSB0byB0aGUgdGV4dHVyZTtcbiAgICogICBDcmVhdGVzIGEgdGV4dHVyZSBkYXRhIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIHRlbnNvci5cbiAgICogQHBhcmFtIHRlbnNvciB0aGUgdGVuc29yIHdpdGggZGF0YSB0byB1cGxvYWRcbiAgICovXG4gIHByaXZhdGUgZ2V0T3JDcmVhdGVUZXh0dXJlRGF0YSh0ZW5zb3I6IFRlbnNvciwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlKSB7XG4gICAgbGV0IHRkID0gdGhpcy5nZXRUZXh0dXJlRGF0YSh0ZW5zb3IuZGF0YUlkLCB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKTtcblxuICAgIGlmICghdGQpIHtcbiAgICAgIC8vIGNoZWNrIGlmIHdlIGhhdmUgdGV4dHVyZSBkYXRhIGluIGRpZmZlcmVudCB0eXBlXG4gICAgICB0ZCA9IHRoaXMuZ2V0VGV4dHVyZURhdGEodGVuc29yLmRhdGFJZCwgdGV4dHVyZVR5cGUgIT09IFRleHR1cmVUeXBlLnBhY2tlZCk7XG4gICAgICBpZiAodGQpIHtcbiAgICAgICAgaWYgKHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5wYWNrKHRkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy51bnBhY2sodGQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF0ZCkge1xuICAgICAgY29uc3QgbGF5b3V0ID0gY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZSh0aGlzLnNlc3Npb24ubGF5b3V0U3RyYXRlZ3ksIHRlbnNvci5kaW1zLCB0ZXh0dXJlVHlwZSk7XG5cbiAgICAgIGlmICh0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbikge1xuICAgICAgICBjb25zdCBncm91cCA9IDE7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxzID0gNDtcbiAgICAgICAgY29uc3Qgc2hhcGUgPSB0ZW5zb3IuZGltcztcbiAgICAgICAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gNCkge1xuICAgICAgICAgIC8vIHByZS1wcm9jZXNzaW5nIGZvciBrZXJuZWwgZGF0YSBvZiBDb252LlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gVE9ETzogY3VycmVudGx5IHRoaXMgaXMgYSBoYWNraW5nIHRvIG92ZXJ3cml0ZSBDb252J3Mgd2VpZ2h0LiBUaGUgY29ycmVjdCB3YXkgdG8gZG8gdGhpcyBzaG91bGQgYmU6XG4gICAgICAgICAgLy8gMS4gaW1wbGVtZW50IHRleHR1cmUgYmFzZWQgY29uc3QtZm9sZGluZ1xuICAgICAgICAgIC8vIDIuIGNyZWF0ZSBhIFdlYkdMIHByb2dyYW0gXCJwcmVwcm9jZXNzQ29udldlaWdodFwiIHRvIGRvIHRoZSBzYW1lIHdvcmsgYXMgYmVsb3dcbiAgICAgICAgICAvLyAzLiBydW4gdGhlIHByb2dyYW0gYmVmb3JlIGRvdFByb2R1Y3QuXG4gICAgICAgICAgLy9cbiAgICAgICAgICBjb25zdCBhZGp1c3RlZEtlcm5lbFNoYXBlID0gW3NoYXBlWzBdLCBNYXRoLmNlaWwoKHNoYXBlWzFdICogc2hhcGVbMl0gKiBzaGFwZVszXSkgLyBjaGFubmVscyldO1xuICAgICAgICAgIGNvbnN0IGFkanVzdGVkTGF5b3V0ID0gY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZShcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5sYXlvdXRTdHJhdGVneSxcbiAgICAgICAgICAgIGFkanVzdGVkS2VybmVsU2hhcGUsXG4gICAgICAgICAgICB0ZXh0dXJlVHlwZSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGxldCBidWZmZXIgPSB0ZW5zb3IubnVtYmVyRGF0YTtcbiAgICAgICAgICBpZiAoKHNoYXBlWzFdICogc2hhcGVbMl0gKiBzaGFwZVszXSkgJSBjaGFubmVscyAhPT0gMCkge1xuICAgICAgICAgICAgY29uc3QgbnVtRmVhdHVyZU1hcHMgPSBzaGFwZVswXTtcbiAgICAgICAgICAgIGNvbnN0IG9sZFJvd1NpemUgPSBzaGFwZVsxXSAqIHNoYXBlWzJdICogc2hhcGVbM107XG4gICAgICAgICAgICBjb25zdCBuZXdSb3dTaXplID0gTWF0aC5jZWlsKChvbGRSb3dTaXplICogZ3JvdXApIC8gY2hhbm5lbHMpICogY2hhbm5lbHM7XG4gICAgICAgICAgICBjb25zdCBuZXdTaXplID0gbnVtRmVhdHVyZU1hcHMgKiBuZXdSb3dTaXplO1xuICAgICAgICAgICAgYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShuZXdTaXplKTtcbiAgICAgICAgICAgIGZvciAobGV0IGYgPSAwOyBmIDwgbnVtRmVhdHVyZU1hcHM7ICsrZikge1xuICAgICAgICAgICAgICBjb25zdCBvbGRPZmZzZXQgPSBmICogb2xkUm93U2l6ZTtcbiAgICAgICAgICAgICAgY29uc3QgbmV3T2Zmc2V0ID0gZiAqIG5ld1Jvd1NpemUgKyAoZiAlIGdyb3VwKSAqIG9sZFJvd1NpemU7XG4gICAgICAgICAgICAgIGJ1ZmZlci5zZXQodGVuc29yLm51bWJlckRhdGEuc3ViYXJyYXkob2xkT2Zmc2V0LCBvbGRPZmZzZXQgKyBvbGRSb3dTaXplKSwgbmV3T2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlVGV4dHVyZURhdGEoYWRqdXN0ZWRMYXlvdXQsIHRlbnNvci50eXBlLCBidWZmZXIsIHRlbnNvciwgRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKSB7XG4gICAgICAgIGNvbnN0IHVucGFja2VkVGV4dHVyZUxheW91dCA9IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUodGhpcy5zZXNzaW9uLmxheW91dFN0cmF0ZWd5LCB0ZW5zb3IuZGltcywgMSwgW10sIHtcbiAgICAgICAgICByZXZlcnNlV0g6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB1bnBhY2tlZFRleHR1cmVEYXRhID0gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YShcbiAgICAgICAgICB1bnBhY2tlZFRleHR1cmVMYXlvdXQsXG4gICAgICAgICAgdGVuc29yLnR5cGUsXG4gICAgICAgICAgdGVuc29yLm51bWJlckRhdGEsXG4gICAgICAgICAgdGVuc29yLFxuICAgICAgICAgIEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5LFxuICAgICAgICApO1xuICAgICAgICB0ZCA9IHRoaXMucGFjayh1bnBhY2tlZFRleHR1cmVEYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRkID0gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YShsYXlvdXQsIHRlbnNvci50eXBlLCB0ZW5zb3IubnVtYmVyRGF0YSwgdGVuc29yLCBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0ZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBUZXh0dXJlRGF0YSBvYmplY3QgdXNpbmcgdGhlIGdpdmVuIGRhdGEgYW5kIGJpbmQgdG8gdGhlIGdpdmVuIHRlbnNvci5cbiAgICogVXNhZ2UgPSBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seS5cbiAgICogTk9URTogdGhpcyBmdW5jdGlvbiBpcyBhIGhhY2sgZm9yIENvbnYgaW1wbGVtZW50YXRpb24uIHNob3VsZCByZW1vdmUgdGhpcyBmdW5jdGlvbiwgYWZ0ZXIgcmV3cml0aW5nIENvbnZcbiAgICogaW1wbGVtZW50YXRpb24gYnkgR3JhcGguVHJhbnNmb3JtZXJcbiAgICogQHBhcmFtIGRhdGFUeXBlIHRoZSB0ZW5zb3IgZGF0YSB0eXBlXG4gICAqIEBwYXJhbSBkYXRhIHRoZSBhY3R1YWwgZGF0YSB0byB1cGxvYWRcbiAgICogQHBhcmFtIHRlbnNvciB0aGUgdGVuc29yIHRvIGJpbmQuIHRlbnNvcidzIGRhdGEgaXMgaWdub3JlZC5cbiAgICovXG4gIGNyZWF0ZVRleHR1cmVEYXRhRnJvbUxheW91dEJpbmRUZW5zb3IoXG4gICAgbGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsXG4gICAgZGF0YTogVGVuc29yLk51bWJlclR5cGUsXG4gICAgdGVuc29yOiBUZW5zb3IsXG4gICk6IFRleHR1cmVEYXRhIHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YShsYXlvdXQsIGRhdGFUeXBlLCBkYXRhLCB0ZW5zb3IsIEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVGV4dHVyZURhdGEoXG4gICAgbGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsXG4gICAgZGF0YT86IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHRlbnNvcj86IFRlbnNvcixcbiAgICB1c2FnZT86IEVuY29kZXJVc2FnZSxcbiAgKTogVGV4dHVyZURhdGEge1xuICAgIExvZ2dlci52ZXJib3NlKCdJbmZlcmVuY2VIYW5kbGVyJywgYENyZWF0aW5nIFRleHR1cmVEYXRhOiBsYXlvdXQ6WyR7SlNPTi5zdHJpbmdpZnkobGF5b3V0KX1dYCk7XG4gICAgY29uc3QgdGV4dHVyZSA9IHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5jcmVhdGVUZXh0dXJlRnJvbUxheW91dChkYXRhVHlwZSwgbGF5b3V0LCBkYXRhLCB1c2FnZSk7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShsYXlvdXQsIGRhdGFUeXBlLCB0ZXh0dXJlLCB0ZW5zb3IpO1xuICB9XG5cbiAgcmVzaGFwZVVucGFja2VkKGlucHV0OiBUZW5zb3IsIHJlc2hhcGVkRGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3Ige1xuICAgIGNvbnN0IGlucHV0VEQgPSB0aGlzLmdldE9yQ3JlYXRlVGV4dHVyZURhdGEoaW5wdXQsIFRleHR1cmVUeXBlLnVucGFja2VkKTtcbiAgICBjb25zdCBuZXdUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0ge1xuICAgICAgY2hhbm5lbHM6IGlucHV0VEQuY2hhbm5lbHMsXG4gICAgICBoZWlnaHQ6IGlucHV0VEQuaGVpZ2h0LFxuICAgICAgd2lkdGg6IGlucHV0VEQud2lkdGgsXG4gICAgICAvLyBoYW5kbGUgcmVzaGFwaW5nIGludG8gc2NhbGFyIFRlbnNvcnNcbiAgICAgIHNoYXBlOiByZXNoYXBlZERpbXMubGVuZ3RoICE9PSAwID8gcmVzaGFwZWREaW1zIDogWzFdLFxuICAgICAgc3RyaWRlczogU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKHJlc2hhcGVkRGltcyksXG4gICAgICB1bnBhY2tlZFNoYXBlOiByZXNoYXBlZERpbXMsXG4gICAgfTtcbiAgICBjb25zdCBuZXdUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShuZXdUZXh0dXJlTGF5b3V0LCBpbnB1dC50eXBlLCBpbnB1dFRELnRleHR1cmUpO1xuICAgIHJldHVybiBuZXdUZXh0dXJlRGF0YS50ZW5zb3I7XG4gIH1cblxuICByZXNoYXBlUGFja2VkKGlucHV0OiBUZW5zb3IsIHJlc2hhcGVkRGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3Ige1xuICAgIGNvbnN0IGlucHV0VEQgPSB0aGlzLmdldE9yQ3JlYXRlVGV4dHVyZURhdGEoaW5wdXQsIFRleHR1cmVUeXBlLnBhY2tlZCk7XG5cbiAgICAvLyBjaGVjayBpZiB0aGUgcmVzaGFwZSBpcyAnY2hlYXAnXG4gICAgaWYgKGlzUmVzaGFwZUNoZWFwKGlucHV0LmRpbXMsIHJlc2hhcGVkRGltcykpIHtcbiAgICAgIGNvbnN0IG5ld1RleHR1cmVMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSB7XG4gICAgICAgIGNoYW5uZWxzOiBpbnB1dFRELmNoYW5uZWxzLFxuICAgICAgICBoZWlnaHQ6IGlucHV0VEQuaGVpZ2h0LFxuICAgICAgICB3aWR0aDogaW5wdXRURC53aWR0aCxcbiAgICAgICAgLy8gaGFuZGxlIHJlc2hhcGluZyBpbnRvIHNjYWxhciBUZW5zb3JzXG4gICAgICAgIHNoYXBlOiByZXNoYXBlZERpbXMubGVuZ3RoICE9PSAwID8gcmVzaGFwZWREaW1zIDogWzFdLFxuICAgICAgICBzdHJpZGVzOiBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMocmVzaGFwZWREaW1zKSxcbiAgICAgICAgdW5wYWNrZWRTaGFwZTogcmVzaGFwZWREaW1zLFxuICAgICAgICBpc1BhY2tlZDogdHJ1ZSxcbiAgICAgIH07XG4gICAgICBjb25zdCBuZXdUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShuZXdUZXh0dXJlTGF5b3V0LCBpbnB1dC50eXBlLCBpbnB1dFRELnRleHR1cmUpO1xuICAgICAgcmV0dXJuIG5ld1RleHR1cmVEYXRhLnRlbnNvcjtcbiAgICB9XG5cbiAgICBjb25zdCBzcXVlZXplZElucHV0U2hhcGUgPSBwcm9jZXNzRGltczNEKGlucHV0LmRpbXMpO1xuICAgIGNvbnN0IHNxdWVlemVkT3V0cHV0U2hhcGUgPSBwcm9jZXNzRGltczNEKHJlc2hhcGVkRGltcyk7XG5cbiAgICBjb25zdCBzcXVlZXplZElucHV0VGVuc29yID0gdGhpcy5yZXNoYXBlUGFja2VkKGlucHV0LCBzcXVlZXplZElucHV0U2hhcGUpO1xuICAgIGNvbnN0IHNxdWVlemVkT3V0cHV0VGVuc29yID0gdGhpcy5ydW4oXG4gICAgICBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtSW5mb0xvYWRlcih0aGlzLCBzcXVlZXplZElucHV0VGVuc29yLCBzcXVlZXplZE91dHB1dFNoYXBlKSxcbiAgICAgIFtzcXVlZXplZElucHV0VGVuc29yXSxcbiAgICApO1xuICAgIGNvbnN0IG91dHB1dFRlbnNvciA9IHRoaXMucmVzaGFwZVBhY2tlZChzcXVlZXplZE91dHB1dFRlbnNvciwgcmVzaGFwZWREaW1zKTtcbiAgICByZXR1cm4gb3V0cHV0VGVuc29yO1xuICB9XG5cbiAgY2FzdChpbnB1dDogVGVuc29yLCB0eXBlOiBUZW5zb3IuRGF0YVR5cGUpOiBUZW5zb3Ige1xuICAgIGNvbnN0IGlucHV0VEQgPSB0aGlzLmdldE9yQ3JlYXRlVGV4dHVyZURhdGEoaW5wdXQsIFRleHR1cmVUeXBlLnVucGFja2VkKTtcbiAgICBjb25zdCBuZXdUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShpbnB1dFREIGFzIFRleHR1cmVMYXlvdXQsIHR5cGUsIGlucHV0VEQudGV4dHVyZSk7XG4gICAgcmV0dXJuIG5ld1RleHR1cmVEYXRhLnRlbnNvcjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShcbiAgICBsYXlvdXQ6IFRleHR1cmVMYXlvdXQsXG4gICAgZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSxcbiAgICB0ZXh0dXJlOiBXZWJHTFRleHR1cmUsXG4gICAgdGVuc29yPzogVGVuc29yLFxuICAgIHRlbnNvcklkPzogVGVuc29yLklkLFxuICApIHtcbiAgICBjb25zdCB0ZXh0dXJlRGF0YTogVGV4dHVyZURhdGEgPSB7XG4gICAgICAuLi5sYXlvdXQsXG4gICAgICB0ZW5zb3I6XG4gICAgICAgIHRlbnNvciB8fFxuICAgICAgICBuZXcgVGVuc29yKFxuICAgICAgICAgIGxheW91dC51bnBhY2tlZFNoYXBlLFxuICAgICAgICAgIGRhdGFUeXBlLFxuICAgICAgICAgIChfaWQ6IFRlbnNvci5JZCkgPT4gdGhpcy5yZWFkVGV4dHVyZSh0ZXh0dXJlRGF0YSksXG4gICAgICAgICAgYXN5bmMgKF9pZDogVGVuc29yLklkKSA9PiB0aGlzLnJlYWRUZXh0dXJlQXN5bmModGV4dHVyZURhdGEpLFxuICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICB0ZW5zb3JJZCxcbiAgICAgICAgKSxcbiAgICAgIHRleHR1cmUsXG4gICAgfTtcbiAgICB0aGlzLnNldFRleHR1cmVEYXRhKHRleHR1cmVEYXRhLnRlbnNvci5kYXRhSWQsIHRleHR1cmVEYXRhLCBsYXlvdXQuaXNQYWNrZWQpO1xuICAgIHJldHVybiB0ZXh0dXJlRGF0YTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0VGV4dHVyZURhdGEodGVuc29ySWQ6IFRlbnNvci5JZCwgaXNQYWNrZWQgPSBmYWxzZSk6IFRleHR1cmVEYXRhIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIodGVuc29ySWQpXG4gICAgICA/IHRoaXMuc2Vzc2lvbi5nZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZCwgaXNQYWNrZWQpXG4gICAgICA6IGlzUGFja2VkXG4gICAgICAgID8gdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmdldCh0ZW5zb3JJZClcbiAgICAgICAgOiB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZS5nZXQodGVuc29ySWQpO1xuICB9XG4gIHNldFRleHR1cmVEYXRhKHRlbnNvcklkOiBUZW5zb3IuSWQsIHRkOiBUZXh0dXJlRGF0YSwgaXNQYWNrZWQgPSBmYWxzZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNlc3Npb24uaXNJbml0aWFsaXplcih0ZW5zb3JJZCkpIHtcbiAgICAgIHRoaXMuc2Vzc2lvbi5zZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZCwgdGQsIGlzUGFja2VkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgKGlzUGFja2VkID8gdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlIDogdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUpLnNldCh0ZW5zb3JJZCwgdGQpO1xuICAgIH1cbiAgfVxuICBpc1RleHR1cmVMYXlvdXRDYWNoZWQodGVuc29yOiBUZW5zb3IsIGlzUGFja2VkID0gZmFsc2UpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmdldFRleHR1cmVEYXRhKHRlbnNvci5kYXRhSWQsIGlzUGFja2VkKTtcbiAgfVxuXG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLmNsZWFyQWN0aXZlVGV4dHVyZXMoKTtcbiAgICB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZm9yRWFjaCgodGQpID0+IHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCkpO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZS5mb3JFYWNoKCh0ZCkgPT4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlbGVhc2VUZXh0dXJlKHRkKSk7XG4gICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gIH1cblxuICByZWFkVGV4dHVyZSh0ZXh0dXJlRGF0YTogVGV4dHVyZURhdGEpOiBUZW5zb3IuTnVtYmVyVHlwZSB7XG4gICAgaWYgKHRleHR1cmVEYXRhLmlzUGFja2VkKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWFkVGV4dHVyZSh0aGlzLnVucGFjayh0ZXh0dXJlRGF0YSkpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC5pc0Zsb2F0MzJEb3dubG9hZFN1cHBvcnRlZCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWFkVWludDhUZXh0dXJlQXNGbG9hdChlbmNvZGVBc1VpbnQ4KHRoaXMsIHRleHR1cmVEYXRhKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIucmVhZFRleHR1cmUodGV4dHVyZURhdGEsIHRleHR1cmVEYXRhLnRlbnNvci50eXBlLCB0ZXh0dXJlRGF0YS5jaGFubmVscyk7XG4gIH1cblxuICBhc3luYyByZWFkVGV4dHVyZUFzeW5jKHRleHR1cmVEYXRhOiBUZXh0dXJlRGF0YSk6IFByb21pc2U8VGVuc29yLk51bWJlclR5cGU+IHtcbiAgICBpZiAodGV4dHVyZURhdGEuaXNQYWNrZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlYWRUZXh0dXJlQXN5bmModGhpcy51bnBhY2sodGV4dHVyZURhdGEpKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQuaXNGbG9hdDMyRG93bmxvYWRTdXBwb3J0ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIucmVhZFVpbnQ4VGV4dHVyZUFzRmxvYXQoZW5jb2RlQXNVaW50OCh0aGlzLCB0ZXh0dXJlRGF0YSkpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlYWRUZXh0dXJlQXN5bmModGV4dHVyZURhdGEsIHRleHR1cmVEYXRhLnRlbnNvci50eXBlLCB0ZXh0dXJlRGF0YS5jaGFubmVscyk7XG4gIH1cblxuICBwYWNrKGlucHV0OiBUZXh0dXJlRGF0YSk6IFRleHR1cmVEYXRhIHtcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlRGF0YSA9IHRoaXMuZXhlY3V0ZVByb2dyYW0oY3JlYXRlUGFja1Byb2dyYW1JbmZvTG9hZGVyKHRoaXMsIGlucHV0LnRlbnNvciksIFtpbnB1dC50ZW5zb3JdKTtcbiAgICByZXR1cm4gb3V0cHV0VGV4dHVyZURhdGE7XG4gIH1cblxuICB1bnBhY2soaW5wdXQ6IFRleHR1cmVEYXRhKTogVGV4dHVyZURhdGEge1xuICAgIGNvbnN0IG91dHB1dFRleHR1cmVEYXRhID0gdGhpcy5leGVjdXRlUHJvZ3JhbShjcmVhdGVVbnBhY2tQcm9ncmFtSW5mb0xvYWRlcih0aGlzLCBpbnB1dC50ZW5zb3IpLCBbaW5wdXQudGVuc29yXSk7XG4gICAgcmV0dXJuIG91dHB1dFRleHR1cmVEYXRhO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmNsYXNzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleUltcGwge1xuICBjb25zdHJ1Y3RvcihhdHRyaWJ1dGU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSB7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCBhdHRyaWJ1dGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBrZXk6IHN0cmluZztcbiAgcHVibGljIGdldCBjYWNoZUtleSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5rZXkpIHtcbiAgICAgIHRoaXMua2V5ID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGhpcylcbiAgICAgICAgLnNvcnQoKVxuICAgICAgICAubWFwKChuYW1lKSA9PiBgJHsodGhpcyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbbmFtZV19YClcbiAgICAgICAgLmpvaW4oJzsnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMua2V5O1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgY2FjaGVLZXk6IHN0cmluZztcbn1cblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSA9IDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+KFxuICBhdHRyaWJ1dGU6IFQsXG4pOiBUICYgQXR0cmlidXRlV2l0aENhY2hlS2V5ID0+IG5ldyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXlJbXBsKGF0dHJpYnV0ZSkgYXMgdW5rbm93biBhcyBUICYgQXR0cmlidXRlV2l0aENhY2hlS2V5O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIGVwc2lsb246IG51bWJlcjtcbiAgbW9tZW50dW06IG51bWJlcjtcbiAgc3BhdGlhbDogbnVtYmVyO1xufVxuXG5jb25zdCBiYXRjaE5vcm1hbGl6YXRpb25Qcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdCYXRjaE5vcm1hbGl6YXRpb24nLFxuICBpbnB1dE5hbWVzOiBbJ0EnLCAnU2NhbGUnLCAnQicsICdNZWFuJywgJ1ZhcmlhbmNlJ10sXG4gIGlucHV0VHlwZXM6IFtcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgXSxcbn07XG5cbmV4cG9ydCBjb25zdCBiYXRjaE5vcm1hbGl6YXRpb246IE9wZXJhdG9ySW1wbGVtZW50YXRpb248QmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4uYmF0Y2hOb3JtYWxpemF0aW9uUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVCYXRjaE5vcm1hbGl6YXRpb25Qcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAgIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGVwc2lsb24gPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2Vwc2lsb24nLCAxZS01KTtcbiAgY29uc3QgbW9tZW50dW0gPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ21vbWVudHVtJywgMC45KTtcbiAgY29uc3Qgc3BhdGlhbCA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3NwYXRpYWwnLCAxKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGVwc2lsb24sIG1vbWVudHVtLCBzcGF0aWFsIH0pO1xufTtcblxuY29uc3QgY3JlYXRlQmF0Y2hOb3JtYWxpemF0aW9uUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCByYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoO1xuICBjb25zdCBbc2NhbGVXaWR0aCwgc2NhbGVIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgaW5wdXRzWzFdLmRpbXMsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICk7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgZmxvYXQgcHJvY2VzcyhpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuICAgIHZlYzIgcG9zaXRpb24gPSBvZmZzZXRUb0Nvb3JkcyhpbmRpY2VzWzFdLCAke3NjYWxlV2lkdGh9LCAke3NjYWxlSGVpZ2h0fSk7XG4gICAgZmxvYXQgc2NhbGUgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oU2NhbGUsIHBvc2l0aW9uKSk7XG4gICAgZmxvYXQgbWVhbiA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShNZWFuLCBwb3NpdGlvbikpO1xuICAgIGZsb2F0IHZhcmlhbmNlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KFZhcmlhbmNlLCBwb3NpdGlvbikpO1xuICAgIGZsb2F0IGIgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQiwgcG9zaXRpb24pKTtcblxuICAgIHJldHVybiBzY2FsZSAqICggKF9BKGluZGljZXMpIC0gbWVhbikgLyBzcXJ0KHZhcmlhbmNlICsgZmxvYXQoJHthdHRyaWJ1dGVzLmVwc2lsb259KSkgKSArIGI7XG4gIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLmJhdGNoTm9ybWFsaXphdGlvblByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW5wdXRzWzBdLmRpbXMsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0JhdGNoTm9ybWFsaXphdGlvbiByZXF1aXJlcyA1IGlucHV0cy4nKTtcbiAgfVxuXG4gIGNvbnN0IFggPSBpbnB1dHNbMF07XG4gIGNvbnN0IHNjYWxlID0gaW5wdXRzWzFdO1xuICBjb25zdCBCID0gaW5wdXRzWzJdO1xuICBjb25zdCBtZWFuID0gaW5wdXRzWzNdO1xuICBjb25zdCB2YXJfID0gaW5wdXRzWzRdO1xuXG4gIC8vIGlucHV0IHNob3VsZCBhdGxlYXN0IGhhdmUgdGhyZWUgZGltZW5zaW9ucyAtIE4sQyxkaW0xLC4uLixkaW1uXG4gIC8vIG90aGVyIGlucHV0cyBjYW4gaGF2ZSBvbmx5IG9uZSBkaW1lbnNpb25zXG4gIGlmIChcbiAgICBYLmRpbXMubGVuZ3RoIDwgMyB8fFxuICAgIHNjYWxlLmRpbXMubGVuZ3RoICE9PSAxIHx8XG4gICAgQi5kaW1zLmxlbmd0aCAhPT0gMSB8fFxuICAgIG1lYW4uZGltcy5sZW5ndGggIT09IDEgfHxcbiAgICB2YXJfLmRpbXMubGVuZ3RoICE9PSAxXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoXG4gICAgc2NhbGUuZGltc1swXSAhPT0gWC5kaW1zWzFdIHx8XG4gICAgQi5kaW1zWzBdICE9PSBYLmRpbXNbMV0gfHxcbiAgICBtZWFuLmRpbXNbMF0gIT09IFguZGltc1sxXSB8fFxuICAgIHZhcl8uZGltc1swXSAhPT0gWC5kaW1zWzFdXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoXG4gICAgKFgudHlwZSAhPT0gJ2Zsb2F0MzInICYmIFgudHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgIChzY2FsZS50eXBlICE9PSAnZmxvYXQzMicgJiYgc2NhbGUudHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgIChCLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBCLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAobWVhbi50eXBlICE9PSAnZmxvYXQzMicgJiYgbWVhbi50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKHZhcl8udHlwZSAhPT0gJ2Zsb2F0MzInICYmIHZhcl8udHlwZSAhPT0gJ2Zsb2F0NjQnKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQgdGVuc29yIHR5cGVzLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZUxheW91dCB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgV2ViR0xDb250ZXh0IH0gZnJvbSAnLi93ZWJnbC1jb250ZXh0JztcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXG5leHBvcnQgZW51bSBGdW5jdGlvblR5cGUge1xuICBWYWx1ZUJhc2VkLFxuICBQb3NpdGlvbmFsLFxufVxuZXhwb3J0IGludGVyZmFjZSBHbHNsRnVuY3Rpb248VCBleHRlbmRzIEZ1bmN0aW9uVHlwZT4ge1xuICBib2R5OiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbiAgdHlwZTogVDtcbn1cbmV4cG9ydCB0eXBlIEdsc2xWYWx1ZUZ1bmN0aW9uID0gR2xzbEZ1bmN0aW9uPEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkPjtcbmV4cG9ydCBpbnRlcmZhY2UgR2xzbFBvc2l0aW9uYWxGdW5jdGlvbiBleHRlbmRzIEdsc2xGdW5jdGlvbjxGdW5jdGlvblR5cGUuUG9zaXRpb25hbD4ge1xuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5leHBvcnQgY2xhc3MgR2xzbENvbnRleHQge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQsXG4gICAgcHVibGljIHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mbyxcbiAgICBwdWJsaWMgaW5wdXRUZXh0dXJlTGF5b3V0czogVGV4dHVyZUxheW91dFtdLFxuICAgIHB1YmxpYyBvdXRwdXRUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICApIHt9XG59XG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgR2xzbExpYiB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBjb250ZXh0OiBHbHNsQ29udGV4dCkge31cbiAgYWJzdHJhY3QgZ2V0RnVuY3Rpb25zKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH07XG4gIGFic3RyYWN0IGdldEN1c3RvbVR5cGVzKCk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9O1xufVxuXG4vLyBhYnN0cmFjdGlvbiB0byByZXByZXNlbnQgYSBHTFNMIGxpYnJhcnkgcm91dGluZSBhbmQgaXQncyBkZXBlbmRlbmNpZXNcbmV4cG9ydCBjbGFzcyBHbHNsTGliUm91dGluZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByb3V0aW5lQm9keTogc3RyaW5nLFxuICAgIHB1YmxpYyBkZXBlbmRlbmNpZXM/OiBzdHJpbmdbXSxcbiAgKSB7fVxufVxuXG4vLyBhYnN0cmFjdGlvbiB0byByZXByZXNlbnQgYSBHTFNMIGxpYnJhcnkgcm91dGluZSBhbmQgaXQncyBkZXBlbmRlbmNpZXMgQVMgR1JBUEggTm9kZXNcbi8vIHRoaXMgbGV2ZWwgb2YgYWJzdHJhY3Rpb24gaXMgdXNlZCB0byB0b3BvbG9naWNhbGx5IHNvcnQgcm91dGluZXMgYmVmb3JlIGZyYWdtZW50IHNoYWRlIGluY2x1c2lvblxuZXhwb3J0IGNsYXNzIEdsc2xMaWJSb3V0aW5lTm9kZSB7XG4gIGRlcGVuZGVuY2llczogR2xzbExpYlJvdXRpbmVOb2RlW107XG4gIHJvdXRpbmVCb2R5OiBzdHJpbmc7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBuYW1lOiBzdHJpbmcsXG4gICAgcm91dGluZUJvZHk/OiBzdHJpbmcsXG4gICAgZGVwZW5kZW5jaWVzPzogR2xzbExpYlJvdXRpbmVOb2RlW10sXG4gICkge1xuICAgIGlmIChkZXBlbmRlbmNpZXMpIHtcbiAgICAgIHRoaXMuZGVwZW5kZW5jaWVzID0gZGVwZW5kZW5jaWVzO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlcGVuZGVuY2llcyA9IFtdO1xuICAgIH1cblxuICAgIGlmIChyb3V0aW5lQm9keSkge1xuICAgICAgdGhpcy5yb3V0aW5lQm9keSA9IHJvdXRpbmVCb2R5O1xuICAgIH1cbiAgfVxuICBhZGREZXBlbmRlbmN5KG5vZGU6IEdsc2xMaWJSb3V0aW5lTm9kZSkge1xuICAgIGlmIChub2RlKSB7XG4gICAgICB0aGlzLmRlcGVuZGVuY2llcy5wdXNoKG5vZGUpO1xuICAgIH1cbiAgfVxufVxuXG4vLyB0b3BvbG9naWNhbGx5IHNvcnQgR0xTTCBsaWJyYXJ5IHJvdXRpbmVzIChncmFwaCBub2RlcyBhYnN0cmFjdGlvbikgYmVmb3JlIHNoYWRlciBzY3JpcHQgaW5jbHVzaW9uXG5leHBvcnQgY2xhc3MgVG9wb2xvZ2ljYWxTb3J0R2xzbFJvdXRpbmVzIHtcbiAgc3RhdGljIHJldHVybk9yZGVyZWROb2Rlcyhub2RlczogR2xzbExpYlJvdXRpbmVOb2RlW10pOiBHbHNsTGliUm91dGluZU5vZGVbXSB7XG4gICAgaWYgKCFub2RlcyB8fCBub2Rlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBpZiAobm9kZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4gbm9kZXM7XG4gICAgfVxuXG4gICAgY29uc3QgY3ljbGVDaGVjayA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IGFscmVhZHlUcmF2ZXJzZWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBjb25zdCByZXN1bHQgPSBuZXcgQXJyYXk8R2xzbExpYlJvdXRpbmVOb2RlPigpO1xuXG4gICAgdGhpcy5jcmVhdGVPcmRlcmVkTm9kZXMobm9kZXMsIGN5Y2xlQ2hlY2ssIGFscmVhZHlUcmF2ZXJzZWQsIHJlc3VsdCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGNyZWF0ZU9yZGVyZWROb2RlcyhcbiAgICBncmFwaE5vZGVzOiBHbHNsTGliUm91dGluZU5vZGVbXSxcbiAgICBjeWNsZUNoZWNrOiBTZXQ8c3RyaW5nPixcbiAgICBhbHJlYWR5VHJhdmVyc2VkOiBTZXQ8c3RyaW5nPixcbiAgICByZXN1bHQ6IEdsc2xMaWJSb3V0aW5lTm9kZVtdLFxuICApIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoTm9kZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHRoaXMuZGZzVHJhdmVyc2UoZ3JhcGhOb2Rlc1tpXSwgY3ljbGVDaGVjaywgYWxyZWFkeVRyYXZlcnNlZCwgcmVzdWx0KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBkZnNUcmF2ZXJzZShcbiAgICByb290OiBHbHNsTGliUm91dGluZU5vZGUsXG4gICAgY3ljbGVDaGVjazogU2V0PHN0cmluZz4sXG4gICAgYWxyZWFkeVRyYXZlcnNlZDogU2V0PHN0cmluZz4sXG4gICAgcmVzdWx0OiBHbHNsTGliUm91dGluZU5vZGVbXSxcbiAgKSB7XG4gICAgLy8gaWYgdGhpcyByb290IGhhcyBhbHJlYWR5IGJlZW4gdHJhdmVyc2VkIHJldHVyblxuICAgIGlmICghcm9vdCB8fCBhbHJlYWR5VHJhdmVyc2VkLmhhcyhyb290Lm5hbWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gY3ljbGljIGRlcGVuZGVuY3kgaGFzIGJlZW4gZGV0ZWN0ZWRcbiAgICBpZiAoY3ljbGVDaGVjay5oYXMocm9vdC5uYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ3ljbGljIGRlcGVuZGVuY3kgZGV0ZWN0ZWQuIENhbid0IHRvcG9sb2dpY2FsbHkgc29ydCByb3V0aW5lcyBuZWVkZWQgZm9yIHNoYWRlci5cIik7XG4gICAgfVxuXG4gICAgLy8gaG9sZCB0aGlzIG5vZGUgdG8gZGV0ZWN0IGN5Y2xlcyBpZiBhbnlcbiAgICBjeWNsZUNoZWNrLmFkZChyb290Lm5hbWUpO1xuXG4gICAgLy8gdHJhdmVyc2UgY2hpbGRyZW4gaW4gYSBkZnMgZmFzaGlvblxuICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IHJvb3QuZGVwZW5kZW5jaWVzO1xuICAgIGlmIChkZXBlbmRlbmNpZXMgJiYgZGVwZW5kZW5jaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVwZW5kZW5jaWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHRoaXMuZGZzVHJhdmVyc2UoZGVwZW5kZW5jaWVzW2ldLCBjeWNsZUNoZWNrLCBhbHJlYWR5VHJhdmVyc2VkLCByZXN1bHQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkZCB0byByZXN1bHQgaG9sZGVyXG4gICAgcmVzdWx0LnB1c2gocm9vdCk7XG5cbiAgICAvLyBtYXJrIHRoaXMgbm9kZSBhcyB0cmF2ZXJzZWQgc28gdGhhdCB3ZSBkb24ndCB0cmF2ZXJzZSBmcm9tIHRoaXMgYWdhaW5cbiAgICBhbHJlYWR5VHJhdmVyc2VkLmFkZChyb290Lm5hbWUpO1xuXG4gICAgLy8gcmVsZWFzZSB0aGUgaG9sZFxuICAgIGN5Y2xlQ2hlY2suZGVsZXRlKHJvb3QubmFtZSk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IEJyb2FkY2FzdFV0aWwsIFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgRnVuY3Rpb25UeXBlLCBHbHNsVmFsdWVGdW5jdGlvbiB9IGZyb20gJy4uL2dsc2wtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQWRkKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdhZGRfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGEgKyBiO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHYxICsgdjI7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsRGl2KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdkaXZfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGEgLyBiO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHYxIC8gdjI7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTXVsKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdtdWxfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGEgKiBiO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHYxICogdjI7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsU3ViKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdzdWJfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGEgLSBiO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHYxIC0gdjI7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsRXF1YWwoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2VxdWFsXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBmbG9hdChhID09IGIpO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHZlYzQoZXF1YWwodjEsIHYyKSk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsR3JlYXRlcigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnZ3JlYXRlcl8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoYSA+IGIpO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHZlYzQoIHYxLnIgPiB2Mi5yICxcbiAgICAgIHYxLmcgPiB2Mi5nLFxuICAgICAgdjEuYiA+IHYyLmIsXG4gICAgICB2MS5hID4gdjIuYSApO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbExlc3MoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2xlc3NfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KGEgPCBiKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2ZWM0KCB2MS5yIDwgdjIuciAsXG4gICAgICAgICAgICAgICAgdjEuZyA8IHYyLmcsXG4gICAgICAgICAgICAgICAgdjEuYiA8IHYyLmIsXG4gICAgICAgICAgICAgICAgdjEuYSA8IHYyLmEgKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xBbmQoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2FuZF8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoIGJvb2woYSkgJiYgYm9vbChiKSApO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgYnZlYzQgYjEgPSBidmVjNCh2MSk7XG4gICAgYnZlYzQgYjIgPSBidmVjNCh2Mik7XG4gICAgcmV0dXJuIHZlYzQoIGIxLnIgJiYgYjIuciAsXG4gICAgICAgICAgICAgICAgYjEuZyAmJiBiMi5nLFxuICAgICAgICAgICAgICAgIGIxLmIgJiYgYjIuYixcbiAgICAgICAgICAgICAgICBiMS5hICYmIGIyLmEgKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xPcigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnb3JfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KCBib29sKGEpIHx8IGJvb2woYikgKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIGJ2ZWM0IGIxID0gYnZlYzQodjEpO1xuICAgIGJ2ZWM0IGIyID0gYnZlYzQodjIpO1xuICAgIHJldHVybiB2ZWM0KCBiMS5yIHx8IGIyLnIgLFxuICAgICAgICAgICAgICAgIGIxLmcgfHwgYjIuZyxcbiAgICAgICAgICAgICAgICBiMS5iIHx8IGIyLmIsXG4gICAgICAgICAgICAgICAgYjEuYSB8fCBiMi5hICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsWG9yKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICd4b3JfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KCBib29sKGEpIF5eIGJvb2woYikgKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIGJ2ZWM0IGIxID0gYnZlYzQodjEpO1xuICAgIGJ2ZWM0IGIyID0gYnZlYzQodjIpO1xuICAgIHJldHVybiB2ZWM0KCBiMS5yIF5eIGIyLnIgLFxuICAgICAgICAgICAgICAgIGIxLmcgXl4gYjIuZyxcbiAgICAgICAgICAgICAgICBiMS5iIF5eIGIyLmIsXG4gICAgICAgICAgICAgICAgYjEuYSBeXiBiMi5hICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsUG93KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluQmluYXJ5KCdwb3cnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsUFJlbHUoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3ByZWx1Xyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBhIDwgMC4wID8gYSAqIGI6IGE7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdmVjNChcbiAgICAgIHYxLnIgPCAwLjAgPyB2MS5yICogdjIucjogdjEucixcbiAgICAgIHYxLmcgPCAwLjAgPyB2MS5nICogdjIuZzogdjEuZyxcbiAgICAgIHYxLmIgPCAwLjAgPyB2MS5iICogdjIuYjogdjEuYixcbiAgICAgIHYxLmEgPCAwLjAgPyB2MS5hICogdjIuYTogdjEuYVxuICAgICAgKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuXG5mdW5jdGlvbiBnbHNsQnVpbHRpbkJpbmFyeShmbmFtZTogc3RyaW5nKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gYCR7Zm5hbWV9X2A7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiAke2ZuYW1lfShhLCBiKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiAke2ZuYW1lfSh2MSwgdjIpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5cbmNvbnN0IGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGdsc2xGdW5jOiBHbHNsVmFsdWVGdW5jdGlvbixcbiAgb3V0cHV0VGVuc29yVHlwZTogVGVuc29yLkRhdGFUeXBlID0gaW5wdXRzWzBdLnR5cGUsXG4gIGNhY2hlS2V5Pzogc3RyaW5nLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCB0ZXh0dXJlVHlwZSA9IGhhbmRsZXIuc2Vzc2lvbi5wYWNrID8gVGV4dHVyZVR5cGUucGFja2VkIDogVGV4dHVyZVR5cGUudW5wYWNrZWQ7XG4gIHJldHVybiB7XG4gICAgbmFtZTogZ2xzbEZ1bmMubmFtZSxcbiAgICBpbnB1dE5hbWVzOiBbJ0EnLCAnQiddLFxuICAgIGlucHV0VHlwZXM6IFt0ZXh0dXJlVHlwZSwgdGV4dHVyZVR5cGVdLFxuICAgIGNhY2hlSGludDogY2FjaGVLZXksXG4gICAgZ2V0OiAoKSA9PiBjcmVhdGVCaW5hcnlQcm9ncmFtSW5mbyhoYW5kbGVyLCBpbnB1dHMsIGdsc2xGdW5jLCBvdXRwdXRUZW5zb3JUeXBlKSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGdsc2xGdW5jOiBHbHNsVmFsdWVGdW5jdGlvbixcbiAgb3V0cHV0VGVuc29yVHlwZTogVGVuc29yLkRhdGFUeXBlID0gaW5wdXRzWzBdLnR5cGUsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHRleHR1cmVUeXBlID0gaGFuZGxlci5zZXNzaW9uLnBhY2sgPyBUZXh0dXJlVHlwZS5wYWNrZWQgOiBUZXh0dXJlVHlwZS51bnBhY2tlZDtcbiAgY29uc3QgaXNCcm9hZGNhc3QgPSAhU2hhcGVVdGlsLmFyZUVxdWFsKGlucHV0c1swXS5kaW1zLCBpbnB1dHNbMV0uZGltcyk7XG4gIGxldCBvdXRwdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuXG4gIGNvbnN0IHVzZVBhY2tlZFRleHR1cmUgPSBoYW5kbGVyLnNlc3Npb24ucGFjaztcblxuICBpZiAoaXNCcm9hZGNhc3QpIHtcbiAgICBjb25zdCBjYWxjdWxhdGVkU2hhcGUgPSBCcm9hZGNhc3RVdGlsLmNhbGNTaGFwZShpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmRpbXMsIGZhbHNlKTtcbiAgICBpZiAoIWNhbGN1bGF0ZWRTaGFwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgcGVyZm9ybSBiaW5hcnkgb3Agb24gdGhlIGdpdmVuIHRlbnNvcnNcIik7XG4gICAgfVxuICAgIG91dHB1dFNoYXBlID0gY2FsY3VsYXRlZFNoYXBlO1xuICAgIGNvbnN0IG91dHB1dFJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgYVJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDAgPyBpbnB1dHNbMF0uZGltcy5sZW5ndGggOiAxO1xuICAgIGNvbnN0IGJSYW5rID0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSAwID8gaW5wdXRzWzFdLmRpbXMubGVuZ3RoIDogMTtcbiAgICBjb25zdCBhQmNhc3QgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDAgPyAnYmNhc3RJbmRpY2VzX0EoaW5kaWNlcywgYWluZGljZXMpOycgOiAnYWluZGljZXNbMF0gPSAwOyc7XG4gICAgY29uc3QgYkJjYXN0ID0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSAwID8gJ2JjYXN0SW5kaWNlc19CKGluZGljZXMsIGJpbmRpY2VzKTsnIDogJ2JpbmRpY2VzWzBdID0gMDsnO1xuXG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IHVzZVBhY2tlZFRleHR1cmVcbiAgICAgID8gYFxuICAgICAgJHtnbHNsRnVuYy5ib2R5fVxuICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICB2ZWM0IGEgPSBnZXRBQXRPdXRDb29yZHMoKTtcbiAgICAgICAgdmVjNCBiID0gZ2V0QkF0T3V0Q29vcmRzKCk7XG4gICAgICAgIHZlYzQgcmVzdWx0ID0gJHtnbHNsRnVuYy5uYW1lfShhLCBiKTtcbiAgICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgICB9YFxuICAgICAgOiBgXG4gICAgICAke2dsc2xGdW5jLmJvZHl9XG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7b3V0cHV0UmFua31dKSB7XG4gICAgICAgIGludCBhaW5kaWNlc1ske2FSYW5rfV07XG4gICAgICAgIGludCBiaW5kaWNlc1ske2JSYW5rfV07XG4gICAgICAgICR7YUJjYXN0fVxuICAgICAgICAke2JCY2FzdH1cbiAgICAgICAgcmV0dXJuICR7Z2xzbEZ1bmMubmFtZX0oX0EoYWluZGljZXMpLCBfQihiaW5kaWNlcykpO1xuICAgICAgfWA7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogZ2xzbEZ1bmMubmFtZSxcbiAgICAgIGlucHV0TmFtZXM6IFsnQScsICdCJ10sXG4gICAgICBpbnB1dFR5cGVzOiBbdGV4dHVyZVR5cGUsIHRleHR1cmVUeXBlXSxcbiAgICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogb3V0cHV0VGVuc29yVHlwZSwgdGV4dHVyZVR5cGUgfSxcbiAgICAgIHNoYWRlclNvdXJjZSxcbiAgICAgIGhhc01haW46IHVzZVBhY2tlZFRleHR1cmUsXG4gICAgfTtcbiAgfVxuICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAke2dsc2xGdW5jLmJvZHl9XG4gICAgdm9pZCBtYWluKCkge1xuICAgICAgdmVjNCB2MSA9ICR7Z2xzbC50ZXh0dXJlMkR9KEEsIFRleENvb3Jkcyk7XG4gICAgICB2ZWM0IHYyID0gJHtnbHNsLnRleHR1cmUyRH0oQiwgVGV4Q29vcmRzKTtcbiAgICAgIHZlYzQgcmVzdWx0ID0gJHtnbHNsRnVuYy5uYW1lfSh2MSwgdjIpO1xuICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgfVxuICAgIGA7XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBnbHNsRnVuYy5uYW1lLFxuICAgIGlucHV0TmFtZXM6IFsnQScsICdCJ10sXG4gICAgaW5wdXRUeXBlczogW3RleHR1cmVUeXBlLCB0ZXh0dXJlVHlwZV0sXG4gICAgb3V0cHV0OiB7IGRpbXM6IGlucHV0c1swXS5kaW1zLCB0eXBlOiBvdXRwdXRUZW5zb3JUeXBlLCB0ZXh0dXJlVHlwZSB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGFkZCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbEFkZCgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBhbmQgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xBbmQoKSwgJ2Jvb2wnKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBkaXYgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xEaXYoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgZXF1YWwgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xFcXVhbCgpLCAnYm9vbCcpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGdyZWF0ZXIgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xHcmVhdGVyKCksICdib29sJyksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgbGVzcyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbExlc3MoKSwgJ2Jvb2wnKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBtdWwgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xNdWwoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3Qgb3IgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xPcigpLCAnYm9vbCcpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHBvdyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbFBvdygpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBwUmVsdSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbFBSZWx1KCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHN1YiA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbFN1YigpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCB4b3IgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xYb3IoKSwgJ2Jvb2wnKSwgaW5wdXRzKSxcbl07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgUHJvdG9VdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCBjYXN0OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFRlbnNvci5EYXRhVHlwZT4gPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgdG86IFRlbnNvci5EYXRhVHlwZSxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgcmV0dXJuIFtoYW5kbGVyLmNhc3QoaW5wdXRzWzBdLCB0byldO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ2FzdEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VGVuc29yLkRhdGFUeXBlPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogVGVuc29yLkRhdGFUeXBlID0+XG4gIFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byhub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCd0bycpKTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYXN0IHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0Q29vcmRzRGF0YVR5cGUsIGdldEdsQ2hhbm5lbHMgfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IENvbmNhdEF0dHJpYnV0ZXMgfSBmcm9tICcuL2NvbmNhdCc7XG5pbXBvcnQgeyBnZXRDaGFubmVscywgdW5wYWNrRnJvbUNoYW5uZWwgfSBmcm9tICcuL3BhY2tpbmctdXRpbHMnO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRDb25jYXRQcm9ncmFtTWV0YWRhdGEgPSAoaW5wdXRDb3VudDogbnVtYmVyLCBjYWNoZUhpbnQ6IHN0cmluZykgPT4gKHtcbiAgbmFtZTogJ0NvbmNhdCAocGFja2VkKScsXG4gIGlucHV0TmFtZXM6IEFycmF5LmZyb20oeyBsZW5ndGg6IGlucHV0Q291bnQgfSwgKF92LCBpKSA9PiBgWCR7aX1gKSxcbiAgaW5wdXRUeXBlczogQXJyYXkoaW5wdXRDb3VudCkuZmlsbChUZXh0dXJlVHlwZS5wYWNrZWQpLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbUluZm8gPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXhpczogbnVtYmVyLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgaWYgKGF4aXMgPj0gaW5wdXRTaGFwZS5sZW5ndGggfHwgYXhpcyA8IC0xICogaW5wdXRTaGFwZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJheGlzIHNwZWNpZmllZCBmb3IgY29uY2F0IGRvZXNuJ3QgbWF0Y2ggaW5wdXQgZGltZW5zaW9uYWxpdHlcIik7XG4gIH1cbiAgaWYgKGF4aXMgPCAwKSB7XG4gICAgYXhpcyA9IGlucHV0U2hhcGUubGVuZ3RoICsgYXhpcztcbiAgfVxuICAvLyBlbnN1cmUgYWxsIG9mIHRoZSBub24tY29uY2F0ZW5hdGVkIGF4ZXMgbWF0Y2ggZWFjaCBvdGhlclxuICAvLyBjYWxjdWxhdGUgdGhlIHNoYXBlIG9mIHRoZSBvdXRwdXQgdGVuc29yIHdoaWxlIHdlIGRvIHRoYXRcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dFNoYXBlLnNsaWNlKDApO1xuICBmb3IgKGxldCBpID0gMTsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGRhdGFOU2hhcGUgPSBpbnB1dHNbaV0uZGltcy5zbGljZSgpO1xuICAgIGZvciAobGV0IGF4aXNJbmRleCA9IDA7IGF4aXNJbmRleCA8IGlucHV0U2hhcGUubGVuZ3RoOyBheGlzSW5kZXgrKykge1xuICAgICAgLy8gYWRkIHRvIHRoZSBwbGFjZWhvbGRlciBmb3IgY29tcHV0aW5nIG91dHB1dCBzaGFwZVxuICAgICAgaWYgKGF4aXNJbmRleCA9PT0gYXhpcykge1xuICAgICAgICBvdXRwdXRTaGFwZVtheGlzXSArPSBkYXRhTlNoYXBlW2F4aXNJbmRleF07XG4gICAgICB9XG4gICAgICAvLyBlbnN1cmUgYWxsIG5vbi1jYW5jYXRlbmF0ZWQgYXhlcyBtYXRjaCBlYWNoIG90aGVyXG4gICAgICBlbHNlIGlmIChpbnB1dFNoYXBlW2F4aXNJbmRleF0gIT09IGRhdGFOU2hhcGVbYXhpc0luZGV4XSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vbiBjb25jYXQgZGltZW5zaW9ucyBtdXN0IG1hdGNoJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgY29vcmRzID0gZ2V0Q2hhbm5lbHMoJ2Nvb3JkcycsIHJhbmspO1xuICBjb25zdCBkdHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKHJhbmspO1xuICBjb25zdCB1bnBhY2tDaGFubmVsID0gdW5wYWNrRnJvbUNoYW5uZWwoKTtcblxuICBjb25zdCBzaGFwZXMgPSBpbnB1dHMubWFwKChpKSA9PiBpLmRpbXMpO1xuICBjb25zdCBjaGFubmVscyA9IGdldEdsQ2hhbm5lbHMocmFuayk7XG4gIGNvbnN0IG9mZnNldHM6IG51bWJlcltdID0gbmV3IEFycmF5KHNoYXBlcy5sZW5ndGggLSAxKTtcblxuICBvZmZzZXRzWzBdID0gc2hhcGVzWzBdW2F4aXNdO1xuICBmb3IgKGxldCBpID0gMTsgaSA8IG9mZnNldHMubGVuZ3RoOyBpKyspIHtcbiAgICBvZmZzZXRzW2ldID0gb2Zmc2V0c1tpIC0gMV0gKyBzaGFwZXNbaV1bYXhpc107XG4gIH1cblxuICBjb25zdCBjaGFubmVsID0gY2hhbm5lbHNbYXhpc107XG4gIGNvbnN0IGxhc3RDaGFubmVscyA9IGNoYW5uZWxzLnNsaWNlKC0yKTtcbiAgY29uc3QgYWxsQ2hhbm5lbHMgPSBjaGFubmVscy5qb2luKCk7XG5cbiAgbGV0IGdldFZhbHVlU25pcHBldCA9IGBpZiAoJHtjaGFubmVsfSA8ICR7b2Zmc2V0c1swXX0pIHtcbiAgICAgICAgcmV0dXJuIGdldENoYW5uZWwoXG4gICAgICAgICAgICBnZXRYMCgke2FsbENoYW5uZWxzfSksIHZlYzIoJHtsYXN0Q2hhbm5lbHMuam9pbigpfSkpO1xuICAgICAgICB9YDtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBvZmZzZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgc2hpZnQgPSBvZmZzZXRzW2kgLSAxXTtcbiAgICBnZXRWYWx1ZVNuaXBwZXQgKz0gYFxuICAgICAgICAgICAgaWYgKCR7Y2hhbm5lbH0gPCAke29mZnNldHNbaV19ICAmJiAke2NoYW5uZWx9ID49ICR7b2Zmc2V0c1tpIC0gMV19KSB7XG4gICAgICAgICAgICAgIHJldHVybiBnZXRDaGFubmVsKFxuICAgICAgICAgICAgICAgIGdldFgke2l9KCR7Z2V0U2hpZnRlZENoYW5uZWxzU25pcHBldChjaGFubmVscywgY2hhbm5lbCwgc2hpZnQpfSksXG4gICAgICAgICAgICAgICAgdmVjMigke2dldFNoaWZ0ZWRDaGFubmVsc1NuaXBwZXQobGFzdENoYW5uZWxzLCBjaGFubmVsLCBzaGlmdCl9KSk7XG4gICAgICAgICAgICB9YDtcbiAgfVxuICBjb25zdCBsYXN0SW5kZXggPSBvZmZzZXRzLmxlbmd0aDtcbiAgY29uc3Qgc2hpZnQgPSBvZmZzZXRzW29mZnNldHMubGVuZ3RoIC0gMV07XG4gIGdldFZhbHVlU25pcHBldCArPSBgXG4gICAgICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChcbiAgICAgICAgICAgICAgZ2V0WCR7bGFzdEluZGV4fSgke2dldFNoaWZ0ZWRDaGFubmVsc1NuaXBwZXQoY2hhbm5lbHMsIGNoYW5uZWwsIHNoaWZ0KX0pLFxuICAgICAgICAgICAgICB2ZWMyKCR7Z2V0U2hpZnRlZENoYW5uZWxzU25pcHBldChsYXN0Q2hhbm5lbHMsIGNoYW5uZWwsIHNoaWZ0KX0pKTtgO1xuXG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICAgJHt1bnBhY2tDaGFubmVsfVxuICAgICAgICAgIGZsb2F0IGdldFZhbHVlKCR7Y2hhbm5lbHMubWFwKCh4KSA9PiAnaW50ICcgKyB4KX0pIHtcbiAgICAgICAgICAgICR7Z2V0VmFsdWVTbmlwcGV0fVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgICAgICR7ZHR5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAgICAgICAgICAgaW50IGxhc3REaW0gPSBjb29yZHMuJHtjaGFubmVsc1tyYW5rIC0gMV19O1xuICAgICAgICAgICAgY29vcmRzLiR7Y2hhbm5lbHNbcmFuayAtIDFdfSA9IGNvb3Jkcy4ke2NoYW5uZWxzW3JhbmsgLSAyXX07XG4gICAgICAgICAgICBjb29yZHMuJHtjaGFubmVsc1tyYW5rIC0gMl19ID0gbGFzdERpbTtcblxuICAgICAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KGdldFZhbHVlKCR7Y29vcmRzfSksIDAuLCAwLiwgMC4pO1xuXG4gICAgICAgICAgICAke2Nvb3Jkc1tyYW5rIC0gMV19ID0gJHtjb29yZHNbcmFuayAtIDFdfSArIDE7XG4gICAgICAgICAgICBpZiAoJHtjb29yZHNbcmFuayAtIDFdfSA8ICR7b3V0cHV0U2hhcGVbcmFuayAtIDFdfSkge1xuICAgICAgICAgICAgICByZXN1bHQuZyA9IGdldFZhbHVlKCR7Y29vcmRzfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICR7Y29vcmRzW3JhbmsgLSAyXX0gPSAke2Nvb3Jkc1tyYW5rIC0gMl19ICsgMTtcbiAgICAgICAgICAgIGlmICgke2Nvb3Jkc1tyYW5rIC0gMl19IDwgJHtvdXRwdXRTaGFwZVtyYW5rIC0gMl19KSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5hID0gZ2V0VmFsdWUoJHtjb29yZHN9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgJHtjb29yZHNbcmFuayAtIDFdfSA9ICR7Y29vcmRzW3JhbmsgLSAxXX0gLSAxO1xuICAgICAgICAgICAgaWYgKCR7Y29vcmRzW3JhbmsgLSAyXX0gPCAke291dHB1dFNoYXBlW3JhbmsgLSAyXX0gJiZcbiAgICAgICAgICAgICAgICAke2Nvb3Jkc1tyYW5rIC0gMV19IDwgJHtvdXRwdXRTaGFwZVtyYW5rIC0gMV19KSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5iID0gZ2V0VmFsdWUoJHtjb29yZHN9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcblxuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQYWNrZWRDb25jYXRQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb25jYXRBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbUluZm8oaGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgYXR0cmlidXRlcy5heGlzKSB9O1xufTtcblxuY29uc3QgZ2V0U2hpZnRlZENoYW5uZWxzU25pcHBldCA9IChjaGFubmVsczogc3RyaW5nW10sIGNoYW5uZWw6IHN0cmluZywgc2hpZnQ6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGNoYW5uZWxJZHggPSBjaGFubmVscy5pbmRleE9mKGNoYW5uZWwpO1xuICBjb25zdCByZXMgPSBjaGFubmVscy5tYXAoKGMsIGlkeCkgPT4ge1xuICAgIGlmIChpZHggPT09IGNoYW5uZWxJZHgpIHtcbiAgICAgIHJldHVybiBgJHtjfSAtICR7c2hpZnR9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGM7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlcy5qb2luKCk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL2NvbmNhdC1wYWNrZWQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbmNhdEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGlzOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBjb25jYXQ6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248Q29uY2F0QXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29uY2F0QXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgaWYgKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5wYWNrICYmIGlucHV0c1swXS5kaW1zLmxlbmd0aCA+IDEpIHtcbiAgICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgIGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksXG4gICAgICBpbnB1dHMsXG4gICAgKTtcbiAgICByZXR1cm4gW291dHB1dF07XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksXG4gICAgICBpbnB1dHMsXG4gICAgKTtcbiAgICByZXR1cm4gW291dHB1dF07XG4gIH1cbn07XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbU1ldGFkYXRhID0gKGlucHV0Q291bnQ6IG51bWJlciwgY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdDb25jYXQnLFxuICBpbnB1dE5hbWVzOiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBpbnB1dENvdW50IH0sIChfdiwgaSkgPT4gYFgke2l9YCksXG4gIGlucHV0VHlwZXM6IEFycmF5KGlucHV0Q291bnQpLmZpbGwoVGV4dHVyZVR5cGUudW5wYWNrZWQpLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRDb25jYXRQcm9ncmFtSW5mbyA9IChcbiAgX2hhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXhpczogbnVtYmVyLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgaWYgKGF4aXMgPj0gaW5wdXRTaGFwZS5sZW5ndGggfHwgYXhpcyA8IC0xICogaW5wdXRTaGFwZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJheGlzIHNwZWNpZmllZCBmb3IgY29uY2F0IGRvZXNuJ3QgbWF0Y2ggaW5wdXQgZGltZW5zaW9uYWxpdHlcIik7XG4gIH1cbiAgaWYgKGF4aXMgPCAwKSB7XG4gICAgYXhpcyA9IGlucHV0U2hhcGUubGVuZ3RoICsgYXhpcztcbiAgfVxuICAvLyBlbnN1cmUgYWxsIG9mIHRoZSBub24tY29uY2F0ZW5hdGVkIGF4ZXMgbWF0Y2ggZWFjaCBvdGhlclxuICAvLyBjYWxjdWxhdGUgdGhlIHNoYXBlIG9mIHRoZSBvdXRwdXQgdGVuc29yIHdoaWxlIHdlIGRvIHRoYXRcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dFNoYXBlLnNsaWNlKDApO1xuICBmb3IgKGxldCBpID0gMTsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGRhdGFOU2hhcGUgPSBpbnB1dHNbaV0uZGltcy5zbGljZSgpO1xuICAgIGZvciAobGV0IGF4aXNJbmRleCA9IDA7IGF4aXNJbmRleCA8IGlucHV0U2hhcGUubGVuZ3RoOyBheGlzSW5kZXgrKykge1xuICAgICAgLy8gYWRkIHRvIHRoZSBwbGFjZWhvbGRlciBmb3IgY29tcHV0aW5nIG91dHB1dCBzaGFwZVxuICAgICAgaWYgKGF4aXNJbmRleCA9PT0gYXhpcykge1xuICAgICAgICBvdXRwdXRTaGFwZVtheGlzXSArPSBkYXRhTlNoYXBlW2F4aXNJbmRleF07XG4gICAgICB9XG4gICAgICAvLyBlbnN1cmUgYWxsIG5vbi1jYW5jYXRlbmF0ZWQgYXhlcyBtYXRjaCBlYWNoIG90aGVyXG4gICAgICBlbHNlIGlmIChpbnB1dFNoYXBlW2F4aXNJbmRleF0gIT09IGRhdGFOU2hhcGVbYXhpc0luZGV4XSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vbiBjb25jYXQgZGltZW5zaW9ucyBtdXN0IG1hdGNoJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcblxuICBjb25zdCBzaXplSW5Db25jYXRBeGlzID0gbmV3IEFycmF5PG51bWJlcj4oaW5wdXRzLmxlbmd0aCk7XG4gIGxldCBwcmV2aW91c1N1bSA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZUluQ29uY2F0QXhpcy5sZW5ndGg7ICsraSkge1xuICAgIHByZXZpb3VzU3VtICs9IGlucHV0c1tpXS5kaW1zW2F4aXNdO1xuICAgIHNpemVJbkNvbmNhdEF4aXNbaV0gPSBwcmV2aW91c1N1bTtcbiAgfVxuXG4gIGxldCBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTWV0aG9kID0gJyc7XG4gIC8vIGluIG1vc3QgY2FzZXMgbGluZWFyIHNlYXJjaCBpcyBzdWZmaWNpZW50LCBhcyBpbiBtb3N0IHNjZW5hcmlvcywgb25seSAyIHRlbnNvcnMgYXJlIGNvbmNhdGVuYXRlZFxuICBpZiAoaW5wdXRzLmxlbmd0aCA8IDUpIHtcbiAgICBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTWV0aG9kID0gZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc0xpbmVhclNlYXJjaChzaXplSW5Db25jYXRBeGlzKTtcbiAgfSBlbHNlIHtcbiAgICBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTWV0aG9kID0gZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc0JpbmFyeVNlYXJjaChzaXplSW5Db25jYXRBeGlzKTtcbiAgfVxuXG4gIGNvbnN0IGZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZU1ldGhvZCA9IGdldEZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZU1ldGhvZChpbnB1dHMubGVuZ3RoLCByYW5rKTtcbiAgY29uc3QgZ2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4TWV0aG9kID0gZ2V0R2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4TWV0aG9kKHNpemVJbkNvbmNhdEF4aXMpO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICR7ZmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlTWV0aG9kfVxuICAgICAgICAke2dldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleE1ldGhvZH1cbiAgICAgICAgJHtnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTWV0aG9kfVxuICAgICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IHRleHR1cmVJbmRleCA9IGdldFRleHR1cmVXaGVyZURhdGFSZXNpZGVzIChpbmRpY2VzWyR7YXhpc31dKTtcblxuICAgICAgICAgIGlmKHRleHR1cmVJbmRleCAhPSAwKSB7XG4gICAgICAgICAgICBpbmRpY2VzWyR7YXhpc31dID0gaW5kaWNlc1ske2F4aXN9XSAtIGludChnZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXgodGV4dHVyZUluZGV4LWludCgxKSkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBmZXRjaERhdGFGcm9tQ29ycmVjdFRleHR1cmUodGV4dHVyZUluZGV4LCBpbmRpY2VzKTtcbiAgICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRDb25jYXRQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb25jYXRBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGgsIGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICByZXR1cm4geyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1JbmZvKGhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIGF0dHJpYnV0ZXMuYXhpcykgfTtcbn07XG5cbmNvbnN0IGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNMaW5lYXJTZWFyY2ggPSAoc2l6ZUluQ29uY2F0QXhpczogbnVtYmVyW10pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBzZWFyY2hBeGlzID0gc2l6ZUluQ29uY2F0QXhpcy5tYXAoXG4gICAgKHNpemUsIGkpID0+IGBpZihpbmRleDwke3NpemV9KSB7cmV0dXJuICR7aX07fVxuYCxcbiAgKTtcbiAgcmV0dXJuIGBpbnQgZ2V0VGV4dHVyZVdoZXJlRGF0YVJlc2lkZXMoaW50IGluZGV4KSB7XG4gICAgICAke3NlYXJjaEF4aXMuam9pbignJyl9XG4gICAgfWA7XG59O1xuXG4vLyBUT0RPOiBJbXBsZW1lbnQgQmluYXJ5U2VhcmNoIGluIEdMU0xcbmNvbnN0IGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNCaW5hcnlTZWFyY2ggPSAoc2l6ZUluQ29uY2F0QXhpczogbnVtYmVyW10pOiBzdHJpbmcgPT5cbiAgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc0xpbmVhclNlYXJjaChzaXplSW5Db25jYXRBeGlzKTtcblxuY29uc3QgZ2V0RmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlTWV0aG9kID0gKG51bWJlck9mVGVuc29yczogbnVtYmVyLCB0ZW5zb3JSYW5rOiBudW1iZXIpID0+IHtcbiAgY29uc3QgY29kZUxpbmVzOiBzdHJpbmdbXSA9IFtgZmxvYXQgZmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlKGludCB0ZXh0dXJlSW5kZXgsIGludCBpbmRpY2VzWyR7dGVuc29yUmFua31dKSB7YF07XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZUZW5zb3JzOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyBgaWYgKHRleHR1cmVJbmRleCA9PSAke2l9KSB7IHJldHVybiBfWCR7aX0oaW5kaWNlcyk7IH1gKTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IG51bWJlck9mVGVuc29ycyAtIDEpIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGVsc2UgeyByZXR1cm4gX1gke2l9KGluZGljZXMpOyB9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGVsc2UgaWYgKHRleHR1cmVJbmRleCA9PSAke2l9KSB7IHJldHVybiBfWCR7aX0oaW5kaWNlcyk7IH1gKTtcbiAgICB9XG4gIH1cbiAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyAnfScpO1xuICByZXR1cm4gY29kZUxpbmVzLmpvaW4oJ1xcbicpO1xufTtcblxuY29uc3QgZ2V0R2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4TWV0aG9kID0gKHNpemVJbkNvbmNhdEF4aXM6IG51bWJlcltdKTogc3RyaW5nID0+IHtcbiAgY29uc3QgY29kZUxpbmVzOiBzdHJpbmdbXSA9IFsnaW50IGdldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleChpbnQgaW5kZXgpIHsnXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplSW5Db25jYXRBeGlzLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGkgPT09IDApIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGlmIChpbmRleCA9PSAke2l9KSB7IHJldHVybiAke3NpemVJbkNvbmNhdEF4aXNbaV19OyB9YCk7XG4gICAgfSBlbHNlIGlmIChpID09PSBzaXplSW5Db25jYXRBeGlzLmxlbmd0aCAtIDEpIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGVsc2UgeyByZXR1cm4gJHtzaXplSW5Db25jYXRBeGlzW2ldfTsgfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBlbHNlIGlmIChpbmRleCA9PSAke2l9KSB7IHJldHVybiAke3NpemVJbkNvbmNhdEF4aXNbaV19OyB9YCk7XG4gICAgfVxuICB9XG4gIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgJ30nKTtcblxuICByZXR1cm4gY29kZUxpbmVzLmpvaW4oJ1xcbicpO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ29uY2F0QXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxDb25jYXRBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogQ29uY2F0QXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGlzOiBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdheGlzJykgfSk7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3RvbyBmZXcgaW5wdXRzJyk7XG4gIH1cblxuICBjb25zdCBpbnB1dFR5cGUgPSBpbnB1dHNbMF0udHlwZTtcbiAgY29uc3QgaW5wdXREaW1lbnNpb25hbGl0eSA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcblxuICAvLyBUT0RPOiBTdXBwb3J0IHN0cmluZyBjb25jYXRcbiAgaWYgKGlucHV0VHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0cmluZyB0ZW5zb3IgaXMgbm90IHN1cHBvcnRlZCB5ZXQnKTtcbiAgfVxuXG4gIGZvciAoY29uc3QgaW5wdXQgb2YgaW5wdXRzKSB7XG4gICAgLy8gbWFrZSBzdXJlIHR5cGVzIG9mIGFsbCBpbnB1dHMgbWF0Y2hcbiAgICBpZiAoaW5wdXQudHlwZSAhPT0gaW5wdXRUeXBlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHRlbnNvcnMgc2hvdWxkIGJlIG9uZSB0eXBlJyk7XG4gICAgfVxuXG4gICAgLy8gbWFrZSBzdXJlIHRoZSBkaW1lbnNpb25hbGl0eSBvZiBhbGwgaW5wdXRzIGFyZSB0aGUgc2FtZVxuICAgIGlmIChpbnB1dC5kaW1zLmxlbmd0aCAhPT0gaW5wdXREaW1lbnNpb25hbGl0eSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCB0ZW5zb3JzIHNob3VsZCBoYXZlIHRoZSBzYW1lIHNoYXBlJyk7XG4gICAgfVxuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBNQVhfQ0xJUCwgTUlOX0NMSVAgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IEZ1bmN0aW9uVHlwZSwgR2xzbFZhbHVlRnVuY3Rpb24gfSBmcm9tICcuLi9nbHNsLWRlZmluaXRpb25zJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQWJzKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2FicycpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xBY29zKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2Fjb3MnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQXNpbigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdhc2luJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEF0YW4oKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnYXRhbicpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xDZWlsKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2NlaWwnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQ29zKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2NvcycpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xFbHUoYWxwaGE6IG51bWJlcik6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdlbHUnO1xuICBjb25zdCBib2R5ID0gYFxuICBjb25zdCBmbG9hdCBhbHBoYSA9IGZsb2F0KCR7YWxwaGF9KTtcblxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIGEgPj0gMC4wID8gYTogKGV4cChhKSAtIDEuMCkgKiBhbHBoYTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiB2ZWM0KCR7bmFtZX1fKHYueCksICR7bmFtZX1fKHYueSksICR7bmFtZX1fKHYueiksICR7bmFtZX1fKHYudykpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEV4cCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdleHAnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsRmxvb3IoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnZmxvb3InKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQ2xpcChtaW46IG51bWJlciwgbWF4OiBudW1iZXIpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnY2xpcCc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGNvbnN0IGZsb2F0IG1pbiA9IGZsb2F0KCR7bWlufSk7XG4gIGNvbnN0IGZsb2F0IG1heCA9IGZsb2F0KCR7bWF4fSk7XG5cbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBjbGFtcChhLCBtaW4sIG1heCk7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gY2xhbXAodiwgbWluLCBtYXgpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbElkZW50aXR5KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdpbmRlbnRpdHknO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIGE7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gdjtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xMZWFreVJlbHUoYWxwaGE6IG51bWJlcik6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdsZWFreVJlbHUnO1xuICBjb25zdCBib2R5ID0gYFxuICBjb25zdCBmbG9hdCBhbHBoYSA9IGZsb2F0KCR7YWxwaGF9KTtcblxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIGEgPCAwLjAgPyBhICogYWxwaGEgOiBhO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIHZlYzQoJHtuYW1lfV8odi54KSwgJHtuYW1lfV8odi55KSwgJHtuYW1lfV8odi56KSwgJHtuYW1lfV8odi53KSk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTG9nKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2xvZycpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xOZWcoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ25lZyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gLWE7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gLXY7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTm90KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdub3QnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIGZsb2F0KCAhIGJvb2woYSkgKTtcbiAgfVxuICBib29sICR7bmFtZX1fKGJvb2wgYSkge1xuICAgIHJldHVybiAhYTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiB2ZWM0KCFib29sKHYueCksICFib29sKHYueSksICFib29sKHYueiksICFib29sKHYudykpO1xuICB9XG4gIGJ2ZWM0ICR7bmFtZX1fKGJ2ZWM0IHYpIHtcbiAgICByZXR1cm4gYnZlYzQoIXYueCwgIXYueSwgIXYueiwgIXYudyk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsU2luKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ3NpbicpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xSZWx1KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdyZWx1JztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBtYXgoIGEsIDAuMCApO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIG1heCggdiwgMC4wICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsU2lnbW9pZCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnc2lnbW9pZCc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gMS4wIC8gKDEuMCArIGV4cCgtYSkpO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIDEuMCAvICgxLjAgKyBleHAoLXYpKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xTcXJ0KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ3NxcnQnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsVGFuKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ3RhbicpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xUYW5oKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICd0YW5oJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIGEgPSBjbGFtcChhLCAtMTAuLCAxMC4pO1xuICAgIGEgPSBleHAoMi4qYSk7XG4gICAgcmV0dXJuIChhIC0gMS4pIC8gKGEgKyAxLik7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICB2ID0gY2xhbXAodiwgLTEwLiwgMTAuKTtcbiAgICB2ID0gZXhwKDIuKnYpO1xuICAgIHJldHVybiAodiAtIDEuKSAvICh2ICsgMS4pO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5mdW5jdGlvbiBnbHNsQnVpbHRpblVuYXJ5KG5hbWU6IHN0cmluZyk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiAke25hbWV9KGEpO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuICR7bmFtZX0odik7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cblxuLy8vLy9cbi8vLy8vXG4vLy8vL1xuXG5jb25zdCBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGdsc2xGdW5jOiBHbHNsVmFsdWVGdW5jdGlvbixcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgdGV4dHVyZVR5cGUgPSBoYW5kbGVyLnNlc3Npb24ucGFjayA/IFRleHR1cmVUeXBlLnBhY2tlZCA6IFRleHR1cmVUeXBlLnVucGFja2VkO1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IGlucHV0LmRpbXMsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlIH0sXG4gICAgc2hhZGVyU291cmNlOiBgXG4gICAgICR7Z2xzbEZ1bmMuYm9keX1cbiAgICAgdm9pZCBtYWluKCkge1xuICAgICAgIHZlYzQgdiA9ICR7Z2xzbC50ZXh0dXJlMkR9KEEsIFRleENvb3Jkcyk7XG4gICAgICAgdiA9ICR7Z2xzbEZ1bmMubmFtZX1fKHYpO1xuICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdjtcbiAgICAgfVxuICAgICBgLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGdsc2xGdW5jOiBHbHNsVmFsdWVGdW5jdGlvbixcbiAgY2FjaGVLZXk/OiBzdHJpbmcsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IHRleHR1cmVUeXBlID0gaGFuZGxlci5zZXNzaW9uLnBhY2sgPyBUZXh0dXJlVHlwZS5wYWNrZWQgOiBUZXh0dXJlVHlwZS51bnBhY2tlZDtcbiAgY29uc3QgbWV0YWRhdGEgPSB7IG5hbWU6IGdsc2xGdW5jLm5hbWUsIGlucHV0VHlwZXM6IFt0ZXh0dXJlVHlwZV0sIGlucHV0TmFtZXM6IFsnQSddLCBjYWNoZUhpbnQ6IGNhY2hlS2V5IH07XG4gIHJldHVybiB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oaGFuZGxlciwgbWV0YWRhdGEsIGlucHV0LCBnbHNsRnVuYykgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBhYnMgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbEFicygpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBhY29zID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xBY29zKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGFzaW4gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbEFzaW4oKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgYXRhbiA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQXRhbigpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xpcEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBtaW46IG51bWJlcjtcbiAgcmVhZG9ubHkgbWF4OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBjbGlwID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQ2xpcEF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoXG4gICAgICBoYW5kbGVyLFxuICAgICAgaW5wdXRzWzBdLFxuICAgICAgZ2xzbENsaXAoYXR0cmlidXRlcy5taW4sIGF0dHJpYnV0ZXMubWF4KSxcbiAgICAgIGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgKSxcbiAgICBpbnB1dHMsXG4gICksXG5dO1xuXG5leHBvcnQgY29uc3QgcGFyc2VDbGlwQXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlKTogQ2xpcEF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBtaW46IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnbWluJywgTUlOX0NMSVApLFxuICAgIG1heDogbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtYXgnLCBNQVhfQ0xJUCksXG4gIH0pO1xuXG5leHBvcnQgY29uc3QgY2xpcFYxMSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSBnZW5lcmF0ZUNsaXBBdHRyaWJ1dGVzRnJvbUlucHV0cyhoYW5kbGVyLCBpbnB1dHMpO1xuICByZXR1cm4gY2xpcChoYW5kbGVyLCBbaW5wdXRzWzBdXSwgYXR0cmlidXRlcyk7XG59O1xuXG5jb25zdCBnZW5lcmF0ZUNsaXBBdHRyaWJ1dGVzRnJvbUlucHV0cyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBDbGlwQXR0cmlidXRlcyA9PiB7XG4gIGlmIChcbiAgICBpbnB1dHMubGVuZ3RoID49IDMgJiZcbiAgICAoIWhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1sxXS5kYXRhSWQpIHx8ICFoYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMl0uZGF0YUlkKSlcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkeW5hbWljIGNsaXAgYXR0cmlidXRlcyBhcmUgbm90IGFsbG93ZWQnKTtcbiAgfVxuXG4gIGNvbnN0IG1pbiA9IGlucHV0cy5sZW5ndGggPj0gMyA/IGlucHV0c1sxXS5udW1iZXJEYXRhWzBdIDogTUlOX0NMSVA7XG4gIGNvbnN0IG1heCA9IGlucHV0cy5sZW5ndGggPj0gMyA/IGlucHV0c1syXS5udW1iZXJEYXRhWzBdIDogTUFYX0NMSVA7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBtaW4sIG1heCB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBjZWlsID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xDZWlsKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGNvcyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQ29zKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGludGVyZmFjZSBFbHVBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYWxwaGE6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGVsdSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IEVsdUF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsRWx1KGF0dHJpYnV0ZXMuYWxwaGEpLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KSxcbiAgICBpbnB1dHMsXG4gICksXG5dO1xuXG5leHBvcnQgY29uc3QgcGFyc2VFbHVBdHRyaWJ1dGVzID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBFbHVBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGFscGhhOiBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2FscGhhJywgMS4wKSB9KTtcblxuZXhwb3J0IGNvbnN0IGV4cCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsRXhwKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGZsb29yID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xGbG9vcigpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBpZGVudGl0eSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsSWRlbnRpdHkoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgaW50ZXJmYWNlIExlYWt5UmVsdUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBhbHBoYTogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgbGVha3lSZWx1ID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IExlYWt5UmVsdUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsTGVha3lSZWx1KGF0dHJpYnV0ZXMuYWxwaGEpLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KSxcbiAgICBpbnB1dHMsXG4gICksXG5dO1xuXG5leHBvcnQgY29uc3QgcGFyc2VMZWFreVJlbHVBdHRyaWJ1dGVzID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBMZWFreVJlbHVBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGFscGhhOiBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2FscGhhJywgMC4wMSkgfSk7XG5cbmV4cG9ydCBjb25zdCBsb2cgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbExvZygpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBuZWcgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbE5lZygpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBub3QgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbE5vdCgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCByZWx1ID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xSZWx1KCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHNpZ21vaWQgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFNpZ21vaWQoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3Qgc2luID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xTaW4oKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3Qgc3FydCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsU3FydCgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCB0YW4gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFRhbigpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCB0YW5oID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xUYW5oKCkpLCBpbnB1dHMpLFxuXTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlIH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlJztcbmltcG9ydCB7IE1BWF9DTElQLCBNSU5fQ0xJUCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgR2xzbFZhbHVlRnVuY3Rpb24gfSBmcm9tICcuLi9nbHNsLWRlZmluaXRpb25zJztcblxuaW1wb3J0IHsgZ2xzbENsaXAsIGdsc2xSZWx1LCBnbHNsU2lnbW9pZCB9IGZyb20gJy4vdW5hcnktb3AnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMge1xuICByZWFkb25seSBhY3RpdmF0aW9uOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNsaXBNaW4/OiBudW1iZXI7XG4gIHJlYWRvbmx5IGNsaXBNYXg/OiBudW1iZXI7XG4gIHJlYWRvbmx5IGFjdGl2YXRpb25DYWNoZUtleTogc3RyaW5nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcykge1xuICBsZXQgZnVuYzogR2xzbFZhbHVlRnVuY3Rpb247XG4gIHN3aXRjaCAoYXR0cmlidXRlcy5hY3RpdmF0aW9uKSB7XG4gICAgY2FzZSAnUmVsdSc6XG4gICAgICBmdW5jID0gZ2xzbFJlbHUoKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ1NpZ21vaWQnOlxuICAgICAgZnVuYyA9IGdsc2xTaWdtb2lkKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdDbGlwJzpcbiAgICAgIGZ1bmMgPSBnbHNsQ2xpcChhdHRyaWJ1dGVzLmNsaXBNaW4hLCBhdHRyaWJ1dGVzLmNsaXBNYXghKTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIFRPRE86IGFkZGluZyBvdGhlciBhY3RpdmF0aW9ucyB0aGF0IGNhbiBiZSBmdXNlZC5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHsgYWN0aXZhdGlvbkZ1bmN0aW9uOiAnJywgYXBwbHlBY3RpdmF0aW9uOiAnJyB9O1xuICB9XG5cbiAgY29uc3QgYWN0aXZhdGlvbk5hbWUgPSBmdW5jLm5hbWU7XG4gIGNvbnN0IGFjdGl2YXRpb25GdW5jdGlvbiA9IGZ1bmMuYm9keTtcbiAgY29uc3QgYXBwbHlBY3RpdmF0aW9uID0gYHZhbHVlID0gJHthY3RpdmF0aW9uTmFtZX1fKHZhbHVlKTtgO1xuICByZXR1cm4geyBhY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbiB9O1xufVxuXG5leHBvcnQgY29uc3QgcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZSk6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBhY3RpdmF0aW9uID0gYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2FjdGl2YXRpb24nLCAnJyk7XG5cbiAgaWYgKGFjdGl2YXRpb24gPT09ICdDbGlwJykge1xuICAgIGNvbnN0IFtjbGlwTWluLCBjbGlwTWF4XSA9IGF0dHJpYnV0ZXMuZ2V0RmxvYXRzKCdhY3RpdmF0aW9uX3BhcmFtcycsIFtNSU5fQ0xJUCwgTUFYX0NMSVBdKTtcbiAgICByZXR1cm4geyBhY3RpdmF0aW9uLCBjbGlwTWF4LCBjbGlwTWluLCBhY3RpdmF0aW9uQ2FjaGVLZXk6IGAke2FjdGl2YXRpb259OiR7Y2xpcE1pbn0sJHtjbGlwTWF4fWAgfTtcbiAgfVxuICByZXR1cm4geyBhY3RpdmF0aW9uLCBhY3RpdmF0aW9uQ2FjaGVLZXk6IGFjdGl2YXRpb24gfTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJy4uLy4uLy4uL2luc3RydW1lbnQnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNhbGN1bGF0ZU91dHB1dFNoYXBlLCBDb252QXR0cmlidXRlcyB9IGZyb20gJy4vY29udic7XG5pbXBvcnQgeyBnZXRBY3RpdmF0aW9uU25pcHBldCB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtTWV0YWRhdGEgPSAoaGFzQmlhczogYm9vbGVhbiwgY2FjaGVIaW50OiBzdHJpbmcpOiBQcm9ncmFtTWV0YWRhdGEgPT4gKHtcbiAgbmFtZTogJ0dyb3VwZWRDb252JyxcbiAgaW5wdXROYW1lczogaGFzQmlhcyA/IFsnWCcsICdXJywgJ0JpYXMnXSA6IFsnWCcsICdXJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXNcbiAgICA/IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXVxuICAgIDogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIGNhY2hlSGludCxcbn0pO1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID4gMjtcbiAgY29uc3QgcHJvY2Vzc0JpYXMgPSBoYXNCaWFzID8gJ3ZhbHVlICs9IGdldEJpYXMob3V0cHV0X2NoYW5uZWwpOycgOiAnJztcbiAgY29uc3QgeFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3Qgd1NoYXBlID0gaW5wdXRzWzFdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3Qgb3V0cHV0Q2hhbm5lbHNQZXJHcm91cCA9IHdTaGFwZVswXSAvIGF0dHJpYnV0ZXMuZ3JvdXA7XG4gIExvZ2dlci52ZXJib3NlKFxuICAgICdHcm91cGVkQ29udicsXG4gICAgYGF1dHBQYWQ6JHthdHRyaWJ1dGVzLmF1dG9QYWR9LCBkaWxhdGlvbnM6JHthdHRyaWJ1dGVzLmRpbGF0aW9uc30sIGdyb3VwOiR7YXR0cmlidXRlcy5ncm91cH0sIGtlcm5lbFNoYXBlOiR7XG4gICAgICBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlXG4gICAgfSwgcGFkczoke2F0dHJpYnV0ZXMucGFkc30sIHN0cmlkZXM6JHthdHRyaWJ1dGVzLnN0cmlkZXN9YCxcbiAgKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBjYWxjdWxhdGVPdXRwdXRTaGFwZSh4U2hhcGUsIHdTaGFwZSwgYXR0cmlidXRlcy5kaWxhdGlvbnMsIGF0dHJpYnV0ZXMucGFkcywgYXR0cmlidXRlcy5zdHJpZGVzKTtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCB7IGFjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9uIH0gPSBnZXRBY3RpdmF0aW9uU25pcHBldChhdHRyaWJ1dGVzKTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gIGNvbnN0IGl2ZWMyIHN0cmlkZXMgPSBpdmVjMigke2F0dHJpYnV0ZXMuc3RyaWRlc1swXX0sICR7YXR0cmlidXRlcy5zdHJpZGVzWzFdfSk7XG4gIGNvbnN0IGl2ZWMyIHBhZHMgPSBpdmVjMigke2F0dHJpYnV0ZXMucGFkc1swXX0sICR7YXR0cmlidXRlcy5wYWRzWzFdfSk7XG4gICR7YWN0aXZhdGlvbkZ1bmN0aW9ufVxuICB2b2lkIG1haW4oKSB7XG4gICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgaW50IGJhdGNoID0gY29vcmRzLng7XG4gICAgaW50IG91dHB1dF9jaGFubmVsID0gY29vcmRzLnk7XG4gICAgaXZlYzIgeFJDQ29ybmVyID0gY29vcmRzLnp3ICogc3RyaWRlcyAtIHBhZHM7XG4gICAgaW50IGdyb3VwX2lkID0gb3V0cHV0X2NoYW5uZWwgLyAke291dHB1dENoYW5uZWxzUGVyR3JvdXB9O1xuXG4gICAgZmxvYXQgdmFsdWUgPSAwLjA7XG4gICAgZm9yIChpbnQgd0luQ2hhbm5lbCA9IDA7IHdJbkNoYW5uZWwgPCAke3dTaGFwZVsxXX07IHdJbkNoYW5uZWwrKykge1xuICAgICAgaW50IGlucHV0X2NoYW5uZWwgPSBncm91cF9pZCAqICR7d1NoYXBlWzFdfSArIHdJbkNoYW5uZWw7XG4gICAgICBmb3IgKGludCB3SGVpZ2h0ID0gMDsgd0hlaWdodCA8ICR7d1NoYXBlWzJdfTsgd0hlaWdodCsrKSB7XG4gICAgICAgIGludCB4SGVpZ2h0ID0geFJDQ29ybmVyLnggKyB3SGVpZ2h0ICogJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1swXX07XG5cbiAgICAgICAgaWYgKHhIZWlnaHQgPCAwIHx8IHhIZWlnaHQgPj0gJHt4U2hhcGVbMl19KSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGludCB3V2lkdGggPSAwOyB3V2lkdGggPCAke3dTaGFwZVszXX07IHdXaWR0aCsrKSB7XG4gICAgICAgICAgaW50IHhXaWR0aCA9IHhSQ0Nvcm5lci55ICsgd1dpZHRoICogJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXX07XG4gICAgICAgICAgaWYgKHhXaWR0aCA8IDAgfHwgeFdpZHRoID49ICR7eFNoYXBlWzNdfSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZmxvYXQgeFZhbCA9IGdldFgoYmF0Y2gsIGlucHV0X2NoYW5uZWwsIHhXaWR0aCwgeEhlaWdodCk7XG4gICAgICAgICAgZmxvYXQgd1ZhbCA9IGdldFcob3V0cHV0X2NoYW5uZWwsIHdJbkNoYW5uZWwsIHdXaWR0aCwgd0hlaWdodCk7XG4gICAgICAgICAgdmFsdWUgKz0geFZhbCp3VmFsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgICR7cHJvY2Vzc0JpYXN9XG4gICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KHZhbHVlLCAuMCwgLjAsIC4wKTtcbiAgfVxuYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoID4gMiwgYXR0cmlidXRlcy5jYWNoZUtleSk7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgZ2V0OiAoKSA9PiBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBtZXRhZGF0YSwgYXR0cmlidXRlcyksXG4gIH07XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuL2NvbnYnO1xuaW1wb3J0IHsgdW5wYWNrRnJvbUNoYW5uZWwgfSBmcm9tICcuL3BhY2tpbmctdXRpbHMnO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRJbTJDb2xQcm9ncmFtTWV0YWRhdGEgPSAoY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdJbTJDb2wgKHBhY2tlZCknLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnBhY2tlZF0sXG4gIGNhY2hlSGludCxcbn0pO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRJbTJDb2xQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICB4OiBUZW5zb3IsXG4gIHc6IFRlbnNvcixcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgeHNoYXBlID0geC5kaW1zO1xuICBjb25zdCB3c2hhcGUgPSB3LmRpbXM7XG4gIGNvbnN0IHJvd0RpbSA9IDI7XG4gIGNvbnN0IGNvbERpbSA9IDM7XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGltMmNvbFNoYXBlID0gW3dzaGFwZVsxXSAqIHdzaGFwZVsyXSAqIHdzaGFwZVszXSwgb3V0cHV0U2hhcGVbMl0gKiBvdXRwdXRTaGFwZVszXV07XG4gIGNvbnN0IGtlcm5lbFNpemUgPSB3c2hhcGVbMl0gKiB3c2hhcGVbM107XG4gIGNvbnN0IHVucGFja0NoYW5uZWwgPSB1bnBhY2tGcm9tQ2hhbm5lbCgpO1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGxldCB1bnJvbGxlZCA9ICcnO1xuXG4gIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8PSAxOyByb3crKykge1xuICAgIGZvciAobGV0IGNvbCA9IDA7IGNvbCA8PSAxOyBjb2wrKykge1xuICAgICAgdW5yb2xsZWQgKz0gYFxuICAgICAgICAgICAgYmxvY2tJbmRleCA9IHJjLnggKyAke2NvbH07XG4gICAgICAgICAgICBwb3MgPSByYy55ICsgJHtyb3d9O1xuXG4gICAgICAgICAgICBpZihibG9ja0luZGV4IDwgJHtpbTJjb2xTaGFwZVsxXX0gJiYgcG9zIDwgJHtpbTJjb2xTaGFwZVswXX0pIHtcbiAgICAgICAgICAgICAgb2Zmc2V0WSA9IGludChibG9ja0luZGV4IC8gKCR7b3V0cHV0U2hhcGVbcmFuayAtIDFdfSkpICogJHthdHRyaWJ1dGVzLnN0cmlkZXNbMF19IC1cbiAgICAgICAgICAgICAgICAke2F0dHJpYnV0ZXMucGFkc1swXX07XG4gICAgICAgICAgICAgIGQwID0gb2Zmc2V0WSArICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMF19ICogKGltb2QocG9zLCAke2tlcm5lbFNpemV9KSAvICR7d3NoYXBlWzJdfSk7XG5cbiAgICAgICAgICAgICAgaWYoZDAgPCAke3hzaGFwZVtyb3dEaW1dfSAmJiBkMCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0WCA9IGltb2QoYmxvY2tJbmRleCwgJHtvdXRwdXRTaGFwZVtyYW5rIC0gMV19KSAqICR7YXR0cmlidXRlcy5zdHJpZGVzWzFdfSAtXG4gICAgICAgICAgICAgICAgICAke2F0dHJpYnV0ZXMucGFkc1sxXX07XG4gICAgICAgICAgICAgICAgZDEgPSBvZmZzZXRYICsgJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXX0gKiBpbW9kKGltb2QocG9zLCAke2tlcm5lbFNpemV9KSwgJHt3c2hhcGVbMl19KTtcblxuICAgICAgICAgICAgICAgIGlmKGQxIDwgJHt4c2hhcGVbY29sRGltXX0gJiYgZDEgPj0gMCkge1xuXG4gICAgICAgICAgICAgICAgICBjaCA9IGludChmbG9hdChwb3MpLyAke2tlcm5lbFNpemV9Lik7XG4gICAgICAgICAgICAgICAgICAgIGlubmVyRGltcyA9IHZlYzIoZDAsIGQxKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0WyR7cm93ICogMiArIGNvbH1dID0gZ2V0Q2hhbm5lbChcbiAgICAgICAgICAgICAgICAgICAgICBnZXRBKDAsIGNoLCBpbnQoaW5uZXJEaW1zLngpLFxuICAgICAgICAgICAgICAgICAgICAgIGludChpbm5lckRpbXMueSkpLCBpbm5lckRpbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgYDtcbiAgICB9XG4gIH1cblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke3VucGFja0NoYW5uZWx9XG5cbiAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgaXZlYzIgcmMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMC4wKTtcbiAgICAgICAgICBpbnQgYmxvY2tJbmRleCwgcG9zLCBvZmZzZXRZLCBkMCwgb2Zmc2V0WCwgZDEsIGNoO1xuICAgICAgICAgIHZlYzIgaW5uZXJEaW1zO1xuICAgICAgICAgICR7dW5yb2xsZWR9XG4gICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgICB9XG4gICAgICAgICAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbTJjb2xTaGFwZSwgdHlwZTogeC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgeDogVGVuc29yLFxuICB3OiBUZW5zb3IsXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbU1ldGFkYXRhKGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIGdldDogKCkgPT4gY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIHgsIHcsIG91dHB1dFNoYXBlLCBhdHRyaWJ1dGVzKSxcbiAgfTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgQnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRDb29yZHNEYXRhVHlwZSwgZ2V0R2xDaGFubmVscyB9IGZyb20gJy4uL3V0aWxzJztcblxuaW1wb3J0IHsgZ2V0QWN0aXZhdGlvblNuaXBwZXQsIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsIHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQgeyBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vbWF0bXVsLXBhY2snO1xuXG5leHBvcnQgY29uc3QgbWF0TXVsOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgaWYgKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5wYWNrKSB7XG4gICAgcmV0dXJuIFtpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLCBpbnB1dHMpXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW2luZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvTG9hZGVyKGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyldO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VNYXRNdWxBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyA9PiBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMobm9kZS5hdHRyaWJ1dGVzKTtcblxuY29uc3QgY3JlYXRlTWF0bXVsUHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnTWF0TXVsJyxcbiAgaW5wdXROYW1lczogaGFzQmlhcyA/IFsnQScsICdCJywgJ0JpYXMnXSA6IFsnQScsICdCJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXNcbiAgICA/IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXVxuICAgIDogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIGNhY2hlSGludCxcbn0pO1xuXG5mdW5jdGlvbiBjcmVhdGVNYXRtdWxQcm9ncmFtSW5mbyhcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYWN0aXZhdGlvbkF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyB7XG4gIGNvbnN0IGFTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBiU2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBCcm9hZGNhc3RVdGlsLmNhbGNTaGFwZShhU2hhcGUsIGJTaGFwZSwgdHJ1ZSk7XG4gIGlmICghb3V0cHV0U2hhcGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCB1c2UgbWF0bXVsIG9uIHRoZSBnaXZlbiB0ZW5zb3JzXCIpO1xuICB9XG4gIGNvbnN0IGNvb3Jkc0RhdGFUeXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3QgYWxsR2xDaGFubmVscyA9IGdldEdsQ2hhbm5lbHMoKTtcbiAgY29uc3QgeyBhY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbiB9ID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYWN0aXZhdGlvbkF0dHJpYnV0ZXMpO1xuXG4gIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID4gMjtcbiAgY29uc3QgcHJvY2Vzc0JpYXMgPSBoYXNCaWFzID8gJ3ZhbHVlICs9IGdldEJpYXNGb3JNYXRtdWwoKTsnIDogJyc7XG4gIGNvbnN0IGdldEJpYXNGb3JNYXRtdWxTbmlwcGV0ID0gaGFzQmlhc1xuICAgID8gYCR7Z2V0Qmlhc0Zvck1hdG11bChjb29yZHNEYXRhVHlwZSwgYWxsR2xDaGFubmVscywgaW5wdXRzWzJdLmRpbXMsIG91dHB1dFNoYXBlLCBmYWxzZSl9YFxuICAgIDogJyc7XG5cbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgYXJhbmsgPSBhU2hhcGUubGVuZ3RoO1xuICBjb25zdCBicmFuayA9IGJTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IHNoYXJlZERpbSA9IGFTaGFwZVthU2hhcGUubGVuZ3RoIC0gMV07XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAke2FjdGl2YXRpb25GdW5jdGlvbn1cbiAgICAke2dldEJpYXNGb3JNYXRtdWxTbmlwcGV0fVxuICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IGFbJHthcmFua31dO1xuICAgICAgICBpbnQgYlske2JyYW5rfV07XG4gICAgICAgIGJjYXN0TWF0bXVsSW5kaWNlc19BKGluZGljZXMsIGEpO1xuICAgICAgICBiY2FzdE1hdG11bEluZGljZXNfQihpbmRpY2VzLCBiKTtcblxuICAgICAgICBmbG9hdCB2YWx1ZTtcbiAgICAgICAgZm9yIChpbnQgaz0wOyBrPCR7c2hhcmVkRGltfTsgKytrKSB7XG4gICAgICAgICAgICBhWyR7YXJhbmsgLSAxfV0gPSBrO1xuICAgICAgICAgICAgYlske2JyYW5rIC0gMn1dID0gaztcbiAgICAgICAgICAgIHZhbHVlICs9IF9BKGEpICogX0IoYik7XG4gICAgICAgIH1cbiAgICAgICAgJHtwcm9jZXNzQmlhc31cbiAgICAgICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYWN0aXZhdGlvbkF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlTWF0bXVsUHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGggPiAyLCBhY3RpdmF0aW9uQXR0cmlidXRlcy5hY3RpdmF0aW9uQ2FjaGVLZXkpO1xuICByZXR1cm4geyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVNYXRtdWxQcm9ncmFtSW5mbyhtZXRhZGF0YSwgaW5wdXRzLCBhY3RpdmF0aW9uQXR0cmlidXRlcykgfTtcbn1cblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNYXRNdWwgcmVxdWlyZXMgMiBpbnB1dHMuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLmRpbXNbaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMV0gIT09IGlucHV0c1sxXS5kaW1zW2lucHV0c1sxXS5kaW1zLmxlbmd0aCAtIDJdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzaGFyZWQgZGltZW5zaW9uIGRvZXMgbm90IG1hdGNoLicpO1xuICB9XG5cbiAgaWYgKFxuICAgIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDY0JylcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dHMgc2hvdWxkIGJlIGZsb2F0IHR5cGUnKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gaW5wdXRzWzFdLnR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0cyB0eXBlcyBzaG91bGQgbWF0Y2gnKTtcbiAgfVxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJpYXNGb3JNYXRtdWwoXG4gIGNvb3Jkc0RhdGFUeXBlOiBzdHJpbmcsXG4gIGFsbEdsQ2hhbm5lbHM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuICBpblNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgb3V0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBpc1BhY2tlZDogYm9vbGVhbixcbik6IHN0cmluZyB7XG4gIGxldCB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSAnJztcbiAgY29uc3QgaW5SYW5rID0gaW5TaGFwZS5sZW5ndGg7XG4gIGNvbnN0IG91dFJhbmsgPSBvdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IHJhbmtEaWZmID0gb3V0UmFuayAtIGluUmFuaztcbiAgaWYgKG91dFJhbmsgPCAyICYmIGluUmFuayA+IDApIHtcbiAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSAnY29vcmRzJztcbiAgfSBlbHNlIHtcbiAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSBpblNoYXBlLm1hcCgoX3MsIGkpID0+IGBjb29yZHMuJHthbGxHbENoYW5uZWxzW2kgKyByYW5rRGlmZl19YCkuam9pbignLCAnKTtcbiAgfVxuICBjb25zdCBicm9hZGNhc3REaW1zID0gQnJvYWRjYXN0VXRpbC5nZXRCcm9hZGNhc3REaW1zKGluU2hhcGUsIG91dFNoYXBlKTtcbiAgY29uc3QgY29vcmRzU25pcHBldCA9IGJyb2FkY2FzdERpbXMubWFwKChkKSA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tkICsgcmFua0RpZmZdfSA9IDA7YCkuam9pbignXFxuJyk7XG4gIGNvbnN0IGluU2l6ZSA9IFNoYXBlVXRpbC5zaXplKGluU2hhcGUpO1xuICBjb25zdCBpc0lucHV0U2NhbGFyID0gaW5TaXplID09PSAxO1xuICBsZXQgb3V0cHV0ID0gJ3ZlYzQob3V0cHV0VmFsdWUueHgsIG91dHB1dFZhbHVlLnl5KSc7XG4gIGlmIChpc0lucHV0U2NhbGFyKSB7XG4gICAgb3V0cHV0ID0gJ3ZlYzQob3V0cHV0VmFsdWUueCknO1xuICB9XG4gIGNvbnN0IGdldEJpYXNGb3JNYXRtdWxTb3VyY2UgPSBpc1BhY2tlZFxuICAgID8gYFxudmVjNCBnZXRCaWFzRm9yTWF0bXVsKCkge1xuICAke2Nvb3Jkc0RhdGFUeXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgJHtjb29yZHNTbmlwcGV0fVxuICB2ZWM0IG91dHB1dFZhbHVlID0gZ2V0Qmlhcygke3VucGFja2VkQ29vcmRzU25pcHBldH0pO1xuICByZXR1cm4gJHtvdXRwdXR9O1xufWBcbiAgICA6IGBcbmZsb2F0IGdldEJpYXNGb3JNYXRtdWwoKSB7XG4gICR7Y29vcmRzRGF0YVR5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAke2Nvb3Jkc1NuaXBwZXR9XG4gIHJldHVybiBnZXRCaWFzKGNvb3Jkcy54KTtcbn1gO1xuXG4gIHJldHVybiBnZXRCaWFzRm9yTWF0bXVsU291cmNlO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgQnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0Q29vcmRzRGF0YVR5cGUsIGdldEdsQ2hhbm5lbHMgfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IGdldEFjdGl2YXRpb25TbmlwcGV0LCBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIH0gZnJvbSAnLi9mdXNlLXV0aWxzJztcbmltcG9ydCB7IGdldEJpYXNGb3JNYXRtdWwgfSBmcm9tICcuL21hdG11bCc7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1NZXRhZGF0YSA9IChoYXNCaWFzOiBib29sZWFuLCBjYWNoZUhpbnQ6IHN0cmluZykgPT4gKHtcbiAgbmFtZTogJ01hdE11bCAocGFja2VkKScsXG4gIGlucHV0TmFtZXM6IGhhc0JpYXMgPyBbJ0EnLCAnQicsICdCaWFzJ10gOiBbJ0EnLCAnQiddLFxuICBpbnB1dFR5cGVzOiBoYXNCaWFzXG4gICAgPyBbVGV4dHVyZVR5cGUucGFja2VkLCBUZXh0dXJlVHlwZS5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZF1cbiAgICA6IFtUZXh0dXJlVHlwZS5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZF0sXG4gIGNhY2hlSGludCxcbn0pO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhY3RpdmF0aW9uQXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaGFzQmlhcyA9IGlucHV0cy5sZW5ndGggPiAyO1xuICBjb25zdCBwcm9jZXNzQmlhcyA9IGhhc0JpYXMgPyAndmFsdWUgKz0gZ2V0Qmlhc0Zvck1hdG11bCgpOycgOiAnJztcbiAgY29uc3QgYVNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGJTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IEJyb2FkY2FzdFV0aWwuY2FsY1NoYXBlKGFTaGFwZSwgYlNoYXBlLCB0cnVlKTtcbiAgY29uc3QgaXNCcm9hZGNhc3QgPSAhU2hhcGVVdGlsLmFyZUVxdWFsKGlucHV0c1swXS5kaW1zLCBpbnB1dHNbMV0uZGltcyk7XG5cbiAgaWYgKCFvdXRwdXRTaGFwZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IHVzZSBtYXRtdWwgb24gdGhlIGdpdmVuIHRlbnNvcnNcIik7XG4gIH1cbiAgY29uc3Qgc2hhcmVkRGltID0gYVNoYXBlW2FTaGFwZS5sZW5ndGggLSAxXTtcbiAgY29uc3Qgc2hhcmVkRGltSW5kZXggPSBNYXRoLmNlaWwoc2hhcmVkRGltIC8gMik7XG4gIGNvbnN0IGFSYW5rID0gYVNoYXBlLmxlbmd0aDtcbiAgY29uc3QgYlJhbmsgPSBiU2hhcGUubGVuZ3RoO1xuXG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgY29vcmRzRGF0YVR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBvdXRSYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBhbGxHbENoYW5uZWxzID0gZ2V0R2xDaGFubmVscygpO1xuICBjb25zdCB7IGFjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9uIH0gPSBnZXRBY3RpdmF0aW9uU25pcHBldChhY3RpdmF0aW9uQXR0cmlidXRlcyk7XG5cbiAgY29uc3QgZ2V0Qmlhc0Zvck1hdG11bFNuaXBwZXQgPSBoYXNCaWFzXG4gICAgPyBgJHtnZXRCaWFzRm9yTWF0bXVsKGNvb3Jkc0RhdGFUeXBlLCBhbGxHbENoYW5uZWxzLCBpbnB1dHNbMl0uZGltcywgb3V0cHV0U2hhcGUsIHRydWUpfWBcbiAgICA6ICcnO1xuXG4gIGNvbnN0IGdldEJjYXN0ZWRTYW1wbGVyRm9yTWF0bXVsU25pcHBldCA9IGlzQnJvYWRjYXN0XG4gICAgPyBgJHtnZXRCY2FzdFNhbXBsZXJGb3JNYXRtdWwoY29vcmRzRGF0YVR5cGUsIGFsbEdsQ2hhbm5lbHMsIGlucHV0cywgb3V0cHV0U2hhcGUpfWBcbiAgICA6ICcnO1xuXG4gIGNvbnN0IGdldFNhbXBsZXJBSW5Mb29wU25pcHBldCA9IGlzQnJvYWRjYXN0ID8gJ2dldEFBdE91dENvb3Jkc01hdG11bChpKScgOiBgZ2V0QSgke2dldEEoYWxsR2xDaGFubmVscywgYVJhbmspfSlgO1xuICBjb25zdCBnZXRTYW1wbGVyQkluTG9vcFNuaXBwZXQgPSBpc0Jyb2FkY2FzdCA/ICdnZXRCQXRPdXRDb29yZHNNYXRtdWwoaSknIDogYGdldEIoJHtnZXRCKGFsbEdsQ2hhbm5lbHMsIGJSYW5rKX0pYDtcbiAgY29uc3QgZ2V0T3V0cHV0Q29vcmRzU25pcHBldCA9IGlzQnJvYWRjYXN0XG4gICAgPyAnJ1xuICAgIDogYCR7Y29vcmRzRGF0YVR5cGV9IHJjID1cbiAgICAgICAgICBnZXRPdXRwdXRDb29yZHMoKTsgaW50IGxhc3REaW0gPSByYy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDFdfTsgcmMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAxXX0gPVxuICAgICAgICAgIHJjLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMl19OyByYy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDJdfSA9IGxhc3REaW07XG4gICAgICBgO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICAgICAke2dldEJjYXN0ZWRTYW1wbGVyRm9yTWF0bXVsU25pcHBldH1cbiAgICAgICAgICAgICR7Z2V0Qmlhc0Zvck1hdG11bFNuaXBwZXR9XG4gICAgICAgICAgICAke2FjdGl2YXRpb25GdW5jdGlvbn1cbiAgICAgICAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgICAgICAgJHtnZXRPdXRwdXRDb29yZHNTbmlwcGV0fVxuXG4gICAgICAgICAgICAgIHZlYzQgdmFsdWUgPSB2ZWM0KDApO1xuICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7c2hhcmVkRGltSW5kZXh9OyBpKyspIHtcbiAgICAgICAgICAgICAgICB2ZWM0IGEgPSAke2dldFNhbXBsZXJBSW5Mb29wU25pcHBldH07XG4gICAgICAgICAgICAgICAgdmVjNCBiID0gJHtnZXRTYW1wbGVyQkluTG9vcFNuaXBwZXR9O1xuXG4gICAgICAgICAgICAgICAgdmFsdWUgKz0gKGEucnJiYiAqIGIucmdyZyk7XG4gICAgICAgICAgICAgICAgdmFsdWUgKz0gKGEuZ2dhYSAqIGIuYmFiYSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgJHtwcm9jZXNzQmlhc31cbiAgICAgICAgICAgICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmFsdWU7XG4gICAgICAgICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYWN0aXZhdGlvbkF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGggPiAyLCBhY3RpdmF0aW9uQXR0cmlidXRlcy5hY3RpdmF0aW9uQ2FjaGVLZXkpO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIGdldDogKCkgPT4gY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgYWN0aXZhdGlvbkF0dHJpYnV0ZXMpLFxuICB9O1xufTtcblxuZnVuY3Rpb24gZ2V0QmNhc3RTYW1wbGVyRm9yTWF0bXVsKFxuICBjb29yZHNEYXRhVHlwZTogc3RyaW5nLFxuICBhbGxHbENoYW5uZWxzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgb3V0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogc3RyaW5nIHtcbiAgbGV0IHVucGFja2VkQUNvb3Jkc1NuaXBwZXQgPSBbXTtcbiAgbGV0IHVucGFja2VkQkNvb3Jkc1NuaXBwZXQgPSBbXTtcblxuICBjb25zdCBpbkFTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbkJTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuXG4gIGNvbnN0IGluQVJhbmsgPSBpbkFTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGluQlJhbmsgPSBpbkJTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3Qgb3V0UmFuayA9IG91dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgcmFua0FEaWZmID0gb3V0UmFuayAtIGluQVJhbms7XG4gIGNvbnN0IHJhbmtCRGlmZiA9IG91dFJhbmsgLSBpbkJSYW5rO1xuXG4gIHVucGFja2VkQUNvb3Jkc1NuaXBwZXQgPSBpbkFTaGFwZS5tYXAoKF9zLCBpKSA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tpICsgcmFua0FEaWZmXX1gKTtcbiAgdW5wYWNrZWRBQ29vcmRzU25pcHBldFtpbkFSYW5rIC0gMV0gPSAnaSoyJztcbiAgdW5wYWNrZWRBQ29vcmRzU25pcHBldC5qb2luKCcsICcpO1xuICB1bnBhY2tlZEJDb29yZHNTbmlwcGV0ID0gaW5CU2hhcGUubWFwKChfcywgaSkgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbaSArIHJhbmtCRGlmZl19YCk7XG4gIHVucGFja2VkQkNvb3Jkc1NuaXBwZXRbaW5CUmFuayAtIDJdID0gJ2kqMic7XG4gIHVucGFja2VkQkNvb3Jkc1NuaXBwZXQuam9pbignLCAnKTtcblxuICBjb25zdCBicm9hZGNhc3RBRGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpbkFTaGFwZSwgb3V0U2hhcGUpO1xuICBjb25zdCBicm9hZGNhc3RCRGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpbkJTaGFwZSwgb3V0U2hhcGUpO1xuXG4gIGNvbnN0IGNvb3Jkc0FTbmlwcGV0ID0gYnJvYWRjYXN0QURpbXMubWFwKChkKSA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tkICsgcmFua0FEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICBjb25zdCBjb29yZHNCU25pcHBldCA9IGJyb2FkY2FzdEJEaW1zLm1hcCgoZCkgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbZCArIHJhbmtCRGlmZl19ID0gMDtgKS5qb2luKCdcXG4nKTtcbiAgY29uc3Qgc3dhcERpbVNuaXBwZXQgPSBgaW50IGxhc3REaW0gPSBjb29yZHMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAxXX07XG4gIGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDFdfSA9IGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDJdfTtcbiAgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMl19ID0gbGFzdERpbTtgO1xuXG4gIGNvbnN0IGdldEJjYXN0U2FtcGxlck1hdG11bFNvdXJjZSA9IGBcbnZlYzQgZ2V0QUF0T3V0Q29vcmRzTWF0bXVsKGludCBpKSB7XG4gICR7Y29vcmRzRGF0YVR5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAke3N3YXBEaW1TbmlwcGV0fVxuICAke2Nvb3Jkc0FTbmlwcGV0fVxuICB2ZWM0IG91dHB1dFZhbHVlID0gZ2V0QSgke3VucGFja2VkQUNvb3Jkc1NuaXBwZXR9KTtcbiAgcmV0dXJuIG91dHB1dFZhbHVlO1xufVxuXG52ZWM0IGdldEJBdE91dENvb3Jkc01hdG11bChpbnQgaSkge1xuICAke2Nvb3Jkc0RhdGFUeXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgJHtzd2FwRGltU25pcHBldH1cbiAgJHtjb29yZHNCU25pcHBldH1cbiAgdmVjNCBvdXRwdXRWYWx1ZSA9IGdldEIoJHt1bnBhY2tlZEJDb29yZHNTbmlwcGV0fSk7XG4gIHJldHVybiBvdXRwdXRWYWx1ZTtcbn1gO1xuXG4gIHJldHVybiBnZXRCY2FzdFNhbXBsZXJNYXRtdWxTb3VyY2U7XG59XG5cbmZ1bmN0aW9uIGdldEEoYWxsR2xDaGFubmVsczogc3RyaW5nW10sIHJhbms6IG51bWJlcik6IHN0cmluZyB7XG4gIGxldCByZXMgPSAnJztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rIC0gMjsgaSsrKSB7XG4gICAgcmVzICs9IGByYy4ke2FsbEdsQ2hhbm5lbHNbaV19LCBgO1xuICB9XG4gIHJlcyArPSBgcmMuJHthbGxHbENoYW5uZWxzW3JhbmsgLSAyXX0sIGAgKyAnaSoyJztcbiAgcmV0dXJuIHJlcztcbn1cblxuZnVuY3Rpb24gZ2V0QihhbGxHbENoYW5uZWxzOiBzdHJpbmdbXSwgcmFuazogbnVtYmVyKTogc3RyaW5nIHtcbiAgbGV0IHJlcyA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAyOyBpKyspIHtcbiAgICByZXMgKz0gYHJjLiR7YWxsR2xDaGFubmVsc1tpXX0sIGA7XG4gIH1cbiAgcmVzICs9ICdpKjIsICcgKyBgcmMuJHthbGxHbENoYW5uZWxzW3JhbmsgLSAxXX1gO1xuICByZXR1cm4gcmVzO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5pbXBvcnQgeyBjYWxjdWxhdGVPdXRwdXRTaGFwZSwgQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuL2NvbnYnO1xuaW1wb3J0IHsgY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL2ltMmNvbC1wYWNrJztcbmltcG9ydCB7IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9tYXRtdWwtcGFjayc7XG5cbmV4cG9ydCBjb25zdCBjb252MkRQYWNrZWRQb2ludHdpc2UgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3IgPT4ge1xuICBjb25zdCB4c2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gY2FsY3VsYXRlT3V0cHV0U2hhcGUoeHNoYXBlLCBrc2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG4gIGNvbnN0IHJlc2hhcGVkWCA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVBhY2tlZChpbnB1dHNbMF0sIFt4c2hhcGVbMV0sIHhzaGFwZVsyXSAqIHhzaGFwZVszXV0pO1xuICBjb25zdCByZXNoYXBlZEsgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVQYWNrZWQoaW5wdXRzWzFdLCBba3NoYXBlWzBdLCBrc2hhcGVbMV1dKTtcblxuICBjb25zdCBtYXRtdWxJbnB1dHMgPSBpbnB1dHMubGVuZ3RoID4gMiA/IFtyZXNoYXBlZEssIHJlc2hhcGVkWCwgaW5wdXRzWzJdXSA6IFtyZXNoYXBlZEssIHJlc2hhcGVkWF07XG4gIGNvbnN0IG1hdG11bE91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIG1hdG11bElucHV0cywgYXR0cmlidXRlcyksXG4gICAgbWF0bXVsSW5wdXRzLFxuICApO1xuICByZXR1cm4gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlUGFja2VkKG1hdG11bE91dHB1dCwgb3V0cHV0U2hhcGUpO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbnYyRFBhY2tlZCA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFRlbnNvciA9PiB7XG4gIGNvbnN0IHhzaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBrc2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBjYWxjdWxhdGVPdXRwdXRTaGFwZSh4c2hhcGUsIGtzaGFwZSwgYXR0cmlidXRlcy5kaWxhdGlvbnMsIGF0dHJpYnV0ZXMucGFkcywgYXR0cmlidXRlcy5zdHJpZGVzKTtcblxuICAvLyBydW4gaW0yY29sXG4gIGNvbnN0IGltMmNvbE91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgaW5wdXRzWzFdLCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcyksXG4gICAgW2lucHV0c1swXV0sXG4gICk7XG5cbiAgLy8gcmVzaGFwZSBrZXJuZWxcbiAgY29uc3Qga2VybmVsUmVzaGFwZWQgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVQYWNrZWQoaW5wdXRzWzFdLCBba3NoYXBlWzBdLCBrc2hhcGVbMV0gKiBrc2hhcGVbMl0gKiBrc2hhcGVbM11dKTtcblxuICAvLyBydW4gbWF0bXVsXG4gIGNvbnN0IG1hdG11bElucHV0cyA9IGlucHV0cy5sZW5ndGggPT09IDMgPyBba2VybmVsUmVzaGFwZWQsIGltMmNvbE91dHB1dCwgaW5wdXRzWzJdXSA6IFtrZXJuZWxSZXNoYXBlZCwgaW0yY29sT3V0cHV0XTtcbiAgY29uc3QgbWF0bXVsT3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgbWF0bXVsSW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgICBtYXRtdWxJbnB1dHMsXG4gICk7XG5cbiAgLy8gcmVzaGFwZSBvdXRwdXRcbiAgY29uc3Qgb3V0cHV0UmVzaGFwZWQgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVQYWNrZWQobWF0bXVsT3V0cHV0LCBvdXRwdXRTaGFwZSk7XG4gIHJldHVybiBvdXRwdXRSZXNoYXBlZDtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IENvbnZBdHRyaWJ1dGVzIH0gZnJvbSAnLi9jb252JztcblxuY29uc3QgY3JlYXRlSW0yQ29sUHJvZ3JhbU1ldGFkYXRhID0gKGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnSW0yQ29sJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIGNhY2hlSGludCxcbn0pO1xuXG5jb25zdCBjcmVhdGVJbTJDb2xQcm9ncmFtSW5mbyA9IChcbiAgX2luZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgeDogVGVuc29yLFxuICB3OiBUZW5zb3IsXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHhzaGFwZSA9IHguZGltcztcbiAgY29uc3Qgd3NoYXBlID0gdy5kaW1zO1xuXG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGltMmNvbERpbXMgPSBjYWxjdWxhdGVJbTJDb2xEaW1zKHhzaGFwZSwgd3NoYXBlLCBvdXRwdXRTaGFwZSwgNCk7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICBjb25zdCBpbnQgWEMgPSAke3hzaGFwZVsxXX07XG4gICAgICAgIGNvbnN0IGludCBYSCA9ICR7eHNoYXBlWzJdfTtcbiAgICAgICAgY29uc3QgaW50IFhXID0gJHt4c2hhcGVbM119O1xuICAgICAgICBjb25zdCBpbnQgS0ggPSAke2F0dHJpYnV0ZXMua2VybmVsU2hhcGVbMF19O1xuICAgICAgICBjb25zdCBpbnQgS1cgPSAke2F0dHJpYnV0ZXMua2VybmVsU2hhcGVbMV19O1xuICAgICAgICBjb25zdCBpbnQgZGlsYXRpb25IID0gJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1swXX07XG4gICAgICAgIGNvbnN0IGludCBkaWxhdGlvblcgPSAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzFdfTtcbiAgICAgICAgY29uc3QgaW50IHN0cmlkZUggPSAke2F0dHJpYnV0ZXMuc3RyaWRlc1swXX07XG4gICAgICAgIGNvbnN0IGludCBzdHJpZGVXID0gJHthdHRyaWJ1dGVzLnN0cmlkZXNbMV19O1xuICAgICAgICBjb25zdCBpbnQgcGFkSCA9ICR7YXR0cmlidXRlcy5wYWRzWzBdfTtcbiAgICAgICAgY29uc3QgaW50IHBhZFcgPSAke2F0dHJpYnV0ZXMucGFkc1sxXX07XG4gICAgICAgIGNvbnN0IGludCBLSEtXID0gS0gqS1c7XG4gICAgICAgIGNvbnN0IGludCBYQ0tIS1cgPSBYQyAqIEtIS1c7XG4gICAgICAgIGNvbnN0IGludCBvdXRwdXRDaGFubmVscyA9IDQ7XG4gICAgICAgIHZlYzQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBiICA9IGluZGljZXNbMF07IC8vIGJhdGNoIHNpemVcbiAgICAgICAgICBpbnQgb2ggPSBpbmRpY2VzWzFdICogc3RyaWRlSCAtIHBhZEg7IC8vb3V0cHV0IGhlaWdodFxuICAgICAgICAgIGludCBvdyA9IGluZGljZXNbMl0gKiBzdHJpZGVXIC0gcGFkVzsgLy9vdXRwdXQgd2lkdGhcbiAgICAgICAgICBpbnQgcCA9IGluZGljZXNbM10gKiBvdXRwdXRDaGFubmVsczsgLy9wYXRjaFxuICAgICAgICAgIHZlYzQgdmFsdWUgPSB2ZWM0KDAuMCk7XG4gICAgICAgICAgZm9yKGludCBpPTA7IGkgPCBvdXRwdXRDaGFubmVsczsgKytpKSB7XG4gICAgICAgICAgICBpZihwIDwgWENLSEtXKSB7XG4gICAgICAgICAgICAgIGludCBwYXRjaEMgPSBwIC8gS0hLVztcbiAgICAgICAgICAgICAgaW50IHBhdGNoSCA9IChwIC0gcGF0Y2hDKktIS1cpIC8gS1c7XG4gICAgICAgICAgICAgIGludCBwYXRjaFcgPSAocCAtIHBhdGNoQypLSEtXKSAtIHBhdGNoSCAqIEtXO1xuICAgICAgICAgICAgICBpbnQgeGgyID0gb2ggKyBwYXRjaEggKiBkaWxhdGlvbkg7XG4gICAgICAgICAgICAgIGludCB4dzIgPSBvdyArIHBhdGNoVyAqIGRpbGF0aW9uVztcbiAgICAgICAgICAgICAgaW50IHhbJHt4c2hhcGUubGVuZ3RofV07XG4gICAgICAgICAgICAgIHhbMF0gPSBiO1xuICAgICAgICAgICAgICB4WzFdID0gcGF0Y2hDO1xuICAgICAgICAgICAgICB4WzJdID0geGgyO1xuICAgICAgICAgICAgICB4WzNdID0geHcyO1xuICAgICAgICAgICAgICBpZih4aDIgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgeGgyIDwgWEggJiZcbiAgICAgICAgICAgICAgICAgIHh3MiA+PSAwICYmXG4gICAgICAgICAgICAgICAgICB4dzIgPCBYVykge1xuICAgICAgICAgICAgICAgIHZhbHVlW2ldID0gX1goeCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICsrcDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IGltMmNvbERpbXMsIHR5cGU6IHgudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24gfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgeDogVGVuc29yLFxuICB3OiBUZW5zb3IsXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlSW0yQ29sUHJvZ3JhbU1ldGFkYXRhKGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIGdldDogKCkgPT4gY3JlYXRlSW0yQ29sUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIHgsIHcsIG91dHB1dFNoYXBlLCBhdHRyaWJ1dGVzKSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjYWxjdWxhdGVJbTJDb2xEaW1zID0gKFxuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGNoYW5uZWxzID0gNCxcbik6IG51bWJlcltdID0+IFtcbiAgb3V0cHV0U2hhcGVbMF0sXG4gIG91dHB1dFNoYXBlWzJdLFxuICBvdXRwdXRTaGFwZVszXSxcbiAgTWF0aC5jZWlsKChpbnB1dFNoYXBlWzFdICoga2VybmVsU2hhcGVbMl0gKiBrZXJuZWxTaGFwZVszXSkgLyBjaGFubmVscyksXG5dO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBnZXRBY3RpdmF0aW9uU25pcHBldCwgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQgeyBjYWxjdWxhdGVJbTJDb2xEaW1zIH0gZnJvbSAnLi9pbTJjb2wnO1xuXG5jb25zdCBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMpID0+ICh7XG4gIG5hbWU6ICdDb252RG90UHJvZHVjdCcsXG4gIGlucHV0TmFtZXM6IGhhc0JpYXMgPyBbJ0ltMkNvbCcsICdLJywgJ0InXSA6IFsnSW0yQ29sJywgJ0snXSxcbiAgaW5wdXRUeXBlczogaGFzQmlhc1xuICAgID8gW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uLCBUZXh0dXJlVHlwZS51bnBhY2tlZF1cbiAgICA6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbl0sXG4gIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmFjdGl2YXRpb25DYWNoZUtleSxcbn0pO1xuXG5jb25zdCBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgb3V0cHV0U2hhcGU6IG51bWJlcltdLFxuICBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCB4c2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IGFkanVzdGVkS2VybmVsU2hhcGUgPSBba3NoYXBlWzBdLCBNYXRoLmNlaWwoKHhzaGFwZVsxXSAqIGtzaGFwZVsyXSAqIGtzaGFwZVszXSkgLyA0KV07XG4gIGNvbnN0IGltMmNvbFNoYXBlID0gY2FsY3VsYXRlSW0yQ29sRGltcyh4c2hhcGUsIGtzaGFwZSwgb3V0cHV0U2hhcGUpO1xuICBjb25zdCBba1dpZHRoLCBrSGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGFkanVzdGVkS2VybmVsU2hhcGUsXG4gICAgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbixcbiAgKTtcblxuICBjb25zdCBpbTJjb2xTdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKGltMmNvbFNoYXBlKTtcbiAgY29uc3QgW2ltMmNvbFdpZHRoLCBpbTJjb2xIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgaW0yY29sU2hhcGUsXG4gICAgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbixcbiAgKTtcbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcblxuICBjb25zdCBpbml0VmFsdWUgPSBpbnB1dHMubGVuZ3RoIDwgMyA/ICcwLjAnIDogJ19CKGIpJztcbiAgY29uc3Qgc2hhcmVkRGltID0gTWF0aC5jZWlsKCh4c2hhcGVbMV0gKiBrc2hhcGVbMl0gKiBrc2hhcGVbM10pIC8gNCk7XG4gIGNvbnN0IHsgYWN0aXZhdGlvbkZ1bmN0aW9uLCBhcHBseUFjdGl2YXRpb24gfSA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGF0dHJpYnV0ZXMpO1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiR7YWN0aXZhdGlvbkZ1bmN0aW9ufVxuZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICBpbnQgYlsxXTtcbiAgYlswXSA9IGluZGljZXNbMV07XG4gIGludCBpbTJjb2xbNF07XG4gIGltMmNvbFswXSA9IGluZGljZXNbMF07XG4gIGltMmNvbFsxXSA9IGluZGljZXNbMl07XG4gIGltMmNvbFsyXSA9IGluZGljZXNbM107XG4gIGludCBpbTJjb2xPZmZzZXQgPSBpbTJjb2xbMF0gKiAke2ltMmNvbFN0cmlkZXNbMF19ICsgaW0yY29sWzFdICogJHtpbTJjb2xTdHJpZGVzWzFdfSArIGltMmNvbFsyXSAqICR7XG4gICAgaW0yY29sU3RyaWRlc1syXVxuICB9O1xuICBpbnQga2VybmVsT2Zmc2V0ID0gaW5kaWNlc1sxXSAqICR7YWRqdXN0ZWRLZXJuZWxTaGFwZVsxXX07XG4gIGZsb2F0IHZhbHVlID0gJHtpbml0VmFsdWV9O1xuICBmb3IgKGludCBpID0gMDsgaSA8ICR7c2hhcmVkRGltfTsgKytpKSB7XG4gICAgdmVjMiBpbTJjb2xDb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhpbTJjb2xPZmZzZXQsICR7aW0yY29sV2lkdGh9LCAke2ltMmNvbEhlaWdodH0pO1xuICAgIHZlYzIga2VybmVsQ29vcmRzID0gb2Zmc2V0VG9Db29yZHMoa2VybmVsT2Zmc2V0LCAke2tXaWR0aH0sICR7a0hlaWdodH0pO1xuICAgIHZhbHVlICs9IGRvdCgke2dsc2wudGV4dHVyZTJEfShJbTJDb2wsIGltMmNvbENvb3JkcyksICR7Z2xzbC50ZXh0dXJlMkR9KEssIGtlcm5lbENvb3JkcykpO1xuICAgICsraW0yY29sT2Zmc2V0O1xuICAgICsra2VybmVsT2Zmc2V0O1xuICB9XG4gICR7YXBwbHlBY3RpdmF0aW9ufVxuICByZXR1cm4gdmFsdWU7XG59YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlRG90UHJvZHVjdFByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIG91dHB1dFNoYXBlOiBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGggPiAyLCBhdHRyaWJ1dGVzKTtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBnZXQ6ICgpID0+IGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcyksXG4gIH07XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vLi4vLi4vYmFja2VuZCc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFBvb2xDb252VXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5pbXBvcnQgeyBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL2NvbnYtZ3JvdXBlZCc7XG5pbXBvcnQgeyBjb252MkRQYWNrZWQgfSBmcm9tICcuL2NvbnYtcGFjayc7XG5pbXBvcnQgeyBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL2RvdC1wcm9kdWN0JztcbmltcG9ydCB7IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsIHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQgeyBjcmVhdGVJbTJDb2xQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vaW0yY29sJztcbmltcG9ydCB7IGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9tYXRtdWwnO1xuXG5leHBvcnQgY29uc3QgY2FsY3VsYXRlT3V0cHV0U2hhcGUgPSAoXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGFkanVzdFBhZHM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbik6IG51bWJlcltdID0+IHtcbiAgY29uc3QgYmF0Y2hTaXplID0gaW5wdXRTaGFwZVswXTtcbiAgY29uc3QgaW5wdXRTcGF0aWFsU2hhcGUgPSBpbnB1dFNoYXBlLnNsaWNlKDIpO1xuICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0U3BhdGlhbFNoYXBlLmxlbmd0aDtcbiAgY29uc3Qgb3V0Q2hhbm5lbHMgPSBrZXJuZWxTaGFwZVswXTtcbiAgY29uc3Qga2VybmVsU3BhdGlhbFNoYXBlID0ga2VybmVsU2hhcGUuc2xpY2UoMik7XG4gIGNvbnN0IGRpbGF0ZWRLZXJuZWxTaGFwZSA9IGtlcm5lbFNwYXRpYWxTaGFwZS5tYXAoKHYsIGkpID0+IHYgKyAodiAtIDEpICogKGRpbGF0aW9uc1tpXSAtIDEpKTtcbiAgY29uc3QgaW5wdXRTcGF0aWFsU2hhcGVXaXRoUGFkID0gaW5wdXRTcGF0aWFsU2hhcGUubWFwKCh2LCBpKSA9PiB2ICsgYWRqdXN0UGFkc1tpXSArIGFkanVzdFBhZHNbaSArIHNwYXRpYWxSYW5rXSk7XG4gIGNvbnN0IG91dHB1dFNwYXRpYWxTaGFwZSA9IGlucHV0U3BhdGlhbFNoYXBlV2l0aFBhZC5tYXAoKHYsIGkpID0+XG4gICAgTWF0aC5mbG9vcigodiAtIGRpbGF0ZWRLZXJuZWxTaGFwZVtpXSArIHN0cmlkZXNbaV0pIC8gc3RyaWRlc1tpXSksXG4gICk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW2JhdGNoU2l6ZSwgb3V0Q2hhbm5lbHNdLmNvbmNhdCguLi5vdXRwdXRTcGF0aWFsU2hhcGUpO1xuICByZXR1cm4gb3V0cHV0U2hhcGU7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbnZBdHRyaWJ1dGVzIGV4dGVuZHMgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcywgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXV0b1BhZDogc3RyaW5nO1xuICByZWFkb25seSBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBncm91cDogbnVtYmVyO1xuICByZWFkb25seSBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHBhZHM6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGNvbnN0IGNvbnY6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248Q29udkF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTsgLy8gY3VycmVudGx5IHdpbGwgZmFpbCBpZiBub3QgY29udjJEXG4gIHJldHVybiBjb252MmQoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbn07XG5cbmNvbnN0IGNvbnYyZDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxDb252QXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IGFkanVzdGVkQXR0cmlidXRlcyA9IGdldEFkanVzdGVkQ29udkF0dHJpYnV0ZXMoYXR0cmlidXRlcywgaW5wdXRzKTtcbiAgY29uc3QgcGFja01vZGUgPSBpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24ucGFjaztcbiAgY29uc3QgaXNQb2ludHdpc2UgPSBhZGp1c3RlZEF0dHJpYnV0ZXMua2VybmVsU2hhcGVbMF0gPT09IDEgJiYgYWRqdXN0ZWRBdHRyaWJ1dGVzLmtlcm5lbFNoYXBlWzFdID09PSAxO1xuICBpZiAoYWRqdXN0ZWRBdHRyaWJ1dGVzLmdyb3VwID4gMSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzKSxcbiAgICAgIGlucHV0cyxcbiAgICApO1xuICAgIHJldHVybiBbcmVzdWx0XTtcbiAgfSBlbHNlIGlmIChpc1BvaW50d2lzZSAmJiBwYWNrTW9kZSkge1xuICAgIHJldHVybiBbY29udjJEVW5wYWNrZWRQb2ludHdpc2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMpXTtcbiAgfSBlbHNlIGlmIChwYWNrTW9kZSAmJiBpbnB1dHNbMF0uZGltcy5sZW5ndGggPT09IDQgJiYgaW5wdXRzWzBdLmRpbXNbMF0gPT09IDEgJiYgIWlzUG9pbnR3aXNlKSB7XG4gICAgcmV0dXJuIFtjb252MkRQYWNrZWQoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMpXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW2NvbnYyRFVucGFja2VkKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzKV07XG4gIH1cbn07XG5cbmNvbnN0IGNvbnYyRFVucGFja2VkUG9pbnR3aXNlID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgeHNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGtzaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGNhbGN1bGF0ZU91dHB1dFNoYXBlKHhzaGFwZSwga3NoYXBlLCBhdHRyaWJ1dGVzLmRpbGF0aW9ucywgYXR0cmlidXRlcy5wYWRzLCBhdHRyaWJ1dGVzLnN0cmlkZXMpO1xuICBjb25zdCByZXNoYXBlZFggPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIFt4c2hhcGVbMV0sIHhzaGFwZVsyXSAqIHhzaGFwZVszXV0pO1xuICBjb25zdCByZXNoYXBlZEsgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMV0sIFtrc2hhcGVbMF0sIGtzaGFwZVsxXV0pO1xuXG4gIGNvbnN0IG1hdG11bElucHV0cyA9IGlucHV0cy5sZW5ndGggPiAyID8gW3Jlc2hhcGVkSywgcmVzaGFwZWRYLCBpbnB1dHNbMl1dIDogW3Jlc2hhcGVkSywgcmVzaGFwZWRYXTtcbiAgY29uc3QgbWF0bXVsT3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIobWF0bXVsSW5wdXRzLCBhdHRyaWJ1dGVzKSwgbWF0bXVsSW5wdXRzKTtcbiAgcmV0dXJuIGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKG1hdG11bE91dHB1dCwgb3V0cHV0U2hhcGUpO1xufTtcblxuY29uc3QgY29udjJEVW5wYWNrZWQgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3IgPT4ge1xuICBjb25zdCB4c2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gY2FsY3VsYXRlT3V0cHV0U2hhcGUoeHNoYXBlLCBrc2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG4gIGNvbnN0IHhJbTJDb2wgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVJbTJDb2xQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGlucHV0c1sxXSwgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpLFxuICAgIFtpbnB1dHNbMF1dLFxuICApO1xuXG4gIGNvbnN0IGRvdFByb2R1Y3RJbnB1dHMgPSBpbnB1dHMubGVuZ3RoID09PSAzID8gW3hJbTJDb2wsIGlucHV0c1sxXSwgaW5wdXRzWzJdXSA6IFt4SW0yQ29sLCBpbnB1dHNbMV1dO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcyksXG4gICAgZG90UHJvZHVjdElucHV0cyxcbiAgKTtcbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbmNvbnN0IGdldEFkanVzdGVkQ29udkF0dHJpYnV0ZXMgPSA8VCBleHRlbmRzIENvbnZBdHRyaWJ1dGVzPihhdHRyaWJ1dGVzOiBULCBpbnB1dHM6IFRlbnNvcltdKTogVCA9PiB7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5zbGljZSgpO1xuICAvLyBpZiBrZXJuZWxTaGFwZSBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgb3AsIGluZmVyIGl0IGZyb20gdGhlIHdlaWdodCB0ZW5zb3IgZGltc1xuICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICBmb3IgKGxldCBpID0gMjsgaSA8IGlucHV0c1sxXS5kaW1zLmxlbmd0aDsgKytpKSB7XG4gICAgICBrZXJuZWxTaGFwZS5wdXNoKGlucHV0c1sxXS5kaW1zW2ldKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMucGFkcy5zbGljZSgpO1xuICBQb29sQ29udlV0aWwuYWRqdXN0UGFkc0Jhc2VkT25BdXRvUGFkKFxuICAgIGlucHV0c1swXS5kaW1zLFxuICAgIGF0dHJpYnV0ZXMuc3RyaWRlcyxcbiAgICBhdHRyaWJ1dGVzLmRpbGF0aW9ucyxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBwYWRzLFxuICAgIGF0dHJpYnV0ZXMuYXV0b1BhZCxcbiAgKTtcblxuICAvLyBhbHdheXMgcmV0dXJuIGEgbmV3IG9iamVjdCBzbyBkb2VzIG5vdCBtb2RpZnkgdGhlIG9yaWdpbmFsIGF0dHJpYnV0ZXNcbiAgY29uc3QgbmV3QXR0cmlidXRlczogVCA9IE9iamVjdC5hc3NpZ24oe30sIGF0dHJpYnV0ZXMpO1xuICBPYmplY3QuYXNzaWduKG5ld0F0dHJpYnV0ZXMsIHsga2VybmVsU2hhcGUsIHBhZHMsIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5IH0pO1xuICByZXR1cm4gbmV3QXR0cmlidXRlcztcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNvbnZBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPENvbnZBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogQ29udkF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBhdHRyaWJ1dGVzID0gbm9kZS5hdHRyaWJ1dGVzO1xuICBjb25zdCBhY3RpdmF0aW9uQXR0cmlidXRlcyA9IHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTtcbiAgLy8gVE9ETyA6IE1ha2UgdGhpcyBnZW5lcmljIGVub3VnaCB0byBjb21wdXRlIGRlZmF1bHQgYXR0cmlidXRlcyBmb3IgbXVsdGktZGltZW5zaW9uYWwgY29udlxuICBjb25zdCBhdXRvUGFkID0gYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2F1dG9fcGFkJywgJ05PVFNFVCcpO1xuICBjb25zdCBkaWxhdGlvbnMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ2RpbGF0aW9ucycsIFsxLCAxXSk7XG4gIGNvbnN0IGdyb3VwID0gYXR0cmlidXRlcy5nZXRJbnQoJ2dyb3VwJywgMSk7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5nZXRJbnRzKCdrZXJuZWxfc2hhcGUnLCBbXSk7XG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnLCBbMCwgMCwgMCwgMF0pO1xuICBjb25zdCBzdHJpZGVzID0gYXR0cmlidXRlcy5nZXRJbnRzKCdzdHJpZGVzJywgWzEsIDFdKTtcblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBhdXRvUGFkLFxuICAgIGRpbGF0aW9ucyxcbiAgICBncm91cCxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBwYWRzLFxuICAgIHN0cmlkZXMsXG4gICAgLi4uYWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4gIH0pO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgLy8gUmVmZXIgdG8gdGhlIGJlbG93IGxpbmsgZm9yIGFsbCBpbnB1dCBjaGVja3NcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9PcGVyYXRvcnMubWQjQ29udlxuICBpZiAoIWlucHV0cyB8fCAoaW5wdXRzLmxlbmd0aCAhPT0gMiAmJiBpbnB1dHMubGVuZ3RoICE9PSAzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udiByZXF1aXJlcyAyIG9yIDMgaW5wdXRzJyk7XG4gIH1cblxuICAvLyBUT0RPIDogTmVlZCB0byBhZGQgc3VwcG9ydCBmb3IgbXVsdGktZGltZW5zaW9uYWwgY29udlxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0IHx8IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY3VycmVudGx5IG9ubHkgc3VwcG9ydCAyLWRpbWVuc2lvbmFsIGNvbnYnKTtcbiAgfVxuXG4gIC8vIEZJTFRFUl9JTl9DSEFOTkVMIHNob3VsZCBiZSBlcXVhbCB0byBEQVRBX0NIQU5ORUxcbiAgY29uc3QgZGF0YUNoYW5uZWwgPSBpbnB1dHNbMF0uZGltc1sxXTtcbiAgY29uc3QgZmlsdGVySW5DaGFubmVsID0gaW5wdXRzWzFdLmRpbXNbMV0gKiBhdHRyaWJ1dGVzLmdyb3VwO1xuICBpZiAoZGF0YUNoYW5uZWwgIT09IGZpbHRlckluQ2hhbm5lbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRklMVEVSX0lOX0NIQU5ORUwgc2hvdWxkIGJlIGVxdWFsIHRvIERBVEFfQ0hBTk5FTCcpO1xuICB9XG5cbiAgLy8gaWYgYmlhcyBpcyBwcm92aWRlZCBpdCBzaG91bGQgYmUgMUQgYW5kIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgc2hvdWxkIGJlIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgZmVhdHVyZSBtYXBzXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIChpbnB1dHNbMl0uZGltcy5sZW5ndGggIT09IDEgfHwgaW5wdXRzWzFdLmRpbXNbMF0gIT09IGlucHV0c1syXS5kaW1zWzBdKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBiaWFzJyk7XG4gIH1cblxuICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCAtIDI7XG4gIC8vIHdyb25nIGRpbGF0aW9ucyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMuZGlsYXRpb25zLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGRpbGF0aW9ucyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBzdHJpZGVzIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5zdHJpZGVzLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHN0cmlkZXMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gV3JvbmcgcGFkcyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMucGFkcy5sZW5ndGggIT09IHNwYXRpYWxSYW5rICogMikge1xuICAgIHRocm93IG5ldyBFcnJvcihgcGFkcyBzaG91bGQgYmUgJHtzcGF0aWFsUmFuayAqIDJ9RGApO1xuICB9XG5cbiAgLy8gaWYga2VybmVsU2hhcGUgaXMgc3BlY2lmaWVkLCBpdCdzIGRhdGEgbGVuZ3RoIG11c3QgYmUgMiBsZXNzIHRoYW4gZGltcyBsZW5ndGggb2YgdGhlIHdlaWdodHMgdGVuc29yXG4gIC8vICh0aGUgZmlyc3QgMiBkaW1zIGFyZSBiYXRjaF9zaXplIGFuZCBjaGFubmVscylcbiAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoICE9PSAwICYmIGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoICE9PSBpbnB1dHNbMV0uZGltcy5sZW5ndGggLSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGtlcm5lbCBzaGFwZScpO1xuICB9XG5cbiAgLy8gVE9ETyA6IE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIGZsb2F0NjRcbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgfHwgaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udiBpbnB1dChYLFcpIHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxuXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1syXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnYgaW5wdXQoYmlhcykgc2hvdWxkIGJlIGZsb2F0IHRlbnNvcicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uLy4uLy4uL2JhY2tlbmQnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBDb252QXR0cmlidXRlcyB9IGZyb20gJy4vY29udic7XG5pbXBvcnQgeyBnZXRBY3RpdmF0aW9uU25pcHBldCwgcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIH0gZnJvbSAnLi9mdXNlLXV0aWxzJztcblxuY29uc3QgY29tcHV0ZVRvdGFsUGFkID0gKFxuICBpbkRpbTogbnVtYmVyLFxuICBzdHJpZGU6IG51bWJlcixcbiAgYWRqOiBudW1iZXIsXG4gIGtlcm5lbDogbnVtYmVyLFxuICBkaWxhdGlvbjogbnVtYmVyLFxuICBvdXRTaXplOiBudW1iZXIsXG4pID0+IChpbkRpbSAtIDEpICogc3RyaWRlICsgYWRqICsgKGtlcm5lbCAtIDEpICogZGlsYXRpb24gKyAxIC0gb3V0U2l6ZTtcblxuY29uc3QgZGlzdHJpYnV0ZVBhZGRpbmcgPSAodG90YWxQYWQ6IG51bWJlciwgYXV0b1BhZDogc3RyaW5nLCBwYWRzOiBudW1iZXJbXSwgaGVhZDogbnVtYmVyLCB0YWlsOiBudW1iZXIpID0+IHtcbiAgY29uc3Qgc21hbGxQYWQgPSBNYXRoLmZsb29yKHRvdGFsUGFkIC8gMik7XG4gIGlmIChhdXRvUGFkID09PSAnU0FNRV9VUFBFUicpIHtcbiAgICBwYWRzW2hlYWRdID0gc21hbGxQYWQ7XG4gICAgcGFkc1t0YWlsXSA9IHRvdGFsUGFkIC0gc21hbGxQYWQ7XG4gIH0gZWxzZSBpZiAoYXV0b1BhZCA9PT0gJ1NBTUVfTE9XRVInKSB7XG4gICAgcGFkc1toZWFkXSA9IHRvdGFsUGFkIC0gc21hbGxQYWQ7XG4gICAgcGFkc1t0YWlsXSA9IHNtYWxsUGFkO1xuICB9XG59O1xuXG5jb25zdCBjYWxjdWxhdGVPdXRwdXRTaGFwZUFuZFBhZHMgPSAoXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGF1dG9QYWQ6IHN0cmluZyxcbiAgcGFkczogbnVtYmVyW10sXG4gIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvdXRwdXRQYWRkaW5nOiByZWFkb25seSBudW1iZXJbXSxcbiAgb3V0cHV0U2hhcGU6IG51bWJlcltdLFxuKSA9PiB7XG4gIGNvbnN0IHNwYXRpYWxSYW5rID0gaW5wdXRTaGFwZS5sZW5ndGggLSAyO1xuICBjb25zdCB1cGRhdGVTaGFwZSA9IG91dHB1dFNoYXBlLmxlbmd0aCA9PT0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzcGF0aWFsUmFuazsgKytpKSB7XG4gICAgY29uc3Qgb3V0U2l6ZSA9IHVwZGF0ZVNoYXBlID8gaW5wdXRTaGFwZVtpICsgMl0gKiBzdHJpZGVzW2ldIDogb3V0cHV0U2hhcGVbaV07XG4gICAgY29uc3QgdG90YWxQYWQgPSBjb21wdXRlVG90YWxQYWQoaW5wdXRTaGFwZVtpICsgMl0sIHN0cmlkZXNbaV0sIHBhZHNbaV0sIGtlcm5lbFNoYXBlW2ldLCBkaWxhdGlvbnNbaV0sIG91dFNpemUpO1xuICAgIGRpc3RyaWJ1dGVQYWRkaW5nKHRvdGFsUGFkLCBhdXRvUGFkLCBwYWRzLCBpLCBpICsgc3BhdGlhbFJhbmspO1xuICAgIGlmICh1cGRhdGVTaGFwZSkge1xuICAgICAgb3V0cHV0U2hhcGUucHVzaChcbiAgICAgICAgc3RyaWRlc1tpXSAqIChpbnB1dFNoYXBlW2kgKyAyXSAtIDEpICtcbiAgICAgICAgICBvdXRwdXRQYWRkaW5nW2ldICtcbiAgICAgICAgICAoa2VybmVsU2hhcGVbaV0gLSAxKSAqIGRpbGF0aW9uc1tpXSArXG4gICAgICAgICAgMSAtXG4gICAgICAgICAgcGFkc1tpXSAtXG4gICAgICAgICAgcGFkc1tpICsgc3BhdGlhbFJhbmtdLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMgZXh0ZW5kcyBDb252QXR0cmlidXRlcyB7XG4gIHJlYWRvbmx5IG91dHB1dFBhZGRpbmc6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbmV4cG9ydCBjb25zdCBjb252VHJhbnNwb3NlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7IC8vIGN1cnJlbnRseSB3aWxsIGZhaWwgaWYgbm90IGNvbnZUcmFuc3Bvc2UyRFxuICByZXR1cm4gY29udlRyYW5zcG9zZTJkKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyk7XG59O1xuXG5jb25zdCBjb252VHJhbnNwb3NlMmQ6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248Q29udlRyYW5zcG9zZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCBhZGp1c3RlZEF0dHJpYnV0ZXMgPSBnZXRBZGp1c3RlZENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzKGF0dHJpYnV0ZXMsIGlucHV0cyk7XG4gIHJldHVybiBbY29udlRyYW5zcG9zZTJEVW5wYWNrZWQoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMpXTtcbn07XG5cbmNvbnN0IGNyZWF0ZUNvbnZUcmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEgPSAoaGFzQmlhczogYm9vbGVhbiwgY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdDb252VHJhbnNwb3NlJyxcbiAgaW5wdXROYW1lczogaGFzQmlhcyA/IFsnWCcsICdXJywgJ0InXSA6IFsnWCcsICdXJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXNcbiAgICA/IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXVxuICAgIDogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIGNhY2hlSGludCxcbn0pO1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZENvbnZUcmFuc3Bvc2VQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaGFzQmlhcyA9IGlucHV0cy5sZW5ndGggPiAyO1xuICBjb25zdCB2YWx1ZUluaXQgPSBoYXNCaWFzID8gJ2dldEIob3V0cHV0X2NoYW5uZWwpJyA6ICcwLjAnO1xuICBjb25zdCB4U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qgd1NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dHB1dENoYW5uZWxzUGVyR3JvdXAgPSB3U2hhcGVbMV07XG4gIGNvbnN0IGlucHV0Q2hhbm5lbHNQZXJHcm91cCA9IHdTaGFwZVswXSAvIGF0dHJpYnV0ZXMuZ3JvdXA7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW2lucHV0c1swXS5kaW1zWzBdLCBpbnB1dHNbMV0uZGltc1sxXSAqIGF0dHJpYnV0ZXMuZ3JvdXAsIC4uLmF0dHJpYnV0ZXMub3V0cHV0U2hhcGVdO1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IHsgYWN0aXZhdGlvbkZ1bmN0aW9uLCBhcHBseUFjdGl2YXRpb24gfSA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGF0dHJpYnV0ZXMpO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgY29uc3QgaXZlYzIgc3RyaWRlcyA9IGl2ZWMyKCR7YXR0cmlidXRlcy5zdHJpZGVzWzBdfSwgJHthdHRyaWJ1dGVzLnN0cmlkZXNbMV19KTtcbiAgY29uc3QgaXZlYzIgcGFkcyA9IGl2ZWMyKCR7YXR0cmlidXRlcy5wYWRzWzBdfSwgJHthdHRyaWJ1dGVzLnBhZHNbMV19KTtcbiAgJHthY3RpdmF0aW9uRnVuY3Rpb259XG4gIHZvaWQgbWFpbigpIHtcbiAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICBpbnQgYmF0Y2ggPSBjb29yZHMueDtcbiAgICBpbnQgb3V0cHV0X2NoYW5uZWwgPSBjb29yZHMueTtcblxuICAgIGl2ZWMyIGxvYyA9IGNvb3Jkcy56dyArIHBhZHM7XG5cbiAgICBpbnQgZ3JvdXBfaWQgPSBvdXRwdXRfY2hhbm5lbCAvICR7b3V0cHV0Q2hhbm5lbHNQZXJHcm91cH07XG4gICAgaW50IHdPdXRDaGFubmVsID0gb3V0cHV0X2NoYW5uZWwgLSBncm91cF9pZCAqICR7b3V0cHV0Q2hhbm5lbHNQZXJHcm91cH07XG5cbiAgICBmbG9hdCB2YWx1ZSA9ICR7dmFsdWVJbml0fTtcbiAgICBmb3IgKGludCBpbkNoYW5uZWxPZmZzZXQgPSAwOyBpbkNoYW5uZWxPZmZzZXQgPCAke2lucHV0Q2hhbm5lbHNQZXJHcm91cH07IGluQ2hhbm5lbE9mZnNldCsrKSB7XG4gICAgICBpbnQgaW5wdXRfY2hhbm5lbCA9IGdyb3VwX2lkICogJHtpbnB1dENoYW5uZWxzUGVyR3JvdXB9ICsgaW5DaGFubmVsT2Zmc2V0O1xuICAgICAgZm9yIChpbnQgd1dPZmYgPSAwOyB3V09mZiA8ICR7d1NoYXBlWzJdfTsgd1dPZmYrKykge1xuICAgICAgICBmb3IgKGludCB3SE9mZiA9IDA7IHdIT2ZmIDwgJHt3U2hhcGVbM119OyB3SE9mZisrKSB7XG4gICAgICAgICAgaXZlYzIgd09mZiA9IGl2ZWMyKHdXT2ZmICogJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1swXX0sIHdIT2ZmICogJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXX0pO1xuICAgICAgICAgIGl2ZWMyIHdMb2MgPSBsb2MgLSB3T2ZmO1xuICAgICAgICAgIGl2ZWMyIHdMb2NJbiA9IHdMb2MgLyBzdHJpZGVzO1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHdMb2NJbiAqIHN0cmlkZXMgPT0gd0xvYyAmJlxuICAgICAgICAgICAgd0xvY0luLnggPj0gMCAmJiB3TG9jSW4ueCA8ICR7eFNoYXBlWzJdfSAmJlxuICAgICAgICAgICAgd0xvY0luLnkgPj0gMCAmJiB3TG9jSW4ueSA8ICR7eFNoYXBlWzNdfVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgZmxvYXQgeFZhbCA9IGdldFgoYmF0Y2gsIGlucHV0X2NoYW5uZWwsIHdMb2NJbi55LCB3TG9jSW4ueCk7XG4gICAgICAgICAgICBmbG9hdCB3VmFsID0gZ2V0VyhpbnB1dF9jaGFubmVsLCB3T3V0Q2hhbm5lbCwgd0hPZmYsIHdXT2ZmKTtcbiAgICAgICAgICAgIHZhbHVlICs9IHhWYWwgKiB3VmFsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQodmFsdWUsIC4wLCAuMCwgLjApO1xuICB9XG5gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRDb252VHJhbnNwb3NlUHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlQ29udlRyYW5zcG9zZVByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoID4gMiwgYXR0cmlidXRlcy5jYWNoZUtleSk7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgZ2V0OiAoKSA9PiBjcmVhdGVVbnBhY2tlZENvbnZUcmFuc3Bvc2VQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIG1ldGFkYXRhLCBhdHRyaWJ1dGVzKSxcbiAgfTtcbn07XG5cbmNvbnN0IGNvbnZUcmFuc3Bvc2UyRFVucGFja2VkID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgcmVzdWx0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgY3JlYXRlVW5wYWNrZWRDb252VHJhbnNwb3NlUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5jb25zdCBnZXRBZGp1c3RlZENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzID0gPFQgZXh0ZW5kcyBDb252VHJhbnNwb3NlQXR0cmlidXRlcz4oYXR0cmlidXRlczogVCwgaW5wdXRzOiBUZW5zb3JbXSk6IFQgPT4ge1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGUuc2xpY2UoKTtcbiAgLy8gaWYga2VybmVsU2hhcGUgaXMgbm90IHNwZWNpZmllZCBpbiB0aGUgYXR0cmlidXRlcyBvZiB0aGlzIG9wLCBpbmZlciBpdCBmcm9tIHRoZSB3ZWlnaHQgdGVuc29yIGRpbXNcbiAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChsZXQgaSA9IDI7IGkgPCBpbnB1dHNbMV0uZGltcy5sZW5ndGg7ICsraSkge1xuICAgICAga2VybmVsU2hhcGUucHVzaChpbnB1dHNbMV0uZGltc1tpXSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMucGFkcy5zbGljZSgpO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGF0dHJpYnV0ZXMub3V0cHV0U2hhcGUuc2xpY2UoKTtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICAvLyBJZiBvdXRwdXRTaGFwZSBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgb3AsIGluZmVyIGl0IGZyb20gdGhlIHBhcmFtZXRlcnNcbiAgLy8gU2ltaWxhcmx5LCBhdXRvbWF0aWNhbGx5IGluZmVyIHBhZHMgaWYgbm90IHNwZWNpZmllZFxuICBjYWxjdWxhdGVPdXRwdXRTaGFwZUFuZFBhZHMoXG4gICAgaW5wdXRTaGFwZSxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBhdHRyaWJ1dGVzLmRpbGF0aW9ucyxcbiAgICBhdHRyaWJ1dGVzLmF1dG9QYWQsXG4gICAgcGFkcyxcbiAgICBhdHRyaWJ1dGVzLnN0cmlkZXMsXG4gICAgYXR0cmlidXRlcy5vdXRwdXRQYWRkaW5nLFxuICAgIG91dHB1dFNoYXBlLFxuICApO1xuXG4gIC8vIGFsd2F5cyByZXR1cm4gYSBuZXcgb2JqZWN0IHNvIGRvZXMgbm90IG1vZGlmeSB0aGUgb3JpZ2luYWwgYXR0cmlidXRlc1xuICBjb25zdCBuZXdBdHRyaWJ1dGVzOiBUID0gT2JqZWN0LmFzc2lnbih7fSwgYXR0cmlidXRlcyk7XG4gIE9iamVjdC5hc3NpZ24obmV3QXR0cmlidXRlcywgeyBrZXJuZWxTaGFwZSwgcGFkcywgb3V0cHV0U2hhcGUsIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5IH0pO1xuICByZXR1cm4gbmV3QXR0cmlidXRlcztcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXR0cmlidXRlcyA9IG5vZGUuYXR0cmlidXRlcztcbiAgY29uc3QgYWN0aXZhdGlvbkF0dHJpYnV0ZXMgPSBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMoYXR0cmlidXRlcyk7XG4gIC8vIFRPRE8gOiBNYWtlIHRoaXMgZ2VuZXJpYyBlbm91Z2ggdG8gY29tcHV0ZSBkZWZhdWx0IGF0dHJpYnV0ZXMgZm9yIG11bHRpLWRpbWVuc2lvbmFsIGNvbnZcbiAgY29uc3QgYXV0b1BhZCA9IGF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdhdXRvX3BhZCcsICdOT1RTRVQnKTtcbiAgY29uc3QgZGlsYXRpb25zID0gYXR0cmlidXRlcy5nZXRJbnRzKCdkaWxhdGlvbnMnLCBbMSwgMV0pO1xuICBjb25zdCBncm91cCA9IGF0dHJpYnV0ZXMuZ2V0SW50KCdncm91cCcsIDEpO1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMuZ2V0SW50cygna2VybmVsX3NoYXBlJywgW10pO1xuICBjb25zdCBvdXRwdXRQYWRkaW5nID0gYXR0cmlidXRlcy5nZXRJbnRzKCdvdXRwdXRfcGFkZGluZycsIFswLCAwXSk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gYXR0cmlidXRlcy5nZXRJbnRzKCdvdXRwdXRfc2hhcGUnLCBbXSk7XG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnLCBbMCwgMCwgMCwgMF0pO1xuICBjb25zdCBzdHJpZGVzID0gYXR0cmlidXRlcy5nZXRJbnRzKCdzdHJpZGVzJywgWzEsIDFdKTtcblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBhdXRvUGFkLFxuICAgIGRpbGF0aW9ucyxcbiAgICBncm91cCxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBvdXRwdXRQYWRkaW5nLFxuICAgIG91dHB1dFNoYXBlLFxuICAgIHBhZHMsXG4gICAgc3RyaWRlcyxcbiAgICAuLi5hY3RpdmF0aW9uQXR0cmlidXRlcyxcbiAgfSk7XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICAvLyBSZWZlciB0byB0aGUgYmVsb3cgbGluayBmb3IgYWxsIGlucHV0IGNoZWNrc1xuICAvLyBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L2Jsb2IvbWFpbi9kb2NzL09wZXJhdG9ycy5tZCNDb252XG4gIGlmICghaW5wdXRzIHx8IChpbnB1dHMubGVuZ3RoICE9PSAyICYmIGlucHV0cy5sZW5ndGggIT09IDMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252IHJlcXVpcmVzIDIgb3IgMyBpbnB1dHMnKTtcbiAgfVxuXG4gIC8vIFRPRE8gOiBOZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBtdWx0aS1kaW1lbnNpb25hbCBjb252XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQgfHwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50bHkgb25seSBzdXBwb3J0IDItZGltZW5zaW9uYWwgY29udicpO1xuICB9XG5cbiAgLy8gRklMVEVSX0lOX0NIQU5ORUwgc2hvdWxkIGJlIGVxdWFsIHRvIERBVEFfQ0hBTk5FTFxuICBjb25zdCBkYXRhQ2hhbm5lbCA9IGlucHV0c1swXS5kaW1zWzFdO1xuICBjb25zdCBmaWx0ZXJJbkNoYW5uZWwgPSBpbnB1dHNbMV0uZGltc1swXTtcbiAgaWYgKGRhdGFDaGFubmVsICE9PSBmaWx0ZXJJbkNoYW5uZWwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZJTFRFUl9JTl9DSEFOTkVMIHNob3VsZCBiZSBlcXVhbCB0byBEQVRBX0NIQU5ORUwnKTtcbiAgfVxuXG4gIGNvbnN0IGZlYXR1cmVNYXBzID0gaW5wdXRzWzFdLmRpbXNbMV0gKiBhdHRyaWJ1dGVzLmdyb3VwO1xuXG4gIC8vIGlmIGJpYXMgaXMgcHJvdmlkZWQgaXQgc2hvdWxkIGJlIDFEIGFuZCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHNob3VsZCBiZSBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGZlYXR1cmUgbWFwc1xuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiAoaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAxIHx8IGlucHV0c1syXS5kaW1zWzBdICE9PSBmZWF0dXJlTWFwcykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYmlhcycpO1xuICB9XG5cbiAgY29uc3Qgc3BhdGlhbFJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAyO1xuICAvLyB3cm9uZyBkaWxhdGlvbnMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLmRpbGF0aW9ucy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBkaWxhdGlvbnMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gV3Jvbmcgc3RyaWRlcyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBzdHJpZGVzIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIHBhZHMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLnBhZHMubGVuZ3RoICE9PSBzcGF0aWFsUmFuayAqIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHBhZHMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmsgKiAyfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIG91dHB1dCBwYWRkaW5nIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5vdXRwdXRQYWRkaW5nLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG91dHB1dF9wYWRkaW5nIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIHNwZWNpZmllZCwgaXQncyBkYXRhIGxlbmd0aCBtdXN0IGJlIDIgbGVzcyB0aGFuIGRpbXMgbGVuZ3RoIG9mIHRoZSB3ZWlnaHRzIHRlbnNvclxuICAvLyAodGhlIGZpcnN0IDIgZGltcyBhcmUgYmF0Y2hfc2l6ZSBhbmQgY2hhbm5lbHMpXG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gMCAmJiBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBrZXJuZWwgc2hhcGUnKTtcbiAgfVxuXG4gIC8vIGFzIHdpdGgga2VybmVsU2hhcGUsIG11c3QgaGF2ZSBzYW1lIG51bWJlciBvZiBzcGF0aWFsIGRpbXMgYXMgaW5wdXRcbiAgaWYgKGF0dHJpYnV0ZXMub3V0cHV0U2hhcGUubGVuZ3RoICE9PSAwICYmIGF0dHJpYnV0ZXMub3V0cHV0U2hhcGUubGVuZ3RoICE9PSBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIG91dHB1dCBzaGFwZScpO1xuICB9XG5cbiAgLy8gVE9ETyA6IE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIGZsb2F0NjRcbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgfHwgaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udlRyYW5zcG9zZSBpbnB1dChYLFcpIHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxuXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1syXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnZUcmFuc3Bvc2UgaW5wdXQoYmlhcykgc2hvdWxkIGJlIGZsb2F0IHRlbnNvcicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zcG9zZUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBwZXJtOiBudW1iZXJbXTtcbn1cblxuY29uc3QgdHJhbnNwb3NlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnVHJhbnNwb3NlJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3QgdHJhbnNwb3NlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFRyYW5zcG9zZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFRyYW5zcG9zZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLnRyYW5zcG9zZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBhdHRyaWJ1dGVzLnBlcm0pLFxuICAgIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VUcmFuc3Bvc2VBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFRyYW5zcG9zZUF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogVHJhbnNwb3NlQXR0cmlidXRlcyA9PiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBwZXJtOiBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygncGVybScsIFtdKSB9KTtcblxuY29uc3QgY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8gPSAoXG4gIF9pbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIHBlcm06IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXQuZGltcztcbiAgcGVybSA9IGdldEFkanVzdGVkUGVybShpbnB1dFNoYXBlLCBwZXJtKTtcbiAgY29uc3QgdW5wYWNrZWRPdXRwdXRTaGFwZSA9IGdldE91dHB1dFNoYXBlKGlucHV0U2hhcGUsIHBlcm0pO1xuICBjb25zdCByYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG4gIC8vIEEgZGltcz1bJHtpbnB1dHNbMF0uZGltcy50b1N0cmluZygpfV1cbiAgLy8gb3V0IERpbXM9WyR7dW5wYWNrZWRPdXRwdXRTaGFwZS50b1N0cmluZygpfV1cbiAgLy8gYmFzZWQgb24gcGVybT1bJHtwZXJtLnRvU3RyaW5nKCl9XVxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke2dldFBlcm1GdW5jdGlvbkJvZHkoJ3Blcm0nLCBwZXJtLCByYW5rKX1cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IGFbJHtyYW5rfV07XG4gICAgICAgIHBlcm0oYSwgaW5kaWNlcyk7XG4gICAgICAgIHJldHVybiBfQShhKTtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLnRyYW5zcG9zZVByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogdW5wYWNrZWRPdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRQZXJtID0gKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwZXJtOiBudW1iZXJbXSk6IG51bWJlcltdID0+IHtcbiAgaWYgKHBlcm0gJiYgcGVybS5sZW5ndGggIT09IGlucHV0U2hhcGUubGVuZ3RoKSB7XG4gICAgcGVybSA9IFsuLi5pbnB1dFNoYXBlLmtleXMoKV0ucmV2ZXJzZSgpO1xuICB9XG4gIHJldHVybiBwZXJtO1xufTtcblxuY29uc3QgZ2V0T3V0cHV0U2hhcGUgPSAoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHBlcm06IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10gPT4ge1xuICBwZXJtID0gZ2V0QWRqdXN0ZWRQZXJtKGlucHV0U2hhcGUsIHBlcm0pO1xuICByZXR1cm4gU2hhcGVVdGlsLnNvcnRCYXNlZE9uUGVybShpbnB1dFNoYXBlLCBwZXJtKTtcbn07XG5cbmNvbnN0IGdldFBlcm1GdW5jdGlvbkJvZHkgPSAobmFtZTogc3RyaW5nLCBwZXJtOiBudW1iZXJbXSwgcmFuazogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcmV2ZXJzZUZ1bmMgPSBbXTtcbiAgcmV2ZXJzZUZ1bmMucHVzaChgdm9pZCAke25hbWV9KG91dCBpbnQgYVske3Jhbmt9XSwgaW50IHNyY1ske3Jhbmt9XSkge2ApO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7ICsraSkge1xuICAgIHJldmVyc2VGdW5jLnB1c2goYFxcdGFbJHtwZXJtW2ldfV09c3JjWyR7aX1dO2ApO1xuICB9XG4gIHJldmVyc2VGdW5jLnB1c2goJ1xcdH0nKTtcbiAgcmV0dXJuIHJldmVyc2VGdW5jLmpvaW4oJ1xcbicpO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUcmFuc3Bvc2UgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmltcG9ydCB7IHRyYW5zcG9zZSwgVHJhbnNwb3NlQXR0cmlidXRlcyB9IGZyb20gJy4vdHJhbnNwb3NlJztcblxuZXhwb3J0IGludGVyZmFjZSBEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzIHtcbiAgbW9kZTogJ0RDUicgfCAnQ1JEJztcbiAgYmxvY2tzaXplOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBkZXB0aFRvU3BhY2U6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248RGVwdGhUb1NwYWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogRGVwdGhUb1NwYWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3QgYmxvY2tzaXplID0gYXR0cmlidXRlcy5ibG9ja3NpemU7XG4gIGNvbnN0IGJsb2Nrc2l6ZVNxciA9IGJsb2Nrc2l6ZSAqIGJsb2Nrc2l6ZTtcbiAgY29uc3QgdHJhbnNwb3NlUGVybSA9IGF0dHJpYnV0ZXMubW9kZSA9PT0gJ0RDUicgPyBbMCwgMywgNCwgMSwgNSwgMl0gOiBbMCwgMSwgNCwgMiwgNSwgM107XG4gIGNvbnN0IGZpcnN0UmVzaGFwZVNoYXBlID1cbiAgICBhdHRyaWJ1dGVzLm1vZGUgPT09ICdEQ1InXG4gICAgICA/IFtcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1swXSxcbiAgICAgICAgICBibG9ja3NpemUsXG4gICAgICAgICAgYmxvY2tzaXplLFxuICAgICAgICAgIGlucHV0c1swXS5kaW1zWzFdIC8gYmxvY2tzaXplU3FyLFxuICAgICAgICAgIGlucHV0c1swXS5kaW1zWzJdLFxuICAgICAgICAgIGlucHV0c1swXS5kaW1zWzNdLFxuICAgICAgICBdXG4gICAgICA6IFtcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1swXSxcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1sxXSAvIGJsb2Nrc2l6ZVNxcixcbiAgICAgICAgICBibG9ja3NpemUsXG4gICAgICAgICAgYmxvY2tzaXplLFxuICAgICAgICAgIGlucHV0c1swXS5kaW1zWzJdLFxuICAgICAgICAgIGlucHV0c1swXS5kaW1zWzNdLFxuICAgICAgICBdO1xuXG4gIC8vIGNvbnN0IHRyYW5zcG9zZSA9IG5ldyBXZWJHTFRyYW5zcG9zZSgpO1xuICAvLyBjb25zdCBhdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZSh1bmRlZmluZWQpO1xuICAvLyBhdHRyaWJ1dGVzLnNldCgncGVybScsICdpbnRzJywgdHJhbnNwb3NlUGVybSk7XG4gIC8vIHRyYW5zcG9zZS5pbml0aWFsaXplKGF0dHJpYnV0ZXMpO1xuXG4gIC8vIEZpcnN0IHJlc2hhcGVcbiAgY29uc3QgZmlyc3RSZXNoYXBlZFRlbnNvciA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1swXSwgZmlyc3RSZXNoYXBlU2hhcGUpO1xuXG4gIC8vIHRyYW5zcG9zZVxuICBjb25zdCB0cmFuc3Bvc2VBdHRyaWJ1dGVzOiBUcmFuc3Bvc2VBdHRyaWJ1dGVzID0geyBwZXJtOiB0cmFuc3Bvc2VQZXJtLCBjYWNoZUtleTogYCR7dHJhbnNwb3NlUGVybX1gIH07XG4gIGNvbnN0IFt0cmFuc3Bvc2VPdXRwdXRdID0gdHJhbnNwb3NlKGluZmVyZW5jZUhhbmRsZXIsIFtmaXJzdFJlc2hhcGVkVGVuc29yXSwgdHJhbnNwb3NlQXR0cmlidXRlcyk7XG5cbiAgLy8gU2Vjb25kIHJlc2hhcGVcbiAgY29uc3Qgc2Vjb25kUmVzaGFwZVNoYXBlID0gW1xuICAgIGlucHV0c1swXS5kaW1zWzBdLFxuICAgIGlucHV0c1swXS5kaW1zWzFdIC8gYmxvY2tzaXplU3FyLFxuICAgIGlucHV0c1swXS5kaW1zWzJdICogYmxvY2tzaXplLFxuICAgIGlucHV0c1swXS5kaW1zWzNdICogYmxvY2tzaXplLFxuICBdO1xuICBjb25zdCByZXN1bHQgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZCh0cmFuc3Bvc2VPdXRwdXQsIHNlY29uZFJlc2hhcGVTaGFwZSk7XG4gIHJldHVybiBbcmVzdWx0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZURlcHRoVG9TcGFjZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248RGVwdGhUb1NwYWNlQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzID0+IHtcbiAgLy8gcHJvY2Vzc2luZyBub2RlIGF0dHJpYnV0ZXNcbiAgY29uc3QgYmxvY2tzaXplID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYmxvY2tzaXplJyk7XG4gIGlmIChibG9ja3NpemUgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBibG9ja3NpemUgbXVzdCBiZSA+PSAxLCBidXQgZ290IDogJHtibG9ja3NpemV9IGZvciBEZXB0aFRvU3BhY2VgKTtcbiAgfVxuICBjb25zdCBtb2RlID0gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbW9kZScsICdEQ1InKTtcbiAgaWYgKG1vZGUgIT09ICdEQ1InICYmIG1vZGUgIT09ICdDUkQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGB1bnJlY29nbml6ZWQgbW9kZTogJHttb2RlfSBmb3IgRGVwdGhUb1NwYWNlYCk7XG4gIH1cbiAgcmV0dXJuIHsgbW9kZSwgYmxvY2tzaXplIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmIChpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBEZXB0aFRvU3BhY2UgZXhwZWN0IDEgaW5wdXRzLCBidXQgZ290ICR7aW5wdXRzLmxlbmd0aH1gKTtcbiAgfVxuXG4gIC8vIElucHV0IGhhcyB0byBiZSBhIDQtRCB0ZW5zb3JcbiAgLy8gVE9ETzogU3VwcG9ydCBzdHJpbmcgZGVwdGgtdG8tc3BhY2UuXG4gIGlmIChpbnB1dHNbMF0udHlwZSA9PT0gJ3N0cmluZycgfHwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRGVwdGhUb1NwYWNlIGlucHV0IHNob3VsZCBiZSBhIDQtRCBudW1lcmljIHRlbnNvcicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3QgZmxhdHRlbjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxudW1iZXI+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF4aXM6IG51bWJlcixcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBheGlzKTtcblxuICBjb25zdCBvdXRwdXREaW1zID0gU2hhcGVVdGlsLmZsYXR0ZW5TaGFwZShpbnB1dHNbMF0uZGltcywgYXhpcyk7XG4gIHJldHVybiBbaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBvdXRwdXREaW1zKV07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VGbGF0dGVuQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxudW1iZXI+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBudW1iZXIgPT5cbiAgbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIDEpOyAvLyBkZWZhdWx0IGF4aXMgaXMgMVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBheGlzOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRmxhdHRlbiByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgY29uc3QgciA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcbiAgaWYgKHIgPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NjYWxhciB0ZW5zb3IgaXMgbm90IHN1cHBvcnRlZC4nKTtcbiAgfVxuXG4gIGlmIChheGlzIDwgLXIgfHwgYXhpcyA+IHIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYXhpcycpO1xuICB9XG5cbiAgLy8gVE9ETzogU3VwcG9ydCBzdHJpbmcgdHlwZVxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzdHJpbmcgdGVuc29yIGlzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuL2JhY2tlbmQnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yJztcblxuZXhwb3J0IHR5cGUgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxUPiA9IChpbmZlcmVuY2VIYW5kbGVyOiBJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBjb250ZXh0OiBUKSA9PiBUZW5zb3JbXTtcbmV4cG9ydCB0eXBlIE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VD4gPSAobm9kZTogR3JhcGguTm9kZSwgZ3JhcGg6IEdyYXBoKSA9PiBUO1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wZXJhdG9yIHtcbiAgcmVhZG9ubHkgaW1wbDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjx1bmtub3duPjtcbiAgcmVhZG9ubHkgY29udGV4dDogR3JhcGguTm9kZSB8IHVua25vd247XG59XG5cbmV4cG9ydCBjb25zdCBOVU1CRVJfVFlQRVM6IHJlYWRvbmx5IFRlbnNvci5EYXRhVHlwZVtdID0gW1xuICAnZmxvYXQzMicsXG4gICdmbG9hdDY0JyxcbiAgJ2ludDMyJyxcbiAgJ2ludDE2JyxcbiAgJ2ludDgnLFxuICAndWludDE2JyxcbiAgJ3VpbnQzMicsXG4gICd1aW50OCcsXG5dO1xuZXhwb3J0IGNvbnN0IElOVF9UWVBFUzogcmVhZG9ubHkgVGVuc29yLkRhdGFUeXBlW10gPSBbJ2ludDMyJywgJ2ludDE2JywgJ2ludDgnLCAndWludDE2JywgJ3VpbnQzMicsICd1aW50OCddO1xuZXhwb3J0IGNvbnN0IEZMT0FUX1RZUEVTOiByZWFkb25seSBUZW5zb3IuRGF0YVR5cGVbXSA9IFsnZmxvYXQzMicsICdmbG9hdDY0J107XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgTlVNQkVSX1RZUEVTLCBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW50ZXJmYWNlIEdhdGhlckF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGlzOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBnYXRoZXI6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248R2F0aGVyQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogR2F0aGVyQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzLmF4aXMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVHYXRoZXJQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLCBpbnB1dHMpO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VHYXRoZXJBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEdhdGhlckF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBHYXRoZXJBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGF4aXM6IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnLCAwKSB9KTtcblxuY29uc3QgZ2F0aGVyUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnR2F0aGVyJyxcbiAgaW5wdXROYW1lczogWydBJywgJ0InXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVHYXRoZXJQcm9ncmFtSW5mbyA9IChcbiAgX2hhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXhpczogbnVtYmVyLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgaW5kZXhEYXRhU2hhcGUgPSBpbnB1dHNbMV0uZGltcy5zbGljZSgpO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IG5ldyBBcnJheShpbnB1dFNoYXBlLmxlbmd0aCArIGluZGV4RGF0YVNoYXBlLmxlbmd0aCAtIDEpO1xuXG4gIGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhheGlzLCBpbnB1dFNoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IGluZGV4Q29weU9wczogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRTaGFwZS5sZW5ndGg7IGkrKykge1xuICAgIC8vIG91dHB1dFNoYXBlIGlzIGRpdmlkZWQgaW50byB0aHJlZSBwYXJ0czogQSwgQiwgQ1xuICAgIC8vIHwwICAgICAgICBheGlzfCAgYXhpcyArIGluZGV4RGF0YVNoYXBlLmxlbmd0aCB8ICAgICAgICAgIGVuZHxcbiAgICAvLyB8ICAgICBBICAgICAgIHwgICAgICAgICAgICAgQiAgICAgICAgICAgICAgICAgfCAgICAgIEMgICAgICB8XG4gICAgLy9cbiAgICAvLyBpbnB1dElkeDogW0EsIGlucHV0c1sxXVtCXSwgQ11cbiAgICBpZiAoaSA8IGF4aXMpIHtcbiAgICAgIC8vIEFcbiAgICAgIG91dHB1dFNoYXBlW2ldID0gaW5wdXRTaGFwZVtpXTtcbiAgICAgIGluZGV4Q29weU9wcy5wdXNoKGBpbnB1dElkeFske2l9XSA9IG91dHB1dElkeFske2l9XTtgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGkgPCBheGlzICsgaW5kZXhEYXRhU2hhcGUubGVuZ3RoKSB7XG4gICAgICAgIC8vIEJcbiAgICAgICAgb3V0cHV0U2hhcGVbaV0gPSBpbmRleERhdGFTaGFwZVtpIC0gYXhpc107XG4gICAgICAgIGluZGV4Q29weU9wcy5wdXNoKGBpbmRleERhdGFJZHhbJHtpIC0gYXhpc31dID0gb3V0cHV0SWR4WyR7aX1dO2ApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ1xuICAgICAgICBvdXRwdXRTaGFwZVtpXSA9IGlucHV0U2hhcGVbaSAtIGluZGV4RGF0YVNoYXBlLmxlbmd0aCArIDFdOyAvLyBza2lwIDEgZm9yIGF4aXNcbiAgICAgICAgaW5kZXhDb3B5T3BzLnB1c2goYGlucHV0SWR4WyR7aSAtIGluZGV4RGF0YVNoYXBlLmxlbmd0aCArIDF9XSA9IG91dHB1dElkeFske2l9XTtgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBvcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aCB8fCAxO1xuICBjb25zdCBpcmFuayA9IGlucHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBpRHJhbmsgPSBpbmRleERhdGFTaGFwZS5sZW5ndGggfHwgMTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgb3V0cHV0SWR4WyR7b3Jhbmt9XSkge1xuICAgICAgICBpbnQgaW5wdXRJZHhbJHtpcmFua31dO1xuICAgICAgICBpbnQgaW5kZXhEYXRhSWR4WyR7aURyYW5rfV07XG4gICAgICAgIGluZGV4RGF0YUlkeFswXSA9IDA7XG4gICAgICAgICR7aW5kZXhDb3B5T3BzLmpvaW4oJ1xcbiAgICAgICAgJyl9XG4gICAgICAgIGludCBpZHggPSBpbnQoX0IoaW5kZXhEYXRhSWR4KSk7XG4gICAgICAgIGlucHV0SWR4WyR7YXhpc31dID0gaWR4IDwgMCA/IGlkeCArICR7aW5wdXRTaGFwZVtheGlzXX0gOiBpZHg7XG4gICAgICAgIHJldHVybiBfQShpbnB1dElkeCk7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVHYXRoZXJQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBHYXRoZXJBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IHsgLi4uZ2F0aGVyUHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXkgfTtcbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm8oaGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgYXR0cmlidXRlcy5heGlzKSB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhpczogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dhdGhlciByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxuICBjb25zdCB0ZW5zb3JSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoO1xuICBpZiAodGVuc29yUmFuayA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKGF4aXMgPCAtdGVuc29yUmFuayB8fCBheGlzID4gdGVuc29yUmFuayAtIDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYXhpcy4nKTtcbiAgfVxuICBpZiAoTlVNQkVSX1RZUEVTLmluZGV4T2YoaW5wdXRzWzBdLnR5cGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInICYmIGlucHV0c1sxXS50eXBlICE9PSAnaW50MTYnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBHZW1tVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEdlbW1BdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgdHJhbnNBOiBib29sZWFuO1xuICB0cmFuc0I6IGJvb2xlYW47XG4gIGFscGhhOiBudW1iZXI7XG4gIGJldGE6IG51bWJlcjtcbiAgaXNPcHRpb25hbEM6IGJvb2xlYW47IC8vIGluIG9wc2V0IDExLCBDIGJlY29tZXMgb3B0aW9uYWxcbn1cblxuZXhwb3J0IGNvbnN0IGdlbW06IE9wZXJhdG9ySW1wbGVtZW50YXRpb248R2VtbUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEdlbW1BdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVHZW1tUHJvZ3JhbUluZm9Mb2FkZXIoaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgcGFyc2VHZW1tQXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlLCBpc09wdGlvbmFsQzogYm9vbGVhbik6IEdlbW1BdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgdHJhbnNBID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgndHJhbnNBJywgMCkgIT09IDA7XG4gIGNvbnN0IHRyYW5zQiA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3RyYW5zQicsIDApICE9PSAwO1xuICBjb25zdCBhbHBoYSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYWxwaGEnLCAxLjApO1xuICBjb25zdCBiZXRhID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdiZXRhJywgMS4wKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IHRyYW5zQSwgdHJhbnNCLCBhbHBoYSwgYmV0YSwgaXNPcHRpb25hbEMgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VHZW1tQXR0cmlidXRlc1Y3OiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEdlbW1BdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogR2VtbUF0dHJpYnV0ZXMgPT5cbiAgcGFyc2VHZW1tQXR0cmlidXRlcyhub2RlLCBmYWxzZSk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdlbW1BdHRyaWJ1dGVzVjExOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEdlbW1BdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogR2VtbUF0dHJpYnV0ZXMgPT5cbiAgcGFyc2VHZW1tQXR0cmlidXRlcyhub2RlLCB0cnVlKTtcblxuY29uc3QgY3JlYXRlR2VtbVByb2dyYW1JbmZvTG9hZGVyID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IEdlbW1BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IHtcbiAgICBuYW1lOiAnR2VtbScsXG4gICAgaW5wdXROYW1lczogaW5wdXRzLmxlbmd0aCA9PT0gMyA/IFsnQScsICdCJywgJ0MnXSA6IFsnQScsICdCJ10sXG4gICAgaW5wdXRUeXBlczpcbiAgICAgIGlucHV0cy5sZW5ndGggPT09IDNcbiAgICAgICAgPyBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF1cbiAgICAgICAgOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgICBrZXk6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gIH07XG5cbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlR2VtbVByb2dyYW1JbmZvKG1ldGFkYXRhLCBpbnB1dHMsIGF0dHJpYnV0ZXMpIH07XG59O1xuXG5jb25zdCBjcmVhdGVHZW1tUHJvZ3JhbUluZm8gPSAoXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEdlbW1BdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBhU2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBiU2hhcGUgPSBpbnB1dHNbMV0uZGltcy5zbGljZSgpO1xuICBjb25zdCBbTSwgTl0gPSBHZW1tVXRpbC5nZXRTaGFwZU9mR2VtbVJlc3VsdChcbiAgICBhU2hhcGUsXG4gICAgYXR0cmlidXRlcy50cmFuc0EsXG4gICAgYlNoYXBlLFxuICAgIGF0dHJpYnV0ZXMudHJhbnNCLFxuICAgIGlucHV0cy5sZW5ndGggPT09IDMgPyBpbnB1dHNbMl0uZGltcyA6IHVuZGVmaW5lZCxcbiAgKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBbTSwgTl07XG4gIGlmICghb3V0cHV0U2hhcGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCB1c2UgZ2VtbSBvbiB0aGUgZ2l2ZW4gdGVuc29yc1wiKTtcbiAgfVxuICBsZXQgc2hhcmVkRGltID0gYVNoYXBlW2FTaGFwZS5sZW5ndGggLSAxXTtcbiAgbGV0IGxpbmUgPSAnJztcbiAgaWYgKGF0dHJpYnV0ZXMudHJhbnNBKSB7XG4gICAgc2hhcmVkRGltID0gYVNoYXBlWzBdO1xuICB9XG4gIGlmIChhdHRyaWJ1dGVzLnRyYW5zQSAmJiBhdHRyaWJ1dGVzLnRyYW5zQikge1xuICAgIGxpbmUgPSAndmFsdWUgKz0gX0FfVChhKSAqIF9CX1QoYik7JztcbiAgfSBlbHNlIGlmIChhdHRyaWJ1dGVzLnRyYW5zQSAmJiAhYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICBsaW5lID0gJ3ZhbHVlICs9IF9BX1QoYSkgKiBfQihiKTsnO1xuICB9IGVsc2UgaWYgKCFhdHRyaWJ1dGVzLnRyYW5zQSAmJiBhdHRyaWJ1dGVzLnRyYW5zQikge1xuICAgIGxpbmUgPSAndmFsdWUgKz0gX0EoYSkgKiBfQl9UKGIpOyc7XG4gIH0gZWxzZSBpZiAoIWF0dHJpYnV0ZXMudHJhbnNBICYmICFhdHRyaWJ1dGVzLnRyYW5zQikge1xuICAgIGxpbmUgPSAndmFsdWUgKz0gX0EoYSkgKiBfQihiKTsnO1xuICB9XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGRlY2xhcmVDID0gaW5wdXRzLmxlbmd0aCA9PT0gMyA/IGBpbnQgY1ske2lucHV0c1syXS5kaW1zLmxlbmd0aH1dO2AgOiAnJztcbiAgY29uc3QgYnJvYWRjYXN0QyA9IGlucHV0cy5sZW5ndGggPT09IDMgPyAnYmNhc3RJbmRpY2VzX0MoaW5kaWNlcywgYyk7JyA6ICcnO1xuICBjb25zdCBjYWxjdWxhdGVDID0gaW5wdXRzLmxlbmd0aCA9PT0gMyA/ICd2YWx1ZSArPSBiZXRhICogX0MoYyk7JyA6ICcnO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IGFbJHtyYW5rfV07XG4gICAgICAgICAgaW50IGJbJHtyYW5rfV07XG4gICAgICAgICAgJHtkZWNsYXJlQ31cblxuICAgICAgICAgIGNvcHlWZWMoaW5kaWNlcywgYSk7XG4gICAgICAgICAgY29weVZlYyhpbmRpY2VzLCBiKTtcbiAgICAgICAgICAke2Jyb2FkY2FzdEN9XG5cbiAgICAgICAgICBmbG9hdCB2YWx1ZSA9IDAuMDtcbiAgICAgICAgICBmb3IgKGludCBrPTA7IGs8JHtzaGFyZWREaW19OyArK2spIHtcbiAgICAgICAgICAgICAgYVske3JhbmsgLSAxfV0gPSBrO1xuICAgICAgICAgICAgICBiWyR7cmFuayAtIDJ9XSA9IGs7XG4gICAgICAgICAgICAgICR7bGluZX1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlICogYWxwaGE7XG4gICAgICAgICAgJHtjYWxjdWxhdGVDfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHZhcmlhYmxlczogW1xuICAgICAgeyBuYW1lOiAnYWxwaGEnLCB0eXBlOiAnZmxvYXQnLCBkYXRhOiBhdHRyaWJ1dGVzLmFscGhhIH0sXG4gICAgICB7IG5hbWU6ICdiZXRhJywgdHlwZTogJ2Zsb2F0JywgZGF0YTogYXR0cmlidXRlcy5iZXRhIH0sXG4gICAgXSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBHZW1tQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgaXMgbWlzc2luZycpO1xuICB9XG4gIGlmIChhdHRyaWJ1dGVzLmlzT3B0aW9uYWxDICYmIChpbnB1dHMubGVuZ3RoIDwgMiB8fCBpbnB1dHMubGVuZ3RoID4gMykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoIWF0dHJpYnV0ZXMuaXNPcHRpb25hbEMgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMykge1xuICAgIHRocm93IG5ldyBFcnJvcignR2VtbSByZXF1aXJlcyAzIGlucHV0cycpO1xuICB9XG5cbiAgLy8gJ0MnIGNhbiBiZSBvZiBkaW1lbnNpb25hbGl0eSAxIG9yIDIgb25seVxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMl0uZGltcy5sZW5ndGggIT09IDEgJiYgaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlIG9mIEMnKTtcbiAgfVxuXG4gIGlmIChcbiAgICAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgIChpbnB1dHNbMV0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgaW5wdXRzWzJdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMl0udHlwZSAhPT0gJ2Zsb2F0NjQnKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gaW5wdXRzWzFdLnR5cGUgfHwgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgaW5wdXRzWzBdLnR5cGUgIT09IGlucHV0c1syXS50eXBlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgdHlwZXMgYXJlIG1pc21hdGNoZWQnKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgc2NhbGU6IG51bWJlcjtcbiAgYmlhczogbnVtYmVyW107XG59XG5cbmV4cG9ydCBjb25zdCBpbWFnZVNjYWxlcjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxJbWFnZVNjYWxlckF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEltYWdlU2NhbGVyQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlSW1hZ2VTY2FsZXJQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLCBpbnB1dHMpO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VJbWFnZVNjYWxlckF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248SW1hZ2VTY2FsZXJBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IEltYWdlU2NhbGVyQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IHNjYWxlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdzY2FsZScpO1xuICBjb25zdCBiaWFzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0cygnYmlhcycpO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgc2NhbGUsIGJpYXMgfSk7XG59O1xuXG5jb25zdCBpbWFnZVNjYWxlclByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0ltYWdlU2NhbGVyJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVJbWFnZVNjYWxlclByb2dyYW1JbmZvID0gKFxuICBfaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBJbWFnZVNjYWxlckF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgZ2V0Qmlhc01ldGhvZCA9IGNyZWF0ZUdldEJpYXNNZXRob2QoYXR0cmlidXRlcy5iaWFzLmxlbmd0aCk7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICR7Z2V0Qmlhc01ldGhvZH1cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgcmV0dXJuIF9YKGluZGljZXMpICogc2NhbGUgKyBnZXRCaWFzKGJpYXMsIGluZGljZXNbMV0pO1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgdmFyaWFibGVzOiBbXG4gICAgICB7IG5hbWU6ICdiaWFzJywgdHlwZTogJ2Zsb2F0JywgYXJyYXlMZW5ndGg6IGF0dHJpYnV0ZXMuYmlhcy5sZW5ndGgsIGRhdGE6IGF0dHJpYnV0ZXMuYmlhcyB9LFxuICAgICAgeyBuYW1lOiAnc2NhbGUnLCB0eXBlOiAnZmxvYXQnLCBkYXRhOiBhdHRyaWJ1dGVzLnNjYWxlIH0sXG4gICAgXSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVJbWFnZVNjYWxlclByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEltYWdlU2NhbGVyQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSB7IC4uLmltYWdlU2NhbGVyUHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXkgfTtcbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlSW1hZ2VTY2FsZXJQcm9ncmFtSW5mbyhoYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBhdHRyaWJ1dGVzKSB9O1xufTtcblxuY29uc3QgY3JlYXRlR2V0Qmlhc01ldGhvZCA9IChudW1DaGFubmVsczogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgY29uc3QgY29kZUxpbmVzOiBzdHJpbmdbXSA9IFtgZmxvYXQgZ2V0QmlhcyhmbG9hdCBiaWFzWyR7bnVtQ2hhbm5lbHN9XSwgaW50IGNoYW5uZWwpIHtgXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1DaGFubmVsczsgKytpKSB7XG4gICAgaWYgKGkgPT09IDApIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGlmIChjaGFubmVsID09ICR7aX0pIHsgcmV0dXJuIGJpYXNbJHtpfV07IH1gKTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IG51bUNoYW5uZWxzIC0gMSkge1xuICAgICAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyBgZWxzZSB7IHJldHVybiBiaWFzWyR7aX1dOyB9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGVsc2UgaWYgKGNoYW5uZWwgPT0gJHtpfSkgeyByZXR1cm4gYmlhc1ske2l9XTsgfWApO1xuICAgIH1cbiAgfVxuICBjb2RlTGluZXMucHVzaCgnXFx0JyArICd9Jyk7XG4gIHJldHVybiBjb2RlTGluZXMuam9pbignXFxuJyk7XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltYWdlU2NhbGVyIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IGluc3RhbmNlTm9ybWFsaXphdGlvbjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxudW1iZXI+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGVwc2lsb246IG51bWJlcixcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCBtZWFuQW5kVmFyaWFuY2UgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVNZWFuQW5kVmFyaWFuY2VQcm9ncmFtSW5mb0xvYWRlcihpbnB1dHNbMF0pLCBpbnB1dHMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVDb21wdXRlT3V0cHV0UHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBlcHNpbG9uLCBtZWFuQW5kVmFyaWFuY2UuZGltcyksXG4gICAgW2lucHV0c1swXSwgbWVhbkFuZFZhcmlhbmNlLCBpbnB1dHNbMV0sIGlucHV0c1syXV0sXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUluc3RhbmNlTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248bnVtYmVyPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogbnVtYmVyID0+XG4gIG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnZXBzaWxvbicsIDFlLTUpO1xuXG5jb25zdCBtZWFuQW5kVmFyaWFuY2VQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdJbnN0YW5jZU5vcm1hbGl6YXRpb25fTWVhbkFuZFZhcmlhbmNlJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVNZWFuQW5kVmFyaWFuY2VQcm9ncmFtSW5mbyA9IChtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLCBpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCB4RGltcyA9IGlucHV0LmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgY2hhbm5lbCA9IHhEaW1zWzFdO1xuICBjb25zdCBjaGFubmVsU2l6ZSA9IHhEaW1zWzJdICogeERpbXNbM107XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW3hEaW1zWzBdLCBjaGFubmVsXTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICB2ZWM0IHByb2Nlc3MoaW50WzJdIGluZGljZXMpIHtcbiAgICAgICAgdmVjNCB2ID0gdmVjNCgwLjApO1xuICAgICAgICBpbnQgYVs0XTtcbiAgICAgICAgYVswXSA9IGluZGljZXNbMF07XG4gICAgICAgIGFbMV0gPSBpbmRpY2VzWzFdO1xuICAgICAgICBmbG9hdCB0ZW1wID0gMC4wO1xuICAgICAgICBmb3IoaW50IGEyPTA7IGEyPCR7eERpbXNbMl19OyBhMisrKSB7XG4gICAgICAgICAgYVsyXSA9IGEyO1xuICAgICAgICAgIGZvcihpbnQgYTM9MDsgYTM8JHt4RGltc1szXX07IGEzKyspIHtcbiAgICAgICAgICAgIGFbM10gPSBhMztcbiAgICAgICAgICAgIGZsb2F0IHggPSBfWChhKTtcbiAgICAgICAgICAgIHRlbXAgKz0geDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZmxvYXQgbWVhbiA9IHRlbXAgLyBmbG9hdCgke2NoYW5uZWxTaXplfSk7XG4gICAgICAgIHRlbXAgPSAwLjA7XG4gICAgICAgIGZvcihpbnQgYTI9MDsgYTI8JHt4RGltc1syXX07IGEyKyspIHtcbiAgICAgICAgICBhWzJdID0gYTI7XG4gICAgICAgICAgZm9yKGludCBhMz0wOyBhMzwke3hEaW1zWzNdfTsgYTMrKykge1xuICAgICAgICAgICAgYVszXSA9IGEzO1xuICAgICAgICAgICAgZmxvYXQgeCA9IF9YKGEpO1xuICAgICAgICAgICAgdGVtcCArPSAoeCAtIG1lYW4pICogKHggLSBtZWFuKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdi5yID0gbWVhbjtcbiAgICAgICAgdi5nID0gdGVtcCAvIGZsb2F0KCR7Y2hhbm5lbFNpemV9KTtcblxuICAgICAgICByZXR1cm4gdjtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24gfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVNZWFuQW5kVmFyaWFuY2VQcm9ncmFtSW5mb0xvYWRlciA9IChpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4gKHtcbiAgLi4ubWVhbkFuZFZhcmlhbmNlUHJvZ3JhbU1ldGFkYXRhLFxuICBnZXQ6ICgpID0+IGNyZWF0ZU1lYW5BbmRWYXJpYW5jZVByb2dyYW1JbmZvKG1lYW5BbmRWYXJpYW5jZVByb2dyYW1NZXRhZGF0YSwgaW5wdXQpLFxufSk7XG5cbmNvbnN0IGNvbXB1dGVPdXRwdXRQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdJbnN0YW5jZU5vcm1hbGl6YXRpb25fQ29tcHV0ZU91dHB1dCcsXG4gIGlucHV0TmFtZXM6IFsnWCcsICdNZWFuQW5kVmFyaWFuY2UnLCAnU2NhbGUnLCAnQiddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24sIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVDb21wdXRlT3V0cHV0UHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXQ6IFRlbnNvcixcbiAgZXBzaWxvbjogbnVtYmVyLFxuICBtZWFuQW5kVmFyaWFuY2VTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgW3RleHR1cmVXaWR0aCwgdGV4dHVyZUhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBtZWFuQW5kVmFyaWFuY2VTaGFwZSxcbiAgICBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uLFxuICApO1xuICBjb25zdCBbbWVhbkFuZFZhcmlhbmNlV2lkdGgsIG1lYW5BbmRWYXJpYW5jZUhlaWdodF0gPSBbdGV4dHVyZVdpZHRoIC8gNCwgdGV4dHVyZUhlaWdodF07XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIHZlYzQgZ2V0X01lYW5BbmRWYXJpYW5jZShpbnRbMl0gbXYpIHtcbiAgICAgICAgaW50IG9mZnNldCA9IGluZGljZXNUb09mZnNldF9NZWFuQW5kVmFyaWFuY2UobXYpO1xuICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHttZWFuQW5kVmFyaWFuY2VXaWR0aH0sICR7bWVhbkFuZFZhcmlhbmNlSGVpZ2h0fSk7XG4gICAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfShNZWFuQW5kVmFyaWFuY2UsIGNvb3Jkcyk7XG4gICAgICB9XG5cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50WzRdIGluZGljZXMpIHtcbiAgICAgICAgaW50IG12WzJdO1xuICAgICAgICBtdlswXSA9IGluZGljZXNbMF07XG4gICAgICAgIG12WzFdID0gaW5kaWNlc1sxXTtcbiAgICAgICAgdmVjNCBtZWFuX2FuZF92YXJpYW5jZSA9IGdldF9NZWFuQW5kVmFyaWFuY2UobXYpO1xuICAgICAgICBmbG9hdCBtZWFuID0gbWVhbl9hbmRfdmFyaWFuY2UucjtcbiAgICAgICAgZmxvYXQgdmFyaWFuY2UgPSBtZWFuX2FuZF92YXJpYW5jZS5nO1xuXG4gICAgICAgIGludCBzYlsxXTtcbiAgICAgICAgc2JbMF0gPSBpbmRpY2VzWzFdO1xuICAgICAgICBmbG9hdCBzY2FsZSA9IF9TY2FsZShzYik7XG4gICAgICAgIGZsb2F0IGIgPSBfQihzYik7XG5cbiAgICAgICAgcmV0dXJuIHNjYWxlICogKF9YKGluZGljZXMpIC0gbWVhbikgLyBzcXJ0KHZhcmlhbmNlICsgZXBzaWxvbikgKyBiO1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IGlucHV0LmRpbXMsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHZhcmlhYmxlczogW3sgbmFtZTogJ2Vwc2lsb24nLCB0eXBlOiAnZmxvYXQnLCBkYXRhOiBlcHNpbG9uIH1dLFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZUNvbXB1dGVPdXRwdXRQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBlcHNpbG9uOiBudW1iZXIsXG4gIG1lYW5BbmRWYXJpYW5jZVNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSB7IC4uLmNvbXB1dGVPdXRwdXRQcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYCR7ZXBzaWxvbn1gIH07XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgZ2V0OiAoKSA9PiBjcmVhdGVDb21wdXRlT3V0cHV0UHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIGlucHV0LCBlcHNpbG9uLCBtZWFuQW5kVmFyaWFuY2VTaGFwZSksXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0luc3RhbmNlTm9ybWFsaXphdGlvbiByZXF1aXJlcyAzIGlucHV0cy4nKTtcbiAgfVxuXG4gIGNvbnN0IFggPSBpbnB1dHNbMF07XG4gIGNvbnN0IHNjYWxlID0gaW5wdXRzWzFdO1xuICBjb25zdCBCID0gaW5wdXRzWzJdO1xuXG4gIC8vIGlucHV0IHNob3VsZCBhdCBsZWFzdCBoYXZlIHRocmVlIGRpbWVuc2lvbnMgLSBOLEMsZGltMSwuLi4sZGltblxuICAvLyBvdGhlciBpbnB1dHMgY2FuIGhhdmUgb25seSBvbmUgZGltZW5zaW9uc1xuICBpZiAoWC5kaW1zLmxlbmd0aCA8IDMgfHwgc2NhbGUuZGltcy5sZW5ndGggIT09IDEgfHwgQi5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoc2NhbGUuZGltc1swXSAhPT0gWC5kaW1zWzFdIHx8IEIuZGltc1swXSAhPT0gWC5kaW1zWzFdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBzaGFwZXMgYXJlIG1pc21hdGNoZWQuJyk7XG4gIH1cbiAgaWYgKFxuICAgIChYLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBYLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAoc2NhbGUudHlwZSAhPT0gJ2Zsb2F0MzInICYmIHNjYWxlLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAoQi50eXBlICE9PSAnZmxvYXQzMicgJiYgQi50eXBlICE9PSAnZmxvYXQ2NCcpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ09ubHkgc3VwcG9ydCA0LUQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBMcm5BdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgYWxwaGE6IG51bWJlcjtcbiAgYmV0YTogbnVtYmVyO1xuICBiaWFzOiBudW1iZXI7XG4gIHNpemU6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGxybjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxMcm5BdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBMcm5BdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIC8vIGlmIChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24ucGFjaykge1xuICAvLyAgIHJldHVybiBbaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlUGFja2VkTHJuUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgLy8gICBpbnB1dHMpXTtcbiAgLy8gfSBlbHNlIHtcbiAgcmV0dXJuIFtpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVMcm5Qcm9ncmFtSW5mb0xvYWRlcihpbnB1dHMsIGF0dHJpYnV0ZXMpLCBpbnB1dHMpXTtcbiAgLy99XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VMcm5BdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPExybkF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBMcm5BdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYWxwaGEgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2FscGhhJywgMC4wMDAxKTtcbiAgY29uc3QgYmV0YSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYmV0YScsIDAuNzUpO1xuICBjb25zdCBiaWFzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdiaWFzJywgMS4wKTtcbiAgY29uc3Qgc2l6ZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3NpemUnKTtcblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYWxwaGEsIGJldGEsIGJpYXMsIHNpemUgfSk7XG59O1xuXG5jb25zdCBscm5Qcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdMUk4nLFxuICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZUxyblByb2dyYW1JbmZvKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IExybkF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyB7XG4gIGNvbnN0IEMgPSBpbnB1dHNbMF0uZGltc1sxXTtcbiAgY29uc3QgcmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcbiAgY29uc3QgZnJvbSA9IC1NYXRoLmZsb29yKChhdHRyaWJ1dGVzLnNpemUgLSAxKSAvIDIpO1xuICBjb25zdCB0byA9IE1hdGguY2VpbCgoYXR0cmlidXRlcy5zaXplIC0gMSkgLyAyKTtcbiAgY29uc3QgYWxwaGEgPSBgZmxvYXQoJHthdHRyaWJ1dGVzLmFscGhhfSkgLyBmbG9hdCgke2F0dHJpYnV0ZXMuc2l6ZX0pYDtcbiAgY29uc3QgYmlhcyA9IGBmbG9hdCgke2F0dHJpYnV0ZXMuYmlhc30pYDtcbiAgY29uc3QgYmV0YSA9IGBmbG9hdCgke2F0dHJpYnV0ZXMuYmV0YX0pYDtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICBpbnQgYyA9IGluZGljZXNbMV07XG4gICAgICAgIGZsb2F0IHggPSBfWChpbmRpY2VzKTtcbiAgICAgICAgZmxvYXQgc3F1YXJlX3N1bSA9IDAuMDtcblxuICAgICAgICBmb3IgKGludCBpID0gJHtmcm9tfTsgaSA8PSAke3RvfTsgaSsrKSB7XG4gICAgICAgICAgaW50IGlkeCA9IGMgKyBpO1xuICAgICAgICAgIGlmIChjID49IDAgJiYgYyA8ICR7Q30pIHtcbiAgICAgICAgICAgIGluZGljZXNbMV0gPSBpZHg7XG4gICAgICAgICAgICBmbG9hdCBqID0gX1goaW5kaWNlcyk7XG4gICAgICAgICAgICBzcXVhcmVfc3VtICs9IGogKiBqO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCAvIHBvdygke2JpYXN9ICsgJHthbHBoYX0gKiBzcXVhcmVfc3VtLCAke2JldGF9KTtcbiAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5scm5Qcm9ncmFtTWV0YWRhdGEsXG4gICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dHNbMF0uZGltcywgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUxyblByb2dyYW1JbmZvTG9hZGVyKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IExybkF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mb0xvYWRlciB7XG4gIHJldHVybiB7IC4uLmxyblByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LCBnZXQ6ICgpID0+IGNyZWF0ZUxyblByb2dyYW1JbmZvKGlucHV0cywgYXR0cmlidXRlcykgfTtcbn1cblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdMUk4gcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50bHkgb25seSBzdXBwb3J0IExSTiBmb3IgaW5wdXQgd2l0aCBcIk5DSFdcIiBmb3JtYXQnKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgc2hvdWxkIGJlIGZsb2F0IHR5cGUnKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IGdldEdsc2wsIEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFkQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IG1vZGU6IHN0cmluZztcbiAgcmVhZG9ubHkgcGFkczogbnVtYmVyW107XG4gIHJlYWRvbmx5IHZhbHVlOiBudW1iZXI7XG59XG5cbmNvbnN0IHBhZFByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1BhZCcsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHBhZFYyOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFBhZEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFBhZEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzVjIoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4ucGFkUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVQYWRQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGF0dHJpYnV0ZXMpLFxuICAgIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VQYWRBdHRyaWJ1dGVzVjI6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248UGFkQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IFBhZEF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBtb2RlID0gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbW9kZScsICdjb25zdGFudCcpO1xuICBjb25zdCB2YWx1ZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgndmFsdWUnLCAwLjApO1xuICBjb25zdCBwYWRzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IG1vZGUsIHZhbHVlLCBwYWRzIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhZFYxMTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxzdHJpbmc+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIG1vZGU6IHN0cmluZyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHNWMTEoaW5wdXRzKTtcbiAgY29uc3QgYXR0cnVidXRlcyA9IGdlbmVyYXRlUGFkQXR0cmlidXRlc0Zyb21JbnB1dHMoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBtb2RlKTtcbiAgcmV0dXJuIHBhZFYyKGluZmVyZW5jZUhhbmRsZXIsIFtpbnB1dHNbMF1dLCBhdHRydWJ1dGVzKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVBhZEF0dHJpYnV0ZXNWMTE6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248c3RyaW5nPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogc3RyaW5nID0+XG4gIG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ21vZGUnLCAnY29uc3RhbnQnKTtcblxuY29uc3QgZ2VuZXJhdGVQYWRBdHRyaWJ1dGVzRnJvbUlucHV0cyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBtb2RlOiBzdHJpbmcsXG4pOiBQYWRBdHRyaWJ1dGVzID0+IHtcbiAgaWYgKFxuICAgICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMV0uZGF0YUlkKSB8fFxuICAgIChpbnB1dHMubGVuZ3RoID49IDMgJiYgIWluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1syXS5kYXRhSWQpKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2R5bmFtaWMgcGFkIGF0dHJpYnV0ZXMgYXJlIG5vdCBhbGxvd2VkJyk7XG4gIH1cblxuICBjb25zdCBwYWRzID0gQXJyYXkuZnJvbShpbnB1dHNbMV0uaW50ZWdlckRhdGEpO1xuICBjb25zdCB2YWx1ZSA9IGlucHV0cy5sZW5ndGggPj0gMyA/IGlucHV0c1syXS5mbG9hdERhdGFbMF0gOiAwLjA7XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IG1vZGUsIHBhZHMsIHZhbHVlIH0pO1xufTtcblxuY29uc3QgY3JlYXRlUGFkUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgYXR0cmlidXRlczogUGFkQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBTaGFwZVV0aWwucGFkU2hhcGUoaW5wdXQuZGltcy5zbGljZSgpLCBhdHRyaWJ1dGVzLnBhZHMpO1xuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBwYWRGdW5jdGlvbiA9IGdldFBhZEZ1bmN0aW9uKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0LCBhdHRyaWJ1dGVzKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHtwYWRGdW5jdGlvbn1cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50WyR7cmFua31dIGluZGljZXMpIHtcbiAgICAgICAgICByZXR1cm4gcGFkQShpbmRpY2VzKTtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdQYWQnLFxuICAgIGlucHV0TmFtZXM6IFsnQSddLFxuICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0c1YyID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUGFkIHJlcXVpcmVzIDEgaW5wdXQnKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzVjExID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgKGlucHV0cy5sZW5ndGggIT09IDIgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhZCByZXF1aXJlcyAyIG9yIDMgaW5wdXRzJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0cy5sZW5ndGggPj0gMyAmJiBpbnB1dHNbMl0udHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcblxuY29uc3QgZ2V0UGFkRnVuY3Rpb24gPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yLCBhdHRyaWJ1dGVzOiBQYWRBdHRyaWJ1dGVzKTogc3RyaW5nID0+IHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBbd2lkdGgsIGhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChpbnB1dC5kaW1zLCBUZXh0dXJlVHlwZS51bnBhY2tlZCk7XG4gIGNvbnN0IHN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoaW5wdXQuZGltcyk7XG5cbiAgc3dpdGNoIChhdHRyaWJ1dGVzLm1vZGUpIHtcbiAgICBjYXNlICdjb25zdGFudCc6XG4gICAgICByZXR1cm4gZ2V0UGFkQ29uc3RhbnQoZ2xzbCwgaW5wdXQuZGltcywgc3RyaWRlcywgd2lkdGgsIGhlaWdodCwgYXR0cmlidXRlcy5wYWRzLCBhdHRyaWJ1dGVzLnZhbHVlKTtcbiAgICBjYXNlICdyZWZsZWN0JzpcbiAgICAgIHJldHVybiBnZXRQYWRSZWZsZWN0KGdsc2wsIGlucHV0LmRpbXMsIHN0cmlkZXMsIHdpZHRoLCBoZWlnaHQsIGF0dHJpYnV0ZXMucGFkcyk7XG4gICAgY2FzZSAnZWRnZSc6XG4gICAgICByZXR1cm4gZ2V0UGFkRWRnZShnbHNsLCBpbnB1dC5kaW1zLCBzdHJpZGVzLCB3aWR0aCwgaGVpZ2h0LCBhdHRyaWJ1dGVzLnBhZHMpO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgbW9kZScpO1xuICB9XG59O1xuXG5jb25zdCBnZXRQYWRDb25zdGFudCA9IChcbiAgZ2xzbDogR2xzbCxcbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgd2lkdGg6IG51bWJlcixcbiAgaGVpZ2h0OiBudW1iZXIsXG4gIHBhZHM6IG51bWJlcltdLFxuICB2YWx1ZTogbnVtYmVyLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgbGV0IGJsb2NrID0gJyc7XG4gIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICBibG9jayArPSBgXG4gICAgICAgIGsgPSBtWyR7aX1dIC0gJHtwYWRzW2ldfTtcbiAgICAgICAgaWYgKGsgPCAwKSAgcmV0dXJuIGNvbnN0YW50O1xuICAgICAgICBpZiAoayA+PSAke3NoYXBlW2ldfSkgcmV0dXJuIGNvbnN0YW50O1xuICAgICAgICBvZmZzZXQgKz0gayAqICR7c3RyaWRlc1tpXX07XG4gICAgICAgIGA7XG4gIH1cbiAgcmV0dXJuIGBcbiAgICAgIGZsb2F0IHBhZEEoaW50IG1bJHtyYW5rfV0pIHtcbiAgICAgICAgY29uc3QgZmxvYXQgY29uc3RhbnQgPSBmbG9hdCgke3ZhbHVlfSk7XG4gICAgICAgIGludCBvZmZzZXQgPSAwO1xuICAgICAgICBpbnQgayA9IDA7XG4gICAgICAgICR7YmxvY2t9XG4gICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgZmxvYXQgdmFsdWUgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgY29vcmRzKSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGA7XG59O1xuXG5jb25zdCBnZXRQYWRSZWZsZWN0ID0gKFxuICBnbHNsOiBHbHNsLFxuICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICB3aWR0aDogbnVtYmVyLFxuICBoZWlnaHQ6IG51bWJlcixcbiAgcGFkczogbnVtYmVyW10sXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gIGxldCBibG9jayA9ICcnO1xuICBmb3IgKGxldCBpID0gcmFuayAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgYmxvY2sgKz0gYFxuICAgICAgICBrID0gbVske2l9XSAtICR7cGFkc1tpXX07XG4gICAgICAgIGlmIChrIDwgMCkgeyBrID0gLWs7IH1cbiAgICAgICAge1xuICAgICAgICAgIGNvbnN0IGludCBfMm5fMSA9ICR7MiAqIChzaGFwZVtpXSAtIDEpfTtcbiAgICAgICAgICBrID0gaW50KCBtb2QoIGZsb2F0KGspLCBmbG9hdChfMm5fMSkgKSApIDtcbiAgICAgICAgICBpZihrID49ICR7c2hhcGVbaV19KSB7IGsgPSBfMm5fMSAtIGs7IH1cbiAgICAgICAgfVxuICAgICAgICBvZmZzZXQgKz0gayAqICR7c3RyaWRlc1tpXX07XG4gICAgICAgIGA7XG4gIH1cbiAgcmV0dXJuIGBcbiAgICAgIGZsb2F0IHBhZEEoaW50IG1bJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IG9mZnNldCA9IDA7XG4gICAgICAgIGludCBrID0gMDtcbiAgICAgICAgJHtibG9ja31cbiAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhvZmZzZXQsICR7d2lkdGh9LCAke2hlaWdodH0pO1xuICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShBLCBjb29yZHMpKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgYDtcbn07XG5cbmNvbnN0IGdldFBhZEVkZ2UgPSAoXG4gIGdsc2w6IEdsc2wsXG4gIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHdpZHRoOiBudW1iZXIsXG4gIGhlaWdodDogbnVtYmVyLFxuICBwYWRzOiBudW1iZXJbXSxcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgbGV0IGJsb2NrID0gJyc7XG4gIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICBibG9jayArPSBgXG4gICAgICAgIGsgPSBtWyR7aX1dIC0gJHtwYWRzW2ldfTtcbiAgICAgICAgaWYgKGsgPCAwKSAgayA9IDA7XG4gICAgICAgIGlmIChrID49ICR7c2hhcGVbaV19KSBrID0gJHtzaGFwZVtpXSAtIDF9O1xuICAgICAgICBvZmZzZXQgKz0gayAqICR7c3RyaWRlc1tpXX07XG4gICAgICBgO1xuICB9XG4gIHJldHVybiBgXG4gICAgICBmbG9hdCBwYWRBKGludCBtWyR7cmFua31dKSB7XG4gICAgICAgIGludCBvZmZzZXQgPSAwO1xuICAgICAgICBpbnQgayA9IDA7XG4gICAgICAgICR7YmxvY2t9XG4gICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgZmxvYXQgdmFsdWUgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgY29vcmRzKSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGA7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFBvb2xDb252VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBhdXRvUGFkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNlaWxNb2RlOiBudW1iZXI7XG4gIHJlYWRvbmx5IGNvdW50SW5jbHVkZVBhZDogYm9vbGVhbjtcbiAgcmVhZG9ubHkga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgcGFkczogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbmV4cG9ydCBjb25zdCBhdmVyYWdlUG9vbDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxBdmVyYWdlUG9vbEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3QgbWV0YWRhdGEgPSB7XG4gICAgbmFtZTogJ0F2ZXJhZ2VQb29sJyxcbiAgICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgfTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVBdmVyYWdlUG9vbFByb2dyYW1JbmZvKGlucHV0cywgbWV0YWRhdGEsIGZhbHNlLCBhdHRyaWJ1dGVzKSB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQXZlcmFnZVBvb2xBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEF2ZXJhZ2VQb29sQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBhdXRvUGFkID0gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnYXV0b19wYWQnLCAnTk9UU0VUJyk7XG4gIGNvbnN0IGNlaWxNb2RlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnY2VpbF9tb2RlJywgMCk7XG4gIGNvbnN0IGNvdW50SW5jbHVkZVBhZCA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2NvdW50X2luY2x1ZGVfcGFkJywgMCkgPT09IDAgPyBmYWxzZSA6IHRydWU7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2tlcm5lbF9zaGFwZScpO1xuICBjb25zdCBzdHJpZGVzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3N0cmlkZXMnLCBbXSk7XG4gIGNvbnN0IHBhZHMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygncGFkcycsIFtdKTtcblxuICAvLyBUT0RPOiBzdXBwb3J0IGF0dHJpYnV0ZSAnY2VpbF9tb2RlJ1xuICBpZiAoY2VpbE1vZGUgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzaW5nIGNlaWwoKSBpbiBzaGFwZSBjb21wdXRhdGlvbiBpcyBub3QgeWV0IHN1cHBvcnRlZCBmb3IgQXZlcmFnZVBvb2wnKTtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBhdXRvUGFkLCBjZWlsTW9kZSwgY291bnRJbmNsdWRlUGFkLCBrZXJuZWxTaGFwZSwgc3RyaWRlcywgcGFkcyB9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZUF2ZXJhZ2VQb29sUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogVGVuc29yW10sXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4gIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgW2FkanVzdGVkQXR0cmlidXRlcywgb3V0cHV0U2hhcGVdID0gZ2V0QWRqdXN0ZWRQb29sQXR0cmlidXRlc0FuZE91dHB1dFNoYXBlKFxuICAgIGlucHV0cyxcbiAgICBhdHRyaWJ1dGVzLFxuICAgIGlzR2xvYmFsT3BlcmF0b3IsXG4gICk7XG4gIGNvbnN0IGtlcm5lbFNpemUgPSBTaGFwZVV0aWwuc2l6ZShhZGp1c3RlZEF0dHJpYnV0ZXMua2VybmVsU2hhcGUpO1xuICBjb25zdCBvcDEgPSAndmFsdWUgKz0gX1goeCk7JztcbiAgbGV0IG9wMiA9ICcnO1xuICBpZiAoYWRqdXN0ZWRBdHRyaWJ1dGVzLmNvdW50SW5jbHVkZVBhZCkge1xuICAgIG9wMiArPSBgdmFsdWUgLz0gZmxvYXQoJHtrZXJuZWxTaXplfSk7YDtcbiAgfSBlbHNlIHtcbiAgICBvcDIgKz0gYHZhbHVlIC89IGZsb2F0KCR7a2VybmVsU2l6ZX0gLSBwYWQpO2A7XG4gIH1cbiAgY29uc3QgcG9vbGluZ0NvZGUgPSBnZW5lcmF0ZVBvb2xpbmdDb2RlKGlucHV0c1swXS5kaW1zLCBhZGp1c3RlZEF0dHJpYnV0ZXMsIG9wMSwgb3AyLCAnMC4wJyk7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgJHtwb29saW5nQ29kZX1cbiAgICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGdsb2JhbEF2ZXJhZ2VQb29sOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEF2ZXJhZ2VQb29sQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBtZXRhZGF0YSA9IHtcbiAgICBuYW1lOiAnR2xvYmFsQXZlcmFnZVBvb2wnLFxuICAgIGlucHV0TmFtZXM6IFsnWCddLFxuICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgY2FjaGVIaW50OiBgJHthdHRyaWJ1dGVzLmNvdW50SW5jbHVkZVBhZH1gLFxuICB9O1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUF2ZXJhZ2VQb29sUHJvZ3JhbUluZm8oaW5wdXRzLCBtZXRhZGF0YSwgdHJ1ZSwgYXR0cmlidXRlcykgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdsb2JhbEF2ZXJhZ2VQb29sQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxBdmVyYWdlUG9vbEF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgY291bnRJbmNsdWRlUGFkID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnY291bnRfaW5jbHVkZV9wYWQnLCAwKSA9PT0gMCA/IGZhbHNlIDogdHJ1ZTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgYXV0b1BhZDogJycsXG4gICAgY2VpbE1vZGU6IDAsXG4gICAgY291bnRJbmNsdWRlUGFkLFxuICAgIGtlcm5lbFNoYXBlOiBbXSxcbiAgICBzdHJpZGVzOiBbXSxcbiAgICBwYWRzOiBbXSxcbiAgfSk7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIE1heFBvb2xBdHRyaWJ1dGVzIGV4dGVuZHMgQXZlcmFnZVBvb2xBdHRyaWJ1dGVzIHtcbiAgcmVhZG9ubHkgc3RvcmFnZU9yZGVyOiBudW1iZXI7XG4gIHJlYWRvbmx5IGRpbGF0aW9uczogbnVtYmVyW107XG59XG5cbmV4cG9ydCBjb25zdCBtYXhQb29sOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPE1heFBvb2xBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBNYXhQb29sQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3QgbWV0YWRhdGEgPSB7XG4gICAgbmFtZTogJ01heFBvb2wnLFxuICAgIGlucHV0TmFtZXM6IFsnWCddLFxuICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICB9O1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZU1heFBvb2xQcm9ncmFtSW5mbyhpbnB1dHMsIG1ldGFkYXRhLCBmYWxzZSwgYXR0cmlidXRlcykgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZU1heFBvb2xBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPE1heFBvb2xBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IE1heFBvb2xBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXV0b1BhZCA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2F1dG9fcGFkJywgJ05PVFNFVCcpO1xuICBjb25zdCBjZWlsTW9kZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2NlaWxfbW9kZScsIDApO1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdrZXJuZWxfc2hhcGUnKTtcbiAgY29uc3Qgc3RyaWRlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdzdHJpZGVzJywgW10pO1xuICBjb25zdCBwYWRzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnLCBbXSk7XG4gIGNvbnN0IHN0b3JhZ2VPcmRlciA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3N0b3JhZ2Vfb3JkZXInLCAwKTtcbiAgY29uc3QgZGlsYXRpb25zID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2RpbGF0aW9ucycsIFtdKTtcblxuICAvLyBUT0RPOiBzdXBwb3J0IGF0dHJpYnV0ZSAnY2VpbF9tb2RlJyBhbmQgJ3N0b3JhZ2Vfb3JkZXInXG4gIGlmIChzdG9yYWdlT3JkZXIgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvbHVtbiBtYWpvciBzdG9yYWdlIG9yZGVyIGlzIG5vdCB5ZXQgc3VwcG9ydGVkIGZvciBNYXhQb29sJyk7XG4gIH1cbiAgaWYgKGNlaWxNb2RlICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1c2luZyBjZWlsKCkgaW4gc2hhcGUgY29tcHV0YXRpb24gaXMgbm90IHlldCBzdXBwb3J0ZWQgZm9yIE1heFBvb2wnKTtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe1xuICAgIGF1dG9QYWQsXG4gICAgY2VpbE1vZGUsXG4gICAgY291bnRJbmNsdWRlUGFkOiBmYWxzZSxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBzdHJpZGVzLFxuICAgIHBhZHMsXG4gICAgc3RvcmFnZU9yZGVyLFxuICAgIGRpbGF0aW9ucyxcbiAgfSk7XG59O1xuXG5jb25zdCBjcmVhdGVNYXhQb29sUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogVGVuc29yW10sXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4gIGF0dHJpYnV0ZXM6IE1heFBvb2xBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBbYWRqdXN0ZWRBdHRyaWJ1dGVzLCBvdXRwdXRTaGFwZV0gPSBnZXRBZGp1c3RlZFBvb2xBdHRyaWJ1dGVzQW5kT3V0cHV0U2hhcGUoXG4gICAgaW5wdXRzLFxuICAgIGF0dHJpYnV0ZXMsXG4gICAgaXNHbG9iYWxPcGVyYXRvcixcbiAgKTtcbiAgY29uc3Qgb3AxID0gYFxuICAgICAgdmFsdWUgPSBtYXgoX1goeCksIHZhbHVlKTtcbiAgICBgO1xuICBjb25zdCBvcDIgPSAnJztcbiAgY29uc3QgcG9vbGluZ0NvZGUgPSBnZW5lcmF0ZVBvb2xpbmdDb2RlKGlucHV0c1swXS5kaW1zLCBhZGp1c3RlZEF0dHJpYnV0ZXMsIG9wMSwgb3AyLCAnLTFlNScpO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke3Bvb2xpbmdDb2RlfVxuICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRQb29sQXR0cmlidXRlc0FuZE91dHB1dFNoYXBlID0gKFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgfCBNYXhQb29sQXR0cmlidXRlcyxcbiAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbixcbik6IFtBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgfCBNYXhQb29sQXR0cmlidXRlcywgbnVtYmVyW11dID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IGhhc0RpbGF0aW9ucyA9IE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJpYnV0ZXMsICdkaWxhdGlvbnMnKTtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLnNsaWNlKCk7XG4gIGNvbnN0IHN0cmlkZXMgPSBhdHRyaWJ1dGVzLnN0cmlkZXMuc2xpY2UoKTtcbiAgY29uc3QgZGlsYXRpb25zOiBudW1iZXJbXSA9IGhhc0RpbGF0aW9ucyA/IChhdHRyaWJ1dGVzIGFzIE1heFBvb2xBdHRyaWJ1dGVzKS5kaWxhdGlvbnMuc2xpY2UoKSA6IFtdO1xuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5wYWRzLnNsaWNlKCk7XG4gIFBvb2xDb252VXRpbC5hZGp1c3RQb29sQXR0cmlidXRlcyhpc0dsb2JhbE9wZXJhdG9yLCBpbnB1dFNoYXBlLCBrZXJuZWxTaGFwZSwgc3RyaWRlcywgZGlsYXRpb25zLCBwYWRzKTtcblxuICBjb25zdCBvdXRwdXRTaGFwZSA9IFBvb2xDb252VXRpbC5jb21wdXRlUG9vbE91dHB1dFNoYXBlKFxuICAgIGlzR2xvYmFsT3BlcmF0b3IsXG4gICAgaW5wdXRTaGFwZSxcbiAgICBzdHJpZGVzLFxuICAgIGRpbGF0aW9ucyxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBwYWRzLFxuICAgIGF0dHJpYnV0ZXMuYXV0b1BhZCxcbiAgKTtcblxuICBjb25zdCBuZXdBdHRyaWJ1dGVzID0gT2JqZWN0LmFzc2lnbih7fSwgYXR0cmlidXRlcyk7XG4gIGlmIChoYXNEaWxhdGlvbnMpIHtcbiAgICBPYmplY3QuYXNzaWduKG5ld0F0dHJpYnV0ZXMsIHsga2VybmVsU2hhcGUsIHN0cmlkZXMsIHBhZHMsIGRpbGF0aW9ucywgY2FjaGVLZXk6IGF0dHJpYnV0ZXMuY2FjaGVLZXkgfSk7XG4gIH0gZWxzZSB7XG4gICAgT2JqZWN0LmFzc2lnbihuZXdBdHRyaWJ1dGVzLCB7IGtlcm5lbFNoYXBlLCBzdHJpZGVzLCBwYWRzLCBjYWNoZUtleTogYXR0cmlidXRlcy5jYWNoZUtleSB9KTtcbiAgfVxuICByZXR1cm4gW25ld0F0dHJpYnV0ZXMsIG91dHB1dFNoYXBlXTtcbn07XG5cbmNvbnN0IGdsb2JhbE1heFBvb2xBdHRyaWJ1dGVzID0ge1xuICBhdXRvUGFkOiAnJyxcbiAgY2VpbE1vZGU6IDAsXG4gIGNvdW50SW5jbHVkZVBhZDogZmFsc2UsXG4gIGtlcm5lbFNoYXBlOiBbXSxcbiAgc3RyaWRlczogW10sXG4gIHBhZHM6IFtdLFxuICBzdG9yYWdlT3JkZXI6IDAsXG4gIGRpbGF0aW9uczogW10sXG4gIGNhY2hlS2V5OiAnJyxcbn07XG5cbmNvbnN0IGdsb2JhbE1heFBvb2xNZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0dsb2JhbE1heFBvb2wnLFxuICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCBnbG9iYWxNYXhQb29sID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4uZ2xvYmFsTWF4UG9vbE1ldGFkYXRhLFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVNYXhQb29sUHJvZ3JhbUluZm8oaW5wdXRzLCBnbG9iYWxNYXhQb29sTWV0YWRhdGEsIHRydWUsIGdsb2JhbE1heFBvb2xBdHRyaWJ1dGVzKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQb29sIG9wcyByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcblxuY29uc3QgZ2VuZXJhdGVQb29saW5nQ29kZSA9IChcbiAgaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzLFxuICBvcDE6IHN0cmluZyxcbiAgb3AyOiBzdHJpbmcsXG4gIHN0YXJ0OiBzdHJpbmcsXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCByYW5rID0gaW5wdXREaW1zLmxlbmd0aDtcbiAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoIDw9IDIpIHtcbiAgICBjb25zdCBrdyA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGVbYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggLSAxXTtcbiAgICBjb25zdCBzdyA9IGF0dHJpYnV0ZXMuc3RyaWRlc1thdHRyaWJ1dGVzLnN0cmlkZXMubGVuZ3RoIC0gMV07XG4gICAgY29uc3QgcHdTdGFydCA9IGF0dHJpYnV0ZXMucGFkc1thdHRyaWJ1dGVzLnBhZHMubGVuZ3RoIC8gMiAtIDFdO1xuICAgIGNvbnN0IHB3RW5kID0gYXR0cmlidXRlcy5wYWRzW2F0dHJpYnV0ZXMucGFkcy5sZW5ndGggLSAxXTtcbiAgICBjb25zdCBkaW1XID0gaW5wdXREaW1zW3JhbmsgLSAxXTtcbiAgICBsZXQgY29kZVcgPSAnJztcbiAgICBsZXQgY29kZUggPSAnJztcbiAgICBsZXQgY29kZUhFbmQgPSAnJztcbiAgICBpZiAocHdTdGFydCArIHB3RW5kICE9PSAwKSB7XG4gICAgICBjb2RlVyA9IGBcbiAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7a3d9OyBpKyspIHtcbiAgICAgICAgICAgIHhbJHtyYW5rfSAtIDFdID0gaW5kaWNlc1ske3Jhbmt9IC0gMV0gKiAke3N3fSAtICR7cHdTdGFydH0gKyBpO1xuICAgICAgICAgICAgaWYgKHhbJHtyYW5rfSAtIDFdIDwgMCB8fCB4WyR7cmFua30gLSAxXSA+PSAke2RpbVd9KSB7XG4gICAgICAgICAgICAgIHBhZCsrO1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICR7b3AxfVxuICAgICAgICAgIH1gO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlVyA9IGBcbiAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7a3d9OyBpKyspIHtcbiAgICAgICAgICAgIHhbJHtyYW5rfSAtIDFdID0gaW5kaWNlc1ske3Jhbmt9IC0gMV0gKiAke3N3fSAtICR7cHdTdGFydH0gKyBpO1xuICAgICAgICAgICAgJHtvcDF9XG4gICAgICAgICAgfWA7XG4gICAgfVxuXG4gICAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoID09PSAyKSB7XG4gICAgICBjb25zdCBraCA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGVbYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggLSAyXTtcbiAgICAgIGNvbnN0IHNoID0gYXR0cmlidXRlcy5zdHJpZGVzW2F0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggLSAyXTtcbiAgICAgIGNvbnN0IHBoU3RhcnQgPSBhdHRyaWJ1dGVzLnBhZHNbYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAvIDIgLSAyXTtcbiAgICAgIGNvbnN0IHBoRW5kID0gYXR0cmlidXRlcy5wYWRzW2F0dHJpYnV0ZXMucGFkcy5sZW5ndGggLSAyXTtcbiAgICAgIGNvbnN0IGRpbUggPSBpbnB1dERpbXNbcmFuayAtIDJdO1xuICAgICAgaWYgKHBoU3RhcnQgKyBwaEVuZCAhPT0gMCkge1xuICAgICAgICBjb2RlSCA9IGBcbiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgJHtraH07IGorKykge1xuICAgICAgICAgICAgICB4WyR7cmFua30gLSAyXSA9IGluZGljZXNbJHtyYW5rfSAtIDJdICogJHtzaH0gLSAke3BoU3RhcnR9ICsgajtcbiAgICAgICAgICAgICAgaWYgKHhbJHtyYW5rfSAtIDJdIDwgMCB8fCB4WyR7cmFua30gLSAyXSA+PSAke2RpbUh9KSB7XG4gICAgICAgICAgICAgICAgcGFkKz0gJHtrd307XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICBgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29kZUggPSBgXG4gICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8ICR7a2h9OyBqKyspIHtcbiAgICAgICAgICAgICAgeFske3Jhbmt9IC0gMl0gPSBpbmRpY2VzWyR7cmFua30gLSAyXSAqICR7c2h9IC0gJHtwaFN0YXJ0fSArIGo7XG4gICAgICAgICAgICBgO1xuICAgICAgfVxuICAgICAgY29kZUhFbmQgPSBgXG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgIH1cblxuICAgIGNvbnN0IHBvb2xpbmdDb2RlID0gYFxuICAgICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IHhbJHtyYW5rfV07XG4gICAgICAgICAgY29weVZlYyhpbmRpY2VzLCB4KTtcblxuICAgICAgICAgIGZsb2F0IHZhbHVlID0gJHtzdGFydH07XG4gICAgICAgICAgaW50IHBhZCA9IDA7XG4gICAgICAgICAgJHtjb2RlSH1cbiAgICAgICAgICAke2NvZGVXfVxuICAgICAgICAgICR7Y29kZUhFbmR9XG4gICAgICAgICAgJHtvcDJ9XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBwb29saW5nQ29kZTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBrZXJuZWxTaXplID0gU2hhcGVVdGlsLnNpemUoYXR0cmlidXRlcy5rZXJuZWxTaGFwZSk7XG4gICAgY29uc3Qga2VybmVsU3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlKTtcbiAgICBjb25zdCBzdHJpZGVzUmFuayA9IGtlcm5lbFN0cmlkZXMubGVuZ3RoO1xuICAgIGNvbnN0IHBhZHNSYW5rID0gYXR0cmlidXRlcy5wYWRzLmxlbmd0aDtcbiAgICBjb25zdCBvZmZzZXRUb0luZGljZXNGdW5jdGlvbiA9IG9mZnNldFRvSW5kaWNlcyhzdHJpZGVzUmFuayk7XG4gICAgY29uc3QgY29weUlucHV0RGltcyA9IGNvcHlBcnJheShpbnB1dERpbXMsICdpbnB1dERpbXMnKTtcbiAgICBjb25zdCBjb3B5UGFkcyA9IGNvcHlBcnJheShhdHRyaWJ1dGVzLnBhZHMsICdwYWRzJyk7XG4gICAgY29uc3QgY29weUtlcm5lbFN0cmlkZXMgPSBjb3B5QXJyYXkoa2VybmVsU3RyaWRlcywgJ2tlcm5lbFN0cmlkZXMnKTtcbiAgICBjb25zdCBjb3B5U3RyaWRlcyA9IGNvcHlBcnJheShhdHRyaWJ1dGVzLnN0cmlkZXMsICdzdHJpZGVzJyk7XG4gICAgY29uc3QgaGFzUGFkcyA9IGF0dHJpYnV0ZXMucGFkcy5yZWR1Y2UoKHN1bSwgY3VyKSA9PiBzdW0gKyBjdXIpO1xuICAgIGxldCBwYWRDb2RlID0gJyc7XG4gICAgaWYgKGhhc1BhZHMpIHtcbiAgICAgIHBhZENvZGUgPSBgXG4gICAgICAgICAgICBpZiAoeFtqXSA+PSBpbnB1dERpbXNbal0gfHwgeFtqXSA8IDApIHtcbiAgICAgICAgICAgICAgcGFkKys7XG4gICAgICAgICAgICAgIGlzUGFkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghaXNQYWQpIHtcbiAgICAgICAgICAgICR7b3AxfVxuICAgICAgICAgIH1gO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYWRDb2RlID0gYFxuICAgICAgICAgIH1cbiAgICAgICAgICAke29wMX1cbiAgICAgICAgYDtcbiAgICB9XG4gICAgY29uc3QgcG9vbGluZ0NvZGUgPSBgXG4gICAgICAgICR7b2Zmc2V0VG9JbmRpY2VzRnVuY3Rpb259XG4gICAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgeFske3Jhbmt9XTtcbiAgICAgICAgICBjb3B5VmVjKGluZGljZXMsIHgpO1xuICAgICAgICAgIGludCBvZmZzZXRbJHtzdHJpZGVzUmFua31dO1xuICAgICAgICAgIGludCBwYWRzWyR7cGFkc1Jhbmt9XTtcbiAgICAgICAgICBpbnQgaW5wdXREaW1zWyR7cmFua31dO1xuICAgICAgICAgIGludCBrZXJuZWxTdHJpZGVzWyR7c3RyaWRlc1Jhbmt9XTtcbiAgICAgICAgICBpbnQgc3RyaWRlc1ske3N0cmlkZXNSYW5rfV07XG4gICAgICAgICAgJHtjb3B5UGFkc31cbiAgICAgICAgICAke2NvcHlJbnB1dERpbXN9XG4gICAgICAgICAgJHtjb3B5U3RyaWRlc31cbiAgICAgICAgICAke2NvcHlLZXJuZWxTdHJpZGVzfVxuXG4gICAgICAgICAgZmxvYXQgdmFsdWUgPSAke3N0YXJ0fTtcbiAgICAgICAgICBpbnQgcGFkID0gMDtcbiAgICAgICAgICBib29sIGlzUGFkID0gZmFsc2U7XG4gICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke2tlcm5lbFNpemV9OyBpKyspIHtcbiAgICAgICAgICAgIG9mZnNldFRvSW5kaWNlcyhpLCBrZXJuZWxTdHJpZGVzLCBvZmZzZXQpO1xuICAgICAgICAgICAgaXNQYWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGZvciAoaW50IGogPSAke3Jhbmt9IC0gJHtzdHJpZGVzUmFua307IGogPCAke3Jhbmt9OyBqKyspIHtcbiAgICAgICAgICAgICAgeFtqXSA9IGluZGljZXNbal0gKiBzdHJpZGVzW2ogLSAke3Jhbmt9ICsgJHtzdHJpZGVzUmFua31dXG4gICAgICAgICAgICAgICAgKyBvZmZzZXRbaiAtICR7cmFua30gKyAke3N0cmlkZXNSYW5rfV0gLSBwYWRzW2ogLSAyXTtcbiAgICAgICAgICAgICAgJHtwYWRDb2RlfVxuICAgICAgICAgIH1cbiAgICAgICAgICAke29wMn1cblxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gcG9vbGluZ0NvZGU7XG4gIH1cbn07XG5cbmNvbnN0IGNvcHlBcnJheSA9IChhcnJheTogcmVhZG9ubHkgbnVtYmVyW10sIGFycmF5TmFtZTogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgbGV0IGJsb2NrID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICBibG9jayArPSBgXG4gICAgICAke2FycmF5TmFtZX1bJHtpfV0gPSAke2FycmF5W2ldfTtcbiAgICBgO1xuICB9XG4gIHJldHVybiBibG9jaztcbn07XG5cbmNvbnN0IG9mZnNldFRvSW5kaWNlcyA9IChyYW5rOiBudW1iZXIpOiBzdHJpbmcgPT4gYFxuICB2b2lkIG9mZnNldFRvSW5kaWNlcyhpbnQgb2Zmc2V0LCBpbnRbJHtyYW5rfV0gc3RyaWRlcywgb3V0IGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG4gICAgaWYgKCR7cmFua30gPT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7cmFua30gLSAxOyArK2kpIHtcbiAgICAgIGluZGljZXNbaV0gPSBvZmZzZXQgLyBzdHJpZGVzW2ldO1xuICAgICAgb2Zmc2V0IC09IGluZGljZXNbaV0gKiBzdHJpZGVzW2ldO1xuICAgIH1cbiAgICBpbmRpY2VzWyR7cmFua30gLSAxXSA9IG9mZnNldDtcbiAgfWA7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgTlVNQkVSX1RZUEVTLCBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlZHVjZUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGVzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkga2VlcERpbXM6IGJvb2xlYW47XG59XG5cbi8vIHJldHVybiBbaW5pdCBvcHMsIHJlZHVjZSBvcHMsIGZpbmFsIG9wc11cbnR5cGUgUmVkdWNlT3AgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhlczogbnVtYmVyW10pID0+IHN0cmluZ1tdO1xuXG5jb25zdCByZWR1Y2UgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbiAgbmFtZTogc3RyaW5nLFxuICByZWR1Y2VPcDogUmVkdWNlT3AsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3QgcmVkdWNlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICAgIG5hbWUsXG4gICAgaW5wdXROYW1lczogWydBJ10sXG4gICAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgfTtcblxuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7XG4gICAgICAuLi5yZWR1Y2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZVJlZHVjZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgbmFtZSwgcmVkdWNlT3AsIHJlZHVjZVByb2dyYW1NZXRhZGF0YSksXG4gICAgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IFJlZHVjZUF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBheGVzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2F4ZXMnLCBbXSk7XG4gIGNvbnN0IGtlZXBEaW1zID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgna2VlcGRpbXMnLCAxKSA9PT0gMTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGF4ZXMsIGtlZXBEaW1zIH0pO1xufTtcblxuY29uc3QgY3JlYXRlUmVkdWNlUHJvZ3JhbUluZm8gPSAoXG4gIF9oYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4gIF9uYW1lOiBzdHJpbmcsXG4gIHJlZHVjZU9wOiBSZWR1Y2VPcCxcbiAgcmVkdWNlUHJvZ3JhbU1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IG91dHB1dFNoYXBlOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBpUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCB8fCAxO1xuXG4gIGNvbnN0IGlkeENvcHkgPSBbXTsgLy8gY29weSBvdXRwdXQgaW5kZXhlcyB0byBpbnB1dCBpbmRleGVzXG5cbiAgY29uc3QgYXhlcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGVzKGF0dHJpYnV0ZXMuYXhlcywgaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcbiAgY29uc3Qgb3BzID0gcmVkdWNlT3AoaW5wdXRzLCBheGVzKTtcbiAgbGV0IHJlZHVjZU9wcyA9IG9wc1sxXTtcblxuICBmb3IgKGxldCBrID0gMDsgayA8IGlucHV0c1swXS5kaW1zLmxlbmd0aDsgaysrKSB7XG4gICAgLy8gaWYgdGhpcyBheGlzIGlzIHJlZHVjZWRcbiAgICBpZiAoYXhlcy5pbmRleE9mKGspID49IDAgfHwgYXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmIChhdHRyaWJ1dGVzLmtlZXBEaW1zKSB7XG4gICAgICAgIG91dHB1dFNoYXBlLnB1c2goMSk7XG4gICAgICB9IC8vIGVsc2UgeyByZW1vdmUgdGhlIGF4aXMgZnJvbSBvdXRwdXRTaGFwZTsgfVxuXG4gICAgICAvLyBsb29wIG92ZXIgdGhlIGQtdGggYXhpc1xuICAgICAgcmVkdWNlT3BzID0gYFxuICAgICAgICAgIGZvcihpbnQgaiR7a30gPSAwOyBqJHtrfSA8ICR7aW5wdXRzWzBdLmRpbXNba119OyBqJHtrfSsrKSB7XG4gICAgICAgICAgICBpbnB1dElkeFske2t9XSA9IGoke2t9O1xuICAgICAgICAgICAgJHtyZWR1Y2VPcHN9XG4gICAgICAgICAgfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlkeENvcHkucHVzaChgaW5wdXRJZHhbJHtrfV0gPSBvdXRwdXRJZHhbJHtvdXRwdXRTaGFwZS5sZW5ndGh9XTtgKTtcblxuICAgICAgb3V0cHV0U2hhcGUucHVzaChpbnB1dHNbMF0uZGltc1trXSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgb1JhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGggfHwgMTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBvdXRwdXRJZHhbJHtvUmFua31dKSB7XG4gICAgICAgIGZsb2F0IHZhbHVlOyAgICAgICAgICAgICAgICAgLy8gZmluYWwgcmVzdWx0XG4gICAgICAgIGludCBpbnB1dElkeFske2lSYW5rfV07ICAgICAgLy8gYWRkcmVzc2luZyBpbnB1dCBkYXRhXG4gICAgICAgICR7aWR4Q29weS5qb2luKCdcXG4nKX1cbiAgICAgICAgJHtvcHNbMF19ICAgICAgIC8vIGluaXQgb3BzIGZvciByZWR1Y2UgbWF4L21pblxuICAgICAgICAke3JlZHVjZU9wc31cbiAgICAgICAgJHtvcHNbMl19ICAgICAgIC8vIGZpbmFsIGNvbXB1dGF0aW9uIGZvciByZWR1Y2UgbWVhblxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9YDtcblxuICByZXR1cm4ge1xuICAgIC4uLnJlZHVjZVByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIC8vIFRPRE86IHN1cHBvcnQgUmVkdWNlKiBvcGVyYXRvcnMgd2l0aCAyIGlucHV0cy5cbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUmVkdWNlIG9wIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoTlVNQkVSX1RZUEVTLmluZGV4T2YoaW5wdXRzWzBdLnR5cGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlU3VtOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9ICgpOiBzdHJpbmdbXSA9PiBbJ3ZhbHVlID0gMC4wOycsICd2YWx1ZSArPSBfQShpbnB1dElkeCk7JywgJyddO1xuICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZVN1bScsIHJlZHVjZU9wKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VNZWFuOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dHM6IFRlbnNvcltdLCBheGVzOiBudW1iZXJbXSk6IHN0cmluZ1tdID0+IHtcbiAgICBsZXQgc2l6ZSA9IDEuMDtcbiAgICBmb3IgKGxldCBrID0gMDsgayA8IGlucHV0c1swXS5kaW1zLmxlbmd0aDsgaysrKSB7XG4gICAgICBpZiAoYXhlcy5pbmRleE9mKGspID49IDAgfHwgYXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgc2l6ZSAqPSBpbnB1dHNbMF0uZGltc1trXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gWyd2YWx1ZSA9IDAuMDsnLCAndmFsdWUgKz0gX0EoaW5wdXRJZHgpOycsIGB2YWx1ZSAvPSAke3NpemV9LjtgXTsgLy8gZW5zdXJlIHJlYWwgbnVtYmVyIHdpdGggYC5gXG4gIH07XG4gIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlTWVhbicsIHJlZHVjZU9wKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VNYXg6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKGlucHV0czogVGVuc29yW10sIGF4ZXM6IG51bWJlcltdKTogc3RyaW5nW10gPT4ge1xuICAgIGNvbnN0IGlkeFplcm8gPSBbXTtcbiAgICBmb3IgKGxldCBrID0gMDsgayA8IGlucHV0c1swXS5kaW1zLmxlbmd0aDsgaysrKSB7XG4gICAgICBpZiAoYXhlcy5pbmRleE9mKGspID49IDAgfHwgYXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgaWR4WmVyby5wdXNoKGBpbnB1dElkeFske2t9XSA9IDA7YCk7IC8vIGZpcnN0IGVsZW1lbnRcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gW2Ake2lkeFplcm8uam9pbignXFxuJyl9XFxudmFsdWUgPSBfQShpbnB1dElkeCk7YCwgJ3ZhbHVlID0gbWF4KHZhbHVlLCBfQShpbnB1dElkeCkpOycsICcnXTtcbiAgfTtcbiAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VNYXgnLCByZWR1Y2VPcCk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWluOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dHM6IFRlbnNvcltdLCBheGVzOiBudW1iZXJbXSk6IHN0cmluZ1tdID0+IHtcbiAgICBjb25zdCBpZHhaZXJvID0gW107XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dHNbMF0uZGltcy5sZW5ndGg7IGsrKykge1xuICAgICAgaWYgKGF4ZXMuaW5kZXhPZihrKSA+PSAwIHx8IGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGlkeFplcm8ucHVzaChgaW5wdXRJZHhbJHtrfV0gPSAwO2ApOyAvLyBmaXJzdCBlbGVtZW50XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFtgJHtpZHhaZXJvLmpvaW4oJ1xcbicpfVxcbnZhbHVlID0gX0EoaW5wdXRJZHgpO2AsICd2YWx1ZSA9IG1pbih2YWx1ZSwgX0EoaW5wdXRJZHgpKTsnLCAnJ107XG4gIH07XG4gIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlTWluJywgcmVkdWNlT3ApO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZVByb2Q6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKCk6IHN0cmluZ1tdID0+IFsndmFsdWUgPSAxLjA7JywgJ3ZhbHVlICo9IF9BKGlucHV0SWR4KTsnLCAnJ107XG4gIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlUHJvZCcsIHJlZHVjZU9wKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VMb2dTdW06IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKCk6IHN0cmluZ1tdID0+IFsndmFsdWUgPSAwLjA7JywgJ3ZhbHVlICs9IF9BKGlucHV0SWR4KTsnLCAndmFsdWUgPSBsb2codmFsdWUpOyddO1xuICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZUxvZ1N1bScsIHJlZHVjZU9wKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VMb2dTdW1TcXVhcmU6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKCk6IHN0cmluZ1tdID0+IFsnZmxvYXQgdDsgdmFsdWUgPSAwLjA7JywgJ3QgPSBfQShpbnB1dElkeCk7IHZhbHVlICs9IHQgKiB0OycsICcnXTtcbiAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VMb2dTdW1TcXVhcmUnLCByZWR1Y2VPcCk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCByZXNoYXBlID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVzaGFwZWREaW1zID0gU2hhcGVVdGlsLmNhbGN1bGF0ZVJlc2hhcGVkRGltcyhpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmludGVnZXJEYXRhKTtcbiAgaWYgKGhhbmRsZXIuc2Vzc2lvbi5wYWNrKSB7XG4gICAgcmV0dXJuIFtoYW5kbGVyLnJlc2hhcGVQYWNrZWQoaW5wdXRzWzBdLCByZXNoYXBlZERpbXMpXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW2hhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1swXSwgcmVzaGFwZWREaW1zKV07XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBVcHNhbXBsZUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBvcHNldDogbnVtYmVyO1xuICByZWFkb25seSBpc1Jlc2l6ZTogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbW9kZTogc3RyaW5nO1xuICByZWFkb25seSBzY2FsZXM6IG51bWJlcltdO1xuICByZWFkb25seSBleHRyYXBvbGF0aW9uVmFsdWU6IG51bWJlcjtcbiAgcmVhZG9ubHkgY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGU6IHN0cmluZztcbiAgcmVhZG9ubHkgdXNlRXh0cmFwb2xhdGlvbjogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbmVlZFJvaUlucHV0OiBib29sZWFuO1xuICByZWFkb25seSBuZWFyZXN0TW9kZTogc3RyaW5nO1xuICByZWFkb25seSBjdWJpY0NvZWZmaWNpZW50QTogbnVtYmVyO1xuICByZWFkb25seSBleGNsdWRlT3V0c2lkZTogYm9vbGVhbjtcbiAgcmVhZG9ubHkgdXNlTmVhcmVzdDJ4T3B0aW1pemF0aW9uOiBib29sZWFuO1xuICByZWFkb25seSByb2lJbnB1dElkeDogbnVtYmVyO1xuICByZWFkb25seSBzY2FsZXNJbnB1dElkeDogbnVtYmVyO1xuICByZWFkb25seSBzaXplc0lucHV0SWR4OiBudW1iZXI7XG59XG5cbmNvbnN0IHVwc2FtcGxlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnVXBzYW1wbGUnLFxuICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCB1cHNhbXBsZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxVcHNhbXBsZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4udXBzYW1wbGVQcm9ncmFtTWV0YWRhdGEsXG4gICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZVVwc2FtcGxlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjc6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IFVwc2FtcGxlQXR0cmlidXRlcyA9PiBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcyhub2RlLCA3KTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjk6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IFVwc2FtcGxlQXR0cmlidXRlcyA9PiBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcyhub2RlLCA5KTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzID0gKG5vZGU6IEdyYXBoLk5vZGUsIG9wc2V0OiBudW1iZXIpOiBVcHNhbXBsZUF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBpc1Jlc2l6ZSA9IG9wc2V0ID49IDEwO1xuXG4gIC8vIHByb2Nlc3Npbmcgbm9kZSBhdHRyaWJ1dGVzXG4gIGNvbnN0IG1vZGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdtb2RlJywgJ25lYXJlc3QnKTtcbiAgaWYgKG1vZGUgIT09ICduZWFyZXN0JyAmJiBtb2RlICE9PSAnbGluZWFyJyAmJiAob3BzZXQgPCAxMSB8fCBtb2RlICE9PSAnY3ViaWMnKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgdW5yZWNvZ25pemVkIG1vZGU6ICR7bW9kZX1gKTtcbiAgfVxuXG4gIGxldCBzY2FsZXM6IG51bWJlcltdID0gW107XG4gIGlmIChvcHNldCA8IDkpIHtcbiAgICBzY2FsZXMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXRzKCdzY2FsZXMnKTtcbiAgICBzY2FsZXNWYWxpZGF0aW9uKHNjYWxlcywgbW9kZSwgaXNSZXNpemUpO1xuICB9XG5cbiAgY29uc3QgZXh0cmFwb2xhdGlvblZhbHVlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdleHRyYXBvbGF0aW9uX3ZhbHVlJywgMC4wKTtcblxuICBjb25zdCBjb29yZGluYXRlVHJhbnNmb3JtTW9kZSA9XG4gICAgb3BzZXQgPiAxMCA/IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2Nvb3JkaW5hdGVfdHJhbnNmb3JtYXRpb25fbW9kZScsICdoYWxmX3BpeGVsJykgOiAnYXN5bW1ldHJpYyc7XG4gIGlmIChcbiAgICBbXG4gICAgICAnYXN5bW1ldHJpYycsXG4gICAgICAncHl0b3JjaF9oYWxmX3BpeGVsJyxcbiAgICAgICd0Zl9oYWxmX3BpeGVsX2Zvcl9ubicsXG4gICAgICAnYWxpZ25fY29ybmVycycsXG4gICAgICAndGZfY3JvcF9hbmRfcmVzaXplJyxcbiAgICAgICdoYWxmX3BpeGVsJyxcbiAgICBdLmluZGV4T2YoY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUpID09PSAtMVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGNvb3JkaW5hdGVfdHJhbnNmb3JtX21vZGUgJyR7Y29vcmRpbmF0ZVRyYW5zZm9ybU1vZGV9JyBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gIH1cbiAgY29uc3QgbmVlZFJvaUlucHV0ID0gY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgPT09ICd0Zl9jcm9wX2FuZF9yZXNpemUnO1xuICBjb25zdCB1c2VFeHRyYXBvbGF0aW9uID0gbmVlZFJvaUlucHV0O1xuXG4gIGNvbnN0IG5lYXJlc3RNb2RlID1cbiAgICBtb2RlID09PSAnbmVhcmVzdCcgJiYgb3BzZXQgPj0gMTEgPyBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCduZWFyZXN0X21vZGUnLCAncm91bmRfcHJlZmVyX2Zsb29yJykgOiAnJztcbiAgaWYgKFsncm91bmRfcHJlZmVyX2Zsb29yJywgJ3JvdW5kX3ByZWZlcl9jZWlsJywgJ2Zsb29yJywgJ2NlaWwnLCAnJ10uaW5kZXhPZihuZWFyZXN0TW9kZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBuZWFyZXN0X21vZGUgJyR7bmVhcmVzdE1vZGV9JyBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gIH1cblxuICBjb25zdCBjdWJpY0NvZWZmaWNpZW50QSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnY3ViaWNfY29lZmZfYScsIC0wLjc1KTtcbiAgY29uc3QgZXhjbHVkZU91dHNpZGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdleGNsdWRlX291dHNpZGUnLCAwKSAhPT0gMDtcbiAgaWYgKGV4Y2x1ZGVPdXRzaWRlICYmIG1vZGUgIT09ICdjdWJpYycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4Y2x1ZGVfb3V0c2lkZSBjYW4gYmUgc2V0IHRvIDEgb25seSB3aGVuIG1vZGUgaXMgQ1VCSUMuJyk7XG4gIH1cblxuICBjb25zdCB1c2VOZWFyZXN0MnhPcHRpbWl6YXRpb24gPVxuICAgIG9wc2V0IDwgMTEgPyB0cnVlIDogbW9kZSA9PT0gJ25lYXJlc3QnICYmIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlID09PSAnYXN5bW1ldHJpYycgJiYgbmVhcmVzdE1vZGUgPT09ICdmbG9vcic7XG5cbiAgbGV0IHJvaUlucHV0SWR4ID0gMDtcbiAgbGV0IHNjYWxlc0lucHV0SWR4ID0gMDtcbiAgbGV0IHNpemVzSW5wdXRJZHggPSAwO1xuXG4gIGlmIChvcHNldCA+IDEwKSB7XG4gICAgLy8gaGFuZGxlIHdoZW4gcm9pSW5wdXQgaXMgbm90IGdpdmVuXG4gICAgaWYgKG5vZGUuaW5wdXRzLmxlbmd0aCA+IDIpIHtcbiAgICAgIHJvaUlucHV0SWR4ID0gMTtcbiAgICAgIHNjYWxlc0lucHV0SWR4ID0gMjtcbiAgICAgIHNpemVzSW5wdXRJZHggPSAzO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZXNJbnB1dElkeCA9IDE7XG4gICAgICBzaXplc0lucHV0SWR4ID0gMjtcbiAgICB9XG4gIH0gZWxzZSBpZiAob3BzZXQgPT09IDkpIHtcbiAgICBzY2FsZXNJbnB1dElkeCA9IDE7XG4gIH1cblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBvcHNldCxcbiAgICBpc1Jlc2l6ZSxcbiAgICBtb2RlLFxuICAgIHNjYWxlcyxcbiAgICBleHRyYXBvbGF0aW9uVmFsdWUsXG4gICAgY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUsXG4gICAgdXNlRXh0cmFwb2xhdGlvbixcbiAgICBuZWVkUm9pSW5wdXQsXG4gICAgbmVhcmVzdE1vZGUsXG4gICAgY3ViaWNDb2VmZmljaWVudEEsXG4gICAgZXhjbHVkZU91dHNpZGUsXG4gICAgdXNlTmVhcmVzdDJ4T3B0aW1pemF0aW9uLFxuICAgIHJvaUlucHV0SWR4LFxuICAgIHNjYWxlc0lucHV0SWR4LFxuICAgIHNpemVzSW5wdXRJZHgsXG4gIH0pO1xufTtcblxuY29uc3QgY3JlYXRlVXBzYW1wbGVQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBVcHNhbXBsZUF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgW2lucHV0V2lkdGgsIGlucHV0SGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGlucHV0c1swXS5kaW1zLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICApO1xuXG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMubWFwKChkaW0sIGkpID0+IE1hdGguZmxvb3IoZGltICogYXR0cmlidXRlcy5zY2FsZXNbaV0pKTtcbiAgY29uc3QgW291dHB1dFdpZHRoLCBvdXRwdXRIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgb3V0cHV0U2hhcGUsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICk7XG4gIGNvbnN0IGRpbSA9IG91dHB1dFNoYXBlLmxlbmd0aDtcblxuICBjb25zdCBvdXRwdXRQaXRjaGVzID0gbmV3IEFycmF5PG51bWJlcj4oZGltKTtcbiAgY29uc3QgaW5wdXRQaXRjaGVzID0gbmV3IEFycmF5PG51bWJlcj4oZGltKTtcbiAgbGV0IHByZWNhbGN1bGF0ZWRQaXRjaGVzID0gYFxuICAgICAgaW50IG91dHB1dF9waXRjaGVzWyR7ZGltfV07XG4gICAgICBpbnQgaW5wdXRfcGl0Y2hlc1ske2RpbX1dO1xuICAgICAgYDtcbiAgZm9yIChsZXQgZCA9IGRpbSAtIDE7IGQgPj0gMDsgZC0tKSB7XG4gICAgb3V0cHV0UGl0Y2hlc1tkXSA9IGQgPT09IGRpbSAtIDEgPyAxIDogb3V0cHV0UGl0Y2hlc1tkICsgMV0gKiBvdXRwdXRTaGFwZVtkICsgMV07XG4gICAgaW5wdXRQaXRjaGVzW2RdID0gZCA9PT0gZGltIC0gMSA/IDEgOiBpbnB1dFBpdGNoZXNbZCArIDFdICogaW5wdXRzWzBdLmRpbXNbZCArIDFdO1xuXG4gICAgcHJlY2FsY3VsYXRlZFBpdGNoZXMgKz0gYFxuICAgICAgICBvdXRwdXRfcGl0Y2hlc1ske2R9XSA9ICR7b3V0cHV0UGl0Y2hlc1tkXX07XG4gICAgICAgIGlucHV0X3BpdGNoZXNbJHtkfV0gPSAke2lucHV0UGl0Y2hlc1tkXX07XG4gICAgICAgIGA7XG4gIH1cbiAgY29uc3QgZ2V0SW5wdXRGbG9hdEZ1bmN0aW9uID0gYFxuICAgICAgZmxvYXQgZ2V0SW5wdXRGbG9hdChpbnQgaW5kZXgpIHtcbiAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhpbmRleCwgJHtpbnB1dFdpZHRofSwgJHtpbnB1dEhlaWdodH0pO1xuICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShYLCBjb29yZHMpKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgYDtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPVxuICAgIGF0dHJpYnV0ZXMubW9kZSA9PT0gJ25lYXJlc3QnXG4gICAgICA/IC8vIG5lYXJlc3RcbiAgICAgICAgYFxuICAgICR7Z2V0SW5wdXRGbG9hdEZ1bmN0aW9ufVxuICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtkaW19XSkge1xuICAgICAgaW50IGlucHV0X2luZGV4ID0gMDtcbiAgICAgIGludCBvdXRwdXRfaW5kZXggPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7b3V0cHV0V2lkdGh9LCAke291dHB1dEhlaWdodH0pO1xuXG4gICAgICAke3ByZWNhbGN1bGF0ZWRQaXRjaGVzfVxuXG4gICAgICBpbnQgZCwgbTtcbiAgICAgIGZvciAoaW50IGRpbSA9IDA7IGRpbSA8ICR7ZGltfTsgKytkaW0pIHtcbiAgICAgICAgZCA9IG91dHB1dF9pbmRleCAvIG91dHB1dF9waXRjaGVzW2RpbV07XG4gICAgICAgIG0gPSBvdXRwdXRfaW5kZXggLSBkICogb3V0cHV0X3BpdGNoZXNbZGltXTtcbiAgICAgICAgb3V0cHV0X2luZGV4ID0gbTtcblxuICAgICAgICBpZiAoc2NhbGVzW2RpbV0gIT0gMSAmJiBkID4gMCkge1xuICAgICAgICAgIGludCBkMiA9IGQgLyBzY2FsZXNbZGltXTtcbiAgICAgICAgICBtID0gZCAtIGQyICogc2NhbGVzW2RpbV07XG4gICAgICAgICAgZCA9IGQyO1xuICAgICAgICB9XG4gICAgICAgIGlucHV0X2luZGV4ICs9IGlucHV0X3BpdGNoZXNbZGltXSAqIGQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4KTtcbiAgICB9YFxuICAgICAgOiBkaW0gPT09IDRcbiAgICAgICAgPyAvLyBiaWxpbmVhciA0RFxuICAgICAgICAgIGBcbiAgICAke2dldElucHV0RmxvYXRGdW5jdGlvbn1cbiAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWzRdKSB7XG4gICAgICBpbnQgaW5wdXRfaW5kZXggPSAwO1xuICAgICAgaW50IG91dHB1dF9pbmRleCA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHtvdXRwdXRXaWR0aH0sICR7b3V0cHV0SGVpZ2h0fSk7XG5cbiAgICAgICR7cHJlY2FsY3VsYXRlZFBpdGNoZXN9XG5cbiAgICAgIGludCBtO1xuICAgICAgaW50IGluZGV4X29mX2RpbTAsIGluZGV4X29mX2RpbTEsIGluZGV4X29mX2RpbTIsIGluZGV4X29mX2RpbTM7XG4gICAgICBpbmRleF9vZl9kaW0wID0gb3V0cHV0X2luZGV4IC8gb3V0cHV0X3BpdGNoZXNbMF07XG4gICAgICBtID0gb3V0cHV0X2luZGV4IC0gaW5kZXhfb2ZfZGltMCAqIG91dHB1dF9waXRjaGVzWzBdO1xuICAgICAgaW5kZXhfb2ZfZGltMSA9IG0gLyBvdXRwdXRfcGl0Y2hlc1sxXTtcbiAgICAgIG0gPSBtIC0gaW5kZXhfb2ZfZGltMSAqIG91dHB1dF9waXRjaGVzWzFdO1xuICAgICAgaW5kZXhfb2ZfZGltMiA9IG0gLyBvdXRwdXRfcGl0Y2hlc1syXTtcbiAgICAgIG0gPSBtIC0gaW5kZXhfb2ZfZGltMiAqIG91dHB1dF9waXRjaGVzWzJdO1xuICAgICAgaW5kZXhfb2ZfZGltMyA9IG07XG5cbiAgICAgIGludCBpbmRleF9vZl9pbnB1dF9kaW0yLCBpbmRleF9vZl9pbnB1dF9kaW0zLCB4X29mZnNldCwgeV9vZmZzZXQ7XG4gICAgICBpbmRleF9vZl9pbnB1dF9kaW0yID0gaW5kZXhfb2ZfZGltMiAvIHNjYWxlc1syXTtcbiAgICAgIHlfb2Zmc2V0ID0gaW5kZXhfb2ZfZGltMiAtIGluZGV4X29mX2lucHV0X2RpbTIgKiBzY2FsZXNbMl07XG4gICAgICBpbmRleF9vZl9pbnB1dF9kaW0zID0gaW5kZXhfb2ZfZGltMyAvIHNjYWxlc1szXTtcbiAgICAgIHhfb2Zmc2V0ID0gaW5kZXhfb2ZfZGltMyAtIGluZGV4X29mX2lucHV0X2RpbTMgKiBzY2FsZXNbM107XG5cbiAgICAgIGlucHV0X2luZGV4ID0gaW5kZXhfb2ZfZGltMCAqIGlucHV0X3BpdGNoZXNbMF0gK1xuICAgICAgICAgICAgaW5kZXhfb2ZfZGltMSAqIGlucHV0X3BpdGNoZXNbMV0gK1xuICAgICAgICAgICAgaW5kZXhfb2ZfaW5wdXRfZGltMiAqIGlucHV0X3BpdGNoZXNbMl0gK1xuICAgICAgICAgICAgaW5kZXhfb2ZfaW5wdXRfZGltMztcblxuICAgICAgZmxvYXQgeDAwID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCk7XG4gICAgICBmbG9hdCB4MTAsIHgwMSwgeDExO1xuXG4gICAgICBib29sIGVuZF9vZl9kaW0yID0gZmFsc2U7XG4gICAgICBpZiAoaW5kZXhfb2ZfaW5wdXRfZGltMiA9PSAoJHtpbnB1dHNbMF0uZGltc1syXX0gLSAxKSkge1xuICAgICAgICAvLyBJdCdzIHRoZSBlbmQgaW4gZGltZW5zaW9uIDJcbiAgICAgICAgeDAxID0geDAwO1xuICAgICAgICBlbmRfb2ZfZGltMiA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB4MDEgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4ICsgaW5wdXRfcGl0Y2hlc1syXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbmRleF9vZl9pbnB1dF9kaW0zID09IChpbnB1dF9waXRjaGVzWzJdIC0gMSkpIHtcbiAgICAgICAgLy8gSXQncyB0aGUgZW5kIGluIGRpbWVuc2lvbiAzXG4gICAgICAgIHgxMCA9IHgwMDtcbiAgICAgICAgeDExID0geDAxO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHgxMCA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyAxKTtcbiAgICAgICAgeDExID0gZW5kX29mX2RpbTIgPyB4MTAgOiBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4ICsgaW5wdXRfcGl0Y2hlc1syXSArIDEpO1xuICAgICAgfVxuXG4gICAgICBmbG9hdCB5MCA9IHgwMCArIGZsb2F0KHlfb2Zmc2V0KSAqICh4MDEgLSB4MDApIC8gZmxvYXQoc2NhbGVzWzJdKTtcbiAgICAgIGZsb2F0IHkxID0geDEwICsgZmxvYXQoeV9vZmZzZXQpICogKHgxMSAtIHgxMCkgLyBmbG9hdChzY2FsZXNbMl0pO1xuICAgICAgcmV0dXJuIHkwICsgZmxvYXQoeF9vZmZzZXQpICogKHkxIC0geTApIC8gZmxvYXQoc2NhbGVzWzNdKTtcbiAgICB9YFxuICAgICAgICA6IC8vIGJpbGluZWFyIDJEXG4gICAgICAgICAgYFxuICAgICR7Z2V0SW5wdXRGbG9hdEZ1bmN0aW9ufVxuICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbMl0pIHtcbiAgICAgIGludCBpbnB1dF9pbmRleCA9IDA7XG4gICAgICBpbnQgb3V0cHV0X2luZGV4ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke291dHB1dFdpZHRofSwgJHtvdXRwdXRIZWlnaHR9KTtcblxuICAgICAgJHtwcmVjYWxjdWxhdGVkUGl0Y2hlc31cblxuICAgICAgaW50IG07XG4gICAgICBpbnQgaW5kZXhfb2ZfZGltMCwgaW5kZXhfb2ZfZGltMTtcbiAgICAgIGluZGV4X29mX2RpbTAgPSBvdXRwdXRfaW5kZXggLyBvdXRwdXRfcGl0Y2hlc1swXTtcbiAgICAgIG0gPSBvdXRwdXRfaW5kZXggLSBpbmRleF9vZl9kaW0wICogb3V0cHV0X3BpdGNoZXNbMF07XG4gICAgICBpbmRleF9vZl9kaW0xID0gbTtcblxuICAgICAgaW50IGluZGV4X29mX2lucHV0X2RpbTAsIGluZGV4X29mX2lucHV0X2RpbTEsIHhfb2Zmc2V0LCB5X29mZnNldDtcbiAgICAgIGluZGV4X29mX2lucHV0X2RpbTAgPSBpbmRleF9vZl9kaW0wIC8gc2NhbGVzWzBdO1xuICAgICAgeV9vZmZzZXQgPSBpbmRleF9vZl9kaW0wIC0gaW5kZXhfb2ZfaW5wdXRfZGltMCAqIHNjYWxlc1swXTtcbiAgICAgIGluZGV4X29mX2lucHV0X2RpbTEgPSBpbmRleF9vZl9kaW0xIC8gc2NhbGVzWzFdO1xuICAgICAgeF9vZmZzZXQgPSBpbmRleF9vZl9kaW0xIC0gaW5kZXhfb2ZfaW5wdXRfZGltMSAqIHNjYWxlc1sxXTtcblxuICAgICAgaW5wdXRfaW5kZXggPSBpbmRleF9vZl9pbnB1dF9kaW0wICogaW5wdXRfcGl0Y2hlc1swXSArIGluZGV4X29mX2lucHV0X2RpbTE7XG5cbiAgICAgIGZsb2F0IHgwMCA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXgpO1xuICAgICAgZmxvYXQgeDEwLCB4MDEsIHgxMTtcblxuICAgICAgYm9vbCBlbmRfb2ZfZGltMCA9IGZhbHNlO1xuICAgICAgaWYgKGluZGV4X29mX2lucHV0X2RpbTAgPT0gKCR7aW5wdXRzWzBdLmRpbXNbMF19IC0gMSkpIHtcbiAgICAgICAgLy8gSXQncyB0aGUgZW5kIGluIGRpbWVuc2lvbiAwXG4gICAgICAgIHgwMSA9IHgwMDtcbiAgICAgICAgZW5kX29mX2RpbTAgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeDAxID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIGlucHV0X3BpdGNoZXNbMF0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5kZXhfb2ZfaW5wdXRfZGltMSA9PSAoaW5wdXRfcGl0Y2hlc1swXSAtIDEpKSB7XG4gICAgICAgIC8vIEl0J3MgdGhlIGVuZCBpbiBkaW1lbnNpb24gMVxuICAgICAgICB4MTAgPSB4MDA7XG4gICAgICAgIHgxMSA9IHgwMTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB4MTAgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4ICsgMSk7XG4gICAgICAgIHgxMSA9IGVuZF9vZl9kaW0wID8geDEwIDogZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIGlucHV0X3BpdGNoZXNbMF0gKyAxKTtcbiAgICAgIH1cblxuICAgICAgZmxvYXQgeTAgPSB4MDAgKyBmbG9hdCh5X29mZnNldCkgKiAoeDAxIC0geDAwKSAvIGZsb2F0KHNjYWxlc1swXSk7XG4gICAgICBmbG9hdCB5MSA9IHgxMCArIGZsb2F0KHlfb2Zmc2V0KSAqICh4MTEgLSB4MTApIC8gZmxvYXQoc2NhbGVzWzBdKTtcbiAgICAgIHJldHVybiB5MCArIGZsb2F0KHhfb2Zmc2V0KSAqICh5MSAtIHkwKSAvIGZsb2F0KHNjYWxlc1sxXSk7XG4gICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4udXBzYW1wbGVQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIHZhcmlhYmxlczogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnc2NhbGVzJyxcbiAgICAgICAgdHlwZTogJ2ludCcsXG4gICAgICAgIGFycmF5TGVuZ3RoOiBhdHRyaWJ1dGVzLnNjYWxlcy5sZW5ndGgsXG4gICAgICAgIGRhdGE6IGF0dHJpYnV0ZXMuc2NhbGVzLm1hcCgoeCkgPT4gTWF0aC5jZWlsKHgpKSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGU6IFVwc2FtcGxlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAoXG4gICAgIWlucHV0cyB8fFxuICAgIChhdHRyaWJ1dGUub3BzZXQgPCA5ICYmIGlucHV0cy5sZW5ndGggIT09IDEpIHx8XG4gICAgKGF0dHJpYnV0ZS5vcHNldCA+PSA5ICYmIGF0dHJpYnV0ZS5vcHNldCA8IDExICYmIGlucHV0cy5sZW5ndGggIT09IDIpIHx8XG4gICAgKGF0dHJpYnV0ZS5vcHNldCA+PSAxMSAmJiBpbnB1dHMubGVuZ3RoIDwgMilcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChhdHRyaWJ1dGUuc2NhbGVzLmxlbmd0aCA+IDAgJiYgaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSBhdHRyaWJ1dGUuc2NhbGVzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdGVuc29yIHR5cGVzLicpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2NhbGVzVmFsaWRhdGlvbiA9IChzY2FsZXM6IG51bWJlcltdLCBtb2RlOiBzdHJpbmcsIGlzUmVzaXplOiBib29sZWFuKTogdm9pZCA9PiB7XG4gIGlmICghaXNSZXNpemUpIHtcbiAgICBmb3IgKGNvbnN0IHNjYWxlIG9mIHNjYWxlcykge1xuICAgICAgaWYgKHNjYWxlIDwgMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NjYWxlIHZhbHVlIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMS4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZm9yIChjb25zdCBzY2FsZSBvZiBzY2FsZXMpIHtcbiAgICAgIGlmIChzY2FsZSA8PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignU2NhbGUgdmFsdWUgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiAwLicpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAobW9kZSA9PT0gJ2xpbmVhcicgfHwgbW9kZSA9PT0gJ2N1YmljJykge1xuICAgIGlmIChzY2FsZXMubGVuZ3RoICE9PSAyICYmIChzY2FsZXMubGVuZ3RoICE9PSA0IHx8IHNjYWxlc1swXSAhPT0gMSB8fCBzY2FsZXNbMV0gIT09IDEpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCdMaW5lYXInIG1vZGUgYW5kICdDdWJpYycgbW9kZSBvbmx5IHN1cHBvcnQgMi1EIGlucHV0cyAoJ0JpbGluZWFyJywgJ0JpY3ViaWMnKSBcXFxuICAgICAgICBvciA0LUQgaW5wdXRzIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgb3V0ZXJtb3N0IDIgc2NhbGUgdmFsdWVzIGJlaW5nIDEgXFxcbiAgICAgICAgaW4gdGhlICR7aXNSZXNpemUgPyAnUmVzaXplJyA6ICdVcHNhbXBsZSd9IG9wZWFydG9yLmApO1xuICAgIH1cbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0Q29vcmRzRGF0YVR5cGUgfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IHVucGFja0Zyb21DaGFubmVsIH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcbmltcG9ydCB7IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzLCBzY2FsZXNWYWxpZGF0aW9uLCBVcHNhbXBsZUF0dHJpYnV0ZXMsIHZhbGlkYXRlSW5wdXRzIH0gZnJvbSAnLi91cHNhbXBsZSc7XG5cbmNvbnN0IHJlc2l6ZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1Jlc2l6ZScsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCByZXNpemU6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBVcHNhbXBsZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLnJlc2l6ZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlUGFja2VkUmVzaXplUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMDogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxVcHNhbXBsZUF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogVXBzYW1wbGVBdHRyaWJ1dGVzID0+IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzKG5vZGUsIDEwKTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMTogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxVcHNhbXBsZUF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogVXBzYW1wbGVBdHRyaWJ1dGVzID0+IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzKG5vZGUsIDExKTtcblxuY29uc3QgY3JlYXRlUGFja2VkUmVzaXplUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IFtzY2FsZXMsIG91dHB1dFNoYXBlXSA9IHByZXBhcmVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcblxuICBjb25zdCBpc1NhbWUgPSBzY2FsZXMuZXZlcnkoKHM6IG51bWJlcikgPT4gcyA9PT0gMSkgJiYgYXR0cmlidXRlcy5jb29yZGluYXRlVHJhbnNmb3JtTW9kZSAhPT0gJ3RmX2Nyb3BfYW5kX3Jlc2l6ZSc7XG4gIGlmIChpc1NhbWUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4ucmVzaXplUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZCB9LFxuICAgICAgaGFzTWFpbjogdHJ1ZSxcbiAgICAgIHNoYWRlclNvdXJjZTogYHZvaWQgbWFpbigpIHtcbiAgICAgICAgICAgICAgICAgICAgdmVjNCB2ID0gJHtnbHNsLnRleHR1cmUyRH0oWCwgVGV4Q29vcmRzKTtcbiAgICAgICAgICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2O1xuICAgICAgICAgICAgICAgIH1gLFxuICAgIH07XG4gIH1cblxuICBjb25zdCBkaW0gPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGlmIChkaW0gPCAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBvdXRwdXQgZGltZW5zaW9uIHNob3VsZCBiZSBhdCBsZWFzdCAyLCBidXQgZ290ICR7ZGltfWApO1xuICB9XG5cbiAgY29uc3Qgb3V0cHV0SGVpZ2h0ID0gb3V0cHV0U2hhcGVbZGltIC0gMl07XG4gIGNvbnN0IG91dHB1dFdpZHRoID0gb3V0cHV0U2hhcGVbZGltIC0gMV07XG5cbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBpZiAoZGltICE9PSBpbnB1dFNoYXBlLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgb3V0cHV0IGRpbWVuc2lvbiBzaG91bGQgbWF0Y2ggaW5wdXQgJHtpbnB1dFNoYXBlLmxlbmd0aH0sIGJ1dCBnb3QgJHtkaW19YCk7XG4gIH1cbiAgY29uc3QgaW5wdXRIZWlnaHQgPSBpbnB1dFNoYXBlW2RpbSAtIDJdO1xuICBjb25zdCBpbnB1dFdpZHRoID0gaW5wdXRTaGFwZVtkaW0gLSAxXTtcblxuICBjb25zdCBzY2FsZXNIZWlnaHQgPSBzY2FsZXNbZGltIC0gMl07XG4gIGNvbnN0IHNjYWxlc1dpZHRoID0gc2NhbGVzW2RpbSAtIDFdO1xuXG4gIGxldCBnZXRTb3VyY2VGcmFjSW5kZXggPSAnJztcblxuICBpZiAoYXR0cmlidXRlcy5tb2RlICE9PSAnbGluZWFyJykge1xuICAgIC8vIFRPRE86IHN1cHBvcnQgb3RoZXIgbW9kZXNcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHJlc2l6ZSAocGFja2VkKSBkb2VzIG5vdCBzdXBwb3J0IG1vZGU6ICcke2F0dHJpYnV0ZXMubW9kZX0nYCk7XG4gIH1cbiAgc3dpdGNoIChhdHRyaWJ1dGVzLmNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlKSB7XG4gICAgY2FzZSAnYXN5bW1ldHJpYyc6XG4gICAgICBnZXRTb3VyY2VGcmFjSW5kZXggPSBgXG4gICAgICAgICAgICAgICAgICAgIHZlYzQgZ2V0U291cmNlRnJhY0luZGV4KGl2ZWM0IGNvb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZlYzQoY29vcmRzKSAvIHNjYWxlV0hXSDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGA7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdoYWxmX3BpeGVsJzpcbiAgICAgIGdldFNvdXJjZUZyYWNJbmRleCA9IGBcbiAgICAgICAgICAgICAgICAgICAgdmVjNCBnZXRTb3VyY2VGcmFjSW5kZXgoaXZlYzQgY29vcmRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHZlYzQoY29vcmRzKSArIDAuNSkgLyBzY2FsZVdIV0ggLSAwLjU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAncHl0b3JjaF9oYWxmX3BpeGVsJzpcbiAgICAgIGdldFNvdXJjZUZyYWNJbmRleCA9IGBcbiAgICAgICAgICAgICAgICAgICAgdmVjNCBnZXRTb3VyY2VGcmFjSW5kZXgoaXZlYzQgY29vcmRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZWM0IGZjb29yZHMgPSB2ZWM0KGNvb3Jkcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmVjNChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke291dHB1dFdpZHRofS4wID4gMS4wID8gKGZjb29yZHMueCArIDAuNSkgLyBzY2FsZVdIV0gueCAtIDAuNSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke291dHB1dEhlaWdodH0uMCA+IDEuMCA/IChmY29vcmRzLnkgKyAwLjUpIC8gc2NhbGVXSFdILnkgLSAwLjUgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRXaWR0aH0uMCA+IDEuMCA/IChmY29vcmRzLnogKyAwLjUpIC8gc2NhbGVXSFdILnogLSAwLjUgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRIZWlnaHR9LjAgPiAxLjAgPyAoZmNvb3Jkcy53ICsgMC41KSAvIHNjYWxlV0hXSC53IC0gMC41IDogMC4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnYWxpZ25fY29ybmVycyc6XG4gICAgICBnZXRTb3VyY2VGcmFjSW5kZXggPSBgXG4gICAgICAgICAgICAgICAgICAgIHZlYzQgZ2V0U291cmNlRnJhY0luZGV4KGl2ZWM0IGNvb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVjNCByZXNpemVkID0gdmVjNCgke291dHB1dFdpZHRofS4wIC0gMS4wLCAke291dHB1dEhlaWdodH0uMCAtIDEuMCwgJHtvdXRwdXRXaWR0aH0uMCAtIDEuMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke291dHB1dEhlaWdodH0uMCAtIDEuMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZWM0IG9yaWdpbmFsID0gdmVjNCgke2lucHV0V2lkdGh9LjAgLSAxLjAsICR7aW5wdXRIZWlnaHR9LjAgLSAxLjAsICR7aW5wdXRXaWR0aH0uMCAtIDEuMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke2lucHV0SGVpZ2h0fS4wIC0gMS4wKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlYzQgbmV3X3NjYWxlID0gb3JpZ2luYWwgLyByZXNpemVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZlYzQoY29vcmRzKSAqIG5ld19zY2FsZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGA7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgLy8gVE9ETzpzdXBwb3J0aW5nIG90aGVyIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2Rlc1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGByZXNpemUgKHBhY2tlZCkgZG9lcyBub3Qgc3VwcG9ydCBjb29yZGluYXRlVHJhbnNmb3JtTW9kZTogXFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyR7YXR0cmlidXRlcy5jb29yZGluYXRlVHJhbnNmb3JtTW9kZX0nYCk7XG4gIH1cblxuICBjb25zdCBjb29yZHNEYXRhVHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKGRpbSk7XG4gIGNvbnN0IHVucGFja0NoYW5uZWwgPSB1bnBhY2tGcm9tQ2hhbm5lbCgpO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICAgICBjb25zdCB2ZWMyIGlucHV0V0ggPSB2ZWMyKCR7aW5wdXRIZWlnaHR9LjAsICR7aW5wdXRXaWR0aH0uMCk7XG4gICAgICAgICAgICBjb25zdCB2ZWM0IHNjYWxlV0hXSCA9IHZlYzQoZmxvYXQoJHtzY2FsZXNIZWlnaHR9KSwgZmxvYXQoJHtzY2FsZXNXaWR0aH0pLCBmbG9hdCgke3NjYWxlc0hlaWdodH0pLCBmbG9hdCgke1xuICAgICAgICAgICAgICBzY2FsZXNXaWR0aFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgJHt1bnBhY2tDaGFubmVsfVxuICAgICAgICAgICAgJHtnZXRTb3VyY2VGcmFjSW5kZXh9XG4gICAgICAgICAgICBmbG9hdCBnZXRBVmFsdWUoaW50IHgxMCwgaW50IHIsIGludCBjLCBpbnQgZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnZXRDaGFubmVsKGdldEEoeDEwLCByLCBjLCBkKSwgdmVjMihjLCBkKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgICAgICAgICAgJHtjb29yZHNEYXRhVHlwZX0gcmMgPSBnZXRPdXRwdXRDb29yZHMoKTtcblxuICAgICAgICAgICAgICAgIGludCBiYXRjaCA9IHJjWzBdO1xuICAgICAgICAgICAgICAgIGludCBkZXB0aCA9IHJjWzFdO1xuXG4gICAgICAgICAgICAgICAgLy8gcmV0cmlldmUgdGhlIDQgY29vcmRpbmF0ZXMgdGhhdCBpcyB1c2VkIGluIHRoZSA0IHBhY2tlZCBvdXRwdXQgdmFsdWVzLlxuICAgICAgICAgICAgICAgIGl2ZWM0IGNvb3JkcyA9IGl2ZWM0KHJjLnd6LCByYy53ICsgMSwgcmMueiArIDEpO1xuXG4gICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSBzb3VyY2UgaW5kZXggaW4gZnJhY3Rpb25cbiAgICAgICAgICAgICAgICB2ZWM0IHNvdXJjZUZyYWMgPSBnZXRTb3VyY2VGcmFjSW5kZXgoY29vcmRzKTtcblxuICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgbG93ZXIgYW5kIHVwcGVyIGJvdW5kIG9mIHRoZSA0IHZhbHVlcyB0aGF0IHdpbGwgYmUgcGFja2VkIGludG8gb25lIHRleGVsLlxuICAgICAgICAgICAgICAgIGl2ZWM0IHgwMCA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnh5LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnh5KSkpO1xuICAgICAgICAgICAgICAgIGl2ZWM0IHgwMSA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnh3LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnh3KSkpO1xuICAgICAgICAgICAgICAgIGl2ZWM0IHgxMCA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnp5LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnp5KSkpO1xuICAgICAgICAgICAgICAgIGl2ZWM0IHgxMSA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnp3LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnp3KSkpO1xuXG4gICAgICAgICAgICAgICAgYm9vbCBoYXNOZXh0Um93ID0gcmMudyA8ICR7b3V0cHV0SGVpZ2h0IC0gMX07XG4gICAgICAgICAgICAgICAgYm9vbCBoYXNOZXh0Q29sID0gcmMueiA8ICR7b3V0cHV0V2lkdGggLSAxfTtcblxuICAgICAgICAgICAgICAgIC8vIHBhY2sgeDAwLCB4MDEsIHgxMCwgeDExJ3MgdG9wLWxlZnQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCB0b3BMZWZ0ID0gdmVjNChcbiAgICAgICAgICAgICAgICAgICAgZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAwLngsIHgwMC55KSxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMS54LCB4MDEueSkgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTAueCwgeDEwLnkpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMS54LCB4MTEueSkgOiAwLjApO1xuXG4gICAgICAgICAgICAgICAgLy8gcGFjayB4MDAsIHgwMSwgeDEwLCB4MTEncyB0b3AtcmlnaHQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCB0b3BSaWdodCA9IHZlYzQoXG4gICAgICAgICAgICAgICAgICAgIGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMC54LCB4MDAudyksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDEueCwgeDAxLncpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDEwLngsIHgxMC53KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTEueCwgeDExLncpIDogMC4wKTtcblxuICAgICAgICAgICAgICAgIC8vIHBhY2sgeDAwLCB4MDEsIHgxMCwgeDExJ3MgYm90dG9tLWxlZnQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCBib3R0b21MZWZ0ID0gdmVjNChcbiAgICAgICAgICAgICAgICAgICAgZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAwLnosIHgwMC55KSxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMS56LCB4MDEueSkgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTAueiwgeDEwLnkpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMS56LCB4MTEueSkgOiAwLjApO1xuXG4gICAgICAgICAgICAgICAgLy8gcGFjayB4MDAsIHgwMSwgeDEwLCB4MTEncyBib3R0b20tcmlnaHQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCBib3R0b21SaWdodCA9IHZlYzQoXG4gICAgICAgICAgICAgICAgICAgIGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMC56LCB4MDAudyksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDEueiwgeDAxLncpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDEwLnosIHgxMC53KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTEueiwgeDExLncpIDogMC4wKTtcblxuICAgICAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgaW50ZXJwb2xhdGlvbiBmcmFjdGlvbiBvbiB1IGFuZCB2IGRpcmVjdGlvblxuICAgICAgICAgICAgICAgIHZlYzQgZnJhYyA9IHZlYzQoc291cmNlRnJhYykgLSBmbG9vcihzb3VyY2VGcmFjKTtcbiAgICAgICAgICAgICAgICB2ZWM0IGNsYW1wRnJhYyA9IGNsYW1wKGZyYWMsIHZlYzQoMC4wKSwgdmVjNCgxLjApKTtcblxuICAgICAgICAgICAgICAgIHZlYzQgdG9wID0gbWl4KHRvcExlZnQsIHRvcFJpZ2h0LCBjbGFtcEZyYWMueXd5dyk7XG4gICAgICAgICAgICAgICAgdmVjNCBib3R0b20gPSBtaXgoYm90dG9tTGVmdCwgYm90dG9tUmlnaHQsIGNsYW1wRnJhYy55d3l3KTtcbiAgICAgICAgICAgICAgICB2ZWM0IG5ld1ZhbHVlID0gbWl4KHRvcCwgYm90dG9tLCBjbGFtcEZyYWMueHh6eik7XG5cbiAgICAgICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQobmV3VmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLnJlc2l6ZVByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkIH0sXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBwcmVwYXJlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcyk6IFtyZWFkb25seSBudW1iZXJbXSwgcmVhZG9ubHkgbnVtYmVyW11dID0+IHtcbiAgY29uc3QgeCA9IGlucHV0c1swXTtcbiAgY29uc3QgeERpbXMgPSB4LmRpbXM7XG5cbiAgbGV0IHNjYWxlcyA9IGF0dHJpYnV0ZXMuc2NhbGVzO1xuICBsZXQgb3V0cHV0U2l6ZXM6IG51bWJlcltdIHwgdW5kZWZpbmVkO1xuICBpZiAoc2NhbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIGNvbnN0IHNjYWxlc1RlbnNvciA9IGlucHV0c1thdHRyaWJ1dGVzLnNjYWxlc0lucHV0SWR4XTtcbiAgICBpZiAoc2NhbGVzVGVuc29yICYmIHNjYWxlc1RlbnNvci5zaXplICE9PSAwKSB7XG4gICAgICBpZiAoaW5wdXRzW2F0dHJpYnV0ZXMuc2l6ZXNJbnB1dElkeF0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdPbmx5IG9uZSBvZiBzY2FsZXMgb3Igc2l6ZXMgbXVzdCBiZSBwcm92aWRlZCBhcyBpbnB1dC4nKTtcbiAgICAgIH1cbiAgICAgIHNjYWxlcyA9IHBhcnNlU2NhbGVzRGF0YShzY2FsZXNUZW5zb3IsIGF0dHJpYnV0ZXMubW9kZSwgYXR0cmlidXRlcy5pc1Jlc2l6ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHNpemVzVGVuc29yID0gaW5wdXRzW2F0dHJpYnV0ZXMuc2l6ZXNJbnB1dElkeF07XG4gICAgICBpZiAoIXNpemVzVGVuc29yIHx8IHNpemVzVGVuc29yLnNpemUgPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFaXRoZXIgc2NhbGVzIG9yIHNpemVzIE1VU1QgYmUgcHJvdmlkZWQgYXMgaW5wdXQuJyk7XG4gICAgICB9XG5cbiAgICAgIG91dHB1dFNpemVzID0gQXJyYXkuZnJvbShzaXplc1RlbnNvci5pbnRlZ2VyRGF0YSk7XG4gICAgICBzY2FsZXMgPSBwYXJzZVNjYWxlc0RhdGFGcm9tT3V0cHV0U2l6ZShvdXRwdXRTaXplcywgeERpbXMsIGF0dHJpYnV0ZXMubW9kZSwgYXR0cmlidXRlcy5pc1Jlc2l6ZSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChpbnB1dHNbYXR0cmlidXRlcy5zaXplc0lucHV0SWR4XSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdPbmx5IG9uZSBvZiBzY2FsZXMgb3Igc2l6ZXMgbXVzdCBiZSBwcm92aWRlZCBhcyBpbnB1dC4nKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCB5RGltcyA9IG91dHB1dFNpemVzIHx8IHhEaW1zLm1hcCgoZGltLCBpKSA9PiBNYXRoLmZsb29yKGRpbSAqIHNjYWxlc1tpXSkpO1xuXG4gIHJldHVybiBbc2NhbGVzLCB5RGltc107XG59O1xuXG5jb25zdCBwYXJzZVNjYWxlc0RhdGEgPSAoc2NhbGU6IFRlbnNvciwgbW9kZTogc3RyaW5nLCBpc1Jlc2l6ZTogYm9vbGVhbik6IG51bWJlcltdID0+IHtcbiAgY29uc3Qgc2NhbGVzID0gQXJyYXkuZnJvbShzY2FsZS5mbG9hdERhdGEpO1xuICBzY2FsZXNWYWxpZGF0aW9uKHNjYWxlcywgbW9kZSwgaXNSZXNpemUpO1xuICByZXR1cm4gc2NhbGVzO1xufTtcblxuY29uc3QgcGFyc2VTY2FsZXNEYXRhRnJvbU91dHB1dFNpemUgPSAoXG4gIHlEaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgeERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBtb2RlOiBzdHJpbmcsXG4gIGlzUmVzaXplOiBib29sZWFuLFxuKTogbnVtYmVyW10gPT4ge1xuICBjb25zdCBsZW5ndGggPSB4RGltcy5sZW5ndGg7XG4gIGNvbnN0IHNjYWxlcyA9IG5ldyBBcnJheTxudW1iZXI+KGxlbmd0aCk7XG5cbiAgZm9yIChsZXQgaSA9IDAsIGVuZCA9IGxlbmd0aDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgaWYgKHhEaW1zW2ldID09PSAwKSB7XG4gICAgICBpZiAoeURpbXNbaV0gIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBkaW0gaXMgemVybyBidXQgcmVxdWlyZWQgb3V0cHV0IGRpbSBpcyBub24temVyby4nKTtcbiAgICAgIH1cbiAgICAgIHNjYWxlc1tpXSA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjYWxlc1tpXSA9IHlEaW1zW2ldIC8geERpbXNbaV07XG4gICAgfVxuICB9XG4gIHNjYWxlc1ZhbGlkYXRpb24oc2NhbGVzLCBtb2RlLCBpc1Jlc2l6ZSk7XG4gIHJldHVybiBzY2FsZXM7XG59O1xuXG4vLyByb2kgZGF0YSBpcyBub3QgdXNlZCB5ZXQuIGJ1dCBsZWF2ZSBoZXJlIGZvciBmdXR1cmUgdXNhZ2UuXG4vLyBjb25zdCBnZXRSb2kgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzKSA6IG51bWJlcltdID0+IHtcbi8vICAgICBsZXQgcm9pOiBudW1iZXJbXSA9IFtdO1xuLy8gICAgIGlmIChhdHRyaWJ1dGVzLm5lZWRSb2lJbnB1dCkge1xuLy8gICAgICAgICBpZiAoYXR0cmlidXRlcy5yb2lJbnB1dElkeCA8PSAwKSB7XG4vLyAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcm9pIGlucHV0IGluZGV4LicpO1xuLy8gICAgICAgICB9XG4vLyAgICAgICAgIGNvbnN0IHJvaVRlbnNvciA9IGlucHV0c1thdHRyaWJ1dGVzLnJvaUlucHV0SWR4XTtcbi8vICAgICAgICAgcm9pID0gcm9pVGVuc29yLnNpemUgPiAwID8gQXJyYXkuZnJvbShyb2lUZW5zb3IuZmxvYXREYXRhKSA6IFtdO1xuLy8gICAgIH0gZWxzZSB7XG4vLyAgICAgICAgIHJvaSA9IG5ldyBBcnJheShpbnB1dHNbMF0uZGltcy5sZW5ndGggKiAyKS5maWxsKDApO1xuLy8gICAgIH1cbi8vICAgICByZXR1cm4gcm9pO1xuLy8gfTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuZXhwb3J0IGNvbnN0IHNoYXBlID0gKF9pbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIHJldHVybiBbbmV3IFRlbnNvcihbaW5wdXRzWzBdLmRpbXMubGVuZ3RoXSwgJ2ludDMyJywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIG5ldyBJbnQzMkFycmF5KGlucHV0c1swXS5kaW1zKSldO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaGFwZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE5VTUJFUl9UWVBFUywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2xpY2VBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhlczogbnVtYmVyW107XG4gIHJlYWRvbmx5IGVuZHM6IG51bWJlcltdO1xuICByZWFkb25seSBzdGFydHM6IG51bWJlcltdO1xufVxuXG5jb25zdCBzbGljZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1NsaWNlJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3Qgc2xpY2U6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248U2xpY2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBTbGljZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLnNsaWNlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVTbGljZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcyksXG4gICAgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVNsaWNlQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxTbGljZUF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBTbGljZUF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBzdGFydHMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnc3RhcnRzJyk7XG4gIGNvbnN0IGVuZHMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnZW5kcycpO1xuICBjb25zdCBheGVzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2F4ZXMnLCBbXSk7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBzdGFydHMsIGVuZHMsIGF4ZXMgfSk7XG59O1xuXG5jb25zdCBjcmVhdGVTbGljZVByb2dyYW1JbmZvID0gKFxuICBfaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBhdHRyaWJ1dGVzOiBTbGljZUF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGF4ZXMgPSBhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoID09PSAwID8gaW5wdXQuZGltcy5zbGljZSgwKS5tYXAoKF92YWwsIGkpID0+IGkpIDogYXR0cmlidXRlcy5heGVzO1xuICBjb25zdCBub3JtYWxpemVkQXhlcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGVzKGF4ZXMsIGlucHV0LmRpbXMubGVuZ3RoKTtcbiAgY29uc3Qgc3RhcnRzID0gYXR0cmlidXRlcy5zdGFydHMubWFwKChzdGFydCwgaSkgPT4ge1xuICAgIGlmIChzdGFydCA+IGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dIC0gMSkge1xuICAgICAgcmV0dXJuIGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dO1xuICAgIH1cbiAgICByZXR1cm4gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoc3RhcnQsIGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dKTtcbiAgfSk7XG4gIGNvbnN0IGVuZHMgPSBhdHRyaWJ1dGVzLmVuZHMubWFwKChlbmQsIGkpID0+IHtcbiAgICBpZiAoZW5kID4gaW5wdXQuZGltc1tub3JtYWxpemVkQXhlc1tpXV0gLSAxKSB7XG4gICAgICByZXR1cm4gaW5wdXQuZGltc1tub3JtYWxpemVkQXhlc1tpXV07XG4gICAgfVxuICAgIHJldHVybiBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhlbmQsIGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dKTtcbiAgfSk7XG5cbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dC5kaW1zLnNsaWNlKCk7XG5cbiAgY29uc3Qgc2xpY2VPcHM6IHN0cmluZ1tdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbm9ybWFsaXplZEF4ZXMubGVuZ3RoOyBpKyspIHtcbiAgICBvdXRwdXRTaGFwZVtub3JtYWxpemVkQXhlc1tpXV0gPSBlbmRzW2ldIC0gc3RhcnRzW2ldO1xuICAgIGlmIChzdGFydHNbaV0gPiAwKSB7XG4gICAgICBzbGljZU9wcy5wdXNoKGBvdXRwdXRJZHhbJHtub3JtYWxpemVkQXhlc1tpXX1dICs9ICR7c3RhcnRzW2ldfTtgKTtcbiAgICB9IC8vIGVsc2UgeyBzbGljZU9wcy5wdXNoKGBvdXRwdXRJZHhbJHtub3JtYWxpemVkQXhlc1tpXX1dICs9IDA7YCk7IH1cbiAgfVxuXG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IG91dHB1dElkeFske3Jhbmt9XSkge1xuICAgICAgICAke3NsaWNlT3BzLmpvaW4oJ1xcbiAgICAgICcpfVxuICAgICAgICByZXR1cm4gX0Eob3V0cHV0SWR4KTtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLnNsaWNlUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTbGljZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG4gIGlmIChOVU1CRVJfVFlQRVMuaW5kZXhPZihpbnB1dHNbMF0udHlwZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzbGljZVYxMCA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzVjEwKGlucHV0cyk7XG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSBnZW5lcmF0ZVNsaWNlQXR0cmlidXRlc0Zyb21JbnB1dHMoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4uc2xpY2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZVNsaWNlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBhdHRyaWJ1dGVzKSxcbiAgICB9LFxuICAgIFtpbnB1dHNbMF1dLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5jb25zdCBnZW5lcmF0ZVNsaWNlQXR0cmlidXRlc0Zyb21JbnB1dHMgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbik6IFNsaWNlQXR0cmlidXRlcyA9PiB7XG4gIGlmIChcbiAgICAhaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzFdLmRhdGFJZCkgfHxcbiAgICAhaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzJdLmRhdGFJZCkgfHxcbiAgICAoaW5wdXRzLmxlbmd0aCA+PSA0ICYmICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbM10uZGF0YUlkKSkgfHxcbiAgICAoaW5wdXRzLmxlbmd0aCA+PSA1ICYmICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbNF0uZGF0YUlkKSlcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkeW5hbWljIHNsaWNlIGF0dHJpYnV0ZXMgYXJlIG5vdCBhbGxvd2VkJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzLmxlbmd0aCA+PSA1ICYmIGlucHV0c1s0XS5pbnRlZ2VyRGF0YS5zb21lKChpOiBudW1iZXIpID0+IGkgIT09IDEpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50bHkgbm9uLTEgc3RlcHMgaXMgbm90IHN1cHBvcnRlZCBmb3IgU2xpY2UnKTtcbiAgfVxuXG4gIGNvbnN0IHN0YXJ0cyA9IEFycmF5LmZyb20oaW5wdXRzWzFdLmludGVnZXJEYXRhKTtcbiAgY29uc3QgZW5kcyA9IEFycmF5LmZyb20oaW5wdXRzWzJdLmludGVnZXJEYXRhKTtcbiAgY29uc3QgYXhlcyA9IGlucHV0cy5sZW5ndGggPj0gNCA/IEFycmF5LmZyb20oaW5wdXRzWzNdLmludGVnZXJEYXRhKSA6IFtdO1xuICBjb25zdCBjYWNoZUtleSA9IGAke2F4ZXN9OyR7c3RhcnRzfTske2VuZHN9YDtcbiAgcmV0dXJuIHsgc3RhcnRzLCBlbmRzLCBheGVzLCBjYWNoZUtleSB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHNWMTAgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoIDwgMyB8fCBpbnB1dHMubGVuZ3RoID4gNSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBudW1iZXIuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInIHx8IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMl0udHlwZSAhPT0gJ2ludDMyJyB8fCBpbnB1dHNbMl0uZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzLmxlbmd0aCA+PSA0ICYmIChpbnB1dHNbM10udHlwZSAhPT0gJ2ludDMyJyB8fCBpbnB1dHNbM10uZGltcy5sZW5ndGggIT09IDEpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0cy5sZW5ndGggPj0gNSAmJiAoaW5wdXRzWzRdLnR5cGUgIT09ICdpbnQzMicgfHwgaW5wdXRzWzRdLmRpbXMubGVuZ3RoICE9PSAxKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgdHJhbnNwb3NlLCBUcmFuc3Bvc2VBdHRyaWJ1dGVzIH0gZnJvbSAnLi90cmFuc3Bvc2UnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNvZnRtYXhBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhpczogbnVtYmVyO1xufVxuXG5jb25zdCBzb2Z0bWF4Q29tcHV0ZU1heFByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1NvZnRtYXhDb21wdXRlTWF4JyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBzb2Z0bWF4Q29tcHV0ZVNjYWxlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnU29mdG1heENvbXB1dGVTY2FsZScsXG4gIGlucHV0TmFtZXM6IFsnQScsICdNYXgnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBzb2Z0bWF4UHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnU29mdE1heCcsXG4gIGlucHV0TmFtZXM6IFsnQScsICdNYXgnLCAnTm9ybSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3Qgc29mdG1heDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxTb2Z0bWF4QXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogU29mdG1heEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3QgbG9naWNhbFJvd0NvdW50ID0gU2hhcGVVdGlsLnNpemVUb0RpbWVuc2lvbihpbnB1dFNoYXBlLCBheGlzKTtcbiAgY29uc3QgZmVhdHVyZUNvdW50ID0gU2hhcGVVdGlsLnNpemVGcm9tRGltZW5zaW9uKGlucHV0U2hhcGUsIGF4aXMpO1xuXG4gIGNvbnN0IG91dHB1dCA9IGNvbXB1dGVTb2Z0bWF4KGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgbG9naWNhbFJvd0NvdW50LCBmZWF0dXJlQ291bnQpO1xuICByZXR1cm4gb3V0cHV0O1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlU29mdG1heEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248U29mdG1heEF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogU29mdG1heEF0dHJpYnV0ZXMgPT4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpczogbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIDEpIH0pO1xuXG5leHBvcnQgY29uc3QgcGFyc2VTb2Z0bWF4QXR0cmlidXRlc1YxMzogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxTb2Z0bWF4QXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBTb2Z0bWF4QXR0cmlidXRlcyA9PiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGlzOiBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdheGlzJywgLTEpIH0pO1xuXG4vLyBUaGUgXCJzZW1hbnRpY1wiIG1lYW5pbmcgb2YgYXhpcyBoYXMgY2hhbmdlZCBpbiBvcHNldC0xMy5cbi8vIFBsZWFzZSBjb21wYXJlOiBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L2Jsb2IvbWFpbi9kb2NzL09wZXJhdG9ycy5tZCNTb2Z0bWF4XG4vLyB3aXRoIGh0dHBzOi8vZ2l0aHViLmNvbS9vbm54L29ubngvYmxvYi9tYWluL2RvY3MvQ2hhbmdlbG9nLm1kI1NvZnRtYXgtMTEgZm9yIGRldGFpbGVkIGV4cGxhbmF0aW9uc1xuLy8gVG8gYWNjb3VudCBmb3IgdGhlIG9wc2V0LTEzIGJlaGF2aW9yLCBvdXIgcGxhbiB3aWxsIGJlIHRvIHRyYW5zcG9zZSB0aGUgXCJheGlzXCIgZGltIHRvIHRoZSBpbm5lcm1vc3QgZGltXG4vLyBhbmQgcGVyZm9ybSBzb2Z0bWF4IGFuZCB0aGVuIHJldmVyc2UgdGhlIHRyYW5zcG9zZS4gV2UgY2FuIHNraXAgdGhlIHRyYW5zcG9zaW5nIGFzcGVjdCBpZiB0aGUgYXhpcyBpcyBhbHJlYWR5XG4vLyB0aGUgaW5uZXJtb3N0IGRpbVxuZXhwb3J0IGNvbnN0IHNvZnRtYXhWMTM6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248U29mdG1heEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFNvZnRtYXhBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXR0cmlidXRlcy5heGlzLCBpbnB1dFNoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IHJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcblxuICBjb25zdCBpc1RyYW5zcG9zZVJlcXVpcmVkID0gYXhpcyAhPT0gcmFuayAtIDEgPyB0cnVlIDogZmFsc2U7XG4gIGNvbnN0IHRyYW5zcG9zZWRJbnB1dFNoYXBlOiBudW1iZXJbXSA9IFtdO1xuICBsZXQgcGVybTogbnVtYmVyW10gPSBbXTtcbiAgbGV0IHRyYW5zcG9zZWRJbnB1dHM6IFRlbnNvcltdID0gW107XG4gIGxldCB0cmFuc3Bvc2VBdHRyaWJ1dGU6IFRyYW5zcG9zZUF0dHJpYnV0ZXM7XG5cbiAgaWYgKGlzVHJhbnNwb3NlUmVxdWlyZWQpIHtcbiAgICBwZXJtID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogcmFuayB9KS5tYXAoKF8sIGkpID0+IGkpO1xuXG4gICAgLy8gc3dhcCB0aGUgaW5uZXJtb3N0IGRpbSB3aXRoIHRoZSBkaW0gY29ycmVzcG9uZGluZyB0byBheGlzXG4gICAgcGVybVtheGlzXSA9IHJhbmsgLSAxO1xuICAgIHBlcm1bcmFuayAtIDFdID0gYXhpcztcblxuICAgIHBlcm0ubWFwKChwKSA9PiB0cmFuc3Bvc2VkSW5wdXRTaGFwZS5wdXNoKGlucHV0U2hhcGVbcF0pKTtcblxuICAgIHRyYW5zcG9zZUF0dHJpYnV0ZSA9IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IHBlcm0gfSk7XG4gICAgdHJhbnNwb3NlZElucHV0cyA9IHRyYW5zcG9zZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIHRyYW5zcG9zZUF0dHJpYnV0ZSk7XG4gIH1cblxuICBjb25zdCBsb2dpY2FsUm93Q291bnQgPSBpc1RyYW5zcG9zZVJlcXVpcmVkXG4gICAgPyBTaGFwZVV0aWwuc2l6ZVRvRGltZW5zaW9uKHRyYW5zcG9zZWRJbnB1dFNoYXBlLCByYW5rIC0gMSlcbiAgICA6IFNoYXBlVXRpbC5zaXplVG9EaW1lbnNpb24oaW5wdXRTaGFwZSwgcmFuayAtIDEpO1xuICBjb25zdCBmZWF0dXJlQ291bnQgPSBpc1RyYW5zcG9zZVJlcXVpcmVkXG4gICAgPyBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24odHJhbnNwb3NlZElucHV0U2hhcGUsIHJhbmsgLSAxKVxuICAgIDogU2hhcGVVdGlsLnNpemVGcm9tRGltZW5zaW9uKGlucHV0U2hhcGUsIHJhbmsgLSAxKTtcblxuICBjb25zdCBvdXRwdXQgPSBjb21wdXRlU29mdG1heChcbiAgICBpbmZlcmVuY2VIYW5kbGVyLFxuICAgIGlzVHJhbnNwb3NlUmVxdWlyZWQgPyB0cmFuc3Bvc2VkSW5wdXRzIDogaW5wdXRzLFxuICAgIGF0dHJpYnV0ZXMsXG4gICAgbG9naWNhbFJvd0NvdW50LFxuICAgIGZlYXR1cmVDb3VudCxcbiAgKTtcblxuICBpZiAoaXNUcmFuc3Bvc2VSZXF1aXJlZCkge1xuICAgIGNvbnN0IHJldmVyc2VkT3V0cHV0ID0gdHJhbnNwb3NlKGluZmVyZW5jZUhhbmRsZXIsIG91dHB1dCwgdHJhbnNwb3NlQXR0cmlidXRlISk7XG4gICAgcmV0dXJuIHJldmVyc2VkT3V0cHV0O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbn07XG5cbmNvbnN0IGNvbXB1dGVTb2Z0bWF4ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFNvZnRtYXhBdHRyaWJ1dGVzLFxuICBsb2dpY2FsUm93Q291bnQ6IG51bWJlcixcbiAgZmVhdHVyZUNvdW50OiBudW1iZXIsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IGNvbXB1dGVNYXhQcm9ncmFtSW5mbyA9IGNyZWF0ZUNvbXB1dGVNYXhQcm9ncmFtSW5mbyhcbiAgICBpbmZlcmVuY2VIYW5kbGVyLFxuICAgIGlucHV0c1swXSxcbiAgICBsb2dpY2FsUm93Q291bnQsXG4gICAgZmVhdHVyZUNvdW50LFxuICAgIFtsb2dpY2FsUm93Q291bnRdLFxuICApO1xuICBjb25zdCBtYXggPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLnNvZnRtYXhDb21wdXRlTWF4UHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGdldDogKCkgPT4gY29tcHV0ZU1heFByb2dyYW1JbmZvIH0sXG4gICAgaW5wdXRzLFxuICApO1xuXG4gIGNvbnN0IGNvbXB1dGVTY2FsZVByb2dyYW1JbmZvID0gY3JlYXRlQ29tcHV0U2NhbGVQcm9ncmFtSW5mbyhcbiAgICBpbmZlcmVuY2VIYW5kbGVyLFxuICAgIGlucHV0c1swXSxcbiAgICBsb2dpY2FsUm93Q291bnQsXG4gICAgZmVhdHVyZUNvdW50LFxuICAgIGNvbXB1dGVNYXhQcm9ncmFtSW5mby5vdXRwdXQuZGltcyxcbiAgICBbbG9naWNhbFJvd0NvdW50XSxcbiAgKTtcbiAgY29uc3Qgc2NhbGUgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLnNvZnRtYXhDb21wdXRlU2NhbGVQcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgZ2V0OiAoKSA9PiBjb21wdXRlU2NhbGVQcm9ncmFtSW5mbyB9LFxuICAgIFtpbnB1dHNbMF0sIG1heF0sXG4gICk7XG5cbiAgY29uc3Qgc29mdE1heFByb2dyYW1JbmZvID0gY3JlYXRlU29mdE1heFByb2dyYW1JbmZvKFxuICAgIGluZmVyZW5jZUhhbmRsZXIsXG4gICAgaW5wdXRzWzBdLFxuICAgIGxvZ2ljYWxSb3dDb3VudCxcbiAgICBmZWF0dXJlQ291bnQsXG4gICAgY29tcHV0ZU1heFByb2dyYW1JbmZvLm91dHB1dC5kaW1zLFxuICAgIGNvbXB1dGVTY2FsZVByb2dyYW1JbmZvLm91dHB1dC5kaW1zLFxuICApO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLnNvZnRtYXhQcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgZ2V0OiAoKSA9PiBzb2Z0TWF4UHJvZ3JhbUluZm8gfSxcbiAgICBbaW5wdXRzWzBdLCBtYXgsIHNjYWxlXSxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuLyoqXG4gKiBDcmVhdGUgYSB0ZXh0dXJlIHRoYXQgY29udGFpbnMgdGhlIG1heGltdW0gdmFsdWUgb2YgZWFjaCBvZiB0aGUgJ04nIHJvd3NcbiAqL1xuY29uc3QgY3JlYXRlQ29tcHV0ZU1heFByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGxvZ2ljYWxSb3dDb3VudDogbnVtYmVyLFxuICBmZWF0dXJlQ291bnQ6IG51bWJlcixcbiAgb3V0cHV0U2hhcGU6IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBbdGV4dHVyZVdpZHRoLCB0ZXh0dXJlSGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGlucHV0LmRpbXMsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICk7XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG5cbiAgaWYgKGxvZ2ljYWxSb3dDb3VudCA8IDEgfHwgZmVhdHVyZUNvdW50IDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTG9naWNhbCByb3cgY291bnQgTiBhbmQgZmVhdHVyZSBjb3VudCBEIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEnKTtcbiAgfVxuXG4gIGlmIChvdXRwdXRTaGFwZS5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbWVuc2lvbmFsaXR5IG9mIHRoZSBvdXRwdXQgc2hvdWxkIGJlIDEnKTtcbiAgfVxuXG4gIGlmIChvdXRwdXRTaGFwZVswXSAhPT0gbG9naWNhbFJvd0NvdW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaGFwZSBvZiB0aGUgb3V0cHV0IHNob3VsZCBiZSBlcXVhbCB0byBsb2dpY2FsIHJvdyBjb3VudCcpO1xuICB9XG5cbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG4gICAgICAgIGludCBsb2dpY2FsX3Jvd19zdGFydF9vZmZzZXQgPSBpbmRpY2VzWzBdICogJHtmZWF0dXJlQ291bnR9O1xuXG4gICAgICAgIGZsb2F0IG1heCA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShBLCBvZmZzZXRUb0Nvb3Jkcyhsb2dpY2FsX3Jvd19zdGFydF9vZmZzZXQsICR7dGV4dHVyZVdpZHRofSxcbiAgICAgICAgJHt0ZXh0dXJlSGVpZ2h0fSApKSk7XG4gICAgICAgIGZvcihpbnQgaT0xOyBpPCR7ZmVhdHVyZUNvdW50fTsgKytpKVxuICAgICAgICB7XG4gICAgICAgICAgZmxvYXQgY3VycmVudCA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShBLCBvZmZzZXRUb0Nvb3Jkcyhsb2dpY2FsX3Jvd19zdGFydF9vZmZzZXQgKyBpLFxuICAgICAgICAgICAgJHt0ZXh0dXJlV2lkdGh9LCAke3RleHR1cmVIZWlnaHR9KSkpO1xuICAgICAgICAgIGlmKGN1cnJlbnQgPiBtYXgpXG4gICAgICAgICAgbWF4ID0gY3VycmVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtYXg7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5zb2Z0bWF4Q29tcHV0ZU1heFByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgdGV4dHVyZSB0aGF0IGNvbnRhaW5zIHRoZSBub3JtYWxpemF0aW9uIGZhY3RvciBmb3IgZWFjaCBvZiB0aGUgJ04nIHJvd3NcbiAqL1xuY29uc3QgY3JlYXRlQ29tcHV0U2NhbGVQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBsb2dpY2FsUm93Q291bnQ6IG51bWJlcixcbiAgZmVhdHVyZUNvdW50OiBudW1iZXIsXG4gIG1heEVsZW1lbnRQZXJMb2dpY2FsUm93OiByZWFkb25seSBudW1iZXJbXSxcbiAgb3V0cHV0U2hhcGU6IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBbdGV4dHVyZVdpZHRoLCB0ZXh0dXJlSGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGlucHV0LmRpbXMsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICk7XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG5cbiAgaWYgKGxvZ2ljYWxSb3dDb3VudCA8IDEgfHwgZmVhdHVyZUNvdW50IDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTG9naWNhbCByb3cgY291bnQgTiBhbmQgZmVhdHVyZSBjb3VudCBEIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEnKTtcbiAgfVxuXG4gIGlmIChvdXRwdXRTaGFwZS5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbWVuc2lvbmFsaXR5IG9mIHRoZSBvdXRwdXQgc2hvdWxkIGJlIDEnKTtcbiAgfVxuXG4gIGlmIChvdXRwdXRTaGFwZVswXSAhPT0gbG9naWNhbFJvd0NvdW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaGFwZSBvZiB0aGUgb3V0cHV0IHNob3VsZCBiZSBlcXVhbCB0byBsb2dpY2FsIHJvdyBjb3VudCcpO1xuICB9XG5cbiAgaWYgKG1heEVsZW1lbnRQZXJMb2dpY2FsUm93Lmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRGltZW5zaW9uYWxpdHkgb2YgdGhlIGludGVybWVkaWF0ZSByZXN1bHRzIHNob3VsZCBiZSAxJyk7XG4gIH1cblxuICBpZiAobWF4RWxlbWVudFBlckxvZ2ljYWxSb3dbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgb2YgdGhlIGludGVybWVkaWF0ZSByZXN1bHRzIHNob3VsZCBiZSBlcXVhbCB0byBsb2dpY2FsIHJvdyBjb3VudCcpO1xuICB9XG5cbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG4gICAgICAgIGludCBsb2dpY2FsX3Jvd19zdGFydF9vZmZzZXQgPSBpbmRpY2VzWzBdICogJHtmZWF0dXJlQ291bnR9O1xuXG4gICAgICAgIGZsb2F0IG5vcm1fZmFjdG9yID0gMC4wO1xuICAgICAgICBmbG9hdCBtYXggPSBfTWF4KGluZGljZXMpO1xuICAgICAgICBmb3IoaW50IGk9MDsgaTwke2ZlYXR1cmVDb3VudH07ICsraSlcbiAgICAgICAge1xuICAgICAgICAgIG5vcm1fZmFjdG9yICs9IGV4cChnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgb2Zmc2V0VG9Db29yZHMobG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0ICsgaSxcbiAgICAgICAgICAgICR7dGV4dHVyZVdpZHRofSwgJHt0ZXh0dXJlSGVpZ2h0fSkpKSAtIG1heCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbm9ybV9mYWN0b3I7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5zb2Z0bWF4Q29tcHV0ZVNjYWxlUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlU29mdE1heFByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGxvZ2ljYWxSb3dDb3VudDogbnVtYmVyLFxuICBmZWF0dXJlQ291bnQ6IG51bWJlcixcbiAgbWF4RWxlbWVudFBlckxvZ2ljYWxSb3c6IHJlYWRvbmx5IG51bWJlcltdLFxuICBub3JtYWxpemF0aW9uUGVyTG9naWNhbFJvdzogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IFt0ZXh0dXJlV2lkdGgsIHRleHR1cmVIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgaW5wdXQuZGltcyxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgKTtcbiAgY29uc3QgcmFuayA9IGlucHV0LmRpbXMubGVuZ3RoO1xuXG4gIGlmIChsb2dpY2FsUm93Q291bnQgPCAxIHx8IGZlYXR1cmVDb3VudCA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvZ2ljYWwgcm93IGNvdW50IE4gYW5kIGZlYXR1cmUgY291bnQgRCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gIH1cblxuICBpZiAobWF4RWxlbWVudFBlckxvZ2ljYWxSb3cubGVuZ3RoICE9PSAxIHx8IG5vcm1hbGl6YXRpb25QZXJMb2dpY2FsUm93Lmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRGltZW5zaW9uYWxpdHkgb2YgdGhlIGludGVybWVkaWF0ZSByZXN1bHRzIHNob3VsZCBiZSAxJyk7XG4gIH1cblxuICBpZiAobWF4RWxlbWVudFBlckxvZ2ljYWxSb3dbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCB8fCBub3JtYWxpemF0aW9uUGVyTG9naWNhbFJvd1swXSAhPT0gbG9naWNhbFJvd0NvdW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaGFwZSBvZiB0aGUgaW50ZXJtZWRpYXRlIHJlc3VsdHMgc2hvdWxkIGJlIGVxdWFsIHRvIGxvZ2ljYWwgcm93IGNvdW50Jyk7XG4gIH1cblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG5cbiAgICAgIC8vIGdldCBvZmZzZXQgb2YgY3VycmVudCBsb2dpY2FsIHRlbnNvciBpbmRleCBmcm9tIHRoZSAyLUQgdGV4dHVyZSBjb29yZGluYXRlcyAoVGV4Q29vcmRzKVxuICAgICAgaW50IG9mZnNldCA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHt0ZXh0dXJlV2lkdGh9LCAke3RleHR1cmVIZWlnaHR9KTtcblxuICAgICAgLy9kZXRlcm1pbmUgdGhlIGxvZ2ljYWwgcm93IGZvciB0aGlzIGluZGV4XG4gICAgICBpbnQgbG9naWNhbF9yb3dfaW5kZXhbMV07XG4gICAgICBsb2dpY2FsX3Jvd19pbmRleFswXSA9IG9mZnNldCAvICR7ZmVhdHVyZUNvdW50fTtcblxuICAgICAgZmxvYXQgbm9ybV9mYWN0b3IgPSBfTm9ybShsb2dpY2FsX3Jvd19pbmRleCk7XG5cbiAgICAgIC8vIGF2b2lkIHBvc3NpYmxlIGRpdmlzaW9uIGJ5IDBcbiAgICAgIC8vIGlmIG5vcm1fZmFjb3IgaXMgMCwgYWxsIGVsZW1lbnRzIGFyZSB6ZXJvXG4gICAgICAvLyBpZiBzbywgcmV0dXJuIDBcbiAgICAgIGlmKG5vcm1fZmFjdG9yID09IDAuMClcbiAgICAgICAgcmV0dXJuIDAuMDtcblxuICAgICAgcmV0dXJuIGV4cChfQShpbmRpY2VzKSAtIF9NYXgobG9naWNhbF9yb3dfaW5kZXgpKSAvIG5vcm1fZmFjdG9yO1xuICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLnNvZnRtYXhQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IGlucHV0LmRpbXMsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU29mdG1heCByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsLCBTcGxpdFV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBTcGxpdEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGlzOiBudW1iZXI7XG4gIHJlYWRvbmx5IHNwbGl0OiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgbnVtT3V0cHV0czogbnVtYmVyO1xufVxuXG5jb25zdCBzcGxpdFByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1NwbGl0JyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3Qgc3BsaXQ6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248U3BsaXRBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBTcGxpdEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMuYXhpcywgaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcbiAgY29uc3QgY291bnQgPSBnZXRQcm9ncmFtQ291bnQoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBheGlzLCBhdHRyaWJ1dGVzKTtcbiAgY29uc3Qgb3V0cHV0OiBUZW5zb3JbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyArK2kpIHtcbiAgICBvdXRwdXQucHVzaChcbiAgICAgIGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICB7XG4gICAgICAgICAgLi4uc3BsaXRQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgICAgY2FjaGVIaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fTske2l9YCxcbiAgICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZVNwbGl0UHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBhdHRyaWJ1dGVzLCBheGlzLCBpKSxcbiAgICAgICAgfSxcbiAgICAgICAgaW5wdXRzLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVNwbGl0QXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxTcGxpdEF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBTcGxpdEF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBheGlzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIDApO1xuICBjb25zdCBzcGxpdCA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdzcGxpdCcsIFtdKTtcbiAgY29uc3QgbnVtT3V0cHV0cyA9IG5vZGUub3V0cHV0cy5sZW5ndGg7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGlzLCBzcGxpdCwgbnVtT3V0cHV0cyB9KTtcbn07XG5cbmNvbnN0IGdldFByb2dyYW1Db3VudCA9IChcbiAgX2luZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXhpczogbnVtYmVyLFxuICBhdHRyaWJ1dGVzOiBTcGxpdEF0dHJpYnV0ZXMsXG4pOiBudW1iZXIgPT4ge1xuICBjb25zdCBbLCBvZmZzZXRzXSA9IFNwbGl0VXRpbC5zcGxpdFNoYXBlKGlucHV0c1swXS5kaW1zLCBheGlzLCBhdHRyaWJ1dGVzLnNwbGl0LCBhdHRyaWJ1dGVzLm51bU91dHB1dHMpO1xuICByZXR1cm4gb2Zmc2V0cy5sZW5ndGg7XG59O1xuXG5jb25zdCBjcmVhdGVTcGxpdFByb2dyYW1JbmZvID0gKFxuICBfaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBhdHRyaWJ1dGVzOiBTcGxpdEF0dHJpYnV0ZXMsXG4gIGF4aXM6IG51bWJlcixcbiAgaW5kZXg6IG51bWJlcixcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgW3NoYXBlcywgb2Zmc2V0c10gPSBTcGxpdFV0aWwuc3BsaXRTaGFwZShpbnB1dC5kaW1zLCBheGlzLCBhdHRyaWJ1dGVzLnNwbGl0LCBhdHRyaWJ1dGVzLm51bU91dHB1dHMpO1xuICBjb25zdCBvZmZzZXQgPSBvZmZzZXRzW2luZGV4XTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBzaGFwZXNbaW5kZXhdO1xuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgIGluZGljZXNbJHtheGlzfV0gKz0gJHtvZmZzZXR9O1xuICAgICAgICByZXR1cm4gX0EoaW5kaWNlcyk7XG4gICAgICB9XG4gICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5zcGxpdFByb2dyYW1NZXRhZGF0YSxcbiAgICBjYWNoZUhpbnQ6IGAke2F0dHJpYnV0ZXMuY2FjaGVLZXl9OiR7aW5kZXh9YCxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU3BsaXQgcmVxdWlyZXMgb25lIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKFxuICAgIGlucHV0c1swXS50eXBlICE9PSAnaW50OCcgJiZcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ3VpbnQ4JyAmJlxuICAgIGlucHV0c1swXS50eXBlICE9PSAnaW50MTYnICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICd1aW50MTYnICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICdpbnQzMicgJiZcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ3VpbnQzMicgJiZcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0JyAmJlxuICAgIGlucHV0c1swXS50eXBlICE9PSAnYm9vbCdcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCBzcXVlZXplOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPG51bWJlcltdPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBheGVzOiBudW1iZXJbXSxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBTaGFwZVV0aWwuc3F1ZWV6ZVNoYXBlKGlucHV0c1swXS5kaW1zLCBheGVzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBvdXRwdXRTaGFwZSk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBzcXVlZXplVjEzID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHNWMTMoaW5wdXRzKTtcbiAgcmV0dXJuIHNxdWVlemUoaW5mZXJlbmNlSGFuZGxlciwgW2lucHV0c1swXV0sIEFycmF5LmZyb20oaW5wdXRzWzFdLmludGVnZXJEYXRhKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTcXVlZXplQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxudW1iZXJbXT4gPSAobm9kZTogR3JhcGguTm9kZSk6IG51bWJlcltdID0+XG4gIG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdheGVzJyk7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU3F1ZWV6ZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCB0ZW5zb3IgdHlwZXMuJyk7XG4gIH1cbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzVjEzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignU3F1ZWV6ZSByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgY29uc3Qgc3VtID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCBzdW1Qcm9ncmFtTWV0YWRhdGEgPSB7XG4gICAgbmFtZTogJ1N1bScsXG4gICAgaW5wdXROYW1lczogaW5wdXRzLm1hcCgoX3YsIGkpID0+IGBYJHtpfWApLFxuICAgIGlucHV0VHlwZXM6IG5ldyBBcnJheShpbnB1dHMubGVuZ3RoKS5maWxsKFRleHR1cmVUeXBlLnVucGFja2VkKSxcbiAgfTtcblxuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLnN1bVByb2dyYW1NZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVTdW1Qcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIHN1bVByb2dyYW1NZXRhZGF0YSkgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmNvbnN0IGNyZWF0ZVN1bVByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIHN1bVByb2dyYW1NZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3Qgc3VtTGluZSA9IGlucHV0cy5tYXAoKF92LCBpKSA9PiBgJHtnbHNsLnRleHR1cmUyRH0oWCR7aX0sVGV4Q29vcmRzKWApLmpvaW4oJyArICcpO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgIHZlYzQgcmVzdWx0ID0gJHtzdW1MaW5lfTtcbiAgICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgICB9XG4gICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5zdW1Qcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1N1bSByZXF1aXJlcyBpbnB1dHMuJyk7XG4gIH1cblxuICBjb25zdCBsZW5ndGggPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGZvciAobGV0IGkgPSAxOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGxlbmd0aCAhPT0gaW5wdXRzW2ldLmRpbXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHNoYXBlcyBhcmUgbWlzbWF0Y2hlZC4nKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGxlbmd0aDsgaisrKSB7XG4gICAgICBpZiAoaW5wdXRzWzBdLmRpbXNbal0gIT09IGlucHV0c1tpXS5kaW1zW2pdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgc2hhcGVzIGFyZSBub3QgbWF0Y2hlZC4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09IGlucHV0c1tpXS50eXBlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHR5cGVzIGFyZSBub3QgbWF0Y2hlZC4nKTtcbiAgICB9XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IE5VTUJFUl9UWVBFUyB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCB0aWxlID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCB0aWxlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdUaWxlJyxcbiAgICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICB9O1xuXG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHsgLi4udGlsZVByb2dyYW1NZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVUaWxlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCB0aWxlUHJvZ3JhbU1ldGFkYXRhKSB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgY3JlYXRlVGlsZVByb2dyYW1JbmZvID0gKFxuICBfaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICB0aWxlUHJvZ3JhbU1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IG5ldyBBcnJheShpbnB1dFNoYXBlLmxlbmd0aCk7XG5cbiAgY29uc3QgdGlsZU9wczogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dFNoYXBlLmxlbmd0aDsgaSsrKSB7XG4gICAgb3V0cHV0U2hhcGVbaV0gPSBpbnB1dFNoYXBlW2ldICogaW5wdXRzWzFdLm51bWJlckRhdGFbaV07XG4gICAgdGlsZU9wcy5wdXNoKGBpbnB1dElkeFske2l9XSA9IGludChtb2QoZmxvYXQob3V0cHV0SWR4WyR7aX1dKSwgJHtpbnB1dFNoYXBlW2ldfS4pKTtgKTtcbiAgfVxuXG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IG91dHB1dElkeFske3Jhbmt9XSkge1xuICAgICAgICBpbnQgaW5wdXRJZHhbJHtyYW5rfV07XG4gICAgICAgICR7dGlsZU9wcy5qb2luKCdcXG4nKX1cbiAgICAgICAgcmV0dXJuIF9BKGlucHV0SWR4KTtcbiAgICAgIH1cbiAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLnRpbGVQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaWxlIHJlcXVpcmVzIDIgaW5wdXQuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVGhlIHNlY29uZCBpbnB1dCBzaGFwZSBtdXN0IDEgZGltZW5zaW9uLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0uZGltc1swXSAhPT0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmIChOVU1CRVJfVFlQRVMuaW5kZXhPZihpbnB1dHNbMF0udHlwZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInICYmIGlucHV0c1sxXS50eXBlICE9PSAnaW50MTYnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHJlcGVhdCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3QgdW5zcXVlZXplOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPG51bWJlcltdPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBheGVzOiBudW1iZXJbXSxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBTaGFwZVV0aWwudW5zcXVlZXplU2hhcGUoaW5wdXRzWzBdLmRpbXMsIGF4ZXMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIG91dHB1dFNoYXBlKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHVuc3F1ZWV6ZVYxMyA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzVjEzKGlucHV0cyk7XG4gIHJldHVybiB1bnNxdWVlemUoaW5mZXJlbmNlSGFuZGxlciwgW2lucHV0c1swXV0sIEFycmF5LmZyb20oaW5wdXRzWzFdLmludGVnZXJEYXRhKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VVbnNxdWVlemVBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPG51bWJlcltdPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogbnVtYmVyW10gPT5cbiAgbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2F4ZXMnKTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnNxdWVlemUgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQgdGVuc29yIHR5cGVzLicpO1xuICB9XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0c1YxMyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3F1ZWV6ZSByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBPcFNldCB9IGZyb20gJy4uLy4uL29wc2V0JztcblxuaW1wb3J0IHsgYmF0Y2hOb3JtYWxpemF0aW9uLCBwYXJzZUJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9iYXRjaC1ub3JtYWxpemF0aW9uJztcbmltcG9ydCAqIGFzIGJpbmFyeU9wcyBmcm9tICcuL29wcy9iaW5hcnktb3AnO1xuaW1wb3J0IHsgY2FzdCwgcGFyc2VDYXN0QXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2Nhc3QnO1xuaW1wb3J0IHsgY29uY2F0LCBwYXJzZUNvbmNhdEF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9jb25jYXQnO1xuaW1wb3J0IHsgY29udiwgcGFyc2VDb252QXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2NvbnYnO1xuaW1wb3J0IHsgY29udlRyYW5zcG9zZSwgcGFyc2VDb252VHJhbnNwb3NlQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2NvbnYtdHJhbnNwb3NlJztcbmltcG9ydCB7IGRlcHRoVG9TcGFjZSwgcGFyc2VEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvZGVwdGgtdG8tc3BhY2UnO1xuaW1wb3J0IHsgZmxhdHRlbiwgcGFyc2VGbGF0dGVuQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2ZsYXR0ZW4nO1xuaW1wb3J0IHsgZ2F0aGVyLCBwYXJzZUdhdGhlckF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9nYXRoZXInO1xuaW1wb3J0IHsgZ2VtbSwgcGFyc2VHZW1tQXR0cmlidXRlc1YxMSwgcGFyc2VHZW1tQXR0cmlidXRlc1Y3IH0gZnJvbSAnLi9vcHMvZ2VtbSc7XG5pbXBvcnQgeyBpbWFnZVNjYWxlciwgcGFyc2VJbWFnZVNjYWxlckF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9pbWFnZS1zY2FsZXInO1xuaW1wb3J0IHsgaW5zdGFuY2VOb3JtYWxpemF0aW9uLCBwYXJzZUluc3RhbmNlTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9pbnN0YW5jZS1ub3JtYWxpemF0aW9uJztcbmltcG9ydCB7IGxybiwgcGFyc2VMcm5BdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvbHJuJztcbmltcG9ydCB7IG1hdE11bCwgcGFyc2VNYXRNdWxBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvbWF0bXVsJztcbmltcG9ydCB7IHBhZFYxMSwgcGFkVjIsIHBhcnNlUGFkQXR0cmlidXRlc1YxMSwgcGFyc2VQYWRBdHRyaWJ1dGVzVjIgfSBmcm9tICcuL29wcy9wYWQnO1xuaW1wb3J0IHtcbiAgYXZlcmFnZVBvb2wsXG4gIGdsb2JhbEF2ZXJhZ2VQb29sLFxuICBnbG9iYWxNYXhQb29sLFxuICBtYXhQb29sLFxuICBwYXJzZUF2ZXJhZ2VQb29sQXR0cmlidXRlcyxcbiAgcGFyc2VHbG9iYWxBdmVyYWdlUG9vbEF0dHJpYnV0ZXMsXG4gIHBhcnNlTWF4UG9vbEF0dHJpYnV0ZXMsXG59IGZyb20gJy4vb3BzL3Bvb2wnO1xuaW1wb3J0IHtcbiAgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzLFxuICByZWR1Y2VMb2dTdW0sXG4gIHJlZHVjZUxvZ1N1bVNxdWFyZSxcbiAgcmVkdWNlTWF4LFxuICByZWR1Y2VNZWFuLFxuICByZWR1Y2VNaW4sXG4gIHJlZHVjZVByb2QsXG4gIHJlZHVjZVN1bSxcbn0gZnJvbSAnLi9vcHMvcmVkdWNlJztcbmltcG9ydCB7IHJlc2hhcGUgfSBmcm9tICcuL29wcy9yZXNoYXBlJztcbmltcG9ydCB7IHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMCwgcGFyc2VSZXNpemVBdHRyaWJ1dGVzVjExLCByZXNpemUgfSBmcm9tICcuL29wcy9yZXNpemUtcGFja2VkJztcbmltcG9ydCB7IHNoYXBlIH0gZnJvbSAnLi9vcHMvc2hhcGUnO1xuaW1wb3J0IHsgcGFyc2VTbGljZUF0dHJpYnV0ZXMsIHNsaWNlLCBzbGljZVYxMCB9IGZyb20gJy4vb3BzL3NsaWNlJztcbmltcG9ydCB7IHBhcnNlU29mdG1heEF0dHJpYnV0ZXMsIHBhcnNlU29mdG1heEF0dHJpYnV0ZXNWMTMsIHNvZnRtYXgsIHNvZnRtYXhWMTMgfSBmcm9tICcuL29wcy9zb2Z0bWF4JztcbmltcG9ydCB7IHBhcnNlU3BsaXRBdHRyaWJ1dGVzLCBzcGxpdCB9IGZyb20gJy4vb3BzL3NwbGl0JztcbmltcG9ydCB7IHBhcnNlU3F1ZWV6ZUF0dHJpYnV0ZXMsIHNxdWVlemUsIHNxdWVlemVWMTMgfSBmcm9tICcuL29wcy9zcXVlZXplJztcbmltcG9ydCB7IHN1bSB9IGZyb20gJy4vb3BzL3N1bSc7XG5pbXBvcnQgeyB0aWxlIH0gZnJvbSAnLi9vcHMvdGlsZSc7XG5pbXBvcnQgeyBwYXJzZVRyYW5zcG9zZUF0dHJpYnV0ZXMsIHRyYW5zcG9zZSB9IGZyb20gJy4vb3BzL3RyYW5zcG9zZSc7XG5pbXBvcnQgKiBhcyB1bmFyeU9wcyBmcm9tICcuL29wcy91bmFyeS1vcCc7XG5pbXBvcnQgeyBwYXJzZVVuc3F1ZWV6ZUF0dHJpYnV0ZXMsIHVuc3F1ZWV6ZSwgdW5zcXVlZXplVjEzIH0gZnJvbSAnLi9vcHMvdW5zcXVlZXplJztcbmltcG9ydCB7IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjcsIHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjksIHVwc2FtcGxlIH0gZnJvbSAnLi9vcHMvdXBzYW1wbGUnO1xuXG5leHBvcnQgY29uc3QgV0VCR0xfT1BfUkVTT0xWRV9SVUxFUzogcmVhZG9ubHkgT3BTZXQuUmVzb2x2ZVJ1bGVbXSA9IFtcbiAgWydBYnMnLCAnJywgJzYrJywgdW5hcnlPcHMuYWJzXSxcbiAgWydBY29zJywgJycsICc3KycsIHVuYXJ5T3BzLmFjb3NdLFxuICBbJ0FkZCcsICcnLCAnNysnLCBiaW5hcnlPcHMuYWRkXSxcbiAgWydBbmQnLCAnJywgJzcrJywgYmluYXJ5T3BzLmFuZF0sXG4gIFsnQXNpbicsICcnLCAnNysnLCB1bmFyeU9wcy5hc2luXSxcbiAgWydBdGFuJywgJycsICc3KycsIHVuYXJ5T3BzLmF0YW5dLFxuICAvLyBUT0RPOiBzdXBwb3J0IG5ldyBhdHRyaWJ1dGVzIGZvciBBdmVyYWdlUG9vbC0xMFxuICBbJ0F2ZXJhZ2VQb29sJywgJycsICc3KycsIGF2ZXJhZ2VQb29sLCBwYXJzZUF2ZXJhZ2VQb29sQXR0cmlidXRlc10sXG4gIFsnQmF0Y2hOb3JtYWxpemF0aW9uJywgJycsICc3KycsIGJhdGNoTm9ybWFsaXphdGlvbiwgcGFyc2VCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzXSxcbiAgWydDYXN0JywgJycsICc2KycsIGNhc3QsIHBhcnNlQ2FzdEF0dHJpYnV0ZXNdLFxuICBbJ0NlaWwnLCAnJywgJzYrJywgdW5hcnlPcHMuY2VpbF0sXG4gIFsnQ2xpcCcsICcnLCAnNi0xMCcsIHVuYXJ5T3BzLmNsaXAsIHVuYXJ5T3BzLnBhcnNlQ2xpcEF0dHJpYnV0ZXNdLFxuICBbJ0NsaXAnLCAnJywgJzExKycsIHVuYXJ5T3BzLmNsaXBWMTFdLFxuICBbJ0NvbmNhdCcsICcnLCAnNCsnLCBjb25jYXQsIHBhcnNlQ29uY2F0QXR0cmlidXRlc10sXG4gIFsnQ29udicsICcnLCAnMSsnLCBjb252LCBwYXJzZUNvbnZBdHRyaWJ1dGVzXSxcbiAgWydDb252VHJhbnNwb3NlJywgJycsICcxKycsIGNvbnZUcmFuc3Bvc2UsIHBhcnNlQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXNdLFxuICBbJ0NvcycsICcnLCAnNysnLCB1bmFyeU9wcy5jb3NdLFxuICBbJ0RpdicsICcnLCAnNysnLCBiaW5hcnlPcHMuZGl2XSxcbiAgWydEcm9wb3V0JywgJycsICc3KycsIHVuYXJ5T3BzLmlkZW50aXR5XSxcbiAgWydEZXB0aFRvU3BhY2UnLCAnJywgJzErJywgZGVwdGhUb1NwYWNlLCBwYXJzZURlcHRoVG9TcGFjZUF0dHJpYnV0ZXNdLFxuICBbJ0VxdWFsJywgJycsICc3KycsIGJpbmFyeU9wcy5lcXVhbF0sXG4gIFsnRWx1JywgJycsICc2KycsIHVuYXJ5T3BzLmVsdSwgdW5hcnlPcHMucGFyc2VFbHVBdHRyaWJ1dGVzXSxcbiAgWydFeHAnLCAnJywgJzYrJywgdW5hcnlPcHMuZXhwXSxcbiAgWydGbGF0dGVuJywgJycsICcxKycsIGZsYXR0ZW4sIHBhcnNlRmxhdHRlbkF0dHJpYnV0ZXNdLFxuICBbJ0Zsb29yJywgJycsICc2KycsIHVuYXJ5T3BzLmZsb29yXSxcbiAgWydGdXNlZENvbnYnLCAnY29tLm1pY3Jvc29mdCcsICcxKycsIGNvbnYsIHBhcnNlQ29udkF0dHJpYnV0ZXNdLFxuICBbJ0dhdGhlcicsICcnLCAnMSsnLCBnYXRoZXIsIHBhcnNlR2F0aGVyQXR0cmlidXRlc10sXG4gIFsnR2VtbScsICcnLCAnNy0xMCcsIGdlbW0sIHBhcnNlR2VtbUF0dHJpYnV0ZXNWN10sXG4gIFsnR2VtbScsICcnLCAnMTErJywgZ2VtbSwgcGFyc2VHZW1tQXR0cmlidXRlc1YxMV0sXG4gIFsnR2xvYmFsQXZlcmFnZVBvb2wnLCAnJywgJzErJywgZ2xvYmFsQXZlcmFnZVBvb2wsIHBhcnNlR2xvYmFsQXZlcmFnZVBvb2xBdHRyaWJ1dGVzXSxcbiAgWydHbG9iYWxNYXhQb29sJywgJycsICcxKycsIGdsb2JhbE1heFBvb2xdLFxuICBbJ0dyZWF0ZXInLCAnJywgJzcrJywgYmluYXJ5T3BzLmdyZWF0ZXJdLFxuICBbJ0lkZW50aXR5JywgJycsICcxKycsIHVuYXJ5T3BzLmlkZW50aXR5XSxcbiAgWydJbWFnZVNjYWxlcicsICcnLCAnMSsnLCBpbWFnZVNjYWxlciwgcGFyc2VJbWFnZVNjYWxlckF0dHJpYnV0ZXNdLFxuICBbJ0luc3RhbmNlTm9ybWFsaXphdGlvbicsICcnLCAnNisnLCBpbnN0YW5jZU5vcm1hbGl6YXRpb24sIHBhcnNlSW5zdGFuY2VOb3JtYWxpemF0aW9uQXR0cmlidXRlc10sXG4gIFsnTGVha3lSZWx1JywgJycsICc2KycsIHVuYXJ5T3BzLmxlYWt5UmVsdSwgdW5hcnlPcHMucGFyc2VMZWFreVJlbHVBdHRyaWJ1dGVzXSxcbiAgWydMZXNzJywgJycsICc3KycsIGJpbmFyeU9wcy5sZXNzXSxcbiAgWydMUk4nLCAnJywgJzErJywgbHJuLCBwYXJzZUxybkF0dHJpYnV0ZXNdLFxuICBbJ0xvZycsICcnLCAnNisnLCB1bmFyeU9wcy5sb2ddLFxuICBbJ01hdE11bCcsICcnLCAnMSsnLCBtYXRNdWwsIHBhcnNlTWF0TXVsQXR0cmlidXRlc10sXG4gIC8vIFRPRE86IHN1cHBvcnQgbmV3IGF0dHJpYnV0ZXMgZm9yIE1heFBvb2wtOCBhbmQgTWF4UG9vbC0xMFxuICBbJ01heFBvb2wnLCAnJywgJzErJywgbWF4UG9vbCwgcGFyc2VNYXhQb29sQXR0cmlidXRlc10sXG4gIFsnTXVsJywgJycsICc3KycsIGJpbmFyeU9wcy5tdWxdLFxuICBbJ05lZycsICcnLCAnNisnLCB1bmFyeU9wcy5uZWddLFxuICBbJ05vdCcsICcnLCAnMSsnLCB1bmFyeU9wcy5ub3RdLFxuICBbJ09yJywgJycsICc3KycsIGJpbmFyeU9wcy5vcl0sXG4gIFsnUGFkJywgJycsICcyLTEwJywgcGFkVjIsIHBhcnNlUGFkQXR0cmlidXRlc1YyXSxcbiAgWydQYWQnLCAnJywgJzExKycsIHBhZFYxMSwgcGFyc2VQYWRBdHRyaWJ1dGVzVjExXSxcbiAgWydQb3cnLCAnJywgJzcrJywgYmluYXJ5T3BzLnBvd10sXG4gIFsnUFJlbHUnLCAnJywgJzcrJywgYmluYXJ5T3BzLnBSZWx1XSxcbiAgWydSZWR1Y2VMb2dTdW0nLCAnJywgJzErJywgcmVkdWNlTG9nU3VtLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZU1heCcsICcnLCAnMSsnLCByZWR1Y2VNYXgsIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlTWVhbicsICcnLCAnMSsnLCByZWR1Y2VNZWFuLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZU1pbicsICcnLCAnMSsnLCByZWR1Y2VNaW4sIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlUHJvZCcsICcnLCAnMSsnLCByZWR1Y2VQcm9kLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZVN1bScsICcnLCAnMS0xMicsIHJlZHVjZVN1bSwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWR1Y2VTdW1TcXVhcmUnLCAnJywgJzErJywgcmVkdWNlTG9nU3VtU3F1YXJlLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlbHUnLCAnJywgJzYrJywgdW5hcnlPcHMucmVsdV0sXG4gIFsnUmVzaGFwZScsICcnLCAnNSsnLCByZXNoYXBlXSxcbiAgWydSZXNpemUnLCAnJywgJzEwJywgcmVzaXplLCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTBdLFxuICBbJ1Jlc2l6ZScsICcnLCAnMTErJywgcmVzaXplLCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTFdLFxuICBbJ1NoYXBlJywgJycsICcxKycsIHNoYXBlXSxcbiAgWydTaWdtb2lkJywgJycsICc2KycsIHVuYXJ5T3BzLnNpZ21vaWRdLFxuICBbJ1NpbicsICcnLCAnNysnLCB1bmFyeU9wcy5zaW5dLFxuICBbJ1NsaWNlJywgJycsICcxMCsnLCBzbGljZVYxMF0sIC8vIFRPRE86IHN1cHBvcnQgJ3N0ZXBzJyBmb3IgU2xpY2UtMTBcbiAgWydTbGljZScsICcnLCAnMS05Jywgc2xpY2UsIHBhcnNlU2xpY2VBdHRyaWJ1dGVzXSxcbiAgLy8gVGhlIFwic2VtYW50aWNcIiBtZWFuaW5nIG9mIGF4aXMgaGFzIGNoYW5nZWQgaW4gb3BzZXQtMTMuXG4gIFsnU29mdG1heCcsICcnLCAnMS0xMicsIHNvZnRtYXgsIHBhcnNlU29mdG1heEF0dHJpYnV0ZXNdLFxuICBbJ1NvZnRtYXgnLCAnJywgJzEzKycsIHNvZnRtYXhWMTMsIHBhcnNlU29mdG1heEF0dHJpYnV0ZXNWMTNdLFxuICAvLyAnU3BsaXQnIG9wZXJhdG9yIGhhcyBhbiBvcHRpb25hbCBhdHRyaWJ1dGUgJ3NwbGl0J1xuICAvLyB0aGlzIGF0dHJpYnV0ZSBkZXRlcm1pbmVzIGhvdyB0aGUgc3BlY2lmaWVkIGF4aXMgb2YgaW5wdXQgZGF0YSBpcyBzcGxpdC5cbiAgLy8gV2hlbiB0aGUgYXR0cmlidXRlIGlzIG1pc3NpbmcsIHdlIG5lZWQgdGhlIGNvdW50IG9mIG51bWJlciBvZiBvdXRwdXRzXG4gIC8vIHNvIHRoYXQgd2UgY2FuIGRldGVybWluZSB0aGUgJ3NwbGl0JyBhdHRyaWJ1dGUgZnJvbSB0aGUgcnVudGltZSBpbnB1dCB0byB0aGUgT3BlcmF0b3JcbiAgWydTcGxpdCcsICcnLCAnMi0xMicsIHNwbGl0LCBwYXJzZVNwbGl0QXR0cmlidXRlc10sXG4gIFsnU3FydCcsICcnLCAnNisnLCB1bmFyeU9wcy5zcXJ0XSxcbiAgWydTcXVlZXplJywgJycsICcxLTEyJywgc3F1ZWV6ZSwgcGFyc2VTcXVlZXplQXR0cmlidXRlc10sXG4gIFsnU3F1ZWV6ZScsICcnLCAnMTMrJywgc3F1ZWV6ZVYxM10sXG4gIFsnU3ViJywgJycsICc3KycsIGJpbmFyeU9wcy5zdWJdLFxuICBbJ1N1bScsICcnLCAnNisnLCBzdW1dLFxuICBbJ1RhbicsICcnLCAnNysnLCB1bmFyeU9wcy50YW5dLFxuICBbJ1RhbmgnLCAnJywgJzYrJywgdW5hcnlPcHMudGFuaF0sXG4gIFsnVGlsZScsICcnLCAnNisnLCB0aWxlXSxcbiAgWydUcmFuc3Bvc2UnLCAnJywgJzErJywgdHJhbnNwb3NlLCBwYXJzZVRyYW5zcG9zZUF0dHJpYnV0ZXNdLFxuICBbJ1Vwc2FtcGxlJywgJycsICc3LTgnLCB1cHNhbXBsZSwgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXNWN10sXG4gIFsnVXBzYW1wbGUnLCAnJywgJzknLCB1cHNhbXBsZSwgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXNWOV0sXG4gIFsnVW5zcXVlZXplJywgJycsICcxLTEyJywgdW5zcXVlZXplLCBwYXJzZVVuc3F1ZWV6ZUF0dHJpYnV0ZXNdLFxuICBbJ1Vuc3F1ZWV6ZScsICcnLCAnMTMrJywgdW5zcXVlZXplVjEzXSxcbiAgWydYb3InLCAnJywgJzcrJywgYmluYXJ5T3BzLnhvcl0sXG5dO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5jb25zdCBJTkxJTkVfRlVOQ19ERUZfUkVHRVggPSAvQGlubGluZVtcXHNcXG5cXHJdKyhcXHcrKVtcXHNcXG5cXHJdKyhbMC05YS16QS1aX10rKVxccypcXCgoW14pXSopXFwpXFxzKnsoKFtefV18W1xcblxccl0pKil9L2dtO1xuY29uc3QgRlVOQ19DQUxMX1JFR0VYID0gJyhcXFxcdyspP1xcXFxzKyhbXzAtOWEtekEtWl0rKVxcXFxzKz1cXFxccytfX0ZVTkNfX1xcXFwoKC4qKVxcXFwpXFxcXHMqOyc7XG4vKipcbiAqIEdMU0wgcHJlcHJvY2Vzc29yIHJlc3BvbnNpYmxlIGZvciByZXNvbHZpbmcgQGlubGluZSBkaXJlY3RpdmVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXBsYWNlSW5saW5lcyhzY3JpcHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGlubGluZURlZnM6IHsgW25hbWU6IHN0cmluZ106IHsgcGFyYW1zOiBBcnJheTx7IHR5cGU6IHN0cmluZzsgbmFtZTogc3RyaW5nIH0gfCBudWxsPjsgYm9keTogc3RyaW5nIH0gfSA9IHt9O1xuICBsZXQgbWF0Y2g7XG4gIHdoaWxlICgobWF0Y2ggPSBJTkxJTkVfRlVOQ19ERUZfUkVHRVguZXhlYyhzY3JpcHQpKSAhPT0gbnVsbCkge1xuICAgIGNvbnN0IHBhcmFtcyA9IG1hdGNoWzNdXG4gICAgICAuc3BsaXQoJywnKVxuICAgICAgLm1hcCgocykgPT4ge1xuICAgICAgICBjb25zdCB0b2tlbnMgPSBzLnRyaW0oKS5zcGxpdCgnICcpO1xuICAgICAgICBpZiAodG9rZW5zICYmIHRva2Vucy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICByZXR1cm4geyB0eXBlOiB0b2tlbnNbMF0sIG5hbWU6IHRva2Vuc1sxXSB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoKHYpID0+IHYgIT09IG51bGwpO1xuICAgIGlubGluZURlZnNbbWF0Y2hbMl1dID0geyBwYXJhbXMsIGJvZHk6IG1hdGNoWzRdIH07XG4gIH1cbiAgZm9yIChjb25zdCBuYW1lIGluIGlubGluZURlZnMpIHtcbiAgICBjb25zdCByZWdleFN0cmluZyA9IEZVTkNfQ0FMTF9SRUdFWC5yZXBsYWNlKCdfX0ZVTkNfXycsIG5hbWUpO1xuICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChyZWdleFN0cmluZywgJ2dtJyk7XG4gICAgd2hpbGUgKChtYXRjaCA9IHJlZ2V4LmV4ZWMoc2NyaXB0KSkgIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IHR5cGUgPSBtYXRjaFsxXTtcbiAgICAgIGNvbnN0IHZhcmlhYmxlID0gbWF0Y2hbMl07XG4gICAgICBjb25zdCBwYXJhbXMgPSBtYXRjaFszXS5zcGxpdCgnLCcpO1xuICAgICAgY29uc3QgZGVjbExpbmUgPSB0eXBlID8gYCR7dHlwZX0gJHt2YXJpYWJsZX07YCA6ICcnO1xuICAgICAgbGV0IG5ld0JvZHk6IHN0cmluZyA9IGlubGluZURlZnNbbmFtZV0uYm9keTtcbiAgICAgIGxldCBwYXJhbVJlZGVjTGluZSA9ICcnO1xuICAgICAgaW5saW5lRGVmc1tuYW1lXS5wYXJhbXMuZm9yRWFjaCgodiwgaSkgPT4ge1xuICAgICAgICBpZiAodikge1xuICAgICAgICAgIHBhcmFtUmVkZWNMaW5lICs9IGAke3YudHlwZX0gJHt2Lm5hbWV9ID0gJHtwYXJhbXNbaV19O1xcbmA7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgbmV3Qm9keSA9IGAke3BhcmFtUmVkZWNMaW5lfVxcbiAke25ld0JvZHl9YDtcbiAgICAgIG5ld0JvZHkgPSBuZXdCb2R5LnJlcGxhY2UoJ3JldHVybicsIGAke3ZhcmlhYmxlfSA9IGApO1xuICAgICAgY29uc3QgcmVwbGFjZW1lbnQgPSBgXG4gICAgICAke2RlY2xMaW5lfVxuICAgICAge1xuICAgICAgICAke25ld0JvZHl9XG4gICAgICB9XG4gICAgICBgO1xuICAgICAgc2NyaXB0ID0gc2NyaXB0LnJlcGxhY2UobWF0Y2hbMF0sIHJlcGxhY2VtZW50KTtcbiAgICB9XG4gIH1cbiAgc2NyaXB0ID0gc2NyaXB0LnJlcGxhY2UoSU5MSU5FX0ZVTkNfREVGX1JFR0VYLCAnJyk7XG4gIHJldHVybiBzY3JpcHQ7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJy4uLy4uL2luc3RydW1lbnQnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbi8qKiBMYXlvdXQgcHJlZmVyZW5jZXMgKi9cbmV4cG9ydCBpbnRlcmZhY2UgV2lkdGhIZWlnaHRQcmVmcyB7XG4gIGJyZWFrQXhpcz86IG51bWJlcjtcbiAgaXNQYWNrZWQ/OiBib29sZWFuO1xuICByZXZlcnNlV0g/OiBib29sZWFuO1xufVxuLyoqXG4gKiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kgaXMgYW4gYWJzdHJhY3Rpb24gZm9yIGRpZmZlcmVudCBwbGFuc1xuICogZm9yIG1hcHBpbmcgbi1kaW1lbnNpb25hbCBhcnJheXMgdG8gMkQgdGV4dHVyZXMgKGFuZCBiYWNrKVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRleHR1cmVMYXlvdXRTdHJhdGVneSB7XG4gIGNvbXB1dGVUZXh0dXJlV0goc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwcmVmcz86IFdpZHRoSGVpZ2h0UHJlZnMpOiBbbnVtYmVyLCBudW1iZXJdO1xufVxuXG4vKipcbiAqIFRoaXMgc3RyYXRlZ3kgdHJ5IHRvIGZpbmQgdGhlIG1pbmltYWwgbWF4KFcsSCkgdGhhdCBmdWxmaWxscyAoVyAqIEggPT0gdG90YWxTaXplKVxuICovXG5leHBvcnQgY2xhc3MgQWx3YXlzS2VlcE9yaWdpbmFsU2l6ZVN0cmF0ZWd5IGltcGxlbWVudHMgVGV4dHVyZUxheW91dFN0cmF0ZWd5IHtcbiAgY29uc3RydWN0b3IocHVibGljIG1heFRleHR1cmVTaXplOiBudW1iZXIpIHt9XG4gIGNvbXB1dGVUZXh0dXJlV0goc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwcmVmcz86IFdpZHRoSGVpZ2h0UHJlZnMpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICAvLyBzY2FsYXIgdGVuc29yXG4gICAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFsxLCAxXTtcbiAgICB9XG4gICAgY29uc3QgbWF4VGV4dHVyZVNpemUgPSB0aGlzLm1heFRleHR1cmVTaXplO1xuICAgIGlmIChwcmVmcyAmJiBwcmVmcy5icmVha0F4aXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gY2hlY2sgdG8gc2VlIGlmIGRpbXMgZml0XG4gICAgICBjb25zdCB3c2l6ZSA9IHByZWZzLmJyZWFrQXhpcyA+PSBzaGFwZS5sZW5ndGggPyAxIDogc2hhcGUuc2xpY2UocHJlZnMuYnJlYWtBeGlzKS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcbiAgICAgIGNvbnN0IGhzaXplID0gcHJlZnMuYnJlYWtBeGlzIDw9IDAgPyAxIDogc2hhcGUuc2xpY2UoMCwgcHJlZnMuYnJlYWtBeGlzKS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcbiAgICAgIGlmICh3c2l6ZSA+IG1heFRleHR1cmVTaXplIHx8IGhzaXplID4gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgICAgLy8gaWdub3JlIHByZWZlcmVuY2VzXG4gICAgICAgIC8vIGNvbnRpbnVlIHdpdGggZGVmYXVsdCBsYXlvdXRcbiAgICAgICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICAgJ1RleHR1cmVMYXlvdXQnLFxuICAgICAgICAgIGBHaXZlbiB3aWR0aC9oZWlnaHQgcHJlZmVyZW5jZXMgd2VyZSB1bmF0dGFpbmFibGU6IHNoYXBlOiR7c2hhcGV9LCBicmVha0F4aXM6JHtwcmVmcy5icmVha0F4aXN9YCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbd3NpemUsIGhzaXplXTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgdG90YWxTaXplID0gc2hhcGUucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG5cbiAgICBsZXQgd2lkdGggPSBNYXRoLmZsb29yKE1hdGguc3FydCh0b3RhbFNpemUpKTtcblxuICAgIGZvciAoOyB3aWR0aCA8IG1heFRleHR1cmVTaXplICYmIHdpZHRoIDwgdG90YWxTaXplOyB3aWR0aCsrKSB7XG4gICAgICBpZiAodG90YWxTaXplICUgd2lkdGggPT09IDApIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHdpZHRoID49IG1heFRleHR1cmVTaXplIHx8IHRvdGFsU2l6ZSAlIHdpZHRoICE9PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBnaXZlbiBkaW1lbnNpb25zIGFyZSBvdXRzaWRlIHRoaXMgR1BVJ3MgYm91bmRhcmllczogJHtzaGFwZX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIFt3aWR0aCwgdG90YWxTaXplIC8gd2lkdGhdO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQcmVmZXJMb2dpY2FsU3RyYXRlZ3kgaW1wbGVtZW50cyBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgbWF4VGV4dHVyZVNpemU6IG51bWJlcikge31cbiAgY29tcHV0ZVRleHR1cmVXSChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHByZWZzPzogV2lkdGhIZWlnaHRQcmVmcyk6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIGNvbnN0IHdoID0gdGhpcy5jb21wdXRlVGV4dHVyZShzaGFwZSwgcHJlZnMpO1xuICAgIGlmIChwcmVmcyAmJiBwcmVmcy5pc1BhY2tlZCkge1xuICAgICAgd2hbMF0gLz0gMjtcbiAgICAgIHdoWzFdIC89IDI7XG4gICAgfVxuICAgIGlmIChwcmVmcyAmJiBwcmVmcy5yZXZlcnNlV0gpIHtcbiAgICAgIHJldHVybiBbd2hbMV0sIHdoWzBdXTtcbiAgICB9XG4gICAgcmV0dXJuIHdoO1xuICB9XG5cbiAgY29tcHV0ZVRleHR1cmUoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwcmVmcz86IFdpZHRoSGVpZ2h0UHJlZnMpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICBjb25zdCBpc1BhY2tlZCA9IHByZWZzICYmIHByZWZzLmlzUGFja2VkO1xuICAgIC8vIHNjYWxhciB0ZW5zb3JcbiAgICBpZiAoc2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gaXNQYWNrZWQgPyBbMiwgMl0gOiBbMSwgMV07XG4gICAgfVxuICAgIGxldCBtYXhUZXh0dXJlU2l6ZSA9IHRoaXMubWF4VGV4dHVyZVNpemU7XG4gICAgaWYgKHByZWZzICYmIHByZWZzLmJyZWFrQXhpcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBjaGVjayB0byBzZWUgaWYgZGltcyBmaXRcbiAgICAgIGNvbnN0IHdzaXplID0gcHJlZnMuYnJlYWtBeGlzID49IHNoYXBlLmxlbmd0aCA/IDEgOiBzaGFwZS5zbGljZShwcmVmcy5icmVha0F4aXMpLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuICAgICAgY29uc3QgaHNpemUgPSBwcmVmcy5icmVha0F4aXMgPD0gMCA/IDEgOiBzaGFwZS5zbGljZSgwLCBwcmVmcy5icmVha0F4aXMpLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuICAgICAgaWYgKHdzaXplID4gbWF4VGV4dHVyZVNpemUgfHwgaHNpemUgPiBtYXhUZXh0dXJlU2l6ZSkge1xuICAgICAgICAvLyBpZ25vcmUgcHJlZmVyZW5jZXNcbiAgICAgICAgLy8gY29udGludWUgd2l0aCBkZWZhdWx0IGxheW91dFxuICAgICAgICBMb2dnZXIudmVyYm9zZShcbiAgICAgICAgICAnVGV4dHVyZUxheW91dCcsXG4gICAgICAgICAgYEdpdmVuIHdpZHRoL2hlaWdodCBwcmVmZXJlbmNlcyB3ZXJlIHVuYXR0YWluYWJsZTogc2hhcGU6JHtzaGFwZX0sIGJyZWFrQXhpczoke3ByZWZzLmJyZWFrQXhpc31gLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFt3c2l6ZSwgaHNpemVdO1xuICAgICAgfVxuICAgIH1cbiAgICBsZXQgbG9nU2hhcGUgPSBzaGFwZS5zbGljZSgwKTtcbiAgICBpZiAoaXNQYWNrZWQpIHtcbiAgICAgIG1heFRleHR1cmVTaXplID0gbWF4VGV4dHVyZVNpemUgKiAyO1xuXG4gICAgICAvLyBUaGlzIGxvZ2ljIGVuc3VyZXMgd2UgYWNjdXJhdGVseSBjb3VudCB0aGUgbnVtYmVyIG9mIHBhY2tlZCB0ZXhlbHMgbmVlZGVkXG4gICAgICAvLyB0byBhY2NvbW1vZGF0ZSB0aGUgdGVuc29yLiBXZSBjYW4gb25seSBwYWNrIHZhbHVlcyBpbiB0aGUgc2FtZSB0ZXhlbCBpZlxuICAgICAgLy8gdGhleSBhcmUgZnJvbSBhZGphY2VudCBwYWlycyBvZiByb3dzL2NvbHMgd2l0aGluIHRoZSBzYW1lIGJhdGNoLiBTbyBpZiBhXG4gICAgICAvLyB0ZW5zb3IgaGFzIDMgcm93cywgd2UgcHJldGVuZCBpdCBoYXMgNCByb3dzIGluIG9yZGVyIHRvIGFjY291bnQgZm9yIHRoZVxuICAgICAgLy8gZmFjdCB0aGF0IHRoZSB0ZXhlbHMgY29udGFpbmluZyB0aGUgdGhpcmQgcm93IGFyZSBoYWxmIGVtcHR5LlxuICAgICAgbG9nU2hhcGUgPSBsb2dTaGFwZS5tYXAoKF9kLCBpKSA9PlxuICAgICAgICBpID49IGxvZ1NoYXBlLmxlbmd0aCAtIDIgPyAobG9nU2hhcGVbaV0gJSAyID09PSAwID8gbG9nU2hhcGVbaV0gOiBsb2dTaGFwZVtpXSArIDEpIDogbG9nU2hhcGVbaV0sXG4gICAgICApO1xuXG4gICAgICAvLyBQYWNrZWQgdGV4dHVyZSBoZWlnaHQgaXMgYXQgbGVhc3QgMiAodGhlIGNoYW5uZWwgaGVpZ2h0IG9mIGEgc2luZ2xlXG4gICAgICAvLyB0ZXhlbCkuXG4gICAgICBpZiAobG9nU2hhcGUubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGxvZ1NoYXBlID0gWzIsIGxvZ1NoYXBlWzBdXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiBsb2dpY2FsIHNoYXBlIGlzIDIsIHdlIGRvbid0IHNxdWVlemUsIHNpbmNlIHdlIHdhbnQgdG8gbWF0Y2ggcGh5c2ljYWwuXG4gICAgaWYgKGxvZ1NoYXBlLmxlbmd0aCAhPT0gMikge1xuICAgICAgY29uc3Qgc3F1ZWV6ZVJlc3VsdCA9IHNxdWVlemVTaGFwZShsb2dTaGFwZSk7XG4gICAgICBsb2dTaGFwZSA9IHNxdWVlemVSZXN1bHQubmV3U2hhcGU7XG4gICAgfVxuXG4gICAgY29uc3Qgc2l6ZSA9IHNpemVGcm9tU2hhcGUobG9nU2hhcGUpO1xuICAgIGlmIChsb2dTaGFwZS5sZW5ndGggPD0gMSAmJiBzaXplIDw9IG1heFRleHR1cmVTaXplKSB7XG4gICAgICByZXR1cm4gWzEsIHNpemVdO1xuICAgIH0gZWxzZSBpZiAobG9nU2hhcGUubGVuZ3RoID09PSAyICYmIGxvZ1NoYXBlWzBdIDw9IG1heFRleHR1cmVTaXplICYmIGxvZ1NoYXBlWzFdIDw9IG1heFRleHR1cmVTaXplKSB7XG4gICAgICByZXR1cm4gbG9nU2hhcGUgYXMgW251bWJlciwgbnVtYmVyXTtcbiAgICB9IGVsc2UgaWYgKGxvZ1NoYXBlLmxlbmd0aCA9PT0gMyAmJiBsb2dTaGFwZVswXSAqIGxvZ1NoYXBlWzFdIDw9IG1heFRleHR1cmVTaXplICYmIGxvZ1NoYXBlWzJdIDw9IG1heFRleHR1cmVTaXplKSB7XG4gICAgICByZXR1cm4gW2xvZ1NoYXBlWzBdICogbG9nU2hhcGVbMV0sIGxvZ1NoYXBlWzJdXTtcbiAgICB9IGVsc2UgaWYgKGxvZ1NoYXBlLmxlbmd0aCA9PT0gMyAmJiBsb2dTaGFwZVswXSA8PSBtYXhUZXh0dXJlU2l6ZSAmJiBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdIDw9IG1heFRleHR1cmVTaXplKSB7XG4gICAgICByZXR1cm4gW2xvZ1NoYXBlWzBdLCBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdXTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgbG9nU2hhcGUubGVuZ3RoID09PSA0ICYmXG4gICAgICBsb2dTaGFwZVswXSAqIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl0gPD0gbWF4VGV4dHVyZVNpemUgJiZcbiAgICAgIGxvZ1NoYXBlWzNdIDw9IG1heFRleHR1cmVTaXplXG4gICAgKSB7XG4gICAgICByZXR1cm4gW2xvZ1NoYXBlWzBdICogbG9nU2hhcGVbMV0gKiBsb2dTaGFwZVsyXSwgbG9nU2hhcGVbM11dO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBsb2dTaGFwZS5sZW5ndGggPT09IDQgJiZcbiAgICAgIGxvZ1NoYXBlWzBdIDw9IG1heFRleHR1cmVTaXplICYmXG4gICAgICBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdICogbG9nU2hhcGVbM10gPD0gbWF4VGV4dHVyZVNpemVcbiAgICApIHtcbiAgICAgIHJldHVybiBbbG9nU2hhcGVbMF0sIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl0gKiBsb2dTaGFwZVszXV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpc1BhY2tlZCkge1xuICAgICAgICAvLyBGb3IgcGFja2VkIHRleHR1cmVzIHNpemUgZXF1YWxzIHRoZSBudW1iZXIgb2YgY2hhbm5lbHMgcmVxdWlyZWQgdG9cbiAgICAgICAgLy8gYWNjb21tb2RhdGUgdGhlIHRleHR1cmUgZGF0YS4gSG93ZXZlciBpbiBvcmRlciB0byBzcXVhcmlmeSBzdWNoIHRoYXRcbiAgICAgICAgLy8gaW5uZXIgZGltZW5zaW9ucyBzdGF5IGV2ZW4sIHdlIHJld3JpdGUgc2l6ZSB0byBlcXVhbCB0aGUgbnVtYmVyIG9mXG4gICAgICAgIC8vIHRleGVscy4gVGhlbiBpbiB0aGUgcmV0dXJuIHN0YXRlbWVudCB3ZSByZWh5ZHJhdGUgdGhlIHNxdWFyaWZpZWRcbiAgICAgICAgLy8gZGltZW5zaW9ucyB0byBjaGFubmVsIHVuaXRzLlxuICAgICAgICByZXR1cm4gc2l6ZVRvU3F1YXJpc2hTaGFwZShzaXplIC8gNCkubWFwKChkKSA9PiBkICogMikgYXMgW251bWJlciwgbnVtYmVyXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzaXplVG9TcXVhcmlzaFNoYXBlKHNpemUpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc3F1ZWV6ZVNoYXBlKHNoYXBlOiBudW1iZXJbXSwgYXhpcz86IG51bWJlcltdKTogeyBuZXdTaGFwZTogbnVtYmVyW107IGtlcHREaW1zOiBudW1iZXJbXSB9IHtcbiAgY29uc3QgbmV3U2hhcGU6IG51bWJlcltdID0gW107XG4gIGNvbnN0IGtlcHREaW1zOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBpc0VtcHR5QXJyYXkgPSBheGlzICE9IG51bGwgJiYgQXJyYXkuaXNBcnJheShheGlzKSAmJiBheGlzLmxlbmd0aCA9PT0gMDtcbiAgY29uc3QgYXhlcyA9IGF4aXMgPT0gbnVsbCB8fCBpc0VtcHR5QXJyYXkgPyBudWxsIDogcGFyc2VBeGlzUGFyYW0oYXhpcywgc2hhcGUpLnNvcnQoKTtcbiAgbGV0IGogPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHNoYXBlLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGF4ZXMgIT0gbnVsbCkge1xuICAgICAgaWYgKGF4ZXNbal0gPT09IGkgJiYgc2hhcGVbaV0gIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW4ndCBzcXVlZXplIGF4aXMgJHtpfSBzaW5jZSBpdHMgZGltICcke3NoYXBlW2ldfScgaXMgbm90IDFgKTtcbiAgICAgIH1cbiAgICAgIGlmICgoYXhlc1tqXSA9PSBudWxsIHx8IGF4ZXNbal0gPiBpKSAmJiBzaGFwZVtpXSA9PT0gMSkge1xuICAgICAgICBuZXdTaGFwZS5wdXNoKHNoYXBlW2ldKTtcbiAgICAgICAga2VwdERpbXMucHVzaChpKTtcbiAgICAgIH1cbiAgICAgIGlmIChheGVzW2pdIDw9IGkpIHtcbiAgICAgICAgaisrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc2hhcGVbaV0gIT09IDEpIHtcbiAgICAgIG5ld1NoYXBlLnB1c2goc2hhcGVbaV0pO1xuICAgICAga2VwdERpbXMucHVzaChpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHsgbmV3U2hhcGUsIGtlcHREaW1zIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUF4aXNQYXJhbShheGlzOiBudW1iZXIgfCBudW1iZXJbXSwgc2hhcGU6IG51bWJlcltdKTogbnVtYmVyW10ge1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gIC8vIE5vcm1hbGl6ZSBpbnB1dFxuICBheGlzID0gYXhpcyA9PSBudWxsID8gc2hhcGUubWFwKChfcywgaSkgPT4gaSkgOiAoW10gYXMgbnVtYmVyW10pLmNvbmNhdChheGlzKTtcblxuICAvLyBDaGVjayBmb3IgdmFsaWQgcmFuZ2VcbiAgYXNzZXJ0KFxuICAgIGF4aXMuZXZlcnkoKGF4KSA9PiBheCA+PSAtcmFuayAmJiBheCA8IHJhbmspLFxuICAgICgpID0+IGBBbGwgdmFsdWVzIGluIGF4aXMgcGFyYW0gbXVzdCBiZSBpbiByYW5nZSBbLSR7cmFua30sICR7cmFua30pIGJ1dCBgICsgYGdvdCBheGlzICR7YXhpc31gLFxuICApO1xuXG4gIC8vIENoZWNrIGZvciBvbmx5IGludGVnZXJzXG4gIGFzc2VydChheGlzLmV2ZXJ5KGlzSW50KSwgKCkgPT4gJ0FsbCB2YWx1ZXMgaW4gYXhpcyBwYXJhbSBtdXN0IGJlIGludGVnZXJzIGJ1dCAnICsgYGdvdCBheGlzICR7YXhpc31gKTtcblxuICAvLyBIYW5kbGUgbmVnYXRpdmUgYXhpcy5cbiAgcmV0dXJuIGF4aXMubWFwKChhKSA9PiAoYSA8IDAgPyByYW5rICsgYSA6IGEpKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBpc0ludChhOiBudW1iZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIGEgJSAxID09PSAwO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHNpemVGcm9tU2hhcGUoc2hhcGU6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIFNjYWxhci5cbiAgICByZXR1cm4gMTtcbiAgfVxuICBsZXQgc2l6ZSA9IHNoYXBlWzBdO1xuICBmb3IgKGxldCBpID0gMTsgaSA8IHNoYXBlLmxlbmd0aDsgaSsrKSB7XG4gICAgc2l6ZSAqPSBzaGFwZVtpXTtcbiAgfVxuICByZXR1cm4gc2l6ZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRSb3dzQ29scyhzaGFwZTogbnVtYmVyW10pOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IEVycm9yKCdDYW5ub3QgZ2V0IHJvd3MgYW5kIGNvbHVtbnMgb2YgYW4gZW1wdHkgc2hhcGUgYXJyYXkuJyk7XG4gIH1cblxuICByZXR1cm4gW3NoYXBlLmxlbmd0aCA+IDEgPyBzaGFwZVtzaGFwZS5sZW5ndGggLSAyXSA6IDEsIHNoYXBlW3NoYXBlLmxlbmd0aCAtIDFdXTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzaXplVG9TcXVhcmlzaFNoYXBlKHNpemU6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl0ge1xuICBjb25zdCB3aWR0aCA9IE1hdGguY2VpbChNYXRoLnNxcnQoc2l6ZSkpO1xuICByZXR1cm4gW3dpZHRoLCBNYXRoLmNlaWwoc2l6ZSAvIHdpZHRoKV07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0QmF0Y2hEaW0oc2hhcGU6IG51bWJlcltdLCBkaW1zVG9Ta2lwID0gMik6IG51bWJlciB7XG4gIHJldHVybiBzaXplRnJvbVNoYXBlKHNoYXBlLnNsaWNlKDAsIHNoYXBlLmxlbmd0aCAtIGRpbXNUb1NraXApKTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXJyYXlVdGlsLCBCcm9hZGNhc3RVdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcblxuaW1wb3J0IHsgR2xzbENvbnRleHQsIEdsc2xMaWIsIEdsc2xMaWJSb3V0aW5lIH0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuL2dsc2wtc291cmNlJztcbmltcG9ydCB7IHNxdWVlemVTaGFwZSB9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHsgVGV4dHVyZUxheW91dCB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHtcbiAgZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lLFxuICBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWVBdE91dENvb3JkcyxcbiAgZ2V0Q29vcmRzRGF0YVR5cGUsXG4gIGdldEdsQ2hhbm5lbHMsXG4gIGdldFNxdWVlemVkUGFyYW1zLFxuICBzcXVlZXplSW5wdXRTaGFwZSxcbn0gZnJvbSAnLi91dGlscyc7XG5cbi8qKlxuICogR0xTTCBMaWJyYXJ5IHJlc3BvbnNpYmxlIGZvciBkYXRhIHR5cGVzIGFuZCByb3V0aW5lcyBmb3IgbWFuaXB1bGF0aW5nXG4gKiBjb29yZGluYXRlcyBhbmQgbWFwcGluZyB0by9mcm9tIHRlbnNvciBpbmRpY2VzXG4gKi9cbmV4cG9ydCBjbGFzcyBDb29yZHNHbHNsTGliIGV4dGVuZHMgR2xzbExpYiB7XG4gIHJldHVyblR5cGU6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBHbHNsQ29udGV4dCkge1xuICAgIHN1cGVyKGNvbnRleHQpO1xuICB9XG4gIGdldEZ1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5vZmZzZXRUb0Nvb3JkcygpLFxuICAgICAgLi4udGhpcy5jb29yZHNUb09mZnNldCgpLFxuICAgICAgLi4udGhpcy50b1ZlYygpLFxuICAgICAgLi4udGhpcy52YWx1ZUZyb20oKSxcbiAgICAgIC8vIFRPRE8gcmV0dXJuIHRoZXNlIG9ubHkgd2hlbiBwYWNraW5nIGlzIGVuYWJsZWQuXG4gICAgICAuLi50aGlzLmdldENvbW1vblV0aWxGdW5jcygpLFxuICAgICAgLi4udGhpcy5nZXRJbnB1dHNTYW1wbGluZ1NuaXBwZXRzKCksXG4gICAgICAuLi50aGlzLmdldE91dHB1dFNhbXBsaW5nU25pcHBldCgpLFxuICAgIH07XG4gIH1cbiAgZ2V0Q3VzdG9tVHlwZXMoKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIC8qKlxuICAgKiBQcm9kdWNlcyBhIGZ1bmN0aW9uIHRoYXQgY2FuIG1hcCBmcm9tXG4gICAqIDJEIG5vcm1hbHppZWQgY29vcmRpbmF0ZXMgKHMsdCkgdG8gYSBmbGF0IG9mZnNldFxuICAgKi9cbiAgcHJvdGVjdGVkIG9mZnNldFRvQ29vcmRzKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IGZ1bmNOYW1lID0gJ29mZnNldFRvQ29vcmRzJztcbiAgICByZXR1cm4ge1xuICAgICAgb2Zmc2V0VG9Db29yZHM6IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICB2ZWMyICR7ZnVuY05hbWV9KGludCBvZmZzZXQsIGludCB3aWR0aCwgaW50IGhlaWdodCkge1xuICAgICAgICBpbnQgdCA9IG9mZnNldCAvIHdpZHRoO1xuICAgICAgICBpbnQgcyA9IG9mZnNldCAtIHQqd2lkdGg7XG4gICAgICAgIHZlYzIgY29vcmRzID0gKHZlYzIocyx0KSArIHZlYzIoMC41LDAuNSkpIC8gdmVjMih3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgcmV0dXJuIGNvb3JkcztcbiAgICAgIH1cbiAgICAgIGApLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUHJvZHVjZXMgYSBmdW5jdGlvbiB0aGF0IGNhbiBtYXAgZnJvbVxuICAgKiAyRCBub3JtYWx6aWVkIGNvb3JkaW5hdGVzIChzLHQpIHRvIGEgZmxhdCBvZmZzZXRcbiAgICovXG4gIHByb3RlY3RlZCBjb29yZHNUb09mZnNldCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBmdW5jTmFtZSA9ICdjb29yZHNUb09mZnNldCc7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvb3Jkc1RvT2Zmc2V0OiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgaW50ICR7ZnVuY05hbWV9KHZlYzIgY29vcmRzLCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHtcbiAgICAgICAgZmxvYXQgcyA9IGNvb3Jkcy5zICogZmxvYXQod2lkdGgpO1xuICAgICAgICBmbG9hdCB0ID0gY29vcmRzLnQgKiBmbG9hdChoZWlnaHQpO1xuICAgICAgICBpbnQgb2Zmc2V0ID0gaW50KHQpICogd2lkdGggKyBpbnQocyk7XG4gICAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgICB9XG4gICAgICBgKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBjb2RlIGZvciBvdXRwdXQgc2FtcGxlci5cbiAgICovXG5cbiAgcHJvdGVjdGVkIGdldE91dHB1dFNhbXBsaW5nU25pcHBldCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBpZiAob3V0cHV0TGF5b3V0LmlzUGFja2VkKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRQYWNrZWRPdXRwdXRTYW1wbGluZ1NuaXBwZXQob3V0cHV0TGF5b3V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRPdXRwdXRTYW1wbGluZ1NuaXBwZXQob3V0cHV0TGF5b3V0KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGNvZGUgZm9yIHBhY2tlZCBvdXRwdXQgc2FtcGxlci5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRPdXRwdXRTYW1wbGluZ1NuaXBwZXQob3V0cHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0U2hhcGUgPSBvdXRwdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBvdXRUZXhTaGFwZSA9IFtvdXRwdXRMYXlvdXQud2lkdGgsIG91dHB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIGNvbnN0IGZ1bmNOYW1lID0gJ2dldE91dHB1dENvb3Jkcyc7XG4gICAgc3dpdGNoIChvdXRTaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0U2NhbGFyQ29vcmRzKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRQYWNrZWQxRENvb3JkcyhvdXRTaGFwZSBhcyBbbnVtYmVyXSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRQYWNrZWQyRENvb3JkcyhvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFBhY2tlZDNEQ29vcmRzKFxuICAgICAgICAgIG91dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICApO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFBhY2tlZE5EQ29vcmRzKG91dFNoYXBlLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICB9XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAvLyBUT0RPIHdlIG5lZWQgdGhpcyB0byBwcm9wZXJseSByZXR1cm4gYSBwYWNrZWQgdmVjNCBmcm9tIGtlcm5lbHMuXG4gICAgLy8gUmVwbGFjZSBhbGwgJ3tnbHNsLm91dHB1dH0gPSByZXN1bHQnIHdpdGggJ3NldE91dHB1dChyZXN1bHQpJyBpbiBhbGwga2VybmVscy5cbiAgICBjb25zdCBmbG9hdFRleHR1cmVTZXRSR0JBU291cmNlID0gYFxuICAgICAgdm9pZCBzZXRPdXRwdXQodmVjNCB2YWwpIHtcbiAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2YWw7XG4gICAgICB9XG4gICAgYDtcbiAgICBjb25zdCBmbG9hdFRleHR1cmVTZXRSR0JBRnVuY05hbWUgPSAnZmxvYXRUZXh0dXJlU2V0UkdCQSc7XG4gICAgcmVzdWx0W2Zsb2F0VGV4dHVyZVNldFJHQkFGdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoZmxvYXRUZXh0dXJlU2V0UkdCQVNvdXJjZSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgY29kZSBmb3IgdW5wYWNrZWQgb3V0cHV0IHNhbXBsZXIuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRPdXRwdXRTYW1wbGluZ1NuaXBwZXQob3V0cHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0U2hhcGUgPSBvdXRwdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBvdXRUZXhTaGFwZSA9IFtvdXRwdXRMYXlvdXQud2lkdGgsIG91dHB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIGNvbnN0IGZ1bmNOYW1lID0gJ2dldE91dHB1dENvb3Jkcyc7XG4gICAgc3dpdGNoIChvdXRTaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0U2NhbGFyQ29vcmRzKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDFEQ29vcmRzKG91dFNoYXBlIGFzIFtudW1iZXJdLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkMkRDb29yZHMoXG4gICAgICAgICAgb3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICApO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0VW5wYWNrZWQzRENvb3JkcyhcbiAgICAgICAgICBvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDQ6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkNERDb29yZHMoXG4gICAgICAgICAgb3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDU6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkNURDb29yZHMoXG4gICAgICAgICAgb3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICApO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNjpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0VW5wYWNrZWQ2RENvb3JkcyhcbiAgICAgICAgICBvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIG91dHB1dCBkaW1lbnNpb25hbGl0eTogJHtvdXRTaGFwZS5sZW5ndGh9YCk7XG4gICAgfVxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgLy8gVE9ETyB3ZSBuZWVkIHRoaXMgdG8gcHJvcGVybHkgcmV0dXJuIGEgcGFja2VkIHZlYzQgZnJvbSBrZXJuZWxzLlxuICAgIC8vIFJlcGxhY2UgYWxsICd7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0JyB3aXRoICdzZXRPdXRwdXQocmVzdWx0KScgaW4gYWxsIGtlcm5lbHMuXG4gICAgY29uc3QgZmxvYXRUZXh0dXJlU2V0UlNvdXJjZSA9IGBcbiAgICAgICAgdm9pZCBzZXRPdXRwdXQoZmxvYXQgdmFsKSB7XG4gICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KHZhbCwgMCwgMCwgMCk7XG4gICAgICAgIH1cbiAgICBgO1xuICAgIGNvbnN0IGZsb2F0VGV4dHVyZVNldFJGdW5jTmFtZSA9ICdmbG9hdFRleHR1cmVTZXRSJztcbiAgICByZXN1bHRbZmxvYXRUZXh0dXJlU2V0UkZ1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShmbG9hdFRleHR1cmVTZXRSU291cmNlKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIFNjYWxhciBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0U2NhbGFyQ29vcmRzKCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgIGApO1xuICB9XG5cbiAgLyoqXG4gICAqIDFEIHBhY2tlZCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0UGFja2VkMURDb29yZHMoX3NoYXBlOiBbbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSB0ZXhTaGFwZTtcbiAgICBsZXQgc291cmNlID0gJyc7XG4gICAgaWYgKHBhY2tlZFRleFNoYXBlWzBdID09PSAxKSB7XG4gICAgICBzb3VyY2UgPSBgXG4gICAgICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICAgIHJldHVybiAyICogaW50KFRleENvb3Jkcy55ICogJHtwYWNrZWRUZXhTaGFwZVsxXX0uMCk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICAgIH1cblxuICAgIGlmIChwYWNrZWRUZXhTaGFwZVsxXSA9PT0gMSkge1xuICAgICAgc291cmNlID0gYFxuICAgICAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgICByZXR1cm4gMiAqIGludChUZXhDb29yZHMueCAqICR7cGFja2VkVGV4U2hhcGVbMF19LjApO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgICB9XG5cbiAgICBzb3VyY2UgPSBgXG4gICAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICByZXR1cm4gMiAqIChyZXNUZXhSQy55ICogJHtwYWNrZWRUZXhTaGFwZVswXX0gKyByZXNUZXhSQy54KTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogMkQgcGFja2VkIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRQYWNrZWQyRENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGlmIChBcnJheVV0aWwuYXJyYXlzRXF1YWwoc2hhcGUsIHRleFNoYXBlKSkge1xuICAgICAgc291cmNlID0gYFxuICAgICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgcmV0dXJuIDIgKiBpdmVjMihUZXhDb29yZHMueHkgKiB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICAgIH1cblxuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gdGV4U2hhcGU7XG4gICAgLy8gdGV4ZWxzIG5lZWRlZCB0byBhY2NvbW1vZGF0ZSBhIGxvZ2ljYWwgcm93XG4gICAgY29uc3QgdGV4ZWxzSW5Mb2dpY2FsUm93ID0gTWF0aC5jZWlsKHNoYXBlWzFdIC8gMik7XG5cbiAgICAvKipcbiAgICAgKiBnZXRPdXRwdXRDb29yZHNcbiAgICAgKlxuICAgICAqIHJlc1RleFJDOiBUaGUgcm93cyBhbmQgY29sdW1ucyBvZiB0aGUgdGV4ZWxzLiBJZiB5b3UgbW92ZSBvdmVyIG9uZVxuICAgICAqIHRleGVsIHRvIHRoZSByaWdodCBpbiB0aGUgcGFja2VkIHRleHR1cmUsIHlvdSBhcmUgbW92aW5nIG92ZXIgb25lIGNvbHVtblxuICAgICAqIChub3QgdHdvKS5cbiAgICAgKlxuICAgICAqIGluZGV4OiBUaGUgdGV4ZWwgaW5kZXhcbiAgICAgKi9cbiAgICBzb3VyY2UgPSBgXG4gICAgICAgIGl2ZWMyIGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHtwYWNrZWRUZXhTaGFwZVswXX0sICR7cGFja2VkVGV4U2hhcGVbMV19KSk7XG5cbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHtwYWNrZWRUZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuXG4gICAgICAgICAgLy8gcmV2ZXJzZSByIGFuZCBjIG9yZGVyIGZvciBwYWNrZWQgdGV4dHVyZVxuICAgICAgICAgIGludCByID0gaW1vZChpbmRleCwgJHt0ZXhlbHNJbkxvZ2ljYWxSb3d9KSAqIDI7XG4gICAgICAgICAgaW50IGMgPSAyICogKGluZGV4IC8gJHt0ZXhlbHNJbkxvZ2ljYWxSb3d9KTtcblxuICAgICAgICAgIHJldHVybiBpdmVjMihyLCBjKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogM0QgcGFja2VkIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRQYWNrZWQzRENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IFt0ZXhTaGFwZVswXSwgdGV4U2hhcGVbMV1dO1xuICAgIGNvbnN0IHRleGVsc0luTG9naWNhbFJvdyA9IE1hdGguY2VpbChzaGFwZVsyXSAvIDIpO1xuICAgIGNvbnN0IHRleGVsc0luQmF0Y2ggPSB0ZXhlbHNJbkxvZ2ljYWxSb3cgKiBNYXRoLmNlaWwoc2hhcGVbMV0gLyAyKTtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGl2ZWMzIGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHtwYWNrZWRUZXhTaGFwZVswXX0sICR7cGFja2VkVGV4U2hhcGVbMV19KSk7XG4gICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7cGFja2VkVGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcblxuICAgICAgICAgIGludCBiID0gaW5kZXggLyAke3RleGVsc0luQmF0Y2h9O1xuICAgICAgICAgIGluZGV4IC09IGIgKiAke3RleGVsc0luQmF0Y2h9O1xuXG4gICAgICAgICAgLy8gcmV2ZXJzZSByIGFuZCBjIG9yZGVyIGZvciBwYWNrZWQgdGV4dHVyZVxuICAgICAgICAgIGludCByID0gaW1vZChpbmRleCwgJHt0ZXhlbHNJbkxvZ2ljYWxSb3d9KSAqIDI7XG4gICAgICAgICAgaW50IGMgPSAyICogKGluZGV4IC8gJHt0ZXhlbHNJbkxvZ2ljYWxSb3d9KTtcblxuICAgICAgICAgIHJldHVybiBpdmVjMyhiLCByLCBjKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogTkQgcGFja2VkIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRQYWNrZWRORENvb3JkcyhzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gW3RleFNoYXBlWzBdLCB0ZXhTaGFwZVsxXV07XG5cbiAgICBjb25zdCB0ZXhlbHNJbkxvZ2ljYWxSb3cgPSBNYXRoLmNlaWwoc2hhcGVbc2hhcGUubGVuZ3RoIC0gMV0gLyAyKTtcbiAgICBjb25zdCB0ZXhlbHNJbkJhdGNoID0gdGV4ZWxzSW5Mb2dpY2FsUm93ICogTWF0aC5jZWlsKHNoYXBlW3NoYXBlLmxlbmd0aCAtIDJdIC8gMik7XG4gICAgbGV0IHRleGVsc0luQmF0Y2hOID0gdGV4ZWxzSW5CYXRjaDtcbiAgICBsZXQgYmF0Y2hlcyA9ICcnO1xuICAgIGxldCBjb29yZHMgPSAnYiwgciwgYyc7XG5cbiAgICBmb3IgKGxldCBiID0gMjsgYiA8IHNoYXBlLmxlbmd0aCAtIDE7IGIrKykge1xuICAgICAgdGV4ZWxzSW5CYXRjaE4gKj0gc2hhcGVbc2hhcGUubGVuZ3RoIC0gYiAtIDFdO1xuICAgICAgYmF0Y2hlcyA9XG4gICAgICAgIGBcbiAgICAgIGludCBiJHtifSA9IGluZGV4IC8gJHt0ZXhlbHNJbkJhdGNoTn07XG4gICAgICBpbmRleCAtPSBiJHtifSAqICR7dGV4ZWxzSW5CYXRjaE59O1xuICAgIGAgKyBiYXRjaGVzO1xuICAgICAgY29vcmRzID0gYGIke2J9LCBgICsgY29vcmRzO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICBpdmVjJHtzaGFwZS5sZW5ndGh9IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7cGFja2VkVGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcblxuICAgICAgICAke2JhdGNoZXN9XG5cbiAgICAgICAgaW50IGIgPSBpbmRleCAvICR7dGV4ZWxzSW5CYXRjaH07XG4gICAgICAgIGluZGV4IC09IGIgKiAke3RleGVsc0luQmF0Y2h9O1xuXG4gICAgICAgIC8vIHJldmVyc2UgciBhbmQgYyBvcmRlciBmb3IgcGFja2VkIHRleHR1cmVcbiAgICAgICAgaW50IHIgPSBpbW9kKGluZGV4LCAke3RleGVsc0luTG9naWNhbFJvd30pICogMjtcbiAgICAgICAgaW50IGMgPSAyICogKGluZGV4IC8gJHt0ZXhlbHNJbkxvZ2ljYWxSb3d9KTtcblxuICAgICAgICByZXR1cm4gaXZlYyR7c2hhcGUubGVuZ3RofSgke2Nvb3Jkc30pO1xuICAgICAgfVxuICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDFEIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRVbnBhY2tlZDFEQ29vcmRzKF9zaGFwZTogW251bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgICAgcmV0dXJuIHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDJEIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRVbnBhY2tlZDJEQ29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGl2ZWMyIGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7dGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcbiAgICAgICAgICBpbnQgciA9IGluZGV4IC8gJHtzaGFwZVsxXX07XG4gICAgICAgICAgaW50IGMgPSBpbmRleCAtIHIgKiAke3NoYXBlWzFdfTtcbiAgICAgICAgICByZXR1cm4gaXZlYzIociwgYyk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDNEIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRVbnBhY2tlZDNEQ29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gICAgbGV0IHN0cmlkZXMgPSBudWxsO1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgc3RyaWRlcyA9IFtdO1xuICAgIH1cblxuICAgIHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayAtIDEpO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gc2hhcGVbcmFuayAtIDFdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMzsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHN0cmlkZXNbaV0gPSBzdHJpZGVzW2kgKyAxXSAqIHNoYXBlW2kgKyAxXTtcbiAgICB9XG4gICAgY29uc3QgY29vcmRzVG9Db21wdXRlID0gWydyJywgJ2MnLCAnZCddO1xuICAgIGNvbnN0IGNvb3Jkc0Zyb21JbmRleFNuaXBwZXQgPSBzdHJpZGVzXG4gICAgICAubWFwKChzdHJpZGUsIGkpID0+IHtcbiAgICAgICAgY29uc3QgbGluZTEgPSBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2ldfSA9IGluZGV4IC8gJHtzdHJpZGV9YDtcbiAgICAgICAgY29uc3QgbGluZTIgPVxuICAgICAgICAgIGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMVxuICAgICAgICAgICAgPyBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2kgKyAxXX0gPSBpbmRleCAtICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWBcbiAgICAgICAgICAgIDogYGluZGV4IC09ICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWA7XG4gICAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJycpO1xuXG4gICAgc291cmNlID0gYFxuICAgICAgICBpdmVjMyBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgICAgJHtjb29yZHNGcm9tSW5kZXhTbmlwcGV0fVxuICAgICAgICAgIHJldHVybiBpdmVjMyhyLCBjLCBkKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgNEQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkNERDb29yZHMoXG4gICAgc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdLFxuICApOiBHbHNsTGliUm91dGluZSB7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgICBsZXQgc3RyaWRlcyA9IG51bGw7XG4gICAgaWYgKHJhbmsgPCAyKSB7XG4gICAgICBzdHJpZGVzID0gW107XG4gICAgfVxuXG4gICAgc3RyaWRlcyA9IG5ldyBBcnJheShyYW5rIC0gMSk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMl0gPSBzaGFwZVtyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogc2hhcGVbaSArIDFdO1xuICAgIH1cbiAgICBjb25zdCBjb29yZHNUb0NvbXB1dGUgPSBbJ3InLCAnYycsICdkJywgJ2QyJ107XG4gICAgY29uc3QgY29vcmRzRnJvbUluZGV4U25pcHBldCA9IHN0cmlkZXNcbiAgICAgIC5tYXAoKHN0cmlkZSwgaSkgPT4ge1xuICAgICAgICBjb25zdCBsaW5lMSA9IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaV19ID0gaW5kZXggLyAke3N0cmlkZX1gO1xuICAgICAgICBjb25zdCBsaW5lMiA9XG4gICAgICAgICAgaSA9PT0gc3RyaWRlcy5sZW5ndGggLSAxXG4gICAgICAgICAgICA/IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaSArIDFdfSA9IGluZGV4IC0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YFxuICAgICAgICAgICAgOiBgaW5kZXggLT0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YDtcbiAgICAgICAgcmV0dXJuIGAke2xpbmUxfTsgJHtsaW5lMn07YDtcbiAgICAgIH0pXG4gICAgICAuam9pbignJyk7XG5cbiAgICBzb3VyY2UgPSBgXG4gICAgICBpdmVjNCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgICAgJHtjb29yZHNGcm9tSW5kZXhTbmlwcGV0fVxuICAgICAgICAgIHJldHVybiBpdmVjNChyLCBjLCBkLCBkMik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDVEIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRVbnBhY2tlZDVEQ29vcmRzKFxuICAgIHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdLFxuICApOiBHbHNsTGliUm91dGluZSB7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgICBsZXQgc3RyaWRlcyA9IG51bGw7XG4gICAgaWYgKHJhbmsgPCAyKSB7XG4gICAgICBzdHJpZGVzID0gW107XG4gICAgfVxuXG4gICAgc3RyaWRlcyA9IG5ldyBBcnJheShyYW5rIC0gMSk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMl0gPSBzaGFwZVtyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogc2hhcGVbaSArIDFdO1xuICAgIH1cbiAgICBjb25zdCBjb29yZHNUb0NvbXB1dGUgPSBbJ3InLCAnYycsICdkJywgJ2QyJywgJ2QzJ107XG4gICAgY29uc3QgY29vcmRzRnJvbUluZGV4U25pcHBldCA9IHN0cmlkZXNcbiAgICAgIC5tYXAoKHN0cmlkZSwgaSkgPT4ge1xuICAgICAgICBjb25zdCBsaW5lMSA9IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaV19ID0gaW5kZXggLyAke3N0cmlkZX1gO1xuICAgICAgICBjb25zdCBsaW5lMiA9XG4gICAgICAgICAgaSA9PT0gc3RyaWRlcy5sZW5ndGggLSAxXG4gICAgICAgICAgICA/IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaSArIDFdfSA9IGluZGV4IC0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YFxuICAgICAgICAgICAgOiBgaW5kZXggLT0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YDtcbiAgICAgICAgcmV0dXJuIGAke2xpbmUxfTsgJHtsaW5lMn07YDtcbiAgICAgIH0pXG4gICAgICAuam9pbignJyk7XG5cbiAgICBzb3VyY2UgPSBgXG4gICAgICBpdmVjNSBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgICAgJHtjb29yZHNGcm9tSW5kZXhTbmlwcGV0fVxuICAgICAgICAgIHJldHVybiBpdmVjNShyLCBjLCBkLCBkMiwgZDMpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA2RCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQ2RENvb3JkcyhcbiAgICBzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdLFxuICApOiBHbHNsTGliUm91dGluZSB7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgICBsZXQgc3RyaWRlcyA9IG51bGw7XG4gICAgaWYgKHJhbmsgPCAyKSB7XG4gICAgICBzdHJpZGVzID0gW107XG4gICAgfVxuXG4gICAgc3RyaWRlcyA9IG5ldyBBcnJheShyYW5rIC0gMSk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMl0gPSBzaGFwZVtyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogc2hhcGVbaSArIDFdO1xuICAgIH1cbiAgICBjb25zdCBjb29yZHNUb0NvbXB1dGUgPSBbJ3InLCAnYycsICdkJywgJ2QyJywgJ2QzJywgJ2Q0J107XG4gICAgY29uc3QgY29vcmRzRnJvbUluZGV4U25pcHBldCA9IHN0cmlkZXNcbiAgICAgIC5tYXAoKHN0cmlkZSwgaSkgPT4ge1xuICAgICAgICBjb25zdCBsaW5lMSA9IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaV19ID0gaW5kZXggLyAke3N0cmlkZX1gO1xuICAgICAgICBjb25zdCBsaW5lMiA9XG4gICAgICAgICAgaSA9PT0gc3RyaWRlcy5sZW5ndGggLSAxXG4gICAgICAgICAgICA/IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaSArIDFdfSA9IGluZGV4IC0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YFxuICAgICAgICAgICAgOiBgaW5kZXggLT0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YDtcbiAgICAgICAgcmV0dXJuIGAke2xpbmUxfTsgJHtsaW5lMn07YDtcbiAgICAgIH0pXG4gICAgICAuam9pbignJyk7XG5cbiAgICBzb3VyY2UgPSBgXG4gICAgIGl2ZWM2IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7dGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcbiAgICAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgICAgIHJldHVybiBpdmVjNihyLCBjLCBkLCBkMiwgZDMsIGQ0KTtcbiAgICAgICB9XG4gICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBjb2RlIGZvciBjb21tb24gVVYgY29vcmRzIGNvbXB1dGF0aW9uIHV0aWxpdHkgZnVuY3Rpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldENvbW1vblV0aWxGdW5jcygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICBsZXQgZnVuY05hbWUgPSAndXZGcm9tRmxhdCc7XG4gICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgdmVjMiB1dkZyb21GbGF0KGludCB0ZXhOdW1SLCBpbnQgdGV4TnVtQywgaW50IGluZGV4KSB7XG4gICAgICBpbnQgdGV4QyA9IGluZGV4IC8gdGV4TnVtUjtcbiAgICAgIGludCB0ZXhSID0gaW5kZXggLSB0ZXhDICogdGV4TnVtUjtcbiAgICAgIC8vIFRPRE86IHN3YXAgdGV4UiwgdGV4QyBvcmRlciBpbiBmb2xsb3dpbmcgZnVuY3Rpb24gc28gcm93IGlzIGNvcnJlc3BvbmRpbmcgdG8gdSBhbmQgY29sdW1uIGlzIGNvcnJlc3BvbmRpbmcgdG9cbiAgICAgIC8vICAgICAgIHYuXG4gICAgICByZXR1cm4gKHZlYzIodGV4UiwgdGV4QykgKyBoYWxmQ1IpIC8gdmVjMih0ZXhOdW1SLCB0ZXhOdW1DKTtcbiAgICB9XG4gICAgYCk7XG4gICAgZnVuY05hbWUgPSAncGFja2VkVVZmcm9tMUQnO1xuICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgdmVjMiBwYWNrZWRVVmZyb20xRChpbnQgdGV4TnVtUiwgaW50IHRleE51bUMsIGludCBpbmRleCkge1xuICAgICAgICBpbnQgdGV4ZWxJbmRleCA9IGluZGV4IC8gMjtcbiAgICAgICAgaW50IHRleFIgPSB0ZXhlbEluZGV4IC8gdGV4TnVtQztcbiAgICAgICAgaW50IHRleEMgPSB0ZXhlbEluZGV4IC0gdGV4UiAqIHRleE51bUM7XG4gICAgICAgIHJldHVybiAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLyB2ZWMyKHRleE51bUMsIHRleE51bVIpO1xuICAgICAgfVxuICAgICAgYCk7XG4gICAgZnVuY05hbWUgPSAncGFja2VkVVZmcm9tMkQnO1xuICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgdmVjMiBwYWNrZWRVVmZyb20yRChpbnQgdGV4TnVtUiwgaW50IHRleE51bUMsIGludCB0ZXhlbHNJbkxvZ2ljYWxSb3csIGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgaW50IHRleGVsSW5kZXggPSAocm93IC8gMikgKiB0ZXhlbHNJbkxvZ2ljYWxSb3cgKyAoY29sIC8gMik7XG4gICAgICAgIGludCB0ZXhSID0gdGV4ZWxJbmRleCAvIHRleE51bUM7XG4gICAgICAgIGludCB0ZXhDID0gdGV4ZWxJbmRleCAtIHRleFIgKiB0ZXhOdW1DO1xuICAgICAgICByZXR1cm4gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMih0ZXhOdW1DLCB0ZXhOdW1SKTtcbiAgICAgIH1cbiAgICAgIGApO1xuICAgIGZ1bmNOYW1lID0gJ3BhY2tlZFVWZnJvbTNEJztcbiAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIHZlYzIgcGFja2VkVVZmcm9tM0QoaW50IHRleE51bVIsIGludCB0ZXhOdW1DLFxuICAgICAgICAgIGludCB0ZXhlbHNJbkJhdGNoLCBpbnQgdGV4ZWxzSW5Mb2dpY2FsUm93LCBpbnQgYixcbiAgICAgICAgICBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgIGludCBpbmRleCA9IGIgKiB0ZXhlbHNJbkJhdGNoICsgKHJvdyAvIDIpICogdGV4ZWxzSW5Mb2dpY2FsUm93ICsgKGNvbCAvIDIpO1xuICAgICAgICBpbnQgdGV4UiA9IGluZGV4IC8gdGV4TnVtQztcbiAgICAgICAgaW50IHRleEMgPSBpbmRleCAtIHRleFIgKiB0ZXhOdW1DO1xuICAgICAgICByZXR1cm4gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMih0ZXhOdW1DLCB0ZXhOdW1SKTtcbiAgICAgIH1cbiAgICAgIGApO1xuICAgIGZ1bmNOYW1lID0gJ3NhbXBsZVRleHR1cmUnO1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICAgIGZsb2F0IHNhbXBsZVRleHR1cmUoc2FtcGxlcjJEIHRleHR1cmVTYW1wbGVyLCB2ZWMyIHV2KSB7XG4gICAgICAgICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0odGV4dHVyZVNhbXBsZXIsIHV2KS5yO1xuICAgICAgICB9YCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rpbmcgc25pcHBldHMgZm9yIGlucHV0c1xuICAgKi9cbiAgcHJvdGVjdGVkIGdldElucHV0c1NhbXBsaW5nU25pcHBldHMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgoc2FtcGxlck5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IGlucHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV07XG4gICAgICBjb25zdCBmdW5jTmFtZSA9IGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZShzYW1wbGVyTmFtZSk7XG4gICAgICBpZiAoaW5wdXRMYXlvdXQuaXNQYWNrZWQpIHtcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0UGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgc2FtcGxlck5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldFVucGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgc2FtcGxlck5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb3V0Q29vcmRGdW5jTmFtZSA9IGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZUF0T3V0Q29vcmRzKHNhbXBsZXJOYW1lKTtcbiAgICAgIGlmIChpbnB1dExheW91dC51bnBhY2tlZFNoYXBlLmxlbmd0aCA8PSBvdXRwdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGgpIHtcbiAgICAgICAgaWYgKGlucHV0TGF5b3V0LmlzUGFja2VkKSB7XG4gICAgICAgICAgcmVzdWx0W291dENvb3JkRnVuY05hbWVdID0gdGhpcy5nZXRQYWNrZWRTYW1wbGVyQXRPdXRwdXRDb29yZHMoXG4gICAgICAgICAgICBvdXRDb29yZEZ1bmNOYW1lLFxuICAgICAgICAgICAgaW5wdXRMYXlvdXQsXG4gICAgICAgICAgICBvdXRwdXRMYXlvdXQsXG4gICAgICAgICAgICBzYW1wbGVyTmFtZSxcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdFtvdXRDb29yZEZ1bmNOYW1lXSA9IHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyQXRPdXRwdXRDb29yZHMoXG4gICAgICAgICAgICBvdXRDb29yZEZ1bmNOYW1lLFxuICAgICAgICAgICAgaW5wdXRMYXlvdXQsXG4gICAgICAgICAgICBvdXRwdXRMYXlvdXQsXG4gICAgICAgICAgICBzYW1wbGVyTmFtZSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdGluZyBzbmlwcGV0cyBmb3Igb3V0cHV0IGNvb3JkaW5hdGVzIG9mIHNhbXBsZXJzXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKFxuICAgIGZ1bmNOYW1lOiBzdHJpbmcsXG4gICAgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQsXG4gICAgb3V0cHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIG5hbWU6IHN0cmluZyxcbiAgKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IGluU2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IG91dFNoYXBlID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3QgdGV4TmFtZSA9IG5hbWU7XG4gICAgY29uc3QgdGV4RnVuY1NuaXBwZXQgPSBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWUodGV4TmFtZSk7XG5cbiAgICBjb25zdCBpblJhbmsgPSBpblNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBvdXRSYW5rID0gb3V0U2hhcGUubGVuZ3RoO1xuXG4gICAgY29uc3QgYnJvYWRjYXN0RGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpblNoYXBlLCBvdXRTaGFwZSk7XG5cbiAgICBjb25zdCB0eXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0UmFuayk7XG4gICAgY29uc3QgcmFua0RpZmYgPSBvdXRSYW5rIC0gaW5SYW5rO1xuICAgIGxldCBjb29yZHNTbmlwcGV0OiBzdHJpbmc7XG4gICAgY29uc3QgZmllbGRzID0gZ2V0R2xDaGFubmVscygpO1xuXG4gICAgaWYgKGluUmFuayA9PT0gMCkge1xuICAgICAgY29vcmRzU25pcHBldCA9ICcnO1xuICAgIH0gZWxzZSBpZiAob3V0UmFuayA8IDIgJiYgYnJvYWRjYXN0RGltcy5sZW5ndGggPj0gMSkge1xuICAgICAgY29vcmRzU25pcHBldCA9ICdjb29yZHMgPSAwOyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSBicm9hZGNhc3REaW1zLm1hcCgoZCkgPT4gYGNvb3Jkcy4ke2ZpZWxkc1tkICsgcmFua0RpZmZdfSA9IDA7YCkuam9pbignXFxuJyk7XG4gICAgfVxuICAgIGxldCB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSAnJztcbiAgICBpZiAob3V0UmFuayA8IDIgJiYgaW5SYW5rID4gMCkge1xuICAgICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJ2Nvb3Jkcyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9IGluU2hhcGUubWFwKChfcywgaSkgPT4gYGNvb3Jkcy4ke2ZpZWxkc1tpICsgcmFua0RpZmZdfWApLmpvaW4oJywgJyk7XG4gICAgfVxuXG4gICAgbGV0IG91dHB1dCA9ICdyZXR1cm4gb3V0cHV0VmFsdWU7JztcbiAgICBjb25zdCBpblNpemUgPSBTaGFwZVV0aWwuc2l6ZShpblNoYXBlKTtcbiAgICBjb25zdCBpc0lucHV0U2NhbGFyID0gaW5TaXplID09PSAxO1xuICAgIGNvbnN0IG91dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRTaGFwZSk7XG4gICAgY29uc3QgaXNPdXRwdXRTY2FsYXIgPSBvdXRTaXplID09PSAxO1xuXG4gICAgaWYgKGluUmFuayA9PT0gMSAmJiAhaXNJbnB1dFNjYWxhciAmJiAhaXNPdXRwdXRTY2FsYXIpIHtcbiAgICAgIG91dHB1dCA9IGBcbiAgICAgICAgcmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueHksIG91dHB1dFZhbHVlLnh5KTtcbiAgICAgIGA7XG4gICAgfSBlbHNlIGlmIChpc0lucHV0U2NhbGFyICYmICFpc091dHB1dFNjYWxhcikge1xuICAgICAgaWYgKG91dFJhbmsgPT09IDEpIHtcbiAgICAgICAgb3V0cHV0ID0gYFxuICAgICAgICAgIHJldHVybiB2ZWM0KG91dHB1dFZhbHVlLngsIG91dHB1dFZhbHVlLngsIDAuLCAwLik7XG4gICAgICAgIGA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQgPSBgXG4gICAgICAgICAgcmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCk7XG4gICAgICAgIGA7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChicm9hZGNhc3REaW1zLmxlbmd0aCkge1xuICAgICAgY29uc3Qgcm93cyA9IGluUmFuayAtIDI7XG4gICAgICBjb25zdCBjb2xzID0gaW5SYW5rIC0gMTtcblxuICAgICAgaWYgKGJyb2FkY2FzdERpbXMuaW5kZXhPZihyb3dzKSA+IC0xICYmIGJyb2FkY2FzdERpbXMuaW5kZXhPZihjb2xzKSA+IC0xKSB7XG4gICAgICAgIG91dHB1dCA9ICdyZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54KTsnO1xuICAgICAgfSBlbHNlIGlmIChicm9hZGNhc3REaW1zLmluZGV4T2Yocm93cykgPiAtMSkge1xuICAgICAgICBvdXRwdXQgPSAncmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCwgb3V0cHV0VmFsdWUueSwgJyArICdvdXRwdXRWYWx1ZS54LCBvdXRwdXRWYWx1ZS55KTsnO1xuICAgICAgfSBlbHNlIGlmIChicm9hZGNhc3REaW1zLmluZGV4T2YoY29scykgPiAtMSkge1xuICAgICAgICBvdXRwdXQgPSAncmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueHgsIG91dHB1dFZhbHVlLnp6KTsnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHN3YXBMYXN0RGltc1NuaXBwZXQgPSBgXG4gICAgICAgIGludCBsYXN0RGltID0gY29vcmRzLiR7ZmllbGRzW291dFJhbmsgLSAxXX07XG4gICAgICAgIGNvb3Jkcy4ke2ZpZWxkc1tvdXRSYW5rIC0gMV19ID0gY29vcmRzLiR7ZmllbGRzW291dFJhbmsgLSAyXX07XG4gICAgICAgIGNvb3Jkcy4ke2ZpZWxkc1tvdXRSYW5rIC0gMl19ID0gbGFzdERpbTtcbiAgICAgIGA7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgdmVjNCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgJHt0eXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICAgICAgJHtzd2FwTGFzdERpbXNTbmlwcGV0fVxuICAgICAgICAke2Nvb3Jkc1NuaXBwZXR9XG4gICAgICAgIHZlYzQgb3V0cHV0VmFsdWUgPSAke3RleEZ1bmNTbmlwcGV0fSgke3VucGFja2VkQ29vcmRzU25pcHBldH0pO1xuICAgICAgICAke291dHB1dH1cbiAgICAgIH1cbiAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLmdldE91dHB1dENvb3JkcyddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rpbmcgc25pcHBldHMgZm9yIHVucGFja2VkIG91dHB1dCBjb29yZGluYXRlcyBvZiBzYW1wbGVyc1xuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKFxuICAgIGZ1bmNOYW1lOiBzdHJpbmcsXG4gICAgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQsXG4gICAgb3V0cHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIG5hbWU6IHN0cmluZyxcbiAgKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IG91dFRleFNoYXBlID0gW291dHB1dExheW91dC53aWR0aCwgb3V0cHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgaW5UZXhTaGFwZSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCBpblJhbmsgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBvdXRSYW5rID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IGluU2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IG91dFNoYXBlID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3QgdGV4RnVuY1NuaXBwZXQgPSBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWUobmFtZSk7XG5cbiAgICBpZiAoaW5SYW5rID09PSBvdXRSYW5rICYmIEFycmF5VXRpbC5hcnJheXNFcXVhbChpblRleFNoYXBlLCBvdXRUZXhTaGFwZSkpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIFRleENvb3Jkcyk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBjb25zdCB0eXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0UmFuayk7XG4gICAgY29uc3QgYnJvYWRjYXN0RGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpblNoYXBlLCBvdXRTaGFwZSk7XG4gICAgY29uc3QgcmFua0RpZmYgPSBvdXRSYW5rIC0gaW5SYW5rO1xuICAgIGxldCBjb29yZHNTbmlwcGV0OiBzdHJpbmc7XG4gICAgY29uc3QgZmllbGRzID0gZ2V0R2xDaGFubmVscygpO1xuXG4gICAgaWYgKGluUmFuayA9PT0gMCkge1xuICAgICAgY29vcmRzU25pcHBldCA9ICcnO1xuICAgIH0gZWxzZSBpZiAob3V0UmFuayA8IDIgJiYgYnJvYWRjYXN0RGltcy5sZW5ndGggPj0gMSkge1xuICAgICAgY29vcmRzU25pcHBldCA9ICdjb29yZHMgPSAwOyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSBicm9hZGNhc3REaW1zLm1hcCgoZCkgPT4gYGNvb3Jkcy4ke2ZpZWxkc1tkICsgcmFua0RpZmZdfSA9IDA7YCkuam9pbignXFxuJyk7XG4gICAgfVxuICAgIGxldCB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSAnJztcbiAgICBpZiAob3V0UmFuayA8IDIgJiYgaW5SYW5rID4gMCkge1xuICAgICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJ2Nvb3Jkcyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGUubWFwKChfcywgaSkgPT4gYGNvb3Jkcy4ke2ZpZWxkc1tpICsgcmFua0RpZmZdfWApLmpvaW4oJywgJyk7XG4gICAgfVxuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICAgJHt0eXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICAgICAgICAke2Nvb3Jkc1NuaXBwZXR9XG4gICAgICAgICAgcmV0dXJuICR7dGV4RnVuY1NuaXBwZXR9KCR7dW5wYWNrZWRDb29yZHNTbmlwcGV0fSk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuZ2V0T3V0cHV0Q29vcmRzJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdGluZyBzbmlwcGV0cyBmb3IgcGFja2VkIG9wZXJhdGlvbnMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIHN3aXRjaCAoaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkU2FtcGxlclNjYWxhcihmdW5jTmFtZSwgbmFtZSk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZFNhbXBsZXIxRChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYWNrZWRTYW1wbGVyMkQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYWNrZWRTYW1wbGVyTkQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0aW5nIHNuaXBwZXRzIGZvciB1bnBhY2tlZCBvcGVyYXRpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBzd2l0Y2ggKHNoYXBlLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJTY2FsYXIoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyMUQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyMkQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyM0QoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgNDpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyNEQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgNTpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyNUQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgNjpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyNkQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIC8vIFRPRE8gc3VwcG9ydCBtb3JlIGRpbWVuc2lvbmFsaXRpZXNcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkaW1lbnNpb24gJHtzaGFwZS5sZW5ndGh9LURgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGFja2VkIHNjYWxhciBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXJTY2FsYXIoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIHZlYzQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgaGFsZkNSKTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhY2tlZCAxRCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXIxRChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHRleFNoYXBlID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gW3RleFNoYXBlWzFdLCB0ZXhTaGFwZVswXV07XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcblxuICAgIGNvbnN0IHBhY2tlZFNhbXBsZXIgPSBgdmVjNCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgIHZlYzIgdXYgPSBwYWNrZWRVVmZyb20xRChcbiAgICAgICR7cGFja2VkVGV4U2hhcGVbMF19LCAke3BhY2tlZFRleFNoYXBlWzFdfSwgaW5kZXgpO1xuICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIHV2KTtcbiAgICB9YDtcbiAgICBjb25zdCBzb3VyY2UgPSBwYWNrZWRTYW1wbGVyO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnBhY2tlZFVWZnJvbTFEJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhY2tlZCAyRCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXIyRChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCB0ZXhTaGFwZSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIGNvbnN0IHRleE51bVIgPSB0ZXhTaGFwZVswXTtcbiAgICBjb25zdCB0ZXhOdW1DID0gdGV4U2hhcGVbMV07XG5cbiAgICBpZiAodGV4U2hhcGUgIT0gbnVsbCAmJiBBcnJheVV0aWwuYXJyYXlzRXF1YWwoc2hhcGUsIHRleFNoYXBlKSkge1xuICAgICAgY29uc3QgcGFja2VkU2FtcGxlciA9IGB2ZWM0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgdmVjMiB1diA9ICh2ZWMyKGNvbCwgcm93KSArIGhhbGZDUikgLyB2ZWMyKCR7dGV4TnVtQ30uMCwgJHt0ZXhOdW1SfS4wKTtcbiAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIHV2KTtcbiAgICAgIH1gO1xuXG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHBhY2tlZFNhbXBsZXIpO1xuICAgIH1cbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IHRleFNoYXBlO1xuICAgIGNvbnN0IHZhbHVlc1BlclJvdyA9IE1hdGguY2VpbChzaGFwZVsxXSAvIDIpO1xuICAgIGNvbnN0IHBhY2tlZFNhbXBsZXIgPSBgdmVjNCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tMkQoJHtwYWNrZWRUZXhTaGFwZVsxXX0sICR7cGFja2VkVGV4U2hhcGVbMF19LCAke3ZhbHVlc1BlclJvd30sIHJvdywgY29sKTtcbiAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCB1dik7XG4gICAgfWA7XG4gICAgY29uc3Qgc291cmNlID0gcGFja2VkU2FtcGxlcjtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5wYWNrZWRVVmZyb20yRCddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYWNrZWQgM0Qgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyM0QoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3QgdGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQud2lkdGgsIGlucHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSBbdGV4U2hhcGVbMF0sIHRleFNoYXBlWzFdXTtcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuXG4gICAgaWYgKHNoYXBlWzBdID09PSAxKSB7XG4gICAgICBjb25zdCBzcXVlZXplZFNoYXBlID0gc2hhcGUuc2xpY2UoMSk7XG4gICAgICBjb25zdCBrZXB0RGltcyA9IFsxLCAyXTtcbiAgICAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgc3F1ZWV6ZWRTaGFwZSk7XG4gICAgICBjb25zdCBwYXJhbXMgPSBbJ2InLCAncm93JywgJ2NvbCddO1xuICAgICAgLy8gRGVlcCBjb3B5IG9mIGlucHV0IHRleHR1cmUgbGF5b3V0LlxuICAgICAgY29uc3QgbmV3SW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0TGF5b3V0KSk7XG4gICAgICBuZXdJbnB1dExheW91dC51bnBhY2tlZFNoYXBlID0gbmV3SW5wdXRTaGFwZTtcbiAgICAgIGNvbnN0IHNhbXBsZXJSb3V0aW5lID0gdGhpcy5nZXRQYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCk7XG4gICAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYCR7c2FtcGxlclJvdXRpbmUucm91dGluZUJvZHl9XG4gICAgICB2ZWM0ICR7ZnVuY05hbWV9KGludCBiLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgIHJldHVybiAke2Z1bmNOYW1lfSgke2dldFNxdWVlemVkUGFyYW1zKHBhcmFtcywga2VwdERpbXMpfSk7XG4gICAgICB9IGA7XG4gICAgICBjb25zdCBzb3VyY2UgPSBwYWNrZWRTYW1wbGVyO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIHNhbXBsZXJSb3V0aW5lLmRlcGVuZGVuY2llcyk7XG4gICAgfVxuICAgIGNvbnN0IHRleE51bVIgPSBwYWNrZWRUZXhTaGFwZVswXTtcbiAgICBjb25zdCB0ZXhOdW1DID0gcGFja2VkVGV4U2hhcGVbMV07XG5cbiAgICBjb25zdCB2YWx1ZXNQZXJSb3cgPSBNYXRoLmNlaWwoc2hhcGVbMl0gLyAyKTtcbiAgICBjb25zdCB0ZXhlbHNJbkJhdGNoID0gdmFsdWVzUGVyUm93ICogTWF0aC5jZWlsKHNoYXBlWzFdIC8gMik7XG5cbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oaW50IGIsIGludCByb3csIGludCBjb2wpIHtcbiAgICAgIHZlYzIgdXYgPSBwYWNrZWRVVmZyb20zRChcbiAgICAgICAgJHt0ZXhOdW1DfSwgJHt0ZXhOdW1SfSwgJHt0ZXhlbHNJbkJhdGNofSwgJHt2YWx1ZXNQZXJSb3d9LCBiLCByb3csIGNvbCk7XG4gICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgdXYpO31gO1xuICAgIGNvbnN0IHNvdXJjZSA9IHBhY2tlZFNhbXBsZXI7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMucGFja2VkVVZmcm9tM0QnXSk7XG4gIH1cbiAgLypcbiAgICogUGFja2VkIE5EIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlck5EKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgdGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQud2lkdGgsIGlucHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcblxuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gW3RleFNoYXBlWzBdLCB0ZXhTaGFwZVsxXV07XG4gICAgY29uc3QgdGV4TnVtUiA9IHBhY2tlZFRleFNoYXBlWzFdO1xuICAgIGNvbnN0IHRleE51bUMgPSBwYWNrZWRUZXhTaGFwZVswXTtcbiAgICBjb25zdCB2YWx1ZXNQZXJSb3cgPSBNYXRoLmNlaWwoc2hhcGVbcmFuayAtIDFdIC8gMik7XG4gICAgbGV0IHRleGVsc0luQmF0Y2ggPSB2YWx1ZXNQZXJSb3cgKiBNYXRoLmNlaWwoc2hhcGVbcmFuayAtIDJdIC8gMik7XG4gICAgbGV0IHBhcmFtcyA9ICdpbnQgYiwgaW50IHJvdywgaW50IGNvbCc7XG4gICAgbGV0IGluZGV4ID0gYGIgKiAke3RleGVsc0luQmF0Y2h9ICsgKHJvdyAvIDIpICogJHt2YWx1ZXNQZXJSb3d9ICsgKGNvbCAvIDIpYDtcbiAgICBmb3IgKGxldCBiID0gMjsgYiA8IHJhbmsgLSAxOyBiKyspIHtcbiAgICAgIHBhcmFtcyA9IGBpbnQgYiR7Yn0sIGAgKyBwYXJhbXM7XG4gICAgICB0ZXhlbHNJbkJhdGNoICo9IHNoYXBlW3JhbmsgLSBiIC0gMV07XG4gICAgICBpbmRleCA9IGBiJHtifSAqICR7dGV4ZWxzSW5CYXRjaH0gKyBgICsgaW5kZXg7XG4gICAgfVxuICAgIGNvbnN0IHBhY2tlZFNhbXBsZXIgPSBgdmVjNCAke2Z1bmNOYW1lfSgke3BhcmFtc30pIHtcbiAgICAgIGludCBpbmRleCA9ICR7aW5kZXh9O1xuICAgICAgaW50IHRleFIgPSBpbmRleCAvICR7dGV4TnVtQ307XG4gICAgICBpbnQgdGV4QyA9IGluZGV4IC0gdGV4UiAqICR7dGV4TnVtQ307XG4gICAgICB2ZWMyIHV2ID0gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMigke3RleE51bUN9LCAke3RleE51bVJ9KTtcbiAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCB1dik7XG4gICAgfWA7XG4gICAgY29uc3Qgc291cmNlID0gcGFja2VkU2FtcGxlcjtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgc2NhbGFyIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyU2NhbGFyKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgW3RleE51bVIsIHRleE51bUNdID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGlmICh0ZXhOdW1SID09PSAxICYmIHRleE51bUMgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIGhhbGZDUik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KCkge1xuICAgICAgICAgIGludCBvZmZzZXRfJHtuYW1lfSA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSk7XG4gICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSwgb2Zmc2V0XyR7bmFtZX0pO1xuICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgW1xuICAgICAgJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLFxuICAgICAgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLFxuICAgICAgJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0JyxcbiAgICBdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAxRCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjFEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgdE51bVIgPSBpbnB1dExheW91dC53aWR0aDtcbiAgICBjb25zdCB0TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcblxuICAgIGlmICh0TnVtQyA9PT0gMSAmJiB0TnVtUiA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCBoYWxmQ1IpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBpZiAodE51bUMgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKChmbG9hdChpbmRleCkgKyAwLjUpIC8gJHt0TnVtUn0uMCwgMC41KTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICAgIH1cbiAgICBpZiAodE51bVIgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKDAuNSwgKGZsb2F0KGluZGV4KSArIDAuNSkgLyAke3ROdW1DfS4wKTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCBpbmRleCkge1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dE51bVJ9LCAke3ROdW1DfSwgaW5kZXgpO1xuICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy51dkZyb21GbGF0JywgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgMkQgc25pcHBldC5cbiAgICovXG5cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjJEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuXG4gICAgLy8gVE9ETzogbW9kaWZ5IHJvdy9jb2wgb3JkZXIgZm9yIG90aGVyIGRpbWVuc2lvbnMuXG4gICAgY29uc3QgdGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQuaGVpZ2h0LCBpbnB1dExheW91dC53aWR0aF07XG5cbiAgICBpZiAodGV4U2hhcGUgIT0gbnVsbCAmJiBBcnJheVV0aWwuYXJyYXlzRXF1YWwoc2hhcGUsIHRleFNoYXBlKSkge1xuICAgICAgY29uc3QgdGV4TnVtUiA9IHRleFNoYXBlWzFdO1xuICAgICAgY29uc3QgdGV4TnVtQyA9IHRleFNoYXBlWzBdO1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIHZlYzIgdXYgPSAodmVjMihyb3csIGNvbCkgKyBoYWxmQ1IpIC8gdmVjMigke3RleE51bVJ9LjAsICR7dGV4TnVtQ30uMCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IG5ld1NoYXBlLCBrZXB0RGltcyB9ID0gc3F1ZWV6ZVNoYXBlKHNoYXBlIGFzIG51bWJlcltdKTtcbiAgICBjb25zdCBzcXVlZXplZFNoYXBlID0gbmV3U2hhcGU7XG4gICAgaWYgKHNxdWVlemVkU2hhcGUubGVuZ3RoIDwgc2hhcGUubGVuZ3RoKSB7XG4gICAgICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIHNxdWVlemVkU2hhcGUpO1xuICAgICAgLy8gRGVlcCBjb3B5IG9mIGlucHV0IHRleHR1cmUgbGF5b3V0LlxuICAgICAgY29uc3QgbmV3SW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0TGF5b3V0KSk7XG4gICAgICBuZXdJbnB1dExheW91dC51bnBhY2tlZFNoYXBlID0gbmV3SW5wdXRTaGFwZTtcblxuICAgICAgY29uc3QgcGFyYW1zID0gWydjb2wnLCAncm93J107XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgJHt0aGlzLmdldFVucGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgbmFtZSwgbmV3SW5wdXRMYXlvdXQpLnJvdXRpbmVCb2R5fVxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIHJldHVybiAke2Z1bmNOYW1lfSgke2dldFNxdWVlemVkUGFyYW1zKHBhcmFtcywga2VwdERpbXMpfSk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gdGV4U2hhcGVbMV07XG4gICAgY29uc3QgdGV4TnVtQyA9IHRleFNoYXBlWzBdO1xuICAgIGlmICh0ZXhOdW1DID09PSAxKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICAgICAgaW50IG9mZnNldF8ke25hbWV9ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke3RleE51bVJ9LCAke3RleE51bUN9KTtcbiAgICAgICAgICAgIGZsb2F0IGluZGV4ID0gZG90KHZlYzMocm93LCBjb2wsIG9mZnNldF8ke25hbWV9KSwgdmVjMygke3NoYXBlWzFdfSwgMSwgMSkpO1xuICAgICAgICAgICAgdmVjMiB1diA9IHZlYzIoMC41LCAoaW5kZXggKyAwLjUpIC8gJHt0ZXhOdW1SfS4wKTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJywgJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0J10pO1xuICAgIH1cblxuICAgIGlmICh0ZXhOdW1SID09PSAxKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICAgICAgaW50IG9mZnNldF8ke25hbWV9ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke3RleE51bVJ9LCAke3RleE51bUN9KTtcbiAgICAgICAgICAgIGZsb2F0IGluZGV4ID0gZG90KHZlYzMocm93LCBjb2wsIG9mZnNldF8ke25hbWV9KSwgdmVjMygke3NoYXBlWzFdfSwgMSwgMSkpO1xuICAgICAgICAgICAgdmVjMiB1diA9IHZlYzIoKGluZGV4ICsgMC41KSAvICR7dGV4TnVtQ30uMCwgMC41KTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJywgJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0J10pO1xuICAgIH1cblxuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICAgIGludCBpbmRleCA9IGNvbCAqICR7c2hhcGVbMV19ICsgcm93O1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFtcbiAgICAgICdjb29yZGluYXRlcy51dkZyb21GbGF0JyxcbiAgICAgICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJyxcbiAgICAgICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCcsXG4gICAgXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgM0Qgc25pcHBldC5cbiAgICovXG5cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHN0cmlkZTAgPSBzaGFwZVsxXSAqIHNoYXBlWzJdO1xuICAgIGNvbnN0IHN0cmlkZTEgPSBzaGFwZVsyXTtcblxuICAgIGNvbnN0IHsgbmV3U2hhcGUsIGtlcHREaW1zIH0gPSBzcXVlZXplU2hhcGUoc2hhcGUgYXMgbnVtYmVyW10pO1xuICAgIGNvbnN0IHNxdWVlemVkU2hhcGUgPSBuZXdTaGFwZTtcbiAgICBpZiAoc3F1ZWV6ZWRTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgc3F1ZWV6ZWRTaGFwZSk7XG4gICAgICBjb25zdCBwYXJhbXMgPSBbJ2JhdGNoJywgJ2NvbCcsICdyb3cnXTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG4gICAgICBjb25zdCByb3V0aW5lID0gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIG5hbWUsIG5ld0lucHV0TGF5b3V0KTtcbiAgICAgIC8vIFRPRE86IHJldmlzaXQgdGhlIGxvZ2ljIGhlcmUgdG8gbWFrZSBpdCBzaW1wbGVyXG4gICAgICBjb25zdCByZXZEaW1zID0ga2VwdERpbXMucmV2ZXJzZSgpO1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgICR7cm91dGluZS5yb3V0aW5lQm9keX1cbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgYmF0Y2gsIGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIHJldHVybiAke2Z1bmNOYW1lfSgke2dldFNxdWVlemVkUGFyYW1zKHBhcmFtcywgcmV2RGltcyl9KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgcm91dGluZS5kZXBlbmRlbmNpZXMpO1xuICAgIH1cblxuICAgIGNvbnN0IHRleE51bVIgPSBpbnB1dExheW91dC53aWR0aDtcbiAgICBjb25zdCB0ZXhOdW1DID0gaW5wdXRMYXlvdXQuaGVpZ2h0O1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgZGVwdGgsIGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIC8vIEV4cGxpY2l0bHkgdXNlIGludGVnZXIgb3BlcmF0aW9ucyBhcyBkb3QoKSBvbmx5IHdvcmtzIG9uIGZsb2F0cy5cbiAgICAgICAgICAgIGludCBpbmRleCA9IGRlcHRoICogJHtzdHJpZGUwfSArIGNvbCAqICR7c3RyaWRlMX0gKyByb3c7XG4gICAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3RleE51bVJ9LCAke3RleE51bUN9LCBpbmRleCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgW1xuICAgICAgJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLFxuICAgICAgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLFxuICAgICAgJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0JyxcbiAgICBdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA0RCBzbmlwcGV0LlxuICAgKi9cblxuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyNEQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgc3RyaWRlMiA9IHNoYXBlWzNdO1xuICAgIGNvbnN0IHN0cmlkZTEgPSBzaGFwZVsyXSAqIHN0cmlkZTI7XG4gICAgY29uc3Qgc3RyaWRlMCA9IHNoYXBlWzFdICogc3RyaWRlMTtcblxuICAgIC8vXG4gICAgLy8gVE9ETzogcmUtZW5hYmxlIHRoaXMgc2hvcnRjdXQgb25jZSB0aGUgaW5kZXggY2FsY3VsYXRpb24gYnVnIGlzIGZpeGVkLlxuICAgIC8vXG4gICAgLy8gY29uc3Qge25ld1NoYXBlLCBrZXB0RGltc30gPSBzcXVlZXplU2hhcGUoc2hhcGUgYXMgbnVtYmVyW10pO1xuICAgIC8vIGlmIChuZXdTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGgpIHtcbiAgICAvLyAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgbmV3U2hhcGUpO1xuICAgIC8vICAgY29uc3QgcGFyYW1zID0gWydyb3cnLCAnY29sJywgJ2RlcHRoJywgJ2RlcHRoMiddO1xuICAgIC8vICAgLy8gRGVlcCBjb3B5IG9mIGlucHV0IHRleHR1cmUgbGF5b3V0LlxuICAgIC8vICAgY29uc3QgbmV3SW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0TGF5b3V0KSk7XG4gICAgLy8gICBuZXdJbnB1dExheW91dC51bnBhY2tlZFNoYXBlID0gbmV3SW5wdXRTaGFwZTtcbiAgICAvLyAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAvLyAgICAgICAke3RoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCkucm91dGluZUJvZHl9XG4gICAgLy8gICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyKSB7XG4gICAgLy8gICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgIC8vICAgICAgIH1cbiAgICAvLyAgICAgYDtcbiAgICAvLyAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgLy8gICAgICAgc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLCAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgICAvLyB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMikge1xuICAgICAgICAgIGludCBpbmRleCA9IHJvdyAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICtcbiAgICAgICAgICAgICAgZGVwdGgyICogJHtzdHJpZGUyfSArIGRlcHRoO1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDVEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyNUQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgc3RyaWRlMyA9IHNoYXBlWzRdO1xuICAgIGNvbnN0IHN0cmlkZTIgPSBzaGFwZVszXSAqIHN0cmlkZTM7XG4gICAgY29uc3Qgc3RyaWRlMSA9IHNoYXBlWzJdICogc3RyaWRlMjtcbiAgICBjb25zdCBzdHJpZGUwID0gc2hhcGVbMV0gKiBzdHJpZGUxO1xuXG4gICAgY29uc3QgeyBuZXdTaGFwZSwga2VwdERpbXMgfSA9IHNxdWVlemVTaGFwZShzaGFwZSBhcyBudW1iZXJbXSk7XG4gICAgaWYgKG5ld1NoYXBlLmxlbmd0aCA8IHNoYXBlLmxlbmd0aCkge1xuICAgICAgY29uc3QgbmV3SW5wdXRTaGFwZSA9IHNxdWVlemVJbnB1dFNoYXBlKHNoYXBlLCBuZXdTaGFwZSk7XG4gICAgICBjb25zdCBwYXJhbXMgPSBbJ3JvdycsICdjb2wnLCAnZGVwdGgnLCAnZGVwdGgyJywgJ2RlcHRoMyddO1xuICAgICAgLy8gRGVlcCBjb3B5IG9mIGlucHV0IHRleHR1cmUgbGF5b3V0LlxuICAgICAgY29uc3QgbmV3SW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0TGF5b3V0KSk7XG4gICAgICBuZXdJbnB1dExheW91dC51bnBhY2tlZFNoYXBlID0gbmV3SW5wdXRTaGFwZTtcblxuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgICR7dGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIG5hbWUsIG5ld0lucHV0TGF5b3V0KS5yb3V0aW5lQm9keX1cbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIsIGludCBkZXB0aDMpIHtcbiAgICAgICAgICAgIHJldHVybiAke2Z1bmNOYW1lfSgke2dldFNxdWVlemVkUGFyYW1zKHBhcmFtcywga2VwdERpbXMpfSk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy51dkZyb21GbGF0J10pO1xuICAgIH1cblxuICAgIGNvbnN0IHRleE51bVIgPSBpbnB1dExheW91dC53aWR0aDtcbiAgICBjb25zdCB0ZXhOdW1DID0gaW5wdXRMYXlvdXQuaGVpZ2h0O1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzKSB7XG4gICAgICAgICAgaW50IGluZGV4ID0gcm93ICogJHtzdHJpZGUwfSArIGNvbCAqICR7c3RyaWRlMX0gKyBkZXB0aCAqICR7c3RyaWRlMn0gK1xuICAgICAgICAgIGRlcHRoMyAqICR7c3RyaWRlM30gKyBkZXB0aDI7XG4gICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSwgaW5kZXgpO1xuICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJywgJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgNkQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXI2RChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBzdHJpZGU0ID0gc2hhcGVbNV07XG4gICAgY29uc3Qgc3RyaWRlMyA9IHNoYXBlWzRdICogc3RyaWRlNDtcbiAgICBjb25zdCBzdHJpZGUyID0gc2hhcGVbM10gKiBzdHJpZGUzO1xuICAgIGNvbnN0IHN0cmlkZTEgPSBzaGFwZVsyXSAqIHN0cmlkZTI7XG4gICAgY29uc3Qgc3RyaWRlMCA9IHNoYXBlWzFdICogc3RyaWRlMTtcblxuICAgIGNvbnN0IHsgbmV3U2hhcGUsIGtlcHREaW1zIH0gPSBzcXVlZXplU2hhcGUoc2hhcGUgYXMgbnVtYmVyW10pO1xuICAgIGlmIChuZXdTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgbmV3U2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydyb3cnLCAnY29sJywgJ2RlcHRoJywgJ2RlcHRoMicsICdkZXB0aDMnLCAnZGVwdGg0J107XG4gICAgICAvLyBEZWVwIGNvcHkgb2YgaW5wdXQgdGV4dHVyZSBsYXlvdXQuXG4gICAgICBjb25zdCBuZXdJbnB1dExheW91dDogVGV4dHVyZUxheW91dCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaW5wdXRMYXlvdXQpKTtcbiAgICAgIG5ld0lucHV0TGF5b3V0LnVucGFja2VkU2hhcGUgPSBuZXdJbnB1dFNoYXBlO1xuXG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgICAke3RoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCkucm91dGluZUJvZHl9XG4gICAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsXG4gICAgICAgICAgICAgIGludCBkZXB0aDIsIGludCBkZXB0aDMsIGludCBkZXB0aDQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuICR7ZnVuY05hbWV9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMocGFyYW1zLCBrZXB0RGltcyl9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy51dkZyb21GbGF0J10pO1xuICAgIH1cblxuICAgIGNvbnN0IHRleE51bVIgPSBpbnB1dExheW91dC53aWR0aDtcbiAgICBjb25zdCB0ZXhOdW1DID0gaW5wdXRMYXlvdXQuaGVpZ2h0O1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsXG4gICAgICAgICAgICBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzLCBpbnQgZGVwdGg0KSB7XG4gICAgICAgICAgICBpbnQgaW5kZXggPSByb3cgKiAke3N0cmlkZTB9ICsgY29sICogJHtzdHJpZGUxfSArIGRlcHRoICogJHtzdHJpZGUyfSArXG4gICAgICAgICAgICBkZXB0aDIgKiAke3N0cmlkZTN9ICsgZGVwdGgzICogJHtzdHJpZGU0fSArIGRlcHRoNDtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFtcbiAgICAgICdjb29yZGluYXRlcy51dkZyb21GbGF0JyxcbiAgICAgICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJyxcbiAgICAgICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCcsXG4gICAgXSk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBpcyB0aGUgbWFpbiBmdW5jdGlvbiB0byBtYXAgZnJvbSB0aGUgZ2l2ZW4gdGV4dHVyZSBjb29yZGluYXRlcyAocyx0KVxuICAgKiB0byBsb2dpY2FsIGluZGljZXMgZm9yIHRoZSBvdXRwdXRcbiAgICogVGhlcmUgd2lsbCBvbmx5IGJlIG9uZSBzaW5nbGUgdmFyaWF0aW9uIG9mIHRoaXNcbiAgICogQWxzbyBzZWUgY29vcmRzVG9PZmZzZXQgYW5kIG9mZnNldFRvSW5kaWNlcyBmb3IgaW5wdXQtc3BlY2lmaWMgdmVyc2lvbnNcbiAgICovXG4gIHByb3RlY3RlZCB0b1ZlYygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBjb25zdCByYW5rID0gb3V0cHV0LnNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBzdHJpZGVzID0gb3V0cHV0LnN0cmlkZXM7XG4gICAgY29uc3QgeFNjYWxlID0gb3V0cHV0LndpZHRoO1xuICAgIGNvbnN0IHlTY2FsZSA9IG91dHB1dC5oZWlnaHQ7XG5cbiAgICBjb25zdCBzdHJpZGVzQmxvY2sgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAxOyArK2kpIHtcbiAgICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgICAgY1ske2l9XSA9IG9mZnNldCAvICR7c3RyaWRlc1tpXX07YCk7XG4gICAgICBzdHJpZGVzQmxvY2sucHVzaChgXG4gICAgICAgIG9mZnNldCAtPSBjWyR7aX1dICogJHtzdHJpZGVzW2ldfTtgKTtcbiAgICB9XG4gICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgICBjWyR7cmFuayAtIDF9XSA9IG9mZnNldDtgKTtcbiAgICBjb25zdCBib2R5ID0gYFxuICAgICAgdm9pZCB0b1ZlYyh2ZWMyIHRleENvb3Jkcywgb3V0IGludCBjWyR7cmFua31dKSB7XG4gICAgICAgIGludCBvZmZzZXQgPSBjb29yZHNUb09mZnNldCh0ZXhDb29yZHMsICR7eFNjYWxlfSwgJHt5U2NhbGV9KTtcbiAgICAgICAgJHtzdHJpZGVzQmxvY2suam9pbignJyl9XG4gICAgICB9XG4gICAgICB2b2lkIHRvVmVjKGludCBvZmZzZXQsIG91dCBpbnQgY1ske3Jhbmt9XSkge1xuICAgICAgICAke3N0cmlkZXNCbG9jay5qb2luKCcnKX1cbiAgICAgIH1cbiAgICBgO1xuICAgIHJldHVybiB7IHRvVmVjOiBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSwgWydjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKSB9O1xuICB9XG4gIC8qKlxuICAgKiBUaGVzZSBhcmUgdmFsdWUgZ2V0dGVyIGZ1bmN0aW9ucyBnZW5lcmF0ZWQgZm9yIGVhY2ggaW5wdXRcbiAgICogRWFjaCBmdW5jdGlvbiBpcyBoYXJkd2lyZWQgdG8gdGhlIG5hbWUgYW5kIGRpbWVuc2lvbnMgb2YgdGhlIGlucHV0XG4gICAqIEFuICdfVCcgdmFyaWF0aW9uIGlzIGFsc28gcHJvZHVjZWQgd2hpY2ggYWNjZXNzZXMgdmFsdWVzIGFzIGlmIHRoZVxuICAgKiBpbnB1dCB3YXMgdHJhbnNwb3NlZFxuICAgKi9cbiAgcHJvdGVjdGVkIHZhbHVlRnJvbSgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBsYXlvdXQgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXTtcbiAgICAgIGNvbnN0IHNoYXBlID0gbGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoID4gMCA/IGxheW91dC51bnBhY2tlZFNoYXBlIDogbGF5b3V0LnNoYXBlO1xuICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgIGxldCBmdW5jTmFtZSA9IGBfJHtuYW1lfWA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKHRoaXMuZ2V0VmFsdWVGcm9tU2luZ2xlKG5hbWUsIHJhbmssIGxheW91dC53aWR0aCwgbGF5b3V0LmhlaWdodCwgZmFsc2UpLCBbXG4gICAgICAgIGBzaGFwZVV0aWxzLmluZGljZXNUb09mZnNldCR7ZnVuY05hbWV9YCxcbiAgICAgICAgJ2Nvb3JkaW5hdGVzLm9mZnNldFRvQ29vcmRzJyxcbiAgICAgICAgJ2ZyYWdjb2xvci5nZXRDb2xvckFzRmxvYXQnLFxuICAgICAgXSk7XG4gICAgICBmdW5jTmFtZSA9IGZ1bmNOYW1lICsgJ19UJztcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUodGhpcy5nZXRWYWx1ZUZyb21TaW5nbGUobmFtZSwgcmFuaywgbGF5b3V0LndpZHRoLCBsYXlvdXQuaGVpZ2h0LCB0cnVlKSwgW1xuICAgICAgICBgc2hhcGVVdGlscy5pbmRpY2VzVG9PZmZzZXQke2Z1bmNOYW1lfWAsXG4gICAgICAgICdjb29yZGluYXRlcy5vZmZzZXRUb0Nvb3JkcycsXG4gICAgICAgICdmcmFnY29sb3IuZ2V0Q29sb3JBc0Zsb2F0JyxcbiAgICAgIF0pO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgLyoqXG4gICAqIFByb2R1Y2VzIG9uZSB2YWx1ZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIHRoZSBuYW1lIGFuZCByYW5rIGdpdmVuXG4gICAqIElmIGEgdHJhbnNwb3NlIGlzIHNldCBwcm9wZXIgb2Zmc2V0VG9Db29yZHMgbWFwcGluZyB3aWxsIGJlIHVzZWRcbiAgICogQHBhcmFtIG5hbWUgbmFtZSBvZiB0aGUgZnVuY3Rpb25cbiAgICogQHBhcmFtIHJhbmsgcmFuayBvZiB0aGUgaW5wdXRcbiAgICogQHBhcmFtIHRyYW5zcG9zZSB3aGV0aGVyIG9yIG5vdCBzaG91bGQgZ2VuZXJhdGUgYSB0cmFuc3Bvc2UgdmFyaWF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VmFsdWVGcm9tU2luZ2xlKFxuICAgIHZhck5hbWU6IHN0cmluZyxcbiAgICByYW5rOiBudW1iZXIsXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICB0cmFuc3Bvc2U6IGJvb2xlYW4sXG4gICk6IHN0cmluZyB7XG4gICAgbGV0IG5hbWUgPSBgXyR7dmFyTmFtZX1gO1xuICAgIGlmICh0cmFuc3Bvc2UpIHtcbiAgICAgIG5hbWUgPSBuYW1lICsgJ19UJztcbiAgICB9XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICByZXR1cm4gYFxuICAgICAgICBmbG9hdCAke25hbWV9KGludCBtWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IG9mZnNldCA9IGluZGljZXNUb09mZnNldCR7bmFtZX0obSk7XG4gICAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhvZmZzZXQsICR7d2lkdGh9LCAke2hlaWdodH0pO1xuICAgICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KCR7dmFyTmFtZX0sIGNvb3JkcykpO1xuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBgO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2R1Y2VzIGEgcGFja2VkIHZhbHVlIGdldHRlciBmdW5jdGlvbiBmb3IgdGhlIG5hbWUgYW5kIHJhbmsgZ2l2ZW5cbiAgICogSWYgYSB0cmFuc3Bvc2UgaXMgc2V0IHByb3BlciBvZmZzZXRUb0Nvb3JkcyBtYXBwaW5nIHdpbGwgYmUgdXNlZFxuICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9mIHRoZSBmdW5jdGlvblxuICAgKiBAcGFyYW0gcmFuayByYW5rIG9mIHRoZSBpbnB1dFxuICAgKiBAcGFyYW0gdHJhbnNwb3NlIHdoZXRoZXIgb3Igbm90IHNob3VsZCBnZW5lcmF0ZSBhIHRyYW5zcG9zZSB2YXJpYXRpb25cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRWYWx1ZUZyb20oXG4gICAgdmFyTmFtZTogc3RyaW5nLFxuICAgIHJhbms6IG51bWJlcixcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIHRyYW5zcG9zZTogYm9vbGVhbixcbiAgKTogc3RyaW5nIHtcbiAgICBsZXQgbmFtZSA9IGBfJHt2YXJOYW1lfV9QYWNrYDtcbiAgICBpZiAodHJhbnNwb3NlKSB7XG4gICAgICBuYW1lID0gbmFtZSArICdfVCc7XG4gICAgfVxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgcmV0dXJuIGBcbiAgICAgICAgdmVjNCAke25hbWV9KGludCBtWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IG9mZnNldCA9IGluZGljZXNUb09mZnNldF8ke3Zhck5hbWV9KG0pO1xuICAgICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHt2YXJOYW1lfSwgY29vcmRzKTtcbiAgICAgICAgfVxuICAgICAgICBgO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZSB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5cbi8qKlxuICogVGhpcyBHTFNMIGxpYnJhcnkgaGFuZGxlcyByb3V0aW5lcyBjb252ZXJ0aW5nXG4gKiBmbG9hdDMyIHRvL2Zyb20gVW5zaWduZWQgYnl0ZSBvciBmbG9hdCAxNlxuICovXG5leHBvcnQgY2xhc3MgRW5jb2RpbmdHbHNsTGliIGV4dGVuZHMgR2xzbExpYiB7XG4gIGNvbnN0cnVjdG9yKGNvbnRleHQ6IEdsc2xDb250ZXh0KSB7XG4gICAgc3VwZXIoY29udGV4dCk7XG4gIH1cbiAgZ2V0RnVuY3Rpb25zKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIHJldHVybiB7IC4uLnRoaXMuZW5jb2RlRmxvYXQzMigpLCAuLi50aGlzLmRlY29kZUZsb2F0MzIoKSB9O1xuICB9XG4gIGdldEN1c3RvbVR5cGVzKCk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgICByZXR1cm4ge307XG4gIH1cbiAgcHJvdGVjdGVkIGVuY29kZUZsb2F0MzIoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGVuY29kZTogbmV3IEdsc2xMaWJSb3V0aW5lKGBoaWdocCB2ZWM0IGVuY29kZShoaWdocCBmbG9hdCBmKSB7XG4gICAgICAgIHJldHVybiB2ZWM0KGYsIDAuMCwgMC4wLCAwLjApO1xuICAgICAgfVxuICAgICAgICBgKSxcbiAgICB9O1xuICB9XG4gIHByb3RlY3RlZCBkZWNvZGVGbG9hdDMyKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIHJldHVybiB7XG4gICAgICBkZWNvZGU6IG5ldyBHbHNsTGliUm91dGluZShgaGlnaHAgZmxvYXQgZGVjb2RlKGhpZ2hwIHZlYzQgcmdiYSkge1xuICAgICAgICByZXR1cm4gcmdiYS5yO1xuICAgICAgfVxuICAgICAgICBgKSxcbiAgICB9O1xuICB9XG4gIC8qKlxuICAgKiByZXR1cm5zIHRoZSByb3V0aW5lIHRvIGVuY29kZSBlbmNvZGUgYSAzMmJpdCBmbG9hdCB0byBhIHZlYzQgKG9mIHVuc2lnbmVkIGJ5dGVzKVxuICAgKiBAY3JlZGl0OiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy83MDU5OTYyL2hvdy1kby1pLWNvbnZlcnQtYS12ZWM0LXJnYmEtdmFsdWUtdG8tYS1mbG9hdFxuICAgKi9cbiAgcHJvdGVjdGVkIGVuY29kZVVpbnQ4KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IGVuZGlhbm5lc3MgPSBFbmNvZGluZ0dsc2xMaWIuaXNMaXR0bGVFbmRpYW4oKSA/ICdyZ2JhLnJnYmE9cmdiYS5hYmdyOycgOiAnJztcbiAgICByZXR1cm4ge1xuICAgICAgZW5jb2RlOiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgaGlnaHAgdmVjNCBlbmNvZGUoaGlnaHAgZmxvYXQgZikge1xuICAgICAgICBoaWdocCBmbG9hdCBGID0gYWJzKGYpO1xuICAgICAgICBoaWdocCBmbG9hdCBTaWduID0gc3RlcCgwLjAsLWYpO1xuICAgICAgICBoaWdocCBmbG9hdCBFeHBvbmVudCA9IGZsb29yKGxvZzIoRikpO1xuICAgICAgICBoaWdocCBmbG9hdCBNYW50aXNzYSA9IChleHAyKC0gRXhwb25lbnQpICogRik7XG4gICAgICAgIEV4cG9uZW50ID0gZmxvb3IobG9nMihGKSArIDEyNy4wKSArIGZsb29yKGxvZzIoTWFudGlzc2EpKTtcbiAgICAgICAgaGlnaHAgdmVjNCByZ2JhO1xuICAgICAgICByZ2JhWzBdID0gMTI4LjAgKiBTaWduICArIGZsb29yKEV4cG9uZW50KmV4cDIoLTEuMCkpO1xuICAgICAgICByZ2JhWzFdID0gMTI4LjAgKiBtb2QoRXhwb25lbnQsMi4wKSArIG1vZChmbG9vcihNYW50aXNzYSoxMjguMCksMTI4LjApO1xuICAgICAgICByZ2JhWzJdID0gZmxvb3IobW9kKGZsb29yKE1hbnRpc3NhKmV4cDIoMjMuMCAtOC4wKSksZXhwMig4LjApKSk7XG4gICAgICAgIHJnYmFbM10gPSBmbG9vcihleHAyKDIzLjApKm1vZChNYW50aXNzYSxleHAyKC0xNS4wKSkpO1xuICAgICAgICAke2VuZGlhbm5lc3N9XG4gICAgICAgIHJnYmEgPSByZ2JhIC8gMjU1LjA7IC8vIHZhbHVlcyBuZWVkIHRvIGJlIG5vcm1hbGl6ZWQgdG8gWzAsMV1cbiAgICAgICAgcmV0dXJuIHJnYmE7XG4gICAgfVxuICAgICAgICBgKSxcbiAgICB9O1xuICB9XG4gIC8qKlxuICAgKiByZXR1cm5zIHRoZSByb3V0aW5lIHRvIGVuY29kZSBhIHZlYzQgb2YgdW5zaWduZWQgYnl0ZXMgdG8gZmxvYXQzMlxuICAgKiBAY3JlZGl0OiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy83MDU5OTYyL2hvdy1kby1pLWNvbnZlcnQtYS12ZWM0LXJnYmEtdmFsdWUtdG8tYS1mbG9hdFxuICAgKi9cbiAgcHJvdGVjdGVkIGRlY29kZVVpbnQ4KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IGVuZGlhbm5lc3MgPSBFbmNvZGluZ0dsc2xMaWIuaXNMaXR0bGVFbmRpYW4oKSA/ICdyZ2JhLnJnYmE9cmdiYS5hYmdyOycgOiAnJztcbiAgICByZXR1cm4ge1xuICAgICAgZGVjb2RlOiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgICBoaWdocCBmbG9hdCBkZWNvZGUoaGlnaHAgdmVjNCByZ2JhKSB7XG4gICAgICAgICAgcmdiYSA9IHJnYmEgKiAyNTUuMDsgLy8gdmFsdWVzIG5lZWQgdG8gYmUgZGUtbm9ybWFsaXplZCBmcm9tIFswLDFdIHRvIFswLDI1NV1cbiAgICAgICAgICAke2VuZGlhbm5lc3N9XG4gICAgICAgICAgaGlnaHAgZmxvYXQgU2lnbiA9IDEuMCAtIHN0ZXAoMTI4LjAscmdiYVswXSkqMi4wO1xuICAgICAgICAgIGhpZ2hwIGZsb2F0IEV4cG9uZW50ID0gMi4wICogbW9kKHJnYmFbMF0sMTI4LjApICsgc3RlcCgxMjguMCxyZ2JhWzFdKSAtIDEyNy4wO1xuICAgICAgICAgIGhpZ2hwIGZsb2F0IE1hbnRpc3NhID0gbW9kKHJnYmFbMV0sMTI4LjApKjY1NTM2LjAgKyByZ2JhWzJdKjI1Ni4wICtyZ2JhWzNdICsgZmxvYXQoMHg4MDAwMDApO1xuICAgICAgICAgIGhpZ2hwIGZsb2F0IFJlc3VsdCA9ICBTaWduICogZXhwMihFeHBvbmVudCkgKiAoTWFudGlzc2EgKiBleHAyKC0yMy4wICkpO1xuICAgICAgICAgIHJldHVybiBSZXN1bHQ7XG4gICAgICB9XG4gICAgICAgIGApLFxuICAgIH07XG4gIH1cbiAgLyoqXG4gICAqIERldGVybWluZXMgaWYgdGhlIG1hY2hpbmUgaXMgbGl0dGxlIGVuZGlhbiBvciBub3RcbiAgICogQGNyZWRpdDogaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vVG9vVGFsbE5hdGUvNDc1MDk1M1xuICAgKi9cbiAgc3RhdGljIGlzTGl0dGxlRW5kaWFuKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGIgPSBuZXcgQXJyYXlCdWZmZXIoNCk7XG4gICAgY29uc3QgYSA9IG5ldyBVaW50MzJBcnJheShiKTtcbiAgICBjb25zdCBjID0gbmV3IFVpbnQ4QXJyYXkoYik7XG4gICAgYVswXSA9IDB4ZGVhZGJlZWY7XG4gICAgaWYgKGNbMF0gPT09IDB4ZWYpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAoY1swXSA9PT0gMHhkZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gZW5kaWFubmVzcycpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZSB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi9nbHNsLXNvdXJjZSc7XG5cbi8qKlxuICogVGhpcyBHTFNMIGxpYnJhcnkgaGFuZGxlcyByb3V0aW5lcyBhcm91bmQgcmVhZGluZyBhIHRleGxldCBhbmQgd3JpdGluZyB0byBpdFxuICogUmVhZGluZyBhbmQgd3JpdGluZyBjb3VsZCBiZSBtb3JlIHRoYW4ganVzdCBkZWFsaW5nIHdpdGggb25lIGNoYW5uZWxcbiAqIEl0IG1heSByZXF1aXJlIGVuY29kaW5nL2RlY29kaW5nIHRvL2Zyb20gNCBjaGFubmVscyBpbnRvIG9uZVxuICovXG5leHBvcnQgY2xhc3MgRnJhZ0NvbG9yR2xzbExpYiBleHRlbmRzIEdsc2xMaWIge1xuICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBHbHNsQ29udGV4dCkge1xuICAgIHN1cGVyKGNvbnRleHQpO1xuICB9XG4gIGdldEZ1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4geyAuLi50aGlzLnNldEZyYWdDb2xvcigpLCAuLi50aGlzLmdldENvbG9yQXNGbG9hdCgpIH07XG4gIH1cbiAgZ2V0Q3VzdG9tVHlwZXMoKTogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBwcm90ZWN0ZWQgc2V0RnJhZ0NvbG9yKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNldEZyYWdDb2xvcjogbmV3IEdsc2xMaWJSb3V0aW5lKFxuICAgICAgICBgXG4gICAgICAgIHZvaWQgc2V0RnJhZ0NvbG9yKGZsb2F0IHZhbHVlKSB7XG4gICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IGVuY29kZSh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgYCxcbiAgICAgICAgWydlbmNvZGluZy5lbmNvZGUnXSxcbiAgICAgICksXG4gICAgfTtcbiAgfVxuICBwcm90ZWN0ZWQgZ2V0Q29sb3JBc0Zsb2F0KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIHJldHVybiB7XG4gICAgICBnZXRDb2xvckFzRmxvYXQ6IG5ldyBHbHNsTGliUm91dGluZShcbiAgICAgICAgYFxuICAgICAgICBmbG9hdCBnZXRDb2xvckFzRmxvYXQodmVjNCBjb2xvcikge1xuICAgICAgICAgICAgcmV0dXJuIGRlY29kZShjb2xvcik7XG4gICAgICAgIH1cbiAgICAgICAgYCxcbiAgICAgICAgWydlbmNvZGluZy5kZWNvZGUnXSxcbiAgICAgICksXG4gICAgfTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmUgfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuXG4vKipcbiAqIEdMU0wgTGlicmFyeSByZXNwb25zaWJsZSBmb3IgZGF0YSB0eXBlcyBhbmQgcm91dGluZXMgZm9yIG1hbmlwdWxhdGluZ1xuICogY29vcmRpbmF0ZXMgYW5kIG1hcHBpbmcgdG8vZnJvbSB0ZW5zb3IgaW5kaWNlc1xuICovXG5leHBvcnQgY2xhc3MgU2hhcGVVdGlsc0dsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMuYmNhc3RJbmRleCgpLFxuICAgICAgLi4udGhpcy5iY2FzdE1hdG11bEluZGV4KCksXG4gICAgICAuLi50aGlzLm9mZnNldFRvSW5kaWNlcygpLFxuICAgICAgLi4udGhpcy5pbmRpY2VzVG9PZmZzZXQoKSxcbiAgICAgIC4uLnRoaXMuaW5jcmVtZW50SW5kaWNlcygpLFxuICAgIH07XG4gIH1cbiAgZ2V0Q3VzdG9tVHlwZXMoKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIHByb3RlY3RlZCBiY2FzdEluZGV4KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dHB1dFJhbmsgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgY29uc3Qgc2hhcGUgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS51bnBhY2tlZFNoYXBlO1xuICAgICAgaWYgKHNoYXBlLmxlbmd0aCA8PSBvdXRwdXRSYW5rKSB7XG4gICAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGRpbU9mZnNldCA9IG91dHB1dFJhbmsgLSByYW5rO1xuICAgICAgICBjb25zdCBmdW5jTmFtZSA9IGBiY2FzdEluZGljZXNfJHtuYW1lfWA7XG4gICAgICAgIGxldCBibG9jayA9ICcnO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7ICsraSkge1xuICAgICAgICAgIGJsb2NrICs9IGBcbiAgICAgICAgICByZWFsSW5kaWNlc1ske2l9XSA9IGludCggbW9kKGZsb2F0KGJjYXN0ZWRJbmRpY2VzWyR7ZGltT2Zmc2V0ICsgaX1dKSwgJHtzaGFwZVtpXX0uMCkgKTtcbiAgICAgICAgICBgO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICAgIHZvaWQgJHtmdW5jTmFtZX0gKGludCBiY2FzdGVkSW5kaWNlc1ske291dHB1dFJhbmt9XSwgb3V0IGludCByZWFsSW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgICR7YmxvY2t9XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShib2R5KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHByb3RlY3RlZCBiY2FzdE1hdG11bEluZGV4KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dHB1dFJhbmsgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgY29uc3Qgc2hhcGUgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS5zaGFwZTtcbiAgICAgIGlmICghKHNoYXBlLmxlbmd0aCA8IDIgfHwgc2hhcGUubGVuZ3RoID4gb3V0cHV0UmFuaykpIHtcbiAgICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgICAgY29uc3QgZGltT2Zmc2V0ID0gb3V0cHV0UmFuayAtIHJhbms7XG4gICAgICAgIGNvbnN0IGZ1bmNOYW1lID0gYGJjYXN0TWF0bXVsSW5kaWNlc18ke25hbWV9YDtcbiAgICAgICAgbGV0IGJsb2NrID0gJyc7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDI7ICsraSkge1xuICAgICAgICAgIGJsb2NrICs9IGBcbiAgICAgICAgICByZWFsSW5kaWNlc1ske2l9XSA9IGludCggbW9kKGZsb2F0KGJjYXN0ZWRJbmRpY2VzWyR7ZGltT2Zmc2V0ICsgaX1dKSwgJHtzaGFwZVtpXX0uMCkgKTtcbiAgICAgICAgICBgO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICAgIHZvaWQgJHtmdW5jTmFtZX0oaW50IGJjYXN0ZWRJbmRpY2VzWyR7b3V0cHV0UmFua31dLCBvdXQgaW50IHJlYWxJbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgJHtibG9ja31cbiAgICAgICAgICByZWFsSW5kaWNlc1ske3JhbmsgLSAxfV0gPSBiY2FzdGVkSW5kaWNlc1ske291dHB1dFJhbmsgLSAxfV07XG4gICAgICAgICAgcmVhbEluZGljZXNbJHtyYW5rIC0gMn1dID0gYmNhc3RlZEluZGljZXNbJHtvdXRwdXRSYW5rIC0gMn1dO1xuICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBwcm90ZWN0ZWQgaW5kaWNlc1RvT2Zmc2V0KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc2hhcGU7XG4gICAgICBjb25zdCBzdHJpZGVzID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc3RyaWRlcztcbiAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICBsZXQgZnVuY05hbWUgPSBgaW5kaWNlc1RvT2Zmc2V0XyR7bmFtZX1gO1xuICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShTaGFwZVV0aWxzR2xzbExpYi5pbmRleFRvT2Zmc2V0U2luZ2xlKGZ1bmNOYW1lLCByYW5rLCBzdHJpZGVzKSk7XG4gICAgICBmdW5jTmFtZSA9IGBpbmRpY2VzVG9PZmZzZXRfJHtuYW1lfV9UYDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgIFNoYXBlVXRpbHNHbHNsTGliLmluZGV4VG9PZmZzZXRTaW5nbGUoZnVuY05hbWUsIHJhbmssIHN0cmlkZXMuc2xpY2UoKS5yZXZlcnNlKCkpLFxuICAgICAgKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHN0YXRpYyBpbmRleFRvT2Zmc2V0U2luZ2xlKG5hbWU6IHN0cmluZywgcmFuazogbnVtYmVyLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSk6IHN0cmluZyB7XG4gICAgbGV0IGJsb2NrID0gJyc7XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgYmxvY2sgKz0gYFxuICAgICAgICBvZmZzZXQgKz0gaW5kaWNlc1ske2l9XSAqICR7c3RyaWRlc1tpXX07XG4gICAgICAgIGA7XG4gICAgfVxuICAgIHJldHVybiBgXG4gICAgICBpbnQgJHtuYW1lfShpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICBpbnQgb2Zmc2V0ID0gMDtcbiAgICAgICAgJHtibG9ja31cbiAgICAgICAgcmV0dXJuIG9mZnNldDtcbiAgICAgIH1cbiAgICAgIGA7XG4gIH1cbiAgcHJvdGVjdGVkIG9mZnNldFRvSW5kaWNlcygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBzaGFwZSA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnNoYXBlO1xuICAgICAgY29uc3Qgc3RyaWRlcyA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnN0cmlkZXM7XG4gICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgbGV0IGZ1bmNOYW1lID0gYG9mZnNldFRvSW5kaWNlc18ke25hbWV9YDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoU2hhcGVVdGlsc0dsc2xMaWIub2Zmc2V0VG9JbmRpY2VzU2luZ2xlKGZ1bmNOYW1lLCByYW5rLCBzdHJpZGVzKSk7XG4gICAgICBmdW5jTmFtZSA9IGBvZmZzZXRUb0luZGljZXNfJHtuYW1lfV9UYDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgIFNoYXBlVXRpbHNHbHNsTGliLm9mZnNldFRvSW5kaWNlc1NpbmdsZShmdW5jTmFtZSwgcmFuaywgc3RyaWRlcy5zbGljZSgpLnJldmVyc2UoKSksXG4gICAgICApO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgc3RhdGljIG9mZnNldFRvSW5kaWNlc1NpbmdsZShuYW1lOiBzdHJpbmcsIHJhbms6IG51bWJlciwgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10pOiBzdHJpbmcge1xuICAgIGNvbnN0IHN0cmlkZXNCbG9jayA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDE7ICsraSkge1xuICAgICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgaW5kaWNlc1ske2l9XSA9IG9mZnNldCAvICR7c3RyaWRlc1tpXX07YCk7XG4gICAgICBzdHJpZGVzQmxvY2sucHVzaChgXG4gICAgICAgIG9mZnNldCAtPSBpbmRpY2VzWyR7aX1dICogJHtzdHJpZGVzW2ldfTtgKTtcbiAgICB9XG4gICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgaW5kaWNlc1ske3JhbmsgLSAxfV0gPSBvZmZzZXQ7YCk7XG4gICAgcmV0dXJuIGBcbiAgICAgIHZvaWQgJHtuYW1lfShpbnQgb2Zmc2V0LCBvdXQgaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgJHtzdHJpZGVzQmxvY2suam9pbignJyl9XG4gICAgICB9XG4gICAgICBgO1xuICB9XG4gIHByb3RlY3RlZCBpbmNyZW1lbnRJbmRpY2VzKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc2hhcGU7XG4gICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgY29uc3QgZnVuY05hbWUgPSBgaW5jcmVtZW50SW5kaWNlc18ke25hbWV9YDtcbiAgICAgIGxldCBzaGFwZUluaXQgPSAnJztcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgICAgIHNoYXBlSW5pdCArPSBgXG4gICAgICAgIHNoYXBlWyR7aX1dID0gJHtzaGFwZVtpXX07YDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICAgIHZvaWQgJHtmdW5jTmFtZX0oaW50IGF4aXMsIG91dCBpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBzaGFwZVske3Jhbmt9XTtcbiAgICAgICAgICAke3NoYXBlSW5pdH07XG4gICAgICAgICAgZm9yKGludCBpID0gJHtyYW5rfSAtMSA7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICBpZihpID4gYXhpcykgY29udGludWU7XG4gICAgICAgICAgICBpbmRpY2VzW2ldICs9IDE7XG4gICAgICAgICAgICBpZihpbmRpY2VzW2ldIDwgc2hhcGVbaV0pIHtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbmRpY2VzW2ldID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmUgfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuXG4vKipcbiAqIEdMU0wgTGlicmFyeSByZXNwb25zaWJsZSBmb3IgdmVjIHJvdXRpbmVzXG4gKiBWZWMgaXMgYW4gdmFyaWJsZSBsZW5ndGggaW50IGFycmF5LiBUaGUgbGVuZ3RoIGlzIGZpeGVkIGF0IHRoZSB0aW1lIG9mXG4gKiBnZW5lcmF0aW5nIHRoZSBsaWJyYXJ5IGZ1bmN0aW9ucyBmcm9tIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBvdXRwdXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBWZWNHbHNsTGliIGV4dGVuZHMgR2xzbExpYiB7XG4gIGNvbnN0cnVjdG9yKGNvbnRleHQ6IEdsc2xDb250ZXh0KSB7XG4gICAgc3VwZXIoY29udGV4dCk7XG4gIH1cbiAgZ2V0Q3VzdG9tVHlwZXMoKTogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgcmV0dXJuIHsgLi4udGhpcy5iaW5hcnlWZWNGdW5jdGlvbnMoKSwgLi4udGhpcy5jb3B5VmVjKCksIC4uLnRoaXMuc2V0VmVjSXRlbSgpLCAuLi50aGlzLmdldFZlY0l0ZW0oKSB9O1xuICB9XG4gIHByb3RlY3RlZCBiaW5hcnlWZWNGdW5jdGlvbnMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgY29uc3QgcmFuayA9IG91dHB1dExheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgbmFtZU9wOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfSA9IHsgYWRkOiAnKz0nLCBzdWI6ICctPScsIG11bDogJyo9JywgZGl2OiAnLz0nIH07XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgZm9yIChjb25zdCBuYW1lIGluIG5hbWVPcCkge1xuICAgICAgY29uc3QgZm5hbWUgPSBgJHtuYW1lfVZlY2A7XG4gICAgICBsZXQgYXNzaWdubWVudEJsb2NrID0gJyc7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7ICsraSkge1xuICAgICAgICBhc3NpZ25tZW50QmxvY2sgKz0gYFxuICAgICAgICAgIGRlc3RbJHtpfV0gJHtuYW1lT3BbbmFtZV19IHNyY1ske2l9XTtcbiAgICAgICAgICBgO1xuICAgICAgfVxuICAgICAgY29uc3QgYm9keSA9IGBcbiAgICAgICAgdm9pZCAke2ZuYW1lfShpbnQgc3JjWyR7cmFua31dLCBvdXQgaW50IGRlc3RbJHtyYW5rfV0pIHtcbiAgICAgICAgICAke2Fzc2lnbm1lbnRCbG9ja31cbiAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmVzdWx0W2ZuYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShib2R5KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHByb3RlY3RlZCBjb3B5VmVjKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dHB1dExheW91dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGxldCBhc3NpZ25tZW50QmxvY2sgPSAnJztcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7ICsraSkge1xuICAgICAgYXNzaWdubWVudEJsb2NrICs9IGBcbiAgICAgICAgZGVzdFske2l9XSA9IHNyY1ske2l9XTtcbiAgICAgICAgYDtcbiAgICB9XG4gICAgY29uc3QgYm9keSA9IGBcbiAgICAgIHZvaWQgY29weVZlYyhpbnQgc3JjWyR7cmFua31dLCBvdXQgaW50IGRlc3RbJHtyYW5rfV0pIHtcbiAgICAgICAgJHthc3NpZ25tZW50QmxvY2t9XG4gICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiB7IGNvcHlWZWM6IG5ldyBHbHNsTGliUm91dGluZShib2R5KSB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIHNldFZlY0l0ZW0oKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgY29uc3QgcmFuayA9IG91dHB1dExheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgbGV0IGJsb2NrID0gYFxuICAgICAgICBpZihpbmRleCA8IDApXG4gICAgICAgICAgICBpbmRleCA9JHtyYW5rfSArIGluZGV4O1xuICAgICAgICBpZiAoaW5kZXggPT0gMClcbiAgICAgICAgICAgIG1bMF0gPSB2YWx1ZTtcbiAgICAgICAgYDtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHJhbmsgLSAxOyArK2kpIHtcbiAgICAgIGJsb2NrICs9IGBcbiAgICAgICAgZWxzZSBpZiAoaW5kZXggPT0gJHtpfSlcbiAgICAgICAgICAgIG1bJHtpfV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIGA7XG4gICAgfVxuICAgIGJsb2NrICs9IGBcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgbVske3JhbmsgLSAxfV0gPSB2YWx1ZTtcbiAgICAgICAgYDtcbiAgICBjb25zdCBib2R5ID0gYFxuICAgICAgdm9pZCBzZXRWZWNJdGVtKG91dCBpbnQgbVske3Jhbmt9XSwgaW50IGluZGV4LCBpbnQgdmFsdWUpIHtcbiAgICAgICAgJHtibG9ja31cbiAgICAgIH1cbiAgICAgICAgYDtcbiAgICByZXR1cm4geyBzZXRWZWNJdGVtOiBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSkgfTtcbiAgfVxuICBwcm90ZWN0ZWQgZ2V0VmVjSXRlbSgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBjb25zdCByYW5rID0gb3V0cHV0TGF5b3V0LnNoYXBlLmxlbmd0aDtcbiAgICBsZXQgYmxvY2sgPSBgXG4gICAgICAgIGlmKGluZGV4IDwgMClcbiAgICAgICAgICAgIGluZGV4ID0gJHtyYW5rfSArIGluZGV4O1xuICAgICAgICBpZiAoaW5kZXggPT0gMClcbiAgICAgICAgICAgIHJldHVybiBtWzBdO1xuICAgICAgYDtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHJhbmsgLSAxOyArK2kpIHtcbiAgICAgIGJsb2NrICs9IGBcbiAgICAgICAgZWxzZSBpZiAoaW5kZXggPT0gJHtpfSlcbiAgICAgICAgICAgIHJldHVybiBtWyR7aX1dO1xuICAgICAgYDtcbiAgICB9XG4gICAgYmxvY2sgKz0gYFxuICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4gbVske3JhbmsgLSAxfV07XG4gICAgICAgIGA7XG4gICAgY29uc3QgYm9keSA9IGBcbiAgICAgIGludCBnZXRWZWNJdGVtKGludCBtWyR7cmFua31dLCBpbnQgaW5kZXgpIHtcbiAgICAgICAgJHtibG9ja31cbiAgICAgIH1cbiAgICBgO1xuICAgIHJldHVybiB7IGdldFZlY0l0ZW06IG5ldyBHbHNsTGliUm91dGluZShib2R5KSB9O1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IENvb3Jkc0dsc2xMaWIgfSBmcm9tICcuL2dsc2wtY29vcmRpbmF0ZS1saWInO1xuaW1wb3J0IHsgR2xzbENvbnRleHQsIEdsc2xMaWIgfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgRW5jb2RpbmdHbHNsTGliIH0gZnJvbSAnLi9nbHNsLWVuY29kaW5nLWxpYic7XG5pbXBvcnQgeyBGcmFnQ29sb3JHbHNsTGliIH0gZnJvbSAnLi9nbHNsLWZyYWdjb2xvci1saWInO1xuaW1wb3J0IHsgU2hhcGVVdGlsc0dsc2xMaWIgfSBmcm9tICcuL2dsc2wtc2hhcGUtdXRpbHMtbGliJztcbmltcG9ydCB7IFZlY0dsc2xMaWIgfSBmcm9tICcuL2dsc2wtdmVjLWxpYic7XG5cbmV4cG9ydCBjb25zdCBnbHNsUmVnaXN0cnk6IHsgW25hbWU6IHN0cmluZ106IG5ldyAoY29udGV4dDogR2xzbENvbnRleHQpID0+IEdsc2xMaWIgfSA9IHtcbiAgZW5jb2Rpbmc6IEVuY29kaW5nR2xzbExpYixcbiAgZnJhZ2NvbG9yOiBGcmFnQ29sb3JHbHNsTGliLFxuICB2ZWM6IFZlY0dsc2xMaWIsXG4gIHNoYXBlVXRpbHM6IFNoYXBlVXRpbHNHbHNsTGliLFxuICBjb29yZGluYXRlczogQ29vcmRzR2xzbExpYixcbiAgLy8gICdhcnJheXMnOiBBcnJheUdsc2xTTGliXG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmVOb2RlLCBUb3BvbG9naWNhbFNvcnRHbHNsUm91dGluZXMgfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgcmVwbGFjZUlubGluZXMgfSBmcm9tICcuL2dsc2wtZnVuY3Rpb24taW5saW5lcic7XG5pbXBvcnQgeyBnbHNsUmVnaXN0cnkgfSBmcm9tICcuL2dsc2wtcmVnaXN0ZXJlZC1saWJzJztcbmltcG9ydCB7IGdldERlZmF1bHRGcmFnU2hhZGVyTWFpbiwgZ2V0RnJhZ1NoYWRlclByZWFtYmxlIH0gZnJvbSAnLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZUxheW91dCwgVmFyaWFibGVJbmZvIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL3dlYmdsLWNvbnRleHQnO1xuXG4vKipcbiAqIFByZXByb2Nlc3NvciBmb3IgdGhlIGFkZGl0aW9ucyB0byB0aGUgR0xTTCBsYW5ndWFnZVxuICogSXQgZGVhbHMgd2l0aDpcbiAqICBAaW5jbHVkZSBkaXJlY3RpdmVzXG4gKiAgQGlubGluZVxuICogIExvb3AgdW5yb2xsaW5nIChub3QgaW1wbGVtZW50ZWQpXG4gKiAgTWFjcm8gcmVzb2x1dGlvbiAobm90IGltcGxlbWVudGVkKVxuICovXG5leHBvcnQgY2xhc3MgR2xzbFByZXByb2Nlc3NvciB7XG4gIHJlYWRvbmx5IGNvbnRleHQ6IEdsc2xDb250ZXh0O1xuICByZWFkb25seSBsaWJzOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliIH0gPSB7fTtcbiAgcmVhZG9ubHkgZ2xzbExpYlJvdXRpbmVEZXBlbmRlbmN5R3JhcGg6IHsgW3JvdXRpbmVOYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZU5vZGUgfSA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGdsQ29udGV4dDogV2ViR0xDb250ZXh0LFxuICAgIHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mbyxcbiAgICBpbnB1dFRleHR1cmVMYXlvdXRzOiBUZXh0dXJlTGF5b3V0W10sXG4gICAgb3V0cHV0VGV4dHVyZUxheW91dDogVGV4dHVyZUxheW91dCxcbiAgKSB7XG4gICAgdGhpcy5jb250ZXh0ID0gbmV3IEdsc2xDb250ZXh0KGdsQ29udGV4dCwgcHJvZ3JhbUluZm8sIGlucHV0VGV4dHVyZUxheW91dHMsIG91dHB1dFRleHR1cmVMYXlvdXQpO1xuXG4gICAgLy8gY29uc3RydWN0IEdsc2xMaWJzXG4gICAgT2JqZWN0LmtleXMoZ2xzbFJlZ2lzdHJ5KS5mb3JFYWNoKChuYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGxpYiA9IG5ldyBnbHNsUmVnaXN0cnlbbmFtZV0odGhpcy5jb250ZXh0KTtcbiAgICAgIHRoaXMubGlic1tuYW1lXSA9IGxpYjtcbiAgICB9KTtcblxuICAgIC8vIGNvbnN0cnVjdCBHbHNsUm91dGluZURlcGVuZGVuY3lHcmFwaFxuICAgIGNvbnN0IG1hcCA9IHRoaXMuZ2xzbExpYlJvdXRpbmVEZXBlbmRlbmN5R3JhcGg7XG4gICAgZm9yIChjb25zdCBsaWJOYW1lIGluIHRoaXMubGlicykge1xuICAgICAgY29uc3QgbGliID0gdGhpcy5saWJzW2xpYk5hbWVdO1xuICAgICAgY29uc3Qgcm91dGluZXNJbkxpYiA9IGxpYi5nZXRGdW5jdGlvbnMoKTtcbiAgICAgIGZvciAoY29uc3Qgcm91dGluZSBpbiByb3V0aW5lc0luTGliKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGxpYk5hbWUgKyAnLicgKyByb3V0aW5lO1xuICAgICAgICBsZXQgY3VycmVudE5vZGU6IEdsc2xMaWJSb3V0aW5lTm9kZTtcbiAgICAgICAgaWYgKG1hcFtrZXldKSB7XG4gICAgICAgICAgY3VycmVudE5vZGUgPSBtYXBba2V5XTtcbiAgICAgICAgICBjdXJyZW50Tm9kZS5yb3V0aW5lQm9keSA9IHJvdXRpbmVzSW5MaWJbcm91dGluZV0ucm91dGluZUJvZHk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY3VycmVudE5vZGUgPSBuZXcgR2xzbExpYlJvdXRpbmVOb2RlKGtleSwgcm91dGluZXNJbkxpYltyb3V0aW5lXS5yb3V0aW5lQm9keSk7XG4gICAgICAgICAgbWFwW2tleV0gPSBjdXJyZW50Tm9kZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZXBlbmRlbmNpZXMgPSByb3V0aW5lc0luTGliW3JvdXRpbmVdLmRlcGVuZGVuY2llcztcbiAgICAgICAgaWYgKGRlcGVuZGVuY2llcykge1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVwZW5kZW5jaWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBpZiAoIW1hcFtkZXBlbmRlbmNpZXNbaV1dKSB7XG4gICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSBuZXcgR2xzbExpYlJvdXRpbmVOb2RlKGRlcGVuZGVuY2llc1tpXSk7XG4gICAgICAgICAgICAgIG1hcFtkZXBlbmRlbmNpZXNbaV1dID0gbm9kZTtcbiAgICAgICAgICAgICAgY3VycmVudE5vZGUuYWRkRGVwZW5kZW5jeShub2RlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGN1cnJlbnROb2RlLmFkZERlcGVuZGVuY3kobWFwW2RlcGVuZGVuY2llc1tpXV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByZXByb2Nlc3MoKTogc3RyaW5nIHtcbiAgICBjb25zdCBwcm9ncmFtSW5mbyA9IHRoaXMuY29udGV4dC5wcm9ncmFtSW5mbztcbiAgICBsZXQgc291cmNlID0gcHJvZ3JhbUluZm8uc2hhZGVyU291cmNlO1xuXG4gICAgLy8gYXBwZW5kIG1haW4oKSBmdW5jdGlvblxuICAgIGlmICghdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmhhc01haW4pIHtcbiAgICAgIHNvdXJjZSA9IGAke3NvdXJjZX1cbiAgICAgICR7Z2V0RGVmYXVsdEZyYWdTaGFkZXJNYWluKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbiwgdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQuc2hhcGUubGVuZ3RoKX1gO1xuICAgIH1cbiAgICAvLyByZXBsYWNlIGlubGluZXNcbiAgICBzb3VyY2UgPSByZXBsYWNlSW5saW5lcyhzb3VyY2UpO1xuXG4gICAgLy8gY29uY2F0IGZpbmFsIHNvdXJjZSBzdHJpbmdcbiAgICByZXR1cm4gYCR7Z2V0RnJhZ1NoYWRlclByZWFtYmxlKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbil9XG4gICAgJHt0aGlzLmdldFVuaWZvcm1zKHByb2dyYW1JbmZvLmlucHV0TmFtZXMsIHByb2dyYW1JbmZvLnZhcmlhYmxlcyl9XG4gICAgJHt0aGlzLmdldEltcG9ydHMoc291cmNlKX1cbiAgICAke3NvdXJjZX1gO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldEltcG9ydHMoc2NyaXB0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHJvdXRpbmVzSW5jbHVkZWQgPSB0aGlzLnNlbGVjdEdsc2xMaWJSb3V0aW5lc1RvQmVJbmNsdWRlZChzY3JpcHQpO1xuXG4gICAgaWYgKHJvdXRpbmVzSW5jbHVkZWQubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgbGV0IHJvdXRpbmVzID0gJyc7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3V0aW5lc0luY2x1ZGVkLmxlbmd0aDsgKytpKSB7XG4gICAgICBpZiAocm91dGluZXNJbmNsdWRlZFtpXS5yb3V0aW5lQm9keSkge1xuICAgICAgICByb3V0aW5lcyArPSByb3V0aW5lc0luY2x1ZGVkW2ldLnJvdXRpbmVCb2R5ICsgJ1xcbic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgYm9keSBmb3IgdGhlIEdsc2wgTGlicmFyeSByb3V0aW5lOiAke3JvdXRpbmVzSW5jbHVkZWRbaV0ubmFtZX1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcm91dGluZXM7XG4gIH1cbiAgcHJpdmF0ZSBzZWxlY3RHbHNsTGliUm91dGluZXNUb0JlSW5jbHVkZWQoc2NyaXB0OiBzdHJpbmcpOiBHbHNsTGliUm91dGluZU5vZGVbXSB7XG4gICAgY29uc3Qgbm9kZXM6IEdsc2xMaWJSb3V0aW5lTm9kZVtdID0gW107XG5cbiAgICBPYmplY3Qua2V5cyh0aGlzLmdsc2xMaWJSb3V0aW5lRGVwZW5kZW5jeUdyYXBoKS5mb3JFYWNoKChjbGFzc0FuZFJvdXRpbmUpID0+IHtcbiAgICAgIGNvbnN0IHJvdXRpbmUgPSBjbGFzc0FuZFJvdXRpbmUuc3BsaXQoJy4nKVsxXTtcbiAgICAgIGlmIChzY3JpcHQuaW5kZXhPZihyb3V0aW5lKSAhPT0gLTEpIHtcbiAgICAgICAgbm9kZXMucHVzaCh0aGlzLmdsc2xMaWJSb3V0aW5lRGVwZW5kZW5jeUdyYXBoW2NsYXNzQW5kUm91dGluZV0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIFRvcG9sb2dpY2FsU29ydEdsc2xSb3V0aW5lcy5yZXR1cm5PcmRlcmVkTm9kZXMobm9kZXMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldFVuaWZvcm1zKHNhbXBsZXJzPzogc3RyaW5nW10sIHZhcmlhYmxlcz86IFZhcmlhYmxlSW5mb1tdKTogc3RyaW5nIHtcbiAgICBjb25zdCB1bmlmb3JtTGluZXM6IHN0cmluZ1tdID0gW107XG4gICAgaWYgKHNhbXBsZXJzKSB7XG4gICAgICBmb3IgKGNvbnN0IHNhbXBsZXIgb2Ygc2FtcGxlcnMpIHtcbiAgICAgICAgdW5pZm9ybUxpbmVzLnB1c2goYHVuaWZvcm0gc2FtcGxlcjJEICR7c2FtcGxlcn07YCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh2YXJpYWJsZXMpIHtcbiAgICAgIGZvciAoY29uc3QgdmFyaWFibGUgb2YgdmFyaWFibGVzKSB7XG4gICAgICAgIHVuaWZvcm1MaW5lcy5wdXNoKFxuICAgICAgICAgIGB1bmlmb3JtICR7dmFyaWFibGUudHlwZX0gJHt2YXJpYWJsZS5uYW1lfSR7dmFyaWFibGUuYXJyYXlMZW5ndGggPyBgWyR7dmFyaWFibGUuYXJyYXlMZW5ndGh9XWAgOiAnJ307YCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuaWZvcm1MaW5lcy5qb2luKCdcXG4nKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBlbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBMb2dnZXIsIFByb2ZpbGVyIH0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5cbmltcG9ydCB7IEdsc2xQcmVwcm9jZXNzb3IgfSBmcm9tICcuL2dsc2wtcHJlcHJvY2Vzc29yJztcbmltcG9ydCB7IGdldFZlcnRleFNoYWRlclNvdXJjZSB9IGZyb20gJy4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgVGV4dHVyZUxheW91dFN0cmF0ZWd5IH0gZnJvbSAnLi90ZXh0dXJlLWxheW91dC1zdHJhdGVneSc7XG5pbXBvcnQgeyBBcnRpZmFjdCwgUHJvZ3JhbUluZm8sIFByb2dyYW1WYXJpYWJsZSwgVGV4dHVyZURhdGEsIFRleHR1cmVMYXlvdXQsIFZhcmlhYmxlSW5mbyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgV2ViR0xDb250ZXh0IH0gZnJvbSAnLi93ZWJnbC1jb250ZXh0JztcblxuLyoqXG4gKiBQcm9ncmFtTWFuYWdlciBpcyB0aGUgbWFpbiBjbGFzcyBiZWhpbmQgcnVubmluZyBjb21wdXRhdGlvbnNcbiAqIEl0IGJ1aWxkcyBQcm9ncmFtSW5mbydzIGludG8gQXJ0aWZhY3RzXG4gKiBJdCBjb21waWxlcyBnaXZlbiBQcm9ncmFtSW5mbydzIGludG8gV2ViR0wgUHJvcmFtcyAoY2FjaGVkIGFzIEFydGlmYWN0cylcbiAqIFVzZXMgdGhlIGFydGlmYWN0IHRvIHJ1biB0aGUgY29tcHV0YXRpb24gYnkgY2FsbGluZyBEcmF3IG9uXG4gKiB0aGUgV2ViR0wgZHJhd2luZyBidWZmZXJcbiAqIFByb2dyYW1NYW5hZ2VyIGF1dG9tYXRpY2FsbHkgbWFwcyAoYmluZHMpIGlucHV0IHZhcmlhYmxlcyB0byB0aGVpclxuICogY29ycmVzcG9uZGluZyBMb2NhdGlvbidzIGluIHRoZSBiaW5hcnkgcHJvZ3JhbVxuICovXG5leHBvcnQgY2xhc3MgUHJvZ3JhbU1hbmFnZXIge1xuICByZXBvOiBNYXA8dW5rbm93biwgQXJ0aWZhY3Q+OyAvLyB0aGlzIHNob3VsZCBiZSBwZXItc2Vzc2lvbiBvYmplY3RcbiAgdmVydGV4U2hhZGVyOiBXZWJHTFNoYWRlcjtcbiAgYXR0cmlidXRlc0JvdW5kOiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBwcm9maWxlcjogUmVhZG9ubHk8UHJvZmlsZXI+LFxuICAgIHB1YmxpYyBnbENvbnRleHQ6IFdlYkdMQ29udGV4dCxcbiAgICBwdWJsaWMgdGV4dHVyZUxheW91dFN0cmF0ZWd5OiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3ksXG4gICkge1xuICAgIHRoaXMucmVwbyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmF0dHJpYnV0ZXNCb3VuZCA9IGZhbHNlO1xuICB9XG4gIGdldEFydGlmYWN0KGtleTogdW5rbm93bik6IEFydGlmYWN0IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5yZXBvLmdldChrZXkpO1xuICB9XG4gIHNldEFydGlmYWN0KGtleTogdW5rbm93biwgYXJ0aWZhY3Q6IEFydGlmYWN0KTogdm9pZCB7XG4gICAgdGhpcy5yZXBvLnNldChrZXksIGFydGlmYWN0KTtcbiAgfVxuICBydW4oYnVpbGRBcnRpZmFjdDogQXJ0aWZhY3QsIGlucHV0czogVGV4dHVyZURhdGFbXSwgb3V0cHV0OiBUZXh0dXJlRGF0YSk6IHZvaWQge1xuICAgIHRoaXMucHJvZmlsZXIuZXZlbnQoXG4gICAgICAnb3AnLFxuICAgICAgYFByb2dyYW1NYW5hZ2VyLnJ1biAke2J1aWxkQXJ0aWZhY3QucHJvZ3JhbUluZm8ubmFtZSA/PyAndW5rbm93biBrZXJuZWwnfWAsXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGdsID0gdGhpcy5nbENvbnRleHQuZ2w7XG4gICAgICAgIGNvbnN0IHByb2dyYW0gPSBidWlsZEFydGlmYWN0LnByb2dyYW07XG4gICAgICAgIGdsLnVzZVByb2dyYW0ocHJvZ3JhbSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhpcy5iaW5kT3V0cHV0KG91dHB1dCk7XG4gICAgICAgICAgaWYgKCF0aGlzLmF0dHJpYnV0ZXNCb3VuZCkge1xuICAgICAgICAgICAgdGhpcy5iaW5kQXR0cmlidXRlcyhidWlsZEFydGlmYWN0LmF0dHJpYkxvY2F0aW9ucyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuYmluZFVuaWZvcm1zKGJ1aWxkQXJ0aWZhY3QudW5pZm9ybUxvY2F0aW9ucywgYnVpbGRBcnRpZmFjdC5wcm9ncmFtSW5mby52YXJpYWJsZXMgPz8gW10sIGlucHV0cyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIExvZ2dlci5lcnJvcignUHJvZ3JhbU1hbmFnZXInLCBidWlsZEFydGlmYWN0LnByb2dyYW1JbmZvLnNoYWRlclNvdXJjZSk7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnR2xDb250ZXh0LmRyYXcoKScsICgpID0+IHtcbiAgICAgICAgICB0aGlzLmdsQ29udGV4dC5kcmF3KCk7XG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIHRoaXMuZ2xDb250ZXh0LFxuICAgICk7XG4gIH1cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy52ZXJ0ZXhTaGFkZXIpIHtcbiAgICAgIHRoaXMuZ2xDb250ZXh0LmRlbGV0ZVNoYWRlcih0aGlzLnZlcnRleFNoYWRlcik7XG4gICAgfVxuICAgIHRoaXMucmVwby5mb3JFYWNoKChhKSA9PiB0aGlzLmdsQ29udGV4dC5kZWxldGVQcm9ncmFtKGEucHJvZ3JhbSkpO1xuICB9XG4gIGJ1aWxkKHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mbywgaW5wdXRUZXh0dXJlTGF5b3V0czogVGV4dHVyZUxheW91dFtdLCBvdXRwdXRUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogQXJ0aWZhY3Qge1xuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdiYWNrZW5kJywgJ1Byb2dyYW1NYW5hZ2VyLmJ1aWxkJywgKCkgPT4ge1xuICAgICAgY29uc3QgcHJlcHJvY2Vzc29yID0gbmV3IEdsc2xQcmVwcm9jZXNzb3IodGhpcy5nbENvbnRleHQsIHByb2dyYW1JbmZvLCBpbnB1dFRleHR1cmVMYXlvdXRzLCBvdXRwdXRUZXh0dXJlTGF5b3V0KTtcbiAgICAgIGNvbnN0IGZyYWdTY3JpcHQgPSBwcmVwcm9jZXNzb3IucHJlcHJvY2VzcygpO1xuICAgICAgY29uc3QgcHJvZ3JhbSA9IHRoaXMuY29tcGlsZShmcmFnU2NyaXB0KTtcbiAgICAgIGNvbnN0IGFydGlmYWN0ID0ge1xuICAgICAgICBwcm9ncmFtSW5mbyxcbiAgICAgICAgcHJvZ3JhbSxcbiAgICAgICAgdW5pZm9ybUxvY2F0aW9uczogdGhpcy5nZXRVbmlmb3JtTG9jYXRpb25zKFxuICAgICAgICAgIHByb2dyYW0sXG4gICAgICAgICAgcHJlcHJvY2Vzc29yLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcyxcbiAgICAgICAgICBwcmVwcm9jZXNzb3IuY29udGV4dC5wcm9ncmFtSW5mby52YXJpYWJsZXMsXG4gICAgICAgICksXG4gICAgICAgIGF0dHJpYkxvY2F0aW9uczogdGhpcy5nZXRBdHRyaWJMb2NhdGlvbnMocHJvZ3JhbSksXG4gICAgICB9O1xuICAgICAgcmV0dXJuIGFydGlmYWN0O1xuICAgIH0pO1xuICB9XG4gIHByb3RlY3RlZCBjb21waWxlKGZyYWdTaGFkZXJTY3JpcHQ6IHN0cmluZyk6IFdlYkdMUHJvZ3JhbSB7XG4gICAgaWYgKCF0aGlzLnZlcnRleFNoYWRlcikge1xuICAgICAgTG9nZ2VyLnZlcmJvc2UoJ1Byb3JncmFtTWFuYWdlcicsICdDb21waWxpbmcgYW5kIGNhY2hpbmcgVmVydGV4IHNoYWRlciBmb3IgdGhlIGZpcnN0IHRpbWUnKTtcbiAgICAgIGNvbnN0IHZlcnRleFNoYWRlclNjcmlwdCA9IGdldFZlcnRleFNoYWRlclNvdXJjZSh0aGlzLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAgIHRoaXMudmVydGV4U2hhZGVyID0gdGhpcy5nbENvbnRleHQuY29tcGlsZVNoYWRlcih2ZXJ0ZXhTaGFkZXJTY3JpcHQsIHRoaXMuZ2xDb250ZXh0LmdsLlZFUlRFWF9TSEFERVIpO1xuICAgIH1cbiAgICBpZiAoZW52LmRlYnVnKSB7XG4gICAgICBMb2dnZXIudmVyYm9zZShcbiAgICAgICAgJ1Byb3JncmFtTWFuYWdlcicsXG4gICAgICAgIGBGcmFnU2hhZGVyOlxuJHtmcmFnU2hhZGVyU2NyaXB0fVxuYCxcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IGZyYWdTaGFkZXIgPSB0aGlzLmdsQ29udGV4dC5jb21waWxlU2hhZGVyKGZyYWdTaGFkZXJTY3JpcHQsIHRoaXMuZ2xDb250ZXh0LmdsLkZSQUdNRU5UX1NIQURFUik7XG4gICAgY29uc3QgcHJvZ3JhbSA9IHRoaXMuZ2xDb250ZXh0LmNyZWF0ZVByb2dyYW0odGhpcy52ZXJ0ZXhTaGFkZXIsIGZyYWdTaGFkZXIpO1xuICAgIHRoaXMuZ2xDb250ZXh0LmRlbGV0ZVNoYWRlcihmcmFnU2hhZGVyKTtcbiAgICByZXR1cm4gcHJvZ3JhbTtcbiAgfVxuICBiaW5kT3V0cHV0KHRkOiBUZXh0dXJlRGF0YSk6IHZvaWQge1xuICAgIGNvbnN0IHdpZHRoID0gdGQud2lkdGg7XG4gICAgY29uc3QgaGVpZ2h0ID0gdGQuaGVpZ2h0O1xuICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgJ1Byb3JncmFtTWFuYWdlcicsXG4gICAgICBgQmluZGluZyBvdXRwdXQgdGV4dHVyZSB0byBGcmFtZWJ1ZmZlcjogdy9oPSR7d2lkdGh9LyR7aGVpZ2h0fSwgc2hhcGU9JHt0ZC5zaGFwZX0sIHR5cGU9JHt0ZC50ZW5zb3IudHlwZX1gLFxuICAgICk7XG4gICAgdGhpcy5nbENvbnRleHQuYXR0YWNoRnJhbWVidWZmZXIodGQudGV4dHVyZSwgd2lkdGgsIGhlaWdodCk7XG4gIH1cbiAgYmluZEF0dHJpYnV0ZXMoYXR0cmliTG9jYXRpb25zOiBBcnRpZmFjdC5BdHRyaWJMb2NhdGlvbnMpOiB2b2lkIHtcbiAgICBjb25zdCBwb3NpdGlvbkhhbmRsZSA9IGF0dHJpYkxvY2F0aW9ucy5wb3NpdGlvbjtcbiAgICBjb25zdCB0ZXh0dXJlQ29vcmRIYW5kbGUgPSBhdHRyaWJMb2NhdGlvbnMudGV4dHVyZUNvb3JkO1xuICAgIHRoaXMuZ2xDb250ZXh0LnNldFZlcnRleEF0dHJpYnV0ZXMocG9zaXRpb25IYW5kbGUsIHRleHR1cmVDb29yZEhhbmRsZSk7XG4gICAgdGhpcy5hdHRyaWJ1dGVzQm91bmQgPSB0cnVlO1xuICB9XG4gIGJpbmRVbmlmb3JtcyhcbiAgICB1bmlmb3JtTG9jYXRpb25zOiBBcnRpZmFjdC5Vbmlmb3JtTG9jYXRpb25zLFxuICAgIHZhcmlhYmxlczogUHJvZ3JhbVZhcmlhYmxlW10sXG4gICAgdGV4dHVyZXM6IFRleHR1cmVEYXRhW10sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbENvbnRleHQuZ2w7XG4gICAgbGV0IHRleHR1cmVQb3NpdGlvbiA9IDA7XG4gICAgZm9yIChjb25zdCB7IG5hbWUsIHR5cGUsIGxvY2F0aW9uLCBhcnJheUxlbmd0aCB9IG9mIHVuaWZvcm1Mb2NhdGlvbnMpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdmFyaWFibGVzLmZpbmQoKHYpID0+IHYubmFtZSA9PT0gbmFtZSk/LmRhdGE7XG4gICAgICBpZiAodHlwZSAhPT0gJ3NhbXBsZXIyRCcgJiYgIXZhbHVlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdmFyaWFibGUgJyR7bmFtZX0nIGRvZXMgbm90IGhhdmUgZGF0YSBkZWZpbmVkIGluIHByb2dyYW0gaW5mb2ApO1xuICAgICAgfVxuICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgIGNhc2UgJ3NhbXBsZXIyRCc6XG4gICAgICAgICAgdGhpcy5iaW5kVGV4dHVyZSh0ZXh0dXJlc1t0ZXh0dXJlUG9zaXRpb25dLCBsb2NhdGlvbiwgdGV4dHVyZVBvc2l0aW9uKTtcbiAgICAgICAgICB0ZXh0dXJlUG9zaXRpb24rKztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnZmxvYXQnOlxuICAgICAgICAgIGlmIChhcnJheUxlbmd0aCkge1xuICAgICAgICAgICAgZ2wudW5pZm9ybTFmdihsb2NhdGlvbiwgdmFsdWUgYXMgbnVtYmVyW10pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBnbC51bmlmb3JtMWYobG9jYXRpb24sIHZhbHVlIGFzIG51bWJlcik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdpbnQnOlxuICAgICAgICAgIGlmIChhcnJheUxlbmd0aCkge1xuICAgICAgICAgICAgZ2wudW5pZm9ybTFpdihsb2NhdGlvbiwgdmFsdWUgYXMgbnVtYmVyW10pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBnbC51bmlmb3JtMWkobG9jYXRpb24sIHZhbHVlIGFzIG51bWJlcik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5pZm9ybSBub3QgaW1wbGVtZW50ZWQ6ICR7dHlwZX1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgYmluZFRleHR1cmUodGQ6IFRleHR1cmVEYXRhLCB1bmlmb3JtSGFuZGxlOiBXZWJHTFVuaWZvcm1Mb2NhdGlvbiwgcG9zaXRpb246IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZ2xDb250ZXh0LmJpbmRUZXh0dXJlVG9Vbmlmb3JtKHRkLnRleHR1cmUsIHBvc2l0aW9uLCB1bmlmb3JtSGFuZGxlKTtcbiAgfVxuICBnZXRBdHRyaWJMb2NhdGlvbnMocHJvZ3JhbTogV2ViR0xQcm9ncmFtKTogQXJ0aWZhY3QuQXR0cmliTG9jYXRpb25zIHtcbiAgICByZXR1cm4ge1xuICAgICAgcG9zaXRpb246IHRoaXMuZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbSwgJ3Bvc2l0aW9uJyksXG4gICAgICB0ZXh0dXJlQ29vcmQ6IHRoaXMuZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbSwgJ3RleHR1cmVDb29yZCcpLFxuICAgIH07XG4gIH1cbiAgZ2V0VW5pZm9ybUxvY2F0aW9ucyhcbiAgICBwcm9ncmFtOiBXZWJHTFByb2dyYW0sXG4gICAgc2FtcGxlcnM/OiBzdHJpbmdbXSxcbiAgICB2YXJpYWJsZXM/OiBWYXJpYWJsZUluZm9bXSxcbiAgKTogQXJ0aWZhY3QuVW5pZm9ybUxvY2F0aW9ucyB7XG4gICAgY29uc3QgdW5pZm9ybUxvY2F0aW9uczogQXJ0aWZhY3QuVW5pZm9ybUxvY2F0aW9ucyA9IFtdO1xuICAgIGlmIChzYW1wbGVycykge1xuICAgICAgZm9yIChjb25zdCBzYW1wbGVyIG9mIHNhbXBsZXJzKSB7XG4gICAgICAgIHVuaWZvcm1Mb2NhdGlvbnMucHVzaCh7XG4gICAgICAgICAgbmFtZTogc2FtcGxlcixcbiAgICAgICAgICB0eXBlOiAnc2FtcGxlcjJEJyxcbiAgICAgICAgICBsb2NhdGlvbjogdGhpcy5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgc2FtcGxlciksXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodmFyaWFibGVzKSB7XG4gICAgICBmb3IgKGNvbnN0IHZhcmlhYmxlIG9mIHZhcmlhYmxlcykge1xuICAgICAgICB1bmlmb3JtTG9jYXRpb25zLnB1c2goeyAuLi52YXJpYWJsZSwgbG9jYXRpb246IHRoaXMuZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sIHZhcmlhYmxlLm5hbWUpIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5pZm9ybUxvY2F0aW9ucztcbiAgfVxuICBnZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbTogV2ViR0xQcm9ncmFtLCBuYW1lOiBzdHJpbmcpOiBXZWJHTFVuaWZvcm1Mb2NhdGlvbiB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsQ29udGV4dC5nbDtcbiAgICBjb25zdCByZWZlcmVuY2UgPSBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgbmFtZSk7XG4gICAgaWYgKHJlZmVyZW5jZSA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmlmb3JtICR7bmFtZX0gbm90IGZvdW5kLmApO1xuICAgIH1cbiAgICByZXR1cm4gcmVmZXJlbmNlO1xuICB9XG4gIGdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW06IFdlYkdMUHJvZ3JhbSwgbmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2xDb250ZXh0LmdsO1xuICAgIGNvbnN0IGF0dHJpYnV0ZUxvY2F0aW9uOiBudW1iZXIgPSBnbC5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCBuYW1lKTtcbiAgICByZXR1cm4gYXR0cmlidXRlTG9jYXRpb247XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgTG9nZ2VyLCBQcm9maWxlciB9IGZyb20gJy4uLy4uL2luc3RydW1lbnQnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vdGVuc29yJztcblxuaW1wb3J0IHsgRW5jb2RlciwgRW5jb2RlclVzYWdlIH0gZnJvbSAnLi90ZXh0dXJlLWRhdGEtZW5jb2Rlcic7XG5pbXBvcnQgeyBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kgfSBmcm9tICcuL3RleHR1cmUtbGF5b3V0LXN0cmF0ZWd5JztcbmltcG9ydCB7IFRleHR1cmVEYXRhLCBUZXh0dXJlTGF5b3V0IH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL3dlYmdsLWNvbnRleHQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRleHR1cmVNYW5hZ2VyQ29uZmlnIHtcbiAgcmV1c2VUZXh0dXJlcz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogVGV4dHVyZU1hbmFnZXIgaXMgdGhlIG1haW5seSByZXNwb25zaWJsZSBmb3IgY2FjaGluZyBUZXh0dXJlc1xuICogVGV4dHVyZXMgYXJlIGNhY2hlZCBpbiAyIGxldmVsczpcbiAqICAgMS4gdGhlIHRleHVyZXMgd2hpY2ggYXJlIGFzc29jaWF0ZWQgd2l0aCBhIGRhdGFJZCAoZnJvbSBUZW5zb3IpXG4gKiAgICBDYWNoaW5nIHRoZXNlIGlzIGNydWNpYWwgdG8gcGVyZm9ybWFuY2UuIFRoZXNlIGFyZSBJbi11c2UgVGV4dHVyZXNcbiAqICAgMi4gdGV4dHVyZXMgd2hpY2ggYXJlIG5vdCBpbiB1c2UgYnkgYW55IGN1cnJlbnQgUHJvZ3JhbUluZm8vVGVuc29yXG4gKiAgICAgVGhlc2UgYXJlIGNhbGxlZCBGcmVlIFRleHR1cmVzXG4gKiBUZXh0dXJlTWFuYWdlciBpcyBhbHNvIHVzZWQgdG8gaGVscCBjcmVhdGluZyB0ZXh0dXJlcy4gRm9yIHRoaXMgaXRcbiAqIHVzZXMgV2ViR0xDb250ZXh0IGFuZCBUZXh0dXJlTGF5b3V0U3RyYXRlZ3lcbiAqL1xuZXhwb3J0IGNsYXNzIFRleHR1cmVNYW5hZ2VyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBpblVzZVRleHR1cmVzOiBNYXA8c3RyaW5nLCBXZWJHTFRleHR1cmVbXT47XG4gIHByaXZhdGUgcmVhZG9ubHkgaWRsZVRleHR1cmVzOiBNYXA8c3RyaW5nLCBXZWJHTFRleHR1cmVbXT47XG4gIHByaXZhdGUgcmVhZG9ubHkgdGV4dHVyZUxvb2t1cDogTWFwPFdlYkdMVGV4dHVyZSwgc3RyaW5nPjtcbiAgcHJpdmF0ZSByZWFkb25seSBwZW5kaW5nUmVhZDogTWFwPFRlbnNvci5JZCwgQXJyYXk8KGFycjogVGVuc29yLk51bWJlclR5cGUpID0+IHZvaWQ+PiA9IG5ldyBNYXAoKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQsXG4gICAgcHVibGljIGxheW91dFN0cmF0ZWd5OiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3ksXG4gICAgcHVibGljIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj4sXG4gICAgcHJpdmF0ZSBjb25maWc6IFRleHR1cmVNYW5hZ2VyQ29uZmlnLFxuICApIHtcbiAgICBpZiAoY29uZmlnLnJldXNlVGV4dHVyZXMpIHtcbiAgICAgIHRoaXMuaW5Vc2VUZXh0dXJlcyA9IG5ldyBNYXAoKTtcbiAgICAgIHRoaXMuaWRsZVRleHR1cmVzID0gbmV3IE1hcCgpO1xuICAgICAgdGhpcy50ZXh0dXJlTG9va3VwID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgfVxuICBjcmVhdGVUZXh0dXJlRnJvbUxheW91dChcbiAgICBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLFxuICAgIGxheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBkYXRhPzogVGVuc29yLk51bWJlclR5cGUsXG4gICAgdXNhZ2U/OiBFbmNvZGVyVXNhZ2UsXG4gICkge1xuICAgIGNvbnN0IHRleHR1cmVEYXRhVHlwZSA9IHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSk7XG5cbiAgICBjb25zdCBlbmNvZGVyID0gdGhpcy5nbENvbnRleHQuZ2V0RW5jb2Rlcih0ZXh0dXJlRGF0YVR5cGUsIGxheW91dC5jaGFubmVscyB8fCAxLCB1c2FnZSk7XG4gICAgaWYgKGxheW91dC5pc1BhY2tlZCAmJiB1c2FnZSA9PT0gRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuICAgIGNvbnN0IHdpZHRoID0gbGF5b3V0LndpZHRoO1xuICAgIGNvbnN0IGhlaWdodCA9IGxheW91dC5oZWlnaHQ7XG5cbiAgICBsZXQga2V5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgbGV0IGluVXNlVGV4dHVyZXM6IFdlYkdMVGV4dHVyZVtdIHwgdW5kZWZpbmVkO1xuICAgIGlmICh0aGlzLmNvbmZpZy5yZXVzZVRleHR1cmVzKSB7XG4gICAgICBrZXkgPSBgJHt3aWR0aH14JHtoZWlnaHR9XyR7ZW5jb2Rlci5mb3JtYXR9XyR7ZW5jb2Rlci5pbnRlcm5hbEZvcm1hdH1fJHtlbmNvZGVyLnRleHR1cmVUeXBlfWA7XG4gICAgICBpblVzZVRleHR1cmVzID0gdGhpcy5pblVzZVRleHR1cmVzLmdldChrZXkpO1xuICAgICAgaWYgKCFpblVzZVRleHR1cmVzKSB7XG4gICAgICAgIGluVXNlVGV4dHVyZXMgPSBbXTtcbiAgICAgICAgdGhpcy5pblVzZVRleHR1cmVzLnNldChrZXksIGluVXNlVGV4dHVyZXMpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBpZGxlVGV4dHVyZXMgPSB0aGlzLmlkbGVUZXh0dXJlcy5nZXQoa2V5KTtcbiAgICAgIGlmIChpZGxlVGV4dHVyZXMgJiYgaWRsZVRleHR1cmVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgdGV4dHVyZSA9IGlkbGVUZXh0dXJlcy5wb3AoKSE7XG4gICAgICAgIGluVXNlVGV4dHVyZXMucHVzaCh0ZXh0dXJlKTtcbiAgICAgICAgaWYgKHVzYWdlID09PSBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSkge1xuICAgICAgICAgIHRoaXMuZ2xDb250ZXh0LnVwZGF0ZVRleHR1cmUodGV4dHVyZSwgd2lkdGgsIGhlaWdodCwgZW5jb2RlciwgdGhpcy50b1RleHR1cmVEYXRhKGRhdGFUeXBlLCBkYXRhKSEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0ZXh0dXJlO1xuICAgICAgfVxuICAgIH1cblxuICAgIExvZ2dlci52ZXJib3NlKCdUZXh0dXJlTWFuYWdlcicsIGBDcmVhdGluZyBuZXcgdGV4dHVyZSBvZiBzaXplICR7bGF5b3V0LndpZHRofXgke2xheW91dC5oZWlnaHR9YCk7XG4gICAgY29uc3QgdGV4dHVyZSA9IHRoaXMuZ2xDb250ZXh0LmFsbG9jYXRlVGV4dHVyZSh3aWR0aCwgaGVpZ2h0LCBlbmNvZGVyLCB0aGlzLnRvVGV4dHVyZURhdGEoZGF0YVR5cGUsIGRhdGEpKTtcblxuICAgIGlmICh0aGlzLmNvbmZpZy5yZXVzZVRleHR1cmVzKSB7XG4gICAgICBpblVzZVRleHR1cmVzIS5wdXNoKHRleHR1cmUpO1xuICAgICAgdGhpcy50ZXh0dXJlTG9va3VwLnNldCh0ZXh0dXJlLCBrZXkhKTtcbiAgICB9XG4gICAgcmV0dXJuIHRleHR1cmU7XG4gIH1cbiAgcmVhZFRleHR1cmUodGQ6IFRleHR1cmVEYXRhLCBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLCBjaGFubmVscz86IG51bWJlcik6IFRlbnNvci5OdW1iZXJUeXBlIHtcbiAgICBpZiAoIWNoYW5uZWxzKSB7XG4gICAgICBjaGFubmVscyA9IDE7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdiYWNrZW5kJywgJ1RleHR1cmVNYW5hZ2VyLnJlYWRUZXh0dXJlJywgKCkgPT4ge1xuICAgICAgY29uc3QgZGF0YVNpemUgPSB0ZC5zaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKSAqIGNoYW5uZWxzITtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdsQ29udGV4dC5yZWFkVGV4dHVyZShcbiAgICAgICAgdGQudGV4dHVyZSxcbiAgICAgICAgdGQud2lkdGgsXG4gICAgICAgIHRkLmhlaWdodCxcbiAgICAgICAgZGF0YVNpemUsXG4gICAgICAgIHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSksXG4gICAgICAgIGNoYW5uZWxzISxcbiAgICAgICk7XG4gICAgICByZXR1cm4gdGhpcy50b1RlbnNvckRhdGEoZGF0YVR5cGUsIGRhdGEpO1xuICAgIH0pO1xuICB9XG4gIGFzeW5jIHJlYWRUZXh0dXJlQXN5bmModGQ6IFRleHR1cmVEYXRhLCBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLCBjaGFubmVscz86IG51bWJlcik6IFByb21pc2U8VGVuc29yLk51bWJlclR5cGU+IHtcbiAgICBjb25zdCBkYXRhSWQgPSB0ZC50ZW5zb3IuZGF0YUlkO1xuICAgIGlmICghY2hhbm5lbHMpIHtcbiAgICAgIGNoYW5uZWxzID0gMTtcbiAgICB9XG4gICAgaWYgKHRoaXMucGVuZGluZ1JlYWQuaGFzKGRhdGFJZCkpIHtcbiAgICAgIGNvbnN0IHN1YnNjcmliZXJzID0gdGhpcy5wZW5kaW5nUmVhZC5nZXQoZGF0YUlkKTtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxUZW5zb3IuTnVtYmVyVHlwZT4oKHJlc29sdmUpID0+IHN1YnNjcmliZXJzPy5wdXNoKHJlc29sdmUpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnVGV4dHVyZU1hbmFnZXIucmVhZFRleHR1cmVBc3luYycsIGFzeW5jICgpID0+IHtcbiAgICAgIHRoaXMucGVuZGluZ1JlYWQuc2V0KGRhdGFJZCwgW10pO1xuICAgICAgY29uc3QgZGF0YVNpemUgPSB0ZC5zaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKSAqIGNoYW5uZWxzITtcbiAgICAgIC8vIGFkZCBhIGZlbmNlIHdhaXRpbmcgZm9yIHRoZSBkYXRhIHRvIGJlIHJlYWR5XG4gICAgICBhd2FpdCB0aGlzLmdsQ29udGV4dC5jcmVhdGVBbmRXYWl0Rm9yRmVuY2UoKTtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdsQ29udGV4dC5yZWFkVGV4dHVyZShcbiAgICAgICAgdGQudGV4dHVyZSxcbiAgICAgICAgdGQud2lkdGgsXG4gICAgICAgIHRkLmhlaWdodCxcbiAgICAgICAgZGF0YVNpemUsXG4gICAgICAgIHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSksXG4gICAgICAgIGNoYW5uZWxzISxcbiAgICAgICk7XG4gICAgICBjb25zdCB0ZW5zb3JEYXRhID0gdGhpcy50b1RlbnNvckRhdGEoZGF0YVR5cGUsIGRhdGEpO1xuICAgICAgY29uc3Qgc3Vic2NyaWJlcnMgPSB0aGlzLnBlbmRpbmdSZWFkLmdldChkYXRhSWQpO1xuICAgICAgdGhpcy5wZW5kaW5nUmVhZC5kZWxldGUoZGF0YUlkKTtcbiAgICAgIHN1YnNjcmliZXJzPy5mb3JFYWNoKChyZXNvbHZlKSA9PiByZXNvbHZlKHRlbnNvckRhdGEpKTtcbiAgICAgIHJldHVybiB0ZW5zb3JEYXRhO1xuICAgIH0pO1xuICB9XG4gIHJlYWRVaW50OFRleHR1cmVBc0Zsb2F0KHRkOiBUZXh0dXJlRGF0YSk6IEZsb2F0MzJBcnJheSB7XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnVGV4dHVyZU1hbmFnZXIucmVhZFVpbnQ4VGV4dHVyZUFzRmxvYXQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBkYXRhU2l6ZSA9IHRkLnNoYXBlLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZ2xDb250ZXh0LnJlYWRUZXh0dXJlKHRkLnRleHR1cmUsIHRkLndpZHRoLCB0ZC5oZWlnaHQsIGRhdGFTaXplICogNCwgJ2J5dGUnLCA0KTtcbiAgICAgIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KGRhdGEuYnVmZmVyLCBkYXRhLmJ5dGVPZmZzZXQsIGRhdGFTaXplKTtcbiAgICB9KTtcbiAgfVxuICByZWxlYXNlVGV4dHVyZSh0ZXh0dXJlRGF0YTogVGV4dHVyZURhdGEsIGRlbGV0ZVRleHR1cmU/OiBib29sZWFuKTogdm9pZCB7XG4gICAgbGV0IGtleTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGlmICh0aGlzLmNvbmZpZy5yZXVzZVRleHR1cmVzKSB7XG4gICAgICBrZXkgPSB0aGlzLnRleHR1cmVMb29rdXAuZ2V0KHRleHR1cmVEYXRhLnRleHR1cmUpO1xuICAgICAgaWYgKGtleSkge1xuICAgICAgICBpZiAoZGVsZXRlVGV4dHVyZSkge1xuICAgICAgICAgIHRoaXMudGV4dHVyZUxvb2t1cC5kZWxldGUoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpblVzZVRleHR1cmVzID0gdGhpcy5pblVzZVRleHR1cmVzLmdldChrZXkpO1xuICAgICAgICBpZiAoaW5Vc2VUZXh0dXJlcykge1xuICAgICAgICAgIGNvbnN0IGluZGV4ID0gaW5Vc2VUZXh0dXJlcy5pbmRleE9mKHRleHR1cmVEYXRhLnRleHR1cmUpO1xuICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIGluVXNlVGV4dHVyZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIGxldCBpZGxlVGV4dHVyZXMgPSB0aGlzLmlkbGVUZXh0dXJlcy5nZXQoa2V5KTtcbiAgICAgICAgICAgIGlmICghaWRsZVRleHR1cmVzKSB7XG4gICAgICAgICAgICAgIGlkbGVUZXh0dXJlcyA9IFtdO1xuICAgICAgICAgICAgICB0aGlzLmlkbGVUZXh0dXJlcy5zZXQoa2V5LCBpZGxlVGV4dHVyZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWRsZVRleHR1cmVzLnB1c2godGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFrZXkgfHwgZGVsZXRlVGV4dHVyZSkge1xuICAgICAgTG9nZ2VyLnZlcmJvc2UoJ1RleHR1cmVNYW5hZ2VyJywgYERlbGV0aW5nIHRleHR1cmUgb2Ygc2l6ZSAke3RleHR1cmVEYXRhLndpZHRofXgke3RleHR1cmVEYXRhLmhlaWdodH1gKTtcbiAgICAgIHRoaXMuZ2xDb250ZXh0LmRlbGV0ZVRleHR1cmUodGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgfVxuICB9XG4gIHRvVGVuc29yRGF0YShkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLCBkYXRhOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUpOiBUZW5zb3IuTnVtYmVyVHlwZSB7XG4gICAgc3dpdGNoIChkYXRhVHlwZSkge1xuICAgICAgY2FzZSAnaW50MTYnOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEludDE2QXJyYXkgPyBkYXRhIDogSW50MTZBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAnaW50MzInOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEludDMyQXJyYXkgPyBkYXRhIDogSW50MzJBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAnaW50OCc6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgSW50OEFycmF5ID8gZGF0YSA6IEludDhBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAndWludDE2JzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBVaW50MTZBcnJheSA/IGRhdGEgOiBVaW50MTZBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAndWludDMyJzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBVaW50MzJBcnJheSA/IGRhdGEgOiBVaW50MzJBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAndWludDgnOlxuICAgICAgY2FzZSAnYm9vbCc6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgVWludDhBcnJheSA/IGRhdGEgOiBVaW50OEFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyBkYXRhIDogRmxvYXQzMkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkgPyBkYXRhIDogRmxvYXQ2NEFycmF5LmZyb20oZGF0YSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRlbnNvckRhdGEgdHlwZSAke2RhdGFUeXBlfSBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gICAgfVxuICB9XG4gIHRvVGV4dHVyZURhdGEoX2RhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsIGRhdGE6IFRlbnNvci5OdW1iZXJUeXBlIHwgdW5kZWZpbmVkKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWRhdGEpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gZGF0YSA6IG5ldyBGbG9hdDMyQXJyYXkoZGF0YSk7XG4gICAgLypcbiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICBjYXNlICd1aW50MTYnOlxuICAgICAgY2FzZSAndWludDMyJzpcbiAgICAgICAgcmV0dXJuIChkYXRhLmNvbnN0cnVjdG9yID09PSBVaW50MzJBcnJheSkgPyBkYXRhIGFzIFVpbnQzMkFycmF5IDogbmV3IFVpbnQzMkFycmF5KGRhdGEpO1xuICAgICAgY2FzZSAnaW50OCc6XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICBjYXNlICdib29sJzpcbiAgICAgICAgcmV0dXJuIChkYXRhLmNvbnN0cnVjdG9yID09PSBVaW50OEFycmF5KSA/IGRhdGEgYXMgVWludDhBcnJheSA6IG5ldyBVaW50OEFycmF5KGRhdGEpO1xuICAgICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIChkYXRhLmNvbnN0cnVjdG9yID09PSBGbG9hdDMyQXJyYXkpID8gZGF0YSBhcyBGbG9hdDMyQXJyYXkgOiBuZXcgRmxvYXQzMkFycmF5KGRhdGEpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW5zb3JEYXRhIHR5cGUgJHtkYXRhVHlwZX0gaXMgbm90IHN1cHBvcnRlZGApO1xuICAgIH1cbiAgICAqL1xuICB9XG4gIHRvRW5jb2RlclR5cGUoX2RhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUpOiBFbmNvZGVyLkRhdGFUeXBlIHtcbiAgICByZXR1cm4gJ2Zsb2F0JztcbiAgICAvLyBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgLy8gICBjYXNlICdpbnQxNic6XG4gICAgLy8gICBjYXNlICdpbnQzMic6XG4gICAgLy8gICBjYXNlICd1aW50MTYnOlxuICAgIC8vICAgY2FzZSAndWludDMyJzpcbiAgICAvLyAgICAgcmV0dXJuICdpbnQnO1xuICAgIC8vICAgY2FzZSAndWludDgnOlxuICAgIC8vICAgY2FzZSAnYm9vbCc6XG4gICAgLy8gICAgIHJldHVybiAnYnl0ZSc7XG4gICAgLy8gICBjYXNlICdmbG9hdDMyJzpcbiAgICAvLyAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgIC8vICAgICByZXR1cm4gJ2Zsb2F0JztcbiAgICAvLyAgIGRlZmF1bHQ6XG4gICAgLy8gICAgIHRocm93IG5ldyBFcnJvcihgVGVuc29yRGF0YSB0eXBlICR7ZGF0YVR5cGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICAvLyB9XG4gIH1cbiAgY2xlYXJBY3RpdmVUZXh0dXJlcygpOiB2b2lkIHtcbiAgICB0aGlzLmdsQ29udGV4dC5jbGVhckFjdGl2ZVRleHR1cmVzKCk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuLi8uLi9iYWNrZW5kJztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQgeyBPcGVyYXRvciB9IGZyb20gJy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBPcFNldCwgcmVzb2x2ZU9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vb3BzZXQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL3Nlc3Npb24nO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMQmFja2VuZCB9IGZyb20gJy4uL2JhY2tlbmQtd2ViZ2wnO1xuXG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFdFQkdMX09QX1JFU09MVkVfUlVMRVMgfSBmcm9tICcuL29wLXJlc29sdmUtcnVsZXMnO1xuaW1wb3J0IHsgUHJvZ3JhbU1hbmFnZXIgfSBmcm9tICcuL3Byb2dyYW0tbWFuYWdlcic7XG5pbXBvcnQgeyBQcmVmZXJMb2dpY2FsU3RyYXRlZ3ksIFRleHR1cmVMYXlvdXRTdHJhdGVneSB9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHsgVGV4dHVyZU1hbmFnZXIgfSBmcm9tICcuL3RleHR1cmUtbWFuYWdlcic7XG5pbXBvcnQgeyBUZXh0dXJlRGF0YSB9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgY2xhc3MgV2ViR0xTZXNzaW9uSGFuZGxlciBpbXBsZW1lbnRzIFNlc3Npb25IYW5kbGVyIHtcbiAgcHJvZ3JhbU1hbmFnZXI6IFByb2dyYW1NYW5hZ2VyO1xuICB0ZXh0dXJlTWFuYWdlcjogVGV4dHVyZU1hbmFnZXI7XG4gIGxheW91dFN0cmF0ZWd5OiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3k7XG4gIHBhY2tlZFRleHR1cmVEYXRhQ2FjaGU6IE1hcDxUZW5zb3IuSWQsIFRleHR1cmVEYXRhPjtcbiAgdW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlOiBNYXA8VGVuc29yLklkLCBUZXh0dXJlRGF0YT47XG4gIHBhY2sydW5wYWNrTWFwOiBNYXA8VGVuc29yLklkLCBUZW5zb3IuSWQ+O1xuICB1bnBhY2sycGFja01hcDogTWFwPFRlbnNvci5JZCwgVGVuc29yLklkPjtcbiAgaW5pdGlhbGl6ZXJzOiBTZXQ8VGVuc29yLklkPjtcbiAgcGFjaz86IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGJhY2tlbmQ6IFdlYkdMQmFja2VuZCxcbiAgICBwdWJsaWMgcmVhZG9ubHkgY29udGV4dDogU2Vzc2lvbi5Db250ZXh0LFxuICApIHtcbiAgICB0aGlzLmxheW91dFN0cmF0ZWd5ID0gbmV3IFByZWZlckxvZ2ljYWxTdHJhdGVneShiYWNrZW5kLmdsQ29udGV4dC5tYXhUZXh0dXJlU2l6ZSk7XG4gICAgdGhpcy5wcm9ncmFtTWFuYWdlciA9IG5ldyBQcm9ncmFtTWFuYWdlcih0aGlzLmNvbnRleHQucHJvZmlsZXIsIGJhY2tlbmQuZ2xDb250ZXh0LCB0aGlzLmxheW91dFN0cmF0ZWd5KTtcbiAgICB0aGlzLnRleHR1cmVNYW5hZ2VyID0gbmV3IFRleHR1cmVNYW5hZ2VyKGJhY2tlbmQuZ2xDb250ZXh0LCB0aGlzLmxheW91dFN0cmF0ZWd5LCB0aGlzLmNvbnRleHQucHJvZmlsZXIsIHtcbiAgICAgIHJldXNlVGV4dHVyZXM6IGJhY2tlbmQudGV4dHVyZUNhY2hlTW9kZSA9PT0gJ2Z1bGwnLFxuICAgIH0pO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnBhY2sgPSBiYWNrZW5kLnBhY2s7XG4gICAgdGhpcy5wYWNrMnVucGFja01hcCA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFjazJwYWNrTWFwID0gbmV3IE1hcCgpO1xuICB9XG5cbiAgY3JlYXRlSW5mZXJlbmNlSGFuZGxlcigpIHtcbiAgICByZXR1cm4gbmV3IFdlYkdMSW5mZXJlbmNlSGFuZGxlcih0aGlzKTtcbiAgfVxuICBvbkdyYXBoSW5pdGlhbGl6ZWQoZ3JhcGg6IEdyYXBoKTogdm9pZCB7XG4gICAgY29uc3QgaW5pdGlhbGl6ZXJzID0gZ3JhcGhcbiAgICAgIC5nZXRWYWx1ZXMoKVxuICAgICAgLmZpbHRlcigodikgPT4gdi5mcm9tID09PSAtMSAmJiB2LnRlbnNvcilcbiAgICAgIC5tYXAoKHYpID0+IHYudGVuc29yIS5kYXRhSWQpO1xuICAgIHRoaXMuaW5pdGlhbGl6ZXJzID0gbmV3IFNldChpbml0aWFsaXplcnMpO1xuICB9XG4gIGlzSW5pdGlhbGl6ZXIodGVuc29ySWQ6IFRlbnNvci5JZCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmluaXRpYWxpemVycyA/IHRoaXMuaW5pdGlhbGl6ZXJzLmhhcyh0ZW5zb3JJZCkgOiBmYWxzZTtcbiAgfVxuICBhZGRJbml0aWFsaXplcih0ZW5zb3JJZDogVGVuc29yLklkKTogdm9pZCB7XG4gICAgdGhpcy5pbml0aWFsaXplcnMuYWRkKHRlbnNvcklkKTtcbiAgfVxuICBnZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZDogVGVuc29yLklkLCBpc1BhY2tlZDogYm9vbGVhbik6IFRleHR1cmVEYXRhIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoaXNQYWNrZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZ2V0KHRlbnNvcklkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmdldCh0ZW5zb3JJZCk7XG4gICAgfVxuICB9XG4gIHNldFRleHR1cmVEYXRhKHRlbnNvcklkOiBUZW5zb3IuSWQsIHRleHR1cmVEYXRhOiBUZXh0dXJlRGF0YSwgaXNQYWNrZWQgPSBmYWxzZSk6IHZvaWQge1xuICAgIExvZ2dlci52ZXJib3NlKCdXZWJHTFNlc3Npb25IYW5kbGVyJywgJ1N0b3JpbmcgVGV4dHVyZSBkYXRhIGluIGNhY2hlJyk7XG4gICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuc2V0KHRlbnNvcklkLCB0ZXh0dXJlRGF0YSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLnNldCh0ZW5zb3JJZCwgdGV4dHVyZURhdGEpO1xuICAgIH1cbiAgfVxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMucHJvZ3JhbU1hbmFnZXIuZGlzcG9zZSgpO1xuICAgIHRoaXMudGV4dHVyZU1hbmFnZXIuY2xlYXJBY3RpdmVUZXh0dXJlcygpO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5mb3JFYWNoKCh0ZCkgPT4gdGhpcy50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCwgdHJ1ZSkpO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZS5mb3JFYWNoKCh0ZCkgPT4gdGhpcy50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCwgdHJ1ZSkpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICB9XG4gIHJlc29sdmUobm9kZTogR3JhcGguTm9kZSwgb3BzZXRzOiByZWFkb25seSBPcFNldFtdLCBncmFwaDogR3JhcGgpOiBPcGVyYXRvciB7XG4gICAgY29uc3Qgb3AgPSByZXNvbHZlT3BlcmF0b3Iobm9kZSwgb3BzZXRzLCBXRUJHTF9PUF9SRVNPTFZFX1JVTEVTKTtcbiAgICByZXR1cm4geyBpbXBsOiBvcC5vcEltcGwsIGNvbnRleHQ6IG9wLm9wSW5pdCA/IG9wLm9wSW5pdChub2RlLCBncmFwaCkgOiBub2RlIH07XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZW52IH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0ICogYXMgRGF0YUVuY29kZXJzIGZyb20gJy4vdGV4dHVyZS1kYXRhLWVuY29kZXInO1xuaW1wb3J0IHsgRGF0YUVuY29kZXIsIEVuY29kZXIsIEVuY29kZXJVc2FnZSB9IGZyb20gJy4vdGV4dHVyZS1kYXRhLWVuY29kZXInO1xuaW1wb3J0IHsgcmVwZWF0ZWRUcnkgfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBGZW5jZUNvbnRleHQge1xuICBxdWVyeTogV2ViR0xTeW5jIHwgbnVsbDtcbiAgaXNGZW5jZVBhc3NlZCgpOiBib29sZWFuO1xufVxuXG50eXBlIFBvbGxJdGVtID0ge1xuICBpc0RvbmVGbjogKCkgPT4gYm9vbGVhbjtcbiAgcmVzb2x2ZUZuOiAoKSA9PiB2b2lkO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhclNlYXJjaExhc3RUcnVlKGFycjogQXJyYXk8KCkgPT4gYm9vbGVhbj4pOiBudW1iZXIge1xuICBsZXQgaSA9IDA7XG4gIGZvciAoOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgaXNEb25lID0gYXJyW2ldKCk7XG4gICAgaWYgKCFpc0RvbmUpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gaSAtIDE7XG59XG5cbi8qKlxuICogQWJzdHJhY3Rpb24gYW5kIHdyYXBwZXIgYXJvdW5kIFdlYkdMUmVuZGVyaW5nQ29udGV4dCBhbmQgaXRzIG9wZXJhdGlvbnNcbiAqL1xuZXhwb3J0IGNsYXNzIFdlYkdMQ29udGV4dCB7XG4gIGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQ7XG4gIHZlcnNpb246IDEgfCAyO1xuXG4gIHByaXZhdGUgdmVydGV4YnVmZmVyOiBXZWJHTEJ1ZmZlcjtcbiAgcHJpdmF0ZSBmcmFtZWJ1ZmZlcjogV2ViR0xGcmFtZWJ1ZmZlcjtcblxuICAvLyBXZWJHTCBmbGFncyBhbmQgdml0YWwgcGFyYW1ldGVyc1xuICBwcml2YXRlIGlzRmxvYXRUZXh0dXJlQXR0YWNoYWJsZVRvRnJhbWVCdWZmZXI6IGJvb2xlYW47XG4gIGlzRmxvYXQzMkRvd25sb2FkU3VwcG9ydGVkOiBib29sZWFuO1xuICBpc1JlbmRlckZsb2F0MzJTdXBwb3J0ZWQ6IGJvb2xlYW47XG4gIGlzQmxlbmRTdXBwb3J0ZWQ6IGJvb2xlYW47XG4gIG1heFRleHR1cmVTaXplOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbWF4Q29tYmluZWRUZXh0dXJlSW1hZ2VVbml0czogbnVtYmVyO1xuICBwcml2YXRlIG1heFRleHR1cmVJbWFnZVVuaXRzOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbWF4Q3ViZU1hcFRleHR1cmVTaXplOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgc2hhZGluZ0xhbmd1YWdlVmVyc2lvbjogc3RyaW5nO1xuICAvLyBwcml2YXRlIHdlYmdsVmVuZG9yOiBzdHJpbmc7XG4gIC8vIHByaXZhdGUgd2ViZ2xWZXJzaW9uOiBzdHJpbmc7XG5cbiAgLy8gV2ViR0wyIGZsYWdzIGFuZCB2aXRhbCBwYXJhbWV0ZXJzXG4gIC8vIHByaXZhdGUgbWF4M0RUZXh0dXJlU2l6ZTogbnVtYmVyO1xuICAvLyBwcml2YXRlIG1heEFycmF5VGV4dHVyZUxheWVyczogbnVtYmVyO1xuICAvLyBwcml2YXRlIG1heENvbG9yQXR0YWNobWVudHM6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBtYXhEcmF3QnVmZmVyczogbnVtYmVyO1xuXG4gIC8vIFdlYkdMIGV4dGVuc2lvbnNcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNhbWVsY2FzZVxuICB0ZXh0dXJlRmxvYXRFeHRlbnNpb246IE9FU190ZXh0dXJlX2Zsb2F0IHwgbnVsbDtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNhbWVsY2FzZVxuICB0ZXh0dXJlSGFsZkZsb2F0RXh0ZW5zaW9uOiBPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0IHwgbnVsbDtcblxuICAvLyBXZWJHTDIgZXh0ZW5zaW9uc1xuICBjb2xvckJ1ZmZlckZsb2F0RXh0ZW5zaW9uOiB1bmtub3duIHwgbnVsbDtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuICBkaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb246IHsgVElNRV9FTEFQU0VEX0VYVDogR0xlbnVtOyBHUFVfRElTSk9JTlRfRVhUOiBHTGVudW0gfSB8IG51bGw7XG5cbiAgcHJpdmF0ZSBkaXNwb3NlZDogYm9vbGVhbjtcbiAgcHJpdmF0ZSBmcmFtZUJ1ZmZlckJvdW5kID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdmVyc2lvbjogMSB8IDIpIHtcbiAgICB0aGlzLmdsID0gZ2w7XG4gICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjtcblxuICAgIHRoaXMuZ2V0RXh0ZW5zaW9ucygpO1xuICAgIHRoaXMudmVydGV4YnVmZmVyID0gdGhpcy5jcmVhdGVWZXJ0ZXhidWZmZXIoKTtcbiAgICB0aGlzLmZyYW1lYnVmZmVyID0gdGhpcy5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgIHRoaXMucXVlcnlWaXRhbFBhcmFtZXRlcnMoKTtcbiAgfVxuXG4gIGFsbG9jYXRlVGV4dHVyZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgZW5jb2RlcjogRGF0YUVuY29kZXIsIGRhdGE/OiBFbmNvZGVyLkRhdGFBcnJheVR5cGUpOiBXZWJHTFRleHR1cmUge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAvLyBjcmVhdGUgdGhlIHRleHR1cmVcbiAgICBjb25zdCB0ZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuICAgIC8vIGJpbmQgdGhlIHRleHR1cmUgc28gdGhlIGZvbGxvd2luZyBtZXRob2RzIGVmZmVjdCB0aGlzIHRleHR1cmUuXG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01JTl9GSUxURVIsIGdsLk5FQVJFU1QpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NQUdfRklMVEVSLCBnbC5ORUFSRVNUKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9TLCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9ULCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICBjb25zdCBidWZmZXIgPSBkYXRhID8gZW5jb2Rlci5lbmNvZGUoZGF0YSwgd2lkdGggKiBoZWlnaHQpIDogbnVsbDtcbiAgICBnbC50ZXhJbWFnZTJEKFxuICAgICAgZ2wuVEVYVFVSRV8yRCxcbiAgICAgIDAsIC8vIExldmVsIG9mIGRldGFpbC5cbiAgICAgIGVuY29kZXIuaW50ZXJuYWxGb3JtYXQsXG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIDAsIC8vIEFsd2F5cyAwIGluIE9wZW5HTCBFUy5cbiAgICAgIGVuY29kZXIuZm9ybWF0LFxuICAgICAgZW5jb2Rlci50ZXh0dXJlVHlwZSxcbiAgICAgIGJ1ZmZlcixcbiAgICApO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICAgIHJldHVybiB0ZXh0dXJlIGFzIFdlYkdMVGV4dHVyZTtcbiAgfVxuICB1cGRhdGVUZXh0dXJlKFxuICAgIHRleHR1cmU6IFdlYkdMVGV4dHVyZSxcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIGVuY29kZXI6IERhdGFFbmNvZGVyLFxuICAgIGRhdGE6IEVuY29kZXIuRGF0YUFycmF5VHlwZSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIGNvbnN0IGJ1ZmZlciA9IGVuY29kZXIuZW5jb2RlKGRhdGEsIHdpZHRoICogaGVpZ2h0KTtcbiAgICBnbC50ZXhTdWJJbWFnZTJEKFxuICAgICAgZ2wuVEVYVFVSRV8yRCxcbiAgICAgIDAsIC8vIGxldmVsXG4gICAgICAwLCAvLyB4b2Zmc2V0XG4gICAgICAwLCAvLyB5b2Zmc2V0XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIGVuY29kZXIuZm9ybWF0LFxuICAgICAgZW5jb2Rlci50ZXh0dXJlVHlwZSxcbiAgICAgIGJ1ZmZlcixcbiAgICApO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGF0dGFjaEZyYW1lYnVmZmVyKHRleHR1cmU6IFdlYkdMVGV4dHVyZSwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgLy8gTWFrZSBpdCB0aGUgdGFyZ2V0IGZvciBmcmFtZWJ1ZmZlciBvcGVyYXRpb25zIC0gaW5jbHVkaW5nIHJlbmRlcmluZy5cbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIHRoaXMuZnJhbWVidWZmZXIpO1xuICAgIGdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGdsLkZSQU1FQlVGRkVSLCBnbC5DT0xPUl9BVFRBQ0hNRU5UMCwgZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSwgMCk7IC8vIDAsIHdlIGFyZW4ndCB1c2luZyBNSVBNQVBzXG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgZ2wudmlld3BvcnQoMCwgMCwgd2lkdGgsIGhlaWdodCk7XG4gICAgZ2wuc2Npc3NvcigwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgfVxuICByZWFkVGV4dHVyZShcbiAgICB0ZXh0dXJlOiBXZWJHTFRleHR1cmUsXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICBkYXRhU2l6ZTogbnVtYmVyLFxuICAgIGRhdGFUeXBlOiBFbmNvZGVyLkRhdGFUeXBlLFxuICAgIGNoYW5uZWxzOiBudW1iZXIsXG4gICk6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGlmICghY2hhbm5lbHMpIHtcbiAgICAgIGNoYW5uZWxzID0gMTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmZyYW1lQnVmZmVyQm91bmQpIHtcbiAgICAgIHRoaXMuYXR0YWNoRnJhbWVidWZmZXIodGV4dHVyZSwgd2lkdGgsIGhlaWdodCk7XG4gICAgfVxuICAgIGNvbnN0IGVuY29kZXIgPSB0aGlzLmdldEVuY29kZXIoZGF0YVR5cGUsIGNoYW5uZWxzKTtcbiAgICBjb25zdCBidWZmZXIgPSBlbmNvZGVyLmFsbG9jYXRlKHdpZHRoICogaGVpZ2h0KTtcbiAgICAvLyBiaW5kIHRleHR1cmUgdG8gZnJhbWVidWZmZXJcbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICBnbC5mcmFtZWJ1ZmZlclRleHR1cmUyRChnbC5GUkFNRUJVRkZFUiwgZ2wuQ09MT1JfQVRUQUNITUVOVDAsIGdsLlRFWFRVUkVfMkQsIHRleHR1cmUsIDApOyAvLyAwLCB3ZSBhcmVuJ3QgdXNpbmcgTUlQTUFQc1xuICAgIC8vIFRPRE86IENoZWNrIGlmIGZyYW1lYnVmZmVyIGlzIHJlYWR5XG4gICAgZ2wucmVhZFBpeGVscygwLCAwLCB3aWR0aCwgaGVpZ2h0LCBnbC5SR0JBLCBlbmNvZGVyLnRleHR1cmVUeXBlLCBidWZmZXIpO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICAgIC8vIHVuYmluZCBGQlxuICAgIHJldHVybiBlbmNvZGVyLmRlY29kZShidWZmZXIsIGRhdGFTaXplKTtcbiAgfVxuXG4gIGlzRnJhbWVidWZmZXJSZWFkeSgpOiBib29sZWFuIHtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgbG9naWMgdG8gY2hlY2sgaWYgdGhlIGZyYW1lYnVmZmVyIGlzIHJlYWR5XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgZ2V0QWN0aXZlVGV4dHVyZSgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBuID0gZ2wuZ2V0UGFyYW1ldGVyKHRoaXMuZ2wuQUNUSVZFX1RFWFRVUkUpO1xuICAgIHJldHVybiBgVEVYVFVSRSR7biAtIGdsLlRFWFRVUkUwfWA7XG4gIH1cbiAgZ2V0VGV4dHVyZUJpbmRpbmcoKTogV2ViR0xUZXh0dXJlIHtcbiAgICByZXR1cm4gdGhpcy5nbC5nZXRQYXJhbWV0ZXIodGhpcy5nbC5URVhUVVJFX0JJTkRJTkdfMkQpO1xuICB9XG4gIGdldEZyYW1lYnVmZmVyQmluZGluZygpOiBXZWJHTEZyYW1lYnVmZmVyIHtcbiAgICByZXR1cm4gdGhpcy5nbC5nZXRQYXJhbWV0ZXIodGhpcy5nbC5GUkFNRUJVRkZFUl9CSU5ESU5HKTtcbiAgfVxuICBzZXRWZXJ0ZXhBdHRyaWJ1dGVzKHBvc2l0aW9uSGFuZGxlOiBudW1iZXIsIHRleHR1cmVDb29yZEhhbmRsZTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIocG9zaXRpb25IYW5kbGUsIDMsIGdsLkZMT0FULCBmYWxzZSwgMjAsIDApO1xuICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHBvc2l0aW9uSGFuZGxlKTtcbiAgICBpZiAodGV4dHVyZUNvb3JkSGFuZGxlICE9PSAtMSkge1xuICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcih0ZXh0dXJlQ29vcmRIYW5kbGUsIDIsIGdsLkZMT0FULCBmYWxzZSwgMjAsIDEyKTtcbiAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHRleHR1cmVDb29yZEhhbmRsZSk7XG4gICAgfVxuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGNyZWF0ZVByb2dyYW0odmVydGV4U2hhZGVyOiBXZWJHTFNoYWRlciwgZnJhZ1NoYWRlcjogV2ViR0xTaGFkZXIpOiBXZWJHTFByb2dyYW0ge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBwcm9ncmFtID0gZ2wuY3JlYXRlUHJvZ3JhbSgpITtcblxuICAgIC8vIHRoZSBwcm9ncmFtIGNvbnNpc3RzIG9mIG91ciBzaGFkZXJzXG4gICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIHZlcnRleFNoYWRlcik7XG4gICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIGZyYWdTaGFkZXIpO1xuICAgIGdsLmxpbmtQcm9ncmFtKHByb2dyYW0pO1xuICAgIHJldHVybiBwcm9ncmFtO1xuICB9XG4gIGNvbXBpbGVTaGFkZXIoc2hhZGVyU291cmNlOiBzdHJpbmcsIHNoYWRlclR5cGU6IG51bWJlcik6IFdlYkdMU2hhZGVyIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgY29uc3Qgc2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKHNoYWRlclR5cGUpO1xuICAgIGlmICghc2hhZGVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNyZWF0ZVNoYWRlcigpIHJldHVybmVkIG51bGwgd2l0aCB0eXBlICR7c2hhZGVyVHlwZX1gKTtcbiAgICB9XG5cbiAgICBnbC5zaGFkZXJTb3VyY2Uoc2hhZGVyLCBzaGFkZXJTb3VyY2UpO1xuICAgIGdsLmNvbXBpbGVTaGFkZXIoc2hhZGVyKTtcbiAgICBpZiAoZ2wuZ2V0U2hhZGVyUGFyYW1ldGVyKHNoYWRlciwgZ2wuQ09NUElMRV9TVEFUVVMpID09PSBmYWxzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gY29tcGlsZSBzaGFkZXI6ICR7Z2wuZ2V0U2hhZGVySW5mb0xvZyhzaGFkZXIpfVxuU2hhZGVyIHNvdXJjZTpcbiR7c2hhZGVyU291cmNlfWApO1xuICAgIH1cbiAgICByZXR1cm4gc2hhZGVyO1xuICB9XG4gIGRlbGV0ZVNoYWRlcihzaGFkZXI6IFdlYkdMU2hhZGVyKTogdm9pZCB7XG4gICAgdGhpcy5nbC5kZWxldGVTaGFkZXIoc2hhZGVyKTtcbiAgfVxuICBiaW5kVGV4dHVyZVRvVW5pZm9ybSh0ZXh0dXJlOiBXZWJHTFRleHR1cmUsIHBvc2l0aW9uOiBudW1iZXIsIHVuaWZvcm1IYW5kbGU6IFdlYkdMVW5pZm9ybUxvY2F0aW9uKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGdsLmFjdGl2ZVRleHR1cmUoZ2wuVEVYVFVSRTAgKyBwb3NpdGlvbik7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgZ2wudW5pZm9ybTFpKHVuaWZvcm1IYW5kbGUsIHBvc2l0aW9uKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgfVxuICBkcmF3KCk6IHZvaWQge1xuICAgIHRoaXMuZ2wuZHJhd0FycmF5cyh0aGlzLmdsLlRSSUFOR0xFX1NUUklQLCAwLCA0KTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgfVxuICBjaGVja0Vycm9yKCk6IHZvaWQge1xuICAgIGlmIChlbnYuZGVidWcpIHtcbiAgICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAgIGNvbnN0IGVycm9yID0gZ2wuZ2V0RXJyb3IoKTtcbiAgICAgIGxldCBsYWJlbCA9ICcnO1xuICAgICAgc3dpdGNoIChlcnJvcikge1xuICAgICAgICBjYXNlIGdsLk5PX0VSUk9SOlxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY2FzZSBnbC5JTlZBTElEX0VOVU06XG4gICAgICAgICAgbGFiZWwgPSAnSU5WQUxJRF9FTlVNJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBnbC5JTlZBTElEX1ZBTFVFOlxuICAgICAgICAgIGxhYmVsID0gJ0lOVkFMSURfVkFMVUUnO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIGdsLklOVkFMSURfT1BFUkFUSU9OOlxuICAgICAgICAgIGxhYmVsID0gJ0lOVkFMSURfT1BFUkFUSU9OJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBnbC5JTlZBTElEX0ZSQU1FQlVGRkVSX09QRVJBVElPTjpcbiAgICAgICAgICBsYWJlbCA9ICdJTlZBTElEX0ZSQU1FQlVGRkVSX09QRVJBVElPTic7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgZ2wuT1VUX09GX01FTU9SWTpcbiAgICAgICAgICBsYWJlbCA9ICdPVVRfT0ZfTUVNT1JZJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBnbC5DT05URVhUX0xPU1RfV0VCR0w6XG4gICAgICAgICAgbGFiZWwgPSAnQ09OVEVYVF9MT1NUX1dFQkdMJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBsYWJlbCA9IGBVbmtub3duIFdlYkdMIEVycm9yOiAke2Vycm9yLnRvU3RyaW5nKDE2KX1gO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGxhYmVsKTtcbiAgICB9XG4gIH1cbiAgZGVsZXRlVGV4dHVyZSh0ZXh0dXJlOiBXZWJHTFRleHR1cmUpOiB2b2lkIHtcbiAgICB0aGlzLmdsLmRlbGV0ZVRleHR1cmUodGV4dHVyZSk7XG4gIH1cbiAgZGVsZXRlUHJvZ3JhbShwcm9ncmFtOiBXZWJHTFByb2dyYW0pOiB2b2lkIHtcbiAgICB0aGlzLmdsLmRlbGV0ZVByb2dyYW0ocHJvZ3JhbSk7XG4gIH1cbiAgZ2V0RW5jb2RlcihkYXRhVHlwZTogRW5jb2Rlci5EYXRhVHlwZSwgY2hhbm5lbHM6IG51bWJlciwgdXNhZ2U6IEVuY29kZXJVc2FnZSA9IEVuY29kZXJVc2FnZS5EZWZhdWx0KTogRGF0YUVuY29kZXIge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIHJldHVybiBuZXcgRGF0YUVuY29kZXJzLlJlZEZsb2F0MzJEYXRhRW5jb2Rlcih0aGlzLmdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQsIGNoYW5uZWxzKTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICBjYXNlICdmbG9hdCc6XG4gICAgICAgIGlmICh1c2FnZSA9PT0gRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkgfHwgdGhpcy5pc1JlbmRlckZsb2F0MzJTdXBwb3J0ZWQpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IERhdGFFbmNvZGVycy5SR0JBRmxvYXREYXRhRW5jb2Rlcih0aGlzLmdsLCBjaGFubmVscyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBEYXRhRW5jb2RlcnMuUkdCQUZsb2F0RGF0YUVuY29kZXIoXG4gICAgICAgICAgICB0aGlzLmdsLFxuICAgICAgICAgICAgY2hhbm5lbHMsXG4gICAgICAgICAgICB0aGlzLnRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb24hLkhBTEZfRkxPQVRfT0VTLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgJ2ludCc6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJyk7XG4gICAgICBjYXNlICdieXRlJzpcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRhRW5jb2RlcnMuVWludDhEYXRhRW5jb2Rlcih0aGlzLmdsLCBjaGFubmVscyk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGF0YVR5cGU6ICR7ZGF0YVR5cGV9YCk7XG4gICAgfVxuICB9XG4gIGNsZWFyQWN0aXZlVGV4dHVyZXMoKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGZvciAobGV0IHVuaXQgPSAwOyB1bml0IDwgdGhpcy5tYXhUZXh0dXJlSW1hZ2VVbml0czsgKyt1bml0KSB7XG4gICAgICBnbC5hY3RpdmVUZXh0dXJlKGdsLlRFWFRVUkUwICsgdW5pdCk7XG4gICAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCBudWxsKTtcbiAgICB9XG4gIH1cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNwb3NlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBudWxsKTtcbiAgICBnbC5kZWxldGVGcmFtZWJ1ZmZlcih0aGlzLmZyYW1lYnVmZmVyKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgbnVsbCk7XG4gICAgZ2wuZGVsZXRlQnVmZmVyKHRoaXMudmVydGV4YnVmZmVyKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkVMRU1FTlRfQVJSQVlfQlVGRkVSLCBudWxsKTtcbiAgICBnbC5maW5pc2goKTtcbiAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRGVmYXVsdEdlb21ldHJ5KCk6IEZsb2F0MzJBcnJheSB7XG4gICAgLy8gU2V0cyBvZiB4LHkseig9MCkscyx0IGNvb3JkaW5hdGVzLlxuICAgIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KFtcbiAgICAgIC0xLjAsXG4gICAgICAxLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAxLjAsIC8vIHVwcGVyIGxlZnRcbiAgICAgIC0xLjAsXG4gICAgICAtMS4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wLCAvLyBsb3dlciBsZWZ0XG4gICAgICAxLjAsXG4gICAgICAxLjAsXG4gICAgICAwLjAsXG4gICAgICAxLjAsXG4gICAgICAxLjAsIC8vIHVwcGVyIHJpZ2h0XG4gICAgICAxLjAsXG4gICAgICAtMS4wLFxuICAgICAgMC4wLFxuICAgICAgMS4wLFxuICAgICAgMC4wLCAvLyBsb3dlciByaWdodFxuICAgIF0pO1xuICB9XG4gIHByaXZhdGUgY3JlYXRlVmVydGV4YnVmZmVyKCk6IFdlYkdMQnVmZmVyIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgY29uc3QgYnVmZmVyID0gZ2wuY3JlYXRlQnVmZmVyKCk7XG4gICAgaWYgKCFidWZmZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY3JlYXRlQnVmZmVyKCkgcmV0dXJuZWQgbnVsbCcpO1xuICAgIH1cbiAgICBjb25zdCBnZW9tZXRyeSA9IHRoaXMuY3JlYXRlRGVmYXVsdEdlb21ldHJ5KCk7XG4gICAgZ2wuYmluZEJ1ZmZlcihnbC5BUlJBWV9CVUZGRVIsIGJ1ZmZlcik7XG4gICAgZ2wuYnVmZmVyRGF0YShnbC5BUlJBWV9CVUZGRVIsIGdlb21ldHJ5LCBnbC5TVEFUSUNfRFJBVyk7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgcmV0dXJuIGJ1ZmZlcjtcbiAgfVxuICBwcml2YXRlIGNyZWF0ZUZyYW1lYnVmZmVyKCk6IFdlYkdMRnJhbWVidWZmZXIge1xuICAgIGNvbnN0IGZiID0gdGhpcy5nbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgIGlmICghZmIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY3JlYXRlRnJhbWVidWZmZXIgcmV0dXJuZWQgbnVsbCcpO1xuICAgIH1cbiAgICByZXR1cm4gZmI7XG4gIH1cblxuICBwcml2YXRlIHF1ZXJ5Vml0YWxQYXJhbWV0ZXJzKCk6IHZvaWQge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcblxuICAgIHRoaXMuaXNGbG9hdFRleHR1cmVBdHRhY2hhYmxlVG9GcmFtZUJ1ZmZlciA9IHRoaXMuY2hlY2tGbG9hdFRleHR1cmVBdHRhY2hhYmxlVG9GcmFtZUJ1ZmZlcigpO1xuICAgIHRoaXMuaXNSZW5kZXJGbG9hdDMyU3VwcG9ydGVkID0gdGhpcy5jaGVja1JlbmRlckZsb2F0MzIoKTtcbiAgICB0aGlzLmlzRmxvYXQzMkRvd25sb2FkU3VwcG9ydGVkID0gdGhpcy5jaGVja0Zsb2F0MzJEb3dubG9hZCgpO1xuXG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMSAmJiAhdGhpcy50ZXh0dXJlSGFsZkZsb2F0RXh0ZW5zaW9uICYmICF0aGlzLmlzUmVuZGVyRmxvYXQzMlN1cHBvcnRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdib3RoIGZsb2F0MzIgYW5kIGZsb2F0MTYgVGV4dHVyZVR5cGUgYXJlIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG5cbiAgICB0aGlzLmlzQmxlbmRTdXBwb3J0ZWQgPSAhdGhpcy5pc1JlbmRlckZsb2F0MzJTdXBwb3J0ZWQgfHwgdGhpcy5jaGVja0Zsb2F0MzJCbGVuZCgpO1xuXG4gICAgLy8gdGhpcy5tYXhDb21iaW5lZFRleHR1cmVJbWFnZVVuaXRzID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLk1BWF9DT01CSU5FRF9URVhUVVJFX0lNQUdFX1VOSVRTKTtcbiAgICB0aGlzLm1heFRleHR1cmVTaXplID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLk1BWF9URVhUVVJFX1NJWkUpO1xuICAgIHRoaXMubWF4VGV4dHVyZUltYWdlVW5pdHMgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX1RFWFRVUkVfSU1BR0VfVU5JVFMpO1xuICAgIC8vIHRoaXMubWF4Q3ViZU1hcFRleHR1cmVTaXplID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLk1BWF9DVUJFX01BUF9URVhUVVJFX1NJWkUpO1xuICAgIC8vIHRoaXMuc2hhZGluZ0xhbmd1YWdlVmVyc2lvbiA9IGdsLmdldFBhcmFtZXRlcihnbC5TSEFESU5HX0xBTkdVQUdFX1ZFUlNJT04pO1xuICAgIC8vIHRoaXMud2ViZ2xWZW5kb3IgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuVkVORE9SKTtcbiAgICAvLyB0aGlzLndlYmdsVmVyc2lvbiA9IGdsLmdldFBhcmFtZXRlcihnbC5WRVJTSU9OKTtcblxuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIC8vIHRoaXMubWF4M0RUZXh0dXJlU2l6ZSA9IGdsLmdldFBhcmFtZXRlcihXZWJHTDJSZW5kZXJpbmdDb250ZXh0Lk1BWF8zRF9URVhUVVJFX1NJWkUpO1xuICAgICAgLy8gdGhpcy5tYXhBcnJheVRleHR1cmVMYXllcnMgPSBnbC5nZXRQYXJhbWV0ZXIoV2ViR0wyUmVuZGVyaW5nQ29udGV4dC5NQVhfQVJSQVlfVEVYVFVSRV9MQVlFUlMpO1xuICAgICAgLy8gdGhpcy5tYXhDb2xvckF0dGFjaG1lbnRzID0gZ2wuZ2V0UGFyYW1ldGVyKFdlYkdMMlJlbmRlcmluZ0NvbnRleHQuTUFYX0NPTE9SX0FUVEFDSE1FTlRTKTtcbiAgICAgIC8vIHRoaXMubWF4RHJhd0J1ZmZlcnMgPSBnbC5nZXRQYXJhbWV0ZXIoV2ViR0wyUmVuZGVyaW5nQ29udGV4dC5NQVhfRFJBV19CVUZGRVJTKTtcbiAgICB9XG4gIH1cbiAgcHJpdmF0ZSBnZXRFeHRlbnNpb25zKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIHRoaXMuY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbiA9IHRoaXMuZ2wuZ2V0RXh0ZW5zaW9uKCdFWFRfY29sb3JfYnVmZmVyX2Zsb2F0Jyk7XG4gICAgICB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbiA9IHRoaXMuZ2wuZ2V0RXh0ZW5zaW9uKCdFWFRfZGlzam9pbnRfdGltZXJfcXVlcnlfd2ViZ2wyJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGV4dHVyZUZsb2F0RXh0ZW5zaW9uID0gdGhpcy5nbC5nZXRFeHRlbnNpb24oJ09FU190ZXh0dXJlX2Zsb2F0Jyk7XG4gICAgICB0aGlzLnRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb24gPSB0aGlzLmdsLmdldEV4dGVuc2lvbignT0VTX3RleHR1cmVfaGFsZl9mbG9hdCcpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tGbG9hdFRleHR1cmVBdHRhY2hhYmxlVG9GcmFtZUJ1ZmZlcigpOiBib29sZWFuIHtcbiAgICAvLyB0ZXN0IHdoZXRoZXIgRmxvYXQzMiB0ZXh0dXJlIGlzIHN1cHBvcnRlZDpcbiAgICAvLyBTVEVQLjEgY3JlYXRlIGEgZmxvYXQgdGV4dHVyZVxuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCB0ZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbiAgICBjb25zdCBpbnRlcm5hbEZvcm1hdCA9IHRoaXMudmVyc2lvbiA9PT0gMiA/IChnbCBhcyB1bmtub3duIGFzIHsgUkdCQTMyRjogbnVtYmVyIH0pLlJHQkEzMkYgOiBnbC5SR0JBO1xuICAgIGdsLnRleEltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgaW50ZXJuYWxGb3JtYXQsIDEsIDEsIDAsIGdsLlJHQkEsIGdsLkZMT0FULCBudWxsKTtcbiAgICAvLyBTVEVQLjIgYmluZCBhIGZyYW1lIGJ1ZmZlclxuICAgIGNvbnN0IGZyYW1lQnVmZmVyID0gZ2wuY3JlYXRlRnJhbWVidWZmZXIoKTtcbiAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIGZyYW1lQnVmZmVyKTtcbiAgICAvLyBTVEVQLjMgYXR0YWNoIHRleHR1cmUgdG8gZnJhbWVidWZmZXJcbiAgICBnbC5mcmFtZWJ1ZmZlclRleHR1cmUyRChnbC5GUkFNRUJVRkZFUiwgZ2wuQ09MT1JfQVRUQUNITUVOVDAsIGdsLlRFWFRVUkVfMkQsIHRleHR1cmUsIDApO1xuICAgIC8vIFNURVAuNCB0ZXN0IHdoZXRoZXIgZnJhbWVidWZmZXIgaXMgY29tcGxldGVcbiAgICBjb25zdCBpc0NvbXBsZXRlID0gZ2wuY2hlY2tGcmFtZWJ1ZmZlclN0YXR1cyhnbC5GUkFNRUJVRkZFUikgPT09IGdsLkZSQU1FQlVGRkVSX0NPTVBMRVRFO1xuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIG51bGwpO1xuICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgbnVsbCk7XG4gICAgZ2wuZGVsZXRlVGV4dHVyZSh0ZXh0dXJlKTtcbiAgICBnbC5kZWxldGVGcmFtZWJ1ZmZlcihmcmFtZUJ1ZmZlcik7XG4gICAgcmV0dXJuIGlzQ29tcGxldGU7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrUmVuZGVyRmxvYXQzMigpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICBpZiAoIXRoaXMuY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy50ZXh0dXJlRmxvYXRFeHRlbnNpb24pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5pc0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0Zsb2F0MzJEb3dubG9hZCgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICBpZiAoIXRoaXMuY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy50ZXh0dXJlRmxvYXRFeHRlbnNpb24pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLmdsLmdldEV4dGVuc2lvbignV0VCR0xfY29sb3JfYnVmZmVyX2Zsb2F0JykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5pc0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIHdoZXRoZXIgR0xfQkxFTkQgaXMgc3VwcG9ydGVkXG4gICAqL1xuICBwcml2YXRlIGNoZWNrRmxvYXQzMkJsZW5kKCk6IGJvb2xlYW4ge1xuICAgIC8vIGl0IGxvb2tzIGxpa2UgY3VycmVudGx5ICgyMDE5LTA1LTA4KSB0aGVyZSBpcyBubyBlYXN5IHdheSB0byBkZXRlY3Qgd2hldGhlciBCTEVORCBpcyBzdXBwb3J0ZWRcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L29ubnhqcy9pc3N1ZXMvMTQ1XG5cbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG5cbiAgICBsZXQgdGV4dHVyZTogV2ViR0xUZXh0dXJlIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICBsZXQgZnJhbWVCdWZmZXI6IFdlYkdMRnJhbWVidWZmZXIgfCBudWxsIHwgdW5kZWZpbmVkO1xuICAgIGxldCB2ZXJ0ZXhTaGFkZXI6IFdlYkdMU2hhZGVyIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICBsZXQgZnJhZ21lbnRTaGFkZXI6IFdlYkdMU2hhZGVyIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICBsZXQgcHJvZ3JhbTogV2ViR0xQcm9ncmFtIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuICAgIHRyeSB7XG4gICAgICB0ZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuICAgICAgZnJhbWVCdWZmZXIgPSBnbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbiAgICAgIGNvbnN0IGludGVybmFsRm9ybWF0ID0gdGhpcy52ZXJzaW9uID09PSAyID8gKGdsIGFzIHVua25vd24gYXMgeyBSR0JBMzJGOiBudW1iZXIgfSkuUkdCQTMyRiA6IGdsLlJHQkE7XG4gICAgICBnbC50ZXhJbWFnZTJEKGdsLlRFWFRVUkVfMkQsIDAsIGludGVybmFsRm9ybWF0LCAxLCAxLCAwLCBnbC5SR0JBLCBnbC5GTE9BVCwgbnVsbCk7XG5cbiAgICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgZnJhbWVCdWZmZXIpO1xuICAgICAgZ2wuZnJhbWVidWZmZXJUZXh0dXJlMkQoZ2wuRlJBTUVCVUZGRVIsIGdsLkNPTE9SX0FUVEFDSE1FTlQwLCBnbC5URVhUVVJFXzJELCB0ZXh0dXJlLCAwKTtcblxuICAgICAgZ2wuZW5hYmxlKGdsLkJMRU5EKTtcblxuICAgICAgdmVydGV4U2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKGdsLlZFUlRFWF9TSEFERVIpO1xuICAgICAgaWYgKCF2ZXJ0ZXhTaGFkZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgZ2wuc2hhZGVyU291cmNlKHZlcnRleFNoYWRlciwgJ3ZvaWQgbWFpbigpe30nKTtcbiAgICAgIGdsLmNvbXBpbGVTaGFkZXIodmVydGV4U2hhZGVyKTtcblxuICAgICAgZnJhZ21lbnRTaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIoZ2wuRlJBR01FTlRfU0hBREVSKTtcbiAgICAgIGlmICghZnJhZ21lbnRTaGFkZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgZ2wuc2hhZGVyU291cmNlKGZyYWdtZW50U2hhZGVyLCAncHJlY2lzaW9uIGhpZ2hwIGZsb2F0O3ZvaWQgbWFpbigpe2dsX0ZyYWdDb2xvcj12ZWM0KDAuNSk7fScpO1xuICAgICAgZ2wuY29tcGlsZVNoYWRlcihmcmFnbWVudFNoYWRlcik7XG5cbiAgICAgIHByb2dyYW0gPSBnbC5jcmVhdGVQcm9ncmFtKCk7XG4gICAgICBpZiAoIXByb2dyYW0pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIHZlcnRleFNoYWRlcik7XG4gICAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgZnJhZ21lbnRTaGFkZXIpO1xuICAgICAgZ2wubGlua1Byb2dyYW0ocHJvZ3JhbSk7XG4gICAgICBnbC51c2VQcm9ncmFtKHByb2dyYW0pO1xuXG4gICAgICBnbC5kcmF3QXJyYXlzKGdsLlBPSU5UUywgMCwgMSk7XG4gICAgICByZXR1cm4gZ2wuZ2V0RXJyb3IoKSA9PT0gZ2wuTk9fRVJST1I7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGdsLmRpc2FibGUoZ2wuQkxFTkQpO1xuXG4gICAgICBpZiAocHJvZ3JhbSkge1xuICAgICAgICBnbC5kZWxldGVQcm9ncmFtKHByb2dyYW0pO1xuICAgICAgfVxuICAgICAgaWYgKHZlcnRleFNoYWRlcikge1xuICAgICAgICBnbC5kZWxldGVTaGFkZXIodmVydGV4U2hhZGVyKTtcbiAgICAgIH1cbiAgICAgIGlmIChmcmFnbWVudFNoYWRlcikge1xuICAgICAgICBnbC5kZWxldGVTaGFkZXIoZnJhZ21lbnRTaGFkZXIpO1xuICAgICAgfVxuICAgICAgaWYgKGZyYW1lQnVmZmVyKSB7XG4gICAgICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgbnVsbCk7XG4gICAgICAgIGdsLmRlbGV0ZUZyYW1lYnVmZmVyKGZyYW1lQnVmZmVyKTtcbiAgICAgIH1cbiAgICAgIGlmICh0ZXh0dXJlKSB7XG4gICAgICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIG51bGwpO1xuICAgICAgICBnbC5kZWxldGVUZXh0dXJlKHRleHR1cmUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGJlZ2luVGltZXIoKTogV2ViR0xRdWVyeSB7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMiAmJiB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbikge1xuICAgICAgY29uc3QgZ2wyID0gdGhpcy5nbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0O1xuICAgICAgY29uc3QgZXh0ID0gdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb247XG5cbiAgICAgIGNvbnN0IHF1ZXJ5ID0gZ2wyLmNyZWF0ZVF1ZXJ5KCkgYXMgV2ViR0xRdWVyeTtcbiAgICAgIGdsMi5iZWdpblF1ZXJ5KGV4dC5USU1FX0VMQVBTRURfRVhULCBxdWVyeSk7XG4gICAgICByZXR1cm4gcXVlcnk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRPRE86IGFkZCB3ZWJnbCAxIGhhbmRsaW5nLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJHTDEgcHJvZmlsaW5nIGN1cnJlbnRseSBub3Qgc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfVxuXG4gIGVuZFRpbWVyKCkge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIgJiYgdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb24pIHtcbiAgICAgIGNvbnN0IGdsMiA9IHRoaXMuZ2wgYXMgV2ViR0wyUmVuZGVyaW5nQ29udGV4dDtcbiAgICAgIGNvbnN0IGV4dCA9IHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uO1xuICAgICAgZ2wyLmVuZFF1ZXJ5KGV4dC5USU1FX0VMQVBTRURfRVhUKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVE9ETzogYWRkIHdlYmdsIDEgaGFuZGxpbmcuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMMSBwcm9maWxpbmcgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH1cblxuICBpc1RpbWVyUmVzdWx0QXZhaWxhYmxlKHF1ZXJ5OiBXZWJHTFF1ZXJ5KTogYm9vbGVhbiB7XG4gICAgbGV0IGF2YWlsYWJsZSA9IGZhbHNlLFxuICAgICAgZGlzam9pbnQgPSBmYWxzZTtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyICYmIHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uKSB7XG4gICAgICBjb25zdCBnbDIgPSB0aGlzLmdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQ7XG4gICAgICBjb25zdCBleHQgPSB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbjtcblxuICAgICAgYXZhaWxhYmxlID0gZ2wyLmdldFF1ZXJ5UGFyYW1ldGVyKHF1ZXJ5LCBnbDIuUVVFUllfUkVTVUxUX0FWQUlMQUJMRSk7XG4gICAgICBkaXNqb2ludCA9IGdsMi5nZXRQYXJhbWV0ZXIoZXh0LkdQVV9ESVNKT0lOVF9FWFQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUT0RPOiBhZGQgd2ViZ2wgMSBoYW5kbGluZy5cbiAgICAgIHRocm93IG5ldyBFcnJvcignV2ViR0wxIHByb2ZpbGluZyBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBhdmFpbGFibGUgJiYgIWRpc2pvaW50O1xuICB9XG5cbiAgZ2V0VGltZXJSZXN1bHQocXVlcnk6IFdlYkdMUXVlcnkpOiBudW1iZXIge1xuICAgIGxldCB0aW1lRWxhcHNlZCA9IDA7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMikge1xuICAgICAgY29uc3QgZ2wyID0gdGhpcy5nbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0O1xuICAgICAgdGltZUVsYXBzZWQgPSBnbDIuZ2V0UXVlcnlQYXJhbWV0ZXIocXVlcnksIGdsMi5RVUVSWV9SRVNVTFQpO1xuICAgICAgZ2wyLmRlbGV0ZVF1ZXJ5KHF1ZXJ5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVE9ETzogYWRkIHdlYmdsIDEgaGFuZGxpbmcuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMMSBwcm9maWxpbmcgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gICAgLy8gcmV0dXJuIG1pbGlzZWNvbmRzXG4gICAgcmV0dXJuIHRpbWVFbGFwc2VkIC8gMTAwMDAwMDtcbiAgfVxuXG4gIGFzeW5jIHdhaXRGb3JRdWVyeUFuZEdldFRpbWUocXVlcnk6IFdlYkdMUXVlcnkpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGF3YWl0IHJlcGVhdGVkVHJ5KCgpID0+IHRoaXMuaXNUaW1lclJlc3VsdEF2YWlsYWJsZShxdWVyeSkpO1xuICAgIHJldHVybiB0aGlzLmdldFRpbWVyUmVzdWx0KHF1ZXJ5KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBjcmVhdGVBbmRXYWl0Rm9yRmVuY2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZmVuY2VDb250ZXh0ID0gdGhpcy5jcmVhdGVGZW5jZSh0aGlzLmdsKTtcbiAgICByZXR1cm4gdGhpcy5wb2xsRmVuY2UoZmVuY2VDb250ZXh0KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRmVuY2UoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCk6IEZlbmNlQ29udGV4dCB7XG4gICAgbGV0IGlzRmVuY2VQYXNzZWQ6ICgpID0+IGJvb2xlYW47XG4gICAgY29uc3QgZ2wyID0gZ2wgYXMgV2ViR0wyUmVuZGVyaW5nQ29udGV4dDtcbiAgICBjb25zdCBxdWVyeSA9IGdsMi5mZW5jZVN5bmMoZ2wyLlNZTkNfR1BVX0NPTU1BTkRTX0NPTVBMRVRFLCAwKTtcbiAgICBnbC5mbHVzaCgpO1xuICAgIGlmIChxdWVyeSA9PT0gbnVsbCkge1xuICAgICAgaXNGZW5jZVBhc3NlZCA9ICgpID0+IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlzRmVuY2VQYXNzZWQgPSAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IGdsMi5jbGllbnRXYWl0U3luYyhxdWVyeSwgMCwgMCk7XG4gICAgICAgIHJldHVybiBzdGF0dXMgPT09IGdsMi5BTFJFQURZX1NJR05BTEVEIHx8IHN0YXR1cyA9PT0gZ2wyLkNPTkRJVElPTl9TQVRJU0ZJRUQ7XG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4geyBxdWVyeSwgaXNGZW5jZVBhc3NlZCB9O1xuICB9XG5cbiAgYXN5bmMgcG9sbEZlbmNlKGZlbmNlQ29udGV4dDogRmVuY2VDb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICB2b2lkIHRoaXMuYWRkSXRlbVRvUG9sbChcbiAgICAgICAgKCkgPT4gZmVuY2VDb250ZXh0LmlzRmVuY2VQYXNzZWQoKSxcbiAgICAgICAgKCkgPT4gcmVzb2x2ZSgpLFxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaXRlbXNUb1BvbGw6IFBvbGxJdGVtW10gPSBbXTtcblxuICBwb2xsSXRlbXMoKTogdm9pZCB7XG4gICAgLy8gRmluZCB0aGUgbGFzdCBxdWVyeSB0aGF0IGhhcyBmaW5pc2hlZC5cbiAgICBjb25zdCBpbmRleCA9IGxpbmVhclNlYXJjaExhc3RUcnVlKHRoaXMuaXRlbXNUb1BvbGwubWFwKCh4KSA9PiB4LmlzRG9uZUZuKSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gaW5kZXg7ICsraSkge1xuICAgICAgY29uc3QgeyByZXNvbHZlRm4gfSA9IHRoaXMuaXRlbXNUb1BvbGxbaV07XG4gICAgICByZXNvbHZlRm4oKTtcbiAgICB9XG4gICAgdGhpcy5pdGVtc1RvUG9sbCA9IHRoaXMuaXRlbXNUb1BvbGwuc2xpY2UoaW5kZXggKyAxKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYWRkSXRlbVRvUG9sbChpc0RvbmVGbjogKCkgPT4gYm9vbGVhbiwgcmVzb2x2ZUZuOiAoKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5pdGVtc1RvUG9sbC5wdXNoKHsgaXNEb25lRm4sIHJlc29sdmVGbiB9KTtcbiAgICBpZiAodGhpcy5pdGVtc1RvUG9sbC5sZW5ndGggPiAxKSB7XG4gICAgICAvLyBXZSBhbHJlYWR5IGhhdmUgYSBydW5uaW5nIGxvb3AgdGhhdCBwb2xscy5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gU3RhcnQgYSBuZXcgbG9vcCB0aGF0IHBvbGxzLlxuICAgIGF3YWl0IHJlcGVhdGVkVHJ5KCgpID0+IHtcbiAgICAgIHRoaXMucG9sbEl0ZW1zKCk7XG4gICAgICAvLyBFbmQgdGhlIGxvb3AgaWYgbm8gbW9yZSBpdGVtcyB0byBwb2xsLlxuICAgICAgcmV0dXJuIHRoaXMuaXRlbXNUb1BvbGwubGVuZ3RoID09PSAwO1xuICAgIH0pO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJy4uLy4uL2luc3RydW1lbnQnO1xuXG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL3dlYmdsLWNvbnRleHQnO1xuXG5jb25zdCBjYWNoZTogeyBbY29udGV4dElkOiBzdHJpbmddOiBXZWJHTENvbnRleHQgfSA9IHt9O1xuXG4vKipcbiAqIFRoaXMgZmFjdG9yeSBmdW5jdGlvbiBjcmVhdGVzIHByb3BlciBXZWJHTFJlbmRlcmluZ0NvbnRleHQgYmFzZWQgb25cbiAqIHRoZSBjdXJyZW50IGJyb3dzZXJzIGNhcGFiaWxpdGllc1xuICogVGhlIG9yZGVyIGlzIGZyb20gaGlnaGVyL21vc3QgcmVjZW50IHZlcnNpb25zIHRvIG1vc3QgYmFzaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVdlYkdMQ29udGV4dChjb250ZXh0SWQ/OiAnd2ViZ2wnIHwgJ3dlYmdsMicpOiBXZWJHTENvbnRleHQge1xuICBsZXQgY29udGV4dDogV2ViR0xDb250ZXh0IHwgdW5kZWZpbmVkO1xuICBpZiAoKCFjb250ZXh0SWQgfHwgY29udGV4dElkID09PSAnd2ViZ2wyJykgJiYgJ3dlYmdsMicgaW4gY2FjaGUpIHtcbiAgICBjb250ZXh0ID0gY2FjaGUud2ViZ2wyO1xuICB9IGVsc2UgaWYgKCghY29udGV4dElkIHx8IGNvbnRleHRJZCA9PT0gJ3dlYmdsJykgJiYgJ3dlYmdsJyBpbiBjYWNoZSkge1xuICAgIGNvbnRleHQgPSBjYWNoZS53ZWJnbDtcbiAgfVxuXG4gIGlmICghY29udGV4dCkge1xuICAgIHRyeSB7XG4gICAgICAvLyB0cnkgdG8gY3JlYXRlIHdlYmdsIGNvbnRleHQgZnJvbSBhbiBvZmZzY3JlZW4gY2FudmFzXG4gICAgICBjb25zdCBvZmZzY3JlZW5DYW52YXMgPSBjcmVhdGVPZmZzY3JlZW5DYW52YXMoKTtcbiAgICAgIGNvbnRleHQgPSBjcmVhdGVOZXdXZWJHTENvbnRleHQob2Zmc2NyZWVuQ2FudmFzLCBjb250ZXh0SWQpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIGlmIGZhaWxlZCwgZmFsbGJhY2sgdG8gdHJ5IHRvIHVzZSBhIG5vcm1hbCBjYW52YXMgZWxlbWVudFxuICAgICAgY29uc3QgY2FudmFzID0gY3JlYXRlQ2FudmFzKCk7XG4gICAgICBjb250ZXh0ID0gY3JlYXRlTmV3V2ViR0xDb250ZXh0KGNhbnZhcywgY29udGV4dElkKTtcbiAgICB9XG4gIH1cblxuICBjb250ZXh0SWQgPSBjb250ZXh0SWQgfHwgY29udGV4dC52ZXJzaW9uID09PSAxID8gJ3dlYmdsJyA6ICd3ZWJnbDInO1xuICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG5cbiAgY2FjaGVbY29udGV4dElkXSA9IGNvbnRleHQ7XG5cbiAgaWYgKGdsLmlzQ29udGV4dExvc3QoKSkge1xuICAgIGRlbGV0ZSBjYWNoZVtjb250ZXh0SWRdO1xuICAgIHJldHVybiBjcmVhdGVXZWJHTENvbnRleHQoY29udGV4dElkKTtcbiAgfVxuXG4gIGdsLmRpc2FibGUoZ2wuREVQVEhfVEVTVCk7XG4gIGdsLmRpc2FibGUoZ2wuU1RFTkNJTF9URVNUKTtcbiAgZ2wuZGlzYWJsZShnbC5CTEVORCk7XG4gIGdsLmRpc2FibGUoZ2wuRElUSEVSKTtcbiAgZ2wuZGlzYWJsZShnbC5QT0xZR09OX09GRlNFVF9GSUxMKTtcbiAgZ2wuZGlzYWJsZShnbC5TQU1QTEVfQ09WRVJBR0UpO1xuICBnbC5lbmFibGUoZ2wuU0NJU1NPUl9URVNUKTtcbiAgZ2wuZW5hYmxlKGdsLkNVTExfRkFDRSk7XG4gIGdsLmN1bGxGYWNlKGdsLkJBQ0spO1xuXG4gIHJldHVybiBjb250ZXh0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTmV3V2ViR0xDb250ZXh0KGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQsIGNvbnRleHRJZD86ICd3ZWJnbCcgfCAnd2ViZ2wyJyk6IFdlYkdMQ29udGV4dCB7XG4gIGNvbnN0IGNvbnRleHRBdHRyaWJ1dGVzOiBXZWJHTENvbnRleHRBdHRyaWJ1dGVzID0ge1xuICAgIGFscGhhOiBmYWxzZSxcbiAgICBkZXB0aDogZmFsc2UsXG4gICAgYW50aWFsaWFzOiBmYWxzZSxcbiAgICBzdGVuY2lsOiBmYWxzZSxcbiAgICBwcmVzZXJ2ZURyYXdpbmdCdWZmZXI6IGZhbHNlLFxuICAgIHByZW11bHRpcGxpZWRBbHBoYTogZmFsc2UsXG4gICAgZmFpbElmTWFqb3JQZXJmb3JtYW5jZUNhdmVhdDogZmFsc2UsXG4gIH07XG4gIGxldCBnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0IHwgbnVsbDtcbiAgY29uc3QgY2EgPSBjb250ZXh0QXR0cmlidXRlcztcbiAgaWYgKCFjb250ZXh0SWQgfHwgY29udGV4dElkID09PSAnd2ViZ2wyJykge1xuICAgIGdsID0gY2FudmFzLmdldENvbnRleHQoJ3dlYmdsMicsIGNhKTtcbiAgICBpZiAoZ2wpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBuZXcgV2ViR0xDb250ZXh0KGdsLCAyKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBMb2dnZXIud2FybmluZygnR2xDb250ZXh0RmFjdG9yeScsIGBmYWlsZWQgdG8gY3JlYXRlIFdlYkdMQ29udGV4dCB1c2luZyBjb250ZXh0SWQgJ3dlYmdsMicuIEVycm9yOiAke2Vycn1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKCFjb250ZXh0SWQgfHwgY29udGV4dElkID09PSAnd2ViZ2wnKSB7XG4gICAgZ2wgPSBjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wnLCBjYSkgfHwgKGNhbnZhcy5nZXRDb250ZXh0KCdleHBlcmltZW50YWwtd2ViZ2wnLCBjYSkgYXMgV2ViR0xSZW5kZXJpbmdDb250ZXh0KTtcbiAgICBpZiAoZ2wpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBuZXcgV2ViR0xDb250ZXh0KGdsLCAxKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBMb2dnZXIud2FybmluZyhcbiAgICAgICAgICAnR2xDb250ZXh0RmFjdG9yeScsXG4gICAgICAgICAgYGZhaWxlZCB0byBjcmVhdGUgV2ViR0xDb250ZXh0IHVzaW5nIGNvbnRleHRJZCAnd2ViZ2wnIG9yICdleHBlcmltZW50YWwtd2ViZ2wnLiBFcnJvcjogJHtlcnJ9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZGVjbGFyZSBsZXQgT2Zmc2NyZWVuQ2FudmFzOiB7IG5ldyAod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiBIVE1MQ2FudmFzRWxlbWVudCB9O1xuXG5mdW5jdGlvbiBjcmVhdGVDYW52YXMoKTogSFRNTENhbnZhc0VsZW1lbnQge1xuICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ZhaWxlZCB0byBjcmVhdGUgY2FudmFzOiBkb2N1bWVudCBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gIH1cbiAgY29uc3QgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICBjYW52YXMud2lkdGggPSAxO1xuICBjYW52YXMuaGVpZ2h0ID0gMTtcbiAgcmV0dXJuIGNhbnZhcztcbn1cblxuZnVuY3Rpb24gY3JlYXRlT2Zmc2NyZWVuQ2FudmFzKCk6IEhUTUxDYW52YXNFbGVtZW50IHtcbiAgaWYgKHR5cGVvZiBPZmZzY3JlZW5DYW52YXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZmFpbGVkIHRvIGNyZWF0ZSBvZmZzY3JlZW4gY2FudmFzOiBPZmZzY3JlZW5DYW52YXMgaXMgbm90IHN1cHBvcnRlZCcpO1xuICB9XG4gIHJldHVybiBuZXcgT2Zmc2NyZWVuQ2FudmFzKDEsIDEpO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBlbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBCYWNrZW5kLCBTZXNzaW9uSGFuZGxlciB9IGZyb20gJy4uL2JhY2tlbmQnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vc2Vzc2lvbic7XG5cbmltcG9ydCB7IFdlYkdMU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuL3dlYmdsL3Nlc3Npb24taGFuZGxlcic7XG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL3dlYmdsL3dlYmdsLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlV2ViR0xDb250ZXh0IH0gZnJvbSAnLi93ZWJnbC93ZWJnbC1jb250ZXh0LWZhY3RvcnknO1xuXG4vKipcbiAqIFdlYkdMQmFja2VuZCBpcyB0aGUgZW50cnkgcG9pbnQgZm9yIGFsbCBXZWJHTCBvcGVhcnRpb25zXG4gKiBXaGVuIGl0IHN0YXJ0cyBpdCBjcmVhdGVkIHRoZSBXZWJHTFJlbmRlcmluZ0NvbnRleHRcbiAqIGFuZCBvdGhlciBtYWluIGZyYW1ld29yayBjb21wb25lbnRzIHN1Y2ggYXMgUHJvZ3JhbSBhbmQgVGV4dHVyZSBNYW5hZ2Vyc1xuICovXG5leHBvcnQgY2xhc3MgV2ViR0xCYWNrZW5kIGltcGxlbWVudHMgQmFja2VuZCB7XG4gIGdsQ29udGV4dDogV2ViR0xDb250ZXh0O1xuXG4gIGdldCBjb250ZXh0SWQoKTogJ3dlYmdsJyB8ICd3ZWJnbDInIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLmNvbnRleHRJZDtcbiAgfVxuICBzZXQgY29udGV4dElkKHZhbHVlOiAnd2ViZ2wnIHwgJ3dlYmdsMicgfCB1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wuY29udGV4dElkID0gdmFsdWU7XG4gIH1cblxuICBnZXQgbWF0bXVsTWF4QmF0Y2hTaXplKCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGVudi53ZWJnbC5tYXRtdWxNYXhCYXRjaFNpemU7XG4gIH1cbiAgc2V0IG1hdG11bE1heEJhdGNoU2l6ZSh2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgZW52LndlYmdsLm1hdG11bE1heEJhdGNoU2l6ZSA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IHRleHR1cmVDYWNoZU1vZGUoKTogJ2luaXRpYWxpemVyT25seScgfCAnZnVsbCcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBlbnYud2ViZ2wudGV4dHVyZUNhY2hlTW9kZTtcbiAgfVxuICBzZXQgdGV4dHVyZUNhY2hlTW9kZSh2YWx1ZTogJ2luaXRpYWxpemVyT25seScgfCAnZnVsbCcgfCB1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wudGV4dHVyZUNhY2hlTW9kZSA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IHBhY2soKTogYm9vbGVhbiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGVudi53ZWJnbC5wYWNrO1xuICB9XG4gIHNldCBwYWNrKHZhbHVlOiBib29sZWFuIHwgdW5kZWZpbmVkKSB7XG4gICAgZW52LndlYmdsLnBhY2sgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBhc3luYygpOiBib29sZWFuIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLmFzeW5jO1xuICB9XG4gIHNldCBhc3luYyh2YWx1ZTogYm9vbGVhbiB8IHVuZGVmaW5lZCkge1xuICAgIGVudi53ZWJnbC5hc3luYyA9IHZhbHVlO1xuICB9XG5cbiAgaW5pdGlhbGl6ZSgpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5nbENvbnRleHQgPSBjcmVhdGVXZWJHTENvbnRleHQodGhpcy5jb250ZXh0SWQpO1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLm1hdG11bE1heEJhdGNoU2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgdGhpcy5tYXRtdWxNYXhCYXRjaFNpemUgPSAxNjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdGhpcy50ZXh0dXJlQ2FjaGVNb2RlICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLnRleHR1cmVDYWNoZU1vZGUgPSAnZnVsbCc7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHRoaXMucGFjayAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRoaXMucGFjayA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB0aGlzLmFzeW5jICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdGhpcy5hc3luYyA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBMb2dnZXIuc2V0V2l0aEVudihlbnYpO1xuXG4gICAgICBpZiAoIWVudi53ZWJnbC5jb250ZXh0KSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbnYud2ViZ2wsICdjb250ZXh0JywgeyB2YWx1ZTogdGhpcy5nbENvbnRleHQuZ2wgfSk7XG4gICAgICB9XG5cbiAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAnV2ViR0xCYWNrZW5kJyxcbiAgICAgICAgYENyZWF0ZWQgV2ViR0xDb250ZXh0OiAke3R5cGVvZiB0aGlzLmdsQ29udGV4dH0gd2l0aCBtYXRtdWxNYXhCYXRjaFNpemU6ICR7XG4gICAgICAgICAgdGhpcy5tYXRtdWxNYXhCYXRjaFNpemVcbiAgICAgICAgfTsgdGV4dHVyZUNhY2hlTW9kZTogJHt0aGlzLnRleHR1cmVDYWNoZU1vZGV9OyBwYWNrOiAke3RoaXMucGFja307IGFzeW5jOiAke3RoaXMuYXN5bmN9LmAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgTG9nZ2VyLndhcm5pbmcoJ1dlYkdMQmFja2VuZCcsIGBVbmFibGUgdG8gaW5pdGlhbGl6ZSBXZWJHTEJhY2tlbmQuICR7ZX1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgY3JlYXRlU2Vzc2lvbkhhbmRsZXIoY29udGV4dDogU2Vzc2lvbi5Db250ZXh0KTogU2Vzc2lvbkhhbmRsZXIge1xuICAgIHJldHVybiBuZXcgV2ViR0xTZXNzaW9uSGFuZGxlcih0aGlzLCBjb250ZXh0KTtcbiAgfVxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuZ2xDb250ZXh0LmRpc3Bvc2UoKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBXZWJHTEJhY2tlbmQgfSBmcm9tICcuL2JhY2tlbmRzL2JhY2tlbmQtd2ViZ2wnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9yIH0gZnJvbSAnLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgT3BTZXQgfSBmcm9tICcuL29wc2V0JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL3Nlc3Npb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEluZmVyZW5jZUhhbmRsZXIge1xuICAvKipcbiAgICogZGlzcG9zZSB0aGUgaW5mZXJlbmNlIGhhbmRsZXIuIGl0IHdpbGwgYmUgY2FsbGVkIGFzIHRoZSBsYXN0IHN0ZXAgaW4gU2Vzc2lvbi5ydW4oKVxuICAgKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNlc3Npb25IYW5kbGVyIHtcbiAgLyoqXG4gICAqIHRyYW5zZm9ybSB0aGUgZ3JhcGggYXQgaW5pdGlhbGl6YXRpb24gdGltZVxuICAgKiBAcGFyYW0gZ3JhcGhUcmFuc2Zvcm1lciB0aGUgZ3JhcGggdHJhbnNmb3JtZXIgdG8gbWFuaXB1bGF0ZSB0aGUgbW9kZWwgZ3JhcGhcbiAgICovXG4gIHRyYW5zZm9ybUdyYXBoPyhncmFwaFRyYW5zZm9ybWVyOiBHcmFwaC5UcmFuc2Zvcm1lcik6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiBJbmZlcmVuY2VIYW5kbGVyIHRvIHVzZSBpbiBhIFNlc3Npb24ucnVuKCkgY2FsbFxuICAgKi9cbiAgY3JlYXRlSW5mZXJlbmNlSGFuZGxlcigpOiBJbmZlcmVuY2VIYW5kbGVyO1xuXG4gIC8qKlxuICAgKiBkaXNwb3NlIHRoZSBzZXNzaW9uIGhhbmRsZXIuIGl0IHdpbGwgYmUgY2FsbGVkIHdoZW4gYSBzZXNzaW9uIGlzIGJlaW5nIGRpc3Bvc2VkIGV4cGxpY2l0bHlcbiAgICovXG4gIGRpc3Bvc2UoKTogdm9pZDtcblxuICAvKipcbiAgICogUmVzb2x2ZXMgdGhlIG9wZXJhdG9yIGZyb20gdGhlIG5hbWUgYW5kIG9wc2V0IHZlcnNpb247IGJhY2tlbmQgc3BlY2lmaWNcbiAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgdG8gcmVzb2x2ZVxuICAgKiBAcGFyYW0gb3BzZXRzIGEgbGlzdCBvZiBvcHNldHMgdGhhdCBleHBvcnRlZCBmcm9tIHRoZSBtb2RlbFxuICAgKiBAcGFyYW0gZ3JhcGggdGhlIGNvbXBsZXRlbHkgaW5pdGlhbGl6ZWQgZ3JhcGhcbiAgICovXG4gIHJlc29sdmUobm9kZTogR3JhcGguTm9kZSwgb3BzZXRzOiByZWFkb25seSBPcFNldFtdLCBncmFwaDogR3JhcGgpOiBPcGVyYXRvcjtcblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgbGV0J3MgdGhlIHNlc3Npb25IYW5kbGVyIGtub3cgdGhhdCB0aGUgZ3JhcGggaW5pdGlhbGl6YXRpb24gaXMgY29tcGxldGVcbiAgICogQHBhcmFtIGdyYXBoIHRoZSBjb21wbGV0ZWx5IGluaXRpYWxpemVkIGdyYXBoXG4gICAqL1xuICBvbkdyYXBoSW5pdGlhbGl6ZWQ/KGdyYXBoOiBHcmFwaCk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIGEgcmVmZXJlbmNlIHRvIHRoZSBjb3JyZXNwb25kaW5nIGJhY2tlbmRcbiAgICovXG4gIHJlYWRvbmx5IGJhY2tlbmQ6IEJhY2tlbmQ7XG5cbiAgLyoqXG4gICAqIGEgcmVmZXJlbmNlIHRvIHRoZSBzZXNzaW9uIGNvbnRleHRcbiAgICovXG4gIHJlYWRvbmx5IGNvbnRleHQ6IFNlc3Npb24uQ29udGV4dDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCYWNrZW5kIHtcbiAgLyoqXG4gICAqIGluaXRpYWxpemUgdGhlIGJhY2tlbmQuIHdpbGwgYmUgY2FsbGVkIG9ubHkgb25jZSwgd2hlbiB0aGUgZmlyc3QgdGltZSB0aGVcbiAgICogYmFja2VuZCBpdCB0byBiZSB1c2VkXG4gICAqL1xuICBpbml0aWFsaXplKCk6IGJvb2xlYW4gfCBQcm9taXNlPGJvb2xlYW4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgU2Vzc2lvbkhhbmRsZXIgdG8gdXNlIGluIGEgU2Vzc2lvbiBvYmplY3QncyBsaWZlY3ljbGVcbiAgICovXG4gIGNyZWF0ZVNlc3Npb25IYW5kbGVyKGNvbnRleHQ6IFNlc3Npb24uQ29udGV4dCk6IFNlc3Npb25IYW5kbGVyO1xuXG4gIC8qKlxuICAgKiBkaXNwb3NlIHRoZSBiYWNrZW5kLiBjdXJyZW50bHkgdGhpcyB3aWxsIG5vdCBiZSBjYWxsZWRcbiAgICovXG4gIGRpc3Bvc2UoKTogdm9pZDtcbn1cblxuLy8gY2FjaGVzIGFsbCBpbml0aWFsaXplZCBiYWNrZW5kIGluc3RhbmNlc1xuY29uc3QgYmFja2VuZHNDYWNoZTogTWFwPHN0cmluZywgQmFja2VuZD4gPSBuZXcgTWFwKCk7XG5cbmV4cG9ydCBjb25zdCBiYWNrZW5kOiB7IFtuYW1lOiBzdHJpbmddOiBCYWNrZW5kIH0gPSB7XG4gIHdlYmdsOiBuZXcgV2ViR0xCYWNrZW5kKCksXG59O1xuXG4vKipcbiAqIFJlc29sdmUgYSByZWZlcmVuY2UgdG8gdGhlIGJhY2tlbmQuIElmIGEgaGludCBpcyBzcGVjaWZpZWQsIHRoZSBjb3JyZXNwb25kaW5nXG4gKiBiYWNrZW5kIHdpbGwgYmUgdXNlZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlc29sdmVCYWNrZW5kKGhpbnQ/OiBzdHJpbmcgfCByZWFkb25seSBzdHJpbmdbXSk6IFByb21pc2U8QmFja2VuZD4ge1xuICBpZiAoIWhpbnQpIHtcbiAgICByZXR1cm4gcmVzb2x2ZUJhY2tlbmQoWyd3ZWJnbCddKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBoaW50cyA9IHR5cGVvZiBoaW50ID09PSAnc3RyaW5nJyA/IFtoaW50XSA6IGhpbnQ7XG5cbiAgICBmb3IgKGNvbnN0IGJhY2tlbmRIaW50IG9mIGhpbnRzKSB7XG4gICAgICBjb25zdCBjYWNoZSA9IGJhY2tlbmRzQ2FjaGUuZ2V0KGJhY2tlbmRIaW50KTtcbiAgICAgIGlmIChjYWNoZSkge1xuICAgICAgICByZXR1cm4gY2FjaGU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGJhY2tlbmQgPSBhd2FpdCB0cnlMb2FkQmFja2VuZChiYWNrZW5kSGludCk7XG4gICAgICBpZiAoYmFja2VuZCkge1xuICAgICAgICByZXR1cm4gYmFja2VuZDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ25vIGF2YWlsYWJsZSBiYWNrZW5kIHRvIHVzZScpO1xufVxuXG5hc3luYyBmdW5jdGlvbiB0cnlMb2FkQmFja2VuZChiYWNrZW5kSGludDogc3RyaW5nKTogUHJvbWlzZTxCYWNrZW5kIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IGJhY2tlbmRPYmogPSBiYWNrZW5kO1xuXG4gIGlmICh0eXBlb2YgYmFja2VuZE9ialtiYWNrZW5kSGludF0gIT09ICd1bmRlZmluZWQnICYmIGlzQmFja2VuZChiYWNrZW5kT2JqW2JhY2tlbmRIaW50XSkpIHtcbiAgICBjb25zdCBiYWNrZW5kID0gYmFja2VuZE9ialtiYWNrZW5kSGludF07XG4gICAgbGV0IGluaXQgPSBiYWNrZW5kLmluaXRpYWxpemUoKTtcbiAgICBpZiAodHlwZW9mIGluaXQgPT09ICdvYmplY3QnICYmICd0aGVuJyBpbiBpbml0KSB7XG4gICAgICBpbml0ID0gYXdhaXQgaW5pdDtcbiAgICB9XG4gICAgaWYgKGluaXQpIHtcbiAgICAgIGJhY2tlbmRzQ2FjaGUuc2V0KGJhY2tlbmRIaW50LCBiYWNrZW5kKTtcbiAgICAgIHJldHVybiBiYWNrZW5kO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGlzQmFja2VuZChvYmo6IHVua25vd24pIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgY29uc3QgbyA9IG9iaiBhcyBhbnk7XG5cbiAgLy8gY2hlY2sgaWYgYW4gb2JqZWN0IGlzIGEgQmFja2VuZCBpbnN0YW5jZVxuICBpZiAoXG4gICAgJ2luaXRpYWxpemUnIGluIG8gJiZcbiAgICB0eXBlb2Ygby5pbml0aWFsaXplID09PSAnZnVuY3Rpb24nICYmIC8vIGluaXRpYWxpemUoKVxuICAgICdjcmVhdGVTZXNzaW9uSGFuZGxlcicgaW4gbyAmJlxuICAgIHR5cGVvZiBvLmNyZWF0ZVNlc3Npb25IYW5kbGVyID09PSAnZnVuY3Rpb24nICYmIC8vIGNyZWF0ZVNlc3Npb25IYW5kbGVyKClcbiAgICAnZGlzcG9zZScgaW4gbyAmJlxuICAgIHR5cGVvZiBvLmRpc3Bvc2UgPT09ICdmdW5jdGlvbicgLy8gZGlzcG9zZSgpXG4gICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgdHlwZSBCYWNrZW5kVHlwZSA9IEJhY2tlbmQ7XG5leHBvcnQgdHlwZSBTZXNzaW9uSGFuZGxlclR5cGUgPSBSZXR1cm5UeXBlPEJhY2tlbmRUeXBlWydjcmVhdGVTZXNzaW9uSGFuZGxlciddPjtcbmV4cG9ydCB0eXBlIEluZmVyZW5jZUhhbmRsZXJUeXBlID0gUmV0dXJuVHlwZTxTZXNzaW9uSGFuZGxlclR5cGVbJ2NyZWF0ZUluZmVyZW5jZUhhbmRsZXInXT47XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFNlc3Npb25IYW5kbGVyIH0gZnJvbSAnLi9iYWNrZW5kJztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi9ncmFwaCc7XG5pbXBvcnQgeyBMb2dnZXIsIFByb2ZpbGVyIH0gZnJvbSAnLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IE9wZXJhdG9yIH0gZnJvbSAnLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuXG5jbGFzcyBLZXJuZWxPcCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBvcDogT3BlcmF0b3IsXG4gICAgcHVibGljIG5vZGU6IEdyYXBoLk5vZGUsXG4gICkge31cbn1cblxuZXhwb3J0IGNsYXNzIEV4ZWN1dGlvblBsYW4ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGdyYXBoOiBHcmFwaCxcbiAgICBvcHM6IE9wZXJhdG9yW10sXG4gICAgcHJpdmF0ZSBwcm9maWxlcjogUmVhZG9ubHk8UHJvZmlsZXI+LFxuICApIHtcbiAgICB0aGlzLmluaXRpYWxpemUob3BzKTtcbiAgfVxuXG4gIGluaXRpYWxpemUob3BzOiBPcGVyYXRvcltdKSB7XG4gICAgdGhpcy5wcm9maWxlci5ldmVudCgnc2Vzc2lvbicsICdFeGVjdXRpb25QbGFuLmluaXRpYWxpemUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBncmFwaE5vZGVzID0gdGhpcy5ncmFwaC5nZXROb2RlcygpO1xuICAgICAgaWYgKGdyYXBoTm9kZXMubGVuZ3RoICE9PSBvcHMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIHNpemUgb2Ygbm9kZXMgYW5kIE9QcyBkbyBub3QgbWF0Y2guJyk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX29wcyA9IG9wcy5tYXAoKG9wLCBpKSA9PiBuZXcgS2VybmVsT3Aob3AsIGdyYXBoTm9kZXNbaV0pKTtcbiAgICAgIHRoaXMucmVzZXQoKTtcblxuICAgICAgLy8gbG9vayBmb3Igc3RhcnRlciBub2RlKHMpXG4gICAgICB0aGlzLl9zdGFydGVyID0gW107XG4gICAgICB0aGlzLl9vcHMuZm9yRWFjaCgob3AsIGkpID0+IHtcbiAgICAgICAgbGV0IHJlc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgZm9yIChjb25zdCBpbnB1dCBvZiBvcC5ub2RlLmlucHV0cykge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICF0aGlzLl92YWx1ZXNbaW5wdXRdICYmIC8vIG5vdCBhbiBpbml0aWFsaXplZCBpbnB1dFxuICAgICAgICAgICAgdGhpcy5ncmFwaC5nZXRJbnB1dEluZGljZXMoKS5pbmRleE9mKGlucHV0KSA9PT0gLTEgLy8gbm90IG1vZGVsIGlucHV0XG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXNvbHZlZCA9IGZhbHNlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChyZXNvbHZlZCkge1xuICAgICAgICAgIHRoaXMuX3N0YXJ0ZXIucHVzaChpKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICByZXNldCgpIHtcbiAgICB0aGlzLl92YWx1ZXMgPSB0aGlzLmdyYXBoLmdldFZhbHVlcygpLm1hcCgoaSkgPT4gaS50ZW5zb3IpO1xuICB9XG5cbiAgYXN5bmMgZXhlY3V0ZShzZXNzaW9uSGFuZGxlcjogU2Vzc2lvbkhhbmRsZXIsIG1vZGVsSW5wdXRzOiBUZW5zb3JbXSk6IFByb21pc2U8VGVuc29yW10+IHtcbiAgICByZXR1cm4gdGhpcy5wcm9maWxlci5ldmVudCgnc2Vzc2lvbicsICdFeGVjdXRpb25QbGFuLmV4ZWN1dGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyByZXNldCBtZWRpZW0gcmVzdWx0XG4gICAgICB0aGlzLnJlc2V0KCk7XG5cbiAgICAgIC8vIGNyZWF0ZSBpbmZlcmVuY2UgaGFuZGxlclxuICAgICAgY29uc3QgaW5mZXJlbmNlSGFuZGxlciA9IHNlc3Npb25IYW5kbGVyLmNyZWF0ZUluZmVyZW5jZUhhbmRsZXIoKTtcblxuICAgICAgLy8gcG9wdWxhdGUgaW5wdXRzIHZhbHVlXG4gICAgICBjb25zdCBncmFwaElucHV0cyA9IHRoaXMuZ3JhcGguZ2V0SW5wdXRJbmRpY2VzKCk7XG4gICAgICBpZiAobW9kZWxJbnB1dHMubGVuZ3RoICE9PSBncmFwaElucHV0cy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBudW1iZXIgb2YgaW5wdXQgdGVuc29ycyBkb24ndCBtYXRjaCB0aGUgbnVtYmVyIG9mIGlucHV0cyB0byB0aGUgbW9kZWw6IGFjdHVhbDogJHtcbiAgICAgICAgICAgIG1vZGVsSW5wdXRzLmxlbmd0aFxuICAgICAgICAgIH0gZXhwZWN0ZWQ6ICR7Z3JhcGhJbnB1dHMubGVuZ3RofWAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIG1vZGVsSW5wdXRzLmZvckVhY2goKGlucHV0LCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gZ3JhcGhJbnB1dHNbaV07XG4gICAgICAgIHRoaXMuX3ZhbHVlc1tpbmRleF0gPSBpbnB1dDtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBwcmVwYXJlIHJ1bm5pbmcgc2VxdWVuY2VcbiAgICAgIGNvbnN0IHNlcXVlbmNlOiBudW1iZXJbXSA9IHRoaXMuX3N0YXJ0ZXIuc2xpY2UoMCk7XG5cbiAgICAgIC8vIGV4ZWN1dGlvbiBpdGVyYXRpb25zXG4gICAgICBjb25zdCBncmFwaFZhbHVlcyA9IHRoaXMuZ3JhcGguZ2V0VmFsdWVzKCk7XG4gICAgICBjb25zdCBncmFwaE5vZGVzID0gdGhpcy5ncmFwaC5nZXROb2RlcygpO1xuXG4gICAgICBsZXQgcmVhciA9IDA7XG4gICAgICB3aGlsZSAocmVhciA8IHNlcXVlbmNlLmxlbmd0aCkge1xuICAgICAgICBjb25zdCB0aGlzT3BJbmRleCA9IHNlcXVlbmNlW3JlYXIrK107XG4gICAgICAgIGNvbnN0IHRoaXNPcCA9IHRoaXMuX29wc1t0aGlzT3BJbmRleF07XG5cbiAgICAgICAgLy8gY2hlY2sgaW5wdXRcbiAgICAgICAgY29uc3QgaW5wdXRMaXN0ID0gdGhpc09wLm5vZGUuaW5wdXRzLm1hcCgoaSkgPT4gdGhpcy5fdmFsdWVzW2ldKTtcbiAgICAgICAgaWYgKGlucHV0TGlzdC5pbmRleE9mKHVuZGVmaW5lZCkgIT09IC0xKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnJlc29sdmVkIGlucHV0IGRldGVjdGVkOiBvcDogJHt0aGlzT3Aubm9kZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJ1blxuICAgICAgICBjb25zdCBpbnB1dFRlbnNvcnMgPSBpbnB1dExpc3QgYXMgVGVuc29yW107XG4gICAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICdFeGVjUGxhbicsXG4gICAgICAgICAgYFJ1bm5pbmcgb3A6JHt0aGlzT3Aubm9kZS5uYW1lfSAoJHtpbnB1dFRlbnNvcnNcbiAgICAgICAgICAgIC5tYXAoKHQsIGkpID0+IGAnJHt0aGlzT3Aubm9kZS5pbnB1dHNbaV19JzogJHt0LnR5cGV9WyR7dC5kaW1zLmpvaW4oJywnKX1dYClcbiAgICAgICAgICAgIC5qb2luKCcsICcpfSlgLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IG91dHB1dExpc3QgPSBhd2FpdCB0aGlzLnByb2ZpbGVyLmV2ZW50KCdub2RlJywgdGhpc09wLm5vZGUubmFtZSwgYXN5bmMgKCkgPT5cbiAgICAgICAgICB0aGlzT3Aub3AuaW1wbChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dFRlbnNvcnMsIHRoaXNPcC5vcC5jb250ZXh0KSxcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBjaGVjayBvdXRwdXRcbiAgICAgICAgaWYgKG91dHB1dExpc3QubGVuZ3RoICE9PSB0aGlzT3Aubm9kZS5vdXRwdXRzLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndGhlIHNpemUgb2Ygb3V0cHV0IGRvZXMgbm90IG1hdGNoIG1vZGVsIGRlZmluaXRpb24uJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaWxsIHZhbHVlXG4gICAgICAgIG91dHB1dExpc3QuZm9yRWFjaCgob3V0cHV0LCBpKSA9PiB7XG4gICAgICAgICAgY29uc3QgaiA9IHRoaXNPcC5ub2RlLm91dHB1dHNbaV07XG4gICAgICAgICAgaWYgKHRoaXMuX3ZhbHVlc1tqXSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBvdXRwdXQgWyR7an1dIGFscmVhZHkgaGFzIHZhbHVlOiBvcDoke3RoaXNPcC5ub2RlLm5hbWV9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuX3ZhbHVlc1tqXSA9IG91dHB1dDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gcmVzb2x2ZSBkb3duc3RyZWFtIG5vZGVzXG4gICAgICAgIGNvbnN0IGRvd25zdHJlYW1Ob2RlcyA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICAgICAgICBvdXRwdXRMaXN0LmZvckVhY2goKF9vdXRwdXQsIGkpID0+IHtcbiAgICAgICAgICBjb25zdCBqID0gdGhpc09wLm5vZGUub3V0cHV0c1tpXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGN1cnJlbnREb3duc3RyZWFtTm9kZUluZGV4IG9mIGdyYXBoVmFsdWVzW2pdLnRvKSB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RG93bnN0cmVhbU5vZGUgPSBncmFwaE5vZGVzW2N1cnJlbnREb3duc3RyZWFtTm9kZUluZGV4XTtcbiAgICAgICAgICAgIGxldCByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGsgb2YgY3VycmVudERvd25zdHJlYW1Ob2RlLmlucHV0cykge1xuICAgICAgICAgICAgICBpZiAoIXRoaXMuX3ZhbHVlc1trXSkge1xuICAgICAgICAgICAgICAgIHJlc29sdmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXNvbHZlZCkge1xuICAgICAgICAgICAgICBkb3duc3RyZWFtTm9kZXMuYWRkKGN1cnJlbnREb3duc3RyZWFtTm9kZUluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBzZXF1ZW5jZS5wdXNoKC4uLmRvd25zdHJlYW1Ob2Rlcyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG91dHB1dDogVGVuc29yW10gPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ncmFwaC5nZXRPdXRwdXRJbmRpY2VzKCkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0SW5kZXggPSB0aGlzLmdyYXBoLmdldE91dHB1dEluZGljZXMoKVtpXTtcbiAgICAgICAgY29uc3Qgb3V0cHV0VGVuc29yID0gdGhpcy5fdmFsdWVzW291dHB1dEluZGV4XTtcbiAgICAgICAgaWYgKG91dHB1dFRlbnNvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGByZXF1aXJlZCBvdXRwdXQgWyR7b3V0cHV0SW5kZXh9XSBkb2VzIG5vdCBoYXZlIHZhbHVlYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG91dHB1dEluZGV4ID09PSAwKSB7XG4gICAgICAgICAgYXdhaXQgb3V0cHV0VGVuc29yLmdldERhdGEoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG4gICAgICAgICAgb3V0cHV0VGVuc29yLmRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgb3V0cHV0LnB1c2gob3V0cHV0VGVuc29yKTtcbiAgICAgIH1cbiAgICAgIExvZ2dlci52ZXJib3NlKCdFeGVjUGxhbicsICdkaXNwb3Npbmcgb2YgaW5mZXJlbmNlSGFuZGxlcicpO1xuICAgICAgaW5mZXJlbmNlSGFuZGxlci5kaXNwb3NlKCk7XG4gICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH0pO1xuICB9XG5cbiAgX3ZhbHVlczogQXJyYXk8VGVuc29yIHwgdW5kZWZpbmVkPjtcbiAgX29wczogS2VybmVsT3BbXTtcbiAgX3N0YXJ0ZXI6IG51bWJlcltdO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgTG9uZyBmcm9tICdsb25nJztcblxuaW1wb3J0ICogYXMgb3J0RmJzIGZyb20gJy4vb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkJztcbmltcG9ydCB7IG9ubnggfSBmcm9tICcuL29ydC1zY2hlbWEvcHJvdG9idWYvb25ueCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvcic7XG5pbXBvcnQgeyBkZWNvZGVVdGY4U3RyaW5nLCBMb25nVXRpbCB9IGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBBdHRyaWJ1dGUge1xuICBleHBvcnQgaW50ZXJmYWNlIERhdGFUeXBlTWFwIHtcbiAgICBmbG9hdDogbnVtYmVyO1xuICAgIGludDogbnVtYmVyO1xuICAgIHN0cmluZzogc3RyaW5nO1xuICAgIHRlbnNvcjogVGVuc29yO1xuICAgIGZsb2F0czogbnVtYmVyW107XG4gICAgaW50czogbnVtYmVyW107XG4gICAgc3RyaW5nczogc3RyaW5nW107XG4gICAgdGVuc29yczogVGVuc29yW107XG4gIH1cblxuICBleHBvcnQgdHlwZSBEYXRhVHlwZSA9IGtleW9mIERhdGFUeXBlTWFwO1xufVxuXG50eXBlIFZhbHVlVHlwZXMgPSBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbQXR0cmlidXRlLkRhdGFUeXBlXTtcblxudHlwZSBWYWx1ZSA9IFtWYWx1ZVR5cGVzLCBBdHRyaWJ1dGUuRGF0YVR5cGVdO1xuXG5leHBvcnQgY2xhc3MgQXR0cmlidXRlIHtcbiAgY29uc3RydWN0b3IoYXR0cmlidXRlczogb25ueC5JQXR0cmlidXRlUHJvdG9bXSB8IG9ydEZicy5BdHRyaWJ1dGVbXSB8IG51bGwgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLl9hdHRyaWJ1dGVzID0gbmV3IE1hcCgpO1xuICAgIGlmIChhdHRyaWJ1dGVzICE9PSBudWxsICYmIGF0dHJpYnV0ZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZm9yIChjb25zdCBhdHRyIG9mIGF0dHJpYnV0ZXMpIHtcbiAgICAgICAgaWYgKGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvKSB7XG4gICAgICAgICAgdGhpcy5fYXR0cmlidXRlcy5zZXQoYXR0ci5uYW1lLCBbQXR0cmlidXRlLmdldFZhbHVlKGF0dHIpLCBBdHRyaWJ1dGUuZ2V0VHlwZShhdHRyKV0pO1xuICAgICAgICB9IGVsc2UgaWYgKGF0dHIgaW5zdGFuY2VvZiBvcnRGYnMuQXR0cmlidXRlKSB7XG4gICAgICAgICAgdGhpcy5fYXR0cmlidXRlcy5zZXQoYXR0ci5uYW1lKCkhLCBbQXR0cmlidXRlLmdldFZhbHVlKGF0dHIpLCBBdHRyaWJ1dGUuZ2V0VHlwZShhdHRyKV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5fYXR0cmlidXRlcy5zaXplIDwgYXR0cmlidXRlcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkdXBsaWNhdGVkIGF0dHJpYnV0ZSBuYW1lcycpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNldChrZXk6IHN0cmluZywgdHlwZTogQXR0cmlidXRlLkRhdGFUeXBlLCB2YWx1ZTogVmFsdWVUeXBlcyk6IHZvaWQge1xuICAgIHRoaXMuX2F0dHJpYnV0ZXMuc2V0KGtleSwgW3ZhbHVlLCB0eXBlXSk7XG4gIH1cbiAgZGVsZXRlKGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5fYXR0cmlidXRlcy5kZWxldGUoa2V5KTtcbiAgfVxuICBnZXRGbG9hdChrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydmbG9hdCddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ2Zsb2F0JywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldEludChrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydpbnQnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdpbnQnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0U3RyaW5nKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ3N0cmluZyddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ3N0cmluZycsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRUZW5zb3Ioa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsndGVuc29yJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAndGVuc29yJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldEZsb2F0cyhrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydmbG9hdHMnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdmbG9hdHMnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0SW50cyhrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydpbnRzJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnaW50cycsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRTdHJpbmdzKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ3N0cmluZ3MnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdzdHJpbmdzJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldFRlbnNvcnMoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsndGVuc29ycyddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ3RlbnNvcnMnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQ8ViBleHRlbmRzIEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFtBdHRyaWJ1dGUuRGF0YVR5cGVdPihcbiAgICBrZXk6IHN0cmluZyxcbiAgICB0eXBlOiBBdHRyaWJ1dGUuRGF0YVR5cGUsXG4gICAgZGVmYXVsdFZhbHVlPzogVixcbiAgKTogViB7XG4gICAgY29uc3QgdmFsdWVBbmRUeXBlID0gdGhpcy5fYXR0cmlidXRlcy5nZXQoa2V5KTtcbiAgICBpZiAodmFsdWVBbmRUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChkZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGByZXF1aXJlZCBhdHRyaWJ1dGUgbm90IGZvdW5kOiAke2tleX1gKTtcbiAgICB9XG4gICAgaWYgKHZhbHVlQW5kVHlwZVsxXSAhPT0gdHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGB0eXBlIG1pc21hdGNoOiBleHBlY3RlZCAke3R5cGV9IGJ1dCBnb3QgJHt2YWx1ZUFuZFR5cGVbMV19YCk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZUFuZFR5cGVbMF0gYXMgVjtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFR5cGUoYXR0cjogb25ueC5JQXR0cmlidXRlUHJvdG8gfCBvcnRGYnMuQXR0cmlidXRlKTogQXR0cmlidXRlLkRhdGFUeXBlIHtcbiAgICBjb25zdCB0eXBlID0gYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG8gPyBhdHRyLnR5cGUgOiAoYXR0ciBhcyBvcnRGYnMuQXR0cmlidXRlKS50eXBlKCk7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5GTE9BVDpcbiAgICAgICAgcmV0dXJuICdmbG9hdCc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlQ6XG4gICAgICAgIHJldHVybiAnaW50JztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklORzpcbiAgICAgICAgcmV0dXJuICdzdHJpbmcnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SOlxuICAgICAgICByZXR1cm4gJ3RlbnNvcic7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5GTE9BVFM6XG4gICAgICAgIHJldHVybiAnZmxvYXRzJztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLklOVFM6XG4gICAgICAgIHJldHVybiAnaW50cyc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkdTOlxuICAgICAgICByZXR1cm4gJ3N0cmluZ3MnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SUzpcbiAgICAgICAgcmV0dXJuICd0ZW5zb3JzJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgYXR0cmlidXRlIHR5cGUgaXMgbm90IHN1cHBvcnRlZCB5ZXQ6ICR7b25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlW3R5cGVdfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFZhbHVlKGF0dHI6IG9ubnguSUF0dHJpYnV0ZVByb3RvIHwgb3J0RmJzLkF0dHJpYnV0ZSkge1xuICAgIGNvbnN0IGF0dHJUeXBlID0gYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG8gPyBhdHRyLnR5cGUgOiAoYXR0ciBhcyBvcnRGYnMuQXR0cmlidXRlKS50eXBlKCk7XG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuR1JBUEggfHwgYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5HUkFQSFMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ3JhcGggYXR0cmlidXRlIGlzIG5vdCBzdXBwb3J0ZWQgeWV0Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldFZhbHVlTm9DaGVjayhhdHRyKTtcblxuICAgIC8vIGNhc3QgTE9ORyB0byBudW1iZXJcbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlQgJiYgTG9uZ1V0aWwuaXNMb25nKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIExvbmdVdGlsLmxvbmdUb051bWJlcih2YWx1ZSBhcyBiaWdpbnQgfCBMb25nKTtcbiAgICB9XG5cbiAgICAvLyBjYXN0IExPTkdbXSB0byBudW1iZXJbXVxuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLklOVFMpIHtcbiAgICAgIGNvbnN0IGFyciA9IHZhbHVlIGFzIEFycmF5PG51bWJlciB8IExvbmcgfCBiaWdpbnQ+O1xuICAgICAgY29uc3QgbnVtYmVyVmFsdWU6IG51bWJlcltdID0gbmV3IEFycmF5PG51bWJlcj4oYXJyLmxlbmd0aCk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG1heWJlTG9uZyA9IGFycltpXTtcbiAgICAgICAgbnVtYmVyVmFsdWVbaV0gPSBMb25nVXRpbC5sb25nVG9OdW1iZXIobWF5YmVMb25nKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bWJlclZhbHVlO1xuICAgIH1cblxuICAgIC8vIGNhc3Qgb25ueC5UZW5zb3JQcm90byB0byBvbm54anMuVGVuc29yXG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SKSB7XG4gICAgICByZXR1cm4gYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgPyBUZW5zb3IuZnJvbVByb3RvKHZhbHVlIGFzIG9ubnguSVRlbnNvclByb3RvKVxuICAgICAgICA6IFRlbnNvci5mcm9tT3J0VGVuc29yKHZhbHVlIGFzIG9ydEZicy5UZW5zb3IpO1xuICAgIH1cblxuICAgIC8vIGNhc3Qgb25ueC5UZW5zb3JQcm90b1tdIHRvIG9ubnhqcy5UZW5zb3JbXVxuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlRFTlNPUlMpIHtcbiAgICAgIGlmIChhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90bykge1xuICAgICAgICBjb25zdCB0ZW5zb3JQcm90b3MgPSB2YWx1ZSBhcyBvbm54LklUZW5zb3JQcm90b1tdO1xuICAgICAgICByZXR1cm4gdGVuc29yUHJvdG9zLm1hcCgodmFsdWUpID0+IFRlbnNvci5mcm9tUHJvdG8odmFsdWUpKTtcbiAgICAgIH0gZWxzZSBpZiAoYXR0ciBpbnN0YW5jZW9mIG9ydEZicy5BdHRyaWJ1dGUpIHtcbiAgICAgICAgY29uc3QgdGVuc29yUHJvdG9zID0gdmFsdWUgYXMgb3J0RmJzLlRlbnNvcltdO1xuICAgICAgICByZXR1cm4gdGVuc29yUHJvdG9zLm1hcCgodmFsdWUpID0+IFRlbnNvci5mcm9tT3J0VGVuc29yKHZhbHVlKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gY2FzdCBVaW50OEFycmF5IHRvIHN0cmluZ1xuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklORykge1xuICAgICAgLy8gc3RyaW5nIGluIG9ubnggYXR0cmlidXRlIGlzIG9mIHVpbnQ4YXJyYXkgdHlwZSwgc28gd2UgbmVlZCB0byBjb252ZXJ0IGl0IHRvIHN0cmluZyBiZWxvdy4gV2hpbGUgaW4gb3J0IGZvcm1hdCxcbiAgICAgIC8vIHN0cmluZyBhdHRyaWJ1dGVzIGFyZSByZXR1cm5lZCBhcyBzdHJpbmcsIHNvIG5vIGNvbnZlcnNpb24gaXMgbmVlZGVkLlxuICAgICAgaWYgKGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvKSB7XG4gICAgICAgIGNvbnN0IHV0ZjhTdHJpbmcgPSB2YWx1ZSBhcyBVaW50OEFycmF5O1xuICAgICAgICByZXR1cm4gZGVjb2RlVXRmOFN0cmluZyh1dGY4U3RyaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjYXN0IFVpbnQ4QXJyYXlbXSB0byBzdHJpbmdbXVxuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklOR1MpIHtcbiAgICAgIC8vIHN0cmluZ3MgaW4gb25ueCBhdHRyaWJ1dGUgaXMgcmV0dXJuZWQgYXMgdWludDhhcnJheVtdLCBzbyB3ZSBuZWVkIHRvIGNvbnZlcnQgaXQgdG8gc3RyaW5nW10gYmVsb3cuIFdoaWxlIGluIG9ydFxuICAgICAgLy8gZm9ybWF0IHN0cmluZ3MgYXR0cmlidXRlcyBhcmUgcmV0dXJuZWQgYXMgc3RyaW5nW10sIHNvIG5vIGNvbnZlcnNpb24gaXMgbmVlZGVkLlxuICAgICAgaWYgKGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvKSB7XG4gICAgICAgIGNvbnN0IHV0ZjhTdHJpbmdzID0gdmFsdWUgYXMgVWludDhBcnJheVtdO1xuICAgICAgICByZXR1cm4gdXRmOFN0cmluZ3MubWFwKGRlY29kZVV0ZjhTdHJpbmcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZSBhcyBWYWx1ZVR5cGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VmFsdWVOb0NoZWNrKGF0dHI6IG9ubnguSUF0dHJpYnV0ZVByb3RvIHwgb3J0RmJzLkF0dHJpYnV0ZSkge1xuICAgIHJldHVybiBhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgPyB0aGlzLmdldFZhbHVlTm9DaGVja0Zyb21Pbm54Rm9ybWF0KGF0dHIpXG4gICAgICA6IHRoaXMuZ2V0VmFsdWVOb0NoZWNrRnJvbU9ydEZvcm1hdChhdHRyIGFzIG9ydEZicy5BdHRyaWJ1dGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VmFsdWVOb0NoZWNrRnJvbU9ubnhGb3JtYXQoYXR0cjogb25ueC5JQXR0cmlidXRlUHJvdG8pIHtcbiAgICBzd2l0Y2ggKGF0dHIudHlwZSEpIHtcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkZMT0FUOlxuICAgICAgICByZXR1cm4gYXR0ci5mO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UOlxuICAgICAgICByZXR1cm4gYXR0ci5pO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuU1RSSU5HOlxuICAgICAgICByZXR1cm4gYXR0ci5zO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SOlxuICAgICAgICByZXR1cm4gYXR0ci50O1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuR1JBUEg6XG4gICAgICAgIHJldHVybiBhdHRyLmc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5GTE9BVFM6XG4gICAgICAgIHJldHVybiBhdHRyLmZsb2F0cztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLklOVFM6XG4gICAgICAgIHJldHVybiBhdHRyLmludHM7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkdTOlxuICAgICAgICByZXR1cm4gYXR0ci5zdHJpbmdzO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SUzpcbiAgICAgICAgcmV0dXJuIGF0dHIudGVuc29ycztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkdSQVBIUzpcbiAgICAgICAgcmV0dXJuIGF0dHIuZ3JhcGhzO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBhdHRyaWJ1dGUgdHlwZTogJHtvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGVbYXR0ci50eXBlIV19YCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VmFsdWVOb0NoZWNrRnJvbU9ydEZvcm1hdChhdHRyOiBvcnRGYnMuQXR0cmlidXRlKSB7XG4gICAgc3dpdGNoIChhdHRyLnR5cGUoKSkge1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5GTE9BVDpcbiAgICAgICAgcmV0dXJuIGF0dHIuZigpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5JTlQ6XG4gICAgICAgIHJldHVybiBhdHRyLmkoKTtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuU1RSSU5HOlxuICAgICAgICByZXR1cm4gYXR0ci5zKCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLlRFTlNPUjpcbiAgICAgICAgcmV0dXJuIGF0dHIudCgpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5HUkFQSDpcbiAgICAgICAgcmV0dXJuIGF0dHIuZygpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5GTE9BVFM6XG4gICAgICAgIHJldHVybiBhdHRyLmZsb2F0c0FycmF5KCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLklOVFM6IHtcbiAgICAgICAgY29uc3QgaW50cyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dHIuaW50c0xlbmd0aCgpOyBpKyspIHtcbiAgICAgICAgICBpbnRzLnB1c2goYXR0ci5pbnRzKGkpISk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGludHM7XG4gICAgICB9XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLlNUUklOR1M6IHtcbiAgICAgICAgY29uc3Qgc3RyaW5ncyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dHIuc3RyaW5nc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgICAgICBzdHJpbmdzLnB1c2goYXR0ci5zdHJpbmdzKGkpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RyaW5ncztcbiAgICAgIH1cbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuVEVOU09SUzoge1xuICAgICAgICBjb25zdCB0ZW5zb3JzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0ci50ZW5zb3JzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgICAgIHRlbnNvcnMucHVzaChhdHRyLnRlbnNvcnMoaSkhKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGVuc29ycztcbiAgICAgIH1cbiAgICAgIC8vIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuR1JBUEhTOlxuICAgICAgLy8gVE9ETzogU3ViZ3JhcGggbm90IHN1cHBvcnRlZCB5ZXQuXG4gICAgICAvLyBjb25zdCBncmFwaHMgPSBbXTtcbiAgICAgIC8vIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0ci5ncmFwaHNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICAvLyAgIGdyYXBocy5wdXNoKGF0dHIuZ3JhcGhzKGkpISk7XG4gICAgICAvLyB9XG4gICAgICAvLyByZXR1cm4gZ3JhcGhzO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBhdHRyaWJ1dGUgdHlwZTogJHtvcnRGYnMuQXR0cmlidXRlVHlwZVthdHRyLnR5cGUoKV19YCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIF9hdHRyaWJ1dGVzOiBNYXA8c3RyaW5nLCBWYWx1ZT47XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZSB9IGZyb20gJy4vYXR0cmlidXRlJztcbmltcG9ydCAqIGFzIG9ydEZicyBmcm9tICcuL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQgeyBvbm54IH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuaW1wb3J0IHsgTG9uZ1V0aWwsIE1BWF9DTElQLCBNSU5fQ0xJUCwgUHJvdG9VdGlsIH0gZnJvbSAnLi91dGlsJztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIEdyYXBoIHtcbiAgZXhwb3J0IGludGVyZmFjZSBTaGFwZSB7XG4gICAgcmVhZG9ubHkgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBWYWx1ZVR5cGUge1xuICAgIHJlYWRvbmx5IHRlbnNvclR5cGU6IFRlbnNvci5EYXRhVHlwZTtcbiAgICByZWFkb25seSBzaGFwZTogU2hhcGU7XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBWYWx1ZSB7XG4gICAgLy8gdGhlIHRlbnNvciBkYXRhLiBlbXB0eSBmb3Igbm9uLWluaXRpYWxpemVkIGlucHV0c1xuICAgIHJlYWRvbmx5IHRlbnNvcj86IFRlbnNvcjtcblxuICAgIC8vIGluZGV4IHRvIHRoZSBOb2RlIHdoZXJlIHRoZSB2YWx1ZSBjb21lcyBmcm9tLiAtMSBmb3IgaW5pdGlhbGl6ZXIuXG4gICAgcmVhZG9ubHkgZnJvbTogbnVtYmVyO1xuXG4gICAgLy8gaW5kaWNlcyB0byB0aGUgTm9kZXMgd2hlcmUgdGhlIHZhbHVlcyBnbyB0by5cbiAgICByZWFkb25seSB0bzogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgICAvLyB2YWx1ZSB0eXBlIHNwZWNpZmljYXRpb24uIGVtcHR5IGZvciBub24taW5wdXQgdmFsdWVzLlxuICAgIHJlYWRvbmx5IHR5cGU/OiBWYWx1ZVR5cGU7XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBOb2RlIHtcbiAgICAvLyBuYW1lIG9mIHRoZSBub2RlXG4gICAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuXG4gICAgLy8gdGhlIG9wZXJhdG9yIHR5cGVcbiAgICByZWFkb25seSBvcFR5cGU6IHN0cmluZztcblxuICAgIC8vIGluZGljZXMgdG8gdGhlIFZhbHVlcyB3aGVyZSB0aGUgaW5wdXRzIGNvbWUgZnJvbS5cbiAgICByZWFkb25seSBpbnB1dHM6IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gICAgLy8gaW5kaWNlcyB0byB0aGUgVmFsdWVzIHdoZXJlIHRoZSBvdXRwdXMgZ28gdG8uXG4gICAgcmVhZG9ubHkgb3V0cHV0czogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgICAvLyB0aGUgYXR0cmlidXRlcyB0aGF0IHVzZWQgYnkgdGhlIG9wZXJhdG9yXG4gICAgcmVhZG9ubHkgYXR0cmlidXRlczogQXR0cmlidXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIGEgVHJhbnNmb3JtZXIgaXMgYW4gaW5zdGFuY2UgdGhhdCBhbGxvd3MgYWxsIHBvc3NpYmxlIHRyYW5zZm9ybWF0aW9uIG9wZXJhdGlvbnMgdGhhdCBhcHBsaWVkIHRvIGEgZ3JhcGhcbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgVHJhbnNmb3JtZXIge1xuICAgIHJlbW92ZUFsbElkZW50aXR5Tm9kZXMoKTogdm9pZDtcbiAgICByZW1vdmVBbGxEcm9wb3V0Tm9kZXMoKTogdm9pZDtcbiAgICBmdXNlQ29udkFjdGl2YXRpb25Ob2RlcygpOiB2b2lkO1xuICAgIC8vIFRPRE86IGFkZCBnZW5lcmljIGZ1bmN0aW9ucyB0byBtYW5pcHVsYXRlIHRoZSBncmFwaFxuICB9XG5cbiAgLy8gYW4gaW5pdGlhbGl6ZXIgY2FuIHVzZSB0cmFuc2Zvcm1lciB0byB0cmFuc2Zvcm0gdGhlIGdyYXBoXG4gIGV4cG9ydCBpbnRlcmZhY2UgSW5pdGlhbGl6ZXIge1xuICAgIHRyYW5zZm9ybUdyYXBoKHRyYW5zZm9ybWVyOiBUcmFuc2Zvcm1lcik6IHZvaWQ7XG4gIH1cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmVcbmV4cG9ydCBpbnRlcmZhY2UgR3JhcGgge1xuICBnZXRJbnB1dEluZGljZXMoKTogcmVhZG9ubHkgbnVtYmVyW107XG4gIGdldElucHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW107XG4gIGdldE91dHB1dEluZGljZXMoKTogcmVhZG9ubHkgbnVtYmVyW107XG4gIGdldE91dHB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICBnZXRWYWx1ZXMoKTogcmVhZG9ubHkgR3JhcGguVmFsdWVbXTtcbiAgZ2V0Tm9kZXMoKTogcmVhZG9ubHkgR3JhcGguTm9kZVtdO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlXG5leHBvcnQgY29uc3QgR3JhcGggPSB7XG4gIC8qKlxuICAgKiBjb25zdHJ1Y3QgYSBncmFwaCBmcm9tIGEgZ3JhcGggcHJvdG9idWYgdHlwZVxuICAgKi9cbiAgZnJvbTogKGdyYXBoUHJvdG86IG9ubnguSUdyYXBoUHJvdG8gfCBvcnRGYnMuR3JhcGgsIGluaXRpYWxpemVyPzogR3JhcGguSW5pdGlhbGl6ZXIpID0+XG4gICAgbmV3IEdyYXBoSW1wbChncmFwaFByb3RvLCBpbml0aWFsaXplciksXG59O1xuXG5jbGFzcyBWYWx1ZSBpbXBsZW1lbnRzIEdyYXBoLlZhbHVlIHtcbiAgY29uc3RydWN0b3IodmFsdWVJbmZvPzogb25ueC5JVmFsdWVJbmZvUHJvdG8pIHtcbiAgICB0aGlzLl9mcm9tID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3RvID0gW107XG4gICAgdGhpcy50ZW5zb3IgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy50eXBlID0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKHZhbHVlSW5mbykge1xuICAgICAgdGhpcy50eXBlID0gUHJvdG9VdGlsLnRlbnNvclZhbHVlVHlwZUZyb21Qcm90byh2YWx1ZUluZm8udHlwZSEudGVuc29yVHlwZSEpO1xuICAgIH1cbiAgfVxuXG4gIF9mcm9tPzogbnVtYmVyOyAvLyAtMSByZXByZXNlbnQgZnJvbSBpbml0aWFsaXplclxuICBnZXQgZnJvbSgpIHtcbiAgICByZXR1cm4gdGhpcy5fZnJvbSE7XG4gIH1cbiAgX3RvOiBudW1iZXJbXTtcbiAgZ2V0IHRvKCkge1xuICAgIHJldHVybiB0aGlzLl90bztcbiAgfVxuICB0eXBlPzogR3JhcGguVmFsdWVUeXBlO1xuICB0ZW5zb3I/OiBUZW5zb3I7XG59XG5cbmNsYXNzIE5vZGUgaW1wbGVtZW50cyBHcmFwaC5Ob2RlIHtcbiAgY29uc3RydWN0b3IoX25vZGVQcm90bzogb25ueC5JTm9kZVByb3RvIHwgb3J0RmJzLk5vZGUsIG5hbWU/OiBzdHJpbmcpIHtcbiAgICBpZiAoX25vZGVQcm90byBpbnN0YW5jZW9mIG9ubnguTm9kZVByb3RvKSB7XG4gICAgICB0aGlzLm5hbWUgPSBfbm9kZVByb3RvLm5hbWU7XG4gICAgICB0aGlzLm9wVHlwZSA9IF9ub2RlUHJvdG8ub3BUeXBlO1xuICAgICAgdGhpcy5hdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZShfbm9kZVByb3RvLmF0dHJpYnV0ZSk7XG4gICAgfSBlbHNlIGlmIChfbm9kZVByb3RvIGluc3RhbmNlb2Ygb3J0RmJzLk5vZGUpIHtcbiAgICAgIHRoaXMubmFtZSA9IG5hbWUgPz8gX25vZGVQcm90by5uYW1lKCkhO1xuICAgICAgdGhpcy5vcFR5cGUgPSBfbm9kZVByb3RvLm9wVHlwZSgpITtcbiAgICAgIHRoaXMuYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGUoUHJvdG9VdGlsLnRlbnNvckF0dHJpYnV0ZXNGcm9tT1JURm9ybWF0KF9ub2RlUHJvdG8pKTtcbiAgICB9XG5cbiAgICB0aGlzLmlucHV0cyA9IFtdO1xuICAgIHRoaXMub3V0cHV0cyA9IFtdO1xuICAgIHRoaXMuZXhlY3V0ZU5vZGUgPSB0cnVlO1xuICB9XG5cbiAgbmFtZTogc3RyaW5nO1xuICBvcFR5cGU6IHN0cmluZztcbiAgaW5wdXRzOiBudW1iZXJbXTtcbiAgb3V0cHV0czogbnVtYmVyW107XG4gIGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZTtcbiAgZXhlY3V0ZU5vZGU6IGJvb2xlYW47XG59XG5cbmNsYXNzIEdyYXBoSW1wbCBpbXBsZW1lbnRzIEdyYXBoLCBHcmFwaC5UcmFuc2Zvcm1lciB7XG4gIHByaXZhdGUgX2FsbERhdGE6IFZhbHVlW107XG5cbiAgcHJpdmF0ZSBfYWxsSW5wdXRJbmRpY2VzOiBudW1iZXJbXTtcbiAgcHJpdmF0ZSBfYWxsSW5wdXROYW1lczogc3RyaW5nW107XG5cbiAgcHJpdmF0ZSBfYWxsT3V0cHV0SW5kaWNlczogbnVtYmVyW107XG4gIHByaXZhdGUgX2FsbE91dHB1dE5hbWVzOiBzdHJpbmdbXTtcblxuICBwcml2YXRlIF9ub2RlczogTm9kZVtdO1xuXG4gIGNvbnN0cnVjdG9yKGdyYXBoOiBvbm54LklHcmFwaFByb3RvIHwgb3J0RmJzLkdyYXBoLCBncmFwaEluaXRpYWxpemVyPzogR3JhcGguSW5pdGlhbGl6ZXIpIHtcbiAgICBpZiAoIWdyYXBoKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdncmFwaCBpcyBlbXB0eScpO1xuICAgIH1cblxuICAgIC8vIGJ1aWxkIHRoZSBncmFwaCAtIHdpbGwgdGhyb3cgZXhjZXB0aW9ucyBpZiBzb21ldGhpbmcgZmF0YWwgaXMgZGV0ZWN0ZWRcbiAgICB0aGlzLmJ1aWxkR3JhcGgoZ3JhcGgpO1xuXG4gICAgLy8gZXhlY3V0ZSBhbnkgdHJhbnNmb3JtYXRpb24gbG9naWMgZm9yIHRoZSBncmFwaCAoaWYgYXBwbGljYWJsZSlcbiAgICB0aGlzLnRyYW5zZm9ybUdyYXBoKGdyYXBoSW5pdGlhbGl6ZXIpO1xuXG4gICAgLy8gY2hlY2sgZm9yIGN5Y2xlcyBhbmQgb3RoZXIgaW5jb25zaXN0ZW5jaWVzIC0gd2lsbCB0aHJvdyBleGNlcHRpb25zIGlmIHNvbWV0aGluZyBmYXRhbCBpcyBkZXRlY3RlZFxuICAgIHRoaXMuY2hlY2tJc0FjeWNsaWMoKTtcbiAgfVxuXG4gIGdldElucHV0SW5kaWNlcygpOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsbElucHV0SW5kaWNlcztcbiAgfVxuXG4gIGdldElucHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxJbnB1dE5hbWVzO1xuICB9XG5cbiAgZ2V0T3V0cHV0SW5kaWNlcygpOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsbE91dHB1dEluZGljZXM7XG4gIH1cblxuICBnZXRPdXRwdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsbE91dHB1dE5hbWVzO1xuICB9XG5cbiAgZ2V0VmFsdWVzKCk6IHJlYWRvbmx5IEdyYXBoLlZhbHVlW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxEYXRhO1xuICB9XG5cbiAgZ2V0Tm9kZXMoKTogcmVhZG9ubHkgR3JhcGguTm9kZVtdIHtcbiAgICByZXR1cm4gdGhpcy5fbm9kZXM7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkR3JhcGgoZ3JhcGg6IG9ubnguSUdyYXBoUHJvdG8gfCBvcnRGYnMuR3JhcGgpIHtcbiAgICAvLyBidWlsZCB0aGUgZ3JhcGggLSB3aWxsIHRocm93IGV4Y2VwdGlvbnMgaWYgc29tZXRoaW5nIGZhdGFsIGlzIGRldGVjdGVkXG4gICAgaWYgKGdyYXBoIGluc3RhbmNlb2Ygb25ueC5HcmFwaFByb3RvKSB7XG4gICAgICB0aGlzLmJ1aWxkR3JhcGhGcm9tT25ueEZvcm1hdChncmFwaCk7XG4gICAgfSBlbHNlIGlmIChncmFwaCBpbnN0YW5jZW9mIG9ydEZicy5HcmFwaCkge1xuICAgICAgdGhpcy5idWlsZEdyYXBoRnJvbU9ydEZvcm1hdChncmFwaCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0dyYXBoIHR5cGUgaXMgbm90IHN1cHBvcnRlZC4nKTtcbiAgICB9XG4gIH1cbiAgcHJpdmF0ZSBidWlsZEdyYXBoRnJvbU9ubnhGb3JtYXQoZ3JhcGg6IG9ubnguSUdyYXBoUHJvdG8pIHtcbiAgICBjb25zdCBkYXRhSW5kaWNlcyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gICAgdGhpcy5fYWxsRGF0YSA9IFtdO1xuXG4gICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzID0gW107XG4gICAgdGhpcy5fYWxsSW5wdXROYW1lcyA9IFtdO1xuXG4gICAgdGhpcy5fYWxsT3V0cHV0SW5kaWNlcyA9IFtdO1xuICAgIHRoaXMuX2FsbE91dHB1dE5hbWVzID0gW107XG5cbiAgICB0aGlzLl9ub2RlcyA9IFtdO1xuXG4gICAgY29uc3Qgbm9kZXNJbmRpY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcblxuICAgIC8vIHNjYW4gYWxsIGlucHV0c1xuICAgIGlmICghZ3JhcGguaW5wdXQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBpbmZvcm1hdGlvbiBpbiBncmFwaDogaW5wdXQnKTtcbiAgICB9XG4gICAgY29uc3QgaW5wdXRWYWx1ZU5hbWVzID0gW107XG4gICAgZm9yIChjb25zdCBpIG9mIGdyYXBoLmlucHV0KSB7XG4gICAgICBpZiAoZGF0YUluZGljZXMuaGFzKGkubmFtZSEpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBpbnB1dCBuYW1lOiAke2kubmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaChuZXcgVmFsdWUoaSkpIC0gMTtcbiAgICAgIGRhdGFJbmRpY2VzLnNldChpLm5hbWUhLCBjdXJyZW50SW5kZXgpO1xuICAgICAgaW5wdXRWYWx1ZU5hbWVzLnB1c2goaS5uYW1lISk7XG4gICAgfVxuXG4gICAgLy8gc2NhbiBhbGwgaW5pdGlhbGl6ZXJzXG4gICAgaWYgKCFncmFwaC5pbml0aWFsaXplcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGluZm9ybWF0aW9uIGluIGdyYXBoOiBpbml0aWFsaXplcicpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGkgb2YgZ3JhcGguaW5pdGlhbGl6ZXIpIHtcbiAgICAgIGxldCBpbmRleCA9IGRhdGFJbmRpY2VzLmdldChpLm5hbWUhKTtcbiAgICAgIGlmIChpbmRleCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gbmV3IFZhbHVlKCk7XG4gICAgICAgIHZhbHVlLnR5cGUgPSB7XG4gICAgICAgICAgc2hhcGU6IHsgZGltczogUHJvdG9VdGlsLnRlbnNvckRpbXNGcm9tUHJvdG8oaS5kaW1zISkgfSxcbiAgICAgICAgICB0ZW5zb3JUeXBlOiBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8oaS5kYXRhVHlwZSEpLFxuICAgICAgICB9O1xuICAgICAgICBpbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaCh2YWx1ZSkgLSAxO1xuICAgICAgICBkYXRhSW5kaWNlcy5zZXQoaS5uYW1lISwgaW5kZXgpO1xuICAgICAgfVxuICAgICAgdGhpcy5fYWxsRGF0YVtpbmRleF0uX2Zyb20gPSAtMTtcbiAgICAgIHRoaXMuX2FsbERhdGFbaW5kZXhdLnRlbnNvciA9IFRlbnNvci5mcm9tUHJvdG8oaSk7XG4gICAgfVxuXG4gICAgLy8gZmlsdGVyIG91dCBpbnB1dCBpbmRpY2VzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hbGxEYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIXRoaXMuX2FsbERhdGFbaV0udGVuc29yKSB7XG4gICAgICAgIHRoaXMuX2FsbElucHV0SW5kaWNlcy5wdXNoKGkpO1xuICAgICAgICB0aGlzLl9hbGxJbnB1dE5hbWVzLnB1c2goaW5wdXRWYWx1ZU5hbWVzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzY2FuIGFsbCBvdXRwdXRzXG4gICAgaWYgKCFncmFwaC5vdXRwdXQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBpbmZvcm1hdGlvbiBpbiBncmFwaDogb3V0cHV0Jyk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgaSBvZiBncmFwaC5vdXRwdXQpIHtcbiAgICAgIGlmIChkYXRhSW5kaWNlcy5oYXMoaS5uYW1lISkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBkdXBsaWNhdGVkIG91dHB1dCBuYW1lOiAke2kubmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaChuZXcgVmFsdWUoaSkpIC0gMTtcbiAgICAgIGRhdGFJbmRpY2VzLnNldChpLm5hbWUhLCBjdXJyZW50SW5kZXgpO1xuICAgICAgdGhpcy5fYWxsT3V0cHV0SW5kaWNlcy5wdXNoKGN1cnJlbnRJbmRleCk7XG4gICAgICB0aGlzLl9hbGxPdXRwdXROYW1lcy5wdXNoKGkubmFtZSEpO1xuICAgIH1cblxuICAgIC8vIHNjYW4gYWxsIG5vZGVzXG4gICAgaWYgKCFncmFwaC5ub2RlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgaW5mb3JtYXRpb24gaW4gZ3JhcGg6IG5vZGUnKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBub2RlUHJvdG8gb2YgZ3JhcGgubm9kZSkge1xuICAgICAgaWYgKCFub2RlUHJvdG8ubmFtZSkge1xuICAgICAgICAvLyBhc3NpZ24gYSBuYW1lIHRvIHRoZSBub2RlIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmVcbiAgICAgICAgZm9yIChsZXQgcGljayA9IDA7IDsgcGljaysrKSB7XG4gICAgICAgICAgY29uc3QgbmFtZSA9IGB1bm5hbWVkXyR7bm9kZVByb3RvLm9wVHlwZX1fJHtwaWNrfWA7XG4gICAgICAgICAgaWYgKCFub2Rlc0luZGljZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICBub2RlUHJvdG8ubmFtZSA9IG5hbWU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGVzSW5kaWNlcy5oYXMobm9kZVByb3RvLm5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBub2RlIG5hbWU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0aGlzLl9ub2Rlcy5wdXNoKG5ldyBOb2RlKG5vZGVQcm90bykpIC0gMTtcbiAgICAgIG5vZGVzSW5kaWNlcy5zZXQobm9kZVByb3RvLm5hbWUsIGN1cnJlbnRJbmRleCk7XG4gICAgfVxuXG4gICAgLy8gc2NhbiBub2RlJ3Mgb3V0cHV0c1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9ub2Rlc1tpXTtcbiAgICAgIGNvbnN0IG5vZGVQcm90byA9IGdyYXBoLm5vZGVbaV07XG4gICAgICBpZiAoIW5vZGVQcm90by5vdXRwdXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIG91dHB1dCBmb3Igbm9kZTogJHtub2RlUHJvdG8ubmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3Qgb3V0cHV0IG9mIG5vZGVQcm90by5vdXRwdXQpIHtcbiAgICAgICAgbGV0IGRhdGFJbmRleCA9IGRhdGFJbmRpY2VzLmdldChvdXRwdXQpO1xuICAgICAgICBpZiAodHlwZW9mIGRhdGFJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBkYXRhSW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2gobmV3IFZhbHVlKCkpIC0gMTtcbiAgICAgICAgICBkYXRhSW5kaWNlcy5zZXQob3V0cHV0LCBkYXRhSW5kZXgpO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUub3V0cHV0cy5wdXNoKGRhdGFJbmRleCk7XG5cbiAgICAgICAgaWYgKHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fZnJvbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtdWx0aXBsZSBub2RlcyBvdXRwdXQgdG8gb25lIGRhdGEgdmFsdWU6ICR7ZGF0YUluZGV4fWApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fZnJvbSA9IGk7XG5cbiAgICAgICAgLy8gZm9yIHRoZSAnQ29uc3RhbnQnIG9wZXJhdG9yLCBqdXN0IGNyZWF0ZSBhIG5ldyBlZGdlIGluIHRoZSBncmFwaCBjb3JyZXNwb25kaW5nIHRvIHRoZSAnb3V0cHV0JyBvZiB0aGVcbiAgICAgICAgLy8gb3BlcmF0b3IgYW5kIGlnbm9yZSB0aGUgbm9kZSBmcm9tIHRoZSBncmFwaFxuICAgICAgICBpZiAobm9kZVByb3RvLm9wVHlwZSA9PT0gJ0NvbnN0YW50Jykge1xuICAgICAgICAgIGlmICghbm9kZVByb3RvLmF0dHJpYnV0ZSB8fCBub2RlUHJvdG8uYXR0cmlidXRlLmxlbmd0aCAhPT0gMSB8fCAhbm9kZVByb3RvLmF0dHJpYnV0ZVswXS50KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgYXR0cmlidXRlcyBvciBtaXNzaW5nIHRlbnNvciB2YWx1ZSBpbiBhdHRyaWJ1dGVzIGZvciB0aGlzIENvbnN0YW50IG9wZXJhdG9yJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghbm9kZVByb3RvLm91dHB1dCB8fCBub2RlUHJvdG8ub3V0cHV0Lmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIG91dHB1dCBvciBpbmNvcnJlY3QgbnVtYmVyIG9mIG91dHB1dHMgZm9yIHRoaXMgQ29uc3RhbnQgb3BlcmF0b3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbm9kZS5vdXRwdXRzLnBvcCgpO1xuICAgICAgICAgIG5vZGUuZXhlY3V0ZU5vZGUgPSBmYWxzZTtcblxuICAgICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fZnJvbSA9IC0xO1xuICAgICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS50ZW5zb3IgPSBUZW5zb3IuZnJvbVByb3RvKG5vZGVQcm90by5hdHRyaWJ1dGVbMF0udCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzY2FuIG5vZGUncyBpbnB1dHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5fbm9kZXNbaV07XG4gICAgICBjb25zdCBub2RlUHJvdG8gPSBncmFwaC5ub2RlW2ldO1xuXG4gICAgICBpZiAoIW5vZGVQcm90by5pbnB1dCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG1pc3NpbmcgaW5wdXQgZm9yIG5vZGU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGlucHV0IG9mIG5vZGVQcm90by5pbnB1dCkge1xuICAgICAgICBjb25zdCBkYXRhSW5kZXggPSBkYXRhSW5kaWNlcy5nZXQoaW5wdXQpO1xuICAgICAgICBpZiAodHlwZW9mIGRhdGFJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAvLyBoYW5kbGUgZXhjZXB0aW9uIHdoZW4gb3BzZXQgPiA5IGFuZCByb2kgLyBzY2FsZXMgbm90IGdpdmVuXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgaW5wdXQgPT09ICcnICYmXG4gICAgICAgICAgICAobm9kZVByb3RvLmlucHV0Lmxlbmd0aCA9PT0gMyB8fCBub2RlUHJvdG8uaW5wdXQubGVuZ3RoID09PSA0KSAmJlxuICAgICAgICAgICAgbm9kZVByb3RvLm9wVHlwZSA9PT0gJ1Jlc2l6ZSdcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVucmVjb2duaXplZCBpbnB1dCAnJHtpbnB1dH0nIGZvciBub2RlOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUuaW5wdXRzLnB1c2goZGF0YUluZGV4KTtcblxuICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX3RvLnB1c2goaSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkR3JhcGhGcm9tT3J0Rm9ybWF0KGdyYXBoOiBvcnRGYnMuR3JhcGgpIHtcbiAgICBjb25zdCBkYXRhSW5kaWNlcyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gICAgdGhpcy5fYWxsRGF0YSA9IFtdO1xuXG4gICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzID0gW107XG4gICAgdGhpcy5fYWxsSW5wdXROYW1lcyA9IFtdO1xuXG4gICAgdGhpcy5fYWxsT3V0cHV0SW5kaWNlcyA9IFtdO1xuICAgIHRoaXMuX2FsbE91dHB1dE5hbWVzID0gW107XG5cbiAgICB0aGlzLl9ub2RlcyA9IFtdO1xuXG4gICAgY29uc3Qgbm9kZXNJbmRpY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcblxuICAgIC8vIHNjYW4gYWxsIGlucHV0c1xuICAgIGNvbnN0IGlucHV0VmFsdWVOYW1lcyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ3JhcGguaW5wdXRzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3QgaW5wdXROYW1lID0gZ3JhcGguaW5wdXRzKGkpO1xuICAgICAgaWYgKGRhdGFJbmRpY2VzLmhhcyhpbnB1dE5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBpbnB1dCBuYW1lOiAke2lucHV0TmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIC8vIEZpbmQgdGhlIGlucHV0IHR5cGVJbmZvIGZyb20gbm9kZWFyZ3NcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgZ3JhcGgubm9kZUFyZ3NMZW5ndGgoKTsgaisrKSB7XG4gICAgICAgIGlmIChncmFwaC5ub2RlQXJncyhqKT8ubmFtZSgpID09PSBpbnB1dE5hbWUpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IG5ldyBWYWx1ZSgpO1xuICAgICAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IGdyYXBoLm5vZGVBcmdzKGopPy50eXBlKCk/LnZhbHVlVHlwZSgpO1xuICAgICAgICAgIGlmICh2YWx1ZVR5cGUgIT09IG9ydEZicy5UeXBlSW5mb1ZhbHVlLnRlbnNvcl90eXBlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgdmFsdWUgdHlwZSBmb3IgdGhlIG5vZGVBcmcuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHZhbHVlSW5mbyA9IGdyYXBoLm5vZGVBcmdzKGopIS50eXBlKCkhLnZhbHVlKG5ldyBvcnRGYnMuVGVuc29yVHlwZUFuZFNoYXBlKCkpITtcbiAgICAgICAgICBjb25zdCB0eXBlID0gUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKHZhbHVlSW5mby5lbGVtVHlwZSgpKTtcbiAgICAgICAgICBjb25zdCBzaGFwZSA9IHZhbHVlSW5mby5zaGFwZSgpITtcbiAgICAgICAgICBjb25zdCBkaW1zID0gW107XG4gICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBzaGFwZS5kaW1MZW5ndGgoKSE7IGsrKykge1xuICAgICAgICAgICAgZGltcy5wdXNoKExvbmdVdGlsLmxvbmdUb051bWJlcihzaGFwZS5kaW0oaykhLnZhbHVlKCkhLmRpbVZhbHVlKCkhKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhbHVlLnR5cGUgPSB7IHNoYXBlOiB7IGRpbXMgfSwgdGVuc29yVHlwZTogdHlwZSB9O1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaCh2YWx1ZSkgLSAxO1xuICAgICAgICAgIGRhdGFJbmRpY2VzLnNldChpbnB1dE5hbWUsIGN1cnJlbnRJbmRleCk7XG4gICAgICAgICAgaW5wdXRWYWx1ZU5hbWVzLnB1c2goaW5wdXROYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBjaGVjayBpbml0aWFsaXplcnNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoLmluaXRpYWxpemVyc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGNvbnN0IGluaXRpYWxpemVyID0gZ3JhcGguaW5pdGlhbGl6ZXJzKGkpITtcbiAgICAgIGxldCBpbmRleCA9IGRhdGFJbmRpY2VzLmdldChpbml0aWFsaXplci5uYW1lKCkhKTtcbiAgICAgIGlmIChpbmRleCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gbmV3IFZhbHVlKCk7XG4gICAgICAgIGNvbnN0IGRpbXMgPSBQcm90b1V0aWwudGVuc29yRGltc0Zyb21PUlRGb3JtYXQoaW5pdGlhbGl6ZXIpO1xuICAgICAgICBjb25zdCB0eXBlID0gUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKGluaXRpYWxpemVyLmRhdGFUeXBlKCkpO1xuICAgICAgICB2YWx1ZS50eXBlID0geyBzaGFwZTogeyBkaW1zIH0sIHRlbnNvclR5cGU6IHR5cGUgfTtcbiAgICAgICAgaW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2godmFsdWUpIC0gMTtcbiAgICAgICAgZGF0YUluZGljZXMuc2V0KGluaXRpYWxpemVyLm5hbWUoKSEsIGluZGV4KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2FsbERhdGFbaW5kZXhdLl9mcm9tID0gLTE7XG4gICAgICB0aGlzLl9hbGxEYXRhW2luZGV4XS50ZW5zb3IgPSBUZW5zb3IuZnJvbU9ydFRlbnNvcihpbml0aWFsaXplcik7XG4gICAgfVxuXG4gICAgLy8gZmlsdGVyIG91dCBpbnB1dCBpbmRpY2VzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hbGxEYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIXRoaXMuX2FsbERhdGFbaV0udGVuc29yKSB7XG4gICAgICAgIHRoaXMuX2FsbElucHV0SW5kaWNlcy5wdXNoKGkpO1xuICAgICAgICB0aGlzLl9hbGxJbnB1dE5hbWVzLnB1c2goaW5wdXRWYWx1ZU5hbWVzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzY2FuIGFsbCBvdXRwdXRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaC5vdXRwdXRzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3Qgb3V0cHV0TmFtZSA9IGdyYXBoLm91dHB1dHMoaSk7XG4gICAgICBpZiAoZGF0YUluZGljZXMuaGFzKG91dHB1dE5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBvdXRwdXQgbmFtZTogJHtvdXRwdXROYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZSgpKSAtIDE7XG4gICAgICBkYXRhSW5kaWNlcy5zZXQob3V0cHV0TmFtZSwgY3VycmVudEluZGV4KTtcbiAgICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXMucHVzaChjdXJyZW50SW5kZXgpO1xuICAgICAgdGhpcy5fYWxsT3V0cHV0TmFtZXMucHVzaChvdXRwdXROYW1lKTtcbiAgICB9XG5cbiAgICAvLyBzY2FuIGFsbCBub2Rlc1xuICAgIGlmICghZ3JhcGgubm9kZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBpbmZvcm1hdGlvbiBpbiBncmFwaDogbm9kZScpO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoLm5vZGVzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3Qgbm9kZVByb3RvID0gZ3JhcGgubm9kZXMoaSk7XG4gICAgICBsZXQgbmFtZSA9IG5vZGVQcm90byEubmFtZSgpO1xuICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgIC8vIGFzc2lnbiBhIG5hbWUgdG8gdGhlIG5vZGUgaWYgaXQgZG9lc24ndCBoYXZlIG9uZVxuICAgICAgICBmb3IgKGxldCBwaWNrID0gMDsgOyBwaWNrKyspIHtcbiAgICAgICAgICBuYW1lID0gYHVubmFtZWRfJHtub2RlUHJvdG8hLm9wVHlwZSgpfV8ke3BpY2t9YDtcbiAgICAgICAgICBpZiAoIW5vZGVzSW5kaWNlcy5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgIC8vIGFuIHVuaXF1ZSBuYW1lIGlzIGZvdW5kLiBicmVhay5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAobm9kZXNJbmRpY2VzLmhhcyhuYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgbm9kZSBuYW1lOiAke25hbWV9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0aGlzLl9ub2Rlcy5wdXNoKG5ldyBOb2RlKG5vZGVQcm90byEsIG5hbWUpKSAtIDE7XG4gICAgICBub2Rlc0luZGljZXMuc2V0KG5hbWUsIGN1cnJlbnRJbmRleCk7XG4gICAgfVxuXG4gICAgLy8gc2NhbiBub2RlJ3Mgb3V0cHV0c1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9ub2Rlc1tpXTtcbiAgICAgIGNvbnN0IG5vZGVQcm90byA9IGdyYXBoLm5vZGVzKGkpO1xuICAgICAgaWYgKG5vZGVQcm90byA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gbm9kZSBleGlzdHMgYXQgaW5kZXggJHtpfWApO1xuICAgICAgfVxuICAgICAgaWYgKG5vZGVQcm90bz8ub3V0cHV0c0xlbmd0aCgpID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBvdXRwdXQgZm9yIG5vZGU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG5vZGVQcm90bz8ub3V0cHV0c0xlbmd0aCgpOyBqKyspIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gbm9kZVByb3RvPy5vdXRwdXRzKGopO1xuICAgICAgICBsZXQgZGF0YUluZGV4ID0gZGF0YUluZGljZXMuZ2V0KG91dHB1dCk7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YUluZGV4ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGRhdGFJbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaChuZXcgVmFsdWUoKSkgLSAxO1xuICAgICAgICAgIGRhdGFJbmRpY2VzLnNldChvdXRwdXQsIGRhdGFJbmRleCk7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZS5vdXRwdXRzLnB1c2goZGF0YUluZGV4KTtcblxuICAgICAgICBpZiAodGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl9mcm9tICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG11bHRpcGxlIG5vZGVzIG91dHB1dCB0byBvbmUgZGF0YSB2YWx1ZTogJHtkYXRhSW5kZXh9YCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl9mcm9tID0gaTtcblxuICAgICAgICAvLyBmb3IgdGhlICdDb25zdGFudCcgb3BlcmF0b3IsIGp1c3QgY3JlYXRlIGEgbmV3IGVkZ2UgaW4gdGhlIGdyYXBoIGNvcnJlc3BvbmRpbmcgdG8gdGhlICdvdXRwdXQnIG9mIHRoZVxuICAgICAgICAvLyBvcGVyYXRvciBhbmQgaWdub3JlIHRoZSBub2RlIGZyb20gdGhlIGdyYXBoXG4gICAgICAgIGlmIChub2RlUHJvdG8ub3BUeXBlKCkgPT09ICdDb25zdGFudCcpIHtcbiAgICAgICAgICBpZiAobm9kZVByb3RvLmF0dHJpYnV0ZXNMZW5ndGgoKSAhPT0gMSB8fCAhbm9kZVByb3RvLmF0dHJpYnV0ZXMoMCkhLnQoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGF0dHJpYnV0ZXMgb3IgbWlzc2luZyB0ZW5zb3IgdmFsdWUgaW4gYXR0cmlidXRlcyBmb3IgdGhpcyBDb25zdGFudCBvcGVyYXRvcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobm9kZVByb3RvLm91dHB1dHNMZW5ndGgoKSAhPT0gMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIG91dHB1dCBvciBpbmNvcnJlY3QgbnVtYmVyIG9mIG91dHB1dHMgZm9yIHRoaXMgQ29uc3RhbnQgb3BlcmF0b3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbm9kZS5vdXRwdXRzLnBvcCgpO1xuICAgICAgICAgIG5vZGUuZXhlY3V0ZU5vZGUgPSBmYWxzZTtcblxuICAgICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fZnJvbSA9IC0xO1xuICAgICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS50ZW5zb3IgPSBUZW5zb3IuZnJvbU9ydFRlbnNvcihub2RlUHJvdG8uYXR0cmlidXRlcygwKSEudCgpISk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzY2FuIG5vZGUncyBpbnB1dHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5fbm9kZXNbaV07XG4gICAgICBjb25zdCBub2RlUHJvdG8gPSBncmFwaC5ub2RlcyhpKSE7XG5cbiAgICAgIGlmIChub2RlUHJvdG8uaW5wdXRzTGVuZ3RoKCkgPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIGlucHV0IGZvciBub2RlOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBub2RlUHJvdG8uaW5wdXRzTGVuZ3RoKCkhOyBqKyspIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBub2RlUHJvdG8uaW5wdXRzKGopITtcbiAgICAgICAgY29uc3QgZGF0YUluZGV4ID0gZGF0YUluZGljZXMuZ2V0KGlucHV0KTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnJlY29nbml6ZWQgaW5wdXQgJyR7aW5wdXR9JyBmb3Igbm9kZTogJHtub2RlUHJvdG8hLm5hbWUoKX1gKTtcbiAgICAgICAgfVxuICAgICAgICBub2RlLmlucHV0cy5wdXNoKGRhdGFJbmRleCk7XG5cbiAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl90by5wdXNoKGkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tJc0FjeWNsaWMoKSB7XG4gICAgLy8gZ28gdGhyb3VnaCB0aGUgZ3JhcGggYW5kIGNoZWNrIGZvciBjeWNsZXMgb3Igb3RoZXIgZmF0YWwgaW5jb25zaXN0ZW5jaWVzXG4gICAgY29uc3Qgc3RhcnRlcnM6IFNldDxudW1iZXI+ID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzLmZvckVhY2goKGkpID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9hbGxEYXRhW2ldO1xuICAgICAgZGF0YS5fdG8uZm9yRWFjaCgoaikgPT4ge1xuICAgICAgICBzdGFydGVycy5hZGQoaik7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIEl0ZXJhdGl2ZSBERlMgdG8gY2hlY2sgZm9yIGN5Y2xlc1xuICAgIGNvbnN0IG5vZGVzU3RhY2sgPSBBcnJheS5mcm9tKHN0YXJ0ZXJzKTtcbiAgICBjb25zdCBub2Rlc1N0YXRlID0gbmV3IEFycmF5PHN0cmluZz4odGhpcy5fbm9kZXMubGVuZ3RoKS5maWxsKCd3aGl0ZScpO1xuXG4gICAgd2hpbGUgKG5vZGVzU3RhY2subGVuZ3RoID4gMCkge1xuICAgICAgY29uc3Qgbm9kZUluZGV4ID0gbm9kZXNTdGFjay5wb3AoKSE7XG4gICAgICAvLyB0aGlzIG5vZGUgaGFzIG5vdyBiZWVuIHByb2Nlc3NlZCBjb21wbGV0ZWx5LiBNYXJrIHRoaXMgbm9kZSAnYmxhY2snIHRvIGRlbm90ZSB0aGlzLlxuICAgICAgaWYgKG5vZGVzU3RhdGVbbm9kZUluZGV4XSA9PT0gJ2dyYXknKSB7XG4gICAgICAgIG5vZGVzU3RhdGVbbm9kZUluZGV4XSA9ICdibGFjayc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyB0aGlzIG5vZGUgaXMgdW5kZXIgcHJvY2Vzc2luZyBzdGFnZS4gbWFyayB0aGlzIG5vZGUgJ2dyYXknIHRvIGRlbm90ZSB0aGlzLlxuICAgICAgICBub2Rlc1N0YWNrLnB1c2gobm9kZUluZGV4KTtcbiAgICAgICAgbm9kZXNTdGF0ZVtub2RlSW5kZXhdID0gJ2dyYXknO1xuXG4gICAgICAgIHRoaXMuX25vZGVzW25vZGVJbmRleF0ub3V0cHV0cy5mb3JFYWNoKChvdXRnb2luZ0VkZ2VJbmRleCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9hbGxEYXRhW291dGdvaW5nRWRnZUluZGV4XTtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudGVuc29yICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub2RlIG91dHB1dHMgc2hvdWxkIG5vdCBiZSBpbml0aWFsaXplZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZGF0YS5fZnJvbSAhPT0gbm9kZUluZGV4KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJmcm9tIHByb3BlcnR5IG9mIHRoZSBWYWx1ZSBvYmplY3QgZG9lc24ndCBtYXRjaCBpbmRleCBvZiBOb2RlIGJlaW5nIHByb2Nlc3NlZFwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGF0YS5fdG8uZm9yRWFjaCgoZG93bnN0cmVhbU5vZGVJbmRleCkgPT4ge1xuICAgICAgICAgICAgLy8gYmFjayBlZGdlIGZvdW5kIC0gY3ljbGljXG4gICAgICAgICAgICBpZiAobm9kZXNTdGF0ZVtkb3duc3RyZWFtTm9kZUluZGV4XSA9PT0gJ2dyYXknKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbW9kZWwgZ3JhcGggaXMgY3ljbGljJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyB0cmVlIGVkZ2UgZm91bmQgLSBjb250aW51ZSBwcm9jZXNzaW5nIGJ5IGFkZGluZyBpdCB0byBzdGFja1xuICAgICAgICAgICAgZWxzZSBpZiAobm9kZXNTdGF0ZVtkb3duc3RyZWFtTm9kZUluZGV4XSA9PT0gJ3doaXRlJykge1xuICAgICAgICAgICAgICBub2Rlc1N0YWNrLnB1c2goZG93bnN0cmVhbU5vZGVJbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdHJhbnNmb3JtR3JhcGgoZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKTogdm9pZCB7XG4gICAgLy8gYXBwbHkgY29tbW9uIHRyYW5zZm9ybVxuICAgIHRoaXMucmVtb3ZlQWxsSWRlbnRpdHlOb2RlcygpO1xuICAgIHRoaXMucmVtb3ZlQWxsRHJvcG91dE5vZGVzKCk7XG4gICAgdGhpcy5mdXNlQ29udkFjdGl2YXRpb25Ob2RlcygpO1xuICAgIC8vIGFwcGx5IGluaXRpYWxpemVyIHNwZWNpZmljIHRyYW5zZm9ybVxuICAgIGlmIChncmFwaEluaXRpYWxpemVyKSB7XG4gICAgICBncmFwaEluaXRpYWxpemVyLnRyYW5zZm9ybUdyYXBoKHRoaXMpO1xuICAgIH1cblxuICAgIC8vIGZpbmFsaXplIGdyYXBoXG4gICAgdGhpcy5maW5hbGl6ZUdyYXBoKCk7XG4gIH1cblxuICAvKipcbiAgICogZmluYWxpemUgdGhlIGdyYXBoLlxuICAgKlxuICAgKiB0aGlzIGZ1bmN0aW9uIHNob3VsZCBiZSBjYWxsZWQgYWZ0ZXIgYWxsIHRoZSB0cmFuc2Zvcm1hdGlvbiBjb21wbGV0ZWQuXG4gICAqIHRoaXMgZnVuY3Rpb24gcmVtb3ZlcyBhbGwgdW5uZWNlc3Nhcnkgbm9kZXMgYW5kIHZhbHVlcyBmcm9tIHRoZSBncmFwaFxuICAgKi9cbiAgZmluYWxpemVHcmFwaCgpIHtcbiAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICAvLyBkZWxldGUgYWxsIG5vZGVzIHRoYXQgYXJlIG5vdCBiZWluZyBleGVjdXRlZFxuICAgIC8vIFRoZSBncmFwaCBpcyByZXByZXNlbnRlZCB1c2luZyB0aGVzZSB0d28gYXJyYXlzXG4gICAgLy8gdGhpcy5fbm9kZXMgLSBBcnJheSBob2xkaW5nIHRoZSBrZXJuZWxzIHRvIGV4ZWN1dGUgLSBlYWNoIGVudHJ5IGlzIGEga2VybmVsIHBvaW50aW5nIHRvIHRoaXMuX2FsbERhdGFcbiAgICAvLyB0aGlzLl9hbGxEYXRhIC0gaG9sZCAyIGZpZWxkcyAtIHRvIFtdICYgZnJvbSAtIHRoZXNlIGZlaWxlZHMgaG9sZCB0aGUgZ3JhcGggbWFwIGZvciBpbnB1dHMgYW5kIG91dHB1dHMgcGVyIG5vZGVcbiAgICAvLyBuZXdJbmRpY2VzIC0gcmVtYXBwaW5nIHRoZSBncmFwaCBhZnRlciByZWFkaW5nIHRoZSBmbGFnICdleGVjdXRlTm9kZSdcbiAgICBjb25zdCBuZXdJbmRpY2VzID0gbmV3IEFycmF5PG51bWJlcj4odGhpcy5fbm9kZXMubGVuZ3RoLCAwKTtcbiAgICBsZXQgbm9kZVBvc3NpdGlvbiA9IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvLyBnaXZpbmcgbmV3IGluZGV4ZXMgdG8gdGhlIG5vZGVzIGJhc2VkIG9uIGV4ZWN1dGlvbiBmbGFnXG4gICAgICBuZXdJbmRpY2VzW2ldID0gbm9kZVBvc3NpdGlvbjtcbiAgICAgIGlmICh0aGlzLl9ub2Rlc1tpXS5leGVjdXRlTm9kZSkge1xuICAgICAgICBpZiAobm9kZVBvc3NpdGlvbiAhPT0gaSkge1xuICAgICAgICAgIHRoaXMuX25vZGVzW25vZGVQb3NzaXRpb25dID0gdGhpcy5fbm9kZXNbaV07XG4gICAgICAgIH1cbiAgICAgICAgbm9kZVBvc3NpdGlvbisrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZGVsZXRlIGFsbCBvdXRwdXQgdmFsdWVzXG4gICAgICAgIHRoaXMuX25vZGVzW2ldLm91dHB1dHMuZm9yRWFjaCgoaW5kKSA9PiB7XG4gICAgICAgICAgdGhpcy5fYWxsRGF0YVtpbmRdLl9mcm9tID0gLTI7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHJlbW92aW5nIHRoZSB1bnVzZWQgbm9kZXNcbiAgICB0aGlzLl9ub2Rlcy5zcGxpY2Uobm9kZVBvc3NpdGlvbiwgdGhpcy5fbm9kZXMubGVuZ3RoIC0gbm9kZVBvc3NpdGlvbik7XG5cbiAgICAvLyBVcGRhdGluZyB0aGlzLl9hbGxEYXRhIGFjY29yZGluZyB0byB0aGUgbmV3IHRoaXMuX25vZGVzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hbGxEYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBjdXJyZW50RGF0YSA9IHRoaXMuX2FsbERhdGFbaV07XG4gICAgICBpZiAoY3VycmVudERhdGEuX2Zyb20gIT09IHVuZGVmaW5lZCAmJiBjdXJyZW50RGF0YS5fZnJvbSAhPT0gLTEgJiYgY3VycmVudERhdGEuX2Zyb20gIT09IC0yKSB7XG4gICAgICAgIGN1cnJlbnREYXRhLl9mcm9tID0gbmV3SW5kaWNlc1tjdXJyZW50RGF0YS5fZnJvbV07XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgY3VycmVudERhdGEuX3RvLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChjdXJyZW50RGF0YS5fdG9bal0gPj0gMCkge1xuICAgICAgICAgIGN1cnJlbnREYXRhLl90b1tqXSA9IG5ld0luZGljZXNbY3VycmVudERhdGEuX3RvW2pdXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyeWluZyB0byB1cGRhdGUgYSByZW1vdmVkIG5vZGUnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIG9mZnNldCA9IDA7XG4gICAgLy8gZGVsZXRlIGFsbCB2YWx1ZXMgdGhhdCBhcmUgbm90IGJlaW5nIHJlZmVyZW5jZWRcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2FsbERhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIC8vIGlmIGN1cnJlbnQgdmFsdWUgaXMgbmVpdGhlciBsaW5rZWQgdG8gbmV4dCBub2RlLCBub3IgYW4gb3V0cHV0IHZhbHVlLCByZW1vdmUgaXQuXG4gICAgICBpZiAodGhpcy5fYWxsRGF0YVtpXS5mcm9tID09PSAtMiAmJiB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzLmluZGV4T2YoaSArIG9mZnNldCkgPT09IC0xKSB7XG4gICAgICAgIG9mZnNldCsrO1xuICAgICAgICB0aGlzLl9hbGxEYXRhLnNwbGljZShpLCAxKTtcbiAgICAgICAgaS0tO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChvZmZzZXQgPiAwKSB7XG4gICAgICAgIGxldCBpbmQgPSAtMTtcbiAgICAgICAgLy8gaWYgY3VycmVudCB2YWx1ZSBpcyBuZWl0aGVyIGFuIGlucHV0IHZhbHVlIG5vciBhbiBpbml0aWFsaXplciwgZmluZCB0aGUgbm9kZSBpdCdzXG4gICAgICAgIC8vIGNvbWluZyBmcm9tIGFuZCB1cGRhdGUgdGhlIGNvcnJlc3BvbmRpbmcgbm9kZSBvdXRwdXRcbiAgICAgICAgaWYgKHRoaXMuX2FsbERhdGFbaV0uZnJvbSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuX2FsbERhdGFbaV0uZnJvbSAhPT0gLTEpIHtcbiAgICAgICAgICBpbmQgPSB0aGlzLl9ub2Rlc1t0aGlzLl9hbGxEYXRhW2ldLmZyb21dLm91dHB1dHMuaW5kZXhPZihpICsgb2Zmc2V0KTtcbiAgICAgICAgICBpZiAoaW5kICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fbm9kZXNbdGhpcy5fYWxsRGF0YVtpXS5mcm9tXS5vdXRwdXRzW2luZF0gPSBpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBpZiBjdXJyZW50IHZhbHVlIGlzIGFuIGlucHV0IHZhbHVlLCB1cGRhdGUgaXRzIHJlZmVyZW5jZSBpbiBpbnB1dEluZGljZXNcbiAgICAgICAgICBpbmQgPSB0aGlzLl9hbGxJbnB1dEluZGljZXMuaW5kZXhPZihpICsgb2Zmc2V0KTtcbiAgICAgICAgICBpZiAoaW5kICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzW2luZF0gPSBpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZpbmQgdGhlIG5vZGUgdGhhdCB0aGUgY3VycmVudCB2YWx1ZSBpcyBsaW5raW5nIHRvIGFuZCB1cGRhdGUgaXRzIGlucHV0IHJlZmVyZW5jZVxuICAgICAgICB0aGlzLl9hbGxEYXRhW2ldLnRvLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICAgICAgICBpbmQgPSB0aGlzLl9ub2Rlc1tub2RlXS5pbnB1dHMuaW5kZXhPZihpICsgb2Zmc2V0KTtcbiAgICAgICAgICBpZiAoaW5kICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fbm9kZXNbbm9kZV0uaW5wdXRzW2luZF0gPSBpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2ldLnRvLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIC8vIGlmIGN1cnJlbnQgdmFsdWUgaXMgYSBncmFwaCBvdXRwdXQsIHVwZGF0ZSBpdHMgcmVmZXJlbmNlIGluIG91dHB1dEluZGljZXNcbiAgICAgICAgICBpbmQgPSB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzLmluZGV4T2YoaSArIG9mZnNldCk7XG4gICAgICAgICAgaWYgKGluZCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXNbaW5kXSA9IGk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSB0aGUgc3BlY2lmaWVkIG5vZGUuIEFzc3VtZSB0aGUgbm9kZSBoYXMgb25lIGluY29taW5nIGlucHV0IGFuZCB0aGUgZmlyc3Qgb3V0cHV0IGNvbm5lY3RlZCB0byBvdGhlciBub2Rlcy5cbiAgICogQW4gaW5wdXQgdmFsaWRhdGlvbiBtdXN0IGJlIGRvbmUgYmVmb3JlIGNhbGxpbmcgdGhpcyBmdW5jdGlvbi5cbiAgICogQHBhcmFtIG5vZGVJbmRleCBUaGUgaW5kZXggb2Ygbm9kZSB0byBiZSBkZWxldGVkXG4gICAqL1xuICBwcml2YXRlIGRlbGV0ZU5vZGUobm9kZUluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBub2RlID0gdGhpcy5fbm9kZXNbbm9kZUluZGV4XTtcbiAgICBpZiAobm9kZS5vdXRwdXRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgbm9kZS5vdXRwdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW25vZGUub3V0cHV0c1tpXV0udG8ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm9kZSBkZWxldGlvbiB3aXRoIG1vcmUgdGhhbiBvbmUgb3V0cHV0IGNvbm5lY3RlZCB0byBvdGhlciBub2RlcyBpcyBub3Qgc3VwcG9ydGVkLiAnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHRoaXMgbm9kZSB3aWwgbm90IGJlIGV4ZWN1dGVkXG4gICAgbm9kZS5leGVjdXRlTm9kZSA9IGZhbHNlO1xuICAgIGNvbnN0IGlucHV0VmFsdWVJbmRleCA9IG5vZGUuaW5wdXRzWzBdO1xuICAgIGNvbnN0IG91dHB1dFZhbHVlSW5kZXggPSBub2RlLm91dHB1dHNbMF07XG4gICAgY29uc3Qgbm9kZXNDb25zdW1pbmdPdXRwdXQgPSB0aGlzLl9hbGxEYXRhW291dHB1dFZhbHVlSW5kZXhdLnRvO1xuXG4gICAgLy8gcmVtb3ZlIHRoaXMgbm9kZSBmcm9tIHRoZSB0byBwcm9wZXJ0eSBvZiB0aGUgaW5wdXQgVmFsdWVcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGUuaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBkZWxJbmRleCA9IHRoaXMuX2FsbERhdGFbbm9kZS5pbnB1dHNbaV1dLnRvLmluZGV4T2Yobm9kZUluZGV4KTtcbiAgICAgIC8vIHNob3VsZCBub3QgaGFwcGVuXG4gICAgICBpZiAoZGVsSW5kZXggPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBWYWx1ZSBvYmplY3QgZG9lc24ndCBoYXZlIHRoZSBjdXJyZW50IE5vZGUgaW4gaXQncyAndG8nIHByb3BlcnR5IFwiKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2FsbERhdGFbbm9kZS5pbnB1dHNbaV1dLnRvLnNwbGljZShkZWxJbmRleCwgMSk7XG4gICAgfVxuXG4gICAgLy8gY2xlYXIgbm9kZSBpbmRpY2VzIGNvbnN1bWluZyB0aGlzIG91dHB1dCBWYWx1ZVxuICAgIHRoaXMuX2FsbERhdGFbb3V0cHV0VmFsdWVJbmRleF0uX3RvID0gW107XG5cbiAgICAvLyBpZiB0aGUgb3V0cHV0IG9mIHRoaXMgbm9kZSBpcyBhIGdyYXBoIG91dHB1dCwgYWRqdXN0IHRoZSBpbmRleCBhcHByb3ByaWF0ZWx5XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzLmluZGV4T2Yob3V0cHV0VmFsdWVJbmRleCk7XG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgdGhpcy5fYWxsT3V0cHV0SW5kaWNlc1tpbmRleF0gPSBpbnB1dFZhbHVlSW5kZXg7XG4gICAgfVxuXG4gICAgLy8gb3ZlcnJpZGUgdGhlIGlucHV0cyBmb3Igbm9kZXMgY29uc3VtaW5nIHRoaXMgbm9kZSdzIG91dHB1dCB3aXRoIHRoZSBpbnB1dCB0byB0aGlzIG5vZGVcbiAgICBpZiAobm9kZXNDb25zdW1pbmdPdXRwdXQgJiYgbm9kZXNDb25zdW1pbmdPdXRwdXQubGVuZ3RoID4gMCkge1xuICAgICAgZm9yIChjb25zdCBub2RlSW5kZXggb2Ygbm9kZXNDb25zdW1pbmdPdXRwdXQpIHtcbiAgICAgICAgY29uc3QgcmVwbGFjZUluZGV4ID0gdGhpcy5fbm9kZXNbbm9kZUluZGV4XS5pbnB1dHMuaW5kZXhPZihvdXRwdXRWYWx1ZUluZGV4KTtcbiAgICAgICAgLy8gc2hvdWxkIG5vdCBoYXBwZW5cbiAgICAgICAgaWYgKHJlcGxhY2VJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgTm9kZSBvYmplY3QgZG9lc24ndCBoYXZlIHRoZSBvdXRwdXQgVmFsdWUgaW4gaXQncyAnaW5wdXRzJyBwcm9wZXJ0eSBcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbm9kZXNbbm9kZUluZGV4XS5pbnB1dHNbcmVwbGFjZUluZGV4XSA9IGlucHV0VmFsdWVJbmRleDtcbiAgICAgICAgdGhpcy5fYWxsRGF0YVtpbnB1dFZhbHVlSW5kZXhdLnRvLnB1c2gobm9kZUluZGV4KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZW1vdmVBbGxEcm9wb3V0Tm9kZXMoKSB7XG4gICAgbGV0IG5vZGVJbmRleCA9IDA7XG4gICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMuX25vZGVzKSB7XG4gICAgICAvLyB3ZWVkIG91dCAnRHJvcG91dCcgbm9kZXMgc28gdGhhdCBubyB0aW1lIGlzIHdhc3RlZCBpbiBleGVjdXRpb25cbiAgICAgIGlmIChub2RlLm9wVHlwZSA9PT0gJ0Ryb3BvdXQnKSB7XG4gICAgICAgIC8vIHRoZSBub2RlIHNob3VsZCBoYXZlIGV4YWN0bHkgMSBpbnB1dCBhbmQgMSBvciAyIG91dHB1dHNcbiAgICAgICAgaWYgKG5vZGUuaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRHJvcG91dCBub2RlcyBzaG91bGQgb25seSBjb250YWluIG9uZSBpbnB1dC4gJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5vZGUub3V0cHV0cy5sZW5ndGggIT09IDEgJiYgbm9kZS5vdXRwdXRzLmxlbmd0aCAhPT0gMikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRHJvcG91dCBub2RlcyBzaG91bGQgY29udGFpbiBlaXRoZXIgMSBvciAyIG91dHB1dChzKScpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRoZSBzZWNvbmQgb3V0cHV0IHNob3VsZCBub3QgYmUgcmVmZXJlbmNlZCBieSBhbnkgb3RoZXIgbm9kZVxuICAgICAgICBpZiAobm9kZS5vdXRwdXRzLmxlbmd0aCA9PT0gMiAmJiB0aGlzLl9hbGxEYXRhW25vZGUub3V0cHV0c1sxXV0uX3RvLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkRyb3BvdXQgbm9kZXMncyBzZWNvbmQgb3V0cHV0IHNob3VsZCBub3QgYmUgcmVmZXJlbmNlZCBieSBvdGhlciBub2Rlc1wiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRlbGV0ZU5vZGUobm9kZUluZGV4KTtcbiAgICAgIH1cbiAgICAgIG5vZGVJbmRleCsrO1xuICAgIH1cbiAgfVxuXG4gIHJlbW92ZUFsbElkZW50aXR5Tm9kZXMoKSB7XG4gICAgbGV0IG5vZGVJbmRleCA9IDA7XG4gICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMuX25vZGVzKSB7XG4gICAgICAvLyB3ZWVkIG91dCAnSWRlbnRpdHknIG5vZGVzIHNvIHRoYXQgbm8gdGltZSBpcyB3YXN0ZWQgaW4gZXhlY3V0aW9uXG4gICAgICBpZiAobm9kZS5vcFR5cGUgPT09ICdJZGVudGl0eScpIHtcbiAgICAgICAgdGhpcy5kZWxldGVOb2RlKG5vZGVJbmRleCk7XG4gICAgICB9XG4gICAgICBub2RlSW5kZXgrKztcbiAgICB9XG4gIH1cblxuICBpc0FjdGl2YXRpb24objogTm9kZSk6IGJvb2xlYW4ge1xuICAgIHN3aXRjaCAobi5vcFR5cGUpIHtcbiAgICAgIC8vIFRPRE86IGFkZCBvdGhlciBhY3RpdmF0aW9uIG1ldGhvZHNcbiAgICAgIGNhc2UgJ1JlbHUnOlxuICAgICAgY2FzZSAnU2lnbW9pZCc6XG4gICAgICBjYXNlICdDbGlwJzpcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgZnVzZUNvbnZBY3RpdmF0aW9uTm9kZXMoKSB7XG4gICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMuX25vZGVzKSB7XG4gICAgICBpZiAobm9kZS5vcFR5cGUgPT09ICdDb252Jykge1xuICAgICAgICBjb25zdCBuZXh0ID0gdGhpcy5fYWxsRGF0YVtub2RlLm91dHB1dHNbMF1dLl90bztcbiAgICAgICAgaWYgKG5leHQubGVuZ3RoID09PSAxICYmIHRoaXMuaXNBY3RpdmF0aW9uKHRoaXMuX25vZGVzW25leHRbMF1dKSkge1xuICAgICAgICAgIGNvbnN0IGNoaWxkID0gdGhpcy5fbm9kZXNbbmV4dFswXV07XG4gICAgICAgICAgaWYgKGNoaWxkLm9wVHlwZSA9PT0gJ0NsaXAnKSB7XG4gICAgICAgICAgICBpZiAoY2hpbGQuaW5wdXRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5vZGUuYXR0cmlidXRlcy5zZXQoJ2FjdGl2YXRpb25fcGFyYW1zJywgJ2Zsb2F0cycsIFtcbiAgICAgICAgICAgICAgICAgIGNoaWxkLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ21pbicpLFxuICAgICAgICAgICAgICAgICAgY2hpbGQuYXR0cmlidXRlcy5nZXRGbG9hdCgnbWF4JyksXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBub2RlLmF0dHJpYnV0ZXMuc2V0KCdhY3RpdmF0aW9uX3BhcmFtcycsICdmbG9hdHMnLCBbTUlOX0NMSVAsIE1BWF9DTElQXSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgIGNoaWxkLmlucHV0cy5sZW5ndGggPj0gMyAmJlxuICAgICAgICAgICAgICB0aGlzLl9hbGxEYXRhW2NoaWxkLmlucHV0c1sxXV0udGVuc29yICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgdGhpcy5fYWxsRGF0YVtjaGlsZC5pbnB1dHNbMl1dLnRlbnNvciAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgbm9kZS5hdHRyaWJ1dGVzLnNldCgnYWN0aXZhdGlvbl9wYXJhbXMnLCAnZmxvYXRzJywgW1xuICAgICAgICAgICAgICAgIHRoaXMuX2FsbERhdGFbY2hpbGQuaW5wdXRzWzFdXS50ZW5zb3IhLmZsb2F0RGF0YVswXSxcbiAgICAgICAgICAgICAgICB0aGlzLl9hbGxEYXRhW2NoaWxkLmlucHV0c1syXV0udGVuc29yIS5mbG9hdERhdGFbMF0sXG4gICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gU2tpcCBmdXNpb24gd2l0aCBjbGlwIG5vZGUgc2luY2UgY2xpcCBtaW4gYW5kIGNsaXAgbWF4IGFyZSBub3QgY29taW5nIGZyb20gaW5pdGlhbGl6ZXJcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIG5vZGUuYXR0cmlidXRlcy5zZXQoJ2FjdGl2YXRpb24nLCAnc3RyaW5nJywgY2hpbGQub3BUeXBlKTtcbiAgICAgICAgICB0aGlzLmRlbGV0ZU5vZGUobmV4dFswXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BTZXQgfSBmcm9tICcuL29wc2V0JztcbmltcG9ydCAqIGFzIG9ydEZicyBmcm9tICcuL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQgeyBvbm54IH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHsgTG9uZ1V0aWwgfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgY2xhc3MgTW9kZWwge1xuICAvLyBlbXB0eSBtb2RlbFxuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgbG9hZChidWY6IFVpbnQ4QXJyYXksIGdyYXBoSW5pdGlhbGl6ZXI/OiBHcmFwaC5Jbml0aWFsaXplciwgaXNPcnRGb3JtYXQ/OiBib29sZWFuKTogdm9pZCB7XG4gICAgbGV0IG9ubnhFcnJvcjogRXJyb3IgfCB1bmRlZmluZWQ7XG4gICAgaWYgKCFpc09ydEZvcm1hdCkge1xuICAgICAgLy8gaXNPcnRGb3JtYXQgPT09IGZhbHNlIHx8IGlzT3J0Rm9ybWF0ID09PSB1bmRlZmluZWRcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMubG9hZEZyb21Pbm54Rm9ybWF0KGJ1ZiwgZ3JhcGhJbml0aWFsaXplcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGlzT3J0Rm9ybWF0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIG9ubnhFcnJvciA9IGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMubG9hZEZyb21PcnRGb3JtYXQoYnVmLCBncmFwaEluaXRpYWxpemVyKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoaXNPcnRGb3JtYXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgICAgLy8gVHJpZWQgYm90aCBmb3JtYXRzIGFuZCBmYWlsZWQgKHdoZW4gaXNPcnRGb3JtYXQgPT09IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGxvYWQgbW9kZWwgYXMgT05OWCBmb3JtYXQ6ICR7b25ueEVycm9yfVxcbmFzIE9SVCBmb3JtYXQ6ICR7ZX1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGxvYWRGcm9tT25ueEZvcm1hdChidWY6IFVpbnQ4QXJyYXksIGdyYXBoSW5pdGlhbGl6ZXI/OiBHcmFwaC5Jbml0aWFsaXplcik6IHZvaWQge1xuICAgIGNvbnN0IG1vZGVsUHJvdG8gPSBvbm54Lk1vZGVsUHJvdG8uZGVjb2RlKGJ1Zik7XG4gICAgY29uc3QgaXJWZXJzaW9uID0gTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKG1vZGVsUHJvdG8uaXJWZXJzaW9uKTtcbiAgICBpZiAoaXJWZXJzaW9uIDwgMykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdvbmx5IHN1cHBvcnQgT05OWCBtb2RlbCB3aXRoIElSX1ZFUlNJT04+PTMnKTtcbiAgICB9XG5cbiAgICB0aGlzLl9vcHNldHMgPSBtb2RlbFByb3RvLm9wc2V0SW1wb3J0Lm1hcCgoaSkgPT4gKHtcbiAgICAgIGRvbWFpbjogaS5kb21haW4gYXMgc3RyaW5nLFxuICAgICAgdmVyc2lvbjogTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKGkudmVyc2lvbiEpLFxuICAgIH0pKTtcblxuICAgIHRoaXMuX2dyYXBoID0gR3JhcGguZnJvbShtb2RlbFByb3RvLmdyYXBoISwgZ3JhcGhJbml0aWFsaXplcik7XG4gIH1cblxuICBwcml2YXRlIGxvYWRGcm9tT3J0Rm9ybWF0KGJ1ZjogVWludDhBcnJheSwgZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKTogdm9pZCB7XG4gICAgY29uc3QgZmIgPSBuZXcgZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcihidWYpO1xuICAgIGNvbnN0IG9ydE1vZGVsID0gb3J0RmJzLkluZmVyZW5jZVNlc3Npb24uZ2V0Um9vdEFzSW5mZXJlbmNlU2Vzc2lvbihmYikubW9kZWwoKSE7XG4gICAgY29uc3QgaXJWZXJzaW9uID0gTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKG9ydE1vZGVsLmlyVmVyc2lvbigpKTtcbiAgICBpZiAoaXJWZXJzaW9uIDwgMykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdvbmx5IHN1cHBvcnQgT05OWCBtb2RlbCB3aXRoIElSX1ZFUlNJT04+PTMnKTtcbiAgICB9XG4gICAgdGhpcy5fb3BzZXRzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcnRNb2RlbC5vcHNldEltcG9ydExlbmd0aCgpOyBpKyspIHtcbiAgICAgIGNvbnN0IG9wc2V0SWQgPSBvcnRNb2RlbC5vcHNldEltcG9ydChpKSE7XG4gICAgICB0aGlzLl9vcHNldHMucHVzaCh7IGRvbWFpbjogb3BzZXRJZD8uZG9tYWluKCkgYXMgc3RyaW5nLCB2ZXJzaW9uOiBMb25nVXRpbC5sb25nVG9OdW1iZXIob3BzZXRJZC52ZXJzaW9uKCkhKSB9KTtcbiAgICB9XG5cbiAgICB0aGlzLl9ncmFwaCA9IEdyYXBoLmZyb20ob3J0TW9kZWwuZ3JhcGgoKSEsIGdyYXBoSW5pdGlhbGl6ZXIpO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ3JhcGg6IEdyYXBoO1xuICBnZXQgZ3JhcGgoKTogR3JhcGgge1xuICAgIHJldHVybiB0aGlzLl9ncmFwaDtcbiAgfVxuXG4gIHByaXZhdGUgX29wc2V0czogT3BTZXRbXTtcbiAgZ2V0IG9wc2V0cygpOiByZWFkb25seSBPcFNldFtdIHtcbiAgICByZXR1cm4gdGhpcy5fb3BzZXRzO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IHJlc29sdmVCYWNrZW5kLCBTZXNzaW9uSGFuZGxlclR5cGUgfSBmcm9tICcuL2JhY2tlbmQnO1xuaW1wb3J0IHsgRXhlY3V0aW9uUGxhbiB9IGZyb20gJy4vZXhlY3V0aW9uLXBsYW4nO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7IFByb2ZpbGVyIH0gZnJvbSAnLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSAnLi9tb2RlbCc7XG5pbXBvcnQgeyBPcGVyYXRvciB9IGZyb20gJy4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yJztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIFNlc3Npb24ge1xuICBleHBvcnQgaW50ZXJmYWNlIENvbmZpZyB7XG4gICAgYmFja2VuZEhpbnQ/OiBzdHJpbmc7XG4gICAgcHJvZmlsZXI/OiBQcm9maWxlci5Db25maWc7XG4gIH1cblxuICBleHBvcnQgaW50ZXJmYWNlIENvbnRleHQge1xuICAgIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj47XG4gICAgZ3JhcGhJbnB1dFR5cGVzPzogVGVuc29yLkRhdGFUeXBlW107XG4gICAgZ3JhcGhJbnB1dERpbXM/OiBBcnJheTxyZWFkb25seSBudW1iZXJbXT47XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNlc3Npb24ge1xuICBjb25zdHJ1Y3Rvcihjb25maWc6IFNlc3Npb24uQ29uZmlnID0ge30pIHtcbiAgICB0aGlzLl9pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgIHRoaXMuYmFja2VuZEhpbnQgPSBjb25maWcuYmFja2VuZEhpbnQ7XG4gICAgdGhpcy5wcm9maWxlciA9IFByb2ZpbGVyLmNyZWF0ZShjb25maWcucHJvZmlsZXIpO1xuICAgIHRoaXMuY29udGV4dCA9IHsgcHJvZmlsZXI6IHRoaXMucHJvZmlsZXIsIGdyYXBoSW5wdXRUeXBlczogW10sIGdyYXBoSW5wdXREaW1zOiBbXSB9O1xuICB9XG5cbiAgZ2V0IGlucHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9tb2RlbC5ncmFwaC5nZXRJbnB1dE5hbWVzKCk7XG4gIH1cbiAgZ2V0IG91dHB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0T3V0cHV0TmFtZXMoKTtcbiAgfVxuXG4gIHN0YXJ0UHJvZmlsaW5nKCkge1xuICAgIHRoaXMucHJvZmlsZXIuc3RhcnQoKTtcbiAgfVxuXG4gIGVuZFByb2ZpbGluZygpIHtcbiAgICB0aGlzLnByb2ZpbGVyLnN0b3AoKTtcbiAgfVxuXG4gIGFzeW5jIGxvYWRNb2RlbCh1cmk6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gIGFzeW5jIGxvYWRNb2RlbChidWZmZXI6IEFycmF5QnVmZmVyLCBieXRlT2Zmc2V0PzogbnVtYmVyLCBsZW5ndGg/OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+O1xuICBhc3luYyBsb2FkTW9kZWwoYnVmZmVyOiBVaW50OEFycmF5KTogUHJvbWlzZTx2b2lkPjtcbiAgYXN5bmMgbG9hZE1vZGVsKGFyZzogc3RyaW5nIHwgQXJyYXlCdWZmZXIgfCBVaW50OEFycmF5LCBieXRlT2Zmc2V0PzogbnVtYmVyLCBsZW5ndGg/OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ1Nlc3Npb24ubG9hZE1vZGVsJywgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gcmVzb2x2ZSBiYWNrZW5kIGFuZCBzZXNzaW9uIGhhbmRsZXJcbiAgICAgIGNvbnN0IGJhY2tlbmQgPSBhd2FpdCByZXNvbHZlQmFja2VuZCh0aGlzLmJhY2tlbmRIaW50KTtcbiAgICAgIHRoaXMuc2Vzc2lvbkhhbmRsZXIgPSBiYWNrZW5kLmNyZWF0ZVNlc3Npb25IYW5kbGVyKHRoaXMuY29udGV4dCk7XG5cbiAgICAgIHRoaXMuX21vZGVsID0gbmV3IE1vZGVsKCk7XG4gICAgICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc3QgaXNPcnRGb3JtYXQgPSBhcmcuZW5kc1dpdGgoJy5vcnQnKTtcbiAgICAgICAgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb25zICYmIHByb2Nlc3MudmVyc2lvbnMubm9kZSkge1xuICAgICAgICAgIC8vIG5vZGVcbiAgICAgICAgICBjb25zdCB7IHJlYWRGaWxlIH0gPSByZXF1aXJlKCdub2RlOmZzL3Byb21pc2VzJyk7XG4gICAgICAgICAgY29uc3QgYnVmID0gYXdhaXQgcmVhZEZpbGUoYXJnKTtcbiAgICAgICAgICB0aGlzLmluaXRpYWxpemUoYnVmLCBpc09ydEZvcm1hdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gYnJvd3NlclxuICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYXJnKTtcbiAgICAgICAgICBjb25zdCBidWYgPSBhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpO1xuICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZShuZXcgVWludDhBcnJheShidWYpLCBpc09ydEZvcm1hdCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIUFycmF5QnVmZmVyLmlzVmlldyhhcmcpKSB7XG4gICAgICAgIC8vIGxvYWQgbW9kZWwgZnJvbSBBcnJheUJ1ZmZlclxuICAgICAgICBjb25zdCBhcnIgPSBuZXcgVWludDhBcnJheShhcmcsIGJ5dGVPZmZzZXQgfHwgMCwgbGVuZ3RoIHx8IGFyZy5ieXRlTGVuZ3RoKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplKGFycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBsb2FkIG1vZGVsIGZyb20gVWludDhhcnJheVxuICAgICAgICB0aGlzLmluaXRpYWxpemUoYXJnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZShtb2RlbFByb3RvQmxvYjogVWludDhBcnJheSwgaXNPcnRGb3JtYXQ/OiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FscmVhZHkgaW5pdGlhbGl6ZWQnKTtcbiAgICB9XG5cbiAgICB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ1Nlc3Npb24uaW5pdGlhbGl6ZScsICgpID0+IHtcbiAgICAgIC8vIGxvYWQgZ3JhcGhcbiAgICAgIGNvbnN0IGdyYXBoSW5pdGlhbGl6ZXIgPSB0aGlzLnNlc3Npb25IYW5kbGVyLnRyYW5zZm9ybUdyYXBoXG4gICAgICAgID8gKHRoaXMuc2Vzc2lvbkhhbmRsZXIgYXMgR3JhcGguSW5pdGlhbGl6ZXIpXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgdGhpcy5fbW9kZWwubG9hZChtb2RlbFByb3RvQmxvYiwgZ3JhcGhJbml0aWFsaXplciwgaXNPcnRGb3JtYXQpO1xuXG4gICAgICAvLyBncmFwaCBpcyBjb21wbGV0ZWx5IGluaXRpYWx6aWVkIGF0IHRoaXMgc3RhZ2UgLCBsZXQgdGhlIGludGVyZXN0ZWQgaGFuZGxlcnMga25vd1xuICAgICAgaWYgKHRoaXMuc2Vzc2lvbkhhbmRsZXIub25HcmFwaEluaXRpYWxpemVkKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbkhhbmRsZXIub25HcmFwaEluaXRpYWxpemVkKHRoaXMuX21vZGVsLmdyYXBoKTtcbiAgICAgIH1cbiAgICAgIC8vIGluaXRpYWxpemUgZWFjaCBvcGVyYXRvciBpbiB0aGUgZ3JhcGhcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZU9wcyh0aGlzLl9tb2RlbC5ncmFwaCk7XG5cbiAgICAgIC8vIGluc3RhbnRpYXRlIGFuIEV4ZWN1dGlvblBsYW4gb2JqZWN0IHRvIGJlIHVzZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0XG4gICAgICB0aGlzLl9leGVjdXRpb25QbGFuID0gbmV3IEV4ZWN1dGlvblBsYW4odGhpcy5fbW9kZWwuZ3JhcGgsIHRoaXMuX29wcywgdGhpcy5wcm9maWxlcik7XG4gICAgfSk7XG5cbiAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7XG4gIH1cblxuICBhc3luYyBydW4oaW5wdXRzOiBNYXA8c3RyaW5nLCBUZW5zb3I+IHwgVGVuc29yW10pOiBQcm9taXNlPE1hcDxzdHJpbmcsIFRlbnNvcj4+IHtcbiAgICBpZiAoIXRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Nlc3Npb24gbm90IGluaXRpYWxpemVkIHlldCcpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ1Nlc3Npb24ucnVuJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgaW5wdXRUZW5zb3JzID0gdGhpcy5ub3JtYWxpemVBbmRWYWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gICAgICBjb25zdCBvdXRwdXRUZW5zb3JzID0gYXdhaXQgdGhpcy5fZXhlY3V0aW9uUGxhbi5leGVjdXRlKHRoaXMuc2Vzc2lvbkhhbmRsZXIsIGlucHV0VGVuc29ycyk7XG5cbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZU91dHB1dChvdXRwdXRUZW5zb3JzKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbm9ybWFsaXplQW5kVmFsaWRhdGVJbnB1dHMoaW5wdXRzOiBNYXA8c3RyaW5nLCBUZW5zb3I+IHwgVGVuc29yW10pOiBUZW5zb3JbXSB7XG4gICAgY29uc3QgbW9kZWxJbnB1dE5hbWVzID0gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0SW5wdXROYW1lcygpO1xuXG4gICAgLy8gbm9ybWFsaXplIGlucHV0c1xuICAgIC8vIGlucHV0czogVGVuc29yW11cbiAgICBpZiAoQXJyYXkuaXNBcnJheShpbnB1dHMpKSB7XG4gICAgICBpZiAoaW5wdXRzLmxlbmd0aCAhPT0gbW9kZWxJbnB1dE5hbWVzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGluY29ycmVjdCBpbnB1dCBhcnJheSBsZW5ndGg6IGV4cGVjdGVkICR7bW9kZWxJbnB1dE5hbWVzLmxlbmd0aH0gYnV0IGdvdCAke2lucHV0cy5sZW5ndGh9YCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGNvbnZlcnQgbWFwIHRvIGFycmF5XG4gICAgLy8gaW5wdXRzOiBNYXA8c3RyaW5nLCBUZW5zb3I+XG4gICAgZWxzZSB7XG4gICAgICBpZiAoaW5wdXRzLnNpemUgIT09IG1vZGVsSW5wdXROYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbmNvcnJlY3QgaW5wdXQgbWFwIHNpemU6IGV4cGVjdGVkICR7bW9kZWxJbnB1dE5hbWVzLmxlbmd0aH0gYnV0IGdvdCAke2lucHV0cy5zaXplfWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzb3J0ZWRJbnB1dHMgPSBuZXcgQXJyYXk8VGVuc29yPihpbnB1dHMuc2l6ZSk7XG4gICAgICBsZXQgc29ydGVkSW5wdXRzSW5kZXggPSAwO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtb2RlbElucHV0TmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgY29uc3QgdGVuc29yID0gaW5wdXRzLmdldChtb2RlbElucHV0TmFtZXNbaV0pO1xuICAgICAgICBpZiAoIXRlbnNvcikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBpbnB1dCB0ZW5zb3IgZm9yOiAnJHtuYW1lfSdgKTtcbiAgICAgICAgfVxuICAgICAgICBzb3J0ZWRJbnB1dHNbc29ydGVkSW5wdXRzSW5kZXgrK10gPSB0ZW5zb3I7XG4gICAgICB9XG5cbiAgICAgIGlucHV0cyA9IHNvcnRlZElucHV0cztcbiAgICB9XG5cbiAgICAvLyB2YWxpZGF0ZSBkaW1zIHJlcXVpcmVtZW50c1xuICAgIC8vIEZpcnN0IHNlc3Npb24gcnVuIC0gZ3JhcGggaW5wdXQgZGF0YSBpcyBub3QgY2FjaGVkIGZvciB0aGUgc2Vzc2lvblxuICAgIGlmIChcbiAgICAgICF0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dFR5cGVzIHx8XG4gICAgICB0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dFR5cGVzLmxlbmd0aCA9PT0gMCB8fFxuICAgICAgIXRoaXMuY29udGV4dC5ncmFwaElucHV0RGltcyB8fFxuICAgICAgdGhpcy5jb250ZXh0LmdyYXBoSW5wdXREaW1zLmxlbmd0aCA9PT0gMFxuICAgICkge1xuICAgICAgY29uc3QgbW9kZWxJbnB1dEluZGljZXMgPSB0aGlzLl9tb2RlbC5ncmFwaC5nZXRJbnB1dEluZGljZXMoKTtcbiAgICAgIGNvbnN0IG1vZGVsVmFsdWVzID0gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0VmFsdWVzKCk7XG5cbiAgICAgIGNvbnN0IGdyYXBoSW5wdXREaW1zID0gbmV3IEFycmF5PHJlYWRvbmx5IG51bWJlcltdPihtb2RlbElucHV0SW5kaWNlcy5sZW5ndGgpO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1vZGVsSW5wdXRJbmRpY2VzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGNvbnN0IGdyYXBoSW5wdXQgPSBtb2RlbFZhbHVlc1ttb2RlbElucHV0SW5kaWNlc1tpXV07XG4gICAgICAgIGdyYXBoSW5wdXREaW1zW2ldID0gZ3JhcGhJbnB1dC50eXBlIS5zaGFwZS5kaW1zO1xuXG4gICAgICAgIC8vIGNhY2hlZCBmb3Igc2Vjb25kIGFuZCBzdWJzZXF1ZW50IHJ1bnMuXG4gICAgICAgIC8vIFNvbWUgcGFydHMgb2YgdGhlIGZyYW1ld29yayB3b3JrcyBvbiB0aGUgYXNzdW1wdGlvbiB0aGF0IHRoZSBncmFwaCBhbmQgdHlwZXMgYW5kIHNoYXBlcyBhcmUgc3RhdGljXG4gICAgICAgIHRoaXMuY29udGV4dC5ncmFwaElucHV0VHlwZXMhLnB1c2goZ3JhcGhJbnB1dC50eXBlIS50ZW5zb3JUeXBlKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LmdyYXBoSW5wdXREaW1zIS5wdXNoKGlucHV0c1tpXS5kaW1zKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy52YWxpZGF0ZUlucHV0VGVuc29yRGltcyhncmFwaElucHV0RGltcywgaW5wdXRzLCB0cnVlKTtcbiAgICB9XG5cbiAgICAvLyBTZWNvbmQgYW5kIHN1YnNlcXVlbnQgc2Vzc2lvbiBydW5zIC0gZ3JhcGggaW5wdXQgZGF0YSBpcyBjYWNoZWQgZm9yIHRoZSBzZXNzaW9uXG4gICAgZWxzZSB7XG4gICAgICB0aGlzLnZhbGlkYXRlSW5wdXRUZW5zb3JEaW1zKHRoaXMuY29udGV4dC5ncmFwaElucHV0RGltcywgaW5wdXRzLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgLy8gdmFsaWRhdGUgdHlwZXMgcmVxdWlyZW1lbnRcbiAgICB0aGlzLnZhbGlkYXRlSW5wdXRUZW5zb3JUeXBlcyh0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dFR5cGVzISwgaW5wdXRzKTtcblxuICAgIHJldHVybiBpbnB1dHM7XG4gIH1cblxuICBwcml2YXRlIHZhbGlkYXRlSW5wdXRUZW5zb3JUeXBlcyhncmFwaElucHV0VHlwZXM6IFRlbnNvci5EYXRhVHlwZVtdLCBnaXZlbklucHV0czogVGVuc29yW10pIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdpdmVuSW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSBncmFwaElucHV0VHlwZXNbaV07XG4gICAgICBjb25zdCBhY3R1YWxUeXBlID0gZ2l2ZW5JbnB1dHNbaV0udHlwZTtcbiAgICAgIGlmIChleHBlY3RlZFR5cGUgIT09IGFjdHVhbFR5cGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dCB0ZW5zb3JbJHtpfV0gY2hlY2sgZmFpbGVkOiBleHBlY3RlZCB0eXBlICcke2V4cGVjdGVkVHlwZX0nIGJ1dCBnb3QgJHthY3R1YWxUeXBlfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVJbnB1dFRlbnNvckRpbXMoXG4gICAgZ3JhcGhJbnB1dERpbXM6IEFycmF5PHJlYWRvbmx5IG51bWJlcltdPixcbiAgICBnaXZlbklucHV0czogVGVuc29yW10sXG4gICAgbm9uZURpbVN1cHBvcnRlZDogYm9vbGVhbixcbiAgKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBnaXZlbklucHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZXhwZWN0ZWREaW1zID0gZ3JhcGhJbnB1dERpbXNbaV07XG4gICAgICBjb25zdCBhY3R1YWxEaW1zID0gZ2l2ZW5JbnB1dHNbaV0uZGltcztcbiAgICAgIGlmICghdGhpcy5jb21wYXJlVGVuc29yRGltcyhleHBlY3RlZERpbXMsIGFjdHVhbERpbXMsIG5vbmVEaW1TdXBwb3J0ZWQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgaW5wdXQgdGVuc29yWyR7aX1dIGNoZWNrIGZhaWxlZDogZXhwZWN0ZWQgc2hhcGUgJ1ske2V4cGVjdGVkRGltcy5qb2luKCcsJyl9XScgYnV0IGdvdCBbJHthY3R1YWxEaW1zLmpvaW4oXG4gICAgICAgICAgICAnLCcsXG4gICAgICAgICAgKX1dYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNvbXBhcmVUZW5zb3JEaW1zKFxuICAgIGV4cGVjdGVkRGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgYWN0dWFsRGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgbm9uZURpbVN1cHBvcnRlZDogYm9vbGVhbixcbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKGV4cGVjdGVkRGltcy5sZW5ndGggIT09IGFjdHVhbERpbXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBleHBlY3RlZERpbXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmIChleHBlY3RlZERpbXNbaV0gIT09IGFjdHVhbERpbXNbaV0gJiYgKCFub25lRGltU3VwcG9ydGVkIHx8IGV4cGVjdGVkRGltc1tpXSAhPT0gMCkpIHtcbiAgICAgICAgLy8gZGF0YSBzaGFwZSBtaXMtbWF0Y2ggQU5EIG5vdCBhICdOb25lJyBkaW1lbnNpb24uXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlT3V0cHV0KG91dHB1dFRlbnNvcnM6IFRlbnNvcltdKTogTWFwPHN0cmluZywgVGVuc29yPiB7XG4gICAgY29uc3QgbW9kZWxPdXRwdXROYW1lcyA9IHRoaXMuX21vZGVsLmdyYXBoLmdldE91dHB1dE5hbWVzKCk7XG4gICAgaWYgKG91dHB1dFRlbnNvcnMubGVuZ3RoICE9PSBtb2RlbE91dHB1dE5hbWVzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdleHBlY3RlZCBudW1iZXIgb2Ygb3V0cHV0cyBkbyBub3QgbWF0Y2ggbnVtYmVyIG9mIGdlbmVyYXRlZCBvdXRwdXRzJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3V0cHV0ID0gbmV3IE1hcDxzdHJpbmcsIFRlbnNvcj4oKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1vZGVsT3V0cHV0TmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIG91dHB1dC5zZXQobW9kZWxPdXRwdXROYW1lc1tpXSwgb3V0cHV0VGVuc29yc1tpXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZU9wcyhncmFwaDogR3JhcGgpOiB2b2lkIHtcbiAgICBjb25zdCBub2RlcyA9IGdyYXBoLmdldE5vZGVzKCk7XG4gICAgdGhpcy5fb3BzID0gbmV3IEFycmF5KG5vZGVzLmxlbmd0aCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLl9vcHNbaV0gPSB0aGlzLnNlc3Npb25IYW5kbGVyLnJlc29sdmUobm9kZXNbaV0sIHRoaXMuX21vZGVsLm9wc2V0cywgZ3JhcGgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX21vZGVsOiBNb2RlbDtcbiAgcHJpdmF0ZSBfaW5pdGlhbGl6ZWQ6IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSBfb3BzOiBPcGVyYXRvcltdO1xuICBwcml2YXRlIF9leGVjdXRpb25QbGFuOiBFeGVjdXRpb25QbGFuO1xuXG4gIHByaXZhdGUgYmFja2VuZEhpbnQ/OiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBzZXNzaW9uSGFuZGxlcjogU2Vzc2lvbkhhbmRsZXJUeXBlO1xuICBwcml2YXRlIGNvbnRleHQ6IFNlc3Npb24uQ29udGV4dDtcbiAgcHJpdmF0ZSBwcm9maWxlcjogUmVhZG9ubHk8UHJvZmlsZXI+O1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBJbmZlcmVuY2VTZXNzaW9uLCBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciwgU2Vzc2lvbkhhbmRsZXIsIFRlbnNvciB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL3Nlc3Npb24nO1xuaW1wb3J0IHsgVGVuc29yIGFzIE9ubnhqc1RlbnNvciB9IGZyb20gJy4vdGVuc29yJztcblxuZXhwb3J0IGNsYXNzIE9ubnhqc1Nlc3Npb25IYW5kbGVyIGltcGxlbWVudHMgSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHNlc3Npb246IFNlc3Npb24pIHtcbiAgICB0aGlzLmlucHV0TmFtZXMgPSB0aGlzLnNlc3Npb24uaW5wdXROYW1lcztcbiAgICB0aGlzLm91dHB1dE5hbWVzID0gdGhpcy5zZXNzaW9uLm91dHB1dE5hbWVzO1xuICB9XG5cbiAgZ2V0IGlucHV0TWV0YWRhdGEoKTogcmVhZG9ubHkgSW5mZXJlbmNlU2Vzc2lvbi5WYWx1ZU1ldGFkYXRhW10ge1xuICAgIHRocm93IG5ldyBFcnJvcignR2V0dGluZyBtb2RlbCBtZXRhZGF0YSBpcyBub3Qgc3VwcG9ydGVkIGluIHdlYmdsIGJhY2tlbmQuJyk7XG4gIH1cblxuICBnZXQgb3V0cHV0TWV0YWRhdGEoKTogcmVhZG9ubHkgSW5mZXJlbmNlU2Vzc2lvbi5WYWx1ZU1ldGFkYXRhW10ge1xuICAgIHRocm93IG5ldyBFcnJvcignR2V0dGluZyBtb2RlbCBtZXRhZGF0YSBpcyBub3Qgc3VwcG9ydGVkIGluIHdlYmdsIGJhY2tlbmQuJyk7XG4gIH1cblxuICBhc3luYyBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD4ge31cbiAgaW5wdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG4gIG91dHB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcbiAgYXN5bmMgcnVuKFxuICAgIGZlZWRzOiBTZXNzaW9uSGFuZGxlci5GZWVkc1R5cGUsXG4gICAgX2ZldGNoZXM6IFNlc3Npb25IYW5kbGVyLkZldGNoZXNUeXBlLFxuICAgIF9vcHRpb25zOiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMsXG4gICk6IFByb21pc2U8U2Vzc2lvbkhhbmRsZXIuUmV0dXJuVHlwZT4ge1xuICAgIGNvbnN0IGlucHV0TWFwID0gbmV3IE1hcDxzdHJpbmcsIE9ubnhqc1RlbnNvcj4oKTtcbiAgICBmb3IgKGNvbnN0IG5hbWUgaW4gZmVlZHMpIHtcbiAgICAgIGlmIChPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChmZWVkcywgbmFtZSkpIHtcbiAgICAgICAgY29uc3QgZmVlZCA9IGZlZWRzW25hbWVdO1xuICAgICAgICBpbnB1dE1hcC5zZXQoXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICBuZXcgT25ueGpzVGVuc29yKFxuICAgICAgICAgICAgZmVlZC5kaW1zLFxuICAgICAgICAgICAgZmVlZC50eXBlIGFzIE9ubnhqc1RlbnNvci5EYXRhVHlwZSxcbiAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGZlZWQuZGF0YSBhcyBPbm54anNUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBvdXRwdXRNYXAgPSBhd2FpdCB0aGlzLnNlc3Npb24ucnVuKGlucHV0TWFwKTtcbiAgICBjb25zdCBvdXRwdXQ6IFNlc3Npb25IYW5kbGVyLlJldHVyblR5cGUgPSB7fTtcbiAgICBvdXRwdXRNYXAuZm9yRWFjaCgodGVuc29yLCBuYW1lKSA9PiB7XG4gICAgICBvdXRwdXRbbmFtZV0gPSBuZXcgVGVuc29yKHRlbnNvci50eXBlLCB0ZW5zb3IuZGF0YSwgdGVuc29yLmRpbXMpO1xuICAgIH0pO1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbiAgc3RhcnRQcm9maWxpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5zZXNzaW9uLnN0YXJ0UHJvZmlsaW5nKCk7XG4gIH1cbiAgZW5kUHJvZmlsaW5nKCk6IHZvaWQge1xuICAgIHRoaXMuc2Vzc2lvbi5lbmRQcm9maWxpbmcoKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvbm8taW50ZXJuYWwtbW9kdWxlcyAqL1xuaW1wb3J0IHsgQmFja2VuZCwgSW5mZXJlbmNlU2Vzc2lvbiwgSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9vbm54anMvc2Vzc2lvbic7XG5pbXBvcnQgeyBPbm54anNTZXNzaW9uSGFuZGxlciB9IGZyb20gJy4vb25ueGpzL3Nlc3Npb24taGFuZGxlci1pbmZlcmVuY2UnO1xuXG5jbGFzcyBPbm54anNCYWNrZW5kIGltcGxlbWVudHMgQmFja2VuZCB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktZnVuY3Rpb25cbiAgYXN5bmMgaW5pdCgpOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgYXN5bmMgY3JlYXRlSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIoXG4gICAgcGF0aE9yQnVmZmVyOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25IYW5kbGVyPiB7XG4gICAgLy8gTk9URTogU2Vzc2lvbi5Db25maWcoZnJvbSBvbm54LmpzKSBpcyBub3QgY29tcGF0aWJsZSB3aXRoIEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMoZnJvbVxuICAgIC8vIG9ubnhydW50aW1lLWNvbW1vbikuXG4gICAgLy8gICAgICAgSW4gZnV0dXJlIHdlIHNob3VsZCByZW1vdmUgU2Vzc2lvbi5Db25maWcgYW5kIHVzZSBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLlxuICAgIC8vICAgICAgIEN1cnJlbnRseSB3ZSBhbGxvdyB0aGlzIHRvIGhhcHBlbiB0byBtYWtlIHRlc3QgcnVubmVyIHdvcmsuXG4gICAgY29uc3Qgc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKG9wdGlvbnMgYXMgdW5rbm93biBhcyBTZXNzaW9uLkNvbmZpZyk7XG5cbiAgICAvLyB0eXBlc2NyaXB0IGNhbm5vdCBtZXJnZSBtZXRob2Qgb3ZlcnJpZGUgY29ycmVjdGx5IChzbyBmYXIgaW4gNC4yLjMpLiBuZWVkIGlmLWVsc2UgdG8gY2FsbCB0aGUgbWV0aG9kLlxuICAgIGlmICh0eXBlb2YgcGF0aE9yQnVmZmVyID09PSAnc3RyaW5nJykge1xuICAgICAgYXdhaXQgc2Vzc2lvbi5sb2FkTW9kZWwocGF0aE9yQnVmZmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgc2Vzc2lvbi5sb2FkTW9kZWwocGF0aE9yQnVmZmVyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE9ubnhqc1Nlc3Npb25IYW5kbGVyKHNlc3Npb24pO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBvbm54anNCYWNrZW5kID0gbmV3IE9ubnhqc0JhY2tlbmQoKTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlcywgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cyAqL1xuXG4vLyBXZSB1c2UgXCJyZXF1aXJlXCIgaW5zdGVhZCBvZiBcImltcG9ydFwiIGhlcmUgYmVjYXVzZSBpbXBvcnQgc3RhdGVtZW50IG11c3QgYmUgcHV0IGluIHRvcCBsZXZlbC4gT3VyIGN1cnJlbnQgY29kZSBkb2VzXG4vLyBub3QgYWxsb3cgYnVuZGxlciB0byB0cmVlLXNoYWtpbmcgY29kZSBhcyBleHBlY3RlZCBiZWNhdXNlIHNvbWUgY29kZXMgYXJlIHRyZWF0ZWQgYXMgaGF2aW5nIHNpZGUgZWZmZWN0cy5cbi8vIFNvIHdlIGltcG9ydCBjb2RlIGluc2lkZSB0aGUgaWYtY2xhdXNlIHRvIGFsbG93IGJ1bmRsZXIgcmVtb3ZlIHRoZSBjb2RlIHNhZmVseS5cblxuZXhwb3J0ICogZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcbmltcG9ydCAqIGFzIG9ydCBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuZXhwb3J0IGRlZmF1bHQgb3J0O1xuXG5pbXBvcnQgeyByZWdpc3RlckJhY2tlbmQsIGVudiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5pbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSAnLi92ZXJzaW9uJztcblxuaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR0wpIHtcbiAgY29uc3Qgb25ueGpzQmFja2VuZCA9IHJlcXVpcmUoJy4vYmFja2VuZC1vbm54anMnKS5vbm54anNCYWNrZW5kO1xuICByZWdpc3RlckJhY2tlbmQoJ3dlYmdsJywgb25ueGpzQmFja2VuZCwgLTEwKTtcbn1cblxuaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0FTTSkge1xuICBjb25zdCB3YXNtQmFja2VuZCA9IHJlcXVpcmUoJy4vYmFja2VuZC13YXNtJykud2FzbUJhY2tlbmQ7XG4gIGlmICghQlVJTERfREVGUy5ESVNBQkxFX0pTRVApIHtcbiAgICByZWdpc3RlckJhY2tlbmQoJ3dlYmdwdScsIHdhc21CYWNrZW5kLCA1KTtcbiAgICByZWdpc3RlckJhY2tlbmQoJ3dlYm5uJywgd2FzbUJhY2tlbmQsIDUpO1xuICB9XG4gIHJlZ2lzdGVyQmFja2VuZCgnY3B1Jywgd2FzbUJhY2tlbmQsIDEwKTtcbiAgcmVnaXN0ZXJCYWNrZW5kKCd3YXNtJywgd2FzbUJhY2tlbmQsIDEwKTtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGVudi52ZXJzaW9ucywgJ3dlYicsIHsgdmFsdWU6IHZlcnNpb24sIGVudW1lcmFibGU6IHRydWUgfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8vIFRoaXMgZmlsZSBpcyBnZW5lcmF0ZWQgYnkgL2pzL3NjcmlwdHMvdXBkYXRlLXZlcnNpb24udHNcbi8vIERvIG5vdCBtb2RpZnkgZmlsZSBjb250ZW50IG1hbnVhbGx5LlxuXG5leHBvcnQgY29uc3QgdmVyc2lvbiA9ICcxLjIzLjAnO1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLElBZ0JNLFVBQ0EsMEJBWU8saUJBd0NQLGdDQXdDTztBQTdHYjs7QUFnQkEsSUFBTSxXQUFxQyxvQkFBSSxJQUFHO0FB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QUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFHO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBSTtB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OztBQ1BPLElBQU1DLFdBQVU7OztBREt2QixJQUFPLGdCQUFRO0FBS2YsSUFBSSxNQUEyQjtBQUM3QixRQUFNQyxpQkFBZ0IsOERBQTRCO0FBQ2xELGtCQUFnQixTQUFTQSxnQkFBZSxHQUFHO0FBQzdDO0FBRUEsSUFBSSxPQUEwQjtBQUM1QixRQUFNLGNBQWMsS0FBMEI7QUFDOUMsTUFBSSxPQUEwQjtBQUM1QixvQkFBZ0IsVUFBVSxhQUFhLENBQUM7QUFDeEMsb0JBQWdCLFNBQVMsYUFBYSxDQUFDO0FBQUEsRUFDekM7QUFDQSxrQkFBZ0IsT0FBTyxhQUFhLEVBQUU7QUFDdEMsa0JBQWdCLFFBQVEsYUFBYSxFQUFFO0FBQ3pDO0FBRUEsT0FBTyxlQUFlQyxLQUFJLFVBQVUsT0FBTyxFQUFFLE9BQU9DLFVBQVMsWUFBWSxLQUFLLENBQUM7IiwKICAibmFtZXMiOiBbIm5hbWUiLCAiYmFja2VuZCIsICJpIiwgImVudiIsICJjcmVhdGVDYW52YXMiLCAiVGVuc29yIiwgIlRlbnNvciIsICJuYW1lIiwgImJhY2tlbmQiLCAiSW5mZXJlbmNlU2Vzc2lvbiIsICJJbmZlcmVuY2VTZXNzaW9uIiwgIlRlbnNvciIsICJlbnYiLCAibG9nIiwgImVudiIsICJuYW1lIiwgInZlcnNpb24iLCAiZXhwb3J0cyIsICJHdWlkIiwgImNhY2hlIiwgImRpdiIsICJsb2cyIiwgIkFyZ1R5cGUiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgImV4cG9ydHMiLCAiZXhwb3J0cyIsICJFbmNvZGluZyIsICJleHBvcnRzIiwgIkJ5dGVCdWZmZXIiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIkFyZ1R5cGVBbmRJbmRleCIsICJleHBvcnRzIiwgIkF0dHJpYnV0ZVR5cGUiLCAiZXhwb3J0cyIsICJOb2RlVHlwZSIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIk5vZGUiLCAiZXhwb3J0cyIsICJFZGdlRW5kIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiTm9kZUVkZ2UiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJOb2Rlc1RvT3B0aW1pemVJbmRpY2VzIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiUnVudGltZU9wdGltaXphdGlvblJlY29yZCIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIlJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIlJ1bnRpbWVPcHRpbWl6YXRpb25zIiwgImV4cG9ydHMiLCAiVGVuc29yRGF0YVR5cGUiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJUZW5zb3IiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJTcGFyc2VUZW5zb3IiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJNYXBUeXBlIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiU2VxdWVuY2VUeXBlIiwgImV4cG9ydHMiLCAiRGltZW5zaW9uVmFsdWVUeXBlIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiRGltZW5zaW9uVmFsdWUiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJEaW1lbnNpb24iLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJTaGFwZSIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIlRlbnNvclR5cGVBbmRTaGFwZSIsICJleHBvcnRzIiwgIlR5cGVJbmZvVmFsdWUiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJUeXBlSW5mbyIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIlZhbHVlSW5mbyIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIkdyYXBoIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiQXR0cmlidXRlIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2giLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJEZXByZWNhdGVkU3ViR3JhcGhTZXNzaW9uU3RhdGUiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJEZXByZWNhdGVkU2Vzc2lvblN0YXRlIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIk9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiS2VybmVsVHlwZVN0clJlc29sdmVyIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiT3BlcmF0b3JTZXRJZCIsICJ2ZXJzaW9uIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiU3RyaW5nU3RyaW5nRW50cnkiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJNb2RlbCIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIkluZmVyZW5jZVNlc3Npb24iLCAiZXhwb3J0cyIsICJpbXBvcnRfdGVuc29yIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgInBhcmFtcyIsICJvZmZzZXQiLCAiZXhwb3J0cyIsICJpIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImV4cG9ydHMiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAic2xpY2UiLCAic2l6ZSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJmcm9tTnVtYmVyIiwgInRvTnVtYmVyIiwgImV4cG9ydHMiLCAiQnVmZmVyIiwgIm5hbWUiLCAiaSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJjcmVhdGUiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAiY3JlYXRlX2FycmF5IiwgImNyZWF0ZSIsICJidWZmZXIiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAic2VsZiIsICJlcnIiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJleHBvcnRzIiwgInJlcXVpcmVfbWluaW1hbCIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJvbm54IiwgIkRpbWVuc2lvbiIsICJUZW5zb3IiLCAiTWFwIiwgIlNwYXJzZVRlbnNvciIsICJpbml0X3RlbnNvciIsICJUZW5zb3IiLCAic2hhcGUiLCAic3BsaXQiLCAiaW1wb3J0X29ubngiLCAiVGVuc29yIiwgImluaXRfdGVuc29yIiwgImNhY2hlIiwgInZlcnNpb24iLCAibmFtZSIsICJzaGFwZSIsICJzaGFwZSIsICJzaGFwZSIsICJpbml0X3RlbnNvciIsICJzaGFwZSIsICJUZW5zb3IiLCAibmFtZSIsICJuYW1lIiwgIm5hbWUiLCAiYWRkIiwgImFuZCIsICJvciIsICJ4b3IiLCAiZ2xzbCIsICJzaGFkZXJTb3VyY2UiLCAidmFsaWRhdGVJbnB1dHMiLCAic2hpZnQiLCAidmFsaWRhdGVJbnB1dHMiLCAibmFtZSIsICJsb2ciLCAibm90IiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgIm5hbWUiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAic2hhcGUiLCAidmFsaWRhdGVJbnB1dHMiLCAic3VtIiwgInZhbGlkYXRlSW5wdXRzIiwgIm5hbWUiLCAiaW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgImRpbSIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJpbml0X3RlbnNvciIsICJUZW5zb3IiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAic3BsaXQiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHNWMTMiLCAiYWRkIiwgImFuZCIsICJsb2ciLCAibm90IiwgIm9yIiwgInhvciIsICJuYW1lIiwgInNoYXBlIiwgInNoYXBlIiwgIm5hbWUiLCAic291cmNlIiwgInBhY2tlZFNhbXBsZXIiLCAidGV4TnVtUiIsICJ0ZXhOdW1DIiwgInRyYW5zcG9zZSIsICJuYW1lIiwgInNoYXBlIiwgImkiLCAibmFtZSIsICJuYW1lIiwgImVudiIsICJuYW1lIiwgInRleHR1cmUiLCAiYmFja2VuZCIsICJ2ZXJzaW9uIiwgImVudiIsICJlbnYiLCAiY2FjaGUiLCAiYmFja2VuZCIsICJpbml0X2JhY2tlbmQiLCAib3V0cHV0IiwgImltcG9ydF9vbm54IiwgIkF0dHJpYnV0ZSIsICJpbml0X3RlbnNvciIsICJUZW5zb3IiLCAidmFsdWUiLCAiaW1wb3J0X29ubngiLCAiR3JhcGgiLCAiTm9kZSIsICJpbml0X3RlbnNvciIsICJuYW1lIiwgIkF0dHJpYnV0ZSIsICJUZW5zb3IiLCAic2hhcGUiLCAibm9kZUluZGV4IiwgImltcG9ydF9vbm54IiwgIk1vZGVsIiwgIkdyYXBoIiwgImluaXRfYmFja2VuZCIsICJiYWNrZW5kIiwgIk1vZGVsIiwgImluaXRfdGVuc29yIiwgIm5hbWUiLCAiVGVuc29yIiwgInZlcnNpb24iLCAib25ueGpzQmFja2VuZCIsICJlbnYiLCAidmVyc2lvbiJdCn0K